import { Injectable, effect, signal } from '@angular/core'; export const THEMES = [ { value: 'theme-cyber-magenta', label: 'Cyber Magenta' }, { value: 'theme-neon-cyan', label: 'Neon Cyan' }, { value: 'theme-sunset-orange', label: 'Sunset Orange' }, { value: 'theme-matrix-green', label: 'Matrix Green' } ]; /** Palette, high contrast and background motion — on , remembered in this browser. */ @Injectable({ providedIn: 'root' }) export class ThemeService { readonly theme = signal(load('theme', THEMES[0].value)); readonly highContrast = signal(load('contrast', 'off') === 'on'); readonly animation = signal(load('animation', 'on') === 'on'); constructor() { effect(() => { const root = document.documentElement; THEMES.forEach(t => root.classList.toggle(t.value, t.value === this.theme())); root.classList.toggle('high-contrast', this.highContrast()); root.classList.toggle('no-anim', !this.animation()); save('theme', this.theme()); save('contrast', this.highContrast() ? 'on' : 'off'); save('animation', this.animation() ? 'on' : 'off'); }); } } function load(key: string, fallback: string): string { try { return localStorage.getItem('ui.' + key) ?? fallback; } catch { return fallback; } } function save(key: string, value: string): void { try { localStorage.setItem('ui.' + key, value); } catch { /* storage blocked */ } }