const cvPortrait = document.getElementById('cv-portrait-orbit'); const siteThemeStorageKey = 'site-theme'; const legacyCvThemeStorageKey = 'cv-theme'; function normalizeSiteTheme(theme) { return theme === 'light' || theme === 'fancy' ? 'light' : 'dark'; } function getStoredSiteTheme() { try { return localStorage.getItem(siteThemeStorageKey) || localStorage.getItem(legacyCvThemeStorageKey); } catch (_error) { return null; } } function storeSiteTheme(theme) { const nextTheme = normalizeSiteTheme(theme); try { localStorage.setItem(siteThemeStorageKey, nextTheme); localStorage.removeItem(legacyCvThemeStorageKey); } catch (_error) { } } function getSiteThemeButtons() { return [...document.querySelectorAll('[data-site-theme]')]; } function setSiteTheme(theme) { const nextTheme = normalizeSiteTheme(theme); document.documentElement.classList.toggle('theme-light', nextTheme === 'light'); document.documentElement.classList.toggle('theme-dark', nextTheme === 'dark'); document.body.classList.toggle('theme-light', nextTheme === 'light'); document.body.classList.toggle('theme-dark', nextTheme === 'dark'); getSiteThemeButtons().forEach((button) => { const active = normalizeSiteTheme(button.dataset.siteTheme) === nextTheme; button.classList.toggle('is-active', active); button.setAttribute('aria-pressed', active ? 'true' : 'false'); }); storeSiteTheme(nextTheme); } document.addEventListener('click', (event) => { const button = event.target.closest('[data-site-theme]'); if (!button) return; setSiteTheme(button.dataset.siteTheme); }); document.addEventListener('pointermove', (event) => { if (!document.body.classList.contains('theme-light') || !cvPortrait) return; const bounds = cvPortrait.getBoundingClientRect(); const centerX = bounds.left + bounds.width / 2; const centerY = bounds.top + bounds.height / 2; const radians = Math.atan2(event.clientY - centerY, event.clientX - centerX); const degrees = radians * 180 / Math.PI; cvPortrait.style.setProperty('--portrait-rotation', `${degrees + 8}deg`); }); setSiteTheme(getStoredSiteTheme() || 'dark');