@mevdragon/vidfarm-devcli 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/embedded-captions/CATALOG.md +93 -0
- package/.agents/skills/embedded-captions/SKILL.md +286 -0
- package/.agents/skills/embedded-captions/assets/brand/CDPR-fankit-terms.txt +35 -0
- package/.agents/skills/embedded-captions/assets/brand/cyberpunk-widths.json +115 -0
- package/.agents/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
- package/.agents/skills/embedded-captions/dna/README.md +148 -0
- package/.agents/skills/embedded-captions/dna/chrome.json +68 -0
- package/.agents/skills/embedded-captions/dna/cream.json +69 -0
- package/.agents/skills/embedded-captions/dna/documentary.json +62 -0
- package/.agents/skills/embedded-captions/dna/editorial.json +70 -0
- package/.agents/skills/embedded-captions/dna/glitch.json +82 -0
- package/.agents/skills/embedded-captions/dna/ink.json +65 -0
- package/.agents/skills/embedded-captions/dna/keynote.json +62 -0
- package/.agents/skills/embedded-captions/dna/loud.json +75 -0
- package/.agents/skills/embedded-captions/dna/neon.json +58 -0
- package/.agents/skills/embedded-captions/dna/velocity.json +89 -0
- package/.agents/skills/embedded-captions/modes/cinematic/README.md +48 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
- package/.agents/skills/embedded-captions/modes/cinematic/engine.html +355 -0
- package/.agents/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
- package/.agents/skills/embedded-captions/modes/standard/_motion.md +192 -0
- package/.agents/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
- package/.agents/skills/embedded-captions/references/aesthetic-principles.md +168 -0
- package/.agents/skills/embedded-captions/references/anti-patterns.md +188 -0
- package/.agents/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
- package/.agents/skills/embedded-captions/references/caption-grouping.md +130 -0
- package/.agents/skills/embedded-captions/references/composition-craft.md +522 -0
- package/.agents/skills/embedded-captions/references/direction-catalog.md +138 -0
- package/.agents/skills/embedded-captions/references/example-renders/champion.html +371 -0
- package/.agents/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
- package/.agents/skills/embedded-captions/references/failure-modes.md +145 -0
- package/.agents/skills/embedded-captions/references/layout-heuristics.md +238 -0
- package/.agents/skills/embedded-captions/references/motion-vocabulary.md +148 -0
- package/.agents/skills/embedded-captions/references/rail.md +68 -0
- package/.agents/skills/embedded-captions/references/reference-bar.md +47 -0
- package/.agents/skills/embedded-captions/references/scene-types.md +94 -0
- package/.agents/skills/embedded-captions/references/test-set.md +66 -0
- package/.agents/skills/embedded-captions/references/typographic-moves.md +266 -0
- package/.agents/skills/embedded-captions/references/typography-presets.md +63 -0
- package/.agents/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
- package/.agents/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
- package/.agents/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
- package/.agents/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
- package/.agents/skills/embedded-captions/scripts/check-timing.cjs +173 -0
- package/.agents/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
- package/.agents/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
- package/.agents/skills/embedded-captions/scripts/gen-stroke-path.py +46 -0
- package/.agents/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
- package/.agents/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
- package/.agents/skills/embedded-captions/scripts/make-cinematic.cjs +1205 -0
- package/.agents/skills/embedded-captions/scripts/make-composition.cjs +404 -0
- package/.agents/skills/embedded-captions/scripts/make-theme.cjs +8781 -0
- package/.agents/skills/embedded-captions/scripts/matte.cjs +294 -0
- package/.agents/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
- package/.agents/skills/embedded-captions/scripts/prepare.sh +39 -0
- package/.agents/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
- package/.agents/skills/embedded-captions/scripts/render-and-composite.sh +509 -0
- package/.agents/skills/embedded-captions/scripts/render-theme.sh +34 -0
- package/.agents/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
- package/.agents/skills/embedded-captions/scripts/transcribe.cjs +349 -0
- package/.agents/skills/embedded-captions/themes/PORTING.md +49 -0
- package/.agents/skills/embedded-captions/themes/README.md +244 -0
- package/.agents/skills/embedded-captions/themes/anchor.json +27 -0
- package/.agents/skills/embedded-captions/themes/arcade.json +51 -0
- package/.agents/skills/embedded-captions/themes/aurora.json +41 -0
- package/.agents/skills/embedded-captions/themes/biolume.json +35 -0
- package/.agents/skills/embedded-captions/themes/brush.json +74 -0
- package/.agents/skills/embedded-captions/themes/chalkboard.json +52 -0
- package/.agents/skills/embedded-captions/themes/dossier.json +56 -0
- package/.agents/skills/embedded-captions/themes/graffiti.json +62 -0
- package/.agents/skills/embedded-captions/themes/hologram.json +41 -0
- package/.agents/skills/embedded-captions/themes/inkwater.json +43 -0
- package/.agents/skills/embedded-captions/themes/laser.json +46 -0
- package/.agents/skills/embedded-captions/themes/lastpage.json +33 -0
- package/.agents/skills/embedded-captions/themes/neonsign.json +53 -0
- package/.agents/skills/embedded-captions/themes/nightcity.json +56 -0
- package/.agents/skills/embedded-captions/themes/ordnance.json +54 -0
- package/.agents/skills/embedded-captions/themes/papercut.json +37 -0
- package/.agents/skills/embedded-captions/themes/popup.json +46 -0
- package/.agents/skills/embedded-captions/themes/ransom.json +62 -0
- package/.agents/skills/embedded-captions/themes/scoreboard.json +54 -0
- package/.agents/skills/embedded-captions/themes/spectrum.json +46 -0
- package/.agents/skills/embedded-captions/themes/stardust.json +29 -0
- package/.agents/skills/embedded-captions/themes/stomp.json +43 -0
- package/.agents/skills/embedded-captions/themes/terminal.json +49 -0
- package/.agents/skills/embedded-captions/themes/thunder.json +44 -0
- package/.agents/skills/embedded-captions/themes/transit.json +44 -0
- package/.agents/skills/embedded-captions/themes/vhs.json +47 -0
- package/.agents/skills/faceless-explainer/SKILL.md +209 -0
- package/.agents/skills/faceless-explainer/references/cut-catalog.md +215 -0
- package/.agents/skills/faceless-explainer/references/motion-language.md +156 -0
- package/.agents/skills/faceless-explainer/references/story-design.md +248 -0
- package/.agents/skills/faceless-explainer/references/visual-design.md +146 -0
- package/.agents/skills/faceless-explainer/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/faceless-explainer/scripts/audio.mjs +260 -0
- package/.agents/skills/faceless-explainer/scripts/build-frame.mjs +536 -0
- package/.agents/skills/faceless-explainer/scripts/captions.mjs +508 -0
- package/.agents/skills/faceless-explainer/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/faceless-explainer/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
- package/.agents/skills/faceless-explainer/scripts/transitions.mjs +320 -0
- package/.agents/skills/faceless-explainer/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/flockposter/LICENSE +17 -0
- package/.agents/skills/flockposter/README.md +72 -0
- package/.agents/skills/flockposter/SKILL.md +562 -0
- package/.agents/skills/flockposter/examples/cli-instagram-reel.sh +21 -0
- package/.agents/skills/flockposter/examples/cli-multi-platform.json +69 -0
- package/.agents/skills/flockposter/examples/cli-tiktok-upload-only.sh +22 -0
- package/.agents/skills/flockposter/examples/cli-x-thread.sh +17 -0
- package/.agents/skills/flockposter/examples/cli-youtube-short.sh +21 -0
- package/.agents/skills/flockposter/examples/public-api-instagram-reel.json +28 -0
- package/.agents/skills/general-video/SKILL.md +143 -0
- package/.agents/skills/hyperframes/SKILL.md +160 -0
- package/.agents/skills/hyperframes-animation/SKILL.md +84 -0
- package/.agents/skills/hyperframes-animation/adapters/animate-text.md +64 -0
- package/.agents/skills/hyperframes-animation/adapters/animejs.md +114 -0
- package/.agents/skills/hyperframes-animation/adapters/css-animations.md +143 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +118 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap.md +105 -0
- package/.agents/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
- package/.agents/skills/hyperframes-animation/adapters/lottie.md +117 -0
- package/.agents/skills/hyperframes-animation/adapters/three.md +131 -0
- package/.agents/skills/hyperframes-animation/adapters/typegpu.md +178 -0
- package/.agents/skills/hyperframes-animation/adapters/waapi.md +101 -0
- package/.agents/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
- package/.agents/skills/hyperframes-animation/blueprints/constellation-hub.md +44 -0
- package/.agents/skills/hyperframes-animation/blueprints/cta-morph-press.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +57 -0
- package/.agents/skills/hyperframes-animation/blueprints/dataviz-countup.md +46 -0
- package/.agents/skills/hyperframes-animation/blueprints/device-surface-showcase.md +53 -0
- package/.agents/skills/hyperframes-animation/blueprints/grid-card-assemble.md +66 -0
- package/.agents/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +78 -0
- package/.agents/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +69 -0
- package/.agents/skills/hyperframes-animation/blueprints/overwhelm-surround.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
- package/.agents/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
- package/.agents/skills/hyperframes-animation/blueprints/titlecard-reveal.md +42 -0
- package/.agents/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
- package/.agents/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
- package/.agents/skills/hyperframes-animation/blueprints-index.md +146 -0
- package/.agents/skills/hyperframes-animation/examples/assets/avatars/02.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/github.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/nvidia.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/visa.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/zoominfo.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
- package/.agents/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
- package/.agents/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
- package/.agents/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
- package/.agents/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
- package/.agents/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
- package/.agents/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
- package/.agents/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
- package/.agents/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
- package/.agents/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
- package/.agents/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
- package/.agents/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
- package/.agents/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
- package/.agents/skills/hyperframes-animation/rules/3d-page-scroll.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/3d-text-depth-layers.md +297 -0
- package/.agents/skills/hyperframes-animation/rules/ai-tracking-box.md +382 -0
- package/.agents/skills/hyperframes-animation/rules/ambient-glow-bloom.md +305 -0
- package/.agents/skills/hyperframes-animation/rules/asr-keyword-glow.md +286 -0
- package/.agents/skills/hyperframes-animation/rules/avatar-cloud-network.md +371 -0
- package/.agents/skills/hyperframes-animation/rules/camera-cursor-tracking.md +246 -0
- package/.agents/skills/hyperframes-animation/rules/card-morph-anchor.md +267 -0
- package/.agents/skills/hyperframes-animation/rules/center-outward-expansion.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/context-sensitive-cursor.md +257 -0
- package/.agents/skills/hyperframes-animation/rules/coordinate-target-zoom.md +332 -0
- package/.agents/skills/hyperframes-animation/rules/counting-dynamic-scale.md +283 -0
- package/.agents/skills/hyperframes-animation/rules/css-marker-patterns.md +373 -0
- package/.agents/skills/hyperframes-animation/rules/cursor-click-ripple.md +262 -0
- package/.agents/skills/hyperframes-animation/rules/depth-of-field-blur.md +313 -0
- package/.agents/skills/hyperframes-animation/rules/depth-scatter-assemble.md +303 -0
- package/.agents/skills/hyperframes-animation/rules/discrete-text-sequence.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +307 -0
- package/.agents/skills/hyperframes-animation/rules/gsap-effects.md +299 -0
- package/.agents/skills/hyperframes-animation/rules/hacker-flip-3d.md +223 -0
- package/.agents/skills/hyperframes-animation/rules/kinetic-beat-slam.md +183 -0
- package/.agents/skills/hyperframes-animation/rules/motion-blur-streak.md +328 -0
- package/.agents/skills/hyperframes-animation/rules/multi-phase-camera.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/orbit-3d-entry.md +301 -0
- package/.agents/skills/hyperframes-animation/rules/physics-press-reaction.md +350 -0
- package/.agents/skills/hyperframes-animation/rules/press-release-spring.md +296 -0
- package/.agents/skills/hyperframes-animation/rules/reactive-displacement.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/scale-swap-transition.md +298 -0
- package/.agents/skills/hyperframes-animation/rules/sine-wave-loop.md +278 -0
- package/.agents/skills/hyperframes-animation/rules/split-tilt-cards.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/spring-pop-entrance.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/stat-bars-and-fills.md +156 -0
- package/.agents/skills/hyperframes-animation/rules/svg-icon-enrichment.md +329 -0
- package/.agents/skills/hyperframes-animation/rules/svg-path-draw.md +274 -0
- package/.agents/skills/hyperframes-animation/rules/vertical-spring-ticker.md +239 -0
- package/.agents/skills/hyperframes-animation/rules/viewport-change.md +349 -0
- package/.agents/skills/hyperframes-animation/rules-index.md +86 -0
- package/.agents/skills/hyperframes-animation/scripts/animation-map.mjs +606 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-animation/techniques.md +507 -0
- package/.agents/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +167 -0
- package/.agents/skills/hyperframes-animation/transitions/catalog.md +127 -0
- package/.agents/skills/hyperframes-animation/transitions/css-3d.md +12 -0
- package/.agents/skills/hyperframes-animation/transitions/css-blur.md +51 -0
- package/.agents/skills/hyperframes-animation/transitions/css-cover.md +43 -0
- package/.agents/skills/hyperframes-animation/transitions/css-destruction.md +95 -0
- package/.agents/skills/hyperframes-animation/transitions/css-dissolve.md +66 -0
- package/.agents/skills/hyperframes-animation/transitions/css-distortion.md +45 -0
- package/.agents/skills/hyperframes-animation/transitions/css-grid.md +10 -0
- package/.agents/skills/hyperframes-animation/transitions/css-light.md +49 -0
- package/.agents/skills/hyperframes-animation/transitions/css-mechanical.md +30 -0
- package/.agents/skills/hyperframes-animation/transitions/css-other.md +25 -0
- package/.agents/skills/hyperframes-animation/transitions/css-push.md +41 -0
- package/.agents/skills/hyperframes-animation/transitions/css-radial.md +37 -0
- package/.agents/skills/hyperframes-animation/transitions/css-scale.md +24 -0
- package/.agents/skills/hyperframes-animation/transitions/overview.md +153 -0
- package/.agents/skills/hyperframes-cli/SKILL.md +113 -0
- package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
- package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +55 -0
- package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
- package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
- package/.agents/skills/hyperframes-cli/references/preview-render.md +149 -0
- package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
- package/.agents/skills/hyperframes-core/SKILL.md +78 -0
- package/.agents/skills/hyperframes-core/references/composition-patterns.md +263 -0
- package/.agents/skills/hyperframes-core/references/data-attributes.md +70 -0
- package/.agents/skills/hyperframes-core/references/determinism-rules.md +68 -0
- package/.agents/skills/hyperframes-core/references/full-screen-motion.md +62 -0
- package/.agents/skills/hyperframes-core/references/minimal-composition.md +66 -0
- package/.agents/skills/hyperframes-core/references/script-format.md +49 -0
- package/.agents/skills/hyperframes-core/references/storyboard-format.md +95 -0
- package/.agents/skills/hyperframes-core/references/sub-compositions.md +237 -0
- package/.agents/skills/hyperframes-core/references/subagent-dispatch.md +41 -0
- package/.agents/skills/hyperframes-core/references/tailwind.md +125 -0
- package/.agents/skills/hyperframes-core/references/tracks-and-clips.md +76 -0
- package/.agents/skills/hyperframes-core/references/variables-and-media.md +90 -0
- package/.agents/skills/hyperframes-creative/SKILL.md +70 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/FRAME.md +277 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/frame-showcase.html +1439 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/.agents/skills/hyperframes-creative/palettes/bold-energetic.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/clean-corporate.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/dark-premium.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/jewel-rich.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/monochrome.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/nature-earth.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/neon-electric.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/pastel-soft.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/warm-editorial.md +14 -0
- package/.agents/skills/hyperframes-creative/references/audio-reactive.md +76 -0
- package/.agents/skills/hyperframes-creative/references/beat-direction.md +164 -0
- package/.agents/skills/hyperframes-creative/references/composition-patterns.md +199 -0
- package/.agents/skills/hyperframes-creative/references/data-in-motion.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-adherence.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-picker.md +123 -0
- package/.agents/skills/hyperframes-creative/references/design-spec.md +55 -0
- package/.agents/skills/hyperframes-creative/references/house-style.md +73 -0
- package/.agents/skills/hyperframes-creative/references/motion-principles.md +150 -0
- package/.agents/skills/hyperframes-creative/references/narration.md +92 -0
- package/.agents/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
- package/.agents/skills/hyperframes-creative/references/typography.md +218 -0
- package/.agents/skills/hyperframes-creative/references/video-composition.md +63 -0
- package/.agents/skills/hyperframes-creative/references/visual-styles.md +457 -0
- package/.agents/skills/hyperframes-creative/scripts/contrast-report.mjs +353 -0
- package/.agents/skills/hyperframes-creative/scripts/extract-audio-data.py +188 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-creative/templates/design-picker.html +1432 -0
- package/.agents/skills/hyperframes-keyframes/SKILL.md +237 -0
- package/.agents/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
- package/.agents/skills/hyperframes-keyframes/references/keyframe-patterns.md +106 -0
- package/.agents/skills/motion-graphics/SKILL.md +172 -0
- package/.agents/skills/motion-graphics/agents/builder.md +40 -0
- package/.agents/skills/motion-graphics/agents/director.md +53 -0
- package/.agents/skills/motion-graphics/agents/finalize.md +17 -0
- package/.agents/skills/motion-graphics/catalog-map.md +40 -0
- package/.agents/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
- package/.agents/skills/motion-graphics/categories/charts/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
- package/.agents/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
- package/.agents/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
- package/.agents/skills/motion-graphics/categories/maps/module.md +61 -0
- package/.agents/skills/motion-graphics/categories/news/module.md +56 -0
- package/.agents/skills/motion-graphics/categories/stat/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/tweet/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/webpage/module.md +21 -0
- package/.agents/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
- package/.agents/skills/motion-graphics/grounding/locate.mjs +227 -0
- package/.agents/skills/motion-graphics/phases/source/guide.md +21 -0
- package/.agents/skills/motion-graphics/references/builder-contract.md +38 -0
- package/.agents/skills/motion-graphics/references/motion-vocabulary.md +43 -0
- package/.agents/skills/motion-graphics/references/shot-plan-ir.md +54 -0
- package/.agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
- package/.agents/skills/product-launch-video/SKILL.md +208 -0
- package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
- package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
- package/.agents/skills/product-launch-video/references/story-design.md +373 -0
- package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
- package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/product-launch-video/scripts/audio.mjs +260 -0
- package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
- package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
- package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
- package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
- package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
- package/.agents/skills/product-launch-video/scripts/transitions.mjs +327 -0
- package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/slideshow/SKILL.md +550 -0
- package/.agents/skills/slideshow/references/standalone-harness.md +1020 -0
- package/.agents/skills/talking-head-recut/NOTICE.md +39 -0
- package/.agents/skills/talking-head-recut/SKILL.md +1195 -0
- package/.agents/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
- package/.agents/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
- package/.agents/skills/talking-head-recut/references/frames/clean.html +92 -0
- package/.agents/skills/talking-head-recut/references/frames/hairline.html +171 -0
- package/.agents/skills/talking-head-recut/references/frames/polaroid.html +131 -0
- package/.agents/skills/talking-head-recut/references/layouts/overlay.html +164 -0
- package/.agents/skills/talking-head-recut/references/layouts/pip.html +143 -0
- package/.agents/skills/talking-head-recut/references/layouts/split.html +121 -0
- package/.agents/skills/talking-head-recut/references/layouts/stack.html +109 -0
- package/.agents/skills/talking-head-recut/references/styles/academic.html +172 -0
- package/.agents/skills/talking-head-recut/references/styles/audit.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/editorial.html +189 -0
- package/.agents/skills/talking-head-recut/references/styles/geom.html +181 -0
- package/.agents/skills/talking-head-recut/references/styles/minimal.html +130 -0
- package/.agents/skills/talking-head-recut/references/styles/spotlight.html +142 -0
- package/.agents/skills/talking-head-recut/references/styles/swiss.html +188 -0
- package/.agents/skills/talking-head-recut/references/styles/terminal.html +196 -0
- package/.agents/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/xhs.html +206 -0
- package/.agents/skills/vidfarm-media/SKILL.md +85 -0
- package/.agents/skills/vidfarm-media/references/tts.md +54 -0
- package/.agents/skills/vidfarm-media/scripts/audio.mjs +628 -0
- package/.agents/skills/vidfarm-media/scripts/wait-bgm.mjs +31 -0
- package/.agents/skills/website-to-video/SKILL.md +145 -0
- package/.agents/skills/website-to-video/assets/sfx/CREDITS.md +35 -0
- package/.agents/skills/website-to-video/assets/sfx/manifest.json +97 -0
- package/.agents/skills/website-to-video/references/beat-builder-guide.md +263 -0
- package/.agents/skills/website-to-video/references/capabilities.md +713 -0
- package/.agents/skills/website-to-video/references/step-0-capture.md +55 -0
- package/.agents/skills/website-to-video/references/step-1-design.md +333 -0
- package/.agents/skills/website-to-video/references/step-2-brief.md +178 -0
- package/.agents/skills/website-to-video/references/step-3-storyboard.md +572 -0
- package/.agents/skills/website-to-video/references/step-4-vo.md +225 -0
- package/.agents/skills/website-to-video/references/step-5-build.md +483 -0
- package/.agents/skills/website-to-video/references/step-6-validate.md +341 -0
- package/.agents/skills/website-to-video/scripts/w2h-verify.mjs +759 -0
- package/SKILL.director.md +60 -4
- package/SKILL.platform.md +7 -2
- package/demo/dist/app.css +1 -1
- package/demo/dist/app.js +485 -86
- package/dist/src/account-pages-legacy.js +9 -14
- package/dist/src/app.js +659 -159
- package/dist/src/cli.js +618 -17
- package/dist/src/composition-runtime.js +286 -6
- package/dist/src/devcli/composition-edit.js +176 -8
- package/dist/src/devcli/doctor.js +192 -0
- package/dist/src/devcli/hyperframes-cli.js +118 -0
- package/dist/src/devcli/skills.js +476 -0
- package/dist/src/devcli/stills.js +249 -0
- package/dist/src/devcli/transitions.js +205 -0
- package/dist/src/editor-chat.js +260 -4
- package/dist/src/frontend/template-editor-chat.js +6 -5
- package/dist/src/homepage.js +2 -48
- package/dist/src/hyperframes/composition.js +188 -7
- package/dist/src/services/composition-lint.js +199 -0
- package/dist/src/services/hyperframes.js +127 -28
- package/dist/src/services/serverless-records.js +7 -0
- package/dist/src/template-editor-shell.js +87 -48
- package/package.json +2 -1
- package/public/assets/page-runtime-client-app.js +31 -31
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* fill-timings.cjs — fill plan.json group/word times DIRECTLY from transcript.json,
|
|
4
|
+
* by SEQUENCE (Cinematic mode). Kills the timing-drift + duplicate-word class of
|
|
5
|
+
* occlusion/timing-gate re-tries: the agent only decides the GROUPING (which words form
|
|
6
|
+
* each group, in spoken order); times come from the transcript by position, so the
|
|
7
|
+
* second "and"/"actions" matches the right occurrence (text-matching pairs the wrong one).
|
|
8
|
+
*
|
|
9
|
+
* node fill-timings.cjs <project-dir>
|
|
10
|
+
*
|
|
11
|
+
* Reads <project>/plan.json (groups[].words[].text, in spoken order) + transcript.json.
|
|
12
|
+
* Writes <project>/plan.json with each word's start/end and each group's in/out filled.
|
|
13
|
+
* A group word that can't be matched keeps whatever time it had + is reported (so a typo
|
|
14
|
+
* or an added word degrades gracefully instead of silently mis-timing).
|
|
15
|
+
*/
|
|
16
|
+
const path = require("path");
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
|
|
19
|
+
const norm = (s) =>
|
|
20
|
+
String(s == null ? "" : s)
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.replace(/[^a-z0-9]/g, "");
|
|
23
|
+
const LOOKAHEAD = 40; // how far past the pointer to search for a group word (skips dropped fillers)
|
|
24
|
+
|
|
25
|
+
function fillGroup(g, tw, state) {
|
|
26
|
+
const matched = [];
|
|
27
|
+
const unmatched = [];
|
|
28
|
+
for (const w of g.words || []) {
|
|
29
|
+
const target = norm(w.text);
|
|
30
|
+
if (!target) {
|
|
31
|
+
unmatched.push(w.text);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
let found = -1;
|
|
35
|
+
for (let j = state.p; j < Math.min(tw.length, state.p + LOOKAHEAD); j++) {
|
|
36
|
+
if (norm(tw[j].text) === target) {
|
|
37
|
+
found = j;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (found >= 0) {
|
|
42
|
+
w.start = tw[found].start;
|
|
43
|
+
w.end = tw[found].end;
|
|
44
|
+
matched.push(w);
|
|
45
|
+
state.p = found + 1;
|
|
46
|
+
} else {
|
|
47
|
+
unmatched.push(w.text);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (matched.length) {
|
|
51
|
+
const firstStart = +matched[0].start.toFixed(3);
|
|
52
|
+
const lastEnd = +matched[matched.length - 1].end.toFixed(3);
|
|
53
|
+
// WORD start/end are filled above (deterministic). For the group's DISPLAY window we
|
|
54
|
+
// only GUARANTEE it brackets the words (never clip a word) — we do NOT tighten it:
|
|
55
|
+
// a deliberately later `out` is the apex HOLD / sentence ACCUMULATION the author set,
|
|
56
|
+
// and an earlier `in` is a pre-entry. Preserve both; clamp only if they'd clip.
|
|
57
|
+
g.in = g.in == null ? firstStart : Math.min(g.in, firstStart);
|
|
58
|
+
g.out = g.out == null ? lastEnd : Math.max(g.out, lastEnd);
|
|
59
|
+
}
|
|
60
|
+
return { matched: matched.length, unmatched };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function main() {
|
|
64
|
+
const project = path.resolve(process.argv[2] || "");
|
|
65
|
+
if (!process.argv[2]) {
|
|
66
|
+
console.error("usage: fill-timings.cjs <project-dir>");
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
const planPath = path.join(project, "plan.json");
|
|
70
|
+
const trPath = path.join(project, "transcript.json");
|
|
71
|
+
let plan, trWordsRaw;
|
|
72
|
+
try {
|
|
73
|
+
plan = JSON.parse(fs.readFileSync(planPath, "utf8"));
|
|
74
|
+
} catch {
|
|
75
|
+
console.error(`[fill-timings] no plan.json (Cinematic only) — skipping`);
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
trWordsRaw = JSON.parse(fs.readFileSync(trPath, "utf8")).words || [];
|
|
80
|
+
} catch {
|
|
81
|
+
console.error(`[fill-timings] no transcript.json — skipping`);
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
const tw = trWordsRaw.filter((w) => w && "start" in w && "end" in w);
|
|
85
|
+
if (!tw.length) {
|
|
86
|
+
console.error(`[fill-timings] transcript has no word timings — skipping`);
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const state = { p: 0 };
|
|
91
|
+
let totalMatched = 0,
|
|
92
|
+
totalUnmatched = 0;
|
|
93
|
+
const groups = plan.groups || [];
|
|
94
|
+
// crown_group (if any) is spoken last in the standard templates; process groups in order, crown after.
|
|
95
|
+
const ordered = [...groups];
|
|
96
|
+
for (const g of ordered) {
|
|
97
|
+
const r = fillGroup(g, tw, state);
|
|
98
|
+
totalMatched += r.matched;
|
|
99
|
+
totalUnmatched += r.unmatched.length;
|
|
100
|
+
if (r.unmatched.length)
|
|
101
|
+
console.error(
|
|
102
|
+
`[fill-timings] ⚠ ${g.id || "(group)"}: ${r.unmatched.length} word(s) not found in transcript from here: ${r.unmatched.join(" ")}`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
if (plan.crown_group) {
|
|
106
|
+
const r = fillGroup(plan.crown_group, tw, state);
|
|
107
|
+
totalMatched += r.matched;
|
|
108
|
+
totalUnmatched += r.unmatched.length;
|
|
109
|
+
if (r.unmatched.length)
|
|
110
|
+
console.error(`[fill-timings] ⚠ crown_group: ${r.unmatched.join(" ")} not found`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fs.writeFileSync(planPath, JSON.stringify(plan, null, 2));
|
|
114
|
+
console.log(
|
|
115
|
+
`[fill-timings] filled ${totalMatched} word time(s) from transcript by sequence` +
|
|
116
|
+
(totalUnmatched
|
|
117
|
+
? `; ${totalUnmatched} unmatched (kept prior time — check those words)`
|
|
118
|
+
: `; all matched ✓`),
|
|
119
|
+
);
|
|
120
|
+
console.log(
|
|
121
|
+
`[fill-timings] group windows now: ${ordered.map((g) => `${g.id || "?"}[${g.in}-${g.out}]`).join(" ")}`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
main();
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* fit-fonts.cjs — shrink any plan.json caption group whose single line would overflow
|
|
4
|
+
* its box, BEFORE render (Cinematic mode). Kills the "font too big → off-frame → shrink
|
|
5
|
+
* → re-render" overflow round. Estimates rendered width from character count × a
|
|
6
|
+
* per-family advance × the group's font-size, compares to the group's box width (its
|
|
7
|
+
* plane width, else the frame), and only ever SHRINKS to fit. Approximate by design —
|
|
8
|
+
* it prevents gross overflow; check-overflow.cjs remains the exact terminal check.
|
|
9
|
+
*
|
|
10
|
+
* node fit-fonts.cjs <project-dir>
|
|
11
|
+
*/
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
|
|
15
|
+
// rough per-family advance (em per char, caps-ish). Condensed faces are narrow; pixel
|
|
16
|
+
// faces wide. Default is conservative. (Estimate only — gate confirms.)
|
|
17
|
+
const ADV = {
|
|
18
|
+
anton: 0.44,
|
|
19
|
+
oswald: 0.45,
|
|
20
|
+
teko: 0.4,
|
|
21
|
+
"saira stencil one": 0.46,
|
|
22
|
+
"bebas neue": 0.4,
|
|
23
|
+
"press start 2p": 1.05,
|
|
24
|
+
vt323: 0.52,
|
|
25
|
+
monoton: 0.62,
|
|
26
|
+
"special elite": 0.55,
|
|
27
|
+
"jetbrains mono": 0.6,
|
|
28
|
+
"space mono": 0.6,
|
|
29
|
+
"ibm plex mono": 0.6,
|
|
30
|
+
"source code pro": 0.6,
|
|
31
|
+
"archivo black": 0.62,
|
|
32
|
+
bangers: 0.5,
|
|
33
|
+
"bodoni moda": 0.5,
|
|
34
|
+
"playfair display": 0.52,
|
|
35
|
+
cinzel: 0.62,
|
|
36
|
+
"cormorant garamond": 0.45,
|
|
37
|
+
fredoka: 0.55,
|
|
38
|
+
"baloo 2": 0.55,
|
|
39
|
+
"permanent marker": 0.55,
|
|
40
|
+
caveat: 0.4,
|
|
41
|
+
orbitron: 0.66,
|
|
42
|
+
sora: 0.54,
|
|
43
|
+
"space grotesk": 0.54,
|
|
44
|
+
};
|
|
45
|
+
const DEFAULT_ADV = 0.56;
|
|
46
|
+
|
|
47
|
+
const cssVal = (css, prop) => {
|
|
48
|
+
const m = String(css || "").match(new RegExp(prop + "\\s*:\\s*([^;}]+)", "i"));
|
|
49
|
+
return m ? m[1].trim() : null;
|
|
50
|
+
};
|
|
51
|
+
function familyOf(css) {
|
|
52
|
+
const v = cssVal(css, "font-family");
|
|
53
|
+
if (!v) return "inter";
|
|
54
|
+
return v
|
|
55
|
+
.split(",")[0]
|
|
56
|
+
.trim()
|
|
57
|
+
.replace(/^['"]|['"]$/g, "")
|
|
58
|
+
.toLowerCase();
|
|
59
|
+
}
|
|
60
|
+
function sizePxOf(css, H) {
|
|
61
|
+
const v = cssVal(css, "font-size");
|
|
62
|
+
if (!v) return null;
|
|
63
|
+
let m;
|
|
64
|
+
if ((m = v.match(/calc\(\s*([\d.]+)\s*\*\s*var\(--h\)\s*\)/i))) return parseFloat(m[1]) * H;
|
|
65
|
+
if ((m = v.match(/([\d.]+)\s*cqh/i))) return (parseFloat(m[1]) / 100) * H;
|
|
66
|
+
if ((m = v.match(/([\d.]+)\s*vh/i))) return (parseFloat(m[1]) / 100) * H;
|
|
67
|
+
if ((m = v.match(/([\d.]+)\s*px/i))) return parseFloat(m[1]);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function planeWidthPx(plan, plane, W) {
|
|
71
|
+
const p = plan.planes && plan.planes[plane];
|
|
72
|
+
const css = p && (typeof p === "string" ? p : p.css);
|
|
73
|
+
const v = cssVal(css, "width");
|
|
74
|
+
if (!v) return null;
|
|
75
|
+
let m;
|
|
76
|
+
if ((m = v.match(/([\d.]+)\s*%/))) return (parseFloat(m[1]) / 100) * W;
|
|
77
|
+
if ((m = v.match(/([\d.]+)\s*px/))) return parseFloat(m[1]);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function setFontSize(css, fracOfH) {
|
|
81
|
+
const decl = `font-size: calc(${fracOfH.toFixed(3)} * var(--h))`;
|
|
82
|
+
if (/font-size\s*:/i.test(css || "")) return String(css).replace(/font-size\s*:\s*[^;}]+/i, decl);
|
|
83
|
+
return (css ? css.replace(/\s*$/, "").replace(/;?\s*$/, "; ") : "") + decl + ";";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main() {
|
|
87
|
+
const project = path.resolve(process.argv[2] || "");
|
|
88
|
+
if (!process.argv[2]) {
|
|
89
|
+
console.error("usage: fit-fonts.cjs <project-dir>");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const planPath = path.join(project, "plan.json");
|
|
93
|
+
let plan;
|
|
94
|
+
try {
|
|
95
|
+
plan = JSON.parse(fs.readFileSync(planPath, "utf8"));
|
|
96
|
+
} catch {
|
|
97
|
+
console.error("[fit-fonts] no plan.json (Cinematic only) — skipping");
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
const W = plan.width || 1920,
|
|
101
|
+
H = plan.height || 1080;
|
|
102
|
+
const groups = (plan.groups || []).concat(plan.crown_group ? [plan.crown_group] : []);
|
|
103
|
+
const MARGIN = 0.92; // leave 8% breathing room inside the box
|
|
104
|
+
const HERO_MIN_FRAC = 0.18; // a hero below ~0.18·h isn't "big" — keep it punchy, widen its box instead
|
|
105
|
+
|
|
106
|
+
let changed = 0;
|
|
107
|
+
for (const g of groups) {
|
|
108
|
+
const text = (g.words || []).map((w) => w.text).join(" ");
|
|
109
|
+
const nChars = text.replace(/\s/g, "").length + (g.words || []).length * 0.5; // glyphs + ~half-space gaps
|
|
110
|
+
if (nChars < 1) continue;
|
|
111
|
+
const fam = familyOf(g.css);
|
|
112
|
+
let adv = ADV[fam] ?? DEFAULT_ADV;
|
|
113
|
+
if (/text-transform\s*:\s*uppercase/i.test(g.css || "") || text === text.toUpperCase())
|
|
114
|
+
adv *= 1.05;
|
|
115
|
+
const sizePx = sizePxOf(g.css, H);
|
|
116
|
+
if (!sizePx) continue; // no explicit size → template default handles it
|
|
117
|
+
const boxW = (g.plane ? planeWidthPx(plan, g.plane, W) : null) || W;
|
|
118
|
+
const usable = boxW * MARGIN;
|
|
119
|
+
// A WRAPPING group only overflows if a SINGLE word is wider than the box (the rest
|
|
120
|
+
// wraps). A NOWRAP group must fit its whole line. So don't shrink wrapping narration
|
|
121
|
+
// down to one line — only force the whole line for nowrap; else just the longest word.
|
|
122
|
+
const nowrap = /white-space\s*:\s*nowrap/i.test(g.css || "");
|
|
123
|
+
const longestWord = (g.words || []).reduce(
|
|
124
|
+
(m, w) => Math.max(m, String(w.text || "").replace(/\s/g, "").length),
|
|
125
|
+
0,
|
|
126
|
+
);
|
|
127
|
+
const constrainChars = nowrap ? nChars : longestWord;
|
|
128
|
+
if (constrainChars < 1) continue;
|
|
129
|
+
const estW = constrainChars * adv * sizePx;
|
|
130
|
+
if (estW > usable) {
|
|
131
|
+
const newPx = usable / (constrainChars * adv);
|
|
132
|
+
let frac = Math.max(0.02, newPx / H);
|
|
133
|
+
const isHero = g.hero === true || /^(hero|crown)$/i.test(g.plane || "");
|
|
134
|
+
if (isHero && frac < HERO_MIN_FRAC) {
|
|
135
|
+
// The hero must stay BIG. If it won't fit its box while staying punchy, the BOX is
|
|
136
|
+
// too narrow (the hero should span the subject) — keep it at the floor + flag it,
|
|
137
|
+
// rather than silently shrinking the peak into a small word.
|
|
138
|
+
frac = HERO_MIN_FRAC;
|
|
139
|
+
g.css = setFontSize(g.css, frac);
|
|
140
|
+
changed++;
|
|
141
|
+
console.log(
|
|
142
|
+
`[fit-fonts] ⚠ ${g.id || "(group)"} HERO "${text.slice(0, 28)}" won't fit box ${Math.round(usable)}px while staying big → KEPT at floor ${frac}·h. WIDEN the hero plane (it should span the subject, centered), not shrink the peak.`,
|
|
143
|
+
);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
g.css = setFontSize(g.css, frac);
|
|
147
|
+
changed++;
|
|
148
|
+
console.log(
|
|
149
|
+
`[fit-fonts] ${g.id || "(group)"}: "${text.slice(0, 28)}" (${nowrap ? "nowrap line" : "longest word"}) est ${Math.round(estW)}px > box ${Math.round(usable)}px → shrink to ${frac.toFixed(3)}·h (${Math.round(newPx)}px)`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (changed) {
|
|
154
|
+
fs.writeFileSync(planPath, JSON.stringify(plan, null, 2));
|
|
155
|
+
console.log(`[fit-fonts] shrank ${changed} group(s) to fit; wrote plan.json`);
|
|
156
|
+
} else console.log("[fit-fonts] all groups fit their box — no change");
|
|
157
|
+
}
|
|
158
|
+
main();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""gen-stroke-path.py — generalized draw-on path generator.
|
|
3
|
+
|
|
4
|
+
Lays out ANY word in a single-line (pen-path) SVG font — Hershey/EMS — and emits
|
|
5
|
+
one continuous-dash-revealable path `d`. The glyph data IS the pen path, so
|
|
6
|
+
stroke-order reveal is exact by construction for any text, no per-word tuning.
|
|
7
|
+
|
|
8
|
+
Usage: gen-stroke-path.py <font.svg> <text> <target_width_px> <baseline_y> <x0>
|
|
9
|
+
Prints: the path `d` string + layout info on stderr.
|
|
10
|
+
"""
|
|
11
|
+
import re, sys
|
|
12
|
+
|
|
13
|
+
font_path, text, target_w, baseline_y, x0 = (
|
|
14
|
+
sys.argv[1], sys.argv[2], float(sys.argv[3]), float(sys.argv[4]), float(sys.argv[5]))
|
|
15
|
+
|
|
16
|
+
svg = open(font_path).read()
|
|
17
|
+
glyphs = {}
|
|
18
|
+
for m in re.finditer(r'<glyph\s+unicode="(.)"[^>]*?horiz-adv-x="([\d.]+)"(?:[^>]*?d="([^"]*)")?', svg):
|
|
19
|
+
ch, adv, d = m.group(1), float(m.group(2)), m.group(3) or ""
|
|
20
|
+
glyphs[ch] = (adv, d)
|
|
21
|
+
# default advance for space
|
|
22
|
+
space_adv = glyphs.get(" ", (300, ""))[0]
|
|
23
|
+
|
|
24
|
+
# total advance width in font units
|
|
25
|
+
total = 0.0
|
|
26
|
+
for ch in text:
|
|
27
|
+
total += glyphs.get(ch, (space_adv, ""))[0]
|
|
28
|
+
s = target_w / total # scale font-units → px
|
|
29
|
+
|
|
30
|
+
out = []
|
|
31
|
+
cursor = 0.0
|
|
32
|
+
NUM = re.compile(r"[-\d.]+")
|
|
33
|
+
for ch in text:
|
|
34
|
+
adv, d = glyphs.get(ch, (space_adv, ""))
|
|
35
|
+
if d:
|
|
36
|
+
# polylines only (M/L): transform every coordinate pair
|
|
37
|
+
toks = re.findall(r"([ML])\s+([-\d.]+)\s+([-\d.]+)", d)
|
|
38
|
+
for cmd, xs, ys in toks:
|
|
39
|
+
x = x0 + (cursor + float(xs)) * s
|
|
40
|
+
y = baseline_y - float(ys) * s # SVG-font y is UP; flip
|
|
41
|
+
out.append(f"{cmd} {x:.1f} {y:.1f}")
|
|
42
|
+
cursor += adv
|
|
43
|
+
|
|
44
|
+
print(" ".join(out))
|
|
45
|
+
print(f"[gen] chars={len(text)} scale={s:.3f} width={total*s:.0f}px "
|
|
46
|
+
f"subpaths={sum(1 for o in out if o.startswith('M'))}", file=sys.stderr)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* inject-fonts.cjs — inline the @font-face blocks each HTML actually uses.
|
|
4
|
+
*
|
|
5
|
+
* node inject-fonts.cjs <project-dir> [file.html ...]
|
|
6
|
+
*
|
|
7
|
+
* hyperframes' renderer only auto-supplies its ~18 CANONICAL_FONTS. Every other
|
|
8
|
+
* family (Anton, Bangers, VT323, Press Start 2P, …) falls back to a generic font
|
|
9
|
+
* unless the HTML ships a local @font-face — even when it "looks fine" locally,
|
|
10
|
+
* because that only works when the font happens to be installed as a system font.
|
|
11
|
+
* On a clean/offline/CI machine it silently degrades. (hyperframes' own font
|
|
12
|
+
* linter flags exactly this: font_family_without_font_face.)
|
|
13
|
+
*
|
|
14
|
+
* This step reads the bundled font library (modes/standard/fonts/fonts.css —
|
|
15
|
+
* base64 woff2, no sub-resources), finds which of those families the HTML uses,
|
|
16
|
+
* and inlines just those @font-face blocks into a <style id="hf-embedded-fonts">.
|
|
17
|
+
* Idempotent (re-running replaces the block). Families already declared in the
|
|
18
|
+
* HTML, hyperframes-canonical families, and CSS generics are left untouched.
|
|
19
|
+
*
|
|
20
|
+
* Runs BEFORE the layout gates + render so measure-layout and the capture both
|
|
21
|
+
* see the real glyph metrics, never a fallback.
|
|
22
|
+
*/
|
|
23
|
+
const fs = require("fs");
|
|
24
|
+
const path = require("path");
|
|
25
|
+
|
|
26
|
+
const SKILL_ROOT = path.resolve(__dirname, "..");
|
|
27
|
+
const FONTS_CSS = path.join(SKILL_ROOT, "modes", "standard", "fonts", "fonts.css");
|
|
28
|
+
const MARKER = "hf-embedded-fonts";
|
|
29
|
+
|
|
30
|
+
const GENERIC = new Set([
|
|
31
|
+
"serif",
|
|
32
|
+
"sans-serif",
|
|
33
|
+
"monospace",
|
|
34
|
+
"cursive",
|
|
35
|
+
"fantasy",
|
|
36
|
+
"system-ui",
|
|
37
|
+
"ui-serif",
|
|
38
|
+
"ui-sans-serif",
|
|
39
|
+
"ui-monospace",
|
|
40
|
+
"ui-rounded",
|
|
41
|
+
"math",
|
|
42
|
+
"emoji",
|
|
43
|
+
"fangsong",
|
|
44
|
+
"inherit",
|
|
45
|
+
"initial",
|
|
46
|
+
"unset",
|
|
47
|
+
"revert",
|
|
48
|
+
"revert-layer",
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
// Parse fonts.css → Map<lowercased family, [ @font-face block strings ]>.
|
|
52
|
+
function loadFontLibrary() {
|
|
53
|
+
let css;
|
|
54
|
+
try {
|
|
55
|
+
css = fs.readFileSync(FONTS_CSS, "utf8");
|
|
56
|
+
} catch {
|
|
57
|
+
console.error(
|
|
58
|
+
`[inject-fonts] missing ${FONTS_CSS} — run modes/standard/fonts/build-fonts-css.cjs`,
|
|
59
|
+
);
|
|
60
|
+
process.exit(2);
|
|
61
|
+
}
|
|
62
|
+
const lib = new Map();
|
|
63
|
+
// base64 data-URIs contain no "}", so [^}]* safely bounds a block.
|
|
64
|
+
const blockRe = /@font-face\s*\{[^}]*\}/gi;
|
|
65
|
+
const famRe = /font-family\s*:\s*(['"]?)([^;'"]+)\1/i;
|
|
66
|
+
let m;
|
|
67
|
+
while ((m = blockRe.exec(css)) !== null) {
|
|
68
|
+
const fam = m[0].match(famRe);
|
|
69
|
+
if (!fam) continue;
|
|
70
|
+
const key = fam[2].trim().toLowerCase();
|
|
71
|
+
if (!lib.has(key)) lib.set(key, []);
|
|
72
|
+
lib.get(key).push(m[0]);
|
|
73
|
+
}
|
|
74
|
+
return lib;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Families referenced anywhere in the HTML: CSS `font-family:` (in <style> or
|
|
78
|
+
// inline style="") and the data-font-family attribute hyperframes also honors.
|
|
79
|
+
function usedFamilies(html) {
|
|
80
|
+
const out = new Set();
|
|
81
|
+
const add = (stack) => {
|
|
82
|
+
for (const part of String(stack).split(",")) {
|
|
83
|
+
const name = part
|
|
84
|
+
.trim()
|
|
85
|
+
.replace(/^['"]|['"]$/g, "")
|
|
86
|
+
.trim()
|
|
87
|
+
.toLowerCase();
|
|
88
|
+
if (name && !GENERIC.has(name) && !/^var\(/.test(name)) out.add(name);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
// strip existing @font-face so we don't re-list the family it declares
|
|
92
|
+
const body = html.replace(/@font-face\s*\{[^}]*\}/gi, "");
|
|
93
|
+
for (const mm of body.matchAll(/font-family\s*:\s*([^;}{]+)/gi)) add(mm[1]);
|
|
94
|
+
for (const mm of html.matchAll(/data-font-family\s*=\s*["']([^"']+)["']/gi)) add(mm[1]);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Families the HTML ALREADY declares via @font-face — leave those alone.
|
|
99
|
+
function declaredFamilies(html) {
|
|
100
|
+
const out = new Set();
|
|
101
|
+
const famRe = /font-family\s*:\s*(['"]?)([^;'"]+)\1/i;
|
|
102
|
+
for (const mm of html.matchAll(/@font-face\s*\{[^}]*\}/gi)) {
|
|
103
|
+
const f = mm[0].match(famRe);
|
|
104
|
+
if (f) out.add(f[2].trim().toLowerCase());
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function injectInto(file, lib) {
|
|
110
|
+
let html;
|
|
111
|
+
try {
|
|
112
|
+
html = fs.readFileSync(file, "utf8");
|
|
113
|
+
} catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
// drop any previous injection so this is idempotent
|
|
117
|
+
html = html.replace(new RegExp(`\\s*<style id="${MARKER}">[\\s\\S]*?</style>`, "i"), "");
|
|
118
|
+
|
|
119
|
+
const used = usedFamilies(html);
|
|
120
|
+
const already = declaredFamilies(html);
|
|
121
|
+
const blocks = [];
|
|
122
|
+
const inlined = [];
|
|
123
|
+
for (const fam of used) {
|
|
124
|
+
if (already.has(fam)) continue;
|
|
125
|
+
const lb = lib.get(fam);
|
|
126
|
+
if (!lb) continue; // canonical / system / unknown — not ours to supply
|
|
127
|
+
blocks.push(...lb);
|
|
128
|
+
inlined.push(fam);
|
|
129
|
+
}
|
|
130
|
+
if (!blocks.length) {
|
|
131
|
+
fs.writeFileSync(file, html);
|
|
132
|
+
return { file: path.basename(file), inlined: [] };
|
|
133
|
+
}
|
|
134
|
+
const style = `<style id="${MARKER}">\n/* auto-embedded by inject-fonts.cjs — deterministic template fonts */\n${blocks.join("\n")}\n</style>`;
|
|
135
|
+
// Prefer right after <head...>; fall back to before </head>, then <html>, then prepend.
|
|
136
|
+
if (/<head[^>]*>/i.test(html)) html = html.replace(/<head[^>]*>/i, (m0) => `${m0}\n${style}`);
|
|
137
|
+
else if (/<\/head>/i.test(html)) html = html.replace(/<\/head>/i, `${style}\n</head>`);
|
|
138
|
+
else if (/<html[^>]*>/i.test(html))
|
|
139
|
+
html = html.replace(/<html[^>]*>/i, (m0) => `${m0}\n${style}`);
|
|
140
|
+
else html = style + "\n" + html;
|
|
141
|
+
|
|
142
|
+
fs.writeFileSync(file, html);
|
|
143
|
+
return { file: path.basename(file), inlined };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function main() {
|
|
147
|
+
const project = path.resolve(process.argv[2] || "");
|
|
148
|
+
if (!process.argv[2]) {
|
|
149
|
+
console.error("usage: inject-fonts.cjs <project-dir> [file.html ...]");
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
const lib = loadFontLibrary();
|
|
153
|
+
let files = process.argv.slice(3);
|
|
154
|
+
if (!files.length) files = ["index.html", "rail.html", "index_fg.html"];
|
|
155
|
+
files = files.map((f) => (path.isAbsolute(f) ? f : path.join(project, f)));
|
|
156
|
+
|
|
157
|
+
let touched = 0;
|
|
158
|
+
for (const f of files) {
|
|
159
|
+
const r = injectInto(f, lib);
|
|
160
|
+
if (r == null) continue;
|
|
161
|
+
if (r.inlined.length) {
|
|
162
|
+
console.log(`[inject-fonts] ${r.file}: embedded ${r.inlined.join(", ")}`);
|
|
163
|
+
touched++;
|
|
164
|
+
} else console.log(`[inject-fonts] ${r.file}: no non-canonical fonts to embed`);
|
|
165
|
+
}
|
|
166
|
+
if (!touched)
|
|
167
|
+
console.log(`[inject-fonts] nothing embedded (all fonts canonical/system or already declared)`);
|
|
168
|
+
}
|
|
169
|
+
main();
|