{"id":"0d937e72-9428-4cdb-9759-f661337f5f43","shortId":"JtzggQ","kind":"skill","title":"vid-motion-graphics","tagline":"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 ","description":"# vid-motion-graphics\n\nGenerates 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.\n\nCDN fonts only. No external libraries in HTML.\n\n---\n\n## Critical Rules (read before every generation)\n\n1. **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.\n2. **No `animation-delay` on ANY element.** Not needed with renderFrame. If you catch yourself writing `animation-delay`, stop — you're using the wrong architecture.\n3. **`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.\n4. **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.\n5. **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`.\n6. **Body = exact pixel dimensions.** Width and height are integers (`1080px`, `1920px`). No `%`, `vw/vh`, or responsive units.\n7. **No two scenes visible simultaneously** (except 10% enter overlap). All scenes `opacity: 0` outside their renderFrame window.\n8. **Transitions use `opacity` only.** No `display` toggle, no `visibility` — GPU-composited opacity is frame-perfect.\n9. **Never dump HTML in chat.** Save to file, show summary only.\n10. **Title states the message, not the topic.** \"3 Reasons Q4 Crushed Targets\" not \"Q4 2024 Performance Video\".\n11. **Read `references/scene-library.md` before generating ANY HTML.** Use exact HTML structure and CSS class names from that file.\n\n---\n\n## Step 1: Intake\n\n**Required:** `content_brief`\n\n**Optional parameters and defaults:**\n\n| Parameter | Default | Description |\n|---|---|---|\n| content_brief | — | Text describing what the video communicates (required) |\n| scenes | auto | Number of scenes (1–6). Auto = derived from brief. |\n| duration_per_scene | 3s | Duration per scene in seconds (1–8s) |\n| style | kinetic-dark | kinetic-dark / editorial-light / data-pulse / bold-type / minimal-clean |\n| aspect_ratio | 1:1 | 1:1 (1080×1080) / 16:9 (1920×1080) / 9:16 (1080×1920) |\n| fps | 30 | Frames per second (24, 30, or 60) |\n| music | none | Path to audio file for background track (mp3/m4a/wav) |\n| source | — | Source attribution shown in final frame footer |\n\n**If `content_brief` is missing, ask exactly:**\n\n> \"To create the video, I need a content brief — what should the video communicate?\n>\n> Example: 'Show 3 reasons why Q4 revenue grew 85%: new enterprise deals, reduced churn, price increase. Use bold numbers. Style: data-pulse.'\n>\n> Optional: style (default: kinetic-dark), aspect ratio (default: 1:1), seconds per scene (default: 3s)\"\n\nIf `content_brief` is present → proceed to Step 2 immediately.\n\n---\n\n## Step 2: Internal Architecture (never shown to user)\n\n**1. Parse brief into scenes (max 6):**\n- Scene 1 = hook or title (always)\n- Scenes 2–N-1 = supporting points, metrics, or story beats\n- Scene N = CTA or closing summary (always, if more than 1 scene)\n- One key idea per scene — if brief has 7+ ideas, consolidate the weakest ones\n\n**2. Read `references/scene-library.md`** — choose scene type for each scene:\n- Hook/opening → `title-card`\n- Single metric → `stat-reveal`\n- List of 2–4 points → `bullet-list`\n- Before vs after / two values → `split-screen`\n- Testimonial / quote → `quote-card`\n- Final / CTA → `cta-card`\n\n**3. Read `references/style-presets.md`** — load CSS tokens + animation personality for chosen style.\n\n**4. Calculate timing:**\n```\ntotalDuration = sceneCount × duration_per_scene  (seconds)\ntotalFrames   = totalDuration × fps\n```\nEach scene occupies `(100 / sceneCount)%` of the total `@keyframes` range.\n\n| Scene | Start % | End % |\n|---|---|---|\n| 1 | 0% | (100/N)% |\n| 2 | (100/N)% | (200/N)% |\n| … | … | … |\n| N | ((N-1)×100/N)% | 100% |\n\nWithin each scene's range:\n- Enter: first 10% of scene range\n- Hold: 10% to 85% of scene range\n- Exit: 85% to 100% of scene range\n\n**5. Determine pixel dimensions:**\n- `1:1` → W=1080, H=1080\n- `16:9` → W=1920, H=1080\n- `9:16` → W=1080, H=1920\n\n---\n\n## Step 3: HTML Generation\n\nRead `references/scene-library.md` AND `references/style-presets.md` before writing any code.\n\n**Required HTML structure:**\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n[font CDN link from style preset]\n<style>\n:root {\n  [all CSS tokens from style preset]\n}\n\n*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }\nhtml, body {\n  width: [W]px; height: [H]px;\n  overflow: hidden;\n  background: var(--bg);\n  font-family: var(--font-body);\n  position: relative;\n}\n\n.scene {\n  position: absolute;\n  inset: 0;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  padding: 80px;\n  opacity: 0;\n  will-change: opacity, transform;\n}\n.scene-inner {\n  width: 100%;\n  max-width: 960px;\n}\n\n/* Scene-type CSS from scene-library.md */\n[paste scene-type CSS here]\n</style>\n</head>\n<body>\n\n<div class=\"scene scene-1\">\n  <div class=\"scene-inner\">\n    [scene 1 HTML from scene-library.md template]\n  </div>\n</div>\n\n[repeat for each scene]\n\n<script>\nwindow.__videoReady = false;\nwindow.TOTAL_DURATION_MS = [totalDuration * 1000];\n\n// ── Animation helpers ─────────────────────────────────────────────────────────\nfunction lerp(a, b, p) { return a + (b - a) * p; }\nfunction clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }\nfunction easeOutCubic(t) { return 1 - Math.pow(1 - clamp(t, 0, 1), 3); }\n\nfunction sceneState(t, startMs, endMs) {\n  if (t < startMs || t >= endMs) return { opacity: 0, ty: 0 };\n  const prog = (t - startMs) / (endMs - startMs);\n  if (prog < 0.10) {\n    const p = easeOutCubic(prog / 0.10);\n    return { opacity: p, ty: lerp(24, 0, p) };\n  }\n  if (prog < 0.85) return { opacity: 1, ty: 0 };\n  const p = (prog - 0.85) / 0.15;\n  return { opacity: 1 - p, ty: lerp(0, -12, p) };\n}\n\nfunction applySceneState(el, state) {\n  el.style.opacity = state.opacity;\n  el.style.transform = state.ty !== 0 ? `translateY(${state.ty.toFixed(2)}px)` : '';\n}\n\n// ── Main render function — called by Playwright once per frame ────────────────\nwindow.renderFrame = function(t) {\n  // Scene 1: 0ms – [D]ms\n  applySceneState(document.querySelector('.scene-1'), sceneState(t, 0, [D]));\n  // Scene 2: [D]ms – [2D]ms\n  applySceneState(document.querySelector('.scene-2'), sceneState(t, [D], [2D]));\n  // ... repeat per scene ...\n};\n\n// ── Preview loop — stopped by Playwright before frame capture ─────────────────\nlet __previewActive = false;\nlet __previewRafId = null;\nwindow.__stopPreview = function() {\n  __previewActive = false;\n  if (__previewRafId !== null) { cancelAnimationFrame(__previewRafId); __previewRafId = null; }\n};\n\ndocument.fonts.ready.then(() => {\n  window.renderFrame(0);\n  window.__videoReady = true;\n  __previewActive = true;\n  const startTime = performance.now();\n  function previewTick() {\n    if (!__previewActive) return;\n    const elapsed = performance.now() - startTime;\n    if (elapsed < window.TOTAL_DURATION_MS) {\n      window.renderFrame(elapsed);\n      __previewRafId = requestAnimationFrame(previewTick);\n    } else {\n      window.renderFrame(window.TOTAL_DURATION_MS - 1);\n      __previewActive = false;\n    }\n  }\n  __previewRafId = requestAnimationFrame(previewTick);\n});\n</script>\n</body>\n</html>\n```\n\n**Design quality rules:**\n- Headline font size: never smaller than 60px — text must read at mobile thumbnail size\n- Numbers and stats: always the largest element on screen (120–200px)\n- Tight letter-spacing on display type: `-0.02em` to `-0.04em`\n- One accent color per scene — don't scatter accent across multiple elements\n- Dark presets: dividers `rgba(255,255,255,0.10)`, never solid\n- Light presets: dividers `rgba(0,0,0,0.10)`, never solid\n- `transform-origin: center center` on every element that uses `transform`\n- Padding inside `.scene`: minimum 80px — never let text touch viewport edges\n\n---\n\n## Step 4: Self-QA (fix every failure before Step 5)\n\n**renderFrame correctness:**\n- [ ] `window.renderFrame(t)` defined — pure function, no side effects outside style writes\n- [ ] Scene boundary uses `t < startMs` (not `t <= startMs`) — avoids black frame 0\n- [ ] Zero instances of `animation-delay` or `@keyframes` for scene transitions\n- [ ] No two scenes have overlapping `opacity: 1` windows (except 10% enter overlap)\n- [ ] `window.__stopPreview()` exposed and preview rAF loop checks `__previewActive`\n\n**Readiness signal:**\n- [ ] `window.__videoReady = false` declared before `document.fonts.ready`\n- [ ] `window.__videoReady = true` set ONLY inside `document.fonts.ready.then(...)`\n- [ ] `window.renderFrame(0)` called inside `document.fonts.ready.then(...)` before setting `__videoReady = true`\n\n**Layout:**\n- [ ] `html, body` use exact pixel dimensions (`[W]px`, `[H]px`)\n- [ ] No `%`, `vw`, `vh`, `rem` units on `body` width/height\n- [ ] `overflow: hidden` on `html, body`\n- [ ] All scenes `position: absolute; inset: 0`\n\n**Design:**\n- [ ] All colors from style preset tokens — no free hex values\n- [ ] All fonts from style preset — no free font-family strings\n- [ ] Headline font size ≥ 60px\n- [ ] Source in final scene if `source` param provided\n\n---\n\n## Step 5: Export\n\nDetermine slug from brief content (kebab-case, ≤30 chars):\n```bash\nmkdir -p chart/[slug]\n```\n\nSave HTML: `chart/[slug]/video.html`\n\nBrowser preview:\n```bash\nopen chart/[slug]/video.html\n```\n\nRun export (replace `[skill-root]` with path to this skill's directory):\n```bash\nbash [skill-root]/scripts/export-video.sh \\\n  chart/[slug]/video.html \\\n  chart/[slug]/video.mp4 \\\n  --duration [totalDuration] \\\n  --fps [fps] \\\n  --width [W] \\\n  --height [H] \\\n  [--music path/to/audio.mp3]\n```\n\nThe script installs Playwright on first run (~200MB Chromium), captures all frames, then assembles MP4 with FFmpeg.\n\n---\n\n## Step 6: Output Summary\n\n```\n## Video: [title from brief]\nDate: [YYYY-MM-DD] | Scenes: [N] | Style: [style] | Aspect: [ratio]\nDuration: [N]s | FPS: [fps] | Frames: [N]\n\nFiles\n  Source:   chart/[slug]/video.html\n  Output:   chart/[slug]/video.mp4\n  Size:     [X] MB\n\nChecklist\n- [ ] All scenes appear in sequence with no blank frames\n- [ ] Text legible at mobile thumbnail size\n- [ ] Scene transitions smooth (no jump cuts)\n- [ ] Final scene includes CTA or closing message\n- [ ] Source attribution present in final frame (if provided)\n```\n\n---\n\n## Prompt Tips (show when user asks for guidance)\n\n> \"Provide a content brief — bullet points of what each scene should say.\"\n>\n> \"Name the insight directly. '3 reasons Q4 grew 85%' gives the video a spine.\"\n>\n> \"Mention the style if you have a preference: kinetic-dark (default), editorial-light, data-pulse, bold-type, minimal-clean.\"\n>\n> \"Specify aspect ratio for the platform: 1:1 for LinkedIn/Instagram feed, 9:16 for Stories/Reels, 16:9 for YouTube/presentations.\"\n>\n> ✅ Good: \"Create a 9-second video. Q4 revenue hit $4.2M (85% growth). Drivers: enterprise deals, churn 1.2%, price increase. CTA: acme.com/q4. Style: data-pulse. Aspect: 1:1.\"\n>\n> ❌ Bad: \"make a video about our company\"","tags":["vid","motion","graphics","opendirectory","varnan-tech","agent-skills","gtm","hermes-agent","marketing-skills","openclaw-skills","skill-pack","skills"],"capabilities":["skill","source-varnan-tech","skill-vid-motion-graphics","topic-agent-skills","topic-gtm","topic-hermes-agent","topic-marketing-skills","topic-openclaw-skills","topic-skill-pack","topic-skills","topic-technical-seo"],"categories":["opendirectory"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/Varnan-Tech/opendirectory/vid-motion-graphics","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add Varnan-Tech/opendirectory","source_repo":"https://github.com/Varnan-Tech/opendirectory","install_from":"skills.sh"}},"qualityScore":"0.593","qualityRationale":"deterministic score 0.59 from registry signals: · indexed on github topic:agent-skills · 286 github stars · SKILL.md body (11,637 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:54:44.286Z","embedding":null,"createdAt":"2026-05-03T18:54:49.342Z","updatedAt":"2026-05-18T18:54:44.286Z","lastSeenAt":"2026-05-18T18:54:44.286Z","tsv":"'-0.02':800 '-0.04':803 '-1':562,683 '/q4.':1269 '/scripts/export-video.sh':1060 '/video.html':1034,1041,1063,1124 '/video.mp4':1066,1128 '0':242,245,291,676,831,832,833,894,940,977 '0.10':824,834 '1':112,200,248,363,389,404,427,428,429,430,521,522,546,554,579,675,715,716,756,912,1233,1234,1275,1276 '1.2':1263 '10':285,326,693,698,915 '100':665,685,707 '100/n':677,679,684 '1080':32,33,38,42,431,432,436,439,718,720,726,730 '1080px':271 '11':344 '120':791 '16':35,41,433,438,721,728,1239,1242 '1920':37,43,435,440,724,732 '1920px':272 '2':157,536,539,560,595,615,678 '200/n':680 '200mb':1084 '200px':792 '2024':341 '24':446 '255':821,822,823 '3':184,334,491,639,734,1193 '30':442,447,1023 '3s':398,527 '4':207,616,650,860 '4.2':1255 '5':45,232,711,869,1013 '6':261,390,552,1095 '60':449 '60px':774,1003 '7':278,589 '8':296 '80px':852 '85':497,700,705,1197,1257 '8s':405 '9':36,40,314,434,437,722,727,1238,1243,1249 'absolut':975 'accent':806,813 'acme.com':1268 'acme.com/q4.':1267 'across':814 'ai':85 'alway':229,558,575,785 'anim':18,65,72,123,160,175,645,899 'animation-delay':159,174,898 'api':73,86 'appear':1135 'approach':136 'architectur':183,541 'ask':473,1174 'aspect':425,518,1111,1228,1274 'assembl':29,77,1090 'attribut':462,1162 'audio':454 'auto':385,391 'avoid':891 'background':457 'backward':130 'bad':1277 'bash':1025,1037,1055,1056 'beat':568 'beyond':92 'black':249,892 'blank':1140 'bodi':262,950,965,971 'bold':420,506,1222 'bold-typ':419,1221 'boundari':239,884 'brief':13,367,376,394,470,483,530,548,587,1018,1101,1180 'browser':211,1035 'bullet':619,1181 'bullet-list':618 'calcul':651 'call':148,221,223,941 'captur':198,1086 'capture-frames.mjs':222 'card':607,633,638 'case':1022 'catch':171 'cdn':98,750 'center':840,841 'char':1024 'chart':1028,1032,1039,1061,1064,1122,1126 'chat':319 'check':240,924 'checklist':1132 'choos':598 'chosen':648 'chromium':26,68,133,1085 'churn':502,1262 'class':357 'clean':424,1226 'close':573,1159 'code':744 'color':807,980 'communic':382,488 'compani':1283 'composit':308 'comput':141 'consolid':591 'content':12,366,375,469,482,529,1019,1179 'correct':251,871 'creat':476,1247 'critic':106 'crush':337 'css':117,122,356,643 'cta':571,635,637,1157,1266 'cta-card':636 'currenttim':124 'cut':1153 'dark':409,412,517,817,1213 'data':417,510,1219,1272 'data-puls':416,509,1218,1271 'date':1102 'dd':1106 'deal':500,1261 'declar':930 'default':34,371,373,514,520,526,1214 'defin':874 'delay':161,176,900 'depend':91 'deriv':392 'describ':378 'descript':374 'design':765,978 'determin':712,1015 'determinist':153 'dimens':265,714,954 'direct':144,1192 'directori':1054 'display':302,798 'divid':819,829 'document.fonts.ready':932 'document.fonts.ready.then':189,938,943 'driver':1259 'dump':316 'durat':395,399,655,1067,1113 'edg':858 'editori':414,1216 'editorial-light':413,1215 'effect':879 'element':164,788,816,844 'em':801,804 'end':674 'endm':258 'enter':286,691,916 'enterpris':499,1260 'evaluate/screenshot':220 'everi':110,843,865 'exact':263,352,474,952 'exampl':489 'except':284,914 'exit':704 'export':1014,1043 'expos':208,919 'extern':102 'failur':866 'fallback':205 'fals':929 'famili':97,998 'feed':1237 'ffmpeg':31,81,1093 'file':322,361,455,1120 'final':465,634,1006,1154,1165 'first':692,1082 'fix':864 'font':99,193,206,749,769,990,997,1001 'font-famili':996 'footer':467 'fps':441,661,1069,1070,1116,1117 'frame':21,23,75,79,152,199,227,244,312,443,466,893,1088,1118,1141,1166 'frame-by-fram':20 'frame-perfect':311 'frame-seek':74 'free':156,986,995 'function':140,876 'generat':5,55,111,348,736 'gif':96 'give':1198 'good':1246 'gpu':307 'gpu-composit':306 'graphic':4,7,54,60,95 'graphic-gif':94 'grew':496,1196 'growth':1258 'guard':252 'guidanc':1176 'h':719,725,731,957,1074 'headless':25,67 'headlin':768,1000 'height':268,1073 'hex':987 'hidden':260,968 'hit':1254 'hold':697 'hook':555 'hook/opening':604 'html':105,317,350,353,735,746,748,757,949,970,1031 'html/css':17,64 'idea':583,590 'ignor':128 'immedi':537 'includ':230,1156 'increas':504,1265 'inset':976 'insid':188,849,937,942 'insight':1191 'instal':1079 'instanc':896 'intak':364 'integ':270 'intern':540 'js':139 'jump':1152 'kebab':1021 'kebab-cas':1020 'key':582 'keyfram':118,670,902 'kinet':408,411,516,1212 'kinetic-dark':407,410,515,1211 'largest':787 'layout':948 'legibl':1143 'let':854 'letter':795 'letter-spac':794 'librari':103 'light':415,827,1217 'link':751 'linkedin/instagram':1236 'list':613,620 'load':195,642 'loop':215,228,923 'm':1256 'make':246,1278 'max':551 'mb':1131 'mention':1203 'messag':330,1160 'metric':565,609 'millisecond':146 'minim':423,1225 'minimal-clean':422,1224 'minimum':851 'miss':472 'mkdir':1026 'mm':1105 'mobil':779,1145 'motion':3,6,53,59 'mp3/m4a/wav':459 'mp4':9,62,1091 'multi':15,57 'multi-scen':14,56 'multipl':815 'music':450,1075 'must':194,776 'n':561,570,681,682,1108,1114,1119 'name':358,1189 'need':166,480 'never':190,315,542,771,825,835,853 'new':90,498 'none':451 'number':386,507,782 'occupi':664 'one':581,594,805 'opac':142,290,299,309,911 'open':1038 'option':368,512 'origin':839 'output':1096,1125 'outsid':292,880 'overflow':967 'overlap':287,910,917 'p':1027 'pad':848 'param':1010 'paramet':369,372 'pars':547 'path':452,1049 'path/to/audio.mp3':1076 'per':151,396,400,444,524,584,656,808 'perfect':313 'perform':342 'person':646 'pixel':264,713,953 'platform':1232 'playwright':28,70,147,197,218,1080 'png':78 'point':564,617,1182 'posit':974 'prefer':1210 'present':532,1163 'preset':47,754,818,828,983,993 'preview':214,921,1036 'previewact':925 'price':503,1264 'proceed':533 'prompt':1169 'provid':1011,1168,1177 'puls':418,511,1220,1273 'pure':138,875 'px':956,958 'python':88 'q4':336,340,494,1195,1252 'qa':863 'qualiti':766 'quot':630,632 'quote-card':631 'race':155,216 'race-fre':154 'raf':213,922 'rang':671,690,696,703,710 'ratio':426,519,1112,1229 're':179 'react':83 'read':108,345,596,640,737,777 'readi':926 'reason':335,492,1194 'reduc':501 'references/scene-library.md':346,597,738 'references/style-presets.md':641,740 'rem':962 'render':19,63,203 'renderfram':135,168,294,870 'repeat':761 'replac':1044 'requir':365,383,745 'respons':276 'return':259 'reveal':612 'revenu':495,1253 'rgba':820,830 'root':1047,1059 'rule':107,767 'run':1042,1083 'save':320,1030 'say':1188 'scatter':812 'scene':16,58,120,238,247,281,289,384,388,397,401,525,550,553,559,569,580,585,599,603,657,663,672,688,695,702,709,755,764,809,850,883,904,908,973,1007,1107,1134,1148,1155,1186 'scene-library.md':759 'scenecount':654,666 'screen':628,790 'script':1078 'second':403,445,523,658,1250 'seek':76,125,131 'self':862 'self-qa':861 'sequenc':1137 'set':191,935,945 'show':323,490,1171 'shown':463,543 'side':878 'signal':927 'silent':127 'simultan':283 'singl':608 'size':770,781,1002,1129,1147 'skill':1046,1052,1058 'skill-root':1045,1057 'skill-vid-motion-graphics' 'slug':1016,1029,1033,1040,1062,1065,1123,1127 'smaller':772 'smooth':1150 'solid':826,836 'sourc':460,461,1004,1009,1121,1161 'source-varnan-tech' 'space':796 'specifi':1227 'spine':1202 'split':627 'split-screen':626 'start':673 'startm':235,256,887,890 'stat':611,784 'stat-rev':610 'state':328 'step':362,535,538,733,859,868,1012,1094 'stop':177 'stoppreview':224 'stori':567 'stories/reels':1241 'string':999 'structur':354,747 'style':46,406,508,513,649,753,881,982,992,1109,1110,1205,1270 'summari':324,574,1097 'support':44,563 'synchron':192 'target':338 'templat':760 'testimoni':629 'text':202,377,775,855,1142 'thumbnail':780,1146 'tight':793 'time':652 'tip':1170 'titl':327,557,606,1099 'title-card':605 'toggl':303 'token':644,984 'topic':333 'topic-agent-skills' 'topic-gtm' 'topic-hermes-agent' 'topic-marketing-skills' 'topic-openclaw-skills' 'topic-skill-pack' 'topic-skills' 'topic-technical-seo' 'total':669 'totaldur':653,660,1068 'totalfram':659 'touch':856 'track':458 'transform':143,838,847 'transform-origin':837 'transit':121,297,905,1149 'trigger':48 'true':186,934,947 'two':280,624,907 'type':421,600,799,1223 'unit':277,963 'use':113,180,233,298,351,505,846,885,951 'user':50,545,1173 'valu':625,988 'vh':961 'via':27,69 'vid':2,52 'vid-motion-graph':1,51 'video':8,343,381,478,487,1098,1200,1251,1280 'videoreadi':946 'viewport':857 'visibl':282,305 'vs':622 'vw':960 'vw/vh':274 'w':717,723,729,955,1072 'weakest':593 'web':71 'width':266,1071 'width/height':966 'window':295,913 'window.__stoppreview':209,918 'window.__videoready':185,928,933 'window.renderframe':114,872,939 'within':686 'write':173,742,882 'wrong':182 'x':1130 'youtube/presentations':1245 'yyyi':1104 'yyyy-mm-dd':1103 'zero':89,895","prices":[{"id":"7aba61ad-9c40-4f18-8dfa-079c67592f8f","listingId":"0d937e72-9428-4cdb-9759-f661337f5f43","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"Varnan-Tech","category":"opendirectory","install_from":"skills.sh"},"createdAt":"2026-05-03T18:54:49.342Z"}],"sources":[{"listingId":"0d937e72-9428-4cdb-9759-f661337f5f43","source":"github","sourceId":"Varnan-Tech/opendirectory/vid-motion-graphics","sourceUrl":"https://github.com/Varnan-Tech/opendirectory/tree/main/skills/vid-motion-graphics","isPrimary":false,"firstSeenAt":"2026-05-03T18:54:49.342Z","lastSeenAt":"2026-05-18T18:54:44.286Z"}],"details":{"listingId":"0d937e72-9428-4cdb-9759-f661337f5f43","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"Varnan-Tech","slug":"vid-motion-graphics","github":{"repo":"Varnan-Tech/opendirectory","stars":286,"topics":["agent-skills","gtm","hermes-agent","marketing-skills","openclaw-skills","skill-pack","skills","technical-seo"],"license":"mit","html_url":"https://github.com/Varnan-Tech/opendirectory","pushed_at":"2026-05-18T18:27:10Z","description":" AI Agent Skills built for Founders who hate Marketing","skill_md_sha":"1ae7cc114e69970bbf65616bbedb923c4df03d3f","skill_md_path":"skills/vid-motion-graphics/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/Varnan-Tech/opendirectory/tree/main/skills/vid-motion-graphics"},"layout":"multi","source":"github","category":"opendirectory","frontmatter":{"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]"},"skills_sh_url":"https://skills.sh/Varnan-Tech/opendirectory/vid-motion-graphics"},"updatedAt":"2026-05-18T18:54:44.286Z"}}