Accessibility and Overlays
How Deucalion's admin overlay stack works and how we verify accessibility before merge.
Accessibility and overlays
This guide documents the admin-first layered UI system introduced for #136 and the blocking accessibility checks introduced for #141.
Overlay decision tree
Use the lightest surface that matches the job:
-
Tooltip- Use for short non-interactive help on hover and focus.
- Do not trap focus.
- Do not use for form fields or multi-step guidance.
-
Popover- Use for anchored supporting UI such as filter panels, column choosers, and lightweight action surfaces.
- Do not trap focus.
- Close on outside interaction or
Tab.
-
ContextMenu- Use for row-level or card-level secondary actions opened from right click, keyboard context-menu invocation, or long press.
- Keep actions concise and destructive items clearly separated.
-
Modal- Use for blocking task flows, forms, and focused review work.
- Trap focus and restore it on close.
-
AlertDialog- Use for confirmation and destructive decisions.
- Keep the copy explicit.
- Button order in admin web stays
Cancelthen the confirm/destructive action.
-
Panel- Use for large edge-anchored workspaces such as the assistant shell drawer.
- Treat blocking panels like dialogs for focus and dismissal.
-
Sheet- Use for partial-height mobile-style presentations on narrow screens when the task is too large for a popover but does not need a full modal.
Accessibility test matrix
The blocking browser audit covers representative admin states:
- shell and dashboard baseline
- a dense list/table page
- a modal/dialog state
- a popover/action-menu state
- an account/settings page
The blocking repo checks also cover:
- token-pair contrast expectations for the shipped admin theme surfaces
- new raw
z-indexdeclarations outside the explicit legacy allowlist - forced-colors/high-contrast browser states for the shell, modal, table, and popover flows
- 200% text zoom smoke coverage for the same representative admin flows
- mobile touch-target drift in new React Native
PressableandTouchable*usage
Local commands
Run these before pushing overlay or accessibility changes:
npm run test:admin-accessibility
npm run check:admin-contrast
npm run check:admin-z-index
npm run check:mobile-touch-targets
npm run test:admin-browser
npm run test:admin-layout
npm run check:admin-releaseScreen-reader and touch matrix
Use this matrix for VoiceOver, TalkBack, and touch-target spot checks when a change touches one of these surfaces.
| Flow | Platform | Assistive tech | Checks |
|---|---|---|---|
| Admin sign-in and recovery | Web admin | VoiceOver | form labels, password manager controls, error announcement |
| Admin shell navigation | Web admin | VoiceOver | skip link, sidebar links, topbar buttons, current page |
| Global search and command palette | Web admin | VoiceOver | Mod+K, result counts, keyboard selection, route change |
| Dashboard overview | Web admin | VoiceOver | stat names, table/card reading order, focus order |
| Users table and column chooser | Web admin | VoiceOver | table headers, column popover, checkbox names |
| Feature flag creation dialog | Web admin | VoiceOver | dialog label, first focus target, Esc, focus return |
| Account settings and passkeys | Web admin | VoiceOver | form fields, passkey unavailable state, destructive actions |
| PDF template Studio actions | Web admin | VoiceOver | disabled-action reasons, toolbar order, preview actions |
| Page history/comments | Web admin | VoiceOver | activity event labels, mention options, comment editor |
| Notifications and help center | Web admin | VoiceOver | unread state, popover dismissal, support escalation |
| Mobile sign-in | React Native | TalkBack | field labels, errors, submit target size |
| Mobile bottom tabs | React Native | TalkBack | tab labels, selected state, 48dp targets |
| Mobile inspections list | React Native | TalkBack | filters, long-press/context actions, row state |
| Mobile inspection checklist | React Native | TalkBack | result buttons, defect actions, swipe alternatives |
| Mobile asset details | React Native | TalkBack | card actions, context menu, navigation return |
| Mobile photo capture/gallery | React Native | TalkBack | capture controls, annotation actions, delete confirmation |
| Mobile visit notes | React Native | TalkBack | editor labels, voice-note controls, save state |
| Mobile quote creation | React Native | TalkBack | line-item controls, totals, submit action |
| Mobile offline/sync states | React Native | TalkBack | banners, retry controls, live-region announcements |
| Mobile settings/profile | React Native | TalkBack | account actions, subscription controls, sign-out confirmation |
Review prompts
When reviewing layered UI changes, check these behaviors explicitly:
- repeated
Esccloses only the topmost surface - focus returns to the launcher after closing dialogs and panels
- popovers and menus do not trap keyboard users
- shell controls stay readable and operable at 200% text zoom
- forced-colors mode preserves boundaries and focus indication