// Menu system const body = document.body; const menuToggle = document.getElementById('menuToggle'); const menuClose = document.getElementById('menuClose'); const menuOverlay = document.getElementById('menuOverlay'); const mobileMenu = document.getElementById('mobileMenu'); const siteContent = document.getElementById('siteContent'); function openMenu() { body.classList.add('menu-open'); menuOverlay.hidden = false; menuToggle.classList.add('is-open'); menuToggle.setAttribute('aria-expanded', 'true'); menuToggle.setAttribute('aria-label', 'Close menu'); mobileMenu.setAttribute('aria-hidden', 'false'); siteContent.setAttribute('inert', ''); menuClose.focus(); } function closeMenu() { body.classList.remove('menu-open'); menuToggle.classList.remove('is-open'); menuToggle.setAttribute('aria-expanded', 'false'); menuToggle.setAttribute('aria-label', 'Open menu'); mobileMenu.setAttribute('aria-hidden', 'true'); siteContent.removeAttribute('inert'); menuToggle.focus(); window.setTimeout(() => { if (!body.classList.contains('menu-open')) { menuOverlay.hidden = true; } }, 250); } function toggleMenu() { if (body.classList.contains('menu-open')) { closeMenu(); } else { openMenu(); } } menuToggle.addEventListener('click', toggleMenu); menuClose.addEventListener('click', closeMenu); menuOverlay.addEventListener('click', closeMenu); document.addEventListener('keydown', (event) => { if (event.key === 'Escape' && body.classList.contains('menu-open')) { closeMenu(); } }); window.addEventListener('resize', () => { if (window.innerWidth >= 768 && body.classList.contains('menu-open')) { closeMenu(); } }); // accessibility toggle const STORAGE_KEY = 'extra-css-enabled'; function applyOverrideState(enabled) { const link = document.getElementById('a11y-css'); const button = document.getElementById('a11y-toggle'); if (!link) return; link.disabled = !enabled; button?.setAttribute('aria-pressed', String(enabled)); } const enabled = localStorage.getItem(STORAGE_KEY) === 'true'; applyOverrideState(enabled); document.getElementById('a11y-toggle')?.addEventListener('click', () => { const nextState = localStorage.getItem(STORAGE_KEY) !== 'true'; localStorage.setItem(STORAGE_KEY, String(nextState)); applyOverrideState(nextState); }); // light-dark toggle const STORAGE_KEY = 'theme-preference'; const root = document.documentElement; const mq = window.matchMedia('(prefers-color-scheme: dark)'); function getSystemTheme() { return mq.matches ? 'dark' : 'light'; } function getSavedTheme() { try { return localStorage.getItem(STORAGE_KEY) || 'system'; } catch { return 'system'; } } function setSavedTheme(value) { try { localStorage.setItem(STORAGE_KEY, value); } catch {} } function applyTheme(theme = getSavedTheme()) { root.style.colorScheme = theme === 'system' ? 'light dark' : theme; } function getNextTheme() { return getSavedTheme() === 'system' ? (getSystemTheme() === 'dark' ? 'light' : 'dark') : 'system'; } function updateButton() { const btn = document.getElementById('theme-toggle'); if (!btn) return; const theme = getSavedTheme(); // btn.textContent = // theme === 'system' // ? `Use ${getSystemTheme() === 'dark' ? 'light' : 'dark'} theme` // : 'Use browser/OS theme'; } function toggleTheme() { setSavedTheme(getNextTheme()); applyTheme(); updateButton(); } function initThemeToggle() { applyTheme(); updateButton(); const btn = document.getElementById('theme-toggle'); if (btn) btn.addEventListener('click', toggleTheme); mq.addEventListener('change', () => { if (getSavedTheme() === 'system') { applyTheme('system'); updateButton(); } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initThemeToggle); } else { initThemeToggle(); }