Being theme system - loads Crown-specific colors

/* being-themes.js — Theme initialization chip * Runs synchronously in <head> to prevent FOUC. * Exposes window.hexPalette for chip-level theme control and * Portal integration (Color Things → Swatches → Palettes). */ (function () { var LS_KEY = 'hex-theme';

// Apply theme attribute immediately — before first paint var saved = localStorage.getItem(LS_KEY) || 'dark'; document.documentElement.dataset.theme = saved;

/* swatch(name) — resolve a palette color in JS from the server-emitted * --swatch-<name> :root var (Swatch/Color Things, incl. derived tiers). * For color MATH (rgba/canvas) where CSS var() can't be used; for plain * styling prefer var(--swatch-<name>) directly. name uses dashes: * swatch('cycle-moon'), swatch('things-gap'). Returns '' if unset. */ window.swatch = function (name) { return getComputedStyle(document.documentElement) .getPropertyValue('--swatch-' + name).trim(); };

function applyTheme(theme) { document.documentElement.dataset.theme = theme; localStorage.setItem(LS_KEY, theme); window.dispatchEvent(new CustomEvent('hex-theme', { detail: { theme: theme } })); }

/* hexPalette — public API for chips and Portal integration. * * Future: applyFromPortal(paletteId) will fetch a Palette Thing * from Portal, walk its swatch gem_values, and set --hex-* CSS vars * directly on :root — overriding the [data-theme] defaults while * preserving the toggle contract (dark/light as semantic layer). * * Day/Night/Season: call applyPhase('dawn'|'day'|'dusk'|'night') * to apply a sub-palette shift on top of the active base theme. * Phase vars sit on [data-phase] — chips may read --hex-phase-bg etc. */ window.hexPalette = { get: function () { return document.documentElement.dataset.theme || 'dark'; }, set: function (theme) { applyTheme(theme); }, toggle: function () { var next = window.hexPalette.get() === 'light' ? 'dark' : 'light'; applyTheme(next); return next; }, isDark: function () { return window.hexPalette.get() !== 'light'; },

/* Portal integration — fetches the resolved Palette → Swatch → Color * chain from Portal and sets one --swatch-<name> CSS var per swatch * (dots become dashes: ache.identity -> --swatch-ache-identity). * Existing --sacred-*/--col-* tokens can reference these as their * fallback to stay live-driven by Portal instead of hardcoded hex. */ applyFromPortal: function (paletteName) { var url = paletteName ? '/api/palette/' + paletteName : '/api/palette'; return fetch(url).then(function (res) { if (!res.ok) throw new Error('palette fetch failed: ' + res.status); return res.json(); }).then(function (data) { var swatches = data.swatches || {}; var root = document.documentElement.style; Object.keys(swatches).forEach(function (name) { var hex = swatches[name].hex; if (!hex) return; root.setProperty('--swatch-' + name.replace(/\./g, '-'), hex); }); return data; }); },

/* Phase sub-palette (sacred cycle awareness) */ applyPhase: function (phase) { document.documentElement.dataset.phase = phase || ''; } }; })();