Design system foundation. Colors, typography, spacing. Single source of truth. No raw values.
siteConfig.brand → full design system. Zero guessing.
Generate the complete design system (Tailwind config + CSS variables) from siteConfig.brand and siteConfig.fonts. This skill does NOT define colors or fonts — it expands them into a full token system.
siteConfigis the source. This skill is the transformer.
- Colors come from
siteConfig.brand(primary, secondary, accent, dark, light)- Fonts come from
siteConfig.fonts(heading, body)- This skill expands them into full scales, semantic tokens, and Tailwind config
| siteConfig field | This skill generates |
|---|---|
brand.primary (#2563EB) |
primary-50 through primary-950 (full scale) |
brand.accent (#F59E0B) |
accent, accent-hover, accent-light |
brand.dark (#1F2937) |
neutral-50 through neutral-900 |
brand.light (#F9FAFB) |
Light section backgrounds |
brand.secondary |
Secondary element tokens |
brand.surface |
Card/surface backgrounds (if set) |
fonts.heading |
Heading font stack |
fonts.body |
Body font stack with system fallbacks |
tokens_generated: true
tailwind_config: "tailwind.config.mjs"
css_variables: "src/styles/tokens.css"
design_token_verdict: PASS | WARN | FAIL
import { config } from '@/config/siteConfig.example';
const { primary, secondary, accent, dark, light, surface } = config.brand;
const { heading, body } = config.fonts;
From brand.primary, generate shades 50–950 using HSL lightness shifts:
| Shade | Lightness shift | Use |
|---|---|---|
| 50 | Very light (95%) | Subtle backgrounds |
| 100 | Light (90%) | Section backgrounds |
| 200 | (80%) | Borders on dark |
| 300 | (70%) | Disabled states |
| 400 | (55%) | Placeholder text |
| 500 | Base color | — |
| 600 | (40%) | Hover states |
| 700 | (30%) | Secondary text |
| 800 | (20%) | Headings |
| 900 | (15%) | Body text, headlines |
| 950 | Very dark (10%) | Maximum contrast |
Write tailwind.config.mjs with all tokens mapped from siteConfig, and src/styles/tokens.css with CSS custom properties.
| Type | Tokens | Usage |
|---|---|---|
| Semantic | primary-*, accent, neutral-* |
Use in components |
| Utility | spacing.*, font-*, shadow-* |
Internal mapping only |
Rule: Components use semantic tokens. Utility for internal only.
| Token | Allowed | Forbidden |
|---|---|---|
accent |
CTAs, links, highlights | Body text, backgrounds |
primary-900 |
Headlines, body text | Buttons |
primary-100 |
Section backgrounds | Text |
neutral-200 |
Borders, dividers | CTAs |
Wrong scope = WARN.
| Type | Forbidden | Use Instead |
|---|---|---|
| Colors | #FF6B35, rgb() |
bg-accent, text-primary-900 |
| Spacing | mt-[23px] |
mt-6 |
| Font sizes | text-[18px] |
text-lg |
| Shadows | shadow-[...] |
shadow-card |
| Radius | rounded-[12px] |
rounded-lg |
Any raw value in component = FAIL.
| Combination | Min Ratio | Standard |
|---|---|---|
| Body text on white | 4.5:1 | AA |
| Body text on primary-100 | 4.5:1 | AA |
| Large text (≥18px) | 3:1 | AA |
| CTA text on accent | 4.5:1 | AA |
| UI components | 3:1 | AA |
Contrast fail = FAIL.
Every text/background color pair MUST meet minimum contrast ratios:
| Text Type | Min Ratio | Example |
|---|---|---|
| Normal text (<18px, or <14px bold) | 4.5:1 | Body text on backgrounds |
| Large text (≥18px, or ≥14px bold) | 3:1 | Headlines on colored sections |
| UI components (icons, borders) | 3:1 | Icon on background |
Common failure patterns to avoid:
text-white on #C4704B = 3.2:1 FAIL)text-white/80, text-white/75) on colored backgrounds — the reduced opacity lowers contrast furthertext-gray-400 on white = often FAIL)Validation: Use https://webaim.org/resources/contrastchecker/ for every text/background pair.
Rule: When choosing accent colors, always verify that white text passes 4.5:1 on the accent background. If it fails, darken the accent or use primary-900 text instead.
Font family derived from siteConfig.fonts:
config.fonts.heading → system-ui → sans-serifconfig.fonts.body → system-ui → sans-serif| Token | Range | Use |
|---|---|---|
text-base |
16-18px | Body |
text-lg |
18-20px | Lead |
text-2xl |
24-32px | H3 |
text-3xl |
30-40px | H2 |
text-4xl/5xl |
36-64px | H1 |
| Token | Value | Use |
|---|---|---|
py-12 md:py-20 |
48/80px | Section padding Y |
px-4 md:px-8 |
16/32px | Section padding X |
gap-6 md:gap-8 |
24/32px | Component gap |
p-4 md:p-6 |
16/24px | Card padding |
design_token_verdict: PASS | WARN | FAIL
issues: []
| Condition | Verdict |
|---|---|
| Raw value in component | FAIL |
| Contrast fail | FAIL |
| Missing required token | FAIL |
| Token doesn't trace back to siteConfig | FAIL |
| Wrong token scope | WARN |
| Missing shade in scale | WARN |
| All rules pass | PASS |
| Condition |
|---|
| Hardcoded hex in component |
Arbitrary spacing [Xpx] |
| Contrast ratio below AA |
| Missing primary scale |
| Missing accent colors |
| Color/font not derived from siteConfig |
| Condition |
|---|
| Token used in wrong scope |
| Missing optional shades |
| Non-standard font loaded |
tailwind.config.mjs generated from siteConfig.brand + siteConfig.fontstokens.css with CSS variables mapped to siteConfig valuesbrand.primarybrand.accentbrand.darkconfig.fonts.heading and config.fonts.body