// Designs der Oberfläche. Die Auswahl wird pro Browser gespeichert; index.html setzt sie vor dem ersten // Zeichnen (kein Aufblitzen des falschen Designs), dieses Modul hält sie danach aktuell. const KEY = 'p42.design'; const EVENT = 'p42:design'; export const THEMES = [ { key: 'matrix', name: 'Matrix', hint: 'Rotes Retro-Terminal', swatch: ['#ff3a3a', '#1d0505'], color: '#050000' }, { key: 'blackwall', name: 'Blackwall', hint: 'Cyberpunk-Netrunner', swatch: ['#ff2d6f', '#3ff6ff', '#1a0508'], color: '#060104' }, ]; const valid = (key) => THEMES.some((t) => t.key === key); export function getTheme() { const current = document.documentElement.dataset.theme; return valid(current) ? current : 'matrix'; } export function setTheme(key) { if (!valid(key)) return; try { localStorage.setItem(KEY, key); } catch { /* ignorieren */ } const still = document.documentElement.classList.contains('calm') || window.matchMedia('(prefers-reduced-motion: reduce)').matches; // Überblenden, wo der Browser View Transitions kann; kurz warten, bis React den neuen Hintergrund gezeichnet hat if (document.startViewTransition && !still) { document.startViewTransition(async () => { apply(key); await new Promise((resolve) => { setTimeout(resolve, 40); }); }); } else { apply(key); } } export function onThemeChange(fn) { window.addEventListener(EVENT, fn); return () => window.removeEventListener(EVENT, fn); } function apply(key) { document.documentElement.dataset.theme = key; // Browser-Leiste (Handy) passend einfärben document.querySelector('meta[name="theme-color"]')?.setAttribute('content', THEMES.find((t) => t.key === key).color); window.dispatchEvent(new Event(EVENT)); } apply(getTheme());