SuperAPI AI Directory

create-value-prop-ad

General & other

View repository

Updated 10-15 21:54

About this skill

create-value-prop-ad

Originally validated in content-goose at clients/som-sleep/video-01-value-prop-vp-swap/. Adapt paths to your project.

Validated on clients/som-sleep/video-01-value-prop-vp-swap/. Read that project's HOW_TO_MAKE_THIS_VIDEO.md and LEARNINGS.md for the canonical reference run.

Purpose

Produce a 9:16 vertical Value Prop ad where 3-5 short noun-phrase claims are revealed sequentially over per-SKU product visuals. The text + product carry the spot; sound-off legibility is required. Default music bed (instrumental, -14dB) per user preference; format DNA says silent but cinematic/product short-form defaults to music per feedback_music_with_vocals_default.md.

When to use

  • Brand has ≥3 SKU variants (flavors / scents / styles) with clean product photos
  • Brand has 3-5 stackable noun-phrase claims (≤4 words each)
  • Target placement: Reels / Stories / TikTok / Meta vertical
  • Tier 1/5 complexity (simplest paid-social format)

Don't use if:

  • 1 SKU only → use VP-ACCUM (anatomy diagram approach; decision rule below)
  • Strong UGC available → use VP-LIVE (labels over live action; decision rule below)
  • Needs VO narration → use create-vo-anchored-beat-video molecule
  • Lifestyle/UGC-led → use recreate-ugc-ad-from-source

Inputs

Required:

  • brand_url — homepage URL, used for autonomous scrape

Optional (autonomous defaults if omitted):

  • aspect_ratio — 9:16 (default) | 1:1 | 4:5
  • duration_s — default 17 (range 10-20)
  • sub_archetype — auto | VP-SWAP | VP-ACCUM | VP-LIVE
  • value_props[] — 3-5 items {label: "≤4 words", benefit_sentence?: "≤12 words"}. If omitted, scraped autonomously.
  • hook_line — opening tagline (default: scraped from brand H1)
  • tagline — end-card line (default: scraped, or reused as hook)
  • brand_color_hex, brand_font — scraped if omitted
  • music_brief — text prompt for ElevenLabs Music API. Default: brand-appropriate ambient instrumental at -14dB. Pass null to ship silent.
  • vo_script — if provided, generates VO via ElevenLabs (eleven_v3 + atempo=1.20). Ducks music to -22dB. Default: no VO.
  • animation_preset — brand-register-mapped preset name (sleep_wellness, sport_active, energy_cpg, luxury_editorial, tech_active, premium_clinical) OR auto (default — molecule infers from scraped tokens) OR explicit per-layer overrides (see references/animation-library.md).

Composed Atoms

  • atoms/source/source-brand-assets — logo + hero photos at full CDN resolution (scrape)
  • atoms/source/source-company-existing-ads — Meta Ad Library for prop copy inspiration (optional, scrape)
  • atoms/asset-preparation/remove-backgrounds — clean product cutout
  • atoms/product-images/create-product-images-higgsfield-product-photoshoot — hero if scrape fails (optional)
  • atoms/end-cards/create-end-card-from-reference — Pinterest + NB2-edit lifestyle composite (Phase 6)
  • atoms/motion-graphics/create-motion-graphics-hyperframes — beat HTML + Playwright render
  • atoms/music/create-music-elevenlabs — ambient instrumental bed
  • atoms/voiceover/create-voiceover-elevenlabs — only if vo_script provided (optional)
  • atoms/audio-editing/mix-master — VO + music + ducking
  • atoms/assembly/stitch-videos-ffmpeg — concat beat clips + mux audio
  • atoms/review/watch — self-QC midframe extract + audio levels

Do NOT use: Klap captions (text is burned in, not subtitled), Soul ID, UGC-creator atoms.

Workflow

Phase 0 — Autonomous brand intake

Scrape from brand_url:

  1. Logo — header img[alt*="logo"] → fetch without ?width=N query param (Shopify default-resolution is 1644×939-ish; with width param caps at served thumbnail size). Verify via PIL.
  2. Brand colors — getComputedStyle(body) for background-color + color; :root for --color-primary, --color-button, etc.
  3. Brand font — getComputedStyle(h1).fontFamily + body font
  4. Tagline — homepage <h1> or hero copy (verbatim)
  5. Value props (5-source merge):
    • Homepage meta description
    • Homepage feature row
    • PDP "Features" / "What's Inside"
    • Footer trust strip (NSF, USDA Organic, etc.)
    • Stick-pack / package label copy
  6. Per-SKU PNGs — find variety-pack image on PDPs (4-pack composite is common), then PIL bounding-box detect each SKU column:
arr = np.array(img.convert('RGB'))
is_non_white = np.any(arr < 240, axis=2)
col_nonwhite = is_non_white.sum(axis=0)
in_pack = col_nonwhite > 50
# Find contiguous runs → pack bounding boxes → crop with ~12px padding

Output <project>/brief.md with provenance + recommended 5-prop set + sub-archetype recommendation + estimated spend.

🚦 GATE 1 — Brief + asset inventory + animation choice

User can edit:

  • Prop list / hook / tagline / sub-archetype
  • Animation preset — brief.md MUST present the auto-picked brand-register default + the 5 alternative presets with one-sentence descriptions, so user knows what's possible. Render a preview thumbnail per preset on a single prop beat (one-time-rendered ships with skill at shared/animations/_previews/). User picks: keep default, swap preset, or per-layer override (e.g. keep sachet entrance, change text entrance).

See references/animation-library.md for full preset catalog.

Phase 1 — Storyboard + preview hyperframes

  1. Pick sub-archetype (see Decision Rule 2)
  2. Author shot-list.yml (7 beats: hook + 5 props + endcard)
  3. Render preview hyperframes at 540×960 (50% res)
  4. Compile storyboard.html gallery

🚦 GATE 2 — Storyboard approval

User can request copy / layout / accent changes.

Phase 2 — Render + audio + upload (autonomous)

  1. Render each beat at 1080×1920 @ 30fps via render_hyperframe.py
  2. Concat with ffmpeg + silent stereo audio placeholder
  3. Generate music bed via ElevenLabs Music API (fal-ai/elevenlabs/music, force_instrumental: true, $0.04)
  4. Mix music in at -14dB with 0.4s fade-in + 0.6s fade-out
  5. (Optional) Generate end-card composite via Pinterest + NB2-edit (Phase 6 of HOW_TO doc)
  6. Self-QC: ffprobe + volumedetect + midframe extract
  7. Upload to gooseworks for shareable URL

Decision Rules

  1. Format is silent by default (per format DNA — GEKKS/GREATS/INCREDIWEAR all -91dB). User-preference override: add music bed at -14dB. Reject VO unless vo_script explicitly provided.

  2. Sub-archetype selection:

    • VP-SWAP if brand has ≥3 SKUs (Som, GEKKS-style). Per-SKU PNGs cropped, hero+supporters layouts.
    • VP-ACCUM if 1 SKU + anatomy story (GREATS-style "anatomy of X" diagram with accumulating callout labels).
    • VP-LIVE if good product-in-use UGC available OR brand approves Seedance i2v generation (~$0.48 for 10s).
  3. Prop count: 3-5. Never <3, never >7. If brand has more, pick the most differentiating.

  4. Prop word cap: ≤4 words. Compress aggressively (e.g. "NSF Certified for Sport" stays, "Independently Tested by Pro Athletes" → "Pro-Team Tested"). Reject if compression loses meaning.

  5. Benefit sentence (VP-SWAP only): ≤12 words. Optional. Skip if compression awkward.

  6. Uniform pacing. Hook 3.0s, props 2.0-2.5s each (uniform within a run), endcard 2.0s. No acceleration curve.

  7. No human face is focus. If hero image has a model's face, auto-crop to torso-down or product-only.

  8. Display headline cap: ~100-120px for 9:16. Bristle reference is 96px. For supplement/wellness register, 84-112px. Don't exceed 130px — reads as "magazine confident" not "calm authority."

  9. Per-flavor color accents on RULES, not headlines. Yellow/light-color HEADLINES on white = low contrast. Use the per-flavor color as the 4px×72px accent rule under the eyebrow. Headlines stay in --ink navy.

  10. Brand wordmark threading: optional. GEKKS threads "yekks" through every frame; Som doesn't need to (per-pack wordmarks carry attribution). Audit fit per brand. Default: skip wordmark threading on prop beats, lean into the per-SKU wordmark on the canvas instead.

  11. End card: brand wordmark sourced from CDN without ?width=N param. Verify resolution ≥ 1200×600 via PIL after download. No chromatic aberration / RGB-shift effects — they read as pixelated noise on a high-contrast wordmark.

  12. Animation architecture: initRenderer(duration, renderFn) from _shared.js. Pure function of beat-local time t. Never CSS keyframes, never setTimeout. Helpers: tw, tw_lin, easeOut, springScale, revealWords. (Architecture proven on Bristle + Everself v4.)

  13. Per-sachet PNGs when ≥3 SKUs. PIL bounding-box detection on variety-pack source. Crop with ~12px padding. Don't reuse flat 4-pack image as canvas for every beat — reads as same-image-shifting.

  14. Layout variation per beat: alternate hook → row → hero → hero → hero → row → endcard. Rotate which sachet is the hero (Berry → Cherry → Mango → Tangerine). Eye anchor must shift.

  15. Silent audio track via anullsrc mono is mandatory even if no music — some platforms reject videos with no audio stream.

  16. Music mix: -14dB default, normalize=0 (per feedback_ffmpeg_amix_normalize), explicit -map 0:v -map 1:a (per feedback_ffmpeg_map_directive). Verify final audio bit_rate ≥ 100kbps via ffprobe.

  17. NB2-edit (end-card optional layer):

    • Pre-crop source to target aspect before upload (NB2-edit preserves source aspect)
    • Explicit photoreal-compositing language in prompt: "PHYSICAL OBJECTS IN THIS SCENE, not pasted overlays"
    • Pass aspect_ratio: "9:16" explicitly
    • Test ONE first before batch firing (pipeline gate per feedback_media_pipeline_gates)
  18. Pipeline gates (per feedback_media_pipeline_gates):

    • Prompt-review before EVERY paid model call
    • Still-review before video gen
    • Clip-review before composite
    • User can override case-by-case ("fire all 3 anyway") but must do so explicitly.
  19. Animation library is registry-pattern, with user choice surfaced at Gate 1. Animations live in shared/animations/{sachet-entrance,text-entrance,transitions}/<id>.js as JS modules matching the (t, elements, params) → void contract.

    • Default: brand-register-matched preset (see references/animation-library.md). Inferred from scraped tokens (font genre, color saturation, claim word energy, category).
    • Gate 1 surfaces choices: brief.md MUST list the auto-pick + 5 alternative presets with one-sentence descriptions + preview thumbnails. User must KNOW what's possible.
    • Per-layer override: user can swap one layer (e.g. keep sachet, change text) without forcing a full preset swap.
    • v1 ships layers 1+2 (per-beat entrance + inter-beat transition).
    • Layer 3 (continuous sachet state for carousel/conveyor patterns) is documented as v2 — requires unified-timeline rendering. See animation-library.md §v2.
    • Validated presets in v1: sleep_wellness (Som v5), sport_active (Som v6). Others scaffolded but need brand-validation.

Output

<project>/
├── brief.md                          ← Gate 1 review
├── shot-list.yml                     ← beat manifest
├── storyboard.html                   ← Gate 2 review (gallery of previews)
├── HOW_TO_MAKE_THIS_VIDEO.md         ← per-project recipe
├── LEARNINGS.md                      ← run-specific notes
├── source/
│   ├── logo-<brand>.png              ← from CDN, no width param
│   ├── sachets/{sku-1,sku-2,…}.png   ← PIL-cropped
│   ├── scraped-props.yml
│   ├── brand-identity.yml
│   └── end-card-references/          ← Pinterest sourcing (optional)
├── assets/
│   └── hyperframes/                  ← previews + final renders
├── working/
│   ├── hyperframes-v1/{_shared.css, _shared.js, beat-*.html}
│   ├── beat-clips-v1/
│   └── audio/music-raw.mp3
├── finals/
│   ├── master-v1-clean.mp4           ← silent
│   ├── master-v1-with-music.mp4      ← shippable
│   └── master-v1-with-vo.mp4         ← if VO requested
└── archive/                          ← prior versions

Quality Checks

  • Length within 10-20s range (default 17s)
  • Prop count 3-5
  • Every prop label ≤4 words
  • Optional benefit sentence (VP-SWAP) ≤12 words
  • Every prop displayed ≥2.0s
  • Per-SKU PNG canvas (≥3 SKUs) — no flat composite reused as canvas
  • No human face is focus
  • Audio track exists, bit_rate ≥100kbps (verify with ffprobe)
  • Music mean volume between -25dB and -34dB (background level)
  • End card wordmark resolution ≥1200×600
  • No chromatic aberration on end card
  • No CSS keyframes / setTimeout in beat HTMLs (animation only via renderAt(t))
  • Per-flavor accent rule color matches packaging
  • Headline color = --ink (not flavor color)
  • Aspect ratio matches target
  • Gooseworks share URL generated and tested

Failure Modes

Failure Cause Recovery
Brand homepage has no value props Storytelling brand without claim-stack marketing Pivot to PDP bullets / Amazon listing / Meta Ad Library. Surface at Gate 1 if all sources fail.
Props all >4 words after compression Brand uses sentence-form marketing Best-effort LLM compression with strict ≤4-word rule. Surface at Gate 1 if compression loses meaning.
Variety-pack image not found Brand has no composite SKU image Source per-SKU hero PNGs individually from PDPs. Fall back to higgsfield-product-photoshoot only if grounding rules approved.
Per-SKU PIL crop produces wrong boxes Multi-pack source has unusual layout (overlapping, diagonal) Manual crop coordinates. Surface intermediate PNGs at Gate 1.
Headline overlaps hero sachet (9:16 + hero layout) Hero sachet sized too tall Cap hero width at 280px (≈1090px tall on 1620:416 aspect). Push down with bottom: 170px.
End-card wordmark pixelated Logo source served at thumbnail size by Shopify CDN Re-fetch without ?width=N parameter. Verify ≥1200×600 via PIL.
Audio bit_rate 1 kbps after mux Missing -map 0:v -map 1:a in ffmpeg call Re-mux with explicit map directives. Per feedback_ffmpeg_map_directive.
Music too loud / overpowers visuals Default normalize=1 in amix ate the volume filter Set normalize=0 in amix. Per feedback_ffmpeg_amix_normalize.
ElevenLabs music tapers in 2nd half Known API behavior (feedback_elevenlabs_music_decay) For >15s clips, generate 10s + loop+flatten via acrossfade + acompressor + loudnorm.
NB2 returns 2-panel composition Prompt too generic Add "Output a single image, not a comparison panel" + explicit aspect_ratio param. Re-roll.
NB2 wordmarks drifting Reference image not pre-cropped to target aspect Pre-crop source via ffmpeg crop+scale to 1080×1920 before upload.
Whisper mishears VO ("Bristle" → "Bristol") atempo'd / cloned voice with brand-specific vocab Pass initial_prompt with brand terms to Whisper (per feedback_whisper_asmr_sped_audio).

References

  • references/format-dna.md — extracted DNA from GEKKS/GREATS/INCREDIWEAR (the 3 corpus refs)
  • references/gekks-design-teardown.md — frame-by-frame design language (the actual creative brief)
  • references/typography-rules.md — display ladder + Fontshare options + brand-register match criteria
  • references/layout-variation-rules.md — per-beat composition rotation
  • shared/_shared.css + shared/_shared.js — Bristle architecture (validated)
  • shared/beat-templates/{hook-sticker,prop-row,prop-hero,endcard-wordmark}.html
  • Validated run: clients/som-sleep/video-01-value-prop-vp-swap/
  • LEARNINGS: clients/som-sleep/video-01-value-prop-vp-swap/LEARNINGS.md
  • Recipe: clients/som-sleep/video-01-value-prop-vp-swap/HOW_TO_MAKE_THIS_VIDEO.md

Related memories

  • feedback_use_skill_library.md — scan atoms before writing custom scripts
  • feedback_image_grounding_rules.md — NB2 may only edit real images; never gen products
  • feedback_media_pipeline_gates.md — prompt-review before EVERY paid call
  • feedback_render_hyperframe_paths.md — Playwright + relative asset paths
  • feedback_explainer_no_css_keyframes.md — initRenderer architecture mandatory
  • feedback_ffmpeg_map_directive.md + feedback_ffmpeg_amix_normalize.md — audio mux hygiene
  • feedback_music_with_vocals_default.md — user preference: music default for product short-form
  • feedback_elevenlabs_v3_naturalness.md + feedback_v3_audio_tags_color_read.md — VO settings stack
  • feedback_elevenlabs_music_decay.md — loop+flatten for longer music beds
  • feedback_video_review_pattern.md — present local + gooseworks URL together
  • reference_fal_elevenlabs.md — FAL endpoint for ElevenLabs music