slidev-theme-practicum
v2.0.0
Published
Strict Slidev presentation theme with a 12x12 grid, editorial layouts, and low-level slot composition API
Maintainers
Readme
slidev-theme-practicum
Тема Slidev для презентаций Практикума. Этот README в первую очередь помогает автору слайдов выбрать подходящий тип кадра и понять, что на нём писать. Технические поля и API описаны ниже, для тех, кто редактирует разметку руками.
Быстрый маршрут для автора
- Откройте example.md и найдите слайд, похожий по задаче.
- Скопируйте весь блок слайда от
---до следующего---. - Замените видимый заголовок и остальной текст в теле слайда, затем пункты или числа. Технические поля лучше не трогать, пока не станет понятно, за что они отвечают.
- Проверьте, что тезис, факт, инструкция и вывод читаются без фотографии и декоративных элементов.
- Если подходящего примера нет, сначала выберите задачу слайда по таблице ниже.
Агентный скилл
Для коротких промптов вроде «сделай слайды в стиле Практикума» в репозитории есть скилл skills/slidev-practicum/SKILL.md. Он фиксирует связку: официальный Slidev-скилл отвечает за технический синтаксис и экспорт, а этот README и example.md — за публичный API и визуальные правила темы.
Для локального просмотра:
npm install
npm run dev
npm run validate-deck example.mdПроверка markdown-контрактов своей колоды (после npm install slidev-theme-practicum):
npm exec -- slidev-practicum-validate path/to/slides.mdВ package.json колоды:
"validate:slides": "npm exec -- slidev-practicum-validate slides.md"В example.md у канонических слайдов в заметках автора (<!-- Контракт … -->) описано, сколько пунктов и какой вложенности ждёт каждый kind.
Строгая проверка типографики
Режим включается явно. Обычная проверка и внешний вид существующих макетов сохраняются. Галерея показывает весь API темы, поэтому её варианты с muted и несколькими уровнями текста могут не проходить строгую политику.
Правила для содержательного текста слайда:
- Не более двух размеров обычного текста, включая заголовок, подписи, даты и номера шагов.
- Третий размер разрешён только для явно отмеченных ключевых чисел:
<Text as="data" size="9">42%</Text>. В этом режимеas="data"означает утверждение автора, что это ключевое число. Все такие числа на слайде должны иметь один размер. Содержимое не проверяется на наличие цифр. - В каждом
Slotодин цвет текста, безmutedи токеновtext-muted*. Между разными слотами цвета могут различаться. - Текст должен помещаться в границах содержимого слота. При переполнении измените текст или композицию.
- Шапка, номер слайда в шапке, логотипы, фоновые и SVG-иллюстрации исключены. Содержательные подписи к иллюстрациям учитываются.
Пример явной композиции: два обычных размера 5 и 3, отдельный размер 7 для ключевого числа, один основной цвет слота.
---
layout: message
centered: true
---
<Slot role="primary">
<Text as="h1" size="5">Результат эксперимента</Text>
<Text as="data" size="7">42%</Text>
<Text size="3">Участники завершили практическое задание</Text>
</Slot>Проверка объявленных атрибутов:
npm exec -- slidev-practicum-validate slides.md --typography-guardОна считает только явно объявленные Text, сравнивает токены цветов внутри Slot и ловит запрещённый muted. Диапазон size="7-8" считается одной политикой подбора, size="0-12" — политикой автоматического подбора. Литеральные привязки вроде :size="7" и :muted="false" поддерживаются. Динамические размеры, цвета, теги, стили и условные ветви получают сообщение о невозможности статической проверки. Они не подменяются значениями по умолчанию.
Для итоговой проверки сначала соберите эту же колоду, затем проверьте результат в Chromium:
npm install -D playwright-chromium
npm exec -- slidev build slides.md --out dist
npm exec -- slidev-practicum-check-typography slides.md --dist distКоманда ожидает загрузки шрифтов и стабильного подбора текста, проверяет вычисленные размеры и цвета видимых текстовых фрагментов, затем их выход за границы слотов. Учитываются также вложенная разметка, ссылки и текст, созданный сокращёнными Markdown-макетами и компонентами темы. Разные токены одного вычисленного цвета в браузере объединяются. Сообщения содержат номер слайда, фрагмент текста и найденные значения. Нарушение или ошибка отображения дают код выхода 1.
Используйте свежую сборку указанного файла с корнем сайта /. Поддерживаются маршруты hash и history. Проверяется начальное видимое состояние каждого слайда, без перебора кликов, анимаций и интерактивных состояний. Включения слайдов через src пока явно отклоняются. Статический результат не заменяет браузерный. При динамических атрибутах итоговый вердикт даёт браузерная команда для показанного состояния.
Порядок работы агента:
- Включайте режим, когда он выбран для колоды. При копировании примера из галереи проверяйте его по строгим правилам: сама галерея не гарантирует их соблюдение.
- Запустите статическую проверку, затем сборку и браузерную проверку. Если строгая статическая проверка не может вычислить динамические атрибуты, отдельно запустите обычный
slidev-practicum-validateчерезnpm exec --для проверки макетов, а типографику подтвердите браузерной командой. В отчёте укажите эту границу проверки. - Исправляйте замечания в колоде. Если сокращённый макет создаёт
mutedили лишние размеры, используйте явныеSlotиTextлибо локальный вариант по контракту темы. Не редактируйте установленный пакет и не маскируйте замечание дополнительным мелким размером. - После исправлений повторите проверку объявлений, пересоберите колоду и проверьте новую сборку. Успех — отсутствие диагностик в применимых проверках и код выхода
0. Интерактивные состояния проверьте отдельно.
Если команда или флаг отсутствуют, проверьте установленную ревизию slidev-theme-practicum: она должна содержать этот режим. Обновите зависимость на нужную ревизию перед проверкой. Отсутствие инструмента не означает, что колода прошла проверку.
В репозитории темы доступны npm run check-typography -- slides.md --dist dist и npm run test:accessibility -- --typography-guard. Последняя команда проверяет готовую сборку галереи example.md с дополнительной строгой политикой. Автоматические проверки самого механизма запускаются через npm run test:typography и входят в npm test.
Для использования в другой Slidev-презентации:
npm install -D slidev-theme-practicumtheme: practicumТема не загружает шрифты из сети. Если YS Text установлен в системе, браузер использует его локально. Иначе стек последовательно переходит к локальному Inter, системному интерфейсному шрифту и sans-serif. Поэтому сборка и показ остаются офлайн-воспроизводимыми, но метрики текста без YS Text могут немного отличаться. Перед выпуском проверяйте галерею тем же окружением Chromium, которым сформированы пиксельные эталоны.
Структура проекта колоды
Для презентации, которая использует установленную тему, каноническая точка входа — slides.md, а локальные медиа лежат в public/ и подключаются абсолютным путём от корня сайта:
<deck>/
├── slides.md
├── decors.yaml # необязательный внешний каталог декора
├── package.json
├── package-lock.json
├── pages/ # разделы большой колоды
├── components/ # только компоненты этой колоды
│ └── layout-variants/ # локальные варианты тематических layout
├── layouts/ # новые нативные layout самой презентации
├── snippets/ # импортируемые примеры кода
├── styles/index.css # локальные глобальные переопределения
├── public/
│ ├── decor/ # графический декор
│ ├── photos/ # фотографии
│ ├── illustrations/ # контурные предметы, парные PNG/SVG
│ └── figures/ # схемы, графики и снимки интерфейса
└── reference/ # исходники и источники, не входящие в сборкуСоздавайте необязательные каталоги только при появлении содержимого. Не заводите параллельные assets/, images/ или img/. Фотография остаётся в photos, даже если служит фоном; контурный предмет остаётся в illustrations, даже если используется как декор. Для файла колоды пишите /photos/team-workshop.webp, а не public/photos/... и не /theme/photos/.... Префикс /theme принадлежит только встроенным файлам темы.
Полный контракт структуры, классификации, именования и проверки закреплён в агентном справочнике deck-project-structure.md. Производственный контур сюжетных фотографий описан в photographic-illustrations.md, а протокол создания парных PNG/SVG для контурных предметов — в contour-illustrations.md.
Как выбрать слайд
Выбирайте не по теме презентации, а по задаче кадра.
| Задача автора | Что использовать | Что писать |
| --------------------------------------- | ------------------------------------------ | -------------------------------------------------- |
| Открыть презентацию, курс или раздел | Обложку (cover) | Название и короткое ожидание от темы |
| Остановить внимание на одной мысли | Тезисный слайд (message) | Один тезис, вопрос или вывод |
| Дать внешний голос | Цитату (message, quote) | Короткую цитату и автора |
| Объяснить понятие, ситуацию или решение | Поясняющий слайд (explainer) | Заголовок и связное пояснение |
| Дать большой текстовый блок с разметкой | Текстовый блок (explainer) | Абзац, затем короткий список или критерий |
| Показать план, правила или шаги | Коллекцию (collection) | Однотипные пункты в одном формате |
| Сопоставить два состояния или подхода | Relation (collection, relation) | Две стороны с самостоятельными заголовками |
| Показать последовательность действий | Points (collection, points) | От 3 до 6 коротких действий |
| Показать события во времени | Таймлайн (collection, timeline) | Годы или месяцы и короткие подписи |
| Показать несколько чисел | Метрики (collection, metrics) | Главное число и подписи, которые объясняют масштаб |
| Дать несколько пронумерованных опор | Points (collection, points) | От 2 до 6 значений с необязательными подписями |
| Собрать нестандартную композицию | Ручную сетку (none) | Только когда обычные типы не выражают задачу |
Что писать
Заголовок должен отвечать на вопрос «что зритель должен понять сейчас?». Не называйте слайд технически вроде «Метрики» или «Композиция», если можно сразу написать вывод.
В первом headmatter верхнеуровневое поле title разрешено: это служебное название всей колоды для HTML-документа и метаданных Slidev, а не содержимое первого слайда. Видимый заголовок всё равно пишите в теле: как # … для сокращённой записи или как <Text as="h1">…</Text> для явной композиции, включая cover. Со второго слайда верхнеуровневое поле title запрещено, чтобы метаданные не принимали за отображаемый текст. Имена авторов, подписи и значения также пишутся в теле слайда. Во фронтматтере остаются только параметры оформления и служебные метаданные.
Поясняющий текст нужен для контекста, ограничения или критерия выбора. Если текст превращается в два разных вывода, разнесите его по двум слайдам.
Список работает, когда пункты однотипны: шаги, правила, критерии, темы. Пишите пункты в одинаковой грамматической форме, чтобы их можно было быстро просканировать.
Числа должны быть самодостаточными: значение плюс подпись должны объяснять, что измерено. Если число главное, остальные числа поддерживают его: показывают масштаб, выборку, срок или сравнение.
Цитата должна быть короткой. Авторство добавляет источник, но не должно конкурировать с самой фразой.
Семантические роли изображений
Роль изображения определяется не форматом файла и не компонентом, а тем, что зритель должен из него понять.
| Роль | Назначение | Требование к смыслу | |---|---|---| | Декоративная фотография | Настроение, ритм, плотность, брендовый характер или пауза | Взаимозаменяема: если её убрать или заменить, вывод слайда не изменится | | Сюжетная фотографическая иллюстрация | Конкретная метафора, действие или сквозные персонажи | Не взаимозаменяема внутри сюжета, но не является единственным носителем факта, инструкции или вывода | | Информационная фигура | Схема, график, интерфейс, сравнение или доказательство, которое нужно рассмотреть | Существенные данные и вывод продублированы доступной подписью или текстом слайда |
Встроенные фотографии темы и выбор через decor всегда декоративные. Колода может добавлять собственные сюжетные фотографии в public/photos/ и размещать их через Image или Slot.background. В таком случае конкретный сюжетный смысл должен быть назван заголовком, текстом, подписью или доступным описанием: фотография поддерживает рассказ, но не заменяет его.
Не пишите о декоративной фотографии: «фото доказывает» или «фотография объясняет число». Если зритель действительно должен рассмотреть данные, интерфейс или причинно-следственную схему, это информационная фигура из public/figures/, а не декоративный слой.
Живая галерея
Рабочие примеры для авторов хранятся в example.md. README объясняет, как выбирать и писать слайды, а example.md показывает это в виде реальной колоды: обложку, повестку, текстовый блок с разметкой, цитату, определение, таймлайн, метрики, карточки и ручную сетку.
Когда добавляете публичный layout или kind, обновляйте сначала example.md: пример должен объяснять, в какой ситуации нужен паттерн, а не только демонстрировать YAML.
Техническая модель
Версия 1.0 разделяет физическую раскладку и семантические архетипы. Имена section, two-cols, arrangement, active, featured, margin*, surface и max-size удалены. Семантические семейства имеют встроенные варианты композиций с готовыми дефолтами. Контентные поля items, person, body, label, symbol, relation и media во фронтматтере встроенных архетипов больше не поддерживаются, их содержимое переносится в Markdown.
layout: cover | message | explainer | collection | default | nonedefault и none оставляют ручную сетку 12×12. default сохраняет обычную оболочку Slidev, none отключает автоматическую шапку. collection является технической точкой входа для points, relation, metrics и timeline.
Общий физический контракт использует только целые координаты общей сетки 12×12. area задаётся как row-start / col-start / row-end / col-end, col и row задают линии, cols и rows задают целочисленный размер от 1 до 12. Явные координаты резервируются первыми, остальные слоты размещаются по flow: horizontal|vertical. Пересечение, выход за сетку и отсутствие места дают ошибку с именем слота. Дробные размеры, локальные и вложенные сетки запрещены.
padding, padding-top, padding-right, padding-bottom, padding-left задают внутренние отступы. gap задаёт промежуток между содержимым. Оба поля используют шкалу 0–8. vertical: top|center|bottom доступен у Slot, Text и Person, centered центрирует текст по ширине у Slot и Text. focus: true выделяет один пункт Markdown-списка акцентной заливкой и контрастным текстом, не меняя его порядок.
Размеры и интервалы
- Используй публичные шкалы API и существующие токены styles/vars.css. В CSS и встроенных стилях ссылайся на токены без копирования значений и пересчёта от базового модуля. Новые токены, алиасы и изменение значений требуют явного согласования с пользователем.
- Значение и подпись образуют одну группу. Между пунктами текстового списка интервал чуть больше, чем внутри. Оба интервала задаются токенами и сохраняются при переносах и автоподборе текста, без заполнителей и распределения остатка высоты.
- Нули, координаты сетки, относительную геометрию и измерения браузера не превращай в дизайн-токены. Выравнивание задавай через
vertical. - После правок запусти затронутые проверки. В свежей сборке проверь короткие и многострочные подписи, интервалы, автоподбор, клики и переполнения. Перед обновлением эталонов просмотри изменившиеся слайды.
Атрибут grouped у списка объединяет пункты в одну область. flow="vertical|horizontal" задаёт направление, gap — интервал между пунктами, sync-size — общий размер текста. При явных координатах заголовка он остаётся отдельной областью. Без координат заголовок входит в общую группу. Координаты пунктов и grouped несовместимы: задавай область всего списка или отдельные области пунктов.
Text.cols ограничивает ширину текста целым числом колонок общей сетки с учётом внутренних отступов области. В Markdown используй text-cols для текста внутри области, а cols — для самой области. У вложенной текстовой подписи cols относится к тексту. Аналогично text-muted приглушает текст, а muted у области меняет её фон.
Раскладка декора
Композиция областей задаётся decor-layout во фронтматтере или одноимённым атрибутом корневого <Slide>. decor выбирает и настраивает изображение. decor.id и decor.tags используются для поиска, decor.color — для перекрашивания.
decor-layout: "2+1>0"Левая часть строки описывает группы справа от основного содержимого, правая — группы снизу. + разделяет группы вдоль полосы, число задаёт количество слотов поперёк полосы, 0 означает отсутствие стороны. > отдаёт общий угол правой полосе, < — нижней. Справа слоты одной группы идут горизонтально, группы сверху вниз. Снизу слоты одной группы идут вертикально, группы слева направо.
По умолчанию правая полоса занимает шесть колонок, нижняя — шесть строк. Слоты можно уточнить атрибутами area, col, row, cols и rows. Пропорции по умолчанию делятся только при целочисленном результате.
---
layout: cover
decor-layout: "1<2+1"
---
# Основной заголовок
![Декор справа](){decor="cover" tags="blue"}
![Первый декор снизу](){decor="cover" tags="green"}
![Второй декор снизу](){decor="cover" tags="orange"}
![Третий декор снизу](){decor="cover" tags="blue"}Семантические архетипы
Авторский путь — выбрать layout и kind, затем написать содержимое в Markdown. kind обозначает смысл содержимого. Геометрию, типографику, отступы и оформление задают независимые параметры. Атрибуты {...} уточняют отдельные элементы. Все содержательно разные примеры и пояснения к ним сохранены в example.md.
| layout | kind | Композиция и содержимое |
| --- | --- | --- |
| cover | cover | заголовок, вводный абзац и триптих справа |
| message | message, quote, closing | один тезис, цитата с автором, финальный тезис с необязательным абзацем |
| explainer | explainer | заголовок слева и развёрнутый текст справа, явные координаты пунктов создают отдельные опоры |
| explainer | definition | термин, определение и необязательная короткая подпись |
| collection | points | до шести тезисов, фактов или шагов, автоматическая раскладка по количеству и наличию пояснений |
| collection | relation | две стороны и произвольный знак связи с подписью |
| collection | metrics | от трёх до шести значений с подписями и необязательными изображениями |
| collection | timeline | временные метки с описаниями и необязательным выделением одного события |
Обложка принимает # с заголовком, один необязательный абзац и изображения. Обычный путь к изображению задаёт конкретный файл. Пустой путь с {decor="workspace" tags="blue"} выбирает изображение из каталога по смыслу и цвету. {decor-id="…"} закрепляет конкретную запись каталога. decor-layout задаёт композицию полос, локальные координаты имеют приоритет. Широкий верхний заголовок, сбалансированные ряды и узкий триптих выражаются координатами, отступами и настройками текста. kind: cover можно опустить.
---
layout: cover
tone: light
accent: orange
---
# Когда нужен широкий вход {area="1 / 1 / 7 / -1" tone="light" padding="4" gap="4"}
Заголовок на полную ширину заявляет тему, а три изображения поддерживают её. {size="3" muted="false" vertical="top"}
![Поддержка](){decor="support" tags="orange" tone="orange" area="7 / 1 / -1 / 4"}
![Рабочее место](){decor="workspace" tags="blue" area="7 / 4 / -1 / 8"}
![Декор обложки](){decor="cover" tags="orange" tone="dark" area="7 / 8 / -1 / -1"}message принимает один Markdown-заголовок. centered: true включает центрирование по ширине, vertical: top|center|bottom задаёт положение по высоте. closing допускает один абзац после заголовка. quote принимает цитату, заголовок с именем автора, необязательный абзац с его должностью и необязательную фотографию.
---
layout: message
kind: quote
---
> Внешний голос помогает точнее выразить мысль.
## Константин Константинопольский
наставник
{position="62% 42%" zoom="1.18"}definition принимает заголовок с термином и абзац определения. Короткая подпись пишется отдельным абзацем с {role="label"}.
---
layout: explainer
kind: definition
---
#Определение {role="label"}
# Архетип слайда
Именованная схема расположения содержимого, для которой тема задаёт геометрию и ритм текста.В points верхний пункт — основная мысль, вложенные пункты — пояснения. Вложенный пункт с {role="label"} становится короткой подписью перед основной мыслью. Обычный список получает marker: none, нумерованный — marker: number. Явно можно выбрать marker: none|number|circle. {focus} выделяет один пункт. Для повестки объедини список через grouped, выбери marker: circle, задай области текста и изображения. decor="agenda" выбирает иллюстрацию, не меняя геометрию.
---
layout: collection
kind: points
marker: number
---
# Шесть шагов учебного объяснения
- Назвать цель {area="4 / 1 / -1 / 3" tone="light" padding="3" gap="2" size="4"}
- Что студент сделает сам
- Дать контекст {area="4 / 3 / -1 / 5" tone="light" padding="3" gap="2" size="4"}
- Где возникает задача
- Показать пример {area="4 / 5 / -1 / 7" tone="light" padding="3" gap="2" size="4"}
- Один разобранный ход
- Оставить практику {area="4 / 7 / -1 / 9" tone="light" padding="3" gap="2" size="4"}
- Задание без подсказки
- Проверить критерий {focus area="4 / 9 / -1 / 11" tone="light" padding="3" gap="2" size="4"}
- Видимый признак качества
- Закрепить вывод {area="4 / 11 / -1 / 13" tone="light" padding="3" gap="2" size="4"}
- Что перенести дальшеrelation принимает заголовок и два пункта списка с пояснениями. Между заголовком и списком можно добавить один подзаголовок ## … и один короткий абзац описания, вместе или по отдельности. Они сохраняют Markdown-разметку и настройки текста через {…}. Размеры текста автоматически подбираются в общей области заголовка. Знак связи пишется первым абзацем цитаты > …, подпись связи — вторым. flow: horizontal|vertical меняет направление. Для двух сторон без знака используйте points.
---
layout: collection
kind: relation
---
# От ответа к решению
## Обратная связь раскрывает ход мысли
Сравниваем, как ученик объясняет выбор метода до и после разбора.
- Запомнить формулу
- До разбора {role="label"}
- Ответ верный, но выбор метода не объяснён.
- Выбрать метод по условию
- После разбора {role="label"}
- Ученик связывает данные, метод и проверку результата.
> →
>
> объяснить ход мыслиВ metrics верхний пункт — значение, первый вложенный пункт — подпись, следующие вложенные пункты — дополнительные пояснения. Заголовок необязателен. Внешний flow раскладывает карточки по рядам или колонкам, атрибут {flow="horizontal"} у пункта ставит значение и подпись рядом. Изображения записываются отдельными Markdown-элементами и занимают собственные области общей сетки.
Крупное число и пояснение рядом выражаются flow="horizontal" у пункта. Ширина текста задаётся text-cols, оформление и размеры не зависят от числа фотографий. role="body" у подписи включает обычную типографику развёрнутого текста.
---
layout: collection
kind: metrics
---
- ×2 {area="1 / 1 / 7 / -1" flow="horizontal" size="7-12" sync-size=""}
- Вдвое быстрее после практики {role="body" size="5-7" vertical="center"}
- 18 {area="7 / 1 / -1 / 7"}
- минут до подсказок
- 9 {area="7 / 7 / -1 / -1" tone="accent"}
- минут после подсказокВ timeline верхний пункт — временная метка, вложенный — описание события. Необязательная короткая подпись получает {role="label"}, один текущий момент можно выделить через {focus}. Допускается до двенадцати событий.
---
layout: collection
kind: timeline
---
# Эволюция шаблона
- 2021
- Первая версия
- 2024
- Текущая графическая система
- 2026 {focus}
- Шаблоны для использования с ИИЛокальные атрибуты Markdown
Тема разворачивает Markdown в Slot и Text. Встроенные варианты позволяют пользоваться дефолтами без ручных координат. Явные ролевые Slot и сокращённая запись являются взаимоисключающими режимами одного слайда. default и none сохраняют ручную композицию компонентами.
| Где | Атрибуты | Что изменяют |
| --- | --- | --- |
| Заголовок или верхний пункт списка | area, col, row, cols, rows, tone, muted, focus, padding, padding-*, gap | геометрию и оформление слота |
| Заголовок или верхний пункт списка | size, as, priority, text-muted, vertical, centered | типографику основного текста |
| Вложенный пункт или вводный абзац | size, as, priority, muted, vertical, centered | типографику конкретного пояснения |
| Вложенная короткая подпись | role="label" | подпись перед основной мыслью в фактах, связях и хронологии |
| Верхний пункт метрики | flow="horizontal|vertical" | взаимное расположение значения и подписи |
| Изображение | area, col, row, cols, rows, tone, padding, fit, position, anchor, x, y, zoom, rotate, color, opacity, background | область и отображение медиа |
| Декоративное изображение с пустым путём | decor, decor-id, tags | выбор изображения из каталога |
muted на заголовке или верхнем пункте приглушает фон карточки, text-muted — её основной текст. На вложенном пункте muted приглушает текст подписи. Чтобы снять приглушение, используйте muted="false" или text-muted="false". tone принимает none, light, dark, accent, blue, orange, green, red, yellow.
- ×2 {area="2 / 1 / 8 / -1" tone="light" flow="horizontal" size="7-12"}
- Главное пояснение {size="5-7" muted}
{position="48% 44%" zoom="1.08"}Локальные варианты презентации
Локальный вариант — повторяющаяся композиция конкретной колоды. Файл components/layout-variants/explainer/lesson-summary.vue соответствует layout: explainer и kind: lesson-summary. Корневые слоты используют физические area, col, row, cols и rows, а role принадлежит встроенным архетипам.
Для принципиально нового типа слайда создайте нативный layouts/<layout>.vue и выбирайте его через layout: <layout>. Локальные варианты не используют arrangement, вместо него применяются параметры оформления, Markdown в теле слайда и координаты слотов.
Внутри локального варианта используйте типы DeckLayoutVariantProps и DeckLayoutVariantSlots, чтобы фронтматтер и слот default имели явный контракт.
<template>
<Slot area="1 / 1 / 9 / 9" tone="light" padding="4" gap="3">
<slot />
</Slot>
<Slot area="9 / 9 / -1 / -1" tone="blue" padding="3">
<Logo kind="icon" />
</Slot>
</template>Метаданные слайда
layout, kind, tone, accent, debug, header, flow, marker, centered, vertical, decor-layout, decor и themeConfig задаются во фронтматтере. Заголовки, значения, подписи, события, имена авторов и пути изображений находятся в теле слайда. title в первом фронтматтере — служебное имя колоды, видимый заголовок пишется в теле слайда.
Компонент Slot
| Поле | Значения | Назначение |
| --- | --- | --- |
| role | primary, secondary, support, media | роль встроенного архетипа |
| name | строка | стабильное имя слота для диагностики и выбора декора |
| area | четыре целые линии | точный прямоугольник общей сетки |
| col, row | целая линия или span N | начало и размер по оси |
| cols, rows | 1..12 | размер от начальной линии |
| padding, padding-* | 0..8 | внутренние отступы |
| gap | 0..8 | расстояние между дочерними элементами |
| tone | none, light, dark, accent, палитра | визуальная среда слота |
| accent | имя палитры | локальный акцент, наследуется дочерними элементами |
| muted | boolean | приглушённый фон слота |
| centered | boolean | горизонтальное центрирование текста |
| vertical | top, center, bottom | положение содержимого по высоте |
| focus | boolean | выделение слота |
| background | строка, объект с src или массив объектов | цвет подложки или фоновые изображения |
| syncSize | строка | ключ группы согласованного подбора текста в пределах слайда |
| decor | объект выбора декора | выбор изображения из каталога |
Slot.label больше не используется, для служебного имени применяется Slot.name. Короткая содержательная подпись элемента данных по-прежнему называется label.
Компонент Text
| Поле | Значения | Назначение |
| --- | --- | --- |
| as | h1, h2, h3, p, div, data | семантический HTML-элемент |
| size | N или N-M | фиксированный размер или диапазон подбора |
| size="0-M" | диапазон | автоматический нижний предел с максимумом M |
| vertical | top, center, bottom | положение текстового блока по высоте |
| centered | boolean | центрирование строк по ширине |
| muted | boolean | приглушённый цвет текста |
| color | цветовой токен или CSS-цвет | явный цвет текста |
| priority | 1..4 | порядок подбора внутри TextFitGroup |
Диапазон size полностью заменяет отдельное поле max-size. Person.vertical использует тот же словарь, Logo.kind принимает full, short и icon.
Общие текстовые поля и изображения
Текстовые поля name, title, time, body, label принимают строку или объект { text, size, priority, vertical, centered, muted, color }. Поля оформления необязательны. Богатый текст сохраняет разметку и ссылки. title у Person и Logo сохраняет свой прежний смысл.
<template>
<Person name="Анна" title="Редактор"
:avatar="{ src: '/photos/anna.webp', position: 'top', zoom: 1.1 }" />
<Timeline :items="[
{ time: '2026', body: { text: 'Запуск', size: '3-5', muted: false } },
]" />
</template>avatar также принимает строку с источником. Настройки аватара совпадают с Image: fit, position, anchor, x, y, zoom, rotate, color, opacity, background. Поля avatarPosition и другие avatar* заменены общим объектом, bodyText, labelText, timeText — объектами соответствующих текстовых полей.
syncSize у Slot и TextFitGroup имеет строковое значение, например sync-size="metrics". Группа согласует подбор размеров в пределах одного слайда, сохраняя отдельные диапазоны и приоритеты заголовков, значений и подписей. Пустая строка отключает объединение с другими группами.
Цвет и фон
tone задаёт локальную визуальную среду, accent — наследуемую акцентную палитру. tone: dark и accent: green дают тёмный фон с зелёными акцентами. Цветной tone: green задаёт зелёный фон и, при отсутствии явного accent, зелёные акценты. Нейтральные light и dark наследуют акцент. tone: accent выбирает фон в наследуемой палитре. Slot дополнительно допускает tone: none для прозрачной области.
themeConfig.accent задаёт акцент колоды. accent слайда и слота переопределяет его локально. Прежние mode: dark, tone: green заменяются на tone: dark, accent: green. Прежний mode: color выражается цветным tone или tone: accent.
color у текста, логотипа, изображения и декора одинаково разрешает существующие цветовые токены и явные CSS-цвета. У логотипа основной цвет задаёт color, дополнительный — contrast. Перекрашивание изображения сохраняет текущие возможности SVG.
background в строковой форме всегда задаёт цвет, например background="dark-0". У Slot объект { src: '/photo.webp' } задаёт изображение, массив таких объектов — несколько слоёв. Подложка изображения или логотипа принимает цвет. Явный фон переопределяет заливку, а tone и accent продолжают управлять средой и акцентами. Строковые источники прежнего Slot.background нужно записать как объект с src.
muted у Slot приглушает его заливку, у Text — текст. Для основного текста заголовка или пункта Markdown используется text-muted, поскольку тот же узел задаёт параметры слота.
Markdown в default slot
Markdown внутри поддерживаемых архетипов сохраняет inline-разметку, ссылки, переносы строк, появление по клику и сноски, если они входят в контракт конкретного архетипа. Неподдерживаемая структура останавливает сборку с именем архетипа и подсказкой.
Анимация по кликам
v-click, v-after, v-click-hide и диапазоны Slidev работают на обычных Markdown-узлах и на ролевых слотах. Если список обёрнут в v-click, тема сохраняет группу как единый блок, порядок пунктов не меняется.
Image API
Image принимает src, fit, position, anchor, x, y, zoom, rotate, color, opacity и background. Logo.kind="full|short|icon" выбирает форму логотипа.
Decor
decor может содержать id, meaning, tags, src и параметры изображения. tags используются для поиска и могут включать палитру, смысл и другие признаки. Поискового поля decor.tone больше нет. Внешний каталог decors.yaml нормализуется к тем же полям.
themeConfig
debug включает сетку для колоды, одноимённый параметр слайда переопределяет его, включая явное false. debugGrid заменён на debug, defaultTone — на accent.
themeConfig:
decors:
- id: decor-custom-data
src: /decor/custom-data.png
meaning: data
tone: bluethemeConfig:
decors: ./decors.yamlthemeConfig:
deckTitle: 'Название колоды'
debug: false
accent: blue
decors:
- ./decors/clocks.yaml
- ./decors/photos.yaml
- id: decor-custom-data
src: /decor/custom-data.png
meaning: data
tone: blue
cols: [5, 8]
rows: [3, 6]
ratio: [1.2, 2.7]decors принимает список записей, путь к файлу или смешанный список путей и записей. Файл может быть YAML, JSON или ESM (decors.yaml, .yml, .json, .mjs) и содержать массив записей, объект { decors: [...] } или одну запись. Если decors не задан, тема подхватывает decors.yaml / .yml / .json / .mjs в корне колоды, если такой файл есть. Позже идущие записи с тем же id переопределяют более ранние.
Файл каталога по умолчанию заменяет встроенный каталог темы: слоты видят только записи колоды. Короткие inline-записи по умолчанию по-прежнему добавляются к встроенному каталогу. Явный replaceDecors перекрывает оба случая.
В записи каталога cols и rows описывают допустимый размер слота в сетке 12x12, а ratio ограничивает соотношение cols / rows для ориентации. Вместо ratio можно использовать более явный алиас aspectRatio.
| Поле | Тип | По умолчанию | Смысл |
| ----------------- | --------------------------------- | ------------------ | -------------------------------------------------------- |
| deckTitle | строка | пустая строка | служебное название колоды в шапке |
| debug | boolean | false | отладочная сетка 12x12 |
| decors | записи, путь или список путей | встроенный каталог | файл заменяет встроенный каталог; inline-записи добавляют или переопределяют по decor.id |
| replaceDecors | boolean | true для файла каталога | не подмешивать встроенные картинки темы |
| decorSaveOrigin | origin URL | origin dev-сервера | разрешённый origin для сохранения настроек декора |
themeConfig.deckTitle задаётся явно и отвечает только за повторяющееся служебное название в шапке. Он не заменяет видимый заголовок конкретного слайда и не берётся из верхнеуровневого title.
Если dev-сервер работает за reverse proxy с завершением TLS, задайте внешний origin явно:
themeConfig:
decorSaveOrigin: https://slides.exampleEndpoint сохранения принимает только точное значение Origin. Без явного decorSaveOrigin он выводит origin из TLS-соединения и заголовка Host; заголовкам X-Forwarded-* endpoint не доверяет.
Цветовые токены
| Токен | Значение |
| ---------- | --------- |
| light-0 | #ffffff |
| light-1 | #f0f0f0 |
| dark-0 | #1e1e1e |
| dark-1 | #3c3c3c |
| dark-2 | #646464 |
| blue-0 | #027ef2 |
| blue-1 | #98d2fe |
| orange-0 | #ff6c26 |
| orange-1 | #ffd2bd |
| green-0 | #07ab4b |
| green-1 | #9cddb7 |
| red-0 | #e84033 |
| yellow-0 | #ffd20a |
Компонент Text
| Уровень | Размер | Межстрочный интервал |
| ------- | ------ | -------------------- |
| 0 | 16px | 1.2 |
| 1 | 20px | 1.2 |
| 2 | 24px | 1.2 |
| 3 | 36px | 1.2 |
| 4 | 46px | 1.2 |
| 5 | 56px | 1.2 |
| 6 | 80px | 1.1 |
| 7 | 124px | 1.1 |
| 8 | 160px | 0.95 |
| 9 | 200px | 0.95 |
| 10 | 280px | 0.95 |
| 11 | 340px | 0.95 |
| 12 | 400px | 0.95 |
Версии Slidev
Тема проверяется на Slidev 53 (@slidev/cli в devDependencies). Начиная со Slidev 52.20 штатное копирование public/ темы не публикует вложенные каталоги, поэтому тема сама отдаёт свой public/ по /theme/... в режиме разработки и копирует его в сборку. Процессы, запущенные из Cursor или VS Code, наследуют переменную VSCODE_CWD, и UnoCSS тогда не читает наборы значков с диска. Поэтому тема удаляет эту переменную из окружения процесса Slidev, и значки панели отображаются.
Проверка перед выпуском
npm testЕдиная команда последовательно проверяет:
- lint и типы;
- модульные, контрактные и архитектурные тесты;
- продукционную сборку, локальный вариант внешней презентации и состав артефактов;
- репрезентативные слайды в Chromium, переполнение холста и загрузку медиа по
/theme/...; - цвет, альфа-канал, размеры, положение и трансформации перекрашенных SVG в сравнении с обычными SVG нужного цвета;
- контраст всех видимых текстовых пар, семантику медиа и
alt, видимый фокус,prefers-reduced-motionи отсутствие внешних запросов; - точное совпадение всех слайдов
example.mdс PNG-эталонами при зафиксированных Chromium, viewport, DPR, sRGB и доступности локальных шрифтов; - состав и размер npm-пакета, затем установку созданного локального архива во временную внешнюю презентацию, её сборку с
VSCODE_CWD, как при запуске из Cursor или VS Code, показ без внешних запросов, ресурсы/theme/...и значки панели Slidev.
Проверка PDF в macOS
На macOS тот же набор изображений можно дополнительно проверить в PDFKit, который использует «Просмотр». Для запуска нужен Swift из инструментов разработчика Apple:
npm run test:image-renderer -- --pdfkitОбновление пиксельных эталонов
Пиксельные эталоны меняются только осознанно после визуального просмотра результата:
npm run test:pixels:updateПереход на 2.0.0
Версия 2.0.0 меняет авторский API: составные варианты разложены на независимые параметры, а одинаковые по смыслу свойства получили общие имена. Для колод на версии 1.x требуется миграция по таблице ниже. Все 53 примера в example.md уже используют новый API.
В этой версии также исправлена печать перекрашенного SVG-декора в PDFKit и «Просмотре» macOS. Цвет, прозрачность, положение и трансформации изображений проверяются отдельным набором сравнений.
| Было | Стало |
| --- | --- |
| variant | kind, только для самостоятельного смысла |
| Logo.foreground | Logo.color |
| Image.backgroundColor | background |
| debugGrid | debug |
| fitGroup | syncSize |
| avatarPosition, avatarZoom | avatar: { src, position, zoom } |
| bodyText, timeText, labelText | body, time, label: содержимое или { text, ... } |
| mode: dark, tone: green | tone: dark, accent: green |
| mode: color, tone: green | tone: green |
| mode: color без палитры | tone: accent |
| Slot.background: '/photo.webp' | background: { src: '/photo.webp' } |
| grid-balanced, banner, signal, split-media-triptych | layout: cover, области и оформление изображений |
| title-supports, title-supports-bottom-muted, title-supports-bottom-plain | layout: explainer, grouped либо отдельные области, size, text-muted |
| steps-linear, steps-staggered, facts-duo, facts-trio, facts-quartet, facts-featured | kind: points, marker, области, size, focus, sync-size |
| facts-stacked | kind: points, grouped, flow="vertical", области и размеры текста |
| metrics-featured-media, metrics-featured-copy, metrics-featured-copy-split-media | kind: metrics, области, внутренний flow, text-cols, самостоятельные изображения |
Строка background обозначает цвет. Объект { src } обозначает изображение, массив таких объектов — слои изображений. Person.title, Logo.title, position, padding, centered и priority сохраняют имена. Все 53 примера миграции находятся в example.md.
