Tokens
The frozen data-viz palette shipped as @hextor/viz-tokens. Every swatch below renders with the item's real Tailwind class — a broken token shows up here as a broken swatch, not a screenshot.
Axis slots (frozen order)
axis-correctness#2a78d6 / #3987e5axis-test-quality#eb6834 / #d95926axis-complexity#1baf7a / #199e70axis-performance#eda100 / #c98500axis-code-quality#e87ba4 / #d55181Verdict slots (mode-invariant)
verdict-pass#0ca30c (fixed)verdict-warn#fab219 (fixed)verdict-serious#ec835a (fixed)verdict-fail#d03b3b (fixed)Chart ink & grid
viz-gridoklch(0.145 0 0 / 8%) / oklch(1 0 0 / 10%)viz-inkoklch(0.145 0 0) / oklch(0.985 0 0)viz-ink-mutedoklch(0.556 0 0) / oklch(0.708 0 0)Why axis order and colour are frozen
AXIS SLOTS are fixed in order and colour, never cycled, never reassigned. The radar's silhouette is only comparable across users and across seasons if both are frozen; changing either invalidates every Skill Card ever shared. If the rubric changes, ADD an axis — never recolour one.
The values are the validated categorical palette, stepped per mode (dark: worst adjacent CVD deltaE 8.4, normal-vision 19.3, all at least 3:1; light: 9.1 / 19.6). In light mode three slots land under 3:1, so the relief rule applies — every axis is ALWAYS directly labelled with its number and a table view exists. Never colour-alone.
VERDICT SLOTS are the reserved status palette, deliberately not drawn from the axis slots so a pass/fail colour can never be mistaken for a skill axis — which is why correctness is blue, not green. They are mode-invariant: defined once under :root and deliberately ABSENT from the dark block, so .dark inherits them and the two can never drift.
Note that shadcn add merges cssVars append-only unless you pass --overwrite. That is the right default for adoption, but it means the CLI will never tell you your values have drifted from ours. If you depend on cross-app comparability, diff against https://ui.hextor.co/r/viz-tokens.json in your own CI.