/* ── Презентации: полноэкранный слайд-шоу (data-format="presentation") ── */

/* Дочерние шаблоны презентаций прячут шапку/футер/кнопки base.html,
   поэтому основная настройка — тело и контейнер. */

/* Фолбэк-палитра презентации. Задаётся на :root, а не на .presentation:
   иначе близкий к контенту блок перекрывал бы пресеты
   (html[data-pres-theme=...]) и выбор theme в meta не работал бы —
   слайды всегда были бы в цветах фолбэка. Пресеты переопределяют эти
   переменные на html[data-pres-theme=...].
   Когда theme в meta НЕ задана — презентация повторяет тему блога
   (--bg/--fg/--accent), в т.ч. поддерживает текущий светлый/тёмный режим
   (html[data-theme]) — решение Саши 2026-09-16. */
:root {
  --pres-bg: var(--bg);
  --pres-color: var(--fg);
  --pres-accent: var(--accent);
  /* Карточки/панели в дефолтной теме должны быть различимы от фона
     слайда И в светлой, и в тёмной теме блога. Сырой var(--card-bg)
     (в светлой — #f7f7f7 на белом) почти сливается; вместо этого —
     лёгкий замес «чернил» на фон: в светлой даёт ~#f2f2f2 против белого,
     в тёмной — заметно светлее фона. Пресеты (html[data-pres-theme=...])
     задают свой --pres-card и перекрывают. color-mix современный;
     фолбэк ниже — rgba текстового цвета. */
  --pres-card: rgba(127, 127, 127, 0.18); /* фолбэк без color-mix */
  --pres-card: color-mix(in srgb, var(--pres-color) 6%, var(--pres-bg));
}

.pres-body,
.pres-body .container {
  max-width: none;
  padding: 0;
}

.pres-body {
  overflow: hidden;
}

/* Видимость по режиму: .only-presentation виден ТОЛЬКО в слайд-шоу,
   .only-article виден ТОЛЬКО в обычном виде статьи. Обратный тумблер
   (.only-presentation { display:none }) лежит в blog.css — эта секция
   грузится ПОЗЖЕ и отменяет его. */
.only-presentation { display: revert; }
.only-article { display: none; }

/* Обёртка слайд-шоу: занимает весь вьюпорт. */
.pres-body .presentation {
  /* Переопределение переменных блога на палитру презентации: иначе в
     светлой теме сайта инлайн-код/карточки/таблицы тянут светлый фон
     site-темы (--card-bg #f7f7f7), а текст — белый --pres-color →
     белое на белом. Здесь НЕ задаём --pres-bg/--pres-color/--pres-accent:
     фолбэк этих цветов — на :root (см. ниже), пресеты задают их на
     html[data-pres-theme=...], иначе этот блок (ближе к контенту) их
     перекрывал бы и пресеты никогда бы не применялись. */
  --card-bg: var(--pres-card);
  --pres-border: rgba(127, 127, 127, 0.4);
  --fg: var(--pres-color);
  --muted: rgba(127, 127, 127, 0.85);
  --accent: var(--pres-accent);
  --accent-bg: var(--pres-accent);
  --on-accent: var(--pres-bg);
  --border: var(--pres-border);
  --code-border: var(--pres-border);
  --code-block-bg: var(--pres-card);
  --code-block-fg: var(--pres-color);
  --mark-bg: var(--pres-accent);
  --mark-fg: var(--pres-bg);
  --message-bg: rgba(127, 127, 127, 0.18);
  --message-border: rgba(127, 127, 127, 0.35);
  --message-fg: var(--pres-color);
  /* Семантические фоны (.bg-info/.bg-warning/.bg-success/.bg-danger) — на
     полупрозрачных оттенках пресета, а не на site-палитре (иначе в hive
     `.bg-info` был бы синим по жёлтой гамме). color-mix современный; фолбэк
     ниже — rgba из акцент-цвета пресета. */
  --info-bg: color-mix(in srgb, var(--pres-accent) 22%, transparent);
  --info-fg: var(--pres-color);
  --warning-bg: color-mix(in srgb, var(--pres-accent) 26%, transparent);
  --warning-fg: var(--pres-color);
  --success-bg: rgba(80, 200, 120, 0.18);
  --success-fg: var(--pres-color);
  --danger-bg: rgba(255, 102, 102, 0.2);
  --danger-fg: var(--pres-color);
  --critic-del-bg: rgba(255, 102, 102, 0.18);
  --critic-del-fg: #ffd7d5;
  --critic-ins-bg: rgba(80, 200, 120, 0.18);
  --critic-ins-fg: #d4f4d4;
  /* Таблицы (.t-*) */
  --t-border: var(--pres-border);
  --t-header-same-bg: rgba(127, 127, 127, 0.18);
  --t-header-same-fg: var(--pres-color);
  --t-stripe-bg: rgba(127, 127, 127, 0.07);
  --t-stripe-strong-bg: rgba(127, 127, 127, 0.14);
  display: block;
  position: fixed;
  inset: 0;
  background: var(--pres-bg);
  color: var(--pres-color);
}

/* Заголовок статьи до сборки слайдов скрыт; presentation.js переносит его
   в титульный слайд и снимает display:none. */
.pres-title {
  display: none;
}

.pres-cover {
  /* Титульный слайд: заголовок крупнее, без отступов-буллетов.
     Выравнивание: ДЕФОЛТ — центр (решение Саши 2026-09-16, только для
     обложки; в статьях центрирования «самому» нет). meta cover-align:
     left|right переопределяет через data-pres-cover на html. */
  text-align: center;
}

html[data-pres-cover="left"] .pres-cover {
  align-items: flex-start;
  text-align: left;
}

html[data-pres-cover="right"] .pres-cover {
  align-items: flex-end;
  text-align: right;
}

html[data-pres-cover="left"] .pres-cover .pr-cover-sub,
html[data-pres-cover="left"] .pres-cover .pr-cover-line { margin-left: 0; margin-right: auto; }

html[data-pres-cover="right"] .pres-cover .pr-cover-sub,
html[data-pres-cover="right"] .pres-cover .pr-cover-line { margin-left: auto; margin-right: 0; }

.pres-cover h1 {
  font-size: 3em;
  margin: 0;
}

.pres-slideshow {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* Воздух слайдов — CSS-переменные живут на html (:root), наследуются всеми
   слайдами. Дефолт ниже; meta spacing (data-pres-spacing на html) и
   пер-слайдные классы pr-a-tight / pr-a-wide переопределяют их точечно. */
:root {
  --pr-vpad: clamp(16px, 4vw, 64px);
  --pr-hpad: clamp(16px, 6vw, 96px);
}

.pres-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  justify-content: safe center; /* при переполнении — flex-start, верх не обрезается */
  padding: var(--pr-vpad) var(--pr-hpad);
  overflow-y: auto;                 /* высокий контент скроллится внутри слайда */
  background: var(--pres-bg);       /* непрозрачный фон: чистый кросс-фейд без наложения */
  opacity: 0;
  visibility: hidden;
  transform: translateX(8px);
  transition: opacity .35s ease, transform .35s ease, visibility .35s;
  z-index: 1;
}

/* Воздух слайда: базовый дефолт — выше в :root. */

.pres-slide.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  z-index: 2;
}

/* Отключаем горизонтальный скролл у всего слайда; скроллят внутренние
   контейнеры по своим классам (таблицы/код/vega). */
.pres-slide {
  scrollbar-width: thin;
}

.pres-slide h1 {
  font-size: 2.2em;
  color: var(--pres-accent);
  margin: 0 0 .6em;                 /* margin-top: 0 — воздух сверху даёт слайд (--pr-vpad) */
}

/* Таблицы в слайдах: мягкий скролл-режим как в блоге (display:block +
   overflow-x:auto), НО с центрированием. width:fit-content — таблица по
   контенту, max-width:100% ограничивает колонкой, margin:auto центрирует
   узкую; когда таблица шире колонки — появляется горизонтальный скролл
   (display:block это допускает, display:table — нет: широкая таблица
   вылезала за край без скролла, баг 2026-09-17).
   `box {: .h-scroll }` (жёсткий режим) — ниже, переопределяет обратно. */
.pres-slide .markdown table,
.pres-slide table {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Жёсткий режим через `box {: .h-scroll }` в слайде: контейнер скроллит,
   таблица не сжимается (max-content). Перекрывает мягкий режим выше. */
.pres-slide .h-scroll > table {
  display: table;
  width: auto;
  min-width: max-content;
  max-width: none;
  margin: 0;
}

/* Тело слайда: JS оборачивает контент (кроме h1) в .pres-body.
   Дефолт (и большинство стилей): контент — ЕДИНЫЙ столбец.
   общая ширина (fit-content по самому широкому элементу, но не шире
   слайда), центрируется кусочком целиком. Дети stretch на ширину
   колонки — таблицы/списки/абзацы одной ширины. По вертикали — центр
   (safe: при переполнении верх не обрезается, заголовок остаётся).
   Стили-«левши» (swiss, editorial) возвращают display:contents ниже —
   их раскладка не меняется. pr-top/pr-split переопределяют отдельно. */
.pres-slide > .pres-body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  justify-content: safe center;   /* при переполнении — flex-start, верх не обрезается */
  width: fit-content;
  max-width: 100%;
  flex: 1 0 auto;
  min-height: 0;
  overflow-y: auto;               /* высокое тело скроллится, заголовок остаётся */
  scrollbar-width: thin;
}

/* Стили, где контент прижат к левому краю: возвращаем прозрачную обёртку,
   чтобы слайд/стиль сам управлял раскладкой (swiss flex-start; контент слева
   и тексты выровнены влево). editorial — НЕ левша: он центрирует слайд и
   лишь ограничивает ширину детей 42em, поэтому живёт в stack (единый столбец). */
html[data-pres-style="swiss"] .pres-slide > .pres-body {
  display: contents;
  overflow: visible;
  flex: none;
  width: auto;
}

/* ── Режимы контента слайда: stack (единый столбец, дефолт) / loose ──
   Глобально включается meta `layout:` (presentation.js ставит
   data-pres-layout), точечно — классом на заголовке слайда
   (`# Тема {: .pr-loose }` / `{: .pr-stack }`). loose возвращает старое
   поведение: каждый элемент слайда — независимый flex-item, центрируется
   сам (тело прозрачно, display:contents). */
html[data-pres-layout="loose"] .pres-slide > .pres-body,
.pres-slide.pr-loose > .pres-body {
  display: contents;
  overflow: visible;
  flex: none;
  width: auto;
}

/* Пер-слайд принудительный stack поверх глобального loose или лева.
   Специфичность выше (html[data-pres-style]) — перебивает и стилевые.
   Идёт ПОСЛЕ стилевых коррекций (секция «Приоритет...» ниже также ок). */
html[data-pres-style] .pres-slide.pr-stack > .pres-body,
.pres-slide.pr-stack > .pres-body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: safe center;
  width: fit-content;
  max-width: 100%;
  flex: 1 0 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Пер-слайдные позиции заголовка (attr_list на h1 слайда, `# Заголовок{: .pr-head-nw}`):
   работают поверх любого стиля, дают тонкую настройку без нового стиля.
   Все 9 направлений сетки (как pr-anchor-*), но ТОЛЬКО для заголовка:
   слайд/контент не двигаются. left/center/right — старые алиасы:
   horizontal центр = c, left = w, right = e. Вертикаль: верхние (nw/n/ne/w/e)
   в потоке сверху; нижние (sw/s/se) прижимаются к низу через margin-top:auto. */
.pres-slide > h1.pr-head-nw,
.pres-slide > h1.pr-head-w   { align-self: flex-start; text-align: left; }
.pres-slide > h1.pr-head-n,
.pres-slide > h1.pr-head-c,
.pres-slide > h1.pr-head-center { align-self: center; text-align: center; }
.pres-slide > h1.pr-head-ne,
.pres-slide > h1.pr-head-e   { align-self: flex-end; text-align: right; }
.pres-slide > h1.pr-head-left  { align-self: flex-start; text-align: left; }
.pres-slide > h1.pr-head-right { align-self: flex-end; text-align: right; }
.pres-slide > h1.pr-head-sw { align-self: flex-start; text-align: left; margin-top: auto; }
.pres-slide > h1.pr-head-s  { align-self: center; text-align: center; margin-top: auto; }
.pres-slide > h1.pr-head-se { align-self: flex-end; text-align: right; margin-top: auto; }

/* Раскладка .pr-top: «заголовок сверху, контент по центру оставшегося».
   Базовый flex слайда НЕ меняется (по умолчанию всё по центру, как было);
   этот класс переключает слайд на заголовок-сверху и центрирование тела
   в остатке. Комбинируется с любым style. */
.pres-slide.pr-top {
  justify-content: flex-start;
}

.pres-slide.pr-top > .pres-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  justify-content: safe center; /* при переполнении — flex-start, верх не обрезается */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;             /* скроллится ТОЛЬКО тело, заголовок остаётся */
  scrollbar-width: thin;
}

/* Раскладка .pr-split: контент слева, сбоку — «бокс-компаньон» (цитата,
   число, иллюстрация). Делает слайд асимметричным, как в журнальных
   макетах. Правый блок — второй ребёнок .pres-body (например panel/box). */
.pres-slide.pr-split > .pres-body {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: safe center; /* при переполнении — flex-start, верх не обрезается */
  justify-content: center;
  gap: clamp(12px, 3vw, 40px);
  width: 100%;
}

.pres-slide.pr-split > .pres-body > *:first-child {
  flex: 3 1 280px;
}

.pres-slide.pr-split > .pres-body > *:nth-child(2) {
  flex: 2 1 200px;
}

.pres-slide.pr-split > .pres-body > *:nth-child(2) h2 {
  margin-bottom: .4em;
}

.pres-slide h2 {
  color: var(--pres-accent);
}

.pres-slide a {
  color: var(--pres-accent);
}

/* Список-буллеты слайда: маркеры в цвет акцента. */
.pres-slide ul {
  list-style: none;
  padding-left: 0;
}

/* Грид-фенсы (columns/cards) в слайде: в flex-контейнере слайда auto-fit
   ужимает их до контента и складывает в одну колонку — фиксируем ширину. */
.pres-slide .columns,
.pres-slide .cards {
  width: 100%;
  align-self: stretch;
}

/* Фенс-обёртки (```box/```cards/```columns): по контенту и по центру
   слайда — как .cards/.columns ниже. Ширина — на всю колонку контента
   (align-self:stretch по поперечной оси в column-flex).
   Полная высота — ТОЛЬКО по явному классу, дефолтом она не берётся:
     .pr-full        — растянуть без оформления, контент сверху;
     .pr-panel-full  — карточка во весь слайд, контент по центру;
     .pr-scroll      — растянуть и скроллить вертикально.
   Так рамка не двигает содержимое: добавил `box` — раскладка та же. */
.pres-slide .box {
  width: 100%;
  align-self: stretch;
}

.pres-slide ul > li {
  position: relative;
  padding-left: 1.3em;
  margin: .35em 0;
}

.pres-slide ul > li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .55em;
  width: .5em;
  height: .5em;
  background: var(--pres-accent);
  border-radius: 50%;
}

/* ── UI плеера ── */

.pres-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: rgba(255,255,255,.15);
  cursor: pointer;
  z-index: 5;
}

/* Зона клика крупнее тонкой полосы: растягиваем на ~14px вверх, но так,
   чтобы сама полоса оставалась тонкой (fill 4px). Клик по расширенной
   зоне переключает слайд. */
.pres-bar::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 14px;
}

.pres-bar-fill {
  height: 100%;
  width: 0;
  background: var(--pres-accent);
  transition: width .2s linear;
}

.pres-counter {
  position: absolute;
  bottom: 14px;
  right: 18px;
  z-index: 5;
  font-size: 13px;
  opacity: .75;
  color: var(--pres-color);
  font-variant-numeric: tabular-nums;
}

.pres-corners {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.pres-corners > button {
  pointer-events: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  width: 20%;
  max-width: 160px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--pres-color);
  opacity: 0;
  transition: opacity .2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
}

.pres-corners > button:hover,
.pres-corners > button:focus-visible {
  opacity: .5;
}

.pres-corners .pres-prev {
  left: 0;
}

.pres-corners .pres-next {
  right: 0;
}

.pres-actions {
  position: absolute;
  top: 14px;
  right: 18px;
  z-index: 5;
  display: flex;
  gap: 6px;
  /* Единая модель плавающих кнопок блога: слегка видны (opacity .25),
     полный вид по hover/focus. Появление быстрое (.15s), угасание с
     паузой .3s и длительностью .5s (как .zoom-btn в blog.css). */
  opacity: .25;
  transition: opacity .5s .3s;
}

.pres-actions:hover,
.pres-actions:focus-within,
.pres-actions:has(button:focus-visible) {
  opacity: 1;
  transition-duration: .15s;
  transition-delay: 0s;
}

.pres-actions button {
  background: rgba(127,127,127,.2);
  border: 1px solid rgba(255,255,255,.25);
  color: var(--pres-color);
  border-radius: 6px;
  width: 34px;
  height: 34px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pres-actions button:hover {
  background: rgba(255,255,255,.2);
}

/* ── Зум (картинки/mermaid/vega) в слайд-шоу ──
   Оверлеи (body-level) при открытой презентации: контент ограничен
   92vw/92dvh и вписывается в слайды (не «половина широкого экрана»
   в редакторном стиле), палитра/рамка — из презентации (--pres-*). */
body:has(.pres-slideshow) .img-zoom,
body:has(.pres-slideshow) .vega-zoom {
  background: color-mix(in srgb, var(--pres-bg, #000) 92%, transparent);
}
body:has(.pres-slideshow) .img-zoom .img-zoom-content {
  max-width: 92vw;
}
body:has(.pres-slideshow) .img-zoom .img-zoom-content.svg-bg,
body:has(.pres-slideshow) .img-zoom .img-zoom-content img,
body:has(.pres-slideshow) .img-zoom .img-zoom-content svg {
  background: var(--pres-card, var(--card-bg));
  border-radius: 12px;
}
body:has(.pres-slideshow) .img-zoom .img-zoom-content img {
  max-height: 88dvh;
  max-height: 88vh;
}
body:has(.pres-slideshow) .img-zoom .img-zoom-content svg {
  max-height: 88dvh;
  max-height: 88vh;
}
body:has(.pres-slideshow) .img-zoom figcaption {
  color: var(--pres-color, #fff);
}
body:has(.pres-slideshow) .vega-zoom .vega-zoom-content {
  width: min(92vw, 1400px);
  max-height: 90dvh;
  max-height: 90vh;
  background: var(--pres-card, var(--card-bg));
  border: 1px solid var(--pres-border, var(--border));
}
body:has(.pres-slideshow) .vega-zoom .vega-zoom-close,
body:has(.pres-slideshow) .img-zoom .img-zoom-close {
  background: var(--pres-card, var(--card-bg));
  color: var(--pres-color, var(--fg));
  border-color: var(--pres-border, var(--border));
}

/* ── Типографика из meta font-size ── */

html[data-pres-font="sm"] .pres-slide { font-size: 15px; }
html[data-pres-font="md"] .pres-slide { font-size: 17px; }
html[data-pres-font="lg"] .pres-slide { font-size: 20px; }
html[data-pres-font="xl"] .pres-slide { font-size: 24px; }

/* ── Переходы из meta transition ── */

[data-pres-transition="slide"] .pres-slide {
  transform: translateX(8px);
}

[data-pres-transition="slide"] .pres-slide.is-active {
  transform: none;
}

[data-pres-transition="fade"] .pres-slide,
[data-pres-transition="none"] .pres-slide {
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .pres-slide {
    transition: opacity .1s ease, visibility .1s;
    transform: none !important;
  }
}

/* ── Пресеты тем ── */

html[data-pres-theme="cyber"] {
  --pres-bg: #0a0e1a;
  --pres-color: #dbe4ff;
  --pres-accent: #00e5ff;
  --pres-card: #111a33;
  --pres-border: rgba(140, 180, 255, 0.35);
}

html[data-pres-theme="warm"] {
  --pres-bg: #2a1a0e;
  --pres-color: #ffe8d6;
  --pres-accent: #ffb454;
  --pres-card: #3a2718;
  --pres-border: rgba(255, 200, 160, 0.3);
}

html[data-pres-theme="ocean"] {
  --pres-bg: #071621;
  --pres-color: #d6e9ff;
  --pres-accent: #4cc9f0;
  --pres-card: #0e2333;
  --pres-border: rgba(150, 200, 240, 0.32);
}

html[data-pres-theme="mono"] {
  --pres-bg: #111111;
  --pres-color: #eeeeee;
  --pres-accent: #ffffff;
  --pres-card: #1c1c1c;
  --pres-border: rgba(200, 200, 200, 0.32);
}

html[data-pres-theme="minimal"] {
  --pres-bg: #f4f4f2;
  --pres-color: #222222;
  --pres-accent: #111111;
  --pres-card: #ffffff;
  --pres-border: rgba(20, 20, 20, 0.25);
}

/* Тёмная тема «hive»: чёрный / жёлтый / белый (фирменная гамма оператора,
   без названия бренда). Фон чёрный, текст белый, акцент — фирменный жёлтый. */
html[data-pres-theme="hive"] {
  --pres-bg: #0a0a0a;
  --pres-color: #ffffff;
  --pres-accent: #ffd100;
  --pres-card: rgba(255, 209, 0, 0.07);
  --pres-border: rgba(255, 209, 0, 0.3);
}

html[data-pres-theme="lime"] {
  --pres-bg: #0a0a0a;
  --pres-color: #f7ffe0;
  --pres-accent: #a3e635;
  --pres-card: rgba(163, 230, 53, 0.07);
  --pres-border: rgba(163, 230, 53, 0.3);
}

html[data-pres-theme="cherry"] {
  --pres-bg: #0a0a0a;
  --pres-color: #ffeef2;
  --pres-accent: #e8255a;
  --pres-card: rgba(232, 37, 90, 0.07);
  --pres-border: rgba(232, 37, 90, 0.3);
}

/* Тёмная тема «swiss» (швейцарская типографическая школа — урок истории
   11 класс, spec swizer): угольно-тёмный фон, белый текст, красный акцент
   (швейцарский флаг #DA291C), карточки #23262A с серой обводкой #4A5058. */
html[data-pres-theme="swiss"] {
  --pres-bg: #171A1C;
  --pres-color: #F5F7FA;
  --pres-accent: #DA291C;
  --pres-card: #23262A;
  --pres-border: rgba(74, 80, 88, 0.55);
}

/* ── новые палитры 2026 (рефы: dark-gold / electric / paper-ink / midnight /
   terminal / milk / ruby / indigo) ── */

/* dark-gold: чёрное с золотом — люкс, конференции, премиум. */
html[data-pres-theme="dark-gold"] {
  --pres-bg: #0a0a0b;
  --pres-color: #eae6dc;
  --pres-accent: #c4a35a;
  --pres-card: rgba(196, 163, 90, 0.06);
  --pres-border: rgba(196, 163, 90, 0.32);
}

/* electric: белое с электрик-синим — чистый профессиональный. */
html[data-pres-theme="electric"] {
  --pres-bg: #ffffff;
  --pres-color: #111111;
  --pres-accent: #4361ee;
  --pres-card: #f4f6ff;
  --pres-border: #ccd4f5;
}

/* paper-ink: крем и чернила, кармин — литературный editorial. */
html[data-pres-theme="paper-ink"] {
  --pres-bg: #faf9f7;
  --pres-color: #1a1a1a;
  --pres-accent: #c41e3a;
  --pres-card: #ffffff;
  --pres-border: #e3dfd8;
}

/* midnight: глубокий фиолет — драматичные презентации. */
html[data-pres-theme="midnight"] {
  --pres-bg: #0f0c29;
  --pres-color: #e9e8f5;
  --pres-accent: #7c3aed;
  --pres-card: #1c1833;
  --pres-border: rgba(124, 58, 237, 0.35);
}

/* terminal: GitHub-тёмный с зелёным — технические доклады. */
html[data-pres-theme="terminal"] {
  --pres-bg: #0d1117;
  --pres-color: #e6edf3;
  --pres-accent: #39d353;
  --pres-card: #161b22;
  --pres-border: rgba(57, 211, 83, 0.3);
}

/* milk: кремовый молочный, янтарь — мягкая светлая. */
html[data-pres-theme="milk"] {
  --pres-bg: #f7f5f0;
  --pres-color: #2b2722;
  --pres-accent: #b45309;
  --pres-card: #fdfbf7;
  --pres-border: #e5ddd0;
}

/* ruby: рубин на чёрном — насыщенная тёмная. */
html[data-pres-theme="ruby"] {
  --pres-bg: #12060a;
  --pres-color: #ffe4eb;
  --pres-accent: #ff4d6d;
  --pres-card: rgba(255, 77, 109, 0.08);
  --pres-border: rgba(255, 77, 109, 0.35);
}

/* indigo: светлая шафраново-индиговая. */
html[data-pres-theme="indigo"] {
  --pres-bg: #f6f5fd;
  --pres-color: #2a2750;
  --pres-accent: #7c6ff0;
  --pres-card: #ffffff;
  --pres-border: #e0dcef;
}

/* ══════ Специальные классы презентаций (pr-*) ══════
   Прекфикс pr- (presentation) — авторские классы, используемые через
   attr_list в контенте статьи-презентации. Работают ТОЛЬКО в режиме
   презентации (presentation.css не подключён в обычной статье), поэтому
   не ломают режим статьи. Примеры:
     {: .pr-panel }             — панель-карточка
     ```box {: .pr-panel-full } — карточка-панель на всю высоту
     {: .pr-grid-3 }            — трёхколоночная сетка
     {: .pr-kicker }            — мелкая надпись-«бровь» над заголовком */

/* Панель-карточка (bento-плитка): подложка светлее фона + рамка. */
.pres-slide .pr-panel {
  background: var(--pres-card);
  border: 1px solid var(--pres-border);
  border-radius: 14px;
  padding: .8em 1.1em;
}

/* Панель без паддинга (контент сам задаёт поля). */
.pres-slide .pr-panel-0 {
  background: var(--pres-card);
  border: 1px solid var(--pres-border);
  border-radius: 14px;
}

/* Панель на всё свободное место слайда: растянута на всю площадь (flex:1 +
   align-self:stretch в column-flex слайда) и центрирует своё содержимое.
   Центр — только по вертикали: содержимое сохраняет обычную ширину
   (абзацы/списки не сжимаются в узкую колонку), блоки уровня фенсов —
   на всю ширину панели. Безопасный центр: place-content:center работает
   даже при переполнении — контент начинается от центра и скроллится вниз. */
.pres-slide .pr-panel-full {
  background: var(--pres-card);
  border: 1px solid var(--pres-border);
  border-radius: 14px;
  padding: 2em 2.5em;
  width: 100%;
  flex: 1 0 auto;
  align-self: stretch;
  display: grid;
  place-content: center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.pres-slide .pr-panel-full > :first-child { margin-top: 0; }
.pres-slide .pr-panel-full > :last-child { margin-bottom: 0; }

/* Утилиты полей для pr-панелей (pr-panel / pr-panel-full): перекрывают
   дефолт. .pr-pad-md — то же, что базовый отступ панели. */
.pres-slide .pr-panel.pr-pad-none,
.pres-slide .pr-panel-0.pr-pad-none,
.pres-slide .pr-panel-full.pr-pad-none { padding: 0; }
.pres-slide .pr-panel.pr-pad-sm,
.pres-slide .pr-panel-0.pr-pad-sm,
.pres-slide .pr-panel-full.pr-pad-sm { padding: 1em 1.25em; }
.pres-slide .pr-panel.pr-pad-md,
.pres-slide .pr-panel-0.pr-pad-md,
.pres-slide .pr-panel-full.pr-pad-md { padding: 2em 2.5em; }
.pres-slide .pr-panel.pr-pad-lg,
.pres-slide .pr-panel-0.pr-pad-lg,
.pres-slide .pr-panel-full.pr-pad-lg { padding: 3em 4em; }

/* Сетка карточек: .pr-grid-2/3/4 с одинаковым воздухом.
   Дети — в .pr-panel/.pr-panel-0 или просто абзацы/списки. */
.pres-slide .pr-grid-2,
.pres-slide .pr-grid-3,
.pres-slide .pr-grid-4 {
  display: grid;
  gap: 1em;
  width: 100%;
  align-self: stretch;
}

.pres-slide .pr-grid-2 { grid-template-columns: repeat(2, 1fr); }
.pres-slide .pr-grid-3 { grid-template-columns: repeat(3, 1fr); }
.pres-slide .pr-grid-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 720px) {
  .pres-slide .pr-grid-2,
  .pres-slide .pr-grid-3,
  .pres-slide .pr-grid-4 {
    grid-template-columns: 1fr;
    overflow-y: auto;
  }

  /* Ужимаем отступы на маленьких экранах и убираем скруглённые углы —
     экран и так узкий, скругления крадут пространство. */
  .pres-slide .pr-panel-full {
    padding: 1.2em 1em;
    border-radius: 8px;
  }
  /* pr-pad-lg и pr-pad-md — ограниченные отступы на мобиле */
  .pres-slide .pr-panel.pr-pad-lg,
  .pres-slide .pr-panel-full.pr-pad-lg { padding: 1.8em 1.2em; }
  .pres-slide .pr-panel.pr-pad-md,
  .pres-slide .pr-panel-full.pr-pad-md { padding: 1.2em 1em; }
}

/* Растянуть блок на всю высоту слайда (flex-column внутри слайда). */
.pres-slide .pr-full {
  flex: 1 0 auto;
  align-self: stretch;
}

/* Крупный текст-герой (цифра/слово как визуал слайда). */
.pres-slide .pr-hero {
  font-size: 3.2em;
  font-weight: 700;
  line-height: 1.15;
  color: var(--pres-accent);
  margin: 0;
}

/* Мелкая надпись-«бровь» над заголовком (eyebrow). */
.pres-slide .pr-kicker {
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .68em;
  font-weight: 600;
  color: var(--pres-accent);
  margin-bottom: .7em;
}

/* Шапка слайда: кикер + заголовок + линейка-разделитель. */
.pres-slide .pr-head {
  border-bottom: 1px solid var(--pres-border);
  padding-bottom: .5em;
  margin-bottom: 1em;
  width: 100%;
}

/* Центровка блока по горизонтали/вертикали (альтернатива flex слайда). */
.pres-slide .pr-center {
  display: flex;
  flex-direction: column;
  align-items: safe center;
  justify-content: safe center; /* при переполнении — flex-start, верх не обрезается */
  text-align: center;
  width: 100%;
  flex: 1 0 auto;
}

/* Полноширинный блок, скроллится по вертикали.
   Полезно для «досок» с большим числом элементов. */
.pres-slide .pr-scroll {
  width: 100%;
  flex: 1 0 auto;
  align-self: stretch;
}

/* ── Позиционирование контента в слайде (по SLIDES v2: anchor/dock) ──
   Слайд — flex-колонка (align-items/justify-content на .pres-slide).
   pr-anchor-*: 9 позиций сетки 3×3 — куда прижать блок содержимого.
   pr-dock-*: прижать к краю и растянуть вдоль него (fill = весь слайд). */
.pres-slide.pr-anchor-nw { align-items: flex-start; justify-content: flex-start; }
.pres-slide.pr-anchor-n  { align-items: center;     justify-content: flex-start; }
.pres-slide.pr-anchor-ne { align-items: flex-end;   justify-content: flex-start; }
.pres-slide.pr-anchor-w  { align-items: flex-start; justify-content: center; }
.pres-slide.pr-anchor-c  { align-items: center;     justify-content: center; }
.pres-slide.pr-anchor-e  { align-items: flex-end;   justify-content: center; }
.pres-slide.pr-anchor-sw { align-items: flex-start; justify-content: flex-end; }
.pres-slide.pr-anchor-s  { align-items: center;     justify-content: flex-end; }
.pres-slide.pr-anchor-se { align-items: flex-end;   justify-content: flex-end; }

.pres-slide.pr-dock-top    { justify-content: flex-start; }
.pres-slide.pr-dock-bottom { justify-content: flex-end;   }
.pres-slide.pr-dock-left   { align-items: flex-start; }
.pres-slide.pr-dock-right  { align-items: flex-end;   }
.pres-slide.pr-dock-fill   { align-items: stretch; justify-content: flex-start; }
.pres-slide.pr-dock-fill   > .pres-body { width: 100%; }
.pres-slide.pr-dock-fill   > h1 { width: 100%; }

/* Распределение детей в .pres-body (row/column) и зазоры. */
.pres-slide.pr-justify-start   { justify-content: flex-start; }
.pres-slide.pr-justify-center  { justify-content: center; }
.pres-slide.pr-justify-end     { justify-content: flex-end; }
.pres-slide.pr-justify-between { justify-content: space-between; }
.pres-slide.pr-justify-evenly  { justify-content: space-evenly; }
.pres-slide.pr-gap-sm { gap: .5em; }
.pres-slide.pr-gap-md { gap: 1em; }
.pres-slide.pr-gap-lg { gap: 2em; }

/* Растягивание по сетке/лейауту (аналог stretch в slides v2). */
.pres-slide .pr-stretch { align-self: stretch; width: 100%; }

/* Шаги: крупные иконки-маркеры (1, 2, 3) слева у пункта. */
/* Группа шагов: один центрируемый блок, пункты внутри слева. */
/* Два способа использования:
   1. Классы-теги на child-блоках (фенс columns/cards): `.pr-steps` на
      контейнере, `.pr-step` на шаге, `.pr-step-num` — круглый номер.
   2. Прямо на списке (markdown): `ol`/`ul` + `{: .pr-steps }` — li сами
      становятся шагами, номера генерируются CSS-счётчиком (ol) или
      буллетами-кружками (ul). */
.pres-slide .pr-steps {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.pres-slide .pr-step {
  position: relative;
  margin: .45em 0;
  padding-left: 2.55em; /* кружок 1.9em * .85 + зазор .9em */
}

.pres-slide .pr-step-num {
  position: absolute;
  left: 0;
  top: .12em;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  background: var(--pres-accent);
  color: var(--pres-bg);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .85em;
}

/* Стретч по строке: блок по ширине контента, центрируется на слайде
   (в противовес `width:100%`/`.pr-full`). Полезно для компактных
   списков/цитат среди пустого слайда. */
.pres-slide .pr-fit {
  width: fit-content;
  max-width: 100%;
  flex: 0 0 auto;
  align-self: center;             /* перебивает stretch от .box: блок по центру */
  margin-left: auto;
  margin-right: auto;
}

/* pr-steps на списках: li = шаг, круг вместо традиционного маркера.
   ВАЖНО: li — обычный блок, НЕ контейнер (flex/grid превращают инлайн-
   содержимое — strong, формулы span.arithmatex, код — во флекс-блоки и
   ломают переносы на узких экранах, тот же баг что лечили в task-list,
   blog.css ?v=35). Круг вынесен absolute: position:relative + padding-left
   на li, ::before absolute слева. Класс можно ставить ЛИБО на сам список
   (`ol {: .pr-steps }`), ЛИБО на обёртку-фенс вокруг него
   (````box {: .pr-steps }`) — внутренний `ol`/`ul` тоже захватывается,
   counter-reset у обёртки. */
.pres-slide ol.pr-steps,
.pres-slide ul.pr-steps,
.pres-slide .pr-steps ol,
.pres-slide .pr-steps ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
  counter-reset: pr-step;
}

.pres-slide .pr-steps li {
  position: relative;
  margin: .45em 0;
  padding-left: 2.55em; /* кружок 1.9em * .85 + зазор .9em */
  counter-increment: pr-step;
}

.pres-slide .pr-steps li::before {
  position: absolute;
  left: 0;
  top: .12em;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  background: var(--pres-accent);
  color: var(--pres-bg);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .85em;
  content: "\2022"; /* ul: буллет */
}

.pres-slide ol.pr-steps li::before,
.pres-slide .pr-steps ol li::before { content: counter(pr-step); }

/* Титульный слайд: подзаголовок и декоративная линейка. */
.pres-cover .pr-cover-sub {
  font-size: 1.35em;
  color: var(--pres-color);
  opacity: .78;
  margin: .5em auto 0;
  max-width: 26em;
}

.pres-cover .pr-cover-line {
  width: 4em;
  height: 4px;
  border-radius: 2px;
  background: var(--pres-accent);
  margin: .55em auto 0;
}

/* Разделитель внутри слайда. */
.pres-slide .pr-rule {
  width: 100%;
  height: 1px;
  background: var(--pres-border);
  margin: .8em 0;
}


/* ══════ Стили презентаций (data-pres-style) ══════
   Определяют ОБЩИЙ layout слайдов: положение заголовков, декор,
   панели, воздух. Работают вместе с темами (цвета).
   Задаются в meta: style: clean | bold | editorial | bento | glass */

/* ── clean ── Минимализм: воздух, тонкие линии, левое выравнивание.
   Слайд остаётся центрированным (базовый flex слайда); меняется только
   воздух по краям и оформление заголовка/панелей. Лево/центр не прижимаем. */
html[data-pres-style="clean"] {
  --pr-vpad: clamp(20px, 5vw, 80px);
  --pr-hpad: clamp(24px, 7vw, 110px);
}

html[data-pres-style="clean"] .pres-slide h1 {
  font-size: 1.8em;
  font-weight: 500;
  letter-spacing: .06em;
  margin-bottom: .4em;
  padding-bottom: .35em;
}

html[data-pres-style="clean"] .pres-slide h2 {
  font-weight: 500;
  letter-spacing: .03em;
}

html[data-pres-style="clean"] .pr-panel {
  border-radius: 6px;
  border-width: 1px;
}

html[data-pres-style="clean"] .pres-slide ul > li {
  font-weight: 400;
  line-height: 1.6;
}

/* ── bold ── Драматичный: чрезвычайно крупный заголовок как hero, один
   идеей на слайд, акцент-полоса. Увеличенный междустрочный, резкий вес. */
html[data-pres-style="bold"] .pres-slide {
  justify-content: safe center; /* при переполнении — flex-start, верх не обрезается */
  align-items: center;
}

html[data-pres-style="bold"] .pres-slide h1 {
  font-size: 3.4em;
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: -.02em;
  margin-bottom: .6em;
  padding-bottom: .3em;
  display: inline-block;
}

html[data-pres-style="bold"] .pres-slide h2 {
  font-size: 1.8em;
  font-weight: 800;
}

html[data-pres-style="bold"] .pres-slide ul {
}

html[data-pres-style="bold"] .pres-slide ul > li {
  font-size: 1.15em;
  font-weight: 500;
  margin: .6em 0;
}

html[data-pres-style="bold"] .pr-panel {
  border-width: 2px;
  border-color: var(--pres-accent);
  border-radius: 20px;
  font-size: 1.2em;
}

/* pr-panel-full — то же акцентное обрамление, что и pr-panel в bold
   (иначе «панель на всю высоту» остаётся серой: правило выше её не
   покрывает). */
html[data-pres-style="bold"] .pr-panel-full {
  border-width: 2px;
  border-color: var(--pres-accent);
  border-radius: 20px;
}

html[data-pres-style="bold"] .pres-cover h1 {
  font-size: 4.5em;
  border-bottom: none;
  line-height: 1.05;
}

html[data-pres-style="bold"] .pr-hero {
  font-size: 5em;
  font-weight: 900;
  line-height: 1;
}

/* ── editorial ── Журнальный: serif-шрифт, широкие поля, pull-quote,
   асимметричные зоны. Контент прижат левее (max-width), заголовок —
   тяжёлый serif, подпись — тонкий sans. */
html[data-pres-style="editorial"] {
  --pr-vpad: clamp(20px, 5vw, 80px);
  --pr-hpad: clamp(24px, 8vw, 120px);
}

html[data-pres-style="editorial"] .pres-slide h1 {
  font-family: var(--pres-header-font-family, var(--pres-font-family, "Source Serif 4", Georgia, "Times New Roman", serif));
  font-size: 2.4em;
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.2;
  margin-bottom: .5em;
  padding-left: .6em;
}

html[data-pres-style="editorial"] .pres-slide h2 {
  font-family: var(--pres-header-font-family, var(--pres-font-family, "Source Serif 4", Georgia, "Times New Roman", serif));
  font-weight: 600;
  padding-left: .4em;
  font-size: 1.5em;
}

html[data-pres-style="editorial"] .pr-panel {
  border-radius: 10px;
  border-left: 4px solid var(--pres-accent);
  border-top: none;
  border-right: none;
  border-bottom: none;
}

html[data-pres-style="editorial"] .pr-panel-0,
html[data-pres-style="editorial"] .pr-panel-full {
  border-left: 4px solid var(--pres-accent);
  border-top: none;
  border-right: none;
  border-bottom: none;
}

/* Pull-quote: цитата по центру с акцентными кавычками и курсивом */
html[data-pres-style="editorial"] blockquote {
  font-family: var(--pres-font-family, "Source Serif 4", Georgia, "Times New Roman", serif);
  font-style: italic;
  font-size: 1.4em;
  line-height: 1.5;
  border-left: none;
  padding-left: 1.2em;
  padding-right: 1.2em;
  color: var(--pres-accent);
  margin: 1.2em 0;
}

html[data-pres-style="editorial"] blockquote::before {
  content: "\201C";
  font-size: 2em;
  line-height: 0;
  vertical-align: -.3em;
  margin-right: .1em;
  opacity: .4;
}

/* Контент шириной — не растягивать на весь слайд, как в журнале */
html[data-pres-style="editorial"] .pres-body > *:not(.columns):not(.cards):not(.box):not(table) {
  max-width: 42em;
}

html[data-pres-style="editorial"] .pres-cover {
  padding-left: clamp(24px, 6vw, 96px);
}

html[data-pres-style="editorial"] .pres-cover h1 {
  font-family: var(--pres-header-font-family, var(--pres-font-family, "Source Serif 4", Georgia, "Times New Roman", serif));
  font-size: 2.8em;
}

/* ── bento ── «Плитка»: как СТИЛЬ отображения — закругления, объёмные
   панели, плотный ритм. НЕ диктует содержимое: не вводит «геро-зон»,
   размеров первой плитки и т.п. — это прерогатива автора (pr-*). */
html[data-pres-style="bento"] {
  --pr-vpad: clamp(16px, 3.5vw, 48px);
  --pr-hpad: clamp(16px, 5vw, 72px);
}

html[data-pres-style="bento"] .pres-slide h1 {
  font-size: 1.7em;
  font-weight: 700;
  letter-spacing: .01em;
  margin-bottom: .7em;
}

html[data-pres-style="bento"] .pr-panel {
  border-radius: 18px;
  padding: 1em 1.2em;
  background: color-mix(in srgb, var(--pres-card) 60%, transparent);
  border: 1px solid var(--pres-border);
}

html[data-pres-style="bento"] .pr-panel-0,
html[data-pres-style="bento"] .pr-panel-full {
  border-radius: 18px;
  padding: 1em 1.2em;
  background: color-mix(in srgb, var(--pres-card) 60%, transparent);
  border: 1px solid var(--pres-border);
}

html[data-pres-style="bento"] .pr-grid-2,
html[data-pres-style="bento"] .pr-grid-3,
html[data-pres-style="bento"] .pr-grid-4 {
  gap: .7em;
}

html[data-pres-style="bento"] .pres-cover h1 {
  font-size: 3em;
}

html[data-pres-style="bento"] .pr-hero {
  font-size: 3.8em;
}

/* ── glass ── Стекло: полупрозрачные панели, blur, светящиеся заголовки.
   2026: glassmorphism 2.0 — тонкая светлая кайма + мягкая тень-глубина. */
html[data-pres-style="glass"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 80px);
}

html[data-pres-style="glass"] .pres-slide h1 {
  font-size: 2.2em;
  font-weight: 600;
  letter-spacing: .01em;
  margin-bottom: .6em;
  text-shadow: 0 0 24px var(--pres-accent);
}

html[data-pres-style="glass"] .pres-slide h2 {
  opacity: .9;
}

html[data-pres-style="glass"] .pr-panel {
  background: color-mix(in srgb, var(--pres-card) 35%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--pres-color) 22%, transparent);
  border-radius: 18px;
  box-shadow:
    0 8px 24px color-mix(in srgb, var(--pres-accent) 10%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--pres-color) 14%, transparent);
}

html[data-pres-style="glass"] .pr-panel-0,
html[data-pres-style="glass"] .pr-panel-full {
  background: color-mix(in srgb, var(--pres-card) 35%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--pres-color) 22%, transparent);
  border-radius: 18px;
  box-shadow:
    0 8px 24px color-mix(in srgb, var(--pres-accent) 10%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--pres-color) 14%, transparent);
}

html[data-pres-style="glass"] .pres-cover h1 {
  text-shadow: 0 0 32px var(--pres-accent);
}

html[data-pres-style="glass"] .pres-cover .pr-cover-sub {
  text-shadow: 0 0 12px var(--pres-color);
}


/* ── swiss ── Швейцарская типографическая школа (урок истории, swizer):
   контент прижат к левому краю, заголовок крупный белый, под ним короткая
   красная акцент-полоска. Работает поверх тёмной темы swiss (или любой). */
html[data-pres-style="swiss"] {
  --pr-vpad: clamp(20px, 4vw, 64px);
  --pr-hpad: clamp(28px, 8vw, 128px);
}

html[data-pres-style="swiss"] .pres-slide {
  align-items: flex-start;      /* всё содержимое — слева */
  justify-content: flex-start;
  text-align: left;
}

html[data-pres-style="swiss"] .pres-slide h1 {
  font-size: 2em;
  font-weight: 800;
  letter-spacing: .01em;
  color: var(--pres-color);     /* не акцент — заголовок белый, акцент — полоска */
  margin-bottom: .5em;
}

/* Короткая красная полоска под заголовком (акцент швейцарской школы). */
html[data-pres-style="swiss"] .pres-slide h1::after {
  content: "";
  display: block;
  width: 2.4em;
  height: 4px;
  background: var(--pres-accent);
  margin-top: .28em;
}

html[data-pres-style="swiss"] .pres-slide h2 {
  color: var(--pres-accent);
  font-weight: 700;
}

html[data-pres-style="swiss"] .pres-slide ul > li {
  font-weight: 400;
  line-height: 1.7;
}

/* list_bar в оригинале: маркер-полоска (не круг) у каждого пункта. */
html[data-pres-style="swiss"] .pres-slide ul > li::before {
  border-radius: 0;
  width: .7em;
  height: .16em;
  top: .68em;
}

html[data-pres-style="swiss"] .pres-slide ol:not(.pr-steps) {
  list-style: none;
  counter-reset: swiss-ol;
  padding-left: 0;
}

html[data-pres-style="swiss"] .pres-slide ol:not(.pr-steps) > li {
  position: relative;
  padding-left: 1.6em;
  margin: .5em 0;
  counter-increment: swiss-ol;
}

html[data-pres-style="swiss"] .pres-slide ol:not(.pr-steps) > li::before {
  content: counter(swiss-ol);
  position: absolute;
  left: 0;
  top: .1em;
  width: 1em;
  font-size: 1.35em;
  font-weight: 700;
  color: var(--pres-accent);
}

/* Крупная цифра-«герой» для статистики: белая по умолчанию (как в swizer). */
html[data-pres-style="swiss"] .pres-slide .pr-hero {
  color: var(--pres-color);
}

html[data-pres-style="swiss"] .pres-slide .pr-hero.accent {
  color: var(--pres-accent);
}

/* ── neon ── Неоновые вывески: светящиеся акцентные рамки, мягкое свечение
   заголовков и текста, крупные скругления. Лучше с тёмными темами
   (cyber/hive/lime/cherry), но в светлых даёт «динамичный акцент». */
html[data-pres-style="neon"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="neon"] .pres-slide h1 {
  font-size: 2.3em;
  font-weight: 800;
  letter-spacing: .02em;
  margin-bottom: .6em;
  text-shadow: 0 0 18px color-mix(in srgb, var(--pres-accent) 55%, transparent);
}

html[data-pres-style="neon"] .pres-slide h2 {
  color: var(--pres-accent);
  text-shadow: 0 0 12px color-mix(in srgb, var(--pres-accent) 40%, transparent);
}

html[data-pres-style="neon"] .pr-panel {
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 60%, transparent);
  box-shadow:
    0 0 14px color-mix(in srgb, var(--pres-accent) 22%, transparent),
    inset 0 0 18px color-mix(in srgb, var(--pres-accent) 8%, transparent);
  background: color-mix(in srgb, var(--pres-card) 82%, transparent);
}

html[data-pres-style="neon"] .pr-panel-full {
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 60%, transparent);
  box-shadow:
    0 0 16px color-mix(in srgb, var(--pres-accent) 22%, transparent),
    inset 0 0 22px color-mix(in srgb, var(--pres-accent) 8%, transparent);
  background: color-mix(in srgb, var(--pres-card) 82%, transparent);
}

html[data-pres-style="neon"] .pres-slide ul > li::before {
  background: var(--pres-accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--pres-accent) 60%, transparent);
}

html[data-pres-style="neon"] .pres-cover h1 {
  text-shadow: 0 0 28px color-mix(in srgb, var(--pres-accent) 60%, transparent);
}

html[data-pres-style="neon"] .pr-hero {
  font-size: 4em;
  font-weight: 800;
  text-shadow: 0 0 26px color-mix(in srgb, var(--pres-accent) 55%, transparent);
}

/* ── prism ── Цветная дифракция: заголовок градиентом «чернила → акцент»,
   панели в подложке акцента с цветной тенью, живой преломлённый вид.
   Хорошо и в светлых темах (minimal/дефолт), и в тёмных. */
html[data-pres-style="prism"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="prism"] .pres-slide h1 {
  font-size: 2.2em;
  font-weight: 800;
  letter-spacing: .01em;
  margin-bottom: .6em;
  background:
    linear-gradient(120deg, var(--pres-color) 0%, var(--pres-color) 30%, var(--pres-accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

html[data-pres-style="prism"] .pres-slide h2 {
  color: var(--pres-accent);
}

html[data-pres-style="prism"] .pr-panel {
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 35%, transparent);
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--pres-card) 96%, var(--pres-accent)) 0%, var(--pres-card) 60%);
  box-shadow: 0 4px 18px color-mix(in srgb, var(--pres-accent) 12%, transparent);
}

html[data-pres-style="prism"] .pr-panel-full {
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 35%, transparent);
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--pres-card) 96%, var(--pres-accent)) 0%, var(--pres-card) 60%);
  box-shadow: 0 4px 18px color-mix(in srgb, var(--pres-accent) 12%, transparent);
}

html[data-pres-style="prism"] .pres-slide blockquote {
  border-left: 3px solid var(--pres-accent);
  padding-left: 1em;
}

html[data-pres-style="prism"] .pres-cover h1 {
  background:
    linear-gradient(120deg, var(--pres-color) 0%, var(--pres-accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

html[data-pres-style="prism"] .pr-hero {
  font-size: 3.6em;
  font-weight: 800;
}

/* ── paper ── Тёплый «бумажный» минимализм: мягкий кремовый фон, тонкие
   рамки, лёгкие тени, крупный контент. Светлеет палитру: карточки цвета
   «мелованной бумаги», акцент остаётся. Светлая тема по умолчанию. */
html[data-pres-style="paper"] {
  --pr-vpad: clamp(18px, 4vw, 60px);
  --pr-hpad: clamp(22px, 6vw, 88px);
}

html[data-pres-style="paper"] .pres-slide {
  background:
    radial-gradient(ellipse 60% 45% at 20% 100%, color-mix(in srgb, var(--pres-accent) 7%, transparent), transparent),
    var(--pres-bg);
}

html[data-pres-style="paper"] .pres-slide h1 {
  font-size: 2em;
  font-weight: 700;
  letter-spacing: .01em;
  margin-bottom: .6em;
  color: var(--pres-color);
}

html[data-pres-style="paper"] .pres-slide h2 {
  color: var(--pres-accent);
  font-weight: 600;
}

html[data-pres-style="paper"] .pr-panel {
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--pres-color) 14%, transparent);
  background: color-mix(in srgb, var(--pres-card) 92%, var(--pres-accent) 3%);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--pres-color) 8%, transparent);
}

html[data-pres-style="paper"] .pr-panel-full {
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--pres-color) 14%, transparent);
  background: color-mix(in srgb, var(--pres-card) 92%, var(--pres-accent) 3%);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--pres-color) 8%, transparent);
}

html[data-pres-style="paper"] .pres-slide ul > li::before {
  border-radius: 2px;   /* квадратный маркер-«тире» вместо кружка */
}

html[data-pres-style="paper"] .pres-cover h1 {
  font-size: 3.4em;
  color: var(--pres-color);
}

html[data-pres-style="paper"] .pr-hero {
  font-size: 3.4em;
  font-weight: 700;
}

/* ── nebula ── Туманность: многослойные мягкие радиальные пятна акцента,
   полупрозрачные карточки-«диски», лёгкие свечения. Советы: тёмные темы
   (cyber/hive/lime/cherry/ocean), но и в светлых даёт глубину. */
html[data-pres-style="nebula"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="nebula"] .pres-slide {
  background:
    radial-gradient(ellipse 55% 40% at 20% 15%, color-mix(in srgb, var(--pres-accent) 16%, transparent), transparent),
    radial-gradient(ellipse 45% 50% at 85% 90%, color-mix(in srgb, var(--pres-accent) 14%, transparent), transparent),
    radial-gradient(ellipse 40% 35% at 75% 10%, color-mix(in srgb, var(--pres-color) 6%, transparent), transparent),
    var(--pres-bg);
}

html[data-pres-style="nebula"] .pres-slide h1 {
  font-size: 2.1em;
  font-weight: 800;
  letter-spacing: .01em;
  margin-bottom: .6em;
  text-shadow: 0 2px 24px color-mix(in srgb, var(--pres-accent) 35%, transparent);
}

html[data-pres-style="nebula"] .pres-slide h2 {
  color: var(--pres-accent);
}

html[data-pres-style="nebula"] .pr-panel {
  border-radius: 22px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 28%, transparent);
  background: color-mix(in srgb, var(--pres-card) 62%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 10px 40px color-mix(in srgb, var(--pres-accent) 14%, transparent);
}

html[data-pres-style="nebula"] .pr-panel-full {
  border-radius: 22px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 28%, transparent);
  background: color-mix(in srgb, var(--pres-card) 62%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 10px 40px color-mix(in srgb, var(--pres-accent) 14%, transparent);
}

html[data-pres-style="nebula"] .pres-slide ul > li::before {
  background: var(--pres-accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--pres-accent) 70%, transparent);
}

html[data-pres-style="nebula"] .pres-cover {
  background:
    radial-gradient(ellipse 60% 55% at 50% 110%, color-mix(in srgb, var(--pres-accent) 25%, transparent), transparent),
    var(--pres-bg);
}

html[data-pres-style="nebula"] .pr-hero {
  font-size: 4em;
  font-weight: 800;
}

/* ── terminal ── Терминал-хакер: моноширинный шрифт, сканирующие линии,
   рамки-«окна», акцент горит зелёным/цветом темы. Хорошо с тёмными темами. */
html[data-pres-style="terminal"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="terminal"] .pres-slide {
  font-family: var(--pres-font-family, "JetBrains Mono", "Cascadia Mono", Consolas, "Courier New", monospace);
}
html[data-pres-style="terminal"] .pres-slide h1,
html[data-pres-style="terminal"] .pres-slide h2 {
  font-family: var(--pres-header-font-family, var(--pres-font-family, "JetBrains Mono", "Cascadia Mono", Consolas, "Courier New", monospace));
}
html[data-pres-style="terminal"] .pres-slide p,
html[data-pres-style="terminal"] .pres-slide li {
  font-family: var(--pres-font-family, "JetBrains Mono", "Cascadia Mono", Consolas, "Courier New", monospace);
}

html[data-pres-style="terminal"] .pres-slide {
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pres-accent) 5%, transparent) 0 3px, transparent 3px 100%) 0 0 / 100% 8px,
    repeating-linear-gradient(180deg, transparent 0 3px, color-mix(in srgb, var(--pres-color) 3%, transparent) 3px 4px),
    var(--pres-bg);
}

html[data-pres-style="terminal"] .pres-slide h1 {
  font-size: 1.5em;
  font-weight: 700;
  letter-spacing: .02em;
  margin-bottom: .6em;
  color: var(--pres-accent);
  text-shadow: 0 0 12px color-mix(in srgb, var(--pres-accent) 45%, transparent);
}

html[data-pres-style="terminal"] .pres-slide h1::before {
  content: "$ ";
  color: var(--pres-accent);
}

html[data-pres-style="terminal"] .pres-slide h2 {
  color: var(--pres-accent);
}

html[data-pres-style="terminal"] .pr-panel {
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 45%, transparent);
  background: color-mix(in srgb, var(--pres-card) 78%, transparent);
  box-shadow: 0 0 16px color-mix(in srgb, var(--pres-accent) 12%, transparent);
}

html[data-pres-style="terminal"] .pr-panel::before {
  content: "> ";
  color: var(--pres-accent);
}

html[data-pres-style="terminal"] .pr-panel-full {
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--pres-accent) 45%, transparent);
  background: color-mix(in srgb, var(--pres-card) 78%, transparent);
  box-shadow: 0 0 16px color-mix(in srgb, var(--pres-accent) 12%, transparent);
}

/* Burlёты как промпт терминала: > в потоке, без absolute-свисания кружка. */
html[data-pres-style="terminal"] .pres-slide ul > li {
  padding-left: .9em;
}
html[data-pres-style="terminal"] .pres-slide ul > li::before {
  content: ">";
  position: static;
  display: inline;
  width: auto;
  height: auto;
  background: none;
  border-radius: 0;
  color: var(--pres-accent);
  font-weight: 700;
  margin-right: .35em;
}

/* pr-steps в терминале: вместо кружков-номеров — приглашения «1>», «2>»… */
html[data-pres-style="terminal"] .pres-slide .pr-steps li,
html[data-pres-style="terminal"] .pres-slide ol.pr-steps li,
html[data-pres-style="terminal"] .pres-slide .pr-steps ol li {
  padding-left: 0;
}

html[data-pres-style="terminal"] .pres-slide .pr-steps li::before,
html[data-pres-style="terminal"] .pres-slide ol.pr-steps li::before,
html[data-pres-style="terminal"] .pres-slide .pr-steps ol li::before {
  content: counter(pr-step) ">";
  position: static;
  display: inline;
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  color: var(--pres-accent);
  font-weight: 700;
  font-size: 1em;
  margin-top: 0;
  margin-right: .5em;
  font-family: var(--pres-code-font-family, var(--pres-font-family, "JetBrains Mono", "Cascadia Mono", Consolas, "Courier New", monospace));
}

html[data-pres-style="terminal"] .pres-cover h1 {
  color: var(--pres-accent);
  text-shadow: 0 0 20px color-mix(in srgb, var(--pres-accent) 50%, transparent);
}

html[data-pres-style="terminal"] .pr-hero {
  font-family: var(--pres-font-family, "JetBrains Mono", Consolas, "Courier New", monospace);
  font-size: 3.4em;
  font-weight: 700;
}

/* ── poster ── Нео-бруталь: толстые жёсткие рамки, слегка смешённые тени,
   без скруглений, крупный контент. Живой постер-энергия в любых темах. */
html[data-pres-style="poster"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="poster"] .pres-slide h1 {
  font-size: 2.4em;
  font-weight: 900;
  letter-spacing: -.01em;
  line-height: 1.05;
  margin-bottom: .6em;
  text-transform: uppercase;
}

html[data-pres-style="poster"] .pres-slide h2 {
  font-weight: 800;
}

html[data-pres-style="poster"] .pr-panel {
  border-radius: 0;
  border: 3px solid var(--pres-color);
  background: var(--pres-card);
  box-shadow: 5px 5px 0 0 var(--pres-accent);
}

html[data-pres-style="poster"] .pr-panel-full {
  border-radius: 0;
  border: 3px solid var(--pres-color);
  background: var(--pres-card);
  box-shadow: 6px 6px 0 0 var(--pres-accent);
}

html[data-pres-style="poster"] .pres-slide ul > li::before {
  background: var(--pres-accent);
  border-radius: 0;
}

html[data-pres-style="poster"] .pres-slide blockquote {
  border-left: 6px solid var(--pres-accent);
  padding-left: 1em;
  font-weight: 700;
}

html[data-pres-style="poster"] .pres-cover h1 {
  text-transform: uppercase;
}

html[data-pres-style="poster"] .pr-hero {
  font-size: 4em;
  font-weight: 900;
  text-transform: uppercase;
}

/* ── candy ── Пастельно-поп: толстые акцентные рамки большого радиуса,
   жирный текст, дробные маркеры-пончики, тепло и дружелюбно. */
html[data-pres-style="candy"] {
  --pr-vpad: clamp(16px, 4vw, 56px);
  --pr-hpad: clamp(20px, 6vw, 84px);
}

html[data-pres-style="candy"] .pres-slide h1 {
  font-size: 2.2em;
  font-weight: 800;
  letter-spacing: .01em;
  margin-bottom: .6em;
}

html[data-pres-style="candy"] .pres-slide h2 {
  color: var(--pres-accent);
}

html[data-pres-style="candy"] .pr-panel {
  border-radius: 28px;
  border: 3px solid color-mix(in srgb, var(--pres-accent) 70%, transparent);
  background: color-mix(in srgb, var(--pres-card) 84%, var(--pres-accent) 5%);
}

html[data-pres-style="candy"] .pr-panel-full {
  border-radius: 28px;
  border: 3px solid color-mix(in srgb, var(--pres-accent) 70%, transparent);
  background: color-mix(in srgb, var(--pres-card) 84%, var(--pres-accent) 5%);
}

html[data-pres-style="candy"] .pres-slide ul > li::before {
  width: .72em;
  height: .72em;
  background: color-mix(in srgb, var(--pres-accent) 65%, var(--pres-bg));
  border-radius: 50%;
  top: .62em;
}

html[data-pres-style="candy"] .pres-cover h1 {
  font-size: 3.8em;
}

html[data-pres-style="candy"] .pr-hero {
  font-size: 3.8em;
  font-weight: 800;
}

/* ══════ Фоны презентаций (data-pres-bg) ══════
   Задаются в meta: bg: gradient | soft | aurora
   Добавляют декоративный фон поверх flat-цвета темы.
   Совместимы с любым стилем. */

/* gradient — диагональный градиент (немного светлее к низу-праву). */
html[data-pres-bg="gradient"] .pres-slide {
  background: linear-gradient(
    135deg,
    var(--pres-bg) 0%,
    color-mix(in srgb, var(--pres-bg) 82%, var(--pres-color)) 100%
  );
}

/* soft — мягкое свечение акцент-цвета в правом нижнем углу. */
html[data-pres-bg="soft"] .pres-slide {
  background:
    radial-gradient(ellipse 45% 40% at 85% 80%, color-mix(in srgb, var(--pres-accent) 12%, transparent), transparent),
    var(--pres-bg);
}

/* aurora — многоцветное свечение: 2-3 пятна разного оттенка. */
html[data-pres-bg="aurora"] .pres-slide {
  background:
    radial-gradient(ellipse 40% 35% at 15% 80%, color-mix(in srgb, var(--pres-accent) 10%, transparent), transparent),
    radial-gradient(ellipse 35% 40% at 80% 20%, color-mix(in srgb, var(--pres-accent) 8%, transparent), transparent),
    radial-gradient(ellipse 50% 30% at 50% 50%, color-mix(in srgb, var(--pres-color) 3%, transparent), transparent),
    var(--pres-bg);
}

/* image — ПОЛЬЗОВАТЕЛЬСКОЕ фоновое изображение (meta bg-image: <URL>).
   URL может быть в /media/..., https:// или data:. Второй слой
   (linear-gradient с --pres-bg-dim, 0..1) — затемнение для читаемости
   текста; по умолчанию 0 (без затемнения). */
html[data-pres-bg="image"] .pres-slide {
  background:
    linear-gradient(
      rgba(0, 0, 0, var(--pres-bg-dim, 0)),
      rgba(0, 0, 0, var(--pres-bg-dim, 0))
    ),
    var(--pres-bg-image) center / cover no-repeat,
    var(--pres-bg);
}

/* ── Воздух слайда (спейсинг) ──
   Перекрывает стили (стоят ПОСЛЕ них в файле; у равных селекторов
   побеждает последний). Приоритет:
   per-slide класс pr-a-tight/pr-a-wide > spacing в meta (этот блок) >
   дефолт стиля (> :root). */
html[data-pres-spacing="tight"] { --pr-vpad: clamp(8px, 2vw, 32px); --pr-hpad: clamp(12px, 4vw, 60px); }
html[data-pres-spacing="wide"]  { --pr-vpad: clamp(40px, 7vw, 110px); --pr-hpad: clamp(24px, 8vw, 128px); }
.pres-slide.pr-a-tight { --pr-vpad: clamp(8px, 2vw, 32px); --pr-hpad: clamp(12px, 4vw, 60px); }
.pres-slide.pr-a-wide  { --pr-vpad: clamp(40px, 7vw, 110px); --pr-hpad: clamp(24px, 8vw, 128px); }

/* ── Ширина колонки контента (column) ──
   Доля ширины слайда под контент (тело .pres-body). Дефолт — на всю
   ширину (полная колонка, как без меты). Значения в meta презентации:
   `column: full | three-quarters | two-thirds | half`. Работает в stack
   (тело как flex-колонка); в loose/левшах (display:contents) колонка
   не применима — там контент в потоке слайда. Не конфликтует со spacing:
   поля — это внешний воздух слайда, column — ширина контента внутри. */
html[data-pres-column="three-quarters"] .pres-slide > .pres-body { width: 75%;  max-width: 75%; }
html[data-pres-column="two-thirds"]     .pres-slide > .pres-body { width: 66.67%; max-width: 66.67%; }
html[data-pres-column="half"]           .pres-slide > .pres-body { width: 50%;  max-width: 50%; }

/* Пер-слайдная колонка (attr_list на h1 слайда, `# Заголовок {: .pr-col-half }`):
   перекрывает глобальную мету column (специфичность выше). pr-col-full — явно
   «на всю ширину» поверх глобальной колонки. */
.pres-slide.pr-col-full          > .pres-body { width: 100%;   max-width: 100%; }
.pres-slide.pr-col-three-quarters > .pres-body { width: 75%;   max-width: 75%; }
.pres-slide.pr-col-two-thirds    > .pres-body { width: 66.67%; max-width: 66.67%; }
.pres-slide.pr-col-half          > .pres-body { width: 50%;   max-width: 50%; }
/* ══════ Приоритет per-slide раскладок над стилями ══════
   Стиль `bold` (и др.) центрирует слайд жёстко через
   html[data-pres-style="bold"] .pres-slide — у него специфичность ВЫШЕ,
   чем у .pres-slide.pr-* (0,2,1 > 0,2,0), и пер-слайдные классы
   anchor/dock/justify/top «не работали» под style. Явная per-slide
   раскладка должна побеждать дефолт стиля. Блок поднят до (0,3,1)
   префиксом html[data-pres-style] и стоит ПОСЛЕ стилей. */
html[data-pres-style] .pres-slide.pr-top          { justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-anchor-nw    { align-items: flex-start; justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-anchor-n     { align-items: center;     justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-anchor-ne    { align-items: flex-end;   justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-anchor-w     { align-items: flex-start; justify-content: center; }
html[data-pres-style] .pres-slide.pr-anchor-c     { align-items: center;     justify-content: center; }
html[data-pres-style] .pres-slide.pr-anchor-e     { align-items: flex-end;   justify-content: center; }
html[data-pres-style] .pres-slide.pr-anchor-sw    { align-items: flex-start; justify-content: flex-end; }
html[data-pres-style] .pres-slide.pr-anchor-s     { align-items: center;     justify-content: flex-end; }
html[data-pres-style] .pres-slide.pr-anchor-se    { align-items: flex-end;   justify-content: flex-end; }
html[data-pres-style] .pres-slide.pr-dock-top     { justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-dock-bottom  { justify-content: flex-end; }
html[data-pres-style] .pres-slide.pr-dock-left    { align-items: flex-start; }
html[data-pres-style] .pres-slide.pr-dock-right   { align-items: flex-end; }
html[data-pres-style] .pres-slide.pr-dock-fill    { align-items: stretch; justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-justify-start   { justify-content: flex-start; }
html[data-pres-style] .pres-slide.pr-justify-center  { justify-content: center; }
html[data-pres-style] .pres-slide.pr-justify-end     { justify-content: flex-end; }
html[data-pres-style] .pres-slide.pr-justify-between { justify-content: space-between; }
html[data-pres-style] .pres-slide.pr-justify-evenly  { justify-content: space-evenly; }

/* ══════ Заголовки слайдов уважают классы статей .h1–.h6 ══════
   Пользователь может задать заголовку размер классом статьи
   (`# Заголовок {: .h4 }`). Стили презентации задают font-size на
   .pres-slide h1/h2 с большей специфичностью — явный класс должен
   побеждать (как в статьях). Покрываем все заголовки и все значения.
   Двойной селектор: без стиля (0,2,1) и под html[data-pres-style] (0,3,2). */
.pres-slide :is(h1, h2, h3, h4, h5, h6).h1,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h1 { font-size: 2rem; }
.pres-slide :is(h1, h2, h3, h4, h5, h6).h2,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h2 { font-size: 1.5rem; }
.pres-slide :is(h1, h2, h3, h4, h5, h6).h3,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h3 { font-size: 1.25rem; }
.pres-slide :is(h1, h2, h3, h4, h5, h6).h4,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h4 { font-size: 1.125rem; }
.pres-slide :is(h1, h2, h3, h4, h5, h6).h5,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h5 { font-size: 1rem; }
.pres-slide :is(h1, h2, h3, h4, h5, h6).h6,
html[data-pres-style] .pres-slide :is(h1, h2, h3, h4, h5, h6).h6 { font-size: 0.875rem; }

/* ══════ Шрифты презентации (meta font / header-font) ══════
   presentation.js ставит --pres-font-family (тело) и
   --pres-header-font-family (заголовки) при `font:`/`header-font:` в meta;
   один без другого подхватывает значение второго (фолбэк в JS).
   Без meta слайды наследуют шрифт страницы (как раньше). */
.pres-slide,
.pres-cover {
  font-family: var(--pres-font-family, var(--body-family, inherit));
}

/* Заголовки слайдов берут header-font; если его нет — свойство не задано,
   и они наследуют шрифт тела через --pres-font-family (в .pres-slide).
   Классы-утилиты .h1..h6 (div/span/p) тоже получают header-font. */
.pres-slide h1,
.pres-slide h2,
.pres-slide h3,
.pres-slide h4,
.pres-slide h5,
.pres-slide h6,
.pres-slide .h1,
.pres-slide .h2,
.pres-slide .h3,
.pres-slide .h4,
.pres-slide .h5,
.pres-slide .h6 {
  font-family: var(--pres-header-font-family, var(--heading-family, inherit));
}

/* ══════ Кодовый шрифт презентации (meta code-font) ══════
   presentation.js ставит --pres-code-font-family при `code-font:` в meta
   (Google Fonts напрямую). Применяется ТОЛЬКО к коду/моно; НЕ влияет на
   font/header-font и не меняется на них. Без code-font — системный
   моноширинный (как в блоге). В терминальном стиле (JetBrains Mono в
   font-family слайда ниже по специфичности приоритет кода выше). */
.pres-slide :where(code, pre, .mono) {
  font-family: var(--pres-code-font-family, var(--code-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace));
}
