document.documentElement.classList.add('js'); function readThemePreference(key, fallback) { try { return localStorage.getItem(key) || fallback; } catch (error) { return fallback; } } const moduleName = document.documentElement.dataset.module || ''; const mainThemeMode = readThemePreference('nexus.theme', 'day'); const mainThemeAccent = readThemePreference('nexus.accent', 'logo'); const moduleThemeMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : mainThemeMode; const moduleThemeAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : mainThemeAccent; function normalizeThemeValue(value, allowed, fallback) { return allowed.includes(value) ? value : fallback; } function storedTheme() { const rawMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : readThemePreference('nexus.theme', 'day'); const rawAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : readThemePreference('nexus.accent', 'logo'); const mode = moduleName ? normalizeThemeValue(rawMode, ['inherit', 'day', 'night'], 'inherit') : normalizeThemeValue(rawMode, ['day', 'night'], 'day'); const accent = moduleName ? normalizeThemeValue(rawAccent, ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'], 'inherit') : normalizeThemeValue(rawAccent, ['logo', 'pink', 'cyan', 'orange', 'green'], 'logo'); return { mode, accent }; } function applyTheme(mode, accent, persist = true) { const allowedModes = moduleName ? ['inherit', 'day', 'night'] : ['day', 'night']; const allowedAccents = moduleName ? ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'] : ['logo', 'pink', 'cyan', 'orange', 'green']; const normalizedMode = normalizeThemeValue(mode, allowedModes, moduleName ? 'inherit' : 'day'); const normalizedAccent = normalizeThemeValue(accent, allowedAccents, moduleName ? 'inherit' : 'logo'); const effectiveMode = normalizedMode === 'inherit' ? mainThemeMode : normalizedMode; const effectiveAccent = normalizedAccent === 'inherit' ? mainThemeAccent : normalizedAccent; document.documentElement.dataset.theme = effectiveMode; document.documentElement.dataset.accent = effectiveAccent; try { if (persist) { if (moduleName) { if (normalizedMode === 'inherit') { localStorage.removeItem(`nexus.module.${moduleName}.theme`); } else { localStorage.setItem(`nexus.module.${moduleName}.theme`, normalizedMode); } if (normalizedAccent === 'inherit') { localStorage.removeItem(`nexus.module.${moduleName}.accent`); } else { localStorage.setItem(`nexus.module.${moduleName}.accent`, normalizedAccent); } } else { localStorage.setItem('nexus.theme', normalizedMode); localStorage.setItem('nexus.accent', normalizedAccent); } } } catch (error) { // Ignore blocked storage; the current page still receives the theme. } return { mode: normalizedMode, accent: normalizedAccent }; } const initialTheme = applyTheme(moduleThemeMode, moduleThemeAccent, false); const themeModeSelect = document.querySelector('[data-theme-mode]'); const themeAccentSelect = document.querySelector('[data-theme-accent]'); if (themeModeSelect) { themeModeSelect.value = initialTheme.mode; themeModeSelect.addEventListener('change', () => { const current = storedTheme(); applyTheme(themeModeSelect.value, current.accent); }); } if (themeAccentSelect) { themeAccentSelect.value = initialTheme.accent; themeAccentSelect.addEventListener('change', () => { const current = storedTheme(); applyTheme(current.mode, themeAccentSelect.value); }); } for (const element of document.querySelectorAll('[data-reveal]')) { element.classList.add('reveal'); }