/* Тема кабинета Converter — та же, что у 404.vodka.
 *
 * Палитра и шрифты взяты не «на глаз со скриншота», а из настоящей таблицы стилей
 * лендинга (project_404/static/landing/css/main.css, блок :root и [data-theme="light"]):
 * значения должны совпадать до цифры, иначе продукты одной марки будут выглядеть
 * похоже-но-не-так, а это заметно сильнее, чем полное различие.
 *
 * Одно отличие сознательное. На лендинге кнопки и мелкие подписи набраны Orbitron
 * (--f-display). В Orbitron нет кириллических глифов — замерено на Android-клиенте:
 * покрытие cmap нулевое, браузер подставляет свой фолбэк, и кнопка «Применить» вылезает
 * другим шрифтом рядом с латинской. Поэтому Orbitron здесь применяется только к
 * латинскому логотипу, а «техничность» кнопок и подписей делается тем же приёмом на
 * IBM Plex Sans: верхний регистр плюс разрядка.
 */

:root {
  --bg: #080c10;
  --bg-1: #0e1318;
  --bg-2: #141b23;
  --text: #dde4ec;
  --muted: #4d5f73;
  --faint: #1e2831;
  --cyan: #00e5c5;
  --cyan-dim: rgba(0, 229, 197, 0.12);
  --pink: #ff3366;
  --purple: #9b5de5;
  --line: rgba(255, 255, 255, 0.07);
  --f-display: 'Orbitron', sans-serif;
  --f-body: 'IBM Plex Sans', 'Urbanist', system-ui, sans-serif;
  --f-mono: 'IBM Plex Mono', 'JetBrains Mono', ui-monospace, monospace;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --nav-height: 60px;
  --container-max: 1040px;
  --ok: #00e5c5;
  --warn: #ffb347;
  --err: #ff3366;
  /* Акцент отдельно для заливок и отдельно для текста. На тёмном фоне это одно и то же,
   * на светлом — нет: бирюза лендинга на светлой панели даёт контраст 2.8:1, а это
   * нечитаемо для 15 пикселей. На лендинге тем же цветом набраны крупные заголовки,
   * у нас — ссылки и сообщения, поэтому текстовые токены свои. */
  --cyan-text: #00e5c5;
  --pink-text: #ff3366;
  --warn-text: #ffb347;
  --purple-text: #9b5de5;
}

[data-theme="light"] {
  --bg: #f2f4f7;
  --bg-1: #e8ebf0;
  --bg-2: #ffffff;
  --text: #111820;
  /* Темнее, чем #6b7a8d лендинга: там этим цветом набраны абзацы по 16–18 пикселей,
   * а у нас подписи колонок по 11. Замер на панели: было 3.67:1, стало 5.36:1. */
  --muted: #54606f;
  --faint: #dde2e8;
  --line: rgba(0, 0, 0, 0.08);
  --cyan: #009e89;
  --cyan-dim: rgba(0, 158, 137, 0.1);
  --pink: #d81f4a;
  --purple: #7b3fc4;
  --ok: #009e89;
  --warn: #b26a00;
  --err: #d81f4a;
  /* Текстовые значения: 5.5:1, 5.8:1, 5.4:1 и 5.3:1 на светлой панели. */
  --cyan-text: #00695c;
  --pink-text: #b3103a;
  --warn-text: #8a5200;
  --purple-text: #7b3fc4;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.6 var(--f-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--cyan-text); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── шапка ─────────────────────────────────────────────── */

.nav {
  height: var(--nav-height);
  border-bottom: 1px solid var(--line);
  background: rgba(8, 12, 16, 0.85);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 10;
}

[data-theme="light"] .nav { background: rgba(242, 244, 247, 0.88); }

/* Единственное место, где Orbitron уместен: латинское слово. */
.logo {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
}
.logo:hover { text-decoration: none; color: var(--cyan-text); }
.logo b { color: var(--cyan-text); font-weight: 700; }

.nav__link {
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 0;
  border-bottom: 1px solid transparent;
  transition: color 0.25s, border-color 0.25s;
}
.nav__link:hover { color: var(--text); text-decoration: none; }
.nav__link.is-active { color: var(--cyan-text); border-bottom-color: var(--cyan); }

.nav__spacer { margin-left: auto; }

.nav__user {
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 12px;
}

main {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 28px 22px 64px;
}

.foot {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 22px 40px;
  color: var(--muted);
  font-size: 12px;
}

/* ── панели ────────────────────────────────────────────── */

.panel {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 22px 20px;
  margin-bottom: 18px;
  position: relative;
  overflow: hidden;
}

/* Полоска сверху — узнаваемая деталь карточек лендинга. */
.panel::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--cyan), var(--purple));
  opacity: 0.35;
}

.panel h2, .panel h3 { margin: 0 0 14px; font-weight: 600; }
.panel h2 { font-size: 19px; }
.panel h3 { font-size: 16px; }

h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0 0 18px;
}
h2 { font-size: 19px; font-weight: 600; }

.muted { color: var(--muted); font-size: 13px; }

/* ── раскладка ─────────────────────────────────────────── */
/* Три утилиты вместо трёх десятков повторов инлайнового style= в шаблонах: отступ
 * сверху, строка с разнесёнными краями и строка кнопок. Больше не заводим — полноценные
 * утилитарные классы придут с дизайн-системой (converter#565), а до неё важно, чтобы
 * отступы задавались из одного места, а не переписывались в каждом шаблоне. */

.mt { margin-top: 12px; }
.mt-lg { margin-top: 20px; }

.row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
}

.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* Для коротких технических значений — имён нод, портов, адресов: перенос посреди
   слова читается как опечатка, а не как перенос. */
.nowrap { white-space: nowrap; }
.actions form { display: contents; }

/* ── таблицы ───────────────────────────────────────────── */

table { width: 100%; border-collapse: collapse; }

th, td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

th {
  color: var(--muted);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

tr:last-child td { border-bottom: 0; }

/* ── состояния и полоса квоты ──────────────────────────── */

.bar { height: 6px; background: var(--faint); border-radius: 3px; overflow: hidden; }
.bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--purple)); }
.bar.alert span { background: linear-gradient(90deg, var(--warn), var(--pink)); }

.state-active { color: var(--cyan-text); }
.state-error, .state-degraded { color: var(--pink-text); }
.state-creating, .state-stopped { color: var(--muted); }
/* Пауза — не поломка и не работа: приглушённым, как остановленная, потому что
   связка ничего не делает; жёлтым её красить нельзя — разбирать нечего. */
.state-paused { color: var(--muted); }
/* Предупреждение внутри ячейки: не ошибка — состояние рабочее, — но и не серый текст,
   который проскальзывают взглядом. */
.state-warn { color: var(--warn-text); font-size: 13px; margin-top: 4px; }

/* ── кнопки ────────────────────────────────────────────── */

button, .btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 18px;
  border: 0;
  border-radius: 3px;
  background: var(--cyan);
  color: #05080b;
  font-family: var(--f-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 0.2s var(--ease), box-shadow 0.25s, border-color 0.25s, color 0.25s;
}
button:hover, .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(0, 229, 197, 0.22);
  text-decoration: none;
}

button.ghost, .btn.ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--line);
  box-shadow: none;
}
button.ghost:hover, .btn.ghost:hover {
  border-color: var(--cyan);
  color: var(--cyan-text);
  background: var(--cyan-dim);
  box-shadow: none;
}

button.danger, .btn.danger { background: transparent; color: var(--pink-text); border: 1px solid var(--pink); }
button.danger:hover, .btn.danger:hover { background: rgba(255, 51, 102, 0.12); box-shadow: none; }

button:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* ── формы ─────────────────────────────────────────────── */

input, select, textarea {
  background: var(--bg-2);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 9px 10px;
  width: 100%;
  font: inherit;
  transition: border-color 0.2s;
}
input:focus, select:focus, textarea:focus { outline: 0; border-color: var(--cyan); }

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

   Переменные объявлены на его собственных корнях (.ss-main и .ss-content), а НЕ на
   :root, и это не стиль: файл библиотеки грузится после нашего, и её `:root` перебил
   бы наши значения. На её классах спор невозможен вовсе — заодно тема не расползается
   на страницы, где виджета нет.

   .ss-content библиотека кладёт в конец body, поэтому оба корня перечислены: у них не
   общий родитель, и наследование от одного второго не покроет. */
.ss-main, .ss-content {
  --ss-primary-color: var(--cyan);
  --ss-bg-color: var(--bg-2);
  --ss-font-color: var(--text);
  --ss-font-placeholder-color: var(--muted);
  --ss-border-color: var(--line);
  --ss-focus-color: var(--cyan);
  --ss-disabled-color: var(--bg-1);
  --ss-error-color: var(--pink);
  --ss-border-radius: 3px;
  /* Под наши поля: input у нас 9px отступа плюс строка — около сорока пикселей. */
  --ss-main-height: 40px;
  --ss-spacing-l: 8px;
  --ss-spacing-m: 6px;
  --ss-spacing-s: 4px;
}
/* Выбранное — «плашками» с цветом наших кнопок. Текст в плашке библиотека красит
   переменной фона (--ss-bg-color), поэтому на бирюзовом он выходит тёмным в тёмной
   теме и белым в светлой — как у кнопок, а не как случайное совпадение. */
.ss-main .ss-values .ss-value { font-weight: 500; }
.ss-main:focus { box-shadow: none; border-color: var(--cyan); }
.ss-content { border-radius: 3px; }

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

   Отдельно от обычного select, потому что браузер рисует его иначе:
   высота считается по size, у строк своя подложка, а выбранную строку он красит
   системным акцентом — синим на макоси, — и в нашей теме это выглядит чужой деталью.

   Выбранная строка красится через linear-gradient, а не background-color: Chrome и
   Safari цвет фона у option игнорируют, а градиент из одного цвета применяют. Приём
   известный и некрасивый, но альтернатива — рисовать список на скриптах, то есть
   заводить свой виджет там, где хватает штатного элемента. */
select[multiple] {
  padding: 4px;
  /* Высота из числа строк, а не из size: браузер считает по size своей меркой строки и
     про отступы у option не знает — на трёх пунктах появлялась полоса прокрутки.
     --rows приходит из шаблона, поэтому новая роль высоту тоже подвинет.
     Арифметика: строка 34px (20 на текст плюс 7+7), свои отступы 8, рамки 2 и ещё 2
     на запас — высота строки у браузера дробная (замерено 33.5px), и без запаса
     содержимое на пиксель не влезало, а полоса прокрутки на списке из трёх пунктов
     читается как поломка. box-sizing здесь border-box, он общий для полей. */
  height: calc(var(--rows, 3) * 34px + 12px);
  /* У select[multiple] браузер по умолчанию держит overflow-y: scroll и всегда
     отводит полосе прокрутки 15 пикселей справа — замерено. Список ровно по числу
     строк переполниться не может, поэтому auto: полоса появится, только если она
     действительно понадобится, а не «на случай». */
  overflow-y: auto;
}
select[multiple] option {
  padding: 7px 8px;
  line-height: 20px;
  border-radius: 3px;
  color: var(--text);
}
select[multiple] option:checked {
  background: linear-gradient(var(--cyan-dim), var(--cyan-dim));
  color: var(--cyan-text);
  font-weight: 500;
}
/* Выключенный мультиселект у того, кому нельзя назначать: браузер и так гасит его
   курсором, но не цветом — без этого поле выглядит рабочим. */
select[multiple]:disabled { opacity: 0.6; }
textarea { font-family: var(--f-mono); font-size: 13px; }

label {
  display: block;
  margin: 14px 0 5px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ── сообщения ─────────────────────────────────────────── */

.msg {
  padding: 11px 14px;
  margin-bottom: 14px;
  border-left: 2px solid var(--line);
  background: var(--bg-1);
}
.msg.success { border-left-color: var(--cyan); color: var(--cyan-text); }
.msg.warning { border-left-color: var(--warn); color: var(--warn-text); }
.msg.error { border-left-color: var(--err); color: var(--pink-text); }

/* Сообщение, под которым свёрнуты однотипные строки (converter#1029). Своего вида у
   него нет и не нужно: это то же сообщение, просто с продолжением — треугольник
   раскрытия рисует браузер, и второй знак того же самого только спорил бы с ним.
   Отступ появляется раскрытым: свёрнутым он оставил бы пустое место под одной
   строкой. */
.msg--fold > summary { cursor: pointer; }
.msg--fold[open] > summary { margin-bottom: 8px; }
.msg__row + .msg__row { margin-top: 6px; }

/* ── код и длинные строки ──────────────────────────────── */

code {
  background: var(--bg-2);
  border: 1px solid var(--line);
  padding: 2px 6px;
  border-radius: 3px;
  font-family: var(--f-mono);
  font-size: 12.5px;
}

/* Ссылка подключения и команды длиннее любой разумной колонки: пусть прокручиваются
 * внутри своего блока, а не растягивают страницу. */
.code-block {
  display: block;
  padding: 10px 12px;
  overflow-x: auto;
  white-space: pre;
  word-break: normal;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  font-family: var(--f-mono);
  font-size: 12.5px;
  line-height: 1.5;
}

.copy-row { display: flex; gap: 8px; align-items: flex-start; }
.copy-row .code-block { flex: 1; min-width: 0; }

.qr { display: inline-block; padding: 12px; background: #fff; border-radius: 4px; }

/* ── график расхода ────────────────────────────────────── */

.chart { width: 100%; height: auto; display: block; }
.chart .bar-in { fill: var(--cyan); }
.chart .bar-out { fill: var(--purple); }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .tick { fill: var(--muted); font-size: 10px; font-family: var(--f-mono); }

.legend { display: flex; gap: 16px; align-items: center; color: var(--muted); font-size: 12px; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; }
.legend .in { background: var(--cyan); }
.legend .out { background: var(--purple); }

/* ── узкий экран ───────────────────────────────────────── */

@media (max-width: 720px) {
  .nav { gap: 14px; padding: 0 14px; overflow-x: auto; }
  .nav__link { font-size: 11px; letter-spacing: 0.08em; }
  main { padding: 18px 14px 48px; }
  .panel { padding: 18px 14px; }

  /* Таблица на телефоне нечитаема: разбираем её на карточки. Название колонки берётся
   * из data-label — тот же приём, что на лендинге в блоке цен. */
  .table-cards thead { display: none; }
  .table-cards tr {
    display: block;
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 10px 12px;
    margin-bottom: 12px;
  }
  .table-cards td {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    border: 0;
    padding: 5px 0;
  }
  .table-cards td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    flex: 0 0 auto;
  }
  .table-cards td[data-label=""]::before { content: none; }
  .copy-row { flex-direction: column; }
  .copy-row button { width: 100%; justify-content: center; }
}

/* --- админ-зона (converter#699) --------------------------------------------------
   Своих цветов не вводит: состояния и акценты берутся из тех же токенов, что в
   кабинете. Иначе «ошибка» в операторском экране и «ошибка» в карточке связки со
   временем разъехались бы по смыслу. */

.subnav {
  display: flex;
  /* Заметный зазор, а не 4px: у .nav__link горизонтальных отступов нет, и вплотную
     четыре ссылки читаются как одна строка «контурсвязкитарифыстатистика». */
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

/* Плитки сводки. auto-fit, а не фиксированные колонки: число плиток меняется, и на
   узком экране они обязаны переноситься сами, без своей медиа-точки. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}

.tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.tile__num { font-size: 26px; font-weight: 600; line-height: 1.1; }

/* Плитка «требуют разбора» подсвечивается только когда там не ноль: постоянно
   заметная рамка перестаёт что-либо значить через день работы. */
.tile--warn { border-color: var(--warn); }
.tile--warn .tile__num { color: var(--warn-text); }

.mb { margin-bottom: 6px; }

/* Фильтр состояния: без ограничения по ширине select растягивается на всю строку —
   .row это флекс-контейнер, и поле забирает всё свободное место. */
.filter { align-items: flex-end; }
.filter select { max-width: 260px; }

/* Флажки в формах админ-зоны. Тема задаёт input шириной во всю строку, и флажок от
   этого уезжает в середину поля — выглядит как сбитая вёрстка. */
.panel input[type="checkbox"] { width: auto; }

/* Галочка с подписью в одну строку. Тема задаёт label блочным и с отступом сверху,
   из-за чего флажок и его текст расходились на две строки. */
.check {
  display: flex;
  align-items: center;
  gap: 8px;
  text-transform: none;
  letter-spacing: normal;
}

/* Две сводки рядом. Не .row: там флекс с прижатием к краям, и две короткие таблицы
   расходятся по углам панели, между ними пустота во всю ширину. */
.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
}

/* Виджет капчи регистрации (ALTCHA, converter#2153). Его стили живут в теневом DOM,
 * снаружи достать можно только его переменные — ими и переводим его на нашу тему.
 * Токены ссылаются на наши, поэтому светлая тема подхватывается сама. */
altcha-widget {
  --altcha-color-base: var(--bg-1);
  --altcha-color-base-content: var(--text);
  --altcha-color-neutral: var(--muted);
  --altcha-color-primary: var(--cyan);
  --altcha-color-primary-content: var(--bg);
  --altcha-color-success: var(--ok);
  --altcha-color-error: var(--err);
  --altcha-border-color: var(--line);
  --altcha-max-width: 100%;
  display: block;
  margin-top: 12px;
}

/* Кнопка чата поддержки (converter#2149). Своя, пока SDK Chatwoot не загружен: после
 * загрузки её место занимает пузырь самого Chatwoot. */
.support-bubble {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 50;
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}
.support-bubble[hidden] { display: none; }
.support-bubble:disabled { opacity: 0.6; cursor: progress; }
