Three tiers. One source of truth.
Every colour, type step and radius on this site resolves through the same pipeline: primitive scales feed semantic decisions, and components only ever read the semantic layer. Flip the theme or accent in the header, and the values below are read live from the page, not hard-coded into it.
Primitives: raw material, no opinions
Named scales with no idea where they'll be used. A primitive never appears in component code; its only job is to be referenced by the semantic layer.
Semantic: decisions, not colours
Each token answers a question (what is the page background? what is muted text?) by pointing at a primitive. Dark mode is nothing more than re-pointing this layer; no component changes.
| token | light | dark | resolved right now |
|---|---|---|---|
| --bg | --gray-0 | --navy-950 | … |
| --bg-2 | --gray-100 | --navy-900 | … |
| --surface | --gray-0 | --navy-850 | … |
| --surface-2 | --gray-50 | --navy-800 | … |
| --text | --gray-900 | --mist-100 | … |
| --text-2 | --gray-600 | --mist-400 | … |
| --text-3 | --gray-400 | --mist-600 | … |
| --line | --gray-200 | --navy-700 | … |
| --accent-strong | color-mix(in oklab, var(--accent) 64%, var(--text)) | derived · re-computes per theme × accent | |
| --halo | color-mix(in oklab, var(--accent) 16%, transparent) | derived · re-computes per theme × accent | |
Contrast: the system holds itself accountable
The same resolved values, checked live against WCAG. Drag the hue slider in the header and watch the button label pass or fail in real time: this is why the accent ramp carries a paired ink token, not a guessed one.
- Body text--text on --bg…
- Muted text--text-2 on --bg…
- Subtle text--text-3 on --bg…
- Button label--accent-ink on --accent…
- Text on surface--text on --surface…
What the contract buys you
one panel reads the semantic layer · one hardcodes hex · flip it and watch
background: var(--surface)
color: var(--text)
background: #ffffff
color: #18181b
Components: consumers, never authors
Components read the semantic layer and nothing else. That contract is why one hue slider in the header can restyle every element on the site without a single component knowing.
Buttons
--accent on --accent-ink · hero CTAs
Badge & field
--halo · --accent-strong · --surface
Nav links
--text-2 → --text · --accent underline · header
Theme controls
replicas: the live ones sit in the header
Tags
--line · --halo when active · case studies & writing topics
Blockquote
--accent rule · Newsreader italic · writing posts
Design tokens are promises a UI keeps.- every talk I give
Callout
--halo wash · --accent-strong label · post asides
Semantic tokens re-point per theme. Components never notice; that’s the whole trick.
Tooltip
CSS-only · :focus-visible too · aria-describedby
Type
Newsreader · Mona Sans · JetBrains Mono
Space & radius
--r · --r-sm