Fil · Skills

HTML Explainer Video, a skill for Claude Code, Codex and Cursor

A skill for Claude Code, Codex and Cursor: turn a product, a feature or an idea into a one-minute explainer film in your own look, its script and voice written for you, every scene HTML drawn from the voice’s words and cut in Fil’s video editor. Any look, any shape, and no camera unless you want to be in it.

Install it

Claude Code:

curl -fsSL https://fil.design/skills/html-explainer-video.zip -o /tmp/html-explainer-video.zip && unzip -o /tmp/html-explainer-video.zip -d ~/.claude/skills

Codex:

curl -fsSL https://fil.design/skills/html-explainer-video.zip -o /tmp/html-explainer-video.zip && unzip -o /tmp/html-explainer-video.zip -d ~/.codex/skills

GitHub:

npx degit MengTo/Skills/agent-skills/media/html-explainer-video ~/.claude/skills/html-explainer-video

Or make one in Fil with its workflow: https://fil.design/workflows/html-explainer-video. Fil is invite-only for now: join the waitlist at https://fil.design/waitlist.

Or tell your agent:

Install the HTML Explainer Video skill from https://fil.design/skills/html-explainer-video: unzip https://fil.design/skills/html-explainer-video.zip into your skills folder (~/.claude/skills for Claude Code, ~/.codex/skills for Codex), then read its SKILL.md.

The skill’s folder: https://fil.design/skills/html-explainer-video.zip (zip), GitHub, and each file:

SKILL.md

HTML scenes · Fil's video editor over MCP · Playwright · ffmpeg. A scene engine without a framework is in scripts/explainer.js.

An explainer is a voice with pictures cut to it. This skill writes the voice, then draws every picture in HTML from one number: the film's seconds. Each thing on screen lands on the word that names it, because its time is that word's time (T.clock is when the voice says "clock"). It looks like motion design and it's a web page, so its look, its shape and its camera are settings, not rebuilds.

Boundary. Use html-demo for a live app window on a web page (no video file). Use html-reel to turn an existing post, video or page into a 9:16 reel in that source's look. Use website-to-motion-design for a short piece with no voice. Use this skill when the deliverable is a finished explainer film, about one minute, that explains something.

Provenance. Extracted from seven one-minute onboarding films for Fil, 31 October to 1 November 2026. Each had a hook, a benefit, a quick tutorial with numbered headings and an ask, with scenes rendered at 2× and 60 fps and assembled in Fil's video editor. Those were locked to one dark look, one shape (4:3) and a camera slot, and built on Fil's own demo components. Here all three are inputs and nothing depends on Fil's components. The film in demo/ is this skill's own explainer, made with it: one script, in four looks and four shapes, with the camera off or on, and no change to a scene. The rules below are what those films cost to learn.

The mechanism

Every frame is a pure function of one number, and every time is a word. A scene sets everything from t, the film's seconds. HTMLExplainer.times(WORDS) names each word of the voice (T.clock, T.clockEnd, a word said again T.look2). A renderer calls window.__frame(t) once a frame and screenshots; nothing reads a clock.

// film.js: a scene. No colour, no font, no pixel of layout from the shape.
const T = times(window.WORDS);
const step3 = {
  id: 'step3', from: T.three - 0.12, tone: 3,
  draw(t, $, f) {
    show($('.x-head'), t, T.three);            // when; the look says how
    show($('#code'), t, T.clock);              // lands on the word "clock"
    ring($('#last'), t, T.word);               // a thin line, on "word"
    $('#code').textContent = `T.clock = ${T.clock.toFixed(2)}`;
  },
};
film({ words: window.WORDS, end: T.end + 2.4, scenes: [hook, step3, end] });

Take that away and all of it breaks. A scene on CSS timelines or timers plays at its own pace, so a new voice means animating it again, and the cuts drift a few frames every time. A frame drawn from t is the same picture every run, so a re-render changes only what you changed.

The three inputs

None of these touches a scene. Read them from the person, or use the defaults.

inputhow it's setdefaultwhat it changes
Look<html data-look="…"> or ?look=, one block of --x- variables (references/looks.md)read from their site, else ask for a styletype, colour, corners, edges, where the headline sits, window chrome, picture treatment, captions, and how things move
Shapeshape: or ?shape=: 4:3, 16:9, 1:1, 9:16where it'll be seen; 4:3 if nobody saysthe stage (short side always 1080) and every region: --pic-x, --head-y…
Cameracamera: or ?camera=onoffoff: no slots, no kept corner, scenes fill the frame. On: references/camera.md

show(el, t, at, leave) is why a look can move differently without a change to a scene: the scene says when, and --x-motion (rise, fade, snap, wipe) says how. A look's block of variables can sit on any element too, which is how the film shows three looks side by side.

Workflow

Ask at most one question before starting, and only if the thing to explain is missing. Say the defaults you took.

  1. Write Explainer.md: what it is, the one idea someone should leave believing, who it's for, every fact the film may state with where it comes from, and the ask. Read the product's own site, docs or source for those facts. A film can only say what's on this list.
  2. Set the look (references/looks.md): scripts/read-look.mjs <their site> --name brand measures it into brand.css and brand.md; or they name a style and you write the block. Compare it with their page by eye. Collect their real logo and real pictures now, sized for where they'll be drawn.
  3. Write the script (references/format.md): hook, benefit, quick tutorial, try it. About 2.6 words a second, so 140 to 155 words a minute. Write for the ear. Under each line, say what the picture does and the word it lands on.
  4. Build on a free clock. scripts/words.py --draft script.txt --out words times the script from its letters and punctuation, for nothing. Scenes on it are timed by name, so the real voice replaces it without changing a scene.
  5. Build the scenes on scripts/explainer.js and explainer.css, one <section class="x-scene"> each, about 4 to 8 s long. The first frame is the cover. Only variables and regions, no fixed colour or size that belongs to one look or one shape. Look at stills as you go: scripts/render.mjs film.html --stills 0,3,8,16 --out stills. At least three rounds, in at least two looks: a scene that only works in one look isn't finished.
  6. Check. scripts/check-film.mjs film.html in every look, shape and camera setting you'll render: enlarged pictures, soft 3D, two headlines at once, words at the edge or under the camera, a frame that differs between runs.
  7. Show the price, then make the voice. In Fil, an audio node on eleven-v4 with max_credits: 0 gives the price. Get the person's OK, then run it. Captions with look: { max_words: 1 } give word times (about ⚡1 a minute); get_video with captions: "list", saved, goes through scripts/words.py --voice voice.mp3. Read the words against the script before going on: names and numbers above all.
  8. Place the sound. window.SFX lists the cues, and scripts/sfx.mjs film.html gives each its take, sync point and level (references/sound.md).
  9. Preview it. scripts/preview.mjs film.html --voice voice.mp3 --music bed.mp3 --sfx sfx.json --out preview.mp4: the whole film at 1×, 30 fps, with captions and sound at −14 LUFS, and a contact sheet. Judge it here: a change costs a minute.
  10. Render. scripts/render.mjs film.html --scene all --fps 60 --scale 2 --out final writes one MP4 per scene. Run it niced and in the background; it takes minutes per scene.
  11. Assemble in Fil over MCP (references/fil-editor.md): scenes in order, voice, captions in the look, music, sound effects, chapters.
  12. Export and verify the file, not the timeline. Then score it with blind judges and fix what they both name (references/checks.md).

With a camera, steps 7 and 11 change and the person records last: references/camera.md.

Rules, each with the failure it prevents

Numbers from the source films and this one

whatvalue
length57 to 60 s, about 2.6 words a second, 146 to 155 words
stageshort side 1080: 1440 × 1080, 1920 × 1080, 1080 × 1080, 1080 × 1920; rendered at 2×
frames60 fps for the edit; 30 fps at 1× for a draft
partshook 3 to 6 s; benefit 12 to 20 s; quick tutorial 22 to 30 s; try it 6 to 14 s
scenes10 to 12, about 4 to 8 s each
endthe last word's end plus about 2.4 s
headlines62 px on 4:3, 76 px on 16:9, 78 px on 9:16; two-tone: a lead-in and a statement
soundsabout 1 a second; 64 in this film's 59 s, 18 of them keys under typing
voice⚡7 for 146 words on ElevenLabs v4, in a stock voice
captions⚡1 for one minute
corner camera374 × 210, 40 px from the right and the bottom (4:3, 16:9)
loudness−14 LUFS

Verify

Files

Without Fil. The edit is Fil's, but the film doesn't have to be: scripts/preview.mjs makes a finished MP4 on your own machine from any voice file and its word times (words.py --json).