Skeletons use the template primitives and void tokens. Copy, then replace content with real content from src/content/*. All are Server Components unless marked.
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Container } from "@/components/ui/container";
import { Eyebrow } from "@/components/ui/eyebrow";
import { Section } from "@/components/ui/section";
import { TextLink } from "@/components/ui/link";
import { cn } from "@/lib/cn";Rules for every section: one job; left-aligned unless noted; heading max-w-[Nch]; eyebrows on ≤ 1/3 of sections; adjacent sections differ in archetype and rhythm.
1. Heroes
Measured patterns (24 sites): left H1 + short sub + 1–2 CTAs then real product (Linear, Cursor, Framer); split H1 left / paragraph right (Anthropic, Supabase); centered with product UI (Attio, Clerk, Railway); poster/type-as-image (Granola, Dia, hellohello). Headers 56–72px; H1 46–96px desktop; sub 18–24px, max 480–672px.
1a. Editorial left (default when there's no strong visual)
<section aria-labelledby="hero-title" className="grain relative overflow-clip border-b border-line-subtle">
<Container className="pt-16 pb-20 sm:pt-24 lg:pt-36 lg:pb-28">
<Eyebrow>Open source · MIT · v3.2</Eyebrow>
<h1 id="hero-title" className="mt-6 max-w-[15ch] text-display-xl text-fg">Feature flags that live in your repo.</h1>
<div className="mt-8 grid gap-8 lg:grid-cols-12">
<p className="max-w-[46ch] text-lg text-fg-muted lg:col-span-6">
Flags are YAML next to the code they gate. Reviews, rollbacks and audit history come from git, not a dashboard.
</p>
<div className="flex flex-wrap items-center gap-6 lg:col-span-6 lg:justify-end lg:self-end">
<Button href="/docs/quickstart" size="lg">Read the quickstart</Button>
<TextLink href="https://github.com/acme/flags" tone="muted" className="font-mono text-sm">github.com/acme/flags</TextLink>
</div>
</div>
</Container>
</section>1b. Product shot (UI is the proof)
<section aria-labelledby="hero-title" className="relative overflow-clip">
<div aria-hidden="true" className="pointer-events-none absolute inset-x-0 top-0 -z-10 h-144 bg-[radial-gradient(60%_70%_at_20%_0%,color-mix(in_oklch,var(--brand)_12%,transparent),transparent_70%)]" />
<Container className="pt-16 lg:pt-28">
<div className="flex flex-wrap items-end justify-between gap-6">
<h1 id="hero-title" className="max-w-[16ch] text-display-lg text-fg">Deploy previews for every branch in 14 seconds.</h1>
<TextLink href="/changelog" tone="muted" className="text-sm">New · Rollback from Slack →</TextLink>
</div>
<p className="mt-6 max-w-[44ch] text-lg text-fg-muted">Push a branch, get a URL. Logs, env and rollbacks live on the same page.</p>
<div className="mt-8 flex flex-wrap gap-3">
<Button href="/signup" size="lg">Start deploying</Button>
<Button href="/demo" size="lg" variant="secondary">Book a demo</Button>
</div>
<figure className="mt-14 lg:mt-20">
<div className="overflow-clip rounded-2xl border border-line bg-surface shadow-3">
<Image src={deployShot} alt="Deploy view listing three branch previews with build times" sizes="(min-width: 1280px) 1136px, 100vw"
fetchPriority="high" loading="eager" className="h-auto w-full" />
</div>
</figure>
</Container>
</section>Frame rules: real UI, no browser chrome, no glow, no tilt. On mobile crop to the most legible region (object-left-top in a fixed aspect-[4/3] box) instead of shrinking.
1c. Typographic poster (voice-led, agency, launch)
<section aria-labelledby="hero-title" className="relative min-h-[80svh] border-b border-line">
<Container className="flex min-h-[80svh] flex-col justify-between pt-10 pb-10">
<div className="flex justify-between label-mono text-fg-muted">
<span>Studio Norte</span><span>Montevideo · est. 2014</span>
</div>
<div>
<h1 id="hero-title" className="sr-only">Studio Norte — brand and product design studio in Montevideo</h1>
<p aria-hidden="true" className="text-[clamp(3rem,1.2rem+6.2vw,6.75rem)] leading-[0.9] [font-weight:var(--weight-display)] tracking-[-0.03em] text-fg">
Brands that<br />look like<br /><span className="text-fg-muted">nobody else.</span>
</p>
<p className="mt-8 max-w-[40ch] text-lg text-fg-muted">Identity, product and web for 41 companies since 2014.</p>
</div>
<div className="flex items-end justify-between label-mono text-fg-subtle"><span>(Scroll)</span><span>Selected work ↓</span></div>
</Container>
</section>One semantic (visually hidden is fine), the visual lockup aria-hidden. Test the lockup at 320px.
1d. Split (H1 needs nuance beside it)
<Container className="grid gap-10 border-b border-line-subtle pt-16 pb-16 lg:grid-cols-12 lg:pt-32 lg:pb-24">
<h1 className="text-display-lg text-fg lg:col-span-7">Postgres with branching, for teams that ship daily.</h1>
<div className="lg:col-span-5 lg:self-end">
<p className="text-lg text-fg-muted">Every pull request gets its own database copy in under a second. Schema changes merge like code.</p>
<div className="mt-6 flex gap-3"><Button href="/signup">Start free</Button><Button href="/docs" variant="ghost">Docs</Button></div>
</div>
</Container>Centered variant: only for a ≤ 3-line H1 + ≤ 2-line sub + product UI below (Attio, Clerk). Everything after the hero goes back to left-aligned.
2. Proof strip / logo wall (only real, permitted logos)
<section aria-label="Customers" className="border-b border-line-subtle py-10 lg:py-12">
<Container className="grid items-center gap-8 lg:grid-cols-12">
<p className="text-sm text-fg-muted lg:col-span-3">Runs production deploys for 1,200 teams, including</p>
<ul className="grid grid-cols-3 items-center gap-x-10 gap-y-6 text-fg-subtle sm:grid-cols-6 lg:col-span-9">
{logos.map((l) => (
<li key={l.name} className="flex justify-center"><l.Svg aria-label={l.name} role="img" className="h-5 w-auto" /></li>
))}
</ul>
</Container>
</section>- 4–8 logos, SVG with
fill="currentColor", equal optical area (wide wordmarks shorter), no hover color bloom unless brand-mixed. - A specific claim beats "Trusted by". No real logos yet → skip the section; do not use grey placeholder logos.
- Marquee only with 12+ logos and never as the primary proof (
components→ Marquee).
3. Product showcase (one screen explains the product)
<Section aria-labelledby="showcase-title">
<Container>
<h2 id="showcase-title" className="max-w-[24ch] text-display-sm text-fg">
One timeline for every deploy. <span className="text-fg-muted">Commits, builds, errors and rollbacks in order.</span>
</h2>
<figure className="reveal mt-12 lg:mt-16">
<div className="overflow-clip rounded-2xl border border-line bg-surface shadow-3"><Image src={timeline} alt="…" sizes="(min-width:1280px) 1136px, 100vw" /></div>
<figcaption className="mt-6 grid gap-6 text-sm text-fg-muted sm:grid-cols-3">
<p><span className="text-fg">Build logs</span> stream as they run.</p>
<p><span className="text-fg">Errors</span> link to the commit that caused them.</p>
<p><span className="text-fg">Rollback</span> is one click or `/rollback` in Slack.</p>
</figcaption>
</figure>
</Container>
</Section>4. Feature deep-dive rows (alternating)
<Section aria-labelledby="features-title">
<Container>
<h2 id="features-title" className="max-w-[20ch] text-display-sm text-fg">What changes on day one</h2>
<div className="mt-16 space-y-24 lg:space-y-32">
{features.map((f, i) => (
<article key={f.slug} className="grid items-center gap-10 lg:grid-cols-12">
<div className={i % 2 ? "lg:order-2 lg:col-span-5 lg:col-start-8" : "lg:col-span-5"}>
<p className="label-mono text-fg-subtle">{String(i + 1).padStart(2, "0")} · {f.kicker}</p>
<h3 className="mt-4 text-2xl text-fg">{f.title}</h3>
<p className="mt-4 text-md text-fg-muted">{f.body}</p>
<TextLink href={f.href} className="mt-6 inline-block text-sm">{f.linkLabel}</TextLink>
</div>
<div className={i % 2 ? "lg:order-1 lg:col-span-7" : "lg:col-span-7"}>
<div className="overflow-clip rounded-xl border border-line-subtle bg-surface">{/* real UI crop, code, or diagram */}</div>
</div>
</article>
))}
</div>
</Container>
</Section>2–4 rows. Each visual shows the actual feature, cropped to the relevant 400–600px. Reveal at most the visuals, not the text.
5. Editorial capability list (no visuals, many items)
<Section aria-labelledby="services-title">
<Container className="grid gap-10 lg:grid-cols-12">
<h2 id="services-title" className="text-display-sm text-fg lg:col-span-4">What we do</h2>
<ol className="divide-y divide-line-subtle border-y border-line-subtle lg:col-span-8">
{services.map((s, i) => (
<li key={s.name} className="grid gap-2 py-6 sm:grid-cols-12 sm:gap-6">
<span className="font-mono text-sm text-fg-subtle tabular-nums sm:col-span-1">({i + 1})</span>
<h3 className="text-xl text-fg sm:col-span-4">{s.name}</h3>
<p className="text-md text-fg-muted sm:col-span-7">{s.detail}</p>
</li>
))}
</ol>
</Container>
</Section>The honest replacement for "3 icon cards". Measured on hellohello (numbered rows, 1px rules) and Anthropic.
6. Bento that isn't slop
<Section aria-labelledby="bento-title">
<Container>
<h2 id="bento-title" className="max-w-[22ch] text-display-sm text-fg">Everything the on-call engineer opens at 3 a.m.</h2>
<div className="mt-12 grid gap-4 lg:grid-cols-6 lg:grid-rows-2">
<Card className="lg:col-span-4 lg:row-span-2 p-0">{/* biggest tile = most important real UI */}</Card>
<Card className="lg:col-span-2">{/* real metric or chart */}</Card>
<Card className="lg:col-span-2">{/* real code or config */}</Card>
</div>
</Container>
</Section>- 3–6 tiles; spans follow importance; every tile shows something concrete (UI crop, number with unit, code, log).
- Tile text:
text-sm text-fg-mutedcaption +text-lg text-fgtitle. No icon-in-circle tiles. - Uneven heights → independent columns (
flex flex-col gap-4per column) instead of a stretched row grid.
7. Metrics strip (only measured numbers)
<section aria-labelledby="numbers-title" className="border-y border-line-subtle py-12 lg:py-16">
<Container>
<h2 id="numbers-title" className="label-mono text-fg-muted">Measured on production, Aug 2026</h2>
<dl className="mt-8 grid grid-cols-2 gap-px overflow-clip rounded-xl border border-line-subtle bg-line-subtle lg:grid-cols-4">
{metrics.map((m) => (
<div key={m.label} className="bg-bg p-6">
<dt className="label-mono text-fg-subtle">{m.label}</dt>
<dd className="mt-3 text-display-sm text-fg tabular-nums">{m.value}<span className="ml-1 text-xl text-fg-muted">{m.unit}</span></dd>
{m.source ? <dd className="mt-2 text-xs text-fg-subtle">{m.source}</dd> : null}
</div>
))}
</dl>
</Container>
</section>Numbers need a unit, a date/context and a source you can defend. "99.9% uptime" without a status page is fake.
8. Quote
<Section spacing="default" aria-label="Customer quote">
<Container className="grid gap-8 lg:grid-cols-12">
<figure className="lg:col-span-9 lg:col-start-3">
<blockquote className="text-3xl text-fg lg:text-4xl">
<p>“We cut our release checklist from 42 steps to 6. Nobody on the team has opened the old runbook since March.”</p>
</blockquote>
<figcaption className="mt-8 flex items-center gap-4 text-sm">
<Image src={avatar} alt="" width={40} height={40} className="size-10 rounded-full" />
<span><span className="text-fg">Dana Ortiz</span> <span className="text-fg-muted">· Staff Engineer, Northwind</span></span>
</figcaption>
</figure>
</Container>
</Section>One long specific quote > a carousel. No star ratings unless they are real reviews with a source (and then seo rules for schema).
9. How it works / install (developer products)
<Section aria-labelledby="start-title">
<Container className="grid gap-12 lg:grid-cols-12">
<div className="lg:col-span-5">
<h2 id="start-title" className="text-display-sm text-fg">Running in three commands</h2>
<p className="mt-4 text-md text-fg-muted">No account needed for local use.</p>
</div>
<ol className="space-y-6 lg:col-span-7">
{steps.map((s, i) => (
<li key={s.cmd} className="grid grid-cols-[2rem_1fr] gap-4">
<span className="font-mono text-sm text-fg-subtle tabular-nums">{i + 1}.</span>
<div>
<p className="text-md text-fg">{s.title}</p>
<pre className="mt-3 overflow-x-auto rounded-lg border border-line-subtle bg-bg-subtle px-4 py-3 font-mono text-sm text-fg"><code>{s.cmd}</code></pre>
</div>
</li>
))}
</ol>
</Container>
</Section>Add a copy button as a tiny client island. Code highlighting at build time (Shiki), never a client highlighter (speed).
10. Pricing
<Section aria-labelledby="pricing-title">
<Container>
<h2 id="pricing-title" className="text-display-sm text-fg">Pricing</h2>
<div className="mt-12 grid gap-px overflow-clip rounded-xl border border-line bg-line lg:grid-cols-3">
{plans.map((p) => (
<div key={p.name} className={cn("flex flex-col bg-bg p-6 lg:p-8", p.recommended && "bg-brand-subtle")}>
<div className="flex items-center justify-between">
<h3 className="text-xl text-fg">{p.name}</h3>
{p.recommended ? <span className="label-mono text-brand-text">Most teams</span> : null}
</div>
<p className="mt-6 text-display-sm text-fg tabular-nums">{p.price}<span className="ml-1 text-sm text-fg-muted">{p.per}</span></p>
<p className="mt-2 text-sm text-fg-muted">{p.summary}</p>
<ul className="mt-6 space-y-2 text-sm text-fg-muted">{p.features.map((f) => <li key={f}>— {f}</li>)}</ul>
<Button href={p.href} variant={p.recommended ? "primary" : "secondary"} className="mt-8">{p.cta}</Button>
</div>
))}
</div>
<p className="mt-6 text-sm text-fg-muted">Prices in USD, excluding tax. <TextLink href="/pricing#compare">Compare every limit</TextLink></p>
</Container>
</Section>No scaled-up middle card, no gradient border. Highlight = Answers start with the answer ("Yes. …", "Per build minute. …"). Accordion CSS: Repeat the primary CTA label exactly. Centering is acceptable here if the hero was left-aligned. Only links that exist. Status text only if it's wired to a real status source.bg-brand-subtle + label. Full comparison as a real (
page-types.md).
11. FAQ (real objections only)
<Section aria-labelledby="faq-title">
<Container className="grid gap-10 lg:grid-cols-12">
<h2 id="faq-title" className="text-display-sm text-fg lg:col-span-4">Questions teams ask before switching</h2>
<div className="border-t border-line-subtle lg:col-span-8">
{faqs.map((q) => (
<details key={q.q} name="faq" className="void-accordion border-b border-line-subtle py-5">
<summary className="flex cursor-pointer items-center justify-between gap-4 text-md text-fg">{q.q}</summary>
<p className="pt-3 text-md text-fg-muted">{q.a}</p>
</details>
))}
</div>
</Container>
</Section>motion/references/recipes.md §8. Keep the text in the HTML (details content is indexable).12. CTA band
<section aria-labelledby="cta-title" className="grain relative overflow-clip border-t border-line-subtle py-24 lg:py-32">
<Container className="flex flex-col items-start gap-8 lg:flex-row lg:items-end lg:justify-between">
<h2 id="cta-title" className="max-w-[18ch] text-display text-fg">Your next branch deploys itself.</h2>
<div className="flex flex-wrap gap-3"><Button href="/signup" size="lg">Start deploying</Button><Button href="/demo" size="lg" variant="ghost">Talk to an engineer</Button></div>
</Container>
</section>13. Footer
<footer className="border-t border-line-subtle pt-16 pb-10">
<Container>
<div className="grid gap-10 sm:grid-cols-2 lg:grid-cols-12">
<div className="lg:col-span-4">
<Logo className="h-5 text-fg" />
<p className="mt-4 max-w-[32ch] text-sm text-fg-muted">{site.description}</p>
</div>
{columns.map((c) => (
<nav key={c.title} aria-label={c.title} className="lg:col-span-2">
<p className="label-mono text-fg-subtle">{c.title}</p>
<ul className="mt-4 space-y-2 text-sm">{c.links.map((l) => <li key={l.href}><a href={l.href} className="text-fg-muted hover:text-fg">{l.label}</a></li>)}</ul>
</nav>
))}
</div>
<div className="mt-16 flex flex-wrap justify-between gap-4 border-t border-line-subtle pt-6 text-xs text-fg-subtle">
<p>© 2026 Acme, Inc.</p><p className="font-mono">All systems normal</p>
</div>
</Container>
</footer>
Page composition checks
py-10) → showcase (airy, py-24 lg:py-40) → rows (section-y) → metrics (dense) → CTA (airy).bg-bg-subtle bands, border-y rules) at most 2–3 times per page.