hyperframes 0.8.184 → 0.8.185
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-5ZTD3MUZ.js → add-ODTNPRGG.js} +14 -14
- package/dist/{agentPromptGenerator-VIIPZCJ3.js → agentPromptGenerator-KYO5MKTW.js} +1 -1
- package/dist/{animatedGifPrep-AGASIWVA.js → animatedGifPrep-PEP5GWOJ.js} +9 -9
- package/dist/api.js +17 -17
- package/dist/{asset-LSTEMPIB.js → asset-EZG42XPA.js} +2 -2
- package/dist/{assetCataloger-BKBMNL3A.js → assetCataloger-OHAJFCA7.js} +9 -9
- package/dist/{audio-KGK44XE4.js → audio-65R4T74I.js} +16 -15
- package/dist/{auth-MJWKYK77.js → auth-VP2SIZFN.js} +1 -1
- package/dist/{autoUpdate-2GGDKYR2.js → autoUpdate-RVSUX4SS.js} +2 -2
- package/dist/{backgroundChecks-7GRX5VQY.js → backgroundChecks-LEHK74NS.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-BCV2LELR.js → batchRender-3X6CL7PK.js} +5 -5
- package/dist/{beats-7BCFRBAL.js → beats-66VPQLSC.js} +6 -6
- package/dist/{benchmark-2R6CN5MQ.js → benchmark-PBJVTOJP.js} +10 -10
- package/dist/{browser-6AFGOI7G.js → browser-TPL5MWGC.js} +3 -3
- package/dist/{bundleWithLocalizedFonts-2EGPA5ZO.js → bundleWithLocalizedFonts-67MLTHKM.js} +2 -2
- package/dist/{capture-HOIAW6MO.js → capture-F3GNMRZM.js} +13 -13
- package/dist/{capture-HA2UHLIU.js → capture-YYRE7EV3.js} +2 -2
- package/dist/{captureCompositionFrame-4236FVWJ.js → captureCompositionFrame-PXV2ISHD.js} +13 -13
- package/dist/{catalog-A6CZAWW4.js → catalog-6SDD3OHF.js} +14 -14
- package/dist/{catch-up-TNA4DJOA.js → catch-up-CWIVA5VG.js} +4 -4
- package/dist/{check-5E5U2EQZ.js → check-YQ6REK2S.js} +34 -34
- package/dist/{checkBrowser-FNINXBMZ.js → checkBrowser-5XZCBRXM.js} +31 -31
- package/dist/{chunk-2ULXZ4PG.js → chunk-2TAS5O4P.js} +56 -11
- package/dist/{chunk-3TXNNBI2.js → chunk-37CNYTQQ.js} +2 -2
- package/dist/chunk-3NPOFC43.js +3805 -0
- package/dist/{chunk-EEP5Y5IE.js → chunk-46HEFGXJ.js} +1 -1
- package/dist/{chunk-2XA7KXQO.js → chunk-4CTNDBE3.js} +2 -2
- package/dist/{chunk-MFAETWIF.js → chunk-55YELV7B.js} +1 -1
- package/dist/{chunk-LRGYPXHF.js → chunk-5GUKZRQN.js} +1 -1
- package/dist/{chunk-SAX7HQ5E.js → chunk-6ASIXMFP.js} +1 -1
- package/dist/{chunk-SN7KI5JA.js → chunk-6GPR3G3C.js} +2 -2
- package/dist/{chunk-E32ZQ2WO.js → chunk-6RIZY7OP.js} +1 -1
- package/dist/{chunk-5CS4T6C6.js → chunk-7L37AB57.js} +1 -1
- package/dist/{chunk-BCHSTE7U.js → chunk-7PS6RVWD.js} +1 -1
- package/dist/{chunk-X3CG5YQA.js → chunk-7RAY4WZP.js} +3 -3
- package/dist/{chunk-YWHCXIMD.js → chunk-A6QCO474.js} +5 -5
- package/dist/{chunk-YMS5FOMC.js → chunk-B2A56S5C.js} +1 -1
- package/dist/{chunk-IWTNTUPQ.js → chunk-BH7TTIPN.js} +11 -13
- package/dist/{chunk-DWUGKEHR.js → chunk-BRAPBUPQ.js} +1 -1
- package/dist/{chunk-R2BFTECP.js → chunk-CX3USX23.js} +3 -3
- package/dist/{chunk-JB6ARMQS.js → chunk-D42NU3DZ.js} +1 -1
- package/dist/{chunk-GDEV42FA.js → chunk-EMAWIZ54.js} +481 -36
- package/dist/{chunk-UNNXFKVG.js → chunk-EMSDWBG3.js} +2 -2
- package/dist/{chunk-CXABAXB3.js → chunk-ESBMUZXZ.js} +1 -1
- package/dist/{chunk-EM7C7H7S.js → chunk-F3OPUWQX.js} +7 -7
- package/dist/{chunk-YOZPQCSR.js → chunk-FX6RUJUY.js} +3 -3
- package/dist/{chunk-PSKEKWVU.js → chunk-G2UANIDX.js} +1 -1
- package/dist/{chunk-UKOTVJFV.js → chunk-H5SM5PJI.js} +1 -1
- package/dist/{chunk-YWNJTZGN.js → chunk-H6UY725W.js} +2 -2
- package/dist/{chunk-PFYWVUHA.js → chunk-HDIRZGK4.js} +1 -1
- package/dist/{chunk-HR23IKLZ.js → chunk-HHSJJFVM.js} +2 -2
- package/dist/{chunk-LLC4CS6I.js → chunk-HXUTX5GR.js} +3 -3
- package/dist/{chunk-RGXVEYHI.js → chunk-I3IH5MV5.js} +6 -10
- package/dist/{chunk-Q33P4EAC.js → chunk-I45HL3VP.js} +3 -3
- package/dist/{chunk-TYXH3EKP.js → chunk-I5JRXMCV.js} +16 -1
- package/dist/{chunk-4N4P3ZWL.js → chunk-I7QMXZSB.js} +2 -2
- package/dist/{chunk-ICJEAFPD.js → chunk-IDFNKFPL.js} +7 -7
- package/dist/{chunk-VNVQGDPC.js → chunk-IDGLGXPA.js} +1 -1
- package/dist/{chunk-2PVE4WS2.js → chunk-IPDKZ5IN.js} +33 -6
- package/dist/{chunk-ABZYYUUH.js → chunk-ISTRDGIX.js} +1 -1
- package/dist/{chunk-3MDJIWOV.js → chunk-IVEFOUZI.js} +46 -30
- package/dist/{chunk-4KKKBEP3.js → chunk-J5XEZ24I.js} +3 -3
- package/dist/{chunk-7HJALUIO.js → chunk-K2ZKXTVL.js} +1 -1
- package/dist/{chunk-TE427YID.js → chunk-K73RJB23.js} +2 -2
- package/dist/{chunk-3QVMJ7GX.js → chunk-KQ4JEJLF.js} +9 -9
- package/dist/{chunk-J3QM7AHP.js → chunk-KROXPHXX.js} +9 -3
- package/dist/{chunk-OLZENUPI.js → chunk-LLFQA7XF.js} +1 -1
- package/dist/chunk-LLMSX6V6.js +17 -0
- package/dist/{chunk-WTFUDNW2.js → chunk-LYKSTRAY.js} +3 -3
- package/dist/{chunk-VDM3FEDP.js → chunk-OAG47RE6.js} +1 -1
- package/dist/{chunk-FGJEUV4S.js → chunk-PHMBMOXF.js} +1 -1
- package/dist/{chunk-7MB2ZAQF.js → chunk-PMMQRJDE.js} +1 -1
- package/dist/{chunk-ADDHW2FS.js → chunk-Q447CX26.js} +82 -12
- package/dist/{chunk-YALM6XN4.js → chunk-Q47FAYYK.js} +3 -3
- package/dist/{chunk-ZOCHDXDG.js → chunk-RTBSA3EA.js} +1 -1
- package/dist/{chunk-UJKUB2LH.js → chunk-RUEGYANA.js} +11 -11
- package/dist/{chunk-OYLO6TYK.js → chunk-RUOG4VB7.js} +1 -1
- package/dist/{chunk-ZRHO6YMM.js → chunk-SKYPMHQC.js} +4 -4
- package/dist/{chunk-ES426XRJ.js → chunk-SQVRXHOW.js} +3 -3
- package/dist/{chunk-QL2PNIXC.js → chunk-TAX2ZJAP.js} +24 -16
- package/dist/{chunk-KN46TGHV.js → chunk-TOI35GN2.js} +1 -1
- package/dist/{chunk-74JMKLVU.js → chunk-UPR3MU6Z.js} +1 -1
- package/dist/{chunk-JIUTXKWA.js → chunk-WQLKDL35.js} +2 -1
- package/dist/{chunk-WHPN2TIT.js → chunk-X6L6MD5B.js} +5 -5
- package/dist/{chunk-7NRI7HYX.js → chunk-XWC7CNPY.js} +1 -1
- package/dist/{clean-HGASSMWI.js → clean-7J6ZCCGV.js} +18 -18
- package/dist/cli.js +53 -53
- package/dist/{cloud-JPDVNXHN.js → cloud-7IJCJCDD.js} +4 -4
- package/dist/{cloudrun-AMMGSDRP.js → cloudrun-UNZRIIDB.js} +7 -7
- package/dist/commands/contrast-audit.browser.js +1 -2
- package/dist/commands/layout-audit.browser.js +196 -0
- package/dist/{compare-LHHVHUN3.js → compare-Q7VW5JZT.js} +28 -28
- package/dist/{compiler-Q3N6QXMT.js → compiler-KPHYGFXL.js} +6 -6
- package/dist/{component-D72J32Q7.js → component-UUBREJKN.js} +3 -3
- package/dist/{compositions-UQRJ5ROG.js → compositions-T4FTKIDP.js} +13 -13
- package/dist/{delete-P42VIDDA.js → delete-WZQF2IIA.js} +2 -2
- package/dist/{deploy-WZTH57O4.js → deploy-JU7A3XNC.js} +1 -1
- package/dist/{deterministicFonts-VQ5UBMXY.js → deterministicFonts-EGAAE7QL.js} +3 -3
- package/dist/{dist-SENYPQGW.js → dist-LM7AVHOU.js} +3 -3
- package/dist/{dist-DYS24AMA.js → dist-ULGTPSU4.js} +8 -4
- package/dist/docs/data-attributes.md +1 -1
- package/dist/{doctor-KEJIG2SK.js → doctor-VSNGRKXJ.js} +13 -13
- package/dist/{events-CYKSNR7N.js → events-CRW2DYUT.js} +3 -3
- package/dist/{events-UZXFQPMT.js → events-E63YBUL2.js} +3 -3
- package/dist/{feedback-LXNQF7CA.js → feedback-OSZWVR6N.js} +8 -8
- package/dist/{ffmpeg-BYHON577.js → ffmpeg-JLH3Z7G7.js} +9 -9
- package/dist/{figma-EIQ35PS6.js → figma-2BQNNR53.js} +3 -3
- package/dist/fontLocalizeCli.js +12 -12
- package/dist/{get-CC2YL7QO.js → get-P2XI53QW.js} +2 -2
- package/dist/{gpuPolicy-VFSACUQV.js → gpuPolicy-NTKQJY75.js} +9 -9
- package/dist/{grade-compare-TUQL7IV2.js → grade-compare-OYASIHIB.js} +29 -29
- package/dist/{gsapParserAcorn-7NCK2LVT.js → gsapParserAcorn-SKODXC2N.js} +2 -2
- package/dist/{help-ROROO5K6.js → help-HK6K2N4G.js} +1 -1
- package/dist/{history-PNELYLXX.js → history-JMTYKLXW.js} +6 -6
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +63 -63
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/{info-4FZTH6AS.js → info-AW7CIVRE.js} +9 -9
- package/dist/{init-I43GHHVP.js → init-6KIDG4LB.js} +30 -30
- package/dist/{inspect-IT4TYIZ3.js → inspect-B7BLYMRZ.js} +29 -29
- package/dist/{installer-CWOJVK5K.js → installer-ZP2LQZUQ.js} +7 -7
- package/dist/{keyframes-3FBOGVD4.js → keyframes-EQ36A5JE.js} +7 -7
- package/dist/{lambda-H3V32I7M.js → lambda-E6VURLIS.js} +9 -9
- package/dist/{layout-BZ5LYJ5C.js → layout-XYC64QQQ.js} +29 -29
- package/dist/{lint-ZTNSGP2S.js → lint-V5DJYWBX.js} +9 -9
- package/dist/{lintProject-C2ONSH2U.js → lintProject-JATQKR64.js} +3 -3
- package/dist/{list-XM4GWJYY.js → list-RUGVRTVD.js} +2 -2
- package/dist/{login-H6HYKMWX.js → login-ZTKGKXGS.js} +4 -4
- package/dist/{manager-TWVDSJXO.js → manager-JUP7PM6N.js} +10 -10
- package/dist/{media-treatment-N7MY5NXB.js → media-treatment-VIUPK4OR.js} +15 -15
- package/dist/{models-WEMIMYBD.js → models-LJS2HBOZ.js} +13 -13
- package/dist/{motionShot-RHICTVPU.js → motionShot-3UAXZ7SN.js} +16 -16
- package/dist/{normalize-audio-ZFUZCJE3.js → normalize-audio-SBYI4YIH.js} +4 -4
- package/dist/{open-IBJ4FL3G.js → open-S27TUD3A.js} +14 -14
- package/dist/{parakeetRunner-XXO4WSLR.js → parakeetRunner-ETLMLJ4L.js} +14 -14
- package/dist/{pipeline-6ML3LUVK.js → pipeline-I2M22M24.js} +10 -10
- package/dist/{play-RV4NAVF5.js → play-COJU6VJK.js} +21 -21
- package/dist/{preflight-R3DEFMLA.js → preflight-FZ24NCHH.js} +10 -10
- package/dist/{present-5TBJGE6B.js → present-YAHKLC5D.js} +17 -17
- package/dist/{preview-FLKZ5CXJ.js → preview-KQOEU5YE.js} +20 -20
- package/dist/{producer-7XYSPVKH.js → producer-DTNNG4T6.js} +1 -1
- package/dist/{projectConfig-TBU2VWZX.js → projectConfig-4A76VYUP.js} +9 -9
- package/dist/{publication-CWWUJYJ5.js → publication-SQPMC2W3.js} +4 -4
- package/dist/{publish-FSNE4FEB.js → publish-QUEJBGGT.js} +11 -11
- package/dist/{remove-background-MDFWRWCT.js → remove-background-FP2ETAQH.js} +11 -11
- package/dist/{render-F4JQ553X.js → render-BIFIL4U6.js} +31 -31
- package/dist/{render-DBGQZAZT.js → render-GQFXJWLV.js} +17 -29
- package/dist/{render-LWZKXCLY.js → render-P664SMC7.js} +5 -5
- package/dist/{render-batch-PU7NMLIJ.js → render-batch-ZCPMYH6Z.js} +5 -5
- package/dist/renderSetupWorker.js +3 -3
- package/dist/{resolver-RUBGFXPC.js → resolver-BUC2GFZQ.js} +6 -6
- package/dist/{sherpa-X2TBNO6P.js → sherpa-HFT6XEP6.js} +13 -13
- package/dist/skills/hyperframes/SKILL.md +52 -174
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/caption-skin.html +220 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/FRAME.md +307 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/caption-skin.html +224 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/frame-showcase.html +1166 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/frame-showcase.html +1465 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/FRAME.md +278 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/caption-skin.html +221 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/caption-skin.html +237 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/FRAME.md +277 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-eb-garamond.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-inter.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-jetbrains-mono.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/frame-showcase.html +1438 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/FRAME.md +314 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/caption-skin.html +225 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/frame-showcase.html +1268 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/FRAME.md +333 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/caption-skin.html +226 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/FRAME.md +274 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/dist/skills/hyperframes/references/captions.md +46 -0
- package/dist/skills/hyperframes/references/film.md +47 -0
- package/dist/skills/hyperframes/references/format.md +157 -0
- package/dist/skills/hyperframes/references/look.md +69 -0
- package/dist/skills/hyperframes/references/motion.md +94 -0
- package/dist/skills/hyperframes/references/overlays.md +39 -0
- package/dist/skills/hyperframes/references/plugin-installation.md +3 -3
- package/dist/skills/hyperframes/references/review.md +51 -0
- package/dist/skills/hyperframes/references/runtimes.md +43 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +21 -13
- package/dist/skills/hyperframes/references/sound.md +43 -0
- package/dist/skills/hyperframes/references/spec.md +76 -0
- package/dist/skills/hyperframes/references/story.md +103 -0
- package/dist/skills/hyperframes/references/storyboard-format.md +30 -22
- package/dist/skills/hyperframes/references/storyboard.md +36 -0
- package/dist/skills/hyperframes/references/types/3d.md +25 -0
- package/dist/skills/hyperframes/references/types/character.md +20 -0
- package/dist/skills/hyperframes/references/types/data.md +19 -0
- package/dist/skills/hyperframes/references/types/explainer.md +34 -0
- package/dist/skills/hyperframes/references/types/launch.md +31 -0
- package/dist/skills/hyperframes/references/types/music.md +24 -0
- package/dist/skills/hyperframes/references/types/vertical.md +23 -0
- package/dist/skills/hyperframes/scripts/bake-basemap.mjs +324 -0
- package/dist/skills/hyperframes/scripts/lib/main-module.test.mjs +1 -6
- package/dist/skills/hyperframes/scripts/locate.mjs +228 -0
- package/dist/skills/hyperframes-cli/SKILL.md +76 -179
- package/dist/skills/hyperframes-cli/references/beats.md +1 -1
- package/dist/skills/hyperframes-cli/references/cloud.md +2 -2
- package/dist/skills/hyperframes-cli/references/cloudrun.md +1 -1
- package/dist/skills/hyperframes-cli/references/conventions.md +17 -0
- package/dist/skills/hyperframes-cli/references/feedback.md +14 -0
- package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +11 -7
- package/dist/skills/hyperframes-cli/references/lambda.md +1 -1
- package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +19 -8
- package/dist/skills/hyperframes-cli/references/preview-render.md +8 -2
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +8 -0
- package/dist/skills/media-use/SKILL.md +47 -91
- package/dist/skills/media-use/audio/references/bgm.md +1 -1
- package/dist/skills/media-use/audio/references/captions/authoring.md +1 -2
- package/dist/skills/media-use/audio/references/captions/motion.md +5 -5
- package/dist/skills/media-use/audio/references/tts.md +0 -3
- package/dist/skills/media-use/audio/scripts/audio.mjs +5 -6
- package/dist/skills/media-use/audio/scripts/carve.mjs +560 -0
- package/dist/skills/media-use/audio/scripts/carve.test.mjs +254 -0
- package/dist/skills/media-use/audio/scripts/extract-audio-data.py +199 -0
- package/dist/skills/media-use/references/local.md +24 -0
- package/dist/skills/media-use/references/memory.md +4 -4
- package/dist/skills/media-use/references/mixing.md +71 -0
- package/dist/skills/media-use/references/operations.md +1 -1
- package/dist/skills/media-use/scripts/compatibility.test.mjs +1 -56
- package/dist/skills/media-use/scripts/lib/prefs-store.mjs +1 -1
- package/dist/skills/media-use/scripts/lib/recipe-store.mjs +1 -1
- package/dist/skills/media-use/scripts/prefs.mjs +2 -3
- package/dist/skills/media-use/scripts/recipe.mjs +1 -3
- package/dist/{skills-WHKMWO2D.js → skills-3WEVO3NU.js} +20 -13
- package/dist/{skillsUpdateCheck-XQGZGJJG.js → skillsUpdateCheck-BFPWFOK5.js} +3 -3
- package/dist/{snapshot-M4NUUSNU.js → snapshot-WDQ6S7CJ.js} +457 -98
- package/dist/{src-6MSC62U2.js → src-NPR2JZOJ.js} +11 -11
- package/dist/{src-4UYM2K3S.js → src-RZ574OKP.js} +8 -8
- package/dist/{staticProjectServer-ERDTFP45.js → staticProjectServer-FTGTEZI4.js} +17 -17
- package/dist/studio/assets/{hyperframes-player-DEncBxR7.js → hyperframes-player-CoOdf435.js} +1 -1
- package/dist/studio/assets/{index-Cc22mgvY.js → index-CR85xg2x.js} +1 -1
- package/dist/studio/assets/{index-BABXr78Q.js → index-C_6rTpaB.js} +5 -5
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-SAKD3VKC.js → studio-api-TAWB7B23.js} +11 -11
- package/dist/{studioServer-IRI7EVOM.js → studioServer-HRQGJTBU.js} +48 -48
- package/dist/{telemetry-F4XADVAF.js → telemetry-QZ6HJF4W.js} +3 -3
- package/dist/templates/_shared/AGENTS.md +14 -19
- package/dist/templates/_shared/CLAUDE.md +14 -19
- package/dist/templates/blank/index.html +10 -4
- package/dist/{timeline-5I444RRE.js → timeline-IKUEW42T.js} +20 -19
- package/dist/{tokens-LRRYM35A.js → tokens-AUGUEWHS.js} +2 -2
- package/dist/{transcribe-44XDFNVU.js → transcribe-7734CG3N.js} +18 -18
- package/dist/{transcribe-WHYHWAB2.js → transcribe-FWU6EMEO.js} +12 -12
- package/dist/{updateCheck-7CPH3CAZ.js → updateCheck-VIPQ3FPW.js} +2 -2
- package/dist/{upgrade-WW4GQ2RI.js → upgrade-4VNDQTVO.js} +2 -2
- package/dist/{urlDownloader-OHLLP45A.js → urlDownloader-6CXL4CL7.js} +8 -8
- package/dist/{validate-VNCDH2LW.js → validate-QWCMVWID.js} +23 -23
- package/dist/{video-5OHTLL2D.js → video-245Q5WN4.js} +9 -9
- package/dist/warmCheck.js +36 -36
- package/package.json +1 -1
- package/dist/chunk-R2SQBPMH.js +0 -3805
- package/dist/skills/hyperframes/references/brief-contract.md +0 -108
- package/dist/skills/hyperframes/references/brief-format.md +0 -72
- package/dist/skills/hyperframes/references/capability-menu.md +0 -47
- package/dist/skills/hyperframes/references/frame-worker-core.md +0 -82
- package/dist/skills/hyperframes/references/intent-interview.md +0 -73
- package/dist/skills/hyperframes/references/pitch-round.md +0 -40
- package/dist/skills/hyperframes/references/production-loop.md +0 -26
- package/dist/skills/hyperframes/references/review-loop.md +0 -37
- package/dist/skills/hyperframes/references/route-briefs.md +0 -11
- package/dist/skills/hyperframes/references/routes/embedded-captions.md +0 -11
- package/dist/skills/hyperframes/references/routes/faceless-explainer.md +0 -12
- package/dist/skills/hyperframes/references/routes/general-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/motion-graphics.md +0 -11
- package/dist/skills/hyperframes/references/routes/music-to-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/pr-to-video.md +0 -28
- package/dist/skills/hyperframes/references/routes/product-launch-video.md +0 -13
- package/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +0 -9
- package/dist/skills/hyperframes/references/routes/slideshow.md +0 -11
- package/dist/skills/hyperframes/references/routes/talking-head-recut.md +0 -11
- package/dist/skills/hyperframes/references/script-format.md +0 -52
- package/dist/skills/hyperframes/references/subagent-dispatch.md +0 -35
- package/dist/skills/hyperframes/references/workflow-catalog.md +0 -10
- package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +0 -176
- package/dist/skills/media-use/audio/scripts/lib/host-audio.mjs +0 -28
- package/dist/skills/media-use/audio/scripts/lib/host-audio.test.mjs +0 -106
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Captions
|
|
2
|
+
|
|
3
|
+
## Words and timings
|
|
4
|
+
|
|
5
|
+
- `npx hyperframes transcribe <file> --json` and a HeyGen voiceover (`/media-use`) give every word's start and end. Work from those as `[{ "id": "w0", "text": "Hello", "start": 0.0, "end": 0.5 }, …]`.
|
|
6
|
+
- Local transcription defaults to `small.en`, which **translates** non-English speech into English. Pass the model: `npx hyperframes transcribe <file> --model small.en` for English, `--model small --language <code>` otherwise, `--model medium.en` for speech over music. It writes `assets/transcript.json` (its JSON names the path) and overwrites it on the next run; `--to srt` or `--to vtt` writes a sidecar.
|
|
7
|
+
- For Chinese, Japanese and other unspaced scripts, local transcription returns a whole sentence as one "word", sometimes in the other script (Traditional for Simplified speech). Split each segment's text into short phrases and spread its time across them by character count; check the characters against what is said.
|
|
8
|
+
- Whisper invents "Thank you." over silence and repeats lines over a silent tail: drop words that start inside a final silence (`silencedetect=noise=-35dB:d=0.6`; real speech sits around −16 to −26 dB).
|
|
9
|
+
- Never put two words in one timed entry, and match transcript words to caption words by position, not text, or a repeated word takes the wrong time.
|
|
10
|
+
- Read the transcript before using it. More than 20% `♪` or `�` tokens, or nonsense words, means it failed: retry with a larger model, or take lyrics from the person. Drop non-word tokens before building groups.
|
|
11
|
+
|
|
12
|
+
## Structure
|
|
13
|
+
|
|
14
|
+
- One sub-composition host with `data-track-kind="captions"` holds every caption group, so Studio shows them on one captions track.
|
|
15
|
+
- Ready-made styles: `npx hyperframes catalog --tag caption-style --json`. An installed one is source you can restyle.
|
|
16
|
+
|
|
17
|
+
## Groups
|
|
18
|
+
|
|
19
|
+
- 2–3 words for high energy, 3–5 conversational, 4–6 calm. Break at a sentence end, a pause of 150 ms or more, or the word limit.
|
|
20
|
+
- One group visible at a time. A group opens at or before its first word's start and closes at or after its last word's end. A caption at exactly 0 s looks pre-existing: start 0.1–0.3 s in.
|
|
21
|
+
- Every group ends with a hard kill after its exit, or a stale group can stay on screen:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
tl.to(group, { opacity: 0, duration: 0.12, ease: "power2.in" }, end - 0.12);
|
|
25
|
+
tl.set(group, { opacity: 0, visibility: "hidden" }, end);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`tl.set` is an instant flip, so setting `visibility` on the group is fine; never tween it on a `.clip`.
|
|
29
|
+
|
|
30
|
+
## Fit and place
|
|
31
|
+
|
|
32
|
+
- Size each group to fit: `window.__hyperframes.fitTextFontSize(text, { fontFamily, fontWeight, maxWidth })` returns `{ fontSize }`. Defaults: `maxWidth` 1600 landscape, 900 portrait; base 78, minimum 42, step 2. When a word scales up for emphasis, divide `maxWidth` by that scale.
|
|
33
|
+
- A full-width absolute container, centred with text alignment. Never `left: 50%; transform: translateX(-50%)`, which clips at the frame edges.
|
|
34
|
+
- `overflow: visible`, not `hidden`, which cuts off scaled words and glows.
|
|
35
|
+
- Landscape: 80–120 px from the bottom. Portrait: about 600–700 px from the bottom. Never over the speaker's face; inside the 80% title-safe box.
|
|
36
|
+
- Position each group absolutely. In a flex column a group hidden with `visibility: hidden` still takes space, so the next one lands lower. In a stack that accumulates, groups in one block share one exit time, or the stack reflows.
|
|
37
|
+
- Fade the group or its words, not both: the opacities multiply and read as a pop. A gradient or `background-clip: text` fill goes on the inner text span, not the transformed container.
|
|
38
|
+
- Over footage, choose the blend by the brightness (0–255) behind the text: under 60 `screen`, 60–180 `overlay`, over 180 `normal` with opaque colour. Plain subtitles above brightness 60 get a scrim sized to the text (30–40%), never a full-width bar.
|
|
39
|
+
- Footage may already carry burned-in subtitles only mid-clip: scan a 1 fps contact sheet before placing captions.
|
|
40
|
+
|
|
41
|
+
## Text behind the speaker
|
|
42
|
+
|
|
43
|
+
- Stack the video, then the captions, then a cutout of the person from `npx hyperframes remove-background` (`/media-use`), ordered by `z-index`. Shake or punch in the video and the cutout together in one wrapper.
|
|
44
|
+
- `check` treats a `<video>` as opaque across its whole box, so a WebM cutout fails every caption behind it with `text_occluded`: put `data-layout-allow-occlusion` on the cutout and judge from `snapshot`.
|
|
45
|
+
- A big word behind the head reads best 30–55% covered: under about 15% it floats, over about 65% it is eaten. Re-lay out when a content word is 80% covered, or two adjacent words 50% each. Measure the rendered word boxes against the matte over each caption's own time window (heads move: one clip went from y=224 to y=96 in 8 s); estimates from character widths were wrong both ways.
|
|
46
|
+
- The matte model drops mic arms, lets large rigs near the body leak in, and flickers on held objects. Its first run downloads 168 MB, and it runs at about 2 fps at 1080p on CPU.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Films from a source: measured facts
|
|
2
|
+
|
|
3
|
+
What is specific to HyperFrames, or was measured on shipped films, when one video is made from a website, a script, a pull request, a music track, a real place or a short motion brief. The story comes first, from `story.md`; the shape of each kind of film is in `types/`. Motion craft is in `motion.md`, look in `look.md`, sound in `sound.md`, captions in `captions.md`.
|
|
4
|
+
|
|
5
|
+
## Script and pacing
|
|
6
|
+
|
|
7
|
+
- TTS reads about 2.2 words a second. Keep a scene to about 19 words (9 s); at most two scenes may reach 26 words (12 s). 30–90 s is about 155 words or fewer; a whole film about 400 at most.
|
|
8
|
+
- A voiceover longer than its visuals makes the visuals pad with idle drift. Trim the script; never stretch the motion.
|
|
9
|
+
- Everything on screen in the first quarter of a scene, then frozen, reads as a slideshow. Reveal each piece when the voiceover names it, across the back half of the scene; write the voiceover as separate phrases so it has cue points.
|
|
10
|
+
- Up to about six short scenes, build them yourself in one context (about 9 min for five, against about 21 min split across sub-agents). Beyond that, give each worker two or three scenes and start them all at once; a second wave nearly doubles the time.
|
|
11
|
+
|
|
12
|
+
## From a website
|
|
13
|
+
|
|
14
|
+
- `npx hyperframes capture <url> --json` writes `screenshots/full-page.png`: a 1x plate of the whole page, taken after the scroll pass with sticky and fixed elements made static, pixel-exact for a 1920-wide viewport travelling down it. It is skipped above 16384 px tall (use `scroll-*.png`); pushing in past 1:1 needs its own 2x capture of that region.
|
|
15
|
+
- To show the site as it is, use its screenshots. Rebuilding the page in HTML drifts from the real layout; rebuild only the part that moves, or overlay captured assets at measured positions.
|
|
16
|
+
- `--capture-budget` (default 120000 ms) bounds work after navigation; `--timeout` bounds navigation only. Videos are not downloaded: `capture --video <dir> --list`, then `--index N`. `asset-descriptions.md` has vision captions only when `OPENROUTER_API_KEY`, `GEMINI_API_KEY` or `GOOGLE_API_KEY` is set.
|
|
17
|
+
- "very little text content" with an empty asset catalog means the capture is unusable even when it says `ok: true`. A `logo-*.svg` name is a guess from page structure, not proof.
|
|
18
|
+
- Brand tokens: link blue `#0000EE` and status reds and greens are never the accent; the accent is the colour that recurs across the most roles. Icon fonts (Font Awesome, icomoon, webflow-icons) are never the display or body face; a captured monospace goes to the mono role. Use only weights the brand font ships, or 600/700 render as fake bold. Every preset has a light ground: for a dark brand, swap ground and ink.
|
|
19
|
+
- Capture keeps each `@font-face` rule, `unicode-range` subsets included, in `extracted/page.html`; copying the font files alone loses which characters each covers. Name copied fonts by family, weight and style, or an upright and an italic "Regular" collide.
|
|
20
|
+
|
|
21
|
+
## From a pull request
|
|
22
|
+
|
|
23
|
+
- `gh pr view --json files` stops at about 100 files: page `gh api repos/{owner}/{repo}/pulls/N/files`.
|
|
24
|
+
- The PR author only opened it: credit commit authors, by commit count (`commits[].authors[]`); skip bots, lockfiles and `dist/`. Reviewers come as logins; names via `gh api users/<login> --jq .name`. TTS reads `@handles` aloud, so speak names.
|
|
25
|
+
- Never invent a version. Use the first non-draft release published at or after the merge; else the default branch's `package.json` version as "unreleased"; else only the PR URL.
|
|
26
|
+
- Length from size (additions + deletions), as a ceiling: ≲50 lines 20–40 s, 50–200 40–70 s, 200–600 70–110 s, ≳600 lines or 25+ files 110–180 s.
|
|
27
|
+
- Show 2–4 hunks of 4–12 lines; counts like +N/−M go on a stat card, not into the voiceover.
|
|
28
|
+
- The `code-*` registry blocks (`npx hyperframes catalog --query code --json`) are 1920×1080 scenes driven by `window.__TOKENS` (Shiki tokens, `github-dark`; `fontStyle` bit 1 italic, bit 2 bold) and `window.__BLOCK` (`{id, effect, seq, line?, duration}`). `code-diff` and `code-morph` need at least two states; `code-highlight` counts lines from 0 and `code-scroll` from 1; `code-typing` types at a fixed speed, so check characters × speed against the scene's duration. They reserve no caption band: inset the panel when captions are on.
|
|
29
|
+
|
|
30
|
+
## On music
|
|
31
|
+
|
|
32
|
+
- Library music, HeyGen's included, comes as 15–30 s loops: loop the bed to the film with a 0.4 s fade-in and a 1.5 s fade-out. A track whose opening is a quiet build drains a short film: start from a stronger later section.
|
|
33
|
+
- Trust beat times only on rhythmic stretches; on calm music the tracker invents a metronome, often at double tempo (`npx hyperframes beats` reports `bpmConfidence`). Cut there on phrase and energy changes; `npx hyperframes audio --only sections,onsets,moments --json` finds them.
|
|
34
|
+
- A move that must land on a hit starts 40–190 ms early; a reaction starts 0–45 ms after. The hit itself is a 0 ms `tl.set`: easing a hit kills it. Scenes tile the track with no gaps.
|
|
35
|
+
- A word meant to be read holds at least one beat. Any single treatment goes stale after about 6 s: lengthen a section with a hold or a new treatment, never by slowing tweens. On rhythmic sections give footage one clip per strong beat; on calm ones one slow push from 1.0 to 1.08.
|
|
36
|
+
|
|
37
|
+
## Maps and real places
|
|
38
|
+
|
|
39
|
+
- A real place (a city, a building, a route, a zoom from the globe to a street) is shown on real imagery. Vector outlines from Natural Earth or GeoJSON read as a diagram and lose the place; keep them for borders and labels drawn on top.
|
|
40
|
+
- Live tiles change between renders, so bake the camera move to video with `scripts/bake-basemap.mjs` (MapLibre over Esri satellite or Carto tiles; writes an all-intra MP4 and `<NAME>-coords.json`). From space down to a street: `PROJECTION=globe FROM="lng,lat" CENTER="lng,lat" ZSTART=1.85 ZEND=16` (Earth in a starfield turns from FROM to CENTER, then dives); `--help` lists the rest. It needs network for the tiles and takes well under a second a frame, so bake once, keep the MP4, and run one bake at a time. Draw borders, pins and labels as a live SVG from those coordinates, animating them only while the camera holds.
|
|
41
|
+
- Credit the imagery on screen ("Esri, Maxar, Earthstar Geographics" or "© CARTO, © OpenStreetMap") in small type on a soft dark backing, so it holds contrast over bright tiles; mark it `data-layout-ignore` so the type floor in `check` skips it.
|
|
42
|
+
|
|
43
|
+
## Short motion pieces
|
|
44
|
+
|
|
45
|
+
- Kinetic type takes 3–7 English words or 4–12 Chinese characters per scene. A count-up runs 1.2–1.6 s, then holds, landing on a downbeat or a hard stop.
|
|
46
|
+
- A highlighter that wraps across lines: tween a custom property on a `background-size` band with `box-decoration-break: clone`. `getTotalLength()` can return 0 before layout; give line draw-ons a fallback.
|
|
47
|
+
- A point in an image guessed directly misses by 16–24% of the frame. `scripts/locate.mjs` narrows it with a numbered 9×9 grid, then 6×6 on the crop, then a check render (about 2% error).
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Composition format
|
|
2
|
+
|
|
3
|
+
The detail behind the contract in `SKILL.md`. Full references: `npx hyperframes docs compositions`, `docs data-attributes`, `docs troubleshooting`.
|
|
4
|
+
|
|
5
|
+
## Shape of a project
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- index.html: a normal document; declares variables, mounts scenes -->
|
|
9
|
+
<html
|
|
10
|
+
data-composition-variables='[{"id":"headline","type":"string","label":"Headline","default":"…"}]'
|
|
11
|
+
>
|
|
12
|
+
<body>
|
|
13
|
+
<div
|
|
14
|
+
id="root"
|
|
15
|
+
data-composition-id="main"
|
|
16
|
+
data-start="0"
|
|
17
|
+
data-duration="12"
|
|
18
|
+
data-width="1920"
|
|
19
|
+
data-height="1080"
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
id="intro"
|
|
23
|
+
data-composition-id="intro"
|
|
24
|
+
data-composition-src="compositions/intro.html"
|
|
25
|
+
data-start="0"
|
|
26
|
+
data-duration="4"
|
|
27
|
+
data-track-index="1"
|
|
28
|
+
data-width="1920"
|
|
29
|
+
data-height="1080"
|
|
30
|
+
></div>
|
|
31
|
+
</div>
|
|
32
|
+
<script>
|
|
33
|
+
window.__timelines["main"] = gsap.timeline({ paused: true });
|
|
34
|
+
</script>
|
|
35
|
+
</body>
|
|
36
|
+
</html>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<!-- compositions/intro.html: everything inside <template> -->
|
|
41
|
+
<template>
|
|
42
|
+
<style>
|
|
43
|
+
#root {
|
|
44
|
+
position: absolute;
|
|
45
|
+
inset: 0;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
<div id="root" data-composition-id="intro" data-width="1920" data-height="1080">
|
|
49
|
+
<h1 id="headline" class="clip" data-start="0.4" data-duration="3" data-var-text="headline">
|
|
50
|
+
…
|
|
51
|
+
</h1>
|
|
52
|
+
</div>
|
|
53
|
+
<script>
|
|
54
|
+
const tl = gsap.timeline({ paused: true });
|
|
55
|
+
tl.fromTo(
|
|
56
|
+
"#headline",
|
|
57
|
+
{ opacity: 0, filter: "blur(8px)" },
|
|
58
|
+
{ opacity: 1, filter: "blur(0px)", duration: 0.18, ease: "power4.out" },
|
|
59
|
+
0.4,
|
|
60
|
+
);
|
|
61
|
+
window.__timelines["intro"] = tl;
|
|
62
|
+
</script>
|
|
63
|
+
</template>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Give the host, the scene root and the timeline key the same id. A host id that differs from its scene's makes each render wait 45 s per scene, then show static frames. Styles and scripts outside `<template>` are dropped.
|
|
67
|
+
- Size the scene root with `inset: 0`, never hard-coded pixels; the canvas is `data-width` × `data-height`.
|
|
68
|
+
- Keep ids unique across the assembled page (prefix them: `#intro-title`). A scene's timeline can't reach elements outside its file.
|
|
69
|
+
- Use `fromTo`, not `from`, inside a scene: the host re-seeks the scene each time it shows, and `from` records its start state once, so it drifts on seek-back.
|
|
70
|
+
- Never `add()` a scene's timeline to the root's; the runtime drives each scene itself, and nesting seeks it twice.
|
|
71
|
+
|
|
72
|
+
## Attributes you'll use most
|
|
73
|
+
|
|
74
|
+
| Attribute | Meaning |
|
|
75
|
+
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| `data-start`, `data-duration` | Seconds, local to the file that declares the element |
|
|
77
|
+
| `data-track-index` | Studio lane only; paint order is CSS `z-index` |
|
|
78
|
+
| `data-track-kind` | `graphics` or `captions` on scene hosts (video and audio come from the tag) |
|
|
79
|
+
| `data-composition-src`, `data-variable-values` | Mount a scene file; per-mount variable values (a JSON object) |
|
|
80
|
+
| `data-media-start` | Offset into the source media (a trim) |
|
|
81
|
+
| `data-playback-rate` | Constant speed, 0.1–10 |
|
|
82
|
+
| `data-has-audio="true"` | A `<video>` keeps its own sound; a timed `<video>` with neither this nor `muted` fails lint |
|
|
83
|
+
| `data-volume`, `data-fade-in`, `data-fade-out` | Gain (1 = 0 dB, up to 3.98 = +12 dB) and edge fades; envelopes use `data-automation` (`/media-use`) |
|
|
84
|
+
| `data-link`, `data-sync-origin` | A video and audio edited as one (see Linked clips) |
|
|
85
|
+
| `data-hidden` | Hidden in preview and render; reversible |
|
|
86
|
+
| `data-no-timeline` | On the root of a still composition: no timeline to wait for |
|
|
87
|
+
|
|
88
|
+
## Variables
|
|
89
|
+
|
|
90
|
+
- Declare an array of `{id, type, label, default}`: the video's own on `index.html`'s `<html>`, a scene or block file's on that file's `<html>` (or root element), where they stay inside each mount. Types: `string` (`placeholder`, `maxLength`), `number` (`min`, `max`, `step`, `unit`), `color`, `boolean`, `enum` (`options: [{value, label}]`).
|
|
91
|
+
- Bind without script: `data-var-text="id"`, `data-var-src="id"` (keep a real fallback `src` on media with audio), `var(--id)` in CSS; for logic, `window.__hyperframes.getVariables()` once at init.
|
|
92
|
+
- Values are an object keyed by id. A host's `data-variable-values` sets one mount; Studio's Variables panel and batch renders set only the root's variables, so to vary a block, change its host's values. Variables can't change the root's `data-duration`.
|
|
93
|
+
|
|
94
|
+
## Fonts
|
|
95
|
+
|
|
96
|
+
- Bundled, so they resolve by name: Inter, Montserrat, Outfit, Nunito, Oswald, League Gothic, Archivo Black, Space Mono, IBM Plex Mono, JetBrains Mono, EB Garamond, Playfair Display, Source Code Pro, Noto Sans JP, Roboto, Open Sans, Lato, Poppins. Common system fonts (Helvetica, Arial, Times, Menlo and the like) are swapped for the nearest of these.
|
|
97
|
+
- Any other family needs `@font-face` in the file that uses it, or lint fails `font_family_without_font_face`: `src: url('assets/fonts/x.woff2')` for a file in the project (a capture's own fonts, or one you download there), or `local('Exact Name')` for a font installed on this machine.
|
|
98
|
+
|
|
99
|
+
## Timing and the timeline
|
|
100
|
+
|
|
101
|
+
- A clip shows over `[start, start + duration)`: an end state landing exactly on its end is never rendered.
|
|
102
|
+
- Only a composition's root timeline is paused; timelines nested inside it are not. Never `tl.play()`.
|
|
103
|
+
- A scene's clock starts at 0 at its host's `data-start`; media `data-start` is local to its composition. `<video>` / `<audio>` without `data-duration` play their full length; an `<img>` without one lasts 3 s.
|
|
104
|
+
- A host's `data-duration` is the scene's slot: a shorter scene timeline holds its last frame, and a slot shorter than the video goes blank when it ends.
|
|
105
|
+
- Root children with `data-start` are laid out full-frame by the runtime; an untimed full-bleed background needs `position: absolute; inset: 0` or it collapses to nothing.
|
|
106
|
+
- A fill on the composition root is dropped when the video has shader transitions or HDR media; put it on a full-bleed child.
|
|
107
|
+
- `data-start="intro + 0.5"` starts after `intro` ends (spaces required). A typo, a missing id or a cycle silently resolves to 0, so snapshot what you time this way.
|
|
108
|
+
- A clip nested inside another timed element counts its `data-start` from the composition, not from that element, and shows only while that element shows. `timeline` lists it under its parent and warns `never visible` when the windows miss (`lint`: `nested_clip_never_visible`).
|
|
109
|
+
- `npx hyperframes timeline --json` lists every clip by kind with `absStart`, `absEnd`, `file`, `src`, `playbackRate`, `nested`, `host` and `durationSource`: read it instead of opening every file. It reads one level of nesting (a deeper scene shows `children=unread`); `laneError` means a `data-automation` or `data-fx-chain` that doesn't parse.
|
|
110
|
+
|
|
111
|
+
## Adding media
|
|
112
|
+
|
|
113
|
+
Write what a Studio drop writes, so the clip behaves like one the person dropped:
|
|
114
|
+
|
|
115
|
+
- `id`, `class="clip"`, `data-start` (the playhead or the requested time, never a silent 0) and `data-track-index`. Video with sound: `playsinline data-has-audio="true"`; silent footage: `muted playsinline`. Audio: `data-volume="1"`.
|
|
116
|
+
- Images and video fill the frame: `position: absolute; left: 0; top: 0`, width and height equal to the canvas, `object-fit: contain`.
|
|
117
|
+
- `z-index` is the number of top-level clips already in that file plus one.
|
|
118
|
+
- Raise the root's `data-duration` to cover the new clip's end, or it never plays.
|
|
119
|
+
|
|
120
|
+
## Linked clips
|
|
121
|
+
|
|
122
|
+
Studio's Detach audio writes a muted `<video>` and an `<audio>` of the same file sharing `data-link` and `data-sync-origin`; Studio moves, trims, splits and deletes them as one.
|
|
123
|
+
|
|
124
|
+
- Prefer one `<video data-has-audio="true">`; link only when the sound needs its own track, volume or effects.
|
|
125
|
+
- Every member keeps the same `data-start`, `data-duration`, `data-media-start` and `data-playback-rate`; retime them all together.
|
|
126
|
+
- Unlink by removing `data-link` from every member. Leave `data-sync-origin` alone while they are still one source.
|
|
127
|
+
|
|
128
|
+
## Layout audit opt-outs
|
|
129
|
+
|
|
130
|
+
`check` measures boxes at sampled times; `overflow: hidden` does not silence a finding. Use the narrowest opt-out:
|
|
131
|
+
|
|
132
|
+
| Attribute | Silences |
|
|
133
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
134
|
+
| `data-layout-allow-overflow` | Overflow on the element and every descendant, including text-clipping checks: keep it on the smallest decorative wrapper |
|
|
135
|
+
| `data-layout-bleed="true"` | One intentional crop of primary text |
|
|
136
|
+
| `data-layout-allow-overlap` | Deliberate text layering, on that block only (not inherited) |
|
|
137
|
+
| `data-layout-allow-occlusion` | An element meant to cover text |
|
|
138
|
+
| `data-layout-allow-caption-zone` | Intentional copy in the caption band |
|
|
139
|
+
| `data-layout-ignore` | A decorative element never audited |
|
|
140
|
+
|
|
141
|
+
## Lint errors you'll meet first
|
|
142
|
+
|
|
143
|
+
| Rule | Fix |
|
|
144
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
|
|
145
|
+
| `video_missing_muted` | A timed `<video>` gets `data-has-audio="true"` or `muted` |
|
|
146
|
+
| `gsap_css_transform_conflict` | Set the start inside the tween (`gsap.fromTo`) instead of a CSS `transform` |
|
|
147
|
+
| `gsap_animates_clip_element` | Animate a child of the `.clip`, or its `opacity` |
|
|
148
|
+
| `video_nested_in_timed_element` | Time the `<video>` or its wrapper, not both |
|
|
149
|
+
| `media_missing_id`, `media_crossorigin_breaks_preview` | Give every `<audio>` an `id`; drop `crossorigin` |
|
|
150
|
+
| `gsap_timeline_registered_before_async_build` | Register the timeline at the end of the async callback |
|
|
151
|
+
| `standalone_composition_wrapped_in_template` | Only scene files use `<template>` |
|
|
152
|
+
| `subcomposition_root_styled_by_class` | Style a scene's root as `#root` |
|
|
153
|
+
| `subcomposition_blanks_before_host` | Make the scene's slot span the time it should show |
|
|
154
|
+
| `clip_ends_past_root_duration` | Raise the root's `data-duration` |
|
|
155
|
+
| `linked_clips_out_of_sync`, `linked_clip_orphan` | Retime every linked member together; unlink from all of them |
|
|
156
|
+
| `sweep_static` | A 3 s+ video with no visible change: spread the motion, or mark a still composition `data-no-timeline` |
|
|
157
|
+
| `missing_data_no_timeline` | A root or host with no timeline: add `data-no-timeline`, or every render waits 45 s |
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# The look
|
|
2
|
+
|
|
3
|
+
Left alone, the same brief comes out with the same look run after run, and banning that look only moves it to the next default. Outside input breaks it, in this order: the project's design spec, a real brand, a reference image or film the person gave you, the subject's own world. Settle it before the first scene, as numbers in the LOOK line (below).
|
|
4
|
+
|
|
5
|
+
## The project's design spec
|
|
6
|
+
|
|
7
|
+
Read the first of `frame.md`, `design.md`, `DESIGN.md` at the project root that exists; ignore the rest.
|
|
8
|
+
|
|
9
|
+
- **Frontmatter is normative**: `colors`, `typography`, `spacing`, `components`. Quote hex values, families and weights exactly; never round or invent them.
|
|
10
|
+
- **The prose is intent**: what the look is for, Do's and Don'ts. Follow it for judgment, not values.
|
|
11
|
+
- **Brand, not layout**: hex, fonts, weight relationships and Do's and Don'ts are strict; type sizes, spacing, border weight and decoration are yours to scale for video. A 1px border or a 6% shadow from a web page vanishes on screen.
|
|
12
|
+
|
|
13
|
+
## From a brand
|
|
14
|
+
|
|
15
|
+
- A website: `npx hyperframes capture <url> --json` writes screenshots, the copy (`extracted/visible-text.txt`), images, logos, `extracted/tokens.json` (colours, fonts) and `extracted/design-styles.json` under its output folder. Look at the screenshots before choosing anything. A capture that exits non-zero, prints `ok: false` or writes `BLOCKED.md` failed: take no brand data from its partial files.
|
|
16
|
+
- Figma: `npx hyperframes figma tokens <fileKey>` (`/figma`).
|
|
17
|
+
- Images the person attached: take palette and type from what you see.
|
|
18
|
+
|
|
19
|
+
Use the brand's own fonts when the capture shipped their files or they are bundled (`format.md`); otherwise download the family's `.woff2` into `assets/fonts/` with an `@font-face`, or pick the closest bundled family and say so.
|
|
20
|
+
|
|
21
|
+
## From a reference
|
|
22
|
+
|
|
23
|
+
A reference film or image gives its grammar, never its content: shot lengths, how titles enter and leave, the transitions, the palette roles, the type's scale and weight. Snapshot it next to yours (`snapshot --at <t,…> --against ref.mp4`) and write the grammar down, marking what you measured apart from what you guessed.
|
|
24
|
+
|
|
25
|
+
## Presets
|
|
26
|
+
|
|
27
|
+
The presets are slide-deck looks: use one when the person names it, or for a deck (`/slideshow`), never as the fallback for a film without a brand. Each folder in `../assets/frame-presets/` holds a `FRAME.md` spec, a `caption-skin.html` and a `frame-showcase.html` contact sheet. To use one, copy its `FRAME.md` to the project root as `frame.md`, then read it as above; its fonts that aren't bundled need `@font-face` files. The two HTML files are reference code: read them for treatments, never mount them.
|
|
28
|
+
|
|
29
|
+
| Preset | Look |
|
|
30
|
+
| ------------------- | ---------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `biennale-yellow` | Museum catalogue: parchment, deep indigo ink, solar-yellow blooms, Instrument Serif, hairlines |
|
|
32
|
+
| `blockframe` | Loud neobrutalist: 4px black borders, hard shadows, candy pastels, Inter 900 caps |
|
|
33
|
+
| `blue-professional` | Consulting restraint: cream canvas, one cobalt accent, Space Grotesk + Inter, tinted cards |
|
|
34
|
+
| `bold-poster` | Vintage editorial poster: Shrikhand tilted display, Baskerville, tomato red, double borders |
|
|
35
|
+
| `broadside` | Protest poster: ink-black and fire-orange planes, giant lowercase Barlow 900, mono chrome |
|
|
36
|
+
| `capsule` | Friendly editorial: every container a pill, cream, nine candy accents, Bodoni Moda |
|
|
37
|
+
| `cartesian` | Quiet catalogue: warm-stone palette, Playfair + Inter, taupe hairline grid, compass rings |
|
|
38
|
+
| `cobalt-grid` | Two-colour risograph: cream paper, cobalt ink, graph-paper grid, Newsreader serif |
|
|
39
|
+
| `code-editorial` | Developer brand book: warm paper, scarce terracotta, EB Garamond, navy code surface |
|
|
40
|
+
| `coral` | Bold magazine: coral, ink and cream planes at hard edges, Bebas Neue, giant numerals |
|
|
41
|
+
| `creative-mode` | Sparse neobrutalist: cream, 4px ink borders, Archivo Black caps, rationed accents |
|
|
42
|
+
| `daisy-days` | Picture book: charcoal outlines, sunny pastels, Fredoka One, hand-drawn ornaments |
|
|
43
|
+
| `editorial-forest` | Literary: green, pink and cream, Source Serif display, mono chrome, flat paper |
|
|
44
|
+
|
|
45
|
+
## The LOOK line
|
|
46
|
+
|
|
47
|
+
With no design spec, the look is the LOOK line of `SPEC.md` (`spec.md`), taken from the brand, the reference or the subject itself: its era, its materials, where it would be shown. Every part is a number (hex, px, %, a named face and weight), the ground and the hero come from a medium rather than from effects, and the BANNED line keeps it off the defaults. Inter, Space Grotesk, Instrument Serif, Geist and JetBrains Mono are where generated design lands; use them when the brand does, not by default. Copy the palette and the faces into the root variables below.
|
|
48
|
+
|
|
49
|
+
## Video facts
|
|
50
|
+
|
|
51
|
+
- Full-screen linear gradients on dark grounds band under H.264; use a radial gradient, a solid fill or a solid plus a local glow.
|
|
52
|
+
- An accent at 5% opacity disappears in compression: 15–25% for atmosphere, full saturation for the focal element.
|
|
53
|
+
|
|
54
|
+
## Make it re-brandable
|
|
55
|
+
|
|
56
|
+
Declare palette and fonts as variables on the root `<html>` and use them everywhere, so the person can re-brand from Studio's Variables panel:
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<html
|
|
60
|
+
data-composition-variables='[
|
|
61
|
+
{"id":"color-ground","type":"color","label":"Background","default":"<ground from the plan>"},
|
|
62
|
+
{"id":"color-ink","type":"color","label":"Text","default":"<ink from the plan>"},
|
|
63
|
+
{"id":"color-accent","type":"color","label":"Accent","default":"<accent from the plan>"},
|
|
64
|
+
{"id":"font-display","type":"string","label":"Display font","default":"<display face from the plan>"}
|
|
65
|
+
]'
|
|
66
|
+
></html>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Reference them as `var(--color-accent)`; point a registry item's colour and font variables at the same values.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Motion
|
|
2
|
+
|
|
3
|
+
## Motion craft
|
|
4
|
+
|
|
5
|
+
Measured frame by frame from the official HyperFrames launch films. These are defaults: a reference the person gave, or a Moment that does otherwise on purpose, wins for its own beat.
|
|
6
|
+
|
|
7
|
+
- **Moves**: a fast move takes 0.3–0.6 s and carries motion blur on its own ease, peaking at its fastest frame: 6–12 px on text-sized elements, 15–20 px full-frame, horizontal-only on a horizontal move. One move is one tween.
|
|
8
|
+
- **Arrive slow, leave clean**: long-tailed ease-outs on arrivals; landing takes longer than leaving. An exit is one smooth motion, never slide, stop, then leave. Entrances that are too snappy read as glitches; slowing the whole video by about a second often fixes it.
|
|
9
|
+
- **Ease by role**: an arrival lands on a long tail (`expo.out`, `power4.out`), a camera move or a colour flood eases both ways (`power2.inOut`), a zoom through or an exit accelerates (`power3.in`). The same `power2.out` at 0.5 s on everything is the flat default that makes a film feel generated. Linear only for rotation, progress and constant speed that is the point.
|
|
10
|
+
- **Springs** are named by damping ratio: 1.0 never bounces, 0.7-0.85 reads premium, 0.4-0.6 playful, under 0.3 a cartoon. Position and size may bounce; opacity and colour never do. GSAP's `elastic.out(1, 0.5)` and `back.out(1.4)` are the nearest built-ins; a closed-form spring of `t` keeps any frame renderable on its own.
|
|
11
|
+
- **Exits** are 40-50% shorter than their entrances. **Overlap**: the next element starts when the previous is 30-50% done; fully sequential looks robotic, all at once looks cheap. **Stagger**: letters a frame apart, words 60-120 ms, list items 40-80 ms.
|
|
12
|
+
- **Beat grid**: frames per beat = fps × 60 / BPM; compute each beat from its index and round it, never add a rounded beat repeatedly (at 128 BPM and 30 fps that drifts 2 frames in 32 beats). Cut on the beat, change the layout on the bar.
|
|
13
|
+
- **Cuts**: cut at the fastest frame of a move, with matching direction and speed on both sides. A click into a new screen is a match cut on the click's rebound; the new screen comes in slightly large and settles.
|
|
14
|
+
- **Titles**: a landed title is dead still; the motion moves to the next element, the camera or the world behind. Vary the entrance within a film, never a fade and slide-up for each:
|
|
15
|
+
- per word: `blur(6px)` → 0 and opacity 0 → 1 in 0.13 s, 0.067 s apart, no translate;
|
|
16
|
+
- per word from light grey to ink, 0.07–0.1 s apart, no position change;
|
|
17
|
+
- the whole line blurring in, 8 px → 0 in 0.13–0.2 s;
|
|
18
|
+
- per letter for a name, 0.1 s apart, opacity 0.3 → 1 with a slight blur;
|
|
19
|
+
- behind the subject: the title between the plate and a matte of the person;
|
|
20
|
+
- one word of the sentence rolling through options like a slot machine, about 0.1 s a roll.
|
|
21
|
+
- **Holds**: a line the viewer must read holds about 0.5 s plus 0.3 s a word, the film's last line at least 2 s; a one- or two-word chapter line may hold 0.4 s. Then exit with a blur-out and fade of 0.13–0.25 s, word by word, or with the scene's move.
|
|
22
|
+
- **Title size**: 4–9% of the frame height, one or two lines; quiet lines at 2.5–4% against hero words that fill 60–90% of the width. One highlighted word in the accent colour, which carries meaning.
|
|
23
|
+
- **Rhythm**: contrast speeds. Montages cut every 0.13–0.8 s; a demo holds one framing for 7–10 s while the UI acts; shots average 1.8–3 s with motion inside them. Hold 0.3–0.75 s before the payoff, which plays at normal speed.
|
|
24
|
+
- **Continuous motion that works**: the product's UI working, footage playing, a character acting, a 3D world turning, a slow orbit of a background stage (3–5° a second).
|
|
25
|
+
- **Defaults that look generated**: breathing, floating or pulsing loops standing in for motion on titles and UI; titles that keep sliding or scaling after they land; a slow creeping scale on a title or a slow push late in a scene; bounce on UI; click rings; every scene entering the same way; every element fading and sliding up. A character's idle and overshoot are acting, not these (`types/character.md`).
|
|
26
|
+
|
|
27
|
+
## Transitions with a cause
|
|
28
|
+
|
|
29
|
+
Use 3–5 kinds in a film, each caused by something on screen. Hard cuts belong inside a scene (punch-ins); at most a third of the seams between beats are hard cuts, and worlds never crossfade into each other. Measured on the official films:
|
|
30
|
+
|
|
31
|
+
| Transition | How it is built |
|
|
32
|
+
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| Zoom through a button | the camera tracks to the button with blur (0.6 s), then the button scales from ~8% to ~250% of the frame in 0.35 s, strong ease-in; its fill becomes the next frame |
|
|
34
|
+
| Object becomes the world | a pill or card grows past the frame in 0.65 s, ease-in-out, its radius shrinking; what was around it blurs ~15 px and fades in 0.3 s; the new content fades in while it still grows |
|
|
35
|
+
| Morph | one container widens into the next (icon card → prompt box, ~110 → ~880 px in 0.2 s `power3.out`) with a horizontal blur 12 → 0 |
|
|
36
|
+
| Carry across | the result shrinks 1 → 0.6 with blur peaking at 6 px mid-move and lands inside the next app as it builds around it |
|
|
37
|
+
| Colour flood | the hero object stays while the whole ground changes colour in ~0.4 s `power2.inOut` |
|
|
38
|
+
| Whip | a horizontal or vertical smear of 0.13–0.3 s; the arriving element lands blurred and sharpens in ~0.13 s |
|
|
39
|
+
| Iris from the click | `clip-path: circle()` opens from the clicked point onto the next world in 0.15 s |
|
|
40
|
+
| Dip cut | the outgoing frame darkens ~40% for 3 frames before a hard cut, so the cut reads as meant |
|
|
41
|
+
| Blur swap on one stage | out: opacity → 0 with ~8 px blur in 0.13–0.2 s; in: blur → 0 in 0.13 s; the ground never cuts |
|
|
42
|
+
|
|
43
|
+
Registry versions: `npx hyperframes catalog --tag transition --json`.
|
|
44
|
+
|
|
45
|
+
| The person says | Change |
|
|
46
|
+
| ---------------------- | ------------------------------------------------------------------------------ |
|
|
47
|
+
| "too fast" | Slow every zoom and pan to 0.7× of its speed, nothing else |
|
|
48
|
+
| "speed this up" | Speed the content and shorten the beat by the same amount; later beats move up |
|
|
49
|
+
| "the titles move" | Land them, then hold them dead still until they leave |
|
|
50
|
+
| "it feels like slides" | Enter the next scene through an object on screen; cut a move mid-flight |
|
|
51
|
+
|
|
52
|
+
## The right mechanism
|
|
53
|
+
|
|
54
|
+
| Request | Mechanism |
|
|
55
|
+
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| Punch-in, zoom, pan, Ken Burns, reframe | Tween `scale` and `x`/`y` on a wrapper inside the clip, never on the timed media element; chain the states on one timeline |
|
|
57
|
+
| Crop or mask reveal | Tween `clip-path` or a mask on an inner wrapper; source time is untouched |
|
|
58
|
+
| Constant speed change | `data-playback-rate` on the media, 0.1–10 (picture and pitch-preserved sound) |
|
|
59
|
+
| Speed ramp | A `rate` lane in `data-automation` on the media (`t` in clip seconds, `v` 0.1–10); it overrides the constant rate |
|
|
60
|
+
| Hold or freeze | Hold a final frame or a finished scene; a freeze mid-source needs a still exported first and placed as its own clip |
|
|
61
|
+
|
|
62
|
+
Ready-made moves: `npx hyperframes catalog --tag camera --json`, or `catalog --query "<the move>" --tag motion-primitive --json`.
|
|
63
|
+
|
|
64
|
+
## Seeing motion
|
|
65
|
+
|
|
66
|
+
The whole-film pass (beat sheet, cuts, phone width, the craft warnings) is `review.md`. For one move:
|
|
67
|
+
|
|
68
|
+
- `npx hyperframes keyframes --json [--selector '#id'] [--runtime all]` lists keyframes and motion paths (GSAP, CSS, anime.js): property, time, value, ease.
|
|
69
|
+
- `npx hyperframes keyframes --shot motion.png --selector '#id'` draws the real element's samples over time with its path (9 samples; `--samples N`). `--layout strip` for motion in place, `--from`/`--to` for one stretch, `--angle iso|top|side|'yaw,pitch'` for 3D, `--ghost` for a `<canvas>`.
|
|
70
|
+
- `npx hyperframes snapshot --range 2,4 --frames 8` samples one stretch; `--composition <id>` samples one scene; `--at <t,…>` exact instants; `--zoom '#id'` a sharp crop; `--angle iso` depth and overlap.
|
|
71
|
+
- Against a reference video: `snapshot --at <t,…> --against ref.mp4` writes a side-by-side sheet.
|
|
72
|
+
- Assert intent instead of eyeballing it: a `<name>.motion.json` next to the composition makes `check` verify it on the seeked timeline, as errors (`motion_appears_late`, `motion_out_of_order`, `motion_off_frame`, `motion_frozen`):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"assertions": [
|
|
77
|
+
{ "kind": "appearsBy", "selector": "#headline", "bySec": 0.5 },
|
|
78
|
+
{ "kind": "before", "a": "#headline", "b": "#cta" },
|
|
79
|
+
{ "kind": "staysInFrame", "selector": ".card" },
|
|
80
|
+
{ "kind": "keepsMoving", "withinSelector": ".scene" }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Common faults
|
|
86
|
+
|
|
87
|
+
| Symptom | Usual cause |
|
|
88
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
89
|
+
| Blank or frozen scene | Timeline registered before an async build finished, `visibility` tweened on a `.clip`, or a host id that differs from its scene's timeline key |
|
|
90
|
+
| Stutter or drift between renders | Layout measured in `onUpdate`, `requestAnimationFrame` or clock time; two timelines on one property |
|
|
91
|
+
| Jump at a cut | Outgoing and incoming states differ at the seam: snapshot just before and after it |
|
|
92
|
+
| Ease looks off at a handoff | Speeds don't match across the seam: mirror the ease (`power3.in` out, `power3.out` in) |
|
|
93
|
+
|
|
94
|
+
Studio's keyframe diamonds and motion-path handles rewrite the GSAP script in the composition file, so the person may have changed motion since you wrote it.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Cards over talking-head footage
|
|
2
|
+
|
|
3
|
+
Designed cards, lower thirds and split layouts over a person speaking. Placement numbers are for 1920×1080 and 1080×1920; scale others.
|
|
4
|
+
|
|
5
|
+
## Where the video sits
|
|
6
|
+
|
|
7
|
+
| Layout | Landscape (x, y, w×h) | Portrait (x, y, w×h) |
|
|
8
|
+
| ---------------------------- | --------------------- | -------------------- |
|
|
9
|
+
| Split, video beside the card | 960, 0, 960×1080 | 0, 960, 1080×960 |
|
|
10
|
+
| Stack, video above | 14, 14, 1892×548 | 0, 0, 1080×844 |
|
|
11
|
+
| Overlay | full frame | full frame |
|
|
12
|
+
|
|
13
|
+
Picture-in-picture, 28 px from the edges (bottom-right: y = H − h − 28):
|
|
14
|
+
|
|
15
|
+
| Canvas | Source | Rectangle |
|
|
16
|
+
| --------- | ------ | ----------------- |
|
|
17
|
+
| Landscape | 16:9 | 1432, 28, 460×258 |
|
|
18
|
+
| Landscape | 9:16 | 1644, 28, 248×440 |
|
|
19
|
+
| Portrait | 16:9 | 690, 28, 360×203 |
|
|
20
|
+
| Portrait | 9:16 | 738, 28, 312×555 |
|
|
21
|
+
|
|
22
|
+
- Card zones: a lower third is the bottom 30%; a side panel the right 42% (landscape) or bottom 40% (portrait). Glass card slots: 48, 460, 660×540 landscape; 24, 1280, 1032×564 portrait.
|
|
23
|
+
- Portrait type is landscape × 1.3 (titles × 1.35, stats × 1.4); padding drops from 40–64 px to 24–36 px.
|
|
24
|
+
- Size a rectangle to its source's aspect: `object-fit: cover` crops a portrait source in a landscape box.
|
|
25
|
+
|
|
26
|
+
## Timing
|
|
27
|
+
|
|
28
|
+
- Cards fade in over 0.4 s (`power2.out`) and out over 0.35 s (`power2.in`). Re-frame the video (0.5–0.7 s) only in a gap between cards; move it with transforms on a wrapper, not `left`/`top`/`width`/`height`.
|
|
29
|
+
- A static card goes dead after about 8 s; past about 15 s it needs a staged reveal. As a starting density: one card per 6–8 s under a minute, 8–12 s up to 3 min, 12–20 s up to 10 min.
|
|
30
|
+
- A transcript's last word can end past the media: clamp card ends and the root `data-duration` to the file's ffprobe length, or the render ends in black.
|
|
31
|
+
|
|
32
|
+
## Pitfalls
|
|
33
|
+
|
|
34
|
+
- Lower-third, overlay and picture-in-picture scenes need a transparent root, or they hide the speaker.
|
|
35
|
+
- Glass over bright footage goes white on white: put a dark scrim behind it (about `rgba(0,0,0,.55)` fading out from the top, `.72` at the bottom) and a dark glass base such as `rgba(15,16,22,.78)` with `backdrop-filter: blur(22px)`.
|
|
36
|
+
- More than 3 timed elements on one track warns `timeline_track_too_dense`: give each chapter its own sub-composition.
|
|
37
|
+
- Footage with keyframes more than about 1 s apart freezes on seek: re-encode with `-g <fps>`.
|
|
38
|
+
|
|
39
|
+
Text behind the speaker (a caption between the footage and a cutout of the person): `captions.md`.
|
|
@@ -7,10 +7,10 @@ That directory is `<PLUGIN_ROOT>`. If none exists, this is a standalone skill;
|
|
|
7
7
|
follow the normal installation and freshness instructions.
|
|
8
8
|
|
|
9
9
|
For a plugin installation, these rules replace the standalone update commands
|
|
10
|
-
in every
|
|
10
|
+
in every skill and reference:
|
|
11
11
|
|
|
12
12
|
- Do not run `hyperframes skills update`, `skills check`, or `npx skills add`.
|
|
13
|
-
The agent's plugin manager owns installation and updates. Read the
|
|
13
|
+
The agent's plugin manager owns installation and updates. Read the skill at
|
|
14
14
|
`<PLUGIN_ROOT>/skills/<name>/SKILL.md`; report a missing bundled skill instead
|
|
15
15
|
of downloading a different release. Resolve all skill references inside this
|
|
16
16
|
bundle, even if a standalone copy is also installed. Claude exposes the router
|
|
@@ -35,7 +35,7 @@ in every workflow and reference:
|
|
|
35
35
|
version alone does not freeze those inputs.
|
|
36
36
|
- Treat the plugin directory as read-only. Put outputs and temporary work in the
|
|
37
37
|
project or a temporary directory. Pass this plugin root and launcher convention
|
|
38
|
-
to any delegated
|
|
38
|
+
to any delegated agent so it does not fall back to global skills.
|
|
39
39
|
|
|
40
40
|
To get newer skills, use the client's plugin update flow and reload the session.
|
|
41
41
|
Do not silently update an installed plugin during a video task.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Review
|
|
2
|
+
|
|
3
|
+
You wrote the timeline, so you know what happens; the viewer sees it once, at full speed, often on a phone. Review is how you see the film as they will: as a harsh motion director, not a proud author. `check` catches what is broken; this pass catches what is weak. Run it after `check` passes, on every new film and on any edit that changes timing or layout, before you reply or render.
|
|
4
|
+
|
|
5
|
+
## 1. Measure, then look
|
|
6
|
+
|
|
7
|
+
1. `npx hyperframes check --json`. Besides errors it warns on craft it can measure: a line on screen too briefly to read (`line_unread`), more than 3 s with nothing changing (`dead_stretch`), text under 2.6% of the frame's short side (`text_below_floor`), an empty first frame (`first_frame_empty`, the thumbnail on social players), a film over 15 s with no sound (`film_silent`). A warning is a question, not a rule: fix it, or keep it on purpose and say why in the note (a deliberate hold carries `data-hold`).
|
|
8
|
+
2. `npx hyperframes snapshot --review` writes three sheets: each scene just after it starts and at its middle, plus each `data-beat`, a strip across every cut (−0.2 s to +0.2 s), and the beat frames at phone width (360 px). Open all three.
|
|
9
|
+
3. Motion between the beats: `snapshot --range START,END --frames 8` around the hero move and the payoff; `keyframes --shot` for a path that must arc or land.
|
|
10
|
+
4. The rendered file: `npx hyperframes audio <video> --json` shows whether sound is there, where it hits and how loud it is. You cannot hear it; say so.
|
|
11
|
+
|
|
12
|
+
Trust the numbers over your eye where they disagree: a clipped label or a 0.6 s line looks fine on a contact sheet.
|
|
13
|
+
|
|
14
|
+
## 2. What to look for
|
|
15
|
+
|
|
16
|
+
First, describe each beat frame in one sentence as a stranger would, naming every object; an object you would have to explain ("those bars are mirrors") is a P0. Then read the beat frames in order: do they tell a story a stranger follows, each one causing the next? Compare each with its shot in `SPEC.md`; what does not match is a note. Then name every default the frames show (`spec.md` "BANNED by default", or one not on the list yet), add each to the BANNED line, and fix them before anything else.
|
|
17
|
+
|
|
18
|
+
Then go through the sheets once per question:
|
|
19
|
+
|
|
20
|
+
| Question | What it catches |
|
|
21
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
22
|
+
| Does it read as what it is? | A shape that reads as another object, a material that reads as plastic, a product screen that reads as a mockup, a face or mascot that reads wrong |
|
|
23
|
+
| Does the subject separate? | Subject and ground too close in value, two focal points in one frame, the eye with nowhere to go |
|
|
24
|
+
| Framing and contact | Crops, text at the edge or under platform UI, collisions at a seam, things floating that should touch |
|
|
25
|
+
| Timing as a first-time viewer | A read shorter than its words (`story.md` §6), something that pops on with no move, a jump at a cut, everything moving at once on one curve |
|
|
26
|
+
| Tells | Which items of `story.md` §8 and `motion.md` "Defaults that look generated" are on screen |
|
|
27
|
+
| The pictures alone | With the words covered, do the beat frames still tell the storyline? |
|
|
28
|
+
| The phone sheet | Can every line meant to be read be read at 360 px? |
|
|
29
|
+
|
|
30
|
+
## 3. Notes and fixes
|
|
31
|
+
|
|
32
|
+
Write each problem as one line: `t=4.2s · where · problem → exact change · what stays`. Rank them:
|
|
33
|
+
|
|
34
|
+
- **P0** breaks the read or the contract: unreadable, wrong, broken, a tell in the hero shot.
|
|
35
|
+
- **P1** weakens the film: a dead stretch, a soft payoff, a seam that jumps.
|
|
36
|
+
- **P2** polish.
|
|
37
|
+
|
|
38
|
+
Fix every P0 and the P1s worth their time: text first, then timing, then detail. Then snapshot only what you changed, once. A second pass only when a P0 is still open. Never score the film out of 10: a score finds nothing to fix. When a fix does not hold, snapshot the frames on either side of the problem, list every difference, and change only the line that causes it. A film that feels busy: remove a third of the motion and keep the moves that lead the eye.
|
|
39
|
+
|
|
40
|
+
A fresh pair of eyes, when your host can start a sub-agent: give it only `STORYBOARD.md` and the three sheets, ask for P0 and P1 lines in the format above, and keep editing to yourself. Commit or copy the project before you fix, so a fix that makes things worse can be rolled back.
|
|
41
|
+
|
|
42
|
+
## 4. The delivery note
|
|
43
|
+
|
|
44
|
+
Write `REVIEW.md` at the project root and put its short form in your reply:
|
|
45
|
+
|
|
46
|
+
- the creative calls you made, and the storylines you did not build;
|
|
47
|
+
- what you measured and what you only looked at; what nobody checked (the sound was measured, not heard);
|
|
48
|
+
- the weakest shot, and what you would change with more time;
|
|
49
|
+
- warnings you kept on purpose, and why.
|
|
50
|
+
|
|
51
|
+
The next turn reads it before changing anything.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Animation runtimes
|
|
2
|
+
|
|
3
|
+
HyperFrames seeks each frame on its own, so motion must be a function of time, never of the previous frame. Full GSAP reference: `npx hyperframes docs gsap`.
|
|
4
|
+
|
|
5
|
+
## GSAP facts that bite
|
|
6
|
+
|
|
7
|
+
- Register the timeline last. Building inside `document.fonts.ready.then(…)` or another async callback is fine if you register at the end of it; registering first renders blank (`gsap_timeline_registered_before_async_build`).
|
|
8
|
+
- Place tweens at absolute seconds (`tl.to(el, {…}, 2.4)`). Set start states in the tween (`fromTo`), not in CSS.
|
|
9
|
+
- Measure layout once before building tweens, never inside `onUpdate`.
|
|
10
|
+
- Finite repeats only: `repeat: Math.max(0, Math.floor(duration / cycle) - 1)`.
|
|
11
|
+
- Seed randomness with a small PRNG (mulberry32).
|
|
12
|
+
- A scene's timeline can't reach elements outside its file, and two timelines must not animate the same property of one element.
|
|
13
|
+
- Transforms on a `<span>` need `display: inline-block` or `block`.
|
|
14
|
+
- Text that must fit a width: `window.__hyperframes.fitTextFontSize(text, { fontFamily, fontWeight, maxWidth })` returns `{ fontSize }`; `window.__hyperframes.pretext` measures text without a reflow.
|
|
15
|
+
|
|
16
|
+
## Other runtimes
|
|
17
|
+
|
|
18
|
+
| Runtime | Use for | How HyperFrames drives it |
|
|
19
|
+
| ---------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
20
|
+
| CSS `@keyframes` | Simple loops and decoration | Found automatically; finite iterations, `animation-fill-mode: both`, `data-start` on the element |
|
|
21
|
+
| WAAPI | Native keyframes | `element.animate(…, { fill: "both" })` then `pause()`; times are document time, so use `delay` |
|
|
22
|
+
| Lottie / dotLottie | After Effects exports, characters | `autoplay: false`, always set `loop`, push the instance to `window.__hfLottie` |
|
|
23
|
+
| anime.js v4 | Existing anime code | `autoplay: false`, push to `window.__hfAnime`, `anime.createSeededRandom` |
|
|
24
|
+
| Three.js, WebGPU, p5, canvas | 3D and generative | Draw from `e.detail.time` in an `hf-seek` listener; set `data-duration` on the root |
|
|
25
|
+
|
|
26
|
+
Charts and map overlays: drive them from a GSAP tween's `onUpdate`, not the library's own transitions. A real place is shown on baked imagery, not drawn (`film.md` "Maps and real places"). Heavy setup (big meshes, shader compiles) registers a `window.__hf.buildReady["<key>"]` promise.
|
|
27
|
+
|
|
28
|
+
## The seek protocol
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<script>
|
|
32
|
+
function renderAt(t) {
|
|
33
|
+
/* draw the frame for t seconds from state derived from t alone */
|
|
34
|
+
}
|
|
35
|
+
window.addEventListener("hf-seek", (e) => {
|
|
36
|
+
renderAt(e.detail.time);
|
|
37
|
+
// async work (GPU submit, image decode): e.detail.waitUntil(promise), called synchronously
|
|
38
|
+
});
|
|
39
|
+
renderAt(0);
|
|
40
|
+
</script>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
No `requestAnimationFrame` loop or timer as the clock.
|