# StellaOps Console Accessibility Guide > **Audience:** Accessibility Guild, Console Guild, Docs Guild, QA. > **Scope:** Keyboard interaction model, screen-reader behaviour, colour & focus tokens, testing workflows, offline considerations, and compliance checklist for the StellaOps Console (Sprint 23). The console targets **WCAG 2.2 AA** across all supported browsers (Chromium, Firefox ESR) and honours StellaOps’ sovereign/offline constraints. Every build must keep keyboard-only users, screen-reader users, and high-contrast operators productive without relying on third-party services. --- ## 1 · Accessibility Principles 1. **Deterministic navigation** – Focus order, shortcuts, and announcements remain stable across releases; URLs encode state for deep links. 2. **Keyboard-first design** – Every actionable element is reachable via keyboard; shortcuts provide accelerators, and remapping is available via *Settings → Accessibility → Keyboard shortcuts*. 3. **Assistive technology parity** – ARIA roles and live regions mirror visual affordances (status banners, SSE tickers, progress drawers). Screen readers receive polite/atomic updates to avoid chatter. 4. **Colour & contrast tokens** – All palettes derive from design tokens that achieve ≥ 4.5:1 contrast (text) and ≥ 3:1 for graphical indicators; tokens pass automated contrast linting. 5. **Offline equivalence** – Accessibility features (shortcuts, offline banners, focus restoration) behave the same in sealed environments, with guidance when actions require online authority. --- ## 2 · Keyboard Interaction Map ### 2.1 Global shortcuts | Action | Macs | Windows/Linux | Notes | |--------|------|---------------|-------| | Command palette | `⌘ K` | `Ctrl K` | Focuses palette search; respects tenant scope. | | Tenant picker | `⌘ T` | `Ctrl T` | Opens modal; `Enter` confirms, `Esc` cancels. | | Filter tray toggle | `⇧ F` | `Shift F` | Focus lands on first filter; `Tab` cycles filters before returning to page. | | Saved view presets | `⌘ 1-9` | `Ctrl 1-9` | Bound per tenant; missing preset triggers tooltip. | | Keyboard reference | `?` | `?` | Opens overlay listing context-specific shortcuts; `Esc` closes. | | Global search (context) | `/` | `/` | When the filter tray is closed, focuses inline search field. | ### 2.2 Module-specific shortcuts | Module | Action | Macs | Windows/Linux | Notes | |--------|--------|------|---------------|-------| | Findings | Explain search | `⌘ /` | `Ctrl /` | Only when Explain drawer open; announces results via live region. | | SBOM Explorer | Toggle overlays | `⌘ G` | `Ctrl G` | Persists per session (see `/docs/ui/sbom-explorer.md`). | | Advisories & VEX | Provider filter | `⌘ ⌥ F` | `Ctrl Alt F` | Moves focus to provider chip row. | | Runs | Refresh snapshot | `⌘ R` | `Ctrl R` | Soft refresh of SSE state; no full page reload. | | Policies | Save draft | `⌘ S` | `Ctrl S` | Requires edit scope; exposes toast + status live update. | | Downloads | Copy CLI command | `⇧ D` | `Shift D` | Copies manifest or export command; toast announces scope hints. | All shortcuts are remappable. Remaps persist in IndexedDB (per tenant) and export as part of profile bundles so operators can restore preferences offline. --- ## 3 · Screen Reader & Focus Behaviour - **Skip navigation** – Each route exposes a “Skip to content” link revealed on keyboard focus. Focus order: global header → page breadcrumb → action shelf → data grid/list → drawers/dialogs. - **Live regions** – Status ticker and SSE progress bars use `aria-live="polite"` with throttling to avoid flooding AT. Error toasts use `aria-live="assertive"` and auto-focus dismiss buttons. - **Drawers & modals** – Dialog components trap focus, support `Esc` to close, and restore focus to the launching control. Screen readers announce title + purpose. - **Tables & grids** – Large tables (Findings, SBOM inventory) switch to virtualised rows but retain ARIA grid semantics (`aria-rowcount`, `aria-colindex`). Column headers include sorting state via `aria-sort`. - **Tenancy context** – Tenant badge exposes `aria-describedby` linking to context summary (environment, offline snapshot). Switching tenant queues a polite announcement summarising new scope. - **Command palette** – Uses `role="dialog"` with search input labelled. Keyboard navigation within results uses `Up/Down`; screen readers announce result category + command. - **Offline banner** – When offline, a dismissible banner announces reason and includes instructions for CLI fallback. The banner has `role="status"` so it announces once without stealing focus. --- ## 4 · Colour & Focus Tokens Console consumes design tokens published by the Console Guild (tracked via CONSOLE-FEAT-23-102). Tokens live in the design system bundle (`ui/design/tokens/colors.json`, mirrored at build time). Key tokens: | Token | Purpose | Contrast target | |-------|---------|-----------------| | `so-color-surface-base` | Primary surface/background | ≥ 4.5:1 against `so-color-text-primary`. | | `so-color-surface-raised` | Cards, drawers, modals | ≥ 3:1 against surrounding surfaces. | | `so-color-text-primary` | Default text colour | ≥ 4.5:1 against base surfaces. | | `so-color-text-inverted` | Text on accent buttons | ≥ 4.5:1 against accent fills. | | `so-color-accent-primary` | Action buttons, focus headings | ≥ 3:1 against surface. | | `so-color-status-critical` | Error toasts, violation chips | ≥ 4.5:1 for text; `critical-bg` provides >3:1 on neutral surface. | | `so-color-status-warning` | Warning banners | Meets 3:1 on surface and 4.5:1 for text overlays. | | `so-color-status-success` | Success toasts, pass badges | ≥ 3:1 for iconography; text uses `text-primary`. | | `so-focus-ring` | 2 px outline used across focusable elements | 3:1 against both light/dark surfaces. | Colour tokens undergo automated linting (**axe-core contrast checks** + custom luminance script) during build. Any new token must include dark/light variants and pass the token contract tests. --- ## 5 · Testing Workflow | Layer | Tooling | Frequency | Notes | |-------|---------|-----------|-------| | Component a11y | Storybook + axe-core addon | On PR (story CI) | Fails when axe detects violations. | | Route regression | Playwright a11y sweep (`pnpm test:a11y`) | Nightly & release pipeline | Executes keyboard navigation, checks focus trap, runs Axe on key routes (Dashboard, Findings, SBOM, Admin). | | Colour contrast lint | Token validator (`src/Tools/a11y/check-contrast.ts`) | On token change | Guards design token updates. | | CI parity | Pending `scripts/check-console-cli-parity.sh` (CONSOLE-DOC-23-502) | Release CI | Ensures CLI commands documented for parity features. | | Screen-reader spot checks | Manual NVDA + VoiceOver scripts | Pre-release checklist | Scenarios: tenant switch, explain drawer, downloads parity copy. | | Offline smoke | `stella offline kit import` + Playwright sealed-mode run | Prior to Offline Kit cut | Validates offline banners, disabled actions, keyboard flows without Authority. | Accessibility QA (CONSOLE-QA-23-402) tracks failing scenarios via Playwright snapshots and publishes reports in the Downloads parity channel (`kind = "parity.report"` placeholder until CLI parity CI lands). --- ## 6 · Offline & Internationalisation Considerations - Offline mode surfaces staleness badges and disables remote-only palette entries; keyboard focus skips disabled controls. - Saved shortcuts, presets, and remaps serialise into Offline Kit bundles so operators can restore preferences post-import. - Locale switching (future feature flag) will load translations at runtime; ensure ARIA labels use i18n tokens rather than hard-coded strings. - For sealed installs, guidance panels include CLI equivalents (`stella auth fresh-auth`, `stella runs export`) to unblock tasks when Authority is unavailable. --- ## 7 · Compliance Checklist - [ ] Keyboard shortcut matrix validated (default + remapped) and documented. - [ ] Screen-reader pass recorded for tenant switch, Explain drawer, Downloads copy-to-clipboard. - [ ] Colour tokens audited; contrast reports stored with release artifacts. - [ ] Automated a11y pipelines (Storybook axe, Playwright a11y) green; failures feed the `#console-qa` channel. - [ ] Offline kit a11y smoke executed before publishing each bundle. - [ ] CLI parity gaps logged in `/docs/cli-vs-ui-parity.md`; UI callouts reference fallback commands until parity closes. - [ ] Accessibility Guild sign-off captured in sprint log and release notes reference this guide. - [ ] References cross-checked (`/docs/ui/navigation.md`, `/docs/ui/downloads.md`, `/docs/security/console-security.md`, `/docs/observability/ui-telemetry.md`). --- ## 8 · References - `/docs/ui/navigation.md` – shortcut definitions, URL schema. - `/docs/ui/downloads.md` – CLI parity and offline copy workflows. - `/docs/ui/console-overview.md` – tenant model, filter behaviours. - `/docs/security/console-security.md` – security metrics and DPoP/fresh-auth requirements. - `/docs/observability/ui-telemetry.md` – telemetry metrics mapped to accessibility features. - `/docs/cli-vs-ui-parity.md` – parity status per console feature. - `CONSOLE-QA-23-402` – Accessibility QA backlog (Playwright + manual checks). - `CONSOLE-FEAT-23-102` – Design tokens & theming delivery. --- *Last updated: 2025-10-28 (Sprint 23).*