diff --git a/index.html b/index.html
index c341616..f7ff57d 100644
--- a/index.html
+++ b/index.html
@@ -331,6 +331,11 @@
background: var(--border);
}
+ .modal-close:focus {
+ outline: 2px solid var(--forest);
+ outline-offset: 2px;
+ }
+
.modal-body {
padding: 24px;
}
@@ -405,6 +410,11 @@
background: var(--terracotta-light);
}
+ .btn:focus {
+ outline: 3px solid var(--oak);
+ outline-offset: 2px;
+ }
+
.btn-secondary {
background: var(--cream);
color: var(--charcoal);
@@ -427,6 +437,11 @@
accent-color: var(--forest);
}
+ .checkbox-group input:focus {
+ outline: 2px solid var(--forest);
+ outline-offset: 2px;
+ }
+
.pin-input {
letter-spacing: 8px;
text-align: center;
@@ -1156,11 +1171,23 @@
// Make background content inert (unfocusable)
document.getElementById('mainContent').setAttribute('inert', '');
- // Focus first focusable element in modal
+ // Focus the primary input field in the modal
setTimeout(() => {
- const focusable = getFocusableElements(modal);
- if (focusable.length > 0) {
- focusable[0].focus();
+ let focusTarget = null;
+ if (id === 'pinModal') {
+ focusTarget = document.getElementById('pinInput');
+ } else if (id === 'setPinModal') {
+ focusTarget = document.getElementById('newPinInput');
+ } else if (id === 'itemModal') {
+ focusTarget = document.getElementById('itemName');
+ }
+ if (focusTarget) {
+ focusTarget.focus();
+ } else {
+ const focusable = getFocusableElements(modal);
+ if (focusable.length > 0) {
+ focusable[0].focus();
+ }
}
}, 50);
@@ -1184,11 +1211,15 @@
}
function getFocusableElements(container) {
- const elements = container.querySelectorAll('button, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');
- return Array.from(elements).filter(el => {
+ const selector = 'button, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])';
+ const elements = Array.from(container.querySelectorAll(selector));
+ return elements.filter(el => {
if (el.disabled) return false;
+ // Check if element is visible
+ if (el.offsetWidth === 0 && el.offsetHeight === 0) return false;
const style = window.getComputedStyle(el);
- return style.display !== 'none' && style.visibility !== 'hidden';
+ if (style.display === 'none' || style.visibility === 'hidden') return false;
+ return true;
});
}
@@ -1203,21 +1234,22 @@
return;
}
- // Trap focus on Tab
+ // Handle all Tab navigation manually
if (e.key === 'Tab') {
+ e.preventDefault();
const focusable = getFocusableElements(modal);
if (focusable.length === 0) return;
- const first = focusable[0];
- const last = focusable[focusable.length - 1];
+ const currentIndex = focusable.indexOf(document.activeElement);
+ let nextIndex;
- if (e.shiftKey && document.activeElement === first) {
- e.preventDefault();
- last.focus();
- } else if (!e.shiftKey && document.activeElement === last) {
- e.preventDefault();
- first.focus();
+ if (e.shiftKey) {
+ nextIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;
+ } else {
+ nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;
}
+
+ focusable[nextIndex].focus();
}
}