dsh-hyperframes 0.3.2 → 0.4.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 (375) hide show
  1. package/README.en.md +4 -3
  2. package/README.md +5 -4
  3. package/lib/index.d.ts +1 -1
  4. package/lib/index.js +1 -0
  5. package/package.json +2 -2
  6. package/skills/embedded-captions/SKILL.md +28 -3
  7. package/skills/embedded-captions/references/aesthetic-principles.md +2 -3
  8. package/skills/embedded-captions/references/rail.md +1 -1
  9. package/skills/embedded-captions/scripts/check-occlusion.cjs +4 -1
  10. package/skills/embedded-captions/scripts/check-overflow.cjs +1 -0
  11. package/skills/embedded-captions/scripts/check-rail-climax.cjs +5 -1
  12. package/skills/embedded-captions/scripts/fixtures/heroless/theme.json +11 -0
  13. package/skills/embedded-captions/scripts/hf-cli.cjs +33 -0
  14. package/skills/embedded-captions/scripts/make-theme.cjs +95 -57
  15. package/skills/embedded-captions/scripts/make-theme.test.mjs +131 -0
  16. package/skills/embedded-captions/scripts/matte.cjs +1 -13
  17. package/skills/embedded-captions/scripts/measure-layout.cjs +2 -1
  18. package/skills/embedded-captions/scripts/preview-frames.cjs +39 -11
  19. package/skills/embedded-captions/scripts/preview-frames.test.mjs +24 -0
  20. package/skills/embedded-captions/scripts/render-and-composite.sh +8 -52
  21. package/skills/embedded-captions/scripts/safe-zones.cjs +4 -1
  22. package/skills/embedded-captions/scripts/transcribe.cjs +5 -14
  23. package/skills/embedded-captions/scripts/transcribe.test.mjs +41 -0
  24. package/skills/faceless-explainer/SKILL.md +20 -16
  25. package/skills/faceless-explainer/references/story-design.md +1 -1
  26. package/skills/faceless-explainer/scripts/assemble-index.mjs +6 -4
  27. package/skills/faceless-explainer/scripts/assemble-index.test.mjs +57 -2
  28. package/skills/faceless-explainer/scripts/audio.mjs +2 -0
  29. package/skills/faceless-explainer/scripts/build-frame.mjs +6 -3
  30. package/skills/faceless-explainer/scripts/captions.mjs +7 -4
  31. package/skills/faceless-explainer/scripts/frame-packets.mjs +4 -4
  32. package/skills/faceless-explainer/scripts/lib/bgm-volume.mjs +4 -0
  33. package/skills/faceless-explainer/scripts/lib/captured-fonts.mjs +58 -0
  34. package/skills/{hyperframes-core → faceless-explainer}/scripts/lib/frame-packets-core.mjs +5 -23
  35. package/skills/faceless-explainer/scripts/lib/storyboard.mjs +1 -1
  36. package/skills/faceless-explainer/scripts/lib/transitions.json +3 -3
  37. package/skills/faceless-explainer/scripts/transitions.mjs +1 -0
  38. package/skills/faceless-explainer/scripts/transitions.test.mjs +2 -0
  39. package/skills/faceless-explainer/sub-agents/frame-worker.md +1 -1
  40. package/skills/figma/SKILL.md +2 -0
  41. package/skills/general-video/SKILL.md +13 -11
  42. package/skills/general-video/scripts/frame-packets.mjs +4 -4
  43. package/skills/general-video/scripts/lib/frame-packets-core.mjs +194 -0
  44. package/skills/general-video/sub-agents/frame-worker.md +1 -1
  45. package/skills/hyperframes/SKILL.md +40 -30
  46. package/skills/{hyperframes-core → hyperframes}/references/brief-contract.md +15 -15
  47. package/skills/{hyperframes-core → hyperframes}/references/brief-format.md +8 -8
  48. package/skills/hyperframes/references/capability-menu.md +2 -2
  49. package/skills/{hyperframes-core → hyperframes}/references/frame-worker-core.md +1 -1
  50. package/skills/hyperframes/references/intent-interview.md +16 -16
  51. package/skills/hyperframes/references/plugin-installation.md +43 -0
  52. package/skills/{hyperframes-core → hyperframes}/references/production-loop.md +11 -11
  53. package/skills/hyperframes/references/review-loop.md +37 -0
  54. package/skills/hyperframes/references/route-briefs.md +1 -1
  55. package/skills/hyperframes/references/routes/motion-graphics.md +1 -1
  56. package/skills/{hyperframes-core → hyperframes}/references/script-format.md +3 -3
  57. package/skills/hyperframes/references/skill-lifecycle.md +2 -0
  58. package/skills/{hyperframes-core → hyperframes}/references/storyboard-format.md +3 -34
  59. package/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
  60. package/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
  61. package/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
  62. package/skills/hyperframes-animation/SKILL.md +5 -1
  63. package/skills/hyperframes-animation/adapters/gsap.md +1 -1
  64. package/skills/hyperframes-animation/adapters/lottie.md +15 -2
  65. package/skills/hyperframes-animation/adapters/three.md +14 -0
  66. package/skills/hyperframes-animation/blueprints/titlecard-reveal.md +1 -1
  67. package/skills/hyperframes-animation/references/motion-blur.md +133 -0
  68. package/skills/hyperframes-animation/rules/cursor-click-ripple.md +1 -1
  69. package/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +1 -1
  70. package/skills/hyperframes-animation/rules/hacker-flip-3d.md +1 -1
  71. package/skills/hyperframes-animation/rules/kinetic-beat-slam.md +2 -2
  72. package/skills/hyperframes-animation/rules/motion-blur-streak.md +1 -1
  73. package/skills/hyperframes-animation/rules/vertical-spring-ticker.md +1 -1
  74. package/skills/hyperframes-animation/scripts/package-loader.mjs +47 -16
  75. package/skills/hyperframes-animation/scripts/package-loader.test.mjs +52 -0
  76. package/skills/hyperframes-animation/techniques.md +1 -1
  77. package/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +3 -3
  78. package/skills/hyperframes-animation/transitions/css-push.md +4 -4
  79. package/skills/hyperframes-audio/SKILL.md +30 -22
  80. package/skills/hyperframes-audio/scripts/carve.mjs +6 -3
  81. package/skills/hyperframes-audio/scripts/carve.test.mjs +16 -1
  82. package/skills/hyperframes-cli/SKILL.md +44 -35
  83. package/skills/hyperframes-cli/references/init-and-scaffold.md +8 -6
  84. package/skills/hyperframes-cli/references/lint-validate-inspect.md +3 -3
  85. package/skills/hyperframes-cli/references/preview-render.md +35 -32
  86. package/skills/hyperframes-cli/references/upgrade-info-misc.md +50 -1
  87. package/skills/hyperframes-core/SKILL.md +30 -24
  88. package/skills/hyperframes-core/references/composition-patterns.md +3 -42
  89. package/skills/hyperframes-core/references/creator-editing-recipes.md +131 -7
  90. package/skills/hyperframes-core/references/data-attributes.md +11 -11
  91. package/skills/hyperframes-core/references/determinism-rules.md +2 -19
  92. package/skills/hyperframes-core/references/full-screen-motion.md +0 -9
  93. package/skills/hyperframes-core/references/minimal-composition.md +2 -2
  94. package/skills/hyperframes-core/references/sub-compositions.md +3 -66
  95. package/skills/hyperframes-core/references/tailwind.md +1 -20
  96. package/skills/hyperframes-core/references/tracks-and-clips.md +2 -6
  97. package/skills/hyperframes-core/references/variables-and-media.md +3 -3
  98. package/skills/hyperframes-creative/SKILL.md +2 -0
  99. package/skills/hyperframes-creative/references/house-style.md +15 -15
  100. package/skills/hyperframes-creative/references/story-spine.md +3 -1
  101. package/skills/hyperframes-creative/references/storyboard-recipe.md +57 -0
  102. package/skills/hyperframes-creative/references/typography.md +1 -1
  103. package/skills/hyperframes-creative/scripts/package-loader.mjs +47 -16
  104. package/skills/hyperframes-creative/scripts/package-loader.test.mjs +52 -0
  105. package/skills/hyperframes-keyframes/SKILL.md +4 -2
  106. package/skills/hyperframes-registry/SKILL.md +3 -1
  107. package/skills/hyperframes-registry/references/contributing.md +8 -2
  108. package/skills/hyperframes-registry/references/discovery.md +20 -34
  109. package/skills/hyperframes-studio/SKILL.md +77 -0
  110. package/skills/media-use/SKILL.md +14 -12
  111. package/skills/media-use/audio/references/captions/authoring.md +4 -0
  112. package/skills/media-use/audio/references/remove-background.md +1 -1
  113. package/skills/media-use/audio/references/tts-to-captions.md +11 -2
  114. package/skills/media-use/audio/references/tts.md +84 -6
  115. package/skills/media-use/audio/scripts/audio.mjs +15 -6
  116. package/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +113 -0
  117. package/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
  118. package/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
  119. package/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
  120. package/skills/media-use/audio/scripts/lib/bgm.mjs +2 -6
  121. package/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
  122. package/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
  123. package/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
  124. package/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
  125. package/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
  126. package/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
  127. package/skills/media-use/audio/scripts/lib/heygen.mjs +2 -1
  128. package/skills/media-use/audio/scripts/lib/tts.mjs +15 -3
  129. package/skills/media-use/audio/scripts/wait-bgm.mjs +8 -4
  130. package/skills/media-use/audio/scripts/wait-bgm.test.mjs +65 -0
  131. package/skills/media-use/references/audio.md +3 -2
  132. package/skills/media-use/references/grading.md +7 -7
  133. package/skills/media-use/references/media-treatment-recipes.md +1 -1
  134. package/skills/media-use/references/memory.md +2 -2
  135. package/skills/media-use/references/meta.md +2 -2
  136. package/skills/media-use/references/operations.md +15 -13
  137. package/skills/media-use/references/resolve.md +22 -11
  138. package/skills/media-use/references/setup-providers.md +11 -11
  139. package/skills/media-use/scripts/audio-duck.mjs +19 -27
  140. package/skills/media-use/scripts/compatibility.test.mjs +96 -0
  141. package/skills/media-use/scripts/lib/config-lock.mjs +45 -0
  142. package/skills/media-use/scripts/lib/duck.mjs +16 -10
  143. package/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
  144. package/skills/media-use/scripts/lib/media-home.mjs +20 -0
  145. package/skills/media-use/scripts/lib/npx-sync.mjs +28 -2
  146. package/skills/media-use/scripts/lib/prefs-store.mjs +2 -2
  147. package/skills/media-use/scripts/lib/recipe-store.mjs +2 -2
  148. package/skills/media-use/scripts/lib/telemetry.mjs +29 -41
  149. package/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
  150. package/skills/media-use/scripts/prefs.mjs +1 -1
  151. package/skills/media-use/scripts/recipe.mjs +1 -1
  152. package/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
  153. package/skills/media-use/scripts/resolve.mjs +27 -1267
  154. package/skills/media-use/scripts/transcribe.mjs +39 -25
  155. package/skills/media-use/scripts/transcribe.test.mjs +112 -0
  156. package/skills/media-use/scripts/transcript-cut.mjs +39 -8
  157. package/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
  158. package/skills/motion-graphics/SKILL.md +3 -1
  159. package/skills/motion-graphics/agents/builder.md +1 -0
  160. package/skills/motion-graphics/agents/director.md +2 -1
  161. package/skills/motion-graphics/catalog-map.md +25 -13
  162. package/skills/motion-graphics/categories/charts/module.md +2 -1
  163. package/skills/motion-graphics/categories/lower-thirds/module.md +4 -0
  164. package/skills/motion-graphics/categories/news/module.md +1 -1
  165. package/skills/motion-graphics/references/motion-vocabulary.md +4 -0
  166. package/skills/music-to-video/SKILL.md +8 -6
  167. package/skills/music-to-video/references/montage.md +3 -6
  168. package/skills/music-to-video/references/motion-primitives/3d-card-flip/index.html +10 -111
  169. package/skills/music-to-video/references/motion-primitives/3d-card-flip/scene.html +119 -0
  170. package/skills/music-to-video/references/motion-primitives/bg-flow-field/index.html +11 -284
  171. package/skills/music-to-video/references/motion-primitives/bg-flow-field/scene.html +294 -0
  172. package/skills/music-to-video/references/motion-primitives/binary-decrypt/index.html +10 -76
  173. package/skills/music-to-video/references/motion-primitives/binary-decrypt/scene.html +85 -0
  174. package/skills/music-to-video/references/motion-primitives/blur-resolve/index.html +10 -52
  175. package/skills/music-to-video/references/motion-primitives/blur-resolve/scene.html +60 -0
  176. package/skills/music-to-video/references/motion-primitives/braam-punch/index.html +10 -92
  177. package/skills/music-to-video/references/motion-primitives/braam-punch/scene.html +100 -0
  178. package/skills/music-to-video/references/motion-primitives/chromatic-split/index.html +10 -103
  179. package/skills/music-to-video/references/motion-primitives/chromatic-split/scene.html +111 -0
  180. package/skills/music-to-video/references/motion-primitives/chrome-sweep/index.html +10 -60
  181. package/skills/music-to-video/references/motion-primitives/chrome-sweep/scene.html +68 -0
  182. package/skills/music-to-video/references/motion-primitives/counting-punch/index.html +10 -110
  183. package/skills/music-to-video/references/motion-primitives/counting-punch/scene.html +119 -0
  184. package/skills/music-to-video/references/motion-primitives/crash-zoom-in/index.html +10 -112
  185. package/skills/music-to-video/references/motion-primitives/crash-zoom-in/scene.html +120 -0
  186. package/skills/music-to-video/references/motion-primitives/datamosh-smear/index.html +10 -121
  187. package/skills/music-to-video/references/motion-primitives/datamosh-smear/scene.html +131 -0
  188. package/skills/music-to-video/references/motion-primitives/directional-fill/index.html +10 -90
  189. package/skills/music-to-video/references/motion-primitives/directional-fill/scene.html +103 -0
  190. package/skills/music-to-video/references/motion-primitives/dolly-zoom/index.html +10 -94
  191. package/skills/music-to-video/references/motion-primitives/dolly-zoom/scene.html +102 -0
  192. package/skills/music-to-video/references/motion-primitives/electric-arc/index.html +10 -100
  193. package/skills/music-to-video/references/motion-primitives/electric-arc/scene.html +105 -0
  194. package/skills/music-to-video/references/motion-primitives/flash-cut/index.html +10 -89
  195. package/skills/music-to-video/references/motion-primitives/flash-cut/scene.html +97 -0
  196. package/skills/music-to-video/references/motion-primitives/gooey-metaball/index.html +10 -197
  197. package/skills/music-to-video/references/motion-primitives/gooey-metaball/scene.html +206 -0
  198. package/skills/music-to-video/references/motion-primitives/hard-cut/index.html +10 -74
  199. package/skills/music-to-video/references/motion-primitives/hard-cut/scene.html +82 -0
  200. package/skills/music-to-video/references/motion-primitives/hypercut-whip/index.html +10 -36
  201. package/skills/music-to-video/references/motion-primitives/hypercut-whip/scene.html +44 -0
  202. package/skills/music-to-video/references/motion-primitives/iris-open/index.html +10 -61
  203. package/skills/music-to-video/references/motion-primitives/iris-open/scene.html +69 -0
  204. package/skills/music-to-video/references/motion-primitives/kinetic-letter-in/index.html +10 -55
  205. package/skills/music-to-video/references/motion-primitives/kinetic-letter-in/scene.html +64 -0
  206. package/skills/music-to-video/references/motion-primitives/liquid-morph/index.html +10 -88
  207. package/skills/music-to-video/references/motion-primitives/liquid-morph/scene.html +96 -0
  208. package/skills/music-to-video/references/motion-primitives/mask-reveal/index.html +10 -66
  209. package/skills/music-to-video/references/motion-primitives/mask-reveal/scene.html +74 -0
  210. package/skills/music-to-video/references/motion-primitives/mosaic-pack/index.html +10 -81
  211. package/skills/music-to-video/references/motion-primitives/mosaic-pack/scene.html +89 -0
  212. package/skills/music-to-video/references/motion-primitives/neon-flicker/index.html +10 -65
  213. package/skills/music-to-video/references/motion-primitives/neon-flicker/scene.html +73 -0
  214. package/skills/music-to-video/references/motion-primitives/outline-to-fill/index.html +10 -74
  215. package/skills/music-to-video/references/motion-primitives/outline-to-fill/scene.html +82 -0
  216. package/skills/music-to-video/references/motion-primitives/palette-flip/index.html +10 -89
  217. package/skills/music-to-video/references/motion-primitives/palette-flip/scene.html +97 -0
  218. package/skills/music-to-video/references/motion-primitives/particle-burst/index.html +10 -98
  219. package/skills/music-to-video/references/motion-primitives/particle-burst/scene.html +106 -0
  220. package/skills/music-to-video/references/motion-primitives/pixel-dissolve/index.html +10 -78
  221. package/skills/music-to-video/references/motion-primitives/pixel-dissolve/scene.html +86 -0
  222. package/skills/music-to-video/references/motion-primitives/radial-burst-lines/index.html +10 -117
  223. package/skills/music-to-video/references/motion-primitives/radial-burst-lines/scene.html +130 -0
  224. package/skills/music-to-video/references/motion-primitives/screen-shake/index.html +10 -70
  225. package/skills/music-to-video/references/motion-primitives/screen-shake/scene.html +78 -0
  226. package/skills/music-to-video/references/motion-primitives/slot-machine-reveal/index.html +10 -87
  227. package/skills/music-to-video/references/motion-primitives/slot-machine-reveal/scene.html +100 -0
  228. package/skills/music-to-video/references/motion-primitives/spotlight-sweep/index.html +10 -94
  229. package/skills/music-to-video/references/motion-primitives/spotlight-sweep/scene.html +102 -0
  230. package/skills/music-to-video/references/motion-primitives/staggered-exit/index.html +10 -74
  231. package/skills/music-to-video/references/motion-primitives/staggered-exit/scene.html +82 -0
  232. package/skills/music-to-video/references/motion-primitives/text-spectral-rays/index.html +11 -271
  233. package/skills/music-to-video/references/motion-primitives/text-spectral-rays/scene.html +280 -0
  234. package/skills/music-to-video/references/motion-primitives/text-wave-distort/index.html +10 -92
  235. package/skills/music-to-video/references/motion-primitives/text-wave-distort/scene.html +106 -0
  236. package/skills/music-to-video/references/motion-primitives/tile-mosaic/index.html +10 -101
  237. package/skills/music-to-video/references/motion-primitives/tile-mosaic/scene.html +109 -0
  238. package/skills/music-to-video/references/motion-primitives/typewriter-reveal/index.html +10 -79
  239. package/skills/music-to-video/references/motion-primitives/typewriter-reveal/scene.html +91 -0
  240. package/skills/music-to-video/references/motion-primitives/word-grid-burst/index.html +10 -83
  241. package/skills/music-to-video/references/motion-primitives/word-grid-burst/scene.html +96 -0
  242. package/skills/music-to-video/references/planning.md +2 -2
  243. package/skills/music-to-video/scripts/lib/storyboard.mjs +1 -1
  244. package/skills/music-to-video/sub-agents/frame-worker.md +2 -2
  245. package/skills/pr-to-video/SKILL.md +20 -16
  246. package/skills/pr-to-video/references/code-vocabulary.md +14 -12
  247. package/skills/pr-to-video/references/story-design.md +1 -1
  248. package/skills/pr-to-video/scripts/assemble-index.mjs +6 -4
  249. package/skills/pr-to-video/scripts/assemble-index.test.mjs +57 -2
  250. package/skills/pr-to-video/scripts/audio.mjs +2 -0
  251. package/skills/pr-to-video/scripts/build-frame.mjs +6 -3
  252. package/skills/pr-to-video/scripts/captions.mjs +7 -4
  253. package/skills/pr-to-video/scripts/captions.test.mjs +41 -0
  254. package/skills/pr-to-video/scripts/frame-packets.mjs +4 -4
  255. package/skills/pr-to-video/scripts/lib/bgm-volume.mjs +4 -0
  256. package/skills/pr-to-video/scripts/lib/captured-fonts.mjs +58 -0
  257. package/skills/pr-to-video/scripts/lib/frame-packets-core.mjs +194 -0
  258. package/skills/pr-to-video/scripts/lib/storyboard.mjs +1 -1
  259. package/skills/pr-to-video/scripts/lib/transitions.json +3 -3
  260. package/skills/pr-to-video/scripts/transitions.mjs +7 -5
  261. package/skills/pr-to-video/sub-agents/frame-worker.md +1 -1
  262. package/skills/product-launch-video/SKILL.md +20 -16
  263. package/skills/product-launch-video/references/story-design.md +1 -1
  264. package/skills/product-launch-video/scripts/assemble-index.mjs +6 -4
  265. package/skills/product-launch-video/scripts/assemble-index.test.mjs +57 -2
  266. package/skills/product-launch-video/scripts/audio.mjs +2 -0
  267. package/skills/product-launch-video/scripts/audio.test.mjs +16 -0
  268. package/skills/product-launch-video/scripts/build-frame-subsets.test.mjs +152 -0
  269. package/skills/product-launch-video/scripts/build-frame.mjs +6 -3
  270. package/skills/product-launch-video/scripts/captions.mjs +7 -4
  271. package/skills/product-launch-video/scripts/frame-packets.mjs +4 -4
  272. package/skills/product-launch-video/scripts/lib/bgm-volume.mjs +4 -0
  273. package/skills/product-launch-video/scripts/lib/captured-fonts.mjs +58 -0
  274. package/skills/product-launch-video/scripts/lib/frame-packets-core.mjs +194 -0
  275. package/skills/product-launch-video/scripts/lib/storyboard.mjs +1 -1
  276. package/skills/product-launch-video/scripts/lib/transitions.json +3 -3
  277. package/skills/product-launch-video/scripts/transitions.mjs +7 -5
  278. package/skills/product-launch-video/scripts/transitions.test.mjs +68 -0
  279. package/skills/product-launch-video/sub-agents/frame-worker.md +1 -1
  280. package/skills/remotion-to-hyperframes/SKILL.md +7 -4
  281. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +5 -5
  282. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/compositions/title.html +31 -0
  283. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +10 -25
  284. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +8 -8
  285. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +9 -9
  286. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-1.html +35 -0
  287. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-2.html +35 -0
  288. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-3.html +36 -0
  289. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +28 -71
  290. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +3 -3
  291. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-1.html +52 -0
  292. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-2.html +99 -0
  293. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-3.html +55 -0
  294. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +13 -212
  295. package/skills/remotion-to-hyperframes/references/api-map.md +16 -16
  296. package/skills/remotion-to-hyperframes/references/limitations.md +7 -7
  297. package/skills/remotion-to-hyperframes/references/lottie.md +5 -7
  298. package/skills/remotion-to-hyperframes/references/media.md +3 -3
  299. package/skills/remotion-to-hyperframes/references/parameters.md +5 -0
  300. package/skills/remotion-to-hyperframes/references/sequencing.md +71 -18
  301. package/skills/slideshow/SKILL.md +4 -1
  302. package/skills/slideshow/references/standalone-harness.md +0 -3
  303. package/skills/talking-head-recut/SKILL.md +10 -1
  304. package/skills/hyperframes-core/references/review-loop.md +0 -41
  305. package/skills/media-use/scripts/lib/adopt.mjs +0 -128
  306. package/skills/media-use/scripts/lib/adopt.test.mjs +0 -95
  307. package/skills/media-use/scripts/lib/bgm-provider.mjs +0 -20
  308. package/skills/media-use/scripts/lib/brand-provider.mjs +0 -59
  309. package/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +0 -108
  310. package/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +0 -85
  311. package/skills/media-use/scripts/lib/cache.mjs +0 -150
  312. package/skills/media-use/scripts/lib/candidates.mjs +0 -91
  313. package/skills/media-use/scripts/lib/candidates.test.mjs +0 -155
  314. package/skills/media-use/scripts/lib/codex-provider.mjs +0 -161
  315. package/skills/media-use/scripts/lib/codex-provider.test.mjs +0 -34
  316. package/skills/media-use/scripts/lib/coverage.test.mjs +0 -117
  317. package/skills/media-use/scripts/lib/cube-build.mjs +0 -181
  318. package/skills/media-use/scripts/lib/cube-build.test.mjs +0 -80
  319. package/skills/media-use/scripts/lib/cube-validate.mjs +0 -198
  320. package/skills/media-use/scripts/lib/cube-validate.test.mjs +0 -125
  321. package/skills/media-use/scripts/lib/cutlist.test.mjs +0 -148
  322. package/skills/media-use/scripts/lib/duck.test.mjs +0 -118
  323. package/skills/media-use/scripts/lib/error-diffusion.test.mjs +0 -102
  324. package/skills/media-use/scripts/lib/freeze.mjs +0 -70
  325. package/skills/media-use/scripts/lib/freeze.test.mjs +0 -46
  326. package/skills/media-use/scripts/lib/grade-analyzer.mjs +0 -264
  327. package/skills/media-use/scripts/lib/grade-analyzer.test.mjs +0 -285
  328. package/skills/media-use/scripts/lib/heygen-cli.mjs +0 -191
  329. package/skills/media-use/scripts/lib/heygen-cli.test.mjs +0 -301
  330. package/skills/media-use/scripts/lib/heygen-search.mjs +0 -45
  331. package/skills/media-use/scripts/lib/heygen-search.test.mjs +0 -49
  332. package/skills/media-use/scripts/lib/heygen-video-provider.mjs +0 -127
  333. package/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +0 -344
  334. package/skills/media-use/scripts/lib/image-provider.mjs +0 -44
  335. package/skills/media-use/scripts/lib/local-models.mjs +0 -318
  336. package/skills/media-use/scripts/lib/local-models.test.mjs +0 -220
  337. package/skills/media-use/scripts/lib/local-run.mjs +0 -78
  338. package/skills/media-use/scripts/lib/local-run.test.mjs +0 -121
  339. package/skills/media-use/scripts/lib/logo-provider.mjs +0 -222
  340. package/skills/media-use/scripts/lib/logo-provider.test.mjs +0 -137
  341. package/skills/media-use/scripts/lib/ltx-video-provider.mjs +0 -94
  342. package/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +0 -316
  343. package/skills/media-use/scripts/lib/lut-preset-provider.mjs +0 -266
  344. package/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +0 -176
  345. package/skills/media-use/scripts/lib/manifest.test.mjs +0 -388
  346. package/skills/media-use/scripts/lib/match.mjs +0 -47
  347. package/skills/media-use/scripts/lib/mflux-provider.mjs +0 -128
  348. package/skills/media-use/scripts/lib/mflux-provider.test.mjs +0 -174
  349. package/skills/media-use/scripts/lib/misses.mjs +0 -49
  350. package/skills/media-use/scripts/lib/misses.test.mjs +0 -78
  351. package/skills/media-use/scripts/lib/npx-sync.test.mjs +0 -50
  352. package/skills/media-use/scripts/lib/parakeet-words.test.mjs +0 -44
  353. package/skills/media-use/scripts/lib/prefs-store.test.mjs +0 -189
  354. package/skills/media-use/scripts/lib/probe.mjs +0 -39
  355. package/skills/media-use/scripts/lib/probe.test.mjs +0 -31
  356. package/skills/media-use/scripts/lib/providers.mjs +0 -5
  357. package/skills/media-use/scripts/lib/recipe-store.test.mjs +0 -367
  358. package/skills/media-use/scripts/lib/registry.mjs +0 -218
  359. package/skills/media-use/scripts/lib/registry.test.mjs +0 -261
  360. package/skills/media-use/scripts/lib/search.mjs +0 -24
  361. package/skills/media-use/scripts/lib/search.test.mjs +0 -32
  362. package/skills/media-use/scripts/lib/sfx-provider.mjs +0 -23
  363. package/skills/media-use/scripts/lib/specs.mjs +0 -132
  364. package/skills/media-use/scripts/lib/specs.test.mjs +0 -157
  365. package/skills/media-use/scripts/lib/stats.mjs +0 -117
  366. package/skills/media-use/scripts/lib/stats.test.mjs +0 -165
  367. package/skills/media-use/scripts/lib/telemetry.test.mjs +0 -373
  368. package/skills/media-use/scripts/lib/tts-local-provider.mjs +0 -92
  369. package/skills/media-use/scripts/lib/tts-local-provider.test.mjs +0 -72
  370. package/skills/media-use/scripts/lib/usage.mjs +0 -57
  371. package/skills/media-use/scripts/lib/usage.test.mjs +0 -54
  372. package/skills/media-use/scripts/lib/voice-provider.mjs +0 -57
  373. package/skills/media-use/scripts/lib/voice-provider.test.mjs +0 -46
  374. package/skills/media-use/scripts/resolve.test.mjs +0 -1120
  375. /package/skills/{hyperframes-core → hyperframes}/references/subagent-dispatch.md +0 -0
@@ -3,6 +3,8 @@ name: remotion-to-hyperframes
3
3
  description: 'Port an existing Remotion (React) composition''s source to HyperFrames HTML. Use ONLY on an explicit ask to port/convert/migrate/translate a Remotion source — one-way, Remotion-only. A passing Remotion mention, reference-only code, or "make something like my Remotion video" is a fresh build (/general-video). Unclear → /hyperframes.'
4
4
  ---
5
5
 
6
+ **Plugin installs:** Before setup or freshness commands, follow [plugin execution rules](../hyperframes/references/plugin-installation.md) when this skill is inside a HyperFrames plugin. Standalone installs keep the update instructions below.
7
+
6
8
  > **First, keep this skill fresh — confirm with the user before running:** `npx hyperframes skills update remotion-to-hyperframes`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them.
7
9
 
8
10
  # Remotion to HyperFrames
@@ -67,15 +69,16 @@ Read [`references/api-map.md`](references/api-map.md) — the index of every Rem
67
69
 
68
70
  Don't load all of them — load only what the specific source needs.
69
71
 
72
+ **Search the live catalog for any visual effect the table does not map.** When the source paints a look with no HF API equivalent — a scanline/CRT overlay, a glitch or chromatic-aberration pass, a shader wipe, a film-grain treatment — run `npx hyperframes catalog --query "<the effect, in plain English>" --json` before hand-writing it in GSAP. The search needs **nothing installed**: no project, no prior `add`, no account. It ranks the whole hosted registry (~400 blocks and components) from any directory, and `transitions.md` already takes this route for `clockWipe()` / `iris()` via `npx hyperframes add sdf-iris`. A real component is closer to the source than a hand-approximation, so it usually raises the SSIM rather than lowering it — but the render diff in Step 4 is still the arbiter. Hand-write the effect when a search returns nothing that fits, and record the substitution in `TRANSLATION_NOTES.md` either way.
73
+
70
74
  ### Step 3: Generate the HF composition
71
75
 
72
76
  Emit `index.html` with:
73
77
 
74
78
  - Root `<div id="stage">` carrying the composition's `data-composition-id`, `data-start="0"`, `data-duration` (in seconds), `data-fps`, `data-width`, `data-height`, plus one `data-*` per scalar prop.
75
- - A flat list of scene divs with `data-start` / `data-duration` / `data-track-index`.
76
- - Inline `<style>` for layout; CSS sets the `from` state of every animated property.
77
- - A single `<script>` tag at the bottom containing one paused `gsap.timeline({paused: true})`. Every Remotion `useCurrentFrame()` derivation becomes a tween on this timeline at the right offset.
78
- - `window.__timelines["<composition-id>"] = tl;` registers the timeline with HF's runtime.
79
+ - One host `<div>` per scene with `data-composition-src="compositions/<scene>.html"` and `data-start` / `data-duration` / `data-track-index`. The root holds no nested layout.
80
+ - One `compositions/<scene>.html` per scene (a `<template>` sub-composition): its inline `<style>` for layout (CSS sets the `from` state of every animated property), its markup, and one paused `gsap.timeline({paused: true})` in the scene's local time. Every Remotion `useCurrentFrame()` derivation becomes a tween on that timeline at the offset within the scene.
81
+ - `window.__timelines["<scene-id>"] = tl;` in each scene file, and `window.__timelines["<composition-id>"]` for the root's own (possibly empty) timeline.
79
82
 
80
83
  Custom React subcomponents inline as repeated HTML using the prop interface as the template (see [`parameters.md`](references/parameters.md) for the per-instance `data-*` pattern).
81
84
 
@@ -10,11 +10,11 @@
10
10
  "ssim_threshold": 0.95,
11
11
  "validation": {
12
12
  "measured_mean_ssim": 0.974,
13
- "measured_min_ssim": 0.972,
14
- "measured_p05_ssim": 0.972,
15
- "measured_p95_ssim": 0.983,
16
- "measured_at": "2026-04-27",
17
- "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.4.15-alpha.1"
13
+ "measured_min_ssim": 0.973,
14
+ "measured_p05_ssim": 0.973,
15
+ "measured_p95_ssim": 0.984,
16
+ "measured_at": "2026-09-18",
17
+ "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.7.71 (sub-composition fixtures)"
18
18
  },
19
19
  "translation_notes": [
20
20
  "Remotion: AbsoluteFill → HF: position:absolute;inset:0 div",
@@ -0,0 +1,31 @@
1
+ <template id="title-scene-template">
2
+ <div data-composition-id="title-scene" data-width="1280" data-height="720" data-duration="3">
3
+ <style>
4
+ .title {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ color: #ffffff;
11
+ font-size: 160px;
12
+ font-weight: 800;
13
+ letter-spacing: 0.05em;
14
+ opacity: 0;
15
+ }
16
+ </style>
17
+ <div class="title">HELLO</div>
18
+ <script>
19
+ // Translation of Remotion's
20
+ // interpolate(frame, [0, 15, 75, 90], [0, 1, 1, 0]) at fps=30
21
+ // into a paused GSAP timeline keyed in seconds.
22
+ const tl = gsap.timeline({ paused: true });
23
+ const target = document.querySelector(".title");
24
+ tl.to(target, { opacity: 1, duration: 0.5, ease: "none" }, 0);
25
+ tl.to(target, { opacity: 1, duration: 2.0, ease: "none" }, 0.5);
26
+ tl.to(target, { opacity: 0, duration: 0.5, ease: "none" }, 2.5);
27
+ window.__timelines = window.__timelines || {};
28
+ window.__timelines["title-scene"] = tl;
29
+ </script>
30
+ </div>
31
+ </template>
@@ -15,18 +15,6 @@
15
15
  background: #0a0a0a;
16
16
  font-family: Helvetica, Arial, sans-serif;
17
17
  }
18
- .title {
19
- position: absolute;
20
- inset: 0;
21
- display: flex;
22
- align-items: center;
23
- justify-content: center;
24
- color: #ffffff;
25
- font-size: 160px;
26
- font-weight: 800;
27
- letter-spacing: 0.05em;
28
- opacity: 0;
29
- }
30
18
  </style>
31
19
  </head>
32
20
  <body>
@@ -39,22 +27,19 @@
39
27
  data-duration="3"
40
28
  data-fps="30"
41
29
  >
42
- <div id="title" class="clip" data-start="0" data-duration="3" data-track-index="0">
43
- <div class="title">HELLO</div>
44
- </div>
30
+ <div
31
+ id="title"
32
+ class="clip"
33
+ data-composition-id="title-scene"
34
+ data-composition-src="compositions/title.html"
35
+ data-start="0"
36
+ data-duration="3"
37
+ data-track-index="0"
38
+ ></div>
45
39
 
46
40
  <script>
47
- // Translation of Remotion's
48
- // interpolate(frame, [0, 15, 75, 90], [0, 1, 1, 0]) at fps=30
49
- // into a paused GSAP timeline keyed in seconds.
50
- // Frame ranges → time ranges: 0/30=0, 15/30=0.5, 75/30=2.5, 90/30=3.0
51
- const tl = gsap.timeline({ paused: true });
52
- const target = document.querySelector("#title .title");
53
- tl.to(target, { opacity: 1, duration: 0.5, ease: "none" }, 0);
54
- tl.to(target, { opacity: 1, duration: 2.0, ease: "none" }, 0.5);
55
- tl.to(target, { opacity: 0, duration: 0.5, ease: "none" }, 2.5);
56
41
  window.__timelines = window.__timelines || {};
57
- window.__timelines["tier-1-title-card"] = tl;
42
+ window.__timelines["tier-1-title-card"] = gsap.timeline({ paused: true });
58
43
  </script>
59
44
  </div>
60
45
  </body>
@@ -18,16 +18,16 @@ If a translation passes T2, the skill correctly handles `<Sequence>` boundaries,
18
18
 
19
19
  ## Translation walk-through
20
20
 
21
- | Remotion | HyperFrames |
22
- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
23
- | `<Sequence from={0} durationInFrames={60}>` | `<div data-start="0" data-duration="2" data-track-index="0">` |
24
- | `spring({frame, fps, config: {damping:12, stiffness:100, mass:1}})` | `gsap.to(target, { scale: 1, duration: 0.7, ease: "back.out(1.4)" })` |
25
- | `<Audio src={staticFile("music.wav")} volume={0.5} />` | `<audio src="assets/music.wav" data-start="0" data-duration="6" data-volume="0.5" data-track-index="1">` |
26
- | `<Img src={staticFile("square.png")} />` | `<img src="assets/square.png">` (with setup.sh copying into both trees) |
27
- | `interpolate(frame, [0, 15], [0, 1])` at 30 fps | `gsap.to(target, { opacity: 1, duration: 0.5, ease: "none" })` |
21
+ | Remotion | HyperFrames |
22
+ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
23
+ | `<Sequence from={0} durationInFrames={60}>` | host `<div data-composition-src="compositions/scene-1.html" data-start="0" data-duration="2" data-track-index="0">` |
24
+ | `spring({frame, fps, config: {damping:12, stiffness:100, mass:1}})` | `gsap.to(target, { scale: 1, duration: 0.7, ease: "back.out(1.4)" })` |
25
+ | `<Audio src={staticFile("music.wav")} volume={0.5} />` | `<audio src="assets/music.wav" data-start="0" data-duration="6" data-volume="0.5" data-track-index="1">` |
26
+ | `<Img src={staticFile("square.png")} />` | `<img src="../assets/square.png">` inside `compositions/scene-2.html` (with setup.sh copying into both trees) |
27
+ | `interpolate(frame, [0, 15], [0, 1])` at 30 fps | `gsap.to(target, { opacity: 1, duration: 0.5, ease: "none" })` |
28
28
 
29
29
  The scene crossfading is a HyperFrames idiom, not a Remotion one: at scene boundaries
30
- we `gsap.set(scene, { opacity: 0 })` so the previous scene disappears at the
30
+ each scene sub-composition sets its own `gsap.set(scene, { opacity: 0 })` at its local end so the scene disappears at the
31
31
  right time. Remotion does this implicitly by virtue of `<Sequence>`'s durationInFrames.
32
32
 
33
33
  ## How to render and evaluate
@@ -9,19 +9,19 @@
9
9
  "height": 720,
10
10
  "ssim_threshold": 0.95,
11
11
  "validation": {
12
- "measured_mean_ssim": 0.985,
13
- "measured_min_ssim": 0.963,
14
- "measured_p05_ssim": 0.966,
15
- "measured_p95_ssim": 0.999,
16
- "measured_at": "2026-04-27",
17
- "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.4.15-alpha.1",
18
- "notes": "Spring → back.out(1.4) translation came out cleaner than expected; mean 0.985 leaves substantial headroom over 0.95."
12
+ "measured_mean_ssim": 0.986,
13
+ "measured_min_ssim": 0.964,
14
+ "measured_p05_ssim": 0.967,
15
+ "measured_p95_ssim": 1,
16
+ "measured_at": "2026-09-18",
17
+ "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.7.71 (sub-composition fixtures)",
18
+ "notes": "Spring → back.out(1.4) translation came out cleaner than expected; mean 0.986 leaves substantial headroom over 0.95."
19
19
  },
20
20
  "translation_notes": [
21
21
  "spring({damping:12, stiffness:100, mass:1}) → back.out(1.4) over 0.7s. Spring overshoot+settle and back.out's overshoot+settle have similar shape; budget ~0.02 SSIM for the late-tail curvature mismatch (validated lower than predicted in spec; original notes overestimated drift).",
22
- "<Sequence from durationInFrames> → wrapping div with data-start/data-duration in seconds and explicit gsap.set(opacity, 0/1) at scene boundaries to crossfade in/out cleanly",
22
+ "<Sequence from durationInFrames> → a sub-composition host with data-start/data-duration in seconds; the scene's own file uses local time and explicit gsap.set(opacity, 0/1) at its boundaries to crossfade in/out cleanly",
23
23
  "<Audio src volume> → <audio data-start data-duration data-volume>",
24
- "<Img src={staticFile('x')}> → <img src='assets/x'>; setup.sh copies the asset into both fixture trees",
24
+ "<Img src={staticFile('x')}> → <img src='assets/x'> (`../assets/x` inside the scene sub-composition file); setup.sh copies the asset into both fixture trees",
25
25
  "interpolate with default linear easing → ease:'none' in GSAP",
26
26
  "Fonts again rely on system Helvetica/Arial; ~0.015 SSIM cost from AA differences"
27
27
  ],
@@ -0,0 +1,35 @@
1
+ <template id="scene-1-template">
2
+ <div data-composition-id="scene-1" data-width="1280" data-height="720" data-duration="2">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .title {
13
+ font-size: 140px;
14
+ font-weight: 800;
15
+ color: #ffffff;
16
+ letter-spacing: 0.05em;
17
+ transform: scale(0);
18
+ }
19
+ </style>
20
+ <div class="scene">
21
+ <div class="title">Welcome</div>
22
+ </div>
23
+ <script>
24
+ // Scene 1 (0-2s): spring scale on "Welcome". Remotion:
25
+ // spring({frame, fps, config: {damping:12, stiffness:100, mass:1}}) -> back.out(1.4) over ~0.7s.
26
+ const tl = gsap.timeline({ paused: true });
27
+ const scene = document.querySelector(".scene");
28
+ tl.set(scene, { opacity: 1 }, 0);
29
+ tl.to(scene.querySelector(".title"), { scale: 1, duration: 0.7, ease: "back.out(1.4)" }, 0);
30
+ tl.set(scene, { opacity: 0 }, 2);
31
+ window.__timelines = window.__timelines || {};
32
+ window.__timelines["scene-1"] = tl;
33
+ </script>
34
+ </div>
35
+ </template>
@@ -0,0 +1,35 @@
1
+ <template id="scene-2-template">
2
+ <div data-composition-id="scene-2" data-width="1280" data-height="720" data-duration="2">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .square {
13
+ width: 200px;
14
+ height: 200px;
15
+ opacity: 0;
16
+ transform: scale(0.8);
17
+ }
18
+ </style>
19
+ <div class="scene">
20
+ <img class="square" src="../assets/square.png" alt="" />
21
+ </div>
22
+ <script>
23
+ // Scene 2 (2-4s, local 0-2s): opacity 0->1 over 0.5s, scale 0.8->1.0 over 2s, both linear.
24
+ const tl = gsap.timeline({ paused: true });
25
+ const scene = document.querySelector(".scene");
26
+ const square = scene.querySelector(".square");
27
+ tl.set(scene, { opacity: 1 }, 0);
28
+ tl.to(square, { opacity: 1, duration: 0.5, ease: "none" }, 0);
29
+ tl.to(square, { scale: 1.0, duration: 2.0, ease: "none" }, 0);
30
+ tl.set(scene, { opacity: 0 }, 2);
31
+ window.__timelines = window.__timelines || {};
32
+ window.__timelines["scene-2"] = tl;
33
+ </script>
34
+ </div>
35
+ </template>
@@ -0,0 +1,36 @@
1
+ <template id="scene-3-template">
2
+ <div data-composition-id="scene-3" data-width="1280" data-height="720" data-duration="2">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .outro {
13
+ font-size: 100px;
14
+ font-weight: 600;
15
+ color: #ffffff;
16
+ }
17
+ </style>
18
+ <div class="scene">
19
+ <div class="outro">Goodbye</div>
20
+ </div>
21
+ <script>
22
+ // Scene 3 (4-6s, local 0-2s): opacity 0->1 over 1s, linear.
23
+ const tl = gsap.timeline({ paused: true });
24
+ const scene = document.querySelector(".scene");
25
+ tl.set(scene, { opacity: 1 }, 0);
26
+ tl.fromTo(
27
+ scene.querySelector(".outro"),
28
+ { opacity: 0 },
29
+ { opacity: 1, duration: 1.0, ease: "none" },
30
+ 0,
31
+ );
32
+ window.__timelines = window.__timelines || {};
33
+ window.__timelines["scene-3"] = tl;
34
+ </script>
35
+ </div>
36
+ </template>
@@ -15,32 +15,6 @@
15
15
  background: #0a0a0a;
16
16
  font-family: Helvetica, Arial, sans-serif;
17
17
  }
18
- .scene {
19
- position: absolute;
20
- inset: 0;
21
- display: flex;
22
- align-items: center;
23
- justify-content: center;
24
- opacity: 0;
25
- }
26
- .title {
27
- font-size: 140px;
28
- font-weight: 800;
29
- color: #ffffff;
30
- letter-spacing: 0.05em;
31
- transform: scale(0);
32
- }
33
- .square {
34
- width: 200px;
35
- height: 200px;
36
- opacity: 0;
37
- transform: scale(0.8);
38
- }
39
- .outro {
40
- font-size: 100px;
41
- font-weight: 600;
42
- color: #ffffff;
43
- }
44
18
  </style>
45
19
  </head>
46
20
  <body>
@@ -53,17 +27,35 @@
53
27
  data-duration="6"
54
28
  data-fps="30"
55
29
  >
56
- <div id="scene-1" class="scene clip" data-start="0" data-duration="2" data-track-index="0">
57
- <div class="title">Welcome</div>
58
- </div>
30
+ <div
31
+ id="scene-1"
32
+ class="clip"
33
+ data-composition-id="scene-1"
34
+ data-composition-src="compositions/scene-1.html"
35
+ data-start="0"
36
+ data-duration="2"
37
+ data-track-index="0"
38
+ ></div>
59
39
 
60
- <div id="scene-2" class="scene clip" data-start="2" data-duration="2" data-track-index="0">
61
- <img class="square" src="assets/square.png" alt="" />
62
- </div>
40
+ <div
41
+ id="scene-2"
42
+ class="clip"
43
+ data-composition-id="scene-2"
44
+ data-composition-src="compositions/scene-2.html"
45
+ data-start="2"
46
+ data-duration="2"
47
+ data-track-index="0"
48
+ ></div>
63
49
 
64
- <div id="scene-3" class="scene clip" data-start="4" data-duration="2" data-track-index="0">
65
- <div class="outro">Goodbye</div>
66
- </div>
50
+ <div
51
+ id="scene-3"
52
+ class="clip"
53
+ data-composition-id="scene-3"
54
+ data-composition-src="compositions/scene-3.html"
55
+ data-start="4"
56
+ data-duration="2"
57
+ data-track-index="0"
58
+ ></div>
67
59
 
68
60
  <audio
69
61
  id="bg-music"
@@ -75,43 +67,8 @@
75
67
  ></audio>
76
68
 
77
69
  <script>
78
- // Translation of Remotion's 3-Sequence MultiScene at fps=30, total 6s.
79
- //
80
- // Scene 1 (0-2s): TitleScene — spring scale on "Welcome".
81
- // Remotion: spring({frame, fps, config: {damping:12, stiffness:100, mass:1}})
82
- // GSAP equivalent: back.out(1.4) over ~0.7s. Spring → ease translation
83
- // is approximate; expect minor differences in the tail of the curve.
84
- //
85
- // Scene 2 (2-4s): ImageScene — opacity 0→1 over 0-0.5s + scale 0.8→1.0 over 0-2.0s.
86
- // Both Remotion interpolates use linear (default), match with ease:"none".
87
- //
88
- // Scene 3 (4-6s): OutroScene — opacity 0→1 over 4-5s, linear.
89
-
90
- const tl = gsap.timeline({ paused: true });
91
-
92
- // Scene 1 setup: opacity flick on so scene becomes visible at start
93
- const scene1 = document.querySelector("#scene-1");
94
- const title = scene1.querySelector(".title");
95
- tl.set(scene1, { opacity: 1 }, 0);
96
- tl.to(title, { scale: 1, duration: 0.7, ease: "back.out(1.4)" }, 0);
97
- tl.set(scene1, { opacity: 0 }, 2);
98
-
99
- // Scene 2
100
- const scene2 = document.querySelector("#scene-2");
101
- const square = scene2.querySelector(".square");
102
- tl.set(scene2, { opacity: 1 }, 2);
103
- tl.to(square, { opacity: 1, duration: 0.5, ease: "none" }, 2);
104
- tl.to(square, { scale: 1.0, duration: 2.0, ease: "none" }, 2);
105
- tl.set(scene2, { opacity: 0 }, 4);
106
-
107
- // Scene 3
108
- const scene3 = document.querySelector("#scene-3");
109
- const outro = scene3.querySelector(".outro");
110
- tl.set(scene3, { opacity: 1 }, 4);
111
- tl.fromTo(outro, { opacity: 0 }, { opacity: 1, duration: 1.0, ease: "none" }, 4);
112
-
113
70
  window.__timelines = window.__timelines || {};
114
- window.__timelines["tier-2-multi-scene"] = tl;
71
+ window.__timelines["tier-2-multi-scene"] = gsap.timeline({ paused: true });
115
72
  </script>
116
73
  </div>
117
74
  </body>
@@ -12,9 +12,9 @@
12
12
  "measured_mean_ssim": 0.953,
13
13
  "measured_min_ssim": 0.927,
14
14
  "measured_p05_ssim": 0.938,
15
- "measured_p95_ssim": 0.977,
16
- "measured_at": "2026-04-27",
17
- "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.4.15-alpha.1",
15
+ "measured_p95_ssim": 0.978,
16
+ "measured_at": "2026-09-18",
17
+ "measured_against": "remotion@4.0 (PNG output, BT.709) vs hyperframes@0.7.71 (sub-composition fixtures)",
18
18
  "notes": "Count-up timing in StatsScene shows a few-frame offset between Remotion's manual 1-(1-t)^3 and GSAP's power3.out — both formulas are identical, so the offset comes from sub-frame timing of when the seek + onUpdate fire. Final values converge correctly. Visible only as transient digit mismatches mid-animation; no SSIM impact above the noise floor."
19
19
  },
20
20
  "remotion_apis_exercised": [
@@ -0,0 +1,52 @@
1
+ <template id="scene-1-template">
2
+ <div data-composition-id="scene-1" data-width="1280" data-height="720" data-duration="3">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .scene-1 {
13
+ flex-direction: column;
14
+ }
15
+ .scene-1 .title {
16
+ font-size: 160px;
17
+ font-weight: 900;
18
+ letter-spacing: 0.05em;
19
+ transform: scale(0);
20
+ }
21
+ .scene-1 .subtitle {
22
+ font-size: 36px;
23
+ font-weight: 400;
24
+ color: #9ca3af;
25
+ margin-top: 24px;
26
+ opacity: 0;
27
+ }
28
+ </style>
29
+ <div class="scene scene-1">
30
+ <div class="title">STARGAZED</div>
31
+ <div class="subtitle">by HeyGen</div>
32
+ </div>
33
+ <script>
34
+ // Remotion: <Sequence 0..90> TitleScene. Frame -> time at 30 fps.
35
+ const tl = gsap.timeline({ paused: true });
36
+ const scene = document.querySelector(".scene-1");
37
+ tl.set(scene, { opacity: 1 }, 0);
38
+ // spring({damping:12, stiffness:100, mass:1}) -> back.out(1.4) ~0.7s
39
+ tl.to(scene.querySelector(".title"), { scale: 1, duration: 0.7, ease: "back.out(1.4)" }, 0);
40
+ // interpolate(frame, [20,40], [0,1]) -> 0.667s..1.333s linear
41
+ tl.fromTo(
42
+ scene.querySelector(".subtitle"),
43
+ { opacity: 0 },
44
+ { opacity: 1, duration: 0.667, ease: "none" },
45
+ 0.667,
46
+ );
47
+ tl.set(scene, { opacity: 0 }, 3);
48
+ window.__timelines = window.__timelines || {};
49
+ window.__timelines["scene-1"] = tl;
50
+ </script>
51
+ </div>
52
+ </template>
@@ -0,0 +1,99 @@
1
+ <template id="scene-2-template">
2
+ <div data-composition-id="scene-2" data-width="1280" data-height="720" data-duration="4">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .scene-2 {
13
+ gap: 48px;
14
+ }
15
+ .stat-card {
16
+ width: 280px;
17
+ height: 220px;
18
+ background: #1a1a1a;
19
+ border-radius: 16px;
20
+ border: 2px solid var(--card-color);
21
+ display: flex;
22
+ flex-direction: column;
23
+ justify-content: center;
24
+ align-items: center;
25
+ opacity: 0;
26
+ transform: scale(0);
27
+ }
28
+ .stat-card .number {
29
+ font-size: 72px;
30
+ font-weight: 800;
31
+ color: var(--card-color);
32
+ line-height: 1;
33
+ }
34
+ .stat-card .label {
35
+ font-size: 24px;
36
+ font-weight: 500;
37
+ color: #9ca3af;
38
+ margin-top: 16px;
39
+ text-transform: uppercase;
40
+ letter-spacing: 0.1em;
41
+ }
42
+ </style>
43
+ <div class="scene scene-2">
44
+ <div
45
+ class="stat-card"
46
+ data-stat-index="0"
47
+ data-stat-value="1247"
48
+ style="--card-color: #fbbf24"
49
+ >
50
+ <div class="number">0</div>
51
+ <div class="label">Stars</div>
52
+ </div>
53
+ <div
54
+ class="stat-card"
55
+ data-stat-index="1"
56
+ data-stat-value="312"
57
+ style="--card-color: #60a5fa"
58
+ >
59
+ <div class="number">0</div>
60
+ <div class="label">Forks</div>
61
+ </div>
62
+ <div class="stat-card" data-stat-index="2" data-stat-value="48" style="--card-color: #f87171">
63
+ <div class="number">0</div>
64
+ <div class="label">Issues</div>
65
+ </div>
66
+ </div>
67
+ <script>
68
+ // Remotion: <Sequence 90..210> StatsScene; StatCard stagger i*12 frames = i*0.4s.
69
+ const tl = gsap.timeline({ paused: true });
70
+ const scene = document.querySelector(".scene-2");
71
+ tl.set(scene, { opacity: 1 }, 0);
72
+ scene.querySelectorAll(".stat-card").forEach((card, i) => {
73
+ const start = i * 0.4;
74
+ const value = Number(card.dataset.statValue);
75
+ const numberEl = card.querySelector(".number");
76
+ // spring({damping:14, stiffness:90, mass:1}) -> back.out(1.2) ~0.7s; opacity 0..0.4s linear
77
+ tl.to(card, { scale: 1, duration: 0.7, ease: "back.out(1.2)" }, start);
78
+ tl.to(card, { opacity: 1, duration: 0.4, ease: "none" }, start);
79
+ // AnimatedNumber: easeOutCubic over 45 frames (1.5s) is GSAP power3.out on a counter.
80
+ const counter = { v: 0 };
81
+ tl.to(
82
+ counter,
83
+ {
84
+ v: value,
85
+ duration: 1.5,
86
+ ease: "power3.out",
87
+ onUpdate: () => {
88
+ numberEl.textContent = Math.round(counter.v).toLocaleString();
89
+ },
90
+ },
91
+ start,
92
+ );
93
+ });
94
+ tl.set(scene, { opacity: 0 }, 4);
95
+ window.__timelines = window.__timelines || {};
96
+ window.__timelines["scene-2"] = tl;
97
+ </script>
98
+ </div>
99
+ </template>
@@ -0,0 +1,55 @@
1
+ <template id="scene-3-template">
2
+ <div data-composition-id="scene-3" data-width="1280" data-height="720" data-duration="3">
3
+ <style>
4
+ .scene {
5
+ position: absolute;
6
+ inset: 0;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ opacity: 0;
11
+ }
12
+ .scene-3 .outro-wrap {
13
+ position: relative;
14
+ display: inline-block;
15
+ opacity: 0;
16
+ }
17
+ .scene-3 .outro-text {
18
+ font-size: 80px;
19
+ font-weight: 600;
20
+ }
21
+ .scene-3 .outro-underline {
22
+ position: absolute;
23
+ left: 0;
24
+ bottom: -8px;
25
+ width: 100%;
26
+ height: 6px;
27
+ background: #fbbf24;
28
+ border-radius: 3px;
29
+ transform: scaleX(0);
30
+ transform-origin: left center;
31
+ }
32
+ </style>
33
+ <div class="scene scene-3">
34
+ <div class="outro-wrap">
35
+ <div class="outro-text">thanks for watching</div>
36
+ <div class="outro-underline"></div>
37
+ </div>
38
+ </div>
39
+ <script>
40
+ // Remotion: <Sequence 210..300> OutroScene.
41
+ const tl = gsap.timeline({ paused: true });
42
+ const scene = document.querySelector(".scene-3");
43
+ tl.set(scene, { opacity: 1 }, 0);
44
+ tl.to(scene.querySelector(".outro-wrap"), { opacity: 1, duration: 0.4, ease: "none" }, 0);
45
+ // interpolate(frame, [10,40], [0,1]) for the underline -> starts 0.333s, 1s long
46
+ tl.to(
47
+ scene.querySelector(".outro-underline"),
48
+ { scaleX: 1, duration: 1.0, ease: "none" },
49
+ 0.333,
50
+ );
51
+ window.__timelines = window.__timelines || {};
52
+ window.__timelines["scene-3"] = tl;
53
+ </script>
54
+ </div>
55
+ </template>