Skip to content

A11Y-001: a status chip on a status-tinted row is readable - #996

Merged
NewWorldVenture merged 2 commits into
mainfrom
claude/a11y-001-nested-status-chip-etzqg7
Oct 11, 2026
Merged

NewWorldVenture merged 2 commits into
mainfrom
claude/a11y-001-nested-status-chip-etzqg7

Conversation

@NewWorldVenture

Copy link
Copy Markdown
Owner

A11Y-001: follows #994. That PR merged at fd9eeb2 before this owner finding could ride it.

The defect

#994 held each status role's text to 4.5:1 on the strongest tint that one class string pairs with it. A chip can also sit on another element's tint. In the reminders list:

  • a snoozed reminder's row is bg-warning/5 (components/modules/reminders-module.tsx, the row's cn());
  • an overdue one's row is bg-danger/5;
  • each row carries Badges (bg-<role>/15 text-<role>, components/ui/badge.tsx): one for its priority (medium is warning; high and urgent are danger) and one for its state.

The two tints compound to an effective 19.25%. With #994's light --warning, a warning chip reads:

Chip Ground Ratio
Warning chip on a snoozed row over --bg 4.27
Warning chip on an overdue row over --bg 4.23

The fix

--warning (light) is darkened once more, the way the token block prescribes: hue and saturation held, lightness reduced, to the first value that clears 4.5:1 on that nested ground.

Token Was Now
--warning (light) 129 93 16 123 88 15
  • The worst nested case is now 4.53. Warning on --bg is 6.04, and white on warning as a solid fill is 6.47.
  • design/tokens.json, which the mobile app reads, moves with it.
  • Dark-theme tokens and the other roles are unchanged. Danger chips on either row already clear 4.5 (4.58 at worst).

Tests

tests/brand-contrast-contract.test.ts, new block: "a status chip on a status-tinted reminder row is readable".

  • Reads, from the source, the row's tint for each state, Badge's tones, and the tones a row can show (PRIORITIES plus the snoozed and overdue Badges).
  • Composes them over every ground, in both themes.
  • Non-vacuity: both row tints are found, and the chip roles are exactly warning and danger.

tests/e2e/a-status-chip-on-a-tinted-row.spec.ts (Chromium, no account):

  • Builds each row from the component's own class strings, merged with the same cn(), and builds its Badges from Badge's tone strings. These go on the sign-in page over bg-bg, bg-surface and bg-elevated.
  • Composes each chip's background from the computed background of every ancestor up to the first opaque one, and checks there are exactly three layers: the chip, the row and the ground.
  • A control sets the previous --warning on the fixture and shows that the same measurement then fails at 4.2x.
Check main This branch
New unit block light fails: 4.27, 4.23 passes
New browser spec (production build, local) — 3/3; its control, with the previous --warning set on the fixture, measures 4.2x on both rows over bg-bg
Real /dashboard/reminders, a disposable household with snoozed and overdue reminders at medium, high and urgent priority, composed computed styles (author-run, local, not committed) worst warning chip 4.23 (overdue row) and 4.26 (snoozed row), with the previous token set on the page worst 4.53; every chip 4.53–4.65; dark theme 5.48 and up, unchanged
brand-contrast and design-tokens suites — 24/24
Full unit suite / tsc / eslint — 30,914 passed (the 3 failures are this container's Node 22 against the pinned Node 24, red on main too) / 0 / 0 errors

Limits

A clean run here does not mean every chip is readable. The flat scan and this block still miss:

  • nesting across files (a tinted card in one component, a chip in another);
  • text colour inherited from an ancestor;
  • class strings split over lines or built at runtime.

A same-file search for other tinted containers holding a status chip found none beyond this row. Status text directly on a /5–/10 box, such as the overdue banner or the contacts emergency strip, is a flat tint that #994's bound already covers. That search is a heuristic, not a proof.

No component, configuration or dependency change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TRY21ZKsFrfB3qtoP972A4


Generated by Claude Code

A snoozed reminder's row is bg-warning/5 and an overdue one's bg-danger/5,
and each carries a warning Badge (bg-warning/15) for its priority or its
snooze. The tints compound to 19.25%, where the light theme's --warning read
4.23 over --bg. Darken it once more, hue and saturation held, to the first
value that clears 4.5 on that nested ground (123 88 15, 4.53); the mobile
tokens move with it.

The contract test composes the row's tint and the Badge's from the source,
in both themes; a new Chromium spec builds the row and Badges from the
components' own class strings, measures computed backgrounds through every
ancestor, and shows the previous token failing the same measurement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TRY21ZKsFrfB3qtoP972A4
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
bubaly Ignored Ignored Oct 11, 2026 12:21am UTC

Request Review

#1001 landed first and edited the same light token block and the same test
file. Kept #996's extended comment and --warning: 123 88 15 beside #1001's
--accent: 169 66 21, and both new describe blocks, each with its own closing
lines. brand-contrast-contract, design-tokens, the palette, read-only-field
and readiness-score tests pass on the merge (8 files, 105 tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
@NewWorldVenture
NewWorldVenture marked this pull request as ready for review October 11, 2026 01:06
@NewWorldVenture
NewWorldVenture merged commit 64fa338 into main Oct 11, 2026
9 checks passed
NewWorldVenture pushed a commit that referenced this pull request Oct 11, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
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.

2 participants