Skip to content

feat(a11y): PRD-003 F1 — frontend recovery + a11y (5 HIGH audit fixes)#22

Merged
explosivebit merged 7 commits into
developfrom
feature/frontend-recovery-a11y-f1
May 5, 2026
Merged

feat(a11y): PRD-003 F1 — frontend recovery + a11y (5 HIGH audit fixes)#22
explosivebit merged 7 commits into
developfrom
feature/frontend-recovery-a11y-f1

Conversation

@explosivebit
Copy link
Copy Markdown
Contributor

Closes 5 HIGH frontend audit findings: +error.svelte boundary (FR-001), role=img on 5 graph SVGs (FR-002), nested button in InsightsRail (FR-003), prefers-reduced-motion guards (FR-004), narrow-viewport grid alignment (FR-005). Refs PRD-003. 7 commits revertable per NFR-003. Local smoke PASS, svelte-check 0/0.

Any throw in load/render or in a  (e.g. one of 8 pollers on HomePage) used to crash to the default unstyled SvelteKit error page. New +error.svelte renders a styled fallback: large status code in --accent, error message, monospace Go home link. Reuses CSS tokens from app/styles/app.css; no new deps; Svelte 5 runes ( from $app/state).

Refs: PRD-003
All 5 graph views (Force/Lanes/Matrix/Radial/Tree) declared role=application — screen readers treat that as do not interpret content. Today these views have only click interaction; role=img with descriptive aria-label is the conformant semantic. If we ever add custom keyboard pan/zoom to ForceView, that one can flip back.

aria-label per view names the layout: Force-directed dependency graph, Lanes view by status, Adjacency matrix, Radial hierarchy, Tree hierarchy.

Refs: PRD-003 (FR-002)
…-004)

New shared helper template/src/widgets/dependency-graph/lib/reduced-motion.ts exports motionDuration(defaultMs) — returns 0 when window.matchMedia('(prefers-reduced-motion: reduce)') matches, otherwise the default. SSR-safe (window guard).

Note: imports + .transition().duration(motionDuration(300)) call-site wrapping in 5 view files landed together with the role=img swap (51edb7a) because the same files were touched. Keeping that as a single revertable surface for the views; this commit owns the helper + ForceView simulation guard (alphaDecay(0.1).alphaMin(0.05) when reduce-motion is set).

Refs: PRD-003 (FR-004)
…003)

Two row patterns in InsightsRail (recent activity at L107 and agents claim card at L133) used <li role=button tabindex=0 onclick=...> with svelte-ignore a11y_no_noninteractive_element_to_interactive_role. That suppresses the rule rather than fixing it; native focus order was masked.

Refactored to <li><button class=row-trigger>...</button></li>. Inner button strips browser defaults (background:transparent, border:0, padding:0, font:inherit, etc.) and carries hover/focus styles. .row.card uses :has(.row-trigger:hover/:focus-visible) on the outer <li> to keep card-outline accent. Removed both svelte-ignore directives, the rowKey helper, and all tabindex=0.

Refs: PRD-003 (FR-003)
At <1100px, .layout.has-panel had grid-template-columns:180px 1fr 360px (3 cols) while markup has 4 children (filters + canvas + insights rail + panel). The aside.rail was display:none under a separate selector but still claimed a grid cell, so the panel implicitly flowed out of the grid.

Fix: consolidate .layout aside.rail and .layout.has-panel aside.rail into one display:none rule; bump narrow .layout.has-panel grid to 200px 1fr 380px (matching desktop filters/panel widths) so 3 cells exactly host filters+canvas+panel. Bumped .layout (no-panel) from 180px to 200px for consistency.

Refs: PRD-003 (FR-005)
Five FRs from PRD-003: error.svelte boundary, role=img, nested button, prefers-reduced-motion, narrow-viewport grid.

Refs: PRD-003
Standard depth, 6 FRs, 4 NFRs, 5 risks. Drives PR F1 frontend recovery + a11y. Linked artifact: PRD-002 prior tactical model. EVID-F1 planned post-merge.

Refs: PRD-003
@explosivebit explosivebit merged commit d939f88 into develop May 5, 2026
3 checks passed
@explosivebit explosivebit deleted the feature/frontend-recovery-a11y-f1 branch May 5, 2026 08:44
explosivebit added a commit that referenced this pull request May 5, 2026
Forge-cycle Step 7-8 for PR #22 (PRD-003 F1 frontend recovery + a11y).
EVID-010 verifies all 7 SC via live MCP Playwright DOM eval + visual
screenshots. R_eff=1.00 CL3 grade A. Activates both. Refs PRD-003
EVID-010.
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