const wordmark = document.getElementById('wordmark'); if (wordmark) { document.addEventListener('mousemove', (e) => { const cx = window.innerWidth / 2; const cy = window.innerHeight / 2; const dx = (e.clientX - cx) / cx; const dy = (e.clientY - cy) / cy; wordmark.style.transform = `perspective(800px) rotateX(${-dy * 5}deg) rotateY(${dx * 5}deg)`; }); document.addEventListener('mouseleave', () => { wordmark.style.transform = ''; }); } const THEME_KEY = 'theme'; const themeMenu = document.querySelector('.theme-menu'); const themeToggle = themeMenu ? themeMenu.querySelector('.theme-toggle') : null; const themeDropdown = themeMenu ? themeMenu.querySelector('.theme-dropdown') : null; const themeOptions = themeMenu ? themeMenu.querySelectorAll('[data-theme-choice]') : []; const themeQuery = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null; function getEffectiveTheme(mode) { if (mode === 'auto') { return themeQuery && themeQuery.matches ? 'dark' : 'light'; } return mode; } function updateToggle(mode, effectiveTheme) { if (!themeToggle) { return; } let iconClass = 'fa-circle-half-stroke'; if (mode === 'dark') { iconClass = 'fa-sun'; } else if (mode === 'light') { iconClass = 'fa-moon'; } themeToggle.innerHTML = ` `; themeToggle.setAttribute('aria-label', `Theme: ${mode.charAt(0).toUpperCase() + mode.slice(1)}`); themeToggle.setAttribute('data-effective-theme', effectiveTheme); } function updateActiveOption(mode) { themeOptions.forEach((option) => { const isActive = option.dataset.themeChoice === mode; option.classList.toggle('is-active', isActive); option.setAttribute('aria-checked', isActive ? 'true' : 'false'); }); } function setThemeMode(mode, persist = true) { const effectiveTheme = getEffectiveTheme(mode); document.documentElement.setAttribute('data-theme', effectiveTheme); updateToggle(mode, effectiveTheme); updateActiveOption(mode); if (persist) { localStorage.setItem(THEME_KEY, mode); } } function initTheme() { const savedMode = localStorage.getItem(THEME_KEY); const mode = savedMode || 'auto'; setThemeMode(mode, Boolean(savedMode)); } function openThemeMenu() { if (!themeMenu || !themeToggle) { return; } themeMenu.classList.add('is-open'); themeToggle.setAttribute('aria-expanded', 'true'); } function closeThemeMenu() { if (!themeMenu || !themeToggle) { return; } themeMenu.classList.remove('is-open'); themeToggle.setAttribute('aria-expanded', 'false'); } if (themeMenu && themeToggle && themeDropdown) { initTheme(); themeToggle.addEventListener('click', (event) => { event.stopPropagation(); themeMenu.classList.contains('is-open') ? closeThemeMenu() : openThemeMenu(); }); themeOptions.forEach((option) => { option.addEventListener('click', () => { const mode = option.dataset.themeChoice || 'auto'; setThemeMode(mode); closeThemeMenu(); }); }); document.addEventListener('click', (event) => { if (!themeMenu.contains(event.target)) { closeThemeMenu(); } }); document.addEventListener('keydown', (event) => { if (event.key === 'Escape') { closeThemeMenu(); } }); } else { initTheme(); } if (themeQuery) { themeQuery.addEventListener('change', () => { const mode = localStorage.getItem(THEME_KEY) || 'auto'; if (mode === 'auto') { setThemeMode('auto', false); } }); }