@heart-of-gold/toolkit 0.1.39 → 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.9"
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.9"
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.7"
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.39",
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.7",
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",
@@ -131,21 +131,47 @@
131
131
  margin-bottom: var(--space-3);
132
132
  }
133
133
 
134
- .theme-toggle {
134
+ .theme-switcher {
135
135
  display: inline-flex;
136
136
  align-items: center;
137
- gap: 10px;
138
- padding: 10px 14px;
137
+ gap: 6px;
138
+ padding: 6px;
139
139
  border-radius: 999px;
140
140
  border: 1px solid var(--border);
141
- background: var(--panel-soft);
141
+ background: color-mix(in srgb, var(--panel-strong) 82%, transparent);
142
142
  box-shadow: var(--shadow-md);
143
- color: var(--muted);
144
143
  backdrop-filter: blur(14px);
145
144
  }
146
145
 
147
- .theme-toggle strong {
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 {
148
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 {
149
175
  font-size: 13px;
150
176
  font-weight: 600;
151
177
  }
@@ -414,9 +440,17 @@
414
440
  justify-content: stretch;
415
441
  }
416
442
 
417
- .theme-toggle {
443
+ .theme-switcher {
418
444
  width: 100%;
419
- justify-content: center;
445
+ justify-content: space-between;
446
+ }
447
+
448
+ .theme-option {
449
+ flex: 1 1 0;
450
+ }
451
+
452
+ .theme-option .text {
453
+ display: none;
420
454
  }
421
455
 
422
456
  .hero,
@@ -442,10 +476,20 @@
442
476
  <body>
443
477
  <main>
444
478
  <div class="topbar">
445
- <button class="theme-toggle" id="theme-toggle" type="button" aria-label="Toggle light and dark theme">
446
- <strong>Theme</strong>
447
- <span id="theme-label">Auto</span>
448
- </button>
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>
449
493
  </div>
450
494
 
451
495
  <section class="hero">
@@ -503,10 +547,9 @@
503
547
  (() => {
504
548
  const root = document.documentElement;
505
549
  const metaTheme = document.querySelector('meta[name="theme-color"]');
506
- const button = document.getElementById('theme-toggle');
507
- const label = document.getElementById('theme-label');
508
550
  const storageKey = 'hog-artifact-theme';
509
551
  const media = window.matchMedia('(prefers-color-scheme: dark)');
552
+ const options = Array.from(document.querySelectorAll('.theme-option'));
510
553
 
511
554
  const computeTheme = (mode) => {
512
555
  if (mode === 'auto') return media.matches ? 'dark' : 'light';
@@ -517,18 +560,21 @@
517
560
 
518
561
  const apply = (mode) => {
519
562
  root.dataset.theme = mode;
520
- if (label) label.textContent = mode[0].toUpperCase() + mode.slice(1);
521
563
  if (metaTheme) metaTheme.setAttribute('content', themeColor(mode));
564
+ options.forEach((option) => {
565
+ option.setAttribute('aria-pressed', option.dataset.themeValue === mode ? 'true' : 'false');
566
+ });
522
567
  };
523
568
 
524
569
  const saved = localStorage.getItem(storageKey) || 'auto';
525
570
  apply(saved);
526
571
 
527
- button?.addEventListener('click', () => {
528
- const current = root.dataset.theme || 'auto';
529
- const next = current === 'auto' ? 'dark' : current === 'dark' ? 'light' : 'auto';
530
- localStorage.setItem(storageKey, next);
531
- apply(next);
572
+ options.forEach((option) => {
573
+ option.addEventListener('click', () => {
574
+ const mode = option.dataset.themeValue || 'auto';
575
+ localStorage.setItem(storageKey, mode);
576
+ apply(mode);
577
+ });
532
578
  });
533
579
 
534
580
  media.addEventListener?.('change', () => {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deep-thought",
3
- "version": "0.2.9",
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.9",
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",