@invisibleloop/pulse 0.20.5 → 0.20.7

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.
Files changed (164) hide show
  1. package/.claude/pulse-checklist.md +1 -2
  2. package/CLAUDE.md +1 -2
  3. package/docs/.claude/pulse-checklist.md +1 -2
  4. package/docs/public/coutumes.css +21 -44
  5. package/docs/public/docs.css +73 -6
  6. package/docs/public/home-brut.css +175 -191
  7. package/docs/public/pulse-ui.css +8 -1037
  8. package/docs/public/retrowheels.css +23 -0
  9. package/docs/public/shop.css +35 -1
  10. package/docs/public/sparkys.css +56 -23
  11. package/docs/public/theme.css +51 -7
  12. package/docs/server.js +0 -11
  13. package/docs/src/lib/component-page.js +2 -1
  14. package/docs/src/lib/nav.js +0 -11
  15. package/docs/src/pages/accessibility.js +2 -1
  16. package/docs/src/pages/actions.js +2 -1
  17. package/docs/src/pages/auth.js +2 -1
  18. package/docs/src/pages/caching.js +2 -1
  19. package/docs/src/pages/components/accordion.js +2 -1
  20. package/docs/src/pages/components/alert.js +2 -1
  21. package/docs/src/pages/components/app-badge.js +2 -1
  22. package/docs/src/pages/components/avatar.js +2 -1
  23. package/docs/src/pages/components/badge.js +2 -1
  24. package/docs/src/pages/components/breadcrumbs.js +2 -1
  25. package/docs/src/pages/components/button.js +2 -1
  26. package/docs/src/pages/components/card.js +2 -1
  27. package/docs/src/pages/components/charts.js +4 -2
  28. package/docs/src/pages/components/checkbox.js +2 -1
  29. package/docs/src/pages/components/cluster.js +2 -1
  30. package/docs/src/pages/components/container.js +2 -1
  31. package/docs/src/pages/components/cta.js +2 -1
  32. package/docs/src/pages/components/divider.js +2 -1
  33. package/docs/src/pages/components/empty.js +2 -1
  34. package/docs/src/pages/components/feature.js +2 -1
  35. package/docs/src/pages/components/fieldset.js +2 -1
  36. package/docs/src/pages/components/fileupload.js +2 -1
  37. package/docs/src/pages/components/footer.js +2 -1
  38. package/docs/src/pages/components/grid.js +11 -6
  39. package/docs/src/pages/components/heading.js +2 -1
  40. package/docs/src/pages/components/hero.js +2 -1
  41. package/docs/src/pages/components/icons.js +2 -1
  42. package/docs/src/pages/components/image.js +2 -1
  43. package/docs/src/pages/components/input.js +2 -1
  44. package/docs/src/pages/components/media.js +2 -1
  45. package/docs/src/pages/components/modal.js +2 -1
  46. package/docs/src/pages/components/nav.js +2 -1
  47. package/docs/src/pages/components/phone-frame.js +2 -1
  48. package/docs/src/pages/components/progress.js +2 -1
  49. package/docs/src/pages/components/prose.js +2 -1
  50. package/docs/src/pages/components/pullquote.js +2 -1
  51. package/docs/src/pages/components/radio.js +2 -1
  52. package/docs/src/pages/components/rating.js +2 -1
  53. package/docs/src/pages/components/search.js +2 -1
  54. package/docs/src/pages/components/section.js +2 -1
  55. package/docs/src/pages/components/segmented.js +2 -1
  56. package/docs/src/pages/components/select.js +2 -1
  57. package/docs/src/pages/components/slider.js +2 -1
  58. package/docs/src/pages/components/spinner.js +2 -1
  59. package/docs/src/pages/components/stack.js +2 -1
  60. package/docs/src/pages/components/stat.js +2 -1
  61. package/docs/src/pages/components/stepper.js +2 -1
  62. package/docs/src/pages/components/table.js +2 -1
  63. package/docs/src/pages/components/textarea.js +2 -1
  64. package/docs/src/pages/components/toggle.js +2 -1
  65. package/docs/src/pages/components/tooltip.js +2 -1
  66. package/docs/src/pages/components.js +2 -5
  67. package/docs/src/pages/config.js +2 -1
  68. package/docs/src/pages/constraints.js +2 -1
  69. package/docs/src/pages/deploy.js +2 -1
  70. package/docs/src/pages/error-pages.js +2 -1
  71. package/docs/src/pages/extending.js +2 -1
  72. package/docs/src/pages/faq.js +2 -1
  73. package/docs/src/pages/forms.js +2 -1
  74. package/docs/src/pages/getting-started.js +2 -1
  75. package/docs/src/pages/guard.js +2 -1
  76. package/docs/src/pages/home.js +24 -15
  77. package/docs/src/pages/how-it-works.js +22 -15
  78. package/docs/src/pages/hydration.js +2 -1
  79. package/docs/src/pages/images.js +2 -1
  80. package/docs/src/pages/markdown.js +2 -1
  81. package/docs/src/pages/meta.js +2 -1
  82. package/docs/src/pages/mutations.js +2 -1
  83. package/docs/src/pages/navigation.js +2 -1
  84. package/docs/src/pages/performance.js +2 -1
  85. package/docs/src/pages/persist.js +2 -1
  86. package/docs/src/pages/project-structure.js +2 -1
  87. package/docs/src/pages/prompt-examples.js +2 -1
  88. package/docs/src/pages/raw-responses.js +2 -1
  89. package/docs/src/pages/routing.js +2 -1
  90. package/docs/src/pages/server-api.js +2 -1
  91. package/docs/src/pages/server-data.js +2 -1
  92. package/docs/src/pages/slash-commands.js +2 -1
  93. package/docs/src/pages/spec.js +2 -1
  94. package/docs/src/pages/state.js +2 -1
  95. package/docs/src/pages/store.js +2 -1
  96. package/docs/src/pages/streaming.js +2 -1
  97. package/docs/src/pages/stripe.js +2 -1
  98. package/docs/src/pages/supabase.js +2 -1
  99. package/docs/src/pages/templates/coutumes.js +83 -72
  100. package/docs/src/pages/templates/mobile-app.js +36 -9
  101. package/docs/src/pages/templates/retrowheels.js +17 -4
  102. package/docs/src/pages/templates/shop.js +21 -10
  103. package/docs/src/pages/templates/sparkys.js +35 -20
  104. package/docs/src/pages/templates.js +2 -2
  105. package/docs/src/pages/testing.js +2 -1
  106. package/docs/src/pages/validation.js +2 -1
  107. package/examples/.claude/pulse-checklist.md +1 -2
  108. package/examples/examples.test.js +4 -4
  109. package/examples/pricing.js +21 -3
  110. package/examples/public/pulse-ui.css +8 -1037
  111. package/examples/retrowheels.css +23 -0
  112. package/examples/retrowheels.js +17 -4
  113. package/package.json +5 -1
  114. package/public/.pulse-ui-version +1 -1
  115. package/public/pulse-ui.css +8 -1037
  116. package/src/agent/checklist.md +1 -2
  117. package/src/agent/guide-components.md +43 -67
  118. package/src/agent/guide-design-gallery.md +14 -14
  119. package/src/agent/guide-design-references.md +21 -21
  120. package/src/agent/guide-styles.md +2 -2
  121. package/src/agent/guide-templates.md +6 -6
  122. package/src/agent/identity.md +1 -1
  123. package/src/agent/workflow.md +1 -2
  124. package/src/mcp/server.js +31 -24
  125. package/src/ui/index.js +0 -27
  126. package/src/ui/ui.test.js +0 -137
  127. package/types/charts.d.ts +61 -0
  128. package/types/ui.d.ts +1 -129
  129. package/docs/src/pages/components/banner.js +0 -44
  130. package/docs/src/pages/components/carousel.js +0 -71
  131. package/docs/src/pages/components/code-window.js +0 -56
  132. package/docs/src/pages/components/decorate.js +0 -74
  133. package/docs/src/pages/components/gallery.js +0 -102
  134. package/docs/src/pages/components/list.js +0 -111
  135. package/docs/src/pages/components/marquee.js +0 -76
  136. package/docs/src/pages/components/photo-card.js +0 -74
  137. package/docs/src/pages/components/pricing.js +0 -67
  138. package/docs/src/pages/components/testimonial.js +0 -48
  139. package/docs/src/pages/components/timeline.js +0 -226
  140. package/src/ui/banner.js +0 -41
  141. package/src/ui/brand-statement.js +0 -58
  142. package/src/ui/carousel.js +0 -59
  143. package/src/ui/code-window.js +0 -39
  144. package/src/ui/colophon.js +0 -29
  145. package/src/ui/contact-row.js +0 -41
  146. package/src/ui/decorate.js +0 -55
  147. package/src/ui/display-heading.js +0 -44
  148. package/src/ui/drop-cap.js +0 -29
  149. package/src/ui/editorial-hero.js +0 -63
  150. package/src/ui/entry-list.js +0 -36
  151. package/src/ui/gallery.js +0 -60
  152. package/src/ui/image-pair.js +0 -72
  153. package/src/ui/list.js +0 -36
  154. package/src/ui/marquee.js +0 -48
  155. package/src/ui/photo-card.js +0 -44
  156. package/src/ui/pricing.js +0 -56
  157. package/src/ui/product-card.js +0 -65
  158. package/src/ui/section-label.js +0 -38
  159. package/src/ui/service-card.js +0 -47
  160. package/src/ui/stat-grid.js +0 -40
  161. package/src/ui/testimonial.js +0 -59
  162. package/src/ui/timeline.js +0 -72
  163. package/src/ui/top-strip.js +0 -47
  164. package/src/ui/trust-list.js +0 -46
@@ -327,6 +327,29 @@ h1, h2, h3, h4, h5, h6,
327
327
  margin-bottom: var(--ui-space-4);
328
328
  }
329
329
 
330
+ /* Review cards — replaces the removed testimonial() component */
331
+ .rw-review-stars {
332
+ display: flex;
333
+ gap: 2px;
334
+ color: var(--rw-orange-dark);
335
+ margin-bottom: var(--ui-space-3);
336
+ }
337
+
338
+ .rw-review-quote {
339
+ font-style: italic;
340
+ color: var(--ui-text);
341
+ }
342
+
343
+ .rw-review-name {
344
+ font-family: var(--ui-font-display);
345
+ font-weight: 900;
346
+ }
347
+
348
+ .rw-review-role {
349
+ font-size: var(--ui-text-sm);
350
+ color: var(--ui-muted);
351
+ }
352
+
330
353
  .rw-service-price {
331
354
  font-family: 'Courier New', monospace;
332
355
  font-size: var(--ui-text-sm);
@@ -41,7 +41,7 @@ body {
41
41
  padding: var(--ui-space-16) var(--ui-space-6) var(--ui-space-8);
42
42
  }
43
43
 
44
- .product-display .ui-display-heading {
44
+ .product-display .product-display-title {
45
45
  font-size: clamp(3rem, 10vw, 8rem);
46
46
  line-height: 1;
47
47
  letter-spacing: -0.04em;
@@ -49,6 +49,40 @@ body {
49
49
  color: var(--ui-text);
50
50
  }
51
51
 
52
+ /* Section eyebrow + rule — replaces the removed sectionLabel() component */
53
+ .shop-section-label {
54
+ margin-bottom: var(--ui-space-6);
55
+ }
56
+ .shop-section-label-eyebrow {
57
+ font-size: var(--ui-text-sm);
58
+ letter-spacing: 0.1em;
59
+ text-transform: uppercase;
60
+ font-weight: 600;
61
+ color: var(--ui-color-muted);
62
+ margin-bottom: var(--ui-space-2);
63
+ }
64
+ .shop-section-label-heading {
65
+ margin-bottom: var(--ui-space-3);
66
+ }
67
+ .shop-section-label-rule {
68
+ border: none;
69
+ border-top: 1px solid var(--ui-border);
70
+ }
71
+
72
+ /* End-of-page metadata — replaces the removed colophon() component */
73
+ .shop-colophon {
74
+ padding: var(--ui-space-8) var(--ui-space-6);
75
+ text-align: center;
76
+ border-top: 1px solid var(--ui-border);
77
+ }
78
+ .shop-colophon-inner {
79
+ font-size: var(--ui-text-sm);
80
+ color: var(--ui-color-muted);
81
+ }
82
+ .shop-colophon-inner a {
83
+ color: inherit;
84
+ }
85
+
52
86
  .product-display .product-tagline {
53
87
  margin-top: var(--ui-space-4);
54
88
  font-size: var(--ui-text-xl);
@@ -41,17 +41,23 @@ body {
41
41
  }
42
42
 
43
43
  /* ── Top utility strip ─────────────────────────────────────────────────── */
44
- /* top-strip rendered via topStrip() component — background/color set inline */
45
- .ui-top-strip {
46
- max-width: none;
47
- padding-inline: var(--ui-space-6);
44
+ /* raw two-column bar — replaces the removed topStrip() component */
45
+ .top-strip {
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: space-between;
49
+ gap: var(--ui-space-4);
50
+ padding: var(--ui-space-2) var(--ui-space-6);
51
+ background: var(--brand-navy-deep);
52
+ color: var(--brand-white);
53
+ font-size: var(--ui-text-sm);
48
54
  }
49
- .ui-top-strip a {
55
+ .top-strip a {
50
56
  color: inherit;
51
57
  text-decoration: none;
52
58
  font-weight: 600;
53
59
  }
54
- .ui-top-strip a:hover { text-decoration: underline; }
60
+ .top-strip a:hover { text-decoration: underline; }
55
61
 
56
62
  /* ── Hero ──────────────────────────────────────────────────────────────── */
57
63
  .hero-split {
@@ -105,10 +111,23 @@ body {
105
111
  color: var(--ui-muted);
106
112
  font-weight: 600;
107
113
  }
108
- /* trustList() inside trust slot — override default small size */
109
- .hero-split__trust .ui-trust-list-item {
114
+ /* trust-inline list — replaces the removed trustList() component */
115
+ .trust-inline {
116
+ display: flex;
117
+ flex-wrap: wrap;
118
+ gap: var(--ui-space-5);
119
+ list-style: none;
120
+ }
121
+ .trust-inline__item {
122
+ display: flex;
123
+ align-items: center;
124
+ gap: var(--ui-space-2);
110
125
  font-weight: 600;
111
126
  }
127
+ .trust-inline__icon {
128
+ display: inline-flex;
129
+ color: var(--brand-amber);
130
+ }
112
131
 
113
132
  .hero-split__panel {
114
133
  background: linear-gradient(160deg, var(--ui-accent) 0%, var(--brand-navy-deep) 100%);
@@ -198,22 +217,29 @@ body {
198
217
  color: var(--ui-muted);
199
218
  }
200
219
 
201
- /* ── Services grid — serviceCard() component ───────────────────────────── */
202
- .services {
220
+ /* ── Services grid — card() component with a bordered service-card look ─── */
221
+ .service-card {
222
+ border: 1px solid var(--ui-border);
223
+ box-shadow: none;
224
+ }
225
+ .service-card .ui-service-card-icon {
226
+ width: 44px;
227
+ height: 44px;
228
+ border-radius: var(--ui-radius-md);
229
+ background: var(--ui-accent-dim);
230
+ color: var(--ui-accent);
203
231
  display: grid;
204
- grid-template-columns: repeat(3, 1fr);
205
- gap: var(--ui-space-5);
232
+ place-items: center;
233
+ margin-bottom: var(--ui-space-4);
206
234
  }
207
- /* serviceCard() title size override */
208
- .services .ui-service-card-title {
235
+ .service-card .ui-service-card-title {
209
236
  font-size: var(--ui-text-xl);
210
237
  font-weight: 700;
238
+ margin-bottom: var(--ui-space-2);
211
239
  }
212
- .services .ui-service-card-desc {
240
+ .service-card .ui-service-card-desc {
213
241
  font-size: var(--ui-text-base);
214
- }
215
- .services .ui-service-card--linked:hover {
216
- transform: translateY(-2px);
242
+ color: var(--ui-muted);
217
243
  }
218
244
 
219
245
  /* ── Why grid ──────────────────────────────────────────────────────────── */
@@ -295,17 +321,24 @@ body {
295
321
  flex-direction: column;
296
322
  gap: var(--ui-space-3);
297
323
  }
298
- .contact-strip__details .ui-contact-row {
324
+ /* contact-inline list — replaces the removed contactRow() component */
325
+ .contact-inline {
326
+ display: flex;
299
327
  flex-direction: column;
328
+ gap: var(--ui-space-3);
329
+ list-style: none;
300
330
  }
301
- .contact-strip__details .ui-contact-row-item {
331
+ .contact-inline__item {
332
+ display: flex;
333
+ align-items: center;
334
+ gap: var(--ui-space-3);
302
335
  color: var(--brand-white);
303
336
  font-weight: 600;
304
337
  font-size: var(--ui-text-lg);
305
338
  }
306
- .contact-strip__details .ui-contact-row-item a { color: var(--brand-white); }
307
- .contact-strip__details .ui-contact-row-item a:hover { color: var(--brand-amber-strong); }
308
- .contact-strip__details .ui-contact-row-icon {
339
+ .contact-inline__item a { color: var(--brand-white); text-decoration: none; }
340
+ .contact-inline__item a:hover { color: var(--brand-amber-strong); }
341
+ .contact-inline__icon {
309
342
  width: 36px;
310
343
  height: 36px;
311
344
  border-radius: 50%;
@@ -1,8 +1,52 @@
1
- /* Brut theme tokens */
2
- :root {
3
- --brut-yellow: #f0e642;
4
- --brut-ink: #0a0a0a;
5
- --brut-surface: #ffffff;
6
- --brut-dark: #111114;
7
- --brut-darker: #111214;
1
+ /* Brut theme tokens — home page only, scoped to [data-theme="light"] on <body> */
2
+ [data-theme="light"] {
3
+ /* Confident saturated gold — solid block fill (dark ink text sits on top) */
4
+ --brut-gold: #e8b613;
5
+ --brut-gold-deep: #c99700;
6
+ --brut-ink: #171512;
7
+ --brut-surface: #faf8f2;
8
+ --brut-surface-2: #f1ede1;
9
+ --brut-muted: #5c574c;
10
+ --brut-dark: #171512;
11
+ --brut-darker: #100f0c;
12
+ --brut-surface-dot: #e6e0d2;
13
+ }
14
+
15
+ /* Site-wide light theme tokens — feeds docs.css's :root token names (--bg,
16
+ --surface, --text, --accent, etc.) and pulse-ui.css's input tokens, so
17
+ every docs page (nav, sidebar, guides, component reference, templates
18
+ gallery) picks up the same warm/gold/paper palette as the home page. */
19
+ [data-theme="light"] {
20
+ --bg: var(--brut-surface);
21
+ --surface: #ffffff;
22
+ --surface-2: var(--brut-surface-2);
23
+ --border: #ddd6c4;
24
+ --border-subtle: #ece7d9;
25
+ --text: var(--brut-ink);
26
+ --muted: var(--brut-muted);
27
+ --muted-2: #8a8272;
28
+ --accent: var(--brut-gold-deep);
29
+ --accent-text: var(--brut-ink);
30
+ --accent-hover: #a97f00;
31
+ --accent-dim: rgba(201, 151, 0, 0.12);
32
+ --green: #166534;
33
+ --red: #b91c1c;
34
+
35
+ /* Syntax tokens — dark-on-light, tuned for contrast on --surface-2 */
36
+ --tok-kw: #7c3aed;
37
+ --tok-str: #15803d;
38
+ --tok-cmt: #78716c;
39
+ --tok-num: #c2410c;
40
+ --tok-fn: #1d4ed8;
41
+ --tok-prop: #a16207;
42
+ --tok-op: #0891b2;
43
+ --tok-punct: #57534e;
44
+
45
+ /* Sticky header background — replaces the hardcoded rgba(13,13,16,.9) */
46
+ --header-bg: rgba(250, 248, 242, 0.9);
47
+
48
+ /* Callout / tag accents that were hardcoded dark-theme hex in docs.css */
49
+ --callout-note-icon: #1d4ed8;
50
+ --tag-required-bg: rgba(185, 28, 28, 0.12);
51
+ --tag-required-text: #b91c1c;
8
52
  }
package/docs/server.js CHANGED
@@ -76,7 +76,6 @@ await createServer(
76
76
  new URL('./src/pages/components/button.js', import.meta.url),
77
77
  new URL('./src/pages/components/card.js', import.meta.url),
78
78
  new URL('./src/pages/components/checkbox.js', import.meta.url),
79
- new URL('./src/pages/components/carousel.js', import.meta.url),
80
79
  new URL('./src/pages/components/charts.js', import.meta.url),
81
80
  new URL('./src/pages/components/empty.js', import.meta.url),
82
81
  new URL('./src/pages/components/fieldset.js', import.meta.url),
@@ -84,12 +83,8 @@ await createServer(
84
83
  new URL('./src/pages/components/heading.js', import.meta.url),
85
84
  new URL('./src/pages/components/icons.js', import.meta.url),
86
85
  new URL('./src/pages/components/image.js', import.meta.url),
87
- new URL('./src/pages/components/gallery.js', import.meta.url),
88
86
  new URL('./src/pages/components/input.js', import.meta.url),
89
- new URL('./src/pages/components/list.js', import.meta.url),
90
- new URL('./src/pages/components/marquee.js', import.meta.url),
91
87
  new URL('./src/pages/components/modal.js', import.meta.url),
92
- new URL('./src/pages/components/photo-card.js', import.meta.url),
93
88
  new URL('./src/pages/components/progress.js', import.meta.url),
94
89
  new URL('./src/pages/components/prose.js', import.meta.url),
95
90
  new URL('./src/pages/components/pullquote.js', import.meta.url),
@@ -104,7 +99,6 @@ await createServer(
104
99
  new URL('./src/pages/components/stepper.js', import.meta.url),
105
100
  new URL('./src/pages/components/table.js', import.meta.url),
106
101
  new URL('./src/pages/components/textarea.js', import.meta.url),
107
- new URL('./src/pages/components/timeline.js', import.meta.url),
108
102
  new URL('./src/pages/components/toggle.js', import.meta.url),
109
103
  new URL('./src/pages/components/tooltip.js', import.meta.url),
110
104
  // Landing Components
@@ -115,8 +109,6 @@ await createServer(
115
109
  new URL('./src/pages/components/hero.js', import.meta.url),
116
110
  new URL('./src/pages/components/nav.js', import.meta.url),
117
111
  new URL('./src/pages/components/phone-frame.js', import.meta.url),
118
- new URL('./src/pages/components/pricing.js', import.meta.url),
119
- new URL('./src/pages/components/testimonial.js', import.meta.url),
120
112
  // Templates
121
113
  new URL('./src/pages/templates.js', import.meta.url),
122
114
  new URL('./src/pages/templates/mobile-app.js', import.meta.url),
@@ -131,11 +123,8 @@ await createServer(
131
123
  new URL('./src/pages/templates/journey.js', import.meta.url),
132
124
  new URL('./src/pages/templates/shop.js', import.meta.url),
133
125
  // Layout Components
134
- new URL('./src/pages/components/banner.js', import.meta.url),
135
126
  new URL('./src/pages/components/cluster.js', import.meta.url),
136
- new URL('./src/pages/components/code-window.js', import.meta.url),
137
127
  new URL('./src/pages/components/container.js', import.meta.url),
138
- new URL('./src/pages/components/decorate.js', import.meta.url),
139
128
  new URL('./src/pages/components/divider.js', import.meta.url),
140
129
  new URL('./src/pages/components/footer.js', import.meta.url),
141
130
  new URL('./src/pages/components/grid.js', import.meta.url),
@@ -11,6 +11,7 @@ import { highlight } from './highlight.js'
11
11
  export function demo(previewHtml, codeStr, { col = false, scroll = false, bleed = false } = {}) {
12
12
  const previewClass = [
13
13
  'demo-preview',
14
+ 'is-light',
14
15
  col ? 'demo-preview--col' : '',
15
16
  scroll ? 'demo-preview--scroll' : '',
16
17
  bleed ? 'demo-preview--bleed' : '',
@@ -20,7 +21,7 @@ export function demo(previewHtml, codeStr, { col = false, scroll = false, bleed
20
21
  <svg class="demo-theme-toggle__light" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
21
22
  </button>`
22
23
  return `<div class="component-demo">
23
- <div class="${previewClass}">${toggle}<div class="demo-preview-inner">${previewHtml}</div></div>
24
+ <div class="${previewClass}">${toggle}<div class="demo-preview-inner ui-theme-light">${previewHtml}</div></div>
24
25
  <div class="demo-code">${codeBlock(highlight(codeStr, 'js'))}</div>
25
26
  </div>`
26
27
  }
@@ -84,7 +84,6 @@ export const NAV = [
84
84
  { label: 'Button', href: '/components/button' },
85
85
  { label: 'Card', href: '/components/card' },
86
86
  { label: 'Checkbox', href: '/components/checkbox' },
87
- { label: 'Carousel', href: '/components/carousel' },
88
87
  { label: 'Charts', href: '/components/charts' },
89
88
  { label: 'Empty', href: '/components/empty' },
90
89
  { label: 'Fieldset', href: '/components/fieldset' },
@@ -92,12 +91,8 @@ export const NAV = [
92
91
  { label: 'Heading', href: '/components/heading' },
93
92
  { label: 'Icons', href: '/components/icons' },
94
93
  { label: 'Image', href: '/components/image' },
95
- { label: 'Gallery', href: '/components/gallery' },
96
94
  { label: 'Input', href: '/components/input' },
97
- { label: 'List', href: '/components/list' },
98
- { label: 'Marquee', href: '/components/marquee' },
99
95
  { label: 'Modal', href: '/components/modal' },
100
- { label: 'Photo Card', href: '/components/photo-card' },
101
96
  { label: 'Progress', href: '/components/progress' },
102
97
  { label: 'Prose', href: '/components/prose' },
103
98
  { label: 'Pullquote', href: '/components/pullquote' },
@@ -112,7 +107,6 @@ export const NAV = [
112
107
  { label: 'Stepper', href: '/components/stepper' },
113
108
  { label: 'Table', href: '/components/table' },
114
109
  { label: 'Textarea', href: '/components/textarea' },
115
- { label: 'Timeline', href: '/components/timeline' },
116
110
  { label: 'Toggle', href: '/components/toggle' },
117
111
  { label: 'Tooltip', href: '/components/tooltip' },
118
112
  ],
@@ -127,18 +121,13 @@ export const NAV = [
127
121
  { label: 'Hero', href: '/components/hero' },
128
122
  { label: 'Nav', href: '/components/nav' },
129
123
  { label: 'Phone Frame', href: '/components/phone-frame' },
130
- { label: 'Pricing', href: '/components/pricing' },
131
- { label: 'Testimonial', href: '/components/testimonial' },
132
124
  ],
133
125
  },
134
126
  {
135
127
  section: 'Layout Components',
136
128
  items: [
137
- { label: 'Banner', href: '/components/banner' },
138
129
  { label: 'Cluster', href: '/components/cluster' },
139
- { label: 'Code Window', href: '/components/code-window' },
140
130
  { label: 'Container', href: '/components/container' },
141
- { label: 'Decorate', href: '/components/decorate' },
142
131
  { label: 'Divider', href: '/components/divider' },
143
132
  { label: 'Footer', href: '/components/footer' },
144
133
  { label: 'Grid', href: '/components/grid' },
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/accessibility')
7
7
  export default {
8
8
  route: '/accessibility',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Accessibility — Pulse Docs',
11
12
  description: 'Keyboard navigation, focus management, semantic HTML, and ARIA patterns in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/accessibility',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/actions')
7
7
  export default {
8
8
  route: '/actions',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Actions — Pulse Docs',
11
12
  description: 'Async operations in Pulse — lifecycle, FormData, error handling.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/auth')
7
7
  export default {
8
8
  route: '/auth',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Auth (Auth0) — Pulse Docs',
11
12
  description: 'Integrating Auth0 OAuth authentication with Pulse using guard functions, ctx.setCookie, and raw response specs.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/auth',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/caching')
7
7
  export default {
8
8
  route: '/caching',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Caching — Pulse Docs',
11
12
  description: 'HTTP cache headers, in-process server data caching, and asset caching in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/caching',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/accordion')
8
8
  export default {
9
9
  route: '/components/accordion',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Accordion — Pulse Docs',
12
13
  description: 'Accordion component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/accordion',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components/alert')
7
7
  export default {
8
8
  route: '/components/alert',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Alert — Pulse Docs',
11
12
  description: 'Alert component for Pulse UI.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderComponentPage({
15
16
  currentHref: '/components/alert',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/app-badge')
8
8
  export default {
9
9
  route: '/components/app-badge',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'App Badge — Pulse Docs',
12
13
  description: 'App Badge component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/app-badge',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components/avatar')
7
7
  export default {
8
8
  route: '/components/avatar',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Avatar — Pulse Docs',
11
12
  description: 'Avatar component for Pulse UI.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderComponentPage({
15
16
  currentHref: '/components/avatar',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components/badge')
7
7
  export default {
8
8
  route: '/components/badge',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Badge — Pulse Docs',
11
12
  description: 'Badge component for Pulse UI.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderComponentPage({
15
16
  currentHref: '/components/badge',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/breadcrumbs')
8
8
  export default {
9
9
  route: '/components/breadcrumbs',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Breadcrumbs — Pulse Docs',
12
13
  description: 'Accessible breadcrumb navigation component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/breadcrumbs',
@@ -9,9 +9,10 @@ const { prev, next } = prevNext('/components/button')
9
9
  export default {
10
10
  route: '/components/button',
11
11
  meta: {
12
+ theme: 'light',
12
13
  title: 'Button — Pulse Docs',
13
14
  description: 'Button component for Pulse UI.',
14
- styles: ['/pulse-ui.css', '/docs.css'],
15
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
15
16
  },
16
17
  view: () => renderComponentPage({
17
18
  currentHref: '/components/button',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/card')
8
8
  export default {
9
9
  route: '/components/card',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Card — Pulse Docs',
12
13
  description: 'Card component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/card',
@@ -1,7 +1,8 @@
1
1
  import { renderComponentPage, demo } from '../../lib/component-page.js'
2
2
  import { prevNext } from '../../lib/nav.js'
3
3
  import { table } from '../../lib/layout.js'
4
- import { barChart, lineChart, donutChart, sparkline, stat, card, grid } from '../../../../src/ui/index.js'
4
+ import { stat, card, grid } from '../../../../src/ui/index.js'
5
+ import { barChart, lineChart, donutChart, sparkline } from '../../../../src/ui/charts.js'
5
6
 
6
7
  const { prev, next } = prevNext('/components/charts')
7
8
 
@@ -28,9 +29,10 @@ const traffic = [
28
29
  export default {
29
30
  route: '/components/charts',
30
31
  meta: {
32
+ theme: 'light',
31
33
  title: 'Charts — Pulse Docs',
32
34
  description: 'Server-rendered SVG charts for Pulse UI.',
33
- styles: ['/pulse-ui.css', '/docs.css'],
35
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
34
36
  },
35
37
  view: () => renderComponentPage({
36
38
  currentHref: '/components/charts',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/checkbox')
8
8
  export default {
9
9
  route: '/components/checkbox',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Checkbox — Pulse Docs',
12
13
  description: 'Custom-styled checkbox component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/checkbox',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/cluster')
8
8
  export default {
9
9
  route: '/components/cluster',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Cluster — Pulse Docs',
12
13
  description: 'Cluster component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/cluster',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/container')
8
8
  export default {
9
9
  route: '/components/container',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Container — Pulse Docs',
12
13
  description: 'Container component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/container',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/cta')
8
8
  export default {
9
9
  route: '/components/cta',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'CTA — Pulse Docs',
12
13
  description: 'Call-to-action block with eyebrow, heading, body text, and an actions slot.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  state: {},
16
17
  view: () => renderComponentPage({
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/divider')
8
8
  export default {
9
9
  route: '/components/divider',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Divider — Pulse Docs',
12
13
  description: 'Divider component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/divider',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components/empty')
7
7
  export default {
8
8
  route: '/components/empty',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Empty — Pulse Docs',
11
12
  description: 'Empty state component for Pulse UI.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderComponentPage({
15
16
  currentHref: '/components/empty',