Skip to content

fix: make status palette colour-blind-safe - #501

Open
QingqiShi wants to merge 2 commits into
mainfrom
fix/colorblind-status-palette
Open

fix: make status palette colour-blind-safe#501
QingqiShi wants to merge 2 commits into
mainfrom
fix/colorblind-status-palette

Conversation

@QingqiShi

@QingqiShi QingqiShi commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Why

The status colour tokens (info / success / warning / danger) paired a pure green for success against red for danger — the classic red-green colour-blindness trap that affects ~8% of men. Success and danger were only borderline distinguishable, and in dark mode they collapsed together for deuteranopes. This makes the status palette colour-blind-safe while keeping the conventional green / amber / red semantics everyone expects.

What changes

The fix follows established CVD guidance — never rely on red vs green alone; the reliable lever is to shift green toward a blue-green. Each status pair was then checked with a Machado-2009 CVD simulation, measuring perceptual distance (ΔE) under both deuteranopia and protanopia:

  • Success moves from pure green to emerald (a blue-shifted green that survives red-green CVD), in both light and dark themes. This is what actually resolves the success-vs-danger confusion (ΔE ~9–23 → ~21–43).
  • Danger stays a vivid red-700 — the brightest AA-safe red on the tint. Deepening it was considered and rejected: it only bought marginal warning-vs-danger separation while dimming the red for the very red-blind viewers this change helps (lower protanope-perceived lightness, smaller distance from neutral dark text).
  • Warning stays amber and Info stays blue: testing showed orange would make warning harder to tell from both danger and success, and blue is the safe anchor colour.

Warning-vs-danger is inherently a weak colour distinction (red and amber both collapse toward yellow under deuteranopia) and is not solved by colour alone — it belongs to icons + text at the component layer.

Result

The critical success-vs-danger pair is now clearly distinguishable under simulated deuteranopia and protanopia in both themes, and all foreground/background pairs still meet WCAG AA (≥4.5:1). --destructive is aliased to the danger foreground token, so all shadcn error surfaces stay consistent and above AA. Verified visually on the /brand guidelines page in both light and dark themes.

Follow-up

Full CVD robustness needs status to never rely on colour alone — success/warning/danger alerts should carry distinct icons (✓ / ⚠ / ✕) and text. That is a component/usage change, out of scope for this token PR.

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
uk-student-loan-study Ready Ready Preview Aug 20, 2026 8:15am

Request Review

Deepening danger to red-800 only bought marginal warning/danger separation
while darkening the red for the red-blind viewers the change is meant to help
(protanope-perceived lightness drops, and its distance from neutral dark text
shrinks). red-700 is the brightest AA-safe red on the tint; warning-vs-danger
is disambiguated by icons + text at the component layer, not by colour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant