/vid-motion-graphics
Generates motion graphics videos (MP4) from a content brief. Multi-scene HTML/CSS animations rendered frame-by-frame in headless Chromium via Playwright, assembled with FFmpeg. 1080×1080 default, 16:9 (1920×1080) and 9:16 (1080×1920) supported. 5 style presets. Trigger when user
$ npx -y skills add Varnan-Tech/opendirectory --skill vid-motion-graphics --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/vid-motion-graphics
Context preview
The summary Claude sees to decide when to auto-load this skill.
Generates motion graphics videos (MP4) from a content brief. Multi-scene HTML/CSS animations rendered frame-by-frame in headless Chromium via Playwright, assembled with FFmpeg. 1080×1080 default, 16:9 (1920×1080) and 9:16 (1080×1920) supported. 5 style presets. Trigger when user
SKILL.md
vid-motion-graphics.SKILL.mdname: vid-motion-graphics
description: Generates motion graphics videos (MP4) from a content brief. Multi-scene HTML/CSS animations rendered frame-by-frame in headless Chromium via Playwright, assembled with FFmpeg. 1080×1080 default, 16:9 (1920×1080) and 9:16 (1080×1920) supported. 5 style presets. Trigger when user says "create a video", "motion graphic", "animated video", "make a reel", "create an explainer", "animated infographic", or "short video".
compatibility: [claude-code, gemini-cli, github-copilot]
author: OpenDirectory
version: 1.0.0
vid-motion-graphics
Generates multi-scene motion graphics as MP4. Renders HTML/CSS animations in headless Chromium via Playwright (Web Animations API frame-seeking), assembles PNG frames with FFmpeg. No React, no AI APIs, no Python — zero new dependencies beyond the graphic-gif family.
CDN fonts only. No external libraries in HTML.
---
Critical Rules (read before every generation)
1. **Use `window.renderFrame(t)` — no CSS `@keyframes` for scene transitions.** CSS animation `currentTime` seeking is silently ignored for backward seeks in Chromium. The renderFrame approach: a pure JS function computes `opacity`/`transform` directly from milliseconds. Playwright calls it once per frame. Deterministic, race-free. 2. **No `animation-delay` on ANY element.** Not needed with renderFrame. If you catch yourself writing `animation-delay`, stop — you're using the wrong architecture. 3. **`window.__videoReady = true` only inside `document.fonts.ready.then(...)`.** Never set synchronously — fonts must load before Playwright captures frame 1 or text renders with fallback fonts. 4. **Expose `window.__stopPreview()`.** The browser's rAF preview loop races with Playwright's evaluate/screenshot calls. `capture-frames.mjs` calls `__stopPreview()` before the frame loop. Always include it. 5. **Use `t < startMs` (not `<=`) in scene boundary checks.** `t <= 0` at frame 0 makes scene 1 black. The correct guard is `if (t < startMs || t >= endMs) return hidden`. 6. **Body = exact pixel dimensions.** Width and height are integers (`1080px`, `1920px`). No `%`, `vw/vh`, or responsive units. 7. **No two scenes visible simultaneously** (except 10% enter overlap). All scenes `opacity: 0` outside their renderFrame window. 8. **Transitions use `opacity` only.** No `display` toggle, no `visibility` — GPU-composited opacity is frame-perfect. 9. **Never dump HTML in chat.** Save to file, show summary only. 10. **Title states the message, not the topic.** "3 Reasons Q4 Crushed Targets" not "Q4 2024 Performance Video". 11. **Read `references/scene-library.md` before generating ANY HTML.** Use exact HTML structure and CSS class names from that file.
---
Step 1: Intake
**Required:** `content_brief`
**Optional parameters and defaults:**
| Parameter | Default | Description | |---|---|---| | content_brief | — | Text describing what the video communicates (required) | | scenes | auto | Number of scenes (1–6). Auto = derived from brief. | | duration_per_scene | 3s | Duration per scene in seconds (1–8s) | | style | kinetic-dark | kinetic-dark / editorial-light / data-pulse / bold-type / minimal-clean | | aspect_ratio | 1:1 | 1:1 (1080×1080) / 16:9 (1920×1080) / 9:16 (1080×1920) | | fps | 30 | Frames per second (24, 30, or 60) | | music | none | Path to audio file for background track (mp3/m4a/wav) | | source | — | Source attribution shown in final frame footer |
**If `content_brief` is missing, ask exactly:**
> "To create the video, I need a content brief — what should the video communicate? > > Example: 'Show 3 reasons why Q4 revenue grew 85%: new enterprise deals, reduced churn, price increase. Use bold numbers. Style: data-pulse.' > > Optional: style (default: kinetic-dark), aspect ratio (default: 1:1), seconds per scene (default: 3s)"
If `content_brief` is present → proceed to Step 2 immediately.
---
Step 2: Internal Architecture (never shown to user)
**1. Parse brief into scenes (max 6):**
- Scene 1 = hook or title (always)
- Scenes 2–N-1 = supporting points, metrics, or story beats
- Scene N = CTA or closing summary (always, if more than 1 scene)
- One key idea per scene — if brief has 7+ ideas, consolidate the weakest ones
**2. Read `references/scene-library.md`** — choose scene type for each scene:
- Hook/opening → `title-card`
- Single metric → `stat-reveal`
- List of 2–4 points → `bullet-list`
- Before vs after / two values → `split-screen`
- Testimonial / quote → `quote-card`
- Final / CTA → `cta-card`
**3. Read `references/style-presets.md`** — load CSS tokens + animation personality for chosen style.
**4. Calculate timing:**
totalDuration = sceneCount × duration_per_scene (seconds)
totalFrames = totalDuration × fps
Each scene occupies `(100 / sceneCount)%` of the total `@keyframes` range.
| Scene | Start % | End % | |---|---|---| | 1 | 0% | (100/N)% | | 2 | (100/N)% | (200/N)% | | … | … | … | | N | ((N-1)×100/N)% | 100% |
Within each scene's range:
- Enter: first 10% of scene range
- Hold: 10% to 85% of scene range
- Exit: 85% to 100% of scene range
**5. Determine pixel dimensions:**
- `1:1` → W=1080, H=1080
- `16:9` → W=1920, H=1080
- `9:16` → W=1080, H=1920
---
Step 3: HTML Generation
Read `references/scene-library.md` AND `references/style-presets.md` before writing any code.
**Required HTML structure:**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from style preset]
<style>
:root {
[all CSS tokens from style preset]
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: [W]px; height: [H]px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
position: relative;
}
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px;
opacity: 0;
will-change: opacity, transform;
}
.scene-inner {
width: 100%;
max-wiRead more
name: vid-motion-graphics description: Generates motion graphics videos (MP4) from a content brief. Multi-scene HTML/CSS animations rendered frame-by-frame in headless Chromium via Playwright, assembled with FFmpeg. 1080×1080 default, 16:9 (1920×1080) and 9:16 (1080×1920) supported. 5 style presets. Trigger when user says "create a video", "motion graphic", "animated video", "make a reel", "create an explainer", "animated infographic", or "short video". compatibility: [claude-code, gemini-cli, github-copilot] author: OpenDirectory version: 1.0.0
vid-motion-graphics
Generates multi-scene motion graphics as MP4. Renders HTML/CSS animations in headless Chromium via Playwright (Web Animations API frame-seeking), assembles PNG frames with FFmpeg. No React, no AI APIs, no Python — zero new dependencies beyond the graphic-gif family.
CDN fonts only. No external libraries in HTML.
---
Critical Rules (read before every generation)
1. **Use `window.renderFrame(t)` — no CSS `@keyframes` for scene transitions.** CSS animation `currentTime` seeking is silently ignored for backward seeks in Chromium. The renderFrame approach: a pure JS function computes `opacity`/`transform` directly from milliseconds. Playwright calls it once per frame. Deterministic, race-free. 2. **No `animation-delay` on ANY element.** Not needed with renderFrame. If you catch yourself writing `animation-delay`, stop — you're using the wrong architecture. 3. **`window.__videoReady = true` only inside `document.fonts.ready.then(...)`.** Never set synchronously — fonts must load before Playwright captures frame 1 or text renders with fallback fonts. 4. **Expose `window.__stopPreview()`.** The browser's rAF preview loop races with Playwright's evaluate/screenshot calls. `capture-frames.mjs` calls `__stopPreview()` before the frame loop. Always include it. 5. **Use `t < startMs` (not `<=`) in scene boundary checks.** `t <= 0` at frame 0 makes scene 1 black. The correct guard is `if (t < startMs || t >= endMs) return hidden`. 6. **Body = exact pixel dimensions.** Width and height are integers (`1080px`, `1920px`). No `%`, `vw/vh`, or responsive units. 7. **No two scenes visible simultaneously** (except 10% enter overlap). All scenes `opacity: 0` outside their renderFrame window. 8. **Transitions use `opacity` only.** No `display` toggle, no `visibility` — GPU-composited opacity is frame-perfect. 9. **Never dump HTML in chat.** Save to file, show summary only. 10. **Title states the message, not the topic.** "3 Reasons Q4 Crushed Targets" not "Q4 2024 Performance Video". 11. **Read `references/scene-library.md` before generating ANY HTML.** Use exact HTML structure and CSS class names from that file.
---
Step 1: Intake
**Required:** `content_brief`
**Optional parameters and defaults:**
| Parameter | Default | Description | |---|---|---| | content_brief | — | Text describing what the video communicates (required) | | scenes | auto | Number of scenes (1–6). Auto = derived from brief. | | duration_per_scene | 3s | Duration per scene in seconds (1–8s) | | style | kinetic-dark | kinetic-dark / editorial-light / data-pulse / bold-type / minimal-clean | | aspect_ratio | 1:1 | 1:1 (1080×1080) / 16:9 (1920×1080) / 9:16 (1080×1920) | | fps | 30 | Frames per second (24, 30, or 60) | | music | none | Path to audio file for background track (mp3/m4a/wav) | | source | — | Source attribution shown in final frame footer |
**If `content_brief` is missing, ask exactly:**
> "To create the video, I need a content brief — what should the video communicate? > > Example: 'Show 3 reasons why Q4 revenue grew 85%: new enterprise deals, reduced churn, price increase. Use bold numbers. Style: data-pulse.' > > Optional: style (default: kinetic-dark), aspect ratio (default: 1:1), seconds per scene (default: 3s)"
If `content_brief` is present → proceed to Step 2 immediately.
---
Step 2: Internal Architecture (never shown to user)
**1. Parse brief into scenes (max 6):**
- Scene 1 = hook or title (always)
- Scenes 2–N-1 = supporting points, metrics, or story beats
- Scene N = CTA or closing summary (always, if more than 1 scene)
- One key idea per scene — if brief has 7+ ideas, consolidate the weakest ones
**2. Read `references/scene-library.md`** — choose scene type for each scene:
- Hook/opening → `title-card`
- Single metric → `stat-reveal`
- List of 2–4 points → `bullet-list`
- Before vs after / two values → `split-screen`
- Testimonial / quote → `quote-card`
- Final / CTA → `cta-card`
**3. Read `references/style-presets.md`** — load CSS tokens + animation personality for chosen style.
**4. Calculate timing:**
totalDuration = sceneCount × duration_per_scene (seconds) totalFrames = totalDuration × fps
Each scene occupies `(100 / sceneCount)%` of the total `@keyframes` range.
| Scene | Start % | End % | |---|---|---| | 1 | 0% | (100/N)% | | 2 | (100/N)% | (200/N)% | | … | … | … | | N | ((N-1)×100/N)% | 100% |
Within each scene's range:
- Enter: first 10% of scene range
- Hold: 10% to 85% of scene range
- Exit: 85% to 100% of scene range
**5. Determine pixel dimensions:**
- `1:1` → W=1080, H=1080
- `16:9` → W=1920, H=1080
- `9:16` → W=1080, H=1920
---
Step 3: HTML Generation
Read `references/scene-library.md` AND `references/style-presets.md` before writing any code.
**Required HTML structure:**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from style preset]
<style>
:root {
[all CSS tokens from style preset]
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: [W]px; height: [H]px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
position: relative;
}
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px;
opacity: 0;
will-change: opacity, transform;
}
.scene-inner {
width: 100%;
max-wiAI Agent Skills built for Founders who hate Marketing
Repo: Varnan-Tech/opendirectory
Other skills on opendirectory-gtm-skills.
- /app-store-review-arbitrage
Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.
Open skill - /blog-cover-image-cli
Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.
Open skill - /brand-alchemy
World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.
Open skill - /claude-md-generator
Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.
Open skill - /cold-email-verifier
Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.
Open skill - /company-radar
Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.
Open skill

