Dashboard a11y — aria-current, faint-text contrast, decision-body markdown rendering
title: Dashboard a11y — aria-current, faint-text contrast, decision-body markdown rendering date: 2026-05-09 status: published mr: MR-7 outranks: []
Section titled “title: Dashboard a11y — aria-current, faint-text contrast, decision-body markdown rendering date: 2026-05-09 status: published mr: MR-7 outranks: []”Dashboard a11y — aria-current, faint-text contrast, decision-body markdown rendering
Section titled “Dashboard a11y — aria-current, faint-text contrast, decision-body markdown rendering”Recorded under MR-7 (append-only) following the Phase 6 recurring audit at the close of the 2026-05-09 IMPECCABLE_HANDBOOK pass. Three findings of P0/P1 severity surfaced after Phases 0–5 closed; this doc captures the routing decision for the next handbook cycle.
Findings
Section titled “Findings”A1 — aria-current="page" absent from active dashboard nav (P0, harden)
Section titled “A1 — aria-current="page" absent from active dashboard nav (P0, harden)”dashboard/src/layouts/Shell.astro sets a visual class="active" on the active topbar nav anchor but does not set aria-current="page". Screen readers and keyboard navigators receive no semantic location signal. WCAG 2.2 SC 2.4.3 (Focus Order) and SC 4.1.2 (Name, Role, Value) implicated. Carried unresolved from the Phase 1 audit (1.4-A-01).
Fix: aria-current={activeNav === l.label ? "page" : undefined} on each nav <a>.
A2 — --console-text-faint fails WCAG AA contrast (P1, harden)
Section titled “A2 — --console-text-faint fails WCAG AA contrast (P1, harden)”--console-text-faint resolves to oklch(38% 0.015 270) against --console-bg oklch(8% 0.02 270), yielding ≈2.96:1. WCAG 2.2 SC 1.4.3 requires 4.5:1 for text under 18pt normal / 14pt bold. Affected sites include .card-sweep (10.5px), .chip-profile, .field-label, .verif-pill--na, .badge.closed, table <th>.
Fix options: (a) lift the token to ≥oklch(46%) to clear AA on the smallest body sizes; (b) substitute --console-text-mute (oklch(50%)) on small-text call sites and reserve --console-text-faint for non-text or large-text only.
Preferred: (a). Token-layer fix is one edit; per-site substitution multiplies scope.
R1 — Decision body markdown rendered unparsed (P1, harden)
Section titled “R1 — Decision body markdown rendered unparsed (P1, harden)”dashboard/src/pages/console/decisions/[id].astro renders bodyHtml via set:html but the RPC returns raw Markdown. Frontmatter is correctly stripped; the body still renders literal # Heading, **bold**, - item characters in the browser. Introduced by Phase 2.2 craft.
Fix options: (a) add a Markdown parser (marked or micromark) and parse in the page frontmatter block; (b) return pre-rendered HTML from the host RPC verb; (c) render the raw body in a <pre> block as source text, dropping the prose typography.
Preferred: (a) for the dashboard render path; (b) is upstream and out-of-scope for a single-handbook cycle.
Routing
Section titled “Routing”A1 and A2 route to a future Phase 3 (/impeccable harden) prompt against dashboard/src/layouts/Shell.astro and shared/styles/tokens.css respectively.
R1 routes to a future Phase 2-or-3 prompt against dashboard/src/pages/console/decisions/[id].astro plus a package.json dependency add.
All three are carried into the next IMPECCABLE_HANDBOOK cycle. None are silently fixed in this audit pass per the audit-does-not-fix rule.
References
Section titled “References”- Phase 6 audit transcript at
.impeccable-state.json(cohortp6.c1) - Phase 1 audit (1.4-A-01: aria-current first surfaced)
- WCAG 2.2 SC 1.4.3, 2.4.3, 4.1.2