ADR 0007: Theme tokens from the brand kit, monochrome product accents, 4/8 px geometry
- Status
- Accepted
- Date
- Deciders
- Founder, product team
Context
The brand kit fixes seven colours (Midnight #121C38, Cobalt #2347F2, Ice #E8EEFF, Canvas #F7F9FD, Slate #515F77, Silver #D8E0ED, White), light and dark semantic tokens (tokens/brand-tokens.css: light action Cobalt with White label, dark action Ice with Midnight label, dark surface Midnight), four status pairs that are identical in both themes, radii 4 px (controls) and 8 px (cards), and motion 120/180/240 ms. tokens/accessibility.md measures Cobalt on Midnight at 2.61:1 (“Decorative only”) and forbids Cobalt as dark-theme text. The forge method expects one accent hue per product; the kit is deliberately monochrome and says status colours are the only functional colours. The forge defaults (radii 8/12 px, product hues) had to yield to the kit.
Decision
- Semantic tokens map the kit one to one (PRODUCT-PLAN.md Part 2 B.2). Derived UI values that are not brand colours:
#1B39C4(hover step of Cobalt),#1C2848and#26345C(rail hover/active, lifted Midnight),#0C1329(dark rail, one step below Midnight). Status pairs are the kit’s and are not lifted in dark. - Product accents are tonal steps of the brand palette: evidence Cobalt
#2347F2, plans#1B39C4, review Slate#515F77, progress Midnight#121C38, with light tints Ice,#DDE4FB,#E6EAF1, Silver and text tokens#1B39C4,#14289A,#3F4B60,#121C38. Dark accents are lifted so icons reach 3:1 on Midnight:#7D94FF,#A9B8FF,#A7B4CC,#D8E0ED; dark tints are 22 % mixes over Midnight stored as hex (#2A3664,#333E64,#333D59,#3E4760); dark text is Ice for all four. Product identity is carried primarily by the kit’s icons (source, modules, review, program) and labels. - Geometry and motion follow the kit:
--shape-radius: 4px,--radius-panel: 8px,--radius-graphic: 0,--motion-fast/normal/slow120/180/240 ms withcubic-bezier(0.2, 0, 0, 1), focus outline 2 px offset 3 px, reduced motion to 0. - Typography: IBM Plex Sans for display and headings (500/600, tracking -2 %/-1 %), Inter for body, labels and captions; tabular numerals on tables.
Measured on 2026-09-13 with web/scripts/check-contrast.mjs --verbose: check-contrast: ok (90 pairs across 2 themes; text >= 4.5:1, icons >= 3:1; lowest 5.57:1 for "status neutral on its background" in light). Selected pairs: Midnight on Canvas 15.95, White on Cobalt 6.45, Cobalt on Ice 5.56, Ice on Midnight 14.50, #1B39C4 on Canvas 8.20, Slate on Ice 5.57, dark #7D94FF on Midnight 6.05, dark #A7B4CC on Midnight 8.04. docs/scripts/check-tokens.mjs: check-tokens: ok (80 token values match).
Consequences
forge.config.jsonpalette keys are the CSS custom properties;web/app/globals.css,docs/app/globals.cssanddeck/src/tokens.cssare generated from it and are identical.- The deck’s CSS gate whitelist lacks
4px, so radii are always written asvar(--shape-radius)/var(--radius-panel). - Products look alike in colour by design; screens rely on icon and label for identity, and accents never carry status meaning.
Alternatives considered
- Four distinct hues derived from the brand family: stronger product identity, but introduces colours the kit does not define; rejected by the user.
- Forge default geometry (8/12 px): contradicts the kit; rejected.
- Dark card one step lighter than Midnight: the kit sets dark surface = Midnight; kept the kit’s value and separate cards with a Slate hairline.
Follow-ups
- Record the measured ratios on the docs “Brand and theme” page (docs writer).