/** * static/js/theme.js * Dark / light theme toggle. * - Defaults to the OS/browser colour-scheme preference. * - User override is persisted in localStorage. * - Applies via . */ const STORAGE_KEY = 'local-mcp-theme'; function systemTheme() { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } function storedTheme() { return localStorage.getItem(STORAGE_KEY); // 'dark' | 'light' | null } function iconSun() { return ` `; } function iconMoon() { return ` `; } function applyTheme(theme) { document.documentElement.dataset.theme = theme; const btn = document.getElementById('theme-toggle'); if (!btn) return; const isDark = theme === 'dark'; btn.setAttribute('aria-label', isDark ? 'Switch to light mode' : 'Switch to dark mode'); btn.setAttribute('title', isDark ? 'Switch to light mode' : 'Switch to dark mode'); btn.innerHTML = isDark ? iconMoon() : iconSun(); } function toggle() { const current = document.documentElement.dataset.theme || 'dark'; const next = current === 'dark' ? 'light' : 'dark'; localStorage.setItem(STORAGE_KEY, next); applyTheme(next); } export function initTheme() { // Apply immediately (before paint) based on stored or system preference const theme = storedTheme() || systemTheme(); applyTheme(theme); // Follow system changes only when the user hasn't manually overridden window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { if (!storedTheme()) { applyTheme(e.matches ? 'dark' : 'light'); } }); document.getElementById('theme-toggle')?.addEventListener('click', toggle); }