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);
}
});
}