astra-component-video — Видео в стиле Astra DS

Источник: ds-internal/presentations/component-video-skill/SKILL.md — пакет скилла, готовый архив dist/astra-component-video.zip. README, вход для агентов без скиллов и справочники — вложенные страницы. В вики не выложены: шаблон template/ (кладётся в пакет при сборке из ds-internal/presentations/component-video), tools/build.mjs, tools/selftest.mjs, tools/voice_check.py, pack.py, requirements.txt, examples/, dist/. Справочник references/infostyle.md кладётся в пакет при сборке из ds-internal/writing/infostyle.md и отдельно не выложен.

Шапка скилла:

name: astra-component-video
description: Собирает видео в фирменном стиле Astra Design System — 4:3, 1440×1080, MP4 со звуком; интро Astra DS → обложка → сцены → финал «разработано дизайн-командой». Ролики о доработке компонента (новое свойство, Type Scale, матрица вариантов, экраны, касания), обучающие видео-презентации (переходы, токены) и объясняющие ролики с голосом диктора (процесс, формат, решение) — с раскадровкой на согласование, локальным синтезом речи и проверкой голоса распознаванием. Движок, фон, шрифт, хронометраж, музыка и голос зафиксированы в шаблоне скилла; под ролик пишутся только данные и кадры, поэтому результат одинаков у любой модели. Use for any request to make an Astra DS video — «сделай видео по доработке <компонент>», «ролик о доработке», «видео-презентация», «расскажи голосом», «ролик с озвучкой», «анимация для команды».

Один запрос — один готовый MP4. Например: «сделай видео по доработке Current Product AF, вот ссылки на Figma и описание» или «собери объясняющий ролик с голосом по этому сценарию».

Почему у всех выходит одинаково

Ролик = шаблон + данные + кадры.

  • Шаблон лежит в template/ этого скилла: движок сцен, стили, фон, шрифт Inter, музыка, хронометраж. Он задаёт стиль и не меняется от ролика к ролику.
  • Данные — один файл videos/<ролик>.js: тексты, порядок сцен, пути к картинкам, текст диктора.
  • Кадры — картинки компонента из Figma в assets/<ролик>/.
  • Голос — локальная модель с утверждённым описанием голоса и темпом (references/voice.md).

Исполнитель пишет только данные и кадры. Всё остальное делают скрипты: tools/build.mjs собирает ролик одной командой, tools/selftest.mjs проверяет, что машина собирает образцы так же, как эталон.

Чего не делать никогда

  1. Не править шаблон: engine/, tools/, assets/fonts/, assets/vendor/, разметку index.html. Три строки index.html, которые меняются от ролика к ролику, правит build.mjs — руками их не трогать. Новый тип сцены или другой визуал — только по прямой просьбе пользователя: это меняет стиль всех роликов (references/engine.md).
  2. Не выдумывать тексты и числа. Подписи сцен, теги, пункты списков, версия, текст диктора — из описания пользователя, его сценария или журнала изменений компонента (блок «История изменений» в Section компонента в Figma). У каждого числа — источник и дата в шапке файла данных. Нет текста или источника — спросить. Ролик уходит команде как факт.
  3. Не менять brand («Astra Design System») и credit («разработано дизайн-командой») — проверка их сверяет.
  4. Не подменять крупный кадр PNG-скриншотом. Компонент крупным планом — только очищенный SVG (references/figma.md): у выгрузки PNG под компонентом остаётся фон страницы.
  5. Не перезаписывать готовый рендер. build.mjs сам кладёт новую версию рядом: <ролик>-2.mp4.

Требования

Node.js 22+сборка, метки (встроенный WebSocket)node -v
Python 3.10+ с numpy, scipy; Pillow для нарезкимузыка, нарезка матрицыpip install -r template/requirements.txt
ffmpeg и ffprobe в PATHрендер, сверкаffprobe -version
доступ к npm-пакету hyperframesрендер; Chrome для него скачивается самnpx --yes hyperframes@0.8.160 doctor
Figma MCP (официальный сервер Figma) с правами редактора на файлгеометрия и кадрывызов get_metadata
Для голоса: отдельный Python с моделью Qwen3-TTS (видеокарта NVIDIA) или Silero; faster-whisper для проверкиозвучка, проверка разборчивостиreferences/voice.md, раздел «Установка»

Без Figma MCP ролик собирается из выгрузок, которые пришлёт пользователь, — их обработка та же (references/figma.md). Без модели голоса собирается ролик, чьи фразы уже озвучены.

Какой ролик просят

Доработка компонента: «сделай видео по доработке <компонент>»шаги 1–8
Видео-презентация без голоса: токены, переходышаги 1, 3, 5–8
Объясняющий ролик с голосом: «расскажи голосом», «с озвучкой», сценарий или колодаreferences/storyboard.md: источник → раскадровка на согласование → ролик по блокам; затем шаги 5–8 и references/voice.md

Короткий ролик (до минуты) с готовым текстом голоса можно собрать без раскадровки. Длинный (больше минуты) — только после раскадровки: переозвучить три минуты дороже, чем поправить слайд.

0. Рабочая папка — один раз

  • Если в проекте уже есть папка роликов (в ней лежат engine/astra-video.js и tools/build.mjs) — работать в ней.
  • Иначе скопировать template/ скилла целиком в astra-video/ в корне проекта или туда, куда скажет пользователь. В папке самого скилла ничего не собирать.
  • На новой машине первым делом: node tools/selftest.mjs (около 4 минут). Должно кончиться строкой «Всё совпало с эталоном». Не совпало — references/pitfalls.md, раздел «Самопроверка», до начала работы.

Все команды дальше — из рабочей папки.

1. Что нужно от пользователя

Ссылки на Figma: компонент и его варианты, матрица, экраны — что показыватьспросить: без кадров ролик не собрать
Что изменилось и в какой версиивзять из «Истории изменений» в Section компонента; нет и там — спросить

Слова пользователя главнее журнала: что он назвал — то и в ролике, журнал нужен для того, чего в просьбе нет. Журнал не сверялся — так и сказать в отчёте.

Ролик о доработке на согласование не выносить: он собирается по одной просьбе. Выбранные сцены и источник каждого текста называются в отчёте — пользователь поправит по готовому. Объясняющий ролик с голосом длиннее минуты — наоборот: сначала раскадровка (references/storyboard.md).

2. Разобрать ссылки Figma

fileKey и nodeId — из ссылки: figma.com/design/<fileKey>/…?node-id=40016871-145809 → nodeId 40016871:145809.

  • get_metadata(fileKey, nodeId) на каждую ссылку — типы узлов, размеры, координаты детей. Главный источник геометрии: высоты вариантов, сетка матрицы, позиции экранов. Числа берутся отсюда без пересчёта, а не со скриншота.
  • get_screenshot(fileKey, nodeId) — понять, что на узле. В ролик не идёт.

Пример: матрица 2178×1995, у инстансов x="0" y="53" width="343" height="88", x="367" y="53" … height="88", x="734" y="53" … height="122" → в данных colX: [0, 367, 734, …], cellW: 343, строка { y: 53, h: [88, 88, 122, …] }.

3. Выбрать сцены

Сцена выбирается по сути показа, не по вкусу. Полный справочник полей — references/scenes.md.

Ролик о доработке компонента (kind: "Доработка", 2–4 сцены, обычно 25–35 с):

Свойство компонента и его значения: Type Scale = Base ↔ Scale, Size = S ↔ MvariantsSVG на каждое значение
Шаги множителя шрифта Typo Scale x1 … x1.5 и как от них растёт высотаscaleStepsSVG на каждый шаг + высоты
Вся матрица «вариант × значение»gridPNG матрицы 1x и нарезка; при 2×2–3×3 — SVG ячеек
Как выглядит в интерфейсе, сравнение экрановphonesPNG экранов 2x, до трёх
Касание, нажатие, отклик на экранеdevicePNG экрана 2x + координаты касаний
Перечень правокchangesтолько тексты

Порядок — от общего к частному: что появилось (variants) → как работает (scaleSteps, device) → вся картина (grid) → где видно (phones). Перечень правок changes — первой сценой, если правок много и они разные, иначе не нужен.

Пользователь назвал сцены — делать ровно их, в его порядке, даже если ролик выйдет короче 25 с. Не назвал — выбрать по таблице, 2–4 сцены.

Видео-презентация (обучающий ролик, 5–9 сцен, 45–60 с; kind — тема, например «Токены анимации»):

Тезисы «тег · текст»: зачем, как применятьchanges
Переход между страницами на телефоне: касание, реальная скорость, повтор в 4 раза медленнееflow
Таблица «токен · примитив · значение» по платформамtokens
Два уровня: примитивы → композитныеtiers
Длительности полосами, точки пробегают их за реальное времяdurations
Кривые анимации на одной длительностиcurves
Масштаб и непрозрачностьvalues
Дистанции ±100vw / ±100vhdistances
Компонентные токены на живом компонентеcomposite

Объясняющий ролик с голосом (процесс, формат, решение; 1–4 минуты; обложка — title):

Шаги процесса слева направо; «где ломается» — выделить стрелкуchain
Весь процесс: общий путь и ветки к платформамpipeline
Два подхода рядом и выводversus
Фрагмент файла и то же прозойcode
Команда и её выводterminal
«Откуда → куда»: поле → место в кодеmapping
Крупные числаstats
Тезисы, роли, правилаchanges
Итоговая фразаquote

Элементы этих сцен встают под голос: beat: k — на k-й фразе сцены.

Ни одна сцена не подходит — сказать пользователю, какой показ нужен, и спросить, заводить ли новый тип (references/engine.md). Самому движок не менять.

4. Подготовить кадры

Подробно, с командами — references/figma.md. Коротко:

Компонент крупно (variants, scaleSteps, composite)download_assets(…, defaultFormat: "svg"), скачать export, python -I tools/clean_figma_svg.py <сырой.svg> assets/<ролик>/svg/<имя>.svg
Матрица (grid)download_assets(…, "png", scale 1) и нарезка по координатам из get_metadata
Экран (phones, device, flow)download_assets(…, "png", scale 2) → 750×1624

Раскладка папки: assets/<ролик>/_raw/ — сырые выгрузки, svg/, grid/, screens/ — готовое.

Имя ролика — <компонент>-<суть> латиницей через дефис, например toolbar-af-scale. Имена образцов (current-product-af-scale, toolbar-af-scale, flow-motion, motion-tokens, design-contract-short, design-contract-v3) заняты: их файлы сверяет самопроверка, перезаписывать нельзя. Совпало — добавить версию: current-product-af-scale-v3.

После чистки размер SVG обязан совпасть с размером узла из get_metadata — скрипт его печатает, build.mjs сверяет ещё раз.

5. Написать данные

Скопировать ближайший образец из videos/ в videos/<ролик>.js и заменить содержимое:

current-product-af-scale.jsдоработка: variants → scaleSteps → grid из PNG 11×6 → phones
toolbar-af-scale.jsдоработка: то же, grid 2×2 из SVG (clip: false), линейка height
flow-motion.jsпрезентация: changes, шесть flow, tokens
motion-tokens.jsпрезентация: changes, tiers, durations, curves, values, distances, composite
design-contract-short.jsголос Qwen3: обложка title, chain с выделенной стрелкой, итог quote; фразы уже озвучены, собирается без модели
design-contract-v3.jsобъясняющий ролик целиком, 13 кадров, 3 мин 17 с: все сцены с голосом и beat; голосовых файлов в пакете нет — собрать можно только с моделью

В шапке файла — комментарий с источниками: файл Figma и id узлов, сценарий, раскадровка, откуда каждое число.

brand, creditне трогать
kind«Доработка» для ролика о доработке; тема — для презентации
componentимя компонента дословно из Figma; у презентации — тема латиницей, как в Figma
versionv 3.0.0 из журнала изменений; у презентации — короткая подпись («React · Flutter»)
title, titleSize, headerу объясняющего ролика: заголовок обложки одной строкой, его кегль, подпись шапки
narrator, voice, outroVoiceголос: движок и описание голоса, фраза на обложке, на финале — references/voice.md
fogне ставить: туман — визуал прежней версии
slidesсцены по порядку, у каждой type, caption; с голосом — voice (фразы) и beat у элементов

Тексты на экране и в голосе пишутся инфостилем — references/infostyle.md: главное в начале, одна мысль — одна фраза, глагол вместо отглагольного существительного, факт и число вместо оценки, без командного жаргона для широкого зрителя. Неразрывные пробелы в кадре ставит движок (nb()), в данных их писать не нужно. Голос — правила references/voice.md, раздел «Как писать текст для голоса».

  • caption — до 40 знаков, без точки в конце, с заглавной буквы: «Новое свойство Type Scale»;
  • имена свойств, значений и токенов — дословно из панели свойств Figma, латиницей как есть: Type Scale, Base, motion-page-duration;
  • множители Typo Scale — латинская x и точка: x1, x1.1 … x1.5, даже если в подписях на холсте Figma «х1,1» с русской «х» и запятой;
  • кавычки «ёлочки», тире —, числа с пробелом перед единицей: «300 мс»;
  • стрелку → не писать: её нет в шрифте Inter, она возьмётся из системного шрифта и на другой машине будет выглядеть иначе.

Числовые поля (display, top, fit, push) — значения по умолчанию и формулы из references/scenes.md, менять только если снимок на шаге 6 показал проблему. Числа в образцах подогнаны под их кадры (у variants образца top 490, а не 470) — в новый ролик их не переносить.

6. Собрать без рендера и посмотреть

node tools/build.mjs <ролик> --no-render

Около 20 секунд, ролик с голосом на три минуты — около минуты плюс озвучка изменённых фраз. Скрипт:

  1. проверяет данные: поля сцен, тексты, brand и credit, что все картинки на месте и размеры SVG совпадают с данными; у голоса — фразы под выбранную модель и номера beat;
  2. переключает index.html на ролик и ставит длительность;
  3. с голосом — озвучивает только изменённые фразы (ASTRA_TTS_PYTHON, references/voice.md);
  4. снимает метки событий и синтезирует музыку под них; с голосом — сводит голос с музыкой;
  5. прогоняет hyperframes lint;
  6. делает снимки в renders/<ролик>.snapshots/: обложка, по два кадра на сцену — в начале, когда сцена въехала, и в конце, когда всё показано, — и финал.

С голосом — ещё проверка разборчивости: <python с faster-whisper> -I -X utf8 tools/voice_check.py <ролик>. Фразы с ✗ прослушать; слово пропало или слилось — перестроить фразу и собрать снова.

Ошибка — строка «Стоп: …» с причиной; исправить данные и запустить снова.

Открыть renders/<ролик>.snapshots/contact-sheet.jpg и каждый кадр. Проверить:

  • компонент целиком, без серой подложки и обрезанных углов;
  • подписи не обрезаны и не налезают на шапку (имя компонента, счётчик) и подвал (подпись сцены, «Astra Design System»);
  • матрица целиком в кадре, подписи колонок читаются;
  • тексты — те, что дал пользователь, без опечаток;
  • с голосом — на экране то же, что звучит, и элементы встают на своих фразах.

Нашлось — поправить данные (top, display, fit, push, headSize) и собрать снова. Нужен другой момент — снимок вручную: HYPERFRAMES_SKIP_SKILLS=1 npx --yes hyperframes@0.8.160 snapshot --at <секунды> --output renders/<ролик>.extra (в PowerShell переменную задать отдельно: $env:HYPERFRAMES_SKIP_SKILLS = "1").

7. Отрендерить

node tools/build.mjs <ролик>

Повторяет шаг 6 и рендерит renders/<ролик>.mp4 в качестве delivery. Ролик на 30 с — около минуты, на три минуты — около 10 минут; запускать в фоне, если среда позволяет. В конце строка «Готово: …» с длиной, размером кадра, звуком и весом файла; расхождение — «Стоп: …».

8. Отчитаться

  • путь к MP4, длина, вес;
  • сцены по порядку с подписями;
  • откуда каждый текст: описание пользователя или журнал изменений (с id узла); у каждого числа — источник, числа без источника — отдельным списком;
  • с голосом — модель и её лицензия (Qwen3-TTS — Apache 2.0, Silero — CC BY-NC 4.0, только внутренние ролики), итог проверки voice_check.py;
  • что решено без пользователя и что не проверено.

Ничего не коммитить и не публиковать без отдельной просьбы.

Справочники

references/scenes.mdна шаге 5 — поля и значения по умолчанию всех сцен, длительности
references/storyboard.mdобъясняющий ролик: источник, раскадровка на согласование, ролик по блокам
references/voice.mdголос: движки, установка, описание голоса, темп, beat и hold, проверка, лицензии
references/infostyle.mdперед любым текстом на экране и в голосе
references/figma.mdна шаге 4 — выгрузка, чистка SVG, нарезка, запасные пути без MCP
references/pitfalls.mdкогда что-то пошло не так; Windows, PowerShell, кодировки
references/engine.mdтолько по просьбе пользователя: новый тип сцены, смена визуала