{"slug":"interflow-video-cut","title":"\u53e3\u64ad\u5207\u7247\u6210\u5361\u7247","description":"\u628a\u672c\u5730\u53e3\u64ad\u89c6\u9891\u5207\u6210\u6210\u7247\u5e76\u751f\u6210\u5143\u6570\u636e\uff0c\u81ea\u52a8\u4ea7\u51fa\u53ef\u590d\u7528\u7684\u5207\u7247\u4e0e\u5361\u7247\u7d20\u6750\u3002","category":"\u526a\u8f91\u4e0e\u5305\u88c5","tags":["\u53e3\u64ad","\u5207\u7247","\u526a\u8f91"],"author":"derek-zhuolin","source_url":"https://github.com/derek-zhuolin/interflow-video-cut/blob/main/SKILL.md","license":"MIT","status":"published","verification":"source_reviewed","verification_notes":"\u6765\u6e90 derek-zhuolin/interflow-video-cut\uff08SKILL.md\uff09\uff0c\u672c\u5730\u6253\u5305\u4e0a\u4f20\uff1b\u672a\u6267\u884c\u5305\u5185\u811a\u672c\u3002","revision":"13b0c72ad7504f36a883f834ac0f7e8d","created_at":"2026-10-28T15:38:54+00:00","updated_at":"2026-10-28T15:39:17+00:00","source_repo":"","source_path":"","source_commit":"","source_updated_at":"","stars":0,"proxy_score":null,"score":null,"grade":null,"dimensions":{},"evaluation":{},"installs":0,"platforms":[],"formats":[],"category_slug":"packaging","category_name":"\u526a\u8f91\u4e0e\u5305\u88c5","usage_guide":{},"read_url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut","skill_url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/SKILL.md","download_url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/download","install_url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/install","files":[{"path":"LICENSE","bytes":1069,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/LICENSE"},{"path":"README.md","bytes":10231,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/README.md"},{"path":"SKILL.md","bytes":41188,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/SKILL.md"},{"path":"assets/fonts/Caveat-400-latin.woff2","bytes":74932,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/Caveat-400-latin.woff2"},{"path":"assets/fonts/Caveat-700-latin.woff2","bytes":74932,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/Caveat-700-latin.woff2"},{"path":"assets/fonts/Inter-400-latin.woff2","bytes":23692,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/Inter-400-latin.woff2"},{"path":"assets/fonts/Inter-700-latin.woff2","bytes":24352,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/Inter-700-latin.woff2"},{"path":"assets/fonts/LXGWWenKaiTC-400-latin.woff2","bytes":19380,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/LXGWWenKaiTC-400-latin.woff2"},{"path":"assets/fonts/Virgil.woff2","bytes":61248,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/fonts/Virgil.woff2"},{"path":"assets/vendor/gsap.min.js","bytes":72925,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/assets/vendor/gsap.min.js"},{"path":"references/DESIGN_INDEX.md","bytes":31123,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/DESIGN_INDEX.md"},{"path":"references/backgrounds/backgrounds.js","bytes":12528,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/backgrounds/backgrounds.js"},{"path":"references/backgrounds/playground.html","bytes":14201,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/backgrounds/playground.html"},{"path":"references/card-contract.md","bytes":31278,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/card-contract.md"},{"path":"references/card-shots.md","bytes":6166,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/card-shots.md"},{"path":"references/components/components-gallery.html","bytes":16823,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/components/components-gallery.html"},{"path":"references/components/components.md","bytes":9132,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/components/components.md"},{"path":"references/components/style-playground-dark.html","bytes":12879,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/components/style-playground-dark.html"},{"path":"references/composition-assembly.md","bytes":21595,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/composition-assembly.md"},{"path":"references/composition-shell.html","bytes":8949,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/composition-shell.html"},{"path":"references/curve-motion/README.md","bytes":5519,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/curve-motion/README.md"},{"path":"references/curve-motion/curve-atmosphere.js","bytes":13495,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/curve-motion/curve-atmosphere.js"},{"path":"references/curve-motion/curve-motion.js","bytes":4877,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/curve-motion/curve-motion.js"},{"path":"references/editorial-print-montage.md","bytes":17786,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/editorial-print-montage.md"},{"path":"references/frames/clean.html","bytes":2294,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/frames/clean.html"},{"path":"references/frames/hairline.html","bytes":5230,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/frames/hairline.html"},{"path":"references/frames/polaroid.html","bytes":5337,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/frames/polaroid.html"},{"path":"references/impact-motion.md","bytes":13947,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/impact-motion.md"},{"path":"references/impact-motion/playground.html","bytes":53200,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/impact-motion/playground.html"},{"path":"references/layouts/deck.html","bytes":8384,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/deck.html"},{"path":"references/layouts/overlay.html","bytes":5290,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/overlay.html"},{"path":"references/layouts/pip.html","bytes":4479,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/pip.html"},{"path":"references/layouts/showcase.html","bytes":11262,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/showcase.html"},{"path":"references/layouts/split.html","bytes":3591,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/split.html"},{"path":"references/layouts/stack.html","bytes":3315,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/layouts/stack.html"},{"path":"references/narrative-progression.md","bytes":7105,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/narrative-progression.md"},{"path":"references/render-strategy.md","bytes":50929,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/render-strategy.md"},{"path":"references/styles/LICENSE.AGPL-3.0.txt","bytes":34523,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/LICENSE.AGPL-3.0.txt"},{"path":"references/styles/NOTICE-guizang-family.md","bytes":2320,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/NOTICE-guizang-family.md"},{"path":"references/styles/build-playground.mjs","bytes":18293,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/build-playground.mjs"},{"path":"references/styles/cinematic-bloom.html","bytes":6848,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/cinematic-bloom.html"},{"path":"references/styles/depth-parallax.html","bytes":7354,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/depth-parallax.html"},{"path":"references/styles/editorial-print.html","bytes":11407,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/editorial-print.html"},{"path":"references/styles/geom.html","bytes":8731,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/geom.html"},{"path":"references/styles/glass-hud.html","bytes":15126,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/glass-hud.html"},{"path":"references/styles/glass.html","bytes":9915,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/glass.html"},{"path":"references/styles/guizang-checklist.md","bytes":2633,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/guizang-checklist.md"},{"path":"references/styles/guizang-clean.css","bytes":30759,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/guizang-clean.css"},{"path":"references/styles/guizang-dna.md","bytes":9121,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/guizang-dna.md"},{"path":"references/styles/holo-iridescent.html","bytes":10135,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/holo-iridescent.html"},{"path":"references/styles/ink-figure.html","bytes":14500,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/ink-figure.html"},{"path":"references/styles/kinetic-megatype.html","bytes":7185,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/kinetic-megatype.html"},{"path":"references/styles/liquid-aurora.html","bytes":9480,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/liquid-aurora.html"},{"path":"references/styles/minimal.html","bytes":4914,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/minimal.html"},{"path":"references/styles/nebula-glass.html","bytes":15578,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/nebula-glass.html"},{"path":"references/styles/neon-grid-hud.html","bytes":14711,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/neon-grid-hud.html"},{"path":"references/styles/pastel-aura.html","bytes":11571,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/pastel-aura.html"},{"path":"references/styles/playground-gallery/README.md","bytes":4400,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/playground-gallery/README.md"},{"path":"references/styles/playground-gallery/neon-grid-hud.html","bytes":16447,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/playground-gallery/neon-grid-hud.html"},{"path":"references/styles/spatial.html","bytes":13168,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/spatial.html"},{"path":"references/styles/style-playground.html","bytes":265669,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/style-playground.html"},{"path":"references/styles/swiss.html","bytes":7151,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/swiss.html"},{"path":"references/styles/terminal.html","bytes":10488,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/styles/terminal.html"},{"path":"references/transitions-dev-motion.md","bytes":6419,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/references/transitions-dev-motion.md"},{"path":"scripts/auto-style.py","bytes":5638,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/auto-style.py"},{"path":"scripts/build-timeline.py","bytes":59586,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/build-timeline.py"},{"path":"scripts/card_shots.py","bytes":18271,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/card_shots.py"},{"path":"scripts/lint-cards.py","bytes":2083,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/lint-cards.py"},{"path":"scripts/test-build-timeline.py","bytes":8559,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/test-build-timeline.py"},{"path":"scripts/transcribe.js","bytes":6387,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/transcribe.js"},{"path":"scripts/validate-clean-card.mjs","bytes":5890,"url":"https://shiliuai.cn/api/v2/skills/interflow-video-cut/files/scripts/validate-clean-card.mjs"}],"content":"---\nname: interflow-video-cut\ndescription: Turn a local talking-head / \u53e3\u64ad video into metadata, transcript, and an AI-composed card-based video where the agent composes cards by cloning styled templates and filling them (designing bespoke only when content needs it), then renders to MP4. Ships with the Interflow AI club sign-off (\"Interflow AI \u51fa\u54c1\"). Use when the user asks for interflow-video-cut, \u53e3\u64ad\u6210\u7247, talking-head repurposing, video takeaways, transcript cleanup, or turning a spoken video into a captioned card video.\n---\n\n# Interflow Video Cut \u2014 \u53e3\u64ad\u6210\u7247 Workflow\n\nInterflow Video Cut converts a local video into a card-based composition: the\nagent designs the cards (timing + content), assembles one composition HTML, and\nrenders it to MP4 via `hyperframes`.\n\n**Default authoring mode: clone-and-recompose, not free-design.** Per card, start\nfrom a shipped fragment (`references/styles/<key>.html`); always swap the text +\naccent, and **recompose its layout freely to serve the card's point \u2014 while\nholding the style's DNA fixed** (fonts, theme palette, ornament, spacing scale,\noverflow guards). Cloning anchors the quality floor in the style's *tokens*, not\nin a frozen arrangement, so adjacent cards need not look identical. Hand-authoring\nfrom a blank file is the **exception**, only when content fits no reference.\n\n## CLI Resolution\n\n`vtake` CLI (`npx -y @notedit/vtake@latest`) handles extract/transcribe;\n`hyperframes` (`npx -y hyperframes@latest`) renders. Both auto-download from npm.\n`SKILL_DIR` = this skill's dir (host injects it as \"Base directory for this\nskill: \u2026\"); all `references/\u2026` + `scripts/\u2026` paths are relative to it.\n\n## Reference Map \u2014 read the right file at the right step\n\nThe workflow skeleton is below; the heavy detail lives in `references/`. Clone\nfrom the library, don't reinvent.\n\n**Loading discipline (progressive disclosure \u2014 read this first).** Every file\nbelow is **Level 3**: it costs zero tokens until you open it, so open it **only\nwhen you actually branch into its step, and read only the slice you need** \u2014 not\nthe whole file \"to be safe.\" Concretely: (1) **never pre-read** these at the\nstart of a run; pull each one at the moment its step arrives. (2) When a file is\na catalog/matrix (`DESIGN_INDEX.md`, the resolution tables in\n`render-strategy.md`), read **the chosen style's / ratio's row**, not the entire\nmatrix. (3) On the **fast path** \u2014 the user pre-approved a single known preset\n(e.g. says \"\u9ed8\u8ba4 / glass-hud / \u76f4\u63a5\u4ea7\") \u2014 skip `render-strategy.md` **and**\n`DESIGN_INDEX.md` entirely and go straight to that preset's recipe + the one\nstyle fragment it clones. Reading all four heavy refs on every run defeats the\nwhole point of moving them out of `SKILL.md`.\n\n| file | what's inside | read at |\n|---|---|---|\n| `references/DESIGN_INDEX.md` | full style \u00d7 layout \u00d7 frame matrix + a decision guide + the \u4e2d\u6587\u98ce\u683c\u8bcd\u5e93 (\u4e2d\u6587\u540d \u2194 key) | Step 6 / 7 |\n| `references/render-strategy.md` | **Step 7 in full** \u2014 the 5-question call (Channel A `AskUserQuestion` + Channel B plain-text), precompute rules, day/night auto-match, canvas/frame/bounds resolution tables, theme palettes, \u7559\u767d, camera rhythm (\u8fd0\u955c), layout compositions, storyboard render contract | Step 7 |\n| `references/card-contract.md` | **Step 8 in full** \u2014 clone-first steps, the card HTML contract + hard rules, NON-NEGOTIABLE overflow safety, portrait sizing, motion philosophy, the `data-anim` kinds table, and the `card-cta` brand-outro template | Step 8 |\n| `references/composition-assembly.md` | **Step 9 reference detail** \u2014 GSAP statement cheat sheet, timing validation, video framing reference, HyperFrames QA rules, hard-won gotchas, the fixed card-cta GSAP block | Step 9 |\n| `references/composition-shell.html` | the STATIC composition scaffold you `cp` and fill (do NOT retype it) | Step 9 |\n| `references/transitions-dev-motion.md` | **transitions.dev motion kit** \u2014 7 ported product-UI component effects (digit-flip / lines-reveal / blur-swap / badge-pop / check-draw / icon-swap / shimmer) + 2 handoffs (page / reveal), the CSS-cubic-bezier\u2192GSAP curve map, required card HTML/CSS hooks, and the **content-driven default-by-content table**. The kit is the default surface for graphic cards (every video shows crafted micro-motion, not plain text). | Step 6 / 8 (any graphic card) |\n| `references/impact-motion.md` (+ `impact-motion/playground.html` live demo, `?seek=<sec>` freezes frames) | **impact-motion kit\uff08\u70b8\u88c2\u65cf\u52a8\u6548\uff09v2** \u2014 12 hard-arrival kinds (type-on / char-scramble / word-slam / shake / light-sweep / stamp + mask-lines / magnetic-assemble / ink-bleed / rgb-split / split-flap / flip-3d) + 4 exit transitions (shatter / blinds / flash-cut / punch) + `slam` beat + `videoPunch` \u955c\u5934\u63a8\u8fd1, compiled by `build-timeline.py`, seeded & seek-safe. Contains **SLAM DNA \u4e09\u94c1\u5f8b**, the **Style \u00d7 impact \u51c6\u5165\u77e9\u9635** (incl. \u6b78\u85cf clean family + light-theme ink flash), and the **\u51b2\u51fb\u81ea\u52a8\u5206\u914d** signal table. Whole-film budget: **\u22643 impact uses**\uff08\u70b8\u88c2\uff0c\u4f46\u514b\u5236\uff09. | Step 6 (\u81ea\u52a8\u5206\u914d) / 8 (writing impact cards) |\n| `references/card-shots.md` | **\u5361\u7247\u5206\u955c\u5e93\uff08\u5f62\u72b6\u5c42\uff09** \u2014 7 \u4e2a\u6574\u5361\u591a\u5e55\u7f16\u6392\u9884\u8bbe\uff08number-landing / list-cascade / quote-hold / compare-split / mechanism-draw / token-cycle / headline-stack\uff09\uff0c\u7b7e\u540d\u52a8\u4f5c + \u69fd\u4f4d\u5951\u7ea6 + \u540e 50% \u63ed\u793a\u9ed8\u8ba4\uff0c`build-timeline.py` \u7f16\u8bd1\uff08`scripts/card_shots.py`\uff09\u3002\u542b **\u8bcd\u65f6\u89e6\u53d1**\uff08`data-anim-at-word` / \u69fd `atWord` / \u5b57\u7b26\u4e32 `videoPunch`\u2014\u2014\u63ed\u793a\u8e29\u8bf4\u8bdd\u4eba\u771f\u5b9e\u8bcd\u65f6\uff09\u4e0e **direction \u5bfc\u6f14\u5757**\uff08\u524d\u94fa\u540e\u51bb / \u6784\u56fe\u8f6e\u6362 / \u547c\u5438\u5e27 lint\uff0copt-in\uff09\u3002\u5185\u5bb9\u2192\u5206\u955c\u9ed8\u8ba4\u8868\u5728\u6587\u5185\u3002 | Step 6 (\u9009\u5206\u955c/\u5bfc\u6f14\u5757) / 8 (\u5199 shot \u5361\u7684 DOM \u5951\u7ea6) |\n| `references/narrative-progression.md` | **\u53d9\u4e8b\u9012\u8fdb\u7f16\u6392** \u2014 when the transcript *argues / explains* (mechanism, cause\u2192effect, this-vs-that, setup\u2192payoff), 4 arcs (\u95ee\u9898\u2192\u673a\u5236\u2192\u4ea7\u51fa \u00b7 \u5206\u9636\u6bb5\u63ed\u793a \u00b7 \u5bf9\u6bd4\u9012\u8fdb \u00b7 \u8ba4\u77e5\u7ffb\u8f6c) that sequence cards + stage each card's reveal so motion *carries the logic*. Expressed entirely in `beat`/`transition`/`data-anim`/`zone` \u2014 no new visual style. Skip for a flat list of independent takeaways. | Step 6 (sequencing an explainer) |\n| `references/editorial-print-montage.md` | the multi-asset montage kit for the `editorial-print` style (5 layout primitives, 3 transitions, asset staging, woven vs standalone modes) | when style = editorial-print |\n| `references/styles/*.html` | self-contained style fragments \u2014 **clone these**; includes the \u70b8\u88c2\u65cf (neon-grid-hud / liquid-aurora / holo-iridescent + playground-gallery DNA) | Step 7 / 8 |\n| `references/styles/guizang-dna.md` (+ `guizang-clean.css` \u7ec4\u4ef6 + `guizang-checklist.md` \u8d28\u68c0) | **\u7b80\u6d01\u6392\u7248\u7c7b\u00b7\u6b78\u85cf\u5bb6\u65cf**\u7684 DNA \u7eaa\u5f8b\u5c42\uff08\u4e24\u652f\u67f1\u3001\u5b57\u53f7\u5b57\u91cd\u8026\u5408\u3001\u9884\u8bbe\u8c03\u8272\u677f\u3001\u7ec4\u4ef6\u5e93\uff09\u3002\u7edf\u7ba1 swiss / minimal / terminal / editorial-print / pastel-aura | \u9009\u4e86 clean \u5bb6\u65cf\u4efb\u4e00\u6b3e\u65f6\uff08Step 7/8\uff09|\n| `references/components/components.md` (+ `components-gallery.html` \u6e32\u67d3 demo / \u62ac\u53d6\u6e90) | **\u89c6\u89c9\u7d20\u6750\u7ec4\u4ef6\u5e93\u00b7\u9ad8\u9891\u5305**\uff08\u5f52\u85cf\u5bb6\u65cf\u65b0\u6210\u5458\uff0c13 \u4e2a\u5185\u5bb9\u5f62\u6001\uff1a\u6298\u7ebf/\u67f1/\u73af\u5f62/\u5927\u6570\u5b57 \u00b7 \u7c7b\u6bd4/\u9ed1\u76d2/\u7b49\u5f0f/\u5149\u8c31/\u51b0\u5c71/\u5bf9\u7167 \u00b7 \u7ec8\u7aef/\u5bf9\u8bdd/\u4ee3\u7801\uff09\u3002\u5185\u5bb9\u547d\u4e2d\u67d0\u79cd\u5f62\u6001\u65f6\u62ac\u4e00\u4e2a\u7ec4\u4ef6\u8fdb\u5361\uff0c\u8d28\u91cf\u9501\u6b7b\u5728\u89c4\u683c\u4e0a\u3002\u542b content\u2192\u7ec4\u4ef6 \u67e5\u8868\u3002**\u4ec5 clean \u5bb6\u65cf**\uff0cCSS \u5728 guizang-clean.css | clean \u5bb6\u65cf\u5361\u5185\u5bb9\u547d\u4e2d\u7ed3\u6784\u5f62\u6001\u65f6\uff08Step 6 \u9009\u5f62 / Step 8 \u5199\u5361\uff09|\n| `references/layouts/*.html` | layout skeletons (videoBounds + cardBounds, landscape/portrait); neon-grid-hud carries its own window-scene | Step 7 / 9 |\n| `references/frames/*.html` | 3 frame chrome fragments (clean / hairline / polaroid) | Step 9 |\n| `references/curve-motion/README.md` | **\u53ef\u9009\u89c6\u89c9\u589e\u5f3a** \u2014 \u6570\u5b66\u66f2\u7ebf\u6bcd\u9898\uff0c**\u6309\u7528\u9014\u5206\u6d41**\uff1a\u6c1b\u56f4\u5e95(\u4efb\u610f\u66f2\u7ebf) \u00b7 \u659c\u5b57 textPath(**\u4ec5\u5f00\u653e\u66f2\u7ebf `openKeys`**\uff0c\u95ed\u5408\u66f2\u7ebf\u6392\u5b57\u5fc5\u6ea2\u51fa) \u00b7 clip \u88c1\u56fe\u526a\u5f71(**\u4ec5\u95ed\u5408\u66f2\u7ebf**) \u00b7 \u91c7\u6837\u70b9\u5e03\u70b9(\u4efb\u610f) + \u6cbf\u66f2\u7ebf\u4e1d\u6ed1\u5165\u573a\u6f02\u79fb\uff08`curveIn`/`curveBob`\uff09\u3002\u5168\u95ed\u5f0f `draw(t)`\u3001\u786e\u5b9a\u6027 seek \u5b89\u5168\uff1b\u914d\u6697\u5e95\u98ce\u683c\uff08nebula-glass/glass/spatial/geom\uff09\uff0c\u4e0d\u53e0 glass-hud/swiss/minimal\u3002**Step 7 \u7684\u66f2\u7ebf\u9002\u914d\u98ce\u683c\u4f1a\u89e6\u53d1\u4e00\u6b21 curve-intent \u6761\u4ef6\u8ffd\u95ee**\uff08\u89c1 render-strategy.md\u300c5b\u300d\uff09 | Step 7 / 8 / 9\uff08\u60f3\u52a0\u9ad8\u7ea7\u52a8\u6001\u8d28\u611f\u65f6\uff09 |\n\n## Workflow\n\n### Interaction contract \u2014 \u524d\u7f6e\u4e00\u6b21\u95ee\u5168\uff0c\u7136\u540e\u65e0\u4eba\u503c\u5b88\u8dd1\u5b8c\uff08ALL channels\uff09\n\n**The user hands you a video to get back a finished film, not to babysit a\npipeline.** So the ONLY moment you ask the user anything is **once, upfront**\n(Step 3.5), in a single batched round \u2014 ratio / layout / style / \u8fd0\u955c / card\ndensity. After they answer, you run the\n**entire** pipeline (transcribe \u2192 correct \u2192 storyboard \u2192 cards \u2192 assemble \u2192\nrender) **autonomously to a finished MP4, with\nno further questions** \u2014 so they can walk away and come back to a complete\nwork. This ordering is **identical on every invocation channel** (\u624b\u673a CLI,\n\u98de\u4e66 bot, desktop) \u2014 the channel only changes the question *transport* (native\n`AskUserQuestion` vs plain-text), never the *timing*.\n\nRules:\n- **Front-load, don't drip.** Never ask a question mid-pipeline that you could\n  have asked in Step 3.5. The old flow asked visual direction at Step 7 (after\n  transcribe) \u2014 that's the bug this contract fixes. Precompute\n  everything askable from the **file alone** (metadata + color analysis) so the\n  whole batch fires before any slow/mechanical step.\n- **Autonomous = render and deliver, not preview-and-wait.** On the autonomous\n  path you self-QA with snapshots (Step 10) and go straight to render (Step 11) \u2014\n  the user reviews the **finished MP4** and asks for revisions after. Only drop\n  into the interactive preview loop if the user explicitly says they want to\n  watch/iterate live.\n- **Stop early only for a genuine blocker** (missing file, ASR rate-limit, a\n  contradiction in the request) \u2014 not for a preference you could have batched.\n- If the user *explicitly* pre-answers in their opening message (\"\u7ad6\u5c4f glass \u76f4\u63a5\u4ea7\")\n  or says \"\u4f60\u770b\u7740\u6765/\u9ed8\u8ba4\", skip Step 3.5's questions and proceed on those + the\n  auto-recommendations.\n\n### 1. Check Environment\n\n```bash\nnpx -y @notedit/vtake@latest doctor\n# confirm bundled assets:\nls \"<SKILL_DIR>/assets/fonts\" \"<SKILL_DIR>/assets/vendor/gsap.min.js\"\n```\n\nRequired:\n\n- `ffmpeg` / `ffprobe` (system)\n- `python3` (stdlib only) \u2014 for `scripts/auto-style.py`, the auto style-match by video color in Step 7.0\n- `<SKILL_DIR>/assets/fonts/*.woff2`, `<SKILL_DIR>/assets/vendor/gsap.min.js` (bundled inside this skill, staged to work dir in Step 9)\n\nOptional:\n\n- `ELEVEN_API_KEY` \u2014 set \u2192 `vtake transcribe` hits ElevenLabs directly (no rate\n  limit). Unset \u2192 proxy `https://vtake.app/api/transcribe` (**3 req/min/IP**;\n  override via `VTAKE_TRANSCRIBE_ENDPOINT`).\n\nStrongly recommended on macOS for `hyperframes render`:\n\n```bash\nexport PRODUCER_BROWSER_GPU_MODE=hardware\n```\n\n### 2. Create a Work Directory\n\n```bash\nVIDEO_PATH=\"/absolute/path/input.mp4\"\nWORK_DIR=\".interflow-video-work/$(basename \"$VIDEO_PATH\" | sed 's/\\.[^.]*$//')\"\nmkdir -p \"$WORK_DIR\"\n```\n\n### 3. Extract Audio and Metadata\n\n```bash\nnpx -y @notedit/vtake@latest extract \"$VIDEO_PATH\" --out-dir \"$WORK_DIR\"\n```\n\nOutputs: `metadata.json` (duration, width, height, fps) + `audio.mp3`.\n\n### 3.5 Upfront Consultation \u2014 ask EVERYTHING here, once (then go autonomous)\n\n**This is the single user-interaction gate.** Everything askable is decidable\nfrom the **file alone** \u2014 no transcript needed yet \u2014 so ask it all now, before\nthe slow steps, then run the rest untouched (per the Interaction contract above).\n\n**Precompute first (file-only, cheap):**\n\n```bash\npython3 \"<SKILL_DIR>/scripts/auto-style.py\" \"$VIDEO_PATH\" --json\n# \u2192 {\"mode\",\"temp\",\"recommend\":[...],\"recommend_cn\":[...]}  \u2192 recommendedStyle\n```\n- `recommendedRatio` from `metadata.json` aspect (\u22651.5\u219216:9 \u00b7 \u22640.7\u21929:16 \u00b7 else 4:5).\n  **iPhone `.MOV` caveat:** ffprobe may report a rotated `1920\u00d71080` that displays\n  as portrait \u2014 check `stream_side_data=rotation` before trusting the aspect.\n- `autoCount` from duration \u00d7 **assumed-medium** density (Step 6 math) \u2014 label it\n  \"\u7ea6 N \u5f20\"; you refine the exact count after the transcript exists. Good enough to ask.\n\n**Then ask ONE batched round** \u2014 the 5 visual questions. Use the best channel\n(native `AskUserQuestion`; else the plain-text template). The 5 visual questions\n+ resolution tables live in\n[`references/render-strategy.md`](references/render-strategy.md) (read its question\ncall now).\n\nRecord all 5 answers in working memory: `ratio / layout / style / rhythm /\ncardDensity`. These drive Steps 6, 7, 8 \u2014 **do not re-ask any\nof them later.** (Channels without a native question tool: post the plain-text\nbatch as one message, parse the reply, proceed. Same timing on every channel.)\n\n> If the user already stated preferences in their opening message, or said\n> \"\u9ed8\u8ba4/auto/\u4f60\u770b\u7740\u6765\", skip the questions and use those + the auto-recommendations.\n> After this gate, you do not pause again until the finished MP4 (Step 12) \u2014\n> unless a genuine blocker appears.\n\n### 4. Transcribe (provider-aware: \u706b\u5c71 Seed ASR or ElevenLabs)\n\nBoth produce the **same** `transcript.json` shape (`{ segments, words, raw }`, word-\nlevel timestamps in seconds) \u2014 the rest of the pipeline doesn't care which ran.\n\n```bash\nif [ -n \"$VOLC_ASR_API_KEY\" ]; then\n  # \u706b\u5c71\u5f15\u64ce Seed ASR 2.0 \u2014 \u4e2d\u6587\u53cb\u597d\u3001\u4fbf\u5b9c\u3001\u8bcd\u7ea7\u65f6\u95f4\u6233\u3002Key \u8d70 env\uff08\u4e0d\u8fdb git\uff09\u3002\n  node \"$SKILL_DIR/scripts/transcribe.js\" --audio \"$WORK_DIR/audio.mp3\" --out-dir \"$WORK_DIR\"\nelse\n  # fallback: ElevenLabs via vtake (proxy mode works key-free, 3 req/min/IP)\n  npx -y @notedit/vtake@latest transcribe \"$WORK_DIR/audio.mp3\" --out-dir \"$WORK_DIR\" --asr elevenlabs\nfi\n```\n\nOutput: `transcript.json` with `{ segments, words, raw }`.\n\n**Two ASR providers, pick by env:**\n- **\u706b\u5c71 Seed ASR** (`VOLC_ASR_API_KEY` set) \u2014 async submit (base64 audio, **no\n  public URL needed**); `transcribe.js` resamples to 16k mono first, polls, and\n  emits the same shape. Optional: `VOLC_ASR_RESOURCE_ID` (default `volc.seedasr.auc`),\n  `VOLC_ASR_MODEL` (default `bigmodel`). Re-convert a saved result without re-\n  billing: `node transcribe.js --from-result volcengine_result.json --out-dir \"$WORK_DIR\"`.\n- **ElevenLabs** (no `VOLC_ASR_API_KEY`) \u2014 `vtake` proxy mode runs key-free out of\n  the box (zero model download) and only hits the rate limit below. There is no\n  local/whisper path.\n\n**Rate limiting (proxy mode only \u2014 no `ELEVEN_API_KEY`):** the server allows\n3 requests per minute per IP. If you see an error starting with\n`rate_limited:` or `service_busy:`, do **not** auto-retry \u2014 stop and tell\nthe user how many seconds to wait (the message includes the retry hint),\nthen resume from this step when they ask again.\n\n> **Note \u2014 this skill is additive only.** It *decorates* a take (cards over\n> video); it does NOT \u53bb\u53e3\u6c34\u8bcd / \u53bb\u6c14\u53e3 / \u53bb\u5e9f\u8bdd. It assumes a reasonably clean\n> recording. If a raw \u53e3\u64ad has lots of \u53e3\u6c34\u8bcd / \u5361\u987f / \u91cd\u8bf4, those stay in the\n> footage and get baked under your cards \u2014 clean it first with whatever editor\n> you prefer, then feed the cleaned video here. (Automatic rough-cut is no longer\n> wired into this pipeline.)\n\n### 5. Correct Transcript\n\nRead `transcript.json` and fix obvious ASR errors:\n\n- Homophones, product names, technical terms, punctuation\n- Preserve all `start` / `end` timestamps\n- Prefer editing `segments[].text` only\n- Edit individual `words[].word` only for clear one-to-one replacements\n\n### 6. Draft a Lightweight Storyboard (in chat)\n\n**No CLI involved.** Read `transcript.json` + `metadata.json` and design\ncards directly. `storyboard.json` is an agent-internal planning artifact\n\u2014 no vtake CLI command consumes it; it exists so you can think clearly\nabout timing and content before writing each card's HTML. Keep the\nshape consistent with the example below so the same outline can drive\nthe composition you author in Step 9:\n\n```json\n{\n  \"schemaVersion\": 3,\n  \"composition\": {\n    \"fps\": 30,\n    \"width\": 1080,\n    \"height\": 1920,\n    \"durationSeconds\": 121.2,\n    \"layout\": \"portrait\",\n    \"themeId\": \"noir\",\n    \"seed\": 42,\n    \"background\": { \"key\": \"dark-particles\", \"accent\": \"#7aa2ff\", \"opacity\": 0.9 }\n  },\n  \"videoTrack\": {\n    \"sourcePath\": \"input-video.mp4\",\n    \"startSec\": 0,\n    \"endSec\": 121.2,\n    \"bounds\": { \"x\": 0, \"y\": 0, \"width\": 1080, \"height\": 1920 }\n  },\n  \"subtitles\": { \"enabled\": false },\n  \"cards\": [\n    {\n      \"id\": \"card-01\",\n      \"intent\": \"Hook with the speaker's anxious midnight question\",\n      \"startSec\": 0.5,\n      \"endSec\": 13.0,\n      \"accentIndex\": 0,\n      \"zone\": \"fullscreen\",\n      \"beat\": \"kinetic\",\n      \"contentHints\": {\n        \"kicker\": \"AN HONEST QUESTION\",\n        \"title\": \"\u665a\u4e0a 11 \u70b9\u7684\u7075\u9b42\u63d0\u95ee\",\n        \"detail\": \"\u5ba2\u6237\u516d\u5341\u79d2\u8bed\u97f3\uff1a\u300c\u4eba\u6c11\u5e01\u4f1a\u5347\u503c\uff0c\u6211\u7684\u7f8e\u91d1\u4fdd\u5355\u662f\u4e0d\u662f\u4e8f\u60e8\u4e86\uff1f\u300d\"\n      }\n    }\n  ]\n}\n```\n\n**Required Card fields:**\n\n| field | type | purpose |\n|---|---|---|\n| `id` | string | stable id used in card HTML & GSAP selectors |\n| `intent` | string | natural-language description; fed to card synthesis |\n| `startSec` / `endSec` | number | times in seconds (endSec > startSec) |\n| `accentIndex` | 0 \\| 1 \\| 2 \\| 3 \\| 4 | which of the 5 theme accent colors this card pulls |\n| `zone` | enum (see below) | where on the canvas the card lives |\n| `contentHints` | object | free-form bag; agent puts kicker/title/detail/data/quote here |\n| `archetype` (optional) | string | free-form label you may attach to remember a card's pattern; absent = free-form, which is the default |\n| `beat` (optional) | enum: `settle` \\| `cut` \\| `hold` \\| `kinetic` \\| `montage` \\| `footage` \\| `slam` | **the card's motion = its INTENT** (not a random gesture). `build-timeline.py` picks the whole enter/life/exit by this. Absent = `settle` (calm slip+drift, the legacy default). Assign by what the card means \u2014 hook\u2192`kinetic` \u6216 `slam`\uff08\u6574\u5361\u9010\u5757\u7838\u843d+\u6b7b\u9759\uff0cimpact \u65cf\u3001\u8ba1\u5165 \u22643 \u9884\u7b97\u3001\u5361\u9700 \u22652.5s\uff09, \u91cd\u9524/\u4e25\u8083\u2192`cut`, \u91d1\u53e5/\u7559\u767d\u2192`hold`, \u7f57\u5217/\u8bc1\u636e\u2192`montage`, \u89c6\u9891\u5f53\u4e3b\u89d2\u2192`footage`. See the beat table in `composition-assembly.md`. |\n| `videoPunch` (optional) | (number \\| string)[] \u2014 \u79d2\uff08\u76f8\u5bf9\u5361 start\uff09\u6216**\u8981\u8e29\u7684\u8bcd** | **\u8bf4\u8bdd\u4eba\u7206\u70b9\u77ac\u95f4\u7684\u955c\u5934\u786c\u63a8\u8fd1**\uff1a`#video-wrap` scale 1\u21921.06 (0.14s power4.out) \u2192 \u56de 1 (0.3s)\u3002\u5b57\u7b26\u4e32\u6761\u76ee\uff08\u5982 `[\"\u79c1\u4fe1\"]`\uff09= \u4ece transcript \u8bcd\u7ea7\u65f6\u95f4\u6233\u89e3\u6790\u3001\u63a8\u8fd1\u843d\u5728\u8bf4\u8bdd\u4eba**\u8bf4\u51fa\u8be5\u8bcd\u7684\u77ac\u95f4**\u3002\u4e24\u6b21\u95f4\u9694 \u22650.5s\uff1b\u4e00\u7247 \u22642 \u6b21\uff1b\u4e0d\u8ba1\u5165 impact \u9884\u7b97\u3002 |\n| `shot` (optional) | `{key, slots, params}` | **\u5361\u7247\u5206\u955c\u9884\u8bbe**\uff08\u5f62\u72b6\u5c42\uff09\uff1a\u4e00\u5f20\u5361\u7684\u6574\u6bb5\u591a\u5e55\u7f16\u6392\u7531\u7f16\u8bd1\u5668\u5c55\u5f00\u2014\u20147 \u4e2a\u9884\u8bbe\uff08number-landing / list-cascade / quote-hold / compare-split / mechanism-draw / token-cycle / headline-stack\uff09\uff0c\u6bcf\u4e2a\u5e26\u7b7e\u540d\u52a8\u4f5c + \u69fd\u4f4d\u5951\u7ea6 + \u540e 50% \u63ed\u793a\u9ed8\u8ba4\uff1b\u69fd\u53ef `atWord` \u8e29\u8bcd\u65f6\u3002\u58f0\u660e\u65f6\u63a5\u7ba1 enter/life\uff08beat \u5ffd\u7565\uff09\uff1b\u6821\u9a8c\u5931\u8d25\u56de\u843d beat\u3002\u89c1 `references/card-shots.md`\u3002\u7559\u7ed9\u503c\u5f97\u7f16\u6392\u7684\u8282\u70b9\uff08\u4e00\u7247 2-4 \u4e2a\uff09\uff0c\u666e\u901a\u5361\u7528 beat\u3002 |\n| `transition` (optional) | enum: `cut` \\| `fade` \\| `slide` \\| `wipe` \\| `page` \\| `reveal` \\| `shatter` \\| `blinds` \\| `flash-cut` \\| `punch` | card-to-card handoff (**now live** in `build-timeline.py`): `cut` = hard frame boundary (no slip overlap; set next card's `startSec` = this `endSec`), `wipe` = clip sweep, `fade`/`slide`/absent = the silky slip-up; `page`/`reveal` = transitions.dev handoffs; `shatter`/`blinds`/`flash-cut`/`punch` = impact kit\uff08`flash-cut` is a hard boundary like `cut`; `shatter` needs the card \u22651.6s; \u22643 impact uses per film \u2014 see `references/impact-motion.md`\uff09. |\n| `styleKey` (optional) | string (a `references/styles/<key>`) | which style fragment to clone this card from. Absent = the film's **primary** style. Set it only on **accent cards** (hero / big-number / outro) to pull a tonally-compatible **sibling** style \u2014 see the style-family note in Step 7. Colors stay coherent automatically: every fragment paints from `var(--accent-N)`, so a sibling inherits the theme palette. |\n| `componentKey` (optional) | string (a `references/components/<key>`) | which **visual component** this card's content maps to (\u6298\u7ebf/\u67f1/\u73af\u5f62/\u5927\u6570\u5b57 \u00b7 \u7c7b\u6bd4/\u9ed1\u76d2/\u7b49\u5f0f/\u5149\u8c31/\u51b0\u5c71/\u5bf9\u7167 \u00b7 \u7ec8\u7aef/\u5bf9\u8bdd/\u4ee3\u7801). Set it when the transcript hits a structured shape (a trend, a ratio, an analogy, a dialogue\u2026) \u2014 pick via the content\u2192\u7ec4\u4ef6 table in `references/components/components.md`. Absent = free-compose (today's default). **clean \u5bb6\u65cf only.** |\n\n**Composition-level `background` (optional)** \u2014 a moving atmosphere layer behind the\ncards / above the video. `{ key, accent, opacity }`; `key` \u2208 backgrounds \u5e93\n(`dark-particles` / `starfield` / `aurora` / `grid-hud` / `mesh-gradient`) \u6216\n`curve:<\u66f2\u7ebf>`\uff08\u66f2\u7ebf**\u6c1b\u56f4\u5e95**\u2014\u2014\u6c1b\u56f4\u5f52\u8fd9\u5c42\uff0c\u4e0d\u662f\u524d\u666f\u659c\u5b57\uff09\u3002`build-timeline.py` \u81ea\u52a8\u6ce8\u5165\n`<canvas>` + `draw(t)` \u94a9\u5b50\uff08Step 9 \u8bb0\u5f97 `cp` `backgrounds.js` + `curve-atmosphere.js` \u8fdb\n`vendor/`\uff09\u3002\u9009\u62e9\u5728 Step 7\u300c\u80cc\u666f\u5c42\u300d\u95ee\u9898\u91cc\u51b3\u5b9a\uff08\u89c1 render-strategy.md\uff09\u3002\u5168\u95ed\u5f0f `draw(t)`\u3001\nseek \u5b89\u5168\u3002\n\n**Five `zone` values** (resolve to card-host pixel bounds in Step 9; full bounds\ntable in `references/composition-assembly.md`): `fullscreen` (whole canvas \u2014\nhero / big numbers) \u00b7 `whiteboard-area` (40px inset or portrait bottom-45% \u2014\ndense data) \u00b7 `lower-third` (bottom 30% \u2014 annotate over video) \u00b7 `side-panel`\n(landscape right-42% / portrait bottom-40% \u2014 data beside video) \u00b7 `video-overlay`\n(full canvas, mostly-transparent card \u2014 overlay on full-bleed video). Video\nbounds are set **once** (`videoTrack.bounds`); \"moving\" video between cards =\nGSAP tweens on `#video-wrap` (Step 9).\n\n**\u51b2\u51fb\u81ea\u52a8\u5206\u914d\uff08pipeline \u5168\u81ea\u52a8 \u2014 drafting \u65f6\u6267\u884c\uff0c\u7528\u6237\u4e0d\u624b\u9009\uff09\u3002** \u626b\u63cf\u4fee\u6b63\u540e\u7684\ntranscript\uff0c\u547d\u4e2d\u4fe1\u53f7\u5c31\u81ea\u52a8\u5206\u914d impact\uff0c\u6309\u4f18\u5148\u7ea7\u53d6**\u6700\u5f3a \u22643 \u4e2a**\uff08\u9884\u7b97\u786c\u7ea6\u675f\uff0c\n\u8d85\u4e86 build-timeline.py \u4f1a WARN\uff09\uff0c\u5176\u4f59\u4e00\u5f8b\u56de\u843d transitions.dev \u4e1d\u6ed1 kit\uff1a\n\u2460 **\u8ba4\u77e5\u7ffb\u8f6c**\uff08\"\u4f46\u5176\u5b9e/\u771f\u76f8\u662f/\u5927\u5bb6\u90fd\u9519\u4e86\"\uff09\u2192 break \u5361 `transition: shatter` +\n\u4e0b\u4e00\u5f20 `word-slam` \u7acb\u65b0\u89c2\u70b9\uff08\u4f18\u5148\u7ea7\u6700\u9ad8\uff09\uff1b\u2461 **\u5f00\u573a hook / \u5168\u7247\u6700\u5f3a\u4e3b\u5f20** \u2192\n`beat: \"slam\"`\uff1b\u2462 **\u60c5\u7eea\u7206\u70b9 / \u7ae0\u8282\u786c\u5207** \u2192 `flash-cut` \u6216 `punch` + \u53ef\u9009\n`videoPunch` \u8e29\u5728\u91cd\u97f3\u97f3\u8282\u4e0a\uff1b\u2463 **\u547d\u4ee4 / \u4ee3\u7801 / \u5de5\u5177\u540d** \u2192 `type-on`\u3002\n\u5b8c\u6574\u4fe1\u53f7\u8868 + Style \u00d7 impact \u51c6\u5165\u77e9\u9635\uff08\u6b78\u85cf clean \u5bb6\u65cf\u54ea\u4e9b\u614e\u7528\uff09\u89c1\n[`references/impact-motion.md`](references/impact-motion.md)\u3002\n\n**No prescribed roles or arc** \u2014 cards emerge from what the video says (all\nquotes, all data, open on a number or a story; let the transcript drive).\n**But when the transcript *argues or explains*** (a mechanism, cause\u2192effect,\nthis-vs-that, setup\u2192payoff \u2014 you can say \"first\u2026 which causes\u2026 which is why\u2026 so\u2026\"\nacross the cards), reach for [`references/narrative-progression.md`](references/narrative-progression.md):\n4 arcs that sequence the cards + stage each card's reveal so motion carries the\nlogic, all in `beat`/`transition`/`data-anim` (no new style). Skip it for a flat\nlist of independent takeaways \u2014 those stay\u5e73\u94fa.\n\n**Card boundaries \u2014 one intent per card** (\"let the transcript drive\" \u2260 \"cut\nanywhere\"). A boundary belongs where the speaker *pivots to a new idea*; a card\nspans the stretch between two boundaries. Signals: **topic shift** (\"\u2026now here's\nwhat works\" = new card) \u00b7 **argument unit** (a setup\u2192proof\u2192payoff >~20s = 2\u20133\ncards, one per move) \u00b7 **distinct claim/number/comparison** (each its own card,\nno 4-facts data-dump) \u00b7 **emphasis/repetition** (repeated phrase / \"the key\npoint\" = its own beat) \u00b7 **shot change** (face\u2192screen-share\u2192prop). The math\nbelow sets *how many*; these set *where*. Disagree \u2192 trust the intents; never\nsplit one idea or fuse two to hit a number.\n\n**How many takeaways? \u2014 auto-infer from duration + density.** No fixed\nupper limit. Floor is fixed: **minimum 5 cards**.\n\n**Step 1 \u2014 base pace by duration** (natural sec/card for medium density):\n\n| video duration | base pace (sec per card) |\n|---|---|\n| < 60s (short reel) | **6\u20138s** |\n| 60s \u2013 3 min | **8\u201312s** |\n| 3 \u2013 10 min | **12\u201320s** |\n| 10 \u2013 30 min | **20\u201335s** |\n| > 30 min | **30\u201360s** |\n\n**Step 2 \u2014 density multiplier:** High density (many numbers / distinct claims / staccato) **\u00d7 0.7** \u00b7 Medium (mixed data + narrative) **\u00d7 1.0** \u00b7 Low (slow narrative, one idea over many sentences) **\u00d7 1.4**.\n\n**Step 3 \u2014 compute:**\n\n```\ncardCount = max(5, round(videoSec / (basePace \u00d7 densityMultiplier)))\n```\n\nAlways sanity-check against content: the math gives a starting count, but the\nactual intents decide the final count.\n\n**Speaker presence \u2014 keep the talking head on screen** (unless the user wants a\nfaceless explainer): cards annotate, they don't replace. Default = full-bleed/\nlarge-PIP speaker on opening + closing cards, \u2265 small PIP/side-panel where the\nspeaker makes a personal point; data-heavy cards can go full-card briefly.\n\n**Distill, don't transcribe \u2014 a card is information design.** The #1 failure is\npasting a spoken sentence onto a card; a headline is a *rewrite* (same meaning,\n\u2153 the words, point surfaced). Gate every card: (1) **one intent, one sentence**\n\u2014 can't \u2192 split; (2) **headline \u2260 quote** \u2014 ~14-char title, demote the\nexplanation to a small detail line; (3) **no two cards make the same point** \u2014\nmerge/reframe overlaps; (4) **shape follows content** \u2014 comparison\u2192two-column,\nnumber\u2192big figure+label, list\u2192stacked rows, quote\u2192large centered. Reject &\nrewrite if: `title` > ~14 \u4e2d\u6587\u5b57, `detail` is a verbatim clause, or the card is\n\"the next sentence\" not \"the next idea\".\n\n**Final card \u2014 append a customizable brand outro (`card-cta`).** After all\ncontent cards, append one `fullscreen` outro card (`contentHints`: `recap` +\n`purpose`) and extend `composition.durationSeconds` by ~3.5s to match its\n`endSec`. Lead with a **recap / payoff line rewritten from what the video said**\n(the earned content beat, not a logo flash) + a one-line **purpose / \u5ef6\u4f38** under\nthe wordmark. **Re-theme it to the composition's style** (reuse `--bg`/`--ink`/\n`--accent-0`, swap mark/wordmark/tagline; keep the entrance choreography) \u2014 a\nclashing fixed outro is a defect. Ships the Interflow club sign-off (`Interflow`\n+ `Interflow AI \u51fa\u54c1`); for an outside creator swap/drop the brand, no hard-sell\nCTA, **strip AI-jargon** (\u8d4b\u80fd/\u95ed\u73af/leverage\u2026). Full template + JSON + entrance\nchoreography: `references/card-contract.md`.\n\n### 7. Resolve Render Strategy (from the Step 3.5 answers \u2014 do NOT ask again)\n\nThe visual system \u2014 ratio / layout / style / \u8fd0\u955c / density \u2014 was **already chosen\nby the user in Step 3.5**. This step is pure **resolution**: turn those stored\nanswers into concrete canvas size, frame, theme palette, and per-card bounds. No\nquestions here (front-load contract).\n\nWhat this step does with the stored answers:\n- **Resolve canvas** from `ratio` (16:9\u21921920\u00d71080 `landscape` \u00b7 9:16\u21921080\u00d71920\n  `portrait` \u00b7 4:5\u21921080\u00d71350 `portrait`).\n- **Map `style` \u2192 a specific style key** and **auto-pick the frame** from the\n  layout \u00d7 style matrix; **resolve `rhythm`** (fixed vs dynamic videoBounds).\n- **Refine `cardCount`**: in 3.5 you used assumed-medium density for the \"\u7ea6 N\"\n  label; now the transcript exists, so apply the real density multiplier (Step 6)\n  and let the actual intents set the final count.\n- **Conditional follow-up already handled in 3.5:** if `style` \u2208 {glass /\n  nebula-glass / spatial / geom}, the curve-foreground (5b) and dark-background\n  (5c) micro-questions fire as part of the upfront gate (the user is still there\n  right after picking style) \u2014 not here. By Step 7 they're already answered.\n\n**\u2192 The full resolution detail \u2014 the canvas / frame / bounds tables, theme\npalettes, day/night style map, \u7559\u767d, camera rhythm, the storyboard render\ncontract, AND (for reference) the original question call + plain-text fallback \u2014\nis in [`references/render-strategy.md`](references/render-strategy.md).** Read\nonly the slice for your resolved ratio/style. (Its \"ask\" machinery is what Step\n3.5 invokes; here you read the **resolution tables**.)\n\nState back what's locked in one sentence (ratio + canvas size, layout, primary\nstyle + any sibling accent styles, frame, final cardCount, rhythm), then proceed.\n\n### 8. Write Each Card's HTML\n\n**Clone-first (the default).** For each card:\n\n1. `cp \"$SKILL_DIR/references/styles/<styleKey>.html\" \"$WORK_DIR/public/cards/<card-id>.html\"` \u2014 `<styleKey>` is the card's `styleKey` if set, else the film's **primary** style (see the style-family note in Step 7: most cards use the primary; accent cards may pull a tonally-compatible sibling).\n2. Rename the fragment's `data-card-id=\"ref-<key>\"` to this card's `<card-id>` (update the scoped `<style>` selectors + element ids).\n3. Swap the placeholder copy for this card's real `contentHints`, set the accent to the card's `accentIndex`.\n4. **Compose, don't just fill \u2014 but hold the style's DNA.** The floor is the style's design tokens (fonts, theme palette / `var(--accent-N)`, ornament, spacing scale) + the overflow guards \u2014 keep those fixed. Within that envelope you're free to **recompose the fragment to serve this card's point**: promote/demote emphasis, switch stacked \u2194 two-column, move the panel (bottom / centered / side), drop an unused slot, let shape follow content. Two adjacent cards should NOT be structurally identical when their content differs. Off-limits: re-picking fonts, off-theme color, foreign ornament, breaking overflow safety. Over a talking head, keep the speaker's face clear (a deliberate full-dim statement beat is the rare exception). Full guidance in `references/card-contract.md`.\n\nAuthoring a fragment from a blank file is the **exception**. Animations are\n**declared, not coded** \u2014 use `data-anim-*` attributes only; never write\n`<script>` in a card. The composition `index.html` is the only place a\n`<script>` (the GSAP block) lives.\n\n**Give each graphic card ONE crafted motion moment (transitions.dev kit \u2014 the\ndefault, not optional).** A card that's just static text on video is the failure\nthis is here to fix. As you fill each card, reach for the **content-matched**\ncomponent effect: a number \u2192 `digit-flip`, a list \u2192 `lines-reveal`, an emphasis\nword \u2192 `blur-swap`/`shimmer`, a chip \u2192 `badge-pop`, a \u2713 \u2192 `check-draw`, a\nthis\u2192that swap \u2192 `icon-swap`; topic shifts between cards \u2192 `page`/`reveal`\nhandoffs. Add the right `<span class=\"digit\">` / `.line` / `.icon-from` hooks the\neffect needs (see the kit). **One** effect per card + its beat \u2014 never stack\nthree (\u6070\u5230\u597d\u5904). Talking-head/face-is-the-point cards may stay calm; the kit\nserves the *graphic* cards. Full default-by-content table + required HTML/CSS per\nkind + the curve map: [`references/transitions-dev-motion.md`](references/transitions-dev-motion.md).\n\n**\u7ed3\u6784\u5316\u5185\u5bb9 \u2192 \u62ac\u4e00\u4e2a\u89c6\u89c9\u7ec4\u4ef6 (clean \u5bb6\u65cf).** When a card's content hits a\nstructured shape \u2014 a trend, a ratio breakdown, a single hero number, an analogy\n(X\u2248Y), a black-box, an A+B=C equation, a spectrum, an iceberg, a two-way\ncomparison, or a terminal/chat/code mock \u2014 don't free-design it: pick the\ncomponent via the content\u2192\u7ec4\u4ef6 table in\n[`references/components/components.md`](references/components/components.md), copy\nits `<!-- COMP:<key> -->` block from `components-gallery.html`, fill real content,\nand scope its `guizang-clean.css` classes into the card (same as cloning a clean\nfragment). These are \u5f52\u85cf-family members \u2014 they already encode the \u5b57\u53f7\u5b57\u91cd +\n\u95f4\u8ddd discipline, so **don't hand-tweak their font/spacing values**. clean \u5bb6\u65cf only.\n\n**\u7b80\u6d01\u6392\u7248\u7c7b\u00b7\u6b78\u85cf\u5bb6\u65cf cards** (swiss / minimal / terminal / editorial-print /\npastel-aura): before composing, read\n[`references/styles/guizang-dna.md`](references/styles/guizang-dna.md) \u2014 these\nshare one DNA (\u5b57\u53f7\u5b57\u91cd\u8026\u5408 + \u9884\u8bbe\u8c03\u8272\u677f + \u7ec4\u4ef6\u5e93 `guizang-clean.css`)\u3002\u914d\u8272\u53ea\u80fd\u53d6\n\u9884\u8bbe\u8868\uff08\u7981\u81ea\u5b9a\u4e49 hex\uff0caccent \u7ecf `--accent`\uff09\uff0c\u7ec4\u4ef6\u7528 `.stat-card`/`.callout`/\n`.pipeline`/`.timeline-v`/`.bar-chart`/`.kicker`/`.meta`/`.mark`\uff0c\u4e00\u7247\u4e00\u652f\u67f1\u6c38\u4e0d\u6df7\u3002\n\u5199\u5b8c\u6bcf\u5f20 clean \u5361\u8dd1\u4e00\u904d\u6821\u9a8c\uff1a\n\n```bash\nnode \"$SKILL_DIR/scripts/validate-clean-card.mjs\" \"$WORK_DIR/public/cards/<card-id>.html\"\n```\n\n\u5e94 PASS\uff08\u65e0 hard fail\uff09\uff1b\u4ea4\u4ed8\u524d\u5bf9\u7167 [`guizang-checklist.md`](references/styles/guizang-checklist.md) \u8fc7 P0\u3002\n\n**\u2192 The complete Step 8 \u2014 the card HTML contract + hard rules (lint), the\ncanvas-atmosphere exception, NON-NEGOTIABLE overflow safety, portrait\nmobile-first sizing, the silky motion philosophy, the full `data-anim` kinds\ntable, and the `card-cta` brand-outro template \u2014 is in\n[`references/card-contract.md`](references/card-contract.md). Read it **once\nbefore your first card** \u2014 the **overflow safety + contract hard-rules are\nmandatory**; the `data-anim` table and the `card-cta` template are lookups, jump\nto them only when you actually need them (don't re-read the whole file per\ncard).**\n\n### 9. Assemble the Composition HTML\n\nStage the assets and write `$WORK_DIR/public/index.html`:\n\n```bash\n# SKILL_DIR is injected by the host (\"Base directory for this skill: \u2026\")\nSKILL_DIR=\"<SKILL_DIR>\"\n\nmkdir -p \"$WORK_DIR/public/fonts\" \"$WORK_DIR/public/vendor\" \"$WORK_DIR/public/cards\"\ncp -n \"$SKILL_DIR/assets/fonts/\"*            \"$WORK_DIR/public/fonts/\"\ncp -n \"$SKILL_DIR/assets/vendor/gsap.min.js\" \"$WORK_DIR/public/vendor/\"\n# if storyboard.composition.background is set, stage the background-layer libs\n# (build-timeline.py injects the <canvas> + draw(t) hook automatically):\ncp -n \"$SKILL_DIR/references/backgrounds/backgrounds.js\"        \"$WORK_DIR/public/vendor/\"\ncp -n \"$SKILL_DIR/references/curve-motion/curve-atmosphere.js\"  \"$WORK_DIR/public/vendor/\"\n# copy the STATIC composition shell \u2014 do NOT retype it\ncp \"$SKILL_DIR/references/composition-shell.html\" \"$WORK_DIR/public/index.html\"\n# stage the input video so the composition can reference it by relative path\nln -f \"$VIDEO_PATH\" \"$WORK_DIR/public/input-video.mp4\" 2>/dev/null \\\n  || cp \"$VIDEO_PATH\" \"$WORK_DIR/public/input-video.mp4\"\n```\n\n**Then fill the shell \u2014 do not regenerate it.** `index.html` is the copied\n`composition-shell.html` (already has `#stage` / `#video-wrap` / card-host\nstructure + `@font-face` + GSAP runtime). Edit only these slots:\n\n1. **The 6 `{{...}}` tokens** at the top: `{{BG}}` `{{TEXT}}` `{{ACCENT_0..4}}`\n   (from the chosen `themeId` palette), `{{DURATION}}` (= `composition.durationSeconds`),\n   `{{FPS}}`, `{{WIDTH}}`, `{{HEIGHT}}`. The tokens appear in a few places each \u2014\n   a `sed` pass replaces all at once, e.g.\n   `sed -i '' -e 's/{{DURATION}}/121.2/g' -e 's/{{FPS}}/30/g' \u2026 \"$WORK_DIR/public/index.html\"`.\n   (`sed -i ''` is macOS/BSD; on Linux use `sed -i` with no `''`.)\n2. **`.video-wrapper` initial `left/top/width/height`** \u2014 set to card-01's layout bounds.\n3. **The two `INJECT-*` markers** \u2014 **do NOT hand-author these.** Run the\n   generator; it reads `storyboard.json` + `public/cards/*.html` and fills both\n   the card-host divs and the full GSAP timeline (enter / drift / exit, with\n   `data-anim` attributes compiled via the cheat sheet, times quantized,\n   `data-track-index` increasing, drift repeats finite):\n\n   ```bash\n   python3 \"$SKILL_DIR/scripts/build-timeline.py\" --work \"$WORK_DIR\"   # add --slip 0.55 to tune\n   ```\n\n   **Idempotent** \u2014 re-run after editing any card / the storyboard; it re-injects\n   between its `BEGIN/END` sentinels. Run it AFTER Step 8 (cards exist) and AFTER\n   the `sed` fill; read its stderr timing warnings. What it leaves to you:\n   **`#video-wrap` reframes** for dynamic (\u8d77\u4f0f\u8fd0\u955c) rhythm \u2014 add\n   `\"videoBounds\": {left,top,width,height}` (+ optional `\"videoClass\": \"video-wrapper pip\"`)\n   to a card in `storyboard.json` and it emits the reframe tween at that card's\n   slip; cards without `videoBounds` keep the video put (calm default).\n\n> **Hand-authoring the timeline is the exception** \u2014 only for a one-off motion the\n> cheat sheet can't express (then stop re-running the script, it overwrites). Else\n> declare motion as `data-anim-*` (Step 8) and let the generator compile it.\n\n**\u2192 The Step 9 reference detail \u2014 the GSAP statement cheat sheet, card-timing\nvalidation (overlap is intentional), the video framing reference per layout, the\nHyperFrames layout/animation QA rules, the hard-won gotchas (read before\nassembling), and the fixed card-cta GSAP block \u2014 is in\n[`references/composition-assembly.md`](references/composition-assembly.md).**\n\n### 10. QA \u2014 autonomous-default: snapshot self-QA \u2192 render \u2192 deliver\n\n**Default (autonomous path): do NOT open the interactive preview or wait for\napproval.** The user front-loaded their choices in Step 3.5 and walked away to\nget a finished film. So self-QA with **single-frame snapshots** (cheap \u2014 one per\ncard moment), fix any overflow/placement issues you see, then go straight to\nStep 11 (render) and deliver the MP4. The user reviews the **finished work** and\nasks for revisions after \u2014 that's when you iterate.\n\n```bash\ncd \"$WORK_DIR\"\n# self-QA: one snapshot per card beat (cheap; NOT a render)\nnpx hyperframes snapshot public --at 5 --describe false   # writes public/snapshots/frame-\u2026png\n```\n\n**Interactive path (only if the user explicitly asked to watch/iterate live):**\nstart the live studio and share the URL \u2014 it opens instantly, plays/scrubs in\nreal time, and **hot-reloads on every edit**.\n\n```bash\ncd \"$WORK_DIR\"\nnpx hyperframes preview public --no-open\n# prints e.g. \"Studio  http://localhost:3002\" (auto-picks the next free\n# port if taken). Share that URL with the user.\n```\n\nInteractive loop (only when the user opted to watch live):\n\n1. Assemble / edit the composition (Step 9).\n2. Run `hyperframes preview` (once \u2014 it stays up and hot-reloads).\n   Give the user the `localhost` URL.\n3. User reviews in the browser \u2192 requests changes \u2192 you edit the HTML \u2192\n   user just refreshes / re-scrubs. No render in this loop.\n4. **Only when the user explicitly approves** do you move to Step 11\n   (render). Do not render proactively just to \"check\" \u2014 snapshots\n   (`hyperframes snapshot`) cover your own static QA without a full render.\n\n> **Autonomous default does the opposite:** no preview server, no waiting \u2014\n> snapshot-QA then render directly (the user is away). Use the interactive loop\n> ONLY when they said they want to iterate live.\n\nFor YOUR OWN spot-checks during building, use single-frame snapshots\n(cheap), not renders:\n\n```bash\nnpx hyperframes snapshot public --at 5 --describe false   # writes public/snapshots/frame-\u2026png\n```\n\n> Pass `--describe false` to silence the built-in Gemini QA (prints\n> `GEMINI_API_KEY not set, skipping` otherwise). Frames write to the **real**\n> path `public/snapshots/frame-*.png` (not `snap-*.png`). Under zsh an unmatched\n> glob hard-errors (`nomatch` \u2192 exit 1) \u2014 guard loops with `setopt +o nomatch`.\n\nManage preview servers: `hyperframes preview --list` /\n`hyperframes preview --kill-all`.\n\n> Headless / cron runs (no desktop): skip the interactive preview and go\n> straight to Step 11, using snapshots for QA.\n\n### 11. Render to MP4 (autonomous default \u2014 render once snapshots pass; or after live approval)\n\n```bash\ncd \"$WORK_DIR\"\nPRODUCER_BROWSER_GPU_MODE=hardware npx hyperframes render public \\\n  -o output.mp4 \\\n  --fps 60   # 60 for spring/motion-heavy comps \u2014 matches the live preview's fluidity\n```\n\n> **Render at `--fps 60`, not 30.** The live `preview` plays via the browser's\n> rAF (~60fps) so spring/`back.*` overshoot looks buttery; a 30fps render samples\n> the same motion at half the temporal resolution and the springs read as\n> slightly stepped \u2014 the #1 reason \"the MP4 feels stiffer than the preview\". The\n> easing is identical; only the sampling differs. Use 30 only for static/calm\n> talking-head cuts where file size matters.\n\n`hyperframes render <dir>` reads `<dir>/index.html` and produces the MP4.\nThe flag `PRODUCER_BROWSER_GPU_MODE=hardware` (or `--browser-gpu`) is\nstrongly recommended on macOS \u2014 software-only Chrome rendering times out\non most laptops.\n\nFor a sanity check before the full render, capture a single frame at a\nspecific timestamp:\n\n```bash\nnpx hyperframes snapshot public --at 5 --out snapshot-5s.png --describe false\n```\n\n### 12. Report Results\n\nTell the user: work dir path \u00b7 key artifacts (`storyboard.json`,\n`public/cards/*.html`, `public/index.html`, `output.mp4`) \u00b7 ASR provider \u00b7 card\ncount + how you chose them (1 sentence) \u00b7 any missing keys / quality caveats.\nDon't delete the work directory unless asked.\n","usage":"\u8bfb\u53d6 SKILL.md\uff0c\u5e76\u6309\u9700\u8bfb\u53d6\u914d\u5957\u6587\u4ef6\uff1b\u4e0b\u8f7d ZIP \u83b7\u53d6\u5b8c\u6574\u5305\u3002\u6280\u80fd\u662f\u4efb\u52a1\u65b9\u6cd5\uff0c\u4e0d\u6388\u4e88\u65b0\u589e\u8d26\u6237\u3001\u4ed8\u8d39\u6216\u7cfb\u7edf\u6743\u9650\u3002"}
