Design Systems 7 min read October 2026

How to Build an Accessible Color Palette in Figma Variables

Building a design system color scale shouldn't mean guessing contrast ratios for dozens of tokens. Here is how to create compliant tonal palettes in Figma Variables with mathematical precision.

How to Build an Accessible Color Palette in Figma Variables

The Problem with Traditional Tonal Scales (50–900)

Most modern design systems structure their color tokens into numbered scales: slate-50, slate-100, up to slate-900. Designers frequently assume that pairings like 500 on white or white on 600 automatically guarantee sufficient contrast.

In practice, this assumption fails constantly. A pure blue (#0000FF) at 50% lightness looks completely different to the human eye than a pure yellow (#FFFF00) at 50% lightness:

When teams generate shade scales using standard RGB or HSL interpolation, colors shift unevenly, creating muddy midtones and unexpected contrast failures.

Step 1: Understand Why HSL Breaks Color Scales

Traditional digital design relies on sRGB and HSL color spaces. However, HSL is not perceptually uniform: the human eye contains vastly more cone receptors for green and red light than for blue light.

To solve this, modern color scientists and CSS specifications recommend OKLab (developed by Björn Ottosson). In OKLab, changing the lightness coordinate (L) changes perceived brightness uniformly across all hues without altering chromatic purity or hue angles.

The "Contrast Delta" Principle

In an accessible design system, you should be able to predict contrast mathematically by token step distance:

Rule of thumb: A distance of at least 500 steps (e.g. shade-900 on shade-100, or shade-50 on shade-700) should reliably guarantee at least 4.5:1 contrast across all neutral scales.

Step 2: Structuring Primitive vs. Semantic Variables in Figma

Never bind raw hex numbers or primitive steps directly to UI components. In Figma Variables, structure your system into two distinct collections:

1. Primitives Collection (The Raw Spectrum)

Contains raw, immutable color values organized by family and lightness step:

  • color/slate/50 → #F8FAFC
  • color/slate/100 → #F1F5F9
  • color/slate/500 → #64748B
  • color/slate/700 → #334155
  • color/slate/900 → #0F172A

2. Semantics Collection (Role-Based Tokens with Modes)

Contains aliases that switch between Light Mode and Dark Mode automatically:

Semantic Token Light Mode Target Dark Mode Target Expected Contrast
text/primary color/slate/900 color/slate/50 ≥ 14.0:1 (AAA)
text/secondary color/slate/700 color/slate/200 ≥ 5.2:1 (AA)
text/muted color/slate/600 color/slate/300 ≥ 4.6:1 (AA)
border/default color/slate/300 color/slate/700 ≥ 3.1:1 (UI AA)

Step 3: The Dangerous 600-Shade Button Trap

One of the most frequent accessibility bugs caught in design system audits is the Primary Brand Button:

Button Fill: #0D99FF (Figma Blue) with White Text (#FFFFFF) → Contrast Ratio: 2.82:1 (Fails WCAG AA — test in free calculator)

Vibrant brand colors (blues, teals, oranges) are often chosen for marketing punchiness. But white text on vibrant blue almost always fails the 4.5:1 requirement unless the text is large (≥24px or ≥18.66px bold).

Two Compliant Solutions:

  1. Darken the button fill: Shift blue from #0D99FF to #0075D4 (reaches 4.55:1 against white).
  2. Invert to dark text: Use deep navy text (#051D38) over light brand background (#B9E3FF).

Step 4: Auditing the Full Palette with TintSense in Figma

Once your Figma Variables are mapped, create a dedicated Design Tokens Documentation Frame containing sample text swatches of every semantic pairing (learn more about our Design Tokens & Insights engine).

  1. Open TintSense in Figma (⌘R).
  2. Run a Batch Frame Scan on the documentation artboard.
  3. TintSense automatically evaluates all nested variants and checks text contrast against background containers.
  4. For any token pairing that falls below 4.5:1, click Smart Fix. TintSense calculates the optimal OKLab lightness shift that satisfies WCAG without drifting your brand hue.
  5. Update the corresponding Figma Variable value with the suggested hex code.

Summary

A robust design system should make doing the right thing effortless for product designers. By mapping token aliases with verified contrast deltas and testing with TintSense, your entire team can build compliant screens without manual guesswork.

DESIGN SYSTEM ACCESSIBILITY

Audit design tokens automatically in Figma

Install TintSense for free. Batch scan component libraries and verify color variable contrast directly in your files.