Subchapter 34.1
references/DESIGN_INDEX.mdMarkdown10 KBView on GitHub
This directory is a reference library for the talking-head-recut skill. Style, layout, and video frame are three orthogonal dimensions you can freely mix when designing a takeaway video.
Also bundled
Media Contract TestStyle × Layout × VideoFrame
(10) (4) (3) = 120 possible combinationsRead a reference file when you decide to use that dimension. Each file is a
self-contained HTML fragment that follows the talking-head-recut card-HTML contract
(scoped <style>, no <script>, no external URLs, animations only via
data-anim-*).
| key | file | what it does | best for |
|---|---|---|---|
split | layouts/split.html | 50/50 side-by-side (landscape) or top/bottom (portrait) | speaker + data equal weight |
stack | layouts/stack.html | video on top (~52%), card below | talking-head with summary card |
pip | layouts/pip.html | card fills canvas, video rounded PiP in corner | content-heavy moment, speaker secondary |
overlay | layouts/overlay.html | video full-bleed, glass card floats on bottom | cinematic / dramatic moments |
A layout is a two-part recipe: pick a card.zone value to put in
storyboard.json AND author a GSAP tween for #video-wrap to its
target rect in the composition’s <script>. Open the layout file’s
header for the recommended zone + the GSAP statement to paste.
(Earlier docs referenced a card.layout field — that field does NOT
exist in the real schema; the strict v3 schema only has card.zone.)
| key | file | character | accent | suggested font |
|---|---|---|---|---|
academic | styles/academic.html | warm paper · grid · serif · blue highlight | #2557a7 | serif |
editorial | styles/editorial.html | cream · coral block · big italic quote | #ff3a2d | Playfair-like serif |
minimal | styles/minimal.html | pure black/white · huge type · generous space | #000 | Inter |
spotlight | styles/spotlight.html | dark purple gradient · glow · dramatic | #a78bfa | sans |
geom | styles/geom.html | chartreuse + hot pink + black collision | #d4ff00 | Inter bold |
whiteboard | styles/whiteboard.html | paper · Caveat handwriting · sketched borders | #ff6b35 | Caveat |
audit | styles/audit.html | manila paper · justified serif · APPROVED stamp | #8b1d1d | serif |
terminal | styles/terminal.html | dark · monospace · ASCII border · prompt cursor | #4ade80 | mono |
swiss | styles/swiss.html | white · Helvetica · strict double rules · red accent | #e8190f | Helvetica/Inter |
xhs | styles/xhs.html | cream + hot pink · chips · #hashtags · ❤️💬 row | #ff2e63 | sans |
Choose by content tone, not by content type — academic works for finance
too if the tone is reflective; terminal works for non-tech if the tone is
“engineering rigor”.
| key | file | character | when to skip |
|---|---|---|---|
clean | frames/clean.html | no decoration; raw video | default; safest |
hairline | frames/hairline.html | double-stroke + four-corner viewfinder ticks | over overlay layout (clashes with full-bleed) |
polaroid | frames/polaroid.html | white photo frame + Caveat label + blue washi tape (no tilt) | over overlay layout; portrait PiP gets cramped |
A frame is a decorative div that sits next to the #video-wrap inside
the composition’s #stage. It is one-time HTML (not animated), but you can
fade it in/out across cards. See each frame file for the placement snippet
and the inline <style> it needs.
| video content | suggested combos |
|---|---|
| interview / dialogue | academic × stack, audit × split |
| product launch / announcement | editorial × overlay, geom × pip |
| data analysis / financial report | audit × split, swiss × stack, terminal × pip |
| social clip (9:16) | xhs × overlay, editorial × stack |
| technical tutorial | terminal × split, whiteboard × pip |
| emotional story / narration | spotlight × overlay, whiteboard × overlay |
| minimalist presentation | minimal × split, swiss × overlay |
These are starting points only. Look at the transcript, pick the tone, then pick the visual.
Every references/styles/*.html is sized for a 1920×1080 landscape
preview. When the final composition is portrait (1080×1920) — the
default for social / mobile — scale every visual size up so it reads on a
phone held close.
| token | landscape | portrait | scale |
|---|---|---|---|
| hero title (h1/h2) | 64–96px | 88–132px | ×1.35 |
| detail / body | 24–30px | 30–40px | ×1.30 |
| kicker / chip / meta | 14–18px | 18–22px | ×1.25 |
| primary number / stat | 48–60px | 64–88px | ×1.40 |
| horizontal padding | 40–64px | 24–36px | ÷1.5 |
portraitPx ≈ round(landscapePx × 1.3). Hero headlines can go ×1.4;
small meta stays at ×1.2. Padding shrinks in portrait since the card
is narrower.
For a card that must work in both, use a container query on the card
root: container-type: inline-size + font-size: clamp(64px, 8.5cqi, 132px).
Output canvas is independent of source video aspect. Three supported output ratios (selected by the user in Step 7.0 of SKILL.md):
| ratio | canvas | storyboard.layout | best for |
|---|---|---|---|
16:9 | 1920×1080 | "landscape" | YouTube / TV / desktop playback |
9:16 | 1080×1920 | "portrait" | TikTok / Reels / short-form mobile |
4:5 | 1080×1350 | "portrait" (schema treats 4:5 as portrait since h>w) | Instagram feed / WeChat Moments / works for both platforms |
The layout reference files in layouts/ document landscape and
portrait bounds only. For 4:5 derive bounds by proportional
vertical scaling from portrait: 4:5 y/h = round(portrait y/h × 0.703),
keep x/w identical. The composer doesn’t care about the named layout
value; it just uses composition.width × height.
videoBounds matches video aspect, no letterboxvideoBounds is a narrower box (e.g. pip becomes 248×440); empty side filled by card or backgroundvideoBounds becomes a wide-but-short band; stack and overlay work bestThe layout reference files show landscape values; for portrait you usually
flip the long axis: split becomes top/bottom, pip video bubble shrinks
~20%, overlay card slot widens to full width.
<script> — animations only via data-anim-* attributes<style> rules must be prefixed with .card[data-card-id="..."] —
the hyperframes sanitizer auto-scopes them, but write them already-scoped to
stay readableon*= inline handlersIf a reference uses a font you don’t have, fall back:
ui-serif, "Songti SC", "Times New Roman", serifui-sans-serif, system-ui, sans-serifui-monospace, "SF Mono", Menlo, monospace'Caveat', cursive