@marver-design/marver 0.12.0 → 0.14.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +41 -19
  3. package/dist/{build-DmfxJc6L.mjs → build-ByYafIhj.mjs} +37 -5
  4. package/dist/cli.mjs +21 -7
  5. package/dist/{collab-BmaOjwP1.mjs → collab-mAiNZlDj.mjs} +232 -43
  6. package/dist/{comments-pNxjTrGN.mjs → comments-DHB_8BRa.mjs} +3 -3
  7. package/dist/{daemon-WjonKlPz.mjs → daemon-Bfucyf1o.mjs} +3 -3
  8. package/dist/{dev-BXq7yE1p.mjs → dev-yZMyQeUj.mjs} +5 -5
  9. package/dist/{events-C9k-ceOj.mjs → events-B3LBn74P.mjs} +3 -1
  10. package/dist/{init-BpitOqRQ.mjs → init-Dvaso7YO.mjs} +66 -2
  11. package/dist/{manifest-CS6krOTe.mjs → manifest-DvOmglFp.mjs} +7 -0
  12. package/dist/{marver-id-gate-DOjnZakC.mjs → marver-id-gate-D6By7XHj.mjs} +8 -5
  13. package/dist/{plugin-Boy7I_JH.mjs → plugin-BsmG5i2X.mjs} +25 -7
  14. package/dist/{profile-ChpTPd-X.mjs → profile-BjAPAJSb.mjs} +1 -1
  15. package/dist/{serve-BeLLizNg.mjs → serve-Bcwfpvhl.mjs} +4 -3
  16. package/dist/{share-C64b1tdN.mjs → share-Gqo_Ygqw.mjs} +14 -15
  17. package/dist/{shot-Cyv3GN79.mjs → shot-kbR_xzJH.mjs} +7 -1
  18. package/dist/{summary-Bf9tiGrE.mjs → summary-C7CAypbB.mjs} +1 -1
  19. package/dist/{sync-WYxDN9IT.mjs → sync-BZaCWqK-.mjs} +1 -1
  20. package/docs/live-jam.md +173 -0
  21. package/docs/publish.md +270 -0
  22. package/docs/sharing.md +333 -0
  23. package/docs/slides.md +134 -0
  24. package/package.json +3 -1
  25. package/src/client/const.ts +13 -0
  26. package/src/client/content/chart-engine.ts +33 -0
  27. package/src/client/content/chart.tsx +100 -0
  28. package/src/client/content/index.tsx +25 -4
  29. package/src/client/content/slide.tsx +238 -0
  30. package/src/client/content/video.tsx +126 -0
  31. package/src/client/shell/App.tsx +49 -15
  32. package/src/client/shell/Comments.tsx +94 -17
  33. package/src/client/shell/LockedApp.tsx +7 -2
  34. package/src/client/shell/Play.tsx +138 -24
  35. package/src/client/shell/Toolbar.tsx +12 -3
  36. package/src/client/shell/canvas/FrameNode.tsx +5 -3
  37. package/src/client/shell/comments-store.ts +59 -4
  38. package/src/client/shell/hash.ts +3 -1
  39. package/src/client/shell/icons.tsx +2 -0
  40. package/src/client/shell/mentions.ts +108 -1
  41. package/src/client/shell/play-order.ts +22 -0
  42. package/src/client/shell/sound.ts +32 -0
  43. package/src/client/shell/store.ts +41 -12
  44. package/src/client/shell/styles.css +58 -27
  45. package/src/client/stage/main.tsx +54 -3
  46. package/src/shared/events.ts +12 -3
  47. package/src/shared/utm.ts +3 -2
  48. package/templates/AGENTS-embedded.md +1 -0
  49. package/templates/AGENTS-studio.md +1 -0
  50. package/templates/instructions/publish.md +7 -0
  51. package/templates/instructions/reference/deck-layouts.md +230 -0
  52. package/templates/instructions/reference/deck-story.md +110 -0
  53. package/templates/instructions/slides.md +398 -0
@@ -0,0 +1,398 @@
1
+ # Slides - decks that argue, on frames that move
2
+
3
+ Run this when the work is a DECK: the human asks for slides, a presentation,
4
+ a pitch, a review - or a scene of `slide: true` frames exists. Read
5
+ `design/slides.md` too, ALWAYS: it is the project's own layout list and house
6
+ rules, 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 - 1280×720, the
9
+ slide badge, and slides mode when published. Everything you know holds:
10
+ real components, the project theme, comments, variants, promotion. What
11
+ changes is the CRAFT BAR - a deck is an argument wearing the product's
12
+ clothes, and every rule below is binding.
13
+
14
+ **The stage fits every screen.** You author at exactly 1280×720 and the
15
+ Slide root scales and centers itself to any viewport - fill window, a
16
+ laptop, a viewer's phone. One coordinate system: your px, Tailwind classes,
17
+ and charts scale together, so what you compose is what plays. This is a
18
+ guarantee to LEAN ON, not to fight:
19
+ - lay out with flex/grid and the stage's own proportions (percentages,
20
+ `--sl-margin`, the type roles) - never against the window;
21
+ - no viewport units (`vw/vh`) and no media queries inside a slide - the
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.
25
+
26
+ ```tsx
27
+ import { Slide } from '@marver-design/marver/content'
28
+ export const meta = { title: 'Cover', slide: true }
29
+ export default () => (
30
+ <Slide>
31
+ <h1 className="sl-assertion">Churn halved after onboarding v2</h1>
32
+ </Slide>
33
+ )
34
+ ```
35
+
36
+ This file is the floor. Depth lives in instructions/reference/:
37
+
38
+ | File | When |
39
+ |---|---|
40
+ | reference/deck-layouts.md | REQUIRED at step 4 of every deck - the full atlas, the grid, the budgets, charts; and BEFORE step 1 when rebuilding an existing deck (its mode decision comes first) |
41
+ | reference/deck-story.md | when intake is thin or rich, the room is senior, the slide list reads like a table of contents, or the words need work |
42
+
43
+ ## The pipeline (in order, no skipping)
44
+
45
+ **1. The answer.** Before any frame: write the deck's one-paragraph answer -
46
+ what the audience should believe or do when the last slide lands. If the
47
+ human's material is too thin for a substantive deck, SAY SO and ask - never
48
+ pad. Then the slide list: one line per slide, each line the slide's single
49
+ message as a full-sentence assertion. Walk that list once more asking
50
+ "could I draft this slide without inventing a single fact?" - the gaps
51
+ become specific questions to the human, or a smaller deck (the evidence
52
+ check, reference/deck-story.md). The scaffold (step 2) may carry gaps as
53
+ visible placeholders; the build (step 5) may not - a factual gap blocks its
54
+ slide until answered or cut, while editorial copy (framing, captions) you
55
+ draft and label as proposed.
56
+
57
+ **2. Show the deck.** Scaffold every listed slide immediately as a
58
+ placeholder frame - `<Slide>` + its assertion in `sl-assertion` - in one
59
+ scene (one scene = one deck), numbered files (`01-cover.tsx`,
60
+ `02-problem.tsx`), pinned on the board, marked working
61
+ (`npx marver work start ...`). The outline now lives ON the canvas,
62
+ reorderable and vetoable while every slide is still one sentence. THEN
63
+ research, gather evidence, design.
64
+
65
+ **3. The sequence test.** Read only the assertions, in file order. They must
66
+ tell the complete argument - specifically enough that a stranger could guess
67
+ whose deck this is. Generic titles mean the thinking is not done; fix the
68
+ titles before touching layout.
69
+
70
+ **4. Storyboard the silhouettes.** Before any markup, one line per slide:
71
+
72
+ `message | dominant object | silhouette | density | recipe`
73
+
74
+ The dominant object first - what the eye lands on (a number, a quote, a
75
+ chart, the claim itself; for a grid the peer set as one shape, for a stream
76
+ the path) - then the silhouette that serves it (the seven, below), density (airy / balanced / dense), and only
77
+ then the recipe from the list below + the atlas in
78
+ reference/deck-layouts.md + `design/slides.md`, picked against the content's
79
+ real volume. Read the finished list as THUMBNAILS, not as recipe names.
80
+ Pacing, for any deck of eight or more content slides:
81
+ - no silhouette on more than 40% of the deck;
82
+ - no silhouette twice running, except inside a declared visual group
83
+ (three pillars, four pipeline stages - those share ONE layout, variety
84
+ comes between groups) or a build sequence;
85
+ - never three dense slides in a row;
86
+ - an airy statement, hero, or bookend at the opening answer, at every
87
+ major turn of the argument, and at the close.
88
+ Do not alternate mechanically - pace follows the argument. A recipe's
89
+ budget breached = a different recipe or a split, decided here.
90
+
91
+ **5. Build.** Real markup inside `<Slide>`, the project's own classes and
92
+ components, the type roles, the theme's tokens. Name morph anchors as you
93
+ go (choreography, below). The assertion is always the `h1`, but it need not
94
+ sit at the top or be the largest thing: when the slide is about a number,
95
+ a quote, a chart, or a source, THAT dominates and the assertion frames it.
96
+ Never write one wrapper that fixes the title geometry for every slide -
97
+ share tokens, the source treatment, and primitives; give each silhouette
98
+ its own shell. HTML stays honest: images carry `alt`, a chart or diagram
99
+ gets a one-line text summary in a caption, every colour pair reads in both
100
+ themes.
101
+
102
+ **6. The review gate.** Run it before presenting, every time (bottom of this
103
+ file).
104
+
105
+ ## The words
106
+
107
+ - **Assertions, not labels.** "Q3 revenue beat plan by 12%" - never "Q3
108
+ revenue". One line, it commits to a position. (The one exception: a
109
+ FAITHFUL rebuild of an existing deck keeps its titles as written -
110
+ reference/deck-layouts.md.)
111
+ - **Overflow is a second slide.** Never fix a full slide by shrinking type.
112
+ - Numbers over adjectives - every FACTUAL claim carries a figure, a name, or
113
+ a date; a conceptual assertion earns its place by being specific to this
114
+ company, not generic.
115
+ - Active voice. Write like you talk, then cut every word that isn't earning.
116
+ - Kill on sight: "leverage", "robust", "world-class", "streamline",
117
+ "going forward", "potentially", "we believe", "it is important to note".
118
+ - Negatives in brackets: (123). Units once, in the header or axis; within a
119
+ metric family one unit and one time-basis ($M everywhere revenue appears,
120
+ FY or CY - never both).
121
+ - Sources are a short `sl-caption` slug at the foot of the slide - "OpenAI
122
+ technical report, §IV.B" - never a bibliographic sentence; that band
123
+ repeated seventeen times is a report template. Full citations go in the
124
+ frame's comment.
125
+ - The closing slide is a specific, time-bound ask. "Questions?" is not a
126
+ closing slide.
127
+
128
+ ## The type and the space
129
+
130
+ The `<Slide>` root provides the roles - use them, never font-size by hand.
131
+ The values are fixed (one coordinate system with the stage):
132
+
133
+ | Role class | Size | Job |
134
+ |---|---|---|
135
+ | `sl-display` | 160px | the oversize: a hero number, a section numeral, the manifesto line - never running text; at most once per argument group, never on adjacent slides |
136
+ | `sl-stat` | 88px | a ROW of figures (3-4 across), where `sl-display` would not fit |
137
+ | `sl-assertion` | 56px, heavy | the one-line claim (~40 characters full-width, ~20 inside a split - two lines is the ceiling, verify the render) |
138
+ | `sl-support` | 30px | the second voice |
139
+ | `sl-body` | 24px | evidence text - the floor for anything read |
140
+ | `sl-caption` | 18px | sources, footnotes, kickers |
141
+
142
+ Nothing smaller than 18px, ever. One family (`--marver-slide-font`, the
143
+ theme's); the roles carry their weights - add none of your own. One
144
+ reading intent per slide - a single object, a peer set, or a path, never two
145
+ competing. Within a visual group, shared elements keep the SAME
146
+ position unless the movement is the message.
147
+
148
+ ## Silhouette - the deck at thumbnail size
149
+
150
+ A silhouette is the largest geometry the eye sees when the words are
151
+ blurred. Swapping a card row for a stat row under the same standing header
152
+ changes nothing at thumbnail size, and the review gate looks at thumbnails.
153
+ Choose the silhouette before the recipe. Seven:
154
+
155
+ - **statement** - one claim owns the canvas. No kicker, no header, at most
156
+ one short support line. The opening answer, a turn, a synthesis.
157
+ - **hero** - one number, quote, image, or source object owns 60-80% of the
158
+ canvas; the assertion frames it, smaller, and does not compete.
159
+ - **split** - two UNEQUAL fields, 40/60 or 60/40: one argues, one proves.
160
+ - **grid** - 2-6 true peers in one field. Equal weight only when the ideas
161
+ are equal - a 2×2 of causes makes them look like feature cards.
162
+ - **stream** - a path across the canvas: time, sequence, causality,
163
+ escalation, hand-off. The path IS the geometry, not a ruled list.
164
+ - **field** - one chart, table, diagram, or document fragment fills the
165
+ slide; the assertion sits at an edge or inside the field.
166
+ - **bookend** - cover, section turn, closing: a statement or hero that
167
+ ALSO carries the mark and drops the source line, so it reads as a door,
168
+ not a page. Count it as its own silhouette only when that geometry is
169
+ visibly different from the statements around it.
170
+
171
+ The kicker + assertion + hairline over a body is ONE way to build a grid or
172
+ split - it is not the default shell for content slides, and shared margins
173
+ never require shared title geometry. Whitespace needs no defence when it
174
+ establishes dominance; an added companion panel does. Alignment before
175
+ enclosure: if spacing and a hairline establish the group, remove the box -
176
+ cards, panels, and badges are interface furniture, and a deck of them reads
177
+ as a dashboard.
178
+
179
+ ## The space IS the design
180
+
181
+ This is what separates a deck that looks made from one that looks typed.
182
+ The stage is 1280×720 with ASYMMETRIC margins - 88px at the sides, 44px top
183
+ and bottom - so the title sits high, the footnote sits low, and the middle
184
+ is the tallest band on the slide. Content box: **1104×632px**, at every
185
+ viewport. (Override `--marver-slide-pad-x` / `--marver-slide-pad-y` in px,
186
+ never a percentage: a percentage resolves against the viewport, not the
187
+ stage.)
188
+
189
+ When a slide carries a title band (grids and splits usually do; statements,
190
+ heroes, and fields usually do not), the three bands are:
191
+
192
+ | Band | Height | Holds |
193
+ |---|---|---|
194
+ | Title | ~113px | kicker (18px) over the assertion (56px), a hairline under |
195
+ | Body | **~438px** | the recipe - and it is the star, so give it the room |
196
+ | Foot | ~25px | the source slug, or the takeaway bar above it |
197
+
198
+ **The 85% rule.** Content fills at most ~85% of whatever band it lives in
199
+ (≈372 of a 438px body). The remaining sliver is not waste - it is the void
200
+ that makes a slide read as a slide. If your content fills the band, you
201
+ have a document: cut a sentence, drop a card, or split the slide. Never
202
+ close the gap by shrinking type.
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. Local sources require a poster.
237
+ - **Backgrounds are code**: theme-derived gradients, an oversized numeral, a
238
+ clipped photo, one geometric accent. ONE effect per slide, and decoration
239
+ never touches the evidence's contrast.
240
+
241
+ ## The recipes
242
+
243
+ Scan all of them (plus `design/slides.md`) for every slide. Each entry:
244
+ silhouette · skeleton · budget (breach = split, never shrink) · anchor (the
245
+ element that morphs INSIDE a group or build; "none" = a hard cut).
246
+
247
+ 1. **cover** (bookend) - deck title + one line + the mark. Budget: title ≤6
248
+ words. Anchor: the mark.
249
+ 2. **section** (bookend) - an oversized numeral/word divider in
250
+ `sl-display`. Budget: ≤3 words. Anchor: none.
251
+ 3. **assertion-evidence** (split or field) - the workhorse: `sl-assertion`
252
+ + ONE visual. Budget: assertion 1 line, caption 1 line. Anchor: the
253
+ visual.
254
+ 4. **big-number** (hero) - one `sl-display` stat + a context line. Budget:
255
+ 1 stat. Anchor: the number.
256
+ 5. **stat-row** (grid) - 3-4 quick proofs in a row. Budget: each ≤4 words +
257
+ value. Anchor: the row.
258
+ 6. **metric-grid** (grid) - a 2×2 of labeled values. Budget: 4 cells
259
+ exactly. Anchor: the grid.
260
+ 7. **quote** (hero) - the words, the person, nothing else. Budget: ≤30
261
+ words. Anchor: none.
262
+ 8. **quote-wall** (grid) - 3-6 short quotes. Budget: each ≤15 words.
263
+ Anchor: the wall.
264
+ 9. **two-up** (split) - comparison / before-after. Budget: ≤4 rows per
265
+ side. Anchor: the divider.
266
+ 10. **two-stage** (stream) - diagnosis → prescription with a connector.
267
+ Budget: one sentence per stage. Anchor: the connector.
268
+ 11. **numbered-reasons** (grid) - 3-5 ordered points. Budget: each ≤12
269
+ words. Anchor: the numerals.
270
+ 12. **bento** (grid) - 3-5 cells for a system view. Budget: cell = title +
271
+ 1 line. Anchor: the largest cell.
272
+ 13. **timeline** (stream) - a horizontal spine, 3-6 beats. Budget: beat ≤5
273
+ words. Anchor: the spine.
274
+ 14. **roadmap-phases** (stream) - 2-4 phases with contents. Budget: ≤3
275
+ items/phase. Anchor: the phase heads.
276
+ 15. **matrix** (field) - a 2×2 positioning. Budget: ≤6 plotted items.
277
+ Anchor: the axes.
278
+ 16. **full-bleed** (hero) - image + scrim + assertion. Budget: assertion
279
+ only. Anchor: the image.
280
+ 17. **chart-focus** (field) - one `Chart`, near full-slide. Anchor: the
281
+ chart.
282
+ 18. **wall** (grid) - logos/team grid. Budget: 6-12 cells, no captions.
283
+ Anchor: the grid.
284
+ 19. **closing** (bookend) - the ask, one CTA, contact. Budget: ask ≤2
285
+ lines. Anchor: none.
286
+
287
+ These are the core. The atlas in reference/deck-layouts.md carries the rest
288
+ - split, cards, spectrum, insight + evidence, trajectory, table, scenarios,
289
+ flow, cycle, chain, swim lanes, funnel, schedule, layers, concentric,
290
+ pyramid, number line, capability matrix, scorecard, heat map, tracker,
291
+ testimonials, team, manifesto, framed source - each with its budget, plus
292
+ the shared stage, margins, and the optional banded grid they draw from. Scan it for every slide.
293
+
294
+ ## Choreography - the diff IS the animation
295
+
296
+ You never animate. You name elements consistently, and slides mode
297
+ interpolates the difference between adjacent stills. The board is the
298
+ timeline: design motion by designing the diff.
299
+
300
+ **Five verbs** via `view-transition-name` (style prop or class):
301
+
302
+ | Verb | How | Reads as |
303
+ |---|---|---|
304
+ | persist | same name, same box | continuity - the anchor |
305
+ | travel | same name, new position | "follow this" |
306
+ | grow | same name, new size | "this is now the point" |
307
+ | swap | unmatched content | the default crossfade |
308
+ | reveal | new element + `data-animate` | "and then" |
309
+
310
+ **Binding rules:**
311
+ - Adjacent slides inside a visual group or a build share AT LEAST one stable
312
+ named element - the anchor (each recipe names its default above). Across
313
+ a turn of the argument, or into and out of a statement, hero, or bookend,
314
+ a HARD CUT (zero shared names) is the right punctuation - use it. Never
315
+ name the assertion `headline` on every slide as a deck-wide fallback: a
316
+ title that morphs into the next title on seventeen slides is the
317
+ strongest possible signal that every slide has the same shape.
318
+ - AT MOST one element changes position or size per transition. Persist
319
+ freely, travel once.
320
+ - Build steps are sibling frames (`03a-`, `03b-`) sharing morph names -
321
+ progressive disclosure that stays visible and commentable. Variants are
322
+ for exploration, siblings for builds - never both on one slide.
323
+ - Entrances: `data-animate="fade-up | fade | scale-in"` +
324
+ `data-animate-delay="0|1|2|3"`. Never on an element that carries a morph
325
+ name. Runs once, after the transition settles - trust it, don't stack it.
326
+ - Morphs tween bounds and crossfade pixels - a chart "morph" is the picture
327
+ growing, not bars re-plotting. Design for that honestly.
328
+ - One tempo per deck (the root's token). Motion never varies per slide.
329
+ - NOTHING loops, scrolls, or free-runs. A resting slide is still - that is
330
+ what keeps a 40-slide canvas fast, and the review gate checks it.
331
+
332
+ ## Publishing a deck
333
+
334
+ The board is the deck: reading order (top-left to bottom-right) is play
335
+ order - rearrange the board to reorder the deck. Publish with:
336
+
337
+ ```json
338
+ { "boards": { "pitch": { "max": "comment", "type": "slides",
339
+ "open": "slides", "transition": "fade" } } }
340
+ ```
341
+
342
+ `transition`: `fade` (default) or `none`. `chrome`: `full` (default - the
343
+ standard prototype toolbar and walker), `minimal` (a progress strip +
344
+ comments only), or `none`. Add `"lock": true` for a share that is ONLY the
345
+ deck.
346
+
347
+ ## The living list - `design/slides.md`
348
+
349
+ The project's own recipes and rules; it OVERRIDES this file. Its first
350
+ section, **the deck look**, is a fill-in template (tokens, type, the mark,
351
+ colour meaning, imagery, tempo, numbers, voice, terminology, end card): on
352
+ the FIRST deck in a project, draft it from `design/DESIGN.md` and
353
+ `theme.css` as a reviewed edit, tell the human, and build on with the
354
+ theme's tokens meanwhile - fields you cannot settle stay `TBD`, never
355
+ invented. No DESIGN.md yet means the brand doc comes first
356
+ (instructions/brand.md). When the human
357
+ asks you to study `design/slides-inspiration/` (PPTX, PDFs, screenshots),
358
+ propose additions to `design/slides.md` as a normal reviewed edit - each
359
+ with a gap justification (what no existing recipe serves) and a stress pass
360
+ (minimal / typical / worst-case content, both themes) before it earns its
361
+ entry.
362
+
363
+ ## The review gate (run it, every deck, before presenting)
364
+
365
+ Twelve tells, each a defect: label titles · bullet walls · lines past ~15
366
+ words · data without a "so what" · provenance slides (how the work was
367
+ done - a process that IS the subject, an operating model or a rollout plan,
368
+ is content) · hedge language ·
369
+ audience-mismatched jargon · filler words · passive voice · claims missing
370
+ numbers · formatting drift between slides · a weak closing.
371
+
372
+ Then: the sequence test (titles alone tell the argument) · BOTH themes ·
373
+ the slide view AND fill window (the fit scales your composition - check
374
+ nothing relied on the window) and one 390px glance · every slide still at
375
+ rest (no loops, no autoplay) · the silhouette pacing from step 4, checked
376
+ against the storyboard, not the recipe names · anchors inside groups, hard
377
+ cuts at the turns.
378
+
379
+ Then the two reads that catch what polish hides:
380
+ - **Landing, per slide.** Read each slide cold - no presenter, no
381
+ neighbours. Does it deliver the one message you planned for it? Landed ·
382
+ partial (present but buried or hedged) · missed. A missed message on a
383
+ polished slide is still a must-fix.
384
+ - **The cold read, whole deck.** Read every assertion and every takeaway
385
+ bar in sequence, nothing else. Do they alone deliver the one thing the
386
+ human said the audience must leave with? If not, no surface edit fixes it
387
+ - take the gap to the human as a narrative question, do not polish
388
+ around it.
389
+
390
+ Finally the contact sheet: all frames small on the canvas, then squint. If
391
+ the deck blurs into one repeated shape with different fillings, it failed -
392
+ whatever the recipe names say. One silhouette on more than 40% of the
393
+ content slides (decks of eight or more), the same top and bottom horizon on
394
+ every slide, dense slides clumped
395
+ together, accent fills bunched on neighbours, a card row where one card is
396
+ 8 words and the others 40 - each a defect. Iterate until the gate passes; after three passes that
397
+ still surface defects, the remaining list goes to the human and the deck
398
+ ships at their call.