TellMotion — idea → theme → animation
One repeatable flow, cheap in tokens. Works for any topic that fits 2D: diagrams, processes, architectures, algorithms, timelines, concepts. (Not for 3D or live-action video.)
Layout of this skill: themes/ (theme.json catalog) · tools/ (Node, zero deps) · assets/base (Motion Canvas template, with scene recipes) · assets/packs/ (optional component packs) · scripts/new-project.sh · references/.
1. Brief (one round, ask only what is missing)
If the user already gave content/structure, do not ask again. Use AskUserQuestion (max 4 questions) for what is missing:
- Topic and content (if absent: propose an invented one and say so).
- Length / pace (default: calm pace, scenes of 20-60 s) and fps (default 30 preview / 60 render).
- Design — always offer these three options:
- Template: use a theme from the catalog. Run
node tools/list-themes.mjs(compact list) and ask for the id; to browse visually runnode tools/build-catalog.mjs <tmpdir>and opengallery.html(serve withnode tools/serve.mjs <tmpdir>). - Custom design: write 3 contrasting
theme.jsonproposals (seereferences/theme-format.md), render previews and let the user choose (step 2). - Bring your own: user supplies brand colors/fonts or a Figma file → derive a
theme.jsonfrom it.
- Template: use a theme from the catalog. Run
- Packs: infer from the topic, do not ask unless unclear, and add only what the custom scenes will use:
cloud(architectures),algorithms(sorting, trees),charts(data),flowchart(processes),timeline(history/roadmaps),code(programming, CLI),typography(intros, quotes, A vs B),science(cycles, layers, waves),math(equations, functions),ui(product demos, user flows),maps(places, journeys). Combine freely;references/packs.mdlists every component.
2. Custom design (skip when a template was chosen)
- Write 3 proposals as
theme.jsonfiles in a temp folder (copy the closest catalog theme and change tokens; different families, e.g. technical / playful / editorial). node tools/validate.mjs <file>for each, thennode tools/build-catalog.mjs <out> --themes <folder>.- Show previews: open
<out>/gallery.htmlin the browser pane (serve.mjs) or send the SVGs. Wait for the user's choice. - Optional high-fidelity route with Figma (only if the user wants it and the Figma connector exists):
references/figma.md. - Save the chosen theme as
<project>/theme.custom.json(and offer to contribute it to the catalog).
3. Storyboard (the user approves it before anything is animated)
Rewriting an animation is expensive; rewriting a list of scenes is not. Skip this step only for a single scene or if the user asks to.
- Read
references/storyboard.mdandreferences/recipes.md, then writestoryboard.json: one entry per scene, with its recipe (orcustom), what it shows, its seconds and its real text. node tools/storyboard.mjs validate <file>, thennode tools/storyboard.mjs preview <file> --theme <id|file> --out <tmpdir>. Show the page with the browser pane (serve.mjs), and also list the scenes in chat.- Wait for the user's approval. Change the storyboard, not code, until they agree. Stop the preview server afterwards.
After the approval, work autonomously until delivery.
4. Project
bash <skill>/scripts/new-project.sh <name> --theme <id|path.json> [--pack a,b|all] [--demos]
(--demos copies each pack's demo scene: handy to learn an API, then delete the demos.)
Run it from the folder that should contain the project. One project per topic; add scenes to it for new videos. It copies the template, applies the theme (src/theme.ts, src/fonts.ts), installs dependencies and registers the project in .claude/launch.json. Change theme later: node <skill>/tools/apply-theme.mjs <theme> <project> then npm install.
5. Scenes
node tools/storyboard.mjs generate <file> <project> writes every scene and src/project.ts. Recipe scenes are finished. Each custom scene is a running placeholder with its title, captions and length: write its animation, keeping them. For those, read references/motion-guide.md (core API, layout recipe, pitfalls) and references/packs.md (pack components). Re-running generate keeps scenes you edited. Fixed rules:
- One scene per block in
src/scenes/, registered insrc/project.ts(+ a.metafile per scene). - Use
prepareScene(view, title); callenter()first andleave()last; captions viasub.say(text). - Text ≥ 28 px at 1920x1080; captions ≤ 85 characters; one category color per element type + legend in
src/config.ts(LEGEND). - Show only what is needed per scene;
glow()the active element anddim()the rest. - Editable text, timings and colors as constants at the top of each scene (
EDITABLE TEXTcomment); global speed inPACE. - Join pieces with
connect(root, a, b). Requests and events travel withsend(root, arrow.points, {shape: 'dot' | 'diamond', to: piece}), so the shape tells them apart and the piece reacts on arrival. - Never hard-code colors or fonts in scenes: use
C,S,FONT,fs()fromconfig.tsso themes stay swappable.
6. Verify (cheap)
npm run typecheckin the project, thennode tools/storyboard.mjs duration <project>: if a scene is far from the approved plan, fix it or tell the user.preview_start(project name from.claude/launch.json),resize_window1700x950, then click the timeline andzoomon[215,0,800,330]; batch several clicks+zooms in onebrowser_batch.scroll righton the timeline to reach later scenes.- When done:
resize_windowpresetdesktop,preview_stop. Do not render mp4 unless asked.
7. Render (when asked)
npm run render in the project writes output/<name>/<name>.mp4 and render.json (duration per scene, file sizes), without opening the editor. Options (after npm run render --):
--format mp4,webm,gif·--thumbor--thumb-at <seconds>·--fps <n>·--scale <n>. WebM encoding is slow (minutes): request it only when needed.--aspect 9:16,1:1: fits the video inside with bars in the theme background (--pad-coloroverrides); it does not re-lay out the scene, so text shrinks to about 56%. Say so to the user.--draft: 30 fps at half size, inoutput/<name>-draft/. Use it to review.--info: duration of each scene, nothing rendered. Cheap: prefer it over rendering to check pacing.--dry-run: size range per file from rendered samples, nothing saved. Use it before a large render or when the user worries about size.
Needs Chrome, Edge or Chromium (CHROME overrides the path). Projects created before this script existed: node <skill>/tools/render.mjs <project>. The source is tools/render.mjs.
8. Deliver
List scenes (name → what it shows), how to run (npm start), how to render (npm run render), how to change pace (PACE), texts (constants per scene), theme (apply-theme.mjs). State what was not verified. If the workspace has a CLAUDE.md, add the new project to it.
Token savings
- Do not re-read files you just wrote; use
Edit. - Use
list-themes.mjsinstead of reading theme JSON files; read a single theme only when customizing. - Batch screenshots/zooms; avoid full-page captures.
- Reuse
assets/instead of regenerating components.