/* Версія в адресі шрифтів не потрібна: файли шрифтів не змінюються роками, а їхні
   імена містять вагу й підмножину. Змінимо шрифт — зміниться й ім'я файла. */
@import url('/static/fonts/fonts.css');

/* =============================================================================
   ПРИБОРНАЯ ПАНЕЛЬ, А НЕ ВИТРИНА

   Продукт меряет чужой контент относительно медианы. Значит главный элемент интерфейса —
   САМА ЛИНИЯ МЕДИАНЫ: одна сквозная черта, вдоль которой висят публикации. Всё, что выше,
   сработало лучше обычного; всё, что ниже, — хуже. Это не украшение поверх таблицы:
   базовая линия — единственное число, общее для всего на экране, и она нарисована один раз.

   ЦВЕТ. Лиловый по просьбе заказчика, но не «почти чёрный плюс один кислотный акцент»:
   фон подкрашен фиолетовым насквозь, лиловых регистра два (орхидея и бледная мальва),
   и ровно ОДИН тёплый цвет — шампань. Он появляется только над линией медианы, у того,
   что сработало. Один тёплый на весь холодный экран и делает победителей заметными
   без единой подписи.

   ШРИФТЫ. Unbounded для заголовков и главного числа — геометрический, с характером,
   с кириллицей; используется скупо. Golos Text для всего остального — он нарисован под
   русский текст и хорош в мелких размерах интерфейса. Цифры табличные: в приборе колонки
   обязаны выстраиваться.
   ============================================================================= */

:root {
  --ink:        #0B0714;
  --ink-2:      #120C22;
  --ink-3:      #1A1230;
  --line:       #2A1E48;
  --line-soft:  #1E1636;

  --orchid:     #A78BFA;
  --orchid-lo:  #6D28D9;
  --orchid-hi:  #C4B5FD;
  --mauve:      #DDD0F5;

  --signal:     #F2D9A0;   /* шампань — только выше медианы */
  --signal-dim: #8A7343;

  --text:       #EBE5F7;
  --muted:      #8B82A8;
  --muted-2:    #625A7E;

  --rail: 264px;
  --r: 14px;

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: 'Golos Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* Свечение за шапкой: единственный «атмосферный» приём на весь интерфейс.
   Не анимирован — прибор не должен мерцать. */
body::before {
  content: '';
  position: fixed;
  inset: -30% 0 auto 0;
  height: 60vh;
  background: radial-gradient(60% 55% at 30% 0%, rgba(124, 58, 237, .22), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

a { color: var(--orchid-hi); text-decoration: none; }
a:hover { color: var(--mauve); }

:focus-visible {
  outline: 2px solid var(--orchid);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ------------------------------------------------------------------ каркас */

.shell { display: flex; min-height: 100vh; position: relative; z-index: 1; }

.rail {
  width: var(--rail);
  flex: 0 0 var(--rail);
  padding: 26px 18px 22px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  /* Правый край — не линия, а градиент: тонкая обводка, которая гаснет книзу. */
  background:
    linear-gradient(180deg, rgba(167,139,250,.5), rgba(167,139,250,.06) 55%, transparent) right / 1px 100% no-repeat,
    linear-gradient(180deg, rgba(30,22,54,.85), rgba(11,7,20,.85));
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand { display: flex; flex-direction: column; gap: 3px; }
.brand__mark {
  font-family: 'Unbounded', sans-serif;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -.02em;
  background: linear-gradient(92deg, var(--mauve), var(--orchid) 40%, #8B5CF6);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.brand__sub { color: var(--muted-2); font-size: 11.5px; letter-spacing: .02em; }

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav__label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted-2);
  padding: 0 12px 8px;
}
.nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  color: var(--muted);
  font-weight: 500;
  border: 1px solid transparent;
  transition: background .16s, color .16s, border-color .16s;
}
.nav a:hover { background: rgba(167,139,250,.07); color: var(--text); }
.nav a[aria-current='page'] {
  color: var(--text);
  background: linear-gradient(94deg, rgba(109,40,217,.32), rgba(167,139,250,.08));
  border-color: rgba(167,139,250,.32);
}
.nav__count { font-size: 11.5px; color: var(--muted-2); }

.rail__foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }

.who { font-size: 12px; color: var(--muted); }
.who b { color: var(--text); font-weight: 600; }

.main { flex: 1; min-width: 0; padding: 28px 34px 70px; max-width: 1280px; }

/* ------------------------------------------------------------------ шапка */

.head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 20px;
  margin-bottom: 26px;
  border-bottom: 1px solid var(--line-soft);
}
.head h1 {
  font-family: 'Unbounded', sans-serif;
  font-weight: 600;
  font-size: 26px;
  letter-spacing: -.025em;
  margin: 0;
}
.eyebrow {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--orchid);
  margin-bottom: 7px;
}

/* Состояние доступов. Точка, а не текст: её видно боковым зрением, и она обязана
   быть на каждой странице — доступ умирает посреди прогона, и человек должен
   узнать об этом не из логов. */
.dostupy { display: flex; gap: 8px; flex-wrap: wrap; }
.dot {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px 6px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(18,12,34,.7);
  font-size: 12px;
  color: var(--muted);
}
.dot::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--muted-2);
  box-shadow: 0 0 0 3px rgba(139,130,168,.13);
}
.dot--ok::before    { background: #7DD3A0; box-shadow: 0 0 0 3px rgba(125,211,160,.16); }
.dot--dead::before  { background: #F2839B; box-shadow: 0 0 0 3px rgba(242,131,155,.16); }
.dot--error::before { background: var(--signal); box-shadow: 0 0 0 3px rgba(242,217,160,.16); }
.dot b { color: var(--muted); font-weight: 500; }
.head .dot { font-size: 11.5px; padding: 5px 10px 5px 8px; }

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

/* Обводка градиентом И со скруглением. Первая версия использовала border-image —
   он рисует градиент, но ГАСИТ border-radius, и панели выходили с острыми углами
   рядом со скруглёнными карточками. Два фона (padding-box под заливку, border-box
   под обводку) дают тот же градиент и радиус сохраняют. */
.panel {
  border: 1px solid transparent;
  border-radius: var(--r);
  background:
    linear-gradient(180deg, rgba(26,18,48,.75), rgba(18,12,34,.75)) padding-box,
    linear-gradient(150deg, rgba(167,139,250,.45), rgba(42,30,72,.55) 45%, rgba(167,139,250,.2)) border-box;
  padding: 20px 22px;
}
.panel--round {
  background: linear-gradient(180deg, rgba(26,18,48,.6), rgba(18,12,34,.6)) padding-box,
              linear-gradient(160deg, rgba(167,139,250,.26), rgba(42,30,72,.4)) border-box;
}

.grid { display: grid; gap: 14px; }
/* Колонки тягнуться (1fr), а не впираються в 320 px. З межею 320 три картки разом із
   відступами не влазили в ширину сторінки поруч із меню, третя переїжджала вниз, а праворуч
   лишалась порожнеча. auto-fit, а не auto-fill: зайвих порожніх колонок не створюється. */
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* ------------------------------------------------------------------ ГЛАВНОЕ: медиана и трасса */

.mediana {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.mediana__num {
  font-family: 'Unbounded', sans-serif;
  font-weight: 600;
  font-size: clamp(38px, 6vw, 62px);
  line-height: .95;
  letter-spacing: -.045em;
  background: linear-gradient(96deg, var(--mauve), var(--orchid) 55%, var(--orchid-lo));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.mediana__sub { color: var(--muted); font-size: 13px; max-width: 40ch; padding-bottom: 4px; }

/* Трасса: каждая публикация — штрих, положение по времени, высота по коэффициенту.
   Базовая линия одна на всю ширину — это и есть медиана, и она рисуется ПОВЕРХ штрихов.
   Первая версия прятала её под столбцами, и главный элемент интерфейса просто исчезал. */
.trassa { position: relative; height: 118px; margin: 26px 0 4px; }
.trassa__base {
  position: absolute; left: -22px; right: -22px; top: 66%; height: 1px; z-index: 2;
  background: linear-gradient(90deg, transparent, var(--orchid) 6%, var(--orchid-hi) 50%, var(--orchid) 94%, transparent);
  box-shadow: 0 0 12px rgba(196,181,253,.45);
}
.trassa__label {
  position: absolute; right: 22px; top: -21px;
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--orchid-hi);
}
.trassa__scale {
  position: absolute; left: 0; right: 0; bottom: -14px;
  display: flex; justify-content: space-between;
  font-size: 10.5px; color: var(--muted-2); letter-spacing: .04em;
}
.trassa__ticks { position: absolute; inset: 0; display: flex; gap: 2px; z-index: 1; }
/* Колонка тянется на всю ширину, а сам штрих внутри неё остаётся ТОНКИМ и стоит по центру.
   Ограничивать ширину самой колонки нельзя: на выборке из 18 публикаций трасса занимала
   левую половину панели, а на 59 — всю. Прибор должен выглядеть одинаково при любом
   числе замеров, меняться должна плотность, а не длина шкалы. */
.tick { flex: 1 1 0; position: relative; min-width: 2px; }
.tick i {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: min(100%, 22px); display: block; border-radius: 2px;
}
.tick--up i {
  bottom: 34%; transform-origin: bottom center;
  height: calc(var(--h) * 1%);
  background: linear-gradient(180deg, var(--signal), var(--signal-dim));
  box-shadow: 0 0 12px rgba(242,217,160,.25);
}
.tick--down i {
  top: 66%; transform-origin: top center;
  height: calc(var(--h) * 1%);
  background: linear-gradient(180deg, #3B2C63, #1E1636);
}
.tick:hover i, .tick:focus-visible i { filter: brightness(1.35); }
.tick__tip {
  position: absolute; bottom: calc(34% + 8px); left: 50%; transform: translateX(-50%);
  background: var(--ink-3); border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 9px; font-size: 11.5px; white-space: nowrap; color: var(--text);
  opacity: 0; pointer-events: none; transition: opacity .12s; z-index: 4;
}
.tick:hover .tick__tip, .tick:focus-within .tick__tip { opacity: 1; }

/* Одна оркестрованная последовательность на весь интерфейс: штрихи вырастают от
   базовой линии слева направо. Больше нигде ничего не анимируется. */
@media (prefers-reduced-motion: no-preference) {
  .tick i { animation: rost .5s cubic-bezier(.2,.8,.2,1) backwards; animation-delay: calc(var(--i) * 18ms); }
  /* В transform уже лежит центрирование по X — анимация обязана его повторить,
     иначе штрихи прыгнут вправо на половину своей ширины. */
  @keyframes rost {
    from { transform: translateX(-50%) scaleY(0); opacity: 0; }
    to   { transform: translateX(-50%) scaleY(1); opacity: 1; }
  }
}

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

.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th {
  text-align: left; font-weight: 500; font-size: 10.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--muted-2);
  padding: 0 12px 10px; border-bottom: 1px solid var(--line-soft);
}
.tbl td { padding: 11px 12px; border-bottom: 1px solid rgba(30,22,54,.55); vertical-align: top; }
.tbl tr:last-child td { border-bottom: 0; }
.tbl tbody tr { transition: background .12s; }
.tbl tbody tr:hover { background: rgba(167,139,250,.05); }
.num { text-align: right; white-space: nowrap; }
/* Заголовок числового стовпця — праворуч, над своїми числами. Одного `.num` мало:
   `.tbl th` вище за специфічністю (клас + тег проти класу) і тягнув усі заголовки ліворуч,
   тож «перегляди» стояли за сотню пікселів від цифр — на кожній таблиці дашборда. */
.tbl th.num { text-align: right; }
.code {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 12px; color: var(--mauve);
}
.dim { color: var(--muted); }
.tsmall { font-size: 12px; color: var(--muted); }

/* Подпись публикации — ровно одна строка. Перенос ломал ритм таблицы: строки с соавтором
   становились вдвое выше соседних, и колонка чисел переставала читаться сверху вниз.
   В приборе важнее ровный шаг строк, чем лишние двадцать символов текста. */
.tbl td.podpis {
  max-width: 420px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tbl td.podpis .tag { vertical-align: baseline; }

/* Коэффициент — единственное место, где цвет несёт смысл, а не настроение. */
.koef { font-weight: 600; }
.koef--up { color: var(--signal); }
.koef--down { color: var(--muted); }

.tag {
  display: inline-block; padding: 2px 8px; border-radius: 6px;
  border: 1px solid var(--line); font-size: 11px; color: var(--muted);
}
.tag--clips { border-color: rgba(167,139,250,.4); color: var(--orchid-hi); }

/* Пустой экран — приглашение к действию, а не грустная картинка. */
.pusto { padding: 34px 22px; text-align: center; color: var(--muted); }
.pusto b { display: block; color: var(--text); font-size: 15px; margin-bottom: 6px; font-weight: 600; }

.note {
  margin-top: 12px; padding: 11px 14px; border-radius: 10px;
  border: 1px solid rgba(242,217,160,.26); background: rgba(242,217,160,.05);
  color: var(--signal); font-size: 12.5px;
}

/* ------------------------------------------------------------------ вход */

.login-wrap {
  min-height: 100vh; display: grid; place-items: center; padding: 24px;
  position: relative; z-index: 1;
}
/* Свечение — по центру, за карточкой: общее body::before прижато к верху экрана
   и на странице входа оказывалось за кадром. */
.login-wrap::before {
  content: ''; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(900px, 92vw); height: 520px; pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(124,58,237,.28), transparent 72%);
}
/* Та самая линия медианы, только без данных: сквозная черта через весь экран,
   карточка стоит на ней. Ничего не измеряет — заявляет, чем занят продукт. */
.login-wrap::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--orchid) 22%, var(--orchid-hi) 50%, var(--orchid) 78%, transparent);
  box-shadow: 0 0 14px rgba(196,181,253,.35);
  pointer-events: none;
}
.login { width: 100%; max-width: 392px; position: relative; z-index: 2; padding: 30px 30px 28px; }
.login h1 {
  font-family: 'Unbounded', sans-serif; font-weight: 600; font-size: 23px;
  letter-spacing: -.03em; margin: 0 0 6px;
  background: linear-gradient(92deg, var(--mauve), var(--orchid) 45%, #8B5CF6);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.login p { color: var(--muted); margin: 0 0 22px; font-size: 13px; }
/* Сторінка дозволу для Claude — та сама картка входу: людина щойно ввела тут пароль, і
   інший вигляд наступного кроку читався б як «мене кудись перекинуло». */
.login .dozvil__hto { color: var(--text); }
.dozvil__mozhe { margin: -8px 0 20px; padding-left: 18px; display: grid; gap: 6px; font-size: 13px; }
.dozvil__mozhe li::marker { color: var(--orchid); }
.dozvil__knopky { display: grid; gap: 10px; }
label { display: block; font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 6px; }
input[type=text], input[type=password] {
  width: 100%; padding: 11px 13px; border-radius: 10px;
  background: var(--ink); border: 1px solid var(--line); color: var(--text);
  font: inherit; margin-bottom: 15px;
}
input:focus { border-color: var(--orchid); outline: none; box-shadow: 0 0 0 3px rgba(167,139,250,.16); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 11px 16px; border-radius: 10px; border: 0; cursor: pointer;
  font: inherit; font-weight: 600; color: #17102A;
  background: linear-gradient(96deg, var(--orchid-hi), var(--orchid) 60%, #8B5CF6);
  transition: filter .15s, transform .05s;
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); }
.btn--ghost {
  width: auto; background: none; color: var(--muted); border: 1px solid var(--line);
  font-weight: 500;
}
.btn--ghost:hover { color: var(--text); border-color: var(--orchid); filter: none; }

.oshibka {
  padding: 10px 13px; border-radius: 9px; margin-bottom: 15px; font-size: 13px;
  border: 1px solid rgba(242,131,155,.34); background: rgba(242,131,155,.07); color: #F2839B;
}

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

@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .rail { width: 100%; flex: none; height: auto; position: static;
          background: linear-gradient(180deg, rgba(30,22,54,.9), rgba(11,7,20,.9));
          border-bottom: 1px solid var(--line); }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .nav a { padding: 8px 12px; }
  .rail__foot { margin-top: 0; }
  .main { padding: 22px 18px 60px; }
  .head { flex-direction: column; align-items: flex-start; gap: 14px; }
}

/* ------------------------------------------------------------------ экран доступов */

/* Две колонки, потому что доступа ровно два и они равноправны. Список из двух пунктов,
   вытянутый в столбец на всю ширину, заставлял бы прокручивать экран ради второго. */
.dvi-kolonky { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }

.pidzagolovok {
  font-family: 'Unbounded', sans-serif; font-weight: 600; font-size: 17px;
  letter-spacing: -.02em; margin: 0 0 14px;
}

.stan-ryadok { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

textarea {
  width: 100%; padding: 13px 15px; border-radius: 12px;
  /* Куки — техническая строка. Моноширинный шрифт даёт увидеть, где кончается одно
     значение и начинается другое, и заметить лишний пробел. Пропорциональный
     превращает её в кашу. */
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  background: var(--ink); border: 1px solid var(--line); color: var(--text);
  font-size: 12px; line-height: 1.6; margin-bottom: 12px;
  resize: vertical; min-height: 108px;
  background: linear-gradient(180deg, rgba(11,7,20,.9), rgba(18,12,34,.9)) padding-box,
              linear-gradient(150deg, rgba(167,139,250,.3), rgba(42,30,72,.5)) border-box;
  border: 1px solid transparent;
  transition: box-shadow .18s, border-color .18s;
  /* Куки — длинная строка без пробелов. Без переноса поле превращается в горизонтальную
     прокрутку, и человек не видит, что именно вставил. */
  word-break: break-all;
}
textarea:focus {
  outline: none;
  background: linear-gradient(180deg, rgba(11,7,20,.95), rgba(18,12,34,.95)) padding-box,
              linear-gradient(150deg, var(--orchid), rgba(109,40,217,.7)) border-box;
  box-shadow: 0 0 0 3px rgba(167,139,250,.14), 0 0 34px -12px rgba(167,139,250,.5);
}
textarea::placeholder { color: var(--muted-2); }

.knopky { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.knopky form { margin: 0; }

/* Удаление доступа необратимо, поэтому кнопка выглядит иначе остальных.
   Одинаковые кнопки рядом — способ однажды нажать не ту. */
.btn--nebezpeka { border-color: rgba(242,131,155,.34); color: #F2839B; }
.btn--nebezpeka:hover { border-color: #F2839B; color: #F2839B; }

.poperedzhennya {
  margin-top: 18px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid rgba(242,217,160,.22); background: rgba(242,217,160,.045);
  color: var(--muted); font-size: 12.5px; line-height: 1.55;
}
.poperedzhennya b { color: var(--signal); font-weight: 600; }

/* Удачное сообщение — зелёная обводка, а не тот же жёлтый, что у предупреждения:
   иначе «сохранено» и «осторожно» выглядят одинаково. */
.note--ok {
  border-color: rgba(125,211,160,.3); background: rgba(125,211,160,.05); color: #9FE0BC;
}

/* Точки состояния в шапке — ссылки на этот экран: увидел красную, нажал, починил. */
.head .dot { text-decoration: none; transition: border-color .15s; }
.head .dot:hover { border-color: var(--orchid); }

/* Раскрывающийся блок для того, что нужно редко. Нативный <details> вместо своей
   реализации на JavaScript: он работает без скриптов, доступен с клавиатуры и его
   состояние понимает браузер. Своя реализация стоила бы кода и не добавила бы ничего. */
.rozgornuty { margin-top: 18px; }
.rozgornuty summary {
  cursor: pointer; color: var(--muted); font-size: 13px; padding: 8px 0;
  list-style: none; display: flex; align-items: center; gap: 8px;
}
.rozgornuty summary::-webkit-details-marker { display: none; }
.rozgornuty summary::before { content: '+'; color: var(--orchid); font-weight: 600; }
.rozgornuty[open] summary::before { content: '−'; }
.rozgornuty summary:hover { color: var(--text); }

/* ==================================================================== цілі збору */

.cili { margin-bottom: 16px; }
.cili__zagolovok {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 12px;
}
.dodaty { display: flex; gap: 8px; }
.dodaty input {
  margin: 0; width: 260px; padding: 8px 12px; font-size: 13px;
  background: var(--ink); border: 1px solid var(--line); border-radius: 9px; color: var(--text);
}
.dodaty input:focus { border-color: var(--orchid); outline: none; box-shadow: 0 0 0 3px rgba(167,139,250,.16); }

.cili__spysok { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
.cil {
  border: 1px solid transparent; border-radius: var(--r); padding: 14px 16px;
  background: linear-gradient(180deg, rgba(26,18,48,.6), rgba(18,12,34,.6)) padding-box,
              linear-gradient(160deg, rgba(167,139,250,.3), rgba(42,30,72,.45)) border-box;
  transition: transform .18s cubic-bezier(.2,.8,.2,1), box-shadow .18s;
}
.cil:hover { transform: translateY(-2px); box-shadow: 0 10px 26px -14px rgba(124,58,237,.6); }
/* Выключенная цель выглядит выключенной, а не «такой же, но где-то там галочка снята». */
.cil--vymknena { opacity: .5; }
.cil__imya { font-size: 15px; font-weight: 600; margin-bottom: 2px; }
.cil__fakty { font-size: 12px; color: var(--muted); }
/* Підписники — тією ж мовою кольору, що й віральність: шампань — «росте», як «вище
   медіани»; спад — приглушений, а не червоний: чужий акаунт, що втратив підписників, — не
   тривога для оператора, а факт. */
.cil__pidp { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; margin: 4px 0 2px; font-size: 12.5px; }
.cil__pidp-chyslo { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.zrist { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.zrist--up { color: var(--signal); }
.zrist--down { color: var(--muted-2); }
.iskra { width: 96px; height: 24px; align-self: center; margin-left: auto; overflow: visible; }
.iskra polyline { fill: none; stroke: var(--signal); stroke-width: 1.5; stroke-linejoin: round;
                  stroke-linecap: round; vector-effect: non-scaling-stroke; }
.iskra--down polyline { stroke: var(--muted-2); }
.cil__forma { margin-top: 10px; }
.cil__forma label { margin-bottom: 4px; }
.cil__forma select, .cil__forma input[type=number] {
  width: 100%; padding: 8px 10px; margin-bottom: 10px; font: inherit; font-size: 13px;
  background: var(--ink); border: 1px solid var(--line); border-radius: 9px; color: var(--text);
}
.cil__para { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.prapor { display: flex; align-items: center; gap: 8px; text-transform: none;
          letter-spacing: 0; font-size: 13px; color: var(--muted); margin-bottom: 12px; }
.prapor input { accent-color: var(--orchid); width: 15px; height: 15px; }
.cil__knopky { display: flex; gap: 8px; margin-top: 12px; }
.cil__knopky form { margin: 0; }
.cil--porozhnya { display: flex; flex-direction: column; gap: 4px; color: var(--muted); }
.cil--porozhnya b { color: var(--text); }

/* ==================================================================== фільтри */

.filtry {
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
  padding: 14px 16px; margin-bottom: 14px; border-radius: var(--r);
  border: 1px solid transparent;
  background: linear-gradient(180deg, rgba(26,18,48,.5), rgba(18,12,34,.5)) padding-box,
              linear-gradient(160deg, rgba(167,139,250,.22), rgba(42,30,72,.4)) border-box;
}
.filtr { display: flex; flex-direction: column; }
.filtr--rist { flex: 1 1 200px; }
.filtr label { margin-bottom: 5px; }
.filtr input, .filtr select {
  padding: 8px 11px; font: inherit; font-size: 13px; margin: 0;
  background: var(--ink); border: 1px solid var(--line); border-radius: 9px; color: var(--text);
  min-width: 130px;
}
.filtr input:focus, .filtr select:focus {
  border-color: var(--orchid); outline: none; box-shadow: 0 0 0 3px rgba(167,139,250,.16);
}
.btn--vuzka { width: auto; padding: 9px 16px; font-size: 13px; }

/* ==================================================================== мініатюри */

.mini-td { width: 56px; position: relative; padding-left: 12px; }
.mini {
  width: 44px; height: 44px; object-fit: cover; border-radius: 8px; display: block;
  border: 1px solid var(--line); background: var(--ink-3);
  transition: transform .18s cubic-bezier(.2,.8,.2,1), border-color .18s;
}
tr:hover .mini { transform: scale(1.06); border-color: var(--orchid); }
.mini--nemaye {
  display: grid; place-items: center; color: var(--muted-2); font-size: 12px;
}
/* Признак видео — на самой картинке, а не отдельной колонкой: колонка, где у всех
   строк одно и то же значение, не несёт информации (её мы уже убирали однажды). */
.mini__video {
  position: absolute; right: 4px; bottom: 8px; width: 15px; height: 15px;
  display: grid; place-items: center; border-radius: 4px; font-size: 9px;
  background: rgba(11,7,20,.82); color: var(--signal); border: 1px solid rgba(242,217,160,.35);
}

/* ЗНАКИ В МІНІАТЮРІ. Два стани, і вони НАВМИСНО різної гучності.
   «T» — тихий: розшифровка вже є, це довідка, і кричати їй нема про що.
   Пульс — гучний: робота ЙДЕ ПРЯМО ЗАРАЗ, і саме заради нього людина може закрити
   картку й піти далі. Якби обидва були однакові, список перестав би відповідати на
   питання «де воно зараз крутиться» — а це єдине питання, заради якого знак і потрібен. */
.znak {
  position: absolute; right: 4px; top: 4px; width: 15px; height: 15px;
  display: grid; place-items: center; border-radius: 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .02em;
}
.znak--tekst {
  background: rgba(11,7,20,.82); color: var(--mauve);
  border: 1px solid rgba(167,139,250,.32);
}
/* Відмова МАЄ ЗАЛИШИТИ СЛІД. Якби знак просто зникав, невдала розшифровка виглядала б
   так само, як та, якої не запускали, — тобто мовчазно невірна відповідь (пункт A.5
   інструкції). Причина — у підказці: знак каже «сталося», підказка каже «що саме». */
.znak--bida {
  background: rgba(11,7,20,.82); color: #F2839B;
  border: 1px solid rgba(242,131,155,.42);
}

/* Пульс — коло, а не квадрат: коло серед прямокутних знаків помітне периферійним зором,
   тобто його видно, поки очі йдуть по числах, а не по мініатюрах. */
.znak--ide {
  width: 13px; height: 13px; border-radius: 50%; border: 0;
  background: radial-gradient(circle at 35% 32%, var(--orchid-hi), var(--orchid-lo));
  box-shadow: 0 0 0 2px rgba(11,7,20,.9);
}
.znak--ide::after {
  content: ''; position: absolute; inset: -1px; border-radius: 50%;
  border: 1.5px solid var(--orchid);
  animation: pulsuye 1.9s cubic-bezier(.2,.7,.3,1) infinite;
}
@keyframes pulsuye {
  0%   { transform: scale(.72); opacity: .95; }
  70%  { transform: scale(2.1);  opacity: 0; }
  100% { transform: scale(2.1);  opacity: 0; }
}
/* Рядок у роботі підсвічений ледь-ледь: знака достатньо, щоб знайти, а підсвітка потрібна,
   щоб не втратити його при прокручуванні. Голосніше — і таблиця почне мигтіти цілком. */
tr.ryadok--ide { background: rgba(167,139,250,.055); }
tr.ryadok--ide .mini { border-color: var(--orchid); }

/* Рух — не єдиний носій змісту: при вимкненій анімації лишається саме коло, і воно
   так само відрізняється від квадратної «T». */
@media (prefers-reduced-motion: reduce) {
  .znak--ide::after { animation: none; opacity: .55; transform: scale(1.25); }
}

/* Смуга поступу збору під ціллю. Та сама смуга, що в розшифровці: однаковий знак для
   однакового змісту «робота йде, ось скільки». */
.zbir-postup { margin-top: 12px; display: grid; gap: 6px; }
.zbir-postup__pidpys {
  display: flex; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--muted);
}
.zbir-postup__chyslo { color: var(--signal); font-variant-numeric: tabular-nums; }
.zbir-postup--gotovo .zbir-postup__etap { color: var(--text); }
.zbir-postup--bida .postup__smuga i { background: #F2839B; }
.zbir-postup--bida .zbir-postup__etap { color: #F2839B; }
.zbir-bida { margin-top: 8px; font-size: 12px; color: #F2839B; }
.zbir-bez-cili:empty { display: none; }
.zbir-bez-cili { display: grid; gap: 10px; margin-bottom: 12px; }
.zbir-ryadok {
  padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line);
  background: rgba(167,139,250,.05);
}
.zbir-ryadok__cil { font-size: 13px; font-weight: 600; }

/* Вибір акаунтів у фільтрах. Згорнутий — такий самий на вигляд, як сусідні поля, щоб ряд
   фільтрів не ламався; розгорнутий — висить поверх списку, а не розсуває його. */
.filtr--vybir { position: relative; }
/* Розміри — як у сусідніх <select>: інакше ряд фільтрів мав би одне поле вищим за інші. */
.vybir summary {
  list-style: none; cursor: pointer; padding: 8px 28px 8px 11px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--ink);
  color: var(--text); font-size: 13px; line-height: 1.4; position: relative; white-space: nowrap;
}
.vybir summary::-webkit-details-marker { display: none; }
.vybir summary::after {
  content: '▾'; position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  color: var(--muted); font-size: 11px;
}
.vybir[open] summary { border-color: var(--orchid); }
.vybir__spysok {
  position: absolute; z-index: 20; top: calc(100% + 6px); left: 0; min-width: 220px;
  max-height: 320px; overflow: auto; padding: 8px; display: grid; gap: 2px;
  background: var(--ink-3); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 18px 40px rgba(0,0,0,.45);
}
/* Специфічність навмисно вища (.vybir .vybir__punkt): пункти — теж <label> і <input>
   усередині .filtr, і правила `.filtr label` / `.filtr input` зробили б їх великими
   літерами з відступом, а позначку — розтягнутою на всю ширину. */
.vybir .vybir__punkt {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px;
  cursor: pointer; font-size: 13px; color: var(--text); margin: 0;
  text-transform: none; letter-spacing: normal;
}
.vybir .vybir__punkt:hover { background: rgba(167,139,250,.08); }
.vybir .vybir__punkt input { width: auto; flex: 0 0 auto; margin: 0; padding: 0; accent-color: var(--orchid); }
.vybir__spysok .btn { margin-top: 6px; }

/* Сторінка «Групи»: підсумок пошуку — числа великим, щоб «знайдено 17 із 1 240 переглянутих»
   читалося з одного погляду, а не з рядка дрібного тексту. */
.poshuk-pidsumok { margin-top: 14px; }
.poshuk-pidsumok__shapka { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.poshuk-pidsumok__chysla { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 8px; color: var(--muted); font-size: 13px; }
.poshuk-pidsumok__chysla b { color: var(--text); font-size: 20px; margin-right: 4px; font-variant-numeric: tabular-nums; }
.poshuk-tekst { max-width: 560px; white-space: pre-wrap; overflow-wrap: anywhere; }

/* Журнал прогонів. Ширина колонок ЗАДАНА, і текст у них переноситься: раніше в останній
   колонці стояв сирий словник і помилка Chrome на тисячу символів без пробілів-розривів,
   і таблиця виходила за межі панелі. На вузькому екрані таблиця прокручується сама, а не
   сторінка. */
.zhurnal { margin-top: 14px; padding: 18px 10px 12px; }
.zhurnal__shapka {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 12px 12px;
}
.tbl--zhurnal { table-layout: fixed; }
.tbl--zhurnal th:first-child, .tbl--zhurnal td:first-child { padding-left: 12px; }
.tbl--zhurnal .zh-koly  { width: 96px; }
.tbl--zhurnal .zh-hto   { width: 96px; }
.tbl--zhurnal .zh-shcho { width: 230px; }
.tbl--zhurnal .zh-yak   { width: 118px; }
.tbl--zhurnal .zh-stan  { width: 92px; }
.tbl--zhurnal td { overflow-wrap: anywhere; }
.zh-platforma { color: var(--muted); margin-right: 4px; }
.zh-vidmova { color: #F2839B; font-weight: 600; }
.zh-povna { margin-top: 6px; }
.zh-povna summary { cursor: pointer; color: var(--orchid); width: max-content; }
.zh-povna pre {
  margin: 8px 0 0; max-height: 220px; overflow: auto; white-space: pre-wrap;
  font-size: 11.5px; line-height: 1.5; color: var(--muted);
  background: var(--ink); border: 1px solid var(--line-soft); border-radius: 8px; padding: 10px;
}
.stan-zagolovok { font-size: 16px; font-weight: 600; margin-bottom: 8px; }

/* Карусель елементів публікації. Кадр фіксованої висоти, щоб картка не стрибала від фото
   до відео; стрілки — поверх кадру по краях, лічильник — унизу. */
.galereya { position: relative; }
.galereya__kadr { min-height: 240px; display: grid; place-items: center; }
.galereya__chekayemo {
  width: 100%; min-height: 320px; display: grid; place-items: center;
  background-size: cover; background-position: center; position: relative;
}
.galereya__chekayemo::before {
  content: ''; position: absolute; inset: 0; background: rgba(11,7,20,.72);
  backdrop-filter: blur(6px); border-radius: inherit;
}
.galereya__chekayemo span { position: relative; color: var(--muted); font-size: 13px; }
.galereya__strilka {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line);
  background: rgba(11,7,20,.78); color: var(--text); font-size: 22px; line-height: 1;
  cursor: pointer; display: grid; place-items: center;
}
.galereya__strilka:hover { border-color: var(--orchid); color: var(--orchid-hi); }
.galereya__strilka--nazad { left: 10px; }
.galereya__strilka--vpered { right: 10px; }
.galereya__lichylnyk {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); z-index: 2;
  padding: 4px 10px; border-radius: 999px; background: rgba(11,7,20,.8);
  border: 1px solid var(--line); font-size: 12px; color: var(--mauve);
  font-variant-numeric: tabular-nums;
}
.kartka__media--nemaye .btn { margin-top: 10px; }
/* Позначка альбому на мініатюрі — число елементів, а не трикутник відео. */
.mini__albom { width: auto; min-width: 15px; padding: 0 4px; font-weight: 600; }

/* Розбір і сценарії в картці. Сценарій — текст, який людина читатиме цілим і,
   можливо, копіюватиме: тому переноси рядків збережено, а шрифт — той самий, що в тексті
   публікації, а не дрібний службовий. */
.rozbir { margin-top: 22px; display: grid; gap: 10px; }
.rozbir__polya {
  display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0;
  font-size: 13px;
}
.rozbir__polya dt { color: var(--muted); }
.rozbir__polya dd { margin: 0; color: var(--text); }
.scenariy {
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  background: rgba(167,139,250,.04);
}
.scenariy__shapka {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--muted-2); margin-bottom: 8px;
}
.scenariy__tekst { white-space: pre-wrap; line-height: 1.55; font-size: 14px; }

/* Кроки прив\'язки бота: порядок тут справжня послідовність — без «Start» перевірка
   нічого не знайде, — тому й нумерований список, а не просто три кнопки. */
.kroky { margin: 18px 0 8px; padding-left: 20px; display: grid; gap: 10px; color: var(--muted); }
.kroky li::marker { color: var(--orchid); font-weight: 600; }
.kroky code { color: var(--mauve); font-size: 12.5px; overflow-wrap: anywhere; user-select: all; }
.kroky .btn { margin-left: 6px; vertical-align: middle; }
/* Вхід токеном для Claude Code — згорнутий: команді він не потрібен, і без згортки
   людина бачила б два способи підключення й не знала, котрий її. */
.claude-code { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.claude-code summary { cursor: pointer; color: var(--muted); font-size: 13px; }
.claude-code summary:focus-visible { outline: 2px solid var(--orchid); outline-offset: 3px; border-radius: 4px; }

/* Новий токен — єдине місце на сторінці, яке має кричати: його покажуть лише раз. */
.token-novyy {
  margin-top: 16px; padding: 14px; border-radius: 12px;
  border: 1px solid var(--orchid); background: rgba(167,139,250,.07);
  display: grid; gap: 8px;
}
.token-novyy__ryadok { display: flex; gap: 10px; align-items: flex-start; }
.token-novyy code {
  flex: 1; min-width: 0; font-size: 12px; line-height: 1.5; color: var(--mauve);
  word-break: break-all; user-select: all;
}
.tokeny { margin-top: 16px; display: grid; gap: 8px; }
.tokeny__ryadok {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  padding: 8px 0; border-top: 1px solid var(--line-soft);
}
.tokeny__ryadok code { color: var(--mauve); font-size: 12px; }
.tokeny__ryadok form { margin-left: auto; }

/* Рядок розкладу під ціллю. Дрібно й тихо: це довідка, а не заклик до дії. Кольором
   виділено лише невдачу — «зібрано» не потребує уваги, «не вдався» потребує. */
.cil__rozklad {
  display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px;
  font-size: 12px; color: var(--muted-2);
}
.cil__ok { color: var(--muted); }
.cil__bida { color: #F2839B; }

.tbl--klikabelna tbody tr { cursor: pointer; }
.tbl--klikabelna tbody tr:focus-visible {
  outline: 2px solid var(--orchid); outline-offset: -2px; background: rgba(167,139,250,.07);
}
.spysok__pidsumok { padding: 12px 12px 0; }

/* ==================================================================== картка */

.kartka { position: fixed; inset: 0; z-index: 50; }
.kartka__tlo {
  position: absolute; inset: 0; background: rgba(6,3,12,.72);
  backdrop-filter: blur(3px);
  opacity: 0; transition: opacity .2s ease;
}
.kartka__vikno {
  position: absolute; inset: 4vh 50% auto auto; transform: translateX(50%) translateY(14px) scale(.98);
  right: 50%; width: min(980px, 94vw); max-height: 92vh; overflow: auto;
  border: 1px solid transparent; border-radius: 18px; padding: 24px 26px;
  background: linear-gradient(180deg, rgba(26,18,48,.98), rgba(15,10,28,.98)) padding-box,
              linear-gradient(150deg, rgba(167,139,250,.55), rgba(42,30,72,.6) 45%, rgba(167,139,250,.28)) border-box;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.85);
  opacity: 0; transition: opacity .22s ease, transform .22s cubic-bezier(.2,.8,.2,1);
}
.kartka--vidkryta .kartka__tlo { opacity: 1; }
.kartka--vidkryta .kartka__vikno { opacity: 1; transform: translateX(50%) translateY(0) scale(1); }

.kartka__hrestyk {
  position: absolute; top: 14px; right: 16px; width: 32px; height: 32px;
  border-radius: 9px; border: 1px solid var(--line); background: rgba(11,7,20,.6);
  color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer;
  transition: color .15s, border-color .15s;
}
.kartka__hrestyk:hover { color: var(--text); border-color: var(--orchid); }

.kartka__chekayemo, .kartka__pomylka { padding: 40px; text-align: center; color: var(--muted); }
.kartka__pomylka { color: #F2839B; }

.kartka__shapka {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  padding-bottom: 16px; margin-bottom: 18px; border-bottom: 1px solid var(--line-soft);
  padding-right: 40px;
}
.kartka__shapka h2 {
  font-family: 'Unbounded', sans-serif; font-weight: 600; font-size: 19px;
  letter-spacing: -.02em; margin: 0;
}
.kartka__tilo { display: grid; grid-template-columns: 300px 1fr; gap: 24px; }
.kartka__livoruch { position: relative; }
.kartka__media {
  width: 100%; border-radius: 12px; border: 1px solid var(--line); display: block;
}
.kartka__media--nemaye {
  aspect-ratio: 4/5; display: grid; place-items: center; color: var(--muted-2);
  font-size: 12.5px; background: var(--ink);
}
.kartka__mitka {
  position: absolute; left: 10px; bottom: 10px; padding: 4px 9px; border-radius: 7px;
  background: rgba(11,7,20,.85); border: 1px solid rgba(242,217,160,.35);
  color: var(--signal); font-size: 11.5px;
}
.kartka__fakty {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 1px;
  background: var(--line-soft); border: 1px solid var(--line-soft);
  border-radius: 10px; overflow: hidden; margin-bottom: 16px;
}
.kartka__fakt { background: var(--ink-2); padding: 10px 12px; }
.kartka__fakt span { display: block; font-size: 10.5px; letter-spacing: .1em;
                     text-transform: uppercase; color: var(--muted-2); margin-bottom: 3px; }
.kartka__fakt b { font-size: 16px; font-weight: 600; }
.kartka__fakt--vyshche b { color: var(--signal); }
.kartka__tekst {
  white-space: pre-wrap; line-height: 1.6; max-height: 260px; overflow: auto;
  padding: 14px 16px; border-radius: 10px; background: var(--ink);
  border: 1px solid var(--line-soft); font-size: 13.5px;
}
.kartka__tekst--nemaye { color: var(--muted); font-style: italic; }
.kartka__zamiry { margin-top: 16px; }
.zamir { display: flex; justify-content: space-between; padding: 6px 0;
         border-bottom: 1px solid rgba(30,22,54,.5); font-size: 12.5px; color: var(--muted); }
.zamir b { color: var(--text); font-weight: 500; }
.kartka__diyi { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.kartka__diyi .btn[disabled] { opacity: .45; cursor: not-allowed; filter: none; }
.kartka__poyasnennya { margin-top: 10px; font-size: 12px; color: var(--muted-2); line-height: 1.5; }

/* ==================================================================== рух */

/* Появление блоков и строк — ОДНА последовательность на загрузку страницы, а не
   отдельная анимация у каждого элемента. Разрозненные эффекты дают ощущение
   суетливости; здесь всё едет в одну сторону с общим шагом.
   Уважение к prefers-reduced-motion обязательно: для части людей движение —
   не украшение, а помеха. */
@media (prefers-reduced-motion: no-preference) {
  .zyavlyayetsya { animation: vyplyv .42s cubic-bezier(.2,.8,.2,1) backwards; }
  .panel.zyavlyayetsya:nth-of-type(2) { animation-delay: .05s; }
  .spysok.zyavlyayetsya { animation-delay: .1s; }
  @keyframes vyplyv { from { opacity: 0; transform: translateY(10px); } }

  .tbl--klikabelna tbody tr {
    animation: ryadok-vyplyv .34s cubic-bezier(.2,.8,.2,1) backwards;
    animation-delay: calc(min(var(--r), 24) * 14ms + .12s);
  }
  @keyframes ryadok-vyplyv { from { opacity: 0; transform: translateY(6px); } }

  .cil { animation: vyplyv .4s cubic-bezier(.2,.8,.2,1) backwards; }
}
@media (prefers-reduced-motion: reduce) {
  .kartka__tlo, .kartka__vikno { transition: none; }
}

@media (max-width: 980px) {
  .kartka__tilo { grid-template-columns: 1fr; }
  .kartka__vikno { inset: 2vh 50% auto auto; padding: 20px 18px; }
}

/* Вимкнена кнопка має ВИГЛЯДАТИ вимкненою. Зменшеної прозорості мало: градієнт
   лишався яскравим, і кнопка читалася як робоча. Людина тисне, нічого не стається —
   і вирішує, що зламано, хоча служба просто ще не піднята. */
.btn[disabled], .btn[disabled]:hover {
  background: rgba(30,22,54,.7); color: var(--muted-2);
  border: 1px solid var(--line); opacity: 1; filter: none; cursor: not-allowed;
}
.btn--ghost[disabled] { background: none; }

/* ============================================ виправлення після візуальної перевірки */

/* 1. ПІДКАЗКИ ТРАСИ ВИЛАЗИЛИ ЗА КРАЙ ЕКРАНА. Они позиционированы от центра штриха,
      и у крайних штрихов уходили за границу окна — появлялась горизонтальная прокрутка
      всей страницы. Прижимаем крайние подсказки к своему краю. */
.tick:nth-last-child(-n+6) .tick__tip { left: auto; right: 0; transform: none; }
.tick:nth-child(-n+6) .tick__tip { left: 0; right: auto; transform: none; }
.tick__tip { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }

/* 2. ТАБЛИЦЯ ШИРША ЗА ЕКРАН НА СЕРЕДНІХ ШИРИНАХ. Таблица с восемью колонками не
      сжимается бесконечно. Пусть прокручивается ВНУТРИ своей панели, а не тянет
      за собой всю страницу: горизонтальная прокрутка страницы ломает и меню, и шапку. */
.spysok { overflow-x: auto; }
.spysok .tbl { min-width: 780px; }

/* 3. КНОПКА ЗА ЗАМОВЧУВАННЯМ БУЛА НА ВСЮ ШИРИНУ. Из-за `width: 100%` две кнопки
      рядом раздувались и переносились одна под другую — ровно то, что заказчик увидел
      на своём экране. Ширина по содержимому это норма для кнопки; во всю ширину —
      особый случай (вход, «зберегти куки»), и он теперь называется явно. */
.btn { width: auto; }
.btn--shyroka { width: 100%; }

/* 4. ФІЛЬТРИ МАЮТЬ ЛИШАТИСЯ В РЯД ДОВШЕ. Поля были с жёстким `min-width: 130px` и на
      1100 пикселях переносились. Даём им сжиматься до разумного предела — тогда ряд
      держится до узких экранов, а на телефоне перенос уместен и ожидаем. */
.filtry { gap: 10px 12px; }
.filtr input, .filtr select { min-width: 0; width: 100%; }
/* Основа 112 px: з нею пошук, дві дати, акаунти, тип і порядок разом із кнопкою стають
   в один ряд уже на 1280 px поруч із меню. На 122 px одне поле переїжджало на другий
   рядок і розтягувалось на всю ширину — ряд виглядав зламаним. */
.filtr { flex: 1 1 112px; min-width: 0; }
.filtr--rist { flex: 2 1 180px; }
.filtry .btn { flex: 0 0 auto; }

/* 5. ТРАСА ТЯГЛА СТОРІНКУ ВБІК — і лише за певної кількості точок. Кожен штрих мав
      мінімум 2 px і 2 px проміжку, тож 100 точок вимагали 398 px — більше, ніж є на
      телефоні. Проявилось 11.09.2026, коли в Telegram змінився набір постів: на 430 px
      сторінка поїхала вбік на 9 px, на 1100 — на 1 px через підказку сьомого з краю штриха.
      Лікування двоє, бо причин двоє:
      * на вузькому екрані штрих і проміжок — по 1 px: 120 точок (стеля вибірки) — 239 px;
      * смуга штрихів обрізає горизонтальний вихід за свій край (`clip`, а не `hidden`:
        лише `clip` дозволяє лишити вертикаль відкритою, і підказки над штрихами не
        обрізаються згори). Лінія медіани — не всередині смуги, тож її вихід за край, що
        зроблений навмисно, лишається. */
.trassa__ticks { overflow-x: clip; overflow-y: visible; }
@media (max-width: 640px) {
  .trassa__ticks { gap: 1px; }
  .tick { min-width: 1px; }
}

/* Підказки траси на вузькому екрані вимикаємо зовсім: наведення там немає в принципі
   (палець не наводять, а торкаються), а місця під підказку шириною 240 px просто нема. */
@media (max-width: 900px) {
  .tick__tip { display: none; }
}

/* Повне медіа в картці. Відео і фото діляться однією рамкою — тоді картка не стрибає
   від публікації до публікації. */
.kartka__media { max-height: 68vh; object-fit: contain; background: var(--ink); }
video.kartka__media { width: 100%; }
.kartka__nota, .kartka__media--nemaye span {
  display: block; margin-top: 8px; font-size: 11.5px; color: var(--muted-2); line-height: 1.45;
}

.btn--dovantazh { margin-top: 10px; }

/* ==================================================================== розшифровка */

.rozshyfrovka { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.rozshyfrovka__forma { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
.rozshyfrovka__forma select {
  padding: 8px 10px; font: inherit; font-size: 13px; margin: 0;
  background: var(--ink); border: 1px solid var(--line); border-radius: 9px; color: var(--text);
}
/* Хук — перше, що читають у розшифровці, тому він виділений, а не схований у тексті. */
.hook {
  margin: 10px 0 12px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid rgba(242,217,160,.3); background: rgba(242,217,160,.05);
  color: var(--signal); font-size: 14px; line-height: 1.5;
}
.hook span {
  display: block; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--signal-dim); margin-bottom: 5px;
}
.kartka__pomylka--ryadok { padding: 10px 0 0; text-align: left; font-size: 12.5px; }
.tr--vidkryta { background: rgba(167,139,250,.08) !important; }

/* Скільки збирати — видиме поле біля кнопки, а не сховане в налаштуваннях.
   Ховати число, яке оператор змінює щоразу, означає змушувати його щоразу шукати. */
.zbir { display: flex; gap: 8px; align-items: flex-end; margin-top: 12px; flex-wrap: wrap; }
.zbir__pole { display: flex; flex-direction: column; }
.zbir__pole label { margin-bottom: 4px; font-size: 10px; }
.zbir input {
  width: 78px; padding: 8px 10px; margin: 0; font: inherit; font-size: 13px;
  background: var(--ink); border: 1px solid var(--line); border-radius: 9px; color: var(--text);
}
.zbir input:focus { border-color: var(--orchid); outline: none; box-shadow: 0 0 0 3px rgba(167,139,250,.16); }

/* Форма додавання цілі з полями кількості не вміщалася на вузькому екрані і тягла
   сторінку вбік на 114 px. Даємо їй переноситися й стискатися: на телефоні три поля
   в один рядок фізично не поміщаються, і перенесення тут правильніше за прокрутку. */
.dodaty { flex-wrap: wrap; max-width: 100%; }
.dodaty input[type=text] { flex: 1 1 200px; width: auto; min-width: 0; }
.dodaty input[type=number] { flex: 0 1 86px; min-width: 0; }
@media (max-width: 640px) {
  .cili__zagolovok { flex-direction: column; align-items: stretch; }
  .dodaty { width: 100%; }
  .dodaty .btn { flex: 1 1 100%; }
}

/* Смуга поступу розшифровки. Показує ЧЕСНИЙ відсоток: кінець розшифрованого сегмента
   поділений на тривалість ролика, а не вигадану анімацію «щось відбувається».
   Нерухома кнопка на хвилину виглядає як зависання — і люди перезавантажують сторінку,
   втрачаючи роботу. */
/* Браузерне `[hidden] { display: none }` живе в таблиці САМОГО браузера, а це
   найслабша специфічність з усіх. Будь-яке наше правило з `display` її перебиває —
   і вузол, якому ми поставили `hidden`, лишається на екрані. Так смуга поступу
   висіла в кожній картці, показуючи «0%» там, де не йшло жодної роботи: не прикраса,
   а неправда на екрані. Правило нижче повертає `hidden` його зміст.
   ЦІНА: `!important`, тобто вузол з `hidden` не сховати назад інакше як знявши
   атрибут. Це і є потрібна поведінка: `hidden` — не підказка, а стан. */
[hidden] { display: none !important; }

.postup { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.postup__smuga {
  flex: 1; height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--ink); border: 1px solid var(--line);
}
.postup__smuga i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--orchid), var(--signal));
  transition: width .45s cubic-bezier(.2,.8,.2,1);
}
.postup__chyslo {
  font-size: 12px; color: var(--signal); min-width: 40px; text-align: right;
  font-variant-numeric: tabular-nums;
}
