@invisibleloop/pulse 0.20.4 → 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/.github/workflows/ci.yml +3 -0
- 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
|
@@ -327,6 +327,29 @@ h1, h2, h3, h4, h5, h6,
|
|
|
327
327
|
margin-bottom: var(--ui-space-4);
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
/* Review cards — replaces the removed testimonial() component */
|
|
331
|
+
.rw-review-stars {
|
|
332
|
+
display: flex;
|
|
333
|
+
gap: 2px;
|
|
334
|
+
color: var(--rw-orange-dark);
|
|
335
|
+
margin-bottom: var(--ui-space-3);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.rw-review-quote {
|
|
339
|
+
font-style: italic;
|
|
340
|
+
color: var(--ui-text);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.rw-review-name {
|
|
344
|
+
font-family: var(--ui-font-display);
|
|
345
|
+
font-weight: 900;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.rw-review-role {
|
|
349
|
+
font-size: var(--ui-text-sm);
|
|
350
|
+
color: var(--ui-muted);
|
|
351
|
+
}
|
|
352
|
+
|
|
330
353
|
.rw-service-price {
|
|
331
354
|
font-family: 'Courier New', monospace;
|
|
332
355
|
font-size: var(--ui-text-sm);
|
package/docs/public/shop.css
CHANGED
|
@@ -41,7 +41,7 @@ body {
|
|
|
41
41
|
padding: var(--ui-space-16) var(--ui-space-6) var(--ui-space-8);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
.product-display .
|
|
44
|
+
.product-display .product-display-title {
|
|
45
45
|
font-size: clamp(3rem, 10vw, 8rem);
|
|
46
46
|
line-height: 1;
|
|
47
47
|
letter-spacing: -0.04em;
|
|
@@ -49,6 +49,40 @@ body {
|
|
|
49
49
|
color: var(--ui-text);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/* Section eyebrow + rule — replaces the removed sectionLabel() component */
|
|
53
|
+
.shop-section-label {
|
|
54
|
+
margin-bottom: var(--ui-space-6);
|
|
55
|
+
}
|
|
56
|
+
.shop-section-label-eyebrow {
|
|
57
|
+
font-size: var(--ui-text-sm);
|
|
58
|
+
letter-spacing: 0.1em;
|
|
59
|
+
text-transform: uppercase;
|
|
60
|
+
font-weight: 600;
|
|
61
|
+
color: var(--ui-color-muted);
|
|
62
|
+
margin-bottom: var(--ui-space-2);
|
|
63
|
+
}
|
|
64
|
+
.shop-section-label-heading {
|
|
65
|
+
margin-bottom: var(--ui-space-3);
|
|
66
|
+
}
|
|
67
|
+
.shop-section-label-rule {
|
|
68
|
+
border: none;
|
|
69
|
+
border-top: 1px solid var(--ui-border);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* End-of-page metadata — replaces the removed colophon() component */
|
|
73
|
+
.shop-colophon {
|
|
74
|
+
padding: var(--ui-space-8) var(--ui-space-6);
|
|
75
|
+
text-align: center;
|
|
76
|
+
border-top: 1px solid var(--ui-border);
|
|
77
|
+
}
|
|
78
|
+
.shop-colophon-inner {
|
|
79
|
+
font-size: var(--ui-text-sm);
|
|
80
|
+
color: var(--ui-color-muted);
|
|
81
|
+
}
|
|
82
|
+
.shop-colophon-inner a {
|
|
83
|
+
color: inherit;
|
|
84
|
+
}
|
|
85
|
+
|
|
52
86
|
.product-display .product-tagline {
|
|
53
87
|
margin-top: var(--ui-space-4);
|
|
54
88
|
font-size: var(--ui-text-xl);
|
package/docs/public/sparkys.css
CHANGED
|
@@ -41,17 +41,23 @@ body {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/* ── Top utility strip ─────────────────────────────────────────────────── */
|
|
44
|
-
/*
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
/* raw two-column bar — replaces the removed topStrip() component */
|
|
45
|
+
.top-strip {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
gap: var(--ui-space-4);
|
|
50
|
+
padding: var(--ui-space-2) var(--ui-space-6);
|
|
51
|
+
background: var(--brand-navy-deep);
|
|
52
|
+
color: var(--brand-white);
|
|
53
|
+
font-size: var(--ui-text-sm);
|
|
48
54
|
}
|
|
49
|
-
.
|
|
55
|
+
.top-strip a {
|
|
50
56
|
color: inherit;
|
|
51
57
|
text-decoration: none;
|
|
52
58
|
font-weight: 600;
|
|
53
59
|
}
|
|
54
|
-
.
|
|
60
|
+
.top-strip a:hover { text-decoration: underline; }
|
|
55
61
|
|
|
56
62
|
/* ── Hero ──────────────────────────────────────────────────────────────── */
|
|
57
63
|
.hero-split {
|
|
@@ -105,10 +111,23 @@ body {
|
|
|
105
111
|
color: var(--ui-muted);
|
|
106
112
|
font-weight: 600;
|
|
107
113
|
}
|
|
108
|
-
/*
|
|
109
|
-
.
|
|
114
|
+
/* trust-inline list — replaces the removed trustList() component */
|
|
115
|
+
.trust-inline {
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-wrap: wrap;
|
|
118
|
+
gap: var(--ui-space-5);
|
|
119
|
+
list-style: none;
|
|
120
|
+
}
|
|
121
|
+
.trust-inline__item {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: var(--ui-space-2);
|
|
110
125
|
font-weight: 600;
|
|
111
126
|
}
|
|
127
|
+
.trust-inline__icon {
|
|
128
|
+
display: inline-flex;
|
|
129
|
+
color: var(--brand-amber);
|
|
130
|
+
}
|
|
112
131
|
|
|
113
132
|
.hero-split__panel {
|
|
114
133
|
background: linear-gradient(160deg, var(--ui-accent) 0%, var(--brand-navy-deep) 100%);
|
|
@@ -198,22 +217,29 @@ body {
|
|
|
198
217
|
color: var(--ui-muted);
|
|
199
218
|
}
|
|
200
219
|
|
|
201
|
-
/* ── Services grid —
|
|
202
|
-
.
|
|
220
|
+
/* ── Services grid — card() component with a bordered service-card look ─── */
|
|
221
|
+
.service-card {
|
|
222
|
+
border: 1px solid var(--ui-border);
|
|
223
|
+
box-shadow: none;
|
|
224
|
+
}
|
|
225
|
+
.service-card .ui-service-card-icon {
|
|
226
|
+
width: 44px;
|
|
227
|
+
height: 44px;
|
|
228
|
+
border-radius: var(--ui-radius-md);
|
|
229
|
+
background: var(--ui-accent-dim);
|
|
230
|
+
color: var(--ui-accent);
|
|
203
231
|
display: grid;
|
|
204
|
-
|
|
205
|
-
|
|
232
|
+
place-items: center;
|
|
233
|
+
margin-bottom: var(--ui-space-4);
|
|
206
234
|
}
|
|
207
|
-
|
|
208
|
-
.services .ui-service-card-title {
|
|
235
|
+
.service-card .ui-service-card-title {
|
|
209
236
|
font-size: var(--ui-text-xl);
|
|
210
237
|
font-weight: 700;
|
|
238
|
+
margin-bottom: var(--ui-space-2);
|
|
211
239
|
}
|
|
212
|
-
.
|
|
240
|
+
.service-card .ui-service-card-desc {
|
|
213
241
|
font-size: var(--ui-text-base);
|
|
214
|
-
|
|
215
|
-
.services .ui-service-card--linked:hover {
|
|
216
|
-
transform: translateY(-2px);
|
|
242
|
+
color: var(--ui-muted);
|
|
217
243
|
}
|
|
218
244
|
|
|
219
245
|
/* ── Why grid ──────────────────────────────────────────────────────────── */
|
|
@@ -295,17 +321,24 @@ body {
|
|
|
295
321
|
flex-direction: column;
|
|
296
322
|
gap: var(--ui-space-3);
|
|
297
323
|
}
|
|
298
|
-
|
|
324
|
+
/* contact-inline list — replaces the removed contactRow() component */
|
|
325
|
+
.contact-inline {
|
|
326
|
+
display: flex;
|
|
299
327
|
flex-direction: column;
|
|
328
|
+
gap: var(--ui-space-3);
|
|
329
|
+
list-style: none;
|
|
300
330
|
}
|
|
301
|
-
.contact-
|
|
331
|
+
.contact-inline__item {
|
|
332
|
+
display: flex;
|
|
333
|
+
align-items: center;
|
|
334
|
+
gap: var(--ui-space-3);
|
|
302
335
|
color: var(--brand-white);
|
|
303
336
|
font-weight: 600;
|
|
304
337
|
font-size: var(--ui-text-lg);
|
|
305
338
|
}
|
|
306
|
-
.contact-
|
|
307
|
-
.contact-
|
|
308
|
-
.contact-
|
|
339
|
+
.contact-inline__item a { color: var(--brand-white); text-decoration: none; }
|
|
340
|
+
.contact-inline__item a:hover { color: var(--brand-amber-strong); }
|
|
341
|
+
.contact-inline__icon {
|
|
309
342
|
width: 36px;
|
|
310
343
|
height: 36px;
|
|
311
344
|
border-radius: 50%;
|
package/docs/server.js
CHANGED
|
@@ -76,7 +76,6 @@ await createServer(
|
|
|
76
76
|
new URL('./src/pages/components/button.js', import.meta.url),
|
|
77
77
|
new URL('./src/pages/components/card.js', import.meta.url),
|
|
78
78
|
new URL('./src/pages/components/checkbox.js', import.meta.url),
|
|
79
|
-
new URL('./src/pages/components/carousel.js', import.meta.url),
|
|
80
79
|
new URL('./src/pages/components/charts.js', import.meta.url),
|
|
81
80
|
new URL('./src/pages/components/empty.js', import.meta.url),
|
|
82
81
|
new URL('./src/pages/components/fieldset.js', import.meta.url),
|
|
@@ -84,12 +83,8 @@ await createServer(
|
|
|
84
83
|
new URL('./src/pages/components/heading.js', import.meta.url),
|
|
85
84
|
new URL('./src/pages/components/icons.js', import.meta.url),
|
|
86
85
|
new URL('./src/pages/components/image.js', import.meta.url),
|
|
87
|
-
new URL('./src/pages/components/gallery.js', import.meta.url),
|
|
88
86
|
new URL('./src/pages/components/input.js', import.meta.url),
|
|
89
|
-
new URL('./src/pages/components/list.js', import.meta.url),
|
|
90
|
-
new URL('./src/pages/components/marquee.js', import.meta.url),
|
|
91
87
|
new URL('./src/pages/components/modal.js', import.meta.url),
|
|
92
|
-
new URL('./src/pages/components/photo-card.js', import.meta.url),
|
|
93
88
|
new URL('./src/pages/components/progress.js', import.meta.url),
|
|
94
89
|
new URL('./src/pages/components/prose.js', import.meta.url),
|
|
95
90
|
new URL('./src/pages/components/pullquote.js', import.meta.url),
|
|
@@ -104,7 +99,6 @@ await createServer(
|
|
|
104
99
|
new URL('./src/pages/components/stepper.js', import.meta.url),
|
|
105
100
|
new URL('./src/pages/components/table.js', import.meta.url),
|
|
106
101
|
new URL('./src/pages/components/textarea.js', import.meta.url),
|
|
107
|
-
new URL('./src/pages/components/timeline.js', import.meta.url),
|
|
108
102
|
new URL('./src/pages/components/toggle.js', import.meta.url),
|
|
109
103
|
new URL('./src/pages/components/tooltip.js', import.meta.url),
|
|
110
104
|
// Landing Components
|
|
@@ -115,8 +109,6 @@ await createServer(
|
|
|
115
109
|
new URL('./src/pages/components/hero.js', import.meta.url),
|
|
116
110
|
new URL('./src/pages/components/nav.js', import.meta.url),
|
|
117
111
|
new URL('./src/pages/components/phone-frame.js', import.meta.url),
|
|
118
|
-
new URL('./src/pages/components/pricing.js', import.meta.url),
|
|
119
|
-
new URL('./src/pages/components/testimonial.js', import.meta.url),
|
|
120
112
|
// Templates
|
|
121
113
|
new URL('./src/pages/templates.js', import.meta.url),
|
|
122
114
|
new URL('./src/pages/templates/mobile-app.js', import.meta.url),
|
|
@@ -131,11 +123,8 @@ await createServer(
|
|
|
131
123
|
new URL('./src/pages/templates/journey.js', import.meta.url),
|
|
132
124
|
new URL('./src/pages/templates/shop.js', import.meta.url),
|
|
133
125
|
// Layout Components
|
|
134
|
-
new URL('./src/pages/components/banner.js', import.meta.url),
|
|
135
126
|
new URL('./src/pages/components/cluster.js', import.meta.url),
|
|
136
|
-
new URL('./src/pages/components/code-window.js', import.meta.url),
|
|
137
127
|
new URL('./src/pages/components/container.js', import.meta.url),
|
|
138
|
-
new URL('./src/pages/components/decorate.js', import.meta.url),
|
|
139
128
|
new URL('./src/pages/components/divider.js', import.meta.url),
|
|
140
129
|
new URL('./src/pages/components/footer.js', import.meta.url),
|
|
141
130
|
new URL('./src/pages/components/grid.js', import.meta.url),
|
package/docs/src/lib/nav.js
CHANGED
|
@@ -84,7 +84,6 @@ export const NAV = [
|
|
|
84
84
|
{ label: 'Button', href: '/components/button' },
|
|
85
85
|
{ label: 'Card', href: '/components/card' },
|
|
86
86
|
{ label: 'Checkbox', href: '/components/checkbox' },
|
|
87
|
-
{ label: 'Carousel', href: '/components/carousel' },
|
|
88
87
|
{ label: 'Charts', href: '/components/charts' },
|
|
89
88
|
{ label: 'Empty', href: '/components/empty' },
|
|
90
89
|
{ label: 'Fieldset', href: '/components/fieldset' },
|
|
@@ -92,12 +91,8 @@ export const NAV = [
|
|
|
92
91
|
{ label: 'Heading', href: '/components/heading' },
|
|
93
92
|
{ label: 'Icons', href: '/components/icons' },
|
|
94
93
|
{ label: 'Image', href: '/components/image' },
|
|
95
|
-
{ label: 'Gallery', href: '/components/gallery' },
|
|
96
94
|
{ label: 'Input', href: '/components/input' },
|
|
97
|
-
{ label: 'List', href: '/components/list' },
|
|
98
|
-
{ label: 'Marquee', href: '/components/marquee' },
|
|
99
95
|
{ label: 'Modal', href: '/components/modal' },
|
|
100
|
-
{ label: 'Photo Card', href: '/components/photo-card' },
|
|
101
96
|
{ label: 'Progress', href: '/components/progress' },
|
|
102
97
|
{ label: 'Prose', href: '/components/prose' },
|
|
103
98
|
{ label: 'Pullquote', href: '/components/pullquote' },
|
|
@@ -112,7 +107,6 @@ export const NAV = [
|
|
|
112
107
|
{ label: 'Stepper', href: '/components/stepper' },
|
|
113
108
|
{ label: 'Table', href: '/components/table' },
|
|
114
109
|
{ label: 'Textarea', href: '/components/textarea' },
|
|
115
|
-
{ label: 'Timeline', href: '/components/timeline' },
|
|
116
110
|
{ label: 'Toggle', href: '/components/toggle' },
|
|
117
111
|
{ label: 'Tooltip', href: '/components/tooltip' },
|
|
118
112
|
],
|
|
@@ -127,18 +121,13 @@ export const NAV = [
|
|
|
127
121
|
{ label: 'Hero', href: '/components/hero' },
|
|
128
122
|
{ label: 'Nav', href: '/components/nav' },
|
|
129
123
|
{ label: 'Phone Frame', href: '/components/phone-frame' },
|
|
130
|
-
{ label: 'Pricing', href: '/components/pricing' },
|
|
131
|
-
{ label: 'Testimonial', href: '/components/testimonial' },
|
|
132
124
|
],
|
|
133
125
|
},
|
|
134
126
|
{
|
|
135
127
|
section: 'Layout Components',
|
|
136
128
|
items: [
|
|
137
|
-
{ label: 'Banner', href: '/components/banner' },
|
|
138
129
|
{ label: 'Cluster', href: '/components/cluster' },
|
|
139
|
-
{ label: 'Code Window', href: '/components/code-window' },
|
|
140
130
|
{ label: 'Container', href: '/components/container' },
|
|
141
|
-
{ label: 'Decorate', href: '/components/decorate' },
|
|
142
131
|
{ label: 'Divider', href: '/components/divider' },
|
|
143
132
|
{ label: 'Footer', href: '/components/footer' },
|
|
144
133
|
{ label: 'Grid', href: '/components/grid' },
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { renderComponentPage, demo } from '../../lib/component-page.js'
|
|
2
2
|
import { prevNext } from '../../lib/nav.js'
|
|
3
3
|
import { table } from '../../lib/layout.js'
|
|
4
|
-
import {
|
|
4
|
+
import { stat, card, grid } from '../../../../src/ui/index.js'
|
|
5
|
+
import { barChart, lineChart, donutChart, sparkline } from '../../../../src/ui/charts.js'
|
|
5
6
|
|
|
6
7
|
const { prev, next } = prevNext('/components/charts')
|
|
7
8
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { renderComponentPage, demo } from '../../lib/component-page.js'
|
|
2
2
|
import { prevNext } from '../../lib/nav.js'
|
|
3
3
|
import { table } from '../../lib/layout.js'
|
|
4
|
-
import { grid, card, stat, feature
|
|
4
|
+
import { grid, card, stat, feature } from '../../../../src/ui/index.js'
|
|
5
5
|
|
|
6
6
|
const { prev, next } = prevNext('/components/grid')
|
|
7
7
|
|
|
@@ -96,18 +96,22 @@ export default {
|
|
|
96
96
|
)}
|
|
97
97
|
|
|
98
98
|
<h3 class="doc-h3">Testimonial grid</h3>
|
|
99
|
+
<p>There is no dedicated <code>testimonial</code> component — build one with <code>card()</code>: the quote in <code>content</code>, the name and role in <code>footer</code>.</p>
|
|
99
100
|
${demo(
|
|
100
101
|
grid({
|
|
101
102
|
cols: 3,
|
|
102
103
|
content: [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
card({ content: `<p style="color:var(--muted);margin:0">“Shipped our redesign in a weekend. No boilerplate, no config hell.”</p>`, footer: `<strong>Alex Morgan</strong><br><span style="color:var(--muted)">CTO at Launchpad</span>` }),
|
|
105
|
+
card({ content: `<p style="color:var(--muted);margin:0">“The streaming SSR makes our pages feel instant. Lighthouse is happy.”</p>`, footer: `<strong>Sara Kim</strong><br><span style="color:var(--muted)">Lead Engineer, Orbit</span>` }),
|
|
106
|
+
card({ content: `<p style="color:var(--muted);margin:0">“Finally a UI kit that doesn\'t fight the platform. Just HTML.”</p>`, footer: `<strong>Dan Okafor</strong><br><span style="color:var(--muted)">Founder, Stackly</span>` }),
|
|
106
107
|
].join(''),
|
|
107
108
|
}),
|
|
108
109
|
`grid({
|
|
109
110
|
cols: 3,
|
|
110
|
-
content: testimonials.map(t =>
|
|
111
|
+
content: testimonials.map(t => card({
|
|
112
|
+
content: \`<p>\${t.quote}</p>\`,
|
|
113
|
+
footer: \`<strong>\${t.name}</strong><br>\${t.role}\`,
|
|
114
|
+
})).join(''),
|
|
111
115
|
})`
|
|
112
116
|
)}
|
|
113
117
|
|
|
@@ -94,8 +94,6 @@ export default {
|
|
|
94
94
|
['<a href="/components/hero">hero</a>', 'Full-width hero section with eyebrow, title, and actions.'],
|
|
95
95
|
['<a href="/components/app-badge">appBadge</a>', 'App Store / Google Play download badge.'],
|
|
96
96
|
['<a href="/components/feature">feature</a>', 'Icon + title + description block for feature grids.'],
|
|
97
|
-
['<a href="/components/testimonial">testimonial</a>', 'Customer quote with avatar and star rating.'],
|
|
98
|
-
['<a href="/components/pricing">pricing</a>', 'Plan card with feature list and CTA. Supports highlighted state.'],
|
|
99
97
|
['<a href="/components/accordion">accordion</a>', 'Collapsible FAQ items — no JS, native <code><details></code>.'],
|
|
100
98
|
['<a href="/components/cta">cta</a>', 'Call-to-action block with eyebrow, heading, body, and actions slot.'],
|
|
101
99
|
]
|
|
@@ -111,9 +109,7 @@ export default {
|
|
|
111
109
|
['<a href="/components/stack">stack</a>', 'Flex column with consistent vertical gap.'],
|
|
112
110
|
['<a href="/components/cluster">cluster</a>', 'Flex row with wrapping — for badges, buttons, etc.'],
|
|
113
111
|
['<a href="/components/divider">divider</a>', 'Horizontal rule, optionally with centred label.'],
|
|
114
|
-
['<a href="/components/banner">banner</a>', 'Full-width announcement bar above the nav.'],
|
|
115
112
|
['<a href="/components/media">media</a>', 'Two-column image + text layout, stacks on mobile.'],
|
|
116
|
-
['<a href="/components/code-window">codeWindow</a>', 'macOS window chrome around a code block. Accepts pre-highlighted HTML.'],
|
|
117
113
|
['<a href="/components/footer">footer</a>', 'Site footer with logo, nav links, and legal text. Stacks on mobile.'],
|
|
118
114
|
]
|
|
119
115
|
)}
|
package/docs/src/pages/home.js
CHANGED
|
@@ -2,9 +2,24 @@
|
|
|
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 {
|
|
@@ -1,67 +1,73 @@
|
|
|
1
1
|
import { renderLayout, h1, lead, section, callout } from '../lib/layout.js'
|
|
2
2
|
import { prevNext } from '../lib/nav.js'
|
|
3
|
-
import {
|
|
3
|
+
import { card } from '../../../src/ui/index.js'
|
|
4
4
|
|
|
5
5
|
const { prev, next } = prevNext('/how-it-works')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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',
|