/*
 * ОФОРМЛЕНИЕ КАБИНЕТА — «УЛЬТРА».
 *
 * Файл перенесён из макета docs/design/cabinet.html без переделки: там он был
 * утверждён целиком — от цвета до отступов, — и любое «улучшение на месте»
 * означало бы, что кабинет уже не 1в1 с тем, что смотрели.
 *
 * ОДИН ИСТОЧНИК НА СТРАНИЦУ. Страницы кабинета подключают ТОЛЬКО этот файл:
 * ни base.css, ни cabinet.css, ни components.css. Старая сборка (tokens + шесть
 * файлов) остаётся для витрины и страницы входа, пока их не перенесли так же;
 * смешивать их на одной странице нельзя — там другие имена классов и другая
 * шкала поверхностей.
 *
 * ДЕНЬ И НОЧЬ. Единственная ось — атрибут data-theme на <html>. Без него
 * действует ночная тема: кабинет открывают и с выключенным JavaScript (Tor
 * Browser), и там переключатель просто не появится, а страница останется рабочей.
 */
/* ==========================================================================
   ЛИЧНЫЙ КАБИНЕТ ЦЕЛИКОМ
   --------------------------------------------------------------------------
   Здесь не «красивая страница», а ВЕСЬ функционал, который кабинет умеет
   сегодня, разложенный по экранам. Сверено по коду, а не по памяти:
   routes/public.php, resources/views/user/*, lang/uk/{orders,billing,checkout,
   nav,pages}.php.

   Правило разбора: у каждого действия есть ровно одно место, и это место
   определяется ЧАСТОТОЙ, а не удобством вёрстки.

     на карточке      то, что делают каждую неделю          Продлить, Скачать
     в меню «⋯»       то, что делают раз в месяц-два        Изменить IP/регион/
                                                            протокол, Переименовать,
                                                            Уведомления
     на странице      то, что делают один раз и с опаской   Удалить
     заказа, внизу

   Старая карточка держала все семь действий разом — и получалась стена, в
   которой «Продлить» весило ровно столько же, сколько «Изменить протокол».
   ========================================================================== */

/* ------------------------------------------------------------ ЦВЕТ ------ */
:root{
  --bg:#DCE3E9; --surface:#F6F9FB; --surface-2:#E9EFF4;
  --ink:#16232B; --ink-2:#55666F; --line:#C5D0D9;
  --brand:#0AA2E0; --brand-strong:#06688F; --brand-ink:#FFFFFF; --brand-soft:#D3EDF9;
  --accent:#8FD400; --accent-strong:#4C6E00; --accent-soft:#E6F6C4;
  --grad:linear-gradient(100deg,#0AA2E0 0%,#1CC9B4 55%,#A8E22B 100%);
  --grad-cool:linear-gradient(100deg,#0AA2E0 0%,#1CC9B4 100%);
  --ok:#0F9D58; --ok-soft:#D5F0E1; --warn:#B45309; --warn-soft:#F8E7C8;
  --bad:#E23A48; --bad-soft:#FBD9DC; --tint:10,162,224;
  /* «Замена» — отдельное состояние, а не оттенок прочих: сервер уже был, его
     сейчас меняют. Зелёный читался как «всё хорошо», красный — как «сломалось». */
  --busy:#5D48D6; --busy-soft:#E4E0FB;

  /*
   * СТУПЕНИ ТАРИФОВ. Это не цвета состояния, а ШКАЛА: серый → зелёный → синий →
   * фиолетовый → жёлтый → оранжевый, от обычного до мифического. Порядок задаёт
   * App\Models\Tariff::COLORS, подписи — lang/<язык>/tariffs.php.
   *
   * ЗВЁЗДОЧКА С КОСОЙ ЧЕРТОЙ В ЭТОМ ПУТИ НЕ ПИШЕТСЯ. Раньше строкой выше стояло
   * lang/ звёздочка коса-черта tariffs.php — и эта последовательность ЗАКРЫВАЛА
   * комментарий прямо посреди фразы. Всё до конца этого блока парсер читал как
   * испорченное объявление и глотал до первой точки с запятой — то есть вместе
   * с --tier ниже. Переменная просто не попадала в :root, и запасной цвет
   * тарифа не работал: ни ошибки, ни предупреждения, ни следа в консоли.
   *
   * Та же ловушка описана в app/Services/Audit.php — там путь тоже записан
   * словами. Проект знал про неё и всё равно наступил второй раз.
   *
   * Палитра своя, а не из токенов состояний: зелёный ступени не должен означать
   * «всё хорошо», а красного тут нет вовсе — иначе самый дорогой тариф читался
   * бы как ошибка. Значения подобраны так, чтобы все шесть оставались
   * различимыми и на светлом, и на тёмном.
   */
  /* Запасной цвет тарифа: серый. Значение лежит в базе, тут — лишь то, чем
     рисовать, если в разметку ничего не приехало. */
  --tier:#64748B;
}
:root{--brand-deep:#06688F; --raised:#FFFFFF; --inv-bg:#16232B; --inv-ink:#FFFFFF}

/* ----------------------------------------------------- НОЧНАЯ ТЕМА ------ */
/* Насыщенность фона 6–10% при светлоте 12–18%: тёмное и насыщенное
   одновременно читается как грязное пятно, а не как темнота. Градиенты на
   больших площадях ночью взяты глубже дневных. */
[data-theme="dark"]{
  --bg:#1C1E22; --surface:#262930; --surface-2:#2F333B; --raised:#3A3F48;
  --ink:#ECEEF2; --ink-2:#A0A6B0; --line:#383D45;
  --brand:#2BC4F5; --brand-strong:#8FDFFA; --brand-deep:#06688F; --brand-ink:#082430; --brand-soft:#173846;
  --accent:#A6D93C; --accent-strong:#CBEA85; --accent-soft:#2A3620;
  --grad:linear-gradient(100deg,#1C86B8 0%,#1BA79C 55%,#7FA736 100%);
  --grad-cool:linear-gradient(100deg,#1C86B8 0%,#1BA79C 100%);
  --ok:#35C07E; --ok-soft:#1B3329; --warn:#DFAE63; --warn-soft:#383025;
  --bad:#EF6273; --bad-soft:#3A262A; --inv-bg:#ECEEF2; --inv-ink:#1C1E22; --tint:43,196,245;
  --busy:#A594F5; --busy-soft:#2E2A45;
}

/* Поле ввода днём БЕЛОЕ, то есть СВЕТЛЕЕ карточки: фон страницы теперь
   приглушён, и поле того же цвета, что карточка, слилось бы с ней. */


html{--grad-ink:#FFFFFF}
:root{--field:#FFFFFF}
[data-theme="dark"]{--field:var(--bg)}

/* ----------------------------------------------------------- ФОРМА ------ */
:root{
  --r-card:18px; --r-ctl:12px; --r-chip:999px; --bw:1px; --card-line:var(--line);
  --sh-card:0 1px 2px rgba(25,23,51,.08), 0 6px 16px rgba(25,23,51,.07);
  --sh-btn:0 6px 16px rgba(var(--tint),.28); --btn-caps:none; --btn-track:0; --btn-weight:700;
}

/* СВЕЧЕНИЕ НОЧЬЮ УБРАНО.
   Цветная тень днём читается как мягкая подсветка под карточкой. Ночью ТА ЖЕ
   тень превращается в ореол вокруг каждой кнопки — светится весь экран разом,
   и глазу не за что зацепиться. Ночью глубину даёт перепад светлоты
   поверхностей, а тень остаётся нейтральной и почти незаметной. */
[data-theme="dark"]{
  --sh-card:0 1px 0 rgba(255,255,255,.03), 0 8px 20px rgba(0,0,0,.30);
  --sh-btn:0 2px 6px rgba(0,0,0,.30);
}
:root{--sh-pop:0 24px 60px rgba(var(--tint),.24)}
[data-theme="dark"]{--sh-pop:0 24px 60px rgba(0,0,0,.55)}

/* ------------------------------------------------------------ БАЗА ------ */
*{box-sizing:border-box}
body{margin:0; background:var(--bg); color:var(--ink);
  font:15.5px/1.55 -apple-system,"Segoe UI",Roboto,Ubuntu,"Helvetica Neue",sans-serif}

.switcher{
  position:sticky; top:0; z-index:60; background:var(--surface); border-bottom:1px solid var(--line);
  padding:9px 16px; display:flex; flex-wrap:wrap; gap:16px; align-items:center;
}
.switcher .g{display:flex; align-items:center; gap:6px}
.switcher .cap{font-size:10px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-2)}
.switcher button{font:inherit; font-size:12.5px; font-weight:700; cursor:pointer; padding:5px 11px;
  border-radius:999px; border:1px solid var(--line); background:transparent; color:var(--ink)}
.switcher button[aria-pressed="true"]{background:var(--ink); color:var(--bg); border-color:var(--ink)}
.switcher .home{margin-left:auto; font-size:13px; color:var(--ink-2); text-decoration:none}

/* --------------------------------------------------------- КАРКАС ------ */
.app{display:grid; grid-template-columns:236px 1fr; min-height:100vh}
@media (max-width:900px){ .app{grid-template-columns:1fr} }

/* МЕНЮ — ЭТО ПАНЕЛЬ, А НЕ ПОЛЕ СЛЕВА.
   Раньше оно лежало прямо на полотне страницы, то есть имело тот самый
   цвет, что и пустое место вокруг, и отделяла его одна волосяная
   линия. На светлой теме этого не видно вовсе. Теперь у него своя
   поверхность — та же, что у карточек, — и граница читается сама собой. */
.side{
  background:var(--surface); border-right:1px solid var(--line);
  padding:20px 14px 26px; display:flex; flex-direction:column;
  /* Нуль, а не 46: отступ был высотой демонстрационной полосы, которую убрали.
     Меню оставалось сдвинутым на неё вниз и на столько же не доходило до низа. */
  position:sticky; top:0; height:100vh;
}
@media (max-width:900px){ .side{display:none} }
.brand{display:flex; align-items:center; gap:10px; font-weight:800; font-size:17px; padding:0 8px 18px}
.brand .mark{width:30px; height:30px; border-radius:9px; background:var(--grad); flex:none}
/* Когда логотип загружен — это <img> с тем же классом: заполняем квадрат
   изображением без искажения, градиент-заглушка больше не нужна. */
.brand img.mark{object-fit:cover; background:none}

/* КОШЕЛЁК В МЕНЮ, А НЕ НА СТРАНИЦЕ «ПЛАТЕЖИ».
   Баланс решает, можно ли нажать «Продлить», поэтому он нужен на КАЖДОМ
   экране, а не только там, где деньгами занимаются специально. */
.wallet{background:var(--surface-2); border-radius:var(--r-card); padding:13px 15px; margin-bottom:16px}
.wallet .k{font-size:10px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-2)}
.wallet .v{font-size:26px; font-weight:800; letter-spacing:-.02em; margin:2px 0 9px}
.wallet .btn{width:100%; text-align:center}

.menu{display:flex; flex-direction:column; gap:2px; flex:1}
.menu a{
  display:flex; align-items:center; gap:11px; padding:10px 12px; border-radius:var(--r-ctl);
  text-decoration:none; color:var(--ink-2); font-weight:600; font-size:14.5px; cursor:pointer;
}
.menu a:hover{background:var(--surface-2); color:var(--ink)}
/* Выбранный пункт — градиентом, а не бледной заливкой: это единственная
   отметка «вы здесь» на весь каркас, и она должна читаться с первого взгляда. */
.menu a[aria-current]{background:var(--grad-cool); background-origin:border-box;
  background-repeat:no-repeat; color:var(--grad-ink)}
.menu a[aria-current] .ic{color:var(--grad-ink)}
.menu .ic{width:19px; text-align:center; font-size:15px; flex:none}
.menu .sep{height:1px; background:var(--line); margin:10px 4px}
.menu .out{margin-top:auto}

/* Нижняя панель — мобильный дубликат меню. Пять пунктов, не больше:
   шестой на телефоне уже не попадается пальцем. */
.tabbar{
  display:none; position:fixed; left:0; right:0; bottom:0; z-index:50;
  background:var(--surface); border-top:1px solid var(--line); padding:6px 4px;
}
@media (max-width:900px){ .tabbar{display:grid; grid-template-columns:repeat(5,1fr)} }
.tabbar a{
  display:flex; flex-direction:column; align-items:center; gap:3px; padding:7px 2px; cursor:pointer;
  text-decoration:none; color:var(--ink-2); font-size:10.5px; font-weight:700;
}
.tabbar a[aria-current]{color:var(--brand-strong)}
.tabbar .ic{font-size:18px; line-height:1}

/*
 * min-width:0 — НЕ УКРАШЕНИЕ, А ЕДИНСТВЕННОЕ, ЧТО ДЕРЖИТ ТЕЛЕФОН.
 *
 * .app — сетка, а элемент сетки по умолчанию имеет min-width:auto: он не может
 * стать уже собственного самого широкого содержимого. На экране 375 px это
 * раздувало <main> до 473 px, и страница ехала вбок целиком — вместе с нижней
 * панелью, карточкой аккаунта и балансом, который выглядел обрезанным.
 *
 * Причина была не в конкретном блоке, а именно в этом правиле сетки: стоит
 * разрешить <main> сжиматься — и всё внутри укладывается само, ведь полосы
 * фильтров и без того прокручиваются.
 */
main{padding:20px 26px 90px; max-width:1480px; width:100%; margin:0 auto; min-width:0}

/* Ширина по назначению экрана. Списки и таблицы выигрывают от простора,
   сплошной текст — наоборот: строку на 1500 px читать невозможно, глаз не
   находит начало следующей. */
#s-order{max-width:1120px}
#s-topup{max-width:1200px}
#s-help{max-width:940px}
@media (max-width:900px){ main{padding:14px 14px 96px} }

.top{display:flex; align-items:center; gap:12px; margin-bottom:18px}
.top h1{font-size:24px; margin:0; letter-spacing:-.02em}
.top .sub{color:var(--ink-2); font-size:13.5px; margin:2px 0 0}
.top .right{margin-left:auto; display:flex; align-items:center; gap:9px}
.lang{display:flex; gap:2px; background:var(--surface-2); border-radius:999px; padding:3px}
.lang button, .lang a{font:inherit; text-decoration:none; font-size:12px; font-weight:700; cursor:pointer; border:0;
  background:transparent; color:var(--ink-2); padding:4px 9px; border-radius:999px}
.lang button[aria-pressed="true"], .lang a[aria-pressed="true"]{background:var(--raised); color:var(--ink)}
.ava{width:30px; height:30px; border-radius:50%; background:var(--surface-2);
  display:flex; align-items:center; justify-content:center; font-size:14px}
/* Кошелёк в шапке — только на телефоне, где боковой панели нет. */
.wallet-top{display:none; align-items:center; gap:8px; font-weight:800; font-size:15px}
@media (max-width:900px){ .wallet-top{display:flex} .top h1{font-size:20px} }

/* -------------------------------------------------------- ЭЛЕМЕНТЫ ---- */
/* ТРИ УРОВНЯ ГРОМКОСТИ, А НЕ ДВА.
   Раньше базовая кнопка была сплошь фиолетовой — и таким же становилось
   действие на каждой из тридцати четырёх карточек. Тридцать четыре фиолетовых
   прямоугольника на экране перестают что-то означать: громкость, которая
   звучит везде, больше не выделяет ничего, и именно она читалась «не по стилю».

   Теперь:
     .btn        мягкая заливка цветом бренда — частое действие в перечне;
     .btn.grad   градиент и тень — ОДНО главное действие экрана;
     .btn.quiet  нейтральная — второстепенное;
     .btn.bad    опасное.
*/
.btn{font:inherit; font-weight:var(--btn-weight); font-size:14px; cursor:pointer;
  padding:10px 16px; border-radius:var(--r-ctl); border:var(--bw) solid transparent;
  background:var(--brand-soft); color:var(--brand-strong); box-shadow:none;
  text-transform:var(--btn-caps); letter-spacing:var(--btn-track); text-decoration:none; display:inline-block}
.btn:hover{border-color:var(--brand)}
/* СВЕТЛАЯ ПОЛОСА СЛЕВА — ЭТО ПОВТОР ГРАДИЕНТА, И ЛЕЧИТСЯ ОН ИМЕННО ТУТ.
   У кнопки прозрачная рамка. По умолчанию фон РАСТЯГИВАЕТСЯ по padding-box
   (background-origin), а РИСУЕТСЯ по border-box (background-clip). Полоска
   под рамкой остаётся вне растянутого градиента, и туда ложится повтор —
   хвост соседней плитки, то есть КОНЕЧНЫЙ цвет градиента. В «Ультре» он
   салатовый, поэтому слева светится вертикальная линия.

   Ставить это на .btn бесполезно: background — сокращение, и строка ниже
   сбрасывает background-origin и background-repeat назад к обычным. Поэтому оба
   свойства должны стоять в том же правиле, что и сам градиент. */
/* Тень осталась только у главного действия — вместе с градиентом. На мягкой
   заливке цветной ореол читался бы как брак, а не как объём. */
.btn.grad{background:var(--grad); background-origin:border-box; background-repeat:no-repeat;
  color:var(--grad-ink); box-shadow:var(--sh-btn)}
.btn.grad:hover{border-color:transparent; filter:brightness(1.05)}
.btn.ghost{background:transparent; color:var(--brand-strong); border-color:var(--brand); box-shadow:none}
.btn.quiet{background:var(--surface-2); color:var(--ink); box-shadow:none}
.btn.bad{background:transparent; color:var(--bad); border-color:var(--bad); box-shadow:none}
.btn.sm{padding:7px 12px; font-size:13px}
.btn.wide{width:100%; text-align:center; padding:14px}
.card{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:18px; box-shadow:var(--sh-card)}
.chip{display:inline-block; font-size:11.5px; font-weight:700; padding:4px 10px;
  border-radius:var(--r-chip); background:var(--brand-soft); color:var(--brand-strong); white-space:nowrap}
.chip.ok{background:var(--ok-soft); color:var(--ok)}
.chip.warn{background:var(--warn-soft); color:var(--warn)}
.chip.bad{background:var(--bad-soft); color:var(--bad)}
.chip.acc{background:var(--accent-soft); color:var(--accent-strong)}
/* Состояния заказа — теми же цветами, что и точка списка (см. .st). */
.chip.active{background:var(--ok-soft); color:var(--ok)}
.chip.soon{background:var(--warn-soft); color:var(--warn)}
.chip.expired{background:var(--bad-soft); color:var(--bad)}
.chip.ordered{background:var(--brand-soft); color:var(--brand-strong)}
.chip.replacing{background:var(--busy-soft); color:var(--busy)}
.chip.deleted{background:var(--surface-2); color:var(--ink-2)}
.inp{width:100%; font:inherit; padding:10px 13px; border-radius:var(--r-ctl);
  border:var(--bw) solid var(--line); background:var(--field); color:var(--ink)}
.inp:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 4px rgba(var(--tint),.16)}
.inp::placeholder{color:var(--ink-2); opacity:.7}
.mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace}
.muted{color:var(--ink-2)}
/* Каждый заголовок раздела получает фирменную черту — мелкий, но постоянный
   яркий элемент, который повторяется на всех страницах. */
h2.sec{font-size:15px; margin:26px 0 10px; letter-spacing:.01em;
  display:flex; align-items:center; gap:9px}
h2.sec::before{content:""; width:4px; height:15px; border-radius:999px;
  background:var(--grad); flex:none}
.hint{font-size:12.5px; color:var(--ink-2)}

/* ---------------------------------------------------- КАРТОЧКА ЗАКАЗА -- */
.tools{display:flex; flex-wrap:wrap; gap:9px; align-items:center; margin-bottom:14px}
.tools .search{flex:1; min-width:190px; position:relative}
.tools .search .inp{padding-left:34px}
.tools .search .ic{position:absolute; left:12px; top:50%; transform:translateY(-50%); color:var(--ink-2)}

/* align-items:start — карточки не тянутся до высоты самой высокой в ряду: иначе
   в низких появлялось пустое место внизу. Каждая карточка — своей высоты. */
.orders{display:grid; grid-template-columns:repeat(auto-fill,minmax(330px,1fr)); gap:13px; align-items:start}
.ord{background:var(--surface); border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  padding:16px 17px 14px; box-shadow:var(--sh-card); cursor:pointer;
  display:flex; flex-direction:column; transition:border-color .12s ease}
.ord:hover{border-color:var(--brand)}

.ord-head{display:flex; align-items:flex-start; gap:10px; margin-bottom:12px}
.ord .flag img{width:24px; height:17px; border-radius:3px; display:block; margin-top:2px;
  box-shadow:0 0 0 1px rgba(0,0,0,.12)}
.ord-name{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; line-height:1.3}
.ord-name b{font-size:16px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
/* Номер и страна — то, чего на карточке не было вовсе. Номер копируется тем
   же элементом, что и в списке: поддержка спрашивает именно его. */
.ord-sub{display:flex; align-items:center; gap:5px; font-size:12px; color:var(--ink-2); min-width:0}
.ord-sub .cp{padding:2px 5px; margin-left:-5px; font-size:12px; font-weight:700}
.ord-head .chip{flex:none}
.dot-sep{opacity:.5}
/* Справа в шапке — состояние и управление одним столбиком: состояние сверху,
   под ним колокольчик и «⋯» в одну строку. Так они не занимают отдельной
   строки внизу карточки с кучей пустого места. */
.ord-right{display:flex; flex-direction:column; align-items:flex-end; gap:8px; flex:none}
.ord-tools{display:flex; align-items:center; gap:7px}
.ord-tools .more{margin-left:0}

.ord-ip{margin-bottom:11px; font-size:13.5px}
.ord-ip .cp{padding:3px 6px; margin-left:-6px}

.ord .bar{height:6px; border-radius:999px; background:var(--surface-2); overflow:hidden; margin-bottom:8px}
/* Заливка полосы — общее правило для КАРТОЧКИ, СТРОКИ СПИСКА и СТРАНИЦЫ
   ЗАКАЗА. Без display:block <i> остаётся строчным, и ширина в процентах
   даёт нуль.

   .term .bar i ТУТ НЕ БЫЛО, и на странице заказа полоса стояла пустая:
   вставка рисовала <i> с правильной шириной, но без цвета — то есть
   невидимый. Ширина в нём inline, поэтому и заметить было нечего.

   ЦВЕТ — ЭТО СОСТОЯНИЕ СРОКА, А НЕ МЕСТО В ПОЛОСЕ.

   Было: неподвижный градиент красный → янтарный → зелёный на всю дорожку,
   обрезанный по заполненной части. То есть у только что оплаченного заказа
   полоса начиналась с красного — и на светлой теме та красная треть читалась
   как тревога там, где всё хорошо.

   Стало: вся заполненная часть одного цвета, и считается он из доли
   --left (сколько срока осталось), которую проставляет вставка bar.blade.php:

       свыше 0.75 → зелёный      (--ok)
            ~0.35 → янтарный     (--warn)
             0.00 → красный      (--bad)

   Двумя вложенными color-mix: до 0.35 идёт участок bad→warn, от 0.35 до
   0.75 — warn→ok, выше просто зелёный. Числа именно такие, потому что шкала
   должна молчать, пока всё хорошо: зелёный держится, пока осталась четверть
   срока и больше, а красный появляется в последней десятой — там, где он и
   означает «пора продлевать».

   min()/max() тут — обрезание диапазона, а не условие, поэтому переходы
   остаются плавными, и порогов вроде «меньше семи дней — красный» нет.

   Первая строка background — запасная: если браузер не знает color-mix, все
   остальные объявления отпадают, и без неё полоса снова стала бы невидимой. */
.ord .bar i, .cell-term .b i, .term .bar i{
  display:block; height:100%; border-radius:999px;
  background:var(--ok);
  background:color-mix(in oklab,
    color-mix(in oklab, var(--bad), var(--warn) calc(min(var(--left, 1) / .35, 1) * 100%)),
    var(--ok) calc(min(max(var(--left, 1) - .35, 0) / .4, 1) * 100%));
}

/* Срок — одним предложением. Было двумя концами строки: дата слева, остаток
   справа, и читалось как два не связанных факта. */
.ord-term{margin:0 0 13px; font-size:12.5px; color:var(--ink-2)}
.ord-term.soon{color:var(--warn); font-weight:700}
.ord-term.expired{color:var(--bad); font-weight:700}

/* Характеристики — ПЛИТКАМИ 2×2: подпись сверху, значение снизу
   (Протокол | Хостер / Тариф | Цена). Компактнее прежнего списка строк и
   читается как цветные клетки. Тонкие линии между плитками даёт фон --line
   сквозь промежутки в 1px. .wide оставлен на случай нечётного числа клеток. */
.ord-facts{display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--line);
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); overflow:hidden; margin:0}
.ord-fact{display:flex; flex-direction:column; gap:2px; background:var(--surface); padding:7px 11px; min-width:0}
.ord-fact.wide{grid-column:1 / -1}
.ord-fact span{font-size:10px; color:var(--ink-2); text-transform:uppercase; letter-spacing:.04em}
.ord-fact b{font-size:13px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

/* Запасная ссылка на поддержку — только пока заказ готовится. Мелко,
   под характеристиками, без веса кнопки. */
.ord-support{display:inline-block; margin-top:11px; color:var(--brand-strong);
  font-size:12.5px; font-weight:600; text-decoration:none}
.ord-support:hover{text-decoration:underline}
.more{position:relative}
/* Правило для текстового «⋯» из первой версии карточки. Кнопка давно стала
   значком (.dots), а это осталось и перебивало ей фон: поэтому в раскрытом
   состоянии она красилась лишь текстом, а поверхность оставалась прозрачной. */
/* ОТКРЫВАЕТСЯ ВНИЗ, И ТОЛЬКО ПРИ НУЖДЕ — ВВЕРХ.
   Сначала меню всегда шло вверх: для карточки внизу экрана это правильно, а для
   первой строки списка означало, что верхние пункты — и среди них «Продлить»
   — выезжают под липкую шапку и становятся недосягаемы. Направление теперь
   выбирается по оставшемуся месту (см. обработчик data-more). */
.menu-pop{
  display:none; position:absolute; right:0; top:calc(100% + 6px); z-index:30; min-width:196px;
  background:var(--raised); border:var(--bw) solid var(--line); border-radius:var(--r-card);
  padding:5px; box-shadow:var(--sh-pop);
}
/* БЕЗ ПРЕФИКСА .ord — правило нужно обоим представлениям.
   Сначала оно было привязано к карточке, и в списке меню «⋯» не открывалось
   вовсе: класс .open ставился, а показывать его было нечему. */
.more{position:relative}
.more.open .menu-pop{display:block}
.more.up .menu-pop{top:auto; bottom:calc(100% + 7px)}
.menu-pop button, .menu-pop a{
  display:flex; text-decoration:none; width:100%; align-items:center; gap:9px; text-align:left; border:0; cursor:pointer;
  background:transparent; color:var(--ink); font:inherit; font-size:13px; font-weight:600;
  padding:6px 9px; border-radius:calc(var(--r-ctl) - 3px); line-height:1.35; white-space:nowrap;
}
.menu-pop button:hover, .menu-pop a:hover{background:var(--surface-2)}
.menu-pop .danger{color:var(--bad)}
.menu-pop form{display:contents}
/* Разделитель между ГРУППАМИ (не между каждой строкой). Был 1px на --line — на
   фоне --raised его почти не было видно. Теперь заметнее: плотнее линия
   с отступом на всю ширину меню. */
.menu-pop .sep{height:1px; background:var(--card-line); margin:5px 4px; opacity:.9}
/* ЗНАЧКИ — ЦВЕТНЫЕ ПЛИТКИ, а не серые галочки: группа узнаётся с первого
   взгляда (зелёное — скачать, голубое — продлить, фиолетовое — замены). */
.menu-pop .ic{
  width:24px; height:24px; border-radius:7px; flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--ink-2);
}
.menu-pop .ic svg{width:15px; height:15px}
.menu-pop .ic-dl{background:var(--ok-soft); color:var(--ok)}
.menu-pop .ic-renew{background:var(--brand-soft); color:var(--brand-strong)}
.menu-pop .ic-change{background:var(--busy-soft); color:var(--busy)}
.menu-pop .ic-rename,
.menu-pop .ic-details{background:var(--surface-2); color:var(--ink-2)}

/* -------------------------------------------------------- ЭКРАНЫ ------ */
.screen{display:none}
.screen.on{display:block}
.back{display:inline-flex; align-items:center; gap:6px; color:var(--ink-2);
  text-decoration:none; font-size:13.5px; font-weight:600; margin-bottom:12px; cursor:pointer}
.back:hover{color:var(--ink)}

.facts{display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--line);
  border-radius:var(--r-card); overflow:hidden; border:var(--bw) solid var(--card-line)}
@media (max-width:700px){ .facts{grid-template-columns:1fr 1fr} }
.facts>div{background:var(--surface); padding:13px 15px}
.facts .k{font-size:10.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-2)}
.facts .v{font-size:15px; font-weight:700; margin-top:3px; display:flex; align-items:center; gap:7px}

.ping{height:110px; width:100%; display:block}
.ping .grid{stroke:var(--line); stroke-width:1}
.ping .line{fill:none; stroke:var(--brand); stroke-width:2.5; stroke-linejoin:round; stroke-linecap:round}
.ping .area{fill:rgba(var(--tint),.14)}

/* Обрыв связи. Рисуется чертой, а не точкой: у графика
   preserveAspectRatio="none", он растягивается по ширине карточки — круг в
   такой системе координат превратился бы в яйцо, а черта тянется честно.
   vector-effect держит толщину линии постоянной при любом растяжении. */
.ping .gap{stroke:var(--bad); stroke-width:2; stroke-dasharray:3 4; opacity:.75;
  vector-effect:non-scaling-stroke}

/* Вертикаль под курсором — ставит скрипт, в разметке она скрыта. */
.ping .cursor{stroke:var(--ink-2); stroke-width:1; opacity:.55;
  vector-effect:non-scaling-stroke; pointer-events:none}

/* Подсказка. Обычный div, а не часть SVG: внутри растянутой системы координат
   текст поехал бы вместе с ней. */
.ping-wrap{position:relative}
.ping-tip{position:absolute; transform:translate(-50%,-140%); pointer-events:none;
  white-space:nowrap; font-size:11.5px; font-weight:700; line-height:1;
  padding:5px 8px; border-radius:var(--r-ctl); background:var(--raised); color:var(--ink);
  border:var(--bw) solid var(--line); box-shadow:0 4px 14px -6px rgba(0,0,0,.5)}
.ping-tip.bad{color:var(--bad); border-color:var(--bad)}

.files{display:grid; gap:9px}
.file{display:flex; align-items:center; gap:12px; padding:12px 14px; background:var(--surface-2);
  border-radius:var(--r-ctl)}
.file .ic{width:34px; height:34px; border-radius:calc(var(--r-ctl) - 3px); background:var(--brand-soft);
  color:var(--brand-strong); display:flex; align-items:center; justify-content:center; font-weight:800; font-size:11px; flex:none}
.file b{display:block; font-size:14px}
.file .sub{font-size:12px; color:var(--ink-2)}
.file .btn{margin-left:auto}

/* ------------------------------------------------------- НОВЫЙ ЗАКАЗ -- */
.step{margin-bottom:20px}
.step .lbl{display:flex; align-items:center; gap:9px; font-size:13px; font-weight:800;
  letter-spacing:.02em; margin-bottom:10px}
.step .n{width:22px; height:22px; border-radius:50%; background:var(--brand); color:var(--brand-ink);
  display:flex; align-items:center; justify-content:center; font-size:12px; flex:none}
/* ------------------------------------------------------------- ТАРИФЫ --- */
.plans-note{font-size:12.5px; color:var(--ink-2); margin:0 0 10px}
/* auto-fill, а не три колонки: пять карточек в сетке на три дают 3 + 2 и
   дырку сбоку. Минимум 196 px — ниже этого строки характеристик ломаются. */
.plans{display:grid; grid-template-columns:repeat(auto-fill,minmax(196px,1fr)); gap:11px}
.plan{
  display:flex; flex-direction:column; text-align:left; font:inherit; cursor:pointer;
  background:var(--surface); border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  padding:17px 16px 14px; position:relative; color:var(--ink);
}
.plan:hover{border-color:var(--brand)}
.plan[data-on]{border-color:var(--brand); background:var(--brand-soft)}
/*
 * Распроданный тариф гасим, но не ломаем.
 *
 * Одна прозрачность в половину силы делала карточку похожей на недогрузившуюся:
 * текст еле читается, а цвет всё равно лезет в глаза. Приглушаем сам цвет и
 * оставляем текст читаемым — «занято», а не «сломано».
 */
.plan[data-sold]{opacity:.62; filter:saturate(.3); cursor:not-allowed}
.plan[data-sold]:hover{transform:none; border-color:var(--tier-edge); box-shadow:none}

.plan .badge{
  position:absolute; top:-9px; left:14px; color:var(--grad-ink); font-size:10px; font-weight:800;
  letter-spacing:.08em; text-transform:uppercase; padding:3px 9px; border-radius:999px;
  background:var(--grad);
}
.plan .b-pro{background:var(--ink); color:var(--bg)}
.plan .b-new{background:var(--ok); color:#fff}
.plan .b-sale{background:var(--bad); color:#fff}
.plan .b-sold{background:var(--surface-2); color:var(--ink-2)}

/*
 * ЦВЕТ ТАРИФА НА КАРТОЧКЕ КОНФИГУРАТОРА.
 *
 * Карточка цветная целиком, а не полоской сверху: на этом шаге человек выбирает
 * именно тариф, и цвет — главная примета, по которой он их различает.
 *
 * Цвет произвольный (его задаёт администратор пипеткой), поэтому подложка и
 * граница считаются ОТ НЕГО через color-mix: любой оттенок остаётся светлым
 * пятном днём и глубоким ночью, а текст поверх — всегда обычным --ink.
 * Заливать карточку самим цветом нельзя: на жёлтом чёрный текст, на синем
 * белый, и никакое одно правило тут не работает.
 */
.plan{
  --tier-wash:color-mix(in srgb, var(--tier) 12%, var(--surface));
  --tier-edge:color-mix(in srgb, var(--tier) 45%, var(--card-line));

  /*
   * ТРИ СЛОЯ ВМЕСТО ОДНОЙ ЗАЛИВКИ.
   *
   * Было ровное пятно в 10% цвета — на тёмном фоне такое не читается вовсе, и
   * шесть карточек выглядели одинаково серыми. Теперь: мягкое пятно цвета в
   * верхнем углу (откуда «падает свет»), лёгкий градиент сверху вниз и сама
   * подложка. По отдельности каждый слой едва заметен, вместе они дают
   * карточке объём и собственный оттенок.
   *
   * Слои — в background одного элемента, а не в ::before: у карточки уже есть
   * значок с position:absolute, и лишний слой поверх него пришлось бы
   * разводить по z-index.
   */
  background:
    radial-gradient(115% 62% at 82% -12%,
      color-mix(in srgb, var(--tier) 34%, transparent), transparent 68%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--tier) 17%, var(--surface)),
      var(--tier-wash) 46%);
  border-color:var(--tier-edge);

  /* Две тени: короткая чёрная отрывает карточку от фона, длинная цветная
     кладёт под неё отсвет её же цвета. Одной чёрной мало — она читается как
     грязь под краем, а не как свет. */
  box-shadow:
    0 1px 2px rgba(0,0,0,.16),
    0 10px 24px -16px color-mix(in srgb, var(--tier) 75%, transparent);
  transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}

/* Карточка приподнимается под курсором. Смена цвета рамки этого не заменяет:
   на шести соседних карточках рамка — слишком тихий сигнал, чтобы понять,
   на какой из них ты сейчас. */
.plan:hover{
  border-color:var(--tier);
  transform:translateY(-3px);
  box-shadow:
    0 2px 5px rgba(0,0,0,.2),
    0 20px 36px -18px color-mix(in srgb, var(--tier) 85%, transparent);
}

/* Кому движение мешает — тому его и не будет. */
@media (prefers-reduced-motion:reduce){
  .plan{transition:none}
  .plan:hover{transform:none}
}

/*
 * ВЫБРАННЫЙ ТАРИФ ПОДСВЕЧИВАЕТСЯ СВОИМ ЦВЕТОМ, А НЕ ФИРМЕННЫМ.
 *
 * Сначала выделение было голубым для всех: дескать, цвет тарифа говорит «какой
 * это тариф», а выделение — «этот вы и выбрали». На экране вышло наоборот:
 * едва тариф выбирали, его цвет исчезал под одинаковой голубизной, и именно
 * выбранная карточка становилась единственной бесцветной.
 *
 * Теперь выбранное — тот же цвет, только гуще: подложка вдвое плотнее,
 * граница чистая, и кольцо вокруг. Что это именно выбор, видно по кольцу, а
 * какой тариф — по цвету.
 */
.plan[data-on]{
  --tier-wash:color-mix(in srgb, var(--tier) 26%, var(--surface));
  background:
    radial-gradient(115% 62% at 82% -12%,
      color-mix(in srgb, var(--tier) 46%, transparent), transparent 70%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--tier) 33%, var(--surface)),
      var(--tier-wash) 50%);
  border-color:var(--tier);
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--tier) 45%, transparent),
    0 18px 34px -16px color-mix(in srgb, var(--tier) 80%, transparent);
}
.plan[data-on]:hover{transform:none}

/* Название тарифа на карточке — тем же цветом, что и везде. Точки рядом
   нет: карточка уже цветная, и третий намёк на тот же цвет ничего не
   добавлял, кроме горошины возле названия. */
.p-name{
  font-size:17px; font-weight:800; letter-spacing:-.01em;
  color:color-mix(in oklab, var(--tier), var(--ink) 32%);
}

/*
 * НАЗВАНИЕ ТАРИФА ЕГО СОБСТВЕННЫМ ЦВЕТОМ — везде, где тариф лишь упоминают:
 * список заказов, карточка и страница заказа, витрина, вся панель.
 * Разметку даёт компонент <x-tariff-name>, цвет — переменная --tier в нём же.
 *
 * ПОЧЕМУ ЦВЕТ В ТЕКСТЕ, А НЕ В ТОЧКЕ РЯДОМ. Точка в плотной таблице
 * превращается в мелкую горошину сбоку: цвет видно лишь если
 * присмотреться, а название остаётся таким же серым, как всё вокруг. Текст
 * заметен сразу и не занимает ни пикселя лишнего.
 *
 * ПОЧЕМУ НЕ ЧИСТЫЙ ХЕКС. Цвет произвольный, тем две. Тёмно-синий #2563EB на
 * ночном фоне почти не читается, жёлтый #FACC15 на дневном — так же.
 * Поэтому в цвет подмешивается цвет ТЕКСТА темы: ночью --ink светлый и цвет
 * светлеет, днём тёмный — и цвет темнеет. Одно правило держит обе
 * темы и любой оттенок, не зная о них ничего.
 *
 * Смешиваем в oklab: в srgb такой микс проходит через серый и гасит тон
 * (синий с белым в srgb даёт бледно-сиреневый, в oklab — светло-синий).
 */
/*
 * УДВОЕННЫЙ КЛАСС — НЕ ПРИХОТЬ, А ЛЕКАРСТВО ОТ КОНКРЕТНОЙ ОШИБКИ.
 *
 * Название тарифа лежит внутри чужих контейнеров, и у некоторых из них есть
 * своё правило на любой span: .ord-fact span красит подписи в серый, .p-row
 * span — тоже. По специфичности (0,1,1) они перебивали обычный .tname
 * (0,1,0), и в карточке заказа тариф оставался серым, хотя цвет и приехал в
 * разметке. Ошибка из тех, которых не видно нигде, кроме самой страницы.
 *
 * Охотиться за всеми такими контейнерами — проигрышная игра: следующий
 * появится завтра. Поэтому вес поднимает сам компонент: он отвечает за свой
 * цвет везде, куда его поставили.
 *
 * Первая строка color — запасная для браузеров без color-mix(in oklab):
 * они проигнорируют второе объявление и оставят чистый цвет тарифа.
 */
.tname.tname{
  color:var(--tier);
  color:color-mix(in oklab, var(--tier), var(--ink) 38%);
  font-weight:700;
}
.tname.tname.is-dim{color:var(--ink-2); font-weight:inherit}

/* Вариант с подложкой — для заголовков карточек, где название стоит само по
   себе. В таблицах он не нужен: тридцать плашек подряд читаются
   хуже, чем тридцать цветных названий. */
.tname.is-chip{
  display:inline-block; padding:2px 9px; border-radius:999px;
  background:color-mix(in srgb, var(--tier) 16%, var(--surface));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--tier) 40%, transparent);
}
.p-note{font-size:11.5px; color:var(--ink-2); margin-top:2px; min-height:28px}
.p-price{display:flex; align-items:baseline; gap:6px; margin:8px 0 10px; flex-wrap:wrap}
/*
 * Цена — цветом тарифа, как и название.
 *
 * Самая крупная вещь на карточке была белой у всех шести, и цвет держался на
 * одном заголовке. Подмешиваем цвет текста темы (как в .tname), иначе тёмный
 * оттенок пропадёт ночью, а светлый — днём. Первая строка — запасная для
 * браузеров без color-mix(in oklab).
 */
.p-price b{
  font-size:28px; font-weight:800; letter-spacing:-.02em;
  color:var(--ink);
  color:color-mix(in oklab, var(--tier), var(--ink) 30%);
}
.p-price span{font-size:12.5px; font-weight:600; color:var(--ink-2)}
.p-price s{font-size:13px; color:var(--ink-2); order:-1}

/* Полоска скорости: «500 Мбит» и «2.5 Гбит» на глаз не сравнить, длину — можно. */
.p-bar{height:4px; border-radius:999px; background:var(--surface-2); overflow:hidden; margin-bottom:12px}
.p-bar i{display:block; height:100%; background:var(--grad)}

/* Одинаковые строки в одинаковом порядке — чтобы карточки читались вширь. */
.p-rows{display:flex; flex-direction:column; gap:1px; background:var(--line);
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); overflow:hidden}
/*
 * Строки характеристик берут подложку карточки, а не чистую поверхность: иначе
 * внутри цветной карточки оставался серый прямоугольник, и выбранный тариф
 * выглядел так, будто цвет ему лишь обвели по краю.
 */
.p-row{display:flex; justify-content:space-between; align-items:baseline; gap:8px;
  background:var(--tier-wash); padding:6px 10px}
.p-rows{background:var(--tier-edge); border-color:var(--tier-edge)}
/* Подпись и значение должны различаться сильнее: раньше они были почти
   одного размера и оба приглушённые, и пять строк читались как серая сетка. */
.p-row span{font-size:11px; color:var(--ink-2)}
.p-row b{font-size:13px; font-weight:700; text-align:right; color:var(--ink)}

.p-cta{
  margin-top:12px; text-align:center; font-size:13px; font-weight:800; padding:9px 10px;
  border-radius:var(--r-ctl); border:var(--bw) solid var(--tier-edge); color:var(--ink-2);
}
.plan:hover .p-cta{border-color:var(--tier); color:var(--ink)}

/*
 * Кнопка выбранной карточки — заливка цветом тарифа, но НЕ чистым.
 *
 * Чистый цвет тут не годится: на жёлтом нужна тёмная тушь, на синем
 * светлая, а цвет произвольный — правила, которое угадает оба случая, нет.
 * Поэтому заливка густая, но смешана с поверхностью: --ink остаётся читаемым
 * и днём, и ночью, на любом оттенке.
 */
.plan[data-on] .p-cta{
  background:color-mix(in srgb, var(--tier) 42%, var(--surface));
  border-color:var(--tier); color:var(--ink);
}

/* Кнопка выбранной карточки говорит, что тариф уже выбран, а не предлагает
   выбрать его вторично. Обе надписи лежат в разметке — см. коммент в шаблоне. */
.p-picked{display:none}
.plan[data-on] .p-pick{display:none}
.plan[data-on] .p-picked{display:inline}
.plan[data-sold] .p-cta{border-style:dashed}

.pick{display:flex; flex-wrap:wrap; gap:8px}
.pick button{font:inherit; font-size:13.5px; font-weight:700; cursor:pointer; padding:9px 14px;
  border-radius:var(--r-ctl); border:var(--bw) solid var(--line); background:var(--field); color:var(--ink);
  display:inline-flex; align-items:center; gap:8px}
.pick button:hover{border-color:var(--brand)}
.pick button[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}
.pick button[aria-pressed="true"] .p{color:inherit; opacity:.85}
.pick .p{font-size:11.5px; color:var(--ok); font-weight:700}
.pick img{width:20px; height:14px; border-radius:2px; display:block}
.pick button[disabled]{opacity:.42; cursor:not-allowed}

.total{display:flex; flex-wrap:wrap; align-items:center; gap:14px; padding:16px 18px;
  background:var(--surface-2); border-radius:var(--r-card); margin-top:6px}
.total .sum{font-size:27px; font-weight:800; letter-spacing:-.02em}
.total .right{margin-left:auto; display:flex; align-items:center; gap:12px}

/* --------------------------------------------------------- ПЛАТЕЖИ ---- */
.tiles{display:grid; grid-template-columns:repeat(3,1fr); gap:11px; margin-bottom:16px}
@media (max-width:700px){ .tiles{grid-template-columns:1fr} }
.tile{background:var(--surface); border:var(--bw) solid var(--card-line); border-radius:var(--r-card); padding:15px 17px}
.tile .k{font-size:10.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-2)}
.tile .v{font-size:24px; font-weight:800; letter-spacing:-.02em; margin-top:3px}
table{width:100%; border-collapse:collapse; font-size:14px}
th{text-align:left; font-size:10.5px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-2); padding:0 11px 9px; font-weight:800}
td{padding:12px 11px; border-top:1px solid var(--line)}
td.num{text-align:right; font-variant-numeric:tabular-nums; font-weight:700}
.plus{color:var(--ok)}
.pager{display:flex; gap:6px; margin-top:14px}
.pager a{text-decoration:none; font-size:13.5px; font-weight:700; color:var(--ink); cursor:pointer;
  padding:7px 12px; border-radius:var(--r-ctl); border:var(--bw) solid var(--line)}
.pager a[aria-current]{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}

.pay-grid{display:grid; grid-template-columns:1.05fr .95fr; gap:14px; align-items:start}
@media (max-width:860px){ .pay-grid{grid-template-columns:1fr} }
.amounts{display:grid; grid-template-columns:repeat(5,1fr); gap:7px; margin-bottom:14px}
@media (max-width:560px){ .amounts{grid-template-columns:repeat(3,1fr)} }
.amounts button{font:inherit; font-weight:700; font-size:14.5px; cursor:pointer; padding:10px 0;
  border-radius:var(--r-ctl); border:var(--bw) solid var(--line); background:var(--field); color:var(--ink)}
.amounts button:hover{border-color:var(--brand)}
.amounts button[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}
.money{position:relative; margin-bottom:12px}
.money .cur{position:absolute; left:15px; top:50%; transform:translateY(-50%); font-weight:800; font-size:20px; color:var(--ink-2)}
.money input{width:100%; font:inherit; font-size:24px; font-weight:800; color:var(--ink);
  padding:12px 15px 12px 36px; border-radius:var(--r-ctl); border:var(--bw) solid var(--line); background:var(--field)}
.money input:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 4px rgba(var(--tint),.16)}
.methods{display:grid; gap:8px; margin-bottom:14px}
.m{display:flex; align-items:center; gap:12px; padding:12px 14px; cursor:pointer;
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--field)}
.m .ic{width:34px; height:34px; border-radius:calc(var(--r-ctl) - 3px); background:var(--surface-2);
  display:flex; align-items:center; justify-content:center; font-weight:800; font-size:12px; flex:none}
.m b{display:block; font-size:14px}
.m .sub{font-size:12px; color:var(--ink-2)}
.m input{margin-left:auto; accent-color:var(--brand); width:17px; height:17px}
.m[data-on]{border-color:var(--brand); background:var(--brand-soft)}
.m[data-on] .ic{background:var(--brand); color:var(--brand-ink)}
.m[data-off]{opacity:.45; cursor:not-allowed}

.row{display:flex; align-items:center; gap:10px; padding:11px 0; border-top:1px solid var(--line)}
.row:first-of-type{border-top:0}
.row .lbl{font-size:12.5px; color:var(--ink-2); width:70px; flex:none}
.row .val{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace; font-size:13.5px; font-weight:600}
.row .val.big{font-size:20px; font-weight:800; white-space:nowrap}
.row .val.addr{word-break:break-all}
.row .copy{margin-left:auto; font:inherit; font-size:11.5px; font-weight:700; cursor:pointer;
  border:var(--bw) solid var(--line); background:var(--field); color:var(--ink); padding:5px 10px;
  border-radius:var(--r-chip); flex:none}
.qr{width:118px; height:118px; border-radius:calc(var(--r-card) - 7px); flex:none; border:var(--bw) solid var(--card-line);
  background:repeating-linear-gradient(90deg,#17142B 0 7px,transparent 7px 14px),
             repeating-linear-gradient(0deg,#17142B 0 7px,transparent 7px 14px), #fff}
.timer{display:flex; align-items:center; gap:8px; font-size:13px; font-weight:700; color:var(--warn); margin-top:4px}
.timer .d{width:8px; height:8px; border-radius:50%; background:var(--warn)}
.note{border-radius:var(--r-ctl); padding:11px 14px; font-size:13px; margin-top:12px;
  border:var(--bw) solid transparent; display:flex; gap:9px; align-items:flex-start}
.note.warn{background:var(--warn-soft); color:var(--warn); border-color:var(--warn)}
.note.info{background:var(--brand-soft); color:var(--brand-strong); border-color:var(--brand)}
.note b{display:block}

/* ------------------------------------------------------- ПРОГРАММЫ ---- */
.apps{display:grid; grid-template-columns:repeat(3,1fr); gap:11px}
@media (max-width:760px){ .apps{grid-template-columns:1fr 1fr} }
@media (max-width:460px){ .apps{grid-template-columns:1fr} }
.appc{background:var(--surface); border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  padding:16px; text-align:center}
.appc .os{font-size:26px; margin-bottom:7px}
.appc b{display:block; font-size:14.5px; margin-bottom:2px}
.appc .sub{font-size:12px; color:var(--ink-2); display:block; margin-bottom:11px}

/* --------------------------------------------------------- СПРАВКА ---- */
.faq details{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:14px 17px; margin-bottom:8px}
.faq summary{cursor:pointer; font-weight:700; font-size:14.5px; list-style:none}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+"; float:right; color:var(--ink-2); font-weight:800}
.faq details[open] summary::after{content:"–"}
.faq p{margin:10px 0 0; color:var(--ink-2); font-size:13.5px}

/* =========================================================================
   МНОГО ЗАКАЗОВ
   -------------------------------------------------------------------------
   Пять карточек — красиво. Пятьдесят — бесконечная лента, в которой ничего
   не найти. И дело не в вёрстке: при пятидесяти заказах человек уже не
   «смотрит список», а решает одну из трёх задач —

     где горит        → полоса внимания над списком
     найти нужный     → поиск, фильтры по статусу, сортировка
     продлить пачкой  → отметки в строках и общая сумма внизу

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

/* hidden проигрывает авторскому display:flex — без этой строки полоса
   остаётся на экране, даже когда прятать её и есть весь смысл. */
.attention[hidden]{display:none}

.attention{
  display:flex; align-items:center; gap:12px; margin-bottom:14px; padding:13px 16px;
  background:var(--warn-soft); color:var(--warn); border:var(--bw) solid var(--warn);
  border-radius:var(--r-card);
}
.attention .ic{font-size:18px; line-height:1}
.attention .txt{display:flex; flex-direction:column; line-height:1.35}
.attention .txt b{font-size:14.5px}
.attention .txt span{font-size:12.5px; opacity:.85}
.attention .acts{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap}
.attention .btn{background:transparent; border-color:currentColor; color:inherit; box-shadow:none}
/* То же, что и в .btn.grad: сокращение background тут переопределяется
   вторично, поэтому оба свойства надо повторить — иначе светлая полоса
   возвращается именно на этой кнопке. */
.attention .btn.grad{background:var(--grad); background-origin:border-box;
  background-repeat:no-repeat; border-color:transparent; color:var(--grad-ink)}
@media (max-width:640px){
  .attention{flex-wrap:wrap}
  .attention .acts{margin-left:0; width:100%}
}

.tools .sel{flex:none; width:auto; min-width:190px; cursor:pointer}
.viewtoggle{display:flex; gap:2px; background:var(--surface-2); border-radius:var(--r-ctl); padding:3px; flex:none}
.viewtoggle button{
  font:inherit; font-size:15px; line-height:1; cursor:pointer; border:0; background:transparent;
  color:var(--ink-2); padding:7px 11px; border-radius:calc(var(--r-ctl) - 3px);
}
.viewtoggle button[aria-pressed="true"]{background:var(--raised); color:var(--ink)}

.filters{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:14px}
.filters button{
  font:inherit; font-size:13px; font-weight:700; cursor:pointer; padding:6px 12px;
  border-radius:var(--r-chip); border:var(--bw) solid var(--line);
  background:transparent; color:var(--ink-2);
}
.filters button:hover{color:var(--ink)}
.filters button[aria-pressed="true"]{background:var(--brand-soft); color:var(--brand-strong); border-color:var(--brand)}
.filters .n{opacity:.6; margin-left:5px; font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------- СПИСОК -- */
/* БЕЗ overflow:hidden — ИНАЧЕ КОНТЕЙНЕР СЪЕДАЕТ МЕНЮ.
   Обрезание ставили ради закруглённых углов, но оно заодно обрезает всё,
   что выходит за границы списка: меню «⋯», открытое вверх от верхней строки,
   показывало три пункта из восьми, и «Продлить» среди срезанных.
   Углы теперь закругляет то, что и правда на краю: полоска градиента сверху и
   последняя строка снизу. */
.list{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); box-shadow:var(--sh-card)}
/*
 * СТОЛБЦЫ ТУТ БОЛЬШЕ НЕ ОБЪЯВЛЯЮТСЯ — они ниже, в разделе «СТРОКА СПИСКА».
 *
 * Было два набора правил на те же .lhead и .r: этот (шесть столбцов, скрывает
 * колонки на 980 и 620) и нижний (восемь столбцов, скрывает на 1220/1040/880/660).
 * Ширину столбцов выигрывал нижний, а `display:none` оставались от обоих — и
 * между 660 и 980 пикселями число ВИДИМЫХ ячеек не совпадало с числом
 * столбцов. Ячейки съезжали на соседние дорожки: полоса срока оказывалась в
 * шестидесятипиксельном столбике и вылезала из него прямо под кнопки.
 *
 * Заметно это стало, когда рядом с «⋯» встал колокольчик, но причина была давняя.
 */
.lhead, .r{
  display:grid; align-items:center; gap:12px;
  padding:11px 16px;
}
.lhead{
  font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-2); border-bottom:1px solid var(--line); position:sticky; top:0;
  background:var(--surface-2); z-index:5;
}
.r{border-top:1px solid var(--line); font-size:13.5px}
.r:first-child{border-top:0}
#rows .r:last-child{border-radius:0 0 calc(var(--r-card) - 1px) calc(var(--r-card) - 1px)}
.r:hover{background:var(--surface-2)}
/* Пороги, на которых колонки скрываются, тоже лишь внизу: тут стояли 980 и 620,
   и они не совпадали с теми 1220/1040/880/660 — именно это расхождение и
   сдвигало ячейки. */

.chk{display:flex; align-items:center; cursor:pointer}
.chk input{width:16px; height:16px; accent-color:var(--brand); cursor:pointer}

.cell-name{display:flex; align-items:center; gap:9px; min-width:0}
.cell-name .flag-img{width:20px; height:14px; border-radius:2px; flex:none; box-shadow:0 0 0 1px rgba(0,0,0,.12)}
.cell-name b{font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
/*
 * ТОЧКА СОСТОЯНИЯ. В таблице это единственный знак состояния — подписи рядом
 * нет, поэтому семь пикселей были маловаты, а цвет обязан читаться сам. Ореол
 * цвета состояния делает точку заметной, не забирая места в строке: box-shadow
 * не занимает разметки. Те же цвета носит и чип в карточке — иначе одна и та же
 * вещь в двух представлениях выглядела бы по-разному.
 */
.cell-name .st{width:10px; height:10px; border-radius:50%; flex:none}
.st.active{background:var(--ok); box-shadow:0 0 0 3px var(--ok-soft)}
.st.soon{background:var(--warn); box-shadow:0 0 0 3px var(--warn-soft)}
.st.expired{background:var(--bad); box-shadow:0 0 0 3px var(--bad-soft)}
.st.ordered{background:var(--brand); box-shadow:0 0 0 3px var(--brand-soft)}
.st.replacing{background:var(--busy); box-shadow:0 0 0 3px var(--busy-soft)}
.st.deleted{background:var(--ink-2); box-shadow:0 0 0 3px var(--surface-2)}
.cell-ip{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace; font-size:12.5px; color:var(--ink-2)}
.cell-proto{color:var(--ink-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.cell-term{display:flex; flex-direction:column; gap:3px; min-width:0}
/* Предохранитель на случай долгой даты: лучше троеточие, чем надпись на кнопке. */
.cell-term .d{font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.cell-term .b{height:3px; border-radius:999px; background:var(--surface-2); overflow:hidden}
.cell-term.soon .d{color:var(--warn); font-weight:700}
.cell-term.expired .d{color:var(--bad); font-weight:700}
/* Числа — справа, чтобы разряды стояли один под другим; заголовок — тоже
   справа, иначе «ЦЕНА» висит левее своего столбика и читается как
   подпись к соседнему. */
.cell-price, .lhead .c-price{font-variant-numeric:tabular-nums; text-align:right}
.cell-price{font-weight:700}
.cell-act{display:flex; gap:5px; justify-content:flex-end; position:relative}

.empty-note{color:var(--ink-2); text-align:center; padding:34px 10px}

/* -------------------------------------------------- МАССОВОЕ ДЕЙСТВИЕ -- */

/* Какое подание видно — решает атрибут на самом экране. */
#s-orders[data-view="list"] .orders{display:none}
#s-orders[data-view="cards"] .list{display:none}

/* =========================================================================
   СТРОКА СПИСКА: ЧТО ВИДНО СРАЗУ
   -------------------------------------------------------------------------
   Заказчик перечислил, что должно читаться без открывания карточки: номер
   заказа, IP, тариф, цена, период, протокол. Номер и адрес вдобавок должны
   копироваться быстро — это единственные два значения, которые человек
   переносит руками в чужие поля.

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

/* Ночью нативные чекбоксы, радио и выпадающие списки рисуются светлыми —
   одна строка объясняет браузеру, в какой теме он находится. Ею же он решает,
   какого цвета рисовать полосу прокрутки в Firefox. */
[data-theme="dark"]{color-scheme:dark}
:root{color-scheme:light}

/*
 * ПОЛОСА ПРОКРУТКИ ДОКУМЕНТА.
 *
 * Правила переехали сюда из landing.css: полоса одна на весь продукт, а
 * витрина теперь берёт стили оттуда же, откуда кабинет. Под .landing они бы
 * и не сработали — полоса документа не потомок обёртки страницы.
 *
 * scrollbar-gutter резервирует место заранее: без него переход «витрина →
 * кабинет» сдвигал страницу вбок ровно на ширину полосы.
 */
html{scrollbar-gutter:stable}

::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--line); border-radius:999px}
::-webkit-scrollbar-thumb:hover{background:var(--ink-2)}

:root{--r-box:5px}

/* ----------------------------------------------------------- ФЛАЖКИ ---- */
.chk{position:relative; display:flex; align-items:center; cursor:pointer}
.chk input{position:absolute; opacity:0; width:0; height:0}
.chk .box, .multi .box{
  width:17px; height:17px; flex:none; display:block; border-radius:var(--r-box);
  border:2px solid var(--line); background:var(--field); position:relative;
  transition:background .12s ease, border-color .12s ease;
}
.chk:hover .box, .multi:hover .box{border-color:var(--brand)}
.chk input:checked + .box, .multi input:checked + .box{background:var(--brand); border-color:var(--brand)}
.chk input:checked + .box::after, .multi input:checked + .box::after{
  content:""; position:absolute; left:4px; top:.5px; width:4px; height:8px;
  border:solid var(--brand-ink); border-width:0 2px 2px 0; transform:rotate(43deg);
}
.chk input:focus-visible + .box, .multi input:focus-visible + .box{box-shadow:0 0 0 4px rgba(var(--tint),.22)}

/* ----------------------------------------------------- ВЫПАДАЮЩИЙ СПИСОК */
.selwrap{position:relative; flex:none}
.selwrap::after{
  content:""; position:absolute; right:13px; top:50%; width:7px; height:7px;
  border:solid var(--ink-2); border-width:0 2px 2px 0; pointer-events:none;
  transform:translateY(-70%) rotate(45deg);
}
.sel{appearance:none; -webkit-appearance:none; padding-right:34px; cursor:pointer}

/* ------------------------------------------------------ КОПИРОВАНИЕ ---- */
.cp{
  display:inline-flex; align-items:center; gap:6px; max-width:100%;
  border:0; background:transparent; color:inherit; font:inherit; cursor:pointer;
  padding:3px 6px; margin-left:-6px; border-radius:var(--r-ctl); text-align:left;
}
.cp .v{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cp .cpi{flex:none; fill:none; stroke:currentColor; stroke-width:1.4; opacity:.4; transition:opacity .12s}
.cp:hover{background:var(--surface-2); color:var(--brand-strong)}
.cp:hover .cpi{opacity:1}

/*
 * ОТВЕТ НА КОПИРОВАНИЕ. Зелёный фон и галочка держатся 1.2 секунды —
 * ровно столько, чтобы её заметили, и не настолько долго, чтобы она успела
 * надоесть на списке из десятка заказов.
 *
 * Переход тут не украшение: без него смена цвета происходит в том же
 * кадре, что и нажатие, и читается как мигание, а не как ответ.
 */
.cp{transition:background .15s, color .15s}
.cp.done{background:var(--ok-soft); color:var(--ok)}
.cp.done .cpi{opacity:1}
.cp.done .v::after{content:" ✓"}

@media (prefers-reduced-motion:reduce){
  .cp{transition:none}
}

/* -------------------------------------------------- КНОПКА ДЕЙСТВИЙ ---- */
/* КНОПКА «⋯» — ПОЛНОЦЕННАЯ КНОПКА, А НЕ ТРИ ТОЧКИ В ВОЗДУХЕ.
   Была прозрачной, без рамки и серым цветом: на карточке её приходилось искать,
   хотя за ней живут все действия, кроме одного. Теперь у неё есть поверхность,
   рамка и обычный цвет текста — ровно как у соседних органов управления. */
.dots{
  width:34px; height:34px; display:inline-flex; align-items:center; justify-content:center;
  /* Поверхность СВЕТЛЕЕ строки, а не темнее. С var(--field) кнопка выходила
     темнее карточки — и читалась как дыра, а не как орган управления. */
  border:var(--bw) solid var(--line); background:var(--surface-2); color:var(--ink-2); cursor:pointer;
  border-radius:var(--r-ctl); padding:0; transition:border-color .12s ease, background .12s ease;
}
.dots svg{fill:currentColor}
.dots:hover{border-color:var(--brand); background:var(--brand-soft); color:var(--brand-strong)}
/* Открытое меню видно и по самой кнопке: иначе при нескольких карточках рядом
   непонятно, чьё именно меню развернулось. */
.more.open .dots{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.menu-pop .primary{color:var(--brand-strong); font-weight:800}
.menu-pop .primary:hover{background:var(--brand-soft)}

/* --------------------------------------------- КОЛОКОЛЬЧИК НАПОМИНАНИЙ - */
/* Стоит рядом с «⋯» и должен быть такого же размера: два органа управления в
   одном углу разной высоты читаются как ошибка вёрстки. Форма вокруг
   кнопки не имеет своего размера — иначе она добавила бы строке высоты. */
.bellf{display:inline-flex; margin:0}
/* ЦВЕТ — СОСТОЯНИЕ, А НЕ УКРАШЕНИЕ. Жёлтый означает «напомним», красный —
   «молчит»; фирменный голубой тут не годится, ведь им в списке помечено
   то, что просто нажимается. Цвет идёт ПЛЮС перечёркнутый значок
   (см. ico bell-off): одним лишь цветом состояние показывать нельзя — на
   чёрно-белом экране и в режиме высокой контрастности разницы нет. */
.bell{
  width:34px; height:34px; display:inline-flex; align-items:center; justify-content:center;
  border:var(--bw) solid var(--line); background:var(--surface-2); color:var(--warn);
  cursor:pointer; border-radius:var(--r-ctl); padding:0;
  transition:border-color .12s ease, background .12s ease, color .12s ease;
}
.bell:hover{border-color:var(--warn); background:var(--warn-soft)}
.bell.is-off{color:var(--bad)}
.bell.is-off:hover{border-color:var(--bad); background:var(--bad-soft)}

/* -------------------------------------------------- ЦВЕТ САМОЙ ТАБЛИЦЫ - */
/* Список был серым ящиком: поверхности из палитры, но ни одной её краски.
   Теперь он подписан палитрой — полоска градиента сверху, шапка на
   фирменном фоне, выбранная строка помечена цветной чертой слева. */
.list{position:relative}
/* УГОЛ ТАБЛИЦЫ.
   Полоска градиента была отдельным элементом ПЕРЕД шапкой, а сама шапка имела
   квадратные углы. Контейнер закруглён и без обрезания (обрезание убрали,
   чтобы меню «⋯» могло выйти наружу) — поэтому квадратный угол шапки вылезал
   из-под закруглённого угла рамки, и в углу виднелся лишний кусок фона.

   Теперь полоска — это просто верхний слой фона самой шапки. Закругление у них
   общее, вылезать нечему. */
.lhead{
  background:var(--grad) top / 100% 3px no-repeat, var(--brand-soft);
  color:var(--brand-strong); border-bottom:0;
  border-radius:calc(var(--r-card) - 1px) calc(var(--r-card) - 1px) 0 0;
}

.lhead, .r{
  /* Сроку — больше места, кнопкам — свой столбик.
     «не работает с 2 августа» не влезало в 116 и налезало на кнопку.

     ПОСЛЕДНИЙ СТОЛБИК ДЕРЖИТ ДВЕ КНОПКИ, а не одну: 36 + 36 и промежуток между
     ними. Пока тут стояло 40px (размер одной), колокольчик не влезал и
     выезжал влево — прямо поверх даты и полосы срока, ведь элемент сетки
     ничем не обрезается. Место забирается у гибкого столбика названия, а не
     у срока: название можно обрезать троеточием, дату — нет. */
  /* Девять столбцов: id · название · IP · протокол · ХОСТЕР · тариф · цена ·
     срок · действия. Хостер добавлен (100px) — его не хватало на ПК, хотя
     клиент выбирал его при заказе. */
  grid-template-columns:84px minmax(118px,1.5fr) minmax(150px,.9fr) 106px 100px 118px 60px 138px 82px;
  gap:10px; padding:11px 15px;
}
.cell-id .cp{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size:12.5px; font-weight:700}
.cell-name .nm{display:flex; flex-direction:column; min-width:0; line-height:1.25}
.cell-name .nm .sub{display:none; font-size:11.5px; color:var(--ink-2)}
.cell-plan{display:flex; flex-direction:column; line-height:1.25; min-width:0}
.cell-plan b{font-weight:700; font-size:13px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.cell-plan span{font-size:11.5px; color:var(--ink-2)}
.cell-ip{min-width:0}
.cell-host{color:var(--ink-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0}

/* На ДЕСКТОПЕ обёртки прозрачны: их ячейки ложатся прямо в сетку строки, так
   что все столбцы работают как раньше. На телефоне (ниже) эти обёртки оживают и
   собирают строку в этажи. Чип «#id» (.cell-mid), короткий срок (.ds) и
   третий этаж (.cell-more) — телефонные дублёры десктопных столбцов, на
   десктопе их нет. */
.cell-main, .cell-meta{display:contents}
.cell-mid, .cell-term .ds, .cell-more{display:none}

/* Сворачиваем по одному, в порядке «что можно потерять последним».
   ID, название и срок не исчезают никогда. Хостер идёт первым: он
   наименее срочный из фактов. */
@media (max-width:1320px){ .c-host, .cell-host{display:none} }
@media (max-width:1320px){ .lhead, .r{grid-template-columns:84px minmax(118px,1.6fr) minmax(150px,.9fr) 106px 118px 60px 138px 82px} }
@media (max-width:1220px){ .c-proto, .cell-proto{display:none} }
@media (max-width:1220px){ .lhead, .r{grid-template-columns:84px minmax(118px,1.25fr) 150px 118px 60px 116px 78px} }
@media (max-width:1040px){ .c-plan, .cell-plan{display:none} }
@media (max-width:1040px){ .lhead, .r{grid-template-columns:84px minmax(110px,1.3fr) 148px 60px 112px 78px} }
@media (max-width:880px){ .c-price, .cell-price{display:none} }
@media (max-width:880px){ .lhead, .r{grid-template-columns:82px minmax(110px,1.3fr) 146px 112px 78px} }

/* ТЕЛЕФОН: СТРОКА — ДВА ЭТАЖА, КАК В СТАРОЙ ПАНЕЛИ (orders.php).
   Первая попытка держала всё меню одной строкой без переноса и позволяла
   сжиматься лишь адресу — на узком экране IP сжимался В НОЛЬ
   («WireGuard Duo · ·»), а срок обрезало до «· 3». Отдельная колонка «#id»
   съедала ширину, и номер показывался как «#…».

   Теперь по схеме старого проекта, ТРИ этажа:
     этаж 1:  [точка состояния][флаг] НАЗВАНИЕ……………          [🔔][⋯]
     этаж 2:  [чип #id][чип IP]                       30 дн.
     этаж 3:  протокол · хостер · тариф · $50 / 1 мес.
   Чипы тапаются-копируются, как бейджи оригинала. Вторая строка ПЕРЕНОСИТСЯ
   (flex-wrap), а не скрывает содержимое: долгий IP честно съедет на новую.
   Колонка ID скрыта — номер живёт чипом; полная дата — в карточке и на
   странице, тут короткий остаток срока справа. Третий этаж — остальные
   факты мелкой строкой: после двух этажей в строке оставалось место, а
   без протокола/тарифа/цены список был слишком «голый». */
@media (max-width:660px){
  .lhead{display:none}
  .cell-id{display:none}

  .r{
    grid-template-columns:minmax(0,1fr) auto;
    align-items:center; gap:10px; padding:10px 12px;
  }

  .cell-main{display:flex; flex-direction:column; min-width:0; gap:5px}
  .cell-name{gap:8px}
  .cell-name .nm{min-width:0}
  .cell-name .nm b{font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block}

  .cell-meta{
    display:flex; flex-wrap:wrap; align-items:center; gap:4px 7px; min-width:0;
    font-size:11.5px; color:var(--ink-2); line-height:1.3;
  }

  /* Чипы «#id» и IP: рамка + моно, читаются как «можно тапнуть». */
  .cell-mid{display:inline-flex}
  .cell-mid .cp, .cell-meta .cell-ip .cp{
    padding:1px 7px; margin:0; font-size:11px; font-weight:700; color:var(--ink);
    background:var(--field); border:1px solid var(--line); border-radius:6px;
  }
  .cell-mid .i16, .cell-meta .cell-ip .i16{display:none}

  /* Протокол/хостер/тариф/цена со второго этажа идут на третий (.cell-more)
     — тут их скрываем, чтобы не дублировать. */
  .cell-meta .cell-proto, .cell-meta .cell-host,
  .cell-meta .cell-plan, .cell-meta .cell-price{display:none}

  /* СРОК («30 дн.») — НА ПЕРВОМ ЭТАЖЕ, справа от названия.
     Был на втором, прижатый margin-left:auto: в строке с переносом он
     «висел» посреди ничего — то рядом с чипами, то сам на новой строке,
     каждый раз на другой высоте. В шапке он всегда на том же месте, рядом
     с колокольчиком; название сжимается троеточием, а срок — нет.
     Технически: .cell-name — flex, поэтому order:2 переставляет .cell-term с
     конца .cell-meta в конец .cell-name без изменения разметки. */
  .cell-main{position:relative}
  .cell-name{padding-right:0}
  .cell-term{
    flex-direction:row; align-items:center; margin:0;
    position:absolute; right:0; top:1px;
    padding:1px 8px; border-radius:6px; font-size:11px; font-weight:800;
    background:var(--surface-2); color:var(--ink);
  }
  .cell-term .d, .cell-term .b{display:none}
  .cell-term .ds{display:inline; white-space:nowrap}
  .cell-term.soon{background:var(--warn-soft); color:var(--warn)}
  .cell-term.expired{background:var(--bad-soft); color:var(--bad)}
  /* Названию оставляем место под чип срока, чтобы не наезжали. */
  .cell-name .nm b{padding-right:64px}

  /* ТРЕТИЙ этаж: факты мелко, через точку, с переносом. Тариф — своим
     цветом (x-tariff-name красит сам), цена — жирная, чтобы глаз цеплялся.
     Разделитель — точка ПЕРЕД каждым элементом, кроме первого В СТРОКЕ. То есть
     не «после», а «перед»: после-точка при переносе оставалась висеть в конце
     предыдущей строки («Мифический ·» ↵), а перед-точка при переносе просто
     начинает новую строку — и её мы скрываем отрицательным сдвигом. */
  /* Реализация: .cell-more — обрезчик (overflow:hidden), а флекс-строка
     внутри (.cm-row) сдвинута влево на 12px. У каждого элемента точка стоит
     СЛЕВА в этих 12px. Каждая НОВАЯ строка флекса начинается с той же левой
     границы, поэтому первая точка КАЖДОЙ строки попадает в обрезанную зону и не
     видна — никаких висячих точек ни в конце, ни в начале строк. */
  .cell-more{display:block; overflow:hidden; min-width:0; font-size:11px; color:var(--ink-2); line-height:1.3}
  .cell-more .cm-row{display:flex; flex-wrap:wrap; align-items:center; gap:2px 0; margin-left:-12px}
  .cell-more .cm-row > span{white-space:nowrap; padding-left:12px; position:relative}
  .cell-more .cm-row > span::before{content:'·'; position:absolute; left:3px; opacity:.5}
  .cell-more .cm-plan{font-weight:600}
  .cell-more .cm-price{font-weight:700; color:var(--ink)}

  .bell, .dots{width:32px; height:32px}
  .cell-act{gap:5px}
}

/* =========================================================================
   ЛОКАЦИЯ И ХОСТЕР
   -------------------------------------------------------------------------
   Два уровня выбора, и второй не похож на первый намеренно: страны — плитки,
   хостеры — строки. Одинаковое оформление читалось бы как «выбери ещё шесть
   штук», хотя на самом деле это уточнение к уже сделанному выбору.
   ========================================================================= */
.regions{display:grid; grid-template-columns:repeat(auto-fill,minmax(156px,1fr)); gap:9px}
.reg{
  font:inherit; text-align:left; cursor:pointer; padding:12px 13px;
  border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  background:var(--surface); color:var(--ink);
}
.reg:hover{border-color:var(--brand)}
.reg[data-on]{border-color:var(--brand); background:var(--brand-soft)}
.reg[data-off]{opacity:.45; cursor:not-allowed}
.reg .rt{display:flex; align-items:center; gap:8px}
.reg .flag-img{width:22px; height:16px; border-radius:3px; flex:none; box-shadow:0 0 0 1px rgba(0,0,0,.12)}
.reg b{font-size:14.5px; font-weight:700}
.reg .rm{display:flex; justify-content:space-between; gap:8px; margin-top:8px; font-size:11.5px}
.reg .cnt{color:var(--ink); font-weight:700}
.reg .fr{color:var(--ink-2)}

.sites{margin-top:15px}
.sites .h{font-size:12px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-2); margin-bottom:9px}
.site{
  display:flex; align-items:center; gap:13px; width:100%; text-align:left; font:inherit;
  padding:14px 16px; margin-bottom:9px; cursor:pointer; color:var(--ink);
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--field);
  transition:border-color .15s, background .15s;
}
.site:hover{border-color:var(--brand)}
.site[data-on]{border-color:var(--brand); background:var(--brand-soft)}
.site[data-off]{opacity:.45; cursor:not-allowed}
/* Один хостер: та же карточка, но выбирать не из чего — потому не интерактивна. */
.site-solo{cursor:default}
.site .rad{width:18px; height:18px; border-radius:50%; border:2px solid var(--line);
  position:relative; flex:none}
.site[data-on] .rad{border-color:var(--brand)}
.site[data-on] .rad::after{content:""; position:absolute; inset:3px; border-radius:50%; background:var(--brand)}
.site .info{flex:1; min-width:0}
.site .nm{display:flex; align-items:center; gap:8px; font-weight:700; font-size:15px}
.site .sub{display:block; font-size:12px; color:var(--ink-2); margin-top:2px}
.site .speed{font-size:11.5px; font-weight:800; padding:3px 9px; border-radius:var(--r-chip);
  background:var(--accent-soft); color:var(--accent-strong)}
.site .best{font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:2px 8px; border-radius:var(--r-chip); background:var(--brand); color:var(--brand-ink)}
.site .free{font-size:12.5px; font-weight:700; color:var(--ink-2); white-space:nowrap; flex:none}

/* Что можно будет изменить ПОТОМ — главное невидимое отличие между хостерами.
   Узнать о нём после оплаты означает узнать поздно. */
.caps{display:flex; flex-wrap:wrap; gap:5px; margin-top:6px}
.caps .cap{font-size:10.5px; font-weight:700; padding:2px 8px; border-radius:var(--r-chip);
  width:auto; height:auto; letter-spacing:0; text-transform:none; margin:0; color:inherit}
.cap.yes{background:var(--ok-soft); color:var(--ok)}
.cap.yes::before{content:"✓ "}
.cap.no{background:var(--surface-2); color:var(--ink-2); opacity:.75}
.cap.no::before{content:"✕ "}

@media (max-width:600px){
  .site{flex-wrap:wrap}
  .site .free{width:100%; padding-left:29px}
}

/* =========================================================================
   ПРОТОКОЛЫ, КОНФИГУРАЦИИ, КАЛЬКУЛЯТОР
   ========================================================================= */
/*
 * ПЛИТКА ПРОТОКОЛА.
 *
 * Была одной строкой: значок | текст | значки справа. Описание протокола — это
 * два-три предложения, и зажатое между двумя колонками оно рассыпалось в столбик
 * из двух слов в строке: «Современный быстрый / протокол. Минимальные /
 * задержки». Читать такое труднее, чем не читать вовсе.
 *
 * Теперь плитка — сетка из трёх этажей: значок и название вверху, описание на
 * всю ширину, значки внизу. Описание получает всю ширину карточки, а не треть,
 * и строка наконец вмещает фразу.
 */
.protos{display:grid; grid-template-columns:repeat(auto-fill,minmax(268px,1fr)); gap:10px}
.proto{
  display:grid; grid-template-columns:38px 1fr;
  grid-template-areas:"icon title" "desc desc" "foot foot";
  align-items:center; column-gap:11px; row-gap:9px;
  text-align:left; font:inherit; cursor:pointer;
  padding:13px 14px; border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  background:var(--surface); color:var(--ink);
}
.proto:hover{border-color:var(--brand)}
.proto[data-on]{border-color:var(--brand); background:var(--brand-soft)}
.proto[data-off]{opacity:.45; cursor:not-allowed}
.proto .pi{grid-area:icon; width:38px; height:38px}
.proto .pi svg{width:100%; height:100%; display:block; border-radius:var(--r-ctl)}

/* display:contents — чтобы название и описание легли на РАЗНЫЕ этажи сетки,
   оставаясь одним узлом разметки: её рисует тот же шаблон, что и до перестройки. */
.proto .pt{display:contents}
.proto .pt b{grid-area:title; font-size:15px; font-weight:700; align-self:center}
.proto .pt span{grid-area:desc; font-size:12px; line-height:1.5; color:var(--ink-2)}

/* Значки внизу и В РЯД: вертикальной колонкой они раньше и забирали ту
   ширину, которой не хватало описанию. */
.proto .pf{grid-area:foot; display:flex; flex-wrap:wrap; gap:6px}
.proto .pf .chip{font-size:10px; padding:2px 8px}

.params{display:grid; grid-template-columns:1fr 1.15fr; gap:20px}
@media (max-width:760px){ .params{grid-template-columns:1fr} }
.plbl{font-size:12px; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-2); margin-bottom:9px; display:flex; gap:8px; align-items:baseline}
.plbl .hint{text-transform:none; letter-spacing:0; font-weight:600}

/*
 * КАРТОЧКА ПАРАМЕТРА. Срок и количество — равные по важности вещи, поэтому у
 * них одинаковые рамки и одинаковый внутренний ритм. До того они лежали просто
 * на фоне страницы, и разная высота столбиков читалась как недорисованная.
 */
.pcard{
  display:flex; flex-direction:column; gap:11px;
  background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:15px 16px;
}
.pcard .plbl{margin:0}
.pcard>.hint{margin:0}
/* Пояснение, закрывающее карточку, прижимается к низу — так низ обеих карточек
   стоит на одной линии, сколько бы ступеней ни было в соседней. */
.pcard>.hint:last-child{margin-top:auto}

/* Срок: число большое, слово под ним, скидка отдельной строкой. Три кнопки
   делят ширину поровну — так сравнивают именно числа, а не длину надписей. */
.pick-lg{display:grid; grid-template-columns:repeat(3,1fr); gap:9px}
.pick-lg button{
  display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:11px 8px; text-align:center; line-height:1.15;
}
.pick-lg b{font-size:19px; font-weight:800; letter-spacing:-.02em}
.pick-lg .u{font-size:12px; color:var(--ink-2); font-weight:600}
.pick-lg .off{font-size:11.5px; font-weight:800; color:var(--ok)}
.pick-lg button[aria-pressed="true"] .u,
.pick-lg button[aria-pressed="true"] .off{color:inherit; opacity:.9}

/* Количество: все ступени сразу, под каждой её доплата. Ширина ступени
   фиксирована снизу — при потолке в двести конфигов перечень просто переносится
   строками, а не сжимается до нечитаемого. */
.cfgs{display:grid; grid-template-columns:repeat(auto-fill,minmax(74px,1fr)); gap:8px}
.cfgs button{
  display:flex; flex-direction:column; align-items:center; gap:1px; cursor:pointer;
  font:inherit; padding:9px 6px; line-height:1.2;
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl);
  background:var(--field); color:var(--ink);
}
.cfgs button:hover{border-color:var(--brand)}
.cfgs b{font-size:16px; font-weight:800}
.cfgs span{font-size:11px; color:var(--ink-2); font-weight:700}
.cfgs button[aria-pressed="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.cfgs button[aria-pressed="true"] span{color:inherit; opacity:.88}

.multi{display:flex; align-items:center; gap:11px; margin-top:0; cursor:pointer;
  padding:11px 13px; border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--field)}
.multi[hidden]{display:none}
.multi:has(input:checked){border-color:var(--brand); background:var(--brand-soft)}
.multi input{position:absolute; opacity:0; width:0; height:0}
.multi b{display:block; font-size:13.5px}
.multi .hint{display:block}

/* Поле кастомной подсети: открывается галочкой «Своя подсеть». */
.subnet-field{margin-top:8px}
.subnet-field[hidden]{display:none}
.subnet-field input{width:100%; box-sizing:border-box; padding:11px 13px;
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--field);
  color:var(--ink); font-size:13.5px; font-variant-numeric:tabular-nums; letter-spacing:.02em}
.subnet-field input:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 4px rgba(var(--tint),.18)}
.subnet-field .err{display:block; margin-top:6px; color:#f85149}
.subnet-field .err[hidden]{display:none}

/* ------------------------------------------------------------ КАЛЬКУЛЯТОР */
.calc{background:var(--surface-2); border-radius:var(--r-card); padding:16px 18px; margin-top:6px}
.calc-what{font-size:12.5px; color:var(--ink-2); padding-bottom:10px; margin-bottom:6px;
  border-bottom:1px solid var(--line)}
.calc-row{display:flex; justify-content:space-between; gap:14px; padding:6px 0; font-size:13.5px}
.calc-row span{color:var(--ink-2)}
.calc-row b{font-variant-numeric:tabular-nums; white-space:nowrap}
.calc-row.minus b{color:var(--ok)}
.calc-row.plus b{color:var(--ink)}
.calc-sum{display:flex; justify-content:space-between; align-items:baseline; gap:14px;
  margin-top:10px; padding-top:12px; border-top:1px solid var(--line)}
.calc-sum span{font-size:13px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-2)}
.calc-sum b{font-size:30px; font-weight:800; letter-spacing:-.02em}
.calc-go{display:flex; align-items:center; gap:14px; margin-top:12px; flex-wrap:wrap}
.calc-go .btn{margin-left:auto}

/* ---------------------------------------------------------- ЗНАЧКИ ------ */
/* Один класс на весь набор: толщина линии, закругление концов и цвет
   задаются тут, а не в каждом пути отдельно. */
.i20{
  width:18px; height:18px; display:block; fill:none; stroke:currentColor;
  stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
.menu-pop .ic{display:flex; align-items:center; justify-content:center; color:var(--ink-2)}
.menu-pop .primary .ic, .menu-pop .danger .ic{color:inherit}
.menu a .ic{display:flex; align-items:center; justify-content:center}
.tabbar .ic{display:flex; align-items:center; justify-content:center}
.tabbar .i20{width:21px; height:21px}

/* =========================================================================
   ПРОГРАММЫ
   ========================================================================= */
.sw-pick{margin-bottom:16px}
.sw-lbl{font-size:12px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-2); margin-bottom:9px; display:flex; gap:8px; align-items:baseline}
.sw-lbl .hint{text-transform:none; letter-spacing:0; font-weight:600}
.sw-chips{display:flex; flex-wrap:wrap; gap:7px}
.sw-chip{
  font:inherit; font-size:13.5px; font-weight:700; cursor:pointer; padding:8px 13px;
  border-radius:var(--r-ctl); border:var(--bw) solid var(--line);
  background:var(--field); color:var(--ink);
}
.sw-chip:hover{border-color:var(--brand)}
.sw-chip[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}

/* Карточки протоколов — те же, что на «Новом заказе». */
#sw-protos{display:grid; grid-template-columns:repeat(auto-fill,minmax(214px,1fr)); gap:9px}
/* Протокол, которого у клиента нет, бледный — но кликабельный. */
.proto[data-quiet]{opacity:.5}
.proto[data-quiet][data-on]{opacity:1}

/* ------------------------------------------------------- ВАШИ СЕРВЕРЫ --- */
.sw-mine{display:flex; flex-wrap:wrap; align-items:center; gap:9px; margin-bottom:16px;
  padding:12px 15px; background:var(--brand-soft); border-radius:var(--r-card)}
.sw-mine .k{font-size:12px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  color:var(--brand-strong)}
.sw-mine .list{display:flex; flex-wrap:wrap; gap:6px}
.sw-srv{font:inherit; font-size:13px; font-weight:700; cursor:pointer; padding:5px 11px;
  border-radius:var(--r-chip); border:var(--bw) solid var(--brand); background:transparent;
  color:var(--brand-strong)}
.sw-srv:hover{background:var(--brand); color:var(--brand-ink)}
.sw-mine .hint{width:100%}

/* ---------------------------------------------------------- КАРТОЧКА ---- */
.sw-apps{display:grid; grid-template-columns:repeat(auto-fill,minmax(340px,1fr)); gap:12px}
.sw-app{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:16px 18px; box-shadow:var(--sh-card)}
.sw-head{display:flex; align-items:flex-start; gap:12px}
.sw-ic{width:40px; height:40px; flex:none}
.sw-ic svg{width:100%; height:100%; display:block; border-radius:var(--r-ctl)}
.sw-name{flex:1; min-width:0; display:flex; flex-direction:column; line-height:1.35}
.sw-name b{font-size:15.5px}
.sw-name span{font-size:12.5px; color:var(--ink-2)}
.sw-head .chip{flex:none}

.sw-facts{display:grid; gap:1px; background:var(--line); border-radius:var(--r-ctl);
  overflow:hidden; margin:13px 0 12px; border:var(--bw) solid var(--line)}
.sw-facts>div{background:var(--surface); padding:8px 12px; display:flex; gap:10px;
  justify-content:space-between; align-items:baseline}
.sw-facts .k{font-size:11.5px; color:var(--ink-2); flex:none}
.sw-facts .v{font-size:12.5px; font-weight:600; text-align:right}

.sw-dl{display:grid; grid-template-columns:1fr 1fr; gap:7px}
@media (max-width:520px){ .sw-dl{grid-template-columns:1fr} }
.sw-plat{
  display:flex; flex-direction:column; gap:1px; text-decoration:none; padding:9px 12px;
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--field); color:var(--ink);
}
.sw-plat:hover{border-color:var(--brand); color:var(--brand-strong)}
.sw-plat b{font-size:13.5px; font-weight:700}
.sw-plat span{font-size:11px; color:var(--ink-2)}

.sw-how{margin-top:12px; border-top:1px solid var(--line); padding-top:10px}
.sw-how summary{cursor:pointer; font-size:13px; font-weight:700; list-style:none; color:var(--brand-strong)}
.sw-how summary::-webkit-details-marker{display:none}
.sw-how summary::after{content:" ▾"}
.sw-how[open] summary::after{content:" ▴"}
.sw-how ol{margin:9px 0 0; padding-left:20px; font-size:13px; color:var(--ink-2)}
.sw-how li{padding:3px 0}

.sw-builtin, .sw-empty{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:18px 20px; box-shadow:var(--sh-card)}
.sw-builtin b, .sw-empty b{font-size:16px; display:block; margin-bottom:6px}
.sw-builtin p, .sw-empty p{margin:0; color:var(--ink-2); font-size:13.5px}
.sw-builtin{border-color:var(--ok)}
.sw-empty .btn{margin-top:12px}
.sw-where{display:grid; gap:1px; background:var(--line); border-radius:var(--r-ctl);
  overflow:hidden; margin-top:14px; border:var(--bw) solid var(--line)}
.sw-where>div{background:var(--surface); padding:9px 12px; display:flex; gap:12px;
  justify-content:space-between; align-items:baseline}
.sw-where .k{font-size:12.5px; font-weight:700; flex:none}
.sw-where .v{font-size:12.5px; color:var(--ink-2); text-align:right}
.sw-note{margin-top:18px}

/* =========================================================================
   АККАУНТ И МОБИЛЬНАЯ ШАПКА
   ========================================================================= */
.acct{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left; font:inherit;
  cursor:pointer; padding:10px 11px; margin-top:10px; color:var(--ink);
  border:var(--bw) solid var(--line); border-radius:var(--r-card); background:var(--surface-2);
}
.acct:hover{border-color:var(--brand)}
.av{
  width:34px; height:34px; border-radius:50%; flex:none; background:var(--grad); color:var(--grad-ink);
  display:flex; align-items:center; justify-content:center; font-weight:800; font-size:15px;
}
.av.big{width:44px; height:44px; font-size:19px}
.acct .who, .sheet-head .who{display:flex; flex-direction:column; min-width:0; line-height:1.3}
.acct .who b{font-size:14px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.acct .who span{font-size:11.5px; color:var(--ink-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.acct .chev{margin-left:auto; width:7px; height:7px; flex:none;
  border:solid var(--ink-2); border-width:0 2px 2px 0; transform:translateY(-2px) rotate(45deg)}

.mtop{display:none; align-items:center; gap:10px; margin-bottom:14px}
.mtop .acct{margin-top:0; flex:1; min-width:0}
.mtop .bal{
  display:flex; flex-direction:column; align-items:flex-end; gap:1px; flex:none; cursor:pointer;
  font:inherit; color:var(--grad-ink); padding:9px 14px; border:0; border-radius:var(--r-card); background:var(--grad-cool);
}
.mtop .bal span{font-size:9.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; opacity:.85}
.mtop .bal b{font-size:17px; font-weight:800; letter-spacing:-.01em}
@media (max-width:900px){ .mtop{display:flex} .side .acct{display:none} }

/* ---------------------------------------------------- КАРТОЧКА АККАУНТА */
.sheet-bg{position:fixed; inset:0; z-index:70; background:rgba(0,0,0,.45)}
.sheet-bg[hidden]{display:none}
.sheet{
  position:fixed; z-index:71; right:16px; top:58px; width:min(320px, calc(100vw - 32px));
  background:var(--raised); border:var(--bw) solid var(--line); border-radius:var(--r-card);
  box-shadow:var(--sh-pop); padding:16px;
}
.sheet[hidden]{display:none}
@media (max-width:900px){
  /* На телефоне карточка выезжает снизу — туда достаёт большой палец,
     а до правого верхнего угла он не достаёт вовсе. */
  .sheet{right:12px; left:12px; top:auto; bottom:78px; width:auto}
}
.sheet-head{display:flex; align-items:center; gap:12px; padding-bottom:13px;
  border-bottom:1px solid var(--line)}
.sheet-head .who b{font-size:16px}
.sheet-head .who span{font-size:13px; color:var(--ink-2)}
.sheet-rows{padding:6px 0}
.sheet-row{display:flex; align-items:center; justify-content:space-between; gap:12px; padding:8px 0; font-size:13.5px}
.sheet-row>span{color:var(--ink-2)}
.sheet-lang{display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 0; margin-top:2px; border-top:1px solid var(--line); font-size:13.5px}
.sheet-lang>span{color:var(--ink-2)}
.sheet-out{width:100%; margin-top:10px; display:flex; align-items:center; justify-content:center; gap:9px}
.sheet-out .ic{display:flex}

/* =========================================================================
   ТЕЛЕФОН: ПАНЕЛЬ ИНСТРУМЕНТОВ И ФИЛЬТРЫ
   -------------------------------------------------------------------------
   На узком экране flex-wrap раскладывал элементы как выйдет: поиск и
   сортировка в один ряд, а переключатель вида оказывался рядом с «Заказать»,
   будто они одно целое. Поэтому на телефоне раскладка задаётся явно.
   ========================================================================= */
@media (max-width:660px){
  .tools{display:grid; grid-template-columns:1fr auto auto; gap:8px}
  .tools .search{grid-column:1 / -1; min-width:0}
  /* min-width снимается вместе с width. Без этой строки сортировка
     оставалась 190 px шириной — на 375 px экране она вылезала из своей
     колонки и накрывала собой переключатель «список / карточки». */
  .tools .selwrap, .tools .sel{width:100%; min-width:0}
  .tools .btn{white-space:nowrap}

  /* Шесть фильтров в два ряда съедали пол экрана. Один ряд с прокруткой
     вбок показывает столько, сколько вмещается, и не ломает страницу. */
  .filters{flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; padding-bottom:2px}
  .filters::-webkit-scrollbar{display:none}
  .filters button{flex:none}

  .top{flex-wrap:wrap}
  .top .right{margin-left:auto}
}

/* =========================================================================
   ПЛАТЕЖИ
   ========================================================================= */
.tile .t-sub{font-size:11.5px; color:var(--ink-2); margin-top:3px}
/* Текущий баланс — главное число страницы, поэтому оно единственное светится. */
.tile-now{background:var(--grad-cool); background-origin:border-box; background-repeat:no-repeat;
  border-color:transparent; color:var(--grad-ink)}
.tile-now .k, .tile-now .t-sub{color:var(--grad-ink); opacity:.85}

.pending{
  display:flex; align-items:center; gap:12px; margin-bottom:16px; padding:13px 16px;
  background:var(--brand-soft); color:var(--brand-strong);
  border:var(--bw) solid var(--brand); border-radius:var(--r-card);
}
.pending[hidden]{display:none}
.pending .pi{display:flex; align-items:center}
.pending .pi svg{width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:1.5}
.pending .txt{display:flex; flex-direction:column; line-height:1.35}
.pending .txt b{font-size:14.5px}
.pending .txt span{font-size:12.5px; opacity:.85}
.pending .acts{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap}
@media (max-width:640px){
  .pending{flex-wrap:wrap}
  .pending .acts{margin-left:0; width:100%}
}

/* ----------------------------------------------------- ГРУППА ПО МЕСЯЦУ */
.op-month{display:flex; justify-content:space-between; align-items:baseline; gap:12px;
  margin:20px 2px 8px; font-size:12px; font-weight:800; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-2)}
.op-total{font-weight:700; letter-spacing:0; text-transform:none; font-size:12.5px}
.ops-group{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); box-shadow:var(--sh-card); overflow:hidden}

/* ------------------------------------------------------------- ОПЕРАЦИЯ */
.op{display:grid; grid-template-columns:36px 1fr auto 18px; align-items:center; gap:12px;
  padding:12px 15px; border-top:1px solid var(--line)}
.ops-group .op:first-child{border-top:0}
.op[data-has-detail]{cursor:pointer}
.op[data-has-detail]:hover{background:var(--surface-2)}
.op-ic{width:36px; height:36px; border-radius:var(--r-ctl); display:flex; align-items:center;
  justify-content:center; background:var(--surface-2); color:var(--ink-2)}
.op-ic svg{width:19px; height:19px; stroke:currentColor; fill:none; stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round}
/* Приход помечен и знаком, и цветом значка: одного цвета цифры мало,
   когда строк двадцать и глаз бежит по левому краю. */
.op.in .op-ic{background:var(--ok-soft); color:var(--ok)}
.op-main{min-width:0; display:flex; flex-direction:column; gap:3px}
.op-main b{font-size:14px; font-weight:700}
.op-link{color:var(--brand-strong); text-decoration:none; cursor:pointer}
.op-link:hover{text-decoration:underline}
.op-meta{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.op-src{font-size:11px; font-weight:700; padding:2px 8px; border-radius:var(--r-chip);
  background:var(--surface-2); color:var(--ink-2)}
.op-date{font-size:12px; color:var(--ink-2)}
.op-sum{font-size:15px; font-weight:800; font-variant-numeric:tabular-nums; white-space:nowrap}
.op.in .op-sum{color:var(--ok)}
.op-chev{width:7px; height:7px; justify-self:center; border:solid var(--ink-2);
  border-width:0 2px 2px 0; transform:translateY(-2px) rotate(45deg); transition:transform .15s}
.op.open .op-chev{transform:translateY(1px) rotate(-135deg)}

.op-detail{background:var(--surface-2); padding:4px 15px 12px 63px; display:grid; gap:1px}
.op-detail[hidden]{display:none}
.op-detail>div{display:flex; justify-content:space-between; align-items:baseline; gap:12px;
  padding:7px 0; border-bottom:1px solid var(--line)}
.op-detail>div:last-child{border-bottom:0}
.op-detail .k{font-size:12px; color:var(--ink-2); flex:none}
.op-detail .v{font-size:12.5px; font-weight:600; text-align:right; min-width:0; overflow-wrap:anywhere}
.op-detail .cp{padding:2px 6px; margin:0}

@media (max-width:640px){
  .op{grid-template-columns:32px 1fr auto; gap:10px; padding:11px 12px}
  .op-chev{display:none}
  .op-ic{width:32px; height:32px}
  .op-detail{padding-left:12px}
}

.op-empty{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:34px 20px; text-align:center; box-shadow:var(--sh-card)}
.op-empty b{font-size:16px; display:block; margin-bottom:6px}
.op-empty p{margin:0; color:var(--ink-2); font-size:13.5px}

/* --------------------------------------------------- ПЕРЕКЛЮЧАТЕЛЬ ТЕМЫ */
/* Выглядит как переключатель языка намеренно: они стоят рядом и делают одно и
   то же — меняют то, как страница выглядит, не трогая её содержания. */
.theme{display:flex; gap:2px; background:var(--surface-2); border-radius:999px; padding:3px; flex:none}
.theme button{
  display:flex; align-items:center; gap:6px; font:inherit; font-size:12px; font-weight:700;
  cursor:pointer; border:0; background:transparent; color:var(--ink-2);
  padding:5px 9px; border-radius:999px;
}
.theme button[aria-pressed="true"]{background:var(--raised); color:var(--ink)}
.theme svg{width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; display:block}
/* В шапке — одни значки: там рядом уже стоит UA/RU/EN, и два слова подряд
   превратили бы угол в надпись. В карточке аккаунта места хватает, там с текстом. */
.top .theme button{padding:5px 8px}
.top .theme button span{display:none}

.demo-back{
  display:block; text-align:center; padding:18px 10px 26px; font-size:13px;
  color:var(--ink-2); text-decoration:none;
}
.demo-back:hover{color:var(--ink)}

/* =========================================================================
   СПРАВКА
   ========================================================================= */
.hsearch{position:relative; margin-bottom:14px}
.hsearch .ic{position:absolute; left:14px; top:50%; transform:translateY(-50%); color:var(--ink-2)}
.hsearch .inp{padding:13px 14px 13px 40px; font-size:15px}

.hot{display:flex; flex-wrap:wrap; gap:7px; align-items:center; margin-bottom:16px}
.hot:empty{display:none}
.hot-k{font-size:11.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-2)}
.hot-q{
  font:inherit; font-size:13px; font-weight:700; cursor:pointer; padding:7px 13px;
  border-radius:var(--r-chip); border:var(--bw) solid var(--brand);
  background:var(--brand-soft); color:var(--brand-strong); text-align:left;
}
.hot-q:hover{background:var(--brand); color:var(--brand-ink)}

.hq{background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:0; margin-bottom:8px; box-shadow:var(--sh-card)}
.hq summary{
  display:flex; align-items:center; gap:12px; cursor:pointer; list-style:none;
  padding:15px 18px; font-weight:700; font-size:14.5px;
}
.hq summary::-webkit-details-marker{display:none}
.hq summary::after{content:"+"; margin-left:auto; color:var(--ink-2); font-weight:800; font-size:17px}
.hq[open] summary::after{content:"–"}
.hq[open] summary{border-bottom:1px solid var(--line)}
.hq-t{min-width:0}
.hq-c{font-size:10.5px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:3px 8px; border-radius:var(--r-chip); background:var(--surface-2); color:var(--ink-2); flex:none}
.hq-a{padding:14px 18px 16px}
.hq-a p{margin:0; color:var(--ink-2); font-size:13.5px; line-height:1.6; max-width:74ch}
.hq-a .btn{margin-top:12px}

.hempty{background:var(--surface); border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  padding:30px 20px; text-align:center; box-shadow:var(--sh-card)}
.hempty b{display:block; font-size:16px; margin-bottom:6px}
.hempty p{margin:0; color:var(--ink-2); font-size:13.5px}

/* Состояния — теми же точками, что в списке заказов. Объяснять цвета
   другими цветами означает объяснять не то. */
.hstatus{margin-top:22px; background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:16px 18px; box-shadow:var(--sh-card)}
.hstatus:empty{display:none}
.hstatus-k{font-size:11.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-2); margin-bottom:10px}
.hstatus-r{display:flex; align-items:baseline; gap:10px; padding:7px 0; border-top:1px solid var(--line)}
.hstatus-r:nth-child(2){border-top:0}
/* Размер точки задан в .cell-name .st, то есть внутри строки списка.
   Тут точка живёт вне неё — без своего размера она имела нулевую ширину
   и не рисовалась вовсе, хотя цвет ей достался. */
.hstatus-r .st{width:9px; height:9px; border-radius:50%; flex:none; align-self:center}
.hstatus-r b{font-size:13.5px; width:118px; flex:none}
.hstatus-r span:last-child{font-size:13px; color:var(--ink-2)}
@media (max-width:560px){
  .hstatus-r{flex-wrap:wrap}
  .hstatus-r b{width:auto}
  .hstatus-r span:last-child{width:100%; padding-left:17px}
}

.hsupport{
  display:flex; align-items:center; gap:14px; margin-top:22px; padding:16px 18px;
  background:var(--brand-soft); border:var(--bw) solid var(--brand);
  border-radius:var(--r-card); color:var(--brand-strong);
}
.hsupport .ic{display:flex; flex:none}
.hsupport .ic svg{width:22px; height:22px; stroke:currentColor; fill:none; stroke-width:1.5}
.hsupport .txt{display:flex; flex-direction:column; gap:3px; min-width:0}
.hsupport .txt>b{font-size:15px}
.hsupport .txt>span{font-size:13px; opacity:.9}
.hsupport .acc{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace}
.hsupport .acts{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap; flex:none}
@media (max-width:700px){
  .hsupport{flex-wrap:wrap}
  .hsupport .acts{margin-left:0; width:100%}
}

/* --------------------------------------------------- ЯЗЫК И ТЕМА В МЕНЮ */
.side-prefs{display:flex; align-items:center; gap:8px; margin-top:auto; padding-top:14px}
.side-prefs .lang{flex:1; justify-content:center}
.side-prefs .lang button, .side-prefs .lang a{flex:1; text-align:center}
/* В боковом меню тема — одними значками: рядом уже три слова языка, и ещё два
   превратили бы уголок в надпись. */
.side-prefs .theme button span{display:none}
.side-prefs .theme button{padding:6px 8px}
/* На компьютере язык и тема уже стоят в меню, поэтому в карточке аккаунта они
   лишние. На телефоне меню нет — там эти строки единственный путь к ним. */
@media (min-width:901px){ .sheet-lang{display:none} }



/* Значок копирования рядом со значением — мельче значков меню. */
.i16{width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; flex:none}

/* Переключатель темы — форма, поэтому внутри .theme может стоять <form>. */
.theme form{display:contents}

/* Название сервиса ведёт на список заказов, но остаётся текстом. */
.brand a{color:inherit; text-decoration:none}

/* Карточка тарифа стала ссылкой (?tariff=N), чтобы выбор работал и без
   JavaScript. В макете это была кнопка, поэтому подчёркивание и синий цвет
   текста приходится снимать тут — внутри карточки ссылок нет. */
.plan{text-decoration:none}
.plan *{text-decoration:none}

/* Не хватает средств — подпись под калькулятором должна это показать. */
.calc-go .hint.bad{color:var(--bad); font-weight:700}

/* Количество серверов. Стоит между описанием заказа и разбивкой цены, и от
   строк разбивки отделено чертой: это не слагаемое, а множитель — им человек
   управляет, а не читает его. Поле узкое намеренно, число там короткое. */
.calc-qty{display:flex; justify-content:space-between; align-items:center; gap:14px;
  padding-bottom:10px; margin-bottom:6px; border-bottom:1px solid var(--line)}
.calc-qty label{display:flex; flex-direction:column; gap:2px; font-size:13.5px; cursor:pointer}
.calc-qty label b{font-weight:700}
.calc-qty .hint{font-size:11.5px; font-weight:600; color:var(--ink-2)}

/* «−  1  +» одной рамкой, как единый орган управления: рамка на группе, а не
   на каждой части, иначе три бортика встают в ряд и читаются как три кнопки. */
.qty-ctl{display:flex; flex:none; align-items:stretch; border-radius:var(--r-ctl);
  border:var(--bw) solid var(--line); background:var(--field); overflow:hidden}
.qty-ctl button{font:inherit; font-size:17px; font-weight:700; line-height:1; cursor:pointer;
  width:34px; padding:0; border:0; background:transparent; color:var(--ink-2)}
.qty-ctl button:hover:not(:disabled){background:var(--surface); color:var(--ink)}
.qty-ctl button:disabled{opacity:.35; cursor:not-allowed}
.qty-ctl input{width:46px; flex:none; font:inherit; font-size:15px; font-weight:800;
  text-align:center; font-variant-numeric:tabular-nums; padding:8px 0;
  border:0; border-left:var(--bw) solid var(--line); border-right:var(--bw) solid var(--line);
  background:transparent; color:var(--ink)}
.qty-ctl input:focus{outline:none; background:var(--surface)}
.qty-ctl:focus-within{border-color:var(--brand)}

/* Родные стрелки числового поля не поддаются оформлению: в тёмной теме они
   остаются светлыми и наезжают на само число. Убираем — кнопки выше делают
   то же самое и выглядят как остальной кабинет. */
.qty-ctl input::-webkit-outer-spin-button,
.qty-ctl input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.qty-ctl input[type="number"]{-moz-appearance:textfield; appearance:textfield}

/* Строки калькулятора. В макете их рисовал скрипт, тут они приходят так
   же, но классы должны быть описаны. */
.calc-row{display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  padding:5px 0; font-size:13px; color:var(--ink-2)}
.calc-row b{font-weight:700; color:var(--ink)}
.calc-row.off b{color:var(--ok)}

/* В макете протокол и хостер были кнопками. Тут это <label> с радио —
   иначе выбор не пережил бы выключенный JavaScript. Само радио скрываем, но
   НЕ убираем из фокуса: оно растянуто на всю карточку, поэтому клавиатура
   и читалка видят обычный переключатель, а глаз — карточку из макета. */
/*
 * МУЛЬТИКОНФИГ СЮДА НЕ ВХОДИТ — и это не мелочь стиля, а исправление бага.
 *
 * Флажок мультиконфига уже скрыт выше (.multi input) так, как было в
 * макете: нулевого размера. Когда я добавил его в этот перечень, он получил
 * inset:0 и растянулся — но не на свою карточку, ведь в .multi нет
 * position:relative, а на ближайшего позиционированного предка, то есть почти
 * на весь экран заказа. Выходил невидимый флажок поверх страницы: где угодно
 * нажал — и мультиконфиг включился сам.
 *
 * Протоколу и хостеру растянутый вход НУЖЕН (в макете там были кнопки, а
 * тут <label> с радио), поэтому у обоих свой position:relative.
 */
.proto{position:relative}
.site{position:relative}
.proto input[type="radio"], .site input[type="radio"]{
  position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer;
}
.proto:focus-within, .site:focus-within{outline:2px solid var(--brand); outline-offset:2px}

/*
 * АТРИБУТ hidden ДОЛЖЕН РАБОТАТЬ ВСЕГДА.
 *
 * Браузер скрывает [hidden] правилом display:none из своей таблицы стилей, и
 * любой НАШ display его перебивает — просто потому, что авторские стили
 * весят больше. Так «мультиконфиг» показывался на всех восьми плитках
 * протоколов: у .chip есть display:inline-block, и hidden против него ничего
 * не мог. В макете ту же ловушку латали поштучно (.multi[hidden]) — тут она
 * закрыта один раз для всего файла.
 */
[hidden]{display:none !important}

/*
 * ССЫЛКИ, КОТОРЫЕ ВЫГЛЯДЯТ КАК ЭЛЕМЕНТЫ УПРАВЛЕНИЯ.
 *
 * В макете это были <button> и <div>, в проекте — <a>: переход на другую
 * страницу должен работать без JavaScript и открываться в новой вкладке
 * средним кликом. Вместе с тегом приходит обычное подчёркивание браузера —
 * и баланс в мобильной шапке оказался подчёркнутым, будто это ссылка в
 * тексте. Снимаем его там, где элемент имеет вид карточки или кнопки.
 */
.bal, .cell-name, .ord-name, .ord-name a, .plan, .sw-srv, .sheet-row a, .files a{text-decoration:none; color:inherit}

/* ------------------------------------------------------- ОКНО ВОПРОСА --- */
/* Своё вместо window.prompt: то выглядело как системное предупреждение
   браузера, не умело ни подписи, ни ограничения длины, ни оформления. */
.ask{position:fixed; inset:0; z-index:120; display:flex; align-items:center; justify-content:center; padding:18px}
.ask-bg{position:absolute; inset:0; background:rgba(0,0,0,.45)}
.ask-box{
  position:relative; width:100%; max-width:380px; background:var(--surface);
  border:var(--bw) solid var(--card-line); border-radius:var(--r-card);
  padding:18px; box-shadow:var(--sh-pop);
}
.ask-title{font-size:15px; font-weight:700; margin-bottom:12px}
.ask-input{width:100%}
.ask-acts{display:flex; justify-content:flex-end; gap:8px; margin-top:14px}

/* ------------------------------------------ ПОДТВЕРЖДЕНИЕ СПИСАНИЯ --- */
/*
 * Главное в окне — сумма, поэтому она и самая большая: вопрос «точно списать?»
 * без числа не вопрос. Баланс и остаток стоят рядом мелким, ведь это
 * проверка, а не новость: человек сверяет их взглядом и жмёт «Да».
 */
.sure .ask-box{max-width:400px}
.sure-text{margin:0; font-size:13px; color:var(--ink-2); line-height:1.5}
.sure-money{margin-top:14px; border:var(--bw) solid var(--line); border-radius:var(--r-ctl); overflow:hidden}
.sure-sum{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:11px 13px; background:var(--surface-2);
}
.sure-sum span{font-size:12px; color:var(--ink-2)}
.sure-sum b{font-size:22px; font-weight:800; letter-spacing:-.02em}
.sure-rows{padding:4px 13px 9px}
.sure-rows div{display:flex; justify-content:space-between; gap:12px; padding:4px 0; font-size:12.5px}
.sure-rows span{color:var(--ink-2)}
.sure-rows b{font-weight:700}

/* -------------------------------------------------- СТРАНИЦА ЗАКАЗА --- */
/* Полоса срока над фактами: то же, что в списке, тем же видом.
   Главное число страницы не должно зависеть от того, откуда на неё пришли. */
.term{margin:0 0 16px}
.term .bar{height:6px; border-radius:999px; background:var(--surface-2); overflow:hidden; margin-bottom:8px}
.term .ord-term{margin:0}

/* Числа над графиком: среднее, наименьшее и наибольшее за сутки. Сам график
   без них читается как картинка — форма есть, а величины нет. */
.ping-nums{display:flex; flex-wrap:wrap; gap:18px; margin-bottom:12px; font-size:12.5px; color:var(--ink-2)}
.ping-nums b{font-size:19px; font-weight:800; color:var(--ink); margin-right:5px}

/* ---------------------------------------------------- ПОЛОСА СООБЩЕНИЙ --- */
/*
 * Подтверждение выполненного действия. Действия кабинета складывали текст в
 * сессию, а показывать его было некому: человек переименовывал заказ и не видел
 * никакого ответа.
 *
 * Сверху и по центру, а не тостом в углу: в углу его не замечают на
 * телефоне, где большой палец держит низ экрана, а глаза — верх.
 */
.toast{
  position:sticky; top:10px; z-index:60; margin:0 0 14px;
  padding:11px 14px; border-radius:var(--r-ctl);
  background:var(--ok-soft); border:var(--bw) solid var(--ok);
  color:var(--ink); font-size:13.5px; font-weight:600;
}
.toast.bad{background:var(--bad-soft); border-color:var(--bad)}

/* ----------------------------------------------------- СТРАНИЦА ЗАМЕНЫ --- */
/*
 * Две колонки: слева выбор, справа цена и кнопка. Цена липнет к верху —
 * на длинном перечне регионов она иначе уехала бы за границы экрана вместе с
 * выбором, и человек нажимал бы «изменить», не видя суммы.
 */
.chg{display:grid; grid-template-columns:minmax(0,1fr) 260px; gap:16px; align-items:start}
.chg-opts{min-width:0}

.chg-pay{
  position:sticky; top:14px; background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-card); padding:16px;
}
.chg-pay .k{font-size:12px; color:var(--ink-2); font-weight:600}
/* Градиент тут --grad, а НЕ --grad-ink: второе — это цвет текста ПОВЕРХ
   градиента (белый), и как заливка оно давало белые цифры на белой карточке,
   то есть цену, которой на дневной теме не видно вовсе. */
.chg-pay .v{font-size:30px; font-weight:800; margin:2px 0 12px; background:var(--grad);
  -webkit-background-clip:text; background-clip:text; color:transparent}
.chg-pay .btn{width:100%; justify-content:center}
.chg-bal{font-size:12.5px; color:var(--ink-2); margin-bottom:12px}
.chg-bal.bad{color:var(--bad); font-weight:700}

.chg-warn{margin-bottom:14px}
.chg-warn b{display:block; font-size:13px; margin-bottom:7px}
.chg-warn ul{margin:0; padding-left:18px; font-size:12.5px; color:var(--ink-2); line-height:1.7}
.chg-err{margin-bottom:14px; border-color:var(--bad); color:var(--bad); font-size:13.5px; font-weight:600}
.chg-stop h3{font-size:16px; margin:0 0 6px}
.chg-stop .btn{margin-top:12px}

/* Текущее значение показываем, но выбрать его нельзя: иначе непонятно,
   от чего именно идёт замена. Курсор и прозрачность говорят это без подписи. */
.chg .reg.is-current, .chg .proto.is-current, .chg .count.is-current{cursor:default}
.chg .reg:has(:checked), .chg .proto:has(:checked), .chg .count:has(:checked){
  border-color:var(--brand); background:var(--brand-soft);
}
.chg .reg, .chg .proto, .chg .count{position:relative}
.chg .reg input[type="radio"], .chg .count input[type="radio"]{
  position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer;
}

/* Лестница количества конфигураций: ступени одинаковы по размеру, поэтому видно,
   что это перечень, а не поле для произвольного числа. */
.counts{display:grid; grid-template-columns:repeat(auto-fill,minmax(104px,1fr)); gap:9px}
.count{
  display:flex; flex-direction:column; align-items:center; gap:2px; padding:12px 10px;
  background:var(--surface); border:var(--bw) solid var(--card-line);
  border-radius:var(--r-ctl); cursor:pointer;
}
.count:hover{border-color:var(--brand)}
.count[data-off]{opacity:.5}
.count b{font-size:19px; font-weight:800}
.count span{font-size:11.5px; color:var(--ink-2)}

@media (max-width:900px){
  .chg{grid-template-columns:1fr}
  .chg-pay{position:static}
}

/* ------------------------------------------- ЗАГОЛОВОК СТРАНИЦЫ ЗАКАЗА --- */
/*
 * НОМЕР ЗАКАЗА — ЗНАК, А НЕ ПОДПИСЬ.
 *
 * Его называют, когда пишут в поддержку, и именно его ищут глазами первым.
 * Раньше он стоял мелким текстом «Заказ #12» рядом с датой создания,
 * то есть выглядел как часть описания, а не как то, что отсюда забирают.
 */
.ord-id{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size:15px; font-weight:800; color:var(--ink); letter-spacing:.02em}
.ord-id .cpi{opacity:.5}

/* Карандаш стоит в строке заголовка, поэтому не должен ни увеличивать его
   высоту, ни тянуть на себя внимание: он проявляется цветом при наведении. */
.ttl{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.rn{display:inline-flex}
.rn button{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; padding:0; border-radius:var(--r-ctl);
  border:var(--bw) solid var(--card-line); background:var(--surface);
  color:var(--ink-2); cursor:pointer; transition:color .15s, border-color .15s;
}
.rn button:hover{color:var(--brand-strong); border-color:var(--brand)}
.rn svg{fill:none; stroke:currentColor; stroke-width:1.6}

@media (prefers-reduced-motion:reduce){
  .rn button{transition:none}
}

/* ------------------------------------------ ДЕЙСТВИЯ НАД ЗАКАЗОМ -------- */
/*
 * Ряд действий заказа. Стоял в самом низу страницы, под графиком пинга, и
 * состоял из пяти одинаковых кнопок — то есть главное, ради чего сюда
 * заходят, и искалось прокруткой, и не отличалось от второстепенного.
 *
 * Теперь раздел идёт сразу за фактами, продление в нём одно покрашенное
 * (.btn.grad), а замены — тихие плитки с подписью цены. Цена вынесена в <b> и
 * прижата к правому краю: в ряду из четырёх замен глаз сравнивает именно суммы.
 */
.acts{display:flex; flex-wrap:wrap; gap:9px; align-items:center}
.acts form{display:contents}

.acts .btn.quiet{display:inline-flex; align-items:center; gap:8px}
.acts .btn.quiet .ic{display:inline-flex; color:var(--ink-2)}
.acts .btn.quiet .ic svg{width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.6}
.acts .btn.quiet b{font-weight:800; color:var(--brand-strong); white-space:nowrap}
.acts .btn.quiet:hover .ic{color:var(--brand-strong)}

/* Запрещённую хостером замену показываем, но не делаем вид, что на неё можно
   нажать: иначе о запрете узнают уже после нажатия. */
.acts .btn.quiet.off{opacity:.45; cursor:not-allowed}
.acts .btn.quiet.off:hover{border-color:var(--card-line)}

/* Опасный раздел. Отдельной карточкой, а не полосой внутри «Управления»:
   удаление — единственное действие, которое нельзя откатить. */
.card.danger{border-color:color-mix(in srgb, var(--bad) 35%, var(--card-line))}

@media (max-width:640px){
  /* На телефоне кнопки в ряд не влезают и ломаются на полуслове. */
  .acts{flex-direction:column; align-items:stretch}
  .acts .btn{width:100%; justify-content:center}
  .acts .btn.quiet{justify-content:space-between}
}

/* ----------------------------------------------- ЭКРАН ПЕРЕВОДА --------- */
/*
 * Счёт на пополнение. Экран одной задачи: перевести сумму на адрес —
 * и больше тут не делают ничего.
 *
 * ПОЧЕМУ УЗКАЯ КОЛОНКА. Первая версия раскладывала те же данные четырьмя плитами
 * на всю ширину страницы (1480 px), и на мониторе это выглядело как недоделанный
 * экран: сумма терялась посреди пустой полосы, адрес стоял в левой трети,
 * а правые две трети карточек были пусты. Данных хватало — не хватало
 * границы, в которую их сложено.
 */
.pay{max-width:660px; margin:0 auto}
.pay-card{padding:0; overflow:hidden}

/* Каждый блок карточки отделён волосяной линией: счёт читается сверху вниз
   строка за строкой, а не как набор отдельных карточек. */
.pay-card > *{padding:18px 20px; border-top:var(--bw) solid var(--line)}
.pay-card > *:first-child{border-top:0}

.pay-head{display:flex; align-items:center; gap:13px}
.pay-head .coin{
  width:44px; height:44px; flex:none; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--grad); color:var(--grad-ink);
  font-size:19px; font-weight:800; letter-spacing:-.02em;
}
.pay-head .coin.abbr{font-size:12.5px; letter-spacing:.02em}
.pay-head .ttl{min-width:0}
.pay-head b{display:block; font-size:16px; font-weight:800; line-height:1.25}
.pay-head .sub{display:block; font-size:12px; color:var(--ink-2); margin-top:3px}

/* --- сумма ------------------------------------------------------------ */
.pay-amount{text-align:center}
.pay-amount .k{font-size:11.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-2)}
.pay-amount .n{
  display:flex; align-items:baseline; justify-content:center; gap:9px; margin:6px 0 12px;
  font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}
.pay-amount .n b{
  font-size:36px; font-weight:800; letter-spacing:-.02em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.pay-amount .n span{font-size:17px; font-weight:700; color:var(--ink-2)}
.pay-amount .btn{gap:7px}
.pay-amount .hint{margin:12px 0 0}
.pay-amount .hint.exact{margin-top:6px}

/* Кнопка «Скопировать» — обычная кнопка, поэтому общее правило .cp.done с его
   галочкой после значения тут лишнее: подтверждаем цветом. */
.pay-amount .cp.done{background:var(--ok-soft); color:var(--ok)}
.pay-amount .cp.done .v::after{content:none}

/* --- QR и адрес -------------------------------------------------------- */
.pay-to{display:flex; align-items:center; gap:18px}
/* QR — главный носитель адреса, поэтому заметно больше и в градиентной рамке:
   белизна внутри остаётся чистой (иначе сканер не берёт), цвет даёт лишь
   рамка и мягкое свечение под ней. Обе темы: рамка и тень на токенах. */
.pay-to .qr{
  width:188px; height:188px; flex:none; padding:11px; border-radius:18px;
  background:linear-gradient(#FFF,#FFF) padding-box, var(--grad) border-box;
  border:3px solid transparent;
  box-shadow:0 12px 30px color-mix(in oklab, var(--brand) 26%, transparent);
  display:flex; align-items:center; justify-content:center;
}
.pay-to .qr svg, .pay-to .qr img{width:100%; height:100%; display:block}
.pay-to .addr{min-width:0; flex:1}
.pay-to .addr .k{font-size:11.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-2); margin-bottom:5px}
/* Адрес не переносим: разрыв строки читается как два разных кошелька.
   Кошелёк сделали заметнее: целое поле-«чип» на всю ширину, больший кегль —
   его читают и сверяют глазами, поэтому мелкая строка тут вредила. */
.pay-to .addr .cp{max-width:100%; width:100%; padding:11px 12px; margin-left:0;
  border:var(--bw) solid var(--line); border-radius:var(--r-ctl); background:var(--surface-2)}
.pay-to .addr .cp:hover{border-color:var(--brand); background:var(--surface-2);
  box-shadow:0 0 0 3px rgba(var(--tint),.15)}
.pay-to .addr .cp .v{font-size:15px; font-weight:600; overflow-x:auto; text-overflow:clip}
.pay-to .note{margin-top:11px}

/* --- справка ----------------------------------------------------------- */
/* Сеткой, а не строкой: во флексе три коротких подписи сбивались в левый угол
   и оставляли половину строки пустой. */
.pay-facts{display:grid; grid-template-columns:repeat(auto-fit,minmax(110px,1fr)); gap:12px}
.pay-facts .k{font-size:11px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2)}
.pay-facts .v{font-size:14px; font-weight:700; margin-top:2px}

/* --- состояние --------------------------------------------------------- */
/* Последняя строка карточки: подпись слева, сколько осталось — справа.
   Значок состояния приходит в самой подписи (⏳ / 🎉 / ❌), поэтому своего тут
   нет: два маркера одного и того же рядом читаются как ошибка. */
.pay-state{display:flex; align-items:center; gap:12px; background:var(--surface-2)}
.pay-state .txt{font-size:14px; font-weight:700}
.pay-state .left{margin-left:auto; font-size:15px; font-weight:800; color:var(--ink-2); font-variant-numeric:tabular-nums}
.pay-state.is-paid{background:var(--ok-soft)}
.pay-state.is-paid .txt{color:var(--ok)}
.pay-state.is-over{background:var(--bad-soft)}
.pay-state.is-over .txt{color:var(--bad)}

@media (max-width:560px){
  .pay-to{flex-direction:column; align-items:stretch}
  .pay-to .qr{width:100%; height:auto; aspect-ratio:1; max-width:220px; margin:0 auto}
  .pay-amount .n b{font-size:30px}
  .pay-card > *{padding:16px}
}

/* =========================================================== ГОСТЬ ====== */
/*
 * Страницы до входа: авторизация и «нужен вход».
 *
 * Тот же дизайн, что в кабинете, но без его оболочки — бокового меню,
 * баланса и панели вкладок у гостя быть не может, за ними ничего нет.
 * Остаётся логотип, язык и тема: ровно то, чем пользуются до входа.
 */
body.guest{min-height:100dvh; display:flex; flex-direction:column}
.g-wrap{flex:1; display:flex; flex-direction:column; width:100%; max-width:1100px; margin:0 auto; padding:16px}

.g-top{display:flex; align-items:center; gap:14px; padding:4px 2px 0}
/* .brand в кабинете — строка со вложенной ссылкой, тут ссылка САМА и есть
   .brand. Без этой строки название сервиса в шапке становилось синим и
   подчёркнутым, как обычная ссылка в тексте. */
.g-top .brand{margin:0; flex:1; min-width:0; padding:0; text-decoration:none; color:inherit}
.g-top .brand img{width:30px; height:30px; border-radius:9px; object-fit:cover; flex:none}
.g-tools{display:flex; align-items:center; gap:10px; flex:none}

/* Главное — карточка по центру экрана, а не прижатая к шапке: страница
   делает одно дело, и смотреть на ней больше некуда. */
.g-main{flex:1; display:flex; align-items:center; justify-content:center; padding:24px 0 40px}
.g-card{width:100%; max-width:420px; text-align:center; padding:26px 24px}

/* --- общее для входа и «нужен вход» ------------------------------------- */
.auth .back{display:inline-flex; margin:0 0 14px; align-self:flex-start}
.auth h1{font-size:22px; margin:0 0 8px; letter-spacing:-.02em}
/* Пояснение приходит из перевода с переносом строки — он там намеренный. */
.auth .lede{margin:0; color:var(--ink-2); font-size:14px; line-height:1.55; white-space:pre-line}

.auth-logo{
  width:112px; height:112px; margin:2px auto 12px; display:block; border-radius:50%;
  object-fit:cover; box-shadow:0 0 0 var(--bw) var(--card-line), var(--sh-pop);
  animation:auth-float 3.6s ease-in-out infinite;
}
/* Лёгкое покачивание аватара бота — оживляет страницу, куда человек пришёл ждать. */
@keyframes auth-float{ 0%,100%{transform:translateY(0)} 50%{transform:translateY(-7px)} }
@media (prefers-reduced-motion:reduce){ .auth-logo{animation:none} }

/* Код — главное число страницы: его переносят в бота. */
.auth-code{margin:14px 0 12px; padding:12px 14px; background:var(--surface-2); border-radius:var(--r-ctl)}
.auth-code .k{font-size:11.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-2)}
.auth-code .cp{margin-top:4px; padding:4px 8px}
.auth-code .cp .v{
  font-size:30px; font-weight:800; letter-spacing:.14em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* Ответ на копирование рисует общее .cp.done — на прозрачном тексте его
   не видно, поэтому цвет возвращаем. */
.auth-code .cp.done .v{background:none; color:var(--ok); -webkit-text-fill-color:currentColor}

.auth-go{width:100%; justify-content:center; gap:8px; margin-top:14px}
/* Второй путь к боту — тихой строкой: он нужен лишь тому, у кого нет
   приложения, и спорить с главной кнопкой за внимание не должен. */
.auth-web{display:inline-block; margin-top:12px; font-size:13px; color:var(--brand-strong); text-decoration:none}
.auth-web:hover{text-decoration:underline}
.auth-web.quiet{color:var(--ink-2); font-size:12px}
.auth-ttl{margin:12px 0 0}
.auth-ttl b{color:var(--ink)}

/* --- строка состояния -------------------------------------------------- */
/* Точка мигает, пока страница и правда спрашивает сервер: это единственный
   признак, что вход ещё возможен и ждать имеет смысл. */
.auth-state{
  display:flex; align-items:center; justify-content:center; gap:9px;
  margin-top:20px; padding-top:16px; border-top:var(--bw) solid var(--line);
  font-size:13px; font-weight:700; color:var(--ink-2);
}
.auth-state .live{
  width:8px; height:8px; border-radius:50%; flex:none; background:var(--brand);
  animation:auth-pulse 1.5s ease-in-out infinite;
}
.auth-state.is-paused .live{animation:none; background:var(--warn)}
.auth-said:empty{display:none}
.auth-said{margin:10px 0 0; color:var(--warn)}

@keyframes auth-pulse{
  0%, 100%{opacity:1; transform:scale(1)}
  50%{opacity:.3; transform:scale(.8)}
}

@media (prefers-reduced-motion:reduce){
  .auth-state .live{animation:none}
}

@media (max-width:480px){
  .g-card{padding:22px 18px}
  .auth-code .cp .v{font-size:26px}
}

/* -------------------------------------------------------------- ФЛАГИ --- */
/*
 * Нарисованных флажков в проекте шесть, а стран в справочнике сорок с лишним.
 * Компонент <x-flag> подставляет символьный флажок там, где картинки нет,
 * и оба должны выглядеть одинаково: иначе в одном ряду половина стран
 * читалась бы как другой тип элемента.
 */
/* Два класса, а не один: так правило бьёт размеры .flag-img, заданные для
   картинки выше в файле, и снимает с символа рамку — вокруг эмодзи она
   выглядит как ошибка вёрстки. */
.flag-img.flag-emoji{
  display:inline-flex; align-items:center; justify-content:center;
  width:auto; height:auto; font-size:16px; line-height:1;
  box-shadow:none; border-radius:0;
  font-family:"Noto Color Emoji","Apple Color Emoji","Segoe UI Emoji",sans-serif;
}

/* ----------------------------------------------- ДОКУМЕНТ (ПРАВИЛА) ---- */
/*
 * Долгий текст, который читают сверху вниз. Колонка уже карточки кабинета
 * намеренно: строка длиной на весь экран глазами не держится, а правила — это
 * именно то, что читают внимательно или не читают вовсе.
 */
.g-doc{width:100%; max-width:760px; margin:0 auto; padding:8px 0 40px}
.g-doc .back{display:inline-flex; margin-bottom:16px}

.doc-head{margin-bottom:22px}
.doc-head h1{font-size:26px; margin:0; letter-spacing:-.02em}
.doc-head .sub{margin:6px 0 0; color:var(--ink-2); font-size:14.5px}
.doc-head .hint{margin:10px 0 0}

/* Главный тезис — карточка с акцентной рамкой: её должен увидеть тот, кто
   открыл страницу по диагонали. */
.doc-accept{border-color:var(--brand); background:var(--brand-soft); margin-bottom:26px}
.doc-accept b{display:block; font-size:15.5px; margin-bottom:7px}
.doc-accept p{margin:0; font-size:14px; line-height:1.65; color:var(--ink-2)}

.doc-part{margin-bottom:26px}
.doc-part h2{font-size:17px; font-weight:800; margin:0 0 10px; letter-spacing:-.01em}
.doc-lead{margin:0 0 8px; font-size:14px; color:var(--ink-2)}
.doc-part ul{margin:0; padding-left:20px; display:grid; gap:9px}
.doc-part li{font-size:14px; line-height:1.65; color:var(--ink-2)}

.doc-contacts{text-align:center; padding:22px}
.doc-contacts b{display:block; font-size:15.5px; margin-bottom:6px}
.doc-contacts p{margin:0 0 16px; font-size:14px; color:var(--ink-2)}

@media (max-width:560px){
  .doc-head h1{font-size:22px}
}

/* Согласие с правилами. Текст длиннее одной строки, поэтому галочка
   выравнивается по ПЕРВОЙ строке, а не по середине абзаца — иначе она съезжает
   вниз и перестаёт читаться как пара к нему. Черта сверху отделяет согласие от
   подсчёта: это уже не про деньги. */
.terms-ok{
  align-items:flex-start; gap:10px; margin-top:14px; padding-top:13px;
  border-top:1px solid var(--line); font-size:12.5px; line-height:1.5; color:var(--ink-2);
}
.terms-ok .box{margin-top:1px}
.terms-ok a{color:var(--brand-strong)}

/*
 * ПОЧЕМУ ПОЛЕ ТУТ ИМЕЕТ РАЗМЕР, ХОТЯ ЕГО НЕ ВИДНО.
 *
 * Общее правило скрывает флажок в ноль (.chk input — width:0; height:0), и
 * именно из-за этого нажатие «Заказать» без галочки НЕ давало ничего: браузер
 * останавливал отправку через required, но свою подсказку показать не мог —
 * подсказка крепится к полю, а поля размером ноль на экране нет. В консоли
 * при этом оставалась строка «An invalid form control is not focusable», которую
 * клиент, разумеется, не видит.
 *
 * Поэтому флажок согласия остаётся прозрачным, но имеет размер своей
 * нарисованной коробки и лежит ровно на ней: подсказка браузера получает, к чему
 * прикрепиться, и работает даже с выключенным JavaScript.
 */
.terms-ok input{width:17px; height:17px; left:0; top:14px}

/*
 * ОТКАЗ ДОЛЖЕН БЫТЬ ВИДЕН.
 *
 * Подсказки браузера мало: она исчезает за секунды, выглядит чужой и на
 * телефоне может появиться вне экрана. Поэтому сама строка согласия помечается
 * красным и остаётся такой, пока галочку не поставят, — это ответ на
 * вопрос «почему не работает кнопка», а не мгновенная вспышка.
 */
@keyframes terms-shake{
  0%,100%{transform:translateX(0)}
  18%{transform:translateX(-6px)}
  38%{transform:translateX(5px)}
  58%{transform:translateX(-3px)}
  78%{transform:translateX(2px)}
}
.terms-ok.shake{animation:terms-shake .38s ease}
.terms-ok.needs{color:var(--bad)}
.terms-ok.needs a{color:var(--bad)}
.terms-ok.needs .box{border-color:var(--bad)}
.terms-ok.needs input:not(:checked) + .box{box-shadow:0 0 0 4px color-mix(in srgb, var(--bad) 20%, transparent)}

/* Движение — не единственный носитель смысла: цвет остаётся и тогда, когда
   анимации выключены в системе. */
@media (prefers-reduced-motion: reduce){
  .terms-ok.shake{animation:none}
}

/* =================================================== ПОПОЛНЕНИЕ: ЖИВОЕ ===
 *
 * Пополнение должно ХОТЕТЬСЯ сделать: цвет, мягкое свечение и движение делают
 * экран праздничным, но без крика — всё на токенах, поэтому день и ночь читаются
 * оба, а @media (prefers-reduced-motion) снимает движение и оставляет цвет.
 *
 * Новое не затрагивает общих правил: анимации CTA привязаны к #s-topup, большие
 * числа — к #s-transfer, а остальное — к своим классам экранов пополнения.
 * ======================================================================== */

/* --- поле суммы: свой степпер + убранный родной ------------------------ */
/* Родные стрелки number-поля разные в каждом браузере и портят поле — скрываем
   их и даём свои кнопки. */
.money input::-webkit-outer-spin-button,
.money input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.money input[type=number]{-moz-appearance:textfield; appearance:textfield}
.money input{padding-right:92px}
.money .step{position:absolute; right:8px; top:50%; transform:translateY(-50%);
  display:flex; gap:6px}
.money .step button{
  width:36px; height:36px; flex:none; padding:0; line-height:1;
  display:flex; align-items:center; justify-content:center;
  font:inherit; font-size:20px; font-weight:800; cursor:pointer; color:var(--ink);
  border:var(--bw) solid var(--line); border-radius:calc(var(--r-ctl) - 4px);
  background:var(--surface-2);
  transition:transform .12s ease, box-shadow .18s ease, border-color .18s ease, background .18s ease, color .18s ease;
}
.money .step button:hover{border-color:var(--brand); color:var(--brand-strong);
  box-shadow:0 0 0 3px rgba(var(--tint),.18)}
.money .step .s-up:hover{background:color-mix(in oklab, var(--accent) 20%, var(--surface-2));
  border-color:var(--accent)}
.money .step button:active{transform:scale(.88)}

/* --- быстрые суммы: выбранная светится и пульсирует -------------------- */
.amounts button{transition:transform .1s ease, box-shadow .18s ease, border-color .18s ease}
.amounts button:active{transform:scale(.94)}
.amounts button[aria-pressed="true"]{
  background:var(--grad); background-origin:border-box; background-repeat:no-repeat;
  color:var(--grad-ink); border-color:transparent;
  animation:amt-pop 2.4s ease-in-out infinite;
}
@keyframes amt-pop{
  0%,100%{box-shadow:0 0 0 3px rgba(var(--tint),.18), 0 6px 16px rgba(var(--tint),.20)}
  50%{box-shadow:0 0 0 5px rgba(var(--tint),.28), 0 9px 22px rgba(var(--tint),.32)}
}

/* --- способы оплаты: у каждого свой фирменный цвет -------------------- */
/* Значок монеты больше не серый: у каждого метода свой цвет (Tether —
   зелёно-бирюзовый, TRON — красный, CryptoBot — синий). Cryptomus остаётся
   приглушённым: он недоступен, и цвет тут читался бы как «работает». */
.m{--mc:var(--brand); --mc2:var(--brand-strong);
  transition:border-color .18s ease, background .18s ease, box-shadow .2s ease}
.m[data-method="usdt_trc20"]{--mc:#12B98A; --mc2:#12A8B8}
.m[data-method="trx"]{--mc:#F0413F; --mc2:#C11F38}
.m[data-method="cryptobot"]{--mc:#2AABEE; --mc2:#1E7FD4}
.m[data-method="usdt_trc20"] .ic,
.m[data-method="trx"] .ic,
.m[data-method="cryptobot"] .ic{
  background:linear-gradient(135deg, var(--mc), var(--mc2)); color:#FFF;
  box-shadow:0 3px 9px color-mix(in oklab, var(--mc) 34%, transparent);
}
/* Выбранная строка светится СВОИМ цветом, а не общим брендовым. */
.m[data-on]{border-color:var(--mc); background:color-mix(in oklab, var(--mc) 13%, var(--field));
  animation:m-glow 2.3s ease-in-out infinite}
.m[data-on] .ic{background:linear-gradient(135deg, var(--mc), var(--mc2)); color:#FFF}
@keyframes m-glow{
  0%,100%{box-shadow:0 0 0 3px color-mix(in oklab, var(--mc) 18%, transparent), 0 8px 20px color-mix(in oklab, var(--mc) 15%, transparent)}
  50%{box-shadow:0 0 0 5px color-mix(in oklab, var(--mc) 26%, transparent), 0 10px 26px color-mix(in oklab, var(--mc) 24%, transparent)}
}

/* --- главная кнопка: градиент с бегущим блеском ----------------------- */
/* Блеск — отдельный слой поверх градиента (::after), сам градиент не трогаем:
   так другие экраны с .btn.grad остаются неизменными. Привязка к #s-topup. */
#s-topup .btn.grad.wide{position:relative; overflow:hidden;
  transition:transform .12s ease, filter .18s ease, box-shadow .2s ease}
#s-topup .btn.grad.wide::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(105deg, transparent 32%, rgba(255,255,255,.5) 50%, transparent 68%);
  transform:translateX(-120%);
  animation:cta-sheen 3.2s ease-in-out infinite;
}
#s-topup .btn.grad.wide:hover{transform:translateY(-1px);
  box-shadow:0 10px 26px rgba(var(--tint),.4)}
#s-topup .btn.grad.wide:active{transform:translateY(0) scale(.99)}
@keyframes cta-sheen{
  0%{transform:translateX(-120%)}
  60%,100%{transform:translateX(120%)}
}

/* --- счёт: большое число с переливом и аурой -------------------------- */
#s-transfer .pay-amount .n b{
  background-size:220% 100%;
  animation:amt-shimmer 5s ease-in-out infinite;
  filter:drop-shadow(0 0 16px color-mix(in oklab, var(--brand) 30%, transparent));
}
@keyframes amt-shimmer{
  0%,100%{background-position:0% 50%}
  50%{background-position:100% 50%}
}

/* --- ожидание оплаты: тёплый пульс ------------------------------------ */
/* Своего значка не добавляем (он уже в подписи — ⏳); лишь живой цвет: строка
   теплеет и гаснет, поэтому видно, что экран ждёт, а не завис. */
.pay-state:not(.is-paid):not(.is-over){animation:wait-glow 2.6s ease-in-out infinite}
.pay-state:not(.is-paid):not(.is-over) .txt{color:var(--warn)}
@keyframes wait-glow{
  0%,100%{background:var(--surface-2)}
  50%{background:color-mix(in oklab, var(--warn) 14%, var(--surface-2))}
}

/* Движение — украшение, не смысл: в reduced-motion оставляем цвет, снимаем
   анимацию и трансформации нажатия. */
@media (prefers-reduced-motion:reduce){
  .amounts button[aria-pressed="true"],
  .m[data-on],
  #s-topup .btn.grad.wide::after,
  #s-transfer .pay-amount .n b,
  .pay-state:not(.is-paid):not(.is-over){animation:none}
  .amounts button, .money .step button,
  #s-topup .btn.grad.wide{transition:none}
  .amounts button:active, .money .step button:active,
  #s-topup .btn.grad.wide:hover, #s-topup .btn.grad.wide:active{transform:none}
}
