# Kinetic Motion Ad

> Build premium white-background, single-green-accent kinetic-typography motion ads (9:16) with real footage layered behind HTML type — the divyansh.fx_ style. Use when the user wants a "motion graphics ad", "kinetic typography video", "text animation ad", or to turn a voiceover script into a faceless/objects-driven social ad in the workspace under C:\Users\user\Desktop\video-ad. Composites keyed or framed footage (green-screen OR their own Veo clips) with animated HTML/SVG objects, one green accent, italic-serif emphasis, depth/parallax, and a brand end card.

- Skill: `abdul977/kinetic-motion-ad` (Agent Skill)
- Install (CLI): `npx skillmds@latest add abdul977/kinetic-motion-ad`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abdul977/kinetic-motion-ad/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: abdul977 (https://skillmd.com/u/abdul977)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/abdul977/kinetic-motion-ad

---


Turn a voiceover script into a polished 9:16 motion-graphics ad. This is NOT plain kinetic text —
it layers **real footage + animated objects + refined type** with depth. Learned across the Ahmad /
Muahib "3 signs your business is invisible" build. Companion skills: use `frontend-design` and
`ui-design-system` for design polish, `modern-css` for CSS. See also the `video-ad-concept-editor`
skill for the ffmpeg/clip-cutting fundamentals.

## Non-negotiable design system (derived from @divyansh.fx_)
| token | value |
|---|---|
| background | pure white `#ffffff`, with faint drifting green **rings** + green **bokeh** particles |
| accent | ONE grass green `#16c000` — never a second accent color |
| ink | `#0c0c0d` |
| statement type | heavy grotesque (Segoe UI Black / 900) |
| emphasis type | **italic serif** (Georgia italic) on the ONE key word per line, with a green **glow** (`text-shadow:0 0 44px rgba(22,192,0,.5)`) |
| motifs | numbered chips, kinetic word pop-ins (back-ease overshoot), objects that *argue* the line, hand-drawn ellipse highlight, callback (problems→green checks), brand end card |

## The rules that make it look pro (all hard-won from user feedback)
1. **Objects over text.** For each VO line ask "what object shows this?" — a map with your pin missing,
   a browser aging into a CLOSED sign, followers-up vs customers-flat. Text = only the emphasis word.
2. **Cast for the audience.** Nigerian client → Nigerian faces. Free green-screen of Black
   businesspeople is scarce; **reuse the client's own Veo clips** as footage layers instead.
3. **Never a hard cutout.** Blend every keyed/framed edge: despill → erode → feather → contact shadow →
   (on white) a white light-wrap. The element must SIT in the frame, not on it.
4. **Never let one clip carry a scene.** Multiple assets moving; something always changing.
5. **Depth + parallax.** Layers back→front: rings/glow → blurred footage wash → sharp hero (rises
   sharp, recedes+blurs on exit) → bokeh → type. Each layer moves at a different rate.
6. **Deliberate, UNIFORM composition.** Same skeleton every scene (e.g. text top-left, framed
   presenter top-right, scene object across the bottom). Respect 9:16 safe margins.
7. **QC frame-by-frame before shipping** (§QC). Every element in-box, no overflow, circle where it
   belongs, footage fades when the HTML says so.

## Pipeline (local, no network)
- `tools/html2mp4/render.mjs <html> <out> <frames> <fps>` — opaque render (footage inside HTML).
- `tools/html2mp4/render_alpha.mjs …` — **transparent** render (graphics to overlay on footage). Both
  step `window.seek(t)` per frame and await optional `window.__assetsReady`.
- **Architecture that scales:** footage layers in ffmpeg, graphics rendered TRANSPARENT and overlaid
  last. One `*_fg.html` (transparent: objects+type+frame-ring+bokeh) per scene → `render_alpha` →
  ffmpeg composite `white bg + footage wash + framed inset + [alpha graphics]` → concat + VO.
- Deterministic HTML: drive everything from `t`; no CSS animations / Date.now; call `seek(0)` at end.

## Footage as a layer (two ways)
- **Green-screen → key:** `chromakey=0xGREEN:0.13:0.05,despill=type=green:mix=0.4,format=yuva420p,split[c0][c1];[c1]alphaextract,erosion,erosion,gblur=sigma=1.1[a];[c0][a]alphamerge` then contact shadow `alphaextract→gblur=9→black→colorchannelmixer=aa=0.38`.
- **Non-green client clip (e.g. Veo):** crop ABOVE the ✦ watermark (`crop=720:994:0:40`), scale, round
  with a PIL rounded-rect mask + `alphamerge`, add contact shadow, overlay; HTML draws a refined frame
  ring on top. Also make a **blurred wash**: `boxblur=42,eq=brightness=0.15:saturation=0.5,colorchannelmixer=aa=0.14` so white brand shows through.

### Refined framed-inset CSS (premium, not rough)
White 7px border, radius 44 (match the mask), layered shadow with a faint green cast, a top gloss
highlight, a bottom dark scrim gradient for a clean caption (green dot + tracked label). NOT a thick
inset border + muddy gradient bar. Grade the footage `eq=brightness=0.02:contrast=1.05:saturation=1.06`.

## Audio (social spec, verified)
`highpass=f=85,afftdn=nr=12:nf=-30,deesser=i=0.4,loudnorm=I=-14:TP=-1.5:LRA=11,alimiter=limit=0.84:level=disabled`
(alimiter MUST have `level=disabled` or it re-normalizes hot). Per-scene VO padded to that scene's exact
video length so audio+graphics stay block-locked. Encode: libx264 crf 17-18, yuv420p, +faststart; aac 192k 48k.

## QC — do this every time before calling it done
Extract ~5 frames per scene at the moment each element is fully on; check EACH for: text overflowing
its box (auto-width box x+width must be ≤1080), missing headline (breaks uniformity), an emphasis
circle/underline offset to the wrong place (SVG child positioned relative to its text, not 300px away),
and footage insets that must fade with the HTML (ffmpeg-composited video ignores HTML fades — fade it
in ffmpeg too). Re-transcribe the render; confirm -14 LUFS, A/V drift <2 frames.

## Runtime math (say it out loud)
N seconds of VO ≈ N seconds of ad. Hitting a shorter target (e.g. 33s from 41s) means CUTTING spoken
lines and re-timing those scenes' animations — it is a content decision, not a silent speed-up.

