Skill #12 · Static creatives

creative-poster

Production-grade генератор статичных постеров для Meta/Instagram через Gemini 3 Pro Image. Brand-library, multi-shot referencing, итеративный refine, variant explosion, multi-aspect outpaint, Vision-based QA, OCR конкурентов, locale-aware рендер, cross-model fallback. Пэйрится с creative-orchestrator.

Путь
~/.claude/skills/creative-poster/
Триггеры
сделай постер, рекламная картинка, статика для инсты, image creative, ad poster, картинка через нано банана, generate poster, batch постеров, ocr конкурента
Зависит от
google-genai, Pillow, PyYAML, GOOGLE_API_KEY, project/brand.yaml
Пэйрится с
creative-orchestrator, creative-carousel, copywriter (для textover_hook текстов)

Что делает простыми словами

Это «студия статичной рекламы». Дёргает Gemini 3 Pro Image (он же nano-banana-pro), знает как промптить постеры по 5-компонентной формуле, автоматически подмешивает brand-context из проекта и проверяет результат на типографические ошибки. По шагам:

  1. Загружает brand.yaml проекта → palette, шрифты, voice, forbidden — собирает BRAND CONTEXT блок
  2. Загружает preset recipe (один из 16 эстетических пресетов) → typography, palette, layout hints, avoid
  3. Применяет locale (ru/kk/en/uk) — добавляет text rendering hint для алфавита
  4. Если переданы --reference картинки с ролями → multi-shot композиция с explicit role mapping
  5. Собирает финальный промпт по 5-компонентной формуле (SUBJECT + ACTION + LOCATION + COMPOSITION + STYLE)
  6. Дёргает gemini-3-pro-image-preview, при 429/503 — fallback chain
  7. Логирует в creative_posters таблицу
  8. Открывает HTML preview-страницу с payload sidebar (GR-1)
Параллельный трек к видео-пайплайну. Та же multi-project структура, тот же director.db, та же brand library — другой output формат (PNG вместо MP4). Используется для Meta/Instagram Feed (4:5) и Story (9:16) креативов.

5-Component Prompt Formula

Промпт для Gemini Pro Image собирается по жёсткой схеме (source: banana-claude, Google Cloud guide):

ComponentЧто описывается
SUBJECTHero-объект с explicit reference role(s) — что главное в кадре, какая reference-картинка играет роль hero, какая — side angle, какая — logo
ACTIONЧто происходит + viewer eye-tracking flow (куда движется взгляд зрителя по композиции)
LOCATIONWorld-building и атмосфера сцены — из user brief
COMPOSITIONRule-of-thirds, где каждый элемент сидит в процентах (например «headline в верхней трети 15-25%, продукт в центре 40-60%»)
STYLECamera (50mm equiv, 5° low angle), lighting RESULT (off-screen источники, никогда не visible equipment), artistic reference (Apple keynote / Philips Healthcare poster)
Расписывать подробно, не в двух словах. Gemini Pro Image отзывается на детализацию. Один и тот же offer с тонким STYLE-блоком («minimal studio, off-axis softbox, subtle rim light, Helvetica Neue at 95% letterspacing») даёт несравнимо лучший результат чем «минималистично, белый фон».

HARD CONSTRAINTS (зашиты в SYSTEM_RULES)

Эти правила автоматически инжектятся в каждый промпт и проверяются в QA. Нарушение = auto-fail.

#ConstraintПочему
1 NO CTA button — никаких pill/badge с «Подробнее», «Узнать больше», «Записаться», «WhatsApp», стрелки → с текстом, любые clickable-looking прямоугольники Meta добавляет CTA сама через page connection. Двойная кнопка = конфликт.
2 NO brand logo / wordmark / tagline / watermark Meta добавляет page name + avatar автоматически. Бренд передаётся через colors/fonts/voice, не через рисование «APPARATUS» в углу.
3 NO photo/lighting equipment in frame — softbox, octobox, ring light, umbrella, light stand, tripod, reflector, gel, фотограф, камера всегда OFF-CAMERA Видимый только результат света (тень, gradient, rim glow), не источник. Профессиональная съёмка не показывает оборудование.
4 Unicode glyph fidelity это U+20B8, не Cyrillic Т; × это U+00D7, не Latin x; и — настоящие тире, не - Gemini Pro Image любит подменять символы похожими буквами. Критично для KZ-проектов с тенге.
5 No text truncation — каждая quoted строка в FULL без сокращений. «ИК-терапия» не должно стать «ИК», «протоколы для всех зон» не должно стать «протоколы» Если слишком длинно — уменьшать font-size, не обрезать слова.
6 Single continuous background — никаких frames/borders/colored bars/zones edge-to-edge Чтобы outpaint в 9:16 / 1:1 / 2:3 работал бесшовно.
7 NO служебных слов — «Offer», «Bullets», «4:5», «9:16», «Reels», «Stories», «Instagram», aspect-ratio цифры, safe-zone marker'ы Эти слова попадают в промпт как разметка, но не должны проступать в финальном пикселе.
8 NO PROFIT badge как кнопка — PROFIT/BONUS текст в plain colored brand-accent цвете, без pill/capsule/ribbon/rounded rectangle background Часто Gemini пытается обрамить PROFIT-текст плашкой, что выглядит как CTA = срабатывает constraint #1.
Vertical 4:5 (1080×1350) — единственный базовый формат. Outpaint в 9:16 / 1:1 / 2:3 идёт через multi_aspect.py отдельным шагом. Текст в центральной полосе 20-80% по вертикали, минимум 5% горизонтального margin.

16 aesthetic preset recipes

Каждый preset — YAML с description, typography, color_palette[], layout_hints[], avoid[]. Загружается через --preset-recipe <slug> и инжектится как PRESET RECIPE блок в промпт.

Original 8 (Wave 4L)

SlugПод что
tech_minimalSaaS, B2B, чистый минимал в духе Linear/Vercel
premium_luxuryPremium-бренды, dark+gold, серьёзная типографика
ugc_authenticНатуральное UGC-ощущение, тёплый свет, неровная композиция
editorial_magazineЖурнальный layout, Vogue/NYT, сильная типографика
b2b_corporateКорпоратив, deep navy + accent, чистые шрифты
visual_hook_boldЯркий контраст, большой текст, бьёт в глаз
infographic_dataЦифры в центре, минимум картинки, чарты
product_hero_cleanПродукт на белом, мягкий gradient, Apple keynote-стайл

Added May 2026 (+8 из rohitg00/awesome-claude-design)

SlugЭстетика
terminal_coreBerkeley Mono, Ollama-style — терминальный минимал
warm_editorialCream + mocha + rust, Monocle-feel
cinematic_darkA24 / Apple keynote teaser, кинематографичная темнота
playful_colorNotion / Linear плоский цвет, дружелюбно
glass_futurismvisionOS / iOS 17 frosted glass
neon_brutalistBerghain / MSCHF / Off-White — резкий неон
cult_indieMixed-media collage, Death & Co атмосфера
swiss_minimalMüller-Brockmann strict grid, швейцарская школа

Кастомные пресеты добавляются как presets/<slug>.yaml в скилл-папку.

Brand auto-injection

Когда задан --project-dir, цепочка инжекции выглядит так:

gen.py запускается:
1. Load --project-dir/brand.yaml → BRAND CONTEXT блок (colors, fonts, voice, forbidden)
2. Load --preset-recipe → PRESET RECIPE блок (typography, palette, layout hints, avoid)
3. Apply --locale → text rendering hint (Cyrillic/Kazakh/English/Ukrainian)
4. If --reference-role given → multi-shot composition с explicit role mapping
5. Try --model → on 429/503 → fall through FALLBACK_CHAIN автоматически

brand.yaml — опциональная но настоятельно рекомендуемая штука. Без неё каждый gen.py требует brand colors/fonts/voice в --custom-prompt каждый раз. С ней — auto-injection.

Команды

Brand library

brand.py init <project-dir> [--from-project-yaml]
brand.py show <project-dir>
brand.py add-reference <project-dir> <image-path>
brand.py validate <project-dir>
brand.py to-prompt <project-dir>          # рендерит brand-context блок

Генерация одного постера

gen.py \
  --project-dir ~/video-projects/apparatus \
  --output out.png \
  --offer "..." --bullets "...\n...\n..." --profits "..." \
  --reference path1.jpg --reference-role "hero product" \
  --reference path2.jpg --reference-role "side angle" \
  --reference path3.jpg --reference-role "logo asset" \
  --style modern_performance \
  --preset-recipe tech_minimal \
  --custom-prompt "Brand: APPARATUS KZ. Background: deep navy gradient..." \
  --locale ru \
  [--aspect-ratio 4:5] [--upscale-4k] [--expand-9x16]

Refine (итерация)

refine.py --input poster.png --output v2.png \
  --change "headline +30%, move device left, swap red badge for gold" \
  --keep "layout, brand colors, all text content"

Multi-aspect (omnichannel)

multi_aspect.py --input base_4x5.png --output-dir out/ \
  --formats feed,story,square,pinterest,wide \
  --skip-same-aspect

# Получим: <prefix>_feed_4x5.png, <prefix>_story_9x16.png,
#          <prefix>_square_1x1.png, и т.д.

Variants (A/B explosion)

variants.py --project-dir ~/video-projects/apparatus --output-dir out/ \
  --base-offer "Конкурент уже купил УВТ" \
  --bullets "...\n...\n..." --profits "..." --reference X \
  --count 6 \
  --explore-angles math,emotion,fear,curiosity,authority,benefit

# Каждый angle переписывает OFFER через свою линзу
# (math/emotion/fear/curiosity/authority/social/urgency/benefit)
# через Gemini text model, потом дергает gen.py на каждый

QA (Vision-based)

qa_review.py --input poster.png \
  --expect-text "Headline; Bullet1; Bullet2; Bullet3; Profit" \
  [--brand-context "..."]

# → JSON: {score: 0-10, pass: bool, issues: [
#     {type, severity, description, suggested_fix}
#   ]}
# suggested_fix → сразу в refine.py --change

OCR (анализ конкурентов)

ocr.py --input competitor.jpg --structured

# → JSON: headline / subhead / bullets / cta / profit_or_offer /
#         fine_print / brand / tagline
# Фидится в video-copywriter --type reference

DB (track + learn)

db.py init                                            # создать таблицы
db.py log --output X.png --offer "..." --style ...    # записать генерацию
db.py list --project-dir ~/video-projects/apparatus
db.py link-performance --poster-id N --fb-ad-id A --ctr 1.2 --cpl 3.4
db.py winners --project-dir ~/video-projects/apparatus --metric cpl

Multi-shot referencing

До 14 reference-картинок на запрос (для сравнения: у Veo лимит 3). Каждая может иметь explicit роль:

--reference hero.jpg     --reference-role "hero product"
--reference side.jpg     --reference-role "side angle"
--reference logo.png     --reference-role "logo asset"
--reference texture.jpg  --reference-role "background texture"

Роли вшиваются в SUBJECT-блок как explicit «use IMAGE A for X, IMAGE B for Y» инструкции. Без ролей — Gemini сам решает что взять, что часто работает хуже.

Locales

LocaleЧто добавляет в промпт
ru (default)Cyrillic rendering hint, ё/ъ/ь fidelity
kkKazakh Cyrillic с қ/ң/ғ/ү/ұ/һ/ә/і/ө
enLatin rendering, простая типографика
ukUkrainian Cyrillic с і/ї/є/ґ

Текст рендерится ровно так как передан — никакого авто-перевода. Locale только влияет на качество глифов.

Cross-model fallback chain

Default: gemini-3-pro-image-preview с автоматическим переходом при 429 / RESOURCE_EXHAUSTED / 500 / 503 / NOT_FOUND:

gemini-3-pro-image-preview nano-banana-pro-preview gemini-3.1-flash-image-preview gemini-2.5-flash-image

Качество падает по цепочке, но не падает с RESOURCE_EXHAUSTED-ошибкой. Отключить — --no-fallback.

nano-banana-pro-preview — алиас для Pro-модели. Названия меняются между релизами, оба резолвятся.

Цены

ОперацияМодельЦена
4:5 base generationgemini-3-pro-image-preview$0.04
4K upscale (Pillow LANCZOS)локальноfree
9:16 outpaintinggemini-3-pro-image-preview$0.08
QA reviewgemini-2.5-flash$0.001
Refine (single)gemini-3-pro-image-preview$0.04
OCRgemini-2.5-flash$0.001
Variant rewrite (text only)gemini-2.5-flash$0.0001

Полный pipeline run (6 вариантов × 2 aspect'а + QA + delivery) ≈ $0.78. Дёшево относительно видео-пайплайна.

Скрипты

ФайлЧто делает
scripts/gen.py главный Text→image с 5-component formula prompt. Brand auto-injection, multi-shot references, locale, cross-model fallback. Логирует в БД и открывает HTML preview.
scripts/refine.pyИтеративный multi-turn edit (keep X, change Y) для тонкой подстройки
scripts/multi_aspect.pyOutpaint base 4:5 → feed/story/square/pinterest/wide через SEAMLESS OUTPAINTING промпт
scripts/variants.py Angle explosion — переписывает OFFER через линзы math/emotion/fear/curiosity/authority/social/urgency/benefit через Gemini text model, потом рендерит через gen.py
scripts/qa_review.py Gemini Vision QA → JSON {score 0-10, pass, issues[{type, severity, description, suggested_fix}]}. suggested_fix сразу фидится в refine.py --change.
scripts/ocr.pyOCR конкурентных постеров (plain или structured: headline / bullets / cta / profit / fine_print)
scripts/brand.py brand.yaml CRUD (init, show, add-reference, validate, to-prompt). Auto-injection во все gen.py вызовы.
scripts/db.py creative_posters + creative_performance + project_creative_posters таблицы. Логирует каждую генерацию, линкует Meta-API метрики для winners-репорта.
scripts/present.py GR-1: HTML preview-страница с payload sidebar (model, aspect, style, preset, locale, cost, QA score, brand context, references thumbnails, custom prompt, final prompt)

Auto-preview (GLOBAL RULE для всех creative-* скиллов)

После каждой успешной генерации gen.py автоматически логирует в creative_posters таблицу и открывает HTML preview-страницу с:

Отключить — --no-present. Вручную: present.py --output-image X.png --output preview.html --open

Зачем preview-страница с payload. Агентство ревьюит креативы читая весь payload, не только картинку. Реверу нужно видеть «этот постер пришёл из этого brief + этих references + этого preset + этих brand colors» чтобы дебажить плохие выводы и аппрувить хорошие. Preview без payload sidebar = неполный.

Архитектура папки

~/.claude/skills/creative-poster/
├── SKILL.md                      ← spec + commands cheat-sheet
├── presets/                      ← 16 aesthetic-family recipes
│   ├── tech_minimal.yaml
│   ├── premium_luxury.yaml
│   ├── ugc_authentic.yaml
│   ├── editorial_magazine.yaml
│   ├── b2b_corporate.yaml
│   ├── visual_hook_bold.yaml
│   ├── infographic_data.yaml
│   ├── product_hero_clean.yaml
│   ├── terminal_core.yaml        ← May 2026
│   ├── warm_editorial.yaml       ← May 2026
│   ├── cinematic_dark.yaml       ← May 2026
│   ├── playful_color.yaml        ← May 2026
│   ├── glass_futurism.yaml       ← May 2026
│   ├── neon_brutalist.yaml       ← May 2026
│   ├── cult_indie.yaml           ← May 2026
│   └── swiss_minimal.yaml        ← May 2026
└── scripts/
    ├── gen.py            ← главный
    ├── refine.py
    ├── multi_aspect.py
    ├── variants.py
    ├── qa_review.py
    ├── ocr.py
    ├── brand.py
    ├── db.py
    └── present.py        ← GR-1 preview

Зависимости и env

pip install google-genai pillow pyyaml
export GOOGLE_API_KEY=<key>

API-key auto-resolution: --api-key > --project-dir/api_keys.db > $GOOGLE_API_KEY.

Gotchas и tips

Gemini Pro Image — glyph rendering ненадёжен (~50% failure rate). Тенге заменяется на Cyrillic Т. Митигации: (a) принять подмену (в KZ-контексте Т читается как тенге), (b) заменить словом «тенге» в исходнике, (c) post-process через Pillow overlay (auto-fix-pass в qa_review.py — TODO).
Rate limits на Pro Image. Sequential генерация с ≥30s cooldown безопасна; параллельные вызовы тригерят 429 RESOURCE_EXHAUSTED. Fallback chain в gen.py обрабатывает transient 429 переключением на gemini-2.5-flash-image автоматически.
brand.yaml ОПЦИОНАЛЕН но настоятельно рекомендуется. Без него каждый gen.py требует brand colors/fonts/voice в --custom-prompt. С ним — auto-injection из проекта.
NOT NEVER рендерить brand logos или CTA buttons на постере. Это intentional. Meta/Instagram добавляют page logo, page name, CTA button автоматически в ad runtime через page connection. Рисование на изображении создаёт дубли/конфликты — Meta-модерация может зарезать креатив или пометить как «trust issue».
Первый запуск: creative-poster/scripts/db.py init один раз. Идемпотентно — создаёт 3 таблицы (creative_posters, creative_performance, project_creative_posters) если их нет.
QA-loop: qa_review возвращает suggested_fix в каждом issue. Это форматированная строка которая сразу идёт в refine.py --change. Можно автоматизировать loop: generate → QA → if score < 7 → refine → QA → ... Останов на score ≥ 7 или max-iter.
Variant explosion для A/B-теста. variants.py --count 6 --explore-angles math,emotion,fear,curiosity,authority,benefit — даёт 6 разных подходов к одному и тому же офферу. Дешёвый способ за $0.24 + $0.0006 (rewrite) сразу получить материал на неделю Meta-тестов.

Pairs with

🎬 Примеры работы

Открой Showcase → posters — там 9 реальных постеров для Apparatus KZ (T608, ETC5, T8) в 4:5 и 9:16, с brand-injection из apparatus/brand.yaml. Все примеры — реальные production-runs, embedded локально (работают офлайн).

Место в пайплайне

copywriter creative-poster (gen) qa_review refine (if < 7) multi_aspect deliver

Parallel к видео-пайплайну. Та же multi-project структура, та же brand library, та же director.db. Над всем этим — creative-orchestrator для batch-пайплайна.