hlassiege/darylpublic Fork
⑂ 7d84a31
Commits
⬇ Clone ▾
git clone https://git.rickub.com/hlassiege/daryl.git
git clone ssh://git@rickub.com/hlassiege/daryl.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

docs: add motion storyboard plan

hlassiege committed 2026-10-11T13:01:48+02:00 Browse files
7d84a31 parent: c123cdd
added docs/plan-motion-storyboard.md +215 -0
new file mode 100644
@@ -0,0 +1,215 @@
1+# Plan — storyboard de motion design et bibliothèque d'inspirations
2+
3+Reprise d'idées d'**editing-os** (dossier `editing-os-starter/`, kit Claude Code + HyperFrames d'un autre
4+créateur, licence MIT, analysé le 09/10/2026). On en reprend les méthodes, pas les fichiers : ses scripts
5+supposent macOS et ses cartes sont en anglais, calées sur ses styles.
6+
7+## Où on en est
8+
9+**Fait (10/10/2026)**
10+- Dérush automatique : onglet **Daryl** de l'étape Dérush (`backend/studio/modules/projects/autoderush.py`,
11+ `web/src/project/steps/derush/AutoDerush.vue`). Recalage des mots sur le son, silences avec respiration
12+ selon le contexte, bégaiements, lecture des prises par Claude (coupes désignées en texte + ancre
13+ `before`, jamais en timecode), contrôles (phrase encore dite deux fois, contenu coupé sans équivalent,
14+ coupe introuvable). Rien n'est coupé sans « Appliquer ». Testé sur « Lever l'anonymat ? » : 35 coupes
15+ de prises toutes retrouvées, 1 avertissement, ~1 min.
16+- Les transcriptions enregistrent leur moteur (`state.engine`, `transcript/tasks.py`). Dans « Lever
17+ l'anonymat ? », les rushes 0021, 0024, 0025, 0026 et 0028 sont encore en Whisper (à refaire en ElevenLabs).
18+
19+- Phase 1.1 + 1.2 : `backend/studio/modules/projects/storyboard.py` (job `project_storyboard`, file
20+ `storyboard`), routes `GET/POST /{pid}/montage/storyboard` et `POST …/storyboard/stop`. Le transcript de
21+ la timeline est reconstruit mot à mot (`timeline_words`) ; Claude donne `line` + `anchor` + `until`
22+ (jamais de timecode) ; `at` = mot d'ancre − 0,2 s, fin = dernier mot couvert + 0,5 s (2,5 à 15 s) ;
23+ `fit` raccourcit un beat qui déborde ; `check` (refait à chaque lecture) signale `anchor`, `late`
24+ (hors −0,2 / +1,8 s), `overlap`, `busy` (motion déjà là), `density`. Testé sur « Lever l'anonymat ? »
25+ (17 min, densité équilibrée) : 32 beats en 2 min, toutes les ancres retrouvées, aucun avertissement.
26+- Phase 1.3 : le storyboard est **une étape à part** (`storyboard`, phase « long », avant Montage) :
27+ `web/src/project/steps/StoryboardStep.vue` + `montage/useStoryboard.ts`. Beats en cartes larges
28+ (quand / il dit + on montre / place, type, base du kit, son), aperçu fixe à droite avec la place du
29+ beat dessinée dessus, bande de rythme en haut, ↑/↓ d'un beat à l'autre. Retouches par
30+ `PUT …/storyboard`. « Valider → Montage » termine l'étape, sans rien générer.
31+- Places d'un beat : `full`, `left`, `right`, `top`, `lower` (l'ancien `side` est lu comme `right`).
32+ Choisies sur un petit écran 16:9 cliquable. À la génération, Daryl reçoit 3 images de la vidéo
33+ (20 / 50 / 80 % de la durée) pour mettre le visuel du côté libre. Les zooms restent au Montage.
34+- Chat du storyboard, sous l'aperçu (`storyboard_chat.py`, job `{pid}-storyboard-chat`, file `storyboard` ;
35+ `web/src/project/steps/storyboard/StoryboardChat.vue`) : demande sur toute la vidéo ou sur le moment
36+ choisi (beat sélectionné, sinon tête de lecture), avec l'image de la vidéo source à ce moment
37+ (ffmpeg → `montage/frames/frame-<ms>.jpg`, lue par Daryl avec Read). Réponse structurée
38+ (`add` / `update` / `remove`) : un beat ajouté est placé par ses mots exacts (`locate`), une ancre
39+ introuvable est signalée. Les retouches à la main sont bloquées pendant sa réponse. Session reprise
40+ d'un tour à l'autre (le transcript n'est envoyé qu'au premier). Pas encore testé avec Claude.
41+- Phase 1.4, dans le Montage (c'est là qu'on teste le rendu) : les beats cochés sans animation sont en
42+ pointillés sur la piste motion (clic = la lecture va sur le beat) et en slide sur l'aperçu, à leur place
43+ (`Preview.vue`, props `beats` / `create` / `anims`), avec « Créer l'animation », et « Créer les n
44+ animations » dans la barre d'outils. `POST …/storyboard/animate` (`beats` : ids, sinon tous) :
45+ `storyboard.compose` pose un motion par beat (`beat` = id du beat, place et durée validées) et son son
46+ d'entrée (0,15 s avant, −12 dB), puis **une tâche par beat** (`beat_anim.py`, job `{pid}-anim-{beat}`)
47+ écrit `motion/<id>.html` avec une fiche courte (`storyboard.brief`, mots du beat avec leurs instants,
48+ `MOTION_RULES`, charte, modèle du kit). 3 files (`beat_anim_0..2`) : 3 créations à la fois, les autres
49+ en file. État par beat dans `view.anim_jobs` (file, en cours + activité, échec) : sur la slide et dans
50+ la barre « Animations » du Montage, avec Arrêter / Relancer. Un beat compte comme animé quand son HTML
51+ existe (`storyboard.animated`) : un motion posé mais jamais écrit se relance. Le chat du monteur ne
52+ compose plus de beats ; `contexte.md` liste les motions en cours de création pour qu'il n'y touche pas.
53+ Lois chiffrées d'editing-os ajoutées à `MOTION_RULES`, « Fais le travail » retiré.
54+- **Types de beats** (`type`) : `motion`, `zoom`, `broll`, `transition` (un ancien beat est un motion).
55+ - zoom : `zoom {scale 1,05–1,5, x, y}`, le centre borné pour que le cadre reste dans l'image (`zoom_of`),
56+ 2 à 8 s, 0,1 s avant le mot ; posé tel quel sur la piste `zooms` (champ `beat`).
57+ - broll : `src` (média visuel du projet ou de la bibliothèque, `storyboard.visuals`) ou, vide, une
58+ suggestion « à trouver » avec `search`. Une vidéo va sur la piste `broll` ; une image devient un motion
59+ animé par Daryl (copiée dans `motion/media/<beat>-<nom>`, plein écran ou sur un côté comme un portrait).
60+ Les plans Image / Écran / B-roll du script deviennent des broll avec leur média attaché.
61+ - transition : plein écran, 1,2 s, 0,9 s avant les premiers mots de la nouvelle partie ; un motion animé
62+ par Daryl avec une fiche dédiée.
63+ - Contrôles : chevauchement entre ce qui occupe l'écran (motion, broll, transition) et entre zooms,
64+ `hidden` (zoom sous un plein écran), `busy` par piste ; la densité ne compte que les motions.
65+ - Génération : choix des types à proposer (`types`). Écran : filtres par type, couleurs, carte par type
66+ (zoom : grossissement + cadre cliquable sur l'image de la vidéo ; broll : média, aperçu, recherche à
67+ copier, lien Assets). Montage : « Créer les n animations » et « Poser n zooms et B-roll » ; un zoom ou
68+ un B-roll vidéo pas encore posé se voit déjà dans l'aperçu. `POST …/animate` rend
69+ `{queued, placed, skipped, missing}`. Pas encore testé avec une vraie génération de Claude.
70+- **Suite décidée** : retours image par image dans le Montage (temps local du motion + beat + HTML
71+ envoyés à Daryl, sans rendu ; retours accumulés puis envoyés ; un retour généralisable devient une règle).
72+- Plans du script : les plans Animation / Texte à l'écran de `script.json` sont les beats de départ
73+ (`origin: "script"`, `plan` = id du plan), repérés dans la timeline par vote de triplets de mots
74+ (`find_passage`) ; Daryl les détaille sans les remplacer et n'ajoute des beats (`origin: "daryl"`) que
75+ pour la densité ; un plan qu'il oublie est posé tel quel ; un plan introuvable est signalé. Les plans
76+ Image / Écran / B-roll / Insert / Plan de coupe occupent l'écran : contrôle `cover`. Les plans sont
77+ aussi listés dans `contexte.md` pour le chat du monteur. « Lever l'anonymat ? » : 12 plans repris sur 13
78+ (« 35 millions de comptes » dit autrement), 21 beats ajoutés, aucun avertissement.
79+
80+- **Bibliothèque de transitions** (10/10/2026) : `backend/studio/modules/projects/transitions.py`, les 55
81+ transitions `xfade` de ffmpeg 7.1 en 5 familles (fondus, balayages, glissements, formes, effets ; `squeezev`
82+ retirée, elle fait planter ffmpeg). Timeline : `transition` de l'A-roll = `{fx, dur}` (un ancien nombre est lu
83+ comme un fondu), `enter` / `exit` sur B-roll et motions. Rendu (`render.overlay_groups`) : entrée et sortie =
84+ `xfade` contre une image transparente, un plan collé au précédent de sa piste avec une entrée s'enchaîne avec
85+ lui (centré sur la coupe, vraies images du média autour). Galerie : démos rendues par ffmpeg
86+ (`data/cache/transitions/`), onglet Transitions de la Bibliothèque, sélecteur dans l'inspecteur du Montage et
87+ sur les cartes motion / B-roll du storyboard. Aperçu du Montage en CSS (`web/src/lib/transitions.ts`,
88+ `layersAt`), approché pour lamelles, vent, pixels, dissolution. Daryl propose `enter_fx` / `exit_fx` au
89+ storyboard et connaît le catalogue au chat du Montage. Resolve : fondu enchaîné à la place des autres
90+ transitions de l'A-roll, coupes franches pour les entrées / sorties (signalé à l'export).
91+
92+**Pas encore fait, à garder en tête**
93+- Vérification après rendu (re-transcrire le MP4 exporté et vérifier que les coupes ont porté).
94+- Mastering -14 LUFS (loudnorm deux passes, puis `aresample=48000`, `alimiter`, `aformat=s16` avant l'AAC :
95+ voir `editing-os-starter/scripts/master.py`).
96+- Export de la timeline du dérush : remis à plus tard par l'utilisateur.
97+
98+## Constat de départ (étape Montage)
99+
100+- Daryl crée les motions **directement** dans `montage/timeline.json` + `montage/motion/<id>.html`. Son
101+ prompt dit « Fais le travail, ne propose pas seulement » (`montage_tasks.py`), ce qui contredit la règle
102+ de l'utilisateur : l'IA propose, l'utilisateur décide.
103+- Une seule charte (`animations/kit/style.css`) et 2 exemples (`exemple-arbre`, `exemple-chronologie`).
104+- Les shorts ont leur propre flux de slides (`animations/service.py`), avec des densités sobre / équilibrée / dense.
105+
106+## Phase 1 — Storyboard dans l'étape Montage
107+
108+But : Daryl propose d'abord un storyboard, l'utilisateur le valide, et seulement ensuite il compose.
109+Méthode reprise de `editing-os-starter/.claude/skills/design-beats/SKILL.md`.
110+
111+### 1.1 Génération (job `project_storyboard`, sortie structurée)
112+- Entrées : transcript en temps timeline (comme `contexte.md`), chapitres, script, charte, densité choisie,
113+ sélection d'inspirations (phase 2).
114+- La question pour chaque passage : « qu'est-ce qu'on **montre** pendant qu'il dit ça ? », jamais « quel
115+ texte on affiche ». Grille de traduction adaptée à la vidéo longue éducative : chiffre → compteur qui se
116+ construit ; processus → schéma qui s'assemble ; comparaison → A/B ; date → chronologie ; outil cité →
117+ capture ou logo ; liste → éléments qui se cochent. Interdits : carte-label statique, texte qui répète la
118+ parole, décor.
119+- Un beat : `{id, at, dur, anchor (mots exacts du départ), says, show, kind, place (plein écran | côté |
120+ bas), motion (entrée / entretien / sortie), sfx, ref (inspiration, phase 2), why}`.
121+- Stockage : `montage/storyboard.json`.
122+
123+### 1.2 Contrôles automatiques
124+- L'ancre existe dans le transcript, et le beat démarre entre 0,2 s avant et 1,8 s après le mot ancré
125+ (« Gate 0 » d'editing-os) : sinon on recale ou on signale.
126+- Pas de chevauchement ; densité réelle comparée à la densité demandée.
127+- Ancre introuvable : signalée, pas devinée (comme le dérush automatique).
128+
129+### 1.3 Écran (onglet Storyboard de l'étape Montage, à côté du chat)
130+- Une ligne par beat : timecode cliquable, « il dit », « on montre » modifiable, type, place, case à cocher,
131+ supprimer, « refaire ce beat ».
132+- Les beats en fantôme sur la piste motion de la timeline, pour juger le rythme.
133+- Bouton « Composer les n beats validés ».
134+
135+### 1.4 Composition depuis le storyboard
136+- Daryl ne compose que les beats validés, en suivant « on montre » ; tout écart est re-proposé.
137+- Le chat garde l'édition directe pour les petites demandes explicites ; une création d'ensemble passe par
138+ le storyboard. Retirer « Fais le travail, ne propose pas seulement ».
139+- Ajouter à `MOTION_RULES` les lois chiffrées d'editing-os (`MOTION_PHILOSOPHY.md`, skill `motion-doctrine`) :
140+ une idée par beat ; visuel 0,2 s avant le mot ; sortie ≈ 75 % de la durée d'entrée ; pas d'oscillation
141+ décorative (`repeat: -1`, yoyo) ; immobilité de 0,3 à 0,75 s avant un climax ; la timeline doit durer
142+ toute la composition (`tl.to({}, {duration}, 0)`), sinon flash noir.
143+
144+## Phase 2 — Bibliothèque d'inspirations
145+
146+But : une galerie de références de motion (démo, mécanique, prompt) dans laquelle l'utilisateur choisit et
147+annote ce que Daryl doit suivre. Modèle : `editing-os-starter/motion-library/` et
148+`scripts/motion-library/` (import, catégories, planches), `editing-os/lib/selection.mjs`.
149+
150+### 2.1 Données
151+- Base : `editing-os-starter/motion-library/analyse.json` — 270 références analysées (54 pépites,
152+ 159 solides, 57 faibles ; 15 usages : explicatif, data, typo, UI, produit…). Chaque fiche :
153+ `titre, resume, usage, usages, ambiance, mecanique {transitions, rythme, texte, techniques}, niveau,
154+ pourquoi`.
155+- Import porté en Python : démos, posters et prompts depuis julienpocinho.fr et prompt-motion.com
156+ (décodage des morceaux RSC Next.js, voir `import.mjs`). 4 requêtes à la fois au plus.
157+- Planche de 12 images (4×3, 480×270) par démo avec ffmpeg, lue directement depuis l'URL ; vignette = le
158+ JPEG le plus lourd entre 25 et 85 % de la durée (les images noires pèsent presque rien).
159+- Stockage local `data/library/inspirations/` : **contenu de tiers, jamais dans le dépôt** (on ne versionne
160+ que l'importeur).
161+- Références de l'utilisateur : URL ou clip (téléchargement yt-dlp existant) ; Claude regarde la planche et
162+ remplit la fiche « mécanique » au même format.
163+
164+### 2.2 Écran (onglet Inspirations de la page Bibliothèque)
165+- Grille de posters, démo au survol ; filtres usage / niveau / ambiance ; les faibles masqués par défaut.
166+- Fiche : démo, planche, mécanique, prompt d'origine. « Ajouter à ma sélection » avec une note.
167+
168+### 2.3 Lien avec le storyboard
169+- Daryl reçoit la sélection et ses notes (prioritaires), puis l'index par usage ; il cite une référence par
170+ beat avancé, affichée en vignette sur la ligne du beat.
171+- On reprend la mécanique (mouvement, rythme, transitions), jamais l'habillage : la charte reste celle de
172+ l'utilisateur.
173+
174+## Plus tard — styles (design system)
175+Plusieurs chartes au choix par projet (`tokens.css` + `DESIGN.md`), puis des cartes à emplacements de texte
176+(`data-slot` + `maxChars`), rangées par tier (t1 plein écran opaque, t2 transparent qui ne couvre pas le
177+visage) et par usage, avec une registry et un tirage reproductible sans répétition consécutive (voir
178+`editing-os-starter/style-library/GUIDE.md`, `.claude/skills/motion-graphics/`). Le champ `kind` / `place`
179+du storyboard deviendra le choix d'une carte.
180+
181+## Ordre
182+1. Phase 1.1 + 1.2, testées sur un projet réel sans interface.
183+2. Phase 1.3 + 1.4 : utilisable pour de vrai.
184+3. Phase 2.1.
185+4. Phase 2.2 + 2.3.
186+
187+## Décisions (10/10/2026)
188+1. **Vidéo longue uniquement** pour l'instant (les shorts plus tard).
189+2. Densité : reprendre les trois densités des slides (`animations/service.py`, `DENSITIES`) : sobre
190+ (~1 motion / 1 min 30), équilibrée (~1 / 30-45 s), dense (~1 / 15-20 s). Le rythme des reels
191+ d'editing-os (un événement toutes les 1 à 2 s) est trop dense pour une vidéo longue. **« Équilibrée »
192+ par défaut, réglable à chaque génération** (validé).
193+3. **Import complet** des inspirations (démos, posters, prompts des deux sites, en local).
194+
195+## Notes d'outillage (réponses du 10/10/2026)
196+- **Analyser une animation** : editing-os ne décompose pas image par image. ffmpeg tire une planche de
197+ 12 images réparties sur la démo, Claude la regarde (vision) avec le prompt d'origine et écrit la fiche
198+ « mécanique ». Ça capte la composition et les états, pas les courbes ni les timings fins. Pour reproduire
199+ une transition précise : une planche dense autour du moment (8 à 12 images par seconde sur 1 à 2 s),
200+ repéré par détection de changement de plan (`select='gt(scene,0.15)'`).
201+- **Détourage** : CLI HyperFrames, `npx hyperframes remove-background` (modèle u2net_human_seg, ~168 Mo,
202+ local, gratuit). Sortie ProRes 4444 ou WebM VP9 avec alpha. Lent : ~2 images/s en 1080p sur CPU, donc
203+ à réserver aux passages qui en ont besoin. Re-encoder d'abord une source à cadence variable (sinon sujet
204+ dédoublé), et appliquer les mêmes coupes à la vidéo et au détourage. Usages : texte derrière la personne
205+ (on rend vidéo + texte, puis on recolle la personne détourée par-dessus), personne qui dépasse d'une carte.
206+- **Musique et sons** :
207+ - editing-os : un pack de SFX maison nommés par rôle (`whoosh`, `pop`, `click`, `cash`, `impact`,
208+ `riser`, `buzzer`…) avec une table son ↔ animation et un volume par son (`asset-library/sfx/README.md`) ;
209+ la musique via `npx hyperframes media-use resolve --type bgm` (catalogue HeyGen, compte heygen
210+ requis) ; le mixage (ducking, fondus) via le skill `hyperframes-audio`.
211+ - Studio : bibliothèque `data/library/` (musique, sfx), Daryl ne place que des fichiers listés dans
212+ `contexte.md`, gains fixes, pas de ducking.
213+ - À reprendre : nommer les SFX par rôle et donner la table son ↔ animation à Daryl ; un `sfx` par beat
214+ dans le storyboard ; ducking de la musique sous la voix au rendu (`sidechaincompress` ffmpeg) ; le
215+ catalogue HeyGen seulement si l'utilisateur veut un compte de plus.
new file mode 100644
@@ -0,0 +1,215 @@
1+# Plan — storyboard de motion design et bibliothèque d'inspirations
2+
3+Reprise d'idées d'**editing-os** (dossier `editing-os-starter/`, kit Claude Code + HyperFrames d'un autre
4+créateur, licence MIT, analysé le 09/10/2026). On en reprend les méthodes, pas les fichiers : ses scripts
5+supposent macOS et ses cartes sont en anglais, calées sur ses styles.
6+
7+## Où on en est
8+
9+**Fait (10/10/2026)**
10+- Dérush automatique : onglet **Daryl** de l'étape Dérush (`backend/studio/modules/projects/autoderush.py`,
11+ `web/src/project/steps/derush/AutoDerush.vue`). Recalage des mots sur le son, silences avec respiration
12+ selon le contexte, bégaiements, lecture des prises par Claude (coupes désignées en texte + ancre
13+ `before`, jamais en timecode), contrôles (phrase encore dite deux fois, contenu coupé sans équivalent,
14+ coupe introuvable). Rien n'est coupé sans « Appliquer ». Testé sur « Lever l'anonymat ? » : 35 coupes
15+ de prises toutes retrouvées, 1 avertissement, ~1 min.
16+- Les transcriptions enregistrent leur moteur (`state.engine`, `transcript/tasks.py`). Dans « Lever
17+ l'anonymat ? », les rushes 0021, 0024, 0025, 0026 et 0028 sont encore en Whisper (à refaire en ElevenLabs).
18+
19+- Phase 1.1 + 1.2 : `backend/studio/modules/projects/storyboard.py` (job `project_storyboard`, file
20+ `storyboard`), routes `GET/POST /{pid}/montage/storyboard` et `POST …/storyboard/stop`. Le transcript de
21+ la timeline est reconstruit mot à mot (`timeline_words`) ; Claude donne `line` + `anchor` + `until`
22+ (jamais de timecode) ; `at` = mot d'ancre − 0,2 s, fin = dernier mot couvert + 0,5 s (2,5 à 15 s) ;
23+ `fit` raccourcit un beat qui déborde ; `check` (refait à chaque lecture) signale `anchor`, `late`
24+ (hors −0,2 / +1,8 s), `overlap`, `busy` (motion déjà là), `density`. Testé sur « Lever l'anonymat ? »
25+ (17 min, densité équilibrée) : 32 beats en 2 min, toutes les ancres retrouvées, aucun avertissement.
26+- Phase 1.3 : le storyboard est **une étape à part** (`storyboard`, phase « long », avant Montage) :
27+ `web/src/project/steps/StoryboardStep.vue` + `montage/useStoryboard.ts`. Beats en cartes larges
28+ (quand / il dit + on montre / place, type, base du kit, son), aperçu fixe à droite avec la place du
29+ beat dessinée dessus, bande de rythme en haut, ↑/↓ d'un beat à l'autre. Retouches par
30+ `PUT …/storyboard`. « Valider → Montage » termine l'étape, sans rien générer.
31+- Places d'un beat : `full`, `left`, `right`, `top`, `lower` (l'ancien `side` est lu comme `right`).
32+ Choisies sur un petit écran 16:9 cliquable. À la génération, Daryl reçoit 3 images de la vidéo
33+ (20 / 50 / 80 % de la durée) pour mettre le visuel du côté libre. Les zooms restent au Montage.
34+- Chat du storyboard, sous l'aperçu (`storyboard_chat.py`, job `{pid}-storyboard-chat`, file `storyboard` ;
35+ `web/src/project/steps/storyboard/StoryboardChat.vue`) : demande sur toute la vidéo ou sur le moment
36+ choisi (beat sélectionné, sinon tête de lecture), avec l'image de la vidéo source à ce moment
37+ (ffmpeg → `montage/frames/frame-<ms>.jpg`, lue par Daryl avec Read). Réponse structurée
38+ (`add` / `update` / `remove`) : un beat ajouté est placé par ses mots exacts (`locate`), une ancre
39+ introuvable est signalée. Les retouches à la main sont bloquées pendant sa réponse. Session reprise
40+ d'un tour à l'autre (le transcript n'est envoyé qu'au premier). Pas encore testé avec Claude.
41+- Phase 1.4, dans le Montage (c'est là qu'on teste le rendu) : les beats cochés sans animation sont en
42+ pointillés sur la piste motion (clic = la lecture va sur le beat) et en slide sur l'aperçu, à leur place
43+ (`Preview.vue`, props `beats` / `create` / `anims`), avec « Créer l'animation », et « Créer les n
44+ animations » dans la barre d'outils. `POST …/storyboard/animate` (`beats` : ids, sinon tous) :
45+ `storyboard.compose` pose un motion par beat (`beat` = id du beat, place et durée validées) et son son
46+ d'entrée (0,15 s avant, −12 dB), puis **une tâche par beat** (`beat_anim.py`, job `{pid}-anim-{beat}`)
47+ écrit `motion/<id>.html` avec une fiche courte (`storyboard.brief`, mots du beat avec leurs instants,
48+ `MOTION_RULES`, charte, modèle du kit). 3 files (`beat_anim_0..2`) : 3 créations à la fois, les autres
49+ en file. État par beat dans `view.anim_jobs` (file, en cours + activité, échec) : sur la slide et dans
50+ la barre « Animations » du Montage, avec Arrêter / Relancer. Un beat compte comme animé quand son HTML
51+ existe (`storyboard.animated`) : un motion posé mais jamais écrit se relance. Le chat du monteur ne
52+ compose plus de beats ; `contexte.md` liste les motions en cours de création pour qu'il n'y touche pas.
53+ Lois chiffrées d'editing-os ajoutées à `MOTION_RULES`, « Fais le travail » retiré.
54+- **Types de beats** (`type`) : `motion`, `zoom`, `broll`, `transition` (un ancien beat est un motion).
55+ - zoom : `zoom {scale 1,05–1,5, x, y}`, le centre borné pour que le cadre reste dans l'image (`zoom_of`),
56+ 2 à 8 s, 0,1 s avant le mot ; posé tel quel sur la piste `zooms` (champ `beat`).
57+ - broll : `src` (média visuel du projet ou de la bibliothèque, `storyboard.visuals`) ou, vide, une
58+ suggestion « à trouver » avec `search`. Une vidéo va sur la piste `broll` ; une image devient un motion
59+ animé par Daryl (copiée dans `motion/media/<beat>-<nom>`, plein écran ou sur un côté comme un portrait).
60+ Les plans Image / Écran / B-roll du script deviennent des broll avec leur média attaché.
61+ - transition : plein écran, 1,2 s, 0,9 s avant les premiers mots de la nouvelle partie ; un motion animé
62+ par Daryl avec une fiche dédiée.
63+ - Contrôles : chevauchement entre ce qui occupe l'écran (motion, broll, transition) et entre zooms,
64+ `hidden` (zoom sous un plein écran), `busy` par piste ; la densité ne compte que les motions.
65+ - Génération : choix des types à proposer (`types`). Écran : filtres par type, couleurs, carte par type
66+ (zoom : grossissement + cadre cliquable sur l'image de la vidéo ; broll : média, aperçu, recherche à
67+ copier, lien Assets). Montage : « Créer les n animations » et « Poser n zooms et B-roll » ; un zoom ou
68+ un B-roll vidéo pas encore posé se voit déjà dans l'aperçu. `POST …/animate` rend
69+ `{queued, placed, skipped, missing}`. Pas encore testé avec une vraie génération de Claude.
70+- **Suite décidée** : retours image par image dans le Montage (temps local du motion + beat + HTML
71+ envoyés à Daryl, sans rendu ; retours accumulés puis envoyés ; un retour généralisable devient une règle).
72+- Plans du script : les plans Animation / Texte à l'écran de `script.json` sont les beats de départ
73+ (`origin: "script"`, `plan` = id du plan), repérés dans la timeline par vote de triplets de mots
74+ (`find_passage`) ; Daryl les détaille sans les remplacer et n'ajoute des beats (`origin: "daryl"`) que
75+ pour la densité ; un plan qu'il oublie est posé tel quel ; un plan introuvable est signalé. Les plans
76+ Image / Écran / B-roll / Insert / Plan de coupe occupent l'écran : contrôle `cover`. Les plans sont
77+ aussi listés dans `contexte.md` pour le chat du monteur. « Lever l'anonymat ? » : 12 plans repris sur 13
78+ (« 35 millions de comptes » dit autrement), 21 beats ajoutés, aucun avertissement.
79+
80+- **Bibliothèque de transitions** (10/10/2026) : `backend/studio/modules/projects/transitions.py`, les 55
81+ transitions `xfade` de ffmpeg 7.1 en 5 familles (fondus, balayages, glissements, formes, effets ; `squeezev`
82+ retirée, elle fait planter ffmpeg). Timeline : `transition` de l'A-roll = `{fx, dur}` (un ancien nombre est lu
83+ comme un fondu), `enter` / `exit` sur B-roll et motions. Rendu (`render.overlay_groups`) : entrée et sortie =
84+ `xfade` contre une image transparente, un plan collé au précédent de sa piste avec une entrée s'enchaîne avec
85+ lui (centré sur la coupe, vraies images du média autour). Galerie : démos rendues par ffmpeg
86+ (`data/cache/transitions/`), onglet Transitions de la Bibliothèque, sélecteur dans l'inspecteur du Montage et
87+ sur les cartes motion / B-roll du storyboard. Aperçu du Montage en CSS (`web/src/lib/transitions.ts`,
88+ `layersAt`), approché pour lamelles, vent, pixels, dissolution. Daryl propose `enter_fx` / `exit_fx` au
89+ storyboard et connaît le catalogue au chat du Montage. Resolve : fondu enchaîné à la place des autres
90+ transitions de l'A-roll, coupes franches pour les entrées / sorties (signalé à l'export).
91+
92+**Pas encore fait, à garder en tête**
93+- Vérification après rendu (re-transcrire le MP4 exporté et vérifier que les coupes ont porté).
94+- Mastering -14 LUFS (loudnorm deux passes, puis `aresample=48000`, `alimiter`, `aformat=s16` avant l'AAC :
95+ voir `editing-os-starter/scripts/master.py`).
96+- Export de la timeline du dérush : remis à plus tard par l'utilisateur.
97+
98+## Constat de départ (étape Montage)
99+
100+- Daryl crée les motions **directement** dans `montage/timeline.json` + `montage/motion/<id>.html`. Son
101+ prompt dit « Fais le travail, ne propose pas seulement » (`montage_tasks.py`), ce qui contredit la règle
102+ de l'utilisateur : l'IA propose, l'utilisateur décide.
103+- Une seule charte (`animations/kit/style.css`) et 2 exemples (`exemple-arbre`, `exemple-chronologie`).
104+- Les shorts ont leur propre flux de slides (`animations/service.py`), avec des densités sobre / équilibrée / dense.
105+
106+## Phase 1 — Storyboard dans l'étape Montage
107+
108+But : Daryl propose d'abord un storyboard, l'utilisateur le valide, et seulement ensuite il compose.
109+Méthode reprise de `editing-os-starter/.claude/skills/design-beats/SKILL.md`.
110+
111+### 1.1 Génération (job `project_storyboard`, sortie structurée)
112+- Entrées : transcript en temps timeline (comme `contexte.md`), chapitres, script, charte, densité choisie,
113+ sélection d'inspirations (phase 2).
114+- La question pour chaque passage : « qu'est-ce qu'on **montre** pendant qu'il dit ça ? », jamais « quel
115+ texte on affiche ». Grille de traduction adaptée à la vidéo longue éducative : chiffre → compteur qui se
116+ construit ; processus → schéma qui s'assemble ; comparaison → A/B ; date → chronologie ; outil cité →
117+ capture ou logo ; liste → éléments qui se cochent. Interdits : carte-label statique, texte qui répète la
118+ parole, décor.
119+- Un beat : `{id, at, dur, anchor (mots exacts du départ), says, show, kind, place (plein écran | côté |
120+ bas), motion (entrée / entretien / sortie), sfx, ref (inspiration, phase 2), why}`.
121+- Stockage : `montage/storyboard.json`.
122+
123+### 1.2 Contrôles automatiques
124+- L'ancre existe dans le transcript, et le beat démarre entre 0,2 s avant et 1,8 s après le mot ancré
125+ (« Gate 0 » d'editing-os) : sinon on recale ou on signale.
126+- Pas de chevauchement ; densité réelle comparée à la densité demandée.
127+- Ancre introuvable : signalée, pas devinée (comme le dérush automatique).
128+
129+### 1.3 Écran (onglet Storyboard de l'étape Montage, à côté du chat)
130+- Une ligne par beat : timecode cliquable, « il dit », « on montre » modifiable, type, place, case à cocher,
131+ supprimer, « refaire ce beat ».
132+- Les beats en fantôme sur la piste motion de la timeline, pour juger le rythme.
133+- Bouton « Composer les n beats validés ».
134+
135+### 1.4 Composition depuis le storyboard
136+- Daryl ne compose que les beats validés, en suivant « on montre » ; tout écart est re-proposé.
137+- Le chat garde l'édition directe pour les petites demandes explicites ; une création d'ensemble passe par
138+ le storyboard. Retirer « Fais le travail, ne propose pas seulement ».
139+- Ajouter à `MOTION_RULES` les lois chiffrées d'editing-os (`MOTION_PHILOSOPHY.md`, skill `motion-doctrine`) :
140+ une idée par beat ; visuel 0,2 s avant le mot ; sortie ≈ 75 % de la durée d'entrée ; pas d'oscillation
141+ décorative (`repeat: -1`, yoyo) ; immobilité de 0,3 à 0,75 s avant un climax ; la timeline doit durer
142+ toute la composition (`tl.to({}, {duration}, 0)`), sinon flash noir.
143+
144+## Phase 2 — Bibliothèque d'inspirations
145+
146+But : une galerie de références de motion (démo, mécanique, prompt) dans laquelle l'utilisateur choisit et
147+annote ce que Daryl doit suivre. Modèle : `editing-os-starter/motion-library/` et
148+`scripts/motion-library/` (import, catégories, planches), `editing-os/lib/selection.mjs`.
149+
150+### 2.1 Données
151+- Base : `editing-os-starter/motion-library/analyse.json` — 270 références analysées (54 pépites,
152+ 159 solides, 57 faibles ; 15 usages : explicatif, data, typo, UI, produit…). Chaque fiche :
153+ `titre, resume, usage, usages, ambiance, mecanique {transitions, rythme, texte, techniques}, niveau,
154+ pourquoi`.
155+- Import porté en Python : démos, posters et prompts depuis julienpocinho.fr et prompt-motion.com
156+ (décodage des morceaux RSC Next.js, voir `import.mjs`). 4 requêtes à la fois au plus.
157+- Planche de 12 images (4×3, 480×270) par démo avec ffmpeg, lue directement depuis l'URL ; vignette = le
158+ JPEG le plus lourd entre 25 et 85 % de la durée (les images noires pèsent presque rien).
159+- Stockage local `data/library/inspirations/` : **contenu de tiers, jamais dans le dépôt** (on ne versionne
160+ que l'importeur).
161+- Références de l'utilisateur : URL ou clip (téléchargement yt-dlp existant) ; Claude regarde la planche et
162+ remplit la fiche « mécanique » au même format.
163+
164+### 2.2 Écran (onglet Inspirations de la page Bibliothèque)
165+- Grille de posters, démo au survol ; filtres usage / niveau / ambiance ; les faibles masqués par défaut.
166+- Fiche : démo, planche, mécanique, prompt d'origine. « Ajouter à ma sélection » avec une note.
167+
168+### 2.3 Lien avec le storyboard
169+- Daryl reçoit la sélection et ses notes (prioritaires), puis l'index par usage ; il cite une référence par
170+ beat avancé, affichée en vignette sur la ligne du beat.
171+- On reprend la mécanique (mouvement, rythme, transitions), jamais l'habillage : la charte reste celle de
172+ l'utilisateur.
173+
174+## Plus tard — styles (design system)
175+Plusieurs chartes au choix par projet (`tokens.css` + `DESIGN.md`), puis des cartes à emplacements de texte
176+(`data-slot` + `maxChars`), rangées par tier (t1 plein écran opaque, t2 transparent qui ne couvre pas le
177+visage) et par usage, avec une registry et un tirage reproductible sans répétition consécutive (voir
178+`editing-os-starter/style-library/GUIDE.md`, `.claude/skills/motion-graphics/`). Le champ `kind` / `place`
179+du storyboard deviendra le choix d'une carte.
180+
181+## Ordre
182+1. Phase 1.1 + 1.2, testées sur un projet réel sans interface.
183+2. Phase 1.3 + 1.4 : utilisable pour de vrai.
184+3. Phase 2.1.
185+4. Phase 2.2 + 2.3.
186+
187+## Décisions (10/10/2026)
188+1. **Vidéo longue uniquement** pour l'instant (les shorts plus tard).
189+2. Densité : reprendre les trois densités des slides (`animations/service.py`, `DENSITIES`) : sobre
190+ (~1 motion / 1 min 30), équilibrée (~1 / 30-45 s), dense (~1 / 15-20 s). Le rythme des reels
191+ d'editing-os (un événement toutes les 1 à 2 s) est trop dense pour une vidéo longue. **« Équilibrée »
192+ par défaut, réglable à chaque génération** (validé).
193+3. **Import complet** des inspirations (démos, posters, prompts des deux sites, en local).
194+
195+## Notes d'outillage (réponses du 10/10/2026)
196+- **Analyser une animation** : editing-os ne décompose pas image par image. ffmpeg tire une planche de
197+ 12 images réparties sur la démo, Claude la regarde (vision) avec le prompt d'origine et écrit la fiche
198+ « mécanique ». Ça capte la composition et les états, pas les courbes ni les timings fins. Pour reproduire
199+ une transition précise : une planche dense autour du moment (8 à 12 images par seconde sur 1 à 2 s),
200+ repéré par détection de changement de plan (`select='gt(scene,0.15)'`).
201+- **Détourage** : CLI HyperFrames, `npx hyperframes remove-background` (modèle u2net_human_seg, ~168 Mo,
202+ local, gratuit). Sortie ProRes 4444 ou WebM VP9 avec alpha. Lent : ~2 images/s en 1080p sur CPU, donc
203+ à réserver aux passages qui en ont besoin. Re-encoder d'abord une source à cadence variable (sinon sujet
204+ dédoublé), et appliquer les mêmes coupes à la vidéo et au détourage. Usages : texte derrière la personne
205+ (on rend vidéo + texte, puis on recolle la personne détourée par-dessus), personne qui dépasse d'une carte.
206+- **Musique et sons** :
207+ - editing-os : un pack de SFX maison nommés par rôle (`whoosh`, `pop`, `click`, `cash`, `impact`,
208+ `riser`, `buzzer`…) avec une table son ↔ animation et un volume par son (`asset-library/sfx/README.md`) ;
209+ la musique via `npx hyperframes media-use resolve --type bgm` (catalogue HeyGen, compte heygen
210+ requis) ; le mixage (ducking, fondus) via le skill `hyperframes-audio`.
211+ - Studio : bibliothèque `data/library/` (musique, sfx), Daryl ne place que des fichiers listés dans
212+ `contexte.md`, gains fixes, pas de ducking.
213+ - À reprendre : nommer les SFX par rôle et donner la table son ↔ animation à Daryl ; un `sfx` par beat
214+ dans le storyboard ; ducking de la musique sous la voix au rendu (`sidechaincompress` ffmpeg) ; le
215+ catalogue HeyGen seulement si l'utilisateur veut un compte de plus.