diff --git a/apps/pwa/src/hooks/useFocusTrap.ts b/apps/pwa/src/hooks/useFocusTrap.ts index 12fb791..e55c725 100644 --- a/apps/pwa/src/hooks/useFocusTrap.ts +++ b/apps/pwa/src/hooks/useFocusTrap.ts @@ -43,6 +43,16 @@ export function useFocusTrap( const first = focusable[0]; const last = focusable[focusable.length - 1]; + // Containment guard (IN-01): if focus has somehow landed outside the dialog + // (programmatic focus, browser quirk), neither boundary condition below + // matches and Tab would walk background content. Pull focus back to the + // first focusable instead of relying on a boundary-only trap. + if (!dialogRef.current.contains(document.activeElement)) { + e.preventDefault(); + first.focus(); + return; + } + if (e.shiftKey) { // Shift+Tab: if on first element, wrap to last if (document.activeElement === first) {