@mevdragon/vidfarm-devcli 0.14.0 → 0.15.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 (418) hide show
  1. package/.agents/skills/embedded-captions/CATALOG.md +93 -0
  2. package/.agents/skills/embedded-captions/SKILL.md +286 -0
  3. package/.agents/skills/embedded-captions/assets/brand/CDPR-fankit-terms.txt +35 -0
  4. package/.agents/skills/embedded-captions/assets/brand/cyberpunk-widths.json +115 -0
  5. package/.agents/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
  6. package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
  7. package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
  8. package/.agents/skills/embedded-captions/dna/README.md +148 -0
  9. package/.agents/skills/embedded-captions/dna/chrome.json +68 -0
  10. package/.agents/skills/embedded-captions/dna/cream.json +69 -0
  11. package/.agents/skills/embedded-captions/dna/documentary.json +62 -0
  12. package/.agents/skills/embedded-captions/dna/editorial.json +70 -0
  13. package/.agents/skills/embedded-captions/dna/glitch.json +82 -0
  14. package/.agents/skills/embedded-captions/dna/ink.json +65 -0
  15. package/.agents/skills/embedded-captions/dna/keynote.json +62 -0
  16. package/.agents/skills/embedded-captions/dna/loud.json +75 -0
  17. package/.agents/skills/embedded-captions/dna/neon.json +58 -0
  18. package/.agents/skills/embedded-captions/dna/velocity.json +89 -0
  19. package/.agents/skills/embedded-captions/modes/cinematic/README.md +48 -0
  20. package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
  21. package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
  22. package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
  23. package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
  24. package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
  25. package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
  26. package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
  27. package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
  28. package/.agents/skills/embedded-captions/modes/cinematic/engine.html +355 -0
  29. package/.agents/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
  30. package/.agents/skills/embedded-captions/modes/standard/_motion.md +192 -0
  31. package/.agents/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
  32. package/.agents/skills/embedded-captions/references/aesthetic-principles.md +168 -0
  33. package/.agents/skills/embedded-captions/references/anti-patterns.md +188 -0
  34. package/.agents/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
  35. package/.agents/skills/embedded-captions/references/caption-grouping.md +130 -0
  36. package/.agents/skills/embedded-captions/references/composition-craft.md +522 -0
  37. package/.agents/skills/embedded-captions/references/direction-catalog.md +138 -0
  38. package/.agents/skills/embedded-captions/references/example-renders/champion.html +371 -0
  39. package/.agents/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
  40. package/.agents/skills/embedded-captions/references/failure-modes.md +145 -0
  41. package/.agents/skills/embedded-captions/references/layout-heuristics.md +238 -0
  42. package/.agents/skills/embedded-captions/references/motion-vocabulary.md +148 -0
  43. package/.agents/skills/embedded-captions/references/rail.md +68 -0
  44. package/.agents/skills/embedded-captions/references/reference-bar.md +47 -0
  45. package/.agents/skills/embedded-captions/references/scene-types.md +94 -0
  46. package/.agents/skills/embedded-captions/references/test-set.md +66 -0
  47. package/.agents/skills/embedded-captions/references/typographic-moves.md +266 -0
  48. package/.agents/skills/embedded-captions/references/typography-presets.md +63 -0
  49. package/.agents/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
  50. package/.agents/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
  51. package/.agents/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
  52. package/.agents/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
  53. package/.agents/skills/embedded-captions/scripts/check-timing.cjs +173 -0
  54. package/.agents/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
  55. package/.agents/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
  56. package/.agents/skills/embedded-captions/scripts/gen-stroke-path.py +46 -0
  57. package/.agents/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
  58. package/.agents/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
  59. package/.agents/skills/embedded-captions/scripts/make-cinematic.cjs +1205 -0
  60. package/.agents/skills/embedded-captions/scripts/make-composition.cjs +404 -0
  61. package/.agents/skills/embedded-captions/scripts/make-theme.cjs +8781 -0
  62. package/.agents/skills/embedded-captions/scripts/matte.cjs +294 -0
  63. package/.agents/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
  64. package/.agents/skills/embedded-captions/scripts/prepare.sh +39 -0
  65. package/.agents/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
  66. package/.agents/skills/embedded-captions/scripts/render-and-composite.sh +509 -0
  67. package/.agents/skills/embedded-captions/scripts/render-theme.sh +34 -0
  68. package/.agents/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
  69. package/.agents/skills/embedded-captions/scripts/transcribe.cjs +349 -0
  70. package/.agents/skills/embedded-captions/themes/PORTING.md +49 -0
  71. package/.agents/skills/embedded-captions/themes/README.md +244 -0
  72. package/.agents/skills/embedded-captions/themes/anchor.json +27 -0
  73. package/.agents/skills/embedded-captions/themes/arcade.json +51 -0
  74. package/.agents/skills/embedded-captions/themes/aurora.json +41 -0
  75. package/.agents/skills/embedded-captions/themes/biolume.json +35 -0
  76. package/.agents/skills/embedded-captions/themes/brush.json +74 -0
  77. package/.agents/skills/embedded-captions/themes/chalkboard.json +52 -0
  78. package/.agents/skills/embedded-captions/themes/dossier.json +56 -0
  79. package/.agents/skills/embedded-captions/themes/graffiti.json +62 -0
  80. package/.agents/skills/embedded-captions/themes/hologram.json +41 -0
  81. package/.agents/skills/embedded-captions/themes/inkwater.json +43 -0
  82. package/.agents/skills/embedded-captions/themes/laser.json +46 -0
  83. package/.agents/skills/embedded-captions/themes/lastpage.json +33 -0
  84. package/.agents/skills/embedded-captions/themes/neonsign.json +53 -0
  85. package/.agents/skills/embedded-captions/themes/nightcity.json +56 -0
  86. package/.agents/skills/embedded-captions/themes/ordnance.json +54 -0
  87. package/.agents/skills/embedded-captions/themes/papercut.json +37 -0
  88. package/.agents/skills/embedded-captions/themes/popup.json +46 -0
  89. package/.agents/skills/embedded-captions/themes/ransom.json +62 -0
  90. package/.agents/skills/embedded-captions/themes/scoreboard.json +54 -0
  91. package/.agents/skills/embedded-captions/themes/spectrum.json +46 -0
  92. package/.agents/skills/embedded-captions/themes/stardust.json +29 -0
  93. package/.agents/skills/embedded-captions/themes/stomp.json +43 -0
  94. package/.agents/skills/embedded-captions/themes/terminal.json +49 -0
  95. package/.agents/skills/embedded-captions/themes/thunder.json +44 -0
  96. package/.agents/skills/embedded-captions/themes/transit.json +44 -0
  97. package/.agents/skills/embedded-captions/themes/vhs.json +47 -0
  98. package/.agents/skills/faceless-explainer/SKILL.md +209 -0
  99. package/.agents/skills/faceless-explainer/references/cut-catalog.md +215 -0
  100. package/.agents/skills/faceless-explainer/references/motion-language.md +156 -0
  101. package/.agents/skills/faceless-explainer/references/story-design.md +248 -0
  102. package/.agents/skills/faceless-explainer/references/visual-design.md +146 -0
  103. package/.agents/skills/faceless-explainer/scripts/assemble-index.mjs +570 -0
  104. package/.agents/skills/faceless-explainer/scripts/audio.mjs +260 -0
  105. package/.agents/skills/faceless-explainer/scripts/build-frame.mjs +536 -0
  106. package/.agents/skills/faceless-explainer/scripts/captions.mjs +508 -0
  107. package/.agents/skills/faceless-explainer/scripts/lib/assets.mjs +55 -0
  108. package/.agents/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
  109. package/.agents/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
  110. package/.agents/skills/faceless-explainer/scripts/lib/tokens.mjs +204 -0
  111. package/.agents/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
  112. package/.agents/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
  113. package/.agents/skills/faceless-explainer/scripts/transitions.mjs +320 -0
  114. package/.agents/skills/faceless-explainer/sub-agents/frame-worker.md +75 -0
  115. package/.agents/skills/flockposter/LICENSE +17 -0
  116. package/.agents/skills/flockposter/README.md +72 -0
  117. package/.agents/skills/flockposter/SKILL.md +562 -0
  118. package/.agents/skills/flockposter/examples/cli-instagram-reel.sh +21 -0
  119. package/.agents/skills/flockposter/examples/cli-multi-platform.json +69 -0
  120. package/.agents/skills/flockposter/examples/cli-tiktok-upload-only.sh +22 -0
  121. package/.agents/skills/flockposter/examples/cli-x-thread.sh +17 -0
  122. package/.agents/skills/flockposter/examples/cli-youtube-short.sh +21 -0
  123. package/.agents/skills/flockposter/examples/public-api-instagram-reel.json +28 -0
  124. package/.agents/skills/general-video/SKILL.md +143 -0
  125. package/.agents/skills/hyperframes/SKILL.md +160 -0
  126. package/.agents/skills/hyperframes-animation/SKILL.md +84 -0
  127. package/.agents/skills/hyperframes-animation/adapters/animate-text.md +64 -0
  128. package/.agents/skills/hyperframes-animation/adapters/animejs.md +114 -0
  129. package/.agents/skills/hyperframes-animation/adapters/css-animations.md +143 -0
  130. package/.agents/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +118 -0
  131. package/.agents/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
  132. package/.agents/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +96 -0
  133. package/.agents/skills/hyperframes-animation/adapters/gsap.md +105 -0
  134. package/.agents/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
  135. package/.agents/skills/hyperframes-animation/adapters/lottie.md +117 -0
  136. package/.agents/skills/hyperframes-animation/adapters/three.md +131 -0
  137. package/.agents/skills/hyperframes-animation/adapters/typegpu.md +178 -0
  138. package/.agents/skills/hyperframes-animation/adapters/waapi.md +101 -0
  139. package/.agents/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
  140. package/.agents/skills/hyperframes-animation/blueprints/constellation-hub.md +44 -0
  141. package/.agents/skills/hyperframes-animation/blueprints/cta-morph-press.md +28 -0
  142. package/.agents/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +57 -0
  143. package/.agents/skills/hyperframes-animation/blueprints/dataviz-countup.md +46 -0
  144. package/.agents/skills/hyperframes-animation/blueprints/device-surface-showcase.md +53 -0
  145. package/.agents/skills/hyperframes-animation/blueprints/grid-card-assemble.md +66 -0
  146. package/.agents/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +78 -0
  147. package/.agents/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +69 -0
  148. package/.agents/skills/hyperframes-animation/blueprints/overwhelm-surround.md +28 -0
  149. package/.agents/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
  150. package/.agents/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
  151. package/.agents/skills/hyperframes-animation/blueprints/titlecard-reveal.md +42 -0
  152. package/.agents/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
  153. package/.agents/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
  154. package/.agents/skills/hyperframes-animation/blueprints-index.md +146 -0
  155. package/.agents/skills/hyperframes-animation/examples/assets/avatars/02.avif +0 -0
  156. package/.agents/skills/hyperframes-animation/examples/assets/brands/github.avif +0 -0
  157. package/.agents/skills/hyperframes-animation/examples/assets/brands/nvidia.avif +0 -0
  158. package/.agents/skills/hyperframes-animation/examples/assets/brands/visa.avif +0 -0
  159. package/.agents/skills/hyperframes-animation/examples/assets/brands/zoominfo.avif +0 -0
  160. package/.agents/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
  161. package/.agents/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
  162. package/.agents/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
  163. package/.agents/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
  164. package/.agents/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
  165. package/.agents/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
  166. package/.agents/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
  167. package/.agents/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
  168. package/.agents/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
  169. package/.agents/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
  170. package/.agents/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
  171. package/.agents/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
  172. package/.agents/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
  173. package/.agents/skills/hyperframes-animation/rules/3d-page-scroll.md +227 -0
  174. package/.agents/skills/hyperframes-animation/rules/3d-text-depth-layers.md +297 -0
  175. package/.agents/skills/hyperframes-animation/rules/ai-tracking-box.md +382 -0
  176. package/.agents/skills/hyperframes-animation/rules/ambient-glow-bloom.md +305 -0
  177. package/.agents/skills/hyperframes-animation/rules/asr-keyword-glow.md +286 -0
  178. package/.agents/skills/hyperframes-animation/rules/avatar-cloud-network.md +371 -0
  179. package/.agents/skills/hyperframes-animation/rules/camera-cursor-tracking.md +246 -0
  180. package/.agents/skills/hyperframes-animation/rules/card-morph-anchor.md +267 -0
  181. package/.agents/skills/hyperframes-animation/rules/center-outward-expansion.md +227 -0
  182. package/.agents/skills/hyperframes-animation/rules/context-sensitive-cursor.md +257 -0
  183. package/.agents/skills/hyperframes-animation/rules/coordinate-target-zoom.md +332 -0
  184. package/.agents/skills/hyperframes-animation/rules/counting-dynamic-scale.md +283 -0
  185. package/.agents/skills/hyperframes-animation/rules/css-marker-patterns.md +373 -0
  186. package/.agents/skills/hyperframes-animation/rules/cursor-click-ripple.md +262 -0
  187. package/.agents/skills/hyperframes-animation/rules/depth-of-field-blur.md +313 -0
  188. package/.agents/skills/hyperframes-animation/rules/depth-scatter-assemble.md +303 -0
  189. package/.agents/skills/hyperframes-animation/rules/discrete-text-sequence.md +273 -0
  190. package/.agents/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +307 -0
  191. package/.agents/skills/hyperframes-animation/rules/gsap-effects.md +299 -0
  192. package/.agents/skills/hyperframes-animation/rules/hacker-flip-3d.md +223 -0
  193. package/.agents/skills/hyperframes-animation/rules/kinetic-beat-slam.md +183 -0
  194. package/.agents/skills/hyperframes-animation/rules/motion-blur-streak.md +328 -0
  195. package/.agents/skills/hyperframes-animation/rules/multi-phase-camera.md +273 -0
  196. package/.agents/skills/hyperframes-animation/rules/orbit-3d-entry.md +301 -0
  197. package/.agents/skills/hyperframes-animation/rules/physics-press-reaction.md +350 -0
  198. package/.agents/skills/hyperframes-animation/rules/press-release-spring.md +296 -0
  199. package/.agents/skills/hyperframes-animation/rules/reactive-displacement.md +277 -0
  200. package/.agents/skills/hyperframes-animation/rules/scale-swap-transition.md +298 -0
  201. package/.agents/skills/hyperframes-animation/rules/sine-wave-loop.md +278 -0
  202. package/.agents/skills/hyperframes-animation/rules/split-tilt-cards.md +277 -0
  203. package/.agents/skills/hyperframes-animation/rules/spring-pop-entrance.md +273 -0
  204. package/.agents/skills/hyperframes-animation/rules/stat-bars-and-fills.md +156 -0
  205. package/.agents/skills/hyperframes-animation/rules/svg-icon-enrichment.md +329 -0
  206. package/.agents/skills/hyperframes-animation/rules/svg-path-draw.md +274 -0
  207. package/.agents/skills/hyperframes-animation/rules/vertical-spring-ticker.md +239 -0
  208. package/.agents/skills/hyperframes-animation/rules/viewport-change.md +349 -0
  209. package/.agents/skills/hyperframes-animation/rules-index.md +86 -0
  210. package/.agents/skills/hyperframes-animation/scripts/animation-map.mjs +606 -0
  211. package/.agents/skills/hyperframes-animation/scripts/package-loader.mjs +288 -0
  212. package/.agents/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
  213. package/.agents/skills/hyperframes-animation/techniques.md +507 -0
  214. package/.agents/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +167 -0
  215. package/.agents/skills/hyperframes-animation/transitions/catalog.md +127 -0
  216. package/.agents/skills/hyperframes-animation/transitions/css-3d.md +12 -0
  217. package/.agents/skills/hyperframes-animation/transitions/css-blur.md +51 -0
  218. package/.agents/skills/hyperframes-animation/transitions/css-cover.md +43 -0
  219. package/.agents/skills/hyperframes-animation/transitions/css-destruction.md +95 -0
  220. package/.agents/skills/hyperframes-animation/transitions/css-dissolve.md +66 -0
  221. package/.agents/skills/hyperframes-animation/transitions/css-distortion.md +45 -0
  222. package/.agents/skills/hyperframes-animation/transitions/css-grid.md +10 -0
  223. package/.agents/skills/hyperframes-animation/transitions/css-light.md +49 -0
  224. package/.agents/skills/hyperframes-animation/transitions/css-mechanical.md +30 -0
  225. package/.agents/skills/hyperframes-animation/transitions/css-other.md +25 -0
  226. package/.agents/skills/hyperframes-animation/transitions/css-push.md +41 -0
  227. package/.agents/skills/hyperframes-animation/transitions/css-radial.md +37 -0
  228. package/.agents/skills/hyperframes-animation/transitions/css-scale.md +24 -0
  229. package/.agents/skills/hyperframes-animation/transitions/overview.md +153 -0
  230. package/.agents/skills/hyperframes-cli/SKILL.md +113 -0
  231. package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
  232. package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +55 -0
  233. package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
  234. package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
  235. package/.agents/skills/hyperframes-cli/references/preview-render.md +149 -0
  236. package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
  237. package/.agents/skills/hyperframes-core/SKILL.md +78 -0
  238. package/.agents/skills/hyperframes-core/references/composition-patterns.md +263 -0
  239. package/.agents/skills/hyperframes-core/references/data-attributes.md +70 -0
  240. package/.agents/skills/hyperframes-core/references/determinism-rules.md +68 -0
  241. package/.agents/skills/hyperframes-core/references/full-screen-motion.md +62 -0
  242. package/.agents/skills/hyperframes-core/references/minimal-composition.md +66 -0
  243. package/.agents/skills/hyperframes-core/references/script-format.md +49 -0
  244. package/.agents/skills/hyperframes-core/references/storyboard-format.md +95 -0
  245. package/.agents/skills/hyperframes-core/references/sub-compositions.md +237 -0
  246. package/.agents/skills/hyperframes-core/references/subagent-dispatch.md +41 -0
  247. package/.agents/skills/hyperframes-core/references/tailwind.md +125 -0
  248. package/.agents/skills/hyperframes-core/references/tracks-and-clips.md +76 -0
  249. package/.agents/skills/hyperframes-core/references/variables-and-media.md +90 -0
  250. package/.agents/skills/hyperframes-creative/SKILL.md +70 -0
  251. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
  252. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
  253. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
  254. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
  255. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
  256. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
  257. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
  258. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
  259. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
  260. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
  261. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
  262. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
  263. package/.agents/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
  264. package/.agents/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
  265. package/.agents/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
  266. package/.agents/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
  267. package/.agents/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
  268. package/.agents/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
  269. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
  270. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
  271. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
  272. package/.agents/skills/hyperframes-creative/frame-presets/claude/FRAME.md +277 -0
  273. package/.agents/skills/hyperframes-creative/frame-presets/claude/caption-skin.html +224 -0
  274. package/.agents/skills/hyperframes-creative/frame-presets/claude/frame-showcase.html +1439 -0
  275. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
  276. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
  277. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
  278. package/.agents/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
  279. package/.agents/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
  280. package/.agents/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
  281. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
  282. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
  283. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
  284. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
  285. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
  286. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
  287. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
  288. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
  289. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
  290. package/.agents/skills/hyperframes-creative/palettes/bold-energetic.md +14 -0
  291. package/.agents/skills/hyperframes-creative/palettes/clean-corporate.md +14 -0
  292. package/.agents/skills/hyperframes-creative/palettes/dark-premium.md +14 -0
  293. package/.agents/skills/hyperframes-creative/palettes/jewel-rich.md +14 -0
  294. package/.agents/skills/hyperframes-creative/palettes/monochrome.md +14 -0
  295. package/.agents/skills/hyperframes-creative/palettes/nature-earth.md +14 -0
  296. package/.agents/skills/hyperframes-creative/palettes/neon-electric.md +14 -0
  297. package/.agents/skills/hyperframes-creative/palettes/pastel-soft.md +14 -0
  298. package/.agents/skills/hyperframes-creative/palettes/warm-editorial.md +14 -0
  299. package/.agents/skills/hyperframes-creative/references/audio-reactive.md +76 -0
  300. package/.agents/skills/hyperframes-creative/references/beat-direction.md +164 -0
  301. package/.agents/skills/hyperframes-creative/references/composition-patterns.md +199 -0
  302. package/.agents/skills/hyperframes-creative/references/data-in-motion.md +19 -0
  303. package/.agents/skills/hyperframes-creative/references/design-adherence.md +19 -0
  304. package/.agents/skills/hyperframes-creative/references/design-picker.md +123 -0
  305. package/.agents/skills/hyperframes-creative/references/design-spec.md +55 -0
  306. package/.agents/skills/hyperframes-creative/references/house-style.md +73 -0
  307. package/.agents/skills/hyperframes-creative/references/motion-principles.md +150 -0
  308. package/.agents/skills/hyperframes-creative/references/narration.md +92 -0
  309. package/.agents/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
  310. package/.agents/skills/hyperframes-creative/references/typography.md +218 -0
  311. package/.agents/skills/hyperframes-creative/references/video-composition.md +63 -0
  312. package/.agents/skills/hyperframes-creative/references/visual-styles.md +457 -0
  313. package/.agents/skills/hyperframes-creative/scripts/contrast-report.mjs +353 -0
  314. package/.agents/skills/hyperframes-creative/scripts/extract-audio-data.py +188 -0
  315. package/.agents/skills/hyperframes-creative/scripts/package-loader.mjs +288 -0
  316. package/.agents/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
  317. package/.agents/skills/hyperframes-creative/templates/design-picker.html +1432 -0
  318. package/.agents/skills/hyperframes-keyframes/SKILL.md +237 -0
  319. package/.agents/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
  320. package/.agents/skills/hyperframes-keyframes/references/keyframe-patterns.md +106 -0
  321. package/.agents/skills/motion-graphics/SKILL.md +172 -0
  322. package/.agents/skills/motion-graphics/agents/builder.md +40 -0
  323. package/.agents/skills/motion-graphics/agents/director.md +53 -0
  324. package/.agents/skills/motion-graphics/agents/finalize.md +17 -0
  325. package/.agents/skills/motion-graphics/catalog-map.md +40 -0
  326. package/.agents/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
  327. package/.agents/skills/motion-graphics/categories/charts/module.md +21 -0
  328. package/.agents/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
  329. package/.agents/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
  330. package/.agents/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
  331. package/.agents/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
  332. package/.agents/skills/motion-graphics/categories/maps/module.md +61 -0
  333. package/.agents/skills/motion-graphics/categories/news/module.md +56 -0
  334. package/.agents/skills/motion-graphics/categories/stat/module.md +21 -0
  335. package/.agents/skills/motion-graphics/categories/tweet/module.md +16 -0
  336. package/.agents/skills/motion-graphics/categories/webpage/module.md +21 -0
  337. package/.agents/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
  338. package/.agents/skills/motion-graphics/grounding/locate.mjs +227 -0
  339. package/.agents/skills/motion-graphics/phases/source/guide.md +21 -0
  340. package/.agents/skills/motion-graphics/references/builder-contract.md +38 -0
  341. package/.agents/skills/motion-graphics/references/motion-vocabulary.md +43 -0
  342. package/.agents/skills/motion-graphics/references/shot-plan-ir.md +54 -0
  343. package/.agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
  344. package/.agents/skills/product-launch-video/SKILL.md +208 -0
  345. package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
  346. package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
  347. package/.agents/skills/product-launch-video/references/story-design.md +373 -0
  348. package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
  349. package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
  350. package/.agents/skills/product-launch-video/scripts/audio.mjs +260 -0
  351. package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
  352. package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
  353. package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
  354. package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
  355. package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
  356. package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
  357. package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
  358. package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
  359. package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
  360. package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
  361. package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
  362. package/.agents/skills/product-launch-video/scripts/transitions.mjs +327 -0
  363. package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +75 -0
  364. package/.agents/skills/slideshow/SKILL.md +550 -0
  365. package/.agents/skills/slideshow/references/standalone-harness.md +1020 -0
  366. package/.agents/skills/talking-head-recut/NOTICE.md +39 -0
  367. package/.agents/skills/talking-head-recut/SKILL.md +1195 -0
  368. package/.agents/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
  369. package/.agents/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
  370. package/.agents/skills/talking-head-recut/references/frames/clean.html +92 -0
  371. package/.agents/skills/talking-head-recut/references/frames/hairline.html +171 -0
  372. package/.agents/skills/talking-head-recut/references/frames/polaroid.html +131 -0
  373. package/.agents/skills/talking-head-recut/references/layouts/overlay.html +164 -0
  374. package/.agents/skills/talking-head-recut/references/layouts/pip.html +143 -0
  375. package/.agents/skills/talking-head-recut/references/layouts/split.html +121 -0
  376. package/.agents/skills/talking-head-recut/references/layouts/stack.html +109 -0
  377. package/.agents/skills/talking-head-recut/references/styles/academic.html +172 -0
  378. package/.agents/skills/talking-head-recut/references/styles/audit.html +170 -0
  379. package/.agents/skills/talking-head-recut/references/styles/editorial.html +189 -0
  380. package/.agents/skills/talking-head-recut/references/styles/geom.html +181 -0
  381. package/.agents/skills/talking-head-recut/references/styles/minimal.html +130 -0
  382. package/.agents/skills/talking-head-recut/references/styles/spotlight.html +142 -0
  383. package/.agents/skills/talking-head-recut/references/styles/swiss.html +188 -0
  384. package/.agents/skills/talking-head-recut/references/styles/terminal.html +196 -0
  385. package/.agents/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
  386. package/.agents/skills/talking-head-recut/references/styles/xhs.html +206 -0
  387. package/.agents/skills/vidfarm-media/SKILL.md +85 -0
  388. package/.agents/skills/vidfarm-media/references/tts.md +54 -0
  389. package/.agents/skills/vidfarm-media/scripts/audio.mjs +628 -0
  390. package/.agents/skills/vidfarm-media/scripts/wait-bgm.mjs +31 -0
  391. package/.agents/skills/website-to-video/SKILL.md +145 -0
  392. package/.agents/skills/website-to-video/assets/sfx/CREDITS.md +35 -0
  393. package/.agents/skills/website-to-video/assets/sfx/manifest.json +97 -0
  394. package/.agents/skills/website-to-video/references/beat-builder-guide.md +263 -0
  395. package/.agents/skills/website-to-video/references/capabilities.md +713 -0
  396. package/.agents/skills/website-to-video/references/step-0-capture.md +55 -0
  397. package/.agents/skills/website-to-video/references/step-1-design.md +333 -0
  398. package/.agents/skills/website-to-video/references/step-2-brief.md +178 -0
  399. package/.agents/skills/website-to-video/references/step-3-storyboard.md +572 -0
  400. package/.agents/skills/website-to-video/references/step-4-vo.md +225 -0
  401. package/.agents/skills/website-to-video/references/step-5-build.md +483 -0
  402. package/.agents/skills/website-to-video/references/step-6-validate.md +341 -0
  403. package/.agents/skills/website-to-video/scripts/w2h-verify.mjs +759 -0
  404. package/SKILL.director.md +37 -0
  405. package/SKILL.platform.md +6 -1
  406. package/demo/dist/app.js +295 -11
  407. package/dist/src/app.js +317 -133
  408. package/dist/src/cli.js +529 -12
  409. package/dist/src/composition-runtime.js +262 -3
  410. package/dist/src/devcli/doctor.js +192 -0
  411. package/dist/src/devcli/hyperframes-cli.js +118 -0
  412. package/dist/src/devcli/skills.js +476 -0
  413. package/dist/src/devcli/stills.js +249 -0
  414. package/dist/src/editor-chat.js +255 -0
  415. package/dist/src/hyperframes/composition.js +5 -5
  416. package/dist/src/services/composition-lint.js +199 -0
  417. package/dist/src/services/hyperframes.js +67 -13
  418. package/package.json +2 -1
@@ -0,0 +1,244 @@
1
+ # THEME mode — composed visual constitutions
2
+
3
+ Theme mode is the third compiler (`scripts/make-theme.cjs`), beside Standard and
4
+ Cinematic. It exists because "mode" was a bundle of orthogonal axes pretending
5
+ to be one switch. A theme DNA composes its identity from registries implemented
6
+ ONCE in the compiler — **paradigms are the unit of code; DNAs are the unit of
7
+ identity**. A new look is a JSON file; only a genuinely new paradigm/setpiece
8
+ (rare) touches the compiler.
9
+
10
+ ```
11
+ theme DNA = body PARADIGM how the transcript surface lives
12
+ × body LAYER fg-alpha (rail.html channel) | bg-embed
13
+ × hero SETPIECE the climax choreography
14
+ × front FX flash / rings / sparks / scanband / crowdflash / paflash (fg, over subject)
15
+ × PLATE budget charge-dim (in-page) + punch/shake/grain (_postfx.sh)
16
+ × LINKAGES declarative theme interactions
17
+ ```
18
+
19
+ Standard and Cinematic were, in retrospect, two fixed points of this space.
20
+ Standard is now RETIRED (2026-06-12): its rail×embed-climax point is served by
21
+ the `anchor` theme (rail paradigm × settle setpiece — the quiet default).
22
+ Cinematic remains a separate compiler; do not re-implement it as a theme yet.
23
+
24
+ ## Unification roadmap (strangler fig — interface first, engines later)
25
+
26
+ The user-facing model is already unified (SKILL.md Step 0): one catalog of
27
+ LOOKS; classic looks pick a DELIVERY (rail | column), themed looks bind their
28
+ own. "Standard/Cinematic" are delivery/compiler names, not modes. Remaining
29
+ phases, each gated on need — never rewrite for tidiness alone:
30
+
31
+ - **Phase 2 — one authoring schema.** `lines`/`minors`/`hero` are already
32
+ ~90% shared between standard.json and theme.json; a router that translates a
33
+ single `caption.json` into the engine-specific file removes the last
34
+ user-visible seam. cinematic.json's blocks/planes are the odd one — map the
35
+ common fields, pass engine-specific ones through.
36
+ - **Phase 3 — engine convergence.** Port a classic delivery into make-theme
37
+ ONLY when something forces it (e.g. a classic DNA wants a plate budget or a
38
+ setpiece). Acceptance bar: blind A/B on the cap_multi regression scenes vs
39
+ the old compiler — swap engines only when indistinguishable or better. Until
40
+ then the old compilers are the reference implementation of 8 rounds of
41
+ validated typography (lockup/orbit, multi-climax, ratio-lock, per-plane
42
+ legibility, occlusion adjudication) — that machinery is the moat, not debt.
43
+
44
+ ## Body paradigms (registry)
45
+
46
+ | paradigm | surface | layer | entrance verbs | exit verbs |
47
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48
+ | `rail` | lower-third lines, replace | fg | `stamp` (1f hot appear→crush→recoil→cool), `flick` (tube double-flick), `bootflick` (corrupted-cyan boot 1–2f → settles to UI color; minors keep a cyan/red registration shadow). `stamp` minors cool to `palette.minorCool` (default amber) | `drop` (mass falls), `powercut` (bright→ghost→off) |
49
+ | `panel` | docked glass console, accumulate + typed | fg | `type` (width steps per word, $ prompt, caret blinks) | hold |
50
+ | `poem` | open-space stanzas, accumulate; letters CONDENSE from seeded dust | fg | `condense` | `drift` (stanza hand-off) + optional dispersal linkage |
51
+ | `takeover` | full-frame hard-cut cards, plate dimmed throughout | bg | `cut` (+ tension `creep` before silences, auto-detected) | hard cut / blur dissolve |
52
+ | `lastpage` | manuscript rail (typed serif) + a seeded field of BLURRED apex-word instances haunting the room from t=0 | bg | typed rail; field breathes imperceptibly | rail fades; field resolves at apex (see `rackfocus`) |
53
+ | `flaprail` | split-flap word tiles on a chyron bar (tag + ROW flip-counter; optional odometer chip docks above the bar while the first emphasis line reads) | fg | `splitflap` (3 flips: wrong word → wrong word → real word clacks on hot, squash → elastic settle → cools to bone; emphasis tiles keep amber text + underline) | flip-to-blank cascade left→right (completes before the next line) |
54
+ | `ledboard` | amber LED departure strip docked lower-third (`body.board` geometry); lines page by vertical scroll-snap (steps(6)) inside the board window; furniture: green platform tag, ticking seconds clock (stacked digit reel), ⚠ DELAYED blinks then pages to ● ON TIME ~0.7s after the apex, idle LED shimmer in dead air ≥1.2s | fg | `ledwipe-mini` (per-word L→R LED column wipe, clipPath steps(len), + 1-frame arrival flicker; emphasis words get the LED-refresh double-blink; last word gets one late refresh) | scroll-snap page-up (next line pages in at the same instant) |
55
+ | `vhsrail` | camcorder-playback lower third: every word carries a PERMANENT 1px red+cyan misregistration fringe (split clip-path halves); furniture: ▶ PLAY / ◀◀ REW top-left (REW gag in dead air ≥0.7s + the final rewind), ● REC top-right through the apex window, green timestamp bottom-right with 1 Hz blinking colon, idle tape-drift line in long silences, plus apex-coupled artifacts (1-frame white tear band + head-switching noise bar at REC FREEZE, scrub lines at the apex band on the hero rewind) | fg | `trackglitch` (instant on + 2-frame y-shake + 1-frame band-slice shift of the word's bottom half; emphasis = PAUSE jitter ±1px y oscillation + white noise-band flicker) | REWIND streak left + flat-white echo copy + 2 scrub-line flickers |
56
+ | `hudrail` | arcade-cabinet HUD: whole frame plays through CRT overlays (scanlines `body.scan` + corner vignette); docked HUD bar (`body.bar` geometry, 2px accent border, glow) with `body.tags` 1UP / CREDIT furniture — the 1UP tag blinks on the classic 0.45s attract cadence all clip; HUD yields (`body.yield`) while the boss lands | fg | `coinpop` (instant-on + steps(2) scale pop from the baseline + 1-frame white coin-blip tick over the word; emphasis = 3-frame palette swap body→accent→magenta→body) | checkerboard dissolve (words vanish in 2 alternating 2-frame passes, line off ≤ DUR−0.02) |
57
+ | `carbonstrip` | cold-war case-file transcript strip docked on the clearer side (manila gradient, punch holes, faint red `body.watermark`, typed `body.header` that types on by width steps); lines live on up to `body.rows` fixed slots; PAGES (broken at full rows, dead-air gaps > 0.7s, and after the hero hand-off line — it is filed away while the stamp owns the frame); the strip top-shadow breathes during the stamp's dead-still hold and the strip yields (`body.yield`) while it lands; the final page is pulled with the whole strip at clip end | fg | `hammer` (per-char sets 30ms apart, scale 1.35→1 in one frame = the stamp motif at low amplitude; seeded ±1.2px baselines + seeded ribbon-ink opacity; every strike kicks the strip 1px — y-channel locked while the strip itself tweens; emphasis words get a red ink ellipse drawn around them, 0.25s) | X-row over-strike (3 chunks per line, 0.05s apart, lines 0.16s apart) → carriage yank-down feed → return; roomy cadence in dead air, compressed when the next page is close — always completes before the next page's first strike |
58
+ | `laserrail` | concert lower third: lines centered on a bottom rail (`body.bottomPx`), uppercase laser-green words with a neon text-glow; emphasis words render at `body.minorScale`× with a hotter glow; word centers are BAKED at compile time from the measured char-width table (`assets/fonts/char-widths.json`, ≤3px vs browser ground truth) so the beam aim can't be skewed by font-load timing; per-word furniture = two thin beams (accent from top-left, magenta from top-right) that sweep to CONVERGE on the word 2 frames early + a convergence flare; beams dim ×`yield.beamDim` inside the apex window and the visible line dims to `yield.dim` | fg | `igniteconverge` (beams converge at st−0.083 → flare pop → word snaps on at opacity 1 with brightness 1.85, crush 0.09s power3.in → 2-frame contact squash → elastic settle → brightness cools; emphasis = single 1-frame strobe off/on + lingering beams) | sweeper beam crosses L→R in 0.13s and each word streaks away (x+44, blur 5) as it passes; line off ≤ DUR−0.02 |
59
+
60
+ | `stormrail` | rain-washed lower third: ambient rain = `body.rain.count` seeded thin streaks falling on repeating linear cycle tweens (pure f(t), one slanted wind vector, mid-fall at t=0); a second seeded set DOUBLES the rain for ~1s after the strike; lines sit on a bottom gradient scrim (stable reading surface); the visible line dims to `yield.dim` while the bolt lands and its text-shadow flips toward the strike (`hero.params.side`) for the flash frames | fg | `lightningpop` (the apex motif at low amplitude: instant on at brightness 2.2, y+4, scale 1.06 → 0.12s micro settle; emphasis = sheet-lightning double flash, 2-frame brightness 1.9/1.0/1.8 chain — the bg sky double-kisses at the same beats) | wash downward with the rain (y+22, blur 3, 0.18s power1.in); a line facing dead air washes early at lastWord+1.08s; line off ≤ DUR−0.02 |
61
+ | `holorail` | volumetric projection plate: a scanlined glass slab (`body.plateW`×`plateH`, centered at `H − bottomPx`) with corner brackets + feed tag (`body.tag` / `theme.plateTag` override) boots like a projector turning ON (scaleY 0.03→1 expo + 1-frame flicker) and breathes a finite yoyo luminance cycle sized to the clip length; lines sit centered IN the plate (`lineDy` below plate center) with a constant chromatic-fringe text-shadow (−1.5px accent / +1.5px magenta) and drift slowly in rotationY (it IS a projection); the whole railwrap — plate included — dims to `yield.dim` while the apex lands | fg | `sweepboot` (the apex motif at low amplitude: instant opacity + rising clip-wipe reveal 0.15s + 1-frame x interference glitch at st+0.05/0.09/0.13; emphasis = 2-frame projection DROPOUT at `body.emphDelay`, restores brighter in `palette.em` with a hotter fringe, then settles back — the delay auto-shrinks near the line's exit so dropout+restore always complete) | projector cut — brightness 2.2 pop → collapse to a horizontal slit (scaleY 0.045, 0.07s power3.in) → to a dot (scaleX 0.015, 0.06s) → off at exit+0.15; the plate itself gets the same cut at DUR−0.14 |
62
+ | `planktonrail` | deep-sea lower third on TWO coexisting row slots: even lines ride the upper row (`H − bottomPx − rowDy`), odd lines the lower (`H − bottomPx`) — couplets share the water like drifting strata. A line clears when its row is next needed (line i+2 in − 0.15) or ~0.3s after its couplet finishes speaking (staggered pair exits, +0.12s on odd rows); the pre-apex leftover clears at heroIn−0.21 while the FEEDING line (last to start before the apex) yields to `yield.dim` instead — no restore unless ≥1.2s of hold remains (it exits dimmed, by design); a line entering during the hold arrives at `yield.enter` and restores at I+`yield.post`; every line floats on a gentle y keyframe drift sized to its window. Furniture: `body.motes` = {count, near, seed} plankton motes on seeded drift walks f(t); the first `near` seed a ring around the apex heart (ring radius scales with hero fontPx/120) and get ATTRACTED to the bloom at I−0.19 (pulled 0.72× toward it, brightening to 0.42 at scale 1.7), wiggle through the hold, and sink at clip end | fg | `glowon` (the apex bloom at low amplitude: 2-frame opacity ramp + radial bloom from word center — scale 0.92→1, blur 5→0, brightness 0.45→1, 0.4s sine.out — while a cyan glow text-shadow grows in; emphasis = slow DOUBLE-BEAT propulsion pulse at st+0.52, 5-key brightness/scale 0.55s, guarded ≤ DUR−0.09) | light sinks — y+15 while dimming, 0.3s power1.in; the last line floats to the end of the clip; line off ≤ DUR−0.02 |
63
+ | `sheenrail` | iridescent silk lower third on TWO coexisting row slots: even lines ride the upper row (`H − bottomPx − rowDy`), odd lines the lower (`H − bottomPx`) — couplets read together like a woven pair. Words are aurora-gradient ink (background-clip:text over a rose→teal→violet 300% wash whose backgroundPosition drifts f(t) 0%→300% across the whole clip — the body's hold life) above a blurred dark understroke (top+3px, blur 3); a soft radial band scrim sits under the rows (stable reading surface). Line scheduling mirrors planktonrail: a row clears when next needed (line i+2 in − 0.15) or shortly after its couplet finishes speaking (pairEnd + 0.23 + 0.17 on odd rows); the pre-apex leftover clears at heroIn−0.32 while the FEEDING line stays and dims with the railwrap yield (`yield.dim` at I−`pre`, restore at I+`post` — band included); the last line holds to the end | fg | `flowon` (the ribbon's flow at low amplitude: 2-frame opacity + y8 settle 0.38s sine.out; emphasis = ONE bright sheen sweep — a white highlight marches through the word once at st+0.16 (backgroundPosition −80%→180%, 0.42s power2.inOut) + a brightness 1.55 pulse) | dissolve UPWARD — words to y−12, blur 3, 0.32s power1.in staggered 0.035; each line releases `body.streaks` seeded light streaks (rose/teal/violet verticals) that float up from its row (y 14→−78, 0.62s, start clamped ≤ DUR−0.66) |
64
+ | `scoperail` | oscilloscope lower third: a dark phosphor scope band (`body.bandH`, top border + glass shadow) hosts HUD readouts (`body.hudL` left, sample-rate `· TRIG` + amber trig LED right), a graticule, and an ALWAYS-ALIVE waveform — an SVG polyline rebuilt from baked point-set states (seeded pseudo-RMS envelope at ~12 states/s + 3-frame triplets on word arrivals: speech grows the amplitude, silence flattens it, every word kicks a local gaussian burst at its slot center — burst x BAKED at compile time from the measured char-width table; the hero words kick WIDE bursts spread from `HG.x` toward `HG.x + 0.6·halfW`, where the trace surges to write). Body lines sit centered on the band above the trace with reserved-width slots (sizer + clip — no re-center drift as words arrive); the whole band (lines + wave + HUD) dims to `yield.dim` while the apex writes. At the FINAL transcript word the scope DIES: band x-shake, trig LED panics red then dies, the trace explodes to max-amp chaos for ~0.3s, flatlines, collapses to a single dot (scaleX 0.015) and `body.siglost` stamps with a 2-frame flicker (all clamped ≤ DUR−0.02) | fg | `tracewipe` (the apex pen-write at low amplitude: clip wipes the word in L→R over 0.10s + a 2-frame just-traced flash — flash-white instantly, settle to phosphor green; the death word settles to `palette.em` amber; the trig LED blinks on every arrival; emphasis = a ticking frequency-readout chip above the word, 3 seeded ascending values stepping every 2 frames) | the line collapses INTO the waveform (y+30, 0.13s power2.in) — early into dead air (lastWordStart+0.67), else just before the next line needs the slot; the last line collapses as the trace flatlines (min(NZ+0.33, DUR−0.2)) |
65
+ | `paperrail` | stop-motion craft table: a kraft strip (torn top edge via seeded polygon clip-path, washi-taped corners, handwritten `body.tag` in the tag font) docked lower-third (`body.strip` geometry, centered by default); body words are cream paper chips (`palette.chip` on `palette.chipEdge` border, hard dy3 shadow) on centered replace-lines; the whole strip jitters ±0.7px every 4 frames (handmade stop-motion weave); the hero slot keeps a red paper star (`palette.accent`, rail↔climax hand-off) that pulses 1.18→1.06→1 as the apex chips land; the FINAL transcript word is an accent-red sign-off chip; emphasis words get a washi-tape slap (steps(2) scale 1.7→1 at `word.start + body.tapeDelay`, chip pressed 1 frame); strip + lines yield (`body.yield`) while the apex lands | fg | `place` (the papermat drop at low amplitude: opacity full in 0 frames + seeded ±2.5° rotation, y −16 + scale 1.06→1 steps(2) 0.12s; hold = rotation-only ~5fps wobble) | `peel` (rotation −8°, y −40, fade, steps(3), staggered 0.03s; last line clamped to finish on frame) |
66
+ | `popuprail` | pop-up book page: a cream page strip (`body.strip` geometry, center foldline, top border + paper glow inset) unfolds up from the bottom edge (scaleY 0.02→1 back.out at 0.14 — the stage is built) and hosts TWO reading rows (`body.rowA`/`rowB` px above H) that alternate per line; the whole page breathes a gentle y drift sized to the clip; the hero slot keeps a blue paper star chip (`palette.accent` clip-path star, rail↔climax hand-off — spliced into the line whose window holds heroIn); emphasis words land at `body.emPx` weight 800 with a contact squash (1.06/0.93 set → elastic settle) the strip FEELS (1px dip), then flick-wobble (5-key rotationX, squeezed to fit before the fold) with a blue paper strut leaning in behind (scaleY back.out(2)); the FINAL transcript word is a blue sign-off with a strut; page yields (`body.yield`) while the centerfold lands; on the final word the whole page TILTS 2° +x6 (paper physics, `body.tilt:false` opts out) and the strip folds shut on the last frame (scaleY power3.in ≤ DUR−0.017) | fg | `popup` (the centerfold motif at low amplitude: opacity 1 in 0 frames + rotationX 85→0 baseline hinge, 0.25s back.out(1.4), back-shadow grows as it rises) | `fold` (the page closing: rotationX 88 power2.in 0.12s, shadow off, L→R wave staggered 0.045s, slot hidden at +0.13; fold at next line in / lastWord+`body.maxHold` in silence, wave clamped ≤ DUR−0.017) |
67
+ | `chalkrail` | night-lecture chalk band: a deep-green board strip (`body.strip` geometry, worn top hairline, eraser smudges, handwritten `body.tag` header in the tag font, two chalk sticks bottom-right) docked at the bottom edge hosts `body.rows` reading rows that ACCUMULATE — lines fill the rows top→bottom in phases of rows.length; when the next phase needs the rows an ERASER SWIPE clears the board (blurred light band sweeps across 0.42s at `prevEnd + body.eraseDelay` clamped clear of the next phase, the old words SMEAR out scaleX 1.3 + x+24 + blur(8) staggered 0.06s, faint ghost smudges fade in and STAY — chalk never fully erases); the FINAL transcript word lands in yellow chalk (`palette.em` sign-off); the band yields (`body.yield`) while the apex writes | fg | `scribble` (the chalkwrite verb at low amplitude: 2-frame opacity pop + scribble clip-reveal steps(4) 0.12s + y4 drop-settle + 6 seeded dust specks puffing at the word base, seeded ±2° tilt; emphasis = double underline dashes drawn beneath at st+0.22/+0.38) | eraser-swipe smear between phases (scaleX 1.3, x+24, blur 8, power2.in 0.18s); the final phase holds to clip end |
68
+ | `markerrail` | street handstyle rail: centered marker lines on a bottom rail (`body.bottomPx`), `palette.body` cream paint with a heavy drop text-shadow; emphasis words take ALTERNATING paint colors (`palette.em`/`em2`, yellow/magenta) + a spray-underline SWOOSH (dash-revealed squiggle viewBox-stretched to the word) with 8 seeded overspray dots that pop and fade; the FINAL transcript word lands BIG (1.5×) in `palette.em` with mini apex-impact physics (crush 0.09s power3.in → 2-frame contact squash → elastic settle — it rides the plate punch); the line visible at the tag's onset yields (`body.yield`, restore only with runway before its buff — else it exits dimmed) | fg | `flick` (the spray-write verb at low amplitude: opacity full in 1 frame at scale 1.18, seeded ±6° rotation settling to ±2°, 1-frame squeak skewX 7, back.out(2.2) settle 0.18s) | ROLLER BUFF (gray paint roller scaleX-sweeps the line 0.15s power2.in, words vanish under it, the wet smear lingers at 0.15 + blur(2) before fading); the last line is never buffed — the sign-off stays painted |
69
+ | `brushrail` | washi paper band: a deckle-edged band (`body.strip` geometry, two faintly rotated `paperHi`→`paperLo` under-sheets at 0.42 + a translucent `sheetHi`→`sheetLo` main sheet with warm inset shadow) swipes in L→R behind a traveling brush-head shadow (clipPath wipe 0.2s power2.out + blurred `palette.bh` gradient head — the ink gesture at low amplitude), then the under-sheet breathes faintly (0.32 Hz baked f(t)); body lines are centered replace-lines on the band (`fonts.body` serif at `body.fontPx`/`body.weight`, seeded ±1° tilt); emphasis words get a DOUBLE curved ink underline (`palette.ulInk`, fat 7/0.3 wash + tight 2.6/0.95 core, dash-drawn at st+0.12/+0.15); band + the line under the gesture yield (`body.yield`) while the apex lands; the band exits with the last line on one final R→L wipe | fg | `brush-wipe` (the gesture at low amplitude: clipPath inset reveal L→R 0.16s power2.out with a blurred per-word brush-head shadow riding the reveal edge, then vanishing) | wet-cloth WIPE (the reveal in reverse: the line clipPath wipes R→L over 0.10–0.14s power2.in with an erase brush head riding it, at min(next line − 0.136, lastWord + `body.maxHold`); the LAST line and the band wipe together at DUR−0.142) |
70
+ | `inkrail` | sumi ink on still water: up to THREE fixed reading rows at the bottom center (`body.bottomPx` = last-row center, `body.rowGap` apart; rows cycle in pairs, the closing line takes the third row — the final thought ACCUMULATES instead of replacing); `fonts.body` Mincho serif at `body.fontPx`/`body.weight`/`body.letterSpacing`, `palette.body` ink over a paper-white text-shadow halo (`palette.paper`/`paper2` glow stack — readable on bright skies) with a duplicate blurred dark halo per word; an ink-settling RULE (86%-width gradient hairline, scaleX 0→1 over 0.9s) draws beneath each line at firstWord+0.12; emphasis words shed a faint ink wisp curling off the word top (st+0.55, ±dir by line parity, skipped near clip end); the rows visible under the bloom yield (`body.yield` — dim at heroIn+`delay`, restore at heroIn+`post` only with runway before the exit) | fg | `bleed` (the apex bloom at low amplitude: opacity snaps in 2 frames; blur 12→0 + scale 1.25→1 power2.out carry the bleed — late words bleed faster so they resolve before clip end; the dark halo overshoots scale 1.5→1.04 while its opacity decays 0.5→0.25) | RE-DISSOLVE (blur 9 + scale 1.13 + fade + y−8 power1.in — ink dispersing back into the water) as the line-after-next approaches (= the next occupant of its row, outDur 0.5−0.05·i, never mid-read); the closing TWO lines persist to clip end |
71
+ | `ransomrail` | kidnapper's collage rail: every transcript word is a cutout chip in one of 4 cycled recipes (cream/`fonts.body` Anton, black/`fonts.dark` Inter-800, newsprint/`fonts.news` Special Elite, accent/`fonts.accent` Permanent Marker — emphasis words snap to the accent chip, never two identical chips in a row) PASTED along the bottom rail line (`body.bottomPx`) with seeded crookedness (rot sign alternates with line+word parity, baseline dy leans the other way), seeded ±px sizes (`body.fontPx`−2..+1, emphasis +3) and torn edges (seeded 12-vertex tear polygon, same paper stock as the apex); chips carry a hard dy5 offset drop-shadow; lines breathe (5-key scale keyframes) through their hold; the whole railwrap yields (`body.yield`, container opacity — never contests per-chip channels) while the apex letters slam | fg | `paste` (the apex slam motif at low amplitude: opacity full in 1 frame at scale 1.12 / rot×1.5 / y−8 → power3.in crush 0.08s → 2-frame contact squash 1.05/0.95 → elastic settle; emphasis = 1-frame RE-PASTE lift at `body.emphDelay` — shadow grows to a flight blur, rotation flips sign for good, then crush + squash + elastic again, rip-runway-guarded) | RIPPED off one by one (rotation ±16/17° throw + y−30 + fade, power2.in, staggered 0.045s) with a 1-frame paper-tear flash under each chip — timed so the rip tail overlaps the next line's pastes a beat (collage chaos, by design); the last line tears off clamped to finish on frame |
72
+
73
+ fg body uses the **rail.html alpha-webm channel** (true alpha — dark panels and
74
+ scrims work; never the screen-blend index_fg path, which can only add light).
75
+
76
+ ## Hero setpieces (registry)
77
+
78
+ | setpiece | what happens | notes |
79
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
80
+ | `detonation` | charge-dim → sheared stencil slices crush in hot → SNAP into register → squash → elastic settle → paint cools to bone → bars/ticks/designation-tag deploy → shear-apart exit | pairs with fx flash/rings/sparks + plate punch/shake |
81
+ | `decode` | slot-machine glyph reels (steps() ease, seek-safe) lock left→right with RGB jitter → lock snap → CRT power-off exit | pairs with `redact-until-hero` |
82
+ | `drawon` | the word is WRITTEN stroke-by-stroke from a single-line font (Hershey) — per-stroke paths revealed sequentially at constant pen speed, nib rides `getPointAtLength`, hops at pen lifts; then hum + buzz dip | any word, zero tuning: `gen-stroke-path.py` lays out glyph pen-paths at compile time |
83
+ | `cpslam` | acid-yellow stencil word slams in BEHIND the subject with REAL diagonal notch cuts (SVG mask = true transparency over footage), chromatic split that settles to a PERMANENT cyan/red registration error, seeded glitch ticks, katakana tag, glitch-out exit | bounded hold (~2.6s default, `params.hold` / `hero.exitAt` override) — a climax is an event, not wallpaper |
84
+ | `coverword` | the spoken apex word SET IN the replica typeface of the CP2077 cover mark (`assets/brand/CyberpunkReplica.ttf` — lowercase glyphs carry the logo's real brush chops, blade terminals and spikes; logo case = First-upper rest-lower). The setpiece adds only what the font lacks: solid cyan duplicate offset (-7,8), baseline streak merged with the glyph feet + cyan debris, circuit trace off the tail, tear-in slices / living print / tear-out | metric-exact layout from `cyberpunk-widths.json` (advance widths + ink bounds; `fontPx` = target INK height). No digits in the replica → compile ERROR with guidance. Replica font: personal-use license — samurai is already fan-kit non-commercial |
85
+ | `assembly` | (inline, poem) apex word condenses BIG while star particles fly into it | |
86
+ | `colorflip` | (inline, takeover) accent-color crush card + dim kick + squash/settle + loom | pairs with fx flash + plate punch/shake |
87
+ | `flapboard` | split-flap departures board takeover: floodlight dim/scrim swing on, the housing clacks down (rotationX, squash, elastic) behind the subject, one giant flap tile per char flip-cycles 3–5 seeded wrong glyphs then LOCKS left→right across `params.lockWindow` (hot flash → cools to bone) under baked clack y-jitter; lock-complete = big clack + amber glow flicker + rule wipe + steps() status-ticker; hold = loom + one tile re-flutter; exit = tiles flip to blank cascade, housing flips away | pairs with `fx.crowdflash` (pops at lock start/end) and `plate.punchOffset = lockWindow` so the plate punch lands on the lock-complete clack, not the hero onset |
88
+ | `ledwipe` | transit LED board takeover: cool scrim + dim charge, an amber dot-matrix panel EXPANDS upward (scaleY steps(6)) behind the subject, header tags + unlit LED ghost boot-flicker alive, then the word ILLUMINATES column-by-column (clipPath L→R, steps ≈ 1.4×chars over `params.wipeDur`) hot → cools to amber; contact = cell squash + elastic settle + PA "ding" double brightness pulse; an 8-phase chasing LED-marquee border runs to the exit; hold = glow breathe + seeded-look LED dropouts; exit = word pages up out of the window, panel collapses back down | pairs with `fx.paflash` (amber PA flash at wipe-complete contact). Panel geometry derives from fontPx (`panelH = 44 + 1.42×fontPx + 18`); `params.panelW` fixed, width-fit shrinks the type only. Plate: grain-only (no punch) is the demo register |
89
+ | `vhsosd` | REC FREEZE camcorder slam: permanent lens vignette (`params.vignette`) + backlight-comp scrim (peak = `plate.charge`, cools to 0.69×) kill the bright sky; the word crushes in as a huge OSD readout — 3 horizontal clip-path tracking bands (`params.bandClips`) sheared (`params.bandShear`) + blurred (power4.in over `params.crush`) SNAP into register on the contact frame, squash → elastic settle; red/cyan misregistration copies cool from ±`misregIn` to ±`misreg` px and keep BREATHING through the hold under tape-weave y jitter (`params.weave`) + slow loom; auto-iris pump (white wash 0.20, dark dip = `plate.dim`); exit at `I + params.hold` = REWIND streak left + flat-white echo copy | pairs with the `vhsrail` paradigm, which emits the fg REC-FREEZE artifacts (tear band, head-switching bar, apex scrub lines, ● REC) at the same I/X times. Plate: grain-only (no punch) is the demo register; hold-life keyframes auto-clamp inside [contact, exit] |
90
+ | `bossintro` | arcade BOSS INTRO: the room dims (gradient `plate.dim`) behind a CRT edge glow (cyan base wash that pulses on the last emphasis word before the boss and spills magenta on the strobe + the final word); `params.tag` (WARNING) blinks 2× above the word rect; ~COLS×ROWS (`params.rows`, cells 0.7×/0.5× fontPx) seeded pixel blocks fall steps(3) from above into a tight matrix grid covering the word rect, each landing with a 1-frame white tick; at `I + params.flashDelay` the word flashes ON (Press Start 2P, instant at opacity 1, scale 1.15 → steps(3) crush → 2-frame squash → elastic settle) with ±4px chromatic ghost layers + a 3-frame palette strobe (white→cyan→magenta→white); hold = quantized 1.6% breathe + CRT glow cycle + baked block shimmer blinks; exit at `I + params.hold` = per-letter checkerboard dissolve, blocks drop away steps(3) | pairs with the `hudrail` paradigm; emits fg furniture via setpiece fg parts: letterbox bars (`params.letterbox` px) slam in steps(3) with a 1-frame overshoot and retract after the exit, HI-SCORE odometer (accent label, yellow digits) rolls every 0.066s through the hold, 1-frame white tick out. `fx.coinflash` adds the 1-frame radial impact flash at the strike; plate punch anchors at `punchOffset` = `flashDelay` |
91
+ | `rubberstamp` | the footage becomes an archive page (vignette charge = `plate.charge`, manila sepia wash `params.sepia`, dim kick = `plate.dim` that cools to 0.385×) and the verdict slams in BEHIND the subject as a bordered rubber stamp at `params.rotation`: a manila paper wash lights an instant before contact, the stamp crushes 2.2→1 power4.in over 0.115s, 2-frame contact squash, double-strike ghost print (`opacity 0.35`, offset +5/−4 rot 1.3), two thin-ink patches (`params.patches` clip-path circles in paper color), wet-ink saturate/brightness settle, paper indent shadow bloom; stamps don't move — the hold is DEAD STILL, sold by the breathing indent + a slow paper loom; exit at `C + params.hold` = mechanical 3-frame yank-down cut (the page is filed away), the archive plate releases 0.25s before | contact `C = heroIn + params.crush`; pairs with `fx.inkflecks` (seeded red spatter at C, ballistic with gravity) and `plate.punchOffset = params.crush` so the plate punch lands on the stamp contact; pairs with the `carbonstrip` paradigm (strip yield + shade breathe anchor at the same C); face chrome (border, radius, padding, ghost offset) scales with fontPx from the 120px demo cut |
92
+ | `lasercage` | concert-blackout laser show: the plate dims to `plate.dim` at t=0 and deepens to `plate.charge` before the drop while haze cones breathe in the top corners; a 6-beam array (alternating accent/magenta, emitters along the top edge) snaps on at I−0.26 and SWEEPS to converge on the word center (staggered 0.022s), a hot core pops at convergence; the word IGNITES behind the subject as an additive glow stack (wide accent blur 0.22×fontPx + magenta fringe offset + tight soft blur + near-white core): scale 1.16 crush power4.in → 2-frame contact squash → elastic settle + 2 controlled strobe pops (brightness 2.05, 1s apart, runway-guarded); a criss-cross beam CAGE (6 lines derived from the word rect) draws itself dash-by-dash around the word and flickers; through the hold the array FANS OUT slowly to floor targets (the iconic concert fan) while the word looms; exit at `heroOut − 0.38` = cage un-draws, beams sweep away L→R (+0.74W) carrying the letters (per-letter streak + blur, stagger auto-clamped ≤ DUR), the room lifts back to 0.12 | word geometry is metric-exact via `assets/fonts/char-widths.json` (cage/spill/flash all derive from `halfW` + `fontPx`); pairs with `fx.laserflash` (accent contact flash at I+0.03, sized 2·halfW+80 × 4.8·fontPx) and the `laserrail` paradigm (same converge-ignite motif at low amplitude); plate punch anchors at `punchOffset` ≈ 0.07 (the ignite contact) |
93
+
94
+ | `boltstrike` | THE STRIKE: a slate storm mood (`params.mood`) sits on the room from t=0 and the sky KISSES (1-frame 6% gradient brighten) on every body word — double-kiss on emphasis words, re-flashes at I+0.84/I+1.44 during the hold; the room charge-dims to `plate.charge` under a radial word scrim from I−0.39; a hand-authored branched bolt (5-seg zigzag + 2 branches, haze/glow/core SVG stack in `palette.accent`/`glow`/`core`) flashes 2 frames BEFORE the word — leader 1 → 0.35 → return stroke 1 at contact — with a sky flash; the word slams in (Anton scale 3.1 crush power4.in 0.105s, blur 14→0, brightness 3.2→2.5) → 2-frame contact squash → elastic settle, lit HARD for 2 frames then cools to 1; SIGNATURE: the word's text-shadow flips toward the bolt side for the flash frames; ozone under-glow (accent, blur 26×fontPx/145) blooms at contact and breathes (6-key opacity cycle) through the hold + slow loom + 2-frame lit blips on the sheet re-flashes; the dim releases at the flash, settles to a `plate.dim` storm hold and lifts before the exit; exit at `min(heroOut−0.2, I+params.hold)` = washes downward with the rain (y+38, blur 6) | bolt geometry is baked at compile time as offsets from the word center (halfW/360 × fontPx/145 units, `params.side` flips it); word rect is metric-exact via `assets/fonts/char-widths.json`; word scrim = 2·halfW+380 × 2.28·fontPx; pairs with `fx.strikeflash` (full-frame fg flash with the same leader/return flicker grammar) and the `stormrail` paradigm (rain doubles + shadow flip at the same I); plate punch anchors at `punchOffset` ≈ 0.02 (the return stroke) |
95
+ | `holoboot` | full volumetric boot behind the subject: a desk emitter dot pops (back.out scale), the projection cone SNAPS wide (scaleX 0.07→1 expo, 0.11s, then dips 0.55→0.95), a seed beam fires up from the emitter (scaleY power3.in, fades after contact), and the word boots with a RISING clip sweep (opacity instant at I−0.055, the reveal is the wipe) into a 7-layer projection stack (dark backing shadow / wide `palette.glow` blur / magenta + cyan chromatic fringes / `palette.core` word / scanline mask / climbing interference bands, band pitch 0.39×fontPx); contact at I+0.07 = brightness 2.3 flash + scaleX 1.07 / scaleY 0.91 squash held 2 frames + elastic settle + 1-frame x interference jumps; fringes blow ±8px then settle to the permanent ±2px registration offset; hold = bands climb −6 pitches, rotationY oscillates [0,6,−7,5,0], glow/cone breathe, emitter dot pulses, slow 1.028 loom; at `I + params.passAt` (≥ I+1.25, runway-guarded) a hand "passes through" the projection (skew 6/−4/0 + blur + fringe blowout + scaleY ripple — pure projection logic); exit at `min(heroOut−0.22, DUR−0.3)` = projector cut: brightness 2.4 → collapse to a horizontal line (scaleY 0.018) → to the base dot (scaleX 0.015), cone fades, dot pops 2.2× and dies. A second smaller emitter cone (`params.coneW`) rises from the desk under the holorail plate ALL video with baked flicker cycles + dot pulses, and gets its own projector cut at DUR−0.2 | word rect is metric-exact via `assets/fonts/char-widths.json` (cone width 2·halfW+80, emitter at cy+2.4·fontPx, all rig geometry derives from `halfW` + `fontPx`; scene scrim is a radial centered on the hero's frame fractions); pairs with `fx.holoflash` (cyan fg lock flash at I+0.075, radial at the same hero fractions) and the `holorail` paradigm (same sweep-boot + interference-glitch motif at low amplitude; the body cone is aimed at ITS plate); plate: grain-only (no punch) is the demo register, scene reaction = `plate.scrim`/`charge`/`dim` |
96
+ | `biobloom` | bioluminescent BLOOM behind the subject: the abyss grade (`params.mood`) + a breathing vignette (6-key opacity cycle sized to the clip) sit on the room from t=0 — the world is underwater before anything speaks; a creature pre-glow (1.083×/0.717× fontPx ellipse) gathers with a double-beat anticipation at I−0.31 and crushes to a point at I−0.115; a dark pocket scrim (`plate.scrim`, 2·halfW+280 × 2.5·fontPx) opens behind the word zone at I−0.03; the word CONDENSES in (scale 2.35 crush power4.in over `params.crush`, blur 15→2, brightness 2.6→1.7) → 2-frame contact squash (1.09/0.93) → elastic settle while cyan light SPILLS onto the scene (radial at the hero's frame fractions: snap 0.55 at contact → 0.2 → shimmer keyframes); 6 luminous tendrils (paired blurred SVG strokes — glow w9/blur5 + core w3/blur1.1, accent/violet/ice alternating) draw outward from the word rect staggered 0.05s (stagger auto-clamps so the last filament completes before the sink); hold = glow breathes 8–14% (4-key scale/opacity), glow-layer flicker, two counter-drifting caustic gradients shimmer over the text zone, the bloom drifts slowly with the current (`params.drift` on the x channel); exit at `min(heroOut−0.2, DUR−0.3)` = the light SINKS — tendrils (via their HTML wrapper, never gsap-y on inner SVG), caustics, pocket, spill and the word all drift down (+14/+26) while dimming, word blurs out | tendril geometry is hand-authored from the demo and baked at compile time as offsets from the word center (x scaled by halfW/demoHalf, y by fontPx/120, endpoints frame-clamped); word rect is metric-exact via `assets/fonts/char-widths.json` (0.01em tracking); pairs with `fx.sporeburst` (seeded spore puffs burst PAST the bloom at contact in the fg layer, ballistic with slight sink) and the `planktonrail` paradigm (same glow-on motif at low amplitude + mote attraction anchored at the same I); plate: pushIn+grain (no punch) is the demo register — the demo's postfx profile was `push` |
97
+ | `silkribbon` | aurora silk WRITTEN into the night sky behind the subject: the hero word is a sequential Hershey-stroke reveal (one `<path>` per pen stroke at constant pen speed, `gen-stroke-path.py` baked at compile time — any word, zero tuning) in a blurred halo (`params.haloWidth`, feGaussianBlur 7) + tight core (`params.coreWidth`, white drop-shadow), BOTH stroked by ONE userSpaceOnUse rose→teal→violet linearGradient with reflect spread; SIGNATURE: the gradient's x1/x2 translate f(t) from I−0.07 to the clip end (shift 1.5× the gradient span) so the aurora colors FLOW THROUGH the drawn ribbon during the hold; a soft light mote (blurred halo + core dot) rides the pen, hops at lifts, and blooms out 2.4× at the final stroke; scene reaction = two huge aurora blobs (teal top-left / rose top-right, frame-fraction geometry) drift the sky f(t) from t=0 at `params.wash` and DEEPEN to `params.deepen` as the ribbon writes, a top scrim (`plate.scrim`, 0.653H) charges in at I−0.34 (sky washout guard), a light spill (`params.spill`) tints the sky at I+0.1 once the ribbon completes and flickers gently, and the halo breathes (5-key opacity cycle) through the hold; gentle — no shake, no contact squash: the apex verb is the writing itself; writing window = `params.window` clamped so the ribbon finishes + holds before ENDT = DUR−0.04 | canvas/gradient/spill all derive from `params.targetWidth` (demo: 880 ink on a 1010×280 canvas, baseline 200; svgW = tw+130, spill = (tw+60)×0.51, gradient span = 0.6364·tw), centered at the scene-aware HG (pref top 18, the sky band — same as drawon); pairs with `fx.silkmotes` (seeded aurora motes rise near the ribbon during the hold, fg layer, demo spread fractions keep the face gap) and the `sheenrail` paradigm (same flow motif at low amplitude); plate: pushIn+grain (no punch) is the demo register — the demo's postfx profile was `push` |
98
+ | `scopetrace` | the scope's own trace LEAPS off the band and WRITES the hero word behind the subject: a surge column (3px, bottom-anchored scaleY pop, landing at the pen-start point parsed from the baked path) jumps from the scope band at I−0.12; the word is a sequential Hershey-stroke reveal (one `<path>` per pen lift at constant pen speed, `gen-stroke-path.py` baked at compile time — any word, zero tuning; punctuation stripped for the pen) drawn CORE-ONLY in a thin phosphor stroke (`params.coreWidth`, bright `palette.bright` + accent drop-shadows — it is a trace, not a tube), nib rides `getPointAtLength` and pops 2.4× at DRAWN; the phosphor FILL (blurred halo strokes, `params.haloWidth`, blur 7) flicker-arrives AFTER the write at FLICK = DRAWN+`params.flickGap` (pre-arm 2 frames early, 5-step 1/0.25/1/0.55/1 blink, core dips 0.55 for a frame); hold = glow hum (7 Hz + 11.3 Hz sine keyframes, f(t)) + 1.6% breathe on an HTML wrapper with transformOrigin at the hero's frame fractions, ending exactly at the collapse; exit = the word COLLAPSES to a flatline (wrapper scaleY 0.02, 0.14s power3.in, same origin) + a horizontal flash bar (2·halfW wide at the word center) that shrinks out — scheduled at nextSpokenWord − `params.clearGap` (clamped ≥ FLICK+0.45, ≤ heroOut) so the trace clears BEFORE the next line speaks; scene reaction = phosphor radial scrim (`plate.scrim` at the hero fractions, I−0.18 → EXIT+0.05) + green spill sized from targetWidth (`params.spill`); second beat: a 1-frame phosphor pulse answers the FINAL transcript word — the same death beat the scoperail finale owns | trace geometry derives from `params.targetWidth` (svgW = tw+140, local baseline 215, ink center ≈ baseline−28 — the demo registration; surge x parsed from the first `M` of the path); centered at the scene-aware HG (pref top 25, ink height 115); pairs with the `scoperail` paradigm (tracewipe = the same pen-write at low amplitude; the paradigm's hero waveform kicks fire at the same word onsets) and needs no front fx; plate: grain-only (no punch) is the demo register |
99
+ | `papermat` | STOP-MOTION PAPERCUT behind the subject: a torn-edge kraft mat (two seeded torn polygon layers) DROPS from above with steps(2) gravity and slaps down (squash → rest, soft blob shadow); then one torn cream chip per char (`palette.paper`/`paper2`, hero-font ink `palette.ink`) drops with steps(3) gravity + 1-frame overshoot at `I + i·params.step`, each announced by an anticipation shadow 3 frames early, landing crooked (seeded ±3° ±4px), settling through three 12fps poses, then holding an 8fps wobble (baked set chain — the stop-motion heartbeat) while the whole tableau breathes 1.6% (camera-push loom); scene reaction = a warm vignette (`params.vig`) charging with the landing; on the FINAL word the table BUMPS (y4, 1 frame) and the chips SCATTER off down-right steps(4) staggered 0.045s, the mat swept off last (disperse-on-last-word, `hero.exitAt` overrides) | chip geometry derives from `hero.fontPx` (demo ratios: tile 0.91×/1.31× fontPx, pitch tile+14, mat N·pitch+80 × 1.846× fontPx), width-fit shrinks type and chips together; pairs with `fx.paperscraps` (paper scraps puff at each chip contact, fg) and the `paperrail` paradigm (same place verb at low amplitude); plate: grain only is the demo register |
100
+ | `centerfold` | POP-UP BOOK CENTERFOLD behind the subject: blue + cream 12-point paper starbursts (deterministic starPts polygon, `palette.accent`/`cream` fills with kraft-edge strokes) unfold on a baseline hinge (scaleY 0.03→1 back.out(1.6), cream staggered +0.06) starting I−0.272 while a blob shadow grows beneath; the hero word pops up at I in `params.segs` hinged clip-path segments (rotationX 85→0 back.out(1.4) staggered `params.segStagger` — the body's popup verb at full amplitude); two kraft struts lean in at I+0.33; backdrop + word wobble-settle TOGETHER (one `#cfWob` wrapper owns rotationX, 6-key) then breathe through the hold (word 5-key rotationX + shadow scaleX, both auto-squeezed into the window); scene reaction = a dusk radial scrim at the hero's frame fractions (`params.scrim`, bright-sky insurance) charging with the unfold; exit = the whole spread folds FLAT (segments rotationX 88 staggered, struts/bursts scaleY collapse cream-then-blue, scrim out) at `max(I+segStagger·(segs−1)+0.45, min(heroOut−0.33, DUR−0.39))` — the book closes before the next sentence | burst geometry derives from the word rect (metric-exact via char-widths: burstR = clamp(1.83·fontPx, 0.59·wordW, 0.42·H), box 2R+180 × 2R+fontPx, demo props scale at burstR/220), width-fit shrinks the type first; pairs with `fx.confetti` (seeded ballistic paper confetti launched from the hinge line at I+0.128, fg) and the `popuprail` paradigm (same baseline-hinge verb at low amplitude); plate: grain only is the demo register |
101
+ | `chalkwrite` | NIGHT LECTURE behind the subject: the lower chalk band grows into a FULL deep-green board (scaleY 0→1 power3.out from the bottom edge at I−0.3, the room dims `params.dim` + vignette `params.vig` with it); the hero word is HAND-WRITTEN in chalk — sequential Hershey stroke reveal (drawon pattern, `gen-stroke-path.py` baked at compile time), dry/rough via seeded ±1px jitter on every pen point (`params.jitterSeed`), a blurred halo (`params.haloWidth`, feGaussianBlur 3.2, group opacity `params.halo`) under a tight core (`params.coreWidth`), a chalk-stick nib (rotated rect) riding the pen — while `params.dustN` dust specks fall from the nib along the path; at write-complete a hand-slap CLAP shakes the board 1 frame (set-chain y 3/−2/1/0; the dust burst lives in the rail, in FRONT: `fx.chalkclap`), then TWO violent accelerating underlines slash beneath (seeded waviness, power3.in, the nib rides them, dust kicks at the ends), the chalk flicks away, and the halo breathes (baked 1.6/3.7 Hz f(t)) through the hold with two slow motes drifting off the letters | geometry registers on the MEASURED ink box (the stroke path is parsed at compile time; ink CENTER lands on scene-aware HG.y, pref top 44): the board rect (`params.boardGap`×inkH above the ink, bottom flush with the frame, width = the body strip), the underlines (inkL+14→inkR−4 at inkBot+30/+50) and the fg clap point (the pen's LAST contact point → HG.clapX/Y/T) all derive from it; x defaults to the board's LEFT margin + tw/2 — a hand writes from the left, never centered on the subject (`theme.hero.x` overrides); pairs with `fx.chalkclap` (12 seeded radial dust specks + a blurred puff at DRAWN, fg) and the `chalkrail` paradigm (same scribble verb at low amplitude); plate: grain only is the demo register; needs `python3` |
102
+ | `spraytag` | STREET TAG behind the subject: the dusk wall dims (`params.dim`) + a radial scrim charges (`params.scrim`) at I−0.42 as the writer steps up; the can RATTLES at the pen-start point (6 seeded set-chain nib jitters, I−0.30→I−0.02), then the hero word is spray-written stroke by stroke — sequential Hershey dash reveal at constant pen speed (`gen-stroke-path.py` baked at compile time) — as a TRIPLE stack per stroke: fat dark under-stroke `palette.under` (`params.underWidth`, sky-contrast armor) + blurred overspray halo (`params.haloWidth`, feGaussianBlur 7, group opacity `params.haloOpacity`) + wet paint core (`params.coreWidth`, drop-shadow), the glowing nib (r9, `palette.nib`) riding each stroke; `params.osprayN` seeded overspray dots pop near the nib as it passes; nib throws off 2.6× at DRAWN; through the hold `params.drips` seeded DRIPS (paint→`dripMid`→`dripLo` gradient bars) grow from painted low points (x-separated >110px) and KEEP growing, the halo hums (7/11 Hz baked f(t)) and the whole tag looms 1.014; writing window = `params.window` (demo 0.58s) clamped so write + splat + drip fit before ENDT = DUR−0.04 | geometry registers on the MEASURED ink box (ink CENTER lands on scene-aware HG.y, pref top 26 — the sky band, crossing the subject silhouette is the point; tag centers on the hero anchor, `targetWidth` capped at W−140); the pen-finish point is baked onto HG.splatX/Y/T for the fg splat; pairs with `fx.paintsplat` (hot `em2` ring + paint ring + seeded ballistic droplets at DRAWN, fg, in FRONT of the subject) and the `markerrail` paradigm (same flick verb at low amplitude); plate: punch with `punchOffset` ≈ window+0.05 so the punch lands on the splat, not the hero onset; needs `python3` |
103
+ | `brushwrite` | SUMI-E GESTURE behind the subject: a warm paper wash (`palette.wash`/`wash2` radial, `targetWidth`+380 × `params.washH`) charges at I−0.18 to `params.wash`, settling to `params.washSettle` through the hold; the brush SLAPS down at the first pen point — a start-SPLAT (irregular ink ellipse rotated −24° + 5 seeded satellite dots, scale 0.35→1 power3.out 0.12s; the fg fleck pass rides `fx.brushflecks`) — then the hero word is written in ONE sequential gesture (Hershey dash reveal at constant pen speed, `gen-stroke-path.py` baked at compile time) as a FOUR-layer stack per stroke: blurred bleed (`params.bleedWidth`, feGaussianBlur 6, group hidden until the hold) under fat/mid/core widths (`fatWidth` 0.25 / `midWidth` 0.6 / `coreWidth` 1.0 stroke-opacity = pressure-tapered wet brush), the round ink nib (r7.5, `palette.nib`) riding the pen and flicking off (+42,−30, scale 1.9) at DRAWN; ≤`params.spatterN` spatter droplets eject PERPENDICULAR at the sharpest-curvature points of the gesture (angle-delta > 0.55 rad, te-separated > 0.045s); through the hold the ink BLEEDS into the paper (bleed group fades to `params.bleed` over ≤1.7s) and the whole work breathes 0.6% (`params.breatheHz` baked f(t), svgOrigin = ink center); then the vermilion SEAL chop (`params.sealGlyph`, `palette.seal`/`sealMid`/`sealLo` radial face, `fonts.seal` glyph) stamps at DRAWN+`params.sealDelay` — power4.in crush 0.09s → 2-frame squash → elastic settle + 3 seeded red flecks — skipped entirely if the clip ends too soon; writing window = `params.window` (demo 0.45s) clamped so write + seal + bleed fit before ENDT = DUR−0.04 | geometry registers on the MEASURED ink box (ink CENTER lands on scene-aware HG.y, pref top 19 — the sky band, crossing the subject silhouette is the point; gesture centers on the hero anchor, `targetWidth` capped at W−240 — on scenes with a dark object near the pen start, set `theme.hero.x` so the slap-down lands clear, like the demo's 864); the pen-START point is baked onto HG.fleckX/Y/T for the fg flecks and the seal sits at (inkR−103, inkBot+72) clamped on frame (`params.sealDx/sealDy` override); pairs with `fx.brushflecks` (seeded upward ballistic ink flecks at the slap-down, fg, in FRONT of the subject) and the `brushrail` paradigm (same brush-wipe verb at low amplitude); plate: punch with `punchOffset` ≈ window+`sealDelay` so the punch lands on the seal CONTACT, not the hero onset; needs `python3` |
104
+ | `ransomnote` | RANSOM NOTE slam behind the subject: one cutout chip per letter (4 recipes cycled, seeded ±13% sizes around `hero.fontPx`, alternating-sign rotations ±2–5°, misaligned baselines ±2–6px, seeded tear-polygon edges) slams in oversized (scale 1.5, rot×1.8, flight drop-shadow) at S_k = I + 0.01 + `params.step`·k, crushes power3.in over 0.085s, and on contact the shadow POPS tight (1-frame filter swap) → 2-frame squash 1.07/0.93 → elastic settle; when the LAST letter lands the whole word takes a collective 1-frame JOLT (y6 → power3.out) + a scene pulse (`params.pulse` full-frame dark blink); hold = slow 5-key loom (the crooked grid never straightens); exit = letters RIPPED off one by one (rot+±15–22° throw, y−34, fade, 1-frame tear flash under each) at ripT = min(lastWord − `params.ripLead`, DUR-clamped), ≥ jolt+0.45; scene reaction = collage scrim (`params.scrim` top-dark gradient) charges at I−0.07, out with the rip | width-fit measures each glyph IN ITS OWN recipe font (`assets/fonts/char-widths.json`) + 0.20em chip padding + 6px margins so the collage never overflows; chip chrome (shadows, space width) scales with fontPx from the 130px demo cut; the setpiece RECOMPUTES `plate.punchOffset` = 0.01 + step·(N−1) + crush from the real letter count so the plate punch always lands on the collective jolt, whatever the hero word length; pairs with the `ransomrail` paradigm (same paste verb + tear flashes at low amplitude, same recipe classes/seeded tear polygon emitted into both layers); no front fx — the flashes live inside the chips |
105
+ | `inkbloom` | INK DROP IN STILL WATER behind the subject: paper-white radial washes charge the two text zones (`palette.wash` rail wash from t≈0.15, PERSISTS to clip end so the closing body lines keep their ground — it registers on the body row geometry `body.bottomPx`/`rowGap`; `palette.washApex` apex wash at I−0.077, out with the bloom) and a gentle vignette (`params.vig`) STILLS the world while the ink blooms; the drop (ink teardrop, `params.fall` 0.15s) appears above the word point at I−0.08, swells, falls power2.in with a scaleY stretch, squashes 1.7/0.35 on contact (2 frames) and merges into the BLOOM — 3 stacked blurred irregular ink ellipses (`palette.ink`, opacity snaps 0.82/0.62/0.5 then decays) scaling at different rates with counter-rotations (expo.out 1.15/1.35/1.5s) + 2 thin concentric ripple rings expanding 7.2×/9.6× on the water surface; the hero words RESOLVE out of the blob (opacity snaps, blur 16→0 + scale 1.12→1 power2.out) — the FIRST at contact+0.02, the following at their own spoken times (multi-word hero, per-word hand-off); through the hold the glyph edges BREATHE (baked 5-key blur keyframes per word, alternating 0.66/0.5s), the group looms 1.018 and two faint ink wisps curl off the word top (C+0.573/C+0.753, fit-guarded); exit: RE-DISSOLVE (blur 11 + scale 1.15 + fade, 0.52s power1.in) at XOUT = min(I+`params.maxHold`, next body line − `params.clearGap`, DUR−0.6) — the ink clears before the next thought needs the reader | geometry derives from the measured word rect (`assets/fonts/char-widths.json`; kx = halfW/demoHalf, ky = fontPx/132 scale the demo's blob/ring/wisp anchors; pref top 25 — the sky band, crossing the subject silhouette is the point); dark `palette.ink` + its paper washes carry the contrast on bright skies; pairs with the `inkrail` paradigm (same bleed verb at low amplitude); plate: quiet `pushIn`, no punch — the bloom is liquid, not percussive |
106
+
107
+ Inline setpieces (`hero.inline: true`) live inside the body paradigm — the hero
108
+ word stays in `lines`. Embed setpieces own the word: leave it OUT of `lines`
109
+ (rail↔climax hand-off), except `panel` + `redact-until-hero`, where the words
110
+ appear in the log as `█████` until the decode locks.
111
+
112
+ A setpiece may additionally return `fgCss/fgHtml/fgJs` — those parts are merged
113
+ into the fg alpha page (rail.html), for furniture that must ride ABOVE the matte
114
+ (e.g. a verbatim chip that may never be occluded) while the setpiece scenery
115
+ stays embedded behind the subject.
116
+
117
+ ## Linkages
118
+
119
+ - `redact-until-hero` — panel log shows hero words as blocks; un-redacts at lock
120
+ - `corrupt-on-last-word` — panel jitters + hue-shifts on the final word
121
+ - `disperse-on-last-word` — every visible poem letter scatters back to dust
122
+ - `field-is-the-apex` — (lastpage) the blurred future-field rack-focuses at the
123
+ apex: every faint line was the apex word all along; the main instance holds,
124
+ the rest re-blur and die
125
+
126
+ ## Hard rules inherited (do not relax)
127
+
128
+ - determinism: paused GSAP on `window.__timelines["main"]`, seeded PRNG only,
129
+ set-chains / keyframes, no Math.random/Date.now/CSS-keyframes
130
+ - 80 ms word sync (timings come from transcript.json via the strict matcher;
131
+ any uncovered transcript word is a compile ERROR — verbatim completeness)
132
+ - apex owns the frame: fg furniture must avoid the setpiece rect or yield
133
+ (`body.yield`) during the hero window
134
+ - plate punch/shake ALWAYS post-composite (`_postfx.sh`) so subject + text +
135
+ plate move as one photographed frame (matte never desyncs)
136
+
137
+ ## SVG gotchas (paid for, do not rediscover)
138
+
139
+ - dash patterns restart on EVERY subpath → sequential per-stroke paths, never
140
+ one dashoffset across a multi-stroke word
141
+ - round linecap renders a DOT at dashoffset=len → hide each stroke until its turn
142
+ - inline-block trailing spaces collapse → word gaps via margin, not text spaces
143
+ - SVG-font glyph y is UP → flip when converting (gen-stroke-path.py does)
144
+ - NEVER gsap x/y/scale on raw SVG children: it runs `_parseTransform`/getBBox, and
145
+ zero-area shapes (fan-kit slivers) trip GSAP's bbox hack → `appendChild` on a
146
+ null docElement in injected-gsap contexts (preview-frames, renderer). Jitter
147
+ SVG pieces via `attr:{transform:"translate(...)"}` only; scale/loom belongs on
148
+ an HTML wrapper div. Nuance: a ROOT `<svg>` inside a div has null
149
+ ownerSVGElement → GSAP classifies it as HTML (CSS transforms, no getBBox), so
150
+ scale/skew on the svg root is safe — but copying that onto an inner `<g>`
151
+ becomes the fatal class. attr transforms can't TWEEN — use frame-quantized
152
+ step chains (identical on screen at 24fps)
153
+
154
+ ## Timeline ownership rules (audit-derived, do not relax)
155
+
156
+ - ONE owner per (target, property) at any instant. A duration tween re-renders
157
+ every tick until it ends — any set/tween on the same property inside that
158
+ window gets visually overwritten a frame later (1-frame ghosts, flash-backs).
159
+ Known shapes: yield dim vs line exit; yield restore vs powercut set-chain;
160
+ per-word line-y bounces with word gaps < 0.22s. The rail emitter guards these
161
+ (bounce ownership tracker, dim clamped ≥ line-in, restore only with ≥0.3s
162
+ runway before exit — else the line exits dimmed, by design).
163
+ - Inverted clamps: `Math.max(lo, Math.min(hi, x))` with lo > hi silently pins to
164
+ lo. When a lockup is wider than the frame, CENTER it (x = W/2) instead of
165
+ clamping — decorative bleed must be symmetric.
166
+ - The overflow gate only measures elements with direct text nodes — SVG-painted
167
+ setpieces (mask text + rects) are invisible to it. Do not read its "ok" as
168
+ proof for svg lockups; judge those on the preview frames.
169
+
170
+ ## theme.json — full schema
171
+
172
+ ```json
173
+ { "dna": "<themes/*.json name>", // required
174
+ "lines": [["word","word",...], ...], // required — verbatim transcript tokens, in order,
175
+ // INCLUDING punctuation ("size.", "noise.")
176
+ "minors": ["word", ...], // optional — theme's inline emphasis treatment
177
+ "hero": { "match": "word or phrase", // required — exact transcript tokens (case-insensitive,
178
+ // punctuation-stripped match); first occurrence wins
179
+ "text": "DISPLAY FORM", // optional display override
180
+ "out": 5.9, "exitAt": 3.3 }, // optional window overrides (seconds)
181
+ "width": 1280, "height": 720, // optional, default 1280x720 (theme DNAs are tuned
182
+ // for 16:9; vertical needs a DNA variant)
183
+ "fps": 24, // optional — matte.fps is AUTHORITATIVE when present
184
+ "panelHeader": "..." } // optional (panel paradigm)
185
+ ```
186
+
187
+ Scene awareness (inherited from the existing typography system): when
188
+ `safe-zones.json` is present the compiler re-anchors the hero setpiece to the
189
+ measured occlusion bands (`heroBands.profile`, 18–55% occlusion, closest to the
190
+ setpiece's preferred height) and `heroAnchor.centerXPct`, width-fits the hero
191
+ font to the actual word, and docks panel/poem furniture on
192
+ `subject.clearerSide`. Explicit `theme.json` values > scene auto > DNA fallback.
193
+
194
+ Expected (benign) log noise: `[Browser:REQUESTFAILED] GET source.mp4
195
+ net::ERR_ABORTED` during the fg-layer page load, reel-glyph overflow lint
196
+ lines, and `media_missing_data_start` — all cosmetic; the render is good if
197
+ render-theme.sh exits 0 and prints the gates summary.
198
+
199
+ ## Authoring a project (this is ALL a user writes)
200
+
201
+ `<project>/theme.json`:
202
+
203
+ ```json
204
+ {
205
+ "dna": "ordnance",
206
+ "lines": [
207
+ ["The", "stars", "were", "only", "limited"],
208
+ ["by", "the", "pixel", "size."],
209
+ ["It's"],
210
+ ["what", "you", "can", "actually"],
211
+ ["recover", "from", "the", "noise."]
212
+ ],
213
+ "minors": ["stars"],
214
+ "hero": { "match": "remarkable" }
215
+ }
216
+ ```
217
+
218
+ - `lines` follow the transcript verbatim, in order (compile error otherwise);
219
+ every transcript word must be covered by `lines` ∪ `hero.match` — the example
220
+ above omits "remarkable" from `lines` precisely because `hero.match` covers it
221
+ (it slots between `["It's"]` and `["what",...]`)
222
+ - leave the hero word(s) out of `lines` for embed setpieces; keep them for
223
+ inline setpieces and for panel+redact
224
+ - `takeover`: each line is one CARD — group by beat (1–2 words), not subtitle
225
+ length; `panel` scrolls automatically past ~5 lines (terminal scroll)
226
+ - the ordnance "charge" is an edge vignette + rail yield (the center stays
227
+ clean by design) — judge it at the frame corners, not the center
228
+ - `minors`: words that get the theme's inline emphasis treatment
229
+ - preview first: `node scripts/make-theme.cjs <project>` then
230
+ `node scripts/preview-frames.cjs <project> <t1> <t2> ...` (Visual QA)
231
+ - then: `bash scripts/render-theme.sh <project>` → **`final_fx.mp4`** (the
232
+ deliverable; `final.mp4` is pre-plate-reaction)
233
+
234
+ Prereqs identical to other modes — `prepare.sh` outputs: transcript.json,
235
+ frames_fg/, matte.fps, safe-zones.json (scene awareness), source.mp4.
236
+ frames_bg/ is only needed by preview-frames.cjs, not by the render.
237
+
238
+ ## Adding a theme DNA
239
+
240
+ Copy a `themes/*.json`, change identity fields. You may ONLY combine existing
241
+ paradigm/setpiece/linkage names — if the look you want needs a new mechanism,
242
+ that is a registry contribution (this file + make-theme.cjs), reviewed like an
243
+ engine change. A DNA that needs per-word visual tuning to ship is rejected:
244
+ **any input, zero hand-fixing** is the acceptance bar (the draw-on lesson).
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "anchor",
3
+ "voice": "the quiet professional — a verbatim rail that simply reads (2-frame fade-ups, accent emphasis), and one climax that settles into the scene behind the subject with a drawn accent underline. No spectacle: discipline IS the style. This is the conservative default that replaced Standard mode.",
4
+ "when": "explainers, tutorials, product walkthroughs, corporate and news-adjacent clips — anywhere every word must be read and nothing should show off. Pick it when unsure.",
5
+ "register": "calm",
6
+ "fonts": { "body": "Sora", "hero": "Sora", "tag": "Sora" },
7
+ "palette": { "body": "#F2EFE9", "accent": "#D9B98C", "em": "#EFCB9A" },
8
+ "body": {
9
+ "paradigm": "rail",
10
+ "layer": "fg",
11
+ "fontPx": 46,
12
+ "bottomPx": 96,
13
+ "letterSpacing": "0.012em",
14
+ "entrance": "fade",
15
+ "exit": "fade",
16
+ "minorScale": 1.0,
17
+ "yield": { "dim": 0.55, "pre": 0.2, "post": 0.9 }
18
+ },
19
+ "hero": {
20
+ "setpiece": "settle",
21
+ "layer": "bg",
22
+ "fontPx": 150,
23
+ "params": {}
24
+ },
25
+ "plate": { "dim": 0.16, "pushIn": 0.012, "grain": 5 },
26
+ "linkages": []
27
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "arcade",
3
+ "voice": "8-bit cabinet attract mode — the whole frame plays through a CRT (scanlines + vignette) above a bordered HUD bar (1UP blinking on the classic cadence, CREDIT 01) where every word coin-pops in on steps(2) with a 1-frame white blip; emphasis words run a cyan→magenta palette swap. The apex is a BOSS INTRO behind the subject: the room dims, WARNING blinks twice, ~64 seeded pixel blocks fall quantized into a matrix grid over the word rect, then the word flashes ON in Press Start 2P with chromatic ghost layers + a 3-frame palette strobe while letterbox bars slam in and a HI-SCORE odometer rolls top-right; everything dissolves checkerboard and the blocks drop away.",
4
+ "when": "gaming, retro-tech, playful hype, launches, achievement/level-up beats, '像素/街机/8-bit/打游戏' asks — anything that should read as an arcade cabinet boss fight. Loud register; the boss dim + dark HUD bar bring their own contrast on bright skies.",
5
+ "register": "loud",
6
+ "fonts": { "body": "Press Start 2P", "hero": "Press Start 2P", "tag": "Press Start 2P" },
7
+ "palette": {
8
+ "body": "#FFFFFF",
9
+ "accent": "#00E5FF",
10
+ "magenta": "#FF2E88",
11
+ "yellow": "#FFE600",
12
+ "credit": "#7ADCFF"
13
+ },
14
+ "body": {
15
+ "paradigm": "hudrail",
16
+ "layer": "fg",
17
+ "fontPx": 26,
18
+ "bar": { "h": 70, "inset": 24, "bottom": 50 },
19
+ "tags": { "left": "1UP", "right": "CREDIT 01" },
20
+ "scan": 0.06,
21
+ "textTransform": "uppercase",
22
+ "yield": { "dim": 0.55, "pre": 0.09, "post": 1.04 }
23
+ },
24
+ "hero": {
25
+ "setpiece": "bossintro",
26
+ "layer": "bg",
27
+ "fontPx": 84,
28
+ "params": {
29
+ "seed": 13013,
30
+ "rows": 4,
31
+ "tag": "WARNING",
32
+ "flashDelay": 0.14,
33
+ "hold": 1.24,
34
+ "letterbox": 44
35
+ }
36
+ },
37
+ "fx": { "coinflash": 0.55 },
38
+ "plate": {
39
+ "dim": 0.58,
40
+ "punch": 0.04,
41
+ "punchDecay": 9,
42
+ "punchOffset": 0.14,
43
+ "shakeAmpX": 7,
44
+ "shakeAmpY": 5,
45
+ "shakeHz": 12,
46
+ "shakeDecay": 7,
47
+ "shakeWindow": 0.6,
48
+ "grain": 6
49
+ },
50
+ "linkages": []
51
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "aurora",
3
+ "voice": "polar-night elegance — the sky is alive and every caption is woven light. Two huge aurora blobs drift the top of frame all clip; body words are silk serif ink whose rose→teal→violet sheen drifts continuously through the letters (emphasis words get one bright highlight sweep), lines share two coexisting rows like a woven couplet and dissolve UPWARD into drifting light streaks. The apex is a SILK RIBBON: the hero word is hand-WRITTEN into the sky behind the subject stroke by stroke (single-line script font, blurred halo + bright core, a light mote riding the pen) — and the signature: the aurora gradient keeps FLOWING through the drawn ribbon during the hold while a soft spill tints the sky and light motes rise past the subject. Gentle — no shake.",
4
+ "when": "dreamy / romantic / wonder content, night-sky and travel pieces, poetry, weddings, elegant brand films, '极光/丝带/优雅手写字幕' asks — anything that should feel written by light rather than printed. Soft register; the apex scrim + dark understroke carry contrast on bright skies.",
5
+ "register": "elegant",
6
+ "fonts": { "body": "Cormorant Garamond", "strokeFont": "HersheyScript1.svg" },
7
+ "palette": {
8
+ "body": "#F2EFF7",
9
+ "rose": "#FF9EC4",
10
+ "accent": "#7FE0D4",
11
+ "violet": "#B9A8FF",
12
+ "deep": "#070C24"
13
+ },
14
+ "body": {
15
+ "paradigm": "sheenrail",
16
+ "layer": "fg",
17
+ "fontPx": 48,
18
+ "bottomPx": 76,
19
+ "rowDy": 58,
20
+ "band": { "w": 860, "h": 170 },
21
+ "streaks": 4,
22
+ "seed": 20260611,
23
+ "yield": { "dim": 0.5, "pre": 0.16, "post": 0.62 }
24
+ },
25
+ "hero": {
26
+ "setpiece": "silkribbon",
27
+ "layer": "bg",
28
+ "params": {
29
+ "targetWidth": 880,
30
+ "window": 0.68,
31
+ "haloWidth": 18,
32
+ "coreWidth": 6,
33
+ "wash": 0.12,
34
+ "deepen": 0.2,
35
+ "spill": 0.3
36
+ }
37
+ },
38
+ "fx": { "silkmotes": 6, "seed": 20260612 },
39
+ "plate": { "scrim": 0.72, "pushIn": 0.012, "grain": 5 },
40
+ "linkages": []
41
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "biolume",
3
+ "voice": "deep-sea bioluminescence — the clip sinks into an abyss grade with a breathing vignette and every caption is a living light. Body words GLOW ON like jellyfish (2-frame opacity + radial bloom from center while a cyan glow breathes in), emphasis words pulse a slow double-beat (propulsion), lines float on a gentle drift across two coexisting rows and SINK away dimming; seeded plankton motes drift the open water and the ones ringing the apex get pulled into the bloom. The apex is a bioluminescent BLOOM behind the subject: a creature pre-glow double-beats and crushes to a point, the word condenses in, six luminous tendrils draw outward like filaments while caustics shimmer and cyan light spills onto the scene — then all the light sinks back into the deep.",
4
+ "when": "ocean / nature / science-wonder docs, dreamy or meditative monologues, slow night-time reveals, 'underwater / 深海 / 发光水母' asks — anything that should feel alive and submerged rather than printed. Soft register; the abyss grade + pocket scrim make their own contrast on bright scenes.",
5
+ "register": "dreamy",
6
+ "fonts": { "body": "Fredoka", "hero": "Fredoka", "tag": "Fredoka" },
7
+ "palette": {
8
+ "body": "#E9FFFA",
9
+ "accent": "#6DF2E0",
10
+ "violet": "#9D7BFF",
11
+ "ice": "#8FE8FF",
12
+ "core": "#F2FFFD",
13
+ "em": "#F4FFFD",
14
+ "mote": "#96F5E8",
15
+ "spore": "#BDFFF4"
16
+ },
17
+ "body": {
18
+ "paradigm": "planktonrail",
19
+ "layer": "fg",
20
+ "fontPx": 44,
21
+ "bottomPx": 70,
22
+ "rowDy": 58,
23
+ "motes": { "count": 12, "near": 5, "seed": 2929 },
24
+ "yield": { "dim": 0.55, "pre": 0.17, "enter": 0.8, "post": 0.63 }
25
+ },
26
+ "hero": {
27
+ "setpiece": "biobloom",
28
+ "layer": "bg",
29
+ "fontPx": 120,
30
+ "params": { "crush": 0.11, "drift": -30, "mood": 0.92 }
31
+ },
32
+ "fx": { "sporeburst": 7, "seed": 2930 },
33
+ "plate": { "scrim": 0.55, "pushIn": 0.012, "grain": 5 },
34
+ "linkages": []
35
+ }