[1.56.1] — 2026-05-19
fix(a11y): suppress the spurious brand focus ring on router-managed tabindex="-1" heading focus.
🐛 Fixes
- A red box framed every view's
<h1>(regression surfaced by v1.56.0 UX-12, rooted in the v1.41.0 SPA focus-management pattern).public/js/router.jsgives each destination view's headingtabindex="-1"and.focus()'s it on every client-side navigation so screen readers announce the new page. Atabindex="-1"element is never keyboard-reachable, yet Chromium's:focus-visiblemodality heuristic still painted the global brand ring (*:focus-visible { outline: 2px solid var(--rausch) }) around it — a red rectangle around the page heading (e.g. "Command Center" on#/dashboard) on every navigation, which had also been baked into theimages/dashboard-*.pnghero screenshots. The fix is one scoped rule —[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline: none }— the WAI-ARIA APG managed-focus pattern. Genuine keyboard focus on real interactive controls keeps the global*:focus-visiblering (WCAG 2.4.7 intact); the skip-link's ring is unaffected (it is an<a>, nottabindex="-1", with a higher-specificity rule). - All 8
images/dashboard-*.pngregenerated against the fixed UI — the README hero screenshots no longer show the red box.
🧪 Tests
- New CI-isolated source-static suite
tests/managed-focus-no-ring.test.mjs(4): the global*:focus-visiblebrand ring is still defined (WCAG 2.4.7 not regressed);[tabindex="-1"]:focus, :focus-visibleresolves tooutline: none; the suppression rule follows the global rule (cascade safety); the fix stays scoped (no blanket*:focus { outline: none }). Pairs with the existingtests/dashboard-initial-focus.test.mjs(router still sets tabindex + focuses on navigation). 813 → 817.