How to select your primary color
Your primary is the most consequential decision in the system — every hover, CTA, and focus ring stems from it. Here's the framework for choosing it well.
Step 1 — Choose a hue family
Hue carries brand meaning before a word is read
Blue signals trust (fintech, SaaS); green maps to growth and money; purple reads premium; teal is calm and modern. Red and orange feel urgent but clash with error/warning semantics. The hue is a brand statement on its own.
Step 2 — Test against four criteria before committing
Contrast on white and dark backgrounds
Your primary must reach at least 4.5:1 contrast against white for text use, and work equally on dark surfaces. Colors in the 40–60% lightness range tend to fail one or both. Vivid mid-tone colors often look great but fail text contrast — test before falling in love with a color.
Legibility at small scale
Primary colors appear on 14px labels, 2px focus rings, and 8px active nav dots. A color that looks confident at 200px can become ambiguous at 12px. Always render the color at its smallest intended use. Cool hues generally hold up better at small sizes than warm hues.
Semantic neutrality
Avoid hues already claimed by semantic states. Red, orange, and yellow carry universal error/warning meaning. Green often signals success. Using them as your primary creates an unresolvable cognitive conflict. Blue, teal, and purple have no strong semantic pre-assignment.
Full-scale scalability (11 stops)
Your primary must generate a complete tonal scale — very light tints through very dark shades — without losing recognizable identity. Low-saturation or unusual hue angles often collapse into gray at the light end or muddy brown at the dark end. Test the extremes (stop 50 and 950) before committing.
Step 3 — Validate contrast ratios for every use context
The primary appears as a fill behind white text, as text on white, and as text on its own tint — each with different contrast requirements. All must pass before you commit.
The ratio targets
WCAG AA: 4.5:1 for normal text, 3:1 for large text (18px+ / 14px+ bold) and UI boundaries. AAA: 7:1. Target AA everywhere, AAA on critical elements.
Step 4 — Define the colors that live around the primary
No primary lives alone — it needs hover/active variants, complementary accents, and a neutral palette to carry the interface. Six proven harmony strategies:
Tints & shades (same hue)
Lighter tints for backgrounds and hover fills; darker shades for active and pressed states. All derived from the same hue — zero dissonance. The most practical pairing strategy for any product UI. Always build these first.
Analogous (±30° on wheel)
Adjacent hues feel cohesive and calm. A blue primary might pair with cyan and indigo. Great for secondary accents that support without competing — multi-section dashboards where each section needs a distinct but harmonious color.
Triadic (120° apart)
Three hues equally spaced on the wheel. Creates vibrant, high-energy contrast — ideal for data visualization where categories need clearly distinct colors. Use primary at full weight, the other two as supporting accents.
Complementary (180° opposite)
Maximum contrast — the hue directly across the wheel. Use the complement very sparingly: a highlight color, a sale badge, a special alert. Never as an equal-weight second primary. One dominant, one accent-only.
Split complementary
Primary + two hues flanking the complement. Lower tension than full complementary, more variety than analogous. Excellent for extended palettes — fintech apps with multiple product lines, analytics with 3+ data categories.
Primary + neutral (most common)
One strong accent color and a complete neutral gray family. The neutral carries 90% of the interface; the primary punctuates the 10% that matters most. Simple, robust, and the right choice for most product UIs.
The complete set of colors derived from one primary
Primary (500) — the base interactive color
Used on: primary CTA fills, active navigation indicators, selected checkbox/radio fills, focus rings, active tab underlines, highlighted metric values. This is the color users associate with “action” in your product.
#0066CC · HSL(210, 100%, 40%)Hover state (400) — one step lighter
The primary lightens slightly on hover — a subtle shift that signals interactivity without a dramatic change. Never use a completely different hue for hover; always derive it from the same hue, one stop lighter.
#3380FF · HSL(210, 100%, 57%) · hover of primary CTAActive / pressed state (600) — one step darker
When a button is actively clicked or a state is “on”, the color darkens one stop. This communicates commitment — something is selected and persisting. Pressed button fills, active toggle backgrounds, current nav item fills.
#0052A3 · HSL(210, 100%, 32%) · active press, selectedTint backgrounds (50–200) — the ambient presence
Very light tints used for: active row fills, selected card backgrounds, info banner fills, highlighted search results, chip/badge fills for filters. They keep the primary present in the layout without the full weight of a button fill.
#EBF3FF (50) · #CCE0FF (100) · #99C0FF (200)Dark shades (700–900) — text and high-contrast use
Used when the primary hue appears as text on a light background, or as a border on an accent-tinted surface. Stop 700 works as accent link color on white. 800 for text inside info banners. 900 for maximum contrast.
#003D7A (700) → link text · #002952 (800) → text on tint bgNeutral gray family — the interface carrier
The workhorse. Slightly warm or cool the neutral to harmonize with your primary hue. A blue primary pairs with a cool gray; a warm orange primary with a warm gray. Use 5–10 stops, same naming convention as the primary scale.
gray-50 → gray-950 · HSL(210, 6%, varies) for a blue systemOne primary is usually enough
Most interfaces need just one primary, one neutral scale, and semantic colors. Add a secondary accent only for a clear functional need — never to make the palette “more interesting.” Restraint is a marker of maturity.