/* ============================================================
   Дизайн-токены. Всё остальное ссылается только на них.
   Меняешь тему - правишь здесь, компоненты не трогаешь.
   ============================================================ */
/* «АФИША»: тёплая бумага вместо холодного офисного серого.

   Прежняя палитра была снята с aimp3.ru - светло-серый фон и синие
   чернила. Она честно работала, но у сервиса, где заказывают песню на
   свадьбу и открытку ко дню рождения, лицо получалось как у бухгалтерии.
   Теперь фон - бумага афиши, чернила почти чёрные, а акцент один и
   громкий: кирпичный красный, каким печатают заголовки на тумбах.

   Цвета подобраны не на глаз, а посчитаны по формуле контраста WCAG.
   Каждый рабочий цвет на своём фоне даёт не меньше 4.5:1 - см. цифру
   в скобках рядом. Ниже этого порога текст перестают читать те, у
   кого экран на солнце или зрение не двадцать лет. */
:root{
  --bg:#fdf8ef;            /* бумага */
  --surface:#ffffff;
  --surface-2:#f6eede;
  --surface-3:#ecdfc7;
  --text:#171310;          /* 17.5:1 на бумаге */
  --text-2:#5a5046;        /* 7.4:1 */
  --text-3:#73675a;        /* 5.2:1 - подписи и сноски тоже читают */
  --border:#e6dac3;
  --border-2:#d6c6a8;
  /* ОДИН акцент на две работы сразу: и заливка, и надпись.

     В макете стоял ярче - #e8452c, - но он даёт на бумаге всего 3.7:1
     и в надписи («Каталог», выбранная вкладка, ссылка в сноске) читался
     плохо. Этот на полтона глубже: белым по нему 5.3:1, им самим по
     бумаге 5.0:1. Значит второй «тёмный красный только для текста»
     заводить не нужно - хватает одного. */
  --accent:#c9331c;
  --accent-soft:#fbe6e0;
  --accent-text:#a82a15;   /* 5.8:1 на --accent-soft */
  /* Цвет надписи ПОВЕРХ заливки акцентом. В светлой теме акцент тёмный
     и надпись белая; в тёмной наоборот - там акцент светлый коралл, и
     белым по нему не прочесть ничего. */
  --on-accent:#ffffff;
  /* Кнопка, которая тратит деньги, - зелёная и единственная такая на
     экране. На основном сайте это работает годами: её не ищут.
     В тёмной теме НЕ меняется: узнаётся по цвету, а подгонка под тему
     её обезличивает. Белым по ней 4.6:1. */
  --go:#12864a;
  --go-dark:#0d6c3b;
  --ok:#0d6e3d;
  --ok-soft:#dff0e4;       /* 5.9:1 */
  --warn:#8a5008;
  --warn-soft:#fbeacd;     /* 5.5:1 */
  --danger:#b02616;
  --danger-soft:#fbe3df;   /* 5.5:1 */
  /* ТРИ РАДИУСА НА ВЕСЬ САЙТ, и больше никаких.
     Разнобой скруглений - самое заметное, что выдаёт кустарную вёрстку:
     глаз ловит несогласованность раньше, чем успевает прочитать текст.

     --radius     панели, карточки, крупные блоки
     --radius-sm  всё, на что нажимают: кнопки, чипы, поля, вкладки
     --radius-xs  мелочь внутри кнопок и значков

     В «Афише» среднее значение - таблетка. 999 у квадратного элемента
     сам собой даёт круг, поэтому отдельного «круглого» радиуса не
     нужно: кнопка-значок, аватар и кружок подсказки берут тот же
     --radius-sm. А блокам с несколькими строками внутри (поле ввода
     в три строки, подсказка, пункт меню) таблетка не идёт - им на
     месте прописан --radius или --radius-xs. */
  --radius:18px;
  --radius-sm:999px;
  --radius-xs:12px;

  /* ОДНА ВЫСОТА НА ВСЕ ОРГАНЫ УПРАВЛЕНИЯ.

     Кнопка, поле, чип, вкладка, выпадашка - всё, на что нажимают,
     ростом ровно --ctl. Раньше у каждого была своя высота: сорок у
     кнопки, сорок два у поля, тридцать четыре у мелкой, - и любой ряд
     из двух соседних элементов выходил ступенькой. Это тот сорт
     неаккуратности, который замечают все и никто не может назвать.

     «Афиша» просит крупнее: 44 -> 48. Мелкая выросла с 36 до 40 не
     ради вида, а ради пальца: сорок - нижняя граница, ниже которой в
     кнопку промахиваются. Все места, где высота была вписана числом
     мимо переменной (вторичные чипы 32 и 30, переключатель темы 30,
     кнопка «свернуть» 38), переведены на --ctl-sm. */
  --ctl:48px;
  --ctl-sm:40px;
  --ctl-lg:56px;

  --sidebar:248px;
  --sidebar-min:62px;      /* свёрнутое меню: только значки */
  --tabbar:60px;
  /* Сколько места внизу занимает полоса плеера. Ноль, пока она спрятана;
     когда появляется - её настоящую высоту вписывает сюда JS.

     Через переменную, а не через класс на body: высота полосы разная на
     телефоне и на мониторе, и подбирать её числом в четырёх медиа-
     запросах значит однажды промахнуться. Кто уступает место - тот и
     ссылается на переменную: страница снизу и липкие кнопки. */
  --player-h:0px;
  /* Тень тёплая, не серая: серая тень на бумаге выглядит грязью. */
  --shadow:0 1px 2px rgba(74,52,28,.06), 0 14px 34px -20px rgba(74,52,28,.34);
  --shadow-sm:0 1px 3px rgba(74,52,28,.08);
  /* ДВА ШРИФТА, И У КАЖДОГО СВОЯ РАБОТА.

     Заголовки - с засечками: это лицо «Афиши», по нему страница
     узнаётся раньше, чем прочитана. Интерфейс - без засечек: подписи
     полей, кнопки и таблицы читаются в мелком кегле лучше, а Georgia
     в двенадцати пикселях мылится.

     Отдельная переменная нужна именно потому, что шрифта два: свести
     их в один --font нельзя, а прописывать стек по месту в двадцати
     правилах - тот же разнобой, от которого мы уходим.

     Ни одного веб-шрифта: сеть не ждём, скачков вёрстки нет. Georgia
     есть на Windows и macOS вместе с кириллицей, на Android общий
     serif даёт Noto Serif - тоже с кириллицей. */
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  --font-head:Georgia,"Iowan Old Style","Palatino Linotype","Times New Roman",serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
/* ТЁМНАЯ ТЕМА В ТРЁХ СОСТОЯНИЯХ.

   Системная настройка работает сама, но выбор человека сильнее её:
   у многих в системе стоит тёмная «на ночь», а конкретный сайт они
   хотят видеть светлым. Поэтому три положения: как в системе,
   светлая, тёмная - и последние два перебивают системное.

   Порядок правил важен. Сначала системное предпочтение, но только
   когда человек НЕ выбрал светлую явно; потом явный выбор тёмной.
   Иначе переключатель работал бы в одну сторону.

   Тёмная «Афиша» - не серый, а тёмное дерево: тот же тёплый тон,
   вывернутый. Холодный графит рядом с кирпичным акцентом выглядит
   как две разные темы, случайно оказавшиеся на одной странице. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#161310;
    --surface:#211d18;
    --surface-2:#2b251e;
    --surface-3:#392f25;
    --text:#f7efe2;
    --text-2:#cdc0ad;      /* 8.5:1 на --surface-2, 5.0:1 на самой светлой карточке масти */
    --text-3:#9a8e7d;      /* 4.7:1 на --surface-2 */
    --border:#3a3125;
    --border-2:#4d4132;
    --accent:#ff7a5c;      /* 7.2:1 надписью по тёмному фону */
    --accent-soft:#3a201a;
    --accent-text:#ffab95; /* 8.2:1 на --accent-soft */
    --on-accent:#1a0d09;
    --ok:#5fce9b;
    --ok-soft:#173327;
    --warn:#eab259;
    --warn-soft:#3a2a11;
    --danger:#ff8873;
    --danger-soft:#3d1f1a;
    --shadow:0 1px 2px rgba(0,0,0,.34), 0 14px 34px -20px rgba(0,0,0,.75);
    --shadow-sm:0 1px 3px rgba(0,0,0,.4);
    color-scheme:dark;
  }
}
/* Тот же набор, но по явному выбору человека. Дублируется намеренно:
   объединить селекторы через запятую нельзя - @media и обычное
   правило живут в разных плоскостях, и браузер, не понявший медиа,
   выбросил бы вместе с ним и явный выбор. */
:root[data-theme="dark"]{
    --bg:#161310;
    --surface:#211d18;
    --surface-2:#2b251e;
    --surface-3:#392f25;
    --text:#f7efe2;
    --text-2:#cdc0ad;
    --text-3:#9a8e7d;
    --border:#3a3125;
    --border-2:#4d4132;
    --accent:#ff7a5c;
    --accent-soft:#3a201a;
    --accent-text:#ffab95;
    --on-accent:#1a0d09;
    --ok:#5fce9b;
    --ok-soft:#173327;
    --warn:#eab259;
    --warn-soft:#3a2a11;
    --danger:#ff8873;
    --danger-soft:#3d1f1a;
    --shadow:0 1px 2px rgba(0,0,0,.34), 0 14px 34px -20px rgba(0,0,0,.75);
    --shadow-sm:0 1px 3px rgba(0,0,0,.4);
  color-scheme:dark;
}
:root[data-theme="light"]{color-scheme:light}

*,*::before,*::after{box-sizing:border-box}

/* Атрибут hidden сильнее любого display.

   Браузер прячет hidden правилом display:none с самой низкой силой -
   его перебивает любой наш класс с display:flex или grid. Из-за этого
   «скрытая» заглушка «Здесь появится результат» оставалась на экране
   рядом с историей работ, а карточки стилей однажды показались все
   разом. Ошибка выглядит как «hidden не работает», хотя работает всё
   ровно так, как написано в стандарте. */
[hidden]{display:none !important}
html,body{margin:0;padding:0}
html{
  /* Поворот телефона не должен раздувать шрифт: без этого Safari сам
     увеличивает текст в узких колонках, и вёрстка едет на ровном месте. */
  -webkit-text-size-adjust:100%;text-size-adjust:100%;
}

/* Палец не наводит, палец нажимает. touch-action убирает и лишнюю
   задержку в треть секунды перед нажатием, и зум по двойному тапу,
   от которого страница прыгает в самый неподходящий момент. */
a,button,input,textarea,select,label,summary,
.chip,.seg__b,.stab,.pcard,.tab,.modbar__i,.navitem,.hrow__play{
  touch-action:manipulation;
}
body{
  font-family:var(--font);
  /* Шестнадцать, а не пятнадцать: «Афиша» - про крупный текст.
     Большинство размеров в файле проставлены в пикселях по месту, так
     что этот кегль достаётся тому, что не описано отдельно, - абзацам
     подсказок, спискам, содержимому раскрывашек. */
  font-size:16px;
  line-height:1.55;
  color:var(--text);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  overscroll-behavior-y:none;
}
a{color:inherit;text-decoration:none}
button,input,textarea,select{font:inherit;color:inherit}
/* Заголовки - с засечками и крупно. Это главный признак «Афиши»:
   страница узнаётся по первой строке, ещё до того как прочитана.
   Отрицательный трекинг - потому что Georgia в крупном кегле стоит
   разреженно и заголовок рассыпается на отдельные буквы. */
h1,h2,h3{margin:0;font-family:var(--font-head);font-weight:700;letter-spacing:-.02em;line-height:1.15}
h1{font-size:40px;letter-spacing:-.03em}
h2{font-size:25px}
h3{font-size:18px}
p{margin:0}

/* ============================================================
   Кнопки. БАЗА ИДЁТ ПЕРВОЙ, и это не вкусовщина.

   Пока .btn был объявлен ниже своих же модификаторов, он их молча
   съедал: у правил одинаковый вес, и при равенстве побеждает то,
   что записано позже. Красная кнопка Яндекса выходила белой,
   прозрачная .btn--ghost - серой, мелкая .btn--sm - обычной.
   Внешне это выглядело как «не применился класс», хотя класс стоял
   на месте. Всё, что уточняет .btn, обязано идти после него.
   ============================================================ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:0 16px;height:var(--ctl);border-radius:var(--radius-sm);
  border:0;background:var(--surface-2);color:var(--text-2);
  font-family:inherit;font-size:15px;font-weight:700;cursor:pointer;
  white-space:nowrap;
  transition:background .15s ease,color .15s ease;
}
.btn:hover{background:var(--surface-3);color:var(--text)}
.btn--primary{background:var(--accent);color:var(--on-accent)}
.btn--primary:hover{background:var(--accent);color:var(--on-accent);filter:brightness(1.12)}

/* Единственная зелёная кнопка на экране - та, что тратит деньги.
   Так сделано на основном сайте, и там её не приходится искать: глаз
   находит цвет раньше, чем читает подпись. Больше ничего зелёного в
   интерфейсе нет, иначе приём перестаёт работать. */
.btn--go{background:var(--go);color:#fff}

/* ВОЛОСЯНОЙ ШОВ НА ЗАЛИВНЫХ ТАБЛЕТКАХ - и как он лечится.
 *
 * Что видно: по яркой кнопке или чипу проходит светлая полоска в один
 * пиксель. То поперёк, то вдоль, то появляется, то исчезает при смене
 * ширины окна. На бледных кнопках её нет - точнее, она есть, но между
 * двумя почти одинаковыми серыми её не различить.
 *
 * Откуда берётся. Скругление у нас 999px, то есть фигура - таблетка:
 * два круглых торца и прямая середина. Chrome рисует её не одним
 * мазком, а частями. Пока всё лежит по целым пикселям, стыки сходятся
 * идеально. Но у монитора владельца масштаб 125%, и один CSS-пиксель
 * равен 1,25 экранного: любая дробная координата - а они появляются от
 * flex-раскладки, межстрочного и отступов - двигает стык на сотые доли.
 * В этот зазор просвечивает фон. Ни цвет, ни разметка ни при чём: это
 * округление при растеризации.
 *
 * Лечение. Своя плоскость отрисовки: браузер рисует такой элемент одним
 * куском в отдельный слой и только потом кладёт на страницу - швам
 * взяться неоткуда. Раздавать её всем подряд нельзя, каждый слой стоит
 * памяти, поэтому список ровно из тех, у кого заливка яркая и шов
 * заметен: три главные кнопки, опасная, вход Яндексом и выбранный чип.
 * Внешне не меняется ничего. */
.btn--go,
.btn--primary,
.btn--danger,
.btn--ya,
.chip--on,
.seg__b--on{
  transform:translateZ(0);
  backface-visibility:hidden;
}
.btn--go:hover{background:var(--go-dark);color:#fff}

/* ШИРОКОЙ КНОПКЕ РАЗРЕШЕНО ПЕРЕНОСИТЬ НАДПИСЬ.
 *
 * У всех кнопок стоит white-space:nowrap, и это верно для коротких:
 * «Скачать», «Создать ещё» - рвать их по слогам незачем. Но с тех пор
 * как на главную кнопку встала вся сделка целиком («Создать картинку
 * за 25 токенов»), запрет переноса превратился в распорку: на телефоне
 * шириной 337 неразрывная надпись требовала 352 пикселя, растягивала
 * колонку сетки шире экрана - и вся страница уезжала вправо, оставляя
 * зазор слева и обрезанный край справа.
 *
 * Широкая кнопка занимает строку целиком, ей переносить не стыдно:
 * на узком экране надпись встаёт в две строки по центру, на обычном
 * остаётся в одну. */
.btn--wide{width:100%;white-space:normal;min-width:0;line-height:1.25}
.btn--lg{height:var(--ctl-lg);font-size:17px;font-weight:800;letter-spacing:0}
.btn[disabled]{opacity:.55;cursor:not-allowed}
/* Цена приглушена ЦВЕТОМ, а не прозрачностью.

   opacity заводит браузеру отдельный слой поверх кнопки, и на экранах
   с дробным масштабом (125% в Windows - самый обычный случай) по краю
   этого слоя проступает волосяная линия прямо поперёк цифр. Полупро-
   зрачная краска даёт тот же вид и слоя не создаёт. */
.btn__price{
  margin-left:auto;font-size:13px;font-weight:700;color:inherit;
  padding-left:10px;font-variant-numeric:tabular-nums;
}
.btn--go .btn__price{color:rgba(255,255,255,.85)}
.btn--primary .btn__price{color:color-mix(in srgb,var(--on-accent) 85%,transparent)}

/* ============================================================
   Каркас
   ============================================================ */
/* Полоса плеера висит поверх страницы, поэтому место под неё страница
   отдаёт сама. Иначе последняя строка списка оказывается под полосой, и
   человек, дослушав песню, не может нажать на неё же. */
.app{min-height:100vh;padding-bottom:var(--player-h)}
.main{padding:28px 32px 64px}
/* ШИРИНЫ У СОДЕРЖИМОГО НЕТ - ЕЁ ДЕЛЯТ МЕЖДУ СОБОЙ ОБЛАСТИ ВНУТРИ.

   Здесь стоял потолок с центровкой, и на мониторе 2307 он давал по
   470 пикселей пустого поля с каждой стороны: страница превращалась
   в остров, хотя слева и так уже стоит меню. Любое другое число
   давало то же самое, только с одной стороны.

   Теперь у всех разделов одна левая граница, сразу за меню, а ширину
   делят области рабочего экрана - панель промта и полка результата
   (см. «Экран задачи»). Читаемость держат пределы внутри областей,
   а не поля по краям. */
/* Обычные разделы - витрина, токены, работы, свой голос - живут в
   колонке 1280 и прижаты влево. Растянутые во всю ширину монитора, они
   выглядели полосой: строка баланса в две тысячи пикселей, кнопка
   оплаты через весь экран, а читать в них нечего - там пять строк.

   Рабочие экраны (генерация, чат, пульт) ширину используют по делу и
   потолка не имеют: там своя раскладка на три области, и она сама
   решает, кому сколько. */
/* ПО ЦЕНТРУ, НО С ПОТОЛКОМ.
 *
 * Раньше макет был прижат к левому краю - и правильно: с потолком и
 * центровкой на большом мониторе оставалось по полкилометра пустоты с
 * каждой стороны, а слева и так стоит меню, из-за которого страница
 * ещё и уезжала вбок.
 *
 * На тридцати двух дюймах это перестало работать иначе: содержимое
 * прибито к левому краю, а справа зияет треть экрана. Владелец примерил
 * варианты прямо в браузере (tools/centr.js) и выбрал этот: тот же
 * потолок 1280, но по центру. На широком мониторе выходит по 381
 * пикселю поля с каждой стороны - симметрично и спокойно; на обычном
 * ноутбуке содержимое до потолка не дорастает, и центровка там не
 * делает ничего. */
.wrap,.wrap--wide{max-width:1280px;margin:0 auto}

/* ПОЛЯ И КНОПКИ НЕ ТЯНУТСЯ НА ВСЮ ШИРИНУ.

   Ширина нужна каталогу стилей и спискам работ, а не строке ввода:
   править текст в поле шириной в полтора метра невозможно - глаз
   теряет начало следующей строки. Кнопка «Перейти к оплате» по той же
   причине растягивалась на тысячу семьсот пикселей и выглядела нелепо. */
.main textarea,.main .input,.main .seg,.main .btn--wide,.main .findrow{max-width:1100px}
.sfind{display:block;width:100%}
/* Отступы страницы не растут вместе с монитором: они и были той самой
   пустотой у краёв. Чуть больше воздуха сверху - и хватит. */
@media (min-width:1500px){ .main{padding:32px 32px 72px} }

/* --- Сайдбар (десктоп) --- */
.sidebar{
  position:fixed;inset:0 auto 0 0;width:var(--sidebar);
  background:var(--surface);border-right:1px solid var(--border);
  display:flex;flex-direction:column;z-index:30;
}
.sidebar__brand{
  display:flex;align-items:center;gap:10px;
  padding:18px 18px 14px;
  font-family:var(--font-head);font-weight:700;font-size:19px;letter-spacing:-.02em;
}
/* Круг, а не квадратик: буква в круге читается как печать на афише.
   Это единственное место, где логотип вообще что-то говорит о сервисе. */
.brand__mark{
  width:30px;height:30px;border-radius:50%;flex:0 0 auto;
  background:var(--accent);color:var(--on-accent);
  display:grid;place-items:center;font-size:14px;font-weight:700;
}
.sidebar__label{
  padding:14px 18px 6px;font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3);
}
.sidebar__nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:0 10px 10px}
/* Просвет между пунктами обязателен.

   Без него подсветка соседних пунктов смыкается в одну сплошную
   плашку, и вместо двух кнопок глаз видит один слипшийся блок -
   особенно когда наведение стоит рядом с выбранным пунктом. */
.navitem{
  display:flex;align-items:center;gap:11px;min-width:0;min-height:var(--ctl-sm);
  margin-bottom:3px;
  padding:0 14px;border-radius:var(--radius-sm);
  color:var(--text-2);font-size:15px;font-weight:500;
  transition:background .12s,color .12s;
}
.navitem__t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.navitem:hover{background:var(--surface-2);color:var(--text)}
.navitem--on{background:var(--accent-soft);color:var(--accent-text);font-weight:700}
.navitem--off{opacity:.5;cursor:default}
.navitem--off:hover{background:transparent;color:var(--text-2)}
.navitem .ico{flex:0 0 auto}
.navitem__soon{
  margin-left:auto;flex:0 0 auto;
  font-size:10.5px;font-weight:600;letter-spacing:.03em;
  color:var(--text-3);border:1px solid var(--border-2);
  padding:1px 6px;border-radius:var(--radius-sm);white-space:nowrap;
}
.sidebar__foot{border-top:1px solid var(--border);padding:10px}

.purse{
  display:flex;align-items:center;gap:10px;padding:10px;margin-top:8px;
  border-radius:var(--radius-sm);background:var(--surface-2);
}
.purse__sum{font-weight:700;font-size:16px;letter-spacing:-.01em}
.purse__cap{font-size:11.5px;color:var(--text-3);line-height:1.2}
.purse__add{
  /* Была 28 - в неё промахивались. Сорок - нижняя граница мишени
     для пальца, ниже неё попадание становится делом удачи. */
  margin-left:auto;width:var(--ctl-sm);height:var(--ctl-sm);border-radius:var(--radius-sm);
  border:1px solid var(--border-2);background:var(--surface);
  display:grid;place-items:center;cursor:pointer;flex:0 0 auto;
}
.purse__add:hover{border-color:var(--accent);color:var(--accent)}

.account{
  display:flex;align-items:center;gap:10px;padding:9px 10px;margin-top:4px;
  border-radius:var(--radius-sm);cursor:pointer;
}
.account:hover{background:var(--surface-2)}
.avatar{
  width:28px;height:28px;border-radius:50%;flex:0 0 auto;
  background:var(--surface-3);display:grid;place-items:center;
  font-size:12px;font-weight:600;color:var(--text-2);
}
.account__box{min-width:0;display:flex;flex-direction:column}
.account__name{font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.account__sub{font-size:11.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
img.avatar{object-fit:cover}
.signin__note{font-size:11.5px;color:var(--text-3);line-height:1.4;padding:8px 4px 2px}

/* Две двери оплаты */
.pays{display:flex;flex-direction:column;gap:8px}
.paydiv{display:flex;align-items:center;gap:10px;margin:2px 0;color:var(--text-3);font-size:12px}
.paydiv::before,.paydiv::after{content:"";flex:1;height:1px;background:var(--border)}
.btn--ghost{background:transparent}
.btn--ghost:hover{background:var(--surface-2)}

/* Вход через Яндекс - фирменным красным.

   Это не украшательство: человек отдаёт доступ к своей почте чужому
   сайту, и решается он на это по узнаванию. Знакомая красная кнопка
   говорит «это тот самый Яндекс» быстрее любой подписи, а серая
   такая же, как все остальные, заставляет вчитываться и сомневаться.

   Цвет захардкожен и не берётся из токенов темы намеренно: он
   принадлежит не нам, и в тёмной теме тоже должен остаться собой. */
.btn--ya{
  background:#fc3f1d;color:#fff;font-weight:700;
}
/* Отступ нужен только в подвале меню, где кнопка идёт сразу за
   переключателем темы. На других страницах у неё своё окружение. */
.sidebar__foot .btn--ya{margin-top:8px}
.btn--ya:hover{background:#e63512;color:#fff}
.btn--ya svg{color:#fff}

.down{display:flex;gap:10px;padding:13px 15px;border-radius:var(--radius);
  background:var(--warn-soft);color:var(--warn);font-size:13.5px;line-height:1.5}
.down .ico{flex:0 0 auto;margin-top:2px}

/* ============================================================
   Чат
   ============================================================ */
/* Разговор - это текст, а текст в строке шириной в монитор не читается:
   глаз проходит строку и теряет начало следующей. Тысяча двести - тот
   же порядок, что у панели промта на соседней странице. */
.chat{display:flex;flex-direction:column;gap:12px;max-width:1200px}
.chat__log{
  display:flex;flex-direction:column;gap:10px;
  min-height:420px;max-height:66vh;overflow-y:auto;
  padding:18px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius);
}
.msg{
  max-width:min(82%, 900px);padding:12px 18px;border-radius:var(--radius);
  font-size:16px;line-height:1.55;white-space:pre-wrap;word-break:break-word;
}
.msg--me{align-self:flex-end;background:var(--accent);color:var(--on-accent);border-bottom-right-radius:var(--radius-xs)}
.msg--ai{align-self:flex-start;background:var(--surface-2);border-bottom-left-radius:var(--radius-xs)}
.msg--wait{align-self:flex-start;background:var(--surface-2);color:var(--text-3)}
/* Полоса «разговор скоро закончится». Спокойная, не тревожная: ничего
   не сломалось и деньги не потеряны - просто у памяти собеседника есть
   край, и о нём сказано заранее. */
.chat__left{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:11px;padding:11px 15px;border-radius:var(--radius);
  background:var(--warn-soft);color:var(--warn);
  font-size:14px;line-height:1.45;
}
.chat__left span{flex:1;min-width:200px}
.chat__left .ico{flex:0 0 auto}
.chat__left .btn{flex:0 0 auto;background:var(--surface)}
.chat__left .btn:hover{background:var(--surface-3)}

/* ============================================================
   КОД В ОТВЕТЕ МОДЕЛИ

   Отдельный блок с шапкой и кнопкой, а не строчки в общем потоке.
   Код отличается от текста тем, что его берут целиком и переносят к
   себе; значит ему нужны моноширинный шрифт, сохранённые отступы,
   собственная прокрутка вбок и кнопка «копировать» на видном месте.
   ============================================================ */
.code{
  margin:10px 0;border-radius:var(--radius);overflow:hidden;
  background:var(--surface);border:1px solid var(--border);
}
.code__top{
  display:flex;align-items:center;gap:10px;
  padding:6px 8px 6px 12px;background:var(--surface-2);
  border-bottom:1px solid var(--border);
}
.code__lang{
  font-size:11.5px;font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;color:var(--text-3);
}
.code__copy{
  margin-left:auto;height:28px;padding:0 11px;cursor:pointer;
  border:0;border-radius:var(--radius-sm);background:var(--surface);
  font-family:inherit;font-size:12.5px;font-weight:700;color:var(--text-2);
  white-space:nowrap;
}
.code__copy:hover{background:var(--surface-3);color:var(--text)}
.code__copy--ok{background:var(--ok-soft);color:var(--ok)}

/* Длинная строка кода не должна растягивать пузырь: она прокручивается
   внутри своего блока, а разговор остаётся на месте. */
.code pre{
  margin:0;padding:12px 14px;overflow-x:auto;
  font-family:var(--mono);font-size:12.5px;line-height:1.55;
  white-space:pre;color:var(--text);
}
.code code{font:inherit;color:inherit}

/* Слово в кавычках - имя файла или функции. Тихая подсветка: это
   уточнение внутри фразы, а не отдельный объект. */
.code--in{
  padding:1px 5px;border-radius:var(--radius-xs);
  background:var(--surface-2);border:1px solid var(--border);
  font-family:var(--mono);font-size:.92em;
}
.msg--me .code--in{background:rgba(255,255,255,.16);border-color:transparent;color:inherit}

.chat__bar{
  padding:14px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius);
}
/* Ряд моделей убран из чата вместе с выбором. Осталась одна тихая
   кнопка над перепиской - «начать заново». */
.chat__top{display:flex;align-items:center;gap:10px;justify-content:flex-end;margin-bottom:9px}

/* Прошлые разговоры - тихой строкой под полем ввода. Их редко
   открывают, но знать, что они целы, важно всегда. */
.chat__old{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:11px}
.chat__old-t{margin-right:auto;font-size:12.5px;color:var(--text-3)}
.chat__top .chat__old-t{margin-right:0}
/* ---------- Строка ввода ----------

   Одна рамка на поле и кнопку, а не два предмета в ряд.

   Раньше это были textarea и кнопка рядом, каждая со своим
   скруглением. Пока сообщение в одну строку, ряд выглядел ровно; но
   поле растёт по мере набора, а кнопка нет - и к пятой строке рядом с
   высоким полем висел маленький квадратик, приклеенный к нижнему
   краю. Рамка вокруг обоих снимает вопрос: это одно место, куда пишут
   и откуда отправляют.

   Рамку рисует контейнер, а не поле: подсветка при наборе должна
   обводить всё вместе, иначе внутри рамки загорается вторая. */
.chat__form{
  background:var(--surface);
  border:1.5px solid var(--border);border-radius:var(--radius);
  transition:border-color .15s ease,box-shadow .15s ease;
}
.chat__form:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}

/* Поле - без своей рамки и фона: они уже есть у контейнера.
   Шестнадцать пикселей не для красоты: на меньшем кегле Safari на
   айфоне сам увеличивает страницу при попадании в поле, и разговор
   уезжает за край экрана. */
/* Селектор с двумя классами намеренно: выше по странице стоит
   `.main textarea{max-width:1100px}` - ограничение для полей в потоке
   страницы. Здесь оно вредит: поле лежит внутри рамки, и обрезанное по
   1100 оно оставляло бы справа от себя пустую полосу рамки. */
.chat__form .chat__q{
  display:block;width:100%;max-width:none;
  min-height:26px;max-height:190px;
  padding:13px 16px 4px;
  border:0;background:transparent;color:var(--text);
  font-family:inherit;font-size:16px;line-height:1.5;
  resize:none;overflow-y:auto;
}
.chat__q:focus{outline:none}
.chat__q::placeholder{color:var(--text-3)}
.chat__q:disabled{color:var(--text-3);-webkit-text-fill-color:var(--text-3);opacity:1}

/* Нижний ряд рамки. Служебных кнопок слева у нас нет, поэтому здесь
   только отправка - и она прижата вправо, как во всех чатах. */
.chat__act{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 8px 8px}
.chat__send{
  flex:0 0 auto;width:var(--ctl-sm);height:var(--ctl-sm);
  display:grid;place-items:center;cursor:pointer;
  border:0;border-radius:var(--radius-sm);
  background:var(--accent);color:var(--on-accent);
  transition:background .14s ease,color .14s ease,filter .14s ease;
}
.chat__send:hover{filter:brightness(1.1)}
/* Пустое отправлять некуда, и кнопка об этом говорит заранее - серым,
   а не отказом после нажатия. */
.chat__send:disabled{background:var(--surface-2);color:var(--text-3);cursor:default;filter:none}
/* Пока ответ идёт: то же кольцо, что и на экране задачи. Заводить
   вторую вертушку ради одной кнопки незачем. */
.chat__send--busy{background:var(--surface-2);cursor:default;filter:none}
.chat__send--busy .ico{display:none}
.chat__send--busy::before{
  content:"";width:17px;height:17px;border-radius:50%;
  border:2px solid var(--border-2);border-top-color:var(--accent);
  animation:ring 800ms linear infinite;
}
@media (prefers-reduced-motion:reduce){ .chat__send--busy::before{animation:none} }

@media(max-width:899.98px){.chat__log{max-height:52vh}.msg{max-width:92%}}

/* ============================================================
   Форма песни: сегменты, слайдеры, сворачиваемые блоки, треки
   ============================================================ */
.fwrap[hidden]{display:none}

/* Переключатель из двух-трёх кнопок. На основном сайте такие кнопки
   стоят просто в ряд, без подложки-корытца, и выбранная заливается
   чернилами. Корытце добавляло третий оттенок серого в блок, где их
   и так два. */
.seg{display:flex;gap:8px}
.seg__b{
  flex:1;height:var(--ctl);padding:0 12px;border:none;border-radius:var(--radius-sm);
  cursor:pointer;background:var(--surface-2);
  font-family:inherit;font-size:15px;font-weight:700;color:var(--text-2);
  transition:background .15s ease,color .15s ease;
}
.seg__b:hover{background:var(--surface-3);color:var(--text)}
.seg__b--on{background:var(--accent);color:var(--on-accent)}
.seg__b--on:hover{background:var(--accent);color:var(--on-accent)}

/* Вторичные чипы - ниже основных, но по-прежнему одной высоты между
   собой: разнобой в одном ряду заметнее, чем разница между рядами. */
.chips--soft{margin-top:8px}
/* Тише основных не ростом, а кеглем и цветом: высота у всего, во что
   тычут пальцем, одна - иначе ряд выходит ступенькой, а в мелкое
   промахиваются. Раньше здесь стояли 32 и 30 числом мимо переменной. */
.chips--soft .chip{height:var(--ctl-sm);padding:0 13px;font-size:13.5px}
.chip--x{height:var(--ctl-sm);padding:0 13px;font-size:13px}

.rangerow{display:flex;align-items:center;gap:10px}
.rangerow input[type=range]{flex:1;accent-color:var(--accent)}

/* Фон белый, а не серый: внутри лежат чипы и поля, а они сами
   светло-серые - на сером фоне их просто не видно. */
.fold{
  border:1px solid var(--border);border-radius:var(--radius);
  margin:16px 0 0;background:var(--surface);
}
.fold>summary{
  padding:13px 18px;cursor:pointer;font-size:15px;font-weight:700;
  color:var(--text-2);list-style:none;
}
.fold>summary::-webkit-details-marker{display:none}
.fold>summary::before{content:"▸ ";color:var(--text-3)}
.fold[open]>summary::before{content:"▾ "}
.fold>summary svg{vertical-align:-2px;margin-right:4px;opacity:.75}
.fold__in{padding:2px 18px 16px}
/* Приписка перечисляет, что внутри: без неё строку не открывают -
   «подробнее» само по себе ни о чём не говорит. */
.fold__note{display:block;margin-top:2px;font-size:12.5px;font-weight:400;color:var(--text-3)}

/* Подтверждение списания. Намеренно шумное: это последняя точка,
   где человек может передумать бесплатно. */
.ask{
  margin-top:10px;padding:13px 14px;border-radius:var(--radius);
  background:var(--warn-soft);border:1px solid var(--warn);
}
.ask__t{font-size:14.5px;color:var(--text);line-height:1.45}
.ask__s{margin-top:6px;font-size:12.5px;color:var(--text-2);line-height:1.5}
.ask__row{display:flex;gap:9px;flex-wrap:wrap;margin-top:12px}

/* Панель под текстом, который написал ИИ. Не рамка вокруг текста, а тихая
   строка под ним: сам текст живёт в обычном поле и правится как свой. */
.lyrpanel{margin-top:9px}
.lyrpanel__t{font-size:12.5px;color:var(--text-3);margin-bottom:8px}

/* Две кнопки делят строку поровну, третья уходит вниз во всю ширину.
   Ширина считается флексом, а не сеткой: когда «Другой вариант» скрыт
   (вариант всего один), соседка просто занимает освободившееся место,
   и дырки в раскладке не остаётся. */
.lyrpanel__row{display:flex;gap:8px;flex-wrap:wrap}
.lyrpanel__row .btn{flex:1 1 0;min-width:132px;justify-content:center}
.lyrpanel__row .btn--full{flex:1 1 100%}

/* Мелкая кнопка - для действий рядом с полем, не для главных решений */
.btn--sm{height:var(--ctl-sm);padding:0 13px;font-size:13px;border-radius:var(--radius-sm)}
.btn--sm .btn__price{margin-left:5px;font-size:12px}

/* Взведённая платная кнопка: следующее нажатие спишет токены.
   Цвет предупреждающий, а не тревожный - человек ничего не сломал,
   он просто ещё не подтвердил. */
.btn--armed{
  background:var(--warn-soft);border-color:var(--warn);color:var(--warn);
  font-weight:600;
}
.btn--armed .btn__price{color:color-mix(in srgb,var(--warn) 60%,transparent)}
.btn--armed svg{display:none}

/* ГЛАВНАЯ ЗЕЛЁНАЯ КНОПКА ВЗВОДИТСЯ, НЕ МЕНЯЯ ЦВЕТА НА ЖЁЛТЫЙ.

   Жёлтое предупреждение здесь читалось бы как «что-то не так», а не
   так всё: человек всё сделал правильно, ему осталось подтвердить.
   Кнопка просто темнеет и переименовывается в то, что сейчас
   произойдёт, а кольцо вокруг показывает, что она ждёт ответа.

   Правило прописано и для наведения тоже, и это не перестраховка:
   без него подсветка мыши перебивала взвод по силе селектора, и
   кнопка под курсором выглядела как обычная. Состояние, зависящее от
   того, где мышь, - это не состояние. */
.btn--go.btn--armed,
.btn--go.btn--armed:hover{
  background:var(--go-dark);color:#fff;
  box-shadow:0 0 0 3px color-mix(in srgb,var(--go) 28%,transparent);
}

/* ============================================================
   Пилюля выбора (движок)

   Стоит в углу над формой и почти не занимает места: это не настройка
   песни, а отметка «каким инструментом пишем». Развёрнутый список даёт
   к каждому названию строчку смысла - без неё выбирать между «V4.5ALL»
   и «V4.5+» человек не станет и не тронет список никогда.
   ============================================================ */
.formtop{display:flex;justify-content:flex-end;margin:-2px 0 12px}
.formtop .fwrap:not([hidden]){display:inline-block}

.pick{position:relative}
.pick__btn{
  display:inline-flex;align-items:center;gap:7px;
  height:var(--ctl-sm);padding:0 12px;border-radius:var(--radius-sm);cursor:pointer;
  border:0;background:var(--surface-2);
  font-family:inherit;font-size:13px;font-weight:700;color:var(--text-2);
  transition:border-color .12s,color .12s;
}
.pick__btn:hover{background:var(--surface-3);color:var(--text)}
.pick__caret{
  width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid currentColor;opacity:.6;
}
.pick__menu{
  position:absolute;top:calc(100% + 6px);right:0;z-index:40;
  min-width:270px;padding:5px;
  /* За край экрана не вылезаем ни при какой ширине окна. Потолок
     считается от самого экрана, а не от родителя: список висит поверх
     страницы, и границы родителя ему не указ. */
  max-width:calc(100vw - 28px);
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);
}
.pick__opt{
  display:block;width:100%;text-align:left;cursor:pointer;
  /* Пункт в две строки - не таблетка: скругление в полвысоты
     срезало бы у подписи начало и конец. */
  padding:9px 12px;border:0;border-radius:var(--radius-xs);background:transparent;
}
.pick__opt:hover{background:var(--surface-2)}
.pick__opt--on{background:var(--accent-soft)}
.pick__opt-t{display:block;font-size:14px;font-weight:600}
.pick__opt--on .pick__opt-t{color:var(--accent-text)}
.pick__opt-s{display:block;font-size:12px;color:var(--text-3);margin-top:1px}

/* НА УЗКОМ ЭКРАНЕ СПИСОК ОСТАЁТСЯ У ПРАВОГО КРАЯ.
 *
 * Здесь стояло left:0 - список отвязывался от правого края и начинал
 * расти вправо от кнопки. А кнопка выбора движка стоит в правом углу
 * формы, и расти ей туда некуда: на телефоне список вылезал за экран
 * на полтораста пикселей, обрезая описания на полуслове - «новее
 * всех, мо…», «выразительнь…».
 *
 * Потолок ширины стоит и в общем правиле тоже, не только здесь: он
 * страхует от того же самого на любой ширине окна, а не только на
 * тех, что мы вспомнили. */
@media(max-width:560px){
  .pick__menu{right:0;left:auto;min-width:0;width:max-content}
}

/* Готовые треки */
.track{
  display:flex;gap:14px;padding:14px;margin-bottom:12px;
  border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);
}
.track__cov{
  /* Обложка - не таблетка: у квадрата 999 даёт круг, и картинку
     обрезает по краям как раз там, где обычно лицо или надпись. */
  width:104px;height:104px;flex:0 0 auto;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);
}
.track__cov img{width:100%;height:100%;object-fit:cover;display:block}
.track__b{flex:1;min-width:0;display:flex;flex-direction:column}
.track__t{font-family:var(--font-head);font-weight:700;font-size:18px;letter-spacing:-.02em}
.track__s{font-size:12.5px;color:var(--text-3);margin:3px 0 10px}
.track__b audio{width:100%}
.track__b .fold{margin:10px 0 0}
.track__lyr{
  padding:0 14px 12px;font-size:13px;line-height:1.6;color:var(--text-2);
  white-space:pre-wrap;max-height:260px;overflow-y:auto;
}
@media(max-width:600px){
  .track{flex-direction:column}
  .track__cov{width:100%;height:auto;aspect-ratio:1}
}

/* Здоровье моделей */
.mh{width:100%;border-collapse:collapse;font-size:13.5px;margin-top:10px}
.mh td{padding:8px 0;border-top:1px solid var(--border)}
.mh .m{font-family:var(--mono);font-size:12.5px}
.pill{font-size:11.5px;font-weight:600;padding:2px 9px;border-radius:var(--radius-sm);white-space:nowrap}
.pill--ok{background:var(--ok-soft);color:var(--ok)}
.pill--down{background:var(--danger-soft);color:var(--danger)}

/* --- Верхняя панель (мобильная) --- */
.topbar{display:none}

/* --- Лента модулей (планшет и ноутбук) ---
   Между сайдбаром и нижними вкладками есть полоса ширин, где сайдбар
   уже мешает, а четырёх вкладок снизу мало: модулей больше. Здесь
   работает горизонтальная лента под шапкой. */
.modbar{display:none}

/* --- Нижние вкладки (мобильные) --- */
.tabbar{display:none}

@media (min-width:900px){
  .main{margin-left:var(--sidebar);transition:margin-left .16s}

  /* Свёрнутое меню отдаёт почти двести пикселей рабочей области.
     Значки остаются на месте, подписи прячутся - привычка к позиции
     пунктов не ломается, а места становится заметно больше. */
  body.nav--min .sidebar{width:var(--sidebar-min)}
  body.nav--min .main{margin-left:var(--sidebar-min)}
  body.nav--min .navitem__t,
  body.nav--min .navitem__soon,
  body.nav--min .sidebar__label,
  body.nav--min .brand__t,
  body.nav--min .purse > div,
  body.nav--min .purse__add,
  body.nav--min .account__box,
  body.nav--min .signin__note,
  body.nav--min .navfold__t{display:none}
  body.nav--min .navitem,
  body.nav--min .purse,
  body.nav--min .account,
  body.nav--min .sidebar__foot .btn{justify-content:center;padding-left:0;padding-right:0}
  body.nav--min .sidebar__brand{justify-content:center;padding-left:0;padding-right:0}
}

/* Кнопка сворачивания. Внизу списка, тихая: ей пользуются один раз
   и забывают, что она есть. */
.navfold{
  display:flex;align-items:center;gap:11px;width:100%;
  margin-top:6px;min-height:var(--ctl-sm);padding:0 14px;border:0;border-radius:var(--radius-sm);
  background:transparent;color:var(--text-3);font:inherit;font-size:13.5px;
  cursor:pointer;
}
.navfold:hover{background:var(--surface-2);color:var(--text-2)}
.navfold svg{flex:0 0 auto;transition:transform .16s}
body.nav--min .navfold svg{transform:rotate(180deg)}
@media (max-width:899.98px){ .navfold{display:none} }
@media (max-width:899.98px){
  .sidebar{display:none}
  .topbar{
    display:flex;align-items:center;gap:10px;
    position:sticky;top:0;z-index:30;
    padding:10px 16px;
    background:var(--surface);border-bottom:1px solid var(--border);
  }
  .topbar__brand{display:flex;align-items:center;gap:9px;min-height:var(--ctl-sm);font-family:var(--font-head);font-weight:700;font-size:17px}
  .topbar__purse{
    margin-left:auto;display:flex;align-items:center;gap:7px;
    background:var(--surface-2);border-radius:var(--radius-sm);
    min-height:var(--ctl-sm);padding:0 15px;
    font-size:14px;font-weight:700;
  }

  .modbar{
    display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;
    position:sticky;top:53px;z-index:29;
    padding:8px 16px;
    background:var(--surface);border-bottom:1px solid var(--border);
  }
  .modbar::-webkit-scrollbar{display:none}
  .modbar__i{
    display:inline-flex;align-items:center;gap:7px;flex:0 0 auto;
    min-height:var(--ctl-sm);padding:0 15px;border-radius:var(--radius-sm);white-space:nowrap;
    background:var(--surface-2);color:var(--text-2);
    font-size:14px;font-weight:600;
  }
  .modbar__i--on{background:var(--accent-soft);color:var(--accent-text);font-weight:600}
  .tabbar{
    display:grid;grid-template-columns:repeat(4,1fr);
    position:fixed;inset:auto 0 0 0;z-index:40;height:var(--tabbar);
    background:var(--surface);border-top:1px solid var(--border);
    padding-bottom:env(safe-area-inset-bottom);
  }
  .tab{
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    font-size:11px;font-weight:600;color:var(--text-3);
  }
  .tab--on{color:var(--accent)}
  .main{padding:18px 16px calc(var(--tabbar) + 28px)}
}

/* ============================================================
   Общие элементы
   ============================================================ */
.head{margin-bottom:26px}
/* Ширина в символах, а не в пикселях: строка длиннее шестидесяти знаков
   заставляет глаз искать начало следующей. При крупном кегле это
   особенно заметно. */
.head p{color:var(--text-2);margin-top:8px;font-size:16px;max-width:60ch;line-height:1.5}

.card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow-sm);
}

.ico{display:inline-block;vertical-align:-2px}

/* ============================================================
   Витрина модулей
   ============================================================ */
.grid{
  display:grid;gap:16px;
  grid-template-columns:repeat(auto-fill,minmax(258px,1fr));
}

/* КАРТОЧКА УСЛУГИ ЦЕЛИКОМ В СВОЁМ ЦВЕТЕ.

   Услуга - это настроение, а не строка каталога: «песня на свадьбу» и
   «убрать фон» человек различает по масти раньше, чем прочитает
   название. Цвет приходит данными - из modules.php через inline
   --tint, - а не прописан здесь по одному правилу на модуль: иначе
   новый модуль приходилось бы заводить в двух местах, и второе
   рано или поздно забыли бы.

   Без цвета карточка обязана выглядеть прилично: запасное значение
   --surface-2 - обычная бумажная плашка, ровно как было. */
.mod{
  display:flex;flex-direction:column;gap:10px;
  padding:22px;background:var(--tint,var(--surface-2));
  border:1px solid transparent;border-radius:var(--radius);
  transition:transform .14s,box-shadow .14s;
}
a.mod:hover{transform:translateY(-3px);box-shadow:var(--shadow)}
.mod--off{opacity:.62}
/* Значок в круге. Подложка полупрозрачно-белая, а не цветом из
   палитры: она обязана сработать поверх ЛЮБОГО оттенка карточки,
   а фиксированный цвет с половиной мастей поспорит. */
.mod__ico{
  width:44px;height:44px;border-radius:50%;
  background:rgba(255,255,255,.6);color:var(--text);
  display:grid;place-items:center;
}
.mod--off .mod__ico{background:rgba(255,255,255,.45);color:var(--text-2)}
.mod__title{font-family:var(--font-head);font-weight:700;font-size:22px;letter-spacing:-.025em;line-height:1.15}
.mod__short{font-size:14.5px;color:var(--text-2);line-height:1.45;flex:1}
/* Черта отделяет цену от описания. Полупрозрачная по той же причине,
   что и подложка значка: она ложится на цвет карточки. */
.mod__foot{
  display:flex;align-items:center;gap:8px;
  margin-top:2px;padding-top:12px;border-top:1px solid rgba(0,0,0,.10);
}
.price{font-size:15px;font-weight:700}
.price small{font-weight:400;color:var(--text-2)}
.badge{
  display:inline-flex;align-items:center;min-height:28px;
  font-size:12.5px;font-weight:700;letter-spacing:.01em;
  padding:0 12px;border-radius:var(--radius-sm);
  background:rgba(0,0,0,.07);color:var(--text-2);
}

/* В ТЁМНОЙ ТЕМЕ МАСТЬ РАБОТАЕТ ИНАЧЕ.

   Тинты подобраны бледными - на бумаге они и должны быть бледными. В
   тёмной теме бледная заливка выдала бы белую карточку посреди тёмной
   страницы, а тёмные чернила на ней перестали бы читаться. Поэтому
   там от масти остаётся примесь: цвет подмешивается к тёмной плашке,
   и карточки по-прежнему различаются, но темы остаются двумя темами.

   Первая строка - запасная: браузер, не знающий color-mix, просто её
   и оставит, и получит ровную тёмную карточку без цвета. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .mod{
    background:var(--surface-2);
    background:color-mix(in srgb, var(--tint,var(--surface-2)) 16%, var(--surface-2));
  }
  :root:not([data-theme="light"]) .mod__ico{
    color:var(--tint,var(--text));
    background:rgba(255,255,255,.10);
    background:color-mix(in srgb, var(--tint,#ffffff) 22%, transparent);
  }
  :root:not([data-theme="light"]) .pcard__n{color:var(--tint,var(--text))}
  :root:not([data-theme="light"]) .mod__title{color:var(--tint,var(--text))}
  :root:not([data-theme="light"]) .mod--off .mod__ico{background:rgba(255,255,255,.06)}
  :root:not([data-theme="light"]) .mod__foot{border-top-color:rgba(255,255,255,.13)}
  :root:not([data-theme="light"]) .badge{background:rgba(255,255,255,.09)}
}
:root[data-theme="dark"] .mod{
  background:var(--surface-2);
  background:color-mix(in srgb, var(--tint,var(--surface-2)) 16%, var(--surface-2));
}
/* Масть в кружке значка и в названии. Подмешать её в фон сильнее
   нельзя - вместе с фоном светлеет и текст на нём, а подпись карточки
   уже на пределе 4.5:1. Значок и название - места, где цвет ничему не
   мешает: он там сам себе текст, и контраст к тёмной карточке у любой
   масти выше десяти. Без масти остаётся прежняя белёсая плашка. */
:root[data-theme="dark"] .mod__ico{
  color:var(--tint,var(--text));
  background:rgba(255,255,255,.10);
  background:color-mix(in srgb, var(--tint,#ffffff) 22%, transparent);
}
:root[data-theme="dark"] .pcard__n{color:var(--tint,var(--text))}
:root[data-theme="dark"] .mod__title{color:var(--tint,var(--text))}
:root[data-theme="dark"] .mod--off .mod__ico{background:rgba(255,255,255,.06)}
:root[data-theme="dark"] .mod__foot{border-top-color:rgba(255,255,255,.13)}
:root[data-theme="dark"] .badge{background:rgba(255,255,255,.09)}

/* ============================================================
   Экран задачи: три области - меню, панель промта, полка результата
   ============================================================ */
/* Колонки сетки не раздуваются содержимым.
 *
 * По умолчанию ячейка сетки не даёт себя сузить ниже самого широкого
 * неразрывного куска внутри - и одна длинная надпись растягивает всю
 * страницу шире экрана. Тут это уже случилось однажды: кнопка «Создать
 * картинку за 25 токенов» на телефоне уводила вправо весь сайт.
 * min-width:0 снимает это правило: пусть содержимое ужимается или
 * переносится, но границы страницы держатся. */
.gen{display:grid;gap:20px;align-items:start}
.gen > *{min-width:0}

/* ТРИ ОБЛАСТИ, И ГРАНИЦЫ У НИХ ПОСТОЯННЫЕ.

   Первая область - меню, оно живёт в каркасе и стоит слева. Вторая -
   панель промта, главное рабочее место: чем она шире, тем больше
   стилей видно сразу. Третья - полка результата.

   Полка стоит на своём месте всегда, даже когда работ ещё ни одной.
   Пока её не было до первого заказа, панель промта разъезжалась на
   всю ширину, а после нажатия «Создать» схлопывалась обратно:
   страница перестраивалась под человеком ровно в ту секунду, когда
   он ждал результат. Пустая полка не отнимает место, а показывает,
   куда смотреть через три минуты.

   Ширина полки растёт вместе с экраном, но в границах. Меньше 360 в
   строку работы не помещаются обложка, название и меню; больше 480
   ей уже нечем занять место - там всего один столбец строк. Всё
   остальное забирает панель промта, и пустого поля у края не
   остаётся: на мониторе 2307 это 1475 панели плюс 480 полки.

   Потолок 1600 у панели нужен только сверхшироким мониторам: форма
   в две с половиной тысячи пикселей - уже не рабочее место, а поле.

   Порог 1300, а не 1000: замерял, сколько карточек стиля влезает в
   ряд. На ноутбуке 1280 две области дали бы панели 588 пикселей -
   это три карточки, колодец; одна область на той же машине даёт
   пять. Ниже порога областей две: меню и всё остальное. */
@media (min-width:1300px){
  /* ПАНЕЛЬ ПРОМТА - 880, И ЭТО ЧИСЛО НЕ С ПОТОЛКА.

     Владелец сам нашёл верную ширину: открыл инспектор, сузил окно до
     удобного вида и показал замер - 878 пикселей. Ровно столько же на
     основном сайте: там колонка формы около 880, и в неё встают пять
     карточек стилей. Значит спорить не о чем, ставим 880.

     Всё, что шире, уходит третьей области - полке результата. Она этой
     ширине только рада: в строке работы обложка, название, длительность
     и меню, и чем больше места, тем меньше они жмутся. Пустого поля у
     края при этом не остаётся: панель не растягивается, но и дырки
     после себя не оставляет. */
  .gen{grid-template-columns:minmax(0,880px) minmax(360px,1fr)}
  /* 880 + 20 зазора + 380 полки = 1280 - ровно столько же, сколько у
     всех остальных разделов. Левый и правый края совпадают на любой
     странице, и переход между разделами перестаёт дёргать содержимое. */

  /* ПРИЛИПАЕТ РЕЗУЛЬТАТ, А НЕ ФОРМА, и это принципиально.
     Форма выше экрана - прилипание к ней не даёт вообще ничего, липкий
     блок не может «зависнуть», пока сам не поместился. А вот сцена
     результата низкая, и когда человек прокручивает длинную форму до
     кнопки «Создать», она уезжает вверх за край. Получается: нажал -
     и ничего не произошло. На самом деле произошло, просто в той части
     страницы, которой на экране уже нет: и полоса ожидания, и готовая
     песня, и текст ошибки. Теперь сцена едет следом и всегда на виду. */
  .gen__form{position:static}

  /* Панель прилипает ЦЕЛИКОМ, без своей прокрутки.

     Внутренний скролл здесь был честной попыткой уместить растущий
     список, но давал на странице два колеса: человек крутил мышью,
     попадал курсором в панель и вместо страницы прокручивал список -
     форма при этом стояла. Вместо этого мы держим панель короткой
     (пять свежих работ, остальное - на своей странице), и тогда
     прилипания достаточно: она просто всегда на виду. */
  .stage{position:sticky;top:24px}

  /* Страница заказа: одна колонка, прижатая ВЛЕВО.

     Стояло margin:0 auto - и блок уезжал в середину экрана, оставляя
     поля с обеих сторон. А человек только что смотрел на эту страницу
     с формой слева; когда форма ушла, её место должен занять заказ, а
     не сдвинуться всё разом. Ширину всё равно ограничиваем: строка в
     полторы тысячи пикселей заставляет глаз ехать от обложки к кнопке
     через пустоту. */
  .gen--one{grid-template-columns:minmax(0,1fr);max-width:920px}
  .gen--one .stage{position:static;max-height:none;overflow:visible}

  /* Страницы, где полки результата нет по смыслу (свой голос): область
     одна и делить нечего. Раньше сюда же попадала страница генерации
     без работ, и её форму приходилось центрировать; теперь полка есть
     всегда, а центровки нет нигде - всё прижато влево. */
  .gen--solo{grid-template-columns:minmax(0,1fr)}
}
@media (min-width:1500px){ .gen{gap:26px} .panel{padding:26px} }

/* ПАНЕЛЬ ЗАНИМАЕТ СВОЮ ОБЛАСТЬ ЦЕЛИКОМ, А СТРОКИ ВНУТРИ НЕЁ - НЕТ.

   Поле, его подпись и счётчик - одна вещь, и кончаться они должны в
   одном месте. Пока предел ширины стоял на самом поле, счётчик
   «0 / 200» уезжал к дальнему краю панели и висел в трёхстах
   пикселях от строки, к которой относится. Поэтому предел - на всём
   блоке поля, а не только на вводе.

   Каталог стилей из правила выпадает намеренно: плитки тем полезнее,
   чем больше их в ряду, и лишняя ширина ему на пользу. */
.gen__form{width:100%}
.gen__form .field,
.gen__form .formtop,
.gen__form .fold,
.gen__form .formfoot{max-width:1100px}
.gen__form .field.styles{max-width:none}

.panel{padding:22px;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow-sm)}

.field{margin-bottom:17px}
.field:last-child{margin-bottom:0}
/* Подпись поля - без засечек и без «Афиши»: это указание, что делать,
   а не заголовок. Крупнее прежнего, потому что рядом теперь всё крупнее
   и тринадцать пикселей читались как сноска. */
.field__label{
  display:flex;align-items:baseline;gap:8px;
  font-size:14.5px;font-weight:700;margin-bottom:9px;letter-spacing:-.01em;
}
.field__count{margin-left:auto;font-size:12.5px;color:var(--text-3);font-variant-numeric:tabular-nums}
.field__hint{font-size:13.5px;color:var(--text-3);margin-top:7px;line-height:1.45}

/* Поля - белые, в тонкой рамке, как на основном сайте. Заливка вместо
   рамки смотрелась современнее, но у нас поля стоят на белой панели
   среди серых кнопок, и залитое поле переставало отличаться от
   кнопки: человек видел ряд одинаковых серых прямоугольников и не
   понимал, куда писать, а куда нажимать. Рамка отвечает на это
   мгновенно и не требует ни одного слова подписи. */
textarea.input,input.input{
  width:100%;padding:0 13px;height:var(--ctl);
  background:var(--surface);border:1.5px solid var(--border);
  color:var(--text);font-family:inherit;
  border-radius:var(--radius-sm);font-size:15px;line-height:1.5;
  transition:border-color .15s ease,box-shadow .15s ease;
}
input.input{padding:0 18px}
/* Многострочному полю таблетка не идёт: скруглением в полвысоты она
   отъедает у текста первую и последнюю строку по краям. Поле в одну
   строку остаётся таблеткой - там скругление упирается в высоту. */
textarea.input{min-height:150px;height:auto;padding:13px 16px;resize:vertical;line-height:1.6;border-radius:var(--radius)}
@media (min-width:1500px){ textarea.input{min-height:180px} }
.input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.input::placeholder{color:var(--text-3)}
.input--bad{border-color:var(--danger);background:var(--danger-soft)}

/* Чипы и кнопки-переключатели - одна порода: плоский серый
   прямоугольник, который при выборе заливается чернилами. */
.chips{display:flex;flex-wrap:wrap;gap:7px}
.chip{
  display:inline-flex;align-items:center;justify-content:center;
  height:var(--ctl-sm);padding:0 14px;border-radius:var(--radius-sm);cursor:pointer;
  border:0;background:var(--surface-2);
  font-family:inherit;font-size:14.5px;font-weight:700;color:var(--text-2);
  transition:background .15s ease,color .15s ease;user-select:none;white-space:nowrap;
}
.chip:hover{background:var(--surface-3);color:var(--text)}
.chip--on{background:var(--accent);color:var(--on-accent)}
.chip--on:hover{background:var(--accent);color:var(--on-accent)}

.examples{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.example{
  text-align:left;padding:10px 14px;border-radius:var(--radius);
  border:1px dashed var(--border-2);background:transparent;
  font-size:14px;color:var(--text-2);cursor:pointer;line-height:1.45;
}
.example:hover{border-style:solid;border-color:var(--accent);color:var(--text)}

.formfoot{margin-top:18px;padding-top:16px;border-top:1px solid var(--border)}
.paynote{
  display:flex;align-items:center;gap:6px;
  margin-top:9px;font-size:13.5px;color:var(--text-3);
}
.paynote a{color:var(--accent);font-weight:600;text-decoration:underline;text-underline-offset:3px}
/* Строка про списание - не служебная сноска, а предупреждение: читается
   темнее остальных подписей и переносится, а не жмётся в одну строку. */
.paynote--warn{display:block;color:var(--text-2);line-height:1.5}
.paynote--warn:empty{display:none}
.err{
  display:none;margin-top:9px;padding:10px 13px;border-radius:var(--radius);
  background:var(--danger-soft);color:var(--danger);font-size:14px;
}
.err--on{display:block}

/* На узком экране липнет ТОЛЬКО кнопка. Раньше липким был весь подвал -
   кнопка плюс два абзаца пояснений, и это съедало половину экрана,
   ради которого человек и открыл форму. Предупреждение о сумме уходит
   выше, в поток: прочитать его нужно один раз, а не держать перед
   глазами всё время. Остаток на счету и так виден в шапке. */
@media (max-width:999.98px){
  .formfoot{
    display:flex;flex-direction:column;
    margin:16px -18px -18px;padding:0 18px 10px;border-top:0;
  }
  .formfoot::before{
    content:"";display:block;height:1px;margin:0 -18px 12px;background:var(--border);
  }
  .paynote--warn{order:1;margin:0 0 10px}
  .pays{
    order:2;position:sticky;bottom:calc(var(--tabbar) + 8px + var(--player-h));z-index:20;
    padding:8px 0;background:var(--surface);
  }
  .formfoot .paynote:not(.paynote--warn){order:3;margin-top:8px}
  .btn--lg{height:var(--ctl-lg)}
}

/* ============================================================
   Результат: шесть состояний, все нарисованы заранее
   ============================================================ */
/* Высота - по содержимому, и точка.

   Пятьсот двадцать пикселей стояли, чтобы пустая колонка не выглядела
   обрывом рядом с длинной формой. На деле выходило хуже: две готовые
   песни занимали сто пикселей, а под ними тянулось четыреста пустого
   белого поля. Пустая рамка - честнее короткая. */
.stage{min-height:0}
.gen--one .stage{min-height:0}

/* Ссылка на всю историю - последней строкой списка, тихая. Она не
   действие, а выход: «остальное там». */
.hist__all{
  display:flex;align-items:center;gap:8px;min-height:var(--ctl-sm);
  padding:0 14px;border-radius:var(--radius-sm);
  font-size:14.5px;font-weight:700;color:var(--text-2);
}
.hist__all:hover{background:var(--surface-2);color:var(--text)}
.hist__n{
  margin-left:auto;font-weight:400;font-size:12.5px;color:var(--text-3);
}
.stage{
  padding:18px;
  scroll-margin-top:16px;      /* чтобы подкрутка не упирала блок в самый край */
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);
  display:flex;flex-direction:column;
}
.state{display:none;flex:1;flex-direction:column}
.state--on{display:flex}

/* ПУСТАЯ ПОЛКА - БЕЗ РАМКИ И БЕЗ ФОНА.

   Пока показывать нечего, белая карточка с обводкой обещает содержимое,
   которого нет: глаз читает её как «здесь что-то не загрузилось».
   Достаточно значка и двух строк прямо на фоне страницы - место занято,
   но ничего не обещано. Как только приходит первая работа, полка
   становится обычной панелью с рамкой: там уже есть что держать. */
.stage--blank{
  background:none;border-color:transparent;box-shadow:none;padding:0;
}
.blank{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;text-align:center;padding:48px 20px;color:var(--text-3);
}
/* Значок без плашки: тонкий контур на прозрачном - так он читается как
   пометка места, а не как кнопка, на которую забыли повесить действие. */
.blank__ico{
  width:56px;height:56px;border-radius:50%;
  border:1px solid var(--border);color:var(--text-3);opacity:.75;
  display:grid;place-items:center;
}
.blank h3{font-size:20px;color:var(--text-2);font-weight:700}
.blank p{font-size:14.5px;max-width:320px;line-height:1.5}

/* На узком экране полка идёт под формой, и «прозрачная» пустая карточка
   там сливается с концом страницы. Возвращаем ей отступ, чтобы блок не
   лип к форме. */
@media (max-width:1299.98px){ .stage--blank{padding:8px 0 0} }

.work{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:36px 20px}
.skel{
  width:100%;max-width:min(420px, 60%);aspect-ratio:1;border-radius:var(--radius);
  background:linear-gradient(100deg,var(--surface-2) 30%,var(--surface-3) 50%,var(--surface-2) 70%);
  background-size:220% 100%;animation:sweep 1.4s ease-in-out infinite;
}
@keyframes sweep{0%{background-position:120% 0}100%{background-position:-20% 0}}
.work__meta{text-align:center}
.work__title{font-size:14.5px;font-weight:500}
.work__sub{font-size:13px;color:var(--text-3);margin-top:3px;font-variant-numeric:tabular-nums}
.bar{width:100%;max-width:min(420px, 60%);height:4px;border-radius:var(--radius-xs);background:var(--surface-2);overflow:hidden}
.bar__fill{height:100%;width:0;background:var(--accent);border-radius:var(--radius-xs);transition:width .6s linear}
@media (prefers-reduced-motion:reduce){
  .skel{animation:none}
  .bar__fill{transition:none}
}

.shots{display:grid;gap:12px;grid-template-columns:1fr}
.shots--multi{grid-template-columns:repeat(2,1fr)}
@media (min-width:1600px){ .shots--multi{grid-template-columns:repeat(3,1fr)} }
.shot{
  position:relative;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--border);
}
.shot img{display:block;width:100%;height:auto}
.shot__bar{
  position:absolute;inset:auto 0 0 0;display:flex;gap:6px;justify-content:flex-end;
  padding:8px;background:linear-gradient(transparent,rgba(0,0,0,.5));
  opacity:0;transition:opacity .14s;
}
.shot:hover .shot__bar{opacity:1}
.iconbtn{
  width:var(--ctl-sm);height:var(--ctl-sm);border-radius:var(--radius-sm);cursor:pointer;
  border:none;background:rgba(255,255,255,.92);color:#1b1b19;
  display:grid;place-items:center;
}
.iconbtn:hover{background:#fff}

.done__foot{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border)}

.fail{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:12px;text-align:center;padding:36px 20px;
}
.fail__ico{
  width:48px;height:48px;border-radius:var(--radius);
  background:var(--danger-soft);color:var(--danger);display:grid;place-items:center;
}
.fail h3{font-size:16px}
.fail p{font-size:13.5px;color:var(--text-2);max-width:340px}
.refund{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--ok-soft);color:var(--ok);
  padding:5px 11px;border-radius:var(--radius-sm);font-size:12.5px;font-weight:500;
}

/* Загрузка файла */
.drop{
  display:block;position:relative;cursor:pointer;
  border:1.5px dashed var(--border-2);border-radius:var(--radius);
  background:var(--bg);padding:22px 16px;text-align:center;
  transition:border-color .12s,background .12s;
}
.drop:hover,.drop--over{border-color:var(--accent);background:var(--accent-soft)}
.drop--has{padding:0;border-style:solid;overflow:hidden}
.drop--has .drop__body{position:absolute;inset:auto 0 0 0;padding:8px;
  background:linear-gradient(transparent,rgba(0,0,0,.55));color:#fff;gap:2px}
.drop--has .drop__s{color:rgba(255,255,255,.8)}
.drop--has .ico{display:none}
.drop__prev{display:block;width:100%;max-height:340px;object-fit:contain;background:var(--surface-2)}
.drop__body{display:flex;flex-direction:column;align-items:center;gap:5px;color:var(--text-3)}
.drop__t{font-size:14px;font-weight:500;color:var(--text-2)}
.drop--has .drop__t{color:#fff}
.drop__s{font-size:12.5px}

/* Видео и аудио в результате */
.shot video{display:block;width:100%;height:auto;background:#000}
.audio{
  display:flex;flex-direction:column;gap:12px;align-items:center;justify-content:center;
  flex:1;padding:32px 20px;
}
.audio audio{width:100%;max-width:420px}
.audio__ico{width:52px;height:52px;border-radius:var(--radius);background:var(--accent-soft);
  color:var(--accent-text);display:grid;place-items:center}

/* ============================================================
   Мои работы
   ============================================================ */
/* ============================================================
   Мои работы: список строками

   Строка - это заказ. Плитка квадратиков выглядела нарядно, но
   отвечала не на те вопросы: человек ищет здесь «что я делал и когда»,
   а не «как это выглядело». Поэтому слева маленькая обложка (узнать с
   одного взгляда), в середине название и вид, справа срок хранения -
   и всё это в одну строку, которую глаз пробегает сверху вниз.
   ============================================================ */
.wbar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-bottom:10px;
}
.wbar__all{margin-right:auto}

.wcheck{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  font-size:13px;color:var(--text-2);user-select:none}
.wcheck{min-height:var(--ctl-sm)}
.wcheck input{width:20px;height:20px;accent-color:var(--accent);cursor:pointer;flex:0 0 auto}

/* Отбор по видам. Пилюли, а не вкладки: вкладки обещают разные
   страницы, а здесь один и тот же список, только короче. */
.wfilt{display:flex;gap:6px;flex-wrap:wrap}
.wf{
  display:inline-flex;align-items:center;gap:6px;height:var(--ctl-sm);
  padding:0 14px;border-radius:var(--radius-sm);cursor:pointer;
  border:1px solid var(--border-2);background:var(--surface);
  color:var(--text-2);font-size:14px;font-weight:600;font-family:inherit;
  transition:border-color .12s,color .12s,background .12s;
}
.wf:hover{border-color:var(--accent);color:var(--text)}
.wf span{font-size:11.5px;color:var(--text-3);
  background:var(--surface-2);border-radius:999px;padding:1px 6px}
.wf--on{border-color:var(--accent);background:var(--accent);color:var(--on-accent)}
.wf--on span{background:rgba(255,255,255,.22);color:inherit}

.wlist{display:flex;flex-direction:column;gap:6px}

.wrow{
  display:flex;align-items:center;gap:2px;
  border:1px solid transparent;border-radius:var(--radius);
  background:var(--surface);
  transition:border-color .12s,background .12s,opacity .18s,transform .18s;
}
.wrow:hover{border-color:var(--accent)}
.wrow--pick{border-color:var(--accent);background:var(--surface-2)}
/* Уходящая строка не исчезает рывком: глаз должен успеть заметить,
   ЧТО именно ушло, - иначе удаление не туда останется незамеченным. */
.wrow--gone{opacity:0;transform:translateX(-12px);pointer-events:none}

.wrow__pick{display:flex;align-items:center;padding:0 4px 0 14px;flex:0 0 auto}

/* Вся строка - одна ссылка на заказ. Нажатие мимо мелких кнопок должно
   работать: попадать пальцем в название на телефоне никто не обязан. */
.wrow__go{
  flex:1;min-width:0;display:flex;align-items:center;gap:12px;
  padding:9px 4px 9px 8px;color:inherit;text-decoration:none;
}

/* Обложка - квадратная со скруглением, а не круг: под таблеткой
   999 у квадрата получается круг, и картинку срезает по углам как
   раз там, где обычно лицо. Фон плашки берёт масть услуги - ту же,
   что и карточка на витрине, чтобы список работ и витрина говорили
   об одной услуге одним цветом. */
.wrow__cov{
  flex:0 0 auto;width:52px;height:52px;border-radius:var(--radius-xs);
  overflow:hidden;background:var(--tint,var(--surface-2));color:var(--text-2);
  display:grid;place-items:center;
}
.wrow__cov img{width:100%;height:100%;object-fit:cover;display:block}

.wrow__b{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.wrow__t{
  font-family:var(--font-head);font-size:17px;font-weight:700;letter-spacing:-.02em;
  color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.wrow__s{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:13.5px;color:var(--text-3)}
.wdot{opacity:.5}

/* Вид работы. Значок делает половину дела: «кавер» и «песня» читаются
   одинаково быстро, но нота и картинка различаются мгновенно. */
.wtag{display:inline-flex;align-items:center;gap:4px;
  color:var(--text-2);font-weight:500}
.wtag svg{opacity:.7}

.wrow__keep{
  flex:0 0 auto;font-size:13px;color:var(--text-3);
  white-space:nowrap;padding:0 6px;
}
.wrow__keep--warn{
  display:inline-flex;align-items:center;gap:4px;
  color:var(--warn);font-weight:500;
}

/* Работа на грани удаления. Красный здесь был бы враньём - ничего
   ещё не сломалось, - а незаметная серая подпись пропала бы совсем.
   Жёлтая полоса слева видна в списке из тридцати строк. */
.wrow--soon{background:var(--warn-soft);border-color:var(--warn-soft)}
.wrow--soon:hover{border-color:var(--warn)}
.wrow--soon .wrow__cov{background:rgba(0,0,0,.05)}

.wdel{
  flex:0 0 auto;width:var(--ctl-sm);height:var(--ctl-sm);margin-right:8px;
  display:grid;place-items:center;cursor:pointer;
  border:1px solid transparent;border-radius:var(--radius-sm);
  background:transparent;color:var(--text-3);
  transition:color .12s,background .12s,border-color .12s;
}
.wdel:hover{color:var(--danger);background:var(--danger-soft)}
/* Взведённая кнопка перестаёт быть квадратиком: слово «Удалить?» в
   него не влезает, и раньше надпись вылезала за края. */
.wdel--arm{
  width:auto;padding:0 11px;font-size:12.5px;font-family:inherit;
  background:var(--danger);color:#fff;border-color:var(--danger);
}
.wdel--arm svg{display:none}

/* Панель массового удаления. Прилипает к низу: список длинный, и
   возвращаться наверх за кнопкой после двадцатого флажка - лишняя
   работа руками. */
.wmass{
  position:sticky;bottom:calc(12px + var(--player-h));z-index:20;
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:12px;padding:10px 14px;
  border:1px solid var(--border);border-radius:var(--radius);
  background:var(--surface);box-shadow:0 6px 22px rgba(0,0,0,.13);
}
.wmass__n{flex:1;font-size:14.5px;font-weight:700;min-width:120px}

.btn--danger{background:var(--danger);color:#fff;border-color:var(--danger)}
.btn--danger:hover{background:var(--danger);filter:brightness(.93)}

/* Только для читалок: флажок без подписи для них - кнопка без имени. */
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

@media (max-width:640px){
  /* На телефоне срок уходит под название: держать его справа значит
     отгрызть у названия половину ширины ради двух слов. */
  .wrow__go{flex-wrap:wrap;gap:10px;padding-right:2px}
  .wrow__b{flex:1 1 100px}
  .wrow__keep{width:100%;padding:0 0 0 64px;margin-top:-4px}
  .wbar__all{margin-right:0;width:100%}
  .wmass{bottom:calc(var(--tabbar) + 10px + var(--player-h))}
}

.empty{
  text-align:center;padding:64px 20px;color:var(--text-3);
  display:flex;flex-direction:column;align-items:center;gap:12px;
}

/* ============================================================
   Баланс
   ============================================================ */
.packs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));margin-top:16px}
.pack{
  padding:20px;border-radius:var(--radius);cursor:pointer;text-align:left;
  border:1.5px solid var(--border-2);background:var(--surface);
  transition:border-color .12s,transform .12s;
}
.pack:hover{border-color:var(--accent);transform:translateY(-2px)}
.pack--best{border-color:var(--accent);border-width:2.5px;padding:19px}
.pack__sum{font-size:26px;font-weight:700;letter-spacing:-.02em}
/* Рублёвая цена нарочно тише токенов: главное - что человек получает,
   а не сколько отдаёт. Но спрятать её нельзя, платит он всё-таки деньгами. */
.pack__price{font-size:14px;color:var(--text-2);margin-top:3px}
.pack__note{font-size:13px;color:var(--text-3);margin-top:4px}

.note{
  display:flex;gap:12px;padding:16px 18px;margin-top:22px;
  border-radius:var(--radius);background:var(--surface-2);
  font-size:15px;color:var(--text-2);line-height:1.55;
}
.note .ico{flex:0 0 auto;color:var(--text-3);margin-top:2px}
/* Та же подсказка, но про срок: жёлтая, потому что предупреждает о
   потере, а не сообщает об ошибке. */
.note--warn{background:var(--warn-soft);color:var(--warn)}
.note--warn .ico{color:var(--warn)}

.demo{
  display:flex;align-items:center;gap:8px;justify-content:center;
  padding:7px 14px;background:var(--warn-soft);color:var(--warn);
  font-size:12.5px;font-weight:500;
}

/* ============================================================
   ПОДСКАЗКИ-ВОПРОСИКИ
   Маленький кружок у заголовка поля. Развёрнутый текст под каждым
   полем занимал два экрана и читался один раз - теперь по запросу.
   ============================================================ */
.qq{
  position:relative;
  display:inline-grid;place-items:center;vertical-align:1px;
  /* Кружок стоит в подписи поля, а та - флексовая строка: без запрета
     на сжатие на узком экране его сплющивало в семь пикселей, и вместо
     круга получался лепесток. */
  flex:0 0 auto;
  width:18px;height:18px;margin-left:6px;padding:0;
  border:1.5px solid var(--border-2);border-radius:50%;background:transparent;
  font-size:11.5px;font-weight:700;line-height:1;color:var(--text-3);cursor:pointer;
}
/* Кружок остаётся маленьким - рядом с подписью поля большой выглядел
   бы кнопкой, - но мишень под пальцем у него сорок пикселей:
   невидимая рамка вокруг. Значок и область нажатия - разные вещи. */
.qq::after{content:"";position:absolute;inset:-11px}
.qq:hover,.qq--on{border-color:var(--accent);color:var(--accent)}
.tipbox{
  position:absolute;z-index:60;padding:14px 16px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);
  font-size:14px;line-height:1.5;color:var(--text-2);font-weight:400;
  font-family:var(--font);
}

/* ============================================================
   КАТАЛОГ СТИЛЕЙ
   ============================================================ */
.styles{margin-bottom:16px}

/* Вкладки каталога - подчёркиванием, а не заливкой. Заливка тут
   спорила бы с выбранной карточкой стиля прямо под ними: два разных
   «выбрано» в одном блоке читаются как ошибка. */
.stabs{display:flex;gap:2px;margin-bottom:11px;border-bottom:1px solid var(--border)}
/* Вкладка делит строку пополам, но до 260 пикселей и не шире: в
   широкой панели две вкладки по семьсот выглядели не переключателем,
   а двумя половинами экрана. Черта под ними при этом идёт во всю
   ширину - она отделяет каталог, а не подчёркивает вкладки. */
.stab{
  flex:1 1 auto;max-width:260px;
  height:var(--ctl);padding:0 12px;border:0;background:none;position:relative;
  font-family:var(--font-head);font-size:17px;font-weight:700;letter-spacing:-.02em;
  color:var(--text-3);cursor:pointer;
}
.stab:hover{color:var(--text-2)}
.stab--on{color:var(--accent)}
.stab--on::after{
  content:"";position:absolute;left:8px;right:8px;bottom:-1px;
  height:3px;background:var(--accent);border-radius:3px;
}

.spane{display:none}
.spane--on{display:block}

.sfind{margin-bottom:10px}
/* Поиск по стилям - тоже поле, а не объект: рамки не нужно. */

/* Карточки: эмодзи, имя, описание бытовым языком. Английские теги
   человеку не показываем - он их не читает, а пугается.

   Колонок НЕ фиксированное число, а столько, сколько влезет по 116
   пикселей. Жёсткие «четыре в ряд» разваливались, как только форма
   оставалась единственной колонкой: на тысяче пикселей карточка
   раздувалась до двухсот пятидесяти, и внутри квадрата болталось
   пустое место с одним эмодзи. Теперь ширина карточки почти постоянна,
   а меняется их количество - как и должно быть у каталога. */
.pgrid{
  display:grid;gap:7px;margin-bottom:10px;

  /* Ряд считается от КОЛОНКИ, а не от окна.

     Я ошибся здесь дважды, и обе ошибки об одном. Сперва задал размер
     плитки долей колонки - вышли плитки с ладонь. Потом прописал число
     колонок под ширину ОКНА - и на широком мониторе восемь колонок
     легли в узкую колонку формы: плитки по 77 пикселей с обрезанными
     названиями. Окно и колонка - разные вещи, между ними меню, отступы
     и полка результата.

     Правильно так: задаём минимальную ширину плитки, а сколько их
     влезет, считает сама колонка. Плитка не бывает мельче 158 пикселей
     ни при какой ширине, и текст в ней всегда целый. Проверено на живой
     странице при панели 1475, 1400, 1200, 900, 740, 615, 560 и 420:
     ноль обрезаний, плитка от 160 до 188. */
  grid-template-columns:repeat(auto-fill,minmax(158px,1fr));
}
/* На телефоне плитка чуть уже: при 158 в узкую колонку влезала одна
   штука во всю ширину экрана. Проверено на 320, 360 и 420 - везде две. */
@media (max-width:640px){ .pgrid{grid-template-columns:repeat(auto-fill,minmax(132px,1fr))} }
/* Карточка стиля - как на основном сайте: плоский серый квадрат без
   рамки, а выбор показывается обводкой ВНУТРЬ. Обводка снаружи меняла
   бы размер карточки на пиксель, и вся сетка на выбор чуть дёргалась. */
.pcard{
  position:relative;display:flex;flex-direction:column;
  /* НЕ КВАДРАТ - и это была главная ошибка.

     Стояло aspect-ratio:1, высота повторяла ширину: в широкой колонке
     ряд плиток занимал пол-экрана. Померил основной сайт - там плитка
     146 на 120, высота задана числом. Делаем так же, и высота при этом
     нижняя граница, а не потолок: со строгой высотой и overflow:hidden
     длинные названия обрезались на полуслове - «Душевны», «Праздничн». */
  min-height:118px;padding:12px;
  text-align:left;cursor:pointer;font:inherit;color:inherit;
  /* Своя масть, как у карточек услуг, и по той же причине: в каталоге
     из ста тридцати плиток цвет - единственный быстрый ориентир.
     Оттенки берутся из styles.php и подобраны по семьям (рэп, шансон,
     детское, электроника), а не по одному на плитку: сто тридцать
     разных цветов подряд - это рябь, а не каталог. */
  border:0;border-radius:var(--radius-xs);
  background:var(--tint,var(--surface-2));
  transition:box-shadow .15s ease,background .15s ease;
}
.pcard:hover{box-shadow:inset 0 0 0 2px var(--accent)}
/* Выбранную плитку обводим чернилами, а не акцентом: акцент спорил бы
   с мастью самой плитки, и на красных плитках выбор пропадал совсем. */
.pcard--on{box-shadow:inset 0 0 0 3px var(--text)}
.pcard[hidden]{display:none}

.pcard__e{font-size:24px;line-height:1.1;margin-bottom:auto}
.pcard__e svg{vertical-align:middle}
.pcard__n{
  font-family:var(--font-head);
  font-size:14px;font-weight:700;line-height:1.2;margin-bottom:3px;letter-spacing:-.02em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* Описание вторично: если не влезло - обрезаем его, а не название. */
.pcard__d{
  font-size:11.5px;color:var(--text-2);line-height:1.3;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* В тёмной теме - та же примесь, что у карточек услуг: бледный тинт
   заливкой дал бы светлое пятно посреди тёмной страницы. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .pcard{
    background:var(--surface-2);
    background:color-mix(in srgb, var(--tint,var(--surface-2)) 18%, var(--surface-2));
  }
}
:root[data-theme="dark"] .pcard{
  background:var(--surface-2);
  background:color-mix(in srgb, var(--tint,var(--surface-2)) 18%, var(--surface-2));
}

/* Треугольник прослушивания - отдельная мишень: слушать и выбирать
   это разные намерения, путать их нельзя. */
.pcard__play{
  position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:var(--radius-sm);
  background:var(--surface);border:1px solid var(--border);
  display:grid;place-items:center;
}
/* Кружок нарочно маленький - он не должен закрывать плитку, - но
   мишень под пальцем у него полноразмерная: невидимая рамка вокруг
   доводит область нажатия до сорока пикселей. Слушать и выбирать -
   разные намерения, и промах между ними самый обидный. */
.pcard__play::after{content:"";position:absolute;inset:-7px}
.pcard__play::before{
  content:"";width:0;height:0;margin-left:2px;
  border-top:4px solid transparent;border-bottom:4px solid transparent;
  border-left:7px solid var(--text-2);
}
.pcard__play:hover{border-color:var(--accent)}
.pcard__play:hover::before{border-left-color:var(--accent)}
.pcard--play .pcard__play{background:var(--accent);border-color:var(--accent)}
.pcard--play .pcard__play::before{
  width:9px;height:10px;margin:0;border:0;background:#fff;
  clip-path:polygon(0 0,34% 0,34% 100%,0 100%,0 0,66% 0,100% 0,100% 100%,66% 100%,66% 0);
}

.snone{padding:14px 0;font-size:13.5px;color:var(--text-3);text-align:center}

.sgroup{margin-bottom:14px}
.sgroup__t{font-size:13px;font-weight:600;color:var(--text-2);margin-bottom:7px}
.chip--more{color:var(--text-3);border-style:dashed}

/* Итог виден всегда: человек должен знать, что уедет на сервис,
   а не угадывать по подсветке кнопок. */
.sout{
  /* Многострочная сводка - не таблетка. */
  margin-top:10px;padding:11px 14px;border-radius:var(--radius);
  background:var(--surface-2);
  font-size:13.5px;line-height:1.5;color:var(--text-2);word-break:break-word;
}

/* На телефоне даём карточкам чуть больше воздуха: пальцем в стопятьдесят
   пикселей попадают увереннее, чем в сто шестнадцать. */
@media(max-width:480px){
  .pgrid{grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:8px}
  .pcard{padding:12px}
  .pcard__e{font-size:23px}
  .pcard__n{font-size:14.5px}
  .pcard__d{font-size:12px}
}

/* Карточка суммы - кнопка выбора, а не ссылка в кассу */
.pack{
  display:flex;flex-direction:column;align-items:flex-start;
  text-align:left;cursor:pointer;font:inherit;color:inherit;
}
.pack--on{border-color:var(--accent);background:var(--accent-soft)}
.pack--on .pack__price,.pack--on .pack__note{color:var(--accent-text);opacity:.85}
.ownsum{margin-top:12px;max-width:260px}
.ownsum .field__label{margin-bottom:5px}

/* Ряд дополнений под треком: обложка, WAV, видео. Кнопки мелкие и в ряд -
   это довесок к готовой песне, а не выбор, ради которого сюда шли. */
.xrow{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px}
.xrow .btn{flex:0 0 auto}
.xdone{display:inline-flex;align-items:center;padding:8px 12px;border-radius:var(--radius-sm);
  background:var(--ok-soft);color:var(--ok);font-size:13px;font-weight:500}

/* Карточка выбранного файла. Стоит НА МЕСТЕ зоны загрузки, а не внутри
   неё: пока плеер лежал под <label>, каждое нажатие по нему открывало
   диалог выбора файла и послушать загруженное было нельзя. */
.fcard{
  padding:12px 13px;border:1px solid var(--border);border-radius:var(--radius);
  background:var(--surface-2);
}
.fcard__top{display:flex;align-items:center;gap:10px;margin-bottom:9px}
.fcard__name{
  flex:1;min-width:0;font-size:14px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.fcard__x{
  flex:0 0 auto;width:var(--ctl-sm);height:var(--ctl-sm);border-radius:var(--radius-sm);cursor:pointer;
  display:grid;place-items:center;color:var(--text-3);
  border:1px solid var(--border-2);background:var(--surface);
}
.fcard__x:hover{border-color:var(--danger);color:var(--danger)}
.fcard__au{width:100%;display:block}

/* Выключенный чат для гостя. Показываем устройство целиком, но глушим:
   заглушка вместо интерфейса не объясняет, что человек получит. */
.chat--off{position:relative}
.chat--off .chat__log,.chat--off .chat__bar{opacity:.55;pointer-events:none;filter:saturate(.4)}
.chat__lock{
  display:flex;align-items:center;gap:13px;flex-wrap:wrap;
  padding:14px 16px;border-radius:var(--radius);
  background:var(--accent-soft);color:var(--accent-text);
  font-size:13.5px;line-height:1.5;
}
.chat__lock > div{flex:1;min-width:220px}
.chat__lock .ico{flex:0 0 auto}
.chat__lock strong{display:block;font-size:15px;margin-bottom:2px;color:var(--text)}
.chat__lock .btn{flex:0 0 auto}

/* Номер заказа для гостя и его история */
/* НОМЕР ЗАКАЗА - СПОКОЙНАЯ ПОЛОСА, А НЕ КРАСНАЯ.

   Раньше она красилась акцентом, а акцент у нас алый. Получалось, что
   под готовой песней, которая только что успешно сделана, стоит красная
   рамка с красным текстом - ровно так на этом сайте выглядит ошибка.
   Человек дочитывал до слова «сохрани» и решал, что что-то сломалось.

   Красный тут нёс только одну полезную работу - привлечь внимание к
   номеру. Её делает сам номер: моноширинный и крупнее остального. */
.onote{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:12px 14px;margin-bottom:12px;border-radius:var(--radius);
  background:var(--surface-2);border:1px solid var(--border);
  color:var(--text-2);font-size:13.5px;line-height:1.5;
}
.onote b{color:var(--text)}
.onote > div{flex:1;min-width:220px}
.onote b{font-family:var(--mono);font-size:15px;letter-spacing:.02em}
.onote span{color:inherit;opacity:.75;font-size:12.5px}
.findrow{display:flex;gap:8px;flex-wrap:wrap}
.findrow .input{flex:1;min-width:220px;font-family:var(--mono)}
.orow{
  display:flex;align-items:center;gap:12px;width:100%;cursor:pointer;text-align:left;
  padding:12px 16px;margin-bottom:8px;border-radius:var(--radius);
  border:1px solid var(--border);background:var(--surface);font:inherit;color:inherit;
}
.orow:hover{border-color:var(--accent)}
.orow__t{font-family:var(--font-head);font-weight:700;font-size:16px;flex:0 0 auto}
.orow__i{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  font-family:var(--mono);font-size:12.5px;color:var(--text-3)}
.orow__d{flex:0 0 auto;font-size:12.5px;color:var(--text-3)}
/* Судьба заказа - словом и цветом. «Готово» и «не получилось» человек
   должен различать взглядом, не вчитываясь. */
.orow__s{
  flex:0 0 auto;font-size:12px;font-weight:700;
  padding:2px 9px;border-radius:var(--radius-sm);white-space:nowrap;
}
.orow__s--ok{background:var(--ok-soft);color:var(--ok)}
.orow__s--bad{background:var(--danger-soft);color:var(--danger)}
.orow__s--wait{background:var(--surface-2);color:var(--text-3)}
@media(max-width:560px){ .orow__i{display:none} }

/* ============================================================
   ТРИ РЕЖИМА НАВИГАЦИИ, И РОВНО ОДИН ЗА РАЗ

   Широкий экран  - сайдбар слева.
   Планшет/ноутбук - лента модулей под шапкой.
   Телефон        - четыре вкладки снизу.

   Держать две навигации одновременно нельзя: человек перестаёт
   понимать, какая из них главная, и обе перестают работать. */
@media (min-width:600px) and (max-width:899.98px){
  .tabbar{display:none}
  .main{padding-bottom:48px}
  /* Нижней панели нет - липкой кнопке некуда отступать, кроме как над
     полосой плеера, если та сейчас на экране. */
  .pays{bottom:calc(10px + var(--player-h)) !important}
}
@media (max-width:599.98px){
  .modbar{display:none}
  .main{padding:16px 14px calc(var(--tabbar) + 24px)}
  .panel{padding:15px}
  .formfoot{margin:14px -15px -15px;padding:0 15px 10px}
  .formfoot::before{margin:0 -15px 10px}
  /* На 390 сорок пикселей заголовка съедают треть первого экрана и
     переносятся на три строки. Двадцать восемь - тот же приём с
     засечками, но помещается в две. */
  h1{font-size:28px}
  h2{font-size:21px}
  .head p{font-size:15px}

  /* Ряд из двух кнопок на узком экране - это две кнопки в столбик, а
     не две половинки, в которые не попасть. Исключение - переключатели
     из двух слов: они и в половину ширины читаются целиком. */
  .ordbox__act{width:100%;margin-left:0}
  .ordbox__act .btn{flex:1 1 calc(50% - 4px);min-width:0}
  .lyrpanel__row .btn{flex:1 1 100%}
  .xrow .btn{flex:1 1 calc(50% - 4px)}
}

/* ============================================================
   ТЕЛЕФОН И ПЛАНШЕТ: ПАЛЕЦ ВМЕСТО МЫШИ
   ============================================================ */
@media (pointer:coarse){
  /* Шестнадцать пикселей в полях - не вкусовщина, а лечение.
     Safari на айфоне сам приближает страницу, когда фокус попадает в
     поле мельче шестнадцати, и обратно не отдаляет: человек печатает
     в увеличенной странице, вылезшей за края экрана. Единственное
     средство - не давать поводу случиться. */
  input,textarea,select,.input{font-size:16px}

  /* Мишень меньше сорока четырёх пикселей - это промах через раз.
     Здесь мы поднимаем до общего роста даже те кнопки, которым на
     мониторе позволено быть мелкими. */
  .btn--sm,.chip,.stab,.pick__btn{height:var(--ctl)}
  .qq{width:22px;height:22px;font-size:12px}
  .hmenu__b{width:var(--ctl);height:var(--ctl)}
}

/* Совсем узкие телефоны: 320 пикселей всё ещё в ходу, и на них
   двухколоночные ряды превращаются в кашу. */
@media (max-width:359.98px){
  .main{padding:14px 10px calc(var(--tabbar) + 22px)}
  .panel{padding:12px}
  .formfoot{margin:12px -12px -12px;padding:0 12px 10px}
  .formfoot::before{margin:0 -12px 10px}
  .seg{flex-wrap:wrap}
  .seg__b{flex:1 1 100%}
  .ordbox__act .btn{flex:1 1 100%}
  .hrow__cov{width:52px;height:52px}
}

/* Платная кнопка без денег на счету: видна и понятна, но приглушена -
   прятать её нельзя, иначе о возможности никто не узнает. */
.btn--dim{opacity:.6}

/* ============================================================
   ПОЛЗУНКИ

   Дорожку рисуем сами. Штатный accent-color красит только бегунок,
   а сама полоса остаётся одноцветной - значит опасные края видны
   лишь после того, как в них заехал. Красим края заранее: человек
   видит, куда лучше не лезть, ещё до того, как потянул.

   Насечки поперёк дорожки не украшение: сплошная полоса не даёт
   почувствовать шаг, и человек не понимает, много ли он сдвинул.
   ============================================================ */
.rangerow{display:flex;align-items:center;gap:10px}

.rangerow input[type=range]{
  -webkit-appearance:none;appearance:none;
  flex:1;min-width:0;height:26px;background:transparent;cursor:pointer;
}

/* Дорожка: толстая, с насечками через каждые 10%. */
.rangerow input[type=range]::-webkit-slider-runnable-track{
  height:12px;border-radius:6px;
  background:
    repeating-linear-gradient(to right,
      transparent 0 calc(10% - 1px), var(--border-2) calc(10% - 1px) 10%),
    var(--surface-3);
}
.rangerow input[type=range]::-moz-range-track{
  height:12px;border-radius:6px;
  background:
    repeating-linear-gradient(to right,
      transparent 0 calc(10% - 1px), var(--border-2) calc(10% - 1px) 10%),
    var(--surface-3);
}

/* Крайние 15% с каждой стороны опасные, и это видно всегда. */
[data-risky]::-webkit-slider-runnable-track{
  background:
    repeating-linear-gradient(to right,
      transparent 0 calc(10% - 1px), var(--border-2) calc(10% - 1px) 10%),
    linear-gradient(to right,
      var(--danger-soft) 0 15%,
      var(--surface-3)  15% 85%,
      var(--danger-soft) 85% 100%) !important;
}
[data-risky]::-moz-range-track{
  background:
    repeating-linear-gradient(to right,
      transparent 0 calc(10% - 1px), var(--border-2) calc(10% - 1px) 10%),
    linear-gradient(to right,
      var(--danger-soft) 0 15%,
      var(--surface-3)  15% 85%,
      var(--danger-soft) 85% 100%) !important;
}

/* Бегунок - вертикальная капсула, как в панели Suno: её видно
   на толстой дорожке и она не путается с насечками. */
.rangerow input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:14px;height:26px;margin-top:-7px;border-radius:7px;
  background:var(--accent);border:2px solid var(--surface);
  box-shadow:0 1px 4px rgba(0,0,0,.28);
}
.rangerow input[type=range]::-moz-range-thumb{
  width:14px;height:26px;border-radius:7px;
  background:var(--accent);border:2px solid var(--surface);
  box-shadow:0 1px 4px rgba(0,0,0,.28);
}

/* Заехал в край - краснеет и бегунок, и число. */
.range--risk::-webkit-slider-thumb{background:var(--danger)}
.range--risk::-moz-range-thumb{background:var(--danger)}
.field__count--risk{color:var(--danger);font-weight:600}

/* Длительность спрятана за «Авто / Задать»: это не настройка
   на каждый день, и пустая шкала на экране просит, чтобы её
   подвигали, хотя трогать её незачем. */
.askrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.askrow .field__label{margin-bottom:0;flex:1;min-width:0}
.seg--sm{flex:0 0 auto;gap:6px}
.seg--sm .seg__b{height:var(--ctl-sm);padding:0 12px;font-size:13px;flex:0 0 auto}
.field--ask .rangerow{margin-top:10px}
.field--ask .rangerow[hidden]{display:none}

/* Возврат к автоматическому выбору. Круглая, тихая, появляется только
   когда есть что возвращать - как в панели Suno. */
.undo{
  flex:0 0 auto;width:var(--ctl-sm);height:var(--ctl-sm);border-radius:var(--radius-sm);cursor:pointer;
  display:grid;place-items:center;
  border:1px solid var(--border-2);background:var(--surface);color:var(--text-3);
  transition:border-color .12s,color .12s;
}
.undo:hover{border-color:var(--accent);color:var(--accent)}
.undo[hidden]{display:none}

/* ============================================================
   ИСТОРИЯ В ОБЛАСТИ РЕЗУЛЬТАТА

   Пустая рамка «здесь появится результат» занимала половину экрана и
   не говорила ничего. Список сделанного отвечает сразу на два вопроса:
   что тут вообще получается и где моё прошлое.
   ============================================================ */
.hist{display:flex;flex-direction:column;gap:8px}
.hist__top{display:flex;align-items:center;gap:10px;margin-bottom:4px}
.hist__top h3{flex:1;min-width:0}
.hist__all{font-size:14px;color:var(--accent);font-weight:700;flex:0 0 auto}
.hist__note{
  margin-top:8px;padding-top:12px;border-top:1px solid var(--border);
  font-size:12.5px;line-height:1.5;color:var(--text-3);
}

.hrow{
  display:flex;align-items:center;gap:12px;
  padding:10px;border-radius:var(--radius);
  transition:background .12s;
}
.hrow:hover{background:var(--surface-2)}

/* Скругление, а не круг: см. .wrow__cov - у квадрата таблетка даёт
   окружность и срезает картинку по углам. */
.hrow__cov{
  position:relative;flex:0 0 auto;width:58px;height:58px;
  border-radius:var(--radius-xs);overflow:hidden;background:var(--surface-3);
}
.hrow__cov img{width:100%;height:100%;object-fit:cover;display:block}

/* Треугольник поверх обложки: слушать - главное действие строки,
   и тянуться за ним в меню человек не должен. */
.hrow__play{
  position:absolute;inset:0;width:100%;height:100%;cursor:pointer;
  border:0;background:rgba(0,0,0,.34);
  display:grid;place-items:center;opacity:0;transition:opacity .12s;
}
.hrow:hover .hrow__play,.hrow--play .hrow__play,
.hrow__play:focus-visible{opacity:1}

/* На сенсорном экране наведения не существует: палец либо касается,
   либо нет. Кнопка, показывающаяся по hover, там просто невидима -
   человек смотрит на обложку и не догадывается, что её можно нажать.
   Где нет мыши, показываем сразу. */
@media (hover:none){ .hrow__play{opacity:1} }
.hrow__play::before{
  content:"";width:0;height:0;margin-left:3px;
  border-top:7px solid transparent;border-bottom:7px solid transparent;
  border-left:12px solid #fff;
}
.hrow--play .hrow__play::before{
  width:11px;height:12px;margin:0;border:0;background:#fff;
  clip-path:polygon(0 0,34% 0,34% 100%,0 100%,0 0,66% 0,100% 0,100% 100%,66% 100%,66% 0);
}
.hrow__dur{
  position:absolute;right:4px;bottom:4px;
  padding:1px 5px;border-radius:var(--radius-xs);
  background:rgba(0,0,0,.62);color:#fff;font-size:11px;font-weight:600;
}

.hrow__b{flex:1;min-width:0}
.hrow__t{font-family:var(--font-head);font-size:16.5px;font-weight:700;letter-spacing:-.02em;
  margin-bottom:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hrow__s{font-size:13.5px;color:var(--text-3);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
.hrow__k{font-size:11.5px;color:var(--text-3);opacity:.75;margin-top:3px}

/* Меню действий вместо ряда кнопок: их на строку нужно три-четыре,
   и в ряд они перевешивают саму работу. */
.hmenu{position:relative;flex:0 0 auto}
.hmenu__b{
  width:var(--ctl-sm);height:var(--ctl-sm);border-radius:var(--radius-sm);cursor:pointer;
  display:grid;place-items:center;
  border:0;background:transparent;color:var(--text-3);
}
.hmenu__b:hover{background:var(--surface-2);color:var(--text)}
.hmenu__list{
  position:absolute;top:calc(100% + 5px);right:0;z-index:25;min-width:180px;padding:5px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);
}
.hmenu__list a{
  display:block;padding:8px 10px;border-radius:var(--radius-sm);
  font-size:13.5px;color:var(--text-2);
}
.hmenu__list a:hover{background:var(--surface-2);color:var(--text)}

/* Переключатель темы. Три положения подряд: система, светлая, тёмная. */
.theme{display:flex;gap:4px;padding:3px;
  background:var(--surface-2);border-radius:var(--radius-sm)}
.theme__b{
  flex:1;display:grid;place-items:center;height:var(--ctl-sm);cursor:pointer;
  border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-3);
}
.theme__b:hover{color:var(--text-2)}
.theme__b--on{background:var(--surface);color:var(--text);box-shadow:var(--shadow)}
body.nav--min .theme{flex-direction:column;padding:2px;gap:2px}
/* В свёрнутом меню переключатель встаёт столбиком, и flex:1 из общего
   правила начинает делить ВЫСОТУ: заданный рост он при этом отменяет
   (flex:1 - это flex-basis:0), и кнопки сплющивались до восемнадцати
   пикселей - высоты одного значка. Поэтому здесь рост задаётся жёстко,
   а растягивание выключается. */
body.nav--min .theme__b{flex:0 0 auto;height:36px}
@media (max-width:899.98px){ .theme{display:none} }

/* Ряд кнопок под сеткой стилей: «показать ещё» широкая, «свернуть» - значок */
.prow{display:flex;gap:8px;margin-top:2px}
.prow__more{flex:1}
.prow__less{flex:0 0 auto;width:var(--ctl-sm);padding:0;color:var(--text-3)}
.prow__less:hover{color:var(--text)}

/* Пункт «Удалить» в меню и кнопка на строке неудачи */
.hmenu__del{
  display:block;width:100%;text-align:left;background:transparent;border:0;
  padding:9px 13px;font:inherit;color:var(--danger);cursor:pointer;
}
.hmenu__del:hover{background:var(--danger-soft)}
.hmenu__del--arm{background:var(--danger-soft);font-weight:600}
.hrow__del{flex:0 0 auto;width:var(--ctl-sm);padding:0;color:var(--text-3)}
/* Пока задан вопрос, квадратик раздвигается под текст: фиксированная
   ширина в значок обрезала бы «Точно удалить?» по краям. */
.hrow__del.btn--armed{width:auto;padding:0 12px}
.hrow__del:hover{color:var(--danger);border-color:var(--danger)}

/* Кнопка повтора на строке неудачи */
.hrow__again{flex:0 0 auto;margin-left:auto;white-space:nowrap}

/* Строка неудачи устроена как все: сверху квадрат и подписи, кнопки -
   отдельной строкой во всю ширину. Кнопки в одном ряду с текстом
   отбирали у него всё место, и в узкой колонке от названия оставалось
   «Не по...». */
.hrow--bad{background:var(--danger-soft);flex-wrap:wrap}
.hrow--bad:hover{background:var(--danger-soft)}
.hrow__act{
  flex:0 0 100%;display:flex;flex-wrap:wrap;gap:8px;
  margin-top:10px;padding-top:10px;
  border-top:1px solid color-mix(in srgb,var(--danger) 14%,transparent);
}
.hrow__act .btn{background:var(--surface)}
.hrow__act .btn:hover{background:var(--surface-2)}
.hrow__act .hrow__del{margin-left:auto}

/* ВЫБОР ПОСЛЕ СБОЯ: предупреждение, «Перезапустить» и - тише и ниже -
   «Запросить возврат».

   Вес у кнопок разный намеренно. Человек, у которого не получилось,
   пришёл за песней, а не за разбирательством с деньгами: перезапуск
   выглядит как обычная кнопка, возврат - как ссылка. Поставь их
   вровень - и половина уйдёт с возвратом вместо песни, которая
   получилась бы со второго раза. Прятать возврат при этом нельзя:
   он там, где его будут искать, и подписан своими словами. */
.hfix{margin-top:10px;display:flex;flex-direction:column;align-items:flex-start;gap:8px}
.hfix__warn{font-size:13px;line-height:1.5;color:var(--text-2)}
.hfix__go{min-width:150px}
.hfix__left{font-size:12px;color:var(--text-3)}
.hfix__err{font-size:13px;color:var(--danger)}
.hfix__note{font-size:13px;line-height:1.5;color:var(--text-2)}
.hfix__ref{
  background:none;border:0;padding:0;margin-top:2px;font:inherit;font-size:13px;
  color:var(--text-3);text-decoration:underline;text-underline-offset:2px;cursor:pointer;
}
.hfix__ref:hover{color:var(--text)}
.hfix__ref[disabled]{opacity:.55;cursor:not-allowed}

/* Кнопки в шапке заказа */
.ordbox__act{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}

/* Серое на сером не видно.

   Кнопки у нас плоские и светло-серые - это работает, пока под ними
   белая панель. Внутри серых блоков - карточки заказа, подсказки,
   приглашения войти - такая кнопка сливается с фоном и перестаёт
   выглядеть кнопкой. Там она становится белой: тот же силуэт, та же
   высота, просто вывернутый контраст. */
/* Красить фон - только у кнопок БЕЗ своего цвета.

   Раньше правило било по всем кнопкам подряд, а каждой цветной потом
   возвращали цвет отдельной строкой. Кому строку не написали - тот
   пропадал: у кнопки Яндекса фон становился белым, а надпись на ней
   оставалась белой, и человек видел пустой прямоугольник. Список
   исключений здесь один на все цветные кнопки, поэтому забыть новую
   больше нельзя. */
:is(.ordbox,.note,.chat__lock,.onote,.down,.ask)
  .btn:not(.btn--primary,.btn--go,.btn--ya,.btn--danger,.btn--armed,.btn--busy){
  background:var(--surface);
}
:is(.ordbox,.note,.chat__lock,.onote,.down,.ask)
  .btn:not(.btn--primary,.btn--go,.btn--ya,.btn--danger,.btn--armed,.btn--busy):hover{
  background:var(--surface-3);
}

/* Песни внутри карточки заказа: та же строка, но на общем фоне */
.ordbox__list{margin-top:12px}
.ordbox__list .hrow{background:var(--surface)}
.ordbox__list .hrow:hover{background:var(--surface-3)}
.ordbox__list:empty{display:none}

/* Карточка открытого заказа: что это за работа и как к ней вернуться */
.ordbox{
  background:var(--surface-2);border:1px solid var(--border);
  border-radius:var(--radius);padding:14px 16px;margin-bottom:12px;
}
.ordbox__top{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.ordbox__ttl{font-size:11.5px;color:var(--text-3);text-transform:uppercase;letter-spacing:.05em}
.ordbox__id{font-size:14px;font-weight:600;word-break:break-all}
.ordbox__top .btn{margin-left:auto}
.ordbox__grid{display:flex;flex-direction:column;gap:5px;margin-top:11px}
.ordbox__k{display:inline-block;min-width:78px;color:var(--text-3);font-size:12.5px}
.ordbox__v{font-size:13.5px}
.ordbox__lyr{margin-top:10px}
.ordbox__lyr summary{font-size:12.5px;color:var(--text-3);cursor:pointer}
.ordbox__lyr summary:hover{color:var(--text-2)}
.ordbox__lyrbox{
  margin-top:8px;padding:12px 15px;border-radius:var(--radius);
  background:var(--surface);font-size:13.5px;line-height:1.6;
  white-space:pre-wrap;max-height:260px;overflow:auto;
}

/* ============================================================
   СПИСОК РАБОТ: кольцо ожидания и строки

   Кольцо вместо полосы и подписи. Полоса обещает долю сделанного,
   а мы её не знаем: сервис не сообщает, сколько осталось, и любая
   цифра на экране была бы выдумкой. Кольцо не врёт - оно говорит
   ровно «идёт работа».
   ============================================================ */
.rlist{display:flex;flex-direction:column;gap:8px}
.rlist:empty{display:none}

.ring{
  width:26px;height:26px;border-radius:50%;
  border:2.5px solid var(--border-2);
  border-top-color:var(--accent);
  animation:ring 850ms linear infinite;
}
@keyframes ring{to{transform:rotate(360deg)}}

/* Шкала с долей: заполненное кольцо и число внутри.

   Число - оценка по времени, и мы честно держим его ниже сотни, пока
   работа не готова. Полоса, дошедшая до конца при стоящей песне, - тот
   самый обман, который замечают все и после которого не верят уже
   никакой шкале. Поверх доли крутится дужка: она говорит «идёт»
   даже тогда, когда процент замер. */
.dial{
  --p:0;
  position:relative;width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;
  background:
    conic-gradient(var(--accent) calc(var(--p) * 1%), var(--surface-3) 0);
  transition:background .6s linear;
}
.dial::before{
  content:"";position:absolute;inset:4px;border-radius:50%;
  background:var(--surface);
}
.dial::after{
  content:"";position:absolute;inset:-3px;border-radius:50%;
  border:2px solid transparent;border-top-color:var(--accent);
  opacity:.55;animation:ring 1.1s linear infinite;
}
.dial__n{
  position:relative;font-size:11px;font-weight:600;
  color:var(--text-2);font-variant-numeric:tabular-nums;
}

/* Подпись этапа вместо серых полосок-заглушек */
.hrow__step{font-size:14px;font-weight:500;color:var(--text)}
.hrow__sub{font-size:12.5px;color:var(--text-3);font-variant-numeric:tabular-nums}
.hrow--wait .hrow__cov{background:transparent}

/* Занятая кнопка: кольцо слева от подписи.

   Серая кнопка без единого движения неотличима от сломанной - человек
   жмёт ещё раз, потом решает, что сайт не работает. Кольцо на самой
   кнопке отвечает на вопрос там же, где он возник. */
.btn--busy{position:relative;pointer-events:none}
.btn--busy svg{display:none}
.btn--busy .btn__price{opacity:0}
.btn--busy::before{
  content:"";width:15px;height:15px;flex:0 0 auto;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;opacity:.75;
  animation:ring 800ms linear infinite;
}

/* Кости-заглушки вместо названия и стиля, пока они неизвестны */
.bone{
  height:11px;border-radius:5px;background:var(--surface-3);
  animation:bone 1.4s ease-in-out infinite;
}
.bone--w{height:14px;margin-bottom:7px;max-width:190px}
.hrow--wait .bone{max-width:130px}
.hrow--wait .bone--w{max-width:190px}
@keyframes bone{0%,100%{opacity:.55}50%{opacity:1}}

.hrow--wait .hrow__cov{display:grid;place-items:center;background:var(--surface-2)}
.hrow--wait{cursor:default}

.hrow--bad .hrow__cov{display:grid;place-items:center;background:var(--danger-soft);color:var(--danger)}
.hrow--bad .hrow__t{color:var(--danger)}

/* Текст песни под строкой - раскрывашкой, не в разворот */
.hrow__lyr{margin-top:7px}
.hrow__lyr summary{font-size:12.5px;color:var(--text-3);cursor:pointer}
.hrow__lyr summary:hover{color:var(--text-2)}
.hrow__lyrbox{
  margin-top:7px;padding:12px 14px;border-radius:var(--radius);
  background:var(--surface-2);font-size:13.5px;line-height:1.6;
  white-space:pre-wrap;max-height:230px;overflow:auto;
}

/* Видео в обложке ведёт себя как картинка */
.hrow__cov video{width:100%;height:100%;object-fit:cover;display:block}

/* ============================================================
   СТРОКА РЕЗУЛЬТАТА ПО ВИДАМ РАБОТ

   Общая у них только рамка. Всё остальное - своё: картинку смотрят,
   музыку слушают, ролик запускают. Один шаблон на всех давал
   треугольник «слушать» поверх фотографии и подпись «Скачать mp3» на
   файле png - интерфейс, который сам себе противоречит.
   ============================================================ */

/* Картинка - это и есть результат, а не значок рядом с ним. Квадратик
   у неё крупнее: разглядеть, что вышло, важнее, чем прочитать подпись. */
.hrow--image .hrow__cov{width:78px;height:78px;background:var(--surface-2)}
.hrow__full{display:block;width:100%;height:100%;cursor:zoom-in}
.hrow__full img{width:100%;height:100%;object-fit:cover;display:block}

/* Картинка крупнее - на месте, а не в новой вкладке.

   Новая вкладка выбрасывает человека с сайта ради одного взгляда на
   файл, и возвращаться он должен сам. Раскрываем прямо в строке: во
   всю её ширину и вниз, сколько нужно по пропорциям самой картинки.
   Ширину диктует блок, в котором строка стоит, поэтому на телефоне
   картинка сама укладывается в экран - отдельного правила не нужно.

   Потолок в 78vh - чтобы вертикальная картинка не оказалась выше
   экрана: иначе человек листает и не понимает, где она кончилась.
   Пропорции при этом целы, contain вписывает, а не режет. */
.hrow--open{flex-wrap:wrap}
.hrow--open .hrow__full{cursor:zoom-out}
/* Рамка на самой картинке, а не на месте под неё.

   Место занимает всю строку, но картинка внутри держит свои пропорции
   до последнего пикселя: широкая растягивается во всю ширину, высокая
   упирается в потолок высоты и встаёт по центру. Рамка и скругление
   висят на картинке, поэтому обнимают её вплотную - никаких серых
   полей по бокам, которые выглядели бы браком вёрстки.

   Скругление здесь СВОЁ, не кнопочное: --radius-sm равен 999px, и на
   картинке в пол-экрана это дало бы идеальный круг. Работа человека -
   не аватарка. */
.hrow__big{
  flex:0 0 100%;width:100%;margin-top:6px;
  display:flex;justify-content:center;line-height:0;
  animation:bigin .16s ease-out;
}
.hrow__big img{
  display:block;max-width:100%;width:auto;height:auto;max-height:78vh;
  border-radius:var(--radius-xs);border:1px solid var(--border);
  background:var(--surface-3);cursor:zoom-out;
}
@keyframes bigin{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){ .hrow__big{animation:none} }
.hrow--image .hrow__cov::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.06);border-radius:inherit;
}

/* Значок вместо пустого квадрата у озвучки: там показывать нечего,
   но и серая дыра в строке выглядит как незагрузившаяся картинка. */
.hrow__ico{
  position:absolute;inset:0;display:grid;place-items:center;
  color:var(--text-3);
}

/* Запущенный ролик разворачивается на всю строку: смотреть видео в
   квадратике пятьдесят восемь на пятьдесят восемь невозможно. */
.hrow--playing{flex-direction:column;align-items:stretch}
.hrow--playing .hrow__cov{width:100%;height:auto;aspect-ratio:16/9;margin-bottom:8px}
.hrow--playing .hrow__cov video{height:100%}

/* ============================================================
   СВОЙ ГОЛОС

   Три шага нарисованы сразу: человек должен видеть, во что ввязывается,
   до того как нажмёт «разрешить микрофон». Скрывать второй шаг и
   выкатывать его сюрпризом - верный способ получить брошенную запись.
   ============================================================ */
.vsteps{list-style:none;margin:0 0 18px;padding:0;display:flex;flex-direction:column;gap:9px;counter-reset:v}
.vstep{
  position:relative;padding:11px 13px 11px 44px;border-radius:var(--radius);
  background:var(--surface-2);color:var(--text-3);counter-increment:v;
}
.vstep::before{
  content:counter(v);position:absolute;left:12px;top:11px;
  width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface);color:var(--text-3);font-size:12px;font-weight:700;
}
.vstep b{display:block;font-size:14px;color:var(--text-2)}
.vstep span{display:block;margin-top:2px;font-size:12.5px;line-height:1.45}
.vstep--on{background:var(--accent-soft);color:var(--text-2)}
.vstep--on b{color:var(--text)}
.vstep--on::before{background:var(--accent);color:var(--on-accent)}
.vstep--done::before{content:"✓";background:var(--ok-soft);color:var(--ok)}

/* Поле имени и кнопка записи - во всю ширину своей панели.

   Общее правило держит поля и широкие кнопки в 1100 пикселях: длинную
   строку читать неудобно. Здесь оно давало нелепицу - три блока с
   правилами наверху идут во всю панель, а поле и кнопка под ними
   обрываются, не дотянув до края: и не по ширине панели, и не
   аккуратным коротким полем. Внутри этой панели равняем по ней. */
.vrec{margin-top:14px}
.gen--solo .input,
.gen--solo .btn--wide,
.gen--solo textarea{max-width:none}
.vrec__time{
  margin-top:9px;text-align:center;font-size:15px;font-weight:700;
  color:var(--danger);font-variant-numeric:tabular-nums;
}

/* Фраза - крупно. Её поют, глядя в экран с расстояния вытянутой руки,
   и мелкий шрифт здесь означает, что человек будет щуриться вместо
   того, чтобы петь. */
.vphrase{
  margin-top:14px;padding:16px;border-radius:var(--radius);
  background:var(--surface-2);text-align:center;
}
.vphrase__t{font-size:12.5px;color:var(--text-3);margin-bottom:8px}
.vphrase__q{font-size:21px;font-weight:700;line-height:1.4;color:var(--text)}

.vdone{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-top:14px;padding:13px 15px;border-radius:var(--radius);
  background:var(--ok-soft);color:var(--ok);font-size:13.5px;line-height:1.45;
}
.vdone > div{flex:1;min-width:200px}
.vdone strong{display:block;color:var(--text)}
.vdone .ico{flex:0 0 auto}
.vdone .btn{flex:0 0 auto}

/* Строка голоса в списке: значок вместо обложки, слушать нечего. */
.hrow--voice .hrow__cov{background:var(--surface-2)}

/* Приглашение записать голос там, где о нём вспоминают, - в форме
   песни, рядом с выбором исполнителя. */
.vnone{
  display:flex;align-items:center;gap:11px;flex-wrap:wrap;
  padding:11px 13px;border-radius:var(--radius);
  background:var(--surface-2);font-size:13px;line-height:1.45;color:var(--text-2);
}
.vnone > div{flex:1;min-width:190px}
.vnone .ico{flex:0 0 auto;color:var(--text-3)}
.vnone .btn{flex:0 0 auto;background:var(--surface)}
.vnone .btn:hover{background:var(--surface-3)}

/* Значок вида голоса внутри чипа выбора. */
.chip svg{vertical-align:-2px;opacity:.75}

/* Свой голос выбран, а движок его не поёт. Не ошибка формы - её ещё
   можно исправить одним нажатием, - но и не подсказка: пропустишь,
   и песня выйдет чужим голосом. Отсюда жёлтый, а не красный. */
.vwarn{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px;
  padding:9px 12px;border-radius:var(--radius);
  background:var(--warn-soft);color:var(--warn);
  font-size:13px;line-height:1.45;
}
.vwarn > div{flex:1;min-width:180px}
.vwarn .ico{flex:0 0 auto}
.vwarn .btn{flex:0 0 auto;background:var(--surface);color:var(--text)}
.pick--bad .pick__btn{border-color:var(--warn);color:var(--warn)}

/* Свой голос в ряду с мужским и женским. Отличается значком и лёгкой
   заливкой: он не «ещё одна настройка», а именно твой голос, и найти
   его в ряду нужно с одного взгляда. */
.chip--my{gap:6px;display:inline-flex;align-items:center}
.chip--my svg{opacity:.7}
.chip--my.chip--on svg{opacity:1}
.vmine{margin-top:7px}

/* Счётчик записи на исходе: последние пять секунд подсвечены, чтобы
   остановка не выглядела обрывом. */
.vrec__time--end{color:var(--warn);font-weight:600}

/* Кнопка «Ещё N» и ссылка «Записать» стоят в ряду голосов, но выбором
   не являются - поэтому они тише и с пунктиром. */
.chip--more,.chip--add{border-style:dashed;color:var(--text-3)}
.chip--more:hover,.chip--add:hover{border-color:var(--accent);color:var(--text-2)}
.chip--add{display:inline-flex;align-items:center;gap:6px;text-decoration:none}

/* Заголовок «Мои голоса» и кнопка записи в одной строке. */
.vhead{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.vhead h3{flex:1;margin:0}

/* Тумблер «слушать стиль при выборе».

   Настоящий переключатель, а не чекбокс: у него два внятных положения,
   и человек видит, включён звук или нет, не читая подпись. Флажок в
   этом месте читался бы как «согласен с условиями». */
/* Мишень - вся строка с подписью, а не тумблер в двадцать два
   пикселя: в него одного пальцем не попасть. */
.sprev{
  display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  min-height:var(--ctl-sm);margin-bottom:10px;user-select:none;
}
.sprev input{position:absolute;opacity:0;width:0;height:0}
.sprev__t{font-size:13px;color:var(--text-2)}
.sprev input:checked ~ .sprev__t{color:var(--text)}

.sw{
  position:relative;flex:0 0 auto;width:38px;height:22px;border-radius:999px;
  background:var(--surface-3);border:1px solid var(--border);
  transition:background .14s,border-color .14s;
}
.sw__k{
  position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:var(--surface);box-shadow:0 1px 3px rgba(0,0,0,.25);
  transition:transform .14s;
}
.sprev input:checked + .sw{background:var(--accent);border-color:var(--accent)}
.sprev input:checked + .sw .sw__k{transform:translateX(16px)}
.sprev input:focus-visible + .sw{outline:2px solid var(--accent);outline-offset:2px}

/* Полоса «тестовый режим». Не тревога - предупреждение, поэтому жёлтая
   и тонкая: она висит неделями, и красная за это время стала бы
   привычным шумом, который перестают замечать. */
.testbar{
  display:flex;align-items:center;gap:9px;
  margin:0 0 14px;padding:8px 12px;
  border-radius:var(--radius);background:var(--warn-soft);color:var(--warn);
  font-size:13px;line-height:1.45;
}
.testbar .ico{flex:0 0 auto}

/* ПОЛОСА ПЕРЕБОЕВ - ПРИКЛЕЕНА К НИЗУ ЭКРАНА.

   Не в потоке страницы, а поверх неё: так она не сдвигает вёрстку при
   появлении и видна на любой прокрутке. Ниже неё нет ничего - даже
   проигрыватель поднимается, чтобы её не перекрыть (см. .pbar ниже).

   Цвет плотный, а не бледный: это единственное место, где сервис
   говорит «сейчас не работает», и оно не должно теряться среди
   подсказок. */
.downbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  background:var(--danger);color:#fff;
  box-shadow:0 -6px 24px rgba(0,0,0,.14);
  font-size:13.5px;line-height:1.45;
}
.downbar__in{
  display:flex;align-items:center;justify-content:center;gap:10px;
  max-width:1280px;margin:0 auto;
  padding:11px 16px calc(11px + env(safe-area-inset-bottom,0px));
}
.downbar .ico{flex:0 0 auto;color:#fff}
.downbar b{color:#fff}

/* Проигрыватель уступает полосе место: две липкие полосы на одном
   краю экрана иначе накладываются, и нижняя оказывается нечитаемой. */
body:has(.downbar) .pbar{bottom:52px}
@media (max-width:600px){ body:has(.downbar) .pbar{bottom:72px} }

/* Выбор из двух режимов в админке: крупные карточки вместо кружков -
   на них не промахиваются, и подпись объясняет, что случится. */
.segs{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.segs__i{
  display:block;padding:12px 14px;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);
  transition:border-color .12s,background .12s;
}
.segs__i:hover{border-color:var(--accent)}
.segs__i--on{border-color:var(--accent);background:var(--surface-2)}
.segs__i input{margin-right:8px;accent-color:var(--accent)}
.segs__i b{font-size:14px}
.segs__i span{display:block;margin-top:3px;font-size:12.5px;color:var(--text-3);line-height:1.4}

/* ============================================================
   НИЖНЯЯ ПОЛОСА ПЛЕЕРА

   ЗАЧЕМ ОНА. Готовая песня играла из крошечного треугольника на
   обложке в строке списка. Пока строка на экране, всё честно; но
   человек тут же уходит листать каталог стилей, читать текст или
   заказывать вторую песню - и единственная кнопка «пауза» уезжает
   вверх вместе со списком. Музыка играет, выключить её нечем, и
   спасает только перезагрузка страницы.

   ЧЕГО ЗДЕСЬ НЕТ. Полоса не появляется на образец стиля из каталога.
   Демка - это примерка на пять секунд, а не прослушивание своей
   работы: полоса под ней мигала бы на каждом втором нажатии и мешала
   именно там, где человек быстрее всего перебирает варианты.
   Технически до неё и не дотянуться - у каталога свой <audio>.

   ПОЧЕМУ КАРТОЧКА, А НЕ ПОЛОСА ВО ВСЮ ШИРИНУ. Полоса от края до края
   в «Афише» читается как ещё одна панель сайта и спорит с нижними
   вкладками, которые стоят ровно под ней. Приподнятая карточка со
   скруглением и тенью сразу видна как временная вещь поверх страницы -
   такая же, как всплывающая подсказка.
   ============================================================ */
.pbar{
  position:fixed;left:0;right:0;bottom:0;z-index:39;
  padding:0 12px calc(10px + env(safe-area-inset-bottom,0px));
  /* Пока полоса уезжает, нажатия сквозь неё проходят на страницу: ловить
     их полупрозрачной уходящей карточкой человек не просил. */
  pointer-events:none;
  transform:translateY(130%);opacity:0;
  transition:transform .28s ease,opacity .2s ease,left .16s;
}
.pbar--on{transform:none;opacity:1;pointer-events:auto}

.pbar__in{
  display:grid;align-items:center;gap:7px 11px;
  max-width:1200px;margin:0 auto;padding:9px 10px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);
  /* Телефон: обложка, название, пуск и крестик в строку, перемотка -
     отдельной строкой во всю ширину. Ужать её в тот же ряд значит
     оставить полоске времени сорок пикселей, по которым не попасть. */
  grid-template-columns:auto minmax(0,1fr) auto auto;
  grid-template-areas:
    "cov info pp x"
    "seek seek seek seek";
}

.pbar__cov{
  grid-area:cov;width:44px;height:44px;
  border-radius:var(--radius-xs);overflow:hidden;background:var(--surface-3);
}
.pbar__cov img{width:100%;height:100%;object-fit:cover;display:block}

.pbar__b{grid-area:info;min-width:0}
.pbar__t{
  font-family:var(--font-head);font-size:15px;font-weight:700;letter-spacing:-.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.pbar__s{
  margin-top:2px;font-size:12.5px;color:var(--text-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Пуск и пауза - тем же приёмом, что и треугольник на строке списка:
   два значка вместо одного пришлось бы держать в разметке и прятать
   поочерёдно, а фигуры из формы кнопки не расходятся с ней никогда. */
.pbar__pp{
  grid-area:pp;width:var(--ctl-sm);height:var(--ctl-sm);
  display:grid;place-items:center;cursor:pointer;
  border:0;border-radius:var(--radius-sm);
  background:var(--accent);color:var(--on-accent);
}
.pbar__pp:hover{filter:brightness(1.1)}
.pbar__pp::before{
  content:"";width:0;height:0;margin-left:3px;
  border-top:7px solid transparent;border-bottom:7px solid transparent;
  border-left:11px solid currentColor;
}
.pbar--play .pbar__pp::before{
  width:11px;height:12px;margin:0;border:0;background:currentColor;
  clip-path:polygon(0 0,34% 0,34% 100%,0 100%,0 0,66% 0,100% 0,100% 100%,66% 100%,66% 0);
}

.pbar__x{
  grid-area:x;width:var(--ctl-sm);height:var(--ctl-sm);
  display:grid;place-items:center;cursor:pointer;
  border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-3);
  transition:background .14s,color .14s;
}
.pbar__x:hover{background:var(--surface-2);color:var(--text)}

.pbar__seek{grid-area:seek;display:flex;align-items:center;gap:9px;min-width:0}
.pbar__vol{grid-area:vol;display:none;align-items:center;gap:7px;width:118px;color:var(--text-3)}
.pbar__vol .ico{flex:0 0 auto}
.pbar__time{
  flex:0 0 auto;font-size:11.5px;font-weight:600;color:var(--text-3);
  font-variant-numeric:tabular-nums;
}

/* Дорожка сама показывает, сколько сыграно: долю в процентах вписывает
   JS в --p, а градиент рисует её и в Chrome, и в Firefox одинаково.
   Отдельного залитого слоя под ползунком не нужно. */
.pbar__seek input[type=range],
.pbar__vol input[type=range]{
  -webkit-appearance:none;appearance:none;
  --p:0%;
  flex:1;min-width:0;height:22px;margin:0;background:transparent;cursor:pointer;
}
.pbar__seek input[type=range]::-webkit-slider-runnable-track,
.pbar__vol input[type=range]::-webkit-slider-runnable-track{
  height:5px;border-radius:999px;
  background:linear-gradient(to right,var(--accent) 0 var(--p),var(--surface-3) var(--p) 100%);
}
.pbar__seek input[type=range]::-moz-range-track,
.pbar__vol input[type=range]::-moz-range-track{
  height:5px;border-radius:999px;
  background:linear-gradient(to right,var(--accent) 0 var(--p),var(--surface-3) var(--p) 100%);
}
.pbar__seek input[type=range]::-webkit-slider-thumb,
.pbar__vol input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:14px;height:14px;margin-top:-4.5px;border-radius:50%;
  background:var(--accent);border:2px solid var(--surface);
  box-shadow:0 1px 4px rgba(0,0,0,.28);
}
.pbar__seek input[type=range]::-moz-range-thumb,
.pbar__vol input[type=range]::-moz-range-thumb{
  width:14px;height:14px;border-radius:50%;
  background:var(--accent);border:2px solid var(--surface);
  box-shadow:0 1px 4px rgba(0,0,0,.28);
}
.pbar__seek input[type=range]:focus-visible,
.pbar__vol input[type=range]:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* Телефон: остаются обложка, название, пуск и перемотка. Стиль под
   названием и цифры времени уходят - на трёхстах девяноста пикселях
   каждая лишняя надпись отгрызает у названия по слову. */
@media (max-width:599.98px){
  /* Нижние вкладки стоят ровно здесь, и перекрывать их полосе нельзя:
     это единственная навигация телефона. Разводим по месту, а не по
     слоям - под полупрозрачной карточкой вкладки всё равно не нажать. */
  .pbar{bottom:calc(var(--tabbar) + env(safe-area-inset-bottom,0px));padding-bottom:10px}
  .pbar__s,.pbar__time{display:none}
}
@media (max-width:359.98px){
  .pbar{padding-left:8px;padding-right:8px}
  .pbar__in{gap:6px 9px;padding:8px}
  .pbar__cov{width:40px;height:40px}
}

/* Начиная с планшета всё встаёт в один ряд: место есть, а вторая
   строка ради одной полоски времени выглядит недоделкой. */
@media (min-width:900px){
  .pbar{left:var(--sidebar);padding-bottom:14px}
  body.nav--min .pbar{left:var(--sidebar-min)}
  .pbar__in{
    gap:14px;padding:10px 14px;
    grid-template-columns:auto minmax(110px,1fr) auto minmax(190px,2fr) auto;
    grid-template-areas:"cov info pp seek x";
  }
}
@media (min-width:1100px){
  .pbar__in{
    grid-template-columns:auto minmax(120px,1fr) auto minmax(220px,2fr) auto auto;
    grid-template-areas:"cov info pp seek vol x";
  }
  .pbar__vol{display:flex}
}

/* Кому движение мешает - тому полоса просто появляется и пропадает.
   Смысл её от этого не меняется. */
@media (prefers-reduced-motion:reduce){
  .pbar{transition:none}
}

/* ============================================================
   ПОДВАЛ И ДОКУМЕНТЫ

   Низ страницы - место, куда смотрит человек, решающий, платить ли
   незнакомому сайту. Там должно быть видно, чьё это хозяйство, куда
   писать и по какому договору всё происходит. Того же требует и
   платёжная касса при подключении.
   ============================================================ */
.foot{
  margin-top:44px;padding-top:26px;
  border-top:1px solid var(--border);
  color:var(--text-3);font-size:13.5px;line-height:1.6;
}
/* Колонки не пересчитываются по ширине окна, а укладываются сами:
   сколько влезло - столько и в ряду. На телефоне выходит одна. */
/* Подвал держится той же колонки, что и содержимое.

   Он лежит снаружи .wrap - на всю ширину рабочей области, - и без
   этого потолка на широком мониторе разъезжался бы с текстом над
   собой: верх страницы по центру, низ во всю ширь. */
.foot__in,.foot__line{max-width:1280px;margin-inline:auto}
.foot__in{
  display:grid;gap:22px 32px;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
}
.foot__col--me{grid-column:span 2;min-width:0}
@media (max-width:700px){ .foot__col--me{grid-column:auto} }
.foot__logo{
  font-family:var(--font-head);font-size:19px;font-weight:800;
  letter-spacing:-.02em;color:var(--text);margin-bottom:7px;
}
.foot__col p{margin:0 0 8px;max-width:44ch}
.foot__req{font-size:12.5px;opacity:.85}
.foot h4{
  font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-2);margin:0 0 10px;
}
.foot__col a{
  display:block;color:var(--text-2);text-decoration:none;
  padding:3px 0;transition:color .12s;
}
.foot__col a:hover{color:var(--accent-text)}
.foot__hours{display:block;padding-top:6px;font-size:12.5px}
.foot__line{
  display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:space-between;
  margin-top:22px;padding:14px 0 4px;
  border-top:1px solid var(--border);font-size:12.5px;
}

/* --- Страница документа --- */
/* Ширина строки, а не ширина монитора: длинную юридическую строку глаз
   проходит и теряет начало следующей. Семьдесят знаков - предел, за
   которым чтение становится работой. */
.doc{max-width:72ch}
.doc h2{
  font-family:var(--font-head);font-size:20px;font-weight:800;letter-spacing:-.02em;
  color:var(--text);margin:26px 0 10px;
}
.doc h2:first-child{margin-top:6px}
.doc h3{font-size:16px;font-weight:700;color:var(--text);margin:18px 0 8px}
.doc p,.doc li{font-size:14.5px;line-height:1.7;color:var(--text-2)}
.doc p{margin:0 0 10px}
.doc ul,.doc ol{margin:0 0 12px;padding-left:22px}
.doc li{margin-bottom:5px}
.doc a{color:var(--accent-text)}
.doc__date{font-size:12.5px;color:var(--text-3);margin-bottom:16px}

/* Таблица тарифов и реквизитов. На телефоне уезжает вбок внутри своей
   рамки, а не растягивает страницу. */
.doctab{
  width:100%;border-collapse:collapse;margin:10px 0 16px;
  font-size:14px;display:block;overflow-x:auto;
}
.doctab th,.doctab td{
  padding:9px 12px 9px 0;text-align:left;vertical-align:top;
  border-top:1px solid var(--border);
}
.doctab tr:first-child th{border-top:0;color:var(--text-3);font-size:12.5px;
  font-weight:700;letter-spacing:.03em;text-transform:uppercase}
.doctab th{color:var(--text-2);font-weight:600;white-space:nowrap}
.doctab td{color:var(--text-2)}
.doctab__n{white-space:nowrap;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text)}

/* Оглавление документов: чипы, как везде на сайте */
.docnav{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:20px}
.docnav__i{
  padding:7px 13px;border-radius:var(--radius-sm);
  background:var(--surface-2);color:var(--text-2);
  text-decoration:none;font-size:13.5px;font-weight:600;
  transition:background .12s,color .12s;
}
.docnav__i:hover{background:var(--surface-3);color:var(--text)}
.docnav__i--on{background:var(--accent-soft);color:var(--accent-text)}

/* Примеры вопросов на пустом экране чата.

   Ряд коротких фраз, каждая заполняет поле ввода в одно нажатие. Перед
   пустым полем человек не знает, о чём тут вообще спрашивать, и уходит;
   три примера отвечают на этот вопрос быстрее любой подсказки. */
.asks{display:flex;flex-direction:column;gap:8px;margin-top:16px;width:100%;max-width:520px}
.ask__b{
  text-align:left;cursor:pointer;font:inherit;font-size:13.5px;line-height:1.45;
  padding:10px 14px;border-radius:var(--radius);
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);
  transition:border-color .12s,color .12s,background .12s;
}
.ask__b:hover{border-color:var(--accent);color:var(--text);background:var(--surface-2)}
.chat--off .ask__b{cursor:default;opacity:.7}
.chat--off .ask__b:hover{border-color:var(--border);color:var(--text-2);background:var(--surface)}
