Intent
Continue the accessibility work started in #319/#320 so Pane’s keyboard-first workflows are consistently operable and understandable with assistive technology. Address the confirmed cross-cutting gaps outside the shared Modal work, and establish automated guardrails that prevent the same classes of regressions from returning.
Scope
- Replace or repair non-semantic clickable elements so all actions and selectable rows are keyboard-operable and expose the correct native semantics.
- Bring
AboutDialog onto an accessible dialog pattern, including an accessible name, focus entry/containment/restoration, and a labeled close control. Coordinate this with any separate shared Modal improvements rather than duplicating dialog infrastructure.
- Add appropriate live-region/status announcements for meaningful asynchronous changes such as errors, connection state, progress, and command outcomes. Avoid announcing noisy high-frequency terminal output.
- Audit custom ARIA widgets (tabs, menus, listboxes, comboboxes, and similar controls) for complete keyboard interaction, focus management, and state semantics rather than ARIA roles alone.
- Add automated accessibility guardrails to frontend linting and Playwright smoke coverage.
- Include a rendered manual pass for focus visibility, zoom/reflow, and color contrast across Pane themes; these cannot be established from static source inspection alone.
Starting Points
frontend/src/components/Sidebar.tsx: clickable version and Docs spans.
frontend/src/components/ExecutionList.tsx: clickable commit rows.
frontend/src/components/panels/diff/DiffViewer.tsx: clickable file expansion headers.
frontend/src/components/AboutDialog.tsx: bespoke visual overlay without complete dialog semantics or focus management.
frontend/src/components/PaneChatView.tsx: tab roles without the complete roving-focus/arrow-key tab interaction model.
frontend/eslint.config.js: no JSX accessibility rules.
tests/: no automated axe-based accessibility smoke coverage.
- Search for clickable
div/span elements, custom role usage, raw form controls, focus suppression, and status/error UI without aria-live, role="status", or role="alert".
This list is not exhaustive. Treat it as a starting point and investigate the local and remote frontends before implementation.
Acceptance Criteria
- User actions and selectable rows are reachable and operable with keyboard alone, preferably through native buttons and links rather than emulated controls.
- AboutDialog follows the project’s accessible dialog contract and returns focus to its opener when closed.
- Important asynchronous success, error, loading, and connection changes have deliberate, non-noisy assistive-technology announcements.
- Custom ARIA widgets implement the expected keyboard and focus behavior for their declared roles.
- Frontend linting catches common JSX accessibility regressions without introducing an untriaged wall of ignored failures.
- Playwright runs automated accessibility checks over at least Home, Settings, session creation, and one active-session workflow, with documented intentional exceptions.
- Manual verification covers keyboard-only operation, visible focus, 200% zoom/reflow, and representative contrast across the supported theme families.
- Existing terminal interaction and global hotkeys continue to work, including while dialogs and composite widgets are active.
Inputs Needed
- Confirm whether WCAG 2.2 AA is the target baseline.
- Decide whether accessibility lint rules should be introduced incrementally or enabled repository-wide after the initial remediation.
Notes
The shared Modal component has its own high-impact focus-trap, focus-restoration, and accessible-labeling concerns and should be handled as separate foundational work. This issue should consume that improved contract when available rather than growing a second modal implementation.
Related: #319, #320.
Intent
Continue the accessibility work started in #319/#320 so Pane’s keyboard-first workflows are consistently operable and understandable with assistive technology. Address the confirmed cross-cutting gaps outside the shared
Modalwork, and establish automated guardrails that prevent the same classes of regressions from returning.Scope
AboutDialogonto an accessible dialog pattern, including an accessible name, focus entry/containment/restoration, and a labeled close control. Coordinate this with any separate sharedModalimprovements rather than duplicating dialog infrastructure.Starting Points
frontend/src/components/Sidebar.tsx: clickable version and Docs spans.frontend/src/components/ExecutionList.tsx: clickable commit rows.frontend/src/components/panels/diff/DiffViewer.tsx: clickable file expansion headers.frontend/src/components/AboutDialog.tsx: bespoke visual overlay without complete dialog semantics or focus management.frontend/src/components/PaneChatView.tsx: tab roles without the complete roving-focus/arrow-key tab interaction model.frontend/eslint.config.js: no JSX accessibility rules.tests/: no automated axe-based accessibility smoke coverage.div/spanelements, customroleusage, raw form controls, focus suppression, and status/error UI withoutaria-live,role="status", orrole="alert".This list is not exhaustive. Treat it as a starting point and investigate the local and remote frontends before implementation.
Acceptance Criteria
Inputs Needed
Notes
The shared
Modalcomponent has its own high-impact focus-trap, focus-restoration, and accessible-labeling concerns and should be handled as separate foundational work. This issue should consume that improved contract when available rather than growing a second modal implementation.Related: #319, #320.