Five surfaces, one lattice.
A token model is a claim until something is built with it. Four of these surfaces are built entirely from the semantic layer — no bespoke values, no per-surface overrides — and two of them run brand forks to prove the palette can change without the geometry noticing. The fifth has no CSS variables at all, and is the one that decides whether any of this is a real abstraction.
How to read these
Each showcase page carries the same four things.
On every page
- The surface itself, live and interactive, inside a frame.
- A density switch. The surface is scoped to the tier it was designed for, but you can change it and watch the whole thing re-derive.
- The fork. The exact CSS that produced its palette — usually under twenty lines.
- What it stresses, and what broke or nearly broke while building it.
What none of them do
- No new tokens. Nothing was added to the system to make these work.
- No raw values. Every dimension resolves through the semantic layer.
- No component forks. The button on the marketing page is the button in the dashboard.
- No pattern above 10%. Including the marketing hero, where it was tempting.
Email and print are the exception to all four: they cannot reference tokens at runtime, so they resolve them at build time instead. That page documents the cost.
The five forks
A fork replaces palette values and reassigns semantic roles. It never touches primitives, and it may not change r = P/2.
| Surface | Fork | Density | Accent light / dark | Contrast |
|---|---|---|---|---|
| Dashboard | neelam · indigo | compact · P = 6 | #33509B / #9DB6E8 | 7.36 / 9.11 |
| Mobile app | ilai · leaf | comfortable · P = 10 | #2E6B45 / #84C291 | 6.15 / 8.95 |
| Website | kavi · canonical | default · P = 8 | #A34524 / #E7936A | 5.92 / 7.77 |
| Web application | kavi · canonical | default · P = 8 | #A34524 / #E7936A | 5.92 / 7.77 |
| Email & print | kavi · resolved | P = 8px / P = 2mm | #A34524 / light only | 5.92 · paper white |
Surfaces
Each stresses a different part of the system.
Operations dashboard
Storage capacity console. Stresses density at P = 6 — where target-size floors engage and the 44px override earns its place. Dense tables, KPI cards, SVG charts, status badges. Pattern layer: absent by design.
02 · comfortableMobile application
Three screens at P = 10. Stresses target sizes, thumb reach, and the expressive layer in onboarding — the one place a small screen can afford a full kolam.
03 · defaultMarketing website
Where the expressive layer gets its budget. Stresses the type scale at display sizes, the 10% density ceiling, and one primary action per view.
04 · defaultWeb application
Three-pane pattern library manager. Stresses continuity — list, detail, and edit without a modal — plus the generator as a working feature rather than decoration.
05 · resolvedEmail & print
The surface without variables. Outlook renders with Word and paper renders nothing — no var(), no flexbox, no max(), no SVG, no JavaScript. Tokens must be resolved at build time, and the lattice re-seeded in millimetres. The hardest test, and the one that broke the most.
What they proved — and what they broke
The four token-consuming surfaces surfaced three problems. The fifth surfaced five more on its own, and they are a different kind of problem — listed separately below.
| Found in | Problem | Fix |
|---|---|---|
| dashboard | Rail items were unreachable on touch at P = 6. They used --alavu-sm, which resolves to 24px at compact density — visually right, but a 24px target. |
Rail items now use padding to reach 44px of interactive area while keeping their compact appearance. This is the visual-size vs. target-size split the accessibility page warns about, met in the wild. |
| mobile | The tab bar had no safe area. At comfortable density the bar looked generous but sat flush against the frame edge. | Bottom inset raised to --space-inset-md, which is where a real device inset would go. Density does not substitute for a safe area. |
| website | The hero kolam crossed the density ceiling. At full strength behind the headline it measured roughly 18% coverage. | Moved out from behind the text into its own panel beside it. The rule held and the layout got better — which is usually how it goes. |
The fifth surface is a different kind of failure
Email and print do not consume tokens — they cannot. The semantic layer has to be resolved into literals by a build step, and four of that surface's five problems are the same problem wearing different clothes: a guarantee that was automatic at runtime became a human responsibility at build time.
Guarantees that stopped being automatic
- The 44px floor.
max()does not exist in Outlook, so the target size was computed by hand into padding plus line-height. It now needs a test, because nothing enforces it. - SVG. Does not render at all; the pattern became a rasterised PNG. Determinism is what makes that safe — the PNG is the same seed, not a lookalike.
- The dual theme. Email dark mode is client-side inversion, not a theme swap. The template declares itself light-only, because the alternative is shipping a variant that gets overridden.
- Two colour roles.
--color-bordervanishes on paper and tertiary text turns to mud in ink — both re-specified in the print block.
What survived intact
- The three-layer split. Only the semantic layer needed resolving. Palette and primitives came through untouched, because nothing consumed them directly — which is the entire argument for the layer rule, tested for the first time.
- The seed relationships.
r = P/2and the √2 ratio are meaningful in millimetres and points, so print re-seeds the lattice at P = 2mm rather than scaling pixel values. A system that could only rescale would have failed here. tokens.json. Written as documentation with nothing consuming it; it turns out to be the only reason a build script can exist. Worth remembering next time a machine-readable export looks like busywork.