| name | create-vignette-ad |
| description | Produce a Vignette ad (Common Thread Co taxonomy): real-time kinetic background video
(sourced from Pexels stock OR generated via T2V) composited with product cutouts, cold-open
text card, and annotated end card. 9-12s, 1:1 or 9:16, music-led, no VO. Validated on
Mother Science (clinical-luxury, 3 SKUs, T2V BG, $8) AND Clinikally (Indian dermat, 5 SKUs,
Pexels BG, $0.66 — 92% cost reduction). Use when brand wants a feed-scroll-friendly
atmospheric short that works muted. NOT for UGC, creator, or VO-driven ads.
|
| status | ACTIVE — validated on 2 brands (Mother Science 2026-05-28, Clinikally 2026-05-28) |
create-vignette-ad
Vignette format = product cutouts laid over a kinetic background video. Music-led,
sub-12s, loopable. The inverse of video inlays. Validated 6-variant comparison run
with 3 sub-archetypes (V-PURE / V-TILE / V-CARD). This molecule focuses on V-CARD
(cold-open card → product carousel → annotated end card).
Purpose
Produce a short-form (9-12s) vertical or square Vignette ad for a brand by:
- Scraping brand assets (products, logo, palette, IG B-roll for inspiration)
- Defining 1-2 BG concepts grounded in brand identity (NOT generic "abstract macro")
- Sourcing BG via Pexels stock FIRST (free, native 9:16 candidates:
ink in water, sheer fabric wind, liquid bloom) — only fall back to T2V (Veo/Kling/Seedance) if Pexels doesn't deliver. Pexels-substitution validated on Clinikally; saves $7+ per run.
- Compositing per-variant: BG (palette-aware dim — heavier on light BG, lighter on dark) + product cutouts (height-anchored at vertical-center for mixed-shape SKUs, width-anchored for similar-aspect SKUs) + cold-open card + annotated end card (WHITE logo variant for dark BGs)
- Adding ambient instrumental music bed + EBU R128 loudness norm
- Delivering N variants for selection (N = num_concepts when BG=Pexels; N = num_concepts × num_models when BG=T2V)
Use when:
- Brand has clean product photography (Shopify PDP shots ideal — birefnet strips cleanly)
- Brand has an active IG presence (gooseworks scrape gives brand-coded reference)
- Aesthetic target is music-led atmospheric, NOT UGC creator or talking-head
- Budget allows multi-variant comparison ($7-10 per run for 6 variants)
Do NOT use for:
- UGC ads with creator → use
skills/molecules/ugc-ad/*
- VO-driven explainer → use
skills/molecules/explainer-video/*
- Single static product hero shot → use
skills/atoms/product-images/*
- Long-form (>15s) → format breaks past 12s
Inputs
Required:
brand_url — e.g. https://motherscience.com
products[] — 1–3 product handles/slugs. 1 = single-cutout focus, 2-3 = carousel.
Optional (with autonomous defaults):
aspect_ratio — 9:16 (default, mobile) or 1:1
duration_s — default 10.5 (range 9-12)
sub_archetype — V-CARD (default — cold-open card + carousel + endcard), V-PURE (pure carousel no text), V-TILE (persistent social-tile layout — heavier production)
bg_concept — free-text concept brief. If omitted, derived from brand category (skincare → liquid macro / molecular; cleaning → foam; supplement → ingredient bloom)
bg_model_set — ["veo-3-1-preview","kling-v2.5-turbo-pro","seedance-2.0"] (default — fire all 3 for comparison) or subset
bg_concepts_count — 2 (default — fire 2 concept variants for choice) or 1 (cheaper, less optionality)
cold_open_text — default 3 lines, e.g. "100% / PROVEN / RESULTS". 3-5 words max.
end_card_lines — small print annotations. Defaults: ["EST {year}", "{ingredient}", "NOVEL MOLECULE", "{claim}"]
music_brief — free-text. Default matched to brand category (skincare → ambient minimal electronic 90 BPM)
Prerequisites:
FAL_API_KEY in env (.env root) — for birefnet, Kling, Seedance, ElevenLabs
PEXELS_API_KEY (optional, in gtm-goose/.env) — for fallback stock
- Higgsfield CLI authed at
~/.config/higgsfield/credentials.json — for Veo 3.1
npx gooseworks credits returns balance — for IG scraping
- Homebrew installed:
ffmpeg, librsvg
Composed Atoms
source-brand-assets — WebFetch product PNGs from Shopify, brand color hex from homepage CSS, brand logo SVG from footer
remove-backgrounds — strip product PNG BG to clean alpha via fal-ai/birefnet/v2 (auto-handles overlay badges + drop shadows)
create-video-veo-3-1-higgsfield — generate cinematic BG variant via Higgsfield CLI (Veo 3.1 ultra preview, 8s, 16:9 or 9:16)
create-video-kling-v2-5-turbo-pro-fal — generate BG variant via FAL Kling v2.5 Turbo Pro T2V (10s, 1:1 supported)
create-video-seedance-2-fal — generate BG variant via FAL Seedance 2.0 T2V (8s 720p, fastest queue)
create-motion-graphics-hyperframes — render cold-open card + annotated end card via PIL + rsvg-convert for brand SVG logo (alternative to Playwright)
create-music-elevenlabs — instrumental music bed via fal-ai/elevenlabs/music endpoint, generate 12s, trim to target
composite-split-screen — used as ffmpeg filter_complex pattern reference for multi-layer composites with per-layer enable + scaling
stitch-videos-ffmpeg — used for the audio mux pass per memory feedback_ffmpeg_lcut_endcard_recipe.md (separate pass from composite)
add-music-track — apply EBU R128 loudness normalization via acompressor + loudnorm I=-18:TP=-2:LRA=9 before mux
watch — /watch:watch external skill for end-to-end QC on each final variant
- External: gooseworks
scrapecreators /v1/instagram/profile — scrape brand IG reels for B-roll inspiration (NOT used as BG directly — only for visual language reference)
Do NOT use: Klap, captions, Whisper, Soul ID, UGC-creator atoms — Vignette is silent-text only.
Workflow
Phase 0 — Brand asset gathering (autonomous)
-
Scrape product PNGs from brand Shopify (or other CDN):
curl -sL "${brand_url}/products/${handle}.json" | jq -r '.product.images[0].src'
Download highest-res; PDP shots typically 1500-2000px on white BG.
-
Background-remove via fal-ai/birefnet/v2 ($0.02 each). Birefnet auto-handles overlay badges (Glamour seals etc.) AND drop shadows. Validate alpha: ≥20% transparent, ≤8% partial-edge. NB2-edit retouch only if validation fails.
-
Scrape brand color hex from homepage — count #xxxxxx patterns, take top 5 frequencies. Logo SVG via footer link or Shopify theme assets path.
-
Scrape brand IG reels via gooseworks (~$0.02):
npx gooseworks call scrapecreators /v1/instagram/profile \
--query='{"handle":"<brand_ig_handle>"}'
Parse out video URLs. Download 3-4 reels. Do NOT use brand B-roll as the BG (felt like remix when validated) — use as REFERENCE for visual language + palette + concept inspiration.
-
Define BG concept(s) grounded in brand identity:
- NOT generic "abstract macro" — that's a style not a theme. Pexels returns stock 3D art for those queries.
- DO brand-category specific: skincare → ingredient bloom / molecular structure / serum drop; supplement → liquid swirl / pour; cleaning → foam macro
- Mother Science default: (α) Chrome Molecular Swarm, (β) Black Ink in Cream Bloom
Output: <project>/brief.md with cutout previews, brand palette swatches, IG reel thumbnails, BG concept(s) + rationale, estimated spend.
🚦 HUMAN GATE 1 — Brief approval
Show user: brief.md + sub-archetype recommendation + BG concept proposals + estimated spend ($7-10 typical for 6-variant comparison).
User approves OR edits brief.md.
Phase 1 — BG generation (post-gate, autonomous)
-
Write per-model T2V prompts per concept (see references/bg-video-sourcing-rules.md). Key rules:
- Use PHASE markers (
PHASE 1 (0-2s):), NEVER "Shot N:" labels (force hard cuts)
- Explicitly say "NOT slow motion" + add to negative prompt — Vignette format wants kinetic real-time motion
- Lock camera (
"camera locked tripod, no movement")
- Explicitly prohibit text, products, hands, people in negative prompt
-
Fire all variants in parallel via ThreadPoolExecutor:
- Veo 3.1 via Higgsfield CLI:
higgsfield generate create veo3_1 --prompt "..." --aspect_ratio 9:16 --duration 8 --model veo-3-1-preview --quality ultra --wait --json
- Kling v2.5 Turbo Pro via FAL:
fal_client.subscribe("fal-ai/kling-video/v2.5-turbo/pro/text-to-video", {...})
- Seedance 2.0 via FAL:
fal_client.subscribe("bytedance/seedance-2.0/text-to-video", {generate_audio: False, ...})
-
Render overlay PNGs at target aspect via PIL:
- Cold-open card: 3-line stacked text in Boska Black on transparent
- End card: brand SVG logo rendered via
rsvg-convert -w 2400 + autocropped → small annotations above/below in Space Grotesk + thin rule lines (Pinterest specimen-sheet style)
Phase 2 — Composite + music (autonomous)
-
Composite each variant via single ffmpeg filter_complex:
- BG: trim/loop to duration, scale-to-fit-vertical + center-crop horizontal, apply per-variant dim filter (palette-aware — see
references/composite-rules.md)
- Cutouts: scale by WIDTH (not height — for 9:16) ~75% tall bottles / ~65% squat jars, overlay vertically centered (
y=(H-h)/2), t-based enable='between(t,a,b)'
- Cold-open card overlay at t≈1.5-3.0s
- End card overlay at t≈7.8-10.5s
- Output: h264 medium crf=20, yuv420p, +faststart, 30fps
-
Generate music bed via fal-ai/elevenlabs/music:
- Brief: ambient instrumental, brand-category coded, 90-100 BPM, "builds subtly in last 2 seconds for end-card reveal"
music_length_ms: 12000 (generate slightly longer than video, trim — avoids 2nd-half decay tail)
output_format: "mp3_44100_192"
-
Process music — trim to duration + acompressor=threshold=-12dB:ratio=2:attack=20:release=200,loudnorm=I=-18:TP=-2:LRA=9 (EBU R128 -18 LUFS broadcast-ad standard)
-
Mux as SEPARATE ffmpeg pass per memory feedback_ffmpeg_lcut_endcard_recipe.md:
ffmpeg -y -i master.mp4 -i music.mp3 \
-c:v copy -c:a aac -b:a 192k -ar 44100 \
-map 0:v:0 -map 1:a:0 -shortest \
-movflags +faststart master-with-music.mp4
Verify audio bit_rate ≈ 192000 via ffprobe (not 1000 — that's the default-mapping silent bug per feedback_ffmpeg_map_directive.md).
-
Self-QC via /watch:watch each variant:
- Cutouts vertically centered (all SKUs at same visual mid-line)
- BG dim appropriate (visible but not competing)
- Cold-open card readable, dwells ~1.35s
- End card readable, holds ~2.5s
- Music instrumental, no peaks, audible
- Duration ≈ target
Output
<project>/
├── brief.md
├── shot-list.yml
├── t2v-prompts-v3-kinetic.md
├── source/
│ ├── scraped-product-images/ # raw PDP PNGs
│ ├── scraped-brand/ # logo SVG, palette
│ ├── scraped-brand-content/ # IG reels via gooseworks (reference only)
│ └── t2v-outputs/ # N BG variants
├── assets/
│ ├── product-cutouts/ # birefnet-stripped PNGs
│ ├── fonts/ # Boska + Space Grotesk TTFs
│ ├── text-overlays/ # cold-open + end card PNGs
│ └── music/ # raw + processed bed
└── finals/
└── master-<aspect>-<concept>-<model>.mp4 # N variants
Decision Rules
-
Format wins over brand category for BG layer. Vignette = "kinetic but low-information." Real-time motion, NOT slow-mo. Even for clinical-luxury brands, the BG must be kinetic — slow-mo makes the ad feel sluggish.
-
Brand wins over format for typography + product cutout + end card. Use brand-appropriate typography (clinical-luxury → high-contrast modulated serif like Boska Black, NOT condensed industrial sans).
-
T2V skips grounding constraint. Text-to-video has no image input, so the "every image must be grounded" rule doesn't apply. Use T2V freely when stock fails. (I2V still requires a grounded keyframe — real photo or improvement of one.)
-
Scrape brand IG FIRST, before any Pexels search. Gooseworks scrapecreators IG endpoint costs ~$0.02 and returns brand-validated B-roll. Pexels for "luxury skincare macro" is a 5-pass dead-end — skip it after 2 weak passes.
-
Multi-variant comparison is the right spend for first-run. Fire 2 concepts × 3 models = 6 variants. ~$7-10 cost buys CERTAINTY about creative direction vs. guessing with 1 variant.
-
Cutout placement: vertical-center, NEVER bottom-anchor. Different SKU shapes (tall bottle vs squat jar) at bottom-anchor produce visually inconsistent placement. y=(H-h)/2 aligns all visual midpoints.
-
BG dim filter is palette-aware (per-variant). If BG has high-contrast elements competing with cutouts (chrome on cream), push saturation DOWN hard (saturation=0.50) — desaturating kills the metallic/vibrant character. For naturally-contrasty BG (dark ink on cream), lighter dim (saturation=0.85) is enough.
-
End card = annotated specimen-sheet, NEVER bare logo. Layout: small tracking text above (EST DATE) + horizontal rule + brand logo + horizontal rule + small annotations (ingredient name, novelty, key claim). Reads as brand specimen sheet vs slideshow exit. Per Pinterest research (Nolan Wells Studios + Daniel Soares film-credit references).
-
Music must be instrumental for Vignette format. Vignette has text overlays (cold-open + end card) — lyrics would compete. force_instrumental: true OR craft prompt with "instrumental only, no vocals, no lyrics".
-
EBU R128 loudness norm before mux. Raw music has variable loudness. acompressor + loudnorm I=-18 TP=-2 produces broadcast-ad-grade levels that sit cleanly under spoken VO (in case repurposed) and don't peak on consumer speakers.
Quality Checks
Before declaring done, verify each variant:
Failure Modes
| Failure | Cause | Recovery |
|---|
| Pexels searches return stock 3D abstract art repeatedly | "luxury / cosmetic / abstract" queries hit stock motion-graphics db | Skip Pexels after 2 weak passes. Go directly to gooseworks IG scrape + T2V |
| Cutout has white halo despite birefnet | BG color too similar to product edges | Re-run with finer matte settings or use NB2-edit ($0.08) to remove halo |
| Brand IG profile not on Instagram OR private | Some brands only have web presence | Skip Path E. Source BG via T2V directly. |
| T2V output has hard cuts when continuous wanted | "Shot N:" labels in prompt or multi_prompt arg | Strip "Shot N:" labels. Use "PHASE N" markers. Never set shot_type=customize |
| T2V output has slow-motion when kinetic wanted | Prompt phrase "slow motion" interpreted literally | Add "NOT slow motion" + explicit "real-time speed" + slow motion to negative_prompt |
| Veo 3.1 returns aspect error | Used 1:1 or --aspect-ratio (hyphen) | Use 9:16 or 16:9 with --aspect_ratio (underscore) |
| Music has lyrics | ElevenLabs ignored instrumental hint | Re-roll with explicit "instrumental only, no vocals, no lyrics" + brief regen. If 2nd attempt also fails, use a different prompt or stock |
| Music tapers in 2nd half | Known ElevenLabs Music behavior | Generate 20% longer than target, trim. OR per memory feedback_elevenlabs_music_decay.md — loop-and-flatten with acrossfade + acompressor + loudnorm |
| Final mp4 audio is 1 kbps | ffmpeg mux without explicit map | Add -map 0:v:0 -map 1:a:0 per memory feedback_ffmpeg_map_directive.md |
| Genesis (jar) sits visibly lower than Hero/Retinol (bottles) | Bottom-anchor overlay | Use y=(H-h)/2 (vertical center) for ALL cutouts |
| Chrome BG still competes after standard dim | Chrome highlights too prominent at default saturation | Push saturation lower (0.50 vs 0.85) — desaturating kills the metallic feel |
| Veo 8s output too short for 10.5s composite |
Spend Reference (validated on Mother Science V-CARD, 2026-05-28)
| Item | Count | Per-unit | Subtotal |
|---|
| birefnet-v2 product cutouts | 3 | $0.02 | $0.06 |
| Pexels Photos/Videos search | many | $0.00 | $0.00 |
| gooseworks IG scrape | 1 | $0.02 | $0.02 |
| Veo 3.1 ultra preview T2V (8s) | 2 | $2.00 | $4.00 |
| Kling v2.5 Turbo Pro T2V (10s) | 2 | $0.70 | $1.40 |
| Seedance 2.0 T2V (8s 720p) | 2 | $0.85 | $1.70 |
| ElevenLabs music (12s) | 1 | $0.40 | $0.40 |
| ffmpeg composite + mux | 6 | $0.00 | $0.00 |
| Total (6 variants comparison) | | | ~$7.58 |
For single-variant runs: roughly $1.50-2.50 depending on model.
Sub-Archetypes
- V-CARD (validated default) — Cold-open text card (1.5s) → product carousel (3 SKUs × 1.5s) → annotated end card (2.5s). 10.5s total. Use when brand has hook copy + multi-SKU lineup.
- V-PURE — Pure cutout carousel, no cold-open, no end card text (logo only). Most minimal. Use when product visuals alone carry the message.
- V-TILE — Persistent social-tile layout with headline + quote + rating + logo over BG. Use when brand has strong review/quote content. Heavier production (custom layout, possibly animated bloom endcard).
This molecule defaults to V-CARD. V-PURE = remove cold-open beat + simplify endcard. V-TILE = significant restructure (see references/format-dna.md for the V02 ClimbOn reference pattern).
Tests
See tests/:
smoke-test.md — structural pass
sample-input.md — Mother Science worked example
expected-output.md — what successful output looks like
human-test.md — manual acceptance criteria
verifier.md — ffmpeg + ffprobe assertions
Related
-
Reference project: clients/mother-science/video-01-clinical-claim-vignette/ — full worked example with HOW_TO_MAKE_THIS_VIDEO.md + LEARNINGS.md (20 load-bearing learnings)
-
Related molecules:
skills/molecules/ugc-ad/* — for UGC creator ads (different format)
skills/molecules/product-video/* — for product-anchored ads (different format)
skills/molecules/explainer-video/* — for VO-driven explainers (different format)
-
Memory rules to read before running:
feedback_ffmpeg_map_directive.md — -map 0:v:0 -map 1:a:0 always
feedback_ffmpeg_lcut_endcard_recipe.md — separate composite + mux passes
feedback_elevenlabs_music_decay.md — generate longer + trim
feedback_image_grounding_rules.md — applies to I2V keyframes only, not T2V
reference_higgsfield_veo_cli_flags.md — Veo aspect/duration constraints
reference_kling_v3_pro_i2v.md — Kling endpoint reference (note: this molecule uses Kling v2.5 Turbo Pro T2V, not v3 i2v)
feedback_endcard_split_frame_layout.md — alternative endcard pattern
feedback_endcard_reference_pattern.md — endcard via reference + NB2 + HTML
Open Questions (not yet Decision Rules)
These need N=2+ project validations before promoting:
- Optimal BG concept count per run — we did 2; would 1 (cheaper) or 3+ (more variety) be a better default?
- Per-aspect cutout scale defaults — we validated 75%/65% width for 9:16. Are 1:1 defaults the same or different?
- Music decay frequency — ElevenLabs decay didn't manifest in our run; may be brief-specific. Track on next 3 brands.
- gooseworks IG scrape reliability — worked perfectly for Mother Science (US prestige brand, active IG). Coverage for India market / niche brands TBD.
- T2V brand-IP risk — we generated chrome molecular spheres + black ink in cream that are very SIMILAR to what Mother Science already uses. Is "inspired by brand language" an issue for brand IP? Surface to legal review for first 2-3 brand runs.