Reference
Design system
Values live in src/styles/tokens.css and are
bound to utility names in
tailwind.config.mjs. This page renders
them so the tokens, the prose in
site/README.md, and what actually ships
can be checked against each other. Every contrast ratio shown is measured
against the surface the colour is used on.
Type
Two families. IBM Plex Sans for everything read as language, IBM Plex Mono for everything read as a machine: commands, labels, task ids, metadata. Latin subsets only, two weights each.
--t-display 52px Commission refuses until it is true
hero headline (lg and up)
--t-display-sm 42px Commission refuses until it is true
hero headline (sm–md)
--t-h1 32px Commission refuses until it is true
page title, hero on mobile
--t-h2 26px Commission refuses until it is true
section heading
--t-h3 21px Commission refuses until it is true
subsection, card heading
--t-lead 18px Commission refuses until it is true
standfirst under a heading
--t-body 16px Commission refuses until it is true
prose
--t-small 14px Commission refuses until it is true
UI, nav, captions
--t-code 13px Commission refuses until it is true
code blocks
--t-micro 12px Commission refuses until it is true
labels, eyebrows, metadata
Palette
Light is warm paper with a code panel recessed below it; dark is cool graphite with the same panel raised above it, because a panel darker than a near-black page reads as a hole rather than a surface. The two themes are separate decisions, not an inversion — toggle this page and watch the relationships change, not just the values.
Surfaces
-
canvaspage background
#FBFBF9 · #0B0D0F
-
surfaceraised panel
#FFFFFF · #121517
-
panelcode block, inline code
#F4F4F1 · #0F1214
-
rulehairline
#E4E4DE · #22272C
-
rule-strongemphasised boundary
#CDCDC5 · #333A41
Ink
- ink primary text light 17.2:1 · dark 16.0:1
- ink-muted secondary text light 6.3:1 · dark 7.8:1
- ink-faint metadata, prompts light 5.0:1 · dark 5.0:1
Semantics
A colour here means a state in the task graph, and is never used for decoration. Colour is also never the only signal: a status dot always travels with its word.
-
accentlinks, in_progress light 6.3:1 · dark 9.4:1 -
okdone, satisfied dependency, evidence present light 6.3:1 · dark 9.3:1 -
warnblocked (derived), missing evidence light 5.7:1 · dark 10.0:1 -
refusalrefusal, exit code 2 light 6.4:1 · dark 7.0:1
Brand — the landing page only
The four semantic colours above name states and belong to every page.
The family below names the product and is used on the landing page
only, which is why this page and /technical look nothing like it. The stage is the deliberate exception to theming:
it is dark in both themes, so anything drawn on it names a
stage-* token rather than a page token. Every
pair that carries text is measured in site/README.md.
-
brandthe product itself — wordmark, dots, edges
#4F46E5 · #8B7CFF
-
brand-deepbrand as text, hover
#4338CA · #7C6CFF
-
brand-violetsecond gradient stop
#7C3AED · #A78BFA
-
brand-cyanthird stop, decorative only
#06B6D4 · #22D3EE
-
bandalternating section ground
#F5F4FF · #10131F
-
stagethe hero ground — dark in both themes
#0D0C1E · #08090F
Spacing and measure
Everything is a multiple of 4px. Only two spacing decisions are global:
the vertical rhythm between sections (--space-section, 4.5rem, rising to 7rem from md) and
the prose measure (--measure, 68ch).
Content is capped at 64rem; the page gutter is 20px on mobile and 32px
from
sm.
Code blocks
Commission is operated by typing, so a code block is this site's primary
illustration rather than an aside. Every block carries a mono label
saying what it is, scrolls horizontally inside itself, and renders the
$ prompt as unselectable decoration so that
copying a block yields runnable commands. Refusals get their own treatment
because exit code 2 is a first-class concept in Commission.
commission check relay-62 1relay-62 criterion 1 checked# comment: dimmed, for annotationrelay-62: in_progress → donerefused: missing evidence: screenshot{ "id": "relay-62", "status": "in_progress", "gate": "verified", "missing": ["screenshot"]}
Inline code — commission next --claim — is bordered
and tinted rather than coloured, so it reads as a token inside a sentence
without competing with a link.
Motion
Three durations and one easing curve (cubic-bezier(0.2, 0, 0, 1)). Anything that needs a fourth duration is a design mistake, not a
missing token.
-
--dur-micro120ms hover, press, focus — anything under the pointer -
--dur-theme200ms colour and theme changes -
--dur-entrance400ms one-shot reveal on scroll -
--dur-loop12s the hero animation on / — the one looping thing on the site -
--reveal-step70ms stagger between siblings in a revealed group
Rules
-
On this page and
/technical, animation is permitted only where it explains a state change: a dependency resolving may animate, a heading arriving may not. The landing page is also allowed motion that gives it life — see the design-system section ofsite/README.mdfor why that exemption exists and what it does not cover. -
The one entrance is an 8px rise and a fade, played once. It uses
transformandopacityonly, so it can never contribute layout shift. - Nothing parallaxes and nothing hijacks the scroll. Exactly one thing loops — the landing page's hero animation — and it holds still for the last second of every cycle.
-
transformandopacityonly, with one documented exception (the flow diagram's travelling dots animateoffset-distance). No animation on this site can contribute layout shift. -
prefers-reduced-motionflattens every transition globally, with no exceptions — no meaning on this site is carried by movement alone. - Content is visible without JavaScript. The observer only adds the animation; it is never what makes text appear.