SuperAPI AI Directory

notification-flood-ad

Design & creation

View repository

Updated 10-15 21:54

About this skill

notification-flood-ad

Use this skill when an ad concept calls for a "lockscreen avalanche" — an iPhone lockscreen filling up with N notifications from one app, sold by sheer volume and pacing. The implicit CTA is the app's icon repeating across every banner.

Scope (read first)

This molecule produces just the lockscreen avalanche MP4 — clips/master-flood.mp4. The deliverable is the notification mechanic by itself, NOT a full ad. The agent stitches it into a larger ad in a downstream pass (with whatever hook clip, end card, or audio mix the brief calls for).

If the orchestrator hands this molecule a hook clip, treat the hook as reference / inspiration, not as material to glue. The molecule never decides the ad's structure — it produces a reusable building block.

The "optional concat" section near the bottom describes how to stitch hook+flood as a follow-up step, but that stitch is the agent's responsibility (or another molecule's), not this one's.

Reference build

Originally validated in content-goose at clients/Yuba/ad-runs/run-02-run2/. Adapt paths to your project.

  • clients/Yuba/ad-runs/run-02-run2/ — 9s vertical Yubo ad with IRL park hook (couple on a picnic blanket, meme caption) → lockscreen avalanche of ~18 Yubo notifications → blue tear overlay sweeps across as the stack overflows.

Purpose

Stitch a hook clip + an animated lockscreen avalanche + (optional) end card into a single shippable 9:16 master MP4. The lockscreen animation is driven by a TIMELINE inside a single continuous Playwright recording — same architecture as create-imessage-video-ad, but driving the render-ios-lockscreen atom instead of create-imessage-mockup.

When to use

  • Ads selling popularity / FOMO / demand ("you'll have so many matches/messages/orders you can't keep up")
  • Dating-app / social-app ads where volume = product proof
  • Marketplace / job-board ads where the punchline is "they keep coming"
  • Any time the brief mentions "phone blowing up", "notification flood", "lockscreen full of"

If the punchline is a single message reveal (FREEPACK code, screenshot of a result), use create-imessage-video-ad instead. If the brief is "person realizes / scrolls / discovers", use a chat thread or hyperframe, not a lockscreen avalanche.

Inputs

  1. brief (required) — what the ad is selling, the app/brand, the volume that makes the joke land (typically 15–25 notifs).
  2. output_folder — <brand>/ad-runs/run-NN-<slug>/ (usually preset by the orchestrator).
  3. brand — { name, app_icon_path }. app_icon_path is the real square PNG of the app icon (see auto-memory: end-card-needs-real-product). For Yubo: clients/Yuba/brand-assets/app-icon.png.
  4. sender_roster — list of { name, avatar_src? }. The molecule shuffles + animates each banner from this list. 15–25 entries is the sweet spot. If avatar_src is omitted, the atom generates a procedural monogram avatar.
  5. wallpaper (optional) — { type: "ios-default" } (recommended — gives the real deep-navy iOS feel), or a custom gradient/image. Defaults to ios-default.
  6. tear (optional) — set decoration.tear: { rotate: -10 } to enable the procedural CSS-only tear/glitch sweep at the climax. No PNG asset needed.

Composed Atoms

  • skills/atoms/messaging/render-ios-lockscreen — generates the lockscreen HTML (insert-flood mode, light frosted iOS-16 cards, the .arrive width-expand keyframe); this molecule drives it via Playwright. This is the load-bearing atom — most of the visual fidelity comes from it.
  • skills/atoms/assembly/stitch-videos-ffmpeg — (downstream) concat the flood with a hook clip (+ optional end card) into the full ad in a follow-up pass.
  • (optional) iOS notification SFX (CC0). Reuse skills/molecules/create-imessage-video-ad/assets/sfx/imessage-receive.mp3 — it's already loudness-normalized. The flood needs roughly one cue every 100–250 ms but mixed quiet (~ -16 LUFS) so the cumulative loudness doesn't peak. Set volume=0.40,alimiter=limit=0.95.

Critical knowledge — read before producing your first ad

These are mistakes that have already been made elsewhere in this skill family. Do not re-introduce them.

0. The volume IS the CTA — do not weaken it with copy

Adding "Download Yubo" overlay text or a hard CTA card during the avalanche kills the joke. The avalanche works because the viewer's brain finishes the sentence ("that many people on this thing?"). End card belongs AFTER, not during. The avalanche itself carries no overlay text — only the lockscreen UI.

1. Real app icon, not styled CSS or AI

Per auto-memory feedback_end_card_real_product: pull the actual square PNG from the App Store icon (1024×1024) or the brand press kit. CSS/AI approximations look amateur even at 38×38. The render-ios-lockscreen atom takes the icon path verbatim and uses it as the banner's left tile — point it at the real file.

2. Single continuous Playwright recording

Same rule as create-imessage-video-ad knowledge #3: record the WHOLE lockscreen animation as ONE continuous Playwright session, never per-scene with reloads. Every reload causes a micro-flicker, and faking the "stack overflow" by removing banners between scenes looks janky.

Architecture (scripts/record-master.template.js, copy to the run's clips/):

  • Render the lockscreen HTML in insert-flood mode (atom builds an empty .notif-pool + a hidden .notif-source pool of all banners), on a 9:16 config.canvas zoomed ×3 (crisp text, fills 1080×1920).
  • An embedded driver pre-fills a few banners, then on each ARRIVALS[t] clones a source banner into the pool at slot 0 with the .arrive class (width-expand) and bumps every existing banner's --slot one row down (instant reposition).
  • ARRIVALS (steady 0.333s) is the single source of truth for the schedule AND the SFX cue list. Record at 3× then ffmpeg-downscale to 1080×1920; mux the receive-SFX per cue; clamp the output to the video length (-t) so the last SFX tail can't leave a frozen frame.

3. Pacing — STEADY ~0.333s cadence (measured from the reference)

This was re-derived frame-by-frame from the reference ad (inter-frame motion analysis on the actual mp4). The flood is dead steady: one notification every ~0.333s (≈10 frames at 30fps), ~11 of them. It is NOT a burst, NOT accelerating, NOT decelerating. An accelerating/uneven cadence reads as wrong — the operator rejected it repeatedly until it was set to a flat 0.333s.

Set ARRIVALS in record-master.js to evenly-spaced 0.333s steps. Verify by re-measuring the render the same way (tblend=difference → spike timestamps → the gaps should all be ~0.33s).

4. The stack grows DOWN — newer banners on top, older pushed down

iOS visually stacks the newest notification at the top of the lockscreen's notification area, with older ones sliding down (or condensing). The atom matches this convention: notifications[0] renders at the top. The molecule must prepend each new banner to the DOM stack as it pops in, or pre-render them all and reveal in reverse order. The reference avalanche does the latter (simpler + deterministic).

5. Banner ARRIVAL geometry — WIDTH-EXPANSION, not a slide, not a pop

This is the single hardest detail to get right; it took many iterations. The correct arrival (verified against reference frames 8→9→10) is:

  • The new banner appears at the TOP slot narrow (reduced width, ≈80%) and expands horizontally to full width as it settles down into place over ~5 frames (~150ms). It's a scaleX (width) animation + a tiny downward settle.
  • It is NOT a uniform scale-pop, and NOT a slide-in from above.
  • The existing banners below must reposition INSTANTLY (the gap opens in one frame). If they slide down over ~90ms, the displaced banner is caught sliding THROUGH the incoming one and they visibly stack on top of each other — the operator explicitly rejected this. Only the new banner animates.

This lives in the atom CSS (render-ios-lockscreen/templates/lockscreen.css): the .insert-flood-mode .notif has transition: none (instant reposition) and the incoming banner gets the .arrive keyframe (translateY(-9px)→0 + scaleX(0.80)→1.0). The molecule's driver adds the .arrive class to each cloned banner on insert and sets every existing banner's --slot one row down.

Implementation note (do not re-trip): driving the scale via a CSS custom property

  • transition did NOT animate in the headless renderer — the keyframe approach is required.

6. Visual look — real iOS-16 material; NO tear, NO emoji band by default

The Yubo reference uses none of the decorative overlays that earlier drafts of this skill recommended. Match the real iOS-16 lockscreen instead:

  • Full-bleed 9:16: author the lockscreen on a 9:16 canvas (config.canvas) and zoom it ×3 so it fills 1080×1920 — NO pillarbox bars, NO horizontal stretch (rendering at true iPhone 19.5:9 and padding into 9:16 caused side black bars).
  • Cards = light frosted material: rgba(245,245,245,0.55), backdrop-blur 40px, radius 23px, black text (from the iOS-16 UI Kit Figma). Dark translucent banners with white text read washed-out over a wallpaper.
  • No decoration.tear and no headerOverlay emoji band unless the brief explicitly asks. The operator rejected both as unrequested noise. The volume of the flood is the whole effect (knowledge #0).
  • Pure brand flood: drop any filler Mail/Messages rows; use unique sender names.

7. End card is static — no Ken Burns, no zoompan

Same as iMessage molecule knowledge #5. If using an end card, render it as a single PNG with the real wordmark + app icon (or just the wordmark on a colored slate), then ffmpeg with -loop 1 -t 1.8 and crossfade in over 250 ms. Drifting end cards undercut the punch.

8. Hook clip MUST be a real-feeling moment

The hook is the trust-building beat. AI-generated UGC stand-ins for the hook are a known failure mode for this format — see auto-memory feedback_multi_cut_ai_supplement_ads. Either:

  • Use real footage the operator provided (IRL, UGC, found content with rights cleared), OR
  • Use a single-take talking-head clip from create-ugc-heygen / lipsync molecules

Do NOT generate the IRL hook scene with image-to-video. The avalanche payoff already pushes the viewer's "is this AI?" detector — making the hook AI too breaks the format.

9. Audio bed: silence under the hook, soft pad under the flood

Keep the hook clip's native audio (ambient + meme caption silence). For the avalanche, layer:

  • A low pad (~-22 LUFS) — see references/audio-recipes.md for a free CC0 pad
  • The receive SFX cues at volume=0.35 (quiet — there are 15–25 of them)
  • A single louder "thunk" cue on the tear overlay reveal at volume=0.7

If the hook clip has dialog, duck the avalanche audio down by 6 dB until the hook ends.

Workflow

State 0 — Brand sanity check

  • Confirm the brand wants a volume-as-CTA angle. If they want a clear feature explanation, use a different format.
  • Confirm the real app icon PNG exists in the brand-assets folder. If not, pull it before proceeding (App Store apps.apple.com/.../id<APP_ID> → screenshot of the icon, or the brand press kit).
  • No competitor-bashing (auto-memory: feedback_no_competitor_bashing_in_ads).

State 1 — Lock the hook clip

  • If the operator provided one, validate: 2–4s, vertical, meme caption already burned, no other on-screen text.
  • If not, brief them: hook needs to land the premise in <3s before the lockscreen reveal. Don't generate a fake one with i2v.

State 2 — Sender roster

  • 15–25 names. The molecule shuffles them and assigns a slide-in time per banner via the TIMELINE.
  • Avatars are optional; without them, the banners render as plain Yubo rows (which still works visually).
  • Names should fit the app's demo: a dating-app flood needs first names + age-appropriate; a job-board flood needs role keywords ("Recruiter at …").

State 3 — Lockscreen config

  • Build production/lockscreen-base.json matching the render-ios-lockscreen atom's schema.
  • Fields the molecule fills in deterministically from inputs: notifications[], decoration.tear, wallpaper.
  • Operator-tunable: clock.time, clock.date, headerOverlay.text.

State 4 — TIMELINE

  • In scripts/record-master.js, the TIMELINE array is the single source of truth for both the recording and the SFX cue list.
  • Use the cadence rules in critical knowledge #3.
  • 18–22 banners is the canonical size; below 12 the joke doesn't land, above 28 it stops escalating.

State 5 — Record (this is the molecule's deliverable)

# Record the avalanche as ONE continuous video → master-flood.mp4 + master-flood.sfx.json
NODE_PATH=<repo>/skills/atoms/messaging/render-ios-lockscreen/node_modules \
  node clips/record-master.js

clips/master-flood.mp4 is the molecule's output. Register it in production/asset-manifest.json with role: "active_master".

State 6 — Review

Open the Final tab; play clips/master-flood.mp4 against the brief. Re-time individual events by editing TIMELINE; re-run the recorder; done.

State 7 (downstream, optional) — concat with a hook clip

If the agent wants to glue this flood into a full ad, the scripts/stitch.template.sh reference in this skill folder shows how to concat a hook clip + flood + end card with deterministic SFX. That stitch is NOT part of this molecule's responsibility — it's a separate pass run by whatever skill owns the ad's overall structure.

Decision Rules

Question Rule
How many banners? 15–25. <12 = doesn't escalate; >28 = stops being funny.
Avatars on banners or no? Use avatars when the app is people-first (dating, social, marketplace with humans). Skip avatars when the app is transactional (job notifications, order alerts).
Tear overlay or no? Always for FOMO/popularity angle. Skip only if the brand voice is grounded/serious (rare for this format).
End card or no? Optional. If the brand wordmark already appears on every banner (because the brand IS the app), an end card is redundant. Use only when the avalanche is for a sub-feature (e.g. "Yubo Live") that needs the parent brand named.
What goes in the hook clip? A 2–4s relatable moment that implies the volume payoff before showing it. Couple bickering, single person doom-scrolling, "POV your phone after [event]".
Where do SFX go? Receive cue on every banner pop (quiet), one loud thunk on the tear reveal, ducked under the hook's dialog.

Output

<output_folder>/
  production/
    lockscreen-base.json     # config for the render-ios-lockscreen atom
    sender-roster.json       # (optional) the source name list before injection into the config
  clips/
    record-master.js         # copy of this molecule's template (the only script needed)
    master-flood.mp4         # ← THE DELIVERABLE. 4–6s, 720×1280, 30fps, h264, no audio.
    master-flood.sfx.json    # deterministic SFX cue list (for downstream mixing)

Optional downstream artifacts (NOT produced by this molecule):

  hook/hook-clip.mp4         # supplied by agent / operator if they want to concat
  edits/stitch.sh            # follow-up concat — see scripts/stitch.template.sh
  edits/master-final.mp4     # output of the downstream concat

Quality Checks

Before declaring the ad shippable:

  • Audio peaks at 0 dB (ffmpeg -af volumedetect); mean roughly -11 to -13 dB
  • Cumulative SFX doesn't crackle — alimiter is present in the mix chain
  • No micro-flicker between hook → lockscreen — there should be ONE crossfade (or hard cut) at this boundary, no others inside the avalanche
  • App icon on every banner is the real PNG, not styled CSS
  • First banner pops 350–500 ms after the lockscreen reveals (not instantly — leave a half-beat of "calm before the storm")
  • Pacing accelerates per critical knowledge #3 (verify by reading clips/master-flood.sfx.json cue times)
  • Tear overlay (if present) fades in around banner ~10, not at start
  • No on-screen ad copy on top of the avalanche — only the brand's notification UI
  • End card (if present) is static — no Ken Burns drift
  • /watch the final master and verify subtitles/captions/glyphs render correctly at 1×

Failure Modes

Symptom Cause Fix
Banners pop in but stack flat (no escalation feel) Flat cadence in TIMELINE Re-time per critical knowledge #3 — first 2 slow, then accelerate
Avalanche reads as "just a list of notifications" No tear overlay, no audio escalation Add tear overlay sweep + louder thunk SFX at the climax
Phone bezel / status bar looks generic / wrong device: "iphone-15-pro" not set on the lockscreen config, OR bezel is on but molecule was supposed to composite into hand-held phone shot Match the framing: if the lockscreen is alone, use bezel; if compositing into a hand-held shot, use device: "bare"
Notification body wraps to 2 lines Body text too long Trim or use truncate: true on the notification
App icon renders as broken-image square Path didn't resolve at render time Use absolute path OR copy icon into the project folder before generating the config
Pinned banner doesn't look pinned Forgot pinned: true on the notification, OR pinned banner isn't first in the array Pinned must be notifications[0] AND have pinned: true
SFX overpower the bed amix defaulted to normalize=1, dividing every input by N Same as iMessage molecule knowledge #6: amix=inputs=N:duration=first:normalize=0 then volume=*,alimiter=limit=0.95
Hook clip → lockscreen cut feels jarring Hard cut with no audio bridge Add a 200 ms crossfade and start the lockscreen's audio bed ramping in 400 ms before the visual cut
Brand looks like it's begging Added "Download Yubo" text overlay on the avalanche Remove it (critical knowledge #0)
Lockscreen looks AI / fake Used CSS-styled app icon instead of real PNG Replace with the real app-store icon at the real path
Avalanche keeps going past the joke Too many banners Cap at 22 visible; the last 2–3 can be partially below the safe-bottom edge to imply "more coming"

Reference run

See clients/Yuba/ad-runs/run-02-run2/ for the canonical Yubo example. Copy its production/lockscreen-base.json + clips/record-master.js and swap brand assets + sender roster as the starting point for a new brand.