name: product-motion description: Делает короткие ролики о фичах любого продукта пользователя — обучающие, промо, для инвесторов или лендинга — в стиле Linear/Stripe: интерфейс продукта в кадре, курсор нажимает, текст печатается, камера ведёт взгляд, голос называет происходящее. HTML-сцены с покадровым рендером через Playwright и ffmpeg, стиль из бренд-профиля проекта (токены, шрифты, логотипы из его кода), экраны и надписи — из кода или прототипа текущего проекта, 16:9 и 9:16 с субтитрами и без, на любом языке. Готовит текст и промт для озвучки в Gemini TTS, раскладывает присланную озвучку по словам, ставит черновую музыку или трек пользователя, сводит и проверяет файлы. Используй всегда, когда просят «сделай / запиши / собери видео, ролик, моушн, туториал, промо или анимацию на N секунд про фичу, экран или раздел», «вертикальный кат для сторис», «подготовь озвучку для ролика», «наложи озвучку или музыку», «сделай ролик динамичнее», — даже если слова «моушн» нет.
Product Motion
Короткие ролики, которые показывают, как работает фича: интерфейс продукта в кадре, курсор нажимает, текст печатается, метки встают под фрагментами ввода, карточки появляются каскадом, камера ведёт взгляд, голос называет происходящее. Подход проверен на роликах для нескольких продуктов; здесь он отделён от конкретного бренда.
Принципы
- Кадр — функция времени. Ролик — HTML-страница, где
render(t)вычисляет состояние кадра по времени, аscripts/render.pyснимает кадры по одному и отдаёт в ffmpeg. Никаких CSS-анимаций, таймеров и записи экрана: нет рывков и рассинхрона, любой момент проверяется отдельным кадром. Движок —templates/engine.js(references/engine.md). - Показываем только то, что есть в продукте. Экраны, надписи, состояния — из кода, прототипа,
docs/или скриншотов текущего проекта. Несуществующих функций в ролике нет. Данные — вымышленные короткие названия. Придуманное для сцены (ответы, тексты состояний) называем пользователю для сверки. - Стиль — продукта, а не скилла. Цвета, акцент, шрифты, логотипы — из бренд-профиля проекта (
motion/brand/), собранного из его кода (references/brand.md). Нейтральный профиль скилла — только для черновика. - Голос не синтезируем сами. Локальные TTS звучат роботом. Пользователь получает текст и промт для Gemini TTS отдельно (или записывает голос сам) и присылает файл;
align_vo.pyраскладывает его по словам. До этого ролик живёт с субтитрами и музыкой. - Сначала глазами, потом рендер. Контактные листы ключевых моментов в выбранных форматах и
verify_scene.py— до полного рендера. Ошибки композиции дешевле всего ловить на кадрах. - Решения пользователя не угадываем. Язык, форматы, ускорение, музыка, публикация — из брифа или вопроса. Умолчания ниже — только когда пользователь не сказал иного.
Процесс
0. Окружение (один раз на машину)
python3 <skill>/scripts/check_env.py
Нужны Python 3.9+, ffmpeg/ffprobe, pip install playwright numpy scipy pillow (+ faster-whisper для озвучки), python -m playwright install chromium; для ускоренной версии — ffmpeg с rubberband. Лучше в venv проекта или рядом; сами зависимости не ставь без согласия пользователя — подскажи команды.
1. Бриф
Фича; длительность (не сказано — 30–35 с на одну фичу, 60–75 с на раздел); аудитория и назначение (обучение, промо, инвестор, лендинг); язык; форматы (не сказано — 16:9, вертикаль 9:16 предложить). Не больше двух вопросов за раз; остальное — разумные умолчания, названные в ответе. Подробно — references/brief.md.
2. Факты о фиче — из текущего проекта
Прочитай код и прототип фичи, docs/, скриншоты: экраны, точные надписи, плейсхолдеры, кнопки, состояния, что есть и чего нет. Если непонятно, что пользователь видит после главного действия, — спроси.
3. Бренд-профиль — один раз на проект
Если в проекте нет motion/brand/ — собери его по references/brand.md: brand.css (токены из CSS-переменных, темы, tailwind-конфига), локальные шрифты с проверенными правами, логотипы. Покажи пользователю кадр-образец до первого ролика. Следующие ролики берут готовый профиль.
4. Сценарий
Таблица «таймкод · что в кадре · камера/анимация · реплика» (references/storyboard.md: скелеты по длительности, плотность текста 1.3–1.6 слова на секунду, архетипы сцен). Ролик длиннее 30 с или бриф неполный — покажи таблицу и дождись «ок»; короткий с ясным брифом — можно собирать сразу и показать таблицу вместе с первыми кадрами.
5. Проект ролика
Если в проекте уже есть место для видео (promo/, design/motion/ и т.п.) — клади туда; иначе motion/<slug>/.
python3 <skill>/scripts/new_project.py motion/<slug> --brand motion/brand --lang ru --title "Фича · Продукт"
Внутри: video.html, plan.js, cues.js, tmap.js, engine.js, processing.js, base.css, brand/, build/, out/, README.md. build/ и тяжёлые out/*.mp4 — в .gitignore проекта, если пользователь не решил иначе. Если в проекте есть docs/, добавь туда короткую ссылку на ролик и его README.
6. plan.js и сцены
plan.js — единый источник: duration, fps, canvas, language, product, audience, hold, реплики vo[] (id, at, text, tts, subs), pronounce, emphasis, music. Строгий JSON после window.PLAN =.
В video.html замени демо-содержание шаблона экранами фичи: build (повторяющиеся элементы), setup (замеры E.measureAt + E.rect, ключи камеры для обоих форматов, курсор, клики), scene(t). События на экране — на слова реплик (E.sync('p3:слово', запасное)). Тёмные экраны и модалки — через E.dim() и в #app2. Рецепты сцен — references/scenes.md, правила движения и камеры — references/motion.md. Превью с ползунком: video.html?preview=1 через python3 -m http.server из папки ролика.
7. Проверка кадрами
python3 <skill>/scripts/verify_scene.py video.html --fmt both
python3 <skill>/scripts/render.py video.html stills --fmt both --times 1,6,9,12,15,19,23,27,31,34 --sheet
Открой build/stills/sheet_h.jpg и sheet_v.jpg: камера смотрит на действие; метки под своими фрагментами; текст не переносится и не обрезается; акцент только на своих местах; на стыке «обработка → результат» нет белой вспышки; в 9:16 текст крупный, субтитры над нижней панелью. Правь, пока ключевые кадры не чистые. Перед первым рендером — references/pitfalls.md.
8. Озвучка
python3 <skill>/scripts/vo_pack.py plan.js # --model 3.8 для Gemini 3.8 Flash TTS, --voice female
Дай out/voiceover/tts_text.txt и tts_prompt.txt двумя отдельными блоками кода (текст — в поле текста, промт — в поле стиля), голос (для русского мужского — Schedar первым), просьбу записать одним дублем целиком и таблицу из timing.md. Подходит и своя запись пользователя по тому же тексту. Правила — references/voiceover.md.
9. Пришла озвучка → раскладка
python3 <skill>/scripts/align_vo.py plan.js voice.wav # build/vo_aligned.wav, cues.js, out/subtitles.srt, отчёт
Прочитай build/align_report.md: слова «проверить на слух» назови пользователю с таймкодом; сдвинутые реплики лучше исправить в plan.js. Скрипт остановится, если речь заходит на финальный кадр (hold).
Ускорение — только предложение. Если ролик «тянется», предложи retime.py (читка +4.5 %, паузы короче, одна карта времени для видео, голоса, музыки и субтитров). Делай основной только по согласию.
10. Музыка, сведение, рендер, сборка
python3 <skill>/scripts/music.py plan.js --out build/music.wav # черновой синтез по разделу music
python3 <skill>/scripts/prepare_music.py plan.js track.mp3 --end-align --out build/music.wav # или трек пользователя
python3 <skill>/scripts/mix.py build/music.wav build/vo_aligned.wav --out build/mix.wav
python3 <skill>/scripts/render.py video.html video --fmt h --out build/h_subs.mp4
python3 <skill>/scripts/render.py video.html video --fmt h --qs subs=0 --out build/h.mp4
python3 <skill>/scripts/assemble.py --video build/h.mp4 --audio build/mix.wav --out out/<slug>_16x9.mp4
python3 <skill>/scripts/assemble.py --video build/h_subs.mp4 --audio build/mix.wav --out out/<slug>_16x9_subs.mp4
# … и то же для --fmt v (_9x16, _9x16_subs), если вертикаль в брифе
python3 <skill>/scripts/verify_media.py plan.js out/*.mp4 --sheet
Рендер ≈ 2–5 минут на минуту видео на формат — запускай в фоне или кусками (--start/--end, склейка assemble.py --video part1 part2 …). Синтезированная музыка — временная; для публичного ролика предложи лицензионный трек. Детали — references/audio.md. По просьбе — export_web.py (чистый MP4, WebVTT, постер, финальный кадр) для плеера на сайте; публикацию не выполняй без отдельного решения пользователя.
Что отдать пользователю
- Файлы в выбранных форматах:
<slug>_16x9.mp4,<slug>_16x9_subs.mp4(+_9x16), SRT, пакет озвучки (до записи голоса), контактный лист. Пути к файлам; если есть инструмент отправки файлов — отправь. - Коротко: длительность, что в каких сценах; что придумано и требует сверки с продуктом; что музыка временная; что не проверено (например, не слушали на слух).
- Обнови README папки ролика: статус, решения брифа, как пересобрать.
- Без пересказа процесса и без рекламы «революционного ИИ».
Файлы скилла
templates/engine.js | движок кадров: камера, курсор, клики, затемнение и верхний слой #app2, субтитры (subs=0), карта времени tmap.js, превью preview=1, замеры, markup/grad/plural |
templates/base.css | компоненты на токенах бренда: шапка, поле с переливом, метки, подсказки, тёмная обработка, выдача, поповеры, чат, оценка, финал |
templates/brand/ | нейтральный бренд-профиль: brand.css, Manrope (OFL), знак-заглушка |
templates/processing.js | нейтральная анимация обработки (кольца, блик акцента, влетающие карточки) |
templates/starter.html, plan.js | рабочий ≈36-секундный демо-ролик «Умный поиск» в вымышленном продукте Demo: хук → ввод с метками → подсказки → обработка → выдача с «почему» → сохранение → оценка → финал |
scripts/ | check_env, new_project, verify_scene, render, vo_pack, align_vo, retime, music, prepare_music, mix, assemble, verify_media, export_web |
references/ | brief.md · brand.md · storyboard.md · scenes.md · motion.md · engine.md · voiceover.md · audio.md · pitfalls.md |