ima2-gen 2.0.15 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +30 -0
  2. package/bin/commands/skill.js +336 -17
  3. package/bin/ima2.js +22 -2
  4. package/bin/lib/doctor-checks.js +6 -4
  5. package/config.js +1 -0
  6. package/docs/CLI.md +25 -3
  7. package/docs/PROMPT_STUDIO.ko.md +29 -0
  8. package/docs/PROMPT_STUDIO.md +31 -0
  9. package/docs/migration/runtime-test-inventory.md +7 -1
  10. package/lib/agentImageVideoGen.js +8 -0
  11. package/lib/agentQueueStore.js +36 -10
  12. package/lib/agentQueueWorker.js +79 -7
  13. package/lib/agentRuntime.js +2 -0
  14. package/lib/assetLifecycle.js +40 -8
  15. package/lib/canvasVersionStore.js +86 -0
  16. package/lib/cardNewsGenerator.js +37 -3
  17. package/lib/cardNewsJobStore.js +10 -0
  18. package/lib/cardNewsManifestStore.js +6 -12
  19. package/lib/cardNewsPath.js +25 -0
  20. package/lib/db.js +2 -0
  21. package/lib/generatePipeline.js +474 -0
  22. package/lib/generationInputValidation.js +32 -0
  23. package/lib/grokImageCore.js +18 -1
  24. package/lib/historyIndex.js +11 -4
  25. package/lib/historyList.js +3 -0
  26. package/lib/imageMetadata.js +3 -0
  27. package/lib/inflight.js +30 -3
  28. package/lib/multimodePipeline.js +462 -0
  29. package/lib/nodeGeneration.js +440 -0
  30. package/lib/nodeValidation.js +23 -0
  31. package/lib/oauthProxy/generators.js +3 -246
  32. package/lib/oauthProxy/multimodeGenerators.js +251 -0
  33. package/lib/routeHelpers.js +9 -2
  34. package/package.json +2 -2
  35. package/routes/agent.js +4 -4
  36. package/routes/canvasVersions.js +21 -1
  37. package/routes/cardNews.js +2 -1
  38. package/routes/edit.js +25 -9
  39. package/routes/events.js +5 -1
  40. package/routes/generate.js +2 -481
  41. package/routes/keys.js +31 -39
  42. package/routes/multimode.js +2 -502
  43. package/routes/nodes.js +3 -448
  44. package/routes/video.js +12 -3
  45. package/routes/videoExtended.js +19 -4
  46. package/server.js +53 -1
  47. package/skills/ima2/SKILL.md +204 -0
  48. package/skills/ima2-front/SKILL.md +611 -0
  49. package/skills/ima2-front/references/a11y-patterns.md +134 -0
  50. package/skills/ima2-front/references/aesthetics.md +327 -0
  51. package/skills/ima2-front/references/anti-slop.md +241 -0
  52. package/skills/ima2-front/references/asset-requirements.md +431 -0
  53. package/skills/ima2-front/references/brand-asset-sourcing.md +122 -0
  54. package/skills/ima2-front/references/color-system.md +132 -0
  55. package/skills/ima2-front/references/consistency-locks.md +20 -0
  56. package/skills/ima2-front/references/crud-ui.md +53 -0
  57. package/skills/ima2-front/references/dropdown-layer.md +110 -0
  58. package/skills/ima2-front/references/i18n-global.md +104 -0
  59. package/skills/ima2-front/references/iterative-design.md +90 -0
  60. package/skills/ima2-front/references/korea-2026.md +174 -0
  61. package/skills/ima2-front/references/layout-discipline.md +161 -0
  62. package/skills/ima2-front/references/liquid-glass.md +181 -0
  63. package/skills/ima2-front/references/logo-sections.md +194 -0
  64. package/skills/ima2-front/references/mobile-ux.md +144 -0
  65. package/skills/ima2-front/references/performance-budget.md +106 -0
  66. package/skills/ima2-front/references/preflight-full.md +58 -0
  67. package/skills/ima2-front/references/product-density.md +53 -0
  68. package/skills/ima2-front/references/prototype-variants.md +54 -0
  69. package/skills/ima2-front/references/reference-capture.md +120 -0
  70. package/skills/ima2-front/references/responsive-viewport.md +139 -0
  71. package/skills/ima2-front/references/seo-baseline.md +123 -0
  72. package/skills/ima2-front/references/soft-3d-asset-gates.md +70 -0
  73. package/skills/ima2-front/references/stacks/astro.md +204 -0
  74. package/skills/ima2-front/references/stacks/mobile-native.md +281 -0
  75. package/skills/ima2-front/references/stacks/nextjs.md +219 -0
  76. package/skills/ima2-front/references/stacks/react.md +264 -0
  77. package/skills/ima2-front/references/stacks/svelte.md +235 -0
  78. package/skills/ima2-front/references/stacks/vanilla.md +226 -0
  79. package/skills/ima2-front/references/theme-switching.md +82 -0
  80. package/skills/ima2-front/references/top-bar.md +126 -0
  81. package/skills/ima2-front/references/typography-wrapping.md +270 -0
  82. package/skills/ima2-front/references/ux-writing-ko.md +62 -0
  83. package/skills/ima2-front/references/visual-verification.md +102 -0
  84. package/skills/ima2-uiux/SKILL.md +477 -0
  85. package/skills/ima2-uiux/references/anti-slop-judgment.md +39 -0
  86. package/skills/ima2-uiux/references/color-system.md +80 -0
  87. package/skills/ima2-uiux/references/design-isms.md +194 -0
  88. package/skills/ima2-uiux/references/design-read-example.md +33 -0
  89. package/skills/ima2-uiux/references/design-system-bootstrap.md +133 -0
  90. package/skills/ima2-uiux/references/favicon-logo.md +355 -0
  91. package/skills/ima2-uiux/references/form-patterns.md +118 -0
  92. package/skills/ima2-uiux/references/intent-discovery-ladder.md +86 -0
  93. package/skills/ima2-uiux/references/korean-design-vocabulary.md +52 -0
  94. package/skills/ima2-uiux/references/layout-macrostructures.md +54 -0
  95. package/skills/ima2-uiux/references/logo-trust-sections.md +96 -0
  96. package/skills/ima2-uiux/references/mobile-native-ux.md +207 -0
  97. package/skills/ima2-uiux/references/product-personalities.md +118 -0
  98. package/skills/ima2-uiux/references/responsive-nav.md +66 -0
  99. package/skills/ima2-uiux/references/typography-line-breaks.md +193 -0
  100. package/skills/ima2-uiux/references/ux-preflight.md +65 -0
  101. package/skills/ima2-uiux/references/ux-states.md +197 -0
  102. package/skills/ima2-uiux/references/visual-hierarchy.md +115 -0
  103. package/ui/dist/.vite/manifest.json +13 -13
  104. package/ui/dist/assets/AgentWorkspace-CtYt4SF5.js +3 -0
  105. package/ui/dist/assets/{CardNewsWorkspace-Cdxn1ohU.js → CardNewsWorkspace-DN5cVqG5.js} +1 -1
  106. package/ui/dist/assets/GenerationRequestLogPanel-DnmUQdKR.js +1 -0
  107. package/ui/dist/assets/{NodeCanvas-C67sLboA.js → NodeCanvas-CxpfIBI0.js} +1 -1
  108. package/ui/dist/assets/PromptBuilderPanel-C2R3ObtR.js +2 -0
  109. package/ui/dist/assets/{PromptImportDialog-DeQXsEEv.js → PromptImportDialog-BIxz_yEx.js} +2 -2
  110. package/ui/dist/assets/PromptImportDiscoverySection-BQTlPMME.js +1 -0
  111. package/ui/dist/assets/PromptImportFolderSection-Ds_Th9O3.js +1 -0
  112. package/ui/dist/assets/{PromptLibraryPanel-Db3xEPM_.js → PromptLibraryPanel-Rs4l45pV.js} +2 -2
  113. package/ui/dist/assets/{SettingsWorkspace-BDk_1W-V.js → SettingsWorkspace-p1AZ6uT9.js} +1 -1
  114. package/ui/dist/assets/index-0-_vgFGs.js +4 -0
  115. package/ui/dist/assets/index-Dm3pFxV4.js +23 -0
  116. package/ui/dist/assets/index-J8yDF3Ch.css +1 -0
  117. package/ui/dist/index.html +2 -2
  118. package/ui/dist/assets/AgentWorkspace-DAg_7zpY.js +0 -3
  119. package/ui/dist/assets/GenerationRequestLogPanel-C_qvEUi2.js +0 -1
  120. package/ui/dist/assets/PromptBuilderPanel-DjvVdAie.js +0 -2
  121. package/ui/dist/assets/PromptImportDiscoverySection-CrwyUKYI.js +0 -1
  122. package/ui/dist/assets/PromptImportFolderSection-CToGMqYE.js +0 -1
  123. package/ui/dist/assets/index-2oG6in1i.css +0 -1
  124. package/ui/dist/assets/index-CoxMOXAU.js +0 -23
  125. package/ui/dist/assets/index-p8egnGHk.js +0 -4
@@ -23,6 +23,11 @@ Start by discovering the local package and running server state:
23
23
  ```bash
24
24
  ima2 skill
25
25
  ima2 skill --json
26
+ ima2 skill ls # list all skills (core, front, uiux)
27
+ ima2 skill install --dir <path> # install skills to agent's skill directory
28
+ ima2 skill install --tmp # install to temp dir (ephemeral fallback)
29
+ ima2 skill front refs # list frontend reference modules
30
+ ima2 skill front ref motion # load one reference module
26
31
  ima2 capabilities --json
27
32
  ima2 defaults --json
28
33
  ima2 ping
@@ -110,6 +115,25 @@ For dense or important text, specify:
110
115
  - visual style;
111
116
  - whether extra readable text is forbidden.
112
117
 
118
+ OpenAI's prompting guide additionally recommends: put literal text **in quotes
119
+ or ALL CAPS**, state typography (font style, size, color, placement) as
120
+ explicit constraints, and for exact copy demand it verbatim. The strongest
121
+ official pattern is a dedicated text block:
122
+
123
+ ```text
124
+ Poster headline (EXACT, verbatim, no extra characters):
125
+ "Fresh and clean"
126
+ Typography: bold sans-serif, high contrast, centered, clean kerning.
127
+ Ensure the text appears once and is perfectly legible.
128
+ ```
129
+
130
+ For tricky words such as brand names or uncommon spellings, spell them out
131
+ letter-by-letter to improve character accuracy. Use `medium` or `high` quality
132
+ whenever the image contains small text, dense panels, or multiple fonts. When
133
+ localizing an existing image, translate the visible text verbatim, add no new
134
+ words, and preserve everything else — layout, imagery, hierarchy — without
135
+ reflowing the design.
136
+
113
137
  GPT Image 2 can generate both stylized and realistic outputs. State the style
114
138
  directly, for example:
115
139
 
@@ -134,6 +158,33 @@ prompts, but a detailed prompt still produces far better results than relying
134
158
  on auto-augmentation alone. For production assets, prefer `--mode direct` with
135
159
  a fully-specified prompt.
136
160
 
161
+ ### Structured Prompt Contract
162
+
163
+ Detailed is not enough — the prompt must be **structured**. OpenAI's official
164
+ gpt-image prompting guide recommends composing prompts in a consistent field
165
+ order — **scene/background → subject → key details → constraints** — and using
166
+ labeled segments or line breaks instead of one long paragraph for complex
167
+ requests. OpenAI's own showcase prompts use labeled blocks such as `Context`,
168
+ `Characters`, and `Composition`. Apply these rules to every agent-authored
169
+ prompt:
170
+
171
+ - **Write labeled sections, not a wall of prose.** Long prompts are fine; an
172
+ unstructured long prompt is not — it becomes impossible to iterate on.
173
+ - **Order fields by priority.** Scene-first is the official default; lead with
174
+ the subject when identity or product fidelity dominates. Field order is a
175
+ priority signal to the model, not a fixed syntax.
176
+ - **Bind attributes locally.** Keep each object's color, material, pose, count,
177
+ and position in the same sentence as the object, and state spatial
178
+ relationships explicitly (foreground/background, left/right, behind, facing,
179
+ closest to camera).
180
+ - **Every sentence must change pixels.** State aspect intent, exact hex colors,
181
+ and transparent background needs directly; cut decorative filler words that
182
+ describe nothing visible.
183
+ - **Do not wrap prompts in JSON.** Structured fields are an authoring tool;
184
+ render them as labeled natural-language sections. Vendors that support JSON
185
+ prompts (e.g. FLUX) document that JSON and prose are understood equally well
186
+ — JSON buys automation, not quality.
187
+
137
188
  ### Required Spec Fields
138
189
 
139
190
  Every agent-authored prompt MUST include all applicable fields. Omit a field
@@ -165,6 +216,27 @@ Avoid: <explicit negative constraints>
165
216
  | "logo on white" | "centered geometric mark: two interlocking triangles forming a hexagonal negative space, flat #1a1a2e on #ffffff, no gradients, strong silhouette at 32px, generous padding" |
166
217
  | "a dashboard screenshot" | "realistic SaaS dashboard UI: top nav with avatar, left sidebar with 6 nav items, main area showing a line chart (3 series, 12 months) and a 4-column data table with 8 rows, light theme, Inter font, compact density" |
167
218
 
219
+ ### Prompt Anti-Patterns
220
+
221
+ These patterns are documented failure modes; reject them when authoring or
222
+ reviewing prompts:
223
+
224
+ | Anti-pattern | Why it fails | Do instead |
225
+ |---|---|---|
226
+ | Keyword soup (`beautiful, stunning, 8k, trending`) | Comma-separated tag piles are a documented anti-pattern for natural-language image models | Structured narrative sentences: subject + attributes + relations |
227
+ | Unmotivated quality tokens (`masterpiece`, `8K`, `ultra-detailed`) | OpenAI's guide: lens, framing, and lighting language is more reliable for realism than generic quality tokens | Name the look: `shallow depth of field`, `soft window light from the left`, `editorial photography` |
228
+ | Trusting precision specs (`85mm f/1.2`, `5600K`) | Official guidance: detailed camera specs may be interpreted loosely — they are look cues, not optical simulation | Prefer perceptual terms: `medium close-up`, `eye level`, `warm tungsten mood`; keep mm/Kelvin only as style hints |
229
+ | Contradictory constraints (`minimalist` + 12 required objects) | Conflicting demands make the model silently drop some of them | Resolve conflicts before generating; one intent per field |
230
+ | Rewriting everything each iteration | Loses working invariants, causes drift | Change ONE variable per pass, restate invariants |
231
+
232
+ **Negative constraints are model-specific.** For GPT Image, write exclusions
233
+ as plain prose inside the prompt — `No extra text, no logos, no watermark` —
234
+ this is the officially recommended form; there is no separate negative-prompt
235
+ parameter. Do not copy diffusion-style negative lists (`wall, frame`) into
236
+ GPT Image prompts; that syntax belongs to models with a dedicated negative
237
+ field (e.g. Imagen), where instruction words like "no/don't" are in turn
238
+ discouraged.
239
+
168
240
  ### Quality and Size Selection
169
241
 
170
242
  | Asset Purpose | Quality | Size | Notes |
@@ -179,16 +251,62 @@ Avoid: <explicit negative constraints>
179
251
  | Game environment concept | `high` | `1792x1024` or `2048x1152` | Wide cinematic |
180
252
  | Storyboard (for i2v) | `high` | `1024x1024` | 3x3 grid, square |
181
253
 
254
+ ### Cutout Assets and Background Strategy
255
+
256
+ GPT Image 2 does not reliably produce true transparent (alpha) backgrounds.
257
+ Use the solid-background-then-remove strategy for cutout assets:
258
+
259
+ **Generate on a pure solid background:**
260
+ - **Black** (`#000000`) for reflective/metallic/glass subjects
261
+ - **White** (`#ffffff`) for dark/matte/opaque subjects
262
+ - **Brand color** when the target page background is known
263
+
264
+ State the exact hex and ban AI additions: "PURE SOLID BLACK background hex
265
+ #000000. No checkerboard, no transparency pattern, no gradient, no floor plane,
266
+ no shadow, no vignette." Use `--mode direct`.
267
+
268
+ ```bash
269
+ ima2 gen "3D chrome splash on PURE SOLID BLACK background hex #000000. \
270
+ No gradient, no floor, no shadow, no vignette." \
271
+ --quality high --size 1024x1024 --mode direct -o splash.png
272
+ ```
273
+
274
+ **Remove background after generation:**
275
+ - CSS `mix-blend-mode: screen` (black bg on light page)
276
+ - CSS `mix-blend-mode: multiply` (white bg on dark page)
277
+ - ima2 Canvas Mode background cleanup (export with alpha or matte)
278
+ - `ima2 edit asset.png --prompt "remove the background, keep only the subject"`
279
+ - Programmatic: `sharp` / ImageMagick / `rembg`
280
+
281
+ **Anti-pattern:** requesting "transparent background" or "PNG with alpha" in the
282
+ prompt — the model often produces a fake checkerboard burned into the image.
283
+
182
284
  ### Korean Text in Images
183
285
 
184
286
  When generating images with Korean text:
185
287
  - Write the exact Korean string in quotes: `"오늘의 추천"`, not "some Korean text"
288
+ - Describe the scene in English and keep only the visible Hangul string in
289
+ Korean: `A clean summer poster with the exact Korean headline "여름 축제"`.
290
+ Practitioner testing found all-Korean prompts produced garbled Hangul while
291
+ English prompts with a quoted Korean string rendered correctly (heuristic,
292
+ not a guarantee)
293
+ - Start with short, label-like strings (a headline, a button) before
294
+ attempting body copy; Hangul glyph complexity makes long dense text the
295
+ most failure-prone case
186
296
  - Specify font style explicitly: `고딕체 (Gothic/Sans-serif)` or `명조체 (Myeongjo/Serif)`
187
297
  - Specify placement (top-center, bottom-left) and approximate size relative to the canvas
188
298
  - For mixed Korean + English, specify which script appears where and in what hierarchy
189
299
  - After generation, always inspect the result with `view_image` — garbled or
190
300
  substituted Hangul is common and must be caught before use
191
301
  - For critical Korean text, generate 2-4 candidates (`-n 4`) and pick the cleanest render
302
+ - If a render is right except for the text, do a targeted `ima2 edit` pass that
303
+ restates the exact string and changes only the text region; if spelling still
304
+ will not stabilize after a couple of passes, stop retrying
305
+ - For legally or commercially exact Korean copy (packaging, UI, contracts),
306
+ the reproducible production path is: generate the image with a reserved
307
+ empty text area (`no text` in that region), then composite real type with an
308
+ actual Korean font in an editor or code. Korean text failure is a
309
+ cross-model limitation, not an ima2-specific one
192
310
 
193
311
  ### Multi-Candidate Strategy
194
312
 
@@ -212,6 +330,9 @@ Do not blindly use the first result.
212
330
  - On the next pass, make ONE targeted change and re-specify all constraints.
213
331
  Do not rewrite the entire prompt from scratch.
214
332
  - Repeat invariants every iteration to prevent drift.
333
+ - This mirrors the official guidance: start from a clean baseline, iterate
334
+ with small single-variable follow-ups instead of overloading one prompt,
335
+ and when a detail drifts, restate it explicitly — never assume it persists.
215
336
  - If the model consistently fails on a detail, try rephrasing, breaking the
216
337
  request into a base generation + `ima2 edit` pass, or switching `--mode`.
217
338
 
@@ -283,6 +404,66 @@ ima2 edit input.png --prompt "make the object blue while preserving composition"
283
404
 
284
405
  Do not use positional edit prompts. `ima2 edit` requires `--prompt`.
285
406
 
407
+ ### Structured Edit Brief
408
+
409
+ OpenAI's official edit pattern is `"change only X"` + `"keep everything else
410
+ the same"` — an edit prompt does not need to re-describe the whole final
411
+ image, but it must make the delta and the invariants explicit. Author every
412
+ edit prompt as a brief:
413
+
414
+ ```text
415
+ Desired result: <one sentence describing the edited image's final state>
416
+ Change only: <the specific modification>
417
+ Preserve exactly: <named lock list: facial structure, pose, product
418
+ silhouette, logo geometry, text spelling, framing, perspective, palette,
419
+ lighting, shadows>
420
+ Do not add or remove: <protected elements>
421
+ ```
422
+
423
+ "Keep everything else the same" alone is weak — name the fragile properties in
424
+ the lock list, and repeat the same lock list on every iterative edit pass to
425
+ prevent drift.
426
+
427
+ **Annotated inputs.** If the edit source or a reference image carries drawn
428
+ markup (arrows, boxes, circled regions, sticky notes), the model tends to
429
+ treat the markup as image content and reproduce it. Prefer sending the clean
430
+ image plus text instructions derived from the markup. When the annotated
431
+ image must be sent, state before and after the edit list that the markup is
432
+ temporary editing instructions only — interpret it, apply the edits, then
433
+ remove every trace of it from the output.
434
+
435
+ **Removal edits.** "Remove X" alone is weak. Pair the removal command with a
436
+ positive description of what replaces it, then lock the rest: "Remove the
437
+ sticky note. Show the continuous walnut desk surface where it was, matching
438
+ the surrounding grain, lighting, and perspective — no residue, outline, or
439
+ discoloration. Preserve every other object, the framing, and the color
440
+ grading exactly." For stubborn removals, generate multiple candidates and
441
+ re-edit only the residual region instead of enlarging the prompt.
442
+
443
+ ### Multi-Reference Rules
444
+
445
+ When passing multiple `--ref` images, label each reference by index and role
446
+ inside the prompt, then state the relationships explicitly:
447
+
448
+ ```text
449
+ Image 1: base scene and composition.
450
+ Image 2: subject identity reference.
451
+ Image 3: style reference.
452
+
453
+ Place the subject from Image 2 into Image 1. Apply only Image 3's palette and
454
+ brushwork. Preserve Image 1's framing, background, perspective, and lighting.
455
+ ```
456
+
457
+ - Put the most identity-critical reference (face, logo, product) **first**:
458
+ documented GPT Image behavior preserves the first input with the richest
459
+ texture and detail.
460
+ - When several faces must all stay recognizable, combine them into one
461
+ composed reference image before generating instead of passing many separate
462
+ portraits.
463
+ - For compositing, specify the source element, its destination and location,
464
+ the preserved context, and harmonization: scale, perspective, lighting,
465
+ shadows.
466
+
286
467
  ## Parallel Generation
287
468
 
288
469
  There is no `--parallel` flag. For multiple candidates from the same prompt,
@@ -424,6 +605,9 @@ ima2 config keys --json
424
605
  - Do not print API keys, OAuth tokens, config files, or `.env` values.
425
606
  - Use `ima2 capabilities --json` before guessing model names.
426
607
  - Use `ima2 skill path` when an agent needs the installed Markdown skill path.
608
+ - Use `ima2 skill <name> refs` to discover reference modules for front/uiux skills.
609
+ - Use `ima2 skill <name> ref <refname>` to load a specific reference module on demand.
610
+ - Use `ima2 skill install --dir <path>` to install skills to the agent's skill directory.
427
611
  - Use `ima2 inflight ls --json` or `ima2 ps --json` to inspect active jobs.
428
612
 
429
613
  ## Video Generation
@@ -885,6 +1069,26 @@ When creating a sequence, write both motions explicitly: "A motion" for the
885
1069
  first clip and "B motion" for the continuation. For last-frame Ref2V, use ref 1
886
1070
  as identity/style and ref 2 as current state/last frame.
887
1071
 
1072
+ **Shot discipline (cross-vendor official guidance):**
1073
+
1074
+ - **One camera move + one primary action per shot** is the most reliable
1075
+ recipe; short clips follow instructions better than long ones. Write actions
1076
+ as observable, timed beats: "takes four steps to the window, pauses, pulls
1077
+ the curtain in the final second" — not abstract descriptions.
1078
+ - **Split audio into explicit channels**: Dialogue (speaker label + exact
1079
+ short line), Ambience, SFX, Music. Declare music policy explicitly —
1080
+ "diegetic only", "no score", or a concrete style. A 4-5s clip fits 1-2 short
1081
+ dialogue exchanges at most.
1082
+ - **I2V prompts describe motion, not the image.** When a reference image or
1083
+ last frame drives the clip, the image already fixes subject, composition,
1084
+ color, and lighting — do not re-describe them. Write only: subject motion,
1085
+ scene reaction, camera motion, motion style.
1086
+ - **Reuse identical anchor phrases across clips.** For multi-clip continuity,
1087
+ repeat the same character/wardrobe/palette wording verbatim in every prompt
1088
+ of the series.
1089
+ - **Failure recovery ladder**: freeze the camera, then simplify the action,
1090
+ then clear the background, then re-add one element per iteration.
1091
+
888
1092
  **Example — product reveal (10s, 1.5, 1080p):**
889
1093
  ```text
890
1094
  A single continuous macro shot begins inches above a matte black desk surface,