/* converting ugc — layout proportions measured from the reference (see docs/03-design-spec.md).
   Mobile-first: base rules are the phone, media queries add tablet (768) and desktop (1024/1280).
   Light theme only, like the reference. */

:root {
  --bg: #ffffff;
  --sidebar-bg: #f3f6fd;
  --surface: #fbfcff;
  --surface-2: #f8faff;
  --line: #ebeef5;
  --line-input: #cbd5e1;
  --ink: #0a0a0a;
  --ink-soft: #6b7280;
  --ink-label: #5c5c69;
  --primary: #1a1a20;
  --primary-ink: #ffffff;
  --danger: #c8322f;
  /* Подсветка пометок подачи в сценарии — тёплая, но не кричащая. */
  --tag-bg: #ffeaa7;
  /* Пометки, которые будут вырезаны. Цвет нейтральный нарочно: это наше
     правило, а не ошибка человека, и пугать его нечем. */
  --tag-drop: #e6e8ef;
  --ok: #1f8a54;

  /* Цвет подсказки онбординга. Родня --tag-bg (#ffeaa7), только насыщеннее:
     тёплый акцент на холодном сером интерфейсе виден мгновенно. Взять
     --primary нельзя — им уже означено «выбрано» (активная модель, кнопка
     отправки), и кольцо читалось бы как состояние элемента, а не как
     указание, куда нажать. */
  --guide: #c47a00;
  --guide-halo: rgba(196, 122, 0, .16);

  --r-card: 24px;
  --r-md: 16px;
  --r-sm: 10px;
  --r-xs: 6px;

  --sidebar-w: 232px;
  --topbar-h: 56px;
  --shadow-card: 0 8px 28px rgba(21, 32, 64, .08);
  --shadow-soft: 0 1px 2px rgba(21, 32, 64, .05);
}

* { box-sizing: border-box; }
[x-cloak] { display: none !important; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.5 "Inter", "Inter Variable", -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a { color: inherit; }
h1 { font-size: 22px; margin: 0 0 4px; }
h2 { font-size: 18px; margin: 0 0 8px; }
h3 { font-size: 16px; margin: 0; font-weight: 600; }
.muted { color: var(--ink-soft); }
.plus { color: var(--ok); }
.minus { color: var(--danger); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 0 18px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  text-decoration: none; transition: transform .06s ease, opacity .15s ease;
}
.btn:active { transform: scale(.98); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn--primary { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.btn--ghost { background: transparent; }
.btn--block { width: 100%; }
.btn--sm { min-height: 36px; padding: 0 12px; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: var(--r-xs); background: transparent;
  color: var(--ink); font-size: 16px; cursor: pointer;
}
.burger { position: relative; width: 18px; height: 1.5px; background: currentColor; border-radius: 2px; }
.burger::before, .burger::after {
  content: ""; position: absolute; left: 0; width: 18px; height: 1.5px;
  background: currentColor; border-radius: 2px;
}
.burger::before { top: -6px; }
.burger::after { top: 6px; }

/* ---------- shell ---------- */
.shell { min-height: 100vh; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 8px;
  height: var(--topbar-h); padding: 0 8px;
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 700; letter-spacing: -.02em; text-decoration: none; font-size: 17px; }
.brand span { color: var(--ink-soft); font-weight: 500; }
.brand--top { flex: 1; text-align: center; }
.credits-pill {
  min-width: 44px; height: 30px; padding: 0 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; font-weight: 600; font-size: 13px;
}

/* drawer state lives on .shell — plain CSS, no JS framework involved */
.scrim { display: none; position: fixed; inset: 0; z-index: 40; background: rgba(10, 16, 34, .4); }
.shell.nav-open .scrim { display: block; }
.shell.nav-open .sidebar { transform: none; }

.sidebar {
  position: fixed; top: 0; left: 0; z-index: 50;
  width: min(86vw, var(--sidebar-w)); height: 100dvh;
  display: flex; flex-direction: column;
  padding: 16px;
  background: var(--sidebar-bg);
  transform: translateX(-102%); transition: transform .25s ease;
  /* Сайдбар целиком не скроллится — как у референса. Прокручивается только
     список папок, а Explore и кнопки внизу всегда на виду. */
  overflow: hidden;
}
.sidebar.is-open { transform: none; }

/* Свёрнутый столбец. На узком экране он и так выдвижной, поэтому правило
   ничего не меняет; вся работа — на широком, где столбец стоит всегда. */
.sidebar__hide { display: none; }
/* Кнопка «вернуть столбец» показывается только там, где столбец можно
   свернуть, — на широком экране. На узком он выдвижной, и его возвращает
   бургер в верхней полосе. */
.nav-show { display: none; }
/* Подпись рядом с бургером. Один значок читался бы как «открыть ящик», а
   ящика на широком экране нет — там столбец либо стоит, либо свёрнут. */
.nav-show__word { line-height: 1; }
.sidebar__head { display: flex; align-items: center; justify-content: space-between; }
/* Низ прижат к краю и намеренно компактный: три кнопки в столбик забирали
   199px и не оставляли списку папок ничего, кроме min-height. Главная кнопка
   остаётся во всю ширину, второстепенные встают парой в одну строку. */
.sidebar__foot { margin-top: auto; padding-top: 12px; display: grid; gap: 8px; }
.sidebar__foot-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sidebar__foot-row .btn { min-height: 34px; padding: 0 10px; font-size: 13px; }
.version { margin-top: 4px; font-size: 11px; color: var(--ink-soft); text-align: center; }

/* workspace card: 287×42, radius 12, padding 6 in the reference */
.workspace-card {
  margin: 14px 0 18px; padding: 6px 10px; min-height: 42px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow-soft);
}
.workspace-card__ava {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--tag-bg); color: var(--ink);
  font-size: 13px; font-weight: 600;
}
.workspace-card__who { min-width: 0; display: flex; flex-direction: column; }
.workspace-card__name { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.workspace-card__mail {
  font-size: 11.5px; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.workspace-card__credits { font-size: 13px; color: var(--ink-soft); white-space: nowrap; margin-left: auto; }
.workspace-card__credits strong { color: var(--ink); }

/* Колонка навигации: список папок забирает остаток высоты и прокручивается,
   Explore держится под ним и не уезжает. */
.nav { position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0; }
/* Папкам отдаём весь остаток высоты. Минимум 120px — это примерно доля,
   которую список папок занимает у референса (144 из 738), иначе на обычном
   окне он схлопывается до пары строк. */
.nav__list--folders { flex: 1 1 auto; min-height: 96px; overflow-y: auto; overscroll-behavior: contain; }
.nav__explore { flex: 0 0 auto; }

/* На низком окне фиксированной части уже не хватает места: там честнее вернуть
   прокрутку всему сайдбару, иначе Explore и кнопки просто обрежет. */
/* Ниже 650px фиксированной части уже не хватает (554px без списка + минимум 96px
   на папки), поэтому там честнее вернуть прокрутку всему сайдбару. */
@media (max-height: 650px) {
  .sidebar { overflow-y: auto; }
  .nav { flex: 0 0 auto; }
  .nav__list--folders { flex: 0 0 auto; overflow: visible; }
}
.nav__label {
  display: flex; align-items: center; justify-content: space-between;
  margin: 14px 0 4px;
  font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-label);
}
.nav__add-btn {
  width: 24px; height: 24px; padding: 0; line-height: 1;
  border: 1px solid var(--line); border-radius: var(--r-xs);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
}
.nav__list { list-style: none; margin: 0; padding: 0; }
/* reference nav item is exactly 36 high with 8/12 padding — keep line-height in check */
.nav__item, .nav__subitem {
  display: flex; align-items: center; gap: 10px;
  height: 36px; padding: 8px 12px;
  border-radius: var(--r-xs); text-decoration: none; color: var(--ink);
  font-size: 16px; line-height: 20px;  /* как у референса */
}
.nav__item:hover, .nav__subitem:hover { background: rgba(255, 255, 255, .7); }
.nav__icon { color: var(--ink-soft); font-size: 12px; }
.nav__sub { list-style: none; margin: 0 0 4px; padding-left: 22px; }
.nav__subitem { min-height: 32px; font-size: 14px; color: var(--ink-soft); }
.main { padding: 12px 12px 128px; }

.demo-strip {
  margin-bottom: 12px; padding: 9px 12px;
  background: #fff8e2; color: #7a5a00; border: 1px solid #f5e3b0;
  border-radius: var(--r-sm); font-size: 13px;
}

/* ---------- content header ---------- */
/* phones: crumbs and search each get their own row, otherwise the crumbs wrap mid-word */
.content-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
.crumbs {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  font-size: 15px; color: var(--ink-soft); white-space: nowrap; overflow: hidden;
}
.crumbs strong { color: var(--ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.crumbs a { text-decoration: none; }
.search {
  margin-left: auto; width: 100%; max-width: none; height: 40px;
  padding: 8px 12px; border: 1px solid var(--line-input); border-radius: var(--r-xs);
  background: var(--bg); font: inherit; font-size: 14px; color: var(--ink);
}

/* ---------- workspace ---------- */
.workspace__bar { margin: 4px 0 12px; text-align: center; font-size: 14px; color: var(--ink-soft); }
.credits-badge { display: none; }

.alert {
  margin-bottom: 12px; padding: 10px 12px;
  background: #fdeceb; color: #7d1f1d; border: 1px solid #f5cfcd;
  border-radius: var(--r-sm); font-size: 14px;
}

.empty { padding: 56px 16px; text-align: center; }
.empty h2 { margin: 0 0 6px; font-size: 18px; font-weight: 400; color: var(--ink-soft); }
.empty p { margin: 0; font-size: 14px; color: var(--ink-soft); }

/* Grid breakpoints copied from the reference: 2 / 3@400 / 2@640 / 3@768 / 4@1024 / 6@1280 */
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (min-width: 400px) { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; } }

/* A tile is the whole card: thumbnail fills it, everything else floats on top. */
.tile {
  position: relative; display: flex; flex-direction: column;
  aspect-ratio: 9 / 16; width: 100%;
  overflow: hidden; border-radius: 10px; background: #f3f4f6; cursor: pointer;
}
.tile__media { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile__media.is-dim { opacity: .3; }

.tile__badge {
  position: absolute; left: 8px; top: 8px; z-index: 10;
  padding: 2px 6px; border-radius: 6px;
  background: rgba(18, 23, 35, .5); backdrop-filter: blur(4px);
  color: #fff; font-size: 8px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase;
  pointer-events: none;
}
.tile__action {
  position: absolute; right: 8px; top: 8px; z-index: 20;
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 999px;
  background: rgba(18, 23, 35, .35); backdrop-filter: blur(4px);
  color: #fff; font-size: 13px; text-decoration: none;
  transition: background .2s ease;
}
.tile__action:hover { background: rgba(18, 23, 35, .7); }

.tile__play {
  position: absolute; inset: 0; z-index: 15;
  display: flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: #fff; font-size: 30px; cursor: pointer;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}

/* bottom gradient with the date — always on for touch, on hover for desktop */
.tile__veil {
  position: absolute; inset: 0; z-index: 12; pointer-events: none;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 2px;
  padding: 8px;
  background: linear-gradient(to top, rgba(0, 0, 0, .8), transparent 45%);
  color: #fff; transition: opacity .3s ease;
}
.tile__date { font-size: 10px; font-weight: 600; }
.tile__script { font-size: 10px; opacity: .8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tile__overlay {
  position: absolute; inset: 0; z-index: 18;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 10px; text-align: center;
  background: rgba(10, 16, 34, .55); color: #fff; font-size: 11px;
}
.tile__overlay--soft { background: rgba(10, 16, 34, .3); }
.tile__overlay--error { background: rgba(90, 12, 12, .68); }
.tile__error { font-size: 10px; line-height: 1.35; }
.tile__hint { font-size: 10px; opacity: .75; }
.spinner {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, .35); border-top-color: #fff;
  animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 3s; } }

@media (min-width: 640px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  .tile__badge { left: 10px; top: 12px; padding: 2px 8px; font-size: 9px; }
  .tile__action { right: 12px; top: 12px; }
  /* on desktop the caption shows on hover, like the reference */
  .tile__veil { opacity: 0; }
  .tile:hover .tile__veil { opacity: 1; }
}

/* ── ящик навигации на телефоне ──────────────────────────────────────
   Ширина была той же, что и у столбца на мониторе, — 232 пикселя, шесть
   десятых экрана: половина названий папок обрывалась многоточием. И почти
   каждая строка была ростом 36 пикселей при рекомендованных сорока
   четырёх — в такую попадают не с первого раза. */
@media (max-width: 1023px) {
  .sidebar { width: min(84vw, 320px); }
  .nav__item, .nav__subitem { min-height: 44px; }
  .nav__add-btn { width: 40px; height: 40px; }
  .sidebar__foot-row .btn { min-height: 44px; }
  /* Свернуть столбец насовсем можно только там, где он и так стоит:
     на телефоне его всё равно вызывают бургером. */
  .sidebar__hide { display: none; }
}

/* ── композер на телефоне: шторка снизу ──────────────────────────────
   Раскрытый композер занимал экран сверху донизу тем же рядом органов,
   что и на широком мониторе: пилюли ломались в три строки, а стрелка
   уезжала вместе с прокруткой — до главного действия приходилось
   докручивать. Здесь он ведёт себя как шторка: заголовок с крестиком,
   тело прокручивается само, а ряд с отправкой прибит к низу и никуда
   не девается.

   Только до 1024: на широком экране композер — карточка посередине,
   и всё это ей ни к чему. */
@media (max-width: 1023px) {
  .composer.is-open {
    top: auto; max-height: 88dvh;
    display: flex; flex-direction: column;
    border-radius: 16px 16px 0 0;
  }
  /* Затемнение позади. Отдельного узла не заводим: шторка и так знает,
     открыта ли она, а лишний div пришлось бы прятать вручную. */
  .composer.is-open::before {
    content: ""; position: fixed; inset: 0;
    background: rgba(0, 0, 0, .38);
  }
  /* Собственный фон шторки — поверх затемнения. Затемнение лежит на всём
     прямоугольнике композера, включая его же подложку, и шапка выходила
     серой, будто она часть погашенной страницы. */
  .composer.is-open > * { position: relative; }
  .composer.is-open .composer__handle,
  .composer.is-open .composer__form { background: var(--surface-2); }

  /* Шапка шторки. Надпись и крестик рисуем стилем, а не разметкой:
     кнопку внутрь кнопки не вложить, а вся шапка и так закрывает. */
  .composer.is-open .composer__handle {
    align-items: flex-start; padding: 12px 14px 10px;
    border-bottom: 1px solid var(--line); flex: none;
  }
  .composer.is-open .composer__mode {
    font-size: 17px; line-height: 1.2;
  }
  .composer.is-open .composer__mode::before {
    content: "Create"; display: block;
    font-size: 10px; font-weight: 600; letter-spacing: .09em;
    text-transform: uppercase; color: var(--ink-soft); margin-bottom: 2px;
  }
  /* Цена уходит из шапки: она есть внизу, в строке итога, и повторять
     её над той же шторкой значит говорить дважды. */
  .composer.is-open .composer__price { display: none; }
  .composer.is-open .composer__chev {
    margin-left: auto; font-size: 0;
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--surface-2); display: grid; place-items: center;
  }
  .composer.is-open .composer__chev::after {
    content: "✕"; font-size: 14px; color: var(--ink-soft);
  }

  .composer.is-open .composer__form {
    flex: 1; min-height: 0; overflow-y: auto;
    display: flex; flex-direction: column;
    padding: 10px 12px 0;
  }

  /* В столбик: снимок над текстом, а не рядом. Бок о бок на 390 обоим
     тесно — зона фото сжимается до марки, а строка текста до двух слов. */
  .composer.is-open .composer__main { flex-direction: column; }
  .composer.is-open .composer__main > .dropzone { height: 148px; flex-basis: auto; }
  /* Парные зоны («ваше видео» и «первый кадр», начало и конец сцены) делят
     строку поровну. Без этого они наследовали `flex-basis: auto` от правила
     выше при нулевом росте и сжимались до ширины плюсика — в «Ad Remake»
     обе зоны выходили по четырнадцать пикселей. */
  .composer.is-open .framepair .dropzone { flex: 1 1 0; height: 148px; }

  /* Поле реплики выглядело как обычный текст: рамки у него нет, а серая
     подсказка внутри читается как чужой абзац, а не как «сюда писать».
     Обводим и подписываем — «Script», тем же словом, что и у витрины.
     Подпись только там, где поле есть: в режимах с эталонным роликом
     писать нечего, и заголовок врал бы. */
  .composer.is-open .composer__fields:has(.tagbox)::before {
    content: "Script";
    font-size: 10.5px; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: var(--ink-soft);
    margin: 2px 0 5px;
  }
  .composer.is-open .tagbox {
    border: 1px solid var(--line-input); border-radius: var(--r-sm);
    background: var(--bg); padding: 4px 6px;
  }
  .composer.is-open .tagbox:focus-within { border-color: var(--primary); }

  /* Ряд отправки прибит к низу шторки: стрелка — главное действие,
     и докручивать до неё нельзя. */
  .composer.is-open .composer__controls {
    /* Слой выше текстового поля. `position: sticky` заводит собственный слой,
       и всё внутри него — включая выпадающие меню с их `z-index: 70` —
       оказалось ниже поля реплики, у которого `z-index: 1`: списки режимов,
       актёров и голосов читались сквозь текст подсказки. */
    position: sticky; bottom: 0; margin-top: auto; z-index: 3;
    padding: 10px 0 calc(10px + env(safe-area-inset-bottom));
    background: var(--surface-2); border-top: 1px solid var(--line);
  }
  /* Органы выбора занимают строку целиком: пилюли шириной в слово
     ловятся пальцем через раз. */
  .composer.is-open .composer__controls > .pickwrap,
  .composer.is-open .composer__controls > .modepick { flex: 1 1 140px; }
  .composer.is-open .composer__controls .pill { width: 100%; min-height: 44px; }
  .composer.is-open .composer__send { margin-left: auto; }
}

/* ---------- composer ---------- */
.composer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 35;
  /* z-index у пикеров внутри считается относительно этого контекста, поэтому
     сами по себе они выше сайдбара (50) подняться не могут и уезжают под него.
     Пока какой-то пикер открыт — поднимаем весь композер над сайдбаром. */
  background: var(--surface-2); border-top: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  padding-bottom: env(safe-area-inset-bottom);
}
.composer:has(details[open]) { z-index: 70; }

.composer__handle {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 56px; padding: 0 14px;
  border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 14px; cursor: pointer;
}
.composer__mode { font-weight: 600; }
.composer__price { margin-left: auto; font-size: 13px; color: var(--ink-soft); }
.composer__chev { transition: transform .2s ease; color: var(--ink-soft); }
.composer__chev.is-up { transform: rotate(180deg); }

.composer__form { display: none; padding: 0 10px 10px; }
.composer.is-open .composer__form { display: block; }

.composer__row { display: flex; gap: 10px; }
.composer__main {
  display: flex; gap: 10px; padding: 6px;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-md);
}
.composer__fields { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.dropzone {
  position: relative; flex: 0 0 84px; height: 112px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line-input); border-radius: 12px;
  background: var(--surface-2); cursor: pointer; overflow: hidden;
}
.dropzone.has-file { border-style: solid; }
.dropzone input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.dropzone img { width: 100%; height: 100%; object-fit: cover; }
.dropzone__text { text-align: center; font-size: 12px; color: var(--ink-soft); line-height: 1.7; }

textarea, input[type="text"], input[type="email"], input[type="password"],
input[type="url"], select {
  width: 100%; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--ink); font: inherit; font-size: 14px; resize: vertical;
}
.composer textarea { border: 0; background: transparent; padding: 6px 4px; min-height: 76px; }
textarea:focus, input:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
.composer textarea:focus { outline: 0; }
.composer__counter { margin: 2px 4px 6px; text-align: right; font-size: 11px; color: var(--ink-soft); }
.composer__scene { border: 0 !important; background: transparent !important; padding: 4px !important; }

.composer__controls {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 10px;
}
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  height: 36px; padding: 8px 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink); font: inherit; font-size: 14px; cursor: pointer;
  box-shadow: var(--shadow-soft);
}
.pill--static { cursor: default; }
.pill__chev { color: var(--ink-soft); font-size: 11px; }

/* <details> based pickers: the browser handles open/close, no JS state */
.modepick summary, .pickwrap summary { list-style: none; cursor: pointer; }
.modepick summary::-webkit-details-marker,
.pickwrap summary::-webkit-details-marker { display: none; }
/* position: relative — не украшение: меню формы кадра позиционируется
   absolute, и без опоры на собственную кнопку оно отсчитывалось от всего
   композера и улетало в его верхний угол. На .sheet внутри пикеров актёра
   и голоса это не влияет: те fixed. */
.pickwrap { display: inline-block; position: relative; }

.modepick { position: relative; display: inline-block; }
.modepick__menu {
  position: absolute; bottom: calc(100% + 6px); left: 0; z-index: 70;
  width: 240px; max-height: 320px; overflow-y: auto; padding: 6px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-card);
}
.modepick__item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; text-align: left; background: none; border: 0;
  font-family: inherit; cursor: pointer;
  padding: 8px 10px; border-radius: var(--r-xs);
  font-size: 14px; text-decoration: none; color: var(--ink);
}
.modepick__item:hover { background: var(--surface-2); }
.modepick__item.is-active { font-weight: 600; background: var(--surface-2); }

/* Запертые режимы: видно, что продукт умеет больше, но пройти можно одним
   путём. Не курсор «нельзя» и не всплывающая жалоба — просто бледнее
   остальных, и строка внизу меню говорит, когда откроются. */
/* Во время онбординга меню не прокручивается: предел в 320px обрезал
   восьмой режим и строку под списком — то есть ровно то, ради чего меню
   и открывается само. */
.composer.is-coached .modepick__menu { max-height: none; overflow: visible; }
.modepick__item.is-locked { color: var(--ink-soft); opacity: .5; cursor: default; }
.modepick__item.is-locked:hover { background: transparent; }
.modepick__foot {
  margin: 6px 0 0; padding: 8px 10px 2px;
  border-top: 1px solid var(--line);
  font-size: 12px; line-height: 1.45; color: var(--ink-soft);
}

/* ── Онбординг: строка над композером и кольцо на элементе ───────────────
   Строка, а не окно поверх экрана: закрывать собой то, что человек как раз
   осваивает, — худшее, что может сделать подсказка.                       */
.coach {
  display: flex; align-items: baseline; gap: 10px;
  margin: 0 0 14px; padding: 2px 0 2px 12px;
  border-left: 3px solid var(--guide);
}
.coach__step {
  flex: none;
  background: var(--guide); color: #fff;
  border-radius: 999px; padding: 3px 9px;
  font-size: 11px; letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}
/* Класс с display перебивает браузерное правило для атрибута: без этой
   строки подсказка висела бы на экране и с проставленным hidden. */
.coach[hidden] { display: none; }
.coach__say { margin: 0; font-size: 14px; line-height: 1.5; max-width: 58ch; }
.coach__say[hidden] { display: none; }
.coach__say b { font-weight: 600; }
.coach__next {
  margin-left: auto;
  border: 0; border-radius: 999px;
  background: var(--guide); color: #fff;
  font: inherit; font-size: 12.5px; font-weight: 500;
  padding: 6px 16px; cursor: pointer;
}
.coach__next[hidden] { display: none; }
.coach__next:hover { filter: brightness(1.08); }
.coach__next + .coach__skip { margin-left: 14px; }
.coach__skip { margin-left: auto; }
.coach__skip {
  border: 0; background: none; padding: 0;
  font: inherit; font-size: 12.5px; color: var(--ink-soft);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.coach__skip:hover { color: var(--ink); }

/* Кольцо. Толстое и с ореолом нарочно: тонкая линия у края элемента
   теряется среди рамок полей, а искать подсказку человек не должен. */
[data-coach].is-lit {
  position: relative;
  /* Обводкой, а не рамкой на ::after. Псевдоэлемент рисуется внутри
     элемента и обрезается его же overflow: hidden — у dropzone он стоит
     ради превью, и от кольца оставался один уголок в углу. Обводка
     рисуется снаружи, сама повторяет скругление и обрезке не поддаётся. */
  outline: 3px solid var(--guide);
  outline-offset: 4px;
  box-shadow: 0 0 0 9px var(--guide-halo);
  /* А номер — обычный псевдоэлемент, и его прячет тот же overflow. */
  overflow: visible;
}
/* Номер связывает кольцо со строкой сверху: две детали читаются как одно
   указание, а не как две несвязанные пометки. */
[data-coach].is-lit::before {
  content: attr(data-lit);
  position: absolute; top: -15px; left: -15px; z-index: 2;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--guide); color: #fff;
  font-size: 11px; line-height: 24px; text-align: center;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 6px rgba(21, 32, 64, .22);
}
@media (prefers-reduced-motion: no-preference) {
  [data-coach].is-lit { transition: box-shadow .2s ease, outline-color .2s ease; }
}
.pill img { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; }
.composer__send {
  margin-left: auto;
  width: 48px; height: 48px; padding: 0;
  border: 0; border-radius: var(--r-md);
  background: var(--primary); color: var(--primary-ink);
  font-size: 18px; cursor: pointer;
}
.composer__send:disabled { opacity: .35; cursor: not-allowed; }

/* кадры на выбор в превью */
.preview__shots { display: flex; flex-direction: column; gap: 10px; }
.shots { display: flex; gap: 8px; }
.shots__one {
  flex: 1; padding: 0; border: 2px solid transparent; border-radius: 8px;
  background: none; cursor: pointer; overflow: hidden; line-height: 0;
}
.shots__one img { width: 100%; height: auto; display: block; border-radius: 6px; }
.shots__one:hover { border-color: var(--line); }
.shots__one.is-on { border-color: var(--primary); }

.composer__scriptbar { display: flex; align-items: center; gap: 12px; margin: 2px 4px 6px; }
.emobtn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-soft);
  font: inherit; font-size: 12px; cursor: pointer;
}
.emobtn:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); }
.emobtn:disabled { opacity: .5; cursor: default; }
.composer__scriptbar .composer__counter { margin: 0 0 0 auto; }
.composer__counter.is-over { color: #b3261e; font-weight: 600; }
.composer__note {
  margin: 8px 0 0; font-size: 12.5px; color: #b3261e;
}
/* Исход, а не ошибка: ничего не сломалось и ничего не потеряно. */
.composer__note--plain { color: var(--ink-soft); }

/* ---------- sheet / modal ---------- */
.sheet { position: fixed; inset: 0; z-index: 60; display: flex; align-items: flex-end; background: rgba(10, 16, 34, .45); }
.sheet__panel {
  width: 100%; max-height: 88dvh; overflow-y: auto;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  background: var(--bg); border-radius: 20px 20px 0 0;
}
.sheet__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.sheet__actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }

/* ---------- pickers (actor / voice) ---------- */
.sheet__panel--picker { display: flex; flex-direction: column; padding: 0; max-height: 88dvh; }

.picker__head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 10px; border-bottom: 1px solid var(--line);
}
.picker__head h3 { white-space: nowrap; }
.picker__search {
  flex: 1; min-width: 0; height: 36px; padding: 8px 12px;
  border: 1px solid var(--line-input); border-radius: var(--r-xs);
  background: var(--bg); font: inherit; font-size: 14px;
}

.picker__body { display: flex; flex-direction: column; gap: 0; overflow: hidden; }
/* Фильтры на телефоне спрятаны за воронкой в шапке, как у витрины. Рядом
   с сеткой они не помещались: полоса сжималась флексом до высоты подписи,
   и «Gender» с «Age» висели над закрытыми кнопками. */
.picker__filters {
  /* Столбиком, а не строкой: строкой последняя группа («Style») уезжала
     за правый край и её теги нельзя было нажать. */
  display: none; flex: none; flex-direction: column; gap: 14px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
/* Своя прокрутка: тегов больше, чем влезает в половину телефона, и нижние
   («Elegant», «Trendy») оказывались за краем панели. */
.sheet__panel.show-filters .picker__filters {
  display: flex; max-height: 42dvh; overflow-y: auto;
}
.picker__filters-btn { flex: none; }
.picker__filters .btn--block { display: none; }
.picker__group { flex: 0 0 auto; }
.picker__label {
  margin-bottom: 6px; font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-label);
}
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: 13px; cursor: pointer;
  white-space: nowrap;
}
.chip.is-active { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.tone {
  width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
}
.tone.is-active { outline: 2px solid var(--primary); outline-offset: 1px; }

.picker__grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;
  padding: 14px; overflow-y: auto;
  /* без этого grid тянет плитки на высоту строки и ломает соотношение 9:16 */
  align-content: start; align-items: start;
}
.picker__list { display: flex; flex-direction: column; gap: 8px; padding: 14px; overflow-y: auto; }
.picker__empty { grid-column: 1 / -1; padding: 24px 0; text-align: center; color: var(--ink-soft); font-size: 14px; }

/* Высота плитки задаётся процентным padding-ом, а не aspect-ratio.
   Через aspect-ratio grid считал высоту строки ~127 px вместо 250, и ряды
   наезжали друг на друга: высота из пропорции не участвует в расчёте строки.
   Процент же считается от ширины колонки, которая у grid определена всегда.
   177.78% = 16/9. */
.actor-tile {
  position: relative; padding: 0; overflow: hidden;
  height: 0; padding-top: 177.78%;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); cursor: pointer;
}
.actor-tile[hidden] { display: none; }
.actor-tile.is-active { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.actor-tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.actor-tile__badge {
  position: absolute; right: 6px; top: 6px;
  padding: 1px 6px; border-radius: 999px;
  background: rgba(18, 23, 35, .5); backdrop-filter: blur(4px);
  color: #fff; font-size: 8px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px;
}
.actor-tile__foot {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding: 14px 8px 6px;
  background: linear-gradient(to top, rgba(0, 0, 0, .75), transparent);
  color: #fff;
}
.actor-tile__name { font-size: 12px; font-weight: 600; }
.actor-tile__meta { font-size: 10px; opacity: .8; }

.voice-card {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.voice-card[hidden] { display: none; }
.voice-card.is-active { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.voice-card__play {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 30px;
  border-radius: 50%; background: var(--surface-2); color: var(--ink-soft); font-size: 11px;
}
/* языков много — колонка фильтров скроллится, а не растёт бесконечно */
.chips--lang { max-height: 232px; overflow-y: auto; }

.picker__pane {
  position: relative; flex: 1; min-width: 0; min-height: 0;
  display: flex; overflow: hidden;
}
.picker__loading {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
  z-index: 2; padding: 4px 12px; border-radius: 999px;
  background: var(--ink); color: #fff; font-size: 12px;
  opacity: 0; transition: opacity .15s;
}
.picker__loading.htmx-request { opacity: 1; }

button.voice-card__play { border: 0; cursor: pointer; }
button.voice-card__play:hover { background: var(--line); color: var(--ink); }
.voice-card__play.is-muted { opacity: .35; }
.voice-card__body {
  flex: 1; min-width: 0; padding: 0; border: 0;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.voice-card__name { display: block; font-size: 14px; font-weight: 600; }
.voice-card__meta { display: block; font-size: 12px; color: var(--ink-soft); }
.voice-card__age { font-size: 11px; color: var(--ink-soft); white-space: nowrap; }

.picker__foot {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}
.picker__foot span:first-child { flex: 1; font-size: 13px; color: var(--ink-soft); }
.picker__foot--audio { justify-content: space-between; }

/* Audio settings — узкая панель, у референса она приезжает справа */
.sheet--right { justify-content: flex-end; align-items: stretch; }
.sheet__panel--audio {
  display: flex; flex-direction: column; padding: 0;
  width: min(360px, 100%); max-height: 100dvh; border-radius: var(--r-card) 0 0 var(--r-card);
}
.audio__body { flex: 1; overflow-y: auto; padding: 14px; }
.audio__voice {
  margin: 0 0 14px; padding: 8px 10px; border-radius: 10px;
  background: var(--surface-2); font-size: 13px; font-weight: 600;
}
.knob + .knob { margin-top: 18px; }
.knob__head { display: flex; align-items: baseline; justify-content: space-between; }
.knob__label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.knob__value { font-size: 12px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.knob__range { width: 100%; margin: 6px 0 4px; accent-color: var(--ink); }
.knob__hint { margin: 0; font-size: 11px; line-height: 1.4; color: var(--ink-soft); }

.avatar-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.avatar-tile {
  padding: 0; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface-2); cursor: pointer; overflow: hidden; text-align: left;
}
.avatar-tile.is-active { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.avatar-tile img { width: 100%; aspect-ratio: 9 / 16; object-fit: cover; display: block; }
.avatar-tile span { display: block; padding: 6px 8px; font-size: 12px; font-weight: 600; color: var(--ink); }
.avatar-tile em { display: block; font-style: normal; font-weight: 400; font-size: 11px; color: var(--ink-soft); }

.preview { display: grid; gap: 14px; }
.preview > img { width: 100%; border-radius: var(--r-md); }
.preview__script { margin: 0 0 12px; font-size: 15px; }
.preview__meta { margin: 0; font-size: 13px; }
/* Только строки таблицы: без > правило ловило и выпадающее меню внутри строки. */
.preview__meta > div { display: flex; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid var(--line); }
.preview__meta dt { color: var(--ink-soft); }
.preview__meta dd { margin: 0; }

/* ---------- panels, tables, stubs ---------- */
.panel { margin-bottom: 14px; padding: 16px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-md); }
.panel__head { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.panel__form { display: flex; gap: 8px; }
.panel__form input { flex: 1; }

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th { padding: 8px 6px; text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); border-bottom: 1px solid var(--line); }
.table td { padding: 12px 6px; border-bottom: 1px solid var(--line); }
.hide-sm { display: none; }

.kv { margin: 0; font-size: 14px; }
.kv div { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.kv dt { color: var(--ink-soft); }
.kv dd { margin: 0; text-align: right; }

.stub { padding: 64px 16px; text-align: center; }
.stub__mark { font-size: 36px; color: var(--ink-soft); opacity: .4; }
.stub h1 { font-size: 20px; }
.stub__hint { max-width: 440px; margin: 8px auto 20px; color: var(--ink-soft); font-size: 14px; }

/* ---------- auth ---------- */
.auth-page { display: grid; place-items: center; min-height: 100dvh; padding: 20px; background: var(--sidebar-bg); }
.auth { width: 100%; max-width: 400px; padding: 26px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-card); }
.brand--auth { display: block; margin-bottom: 20px; text-decoration: none; }
.auth label { display: block; margin-bottom: 14px; font-size: 13px; color: var(--ink-soft); }
.auth input { margin-top: 6px; }
.auth__switch { margin: 16px 0 0; font-size: 14px; text-align: center; color: var(--ink-soft); }

/* ================= tablet ================= */
@media (min-width: 768px) {
  :root { --sidebar-w: 256px; }
  .main { padding: 18px 20px 120px; }
  .content-head { flex-wrap: nowrap; }
  .search { max-width: 320px; }
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
  .avatar-grid { grid-template-columns: repeat(4, 1fr); }
  .hide-sm { display: table-cell; }
  .panel__head { flex-direction: row; align-items: center; justify-content: space-between; }
  .sheet__actions { flex-direction: row; justify-content: flex-end; }
  .dropzone { flex-basis: 96px; height: 128px; }
}

/* ================= desktop ================= */
@media (min-width: 1024px) {
  :root { --sidebar-w: 286px; }

  .topbar { display: none; }
  .scrim { display: none !important; }

  .sidebar { transform: none; width: var(--sidebar-w); border-right: 0; }
  .sidebar__close { display: none; }
  .sidebar__hide { display: inline-flex; }

  .main { margin-left: var(--sidebar-w); padding: 24px 24px 470px; }

  /* Свёрнут: столбец уезжает за край, а рабочая область забирает его место
     целиком — ради этого всё и затевалось. Композер прижат к левому краю
     тем же правилом: он позиционируется от края экрана, а не от области. */
  .shell.nav-hidden .sidebar { transform: translateX(-102%); }
  .shell.nav-hidden .main { margin-left: 0; }
  .shell.nav-hidden .composer { left: 0; }

  /* Единственный след столбца, когда он свёрнут, — и потому обычная кнопка,
     а не намёк на неё. Стоит в левом верхнем углу, там же, где была шапка
     столбца: туда смотрят, когда ищут пропавшее меню. */
  .shell.nav-hidden .nav-show {
    display: inline-flex; align-items: center; gap: 10px;
    position: fixed; left: 16px; top: 16px; z-index: 45;
    height: 38px; padding: 0 14px;
    border: 1px solid var(--line); border-radius: var(--r-sm);
    background: var(--surface); color: var(--ink);
    font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
    box-shadow: var(--shadow-card);
  }
  .shell.nav-hidden .nav-show:hover { border-color: var(--ink-soft); }
  /* Место под кнопку: без него она легла бы на хлебные крошки страницы. */
  .shell.nav-hidden .main { padding-left: 132px; }

  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .avatar-grid { grid-template-columns: repeat(5, 1fr); }

  /* composer: 1000×~416 centred in the content area, 40px above the bottom edge */
  .composer {
    left: var(--sidebar-w); right: 0; bottom: 40px;
    width: auto; background: transparent; border: 0; box-shadow: none;
    display: flex; justify-content: center; pointer-events: none;
  }
  .composer > * { pointer-events: auto; }
  .composer__handle { display: none; }
  .composer__form {
    display: block; width: min(1000px, calc(100% - 48px)); padding: 10px;
    background: var(--surface-2); border: 1px solid var(--line);
    border-radius: var(--r-card); box-shadow: var(--shadow-card);
  }
  /* reference composer is 1000×416; ours lands ~380 because it has three fewer
     control rows (script writer chip, emotion button, engine radios) */
  .composer textarea { min-height: 200px; }
  .composer .dropzone { flex-basis: 168px; height: 252px; }

  /* Как у референса: окно центрируется по всему экрану, а не по рабочей области.
     Сайдбар оно перекрывает всегда и одинаково, на любом зуме — у них это
     `fixed left-1/2 translate-x-[-50%]`, панель 1280 px по центру 1536 px. */
  .sheet { align-items: center; justify-content: center; padding: 24px; }
  .sheet__panel { max-width: 760px; max-height: 84dvh; border-radius: var(--r-card); }
  .sheet__panel--wide { max-width: 980px; }
  /* панель звука приезжает справа во всю высоту — как у референса */
  .sheet--right { align-items: stretch; justify-content: flex-end; padding: 0; }
  .sheet--right .sheet__panel { max-height: 100dvh; }
  .preview { grid-template-columns: 320px 1fr; align-items: start; }

  /* on desktop the filters move into a left column, like the reference.
     Габариты сняты с их окна Add Actors при ширине 1536: 1280×664, радиус 16. */
  .sheet__panel--picker { max-width: 1280px; max-height: 90dvh; border-radius: 16px; }
  .picker__body { flex-direction: row; }
  .picker__filters-btn { display: none; }
  .picker__filters {
    display: flex;
    flex: 0 0 210px; flex-direction: column; gap: 18px; overflow-y: auto;
    padding: 16px; border-right: 1px solid var(--line); border-bottom: 0;
  }
  .picker__filters .btn--block { display: inline-flex; margin-top: auto; }
  .picker__grid { grid-template-columns: repeat(5, minmax(0, 1fr)); flex: 1; }
  .picker__list { flex: 1; }
}

@media (min-width: 1280px) {
  :root { --sidebar-w: 320px; }
  .main { padding-left: 32px; padding-right: 32px; }
  .grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* Настройки ролика — ряд компактных полей, как у референса: подпись сверху,
   значение снизу, клик раскрывает список. Крупные карточки с описаниями здесь
   не нужны: параметр выбирают часто, и он должен читаться одним взглядом. */
.setrow { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; }

.setfield { position: relative; }
.setfield__btn,
.setfield--static {
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  min-height: 44px; padding: 5px 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); cursor: pointer; list-style: none;
}
.setfield--static { cursor: default; background: transparent; }
.setfield__btn::-webkit-details-marker { display: none; }
.setfield__btn:hover { border-color: var(--line-input); }
.setfield__label {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); line-height: 1.2;
}
.setfield__value { font-size: 14px; font-weight: 600; line-height: 1.25; }

/* Список вариантов раскрывается вверх: композер прижат к низу экрана */
.setmenu {
  position: absolute; bottom: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 148px; padding: 6px;
  display: grid; gap: 2px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); box-shadow: var(--shadow-card);
}
.setopt {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 8px 10px; border: 0; border-radius: var(--r-xs);
  background: transparent; color: var(--ink); cursor: pointer; text-align: left;
}
.setopt:hover { background: var(--surface-2); }
.setopt.is-on { background: var(--primary); color: var(--primary-ink); }
.setopt b { font-size: 14px; font-weight: 600; }
/* Цена справа — приглушённая: выбирают секунды, а цена лишь подсказка */
.setopt span { font-size: 12px; color: var(--ink-soft); }
.setopt.is-on span { color: rgba(255, 255, 255, .7); }

/* ---------- storyboard (video editor) ---------- */
/* Две колонки: слева планы по порядку, справа музыка и результат.
   Порядок планов = порядок в ролике, поэтому строка — это план целиком. */
.sb { display: grid; gap: 20px; align-items: start; }
.sb__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
.sb__head h2 { font-size: 18px; }
.sb__empty {
  margin: 0 0 16px; padding: 18px; border: 1px dashed var(--line-input);
  border-radius: var(--r-sm); color: var(--ink-soft); font-size: 14px;
}

.sb__shot {
  display: grid; grid-template-columns: 26px 64px 1fr auto; gap: 12px;
  align-items: center; padding: 10px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); margin-bottom: 8px;
}
.sb__num { font-size: 13px; font-weight: 600; color: var(--ink-soft); text-align: center; }
.sb__thumb { position: relative; width: 64px; height: 114px; border-radius: 8px; overflow: hidden; background: #000; }
.sb__thumb img, .sb__thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.sb__badge {
  position: absolute; left: 4px; bottom: 4px; padding: 1px 5px; border-radius: 5px;
  background: rgba(0, 0, 0, .65); color: #fff; font-size: 10px; letter-spacing: .02em;
}

.sb__fields { display: flex; flex-wrap: wrap; gap: 8px 12px; }
.sb__field { display: grid; gap: 3px; font-size: 11px; color: var(--ink-soft); }
.sb__field--wide { flex: 1 1 220px; }
.sb__field select, .sb__field input[type="text"] {
  height: 32px; padding: 4px 8px; font: inherit; font-size: 13px; color: var(--ink);
  background: var(--bg); border: 1px solid var(--line-input); border-radius: var(--r-xs);
}
.sb__field select:disabled { opacity: .5; }
.sb__field input[type="range"] { width: 100%; accent-color: var(--ink); }

.sb__ops { display: flex; gap: 2px; }

.sb__add { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start; margin-top: 14px; }
.sb__add label.btn { cursor: pointer; }
.sb__pick { position: relative; }
.sb__pick summary { list-style: none; cursor: pointer; }
.sb__pick summary::-webkit-details-marker { display: none; }
.sb__picklist {
  position: absolute; z-index: 40; margin-top: 6px; padding: 8px;
  display: grid; grid-template-columns: repeat(4, 60px); gap: 8px;
  max-height: 320px; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: var(--shadow-card);
}
.sb__pickitem {
  position: relative; padding: 0; width: 60px; height: 107px;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: #000; cursor: pointer;
}
.sb__pickitem video { width: 100%; height: 100%; object-fit: cover; display: block; }
.sb__pickitem span {
  position: absolute; right: 3px; bottom: 3px; padding: 0 4px; border-radius: 4px;
  background: rgba(0, 0, 0, .7); color: #fff; font-size: 10px;
}

.sb__side { display: grid; gap: 16px; }
.sb__box {
  padding: 16px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.sb__box h3 { font-size: 14px; margin-bottom: 10px; }
.sb__box .btn { margin-bottom: 8px; }
.sb__file { font-size: 12px; margin-bottom: 8px; }
.sb__hint { margin: 6px 0 0; font-size: 11px; line-height: 1.4; color: var(--ink-soft); }
.sb__state { font-size: 13px; margin-bottom: 10px; }
.sb__state--bad { color: #b42318; }
.sb__out { width: 100%; border-radius: 10px; background: #000; margin-bottom: 10px; display: block; }

@media (min-width: 1024px) {
  .sb { grid-template-columns: minmax(0, 1fr) 280px; }
}

/* ---------- монтажный стол ---------- */
/* Экран монтажа занимает окно целиком и не прокручивается: холст и таймлайн
   должны быть видны одновременно. Прокрутка живёт внутри — в правой колонке
   и в ленте клипов. Так же устроен редактор у референса. */
.main--editor {
  height: 100dvh; overflow: hidden;
  display: flex; flex-direction: column; padding-bottom: 12px;
}
.main--editor .content-head--tight { margin-bottom: 8px; flex: 0 0 auto; }
.main--editor .alert { flex: 0 0 auto; }

.ed {
  flex: 1 1 auto; min-height: 0;
  display: grid; gap: 16px;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
}
/* Сцена: холст тянется, панель и лента занимают своё */
.ed__stage {
  min-height: 0; display: grid;
  grid-template-rows: minmax(0, 1fr) auto auto;
}
/* Место под холст: занимает всю свободную высоту, кадр центрируется в нём.
   Размер самого кадра считает редактор — CSS не умеет вписывать коробку
   с заданной пропорцией сразу по двум ограничениям. */
.ed__canvasbox {
  min-height: 0; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border-radius: var(--r-sm); overflow: hidden;
}
.ed__canvas {
  position: relative; background: #0b0d12;
  border-radius: var(--r-xs); overflow: hidden;
}
.ed__bar { display: flex; align-items: center; gap: 8px; padding: 10px 0; flex-wrap: wrap; }
.ed__time { font-size: 13px; font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.ed__zoom { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.ed__tl { min-width: 0; }
.ed__side { min-height: 0; overflow-y: auto; display: grid; gap: 12px; align-content: start; }

.tl { user-select: none; }
/* Линейка и лента прокручиваются вместе — обе шириной с ролик */
.tl__ruler {
  position: relative; height: 18px; margin-bottom: 4px; overflow: hidden;
  border-bottom: 1px solid var(--line); cursor: pointer;
}
.tl__inner { position: relative; height: 100%; }
.tl__tick {
  position: absolute; top: 0; font-size: 10px; color: var(--ink-soft);
  padding-left: 3px; border-left: 1px solid var(--line); white-space: nowrap;
}
.tl__strip {
  position: relative; height: 62px; overflow-x: auto; overflow-y: hidden;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-xs); cursor: pointer;
}
.tl__clip {
  position: absolute; top: 4px; bottom: 4px;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 4px 6px; overflow: hidden; cursor: grab;
  background: var(--bg); border: 1px solid var(--line-input); border-radius: 6px;
}
.tl__clip.is-on { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink) inset; }
.tl__clip.is-drag { opacity: .4; }
.tl__name { font-size: 11px; font-weight: 600; white-space: nowrap; }
.tl__len { font-size: 10px; color: var(--ink-soft); }
/* Плейхед поверх клипов и мимо мыши: иначе он перехватывает перетаскивание */
.tl__head {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: #ff4d19; pointer-events: none;
}

/* ── редактор на телефоне ────────────────────────────────────────────
   Сетка редактора рассчитана на монитор: тянущаяся строка со сценой
   и своя строка с настройками. На узком экране высоты не хватает, и
   тянущаяся строка схлопывается в ноль — панель инструментов, лента
   и холст вываливаются из неё и ложатся поверх настроек. Обычный поток
   сверху вниз: сцена своей высоты, настройки под ней, страница
   прокручивается. */
@media (max-width: 1023px) {
  .ed { display: block; }
  .ed__stage { display: block; }
  /* Холст меряет себя сам по месту, которое ему дали; в потоке места
     нет, поэтому задаём его явно. */
  .ed__canvasbox { min-height: 46dvh; }
  .ed__side { overflow-y: visible; margin-top: 16px; }
  .ed__bar { row-gap: 8px; }
}

@media (min-width: 1024px) {
  .ed { grid-template-columns: minmax(0, 1fr) 280px; grid-template-rows: minmax(0, 1fr); }
  .ed__side { grid-row: 1; grid-column: 2; }
}

/* Ручка надписи поверх плеера. Кружок намеренно мелкий: он не должен
   загораживать текст, который им же и двигают. */
.ed__canvas { position: relative; }
.ed__grab {
  position: absolute; width: 18px; height: 18px; margin: -9px 0 0 -9px;
  border-radius: 50%; background: #ff4d19; border: 2px solid #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .5); cursor: grab; z-index: 5;
}
.ed__grab:active { cursor: grabbing; }

/* Список стилей субтитров: каждый показан образцом, а не только названием —
   по имени «Shout Block» догадаться о виде невозможно. */
.stylelist {
  display: grid; gap: 4px; max-height: 230px; overflow-y: auto;
  padding: 4px; border: 1px solid var(--line); border-radius: var(--r-xs);
  background: var(--bg);
}
.stylecard {
  display: grid; gap: 2px; padding: 7px 8px; text-align: left; cursor: pointer;
  border: 1px solid transparent; border-radius: 8px; background: transparent;
}
.stylecard:hover { background: var(--surface-2); }
.stylecard.is-on { border-color: var(--ink); background: var(--surface-2); }
/* Образец рисуется на тёмном: половина стилей — белый текст, на светлом фоне
   их попросту не видно. */
.stylecard__demo {
  display: block; padding: 7px 8px; border-radius: 6px;
  background: #23252d; overflow: hidden; white-space: nowrap;
}
.stylecard__off { color: #75757f; font-size: 15px; }
.stylecard__name { font-size: 11px; color: var(--ink-soft); }

/* Ручка текста крупнее и с рамкой: её надо заметить, не наводя мышь */
.ed__grab {
  width: 22px; height: 22px; margin: -11px 0 0 -11px;
}

/* Переключатель субтитров: галочка рядом с текстом, а не отдельным полем —
   он относится к подписи и должен читаться вместе с ней. */
.sb__check {
  display: flex; align-items: flex-start; gap: 7px;
  margin-top: 8px; font-size: 12px; line-height: 1.35; cursor: pointer;
}
.sb__check input { margin: 1px 0 0; accent-color: var(--ink); }

/* Атрибут hidden не работает против display из класса — возвращаем ему силу.
   Из-за этого поле Zoom оставалось на экране при запертой камере. */
.sb__field[hidden] { display: none; }

/* Поле для вставки реплики: нужно несколько строк, в однострочный input
   фраза целиком не помещается и её не видно. */
.sb__area {
  width: 100%; margin-top: 8px; padding: 7px 9px; resize: vertical;
  font: inherit; font-size: 13px; color: var(--ink);
  background: var(--bg); border: 1px solid var(--line-input); border-radius: var(--r-xs);
}

/* Отбивка между смысловыми группами внутри одного раздела */
.sb__field--gap { margin-top: 14px; }

/* Отказ провайдера — строкой в панели, а не системным alert: его нельзя
   скопировать, он перекрывает экран и не даёт дочитать длинное сообщение. */
.ed__problem {
  flex: 1 1 100%; font-size: 12px; line-height: 1.4; color: #b42318;
}

/* Пункт выбора модели шире обычного: в нём название и цена за длительность
   по умолчанию, а не одно число. */
.setmenu--wide { min-width: 240px; }
.setopt--model { gap: 18px; }

/* ---------- цена и счётчик вплотную к кнопке отправки ----------
   Обе цифры нужны ровно в тот момент, когда рука тянется к ↑, поэтому
   стоят строкой прямо над рядом с кнопкой, а не над настройками. */
.composer__meter {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 8px 4px 0; font-size: 12.5px; color: var(--ink-soft);
}
.composer__credits b { color: var(--ink); font-variant-numeric: tabular-nums; }
.composer__meter .composer__counter { margin: 0; }

/* ---------- окно генерации ----------
   Одно окно на всю жизнь ролика: ожидание, выбор кадра, результат. */
.genstage {
  width: 100%; display: block; border-radius: var(--r-md);
  background: var(--surface-2);
}
.genstage.is-dim { opacity: .45; }
.genstage--blank { height: 44dvh; }
/* Кадр режем по высоте, а не по ширине: вертикальный снимок при 320 px
   ширины вырастает почти на 570, и три варианта под ним оказывались
   за сгибом — то есть главное действие окна пряталось от глаз. */
img.genstage, video.genstage { width: auto; max-width: 100%; max-height: 40dvh; margin: 0 auto; }

/* Кнопки прилипают ко дну окна: «Render video» — то, ради чего окно открыли,
   и оно не должно уезжать под сгиб вместе с содержимым. */
.sheet__panel--wide .sheet__actions {
  position: sticky; bottom: calc(-16px - env(safe-area-inset-bottom));
  margin-top: 8px; padding: 12px 0 calc(16px + env(safe-area-inset-bottom));
  background: var(--bg);
}

.genprog {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 12px; font-size: 14px; font-weight: 600;
}

.gensteps { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 6px; }
.gensteps__one {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-soft);
}
.gensteps__one.is-done { color: var(--ink); }
.gensteps__one.is-now { color: var(--ink); font-weight: 600; }
.gensteps__mark { width: 14px; text-align: center; font-size: 11px; }
.gensteps__one.is-done .gensteps__mark { color: var(--primary); }

/* Плеер озвучки появляется сам, как только она записана: отдельной кнопки
   «послушать» нет — плеер и есть кнопка. */
.genaudio {
  display: grid; gap: 6px; margin-bottom: 14px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.genaudio__label {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft);
}
.genaudio audio { width: 100%; height: 34px; }

/* Место съёмки внутри строки таблицы: список раскрывается вниз — окно
   стоит по центру экрана, а не прижато к его низу, как композер. */
.locpick { position: relative; }
.locpick summary { list-style: none; cursor: pointer; font-weight: 600; }
.locpick summary::-webkit-details-marker { display: none; }
.locpick .setmenu { top: calc(100% + 6px); bottom: auto; right: 0; left: auto; max-height: 44dvh; overflow-y: auto; }

/* ---------- пометки подачи подсвечены прямо в тексте ----------
   Подложка обязана совпасть с полем символ в символ: тот же шрифт, те же
   отступы, тот же перенос. Разойдись они хоть на пиксель — подсветка поедет
   относительно букв. Поэтому общие свойства заданы одним правилом на оба. */
.tagbox { position: relative; display: flex; }

/* Полоса «идёт работа» поверх пустого поля сценария. Крутилка у продукта
   белая — она живёт на тёмных кнопках; здесь фон светлый, и нужна своя. */
.spinner--ink {
  width: 15px; height: 15px; border-width: 2px;
  border-color: var(--line-input); border-top-color: var(--ink-soft);
}
.tagbox__busy {
  position: absolute; inset: 0; z-index: 1;
  display: flex; align-items: center; gap: 9px;
  padding: 6px 4px;
  background: var(--bg);
  font-size: 14px; color: var(--ink-soft);
}
.tagbox__busy[hidden] { display: none; }
.tagbox__back,
.tagbox textarea {
  padding: 6px 4px; border: 0; margin: 0;
  font: inherit; font-size: 14px; line-height: 1.45;
  letter-spacing: normal;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.tagbox__back {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; color: transparent; pointer-events: none;
}
.tagbox textarea {
  position: relative; z-index: 1; flex: 1; min-width: 0;
  background: transparent; resize: vertical;
}
/* Пометку, которая будет вырезана, показываем зачёркнутой: видно, что она
   не сработает, и при этом это не выглядит ошибкой ввода. */
.tagbox__back mark.is-pause {
  background: var(--tag-drop);
  /* Линия по центру строки — подложка прозрачна по тексту, поэтому рисуем
     её фоном, а не text-decoration: зачёркивать нечего, буквы невидимы. */
  background-image: linear-gradient(transparent 46%, var(--ink-soft) 46%,
                                    var(--ink-soft) 54%, transparent 54%);
}
.pausewarn { font-size: 11.5px; line-height: 1.35; color: var(--ink-soft); }

.tagbox__back mark {
  /* Цвет собственный, а не системный: у mark по умолчанию жёлтый фон
     и чёрный текст — текст здесь обязан остаться невидимым. */
  background: var(--tag-bg); color: transparent; border-radius: 4px;
}

/* ---------- модель ----------
   Отдельным рядом над ценой: сначала выбираешь, чем снимать, потом видишь,
   во что это обошлось. */
.composer__engine {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 10px 4px 0; cursor: help;
}
.composer__engine-label {
  margin-right: 4px; font-size: 12.5px; color: var(--ink-soft);
}
.engine {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 6px; border-radius: 999px;
  font-size: 13px; color: var(--ink-soft); cursor: pointer;
}
.engine input { margin: 0; accent-color: var(--primary); }
.engine.is-on { background: var(--surface-2); color: var(--ink); font-weight: 600; }

/* Меню формы кадра раскрывается вверх и вправо: пилюля стоит у правого края
   ряда, и списку слева не хватало места. */
/* Раскрывается вверх и от левого края своей кнопки — тем же движением,
   что и список режимов рядом. */
.modepick__menu--shape { left: 0; right: auto; width: 220px; }

/* ---------- ручки звука в подвале пикера голоса ----------
   Одной строкой над кнопками: настраивают выбранный голос, значит должны
   быть видны там же, где его выбирают, и без прокрутки. */
.tune {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  padding: 10px 14px; border-top: 1px solid var(--line);
  background: var(--surface-2);
}
.tune__title {
  font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-label);
}
.tune__knob { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.tune__label { font-size: 12px; color: var(--ink-soft); }
.tune__knob .knob__range { width: 96px; margin: 0; }
.tune__value {
  min-width: 22px; font-size: 12px; color: var(--ink);
  font-variant-numeric: tabular-nums; text-align: right;
}
.tune__note { flex: 1 1 100%; font-size: 11.5px; color: var(--ink-soft); }
.tune .btn { margin-left: auto; }

@media (min-width: 1024px) {
  .tune__note { flex: 1 1 auto; }
}

/* ---------- ожидание на самой картинке ----------
   Кадр рисуется до минуты, ролик — дольше. Всё это время экран обязан
   объяснять, что происходит: молчащая картинка читается как зависшая. */
.stage { position: relative; display: flex; justify-content: center; }
.stage__load {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 20px; border-radius: var(--r-md);
  background: rgba(10, 16, 34, .55); color: #fff; text-align: center;
  backdrop-filter: blur(2px);
}
.stage__load b { font-size: 15px; }
.stage__hint { max-width: 240px; font-size: 12px; line-height: 1.4; opacity: .8; }
.spinner--lg { width: 34px; height: 34px; border-width: 3px; }

/* Полоса без процентов: сколько осталось, поставщик не сообщает, а рисовать
   выдуманный прогресс — врать. Движение здесь означает «работа идёт». */
.stage__bar {
  width: min(200px, 70%); height: 3px; border-radius: 999px;
  background: rgba(255, 255, 255, .25); overflow: hidden;
}
.stage__bar i {
  display: block; width: 40%; height: 100%; border-radius: inherit;
  background: #fff; animation: stage-slide 1.6s ease-in-out infinite;
}
@keyframes stage-slide {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(360%); }
}
@media (prefers-reduced-motion: reduce) {
  .stage__bar i { animation-duration: 4s; }
}

/* ---------- обещание под кнопкой ----------
   Первое нажатие пугает: непонятно, спишут ли всё сразу и вернут ли за брак.
   Отвечаем цифрами — одной строкой, числа впереди. Подробности за ⓘ:
   спрятанное обещание не успокаивает, а спрятанная подробность не мешает. */
.composer__safe {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0 5px;
  margin: 4px 4px 0; font-size: 12.5px; line-height: 1.4; color: var(--ink-soft);
}
.composer__safe b { color: var(--ink); font-variant-numeric: tabular-nums; }
.composer__safe-dot { color: var(--line-input); }

/* ---------- ⓘ ----------
   Кнопка, а не span: нужен фокус с клавиатуры, и на тач-экране тап по кнопке
   даёт тот же фокус — иначе подсказка была бы доступна только мышью. */
.info { position: relative; display: inline-flex; vertical-align: middle; }
.info__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; padding: 0;
  border: 1px solid var(--line-input); border-radius: 50%;
  background: transparent; color: var(--ink-soft);
  font: inherit; font-size: 10px; font-style: italic; font-weight: 700;
  line-height: 1; cursor: help;
}
.info__btn:hover { border-color: var(--ink-soft); color: var(--ink); }
.info__bubble {
  position: absolute; bottom: calc(100% + 8px); left: 50%; z-index: 80;
  width: max-content; max-width: 260px; padding: 8px 10px;
  transform: translateX(-50%);
  border-radius: var(--r-sm);
  background: var(--primary); color: var(--primary-ink);
  font-size: 12px; line-height: 1.4; font-weight: 400; text-align: left;
  box-shadow: var(--shadow-card);
  opacity: 0; visibility: hidden; transition: opacity .12s ease;
}
/* Хвостик, чтобы пузырь читался как принадлежащий кнопке. */
.info__bubble::after {
  content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px;
  border: 5px solid transparent; border-top-color: var(--primary);
}
.info:hover .info__bubble,
.info__btn:focus + .info__bubble { opacity: 1; visibility: visible; }
/* У правого края окна пузырь упирался в границу — прижимаем к кнопке. */
.preview__meta .info__bubble { left: 0; transform: none; }
.preview__meta .info__bubble::after { left: 12px; }

/* ---------- готовый ролик во весь экран ----------
   В колонке 320 px результат не разглядеть, а выбирать там уже нечего:
   плёнка занимает окно, подробности уходят под неё. */
@media (min-width: 1024px) {
  .preview--result { grid-template-columns: minmax(0, 1fr); }
}
/* Плёнка узкой колонкой слева, подробности справа — размеры сняты с окна
   результата у референса: панель 900×539, видео 256×455 в колонке 280. */
.preview--result video.genstage,
.preview--result img.genstage {
  /* max-height здесь обязателен: общее правило кадра режет высоту до 40dvh. */
  width: 100%; height: auto; max-height: none;
  aspect-ratio: var(--shape, 9 / 16);
  border-radius: 12px;
}
@media (min-width: 1024px) {
  .preview--result { grid-template-columns: 280px minmax(0, 1fr); gap: 24px; }
}

/* Длительность поверх кадра и крупная ▶ по центру — тоже с референса. */
/* У референса это просто белые цифры поверх кадра — и они пропадают, когда
   первый кадр светлый. Кладём их на тёмную подложку: читается на любом. */
.stage__time {
  position: absolute; top: 10px; left: 10px; z-index: 2;
  padding: 2px 7px; border-radius: 999px;
  background: rgba(10, 16, 34, .55); color: #fff;
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.stage__play {
  position: absolute; top: 50%; left: 50%; z-index: 2;
  transform: translate(-50%, -50%);
  width: 48px; height: 48px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .82); color: var(--ink);
  font-size: 15px; cursor: pointer;
  box-shadow: 0 2px 12px rgba(10, 16, 34, .25);
}
.stage__play:hover { background: #fff; }

/* Сценарий отдельным блоком с копированием */
.scriptbox { margin-bottom: 14px; }
.scriptbox__head {
  display: flex; align-items: center; gap: 6px; margin-bottom: 5px;
  font-size: 10px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-label);
}
.scriptbox__copy {
  padding: 2px 4px; border: 0; border-radius: var(--r-xs);
  background: transparent; color: var(--ink-soft); font: inherit; font-size: 12px;
  cursor: pointer; line-height: 1;
}
.scriptbox__copy:hover { background: var(--surface-2); color: var(--ink); }
.scriptbox__text {
  margin: 0; padding: 9px 11px;
  border-radius: var(--r-sm); background: var(--surface-2);
  font-size: 14px; line-height: 1.45;
}

/* ---------- пополнение кредитов ----------
   Три пакета в ряд, как у референса. Цена крупно, под ней — что внутри
   и сколько это примерно роликов: «5000 кредитов» само по себе ничего
   не значит человеку, который ещё не считал. */
.sheet__panel--credits { max-width: 760px; }
.credits__sub { margin: 0 0 18px; font-size: 13.5px; }
.credits__sub b { color: var(--ink); }
.credits__foot {
  margin: 16px 0 0; font-size: 11.5px; color: var(--ink-soft); text-align: center;
}
.credits__pending { margin: 0 0 8px; font-size: 15px; line-height: 1.5; }

.packs { display: grid; gap: 12px; }
@media (min-width: 768px) {
  .packs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.pack {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface);
}
.pack--pick { border-color: var(--primary); }
.pack__note {
  align-self: flex-start; padding: 2px 8px; border-radius: 999px;
  background: var(--primary); color: var(--primary-ink);
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.pack__price { font-size: 30px; font-weight: 700; letter-spacing: -.02em; line-height: 1; }
.pack__price span {
  margin-left: 6px; font-size: 11px; font-weight: 500; letter-spacing: 0;
  color: var(--ink-soft); text-transform: uppercase;
}
.pack__what { font-size: 13.5px; color: var(--ink-soft); }
.pack__what b { color: var(--ink); font-variant-numeric: tabular-nums; }
.pack__what span { display: block; margin-top: 2px; font-size: 12px; }
.pack .btn { margin-top: auto; }

/* Портрет актёра прямо в строке — как у референса */
.dd--face { display: inline-flex; align-items: center; gap: 8px; }
.dd--face img { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }

/* Подписи строк — заглавными микро-буквами, как у референса: 10px/600,
   разрядка .6px, цвет --ink-label. Значение при этом остаётся обычным
   текстом, и колонка цифр читается сама. */
.preview__meta dt {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-label);
}
.preview__meta > div { border-bottom-width: .8px; }
.preview__meta dd { font-size: 13.5px; }

/* Круглая кнопка закрытия — тоже с референса: 36×36 на светлой заливке */
.icon-btn--round {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--surface-2); color: var(--ink-soft); font-size: 13px;
}
.icon-btn--round:hover { background: var(--line); color: var(--ink); }

/* Ручки голоса в окне генерации */
.voicefix { margin-bottom: 14px; }
.voicefix summary {
  cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
  list-style: none;
}
.voicefix summary::-webkit-details-marker { display: none; }
.voicefix summary::before { content: "▸ "; }
.voicefix[open] summary::before { content: "▾ "; }
.voicefix summary:hover { color: var(--ink); }
.tune--modal {
  margin-top: 8px; border: 1px solid var(--line); border-top: 1px solid var(--line);
  border-radius: var(--r-sm);
}

/* ---------- «Сцена»: два кадра рядом ----------
   Первый обязателен, второй ограничивает движение — он задаёт, чем план
   заканчивается. Обе зоны одного размера: они равноправны по смыслу,
   разница только в звёздочке. */
/* Пара кадров занимает то же место, что одна зона товара в соседнем режиме:
   иначе она схлопывалась в две полоски по краю поля ввода. */
.framepair { display: flex; gap: 8px; flex: 0 0 auto; }
.dropzone--half { flex: 0 0 92px; min-width: 0; position: relative; padding-top: 20px; }
.dropzone__cap {
  position: absolute; top: 6px; left: 0; right: 0; z-index: 1;
  font-size: 9px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--ink-soft); text-align: center;
  white-space: nowrap;
}
.dropzone__cap b { color: #b3261e; }

/* Меню длительности — колонкой цифр, а не карточками: значений много,
   и читать их надо одним взглядом. */
.lenmenu { width: 150px; max-height: 260px; overflow-y: auto; }

/* ---------- перенос движения ----------
   Поля нет: что происходит в кадре, задаёт эталонный ролик. Вместо него —
   что получится и во что обойдётся, потому что цену тут считает не настройка,
   а сам файл. */
/* ---------- способ переноса движения ----------
   Два варианта стоят одинаково и отличаются только тем, откуда берётся
   комната. Пилюлями это не показать: разница объясняется фразой, а не
   словом, — поэтому карточки с подписью под названием. */
.swapmode { display: grid; gap: 8px; margin: 0 0 10px; }
.swapmode__opt {
  display: block; padding: 10px 12px; border-radius: 12px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface);
}
.swapmode__opt.is-on { border-color: var(--primary); background: var(--surface-2); }
.swapmode__head { display: flex; align-items: center; gap: 8px; }
.swapmode__head input { margin: 0; accent-color: var(--primary); }
.swapmode__name { font-size: 14px; font-weight: 600; color: var(--ink); }
.swapmode__hint {
  display: block; margin-top: 4px; padding-left: 22px;
  font-size: 12.5px; line-height: 1.4; color: var(--ink-soft);
}

.swapnote { margin: 0 0 8px; font-size: 14px; line-height: 1.45; }
.swapnote--fact {
  margin: 0; font-size: 12.5px; line-height: 1.4; color: var(--ink-soft);
}
.dropzone video { width: 100%; height: 100%; object-fit: cover; }

/* ─────────── Ролик по ссылке ─────────── */

/* Первый экран: одно поле и одна кнопка. Всё, что человек решает здесь, —
   какой товар рекламируем. */
.link-hero { max-width: 620px; margin: 40px auto 28px; text-align: center; }
.link-hero__head { margin: 0 0 8px; font-size: 28px; letter-spacing: -.02em; }
.link-hero__sub { margin: 0 0 22px; color: var(--ink-soft); }
.link-form { display: flex; gap: 8px; }
.link-form__url { flex: 1; }
.link-hero__note { margin: 14px 0 0; font-size: 13px; color: var(--ink-soft); }

.link-recent { max-width: 620px; margin: 0 auto; }
.link-recent__head { margin: 0 0 10px; font-size: 13px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); }
.link-recent__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.link-recent__list a { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r-md); text-decoration: none;
  color: inherit; }
.link-recent__list a:hover { border-color: var(--primary); }
.link-recent__title { font-weight: 600; }
.link-recent__url { font-size: 12px; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.link__head { margin: 0 0 14px; font-size: 15px; }
.link__field { display: block; margin-bottom: 14px; }
.link__field--inline { display: flex; align-items: center; gap: 8px; margin: 0; }
.link__label { display: block; margin-bottom: 5px; font-size: 12px;
  text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); }
.link__hint { margin: 6px 0 0; font-size: 12.5px; }

.link-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 14px; }
.link-points { margin: 0; padding-left: 18px; font-size: 14px; }
.link-points li { margin-bottom: 3px; }

/* Материал со страницы. Сетка плиток с галочками: человек снимает то, что
   не годится в кадр, а не описывает это словами. */
.link-media { margin: 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; }
.link-media__item label { position: relative; display: block; cursor: pointer; }
/* `contain`, а не `cover`. Выбирая картинку, человек должен видеть её
   целиком: обрезка по 3:4 показывала середину широкого кадра, и понять,
   что на нём, было нельзя — на это и пожаловались. Кадрирование под ролик
   произойдёт потом, и там оно уместно. */
.link-media__item img, .link-media__item video {
  width: 100%; aspect-ratio: 3 / 4; object-fit: contain;
  background: var(--surface-2, rgba(127,127,127,.08));
  border-radius: var(--r-sm); border: 2px solid transparent; display: block; }
.link-media__item input { position: absolute; top: 6px; left: 6px; z-index: 1; }
.link-media__item input:not(:checked) ~ img,
.link-media__item input:not(:checked) ~ video { opacity: .3; }
.link-media__item input:checked ~ img,
.link-media__item input:checked ~ video { border-color: var(--primary); }
.link-media__tag { position: absolute; right: 6px; bottom: 6px; padding: 1px 6px;
  border-radius: 4px; background: rgba(0,0,0,.65); color: #fff;
  font-size: 10px; text-transform: uppercase; letter-spacing: .05em; }

/* Сценарии: четыре угла рядом, каждый — своя форма. */
.link-lede { margin: 0 0 14px; color: var(--ink-soft); }
.link-scripts { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px; align-items: start; }
.link-script__head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 12px; }
.link-script__head h2 { margin: 0; font-size: 15px; }
.link-script__len { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }

/* ─────────────── выбор сценария ───────────────
   Карточки во всю ширину и одна под другой, как у Creatify. Три колонки по
   триста пикселей не годились: в каждой стояли пять полей с полосами
   прокрутки, актёр, голос и кнопка — это читалось как форма, а не как текст,
   который человеку надо прочесть и выбрать. */
.pick__head { margin: 0 0 4px; font-size: 22px; }
.pick__lede { margin: 0 0 16px; color: var(--ink-soft); max-width: 70ch; }

.picks { display: grid; gap: 12px; }
.pick { display: block; cursor: pointer; padding: 16px 18px;
  border: 2px solid var(--line); border-radius: var(--r-md, 12px);
  background: var(--surface); }
.pick:hover { border-color: var(--ink-soft); }
.pick.is-on { border-color: var(--primary); }
.pick__radio { position: absolute; opacity: 0; pointer-events: none; }

.pick__top { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.pick__mark { flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line); position: relative; }
.pick.is-on .pick__mark { border-color: var(--primary); background: var(--primary); }
.pick.is-on .pick__mark::after { content: ""; position: absolute;
  left: 4px; top: 1px; width: 4px; height: 8px; border: solid #fff;
  border-width: 0 2px 2px 0; transform: rotate(45deg); }
.pick__name { font-weight: 600; font-size: 15px; }
.pick__len { color: var(--ink-soft); font-size: 12.5px; white-space: nowrap; }
.pick__tone { margin-left: auto; flex: none; width: auto; min-width: 170px; }

.pick__text { width: 100%; font-size: 14.5px; line-height: 1.5; resize: vertical;
  border-color: transparent; background: var(--surface-2, rgba(127,127,127,.06)); }
.pick.is-on .pick__text { background: var(--surface); border-color: var(--line); }
.pick__hint { margin-top: 10px; }

.pick__more { margin: 16px 0 0; text-align: center; }

/* Актёр, голос и кнопка — один раз внизу, а не в каждой карточке. */
.pick__bar[hidden] { display: none; }
.pick__bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.pick__field { display: block; flex: 1 1 220px; min-width: 0; }
.pick__field select { width: 100%; }
.pick__back { flex: none; }
.pick__go { flex: none; margin-left: auto; }
.pick__note { margin: 10px 0 0; max-width: 70ch; }

/* Выбор актёра. Сетка лиц, а не выпадающий список имён: решение о том, кто
   говорит, — решение о лице ролика, и его надо видеть. */
.cast__tools { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.cast__search { flex: 1 1 320px; max-width: 420px; }
.cast__tools .link__hint { margin: 0; }

.cast { margin: 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.cast__item[hidden] { display: none; }
.cast__item label { display: block; cursor: pointer; }
.cast__radio { position: absolute; opacity: 0; pointer-events: none; }

.cast__item img, .cast__none {
  display: block; width: 100%; aspect-ratio: 9 / 16; object-fit: cover;
  border-radius: var(--r-sm); border: 2px solid transparent; background: #000; }
.cast__item.is-on img, .cast__item.is-on .cast__none {
  border-color: var(--primary); }
.cast__item:hover img { border-color: var(--ink-soft); }

/* «Без актёра» — такая же плитка: выбор из плиток нельзя предлагать
   наполовину списком, наполовину галочкой. */
.cast__none { display: grid; place-content: center; gap: 8px; justify-items: center;
  background: var(--surface-2, rgba(127,127,127,.08)); color: var(--ink-soft);
  font-size: 13px; }
.cast__none-mark { font-size: 26px; line-height: 1; }

/* Отметка выбранного. Одной рамки мало: она тонкая, и на экране из двадцати
   плиток непонятно, сработал ли щелчок вообще. */
.cast__item label { position: relative; }
.cast__tick { position: absolute; left: 8px; top: 8px; width: 22px; height: 22px;
  border-radius: 50%; border: 2px solid rgba(255,255,255,.85);
  background: rgba(0,0,0,.35); }
.cast__item.is-on .cast__tick { background: var(--primary); border-color: var(--primary); }
.cast__item.is-on .cast__tick::after { content: ""; position: absolute;
  left: 6px; top: 2px; width: 5px; height: 10px; border: solid #fff;
  border-width: 0 2px 2px 0; transform: rotate(45deg); }

/* Выбранная плитка. Зелёный, а не цвет темы: в интерфейсе им больше ничего
   не закрашено, поэтому зелёная рамка не может быть принята за оформление
   или за наведение курсора. Толщина — шесть пикселей: три читались как
   обводка картинки, и щелчок оставался незаметным. */
.cast__item.is-on img, .cast__item.is-on .cast__none {
  border-color: #22c55e; border-width: 6px;
  box-shadow: 0 0 0 4px rgba(34, 197, 94, .35); }
.cast__item.is-on .cast__name { color: #16a34a; }
/* Наведение не должно спорить с выбором: серая рамка поверх зелёной читалась
   бы как отмена. */
.cast__item.is-on:hover img { border-color: #22c55e; }

/* Плашка стоит поверх фотографии, а не под ней. Снизу у метки живут имя и
   место съёмки, и плашка, привязанная к низу метки, ложилась прямо на них:
   выбранный актёр оказывался единственным, чьё имя нельзя прочесть. */
.cast__badge { position: absolute; left: 36px; right: 8px; top: 8px;
  display: none; padding: 4px 6px; border-radius: 4px; text-align: center;
  background: #22c55e; color: #fff; font-size: 11.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; }
.cast__item.is-on .cast__badge { display: block; }
.cast__item.is-on .cast__tick { background: #22c55e; border-color: #fff; }

/* Остальные приглушаются только после выбора: гашение — ответ на щелчок,
   а не оформление страницы. */
.cast.has-pick .cast__item:not(.is-on) label { opacity: .55; }
.cast.has-pick .cast__item:not(.is-on) label:hover { opacity: 1; }

/* Кто выбран — словами. Выбранная плитка может уехать за край экрана, и по
   одной рамке нельзя сказать, с кем соберётся ролик. */
.cast__pick { margin: 14px 0 0; padding: 8px 12px; border-radius: var(--r-sm);
  border-left: 4px solid #22c55e; background: rgba(34, 197, 94, .12);
  font-size: 14px; font-weight: 600; }
.cast__pick:empty { display: none; }

.cast__why { margin: 0 0 12px; padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--surface-2, rgba(127,127,127,.1)); color: var(--ink-soft);
  font-size: 13px; }
.cast__why[hidden] { display: none; }

.cast__name { display: block; margin-top: 8px; font-size: 13.5px; font-weight: 600; }
.cast__where { display: block; font-size: 12px; color: var(--ink-soft); }
.cast__empty { margin: 14px 0 0; color: var(--ink-soft); }

/* Экран ожидания. Долгие шаги мастера — от десяти секунд до двадцати, и всё
   это время страница просто не отвечала. */
.waiting { position: fixed; inset: 0; z-index: 60; display: grid;
  place-items: center; padding: 24px; background: rgba(0,0,0,.55);
  backdrop-filter: blur(2px); }
.waiting[hidden] { display: none; }
.waiting__box { width: min(420px, 100%); padding: 28px 26px; text-align: center;
  border-radius: var(--r-md, 12px); background: var(--surface);
  border: 1px solid var(--line); }
.waiting__spin { display: block; width: 30px; height: 30px; margin: 0 auto 16px;
  border-radius: 50%; border: 3px solid var(--line);
  border-top-color: var(--primary); animation: waiting-spin .8s linear infinite; }
@keyframes waiting-spin { to { transform: rotate(360deg); } }
.waiting__what { margin: 0 0 4px; font-weight: 600; }
.waiting__time { margin: 0 0 14px; font-size: 13px; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }
.waiting__note { margin: 0; min-height: 2.6em; font-size: 13px;
  color: var(--ink-soft); }

/* Кто просил не двигать — тому не двигаем. Крутилка тогда просто стоит. */
@media (prefers-reduced-motion: reduce) {
  .waiting__spin { animation: none; }
}

@media (max-width: 640px) {
  .pick__top { flex-wrap: wrap; }
  .pick__tone { margin-left: 0; width: 100%; }
  .pick__go { margin-left: 0; width: 100%; justify-content: center; }
}
.link-beats { margin: 0 0 12px; padding-left: 20px; display: grid; gap: 6px; }
.link-beat { width: 100%; font-size: 14px; }
/* Подвал карточки сценария. Столбцом, а не строкой: карточек в ряду три,
   каждая около трёхсот пикселей, и три поля в строку сжимали выбор актёра
   до тридцати восьми пикселей — до стрелки без текста. */
.link-script__foot { display: grid; gap: 8px; }
.link-script__foot .link__field--inline {
  display: grid; grid-template-columns: 54px minmax(0, 1fr); align-items: center; gap: 8px; }
.link-script__foot .link__label { margin: 0; }
.link-script__foot select { width: 100%; min-width: 0; }
.link-script__foot .btn { width: 100%; justify-content: center; }

/* Кнопка паузы рядом с репликой. Узкая и без слова «pause»: место в
   карточке уходит тексту, а не подписи к кнопке. */
.link-beat__pause { font-size: 11px; padding: 3px 6px; }
.link-note { margin: 18px 0 0; font-size: 13px; color: var(--ink-soft); }

/* Подсказки под полем. Кнопки, а не выпадающий список: список надо сперва
   догадаться открыть, а кнопка видна и дописывает в поле через запятую. */
.link-suggest { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.link-suggest__item { padding: 4px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: transparent;
  color: var(--ink-soft); font: inherit; font-size: 12.5px; }
.link-suggest__item:hover { border-color: var(--primary); color: var(--ink); }

/* Акция. Свёрнута, пока не включена: у большинства товаров её нет, а пустые
   поля цены на экране читаются как «надо заполнить». */
.link-promo { margin-top: 14px; }
.link-promo__switch { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.link-promo__switch .link__head { margin: 0; }
.link-promo__body { margin-top: 14px; }
.link-promo__prices { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Картинка, которая не выдержит кадра 720×1280. Галочка снята, и рядом знак,
   объясняющий почему: снятая галочка без объяснения читается как поломка. */
.link-media__item--poor img { filter: grayscale(.6); }
.link-media__why { position: absolute; right: 6px; top: 6px; z-index: 1;
  width: 18px; height: 18px; border-radius: 50%; cursor: help;
  display: grid; place-items: center;
  background: var(--warn, #b45309); color: #fff; font-size: 11px; font-weight: 700; }

/* Взять предложенное или принести своё. */
.link-tabs { display: inline-flex; gap: 2px; margin-bottom: 16px; padding: 2px;
  border-radius: var(--r-sm); background: var(--surface-2, rgba(127,127,127,.1)); }
.link-tabs__tab { padding: 7px 16px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--ink-soft); font: inherit; cursor: pointer; }
.link-tabs__tab.is-on { background: var(--surface); color: var(--ink); }

.link-beats li { display: flex; align-items: flex-start; gap: 6px; }
.link-beat__pause { flex: none; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: transparent; cursor: pointer;
  color: var(--ink-soft); font: inherit; white-space: nowrap; }
.link-beat__pause:hover { border-color: var(--primary); color: var(--ink); }

.link-more { margin-top: 16px; text-align: center; }

/* Кнопка внутри строки текста: «попробовать пример» и «ввести руками»
   стоят там, где человек читает про ограничения разбора. */
.link-hero__try { padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: var(--primary); text-decoration: underline; }
.alert__action { display: inline-block; margin-left: 8px; }
.link-add { margin-top: 14px; }
/* `hidden` перебивается любым своим `display`, поэтому оговариваем. */
.link-add[hidden] { display: none; }
.link-add .link__hint { display: inline-block; margin-left: 10px; }

/* Шаги мастера. Человек должен видеть, где он и сколько осталось: раньше
   товар и настройки ролика стояли рядом на одном экране, и порядка не было
   вовсе. */
.steps { display: flex; gap: 8px; margin: 0 0 18px; padding: 0; list-style: none;
  counter-reset: step; }
.steps__item { counter-increment: step; padding: 6px 14px 6px 34px;
  position: relative; border-radius: 999px; font-size: 13px;
  color: var(--ink-soft); background: var(--surface-2, rgba(127,127,127,.08)); }
.steps__item::before { content: counter(step); position: absolute; left: 10px;
  top: 50%; transform: translateY(-50%); width: 18px; height: 18px;
  border-radius: 50%; display: grid; place-items: center; font-size: 11px;
  background: var(--line); color: var(--ink-soft); }
.steps__item.is-on { color: var(--ink); font-weight: 600; }
.steps__item.is-on::before { background: var(--primary); color: #fff; }
.steps__item.is-done a { color: var(--ink-soft); }
.steps__item a { text-decoration: none; }

.wizard-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
.wizard-note { text-align: right; margin-top: 8px; }

/* Плитка «добавить» первой в списке материала — как у Creatify. */
.link-media__add button { width: 100%; aspect-ratio: 3 / 4; cursor: pointer;
  display: grid; place-content: center; gap: 6px; justify-items: center;
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  background: transparent; color: var(--ink-soft); font: inherit; font-size: 12.5px; }
.link-media__add button:hover { border-color: var(--primary); color: var(--ink); }
.link-media__plus { font-size: 22px; line-height: 1; }

.link-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 12px; }
.link-bulk .link__hint { margin: 0; }

/* Список тона в карточке сценария. Стоит под заголовком: тон — свойство
   этого сценария, а не всего экрана. */
.link-script__tone { margin: 0 0 10px; }
.link-script__tone select { width: 100%; }

/* Первый заход. Отличается обрамлением, а не формой: дело то же самое. */
.link-hero--welcome { padding-top: 4vh; }
.link-hero__kicker { margin: 0 0 6px; font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--primary); }
.link-hero__skip { margin-top: 22px; }
.link-hero__skip button { padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--ink-soft); text-decoration: underline; }
.link-hero__skip button:hover { color: var(--ink); }

/* Три входа на первом экране, равные по весу: свои фотографии и уже
   разобранное — такие же обычные пути, как разобрать новую ссылку.

   Ширину не задаём: ряд наследует её у `.link-hero`, и поле ввода над ним
   получается ровно той же. Своя `max-width` была на двадцать пикселей
   больше, и кнопки торчали за края поля с обеих сторон. */
.link-ways { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  margin: 12px 0 0; }
.link-ways .btn { justify-content: center; }
.link-ways__pick[disabled] { opacity: .45; cursor: not-allowed; }

/* Библиотека разобранного. */
.library { position: fixed; inset: 0; z-index: 50; display: grid;
  place-items: center; padding: 24px; background: rgba(0,0,0,.6); }
/* Атрибут `hidden` прячет элемент через `display:none` в стилях браузера, и
   любой свой `display` его отменяет. Без этой строки окно висело открытым с
   загрузки страницы и не закрывалось: кнопка ставила атрибут, а он ничего
   не значил. Правило идёт после `.library`, иначе проиграет по порядку. */
.library[hidden] { display: none; }
.library__sheet { width: min(880px, 100%); max-height: 82vh; display: flex;
  flex-direction: column; border-radius: var(--r-md, 12px);
  background: var(--surface); border: 1px solid var(--line); }
.library__head { display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--line); }
.library__head h2 { margin: 0; font-size: 15px; flex: none; }
.library__count { padding: 1px 7px; border-radius: 999px; font-size: 12px;
  background: var(--surface-2, rgba(127,127,127,.15)); color: var(--ink-soft); }
.library__search { flex: 1; }
.library__close { flex: none; width: 28px; height: 28px; border: 0; cursor: pointer;
  background: none; color: var(--ink-soft); font-size: 20px; line-height: 1; }
.library__list { margin: 0; padding: 16px; list-style: none; overflow-y: auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.library__item a { display: block; }
.library__tiles { position: relative; display: grid; gap: 2px;
  grid-template-columns: 1fr 1fr; border-radius: var(--r-sm); overflow: hidden;
  aspect-ratio: 1; background: var(--surface-2, #1a1a1a); }
.library__tiles img { width: 100%; height: 100%; object-fit: cover; display: block; }
.library__blank { grid-column: span 2; }
.library__badge { position: absolute; left: 6px; bottom: 6px; padding: 1px 7px;
  border-radius: 4px; background: rgba(0,0,0,.7); color: #fff; font-size: 11px; }
.library__title { display: block; margin-top: 8px; font-size: 13px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.library__url { display: block; font-size: 11.5px; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.library__empty { padding: 0 18px 18px; color: var(--ink-soft); }

@media (max-width: 560px) {
  .link-ways { grid-template-columns: 1fr; }
}

/* Тихие действия — одной строкой под кнопками. Каждое из них уводит в
   сторону от главного пути, и кнопкой они спорили бы с тремя настоящими. */
.link-hero__note .link-hero__try { font-size: inherit; }

@media (max-width: 820px) {
  .link-grid { grid-template-columns: 1fr; }
  .link-form { flex-direction: column; }
  .link-promo__prices { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════════════
   Онбординг на полный экран

   Тот же композер, но один на пустой странице. Всё, до чего человек ещё не
   дошёл, лежит в тумане; кольцо и пульс — на том, что нажимают следующим.

   Отдельного набора экранов нет нарочно: мастер, который тут был, описывал
   понятие «ролик» вторым способом, и способы разошлись до счётчика 298/180
   с запертой кнопкой. Здесь человек с первой секунды нажимает те самые
   органы, которыми будет пользоваться завтра.
   ══════════════════════════════════════════════════════════════════════ */

/* Вокруг композера не остаётся ничего: ни столбца, ни шапки, ни сетки. */
.shell.is-focus .sidebar,
.shell.is-focus .topbar,
.shell.is-focus .scrim,
.shell.is-focus .nav-show,
.shell.is-focus .content-head,
/* Сетка роликов нужна разметке как цель для ответа формы, но не глазам:
   прячем стилем, а не условием в шаблоне. */
.shell.is-focus #workspace { display: none; }

.shell.is-focus { grid-template-columns: 1fr; }
.shell.is-focus .main {
  /* Отступ под столбец снимаем: столбца нет, а место под него на широком
     экране оставалось, и весь онбординг съезжал вправо на 232 пикселя. */
  height: 100dvh; margin-left: 0; padding: 0 !important; overflow: hidden;
  display: flex; flex-direction: column;
  /* Шаг — одна колонка, а не четыре полосы, растянутые по высоте окна.
     Пока середина забирала весь остаток, на широком экране между заголовком
     и карточкой стояло двести пустых пикселей, а кнопка шага уезжала к самому
     низу — так далеко от карточки, что читалась как часть браузера, а не как
     продолжение того, что человек только что сделал. */
  justify-content: center;
}
/* Все четыре части — по одной ширине и по одной оси. Без этого счётчик
   и точки разъезжались к краям окна, а карточка стояла посередине: три
   разных края на одном экране. */
.fk__head,
.fk__say,
.fk__foot { width: 100%; max-width: 700px; margin-inline: auto; }

/* Композер перестаёт быть полосой у нижнего края и встаёт по центру. */
.shell.is-focus .composer {
  position: static; inset: auto; width: 100%;
  display: flex; justify-content: center;
  background: transparent; border: 0; box-shadow: none;
  padding: 0 20px; z-index: auto;
}
.shell.is-focus .composer__handle { display: none; }
/* Класс с display перебивает браузерное правило для атрибута: без этой
   строки композер остаётся на экране под вступлением и финалом. */
.shell.is-focus .composer[hidden] { display: none; }
.shell.is-focus .composer__form {
  display: block; width: 100%; max-width: 660px; padding: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card);
}
/* Композер в фокусе ниже, чем на обычном экране. На шаге про деньги к нему
   добавляются две карточки, и в прежних размерах он переставал влезать
   в окно: обрезался и сверху, и снизу. Реплика здесь в две строки, а зона
   фото на широком экране растянута до 252 пикселей — столько ей ни к чему.
   Селекторы длиннее нарочно: перебиваем правила из медиазапроса. */
.shell.is-focus .composer .composer__form textarea { min-height: 84px; }
.shell.is-focus .composer .dropzone { height: 132px; flex-basis: 116px; }
.shell.is-focus .composer .composer__main { padding: 5px; }

/* ── оболочка шага ──────────────────────────────────────────────────── */
.fk { display: contents; }
/* Класс с display перебивает браузерное правило для атрибута: без этой
   строки `hidden` на обёртке тура ничего не прятал, и тур оставался
   на экране под окном генерации. Та же ловушка, что и с композером. */
.fk[hidden] { display: none; }

.fk__head {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 20px 0; flex: none;
}
.fk__back {
  border: 1px solid var(--line-input); background: var(--bg); color: var(--ink);
  width: 34px; height: 34px; border-radius: 50%; font-size: 15px; line-height: 1;
  cursor: pointer; flex: none;
}
.fk__back[hidden] { display: none; }
.fk__back:hover { border-color: var(--primary); }

.fk__dots { display: flex; gap: 4px; }
.fk__dots button {
  width: 22px; height: 3px; border-radius: 2px; border: 0; padding: 0;
  background: var(--line-input); cursor: default;
}
.fk__dots button.on { background: var(--guide); }
.fk__dots button.can { cursor: pointer; }
.fk__dots button.can:hover { outline: 2px solid var(--guide-halo); outline-offset: 3px; }

.fk__no {
  margin-left: auto; font-size: 11px; color: var(--ink-soft);
  letter-spacing: .06em; font-variant-numeric: tabular-nums;
}

.fk__say { padding: 18px 20px 4px; text-align: center; flex: none; }
.fk__say h1 {
  font-size: clamp(20px, 3vw, 26px); line-height: 1.2; font-weight: 600;
  letter-spacing: -.02em; margin: 0 auto 6px; max-width: 22ch; text-wrap: balance;
}
.fk__say p {
  margin: 0 auto; font-size: 14.5px; color: var(--ink-soft);
  line-height: 1.5; max-width: 48ch;
}
.fk__say p[hidden] { display: none; }

/* Середина растягивается и прокручивается сама. Центрируем автоотступами,
   а не align-items: center: при центрировании флексом переросшее содержимое
   обрезается сверху и до него нельзя доскроллить. */
/* `0 1 auto`, а не `1`: середина занимает столько, сколько нужно карточке,
   и сжимается с прокруткой, только если та не влезла. Расти ей больше не от
   чего — колонка стоит по центру окна. */
.shell.is-focus .composer,
.fk__pane {
  flex: 0 1 auto; min-height: 0; overflow-y: auto;
}
.fk__pane { display: flex; justify-content: center; padding: 14px 20px; }
.shell.is-focus .composer { padding-top: 14px; padding-bottom: 14px; }
.fk__pane[hidden] { display: none; }
/* Автоотступы, а не align-items — и у панелей, и у композера. Флексовое
   центрирование срезает переросшее содержимое сверху, и доскроллить до него
   нельзя: на низком экране шаг про деньги терял верх карточек. */
.fk__pane > *,
.shell.is-focus .composer > .composer__form { margin: auto; }

/* ── вступление: настоящий пример ───────────────────────────────────── */
.fk__eq {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(8px, 2vw, 18px); flex-wrap: nowrap;
}
.fk__eq figure { margin: 0; flex: none; text-align: center; }
.fk__eq img,
.fk__eq video {
  display: block; width: 100%; height: auto; border-radius: var(--r-md);
  border: 1px solid var(--line); box-shadow: var(--shadow-card); background: var(--bg);
}
.fk__eq figure { width: clamp(76px, 15vw, 128px); }
.fk__eq .fk__out { width: clamp(96px, 19vw, 164px); }
.fk__eq .fk__out video { border-color: var(--primary); background: #000; }
.fk__eq figcaption {
  margin-top: 8px; font-size: clamp(9.5px, 1.3vw, 11.5px);
  letter-spacing: .05em; color: var(--ink-soft);
}
.fk__op { font-size: clamp(18px, 3vw, 26px); color: var(--ink-soft); font-weight: 300; flex: none; }

/* На телефоне доли от ширины окна вырождались в нижнюю границу clamp, и
   уравнение съёживалось до трёх марок посреди пустого экрана — при том, что
   это первое, что человек видит, и весь смысл первого экрана. Считаем от
   ширины устройства и сужаем поля: ролик вырастает почти вдвое. */
@media (max-width: 560px) {
  .fk__pane { padding: 14px 12px; }
  /* Уравнение чуть меньше: под ним теперь дорожка, и вдвоём они в экран
     не встают. Уменьшаем картинки, а не дорожку — уравнение и так понятно
     с первого взгляда, а дорожку надо прочитать. */
  .fk__eq figure { width: 20vw; }
  .fk__eq .fk__out { width: 32vw; }
  /* Заголовок и объяснение шага крупнее: доли от ширины окна вырождались
     в нижнюю границу, и на телефоне шаг подписывался тем же кеглем, что
     подпись под картинкой. Это главные слова экрана — их читают первыми. */
  .fk__say h1 { font-size: 24px; max-width: 20ch; }
  .fk__say p { font-size: 16px; line-height: 1.45; }
  .fk__eq { gap: 6px; }
  .fk__eq figure { width: 22vw; }
  .fk__eq .fk__out { width: 36vw; }
  .fk__op { font-size: 20px; }
}

/* Вступление — единственная панель с двумя детьми: уравнение и дорожка
   под ним. Панель выкладывает детей в строку, и без этой пары строк
   дорожка встаёт сбоку от уравнения и уезжает за край экрана. */
.fk__intro { flex-direction: column; justify-content: center; }
.fk__intro > * { margin: 0 auto; }

/* Дорога под уравнением. Уравнение говорит, что получится; дорожка — что
   человек будет делать и что это кончится. Линия и номера не украшение:
   они показывают порядок и конечность, а список без них читается как
   перечень требований.

   Линия рисуется псевдоэлементом от первого кружка к последнему, а не
   рамкой у пунктов: рамка ушла бы вниз за последний номер и обрывалась
   в пустоте. */
.fk__track {
  position: relative;
  margin: clamp(14px, 3vh, 24px) auto 0;
  width: 100%; max-width: 330px;
}
.fk__track::before {
  content: ""; position: absolute; left: 11px; top: 10px; bottom: 12px; width: 2px;
  background: linear-gradient(var(--guide), var(--tag-bg));
}
.fk__track ol {
  list-style: none; counter-reset: fkstep;
  margin: 0; padding: 0; display: grid; gap: 13px;
}
.fk__track li {
  counter-increment: fkstep;
  position: relative; padding-left: 34px;
  font-size: 13.5px; line-height: 1.35;
}
.fk__track li::before {
  content: counter(fkstep);
  position: absolute; left: 0; top: -1px;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg); border: 2px solid var(--guide); color: var(--ink);
  font-size: 11px; font-weight: 700;
}
.fk__track b { display: block; font-weight: 600; color: var(--ink); }
.fk__track span { font-size: 12.5px; color: var(--ink-soft); }

/* ── финал ──────────────────────────────────────────────────────────── */
.fk__end { width: 100%; max-width: 640px; }
.fk__end[hidden] { display: none; }
.fk__lead { font-size: 14px; color: var(--ink-soft); margin: 0 0 14px; line-height: 1.5; }

.fk__modes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 560px) { .fk__modes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.fk__mode {
  display: flex; align-items: center; gap: 6px; justify-content: space-between;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg);
  padding: 9px 11px; font-size: 12.5px; color: var(--ink);
  font-family: inherit; text-align: left; cursor: pointer; min-height: 40px;
}
.fk__mode.is-on { font-weight: 600; }
.fk__mode.is-open { border-color: var(--guide); box-shadow: 0 0 0 3px var(--guide-halo); }
.fk__badge {
  font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase;
  background: var(--tag-bg); color: var(--ink); border-radius: 4px;
  padding: 2px 5px; flex: none; font-style: normal;
}

/* Один экран показа. Ролики слева, подпись и кнопка справа; у «Ad Remake»
   роликов два — «было» и «стало», — и в этом весь его смысл. */
.fk__demo {
  display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 16px; align-items: center;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
}
@media (max-width: 560px) { .fk__demo { grid-template-columns: 1fr; } }
.fk__reels { display: flex; gap: 8px; }
.fk__reels figure { margin: 0; width: 108px; }
.fk__reels.is-pair figure { width: 96px; }
.fk__reels video {
  display: block; width: 100%; height: auto; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface-2);
}
.fk__reels figcaption {
  margin-top: 5px; text-align: center; font-size: 10.5px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft);
}
.fk__noreel { margin: 0; font-size: 12.5px; color: var(--ink-soft); }
.fk__demo-side h3 { margin: 0 0 5px; font-size: 15px; font-weight: 600; }
.fk__demo-side p { margin: 0 0 12px; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
.fk__demo-side .btn { font-size: 13px; }
/* Короткий зов на предпоследнем экране. Отделён чертой: это не часть выбора
   режима, а предложение поговорить, и мешать их в один поток нельзя. */
.fk__need {
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.fk__need p { margin: 0; flex: 1 1 220px; font-size: 13px; line-height: 1.5; color: var(--ink-soft); }
.fk__need b { color: var(--ink); display: block; }
.fk__need-btn { flex: none; background: #25d366; border-color: #25d366; color: #fff; }
.fk__need-btn:hover { background: #1fbe59; border-color: #1fbe59; color: #fff; }
@media (max-width: 560px) { .fk__need-btn { width: 100%; } }

/* Лицо рядом со словами: человек верит глазам раньше, чем тексту.
   Кружком, а не карточкой — это портрет, а не иллюстрация. */
.fk__ask-me { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.fk__ask-me img {
  flex: none; width: 72px; height: 72px; border-radius: 50%;
  object-fit: cover; background: var(--surface-2);
  box-shadow: 0 2px 10px rgba(14, 15, 19, .12);
}
.fk__ask-me h2 { margin: 0; }
.fk__ask-me .fk__ask-eyebrow { margin-bottom: 4px; }

/* Экран разговора. Он последний, и на нём человек читает, а не выбирает,
   поэтому текст в одну колонку и шире обычного: разорванные строки читают
   хуже, а это единственное место, где просят прочитать до конца. */
.fk__ask { width: 100%; max-width: 460px; }
.fk__ask-eyebrow {
  margin: 0 0 6px; font-size: 10.5px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-soft);
}
.fk__ask h2 {
  margin: 0 0 12px; font-size: 21px; line-height: 1.25; font-weight: 650;
  letter-spacing: -.02em; text-wrap: balance;
}
.fk__ask-lead {
  margin: 0 0 12px; font-size: 14.5px; line-height: 1.55; color: var(--ink-soft);
}
/* `flex`, а не `block`: `.btn` центрует содержимое флексом, и `display: block`
   его отменял. На кнопке-ссылке это было видно — «Message me on WhatsApp»
   прижималось к левому краю зелёной плашки, тогда как соседняя кнопка ниже
   стоит по центру (у `<button>` центровку держит ещё и браузер). Две кнопки
   подряд с разной выключкой текста и читаются как съехавшая вёрстка. */
.fk__ask-btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 48px; margin-top: 18px;
  background: #25d366; border-color: #25d366; color: #fff;
  font-size: 15px; font-weight: 600;
}
.fk__ask-btn:hover { background: #1fbe59; border-color: #1fbe59; color: #fff; }
/* Тихая кнопка: разговор — предложение, а не пошлина за выход. */
.fk__ask-skip {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 44px; margin-top: 10px;
}

/* Последнее действие тура — большая кнопка во всю ширину: это продолжение
   пути, а не выход сбоку. */
.fk__go { margin-top: 18px; width: 100%; min-height: 46px; font-size: 15px; }

/* ── разбор списания: два мгновения и полоса остатка ────────────────── */
.fk__costs { width: 100%; max-width: 660px; margin: 12px auto 0; }
.fk__costs[hidden] { display: none; }

/* Столбец, а не два блока рядом. Рядом они читались как выбор из двух —
   «взять подешевле или подороже», — тогда как это одно за другим во времени.
   В столбце порядок виден сам: сперва кадры, и только потом, по желанию,
   ролик. Заодно раскладка одна и та же на телефоне и на мониторе.

   Линия и кружки — те же, что на дорожке первого экрана: одна и та же
   мысль про порядок должна выглядеть одинаково в обоих местах. */
.fk__pay {
  list-style: none; counter-reset: fkpay;
  margin: 0; padding: 0; position: relative;
  display: grid; gap: 14px;
}
.fk__pay::before {
  content: ""; position: absolute; left: 12px; top: 12px; bottom: 14px; width: 2px;
  background: linear-gradient(var(--guide), var(--tag-bg));
}

.fk__pay-step { counter-increment: fkpay; position: relative; padding-left: 38px; }
.fk__pay-step::before {
  content: counter(fkpay);
  position: absolute; left: 0; top: 0;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg); border: 2px solid var(--guide); color: var(--ink);
  font-size: 11px; font-weight: 700;
}
/* Первый кружок залит, второй пустой: первое случится, второе — только если
   человек сам выберет кадр. Разницу видно раньше, чем прочитаны слова. */
.fk__pay-step--now::before { background: var(--guide); color: #fff; border-color: var(--guide); }

/* Начало пункта — ровно те слова, что стоят в строке итога выше. Строка учится
   читаться сама, а она и останется с человеком после тура. */
.fk__pay-line {
  margin: 2px 0 4px; font-size: 15px; line-height: 1.25; color: var(--ink-soft);
}
.fk__pay-line b {
  font-size: 22px; font-weight: 600; letter-spacing: -.02em; color: var(--ink);
  font-variant-numeric: tabular-nums; margin-right: 3px;
}
.fk__why { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }

/* Полоса остатка. «220» ничего не говорит тому, кто пять минут как завёл
   счёт: много это или мало? Полоса отвечает без слов — видно, какую часть
   запаса занимает ролик и сколько остаётся. */
.fk__bal { margin-top: 11px; }
.fk__bar {
  display: flex; height: 7px; border-radius: 4px; overflow: hidden;
  background: var(--line); gap: 2px;
}
.fk__bar span { display: block; height: 100%; border-radius: 4px; }
.fk__bar-now { background: var(--guide); }
.fk__bar-later { background: var(--guide); opacity: .45; }

.fk__after { margin: 7px 0 0; text-align: center; font-size: 13px; color: var(--ink-soft); }
.fk__after b { color: var(--ink); font-variant-numeric: tabular-nums; }
.fk__after.is-short b { color: var(--danger); }

/* Меню режимов в онбординге не открывается: режим один. Показываем его
   надписью, а не органом управления — стрелка вниз обещала бы выбор. */
.modepick.is-frozen > .pill { cursor: default; }
.modepick.is-frozen > .pill:hover { border-color: var(--line-input); }
.modepick.is-frozen .pill__chev { display: none; }

/* ── низ ────────────────────────────────────────────────────────────── */
.fk__foot { flex: none; padding: 14px 20px 22px; display: flex; justify-content: center; }
.fk__foot[hidden] { display: none; }
/* Последний шаг — единственный, где ждут нажатия не на кнопку внизу, а на
   стрелку в углу карточки. Слова «Press the arrow» стояли по центру, под
   серединой карточки, и показывали пальцем в пустое место. Отводим строку
   вправо, под саму стрелку, и ставим знак вверх — читается как указатель,
   а не как ещё одна подпись.

   Отступ справа — половина ширины стрелки (24) плюс поля карточки (14):
   так знак встаёт ровно под её осью, а поскольку карточка и низ ужаты
   одной и той же колонкой, на любой ширине они не разъезжаются. */
.fk__foot--point { justify-content: flex-end; padding-right: 58px; }
.fk__foot--point .fk__wait { padding-top: 4px; text-align: right; }
.fk__foot--point .fk__wait::after {
  content: "↑"; display: block; margin-top: 2px;
  font-size: 15px; color: var(--guide);
}
.fk__next {
  border: 0; border-radius: var(--r-md); background: var(--primary); color: var(--primary-ink);
  font: inherit; font-size: 15px; font-weight: 500; padding: 13px 30px; cursor: pointer;
  min-height: 50px; min-width: 220px;
}
.fk__next[hidden] { display: none; }
.fk__wait { font-size: 13px; color: var(--ink-soft); margin: 0; padding: 15px 0; text-align: center; }
.fk__wait[hidden] { display: none; }

/* ── палец, а не курсор ─────────────────────────────────────────────────
   На телефоне в туре четыре цели были меньше подушечки пальца: возврат 34,
   пометки голоса 30, пилюли выбора 36, кружок «i» — пятнадцать. Промах по
   такой цели человек читает не как свой промах, а как «кнопка не работает»,
   и именно из этого складывается ощущение недоделанности.

   Тур, а не только шторка: правило 44 пикселей стояло под `.composer.is-open`,
   а в туре композер раскрыт другим способом — и до сюда не доставало. */
@media (max-width: 1023px) {
  .fk__back { width: 44px; height: 44px; font-size: 17px; }
  .shell.is-focus .composer__controls .pill { min-height: 44px; }
  .emobtn { min-height: 44px; padding: 5px 14px; }

  /* Кружку «i» рост не нужен: он подпись к строке, а не орган управления,
     и раздутый до 44 пикселей спорил бы с ценой рядом. Растёт только область
     касания — прозрачным пятном поверх, размер на глаз не меняется. */
  .info__btn { position: relative; }
  .info__btn::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
}

/* ── туман ──────────────────────────────────────────────────────────── */
/* Прячет только то, до чего ещё не дошли. Сделанное остаётся чётким: на
   шаге эмоций пометки вставляются в текст, и не видеть его значит не видеть,
   что кнопка сделала; а вернуться к размытому нельзя — оно не ловит нажатий.

   Плавной делаем прозрачность, не фильтр: переход на filter пересчитывает
   свёртку каждый кадр, и на среднем Android это заметная просадка.
   Статичное размытие растрируется один раз. */
.fk-fog {
  filter: blur(5px); opacity: .32;
  transition: opacity .2s ease;
  pointer-events: none; user-select: none;
}
@media (prefers-reduced-motion: reduce) { .fk-fog { transition: none; } }

/* ── кольцо и пульс ─────────────────────────────────────────────────── */
/* Обводкой, а не рамкой на псевдоэлементе: та рисуется внутри и обрезается
   overflow: hidden, который у зоны загрузки стоит ради превью. */
.fk-lit {
  outline: 3px solid var(--guide); outline-offset: 4px;
  box-shadow: 0 0 0 6px var(--guide-halo);
}
/* Строка итога подсвечивается тише карточек: она объясняемое, а не цель
   нажатия. Заливкой, а не рамкой: две рамки одна над другой читались как
   ошибка формы, а заливка просто говорит «речь про эту строку». */
.fk-lit--soft {
  outline: none; box-shadow: none;
  background: var(--guide-halo); border-radius: var(--r-sm);
}

/* Волна на том, что нажимают. Цикл 1.5 с — меньше одной вспышки в секунду:
   чаще трёх в секунду опасно для людей с фотосенситивной эпилепсией. Три
   волны и тишина: самодвижущееся дольше пяти секунд обязано уметь
   останавливаться, а вечное движение у кнопки раздражает того, кто и так
   понял. Две тени, а не одна: кольцо остаётся, волна идёт поверх. */
@keyframes fk-ping {
  0%   { box-shadow: 0 0 0 6px var(--guide-halo), 0 0 0 4px rgba(196, 122, 0, .55); }
  70%  { box-shadow: 0 0 0 6px var(--guide-halo), 0 0 0 26px rgba(196, 122, 0, 0); }
  100% { box-shadow: 0 0 0 6px var(--guide-halo), 0 0 0 4px rgba(196, 122, 0, 0); }
}
.fk-beat { animation: fk-ping 1.5s ease-out 3; }
@media (prefers-reduced-motion: reduce) { .fk-beat { animation: none; } }

/* ── написать основателю ────────────────────────────────────────────────
   Кнопка в углу, а не в меню: человек с особым случаем не идёт её искать —
   он либо видит, куда написать, либо уходит.

   Со словом, а не одной иконкой: зелёный кружок читается как «поддержка»,
   а зовём мы не в поддержку, а к разговору о том, чего в продукте нет.
   На узком экране слово убирается — там дорог каждый пиксель. */
.wa {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 14px 10px 12px; border-radius: 999px;
  background: #25d366; color: #fff; text-decoration: none;
  font-size: 14px; font-weight: 600; line-height: 1;
  box-shadow: 0 6px 20px rgba(14, 15, 19, .28);
}
.wa:hover { background: #1fbe59; }
/* В туре кнопка висит на каждом шаге: человек с особым случаем понимает это
   не в конце, а посреди дороги — на выборе актёра или на цене.

   Исключение одно — финальный экран: там тот же призыв уже стоит блоком,
   и угловая кнопка ложилась прямо на него, двумя одинаковыми зелёными
   кнопками одна поверх другой. */
body:has(#fk-end:not([hidden])) .wa,
body:has(#fk-ask:not([hidden])) .wa { display: none; }
/* В туре композера снизу нет, и подниматься над ним не от чего. Зато в углу
   есть кому мешать: стрелка отправки стоит там же, в правом нижнем углу
   карточки, и на невысоком телефоне (360×640) зелёный кружок ложился прямо
   на неё, а на последнем шаге — ещё и на слова «Press the arrow ↑», так что
   подсказка показывала на WhatsApp.

   Уводим кнопку в левый угол и снимаем слово: сорок четыре пикселя кружка
   помещаются левее кнопки шага даже на самом узком экране, а справа остаётся
   только то, ради чего человек сюда шёл. */
@media (max-width: 640px) {
  body:has(.shell.is-focus) .wa {
    bottom: 16px; right: auto; left: 16px;
    width: 44px; height: 44px; padding: 0; justify-content: center;
  }
  body:has(.shell.is-focus) .wa__word { display: none; }
}
.wa svg { display: block; flex: none; }
@media (max-width: 640px) {
  /* Композер на телефоне прижат к низу, и кнопка села бы ему на голову. */
  .wa { right: 12px; bottom: 76px; padding: 10px; }
  .wa__word { display: none; }
}

/* ── предложение оплатить пробу ─────────────────────────────────────────
   Тем же окном, что и генерация: человек нажал стрелку и ждёт ответа —
   ответ и приходит поверх страницы, а не уводит на новый экран. */
.trial__panel { max-width: 460px; width: 100%; padding: 22px; }
.trial__head {
  display: grid; grid-template-columns: 1fr auto; align-items: start;
  gap: 8px; margin-bottom: 12px;
}
.trial__eyebrow {
  grid-column: 1; font-size: 10.5px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-soft);
}
.trial__head h3 { grid-column: 1; margin: 2px 0 0; font-size: 20px; font-weight: 600; }
.trial__head .icon-btn { grid-column: 2; grid-row: 1 / 3; }
.trial__lead { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--ink-soft); }
.trial__list { margin: 0 0 18px; padding: 0; list-style: none; display: grid; gap: 8px; }
.trial__list li {
  position: relative; padding-left: 22px;
  font-size: 13.5px; line-height: 1.45; color: var(--ink);
}
/* Галочка псевдоэлементом, а не эмодзи: эмодзи съезжает по базовой линии
   и в каждом браузере по-своему. */
.trial__list li::before {
  content: ""; position: absolute; left: 3px; top: 5px;
  width: 5px; height: 9px;
  border: solid var(--primary); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.trial__pay { width: 100%; min-height: 46px; font-size: 15px; }
.trial__note { margin: 8px 0 0; text-align: center; font-size: 12px; color: var(--ink-soft); }
.join__form { display: grid; gap: 12px; margin-bottom: 4px; }
.join__field { display: grid; gap: 5px; }
.join__field span {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-soft);
}
.join__field input {
  height: 44px; padding: 10px 12px;
  border: 1px solid var(--line-input); border-radius: var(--r-sm);
  background: var(--bg); font: inherit; font-size: 15px;
}
.join__field input:focus { outline: none; border-color: var(--primary); }

.trial__ask {
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.5; color: var(--ink-soft);
}
.trial__ask a { color: var(--ink); }

/* ---- Content Library ---------------------------------------------------
   Оформление снято с makeugc: плашка над заголовком, заголовок в две строки
   со второй акцентной, главы пилюлями по центру, сетка вертикальных плиток
   без подписей. Сетка ломается по тем же порогам, что и сетка роликов:
   2 / 3@400 / 4@1024 / 6@1280. */
.lib { max-width: 1180px; margin: 0 auto; }

.lib__head { text-align: center; margin: 10px 0 26px; }
.lib__kicker {
  display: inline-block; padding: 5px 14px; border-radius: 999px;
  background: #eef2ff; color: #4f6ef7; font-size: 13px; font-weight: 500;
}
.lib__head h1 {
  margin: 16px 0 0; font-size: 44px; line-height: 1.12; letter-spacing: -.02em;
}
.lib__head h1 span { color: #4f6ef7; }

.chips {
  display: flex; flex-wrap: wrap; gap: 8px;
  justify-content: center; margin: 0 0 22px;
}
.chip {
  display: inline-block; padding: 8px 15px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: 13px; color: var(--ink); text-decoration: none; white-space: nowrap;
}
.chip:hover { background: var(--surface-2); }
.chip--on { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.chips--tags { justify-content: flex-start; margin: 14px 0 0; }
.chip--tag { font-size: 12px; padding: 5px 11px; color: var(--ink-soft); }

.libgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (min-width: 400px) { .libgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .libgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .libgrid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.libtile {
  position: relative; padding: 0; border: 0; cursor: pointer;
  aspect-ratio: 9 / 16; border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-2); transition: transform .18s ease;
}
.libtile:hover { transform: translateY(-2px); }
.libtile__video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Плитка без снятого образца: пустая рамка со словами, а не мигающая
   заглушка-картинка. */
.libtile--empty { border: 1px dashed var(--line-input); background: var(--surface); }
.libtile__none {
  display: flex; flex-direction: column; gap: 6px; justify-content: center;
  height: 100%; padding: 16px; text-align: center;
}
.libtile__none b { font-size: 14px; color: var(--ink); }
.libtile__none span { font-size: 12.5px; color: var(--ink-soft); }

/* Плашка с перцентилем CTR. Как на лендинге: сверху и на акценте — это
   единственная цифра на витрине, которая говорит про рынок, а не про нас,
   и она должна попадаться на глаза раньше ролика. */
.libtile__badge {
  position: absolute; top: 6px; left: 6px; z-index: 2;
  padding: 3px 7px; border-radius: 999px;
  /* Цвет тот же, что у метки CTR на лендинге (`--accent` в landing.css).
     Значением, а не переменной: landing.css на этой странице не подключён,
     а заводить второй акцент ради одной плашки — способ их развести. */
  background: #ff4d19; color: #fff;
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
  pointer-events: none;
}

/* «Coming soon» лежит поверх низа ролика на затемнении: подпись под плиткой
   сдвинула бы сетку, а без затемнения белый текст пропадает на светлом
   кадре. */
.libtile__soon {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 14px 8px 7px; text-align: center;
  background: linear-gradient(to top, rgba(0, 0, 0, .72), rgba(0, 0, 0, 0));
  color: #fff; font-size: 11px; font-weight: 600; line-height: 1.25;
  pointer-events: none;
}

/* ---- окно карточки ---- */
.sheet__panel--lib { max-width: 900px; width: 100%; }

/* Колонка образца узкая нарочно: вертикальный ролик при 260 px уезжает
   в 460 px высоты, и подвал с кнопкой оказывается за краем окна. */
.libdetail { display: grid; grid-template-columns: 200px 1fr; gap: 22px; padding: 2px 0 4px; }
.libdetail__media {
  aspect-ratio: 9 / 16; border-radius: var(--r-sm); overflow: hidden; background: #000;
}
.libdetail__media video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Вторая полка витрины: что уже снято, но ещё не запущено. Отбита
   заголовком, а не просто отступом: без подписи это выглядело бы как
   продолжение первой, и «Coming soon» на плитке пришлось бы вычитывать. */
.libnext { margin: 34px 0 14px; }
.libnext h2 { margin: 0 0 4px; font-size: 17px; font-weight: 650; letter-spacing: -.01em; }
.libnext p { margin: 0; font-size: 13px; color: var(--ink-soft); }
/* Полка потише: эти рецепты не нажимаются, и тянуть на себя взгляд наравне
   с рабочими им незачем. Оживают под курсором — посмотреть-то можно. */
.libgrid--soon { opacity: .72; }
.libgrid--soon:hover { opacity: 1; }

/* Галочка «оставить реплику образца». Стоит над полем, а не под ним:
   решение принимают до того, как начнут писать, а не после. */
.keepline {
  display: flex; align-items: center; gap: 8px; margin: 0 0 8px;
  font-size: 13px; color: var(--ink); cursor: pointer;
}
.keepline input { width: 16px; height: 16px; margin: 0; flex: none; accent-color: var(--primary); }
/* Погашенное поле остаётся на месте вместе с написанным: спрятать его значит
   отнять текст у того, кто ещё передумает. */
.field--off textarea { opacity: .45; }
.field--off .field__count { opacity: .45; }

/* Длина, когда выбирать не из чего: не ряд из одной кнопки, а строка.
   Кнопка, у которой нет альтернативы, обещает выбор и не даёт его. */
.libfixed { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft); }
.libfixed b { color: var(--ink); font-size: 15px; }

/* На весь экран ролик показывается целиком, а не серединой.

   В окне карточки рамка сама 9:16, и `cover` там ничего не режет — кадр
   и рамка одной формы. Но стоит нажать «во весь экран», и браузер растягивает
   тот же элемент на монитор 16:9. `cover` честно заполняет его целиком —
   то есть срезает у вертикального ролика верх и низ, оставляя горизонтальную
   полосу через середину. Человек жмёт «покажи целиком» и получает меньше,
   чем видел до нажатия.

   Двумя правилами, а не списком через запятую: браузер, не знающий одного
   селектора, выбрасывает всё правило целиком, и починка досталась бы не всем. */
video:fullscreen { object-fit: contain; width: 100%; height: 100%; }
video:-webkit-full-screen { object-fit: contain; width: 100%; height: 100%; }
.libdetail__none {
  display: flex; flex-direction: column; gap: 8px; justify-content: center;
  height: 100%; padding: 20px; text-align: center; background: var(--surface-2);
}
/* Две сноски в окне карточки: чем измерена плашка и почему кнопка погашена.
   Стоят до описания — они меняют то, как читается всё остальное. */
.libnote {
  margin: 0 0 8px; padding: 8px 10px; border-radius: var(--r-xs);
  font-size: 12.5px; line-height: 1.4;
}
.libnote--badge { background: #fff1ec; color: #8a2f12; }
.libnote--soon { background: var(--surface-2); color: var(--ink-soft); }

.libdetail__none b { color: var(--ink); }
.libdetail__none span { font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
.libdetail__body h4 { margin: 0 0 8px; font-size: 22px; letter-spacing: -.01em; }
.libdetail__body > p { margin: 0; line-height: 1.5; }

.libfacts { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 8px; }
.libfacts li {
  display: flex; gap: 10px; justify-content: space-between;
  padding-bottom: 8px; border-bottom: 1px solid var(--line); font-size: 13.5px;
}
.libfacts span { color: var(--ink-soft); }
.libfacts b { text-align: right; font-weight: 600; }

/* ---- форма повтора ---- */
.linkback {
  display: inline-block; margin: 0 0 12px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 14px; color: var(--ink-soft); cursor: pointer;
}
.linkback:hover { color: var(--ink); }

/* Поля лежат в своей рамке — как у них: форма отделена от всего остального
   окна, и видно, где кончается описание и начинается работа. */
.libform__box {
  padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface-2);
}
.libform__lead { margin: 0; font-size: 12px; font-weight: 600; letter-spacing: .06em; }
.libform__sub { margin: 4px 0 16px; font-size: 13px; color: var(--ink-soft); }
.libform .field { display: block; margin: 0 0 14px; }
.libform .field:last-child { margin-bottom: 0; }
.libform .field__label {
  display: block; margin-bottom: 7px; font-size: 13px; font-weight: 600; color: var(--ink-label);
}
.libform textarea {
  width: 100%; padding: 11px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-input); background: var(--bg);
  font: inherit; font-size: 14px; resize: vertical;
}
.libform .field__hint,
.libform .field__count {
  display: block; margin-top: 6px; font-size: 12px; color: var(--ink-soft);
}

/* Зона загрузки. Настоящий input лежит внутри прозрачным во всю площадь:
   так работают и щелчок, и перетаскивание, и скрипт не нужен. */
.drop {
  position: relative; display: flex; flex-direction: column; gap: 4px;
  align-items: center; justify-content: center; padding: 20px 16px;
  border: 1px dashed var(--line-input); border-radius: var(--r-md);
  background: var(--bg); text-align: center; cursor: pointer;
}
.drop:hover { border-color: var(--ink-soft); }
.drop--filled { border-style: solid; border-color: var(--ok); }
.drop input[type="file"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.drop__icon {
  display: grid; place-items: center; width: 38px; height: 38px; margin-bottom: 2px;
  border-radius: 10px; background: var(--surface-2); color: var(--ink-soft);
}
.drop__title { font-size: 14px; color: var(--ink); }
.drop__sub { font-size: 12.5px; color: var(--ink-soft); }

/* Подвал окна: два действия в ряд, дорогое справа. Отдельно от
   .sheet__actions — там колонка на всю ширину, здесь ряд с разделителем.
   У формы подвал другой: одна широкая кнопка, как у makeugc. */
.sheet__foot {
  display: flex; gap: 10px; justify-content: flex-end; align-items: center;
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line);
}
.sheet__foot--wide { display: block; }
.btn--block { width: 100%; }

@media (max-width: 720px) {
  .lib__head h1 { font-size: 30px; }
  .libdetail { grid-template-columns: 1fr; }
  .libdetail__media { max-width: 200px; margin: 0 auto; }
}
@media (max-width: 560px) {
  .sheet__foot { flex-direction: column-reverse; }
  .sheet__foot .btn { width: 100%; }
}

/* Выбор длины переделки: две карточки в ряд, у каждой секунды и цена.
   Цена стоит рядом с длиной нарочно — это единственное, чем они
   отличаются друг от друга для человека. */
.lens { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.len {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 12px;
  border: 1px solid var(--line-input); border-radius: var(--r-sm);
  background: var(--bg); cursor: pointer;
}
.len input { position: absolute; opacity: 0; pointer-events: none; }
.len b { font-size: 14px; }
.len span { font-size: 12px; color: var(--ink-soft); }
.len--on { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.btn[disabled] { opacity: .45; cursor: not-allowed; }

.lens--three { grid-template-columns: repeat(3, 1fr); }

/* ── правовые страницы и возврат из Stripe ─────────────────────────────
   Своя раскладка, не приложение: сюда приходят до регистрации, из окна
   оплаты или из письма — то есть туда, где ни столбца, ни шапки нет. */
.doc-page { background: var(--bg); color: var(--ink); }
.doc__top { padding: 20px 24px; border-bottom: 1px solid var(--line); }

/* Ширина в 70 знаков, а не во весь экран: длинную строку глаз теряет при
   переносе, а правовой текст и так читают через силу. */
.doc { max-width: 680px; margin: 0 auto; padding: 36px 24px 72px; }
.doc h1 { margin: 0 0 4px; font-size: 30px; letter-spacing: -.02em; }
.doc h2 { margin: 32px 0 10px; font-size: 19px; letter-spacing: -.01em; }
.doc h3 { margin: 20px 0 6px; font-size: 15px; font-weight: 650; }
.doc p, .doc li { font-size: 15px; line-height: 1.65; }
.doc p { margin: 0 0 12px; }
.doc ul { margin: 0 0 12px; padding-left: 22px; }
.doc li { margin-bottom: 6px; }
.doc a { color: var(--ink); }
.doc__when { color: var(--ink-soft); font-size: 13px; margin-bottom: 24px; }
.doc__rule { margin: 36px 0 16px; border: 0; border-top: 1px solid var(--line); }
.doc__foot { font-size: 13px; color: var(--ink-soft); }

/* Пока реквизиты не вписаны, документ — черновик, и это должно быть видно
   сразу, а не вычитываться из скобок посреди текста. */
.doc__draft {
  padding: 12px 14px; border-radius: var(--r-sm);
  background: var(--guide-halo); border: 1px solid var(--guide);
  font-size: 13.5px;
}
.doc__draft code { font-size: 12.5px; }

.paid { max-width: 440px; margin: 0 auto; padding: 64px 24px; text-align: center; }
.paid h1 { margin: 0 0 10px; font-size: 26px; letter-spacing: -.02em; }
.paid__mark {
  width: 56px; height: 56px; margin: 0 auto 18px; border-radius: 50%;
  display: grid; place-items: center;
  background: #e8f5ec; color: #1a7f3c;
}
.paid__lead { margin: 0 0 22px; font-size: 15px; line-height: 1.6; color: var(--ink-soft); }
.paid__go { margin-bottom: 14px; }
.paid__note { margin: 0; font-size: 13px; line-height: 1.55; color: var(--ink-soft); }
.paid__legal { margin: 32px 0 0; font-size: 12.5px; color: var(--ink-soft); }
.paid__legal a, .paid__note a { color: var(--ink); }

/* Условия у кнопки оплаты: мелко, но на виду. */
.trial__legal { margin: 10px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink-soft); }
.trial__legal a { color: var(--ink); }

/* ── вход через Google ─────────────────────────────────────────────────
   Белый фон, тёмный текст, их значок слева — так требуют правила Google
   для этой кнопки, и отступать нельзя: на этом проверяют приложение. */
.gbtn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 44px; margin-bottom: 4px;
  border: 1px solid var(--line-input); border-radius: var(--r-sm);
  background: #fff; color: #1f1f1f;
  font: inherit; font-size: 14px; font-weight: 600; text-decoration: none;
}
.gbtn:hover { background: #f7f7f7; }
.gbtn__mark { display: flex; flex: none; }

/* Черта со словом, а не просто отступ: без неё два способа входа стоят
   друг под другом и читаются как одна форма из пяти полей. */
.gbtn__or {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0; font-size: 12px; color: var(--ink-soft);
}
.gbtn__or::before, .gbtn__or::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* Разговор на экране ожидания: пока платёж подтверждают руками, это
   единственное, что человек может сделать, — и оно должно быть под рукой. */
.trial__wait-wa {
  margin-top: 14px; background: #25d366; border-color: #25d366; color: #fff;
}
.trial__wait-wa:hover { background: #1fbe59; border-color: #1fbe59; color: #fff; }
