The 8 principles behind great UI layout
Alignment, hierarchy, and whitespace aren't just buzzwords — they're the load-bearing beams of everything you build.
Eight working card patterns every site needs — pricing, product, team, blog, stats, profile, feature, and testimonials.
Build a full landing page (hero + nav + cards + footer) →For growing teams
<div class="cards"> <div class="card"> <h3>Starter</h3> <div class="price">$9<span>/mo</span></div> <p>For side projects</p> <ul> <li><i class="ph-fill ph-check-circle"></i> 1 user</li> <li><i class="ph-fill ph-check-circle"></i> 10 projects</li> <li><i class="ph-fill ph-check-circle"></i> Basic support</li> </ul> <a href="#" class="cta">Get Starter</a> </div> <!-- featured middle card --> <div class="card featured"> <div class="badge">Most Popular</div> <h3>Pro</h3> <div class="price">$29<span>/mo</span></div> <p>For growing teams</p> <ul> <li><i class="ph-fill ph-check-circle"></i> 10 users</li> <li><i class="ph-fill ph-check-circle"></i> Unlimited projects</li> <li><i class="ph-fill ph-check-circle"></i> Priority support</li> <li><i class="ph-fill ph-check-circle"></i> Advanced analytics</li> </ul> <a href="#" class="cta">Get Pro</a> </div> <div class="card"> <h3>Enterprise</h3> <div class="price">$99<span>/mo</span></div> <p>For large orgs</p> <ul> <li><i class="ph-fill ph-check-circle"></i> Unlimited users</li> <li><i class="ph-fill ph-check-circle"></i> SSO & SAML</li> <li><i class="ph-fill ph-check-circle"></i> Dedicated CSM</li> </ul> <a href="#" class="cta">Contact Sales</a> </div> </div>
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; } .card { padding: 32px 28px; border: 1px solid #e5e5e5; border-radius: 16px; transition: all .2s; } /* Featured card inverts colors + scales up */ .card.featured { background: #111; color: #fff; transform: scale(1.03); position: relative; } .badge { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); } .price { font-size: 2.75rem; font-weight: 800; letter-spacing: -0.03em; }
<div class="cards"> <div class="card"> <div class="thumb"> <span class="fav"><i class="ph-fill ph-heart"></i></span> <i class="ph-duotone ph-headphones"></i> </div> <div class="body"> <div class="brand">Sonos</div> <h3>Wave Bluetooth Headphones</h3> <div class="row"> <div class="price">$249</div> <button class="add-btn">Add to Cart</button> </div> </div> </div> <div class="card"> <div class="thumb"> <span class="fav"><i class="ph ph-heart"></i></span> <i class="ph-duotone ph-sneaker"></i> </div> <div class="body"> <div class="brand">Nike</div> <h3>Cloudstep Running Shoe</h3> <div class="row"> <div class="price">$129</div> <button class="add-btn">Add to Cart</button> </div> </div> </div> <div class="card"> <div class="thumb"> <span class="fav"><i class="ph ph-heart"></i></span> <i class="ph-duotone ph-watch"></i> </div> <div class="body"> <div class="brand">Apple</div> <h3>Watch Series 10</h3> <div class="row"> <div class="price">$399</div> <button class="add-btn">Add to Cart</button> </div> </div> </div> <div class="card"> <div class="thumb"> <span class="fav"><i class="ph ph-heart"></i></span> <i class="ph-duotone ph-sunglasses"></i> </div> <div class="body"> <div class="brand">Ray-Ban</div> <h3>Aviator Classic</h3> <div class="row"> <div class="price">$169</div> <button class="add-btn">Add to Cart</button> </div> </div> </div> </div>
.thumb { height: 200px; position: relative; background: linear-gradient(135deg, #fbbf24, #f97316); } /* Favorite button floats on top of thumb */ .fav { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border-radius: 50%; background: rgba(255,255,255,.85); } .row { display: flex; justify-content: space-between; align-items: center; }
<div class="cards"> <div class="card"> <div class="avatar-wrap"><div class="avatar">JL</div></div> <h3>Julia Lang</h3> <div class="role">CEO & Founder</div> <div class="socials"> <a href="#"><i class="ph ph-linkedin-logo"></i></a> <a href="#"><i class="ph ph-twitter-logo"></i></a> <a href="#"><i class="ph ph-envelope"></i></a> </div> </div> <div class="card"> <div class="avatar-wrap"><div class="avatar">MR</div></div> <h3>Marco Reyes</h3> <div class="role">Head of Design</div> <div class="socials"> <a href="#"><i class="ph ph-linkedin-logo"></i></a> <a href="#"><i class="ph ph-dribbble-logo"></i></a> <a href="#"><i class="ph ph-envelope"></i></a> </div> </div> <div class="card"> <div class="avatar-wrap"><div class="avatar">SP</div></div> <h3>Sana Patel</h3> <div class="role">Engineering</div> <div class="socials"> <a href="#"><i class="ph ph-github-logo"></i></a> <a href="#"><i class="ph ph-linkedin-logo"></i></a> <a href="#"><i class="ph ph-envelope"></i></a> </div> </div> <div class="card"> <div class="avatar-wrap"><div class="avatar">TK</div></div> <h3>Theo Kim</h3> <div class="role">Marketing</div> <div class="socials"> <a href="#"><i class="ph ph-linkedin-logo"></i></a> <a href="#"><i class="ph ph-twitter-logo"></i></a> <a href="#"><i class="ph ph-envelope"></i></a> </div> </div> </div>
/* Gradient banner across the top */ .avatar-wrap { height: 120px; background: linear-gradient(135deg, #ec4899, #3b82f6); position: relative; margin-bottom: 50px; } /* Avatar half-overlaps the banner */ .avatar { width: 90px; height: 90px; border-radius: 50%; border: 5px solid #fff; position: absolute; bottom: -45px; left: 50%; transform: translateX(-50%); } .socials a { width: 32px; height: 32px; border-radius: 50%; background: #f4f4f5; } .socials a:hover { background: #111; color: #fff; }
Alignment, hierarchy, and whitespace aren't just buzzwords — they're the load-bearing beams of everything you build.
Grid does 80% of what teams use Flexbox for, only cleaner. Here's when each actually wins.
OKLCH, color-mix, @color-profile — the color system finally caught up with the web in 2025.
<div class="cards"> <article class="card"> <div class="thumb"><span class="category">Design</span></div> <div class="body"> <h3>The 8 principles behind great UI layout</h3> <p class="excerpt">Alignment, hierarchy, and whitespace aren't just buzzwords — they're the load-bearing beams of everything you build.</p> <div class="meta"> <div class="author-dot">JL</div> <span>Julia Lang · 8 min read</span> </div> </div> </article> <article class="card"> <div class="thumb"><span class="category">CSS</span></div> <div class="body"> <h3>Why I stopped using Flexbox for everything</h3> <p class="excerpt">Grid does 80% of what teams use Flexbox for, only cleaner. Here's when each actually wins.</p> <div class="meta"> <div class="author-dot">MR</div> <span>Marco Reyes · 6 min read</span> </div> </div> </article> <article class="card"> <div class="thumb"><span class="category">Web</span></div> <div class="body"> <h3>A field guide to modern CSS color</h3> <p class="excerpt">OKLCH, color-mix, @color-profile — the color system finally caught up with the web in 2025.</p> <div class="meta"> <div class="author-dot">SP</div> <span>Sana Patel · 11 min read</span> </div> </div> </article> </div>
.thumb { height: 180px; background: linear-gradient(135deg, #6366f1, #8b5cf6); display: flex; align-items: flex-end; padding: 16px; } /* Pill category tag with inverted background */ .category { background: rgba(255,255,255,.95); color: #111; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; } .author-dot { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, #ec4899, #3b82f6); color: #fff; }
<div class="cards"> <div class="card"> <div class="top-row"> <div class="stat-icon"><i class="ph-duotone ph-users"></i></div> <div class="delta up">+ 12.4%</div> </div> <div class="label">Active Users</div> <div class="value">8,247</div> <div class="sub">vs last month</div> </div> <div class="card"> <div class="top-row"> <div class="stat-icon"><i class="ph-duotone ph-currency-dollar"></i></div> <div class="delta up">+ 8.1%</div> </div> <div class="label">Revenue</div> <div class="value">$42.8k</div> <div class="sub">vs last month</div> </div> <div class="card"> <div class="top-row"> <div class="stat-icon"><i class="ph-duotone ph-shopping-cart"></i></div> <div class="delta down">− 3.2%</div> </div> <div class="label">Orders</div> <div class="value">1,128</div> <div class="sub">vs last month</div> </div> <div class="card"> <div class="top-row"> <div class="stat-icon"><i class="ph-duotone ph-chart-line-up"></i></div> <div class="delta up">+ 21.0%</div> </div> <div class="label">Conversion</div> <div class="value">4.72%</div> <div class="sub">vs last month</div> </div> </div>
.top-row { display: flex; justify-content: space-between; align-items: flex-start; } /* Tinted icon tile — subtle brand-colored bg */ .stat-icon { width: 44px; height: 44px; border-radius: 12px; background: rgba(236, 72, 153, .12); color: #ec4899; } /* Delta chip — green up, red down */ .delta.up { color: #10b981; background: rgba(16,185,129,.1); } .delta.down { color: #ef4444; background: rgba(239,68,68,.1); } .value { font-size: 2rem; font-weight: 800; letter-spacing: -0.02em; }
Mathematician, writer, and the world's first programmer. Currently building steam-powered algorithms.
Rear Admiral, compiler inventor, and enemy of the phrase "we've always done it that way."
<div class="cards"> <div class="card"> <div class="header"> <div class="avatar">AL</div> <div> <div class="name">Ada Lovelace</div> <div class="handle">@adalove</div> </div> </div> <p class="bio">Mathematician, writer, and the world's first programmer. Currently building steam-powered algorithms.</p> <div class="stats"> <div class="stat"><strong>1.2k</strong><span>Posts</span></div> <div class="stat"><strong>24.8k</strong><span>Followers</span></div> <div class="stat"><strong>380</strong><span>Following</span></div> </div> <button class="follow">Follow</button> </div> <div class="card"> <div class="header"> <div class="avatar">GH</div> <div> <div class="name">Grace Hopper</div> <div class="handle">@amazinggrace</div> </div> </div> <p class="bio">Rear Admiral, compiler inventor, and enemy of the phrase "we've always done it that way."</p> <div class="stats"> <div class="stat"><strong>842</strong><span>Posts</span></div> <div class="stat"><strong>18.3k</strong><span>Followers</span></div> <div class="stat"><strong>126</strong><span>Following</span></div> </div> <button class="follow">Follow</button> </div> </div>
.header { display: flex; align-items: center; gap: 16px; } .avatar { width: 58px; height: 58px; border-radius: 50%; background: linear-gradient(135deg, #ec4899, #f43f5e); display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; } /* Stat row divided by top/bottom borders */ .stats { display: flex; justify-content: space-between; padding: 16px 0; border-top: 1px solid #eee; border-bottom: 1px solid #eee; }
Ship static pages in milliseconds. Edge-cached. No cold starts.
HTTPS, CSP headers, and rate limiting enabled out of the box.
50+ tools ready to go: Slack, GitHub, Stripe, Notion, and more.
Track every request with live dashboards and anomaly detection.
<div class="cards"> <div class="card"> <div class="icon"><i class="ph-duotone ph-lightning"></i></div> <h3>Blazing fast</h3> <p>Ship static pages in milliseconds. Edge-cached. No cold starts.</p> </div> <div class="card"> <div class="icon"><i class="ph-duotone ph-lock-key"></i></div> <h3>Secure by default</h3> <p>HTTPS, CSP headers, and rate limiting enabled out of the box.</p> </div> <div class="card"> <div class="icon"><i class="ph-duotone ph-plugs-connected"></i></div> <h3>Integrations</h3> <p>50+ tools ready to go: Slack, GitHub, Stripe, Notion, and more.</p> </div> <div class="card"> <div class="icon"><i class="ph-duotone ph-chart-bar"></i></div> <h3>Real-time analytics</h3> <p>Track every request with live dashboards and anomaly detection.</p> </div> </div>
/* Subtle card on dark background */ .card { padding: 28px; border-radius: 14px; background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); transition: all .2s; } .card:hover { border-color: rgba(236, 72, 153, .4); transform: translateY(-3px); } /* Gradient tinted icon tile */ .icon { width: 48px; height: 48px; border-radius: 12px; background: linear-gradient(135deg, rgba(236,72,153,.2), rgba(59,130,246,.15)); color: #ec4899; }
This completely changed how our team ships. What used to take a sprint now takes an afternoon.
The documentation alone is worth the price. Every question I had was already answered with a live example.
Finally something that treats students like designers instead of button-pushers. My class loves it.
<div class="cards"> <div class="card"> <!-- 5 stars --> <div class="rating"> <i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i> </div> <p class="quote">This completely changed how our team ships. What used to take a sprint now takes an afternoon.</p> <div class="person"> <div class="avatar">RN</div> <div> <div class="name">Renée Nakamura</div> <div class="title">Head of Product · Vellum</div> </div> </div> </div> <div class="card"> <div class="rating"> <i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i> </div> <p class="quote">The documentation alone is worth the price. Every question I had was already answered with a live example.</p> <div class="person"> <div class="avatar">DK</div> <div> <div class="name">Devon Kim</div> <div class="title">Staff Engineer · Halo</div> </div> </div> </div> <div class="card"> <div class="rating"> <i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i><i class="ph-fill ph-star"></i> </div> <p class="quote">Finally something that treats students like designers instead of button-pushers. My class loves it.</p> <div class="person"> <div class="avatar">PG</div> <div> <div class="name">Priya Gupta</div> <div class="title">Design Professor · VCU</div> </div> </div> </div> </div>
/* Decorative open-quote behind the text */ .card::before { content: "\201C"; position: absolute; top: 8px; left: 22px; font-family: Georgia, serif; font-size: 5rem; color: rgba(236, 72, 153, .15); line-height: 1; } .quote { font-style: italic; position: relative; line-height: 1.65; } .rating { color: #f59e0b; }
<div class="cards"> <article class="card"> <img src="https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?w=800&q=80" alt="cafe"> <div class="overlay"> <span class="pill">Travel</span> <h3>A morning in Kyoto's tea district</h3> <div class="meta"><span>8 min read</span><span class="dot"></span><span>Mar 2026</span></div> </div> </article> <article class="card"> <img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&q=80" alt="mountains"> <div class="overlay"> <span class="pill">Nature</span> <h3>Chasing light through alpine valleys</h3> <div class="meta"><span>12 min read</span><span class="dot"></span><span>Feb 2026</span></div> </div> </article> <article class="card"> <img src="https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=800&q=80" alt="workspace"> <div class="overlay"> <span class="pill">Workspace</span> <h3>The late-night setup that ships product</h3> <div class="meta"><span>6 min read</span><span class="dot"></span><span>Jan 2026</span></div> </div> </article> </div>
.card { position: relative; aspect-ratio: 4 / 5; border-radius: 18px; overflow: hidden; } /* Image fills the card, scales on hover */ .card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .6s; } .card:hover img { transform: scale(1.08); } /* Dark scrim anchors text to the bottom */ .overlay { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 35%, rgba(0,0,0,.82)); padding: 26px; display: flex; flex-direction: column; justify-content: flex-end; color: #fff; } .pill { align-self: flex-start; background: rgba(255,255,255,.92); color: #111; padding: 5px 12px; border-radius: 999px; font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
A practical guide to starting with color, type, and tone — before touching a single component.
Three rules that keep critique sharp without turning into a personality contest. Works for remote teams too.
Skip the "so what do you think?" and get to the behaviors that actually reveal the problem you're solving.
Sketch six ideas, vote, and ship the best one. The format has worked at three companies and counting.
<div class="cards"> <article class="card"> <!-- Use background-image for flexible ratio --> <div class="img" style="background-image:url('https://images.unsplash.com/photo-1519125323398-675f0ddb6308?w=500&q=80')"></div> <div class="body"> <div class="tag">Design</div> <h3>Building a brand system from scratch</h3> <p>A practical guide to starting with color, type, and tone — before touching a single component.</p> <div class="row"><i class="ph ph-clock"></i><span>9 min read</span></div> </div> </article> <article class="card"> <div class="img" style="background-image:url('https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=500&q=80')"></div> <div class="body"> <div class="tag">Process</div> <h3>How we run design critique without tears</h3> <p>Three rules that keep critique sharp without turning into a personality contest. Works for remote teams too.</p> <div class="row"><i class="ph ph-clock"></i><span>7 min read</span></div> </div> </article> <article class="card"> <div class="img" style="background-image:url('https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=500&q=80')"></div> <div class="body"> <div class="tag">Research</div> <h3>Five user-interview questions worth asking</h3> <p>Skip the "so what do you think?" and get to the behaviors that actually reveal the problem you're solving.</p> <div class="row"><i class="ph ph-clock"></i><span>5 min read</span></div> </div> </article> <article class="card"> <div class="img" style="background-image:url('https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=500&q=80')"></div> <div class="body"> <div class="tag">Workshop</div> <h3>A one-hour design studio for any team</h3> <p>Sketch six ideas, vote, and ship the best one. The format has worked at three companies and counting.</p> <div class="row"><i class="ph ph-clock"></i><span>4 min read</span></div> </div> </article> </div>
/* Horizontal split: fixed image column + flexible body */ .card { display: grid; grid-template-columns: 160px 1fr; border-radius: 16px; overflow: hidden; border: 1px solid #eee; } .card .img { background-size: cover; background-position: center; } .card .body { padding: 20px 22px; display: flex; flex-direction: column; justify-content: center; } /* Accent-colored category tag */ .tag { color: #ec4899; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; }
Editorial layout principles — hierarchy, whitespace, captions — translate surprisingly well to the web.
Typography decisions that happen before anyone touches a font. Leading, tracking, and trust.
Not every decision needs Figma. Sometimes paper, walks, and a phone camera is the right stack.
<div class="cards"> <article class="card"> <div class="thumb"> <img src="https://images.unsplash.com/photo-1518770660439-4636190af475?w=800&q=80" alt=""> <span class="ribbon new">New</span> </div> <div class="body"> <h3>Why the best websites still feel like magazines</h3> <p>Editorial layout principles — hierarchy, whitespace, captions — translate surprisingly well to the web.</p> <div class="bottom"> <div class="author"> <img src="https://i.pravatar.cc/60?img=47" alt=""> <span>Julia Lang</span> </div> <span class="date">Apr 14</span> </div> </div> </article> <article class="card"> <div class="thumb"> <img src="https://images.unsplash.com/photo-1481487196290-c152efe083f5?w=800&q=80" alt=""> <span class="ribbon">Feature</span> </div> <div class="body"> <h3>The quiet craft of a well-set headline</h3> <p>Typography decisions that happen before anyone touches a font. Leading, tracking, and trust.</p> <div class="bottom"> <div class="author"> <img src="https://i.pravatar.cc/60?img=12" alt=""> <span>Marco Reyes</span> </div> <span class="date">Apr 10</span> </div> </div> </article> <article class="card"> <div class="thumb"> <img src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800&q=80" alt=""> <span class="ribbon sale">Save 20%</span> </div> <div class="body"> <h3>A field guide to slower design tools</h3> <p>Not every decision needs Figma. Sometimes paper, walks, and a phone camera is the right stack.</p> <div class="bottom"> <div class="author"> <img src="https://i.pravatar.cc/60?img=32" alt=""> <span>Sana Patel</span> </div> <span class="date">Apr 4</span> </div> </div> </article> </div>
/* Serif headline for magazine feel */ .body h3 { font-family: Georgia, serif; font-size: 1.4rem; font-weight: 700; line-height: 1.25; } /* Image zooms while card stays put */ .thumb { position: relative; aspect-ratio: 16 / 10; overflow: hidden; } .thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s; } .card:hover .thumb img { transform: scale(1.06); } /* Ribbon sits on top of the image */ .ribbon { position: absolute; top: 14px; left: 14px; background: #111; color: #fff; padding: 6px 12px; border-radius: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; } .ribbon.new { background: linear-gradient(135deg, #ec4899, #f43f5e); } .ribbon.sale { background: linear-gradient(135deg, #10b981, #22c55e); } /* Author + date row separated by a divider */ .bottom { display: flex; justify-content: space-between; padding-top: 14px; border-top: 1px solid #f0f0f0; }
12 images · Mar 2026
18 images · Apr 2026
24 images · Feb 2026
<div class="cards"> <article class="card"> <div class="img-wrap"> <img src="https://images.unsplash.com/photo-1515378791036-0648a3ef77b2?w=800&q=80" alt="laptop setup"> <span class="heart"><i class="ph-fill ph-heart"></i></span> </div> <!-- The floating panel overlaps the image's bottom --> <div class="content-float"> <div class="tag">Studio</div> <h3>Modern workspace portraits</h3> <p>12 images · Mar 2026</p> </div> </article> <article class="card"> <div class="img-wrap"> <img src="https://images.unsplash.com/photo-1487956382158-bb926046304a?w=800&q=80" alt="nature"> <span class="heart"><i class="ph ph-heart"></i></span> </div> <div class="content-float"> <div class="tag">Nature</div> <h3>Field notes — spring</h3> <p>18 images · Apr 2026</p> </div> </article> <article class="card"> <div class="img-wrap"> <img src="https://images.unsplash.com/photo-1501196354995-cbb51c65aaea?w=800&q=80" alt="travel"> <span class="heart"><i class="ph ph-heart"></i></span> </div> <div class="content-float"> <div class="tag">Travel</div> <h3>Week in Lisbon</h3> <p>24 images · Feb 2026</p> </div> </article> </div>
/* Card is tall so the floating panel has room to overlap */ .card { position: relative; padding-bottom: 50px; } .img-wrap { position: relative; aspect-ratio: 4 / 5; border-radius: 16px; overflow: hidden; box-shadow: 0 20px 50px rgba(191, 90, 242, .18); } /* Absolute positioning + negative translate = the overlap */ .content-float { position: absolute; bottom: 0; left: 16px; right: 16px; background: #fff; border-radius: 14px; padding: 18px 20px; box-shadow: 0 10px 30px rgba(0,0,0,.08); transform: translateY(30%); } /* Floating heart button on the image corner */ .heart { position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; border-radius: 50%; background: rgba(255,255,255,.92); color: #ec4899; }
<div class="cards"> <div class="flip"> <div class="face front"> <img src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=500&q=80" alt=""> <div class="name"><h3>Maya Chen</h3><span>Photographer</span></div> </div> <div class="face back"> <div class="tagline">"I shoot what I wish I could stay inside forever."</div> <a class="cta" href="#">View portfolio →</a> </div> </div> <div class="flip"> <div class="face front"> <img src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=500&q=80" alt=""> <div class="name"><h3>Dominic Reyes</h3><span>Illustrator</span></div> </div> <div class="face back"> <div class="tagline">"Sketches first, software second — always."</div> <a class="cta" href="#">See work →</a> </div> </div> <div class="flip"> <div class="face front"> <img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=500&q=80" alt=""> <div class="name"><h3>Priya Patel</h3><span>Brand Designer</span></div> </div> <div class="face back"> <div class="tagline">"Identity starts with voice — visuals follow."</div> <a class="cta" href="#">Case studies →</a> </div> </div> </div>
/* Parent needs perspective for the 3D effect */ .cards { perspective: 1200px; } .flip { position: relative; transform-style: preserve-3d; transition: transform .8s cubic-bezier(.2,.7,.3,1); } .flip:hover { transform: rotateY(180deg); } /* Both faces stack — hide the back side of each */ .face { position: absolute; inset: 0; backface-visibility: hidden; border-radius: 18px; overflow: hidden; } /* Pre-rotate the back so it faces you after the flip */ .back { transform: rotateY(180deg); background: linear-gradient(135deg, #ec4899, #8b5cf6, #3b82f6); color: #fff; }
// Optional: make the flip work on tap, not just hover (mobile-friendly). // In your CSS, replace `.flip:hover` with `.flip.flipped` so the JS controls it. document.querySelectorAll('.flip').forEach(card => { card.addEventListener('click', () => { card.classList.toggle('flipped'); }); }); // Bonus: keyboard support — Enter or Space flips the focused card. document.querySelectorAll('.flip').forEach(card => { card.tabIndex = 0; // make focusable card.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); card.classList.toggle('flipped'); } }); });
Works beautifully on photography or gradient backgrounds — the blur picks up the colors behind.
Matches the Liquid Glass aesthetic Apple uses in Control Center and notifications.
Glass is beautiful against visuals. Avoid stacking too many — the effect loses its magic.
<!-- Parent needs a colorful / photo background --> <div class="v14-wrap"> <div class="cards"> <div class="glass"> <div class="icon"><i class="ph-duotone ph-sparkle"></i></div> <h3>Modern feel</h3> <p>Works beautifully on photography or gradient backgrounds — the blur picks up the colors behind.</p> </div> <div class="glass"> <div class="icon"><i class="ph-duotone ph-cloud"></i></div> <h3>iOS-native look</h3> <p>Matches the Liquid Glass aesthetic Apple uses in Control Center and notifications.</p> </div> <div class="glass"> <div class="icon"><i class="ph-duotone ph-magnifying-glass"></i></div> <h3>Use sparingly</h3> <p>Glass is beautiful against visuals. Avoid stacking too many — the effect loses its magic.</p> </div> </div> </div>
/* Background must have something to blur */ .v14-wrap { background: radial-gradient(circle at 20% 30%, #ec4899, transparent 45%), radial-gradient(circle at 80% 60%, #3b82f6, transparent 45%), linear-gradient(135deg, #6366f1, #a855f7); } /* The magic trio: translucent bg + backdrop-filter + thin border */ .glass { background: rgba(255, 255, 255, .12); backdrop-filter: blur(20px) saturate(1.4); -webkit-backdrop-filter: blur(20px) saturate(1.4); border: 1px solid rgba(255, 255, 255, .25); border-radius: 20px; padding: 26px; color: #fff; }
Everything you need to ship your first product to the world.
Unlimited projects, priority support, and analytics.
For growing teams — collaboration, roles, and custom branding.
<!-- Outer = animated gradient, inner = actual content --> <div class="cards"> <div class="grad-card"> <div class="inner"> <div class="icon"><i class="ph-duotone ph-rocket-launch"></i></div> <h3>Launch Plan</h3> <p>Everything you need to ship your first product to the world.</p> <div class="price">$19/mo</div> </div> </div> <div class="grad-card"> <div class="inner"> <div class="icon"><i class="ph-duotone ph-crown"></i></div> <h3>Pro Plan</h3> <p>Unlimited projects, priority support, and analytics.</p> <div class="price">$49/mo</div> </div> </div> <div class="grad-card"> <div class="inner"> <div class="icon"><i class="ph-duotone ph-infinity"></i></div> <h3>Team Plan</h3> <p>For growing teams — collaboration, roles, and custom branding.</p> <div class="price">$99/mo</div> </div> </div> </div>
/* Outer box = colorful gradient, small padding = border width */ .grad-card { padding: 3px; border-radius: 18px; background: linear-gradient(135deg, #ec4899, #8b5cf6, #3b82f6, #06b6d4, #ec4899); background-size: 300% 300%; animation: borderFlow 6s linear infinite; } /* Inner card covers most of the box, leaving a slim gradient ring */ .inner { background: #fff; border-radius: 16px; padding: 28px; } /* Animate the gradient's position for a flowing effect */ @keyframes borderFlow { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* Bonus: gradient-filled text for the price */ .price { background: linear-gradient(135deg, #ec4899, #8b5cf6); -webkit-background-clip: text; background-clip: text; color: transparent; }
<div class="cards"> <div class="deck"> <!-- Back two layers are decorative --> <div class="layer behind-2" style="background:linear-gradient(135deg,#f59e0b,#ef4444)"></div> <div class="layer behind-1" style="background:linear-gradient(135deg,#a78bfa,#ec4899)"></div> <!-- Front card has the actual content --> <div class="layer front-card"> <img src="https://images.unsplash.com/photo-1513475382585-d06e58bcb0e0?w=600&q=80" alt=""> <div class="body"> <div class="tag">Collection</div> <h3>Summer Polaroids</h3> <div class="count"><strong>12</strong> photos · Mar 2026</div> </div> </div> </div> <div class="deck"> <div class="layer behind-2" style="background:linear-gradient(135deg,#34d399,#06b6d4)"></div> <div class="layer behind-1" style="background:linear-gradient(135deg,#60a5fa,#8b5cf6)"></div> <div class="layer front-card"> <img src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=600&q=80" alt=""> <div class="body"> <div class="tag">Series</div> <h3>Coastal Mornings</h3> <div class="count"><strong>8</strong> photos · Feb 2026</div> </div> </div> </div> <div class="deck"> <div class="layer behind-2" style="background:linear-gradient(135deg,#fde047,#f97316)"></div> <div class="layer behind-1" style="background:linear-gradient(135deg,#f472b6,#f43f5e)"></div> <div class="layer front-card"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?w=600&q=80" alt=""> <div class="body"> <div class="tag">Portraits</div> <h3>Studio Cats</h3> <div class="count"><strong>15</strong> photos · Jan 2026</div> </div> </div> </div> </div>
.deck { position: relative; aspect-ratio: 4 / 5; } /* All 3 layers absolute-stacked in the same spot */ .deck .layer { position: absolute; inset: 0; border-radius: 18px; transition: transform .4s cubic-bezier(.2,.8,.3,1); } /* Offset + rotate the decorative layers */ .layer.behind-2 { transform: translate(16px, 16px) rotate(4deg) scale(.96); } .layer.behind-1 { transform: translate(8px, 8px) rotate(-2deg) scale(.98); } /* On hover, fan them out in opposite directions */ .deck:hover .layer.behind-2 { transform: translate(26px, 22px) rotate(7deg); } .deck:hover .layer.behind-1 { transform: translate(-14px, 14px) rotate(-6deg); }
Show the thing you build on nights and weekends — not the client work that pays the bills.
Minimal JS, aggressive caching, and edge delivery — your site should feel instant.
The little details — easter eggs, micro-interactions, and inside jokes — are what people remember.
Portfolios evolve. Revisit yours every six months and prune the pieces that no longer represent you.
<!-- Each card gets a unique color via --neon custom property --> <div class="cards"> <div class="neon"> <div class="icon"><i class="ph-duotone ph-heart"></i></div> <h3><span>Passion</span> project</h3> <p>Show the thing you build on nights and weekends — not the client work that pays the bills.</p> </div> <div class="neon"> <div class="icon"><i class="ph-duotone ph-lightning"></i></div> <h3><span>Lightning</span> fast</h3> <p>Minimal JS, aggressive caching, and edge delivery — your site should feel instant.</p> </div> <div class="neon"> <div class="icon"><i class="ph-duotone ph-gem"></i></div> <h3><span>Hidden</span> gems</h3> <p>The little details — easter eggs, micro-interactions, and inside jokes — are what people remember.</p> </div> <div class="neon"> <div class="icon"><i class="ph-duotone ph-plant"></i></div> <h3><span>Growing</span> with you</h3> <p>Portfolios evolve. Revisit yours every six months and prune the pieces that no longer represent you.</p> </div> </div>
/* Each card gets its own --neon color */ .neon:nth-child(1) { --neon: #ec4899; animation-delay: 0s; } .neon:nth-child(2) { --neon: #3b82f6; animation-delay: 0.9s; } .neon:nth-child(3) { --neon: #22d3ee; animation-delay: 1.8s; } .neon { background: #14141f; color: #f5f5f7; padding: 28px; border-radius: 16px; animation: neonPulse 3.6s ease-in-out infinite; } /* Pulse between dim and bright glow using the color variable */ @keyframes neonPulse { 0%, 100% { box-shadow: 0 0 20px color-mix(in srgb, var(--neon) 25%, transparent); } 50% { box-shadow: 0 0 38px color-mix(in srgb, var(--neon) 55%, transparent); } } /* The accent word gets the neon color too */ h3 span { color: var(--neon); }
<div class="cards"> <div class="tilt"> <img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&q=80" alt=""> <span class="badge">Nature</span> <div class="content"> <h3>Mountain Series</h3> <div class="sub">12 frames · alpine light study</div> </div> </div> <div class="tilt"> <img src="https://images.unsplash.com/photo-1519608487953-e999c86e7455?w=600&q=80" alt=""> <span class="badge">City</span> <div class="content"> <h3>After Hours</h3> <div class="sub">9 frames · neon & reflection</div> </div> </div> <div class="tilt"> <img src="https://images.unsplash.com/photo-1509114397022-ed747cca3f65?w=600&q=80" alt=""> <span class="badge">Ocean</span> <div class="content"> <h3>Tidal Lines</h3> <div class="sub">15 frames · long exposure</div> </div> </div> </div>
/* Parent sets the 3D stage */ .cards { perspective: 1000px; } .tilt { position: relative; border-radius: 18px; overflow: hidden; transform-style: preserve-3d; transition: transform .4s, box-shadow .4s; } /* The whole card tilts on hover */ .tilt:hover { transform: rotateY(-14deg) rotateX(8deg) scale(1.03); box-shadow: -20px 30px 60px rgba(0,0,0,.3); } /* Content + badge lift forward on the Z-axis */ .tilt .content { transform: translateZ(40px); } .tilt .badge { transform: translateZ(50px); }
Everything above — the card grid, its styles, and a hover lift — combined into one complete, standalone HTML file. Copy it into a new index.html, open it in a browser, and it just works — no libraries, no build step.
Live preview
Complete HTML — copy this whole file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Our Plans</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f4f5f7; color: #1f2433; line-height: 1.55;
}
.page { max-width: 1040px; margin: 0 auto; padding: 56px 24px 72px; }
.page-head { text-align: center; margin-bottom: 40px; }
.page-head h1 { font-size: 2.1rem; margin-bottom: 10px; }
.page-head p { color: #6b7280; max-width: 540px; margin: 0 auto; }
/* ===== Card grid: responsive, auto-fitting columns ===== */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
/* ===== One card ===== */
.card {
background: #fff;
border: 1px solid #e9edf3;
border-radius: 16px;
padding: 28px 26px;
text-align: center;
transition: transform .25s, box-shadow .25s;
}
.card:hover {
transform: translateY(-6px);
box-shadow: 0 18px 40px rgba(17, 24, 39, .12);
}
/* The middle (featured) tier stands out */
.card.featured {
border-color: #2563eb;
box-shadow: 0 14px 36px rgba(37, 99, 235, .18);
}
.card.featured .badge {
display: inline-block;
background: #2563eb; color: #fff;
font-size: .72rem; font-weight: 700; letter-spacing: .04em;
text-transform: uppercase;
padding: 4px 12px; border-radius: 999px; margin-bottom: 14px;
}
.card h3 { font-size: 1.1rem; margin-bottom: 8px; }
.card .price { font-size: 2.4rem; font-weight: 800; margin-bottom: 4px; }
.card .price span { font-size: .95rem; font-weight: 500; color: #6b7280; }
.card .desc { color: #6b7280; font-size: .9rem; margin-bottom: 18px; }
.card ul { list-style: none; margin: 0 0 22px; text-align: left; }
.card li {
font-size: .92rem; color: #374151;
padding: 7px 0 7px 26px; position: relative;
border-top: 1px solid #f1f3f7;
}
.card li::before {
content: '\2713'; color: #16a34a; font-weight: 700;
position: absolute; left: 4px;
}
.card .cta {
display: block; text-decoration: none;
padding: 11px; border-radius: 9px; font-weight: 600;
background: #eef2ff; color: #2563eb;
transition: background .2s;
}
.card .cta:hover { background: #e0e7ff; }
.card.featured .cta { background: #2563eb; color: #fff; }
.card.featured .cta:hover { background: #1d4ed8; }
</style>
</head>
<body>
<main class="page">
<header class="page-head">
<h1>Simple, honest pricing</h1>
<p>Pick the plan that fits today — upgrade or downgrade any time. Hover a card to see it lift.</p>
</header>
<div class="cards">
<div class="card">
<h3>Starter</h3>
<div class="price">$9<span>/mo</span></div>
<p class="desc">For side projects</p>
<ul>
<li>1 project</li>
<li>5 GB storage</li>
<li>Community support</li>
</ul>
<a class="cta" href="#">Choose Starter</a>
</div>
<div class="card featured">
<span class="badge">Most popular</span>
<h3>Pro</h3>
<div class="price">$29<span>/mo</span></div>
<p class="desc">For growing teams</p>
<ul>
<li>Unlimited projects</li>
<li>100 GB storage</li>
<li>Priority support</li>
<li>Advanced analytics</li>
</ul>
<a class="cta" href="#">Choose Pro</a>
</div>
<div class="card">
<h3>Business</h3>
<div class="price">$79<span>/mo</span></div>
<p class="desc">For larger orgs</p>
<ul>
<li>Everything in Pro</li>
<li>1 TB storage</li>
<li>SSO & audit logs</li>
<li>Dedicated manager</li>
</ul>
<a class="cta" href="#">Choose Business</a>
</div>
</div>
</main>
</body>
</html>