Thumbnails and titles
Set your brand here
Edit the :root block at the top of both scripts/layout-fullbleed.html and scripts/layout-panel.html:
| setting | CSS variable | default |
|---|---|---|
| accent color | --brand-accent (+ --brand-accent-rgb as r,g,b) | #4a90e2 |
| light text color | --brand-light | #f2f2f2 |
| dark ink color (stroke, panel background) | --brand-ink | #0d131a |
| display font (big text) | --font-display | 'Anton','Bebas Neue',Impact,sans-serif |
| body font (small text) | --font-body | 'Inter',sans-serif |
The display font must be installed locally, since rendering runs in headless Chrome from file://. Anton and Bebas Neue are free on Google Fonts.
Also set your grading LUT in scripts/frames.sh (LUT_DEFAULT), or pass LUT=/path/to.cube per run.
Style defaults (change to taste)
- Never put anything over the face. No scrim gradient across the subject. Either a hard-edged panel with the face fully clear, or full-bleed with text in empty space.
- Pull frames from the RAW 4K, not an export. 1080p export frames look soft.
- Grade the frame first. Log footage (S-Log3 etc.) is flat and grey ungraded. Bake the LUT in with
lut3d(seeframes.sh). Skip the LUT if the camera shoots a finished profile.
Rules that came from research
- Three to five words, and fewer is better. The thumbnail is not where the video gets explained.
- A face wins. Most breakout videos use one. Strong expression beats a neutral one.
- One dominant subject, two or three colours, high contrast.
- Judge it at ~210px. Most viewing decisions happen on a phone. If it doesn't work there, nothing else matters.
- Title and thumbnail should not repeat each other. Two halves of one idea. Keep titles short and specific (roughly 50-60 characters so they don't truncate).
- A/B testing in YouTube Studio beats arguing about it, so give the user 2-3 real options.
Which layout
Full-bleed wins at phone size and is the default. Side by side at 210px, the face reads about twice as large as in the panel version, and panel sublines disappear entirely.
layout-fullbleed.html: graded frame edge to edge, 1-3 words in the display font with a heavy ink stroke, placed in empty space (wall, door) and never on the face. Presetsstab,stat,bottom,band(a solid accent band across the bottom). Legacy example variantse,f,g,h.layout-panel.html: subject in a clean right-hand square panel, text on a dark left half. Use when the idea needs a diagram (the dot grid) or two lines of text. Example variantsa-d.
Run it
# 1. graded frames from the raw, at expressive moments (use the transcript to find them)
bash <skill>/scripts/frames.sh "<YOUR_FOOTAGE_DRIVE>/<folder>/C0001.MP4" "<work>" 178 310 459 503
# 2. look at them before choosing - a contact sheet beats guessing
ffmpeg -i hi-*.jpg -filter_complex hstack=... contact.jpg
# 3. render variants + the phone-size proof sheet
WORK=<work> OUT=<out> node <skill>/scripts/render.mjs variants.json
variants.json:
[{"id":"E-no-time","layout":"fullbleed","v":"e","img":"full-C0001-503.jpg"},
{"id":"S-custom","layout":"fullbleed","img":"full-C0001-310.jpg",
"data":{"preset":"stab","head":"TOO BUSY?","kicker":"TRY THIS"}},
{"id":"B-3x","layout":"panel","v":"b","img":"cut-C0001-97.jpg"}]
Full-bleed text can be passed per variant as data (preset, head, kicker, side, size), or added as a new legacy v block in the layout HTML. Panel text lives in the v blocks of layout-panel.html; add a new variant by adding a block, keeping it to 3 words.
Needs puppeteer-core: reuse ../video-overlays/scripts/node_modules or npm i in the scripts dir. render.mjs launches /Applications/Google Chrome.app/...; change the path on other systems.
Picking the frame
Look for raised eyebrows, an open hand, mid-word mouth. Use the transcript to find a moment with energy, then pull a frame a second in. Dead-eyed frames kill it. The crops in frames.sh assume a 4K (3840x2160) source with the subject at about 46% of frame width; adjust the crop= offsets if your framing differs.
Output
Render at 1920x1080 (YouTube downsamples cleanly), keep under 2MB.
Related
paper-edit,video-overlays: the rest of the video pipeline