Skip to content

feat(render): add html films with a layout check - #21

Merged
umiyosh merged 1 commit into
masterfrom
feat/html-film
Oct 24, 2026
Merged

umiyosh merged 1 commit into
masterfrom
feat/html-film

Conversation

@umiyosh

@umiyosh umiyosh commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds a second kind of film, html, so the skill can make videos without Claude Motion, and a layout check that catches overlapping or hidden elements before a video is rendered.

This takes the route recommended in the Phase 0 spike (#17): our own minimal player rendered by render.ts, which keeps the network block and the Chromium sandbox. Motion films and their path are unchanged; the skill uses Motion when the Motion Artifact type is available and the html path otherwise.

Closes #18. Part of #19 (layout check and authoring guide; contrast and text-size checks are not in this PR). Part of #16.

Why the layout check

A video made in the spike had a ✕ mark half hidden under the condition box, a chip straddling a card's border, and a box sticking out of its panel. Nothing in the old flow caught them: they came from hand-computed coordinates and from relying on HTML order for stacking. Run on that film, the new check reports all three, plus four more that were missed in review.

Changes

  • motion-render kit <work>: sets up <work>/film with the player (kit/player.js), a base stylesheet with role-based stacking layers (kit/base.css), GSAP, Noto Sans JP (400/700, woff2, font-display: block) and the scene times from timing.json. The page fails to load with a pointer to kit when the font is missing.
  • Player API: film.build(fn) (runs after fonts load, so measurements are right), film.at / film.end (scene-relative times), film.spot(el, target) (GSAP x/y that center an element on a target, so chips are not placed by hand).
  • motion-render check <filmDir>: samples the film every 0.2s and reports elements that partly overlap, stick out of their parent, are cut by the frame, or are hidden under another solid element. Only still elements count, so a chip passing over a card is not reported. data-layout-ok marks intended overlaps (chart reference lines, strikethroughs). stills runs the check and prints issues; build stops on them.
  • The page-side snapshot (scripts/snapshot.js) is injected into the untrusted film page; its output is validated in Node (parseBoxes).
  • build rewrites kit/timing.js from timing.json, so a film always follows the current narration.
  • SKILL.md: step 3 splits into Motion (3A) and html (3B); references/html-film.md holds the authoring rules (marks inside their target, stacking by role, flex/grid inside cards, chips stop inside a card or in free space), motion, typography, determinism and sound-effect timing.
  • CLI dispatch moved to a command table; this repays the one baseline lint entry (main complexity).
  • New dependencies, pinned: @fontsource/noto-sans-jp@5.2.8 (OFL), gsap@3.13.0 (GSAP standard no-charge license).

Test plan

  • make lint, make typecheck, Prettier check on changed files
  • vitest run --coverage: 89 tests pass, 95% lines (kit.ts 100%, layout.ts 100%)
  • New tests: layout rules on synthetic samples; an html fixture film that reports the ✕ overlap and passes once the ✕ sits in its chip; scene times from timing.json; the same frame twice is identical; missing font fails with a pointer to kit; film.spot centers a chip on its target; kit and check as CLI commands
  • Quality gate: no new violations, baseline emptied
  • End to end on an account without Motion: narrate → bgm → kit → index.html → check → stills → sfx → build produced a 57.3s 1920x1080 MP4 with narration, BGM and 10 sound effects; each effect's peak is within 0–5 dB of the narration and BGM at the same moment
  • Listen to the sound effects in the rebuilt video
  • CI on Ubuntu (render tests start Chromium with its sandbox on)

README (EN/JA) updates are left for #20.

@umiyosh
umiyosh merged commit ba954f7 into master Oct 24, 2026
1 check passed
@umiyosh
umiyosh deleted the feat/html-film branch October 24, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add an html film backend next to motion (#16 Phase 1)

1 participant