@invisibleloop/pulse 0.20.5 → 0.20.7

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 (164) hide show
  1. package/.claude/pulse-checklist.md +1 -2
  2. package/CLAUDE.md +1 -2
  3. package/docs/.claude/pulse-checklist.md +1 -2
  4. package/docs/public/coutumes.css +21 -44
  5. package/docs/public/docs.css +73 -6
  6. package/docs/public/home-brut.css +175 -191
  7. package/docs/public/pulse-ui.css +8 -1037
  8. package/docs/public/retrowheels.css +23 -0
  9. package/docs/public/shop.css +35 -1
  10. package/docs/public/sparkys.css +56 -23
  11. package/docs/public/theme.css +51 -7
  12. package/docs/server.js +0 -11
  13. package/docs/src/lib/component-page.js +2 -1
  14. package/docs/src/lib/nav.js +0 -11
  15. package/docs/src/pages/accessibility.js +2 -1
  16. package/docs/src/pages/actions.js +2 -1
  17. package/docs/src/pages/auth.js +2 -1
  18. package/docs/src/pages/caching.js +2 -1
  19. package/docs/src/pages/components/accordion.js +2 -1
  20. package/docs/src/pages/components/alert.js +2 -1
  21. package/docs/src/pages/components/app-badge.js +2 -1
  22. package/docs/src/pages/components/avatar.js +2 -1
  23. package/docs/src/pages/components/badge.js +2 -1
  24. package/docs/src/pages/components/breadcrumbs.js +2 -1
  25. package/docs/src/pages/components/button.js +2 -1
  26. package/docs/src/pages/components/card.js +2 -1
  27. package/docs/src/pages/components/charts.js +4 -2
  28. package/docs/src/pages/components/checkbox.js +2 -1
  29. package/docs/src/pages/components/cluster.js +2 -1
  30. package/docs/src/pages/components/container.js +2 -1
  31. package/docs/src/pages/components/cta.js +2 -1
  32. package/docs/src/pages/components/divider.js +2 -1
  33. package/docs/src/pages/components/empty.js +2 -1
  34. package/docs/src/pages/components/feature.js +2 -1
  35. package/docs/src/pages/components/fieldset.js +2 -1
  36. package/docs/src/pages/components/fileupload.js +2 -1
  37. package/docs/src/pages/components/footer.js +2 -1
  38. package/docs/src/pages/components/grid.js +11 -6
  39. package/docs/src/pages/components/heading.js +2 -1
  40. package/docs/src/pages/components/hero.js +2 -1
  41. package/docs/src/pages/components/icons.js +2 -1
  42. package/docs/src/pages/components/image.js +2 -1
  43. package/docs/src/pages/components/input.js +2 -1
  44. package/docs/src/pages/components/media.js +2 -1
  45. package/docs/src/pages/components/modal.js +2 -1
  46. package/docs/src/pages/components/nav.js +2 -1
  47. package/docs/src/pages/components/phone-frame.js +2 -1
  48. package/docs/src/pages/components/progress.js +2 -1
  49. package/docs/src/pages/components/prose.js +2 -1
  50. package/docs/src/pages/components/pullquote.js +2 -1
  51. package/docs/src/pages/components/radio.js +2 -1
  52. package/docs/src/pages/components/rating.js +2 -1
  53. package/docs/src/pages/components/search.js +2 -1
  54. package/docs/src/pages/components/section.js +2 -1
  55. package/docs/src/pages/components/segmented.js +2 -1
  56. package/docs/src/pages/components/select.js +2 -1
  57. package/docs/src/pages/components/slider.js +2 -1
  58. package/docs/src/pages/components/spinner.js +2 -1
  59. package/docs/src/pages/components/stack.js +2 -1
  60. package/docs/src/pages/components/stat.js +2 -1
  61. package/docs/src/pages/components/stepper.js +2 -1
  62. package/docs/src/pages/components/table.js +2 -1
  63. package/docs/src/pages/components/textarea.js +2 -1
  64. package/docs/src/pages/components/toggle.js +2 -1
  65. package/docs/src/pages/components/tooltip.js +2 -1
  66. package/docs/src/pages/components.js +2 -5
  67. package/docs/src/pages/config.js +2 -1
  68. package/docs/src/pages/constraints.js +2 -1
  69. package/docs/src/pages/deploy.js +2 -1
  70. package/docs/src/pages/error-pages.js +2 -1
  71. package/docs/src/pages/extending.js +2 -1
  72. package/docs/src/pages/faq.js +2 -1
  73. package/docs/src/pages/forms.js +2 -1
  74. package/docs/src/pages/getting-started.js +2 -1
  75. package/docs/src/pages/guard.js +2 -1
  76. package/docs/src/pages/home.js +24 -15
  77. package/docs/src/pages/how-it-works.js +22 -15
  78. package/docs/src/pages/hydration.js +2 -1
  79. package/docs/src/pages/images.js +2 -1
  80. package/docs/src/pages/markdown.js +2 -1
  81. package/docs/src/pages/meta.js +2 -1
  82. package/docs/src/pages/mutations.js +2 -1
  83. package/docs/src/pages/navigation.js +2 -1
  84. package/docs/src/pages/performance.js +2 -1
  85. package/docs/src/pages/persist.js +2 -1
  86. package/docs/src/pages/project-structure.js +2 -1
  87. package/docs/src/pages/prompt-examples.js +2 -1
  88. package/docs/src/pages/raw-responses.js +2 -1
  89. package/docs/src/pages/routing.js +2 -1
  90. package/docs/src/pages/server-api.js +2 -1
  91. package/docs/src/pages/server-data.js +2 -1
  92. package/docs/src/pages/slash-commands.js +2 -1
  93. package/docs/src/pages/spec.js +2 -1
  94. package/docs/src/pages/state.js +2 -1
  95. package/docs/src/pages/store.js +2 -1
  96. package/docs/src/pages/streaming.js +2 -1
  97. package/docs/src/pages/stripe.js +2 -1
  98. package/docs/src/pages/supabase.js +2 -1
  99. package/docs/src/pages/templates/coutumes.js +83 -72
  100. package/docs/src/pages/templates/mobile-app.js +36 -9
  101. package/docs/src/pages/templates/retrowheels.js +17 -4
  102. package/docs/src/pages/templates/shop.js +21 -10
  103. package/docs/src/pages/templates/sparkys.js +35 -20
  104. package/docs/src/pages/templates.js +2 -2
  105. package/docs/src/pages/testing.js +2 -1
  106. package/docs/src/pages/validation.js +2 -1
  107. package/examples/.claude/pulse-checklist.md +1 -2
  108. package/examples/examples.test.js +4 -4
  109. package/examples/pricing.js +21 -3
  110. package/examples/public/pulse-ui.css +8 -1037
  111. package/examples/retrowheels.css +23 -0
  112. package/examples/retrowheels.js +17 -4
  113. package/package.json +5 -1
  114. package/public/.pulse-ui-version +1 -1
  115. package/public/pulse-ui.css +8 -1037
  116. package/src/agent/checklist.md +1 -2
  117. package/src/agent/guide-components.md +43 -67
  118. package/src/agent/guide-design-gallery.md +14 -14
  119. package/src/agent/guide-design-references.md +21 -21
  120. package/src/agent/guide-styles.md +2 -2
  121. package/src/agent/guide-templates.md +6 -6
  122. package/src/agent/identity.md +1 -1
  123. package/src/agent/workflow.md +1 -2
  124. package/src/mcp/server.js +31 -24
  125. package/src/ui/index.js +0 -27
  126. package/src/ui/ui.test.js +0 -137
  127. package/types/charts.d.ts +61 -0
  128. package/types/ui.d.ts +1 -129
  129. package/docs/src/pages/components/banner.js +0 -44
  130. package/docs/src/pages/components/carousel.js +0 -71
  131. package/docs/src/pages/components/code-window.js +0 -56
  132. package/docs/src/pages/components/decorate.js +0 -74
  133. package/docs/src/pages/components/gallery.js +0 -102
  134. package/docs/src/pages/components/list.js +0 -111
  135. package/docs/src/pages/components/marquee.js +0 -76
  136. package/docs/src/pages/components/photo-card.js +0 -74
  137. package/docs/src/pages/components/pricing.js +0 -67
  138. package/docs/src/pages/components/testimonial.js +0 -48
  139. package/docs/src/pages/components/timeline.js +0 -226
  140. package/src/ui/banner.js +0 -41
  141. package/src/ui/brand-statement.js +0 -58
  142. package/src/ui/carousel.js +0 -59
  143. package/src/ui/code-window.js +0 -39
  144. package/src/ui/colophon.js +0 -29
  145. package/src/ui/contact-row.js +0 -41
  146. package/src/ui/decorate.js +0 -55
  147. package/src/ui/display-heading.js +0 -44
  148. package/src/ui/drop-cap.js +0 -29
  149. package/src/ui/editorial-hero.js +0 -63
  150. package/src/ui/entry-list.js +0 -36
  151. package/src/ui/gallery.js +0 -60
  152. package/src/ui/image-pair.js +0 -72
  153. package/src/ui/list.js +0 -36
  154. package/src/ui/marquee.js +0 -48
  155. package/src/ui/photo-card.js +0 -44
  156. package/src/ui/pricing.js +0 -56
  157. package/src/ui/product-card.js +0 -65
  158. package/src/ui/section-label.js +0 -38
  159. package/src/ui/service-card.js +0 -47
  160. package/src/ui/stat-grid.js +0 -40
  161. package/src/ui/testimonial.js +0 -59
  162. package/src/ui/timeline.js +0 -72
  163. package/src/ui/top-strip.js +0 -47
  164. package/src/ui/trust-list.js +0 -46
@@ -1,10 +1,25 @@
1
- // component-free — creative override: brutalist design intent; asymmetric typography-driven layout with exposed grid structure, raw borders, and oversized type that component patterns cannot express
1
+ // component-free — creative override: asymmetric typography-driven layout (wide headline column + narrower supporting column), a solid gold mark treatment on "page.", and a light/dark section rhythm that component patterns cannot express
2
2
  import { highlight } from '../lib/highlight.js'
3
3
  import { iconZap, iconShield, iconSettings } from '../../../src/ui/icons.js'
4
4
  import { metricsStore } from '../lib/metrics-store.js'
5
- import { codeWindow } from '../../../src/ui/code-window.js'
6
5
  import pkg from '../../../package.json' with { type: 'json' }
7
6
 
7
+ // macOS-style code window chrome — raw HTML (creative override), replacing
8
+ // the removed codeWindow() component. Reuses the same .ui-code-window*
9
+ // CSS classes still defined in pulse-ui.css.
10
+ const codeWindow = ({ content = '', filename = '', lang = '' }) => `
11
+ <div class="ui-code-window" role="region"${filename ? ` aria-label="${filename}"` : ''}>
12
+ <div class="ui-code-window-chrome" aria-hidden="true">
13
+ <span class="ui-code-window-dot"></span>
14
+ <span class="ui-code-window-dot"></span>
15
+ <span class="ui-code-window-dot"></span>
16
+ ${filename ? `<span class="ui-code-window-filename">${filename}</span>` : ''}
17
+ ${lang ? `<span class="ui-code-window-lang">${lang}</span>` : ''}
18
+ </div>
19
+ <pre class="ui-code-window-pre"><code class="ui-code-window-code">${content}</code></pre>
20
+ </div>
21
+ `
22
+
8
23
  const { version } = pkg
9
24
 
10
25
  const exampleSpec = highlight(`export default {
@@ -40,6 +55,7 @@ export default {
40
55
  meta: {
41
56
  title: 'Pulse — The spec-first web framework',
42
57
  description: 'Pulse is a server-first Node.js framework with zero runtime dependencies. One spec object per page: server data, state, mutations, and view in plain JS. Streaming SSR, security headers, and production caching are enforced by the architecture.',
58
+ theme: 'light',
43
59
  styles: ['https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&display=swap', '/pulse-ui.css', '/theme.css', '/docs.css', '/home-brut.css'],
44
60
  schema: {
45
61
  '@context': 'https://schema.org',
@@ -64,7 +80,7 @@ export default {
64
80
  <nav class="brut-nav" aria-label="Site navigation">
65
81
  <a href="/" class="brut-nav-logo" aria-label="Pulse home">
66
82
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
67
- <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="#f0e642" stroke="#f0e642" stroke-width="1" stroke-linejoin="round"/>
83
+ <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
68
84
  </svg>
69
85
  <span>PULSE</span>
70
86
  </a>
@@ -81,20 +97,13 @@ export default {
81
97
  <div class="brut-hero-tag">v${version} — EARLY ACCESS</div>
82
98
  <h1 class="brut-hero-h1">
83
99
  <span class="brut-hero-kicker">with Pulse</span>
84
- <span class="brut-hero-line1">YOU CAN'T</span>
85
- <span class="brut-hero-line2" role="img" aria-label="SHIP">
86
- <svg class="brut-hero-svg" aria-hidden="true">
87
- <text class="brut-hero-svg-text" y="0.82em" dominant-baseline="auto"
88
- font-family="Inter, system-ui, sans-serif" font-weight="900"
89
- fill="var(--brut-yellow)" stroke="var(--brut-ink)" stroke-width="0.055em" paint-order="stroke fill">SHIP</text>
90
- </svg>
91
- </span>
92
- <span class="brut-hero-line3">A BAD PAGE.</span>
100
+ <span class="brut-hero-line1">The spec is</span>
101
+ <span class="brut-hero-line2">the <span class="brut-hero-mark">page.</span></span>
93
102
  </h1>
94
103
  <div class="brut-hero-aside">
95
104
  <p class="brut-hero-tag-inline">ONE SPEC. ONE WAY TO BUILD.</p>
96
- <p class="brut-hero-desc">A server-first Node.js framework. Streaming SSR, security headers, and production caching are enforced by the architecture, not left to configuration.</p>
97
- <p class="brut-hero-sub"><strong>So constrained that doing it wrong isn't an option. Whether you write it or an AI does.</strong></p>
105
+ <p class="brut-hero-desc">One plain JS object — server data, state, mutations, and view. No split files, no hidden conventions.</p>
106
+ <p class="brut-hero-sub"><strong>So constrained that doing it wrong isn't an option.<br>Whether you write it or an AI&nbsp;does.</strong></p>
98
107
  <div class="brut-hero-ctas">
99
108
  <a href="/getting-started" class="brut-btn-primary">Get Started</a>
100
109
  <a href="/spec" class="brut-btn-ghost">Read the Spec</a>
@@ -192,7 +201,7 @@ export default {
192
201
  <th></th>
193
202
  <th class="brut-th-pulse">
194
203
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" aria-hidden="true" style="vertical-align:middle;margin-right:.3rem">
195
- <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="#f0e642" stroke="#f0e642" stroke-width="1" stroke-linejoin="round"/>
204
+ <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
196
205
  </svg>PULSE
197
206
  </th>
198
207
  <th>Next.js / Remix</th>
@@ -1,74 +1,81 @@
1
1
  import { renderLayout, h1, lead, section, callout } from '../lib/layout.js'
2
2
  import { prevNext } from '../lib/nav.js'
3
- import { timeline, card } from '../../../src/ui/index.js'
3
+ import { card } from '../../../src/ui/index.js'
4
4
 
5
5
  const { prev, next } = prevNext('/how-it-works')
6
6
 
7
- const agentFlow = timeline({
8
- items: [
7
+ // Numbered vertical flow diagram — raw HTML (creative override), replacing
8
+ // the removed timeline()/timelineItem() components. Styled via .hiw-flow*
9
+ // classes in docs.css.
10
+ const flowStep = ({ dot, label, content }) => `
11
+ <li class="hiw-flow-item">
12
+ <div class="hiw-flow-side">
13
+ <div class="hiw-flow-connector hiw-flow-connector--before"></div>
14
+ <div class="hiw-flow-dot" aria-hidden="true">${dot}</div>
15
+ <div class="hiw-flow-connector hiw-flow-connector--after"></div>
16
+ </div>
17
+ <div class="hiw-flow-main">
18
+ <span class="hiw-flow-label">${label}</span>
19
+ <div class="hiw-flow-body">${content}</div>
20
+ </div>
21
+ </li>
22
+ `
23
+
24
+ const agentFlow = `<ol class="hiw-flow">${[
9
25
  {
10
26
  dot: '1',
11
- dotColor: 'accent',
12
27
  label: 'Understand',
13
28
  content: card({ content: `<strong style="color:var(--ui-text)">Read the guide and inspect the project</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent fetches <code>pulse://workflow</code> and the relevant <code>pulse://guide/*</code> sections, then calls <code>pulse_list_structure</code> to see every existing page, component, and store. Ambiguities are surfaced before any files are touched.</p>` }),
14
29
  },
15
30
  {
16
31
  dot: '2',
17
- dotColor: 'accent',
18
32
  label: 'Plan',
19
33
  content: card({ content: `<strong style="color:var(--ui-text)">Present a plan — wait for confirmation</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Before writing anything the agent describes what it intends to build: the route, state shape, server data, interactions, and any components or integrations it will use. The task does not proceed until you confirm.</p>` }),
20
34
  },
21
35
  {
22
36
  dot: '3',
23
- dotColor: 'accent',
24
37
  label: 'Build',
25
38
  content: card({ content: `<strong style="color:var(--ui-text)">Write the spec and any supporting files</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The spec is written as a plain JS object: route, state, server data, mutations, actions, view. The guide constrains every decision — where state lives, how validation is wired, how the view is structured.</p>` }),
26
39
  },
27
40
  {
28
41
  dot: '4',
29
- dotColor: 'accent',
30
42
  label: 'Validate',
31
43
  content: card({ content: `<strong style="color:var(--ui-text)">Call <code>pulse_validate</code> — fix all errors and warnings</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The spec is checked against the Pulse schema. Every error and warning is resolved before moving on — missing hydrate, heading order violations, missing escaping, structural mistakes. A clean output is the gate to the next phase.</p>` }),
32
44
  },
33
45
  {
34
46
  dot: '5',
35
- dotColor: 'accent',
36
47
  label: 'Browser',
37
48
  content: card({ content: `<strong style="color:var(--ui-text)">Screenshot + Lighthouse — desktop and mobile</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent navigates to the route, takes a screenshot to confirm the rendered output, then runs Lighthouse on both desktop and mobile. Accessibility, Best Practices, and SEO must all be 100. Any failure is fixed and re-verified before continuing.</p>` }),
38
49
  },
39
50
  {
40
51
  dot: '6',
41
- dotColor: 'accent',
42
52
  label: 'Tests',
43
53
  content: card({ content: `<strong style="color:var(--ui-text)">Write tests, run them, fix failures</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Unit tests cover any pure logic extracted from the spec. View tests use <code>renderSync</code> / <code>render</code> to assert HTML output. All tests must pass. When fixing a bug, a failing test is written first to pin the behaviour.</p>` }),
44
54
  },
45
55
  {
46
56
  dot: '7',
47
- dotColor: 'accent',
48
57
  label: 'Review',
49
58
  content: card({ content: `<strong style="color:var(--ui-text)">Call <code>pulse_review</code> — only after phases 4–6 all pass</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent switches into reviewer mode — reading the source and rendered output against the full spec checklist. Accessibility, empty states, error handling, component usage, and security are all checked. The review agent is always last.</p>` }),
50
59
  },
51
60
  {
52
61
  dot: '8',
53
- dotColor: 'accent',
54
62
  label: 'Fix and re-verify',
55
63
  content: card({ content: `<strong style="color:var(--ui-text)">Fix every review issue — re-run affected gates</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Every issue raised in review is resolved. Validate, Lighthouse, and tests are re-run to confirm all gates still pass. The task is complete only when every phase clears cleanly.</p>` }),
56
64
  },
57
65
  {
58
66
  dot: '✓',
59
- dotColor: 'success',
60
67
  label: 'Done',
61
68
  content: card({ content: `<strong style="color:var(--ui-text)">The spec is the source of truth</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Validate clean. Lighthouse 100. Tests passing. Review clear. When all four gates pass, the page is done.</p>` }),
62
69
  },
63
- ],
64
- })
70
+ ].map(flowStep).join('')}</ol>`
65
71
 
66
72
  export default {
67
73
  route: '/how-it-works',
68
74
  meta: {
75
+ theme: 'light',
69
76
  title: 'How It Works — Pulse Docs',
70
77
  description: 'How the Pulse MCP server gives an AI agent the knowledge and tools to build Pulse apps correctly.',
71
- styles: ['/pulse-ui.css', '/docs.css'],
78
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
72
79
  },
73
80
  view: () => renderLayout({
74
81
  currentHref: '/how-it-works',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/hydration')
7
7
  export default {
8
8
  route: '/hydration',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Hydration — Pulse Docs',
11
12
  description: 'How Pulse hydrates server-rendered HTML on the client — automatic hydration, mount(), and production bundles.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/images')
7
7
  export default {
8
8
  route: '/images',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Images — Pulse Docs',
11
12
  description: 'The img() and picture() helpers for optimised, CLS-free image markup.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/images',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/markdown')
7
7
  export default {
8
8
  route: '/markdown',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Markdown — Pulse Docs',
11
12
  description: 'Render markdown files as pages with syntax-highlighted code blocks, frontmatter, and the prose component.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/markdown',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/meta')
7
7
  export default {
8
8
  route: '/meta',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Metadata & SEO — Pulse Docs',
11
12
  description: 'How to configure page metadata, Open Graph tags, and structured data in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/meta',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/mutations')
7
7
  export default {
8
8
  route: '/mutations',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Mutations — Pulse Docs',
11
12
  description: 'Synchronous state changes in Pulse — how to declare and trigger mutations.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/navigation')
7
7
  export default {
8
8
  route: '/navigation',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Navigation — Pulse Docs',
11
12
  description: 'Client-side navigation in Pulse — how link interception, JSON responses, and spec re-mounting work.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/navigation',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/performance')
7
7
  export default {
8
8
  route: '/performance',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Performance — Pulse Docs',
11
12
  description: 'Performance targets, techniques, and built-in optimisations in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/performance',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/persist')
7
7
  export default {
8
8
  route: '/persist',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Persist — Pulse Docs',
11
12
  description: 'Persist client state across page refreshes using localStorage.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/project-structure')
7
7
  export default {
8
8
  route: '/project-structure',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Project Structure — Pulse Docs',
11
12
  description: 'Recommended directory layout for a Pulse application.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/project-structure',
@@ -25,9 +25,10 @@ function promptGroup(title, cards) {
25
25
  export default {
26
26
  route: '/prompt-examples',
27
27
  meta: {
28
+ theme: 'light',
28
29
  title: 'Prompt Examples — Pulse Docs',
29
30
  description: 'Real prompts for building Pulse pages with your AI agent — from creating pages to authentication, performance audits, and integrations.',
30
- styles: ['/docs.css'],
31
+ styles: ['/theme.css', '/docs.css'],
31
32
  },
32
33
  view: () => renderLayout({
33
34
  currentHref: '/prompt-examples',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/raw-responses')
7
7
  export default {
8
8
  route: '/raw-responses',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Raw Responses — Pulse Docs',
11
12
  description: 'Return non-HTML responses from Pulse specs — RSS, XML, JSON, and other content types.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/raw-responses',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/routing')
7
7
  export default {
8
8
  route: '/routing',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Routing — Pulse Docs',
11
12
  description: 'How Pulse routes requests to page specs — static and dynamic routes, params, and conventions.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/routing',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/server-api')
7
7
  export default {
8
8
  route: '/server-api',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Server API — Pulse Docs',
11
12
  description: 'Complete reference for createServer — all options, hooks, and response behaviour.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/server-api',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/server-data')
7
7
  export default {
8
8
  route: '/server-data',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Server Data — Pulse Docs',
11
12
  description: 'Fetch, transform, and combine data on the server before rendering — external APIs, multiple fetchers, parallel requests.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/server-data',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/slash-commands')
7
7
  export default {
8
8
  route: '/slash-commands',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Slash Commands — Pulse Docs',
11
12
  description: 'The built-in slash commands available in the Pulse AI agent session.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/slash-commands',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/spec')
7
7
  export default {
8
8
  route: '/spec',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Spec Reference — Pulse Docs',
11
12
  description: 'Complete reference for every field in a Pulse page spec.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/state')
7
7
  export default {
8
8
  route: '/state',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'State — Pulse Docs',
11
12
  description: 'How client state is declared, initialised, and used in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/store')
7
7
  export default {
8
8
  route: '/store',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Global Store — Pulse Docs',
11
12
  description: 'Share server-fetched data across pages with a global store in Pulse.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/streaming')
7
7
  export default {
8
8
  route: '/streaming',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Streaming SSR — Pulse Docs',
11
12
  description: 'How streaming server-side rendering works in Pulse — shell, deferred segments, and when to use it.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/streaming',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/stripe')
7
7
  export default {
8
8
  route: '/stripe',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Payments (Stripe) — Pulse Docs',
11
12
  description: 'Integrating Stripe Checkout and webhooks with Pulse using actions, raw response specs, and server data fetchers.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/supabase')
7
7
  export default {
8
8
  route: '/supabase',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Supabase — Pulse Docs',
11
12
  description: 'Integrate Supabase database queries, authentication, and file storage with Pulse server fetchers, actions, and guard.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  state: {},
15
16
  view: () => renderLayout({