Product Design
What design decision are you making right now?
This hub is the single source of every measurable design rule in this repo. Every threshold below appears here exactly once. Other pages teach the deeper pattern but reference this table for the numbers — they never restate them. Drift starts when a rule lives in three places; the fix is one place, many readers.
Owner. This hub is the public entry point in the design authority chain. The chain runs public schema (Standards) → public hub (this page) → operational bible (
src/components/DESIGN.md) → runtime tokens (tailwind.config.jspaired withsrc/css/custom.css:root). Drift across the chain is owned by the design curator agent. Invoke the curator after any edit to one of the layers; it reports mismatches and proposes the fixes.
Design Memory — Where It Lives
Design knowledge lives in four layers. What we cannot share, are still working out, or is about planning lives inside private project state. What we think is worth sharing lives outside, split by intent: /playbook/ answers HOW, /rhetoric/ answers WHY. The running code and agent config sit beside the components themselves.
| Layer | Where | What lives there |
|---|---|---|
| Inner | private project state | What we cannot share yet, work in progress, tactical planning — per-venture and per-workchart design memory |
| How | /playbook/ (this hub + standards) | Public universal patterns, hard thresholds, schema — worth sharing |
| Why | /rhetoric/ | Public narrative — rhetoric and reflection on why these design decisions matter — worth sharing |
| Operational | src/components/DESIGN.md + tailwind.config.js + src/css/custom.css + agent skill docs | Runtime memory the agents read while building |
One file format across all four layers. The Google Labs design.md standard — YAML front matter (typed design tokens) + Markdown body (human rationale) — describes a design system to any AI agent in any tool. Schema, scope rules (system / per-venture / per-workchart / per-deck), and lint enforcement live in Design System Standards §The DESIGN.md Standard.
# Lint the operational bible before shipping
npx @google/design.md lint src/components/DESIGN.md
The Four-Pass Audit Sequence
The four-pass sequence (Rendering → Visual → Responsive → Interaction) is the canonical loop — see How to Audit a Page. Then pick the situation-specific deep dive from the router below.
Browser Canvas Storytelling
Some ideas should not stay as prose. When a page asks the reader to compare, sequence, diagnose, or hold several dimensions in working memory, climb the ladder from markdown to MDX/React and make the relationship visible.
Use this pass before component styling:
| Question | Browser-canvas move | Pass condition |
|---|---|---|
| What is the reader trying to decide? | Open with a single decision surface, not an abstract intro | A new reader can state the decision in 5 seconds |
| What relationship carries the meaning? | Choose sequence, comparison, matrix, loop, or ledger | The layout shape teaches the concept before the body copy |
| What can be collapsed into a reusable pattern? | Use Section, Container, SectionHeader, Card, Rhythm, TightFive, DataListTable, Stat | The page imports primitives before hand-rolling surfaces |
| What should the reader do next? | End with a prompt, checklist, or routed link that continues the job | The final viewport has one clear next action |
Docs rule. /playbook/ pages stay MDX. They may use JSX and design-system primitives, but they do not become .tsx pages. A visual block is justified when it reduces cognitive load, not when it merely decorates text.
Story arc for teaching pages:
Problem tension → Operating principle → Visual model → Application → Proof/loop → Next action
Use the arc flexibly. The important constraint is state change: the reader should leave with a sharper question, a simpler model, and a next move they can run.
Situation Router
| You're doing this | Use this |
|---|---|
| Deployed but something looks wrong | Audit Loop — Rendering layer |
| Making it look professional | Design Language — tokens + composition |
| Testing on phones or checking speed | Responsive + Performance |
| Ensuring everyone can use it | Interaction + Accessibility |
| Building a page that needs to convert | Landing Page Review |
| Building reusable UI components | Design Language — component hierarchy |
| Building admin/data management UI | Data Interfaces |
| Reviewing someone's work | Audit Loop — Review section |
| Building or auditing a marketplace | Marketplace Design |
| Setting up Tailwind v4 theme tokens (greenfield app) | Tailwind v4 Theme |
| Working in THIS Docusaurus repo (v3 fallback) | src/css/CLAUDE.md |
| Composing components into a system | Design Language — boundaries + composition |
| Using AI to build and review pages | Audit Loop |
| Looking for the brand identity, component inventory, landing page sequence | Design System |
Hard Thresholds — The Single Source
Every measurable design rule in this repo. The "deep dive" column says where to learn the why; the threshold here is the law.
| # | Check | Threshold | Deep dive |
|---|---|---|---|
| 1 | Contrast (body text) | ≥ 4.5:1 | a11y |
| 2 | Contrast (large text — 18px+bold or 24px+) | ≥ 3:1 | a11y |
| 3 | Contrast (UI elements + borders) | ≥ 3:1 | a11y |
| 4 | Touch target | 44×44 px (WCAG 2.2 SC 2.5.8 absolute minimum: 24×24 px) | a11y |
| 5 | Focus ring contrast | ≥ 3:1 against adjacent | a11y |
| 6 | Body text minimum | 16px at every breakpoint | perf |
| 7 | Mobile reflow | 320px viewport, zero horizontal scroll | perf |
| 8 | Line length | 45–75 characters | design-language |
| 9 | H1 per page | Exactly 1 | design-language |
| 10 | Heading hierarchy | No skipped levels (H1 → H2 → H3) | a11y |
| 11 | Visual focal point | 1 element ≥ 1.5× larger per viewport | audit-loop |
| 12 | File length (component) | ≤ 150 lines | design-language |
| 13 | Props per component | ≤ 7 (split if more) | design-language |
| 14 | Nesting depth | ≤ 3 levels | design-language |
| 15 | Prop drilling depth | ≤ 2 levels (else context or composition) | design-language |
| 16 | Composition score | > 80% library imports per page | design-language |
| 17 | Tokens in components | Zero hex literals; reference var(--*) or Tailwind token utility | design-language |
| 18 | Arbitrary Tailwind values | Forbidden (text-[#b91c1c], p-[7px]) — tokens exist | design-language |
| 19 | Modal primary actions | ≤ 2 | data-interfaces |
| 20 | Form fields — inline | 1–3 | data-interfaces |
| 21 | Form fields — modal | 4–6 (> 6 = full page or wizard) | data-interfaces |
| 22 | Modal content height | Fits viewport, no inner scroll | data-interfaces |
| 23 | Table columns visible at once | ≤ 7 | data-interfaces |
| 24 | Table row height | 40–56 px | data-interfaces |
| 25 | Row actions visible | ≤ 3 (overflow menu for more) | data-interfaces |
| 26 | Data list pagination — < 20 items | Show all | data-interfaces |
| 27 | Data list pagination — 20–100 | Paginate (10–25/page) | data-interfaces |
| 28 | Data list pagination — > 100 | Search required | data-interfaces |
| 29 | Data list pagination — > 1000 | Server-side filter + load-on-demand | data-interfaces |
| 30 | Soft-delete undo window | 10 seconds | data-interfaces |
| 31 | LCP (Largest Contentful Paint) | < 2.5s good · 2.5–4.0s needs work · > 4.0s poor | perf |
| 32 | INP (Interaction to Next Paint) | < 200ms good · 200–500ms needs work · > 500ms poor | perf |
| 33 | CLS (Cumulative Layout Shift) | < 0.1 good · 0.1–0.25 needs work · > 0.25 poor | perf |
| 34 | First Contentful Paint | < 1.5s | perf |
| 35 | Page weight total | < 1 MB | perf |
| 36 | JS transferred | < 300 KB | perf |
| 37 | CSS transferred | < 100 KB | perf |
| 38 | Image budget — total | < 500 KB | perf |
| 39 | Image budget — single image | < 200 KB | perf |
| 40 | Fonts | < 100 KB total, max 2–3 families, WOFF2, font-display: swap | perf |
| 41 | Breakpoints (no exceptions) | 375 / 768 / 1024 / 1440 px | perf |
| 42 | 5-second test | 5 of 5 readers identify what/who/action | audit-loop |
| 43 | Confirmation feedback | Visible within 200ms of action | audit-loop |
| 44 | Hover transition | 100–200ms | a11y |
| 45 | Animation duration (UI transitions) | < 400ms | a11y |
| 46 | Auto-playing animation | None except loading indicators | a11y |
| 47 | prefers-reduced-motion | All non-essential animation disabled when set | a11y |
| 48 | Color independence | Status never by colour alone — icon + text required | a11y |
| 49 | alt text on <img> | 100% coverage; decorative images carry alt="" + aria-hidden="true" | a11y |
| 50 | Form labels | Every input has <label for> or aria-label/aria-labelledby | a11y |
| 51 | Keyboard reachability | 100% of interactive elements reachable via Tab | a11y |
| 52 | Skip link | First Tab stop is "Skip to main content" | a11y |
| 53 | Landing page form fields (conversion) | 1–3 preferred; minimum-viable | landing-page |
| 54 | Landing page conversion benchmark | 2–5% good · 5–10% great | landing-page |
| 55 | CTA colour uniqueness | Reserved for clickable elements only; zero non-clickable use | landing-page |
| 56 | Teaching-page story arc | Problem → principle → visual model → application → proof/loop → action | design-language |
| 57 | Browser-canvas trigger | Use MDX/JSX when comparison, sequence, loop, matrix, or ledger carries meaning | design-language |
| 58 | Visual block purpose | Every visual block must answer a named reader question | design-language |
| 59 | Docs implementation format | /playbook/ visual pages remain .mdx; never .tsx | design-language |
| 60 | Next-action close | Final viewport contains one prompt, checklist, or routed next link | audit-loop |
| 61 | Marketplace controls | 6+ comparable items require sort/filter controls before the list | marketplace |
| 62 | Marketplace card mini-IA | Comparable cards expose the same attributes in the same order | marketplace |
| 63 | Marketplace result state | Filtered lists show result count, reset, and designed empty state | marketplace |
| 64 | Evidence-state labels | Marketplace claims label proof state: proven, validating, projected, unvalidated, or consumed | marketplace |
| 65 | Gateway destination clarity | Idea, know-how, proof, demand, and implementation routes are visibly distinct | marketplace |
Foundation Decisions
Use these tables before choosing page-specific art direction. They set the legibility floor. A custom page can be more expressive, but it must beat these defaults on contrast, hierarchy, and reading speed.
Colour Contrast Pairs
Computed from the live tokens in src/css/custom.css. AAA body text is the target for primary reading surfaces. AA is the minimum for accents, badges, and UI states.
| Use this for | Foreground token | Background token | Ratio | Decision |
|---|---|---|---|---|
| Default light body | brand-text | brand-bg | 17.15:1 | Foundation pair for warm editorial pages |
| Muted light copy | brand-muted | brand-bg | 6.85:1 | Secondary copy only; avoid long dense blocks |
| Default neutral body | ink | surface | 17.74:1 | Foundation pair for product and admin UI |
| Neutral secondary copy | ink-muted | surface | 7.56:1 | Safe for ledes, captions, and helper text |
| Cool panel body | ink | paper-cool | 16.98:1 | Use for quiet sections and checklists |
| Cool panel secondary copy | ink-muted | paper-muted | 6.87:1 | Safe secondary copy on grey panels |
| Dark section body | chalk | ink | 16.98:1 | Foundation pair for dark hero/tool surfaces |
| Dark section secondary copy | chalk-muted | ink | 12.04:1 | Safe for supporting text on dark surfaces |
| Dark section tertiary copy | chalk-subtle | ink | 6.99:1 | Labels only; too soft for important body copy |
| Brand link on light | brand-dark | surface | 8.31:1 | Preferred crimson text on light backgrounds |
| Brand accent on warm light | brand-accent | brand-bg | 5.51:1 | Use sparingly for links, labels, and accents |
| Brand accent on dark | brand-on-dark | ink | 6.41:1 | Use for short labels and calls on dark |
| Success badge | status-success | status-success-muted | 6.49:1 | Badge text only; include icon or text label |
| Warning badge | status-warning | status-warning-muted | 6.38:1 | Badge text only; include icon or text label |
| Danger badge | status-danger | status-danger-muted | 6.80:1 | Badge text only; include icon or text label |
| Info badge | status-info | status-info-muted | 7.15:1 | Badge text only; include icon or text label |
| Focus ring on light | focus | surface | 5.17:1 | Passes focus visibility |
| Focus ring on dark | focus | ink | 3.43:1 | Passes focus visibility; keep ring thick |
Font Pairing Decisions
Use at most two families for ordinary pages and three only when mono labels or data are real interface primitives. Body copy stays stable; expression belongs in the display layer.
| Situation | Heading / display | Body | Utility / data | Decision rule |
|---|---|---|---|---|
| Default product or playbook page | Inter 600-700 | Inter 400-500 | JetBrains Mono for labels only | Best foundation for maximum scan speed and low visual noise |
| Editorial or rhetoric-influenced page | Fraunces 600-700 | Inter 400-500 | JetBrains Mono for gauges/labels | Use when the page needs warmth, argument, or a strong point of view |
| Dense admin, data, or operational UI | Inter 600 | Inter 400 | JetBrains Mono for numbers/code | Use one sans family; let spacing and weight carry hierarchy |
| Hero or campaign surface | Fraunces or DM Serif Display | Inter 400-500 | Optional JetBrains Mono eyebrow | Use display type only above the fold and for short, memorable lines |
| Technical reference or code-heavy page | Inter 600 | Inter 400 | JetBrains Mono for code and tokens | Never set long prose in mono; mono is for precision, not reading |
| Bespoke visual article | Article-specific display face if justified | Inter 400-500 | JetBrains Mono for instruments | Custom type must serve the claim and preserve body readability |
The Five-Question Audit (run on every page)
These five questions sit upstream of every checklist. If a page fails any of them, the checklists are decoration.
- Who is this for? A specific person — not "everyone."
- What do they need to know? One essential piece, not five.
- What do they need to do? One clear action, not a menu.
- Why should they trust us? Specific proof, not adjectives.
- What's stopping them? A real objection, named and answered.
If you cannot answer all five in plain prose before opening DevTools, no audit will save the page.
Tailwind: This Repo vs Greenfield Apps
The v3/v4 comparison and the principle behind both lives in Design Language — Tailwind mechanism per context.
Context
- Dreamineering Design System (live reference)
- Process Optimisation — checklists as expert tools
- Value Speed — speed as a design principle
- Standards — why measurable thresholds matter