---
name: term-tension
description: Make a short editable film where competing terms gather around a person and persist when the central scene becomes a photograph.
version: 1.0.2
---

# Term Tension

Build a 7.2-second, 1920×1080, 30 fps composition with HTML, CSS, GSAP and HyperFrames. This is a parameterized renderer: the author supplies a topic, compact labels and properly licensed media. It does not generate people, images or narration.

## Prepare a brief

Create a JSON file with these fields:

- `heading`: up to 40 characters, describing the subject.
- `tokens`: one to six distinct short demands, each no more than 23 characters. Keep their meaning specific to the brief.
- `caption`: up to 32 characters.
- `palette`: `linen`, `estuary`, `plum` or `chalk`.
- `take`: path to a continuous video at least 7.2 seconds long.
- `photo`: path to a real JPG, PNG or WebP photograph that changes the meaning of the same labels.
- `mediaRights`: a nonempty licensing/permission note. This declaration is not a legal verification.
- `framing`: optional `{ "zoom": 1, "x": 0, "y": 0 }`. Zoom may range from 1 to 2; offsets must cover the canvas without gaps.
- `photoFocus`: optional crop focus, such as `"50% 50%"`.

Paths resolve relative to the brief. Preserve a visible person in the continuous take. Choose the photograph deliberately; a decorative object is not a substitute for a person when the story is about human pressure. The generator checks duration but the author must check continuity, framing, natural movement and rights. No raw media is included in this package.

## Generate and render

Requires Node.js 22+, npm, FFmpeg/ffprobe and the browser requirements of HyperFrames. Run ordinary `npm ci` in this package. Dependency lifecycle policy and browser provisioning depend on your host; read installation diagnostics.

```
node scripts/compose.mjs /absolute/brief.json /absolute/project
./node_modules/.bin/hyperframes lint /absolute/project
./node_modules/.bin/hyperframes validate /absolute/project
./node_modules/.bin/hyperframes inspect /absolute/project
node scripts/render.mjs /absolute/project /absolute/project/output.mp4
```

Each render uses one worker. Render projects sequentially on shared hosts. The generated directory contains editable HTML, local GSAP, local Noto Sans SC fonts, media and a brief record. Runtime playback needs no external font service. The generic ZIP excludes finished films and example media. Redistributed dependency notices remain in `assets`.

## Direct the sequence

Labels enter alternately on both sides from 0.32 seconds, 0.49 seconds apart. At 3.55 seconds the background switches; at 3.58 seconds the photograph rises into place. Settled labels never relocate during this change. The image is grayscale and slightly angled; the final quiet hold allows reading. Keep a central area clear enough for the face and meaningful gestures.

The video is muted and the output is intentionally silent. There is no music generation or editable audio mix. Supply audio in a separate authorized editing workflow if required; do not call this a mixed production.

## Validate the delivered result

Check actual encoded frames at label entrances and around the scene cut. Read every token at native size. Exercise forward/backward seeking, including zero and the final frame. Check text bounds, CJK glyphs and the loaded font. Inspect both a light and a dark palette and at least two substantially different topics. Record 1× playback frame totals and dropped frames without replaying to improve the count. A successful render does not establish visual or user acceptance.
