Color Systems
How to build a color system that scales — from brand palette to semantic usage, dark mode, and accessible contrast.
What is it?
A color system is the structured approach to defining and applying color in a design system. It includes: the primitive palette (all available colors), semantic color assignments (what each color means in context), interactive states (hover, active, focus), status colors (success, warning, error, info), and theme variants (light and dark mode).
Why it matters
Color is the most powerful pre-attentive attribute — it communicates meaning before users consciously process content. A poorly defined color system leads to inconsistency, accessibility failures, and brand dilution. A well-defined system makes every designer's decisions faster and every component more consistent.
Best Practices
- Define a primary palette: brand color + its scale (50–950 in 50-point increments, following the Tailwind convention).
- Semantic assignments: --color-action (for interactive elements), --color-success (for positive states), --color-warning, --color-error, --color-info.
- Surface hierarchy: 3–4 distinct background colors (bg.default, bg.subtle, bg.muted) for card layering.
- Never use more than 3–4 primary colors in an interface. Brand secondary colors are accents, not primary UI colors.
- All text/background combinations must meet WCAG AA contrast (4.5:1 for normal text, 3:1 for large text).
- Dark mode: define separate semantic token mappings for dark theme — don't just invert colors.
- Status colors must not rely on color alone — always pair with an icon or label.
- Interactive states: hover, active, and focus must be distinguishable. Focus ring is mandatory.
- Test color blindness: Protanopia, Deuteranopia, Tritanopia. Red/green-only signals will fail.
- HSL color space makes systematic color variation more intuitive than hex values.
Common Mistakes
- Using color alone to convey meaning (color blindness accessibility failure).
- Insufficient contrast — light grey text on white fails WCAG at any size.
- Dark mode that simply inverts light mode — creates wrong-feeling interfaces with unbalanced contrast.
- Too many brand colors used throughout the UI — brand color should be used sparingly (10% of the interface).
- No semantic color naming — developers use --color-blue-500 for both brand and status colors.
- No system for hover/active states — developers improvise inconsistently.
Checklist
Research & Theory
Pre-Attentive Attributes (Healey & Enns, 2012)
Color is one of the most powerful pre-attentive attributes — processed before conscious attention in under 250ms. This makes it extremely effective for drawing attention, but also extremely sensitive to over-use.
Why it's relevant
Use color intentionally. Every use of color communicates something. When color is everywhere, it communicates nothing.
Real-World Examples
Radix Colors
Open-source color system with 12-step scales for every color, accessible contrast ratios built in, and dark mode variants. A design system's best starting point for color.
GitHub Primer
Semantic color system with fg/bg/border tokens, dark and light mode, functional color names. Fully documented with usage guidance.
Stripe
Strict color discipline: one brand color (purple), one secondary (green for success), minimal tertiary. The restraint is what makes the product feel premium.