@anvpx/motion 0.0.0-stage → 0.1.1
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/CATALOG.md +301 -0
- package/LICENSE +21 -0
- package/README.md +95 -2
- package/assets.json +37 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +46 -0
- package/icons/LICENSE-lucide +43 -0
- package/icons/icons.json +2711 -0
- package/icons/licences.json +1521 -0
- package/luts/LICENSE-CC0.txt +20 -0
- package/luts/cool.cube +520 -0
- package/luts/noir.cube +520 -0
- package/luts/warm.cube +520 -0
- package/music/LICENSE-CC0.txt +32 -0
- package/music/bed-full.wav +0 -0
- package/music/bed.wav +0 -0
- package/package.json +69 -3
- package/packs/INDEX.md +22 -0
- package/packs/painted/checklist.md +30 -0
- package/packs/painted/examples/dry-ink/storyboard.json +88 -0
- package/packs/painted/examples/oil/storyboard.json +89 -0
- package/packs/painted/examples/shape-carry/storyboard.json +112 -0
- package/packs/painted/examples/stacked-beat/storyboard.json +106 -0
- package/packs/painted/examples/staged-read/storyboard.json +105 -0
- package/packs/painted/examples/watercolour/storyboard.json +79 -0
- package/packs/painted/look.md +71 -0
- package/packs/painted/pack.json +46 -0
- package/packs/painted/review.md +12 -0
- package/packs/painted/voice.md +30 -0
- package/plugins/motion-kit/.claude-plugin/plugin.json +5 -0
- package/plugins/motion-kit/README.md +39 -0
- package/plugins/motion-kit/commands/mk-draft.md +13 -0
- package/plugins/motion-kit/commands/mk-new.md +15 -0
- package/plugins/motion-kit/commands/mk-render.md +14 -0
- package/plugins/motion-kit/skills/motion-kit/SKILL.md +81 -0
- package/plugins/motion-kit/skills/motion-kit/references/authoring-scene.md +48 -0
- package/plugins/motion-kit/skills/motion-kit/references/authoring-style.md +19 -0
- package/plugins/motion-kit/skills/motion-kit/references/common-mistakes.md +73 -0
- package/plugins/motion-kit/skills/motion-kit/references/content-pack.md +69 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-color.md +50 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-composition.md +52 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-critique.md +68 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-motion.md +55 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-narrative.md +54 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-sound.md +53 -0
- package/plugins/motion-kit/skills/motion-kit/references/craft-type.md +54 -0
- package/plugins/motion-kit/skills/motion-kit/references/critique-repair.md +46 -0
- package/plugins/motion-kit/skills/motion-kit/references/decision-packet.md +59 -0
- package/plugins/motion-kit/skills/motion-kit/references/direction.md +84 -0
- package/plugins/motion-kit/skills/motion-kit/references/faux-ui.md +39 -0
- package/plugins/motion-kit/skills/motion-kit/references/free-storyboard.md +15 -0
- package/plugins/motion-kit/skills/motion-kit/references/intake.md +44 -0
- package/plugins/motion-kit/skills/motion-kit/references/knowledge-routing.md +58 -0
- package/plugins/motion-kit/skills/motion-kit/references/outline.md +34 -0
- package/plugins/motion-kit/skills/motion-kit/references/patching.md +50 -0
- package/plugins/motion-kit/skills/motion-kit/references/patterns.md +55 -0
- package/plugins/motion-kit/skills/motion-kit/references/quality-bar.md +61 -0
- package/plugins/motion-kit/skills/motion-kit/references/review.md +8 -0
- package/plugins/motion-kit/skills/motion-kit/references/scene-recipes.md +300 -0
- package/plugins/motion-kit/skills/motion-kit/references/setup.md +16 -0
- package/plugins/motion-kit/skills/motion-kit/references/slop.md +40 -0
- package/plugins/motion-kit/skills/motion-kit/references/storyboard-json.md +121 -0
- package/plugins/motion-kit/skills/motion-kit/references/themes.md +15 -0
- package/plugins/motion-kit/skills/motion-kit/references/troubleshooting.md +55 -0
- package/plugins/motion-kit/skills/motion-kit/references/voice.md +61 -0
- package/plugins/motion-kit/skills/motion-kit/references/worked-decisions.md +178 -0
- package/plugins/motion-kit/skills/motion-kit/references/worked-example.md +170 -0
- package/shared/themes/README.md +5 -0
- package/shared/themes/bold-dark.json +362 -0
- package/shared/themes/bold-light.json +362 -0
- package/shared/themes/calm-dark.json +362 -0
- package/shared/themes/calm-light.json +362 -0
- package/shared/themes/data-dark.json +360 -0
- package/shared/themes/data-light.json +360 -0
- package/shared/themes/editorial-dark.json +353 -0
- package/shared/themes/editorial-light.json +353 -0
- package/shared/themes/fjord-dark.json +124 -0
- package/shared/themes/fjord-light.json +124 -0
- package/shared/themes/playful-dark.json +362 -0
- package/shared/themes/playful-light.json +362 -0
- package/shared/themes/pop-dark.json +352 -0
- package/shared/themes/pop-light.json +352 -0
- package/shared/themes/tech-dark.json +360 -0
- package/shared/themes/tech-light.json +360 -0
- package/shared/themes/warm-dark.json +368 -0
- package/shared/themes/warm-light.json +368 -0
- package/skills/motion-kit/SKILL.md +81 -0
- package/skills/motion-kit/references/authoring-scene.md +48 -0
- package/skills/motion-kit/references/authoring-style.md +19 -0
- package/skills/motion-kit/references/common-mistakes.md +73 -0
- package/skills/motion-kit/references/content-pack.md +69 -0
- package/skills/motion-kit/references/craft-color.md +50 -0
- package/skills/motion-kit/references/craft-composition.md +52 -0
- package/skills/motion-kit/references/craft-critique.md +68 -0
- package/skills/motion-kit/references/craft-motion.md +55 -0
- package/skills/motion-kit/references/craft-narrative.md +54 -0
- package/skills/motion-kit/references/craft-sound.md +53 -0
- package/skills/motion-kit/references/craft-type.md +54 -0
- package/skills/motion-kit/references/critique-repair.md +46 -0
- package/skills/motion-kit/references/decision-packet.md +59 -0
- package/skills/motion-kit/references/direction.md +84 -0
- package/skills/motion-kit/references/faux-ui.md +39 -0
- package/skills/motion-kit/references/free-storyboard.md +15 -0
- package/skills/motion-kit/references/intake.md +44 -0
- package/skills/motion-kit/references/knowledge-routing.md +58 -0
- package/skills/motion-kit/references/outline.md +34 -0
- package/skills/motion-kit/references/patching.md +50 -0
- package/skills/motion-kit/references/patterns.md +55 -0
- package/skills/motion-kit/references/quality-bar.md +61 -0
- package/skills/motion-kit/references/review.md +8 -0
- package/skills/motion-kit/references/scene-recipes.md +300 -0
- package/skills/motion-kit/references/setup.md +16 -0
- package/skills/motion-kit/references/slop.md +40 -0
- package/skills/motion-kit/references/storyboard-json.md +121 -0
- package/skills/motion-kit/references/themes.md +15 -0
- package/skills/motion-kit/references/troubleshooting.md +55 -0
- package/skills/motion-kit/references/voice.md +61 -0
- package/skills/motion-kit/references/worked-decisions.md +178 -0
- package/skills/motion-kit/references/worked-example.md +170 -0
- package/stopwords.json +65 -0
- package/templates/compare/blueprints/versus.json +79 -0
- package/templates/compare/copy.md +18 -0
- package/templates/compare/pacing.json +15 -0
- package/templates/compare/previews/versus.png +0 -0
- package/templates/compare/styles/editorial.json +6 -0
- package/templates/compare/styles/punchy.json +6 -0
- package/templates/compare/styles/tidy.json +6 -0
- package/templates/compare/template.json +52 -0
- package/templates/datastory/blueprints/data-story.json +95 -0
- package/templates/datastory/blueprints/infographic.json +106 -0
- package/templates/datastory/blueprints/trend.json +93 -0
- package/templates/datastory/copy.md +16 -0
- package/templates/datastory/pacing.json +17 -0
- package/templates/datastory/previews/data-story.png +0 -0
- package/templates/datastory/previews/infographic.png +0 -0
- package/templates/datastory/previews/trend.png +0 -0
- package/templates/datastory/styles/clear.json +6 -0
- package/templates/datastory/styles/editorial.json +6 -0
- package/templates/datastory/styles/pop.json +7 -0
- package/templates/datastory/template.json +57 -0
- package/templates/event/blueprints/promo.json +71 -0
- package/templates/event/blueprints/save-the-date.json +61 -0
- package/templates/event/copy.md +16 -0
- package/templates/event/pacing.json +15 -0
- package/templates/event/previews/promo.png +0 -0
- package/templates/event/previews/save-the-date.png +0 -0
- package/templates/event/styles/bright.json +6 -0
- package/templates/event/styles/pop.json +6 -0
- package/templates/event/template.json +37 -0
- package/templates/explain/blueprints/architecture.json +76 -0
- package/templates/explain/blueprints/concept.json +89 -0
- package/templates/explain/blueprints/howto.json +56 -0
- package/templates/explain/blueprints/overview.json +126 -0
- package/templates/explain/copy.md +19 -0
- package/templates/explain/pacing.json +19 -0
- package/templates/explain/previews/architecture.png +0 -0
- package/templates/explain/previews/concept.png +0 -0
- package/templates/explain/previews/howto.png +0 -0
- package/templates/explain/previews/overview.png +0 -0
- package/templates/explain/styles/calm.json +6 -0
- package/templates/explain/styles/crisp.json +6 -0
- package/templates/explain/template.json +64 -0
- package/templates/guide/blueprints/lesson.json +173 -0
- package/templates/guide/blueprints/onboarding.json +80 -0
- package/templates/guide/blueprints/tutorial.json +102 -0
- package/templates/guide/copy.md +17 -0
- package/templates/guide/pacing.json +59 -0
- package/templates/guide/previews/lesson.png +0 -0
- package/templates/guide/previews/onboarding.png +0 -0
- package/templates/guide/previews/tutorial.png +0 -0
- package/templates/guide/styles/calm.json +15 -0
- package/templates/guide/styles/friendly.json +15 -0
- package/templates/guide/styles/techdark.json +15 -0
- package/templates/guide/template.json +95 -0
- package/templates/pitch/blueprints/feature.json +134 -0
- package/templates/pitch/blueprints/launch.json +173 -0
- package/templates/pitch/blueprints/pricing.json +141 -0
- package/templates/pitch/copy.md +18 -0
- package/templates/pitch/pacing.json +59 -0
- package/templates/pitch/previews/feature.png +0 -0
- package/templates/pitch/previews/launch.png +0 -0
- package/templates/pitch/previews/pricing.png +0 -0
- package/templates/pitch/styles/polished.json +6 -0
- package/templates/pitch/styles/punchy.json +6 -0
- package/templates/pitch/styles/teaser.json +12 -0
- package/templates/pitch/template.json +45 -0
- package/templates/recap/blueprints/news-recap.json +62 -0
- package/templates/recap/blueprints/timeline-story.json +94 -0
- package/templates/recap/copy.md +16 -0
- package/templates/recap/pacing.json +16 -0
- package/templates/recap/previews/news-recap.png +0 -0
- package/templates/recap/previews/timeline-story.png +0 -0
- package/templates/recap/styles/editorial.json +6 -0
- package/templates/recap/styles/editorialdark.json +6 -0
- package/templates/recap/template.json +50 -0
- package/templates/report/blueprints/kpi-review.json +116 -0
- package/templates/report/blueprints/status.json +78 -0
- package/templates/report/copy.md +17 -0
- package/templates/report/pacing.json +16 -0
- package/templates/report/previews/kpi-review.png +0 -0
- package/templates/report/previews/status.png +0 -0
- package/templates/report/styles/exec.json +6 -0
- package/templates/report/styles/memo.json +6 -0
- package/templates/report/styles/walkthrough.json +6 -0
- package/templates/report/template.json +56 -0
- package/templates/social/blueprints/announce.json +109 -0
- package/templates/social/blueprints/listicle.json +117 -0
- package/templates/social/blueprints/tip.json +114 -0
- package/templates/social/copy.md +18 -0
- package/templates/social/pacing.json +49 -0
- package/templates/social/previews/announce.png +0 -0
- package/templates/social/previews/listicle.png +0 -0
- package/templates/social/previews/tip.png +0 -0
- package/templates/social/styles/captioned.json +18 -0
- package/templates/social/styles/hook-first.json +15 -0
- package/templates/social/styles/techcut.json +15 -0
- package/templates/social/template.json +94 -0
- package/templates/update/blueprints/announcement.json +57 -0
- package/templates/update/blueprints/changelog.json +157 -0
- package/templates/update/blueprints/release-notes.json +151 -0
- package/templates/update/blueprints/weekly-update.json +88 -0
- package/templates/update/copy.md +17 -0
- package/templates/update/pacing.json +64 -0
- package/templates/update/previews/announcement.png +0 -0
- package/templates/update/previews/changelog.png +0 -0
- package/templates/update/previews/release-notes.png +0 -0
- package/templates/update/previews/weekly-update.png +0 -0
- package/templates/update/styles/punchy.json +15 -0
- package/templates/update/styles/techdark.json +6 -0
- package/templates/update/styles/tidy.json +6 -0
- package/templates/update/template.json +67 -0
- package/templates/vista/blueprints/spotlight.json +68 -0
- package/templates/vista/blueprints/tour.json +84 -0
- package/templates/vista/copy.md +18 -0
- package/templates/vista/pacing.json +14 -0
- package/templates/vista/previews/spotlight.png +0 -0
- package/templates/vista/previews/tour.png +0 -0
- package/templates/vista/styles/bright.json +6 -0
- package/templates/vista/styles/cinematic.json +6 -0
- package/templates/vista/template.json +42 -0
- package/templates/walkthrough/blueprints/product-tour.json +107 -0
- package/templates/walkthrough/copy.md +16 -0
- package/templates/walkthrough/pacing.json +16 -0
- package/templates/walkthrough/previews/product-tour.png +0 -0
- package/templates/walkthrough/styles/calm.json +6 -0
- package/templates/walkthrough/styles/deep.json +6 -0
- package/templates/walkthrough/template.json +37 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# What never ships
|
|
2
|
+
|
|
3
|
+
Historical style heuristics attributed to a skill built on 53 frame-measured moments and rejected AI films. The underlying corpus and measurements are not qualified by this package. Use the observations to question an unchosen habit, not to define a permissible style.
|
|
4
|
+
|
|
5
|
+
These are style defaults and judgement calls, not engine rules: when the brief earns one of these deliberately, it is allowed — name the exception and its reason in the outline instead of following the list mechanically.
|
|
6
|
+
|
|
7
|
+
## Examine unchosen defaults
|
|
8
|
+
|
|
9
|
+
1. **Page chrome:** a name in a corner, counters ("02 / 05"), timecodes, progress bars, corner brackets.
|
|
10
|
+
2. **Deck layouts:** a held left headline, a kicker above a headline, headline-left/device-right.
|
|
11
|
+
3. **Generic UI:** a rounded card with a status dot and "label . value", skeleton bars, invented numbers.
|
|
12
|
+
4. **The name's first association:** stars for a star, a rocket for "launch".
|
|
13
|
+
5. **Invented stats**, stat walls, on-screen disclaimers.
|
|
14
|
+
6. **Slogan copy:** "Not just X. It's Y.", "Unlock", "Meet X", "the future of".
|
|
15
|
+
7. **The house style as default:** a giant cropped word, a colour-flood wipe, a dot becoming the logo.
|
|
16
|
+
8. **A flat swatch ground per scene**, or a small card on a void.
|
|
17
|
+
9. **A pinned object** at the same coordinates through three shots.
|
|
18
|
+
10. **A web-footer ending:** logo + tagline + button + URL.
|
|
19
|
+
11. **Self-certification:** claiming a gate passed without quoting its number.
|
|
20
|
+
12. **A film you did not look at.**
|
|
21
|
+
|
|
22
|
+
## Historical motion hypotheses
|
|
23
|
+
|
|
24
|
+
These source-specific observations are starting points for a short, energetic treatment, not measured laws of animation. Their counts and ranges have not been independently reproduced here; preview alternatives against the direction.
|
|
25
|
+
|
|
26
|
+
- The source reports a median move of **10 frames (0.33 s)** and travel concentrated in the first 4-8 frames. Longer movement may be necessary for distance, weight or reading.
|
|
27
|
+
- Decelerating arrivals and accelerating exits can make a hand-off decisive. Spring count follows material and meaning rather than a per-film quota.
|
|
28
|
+
- The source reports **3,392 transform entries against 584 opacity fades**. That ratio does not disqualify a dissolve, atmospheric fade or a film built around opacity.
|
|
29
|
+
- An oversize arrival (the source's logo example starts around 3.5x) can express force. Growth from zero can instead communicate emergence when that is the intended idea.
|
|
30
|
+
- A living detail can sustain a held frame. Complete stillness and rest can also give information or emotion time to land.
|
|
31
|
+
- The source's **0.3-2.3 s cuts on motion** suit one pacing vocabulary. Cuts on rest, long takes and slow cinema remain valid choices.
|
|
32
|
+
- The source's **0.6-1.4 s end hold** and shrinking ending are options. Reading load, sound and narrative closure determine the actual hold and scale.
|
|
33
|
+
|
|
34
|
+
## Type sizes, as a fraction of frame height
|
|
35
|
+
|
|
36
|
+
Optional source examples: headline 7-11 % (9 typical) · support 5-7 % · hero number 22-29 % · wordmark 0.22-0.38 of width. They are not engine limits; choose and preview a hierarchy for the actual words, aspect and viewing conditions.
|
|
37
|
+
|
|
38
|
+
## Fix order when it looks wrong
|
|
39
|
+
|
|
40
|
+
broken or untrue → the idea → connections between beats → hierarchy and scale → timing → surface → sound.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Storyboard JSON: the one file you write
|
|
2
|
+
|
|
3
|
+
`mk validate` checks schema, scene props, timing and lint. It is strict: an unknown key is an error, not a warning. Read the pointer in the error, fix that one thing, and use `references/patching.md` after the first write.
|
|
4
|
+
|
|
5
|
+
## Smallest valid shape
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"version": 1,
|
|
10
|
+
"meta": {
|
|
11
|
+
"title": "How a request reaches the data",
|
|
12
|
+
"width": 1920,
|
|
13
|
+
"height": 1080,
|
|
14
|
+
"fps": 30,
|
|
15
|
+
"theme": "default"
|
|
16
|
+
},
|
|
17
|
+
"scenes": [
|
|
18
|
+
{
|
|
19
|
+
"id": "intro",
|
|
20
|
+
"type": "title",
|
|
21
|
+
"duration": 4,
|
|
22
|
+
"move": "push-in",
|
|
23
|
+
"props": { "title": "How a request reaches the data" }
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "end",
|
|
27
|
+
"type": "outro",
|
|
28
|
+
"duration": 4,
|
|
29
|
+
"move": "push-in",
|
|
30
|
+
"props": { "title": "One public door" }
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`version` is literally `1`. There is no version 2 and no migration command; a board with another version is invalid.
|
|
37
|
+
|
|
38
|
+
## meta
|
|
39
|
+
|
|
40
|
+
| Key | Rule |
|
|
41
|
+
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| `title` | required, non-empty |
|
|
43
|
+
| `width` | pixels; default 1920. There is no `aspect` key: 16:9 = 1920x1080, 9:16 = 1080x1920, 1:1 = 1080x1080 |
|
|
44
|
+
| `height` | pixels; default 1080 |
|
|
45
|
+
| `fps` | integer; default 30 |
|
|
46
|
+
| `theme` | default `default`. Built-ins: `default`, `dark`, `tech-dark`, `calm-dark`. A template theme must be vendored into `themes/` (a `mk new` project does this; copying only the JSON elsewhere loses it) |
|
|
47
|
+
| `lang` | optional language code |
|
|
48
|
+
| `platform` | optional delivery-platform id: `facebook`, `linkedin`, `tiktok`, `youtube`, `podcast`, `reels`, `shorts`, `x`; adds that platform's safe margins. An unknown slug still validates, so pick from this list |
|
|
49
|
+
| `approval` | optional `auto` or `confirm`; absent means auto |
|
|
50
|
+
|
|
51
|
+
`mk validate` does not resolve `theme`; `mk build` and `mk preview` do. A board can validate and still fail at preview with `unknown theme "..."`. Check the theme before preview when you wrote the board by hand.
|
|
52
|
+
|
|
53
|
+
## Scene keys
|
|
54
|
+
|
|
55
|
+
| Key | Rule |
|
|
56
|
+
| ---------------- | ----------------------------------------------------------------------------------------- |
|
|
57
|
+
| `id` | required, unique, lowercase slug (`a-z`, `0-9`, hyphens) |
|
|
58
|
+
| `type` | required; exactly a name from `mk catalog` |
|
|
59
|
+
| `duration` | optional positive seconds; omitted = automatic from the text. Lint enforces reading time |
|
|
60
|
+
| `props` | required object; strict. Only fields shown by `mk catalog <type>`, unlisted keys rejected |
|
|
61
|
+
| `narration` | optional spoken text for the voice path |
|
|
62
|
+
| `words` | optional voice word timings, normally written by the voice tool |
|
|
63
|
+
| `shot` | optional `wide`, `medium`, `close`, `overhead` |
|
|
64
|
+
| `move` | optional `static`, `push-in`, `pull-out`, `pan-l`, `pan-r`, `tilt`, `orbit`, `reveal` |
|
|
65
|
+
| `ease` | optional `linear`, `in`, `out`, `in-out`, `spring-soft`, `spring-snappy` |
|
|
66
|
+
| `transition` | optional `cut`, `crossfade`, `wipe`, `push`, `zoom-through`; base scenes only |
|
|
67
|
+
| `focus` | optional label used by review |
|
|
68
|
+
| `layer` | optional `base` or `overlay`; omit for base |
|
|
69
|
+
| `over`, `offset` | overlays only: the base scene id they cover, and seconds into it (default 0) |
|
|
70
|
+
|
|
71
|
+
Defaults belong to the renderer; do not invent direction values. `mk catalog` lists prop defaults, not direction defaults.
|
|
72
|
+
|
|
73
|
+
## Base and overlay
|
|
74
|
+
|
|
75
|
+
- A base scene advances the timeline. An overlay stacks above it and does not advance it.
|
|
76
|
+
- The overlay types are `lower-third`, `bug`, `progress`, `countdown`, `chapter`, `caption`.
|
|
77
|
+
- Every overlay needs `layer: "overlay"`, `over: "<base id>"` and its own `duration` that fits inside the base scene. It does not take `transition`.
|
|
78
|
+
- `offset` is seconds after the base scene starts.
|
|
79
|
+
- A board with no base scene is invalid.
|
|
80
|
+
- A base scene never takes `over` or `offset`.
|
|
81
|
+
|
|
82
|
+
## Timing
|
|
83
|
+
|
|
84
|
+
- Durations are seconds. A base scene's total is its own `duration`; overlays sit inside their base scene.
|
|
85
|
+
- Transitions overlap adjacent base scenes, so the total is not simply the sum of durations. The worked example's four durations (4+6+4+4) plus three crossfades total 16.5 s.
|
|
86
|
+
- `mk validate` reports errors and warnings, not the total. The total is printed by `mk patch`, `mk scene add`, `mk fit` and `mk preview`; use one of those (or read `preview.json`'s `totalSec`).
|
|
87
|
+
- Lint enforces minimum hold and reading time (about 3 words per second of visible text, including the title and lines, not narration). A 6 s scene with only a short list still warns if nothing changes; add a `move`, shorten it, or split it.
|
|
88
|
+
- About one new scene per 7 s is a useful planning number; `mk fit` can move the total only about 1.4x.
|
|
89
|
+
|
|
90
|
+
## Props
|
|
91
|
+
|
|
92
|
+
- Use the exact example shape from `mk catalog <type>`. Copy the example's key names, then replace values; do not rename keys or add explanatory fields.
|
|
93
|
+
- Text limits are per field and are hard at validation (`<=70` means 70 characters, not words).
|
|
94
|
+
- `[x]` marks an accent word in types that document it; do not use it as HTML.
|
|
95
|
+
- Icons are names, not URLs: `mk icon search <word>` or `mk icon list [--tag group]`.
|
|
96
|
+
- Images are local paths inside the project, with an `assets.json` ledger row. Remote URLs fail closed. Import with `mk assets import`, then pass the same `--assets` and `--ledger` to build, preview, approve and render; the image path is relative to `--assets`.
|
|
97
|
+
- `highlight` is not uniform: `chart` and `table` use a 0-based item index; `code` uses an array of 1-based line numbers, for example `[1,3]`. The catalog currently prints the code field as a scalar, but the schema and validator require the array.
|
|
98
|
+
- `chart`: `bar` and `donut` need `data`; `line` needs `x` and `series`; `highlight` is 0-based. `kpi-grid`: `trend` (`up|down|flat`) needs `delta`; `good` (`up|down`) needs `trend`.
|
|
99
|
+
- `media-frame.callouts`: `x` and `y` are percentages 0-100, and each `label` is at most 24 characters.
|
|
100
|
+
- An empty required text field is an error. Keep the copy short enough to read at phone width.
|
|
101
|
+
|
|
102
|
+
## Decode these errors
|
|
103
|
+
|
|
104
|
+
| Message | Fix |
|
|
105
|
+
| -------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
106
|
+
| `unknown key(s): typo -> remove typo (check spelling against the catalog)` | remove the key or `mk catalog <type>` for the real field |
|
|
107
|
+
| `must be a lowercase slug (a-z, 0-9, hyphens)` | rename the scene id |
|
|
108
|
+
| `overlay needs over: <base scene id>` | add `over` pointing at an existing base id |
|
|
109
|
+
| `duplicate scene id "x"` | give every scene a unique id |
|
|
110
|
+
| `unknown theme "x"; use one of: ...` (at build/preview) | use a built-in theme, a vendored `themes/x.json`, or `mk new` |
|
|
111
|
+
| `parent "/scenes/9" does not exist` (patch) | add the parent first, or use a path that exists |
|
|
112
|
+
|
|
113
|
+
## Writing checklist
|
|
114
|
+
|
|
115
|
+
1. `version` is 1; `meta.title`, `width`, `height`, `fps`, `theme` are present.
|
|
116
|
+
2. Every scene id is unique and a slug; every `type` came from `mk catalog`.
|
|
117
|
+
3. Every base scene has a `move` and a `duration`.
|
|
118
|
+
4. Every overlay has `layer`, `over`, `duration` and no `transition`; it fits its base.
|
|
119
|
+
5. Every prop key came from `mk catalog <type>`; every text is within its limit.
|
|
120
|
+
6. Every image exists locally and has a ledger row.
|
|
121
|
+
7. `mk validate` prints `0 errors`; read warnings, do not ignore them.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Themes and the 3D look
|
|
2
|
+
|
|
3
|
+
## Themes
|
|
4
|
+
|
|
5
|
+
The package ships 18 DTCG themes, light and dark: `bold`, `calm`, `data`, `editorial`, `fjord`, `playful`, `pop`, `tech`, `warm`.
|
|
6
|
+
|
|
7
|
+
`mk new` vendors the theme its blueprint uses under `themes/`. To use another, copy `<installed package>/shared/themes/<name>.json` (and its pair, for paired stills) into `themes/` beside the storyboard, then set `meta.theme` with `mk patch`. There is no `mk theme list`; this is the list.
|
|
8
|
+
|
|
9
|
+
For luxury or editorial work, `editorial-*` (serif, ink) and `warm-*` (cream, terracotta) read quieter; `bold-*` (amber on violet) and `tech-*` read louder. Name the choice; the theme is part of the approval hash when vendored.
|
|
10
|
+
|
|
11
|
+
## 3D
|
|
12
|
+
|
|
13
|
+
`scene3d` is a procedural WebGL diorama, not a GLB importer. `model` selects `knot` (default), `gem` (faceted stone), `sphere` or `torus`; `material` is `clay|gloss|metal|emissive`; `post` is `clean|bloom|cinematic|vintage`; `light`/`hdri` are `studio|sunset|night|soft` / `neutral|studio|sunset|night`.
|
|
14
|
+
|
|
15
|
+
For a luxury abstract hero, try `model: gem`, `material: metal`, `light: sunset`, `post: cinematic`, `hdri: sunset` on a dark theme. There is no model upload: use it for an abstract form, not a replica of a specific product. Without WebGL it falls back to a flat 2D canvas; say so when that matters.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Troubleshooting and exit codes
|
|
2
|
+
|
|
3
|
+
Read the first `E` line, not the whole log. It names a pointer and usually a suggestion. Fix that one thing, re-run, then read the next.
|
|
4
|
+
|
|
5
|
+
## First response
|
|
6
|
+
|
|
7
|
+
1. `mk validate` / `mk preview`: read the pointer, compare that scene with `mk catalog <type>`, patch only that scene.
|
|
8
|
+
2. Same error twice: stop changing flags. Rewrite the named scene from its catalog example via `mk patch`, or choose a different type.
|
|
9
|
+
3. Third failure: stop. Tell the user the exact error and the two routes you tried; do not loop.
|
|
10
|
+
4. Never disable lint, raise a limit by editing the output, or hand-edit the JSON to get past a gate.
|
|
11
|
+
|
|
12
|
+
## Exit codes
|
|
13
|
+
|
|
14
|
+
| Exit | Meaning | Do |
|
|
15
|
+
| ---- | -------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
16
|
+
| 0 | success (warnings allowed) | continue; read the warnings |
|
|
17
|
+
| 1 | tool, build or render failure | `mk doctor`; read the last lines and `render-log.txt` |
|
|
18
|
+
| 2 | bad flags, unreadable file, validation errors, no preview for `mk approve` | fix the named pointer; run `mk preview` before approve |
|
|
19
|
+
| 4 | AWAITING_APPROVAL (`--gated`) | not an error: show the pack, ask, `mk approve` only on a yes |
|
|
20
|
+
| 5 | QA failed (`mk verify`) | fix the named scene or param, re-render once, then report |
|
|
21
|
+
| 127 | required program missing | give the install hint from `mk doctor`; do not retry blindly |
|
|
22
|
+
|
|
23
|
+
## Named failures
|
|
24
|
+
|
|
25
|
+
| Symptom | Cause / fix |
|
|
26
|
+
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
27
|
+
| `unknown key(s): typo` | prop not in the catalog: remove it or `mk catalog <type>` |
|
|
28
|
+
| `must be a lowercase slug` | scene id has spaces or capitals; rename to `a-z`, `0-9`, hyphens |
|
|
29
|
+
| `overlay needs over: <base scene id>` | add `"over": "<existing base id>"` and a fitting `duration` |
|
|
30
|
+
| `duplicate scene id "x"` | every id must be unique |
|
|
31
|
+
| `unknown theme "x"; use one of: ...` | built-in theme, vendored `themes/x.json`, or `mk new`; `mk validate` does not catch this. If the theme is not built-in, preview before calling stage 5 done |
|
|
32
|
+
| `mk approve` exits 2 after a preview | the preview used `--out`/`--assets`/`--ledger`/audio flags; repeat those exact flags. The printed `approve:` hint may omit `--out`, so do not trust it alone |
|
|
33
|
+
| `no ledger row` or `no assetsDir` | run `mk assets import` for each file, then pass the same `--assets d --ledger f` to build/preview/approve/render; `image` is relative to `--assets` |
|
|
34
|
+
| `parent "/scenes/9" does not exist` | patch path skips a level; add the parent first or target an existing path |
|
|
35
|
+
| `mk new` slot error (`max 5`, `text<=...`) | shorten or merge; never edit the generated board past the slot limit |
|
|
36
|
+
| `mk fit` refuses "over the X s" | the scenes cannot stretch that far: `mk scene add`, then fit; never pad or stretch past the range |
|
|
37
|
+
| `mk approve` exits 2 | no preview for the current inputs, or a flag differs from preview; re-preview |
|
|
38
|
+
| `mk render --gated` exits 4 | no approval or the inputs changed; preview again and ask again |
|
|
39
|
+
| Preview exits 2 | lint or validation failed; read the still/scene it names |
|
|
40
|
+
| `verify` exit 5 | read the report line: streams, duration, fps or frame count; fix the named scene, render once |
|
|
41
|
+
| `mk captions` asks for `--storyboard` | ops need scene-relative paths; add the board |
|
|
42
|
+
| `mk voice` fails closed | Python 3.12 venv or voice extras missing; `mk doctor`; ship silent if unavailable |
|
|
43
|
+
| Preview says the clip was skipped | budget ran out; stills are still valid; offer `--budget-sec` |
|
|
44
|
+
| `mk state` exits 1 | an artifact claims more than its inputs prove; fix the overclaim, do not re-preview blindly |
|
|
45
|
+
| No vision / cannot open the image | say so; read `preview.json`; ask the user to open the pack and approve |
|
|
46
|
+
|
|
47
|
+
## Recover without a rewrite
|
|
48
|
+
|
|
49
|
+
- Wrong wording or number: `mk patch` replace the leaf.
|
|
50
|
+
- Wrong pacing: `mk patch` replace `duration`, or `mk fit --seconds N`.
|
|
51
|
+
- Wrong structure: `mk scene remove|move|add`, then validate.
|
|
52
|
+
- Wrong look: change the theme or the direction fields, not the copy.
|
|
53
|
+
- Wrong route: restart from `mk new` or `mk scene new`; do not bolt a second route onto a broken board.
|
|
54
|
+
|
|
55
|
+
After any successful edit the approval is stale. Preview again, then ask.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Voice and captions (opt-in)
|
|
2
|
+
|
|
3
|
+
The engine renders silent by default. Add narration only when the user asked for it or approved it. Never imply sound that is not in the preview.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Needs Python 3.12, espeak-ng and the voice extras; see `references/setup.md`. `mk doctor` prints the voice rows, and missing voice tools never fail the overall exit code. If the venv is missing, say so and ship silent; do not fake timings or substitute a different voice.
|
|
8
|
+
|
|
9
|
+
## Narration
|
|
10
|
+
|
|
11
|
+
1. Add `"narration": "..."` to each base scene that speaks. Overlays are skipped. Write the words as they should be spoken, not as slide copy.
|
|
12
|
+
2. **Write numbers as words.** The aligner matches letters; a token with no letters (`01`, `$480`, `1,200`) cannot be aligned and `mk voice` refuses before synthesis. Say "zero one", "four hundred eighty", "twelve hundred". The visual copy can keep digits.
|
|
13
|
+
3. The manifest is a non-overlapping speech sequence. The film keeps each scene's authored duration and places the wav at that scene's start; a scene that ends in silence is normal. Voice never compresses the authored picture.
|
|
14
|
+
4. Keep the words final before synthesis: `mk voice` needs the final script, and a later text edit invalidates the timing.
|
|
15
|
+
5. `mk voice storyboard.json --voice <id>` writes a voice TimingManifest; the stdout line names it. Use a voice the user approved; do not hardcode one silently.
|
|
16
|
+
6. The command preflights the narration against the scene duration and refuses before synthesis when it cannot fit, or when a number is not written out. The silence gate can also refuse words that land inside silence. Fix the script or the scene duration; never edit the manifest to hide it.
|
|
17
|
+
7. `mk qc` gates the manifest plus audio and reports PASS, WARN, FAIL or UNKNOWN. Quote its result; a synthetic file is not human-quality proof.
|
|
18
|
+
|
|
19
|
+
## Music
|
|
20
|
+
|
|
21
|
+
Music is opt-in; without `--music` the film is narration-only or silent. The installed package ships:
|
|
22
|
+
|
|
23
|
+
- `music/bed-full.wav` — a 32 s stereo CC0 ambient bed (use this one).
|
|
24
|
+
- `music/bed.wav` — a 1 s procedural silence placeholder; `--music` rejects it as silent.
|
|
25
|
+
|
|
26
|
+
Pass the identical bed, volume and licence to `mk preview`, `mk approve` and `mk render`:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
mk preview storyboard.json --audio .mk/<name>/voice-manifest.json \
|
|
30
|
+
--music node_modules/@anvpx/motion/music/bed-full.wav --music-volume 0.35 \
|
|
31
|
+
--music-license node_modules/@anvpx/motion/music/LICENSE-CC0.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The bed loops to the narration length and ducks under the voice. Approval binds the bed bytes, volume and licence receipt; any drift exits 4. A visual-only receipt never authorises music.
|
|
35
|
+
|
|
36
|
+
## Captions
|
|
37
|
+
|
|
38
|
+
- `mk captions <manifest> --storyboard storyboard.json --out ops.json` turns voice word timings into one karaoke `caption` overlay per narrated scene, already shifted to scene-relative time.
|
|
39
|
+
- Apply the ops with `mk patch storyboard.json --ops ops.json`. Words past the scene duration are omitted and reported; do not silently keep them.
|
|
40
|
+
- Keep each cue readable: about 20 characters/second, at most 2 lines and 42 characters per line. Shorten the text or split the cue rather than shrinking the type.
|
|
41
|
+
- Export subtitles with `--srt file.srt` or `--vtt file.vtt`. Import existing cues with `--from-srt` or `--from-vtt`; import still needs `--storyboard` because the overlays need scene positions.
|
|
42
|
+
- Preview again after adding captions. The approval covers the captions as part of the storyboard.
|
|
43
|
+
|
|
44
|
+
## Audio and approval
|
|
45
|
+
|
|
46
|
+
- `mk preview` accepts `--audio <manifest>`; `mk approve` infers it from the pack. Pass the same `--audio` to preview, approve and render.
|
|
47
|
+
- The approval binds the storyboard, themes, assets, ledger, audio manifest and wavs. Any later wav, manifest or scene edit exits 4 at render; preview and ask again.
|
|
48
|
+
- Optional music uses `--music`, `--music-volume` and `--music-license` on all three commands. A visual-only receipt never authorizes audio; narration-only never authorizes music.
|
|
49
|
+
- If the preview clip is silent, say so in the ask. Do not describe the film as narrated until the audible preview exists.
|
|
50
|
+
|
|
51
|
+
## Failure paths
|
|
52
|
+
|
|
53
|
+
| Symptom | Do |
|
|
54
|
+
| ----------------------------------- | ----------------------------------------------------------------------- |
|
|
55
|
+
| `mk voice` not installed / exit 127 | `mk doctor`; give the install hint; ship silent only if the user agrees |
|
|
56
|
+
| token `"01"` has no letters | write the number as spoken ("zero one"); digits stay in the visual copy |
|
|
57
|
+
| word inside silence | rewrite the pause/sentence or lengthen that scene; never edit timings |
|
|
58
|
+
| narration refused before synthesis | shorten the words or lengthen that scene; never edit timings |
|
|
59
|
+
| `mk qc` WARN or UNKNOWN | report the exact state; do not call it PASS |
|
|
60
|
+
| `mk captions` omits words | tell the user which scene and how many; adjust the script or duration |
|
|
61
|
+
| render exit 4 after audio work | the audio inputs drifted from approval; re-preview and re-approve |
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Worked decisions: what a choice costs
|
|
2
|
+
|
|
3
|
+
Read this after a provisional direction exists, not before. These are three
|
|
4
|
+
annotated compositions from controlled authoring fixtures. They teach the
|
|
5
|
+
reasoning behind a shot, not a look to copy. Technical validity is not an
|
|
6
|
+
aesthetic verdict; no example was reviewed for professional quality.
|
|
7
|
+
|
|
8
|
+
## How to use a precedent
|
|
9
|
+
|
|
10
|
+
For each example, separate the **decision** from the surface. Ask:
|
|
11
|
+
|
|
12
|
+
1. What question did this composition answer?
|
|
13
|
+
2. What did it reject, and what did that cost?
|
|
14
|
+
3. Which mechanism carries the meaning (crop, route, scale, rhythm, sound)?
|
|
15
|
+
4. What would make the same mechanism wrong for another brief?
|
|
16
|
+
5. What is the smallest native realization, and what evidence would falsify it?
|
|
17
|
+
|
|
18
|
+
If your brief shares the question but not the audience, channel or tone, keep the
|
|
19
|
+
question and change the answer.
|
|
20
|
+
|
|
21
|
+
## Example 1 — an invitation, not an announcement
|
|
22
|
+
|
|
23
|
+
**Brief:** a public-library reading night; about 20 s; 16:9; quiet, adult,
|
|
24
|
+
local. The viewer should feel invited to a room, not sold a program.
|
|
25
|
+
|
|
26
|
+
**Question:** how can type feel discovered rather than announced?
|
|
27
|
+
|
|
28
|
+
**Rejected:** title, date, three bullet benefits, logo. It is accurate, but it
|
|
29
|
+
turns the film into a poster with a voice-over; the viewer is told, not drawn in.
|
|
30
|
+
|
|
31
|
+
**Chosen relationship:** a printed sheet is uncovered from a vertical crop on an
|
|
32
|
+
asymmetric left editorial grid. One large statement, one small mono label, and
|
|
33
|
+
a lot of paper. The reveal follows reading order.
|
|
34
|
+
|
|
35
|
+
**Why motion serves meaning:** the vertical crop is the invitation; the hold
|
|
36
|
+
after the statement is the pause before someone decides to come. A push-in or
|
|
37
|
+
orbit would add urgency the event does not want. Rest is part of the argument.
|
|
38
|
+
|
|
39
|
+
**Native realization:** a `custom` scene with a 12-column grid; the statement
|
|
40
|
+
spans columns 1-7 and the meta line sits at 1-4. On each `seek(t)`, derive one
|
|
41
|
+
progress value and assign clip-path and translate from it; never accumulate
|
|
42
|
+
from the previous frame.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// import { progress } from "../../runtime/compose.js";
|
|
46
|
+
export function createScene(root) {
|
|
47
|
+
const sheet = root.querySelector(".sheet");
|
|
48
|
+
return {
|
|
49
|
+
seek(t) {
|
|
50
|
+
const p = progress(t, 0.2, 0.9);
|
|
51
|
+
sheet.style.clipPath = `inset(${(1 - p) * 18}% 0 0 0)`;
|
|
52
|
+
sheet.style.transform = `translateY(${(1 - p) * 24}px)`;
|
|
53
|
+
},
|
|
54
|
+
dispose() {},
|
|
55
|
+
ready: Promise.resolve(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Inspected evidence:** the pre-reveal frame, the 2 s settle frame, and a
|
|
61
|
+
phone-width crop of the statement. The fixture was reviewed as stills; its sound
|
|
62
|
+
was not synthesized or heard.
|
|
63
|
+
|
|
64
|
+
**Failure mode:** a reveal under about half a second reads as a glitch, and a
|
|
65
|
+
statement wider than its column measure loses the "uncovered page" reading.
|
|
66
|
+
**Counterexample:** a formal institutional brand may need symmetry and a crest;
|
|
67
|
+
the asymmetry would fight that identity.
|
|
68
|
+
**Adaptation exercise:** move the same brief to late-night radio. Which
|
|
69
|
+
mechanism survives (crop, hold, one statement), and what must change (type,
|
|
70
|
+
colour, sound)?
|
|
71
|
+
|
|
72
|
+
## Same brief, another concept
|
|
73
|
+
|
|
74
|
+
For the reading-night brief, a second concept is a single overhead view of a long
|
|
75
|
+
table with one lamp and one empty chair. The type is a small label on the table,
|
|
76
|
+
not a poster; the camera holds, and the only movement is the lamp warming up.
|
|
77
|
+
It answers a different viewer effect (intimacy, not discovery) and would use a
|
|
78
|
+
slow hold with no crop reveal. Neither concept is universally better: the word
|
|
79
|
+
"invitation" and the channel decide. If the client needs programme clarity, the
|
|
80
|
+
poster concept wins; if the event sells atmosphere, the table concept wins. The
|
|
81
|
+
two differ in composition and motion, not palette.
|
|
82
|
+
|
|
83
|
+
## Example 2 — causality along a route
|
|
84
|
+
|
|
85
|
+
**Brief:** explain how rain becomes drinking water in about 40 s for teenagers;
|
|
86
|
+
calm voice; visually clear. Facts are supplied; no number may be invented.
|
|
87
|
+
|
|
88
|
+
**Question:** how do you show a process without a four-step bullet list?
|
|
89
|
+
|
|
90
|
+
**Rejected:** four labeled stages in equal cards. It is correct and forgettable:
|
|
91
|
+
the viewer reads labels, not causality, and every stage has the same weight.
|
|
92
|
+
|
|
93
|
+
**Chosen relationship:** three spatial zones (catchment, treatment, reservoir)
|
|
94
|
+
connected by one route. The viewer follows water across the frame; labels
|
|
95
|
+
confirm what the movement already showed.
|
|
96
|
+
|
|
97
|
+
**Why motion serves meaning:** the path is the causal argument. A label arrives
|
|
98
|
+
after the path reaches its zone, so the viewer sees the connection before
|
|
99
|
+
naming it. A cut between stages would break the continuity the explanation
|
|
100
|
+
depends on.
|
|
101
|
+
|
|
102
|
+
**Native realization:** a `custom` scene with one SVG path. `getTotalLength`
|
|
103
|
+
and `getPointAtLength` are deterministic; drive a marker and each zone's
|
|
104
|
+
emphasis from one progress value.
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
// import { ease, progress } from "../../runtime/compose.js";
|
|
108
|
+
const route = root.querySelector("#route");
|
|
109
|
+
const marker = root.querySelector("#marker");
|
|
110
|
+
const length = route.getTotalLength();
|
|
111
|
+
|
|
112
|
+
export function createScene() {
|
|
113
|
+
return {
|
|
114
|
+
seek(t) {
|
|
115
|
+
const p = ease("in-out", progress(t, 0.4, 4.2));
|
|
116
|
+
const point = route.getPointAtLength(p * length);
|
|
117
|
+
marker.setAttribute("transform", `translate(${point.x} ${point.y})`);
|
|
118
|
+
},
|
|
119
|
+
dispose() {},
|
|
120
|
+
ready: Promise.resolve(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Inspected evidence:** the route midpoint, the first zone's label onset, and
|
|
126
|
+
the final held frame. The fixture was reviewed as stills; no quantitative water
|
|
127
|
+
claim and no audio-quality claim were made.
|
|
128
|
+
|
|
129
|
+
**Failure mode:** labels that appear before the path arrives let the viewer read
|
|
130
|
+
ahead and stop watching the mechanism; a path that moves too fast to track loses
|
|
131
|
+
the same causality. **Counterexample:** a non-spatial process such as an
|
|
132
|
+
approval workflow may need a timeline or state machine, not a map; forcing it
|
|
133
|
+
onto a route would invent geography.
|
|
134
|
+
**Adaptation exercise:** make a 9:16 version. Stack the zones vertically, keep
|
|
135
|
+
the single route, and decide what the marker does at the crop boundary.
|
|
136
|
+
|
|
137
|
+
## Example 3 — continuity is a decision, not a failure
|
|
138
|
+
|
|
139
|
+
**Brief:** episode two of an approved library series. Episode one used the
|
|
140
|
+
crop-reveal editorial system, a warm paper field and a mono label; the client
|
|
141
|
+
wants the series to be recognisable.
|
|
142
|
+
|
|
143
|
+
**Question:** how do you stay recognisably the same without repeating the first
|
|
144
|
+
composition?
|
|
145
|
+
|
|
146
|
+
**Chosen relationship:** preserve the identity axes (type scale, palette roles,
|
|
147
|
+
crop-reveal grammar, end card) and change the episode's central relationship
|
|
148
|
+
(a single poster becomes a schedule grid) and its shot order.
|
|
149
|
+
|
|
150
|
+
**Rejected:** a new palette each episode (breaks recognition), and an identical
|
|
151
|
+
board (the content no longer fits). Consistency is not a lack of ideas; it is a
|
|
152
|
+
chosen constraint.
|
|
153
|
+
|
|
154
|
+
**Why motion serves meaning:** the same reveal grammar signals "same series";
|
|
155
|
+
the new subject gives the viewer a reason to watch again. The end card is the
|
|
156
|
+
anchor, not a decorative repeat.
|
|
157
|
+
|
|
158
|
+
**Native realization:** reuse the existing authored scene's grid and motion
|
|
159
|
+
helpers; change the content layer and the relationship, not the identity tokens.
|
|
160
|
+
If the series is a strict brand template, use the template deliberately and say
|
|
161
|
+
so.
|
|
162
|
+
|
|
163
|
+
**Inspected evidence:** compare fingerprints across narrative, layout, type,
|
|
164
|
+
value/colour, motion, material, tempo and sound. Name which axes are identity
|
|
165
|
+
and which are episode content.
|
|
166
|
+
**Failure mode:** calling a palette swap "a new episode" while the composition
|
|
167
|
+
repeats; or forcing novelty and losing the recognition the client asked for.
|
|
168
|
+
**Counterexample:** a one-off campaign with no prior work should not invent
|
|
169
|
+
continuity it does not have.
|
|
170
|
+
**Adaptation exercise:** list the three axes you would keep for a third episode
|
|
171
|
+
and the three you would change. Explain each in one sentence.
|
|
172
|
+
|
|
173
|
+
## What these examples do not establish
|
|
174
|
+
|
|
175
|
+
They are authored technical fixtures, not a measured quality benchmark. They do
|
|
176
|
+
not prove that a weaker model will reproduce the reasoning, that a reviewer will
|
|
177
|
+
prefer the result, or that the same decisions fit another brand. A precedent
|
|
178
|
+
that only changes copy or colour has not answered its question.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Worked example: brief to an approved preview
|
|
2
|
+
|
|
3
|
+
A complete direct-storyboard run. Copy the shape, not the words. The numbers below are the ones this board actually produced.
|
|
4
|
+
|
|
5
|
+
## Brief
|
|
6
|
+
|
|
7
|
+
- Topic: how a request reaches the data.
|
|
8
|
+
- Audience: colleagues who know the basics.
|
|
9
|
+
- Length: about 18 s. Aspect: 16:9.
|
|
10
|
+
- Facts: client calls the API gateway; the gateway authenticates; the gateway queries the database; median response last quarter was 120 ms.
|
|
11
|
+
- Route: direct storyboard. No blueprint matched the exact three-service path, and the board is short enough to write.
|
|
12
|
+
|
|
13
|
+
## Outline (sent before building)
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
Plan: How a request reaches the data
|
|
17
|
+
Audience: colleagues who know the basics | Length: ~18 s | Aspect: 16:9
|
|
18
|
+
Route: direct storyboard, theme default - the path is the point
|
|
19
|
+
Scenes:
|
|
20
|
+
1. title - the question
|
|
21
|
+
2. flow - client, gateway, database
|
|
22
|
+
3. caption - the gateway checks every request
|
|
23
|
+
4. stat - 120 ms median
|
|
24
|
+
5. outro - one public door
|
|
25
|
+
Assumed: silent, no brand colours, numbers from the last quarterly report
|
|
26
|
+
Go, or what should change?
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## The board
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"version": 1,
|
|
34
|
+
"meta": {
|
|
35
|
+
"title": "How a request reaches the data",
|
|
36
|
+
"width": 1920,
|
|
37
|
+
"height": 1080,
|
|
38
|
+
"fps": 30,
|
|
39
|
+
"theme": "default"
|
|
40
|
+
},
|
|
41
|
+
"scenes": [
|
|
42
|
+
{
|
|
43
|
+
"id": "intro",
|
|
44
|
+
"type": "title",
|
|
45
|
+
"duration": 4,
|
|
46
|
+
"move": "push-in",
|
|
47
|
+
"ease": "out",
|
|
48
|
+
"props": { "kicker": "Architecture", "title": "How a request reaches the data" }
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "path",
|
|
52
|
+
"type": "flow",
|
|
53
|
+
"duration": 6,
|
|
54
|
+
"move": "push-in",
|
|
55
|
+
"ease": "out",
|
|
56
|
+
"transition": "crossfade",
|
|
57
|
+
"props": {
|
|
58
|
+
"nodes": [
|
|
59
|
+
{ "id": "client", "label": "Client" },
|
|
60
|
+
{ "id": "api", "label": "API gateway" },
|
|
61
|
+
{ "id": "db", "label": "Database" }
|
|
62
|
+
],
|
|
63
|
+
"edges": [
|
|
64
|
+
{ "from": "client", "to": "api", "label": "request" },
|
|
65
|
+
{ "from": "api", "to": "db", "label": "query" }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "cap-path",
|
|
71
|
+
"type": "caption",
|
|
72
|
+
"layer": "overlay",
|
|
73
|
+
"over": "path",
|
|
74
|
+
"offset": 0.2,
|
|
75
|
+
"duration": 5.5,
|
|
76
|
+
"props": { "text": "The gateway checks every request." }
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "result",
|
|
80
|
+
"type": "stat",
|
|
81
|
+
"duration": 4,
|
|
82
|
+
"move": "push-in",
|
|
83
|
+
"ease": "out",
|
|
84
|
+
"transition": "crossfade",
|
|
85
|
+
"props": {
|
|
86
|
+
"value": 120,
|
|
87
|
+
"unit": "ms",
|
|
88
|
+
"label": "median response",
|
|
89
|
+
"context": "measured last quarter"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "end",
|
|
94
|
+
"type": "outro",
|
|
95
|
+
"duration": 4,
|
|
96
|
+
"move": "push-in",
|
|
97
|
+
"ease": "out",
|
|
98
|
+
"transition": "crossfade",
|
|
99
|
+
"props": { "title": "One public door, checked every time" }
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Run it
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
mk validate storyboard.json
|
|
109
|
+
# 0 errors, 0 warnings
|
|
110
|
+
|
|
111
|
+
mk preview storyboard.json
|
|
112
|
+
# preview ok | free storyboard | 4 scenes + 1 overlays 16.5s 1920x1080
|
|
113
|
+
# pack out/storyboard.preview | contact.png 4 stills (+0 paired) clip 6.5s
|
|
114
|
+
# est render ~1m (estimate) | lint 0 err 0 warn | approve: mk approve storyboard.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Open `out/storyboard.preview/contact.png` and look at all four stills. Then ask. Only after an explicit yes:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
mk approve storyboard.json --note "the user's exact words"
|
|
121
|
+
mk render storyboard.json --gated --verify
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The preview's 6.5 s clip caps each scene and is silent; the 16.5 s total includes three overlapping crossfades, so it is less than the 18 s sum. The final render is the only thing that proves the full duration, sound and motion. It was not run for this example; on a real task it is the step after the user's yes.
|
|
125
|
+
|
|
126
|
+
## One feedback round
|
|
127
|
+
|
|
128
|
+
Change the number:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
[{ "op": "replace", "path": "/scenes/3/props/value", "value": 95 }]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
mk patch storyboard.json --ops fixes.json
|
|
136
|
+
# patch ok | 1 op | changed /scenes/3/props/value
|
|
137
|
+
# scenes 5 | total 16.5s | 0 errors, 0 warnings
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Add a closing rule:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
mk scene add storyboard.json callout --after result --set text="[Fewer] hops, same answer" --duration 4
|
|
144
|
+
# scene add ok | callout-1 (callout) at 5/6 | total 20.5s | 0 errors, 0 warnings
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Bring it back to 20 s:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
mk fit storyboard.json --seconds 20
|
|
151
|
+
# fit ok | 20.5s -> 20s (target 20s) | 5 scenes | fallback range (no template pacing)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Every one of those edits re-arms approval. Preview again and ask again; do not reuse the old yes.
|
|
155
|
+
|
|
156
|
+
## Ask in three lines
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
Preview: 4 base scenes + 1 caption overlay, 16.5 s, silent, 16:9.
|
|
160
|
+
Shown: contact.png and the 6.5 s clip. Not shown: voice, motion between stills, and scenes without a still.
|
|
161
|
+
If this works, say "yes" and I will render; otherwise tell me which frame or line to change.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## What this example teaches
|
|
165
|
+
|
|
166
|
+
- The base scenes carry the timeline; the caption overlay does not add duration.
|
|
167
|
+
- `move` on every base scene keeps the film out of the flat-static lint.
|
|
168
|
+
- The direct route needs no template, but it does need a theme that resolves (`default` here).
|
|
169
|
+
- Preview is cheap and silent; render is the expensive, gated step.
|
|
170
|
+
- A hash or a lint pass is not a quality review. The stills are.
|