LearnNewsExamplesServices
Frontmatter
id14619
titleFM cockpit accessibility pass: focus order, contrast, reduced motion
stateOpen
labels
enhancementdeveloper-experienceai
assigneesneo-opus-vega
createdAtJul 4, 2026, 4:39 AM
updatedAt6:22 AM
githubUrlhttps://github.com/neomjs/neo/issues/14619
authorneo-opus-vega
commentsCount10
parentIssue14560
subIssues
15115 FM cockpit keyboard operability: listitem cards + native drill Button
subIssuesCompleted1
subIssuesTotal1
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

FM cockpit accessibility pass: focus order, contrast, reduced motion

Open Backlog/active-chunk-3 enhancementdeveloper-experienceai
neo-opus-vega
neo-opus-vega commented on Jul 4, 2026, 4:39 AM

Context

T7.25 of Epic #14560 (map v1.1) — the a11y floor for the cockpit surface: an operator-grade tool must be keyboard-drivable and legible, and "stunning" that fails contrast is a design defect by the epic's own bar. Filed under the decomposition sprint (D#14561).

The Problem

The SSOT's dark palette runs several low-ink tiers (--ink-dim, --ink-faint) over layered panels — contrast must be VERIFIED per token pair, not assumed. The control verbs (#14611/#14612) and the drill path (#14608/#14610) are keyboard-critical: an operator mid-incident cannot be mouse-gated. Reduced-motion gating exists per-leaf; this leaf audits it end-to-end.

The Architectural Reality

  • Token-level contrast audit: every ink-tier × surface-tier pair in #14578 measured against WCAG AA for its usage class (body text vs meta text vs disabled) — results recorded IN the token reference doc (deltas = recorded design decisions with Grace's design authority in the loop).
  • Focus order: the shell's zone composition (#14615) defines the tab topology — grid → card → controls → stream → rails; pop-out windows keep their own coherent order.
  • Verification: unit-level assertions where mechanical (focus sequence fixtures, prefers-reduced-motion config paths) + an audit doc for the judgment calls.

The Fix

One PR: the contrast audit table (token-pair × usage-class × measured ratio × verdict/fix) + focus-order fixtures for the core paths + the end-to-end reduced-motion audit + fixes for any failures found (or split-out leaves if a fix is design-material).

Acceptance Criteria

  • Contrast table covers every shipped ink×surface pair with measured ratios; failures fixed or ticketed with design-authority sign-off.
  • AC2 (reworded 2026-07-17 by the author after V-B-A — the original described a shell that never existed). The keyboard-reachability invariants hold, preset-independently: (a) every steady-state zone is reachable in DOM order with no tabIndex overrides (the shell has none — focus order IS DOM order); (b) the drill button is the only focusable element inside a card (the card root stays a non-interactive listitem); (c) autoHidden zones (detail, perspectives) are not tab stops until revealed; (d) the drill/pop-out path stays green.
    • Superseded: "Focus-order fixtures green for grid→card→controls→stream→rails"the shipped order is controls → grid → stream → detail → perspectives (FleetCockpit composes [toolbar.fm-cockpit-bar, dockConfig]; cockpitDockDocument:27-30 orders fleet/stream/detail/perspectives). Three errors in the old sentence, all its own: controls are FIRST and should be (a toolbar tabs before its content — reordering the shell to match would worsen a11y); card is not a zone (cards live inside the grid; agentCard.spec.mjs:219-223 deliberately pins the root non-focusable); rails = detail+perspectives, both autoHidden, so not steady-state stops. It cited #14615 as defining the topology — that ticket is CLOSED, which is when the sentence went stale.
    • Already met by: FleetGridKeyboardA11y.spec.mjs (is the drill path — list/listitem topology, native Enter/Space, drill jump, gate-3 restoration) · agentCard.spec.mjs (the non-focusable-root pin) · fleetCockpitPopOut.spec.mjs (the pop-out leg). (c) is ALSO already metcockpitDockDocument.spec.mjs:39-47 asserts it and carries its own non-vacuity guard: expect(autoHidden.length).toBeGreaterThan(0) before expect(autoHidden).toEqual(expect.arrayContaining(['detail','perspectives'])), plus expect(items.fleet.autoHidden).toBeUndefined() pinning the primaries. An empty filter cannot pass it. Remaining: (a) alone. (I wrote "the (a)/(c) invariants" above without checking (c) — corrected within minutes, in the very sentence written to fix stale text. Same class, one layer down.)
    • (a)'s honest shape: "focus order IS DOM order" holds iff no tabIndex > 0 exists in the rendered tree — a component's own config can introduce one without the shell's source ever saying tabIndex. So a source-grep of FleetCockpit.mjs would be a guard aimed at a filename (see #15345), not the claim. The honest witness is a mounted whitebox-e2e walking the composed tree — that is the one genuinely-open piece of AC2.
    • Scoping note for whoever writes it: dock zones are document-driven (resolveDockComponentRef resolves componentRef at runtime), so a static "expect this tab sequence" fixture would pin a layout preset, not an invariant — red on every preset change while proving nothing about accessibility. Assert the invariants, never the sequence.
  • Reduced-motion audit: no motion-gated information anywhere (pulse carries no unique signal — verified).
  • Findings folded into the token/contract docs (the drift-proof home).

Out of Scope

Screen-reader deep-pass (a follow-up leaf if the audit warrants) · visual baselines (T7.24) · token values themselves (#14578).

Related

Epic #14560 (parent) · blocked-by #14578 · touches #14615 (focus topology) · D#14561.

Live latest-open sweep: fresh this window; no equivalent. A2A sweep: clean. Structure-map gate: N/A — audit leaf.

Origin Session ID: a28f1415-37a4-4a5a-a3e4-b56adf6274ec Retrieval Hint: "FM cockpit accessibility contrast focus order reduced motion audit"

tobiu referenced in commit 72da9ab - "feat(agentos): FM cockpit agent detail view — drill-in inspector, freshness-labeled panes (#14608) (#15063) on Jul 12, 2026, 11:27 AM
tobiu referenced in commit 5f543de - "feat(agentos): FM cockpit keyboard a11y — roving focus, Enter/Space activation, aria-live + landmarks (#14619) (#15094) on Jul 13, 2026, 1:44 AM