/* ============================================================
   AIVORIA CRM — токены и базовые классы (тема Graphite, v2)
   Один файл, без зависимостей. Подключать до собственных стилей.
   Правило: в разметке не должно быть ни одного хекса — только var(--…).
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&display=swap');

:root {
  /* --- Шрифты. Обе гарнитуры содержат кириллицу.
         Barlow / Barlow Condensed НЕ использовать: без кириллицы,
         русский текст подменяется системным шрифтом. --- */
  --font-heading: 'Oswald', sans-serif;          /* заголовки, надзаголовки, крупные числа */
  --font-body: 'IBM Plex Sans', system-ui, sans-serif;

  /* --- Плоскости. Три уровня, ни одного чёрного. --- */
  --bg: #191c20;          /* фон страницы (графит) */
  --panel: #2d3239;       /* тело блока, на тон светлее фона: блок читается как блок */
  --chrome: #22262b;      /* шапка страницы, шапки блоков, полосы кабинетов — между фоном и телом */

  /* --- Линии. Только волосяные, 1px. --- */
  --line: #565e68;        /* внешняя рамка блока, разделитель секций */
  --line-soft: #474e57;   /* строка таблицы, внутренняя сетка */
  --line-strong: #6f7883; /* рамка кнопки, рамка всплывающего меню */

  /* --- Текст. --- */
  --text: #e6e4e0;        /* основной */
  --text-2: #c3c7cd;      /* вторичные числа */
  --text-3: #a5abb3;      /* подписи, надзаголовки, мета */
  --text-4: #868c94;      /* «делать нечего», прочерк */

  /* --- Акцент и сигналы. Единственные цвета в интерфейсе. --- */
  --accent: #6f97bf;      /* действие: залитая кнопка, активный раздел */
  --link: #8fb4d8;
  --link-hover: #b3cfe9;
  --brand: #c9a063;       /* логотип */

  --ok: #86b08a;          /* положительный профит; состояние «крутит» */
  --ok-dim: #6f8d72;      /* код валюты рядом с положительным числом */
  --run: #7fd08a;         /* «крутит»: деньги идут прямо сейчас — самый яркий */
  --live: #5f9a6b;        /* «активна»: включена, но денег ещё нет — глухой зелёный */
  --wait: #7d8f86;        /* ожидание: модерация, старт по расписанию */
  --bad: #d0776c;         /* убыток, ошибка сбора */
  --warn: #ceaa63;        /* нет данных, нужна авторизация, нет связки */

  /* --- Метрика. --- */
  /* Потолок ширины подстраивается под экран. Фикс в пикселях (в спеке 1180)
     на мониторе 2950px оставлял половину экрана пустой. Нижняя граница — всё
     окно до 1600px: при прежних 1240px ноутбук 1366 терял на полях по бокам
     почти 10rem, и их недоставало колонке имени. От ~1780px — как было, 90vw. */
  --page: clamp(min(100vw, 1600px), 90vw, 2000px);
  --gutter: 2.1333rem;         /* боковой отступ страницы */
  --block-gap: 1.7333rem;      /* вертикальный зазор между блоками */
  --cell-x: 1.3333rem;         /* горизонтальный отступ ячейки таблицы */
  --cell-y: 0.8rem;         /* вертикальный отступ ячейки таблицы */
  --edge: 3px;            /* толщина сигнальной кромки строки */
  --radius: 0;            /* скруглений в системе нет */
  --shadow-pop: 0 18px 40px rgba(0, 0, 0, .45); /* только всплывающее меню */
  --shade: rgba(0, 0, 0, .45);  /* затемнение раздела «в разработке» (.wip-shade) */

  /* Цвета тегов креативов: тег получает цвет по своему номеру (pages.TAG_COLORS).
     Приглушённые, без цветов состояния — красный и песочный заняты сигналами. */
  --tag-1: #7fa7d6;
  --tag-2: #b48ead;
  --tag-3: #d8a657;
  --tag-4: #7fbf9e;
  --tag-5: #d78a8a;
  --tag-6: #8fb8c9;
  --tag-7: #c7b56f;
  --tag-8: #a58cd6;
}

/* ---------- Светлая тема ----------
   Включается атрибутом data-theme=light на <html>: его ставит скрипт в начале
   страницы по выбору из localStorage (ui.page), переключает кнопка в шапке
   (ui.KEEP_SCROLL, aivoriaTheme). Меняются только токены: та же разметка,
   те же правила. Сигнальные цвета темнее, чтобы держать контраст на белом. */
html[data-theme=light] {
  color-scheme: light;
  --bg: #e9ebee;
  --panel: #ffffff;
  --chrome: #f2f3f5;
  --line: #c6ccd3;
  --line-soft: #dbe0e5;
  --line-strong: #a7afb8;
  --text: #1c2025;
  --text-2: #3a4149;
  --text-3: #5b636c;
  --text-4: #828a93;
  --accent: #3b6ea6;
  --link: #2d63a4;
  --link-hover: #1d4c86;
  --brand: #8a6520;
  --ok: #2e8a4c;
  --ok-dim: #4f9466;
  --run: #1e8c46;         /* «крутит»: на белом ярче — насыщеннее, а не светлее */
  --live: #5b8a66;
  --wait: #6f7f78;
  --bad: #c2443a;
  --warn: #b07d10;
  --shadow-pop: 0 18px 40px rgba(0, 0, 0, .18);
  --shade: rgba(0, 0, 0, .28);
  --tag-1: #3f6fa8;
  --tag-2: #8a5c86;
  --tag-3: #a9782b;
  --tag-4: #3e8a63;
  --tag-5: #b05a5a;
  --tag-6: #4d8ba1;
  --tag-7: #8e7d2c;
  --tag-8: #7a5fb0;
}

* { box-sizing: border-box; }

html {
  /* Корень всей сетки размеров. Всё остальное задано в rem, поэтому
     интерфейс масштабируется целиком, а длина строки в символах не меняется.
     Кривая подобрана по замеру живого окна: на 1920 даёт 16,3px — ровно то,
     что владелец получал ручным зумом 90%, и что он назвал идеалом. Попытка
     поднять на пиксель откачена: крупнее владельцу не понравилось.
     Ширина контента при этом не меняется, мельче становится только текст,
     поэтому в таблицу влезает больше строк. */
  font-size: clamp(14.5px, 0.28vw + 10.9px, 18.5px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
}

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }

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

.page { max-width: var(--page); margin: 0 auto; padding: 0 var(--gutter); width: 100%; }

.topbar { background: var(--chrome); border-bottom: 1px solid var(--line); position: relative; z-index: 20; }
.topbar .page { display: flex; align-items: stretch; justify-content: space-between; }
.brand {
  display: flex; align-items: center; padding-right: 2rem; border-right: 1px solid var(--line);
  font-family: var(--font-heading); font-weight: 600; font-size: 1.2667rem;
  letter-spacing: .22em; color: var(--brand);
}
.tab {
  display: flex; align-items: center; padding: 1rem 1.4667rem; border-right: 1px solid var(--line);
  font-family: var(--font-heading); font-size: 1rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-3);
}
.tab:hover { color: var(--text); }
.tab[aria-current] { background: var(--bg); color: var(--text); box-shadow: inset 0 -2px 0 var(--accent); }

.h1 {
  font-family: var(--font-heading); font-weight: 500; font-size: 2.1333rem;
  letter-spacing: .05em; text-transform: uppercase; margin: 0;
}
.kicker {
  font-family: var(--font-heading); font-size: 0.8333rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-3);
}

/* ---------- Блок ---------- */

.block { border: 1px solid var(--line); background: var(--panel); margin-top: var(--block-gap); }
.block-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0.8667rem var(--cell-x); border-bottom: 1px solid var(--line); background: var(--chrome);
}
.block-title {
  font-family: var(--font-heading); font-size: 1rem;
  letter-spacing: .14em; text-transform: uppercase;
}
.block-note { font-size: 0.8667rem; color: var(--text-3); }
/* Фильтры в полочке заголовка: справа, в одну строку с названием блока. */
.block-action { margin-left: auto; align-self: center; display: flex; align-items: center;
  gap: 0.8rem; flex-wrap: wrap; font-size: 0.8667rem; color: var(--text-3); }
.block-action .field { padding: 0.2rem 0.4667rem; font-size: 0.8667rem; }
.block-foot { padding: var(--cell-y) var(--cell-x); border-top: 1px solid var(--line); background: var(--chrome); }

/* Таблица в два столбца внутри блока: ширина блока та же, строк по высоте
   вдвое меньше. Так стоит список баеров — их больше десятка. На узком экране
   столбцы встают друг под друга. */
/* Плашка состояния: в таблице кампаний статус ищут глазами, поэтому он не
   слово в серой строке, а метка цветом строки. Не больше двух строк в ширину
   ячейки: не влезла — многоточие, целиком — в подсказке (title). Слово без
   пробелов переносится: сырой код статуса вылезал на соседние колонки (27.09).
   Одна строка резала и короткое «кампания остановлена» — 602 плашки из 1076. */
.pill { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  width: fit-content; max-width: 100%; overflow: hidden; overflow-wrap: anywhere;
  padding: 0.05rem 0.5rem;
  font-size: 0.8rem; line-height: 1.25; text-align: left;
  border: 1px solid currentColor; border-radius: var(--radius);
  background: color-mix(in srgb, currentColor 14%, transparent); }
/* Имя кампании и подпись под ним — в одну строку: длинное режется многоточием,
   целиком видно в подсказке. */
.line-name { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }

/* Строка кампании: превью квадратом слева от имени. Квадрат в 2,67rem был
   мелким — лица в кадре не разобрать; отступ слева отдан ему же, чтобы кадр
   стоял ближе к краю таблицы. Высота строки растёт до размера квадрата, имя и
   подпись становятся по центру. */
.camp .sub-name { grid-template-columns: 4.2rem minmax(0, 1fr); padding-left: 0.4rem;
  column-gap: 0.6rem; }
.camp .sub-name > .thumb-link { grid-row: 1 / span 2; height: 4.2rem; align-self: center; }
/* Высоту строки на «Сегодня» задаёт превью, а не текст, поэтому вертикальные
   поля ячейки лишние: с ними строка вырастала до семи рем и таблица
   расползалась. В «Заливах» (table-tree) поля свои. */
.table:not(.table-tree) tbody.camp > tr > td { padding-top: 0.2rem; padding-bottom: 0.2rem; }

.split2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px; background: var(--line); }
/* Половины — на фоне панели, зазор между ними остаётся цветом линии: так
   видно, что это два столбца, а не одна таблица с повторёнными колонками. */
.split2 > * { background: var(--panel); }
@media (max-width: 1100px) { .split2 { grid-template-columns: minmax(0, 1fr); } }

/* Полоса итогов: 4 равные ячейки, разделённые линиями. */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid var(--line); background: var(--panel); }
.stats-3 { grid-template-columns: repeat(3, 1fr); }
.stats-5 { grid-template-columns: repeat(5, 1fr); }
.stats > * { padding: 1.2rem var(--cell-x) 1.3333rem; display: flex; flex-direction: column; gap: 0.8rem; }
.stats > * + * { border-left: 1px solid var(--line); }
/* Две полосы подряд — одна панель: вторая без верхней рамки. Компактная —
   вспомогательные цифры: мельче и плотнее. */
.stats + .stats { border-top: 0; }
/* Компактная ячейка — сетка: подпись слева, справа число с метрикой в одну
   строку и, если есть, мелкие строки под ними. Вдвое ниже обычной. */
.stats-compact > * { display: grid; grid-template-columns: auto 1fr; align-items: baseline;
  gap: 0.1rem 0.8rem; padding: 0.55rem var(--cell-x) 0.6rem; }
.stats-compact .kicker { font-size: 0.72rem; align-self: baseline; }
.stats-compact .crow, .stats-compact .cline { grid-column: 2; }
.stats-compact .crow { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap;
  font-variant-numeric: tabular-nums; }
.stats-compact .cv { font-family: var(--font-heading); font-weight: 500; font-size: 1.1333rem;
  line-height: 1.2; }
.stats-compact .cline { display: block; font-size: 0.8rem; color: var(--text-2); line-height: 1.35;
  font-variant-numeric: tabular-nums; }
.stats-compact .cline b { font-family: var(--font-heading); font-weight: 500; color: var(--text);
  margin-right: 0.4rem; }
.figure-lg { font-family: var(--font-heading); font-weight: 500; font-size: 2.2667rem; line-height: 1.06; font-variant-numeric: tabular-nums; }
.figure-md { font-family: var(--font-heading); font-weight: 500; font-size: 1.6rem; line-height: 1.06; font-variant-numeric: tabular-nums; }

/* Страница креатива: плеер и картинка не шире колонки телефона; превью в
   списках — ссылка на страницу креатива. */
.thumb-link { display: inline-block; line-height: 0; }
.player { display: block; width: 100%; max-width: 22rem; background: var(--chrome);
  border: 1px solid var(--line); }
.player-empty { padding: 2rem; text-align: center; line-height: 1.4; }

/* Кнопка «+» у аккаунта: раскрывает форму привязки кабинета. Значок квадратный
   как и всё в теме (--radius=0), без штатного маркера details. */
.addcab { display: inline-block; }
.addcab > summary { list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center; width: 1.8rem; height: 1.8rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  color: var(--text-2); font-size: 1.1rem; line-height: 1; }
.addcab > summary::-webkit-details-marker { display: none; }
.addcab[open] > summary { border-color: var(--accent); color: var(--accent); }

/* Столбец «Тег»: чип — назначенный тег, клик по ячейке открывает меню со
   всеми тегами команды: назначенный отмечен и снимается крестиком, остальные
   назначаются кликом, внизу — новый. Меню фиксировано на экране, чтобы
   прокрутка таблицы его не обрезала. */
.tag { display: inline-flex; align-items: center; padding: 0.1rem 0.45rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-size: 0.8rem; line-height: 1.2; color: var(--text-2); white-space: nowrap; }
/* Квадратная рамка цвета тега; квадратик того же цвета — перед именем в меню. */
.tag-c1 { border-color: var(--tag-1); color: var(--tag-1); }
.tag-c2 { border-color: var(--tag-2); color: var(--tag-2); }
.tag-c3 { border-color: var(--tag-3); color: var(--tag-3); }
.tag-c4 { border-color: var(--tag-4); color: var(--tag-4); }
.tag-c5 { border-color: var(--tag-5); color: var(--tag-5); }
.tag-c6 { border-color: var(--tag-6); color: var(--tag-6); }
.tag-c7 { border-color: var(--tag-7); color: var(--tag-7); }
.tag-c8 { border-color: var(--tag-8); color: var(--tag-8); }
.tag-dot { display: inline-block; width: 0.6rem; height: 0.6rem; margin-right: 0.45rem;
  border: 1px solid currentColor; vertical-align: -0.05rem; }
.tagmenu > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap;
  gap: 0.3rem; align-items: center; min-height: 1.4rem; }
.tagmenu > summary::-webkit-details-marker { display: none; }
.tagmenu-hint { font-size: 0.8667rem; color: var(--text-4); }
.tagmenu > summary:hover .tagmenu-hint, .tagmenu[open] .tagmenu-hint { color: var(--link); }
.tagmenu-pop { position: fixed; z-index: 40; width: 13rem; max-height: 18rem; overflow-y: auto;
  padding: 0.3rem 0; background: var(--panel); border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-pop); }
.tagmenu-row { display: flex; flex-wrap: wrap; align-items: center; }
.tagmenu-item { flex: 1; text-align: left; background: none; border: 0;
  padding: 0.35rem 0.7rem; color: var(--text); font: inherit; font-size: 0.8667rem; cursor: pointer; }
.tagmenu-item:hover { background: var(--chrome); }
.tagmenu-item.is-on { color: var(--link); cursor: default; }
.tagmenu-item.is-on:hover { background: none; }
.tagmenu-x { background: none; border: 0; padding: 0.35rem 0.7rem; color: var(--text-3);
  cursor: pointer; font-size: 0.95rem; line-height: 1; }
.tagmenu-x:hover { color: var(--bad); }
/* Корзина у тега: по клику под строкой появляется кнопка удалить совсем. */
.tagdel > summary { list-style: none; cursor: pointer; display: inline-flex; padding: 0.35rem 0.6rem;
  color: var(--text-4); line-height: 1; }
.tagdel > summary::-webkit-details-marker { display: none; }
.tagdel > summary:hover, .tagdel[open] > summary { color: var(--bad); }
.tagdel-do { display: none; flex: 1 0 100%; margin: 0 0.5rem 0.35rem; padding: 0.3rem 0.6rem;
  background: none; border: 1px solid var(--bad); color: var(--bad); font: inherit;
  font-size: 0.8667rem; text-align: left; cursor: pointer; }
.tagdel-do:hover { background: var(--chrome); }
.tagmenu-row:has(.tagdel[open]) .tagdel-do { display: block; }
.tagmenu-new { display: flex; gap: 0.3rem; margin: 0.3rem 0.5rem 0.2rem; padding-top: 0.4rem;
  border-top: 1px solid var(--line); }
.tagmenu-new .field { flex: 1; min-width: 0; padding: 0.25rem 0.5rem; font-size: 0.8667rem; }
.tagmenu-new .btn { padding: 0.25rem 0.6rem; }
/* Владелец бизнес-центра у админа в «Кабинетах»: имя — объёмная кнопка (уступ снизу,
   при нажатии проседает), меню баеров — то же всплывающее меню, что у тегов
   (pages._owner_menu). */
.owner-btn { font: inherit; font-size: 0.9333rem; color: var(--text); cursor: pointer;
  padding: 0.2rem 0.6667rem; border-radius: var(--radius); background: var(--panel);
  border: 1px solid var(--line-strong); box-shadow: 0 2px 0 var(--line-strong); }
.owner-btn:hover { border-color: var(--text-3); box-shadow: 0 2px 0 var(--text-3); }
.owner-btn:active { transform: translateY(2px); box-shadow: none; }
.owner-pop .tagmenu-item { display: block; width: 100%; }
/* Старшие баеры в «Кабинетах»: строка на старшего — имя, команда плашками с
   крестиком и меню «+ баер» (то же, что у владельца БЦ). Кнопки — формы. */
.lead-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5333rem 0.8rem;
  padding: 0.8rem var(--cell-x); border-bottom: 1px solid var(--line); }
.lead-row:last-child { border-bottom: 0; }
.lead-name { font-family: var(--font-heading); font-size: 1.0667rem; letter-spacing: .04em; }
.lead-form { display: inline; margin: 0; }
.owner-pop .lead-form { display: block; }
.lead-chip { display: inline-flex; align-items: center; gap: 0.2rem; font-size: 0.9333rem;
  padding: 0.1333rem 0.2rem 0.1333rem 0.6rem; border: 1px solid var(--line-strong); background: var(--panel); }
.lead-x, .lead-drop { font: inherit; background: none; border: 0; cursor: pointer; color: var(--text-3); }
.lead-x { padding: 0 0.3333rem; font-size: 1.0667rem; line-height: 1; }
.lead-drop { font-size: 0.8667rem; padding: 0; }
.lead-x:hover, .lead-drop:hover { color: var(--bad); }

/* ---------- Таблица ---------- */

.table { width: 100%; border-collapse: collapse; font-size: 1rem; }
.table th {
  font-family: var(--font-heading); font-size: 0.8333rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-3); text-align: left; padding: 0.6667rem 0.9333rem; border-bottom: 1px solid var(--line);
}
.table th:first-child, .table td:first-child { padding-left: var(--cell-x); }
.table th:last-child,  .table td:last-child  { padding-right: var(--cell-x); }
.table td { padding: var(--cell-y) 0.9333rem; border-bottom: 1px solid var(--line-soft); }
.table tbody tr:hover td { background: color-mix(in srgb, var(--accent) 10%, transparent); }
/* Числовые колонки разделены волосяными вертикалями: в плотной таблице без
   них строка цифр расплывается, глаз теряет, где кончается колонка. */
.table td.num, .table th.num { border-left: 1px solid color-mix(in srgb, var(--line-soft) 70%, transparent); }
/* Шапка колонок темнее тела, строки через одну чуть темнее: в длинной
   таблице взгляд держится на своей строке. */
.table thead th { background: var(--chrome); }
.table:not(.table-tree) tbody tr:nth-child(even) > td { background: color-mix(in srgb, var(--chrome) 45%, var(--panel)); }
/* Строка, выбранная фильтром: полупрозрачная золотая заливка во всю строку.
   Стоит после полосатости — иначе чётные строки перебивают её своим фоном, и
   выбор на них не виден. Золото здесь не сигнал, а отметка выбора: красный и
   песочный заняты кромкой слева. */
.table:not(.table-tree) tbody tr.picked > td {
  background: color-mix(in srgb, var(--brand) 26%, transparent); }
.table:not(.table-tree) tbody tr.picked:hover > td {
  background: color-mix(in srgb, var(--brand) 34%, transparent); }

/* Числовая колонка: направо, табличные цифры, никогда не переносится. */
.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-2); }
/* В таблицах цифры и заголовок над ними — по центру колонки: прижатые вправо,
   на ноутбуке с плотными отступами они липли к линии соседней колонки.
   Заголовок нужен явно: .table th задаёт left и по весу перебивает .num, из-за
   чего шапка уезжала от своих значений. */
.table td.num, .table th.num { text-align: center; }
/* У последней колонки с цифрами поля равные: поле у края таблицы (--cell-x)
   шире, и цифры по центру съезжали влево. Плотные таблицы — в ui.EXTRA_CSS. */
.table td.num:last-child, .table th.num:last-child { padding-right: 0.9333rem; }
/* Сортировка кликом по заголовку: ссылка наследует вид шапки, активная колонка
   ярче и со стрелкой (стрелка приходит в тексте заголовка). */
.table th a.sort { color: inherit; text-decoration: none; }
.table th a.sort:hover, .table th a.sort.is-on { color: var(--text); }
.num-strong { text-align: right; white-space: nowrap; font-family: var(--font-heading); font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.meta { font-size: 0.8667rem; color: var(--text-3); }

/* Сигнальная кромка строки. Ставится ТОЛЬКО когда строка ждёт человека.
   Красная — теряются деньги. Песочная — нет данных или не настроено. */
.edge-bad  { box-shadow: inset var(--edge) 0 0 var(--bad); }
.edge-warn { box-shadow: inset var(--edge) 0 0 var(--warn); }

.val-ok { color: var(--ok); }
.val-bad { color: var(--bad); }
.val-warn { color: var(--warn); }
.val-none { color: var(--text-4); }   /* прочерк «—»: нет данных, не ноль */
/* Состояние делится на три зелёных: чем ярче, тем ближе к деньгам. Крутит —
   деньги идут сейчас; активна — включена, расхода ещё нет; ожидание —
   модерация и старт по расписанию, зелёный почти без цвета. */
.val-live { color: var(--live); }
.val-wait { color: var(--wait); }
/* «Крутит» — единственный статус про деньги прямо сейчас, поэтому у него
   отдельный зелёный, светлее профитного: рядом с «активна» они сливались. */
.pill.val-ok { color: var(--run); }
/* Заливка плашки идёт от её же цвета, поэтому яркость задаётся здесь:
   у «крутит» она плотнее всех, у ожидания — едва заметна. */
.pill.val-ok { background: color-mix(in srgb, currentColor 30%, transparent); font-weight: 500; }
.pill.val-live { background: color-mix(in srgb, currentColor 26%, transparent); }
/* Ожидание — единственное состояние, которое пройдёт само: у него пунктирная
   рамка, и это видно даже там, где цвет не различить. */
.pill.val-wait { background: color-mix(in srgb, currentColor 10%, transparent);
  border-style: dashed; }
.pill.val-warn { background: color-mix(in srgb, currentColor 24%, transparent); }
.pill.val-bad { background: color-mix(in srgb, currentColor 26%, transparent); }
.pill.val-none { background: color-mix(in srgb, currentColor 14%, transparent); }

/* ---------- Управление ---------- */

.btn {
  font-family: var(--font-heading); font-size: 0.9333rem; letter-spacing: .1em; text-transform: uppercase;
  padding: 0.6667rem 1.3333rem; border-radius: var(--radius); cursor: pointer;
}
.btn-primary { background: var(--accent); border: 0; color: var(--chrome); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 85%, white); }
.btn-primary:active { background: color-mix(in srgb, var(--accent) 85%, black); }
.btn-outline { background: none; border: 1px solid var(--line-strong); color: var(--text); }
.btn-outline:hover { border-color: var(--text-3); }
.btn-quiet {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--font-heading); font-size: 0.9rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--link);
}
.btn-sm { font-size: 0.9rem; letter-spacing: .08em; padding: 0.4667rem 1.0667rem; }
.btn:disabled { opacity: .45; cursor: default; }

.badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.3333rem; height: 1.3333rem; border: 1px solid currentColor;
  font-family: var(--font-body); font-size: 0.8rem; font-variant-numeric: tabular-nums;
}

.field {
  background: var(--chrome); border: 1px solid var(--line); color: var(--text);
  font-family: var(--font-body); font-size: 0.9333rem; padding: 0.4667rem 0.7333rem; border-radius: var(--radius);
}
.field::placeholder { color: var(--text-4); }
.field:focus-visible { border-color: var(--accent); }

/* Всплывающее меню: единственный элемент с тенью. Висеть постоянно не должно —
   открывается по кнопке, закрывается крестиком. */
.pop {
  background: var(--panel); border: 1px solid var(--line-strong); border-top: 0;
  box-shadow: var(--shadow-pop);
}
.pop-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0.7333rem 1.0667rem; border-bottom: 1px solid var(--line); background: var(--chrome);
}
.pop-row {
  display: flex; align-items: center; gap: 0.9333rem;
  padding: 0.8667rem 1.0667rem; border-bottom: 1px solid var(--line-soft);
}
/* обязательно: иначе nowrap-текст не даёт строке сжаться и меню лезет за край */
.pop-row > .grow { flex: 1; min-width: 0; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* «Топ офферов» по партнёркам (владелец, 16.10): офферы под строкой своей
   партнёрки — мельче, серым и с отступом. */
.offer-top .offer-sub { font-size: 0.8rem; color: var(--text-3); }
.offer-top .offer-sub .key { padding-left: 1.1rem; }

/* ---------- Адаптация к ширине экрана ----------
   Пороги те же, что у компонентов в ui.EXTRA_CSS: 1900px — ноутбук и небольшой
   монитор, 1100px — планшет и узкое окно, 600px — телефон. Здесь только каркас:
   отступы, полоса итогов, шапка, заголовок. Таблицы на узком экране
   прокручиваются вбок внутри блока. */
/* Ноутбук: поля страницы как у планшета — каждый rem нужен колонке имени. */
@media (max-width: 1900px) {
  :root { --gutter: 1.2rem; }
}
@media (max-width: 1100px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stats > * + * { border-left: 0; }
  .stats > *:nth-child(2n) { border-left: 1px solid var(--line); }
  .stats > *:nth-child(n+3) { border-top: 1px solid var(--line); }
  .tab { padding: 0.9rem 1.1rem; }
  .h1 { font-size: 1.8rem; }
}
/* Вкладки без прокрутки (владелец, 16.10): с «Автозаливом» их у админа восемь, и
   полоса уезжала вбок. Отдельной строкой (до 1660px, ui.EXTRA_CSS) поля у вкладок
   уже, а не влезающие переносятся вторым рядом. В строке с логотипом (шире
   1660px) восьми вкладкам — поля поуже, чем шести-семи. Вкладки растянуты на
   всю полосу: иначе между последней вкладкой и «доской» (и справа от вкладок
   отдельной строкой) оставалась пустота. */
@media (min-width: 601px) {
  body .topbar-nav > .tab { flex: 1 0 auto; justify-content: center; }
}
/* Вкладки — тем же размером и разрядкой, что кнопки шапки (владелец, 16.10). */
@media (min-width: 901px) {
  body .topbar-nav > .tab { font-size: 0.9333rem; letter-spacing: .1em; }
}
@media (min-width: 601px) and (max-width: 1660px) {
  body .topbar-nav { flex-wrap: wrap; overflow: visible; }
  body .topbar-nav .tab { padding: 0.7rem 0.8rem; border-bottom: 1px solid var(--line);
    margin-bottom: -1px; }
}
@media (min-width: 1661px) {
  body .topbar-nav:has(> .tab:nth-child(8)) > .tab { padding-left: 0.9rem; padding-right: 0.9rem; }
}
/* Узкое окно (601–900px): вкладки мельче и плотнее, чтобы и восемь стояли одной
   строкой — двумя рядами они идут только на телефоне (владелец, 16.10). */
@media (min-width: 601px) and (max-width: 900px) {
  body .topbar-nav .tab { padding: 0.6rem clamp(0.3rem, 1.1vw, 0.8rem);
    font-size: clamp(0.72rem, 1.6vw, 1rem); letter-spacing: .06em; }
}
@media (max-width: 600px) {
  :root { --gutter: 0.8rem; --cell-x: 0.9rem; }
  .stats { grid-template-columns: 1fr; }
  .stats > *:nth-child(2n) { border-left: 0; }
  .stats > * + * { border-top: 1px solid var(--line); }
  .stats > * { padding: 0.9rem var(--cell-x) 1rem; }
  .figure-lg { font-size: 1.9rem; }
  .brand { padding-right: 1rem; font-size: 1.1rem; letter-spacing: .16em; }
  .h1 { font-size: 1.5rem; }
  .player { max-width: 100%; }
}

/* Ссылка на отчёт прямо в строке таблицы. Не кнопка: кнопка в каждой строке
   перетягивает внимание с цифр, ради которых таблицу и читают. */
.rowlink { color: var(--link); text-decoration: none; border-bottom: 1px dotted var(--link);
  white-space: nowrap; }
/* Слово «отчёт» рядом с именем — мельче имени; имя-ссылка размер не меняет. */
.rowlink.rowlink-word { font-size: 0.8em; font-weight: 400; }
.rowlink:hover { border-bottom-style: solid; }
/* Стрелка перехода на карточку рядом с именем. Без подчёркивания: пунктир под
   одним знаком читается как опечатка, а не как ссылка. */
.rowgo { color: var(--link); text-decoration: none; white-space: nowrap; }
.rowgo:hover { color: var(--link-hover); }

/* Сутки столбиками на карточке кампании. Без библиотек: в проекте нет
   фронтенда, высота задаётся долей от максимума прямо в разметке.
   Конверсии рисуются позади расхода, чтобы видеть смещение по часам. */
.hourchart { display: grid; grid-template-columns: repeat(24, 1fr); gap: 0.2rem;
  align-items: end; height: 9rem; }
.hourbar { position: relative; height: 100%; display: flex; align-items: flex-end;
  justify-content: center; }
.hour-spend, .hour-conv { position: absolute; bottom: 1.1rem; width: 60%; min-height: 1px; }
.hour-spend { background: var(--accent); }
.hour-conv { background: var(--line-strong); width: 100%; opacity: 0.55; }
.hour-tick { position: absolute; bottom: 0; font-size: 0.65rem; color: var(--text-4); }
.hour-key-spend, .hour-key-conv { display: inline-block; width: 0.7rem; height: 0.7rem;
  vertical-align: -1px; }
.hour-key-spend { background: var(--accent); }
.hour-key-conv { background: var(--line-strong); opacity: 0.55; }

/* Сетап кампании: сетка подписей вместо длинного столбца пар — двенадцать
   строк подряд заставляли скроллить ради двух слов. */
.setup-grid { display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 0.9rem var(--cell-x); padding: 1rem var(--cell-x); }
.setup-grid > div { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.setup-value { font-size: 0.95rem; color: var(--text-1); overflow-wrap: anywhere; }
@media (max-width: 1100px) { .setup-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .setup-grid { grid-template-columns: 1fr; } }

/* Воронка просмотров ролика: подпись, полоса, число. Без библиотек — длина
   полосы задаётся долей от показов прямо в разметке. */
.retention-row { display: grid; grid-template-columns: 9rem 1fr 5rem; align-items: center;
  gap: 0.8rem; padding: 0.2rem 0; }
.retention-bar { background: var(--chrome); height: 0.8rem; display: block; }
.retention-bar > span { background: var(--accent); height: 100%; display: block; }

/* Два блока в одну линию. Разрез из двух-трёх строк во всю ширину экрана гнал
   страницу вниз ради пары чисел; на узком экране пара разворачивается в столбик. */
.pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--block-gap);
  align-items: start; margin-top: var(--block-gap); }
.pair > .block { margin-top: 0; }
@media (max-width: 1100px) { .pair { grid-template-columns: 1fr; } }

/* Верх карточки креатива: файл слева узкой колонкой, цифры справа. Плеер во
   всю ширину отжимал сводку за первый экран. */
.card-top { display: grid; grid-template-columns: 20rem minmax(0, 1fr);
  gap: var(--block-gap); align-items: start; margin-top: var(--block-gap); }
/* Обе колонки начинаются на одной линии: собственные отступы первых блоков
   внутри пары гасятся, иначе левая съезжала вниз на зазор. */
.card-top > .block, .card-top > div > :first-child { margin-top: 0; }
.card-top .player { width: 100%; }
/* В узкой колонке шапка блока встаёт столбиком: подпись файла не помещается
   в одну строку с заголовком и слипалась с ним. Кнопки — тоже столбиком. */
.card-top > .block .block-head { display: block; }
.card-top > .block .block-note { display: block; margin: 0.3rem 0 0; }
.card-top > .block .btn { display: block; margin: 0 0 0.4rem; text-align: center; }
@media (max-width: 1100px) { .card-top { grid-template-columns: 1fr; } }

/* Длинная таблица в узкой колонке: прокрутка внутри, чтобы колонка не
   вытягивалась вдвое выше соседней. */
.scroll-y { max-height: 21rem; overflow-y: auto; }
/* В правой колонке карточки места вдвое меньше: компактные полосы встают
   в два столбца, иначе подписи переносятся по слову. */
.card-top .stats-compact { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ---------- Карточки кампании и креатива (.cmp) ----------
   Компактная раскладка, согласованная с владельцем на макете: полоса итогов,
   блоки в сетке по одной, две или три равные колонки, плотные таблицы со «ещё N».
   Всё под .cmp (класс страницы, ui.page) — остальные экраны этих правил не видят.
   Значения — итоговые из макета; менять только через согласование. */
.cmp { --cx: .8rem; }
.cmp .head-row { align-items: baseline; flex-wrap: wrap; gap: 1rem; padding-top: 0; margin: .6rem 0 .5rem; }
.cmp .head-row > div:first-child { display: flex; align-items: baseline; flex-wrap: wrap; gap: 1rem; min-width: 0; }
.cmp .h1 { font-size: 1.35rem; font-weight: 700; letter-spacing: .02em; text-transform: none;
  min-width: 0; overflow-wrap: anywhere; }  /* имя файла без пробелов распирало телефон */
.cmp .head-row .sub { font-size: .78rem; }
.cmp .kpi { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); border: 1px solid var(--line);
  background: var(--panel); }
.cmp .kpi .k { padding: .45rem var(--cx) .5rem; display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.cmp .kpi .k + .k { border-left: 1px solid var(--line-soft); }
.cmp .k-l { font-size: .66rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.cmp .k-v { font-family: var(--font-heading); font-size: 1.2rem; white-space: nowrap; }
.cmp .k-v .ev-wrap { white-space: normal; }  /* конверсии по целям: корзина переносится целиком */
.cmp .k-s { font-size: .72rem; color: var(--text-3); line-height: 1.3; }  /* переносится, а не режется */
/* Строка сетки: блоки тянутся до самого высокого, нижние края на одной линии. */
.cmp .mrow { display: grid; gap: .6rem; margin-top: .6rem; align-items: stretch; }
.cmp .mb { border: 1px solid var(--line); background: var(--panel); min-width: 0; display: flex;
  flex-direction: column; }
.cmp .mb + .mb { margin-top: .6rem; }
.cmp .mrow > .mb + .mb { margin-top: 0; }
/* Элемент флекс-колонки по умолчанию не сжимается уже содержимого: широкая
   таблица распирала страницу вместо прокрутки внутри блока. */
.cmp .mb > * { min-width: 0; }
.cmp .mb > :last-child { flex: 1 1 auto; }
.cmp .mb-h { display: flex; align-items: baseline; gap: .7rem; padding: .35rem var(--cx);
  border-bottom: 1px solid var(--line-soft); background: var(--chrome); }
.cmp .mb-t { font-family: var(--font-heading); font-size: .82rem; letter-spacing: .06em; text-transform: uppercase; }
.cmp .mb-n { font-size: .72rem; color: var(--text-3); margin-left: auto; text-align: right; }
.cmp .mb-b { padding: .55rem var(--cx) .6rem; }
.cmp .line2, .cmp .line3, .cmp .line4 { display: grid; }
.cmp .line2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cmp .line3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cmp .line4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cmp .line2 > div, .cmp .line3 > div, .cmp .line4 > div { padding: .4rem var(--cx) .45rem; min-width: 0; }
.cmp .line2 > div + div, .cmp .line3 > div + div, .cmp .line4 > div + div { border-left: 1px solid var(--line-soft); }
.cmp .line2 .k-l, .cmp .line3 .k-l, .cmp .line4 .k-l { display: block; }
.cmp .lv { font-family: var(--font-heading); font-size: 1.05rem; }
.cmp .ls { font-size: .72rem; color: var(--text-3); display: block; }
/* График часов: одна клетка на час, столбики растягиваются по ширине блока. */
.cmp .sp { width: 100%; height: 5.4rem; display: block; }
.cmp .sp .g { stroke: var(--line-soft); stroke-width: 1; vector-effect: non-scaling-stroke; }
.cmp .sp .bar { fill: var(--accent); }
.cmp .sp .bar-cv { fill: var(--ok); }
.cmp .sp .hit { fill-opacity: 0; }
.cmp .sp .hit:hover { fill-opacity: .07; }
.cmp .hticks { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); font-size: .62rem;
  color: var(--text-4); text-align: center; margin-top: .15rem; }
.cmp .hticks span:nth-child(3n+2), .cmp .hticks span:nth-child(3n+3) { visibility: hidden; }
.cmp .legend { font-size: .7rem; color: var(--text-3); margin-top: .2rem; }
.cmp .lg-bar, .cmp .lg-cv { display: inline-block; width: .6rem; height: .6rem; border-radius: 2px;
  vertical-align: -1px; margin: 0 .3rem 0 .6rem; }
.cmp .lg-bar { background: var(--accent); margin-left: 0; }
.cmp .lg-cv { background: var(--ok); }
/* Плотная таблица. */
.cmp .ct { width: 100%; border-collapse: collapse; font-size: .78rem; }
.cmp .ct th { font-size: .66rem; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3);
  font-weight: 500; text-align: left; padding: .3rem var(--cx); border-bottom: 1px solid var(--line-soft);
  background: var(--chrome); white-space: nowrap; }
.cmp .ct td { padding: .28rem var(--cx); border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
.cmp .ct .r { text-align: right; font-variant-numeric: tabular-nums; }
.cmp .ct tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--chrome) 35%, var(--panel)); }
.cmp .ct .nm { max-width: 18rem; overflow: hidden; text-overflow: ellipsis; }
/* Имя в разрезах «полной карточки» ролика: таблицы кабинетов и баеров стоят
   по две в ряд, длинное название обрезается, полное — в подсказке. */
.cmp .ct .cut { display: block; max-width: 9rem; overflow: hidden; text-overflow: ellipsis; }
.cmp .scroll-x { overflow-x: auto; }
.cmp .more summary { cursor: pointer; font-size: .74rem; color: var(--link); padding: .3rem var(--cx); list-style: none; }
.cmp .more summary::-webkit-details-marker { display: none; }
/* Сетап: подпись и значение; раскладка «инсталл ×6 · регистрация ×4» переносится. */
.cmp .setup { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem var(--cx);
  padding: .55rem var(--cx) .6rem; }
.cmp .setup6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.cmp .setup div { min-width: 0; }
.cmp .setup .sl { font-size: .62rem; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); display: block; }
.cmp .setup .sv { font-size: .78rem; display: block; white-space: normal; overflow-wrap: anywhere; line-height: 1.35; }
/* Досмотры ролика полосами. */
.cmp .ret { display: flex; flex-direction: column; gap: .22rem; }
.cmp .ret .rr { display: grid; grid-template-columns: 5.6rem minmax(0, 1fr) 4.2rem; gap: .5rem; align-items: center;
  font-size: .74rem; }
.cmp .ret .rb { height: .5rem; background: var(--chrome); border-radius: 2px; overflow: hidden; }
.cmp .ret .rb span { display: block; height: 100%; background: var(--accent); border-radius: 2px; }
.cmp .ret .rv { text-align: right; color: var(--text-2); font-variant-numeric: tabular-nums; }
/* Узкая колонка плеера слева от итогов креатива. */
.cmp .player-s { width: 100%; aspect-ratio: 9/16; max-height: 22rem; background: var(--chrome); display: block;
  border-radius: 2px; }
.cmp img.player-s { object-fit: contain; }
.cmp .player-none { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; padding: .8rem; text-align: center; }
.cmp .btns { display: flex; gap: .4rem; margin-top: .45rem; }
.cmp .btns a { flex: 1; text-align: center; font-size: .72rem; padding: .35rem .4rem; border: 1px solid var(--line-strong);
  color: var(--text-2); text-decoration: none; letter-spacing: .04em; }
.cmp .btns a.pri { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.cmp .tags { margin-top: .45rem; font-size: .72rem; color: var(--text-3); }
.cmp .note-in { width: 100%; background: var(--chrome); border: 1px solid var(--line-soft); color: var(--text);
  padding: .35rem .5rem; font-size: .78rem; }
.cmp .ev { font-size: .7rem; color: var(--text-3); margin-left: .15rem; }
.cmp .nowrap { white-space: nowrap; }
/* «Где крутится»: строка страны раскрывается по клику, под ней копии. */
.cmp .where .g-row { cursor: pointer; }
.cmp .where .g-row td { background: color-mix(in srgb, var(--chrome) 45%, var(--panel)); }
.cmp .where .g-row .g-arr::before { content: "▸"; color: var(--text-3); font-size: .7rem; margin-right: .4rem; }
.cmp .where .g-body.open .g-row .g-arr::before { content: "▾"; }
.cmp .where .g-sub { display: none; }
.cmp .where .g-body.open .g-sub { display: table-row; }
.cmp .where .g-sub td:first-child { padding-left: 1.6rem; }
/* Группы: имя и под ним отличия; у шагов воронки — число и под ним доля и цена.
   Периоды лежат в одной клетке сетки: высота блока при переключении постоянная. */
.cmp .grp .ct td { vertical-align: top; }
.cmp .grp .gnm { display: block; max-width: 34rem; }
.cmp .grp .gset { display: block; font-size: .7rem; color: var(--text-2); white-space: normal; line-height: 1.4;
  margin-top: .1rem; }
.cmp .grp .gk { color: var(--text-4); }
.cmp .grp .pr { display: block; font-size: .7rem; color: var(--text-3); margin-top: .1rem; }
.cmp .grp .goal { font-weight: 600; }
.cmp .grp .gps { display: grid; }
.cmp .grp .gp { grid-area: 1 / 1; visibility: hidden; min-width: 0; }
.cmp .grp.p-today .gp-today, .cmp .grp.p-yesterday .gp-yesterday, .cmp .grp.p-7d .gp-7d,
.cmp .grp.p-30d .gp-30d { visibility: visible; }
/* тот же переключатель, что в «Заливах», только ужат под шапку блока */
.cmp .mb-h .seg { display: inline-flex; vertical-align: middle; margin-left: .6rem; }
.cmp .mb-h .seg a { padding: .08rem .45rem; font-size: .62rem; letter-spacing: .06em; }
.cmp .glegend { font-size: .7rem; border-top: 1px solid var(--line-soft); }
@media (max-width: 1100px) {
  .cmp .kpi { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cmp .kpi .k:nth-child(5) { border-left: 0; }
  .cmp .kpi .k:nth-child(n+5) { border-top: 1px solid var(--line-soft); }
  .cmp .mrow { grid-template-columns: minmax(0, 1fr) !important; }
  .cmp .setup6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .cmp .kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* в две колонки: у первой в ряду нет левой линии, со второго ряда — верхняя */
  .cmp .kpi .k:nth-child(odd) { border-left: 0; }
  .cmp .kpi .k:nth-child(n+3) { border-top: 1px solid var(--line-soft); }
  .cmp .line2, .cmp .line3, .cmp .line4 { grid-template-columns: 1fr; }
  .cmp .line2 > div + div, .cmp .line3 > div + div, .cmp .line4 > div + div { border-left: 0;
    border-top: 1px solid var(--line-soft); }
  .cmp .setup6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Раздел в разработке ----------
   Страница видна, но приглушена и не нажимается: новые в команде не должны
   принять недоделанный раздел за рабочий. Слой фиксирован на весь экран, но
   лежит ниже шапки (у .topbar z-index 20), поэтому вкладки остаются живыми и из
   раздела можно уйти. Содержимое под слоем помечено inert (pages.accounts_page). */
.wip-shade {
  position: fixed; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center;
  background: var(--shade);
}
.wip-note {
  font-family: var(--font-heading); font-weight: 500; font-size: 1.8667rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text);
  background: var(--chrome); border: 1px solid var(--line-strong);
  border-left: var(--edge) solid var(--warn); padding: 1.0667rem 2.4rem;
}

/* ---------- Телефон: всё видно и компактно ----------
   Ширины колонок подобраны под монитор (ui._col): на телефоне цифры держали
   свои 6–10rem, а имени баера оставалось две буквы; имя кампании со стрелкой
   на карточку срезалось многоточием; вкладки разделов уезжали за край, пять
   плашек итогов по одной занимали весь первый экран (владелец, 28.09).
   Только до 600px: колонки по содержимому, колонка имени закреплена слева и
   переносит текст вместо «…», ячейки и подписи плотнее. `body` в селекторах —
   чтобы перебить стили компонентов (ui.EXTRA_CSS), они стоят в странице после
   этого файла; !important — только против ширин из разметки (colgroup и
   min-width таблицы). */
@media (max-width: 600px) {
  :root { --cell-x: 0.55rem; --cell-y: 0.45rem; --block-gap: 1rem; }

  /* Шапка ровными строками (владелец, 28.09): логотип и имя — первой
     строкой, кнопки «задачи · тема · выйти» — второй, поровну, вкладки —
     рядами от края до края, все разделы видны сразу. Блок справа раскрыт
     (display: contents), чтобы его части встали в свои строки; перенос перед
     кнопками — псевдоэлемент во всю ширину. Лишняя линия справа у последней
     вкладки ряда срезается краем полосы (overflow и сдвиг на 1px). */
  body .topbar .page { flex-wrap: wrap; padding: 0; }
  body .topbar .page::after { content: ""; order: 2; flex: 0 0 100%; }
  body .brand { order: 1; flex: 1 1 auto; border-right: 0; padding: 0.6rem var(--gutter);
    font-size: 1.05rem; }
  body .topbar-right { display: contents; }
  body .topbar-user { order: 2; border-left: 0; padding: 0 var(--gutter) 0 0.6rem;
    font-size: 0.78rem; }
  body .topbar-btn { order: 3; flex: 1 1 0; justify-content: center; padding: 0.5rem 0.3rem;
    font-size: 0.78rem; border-top: 1px solid var(--line); }
  body .topbar-right > .topbar-btn:first-child { border-left: 0; }
  /* Вкладки — сеткой в 12 долей, каждый ряд поделён поровну: у баера шесть
     вкладок — 3 + 3, у админа семь — 4 + 3, с «Автозаливом» восемь — 4 + 4,
     у фармера одна — во всю ширину. */
  body .topbar-nav { order: 4; flex: 1 1 100%; display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr)); overflow: hidden;
    border-top: 1px solid var(--line); }
  body .topbar-nav .tab { grid-column: span 4; justify-content: center; margin-right: -1px;
    padding: 0.55rem 0.3rem; font-size: 0.78rem; letter-spacing: .06em;
    border-top: 1px solid var(--line); margin-top: -1px; }
  body .topbar-nav .tab:first-child:nth-last-child(7),
  body .topbar-nav .tab:first-child:nth-last-child(7) ~ .tab:nth-child(-n+4),
  body .topbar-nav .tab:first-child:nth-last-child(8),
  body .topbar-nav .tab:first-child:nth-last-child(8) ~ .tab {
    grid-column: span 3; }
  body .topbar-nav .tab:only-child { grid-column: 1 / -1; }

  /* Переключатели (период, событие, «сегодня · за всё время») — так же ровными
     рядами поровну: пять периодов — 3 + 2, три события — в ряд до края, две
     кнопки — пополам. Линии — у каждой кнопки сверху и слева со сдвигом на 1px:
     у края они ложатся на рамку группы, во втором ряду дают линию сверху. */
  body .seg:not(.mb-h .seg) { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    flex: 1 1 100%; overflow: hidden; }
  /* Переключатель с подписью («событие») — в одной строке с ней, до края. */
  body .meta + .seg:not(.mb-h .seg) { flex: 1 1 0; }
  /* Даты периода — поровну на строку, «Показать» — во всю ширину: край формы
     ровный, как у переключателей над ней. */
  body form.filters { flex: 1 1 100%; }
  body form.filters > input.field { flex: 1 1 0; width: auto !important; min-width: 0; }
  body form.filters > .btn { flex: 1 1 100%; justify-content: center; }
  body .seg:not(.mb-h .seg) > a { grid-column: span 3; display: flex; justify-content: center;
    align-items: center; text-align: center; width: calc(100% + 1px); margin: -1px 0 0 -1px;
    border-left: 1px solid var(--line-strong); border-top: 1px solid var(--line-strong);
    padding-left: 0.3rem; padding-right: 0.3rem; }
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(2),
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(2) ~ * { grid-column: span 6; }
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(3),
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(3) ~ *,
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(5),
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(5) ~ :nth-child(-n+3) {
    grid-column: span 4; }
  body .seg:not(.mb-h .seg) > :first-child:nth-last-child(5) ~ :nth-child(n+4) {
    grid-column: span 6; }

  /* Плашки итогов по две в ряд; у дашборда первая (профит) — во всю ширину. */
  .stats, .stats-3, .stats-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats > * { padding: 0.6rem var(--cell-x) 0.7rem; gap: 0.35rem; }
  .stats > * + * { border-top: 0; }
  .stats > *:nth-child(2n) { border-left: 1px solid var(--line); }
  .stats > *:nth-child(n+3) { border-top: 1px solid var(--line); }
  .stats-5 > :first-child { grid-column: 1 / -1; }
  .stats-5 > :nth-child(2n) { border-left: 0; }
  .stats-5 > :nth-child(2n+1):not(:first-child) { border-left: 1px solid var(--line); }
  .stats-5 > :nth-child(n+2) { border-top: 1px solid var(--line); }
  .figure-lg { font-size: 1.6rem; }
  .figure-md { font-size: 1.2rem; }

  /* Таблицы: колонки по содержимому, подписи колонок мельче. Ширина таблицы —
     по содержимому, а не по экрану: сжатая под экран таблица отдавала каждой
     колонке её минимум, и имени, которому можно переноситься, доставался ноль. */
  body .table { width: max-content; min-width: 100% !important; table-layout: auto;
    font-size: 0.9rem; }
  body .table col { width: auto !important; }
  body .table th { font-size: 0.68rem; letter-spacing: .03em; padding-top: 0.4rem;
    padding-bottom: 0.4rem; }
  body .table td, body .table th { padding-left: 0.5rem; padding-right: 0.5rem; }

  /* Колонка имени закреплена слева: цифры уезжают вбок, а чья строка — видно.
     Фон — как у блока, иначе под именем просвечивали бы уехавшие цифры. */
  body .table td:first-child:not([colspan]), body .table th:first-child:not([colspan]) {
    position: sticky; left: 0; z-index: 1; background: var(--panel); width: 11.5rem; }
  body .table thead th:first-child { background: var(--chrome); z-index: 2; }
  /* Кромку-сигнал рисует строка — у закреплённой ячейки её закрыл бы фон. */
  body .table tr.edge-bad > td:first-child { box-shadow: inset var(--edge) 0 0 var(--bad); }
  body .table tr.edge-warn > td:first-child { box-shadow: inset var(--edge) 0 0 var(--warn); }

  /* Имя, подпись под ним и стрелка на карточку переносятся, а не режутся;
     статус — целиком, не шире 9,5rem. */
  body .line-name, body .table .ellipsis { white-space: normal; overflow: visible;
    overflow-wrap: break-word; }
  body .pill { display: inline-block; -webkit-line-clamp: none; overflow: visible;
    max-width: 9.5rem; }
  /* Превью меньше, чем на мониторе (4,2rem), — место отдано имени; лица в
     кадре на 3,2rem ещё различимы. Пустой треугольник раскрытия (роликов
     нет) места не занимает. */
  body .sub-name, body .camp .sub-name { grid-template-columns: 3.2rem minmax(0, 1fr);
    padding-left: 0.3rem; column-gap: 0.45rem; }
  body .camp .sub-name > .thumb-link, body .table-tree .sub-name > .thumb-link {
    width: 3.2rem; height: 3.2rem; }
  body .fold-none::before { width: 0; }
  /* Имена в строках таблиц чуть мельче (в разметке 1.0667rem): короткое имя
     кабинета иначе рвалось посреди слова — «FRBCkab / 2». */
  body .table .line-name > span[style*="font-size"] { font-size: 0.95rem !important; }

  /* Первая колонка — только превью («Креативы»): она узкая, по картинке, а
     закреплено вместе с ней имя — по одной картинке ролик не опознать.
     Сдвиг имени — ширина колонки превью: 3rem картинка + поля 0,3rem. */
  body .table:has(tbody > tr > td:first-child > .thumb-link:only-child) :is(th, td):first-child {
    width: 3rem; padding-left: 0.3rem; padding-right: 0.3rem; }
  body .table:has(tbody > tr > td:first-child > .thumb-link:only-child) :is(th, td):nth-child(2) {
    position: sticky; left: 3.6rem; z-index: 1; background: var(--panel); width: 9rem; }
  body .table:has(tbody > tr > td:first-child > .thumb-link:only-child) thead th:nth-child(2) {
    background: var(--chrome); z-index: 2; }

  /* «Заливы»: шапка кабинета растянута на всю таблицу (colspan) — на телефоне
     она держится в видимой части и переносится, а не уезжает вправо. */
  body .table-tree .cab-head { position: sticky; left: 0.4rem; max-width: calc(100vw - 3.2rem); }
  body .cab-id { flex-wrap: wrap; max-width: none; gap: 0.2rem 0.5rem; }
  body .cab-id > .meta, body .cab-id > [class^="val-"] { white-space: normal; }

  /* Поля форм («Настройки») — не шире экрана: поле с шириной из разметки
     (28rem) растягивало подпись-обёртку, и вместе с ней уезжала страница. */
  body .block form > * { max-width: 100%; min-width: 0; }
  body .block input, body .block select, body .block textarea { max-width: 100%; }

  /* Публичные страницы: меню переносится, «Sign in» не уходит за край. */
  body .site-top { flex-wrap: wrap; gap: 0.6rem 1rem; padding: 1rem 0; }
  body .site-nav { flex-wrap: wrap; gap: 0.45rem 1rem; font-size: 0.75rem; }
}
