/* ============================================================ CHAINUS — app root: theme / accent / aurora / motion / lang ============================================================ */ const ACCENTS = { 'Sapphire': '#163B7A', 'Navy': '#0E2C5F', 'Steel': '#536B8E', 'Indigo': '#293E8F', }; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "themeMode": "dark", "accent": "#163B7A", "aura": "subtle", "motion": "lively" }/*EDITMODE-END*/; function systemTheme() { return (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) ? 'light' : 'dark'; } function App() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const [lang, setLang] = useState(() => (window.detectLang ? window.detectLang() : 'en')); const [theme, setTheme] = useState(() => document.documentElement.getAttribute('data-theme') || 'dark'); const C = window.I18N[lang]; useReveal(); useEffect(() => { const b = document.getElementById('boot'); if (b) { b.classList.add('gone'); setTimeout(() => b.remove(), 700); } }, []); /* theme: follow tweak mode (auto/dark/light); toggle persists a manual pick */ const applyTheme = (th) => { document.documentElement.setAttribute('data-theme', th); document.querySelector('meta[name="theme-color"]')?.setAttribute('content', th === 'light' ? '#E9ECF3' : '#050609'); setTheme(th); }; useEffect(() => { const mode = t.themeMode || 'auto'; if (mode === 'auto') { applyTheme(systemTheme()); const mq = window.matchMedia('(prefers-color-scheme: light)'); const onCh = () => { if ((TWEAK_DEFAULTS && (t.themeMode || 'auto') === 'auto')) applyTheme(systemTheme()); }; mq.addEventListener && mq.addEventListener('change', onCh); return () => mq.removeEventListener && mq.removeEventListener('change', onCh); } else { applyTheme(mode); } }, [t.themeMode]); const onToggleTheme = () => { const next = theme === 'dark' ? 'light' : 'dark'; try { localStorage.setItem('chainus_theme', next); } catch (e) {} setTweak('themeMode', next); applyTheme(next); }; /* accent */ useEffect(() => { const root = document.documentElement; const v = (!t.accent || t.accent === '#5B7CFF' || t.accent === '#2997FF') ? '#163B7A' : t.accent; root.style.setProperty('--brand', v); root.style.setProperty('--brand-2', `color-mix(in oklab, ${v} 38%, #D8E0EC)`); root.style.setProperty('--brand-hover', `color-mix(in oklab, ${v} 82%, black)`); root.style.setProperty('--brand-active', `color-mix(in oklab, ${v} 70%, black)`); }, [t.accent]); useEffect(() => { document.documentElement.dataset.aura = t.aura || 'balanced'; }, [t.aura]); useEffect(() => { document.documentElement.dataset.motion = t.motion || 'lively'; }, [t.motion]); useEffect(() => { document.documentElement.lang = lang === 'zh' ? 'zh-CN' : 'en'; document.documentElement.dataset.lang = lang; document.body.dataset.lang = lang; if (window.saveLang) window.saveLang(lang); }, [lang]); return (