@invisibleloop/pulse 0.10.1 → 0.11.0

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.
@@ -304,7 +304,7 @@ const downloadCta = section({
304
304
 
305
305
  const pageFooter = footer({
306
306
  logo: `${iconFeather({ size: 18 })}<span class="u-font-bold" style="letter-spacing:-0.02em">Lumio</span>`,
307
- logoHref: '#',
307
+ logoHref: '/',
308
308
  links: [
309
309
  { label: 'Privacy', href: '#' },
310
310
  { label: 'Terms', href: '#' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invisibleloop/pulse",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "AI-first frontend framework. The spec is the source of truth.",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- 0.10.1
1
+ 0.11.0
@@ -0,0 +1,154 @@
1
+ # Pulse Templates — Scaffold Guide
2
+
3
+ Templates are complete, production-ready page specs you can adapt for a new brand. Always start from a template when the user's request matches one — do not build from scratch.
4
+
5
+ ---
6
+
7
+ ## When to use a template
8
+
9
+ Read the user's request and match against the triggers below. If it matches, use the template.
10
+
11
+ | Template | Route | Triggers |
12
+ |---|---|---|
13
+ | Mobile App Landing | `docs/src/pages/templates/mobile-app.js` | "landing page for a mobile app", "app marketing site", "app homepage", "SaaS landing page" |
14
+
15
+ ---
16
+
17
+ ## Before writing any code — mandatory pre-build questions
18
+
19
+ Ask these **before** presenting a plan. Do not skip them.
20
+
21
+ 1. **Colour palette** — "Do you have a colour palette, or should I choose one?"
22
+ 2. **Brand fonts** — "Any brand fonts, or system-ui is fine?"
23
+ 3. **Theme** — "Light or dark theme preference?"
24
+
25
+ Record the answers. If the user provides palette colours, note which are light/mid/dark toned so you can plan contrast strategy before writing any CSS.
26
+
27
+ **Why this matters:** Building with placeholder colours and retrofitting a palette requires rebuilding components, fixing WCAG contrast failures, and touching multiple files. Getting the palette upfront avoids that loop entirely.
28
+
29
+ ---
30
+
31
+ ## Mobile App Landing Page
32
+
33
+ ### What it includes
34
+
35
+ | Section | Component(s) |
36
+ |---|---|
37
+ | Sticky nav | `nav` with logo, links, CTA button |
38
+ | Hero | `hero` (split layout) with `phoneFrame` mockup |
39
+ | Stats bar | `stat` × 4 in a `grid` |
40
+ | Features | `feature` × 6 in a `grid` |
41
+ | Testimonials | `testimonial` × 3 in a `grid` |
42
+ | Pricing | `pricing` × 3 (Free / Pro / Family) in a `grid` |
43
+ | FAQ | `accordion` |
44
+ | Download CTA | `cta` with `appBadge` |
45
+ | Footer | `footer` with logo, links, legal |
46
+
47
+ ### Files to create
48
+
49
+ | File | Purpose |
50
+ |---|---|
51
+ | `src/pages/[name].js` | The page spec — copy and adapt the mobile-app template |
52
+ | `public/themes/[name].css` | Brand theme — palette tokens + light-theme overrides |
53
+
54
+ ### Adapting the template
55
+
56
+ 1. **Brand name** — replace every instance of "Lumio" with the new app name.
57
+ 2. **Copy** — update eyebrows, titles, subtitles, feature descriptions, testimonials, pricing names/features, FAQ items, and footer links to match the new product.
58
+ 3. **Phone screen** — the `phoneScreen` HTML inside `phoneFrame` is a bespoke mockup. Update colours, labels, and data to match the new brand. Inline styles inside `phoneScreen` are intentional — the mockup uses sub-utility-scale sizes that utility classes cannot express.
59
+ 4. **Colour palette** — create `public/themes/[name].css` (see CSS rules below).
60
+ 5. **Icons** — the logo uses `iconFeather` for Lumio. Choose an appropriate icon from `src/ui/icons.js` or add a new one if nothing fits.
61
+ 6. **Route** — set `route: '/[name]'` or `route: '/'` as appropriate.
62
+ 7. **`pulse-ui.js`** — always load via `asset('/pulse-ui.js')` (import `asset` from the docs layout lib). Never hardcode `/pulse-ui.js` — the unhashed path gets a 1h cache header, not the immutable cache the hashed dist path gets.
63
+
64
+ ### Theme CSS rules
65
+
66
+ Create `public/themes/[name].css`. Structure it like this:
67
+
68
+ ```css
69
+ /* Token definitions — raw palette values */
70
+ :root {
71
+ --color-primary: #hex;
72
+ --color-secondary: #hex;
73
+ /* ... other palette colours */
74
+ }
75
+
76
+ /* Light theme overrides — must target [data-theme="light"], NOT :root */
77
+ /* [data-theme="light"] has higher specificity than :root in pulse-ui.css */
78
+ [data-theme="light"], .ui-theme-light {
79
+ --ui-bg: #hex; /* page background */
80
+ --ui-surface: #hex; /* card/panel surface */
81
+ --ui-surface-2: #hex; /* nested surface */
82
+ --ui-border: #hex; /* border colour */
83
+ --ui-accent: #hex; /* MUST pass WCAG AA (4.5:1) on --ui-bg for small text */
84
+ --ui-accent-hover: #hex;
85
+ --ui-accent-dim: rgba(...); /* subtle tint for hover states */
86
+ --ui-accent-text: #fff; /* text on accent background */
87
+ --ui-muted: #hex; /* secondary text */
88
+ }
89
+
90
+ /* Primary button text fix for light theme (framework default uses var(--ui-bg)) */
91
+ [data-theme="light"] .ui-btn--primary {
92
+ color: #fff;
93
+ }
94
+
95
+ /* Nav — frosted glass effect */
96
+ [data-theme="light"] .ui-nav {
97
+ backdrop-filter: blur(14px);
98
+ -webkit-backdrop-filter: blur(14px);
99
+ }
100
+
101
+ /* Mobile nav — inherit dark text, not the white nav bar colour */
102
+ [data-theme="light"] .ui-nav-mobile .ui-nav-link,
103
+ [data-theme="light"] .ui-nav-mobile .ui-nav-mega-item-label,
104
+ [data-theme="light"] .ui-nav-mobile-section {
105
+ color: var(--ui-text);
106
+ }
107
+
108
+ /* Pricing — show Pro card first on mobile */
109
+ @media (max-width: 639px) {
110
+ #pricing .ui-grid > div:nth-child(2) { order: -1; }
111
+ }
112
+ ```
113
+
114
+ Load order in `meta.styles`: `['/pulse-ui.css', '/themes/[name].css']`
115
+
116
+ **WCAG contrast rule for `--ui-accent`:** The palette's mid-tones are often too light to pass 4.5:1 on a near-white background. If none of the palette colours pass, derive a darker tonal variant (e.g. darken the primary colour) for `--ui-accent`. Keep the palette colours for large background areas where dark text is used — those only need 3:1 (large text / non-text).
117
+
118
+ ### Spec meta
119
+
120
+ ```js
121
+ meta: {
122
+ title: '[App name] — [tagline]',
123
+ description: '...',
124
+ theme: 'light',
125
+ styles: ['/pulse-ui.css', '/themes/[name].css'],
126
+ },
127
+ ```
128
+
129
+ `theme: 'light'` sets `data-theme="light"` on `<body>`, which activates the light theme rules in `pulse-ui.css` and your theme file.
130
+
131
+ ### Utility classes — rule
132
+
133
+ All HTML outside `phoneScreen` must use utility classes, not inline `style=""` attributes. The only legitimate inline styles are:
134
+ - Inside `phoneScreen` (sub-utility-scale phone mockup)
135
+ - `letter-spacing` values (no utility equivalent)
136
+ - The skip-link off-screen positioning (`left: -9999px`)
137
+ - `color:#fff` on the nav logo span (overrides the nav's cascaded colour)
138
+ - `background` and `color` props on `hero()` and `nav()` — these are component props, not raw attributes
139
+
140
+ ### Accessibility checklist for this template
141
+
142
+ - Nav and footer logo links must go to the same `href` (both `/`). Identical accessible name + different destination = WCAG failure.
143
+ - Skip link: `<a href="#main-content" class="skip-link" style="position:absolute;left:-9999px;...">Skip to main content</a>` — always include it at the top of the view.
144
+ - `phoneFrame` has `role="img" aria-label="Phone screen preview"` built in.
145
+
146
+ ---
147
+
148
+ ## Adding a new template
149
+
150
+ When you build a new template and want it available for future scaffolding:
151
+
152
+ 1. Add it to this guide under its own `##` section following the pattern above.
153
+ 2. Add a row to the "When to use a template" table.
154
+ 3. Update the MCP resource (`pulse://guide/templates`) — it is loaded from this file.
package/src/mcp/server.js CHANGED
@@ -103,6 +103,13 @@ const GUIDE_RESOURCES = [
103
103
  description: 'Full working page examples including contact form with actions, validation, and error handling.',
104
104
  content: () => GUIDE_EXAMPLES,
105
105
  },
106
+ {
107
+ name: 'guide-templates',
108
+ uri: 'pulse://guide/templates',
109
+ title: 'Pulse Guide — Templates & Scaffolding',
110
+ description: 'Ready-made page templates. Fetch this when the user asks to build a landing page, marketing site, or branded template — it lists triggers, pre-build questions, and adaptation rules for each template.',
111
+ content: () => GUIDE_TEMPLATES,
112
+ },
106
113
  ]
107
114
 
108
115
  for (const { name, uri, title, description, content } of GUIDE_RESOURCES) {
@@ -887,7 +894,8 @@ const GUIDE_SERVER = fs.readFileSync(new URL('../agent/guide-server.md',
887
894
  const GUIDE_STYLES = fs.readFileSync(new URL('../agent/guide-styles.md', import.meta.url), 'utf8')
888
895
  const GUIDE_ROUTING = fs.readFileSync(new URL('../agent/guide-routing.md', import.meta.url), 'utf8')
889
896
  const GUIDE_COMPONENTS = fs.readFileSync(new URL('../agent/guide-components.md', import.meta.url), 'utf8')
890
- const GUIDE_EXAMPLES = fs.readFileSync(new URL('../agent/guide-examples.md', import.meta.url), 'utf8')
897
+ const GUIDE_EXAMPLES = fs.readFileSync(new URL('../agent/guide-examples.md', import.meta.url), 'utf8')
898
+ const GUIDE_TEMPLATES = fs.readFileSync(new URL('../agent/guide-templates.md', import.meta.url), 'utf8')
891
899
 
892
900
  // ---------------------------------------------------------------------------
893
901
  // The Persona — CLI-specific identity header + shared identity content
@@ -927,6 +935,7 @@ const PULSE_GUIDE_INDEX = `# Pulse Framework Guide
927
935
  | \`pulse://guide/routing\` | Navigation, page discovery, dynamic routes |
928
936
  | \`pulse://guide/components\` | All UI components, icons, charts, composition patterns |
929
937
  | \`pulse://guide/examples\` | Complete working page examples |
938
+ | \`pulse://guide/templates\` | **Fetch when asked to build a landing page or branded template.** Pre-build questions, template inventory, adaptation rules, theme CSS patterns. |
930
939
 
931
940
  ## Tools available
932
941