diff --git a/index.html b/index.html
index 5282521..1815519 100644
--- a/index.html
+++ b/index.html
@@ -983,12 +983,60 @@ Sovereignty and service always.`;
// ===== OVERLAY =====
+
+ // Focus trap: cycle through focusable elements within the crisis overlay
+ function getOverlayFocusableElements() {
+ return crisisOverlay.querySelectorAll(
+ 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])'
+ );
+ }
+
+ function trapFocusInOverlay(e) {
+ if (!crisisOverlay.classList.contains('active')) return;
+ if (e.key !== 'Tab') return;
+
+ var focusable = getOverlayFocusableElements();
+ if (focusable.length === 0) return;
+
+ var first = focusable[0];
+ var last = focusable[focusable.length - 1];
+
+ if (e.shiftKey) {
+ // Shift+Tab: if on first, wrap to last
+ if (document.activeElement === first) {
+ e.preventDefault();
+ last.focus();
+ }
+ } else {
+ // Tab: if on last, wrap to first
+ if (document.activeElement === last) {
+ e.preventDefault();
+ first.focus();
+ }
+ }
+ }
+
+ // Store the element that had focus before the overlay opened
+ var _preOverlayFocusElement = null;
+
function showOverlay() {
+ // Save current focus for restoration on dismiss
+ _preOverlayFocusElement = document.activeElement;
+
crisisOverlay.classList.add('active');
overlayDismissBtn.disabled = true;
var countdown = 10;
overlayDismissBtn.textContent = 'Continue to chat (' + countdown + 's)';
+ // Disable background interaction via inert attribute
+ var mainApp = document.querySelector('.app');
+ if (mainApp) mainApp.setAttribute('inert', '');
+ // Also hide from assistive tech
+ var chatSection = document.getElementById('chat');
+ if (chatSection) chatSection.setAttribute('aria-hidden', 'true');
+ var footerEl = document.querySelector('footer');
+ if (footerEl) footerEl.setAttribute('aria-hidden', 'true');
+
if (overlayTimer) clearInterval(overlayTimer);
overlayTimer = setInterval(function() {
countdown--;
@@ -1005,6 +1053,9 @@ Sovereignty and service always.`;
overlayDismissBtn.focus();
}
+ // Register focus trap on document (always listening, gated by class check)
+ document.addEventListener('keydown', trapFocusInOverlay);
+
overlayDismissBtn.addEventListener('click', function() {
if (!overlayDismissBtn.disabled) {
crisisOverlay.classList.remove('active');
@@ -1012,7 +1063,22 @@ Sovereignty and service always.`;
clearInterval(overlayTimer);
overlayTimer = null;
}
- msgInput.focus();
+
+ // Re-enable background interaction
+ var mainApp = document.querySelector('.app');
+ if (mainApp) mainApp.removeAttribute('inert');
+ var chatSection = document.getElementById('chat');
+ if (chatSection) chatSection.removeAttribute('aria-hidden');
+ var footerEl = document.querySelector('footer');
+ if (footerEl) footerEl.removeAttribute('aria-hidden');
+
+ // Restore focus to the element that had it before the overlay opened
+ if (_preOverlayFocusElement && typeof _preOverlayFocusElement.focus === 'function') {
+ _preOverlayFocusElement.focus();
+ } else {
+ msgInput.focus();
+ }
+ _preOverlayFocusElement = null;
}
});