The source of truth is packages/ui/src/styles/tokens.css. Primitive OKLCH scales feed semantic roles; the existing names such as --background, --foreground, and --primary remain compatibility aliases while the system evolves. The :root roles describe light mode and the .dark block overrides the same roles for dark mode.
There are twelve chromatic families — red, orange, amber, yellow, lime, green, teal, cyan, blue, indigo, violet, and pink — plus the neutral foundation. Every chromatic family has eleven predictable steps: 50, 100 through 900, and 950. Each chip includes the token name and a copy action; the scales stack vertically and reflow into one column on narrow screens so no value is clipped.
Raw palette
Raw values are building material, not a component API. Use them to define a new semantic role or a documented illustration; product markup should prefer a semantic role or the colorPalette prop.
Neutral
--color-neutral-*
Red
--color-red-*
Orange
--color-orange-*
Amber
--color-amber-*
Yellow
--color-yellow-*
Lime
--color-lime-*
Green
--color-green-*
Teal
--color-teal-*
Cyan
--color-cyan-*
Blue
--color-blue-*
Indigo
--color-indigo-*
Violet
--color-violet-*
Pink
--color-pink-*
Semantic palette
Semantic roles describe what a color does, not which hue it happens to use. They are the stable contract for surfaces, text, actions, and status feedback.
Light and dark roles
Semantic status roles intentionally change their effective shade between themes. The same component API remains readable without adding a light/dark branch in product code.
Interaction states
Completed or safe result. Pair with a short message, not color alone.
Needs attention but does not block the task.
Risk, invalid input, or destructive intent. Confirm irreversible actions.
Helpful context that is not a success, warning, or error.
Using color
Start with the surface role, then choose the text role that belongs to it. Use --color-action-primary for an action or link, not as a decorative accent that competes with the action hierarchy. For a deliberate hue on a Button or Badge, use colorPalette="red" (or another supported family) and keep the component's existing variant.
Semantic Badge variants (success, warning, danger, and info) keep their fixed meaning even if a colorPalette value is passed. Button's destructive variant likewise remains danger red; custom palettes apply to its other variants.
Pair --color-bg-surface with --color-text-primary, then add a border or icon when status matters.
Use a raw violet or red value directly in markup, or make color the only signal for an error.
Check both canvases at normal text size and in keyboard focus states before shipping. Corner geometry lives on the Border & Radius page; color should not be used to compensate for an unclear surface hierarchy.