Colors
Semantic token roles on a hex base — neutral surfaces with Bloom purple as the single brand override. The dark theme redeclares the surface ladder and chart/chain colors; the semantic tokens resolve per theme through the primitive layer.
Surface
4 tokens
Brand
3 tokens
Status
8 tokens
Form
3 tokens
Chart
5 tokens
Chain identity
5 tokens
Sidebar
5 tokens
Substrate ladder
8 steps
The 8-step elevation cluster every component composes against. Light keeps surfaces 3–8 at #ffffff and separates levels via paired --shadow-surface-N drops; dark walks a true luminance ladder
from #0c0c0e to #312f37. See /components/surfaces for the elevation showcase and per-level shadow recipes.
data-substrate context
relative tokens
Interactive primitives read hover:bg-substrate-hover and aria-expanded:bg-substrate-active — both resolve relative to the nearest data-substrate="N" ancestor.
Card declares data-substrate="3"; Dialog / Sheet / Drawer
declare "5"; Popover / DropdownMenu / Menubar / NavigationMenu
/ HoverCard / Select content declare "7". Dark walks the
surface ladder up one step for hover, two for active; light anchors hover and active to fixed
dim values because surfaces 3–8 all read white in light.
The swatches above show the page-level (no data-substrate ancestor) resolution. Hover the outline buttons in both panels — the lift inside the card lands
on --surface-4 in dark; the page-root version lands on --surface-2.
data-substrate="3"
Inside Card
no data-substrate
Page root
Field recipe
shared idle pattern
The standard form-adjacent fill is bg-input/30 border border-border hover:bg-substrate-hover.
Consumed by Badge variant="outline", every field primitive
(Input, Textarea, Select, NumberField, InputGroup, CommandInput, InputOTPSlot, CurrencyPicker
trigger), and non-Custom chips in LinkChips. Button variant="outline" shares the border + hover halves but stays bg-transparent at idle so the recipe doesn't compete with primary
actions on the same row.