// Theme Toggle - Manual dark/light mode switch with persistence export class ThemeToggle { constructor() { this.button = null; this.currentTheme = this.getSavedTheme() || this.getSystemTheme(); } init() { this.createButton(); this.applyTheme(this.currentTheme); document.addEventListener('toggle-theme', () => this.toggle()); // Listen for system theme changes window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { if (!this.getSavedTheme()) { this.applyTheme(e.matches ? 'dark' : 'light'); } }); } createButton() { this.button = document.createElement('button'); this.button.className = 'theme-toggle'; this.button.setAttribute('aria-label', 'Toggle dark/light theme'); this.button.setAttribute('title', 'Toggle theme (T)'); this.updateIcon(); this.button.addEventListener('click', () => this.toggle()); // Insert into header const headerInfo = document.querySelector('.header-info'); if (headerInfo) { headerInfo.prepend(this.button); } else { const header = document.querySelector('.header'); if (header) header.appendChild(this.button); } } toggle() { this.currentTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; this.applyTheme(this.currentTheme); this.saveTheme(this.currentTheme); } applyTheme(theme) { this.currentTheme = theme; document.documentElement.setAttribute('data-color-scheme', theme); this.updateIcon(); } updateIcon() { if (!this.button) return; const isDark = this.currentTheme === 'dark'; this.button.innerHTML = isDark ? '' : ''; this.button.setAttribute('aria-label', isDark ? 'Switch to light theme' : 'Switch to dark theme'); } getSystemTheme() { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } getSavedTheme() { try { return localStorage.getItem('ruview-theme'); } catch { return null; } } saveTheme(theme) { try { localStorage.setItem('ruview-theme', theme); } catch { // localStorage not available } } dispose() { if (this.button?.parentNode) { this.button.parentNode.removeChild(this.button); } } }