@stacklist-app/brandkit 1.1.1 → 1.2.1

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.
@@ -0,0 +1,15 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="324" height="96" viewBox="0 0 324 96" role="img" aria-label="brandkit">
2
+ <defs>
3
+ <linearGradient id="bk-wm-grad" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#4F46E5"/>
5
+ <stop offset="1" stop-color="#7C3AED"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="0" y="8" width="80" height="80" rx="19" fill="url(#bk-wm-grad)"/>
9
+ <g fill="#FFFFFF">
10
+ <rect x="22" y="31" width="36" height="9" rx="4.5"/>
11
+ <rect x="22" y="44" width="36" height="9" rx="4.5" opacity="0.82"/>
12
+ <rect x="22" y="57" width="23" height="9" rx="4.5" opacity="0.64"/>
13
+ </g>
14
+ <text x="100" y="61" font-family="'Space Grotesk', 'Helvetica Neue', Arial, sans-serif" font-size="46" font-weight="600" letter-spacing="-1.5" fill="#111827">brandkit</text>
15
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="324" height="96" viewBox="0 0 324 96" role="img" aria-label="brandkit, reversed">
2
+ <rect x="1" y="9" width="78" height="78" rx="18" fill="none" stroke="#FFFFFF" stroke-width="2.5"/>
3
+ <g fill="#FFFFFF">
4
+ <rect x="22" y="31" width="36" height="9" rx="4.5"/>
5
+ <rect x="22" y="44" width="36" height="9" rx="4.5" opacity="0.82"/>
6
+ <rect x="22" y="57" width="23" height="9" rx="4.5" opacity="0.64"/>
7
+ </g>
8
+ <text x="100" y="61" font-family="'Space Grotesk', 'Helvetica Neue', Arial, sans-serif" font-size="46" font-weight="600" letter-spacing="-1.5" fill="#FFFFFF">brandkit</text>
9
+ </svg>
package/dist/styles.css CHANGED
@@ -4,6 +4,73 @@
4
4
  CSS custom properties injected by engine.js from config.json.
5
5
  ═══════════════════════════════════════════════════════════════════ */
6
6
 
7
+ /* ───────────────────────────────────────────────────────────────────
8
+ Default tokens — a config only needs to OVERRIDE these.
9
+ This stylesheet consumes every variable below; shipping defaults here
10
+ means a minimal or ported config never renders broken (invisible
11
+ buttons, colorless code, system fonts, transparent tints).
12
+
13
+ The injected config.theme (dev) and the generated :root (build) both
14
+ cascade AFTER this block, so any token a config sets wins.
15
+
16
+ Backward compatibility: pre-1.1.2 configs set --purple / --purple-rgb.
17
+ Those feed --accent / --accent-rgb below, so old configs keep working
18
+ without setting the new accent tokens.
19
+ ─────────────────────────────────────────────────────────────────── */
20
+ :root {
21
+ /* Surfaces & ink */
22
+ --white: #FFFFFF;
23
+ --cloud: #F9FAFB;
24
+ --mist: #F3F4F6;
25
+ --haze: #D1D5DB;
26
+ --slate: #6B7280;
27
+ --graphite: #374151;
28
+ --ink: #111827;
29
+ --ink-rgb: 17, 24, 39;
30
+
31
+ /* Fonts (overridden per-brand from config.fonts) */
32
+ --font-display: 'Inter', sans-serif;
33
+ --font-body: 'Inter', sans-serif;
34
+
35
+ /* Accent — fill vs. text split (Material/shadcn "on-color" convention)
36
+ --accent the fill color (buttons, active chips)
37
+ --accent-foreground text/icon color ON the fill (must pass on --accent)
38
+ --accent-text the accent used AS text/links on a light surface */
39
+ --accent: var(--purple, #6366F1);
40
+ --accent-rgb: var(--purple-rgb, 99, 102, 241);
41
+ --accent-foreground: #FFFFFF;
42
+ --accent-text: var(--accent);
43
+
44
+ /* Primary action — the fill for primary buttons / CTAs.
45
+ Defaults to the accent, so single-accent brands are unchanged. Brands that
46
+ separate the primary action from the accent (e.g. a black CTA with an orange
47
+ accent) override --primary / --primary-foreground. */
48
+ --primary: var(--accent);
49
+ --primary-foreground: var(--accent-foreground);
50
+
51
+ /* Gradients */
52
+ --gradient-brand: linear-gradient(135deg, #4338CA 0%, #6366F1 50%, #EC4899 100%);
53
+ --gradient-brand-subtle: linear-gradient(135deg, rgba(99, 102, 241, 0.06) 0%, rgba(236, 72, 153, 0.06) 100%);
54
+
55
+ /* Header background — the hero block behind the wordmark/logo.
56
+ Defaults to the brand gradient; override (e.g. a flat dark color) for a
57
+ hero that shouldn't carry the accent. */
58
+ --header-bg: var(--gradient-brand);
59
+
60
+ /* Semantic */
61
+ --success: #10B981;
62
+ --success-rgb: 16, 185, 129;
63
+ --warning: #F59E0B;
64
+ --error: #EF4444;
65
+ --error-rgb: 239, 68, 68;
66
+
67
+ /* Extended palette (coral accents, code-syntax highlight) */
68
+ --coral: #F87171;
69
+ --coral-dark: #DC2626;
70
+ --coral-light: #FCA5A5;
71
+ --lavender: #A5B4FC;
72
+ }
73
+
7
74
  * { margin: 0; padding: 0; box-sizing: border-box; }
8
75
 
9
76
  body {
@@ -33,12 +100,20 @@ body {
33
100
  font-family: var(--font-display), sans-serif;
34
101
  font-size: 18px;
35
102
  font-weight: 700;
36
- color: var(--purple);
103
+ color: var(--accent-text);
37
104
  padding: 0 24px;
38
105
  margin-bottom: 32px;
39
106
  letter-spacing: -0.02em;
40
107
  }
41
108
 
109
+ /* Optional logo image in the sidebar top (brand.sidebarLogo) */
110
+ .sidebar-logo {
111
+ display: block;
112
+ max-height: 28px;
113
+ max-width: 100%;
114
+ width: auto;
115
+ }
116
+
42
117
  .sidebar-nav { list-style: none; }
43
118
 
44
119
  .sidebar-nav a {
@@ -52,7 +127,7 @@ body {
52
127
  }
53
128
 
54
129
  .sidebar-nav a:hover { color: var(--ink); background: var(--cloud); }
55
- .sidebar-nav a.active { color: var(--purple); border-left-color: var(--purple); background: rgba(var(--purple-rgb), 0.04); font-weight: 500; }
130
+ .sidebar-nav a.active { color: var(--accent-text); border-left-color: var(--accent-text); background: rgba(var(--accent-rgb), 0.04); font-weight: 500; }
56
131
 
57
132
  /* ── Sidebar Grouped Navigation ── */
58
133
  .nav-group {
@@ -86,7 +161,7 @@ body {
86
161
  }
87
162
 
88
163
  .nav-group-items a:hover { color: var(--ink); background: var(--cloud); }
89
- .nav-group-items a.active { color: var(--purple); border-left-color: var(--purple); background: rgba(var(--purple-rgb), 0.04); font-weight: 500; }
164
+ .nav-group-items a.active { color: var(--accent-text); border-left-color: var(--accent-text); background: rgba(var(--accent-rgb), 0.04); font-weight: 500; }
90
165
 
91
166
  .main { margin-left: 200px; flex: 1; }
92
167
 
@@ -126,8 +201,8 @@ body {
126
201
  }
127
202
 
128
203
  .copy-format-bar button.active {
129
- background: var(--purple);
130
- color: var(--white);
204
+ background: var(--accent);
205
+ color: var(--accent-foreground);
131
206
  }
132
207
 
133
208
  .copy-format-bar button:hover:not(.active) { background: var(--cloud); }
@@ -168,7 +243,7 @@ body {
168
243
 
169
244
  /* ── Header ── */
170
245
  .header {
171
- background: var(--gradient-brand);
246
+ background: var(--header-bg);
172
247
  border-radius: 24px;
173
248
  padding: 64px 56px;
174
249
  margin-bottom: 72px;
@@ -209,6 +284,14 @@ body {
209
284
  z-index: 1;
210
285
  }
211
286
 
287
+ /* Optional logo image in the header (brand.headerLogo) */
288
+ .header-logo {
289
+ display: block;
290
+ max-height: 56px;
291
+ max-width: 100%;
292
+ width: auto;
293
+ }
294
+
212
295
  /* ── Section ── */
213
296
  .section { margin-bottom: 72px; scroll-margin-top: 24px; }
214
297
 
@@ -293,7 +376,7 @@ body {
293
376
  padding: 2px 0;
294
377
  }
295
378
 
296
- .color-value:hover { color: var(--purple); }
379
+ .color-value:hover { color: var(--accent-text); }
297
380
 
298
381
  .color-role { font-size: 11px; color: var(--haze); margin-top: 2px; }
299
382
 
@@ -428,9 +511,9 @@ body {
428
511
  font-family: var(--font-body), sans-serif;
429
512
  font-size: 12px;
430
513
  font-weight: 500;
431
- color: var(--purple);
432
- background: rgba(var(--purple-rgb), 0.06);
433
- border: 1px solid rgba(var(--purple-rgb), 0.15);
514
+ color: var(--accent-text);
515
+ background: rgba(var(--accent-rgb), 0.06);
516
+ border: 1px solid rgba(var(--accent-rgb), 0.15);
434
517
  border-radius: 6px;
435
518
  padding: 4px 8px;
436
519
  cursor: pointer;
@@ -488,7 +571,7 @@ body {
488
571
  .hierarchy-demo .h-primary { font-size: 15px; color: var(--ink); line-height: 1.7; margin-bottom: 14px; }
489
572
  .hierarchy-demo .h-secondary { font-size: 15px; color: var(--graphite); line-height: 1.7; margin-bottom: 14px; }
490
573
  .hierarchy-demo .h-tertiary { font-size: 13px; color: var(--slate); line-height: 1.6; margin-bottom: 14px; }
491
- .hierarchy-demo .h-accent { font-size: 15px; font-weight: 500; color: var(--purple); }
574
+ .hierarchy-demo .h-accent { font-size: 15px; font-weight: 500; color: var(--accent-text); }
492
575
 
493
576
  .hierarchy-labels { display: flex; gap: 28px; flex-wrap: wrap; }
494
577
 
@@ -512,8 +595,8 @@ body {
512
595
 
513
596
  .wordmark-box.on-gradient { background: var(--gradient-brand); color: var(--white); }
514
597
  .wordmark-box.on-dark { background: var(--ink); color: var(--white); }
515
- .wordmark-box.on-light { background: var(--mist); color: var(--purple); }
516
- .wordmark-box.on-white { background: var(--white); color: var(--purple); box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), 0.08); }
598
+ .wordmark-box.on-light { background: var(--mist); color: var(--accent-text); }
599
+ .wordmark-box.on-white { background: var(--white); color: var(--accent-text); box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), 0.08); }
517
600
 
518
601
  .wordmark-note { font-size: 12px; color: var(--slate); text-align: center; margin-top: 6px; }
519
602
 
@@ -607,8 +690,8 @@ body {
607
690
  }
608
691
 
609
692
  .logo-format-toggle button.active {
610
- background: var(--purple);
611
- color: var(--white);
693
+ background: var(--accent);
694
+ color: var(--accent-foreground);
612
695
  }
613
696
 
614
697
  .logo-format-toggle button:hover:not(.active) {
@@ -627,8 +710,8 @@ body {
627
710
  }
628
711
 
629
712
  .logo-card.bg-light .logo-format-toggle button.active {
630
- background: var(--purple);
631
- color: var(--white);
713
+ background: var(--accent);
714
+ color: var(--accent-foreground);
632
715
  }
633
716
 
634
717
  .logo-card.bg-light .logo-format-toggle button:hover:not(.active) {
@@ -682,8 +765,8 @@ body {
682
765
  color: var(--slate);
683
766
  }
684
767
  .logo-card.on-light .logo-format-toggle button.active {
685
- background: var(--purple);
686
- color: var(--white);
768
+ background: var(--accent);
769
+ color: var(--accent-foreground);
687
770
  }
688
771
  .logo-card.on-light .logo-format-toggle button:hover:not(.active) {
689
772
  background: var(--cloud);
@@ -696,7 +779,7 @@ body {
696
779
  .logo-card.on-light .logo-download-btn {
697
780
  border-color: var(--haze);
698
781
  background: transparent;
699
- color: var(--purple);
782
+ color: var(--accent-text);
700
783
  }
701
784
  .logo-card.on-light .logo-download-btn:hover {
702
785
  background: var(--cloud);
@@ -727,11 +810,11 @@ body {
727
810
  .logo-card.bg-light .logo-download-btn {
728
811
  border-color: var(--haze);
729
812
  background: transparent;
730
- color: var(--purple);
813
+ color: var(--accent-text);
731
814
  }
732
815
 
733
816
  .logo-card.bg-light .logo-download-btn:hover {
734
- background: rgba(var(--purple-rgb), 0.06);
817
+ background: rgba(var(--accent-rgb), 0.06);
735
818
  }
736
819
 
737
820
  /* ── Voice ── */
@@ -759,7 +842,7 @@ body {
759
842
  color: var(--ink);
760
843
  margin-bottom: 10px;
761
844
  padding-left: 16px;
762
- border-left: 2px solid rgba(var(--purple-rgb), 0.2);
845
+ border-left: 2px solid rgba(var(--accent-rgb), 0.2);
763
846
  }
764
847
 
765
848
  .voice-example:last-child { margin-bottom: 0; }
@@ -792,11 +875,11 @@ body {
792
875
  .btn-sm { height: 32px; padding: 0 16px; font-size: 13px; border-radius: 9999px; }
793
876
  .btn-md { height: 40px; padding: 0 24px; font-size: 14px; border-radius: 9999px; }
794
877
  .btn-lg { height: 48px; padding: 0 28px; font-size: 16px; border-radius: 9999px; }
795
- .btn-primary { background: var(--purple); color: var(--white); }
796
- .btn-primary:hover { background: #5A2688; }
878
+ .btn-primary { background: var(--primary); color: var(--primary-foreground); }
879
+ .btn-primary:hover { filter: brightness(0.9); }
797
880
  .btn-secondary { background: var(--mist); color: var(--ink); }
798
- .btn-secondary:hover { background: #DDD8E8; }
799
- .btn-ghost { background: transparent; color: var(--purple); border: 1px solid var(--haze); }
881
+ .btn-secondary:hover { filter: brightness(0.96); }
882
+ .btn-ghost { background: transparent; color: var(--accent-text); border: 1px solid var(--haze); }
800
883
  .btn-ghost:hover { background: var(--cloud); }
801
884
  .btn-gradient { background: var(--gradient-brand); color: var(--white); }
802
885
  .btn-gradient:hover { opacity: 0.9; }
@@ -827,8 +910,8 @@ body {
827
910
  font-weight: 500;
828
911
  padding: 3px 10px;
829
912
  border-radius: 9999px;
830
- background: rgba(var(--purple-rgb), 0.08);
831
- color: var(--purple);
913
+ background: rgba(var(--accent-rgb), 0.08);
914
+ color: var(--accent-text);
832
915
  }
833
916
 
834
917
  .dark-card-demo { background: var(--ink); border-radius: 20px; padding: 36px; margin-top: 20px; }
@@ -915,7 +998,7 @@ body {
915
998
 
916
999
  .a11y-badge.pass { background: rgba(var(--success-rgb), 0.15); color: var(--success); }
917
1000
  .a11y-badge.fail { background: rgba(var(--error-rgb), 0.12); color: var(--error); }
918
- .a11y-badge.large { background: rgba(var(--purple-rgb), 0.12); color: var(--purple); }
1001
+ .a11y-badge.large { background: rgba(var(--accent-rgb), 0.12); color: var(--accent-text); }
919
1002
 
920
1003
  /* ── Code Block ── */
921
1004
  .code-block {
@@ -52,7 +52,6 @@ module.exports = function brandkitVite(options) {
52
52
  },
53
53
 
54
54
  closeBundle: function () {
55
- // Copy brand directory to build output
56
55
  var srcDir = path.resolve(brandDir);
57
56
  if (!fs.existsSync(srcDir)) return;
58
57
 
@@ -61,7 +60,27 @@ module.exports = function brandkitVite(options) {
61
60
  fs.mkdirSync(outDir, { recursive: true });
62
61
  }
63
62
 
63
+ // Copy assets (config.json, logos, anything in brand/) to the output.
64
64
  copyDir(srcDir, outDir);
65
+
66
+ // Then produce a real production build into the output: theme baked into
67
+ // styles.css, engine.js copied, and the agent-native exports written +
68
+ // embedded in index.html. This makes the deployed /brand carry brand.json,
69
+ // tokens.json, brand.md and the inline <script id="brandkit-brand"> — so an
70
+ // agent pointed at the URL gets structured brand data without a manual
71
+ // `brandkit build` step. Falls back to the raw copy if config is missing.
72
+ var configPath = path.join(srcDir, 'config.json');
73
+ if (fs.existsSync(configPath)) {
74
+ try {
75
+ var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
76
+ var template = require('../lib/template');
77
+ var resolve = require('../lib/resolve');
78
+ template.build(resolve.getDistPath(), outDir, config);
79
+ } catch (e) {
80
+ // Leave the raw copy in place; don't fail the host build, but say why.
81
+ console.warn('[brandkit] agent-export step skipped: ' + e.message);
82
+ }
83
+ }
65
84
  }
66
85
  };
67
86
  };