Why
Modals (#settings, #addrole, #jdtriage, #ligoogle, legacy #rolepanel) open by toggling .hidden, and Escape already closes some surfaces — but Tab can escape into the page behind, and focus doesn’t always land on the first field.
Size
M — shared helper, wire into open/close paths.
Task
- Add a tiny focus-trap helper (vanilla JS, no library) used when a
.modal opens:
- move focus into the dialog (first input or close control)
- cycle Tab / Shift+Tab inside the
.box
- restore focus to the opener on close
- Ensure each modal has an accessible name (
aria-labelledby → existing heading, or aria-label).
- Keep Escape behavior consistent with today’s close paths.
Acceptance
Tips
Drawer already has role="dialog" aria-modal="true". Prefer matching that pattern. Avoid rewriting the whole hybrid IA.
Why
Modals (
#settings,#addrole,#jdtriage,#ligoogle, legacy#rolepanel) open by toggling.hidden, and Escape already closes some surfaces — but Tab can escape into the page behind, and focus doesn’t always land on the first field.Size
M — shared helper, wire into open/close paths.
Task
.modalopens:.boxaria-labelledby→ existing heading, oraria-label).Acceptance
npm testpassesTips
Drawer already has
role="dialog" aria-modal="true". Prefer matching that pattern. Avoid rewriting the whole hybrid IA.