SuperAPI AI Directory

create-product-hypermotion-with-specs

Design & creation

View repository

Updated 10-15 21:54

About this skill

create-product-hypermotion-with-specs

Hypermotion + Kinetic Typography intercut = one virtuoso AI-gen product clip, diced into segments and interleaved with PIL-rendered text cards for spec callouts, ending with a brand-asset end card. Music-led, silent VO, 9:16 Reels-native. Validated on Soundboks (industrial/party voice) 2026-05-28.

Purpose

Produce a 20-30s 9:16 vertical product ad by:

  1. Gathering brand assets (real product photos + brand logo PNG + brand color palette)
  2. Generating ONE 12-15s hypermotion i2v via Seedance 2.0 using a 5-block prompt recipe
  3. Rendering 5-7 kinetic typography text cards via PIL (italic skew, outline echo, 3D extrusion, slam-with-shake, inversion flash) for spec callouts + CTA
  4. Rendering 1 brand-asset end card via PIL (real logo PNG + brand-coded BG + slam motion blur + cascade reveal of subtitle + CTA + inversion flash)
  5. Cutting the hypermotion into 5-6 segments, intercutting with text cards in a fixed beat structure, ffmpeg concat + crop to 9:16
  6. Generating a 124 BPM bass-driven music bed via ElevenLabs Music (fal proxy)
  7. Mux + self-QC + ship

Use when:

  • Brand voice is industrial / sport / party / utility (Soundboks-class)
  • Hero product photographs well (real PDP shots available, not AI-gen ex-nihilo)
  • Brand has 4-6 hard spec callouts (dB, hours, IP rating, count, etc.)
  • Brand has a logo SVG/PNG that can be extracted (most brand SVGs are base64 PNG wrappers)
  • Target placement: TikTok / Reels / Stories (9:16 vertical) — works muted

Do NOT use for:

  • UGC ads with creator → use skills/molecules/ugc-ad/*
  • VO-driven explainer → use skills/molecules/explainer-video/*
  • Editorial / luxury / wellness brand voices → use create-vignette-ad (calmer)
  • Single static product hero → use skills/atoms/product-images/*
  • 30s long-form — format breaks past 30s (the hypermotion clip is the ceiling)

Inputs

Required:

  • brand_url — e.g. https://soundboks.com
  • product_url — PDP URL for the hero product (Shopify or equivalent)
  • spec_callouts[] — 4-6 short spec strings (e.g. ["126 dB SPL", "40-HOUR BATTERY", "IP65 RATED", "SWAPPABLE BATTERY", "PAIR 5 SPEAKERS"])
  • brand_voice — one of industrial | sport | party | utility | luxury | editorial | playful
    • The first 4 share the same aesthetic palette (black + Space Grotesk + utility orange)
    • editorial uses cream paper + EB Garamond (Hope-style) — better suited for create-vignette-ad
    • luxury and playful need different palettes — currently OUT OF SCOPE (single-brand validation)

Optional (with autonomous defaults):

  • duration_s — default 25.0 (range 20-30)
  • cta_text — default "Own the party." or "Own the {category}."
  • intro_text — default "INTRODUCING"
  • hypermotion_brief — free-text. If omitted, derived from brand category + product (Soundboks → "beach festival crash-zoom on speaker, lateral orbit, slow-mo dust"). See references/hypermotion-prompt-recipe.md.
  • music_brief — default "{BPM} BPM bass-driven electronic banger, no vocals or with a single rallying lyric for end-card sync". BPM default 124 for industrial/party, 100 for sport/utility.
  • accent_color_hex — default #FF6B1A (utility orange). Override via brand palette scrape.
  • bg_color_hex — default #0C0C0C (industrial black). Override only if brand requires.

Prerequisites:

  • FAL_API_KEY in .env at repo root — for Seedance + ElevenLabs Music
  • ffmpeg + ffprobe installed
  • Python 3.10+ with Pillow and fal_client
  • TTF fonts in project source/fonts/:
    • SpaceGrotesk-Bold.ttf (static, NOT variable — variable renders as Regular in PIL)
    • EBGaramond-Italic.ttf (only required for editorial voice)
  • Brand logo as PNG (extract from SVG via base64 decode — see references/brand-asset-extraction.md)

Composed Atoms

  • source-brand-assets — scrape PDP product photo, brand logo SVG, brand color hex from homepage CSS
  • remove-backgrounds — strip product PNG to alpha via fal-ai/birefnet/v2 (only needed if hypermotion uses cutout-on-clean-BG style; for in-environment hypermotion, skip — Seedance handles the BG)
  • create-video-seedance-2-fal — single 12-15s i2v hypermotion call via fal-ai/bytedance/seedance/v2/pro/image-to-video ($0.30/s, supports start_image + audio_off)
  • create-music-elevenlabs — 25-30s music bed via fal-ai/elevenlabs/music endpoint
  • add-music-track — ffmpeg mux pass with -map 0:v -map 1:a explicit
  • stitch-videos-ffmpeg — concat the 12-14 segments (hypermotion cuts + kinetic cards)
  • Inline (not yet an atom — see "Back-propagation to atom"): PIL-based kinetic typography pipeline (11 techniques, see references/kinetic-typography-pipeline.md). The existing skills/atoms/motion-graphics/create-kinetic-typography atom outputs transparent overlays (qtrle .mov); this molecule needs full-frame text cards.
  • watch — /watch:watch external skill for end-to-end QC on the final mp4

Do NOT use: Klap, captions, Whisper, Soul ID, UGC-creator atoms, Higgsfield Marketing Studio (validated to not match Hyper Motion brief — Seedance 2.0 beats it for product-as-hero hypermotion).

Workflow

Phase 0 — Brand asset gathering (autonomous, $0)

  1. Scrape product hero photo from brand PDP:

    curl -sL "${product_url}.json" | jq -r '.product.images[0].src'
    

    Download highest-res (PDP shots typically 1500-2000px). Save to source/scraped-product-images/.

  2. Extract brand logo PNG from SVG. Most brand SVGs are wrappers around base64-encoded PNGs:

    import re, base64
    svg = open('brand_logo.svg').read()
    m = re.search(r'data:img/png;base64,([A-Za-z0-9+/=]+)', svg) or \
        re.search(r'data:image/png;base64,([A-Za-z0-9+/=]+)', svg)
    open('brand_logo.png', 'wb').write(base64.b64decode(m.group(1)))
    

    Validated on Soundboks (decoded to 865×135 PNG of the actual wordmark). If SVG is pure vector (rare), use rsvg-convert -w 2400 brand_logo.svg > brand_logo.png.

  3. Scrape brand palette from homepage CSS — count #xxxxxx patterns, take top 5 frequencies. Map dominant accent color → accent_color_hex.

  4. Download fonts to source/fonts/:

    curl -sSL -o source/fonts/SpaceGrotesk-Bold.ttf \
      "https://raw.githubusercontent.com/floriankarsten/space-grotesk/master/fonts/ttf/static/SpaceGrotesk-Bold.ttf"
    
  5. Write brief.md with: PDP photo preview, brand palette swatches, proposed hypermotion concept + Seedance prompt + spec callouts + estimated spend (~$5).

🚦 HUMAN GATE 1 — Brief approval

Show user: brief.md + hypermotion prompt + 5-7 spec callouts + estimated spend.

User approves OR edits brief.md.

Phase 1 — Hypermotion + music in parallel (~$4.99, ~10 min wallclock)

Run both in parallel via ThreadPoolExecutor or two Bash processes:

  1. Fire Seedance i2v hypermotion ($4.54 for 15s):

    • Endpoint: fal-ai/bytedance/seedance/v2/pro/image-to-video
    • Input: hero product PNG as image_url (uploaded via fal_client.upload_file)
    • Duration: 15s (max for Seedance Pro)
    • Generate audio: false (we use external music bed)
    • Resolution: 1080p, aspect 1:1 (will be center-cropped to 9:16 later)
    • Prompt: 5-block recipe (see references/hypermotion-prompt-recipe.md):
      • Block 1: STYLE ANCHOR ("hypermotion product film, 124 BPM cuts, ...")
      • Block 2: CINEMATOGRAPHY ("ARRI Alexa, 50mm anamorphic, ...")
      • Block 3: SUBJECT + ENVIRONMENT ("Soundboks 4 on beach festival deck, ...")
      • Block 4: MULTI-SHOT TIMECODES ("0-3s crash zoom, 3-6s lateral orbit, ...")
      • Block 5: ABSOLUTE CONSTRAINTS ("no character contact, no multi-product, no text overlays, label-locked geometry, physics effects in environment only NOT on product")
    • Skip-if-exists guard: if assets/hypermotion-raw.mp4 exists, skip the call
  2. Fire ElevenLabs Music ($0.45 for 30s):

    • Endpoint: fal-ai/elevenlabs/music
    • Duration: duration_s * 1000 ms (generate exact target — Soundboks 25s validated)
    • Prompt: {BPM} BPM bass-driven {brand_voice} banger, with rallying single-lyric ending for end-card sync
    • output_format: "mp3_44100_192"
    • Skip-if-exists guard

Phase 2 — Render kinetic typography cards (autonomous, $0)

Render all text clips at 1080×1920 via PIL frame-by-frame to working/kinetic-frames/<label>/f%04d.png, then ffmpeg-encode each to working/kinetic-movs/<label>.mp4.

Cards to render (defaults — adjust per spec_callouts list):

  • intro.mp4 (1.0s) — "INTRODUCING" italic + outline echo, BG: brand bg + grain
  • spec_1.mp4 (1.5s) — Killer-stat slam: 3D extrusion in accent color (the hero spec, e.g. "126 dB SPL")
  • spec_2.mp4 (1.5s) — italic slam on dark BG (e.g. "40-HOUR BATTERY")
  • spec_3.mp4 (1.5s) — italic + outline echo on light BG (e.g. "SWAPPABLE BATTERY")
  • spec_4.mp4 (1.5s) — italic + sparkle accent (e.g. "IP65 RATED")
  • spec_5.mp4 (1.5s) — italic + shadow stack (e.g. "PAIR 5 SPEAKERS")
  • cta.mp4 (1.5s) — "OWN THE PARTY" 3D extrusion + accent→black flash
  • endcard.mp4 (3.5s) — REAL LOGO with slam motion blur, settle, micro-motion, inversion flash at 60% mark, cascade reveal of subtitle ("126 dB · 40 HRS · IP65") + CTA

Use the 11 reusable PIL helpers from references/kinetic-typography-pipeline.md (italic skew, outline echo, 3D extrusion, repetition stack, slam-with-shake, color flash, inversion flash, paper/dark grain BG, rotated text, motion blur, micro-motion).

Reference scripts from Soundboks (copy + adapt):

  • clients/soundboks/video-02-hypermotion/working/scripts/gen_kinetic_v6.py
  • clients/soundboks/video-02-hypermotion/working/scripts/gen_endcard_v10.py

Phase 3 — Assemble + mux (autonomous, $0)

  1. Center-crop hypermotion from 1:1 (1440×1440 or 1080×1080) to 9:16 (1080×1920):

    ffmpeg -i hypermotion-raw.mp4 -vf "scale=-1:1920,crop=1080:1920:(iw-1080)/2:0,fps=30" -c:v libx264 -crf 18 hypermotion-9x16.mp4
    

    Loses ~25% horizontal context but feels Reels-native.

  2. Cut hypermotion into 5-6 segments at fixed timecodes via ffmpeg -ss/-t: Default segments (for 25s ad with 15s hypermotion source):

    • Seg A: t=[0.0, 2.5] (2.5s — opener crash-zoom)
    • Seg B: t=[2.5, 5.0] (2.5s — lateral orbit)
    • Seg C: t=[5.0, 7.0] (2.0s — first slow-mo dust)
    • Seg D: t=[7.0, 8.5] (1.5s — second slow-mo dust)
    • Seg E: t=[8.5, 10.0] (1.5s — pull-back)
    • Seg F: t=[10.0, 11.5] (1.5s — final hero)
  3. Concat segments + cards per beat structure (see references/beat-structure.md):

    intro → segA → spec_1 → segB → spec_2 → segC → spec_3 → segD → spec_4 → segE → spec_5 → segF → cta → endcard
    

    Use ffmpeg concat demuxer with a concat.txt listing all segment files in order.

  4. Mux music as SEPARATE ffmpeg pass per memory feedback_ffmpeg_lcut_endcard_recipe.md:

    ffmpeg -y -i master-silent.mp4 -i music.mp3 \
      -c:v copy -c:a aac -b:a 192k -ar 44100 \
      -map 0:v -map 1:a -shortest \
      -movflags +faststart finals/master-v1-9x16.mp4
    

    Verify audio bit_rate ≈ 192000 via ffprobe (NOT 1000 — that's the default-mapping silent bug per feedback_ffmpeg_map_directive.md).

Phase 4 — Self-QC + ship (autonomous, $0)

  1. Run /watch:watch finals/master-v1-9x16.mp4 to verify:

    • Duration ± 0.5s of target
    • Aspect 1080×1920
    • All text cards readable, no frame bleed (outline echoes at 1.08x sweet spot)
    • Hypermotion segments hold subject identity (no geometry drift)
    • End card real logo visible + inversion flash hits at right beat
    • Music holds throughout, no decay tail visible
  2. Upload to gooseworks for share URL via mcp__gooseworks__get_upload_url + curl PUT.

Output

<project>/
├── brief.md
├── HOW_TO_MAKE_THIS_VIDEO.md
├── source/
│   ├── scraped-product-images/        # raw PDP PNGs
│   ├── logo/
│   │   ├── brand_logo.svg              # original
│   │   └── brand_logo_white.png        # extracted from SVG
│   ├── fonts/
│   │   ├── SpaceGrotesk-Bold.ttf       # static (NOT variable)
│   │   └── EBGaramond-Italic.ttf       # only if editorial voice
│   └── brand-palette.json              # scraped color hex
├── assets/
│   ├── hypermotion-raw.mp4             # Seedance i2v output (12-15s, 1:1)
│   ├── hypermotion-9x16.mp4            # center-cropped to vertical
│   └── music/
│       └── music_bed.mp3               # 20-30s ElevenLabs Music
├── working/
│   ├── kinetic-frames/                 # PIL PNG sequences (intermediate)
│   ├── kinetic-movs/                   # encoded kinetic clips
│   ├── segments/                       # hypermotion cuts
│   └── scripts/
│       ├── fire_hypermotion.py
│       ├── fire_music.py
│       ├── gen_kinetic_cards.py
│       ├── gen_endcard.py
│       └── assemble.py
└── finals/
    └── master-v1-9x16.mp4              # shipping master, ~25s, 1080×1920

Decision Rules

  1. One hypermotion call, not many. Generate ONE 12-15s clip and CUT into 5-6 segments via ffmpeg, rather than firing 5-6 separate Seedance calls. Cheaper ($4.54 vs $22) AND maintains visual consistency across segments (same camera/grade/subject — what Seedance does well in one call).

  2. Center-crop, don't regen for 9:16. Generate Seedance at 1:1 and center-crop to 9:16 in post. Generating natively 9:16 in Seedance is more expensive and quality-equivalent. ~25% horizontal context loss is acceptable for the product-centric framing.

  3. Real brand logo > typeset wordmark on end card. Always use the actual brand SVG/PNG, not typeset text. Per memory feedback_brand_asset_end_card.md — typeset wordmarks miss distinctive letterforms (Soundboks has custom italic-slanted glyphs that Space Grotesk Bold can't approximate). See also LEARNINGS.md #138.

  4. Brand voice drives aesthetic palette. Don't apply Hope-style cream paper + EB Garamond italic to industrial/sport/party brands. Soundboks-class = black BG + Space Grotesk Bold + utility orange accent. Editorial/literary brands belong in create-vignette-ad, not here. Per LEARNINGS.md #139.

  5. Outline echo at 1.08x is the bleed-safe sweet spot. Larger (1.2x+) reads as accidental clipping; smaller defeats the ambient-shadow purpose. Validated on Soundboks V8→V9 bleed audit. Per LEARNINGS.md #140.

  6. Never freeze after settle on the wordmark. Continuous ±1% scale pulse + ±3px horizontal drift for the entire 3.5s end card hold. 3+ seconds of frozen text feels like a JPEG. Per LEARNINGS.md #141.

  7. Hypermotion prompt must include ABSOLUTE CONSTRAINTS block. Without it, Seedance lets geometry drift mid-clip (V2 broke to cowbell shape). Block must include: "no character contact, no multi-product, label-locked geometry, physics effects (heat-shimmer, dust) in environment only NOT on product." Per memory feedback_hypermotion_prompt_recipe.md.

  8. ffmpeg mux: ALWAYS explicit -map 0:v -map 1:a + SEPARATE pass from concat. Default mapping silently produces 1 kbps garbage audio. Per memory feedback_ffmpeg_map_directive.md + feedback_ffmpeg_lcut_endcard_recipe.md.

  9. Use STATIC font TTFs, never variable. PIL doesn't respect variable font axes — SpaceGrotesk[wght].ttf renders as Regular weight regardless of the weight axis. Always download single-weight static TTFs (/static/ subfolder on most font repos).

  10. Skip-if-exists guards on all paid calls. Re-running the orchestrator must NEVER re-bill if outputs already exist. Wrap each fal_client.subscribe in if not output_path.exists(): ....

  11. Music with vocals is fine for industrial/party voice. Per memory feedback_music_with_vocals_default.md — instrumental is the wrong default for hypermotion product ads (no VO competes). Bake a single rallying lyric into the end-card beat for AV-sync hook.

  12. Cut hypermotion at beat boundaries, not arbitrary timecodes. Seedance naturally has 2-3 internal "beats" (crash-zoom → orbit → settle). Cut on these boundaries via /watch:watch frame-by-frame inspection, not at uniform intervals. Uniform cuts break visual rhythm.

Quality Checks

Before declaring done, verify the final mp4:

  • Duration within target ± 0.5s (e.g. 25.0s ± 0.5s)
  • Aspect 1080×1920 (9:16 vertical)
  • All N text cards readable, no accidental frame bleed (outline echoes ≤1.08x)
  • Hypermotion segments hold subject identity (label/logo on product stays consistent across cuts)
  • End card real logo visible + sharp (no PIL upscale artifact)
  • Inversion flash at end card hits at correct beat (~60% of card duration)
  • Continuous micro-motion visible on end card wordmark (NOT frozen)
  • Music holds throughout, no decay tail in last 5s
  • Music aligns to cuts on the strongest beats (intro slam, mid-bridge, end-card flash)
  • Audio bit_rate ≈ 192kbps AAC (verify via ffprobe -show_entries stream=bit_rate)
  • No people, no hands, no text overlays inside the hypermotion clip itself
  • Final mp4 plays cleanly in QuickTime + browser

Failure Modes

Failure Cause Recovery
Hypermotion geometry drifts mid-clip (product morphs shape) Prompt lacks ABSOLUTE CONSTRAINTS block Add the 5th block per references/hypermotion-prompt-recipe.md. Regen ($4.54).
Hypermotion shows character touching product "Character" entered prompt at all Strip all human/hand references from prompt. Add "no character contact" to constraints.
Text cards bleed off frame Outline echo scale > 1.08x Tighten echo to 1.08x. Re-render PIL (free).
Fonts render as Regular weight despite Bold being specified Downloaded variable font TTF Replace with static TTF from /static/ subfolder of font repo
End card wordmark looks generic/wrong Used typeset font instead of real logo Extract real logo PNG from brand SVG via base64 decode. Re-render.
End card feels frozen after 1s No micro-motion phase added Add scale = 1.0 + 0.010*sin(t*1.4); x_off = 3*sin(t*1.1) after settle phase
Final mp4 audio is 1 kbps ffmpeg mux without explicit map Add -map 0:v -map 1:a per memory feedback_ffmpeg_map_directive.md
Music tapers in 2nd half Known ElevenLabs Music behavior Generate 20% longer than target + trim. OR loop-and-flatten with acrossfade + acompressor + loudnorm per feedback_elevenlabs_music_decay.md
9:16 crop loses critical product detail Hypermotion framed product at horizontal edges Re-generate Seedance with explicit "subject centered, vertical-safe composition" in prompt
gen_kinetic_cards.py script fails on font load Wrong font path or font not downloaded Verify source/fonts/SpaceGrotesk-Bold.ttf exists; re-download from raw.githubusercontent.com/floriankarsten/space-grotesk/master/fonts/ttf/static/
Brand logo SVG isn't a base64 PNG wrapper Pure vector SVG (rare) Use rsvg-convert -w 2400 logo.svg > logo.png instead
Hypermotion clip is silent but final has music too quiet Music loudnorm not applied Add acompressor=threshold=-12dB:ratio=2:attack=20:release=200,loudnorm=I=-14:TP=-1.5:LRA=9 to music before mux

Spend Reference (validated on Soundboks V10, 2026-05-28)

Item Count Per-unit Subtotal
Seedance 2.0 i2v 15s (1080p, audio off) 1 $4.54 $4.54
ElevenLabs Music 25s 1 $0.45 $0.45
Brand logo PNG extraction (base64 decode) 1 $0.00 $0.00
PIL kinetic typography rendering (8 clips) 8 $0.00 $0.00
ffmpeg concat + mux + crop 1 $0.00 $0.00
V1 marginal cost (no iteration) ~$4.99

For full multi-iteration runs (Soundboks did V1→V10): ~$17.43 total. V10 alone is $5 to reproduce. Most "iteration cost" is PIL re-renders + ffmpeg = $0.

Sub-Archetypes (none yet)

This molecule has 1 validated sub-archetype: the Soundboks pattern (industrial voice, single-product hero, 5-7 spec callouts, brand-asset end card).

Future sub-archetypes pending multi-brand validation:

  • PH-LUXURY — luxury brand voice (gold + monochrome typography, slower BPM, longer holds)
  • PH-SPORT — sport/fitness voice (high-saturation accent, faster BPM ~140, athletic motion verbs)
  • PH-PLAYFUL — pop/retail voice (bright color blocks, bold display sans, exaggerated 3D extrusion)

Until validated on N=2+ brands per sub-archetype, treat them as open questions, not Decision Rules.

Tests

See tests/:

  • smoke-test.md — structural pass (all required files exist, frontmatter valid)
  • sample-input.md — Soundboks worked example
  • expected-output.md — what successful output looks like
  • human-test.md — manual acceptance criteria
  • verifier.md — ffmpeg + ffprobe assertions

Related

Originally validated in content-goose at clients/soundboks/video-02-hypermotion/. Adapt paths to your project.

  • Reference project: clients/soundboks/video-02-hypermotion/ — full worked example with HOW_TO_MAKE_THIS_VIDEO.md (V1→V10 iteration history)
  • Reference scripts:
    • clients/soundboks/video-02-hypermotion/working/scripts/gen_kinetic_v6.py — 8 spec/filler cards
    • clients/soundboks/video-02-hypermotion/working/scripts/gen_endcard_v10.py — brand-asset end card
    • clients/soundboks/video-02-hypermotion/working/scripts/assemble_v10.py — concat + mux template
  • Related molecules:
    • skills/molecules/ad-format/create-vignette-ad — for editorial/luxury brand voices
    • skills/molecules/ad-format/create-value-prop-ad — for VO-led value prop ads
    • skills/molecules/product-video/create-product-stopmotion-video — for tabletop stop-motion
    • skills/molecules/ugc-ad/* — for UGC creator ads
  • Memory rules to read before running:
    • reference_kinetic_typography_pipeline.md — full PIL pipeline reference (11 techniques + code)
    • feedback_brand_asset_end_card.md — real logo > typeset
    • feedback_hypermotion_prompt_recipe.md — 5-block Seedance prompt template
    • feedback_ffmpeg_map_directive.md — -map 0:v -map 1:a always
    • feedback_ffmpeg_lcut_endcard_recipe.md — separate concat + mux passes
    • feedback_music_with_vocals_default.md — vocals OK for product ads
    • feedback_elevenlabs_music_decay.md — generate longer + trim
  • LEARNINGS.md rules: #137 (PIL kinetic typography supersets atom), #138 (real brand assets on end cards), #139 (brand aesthetic per voice register), #140 (outline echo 1.08x sweet spot), #141 (never freeze after settle).

Back-propagation to skill atom (future work)

The existing skills/atoms/motion-graphics/create-kinetic-typography atom exposes 5 animation_type options. This molecule's PIL pipeline adds 6 more: italic skew, outline echo, 3D extrusion, repetition stack, mask wipe, letterbox slide, color flash, inversion flash. Worth extracting these into the atom as new animation_type options once a 2nd brand validates the pipeline.

Open Questions (not yet Decision Rules)

These need N=2+ project validations before promoting:

  • Optimal segment count per hypermotion clip. Soundboks used 6 segments from a 15s clip. Would 4 (longer holds) or 8 (faster cuts) be better defaults?
  • Spec callout count. Soundboks used 5 hard specs + 1 intro + 1 CTA + 1 endcard. Is 5 specs the right ceiling? Below 3 may feel sparse; above 6 may feel like a deck.
  • Music BPM auto-selection per brand voice. Soundboks 124 BPM worked. Does sport/luxury need different BPM tables?
  • 9:16 vs 1:1 vs 16:9 portability. Soundboks validated 9:16. Does this molecule produce equally-good 1:1 (Instagram feed) and 16:9 (YouTube) variants with just a different center-crop?
  • Cost of iteration. Soundboks went V1→V10 ($17.43 total). What does the 60th-percentile brand spend look like for a "first ship"?