/** * themes.js - Theme management system */ const STORAGE_KEY_THEME = 'selected-theme'; const themes = { dark: { name: 'Dark (Default)', primary: '#1a1a2e', secondary: '#16213e', accent: '#0f3460', text: '#e4e4e4', textMuted: '#a0a0a0', border: '#2a2a3e', cardBg: 'rgba(30, 30, 46, 0.7)', headerBg: 'rgba(26, 26, 46, 0.85)', overlayBg: 'rgba(60, 60, 60, 0.35)' }, light: { name: 'Light', primary: '#f5f5f5', secondary: '#ffffff', accent: '#3498db', text: '#2c3e50', textMuted: '#7f8c8d', border: '#dfe6e9', cardBg: 'rgba(255, 255, 255, 0.85)', headerBg: 'rgba(245, 245, 245, 0.95)', overlayBg: 'rgba(255, 255, 255, 0.15)' }, ocean: { name: 'Ocean', primary: '#0a1828', secondary: '#1a2332', accent: '#178582', text: '#e0f4f4', textMuted: '#8ab4b4', border: '#1a3a3a', cardBg: 'rgba(26, 35, 50, 0.75)', headerBg: 'rgba(10, 24, 40, 0.9)', overlayBg: 'rgba(23, 133, 130, 0.15)' }, sunset: { name: 'Sunset', primary: '#1a0f1e', secondary: '#2a1b2e', accent: '#d4477a', text: '#fce9e9', textMuted: '#c4a4b4', border: '#3a2a3e', cardBg: 'rgba(42, 27, 46, 0.75)', headerBg: 'rgba(26, 15, 30, 0.9)', overlayBg: 'rgba(212, 71, 122, 0.15)' }, forest: { name: 'Forest', primary: '#0f1a0f', secondary: '#1a2a1a', accent: '#4a9a4a', text: '#e4f4e4', textMuted: '#a4c4a4', border: '#2a3a2a', cardBg: 'rgba(26, 42, 26, 0.75)', headerBg: 'rgba(15, 26, 15, 0.9)', overlayBg: 'rgba(74, 154, 74, 0.15)' } }; // Apply theme function applyTheme(themeName) { const theme = themes[themeName] || themes.dark; const root = document.documentElement; root.style.setProperty('--color-primary', theme.primary); root.style.setProperty('--color-secondary', theme.secondary); root.style.setProperty('--color-accent', theme.accent); root.style.setProperty('--color-text', theme.text); root.style.setProperty('--color-text-muted', theme.textMuted); root.style.setProperty('--color-border', theme.border); root.style.setProperty('--color-card-bg', theme.cardBg); root.style.setProperty('--color-header-bg', theme.headerBg); root.style.setProperty('--color-overlay-bg', theme.overlayBg); // Save preference try { localStorage.setItem(STORAGE_KEY_THEME, themeName); } catch (e) { console.error('Error saving theme:', e); } // Update active state in selector document.querySelectorAll('.theme-option').forEach(option => { option.classList.toggle('active', option.dataset.theme === themeName); }); } // Load saved theme function loadSavedTheme() { try { const saved = localStorage.getItem(STORAGE_KEY_THEME); return saved || 'dark'; } catch (e) { console.error('Error loading theme:', e); return 'dark'; } } // Create theme selector UI function createThemeSelector() { const selector = document.createElement('div'); selector.id = 'theme-selector'; selector.className = 'theme-selector'; const toggle = document.createElement('button'); toggle.className = 'theme-toggle'; toggle.innerHTML = '🎨'; toggle.title = 'Change Theme'; const menu = document.createElement('div'); menu.className = 'theme-menu'; Object.entries(themes).forEach(([key, theme]) => { const option = document.createElement('div'); option.className = 'theme-option'; option.dataset.theme = key; option.textContent = theme.name; option.addEventListener('click', () => { applyTheme(key); menu.classList.remove('open'); }); menu.appendChild(option); }); toggle.addEventListener('click', (e) => { e.stopPropagation(); menu.classList.toggle('open'); }); // Close menu when clicking outside document.addEventListener('click', () => { menu.classList.remove('open'); }); selector.appendChild(toggle); selector.appendChild(menu); return selector; } // Initialize theme system function initThemes() { // Apply saved theme const savedTheme = loadSavedTheme(); applyTheme(savedTheme); // Add theme selector to header const header = document.querySelector('header'); if (header) { const selector = createThemeSelector(); header.appendChild(selector); } } // Export for use in other modules window.themesModule = { init: initThemes, applyTheme: applyTheme, themes: themes };