Files

51 lines
3.1 KiB
JavaScript

// Pansy theme — light is the stylesheet default; dark overrides the tokens on <html>.
// Pref ('system'|'light'|'dark') persists in localStorage and is shared by every page.
(function () {
const KEY = 'pansy-theme';
const DARK = {
'--color-bg': '#252220', '--color-surface': '#33302a', '--color-text': '#f1e9da',
'--color-divider': 'color-mix(in srgb, #f5ead8 16%, transparent)',
'--color-accent': '#d67f48',
'--color-neutral-100': '#2e2b25', '--color-neutral-200': '#3a362f', '--color-neutral-300': '#474238',
'--color-neutral-400': '#645c50', '--color-neutral-500': '#82796a', '--color-neutral-800': '#dcd3c4',
'--color-accent-100': '#3d2c1d', '--color-accent-200': '#59331a', '--color-accent-300': '#8c491a',
'--color-accent-400': '#d67f48', '--color-accent-700': '#f6a06b', '--color-accent-800': '#ffd9bd', '--color-accent-900': '#ffe9da',
'--color-accent-2-200': '#333d24', '--color-accent-2-100': '#2d3520', '--color-accent-2-300': '#3d472b', '--color-accent-2-500': '#728157',
'--color-accent-2-600': '#aebf92', '--color-accent-2-700': '#ccdbb2', '--color-accent-2-800': '#e1eecc',
'--shadow-sm': '0 1px 2px rgba(0,0,0,0.4)', '--shadow-md': '0 3px 10px rgba(0,0,0,0.45)', '--shadow-lg': '0 12px 32px rgba(0,0,0,0.55)',
'--p-field': '#2b2823', '--p-grid-ink': '#f5ead8',
'--p-ink-strong': '#d9d0bf', '--p-ink-soft': '#b3a992', '--p-ink-mute': '#8f8674',
'--p-bed-fill': '#4a4131', '--p-bed-stroke': '#6d5f47', '--p-ing-fill': '#3f382c', '--p-ing-stroke': '#5c5343',
'--p-path-fill': '#312e28', '--p-path-stroke': '#4d473c', '--p-bag-fill': '#463d2f', '--p-bag-stroke': '#6a5d49',
'--p-bkt-fill': '#3e382e', '--p-bkt-stroke': '#5f574a', '--p-tree-fill': '#333a28', '--p-tree-stroke': '#56633f',
'--p-str-fill': '#3b362e', '--p-str-stroke': '#5f574a',
};
const P = {
get() { try { return localStorage.getItem(KEY) || 'system'; } catch (e) { return 'system'; } },
set(v) { try { localStorage.setItem(KEY, v); } catch (e) {} },
sysDark() { return !!(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); },
isDark(pref) { return pref === 'dark' || (pref === 'system' && P.sysDark()); },
apply(dark) {
const r = document.documentElement.style;
Object.keys(DARK).forEach(k => { dark ? r.setProperty(k, DARK[k]) : r.removeProperty(k); });
r.colorScheme = dark ? 'dark' : 'light';
},
watch(cb) {
if (!window.matchMedia) return () => {};
const m = window.matchMedia('(prefers-color-scheme: dark)');
m.addEventListener('change', cb);
return () => m.removeEventListener('change', cb);
},
next(p) { return p === 'system' ? 'light' : p === 'light' ? 'dark' : 'system'; },
icon(p) {
return {
system: ['M4 3h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Z', 'M8 21h8', 'M12 17v4'],
light: ['M12 8a4 4 0 1 0 0 8 4 4 0 1 0 0-8', 'M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M6.3 17.7l-1.4 1.4M19.1 4.9l-1.4 1.4', ''],
dark: ['M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z', '', ''],
}[p] || ['', '', ''];
},
};
window.PansyTheme = P;
P.apply(P.isDark(P.get()));
})();