Files
eranos/public/theme.js
T
Alex Gleason 8d03d32b0d Simplify theme system to 4 core colors (background, text, primary, secondary)
Replace the 19-token ThemeTokens interface with a 4-field CoreThemeColors
for config storage, Nostr events, and encrypted settings. All other
Tailwind CSS tokens (card, muted, border, etc.) are now derived
automatically via deriveTokensFromCore().

- Add CoreThemeColors interface: { background, text, primary, secondary }
- Keep ThemeTokens as internal type for CSS variable injection
- Update builtinThemes and themePresets to store CoreThemeColors
- Add backward-compatible parsing for legacy 19-token format in Nostr
  events, encrypted settings, and localStorage
- Simplify ThemeBuilderPage: remove Surface/UI color sections, just 4
  color pickers with auto-derivation always on
- Update all consumers: ThemeSelector, ScopedTheme, ThemeUpdateCard,
  MobileDrawer, LeftSidebar, ProfilePage, InitialSyncGate, etc.
2026-02-25 22:46:27 -06:00

63 lines
2.3 KiB
JavaScript

// Reads the saved theme from localStorage and applies it to <html> and the
// preloader background before first paint. Runs as a blocking <script> so
// there's no flash of the wrong theme.
(function () {
// Builtin themes — only light and dark have hardcoded preview colors here.
// Custom themes read their background/primary from the stored customTheme object.
var builtins = {
dark: { bg: 'hsl(228 20% 10%)', primary: 'hsl(258 70% 60%)' },
light: { bg: 'hsl(0 0% 100%)', primary: 'hsl(258 70% 55%)' }
};
// Legacy preset mapping for backward compat (old configs with "black" or "pink")
var legacyPresets = {
black: { bg: 'hsl(0 0% 0%)', primary: 'hsl(258 70% 60%)' },
pink: { bg: 'hsl(330 100% 96%)', primary: 'hsl(330 90% 60%)' }
};
var theme = 'dark';
var colors = builtins.dark;
try {
var cfg = JSON.parse(localStorage.getItem('nostr:app-config') || '{}');
if (cfg.theme) theme = cfg.theme;
} catch (e) {}
// Resolve "system" to light or dark based on OS preference
if (theme === 'system') {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
colors = builtins[theme];
} else if (theme === 'custom') {
// Read background and primary from stored customTheme
try {
var ct = cfg.customTheme;
if (ct) {
// New format: { background, text, primary, secondary }
// Legacy format: { background, foreground, primary, accent, ... }
var bg = ct.background;
var pr = ct.primary;
if (bg && pr) {
colors = { bg: 'hsl(' + bg + ')', primary: 'hsl(' + pr + ')' };
}
}
} catch (e) {}
} else if (legacyPresets[theme]) {
// Backward compat: old "black"/"pink" values → use their colors
colors = legacyPresets[theme];
} else {
colors = builtins[theme] || builtins.dark;
}
document.documentElement.className = theme;
document.body.style.background = colors.bg;
var p = document.getElementById('preloader');
if (p) {
p.style.background = colors.bg;
var logo = p.querySelector('[data-logo]');
if (logo) logo.style.background = colors.primary;
var spinner = p.querySelector('[data-spinner]');
if (spinner) {
spinner.style.borderColor = colors.primary.replace(')', ' / 0.25)');
spinner.style.borderTopColor = colors.primary;
}
}
})();