Prompt
Build a legal section: a hub page and statically generated document pages.
Stack: Next.js (App Router), React, TypeScript and Tailwind CSS v4.
DESIGN SYSTEM (use exactly):
- Page background #edeef2. Surface (light cards, light pills) #f6f6f8. Muted (gray cards) #d9d9dc. Border #dcdde2.
- Ink #1e1e1e for text, dark cards and primary buttons. Muted text #8a8a8f. Text on dark: #ffffff.
- Accents: purple #c084fc, lime #a3f207.
- Font: Geist Sans. Headings semibold with tight tracking (-0.04em) and tight leading (0.95–1.05).
- Cards: 28px corner radius. Buttons and chips: fully rounded pills (9999px).
- When a card wraps pills, its radius = pill radius + card padding (e.g. 40px pills + 8px padding → 28px card).
- Side gutter: 30px from 768px up, 20px on phones.
- Links and buttons never change color, background or opacity on hover.
DATA
- One typed file with an array of documents: Terms of Service, Privacy Policy, License Agreement, Refund Policy, Cookie Policy.
- Each document has { slug, title, summary, sections: { id, heading, body } }.
- body is an array where a string is a paragraph and a string[] is a bullet list.
- Also export one "last updated" date and a contact email.
HUB (/legals)
- Black header card (radius 28px, padding 24px; 40px from 768px): uppercase label "Legals", h1 "The fine print," / "kept simple" at clamp(2rem, 5vw, 4rem), and "Last updated …" at 60% white.
- A grid of document cards: 1 column, 2 from 768px, 3 from 1024px. Each card:
- #f6f6f8, radius 28px, padding 20px (32px from 768px), min-height 180px (220px from 768px).
- The muted summary and a diagonal arrow on top; the title at the bottom (24px, 30px from 768px, semibold).
DOCUMENT PAGE (/legals/[slug])
- Use generateStaticParams and dynamicParams = false.
- Grid: 320px sidebar and content from 1024px.
- Content: a black header card with a "← Legals" link, the title and the updated date. Then one #f6f6f8 card (padding 20px; 40px from 768px) with the sections.
- Section headings: clamp(1.375rem, 2.6vw, 2.25rem), semibold. Sections are 36px apart (56px from 768px).
- Body text: 16px on phones, 18px from 768px, 20px from 1024px, leading relaxed.
- Bullets: 6px dots (8px from 768px) in #1e1e1e.
- Give each section scroll-margin-top so anchored headings aren't hidden under sticky bars.
STICKY TOPIC NAVIGATOR (client component)
- Desktop (1024px and up): a sticky card at top 30px, max-height 100svh - 60px, scrollable. #f6f6f8, radius 28px, padding 12px.
- "On this page": a list of section pills, min 48px tall, 18px medium.
- Below a divider, "Legals": links to every document, with the current one highlighted on a #edeef2 pill.
- Phones and tablets: a sticky bar at top 0 with the page background.
- It's a single row of section pills that scrolls sideways with no visible scrollbar.
- Pills are 40px tall and 14px (44px and 16px from 768px), with a 1px border.
- It scrolls the active pill into view automatically.
- Active section: the last section whose top is within 30% of the viewport height, and the last section at the bottom of the page. The active pill is black with white text, with a 200ms color transition.
- Clicking a pill: preventDefault, scrollIntoView({ behavior: "smooth" }) and history.replaceState with the hash.