How General Translation films are made in Prototemplate's motion/ folder with HyperFrames.
pnpm skills:install gt-films --project <dir>Run it from a Prototemplate checkout. It links skills/gt-films into the project’s .claude/skills and .agents/skills; --copy vendors the folder instead, and --dry-run prints each step first.
General Translation (GT) makes its blog films, announcement films and translation-history films as HyperFrames compositions: HTML pages with one paused GSAP timeline that the HyperFrames CLI seeks and renders frame by frame to MP4. They are built in $PROTOTEMPLATE/motion/, one project per film, from one shared kit and one brief, motion/MOTION.md. This skill states Kevin's rules, each step of a film, and the checks a film passes before it reaches /motion.
Paths are relative to a Prototemplate checkout ($PROTOTEMPLATE), and paths that start with films/, kit/ or out/ sit inside motion/. references/ is this skill's folder of detail files; scripts/ holds two critic tools that need only Node and ffmpeg (node <this skill's folder>/scripts/<name>.mjs).
motion/: Kevin calls it the Videos session (2026-10-03: "the videos one should be making them, and this one is just for prototemplate work"). Other sessions read motion/, send film requests to it by name and run no film lane; a session without the local motion/ folder reviews against this skill and asks Kevin for the Videos session before building a film.motion/ is tracked through an allowlist in .gitignore (lane L6 of the system v2 plan, 2026-10-10): MOTION.md, the kit's code, the four kit examples (films/_smoke, _gem, _endcard-blue, _endcard-fire), the partnership globe's core in stills/, and the text sources of the films the site publishes (public/motion/published.json; a film in its offSite list is not published). Renders, audio, pictures, fonts, archives, unreleased films, concepts/, LINEUP.md and scratch stay local.node motion/kit/vendor.mjs writes the vendored libraries and the brand twins (files the repository already tracks in public/ and deck/), each checked by SHA-256. motion/kit/picture-sources.json lists every picture, logo, mark and font in the kit and the published films' folders, with its source, licence, hash and the code that loads it; fetch the ones without a twin by hand. Audio is never tracked.films/<slug>/script.json (and the final's transcript to script.stt.json), scrubs machine paths and account lines, runs the public scan on motion/ (PT_DENYLIST=<private list> node scripts/lint/public.mjs --root motion, because pnpm lint:public skips motion/), and stages the paths by name. Never run git add -A or git add .: on 2026-10-01 a broad add pushed 229 files of motion/ to main in b56e64c, and 8c8d6fb had to untrack them.motion/ diff before it is committed. Publishing a film to main is his call; explorations stay local until he reviews them.out/ only through kit/film.mjs (section 9); never edit another film, MOTION.md or LINEUP.md (the lead does); name your scratch folder after your slug; no git command that changes state. references/workflows.md has the full lane rules.These hold for every film (Kevin's notes, 2026-10-01 to 2026-10-10). A film's own SCRIPT, CONCEPT and NOTES files may add to them, never loosen them.
var(--font), and every film credits General Translation clearly.expo.out or power3.out, moves power2.inOut, processes none; no bounce, elastic or back overshoot. Staggers are 40 to 90 ms in reading direction.gt-motion holds the motion rules shared with the web.motion/MOTION.md whole before writing a frame. Its dated sections at the top override the older sections below them ("Dithered artifact pictures (2026-10-05)", "Round 7 direction", "Round 4 direction"); a film's own SCRIPT, CONCEPT and NOTES files record later rounds for that film; section 2 above overrides both where they differ.## The films, one entry per film headed ### <slug>: <title> (<length>), whose first paragraph is the public summary. scripts/build/motion.mjs parses both, so keep their form.references/look.md).references/look.md).BRIEF.md facts and hedges, section 2, public-domain or credited sources and deterministic rendering.| step | output | rule |
|---|---|---|
| Research package (series) | films/<slug>/BRIEF.md | five numbered sections; opens # Brief: <slug> |
| Three directors | motion/concepts/<slug>/<lens>/ | a one-sentence story, a script, key frames, a motion test of the signature move |
| Judge | films/<slug>/SCRIPT.md, CONCEPT.md | six criteria of 10; picks one; grafts only moves in the winner's grammar |
| Kevin reads the scripts | a sent page or file | the build waits for his answer |
| Storyboard | films/<slug>/STORYBOARD.md | beats on the 0.5 s grid, words verbatim, picture, motion and easing, transition out |
| Takes and bed | audio/ (or sound/) | one take per line through kit/audio/el.mjs; the bed edited to length |
| Build and check | index.html, lib/ | key actions timed to the takes' word times; check ends with 0 errors |
| Draft, critics, fixes | films/<slug>/renders/draft.mp4, CRITIQUE-<n>.md | a defect table with times and fixes; each fix checked on the frames that showed it |
| Delivery and records | out/<slug>.mp4 and its records, NOTES.md | kit/film.mjs final, section 9 |
references/workflows.md has the three shapes (treatments and judge; build, critique, fix and verify; script variations and editors) and the hard rules every lane prompt carries. references/pipeline.md has the package format, the briefs and Kevin's direction round by round.cd motion/films
npx -y hyperframes@0.8.106 init <slug> --example blank --non-interactive
cd <slug> && ln -sfn ../../kit kithyperframes skill before writing a composition. Load scripts, fonts and pictures through kit/... or the film's folder, never from a CDN: renders must not touch the network.var(--font) from kit/tokens.css. A literal font-family: 'Inter' makes the compiler fetch Inter from Google Fonts; the render log must never mention Google Fonts. A film's own faces live in its fonts/ folder under private family names.window.__timelines['<id>']. Every frame is a function of time: no Date.now, performance.now, unseeded Math.random (use GTDither.rng(seed)), requestAnimationFrame, timers or repeat: -1. Animate transforms, opacity and colors only.films/_smoke, _gem, _endcard-fire, _endcard-blue).| path | what it is |
|---|---|
kit/tokens.css, kit/fonts/ | Inter @font-face, --font, colors and the deck's type ladder |
kit/dither.js | window.GTDither: grids, tone from images, the Bayer draw, mix on one smoothstep, seeded rng |
kit/gemsmoke.js, kit/gem-shapes/ | window.GTGem, the seekable gem smoke shader; make.mjs makes glass shapes from marks |
kit/endcard/ | the shared end card, addEndCard(tl, { palette, title, url, start }); its README has every measurement |
kit/sheet.js | window.GTSheet, the deck's series frame (the blog films dropped it on 2026-10-04) |
kit/audio/el.mjs, voice.json | ElevenLabs narration, beds, music and transcription; the narrator's settings |
kit/sound/, kit/sound/tones/ | the canonical take recorder, ledger, click, chroma and loudness checks, the mix functions, and the Mandarin tone tools; published films keep their frozen copies |
kit/film.mjs, kit/film.schema.json | the film command and the schema of film.json (section 9) |
kit/contact-sheet.sh, kit/script-export.py | the contact sheet and the script as built (section 9) |
kit/review/ | the script review and narrator audition pages, filled from a JSON file |
kit/vendor.mjs, kit/picture-sources.json | the vendored libraries and twins; the picture and font manifest |
references/kit.md has the gem smoke, dither and end card rules; references/traps.md has the composition and render traps with their fixes.
el.mjs reads, and el.mjs alone reads it. Never read, print or copy that file, never pass a key on a command line or in a prompt, and log the purpose of every ElevenLabs call in the film's NOTES.md.--prev and --next, the request text exactly the script's except respellings. Never generate below speed 1.0, and never speed up or time-stretch a take: calm comes from the gaps. One take per line unless a take is wrong. Check every take, the bed and the final with el.mjs hear. A non-English take needs a native listener's sign-off before release.references/sound.md has the commands, the narrator's history, the mix recipes, model facts and the traps.BRIEF.md states, with titles, names and dates exactly as published. Hedges stay, spoken and on screen.gt, gt-next, npx gt translate) and never start a sentence.# from motion/
node kit/film.mjs status [slug] # finals, current drafts, last render pairs
node kit/film.mjs check <slug> # hyperframes check and film.json
node kit/film.mjs draft <slug> # 30 fps draft: films/<slug>/renders/draft.mp4
node kit/film.mjs final <slug> # renders A and B, master out/<slug>.mp4, records
node kit/film.mjs prune [--dry-run] # superseded drafts and renders to the archivefilms/<slug>/film.json (kit/film.schema.json; example films/_smoke/film.json) sets the kind, the render path (software for series films with large animated type, gpu for gem smoke), workers, the timeout, the poster and the records; a tracked one names voices, never IDs.motion/.render.lock (references/kit.md). Stop only processes you started, by PID; never pkill, killall or a pattern (2026-10-10).final compares A and B by framemd5 and decoded audio; when they differ it keeps both, takes the one matching the previous master and records PSNR and frame ranges in renders/final.compare.txt. It refuses a master that misses section 7's targets, is not faststart or has Google Fonts in a log.out/v<N>/: the previous final and its records, the previous draft and the A and B MP4s move to ~/gt/motion-archive/<date>/, listed in its INDEX.md.final writes: the poster; the contact sheet, PNG and WebP (two frames a second, 384 px tiles, eight to a row, 3 px white gaps, the grid Kevin asked to keep on 2026-10-06); the checking sheet; the script page from the reviewed table and the final's transcript (one el.mjs hear call, or the previous one when the audio is unchanged); the credits; a share copy over 50 MB; a KB film's web copy, captions and VideoObject. Add a dated round entry to NOTES.md.A critic watches the render frame by frame against MOTION.md's "How a film is judged", section 2, the brief, SCRIPT.md and CONCEPT.md, and reports every defect with its time and a fix (references/critic.md).
scripts/scan.mjs): no unplanned black frame, no single-frame flicker, the largest changes on the planned cuts.el.mjs hear against SCRIPT.md, then loudness, true peak and stream lengths (scripts/measure-render.mjs).lang and dir), safe areas (120 px, 160 px for titles), reading floors, holds and the count of headings and quotes./motion lists every roster film with its status, plays the published ones, and shows each series film's research package at /motion/<slug>.public/media/<name>-film.mp4 (faststart) with its poster, the entry in public/motion/published.json, node scripts/build/motion.mjs --pin <slug>, then pnpm build:motion. A film Kevin takes off the site goes into offSite and stays on the roster.build:motion copies the records only from the out/ folder whose render has the pinned streams, so keep each cut's records beside its render.build:motion reads MOTION.md, each BRIEF.md, out/ and each draft (films/<slug>/renders/draft.mp4, else out/_draft-<slug>.mp4), and writes src/lib/motion.ts and public/motion/. Run it where the full motion/ folder exists: a clone without out/ drops the display-only local paths and the in-review entries, and lists an unreleased film whose folder is only local as planned.Promos, product demo videos, README and launch GIFs, launch captures and vendor briefs are made outside motion/ and follow references/short-media.md: a promo opens on the result and cuts on the beat with no narration, a demo starts inside the product, a GIF runs the real CLI, and a vendor brief uses dummy brands. Kevin directs media.
var(--font); the render log has no Google Fonts line; nothing loads from a CDN.hyperframes check ends with 0 errors; NOTES.md names every kept warning.el.mjs hear; non-English takes have a native listener's sign-off.scan.mjs shows no unplanned black frame or flicker; thin lines read at 640 x 360.kit/film.mjs final made the final and its records (the earlier one is in the archive's INDEX.md); NOTES.md is written.motion/ paths are staged, by name, after the public scan; the Prototemplate session knows about a re-render of a published film.Kevin's wiki: hyperframes (the entry point), hyperframes-core, hyperframes-animation, hyperframes-keyframes, hyperframes-cli, hyperframes-audio, elevenlabs-sfx (its config path). GT skills: gt-motion, gt-voice, gt-dither, gt-brand, gt-diagrams, gt-graphics (the partnership globes), prototemplate (the /motion page).
Dated provenance for every rule is in references/sources.md: MOTION.md and its dated sections, the films' NOTES, SCRIPT, CONCEPT and CREDITS files, Kevin's notes from 2026-10-01 to 2026-10-10 and the memory notes that recorded them.
The folder skills/gt-films as agents fetch it. Each file opens raw.
SKILL.mdreferences/critic.mdreferences/kit.mdreferences/look.mdreferences/pipeline.mdreferences/short-media.mdreferences/sound.mdreferences/sources.mdreferences/traps.mdreferences/workflows.mdscripts/measure-render.mjsscripts/scan.mjs