creative-carousel
Карусели для Instagram/Meta из 5-10 слайдов. Принципиально через Remotion (TSX-шаблоны), а не через Gemini Image — потому что в TSX баги с кириллицей, CTA-pill и softbox-in-frame невозможны by construction. 9 типов слайдов, 5 готовых шаблонов, $0 на рендеринг.
Что делает простыми словами
Карусель в Instagram — это серьёзный формат с большим количеством копирайта. 5-10 слайдов, человек свайпает, каждый слайд = одна мысль (хук → проблема → продукт → стата → процесс → доказательство → CTA). Конверсия выше чем у single-image.
Скилл делает ровно одну вещь: получает бриф, придумывает план карусели (через Gemini-текст), а потом рисует каждый слайд через Remotion CLI — никакой Gemini Image в боевом флоу. На выходе: PNG-секвенция, ZIP для аплоада в Ads Manager и multi-page PDF для клиентского ревью.
Почему Remotion, а не Gemini Image
Изначально (v1) карусели рисовались через Gemini Image. И там вылезали стабильные баги, которые QA-петля не всегда ловила:
| Баг | Что было | Почему Remotion решает |
|---|---|---|
| ₸ → Т substitution | Gemini подменял символ тенге на латинскую «Т» из-за токенизации | В TSX ₸ — это просто Unicode-символ в CSS, он не подвергается image-генерации |
| CTA-pill | Модель упорно дорисовывала кнопку «Подробнее» / «Купить» даже когда явно просили не делать | В TSX-шаблонах кнопок-компонентов просто нет. Невозможно отрендерить то, чего нет |
| Softbox-in-frame | На product-шотах ловила в кадр софтбоксы, штативы, аппаратуру | В Product.tsx подгружается только заранее обработанное product-фото через <Img staticFile()/> |
| Brand logo random | Дорисовывала левые лого или искажала бренд-марк | TSX рисует только текст + бренд-цвета. Лого Meta добавит сам через page connection |
| Truncation | Длинный headline обрезался посередине слова | Строки приходят из JSON и рендерятся как есть через CSS |
Per-project Remotion app
Каждый проект получает свою копию Remotion-приложения:
~/video-projects/<project>/carousel-remotion/ ├── package.json ├── tsconfig.json ├── remotion.config.ts ├── src/ │ ├── index.ts │ ├── Root.tsx ← 3 композиции: 4:5, 1:1, 9:16 │ ├── CarouselSlide.tsx ← dispatcher: type → нужный компонент │ ├── slides/ │ │ ├── Hook.tsx │ │ ├── Problem.tsx │ │ ├── Product.tsx ← <Img staticFile()/> для продуктового фото │ │ ├── Stats.tsx │ │ ├── List.tsx │ │ ├── Process.tsx │ │ ├── Comparison.tsx │ │ ├── Proof.tsx │ │ ├── Faq.tsx │ │ └── CtaSwipe.tsx │ └── lib/brand.ts ← бренд-конфиг, автопатчится из brand.yaml └── public/photos/ ← референсные фото, копируются на init
Зачем своя копия на проект: можешь менять TSX-шаблоны под конкретный бренд (например для apparatus сделать Product.tsx с другой раскладкой) — это не сломает другим проектам.
Workflow
init_project.py запускается ОДИН раз на проект. Дальше — только plan → render → pack.
Шаг 1 — bootstrap (один раз на проект)
python ~/.claude/skills/creative-carousel/scripts/init_project.py \
--project apparatus
# Что происходит:
# 1. Копирует remotion_template/ → ~/video-projects/apparatus/carousel-remotion/
# 2. Копирует все references/*.{jpg,png} проекта в public/photos/
# 3. Читает project's brand.yaml и переписывает src/lib/brand.ts
# 4. npm install (~30-60 сек, ОДИН раз)
Шаг 2 — план карусели
python ~/.claude/skills/creative-carousel/scripts/plan.py \
--project apparatus \
--topic "Запусти УВТ-кабинет за 30 дней" \
--template product_launch \
--slide-count 7 \
--output plan.json
# Один вызов gemini-2.5-flash, ~$0.0001, ~5 секунд
# На выходе — JSON с заполненными слайдами:
# { "slide_n": 3, "type": "stats", "headline": "30 дней",
# "subhead": "до окупаемости", "visual_hint": "huge centered number" }
Шаг 3 — Approval gate
Шаг 4 — рендер слайдов
python ~/.claude/skills/creative-carousel/scripts/render_slides.py \ --project apparatus \ --plan plan.json \ --output-dir slides/ \ --aspect 4:5 \ --product-photo ref_eswt_t9.jpg # Под капотом: на каждый слайд — `npx remotion still` # ~5-10 секунд на слайд, 7 слайдов → под минуту # По окончании авто-вызывает present.py (GR-1)
Шаг 5 — упаковка
python ~/.claude/skills/creative-carousel/scripts/pack.py \ --output-dir slides/ \ --zip ~/Desktop/apparatus_carousel.zip \ --pdf ~/Desktop/apparatus_carousel_preview.pdf # ZIP — для аплоада в Meta Ads Manager # PDF — multi-page, по слайду на страницу, для клиентского ревью
9 типов слайдов
| Тип | Use case | Визуальный рецепт |
|---|---|---|
hook | Слайд 1 — scroll-stopper | Огромный headline (80-100pt), один маленький визуал максимум |
problem | Слайд 2-3 — боль | Эмпатичная фраза, muted-палитра, ощущение «before» |
product | Hero-шот аппарата/услуги | Продукт 60-70% кадра, чистый градиент бренд-цвета |
stats | Большая цифра (ROI/окупаемость/доход) | ОДНА огромная цифра (200pt+), tiny label снизу |
list | Features/benefits | 01/02/03 нумерованный список, brief items |
process | 3-4 шага «как работает» | Горизонтальный stepper со стрелками и иконками |
comparison | A/B (before/after, with/without) | 50/50 split с чётким контрастом |
proof | Отзыв с цифрами | Большая кавычка, italic-quote, атрибуция |
faq | Q&A — снимает возражение | Question как headline + reassuring answer |
cta_swipe | Последний слайд — invitation | Bold action text, НИКАКОЙ кнопки |
Полный спек — в справочнике scene/slide-типов.
5 готовых шаблонов
| Шаблон | Слайды | Когда |
|---|---|---|
product_launch | hook → problem → product → stats → process → proof → cta_swipe | Запуск нового продукта/аппарата B2B (дефолт для медтехники) |
sale_promo | hook → stats → comparison → list → cta_swipe | Акция / спецпредложение / распродажа |
case_study | hook → problem → process → stats → proof → cta_swipe | Кейс одного клиента — глубокий разбор |
educational | hook → list → process → faq → cta_swipe | Образовательный пост — учим чему-то полезному |
comparison_vs | hook → comparison → list → stats → cta_swipe | Сравнение: ваш продукт vs альтернативы |
Можно либо --template product_launch, либо --slide-types hook,product,stats,cta_swipe руками.
Внутренности
Скрипты
| Файл | Что делает |
|---|---|
scripts/init_project.py | One-time bootstrap: копирует remotion_template/, фотки, патчит brand.ts, npm install |
scripts/plan.py | Бриф + topic + template → один вызов gemini-2.5-flash → JSON-план (слайд за слайдом) |
scripts/render_slides.py | Главный воркхорс: на каждый слайд из плана зовёт npx remotion still с props |
scripts/pack.py | PNG-секвенция → ZIP + многостраничный PDF |
scripts/present.py | HTML preview с scroll-snap, thumbnails, lightbox и payload-сайдбаром (GR-1) |
scripts/db.py | CRUD по carousel_decks + carousel_slides |
Hard constraints (невозможны by construction)
- NO CTA button — в TSX нет компонентов кнопок
- NO brand logo — рендерится только текст и бренд-цвета
- NO photo equipment in frame — Product.tsx подгружает только подготовленное фото
- NO ₸ → Т substitution — Unicode-символ через CSS
- NO text truncation — строки из JSON, рендер as-is
- NO PROFIT-pill/ribbon — каждый тип слайда имеет фиксированную раскладку
Стоимость и скорость
| Операция | Что использует | Цена | Время |
|---|---|---|---|
| init_project (один раз на проект) | npm install | $0 | 30-60 сек |
| plan.py | gemini-2.5-flash (text) | $0.0001 | ~5 сек |
| render_slides.py | npx remotion still (локально) | $0 | 5-10 сек/слайд × 7 = ~под минуту |
| Итого на 7-слайдовую карусель: | $0.0001 | ~2 мин (или ~1 если init уже был) | |
Для сравнения: Gemini Image-роут был ~$0.28 на карусель + регулярные баги, которые QA приходилось ловить.
Output
~/video-projects/<project>/carousel/<deck>/ ├── slide_01.png ← 1080×1350 (4:5) или 1080×1080 (1:1) ├── slide_02.png ├── ... ├── slide_07.png ├── plan.json ├── manifest.json ← порядок, типы, headlines, ген-метаданные └── preview.html ← GR-1 preview, авто-открывается ~/Desktop/apparatus_carousel.zip ← для Meta Ads Manager ~/Desktop/apparatus_carousel_preview.pdf ← для клиента
Multi-aspect
Передай --aspect 4:5,1:1 — оба формата отрендерятся параллельно (это две разные композиции в Root.tsx).
Gotchas и tips
carousel-remotion/ папки, и render_slides.py упадёт с «no remotion app found». npm install запускается только при первом init.
remotion_template/ в скилл-папке. Это шаблон, с которого делаются копии. Если нужны проектные правки TSX — правь ~/video-projects/<project>/carousel-remotion/src/slides/....
plan.py и render_slides.py юзер видит JSON. Это даёт возможность поправить headlines/subheads до рендера. Без approval rendering пошёл бы автоматом.
brand.ts автогенерятся из brand.yaml при init. Меняешь палитру в brand.yaml → перезапускаешь init_project.py → все будущие карусели обновятся.
🎬 Примеры работы
Место в пайплайне
Карусель — самостоятельный формат, не часть видео-пайплайна. Использует brand.yaml и референсы того же проекта.
Сверху над carousel может стоять creative-orchestrator с режимом carousel-orchestrate для батчей шаблонов × вариантов.