@invisibleloop/pulse 0.20.5 → 0.20.6
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.
- package/.claude/pulse-checklist.md +1 -2
- package/CLAUDE.md +1 -2
- package/docs/.claude/pulse-checklist.md +1 -2
- package/docs/public/coutumes.css +21 -44
- package/docs/public/docs.css +67 -0
- package/docs/public/pulse-ui.css +8 -1037
- package/docs/public/retrowheels.css +23 -0
- package/docs/public/shop.css +35 -1
- package/docs/public/sparkys.css +56 -23
- package/docs/server.js +0 -11
- package/docs/src/lib/nav.js +0 -11
- package/docs/src/pages/components/charts.js +2 -1
- package/docs/src/pages/components/grid.js +9 -5
- package/docs/src/pages/components.js +0 -4
- package/docs/src/pages/home.js +16 -1
- package/docs/src/pages/how-it-works.js +20 -14
- package/docs/src/pages/templates/coutumes.js +83 -72
- package/docs/src/pages/templates/mobile-app.js +36 -9
- package/docs/src/pages/templates/retrowheels.js +17 -4
- package/docs/src/pages/templates/shop.js +21 -10
- package/docs/src/pages/templates/sparkys.js +35 -20
- package/examples/.claude/pulse-checklist.md +1 -2
- package/examples/examples.test.js +4 -4
- package/examples/pricing.js +21 -3
- package/examples/public/pulse-ui.css +8 -1037
- package/examples/retrowheels.css +23 -0
- package/examples/retrowheels.js +17 -4
- package/package.json +5 -1
- package/public/.pulse-ui-version +1 -1
- package/public/pulse-ui.css +8 -1037
- package/src/agent/checklist.md +1 -2
- package/src/agent/guide-components.md +43 -67
- package/src/agent/guide-design-gallery.md +14 -14
- package/src/agent/guide-design-references.md +21 -21
- package/src/agent/guide-styles.md +2 -2
- package/src/agent/guide-templates.md +6 -6
- package/src/agent/identity.md +1 -1
- package/src/agent/workflow.md +1 -2
- package/src/mcp/server.js +31 -24
- package/src/ui/index.js +0 -27
- package/src/ui/ui.test.js +0 -137
- package/types/charts.d.ts +61 -0
- package/types/ui.d.ts +1 -129
- package/docs/src/pages/components/banner.js +0 -44
- package/docs/src/pages/components/carousel.js +0 -71
- package/docs/src/pages/components/code-window.js +0 -56
- package/docs/src/pages/components/decorate.js +0 -74
- package/docs/src/pages/components/gallery.js +0 -102
- package/docs/src/pages/components/list.js +0 -111
- package/docs/src/pages/components/marquee.js +0 -76
- package/docs/src/pages/components/photo-card.js +0 -74
- package/docs/src/pages/components/pricing.js +0 -67
- package/docs/src/pages/components/testimonial.js +0 -48
- package/docs/src/pages/components/timeline.js +0 -226
- package/src/ui/banner.js +0 -41
- package/src/ui/brand-statement.js +0 -58
- package/src/ui/carousel.js +0 -59
- package/src/ui/code-window.js +0 -39
- package/src/ui/colophon.js +0 -29
- package/src/ui/contact-row.js +0 -41
- package/src/ui/decorate.js +0 -55
- package/src/ui/display-heading.js +0 -44
- package/src/ui/drop-cap.js +0 -29
- package/src/ui/editorial-hero.js +0 -63
- package/src/ui/entry-list.js +0 -36
- package/src/ui/gallery.js +0 -60
- package/src/ui/image-pair.js +0 -72
- package/src/ui/list.js +0 -36
- package/src/ui/marquee.js +0 -48
- package/src/ui/photo-card.js +0 -44
- package/src/ui/pricing.js +0 -56
- package/src/ui/product-card.js +0 -65
- package/src/ui/section-label.js +0 -38
- package/src/ui/service-card.js +0 -47
- package/src/ui/stat-grid.js +0 -40
- package/src/ui/testimonial.js +0 -59
- package/src/ui/timeline.js +0 -72
- package/src/ui/top-strip.js +0 -47
- package/src/ui/trust-list.js +0 -46
package/src/agent/checklist.md
CHANGED
|
@@ -31,9 +31,8 @@ Before finishing any spec, verify every point below. Fix anything that fails.
|
|
|
31
31
|
- Hero sections → `hero({ title, subtitle, actions, image, ... })`
|
|
32
32
|
- Product/service cards → `card({ title, body, image, footer, ... })`
|
|
33
33
|
- Image + text two-column layouts → `media({ image, content, reverse })`
|
|
34
|
-
- Horizontal strips/banners → `banner({ content, variant })`
|
|
35
34
|
- Feature tiles → `feature({ icon, title, description })`
|
|
36
|
-
- Testimonials → `
|
|
35
|
+
- Testimonials → `card({ content, footer })` with quote + avatar/name in the content slot
|
|
37
36
|
- CTAs → `cta({ title, subtitle, actions })`
|
|
38
37
|
- Navigation → `nav({ logo, links, actions })`
|
|
39
38
|
- Footers → `footer({ logo, links, columns, legal, ... })`
|
|
@@ -10,7 +10,7 @@ import { nav, hero, feature, button, card, stat, grid, section, container, iconZ
|
|
|
10
10
|
meta: { styles: ['/pulse-ui.css', '/app.css'] }
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Interactive components (
|
|
13
|
+
Interactive components (tooltip) also need `/pulse-ui.js` in `meta.scripts`. Modal is handled natively by the Pulse runtime — no extra script needed.
|
|
14
14
|
|
|
15
15
|
### Component root CSS classes
|
|
16
16
|
|
|
@@ -37,8 +37,6 @@ Use these when writing tests (`.get('.ui-card')`) or custom CSS overrides. The r
|
|
|
37
37
|
| `stack` | `.ui-stack` | |
|
|
38
38
|
| `cluster` | `.ui-cluster` | |
|
|
39
39
|
| `feature` | `.ui-feature` | |
|
|
40
|
-
| `testimonial` | `.ui-testimonial` | |
|
|
41
|
-
| `pricing` | `.ui-pricing` | |
|
|
42
40
|
| `accordion` | `.ui-accordion` | |
|
|
43
41
|
| `cta` | `.ui-cta` | |
|
|
44
42
|
| `footer` | `.ui-footer` | |
|
|
@@ -47,24 +45,11 @@ Use these when writing tests (`.get('.ui-card')`) or custom CSS overrides. The r
|
|
|
47
45
|
| `progress` | `.ui-progress` | |
|
|
48
46
|
| `breadcrumbs` | `.ui-breadcrumbs` | |
|
|
49
47
|
| `stepper` | `.ui-stepper` | |
|
|
50
|
-
| `timeline` | `.ui-timeline` | |
|
|
51
|
-
| `carousel` | `.ui-carousel` | |
|
|
52
48
|
| `tooltip` | `.ui-tooltip` | |
|
|
53
49
|
| `appBadge` | `.ui-app-badge` | |
|
|
54
|
-
| `banner` | `.ui-banner` | |
|
|
55
50
|
| `uiImage` | `.ui-image` | |
|
|
56
|
-
| `gallery` | `.ui-gallery` | |
|
|
57
|
-
| `photoCard` | `.ui-photo-card` | |
|
|
58
|
-
| `marquee` | `.ui-marquee` | |
|
|
59
|
-
| `decorate` | `.ui-decorate` | Inline SVG — parent needs `position: relative` |
|
|
60
|
-
| `codeWindow` | `.ui-code-window` | |
|
|
61
51
|
| `segmented` | `.ui-segmented` | |
|
|
62
52
|
| `rating` | `.ui-rating` | |
|
|
63
|
-
| `entryList` | `.ui-entry-list` | Editorial — tabular list with metadata |
|
|
64
|
-
| `displayHeading` | `.ui-display-heading` | Editorial — large typographic heading |
|
|
65
|
-
| `sectionLabel` | `.ui-section-label` | Editorial — eyebrow + h2 + rule |
|
|
66
|
-
| `dropCap` | `.ui-drop-cap` | Editorial — first-letter treatment |
|
|
67
|
-
| `colophon` | `.ui-colophon` | Editorial — minimal footer |
|
|
68
53
|
|
|
69
54
|
|
|
70
55
|
|
|
@@ -73,7 +58,7 @@ Use these when writing tests (`.get('.ui-card')`) or custom CSS overrides. The r
|
|
|
73
58
|
Server-rendered SVG charts — no JS, no dependencies. Drop into any card, section, or grid.
|
|
74
59
|
|
|
75
60
|
```js
|
|
76
|
-
import { barChart, lineChart, donutChart, sparkline } from '@invisibleloop/pulse/
|
|
61
|
+
import { barChart, lineChart, donutChart, sparkline } from '@invisibleloop/pulse/charts'
|
|
77
62
|
|
|
78
63
|
barChart({
|
|
79
64
|
data: [{ label: 'Jan', value: 42 }, { label: 'Feb', value: 78 }],
|
|
@@ -178,85 +163,76 @@ To add a missing icon: copy a Lucide path (MIT) into `src/ui/icons.js` using `s(
|
|
|
178
163
|
| `breadcrumbs` | `items` ([{label,href}] — last item has no href), `separator` |
|
|
179
164
|
| `stepper` | `steps` (array of label strings), `current` (0-based) |
|
|
180
165
|
| `uiImage` | `src`, `alt`, `caption`, `ratio`, `rounded`, `pill`, `width`, `height`, `maxWidth` |
|
|
181
|
-
| `gallery` | `images` ([{src,alt,caption?,href?}]), `layout` (grid/strip/masonry), `cols` (1–4), `gap` (sm/md/lg), `rounded`, `ratio` — responsive image grid |
|
|
182
|
-
| `photoCard` | `src`, `alt`, `caption`, `tilt` (CSS rotate degrees, e.g. 2 or -1.5), `rounded`, `ratio` — polaroid-style card with optional tilt |
|
|
183
|
-
| `marquee` | `items` (array of HTML strings), `speed` (seconds, default 30), `gap`, `direction` (left/right), `pause` (hover pause), `fade` — CSS-only infinite scroll strip. Ideal for logos, trust badges |
|
|
184
|
-
| `decorate` | `pattern` (dots/grid/lines/zigzag/cross), `color`, `opacity`, `size` — inline SVG overlay. Parent needs `position: relative` (add class `u-relative`) |
|
|
185
166
|
| `pullquote` | `quote`, `cite`, `size` (md/lg) |
|
|
186
|
-
|
|
187
|
-
|
|
167
|
+
|
|
168
|
+
Image galleries, photo grids, logo/trust marquees, and timelines have no dedicated component — build them with `grid()` / `stack()` + `uiImage()` and raw HTML (creative override), or a CSS-only scrolling strip for marquee-style content.
|
|
188
169
|
|
|
189
170
|
### Typography components
|
|
190
171
|
|
|
191
172
|
| Component | Key props |
|
|
192
173
|
|-----------|-----------|
|
|
193
174
|
| `heading` | `level` (1–6), `text`, `size` (xs–4xl, overrides level default), `color` (default/muted/accent), `balance` (true — prevents orphaned words) |
|
|
194
|
-
| `list` | `items` (array of HTML strings), `ordered`, `gap` (xs/sm/md) |
|
|
195
175
|
| `prose` | `content` (raw HTML — not escaped), `size` (sm/base/lg) — for CMS/markdown content you don't control |
|
|
196
176
|
|
|
197
|
-
**Never write raw `<h1>`–`<h6>`
|
|
177
|
+
**Never write raw `<h1>`–`<h6>` without styling.** Use `heading()` instead. *(Mode A only — in a creative override, raw headings styled directly with utility classes or custom CSS are correct. The `heading()` component adds wrapper markup that can fight custom layouts.)* There is no dedicated list component — write `<ul>`/`<ol>` directly, styled with utility classes or `app.css`.
|
|
198
178
|
|
|
199
|
-
**Heading order across components.** `card`, `feature`, `section`, `
|
|
179
|
+
**Heading order across components.** `card`, `feature`, `section`, `cta`, and `modal` all accept a `level` prop. Use it to keep the document outline correct without changing visual style. For example, if a page has an h2 section title and each card inside it has a title, pass `level: 3` on the cards (the default) — but if the cards are the first heading on the page, pass `level: 2`. The CSS class stays the same (`ui-card-title` etc.) so appearance is unaffected.
|
|
200
180
|
|
|
201
181
|
**`balance: true`** on `heading()` prevents orphaned words. Apply to any heading the verification orphan check flags.
|
|
202
182
|
|
|
203
|
-
Use `prose()` for HTML from external sources (CMS, markdown). Use `heading()
|
|
204
|
-
|
|
205
|
-
### Editorial components
|
|
206
|
-
|
|
207
|
-
Editorial/typographic primitives for non-SaaS layouts: paperback books, vintage magazines, editorial sites, portfolio pages. These complement the landing-page-focused components (hero, feature, cta) when the design needs structure that's tabular, asymmetric, or typography-led.
|
|
208
|
-
|
|
209
|
-
| Component | Key props | Use for |
|
|
210
|
-
|-----------|-----------|---------|
|
|
211
|
-
| `entryList` | `items` ([{meta, title, description}]), `metaLabel` (accessible name for meta column — e.g. "Year") | Backlists, release notes, changelogs, project archives, talk logs |
|
|
212
|
-
| `displayHeading` | `text`, `level` (1–6), `maxWidth` (ch units, default 20), `balance` (true), `tracking` ('tight'\|'normal'\|'wide') | Hero titles, chapter openings, large typographic moments |
|
|
213
|
-
| `sectionLabel` | `eyebrow`, `heading`, `level` (1–6, default 2), `rule` (true — show horizontal rule), `align` ('left'\|'center') | Section dividers, chapter labels, content blocks |
|
|
214
|
-
| `dropCap` | `letter` (the drop cap letter or word), `content` (rest of paragraph), `lines` (height in lines, default 3) | First-paragraph treatment, editorial openings |
|
|
215
|
-
| `colophon` | `content` (HTML slot), `align` ('center'\|'left') | Paperback-style footer — minimal, tight type, no columns |
|
|
183
|
+
Use `prose()` for HTML from external sources (CMS, markdown). Use `heading()` when writing headings yourself.
|
|
216
184
|
|
|
217
|
-
|
|
185
|
+
### Editorial / typographic layouts
|
|
218
186
|
|
|
219
|
-
|
|
187
|
+
There is no dedicated editorial component family — for non-SaaS layouts (paperback books, vintage magazines, editorial sites, portfolio pages) needing structure that's tabular, asymmetric, or typography-led, compose from `heading()`, `prose()`, `pullquote()`, `divider()`, and raw HTML styled with utility classes or `app.css` (creative override).
|
|
220
188
|
|
|
221
|
-
**Example: Book backlist**
|
|
189
|
+
**Example: Book backlist** — a tabular list of items, built with raw HTML inside `stack()`:
|
|
222
190
|
```js
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
191
|
+
stack({
|
|
192
|
+
gap: 'md',
|
|
193
|
+
content: books.map(b => `
|
|
194
|
+
<div class="book-entry">
|
|
195
|
+
<span class="book-entry-year">${b.year}</span>
|
|
196
|
+
<div>
|
|
197
|
+
<h3>${b.title}</h3>
|
|
198
|
+
<p>${b.description}</p>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
`).join(''),
|
|
230
202
|
})
|
|
231
203
|
```
|
|
232
204
|
|
|
233
|
-
**Example: Editorial hero**
|
|
205
|
+
**Example: Editorial hero** — a large display title with a custom-styled heading, and a first-paragraph drop-cap treatment via CSS (`::first-letter`) rather than a component:
|
|
234
206
|
```js
|
|
235
|
-
${
|
|
236
|
-
|
|
207
|
+
${heading({ level: 1, text: 'In Search of Lost Code', class: 'display-heading' })}
|
|
208
|
+
<p class="drop-cap">The first computers were humans, pencil-wielding calculators in windowless rooms, computing artillery trajectories by hand...</p>
|
|
237
209
|
```
|
|
238
210
|
|
|
239
|
-
**Example: Section divider**
|
|
211
|
+
**Example: Section divider** — an eyebrow + heading + rule, built directly:
|
|
240
212
|
```js
|
|
241
|
-
|
|
213
|
+
`<div class="section-label">
|
|
214
|
+
<p class="section-label-eyebrow">Chapter 3</p>
|
|
215
|
+
${heading({ level: 2, text: 'The Rise of Symbolic Logic' })}
|
|
216
|
+
${divider()}
|
|
217
|
+
</div>`
|
|
242
218
|
```
|
|
243
219
|
|
|
244
|
-
**Example: Minimal footer for an editorial page**
|
|
220
|
+
**Example: Minimal footer for an editorial page** — plain HTML rather than `footer()`, when the page wants a tight, columnless colophon:
|
|
245
221
|
```js
|
|
246
|
-
colophon
|
|
247
|
-
|
|
248
|
-
<p><a href="/about">About</a> • <a href="/contact">Contact</a></p
|
|
249
|
-
|
|
222
|
+
`<footer class="colophon">
|
|
223
|
+
<p>© 2025 Alden Press • Set in Lyon Text and Atlas Grotesk</p>
|
|
224
|
+
<p><a href="/about">About</a> • <a href="/contact">Contact</a></p>
|
|
225
|
+
</footer>`
|
|
250
226
|
```
|
|
251
227
|
|
|
252
|
-
**Composition:**
|
|
228
|
+
**Composition:** These layouts work inside `section()` + `container()` like any other Pulse component. Use `prose()` for body text, `heading()` for large type moments, and custom CSS classes (defined in `app.css` with tokens from `theme.css`) for editorial-specific presentation.
|
|
253
229
|
|
|
254
230
|
#### When components feel restrictive
|
|
255
231
|
|
|
256
232
|
**Symptom:** You're fighting a component's wrapper styles (padding, max-width, centering) in your CSS overrides.
|
|
257
233
|
|
|
258
234
|
**Solutions:**
|
|
259
|
-
1. **Use the right
|
|
235
|
+
1. **Use the right approach for your design.** If the page is editorial/typographic, compose from `heading()`, `prose()`, and raw HTML (creative override) instead of trying to force `hero()`, `feature()`, `cta()` into an editorial shape.
|
|
260
236
|
2. **Write custom markup for structural differences.** Components provide sensible defaults for common patterns. When your design structure diverges significantly (asymmetric grid, full-bleed sections, custom positioning), write the HTML directly — that's permitted for layouts. Use components for the UI primitives (`button`, `card`, `input`, `badge`), but write the outer structure yourself.
|
|
261
237
|
3. **Override with higher specificity.** Component wrappers use single class names (`.ui-hero`, `.ui-cta`). Override with a more specific selector in your `app.css`:
|
|
262
238
|
```css
|
|
@@ -276,9 +252,9 @@ For example:
|
|
|
276
252
|
- `hero()` with `vibe: 'editorial'` still renders eyebrow + title + subtitle + actions (SaaS structure)
|
|
277
253
|
- The vibe adjusts the font sizes, tracking, and spacing, but the component HTML is unchanged
|
|
278
254
|
|
|
279
|
-
**If you need different HTML structure for an editorial design** — e.g., a large display title + asymmetric layout + drop cap instead of eyebrow/subtitle/actions —
|
|
255
|
+
**If you need different HTML structure for an editorial design** — e.g., a large display title + asymmetric layout + drop cap instead of eyebrow/subtitle/actions — write custom markup styled with `heading()`/`prose()` plus utility classes or `app.css`. Do not expect `hero()` to become structurally editorial when `vibe: 'editorial'` is set.
|
|
280
256
|
|
|
281
|
-
This is by design: vibes are a paint job, not a structural transformation. Components stay predictable and testable. When the design structure itself differs from the SaaS patterns (centred hero, three-column features, pricing cards), reach for
|
|
257
|
+
This is by design: vibes are a paint job, not a structural transformation. Components stay predictable and testable. When the design structure itself differs from the SaaS patterns (centred hero, three-column features, pricing cards), reach for custom layout instead of trying to force `hero()` / `feature()` / `cta()` into shapes they weren't designed for.
|
|
282
258
|
|
|
283
259
|
### Landing page components
|
|
284
260
|
|
|
@@ -288,12 +264,12 @@ This is by design: vibes are a paint job, not a structural transformation. Compo
|
|
|
288
264
|
| `hero` | `eyebrow`, `title`, `subtitle`, `actions` (HTML slot), `image` (HTML slot — activates image layout), `imageAlign` (right/left), `align` (center/left), `size` (md/sm), `layout` (split/asymmetric/overlap — when image provided: 'split'=50/50, 'asymmetric'=60/40 text-heavy, 'overlap'=image fills section with text overlay), `gradient` (true/false or preset: 'purple'\|'blue'\|'green'\|'rose'\|'orange'), `background` (any CSS value), `eyebrowColor` |
|
|
289
265
|
| `phoneFrame` | `content` (HTML slot — rendered inside the phone screen), `animate` (boolean, default `false` — enables a gentle 3-D tilt on hover). Pure CSS phone mockup with dynamic island, side buttons, home indicator. Use as the `image` slot in `hero()` for app landing pages. Add `animate: true` whenever the phone is a prominent hero element. |
|
|
290
266
|
| `feature` | `image` (HTML slot — rendered above icon), `icon` (HTML slot), `title`, `level` (1–6, default 3), `description` (or `body` as alias), `center` |
|
|
291
|
-
| `testimonial` | `quote`, `name`, `role`, `src`, `rating` (1–5) |
|
|
292
|
-
| `pricing` | `name`, `level` (1–6, default 3), `price`, `period`, `features` ([strings]), `action` (HTML slot), `highlighted` |
|
|
293
267
|
| `accordion` | `items` ([{question,answer}]) — native `<details>`, no JS |
|
|
294
268
|
| `appBadge` | `store` (apple/google), `href` — **always use this for App Store / Google Play download buttons. Never write a raw `<a>` with an SVG badge image.** Designed to sit in a `hero()` `actions` slot or anywhere a download CTA is needed. |
|
|
295
269
|
| `cta` | `eyebrow`, `title`, `level` (1–6, default 2), `subtitle` (or `body` as alias), `actions` (HTML slot), `align` (center/left) |
|
|
296
270
|
|
|
271
|
+
There is no dedicated `testimonial` or `pricing` component. Build a testimonial with `card({ content, footer })` — the quote in `content`, an `avatar()` + name/role in `footer`. Build a pricing table with `grid()` of `card({ title, content, footer })` tiles — one card per plan, `variant: 'elevated'` on the highlighted plan.
|
|
272
|
+
|
|
297
273
|
### Layout components
|
|
298
274
|
|
|
299
275
|
| Component | Key props |
|
|
@@ -304,11 +280,11 @@ This is by design: vibes are a paint job, not a structural transformation. Compo
|
|
|
304
280
|
| `stack` | `content`, `gap` (xs–xl), `align` — flex column |
|
|
305
281
|
| `cluster` | `content`, `gap`, `justify`, `align` — flex row with wrap |
|
|
306
282
|
| `divider` | `label` |
|
|
307
|
-
| `banner` | `content`, `variant` |
|
|
308
283
|
| `media` | `image` (HTML slot), `content` (HTML slot), `reverse` — two-column image + text |
|
|
309
|
-
| `codeWindow` | `content` (highlighted code HTML), `filename`, `lang` |
|
|
310
284
|
| `footer` | `logo`, `logoHref`, `links` (flat: `[{label,href}]`), `legal`, `background`, `color` — **Rich layout:** add `columns: [{title, links:[{label,href}]}]` to switch to multi-column mode; also accepts `subscribe` (HTML slot), `wordmark` (giant display text) |
|
|
311
285
|
|
|
286
|
+
There is no dedicated `banner` (thin announcement strip) or `codeWindow` (syntax-highlighted code frame) component. Build a banner as a small raw `<div>` strip styled with utility classes. Build a code window with a raw `<pre><code>` block (creative override), styled via `app.css`.
|
|
287
|
+
|
|
312
288
|
### Modal / dialog
|
|
313
289
|
|
|
314
290
|
Use `modal()` + `modalTrigger()` (or `data-dialog-open`). **Never use `state.modalOpen` or conditional rendering** — this destroys the dialog element on every render, breaking focus, animation, and native ESC.
|
|
@@ -10,9 +10,9 @@ A curated catalogue of ready-to-use design patterns. Each entry names the live t
|
|
|
10
10
|
**Route:** `/templates/local-business`
|
|
11
11
|
**Vibe:** `warm` **Theme:** `light` **CSS:** `lumio.css`
|
|
12
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.
|
|
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 (built with `card`). Contact section with location/hours sidebar and inline booking form. Stat strip showing social proof numbers.
|
|
14
14
|
|
|
15
|
-
**Key components:** `hero({ layout:'split' })`, `section`, `container`, `grid`, `card` (with `footer`), `stat`, `
|
|
15
|
+
**Key components:** `hero({ layout:'split' })`, `section`, `container`, `grid`, `card` (with `footer`), `stat`, `cta`, `badge`
|
|
16
16
|
|
|
17
17
|
**Distinguishing moves:**
|
|
18
18
|
- Gradient hero `linear-gradient(135deg, #fdf6ee, #fdebd0)` with `color:#3d2b1e` — define these hex values as tokens in `public/theme.css` and reference them via `var()`; the lint hook blocks raw hex in any other stylesheet
|
|
@@ -47,14 +47,14 @@ Dark, editorial, high-contrast. Works grid with cover images (fluid fill via `fl
|
|
|
47
47
|
**Route:** `/templates/event`
|
|
48
48
|
**Vibe:** `bold` **Theme:** `dark` **CSS:** *(none extra — dark theme built-in)*
|
|
49
49
|
|
|
50
|
-
Dark navy with violet/purple gradient CTAs. Centred hero with countdown-style stats strip. Sponsor logo
|
|
50
|
+
Dark navy with violet/purple gradient CTAs. Centred hero with countdown-style stats strip. Sponsor logo strip (raw HTML, CSS-only scroll animation). 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
51
|
|
|
52
|
-
**Key components:** `hero`, `section`, `container`, `grid({ cols:4 })`, `card({ flush:true })`, `accordion`, `
|
|
52
|
+
**Key components:** `hero`, `section`, `container`, `grid({ cols:4 })`, `card({ flush:true })`, `accordion`, `badge`, `stat`, `cta`
|
|
53
53
|
|
|
54
54
|
**Distinguishing moves:**
|
|
55
55
|
- Speaker cards: `aspect-ratio:1/1` square portrait images + name/role/quote below
|
|
56
56
|
- Accordion items: `{ question: 'Day 1 — ...', answer: '<div>...timetable rows...</div>' }`
|
|
57
|
-
-
|
|
57
|
+
- Sponsor logo strip: raw HTML `cluster()` of logos, or a CSS `@keyframes` scroll animation for an infinite marquee effect (creative override — no dedicated component)
|
|
58
58
|
- Stats strip: `section({ variant:'alt', padding:'sm' })` + `grid({ cols:4 })`
|
|
59
59
|
|
|
60
60
|
**Best for:** Conference, hackathon, festival, product launch, awards ceremony, summit
|
|
@@ -83,9 +83,9 @@ Dark with serif headline typography. Featured article hero with byline, read-tim
|
|
|
83
83
|
**Route:** `/templates/mobile-app`
|
|
84
84
|
**Vibe:** `bold` or `minimal` **Theme:** `dark` **CSS:** *(dark theme built-in)*
|
|
85
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.
|
|
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. Pricing tiers and testimonials are built from `grid()` of `card()` tiles (no dedicated `pricing`/`testimonial` component).
|
|
87
87
|
|
|
88
|
-
**Key components:** `hero`, `phoneFrame`, `feature`, `
|
|
88
|
+
**Key components:** `hero`, `phoneFrame`, `feature`, `grid`, `card`, `appBadge`, `cta`
|
|
89
89
|
|
|
90
90
|
**Best for:** iOS/Android app, SaaS with mobile client, consumer product launch
|
|
91
91
|
|
|
@@ -174,14 +174,15 @@ section({
|
|
|
174
174
|
})
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
### Sponsor
|
|
177
|
+
### Sponsor Logo Strip
|
|
178
|
+
No dedicated marquee component — use `cluster()` for a static wrapped row, or raw HTML with a CSS `@keyframes` scroll animation for an infinite marquee effect (creative override):
|
|
178
179
|
```js
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
cluster({
|
|
181
|
+
gap: 'xl',
|
|
182
|
+
justify: 'center',
|
|
183
|
+
content: ['Acme Corp', 'Globex', 'Initech', 'Umbrella', 'Hooli'].map(
|
|
181
184
|
name => `<span class="u-font-semibold u-text-lg u-opacity-60">${name}</span>`
|
|
182
|
-
),
|
|
183
|
-
speed: 'slow',
|
|
184
|
-
gap: 'xl',
|
|
185
|
+
).join(''),
|
|
185
186
|
})
|
|
186
187
|
```
|
|
187
188
|
|
|
@@ -251,7 +252,6 @@ The most common mistakes when writing templates. These will silently produce emp
|
|
|
251
252
|
| `card` | `body:` | `content:` |
|
|
252
253
|
| `card` | `image:` *(unsupported)* | Put `<img>` inside `content:` |
|
|
253
254
|
| `card` | `href:` *(unsupported)* | Wrap title in `<a>` inside `content:` |
|
|
254
|
-
| `testimonial` | `author:` | `name:` |
|
|
255
255
|
| `pullquote` | `author:` | `cite:` |
|
|
256
256
|
| `accordion` items | `title:` | `question:` |
|
|
257
257
|
| `accordion` items | `content:` | `answer:` |
|
|
@@ -14,8 +14,8 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
14
14
|
**Geometry:** tight radius (2–6px), mono grids, generous whitespace
|
|
15
15
|
**Typography:** geometric sans, tight tracking on headings, strong size contrast
|
|
16
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`, `
|
|
17
|
+
**Signature moves:** bento grid, floating nav on scroll, stat bar, code window (raw `<pre><code>`, creative override)
|
|
18
|
+
**Components to lead with:** `hero(layout:'centered')`, `grid`, `stat`, `feature`
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -25,8 +25,8 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
25
25
|
**Geometry:** large radius (14–20px), soft card shadows, rounded buttons
|
|
26
26
|
**Typography:** humanist sans (inter, nunito), comfortable line-height
|
|
27
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
|
|
29
|
-
**Components to lead with:** `hero(layout:'split')`, `
|
|
28
|
+
**Signature moves:** real photo hero, services grid with icons, "meet the team", hours + map, handwritten accent (SVG underline, raw HTML)
|
|
29
|
+
**Components to lead with:** `hero(layout:'split')`, `uiImage`, `grid`, `section(variant:'alt')`, `footer` with address
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -53,8 +53,8 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
53
53
|
**Geometry:** medium radius (6–10px), oversized type, dramatic section transitions
|
|
54
54
|
**Typography:** heavy condensed sans (Black weight), massive heading, strong contrast
|
|
55
55
|
**Palette pattern:** black bg + vivid single colour (yellow / red / lime) for accents
|
|
56
|
-
**Signature moves:** work case-study grid, client logo
|
|
57
|
-
**Components to lead with:** `hero(layout:'poster')`, `
|
|
56
|
+
**Signature moves:** work case-study grid, client logo strip (raw HTML, CSS scroll animation), big number stats, diagonal section, full-bleed hero
|
|
57
|
+
**Components to lead with:** `hero(layout:'poster')`, `grid`, `uiImage`, `section(variant:'diagonal')`, `stat`
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
@@ -67,12 +67,12 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
67
67
|
**Signature moves (use these, not 3-col feature grids):**
|
|
68
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
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
|
-
- **
|
|
71
|
-
- **Tilted
|
|
72
|
-
- **Memphis-style geometric shapes** between sections —
|
|
73
|
-
- **Social proof as ticker** — a
|
|
70
|
+
- **Scrolling strip** — giant repeated icon-library glyphs, brand marks, or product icons scrolling across the page between sections (raw HTML + CSS `@keyframes` animation, creative override — no dedicated component). Use icons from `src/ui/icons.js`, not emoji — emoji are banned in UI output (not accessible, not theme-aware).
|
|
71
|
+
- **Tilted cards** — testimonial or feature cards at ±2–4° with `card` + CSS `transform: rotate()`
|
|
72
|
+
- **Memphis-style geometric shapes** between sections — raw inline SVG or CSS background shapes (creative override)
|
|
73
|
+
- **Social proof as ticker** — a CSS scrolling strip of short quotes or star ratings, not a 3-col grid
|
|
74
74
|
|
|
75
|
-
**Components to lead with:** `hero`, `appBadge`, `
|
|
75
|
+
**Components to lead with:** `hero`, `appBadge`, `card`, `section` with flat-colour backgrounds, `stat`
|
|
76
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
77
|
|
|
78
78
|
---
|
|
@@ -84,7 +84,7 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
84
84
|
**Typography:** light weight body, all-caps labels, large work titles
|
|
85
85
|
**Palette pattern:** white or near-black + single neutral accent
|
|
86
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:** `
|
|
87
|
+
**Components to lead with:** `grid`, `uiImage`, `container(size:'sm')`, `heading`, minimal `footer`
|
|
88
88
|
|
|
89
89
|
---
|
|
90
90
|
|
|
@@ -105,8 +105,8 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
105
105
|
**Geometry:** medium radius (8px), textured backgrounds, thick borders
|
|
106
106
|
**Typography:** slab serif (Rockwell / Courier), mixed cases, stamp-style labels
|
|
107
107
|
**Palette pattern:** amber / cream / dark brown / forest green
|
|
108
|
-
**Signature moves:**
|
|
109
|
-
**Components to lead with:** `hero(layout:'stacked')`, `section(variant:'alt')`, `
|
|
108
|
+
**Signature moves:** dotted-pattern background (inline SVG or CSS `radial-gradient`, creative override), thick divider lines, badge-style eyebrows, stacked text hierarchy
|
|
109
|
+
**Components to lead with:** `hero(layout:'stacked')`, `section(variant:'alt')`, `badge`, `card`
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
@@ -117,7 +117,7 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
117
117
|
**Typography:** system-ui or clean sans, no display serif, professional
|
|
118
118
|
**Palette pattern:** navy / corporate blue + white + grey
|
|
119
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`, `
|
|
120
|
+
**Components to lead with:** `hero(layout:'centered')`, `grid`, `feature`, `stat`, `card` (testimonial with company name in the footer slot)
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
@@ -128,7 +128,7 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
128
128
|
**Typography:** impact / black weight / giant, sometimes rotated via CSS transform
|
|
129
129
|
**Palette pattern:** black + white + ONE violent accent (red / lime / hot pink)
|
|
130
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`, `
|
|
131
|
+
**Components to lead with:** raw `section`, `container`, `heading`, `uiImage` (no rounded), CSS noise texture (creative override)
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
@@ -138,8 +138,8 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
138
138
|
**Geometry:** sharp (2–4px), glowing borders, glassmorphism
|
|
139
139
|
**Typography:** monospace or geometric sans, colour gradient on headings
|
|
140
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, `
|
|
141
|
+
**Signature moves:** blurred glow backgrounds, animated grid lines (CSS), terminal code window (raw `<pre><code>`, creative override), token/protocol stats
|
|
142
|
+
**Components to lead with:** `hero` with gradient, `stat`, `section(variant:'spotlight')`, `grid`
|
|
143
143
|
|
|
144
144
|
---
|
|
145
145
|
|
|
@@ -166,7 +166,7 @@ When you choose a design direction, tell the user which one you're using and why
|
|
|
166
166
|
## Cross-cutting rules
|
|
167
167
|
|
|
168
168
|
- Never default to centered hero + feature grid + pricing + FAQ without checking if a different layout suits the product better.
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
169
|
+
- A CSS-only scrolling strip (raw HTML + `@keyframes`, creative override) is great for trust logos, client names, and tech stack badges — use it on agency/corporate/SaaS directions.
|
|
170
|
+
- Photo-forward layouts (`uiImage` inside `grid`) are underused — deploy them whenever the product has visual appeal (food, fitness, places, products).
|
|
171
|
+
- Subtle background textures (dot-grid, noise, lines via inline SVG or CSS gradients, creative override) add texture without images — especially useful on retro, brutalist, and paper directions.
|
|
172
172
|
- `section(variant:'diagonal')` → bold / agency; `section(variant:'paper')` → warm / retro; `section(variant:'spotlight')` → dark tech / neon.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- meta.styles — array of CSS paths loaded as <link rel="stylesheet">. Always include '/app.css'.
|
|
4
4
|
- meta.scripts — array of JS paths loaded as <script defer>. Required for interactive UI components.
|
|
5
5
|
|
|
6
|
-
Interactive Pulse UI components (
|
|
6
|
+
Interactive Pulse UI components (tooltip) require BOTH:
|
|
7
7
|
```js
|
|
8
8
|
meta: {
|
|
9
9
|
styles: ['/app.css', '/pulse-ui.css'],
|
|
@@ -125,7 +125,7 @@ meta: {
|
|
|
125
125
|
|---|---|---|
|
|
126
126
|
| `warm` | radius 14px, softer letter-spacing | rounded photo cards, `section: paper`, warm palette |
|
|
127
127
|
| `editorial` | radius 0, serif display font, tight letter-spacing | `hero layout: overlap`, `section: diagonal`, `pullquote` |
|
|
128
|
-
| `playful` | radius 22px, neutral letter-spacing |
|
|
128
|
+
| `playful` | radius 22px, neutral letter-spacing | rounded image grid, scrolling strip (creative override), bright accent |
|
|
129
129
|
| `minimal` | radius 2px, open letter-spacing, no shadows | left-aligned hero, `section: spotlight`, monochrome |
|
|
130
130
|
| `bold` | radius 6px, very tight letter-spacing | `section: dark`, large `stat` components, gradient hero |
|
|
131
131
|
|
|
@@ -36,9 +36,9 @@ When the vibe is **playful, bold, brutalist, retro, or neon**, run `pulse_sketch
|
|
|
36
36
|
**What this means in practice for expressive vibes:**
|
|
37
37
|
|
|
38
38
|
- The template tells you *what to include* (a hero, features, social proof, CTA). It does **not** tell you how to arrange them or what shape they take.
|
|
39
|
-
- Full-colour section blocks, oversized typography heroes,
|
|
39
|
+
- Full-colour section blocks, oversized typography heroes, CSS-only scrolling strips, dense grids, and palette-as-structure are all fair game.
|
|
40
40
|
- The `phoneFrame` in Mobile App Landing is **not mandatory** — a full-bleed game board, an oversized illustration, or a typography-only hero may serve the brief better.
|
|
41
|
-
- `feature()` in a 3-column grid is the most predictable layout on the web. If the brief is "fun and bold", use a
|
|
41
|
+
- `feature()` in a 3-column grid is the most predictable layout on the web. If the brief is "fun and bold", use a scrolling strip of features (raw HTML + CSS `@keyframes`, creative override), a zigzag alternating layout, or full-bleed feature sections instead.
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -115,8 +115,8 @@ Record the intake answers. If the user provides palette hex values, note which a
|
|
|
115
115
|
| Hero | `hero` (split layout) with `phoneFrame` mockup |
|
|
116
116
|
| Stats bar | `stat` × 4 in a `grid` |
|
|
117
117
|
| Features | `feature` × 6 in a `grid` |
|
|
118
|
-
| Testimonials | `
|
|
119
|
-
| Pricing | `
|
|
118
|
+
| Testimonials | `card({ content, footer })` × 3 in a `grid` |
|
|
119
|
+
| Pricing | `card({ title, content, footer })` × 3 (Free / Pro / Family) in a `grid` |
|
|
120
120
|
| FAQ | `accordion` |
|
|
121
121
|
| Download CTA | `cta` with `appBadge` |
|
|
122
122
|
| Footer | `footer` with logo, links, legal |
|
|
@@ -326,7 +326,7 @@ Do NOT set `meta.theme: 'light'` on dark templates — the default pulse-ui them
|
|
|
326
326
|
| Stats strip | `stat` × 4 in `grid` — clients, rating, years, availability |
|
|
327
327
|
| Services | `card` × 6 in `grid` with name, description, and price |
|
|
328
328
|
| About | Two-column: photo + team bio with trust badges |
|
|
329
|
-
| Reviews | `
|
|
329
|
+
| Reviews | `card({ content, footer })` × 3 in `grid` |
|
|
330
330
|
| Contact / Hours | Two-column: address/phone/hours + booking form |
|
|
331
331
|
| CTA banner | `cta` with offer (e.g. 10% off first visit) |
|
|
332
332
|
| Footer | `footer` with address in `legal` |
|
|
@@ -394,7 +394,7 @@ Portfolio templates rarely need a separate theme CSS — the default dark palett
|
|
|
394
394
|
| Nav | `nav` with event logo, links, Get Tickets CTA |
|
|
395
395
|
| Hero | `hero(size:'xl', align:'center')` with gradient background |
|
|
396
396
|
| Stats strip | `stat` × 4 — days, speakers, attendees, tracks |
|
|
397
|
-
| Sponsor logos | `
|
|
397
|
+
| Sponsor logos | `cluster()` row, or raw HTML + CSS `@keyframes` scrolling strip (creative override) with sponsor names/logos |
|
|
398
398
|
| Speakers | `card` × 8 in `grid` with photo, name, role, topic |
|
|
399
399
|
| Schedule | `accordion` — one item per day with time/session/location |
|
|
400
400
|
| Venue | Two-column: venue info + photo |
|
package/src/agent/identity.md
CHANGED
|
@@ -45,7 +45,7 @@ The component rules marked *(Mode A)* below are suspended under a declared creat
|
|
|
45
45
|
- Use inline `style=""` attributes. Use utility classes or `var(--ui-*)` tokens in a stylesheet. *Exception:* structural image styles with no utility-class equivalent (`aspect-ratio`, `object-fit`) are permitted inline — these are layout facts, not theming, and the design gallery uses them this way.
|
|
46
46
|
- Write raw `<button>`, `<input>`, `<select>`, or `<textarea>` HTML when the component library already provides accessible, styled versions. *(Mode A — under a creative override, functional atoms should still come from components unless there is a specific design reason.)*
|
|
47
47
|
- Write raw `<h1>`–`<h6>` without styling. Use `heading({ level, text })` instead. *(Mode A — under a creative override, raw headings styled with utility classes or custom CSS are correct; `heading()` adds wrapper markup that fights custom layouts.)*
|
|
48
|
-
- Write raw `<ul>` or `<ol>` without styling.
|
|
48
|
+
- Write raw `<ul>` or `<ol>` without visible styling. There is no dedicated list component — style lists with utility classes or `app.css` tokens rather than leaving default browser markers unstyled.
|
|
49
49
|
- Output CMS or database HTML without a `prose()` wrapper. Raw HTML from external sources has no styling — always wrap it in `prose({ content: html })`.
|
|
50
50
|
- Use `data-event` on text inputs. Re-rendering on every keystroke destroys focus. Use uncontrolled inputs and read values from `FormData` in `action.onStart` or `action.run`.
|
|
51
51
|
- Skip `onError` in an action. It is required. Always handle failure.
|
package/src/agent/workflow.md
CHANGED
|
@@ -154,9 +154,8 @@ Or use the guide-components table. Never write these patterns from scratch in Mo
|
|
|
154
154
|
- Hero section → `hero()`
|
|
155
155
|
- Product/service cards → `card()`
|
|
156
156
|
- Image + text layouts → `media()`
|
|
157
|
-
- Horizontal strips → `banner()`
|
|
158
157
|
- Feature tiles → `feature()`
|
|
159
|
-
- Testimonials → `
|
|
158
|
+
- Testimonials → `card({ content, footer })` with quote + avatar/name in the footer slot
|
|
160
159
|
- CTAs → `cta()`
|
|
161
160
|
|
|
162
161
|
If you're about to type `class="hero"` or `class="product-card"` in Mode A, stop — use the component instead.
|