Colour Palette Generator
Generate a complete, accessible colour system from a single brand hex. Produces Tailwind v4 CSS ready to paste into your project.
Workflow
Step 1: Get the Brand Hex
Ask for the primary brand colour. A single hex like #0D9488 is enough.
Step 2: Generate 11-Shade Scale
Convert hex to HSL, then generate shades by varying lightness while keeping hue constant.
Hex to HSL Conversion
Lightness and Saturation Values
Reduce saturation for lighter shades (50-200 by 15-20%, 300-400 by 5-10%) to prevent overly vibrant pastels. Keep full saturation for 500-950.
Complete Scale Generator
HSL to Hex Conversion
Verification
Generated shades should look like the same colour family with smooth progression. Light shades (50-300) usable for backgrounds, dark shades (700-950) usable for text. Brand colour recognisable in 500-700.
Step 3: Map Semantic Tokens
Every background token MUST have a paired foreground token. Never use a background without its pair or dark mode will break.
Light Mode Tokens
Dark Mode Tokens
Dark Mode Inversion Pattern
Dark mode inverts lightness while preserving hue and saturation. Swap extremes (50 becomes 950, 950 becomes 50), preserve middle (500 stays near 500).
Key dark mode principles:
- Use shade 500 (not 600) for primary -- brighter for visibility on dark backgrounds
- Use shade 50 (off-white) for text instead of pure
#FFFFFF-- easier on eyes - Borders need ~10-15% lighter than background (e.g. 800 border on 950 background)
- Higher elevation = lighter colour (opposite of light mode shadows)
- Always update foreground when changing background
Step 4: Check Contrast
WCAG Minimum Ratios
Target AA for most projects, AAA for high-accessibility needs (government, healthcare).
Luminance and Contrast Formulas
Quick Check Table -- Light Mode
Quick Check Table -- Dark Mode
Rule of thumb: For text, aim for 50%+ lightness difference between foreground and background.
Essential Pairs to Verify
- Body text: foreground on background (light: 950 on white = 18.5:1, dark: 50 on 950 = 18.5:1)
- Primary button: primary-foreground on primary (light: white on 600 = 5.7:1, dark: white on 500 = 3.9:1 -- borderline)
- Muted text: muted-foreground on muted (light: 600 on 50 = 5.4:1, dark: 400 on 800 = 4.1:1 -- may fail)
- Card text: card-foreground on card (light: 900 on white = 14.2:1, dark: 50 on 900 = 14.2:1)
Fixing Common Contrast Failures
White on primary-500 fails (3.9:1): Use primary-600 instead (5.7:1), or use dark text on the button.
Muted text in dark mode fails (400 on 800 = 4.1:1): Use 300 on 900 = 6.8:1.
Links hard to see (500 on white = 3.9:1): Use primary-700 (8.1:1), or add underline decoration.
Step 5: Output Tailwind v4 CSS
Copy assets/tailwind-colors.css as a starting template.
Component Usage Examples
Common Adjustments
- Too vibrant at light shades: Reduce saturation by 10-20%
- Poor contrast on primary: Use shade 700+ for text
- Dark mode too dark: Use shade 900 instead of 950 for backgrounds
- Brand colour too light/dark: Adjust to shade 500-600 range
- Dark mode looks washed out: Use shade 500 for primary (brighter than light mode's 600)
- Pure white text too harsh in dark mode: Use shade 50 (off-white) instead
- Dark mode muted text fails contrast: Use more extreme shades (300 on 900 instead of 400 on 800)
Brand Identity Adjustments
- Conservative brands (finance, law): Use primary-700 for buttons, reduce saturation in light shades
- Vibrant brands (creative, tech): Use primary-500-600, keep full saturation
- Minimal brands (design, architecture): Use primary sparingly, emphasise muted tones, subtle borders (primary-100)
Verification Checklist
- Body text: >=4.5:1 (normal) or >=3:1 (large)
- Primary button text: >=4.5:1
- Secondary button text: >=4.5:1
- Muted text: >=4.5:1
- Links: >=4.5:1 (or underlined)
- UI elements (borders): >=3:1
- Focus indicators: >=3:1
- Error text: >=4.5:1
- Dark mode: All above checks pass
- Every background has a foreground pair
- Brand colour recognisable in both modes
- Borders visible but not harsh
- Cards/sections have clear boundaries
Test both modes before shipping.
Optional References
- Online contrast checkers: WebAIM (webaim.org/resources/contrastchecker), Coolors (coolors.co/contrast-checker), Accessible Colors (accessible-colors.com)
- CI/CD contrast tests: Use
getContrastRatio()in test suites to assert minimum ratios for all token pairs - Transparent/gradient edge cases: For colours with opacity, calculate against final rendered colour. For gradients, check both endpoints.
- OLED dark mode: Use
@media (prefers-contrast: high)with#000000background for battery savings on AMOLED screens - Multi-colour palettes: Generate separate shade scales for each brand colour, map to different semantic roles (primary, accent)
- Palette visualisation tools: coolors.co, paletton.com, Figma swatches
assets/tailwind-colors.css— Complete CSS output template

