Colors
Color Step Ranges (12-Step Framework)
App background and subtle component fills.
Normal / hover / active backgrounds for interactive elements.
Subtle to pronounced borders, from a hairline to a focus outline.
The color's "brand" moment — solid buttons, badges, indicators.
Low- and high-contrast text on the app background.
Gray families — real values (this package's actual --n-* scale per family)
These don't change with the Appearance toggle, on purpose: this package's foundation scale is theme-independent (see design-system/AGENTS.md) — light/dark differs in which semantic ROLE picks which step (e.g. bg-canvas = step 50 in light, step 1000/black in dark), not in the swatch values themselves.
Accent colors — generated illustration, light mode
Unlike the grays above, this package only stores ONE hex per accent (see the Configurator's swatch grid) — not a real 12-step scale per theme the way Radix's own colors ship. These rows are generated from that single hue via HSL lightness interpolation (a different curve per theme, which IS how Radix's real scales work) to show what applying the same framework would look like; they're illustrative, not perceptually tuned. Toggle Appearance in the Configurator to see it flip.
Semantic tokens — what components actually consume
--bg-canvas--bg-surface--bg-surface-hover--bg-elevated--hairline--hairline-strong--fg--fg-muted--fg-subtle--link--accent--accent-hover--accent-fg--accent-contrast--accent-text--accent-subtle--accent-subtle-hover--success--warning--dangerShadows, highlights, and overlays
Smart Accent Semantics & Dynamic Luminance Engine
In traditional component libraries, switching an accent color to a high-luminance hue (like Lime, Mint, Amber, or Sky) severely breaks text readability on light surfaces, while selecting dark monochrome colors causes text to vanish in dark mode. @shavin/ui solves this with an integrated, mathematical Dynamic Luminance Engine that guarantees WCAG 2.1 AAA contrast compliance across all 24 presets in both themes.
Evaluates exact linear RGB coefficients per WCAG spec:L = 0.2126R + 0.7152G + 0.0722B
Accents with L > 0.35 in light mode are dynamically darkened for --accent-contrast text, while dark accents in dark mode are complemented to ensure crisp ≥ 4.5:1 text contrast.
Monochrome black (0 0 0) seamlessly inverts to pure white (255 255 255) in dark mode, maintaining pristine brand contrast without manual theme configuration.
Brand Color Tokens
Alongside the DS semantic tokens, Shavin supports custom brand color tokens — supporting colors that brands use for assets, highlights, and different sections. These sit alongside the design system tokens and follow the same two-tier architecture: you enter raw hex values, and the system auto-computes a full cluster of WCAG-accessible derived tokens using the same luminance engine that powers --accent.
npx @shavin/cli initWhen you run npx @shavin/cli init, the CLI automatically scaffolds brand-tokens.css alongside your global CSS, generates the initial brand-preset.mjs, imports it in your CSS, merges the preset into your Tailwind config, and wires these scripts into package.json:
"scripts": {
"brand:gen": "npx @shavin/cli brand", // regenerate derived tokens
"brand:check": "npx @shavin/cli brand --check", // CI check (exit 1 if stale)
"predev": "npm run brand:gen", // auto-fires before npm run dev
"prebuild": "npm run brand:gen" // auto-fires before npm run build
}You never need to run brand:gen manually — it fires automatically before every npm run dev and npm run build. The only time you interact with the file is to add hex values to the INPUT section.
- 1. Declare hex values — Add lines like
--brand-coral: #FF6B6B;to the INPUT section ofbrand-tokens.css. - 2. Auto-compute — The
predevandprebuildhooks firebrand:genautomatically before every dev server start and production build. No manual step needed. - 3. Use in components — Tailwind utilities like
bg-brand-coral,text-brand-coral-contrast,bg-brand-coral-subtlebecome available.
Every hex-based brand color gets 7 derived tokens — the same cluster as --accent:
--brand-{name}Base color (resolved triplet)--brand-{name}-fgForeground on solid fills--brand-{name}-hover±12% mix for hover states--brand-{name}-contrastWCAG-safe text color--brand-{name}-textAlias of contrast--brand-{name}-subtle12% translucent background--brand-{name}-subtle-hover18% translucent hover bgThe file ships with --brand-primary: var(--accent); as a default alias. Uncomment or add new lines with hex values:
/* ─── INPUT ─── */ --brand-primary: var(--accent); --brand-coral: #FF6B6B; --brand-teal: #14B8A6; /* --brand-gold: #F59E0B; */