---
name: code-based-video
description: "Use when creating educational videos with HyperFrames."
version: 2.0.0
tags: [video, hyperframes, remotion, motion-canvas, programmatic, rendering, education, reels]
metadata:
  hermes:
    tags: [video, hyperframes, education, reels, motion-graphics]
    related_skills: [multi-pov, fable5-skill-architecture, media-file-delivery]
---

# Code-Based Video Creation

## Identity

Agent that creates branded educational short-form videos using HyperFrames — HTML+GSAP compositions rendered to MP4 via headless Chrome + FFmpeg. Specializes in Instagram Reels (1080×1920, 9:16) but adapts to any format.

## Core Principle

Brand system first, composition second, animation third. Every video starts from a `brand.json` config that defines colors, fonts, logo, and accent — the HTML composition is generated FROM that config, not hand-picked each time.

User has explicitly flagged brand consistency (fonts, colors, logo) as a priority concern — treat it as a hard requirement, not a nice-to-have.

## When to Use

- Creating educational/explainer videos for Instagram Reels, TikTok, or YouTube Shorts
- Building video templates that need to scale across multiple niches
- Rendering branded motion graphics programmatically
- Batch-generating videos from data feeds

**Don't use for:** AI video generation (Veo, Sora, Runway) — this is code-based, not generative. For live-action editing use CapCut/Premiere. For math animations use the `manim-video` skill.

## Tool Selection

| Tool | Stack | License | Best For |
|------|-------|---------|----------|
| **HyperFrames** | HTML/CSS/JS + GSAP | Apache 2.0 (free) | Agent-authored videos, mixed media, social cuts |
| **Remotion** | React/TypeScript | Free ≤3 ppl, paid above | Branded explainers, UI demos, batch pipelines |
| **Motion Canvas** | TypeScript generators | MIT (free) | Vector animations, voice-over sync, real-time editor |

**Default: HyperFrames.** Token-efficient (single HTML, no build step), agent-native, Apache 2.0, streaming encode by default. See `references/tool-comparison.md` for full analysis.

## Pipeline Overview

```
brand.json → composition (index.html) → lint → check → render → deliver
```

Each phase has a completion gate. Do not skip phases.

## Phase 1: Brand Setup

Load or create a `brand.json` for the target niche. This file drives ALL visual decisions. Never hardcode colors or fonts directly in compositions.

### brand.json Schema

```json
{
  "niche": "tarot",
  "fonts": {
    "display": { "family": "Cinzel", "weights": [600, 700], "source": "google" },
    "body": { "family": "Inter", "weights": [400, 600], "source": "google" }
  },
  "colors": {
    "bg_primary": "#0a0a0f",
    "bg_gradient": ["#1a0a2e", "#16213e"],
    "accent": "#e94560",
    "accent_secondary": "#f5f5dc",
    "text_primary": "#ffffff",
    "text_secondary": "#a0a0b0"
  },
  "logo": {
    "path": "assets/logo-tarot.png",
    "position": "top-right",
    "width": 80,
    "opacity": 0.9
  },
  "spacing_scale": [4, 8, 12, 16, 24, 32, 48, 64]
}
```

**Gate:** brand.json exists and validates (all required keys present, hex colors valid, font families reachable on Google Fonts).

### Font Pairing Rules

- **Display font**: For hooks, headers, big numbers. Gives niche personality.
- **Body font**: For descriptions, step text, captions. Must be highly legible on mobile.
- Never use a single font for everything. Generic defaults (Inter alone, Roboto alone) signal amateur.
- Pre-defined niche pairings live in `references/niche-brand-systems.md`.

## Phase 2: Composition Authoring

Write the `index.html` composition. Follow HyperFrames structural rules — the linter enforces them.

### Structural Rules (Boundaries)

1. **Single root** `<div>` with `data-composition-id`, `data-width`, `data-height`, `data-duration`, `data-fps`. All numeric, all required.
2. **Clips** inside root: `class="clip"` + `data-start` + `data-duration` + `data-track-index`.
3. **GSAP timeline** must be `{ paused: true }` and registered as `window.__timelines["<composition-id>"]`. Mismatched ID = still frame, no error.
4. **Timeline positions are absolute seconds** across the whole composition, not per-clip relative.
5. **No build step.** Plain HTML + inline CSS + GSAP from CDN. No React, no bundlers.
6. Include GSAP: `<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>`

Example composition in `templates/educational-reel.html`.

### Content Structure

Every educational Reel follows: Hook → Content → CTA.

| Section | Duration | Purpose | Element |
|---------|----------|---------|---------|
| Hook | 3-5s | Scroll-stopping claim | Bold text, pattern-interrupt copy |
| Content | 8-30s | Deliver value | Steps, list, diagram, data points |
| CTA | 3-5s | Drive action | Save prompt, follow, specific next step |

### Instagram Reels Optimization (Mandatory)

These determine whether the video performs — not optional polish:

1. **Captions/subtitles**: Burn text captions into the video. 70%+ of Reels are watched on mute.
2. **Safe zones**: Keep critical content within center 80% width (max-width: 860px in 1080px frame). Avoid bottom 220px (IG caption/username area) and right 120px (engagement buttons).
3. **Logo/watermark**: Persistent brand mark in safe zone (top-right or bottom-left).
4. **Progress bar**: Thin bar at top showing elapsed/remaining. Reduces abandonment.
5. **Save-worthy element**: Include a checklist, framework, or summary that makes viewers want to save.
6. **Hook within 0.5s**: First frame must show something visually arresting. No slow fade-ins.
7. **Text density**: Max 10-15 words per screen. Display each text block for ≥1.5s per 10 words.
8. **CTA specificity**: "Save this for later" > "Follow for more." Specific action > vague handle.

### Hook Copy Patterns (Anti-Cliché)

Replace "Did you know?" with pattern interrupts:
- Contrarian: "Everything you know about X is wrong."
- Stakes: "This one mistake costs you $X over 30 years."
- Curiosity gap: "The top 1% do X differently. Here's how."
- Data shock: "90% of people fail at X. Avoid these 3 things."

**Gate:** Composition written. Lint passes (`npx hyperframes lint` → 0 errors).

## Phase 3: Verify

```bash
TMPDIR=/root/tmp npx hyperframes check
```

Validates runtime, layout, motion, and WCAG contrast. Fix all errors before proceeding.

**Gate:** Check passes (0 errors). Contrast issues fixed by adjusting colors, not by ignoring.

## Phase 4: Render

```bash
TMPDIR=/root/tmp npx hyperframes render --output /root/renders/<niche>-<topic>-v1.mp4 --quality standard
```

**Quality rules:**
- `draft`: Development and iteration only. Never publish.
- `standard`: Minimum for final/published video.
- `high`: For hero/flagship content.

After render, run cleanup:

```bash
bash /root/hyperframes-projects/cleanup.sh
```

**Gate:** MP4 exists, correct resolution (verify with ffprobe), file delivered via MEDIA: tag (see media-file-delivery skill for container→host path mapping).

## Rules

- **Brand.json is the source of truth.** Never hardcode colors/fonts in compositions.
- **Standard quality minimum for published content.** Draft is for dev only.
- **Captions are not optional.** A Reel without captions is dead on Instagram.
- **`TMPDIR=/root/tmp` must be set** before lint/check/render. Default `/tmp` is tmpfs (512MB) and will fail.
- **Verify with real output.** Do not claim success without checking the rendered MP4.

## Epistemology

- **Verified**: HyperFrames structural rules (learned from lint errors, confirmed in docs).
- **Verified**: Instagram optimization rules (from platform data, Multi-POV analysis Aug 2026).
- **Inferred**: Font pairing recommendations (design principles, not A/B tested).
- **Uncertain**: Optimal render settings for Instagram's transcode pipeline.

## Formatting

- Prose for explanations. Tables for structured comparisons.
- No filler. State what to do, why, and how to verify.
- Caveman mode: applies unless quality-critical render — then auto-clarity break.
- **User preference:** Provide concise, action-oriented summaries with bullet points instead of paragraphs when delivering results. Lead with outcomes first.
- **User preference:** Provide concise, action-oriented summaries with bullet points instead of paragraphs when delivering results. Lead with outcomes first.

## Pitfalls

| Pitfall | Symptom | Fix |
|---------|---------|-----|
| Timeline ID mismatch | Still frame, no motion | `window.__timelines["<id>"]` must match `data-composition-id` |
| Multiple timelines per clip | Lint: timeline_id_mismatch | ONE timeline per root, animations at absolute seconds |
| `/tmp` disk full | Render fails: "Low disk space" | Set `TMPDIR=/root/tmp` before every command |
| Node version <22 | Init fails: "requires Node >= 22" | Run `n 22` to switch Node version |
| GSAP not loaded | Unstyled/stuck composition | Include GSAP CDN script in `<head>` |
| Contrast check failure | WCAG errors on muted text | Lighten colors — HyperFrames suggests the compliant value |
| Content behind IG UI | Text covered by engagement buttons | Reduce max-width to 860px, add bottom padding 220px |
| Low-memory mode | Only 1 worker, slower renders | Expected (5GB cgroup). Streaming encode compensates. |
| chrome-headless-shell on ARM Linux | `Exec format error`; puppeteer `linux_arm` fetches mislabeled x86-64 | Stable channel is x64-only, but **Dev channel ships linux-arm64** (153.0.8009.0+, Aug 2026; check googlechromelabs availability page). Real gain measured: ~10% (newer engine). NOTE: the beginFrame "fast path" is DEAD in Chromium 147+ — CDP command removed upstream; everything renders screenshot-mode ("visually identical, slightly slower" per hyperframes#294). Don't chase it. |
| Stale HYPERFRAMES_BROWSER_PATH | All renders fail with exec/format errors | `unset HYPERFRAMES_BROWSER_PATH` — terminal env persists between calls in this session. |

## References

- `references/tool-comparison.md` — HyperFrames vs Remotion vs Motion Canvas vs MotionForge: features, license, token efficiency, Instagram adoption.
- `references/niche-brand-systems.md` — Pre-defined brand configs per niche: tarot, trading, marketing, general education. Colors, font pairings, accent colors.
- `references/hyperframes-rendering.md` — Rendering pipeline internals, performance tuning, batch patterns, disk management strategy.
- `templates/educational-reel.html` — Ready-to-modify vertical Reel template with Hook→Content→CTA structure.

## Related Skills

- **manim-video** — For Python-based math/algorithm/equation animations.
- **short-form-video-scripter** — For writing the script/copy before creating the visual video.
- **media-file-delivery** — For delivering rendered MP4s as chat attachments.