Evidence explainer (voice note → 1-minute vertical video with receipts)
Built on "How Malawians get Visa cards with no forex" (11 Nov 2026): a 4:15 Android voice note → a 60.4 s TikTok with 10 web pages as evidence, Bridge's own architecture diagram, 9 logos, 4 chings. Worked example in assets/examples/visa-cards/ (script + lay check, cut list, shoot jobs, full video.json, post copy, contact sheet).
voice note ─► transcribe + islands ─► SCRIPT + LAY CHECK (checkpoint) ─► cut voice (verified edges) ─► tempo + words
│
└► evidence: screenshots w/ target rects · logos · diagrams from docs
│
video.json timeline (scenes, zooms, stamps, glosses, chings, diagram steps)
│
sfx + quiet score + mix ─► stills w/ safe zones ─► render ─► verify
Setup
SK=~/.claude/skills/evidence-explainer
zsh $SK/scripts/new_explainer.sh "<audio file>" .context/<slug> # ~1-3 min; prints disk free
cd .context/<slug> # every script runs from here (W)
Needs ffmpeg, Python 3 + numpy + Pillow, Node 20+, Chrome (Playwright drives the installed Chrome), whisper.cpp + ggml-medium.en.bin in ~/.cache/whisper.cpp (scripts/setup_whisper.sh builds it; override with WHISPER_DIR). The scaffold runs npm i in remotion/, or clones an existing node_modules when EXPLAINER_NODE_MODULES points at one (APFS copy-on-write, ~0 bytes). Look = "dev mode" (src/brand.ts: dot grid, Space Mono, cyan/yellow/amber); handle/site come from video.json.
The stages (read the reference when you get there)
| # | Stage | Read | Tools |
|---|---|---|---|
| 1 | Script the beats from sent.txt, then run the lay-person check | references/01-script-and-lay-check.md | — |
| 2 | Cut the voice to ≤ 60 s on verified edges, tempo, subtitles | references/02-voice-cut.md | islands_labels.txt, dips.py, tx.sh, cut.py, voice.sh, words.py |
| 3 | Evidence: screenshots + target rects, logos, docs diagrams | references/03-evidence.md | shoot.mjs, logo_tools.py, logo.mjs, register_image.py |
| 4 | Timeline in remotion/src/video.json | references/04-video-json.md | engine src/Explainer.tsx |
| 5 | Sound: clicks, chings, quiet score, mix | references/05-sound.md | sfx_mix.py, score.py |
| 6 | Preview with TikTok safe zones, render, verify | references/06-render-verify.md | remotion/stills.mjs, sheet.py, verify.sh |
Quick path once the script is agreed:
python3 $SK/scripts/cut.py cut.json && zsh $SK/scripts/voice.sh 1.18 "Names, Brands, Jargon"
python3 $SK/scripts/words.py word_fixes.json
node $SK/scripts/shoot.mjs shoot_jobs.json shots && cp shots/*.png remotion/public/shots/ && cp shots/shots.json remotion/src/shots.json
python3 $SK/scripts/logo_tools.py sync # after fetching logos
# write remotion/src/video.json, then:
python3 $SK/scripts/sfx_mix.py path/to/music.mp3 # or `none`
(cd remotion && npx tsc -p . && node stills.mjs 45,300,...) && python3 $SK/scripts/sheet.py stills --zones
(cd remotion && npx remotion render src/index.ts Explainer ../out/<slug>.mp4 --codec=h264 --crf=18 --audio-codec=aac --audio-bitrate=192k)
zsh $SK/scripts/verify.sh out/<slug>.mp4
A full render of 60 s takes ~40 s; stills ~1 s each after the bundle.
House style (from the creator's review of the first video — keep it unless told otherwise)
- Full-screen B-roll. Screenshots fill the 1080×1920 frame (no browser card); the camera starts wide, then zooms onto the line that proves the point while a highlighter sweeps it. A slim
https://domainpill + yellow// evidence: …tag sits top-left. - Logos land with a camera click (white card, slight tilt, scale-down pop, white flash). Show more of them: every company named gets its logo once.
- "Ka-ching" on every successful transaction (account created, money received, wallet topped up, payment approved) with a green ✓ chip and ring.
- Architecture for lay people. One diagram (You → App → Infrastructure → Card), with logos in the nodes, built up step by step ("STEP 1 · SIGN UP"…), with labelled packets travelling between nodes. A provider's own developer diagram is shown only zoomed into its plain-English boxes, never whole.
- Ask yourself after writing the script: will this clarify or confuse a lay person who uses the product? Fix every "confuse" before building (gloss cards, simpler labels, no code styling). Put the check in the script file and in the summary.
- Subtitles anchored to the bottom: the box's bottom edge is fixed 400 px above the frame bottom (just over TikTok's username/caption block), 2-line pages grow upward, padded off the right action rail.
- Hook first (big dot-matrix word + the viewer's question over the first evidence, blurred), follow CTA last (logo chain recap, FOLLOW, handle, button, site).
- Music is a quiet bed (score.py BASE −26 LUFS): a loud dramatic score tested as "way too high and annoying".
Checkpoints (stop and ask, with a recommendation)
- Script + lay check before cutting anything: the beat table (what he says → what's on screen) and the confuse/clarify table.
- Claims you can't verify (e.g. "app X uses provider Y"): keep them in his words, word the on-screen labels as "e.g." / "one example", and flag them.
- Before rendering: stills of every new element with
--zones. - Before publishing: logo licences (CC BY/BY-SA need a credit line), hedged claims ("most likely" stays visible), names Whisper misheard (captions use the right spelling even if he said it oddly). Upload only when asked.
Working principles
- Evidence over assertion: every factual beat gets a page that says it, captured live, zoomed to the line. Prefer primary sources (company newsroom, official docs, the regulator/central bank, the app's store page) over blogs. Note what a page does NOT say (Bridge's country table = who can be onboarded, not card availability) and label accordingly.
- Cut on verified edges only: energy islands + bisected dips (
tx.sh), never Whisper word times (they drift up to seconds on phone audio). Re-transcribe the final cut and the render. - Glosses are short and concrete: "stablecoin = a digital dollar, 1 USDC ≈ $1", "KYC = the ID + selfie check you did when signing up", "API = a plug that lets apps use X".
- Zoom limits: a 1200 px mobile screenshot fills the frame at zoom 1.0 (it is already cropped ~36 px a side); paragraphs tolerate ≤ 1.3, short targets (a code line, a table row) 1.8–2.0. Check that the highlighted words and any key column (e.g. currency) stay inside the frame.
- Verify, then report: durations (video vs audio), −14 LUFS / peak ≤ −1, full transcript of the render, chings ≥ +5 dB over the voice, a contact sheet you looked at. Say what you chose by tag without listening (music).
Final summary format
Deliverable path + length; a contact sheet image; what's on screen, beat by beat (short); the lay-person check verdict; "check before posting" (unverified claims, licences, hedges, misheard names); housekeeping (working dir, disk, re-render cost, which file to edit).