Skip to main content
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

Color Palette Strategy

The Problem

AI agents often generate colors in isolation — picking a primary blue here, an accent green there — with no systematic relationship between them. The result is a palette that feels arbitrary: colors clash, fail to harmonize, and have no predictable structure. Without a palette strategy, designs end up with too many colors, no clear hierarchy, and missing semantic roles (no danger state, no muted text color). When combined with HSL's perceptual inconsistency, AI-generated palettes frequently look wrong even when the theory sounds right.

The Solution

A palette strategy works across three layers:

  1. Color harmony — which hues to use and how they relate on the color wheel
  2. Semantic architecture — assigning roles (primary, neutral, feedback) to color groups
  3. Perceptual consistency — using OKLCH so shades look visually as intended

Color Harmony Strategies

Color harmony defines which hues work together and why. The five primary strategies:

  • Monochromatic — One hue at varied lightness and chroma. Safe, cohesive, never clashes.
  • Complementary — Two hues opposite on the color wheel (≈180° apart). High contrast and energy; use one as dominant, one as accent only.
  • Analogous — Three or more adjacent hues (±30° each). Natural and soothing — great for backgrounds with subtle variation.
  • Triadic — Three hues equally spaced (120° apart). Vibrant and balanced, but difficult to control — keep chroma low on two of the three.
  • Split-complementary — One hue plus the two adjacent to its complement (±30° from the opposite). The visual tension of complementary without the jarring clash.
Color Harmony Strategies

Building a Design Color Palette

A complete palette has four layers.

Primary, Secondary, and Accent

The primary color carries your brand and drives all interactive elements (links, buttons, focus rings). Secondary supports the primary in areas like sidebars and section headers. Accent highlights the most important moments — calls to action, badges, notifications — and should represent ≤10% of the visual area.

Neutral/Gray Scale

Neutrals carry most of your UI: backgrounds, surfaces, borders, and text. Use 8–10 steps from near-white to near-black. Slightly tinted neutrals (low chroma in the brand hue direction) feel more refined than pure grays.

Feedback Colors

Every UI needs semantic colors for system states:

  • Success — green (≈hue 150)
  • Warning — amber (≈hue 65)
  • Danger/Error — red (≈hue 25)
  • Info — blue (≈hue 220)

Keep their lightness consistent so they feel like they belong to the same system.

The 60-30-10 Rule

A classic proportion from interior design that translates directly to UI:

  • 60% — dominant neutral (backgrounds, surfaces, most of the page)
  • 30% — secondary supporting color (sidebars, headers, secondary actions)
  • 10% — accent (CTAs, highlights, key interactions)
The 60-30-10 Rule Visualized

Code Examples

Monochromatic Palette in Practice

A single hue at different lightnesses provides enough visual variety for a complete interface. Use the darkest shades for text, midrange for interactive elements, and light shades for backgrounds and subtle accents.

Monochromatic UI — Single Hue Applied to a Card

Complementary Color Scheme

Use the complement as a high-contrast accent — it naturally draws the eye. Reserve it for the single most important action on the page.

Complementary Colors — Blue Primary + Orange Accent

Complete Design Token Palette

A well-structured token set defines every color role before any component is built. This example uses OKLCH to keep consistent perceived lightness across all hue groups. For a full architecture around organizing these tokens into palette, theme, and component layers, see Three-Tier Color Strategy.

:root {
/* Primary — blue, oklch hue 264 */
--color-primary-50: oklch(96% 0.04 264);
--color-primary-100: oklch(90% 0.07 264);
--color-primary-500: oklch(55% 0.2 264);
--color-primary-700: oklch(38% 0.17 264);
--color-primary-900: oklch(22% 0.1 264);

/* Neutral — near-achromatic, hue-tinted */
--color-neutral-50: oklch(98% 0.005 264);
--color-neutral-200: oklch(88% 0.01 264);
--color-neutral-500: oklch(55% 0.01 264);
--color-neutral-700: oklch(38% 0.015 264);
--color-neutral-900: oklch(18% 0.015 264);

/* Feedback — same lightness (58%) across all hues */
--color-success: oklch(58% 0.18 150); /* green */
--color-warning: oklch(58% 0.18 65); /* amber */
--color-danger: oklch(58% 0.2 25); /* red */
--color-info: oklch(58% 0.18 220); /* blue */

/* Semantic aliases — what components use */
--color-bg: var(--color-neutral-50);
--color-surface: oklch(100% 0 0);
--color-border: var(--color-neutral-200);
--color-text: var(--color-neutral-900);
--color-text-muted: var(--color-neutral-500);
--color-interactive: var(--color-primary-500);
--color-interactive-fg: oklch(98% 0.01 264);
}
Design Token Palette — Primary + Neutral + Feedback

Using OKLCH for Systematic Palette Generation

The key advantage of OKLCH: fix lightness and chroma, rotate hue — every resulting color has the same perceived brightness. This is what makes systematic multi-color palettes possible.

/* Generate a categorical palette where all colors feel equally prominent */
:root {
--palette-l: 62%;
--palette-c: 0.18;

--cat-red: oklch(var(--palette-l) var(--palette-c) 25);
--cat-orange: oklch(var(--palette-l) var(--palette-c) 60);
--cat-yellow: oklch(var(--palette-l) var(--palette-c) 90);
--cat-green: oklch(var(--palette-l) var(--palette-c) 150);
--cat-cyan: oklch(var(--palette-l) var(--palette-c) 200);
--cat-blue: oklch(var(--palette-l) var(--palette-c) 264);
--cat-purple: oklch(var(--palette-l) var(--palette-c) 310);
}

/* Generate a lightness scale for a single brand hue */
:root {
--brand-h: 264;
--brand-c: 0.18;

--brand-50: oklch(96% calc(var(--brand-c) * 0.3) var(--brand-h));
--brand-100: oklch(90% calc(var(--brand-c) * 0.5) var(--brand-h));
--brand-300: oklch(74% calc(var(--brand-c) * 0.8) var(--brand-h));
--brand-500: oklch(55% var(--brand-c) var(--brand-h));
--brand-700: oklch(40% calc(var(--brand-c) * 0.9) var(--brand-h));
--brand-900: oklch(24% calc(var(--brand-c) * 0.7) var(--brand-h));
}

Color Tools and Resources

These tools are essential for building, testing, and refining color palettes:

  • Adobe Color — Interactive color wheel with all harmony rules, plus an accessibility checker that flags insufficient contrast ratios.
  • OKLCH Color Picker — Pick and adjust colors directly in OKLCH space, with gamut visualization. Essential for building OKLCH palettes.
  • Tailwind CSS Colors — A carefully crafted 10-step scale for 22 hues. An excellent reference for how a professional lightness scale is structured.
  • Coolors — Fast palette generator with harmony rule suggestions, contrast checker, and export options.
  • Realtime Colors — Preview your palette on a real website layout instead of abstract swatches. Helps identify issues before building.
  • Vercel Geist Colors — Vercel's design system palette: a clean example of a production-grade neutral + semantic token system.
  • Huetone — APCA-based palette builder that creates perceptually balanced lightness scales with built-in contrast checking.
  • ColorSlurp — Desktop color picker with OKLCH support and palette management.

Common AI Mistakes

  • Generating colors one at a time without establishing harmonic relationships — the result is a collection, not a palette
  • Using HSL to create "consistent" lightness scales — hsl(60, 100%, 50%) and hsl(240, 100%, 50%) are nowhere near the same perceived brightness
  • Choosing a complementary accent and using it at full saturation for 40% of the UI — complementary colors work only as accents (≤10%)
  • Omitting feedback colors (success, warning, danger, info) from the palette — components then have no token to reach for and hard-coded one-off colors appear
  • Neutral grays with zero chroma — pure oklch(n% 0 0) neutrals feel lifeless; slight tinting toward the brand hue grounds them in the design
  • Defining 40 one-off color values in components instead of 15 semantic tokens — creates maintenance nightmares when the brand color changes
  • Treating the palette as fixed — a good token system lets you change the entire brand hue by updating --brand-h and watching all tokens update automatically

When to Use

  • Design system setup — define the full palette as tokens before writing any component
  • Multi-hue UIs — use harmony rules (analogous, triadic) to choose hues that don't conflict
  • Data visualization — categorical palettes at the same OKLCH lightness prevent one color from dominating
  • Dark mode — a well-structured token layer (semantic aliases over raw values) makes dark mode a palette swap, not a full rewrite
  • Accessible color selection — keep lightness delta between text and background ≥45% in OKLCH for reliable contrast

When a full palette strategy is overkill

  • Single-page landing sites with one brand color and no complex UI states
  • Quick prototypes where tokens add overhead without benefit
  • Email templates where OKLCH support is limited — stick to hex and test widely

References