From 4530004d87ffd8ee341d2d43a8fc05bbd11e1baa Mon Sep 17 00:00:00 2001 From: Anders Olsson Date: Mon, 8 Jun 2026 09:39:28 +0200 Subject: [PATCH] =?UTF-8?q?docs(plans):=20a11y=20focus/route/skip/semantic?= =?UTF-8?q?s=20=E2=80=94=202-task=20plan=20(#52)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/2026-06-08-a11y-focus.md | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 docs/superpowers/plans/2026-06-08-a11y-focus.md diff --git a/docs/superpowers/plans/2026-06-08-a11y-focus.md b/docs/superpowers/plans/2026-06-08-a11y-focus.md new file mode 100644 index 0000000..ddc86af --- /dev/null +++ b/docs/superpowers/plans/2026-06-08-a11y-focus.md @@ -0,0 +1,217 @@ +# Accessibility — Focus, Route Management, Honest Semantics — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Give every custom control a keyboard focus ring, make the authority "tabs" + lang switch honest, add a skip link + route focus management, and sync `` on language change. + +**Architecture:** A shared `focusRing` class is applied to the five bare controls. Authority tabs become honest `NavLink`s (`aria-current`), the lang switch gains a `role="group"`. The app-shell adds a skip link, a focusable `
`, and a route-change focus effect. A single `i18n.on("languageChanged")` listener syncs `document.documentElement.lang`. + +**Tech Stack:** React 19 + TS + pnpm, react-router 7 (`NavLink`/`useLocation`), react-i18next, Tailwind v4, Vitest + RTL. Test runner: `pnpm test` (single pass). + +**Conventions:** pnpm; **no `any`/`eslint-disable`/`@ts-ignore`**; no codename; en/sv parity (2 new keys); app source double-quote+semicolon; token classes only (`focus-visible:ring-ring` is a token); `focus-visible:` (not `:focus`) so mouse clicks don't ring. + +**Spec:** `docs/superpowers/specs/2026-06-08-a11y-focus-design.md` + +**Key facts (from code):** +- Bare controls lacking a ring: `lang-switch.tsx` (2 buttons, no `type`, inactive `text-muted-foreground`), `theme-switch.tsx` (3 icon buttons, `cn(...)`), `search-panel.tsx` facet chips (`className={\`rounded-md px-2 py-0.5 ${active ? … : "border"}\`}`), `field-list.tsx` row ` + ))} + + ); +} +``` + +- [ ] **Step 4: theme-switch.tsx** — add `focusRing` to the button `cn(...)`: change the `cn("rounded-md p-1 transition-colors", active ? … : …)` to include `focusRing` as a class arg. Import `focusRing`. + +- [ ] **Step 5: search-panel.tsx** — the facet chip `