Skip to content

Design system

Rendered from the tokens, not written about them. Every swatch reads its value from packages/shared, and every component below is the one the product ships.

The mark

One geometry, simplified below 48px where the inner coil fills in.

24px
32px
48px
64px
96px

Surfaces

Four grounds. Anything that sits on one must clear its contrast against the hardest of them.

background#f3f4f8
surface#feffff
muted#ebedf2
secondary#e1e4eb

Roles

Named by the job they do, not by the colour they are.

text#292b32
textMuted#50535d
borderStrong#7d8089
primary#4a5db5
accent#e0be4d
success#246e3a
warning#924e01
danger#a13838
info#00688b
clay#994136
sage#446b2d

Contrast

Computed on render. A failure here is a failure in the product, not a stale note in a document.

PairingRatioNeedsLight
text on background12.867pass
textMuted on surface7.664.5pass
primaryText on primary5.474.5pass
accentText on accent10.034.5pass
dangerText on danger6.144.5pass
success on successBg5.174.5pass
borderStrong on background3.593pass

The dark theme is solved independently and asserted by src/lib/palette-contrast.test.ts, which also requires body text to stay under 16:1 — black on white is 21:1 and is the pairing most often reported as causing glare.

Buttons

Every variant, at the standing 44px minimum target.

Status

Never carried by hue alone — every state has a word in it.

defaultsecondaryoutlinesuccesswarninginfoclaysagedestructive

Alerts

A default alert, with its own foreground solved against its ground.
A success alert, with its own foreground solved against its ground.
A warning alert, with its own foreground solved against its ground.
A info alert, with its own foreground solved against its ground.
A destructive alert, with its own foreground solved against its ground.

Fields

2px border at 3:1, 3px focus ring. Tab into it.

Empty state

Nothing here yet

What a list says before it has anything to show.

Cards

A card

A raised object among objects. A Panel — what every section on this page uses — is a region of the screen you are already on.

Dark

Solved independently. Not an inversion of the light theme.

background#101318
surface#292e38
muted#1d2027
secondary#272a32