diff --git a/index.html b/index.html
index 06cff1c..88d4c8b 100644
--- a/index.html
+++ b/index.html
@@ -1001,6 +1001,13 @@ Sovereignty and service always.`;
var first = focusable[0];
var last = focusable[focusable.length - 1];
+ // If focus escaped outside the overlay (e.g. to body), redirect to first
+ if (!crisisOverlay.contains(document.activeElement)) {
+ e.preventDefault();
+ first.focus();
+ return;
+ }
+
if (e.shiftKey) {
// Shift+Tab: if on first, wrap to last
if (document.activeElement === first) {
@@ -1050,38 +1057,55 @@ Sovereignty and service always.`;
}
}, 1000);
- overlayDismissBtn.focus();
+ // Focus the first focusable element (call link) — dismiss button is still disabled
+ var firstFocusable = crisisOverlay.querySelector('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])');
+ if (firstFocusable) {
+ firstFocusable.focus();
+ }
}
// Register focus trap on document (always listening, gated by class check)
document.addEventListener('keydown', trapFocusInOverlay);
+ function dismissOverlay() {
+ crisisOverlay.classList.remove('active');
+ if (overlayTimer) {
+ clearInterval(overlayTimer);
+ overlayTimer = null;
+ }
+
+ // 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;
+ }
+
overlayDismissBtn.addEventListener('click', function() {
if (!overlayDismissBtn.disabled) {
- crisisOverlay.classList.remove('active');
- if (overlayTimer) {
- clearInterval(overlayTimer);
- overlayTimer = null;
- }
-
- // 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;
+ dismissOverlay();
}
});
+ // Escape key closes crisis overlay (only after dismiss button is enabled)
+ document.addEventListener('keydown', function(e) {
+ if (e.key !== 'Escape') return;
+ if (!crisisOverlay.classList.contains('active')) return;
+ if (overlayDismissBtn.disabled) return; // Don't bypass countdown
+ e.preventDefault();
+ dismissOverlay();
+ });
+
// ===== MESSAGE RENDERING =====
function addMessage(role, text, skipSave) {
var div = document.createElement('div');