Skip to content

fix(frontend): WCAG-AA secondary-text contrast + FilterDrawer chip touch target#356

Merged
dackclup merged 2 commits into
mainfrom
claude/sharp-newton-8pj6p
Jun 1, 2026
Merged

fix(frontend): WCAG-AA secondary-text contrast + FilterDrawer chip touch target#356
dackclup merged 2 commits into
mainfrom
claude/sharp-newton-8pj6p

Conversation

@dackclup
Copy link
Copy Markdown
Owner

@dackclup dackclup commented Jun 1, 2026

What

Follow-up from a fresh $impeccable critique re-run (two independent assessments: design-director review + real-browser persona pass + the bundled detector). The re-critique held at 27/40 Nielsen + 16/20 audit — the #355 P1 blockers (FilterDrawer focus-trap + primary touch targets) are confirmed CLOSED in a real browser (15-Tab focus-trap with restore-to-trigger, 21/21 on-screen-vs-JSON, 0 console errors). The score plateau is the IA / help / power-user-flexibility ceiling, not a11y.

This PR ships the user-chosen "a11y residuals + verify dark contrast" thread:

  • Secondary-text contrast (BOTH modes) — normalized the too-light inverted token text-slate-400 dark:text-slate-500 → the project's own standard text-slate-500 dark:text-slate-400 across 16 components/pages. The inverted token fails WCAG AA in both modes (slate-400 #94a3b8 on white ≈ 2.6:1 light; slate-500 #64748b on slate-900 #0f172a ≈ 3.75:1 dark); the standard clears both (≈ 4.8:1 / ≈ 7:1). slate-* is outside the globals.css OKLCH soft-override allowlist, so contrast is on the raw Tailwind hex.
  • FilterDrawer selection chipsmin-h-[44px] lg:min-h-0 (44px tap target on touch viewports, compact ~24px desktop) — the one touch target the fix(frontend): a11y + clarity punch-down (focus-trap · 44px targets · MoS labels · warning hierarchy) #355 sweep missed.
  • Detail-page price-chart placeholder text flipped to the standard token.

Verify-before-fix

The real-browser agent's a11y list had 4 false positives (declined, not changed):

  • 1D/5D aria-disabled already present (PriceTimePeriodSelector).
  • Loss-Chance column is correctly not sortable → omitting aria-sort is right ARIA.
  • Default Score header aria-sort="none" is correct (Rank is the active default sort).
  • Disclaimer "more" button is deliberately min-h-[24px] (documented WCAG 2.5.8 AA floor).

The agent also mis-named the contrast token (reported slate-400 @ 4.2:1) — the real failing token was slate-500, and the failure spanned both modes, not dark-only. Verifying caught both.

Correctly left faint (do NOT re-fix): disabled controls (WCAG 1.4.3 inactive exemption) + decorative aria-hidden icons.

Verification

  • tsc --noEmit clean · next build 506/506 routes
  • frontend-design-reviewer contrast/regression review in progress (verdict to follow)
  • 16 component/page files, +39/−39 (symmetric token flip + chip min-h) + the committed critique snapshot
  • No compute / schema / scoring / valuation change
  • CLAUDE.md §Gotchas + AGENTS.md mirror record the secondary-text-token standard; PHASE_STATUS_INFLIGHT.md entry added

https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi


Generated by Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

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

Project Deployment Actions Updated (UTC)
quantrank Ready Ready Preview, Comment Jun 1, 2026 1:40pm

claude added 2 commits June 1, 2026 13:38
…uch target

$impeccable critique re-run follow-up. Normalize the too-light secondary-text
token text-slate-400 dark:text-slate-500 (fails WCAG AA in both modes: ~2.6:1
light / ~3.75:1 dark) to the project standard text-slate-500 dark:text-slate-400
(~4.8:1 / ~7:1) across 16 components/pages. Add min-h-[44px] lg:min-h-0 to the
FilterDrawer selection chips (the touch target #355 missed). Flip the detail-page
price-chart placeholder text to the standard token.

Verified: tsc --noEmit clean + next build 506 routes. slate-* is outside the
globals.css soft-override allowlist so contrast is on raw hex; disabled controls
+ decorative aria-hidden icons correctly left faint. No compute/schema/scoring change.

https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi
… decorative-icon aria-hidden

frontend-design-reviewer follow-up on the secondary-text contrast PR.
RawMetricsTable hint + missing-value text on the even:bg-slate-100 stripe was
4.34:1 (slate-500) — bumped to slate-600 (~6.85:1) to clear WCAG AA on the darker
row; white/odd rows already passed. Added aria-hidden="true" to the two
decorative search-icon SVGs (RankingTable + FilterDrawer).

Verified tsc clean + next build 506 routes.

https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi
@dackclup dackclup force-pushed the claude/sharp-newton-8pj6p branch from 09146ac to 33e8e2a Compare June 1, 2026 13:39
@dackclup dackclup merged commit dd56dc1 into main Jun 1, 2026
4 checks passed
@dackclup dackclup deleted the claude/sharp-newton-8pj6p branch June 1, 2026 13:41
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