@anvpx/motion 0.0.0-stage → 0.1.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 (225) hide show
  1. package/CATALOG.md +301 -0
  2. package/LICENSE +21 -0
  3. package/README.md +93 -2
  4. package/assets.json +37 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/main.d.ts +2 -0
  8. package/dist/main.js +46 -0
  9. package/icons/LICENSE-lucide +43 -0
  10. package/icons/icons.json +2711 -0
  11. package/icons/licences.json +1521 -0
  12. package/luts/LICENSE-CC0.txt +20 -0
  13. package/luts/cool.cube +520 -0
  14. package/luts/noir.cube +520 -0
  15. package/luts/warm.cube +520 -0
  16. package/music/LICENSE-CC0.txt +32 -0
  17. package/music/bed-full.wav +0 -0
  18. package/music/bed.wav +0 -0
  19. package/package.json +69 -3
  20. package/packs/INDEX.md +22 -0
  21. package/packs/painted/checklist.md +30 -0
  22. package/packs/painted/examples/dry-ink/storyboard.json +88 -0
  23. package/packs/painted/examples/oil/storyboard.json +89 -0
  24. package/packs/painted/examples/shape-carry/storyboard.json +112 -0
  25. package/packs/painted/examples/stacked-beat/storyboard.json +106 -0
  26. package/packs/painted/examples/staged-read/storyboard.json +105 -0
  27. package/packs/painted/examples/watercolour/storyboard.json +79 -0
  28. package/packs/painted/look.md +71 -0
  29. package/packs/painted/pack.json +46 -0
  30. package/packs/painted/review.md +12 -0
  31. package/packs/painted/voice.md +30 -0
  32. package/plugins/motion-kit/.claude-plugin/plugin.json +5 -0
  33. package/plugins/motion-kit/README.md +31 -0
  34. package/plugins/motion-kit/commands/mk-draft.md +13 -0
  35. package/plugins/motion-kit/commands/mk-new.md +15 -0
  36. package/plugins/motion-kit/commands/mk-render.md +14 -0
  37. package/plugins/motion-kit/skills/motion-kit/SKILL.md +77 -0
  38. package/plugins/motion-kit/skills/motion-kit/references/authoring-scene.md +37 -0
  39. package/plugins/motion-kit/skills/motion-kit/references/authoring-style.md +17 -0
  40. package/plugins/motion-kit/skills/motion-kit/references/common-mistakes.md +73 -0
  41. package/plugins/motion-kit/skills/motion-kit/references/content-pack.md +81 -0
  42. package/plugins/motion-kit/skills/motion-kit/references/faux-ui.md +39 -0
  43. package/plugins/motion-kit/skills/motion-kit/references/free-storyboard.md +15 -0
  44. package/plugins/motion-kit/skills/motion-kit/references/intake.md +18 -0
  45. package/plugins/motion-kit/skills/motion-kit/references/knowledge-routing.md +32 -0
  46. package/plugins/motion-kit/skills/motion-kit/references/outline.md +24 -0
  47. package/plugins/motion-kit/skills/motion-kit/references/patching.md +50 -0
  48. package/plugins/motion-kit/skills/motion-kit/references/patterns.md +55 -0
  49. package/plugins/motion-kit/skills/motion-kit/references/quality-bar.md +61 -0
  50. package/plugins/motion-kit/skills/motion-kit/references/review.md +8 -0
  51. package/plugins/motion-kit/skills/motion-kit/references/scene-recipes.md +300 -0
  52. package/plugins/motion-kit/skills/motion-kit/references/setup.md +16 -0
  53. package/plugins/motion-kit/skills/motion-kit/references/slop.md +38 -0
  54. package/plugins/motion-kit/skills/motion-kit/references/storyboard-json.md +121 -0
  55. package/plugins/motion-kit/skills/motion-kit/references/troubleshooting.md +55 -0
  56. package/plugins/motion-kit/skills/motion-kit/references/voice.md +40 -0
  57. package/plugins/motion-kit/skills/motion-kit/references/worked-example.md +170 -0
  58. package/shared/themes/README.md +5 -0
  59. package/shared/themes/bold-dark.json +362 -0
  60. package/shared/themes/bold-light.json +362 -0
  61. package/shared/themes/calm-dark.json +362 -0
  62. package/shared/themes/calm-light.json +362 -0
  63. package/shared/themes/data-dark.json +360 -0
  64. package/shared/themes/data-light.json +360 -0
  65. package/shared/themes/editorial-dark.json +353 -0
  66. package/shared/themes/editorial-light.json +353 -0
  67. package/shared/themes/fjord-dark.json +124 -0
  68. package/shared/themes/fjord-light.json +124 -0
  69. package/shared/themes/playful-dark.json +362 -0
  70. package/shared/themes/playful-light.json +362 -0
  71. package/shared/themes/pop-dark.json +352 -0
  72. package/shared/themes/pop-light.json +352 -0
  73. package/shared/themes/tech-dark.json +360 -0
  74. package/shared/themes/tech-light.json +360 -0
  75. package/shared/themes/warm-dark.json +368 -0
  76. package/shared/themes/warm-light.json +368 -0
  77. package/skills/motion-kit/SKILL.md +77 -0
  78. package/skills/motion-kit/references/authoring-scene.md +37 -0
  79. package/skills/motion-kit/references/authoring-style.md +17 -0
  80. package/skills/motion-kit/references/common-mistakes.md +73 -0
  81. package/skills/motion-kit/references/content-pack.md +81 -0
  82. package/skills/motion-kit/references/faux-ui.md +39 -0
  83. package/skills/motion-kit/references/free-storyboard.md +15 -0
  84. package/skills/motion-kit/references/intake.md +18 -0
  85. package/skills/motion-kit/references/knowledge-routing.md +32 -0
  86. package/skills/motion-kit/references/outline.md +24 -0
  87. package/skills/motion-kit/references/patching.md +50 -0
  88. package/skills/motion-kit/references/patterns.md +55 -0
  89. package/skills/motion-kit/references/quality-bar.md +61 -0
  90. package/skills/motion-kit/references/review.md +8 -0
  91. package/skills/motion-kit/references/scene-recipes.md +300 -0
  92. package/skills/motion-kit/references/setup.md +16 -0
  93. package/skills/motion-kit/references/slop.md +38 -0
  94. package/skills/motion-kit/references/storyboard-json.md +121 -0
  95. package/skills/motion-kit/references/troubleshooting.md +55 -0
  96. package/skills/motion-kit/references/voice.md +40 -0
  97. package/skills/motion-kit/references/worked-example.md +170 -0
  98. package/stopwords.json +65 -0
  99. package/templates/compare/blueprints/versus.json +79 -0
  100. package/templates/compare/copy.md +18 -0
  101. package/templates/compare/pacing.json +15 -0
  102. package/templates/compare/previews/versus.png +0 -0
  103. package/templates/compare/styles/editorial.json +6 -0
  104. package/templates/compare/styles/punchy.json +6 -0
  105. package/templates/compare/styles/tidy.json +6 -0
  106. package/templates/compare/template.json +52 -0
  107. package/templates/datastory/blueprints/data-story.json +95 -0
  108. package/templates/datastory/blueprints/infographic.json +106 -0
  109. package/templates/datastory/blueprints/trend.json +93 -0
  110. package/templates/datastory/copy.md +16 -0
  111. package/templates/datastory/pacing.json +17 -0
  112. package/templates/datastory/previews/data-story.png +0 -0
  113. package/templates/datastory/previews/infographic.png +0 -0
  114. package/templates/datastory/previews/trend.png +0 -0
  115. package/templates/datastory/styles/clear.json +6 -0
  116. package/templates/datastory/styles/editorial.json +6 -0
  117. package/templates/datastory/styles/pop.json +7 -0
  118. package/templates/datastory/template.json +57 -0
  119. package/templates/event/blueprints/promo.json +71 -0
  120. package/templates/event/blueprints/save-the-date.json +61 -0
  121. package/templates/event/copy.md +16 -0
  122. package/templates/event/pacing.json +15 -0
  123. package/templates/event/previews/promo.png +0 -0
  124. package/templates/event/previews/save-the-date.png +0 -0
  125. package/templates/event/styles/bright.json +6 -0
  126. package/templates/event/styles/pop.json +6 -0
  127. package/templates/event/template.json +37 -0
  128. package/templates/explain/blueprints/architecture.json +76 -0
  129. package/templates/explain/blueprints/concept.json +89 -0
  130. package/templates/explain/blueprints/howto.json +56 -0
  131. package/templates/explain/blueprints/overview.json +126 -0
  132. package/templates/explain/copy.md +19 -0
  133. package/templates/explain/pacing.json +19 -0
  134. package/templates/explain/previews/architecture.png +0 -0
  135. package/templates/explain/previews/concept.png +0 -0
  136. package/templates/explain/previews/howto.png +0 -0
  137. package/templates/explain/previews/overview.png +0 -0
  138. package/templates/explain/styles/calm.json +6 -0
  139. package/templates/explain/styles/crisp.json +6 -0
  140. package/templates/explain/template.json +64 -0
  141. package/templates/guide/blueprints/lesson.json +173 -0
  142. package/templates/guide/blueprints/onboarding.json +80 -0
  143. package/templates/guide/blueprints/tutorial.json +102 -0
  144. package/templates/guide/copy.md +17 -0
  145. package/templates/guide/pacing.json +59 -0
  146. package/templates/guide/previews/lesson.png +0 -0
  147. package/templates/guide/previews/onboarding.png +0 -0
  148. package/templates/guide/previews/tutorial.png +0 -0
  149. package/templates/guide/styles/calm.json +15 -0
  150. package/templates/guide/styles/friendly.json +15 -0
  151. package/templates/guide/styles/techdark.json +15 -0
  152. package/templates/guide/template.json +95 -0
  153. package/templates/pitch/blueprints/feature.json +134 -0
  154. package/templates/pitch/blueprints/launch.json +173 -0
  155. package/templates/pitch/blueprints/pricing.json +141 -0
  156. package/templates/pitch/copy.md +18 -0
  157. package/templates/pitch/pacing.json +59 -0
  158. package/templates/pitch/previews/feature.png +0 -0
  159. package/templates/pitch/previews/launch.png +0 -0
  160. package/templates/pitch/previews/pricing.png +0 -0
  161. package/templates/pitch/styles/polished.json +6 -0
  162. package/templates/pitch/styles/punchy.json +6 -0
  163. package/templates/pitch/styles/teaser.json +12 -0
  164. package/templates/pitch/template.json +45 -0
  165. package/templates/recap/blueprints/news-recap.json +62 -0
  166. package/templates/recap/blueprints/timeline-story.json +94 -0
  167. package/templates/recap/copy.md +16 -0
  168. package/templates/recap/pacing.json +16 -0
  169. package/templates/recap/previews/news-recap.png +0 -0
  170. package/templates/recap/previews/timeline-story.png +0 -0
  171. package/templates/recap/styles/editorial.json +6 -0
  172. package/templates/recap/styles/editorialdark.json +6 -0
  173. package/templates/recap/template.json +50 -0
  174. package/templates/report/blueprints/kpi-review.json +116 -0
  175. package/templates/report/blueprints/status.json +78 -0
  176. package/templates/report/copy.md +17 -0
  177. package/templates/report/pacing.json +16 -0
  178. package/templates/report/previews/kpi-review.png +0 -0
  179. package/templates/report/previews/status.png +0 -0
  180. package/templates/report/styles/exec.json +6 -0
  181. package/templates/report/styles/memo.json +6 -0
  182. package/templates/report/styles/walkthrough.json +6 -0
  183. package/templates/report/template.json +56 -0
  184. package/templates/social/blueprints/announce.json +109 -0
  185. package/templates/social/blueprints/listicle.json +117 -0
  186. package/templates/social/blueprints/tip.json +114 -0
  187. package/templates/social/copy.md +18 -0
  188. package/templates/social/pacing.json +49 -0
  189. package/templates/social/previews/announce.png +0 -0
  190. package/templates/social/previews/listicle.png +0 -0
  191. package/templates/social/previews/tip.png +0 -0
  192. package/templates/social/styles/captioned.json +18 -0
  193. package/templates/social/styles/hook-first.json +15 -0
  194. package/templates/social/styles/techcut.json +15 -0
  195. package/templates/social/template.json +94 -0
  196. package/templates/update/blueprints/announcement.json +57 -0
  197. package/templates/update/blueprints/changelog.json +157 -0
  198. package/templates/update/blueprints/release-notes.json +151 -0
  199. package/templates/update/blueprints/weekly-update.json +88 -0
  200. package/templates/update/copy.md +17 -0
  201. package/templates/update/pacing.json +64 -0
  202. package/templates/update/previews/announcement.png +0 -0
  203. package/templates/update/previews/changelog.png +0 -0
  204. package/templates/update/previews/release-notes.png +0 -0
  205. package/templates/update/previews/weekly-update.png +0 -0
  206. package/templates/update/styles/punchy.json +15 -0
  207. package/templates/update/styles/techdark.json +6 -0
  208. package/templates/update/styles/tidy.json +6 -0
  209. package/templates/update/template.json +67 -0
  210. package/templates/vista/blueprints/spotlight.json +68 -0
  211. package/templates/vista/blueprints/tour.json +84 -0
  212. package/templates/vista/copy.md +18 -0
  213. package/templates/vista/pacing.json +14 -0
  214. package/templates/vista/previews/spotlight.png +0 -0
  215. package/templates/vista/previews/tour.png +0 -0
  216. package/templates/vista/styles/bright.json +6 -0
  217. package/templates/vista/styles/cinematic.json +6 -0
  218. package/templates/vista/template.json +42 -0
  219. package/templates/walkthrough/blueprints/product-tour.json +107 -0
  220. package/templates/walkthrough/copy.md +16 -0
  221. package/templates/walkthrough/pacing.json +16 -0
  222. package/templates/walkthrough/previews/product-tour.png +0 -0
  223. package/templates/walkthrough/styles/calm.json +6 -0
  224. package/templates/walkthrough/styles/deep.json +6 -0
  225. package/templates/walkthrough/template.json +37 -0
@@ -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,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,40 @@
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. Keep the words final before synthesis: `mk voice` needs the final script, and a later text edit invalidates the timing.
13
+ 3. `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.
14
+ 4. The command preflights the narration against the scene duration and refuses before synthesis when it cannot fit; 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.
15
+ 5. `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.
16
+
17
+ ## Captions
18
+
19
+ - `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.
20
+ - 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.
21
+ - 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.
22
+ - 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.
23
+ - Preview again after adding captions. The approval covers the captions as part of the storyboard.
24
+
25
+ ## Audio and approval
26
+
27
+ - `mk preview` accepts `--audio <manifest>`; `mk approve` infers it from the pack. Pass the same `--audio` to preview, approve and render.
28
+ - 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.
29
+ - 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.
30
+ - If the preview clip is silent, say so in the ask. Do not describe the film as narrated until the audible preview exists.
31
+
32
+ ## Failure paths
33
+
34
+ | Symptom | Do |
35
+ | ----------------------------------- | ----------------------------------------------------------------------- |
36
+ | `mk voice` not installed / exit 127 | `mk doctor`; give the install hint; ship silent only if the user agrees |
37
+ | narration refused before synthesis | shorten the words or lengthen that scene; never edit timings |
38
+ | `mk qc` WARN or UNKNOWN | report the exact state; do not call it PASS |
39
+ | `mk captions` omits words | tell the user which scene and how many; adjust the script or duration |
40
+ | render exit 4 after audio work | the audio inputs drifted from approval; re-preview and re-approve |
@@ -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.
@@ -0,0 +1,5 @@
1
+ # Shared themes
2
+
3
+ Theme files referenced by templates as `"file": "@shared/<name>.json"`. The loader reads them from this folder; a theme id is its file name without `.json`.
4
+
5
+ Sixteen files: nine families (`calm`, `bold`, `data`, `editorial`, `tech`, `playful`, `pop`, `warm`) in `-light` and `-dark`. Family table, fonts and guarantees: `../README.md`; motion presets: `../styles-guide.md`.