The Variant system
How the shared variant axis (and its companions borderless + the
tint tokens) work across the library. Each component's live examples live on its own page —
see the component index below.
1 · variant → token
variant maps a semantic name to a palette token (types/variants.ts → variantToken). Every variant-aware component accepts Variant | Responsive<Variant>, in this canonical order:
- •
danger → --ui-color-error; the rest map to their same-named--ui-color-*. - • neutral and ghost are the two non-accent variants → both
--ui-color-text. - • neutral = the uncoloured variant: solid in solid contexts (Button/Toggle), a tint in soft ones (Badge/Alert).
- • ghost = the minimal, near-transparent style (transparent fill, hover-tint only).
2 · The tint scheme (bordered/tinted surfaces)
A tinted surface mixes its own variant token at shared strengths, so every one is calculated identically (change a number → all follow):
- --ui-tint-soft 12% — soft fill (Badge / Alert filled)
- --ui-tint-border 50% — border/frame at rest (every bordered surface)
- --ui-tint-border-hover 80% — the stronger step on hover/focus (interactive fields)
- --ui-tint-strong 80% — foreground text (Badge)
Every bordered surface (Input, TextArea, Card, DataTable, Button outline, …) uses ONE calc —
token @ --ui-tint-border rest, --ui-tint-border-hover on hover —
with no secondary special case. (The old --ui-border-color-strong is retired.)
3 · The borderless mechanic
The border is always 1px — only its colour moves, so toggling it
can't shift the box by a pixel. borderless paints the border the component's own
background; borderless=false uses the standard tint-border. A ghost Button with borderless=false is therefore the outline button — no separate variant. Defaults differ (fill-y things default
`true`: Button/Badge/Banner; framed things default `false`: Alert/Card/Input/DataTable).
4 · Interactive tints (--ui-accent)
Row-hover / section bands / pressed states are one language — --ui-color-hover (4%), --ui-color-surface (8%), --ui-color-active (12%), each a mix of --ui-accent (defaults to --ui-color-text → neutral grey). A
component's variant re-points --ui-accent (via the .ui-accent class), so the whole interactive surface tints — that's how DataTable, List, and Menu colour their hover/selection.
Component index
Live examples on each component's page: