Building a color palette that passes WCAG accessibility requirements is not about sacrificing aesthetics — it is about understanding how luminance works and making deliberate choices at the scale-design stage. Retrofitting contrast into an existing palette is painful; designing for it from the start takes the same amount of time and produces far better results.

Why most palettes fail contrast checks

The root cause is almost always the same: the palette was designed by eye in a saturated, idealized environment — a bright monitor, a design tool canvas with a neutral grey background — where the eye naturally compensates for low luminance differences. When that palette reaches a real product with white page backgrounds and body-sized text, the contrast ratios collapse.

A second common mistake is designing a single "brand color" and using it for everything: buttons, links, text, highlights, and borders. A mid-tone hue at around 50% lightness typically achieves around 3–4:1 on white — which passes for large text and UI components, but fails for normal body text and small labels.

The accessible palette design process

Think in terms of roles rather than individual colors. Every palette needs colors that fulfill specific contrast roles:

Building a contrast-safe color scale

The most reliable method is to build a lightness scale for each hue. A scale of 11 steps — typically labeled 50, 100, 200, … 900, 950 — gives you a predictable set of shades where you can identify in advance which steps pass which contrast thresholds against white and against dark backgrounds.

A practical approach in HSL: fix the hue (H) and saturation (S), then vary the lightness (L) from 97% down to 10% in 11 steps. For most hues:

Run the contrast checker for each adjacent pair in your scale. The ratio between step 700 and white is the most important check — it tells you whether your primary interactive color can carry body-weight text.

Handling your brand primary color

Most brand primary colors live in the mid-tone range because saturated, mid-lightness colors read as vivid and energetic on screen. If your brand primary is something like a mid-blue (#2563EB), a teal, or a coral, you have a few options:

Dark mode palettes and accessible contrast

Dark mode does not simply invert the contrast problem — it changes it. On a dark background (e.g., #121212), a pure white (#FFFFFF) achieves 19.6:1, which is the maximum and can cause visual fatigue. The recommended practice is to use a slightly off-white (#E8E8E8) which achieves around 15:1 — still far above AAA but less visually harsh.

For secondary text in dark mode, aim for shades in the 60–75% lightness range — these typically hit the 4.5:1 threshold against a dark background while reading as visually softer than the primary text.

Documenting accessible color pairs

A palette document that lists hex values without specifying valid usage pairs is incomplete. Every design system handoff should include an explicit list of approved color pairs — foreground + background — with their contrast ratio and the WCAG level achieved. This prevents developers from inadvertently picking two colors from the palette that were never tested together.

A simple format: list each approved pair as a row with the foreground hex, background hex, ratio, and a pass/fail note for AA and AAA at both normal and large text sizes. This becomes the single source of truth for contrast decisions across the product.