Turn a math proof document (markdown) into a Remotion video with a dark background and precise geometric style. All geometry is drawn in code (SVG + stroke-dash outlining), formulas are revealed line by line, and subtitles drive the timeline.
Reference Template:<VIDEO_WORKSPACE>/pythagorean-garfield-proof/ is the completed project for the first episode. When you run into layout/pacing/coordinate issues you are unsure about, look at its src/GarfieldProof.tsxfirst, and don't improvise out of thin air.
Workflow for a New Episode
- Read the source document. Break the proof into 6~10 sections, each with one visual idea:
- Hook: throw out the proposition to be proved, large formula + suspenseful subtitle
- Setup: introduce the construction (triangle/line segment/polygon), introduce variables a/b/c...
- Derivation 1~N: each section proves only one thing (local area, total area, some algebraic simplification...)
- Cancellation/combination: assemble the local results into the final equation
- Ending: boxed conclusion + history/figures/extension credits
-
List the proof checklist. First list the key steps in the source document as a beat checklist:
- Each variable definition (what a is, what b is)
- Each geometric construction (which points form which triangle)
- Each area/angle calculation
- Key algebraic steps (expansion, cancellation, squaring)
- Final conclusion + historical attribution When writing LINES later, use this table to prevent compressing the proof into "three sentences of narration and done".
-
Write LINES, run TTS. Open
scripts/generate_tts.py, replace LINES with the section dialogue for this proof. Each line{"id", "chapter", "text"}. Run:python scripts/generate_tts.pyProduces
public/assets/audio/voice.mp3、work/captions/captions_aligned.json、work/captions/captions.srt。 -
Write back the F timeline. From
captions_aligned.json'slines, take the last frame of each section and write it tosrc/geometry.tsx'sFobject. At the same time, changeRoot.tsx'sdurationInFramestototal_frames。Do not stop at the no-voiceover estimated-timing version。 -
Scaffold:
mkdir "<VIDEO_WORKSPACE>/<new-proof>" cp -R "./.claude/skills/geometry-math-proof-remotion/templates/remotion-project/" \ "<VIDEO_WORKSPACE>/<new-proof>/" cd "<VIDEO_WORKSPACE>/<new-proof>" && npm install⚠️ Use native
npm install, notrtk npm install(rtk will translate it intonpm run installand report an error). -
Edit Proof.tsx:
- Geometric coordinates: define the key points according to this proof's figure
const A = pt(0,0), B = pt(3,0)… - CAPTIONS: from each line of captions_aligned.json
text, extract keywords (marktone: 'accent'), and treat the rest as normal text - STEPS: FormulaStep list,
fromframes aligned to the middle of the corresponding section - Use large formulas for the title/result of HookOverlay / EndingOverlay, and write history/figures in attribution
Do not modify
geometry.tsx/formula-panel.tsx/caption-strip.tsx/hooks-overlay.tsx(the style lock file). If you need new components, add them in new files; do not modify the shared files.
- Geometric coordinates: define the key points according to this proof's figure
-
Verification loop(mandatory):
npx tsc --noEmit- Render still frames near the end of each section and check them one by one:
Check the images: text overflowing the SVG box, geometric elements overlapping and occluding each other, subtitles covering key labels, formula rows/columns misalignednpx remotion still src/index.ts Proof --frame=<章末帧-30> out/check-N.png - Keyword sync spot check: for each LINES keyword (the accent part), render two frames, "0.5s before appearance" and "0.5s after appearance"; the former frame must not reveal it, and the latter frame may only reveal words already spoken
npm run render:previewoutrenders/preview-low.mp4(scale=0.5), and after user confirmation thennpm run renderoutrenders/final-1080p.mp4
Prove fidelity
- The source document is the proof, not an outline. Converting to video may merge similar sentences, but must not skip steps in a way that breaks the chain of derivation.
- Keep the "connecting steps." For example: you cannot directly throw out "the area is c²/2"; there must first be "both legs are c" as the connection.
- The narration may be streamlined, but the causal progression of the derivation must be preserved: construction → local → whole → cancellation → conclusion.
- If cuts are unavoidable, first list the beats to be removed and confirm that they are not logical bridges needed by later text.
- Before TTS, check item by item against the beat checklist to confirm no key definition/construction/cancellation step is missing.
Style DNA (immutable)
| Item | Value |
|---|---|
| Canvas | 1920×1080 @ 30fps, dark background #0d0d12 |
| Colors | Red #e74c3c, Blue #3498db, Green #2ecc71, Yellow #f1c40f(yellow = final conclusion/hook) |
| Fonts | Mathematical serif Cambria Math/STIX Two Math, Chinese PingFang SC/Microsoft YaHei |
| Geometry | SVG viewBox 0 0 1100 860, coordinate transform pt(gx,gy), unit SCALE=130px/unit |
| Stroke | All wireframes use strokeDasharray+strokeDashoffset for the "being drawn" animation |
| Animation | fadeIn(fade in),drawIn(progressive stroke),fadeOut(fade out), easing uniformly bezier(0.4,0,0.2,1);Nobounce/rotation/slide-in |
| Subtitles | Bottom 110px subtitle bar, keywords tone:'accent' highlighted in yellow bold |
| Formulas | Right side 700×820 panel, revealed step by step; final conclusion in yellow-framed large text (tone:'result') |
| Assets | All drawn by code, no bitmaps/icon libraries/emoji at all |
| Voiceover | MiniMax speech-2.8-hd,voice_id moss_audio_2ecaeaac-5e5a-11f1-99fb-96e792fde6a1, 1.2x speech rate |
Chapter layout conventions
- Hook (H): Full-screen mask, large yellow formula text (140px) + Chinese suspense subtitle + gray English attribution (era/author).
HookOverlaycomponent, fades out 18 frames before the second chapter begins. - Preparation (P): TopBar shows the chapter name, the SVG canvas begins drawing basic geometric elements (triangle/line segments), and variable labels a/b/c fade in 30 frames after the element stroke is completed.
- Derivation chapters (one idea per chapter): Each chapter focuses on only one geometric element or one set of algebraic transformations; other elements are dimmed with opacity 0.45; new element stroke → fill → label → formula appears in sync.
- Cancellation/Composition (E): The right-side formula panel continuously derives for 35 steps; each step interval 3050 frames; final conclusion uses
tone:'result'yellow-framed large text. - Ending (F):
EndingOverlayFull-screen mask, Q.E.D. text + yellow-framed formula + historical/personal attribution (era, author, source).
Keyframe rhythm
- One element appearing = stroke 36 frames + fill fade-in 30 frames + label fade-in 24 frames
- One formula step fades in over 24 frames
- Subtitle bar 6-frame fade in/out
- HookOverlay/EndingOverlay 30-frame fade in/out
- Do not add new elements in the last 30 frames of a chapter
Multi-voice extension
Default is single narration. If multiple voices are needed (dialogue-style proof), refer to sketch-story-remotion 's multi-voice workflow, but retain this skill's visual DNA. For voice_id mapping, see sketch-story.
Common pitfalls
- In JSX,
²₁₂₃triggers TS1351. Unicode No-category characters are parsed by TS as a numeric literal followed by an identifier, and error at JSX text positions.Always wrap all mathematical text in string expressions:<span>{'a² + b²'}</span>, do not write bare text<span>a² + b²</span>. Seereferences/jsx-unicode-pitfalls.md。 - Edit tool cannot find strings containing
²,. The Edit tool matches Unicode No characters unstably. Switch to doing it all at once with Pythonstr.replaceor rewrite the entire file. - Remotion gets stuck on storage.googleapis.com in China。
remotion.config.tsmust be set toConfig.setBrowserExecutable(系统 Chrome). Edge will not work (the old headless flag has been removed). - Subtitles drive frames. Run TTS first to get the real duration, then write back F; do not guess the frame count from the spoken length.
- preview-low → final-1080p two-stage approach. First give the user scale=0.5 for confirmation, then output the final film at scale=1, to prevent rework.
rtk npm installfailed. Use nativenpm install。- Image MCP may refuse during still-frame analysis. Check with your naked eye or a local image viewer; do not rely on analyze_image.
Reference documentation
references/composition-patterns.md— SVG strokes, coordinate transforms, FormulaPanel step-by-step reveal, CAPTIONS accent word-splitting detailed patternsreferences/jsx-unicode-pitfalls.md—²/subscript TS1351 pitfall, Edit tool failure, full explanation of the Python alternative- Specification boilerplate
<VIDEO_WORKSPACE>/pythagorean-garfield-proof/src/GarfieldProof.tsx— a complete 631-line real-world example