返回 ppt-master
customize-animations.md
根目录 / skills / ppt-master / workflows / stages / customize-animations.md
1 ---
2 description: Optional post-processing stage for per-slide and per-object animation overrides.
3 ---
4
5 # Customize Animations Stage
6
7 > Optional Generate-PPTX post-processing stage for per-slide or per-object
8 > animation control. Run when `<project_path>/animations.json` already exists,
9 > when the user explicitly asks to customize slide-specific motion, object
10 > order, effects, timing, or reveals, or when the effective Custom Animations
11 > outcome in `design_spec.md §I` is enabled. Deck-wide transitions,
12 > auto-advance, and deck-wide per-element settings without page-specific motion
13 > or an existing sidecar use [`animations.md`](../../references/animations.md)
14 > directly and do not activate this stage. In Quick Generate, the current agent
15 > may activate either path from the request/deck in active context without a
16 > Design Spec or user interaction.
17
18 ## When to Run
19
20 | Condition | Action |
21 |---|---|
22 | Effective Custom Animations outcome in `design_spec.md §I` is enabled | Run this stage after the final SVG quality gate and any enabled speaker-note pass, before Generate Step 7; use §IX suggestions as advice |
23 | User asks for per-slide or per-object animation, reveal order, timing, or effect changes | Run this stage |
24 | `<project_path>/animations.json` already exists | Run this stage to resolve preserve/adjust/replace/suppress intent before export |
25 | §IX contains `Motion suggestion`, but no trigger above is active | Do not run; retain the suggestion as Strategist advice and keep normal export defaults |
26 | No motion request, enabled outcome, or existing sidecar; user only wants the default deck | Do not run; normal export keeps page transitions and no element builds |
27 | No existing sidecar; user only wants deck-wide page transitions, auto-advance, or one per-element object animation policy | Do not run; apply [`animations.md`](../../references/animations.md) with exporter flags such as `-a auto` or `-a emphasis_spin` |
28 | `svg_output/*.svg` is missing | Complete the main Executor phase first |
29
30 **Decision precedence**: latest explicit instruction → final Stage-2 policy →
31 workflow default `false`; provenance stays in Design Spec §I, never the
32 lock. Final Stage-2 `false` blocks creation, not an existing sidecar. Existing
33 sidecars enter this stage; explicit disables follow the table without deletion.
34
35 ---
36
37 ## 1. Resolve Intent and Read Semantic Context
38
39 **Context read**: before editing `animations.json`, read every semantic planning file below that exists.
40
41 | File | Use |
42 |---|---|
43 | `<project_path>/design_spec.md` | Understand each slide's content intent, narrative role, and visual emphasis |
44 | `<project_path>/spec_lock.md` | Confirm page rhythm, layout role, chart/template constraints, and execution contract |
45 | `<project_path>/notes/total.md` or `<project_path>/notes/*.md` | Use speaker flow to tune reveal order, delays, and emphasis |
46
47 **Existing sidecar intent gate**:
48
49 | User intent | Action |
50 |---|---|
51 | Explicit Custom Animations disable | Preserve and validate the sidecar; return `-a none` |
52 | Explicit all-motion disable | Preserve and bypass the sidecar; return `--no-animations` |
53 | Explicit regeneration / rewrite / replacement | Rebuild the semantic grouping plan and replace `animations.json`; the previous choreography is not a constraint |
54 | Explicit adjustment / tuning / repair | Validate first, preserve the existing choreography where its semantic units remain valid, and migrate affected group references after any required regrouping |
55 | Stage activated with an existing sidecar and new §IX suggestions but no user replacement request | Validate first; preserve valid existing choreography and adjust only the affected semantic units |
56 | Existing sidecar with no new motion instruction | Validate and preserve it unchanged; if invalid, repair the owning sidecar/group reference before export |
57 | Ambiguous generation request | Default Generate asks whether to regenerate or modify; Quick Generate decides from the request, visible SVG, and existing sidecar, then continues |
58
59 Unless explicit all-motion disable bypasses it, validate an existing sidecar
60 before deciding to preserve, modify, or suppress object motion:
61
62 ```bash
63 python3 skills/ppt-master/scripts/animation_config.py validate <project_path>
64 ```
65
66 **Hard rule**: semantic files determine both animation intent and animation
67 unit boundaries. The current `svg_output/*.svg` supplies visible content and
68 implementation structure, but its existing `<g>` hierarchy is not accepted as
69 the animation plan merely because it already exists.
70
71 **Optional-context fallback**: these semantic files inform this supporting stage but are not its gate artifacts. If any are absent, state what is missing and proceed with every remaining file plus visible SVG content. If all three context inputs are absent, use only explicit user instructions, visible SVG content, and the resolution rules in [`animations.md`](../../references/animations.md); do not infer detailed choreography beyond what the page itself expresses.
72
73 **Decision ownership — understand, then design**: A §IX `Motion suggestion`
74 expresses the Strategist's communication job and semantic relationship; it
75 neither activates this stage nor locks implementation. Once active, understand
76 that intent, then develop the motion brief from the final SVG's semantic units,
77 visible states, composition, and speaker flow. Do not mechanically map it to
78 groups, effects, order, or timing. Executor may preserve, adapt, simplify,
79 decline, or choose `none`; an unchanged realization is valid and requires no
80 novelty. Explicit user motion requirements bind. Never change page
81 content merely to justify animation.
82
83 **Hard rule — existing visible-layer boundary**: This stage may regroup existing content only under §2 visual equivalence; it MUST NOT create or modify a crop, comparison layer, scrim, lens, hotspot, annotation, or other visible image state to satisfy motion intent. When a required state is missing and ordinary Slide-local authoring can supply it, return to Generate Step 6, rerun the final SVG gate and regenerate notes only when speaker notes are enabled, then resume here. If a structural boundary prevents that repair, simplify a non-binding suggestion to legal existing units, a page transition, or `none`; an explicit requirement follows failure recovery instead of changing structure.
84
85 **No-op is complete**: Evaluate suggestions before regrouping SVG content. If
86 no `animations.json` exists, every page should retain the normal `fade`
87 transition and no object builds, and no explicit user requirement remains
88 unmet, change no SVG, create no sidecar, and return to Generate Step 7. Never
89 author motion merely to expose a capability.
90
91 ---
92
93 ## 2. Rebuild Semantic Motion Units When Needed, Then List IDs
94
95 **Mandatory when object-targeted motion is in scope — content-first grouping
96 audit**: inspect each affected slide's visible content against its communication
97 job and speaker flow before treating any top-level `<g>` as an animation
98 anchor. The affected set is the page named by an adopted suggestion or explicit
99 object-motion request, plus both endpoints of each deterministic Morph pair.
100 Untouched pages need no animation audit. Existing groups are implementation
101 evidence only. Keep a current group unchanged only after confirming that it
102 already represents exactly one audience-facing motion unit or one continuing
103 Morph object. A page-transition-only plan without explicit Morph pairs skips
104 regrouping and group listing.
105
106 | Content condition | Required grouping action |
107 |---|---|
108 | One current group contains several independently narrated rows, cards, steps, claims, or stages | Split it into descriptive direct-root sibling groups, one per motion unit |
109 | One motion unit is scattered across groups or root primitives | Merge or wrap its background, icon, label, value, and supporting text into one direct-root group |
110 | A connector or arrow explains entry into a node or stage | Keep it with the relationship or target unit that makes the connection intelligible |
111 | A hero visual, overview graphic, takeaway, or warning has its own communication role | Give it its own semantic group |
112 | The same semantic object continues across adjacent Morph pages | Isolate each endpoint as one direct-root group and keep both endpoints as compatible object kinds |
113 | Several atoms express one inseparable idea | Keep them together; do not animate the atoms separately |
114 | Page chrome, structural layers, or static framing | Preserve their structure and exclude them from ordinary animation targets |
115
116 **Hard rule — visual equivalence**: regrouping changes object boundaries only.
117 Preserve all visible content, paint order, coordinates, transforms, inherited
118 paint, opacity, clipping, filters, references, and native metadata. Keep
119 rendering-bearing implementation wrappers nested inside the new semantic group
120 when flattening or distributing their attributes could change appearance.
121
122 **Hard rule — structural boundary**: never split or merge across
123 `data-pptx-layer`, `data-pptx-placeholder`, native chart/table carrier, native
124 preset, or imported logical-object boundaries. Structural/static objects remain
125 non-animatable. Ordinary Slide-local content groups follow
126 [`shared-standards-core.md`](../../references/shared-standards-core.md) §4.3:
127 every visible direct-root group has a descriptive unique `id` and positive
128 root-coordinate `data-pptx-bounds`; nested implementation groups carry no
129 bounds.
130
131 **Forbidden — group-list-first choreography**:
132
133 - Choosing effects or order from the pre-existing `list-groups` output before the content-first audit
134 - Keeping a coarse wrapper only because it already has an `id`
135 - Splitting one semantic idea into individual shapes or text lines to increase animation count
136 - Merging unrelated ideas to reduce animation count
137 - Adding animation-specific `data-*` attributes to SVG
138
139 There is no target group count. Granularity follows the page's actual claims,
140 comparisons, sequence, causality, and narration beats.
141
142 After any regrouping, rerun the final SVG quality gate because `svg_output/`
143 changed. Use the owning route's checker form; Quick Generate must add its
144 lockless profile flag:
145
146 ```bash
147 python3 skills/ppt-master/scripts/svg_quality_checker.py <project_path> --stage final --json
148 # Quick Generate: insert --quick-generate before --stage.
149 ```
150
151 Then list the **post-regroup** anchors:
152
153 ```bash
154 python3 skills/ppt-master/scripts/animation_config.py list-groups <project_path>
155 ```
156
157 Output is one line per slide: `<slide_basename>: id1, id2, id3`. Default chrome
158 groups (`bg` / `*-header` / `*-footer` / `*-decor` / `nav` / `watermark` /
159 `logo` / `pagenumber`) are excluded. This post-regroup list is the source of
160 truth when planning §3 and editing §4; never invent a slide or group key.
161
162 An explicit sidecar entry may override only the marker-free legacy id-name
163 heuristic. A group carrying `data-pptx-layer` or an explicit static
164 role/placeholder marker can never animate, even when it is named explicitly.
165
166 If `animations.json` does not exist and a starting file is useful, scaffold
167 only after semantic regrouping:
168
169 ```bash
170 python3 skills/ppt-master/scripts/animation_config.py scaffold <project_path>
171 ```
172
173 The scaffold is neutral: its default object effect is `none`, and listed groups
174 may remain empty `{}` placeholders until adopted. Creating it does not select
175 generic entrance animation. Do not read the full scaffold unless it is needed
176 as an editing starting point.
177
178 ---
179
180 ## 3. Plan Slide and Object Motion
181
182 **Mandatory**: plan the requested motion layers for each affected slide before
183 editing `animations.json`. A local object-animation request does not require a
184 deck-wide transition review.
185
186 | Layer | Config path | Use |
187 |---|---|---|
188 | Page transition | `defaults.transition` or `slides.<slide>.transition` | Control how one slide enters from the previous slide |
189 | Deterministic Morph pair | `slides.<destination>.morph` | Bind one real source group to one real destination group when semantic identity continues across adjacent slides |
190 | Page animation defaults | `defaults.animation` or `slides.<slide>.animation` | Control the default object-animation behavior for animated groups on a slide |
191 | Object lifecycle | `slides.<slide>.groups.<group_id>` | Assign one legacy effect row or an ordered `effects[]` sequence to a real SVG motion unit |
192
193 **Per-affected-page motion brief**: classify the communication job—including
194 none—and each unit's lifecycle. Choose only the required transition, effect,
195 order, timing, and one dominant Start rhythm; mix modes or add emphasis and
196 exit only for a distinct job with a restrained, fitting effect. Read
197 `design_spec.md`, `spec_lock.md`, speaker notes, and SVG group ids for role,
198 rhythm, order, and target validity.
199
200 **Mandatory — select from meaning, not catalog coverage**: run the
201 page-relationship and lifecycle selection playbooks in
202 [`animations.md`](../../references/animations.md) §3 and §4 before choosing any
203 specific effect. Their candidates are recall aids, not coverage targets; this
204 stage binds the selected duties to real targets.
205
206 **Title motion decision**: when a title participates, classify its lifecycle,
207 then choose immediate, delayed, synchronized, post-hero, or narration-cued
208 timing from slide intent. Use the sidecar override for a marker-free legacy
209 chrome-like id; repair an incorrect explicit structural/static marker before
210 animating it.
211
212 **Default — inherit unaffected motion layers (may override when the page's
213 communication job requires it)**: a custom object-animation pass may leave the
214 page transition and every untouched page on exporter or sidecar defaults. Add a
215 slide-specific `transition` only when the affected page needs one; never add
216 variation for coverage.
217
218 **Timing guidance**: use shorter motion for dense/repeated scan content and
219 longer motion for conceptual pivots, hero diagrams, section boundaries, and
220 final takeaways. Uniform timing is valid when it fits the requested style.
221
222 **Reference — not a constraint: motion judgment.** Decide the communication
223 job, lifecycle, tone, audience order, and whether direction carries meaning
224 before using geometry. If motion adds no clarity or intended feeling, classify
225 the unit `static`; use `none`, `entrance_appear`, or `entrance_fade` only when
226 that result matches the lifecycle. Layout direction alone does not require
227 special motion; variation follows a real content/tone change, never a quota.
228
229 ### 3.1 Supported Page Transitions
230
231 Use one of the 48 canonical native effects from the complete shared registry in
232 [`animations.md`](../../references/animations.md) §3. It covers all current
233 PowerPoint Subtle, Exciting, and Dynamic Content gallery effects. The eight old
234 names are readable only as compatibility inputs; do not write them in new
235 plans or sidecars. They normalize to a canonical effect plus native
236 `effect_options` before writing. `none` removes the visual page transition
237 while allowing timed advance to remain.
238
239 **Transition fields**:
240
241 | Field | Behavior |
242 |---|---|
243 | `effect` | One supported page transition effect; `none` removes only the visual effect |
244 | `effect_options` | Optional object containing only the selected native effect's PowerPoint Effect Options; requires an explicit `effect` |
245 | `duration` | Finite transition duration in seconds; must be greater than zero |
246 | `auto_advance` | Optional finite non-negative seconds before automatic slide advance; click remains enabled, and this field is valid with `effect: none` |
247
248 Run
249 `python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition <effect>`
250 before authoring Effect Options. Never infer that one effect accepts another
251 effect's direction, shape, pattern, or boolean fields.
252
253 For a cross-slide object continuation that must not depend on PowerPoint's
254 automatic matching, put one explicit `morph` block on the destination slide.
255 Its `from` slide must be the immediately preceding exported SVG; each stable
256 pair key binds one source direct-root group id to one destination direct-root
257 group id. The exporter supplies PowerPoint's `!!` prefix. Use Morph by object;
258 word/character Morph does not accept this object-pair contract.
259
260 ### 3.2 Supported In-Slide Animations
261
262 Use the 203 canonical PowerPoint-native keys: 53 `entrance_*`, 33
263 `emphasis_*`, 64 `path_*`, and 53 `exit_*`. Run
264 `python3 skills/ppt-master/scripts/pptx_animations.py --list` for the exact
265 categorized names. Each key preserves PowerPoint's complete authored behavior
266 tree. Media-only commands remain in the audio/video workflows.
267
268 | Choice | Behavior |
269 |---|---|
270 | `entrance_*` / `emphasis_*` / `path_*` / `exit_*` | Select one explicit canonical PowerPoint object effect |
271 | `auto` | Generic `enter` only: map content roles to canonical entrances; image-like ids use a richer canonical pool |
272 | `mixed` | Generic `enter` only: cycle 16 canonical entrance presets by group order |
273 | `random` | Generic `enter` only: select deterministically from the same canonical entrance pool |
274 | `none` | Exclude the object or slide from in-slide animation |
275
276 The 29 old short names remain readable only as compatibility inputs; do not use
277 them in new plans or sidecars. All Fly direction names normalize to
278 `entrance_fly`, all Wipe direction names normalize to `entrance_wipe`, and the
279 other old names normalize to their matching `entrance_*` preset. `cut`
280 normalizes to `entrance_appear`. Compatibility Fly/Wipe aliases preserve their
281 direction as `effect_options.direction`; legacy `wheel` preserves its historical
282 four-spoke amount.
283
284 `auto`, `mixed`, and `random` never choose emphasis, motion-path, or exit
285 effects implicitly. Use them only after classifying a unit as a generic
286 `enter`; select an explicit canonical key for every adopted `emphasize`,
287 `move`, or `exit` duty.
288
289 **Hard rule — explicit semantic choreography**: When an adopted plan depends
290 on a specific lifecycle, relationship, or order, target its real groups with
291 explicit canonical effects and order; do not delegate those material decisions
292 to `auto`, `mixed`, or `random`. Those modes remain valid only when generic
293 entrance treatment is sufficient.
294
295 **Start modes**:
296
297 | Trigger | Behavior |
298 |---|---|
299 | `after-previous` | Default click-free cascade |
300 | `with-previous` | One coordinated beat together |
301 | `on-click` | Controlled semantic reveal |
302
303 ---
304
305 ## 4. Edit `animations.json`
306
307 **Hard rule — sparse overrides reference real targets**: write only affected
308 slides and only fields that differ from exporter or sidecar defaults. An
309 unlisted SVG inherits the resolved deck-wide settings; a listed slide may
310 contain only `transition`, `animation`, `groups`, or `morph` fields that it
311 actually overrides. `defaults` is optional and belongs only to intentional
312 deck-wide settings. Group-level overrides remain opt-in. Chrome groups stay out
313 (the exporter pins them to `none` by default). Name a legacy chrome-like id only
314 when the user explicitly wants that content animated and the SVG has no
315 explicit structural layer, role, or placeholder marker.
316
317 **Forbidden**:
318
319 - Referencing a slide that does not exist in `svg_output/`
320 - Referencing a missing, ambiguous, or structural group
321 - Enumerating every content group in a slide just to restate the slide-level default effect
322 - Listing a group with `data-pptx-layer` or an explicit static role/placeholder marker
323 - Listing a legacy chrome-like id without an explicit, reviewed intent to override the name heuristic
324
325 | Field | Behavior |
326 |---|---|
327 | `transition.effect` | Slide-specific page transition effect |
328 | `transition.effect_options` | Effect-specific native PowerPoint options; requires an explicit slide-specific `transition.effect` |
329 | `transition.duration` | Slide-specific page transition duration |
330 | `morph.from` | Immediately preceding SVG stem for an explicit deterministic Morph transition |
331 | `morph.pairs.<key>.from` / `.to` | Unique source/destination direct-root group ids that receive the shared PowerPoint name `!!<key>` |
332 | `animation.effect` | Slide-specific default object animation effect |
333 | `animation.duration` | Slide-specific default object schedule duration |
334 | `animation.stagger` | Slide-specific delay between object animation rows |
335 | `animation.trigger` | Slide-specific start mode |
336 | `groups.<id>.effects` | Non-empty ordered array for a multi-duty lifecycle; every row explicitly names `effect`, and `effects` cannot coexist with legacy single-effect fields in the same group block |
337 | `groups.<id>.effect` | Backward-compatible single-row form: one canonical native effect, `auto`, `mixed`, `random`, or `none`; old names are read-only compatibility inputs |
338 | `effects[].trigger` / legacy `trigger` | Row-specific Start mode; omitted values inherit `animation.trigger` |
339 | `order` | Page-wide order for ordinary rows; ties retain SVG group order and then `effects[]` index. `trigger_shape` rows keep relative order in separate interactive sequences; SVG layer order never changes |
340 | `delay` | Row-specific seconds added to the resolved Start or shape trigger |
341 | `duration` | Per-row schedule duration in seconds; scalable native behavior trees keep their internal timing ratios, while `entrance_appear` and instantaneous native presets retain their PowerPoint-authored duration and use this value for subsequent `after-previous` spacing |
342 | `effect_options` | Effect-specific PowerPoint parameters; requires an explicit canonical `effect` in the same legacy block or `effects[]` row |
343 | `trigger_shape` | Different top-level group id for native **On Click of**; row-only and not inherited. It implies `on-click`; an explicit row `trigger` may accompany it only when also `on-click` |
344 | `repeat_count` / `repeat_duration` | Repeat count or total repeat span; mutually exclusive |
345 | `auto_reverse`, `rewind` | Reverse each cycle and/or restore the pre-animation state |
346 | `accelerate`, `decelerate`, `bounce_end` | `0..1` timing ratios; acceleration plus deceleration must not exceed `1`; bounce requires an interpolated effect and cannot combine with deceleration |
347 | `restart` | `always`, `when-not-active`, or `never` |
348 | `after_effect` | `none`, `dim` with `color`, `hide`, or `hide-on-next-click` |
349 | `sound` | Project-relative or absolute `.m4a`, `.mp3`, or `.wav` path |
350
351 **Hard rule — one group representation**: A populated
352 `groups.<id>` object uses either the backward-compatible single-effect fields
353 or `effects[]`, never both. `effects[]` must contain at least one object, and
354 every row explicitly names `effect`. An untouched scaffold `{}` is a neutral
355 placeholder. Omitted row duration, Start, timing/completion controls, and sound
356 inherit the resolved slide animation values exactly as the legacy form does.
357
358 `effect_options` may contain `direction`, `amount`, `color`, `font_name`,
359 `relative`, or `size`, but validation permits only fields supported by the
360 selected effect. Before writing a parameterized effect, run
361 `python3 skills/ppt-master/scripts/pptx_animations.py --describe
362 <canonical_effect>` and use the returned values exactly. `duration` owns
363 PowerPoint Speed; `accelerate`/`decelerate` own smooth start/end, so do not
364 invent duplicate fields. Change Font's `font_name` is one concrete
365 target-installed PowerPoint face, never a CSS font stack.
366
367 Use the coherent multi-category `effects[]` example in
368 [`animations.md`](../../references/animations.md) §2. Its static frame stays
369 unlisted while one real unit runs enter → move → emphasize → exit. Keep the
370 legacy object for one-row overrides; never convert old sidecars mechanically.
371
372 Use the complete two-slide deterministic Morph example in
373 [`animations.md`](../../references/animations.md) §2.1; do not copy the source
374 group into the destination slide's `groups` block merely to establish identity.
375
376 **Forbidden — SVG pollution**: do not add `data-*` animation attributes to SVG files. Animation customization belongs in `animations.json`.
377
378 ---
379
380 ## 5. Validate and Return to Generate Export
381
382 When `animations.json` was newly created or changed after the §1 validation,
383 run:
384
385 ```bash
386 python3 skills/ppt-master/scripts/animation_config.py validate <project_path>
387 ```
388
389 After validation succeeds, return to the owning export path:
390
391 - Default Generate → [`generate-pptx.md`](../generate-pptx.md) Step 7.1, which
392 owns note splitting, `finalize_svg.py`, native export, and the published
393 postflight receipt.
394 - Quick Generate → [`quick-generate.md`](../profiles/quick-generate.md) §4,
395 which skips finalization and exports with `--quick-generate`.
396
397 Both exporters read `<project_path>/animations.json` automatically. If §2
398 changed `svg_output/`, complete the owning route's required final SVG quality
399 rerun before returning. Do not finalize or export independently from this
400 stage.
401
402 **Validation**: The later native export must reflect the per-slide and
403 per-object overrides. `--animation none` still disables all per-element
404 animation and overrides `animations.json`. Unknown animation
405 effects/modes/triggers; unsupported effect options; incompatible, boolean,
406 non-finite, or out-of-range timing parameters; non-positive durations; negative
407 delay/stagger; invalid order; missing slides/groups; and structural-layer
408 targets fail validation. Transition validation remains strict. None of these
409 failures substitutes a fallback effect or silently drops a requested target.
410 Deterministic Morph also rejects non-adjacent source slides, missing or
411 ambiguous direct-root groups, conflicting or undeclared shared keys, non-object
412 Morph, and any target that does not remain one compatible Slide-local object
413 after structure processing.
414
415 Generate Step 7 export reads back row order, including repeated rows targeting
416 one shape, trigger, target, resolved effect, duration, offset, timing placement,
417 IDs, and shape references. Narration
418 preserves these rows. Direct-PPTX routes fingerprint and preserve source object
419 animation; they never author it. See
420 [`pptx-animations.md`](../../scripts/docs/pptx-animations.md).
421
422 ### 5.1 Optional Video Motion Handoff
423
424 When a downstream video renderer will enhance the deck, have Generate Step 7.3
425 append `--conversion-trace`. After that final export succeeds, derive the motion
426 plan from its resolved trace:
427
428 ```bash
429 python3 skills/ppt-master/scripts/video_motion_plan.py \
430 <project_path>/validation/<output_stem>.trace.json \
431 -o <project_path>/validation/video_motion_plan.json \
432 --style adaptive \
433 --force
434 ```
435
436 For narrated output, use the final `--recorded-narration` trace. The video plan
437 locks identity, effect, direction, order, bounds, and timing; it may refine
438 renderer parameters but cannot replace the source effect. See
439 [`video-motion-plan.md`](../../scripts/docs/video-motion-plan.md).
440
441 ---
442
443 ## ✅ Customize Animations Complete
444
445 - [x] Applicable semantic context and motion intent were resolved
446 - [x] Adopted object targets use real post-regroup SVG ids when object motion is in scope
447 - [x] Sparse `animations.json` overrides are valid when present; a no-op path creates none
448 - [x] Any regrouped SVG passed the final quality gate
449 - [x] Control returned to Generate Step 7 for preview, export, read-back, and package validation
450 - [x] Any requested video plan waits for the final resolved conversion trace
451
451 lines MARKDOWN