Design system
Primitive, semantic and component tokens, and the primitives built on them.
- 163
- Color tokens
- 3
- Tiers
- 20
- Primitives
Tiers
Primitives hold raw values, semantic tokens give them a job, and component CSS only names the job.
- Buttonprimary fill
- Buttonemphasize fill
- Buttonkeyboard focus ring
- Inputfocus glow
- Inputresting border
- Toggleon track
- Badgesuccess text
- ErrorBannerfill
- Modaldestructive glow
- Component · Button.module.css
.root[data-type="primary"] { background: var(--color-brand-solid); }
Color
Six OKLCH ramps of twelve steps, where each step number means the same role in every hue.
P3 outside sRGB
- bg-app…
- bg-subtle…
- bg-element…
- bg-hover…
- bg-active…
- bg-inverse…
- fg-default…
- fg-secondary…
- fg-muted…
- fg-subtle…
- border-faint…
- border-subtle…
- border-default…
- border-strong…
- border-active…
- fg-on-brand…
- fg-on-accent…
- fg-on-destructive…
- fg-on-success…
Each ramp on its own curve.
Type
Text uses a named style that owns size, weight, leading and tracking; an instance may only change its color.
1280pxSpace
Spacing runs on a 2px base, and radius and elevation are named for what an element is.
--space-N = N × 2pxonly buttons and round things are pillsMotion
Four easings named by job, a 400ms ceiling for anything a person triggers, and one press scale.
--duration-slower × 4…the everyday decelerate; hovers, fades, most entrances…snappier, for things meant to be noticed arriving…only for continuous sweeps, never an entrance…a reserved overshoot; do not sprinkle bounce--press-scale: …Primitives
Twenty components, every state rendered from the same CSS the product ships.
Types × states
Sizes and icon-only
Playground
States
Field wiring
- label[for]
- …
- input#id
- …
- aria-describedby
- …
- message#id · role
- … · …
Multiline
Trigger states
Listbox and option states
- Undergraduate
- Graduate
- High school
- Working professional
- Unavailable for now
Keyboard model
- open
- false
- aria-activedescendant
- none
- value
- none
- ↓open, or next enabled option (no wrap)
- ↑open, or previous enabled option
- Homefirst enabled option
- Endlast enabled option
- Enteropen, or commit the active option
- Spacesame as Enter
- Escclose, focus stays on the trigger
- Tabclose and move on
- a to ztypeahead, 500ms buffer
Menu
Modal
Rename lesson
Delete this lesson?
This will hide it from your history. You can't undo this from the app.
SegmentedControl
Toggle
Slider
ControlShell
Badge
Spinner
ErrorBanner
Collapse and AnimateHeight
BackButton and volume
40Also TextField, Textarea, SelectField, Field, FieldMessage, Icon
Built
Plain CSS custom properties and CSS Modules, with the rules written beside the tokens they govern.
--color-blue-900: oklch(49% 0.19 268); /* primitive */
--color-brand-solid: var(--color-blue-900); /* intent */
.root[data-type="primary"] { /* component */
background: var(--color-brand-solid);
}