@invisibleloop/pulse 0.12.3 → 0.14.2

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 (181) hide show
  1. package/.claude/commands/build-page.md +5 -1
  2. package/.claude/commands/verify.md +31 -17
  3. package/.claude/pulse-checklist.md +21 -1
  4. package/.github/workflows/publish.yml +1 -0
  5. package/.pulse-verified +1 -0
  6. package/CLAUDE.md +56 -15
  7. package/docs/.claude/commands/verify.md +4 -0
  8. package/docs/.claude/pulse-checklist.md +20 -2
  9. package/docs/public/.pulse-ui-version +1 -1
  10. package/docs/public/andypixel.css +237 -0
  11. package/docs/public/bookworms.css +422 -0
  12. package/docs/public/coutumes.css +584 -0
  13. package/docs/public/images/bookworms/hero-books.jpg +0 -0
  14. package/docs/public/images/bookworms/how-we-read-now.jpg +0 -0
  15. package/docs/public/images/bookworms/lantern-keepers.jpg +0 -0
  16. package/docs/public/images/bookworms/provincial-bookseller.jpg +0 -0
  17. package/docs/public/images/journey/178.jpg +0 -0
  18. package/docs/public/images/journey/29.jpg +0 -0
  19. package/docs/public/images/retrowheels/hero.jpg +0 -0
  20. package/docs/public/images/shop/devbook-pro.jpg +0 -0
  21. package/docs/public/images/suzukibento/1015.jpg +0 -0
  22. package/docs/public/images/suzukibento/1025.jpg +0 -0
  23. package/docs/public/images/suzukibento/1043.jpg +0 -0
  24. package/docs/public/images/suzukibento/1059.jpg +0 -0
  25. package/docs/public/images/suzukibento/1062.jpg +0 -0
  26. package/docs/public/images/suzukibento/1084.jpg +0 -0
  27. package/docs/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
  28. package/docs/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
  29. package/docs/public/images/swish/1485518882345-15568b007407.jpg +0 -0
  30. package/docs/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
  31. package/docs/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
  32. package/docs/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
  33. package/docs/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
  34. package/docs/public/images/swish/1551803091-e20673f15770.jpg +0 -0
  35. package/docs/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
  36. package/docs/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
  37. package/docs/public/journey.css +528 -0
  38. package/docs/public/pulse-ui.css +1036 -22
  39. package/docs/public/retrowheels.css +402 -0
  40. package/docs/public/shop.css +235 -0
  41. package/docs/public/sparkys.css +349 -0
  42. package/docs/public/suzukibento.css +517 -0
  43. package/docs/public/swish.css +394 -0
  44. package/docs/server.js +19 -4
  45. package/docs/src/lib/nav.js +14 -3
  46. package/docs/src/pages/components/decorate.js +74 -0
  47. package/docs/src/pages/components/gallery.js +102 -0
  48. package/docs/src/pages/components/hero.js +1 -0
  49. package/docs/src/pages/components/marquee.js +76 -0
  50. package/docs/src/pages/components/photo-card.js +74 -0
  51. package/docs/src/pages/components/section.js +40 -1
  52. package/docs/src/pages/meta.js +26 -0
  53. package/docs/src/pages/templates/andypixel.js +260 -0
  54. package/docs/src/pages/templates/bookworms.js +227 -0
  55. package/docs/src/pages/templates/coutumes.js +226 -0
  56. package/docs/src/pages/templates/journey.js +186 -0
  57. package/docs/src/pages/templates/retrowheels.js +342 -0
  58. package/docs/src/pages/templates/shop.js +257 -0
  59. package/docs/src/pages/templates/sparkys.js +249 -0
  60. package/docs/src/pages/templates/suzukibento.js +200 -0
  61. package/docs/src/pages/templates/swish.js +313 -0
  62. package/docs/src/pages/templates.js +313 -2
  63. package/docs/src/pages/testing.js +2 -1
  64. package/examples/.claude/commands/pulse-build.md +7 -0
  65. package/examples/.claude/commands/pulse-dev.md +7 -0
  66. package/examples/.claude/commands/pulse-start.md +9 -0
  67. package/examples/.claude/commands/pulse-stop.md +5 -0
  68. package/examples/.claude/commands/verify.md +84 -0
  69. package/examples/.claude/coverage-check.js +127 -0
  70. package/examples/.claude/pulse-checklist.md +177 -0
  71. package/examples/andypixel.css +237 -0
  72. package/examples/andypixel.js +258 -0
  73. package/examples/bookworms.css +422 -0
  74. package/examples/bookworms.js +225 -0
  75. package/examples/contact.js +1 -0
  76. package/examples/counter.js +1 -0
  77. package/examples/dev.server.js +17 -0
  78. package/examples/journey.css +528 -0
  79. package/examples/journey.js +186 -0
  80. package/examples/pricing.js +1 -0
  81. package/examples/public/.pulse-ui-version +1 -0
  82. package/examples/public/pulse-ui.css +4031 -0
  83. package/examples/public/pulse-ui.js +257 -0
  84. package/examples/quiz.js +1 -0
  85. package/examples/retrowheels.css +402 -0
  86. package/examples/retrowheels.js +340 -0
  87. package/examples/shared.js +6 -0
  88. package/examples/suzukibento.css +513 -0
  89. package/examples/suzukibento.js +200 -0
  90. package/examples/swish.css +394 -0
  91. package/examples/swish.js +311 -0
  92. package/examples/todos.js +1 -0
  93. package/package.json +2 -3
  94. package/public/.pulse-ui-version +1 -1
  95. package/public/images/bookworms/hero-books.jpg +0 -0
  96. package/public/images/bookworms/how-we-read-now.jpg +0 -0
  97. package/public/images/bookworms/lantern-keepers.jpg +0 -0
  98. package/public/images/bookworms/provincial-bookseller.jpg +0 -0
  99. package/public/images/journey/178.jpg +0 -0
  100. package/public/images/journey/29.jpg +0 -0
  101. package/public/images/retrowheels/hero.jpg +0 -0
  102. package/public/images/shop/devbook-pro.jpg +0 -0
  103. package/public/images/suzukibento/1015.jpg +0 -0
  104. package/public/images/suzukibento/1025.jpg +0 -0
  105. package/public/images/suzukibento/1043.jpg +0 -0
  106. package/public/images/suzukibento/1059.jpg +0 -0
  107. package/public/images/suzukibento/1062.jpg +0 -0
  108. package/public/images/suzukibento/1084.jpg +0 -0
  109. package/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
  110. package/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
  111. package/public/images/swish/1485518882345-15568b007407.jpg +0 -0
  112. package/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
  113. package/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
  114. package/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
  115. package/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
  116. package/public/images/swish/1551803091-e20673f15770.jpg +0 -0
  117. package/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
  118. package/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
  119. package/public/pulse-ui.css +1080 -22
  120. package/scripts/build.js +72 -18
  121. package/src/agent/checklist.md +22 -2
  122. package/src/agent/commands/verify.md +4 -0
  123. package/src/agent/guide-components.md +146 -8
  124. package/src/agent/guide-design-gallery.md +288 -0
  125. package/src/agent/guide-design-references.md +172 -0
  126. package/src/agent/guide-explore.md +313 -0
  127. package/src/agent/guide-styles.md +212 -11
  128. package/src/agent/guide-templates.md +223 -10
  129. package/src/agent/guide.md +9 -4
  130. package/src/agent/identity.md +2 -1
  131. package/src/agent/skills/verify/SKILL.md +64 -28
  132. package/src/agent/workflow.md +247 -61
  133. package/src/cli/dev.js +39 -14
  134. package/src/cli/fmt.js +113 -0
  135. package/src/cli/index.js +60 -33
  136. package/src/cli/logger.js +145 -0
  137. package/src/cli/scaffold.js +57 -3
  138. package/src/html.js +6 -1
  139. package/src/mcp/server.js +2561 -99
  140. package/src/mcp/validate-worker.js +49 -5
  141. package/src/runtime/ssr.js +4 -1
  142. package/src/server/index.js +29 -5
  143. package/src/spec/schema.js +21 -0
  144. package/src/spec/schema.test.js +28 -0
  145. package/src/testing/html.js +130 -4
  146. package/src/testing/testing.test.js +58 -0
  147. package/src/ui/banner.js +24 -9
  148. package/src/ui/brand-statement.js +58 -0
  149. package/src/ui/button.js +13 -2
  150. package/src/ui/card.js +20 -1
  151. package/src/ui/colophon.js +29 -0
  152. package/src/ui/contact-row.js +41 -0
  153. package/src/ui/cta.js +18 -4
  154. package/src/ui/decorate.js +55 -0
  155. package/src/ui/display-heading.js +44 -0
  156. package/src/ui/drop-cap.js +29 -0
  157. package/src/ui/editorial-hero.js +63 -0
  158. package/src/ui/entry-list.js +36 -0
  159. package/src/ui/feature.js +20 -3
  160. package/src/ui/footer.js +78 -9
  161. package/src/ui/gallery.js +56 -0
  162. package/src/ui/hero.js +68 -18
  163. package/src/ui/image-pair.js +72 -0
  164. package/src/ui/index.js +20 -0
  165. package/src/ui/input.js +1 -0
  166. package/src/ui/marquee.js +48 -0
  167. package/src/ui/nav.js +19 -9
  168. package/src/ui/photo-card.js +44 -0
  169. package/src/ui/product-card.js +65 -0
  170. package/src/ui/pullquote.js +14 -3
  171. package/src/ui/search.js +1 -0
  172. package/src/ui/section-label.js +38 -0
  173. package/src/ui/section.js +1 -1
  174. package/src/ui/service-card.js +47 -0
  175. package/src/ui/stat-grid.js +40 -0
  176. package/src/ui/stat.js +16 -2
  177. package/src/ui/testimonial.js +17 -6
  178. package/src/ui/textarea.js +1 -0
  179. package/src/ui/top-strip.js +47 -0
  180. package/src/ui/trust-list.js +46 -0
  181. package/src/ui/ui.test.js +35 -0
@@ -0,0 +1,349 @@
1
+ /*
2
+ * sparkys.css — Sparkys Electrical template styles
3
+ * Navy + amber. Light theme.
4
+ */
5
+
6
+ /* ── Palette tokens ─────────────────────────────────────────────────────── */
7
+ [data-theme="light"] {
8
+ --ui-bg: #f7f9fc;
9
+ --ui-surface: #ffffff;
10
+ --ui-surface-2: #eef2f8;
11
+ --ui-border: #d6deea;
12
+ --ui-text: #0f172a;
13
+ --ui-muted: #475569;
14
+ --ui-accent: #0a3160;
15
+ --ui-accent-hover: #082748;
16
+ --ui-accent-dim: #e3ecf7;
17
+ --ui-accent-text: #ffffff;
18
+
19
+ --brand-amber: #b56f00;
20
+ --brand-amber-soft: #fff4dd;
21
+ --brand-amber-strong: #f4a721;
22
+ --brand-navy-deep: #062247;
23
+ --brand-white: #ffffff;
24
+ --brand-mist: #cfd8e6;
25
+ --brand-overlay-12: rgba(255, 255, 255, 0.12);
26
+ }
27
+
28
+ /* ── Base ───────────────────────────────────────────────────────────────── */
29
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
30
+
31
+ body {
32
+ font-family: var(--ui-font, system-ui, sans-serif);
33
+ line-height: 1.6;
34
+ }
35
+
36
+ .brand-mark {
37
+ font-weight: 800;
38
+ letter-spacing: -0.01em;
39
+ font-size: var(--ui-text-lg);
40
+ color: var(--ui-accent);
41
+ }
42
+
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);
48
+ }
49
+ .ui-top-strip a {
50
+ color: inherit;
51
+ text-decoration: none;
52
+ font-weight: 600;
53
+ }
54
+ .ui-top-strip a:hover { text-decoration: underline; }
55
+
56
+ /* ── Hero ──────────────────────────────────────────────────────────────── */
57
+ .hero-split {
58
+ display: grid;
59
+ grid-template-columns: 1.2fr 1fr;
60
+ min-height: 70vh;
61
+ background: var(--ui-bg);
62
+ }
63
+ .hero-split__text {
64
+ padding: var(--ui-space-16) var(--ui-space-8);
65
+ display: flex;
66
+ flex-direction: column;
67
+ justify-content: center;
68
+ max-width: 640px;
69
+ margin-left: auto;
70
+ width: 100%;
71
+ }
72
+ .hero-split__eyebrow {
73
+ font-size: var(--ui-text-sm);
74
+ letter-spacing: 0.15em;
75
+ text-transform: uppercase;
76
+ font-weight: 700;
77
+ color: var(--ui-accent);
78
+ margin-bottom: var(--ui-space-4);
79
+ }
80
+ .hero-split__title {
81
+ font-size: clamp(2.25rem, 5vw, 3.75rem);
82
+ font-weight: 800;
83
+ line-height: 1.05;
84
+ letter-spacing: -0.02em;
85
+ color: var(--ui-text);
86
+ margin-bottom: var(--ui-space-5);
87
+ }
88
+ .hero-split__subtitle {
89
+ font-size: var(--ui-text-lg);
90
+ color: var(--ui-muted);
91
+ margin-bottom: var(--ui-space-8);
92
+ max-width: 52ch;
93
+ }
94
+ .hero-split__actions {
95
+ display: flex;
96
+ flex-wrap: wrap;
97
+ gap: var(--ui-space-3);
98
+ margin-bottom: var(--ui-space-8);
99
+ }
100
+ .hero-split__trust {
101
+ display: flex;
102
+ flex-wrap: wrap;
103
+ gap: var(--ui-space-5);
104
+ font-size: var(--ui-text-sm);
105
+ color: var(--ui-muted);
106
+ font-weight: 600;
107
+ }
108
+ /* trustList() inside trust slot — override default small size */
109
+ .hero-split__trust .ui-trust-list-item {
110
+ font-weight: 600;
111
+ }
112
+
113
+ .hero-split__panel {
114
+ background: linear-gradient(160deg, var(--ui-accent) 0%, var(--brand-navy-deep) 100%);
115
+ color: var(--brand-white);
116
+ padding: var(--ui-space-12) var(--ui-space-8);
117
+ display: flex;
118
+ flex-direction: column;
119
+ justify-content: center;
120
+ gap: var(--ui-space-8);
121
+ position: relative;
122
+ overflow: hidden;
123
+ }
124
+ .hero-split__panel::before {
125
+ content: "";
126
+ position: absolute;
127
+ inset: auto -40px -40px auto;
128
+ width: 220px;
129
+ height: 220px;
130
+ background: var(--brand-amber-strong);
131
+ opacity: 0.18;
132
+ border-radius: 50%;
133
+ }
134
+ .hero-split__panel-title {
135
+ font-size: var(--ui-text-sm);
136
+ letter-spacing: 0.15em;
137
+ text-transform: uppercase;
138
+ font-weight: 700;
139
+ color: var(--brand-amber-strong);
140
+ position: relative;
141
+ }
142
+ .hero-stats {
143
+ display: grid;
144
+ grid-template-columns: 1fr 1fr;
145
+ gap: var(--ui-space-6);
146
+ position: relative;
147
+ }
148
+ .hero-stat__value {
149
+ font-size: clamp(1.875rem, 3.5vw, 2.5rem);
150
+ font-weight: 800;
151
+ letter-spacing: -0.02em;
152
+ color: var(--brand-white);
153
+ line-height: 1;
154
+ margin-bottom: var(--ui-space-2);
155
+ }
156
+ .hero-stat__label {
157
+ font-size: var(--ui-text-sm);
158
+ color: var(--brand-mist);
159
+ }
160
+ .hero-stat__rating {
161
+ display: inline-flex;
162
+ align-items: center;
163
+ gap: var(--ui-space-1);
164
+ color: var(--brand-amber-strong);
165
+ }
166
+
167
+ /* ── Section base ─────────────────────────────────────────────────────── */
168
+ .section {
169
+ padding: var(--ui-space-16) var(--ui-space-6);
170
+ }
171
+ .section--alt { background: var(--ui-surface-2); }
172
+ .section__inner {
173
+ max-width: 1200px;
174
+ margin: 0 auto;
175
+ }
176
+ .section__head {
177
+ max-width: 640px;
178
+ margin: 0 auto var(--ui-space-12);
179
+ text-align: center;
180
+ }
181
+ .section__eyebrow {
182
+ font-size: var(--ui-text-sm);
183
+ letter-spacing: 0.15em;
184
+ text-transform: uppercase;
185
+ font-weight: 700;
186
+ color: var(--ui-accent);
187
+ margin-bottom: var(--ui-space-3);
188
+ }
189
+ .section__title {
190
+ font-size: clamp(1.75rem, 3.5vw, 2.5rem);
191
+ font-weight: 800;
192
+ letter-spacing: -0.02em;
193
+ color: var(--ui-text);
194
+ margin-bottom: var(--ui-space-4);
195
+ }
196
+ .section__subtitle {
197
+ font-size: var(--ui-text-lg);
198
+ color: var(--ui-muted);
199
+ }
200
+
201
+ /* ── Services grid — serviceCard() component ───────────────────────────── */
202
+ .services {
203
+ display: grid;
204
+ grid-template-columns: repeat(3, 1fr);
205
+ gap: var(--ui-space-5);
206
+ }
207
+ /* serviceCard() title size override */
208
+ .services .ui-service-card-title {
209
+ font-size: var(--ui-text-xl);
210
+ font-weight: 700;
211
+ }
212
+ .services .ui-service-card-desc {
213
+ font-size: var(--ui-text-base);
214
+ }
215
+ .services .ui-service-card--linked:hover {
216
+ transform: translateY(-2px);
217
+ }
218
+
219
+ /* ── Why grid ──────────────────────────────────────────────────────────── */
220
+ .why {
221
+ display: grid;
222
+ grid-template-columns: repeat(3, 1fr);
223
+ gap: var(--ui-space-6);
224
+ }
225
+ .why__item {
226
+ padding: var(--ui-space-6);
227
+ border-left: 3px solid var(--brand-amber-strong);
228
+ background: var(--ui-surface);
229
+ }
230
+ .why__title {
231
+ font-size: var(--ui-text-xl);
232
+ font-weight: 700;
233
+ color: var(--ui-text);
234
+ margin-bottom: var(--ui-space-2);
235
+ }
236
+ .why__body {
237
+ color: var(--ui-muted);
238
+ }
239
+
240
+ /* ── Testimonial ───────────────────────────────────────────────────────── */
241
+ .quote {
242
+ max-width: 820px;
243
+ margin: 0 auto;
244
+ text-align: center;
245
+ }
246
+ .quote__mark {
247
+ font-size: var(--ui-text-4xl);
248
+ color: var(--brand-amber-strong);
249
+ font-weight: 800;
250
+ line-height: 1;
251
+ margin-bottom: var(--ui-space-3);
252
+ }
253
+ .quote__text {
254
+ font-size: clamp(1.25rem, 2.5vw, 1.625rem);
255
+ font-weight: 500;
256
+ color: var(--ui-text);
257
+ line-height: 1.45;
258
+ margin-bottom: var(--ui-space-6);
259
+ }
260
+ .quote__cite {
261
+ color: var(--ui-muted);
262
+ font-size: var(--ui-text-sm);
263
+ font-weight: 600;
264
+ letter-spacing: 0.05em;
265
+ text-transform: uppercase;
266
+ }
267
+
268
+ /* ── Contact strip ─────────────────────────────────────────────────────── */
269
+ .contact-strip {
270
+ background: var(--ui-accent);
271
+ color: var(--brand-white);
272
+ padding: var(--ui-space-12) var(--ui-space-6);
273
+ }
274
+ .contact-strip__inner {
275
+ max-width: 1200px;
276
+ margin: 0 auto;
277
+ display: grid;
278
+ grid-template-columns: 1.4fr 1fr;
279
+ gap: var(--ui-space-10);
280
+ align-items: center;
281
+ }
282
+ .contact-strip__title {
283
+ font-size: clamp(1.75rem, 3.5vw, 2.5rem);
284
+ font-weight: 800;
285
+ letter-spacing: -0.02em;
286
+ margin-bottom: var(--ui-space-3);
287
+ color: var(--brand-white);
288
+ }
289
+ .contact-strip__lead {
290
+ font-size: var(--ui-text-lg);
291
+ color: var(--brand-mist);
292
+ }
293
+ .contact-strip__details {
294
+ display: flex;
295
+ flex-direction: column;
296
+ gap: var(--ui-space-3);
297
+ }
298
+ .contact-strip__details .ui-contact-row {
299
+ flex-direction: column;
300
+ }
301
+ .contact-strip__details .ui-contact-row-item {
302
+ color: var(--brand-white);
303
+ font-weight: 600;
304
+ font-size: var(--ui-text-lg);
305
+ }
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 {
309
+ width: 36px;
310
+ height: 36px;
311
+ border-radius: 50%;
312
+ background: var(--brand-overlay-12);
313
+ display: grid;
314
+ place-items: center;
315
+ line-height: 0;
316
+ color: var(--brand-white);
317
+ }
318
+
319
+ /* ── Footer overrides ──────────────────────────────────────────────────── */
320
+ .site-footer__brand {
321
+ color: var(--brand-white);
322
+ font-weight: 800;
323
+ font-size: var(--ui-text-lg);
324
+ letter-spacing: -0.01em;
325
+ }
326
+ .ui-footer .site-footer__brand { color: var(--brand-white); }
327
+ .ui-footer {
328
+ background: var(--brand-navy-deep);
329
+ color: var(--brand-mist);
330
+ }
331
+ .ui-footer a { color: var(--brand-mist); }
332
+ .ui-footer a:hover { color: var(--brand-white); }
333
+ .ui-footer .ui-footer-legal,
334
+ .ui-footer p { color: var(--brand-mist); }
335
+
336
+ /* ── Responsive ───────────────────────────────────────────────────────── */
337
+ @media (max-width: 900px) {
338
+ .hero-split { grid-template-columns: 1fr; min-height: auto; }
339
+ .hero-split__text { padding: var(--ui-space-12) var(--ui-space-6); margin: 0 auto; }
340
+ .hero-split__panel { padding: var(--ui-space-10) var(--ui-space-6); }
341
+ .services { grid-template-columns: repeat(2, 1fr); }
342
+ .why { grid-template-columns: 1fr; }
343
+ .contact-strip__inner { grid-template-columns: 1fr; }
344
+ }
345
+ @media (max-width: 600px) {
346
+ .services { grid-template-columns: 1fr; }
347
+ .hero-stats { grid-template-columns: 1fr; }
348
+ .section { padding: var(--ui-space-12) var(--ui-space-5); }
349
+ }