@heart-of-gold/toolkit 0.1.38 → 0.1.40

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.
@@ -15,19 +15,19 @@
15
15
  "name": "deep-thought",
16
16
  "source": "./plugins/deep-thought",
17
17
  "description": "The Answer Computer — reasoning tools for brainstorming, planning, and deep thinking",
18
- "version": "0.2.8"
18
+ "version": "0.2.10"
19
19
  },
20
20
  {
21
21
  "name": "marvin",
22
22
  "source": "./plugins/marvin",
23
23
  "description": "The Paranoid Android — quality tools for code review, knowledge compounding, and work execution",
24
- "version": "0.3.8"
24
+ "version": "0.3.10"
25
25
  },
26
26
  {
27
27
  "name": "babel-fish",
28
28
  "source": "./plugins/babel-fish",
29
29
  "description": "Universal Translator — media generation tools for audio, image, and video content",
30
- "version": "0.2.6"
30
+ "version": "0.2.8"
31
31
  },
32
32
  {
33
33
  "name": "quellis",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heart-of-gold/toolkit",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "description": "Cross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and more",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-fish",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Universal Translator — media generation tools for audio, image, video, and visualization",
5
5
  "author": {
6
6
  "name": "ondrej-svec",
@@ -116,6 +116,8 @@ Apply these defaults unless the user asks for something else:
116
116
  - readable max-widths for prose
117
117
  - sticky navigation only when it helps, never as the dominant element
118
118
  - polished but restrained effects; no gimmicky AI-demo chrome
119
+ - use the shared theme-ready scaffold with curated palette tokens rather than ad hoc colors
120
+ - default to a calm Rosé Pine-inspired palette that works well for both dark and light modes
119
121
 
120
122
  See also:
121
123
  - `docs/architecture/visualize-design-rules.md`
@@ -376,6 +378,7 @@ Harness note:
376
378
  - prefer the Node helpers for cross-platform behavior
377
379
  - avoid assuming `mktemp /tmp/name-XXXXXX.html` works on every shell; use the provided helper instead
378
380
  - if a harness only supports shell comfortably, use the `.sh` helpers as fallback
381
+ - the shared scaffold already includes a light/dark/auto theme toggle and responsive viewport behavior; preserve those unless the user explicitly wants something else
379
382
 
380
383
  For plans specifically:
381
384
  - do not dump the full task prose into the primary lanes
@@ -450,6 +453,8 @@ When the artifact still feels too markdown-like, do one or more of these:
450
453
  - surface one key takeaway per section before the detail
451
454
  - split `what / why / risk / next` into separate visual units
452
455
  - move citations, raw notes, and source text into a secondary appendix
456
+ - reduce density before widening the layout
457
+ - stack or split crowded regions rather than cramming more into one viewport row
453
458
 
454
459
  ## Guideline Authoring Workflow
455
460
 
@@ -474,6 +479,8 @@ Before returning a shared HTML result, check mentally:
474
479
  - If this is a brainstorm, is it actually branch-shaped enough for a mind map?
475
480
  - Do the section titles help scanning?
476
481
  - Is secondary detail actually secondary?
482
+ - Does the current viewport feel comfortable, or is content being cramped into too few rows?
483
+ - Does the page work in both dark and light mode unless intentionally single-theme?
477
484
 
478
485
  If the answer to several of these is no, reconsider the mode or ask the user.
479
486
 
@@ -1,121 +1,497 @@
1
1
  <!doctype html>
2
- <html lang="en">
2
+ <html lang="en" data-theme="auto">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
+ <meta name="theme-color" content="#1f1d2e" />
6
7
  <title>Heart of Gold Visual Artifact</title>
7
8
  <style>
8
9
  :root {
9
- --bg: #09111f;
10
- --bg-2: #0f1a31;
11
- --panel: rgba(255,255,255,0.06);
12
- --panel-soft: rgba(255,255,255,0.04);
13
- --text: #eef2ff;
14
- --muted: #b8c0d9;
15
- --muted-2: #91a1c2;
16
- --border: rgba(255,255,255,0.11);
17
- --accent: #7c9cff;
18
- --accent-2: #80e0d0;
19
- --success: #86efac;
20
- --warn: #fbbf24;
21
- --danger: #fca5a5;
22
- --shadow: 0 24px 80px rgba(0,0,0,0.34);
23
- --radius-xl: 28px;
24
- --radius-lg: 20px;
25
- --radius-md: 16px;
10
+ --radius-2xl: 28px;
11
+ --radius-xl: 22px;
12
+ --radius-lg: 18px;
13
+ --radius-md: 14px;
14
+ --shadow-lg: 0 22px 80px rgba(0, 0, 0, 0.28);
15
+ --shadow-md: 0 14px 36px rgba(0, 0, 0, 0.16);
16
+ --space-1: 8px;
17
+ --space-2: 12px;
18
+ --space-3: 16px;
19
+ --space-4: 20px;
20
+ --space-5: 24px;
21
+ --space-6: 32px;
22
+ --space-7: 40px;
23
+ --max-main: 1480px;
24
+ --body-max: 76ch;
25
+ --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
26
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
26
27
  }
28
+
29
+ :root,
30
+ :root[data-theme="dark"] {
31
+ color-scheme: dark;
32
+ --bg: #191724;
33
+ --bg-elevated: #1f1d2e;
34
+ --bg-soft: #26233a;
35
+ --panel: rgba(49, 46, 68, 0.78);
36
+ --panel-strong: rgba(38, 35, 58, 0.94);
37
+ --panel-soft: rgba(255, 255, 255, 0.04);
38
+ --text: #e0def4;
39
+ --text-strong: #f6f3ff;
40
+ --muted: #b4b0d0;
41
+ --muted-2: #908caa;
42
+ --border: rgba(224, 222, 244, 0.12);
43
+ --accent: #c4a7e7;
44
+ --accent-2: #9ccfd8;
45
+ --accent-3: #f6c177;
46
+ --success: #9ccfd8;
47
+ --warn: #f6c177;
48
+ --danger: #eb6f92;
49
+ --surface-glow-a: rgba(196, 167, 231, 0.18);
50
+ --surface-glow-b: rgba(156, 207, 216, 0.12);
51
+ --link: #e0def4;
52
+ --hero-border: rgba(224, 222, 244, 0.14);
53
+ --hero-overlay: linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.03));
54
+ }
55
+
56
+ :root[data-theme="light"] {
57
+ color-scheme: light;
58
+ --bg: #faf4ed;
59
+ --bg-elevated: #fffaf3;
60
+ --bg-soft: #f2e9e1;
61
+ --panel: rgba(255, 250, 243, 0.86);
62
+ --panel-strong: rgba(255, 250, 243, 0.98);
63
+ --panel-soft: rgba(86, 61, 56, 0.04);
64
+ --text: #575279;
65
+ --text-strong: #2a273f;
66
+ --muted: #6e6a86;
67
+ --muted-2: #797593;
68
+ --border: rgba(87, 82, 121, 0.12);
69
+ --accent: #907aa9;
70
+ --accent-2: #56949f;
71
+ --accent-3: #ea9d34;
72
+ --success: #56949f;
73
+ --warn: #d7827e;
74
+ --danger: #b4637a;
75
+ --surface-glow-a: rgba(144, 122, 169, 0.12);
76
+ --surface-glow-b: rgba(86, 148, 159, 0.08);
77
+ --link: #3b3756;
78
+ --hero-border: rgba(87, 82, 121, 0.12);
79
+ --hero-overlay: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(255,255,255,0.74));
80
+ --shadow-lg: 0 18px 44px rgba(87, 82, 121, 0.1);
81
+ --shadow-md: 0 10px 24px rgba(87, 82, 121, 0.08);
82
+ }
83
+
27
84
  * { box-sizing: border-box; }
28
- html, body { margin: 0; padding: 0; }
29
- html { color-scheme: dark; }
85
+ html { -webkit-text-size-adjust: 100%; }
86
+ html, body { margin: 0; padding: 0; min-height: 100%; }
30
87
  body {
31
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
32
- line-height: 1.55;
88
+ font-family: var(--font-sans);
89
+ line-height: 1.6;
33
90
  color: var(--text);
34
91
  background:
35
- radial-gradient(circle at top left, rgba(124,156,255,0.18), transparent 32%),
36
- radial-gradient(circle at top right, rgba(128,224,208,0.12), transparent 24%),
37
- linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 100%);
92
+ radial-gradient(circle at top left, var(--surface-glow-a), transparent 30%),
93
+ radial-gradient(circle at top right, var(--surface-glow-b), transparent 25%),
94
+ linear-gradient(180deg, var(--bg-elevated) 0%, var(--bg) 100%);
95
+ text-rendering: optimizeLegibility;
96
+ }
97
+
98
+ a {
99
+ color: var(--link);
100
+ text-decoration-thickness: 1px;
101
+ text-underline-offset: 0.18em;
102
+ }
103
+
104
+ a:hover { text-decoration-thickness: 2px; }
105
+
106
+ button {
107
+ font: inherit;
108
+ color: inherit;
109
+ background: none;
110
+ border: 0;
111
+ cursor: pointer;
112
+ }
113
+
114
+ button:focus-visible,
115
+ a:focus-visible,
116
+ summary:focus-visible {
117
+ outline: 2px solid var(--accent-2);
118
+ outline-offset: 3px;
119
+ border-radius: 12px;
120
+ }
121
+
122
+ main {
123
+ width: min(var(--max-main), calc(100vw - 24px));
124
+ margin: 0 auto;
125
+ padding: clamp(18px, 3vw, 36px) clamp(10px, 2vw, 22px) calc(72px + env(safe-area-inset-bottom));
126
+ }
127
+
128
+ .topbar {
129
+ display: flex;
130
+ justify-content: flex-end;
131
+ margin-bottom: var(--space-3);
38
132
  }
39
- main { max-width: 1480px; margin: 0 auto; padding: 36px 22px 84px; }
40
- .hero, .section, .rail-card, .card, .stat, .chip, .callout {
133
+
134
+ .theme-switcher {
135
+ display: inline-flex;
136
+ align-items: center;
137
+ gap: 6px;
138
+ padding: 6px;
139
+ border-radius: 999px;
41
140
  border: 1px solid var(--border);
42
- box-shadow: var(--shadow);
141
+ background: color-mix(in srgb, var(--panel-strong) 82%, transparent);
142
+ box-shadow: var(--shadow-md);
43
143
  backdrop-filter: blur(14px);
44
144
  }
45
- .hero, .section, .rail-card { background: var(--panel); }
145
+
146
+ .theme-option {
147
+ display: inline-flex;
148
+ align-items: center;
149
+ justify-content: center;
150
+ gap: 8px;
151
+ min-width: 44px;
152
+ padding: 10px 14px;
153
+ border-radius: 999px;
154
+ color: var(--muted-2);
155
+ transition: background-color 160ms ease, color 160ms ease, transform 160ms ease;
156
+ }
157
+
158
+ .theme-option:hover {
159
+ color: var(--text-strong);
160
+ background: color-mix(in srgb, var(--panel-soft) 80%, transparent);
161
+ }
162
+
163
+ .theme-option[aria-pressed="true"] {
164
+ background: color-mix(in srgb, var(--accent) 12%, var(--panel-soft));
165
+ color: var(--text-strong);
166
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, var(--border));
167
+ }
168
+
169
+ .theme-option .icon {
170
+ font-size: 15px;
171
+ line-height: 1;
172
+ }
173
+
174
+ .theme-option .text {
175
+ font-size: 13px;
176
+ font-weight: 600;
177
+ }
178
+
179
+ .hero,
180
+ .section,
181
+ .rail-card,
182
+ .card,
183
+ .stat,
184
+ .callout,
185
+ .lane,
186
+ .chip {
187
+ border: 1px solid var(--border);
188
+ box-shadow: var(--shadow-lg);
189
+ backdrop-filter: blur(16px);
190
+ }
191
+
192
+ .hero,
193
+ .section,
194
+ .rail-card {
195
+ background: var(--panel);
196
+ }
197
+
46
198
  .hero {
47
- padding: 28px;
199
+ position: relative;
200
+ overflow: hidden;
201
+ padding: clamp(20px, 3vw, 32px);
48
202
  border-radius: 32px;
49
- margin-bottom: 24px;
203
+ margin-bottom: var(--space-5);
50
204
  display: grid;
51
- gap: 16px;
205
+ gap: var(--space-3);
206
+ background-image: var(--hero-overlay);
207
+ border-color: var(--hero-border);
208
+ }
209
+
210
+ .hero::after {
211
+ content: "";
212
+ position: absolute;
213
+ inset: auto -10% -50% auto;
214
+ width: 280px;
215
+ height: 280px;
216
+ border-radius: 999px;
217
+ background: radial-gradient(circle, var(--surface-glow-a), transparent 68%);
218
+ pointer-events: none;
52
219
  }
53
- .eyebrow {
220
+
221
+ .eyebrow,
222
+ .label {
54
223
  color: var(--accent-2);
55
224
  text-transform: uppercase;
56
- letter-spacing: 0.16em;
225
+ letter-spacing: 0.14em;
57
226
  font-size: 12px;
58
227
  font-weight: 700;
59
228
  }
60
- h1 { margin: 0; font-size: clamp(34px, 4vw, 62px); line-height: 1.02; text-wrap: balance; }
61
- h2 { margin: 0 0 12px; font-size: clamp(22px, 2vw, 32px); text-wrap: balance; }
62
- h3 { margin: 0 0 10px; font-size: 18px; }
63
- p { margin: 0; color: var(--muted); }
64
- .hero p { max-width: 78ch; font-size: 17px; }
65
- .page { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); gap: 24px; align-items: start; }
66
- .rail { position: sticky; top: 16px; display: grid; gap: 16px; }
67
- .rail-card, .section { padding: 22px; border-radius: var(--radius-xl); }
68
- .section { margin-bottom: 20px; }
69
- .grid-2, .grid-3, .grid-4, .lane-grid { display: grid; gap: 16px; }
229
+
230
+ h1, h2, h3 {
231
+ margin: 0;
232
+ color: var(--text-strong);
233
+ text-wrap: balance;
234
+ }
235
+
236
+ h1 {
237
+ font-size: clamp(2rem, 5vw, 4.3rem);
238
+ line-height: 0.98;
239
+ max-width: 14ch;
240
+ }
241
+
242
+ h2 {
243
+ font-size: clamp(1.45rem, 2.3vw, 2.1rem);
244
+ line-height: 1.08;
245
+ margin-bottom: var(--space-2);
246
+ }
247
+
248
+ h3 {
249
+ font-size: clamp(1.05rem, 1.6vw, 1.25rem);
250
+ line-height: 1.18;
251
+ margin-bottom: var(--space-1);
252
+ }
253
+
254
+ p {
255
+ margin: 0;
256
+ color: var(--muted);
257
+ max-width: var(--body-max);
258
+ }
259
+
260
+ .hero p {
261
+ font-size: clamp(1rem, 1.3vw, 1.1rem);
262
+ }
263
+
264
+ .page {
265
+ display: grid;
266
+ grid-template-columns: minmax(0, 1fr) minmax(250px, 310px);
267
+ gap: var(--space-5);
268
+ align-items: start;
269
+ }
270
+
271
+ .content {
272
+ min-width: 0;
273
+ container-type: inline-size;
274
+ }
275
+
276
+ .rail {
277
+ position: sticky;
278
+ top: 16px;
279
+ display: grid;
280
+ gap: var(--space-3);
281
+ min-width: 0;
282
+ }
283
+
284
+ .rail-card,
285
+ .section {
286
+ padding: clamp(18px, 2vw, 24px);
287
+ border-radius: var(--radius-2xl);
288
+ }
289
+
290
+ .section {
291
+ margin-bottom: var(--space-4);
292
+ overflow: clip;
293
+ }
294
+
295
+ .stack { display: grid; gap: var(--space-3); }
296
+ .grid-2,
297
+ .grid-3,
298
+ .grid-4,
299
+ .lane-grid {
300
+ display: grid;
301
+ gap: var(--space-3);
302
+ min-width: 0;
303
+ }
304
+
70
305
  .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
71
306
  .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
72
307
  .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
73
- .lane-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
74
- .card, .stat, .lane, .callout {
75
- padding: 18px;
76
- border-radius: var(--radius-md);
308
+ .lane-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
309
+
310
+ .card,
311
+ .stat,
312
+ .lane,
313
+ .callout {
314
+ min-width: 0;
315
+ padding: clamp(16px, 1.6vw, 20px);
316
+ border-radius: var(--radius-lg);
77
317
  background: var(--panel-soft);
78
318
  }
79
- .label {
80
- color: var(--accent-2);
81
- text-transform: uppercase;
82
- letter-spacing: 0.11em;
83
- font-size: 12px;
84
- margin-bottom: 8px;
319
+
320
+ .card > p,
321
+ .lane > p,
322
+ .callout > p,
323
+ .rail-card > p {
324
+ max-width: 62ch;
325
+ }
326
+
327
+ .stat .value {
328
+ margin-top: 6px;
329
+ color: var(--text-strong);
330
+ font-size: clamp(1.8rem, 3vw, 2.2rem);
331
+ font-weight: 700;
332
+ font-variant-numeric: tabular-nums;
333
+ }
334
+
335
+ .stat .hint {
336
+ margin-top: 6px;
337
+ color: var(--muted-2);
338
+ font-size: 13px;
85
339
  }
86
- .stat .value { font-size: 28px; font-weight: 700; color: var(--text); margin-top: 6px; }
87
- .stat .hint { color: var(--muted-2); font-size: 13px; margin-top: 6px; }
88
- .chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
340
+
341
+ .chip-row {
342
+ display: flex;
343
+ flex-wrap: wrap;
344
+ gap: var(--space-1);
345
+ margin-top: var(--space-2);
346
+ min-width: 0;
347
+ }
348
+
89
349
  .chip {
90
- display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px; border-radius: 999px;
91
- background: rgba(255,255,255,0.05); color: var(--muted-2); font-size: 12px;
92
- }
93
- .chip.good { color: #c7ffd7; }
94
- .chip.warn { color: #ffd88d; }
95
- .chip.danger { color: #ffd1d1; }
96
- details { margin-top: 12px; }
97
- summary { cursor: pointer; font-weight: 600; }
350
+ display: inline-flex;
351
+ align-items: center;
352
+ gap: 6px;
353
+ max-width: 100%;
354
+ padding: 8px 11px;
355
+ border-radius: 999px;
356
+ background: color-mix(in srgb, var(--panel-strong) 70%, transparent);
357
+ color: var(--muted-2);
358
+ font-size: 12px;
359
+ box-shadow: var(--shadow-md);
360
+ white-space: nowrap;
361
+ }
362
+
363
+ .chip.good { color: var(--success); }
364
+ .chip.warn { color: var(--warn); }
365
+ .chip.danger { color: var(--danger); }
366
+
367
+ .callout {
368
+ background: color-mix(in srgb, var(--accent) 8%, var(--panel-soft));
369
+ border-color: color-mix(in srgb, var(--accent) 22%, var(--border));
370
+ }
371
+
372
+ details {
373
+ margin-top: var(--space-2);
374
+ min-width: 0;
375
+ }
376
+
377
+ summary {
378
+ cursor: pointer;
379
+ font-weight: 600;
380
+ color: var(--text-strong);
381
+ }
382
+
98
383
  .raw {
99
- margin-top: 12px; padding: 14px; border-radius: 14px; border: 1px solid var(--border);
100
- background: rgba(0,0,0,0.22); color: #d8e1fb; white-space: pre-wrap;
101
- font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
384
+ margin-top: var(--space-2);
385
+ padding: 14px;
386
+ border-radius: var(--radius-md);
387
+ border: 1px solid var(--border);
388
+ background: color-mix(in srgb, var(--bg-soft) 70%, transparent);
389
+ color: var(--text);
390
+ white-space: pre-wrap;
391
+ overflow-wrap: anywhere;
392
+ font: 13px/1.55 var(--font-mono);
102
393
  }
103
- a { color: #dce6ff; }
104
- ul { margin: 0; padding-left: 18px; color: var(--muted); }
105
- @media (max-width: 1080px) {
106
- .page { grid-template-columns: 1fr; }
107
- .rail { position: static; }
394
+
395
+ ul,
396
+ ol {
397
+ margin: 0;
398
+ padding-left: 18px;
399
+ color: var(--muted);
400
+ }
401
+
402
+ li + li { margin-top: 6px; }
403
+
404
+ code {
405
+ font-family: var(--font-mono);
406
+ font-size: 0.94em;
407
+ background: color-mix(in srgb, var(--bg-soft) 65%, transparent);
408
+ padding: 0.15em 0.4em;
409
+ border-radius: 8px;
410
+ overflow-wrap: anywhere;
411
+ }
412
+
413
+ .viewport-note {
414
+ margin-top: var(--space-2);
415
+ color: var(--muted-2);
416
+ font-size: 13px;
417
+ }
418
+
419
+ @container (max-width: 860px) {
108
420
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
421
+ .grid-3 { grid-template-columns: 1fr; }
422
+ .grid-2 { grid-template-columns: 1fr; }
109
423
  }
110
- @media (max-width: 720px) {
111
- main { padding: 20px 14px 60px; }
112
- .hero, .section, .rail-card { padding: 18px; }
113
- .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
424
+
425
+ @media (max-width: 1180px) {
426
+ .page { grid-template-columns: 1fr; }
427
+ .rail {
428
+ position: static;
429
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
430
+ }
431
+ }
432
+
433
+ @media (max-width: 760px) {
434
+ main {
435
+ width: min(var(--max-main), calc(100vw - 8px));
436
+ padding: 14px 4px calc(60px + env(safe-area-inset-bottom));
437
+ }
438
+
439
+ .topbar {
440
+ justify-content: stretch;
441
+ }
442
+
443
+ .theme-switcher {
444
+ width: 100%;
445
+ justify-content: space-between;
446
+ }
447
+
448
+ .theme-option {
449
+ flex: 1 1 0;
450
+ }
451
+
452
+ .theme-option .text {
453
+ display: none;
454
+ }
455
+
456
+ .hero,
457
+ .section,
458
+ .rail-card {
459
+ border-radius: 22px;
460
+ }
461
+
462
+ .grid-4,
463
+ .grid-3,
464
+ .grid-2,
465
+ .lane-grid,
466
+ .rail {
467
+ grid-template-columns: 1fr;
468
+ }
469
+
470
+ .chip {
471
+ white-space: normal;
472
+ }
114
473
  }
115
474
  </style>
116
475
  </head>
117
476
  <body>
118
477
  <main>
478
+ <div class="topbar">
479
+ <div class="theme-switcher" role="group" aria-label="Theme switcher">
480
+ <button class="theme-option" id="theme-light" type="button" data-theme-value="light" aria-pressed="false" aria-label="Use light theme" title="Light theme">
481
+ <span class="icon" aria-hidden="true">☀</span>
482
+ <span class="text">Light</span>
483
+ </button>
484
+ <button class="theme-option" id="theme-auto" type="button" data-theme-value="auto" aria-pressed="true" aria-label="Use automatic theme" title="Auto theme">
485
+ <span class="icon" aria-hidden="true">◐</span>
486
+ <span class="text">Auto</span>
487
+ </button>
488
+ <button class="theme-option" id="theme-dark" type="button" data-theme-value="dark" aria-pressed="false" aria-label="Use dark theme" title="Dark theme">
489
+ <span class="icon" aria-hidden="true">☾</span>
490
+ <span class="text">Dark</span>
491
+ </button>
492
+ </div>
493
+ </div>
494
+
119
495
  <section class="hero">
120
496
  <div class="eyebrow">Artifact Family</div>
121
497
  <h1>Title</h1>
@@ -125,10 +501,11 @@
125
501
  <span class="chip">Audience</span>
126
502
  <span class="chip">Purpose</span>
127
503
  </div>
504
+ <div class="viewport-note">Design for the current viewport first. If a section feels cramped, split it, stack it, or reduce its density before adding more content.</div>
128
505
  </section>
129
506
 
130
507
  <div class="page">
131
- <section>
508
+ <section class="content">
132
509
  <section class="section">
133
510
  <div class="label">Summary</div>
134
511
  <h2>Start With the Story</h2>
@@ -165,5 +542,45 @@
165
542
  </aside>
166
543
  </div>
167
544
  </main>
545
+
546
+ <script>
547
+ (() => {
548
+ const root = document.documentElement;
549
+ const metaTheme = document.querySelector('meta[name="theme-color"]');
550
+ const storageKey = 'hog-artifact-theme';
551
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
552
+ const options = Array.from(document.querySelectorAll('.theme-option'));
553
+
554
+ const computeTheme = (mode) => {
555
+ if (mode === 'auto') return media.matches ? 'dark' : 'light';
556
+ return mode;
557
+ };
558
+
559
+ const themeColor = (mode) => computeTheme(mode) === 'dark' ? '#1f1d2e' : '#fffaf3';
560
+
561
+ const apply = (mode) => {
562
+ root.dataset.theme = mode;
563
+ if (metaTheme) metaTheme.setAttribute('content', themeColor(mode));
564
+ options.forEach((option) => {
565
+ option.setAttribute('aria-pressed', option.dataset.themeValue === mode ? 'true' : 'false');
566
+ });
567
+ };
568
+
569
+ const saved = localStorage.getItem(storageKey) || 'auto';
570
+ apply(saved);
571
+
572
+ options.forEach((option) => {
573
+ option.addEventListener('click', () => {
574
+ const mode = option.dataset.themeValue || 'auto';
575
+ localStorage.setItem(storageKey, mode);
576
+ apply(mode);
577
+ });
578
+ });
579
+
580
+ media.addEventListener?.('change', () => {
581
+ if ((root.dataset.theme || 'auto') === 'auto') apply('auto');
582
+ });
583
+ })();
584
+ </script>
168
585
  </body>
169
586
  </html>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deep-thought",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "The Answer Computer — reasoning tools for brainstorming, planning, architecture design, and deep thinking",
5
5
  "author": {
6
6
  "name": "ondrej-svec",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marvin",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "The Paranoid Android — quality tools for code review, knowledge compounding, and work execution",
5
5
  "author": {
6
6
  "name": "ondrej-svec",