Color
The semantic color tokens every BoardUI component is built from — foreground, text, background, and border roles, named 1:1 with the Figma variables.
How the system works
Colors are layered in two tiers. Primitives are the raw palette — Tailwind's default OKLCH scales plus a handful of Figma-tuned overrides in styles/theme.css. Semantic tokens sit on top and reference those primitives by purpose — what the color is for, never what it looks like. --color-text-secondary says “supporting copy”, not “neutral 500”.
Components consume only the semantic layer. That single indirection is what makes the system maintainable: retune a primitive or remap a semantic token and every component updates at once — no component files change. It's also the path to dark mode: the .dark block in theme.css re-points the same tokens at dark values, so components never need dark: prefixes.
Token names mirror the Figma variable paths (text/primary → --color-text-primary), so a design spec translates to code without a lookup table. Note the doubled prefix in class names — text-text-primary, bg-background-primary-default — the first segment is the Tailwind utility, the rest is the token's full semantic path.
Foreground
Icon fills and inverse/on-color foregrounds — everything drawn on top of a surface that isn't running text.
Text
The type hierarchy: primary for headings and key values, secondary for supporting copy, tertiary for hints, plus disabled and error states.
Background
Surface fills. Primary is the page/card surface, secondary the recessed panel behind it, tertiary the strongest inset — each with interaction states.
Border
Hairlines and focus rings. Button borders step darker through hover and active; the focus ring is the single blue accent.
Graphs
Chart colors. Track is the background bar/ring behind a series, cursor the hover outline and dashed reference line, neutral an “other”-style data slice. The numbered accents are a categorical ramp — each pairs a base fill with a one-tone-darker active used for hover emphasis (the 400 → 500 recipe every chart follows). In charts these are consumed as CSS variables (e.g. fill=“var(--color-chart-1)”) rather than classes.