Color
Seven semantic roles, each a ten-step ramp. Components name a role and a step, never a hex. That indirection is the whole reason a re-brand is a one-file change.
import from src/brand/brand.css
The seam
src/system/theme.css declares which roles exist.
It is byte-identical with the design-system reference and travels between projects untouched.
src/brand/brand.css supplies what each role resolves
to, as an H S% L% triplet. The contract wraps those
in hsl() and emits the utilities.
brand.css --primary-500: 44 100% 48% ← the value (brand)
theme.css --color-primary-500: hsl(var(--primary-500)) ← the role (system)
→ Tailwind emits bg-primary-500, text-primary-500, … Dark is the only mode
The site renders <html class="dark"> and has
no toggle, so the .dark block in brand.css is the
one that actually paints. Its neutral ramp is inverted:
neutral-50 is the darkest surface and
neutral-900 the lightest ink. That is why body text
is text-neutral-800 and the page sits on
bg-neutral-50. Never write a
dark: variant here. There is nothing to switch to.
Roles
neutral
the backbone — pure grayscale, #000000 to #FFFFFF
primary
yellow — the signal, base #F7B500
accent
red — punctuation, base #C00B1D
info
semantic only (blue) — a functional signal, not a brand color
success
design-system default
warning
design-system default
destructive
design-system default
No literal color scales
There are deliberately no named color scales here, no
bg-yellow-500 or
text-cyan-400. A component names a role and a
step, and nothing else. A literal scale sitting beside the roles would be a second
representation of the same colors, kept in sync by hand, which is exactly the drift the
two-tier model exists to prevent.
Contrast is membership, not advice
A foreground and background pair is only a legal member of the set if it clears WCAG AA. An off-contrast pair is not discouraged, it is not in the set. The one carve-out is disabled, which is contrast-exempt: the rule is that interactive and enabled pairs must clear contrast.
primary / primary-foreground
the button pair
accent / accent-foreground
the marquee pair
neutral-50 / neutral-800
body — and neutral-500 for muted
destructive / foreground
red means error, everywhere