@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,288 @@
1
+ # Pulse Design Gallery — Templates & Component Combinations
2
+
3
+ A curated catalogue of ready-to-use design patterns. Each entry names the live template (or component combination), its distinguishing visual character, which vibe preset to set, which CSS theme to load, and the key components that make it work. Use this alongside `pulse://guide/design-references` — gallery = what it looks like + how to build it; design-references = aesthetic direction + creative strategy.
4
+
5
+ ---
6
+
7
+ ## Templates
8
+
9
+ ### Local Business Landing Page
10
+ **Route:** `/templates/local-business`
11
+ **Vibe:** `warm` **Theme:** `light` **CSS:** `lumio.css`
12
+
13
+ Warm cream background, hand-crafted feel. Photo-forward hero with a split layout (text left, dog/product image right). Earthy greens and amber for CTAs. Services grid of 6 cards with price footers. Two-column about section with credentials checklist. Three-column testimonials. Contact section with location/hours sidebar and inline booking form. Stat strip showing social proof numbers.
14
+
15
+ **Key components:** `hero({ layout:'split' })`, `section`, `container`, `grid`, `card` (with `footer`), `stat`, `testimonial`, `cta`, `badge`
16
+
17
+ **Distinguishing moves:**
18
+ - Gradient hero `linear-gradient(135deg, #fdf6ee, #fdebd0)` with `color:#3d2b1e`
19
+ - Nav with `background: rgba(255,250,245,0.92)` and matching text colour
20
+ - Cards with price footer: `<div class="u-flex u-items-center u-justify-between"><span>From</span><strong>£35</strong></div>`
21
+ - Credentials list: icon + span with `iconCheckCircle`
22
+ - Booking form inlined inside a `card`
23
+
24
+ **Best for:** Dog groomer, physio, florist, bakery, personal trainer, hair salon, local café, tradesperson
25
+
26
+ ---
27
+
28
+ ### Portfolio / Creative Agency
29
+ **Route:** `/templates/portfolio`
30
+ **Vibe:** `minimal` **Theme:** `dark` **CSS:** *(none extra — dark theme built-in)*
31
+
32
+ Dark, editorial, high-contrast. Works grid with cover images (fluid fill via `flush:true`), category badge overlays, and title links. Minimal nav without action button. About section in a narrow `sm` container for essay-like reading width. Simple plain contact form. Monochromatic palette with accent for hover states.
33
+
34
+ **Key components:** `hero({ layout:'centered' })`, `section`, `container({ size:'sm' })`, `grid({ cols:3 })`, `card({ flush:true })`, `badge({ variant:'soft' })`
35
+
36
+ **Distinguishing moves:**
37
+ - `card({ flush:true })` + `<img>` at top of content, padded inner div below — creates image card without a native image slot
38
+ - `aspect-ratio:3/2` on images for consistent crop
39
+ - `container({ size:'sm' })` for about/contact text — keeps it from stretching wide
40
+ - No eyebrows, no badge decorations in hero — just clean large type
41
+
42
+ **Best for:** Designer, photographer, illustrator, studio, agency, architect, film-maker
43
+
44
+ ---
45
+
46
+ ### Event / Conference
47
+ **Route:** `/templates/event`
48
+ **Vibe:** `bold` **Theme:** `dark` **CSS:** *(none extra — dark theme built-in)*
49
+
50
+ Dark navy with violet/purple gradient CTAs. Centred hero with countdown-style stats strip. Sponsor logo marquee. Speaker portrait grid (4 columns, `flush:true` square images). Schedule as an accordion (3 day items, each with time/stage timetable). Venue section with two-column layout (map + details). Ticket pricing highlight.
51
+
52
+ **Key components:** `hero`, `section`, `container`, `grid({ cols:4 })`, `card({ flush:true })`, `accordion`, `marquee`, `badge`, `stat`, `cta`
53
+
54
+ **Distinguishing moves:**
55
+ - Speaker cards: `aspect-ratio:1/1` square portrait images + name/role/quote below
56
+ - Accordion items: `{ question: 'Day 1 — ...', answer: '<div>...timetable rows...</div>' }`
57
+ - Marquee for sponsor logos: `marquee({ items: [...], gap:'xl', speed:'slow' })`
58
+ - Stats strip: `section({ variant:'alt', padding:'sm' })` + `grid({ cols:4 })`
59
+
60
+ **Best for:** Conference, hackathon, festival, product launch, awards ceremony, summit
61
+
62
+ ---
63
+
64
+ ### Editorial / Magazine
65
+ **Route:** `/templates/editorial`
66
+ **Vibe:** `editorial` **Theme:** `dark` **CSS:** *(none extra — dark theme built-in)*
67
+
68
+ Dark with serif headline typography. Featured article hero with byline, read-time badge, and category tag. Pullquote section with large italic text and cite attribution. Six-card article grid with `flush:true` cards (16:9 cover images, eyebrow category, deck text, author, date, read-time). Newsletter CTA in a `spotlight` section variant.
69
+
70
+ **Key components:** `hero`, `section({ variant:'spotlight' })`, `pullquote`, `container`, `grid({ cols:3 })`, `card({ flush:true })`, `badge`, `cta`
71
+
72
+ **Distinguishing moves:**
73
+ - Article cards: `card({ flush:true })` + `<img style="aspect-ratio:16/9">` + padded inner div with category badge, title link, deck, byline row
74
+ - `pullquote({ quote:'...', cite:'Name, Publication' })` — note `cite` not `author`
75
+ - Featured hero uses `layout:'centered'` with small eyebrow badge and read-time
76
+ - `section({ variant:'spotlight' })` for the newsletter signup gives a glowing background effect
77
+
78
+ **Best for:** Online magazine, news publication, blog, newsletter landing page, media brand
79
+
80
+ ---
81
+
82
+ ### Mobile App Landing Page
83
+ **Route:** `/templates/mobile-app`
84
+ **Vibe:** `bold` or `minimal` **Theme:** `dark` **CSS:** *(dark theme built-in)*
85
+
86
+ Hero with phone-frame mockup, feature grid, pricing section, testimonials, and App Store badges. The centrepiece is a `phoneFrame` component wrapping a screenshot or animated mockup.
87
+
88
+ **Key components:** `hero`, `phoneFrame`, `feature`, `pricing`, `testimonial`, `appBadge`, `cta`
89
+
90
+ **Best for:** iOS/Android app, SaaS with mobile client, consumer product launch
91
+
92
+ ---
93
+
94
+ ### Blog Post
95
+ **Route:** `/templates/blog-post`
96
+ **Vibe:** `editorial` or `minimal` **Theme:** light or dark **CSS:** `/pulse-ui.css`
97
+
98
+ Long-form article layout with `prose` component for markdown rendering, breadcrumbs, reading time, featured image, and a related-posts footer.
99
+
100
+ **Key components:** `prose`, `heading`, `breadcrumbs`, `badge`, `container({ size:'sm' })`
101
+
102
+ **Best for:** Article, tutorial, case study, documentation page, essay
103
+
104
+ ---
105
+
106
+ ## Component Combinations by Use Case
107
+
108
+ ### Image Card (Card with Cover Photo)
109
+ Card doesn't have a native image slot — use `flush:true` and put the image inside `content`:
110
+
111
+ ```js
112
+ card({
113
+ flush: true,
114
+ content: `
115
+ <img src="${url}" alt="${alt}" class="u-w-full" style="aspect-ratio:3/2;object-fit:cover;">
116
+ <div class="u-p-5">
117
+ <h3 class="u-font-semibold">${title}</h3>
118
+ <p class="u-text-sm u-text-muted">${body}</p>
119
+ </div>
120
+ `,
121
+ })
122
+ ```
123
+
124
+ ### Article Card (16:9 image + category + byline)
125
+ ```js
126
+ card({
127
+ flush: true,
128
+ content: `
129
+ <img src="${img}" alt="${title}" class="u-w-full" style="aspect-ratio:16/9;object-fit:cover;">
130
+ <div class="u-p-5">
131
+ <div class="u-mb-2">${badge({ label: category, variant:'soft', size:'sm' })}</div>
132
+ <h3 class="u-font-semibold u-leading-snug">
133
+ <a href="${href}" class="u-text-inherit">${title}</a>
134
+ </h3>
135
+ <p class="u-text-sm u-text-muted u-mt-2">${deck}</p>
136
+ <div class="u-flex u-gap-3 u-mt-3">
137
+ <span class="u-text-xs u-text-muted">${author}</span>
138
+ <span class="u-text-xs u-text-muted">·</span>
139
+ <span class="u-text-xs u-text-muted">${date}</span>
140
+ </div>
141
+ </div>
142
+ `,
143
+ })
144
+ ```
145
+
146
+ ### Credentials List (icon + text rows)
147
+ ```js
148
+ const items = ['City & Guilds Level 3 qualified', 'Fear-free certified', 'Insured and first-aid trained']
149
+ items.map(item => `
150
+ <div class="u-flex u-items-center u-gap-2">
151
+ ${iconCheckCircle({ size: 18 })}
152
+ <span>${item}</span>
153
+ </div>
154
+ `).join('')
155
+ ```
156
+
157
+ ### Stat Strip
158
+ ```js
159
+ section({
160
+ variant: 'alt',
161
+ padding: 'sm',
162
+ content: container({ content: grid({
163
+ cols: 4,
164
+ gap: 'lg',
165
+ content: [
166
+ stat({ value: '2,400+', label: 'Happy customers' }),
167
+ stat({ value: '4.9', label: 'Star rating' }),
168
+ stat({ value: '6 years', label: 'In business' }),
169
+ stat({ value: 'Same day', label: 'Bookings' }),
170
+ ].join(''),
171
+ }) }),
172
+ })
173
+ ```
174
+
175
+ ### Sponsor Marquee
176
+ ```js
177
+ marquee({
178
+ items: ['Acme Corp', 'Globex', 'Initech', 'Umbrella', 'Hooli'].map(
179
+ name => `<span class="u-font-semibold u-text-lg u-opacity-60">${name}</span>`
180
+ ),
181
+ speed: 'slow',
182
+ gap: 'xl',
183
+ })
184
+ ```
185
+
186
+ ### Section with Header (Eyebrow + Title + Subtitle)
187
+ ```js
188
+ section({
189
+ id: 'services',
190
+ eyebrow: 'Our Services',
191
+ title: 'Everything You Need',
192
+ subtitle: 'A supporting line with a bit more detail.',
193
+ align: 'center',
194
+ content: `...grid or cards...`,
195
+ })
196
+ ```
197
+ Note: when using the built-in `eyebrow`/`title`/`subtitle` on `section`, you don't need to put them inside the `content`. They are automatically rendered above `content` as a header block.
198
+
199
+ ### Two-Column Section (Text + Image)
200
+ ```js
201
+ section({
202
+ id: 'about',
203
+ variant: 'alt',
204
+ content: container({ content: grid({
205
+ cols: 2,
206
+ gap: 'xl',
207
+ content: `
208
+ <div>
209
+ <img src="${img}" alt="..." class="u-w-full u-rounded-xl" style="object-fit:cover;height:360px;">
210
+ </div>
211
+ <div class="u-flex u-flex-col u-justify-center u-gap-5">
212
+ ${heading({ level: 2, text: 'About Us' })}
213
+ <p class="u-text-muted u-leading-relaxed">...</p>
214
+ </div>
215
+ `,
216
+ }) }),
217
+ })
218
+ ```
219
+
220
+ ### Booking / Contact Form Inside a Card
221
+ ```js
222
+ card({
223
+ title: 'Book an Appointment',
224
+ content: `
225
+ <p class="u-text-muted u-text-sm u-mb-4">Fill in the form and we'll confirm within a few hours.</p>
226
+ <form class="u-flex u-flex-col u-gap-3" data-action="submit">
227
+ <div class="u-flex u-flex-col u-gap-1">
228
+ <label class="u-text-sm u-font-medium" for="name">Your name</label>
229
+ <input id="name" name="name" type="text" class="u-input" required>
230
+ </div>
231
+ ${button({ label: 'Send Enquiry', type: 'submit', variant: 'primary', fullWidth: true })}
232
+ </form>
233
+ `,
234
+ padding: 'lg',
235
+ })
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Prop Names — Quick Reference (Critical)
241
+
242
+ The most common mistakes when writing templates. These will silently produce empty output:
243
+
244
+ | Component | ❌ Wrong prop | ✅ Correct prop |
245
+ |---|---|---|
246
+ | `section` | `children:` | `content:` |
247
+ | `container` | `children:` | `content:` |
248
+ | `grid` | `children:` | `content:` |
249
+ | `card` | `body:` | `content:` |
250
+ | `card` | `image:` *(unsupported)* | Put `<img>` inside `content:` |
251
+ | `card` | `href:` *(unsupported)* | Wrap title in `<a>` inside `content:` |
252
+ | `testimonial` | `author:` | `name:` |
253
+ | `pullquote` | `author:` | `cite:` |
254
+ | `accordion` items | `title:` | `question:` |
255
+ | `accordion` items | `content:` | `answer:` |
256
+
257
+ ---
258
+
259
+ ## CSS Themes Available
260
+
261
+ | File | Character | Pairs with vibe |
262
+ |---|---|---|
263
+ | *(none — dark default)* | Deep dark, cool greys, blue-ish surface | `minimal`, `bold`, `editorial` |
264
+ | `/themes/lumio.css` | Warm cream whites, earthy mid-tones | `warm`, `paper` |
265
+ | `/themes/neon.css` | Electric neon on very dark surface | `neon`, `brutalist` |
266
+ | `/themes/retro.css` | Muted vintage pastels, aged look | `retro` |
267
+ | `/themes/corporate.css` | Clean neutral greys, professional blue | `corporate` |
268
+
269
+ Load via `meta.styles: ['/pulse-ui.css', '/themes/lumio.css']`.
270
+
271
+ ---
272
+
273
+ ## Vibes (data-vibe attribute)
274
+
275
+ Set via `meta: { vibe: 'warm' }`. Controls radius, font weight, letter-spacing, and some colour nudges.
276
+
277
+ | Vibe | Radius | Feel |
278
+ |---|---|---|
279
+ | `warm` | rounded | Approachable, organic, friendly |
280
+ | `editorial` | square | Serious, print-like, editorial |
281
+ | `minimal` | slight | Clean, airy, Swiss-influenced |
282
+ | `bold` | medium | Confident, high-contrast |
283
+ | `playful` | very rounded | Fun, colourful, consumer |
284
+ | `brutalist` | none | Raw, stark, anti-design |
285
+ | `retro` | pill/soft | Nostalgic, 70s–90s influenced |
286
+ | `corporate` | small | Professional, trustworthy |
287
+ | `neon` | medium | Electric, nightlife, gaming |
288
+ | `paper` | slight | Textured, craft, tactile |
@@ -0,0 +1,172 @@
1
+ # Pulse Design References — Aesthetic Vocabulary
2
+
3
+ Use this guide to build **distinctive** pages rather than defaulting to the standard SaaS landing page. Match the user's product to a design direction, then apply the component combinations, vibe, and token hints below.
4
+
5
+ When you choose a design direction, tell the user which one you're using and why. The whole point is conscious choice.
6
+
7
+ ---
8
+
9
+ ## Design Directions
10
+
11
+ ### 1. Clean SaaS / Productivity
12
+ **Feels like:** Linear, Vercel, Notion, Raycast
13
+ **vibe:** `minimal` or `bold`
14
+ **Geometry:** tight radius (2–6px), mono grids, generous whitespace
15
+ **Typography:** geometric sans, tight tracking on headings, strong size contrast
16
+ **Palette pattern:** near-black bg + single accent (indigo / blue / violet)
17
+ **Signature moves:** bento grid, floating nav on scroll, stat bar, code window
18
+ **Components to lead with:** `hero(layout:'centered')`, `grid`, `stat`, `codeWindow`, `feature`
19
+
20
+ ---
21
+
22
+ ### 2. Warm Local Business
23
+ **Feels like:** a bakery, dog groomer, physiotherapy clinic, florist
24
+ **vibe:** `warm`
25
+ **Geometry:** large radius (14–20px), soft card shadows, rounded buttons
26
+ **Typography:** humanist sans (inter, nunito), comfortable line-height
27
+ **Palette pattern:** earthy warm — terracotta / sage / cream / warm off-white
28
+ **Signature moves:** real photo hero, services grid with icons, "meet the team", hours + map, handwritten accent (SVG underline via decorate)
29
+ **Components to lead with:** `hero(layout:'split')`, `photoCard`, `gallery`, `section(variant:'alt')`, `footer` with address
30
+
31
+ ---
32
+
33
+ ### 3. Editorial / Publication
34
+ **Feels like:** The Verge, Substack, MIT Technology Review, a literary magazine
35
+ **vibe:** `editorial`
36
+ **Geometry:** zero radius, column rules, tight grids
37
+ **Typography:** serif display (Georgia / Playfair Display), strong weight contrast, generous body leading
38
+ **Palette pattern:** black + white + single ink colour (brick red / forest green)
39
+ **Signature moves:** article grid with issue number, pullquote, prose with drop cap, author byline as hero subtitle
40
+ **Components to lead with:** `prose`, `pullquote`, `hero(size:'sm')`, `grid`, `section` with column text
41
+
42
+ > **Font note:** `vibe: 'editorial'` sets `--ui-font-display` to Georgia — this applies to hero headings and display text. Body copy and nav stay sans-serif (by design). For the full editorial look with Playfair Display or a similar web serif, load the font via `meta.styles` and set `--font-display` in your theme CSS:
43
+ > ```css
44
+ > [data-theme="light"] { --font-display: 'Playfair Display', Georgia, serif; }
45
+ > ```
46
+ > Without a loaded web font, the fallback Georgia is still visibly different from sans on hero headings.
47
+
48
+ ---
49
+
50
+ ### 4. Bold Agency / Creative Studio
51
+ **Feels like:** Awwwards winner, design agency, film production studio
52
+ **vibe:** `bold`
53
+ **Geometry:** medium radius (6–10px), oversized type, dramatic section transitions
54
+ **Typography:** heavy condensed sans (Black weight), massive heading, strong contrast
55
+ **Palette pattern:** black bg + vivid single colour (yellow / red / lime) for accents
56
+ **Signature moves:** work case-study grid, client logo marquee, big number stats, diagonal section, full-bleed hero
57
+ **Components to lead with:** `hero(layout:'poster')`, `marquee`, `gallery(layout:'masonry')`, `section(variant:'diagonal')`, `stat`
58
+
59
+ ---
60
+
61
+ ### 5. Playful / Consumer App
62
+ **Feels like:** Duolingo, Headspace, Loom, Figma landing page, pop-art toy brand
63
+ **vibe:** `playful`
64
+ **Geometry:** very rounded (18–24px), friendly icons, colourful
65
+ **Typography:** rounded or friendly sans, loose spacing, emoji-friendly
66
+ **Palette pattern:** bright bg (coral / mint / lavender) + dark text
67
+ **Signature moves (use these, not 3-col feature grids):**
68
+ - **Full-colour section blocks** — each section has its own bg colour (yellow stats strip, cyan testimonials, hot-pink CTA). Palette is structure, not accent.
69
+ - **Oversized hero element** — the product's key visual (a game board, an illustration, an icon) fills most of the hero viewport. `phoneFrame` is one option, not the default.
70
+ - **Marquee strip** — giant repeated glyphs, emoji, or product icons scrolling across the page between sections (`marquee` component)
71
+ - **Tilted `photoCard`s** — testimonial or feature cards at ±2–4° with `photoCard` or CSS `transform: rotate()`
72
+ - **Memphis-style geometric shapes** between sections — use `decorate(pattern:'circles')` or CSS background shapes
73
+ - **Social proof as ticker** — a `marquee` of short quotes or star ratings, not a 3-col grid
74
+
75
+ **Components to lead with:** `hero`, `appBadge`, `marquee`, `photoCard`, `section` with flat-colour backgrounds, `stat`
76
+ **What NOT to do:** 3-column `feature()` grids, centred hero + three columns, phone mockup when the product is a game/board/visual thing
77
+
78
+ ---
79
+
80
+ ### 6. Minimal Portfolio
81
+ **Feels like:** a photographer, architect, developer personal site, typographer
82
+ **vibe:** `minimal`
83
+ **Geometry:** ultra-low radius (0–3px), strong whitespace, grid discipline
84
+ **Typography:** light weight body, all-caps labels, large work titles
85
+ **Palette pattern:** white or near-black + single neutral accent
86
+ **Signature moves:** work grid (no card chrome), simple text navigation, contact via plain `<a href="mailto:...">`, no footer clutter
87
+ **Components to lead with:** `gallery(layout:'grid')`, `grid`, `container(size:'sm')`, `heading`, minimal `footer`
88
+
89
+ ---
90
+
91
+ ### 7. Event / Conference
92
+ **Feels like:** a festival poster, tech conference site, concert landing page
93
+ **vibe:** `bold` or `neon`
94
+ **Geometry:** strong, decisive — either rectangular or very rounded
95
+ **Typography:** poster-style headline, tight date/location details
96
+ **Palette pattern:** dark bg + 2 vivid accent colours; optional gradient hero
97
+ **Signature moves:** date + venue stat bar, speaker grid, schedule accordion, countdown timer (client-only JS), ticket CTA
98
+ **Components to lead with:** `hero` with gradient `background`, `stat`, `grid` for speakers, `accordion` for schedule, `cta` with bold button
99
+
100
+ ---
101
+
102
+ ### 8. Retro / Craft / Nostalgia
103
+ **Feels like:** a craft brewery, vinyl record shop, heritage brand, farmers market
104
+ **vibe:** `retro`
105
+ **Geometry:** medium radius (8px), textured backgrounds, thick borders
106
+ **Typography:** slab serif (Rockwell / Courier), mixed cases, stamp-style labels
107
+ **Palette pattern:** amber / cream / dark brown / forest green
108
+ **Signature moves:** `decorate(pattern:'dots')` background, thick divider lines, badge-style eyebrows, stacked text hierarchy
109
+ **Components to lead with:** `hero(layout:'stacked')`, `section(variant:'alt')`, `decorate`, `badge`, `card`
110
+
111
+ ---
112
+
113
+ ### 9. Corporate / B2B / Enterprise
114
+ **Feels like:** Salesforce, Workday, a consultancy, an insurance company
115
+ **vibe:** `corporate`
116
+ **Geometry:** conservative radius (4px), structured layout, safe
117
+ **Typography:** system-ui or clean sans, no display serif, professional
118
+ **Palette pattern:** navy / corporate blue + white + grey
119
+ **Signature moves:** trust logos, security/compliance badges, case study cards, feature table, partner logos
120
+ **Components to lead with:** `hero(layout:'centered')`, `grid`, `feature`, `stat`, `testimonial` with company name
121
+
122
+ ---
123
+
124
+ ### 10. Brutalist / Art / Counter-culture
125
+ **Feels like:** a Berlin gallery, fashion brand, experimental portfolio, zine
126
+ **vibe:** `brutalist`
127
+ **Geometry:** zero radius everywhere, raw edges, intentional "broken" look
128
+ **Typography:** impact / black weight / giant, sometimes rotated via CSS transform
129
+ **Palette pattern:** black + white + ONE violent accent (red / lime / hot pink)
130
+ **Signature moves:** asymmetric grid, oversized section numbers, text-only nav, full bleed images bleeding into sections, no visual fluff
131
+ **Components to lead with:** raw `section`, `container`, `heading`, `gallery` (no rounded), `decorate(pattern:'noise')`
132
+
133
+ ---
134
+
135
+ ### 11. Dark Tech / Gaming / Crypto
136
+ **Feels like:** a cyberpunk game, crypto protocol, AI startup, hardware brand
137
+ **vibe:** `neon`
138
+ **Geometry:** sharp (2–4px), glowing borders, glassmorphism
139
+ **Typography:** monospace or geometric sans, colour gradient on headings
140
+ **Palette pattern:** very dark bg (#0a0a0f) + neon accent (cyan / green / magenta)
141
+ **Signature moves:** blurred glow backgrounds, animated grid lines (CSS), terminal code window, token/protocol stats
142
+ **Components to lead with:** `hero` with gradient, `codeWindow`, `stat`, `section(variant:'spotlight')`, `grid`
143
+
144
+ ---
145
+
146
+ ### 12. Warm Editorial / Journal
147
+ **Feels like:** a personal newsletter, book club, reading list, thoughtful blog
148
+ **vibe:** `paper`
149
+ **Geometry:** organic radius (10px), soft card shadows
150
+ **Typography:** serif body (Georgia), comfortable 1.8 line-height, warm type colour
151
+ **Palette pattern:** warm off-white bg + dark sepia text + muted link colour
152
+ **Signature moves:** `prose` + `pullquote`, author avatar + bio card, reading time badge, related articles footer
153
+ **Components to lead with:** `prose`, `pullquote`, `avatar`, `card`, `container(size:'sm')`
154
+
155
+ ---
156
+
157
+ ## How to use this guide
158
+
159
+ 1. **At intake** — when the user describes their product, map it to one of the directions above.
160
+ 2. **State the choice** — tell the user "I'm using the Warm Local Business direction — rounded cards, earthy palette, photo-forward hero."
161
+ 3. **Apply the vibe** — set `meta.vibe` to the recommended value.
162
+ 4. **Lead with the right components** — the "Components to lead with" list is ordered: use the first one for the hero, the rest for the body sections.
163
+ 5. **Match the palette pattern** — don't apply a corporate navy palette to a playful app. If the user gave you brand colours, note whether they are warm/cool/saturated before writing CSS.
164
+ 6. **Pick a template if one exists** — design direction + template = fastest correct result. See `pulse://guide/templates`.
165
+
166
+ ## Cross-cutting rules
167
+
168
+ - Never default to centered hero + feature grid + pricing + FAQ without checking if a different layout suits the product better.
169
+ - The `marquee` component is great for trust logos, client names, and tech stack badges — use it on agency/corporate/SaaS directions.
170
+ - The `photoCard` and `gallery` components are underused — deploy them whenever the product has visual appeal (food, fitness, places, products).
171
+ - `decorate` backgrounds (dots, grid, noise, lines) add texture without images — especially useful on retro, brutalist, and paper directions.
172
+ - `section(variant:'diagonal')` → bold / agency; `section(variant:'paper')` → warm / retro; `section(variant:'spotlight')` → dark tech / neon.