How does Huetone help create accessible color palettes?
Updated
Huetone builds palettes in the LCH color space, which separates lightness (L) from chroma (C) and hue (H). Because lightness is an independent, numeric axis, you can generate a set of shades where each step has a predictable, evenly spaced lightness value — and lightness is the main factor that determines whether text stays readable against its background. That predictability is what makes accessibility checks easier: instead of guessing which shade is dark enough, you pick a target lightness and verify the contrast ratio.
The accessibility metric that matters here: contrast ratio
Accessible text depends on the contrast ratio between foreground and background colors, defined by WCAG. The thresholds most teams work against:
| Content type | Minimum ratio (AA) | Enhanced (AAA) |
|---|---|---|
| Normal body text | 4.5:1 | 7:1 |
| Large text (roughly 18pt+ or 14pt+ bold) | 3:1 | 4.5:1 |
| UI components / graphical objects | 3:1 | — |
Contrast ratio is computed from the relative luminance of the two colors, not from their hue. This is why a palette organized around lightness is easier to make accessible than one organized around, say, HSL saturation or a hand-picked set of hex values.
Why LCH lightness helps
In LCH, the L value is perceptual lightness on a consistent scale. Two colors with the same L look similarly light to the eye, even if their hues differ. Practical consequences for palette building:
- Even steps stay even. If you generate shades at L = 90, 80, 70, … the perceived jump between each pair is roughly constant, so a "600" shade is reliably darker than a "500" shade across every hue in your system.
- Hue changes don't secretly change lightness. You can swap a blue for a green at the same L and expect similar contrast behavior against a fixed background — something that is not true when you pick colors by eye or by HSL.
- You can target a contrast goal directly. To make text readable on a light background, you lower the foreground's L until the ratio clears 4.5:1. To keep a dark-mode surface comfortable, you raise the background's L while keeping text light.
The trade-off: LCH is a perceptual model, and some highly saturated colors fall outside the sRGB gamut at certain L/C combinations. If a chosen L and chroma can't be displayed, the rendered color shifts, so verify the final hex values rather than trusting the L number alone.
How to check a foreground/background pair
- Pick the pair you actually ship. Use the real text color and the real surface color, not approximations.
- Compute the contrast ratio. Use a WCAG contrast checker, or compute relative luminance from the sRGB values and apply the (L1 + 0.05) / (L2 + 0.05) formula.
- Compare against the threshold for that content type from the table above.
- Adjust lightness, not hue, if it fails. Move the foreground L down (on light backgrounds) or up (on dark backgrounds) until the ratio clears the bar, then re-check.
- Re-verify after any change, including opacity, overlays, or gradients, which alter the effective colors.
A common failure point: a color passes on a pure white background but fails on a tinted surface, or passes at full opacity but fails when the text is set to 80% opacity. Always test the composited result.
Where predictable scales pay off
A consistent lightness ladder lets you define rules instead of one-off decisions:
- Body text uses a shade guaranteed to clear 4.5:1 against the page background.
- Secondary or muted text uses the next step up, checked separately — muted text is a frequent accessibility miss.
- Borders and icons use a shade that clears 3:1 against their surface.
- Dark mode reuses the same ladder in reverse, so the same contrast logic applies.
Because the steps are evenly spaced and hue-independent, you can apply one rule across every color in the system and expect consistent results, rather than re-testing each hue from scratch.
Limits to keep in mind
- Huetone's LCH approach makes contrast predictable and checkable; it does not automatically certify a palette as WCAG-compliant. You still run the contrast check on the final colors.
- Contrast ratio is necessary but not sufficient for accessibility. Color alone shouldn't carry meaning (add labels, icons, or patterns), and focus indicators, motion, and text sizing matter too.
- Gamut clipping can change a color's actual luminance, so verify the exported values, not just the intended L.
If your goal is a palette where accessibility is a property of the system rather than a per-color afterthought, building on LCH lightness and verifying each shipped pair against the WCAG thresholds is the workable path.