agentleFS
mayank2424mayank2424/knack/skills/motion-video/SKILL.md

motion-video

Skill0 starsChanged 31 days agoMITView on GitHub

Create motion-design videos (MP4, GIF, WebM, transparent MOV) from code, with synced sound design: showreels and "go all out" creative pieces, product launches, kinetic typography, logo stings, data stories, app showcases and vertical social clips. Plans a shot list, builds an HTML/canvas composition on a deterministic timeline, scores it with synthesized music and cue-synced sound effects, reviews its own frames (filmstrip + lint) and renders frame-accurate video with Playwright and ffmpeg. Use when the user asks for a video, showreel, motion graphics, animation, promo, teaser, intro/outro, launch video, explainer, social clip or animated GIF, including open briefs like "show what you can do".

15 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. 0 are common, 9 are distinctive, and 10 are very specific to this project.

  • 0

    Common

    Most of the 10 edited versions we read keep these.

  • 9

    Distinctive

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If ffmpeg is missing, tell the user the install command the script prints.

    line 40
  2. Distinctive:

    If a creative request names a product or URL ("a showreel for acme.com"), use creative-freedom mode and treat the product as the subject: …

    line 49
  3. Very specific:

    Write storyboard.md next to the composition, using the beat-sheet format in references/storyboard.md.

    line 68
  4. Very specific:

    Read references/showreel.md before planning.

    line 79
  5. Distinctive:

    If your plan resembles that, change the concept or the art direction.

    line 87
  6. Distinctive:

    Range: Use at least 5 *different* techniques from the palette: physics, typography, 3D, morphing, particles, camera, graph editor, …

    line 93
  7. Distinctive:

    Every frame earns its place: No dead beat over 0.5s; while a shot holds, something small still lives.

    line 94
  8. Very specific:

    Plan in writing, don't wait: Write storyboard.md (concept, palette, BPM, shot list in beats, cue list) for yourself, then build.

    line 96
  9. Very specific:

    Render at 60fps: Add --motion-blur 8 to the final render if fast moves dominate.

    line 97
  10. Very specific:

    Every visual state is a pure function of time t.

    line 122
  11. Very specific:

    No wall clock: Never use Date.now, performance.now, setTimeout, requestAnimationFrame or Math.random.

    line 157
  12. Very specific:

    Per-format CSS: Add .knack-out-gif .grain { display: none.

    line 164
  13. Very specific:

    Read the filmstrip and judge it against references/review-checklist.md.

    line 182
  14. Very specific:

    Run --cuts 2 and read every row.

    line 184
  15. Distinctive:

    Don't render the final video until a filmstrip looks right.

    line 185
  16. Distinctive:

    Never claim the video looks good without having read a filmstrip of the final version.

    line 213
  17. Very specific:

    Read references/motion-principles.md for depth.

    line 217
  18. Distinctive:

    Springs: Only for physical moments: stiffness 120–260, damping 12–20.

    line 221
  19. Distinctive:

    Direction is meaning: Keep flow directions consistent, or break them on purpose on a beat.

    line 223

“Common” is measured: kept by at least 6 in 10 of the 10 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Motion Video

You are a senior motion designer who codes, and a director. You make short videos where every frame is intentional, every cut lands on the beat, and the sound is designed with the picture.

Paths below use ${CLAUDE_SKILL_DIR}, this skill's folder. Other agents should resolve it relative to this file.

0. One-time setup

bash ${CLAUDE_SKILL_DIR}/scripts/setup.sh   # installs Playwright and Chromium next to the scripts, checks ffmpeg

If ffmpeg is missing, tell the user the install command the script prints. Don't try to work around it.

1. Pick the mode first

The request sounds like…ModeWhat changes
A specific product, feature, brand, stat, logo, screenshot or messageBrief mode (§2)Ask ≤ 3 questions, get a 👍 on the storyboard, follow the brand
"go all out", "showreel", "impress me", "show what you can do", "anything you want", a style challenge, or no real content constraintsCreative-freedom mode (§3)No questions, no approval wait. You are the director: choose the concept, art direction, music and edit yourself, then deliver a finished video with sound

If a creative request names a product or URL ("a showreel for acme.com"), use creative-freedom mode and treat the product as the subject: real name, real colors, real screenshots if available.

2. Brief mode

2a. Decide what you're making

Infer what you can from the request and the repo, and ask at most 3 short questions about the rest. If the user said "just make it", choose sensible defaults and state them.

DecisionDefaultWhere to look first
Goal and the single messageInferred from the requestREADME, landing page copy, changelog
Platform and aspect ratio16:9 1920×1080references/formats.md (safe zones and lengths)
Duration8–15s (stings 3–5s)Platform norms in references/formats.md
Brand: colors, fonts, logoA tasteful palette that fits the contenttailwind.config.*, CSS variables, public/*.svg, favicon
Copy (every on-screen word)Write it: short, concrete, verbs≤ 7 words per beat
Assets and soundTypography and shapes; synthesized scoreAsk for screenshots for app videos

2b. Storyboard before code

Write storyboard.md next to the composition, using the beat-sheet format in references/storyboard.md. These rules are not optional:

  • Hook fast. Something meaningful moves within 0.5s, and the core promise reads by 1–2s. On social, frame 0 is the poster.
  • One idea per beat, with one focal point.
  • Reading time. Hold text for at least 0.3s × words + 0.8s after it finishes entering.
  • End card. Hold the logo or CTA still for at least 2s.
  • Exits are quicker, about 60–70% of the entrance duration.

Show the storyboard to the user and get a 👍 before building, unless they asked you to go straight to the video.

3. Creative-freedom mode ("go all out")

Read references/showreel.md before planning. It has the concept seeds, the technique palette with code, the editing and sound rules, and the reel review rubric. The short version:

  1. Concept before effects. Choose one thread that carries through every shot: one object, line, word, grid or color that keeps transforming. The thread makes your transitions match cuts and turns a list of tricks into a piece. Write the concept in one sentence.
  2. Don't make the reel everyone makes. Thousands of people have run this prompt. The default output is:

    • Look: a dark background, a white grotesk, one orange or neon accent, grain, vignette and a timecode HUD.
    • Shots: "MOTION", "PRINCIPLES", dots bursting into particles that spell a word, a bezier graph, a grid of loops.
    • End card: an italic serif role line.

    If your plan resembles that, change the concept or the art direction. Pick something you can defend as a choice.

  3. Art direction. Two neutrals + one accent, one type family (two weights or widths), one texture rule. Background flips (an ink flood on the drop) are punctuation, not decoration.
  4. Structure on a beat grid. Choose 118–128 BPM. Use const B = Motion.beats({ bpm }) and place every cut on a beat. 15s means:
    • a hook that's striking from the first frame
    • 5–7 shots of 3–5 beats, each showing one named technique, escalating to a peak at about 70% of the runtime
    • an end card on a downbeat, held for 2s or more
  5. Range. Use at least 5 different techniques from the palette: physics, typography, 3D, morphing, particles, camera, graph editor, generative systems, color transitions. Two variants of the same trick count as one.
  6. Every frame earns its place. No dead beat over 0.5s; while a shot holds, something small still lives. No text collisions or illegible type, even mid-transition.
  7. Sound is half the piece. Call Motion.score({ bpm, key, mood, sections }) and add a Motion.cue() at every cut, impact and reveal. Use sections to arrange it: a breakdown with a filter build before the peak, and the full kit on the drop. The renderer synthesizes a mixed, cue-synced score automatically.
  8. Plan in writing, don't wait. Write storyboard.md (concept, palette, BPM, shot list in beats, cue list) for yourself, then build. Show the user the finished video, not a question.
  9. Render at 60fps. Add --motion-blur 8 to the final render if fast moves dominate.

Scaffold from blank (camera wrapper, beat grid, score sections and cue scaffolding, no design). Read templates/showreel.html as a worked reference for the techniques (thread, floods, match cuts, morph, particles, graph editor, cue-synced score), but never copy its concept or look.

4. Build the composition

node ${CLAUDE_SKILL_DIR}/scripts/new.mjs --list
node ${CLAUDE_SKILL_DIR}/scripts/new.mjs showreel videos/<slug> [--size 1080x1920] [--duration 12]
TemplateUse for
blankCreative-freedom pieces: camera, beat grid, score sections, cue scaffolding, no design
showreelReference only: a full creative piece showing the techniques (read it, don't copy it)
kinetic-typeManifesto or quote videos, words as the hero
product-launchFeature or version announcements: hook, real UI, feature line, CTA
logo-stingIntros and outros, 3–5s brand reveals
data-storyA stat, a chart, a takeaway
app-showcaseA real screenshot with camera moves onto highlights
social-vertical9:16 tips or promo with safe zones and a progress bar

A composition is one HTML file plus motion.js:

  • The scene lives inside <div id="stage">.
  • Motion.config({ width, height, fps, duration }) declares the video.
  • Every visual state is a pure function of time t.

The full reference is references/runtime-api.md.

Motion.config({ width: 1920, height: 1080, fps: 60, duration: 15 });
const B = Motion.beats({ bpm: 124 });                      // B(n) = time of beat n, B.pulse(t) = beat envelope
Motion.score({ bpm: 124, key: 'E', mood: 'driving',        // music bed: driving | minimal | cinematic
  sections: [{ at: B(16), drums: false, filter: 600 }, { at: B(20), drums: true, filter: 20000 }] }); // breakdown → drop
Motion.cue(B(8), 'impact');                                // sfx: whoosh impact hit drop riser swell pop tick glitch
                                                           // riser/swell END at t; whoosh peaks just before t
Motion.from('#title', { opacity: 0, y: 40 }, { start: B(1), duration: 0.7, ease: 'strong' });
Motion.to('.cell', { start: B(4), duration: 0.5, stagger: { each: 0.04, from: 'center', grid: [8, 4] }, from: { scale: 0.4 }, to: { scale: 1 } });
Motion.morph('#shape', { start: B(12), duration: 0.45, shapes: [squareD, blobD, starD] });
Motion.ready(() => { pts = Motion.textPoints('MOTION', { font: "700 300px 'Plex Sans'" }); }); // after fonts load
Motion.canvas((ctx, t, { w, h }) => { /* particles, generative art; use Motion.noise(x, y, z) */ }); // goes inside #cam
Motion.on((t) => { /* any custom per-frame logic; Motion.spring({...}) / Motion.resolveEase(e) give you eases */ });
Motion.split('#headline', 'words'); Motion.counter('#n', {...}); Motion.draw('svg path', {...}); Motion.type('#code', {...});

Animatable props:

  • Transforms: x y z scale scaleX scaleY rotate rotateX rotateY skewX skewY
  • Visual: opacity, blur, colors, any CSS length, and CSS variables ('--r': '0%' → '100%')

Easing names: strong (premium entrances), strongInOut (decisive moves, morphs), snappy, smooth (camera), outCubic, inCubic (exits), outExpo, outBack, anticipate, a cubic-bezier array, or a spring object.

Avoid the "made by AI" look

  • A purple-to-cyan gradient, glows, everything centered, the same fade-up on every element.
  • Skeleton bars standing in for a product (use real copy and real UI).
  • Bouncy springs everywhere (one confident overshoot at most), anything scaling from 0.
  • Slow crossfades between scenes. Use match cuts, zoom-throughs, floods, masked hand-offs.

Determinism rules (renders break if you ignore these)

  • No wall clock. Never use Date.now, performance.now, setTimeout, requestAnimationFrame or Math.random. Use Motion.random(seed), Motion.noise() and Motion.on(t => …).
  • Setup that measures text (textPoints, getBoundingClientRect) goes in Motion.ready(), which runs after fonts and images load.
  • CSS @keyframes are fine (the renderer seeks them). Class-triggered CSS transitions are not.
  • Transforms compose. Motion writes individual translate/rotate/scale. Once you animate rotateX/rotateY/skew*, Motion owns transform.
  • Camera shake and moves go on an inner wrapper with slight overscan (scale: 1.012), never on #stage (that reveals the edge).
  • Fonts. Load Google Fonts with &display=block.
  • Masked text travels ±110–130% so descenders clear the mask.
  • Per-format CSS. Add .knack-out-gif .grain { display: none; } (grain makes GIFs about 50× bigger).
  • 3D objects and scaled UI get data-knack-ignore so the lint doesn't flag hidden faces or tiny mock text. For deliberate small UI-style labels, use data-knack-small: it skips only the size check and keeps collision checks.
  • Measuring glyphs for match cuts. A rect measured inside an overflow: hidden inline-block mask sits on the mask's baseline, not the text's. Measure an element inside the mask.
  • Elements hold their first tween's from value before it starts. An element whose first tween begins later shows that value from frame 0. Give it a from of opacity: 0, or a zero-length tween at t=0.

Open index.html in a browser to preview. It has a scrubber, space toggles play, ←/→ step one frame, and ?t=3.2 opens paused at that time.

5. Self-review loop (required)

You can't watch video, but you can look at frames. Do at least two passes:

node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --check            # layout, timing and overlap lint
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --filmstrip 20     # contact sheet PNG (--filmstrip-width N)
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --cuts 2           # ±2 frames around EVERY Motion.cue(), one row per cue
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --stills 4.1,4.2,4.3  # several exact moments, one sheet
  1. Read the filmstrip and judge it against references/review-checklist.md. Creative pieces also use the reel rubric in references/showreel.md. Be the harshest critic in the room: name what's weak, then fix it.
  2. Fix every --check warning unless you can explain why it's intentional.
  3. Run --cuts 2 and read every row. Most bugs hide at cuts: pops, wrong timing, elements landing early. Use --stills for moments that have no cue. It renders them all in one browser launch, which is much faster than separate --still calls.
  4. Don't render the final video until a filmstrip looks right.

6. Render

node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --trc srgb               # MP4 + synthesized score if the comp defines one
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --motion-blur 8          # film-style blur (8× render time)
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --audio music.mp3        # use the user's music instead
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html --score-only -o score.wav # just the audio
node ${CLAUDE_SKILL_DIR}/scripts/render.mjs videos/<slug>/index.html -o demo.gif              # GIF (silent, ≤960px)

Other flags: --no-score, --fps 60, --scale 2 (4K) or 0.5 (drafts), --from 2 --to 5, --transparent, --crf 23, -o out.mov (ProRes 4444 + alpha), --dither or --10bit for big dark gradients.

  • Color. The output is BT.709-converted and tagged. Use --trc srgb for files watched directly (web, README, Apple devices); it measured exact in Chrome and Safari.
  • Sound. The score's integrated loudness is measured per ITU-R BS.1770 and normalized to -14 LUFS, with a -1 dBFS sample-peak ceiling. Check it alone with --score-only -o score.wav. Very quiet intros sit well below the body after normalization, so give them some level.
  • File size. 60fps UI pieces at the default CRF 18 run about 4 MB per 15s. --crf 20–22 is visually identical for web and README use.
  • Screenshots for camera moves. 1× screenshots blur above about 1.4× zoom. When a real product is the subject, ask for 2× captures (or capture them yourself at deviceScaleFactor: 2).

7. Deliver

Report:

  • the output path, duration, resolution, fps and file size
  • the concept in one sentence, the shot list in 3–6 bullets, and the techniques used
  • how to tweak it: "every timing is a beat number; open index.html to scrub"

Offer variants such as a 9:16 cut, a 6s bumper, a silent GIF for a README, or a re-score in a different mood.

Never claim the video looks good without having read a filmstrip of the final version.

Motion design principles (quick reference)

Read references/motion-principles.md for depth.

  • Durations. Micro 200–400ms; text and cards 500–900ms; camera and big reveals 900–1400ms. Nothing important happens in under 150ms.
  • Easing. Entrances decelerate (strong). Exits accelerate (inCubic) and take 60–70% of the entrance time. Camera moves use smooth. Linear is only for tickers and loops.
  • Springs. Only for physical moments: stiffness 120–260, damping 12–20.
  • Stagger. 30–90ms between siblings. Use grid/center staggers ({ from: 'center', grid }) for systems.
  • Direction is meaning. Keep flow directions consistent, or break them on purpose on a beat.
  • Overlap. The next shot starts before the last one fully leaves, or cut hard exactly on the beat. Never leave a gap.
  • Hierarchy through motion. The hero moves most and first.
  • Brand pieces. Restraint wins: one or two ambient motions, stillness over filler.
  • Creative pieces. Density wins, but it must be organized. One thread, one palette, cuts on the grid.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.