Pipeline Hub

format-reaction-duet

Reaction / duet split-screen ad, 20-60 s. Top half = a source panel (a real mom's public forum post rendered verbatim on a quote card (no source line, Fish 10-03), or our own clearly-original explainer card, or real footage we hold rights to); bottom half = a mom reacting, recognizing her own mornings, and turning it into vindication with the band as her answer.

Lane: cartoon-h3 narrator/dialogue for the reactor + ffmpeg vstack composite (manual today); photoreal reactor = ugc-omni (one avatar, native voice, gates G0-G4) · not built yet: 3 (see below) · source: /Users/ayden/.openclaw/workspace/skills/format-reaction-duet

SKILL.mdbeat-sheet.mdsources.mdEvals (6)Learnings (12)

Reaction duet — beat sheet, line rules, top-track cut list, composite

Runtime 20-60 s, target 35-45 s (≈120-150 words at ~3.4 wps). Percentages are of runtime; beats are pack-line ranges, never mid-sentence. The top panel switches only on line boundaries (times from lines.json).

# Beat % Lines Speaker Top panel Bottom panel (intent) Line rules
1 Source hook 0-15 1-3 MOM Q card 1 appears at 0.0 s Mom at the kitchen table, phone in hand, stops scrolling; then reads (eyes down, profile) Line 1 is the card text verbatim or "A mom posted this." + the card read in line 2. Symptom/stake named by line 2. No product.
2 Recognition 15-35 4-10 MOM Q card 1 held; one phrase highlighted (card 1b) Literal inserts of HER morning (third knock at the door, alarms going off on the nightstand, her watching the clock) "That's my house." class line, then her ritual: counts/times from VOC are allowed in video. Failed solutions generic (louder alarms, phone across the room, lights on): never brand names, never bed shakers.
3 Stake 35-50 11-14 MOM Q card 2: the escalation line (same post, or a second sourced post on the same stake) Close on her face LISTENING while she reads card 2 aloud off-screen; then the letter on the table (a shape with a red stamp) The cost lands on the mom (letter in her name, CPS warning, the fight). Mornings caused it. Stake-bank row cited.
4 Vindication turn 50-65 15-18 MOM (+CARD ≤2 lines) E card (sleeping brain under sound waves + one plain sentence) or Q card held Mom side-on, leaning toward the phone, OTS on the screen "You're not failing." to the poster. Fish's ruled root-cause line verbatim (sound doesn't reach a deep-sleeping brain). Science is the authority, not a person.
5 Answer 65-85 19-23 MOM R: real band footage, crop-filled Kid asleep, wrist resting on the duvet, band side-on, display dark; eyes open with small motion lines Mechanism lines: touch gets through; silent to everyone else; keeps going until he turns it off. Product named ONCE.
6 Payoff + CTA 85-100 24-26 MOM End card (optional, --end-card; off by default per Fish 10-06) spans both halves (last 2.5 s) Calm kitchen; kid already at the table Independence/calm on HER ("He's downstairs before me now." class). Last line: product name + 60-night trial.

Line rules (all beats)

Top-track cut list (the ## Top track section of the pack)

card kind first line last line source id text / file
1 Q 1 10 reddit <post id> (thread file) verbatim line
2 Q 11 14 reddit <post id> verbatim line
3 E 15 18 ours cards/e1.png + one sentence
4 R 19 23 own b-roll clip path + in-point
— end card (optional, --end-card; off by default per Fish 10-06) last 2.5 s — endcard.py end_card text

Each card holds from its first line's start (card 1 from 0.0) to the next card's first line start; the last card runs to the end of the reactor cut.

Composite (preferred since 10-06: Remotion DuetStack, SKILL §9; the manual ffmpeg below is the fallback; split.py NOT BUILT)

Cartoon reactor = 720×1280. Captions burn at ~57-62 % of the reactor frame (Remotion tiktok mode, moved up 10-06); crop=720:640:0:560 keeps rows 560-1200, so captions land at ~63-68 % of the composite, just below the seam; the bottom of that is inside Meta Reels' bottom 35 % UI band (safe box = y 14-65 %), so preview it, or use DuetStack (captions at ≤64 %). Photoreal reactor (ugc-omni, 1080×1920, captions at 0.68): use 1080×960 panels and crop=1080:960:0:840.

R=output/cartoon-h3/<slug>; T=$R/top; mkdir -p $T
# 1. quote card PNG (text via make_title, plain navy card), 720x640
python3 -c "
from pathlib import Path; from scripts.cartoon_h3.title import make_title
T=Path('$T'); make_title(['<verbatim quote>'], T/'q1.png', size=72, y_frac=0.45)"   # no credit line (Fish 10-03)
ffmpeg -v error -y -f lavfi -i color=c=0x2D3452:s=1080x1920 -i $T/q1.png \
  -filter_complex "[0][1]overlay=0:0,crop=1080:960:0:480,scale=720:640" -frames:v 1 $T/card1.png
# 2. segments (durations from $R/lines.json start times), same codec params so concat can copy
ffmpeg -v error -y -loop 1 -t <secs> -i $T/card1.png -vf "fps=30,format=yuv420p,setsar=1" -c:v libx264 -crf 18 $T/seg01.mp4
ffmpeg -v error -y -ss <in> -t <secs> -i "<real band clip>" -an \
  -vf "scale=720:640:force_original_aspect_ratio=increase,crop=720:640,fps=30,format=yuv420p,setsar=1" -c:v libx264 -crf 18 $T/seg04.mp4
printf "file 'seg01.mp4'\nfile 'seg02.mp4'\nfile 'seg03.mp4'\nfile 'seg04.mp4'\n" > $T/top.txt
ffmpeg -v error -y -f concat -safe 0 -i $T/top.txt -c copy $T/top.mp4
# 3. stack: top panel over the lower-middle of the reactor cut (assembled with --no-end-card), 4 px seam, reactor audio
ffmpeg -v error -y -i $T/top.mp4 -i $R/<slug>-final.mp4 -filter_complex \
  "[0:v]setpts=PTS-STARTPTS[t];[1:v]crop=720:640:0:560,setsar=1[b];[t][b]vstack=inputs=2,drawbox=x=0:y=638:w=720:h=4:color=white@0.9:t=fill,format=yuv420p[v]" \
  -map "[v]" -map 1:a -c:v libx264 -crf 18 -preset medium -c:a copy -shortest $R/split.mp4
# 4. end card (optional, `--end-card`; off by default per Fish 10-06) over both halves, then preflight
python3 -m scripts.cartoon_h3.endcard $R/split.mp4 $R/split-ec.mp4 --secs 2.5 --text "<end_card>"
python3 scripts/meta_preflight.py $R/split-ec.mp4

Structure example (ILLUSTRATIVE — shows the shape only, not shipping copy; real card lines come from the corpus via voc_check, real MOM lines through Fish's approval)

Top card 1 (Q, paraphrase placeholder of a stake-bank row): "" (no source line on the card; post id in the top track) 1. [MOM] "A mom posted this last night." 2. [MOM] "" 3. [MOM] "I had to put my coffee down." 4. [MOM] "That's my house. Every single school morning." … 15. [MOM] "Listen to me. You are not failing him." 16. [MOM] "Sound doesn't reach a deep-sleeping brain." … 24. [MOM] "Now he's downstairs before I am." 25. [MOM] "Dawn Band. Sixty nights to try it."