anentrypoint-design 0.0.165 → 0.0.167

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/theme.js CHANGED
@@ -1,17 +1,26 @@
1
1
  // 247420 design system — theme controller.
2
2
  //
3
- // Three modes:
4
- // 'auto' — follow OS (prefers-color-scheme). Live-updates on OS change.
5
- // 'paper' — force light.
6
- // 'ink' — force dark.
3
+ // Theme modes (data-theme):
4
+ // 'auto' — follow OS (prefers-color-scheme). Live-updates on OS change.
5
+ // 'paper' — force light.
6
+ // 'ink' — force dark.
7
+ // 'thebird' — warm-paper brand preset (named theme).
8
+ // Accents (data-accent): 'green' | 'purple' | 'mascot'.
9
+ // Density (data-density): 'compact' | 'comfortable' | 'spacious'.
7
10
  //
8
- // Writes the chosen mode to <html data-theme="..."> so CSS rules in
9
- // system.css / colors_and_type.css resolve correctly. Persists to
10
- // localStorage under '247420:theme'. Auto-initializes on import in a
11
- // browser context; safe no-op on server.
11
+ // Each is one attribute on <html> the canonical theme (colors_and_type.css)
12
+ // reads. Adding a theme = one [data-theme="X"] block in colors_and_type.css
13
+ // plus its name in THEMES below. Persists to localStorage; auto-inits on
14
+ // browser import; safe no-op on server.
12
15
 
13
16
  const KEY = '247420:theme';
14
- const VALID = new Set(['auto', 'paper', 'ink']);
17
+ const ACCENT_KEY = '247420:accent';
18
+ const DENSITY_KEY = '247420:density';
19
+ // 'auto' is a mode, not a [data-theme] preset block — it stays in VALID for the
20
+ // controller but is the OS-follow path. The named presets are the rest.
21
+ const VALID = new Set(['auto', 'paper', 'ink', 'thebird']);
22
+ const VALID_ACCENT = new Set(['green', 'purple', 'mascot']);
23
+ const VALID_DENSITY = new Set(['compact', 'comfortable', 'spacious']);
15
24
  const listeners = new Set();
16
25
  let _mq = null;
17
26
  let _current = 'auto';
@@ -82,6 +91,44 @@ export function onThemeChange(cb) {
82
91
  return () => listeners.delete(cb);
83
92
  }
84
93
 
94
+ // ---- Accent + density: independent attribute controllers ----
95
+
96
+ function readStoredKey(key, valid) {
97
+ try { const v = window.localStorage.getItem(key); return valid.has(v) ? v : null; } catch { return null; }
98
+ }
99
+
100
+ export function applyAccent(accent) {
101
+ if (!isBrowser()) return accent;
102
+ if (VALID_ACCENT.has(accent)) {
103
+ document.documentElement.setAttribute('data-accent', accent);
104
+ try { window.localStorage.setItem(ACCENT_KEY, accent); } catch {}
105
+ } else {
106
+ // No accent attribute = the theme's default accent (green).
107
+ document.documentElement.removeAttribute('data-accent');
108
+ try { window.localStorage.removeItem(ACCENT_KEY); } catch {}
109
+ }
110
+ return accent;
111
+ }
112
+
113
+ export function getAccent() {
114
+ if (!isBrowser()) return null;
115
+ return document.documentElement.getAttribute('data-accent');
116
+ }
117
+
118
+ export function applyDensity(density) {
119
+ if (!isBrowser()) return density;
120
+ if (VALID_DENSITY.has(density)) {
121
+ document.documentElement.setAttribute('data-density', density);
122
+ try { window.localStorage.setItem(DENSITY_KEY, density); } catch {}
123
+ }
124
+ return density;
125
+ }
126
+
127
+ export function getDensity() {
128
+ if (!isBrowser()) return null;
129
+ return document.documentElement.getAttribute('data-density');
130
+ }
131
+
85
132
  // Auto-init on browser import. Picks stored value, else falls back to
86
133
  // whatever data-theme is already on <html> (set by page-html.js), else 'auto'.
87
134
  export function initTheme() {
@@ -90,6 +137,12 @@ export function initTheme() {
90
137
  const fromAttr = document.documentElement.getAttribute('data-theme');
91
138
  const initial = stored || (VALID.has(fromAttr) ? fromAttr : 'auto');
92
139
  applyTheme(initial);
140
+ // Restore persisted accent/density (no-op if none stored — keeps the
141
+ // theme's default accent and the page's authored density).
142
+ const accent = readStoredKey(ACCENT_KEY, VALID_ACCENT);
143
+ if (accent) applyAccent(accent);
144
+ const density = readStoredKey(DENSITY_KEY, VALID_DENSITY);
145
+ if (density) applyDensity(density);
93
146
  return initial;
94
147
  }
95
148