@marver-design/marver 0.19.2 → 0.20.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.
- package/CHANGELOG.md +64 -0
- package/README.md +8 -10
- package/dist/{bake-kaf5kGZ7.mjs → bake-tAb0D6Rc.mjs} +1 -1
- package/dist/{build-7ed5H2vT.mjs → build-DwpNPl6Z.mjs} +3 -3
- package/dist/cli.mjs +18 -12
- package/dist/{dev-D3mP2x27.mjs → dev-BjdDP69b.mjs} +3 -3
- package/dist/{init-BQYCS3EU.mjs → init-DKxuRxBr.mjs} +33 -32
- package/dist/{plugin-DI-7NAnx.mjs → plugin-y4Ch7o_A.mjs} +7 -7
- package/dist/{poster-DNh6N27C.mjs → poster-FCv_nXyP.mjs} +1 -1
- package/dist/{publish-bakes-Dp-ZFk3d.mjs → publish-bakes-XH6Bac58.mjs} +8 -2
- package/dist/{shot-DMDvDbeP.mjs → shot-iw3SEcpn.mjs} +7 -7
- package/docs/live-jam.md +1 -1
- package/docs/slides.md +89 -89
- package/docs/sticky-notes.md +9 -0
- package/package.json +1 -1
- package/src/client/const.ts +27 -9
- package/src/client/content/chart.tsx +8 -8
- package/src/client/content/index.tsx +5 -4
- package/src/client/content/slide.tsx +26 -201
- package/src/client/frame-host/main.tsx +10 -0
- package/src/client/shell/Comments.tsx +12 -4
- package/src/client/shell/Play.tsx +26 -14
- package/src/client/shell/Toolbar.tsx +7 -5
- package/src/client/shell/canvas/FrameNode.tsx +16 -2
- package/src/client/shell/store.ts +3 -3
- package/src/client/stage/main.tsx +56 -7
- package/templates/instructions/reference/deck-layouts.md +153 -199
- package/templates/instructions/reference/deck-story.md +6 -6
- package/templates/instructions/slides.md +275 -383
|
@@ -1,342 +1,278 @@
|
|
|
1
|
-
# Slides - decks
|
|
1
|
+
# Slides - decks in code
|
|
2
2
|
|
|
3
3
|
Run this when the work is a DECK: the human asks for slides, a presentation,
|
|
4
4
|
a pitch, a review - or a scene of `slide: true` frames exists. Read
|
|
5
|
-
`design/slides.md` too,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
A slide is an ordinary frame with `slide: true` in its meta
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
stage is the world, and it is always 1280×720 to your code;
|
|
23
|
-
- images and video posters at 2x the box they sit in, so an upscaled fill
|
|
24
|
-
stage stays sharp.
|
|
5
|
+
`design/slides.md` too, always: it holds this project's deck look and house
|
|
6
|
+
habits, and where it disagrees with this file, **the project file wins**.
|
|
7
|
+
|
|
8
|
+
A slide is an ordinary frame with `slide: true` in its meta. That is the
|
|
9
|
+
whole contract. What goes inside is your code - any layout, any typeface,
|
|
10
|
+
any image, any drawing, any animation the browser can render. This file is
|
|
11
|
+
not a rulebook. It is the craft of decks that look made rather than typed,
|
|
12
|
+
the method that gets the argument right before the pixels, and the few
|
|
13
|
+
mechanics of how a slide plays. Take what serves the deck in front of you.
|
|
14
|
+
|
|
15
|
+
| File | When |
|
|
16
|
+
|---|---|
|
|
17
|
+
| reference/deck-story.md | intake is thin or rich, the room is senior, the slide list reads like a table of contents, or the words need work |
|
|
18
|
+
| reference/deck-layouts.md | a slide needs a composition and none comes - an idea bank, plus rebuilding an existing deck and chart craft |
|
|
19
|
+
| craft.md + its references | a slide's type, colour, layout or motion feels off - reference/typography.md, color.md, motion.md and slop.md hold for slides as for screens |
|
|
20
|
+
|
|
21
|
+
## What a slide is
|
|
25
22
|
|
|
26
23
|
```tsx
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export default ()
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
export const meta = { title: 'Onboarding time halved in one quarter', slide: true }
|
|
25
|
+
|
|
26
|
+
export default function Frame() {
|
|
27
|
+
return (
|
|
28
|
+
<main className="dk-page dk-ink dk-statement">
|
|
29
|
+
<h1>Onboarding time<br />halved in one quarter.</h1>
|
|
30
|
+
</main>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
- **The stage.** A slide renders at its stage size: 1280×720 by default.
|
|
36
|
+
Declare a `viewport` (any name in `design/config.ts`, e.g. `'laptop'` for
|
|
37
|
+
1280×800) for another shape, and keep one stage per deck. Compose in px
|
|
38
|
+
at that size: let your root fill the stage (`min-height: 100vh`) and place
|
|
39
|
+
things where you want them.
|
|
40
|
+
- **The host scales, not you.** A slide never reflows: slides mode renders
|
|
41
|
+
the stage and scales the whole of it to the screen - up on a projector,
|
|
42
|
+
down on a laptop or a phone - and a resized canvas node shows it the same
|
|
43
|
+
way, smaller. The document IS the stage, so no breakpoints are needed and
|
|
44
|
+
viewport units are stage units (`100vh` is the stage's height).
|
|
45
|
+
- **On the canvas** a slide is a frame like any other: comments, laser,
|
|
46
|
+
variants, Live Jam, plus the slide badge. The board's reading order (top to
|
|
47
|
+
bottom, left to right) is the play order - drag slides to reorder the deck.
|
|
48
|
+
- **Notes.** `<slide>.note.md` beside the frame is its sticky note - the
|
|
49
|
+
presenter's script and the next agent's memory (the method, below).
|
|
50
|
+
- `<Slide>` from `@marver-design/marver/content` is an optional wrapper that
|
|
51
|
+
fills the frame; earlier decks use it. Nothing requires it.
|
|
52
|
+
|
|
53
|
+
## Motion
|
|
54
|
+
|
|
55
|
+
Code means the motion is yours: CSS keyframes and transitions, SVG
|
|
56
|
+
animation, a JS library the project already uses. Three habits make it play
|
|
57
|
+
well:
|
|
58
|
+
|
|
59
|
+
- **At rest, the finished slide.** On the canvas, in `marver shot`, in a
|
|
60
|
+
thumbnail, the slide shows its final composition. Animate while the deck
|
|
61
|
+
plays: the stage puts `data-sl-play` on `<html>` for the whole show and adds
|
|
62
|
+
`data-sl-entered` once each slide has arrived. Key motion off them:
|
|
63
|
+
|
|
64
|
+
```css
|
|
65
|
+
:root[data-sl-entered] .dk-loop path { animation: dk-draw 900ms ease-out both }
|
|
66
|
+
@keyframes dk-draw { from { stroke-dashoffset: 600 } to { stroke-dashoffset: 0 } }
|
|
67
|
+
@media (prefers-reduced-motion: reduce) {
|
|
68
|
+
:root[data-sl-entered] .dk-loop path { animation: none }
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
In React, `useSlidePlay()` from `/content` says the deck is playing (it
|
|
73
|
+
stays true for the whole show); to start something when THIS slide
|
|
74
|
+
arrives, watch `data-sl-entered` on `<html>` - the stage removes it at
|
|
75
|
+
each swap and sets it again once the new slide has settled.
|
|
76
|
+
- **Between slides, morphs.** Give an element the same
|
|
77
|
+
`view-transition-name` on two adjacent slides and it travels or resizes
|
|
78
|
+
between them; the rest crossfades. A persistent element (the mark, a
|
|
79
|
+
diagram that grows) reads as continuity; a hard cut (no shared names)
|
|
80
|
+
reads as a new chapter. One duration for the deck: `--marver-slide-tempo`
|
|
81
|
+
in the theme (default 350ms).
|
|
82
|
+
- **Builds.** Progressive disclosure is sibling frames (`04a-`, `04b-`)
|
|
83
|
+
sharing morph names, so every step stays visible and commentable.
|
|
84
|
+
|
|
85
|
+
Shortcuts, if they help: `data-animate="fade-up | fade | scale-in"` plus
|
|
86
|
+
`data-animate-delay="1 | 2 | 3"` run once after a slide arrives (never on an
|
|
87
|
+
element that also morphs - one owner per transform).
|
|
88
|
+
|
|
89
|
+
## The deck kit - build it once per deck
|
|
90
|
+
|
|
91
|
+
A strong deck is not twenty bespoke pages; it is one small system applied
|
|
92
|
+
with variety. Before the slides, write the kit into the scene - `_parts.tsx`
|
|
93
|
+
and `_style.css`, the leading underscore keeps them off the canvas:
|
|
94
|
+
|
|
95
|
+
- **The master** - a shell every content slide wears: the mark, a context
|
|
96
|
+
line (who it is prepared for, the date, "confidential"), the body area.
|
|
97
|
+
Covers and closings step outside it.
|
|
98
|
+
- **Tones** - two to four whole-slide colour sets as CSS variables (paper,
|
|
99
|
+
ink, one accent ground), swapped by a class. A tone change is a pacing tool.
|
|
100
|
+
- **Type** - the brand's family, weights and tracking, and a handful of
|
|
101
|
+
sizes: a display, a heading, a body, a small label. Hierarchy through size
|
|
102
|
+
and a muted colour, rarely through weight.
|
|
103
|
+
- **Rules and labels** - the hairline, the numbered label, the spacing rhythm.
|
|
104
|
+
- **The drawing helper** - one component that renders the deck's
|
|
105
|
+
illustrations by name, with their alt text.
|
|
37
106
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
The
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
**One spacing scale**, in px, every value from it and nothing between:
|
|
205
|
-
|
|
206
|
-
| Step | Use |
|
|
207
|
-
|---|---|
|
|
208
|
-
| 8 | label to its value, icon to its text |
|
|
209
|
-
| 16 | rows inside one list, line to hairline |
|
|
210
|
-
| 24 | siblings inside a card or a group |
|
|
211
|
-
| 32 | padding inside a card; between columns |
|
|
212
|
-
| 40 | between distinct groups in the body |
|
|
213
|
-
| 48 | title block to body, body to the foot |
|
|
214
|
-
|
|
215
|
-
Rhythm comes from CONTRAST between those steps - tight inside a group, wide
|
|
216
|
-
between groups. One value repeated everywhere is the flattest thing you can
|
|
217
|
-
do to a slide. Gaps go on the parent (`gap`), never as per-child margins.
|
|
218
|
-
|
|
219
|
-
## The evidence
|
|
220
|
-
|
|
221
|
-
- **One anchor visual per slide, at most** - a peer set or a path counts as
|
|
222
|
-
one.
|
|
223
|
-
- **Charts** (`Chart`): pick the FORM from the Apache ECharts docs
|
|
224
|
-
(https://echarts.apache.org/en/option.html), inside the supported surface
|
|
225
|
-
- series bar, line, pie, scatter, radar, gauge, heatmap, funnel, treemap, sunburst, sankey, boxplot; components grid, polar, radar, tooltip, legend, title, dataset (+ transform), markLine, markPoint, markArea, visualMap, dataZoom; anything else is dropped without an
|
|
226
|
-
error. marver supplies the house theme (colors, type, tooltip); styling
|
|
227
|
-
you pass overrides it, so pass DATA and STRUCTURE, never styling. One message per chart; the takeaway is the
|
|
228
|
-
slide's assertion; direct labels over legends; bar baselines at zero
|
|
229
|
-
(lines may zoom - annotate when they do); hue = category, shade = variant,
|
|
230
|
-
fixed across the whole deck.
|
|
231
|
-
- **Diagrams** (`Diagram`) for structure, plain shapes + arrows for
|
|
232
|
-
concepts - a 2×2 or a flow in divs beats imported artwork.
|
|
233
|
-
- **Images** (`Img`): full-bleed with a scrim and a short assertion, or
|
|
234
|
-
generously matted. Never a small image floating in space.
|
|
235
|
-
- **Video** (`Video src poster`): the poster IS the slide at rest - choose
|
|
236
|
-
it like a photograph. Omit `poster` and marver renders one from the clip
|
|
237
|
-
(`<clip>.poster.png` beside it, committed like any asset); author one when
|
|
238
|
-
the clip's opening is not the picture you want. In slides mode the
|
|
239
|
-
player mounts on its own; everywhere else a frame is live, the poster is
|
|
240
|
-
the play button (the same primitive serves screens and specs).
|
|
241
|
-
- **Backgrounds are code**: theme-derived gradients, an oversized numeral, a
|
|
242
|
-
clipped photo, one geometric accent. ONE effect per slide, and decoration
|
|
243
|
-
never touches the evidence's contrast.
|
|
244
|
-
|
|
245
|
-
## The recipes
|
|
246
|
-
|
|
247
|
-
Scan all of them (plus `design/slides.md`) for every slide. Each entry:
|
|
248
|
-
silhouette · skeleton · budget (breach = split, never shrink) · anchor (the
|
|
249
|
-
element that morphs INSIDE a group or build; "none" = a hard cut).
|
|
250
|
-
|
|
251
|
-
1. **cover** (bookend) - deck title + one line + the mark. Budget: title ≤6
|
|
252
|
-
words. Anchor: the mark.
|
|
253
|
-
2. **section** (bookend) - an oversized numeral/word divider in
|
|
254
|
-
`sl-display`. Budget: ≤3 words. Anchor: none.
|
|
255
|
-
3. **assertion-evidence** (split or field) - the workhorse: `sl-assertion`
|
|
256
|
-
+ ONE visual. Budget: assertion 1 line, caption 1 line. Anchor: the
|
|
257
|
-
visual.
|
|
258
|
-
4. **big-number** (hero) - one `sl-display` stat + a context line. Budget:
|
|
259
|
-
1 stat. Anchor: the number.
|
|
260
|
-
5. **stat-row** (grid) - 3-4 quick proofs in a row. Budget: each ≤4 words +
|
|
261
|
-
value. Anchor: the row.
|
|
262
|
-
6. **metric-grid** (grid) - a 2×2 of labeled values. Budget: 4 cells
|
|
263
|
-
exactly. Anchor: the grid.
|
|
264
|
-
7. **quote** (hero) - the words, the person, nothing else. Budget: ≤30
|
|
265
|
-
words. Anchor: none.
|
|
266
|
-
8. **quote-wall** (grid) - 3-6 short quotes. Budget: each ≤15 words.
|
|
267
|
-
Anchor: the wall.
|
|
268
|
-
9. **two-up** (split) - comparison / before-after. Budget: ≤4 rows per
|
|
269
|
-
side. Anchor: the divider.
|
|
270
|
-
10. **two-stage** (stream) - diagnosis → prescription with a connector.
|
|
271
|
-
Budget: one sentence per stage. Anchor: the connector.
|
|
272
|
-
11. **numbered-reasons** (grid) - 3-5 ordered points. Budget: each ≤12
|
|
273
|
-
words. Anchor: the numerals.
|
|
274
|
-
12. **bento** (grid) - 3-5 cells for a system view. Budget: cell = title +
|
|
275
|
-
1 line. Anchor: the largest cell.
|
|
276
|
-
13. **timeline** (stream) - a horizontal spine, 3-6 beats. Budget: beat ≤5
|
|
277
|
-
words. Anchor: the spine.
|
|
278
|
-
14. **roadmap-phases** (stream) - 2-4 phases with contents. Budget: ≤3
|
|
279
|
-
items/phase. Anchor: the phase heads.
|
|
280
|
-
15. **matrix** (field) - a 2×2 positioning. Budget: ≤6 plotted items.
|
|
281
|
-
Anchor: the axes.
|
|
282
|
-
16. **full-bleed** (hero) - image + scrim + assertion. Budget: assertion
|
|
283
|
-
only. Anchor: the image.
|
|
284
|
-
17. **chart-focus** (field) - one `Chart`, near full-slide. Anchor: the
|
|
285
|
-
chart.
|
|
286
|
-
18. **wall** (grid) - logos/team grid. Budget: 6-12 cells, no captions.
|
|
287
|
-
Anchor: the grid.
|
|
288
|
-
19. **closing** (bookend) - the ask, one CTA, contact. Budget: ask ≤2
|
|
289
|
-
lines. Anchor: none.
|
|
290
|
-
|
|
291
|
-
These are the core. The atlas in reference/deck-layouts.md carries the rest
|
|
292
|
-
- split, cards, spectrum, insight + evidence, trajectory, table, scenarios,
|
|
293
|
-
flow, cycle, chain, swim lanes, funnel, schedule, layers, concentric,
|
|
294
|
-
pyramid, number line, capability matrix, scorecard, heat map, tracker,
|
|
295
|
-
testimonials, team, manifesto, framed source - each with its budget, plus
|
|
296
|
-
the shared stage, margins, and the optional banded grid they draw from. Scan it for every slide.
|
|
297
|
-
|
|
298
|
-
## Choreography - the diff IS the animation
|
|
299
|
-
|
|
300
|
-
You never animate. You name elements consistently, and slides mode
|
|
301
|
-
interpolates the difference between adjacent stills. The board is the
|
|
302
|
-
timeline: design motion by designing the diff.
|
|
303
|
-
|
|
304
|
-
**Five verbs** via `view-transition-name` (style prop or class):
|
|
305
|
-
|
|
306
|
-
| Verb | How | Reads as |
|
|
307
|
-
|---|---|---|
|
|
308
|
-
| persist | same name, same box | continuity - the anchor |
|
|
309
|
-
| travel | same name, new position | "follow this" |
|
|
310
|
-
| grow | same name, new size | "this is now the point" |
|
|
311
|
-
| swap | unmatched content | the default crossfade |
|
|
312
|
-
| reveal | new element + `data-animate` | "and then" |
|
|
313
|
-
|
|
314
|
-
**Binding rules:**
|
|
315
|
-
- Adjacent slides inside a visual group or a build share AT LEAST one stable
|
|
316
|
-
named element - the anchor (each recipe names its default above). Across
|
|
317
|
-
a turn of the argument, or into and out of a statement, hero, or bookend,
|
|
318
|
-
a HARD CUT (zero shared names) is the right punctuation - use it. Never
|
|
319
|
-
name the assertion `headline` on every slide as a deck-wide fallback: a
|
|
320
|
-
title that morphs into the next title on seventeen slides is the
|
|
321
|
-
strongest possible signal that every slide has the same shape.
|
|
322
|
-
- AT MOST one element changes position or size per transition. Persist
|
|
323
|
-
freely, travel once.
|
|
324
|
-
- Build steps are sibling frames (`03a-`, `03b-`) sharing morph names -
|
|
325
|
-
progressive disclosure that stays visible and commentable. Variants are
|
|
326
|
-
for exploration, siblings for builds - never both on one slide.
|
|
327
|
-
- Entrances: `data-animate="fade-up | fade | scale-in"` +
|
|
328
|
-
`data-animate-delay="0|1|2|3"`. Never on an element that carries a morph
|
|
329
|
-
name. Runs once, after the transition settles - trust it, don't stack it.
|
|
330
|
-
- Morphs tween bounds and crossfade pixels - a chart "morph" is the picture
|
|
331
|
-
growing, not bars re-plotting. Design for that honestly.
|
|
332
|
-
- One tempo per deck (the root's token). Motion never varies per slide.
|
|
333
|
-
- NOTHING loops, scrolls, or free-runs. A resting slide is still - that is
|
|
334
|
-
what keeps a 40-slide canvas fast, and the review gate checks it.
|
|
107
|
+
```tsx
|
|
108
|
+
// design/scenes/<deck>/_parts.tsx
|
|
109
|
+
import type { ReactNode } from 'react'
|
|
110
|
+
import './_style.css'
|
|
111
|
+
|
|
112
|
+
export function Page({ tone = 'paper', className = '', children }: {
|
|
113
|
+
tone?: 'paper' | 'ink' | 'accent'; className?: string; children: ReactNode
|
|
114
|
+
}) {
|
|
115
|
+
return (
|
|
116
|
+
<main className={`dk-page dk-${tone} ${className}`}>
|
|
117
|
+
<header className="dk-header"><Mark /><span>Prepared for Acme · Confidential · May 2026</span></header>
|
|
118
|
+
<div className="dk-body">{children}</div>
|
|
119
|
+
</main>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```css
|
|
125
|
+
/* _style.css - tones are variable swaps, so every rule reads the same names */
|
|
126
|
+
.dk-page { --ground: #f1f0ea; --ink: #151616; --muted: #63645f; --line: #cacac2;
|
|
127
|
+
min-height: 100vh; padding: 0 48px; background: var(--ground); color: var(--ink);
|
|
128
|
+
font: 400 20px/1.4 var(--brand-font); letter-spacing: -.015em }
|
|
129
|
+
.dk-ink { --ground: #151616; --ink: #f1f0ea; --muted: #b5b7ad; --line: #474a44 }
|
|
130
|
+
.dk-page h1 { font-weight: 400; font-size: 64px; line-height: 1.05; letter-spacing: -.045em; margin: 0 }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Derive every value from `design/DESIGN.md` and `theme.css`, and use the
|
|
134
|
+
project's real mark component. If the brand is not written down yet, that
|
|
135
|
+
comes first (instructions/brand.md): a deck look invented on slide one has
|
|
136
|
+
drifted by slide five.
|
|
137
|
+
|
|
138
|
+
## The craft - what makes a deck look made
|
|
139
|
+
|
|
140
|
+
The habits that carry the most, distilled from the best decks built on
|
|
141
|
+
marver:
|
|
142
|
+
|
|
143
|
+
1. **The brand, not a deck style.** The identity's own typeface, weights,
|
|
144
|
+
colours and imagery. Large type at regular weight with tight tracking
|
|
145
|
+
looks designed; bold everywhere looks generated.
|
|
146
|
+
2. **One idea per slide.** The headline is the message, written as a
|
|
147
|
+
sentence. Under it, at most a short line and a few supporting items. The
|
|
148
|
+
nuance, the caveats and the talk track go in the note.
|
|
149
|
+
3. **Structure with space and hairlines, not boxes.** Group by alignment and
|
|
150
|
+
gaps, separate with 1px rules, order with small numbered labels in the
|
|
151
|
+
muted colour. A card, a shadow or a badge is for the rare element that is
|
|
152
|
+
genuinely a separate object.
|
|
153
|
+
4. **Real images, used big.** The client's or the product's own photography,
|
|
154
|
+
full-bleed or bleeding off one edge, under a uniform scrim where text sits
|
|
155
|
+
on it. Never a small picture floating in space; never stock that could
|
|
156
|
+
belong to anyone.
|
|
157
|
+
5. **A drawing system of your own.** When an idea needs a picture, draw it as
|
|
158
|
+
native SVG in one style: consistent line weights, a shared grid, mostly
|
|
159
|
+
ink, ONE accent per slide marking the point (the approval, the bottleneck,
|
|
160
|
+
the result). Light and dark versions where tones change. Colour that means
|
|
161
|
+
something (red for the rework loop, green for the outcome) is introduced
|
|
162
|
+
on purpose and kept consistent.
|
|
163
|
+
6. **Diagrams built for the argument.** A process with its failure loop drawn
|
|
164
|
+
back across it, a context and a solution in two illustrated lanes, three
|
|
165
|
+
numbers in a row - composed in HTML and SVG for this message, not picked
|
|
166
|
+
from a menu.
|
|
167
|
+
7. **Pace the deck.** A sparse statement after the cover; working slides on
|
|
168
|
+
the light ground; a dark slide at a turn of the argument; the accent ground
|
|
169
|
+
once, for the proof. Dense slides alternate with quiet ones.
|
|
170
|
+
8. **Bookends are doors.** The cover pairs the marks (yours and the
|
|
171
|
+
audience's) with one strong image and no header. The closing is a quiet
|
|
172
|
+
card - the mark, a contact, a photograph - with the ask on the slide before.
|
|
173
|
+
9. **Honest numbers.** Evidence is big and specific; its limits sit on the
|
|
174
|
+
slide in small type when they matter ("results from a reference project,
|
|
175
|
+
not a forecast").
|
|
176
|
+
10. **Finish the details.** Control the line breaks in headlines, balance the
|
|
177
|
+
gaps, align each drawing with the text beside it, check every tone. The
|
|
178
|
+
distance between good and very good is twenty small passes - and a frozen
|
|
179
|
+
copy of the deck before each big change, so nothing approved is lost.
|
|
180
|
+
|
|
181
|
+
Variety comes from the message: choose each slide's composition for what it
|
|
182
|
+
has to show, and let the kit hold the deck together.
|
|
183
|
+
reference/deck-layouts.md is a bank of compositions to borrow from when you
|
|
184
|
+
are stuck.
|
|
185
|
+
|
|
186
|
+
## The method
|
|
187
|
+
|
|
188
|
+
1. **The answer.** Before any frame: one paragraph - what the audience should
|
|
189
|
+
believe or do when the last slide lands. If the material is too thin for a
|
|
190
|
+
substantive deck, say so and ask; never pad.
|
|
191
|
+
2. **The slide list.** One line per slide, each its message as a sentence.
|
|
192
|
+
Read the lines alone: they should tell the whole argument, specifically
|
|
193
|
+
enough that a stranger could guess whose deck it is. Could you draft each
|
|
194
|
+
slide without inventing a fact? The gaps become questions for the human.
|
|
195
|
+
3. **The brief.** Write `_brief.md` in the scene: the answer, the sequence as
|
|
196
|
+
a storyboard (`message | what the eye lands on | composition | density`),
|
|
197
|
+
the visual system (kit, tones, imagery, drawings) and the sources. It keeps
|
|
198
|
+
a long iteration coherent.
|
|
199
|
+
4. **Scaffold, then build.** Put every slide on the board early - a frame
|
|
200
|
+
holding just its sentence, in one scene, numbered files (`01-cover.tsx`) -
|
|
201
|
+
so the outline is reorderable and vetoable on the canvas. Mark the work
|
|
202
|
+
(`npx marver work start ...`). Then build the kit, then the slides.
|
|
203
|
+
5. **Notes as you go.** Each slide's `.note.md`, in four short parts:
|
|
204
|
+
|
|
205
|
+
```md
|
|
206
|
+
## Aim
|
|
207
|
+
What this slide must do in the argument.
|
|
208
|
+
|
|
209
|
+
## Say
|
|
210
|
+
The talk track, in the presenter's voice.
|
|
211
|
+
|
|
212
|
+
## Visual
|
|
213
|
+
Why it looks the way it does - what the image or drawing carries.
|
|
214
|
+
|
|
215
|
+
## Source context
|
|
216
|
+
Where the facts come from, and their limits.
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Notes ship with a published canvas: keep anything the audience must not
|
|
220
|
+
read out of them.
|
|
221
|
+
6. **Review**, below - then iterate.
|
|
222
|
+
|
|
223
|
+
## Words
|
|
224
|
+
|
|
225
|
+
- Headlines that say something: "Every new market adds a week of manual
|
|
226
|
+
reconciliation", not "Reporting challenges". A label suits a door (a
|
|
227
|
+
section, an agenda, "How we work with your team") - not an argument.
|
|
228
|
+
- Numbers, names and dates over adjectives; units once.
|
|
229
|
+
- Active voice. Cut every word that is not earning its place. Kill on sight:
|
|
230
|
+
"leverage", "robust", "world-class", "streamline", "seamless", "unlock",
|
|
231
|
+
"going forward", "we believe", "it is important to note".
|
|
232
|
+
- Sources as a short line on the slide; the full citation in the note.
|
|
233
|
+
- When a slide is full, split it or move the detail to the note - shrinking
|
|
234
|
+
the type to fit is the slide telling you it holds two ideas.
|
|
235
|
+
|
|
236
|
+
## Evidence
|
|
237
|
+
|
|
238
|
+
- **Chart** (`/content`): an Apache ECharts option on a fixed surface -
|
|
239
|
+
series bar, line, pie, scatter, radar, gauge, heatmap, funnel, treemap,
|
|
240
|
+
sunburst, sankey, boxplot; components grid, polar, radar, tooltip, legend,
|
|
241
|
+
title, dataset (+ transform), markLine, markPoint, markArea, visualMap,
|
|
242
|
+
dataZoom (anything else is dropped without an error). It inherits the
|
|
243
|
+
slide's ink and typeface and reads `--marver-slide-accent`; pass data and
|
|
244
|
+
structure, and style only what the deck needs. One message per chart,
|
|
245
|
+
direct labels, bars from zero. When the form is simple and the brand
|
|
246
|
+
matters more, draw the chart yourself in SVG.
|
|
247
|
+
- **Images**: `Img` for a framed asset from `design/assets/`, or a plain
|
|
248
|
+
`<img>` / CSS background when the slide needs full control (`object-fit`,
|
|
249
|
+
`object-position`, a scrim). Use files at least 2x the size they show -
|
|
250
|
+
the player scales slides up.
|
|
251
|
+
- **Video** (`Video src poster`): the poster is the slide at rest; in slides
|
|
252
|
+
mode the player mounts on its own. Omit `poster` and marver renders one
|
|
253
|
+
from the clip.
|
|
254
|
+
- **Diagram** (Mermaid) for quick structure; hand-built SVG and HTML when the
|
|
255
|
+
diagram IS the slide.
|
|
256
|
+
|
|
257
|
+
## Review - before you present
|
|
258
|
+
|
|
259
|
+
- **The contact sheet.** `npx marver shot --scene <deck>`, then look at every
|
|
260
|
+
slide small, side by side. Does it read as one deck with range, or one
|
|
261
|
+
shape repeated with different words? Squint: where does the eye land on each?
|
|
262
|
+
- **Play it.** Slides mode, start to end, in a big window and a small one:
|
|
263
|
+
nothing clipped or spilling past the stage, every tone legible, motion
|
|
264
|
+
finished at rest.
|
|
265
|
+
- **The cold read.** The headlines alone, in order: do they deliver the
|
|
266
|
+
answer? Each slide alone, without a presenter: does it land its one
|
|
267
|
+
message? A miss is a narrative question for the human, not a polish job.
|
|
268
|
+
- **The generated tells.** Heavy weights everywhere, five type sizes on one
|
|
269
|
+
slide, a card around everything, a tiny uppercase kicker over every
|
|
270
|
+
headline, filler numbers, the same composition three slides running with no
|
|
271
|
+
reason. Delete before you add.
|
|
335
272
|
|
|
336
273
|
## Publishing a deck
|
|
337
274
|
|
|
338
|
-
The board is the deck
|
|
339
|
-
order - rearrange the board to reorder the deck. Publish with:
|
|
275
|
+
The board is the deck. Publish with:
|
|
340
276
|
|
|
341
277
|
```json
|
|
342
278
|
{ "boards": { "pitch": { "max": "comment", "type": "slides",
|
|
@@ -345,58 +281,14 @@ order - rearrange the board to reorder the deck. Publish with:
|
|
|
345
281
|
|
|
346
282
|
`transition`: `fade` (default) or `none`. `chrome`: `full` (default - the
|
|
347
283
|
standard prototype toolbar and walker), `minimal` (a progress strip +
|
|
348
|
-
comments
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
invented. No DESIGN.md yet means the brand doc comes first
|
|
360
|
-
(instructions/brand.md). When the human
|
|
361
|
-
asks you to study `design/slides-inspiration/` (PPTX, PDFs, screenshots),
|
|
362
|
-
propose additions to `design/slides.md` as a normal reviewed edit - each
|
|
363
|
-
with a gap justification (what no existing recipe serves) and a stress pass
|
|
364
|
-
(minimal / typical / worst-case content, both themes) before it earns its
|
|
365
|
-
entry.
|
|
366
|
-
|
|
367
|
-
## The review gate (run it, every deck, before presenting)
|
|
368
|
-
|
|
369
|
-
Twelve tells, each a defect: label titles · bullet walls · lines past ~15
|
|
370
|
-
words · data without a "so what" · provenance slides (how the work was
|
|
371
|
-
done - a process that IS the subject, an operating model or a rollout plan,
|
|
372
|
-
is content) · hedge language ·
|
|
373
|
-
audience-mismatched jargon · filler words · passive voice · claims missing
|
|
374
|
-
numbers · formatting drift between slides · a weak closing.
|
|
375
|
-
|
|
376
|
-
Then: the sequence test (titles alone tell the argument) · BOTH themes ·
|
|
377
|
-
the slide view AND fill window (the fit scales your composition - check
|
|
378
|
-
nothing relied on the window) and one 390px glance · every slide still at
|
|
379
|
-
rest (no loops, no autoplay) · the silhouette pacing from step 4, checked
|
|
380
|
-
against the storyboard, not the recipe names · anchors inside groups, hard
|
|
381
|
-
cuts at the turns.
|
|
382
|
-
|
|
383
|
-
Then the two reads that catch what polish hides:
|
|
384
|
-
- **Landing, per slide.** Read each slide cold - no presenter, no
|
|
385
|
-
neighbours. Does it deliver the one message you planned for it? Landed ·
|
|
386
|
-
partial (present but buried or hedged) · missed. A missed message on a
|
|
387
|
-
polished slide is still a must-fix.
|
|
388
|
-
- **The cold read, whole deck.** Read every assertion and every takeaway
|
|
389
|
-
bar in sequence, nothing else. Do they alone deliver the one thing the
|
|
390
|
-
human said the audience must leave with? If not, no surface edit fixes it
|
|
391
|
-
- take the gap to the human as a narrative question, do not polish
|
|
392
|
-
around it.
|
|
393
|
-
|
|
394
|
-
Finally the contact sheet: all frames small on the canvas, then squint. If
|
|
395
|
-
the deck blurs into one repeated shape with different fillings, it failed -
|
|
396
|
-
whatever the recipe names say. One silhouette on more than 40% of the
|
|
397
|
-
content slides (decks of eight or more), the same top and bottom horizon on
|
|
398
|
-
every slide, dense slides clumped
|
|
399
|
-
together, accent fills bunched on neighbours, a card row where one card is
|
|
400
|
-
8 words and the others 40 - each a defect. Iterate until the gate passes; after three passes that
|
|
401
|
-
still surface defects, the remaining list goes to the human and the deck
|
|
402
|
-
ships at their call.
|
|
284
|
+
comments) or `none`. Add `"lock": true` for a share that is ONLY the deck.
|
|
285
|
+
|
|
286
|
+
## design/slides.md - this project's deck look
|
|
287
|
+
|
|
288
|
+
The project's own file: the deck look (master, tones, type, mark, imagery,
|
|
289
|
+
drawing style, colour meaning, motion, numbers, voice, end card) and any
|
|
290
|
+
compositions and habits the team wants repeated. On the first deck in a
|
|
291
|
+
project, draft its deck look from `design/DESIGN.md` and `theme.css` as a
|
|
292
|
+
reviewed edit and tell the human; it then outlives every deck. When the
|
|
293
|
+
human asks you to study `design/slides-inspiration/` (PPTX, PDFs,
|
|
294
|
+
screenshots), propose additions to it the same way.
|