Kimosabe.AI

WCAG 2.2 AA Audit Checklist

Tracks NFR-07 / NFR-08. Re-run before every release. Findings go into CHANGELOG.md under the release that fixes them.

Tooling:

  • axe-core (manual + future CI gate) — automated catches ~40% of issues.
  • Keyboard-only walkthrough — no mouse, every flow.
  • VoiceOver (macOS / iOS) + NVDA (Windows) spot checks.
  • prefers-reduced-motion + prefers-contrast OS toggles.
  • Mobile 430×697 viewport (our design target).

Status legend: ✅ pass · 🚧 finding open · ⏳ not yet audited


Per-route checklist

Route Initial Keyboard Screen reader Reduced motion Contrast
/ ✅ ✅ ✅ ✅ ✅
/trust ✅ ✅ ⏳ ✅ ⏳
/login ✅ ✅ ✅ ✅ ⏳
/signup ✅ ✅ ✅ ✅ ⏳
/forgot-password ✅ ✅ ⏳ ✅ ⏳
/reset-password ✅ ✅ ⏳ ✅ ⏳
/_authenticated/home ✅ ✅ ⏳ ✅ ⏳
/_authenticated/new ✅ ✅ ⏳ ✅ ⏳
/_authenticated/c/$id ✅ ✅ ⏳ ✅ ⏳
/_authenticated/settings ✅ ✅ ⏳ ✅ ⏳

Cross-cutting checks

Perceivable

  • 1.1.1 Non-text content — every meaningful image has alt; logo decorative alt="".
  • 1.3.1 Info and relationships — semantic landmarks (<main>, <nav>, <header>, <footer>) on every route.
  • 1.4.3 Contrast (minimum) — body text ≥ 4.5:1, large text ≥ 3:1 against the deep-purple ground in both default and prefers-contrast: more.
  • 1.4.4 Resize text — no clipping at 200% browser zoom.
  • 1.4.10 Reflow — no horizontal scroll at 320 CSS px width.
  • 1.4.11 Non-text contrast — focus rings, switch borders, gold accents ≥ 3:1 against background.
  • 1.4.12 Text spacing — layout survives bumped letter/line spacing.
  • 1.4.13 Content on hover or focus — tooltips dismissible, hoverable, persistent.

Operable

  • 2.1.1 Keyboard — every interactive element reachable via Tab.
  • 2.1.2 No keyboard trap — modals, drawers, the composer all release.
  • 2.4.3 Focus order — visual order matches DOM order.
  • 2.4.7 Focus visible — every focusable element shows a ring with ≥ 3:1 contrast.
  • 2.4.11 Focus not obscured (minimum) — no sticky header hides focused inputs (especially the composer at 430px).
  • 2.5.5 Target size (enhanced — 2.2) — interactive targets ≥ 24×24 CSS px, ideally 44×44 on touch.
  • 2.5.7 Dragging movements (2.2) — no drag-only interactions; the attachment picker has a tap fallback.
  • 2.5.8 Target size (minimum — 2.2) — confirm message bubbles' action menu meets minimum.
  • 3.2.6 Consistent help (2.2) — /trust link reachable from every page in the same place.
  • 3.3.7 Redundant entry (2.2) — signup never re-asks for email.
  • 3.3.8 Accessible authentication (minimum — 2.2) — recovery code can be pasted; no cognitive puzzle required.

Understandable

  • 3.1.1 Language of page — <html lang="en"> set.
  • 3.3.1 Error identification — every form error names the field and the fix.
  • 3.3.2 Labels or instructions — recovery code field explains the 24-char format and the dash convention.

Robust

  • 4.1.2 Name, role, value — switch components expose role="switch" + aria-checked. shadcn/ui defaults verified.
  • 4.1.3 Status messages — toast notifications use aria-live.

Motion

  • All decorative animations respect prefers-reduced-motion: reduce.
  • Send-message bubble entrance is replaced with a fade for reduced motion.
  • No auto-playing video or parallax.

Open findings

(none yet — initial pass scheduled)

2026-05-09 — first pass

Fixed

  • F-01 / 2.3.3 Reduced motion — global prefers-reduced-motion: reduce rule in src/styles.css collapses all decorative animations (logo breathe, fade-up entrance, pulse-ring) to ~0ms and forces fade-up content to its final visible state so nothing stays invisible.
  • F-02 / 2.4.1 Bypass blocks — added a focus-revealed "Skip to content" link in src/routes/__root.tsx. Targets #main-content on every route shell.
  • F-03 / 1.3.1 Landmarks — /, /login, /signup, /404 now expose a single <main id="main-content"> landmark.

Open

  • F-04 / 1.4.3 Contrast — measured 2026-05-09 with proper sRGB conversion. Body text 15.4:1, gold accents 9.6:1, muted-foreground 5.3:1, gold-dark 5.3:1 — all pass AA. Fixed: --input raised from 1.32:1 to 3.21:1 (oklch 0.50) so form-control borders meet WCAG 1.4.11. --border kept subtle (1.32:1) since it's only used on decorative dividers.
  • F-05 / 2.4.7 Focus visible — confirm the rounded gold inputs render a visible ring on Safari iOS (focus-visible quirks).
  • F-06 / 2.5.5 Target size (2.2 AA) — composer send button is 32×32; bump to ≥ 24×24 with adequate spacing or to 44×44 on touch.
  • F-07 / _authenticated/* routes — entire authed surface still ⏳.