Stage 08 · Tokens + Components
The design system
The same look as UI + Visual, a different architecture. The flat kit of stage 07 splits into two levels of tokens and one file per component, and the product does not move by a pixel. Four of the nine steps are done: the audit, the consolidation, the tokens, and these foundations.
The code of the system lives in design/system/ and a product loads it with one link. The stand is here, and a person looks at it. The split is simple: design/system/ can be lifted into another project whole, and this stand stays behind.
What the flat kit actually contained Step 1
Facts before decisions, taken on two instruments independently: a parse of the stylesheet against all 28 coloured pages, and Codex read-only over the same corpus. Where the two disagreed, the place was re-read in the file rather than voted on.
The stylesheet came out clean on the thing it was most likely to be dirty about: zero hex literals inside any rule, zero radius literals where a radius variable already held that value, zero literals of any kind on the 28 product screens. The stage 07 rule that a screen carries no style of its own held.
What it was not clean about is the half nobody had tokenised. 23 font sizes and 27 spacing values are in use and not one of them is a variable. That is not a defect of stage 07; it is the shape of the work here. One orphan variable, --success, was declared and read by nothing.
The second half of the step measured the product in a browser rather than reading it: getComputedStyle on every control of every coloured page, in two viewports, 594 records. It found what a file cannot show. "Try again" is played in three different weights on four error screens: a filled petrol button on two, a plain outline button on a third, and a quiet clay link inside a wash on the fourth. A person who learns the loud button on one error screen meets a quiet link on the next, doing the same job.
It also found a form nobody had named: behind the Pro gate, a disabled range button keeps the bold weight of the selected state and loses its petrol, so the chosen range is half-signalled.
Codex found the most valuable thing of the step, and it was in a document rather than in the code. DESIGN.md disagrees with the stylesheet it was generated from in twelve places: it states a headline of 18px where the product ships 21, a merchant name of 14.5px where the product ships 15, a button of 13.5px where the product ships 14. Stage 07 had corrected six values in that file and corrected only the machine-readable half, so the document now disagrees with itself as well as with the code. Three more were found at step 4, on the geometry page. Fifteen in total, and they matter because DESIGN.md is a named input of this stage.
What exists as a unit of the system Step 2
The quietest step of the stage and the only one that writes no code. Step 1 counted what exists; this one decided what exists as a unit. Without it the split into files would carry every piece of drift across intact, and fourteen contextual overrides of the button would land in button.css looking like variants somebody intended.
The only criterion allowed was anatomy: the set of zones and their order. "Looks different" is not a criterion, it is the definition of a variant. 68 components became 55.
| Level | Was | Became | What merged, and on what ground |
|---|---|---|---|
| Atoms | 21 | 18 | Four muted lines are one atom at three sizes, and .removal, .pitch, .p and a paragraph wearing .notice joined them. Five chip look-alikes were already one rule in the code and two rows in the inventory. Two atoms were added: the eyebrow and the label had rules, occurrences, and no row anywhere |
| Molecules | 28 | 23 | .attention and .notice are byte-identical apart from their tone token, and .decoder is the same wash with a different corner. .actions and .secondary differ only by a margin, which belongs to the host. .lede and .state are one text block at three scopes |
| Organisms | 19 | 14 | Three identical divided lists, three grids differing only by column count, two padded cards. The reviewer's page frame left the system altogether: it stands on 57 pages and travels to no build |
The step also produced the renaming map, 39 rows of "old class to new class and variant". It was executed at step 6, in the CSS and in the markup of every screen in one pass, and it is read again by the rollout at stage 12: without it nobody four steps later can reconstruct what .decoder was folded into.
Three things change how the product looks, and all three are named. The decoder's corner goes from 10px to 12px, because two washes with the same fill, the same padding and different corners is drift and not a variant. The Pro gate's padding goes from 18px to 16px, to match the card it turned out to be. And on one error screen "Try again" becomes the filled button it already is on five others. Everything else is a refactor, and the pixel comparison at step 8 has to prove it.
Two levels, and a pair of themes from the first line Step 3
Primitive answers what value, semantic answers why this colour here, and there is no third level. A component token is created case by case and only where a state lands on no role at all. Geometry gets no semantic level: a radius has nothing to override, so components read it straight from primitive.
The finding that decided how many roles exist is the surface axis. A role declares what it paints, and there are three: ink, fill, line. Ink answers to 4.5:1, fill and line to 3:1. One role on two surfaces is forbidden even at the same value, because a fill role placed on a 12px bold caption passes as a surface and fails as text, and a table of text-on-background pairs never catches it: nobody declared it text. Petrol alone became three roles for exactly this reason.
Every role is written twice at the moment it is declared, in :root and in [data-theme="dark"]. 32 roles, 4 state tokens and 3 component tokens, 39 pairs, none missing. Recounted 2026-08-19 off tokens.css itself: the sentence here said 29 and 36, which was two short before --bg-measure arrived and three after. --bg-measure is the newest, the fill of a bar that states a quantity, added 2026-08-19 with the category bars; --plot-line and --plot-area came the day before it. The last three of the state group were counted in nothing until 2026-08-13 and are on the colour page now. The pair is not mirrored, and three places show why. The action darkens under the pointer in the light theme and lightens in the dark one, because the hover has to move away from the ground and the ground swapped ends. The callout shares one value with the page in the light theme and must not in the dark. And the label on a filled action is white in the light theme; on the lightened petrol of the dark theme white measures 1.9:1, so it takes the dark canvas at 7.5:1 instead. That last one would have shipped broken had the pair been left for later.
21 dark primitives are the only new values in the file. They had to be new, because the flat kit had no dark theme to carry.
The material, shown before a single component Step 4
Colour, typography, geometry and icons are material too, and they are shown now rather than at the end. This is the cheapest place in the stage to change a scale: one file, and it reaches everything through var(). After the components are built the same change costs thirty component files plus thirty pages that already show the old value.
Two of the four carry a proposal rather than a change. Typography proposes seven steps for the 23 sizes on screen, with five named exceptions; geometry proposes six steps for the 27 spacings, with the screen foot kept as a family and 104px expressed as the tab bar plus air. Nothing in design/system/ has been changed by either. They are the founder's call, and they are why this page says the foundations are awaiting review.
What this stage has not closed Open
The two proposed scales. Typography and spacing were never tokenised, and both pages propose a scale. Until one is accepted the system has colour and radius as tokens and the rest as literals.
Fifteen divergences in DESIGN.md. The decision is made, the document moves to the code, and the edit waits for the scale that step 4 proposes: writing today's 23 sizes into it would replace one wrong description with a longer one.
One project-wide contrast defect, and it is not this stage's. The SOON badge in the roadmap is #9aa0a2 on white, 2.65:1 against 4.5:1. It lives in the root _nav.css and therefore on every page of the project, from Foundation Research to Handoff. Fixing it is one line and changes every stage, so it is named here rather than changed quietly.
Nine heading rules set a size and no weight. They render at the browser's bold rather than at a decision. Found on the typography page and carried, because it is a component question and the components are step 5.
Where this stage caught itself Corrections
Two of the numbers on this page were wrong when they were first written, and both were caught by a second instrument rather than by the person who wrote them. It is worth recording, because it is the argument for the second instrument existing at all.
The spacing census said 24 values and the real figure is 27. It was taken with a pattern that matched the margin: and padding: shorthand and not one longhand, so every margin-top and padding-left was invisible to it: three values were missed entirely and ten were undercounted. A census taken by pattern is only as complete as the pattern.
The reviewer chrome was documented as moved and had not been moved. The comment at the top of the stand's stylesheet said the frame had left the system; the rules were still in the old file, and when the hub stopped loading that file the roadmap rendered as a plain stack with no panel. Documenting a move is not making one.
The material itself Index
The system's own panel on the left of every stand page is the way to browse this. The index below is the same registry, laid out flat. A component with no page yet is shown quiet: all 57 are built, in rounds from the bottom of the ladder up, and two brand atoms joined them on 2026-08-12 when the founder locked the mark.
The fourth group is new at stage 09 and it is a different kind of thing from the three above it. A component is one brick and its test is what it contains; a pattern is a composition of bricks and its test is repetition, three screens or more, counted on the grey product. The count that produced them and the four candidates still waiting are on Patterns.