@invisibleloop/pulse 0.20.6 → 0.20.8

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 (94) hide show
  1. package/AGENTS.md +697 -0
  2. package/docs/public/docs.css +6 -6
  3. package/docs/public/home-brut.css +175 -191
  4. package/docs/public/theme.css +51 -7
  5. package/docs/src/lib/component-page.js +2 -1
  6. package/docs/src/pages/accessibility.js +2 -1
  7. package/docs/src/pages/actions.js +2 -1
  8. package/docs/src/pages/auth.js +2 -1
  9. package/docs/src/pages/caching.js +2 -1
  10. package/docs/src/pages/components/accordion.js +2 -1
  11. package/docs/src/pages/components/alert.js +2 -1
  12. package/docs/src/pages/components/app-badge.js +2 -1
  13. package/docs/src/pages/components/avatar.js +2 -1
  14. package/docs/src/pages/components/badge.js +2 -1
  15. package/docs/src/pages/components/breadcrumbs.js +2 -1
  16. package/docs/src/pages/components/button.js +2 -1
  17. package/docs/src/pages/components/card.js +2 -1
  18. package/docs/src/pages/components/charts.js +2 -1
  19. package/docs/src/pages/components/checkbox.js +2 -1
  20. package/docs/src/pages/components/cluster.js +2 -1
  21. package/docs/src/pages/components/container.js +2 -1
  22. package/docs/src/pages/components/cta.js +2 -1
  23. package/docs/src/pages/components/divider.js +2 -1
  24. package/docs/src/pages/components/empty.js +2 -1
  25. package/docs/src/pages/components/feature.js +2 -1
  26. package/docs/src/pages/components/fieldset.js +2 -1
  27. package/docs/src/pages/components/fileupload.js +2 -1
  28. package/docs/src/pages/components/footer.js +2 -1
  29. package/docs/src/pages/components/grid.js +2 -1
  30. package/docs/src/pages/components/heading.js +2 -1
  31. package/docs/src/pages/components/hero.js +2 -1
  32. package/docs/src/pages/components/icons.js +2 -1
  33. package/docs/src/pages/components/image.js +2 -1
  34. package/docs/src/pages/components/input.js +2 -1
  35. package/docs/src/pages/components/media.js +2 -1
  36. package/docs/src/pages/components/modal.js +2 -1
  37. package/docs/src/pages/components/nav.js +2 -1
  38. package/docs/src/pages/components/phone-frame.js +2 -1
  39. package/docs/src/pages/components/progress.js +2 -1
  40. package/docs/src/pages/components/prose.js +2 -1
  41. package/docs/src/pages/components/pullquote.js +2 -1
  42. package/docs/src/pages/components/radio.js +2 -1
  43. package/docs/src/pages/components/rating.js +2 -1
  44. package/docs/src/pages/components/search.js +2 -1
  45. package/docs/src/pages/components/section.js +2 -1
  46. package/docs/src/pages/components/segmented.js +2 -1
  47. package/docs/src/pages/components/select.js +2 -1
  48. package/docs/src/pages/components/slider.js +2 -1
  49. package/docs/src/pages/components/spinner.js +2 -1
  50. package/docs/src/pages/components/stack.js +2 -1
  51. package/docs/src/pages/components/stat.js +2 -1
  52. package/docs/src/pages/components/stepper.js +2 -1
  53. package/docs/src/pages/components/table.js +2 -1
  54. package/docs/src/pages/components/textarea.js +2 -1
  55. package/docs/src/pages/components/toggle.js +2 -1
  56. package/docs/src/pages/components/tooltip.js +2 -1
  57. package/docs/src/pages/components.js +2 -1
  58. package/docs/src/pages/config.js +2 -1
  59. package/docs/src/pages/constraints.js +2 -1
  60. package/docs/src/pages/deploy.js +2 -1
  61. package/docs/src/pages/error-pages.js +2 -1
  62. package/docs/src/pages/extending.js +2 -1
  63. package/docs/src/pages/faq.js +2 -1
  64. package/docs/src/pages/forms.js +2 -1
  65. package/docs/src/pages/getting-started.js +2 -1
  66. package/docs/src/pages/guard.js +2 -1
  67. package/docs/src/pages/home.js +8 -14
  68. package/docs/src/pages/how-it-works.js +2 -1
  69. package/docs/src/pages/hydration.js +2 -1
  70. package/docs/src/pages/images.js +2 -1
  71. package/docs/src/pages/markdown.js +2 -1
  72. package/docs/src/pages/meta.js +2 -1
  73. package/docs/src/pages/mutations.js +2 -1
  74. package/docs/src/pages/navigation.js +2 -1
  75. package/docs/src/pages/performance.js +2 -1
  76. package/docs/src/pages/persist.js +2 -1
  77. package/docs/src/pages/project-structure.js +2 -1
  78. package/docs/src/pages/prompt-examples.js +2 -1
  79. package/docs/src/pages/raw-responses.js +2 -1
  80. package/docs/src/pages/routing.js +2 -1
  81. package/docs/src/pages/server-api.js +2 -1
  82. package/docs/src/pages/server-data.js +2 -1
  83. package/docs/src/pages/slash-commands.js +2 -1
  84. package/docs/src/pages/spec.js +2 -1
  85. package/docs/src/pages/state.js +2 -1
  86. package/docs/src/pages/store.js +2 -1
  87. package/docs/src/pages/streaming.js +2 -1
  88. package/docs/src/pages/stripe.js +2 -1
  89. package/docs/src/pages/supabase.js +2 -1
  90. package/docs/src/pages/templates.js +2 -2
  91. package/docs/src/pages/testing.js +2 -1
  92. package/docs/src/pages/validation.js +2 -1
  93. package/package.json +1 -1
  94. package/public/.pulse-ui-version +1 -1
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/slider')
8
8
  export default {
9
9
  route: '/components/slider',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Slider — Pulse Docs',
12
13
  description: 'Styled range input slider component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  state: { brightness: 100 },
16
17
  mutations: {
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/spinner')
8
8
  export default {
9
9
  route: '/components/spinner',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Spinner — Pulse Docs',
12
13
  description: 'Loading spinner component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/spinner',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/stack')
8
8
  export default {
9
9
  route: '/components/stack',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Stack — Pulse Docs',
12
13
  description: 'Stack component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/stack',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/stat')
8
8
  export default {
9
9
  route: '/components/stat',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Stat — Pulse Docs',
12
13
  description: 'Stat component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/stat',
@@ -10,9 +10,10 @@ const STEPS = ['Account', 'Details', 'Payment', 'Review']
10
10
  export default {
11
11
  route: '/components/stepper',
12
12
  meta: {
13
+ theme: 'light',
13
14
  title: 'Stepper — Pulse Docs',
14
15
  description: 'Horizontal step progress indicator component for Pulse UI.',
15
- styles: ['/pulse-ui.css', '/docs.css'],
16
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
16
17
  },
17
18
  view: () => renderComponentPage({
18
19
  currentHref: '/components/stepper',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/table')
8
8
  export default {
9
9
  route: '/components/table',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Table — Pulse Docs',
12
13
  description: 'Table component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/table',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components/textarea')
7
7
  export default {
8
8
  route: '/components/textarea',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Textarea — Pulse Docs',
11
12
  description: 'Textarea component for Pulse UI.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderComponentPage({
15
16
  currentHref: '/components/textarea',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/toggle')
8
8
  export default {
9
9
  route: '/components/toggle',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Toggle — Pulse Docs',
12
13
  description: 'iOS-style switch toggle component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/toggle',
@@ -8,9 +8,10 @@ const { prev, next } = prevNext('/components/tooltip')
8
8
  export default {
9
9
  route: '/components/tooltip',
10
10
  meta: {
11
+ theme: 'light',
11
12
  title: 'Tooltip — Pulse Docs',
12
13
  description: 'Tooltip component for Pulse UI.',
13
- styles: ['/pulse-ui.css', '/docs.css'],
14
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
14
15
  },
15
16
  view: () => renderComponentPage({
16
17
  currentHref: '/components/tooltip',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/components')
7
7
  export default {
8
8
  route: '/components',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Component Library — Pulse Docs',
11
12
  description: 'Server-rendered UI components for Pulse — button, card, input, alert, stat, avatar, table and more. Fully accessible, mobile-ready, zero client JS.',
12
- styles: ['/pulse-ui.css', '/docs.css'],
13
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/components',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/config')
7
7
  export default {
8
8
  route: '/config',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Configuration — Pulse Docs',
11
12
  description: 'Full reference for pulse.config.js — port, Lighthouse thresholds, load test config, environments, and per-route overrides.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/config',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/constraints')
7
7
  export default {
8
8
  route: '/constraints',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Constraints — Pulse Docs',
11
12
  description: 'Automatic min/max bounds on state values, enforced after every mutation.',
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('/deploy')
7
7
  export default {
8
8
  route: '/deploy',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Deployment — Pulse Docs',
11
12
  description: 'Deploy a Pulse app to a VPS, Docker, Fly.io, Railway, or Render.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/deploy',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/error-pages')
7
7
  export default {
8
8
  route: '/error-pages',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Error Pages — Pulse Docs',
11
12
  description: 'Custom 404 pages in Pulse. A spec with route "*" renders through the normal pipeline with status 404 whenever no route matches.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/error-pages',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/extending')
7
7
  export default {
8
8
  route: '/extending',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Extending Pulse — Pulse Docs',
11
12
  description: 'Escape hatches for features outside the Pulse spec — onRequest middleware, raw server access, WebSockets, SSE, and custom error handling.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/extending',
@@ -17,9 +17,10 @@ function q(question, answer) {
17
17
  export default {
18
18
  route: '/faq',
19
19
  meta: {
20
+ theme: 'light',
20
21
  title: 'FAQ — Pulse Docs',
21
22
  description: 'Frequently asked questions about the Pulse framework.',
22
- styles: ['/pulse-ui.css', '/docs.css'],
23
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
23
24
  },
24
25
  view: () => renderLayout({
25
26
  currentHref: '/faq',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/forms')
7
7
  export default {
8
8
  route: '/forms',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Forms — Pulse Docs',
11
12
  description: 'Server-side form handling in Pulse. spec.submit processes POST requests without client JavaScript, with automatic CSRF protection and POST-redirect-GET.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/forms',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/getting-started')
7
7
  export default {
8
8
  route: '/getting-started',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Getting Started — Pulse Docs',
11
12
  description: 'Install Pulse and build your first page with an AI agent in minutes.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/getting-started',
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/guard')
7
7
  export default {
8
8
  route: '/guard',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Guard — Pulse Docs',
11
12
  description: 'Per-route authorization in Pulse. Guard functions run before server data fetchers and redirect unauthorized requests.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/guard',
@@ -1,4 +1,4 @@
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'
@@ -55,6 +55,7 @@ export default {
55
55
  meta: {
56
56
  title: 'Pulse — The spec-first web framework',
57
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',
58
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'],
59
60
  schema: {
60
61
  '@context': 'https://schema.org',
@@ -79,7 +80,7 @@ export default {
79
80
  <nav class="brut-nav" aria-label="Site navigation">
80
81
  <a href="/" class="brut-nav-logo" aria-label="Pulse home">
81
82
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
82
- <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"/>
83
84
  </svg>
84
85
  <span>PULSE</span>
85
86
  </a>
@@ -96,20 +97,13 @@ export default {
96
97
  <div class="brut-hero-tag">v${version} — EARLY ACCESS</div>
97
98
  <h1 class="brut-hero-h1">
98
99
  <span class="brut-hero-kicker">with Pulse</span>
99
- <span class="brut-hero-line1">YOU CAN'T</span>
100
- <span class="brut-hero-line2" role="img" aria-label="SHIP">
101
- <svg class="brut-hero-svg" aria-hidden="true">
102
- <text class="brut-hero-svg-text" y="0.82em" dominant-baseline="auto"
103
- font-family="Inter, system-ui, sans-serif" font-weight="900"
104
- fill="var(--brut-yellow)" stroke="var(--brut-ink)" stroke-width="0.055em" paint-order="stroke fill">SHIP</text>
105
- </svg>
106
- </span>
107
- <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>
108
102
  </h1>
109
103
  <div class="brut-hero-aside">
110
104
  <p class="brut-hero-tag-inline">ONE SPEC. ONE WAY TO BUILD.</p>
111
- <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>
112
- <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>
113
107
  <div class="brut-hero-ctas">
114
108
  <a href="/getting-started" class="brut-btn-primary">Get Started</a>
115
109
  <a href="/spec" class="brut-btn-ghost">Read the Spec</a>
@@ -207,7 +201,7 @@ export default {
207
201
  <th></th>
208
202
  <th class="brut-th-pulse">
209
203
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" aria-hidden="true" style="vertical-align:middle;margin-right:.3rem">
210
- <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"/>
211
205
  </svg>PULSE
212
206
  </th>
213
207
  <th>Next.js / Remix</th>
@@ -72,9 +72,10 @@ const agentFlow = `<ol class="hiw-flow">${[
72
72
  export default {
73
73
  route: '/how-it-works',
74
74
  meta: {
75
+ theme: 'light',
75
76
  title: 'How It Works — Pulse Docs',
76
77
  description: 'How the Pulse MCP server gives an AI agent the knowledge and tools to build Pulse apps correctly.',
77
- styles: ['/pulse-ui.css', '/docs.css'],
78
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
78
79
  },
79
80
  view: () => renderLayout({
80
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({
@@ -517,8 +517,8 @@ export default {
517
517
  meta: {
518
518
  title: 'Templates — Pulse',
519
519
  description: 'Production-ready Pulse templates. Every template uses only Pulse UI components and ships with 100/100/100 Lighthouse scores.',
520
- theme: 'dark',
521
- styles: ['/pulse-ui.css', '/docs.css'],
520
+ theme: 'light',
521
+ styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
522
522
  },
523
523
 
524
524
  view: () => {
@@ -7,9 +7,10 @@ const { prev, next } = prevNext('/testing')
7
7
  export default {
8
8
  route: '/testing',
9
9
  meta: {
10
+ theme: 'light',
10
11
  title: 'Testing — Pulse Docs',
11
12
  description: 'Test Pulse view functions with renderSync and render — query the HTML output with CSS-like selectors, no DOM required.',
12
- styles: ['/docs.css'],
13
+ styles: ['/theme.css', '/docs.css'],
13
14
  },
14
15
  view: () => renderLayout({
15
16
  currentHref: '/testing',