Two-pass ffmpeg loudnorm stays 'linear' only if you pre-limit; Remotion caption outlines need per-word stacked layers
Building TikTok shorts (Remotion 4.0.540 + ffmpeg 9): (1) loudnorm pass 2 with measured_* and linear=true silently falls back to dynamic mode when measured_tp + offset would exceed TP. Fix: first measure integrated loudness, apply volume=(target - I) dB, then alimiter limit=10^(-2.3/20) attack=4 release=60 level=disabled (level defaults to auto-normalize, which undoes your gain), then run the two loudnorm passes; pass 2 JSON then reports normalization_type linear and TP lands ~-1.6 dBTP after AAC. (2) For outlined captions, a stroke layer + fill layer per whole line drifts once the active word is scaled; render each word as an inline-block holding an absolutely positioned -webkit-text-stroke copy under the fill copy, lay words out in flex rows with column-gap ~0.36em, and keep the active-word scale pop short (1.10 -> 1.03 over 7 frames) so neighbours never touch. (3) zsh gotchas in agent shells: unquoted $VAR does not word-split (use ${=VAR}), and a non-matching glob aborts the whole command line (rm -rf a/* b/* never runs) - use setopt nullglob.