Tokens & theming
Knobs → scales → roles. Theming is swapping token values, never overriding component CSS.
Knobs
--hue, --chroma, --neutral-chroma,
status hues, and the radius tokens. Everything below derives from them.
Scales
Theme-relative (Radix convention): step 1 is always the app background, 6–8 borders, 9 the solid, 12 high-contrast text — in both modes.
Roles
Components only touch roles: --color-surface,
--color-text, --color-border,
--color-primary (near-black; the action color),
--color-accent (the one blue: focus, selection), the quiet
interactive fills (--color-fill, -hover,
-active, -strong: secondary buttons, menu hover,
rails and tracks), and the status roles (--color-danger…).
Primary and danger derive their hover and pressed states (--color-primary-hover,
-active; --color-danger-hover, -active), so a
new value for either gets matching states.
Type scale
UI-centered: --text-md (14px) is the interface default.
--text-2xs 11 · --text-xs 12 · --text-sm 13 ·
--text-md 14 · --text-lg 16 · --text-xl 24.
Field text keeps a literal 16px floor regardless of the scale (iOS zoom).
Theming recipes
:root { --radius-sm: .25rem; --radius-md: .375rem; --radius-lg: .75rem } /* un-square */
:root { --hue: 150 } /* different brand */
:root { --color-primary: var(--accent-9);
--color-on-primary: var(--color-on-accent) } /* colorful primary */