@invisibleloop/pulse 0.12.3 → 0.14.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.
Files changed (166) hide show
  1. package/.claude/commands/verify.md +9 -5
  2. package/.claude/pulse-checklist.md +21 -1
  3. package/.github/workflows/publish.yml +1 -0
  4. package/.pulse-verified +1 -0
  5. package/CLAUDE.md +56 -15
  6. package/docs/.claude/commands/verify.md +4 -0
  7. package/docs/.claude/pulse-checklist.md +20 -2
  8. package/docs/public/.pulse-ui-version +1 -1
  9. package/docs/public/andypixel.css +237 -0
  10. package/docs/public/bookworms.css +422 -0
  11. package/docs/public/coutumes.css +584 -0
  12. package/docs/public/images/bookworms/hero-books.jpg +0 -0
  13. package/docs/public/images/bookworms/how-we-read-now.jpg +0 -0
  14. package/docs/public/images/bookworms/lantern-keepers.jpg +0 -0
  15. package/docs/public/images/bookworms/provincial-bookseller.jpg +0 -0
  16. package/docs/public/images/journey/178.jpg +0 -0
  17. package/docs/public/images/journey/29.jpg +0 -0
  18. package/docs/public/images/retrowheels/hero.jpg +0 -0
  19. package/docs/public/images/shop/devbook-pro.jpg +0 -0
  20. package/docs/public/images/suzukibento/1015.jpg +0 -0
  21. package/docs/public/images/suzukibento/1025.jpg +0 -0
  22. package/docs/public/images/suzukibento/1043.jpg +0 -0
  23. package/docs/public/images/suzukibento/1059.jpg +0 -0
  24. package/docs/public/images/suzukibento/1062.jpg +0 -0
  25. package/docs/public/images/suzukibento/1084.jpg +0 -0
  26. package/docs/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
  27. package/docs/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
  28. package/docs/public/images/swish/1485518882345-15568b007407.jpg +0 -0
  29. package/docs/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
  30. package/docs/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
  31. package/docs/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
  32. package/docs/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
  33. package/docs/public/images/swish/1551803091-e20673f15770.jpg +0 -0
  34. package/docs/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
  35. package/docs/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
  36. package/docs/public/journey.css +528 -0
  37. package/docs/public/pulse-ui.css +1036 -22
  38. package/docs/public/retrowheels.css +402 -0
  39. package/docs/public/shop.css +235 -0
  40. package/docs/public/sparkys.css +349 -0
  41. package/docs/public/suzukibento.css +517 -0
  42. package/docs/public/swish.css +394 -0
  43. package/docs/server.js +19 -4
  44. package/docs/src/lib/nav.js +14 -3
  45. package/docs/src/pages/components/decorate.js +74 -0
  46. package/docs/src/pages/components/gallery.js +102 -0
  47. package/docs/src/pages/components/hero.js +1 -0
  48. package/docs/src/pages/components/marquee.js +76 -0
  49. package/docs/src/pages/components/photo-card.js +74 -0
  50. package/docs/src/pages/components/section.js +40 -1
  51. package/docs/src/pages/meta.js +26 -0
  52. package/docs/src/pages/templates/andypixel.js +260 -0
  53. package/docs/src/pages/templates/bookworms.js +227 -0
  54. package/docs/src/pages/templates/coutumes.js +226 -0
  55. package/docs/src/pages/templates/journey.js +186 -0
  56. package/docs/src/pages/templates/retrowheels.js +342 -0
  57. package/docs/src/pages/templates/shop.js +257 -0
  58. package/docs/src/pages/templates/sparkys.js +249 -0
  59. package/docs/src/pages/templates/suzukibento.js +200 -0
  60. package/docs/src/pages/templates/swish.js +313 -0
  61. package/docs/src/pages/templates.js +313 -2
  62. package/docs/src/pages/testing.js +2 -1
  63. package/examples/andypixel.css +237 -0
  64. package/examples/andypixel.js +258 -0
  65. package/examples/bookworms.css +422 -0
  66. package/examples/bookworms.js +225 -0
  67. package/examples/contact.js +1 -0
  68. package/examples/counter.js +1 -0
  69. package/examples/dev.server.js +17 -0
  70. package/examples/journey.css +528 -0
  71. package/examples/journey.js +186 -0
  72. package/examples/pricing.js +1 -0
  73. package/examples/quiz.js +1 -0
  74. package/examples/retrowheels.css +402 -0
  75. package/examples/retrowheels.js +340 -0
  76. package/examples/shared.js +6 -0
  77. package/examples/suzukibento.css +513 -0
  78. package/examples/suzukibento.js +200 -0
  79. package/examples/swish.css +394 -0
  80. package/examples/swish.js +311 -0
  81. package/examples/todos.js +1 -0
  82. package/package.json +2 -3
  83. package/public/.pulse-ui-version +1 -1
  84. package/public/images/bookworms/hero-books.jpg +0 -0
  85. package/public/images/bookworms/how-we-read-now.jpg +0 -0
  86. package/public/images/bookworms/lantern-keepers.jpg +0 -0
  87. package/public/images/bookworms/provincial-bookseller.jpg +0 -0
  88. package/public/images/journey/178.jpg +0 -0
  89. package/public/images/journey/29.jpg +0 -0
  90. package/public/images/retrowheels/hero.jpg +0 -0
  91. package/public/images/shop/devbook-pro.jpg +0 -0
  92. package/public/images/suzukibento/1015.jpg +0 -0
  93. package/public/images/suzukibento/1025.jpg +0 -0
  94. package/public/images/suzukibento/1043.jpg +0 -0
  95. package/public/images/suzukibento/1059.jpg +0 -0
  96. package/public/images/suzukibento/1062.jpg +0 -0
  97. package/public/images/suzukibento/1084.jpg +0 -0
  98. package/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
  99. package/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
  100. package/public/images/swish/1485518882345-15568b007407.jpg +0 -0
  101. package/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
  102. package/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
  103. package/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
  104. package/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
  105. package/public/images/swish/1551803091-e20673f15770.jpg +0 -0
  106. package/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
  107. package/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
  108. package/public/pulse-ui.css +1036 -22
  109. package/scripts/build.js +72 -18
  110. package/src/agent/checklist.md +20 -2
  111. package/src/agent/commands/verify.md +4 -0
  112. package/src/agent/guide-components.md +145 -7
  113. package/src/agent/guide-design-gallery.md +288 -0
  114. package/src/agent/guide-design-references.md +172 -0
  115. package/src/agent/guide-explore.md +313 -0
  116. package/src/agent/guide-styles.md +197 -11
  117. package/src/agent/guide-templates.md +220 -10
  118. package/src/agent/guide.md +9 -4
  119. package/src/agent/workflow.md +208 -58
  120. package/src/cli/dev.js +39 -7
  121. package/src/cli/fmt.js +113 -0
  122. package/src/cli/index.js +63 -30
  123. package/src/cli/scaffold.js +2 -2
  124. package/src/html.js +6 -1
  125. package/src/mcp/server.js +2415 -101
  126. package/src/mcp/validate-worker.js +34 -5
  127. package/src/runtime/ssr.js +4 -1
  128. package/src/server/index.js +22 -2
  129. package/src/spec/schema.js +5 -0
  130. package/src/testing/html.js +130 -4
  131. package/src/testing/testing.test.js +58 -0
  132. package/src/ui/banner.js +24 -9
  133. package/src/ui/brand-statement.js +58 -0
  134. package/src/ui/button.js +12 -1
  135. package/src/ui/card.js +20 -1
  136. package/src/ui/colophon.js +29 -0
  137. package/src/ui/contact-row.js +41 -0
  138. package/src/ui/cta.js +18 -4
  139. package/src/ui/decorate.js +55 -0
  140. package/src/ui/display-heading.js +44 -0
  141. package/src/ui/drop-cap.js +29 -0
  142. package/src/ui/editorial-hero.js +63 -0
  143. package/src/ui/entry-list.js +36 -0
  144. package/src/ui/feature.js +20 -3
  145. package/src/ui/footer.js +78 -9
  146. package/src/ui/gallery.js +56 -0
  147. package/src/ui/hero.js +68 -18
  148. package/src/ui/image-pair.js +72 -0
  149. package/src/ui/index.js +20 -0
  150. package/src/ui/input.js +1 -0
  151. package/src/ui/marquee.js +48 -0
  152. package/src/ui/nav.js +19 -9
  153. package/src/ui/photo-card.js +44 -0
  154. package/src/ui/product-card.js +65 -0
  155. package/src/ui/pullquote.js +14 -3
  156. package/src/ui/search.js +1 -0
  157. package/src/ui/section-label.js +38 -0
  158. package/src/ui/section.js +1 -1
  159. package/src/ui/service-card.js +47 -0
  160. package/src/ui/stat-grid.js +40 -0
  161. package/src/ui/stat.js +16 -2
  162. package/src/ui/testimonial.js +17 -6
  163. package/src/ui/textarea.js +1 -0
  164. package/src/ui/top-strip.js +47 -0
  165. package/src/ui/trust-list.js +46 -0
  166. package/src/ui/ui.test.js +35 -0
@@ -0,0 +1,422 @@
1
+ /*
2
+ * bookworms.css — BookWorms independent bookshop example
3
+ *
4
+ * Palette: warm off-white, deep ink, oxblood accent.
5
+ * Font: Fraunces (display headings, loaded via Google Fonts in meta.styles)
6
+ *
7
+ * Split into two logical sections:
8
+ * 1. Token overrides — hex values, palette definitions ([data-theme="light"])
9
+ * 2. Component styles — layout, typography, custom elements (var() only)
10
+ */
11
+
12
+ /* ==========================================================================
13
+ 1. Token overrides (hex values live here)
14
+ ========================================================================== */
15
+
16
+ /*
17
+ * Override --font and --font-display so --ui-font / --ui-font-display
18
+ * cascade to Fraunces throughout components and custom elements.
19
+ */
20
+ :root {
21
+ --font: 'Fraunces', Georgia, 'Times New Roman', serif;
22
+ --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
23
+ }
24
+
25
+ [data-theme="light"] {
26
+ --ui-bg: #f6f2ec;
27
+ --ui-surface: #ffffff;
28
+ --ui-surface-2: #efe9df;
29
+ --ui-border: #d8cfc1;
30
+ --ui-text: #1a1a1a;
31
+ --ui-muted: #5a5043;
32
+ --ui-accent: #6b2a2a;
33
+ --ui-accent-hover: #4f1d1d;
34
+ --ui-accent-dim: #f0e3e3;
35
+ --ui-accent-text: #ffffff;
36
+
37
+ /* BookWorms-specific token */
38
+ --bw-bg-alt: #efe9df;
39
+ }
40
+
41
+ /* ==========================================================================
42
+ 2. Component styles (var() only — no hex values below this line)
43
+ ========================================================================== */
44
+
45
+ body { line-height: 1.6; }
46
+
47
+ /* --------------------------------------------------------------------------
48
+ Shell (centred max-width wrapper)
49
+ -------------------------------------------------------------------------- */
50
+ .bw-shell {
51
+ max-width: 1180px;
52
+ margin: 0 auto;
53
+ padding: 0 var(--ui-space-6);
54
+ }
55
+
56
+ /* --------------------------------------------------------------------------
57
+ Hero
58
+ -------------------------------------------------------------------------- */
59
+ .bw-hero {
60
+ padding: var(--ui-space-20) 0 var(--ui-space-16);
61
+ border-bottom: 1px solid var(--ui-border);
62
+ overflow: hidden;
63
+ }
64
+
65
+ .bw-hero__inner {
66
+ display: grid;
67
+ grid-template-columns: 1fr 1fr;
68
+ gap: var(--ui-space-12);
69
+ align-items: center;
70
+ }
71
+
72
+ .bw-hero__content {
73
+ min-width: 0;
74
+ }
75
+
76
+ .bw-hero__image {
77
+ position: relative;
78
+ border-radius: var(--ui-radius-lg);
79
+ overflow: hidden;
80
+ aspect-ratio: 3 / 4;
81
+ }
82
+
83
+ .bw-hero__image img {
84
+ width: 100%;
85
+ height: 100%;
86
+ object-fit: cover;
87
+ display: block;
88
+ }
89
+
90
+ @media (max-width: 700px) {
91
+ .bw-hero__inner {
92
+ grid-template-columns: 1fr;
93
+ }
94
+ .bw-hero__image {
95
+ aspect-ratio: 4 / 3;
96
+ order: -1;
97
+ }
98
+ }
99
+
100
+ .bw-eyebrow {
101
+ font-size: var(--ui-text-xs);
102
+ letter-spacing: 0.18em;
103
+ text-transform: uppercase;
104
+ color: var(--ui-muted);
105
+ margin-bottom: var(--ui-space-6);
106
+ }
107
+
108
+ .bw-hero-title {
109
+ font-family: var(--ui-font-display);
110
+ font-size: clamp(2.5rem, 7vw, 5.5rem);
111
+ font-weight: 500;
112
+ line-height: 1.02;
113
+ letter-spacing: -0.025em;
114
+ color: var(--ui-text);
115
+ margin-bottom: var(--ui-space-8);
116
+ max-width: 18ch;
117
+ }
118
+
119
+ .bw-hero-lede {
120
+ font-size: var(--ui-text-xl);
121
+ line-height: 1.55;
122
+ color: var(--ui-muted);
123
+ max-width: 60ch;
124
+ margin-bottom: var(--ui-space-8);
125
+ }
126
+
127
+ /* --------------------------------------------------------------------------
128
+ Section template
129
+ -------------------------------------------------------------------------- */
130
+ .bw-section {
131
+ padding: var(--ui-space-16) 0;
132
+ border-bottom: 1px solid var(--ui-border);
133
+ }
134
+
135
+ .bw-section-label {
136
+ font-size: var(--ui-text-xs);
137
+ letter-spacing: 0.18em;
138
+ text-transform: uppercase;
139
+ color: var(--ui-muted);
140
+ margin-bottom: var(--ui-space-8);
141
+ }
142
+
143
+ .bw-section-title {
144
+ font-family: var(--ui-font-display);
145
+ font-size: clamp(1.75rem, 3.2vw, 2.5rem);
146
+ font-weight: 500;
147
+ line-height: 1.1;
148
+ letter-spacing: -0.02em;
149
+ color: var(--ui-text);
150
+ margin-bottom: var(--ui-space-10);
151
+ max-width: 24ch;
152
+ }
153
+
154
+ /* --------------------------------------------------------------------------
155
+ Staff picks grid
156
+ -------------------------------------------------------------------------- */
157
+ .bw-picks {
158
+ display: grid;
159
+ grid-template-columns: repeat(3, 1fr);
160
+ gap: var(--ui-space-10);
161
+ }
162
+
163
+ @media (max-width: 800px) {
164
+ .bw-picks {
165
+ grid-template-columns: 1fr;
166
+ gap: var(--ui-space-8);
167
+ }
168
+ }
169
+
170
+ .bw-pick-cover-wrap {
171
+ position: relative;
172
+ overflow: hidden;
173
+ margin-bottom: var(--ui-space-6);
174
+ box-shadow: 0 2px 12px rgb(0 0 0 / 0.08);
175
+ }
176
+
177
+ .bw-pick-cover {
178
+ display: block;
179
+ width: 100%;
180
+ height: auto;
181
+ aspect-ratio: 2 / 3;
182
+ object-fit: cover;
183
+ background: var(--bw-bg-alt);
184
+ }
185
+
186
+ .bw-pick-overlay {
187
+ position: absolute;
188
+ inset: 0;
189
+ display: flex;
190
+ flex-direction: column;
191
+ justify-content: flex-end;
192
+ padding: var(--ui-space-6);
193
+ background: linear-gradient(to top, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.2) 50%, transparent 100%);
194
+ }
195
+
196
+ /* First book only — text at top */
197
+ .bw-picks article:first-child .bw-pick-overlay {
198
+ justify-content: flex-start;
199
+ background: linear-gradient(to bottom, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.2) 50%, transparent 100%);
200
+ }
201
+
202
+ .bw-picks article:first-child .bw-pick-overlay-title {
203
+ font-family: Arial, sans-serif;
204
+ font-weight: 700;
205
+ text-transform: uppercase;
206
+ }
207
+
208
+ /* Second book — solid semi-transparent block behind text */
209
+ .bw-picks article:nth-child(2) .bw-pick-overlay {
210
+ inset: auto 0 0 0;
211
+ background: rgba(0, 0, 0, 0.55);
212
+ padding: var(--ui-space-5) var(--ui-space-6);
213
+ }
214
+
215
+ /* Third book — Arial, no italic on author */
216
+ .bw-picks article:nth-child(3) .bw-pick-overlay-title {
217
+ font-family: Arial, sans-serif;
218
+ font-size: 3.75rem;
219
+ }
220
+
221
+ .bw-picks article:nth-child(3) .bw-pick-overlay-author {
222
+ font-family: Arial, sans-serif;
223
+ font-style: normal;
224
+ }
225
+
226
+ .bw-pick-overlay-tag {
227
+ font-size: var(--ui-text-xs);
228
+ letter-spacing: 0.14em;
229
+ text-transform: uppercase;
230
+ color: rgba(255,255,255,0.7);
231
+ margin-bottom: var(--ui-space-2);
232
+ }
233
+
234
+ .bw-pick-overlay-title {
235
+ font-family: var(--ui-font);
236
+ font-size: var(--ui-text-2xl);
237
+ font-weight: 600;
238
+ line-height: 1.15;
239
+ color: #fff;
240
+ margin-bottom: var(--ui-space-1);
241
+ }
242
+
243
+ .bw-pick-overlay-author {
244
+ font-style: italic;
245
+ font-family: var(--ui-font);
246
+ font-size: var(--ui-text-sm);
247
+ color: rgba(255,255,255,0.7);
248
+ }
249
+
250
+ .bw-pick-meta {
251
+ font-size: var(--ui-text-xs);
252
+ letter-spacing: 0.14em;
253
+ text-transform: uppercase;
254
+ color: var(--ui-accent);
255
+ margin-bottom: var(--ui-space-3);
256
+ }
257
+
258
+ .bw-pick-title {
259
+ font-family: var(--ui-font-display);
260
+ font-size: var(--ui-text-2xl);
261
+ font-weight: 500;
262
+ line-height: 1.2;
263
+ margin-bottom: var(--ui-space-2);
264
+ color: var(--ui-text);
265
+ }
266
+
267
+ .bw-pick-author {
268
+ font-style: italic;
269
+ color: var(--ui-muted);
270
+ margin-bottom: var(--ui-space-4);
271
+ }
272
+
273
+ .bw-pick-note {
274
+ font-size: var(--ui-text-base);
275
+ line-height: 1.6;
276
+ color: var(--ui-text);
277
+ }
278
+
279
+ /* --------------------------------------------------------------------------
280
+ Pull-quote
281
+ -------------------------------------------------------------------------- */
282
+ .bw-pull {
283
+ padding: var(--ui-space-20) 0;
284
+ text-align: center;
285
+ border-bottom: 1px solid var(--ui-border);
286
+ }
287
+
288
+ .bw-pull-quote {
289
+ font-family: var(--ui-font-display);
290
+ font-size: clamp(1.75rem, 4vw, 2.75rem);
291
+ font-weight: 400;
292
+ font-style: italic;
293
+ line-height: 1.25;
294
+ letter-spacing: -0.015em;
295
+ color: var(--ui-text);
296
+ max-width: 32ch;
297
+ margin: 0 auto var(--ui-space-6);
298
+ }
299
+
300
+ .bw-pull-cite {
301
+ font-size: var(--ui-text-sm);
302
+ letter-spacing: 0.14em;
303
+ text-transform: uppercase;
304
+ color: var(--ui-muted);
305
+ }
306
+
307
+ /* --------------------------------------------------------------------------
308
+ Feature grid (what we do)
309
+ -------------------------------------------------------------------------- */
310
+ .bw-features {
311
+ display: grid;
312
+ grid-template-columns: 1fr 1fr;
313
+ gap: var(--ui-space-12) var(--ui-space-16);
314
+ }
315
+
316
+ @media (max-width: 800px) {
317
+ .bw-features {
318
+ grid-template-columns: 1fr;
319
+ gap: var(--ui-space-10);
320
+ }
321
+ }
322
+
323
+ .bw-feature-title {
324
+ font-family: var(--ui-font-display);
325
+ font-size: var(--ui-text-xl);
326
+ font-weight: 500;
327
+ margin-bottom: var(--ui-space-2);
328
+ color: var(--ui-text);
329
+ }
330
+
331
+ .bw-feature-body {
332
+ color: var(--ui-muted);
333
+ line-height: 1.6;
334
+ }
335
+
336
+ /* --------------------------------------------------------------------------
337
+ Events list
338
+ -------------------------------------------------------------------------- */
339
+ .bw-events {
340
+ display: flex;
341
+ flex-direction: column;
342
+ }
343
+
344
+ .bw-event {
345
+ display: grid;
346
+ grid-template-columns: 140px 1fr auto;
347
+ align-items: baseline;
348
+ gap: var(--ui-space-8);
349
+ padding: var(--ui-space-6) 0;
350
+ border-top: 1px solid var(--ui-border);
351
+ }
352
+
353
+ .bw-event:last-child {
354
+ border-bottom: 1px solid var(--ui-border);
355
+ }
356
+
357
+ @media (max-width: 700px) {
358
+ .bw-event {
359
+ grid-template-columns: 1fr;
360
+ gap: var(--ui-space-2);
361
+ }
362
+ }
363
+
364
+ .bw-event-date {
365
+ font-family: var(--ui-font-display);
366
+ font-size: var(--ui-text-lg);
367
+ color: var(--ui-accent);
368
+ letter-spacing: 0.02em;
369
+ }
370
+
371
+ .bw-event-title {
372
+ font-family: var(--ui-font-display);
373
+ font-size: var(--ui-text-xl);
374
+ font-weight: 500;
375
+ color: var(--ui-text);
376
+ }
377
+
378
+ .bw-event-host {
379
+ color: var(--ui-muted);
380
+ font-style: italic;
381
+ }
382
+
383
+ /* --------------------------------------------------------------------------
384
+ CTA section
385
+ -------------------------------------------------------------------------- */
386
+ .bw-cta {
387
+ padding: var(--ui-space-24) 0;
388
+ text-align: center;
389
+ }
390
+
391
+ .bw-cta-title {
392
+ font-family: var(--ui-font-display);
393
+ font-size: clamp(2rem, 5vw, 3.5rem);
394
+ font-weight: 500;
395
+ line-height: 1.05;
396
+ letter-spacing: -0.02em;
397
+ margin-bottom: var(--ui-space-6);
398
+ color: var(--ui-text);
399
+ max-width: 20ch;
400
+ margin-left: auto;
401
+ margin-right: auto;
402
+ }
403
+
404
+ .bw-cta-sub {
405
+ color: var(--ui-muted);
406
+ font-size: var(--ui-text-lg);
407
+ margin-bottom: var(--ui-space-8);
408
+ max-width: 50ch;
409
+ margin-left: auto;
410
+ margin-right: auto;
411
+ }
412
+
413
+ .bw-cta-actions {
414
+ display: flex;
415
+ gap: var(--ui-space-4);
416
+ justify-content: center;
417
+ flex-wrap: wrap;
418
+ }
419
+
420
+ .bw-cta-actions--start {
421
+ justify-content: flex-start;
422
+ }