Skip to content

feat: one dialog shell, visible focus, token contrast and axe in CI (UX-10, part A) - #214

Merged
bri-b-dev merged 1 commit into
mainfrom
b/a11y-system
Oct 11, 2026
Merged

bri-b-dev merged 1 commit into
mainfrom
b/a11y-system

Conversation

@bri-b-dev

Copy link
Copy Markdown
Owner

Summary

Part A of UX-10 (inline styles, emoji icons and hard-coded colors/radii follow in part B).

  • One dialog: DialogShell (+ useFocusTrap, useScrollLock) replaces six hand-rolled variants (shuffle, filter sheet, result sheet, live view, onboarding, settings) and the confirm modal. Dialog semantics (role, aria-modal, labelled/described by), focus moves in, Tab stays inside, Escape, focus returns to the opener, page scroll locked (counted for stacked dialogs), layer tokens, safe areas on all sides. Variants: center, bottom sheet, side panel, full screen
  • Focus indicator: a solid 3 px outline in --focus (>= 3:1 on both themes) for every keyboard-focusable control, instead of the faint translucent glow; no ring for mouse clicks (:focus-visible)
  • Tokens: --focus, --border-strong (form controls >= 3:1; the plain --border was 1.2:1), --danger-ink (error text; #ef4444 was 3.8:1), --level-*-ink, spacing/radius/font-size scales, z-index layers, touch target. Tailwind now references the tokens (colors, radius, z-index, shadow)
  • Safe areas: left/right (notch in landscape), tab bar, content bottom padding
  • Tests in CI: tests/a11y/contrast.test.ts reads the real theme.css and checks 16 pairs x 2 themes; tests/a11y/axe.test.ts runs axe-core over 18 real screens and dialogs - serious/critical violations fail the build. npm run a11y is a separate CI step. The old static-HTML scripts/axe-check.mjs (never run in CI) is removed

Bugs fixed on the way

  • Settings: 3 selects and 3 switches had no accessible name (axe: critical); the name field and the HCP label were not associated either
  • Settings panel padding used var(1rem) / an undefined --base-padding, which invalidates the declaration: the top padding was 0 and the close button could sit under the status bar
  • The confirm dialog had a hard-coded white background (broken in dark mode), no Escape and no focus handling; it now focuses "Abbrechen" and resolves false on Escape/backdrop

Notes

  • Color contrast of rendered pages cannot be measured in jsdom; the token test covers the palette, a real-device check is in the test plan
  • Part B: remove the 53 inline style="" attributes, replace emojis with an SVG icon set, replace hard-coded hex colors and radii with tokens

Test plan

  • npm test (437), npm run lint, npm run typecheck, npm run build (local)
  • CI (new step npm run a11y)
  • Manual: keyboard only through Today, catalog + filter sheet, a drill session (live view, result sheet), settings, shuffle; focus ring visible in light/dark; Escape and focus return for every dialog; VoiceOver/TalkBack announces dialogs; settings panel below a translucent status bar; landscape with a notch

🤖 Generated with Claude Code

…UX-10, part A)

- DialogShell + useFocusTrap + useScrollLock for shuffle, filter, result, live, onboarding, settings
  and confirm: dialog semantics, focus in/trap/return, Escape, scroll lock, layers, safe areas
- solid 3px focus ring (--focus) instead of a faint glow; --border-strong for form controls;
  --danger-ink for error text; level colors, spacing, radius, type and z-index tokens; Tailwind reads them
- tests: token contrast from theme.css (both themes) and axe-core over 18 real screens/dialogs
  (serious/critical fail the build); `npm run a11y` in CI
- fixes: unlabeled selects/switches in settings, invalid settings-panel padding, confirm dialog
  ignored the dark theme and had no focus handling
- tests (437)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@bri-b-dev
bri-b-dev merged commit 4e0250a into main Oct 11, 2026
1 check passed
@bri-b-dev
bri-b-dev deleted the b/a11y-system branch October 11, 2026 08:47
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