document.addEventListener('DOMContentLoaded', () => { const menuToggle = document.getElementById('menu-toggle'); const menuOverlay = document.getElementById('menu-overlay'); const menuPanel = document.getElementById('hamburger-menu'); function openMenu() { if (!menuOverlay || !menuPanel) return; // Show overlay menuOverlay.classList.remove('opacity-0'); menuOverlay.classList.remove('invisible'); // Slide menu in menuPanel.classList.remove('translate-x-full'); // Manage accessibility menuToggle.setAttribute('aria-expanded', 'true'); menuPanel.removeAttribute('aria-hidden'); // Control body overflow document.body.style.overflow = 'hidden'; // Focus first focusable element in menu const firstFocusable = menuPanel.querySelector('a, button'); if (firstFocusable) { setTimeout(() => firstFocusable.focus(), 50); } } function closeMenu() { if (!menuOverlay || menuOverlay.classList.contains('opacity-0')) return; // Hide overlay menuOverlay.classList.add('opacity-0'); menuOverlay.classList.add('invisible'); // Slide menu out menuPanel.classList.add('translate-x-full'); // Manage accessibility menuToggle.setAttribute('aria-expanded', 'false'); menuPanel.setAttribute('aria-hidden', 'true'); // Restore body overflow document.body.style.overflow = ''; // Return focus to toggle button menuToggle.focus(); } function toggleMenu() { if (menuOverlay && menuOverlay.classList.contains('opacity-0')) { openMenu(); } else { closeMenu(); } } // Toggle menu when clicking the hamburger button if (menuToggle) { menuToggle.addEventListener('click', toggleMenu); } // Close menu when clicking on the overlay if (menuOverlay) { menuOverlay.addEventListener('click', (e) => { if (e.target === menuOverlay) { closeMenu(); } }); } // Close menu when clicking menu items const menuLinks = document.querySelectorAll('#hamburger-menu a, #hamburger-menu button'); menuLinks.forEach(link => { link.addEventListener('click', closeMenu); }); // Close menu on Escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && menuOverlay && !menuOverlay.classList.contains('opacity-0')) { closeMenu(); } }); // Focus trap: keep tab within menu when open if (menuPanel) { menuPanel.addEventListener('keydown', (e) => { if (e.key !== 'Tab') return; const focusableElements = menuPanel.querySelectorAll('a, button, [tabindex]:not([tabindex="-1"])'); if (focusableElements.length === 0) return; const firstElement = focusableElements[0]; const lastElement = focusableElements[focusableElements.length - 1]; const isMenuOpen = !menuOverlay.classList.contains('opacity-0'); if (!isMenuOpen) return; // Shift+Tab on first element: move to last if (e.shiftKey && document.activeElement === firstElement) { e.preventDefault(); lastElement.focus(); } // Tab on last element: move to first else if (!e.shiftKey && document.activeElement === lastElement) { e.preventDefault(); firstElement.focus(); } }); } });