Skip to content
Back to skills

Fb Creatives

ASecurity

How to make an N-creative FB / Meta / IG static ad pack for a real brand — generalized niche know-how, not one specific ad. A domain overlay on the standard pipeline: supplies the 5-set creative matrix (A real-people · B graphic / typography · C proof / data-viz · D meme · E niche-audience), the site-grounding pre-flight (curl CSS hex + Playwright hero screenshot used as `--ref` on every gen), the true-parallel batch shape on `openai/gpt-5.4-image-2`, the per-set prompt cookbook (testimonial ...

  • 136 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
ai-agentspythongobashexpressapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned June 1, 2026

npx -y skills add alecs5am/ralphy --skill fb-creatives --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fb Creatives?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fb Creatives
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/alecs5am-fb-creatives/badge)](https://www.skillsdirectory.com/skills/alecs5am-fb-creatives)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: fb-creatives
namespace: user
description: >-
  How to make an N-creative FB / Meta / IG static ad pack for a real brand — generalized niche know-how, not one specific ad. A domain overlay on the standard pipeline: supplies the 5-set creative matrix (A real-people · B graphic / typography · C proof / data-viz · D meme · E niche-audience), the site-grounding pre-flight (curl CSS hex + Playwright hero screenshot used as `--ref` on every gen), the true-parallel batch shape on `openai/gpt-5.4-image-2`, the per-set prompt cookbook (testimonial portrait, code-card poster, strikethrough price stack, horizontal bar chart, meme header), and the deliverable folder layout (numbered PNGs + `ads-copy.md` + `README.md`). Works for ANY brand the user names — a SaaS dev tool, a DTC product, a B2B service — the skill supplies the matrix know-how, the user supplies the brand + URL.
  USE WHEN the user asks for an "ad pack", "32 creatives", "FB / Meta / IG ads", "creative matrix", "set of static ads", "performance creatives for <brand>", with N ≥ 4 stills and a single concrete brand / site.
  This is a niche SKILL (generalized), not a remix TEMPLATE. For "remix this exact ad but swap X", that is the remix path in docs/skills-vs-templates.md. For a single poster, use /poster.
---

## Trigger

**FIRES** on a generic N-creative ad-pack brief: "make 32 FB creatives for <brand>", "ad pack for <site>", "set of Meta ads", "creative matrix", "8-10 static ads for IG feed", "performance creatives for our cold-traffic campaign". Any brand, any vertical — the skill is brand-agnostic.

**DO NOT FIRE** when:
- The brief is for ONE still (poster, drop graphic, hero image) → use [`/poster`](../poster/SKILL.md) instead.
- The brief is for a moving video (UGC / unboxing / talking-head) → match the matching `/ralphy-ugc-*` skill.
- The user points at one specific ad to reproduce (`@template:<slug>`, "remix this exact ad") → that is the **remix path**. See [`docs/skills-vs-templates.md`](../../../docs/skills-vs-templates.md).
- The user pasted `@guideline:<slug>` for a register the pack sits in (photoreal humans, anti-AI-slop) → run `ralphy guideline show <slug>` first and fold its rules into the A-set portrait prompts.

## What this skill is

A generalized matrix overlay, not a finished ad pack. It does not name a brand, a hero, a price, or a number — it tells the art-director HOW a multi-register static ad pack is built so a strong one comes out for whatever the user is promoting. It runs **through** `ralphy generate image`; it does not bypass the reference-required gate or the site-grounding invariant.

## Hard invariants

- All generation routes through `ralphy generate image` (no raw API). Read `MODELS.md` before naming any model id — the stack below is a default, not a hardcode.
- **Real-brand pre-flight: site-grounding before ANY prompt.** When the brief names a real brand URL, **dispatch a Playwright sub-agent** to crawl home + `/docs` + `/pricing` + `/features` + `/examples` BEFORE drafting brand-DNA. Read `refs/research.md` (the sub-agent's digest), not a single `WebFetch` of the home page. Every palette hex in a prompt must trace to `refs/tokens.json`; every named API symbol in code-creative slots must trace to "Documented API surfaces" in `research.md`. Skipping this cost `sotaocr-fb-001` $1.20 (wrong-palette v1 burn) + 5/32 hallucinated-Python-SDK creatives. Full discipline: [`docs/playbooks/site-grounding.md`](../../../docs/playbooks/site-grounding.md).
- **`--ref refs/hero.png` on EVERY gen.** Once captured, pass the live-site hero screenshot as `--ref` on all N creatives. Brand-palette + type drift across the pack drops to near zero. Without it, each prompt re-interprets "blue CTA" slightly differently — at 32 concepts the drift compounds.
- **Verify SDK / API surface before any code-creative.** If the C / E sets render code on screen, the named API symbol (`import foo`, `foo.parse()`) must exist on the brand's docs. If the landing only documents curl, the ad shows curl — not an invented Python wrapper. Curl is the strictly-safe fallback for HTTP APIs.
- **Append-only on regen.** Re-rolling a slot writes `.v2.png`, never overwrites. Failed / dark-bg v1 generations stay on disk as A/B reference.
- The reference-required gate still fires for **named real persons / IPs** in the A or D set — refuse without a ref or logged `--no-ref-consent`.
- The quality gate refuses, not warns — two failed `scoreImage` in a row → stop and report options.

## The niche, in one paragraph

An N-creative FB pack lives or dies on **brand consistency across distinct registers**. Ads-Manager wants 8-32 visually-distinct creatives to feed its A/B engine, but every one must read as the same brand at thumb-stop speed. The 5-set matrix gives the campaign 5 register-buckets (real people, typography, proof / data-viz, meme, niche-audience), each with 2-8 concepts inside; site-grounding + a `--ref hero.png` glue holds the brand together across all of them. The pack ships as numbered PNGs + a `ads-copy.md` (primary text / headline / description / CTA per creative) + an Ads-Manager-grouping `README.md`.

## The 5-set creative matrix

| Set | Register | Default concepts | Model |
|---|---|---|---|
| **A — real people** | photoreal candid portraits / testimonials with pull-quote | 4-9 diverse personas (age / ethnicity / wardrobe / setting); each is a pull-quote card layout: photo block + slate-900 quote + blue accent + emerald supporting-stat + CTA pill | `openai/gpt-5.4-image-2` |
| **B — graphic / typography** | wordmark posters, price-stack with strikethrough, data-viz bar chart, code-card | 4-8 visual hooks anchored on a *specific number* from the lander ("$0.003", "5× cheaper", "13 points more accurate") | `openai/gpt-5.4-image-2` |
| **C — proof / dashboard** | screenshot-flavored proof shots: dashboard tile, code-card output, before-after | 4-6 receipts: "we tested all of them", "1 PDF → 1 API call → clean markdown" | `openai/gpt-5.4-image-2` |
| **D — meme** | meme-header on a brand-tinted canvas, dunk-on-competitor, "POV: …" | 2-4; meme should ladder back to one product claim, not generic | `openai/gpt-5.4-image-2` |
| **E — niche audience** | targeted to one persona segment (indie hacker, AI engineer, ops lead, finance ops) | 2-6 segment-specific concepts; can reuse A / B / C templates with niche copy | `openai/gpt-5.4-image-2` |

The matrix scales: 8-12 starter A/B pack → 24-32 full matrix → 40+ broad-spectrum. Default mix for a 32-pack: A=9, B=8, C=7, D=4, E=4.

## Site-grounding (the T1 step)

Before writing any prompt:

1. **Dispatch sub-agent** (via `Agent` tool, `subagent_type: "general-purpose"`) to crawl home + `/docs` + `/pricing` + `/features` + `/examples` + `/blog`. Sub-agent returns `refs/research.md` (the digest), `refs/tokens.json` (CSS hex), `refs/hero.png` (Playwright screenshot), and an enumerated "Documented API surfaces" list (curl / Python / TS / GUI).
2. **Read `refs/research.md`** — never sketch brand-DNA from memory.
3. **Write `brand-dna.md`** with REAL hex values from `refs/tokens.json`, the real type stack, the real CTA color, the real hero claims.
4. **Lock the voice register** at intake (dev-honest / marketing-punchy / mix). Anchor every prompt on a *specific number* from the lander.

## Workflow

1. **Intake.** Run the creative-pack branch of intake (aspect for placements: 4:5 FB feed / 1:1 IG feed / 9:16 Stories / mix; pack size; sets to cover; brand site URL — REQUIRED; voice register; hard no's).
2. **Site-grounding.** Dispatch the Playwright sub-agent (see above). Read `refs/research.md`. Write `brand-dna.md`.
3. **Concept matrix.** Draft the 5-set scaffold; pick the N concepts the user wants. Surface the matrix in chat; get explicit "go".
4. **Prompt scaffold.** One `prompts/<slot>.txt` per concept. Each cites brand-DNA hex verbatim, names a specific photographic spec (camera/lens/grain for A-set, syntax-color spec for code-cards in B/C), includes a ban-negative for known failure modes (beauty filter, plastic skin, missing strikethrough, dark background when site is light).
5. **Generate — TRUE PARALLEL via bash `&`.** `gpt-5.4-image-2` validated for 23-concurrent (sotaocr-fb-001, 2026-05-29). NOT `ralphy queue` — the daemon was idle on 13 jobs that session. Each gen passes `--ref refs/hero.png`.
6. **Review + iterate.** Read all PNGs inline. Re-roll only mis-rendered slots (not the whole batch). Auto-versioning preserves v1.
7. **Deliverable.** `final/` with numbered prefix, `ads-copy.md` (primary text · headline · description · CTA × N), `README.md` with the concept-by-concept table + Ads-Manager ad-set grouping (real-people / diverse-personas / numbers / editorial-graphic / proof-dashboard / code / meme).
8. **Hand off** to `/evaluator` if the user wants a quality gate before delivery.

## Default model stack (verify against MODELS.md)

- **Default — `openai/gpt-5.4-image-2`.** Production-grade parallel (validated 23-concurrent at $0.20/img). Crisp typography (the wordmarks, price stacks, code-cards, syntax coloring). Use for all 5 sets. Aspect via `--size` (FB feed `--size 1080x1350`, IG feed `--size 1080x1080`, Stories `--size 1080x1920`).
- **Fallback — `google/gemini-3-pro-image-preview`.** Faster, cheaper, tolerates ≥4 concurrent, but smudges small embedded typography. Use ONLY for fast palette/composition exploration; finalize on gpt-image.

## Failure modes

- **Brand-DNA invented from memory** (dark-bg + orange when site is white + blue). Cost on sotaocr-fb-001: $1.20 + 12 min. Prevention: site-grounding sub-agent + `refs/hero.png` on T1.
- **Believing stale "cap=1 concurrent" memory on gpt-image** → 25 min wasted on a serial loop. Prevention: 2× parallel probe before architecting any batch shape; gpt-5.4-image-2 is production-grade parallel as of 2026-05-29.
- **`ralphy queue` daemon idle on pending jobs.** Use bash `&` fan-out, not `--queue`, for ad-hoc N-image batches until the daemon is reliable.
- **Hallucinated SDK in code-creatives.** Model auto-completes Python ergonomics from training prior even when brand only ships curl. Verify every named symbol against `refs/research.md` "Documented API surfaces"; fall back to curl when SDK unverified.
- **Generic "Better X for Y" copy.** Cold-traffic FB copy lands when anchored on a specific lander number. Always anchor each headline on one verifiable claim from `brand-dna.md`.
- **A-set portraits going beauty-filter editorial.** Without "naturalistic, NOT glossy" + camera/lens spec + named imperfection in the body, gpt-image defaults to fashion-magazine glaze. See the A-set cookbook below.
- **Missing strikethrough policy in price stack.** Without an explicit anti-token, gpt-image sometimes applies the strikethrough uniformly across rows. Always state row-by-row policy + negative "strikethrough on the brand row".

## Aspect ratio

`--size` is honored by gpt-image as of `loud-kids-poster-001` (lands on nearest native bucket). Defaults:
- FB feed → `--size 1080x1350` (4:5)
- IG feed → `--size 1080x1080` (1:1)
- Stories → `--size 1080x1920` (9:16)
- Mix → fan out separately per placement, do not auto-crop.

## Cookbook

### A-set — real-people testimonial (validated on sotaocr-fb-001 A2/A6/A7/A9)

```
LAYOUT (top to bottom):
1. PHOTO BLOCK (52% height): Rounded 24px-radius photograph filling width with 5% margin.
   CONTENTS: a photoreal candid portrait of <persona> — <2-3 specific features:
   age, ethnicity, hair, wardrobe>. Natural skin texture with visible pores,
   <named imperfection: mole / asymmetry / stubble>, slight facial asymmetry.
   <Setting + lighting>. Sony A7 IV, Sigma 85mm at f/2.0, Kodak Portra 400 grain,
   naturalistic, NOT glossy.
2. QUOTE CARD (30% height): Pure white panel, 88% width, thin border, soft shadow.
   - Pull-quote slate-900 Inter Medium ~52pt, slight italic, blue <ACCENT> open-quote glyph
   - Attribution slate-400 Inter Regular ~26pt
   - Below, emerald #10B981 Inter SemiBold supporting stat
3. CTA + URL FOOTER (18%): Blue <ACCENT> pill + slate-400 sub-line.

Negative: dark background, orange accent, plastic skin, beauty filter, AI fingers,
perfect teeth, frozen expression, fashion-editorial pose.
```

Key tokens: **"naturalistic, NOT glossy"** + **camera + lens + grain spec** + **named imperfection in the body**.

### B-set — price-stack with strikethrough (validated on B4/B8)

```
PRICE STACK (50% height): Four large rows stacked vertically with generous spacing.
Each row: vendor name (left, slate-900 Inter Medium ~36pt), large price
(right, Inter Black ~64pt). Vendors with strikethrough have a 4px red #DC2626
line running cleanly through the ENTIRE row (label + price) horizontally at
vertical center. The <BRAND> row has NO strikethrough and uses emerald #10B981
for the price.

Row 1: "<Competitor 1>" — "<price>" (with red strikethrough through both)
...
Row 4: "<BRAND>" — "<price>" (NO strikethrough, emerald price, small "←" arrow)

Negative: strikethrough on the <BRAND> row, missing strikethrough on the
competitor rows, broken/wavy/dashed strikethrough lines.
```

Key tokens: explicit row-by-row spec + **explicit anti-token "strikethrough on the BRAND row"**.

### B / C / E — code-card (validated on B3/C7/E3)

```
CODE CARD: A floating window-chrome card centered, ~88% canvas width, 25px corner
radius, soft drop shadow. macOS-style window-chrome header with three small
circles (red/amber/emerald), centered title "<file>.py" in JetBrains Mono.
Card body deep navy #0F172A background. Inside, 3-4 lines of crisp monospace
code (JetBrains Mono ~30pt) with line numbers in muted #475569.

Syntax: keywords blue #60A5FA, strings emerald #34D399, comments slate-400 #94A3B8,
variables cream #F1F5F9.

Line 1 (comment): # <one-line value claim>
Line 2: <curl OR import — must match the brand's documented surface>
...
```

Key tokens: **macOS chrome description verbatim** + **explicit syntax-color-per-token mapping** + **line numbers gutter spec**. Verify the named API surface against `refs/research.md`.

### C-set — horizontal bar chart (validated on B2)

```
HORIZONTAL BAR CHART: Four horizontal bars stacked vertically.
Each row has three columns:
   - LEFT: brand label, slate-900 Inter Medium ~32pt, left-aligned
   - MIDDLE: bar — rounded ends, height ~64px, track #F3F4F6, fill in row color
   - RIGHT: percentage, large Inter Bold ~48pt, right-aligned

Rows (top to bottom):
- "<BRAND>" · bar filled emerald #10B981, length 95% · "95%" in emerald
- "<Competitor>" · bar filled slate-400 #9CA3AF, length 82% · "82%" in slate-400
...
```

Key tokens: explicit three-column spec per row + named track + fill colors + named bar length as % of canvas.

## CLI cookbook

```bash
# Site-grounding sub-agent (dispatched via Agent tool — see site-grounding.md
# for the full prompt template). Output lands at refs/research.md + refs/hero.png.

# Per-creative generation — TRUE parallel via bash & fan-out
for slot in a1 a2 a3 b1 b2 b3 c1 c2 c3 d1 d2 e1 e2; do
  ralphy generate image --project <id> --slot "$slot" \
    --model openai/gpt-5.4-image-2 --size 1080x1350 \
    --ref refs/hero.png \
    --prompt "$(cat prompts/$slot.txt)" &
done
wait

# Re-roll a single mis-rendered slot (writes .v2.png — append-only)
ralphy generate image --project <id> --slot a5 \
  --model openai/gpt-5.4-image-2 --size 1080x1350 \
  --ref refs/hero.png \
  --prompt "$(cat prompts/a5.txt)"

# Quality gate
ralphy project score <id> --strict
```

At ~$0.20/creative on gpt-image, a 32-pack ≈ **$6.40 / ~25 min** (with site-grounding done first); the sotaocr-fb-001 reference ran $8.00 / ~30 min because of the wrong-palette v1 burn.

## See also

- [`docs/skills-vs-templates.md`](../../../docs/skills-vs-templates.md) — why this is a skill and not a template.
- [`docs/playbooks/site-grounding.md`](../../../docs/playbooks/site-grounding.md) — the Playwright sub-agent prompt template (mandatory T1 step).
- [`docs/playbooks/intake.md`](../../../docs/playbooks/intake.md) — the creative-pack branch of intake.
- [`docs/playbooks/art-director.md`](../../../docs/playbooks/art-director.md) — model picks + ref-anchor flow.
- `MEMORY.md` — anti-ai-slop image prompts, OR parallel gpt-image OK, verify SDK before code-creative, site-grounding before brand-DNA.
- Reference postmortem: `workspace/projects/sotaocr-fb-001/postmortem/` — the lessons + matrix this skill codifies.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.