Anatomy of a Color System: How I Build Brand Palettes That Scale
A good color palette isn't five pretty swatches — it's a system. Here's my exact process for building brand palettes that scale across products, states, and dark mode without breaking.
A good color palette isn’t a set of five swatches that look nice together. It’s a system — a structured set of decisions that tells your entire product how to look, feel, and communicate across every surface, state, and context.
I’ve built color systems for startups, agencies, and established brands. The process is always the same. Here’s exactly how I do it.
Start with Meaning, Not Mood Boards
Before I open a color picker, I answer three questions:
- What emotion should the brand evoke? Trust? Energy? Calm? Precision?
- Who is the audience? A B2B SaaS for CFOs needs a different palette than a DTC wellness brand.
- Where will it live? A color that works on a marketing site might fail in a dense data dashboard.
These answers constrain the palette before I’ve touched a single swatch. Constraints are good. They prevent “it looks cool” decisions that fall apart at scale.
The Structure: Primary, Secondary, Neutral, Semantic
Every color system I build has four layers:
Primary: The brand’s signature color. One hue with 9–10 shades from near-white to near-black. This is the color people associate with your brand. It needs to work as a background, a text color, a button, and an accent — all from the same hue at different lightness levels.
Secondary: A complementary color for visual interest. Used sparingly — illustrations, badges, highlighted sections. If primary is blue, secondary might be a warm amber or a soft teal.
Neutral: The workhorse. Gray palette with 10+ shades for text, backgrounds, borders, dividers, disabled states, and subtle UI elements. I generate these with a slight tint of the primary hue so they feel cohesive rather than generic.
Semantic: Success (green), warning (amber), error (red), info (blue). These are functional colors with fixed meanings across the product. They don’t change with brand updates.
Accessibility Is Non-Negotiable
Every color combination in the system must meet WCAG AA contrast ratios at minimum. That means 4.5:1 for normal text and 3:1 for large text. I test every pairing — not just the obvious ones, but the edge cases: light text on a colored background, colored text on a light surface, icon colors on hover states.
I use a contrast matrix to map every foreground/background combination and flag any that fall below threshold. If a color can’t meet contrast requirements in enough contexts, it gets adjusted or demoted to a decorative-only role.
Dark Mode Isn’t an Afterthought
If your product will ever have a dark mode, build it into the system from day one. That means defining every color as a semantic token — surface-primary, text-secondary, border-subtle — rather than hardcoding hex values.
In light mode, surface-primary might be #FFFFFF. In dark mode, it’s #1A1A2E. The component doesn’t know or care. It just uses the token.
Naming Conventions Matter
Don’t name colors after what they look like. Name them after what they do. blue-500 tells a developer nothing about when to use it. interactive-primary tells them everything.
I use a two-tier naming system: the base palette uses numbered scales (blue-100 through blue-900), and the semantic layer maps those to functional names (brand-primary, text-muted, surface-elevated). Designers reference the semantic names. The base palette is just the raw material.
Document Everything
A color system without documentation is just a Figma file. I document every color with its hex value, contrast ratios, usage guidelines, and do/don’t examples. When a new designer joins the team and asks “what color should this button be?” — the documentation should answer that question in 30 seconds.
The Test
A good color system passes this test: a designer who has never seen your brand before can build a new page that looks like it belongs, using only the system tokens and documentation. No guessing. No “ask the lead designer.” If the system can’t do that, it’s not finished.