---
name: dubup-battle
description: Écrit le prompt Seedance 2.5 d'une scène du mode Dub Battle — 12 à 18 s, ping-pong acteur IA → doubleur → acteur IA — génère toutes les voix en anglais, garde la VO et les bruitages dans le clip servi et ne retire que la réplique du doubleur, puis rédige le brouillon de SceneManifest à un seul rôle. Use when on prépare une scène Dub Battle, on parle d'une scène à une seule réplique à doubler, ou on veut un clip court où les acteurs IA gardent leur voix.
---

# dubup-battle

Produit une scène du mode **Dub Battle** : un clip de 12 à 18 s où des acteurs IA parlent avec leur
propre voix, un seul personnage a la bouche vide, et chaque joueur y met la réplique qu'il veut.

Ce skill est le petit frère de `dubup-video`. Il **hérite** de tout ce que `dubup-video` dit sur
le jeu, l'ouverture, l'écriture des émotions, le registre, Higgsfield et le profil du catalogue —
ces sections ne sont pas recopiées ici, elles s'appliquent telles quelles. Ce fichier ne décrit
que ce que le mode Dub Battle change. Lire `dubup-video` d'abord si ce n'est pas déjà fait.

## Le mode, tel que Benjamin l'a posé le 2026-09-18

- **2 à 6 joueurs**, la même scène pour tous, chacun enregistre de son côté.
- La scène montre **un ou plusieurs acteurs IA qui parlent, avec leur voix** ; **un seul
  personnage à doubler**, choisi à la conception ; **une seule réplique** ; puis **la réaction
  des acteurs IA**, avec leur voix.
- **Ping-pong, dans cet ordre, toujours : IA → doubleur → IA.** Un acteur IA ouvre, le doubleur
  répond, les acteurs IA réagissent. La réplique ne peut ni ouvrir ni fermer la scène.
- **Le joueur n'a pas de texte.** Il regarde **toute la scène**, réaction comprise, puis enregistre
  la réplique qui, selon lui, la justifie. La réaction est la cible ; le texte est à lui. Le
  manifeste ne porte donc **pas** d'`originalLine` affichable (voir étape 6).
- **Du rythme.** Quand tous les joueurs ont validé : compte à rebours « attention, ça commence
  dans 5, 4, 3, 2, 1 », puis **tout le monde découvre la scène en même temps, jusqu'au bout**.
  Ensuite **30 secondes, pas une de plus**, pour enregistrer sa prise. Puis la révélation.
- Les prises sont **révélées une à une, anonymement**, à tous ; chacun **vote** pour celle
  qu'il préfère, un vote à la fois (voter pour une prise suivante annule le précédent), et peut
  revoir une prise avant de se décider.

Ce que le skill produit : le prompt, le clip servi, le brouillon de manifeste. **Le vote, la
révélation, la partie à 2–6 : c'est l'app**, pas ce skill. Le schéma ne connaît pas encore le
mode Dub Battle ; le brouillon porte `"mode": "battle"` en tête pour que ce soit dit, et `zod` l'ignore
tant que le champ n'existe pas dans `scene.ts` — l'ajouter est l'affaire de la conversation qui
fera le mode côté app.

## Ce qui change par rapport à `dubup-video`

| | `dubup-video` | `dubup-battle` |
|---|---|---|
| Durée | 30 s (deux générations au-delà) | **12 à 18 s**, une génération |
| Rôles | 1 à 6, tous doublés | **1 seul**, les autres sont des acteurs IA |
| Voix anglaises dans le clip servi | **aucune** : toutes retirées | **toutes gardées**, sauf celle du doubleur |
| Ce que Demucs touche | tout le clip | **une seule fenêtre** ; hors de la fenêtre, le mix Seedance est servi tel quel |
| Silence critique | sous chaque réplique | sous **la** réplique, et elle seule |
| Bruitage sous une réplique IA | interdit | **autorisé** : cette voix n'est pas séparée, le mix reste intact |
| Niveau du lit | −31,6 LUFS, 13 dB sous les voix | **les voix IA à −18 LUFS**, le niveau des joueurs (`voiceTargetLufs`) |
| `originalLine` | guide affiché | **rien d'affiché** : le joueur invente |
| Enveloppe, bouche | mesurées, servies au joueur | mesurées de la même façon — sur la seule fenêtre |

**Pourquoi seule la réplique est retirée, et pourquoi c'est plus simple.** Demucs sépare les voix
du fond, il ne sépare pas un locuteur d'un autre. Si l'on ne veut vider qu'une bouche, la
réplique doit être **seule dans sa fenêtre** : personne d'autre ne parle, aucun bruit franc,
aucun geste sonore. Dans cette fenêtre on sert le stem sans voix ; partout ailleurs on sert le
mix d'origine, intact, avec les voix et les bruitages que Seedance a posés. Le fond ne se
dégrade donc qu'à un seul endroit, et cet endroit est sous la voix du joueur.

**Pourquoi l'anglais reste.** C'est ce que Seedance synchronise le mieux, et une VO anglaise ne
souffle jamais la réponse : le joueur n'a rien à recopier, il invente. Une VO française serait
à regénérer.

> **Question ouverte (2026-09-18) : la langue des acteurs IA.** Un joueur français ne voudra pas
> entendre l'amorce et la réaction en anglais, et inversement. Cacher les bouches des acteurs IA
> n'est pas une réponse (Benjamin : « ça va vite se voir »). Les pistes sont un lip-sync en post
> par langue sur les seules fenêtres IA (HeyGen, sync.so…) ou une regénération Seedance avec le
> clip anglais en référence — aucune n'est testée. **Décision : on fait d'abord une scène en
> anglais, on avise ensuite.** Tant que ce n'est pas tranché, ce skill produit un clip anglais,
> et l'étape 5 ne fait pas de version par langue.

## La forme : une amorce, une cible

**Le joueur regarde toute la scène avant d'enregistrer** — l'amorce, la bouche vide, et la
réaction (Benjamin, 2026-09-18). La réaction n'est donc pas un bord qu'il faudrait rendre
compatible avec n'importe quoi : c'est **la cible**. Le jeu, c'est de trouver la réplique qui
la justifie ; le vote départage six façons d'y arriver. Plus la réaction est précise, plus la
scène est un bon puzzle.

- **L'amorce** (temps 1, 4 à 7 s) est une question, une accusation, une demande, un constat qui
  appelle une réponse. « So… what did you tell my mother? » ; « Where were you last night? ».
- **La réplique** (temps 2, 4 à 6 s de bouche) : le doubleur parle, seul. Il n'est pas
  interrompu, on ne lui répond pas encore, les autres **écoutent**.
- **La réaction** (temps 3, ~3 à 5 s) : les acteurs IA réagissent, avec leur voix ou en silence.
  Elle doit être **lisible et forte**, et **surprenante au regard de l'amorce** — c'est
  l'écart entre ce qu'on attendait et ce qui arrive qui oblige le joueur à inventer. Une
  question banale suivie d'une gifle, d'un fou rire contenu, d'un « …I'm calling the police. »
  ou d'une mère qui plie la lettre et sort sans un mot : voilà une cible.
- **La réaction peut désigner un contenu, jamais recopier la réplique.** « You did WHAT with the
  cat? » est une excellente cible : tout le monde doit parler du chat, personne de la même
  façon. En revanche une réaction qui répond mot pour mot à la phrase anglaise générée
  (« No, I did not say that to her ») donne la réplique et ferme le jeu. Le test : lire la
  réaction seule, et se demander si l'on peut deviner la phrase anglaise. Si oui, la
  réécrire.

**Le test de la cible, avant d'écrire le prompt** : regarder mentalement l'amorce puis la
réaction, sans la réplique, et chercher trois répliques différentes qui mènent de l'une à
l'autre. S'il n'y en a qu'une, la réaction donne la réponse ; s'il n'y en a aucune, la réaction
ne se rattache à rien. Dans les deux cas, réécrire la réaction — pas la réplique anglaise, qui
ne sert qu'aux lèvres.

## Le rythme : une seule vision, trente secondes

Le joueur voit la scène **une fois**, en même temps que les autres, puis a **30 s** pour
enregistrer — avec une scène de 15 s, c'est deux essais au plus, et le premier compte. Ce que
ça impose à l'écriture :

- **Tout se comprend à la première vision.** Pas de détail à relire, pas de double sens qui ne
  se voit qu'à la seconde fois. L'amorce est claire, la réaction est nette, et l'image porte le
  sens autant que les mots.
- **L'anglais est celui d'un joueur français.** Amorce et réaction en anglais simple : mots
  courts, pas d'idiome, pas d'argot, pas de nom propre inutile, débit posé, articulé. « So…
  what did you tell my mother? » passe ; « So what'd you end up spilling to Mum? » ne passe
  pas. Le joueur doit saisir la question du premier coup, sans sous-titre.
- **L'image dit ce que dit la voix.** La lettre est visible quand la mère en parle, le
  téléphone est à l'écran quand on l'évoque : un joueur qui rate un mot anglais doit quand même
  comprendre l'amorce et lire la réaction. Une réaction se juge d'abord **son coupé** — si elle
  n'est pas lisible ainsi, elle repose sur un mot que le joueur peut ne pas avoir.
- **Viser 15 s, pas 18.** Chaque seconde de scène est reprise à chaque essai ; à 18 s
  le second essai n'existe plus. Fixé sur « Le musée » (2026-09-18) : ~15 s, fenêtre 5 à 6 s.

## Le doubleur

- **Un seul personnage à doubler, fixé à la conception**, avant le prompt. C'est lui qui a une
  fiche `dubup-image` en `characters`, un `avatarUrl`, un `gender`.
- **Il ne parle qu'une fois.** S'il parle aussi dans l'amorce ou la réaction, ses autres
  répliques restent en anglais dans le clip pendant que le joueur double celle du milieu — et le
  manifeste voudrait un segment pour chacune. Une scène où il parle deux fois est à réécrire.
- **Sa bouche est vue de près pendant la fenêtre.** Plan rapproché ou moyen serré, face ou
  trois-quarts, pas de profil, pas de main devant la bouche, pas de contre-jour. C'est ce que le
  joueur regarde pour caler sa réplique, et ce que `detect-lips` mesure.
- **Sa réplique anglaise ne sert qu'aux lèvres**, mais son écriture compte : une phrase de
  rythme ordinaire, 12 à 20 mots pour 4 à 6 s, sans cri (une bouche grande ouverte impose la même au
  joueur), sans rire ni sanglot (ils s'entendraient dans la respiration et n'appartiennent à
  aucune réplique). Une phrase « moyenne » laisse toutes les répliques possibles.
- **Pendant la réplique, les acteurs IA écoutent** : immobiles, le regard sur lui, aucun geste,
  aucun mot. C'est une direction à écrire, sinon Seedance les fait réagir en cours de phrase —
  et la réaction se retrouve accrochée au contenu anglais.

## Étape 1 — Le tableau, trois lignes

| Temps | de → à | Ce qu'on voit | Qui parle | Son |
|---|---|---|---|---|
| 1 amorce | 0 → 6,5 | plan moyen : le socle vide au premier plan, le gardien déjà arrêté devant, il regarde le socle puis le visiteur | gardien (IA), dès 0,5 s | VO gardée, pas sur le marbre, trousseau |
| 2 réplique | 6,5 → 12,5 | plan rapproché sur le visiteur, le gardien à l'épaule, qui ferme les yeux un instant | **visiteur (doubleur)**, 7,0 → 12,0 | **rien d'autre** : ni voix, ni bruit, ni geste |
| 3 chute | 12,5 → 15,5 | retour sur le gardien, il désigne le socle du menton, regarde sa montre | gardien (IA), 13,0 → 14,3 | VO gardée, trousseau, pas qui s'éloignent |

(« Le musée », première scène du mode, 2026-09-18 : *La statue était là il y a trente secondes.
Vous êtes la seule personne dans cette salle. Je vous écoute : elle est passée où ?* — 5 s
d'alibi — *Montez sur le socle. On ouvre dans deux minutes.*)

Vérifier avant d'écrire le prompt :

- **à 0:02, il s'est passé quelque chose** : l'amorce a attaqué avant 0,8 s, ou un bruit franc
  a eu lieu, ou l'anomalie est cadrée plein champ. La règle d'ouverture de `dubup-video` vaut
  ici plus encore : la scène dure 15 s, elle n'a aucune seconde à installer ;
- le test de la cible est passé : trois répliques possibles, aucune devinable depuis la
  réaction ;
- **un blanc d'au moins 300 ms de chaque côté de la fenêtre** — aucune voix IA qui la touche.
  C'est ce qui rend la découpe propre à l'étape 5 ;
- la réplique dure entre 4 et 6 s de bouche (segment ≥ 700 ms, `SEGMENT_MIN_MS`) ;
- une **queue muette finale** d'au moins 400 ms (`SCENE_MIN_TAIL_MS`), viser 1 s : c'est là que
  le regard se pose ;
- durée totale entre 12 et 18 s — et au moins 5 s, `SCENE_MIN_DURATION_MS`.

## Étape 2 — Le prompt

Même structure que `dubup-video` (profil visuel de `refs.json`, personnages en `@Image N`, lieux,
ACTING, SOUND), avec trois temps au lieu de N plans, et deux directions qui n'existent que
dans ce mode. Écrire les dialogues **en anglais, entre guillemets doubles**, y compris la
réplique du doubleur — c'est elle qui fait bouger ses lèvres.

```
[Profil visuel, repris mot pour mot de refs.json.]

Characters: @Image 1 is <doubleur>, <marqueurs>. @Image 2 is <acteur IA>, <marqueurs>.
Set: @Image 3 is <lieu>, wide. @Image 4 is the same room, reverse angle.
  The whole scene plays in this set; its geometry never changes.

ACTING: naturalistic, understated performance, as in a French realist family drama; the
  actors underplay; gestures small and economical; faces move little; the voice does most
  of the work at ordinary conversational volume. No exaggerated, theatrical or cartoonish
  expressions, no wide-eyed stares, no raised or knitted eyebrows. All expressions change
  gradually and continuously, never between one frame and the next.

Beat 1 (0–6.5 s) — medium shot on <acteur IA>, <le geste d'accroche déjà en cours>. She
  speaks at once: "<amorce, une question ouverte>". <un bruit franc s'il y en a un>.
Beat 2 (6.5–12.5 s) — close shot on <doubleur>, face fully visible, three-quarter to camera.
  He answers: "<réplique anglaise, 12–20 mots, rythme ordinaire>". While he speaks,
  <acteur IA> listens without moving, eyes on him, and says nothing. No other sound
  during his line: no object set down, no step, no door.
Beat 3 (12.5–15.5 s) — back on <acteur IA>. A held beat, then, quietly: "<réaction, courte,
  la cible : forte, précise, qui ne recopie pas la réplique>". <le geste de sortie et son bruit>. Hold on
  <doubleur>'s face, still, to the end.

SOUND: real domestic sound, recorded in the room, at its natural loudness: no cinematic
  sound design, no added impact, no boom, no reverb. Silence under Beat 2 except the
  room tone.
```

Les deux directions propres au mode, à ne jamais oublier :

- **« listens without moving … says nothing »** sur les acteurs IA pendant la réplique.
- **« No other sound during his line »** — et le corollaire visuel : aucun geste sonore à
  l'image sous la réplique, ils vont dans les temps 1 et 3.

Tout le reste — émotions en gestes progressifs, pas de direction sur une partie du visage,
pas de verbe de scène, bruits décrits par ce qu'ils sont — s'applique tel quel depuis
`dubup-video`.

## Étape 3 — Générer

Comme `dubup-video` : Higgsfield, à la main, images de `output/scenes/<slug>/refs/` dans l'ordre
de `refs.json`, **16:9, 720p**. Régler la durée au cran le plus court qui couvre le tableau ; si
l'interface ne propose pas la durée exacte, prendre celle du dessus et rogner à l'encodage.

Ranger la sortie dans `storage/prep/<slug>-vo.mp4`. Ici ce fichier n'est pas seulement une
mesure : **c'est la source du clip servi** hors de la fenêtre. On ne le sert pas pour autant —
il porte la réplique anglaise du doubleur.

## Étape 4 — Mesurer

Mêmes commandes que `dubup-video` (coupes par `select='gt(scene,0.4)'`, parole par
`silencedetect=n=-30dB:d=0.3` sur le `-vo.mp4`, relecture RMS par 100 ms sur le stem de voix
pour ce qui est murmuré). On attend **trois blocs de parole** : amorce, réplique, réaction. La
réplique est le bloc du milieu ; ses bornes mesurées sont `speechStartMs` et `speechEndMs`.

| À vérifier | Si c'est faux |
|---|---|
| Arrêt sur image à 1 s : on sait ce qui se joue ; à 2 s, l'amorce a attaqué | réécrire le temps 1, **regénérer** |
| Trois blocs de parole, dans l'ordre IA / doubleur / IA, **et pas un de plus** | regénérer : un bloc en trop est une bouche de plus dans le clip |
| **Blanc ≥ 300 ms** entre l'amorce et la réplique, et entre la réplique et la réaction | regénérer, ne pas rogner la fenêtre pour compenser |
| Les lèvres du doubleur bougent, visibles de près, toute la réplique | **regénérer** |
| **Rien sous la réplique** hors nappe continue — écouter `no_vocals.wav` sur la fenêtre, pas le mix | **regénérer** : c'est le contrôle décisif |
| Les acteurs IA ne bougent pas et ne parlent pas pendant la réplique | regénérer |
| La réaction est une cible : forte, lisible, et on ne devine pas la phrase anglaise en la regardant seule | regénérer le temps 3 |
| Les voix sont en anglais, celle du doubleur comprise | regénérer |
| **Regardée son coupé, une fois** : on comprend l'amorce et on lit la réaction | réécrire le temps 1 ou 3, regénérer — le joueur n'a qu'une vision |
| L'anglais de l'amorce et de la réaction est simple, posé, sans idiome | regénérer avec les phrases réécrites |
| Queue finale immobile ≥ 400 ms | rogner `durationMs` ou regénérer |

Le bruitage sous l'amorce ou la réaction n'est **pas** un défaut ici : ces instants sont servis
depuis le mix d'origine, Demucs n'y touche pas.

## Étape 5 — Construire le fond, puis normaliser

**Le lit servi = le mix Seedance partout, sauf dans la fenêtre, où c'est `no_vocals`.**

1. Extraire un WAV 48 kHz stéréo du `-vo.mp4`, passer Demucs (même appel que `dubup-video` :
   `python.exe -m demucs --two-stems=vocals -n htdemucs --shifts 2`). Demucs rééchantillonne à
   44,1 kHz — travailler à cette fréquence jusqu'à l'encodage.
2. Assembler avec un script sur le modèle de
   `output/scenes/une-mission-simple/mesure/construire-audio.py` : la ligne
   `lit = fond + voix * gate` est exactement l'opération, avec **une seule fenêtre** dans
   `PAROLE` — `(speechStart, speechEnd, 0.10, 0.25)`, marges 100 ms avant et 250 ms après,
   fondus 50 ms. Hors de la fenêtre, `fond + voix` redonne le mix ; dedans, il reste `fond`.
3. **L'atténuation de −30 dB sous la réplique n'est pas automatique ici.** Dans `dubup-video`,
   le fond est vide sous les répliques, donc le résidu de voix ressort seul et on l'enfonce. Dans
   un Dub Battle, le fond sous la fenêtre est le même qu'autour ; un trou de 30 dB s'entendrait comme
   une coupure. Écouter la fenêtre : si une syllabe anglaise résiduelle s'entend, atténuer **du
   minimum qui la masque**, en comparant au niveau du fond juste avant et juste après — pas plus.
   Si le fond est vraiment vide (nappe sous −55 dB), alors la règle du 17/09 s'applique et −30 dB
   est le bon chiffre.
4. **Régler le niveau sur les voix IA, pas sur le lit.** Mesurer l'intégré LUFS du mix sur
   l'amorce et la réaction (`ffmpeg -ss … -t … -af ebur128`), poser en `volume=<N>dB` la
   différence avec **−18 LUFS** — le niveau auquel `voiceTargetLufs` ramène chaque joueur
   (`packages/shared/src/mix.ts`). Le joueur et ses partenaires IA parlent alors au même
   niveau. `originalAudioGainDb: 0` dans le manifeste, et dire pourquoi en commentaire. Vérifier
   que le pic reste sous −3 dBFS.
5. Encoder au profil du catalogue, avec `-t` à `durationMs` si la génération est plus longue que
   le tableau :

```
ffmpeg -y -i storage/prep/<slug>-vo.mp4 -i lit.wav \
  -map 0:v -map 1:a -t <durationMs/1000> \
  -vf scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1 \
  -r 30 -c:v libx264 -preset slow -crf 21 -pix_fmt yuv420p \
  -c:a aac -b:a 192k -ar 48000 -af volume=<N>dB \
  -movflags +faststart \
  storage/scenes/<slug>.mp4
```

**Écouter le clip servi en entier** : l'amorce et la réaction en anglais, nettes ; la fenêtre
sans aucune syllabe ; et **pas de marche** de niveau ni de timbre aux deux bords de la
fenêtre — c'est le défaut propre à ce mode, un fond qui change de couleur quand la bouche
s'ouvre. Si la marche s'entend, allonger les fondus à 80–100 ms avant d'envisager autre chose.

## Étape 6 — Le manifeste

Un seul personnage, un seul segment. Les acteurs IA **ne sont pas** des `characters` : le
schéma refuse un personnage sans segment (« ce n'est donc pas un rôle »), et c'est juste — ils
sont dans l'image, pas dans la distribution.

```jsonc
{
  "mode": "battle",                     // ignoré par zod tant que scene.ts ne le connaît pas
  "manifestVersion": 1,
  "sceneId": "sc_<slug>", "slug": "<slug>", "title": "…",
  "synopsis": "<la situation en une phrase, sans dire ce qu'il répond>",
  "language": "fr", "translations": {},
  "universe": "<universe>",
  "durationMs": 15500,
  "video": { "url": "scenes/<slug>.mp4", "posterUrl": "scenes/<slug>.jpg", "width": 1280, "height": 720, "fps": 30 },
  "audioBed": { "keepOriginalAudio": true, "originalAudioGainDb": 0, "ambienceUrl": null, "musicUrl": null },
  "characters": [
    { "key": "visiteur", "name": "Le visiteur", "color": "#C6533B", "avatarUrl": "scenes/<slug>/visiteur.png", "gender": "man",
      "description": "<qui il est, pas ce qu'il dit>" }
  ],
  "segments": [
    { "id": "s1", "characterKey": "visiteur",
      "startMs": 6500, "endMs": 12500,       // le tour de parole : du blanc après l'amorce au blanc avant la réaction
      "speechStartMs": 7000, "speechEndMs": 12000,   // mesurés à l'étape 4
      "originalLine": null,                  // le joueur invente : rien d'affichable
      "direction": "<ce que le gardien vient de demander, et ce qu'il va faire après>",
      "envelope": <SLUG>_ENVELOPES.s1, "mouth": <SLUG>_LIPS.s1 }
  ],
  "foley": { "enabled": false, "cues": [] },
  "rights": { "sourceKind": "owned", "allowsPublicSharing": true, "allowsMusicReuse": false }
}
```

- **`originalLine: null`, et pas la réplique anglaise traduite.** Aujourd'hui l'app allume ce
  texte en sous-titre sur la fenêtre de parole ; l'y mettre donnerait à tous la même réplique
  et viderait le vote. La `direction` porte ce dont le joueur a besoin : ce qu'on lui a dit, ce
  qui va suivre. Elle ne suggère jamais une réponse.
- `startMs` / `endMs` : le tour de parole va de la fin de l'amorce au début de la réaction, et
  `speechStartMs` / `speechEndMs` sont **mesurés**, jamais recopiés du tableau.
- `envelope` et `mouth` : mêmes outils que `dubup-video` (`envelopes.mjs`, `detect-lips.mjs`),
  sur `storage/prep/<slug>-vo.mp4`, mis à zéro hors de la fenêtre. Il n'y a qu'un segment, donc
  qu'une bouche à mesurer — regarder la planche `lips.png` quand même.
- Les pièges de champs sont ceux de `dubup-video/references/manifest-checklist.md`.

Validation : `catalogue.ts` + `npm run build -w @dubup/shared` + import du module, comme
`dubup-video`. `npm run validate:scene` n'existe pas.

## Étape 7 — Rendre compte

Dans cet ordre : **l'amorce** (le texte anglais, son attaque mesurée), **la fenêtre** (bornes
mesurées, blancs de chaque côté, ce qu'on entend dessous dans le clip servi — rien, ou une nappe
et à quel niveau), **la réaction** (le texte anglais, ce qu'elle fait, et la preuve qu'elle ne
cite pas la réplique), la queue finale, le niveau des voix IA après encodage.

Puis les trois points qui ne se rattrapent pas après publication :

- **aucune syllabe anglaise dans la fenêtre** de `storage/scenes/<slug>.mp4`, et **les voix IA
  intactes** en dehors ;
- **le test de la cible**, refait sur le clip fini : trois répliques qui mènent à la réaction,
  écrites, et la réaction ne trahit pas la phrase anglaise ;
- `storage/prep/<slug>-vo.mp4` conservé.
