---
feature: DesignTokenSystem
date: 2026-05-26
status: planned
project: crash-test-dev
tags: [tokens, system, color, typography, spacing, layout]
related: [AESTHETIC-GUIDE.md]
---
# Design Token System — Crash Test Dev
## User's Spark (preserved)
> A well-used workshop. Not a pristine showroom — the one where someone actually builds things.
> Tools are organized because disorganization wastes time. The wood has warmth.
> The light is good because you need to see details. There's a coffee cup somewhere.
**Metaphor:** The workbench, not the gallery.
**Materials vocabulary:** Paper, ink, wood, stone, iron.
**Personality:** Dry warmth. Quiet confidence. Evidence over performance.
---
## Complete Token System
```json
{
"colors": {
"_meta": {
"temperature": "warm across all values — no blue-grays, no cool neutrals",
"philosophy": "Aged paper, brown-black ink, fired earth, tarnished brass. Every color drawn from the workbench vocabulary: materials that have been used, heated, and cooled."
},
"surface": {
"base": { "value": "#F5F0E8", "description": "Page background. Heavy unbleached paper stock — warm off-white, not pure white, not yellow." },
"card": { "value": "#FEFCF7", "description": "Reading surface. White card stock laid on the paper base — for article bodies, elevated panels." },
"code": { "value": "#EEEAE2", "description": "Code block background. Heavier paper weight — subtle warm-gray shift from prose background." },
"inset": { "value": "#E8E3DA", "description": "Callout/aside background. Slightly recessed surface, like a different stock weight." }
},
"text": {
"primary": { "value": "#2B2421", "description": "Body text. Warm near-black — brown-black ink, NOT blue-black digital default.", "contrastOnBase": "13.44:1 (AAA)", "contrastOnCard": "14.87:1 (AAA)" },
"secondary": { "value": "#6B5F55", "description": "Metadata, captions, bylines. Warm mid-gray with stone undertone.", "contrastOnBase": "5.46:1 (AA)", "contrastOnCard": "6.04:1 (AA)" },
"tertiary": { "value": "#948880", "description": "Timestamps, tags, disabled text. Lighter warm gray.", "contrastOnBase": "3.04:1 (AA-UI)", "contrastOnCard": "3.36:1 (AA-UI)" }
},
"accent": {
"primary": { "value": "#A0522D", "description": "Links, emphasis, code block left-edge accent. Muted terracotta/sienna — fired earth, not bright red.", "contrastOnBase": "4.95:1 (AA)", "contrastOnCard": "5.48:1 (AA)" },
"primaryHover": { "value": "#8B4726", "description": "Link hover state. Darker rust — the terracotta after more firing.", "contrastOnBase": "6.12:1 (AA)" },
"secondary": { "value": "#7D6C2F", "description": "Special callouts, highlights. Tarnished brass/dark gold — aged metal.", "contrastOnBase": "4.56:1 (AA)", "contrastOnCard": "5.05:1 (AA)" },
"secondaryHover": { "value": "#6B5C28", "description": "Brass hover state. Darker, more patinated." }
},
"code": {
"text": { "value": "#3D342E", "description": "Code text. Warm dark brown, slightly lighter than body text for the different register.", "contrastOnCode": "10.12:1 (AAA)" }
},
"border": {
"subtle": { "value": "#DDD7CD", "description": "Decorative score lines, faint dividers. Barely there — like a fold in paper. No contrast requirement (decorative)." },
"default": { "value": "#C2BAA9", "description": "General-purpose separators, card edges. Visible but quiet." },
"strong": { "value": "#8E857A", "description": "Functional UI borders (form inputs, focused elements). Meets 3:1 on both base and card.", "contrastOnBase": "3.20:1 (AA-UI)", "contrastOnCard": "3.54:1 (AA-UI)" }
},
"focus": {
"ring": { "value": "#A0522D", "description": "Keyboard focus indicator. Terracotta — visible, warm, consistent with accent.", "contrastOnBase": "4.95:1 (AA-UI)" }
},
"state": {
"success": {
"bg": { "value": "#E8EDDF", "description": "Warm sage green tint." },
"text": { "value": "#4A5E3A", "description": "Dark moss green.", "contrastOnBg": "5.96:1 (AA)" },
"border": { "value": "#B5C4A0", "description": "Muted sage border." }
},
"warning": {
"bg": { "value": "#F2E8D0", "description": "Warm amber tint." },
"text": { "value": "#7A5C1F", "description": "Dark warm amber.", "contrastOnBg": "5.10:1 (AA)" },
"border": { "value": "#D4BC7C", "description": "Muted gold border." }
},
"error": {
"bg": { "value": "#F2DED6", "description": "Warm rose/clay tint." },
"text": { "value": "#8B3A2A", "description": "Dark terracotta.", "contrastOnBg": "5.92:1 (AA)" },
"border": { "value": "#CFA090", "description": "Muted clay border." }
},
"info": {
"bg": { "value": "#E5E2DA", "description": "Warm neutral tint." },
"text": { "value": "#4A4540", "description": "Warm dark gray.", "contrastOnBg": "7.32:1 (AAA)" },
"border": { "value": "#B8B2A8", "description": "Warm mid gray border." }
}
},
"shadow": {
"color": { "value": "rgba(43, 36, 33, 0.06)", "description": "Warm-toned shadow base. Derived from text-primary. Barely-there desk shadow." }
}
},
"typography": {
"_meta": {
"philosophy": "Three voices, three jobs. Serif for prose (Ken's voice). Sans for structure (navigation, headings). Mono for evidence (code, proof). The reader always knows which voice is speaking.",
"scaleRatio": 1.25,
"scaleName": "Major Third",
"scaleBase": "18px"
},
"families": {
"prose": { "value": "'Source Serif 4', 'Source Serif Pro', Georgia, 'Times New Roman', serif", "role": "Reading voice — body text, blockquotes, long-form prose" },
"structure": { "value": "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", "role": "Navigation voice — headings, UI labels, metadata" },
"evidence": { "value": "'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace", "role": "Proof voice — code blocks, terminal output, file paths" }
},
"scale": {
"xs": { "value": "0.75rem", "px": 12, "step": -2, "use": "footnotes, legal text" },
"sm": { "value": "0.875rem", "px": 14, "step": -1, "use": "captions, meta, timestamps, tags" },
"base": { "value": "1.125rem", "px": 18, "step": 0, "use": "body prose" },
"lg": { "value": "1.375rem", "px": 22, "step": 1, "use": "h4 headings" },
"xl": { "value": "1.75rem", "px": 28, "step": 2, "use": "h3 headings" },
"2xl": { "value": "2.25rem", "px": 36, "step": 3, "use": "h2 headings — section titles" },
"3xl": { "value": "2.75rem", "px": 44, "step": 4, "use": "h1 headings — article title" }
},
"lineHeight": {
"tight": { "value": 1.15, "use": "display headings (h1)" },
"snug": { "value": 1.25, "use": "headings (h2, h3)" },
"heading": { "value": 1.35, "use": "smaller headings (h4)" },
"normal": { "value": 1.5, "use": "UI text, captions" },
"relaxed": { "value": 1.6, "use": "code blocks, blockquotes" },
"prose": { "value": 1.7, "use": "body prose — generous for dense technical narrative" }
},
"weight": {
"regular": { "value": 400, "use": "body prose, code" },
"medium": { "value": 500, "use": "UI labels, caption emphasis" },
"semibold": { "value": 600, "use": "headings, inline emphasis in prose" },
"bold": { "value": 700, "use": "h1 title, strong emphasis" }
},
"styles": {
"body": {
"fontFamily": "prose",
"fontSize": "1.125rem",
"fontWeight": 400,
"lineHeight": 1.7,
"letterSpacing": "normal",
"description": "Ken's voice on the page. 18px Source Serif 4 at generous line-height for sustained technical reading."
},
"bodySmall": {
"fontFamily": "prose",
"fontSize": "0.875rem",
"fontWeight": 400,
"lineHeight": 1.6,
"letterSpacing": "0.005em",
"description": "Footnotes, secondary prose passages. Still serif — still Ken's voice, just quieter."
},
"h1": {
"fontFamily": "structure",
"fontSize": "2.75rem",
"fontWeight": 700,
"lineHeight": 1.15,
"letterSpacing": "-0.02em",
"description": "Article title. 44px Inter Bold — confident, unhurried. Negative tracking tightens at display size."
},
"h2": {
"fontFamily": "structure",
"fontSize": "2.25rem",
"fontWeight": 600,
"lineHeight": 1.25,
"letterSpacing": "-0.015em",
"description": "Section heading. 36px Inter Semibold — chapter breaks in the narrative."
},
"h3": {
"fontFamily": "structure",
"fontSize": "1.75rem",
"fontWeight": 600,
"lineHeight": 1.3,
"letterSpacing": "-0.01em",
"description": "Subsection heading. 28px Inter Semibold — organizes without competing with prose."
},
"h4": {
"fontFamily": "structure",
"fontSize": "1.375rem",
"fontWeight": 600,
"lineHeight": 1.35,
"letterSpacing": "-0.005em",
"description": "Minor heading. 22px Inter Semibold — just enough hierarchy shift to signal structure."
},
"blockquote": {
"fontFamily": "prose",
"fontSize": "1.25rem",
"fontWeight": 400,
"lineHeight": 1.6,
"letterSpacing": "normal",
"fontStyle": "italic",
"description": "Pull quotes, cited text. 20px Source Serif 4 italic — a gentle size step up signals 'someone else's words' without shouting."
},
"caption": {
"fontFamily": "structure",
"fontSize": "0.875rem",
"fontWeight": 500,
"lineHeight": 1.5,
"letterSpacing": "0.01em",
"description": "Image captions, metadata labels, timestamps, tags. 14px Inter Medium — the structure voice at small scale."
},
"codeInline": {
"fontFamily": "evidence",
"fontSize": "0.9em",
"fontWeight": 400,
"lineHeight": "inherit",
"letterSpacing": "normal",
"description": "Inline code within prose. 0.9em relative to parent — the evidence voice embedded in narrative."
},
"codeBlock": {
"fontFamily": "evidence",
"fontSize": "1rem",
"fontWeight": 400,
"lineHeight": 1.6,
"letterSpacing": "normal",
"description": "Code blocks. 16px JetBrains Mono — factual, verifiable, this-is-what-actually-happened."
}
}
},
"spacing": {
"_meta": {
"base": "8px",
"philosophy": "The page breathes like a well-set book. Generous vertical rhythm for dense technical narrative. Space above H2 is a full breath — section breaks are chapter breaks."
},
"scale": {
"0": { "value": "0", "px": 0 },
"px": { "value": "1px", "px": 1 },
"0.5":{ "value": "0.25rem", "px": 4, "gridMultiple": "0.5x" },
"1": { "value": "0.5rem", "px": 8, "gridMultiple": "1x" },
"1.5":{ "value": "0.75rem", "px": 12, "gridMultiple": "1.5x" },
"2": { "value": "1rem", "px": 16, "gridMultiple": "2x" },
"2.5":{ "value": "1.25rem", "px": 20, "gridMultiple": "2.5x" },
"3": { "value": "1.5rem", "px": 24, "gridMultiple": "3x" },
"4": { "value": "2rem", "px": 32, "gridMultiple": "4x" },
"5": { "value": "2.5rem", "px": 40, "gridMultiple": "5x" },
"6": { "value": "3rem", "px": 48, "gridMultiple": "6x" },
"8": { "value": "4rem", "px": 64, "gridMultiple": "8x" },
"10": { "value": "5rem", "px": 80, "gridMultiple": "10x" },
"12": { "value": "6rem", "px": 96, "gridMultiple": "12x" }
},
"semantic": {
"paragraphGap": { "value": "1.5rem", "px": 24, "note": "~1.33em at 18px body. Generous — lets ideas land." },
"headingAboveH2": { "value": "4rem", "px": 64, "note": "Section breaks are chapter breaks. Full breath between sections." },
"headingBelowH2": { "value": "1rem", "px": 16, "note": "Tight — the heading belongs to its content, not the space above." },
"headingAboveH3": { "value": "2.5rem", "px": 40, "note": "Sub-section breath. Less than H2, still generous." },
"headingBelowH3": { "value": "0.75rem", "px": 12, "note": "Snug — content follows immediately." },
"headingAboveH4": { "value": "2rem", "px": 32, "note": "Minor heading spacing." },
"headingBelowH4": { "value": "0.5rem", "px": 8, "note": "Very tight — H4 is almost inline with its content." },
"codeBlockVertical": { "value": "2.5rem", "px": 40, "note": "Code blocks as exhibited artifacts — generous vertical clearance." },
"codeBlockPadding": { "value": "1.5rem", "px": 24, "note": "Internal padding of code blocks." },
"codeBlockAccentWidth": { "value": "3px", "note": "Left-edge accent line on code blocks." },
"listItemGap": { "value": "0.5rem", "px": 8, "note": "Breathing room between list items." },
"blockquoteIndent": { "value": "1.5rem", "px": 24, "note": "Left indent/border offset for blockquotes." },
"sectionDivider": { "value": "3rem", "px": 48, "note": "Vertical space when using a horizontal rule." }
}
},
"rounded": {
"_meta": {
"philosophy": "Workshop surfaces have worn edges, not machined radii. Just enough softness to not feel sharp, not enough to feel 'designed.'"
},
"none": { "value": "0" },
"sm": { "value": "2px", "use": "inline code, small tags, badges" },
"md": { "value": "4px", "use": "code blocks, buttons, small elements" },
"lg": { "value": "6px", "use": "cards, callout boxes" },
"xl": { "value": "8px", "use": "larger panels, modals (if ever needed)" },
"full": { "value": "9999px", "use": "pills, avatars, toggle tracks" }
},
"layout": {
"_meta": {
"philosophy": "Prose lives in a reading column. Code breaks wider. The width shift signals the register change from narrative to evidence."
},
"prose": { "value": "45rem", "px": 720, "approxCh": "~65ch at 18px serif", "description": "Reading column max-width. Sweet spot for sustained reading." },
"codeBreak": { "value": "52.5rem", "px": 840, "description": "Code block max-width. Wider breakout creates narrow-wide-narrow rhythm." },
"container": { "value": "68.75rem","px": 1100, "description": "Outer container max-width. Provides margin for the prose column." },
"sideGutter": { "value": "1.5rem", "px": 24, "description": "Minimum horizontal padding on small screens." }
},
"shadows": {
"_meta": {
"philosophy": "Nothing gleams. Nothing floats. If something casts a shadow, it's the small soft shadow of a card sitting on a desk — barely there."
},
"sm": { "value": "0 1px 3px rgba(43, 36, 33, 0.04)", "use": "Subtle lift — barely perceptible. Cards at rest." },
"md": { "value": "0 2px 8px rgba(43, 36, 33, 0.06)", "use": "Card on a desk — the maximum depth in this system." },
"none": { "value": "none", "use": "Explicit no-shadow override." }
},
"motion": {
"_meta": {
"philosophy": "Fast, barely-there. The confidence of something that doesn't need to announce itself. Reduce to zero for prefers-reduced-motion."
},
"duration": {
"instant": { "value": "0ms", "use": "Reduced motion fallback." },
"fast": { "value": "100ms", "use": "Color transitions (hover, focus)." },
"normal": { "value": "150ms", "use": "Standard interactions — the site's default." },
"slow": { "value": "250ms", "use": "Layout shifts, expand/collapse (rare)." }
},
"easing": {
"default": { "value": "cubic-bezier(0.25, 0.1, 0.25, 1.0)", "use": "Standard ease — smooth, natural deceleration." },
"inOut": { "value": "cubic-bezier(0.45, 0.05, 0.55, 0.95)", "use": "Symmetric transitions." }
},
"reducedMotion": {
"rule": "@media (prefers-reduced-motion: reduce)",
"behavior": "All durations set to 0ms. All transitions disabled. Non-negotiable."
}
},
"rationale": {
"colorPhilosophy": {
"title": "Why these specific colors",
"explanation": [
"The surface-base (#F5F0E8) was tuned to sit precisely between 'warm' and 'yellow.' Its RGB channels (245, 240, 232) taper from R→G→B, placing the warmth in the red channel without letting it become cream or beige. It reads as 'good light on heavy paper' — the brief's exact intent.",
"Text-primary (#2B2421) avoids the blue-black of browser defaults (which typically live around #1a1a2e or #333). The brown-black comes from keeping R > G > B at the dark end: (43, 36, 33). This is ink with warmth, not ink with coldness.",
"The accent-primary (#A0522D, CSS 'sienna') is a historically grounded earth pigment — literally fired earth. At 4.95:1 contrast on base, it passes AA for body text and works as link color without being 'red' or 'alarming.' The hover state (#8B4726) darkens toward the earth rather than toward black.",
"Accent-secondary (#7D6C2F) captures tarnished brass — the green-gold of aged copper alloy, not the bright gold of decoration. It needed darkening from the first candidate to meet AA (4.56:1), but the constraint improved the color: real tarnished brass IS darker than you'd first guess.",
"State colors (success, warning, error, info) were designed within the warm palette. No saturated primaries. Success uses sage-moss (#4A5E3A on #E8EDDF), warning uses amber (#7A5C1F on #F2E8D0), error uses deeper terracotta (#8B3A2A on #F2DED6). Even the info state avoids blue entirely — it's warm neutral (#4A4540 on #E5E2DA)."
]
},
"contrastStrategy": {
"title": "How we exceeded WCAG requirements",
"explanation": [
"The brief demanded WCAG AAA (7:1) for body text on base. We achieved 13.44:1 — nearly double the requirement. This provides comfortable reading even in imperfect lighting conditions or on devices with lower contrast ratios.",
"Secondary text at 5.46:1 (AA requires 4.5:1) gives comfortable headroom. Tertiary text at 3.04:1 meets AA-UI (3:1) — appropriate since it's used only for supplementary information like timestamps and tags, never for essential content.",
"Code text (#3D342E) on the code surface (#EEEAE2) achieves 10.12:1 (AAA). Code is evidence — it must be maximally readable.",
"Border tokens are split into three tiers: subtle (decorative, no contrast requirement — the 'score line'), default (separators), and strong (#8E857A at 3.20:1, for functional UI elements). This acknowledges that a publishing site's dividers are decorative, not interactive, while still providing accessible borders when needed."
]
},
"typographyRationale": {
"title": "Three voices, mathematically grounded",
"explanation": [
"The Major Third ratio (1.25) was chosen because the brief explicitly asked for conservative hierarchy. At 1.25, the jump from body (18px) to H4 (22px) is perceptible but not dramatic — the family change from serif to sans does most of the work. Weight and family, not size, create the hierarchy.",
"Heading sizes round to clean values: 22, 28, 36, 44px. Each pair's ratio stays within 1.17-1.29 of true Major Third — close enough for mathematical coherence, rounded enough for pixel clarity.",
"The 18px body base was set by the brief, and it's correct for sustained technical reading in a serif face. At 1.125rem, it inherits browser zoom gracefully.",
"Code at 16px (1rem / 0.9em of body) respects the 'different register' described in the aesthetic guide. JetBrains Mono at 16px with 1.6 line-height gives comfortable code reading without competing with the prose voice.",
"Letter-spacing uses negative tracking for headings (-0.02em at h1, tapering to -0.005em at h4) because Inter at display sizes needs tightening to feel intentional. Body prose and code use normal tracking — the fonts were designed for these sizes.",
"Blockquote at 20px italic is the only off-scale value — sitting between base (18) and lg (22). This is deliberate: a pull quote should feel like a different register, not a heading. The italic + size shift + left border treatment (defined in spacing) makes the voice unmistakable."
]
},
"spacingRationale": {
"title": "Book typography meets code breakout",
"explanation": [
"The 8px grid provides the full range from fine-grain (4px component padding) to macro (96px section spacing). All semantic tokens map onto grid multiples.",
"H2 above-spacing (64px / 4rem) creates the 'chapter break' the aesthetic guide describes. At nearly 4x the paragraph gap, it creates a decisive pause in the scroll. H2 below-spacing (16px / 1rem) is deliberately tight — the heading belongs to what follows, not what precedes it.",
"Paragraph gap (24px) is ~1.33em at 18px base — within the 1.2-1.5em range specified, and landing on the 8px grid (3x base).",
"Code block vertical margin (40px / 2.5rem) positions code as 'exhibited artifacts' — clearly separated from prose without creating visual gaps. The 3px left accent line in terracotta signals the register change from narrative to evidence.",
"The prose column at 720px (45rem) produces ~65 characters per line at 18px Source Serif 4 — the typographic sweet spot for sustained reading. Code breaks to 840px (52.5rem) creating the narrow-wide-narrow rhythm described in the aesthetic guide."
]
},
"borderRadiusRationale": {
"title": "Worn edges, not machined radii",
"explanation": [
"Four meaningful stops: 2px (inline code), 4px (code blocks, buttons), 6px (cards), 8px (larger panels). The progression feels like increasingly worn edges on workshop materials — slight softening, never roundness.",
"No radius exceeds 8px except 'full' (pills/avatars). Nothing on this site should look like a mobile app button or a glassmorphism card."
]
},
"motionRationale": {
"title": "Fast, barely-there, respectful",
"explanation": [
"150ms is the site's default transition — fast enough to feel instant, slow enough to not be jarring. Color transitions (hover, focus) at 100ms. Layout transitions at 250ms (rare — this is a reading site, not an app).",
"prefers-reduced-motion reduces all durations to 0ms, no exceptions. This is non-negotiable.",
"Only GPU-accelerated properties (transform, opacity) should be animated. Color transitions are the exception — they're so fast (100ms) that the CPU cost is negligible."
]
},
"whatWeDidNotDo": {
"title": "Intentional omissions",
"explanation": [
"No dark mode tokens. The aesthetic guide explicitly says 'Ken's work happens in daylight.' Dark mode can be added later if needed — the semantic naming makes it straightforward.",
"No elevation system. The brief says 'nothing floats.' Two shadow tokens (sm, md) are the maximum depth vocabulary.",
"No animation choreography. A publishing site doesn't need entrance animations, scroll-triggered effects, or page transitions. Links change color. That's it.",
"No breakpoint tokens. The layout is a single column that narrows gracefully. The prose column (720px) and code breakout (840px) handle their own responsive behavior within the 1100px container.",
"No z-index scale. Nothing overlaps. The page is flat paper with ink on it."
]
}
}
}
```
---
## Contrast Audit Results
Every text/background pairing was tested computationally. Full results:
### Body Text (WCAG AAA — 7:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `text-primary` (#2B2421) on `surface-base` (#F5F0E8) | **13.44:1** | PASS |
| `text-primary` (#2B2421) on `surface-card` (#FEFCF7) | **14.87:1** | PASS |
| `text-primary` (#2B2421) on `surface-code` (#EEEAE2) | **12.71:1** | PASS |
| `text-primary` (#2B2421) on `surface-inset` (#E8E3DA) | **11.93:1** | PASS |
### Secondary Text (WCAG AA — 4.5:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `text-secondary` (#6B5F55) on `surface-base` (#F5F0E8) | **5.46:1** | PASS |
| `text-secondary` (#6B5F55) on `surface-card` (#FEFCF7) | **6.04:1** | PASS |
| `text-secondary` (#6B5F55) on `surface-code` (#EEEAE2) | **5.16:1** | PASS |
### Tertiary Text (WCAG AA UI — 3:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `text-tertiary` (#948880) on `surface-base` (#F5F0E8) | **3.04:1** | PASS |
| `text-tertiary` (#948880) on `surface-card` (#FEFCF7) | **3.36:1** | PASS |
### Accent Links (WCAG AA — 4.5:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `accent-primary` (#A0522D) on `surface-base` (#F5F0E8) | **4.95:1** | PASS |
| `accent-primary` (#A0522D) on `surface-card` (#FEFCF7) | **5.48:1** | PASS |
| `accent-primary` (#A0522D) on `surface-code` (#EEEAE2) | **4.68:1** | PASS |
| `accent-primaryHover` (#8B4726) on `surface-base` (#F5F0E8) | **6.12:1** | PASS |
| `accent-secondary` (#7D6C2F) on `surface-base` (#F5F0E8) | **4.56:1** | PASS |
| `accent-secondary` (#7D6C2F) on `surface-card` (#FEFCF7) | **5.05:1** | PASS |
### Code Text (WCAG AAA — 7:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `code-text` (#3D342E) on `surface-code` (#EEEAE2) | **10.12:1** | PASS |
### State Colors (WCAG AA — 4.5:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `success-text` (#4A5E3A) on `success-bg` (#E8EDDF) | **5.96:1** | PASS |
| `warning-text` (#7A5C1F) on `warning-bg` (#F2E8D0) | **5.10:1** | PASS |
| `error-text` (#8B3A2A) on `error-bg` (#F2DED6) | **5.92:1** | PASS |
| `info-text` (#4A4540) on `info-bg` (#E5E2DA) | **7.32:1** | PASS |
### Functional Borders (WCAG AA UI — 3:1 required)
| Pairing | Ratio | Result |
|---|---|---|
| `border-strong` (#8E857A) on `surface-base` (#F5F0E8) | **3.20:1** | PASS |
| `border-strong` (#8E857A) on `surface-card` (#FEFCF7) | **3.54:1** | PASS |
**Note:** `border-subtle` and `border-default` are decorative (score lines, separators) and do not carry WCAG contrast requirements per [WCAG 1.4.11 Non-text Contrast](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html) — decorative borders that don't convey information are exempt. `border-strong` is provided for any functional UI borders that DO need 3:1.
---
## Implementation Notes
### CSS Custom Properties (recommended structure)
```css
:root {
/* Surfaces */
--surface-base: #F5F0E8;
--surface-card: #FEFCF7;
--surface-code: #EEEAE2;
--surface-inset: #E8E3DA;
/* Text */
--text-primary: #2B2421;
--text-secondary: #6B5F55;
--text-tertiary: #948880;
/* Accents */
--accent-primary: #A0522D;
--accent-primary-hover: #8B4726;
--accent-secondary: #7D6C2F;
--accent-secondary-hover: #6B5C28;
/* Code */
--code-text: #3D342E;
/* Borders */
--border-subtle: #DDD7CD;
--border-default: #C2BAA9;
--border-strong: #8E857A;
/* Focus */
--focus-ring: #A0522D;
/* State: Success */
--success-bg: #E8EDDF;
--success-text: #4A5E3A;
--success-border: #B5C4A0;
/* State: Warning */
--warning-bg: #F2E8D0;
--warning-text: #7A5C1F;
--warning-border: #D4BC7C;
/* State: Error */
--error-bg: #F2DED6;
--error-text: #8B3A2A;
--error-border: #CFA090;
/* State: Info */
--info-bg: #E5E2DA;
--info-text: #4A4540;
--info-border: #B8B2A8;
/* Shadows */
--shadow-sm: 0 1px 3px rgba(43, 36, 33, 0.04);
--shadow-md: 0 2px 8px rgba(43, 36, 33, 0.06);
/* Typography families */
--font-prose: 'Source Serif 4', 'Source Serif Pro', Georgia, 'Times New Roman', serif;
--font-structure: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-evidence: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace;
/* Spacing */
--space-0: 0;
--space-px: 1px;
--space-0-5: 0.25rem;
--space-1: 0.5rem;
--space-1-5: 0.75rem;
--space-2: 1rem;
--space-2-5: 1.25rem;
--space-3: 1.5rem;
--space-4: 2rem;
--space-5: 2.5rem;
--space-6: 3rem;
--space-8: 4rem;
--space-10: 5rem;
--space-12: 6rem;
/* Border radius */
--rounded-none: 0;
--rounded-sm: 2px;
--rounded-md: 4px;
--rounded-lg: 6px;
--rounded-xl: 8px;
--rounded-full: 9999px;
/* Layout */
--width-prose: 45rem;
--width-code: 52.5rem;
--width-container: 68.75rem;
--gutter: 1.5rem;
/* Motion */
--duration-fast: 100ms;
--duration-normal: 150ms;
--duration-slow: 250ms;
--ease-default: cubic-bezier(0.25, 0.1, 0.25, 1.0);
--ease-in-out: cubic-bezier(0.45, 0.05, 0.55, 0.95);
}
@media (prefers-reduced-motion: reduce) {
:root {
--duration-fast: 0ms;
--duration-normal: 0ms;
--duration-slow: 0ms;
}
}
```
### Font Loading (recommended)
```html
```
---
## Success Criteria
- **Functional:** All tokens resolve to concrete CSS values. Zero undefined variables.
- **Aesthetic:** Every color reads warm. The page feels like paper and ink under good light.
- **Accessibility:** AAA body text (13.44:1), AA secondary (5.46:1), AA accent links (4.95:1). All verified.
- **Performance:** Three fonts, minimal weights. No heavy shadow/blur calculations.
- **Longevity:** Nothing here will look dated in 5 years. Paper, ink, and careful spacing don't go out of style.