Tokens · Layer 1
Primitive tokens
Raw values with no meaning attached. They exist so that the semantic layer has a fixed vocabulary to point at — and product code should never reference them directly.
Do not use these in components
A component that reads --brand-600 has hardcoded a brand decision. Reach for the semantic layer instead, so the value can be reassigned once and followed everywhere.
BrowsePermalink to this section
Search by name, by value, or by what a token is for. Copy the raw value, a var() reference, or the full declaration.
How the scales were chosenPermalink to this section
Each ramp is deliberately short. A scale with twenty steps is a scale nobody can hold in their head.
Neutrals carry the product
Twelve steps, weighted toward the light end, because almost every surface, border and text colour in a light theme lives between #ffffff and #e3dcd4.
One brand ramp, ten steps
Enough to cover a soft fill, a base, a hover and a text-on-soft shade, with room for dark mode to pick different rungs.
Status hues are desaturated
The success, warning and danger bases all sit around 4.6–4.9:1 on white. They read as part of the same family as the neutrals rather than as alerts pasted on top.
Spacing follows an 8px rhythm
The main rhythm uses 8px multiples, with 4px half-steps for dense controls and small icon gaps. The scale stays predictable without making compact UI feel oversized.
Five durations, five curves
If an interaction needs a duration that is not on the list, the interaction has not been thought through yet.