Date: 2026-05-14
Project: Sub-project B of a two-part effort. (Sub-project A — responsive pass on all v3 pages — is complete.)
Worktree: /Users/maximilianbrandstaetter/Orcha/.claude/worktrees/website-v3-mobile-responsive, branch website-v3-mobile-responsive.
The v3 website uses far too many distinct values — 39 font sizes, ~38 spacing values, ~15 border-radii, raw hex colors that duplicate existing tokens, and ~5 icon sizes. Define a constrained design-token system covering type, color, icons, spacing, and radius; codify it as CSS custom properties; and migrate the entire v3 site (shared CSS + every page's inline styles) to use it — so the site has a small, defined set of values instead of organic sprawl, with no meaningful visual change.
clamp().--sans and --mono already defined (--serif is an unused alias of --sans).:root token set already exists — but it is defined twice (in v3.css and product.css) and inconsistently used. Raw hexes leak in: many duplicate existing tokens (#006EC7=--accent ×12, #f5f3ee=--bg-2, #5a5a56=--ink-3, #dcd7cb=--line, …); a 5-color categorical pastel palette (#D49B70 #BC7B95 #A185BB #7A9BC0 #6DAF9F) has no tokens; a handful of genuinely-new colors (#fafaf6, #eceae3, #1a1a1a, …) have no tokens; #8627 (×9) is a malformed hex.padding/gap/margin px values; mass in 2–40px, long tail to 140px.--radius: 10px token exists but is rarely used; 999px pill is common.Data-driven snap. Each token scale is derived by keeping the well-used values from the existing distribution and dropping the half-pixels and one-offs. Migration replaces every raw value with its nearest token. Because the kept values are the dominant ones, the overwhelming majority of usages do not move at all; outliers shift by 1–4px at most. The site looks essentially unchanged — it just has a small defined set of values.
Rejected: a fresh modular scale (textbook-cleaner, but full migration would visibly redesign a site that was just made responsive); tokens-without-migration (the user explicitly chose full migration).
www/v3/css/tokens.css — one canonical :root holding every token scale. Linked first on all 30 pages (before v3.css), so it is the base layer.:root blocks in v3.css and product.css are removed — tokens.css is the single source of truth. (Existing token names — --bg, --ink, --accent, --sans, etc. — are preserved so nothing downstream breaks; new scales are added alongside.)var(--token).Values below are the proposed scales — derived from the audit distribution, optimized for minimal drift. They are the primary thing to scrutinize in the spec review.
--text-* (11 discrete steps + display): 9, 10, 11, 12, 13, 14, 15, 16, 19, 24, 32 px. These are the well-used integer sizes (each ≥10 uses, together ~90% of all usage) — kept as-is so they don't move. Display headings keep clamp()-based tokens (--text-display-s/m/l). Snap rule for the rest: each dropped value → nearest kept step (half-pixels collapse: 10.5→11, 9.5→10, 13.5→14, …; one-offs: 17→16, 18→19, 20→19, 22→24, 26→24, 28→32, 30→32, 36→32; 44/48/60/80/88/96 → the display tokens). Open for review: whether to merge the dense 12/13/14/15/16 cluster further (tighter, but moves hundreds of usages).--weight-{regular,medium,semibold}: 400 / 500 / 600. The stray 700 → 600.--sans, --mono. Drop the unused --serif alias.:root. Keep all existing semantic tokens. Add --cat-1…5 for the categorical pastel palette. Genuinely-new colors get named tokens only if used ≥2× with intent, otherwise snap to the nearest existing token. Every raw hex in CSS + pages is replaced with var(--token). Fix #8627. Open for review: the names/values for the categorical palette and any new neutrals.--icon-{sm,md,lg}: 14 / 16 / 18 px (covers the real cluster; 12→14, 13→14). Stroke-width consolidated to --icon-stroke (1.6) and --icon-stroke-bold (1.8); the 1.4/1.5 etc. snap. Open for review: whether 12px deserves its own step.--space-* (~14 steps): 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 64, 80, 120 px. Keeps the heavily-used fine-grained low end; drops 14/18/22/28/36/56/72/etc. → nearest. Open for review: this is the hardest scale — spacing usage is the most spread out; a tighter scale is possible but drifts more padding/gap values.--radius-* (6 steps): 2, 4, 8, 12, 16, 999 (pill). The existing --radius: 10px → --radius-md (12) or kept at 10; 14→12 or 16; etc. Open for review: whether to keep 10px given its frequency.Snap-to-nearest, applied site-wide, staged (mirroring sub-project A's structure):
tokens.css; link it first on all 30 pages; remove the duplicate :root blocks; migrate v3.css, product.css, responsive.css, trial.css to var(--token).style= attributes and in-body <style> blocks across all 30 pages — homepage (de+en) → product pages (de+en) → section pages (de+en). de/en mirrors take the same edits.One spec; writing-plans produces the staged plans.
Extend www/v3/dev/screenshot.mjs into a visual-regression tool:
This replaces the old harness's overflow-only check with a true before/after comparison, which is what a token migration needs.
www/v3/css/tokens.css exists, is linked first on all 30 pages, and is the single :root source (no :root left in v3.css/product.css).var(--token) reference or one of the defined scale values — no raw hexes, no half-pixel font sizes, no off-scale values.tokens.css with clear comments is the guide).clamp() headings — display headings use clamp(min, vw, max); these get --text-display-* tokens but the clamp() expressions themselves must be preserved, not flattened.color-mix() usage — much of the CSS uses color-mix(in oklab, var(--token), …); migration must keep these intact, only replacing raw-hex inputs.