Skip to content

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.

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.

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.

  • Phase 6 audit transcript at .impeccable-state.json (cohort p6.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