Skip to content
🆕 New skill: Pstack Skill! Lauren Tan's rigorous engineering orchestrator — 23 playbooks, 21 procedures, and 21 principles in a single skill for any agent.View skill →

Motion Ad

Turns a landing page into a paid-traffic-ready video spot. The skill researches the destination page, pulls the product’s real imagery, animates a single paused GSAP timeline in one HTML page, and renders it frame by frame into an H.264 MP4.

The renderer does not screen-record: it seeks the timeline on every frame, so the output is deterministic and two renders of the same index.html are identical. That’s what makes iteration drift-free.

The bundled template (assets/template.html) is not a scaffold — it’s a complete 15s 4:5 ad in five beats:

hook + phone → before/after scan reveal → 3D wall of outputs
→ showcase carousel + social proof → CTA end card

All brand and product content lives in a single CONFIG object at the top of the script. The intended workflow is to rewrite the beats from that CONFIG, not to build a timeline from scratch.

  • Produce a video ad, promo video, or animated ad for Meta, TikTok, or Reels
  • Create video creative whose on-screen claims are anchored to the landing page
  • Cut a 9:16 version of an existing 4:5 spot
  • Re-render an earlier ad with a different hook, hero, or CTA
  • Any request for a “video ad”, even when the person never says “motion graphics”

This skill is narrow, and a scope mistake here costs a full render:

Request Right skill
Animating a button, hover, parallax, or scroll in a site/app animate, transitions-dev
Static feed artwork (1080×1350, carousel covers) image
Long-form video with an on-camera presenter or voiceover video
Ad copy (headlines, RSA, primary text) ad-creative
Terminal window
npx skills add https://github.com/fabricioctelles/skills -s motion-ad

The skill needs a local toolchain — the agent alone is not enough:

Terminal window
node -v # 18+
ffmpeg -version # mandatory
python3 -c 'import PIL' # Pillow
cd <skill>/scripts && npm install # gsap + playwright-core
google-chrome --version # or: npx playwright install chromium

Without ffmpeg there is no MP4. Without Chrome (or Playwright’s chromium) there is no render. npm install must run inside the skill folder, because the scripts resolve their own dependencies.

Step What happens Completion criterion
1. Research Reads the landing page: promise, prices, ratings, what’s free A claim list, each one traceable to a page
2. Assets Downloads the site’s real imagery, builds the contact sheet Logo + before/after pair + ≥12 output images
3. Storyboard Sets copy and beats, 4–5 blocks across 15s Final copy on every beat
4. CONFIG Fills brand, colors, copy, and image paths Test stills with no Acme and no Benefit one
5. Stills review Renders 9 frames and tiles them into a contact sheet No placeholders, no overlaps, readable at thumbnail size
6. Render + deliver Full MP4, ffprobe, versioned delivery File in ~/Downloads/ with correct duration and nb_frames

Between step 4 and step 5 sits references/template-map.md — the template anatomy with the render contract, every CONFIG field, DOM ids, geometry constants, and the recipes for cutting/adding a beat and re-laying out.

Time Beat CONFIG fields
0–2.2s Hook, phone scrolls a screen capture, finger taps the input hook, screen, screenScroll, tap
2.2–5.4s Tapped card grows into the hero; scan beam reveals before → after; benefit pills reveal, before, after, beforeLabel, afterLabel, benefits
5.5–8.7s Hero shrinks into a tilted 3D wall of outputs scale, scaleChip, gallery
8.7–11.8s Showcase carousel (3 cards) + proof row proofHl, showcase, showChip, proof
11.8–15s Brand-color circle wipe → logo, headline, chip, button tap cta.headline, cta.chip, cta.button, cta.foot

If a beat doesn’t fit the product, cut it in the timeline instead of forcing it — a desktop tool should open on the hero card, not on a phone.

Format Change needed
4:5 (default) Already the template. Render with --size 1080x1350
9:16 (reels/stories) html,body,#stage → 1080×1920, re-space the vertical positions, --size 1080x1920
1:1 (square feed) The tight one: the phone is 520×1100 and won’t fit 1080×1080. Needs a rescale or a different opening beat — not just re-spacing

The skill separates four rules from the rest because each one’s failure is invisible in the output file — the MP4 renders either way:

  • Every on-screen claim must exist on the destination page. Prices, counts, speeds, guarantees, and “free” get checked by the ad platform and by users. If the client asks for copy that contradicts the page, write it — but flag the conflict once, clearly.
  • Real assets only. The client’s own images, or ones pulled from the live site. Never invent customers, reviews, ratings, or results. With no real number for the proof row, proof: null — the row disappears.
  • Never fabricate a person. If a beat needs more shots of someone than exist, crop or mirror real ones and say so.
  • The brand beats the template. Colors, font, logo, and tone come from the product. No hype, no exclamation marks, no emoji unless the brand uses them.

The ones that cost the most time, because the failure only shows up in the final MP4:

  • The timeline is absolute. Every tl.*() call takes a hard-coded second. Cutting the phone beat without re-timing leaves the video frozen on a still frame until the next beat.
  • A wrong image path is not an error. setImg swaps in a labelled placeholder on onerror — the render “passes” and comes out full of gradients. Check the contact sheet every time.
  • Fewer than ~12 images repeats visibly in the 3D wall. The 7×7 grid picks cells by modulo over gallery, so neighbouring tiles land on the same image.
  • --size does not give you 2×. The CSS is hard-coded to 1080×1350 and deviceScaleFactor is 1. For a 2× master, scale #stage in CSS.
  • A long headline doesn’t shrink, it collides. The box is pinned at a fixed top and the extra line grows downward into whatever sits below it.
  • tap and screenScroll are the same gesture. The finger point is fixed; if the scroll moves the target away, the tap lands on empty white.

Evaluated with skill-evaluation — the same rubric used by Agent Plugin Eval:

Criterion Before After
Overall score 65 (B) 88 (A)
Completion criteria 20 90
Gotchas 55 95
Grounded in expertise 60 95
Progressive disclosure 35 90
Setup / Preflight 45 88

Trigger eval across 10 prompts: 5/5 hit rate on requests that should fire, 0/5 leak rate on near-misses (React hover pop, static 1080×1350 cover, 8-minute video, scroll animation, logo gif).

📄 Full scorecard

The copy in this repository adds standard metadata, portable skill-path resolution, a preflight check, and references/template-map.md.