Repository navigation
fix(frontend): meet WCAG AA contrast and show keyboard focus - #769
Conversation
Darken the success, error, muted, subtle and warning text tokens, the GCP badge and the sort and filter icons so the measured failures pass 4.5:1 (3:1 for icons). Add a --cudly-focus-ring token, a zero-specificity default :focus-visible outline, and use the ring for chips, filters and the recommendation chevron instead of a near-invisible halo. The plan ramp radios are visually hidden rather than display: none, so they are in the tab order, and the card shows the ring on focus. Refs #696, #750 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 5 billable files and costs up to $1.25.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 56 minutes for your next included review. View limit detailsLimit details: You’ve used the included review currently available. Your 87 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (5)
Comment |
Independent review (rv-ux-visual): PR #769 at
|
|
Delta review (independent UX reviewer): conflict resolution at f176679 - APPROVE
|
|
UX merge gate at head f176679 (CLEAN, CI 27/27). Verdict: independent reviewer APPROVED the conflict resolution at this SHA (comment 6085392213); rv-ux-visual APPROVED 26da018. Local evidence from my own merge worktree (macOS): npm ci, tsc --noEmit, jest (100 suites, 3168 passed, 1 skipped), eslint all exit 0; Playwright e2e 136/136 on a private port against a fresh prod build. Merging squash with --match-head-commit. |
Post-merge check (rv-ux-visual)Merged at head |
What
Contrast tokens to WCAG AA and visible keyboard focus (#696, #750). Independent of the other open PRs (branched from main e5ac75d); CSS plus one e2e spec.
Contrast (
base.css,components.css):--cudly-success#34a853 -> #15803d (savings text 3.05 -> 5.0:1; white text on it 5.0:1); button hover greens follow.--cudly-error#ea4335 -> #d93025 (white on it 3.92 -> 4.77:1); hard-coded#d33426hover now uses--cudly-error-fg.--cudly-text-muted#6b7280 -> #4b5563,--cudly-text-subtle#9ca3af -> #6b7280 (4.8:1);.text-muteduses the muted token instead of subtle (2.5 -> 7.5:1; the muted badge text 3.9 -> 6.1:1).--cudly-warn-fg#e65100 -> #b45309 (3.46 -> 4.58:1 on the warn background); GCP badge #4285f4 -> #1a73e8 (3.56 -> 4.51:1); sort and column-filter icons#bbb-> subtle token (>3:1).Focus (
base.css,forms.css,plans.css,components.css):--cudly-focus-ring(surface gap + primary ring) and a zero-specificity default:where(a[href],button,input,select,textarea,summary,[tabindex]):focus-visibleoutline, so components with their own focus style keep it.#eff6ffhalo (1.07:1) or no indicator..ramp-option input[type=radio]wasdisplay:none(bothforms.cssand the duplicate inplans.css): now visually hidden, so it is in the tab order, and the card shows the ring via:has(input:focus-visible).Not changed: charts' JS colour literals, dark mode/theming (#699), the duplicated ramp block (#725).
Refs #696 (VIS-03), #750 (UX-26).
Verification
color-contrastagainst the review mock, 10 pages at 1280 (/tmp/claude/ux-fixes/contrast.js): main fails 5 distinct colour pairs (white/#ea4335 3.92 x23, white/#4285f4 3.56 x8, #34a853/white 3.05 x36, #6b7280/#e5e7eb 3.9 x2, #9ca3af/white 2.53 x1); this head: 0. Per-page counts at 1280/768/390 for 7 pages go from 1-23 nodes to 0 everywhere (/tmp/claude/ux-fixes/r-main.txtvsr-pr4.txt). Measured on the mock data only; states not reachable there (e.g. warning badge,.errortext) are covered by the computed ratios above, not by a render./tmp/claude/ux-fixes/focus.js): on main the ramp radios are not reachable by Tab; on this head Tab reaches the radio and the card computes0 0 0 2px #fff, 0 0 0 4px rgb(37,99,235). Newtests-e2e/ramp-focus.spec.tsfails on a build of main and passes here./tmp/claude/ux-fixes/shots/*-{main,pr4}-*.png; expect green and muted-grey text changes only.🤖 Generated with Claude Code