/* Пульт T18 — тёмная плотная админка (Фаза 1, read-only) */
:root {
  --bg: #0d1117;
  --panel: #161b22;
  --panel2: #1d232c;
  --border: #2a3038;
  --text: #d5dbe3;
  --muted: #8b949e;
  --green: #3fb950;
  --red: #f85149;
  --yellow: #d29922;
  --blue: #58a6ff;
  /* 28/07: тот же лавандовый, что маркер «действия» графика (drawBidChart,
     #d2a8ff) — отметка события в Истории и её точка на графике читаются как
     одно и то же одним цветом. */
  --purple: #d2a8ff;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- topbar ---- */
#topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: 6px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.brand { font-weight: 700; font-size: 14px; letter-spacing: .3px; white-space: nowrap; }
#nav { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; }
#nav::-webkit-scrollbar { display: none; }
#nav a {
  padding: 4px 10px; border-radius: 6px; color: var(--muted);
  white-space: nowrap; font-weight: 500;
}
#nav a:hover { color: var(--text); text-decoration: none; }
#nav a.active { color: var(--text); background: var(--panel2); }
/* Группированные пункты нав-меню (24/07, редизайн 17→5 вкладок): нативный
   <details>/<summary> вместо своего JS-дропдауна — открытие/закрытие и
   клавиатура бесплатно из коробки; закрытие по клику вне/при навигации —
   пара строк в app.js (render() + один document-level click).
   position:fixed, а не absolute (важно!): #nav — overflow-x:auto (горизонт.
   скролл вкладок), а по CSS-спеке overflow-x≠visible ЗАСТАВЛЯЕТ движок
   считать overflow-y тоже auto, даже если явно не задан — любой потомок,
   вылезающий за рамку #nav (в т.ч. position:absolute), обрезается. Найдено
   живой проверкой в браузере: computed style дропдауна был корректным
   (opacity 1, z-index 30, верные координаты), но elementFromPoint() в его
   области возвращал контент СТРАНИЦЫ под ним — меню рисовалось, но
   вырезалось контейнером. fixed игнорирует overflow предков (кроме
   transform/filter/perspective — их тут нет) — координаты app.js
   выставляет в момент открытия (событие toggle), т.к. fixed не наследует
   «100% от родителя». */
.nav-drop { position: relative; display: inline-block; }
.nav-drop > summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: 4px 10px; border-radius: 6px; color: var(--muted); font-weight: 500;
  white-space: nowrap;
}
.nav-drop > summary::-webkit-details-marker { display: none; }
.nav-drop > summary::after { content: ' ▾'; font-size: 9px; opacity: .7; }
.nav-drop > summary:hover { color: var(--text); }
.nav-drop.has-active > summary { color: var(--text); background: var(--panel2); }
.nav-drop[open] > summary { color: var(--text); }
.nav-drop-menu {
  position: fixed; z-index: 35;
  display: flex; flex-direction: column; min-width: 168px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 4px; box-shadow: 0 8px 22px rgba(0,0,0,.45);
}
.nav-drop-menu a { padding: 6px 10px; border-radius: 6px; color: var(--muted); white-space: nowrap; }
.nav-drop-menu a:hover { color: var(--text); background: var(--panel2); text-decoration: none; }
.nav-drop-menu a.active { color: var(--text); background: var(--panel2); }
.top-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.fresh {
  font-family: var(--mono); font-size: 11px; padding: 2px 8px;
  border-radius: 10px; white-space: nowrap;
}
.fresh.ok { color: var(--green); border: 1px solid rgba(63,185,80,.4); }
.fresh.stale { color: var(--red); border: 1px solid rgba(248,81,73,.5); font-weight: 700; }

/* ---- layout ---- */
#view { padding: 12px; max-width: 1500px; margin: 0 auto; }
h2 { font-size: 15px; margin: 4px 0 10px; }
/* Заголовок редизайн-экранов (#/opt, #/zbtop, #/zbid): выше корзин по шкале.
   Класс, а не глобальный h2 — чтобы не трогать #/v2* (Игорю нравятся как есть). */
h2.scr-h { font-size: 20px; font-weight: 700; letter-spacing: -.01em; margin: 6px 0 12px; }
h3 { font-size: 13px; margin: 14px 0 6px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
/* Редизайн 17/07 — единая шкала заголовков: h2 экрана (20) > корзина (15) >
   секция/подсекция (13.5) > мета (11.5). opt-h3 (WL/Бюджет/Ретест/Движок
   пропускает) — ОДИН уровень с summary секций (это siblings внутри корзины);
   отличие — акцентная полоса слева вместо шеврона (не сворачивается). */
h3.opt-h3 { font-size: 13.5px; font-weight: 700; color: var(--text);
  text-transform: none; letter-spacing: 0; margin: 18px 0 6px;
  padding-left: 10px; border-left: 3px solid var(--blue); line-height: 1.35; }
.loading { color: var(--muted); padding: 30px; text-align: center; }
.err-box {
  background: rgba(248,81,73,.1); border: 1px solid rgba(248,81,73,.4);
  color: var(--red); border-radius: 8px; padding: 10px 12px; margin: 10px 0;
}
/* Task 2 (16/07): «липкая» инлайн-плашка результата (см. stickyResult в app.js) —
   зелёный близнец .err-box, но не пропадает сама (крестик закрывает вручную).
   flex-basis:100% — чтобы занять свою строку внутри flex-wrap контейнеров чипов
   (.cre-chips/.cov-gaps), как .cre-chips-xhead; в flex-column контейнерах
   (.cre-qbody) это же правило безвредно. */
.sticky-result {
  display: flex; align-items: flex-start; gap: 8px; flex-basis: 100%;
  background: rgba(63,185,80,.1); border: 1px solid rgba(63,185,80,.4);
  color: var(--text); border-radius: 8px; padding: 6px 10px; margin: 4px 0;
  font-size: 12px; line-height: 1.4;
}
.sticky-result-txt { flex: 1; min-width: 0; }
.sticky-x {
  flex: 0 0 auto; background: none; border: none; color: var(--muted);
  cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px;
}
.sticky-x:hover { color: var(--text); }
.empty { color: var(--muted); padding: 20px; text-align: center; }
.note { color: var(--muted); font-size: 12px; margin: 6px 0; }
/* Бейдж возраста данных (29/07, инцидент 28/07) — шапка экранов решений
   (#/dims, #/champions, #/domains, #/trends, #/opt, #/zbid, #/creatives).
   .badge/.b-red/.b-gray выше уже несут фон/цвет — тут только отступ под h2. */
.data-fresh-badge { margin: -6px 0 10px; }
span.muted { color: var(--muted); font-size: 11px; }

/* ---- cards ---- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; margin-bottom: 12px; }
.card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; min-width: 0;
}
.card .ttl { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
.card .big { font-size: 22px; font-weight: 700; font-family: var(--mono); margin: 2px 0; }
.card .sub { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.card .sub b { color: var(--text); font-weight: 600; }

.panel {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 12px;
}
.chart-panel { height: 260px; position: relative; }
/* F9-3: намёк на кликабельность легенды (приглушённый, под графиком) */
.legend-hint { color: var(--muted); font-size: 11px; margin: 4px 2px 12px; text-align: right; }

/* ---- тренды (#/trends) ---- */
/* Раскатка 18/07: фильтр-панель в языке .opt-filter (panel + радиус 10) —
   этот тулбар делят Тренды, Инвентарь и Чемпионы. */
.trend-ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  padding: 8px 12px; margin: 8px 0 12px; font-size: 12px; color: var(--muted); }
.trend-ctl label { color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.trend-ctl select, .trend-ctl input {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font: inherit; }
.trend-ctl input { width: 130px; }
.trend-ctl input[hidden] { display: none; }
/* Универсальная сортировка таблиц: любой заголовок .sth кликабелен, активный —
   ярче, стрелка ▲/▼ живёт в .sarr (не переносится отдельно от подписи). Общий
   вид для клиентских таблиц (.tbl/.xtbl) и серверного Инвентаря (домены/зоны). */
th.sth { cursor: pointer; user-select: none; white-space: nowrap; }
th.sth:hover, th.sth.on { color: var(--text); }
.sarr { font-size: 10px; }
.dlink { cursor: pointer; }
.trend-total { background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 12px; }
.trend-total .tt-scope { color: var(--muted); font-size: 11px; margin-bottom: 5px; }
.trend-total .tt-row { display: flex; flex-wrap: wrap; gap: 16px; font-size: 13px; font-family: var(--mono); }
.trend-total .tt-row b { font-weight: 700; }
.trend-chart { height: 300px; position: relative; margin-bottom: 14px; }

/* ---- tables ---- */
.tablewrap {
  overflow: auto; max-height: 72vh;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); margin-bottom: 12px;
}
table.tbl {
  border-collapse: collapse; width: 100%;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 12px; white-space: nowrap;
}
.tbl th, .tbl td { padding: 4px 8px; border-bottom: 1px solid var(--border); text-align: right; }
.tbl th.l, .tbl td.l { text-align: left; }
.tbl thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel2); color: var(--muted);
  font-weight: 600; font-size: 11px;
}
.tbl tbody tr:hover { background: rgba(88,166,255,.05); }
/* Зебра плоских таблиц (раскатка 18/07) — только там, где строки однородны
   (без пар строка+detail и без живой вставки строк): двигатели Обзора, Тренды,
   Инвентарь (в #dBody/#zBody), классическая таблица (#cList), Новое, табло
   Эффективности, табы Домены/Вариации карточки, bid-up-таблицы, ОС-сегменты,
   бэктест Порогов. :where — нулевая специфичность: hover / hl-подсветки /
   totals сильнее. (Внутри комментария нельзя писать «звёздочка-слэш» слитно —
   парсер закрывает комментарий досрочно и съедает следующее правило.)
   Пары (opt-tbl/domblk/bidsDown) — отдельное правило 4n+3 ниже; таблицы с
   нерегулярными парами (таб «Зоны») и вставкой строк (#blTbl) — без зебры. */
:where(#moversTbl, #trendsTbl, #newTbl, #sitesTabTbl, #varsTabTbl, #thrBtTbl,
  #bidsUpTbl, #optBidUpTbl, #osFlagsTbl, .eff-tbl) tbody tr:nth-child(even),
:where(#cList, #dBody, #zBody) .tbl tbody tr:nth-child(even) {
  background: rgba(255,255,255,.018);
}
/* top: 25px — вручную подогнан под высоту одной строки thead (font-size 11px
   × line-height 1.45 ≈ 16px + padding 4px×2 + border 1px); при изменении
   паддингов/шрифта шапки таблиц менять синхронно, иначе totals-строка
   отклеится от шапки или наедет на неё при скролле. */
.tbl tr.totals td { background: var(--panel2); font-weight: 700; position: sticky; top: 25px; z-index: 1; }
.tbl tr.muted td { color: var(--muted); }
.zsub {
  display: block; max-width: 170px; overflow: hidden; text-overflow: ellipsis;
  color: var(--muted); font-size: 11px;
}
.hid { display: none !important; }
.pos { color: var(--green); }
.neg { color: var(--red); }
.warn { color: var(--yellow); }

/* Volume Acquired gate: доля объёма по гейту (ok/caution/high). */
.va-ok { color: var(--green); }
.va-caution { color: var(--yellow); }
.va-high { color: var(--red); font-weight: 700; }
.va-high { cursor: help; }
/* Строка доли объёма в шапке карточки. */
.camp-va { font-family: var(--mono); font-size: 12px; margin: 4px 0; }
.camp-va b { font-weight: 700; }
.camp-va.muted-line { color: var(--muted); }

/* Бейдж значимости/надёжности — рядом с причиной/заметкой, инлайн (переносится
   вместе с текстом, без горизонтального переполнения на узких экранах). */
.sig-badge { white-space: nowrap; vertical-align: baseline; }

tr.hl-block { background: rgba(248,81,73,.10); }
tr.hl-unblock { background: rgba(63,185,80,.09); }
tr.hl-review { background: rgba(210,153,34,.09); }
tr.hl-block:hover, tr.hl-unblock:hover, tr.hl-review:hover { filter: brightness(1.15); }
tr.expandable { cursor: pointer; }
tr.detail td {
  background: var(--panel2); white-space: normal; text-align: left;
  color: var(--muted); font-size: 11.5px; line-height: 1.5;
  border-left: 2px solid rgba(88,166,255,.35); /* видимая связка с раскрытой строкой */
}
/* Контент детали — sticky-обёртка: td растянут на всю ширину широкой таблицы,
   а текст остаётся в видимой части при горизонтальном скролле (17/07). */
tr.detail .det-body, tr.zb-det .det-body {
  position: sticky; left: 8px; max-width: calc(100vw - 72px);
}
tr.detail pre {
  margin: 4px 0 0; white-space: pre-wrap; word-break: break-all;
  max-height: 200px; overflow: auto; color: var(--text); font-size: 11px;
}

/* ---- controls ---- */
.controls {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-bottom: 10px; font-size: 12px;
}
.controls label { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); cursor: pointer; }
.controls input[type=text], .controls input[type=search], .controls select {
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit;
}
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.seg button {
  background: var(--panel); color: var(--muted); border: 0;
  padding: 4px 10px; cursor: pointer; font: inherit; font-family: var(--mono);
}
.seg button + button { border-left: 1px solid var(--border); }
.seg button.on { background: var(--panel2); color: var(--text); font-weight: 700; }
/* Сегмент-переключатели во всю строку: Инвентарь [Домены|Зоны], История
   [Все действия|Журнал Пульта] — на своей строке, с отступом от контента. */
.inv-seg, .hist-seg { display: inline-flex; margin: 0 0 12px; }
.btn {
  background: var(--panel2); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 12px; cursor: pointer; font: inherit;
}
.btn:hover { border-color: var(--muted); }
.btn.primary { background: #1f6feb; border-color: #1f6feb; color: #fff; font-weight: 600; }
.btn.ghost { background: transparent; color: var(--muted); padding: 2px 8px; }
.btn.more { display: block; margin: 0 auto 12px; }

/* ---- badges / dots / bars ---- */
.badge {
  display: inline-block; padding: 1px 7px; border-radius: 9px;
  font-size: 11px; font-family: var(--mono); font-weight: 600;
}
.b-red { background: rgba(248,81,73,.15); color: var(--red); }
.b-green { background: rgba(63,185,80,.15); color: var(--green); }
.b-yellow { background: rgba(210,153,34,.18); color: var(--yellow); }
.b-blue { background: rgba(88,166,255,.15); color: var(--blue); }
.b-gray { background: rgba(139,148,158,.15); color: var(--muted); }
.b-purple { background: rgba(210,168,255,.15); color: var(--purple); }

/* ---- контекстные подсказки ⓘ (16/07, заказ Игоря) ----------------------
   Маленький кружок рядом с элементом; текст — из HELP (см. hint() в app.js),
   доставляется в CSS через content:attr(data-hint), без лишнего JS на каждый
   инстанс. Открывается по :hover (мышь) И по классу .open (тап с телефона —
   один делегированный клик-обработчик в app.js переключает .open, закрывает
   остальные открытые, закрывается кликом мимо). Не кричащий — приглушённый
   серый в состоянии покоя, акцентный при наведении/открытии. */
.hint {
  display: inline-block; position: relative;
  font-size: .85em; line-height: 1; vertical-align: middle;
  color: var(--muted); cursor: help; margin-left: 3px;
}
.hint:hover, .hint.open, .hint:focus-visible { color: var(--blue); outline: none; }
.hint::after {
  content: attr(data-hint);
  display: none;
  position: absolute; top: 130%; left: 0; z-index: 9000;
  max-width: 340px; width: max-content;
  padding: 8px 10px; border-radius: 6px;
  background: #1c2128; border: 1px solid var(--border);
  box-shadow: 0 6px 20px rgba(0,0,0,.55);
  color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px; font-weight: 400; font-variant-numeric: normal;
  line-height: 1.45; white-space: normal; text-align: left;
  text-transform: none; letter-spacing: normal; cursor: auto;
}
.hint:hover::after, .hint.open::after, .hint:focus-visible::after { display: block; }
/* Правые колонки таблиц: пузырь открывается ВЛЕВО от иконки, не улетает за
   край экрана (transform-сдвиг при переполнении не нужен — этого достаточно). */
.hint-left::after { left: auto; right: 0; }
/* Заголовки таблиц — свои шрифт/регистр (var(--mono), uppercase, nowrap);
   .hint внутри .sth не должен наследовать ни то, ни другое — оверрайд явно,
   иначе моноширинный ЗАГЛАВНЫЙ текст в пузыре читается хуже прозы. */
th.sth .hint { text-transform: none; }
@media (max-width: 480px) {
  /* На телефоне (Игорь смотрит с него) 340px почти во весь экран — уже. */
  .hint::after { max-width: 240px; }
}

/* 🔴 Сторож переудушения (15/07): красный баннер «я тебя душу» на карточке
   переудушенной кампании + предупреждение над очередью «Оптимизация». */
.overblock-banner {
  margin: 8px 0; padding: 9px 12px; border-radius: 8px;
  background: rgba(248,81,73,.13); border: 1px solid rgba(248,81,73,.4);
  color: #ffb3ad; font-size: 12.5px; line-height: 1.5;
}
.overblock-banner b { color: var(--red); }
.overblock-list { margin: 5px 0 0; padding-left: 18px; }
.overblock-list li { margin: 2px 0; }
/* Баннер устаревшей легаси-аналитики (§2.1-a, 16/07) — тот же красный язык, что
   у overblock-баннера, отдельный класс: смысл другой (staleness, не переудушение). */
.stale-banner {
  margin: 8px 0; padding: 9px 12px; border-radius: 8px;
  background: rgba(248,81,73,.13); border: 1px solid rgba(248,81,73,.4);
  color: #ffb3ad; font-size: 12.5px; line-height: 1.5;
}
/* L1O (переносимость ставок) + prior-dominated бейдж/заметка (внешний аудит 15/07).
   18/07: summary — секционный язык (шеврон-квадратик, open отделён линией). */
.loco-card { margin: 8px 0; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.loco-card > summary {
  cursor: pointer; padding: 8px 10px; font-weight: 700; font-size: 13.5px;
  list-style: none; user-select: none;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
}
.loco-card > summary::-webkit-details-marker { display: none; }
.loco-card > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
.loco-card[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
.loco-card[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.loco-card > summary:hover { background: rgba(255,255,255,.025); border-radius: 10px; }
.loco-card > summary .badge { margin-left: 4px; }
.loco-body { padding: 4px 10px 10px; }
.loco-body .dim { font-size: 12px; margin-bottom: 6px; }
.loco-warn { margin-top: 6px; color: #ffb3ad; font-size: 12px; }
.loco-note { font-style: italic; }
.zb-prior { cursor: help; }
.zb-prior-note { margin: 4px 0; color: var(--yellow); font-size: 12px; }
/* кликабельный бейдж «в BL ✕» в карточке зоны — снять зону с BL кампании */
button.zbl-un { border: 0; cursor: pointer; line-height: inherit; vertical-align: baseline; margin-left: 4px; }
button.zbl-un:hover { background: rgba(248,81,73,.22); color: #ff9c95; }
/* крестик удаления отметки события во вкладке «История» карточки кампании
   (actRow, opts.delEvents) — тот же приём, что zbl-un выше. */
button.evt-del {
  border: 0; background: none; color: var(--muted); cursor: pointer;
  line-height: inherit; vertical-align: baseline; margin-left: 6px; padding: 0 3px;
}
button.evt-del:hover { background: rgba(248,81,73,.22); color: #ff9c95; }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }
.dot.run { background: var(--green); }
.dot.off { background: var(--muted); }
.flag { margin: 0 2px; }
.chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }

.bar {
  display: inline-block; width: 110px; height: 8px; vertical-align: middle;
  background: #21262d; border-radius: 4px; overflow: hidden; margin-right: 6px;
}
.bar i { display: block; height: 100%; background: var(--green); }
.bar.warn i { background: var(--yellow); }
.bar.crit i { background: var(--red); }

/* ---- action feed ---- */
.feed { border: 1px solid var(--border); border-radius: 8px; background: var(--panel); margin-bottom: 12px; }
.act {
  display: flex; gap: 8px; align-items: baseline; padding: 5px 10px;
  border-bottom: 1px solid var(--border); font-family: var(--mono); font-size: 12px;
  min-width: 0;
}
.act:last-child { border-bottom: 0; }
.act.expandable { cursor: pointer; }
.act .ts { color: var(--muted); white-space: nowrap; }
.act .cid { white-space: nowrap; }
.act .zid { color: var(--yellow); white-space: nowrap; }
/* Task 3 (16/07): человеческая строка — полное предложение, не однострочный
   огрызок с многоточием (та и была жалоба «не могу понять, добавилось или
   нет») — своя строка (flex-basis:100%) под ts/badge/zid, перенос по словам. */
.act .reason {
  color: var(--muted); overflow: hidden; white-space: normal;
  word-break: break-word; flex: 1 1 100%; min-width: 60px;
}
.act-detail {
  padding: 6px 12px 8px; border-bottom: 1px solid var(--border);
  background: var(--panel2); font-size: 11px; color: var(--muted);
}
.act-detail pre {
  margin: 4px 0 0; white-space: pre-wrap; word-break: break-all;
  max-height: 240px; overflow: auto; color: var(--text); font-size: 11px;
}
/* «Технические детали» (Task 3): нативный <details>, свёрнуто по умолчанию —
   заменяет прежний div.act-detail.hid + делегат клика по всей строке. Общий
   стиль раскрытия — как у .hday/.jbatch (▸/▾ перед текстом summary). */
.act-tech, .jrow-tech {
  padding: 4px 12px 8px; border-bottom: 1px solid var(--border);
  background: var(--panel2); font-size: 11px; color: var(--muted);
}
/* 18/07: вторичный раскрыватель в языке .why (мелкий приглушённо-акцентный
   summary) + один язык поворота шеврона. */
.act-tech > summary, .jrow-tech > summary {
  cursor: pointer; list-style: none; user-select: none; padding: 2px 0;
  font-size: 11px; color: var(--blue); opacity: .85;
}
.act-tech > summary:hover, .jrow-tech > summary:hover { opacity: 1; }
.act-tech > summary::-webkit-details-marker,
.jrow-tech > summary::-webkit-details-marker { display: none; }
.act-tech > summary::before, .jrow-tech > summary::before {
  content: '▸'; display: inline-block; margin-right: 5px; color: var(--muted);
  transition: transform .15s ease;
}
.act-tech[open] > summary::before, .jrow-tech[open] > summary::before {
  transform: rotate(90deg); color: var(--blue);
}
.act-tech pre, .jrow-tech pre {
  margin: 4px 0 0; white-space: pre-wrap; word-break: break-all;
  max-height: 240px; overflow: auto; color: var(--text); font-size: 11px;
}

/* ---- feed grouped by day (История) ---- */
/* Раскатка 18/07: день — строка-секция в языке .opt-sec (шеврон-квадратик с
   поворотом 90°, открытый день отделён и слегка «утоплен»), не безликая
   стрелка-малютка. Классы/делегаты (.zid внутри) — байт-в-байт. */
.feed-days { padding: 0; }
details.hday { border-bottom: 1px solid var(--border); }
details.hday:last-child { border-bottom: 0; }
details.hday > summary {
  cursor: pointer; padding: 7px 10px; display: flex; gap: 10px; align-items: center;
  list-style: none; user-select: none; min-width: 0;
}
details.hday > summary::-webkit-details-marker { display: none; }
details.hday > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
details.hday[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
details.hday > summary:hover { background: var(--panel2); }
/* линию под шапкой открытого дня рисует .hday-body (border-top) — не дублируем */
details.hday[open] > summary { font-weight: 600; }
details.hday[open] { background: rgba(0, 0, 0, .14); }
.hday-date { font-family: var(--mono); font-weight: 600; white-space: nowrap; }
.hday-sum {
  color: var(--muted); flex: 1; min-width: 0; font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hday-n {
  color: var(--muted); font-size: 11px; white-space: nowrap;
  font-family: var(--mono); opacity: .8;
}
.hday-body { border-top: 1px solid var(--border); }
.hday-body .act:last-child { border-bottom: 0; }

/* ---- CPL deviation vs campaign average (карточка зоны/домена) ---- */
.cpl-dev { font-size: 11px; font-weight: 600; margin-left: 3px; white-space: nowrap; }
.cpl-up { color: var(--red); }
.cpl-down { color: var(--green); }

/* ---- campaign header / tabs ---- */
.camp-head { margin-bottom: 10px; }
/* Раскатка 18/07: заголовок карточки — уровень экрана по шкале (scr-h, 20px);
   разметку (точка статуса + бейдж внутри h2) не трогаем — только размер. */
.camp-head h2 { margin-bottom: 2px; font-size: 20px; font-weight: 700; letter-spacing: -.01em; }
.camp-meta { color: var(--muted); font-size: 12px; font-family: var(--mono); }
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 10px; overflow-x: auto; }
.tabs button {
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--muted); padding: 6px 12px; cursor: pointer; font: inherit; white-space: nowrap;
}
.tabs button.on { color: var(--text); border-bottom-color: var(--blue); font-weight: 600; }

/* ---- overview two-col ---- */
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.cols > div { min-width: 0; }
.h-link { font-size: 11px; font-weight: 400; text-transform: none; letter-spacing: 0; margin-left: 6px; white-space: nowrap; }

/* ---- insights (обзор) ---- */
details.ins-sec { margin: 4px 0 14px; }
details.ins-sec > summary {
  cursor: pointer; color: var(--muted); font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px; padding: 4px 0; list-style: none;
}
details.ins-sec > summary::-webkit-details-marker { display: none; }
details.ins-sec > summary::before { content: '▸'; display: inline-block; margin-right: 6px; }
details.ins-sec[open] > summary::before { content: '▾'; }
.ins-gen { font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 11px; }
.ins-card {
  display: flex; gap: 8px; align-items: baseline; padding: 6px 10px;
  border: 1px solid var(--border); border-left-width: 3px; border-radius: 6px;
  background: var(--panel); margin-bottom: 4px; cursor: pointer; min-width: 0; font-size: 13px;
}
.ins-warn { border-left-color: var(--yellow); }
.ins-good { border-left-color: var(--green); }
.ins-info { border-left-color: var(--blue); }
.ins-card .ins-ico { flex: none; }
.ins-card .ins-title {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text);
}
.ins-camp {
  flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 12px; font-family: var(--mono);
}
.ins-card .exp { flex: none; }
.ins-detail {
  border: 1px solid var(--border); border-top: 0; border-radius: 0 0 6px 6px;
  background: var(--panel2); padding: 8px 10px; margin: -4px 0 6px;
  font-size: 12px; color: var(--muted);
}
.ins-detail .ins-rec { color: var(--text); margin-top: 5px; }
.ins-zones { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.ins-zones .zid { color: var(--yellow); font-family: var(--mono); cursor: pointer; }
.ins-zones .zid:hover { text-decoration: underline; }
.ins-showmore { margin: 2px 0 8px; }
/* фильтры вкладки «Инсайты» (#/insights) — как .controls, но с зазором посвободнее */
.ins-controls { gap: 14px; }
.ins-controls select { font-family: var(--mono); }

/* Тулбар-модификатор (раскатка 18/07): панель+рамка+радиус в одном языке с
   .opt-filter/.zt-bar/.ctl. На generic .controls экранов скоупа добавлен класс
   ctlbar В РАЗМЕТКЕ (классическая таблица, Новое, История, Журнал, таб «Зоны»
   карточки) — глобально .controls не рестайлим: его использует замороженный
   #/v2. Свои-классовые тулбары (.ins-controls/.cre-controls) — сюда же. */
.controls.ctlbar, .ins-controls, .cre-controls {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px; margin: 8px 0 12px;
  color: var(--muted);
}

/* ---- обзор: блок «Вчера» ---- */
.yst { margin: 2px 0 14px; }
.yst-head { color: var(--muted); font-size: 12px; font-family: var(--mono); margin: 0 0 8px; }
.yst-head b { color: var(--text); font-weight: 700; }
.yst-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.yst-tile {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 11px; min-width: 0;
}
.yst-tile.is-main { border-color: rgba(88,166,255,.35); background: var(--panel2); }
.yst-tile .yl { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
.yst-tile .yv { font-family: var(--mono); font-size: 20px; font-weight: 700; margin: 2px 0 5px; }
.yst-tile.is-main .yv { font-size: 26px; }
.yst-tile .ycmps { display: flex; flex-direction: column; gap: 2px; }
.ycmp { font-family: var(--mono); font-size: 11px; white-space: nowrap; color: var(--muted); }
.ycmp .ycl { color: var(--muted); opacity: .75; margin-right: 3px; }
.ycmp.pos { color: var(--green); }
.ycmp.neg { color: var(--red); }
.ycmp.flat { color: var(--muted); }

/* ---- обзор: блок «Требует решения» ---- */
.needs { margin: 2px 0 16px; }
.needs-list { display: flex; flex-direction: column; gap: 6px; }
.need-row {
  display: flex; align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--border); border-left-width: 3px;
  border-left-color: var(--border); border-radius: 7px;
  padding: 7px 11px; color: var(--text); font-size: 13px;
}
.need-row:hover { text-decoration: none; border-color: var(--muted); background: var(--panel2); }
.need-row.need-warn { border-left-color: var(--yellow); }
.need-row .need-ico { flex: none; }
.need-row .need-txt {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.need-row .need-camp {
  flex: none; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--muted); font-family: var(--mono); font-size: 12px;
}
.need-row .need-go { flex: none; color: var(--muted); }
.need-wait, .need-empty { color: var(--muted); font-size: 12px; padding: 5px 2px; }
.need-wait { font-style: italic; }
.need-empty { color: var(--green); }

/* ---- optimization (#/opt) ---- */
/* Один глобальный фильтр кампания/формат на все секции очереди — панель-тулбар
   в общем языке с .zt-bar/.batchbar. Мобилка: wrap, без горизонтального
   скролла страницы. */
.opt-filter {
  margin: 8px 0 14px; display: flex; gap: 8px 14px; align-items: center;
  flex-wrap: wrap; color: var(--muted); font-size: 12px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px;
}
.opt-filter select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit;
  max-width: 100%;
}
/* Форматов пока один (native) — селект показываем (готовность к баннерам), но
   приглушаем, чтобы не тянул внимание. Оживёт визуально при появлении форматов. */
.opt-filter select.fmt-muted { opacity: .55; }
.opt-filter select.fmt-muted:hover, .opt-filter select.fmt-muted:focus { opacity: 1; }
/* Чип формата в строке account-wide «Домены к блокировке» (формат = часть смысла
   кандидата после B5): мельче обычного бейджа, приглушённый. Тот же чип — на
   строках очереди «Оптимизация» (①/②/«Движок пропускает», native vs banner
   300x250 всегда на виду) и в матрице кампаний drawer'а группы. */
.fmt-chip { font-size: 10px; padding: 0 5px; vertical-align: middle; }
/* «+N» доп. форматов зоны (несколько форматов — chipMulti): чуть приглушённее
   основного текста чипа, без лишнего веса. */
.fmt-chip-more { opacity: .75; }
/* ==================== Секционная система (редизайн 17/07) ====================
   Секция = карточка со строкой-заголовком: шеврон-квадратик (поворот при
   open), название, счётчик, чипы «⏸/😴», мета справа. Открытая секция —
   «утопленная» панель (фон темнее + рамка + внутренний отступ), заголовок
   отделён линией; закрытая — призрачная строка. ТОЛЬКО прямые дети (>): у
   чипов отложенных внутри свои summary — старый каскад без «>» красил и их
   (одна из причин «не понимаю, что развёрнуто»).
   .spl-sec («конвертит, но дорого» / секции топа ставок) — та же вёрстка, НО
   отдельный класс (не opt-sec): её действия идут мимо bindOptSection, общий
   класс увёл бы её в generic-биндинг без data-sec и уронил бы экран. */
.opt-sec, .spl-sec {
  margin: 0 0 12px; border: 1px solid transparent; border-radius: 10px;
}
.opt-sec[open], .spl-sec[open] {
  background: rgba(0, 0, 0, .14); border-color: var(--border);
  padding: 0 10px 10px;
}
.opt-sec > summary, .spl-sec > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 9px 10px; border-radius: 10px;
  font-size: 13.5px; font-weight: 700; color: var(--text); line-height: 1.35;
}
.opt-sec[open] > summary, .spl-sec[open] > summary {
  margin: 0 -10px 10px; border-bottom: 1px solid var(--border);
  border-radius: 10px 10px 0 0;
}
.opt-sec > summary:hover, .spl-sec > summary:hover { background: rgba(255,255,255,.025); }
.opt-sec > summary::-webkit-details-marker, .spl-sec > summary::-webkit-details-marker { display: none; }
/* Шеврон-квадратик: один язык раскрытия на всех уровнях (поворот 90°). */
.opt-sec > summary::before, .spl-sec > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
.opt-sec[open] > summary::before, .spl-sec[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
@media (prefers-reduced-motion: reduce) {
  .opt-sec > summary::before, .spl-sec > summary::before { transition: none; }
}
.sec-t { min-width: 0; }
.opt-sec > summary .badge, .spl-sec > summary .badge { font-weight: 600; flex: none; }
/* Мета заголовка (N камп. · €/7д · скрытые счётчики) — вправо, приглушённо. */
.sec-meta { margin-left: auto; text-align: right; font-weight: 400;
  font-size: 11.5px; margin-top: 0; margin-bottom: 0; max-width: 62%; }
/* Поясняющая подпись секции (WL-untarget / ②-«дорого»): под заголовком, приглушённая. */
.opt-sec-note { margin: -2px 0 10px; padding: 0 2px; }
/* C4 (13/07): KPI-плашки кликабельны (скролл к секции) — курсор + лёгкий hover. */
.card.kpi-jump { cursor: pointer; transition: border-color .15s, background .15s; }
.card.kpi-jump:hover { border-color: var(--blue); background: var(--panel2); }
.card.kpi-jump:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* ==================== Три корзины «Оптимизация» (редизайн 17/07) ============
   Один цветной контейнер = один вопрос человека (Отрезать/Починить/
   Масштабировать + Спорные). Шапка-строка: иконка-плитка в цвете корзины,
   [название над вопросом], деньги справа, КРУПНЫЙ шеврон-кружок (поворот 90°
   при open). Цветной борт слева виден всегда; открытая корзина отделяет
   шапку линией — состояние очевидно без обучения (жалоба Игоря 17/07). */
.opt-basket {
  border: 1px solid var(--border); border-left: 4px solid var(--bk, var(--border));
  border-radius: 12px; margin: 0 0 14px; background: var(--panel); overflow: hidden;
}
/* Грид, не flex-wrap: при нехватке места переносятся ДЕНЬГИ (на строку под
   название), а шеврон всегда прибит к правому краю первой строки. */
.opt-basket > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: grid; align-items: center; gap: 2px 12px;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-areas: "icon head money chev";
  padding: 10px 14px; min-height: 52px;
}
.opt-basket > summary::-webkit-details-marker { display: none; }
.opt-basket > summary:hover { background: rgba(255,255,255,.02); }
.opt-basket[open] > summary { border-bottom: 1px solid var(--border); }
.bk-icon {
  grid-area: icon; width: 32px; height: 32px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 15px;
  border-radius: 9px; background: var(--bk-tint, var(--panel2));
  border: 1px solid var(--border);
  border-color: color-mix(in srgb, var(--bk, var(--border)) 40%, transparent);
}
.bk-head { grid-area: head; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bk-title { font-size: 15px; font-weight: 800; letter-spacing: .04em;
  color: var(--bk, var(--text)); line-height: 1.25; }
.bk-q { font-size: 11.5px; color: var(--muted); }
.bk-money { grid-area: money; font-size: 12.5px; font-weight: 600;
  color: var(--text); text-align: right; }
.bk-chev {
  grid-area: chev; width: 26px; height: 26px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 50%;
  font-size: 12px; line-height: 1; color: var(--muted);
  background: var(--panel2); border: 1px solid var(--border);
  transition: transform .18s ease;
}
/* Средняя ширина: деньги не влезают в строку — на второй ряд под название. */
@media (max-width: 980px) {
  .opt-basket > summary {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "icon head chev" "icon money money";
  }
  .bk-money { text-align: left; justify-self: start; }
}
.opt-basket[open] > summary .bk-chev {
  transform: rotate(90deg); color: var(--bk, var(--text));
  border-color: color-mix(in srgb, var(--bk, var(--border)) 50%, transparent);
}
@media (prefers-reduced-motion: reduce) { .bk-chev { transition: none; } }
.bk-body { padding: 10px 14px 12px; }
.bk-empty { color: var(--muted); padding: 8px 2px 4px; font-size: 12.5px; }
.basket-cut   { --bk: var(--red);    --bk-tint: rgba(248,81,73,.10); }
.basket-fix   { --bk: var(--yellow); --bk-tint: rgba(210,153,34,.10); }
.basket-scale { --bk: var(--green);  --bk-tint: rgba(63,185,80,.10); }
.basket-review{ --bk: var(--muted);  --bk-tint: rgba(139,148,158,.10); }
.bk-body .opt-sec, .bk-body .spl-sec { margin-bottom: 12px; }
.bk-body > .opt-h3:first-child, .bk-body > .overblock-banner:first-child { margin-top: 4px; }
/* Причина ПО-ЧЕЛОВЕЧЕСКИ — фраза может занимать пару строк, не обрезаем.
   26ch (было 34) — экономия ширины ради видимости «весь аккаунт»; min-width
   держит колонку от схлопывания в столбик из одиночных слов (17/07). */
.reason-chip { white-space: normal; text-align: left; display: inline-block;
  min-width: 18ch; max-width: 26ch; line-height: 1.25; }
/* C4: цель прыжка коротко подсвечивается, чтобы глаз её поймал. */
@keyframes optFlash { 0% { background: rgba(88,166,255,.22); } 100% { background: transparent; } }
.opt-flash { animation: optFlash 1.3s ease-out; }
@media (prefers-reduced-motion: reduce) { .opt-flash { animation: none; } }
.tbl td.rsn { max-width: 340px; overflow: hidden; text-overflow: ellipsis; }
/* Очередь: причина + бейджи (значимость/подозрительность) в одной ячейке.
   Текст усекается многоточием, бейджи всегда видны целиком (не клипаются). */
.tbl td.rsn.rsn-flex { display: flex; align-items: center; gap: 6px; }
.tbl td.rsn.rsn-flex .badge { flex: 0 0 auto; }
/* Пульт-строки: раскрывающееся «почему?» с полным обоснованием (rationale).
   summary — мелкий, приглушённо-акцентный, кликабельный; тело переносится и
   держится внутри ячейки/.tablewrap (без горизонтального скролла на мобиле). */
.why { margin-top: 4px; }
.why summary { font-size: 11px; color: var(--blue); cursor: pointer; opacity: .85; }
.why summary:hover { opacity: 1; }
.why-body {
  white-space: normal; max-width: 320px; margin-top: 4px;
  color: var(--muted); font-size: 11px; line-height: 1.5;
}
.why-body .wl { margin: 3px 0; line-height: 1.5; }
.why-body .wk { color: var(--muted); font-weight: 600; margin-right: 4px; }
.why-body .wl.sub { margin-left: 12px; color: var(--muted); font-size: 11px; }
.verdict.v-cut { color: var(--red); font-weight: 700; }
.verdict.v-review { color: var(--yellow); font-weight: 700; }
.tbl th.ck, .tbl td.ck { width: 26px; text-align: center; }
.tbl td.ck input, .tbl th.ck input { vertical-align: middle; cursor: pointer; }
.batchbar {
  position: sticky; bottom: 8px; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  background: var(--panel2); border: 1px solid rgba(88,166,255,.4);
  border-radius: 10px; padding: 6px 12px; margin: -6px 0 12px;
  font-family: var(--mono); font-size: 12px;
  box-shadow: 0 8px 22px rgba(0,0,0,.45);
}
.batchbar[hidden] { display: none; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
table.wl-zones { margin-top: 6px; width: auto; min-width: 60%; }

/* ---- login ---- */
#login {
  position: fixed; inset: 0; z-index: 100; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
}
#login[hidden] { display: none; }
#loginForm {
  display: flex; flex-direction: column; gap: 10px; width: 260px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 24px;
}
.login-title { font-size: 18px; font-weight: 700; text-align: center; margin-bottom: 6px; }
#lg, #pw {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px; font: inherit;
}
/* Автозаполнение браузера красит поля в системный белый/жёлтый — на тёмной
   форме это выглядит сломанным. Хрому фон через box-shadow-трюк (background
   он игнорирует), цвет текста — -webkit-text-fill-color. */
#lg:-webkit-autofill, #pw:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--bg) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}
.login-msg { color: var(--red); font-size: 12px; min-height: 16px; text-align: center; }

/* ---- toast ---- */
#toast {
  position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%);
  z-index: 200; max-width: 90vw;
  background: #3d1d20; color: #ffb3ad; border: 1px solid var(--red);
  border-radius: 8px; padding: 8px 14px; font-size: 12px;
}
#toast[hidden] { display: none; }

/* ---- apply buttons (xs / danger) ---- */
.btn.xs { padding: 2px 8px; font-size: 11px; }
.btn.xs + .btn.xs { margin-left: 4px; }
/* ячейка действий: кнопки компактнее и прижаты вправо, чтобы не вылезали за край
   таблицы (жалоба Игоря 15/07 — «отл» обрезался). */
.act-cell { white-space: nowrap; text-align: right; padding-right: 8px; }
.opt-tbl .act-cell .btn.xs { padding: 1px 7px; }
.opt-tbl .act-cell .btn.xs + .btn.xs { margin-left: 3px; }
.opt-tbl .act-cell .btn.xs.ghost { padding: 1px 5px; }
.btn.danger { background: rgba(248,81,73,.15); border-color: rgba(248,81,73,.5); color: #ff9c95; }
.btn.danger:hover { background: rgba(248,81,73,.25); border-color: var(--red); }
.tbl td.act-cell { text-align: center; white-space: nowrap; }
/* Контур ретеста (§4 U2, 16/07): проба, у которой исчерпан кап/срок — «пора
   решить», лёгкая жёлтая подсветка строки (тот же тон, что badge b-yellow). */
tr.retest-flagged td { background: rgba(210,153,34,.08); }

/* ---- вкладка «Ставки» (F6) ---- */
/* компактная ссылка «→ другой экран» в шапке h2 (Оптимизация↔Ставки) */
.screen-link { font-size: 12px; font-weight: 400; margin-left: 8px;
  color: var(--blue); text-decoration: none; }
.screen-link:hover { text-decoration: underline; }
/* bid-up, подавленный недавней сменой бида — приглушённая строка */
.tbl tr.susp td { color: var(--muted); }
/* инлайн-чеврон разворота (bid_down) в ячейке кампании */
span.exp { color: var(--muted); cursor: pointer; margin-right: 2px; user-select: none; }
/* ячейка действий bid_down: [-30%][-50%] + произвольный процент со знаком */
.biddown-ed { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px;
  vertical-align: middle; }
.biddown-pct-input { width: 52px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px; padding: 2px 5px;
  font: inherit; font-size: 11px; text-align: center; }

/* ---- «отложенные» (snooze, #7c) — чипы-кнопки, редизайн 17/07 ----
   Вместо вложенных гармошек: пассивный счётчик «⏸ N · 😴 M» в заголовке
   секции (.snz-note) + два независимых чипа-пилюли под таблицей
   (.snz-chips > details.snz-chip); клик — тонкая вставка со списком,
   открытый чип подсвечен синим. Классы .snoozed-box/.snz-dormant-box
   сохранены (делегаты .snz-back/.zid ловят по ним). */
.snz-note {
  flex: none; color: var(--yellow); font-size: 11px; font-weight: 600;
  font-family: var(--mono); background: rgba(210,153,34,.12);
  border: 1px solid rgba(210,153,34,.3); border-radius: 999px;
  padding: 1px 8px; white-space: nowrap;
}
.snz-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start;
  margin: 2px 0 8px; }
details.snz-chip { min-width: 0; }
details.snz-chip[open] { flex: 1 1 100%; }
details.snz-chip > summary {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none; user-select: none;
  font-size: 12px; color: var(--muted);
  background: var(--panel2); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 12px;
}
details.snz-chip > summary::-webkit-details-marker { display: none; }
details.snz-chip > summary:hover { color: var(--text); border-color: var(--muted); }
details.snz-chip[open] > summary {
  color: var(--text); border-color: rgba(88,166,255,.45);
  background: rgba(88,166,255,.08);
}
details.snz-chip > summary b { font-family: var(--mono); color: var(--text); }
.snz-chev { font-size: 9px; color: var(--muted); transition: transform .15s ease; }
details.snz-chip[open] > summary .snz-chev { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .snz-chev { transition: none; } }
.snz-sub { font-size: 10.5px; color: var(--muted); opacity: .8; }
.snz-tblwrap { margin: 8px 0 2px; max-height: 44vh; }
.snoozed-tbl td.nowrap { white-space: nowrap; color: var(--muted); font-family: var(--mono); }
.snz-dormant-box .snoozed-tbl { opacity: .9; }

/* «↩ Недавно вернулись из отложки» — top-level чип в том же языке, зелёный. */
details.snz-wakes { margin: 8px 0 10px; }
details.snz-wakes > summary {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none; user-select: none;
  font-size: 12px; color: var(--green);
  background: rgba(63,185,80,.08); border: 1px solid rgba(63,185,80,.35);
  border-radius: 999px; padding: 3px 12px;
}
details.snz-wakes > summary::-webkit-details-marker { display: none; }
details.snz-wakes > summary:hover { filter: brightness(1.2); }
details.snz-wakes[open] > summary { background: rgba(63,185,80,.14); }
details.snz-wakes .tablewrap { margin: 8px 0 2px; }

/* бейдж режима отклада (умный/срок) — в «Отложенных» и в «Недавно вернулись» */
.snz-mode-badge {
  font-size: 10px; padding: 1px 6px; border-radius: 4px; white-space: nowrap;
  border: 1px solid var(--border); color: var(--muted);
}
.snz-mode-badge.smart { color: var(--blue); border-color: var(--blue); }

/* переключатель режима в модалке «Отложить» (snoozeModePrompt) */
.snz-mode { margin: 10px 0 4px; display: flex; flex-direction: column; gap: 6px; }
.snz-mode-opt { display: flex; align-items: baseline; gap: 6px; cursor: pointer; font-size: 13px; }
.snz-mode-opt input { margin: 2px 0 0; flex: 0 0 auto; }

/* заметка «вернулась: причина» на строке ленты, аннотированной свежим
   авто-пробуждением (woke_reason/woke_detail). max-width — иначе длинная фраза
   задаёт max-content колонки «зона» и раздувает таблицу (17/07). */
.woke-note { display: block; font-size: 11px; color: var(--green); margin-top: 1px;
  max-width: 220px; white-space: normal; line-height: 1.35; }
.woke-note.bleed { color: var(--red); }
.woke-note.spike { color: var(--yellow); }

/* ---- money editors (campaign header) ---- */
.camp-edits { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.money-ed {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 4px 8px; font-size: 12px; font-family: var(--mono);
}
.money-ed .me-lbl { color: var(--muted); }
.money-ed .me-cur { font-weight: 700; }
.money-ed .me-arrow { color: var(--muted); }
.money-ed .me-input {
  width: 72px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px; padding: 3px 6px; font: inherit;
}

/* ---- единая панель «Ставка и бюджет» (карточка кампании) ---- */
.bid-panel { margin-bottom: 14px; }
/* 18/07: заголовок панели — язык opt-h3 (h3 глобально uppercase-muted). */
.bid-panel .bid-h { margin: 14px 0 8px; font-size: 13.5px; font-weight: 700;
  color: var(--text); text-transform: none; letter-spacing: 0;
  padding-left: 10px; border-left: 3px solid var(--blue); line-height: 1.35; }
/* текущий бид */
.bid-cur {
  display: flex; align-items: baseline; gap: 8px;
  font-family: var(--mono); font-size: 13px; margin-bottom: 8px;
}
.bid-cur .bc-k { color: var(--muted); }
.bid-cur .bc-v { font-weight: 700; font-size: 16px; }
/* строка рекомендации движка / «применено сегодня» */
.bid-rec {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 8px;
  font-family: var(--mono); font-size: 13px;
}
.bid-rec .bid-rec-apply { margin-left: auto; }
.bid-rec.applied { color: var(--green); border-color: rgba(63,185,80,.4); }
/* редакторы бида/бюджета */
.bid-edit {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 8px;
  font-family: var(--mono); font-size: 13px;
}
.bid-edit .ba-lbl { color: var(--muted); }
.bid-edit .ba-arrow { color: var(--muted); }
/* --- режим процента: поле % + две кнопки-направления --- */
.ba-pctwrap { display: inline-flex; align-items: center; gap: 3px; }
.bid-edit .ba-pct {
  width: 56px; background: var(--bg); color: var(--text);
  border: 1px solid var(--blue); border-radius: 5px;
  padding: 4px 6px; font: inherit; text-align: center;
}
.bid-edit .ba-pct.bad { border-color: var(--red); }
.ba-pctsign { color: var(--muted); }
.bid-edit .ba-dir { font-family: var(--mono); white-space: nowrap; }
.bid-edit .ba-dir[disabled] { opacity: .5; cursor: not-allowed; }
.bid-edit .ba-dir .ba-dv, .bid-edit .ba-dir .ba-uv { font-weight: 700; }
/* понизить — красноватая, поднять — синяя (стиль системы) */
.bid-edit .ba-down {
  background: rgba(248,81,73,.12); border-color: rgba(248,81,73,.5); color: #ff9c95;
}
.bid-edit .ba-down:hover:not([disabled]) { background: rgba(248,81,73,.22); border-color: var(--red); }
.bid-edit .ba-up {
  background: rgba(88,166,255,.15); border-color: rgba(88,166,255,.6); color: var(--blue);
}
.bid-edit .ba-up:hover:not([disabled]) { background: rgba(88,166,255,.28); border-color: var(--blue); }
/* переключатель режима — вторичная ссылка справа, не спорит с кнопками */
.bid-edit .ba-mode-link {
  margin-left: auto; color: var(--muted); font-size: 12px;
  cursor: pointer; border-bottom: 1px dashed var(--border);
}
.bid-edit .ba-mode-link:hover { color: var(--text); }
/* --- режим абсолютного бида в € (вторичный) --- */
.ba-eurwrap { display: inline-flex; align-items: center; gap: 3px; color: var(--muted); }
.bid-edit .ba-eur {
  width: 88px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px;
  padding: 4px 6px; font: inherit; text-align: center;
}
.bid-edit .ba-newv { font-weight: 700; font-size: 15px; color: var(--blue); }
.bid-edit .ba-apply { margin-left: 4px; }
/* budget money-ed внутри панели растягивается на всю строку */
.bid-edit-budget { padding: 6px 8px; }
.bid-edit-budget .money-ed { border: none; background: none; padding: 0; width: 100%; }
.bid-edit-budget .money-ed .me-apply { margin-left: auto; }
/* график: шапка с периодом и бейджем «нет данных» + раскрытие дня */
.bid-chart-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 6px;
}
/* «Отметить событие» (28/07) — справа от периода/бейджа «нет данных» */
.bid-mark-event { margin-left: auto; }
/* Форма модалки «Отметить событие»: заголовок + описание, каждое поле —
   своя строка (как у zp-row, только без фиксированной узкой ширины ввода —
   там цифра, здесь свободный текст). */
.evt-row { display: flex; flex-direction: column; gap: 4px; margin: 10px 0; }
.evt-row label { font-size: 12px; color: var(--muted); }
.evt-row input[type="text"] {
  padding: 6px 8px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); font: inherit; box-sizing: border-box;
}
.bid-chart-panel { margin-bottom: 10px; }
.bid-actday {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 10px;
  font-family: var(--mono); font-size: 12px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
.bid-actday .bid-actday-hist { margin-left: auto; }
/* таблица сегментов между сменами бида/бюджета (B2-3) */
.seg-sec { margin: 4px 0 12px; }
.seg-sec .seg-h {
  margin: 10px 0 6px; font-size: 12px; font-weight: 600;
  color: var(--muted); cursor: help;
}
.seg-tbl td.seg-d { font-family: var(--mono); white-space: nowrap; }
/* секция «Рекомендации Пульта» карточки */
.camp-recs { margin-bottom: 14px; }

/* ---- modal ---- */
#modal {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
/* Гвард-модал — отдельный слой ПОВЕРХ базового #modal (прогресс-модал живёт под
   ним, не уничтожается): guard 409 внутри batch/seqCampApply не гасит прогресс. */
#gmodal {
  position: fixed; inset: 0; z-index: 320;
  background: rgba(0,0,0,.45);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.modal-box {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; width: 440px; max-width: 100%; max-height: 88vh;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 12px 40px rgba(0,0,0,.5);
}
.modal-box.warn { border-color: rgba(210,153,34,.6); }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-weight: 700; background: var(--panel2);
}
.modal-box.warn .modal-head { background: rgba(210,153,34,.12); color: var(--yellow); }
.modal-x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 15px; }
.modal-body { padding: 14px; overflow: auto; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 10px 14px; border-top: 1px solid var(--border);
}
.modal-summary { font-size: 13px; line-height: 1.6; }
.modal-summary .note, .modal-ctx { margin-top: 6px; }
.modal-ctx { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.guard-detail { color: var(--yellow); font-weight: 600; margin-bottom: 8px; }
.force-lbl { display: block; margin-top: 12px; font-size: 12px; color: var(--muted); }
.force-lbl input {
  display: block; margin-top: 6px; width: 140px;
  background: var(--bg); color: var(--text); border: 1px solid var(--red);
  border-radius: 6px; padding: 6px 8px; font: inherit; font-family: var(--mono);
}

/* ---- batch progress ---- */
.batch-item { padding: 3px 0; border-bottom: 1px solid var(--border); font-size: 11px; }
.batch-item .mono, .mono { font-family: var(--mono); }

/* ---- batch progress v2: живой per-zone / per-API прогресс ---- */
.bp { font-size: 12px; }
.bp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.bp-title { font-weight: 700; font-size: 13px; display: inline-flex; align-items: center; gap: 7px; }
.bp-title.is-done { color: var(--green); }
.bp-title.is-bad { color: var(--red); }
.bp-title .bp-spin { width: 12px; height: 12px; }
.bp-pct { font-family: var(--mono); color: var(--muted); font-size: 12px; white-space: nowrap; }
.bp-pct b { color: var(--text); }

.bp-bar { height: 7px; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; overflow: hidden; margin-bottom: 12px; }
.bp-fill { height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--blue), var(--green));
  transition: width .55s cubic-bezier(.4,0,.2,1); }
.bp-fill.is-done { background: var(--green); }
.bp-fill.is-bad { background: linear-gradient(90deg, var(--yellow), var(--red)); }

.bp-sub { font-family: var(--mono); font-size: 11px; color: var(--muted); margin: -6px 0 10px; }

.bp-zones { max-height: 44vh; overflow: auto; display: flex; flex-direction: column; gap: 8px; }
.bp-camp { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--panel2); }
.bp-camp-h { display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  background: var(--panel); border-bottom: 1px solid var(--border); font-family: var(--mono); font-size: 12px; }
.bp-camp-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-chip { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  padding: 2px 9px; border-radius: 999px; font-size: 11px; white-space: nowrap; font-weight: 600; }
.bp-chip.is-queued { background: rgba(139,148,158,.14); color: var(--muted); }
.bp-chip.is-run { background: rgba(88,166,255,.16); color: var(--blue); }
.bp-chip.is-ok { background: rgba(63,185,80,.16); color: var(--green); }
.bp-chip.is-bad { background: rgba(248,81,73,.16); color: var(--red); }
.bp-chip.is-warn { background: rgba(210,153,34,.16); color: var(--yellow); }

.bp-zone { display: flex; align-items: center; gap: 8px; padding: 5px 10px;
  border-top: 1px solid rgba(42,48,56,.55); font-family: var(--mono); font-size: 11px; }
/* C1: было `.bp-camp .bp-zone:first-of-type` — мёртвый селектор (:first-of-type
   считает по ТЕГУ div, а .bp-camp-h — тоже div и стоит раньше первой .bp-zone,
   так что ни одна .bp-zone им никогда не была) — двойная граница под шапкой
   кампании (border-bottom шапки + border-top первой строки) визуально читалась
   как «строка наезжает». Adjacent-sibling — точное попадание в первую строку. */
.bp-camp-h + .bp-zone { border-top: 0; }
.bp-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: #4a525c;
  transition: background .3s ease; }
.bp-zone.is-run .bp-dot { background: var(--blue); animation: bpPulse 1.1s ease-in-out infinite; }
.bp-zone.is-ok .bp-dot { background: var(--green); }
.bp-zone.is-skip .bp-dot { background: var(--yellow); }
.bp-zone.is-already .bp-dot { background: #4a525c; opacity: .7; }
.bp-zone.is-bad .bp-dot { background: var(--red); }
.bp-zid { color: var(--text); font-weight: 600; flex: 0 0 auto; }
.bp-zsite { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; }
.bp-zstat { margin-left: auto; white-space: nowrap; flex: 0 0 auto; color: var(--muted); }
.bp-zone.is-run .bp-zstat { color: var(--blue); }
.bp-zone.is-ok .bp-zstat { color: var(--green); }
.bp-zone.is-skip .bp-zstat { color: var(--yellow); }
.bp-zone.is-bad .bp-zstat { color: var(--red); }

.bp-spin { display: inline-block; width: 11px; height: 11px; border: 2px solid rgba(88,166,255,.3);
  border-top-color: var(--blue); border-radius: 50%; animation: bpSpin .7s linear infinite; }
@keyframes bpSpin { to { transform: rotate(360deg); } }
@keyframes bpPulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(1.55); } }
@media (prefers-reduced-motion: reduce) { .bp-spin, .bp-zone.is-run .bp-dot { animation: none; } }

/* разбор + «настоять» под пропущенной-прибыльной зоной */
.bp-zdetail { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 6px 10px 8px 27px; border-top: 1px dashed rgba(210,153,34,.35);
  background: rgba(210,153,34,.05); font-family: var(--mono); font-size: 11px; }
.bp-zd-txt { flex: 1 1 180px; min-width: 0; color: var(--muted); line-height: 1.5; }
.bp-zd-txt b { color: var(--yellow); font-weight: 700; }
.bp-force { flex: 0 0 auto; padding: 3px 10px; border-radius: 6px; font: inherit; cursor: pointer;
  background: rgba(248,81,73,.12); border: 1px solid rgba(248,81,73,.5); color: #ff9c95; }
.bp-force:hover { background: rgba(248,81,73,.22); border-color: var(--red); }
.bp-force[disabled] { opacity: .55; cursor: default; }

/* ---- batch progress: 70vh + sticky-верх, скролл только у списка/«Проблем» ---- */
.modal-box.bp-modal { max-height: 70vh; }
/* C1 (13/07): flex-direction:column забыт здесь — .modal-body по умолчанию
   row, поэтому единственный ребёнок .bp (flex:1 1 auto) считался ROW-флекс-
   айтемом: automatic minimum size (min-width:auto) floor'ил его ШИРИНУ по
   max-content самого длинного nowrap-текста внутри (имя сайта/зоны/кампании),
   раздувая .bp/.bp-camp/.bp-zone до сотен лишних px, ломая text-overflow:
   ellipsis у длинных названий и путая построчную раскладку (второй ряд зоны
   визуально наезжал на заголовок кампании — Игорь 13/07). .bp уже нёс
   min-height:0 в расчёте на column — только сам column и не был объявлен. */
.modal-box.bp-modal .modal-body { display: flex; flex-direction: column; overflow: hidden; flex: 1 1 auto; min-height: 0; padding: 12px 14px; }
.modal-box.bp-modal .bp { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.bp-top { flex: 0 0 auto; }
.modal-box.bp-modal .bp-zones { flex: 1 1 auto; min-height: 0; max-height: none; }

/* ---- batch progress: компактный режим (>20 целей) ---- */
.bp-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 2px 0 10px; }
.bp-tile { display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 7px 4px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel2); }
.bp-tile-n { font-size: 17px; font-weight: 700; font-family: var(--mono); color: var(--text); line-height: 1.1; }
.bp-tile-l { font-size: 10px; color: var(--muted); white-space: nowrap; }
.bp-tile.is-ok .bp-tile-n { color: var(--green); }
.bp-tile.is-warn .bp-tile-n { color: var(--yellow); }
.bp-tile.is-bad .bp-tile-n { color: var(--red); }
.bp-tile.is-zero { opacity: .42; }

.bp-camps { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; }
.bp-cchip { display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
  padding: 2px 8px; border-radius: 999px; font-size: 11px; font-family: var(--mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-cchip b { font-weight: 700; flex: 0 0 auto; }
.bp-cchip.is-queued { background: rgba(139,148,158,.14); color: var(--muted); }
.bp-cchip.is-run { background: rgba(88,166,255,.16); color: var(--blue); }
.bp-cchip.is-ok { background: rgba(63,185,80,.16); color: var(--green); }
.bp-cchip.is-bad { background: rgba(248,81,73,.16); color: var(--red); }
.bp-cchip.is-warn { background: rgba(210,153,34,.16); color: var(--yellow); }

.bp-now { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-bottom: 9px; }
.bp-now b { color: var(--text); }

.bp-probs-h { position: sticky; top: 0; z-index: 1; background: var(--panel);
  padding: 2px 0 6px; font-weight: 700; font-size: 12px; color: var(--red); }
.bp-empty { font-size: 12px; color: var(--muted); padding: 6px 2px; }

/* ---- BL-оптимизатор (модал-отчёт кнопки «⚙ Оптимизировать») ---- */
.blopt { font-size: 13px; }
.blopt-clean { color: var(--green); font-weight: 700; font-size: 14px; }
.blopt-cat { border: 1px solid var(--border); border-radius: 8px; background: var(--panel2);
  padding: 8px 10px; margin-bottom: 8px; }
.blopt-cat-h { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; }
.blopt-cat-h input { margin-top: 2px; flex: 0 0 auto; cursor: pointer; }
.blopt-cat-t { font-weight: 600; line-height: 1.4; }
.blopt-cat-t b { font-family: var(--mono); color: var(--blue); }
.blopt-cat-d { color: var(--muted); font-size: 12px; line-height: 1.5; margin: 5px 0 0 24px; }
/* 18/07: «показать список» — чип-пилюля (.snz-chip-язык) с поворотным шевроном. */
.blopt-list { margin: 6px 0 0 24px; }
.blopt-list > summary {
  cursor: pointer; font-size: 12px; color: var(--muted);
  list-style: none; user-select: none;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 10px;
}
.blopt-list > summary:hover { color: var(--text); border-color: var(--muted); }
.blopt-list[open] > summary {
  color: var(--text); border-color: rgba(88,166,255,.45); background: rgba(88,166,255,.08);
}
.blopt-list > summary::-webkit-details-marker { display: none; }
.blopt-list > summary::before {
  content: '▸'; font-size: 9px; color: var(--muted);
  display: inline-block; transition: transform .15s ease;
}
.blopt-list[open] > summary::before { transform: rotate(90deg); }
.blopt-rows { max-height: 34vh; overflow: auto; display: flex; flex-direction: column;
  gap: 2px; margin-top: 4px; }
.blopt-row { display: flex; align-items: baseline; gap: 8px; padding: 3px 6px;
  border-bottom: 1px solid rgba(42,48,56,.55); font-family: var(--mono); font-size: 11px; }
.blopt-row:last-child { border-bottom: 0; }
.blopt-zid, .blopt-host { color: var(--text); flex: 0 0 auto; }
.blopt-host { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 45%; }
.blopt-zmeta { color: var(--muted); flex: 0 0 auto; }
.blopt-zspend { color: var(--muted); margin-left: auto; flex: 0 0 auto; white-space: nowrap; }
.blopt-pl { margin-left: auto; flex: 0 0 auto; white-space: nowrap; }
.blopt-pl.pos { color: var(--green); }
.blopt-pl.neg { color: var(--red); }
.blopt-row .badge { flex: 0 0 auto; }
.blopt-total { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
  font-size: 13px; }
.blopt-total b { font-family: var(--mono); color: var(--green); font-size: 15px; }
.blopt-total .note { display: inline; margin: 0; }

/* ---- journal (#/j) ---- */
.journal { border: 1px solid var(--border); border-radius: 8px; background: var(--panel); overflow: hidden; }
.jbatch { border-bottom: 1px solid var(--border); }
/* 18/07: batch-заголовок — шеврон-квадратик с поворотом (язык .opt-sec);
   inline-flex, а не flex-шапка: текст summary — смешанные инлайн-куски. */
.jbatch > summary {
  cursor: pointer; padding: 6px 10px; font-size: 12px; background: var(--panel2);
  list-style: none; user-select: none;
}
.jbatch > summary::-webkit-details-marker { display: none; }
.jbatch > summary::before {
  content: '▸'; display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 5px; font-size: 9px; line-height: 1;
  vertical-align: -3px; margin-right: 7px;
  color: var(--muted); background: var(--panel); border: 1px solid var(--border);
  transition: transform .15s ease;
}
.jbatch[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
.jrow {
  display: flex; gap: 8px; align-items: baseline; padding: 5px 10px;
  border-bottom: 1px solid var(--border); font-family: var(--mono);
  font-size: 12px; min-width: 0; flex-wrap: wrap;
}
.jrow.expandable { cursor: pointer; }
.jbatch .jrow { padding-left: 20px; }
.jrow .ts { color: var(--muted); white-space: nowrap; }
.jrow .jkind { white-space: nowrap; }
/* Task 3 (16/07): человеческая строка Журнала — своя строка, перенос по словам
   (та же причина, что у .act .reason — полное предложение не должно резаться
   многоточием). */
.jrow .reason { color: var(--muted); flex: 1 1 100%; min-width: 60px; overflow: hidden; white-space: normal; word-break: break-word; }
.jrow .jundo { margin-left: auto; }

/* ---- mobile ---- */
@media (max-width: 640px) {
  .cols { grid-template-columns: 1fr; }
  .modal-box { width: 100%; }
}
@media (max-width: 480px) {
  #topbar { padding: 4px 6px; gap: 6px; flex-wrap: wrap; }
  .brand { font-size: 13px; }
  #nav { order: 3; width: 100%; }
  #nav a { padding: 4px 8px; font-size: 12px; }
  #view { padding: 8px; }
  h2.scr-h, .camp-head h2, .v2-phead h2 { font-size: 17px; }
  .cards { grid-template-columns: 1fr 1fr; gap: 6px; }
  .card { padding: 8px; }
  .card .big { font-size: 17px; }
  .chart-panel { height: 180px; }
  .tablewrap { max-height: 65vh; }
  .tbl th, .tbl td { padding: 4px 6px; font-size: 11px; }
  .act { flex-wrap: wrap; }
  .act .reason { flex-basis: 100%; }
  .hide-m { display: none; }
  .opt-cards { grid-template-columns: 1fr; }
  .tbl td.rsn { max-width: 160px; }
  .why-body { max-width: 150px; }
  .bid-rec, .bid-edit { gap: 6px; padding: 8px; }
  .bid-rec .bid-rec-apply, .bid-edit .ba-apply { margin-left: 0; flex-basis: 100%; }
  /* редизайн 17/07: корзины/секции на телефоне (деньги на второй ряд —
     уже сработало на брейкпоинте 980) */
  .opt-basket > summary { padding: 8px 10px; gap: 2px 10px; min-height: 46px; }
  .bk-icon { width: 26px; height: 26px; font-size: 13px; border-radius: 7px; }
  .bk-title { font-size: 13.5px; }
  .bk-q { font-size: 11px; }
  .bk-body { padding: 8px 8px 10px; }
  .opt-sec[open], .spl-sec[open] { padding: 0 6px 8px; }
  .opt-sec[open] > summary, .spl-sec[open] > summary { margin: 0 -6px 8px; }
  .opt-sec > summary, .spl-sec > summary { font-size: 13px; gap: 6px; }
  /* мета секции — своей строкой, не зажимает название */
  .sec-meta { flex-basis: 100%; margin-left: 26px; text-align: left; max-width: none; order: 9; }
  .opt-tbl a.camp-link { max-width: 13ch; }
  .zsub { max-width: 110px; }
  .reason-chip { max-width: 20ch; }
  .snz-sub { display: none; } /* чипы отложенных — только иконка+счётчик */
}

/* ---- очередь «Оптимизация»: колонки-периоды 7/30/90 + разворот причины ----
   Редизайн 17/07: ячейка периода = 2 строки (P&L+ROI жирным сверху, «трата ·
   прод» приглушённо ниже) — строки ниже на треть, колонки уже; деньги вперёд.
   18/07: «Чемпионы» приведены к той же 2-строчной ячейке. */
.opt-tbl thead tr.grp th { border-bottom: none; }
.opt-tbl thead tr.grp th.perc { border-left: 1px solid var(--border); text-align: center;
  font-size: 11px; color: var(--muted); }
.opt-tbl th.perc { text-align: right; }
td.exp, .opt-tbl th.exp { width: 22px; text-align: center; color: var(--muted);
  cursor: pointer; user-select: none; }
td.exp:hover { color: var(--text); }
td.per { border-left: 1px solid var(--border); min-width: 68px; white-space: nowrap;
  text-align: right; vertical-align: middle; padding-top: 5px; padding-bottom: 5px; }
/* .c (старая 3-строчная стопка) удалён 18/07 — последний носитель («Чемпионы»)
   приведён к канонической 2-строчной ячейке (.p сверху, .s ниже). */
td.per .s { font-size: 10.5px; color: var(--muted); font-family: var(--mono);
  margin: 1px 0 0; line-height: 1.3; }
td.per .p { font-family: var(--mono); font-size: 12.5px; font-weight: 700; line-height: 1.25; }
/* ROI инлайн рядом с P&L строки очереди (14/07) — приглушённее самого P&L,
   цвет наследуется от родителя .p (pnCls), не задаём свой. */
.roi-inline { font-size: 11px; font-weight: 400; opacity: .85; }
td.per .pm, .ztt .pm { color: var(--muted); font-family: var(--mono); }
/* Имя кампании в таблицах очереди — не даёт раздувать колонку (полное — в title). */
.opt-tbl a.camp-link { display: inline-block; max-width: 22ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
/* Бейдж «⚠ BL N/4000» — блоком под именем кампании, не в ширину колонки. */
.opt-tbl td .bl-fill { display: block; width: fit-content; margin: 2px 0 0; }
/* Лёгкая зебра пар (строка+скрытый detail ⇒ шаг 4). :where — нулевая
   специфичность: подсветки hl-строк / gt-row / hover всегда сильнее.
   retest-tbl без detail-пар — исключена (шаг сбился бы). 18/07: + пары вне
   opt-tbl — детектор доменов (domblk-tbl) и «Понижение» Ставок (#bidsDownTbl).
   ФИКС 18/07: в прежнем тексте комментария «hl-звёздочка-слэш» досрочно
   закрывал комментарий — мусор съедал само правило зебры, оно НЕ работало. */
:where(.opt-tbl:not(.retest-tbl) tbody tr:nth-child(4n+3),
  .domblk-tbl tbody tr:nth-child(4n+3),
  #bidsDownTbl tbody tr:nth-child(4n+3)) { background: rgba(255,255,255,.018); }
.zid { cursor: pointer; color: var(--text); border-bottom: 1px dashed var(--muted); }
.zid:hover { color: var(--blue); border-bottom-color: var(--blue); }
/* колонка «весь аккаунт / 90д» — account-wide цифра зоны (та же, что в карточке).
   Отделена акцентной левой границей + лёгким фоном, чтобы не спутать с текущей
   кампанией. Заголовок группы — акцентным цветом. */
.opt-tbl thead tr.grp th.grp-acct { border-left: 2px solid var(--blue);
  color: var(--blue); font-weight: 600; }
.opt-tbl th.acct, td.per.acct { border-left: 2px solid var(--blue);
  background: rgba(90, 150, 240, .06); }
/* метка «прибыльна по аккаунту» на account-плюсовой строке (обычно per-campaign
   czf: течёт здесь, но в плюсе по аккаунту) — приглушённо-зелёная, мелкая. */
td.per.acct .acct-prof { color: var(--green); font-size: 10px; margin-top: 2px;
  white-space: normal; line-height: 1.1; }
/* свёрнутая global_trash строка «блок везде» (одна зона × N кампаний): лёгкий
   акцентный фон, чтобы визуально отличалась от построчных per-campaign строк. */
tr.gt-row > td { background: rgba(88, 166, 255, .05); }
/* B2 (13/07): строка «Движок пропускает», чью карточку зоны уже открывали
   («в работе» — действие начато, ещё не закончено) — приглушаем, чтобы
   отличалась от нетронутых строк, но не терялась совсем (успешный блок
   убирает строку целиком, это — промежуточное состояние). */
tr.missed-seen > td { opacity: .6; }
.gt-camps { color: var(--muted); font-size: 12px; border-bottom: 1px dashed var(--muted);
  cursor: help; }
/* секция ① «Мусор — блок везде» (trash-tbl): свои колонки (зона · причина ·
   N кампаний · весь аккаунт), «эта кампания» нет — колонка «кампаний» числовая. */
.opt-tbl.trash-tbl th.num, .opt-tbl.trash-tbl td.num { text-align: right;
  white-space: nowrap; }
.opt-tbl.trash-tbl td.num { color: var(--text); }
/* адаптив: широкий монитор — все 3 периода; ноут — прячем 90д; телефон — и 30д
   (остаётся 7д, полное — по «▸» или в карточке зоны). Колонку «весь аккаунт»
   НЕ прячем — она главная (по одной кампании судить нельзя).
   Групповой заголовок «эта кампания» имеет три colspan-варианта (gc3/gc2/gc1):
   на каждом брейкпоинте видим тот, чей colspan = числу видимых периодов. Иначе
   фикс. colspan=3 считает скрытые (display:none) 30д/90д → «весь аккаунт»
   наезжает на «эта кампания» (баг 12/07, чинилось визуально). */
.opt-tbl thead tr.grp th.gc2, .opt-tbl thead tr.grp th.gc1 { display: none; }
/* Брейкпоинты подняты 17/07 (1100→1280, 820→1024): периоды прячутся раньше,
   чтобы «весь аккаунт» оставался виден без скролла на ноуте. */
@media (max-width: 1280px) {
  .opt-tbl .d90 { display: none; }
  .opt-tbl thead tr.grp th.gc3 { display: none; }
  .opt-tbl thead tr.grp th.gc2 { display: table-cell; }
}
@media (max-width: 1024px) {
  .opt-tbl .d30 { display: none; }
  .opt-tbl thead tr.grp th.gc2 { display: none; }
  .opt-tbl thead tr.grp th.gc1 { display: table-cell; }
}

/* ---- карточка зоны (drawer справа) ---- */
.zscrim { position: fixed; inset: 0; background: rgba(0, 0, 0, .5); z-index: 250; display: none; }
.zscrim.on { display: block; }
.zdrawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(860px, 92vw);
  background: var(--panel); border-left: 1px solid var(--border); z-index: 251;
  transform: translateX(100%); transition: transform .18s ease; overflow: auto; padding: 18px 22px; }
.zdrawer.on { transform: none; }
.zdrawer h3 { margin: 0 0 2px; font-size: 15px; color: var(--text);
  text-transform: none; letter-spacing: 0; }
.zdsub { color: var(--muted); font-size: 12px; }
.zdclose { position: absolute; top: 12px; right: 14px; background: none; border: 0;
  color: var(--muted); font-size: 17px; cursor: pointer; line-height: 1; }
.zdclose:hover { color: var(--text); }
/* 18/07: секционные подписи дровера — язык opt-h3 (акцент-бар 13.5), вместо
   мелкого uppercase-шёпота. */
.zdlabel { margin: 16px 0 6px; font-size: 13.5px; font-weight: 700; color: var(--text);
  text-transform: none; letter-spacing: 0; padding-left: 10px;
  border-left: 3px solid var(--blue); line-height: 1.35; }
.ztt { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ztt .cell { background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px; }
.ztt .k { color: var(--muted); font-size: 11px; }
.ztt .cst { font-family: var(--mono); font-size: 12px; color: var(--muted); margin: 4px 0 2px; }
.ztt .pl { font-family: var(--mono); font-size: 15px; font-weight: 700; }
/* ROI зоны/домена (14/07, жалоба Игоря «не вижу ROI в панели») — под P&L,
   тот же mono-шрифт, чуть мельче (P&L остаётся главной цифрой плитки). */
.ztt .roi { font-family: var(--mono); font-size: 12px; margin-top: 1px; }
.ztt .sm { color: var(--muted); font-size: 11px; }
.zspark { width: 100%; height: 96px; background: var(--panel2); border: 1px solid var(--border);
  border-radius: 8px; display: block; }
.zspark-zero { stroke: var(--border); stroke-dasharray: 3 3; }
.xtbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.xtbl th, .xtbl td { padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: right; }
.xtbl th.l, .xtbl td.l { text-align: left; }
.xtbl th { color: var(--muted); font-weight: 600; }
.xtbl th.ck, .xtbl td.ck { width: 22px; padding: 6px 4px; text-align: center; }

/* ---- BL: кликабельные бейджи + разворот «что заблок./разблок. сегодня» ---- */
.bl-badge { cursor: pointer; border-bottom: 1px dotted currentColor; }
.bl-badge:hover { filter: brightness(1.2); }
tr.bl-detail-row > td { background: var(--panel2); padding: 10px 14px 12px;
  border-bottom: 2px solid var(--border); }
.bl-td-sec { margin: 0 0 14px; }
.bl-td-sec:last-child { margin-bottom: 0; }
.bl-td-h { font-weight: 600; font-size: 12px; color: var(--text); margin: 0 0 6px; }
.bl-td-hint { margin: 0 0 6px; }
.bl-td-tbl { max-width: 900px; }
.bl-td-tbl td, .bl-td-tbl th { padding: 5px 8px; }
.bl-td-ts { color: var(--muted); font-family: var(--mono); white-space: nowrap; }
.bl-td-dim { color: var(--muted); }
.bl-td-ids { display: flex; flex-wrap: wrap; gap: 5px; }
.bl-td-id, .bl-td-host { font-family: var(--mono); font-size: 12px; padding: 2px 7px;
  border-radius: 4px; background: var(--panel); border: 1px solid var(--border); }
.bl-td-id { color: var(--muted); }

.zcamp-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
.zcamp-bar label { color: var(--muted); font-size: 12px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
/* Состояние «блокировать нечего» вместо активного бара блока (precheck, 0 целей). */
.zcamp-empty { padding: 6px 10px; border: 1px dashed var(--muted); border-radius: 6px; }
.zcamp-empty .note { margin: 0; }

/* ---- Креативы v3 (#/creatives): сводка, очереди, библиотека, галерея, drawer ---- */

/* Полоса-сводка — кликабельные счётчики решений */
.cre-sumbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 14px; }
.cre-sc { display: inline-flex; align-items: center; gap: 5px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 11px; cursor: pointer;
  color: var(--muted); font: inherit; font-size: 12px; transition: border-color .12s, background .12s; }
.cre-sc:hover { border-color: var(--muted); background: var(--panel2); }
.cre-sc b { color: var(--text); font-family: var(--mono); font-size: 14px; }
.cre-sc-sub { color: var(--muted); font-size: 11px; font-family: var(--mono); }
.cre-sc.warn { border-left: 3px solid var(--red); }

/* Очереди решений (details, раскрыты непустые) */
.cre-queues { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
details.cre-q { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; }
.cre-q.cre-q-scale { border-left: 3px solid var(--green); }
.cre-q.cre-q-kill { border-left: 3px solid var(--red); }
.cre-q.cre-q-refresh { border-left: 3px solid var(--yellow); }
.cre-q.cre-q-switch_offer { border-left: 3px solid var(--blue); }
/* 18/07: очередь — секция в языке .opt-sec (шеврон-квадратик, поворот 90°,
   открытая отделена линией); цветной левый борт решения остаётся. */
details.cre-q > summary { cursor: pointer; list-style: none; padding: 9px 11px;
  font-size: 13.5px; font-weight: 700; color: var(--text);
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
details.cre-q > summary::-webkit-details-marker { display: none; }
details.cre-q > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
details.cre-q[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
details.cre-q[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: 8px; }
details.cre-q > summary:hover { background: rgba(255,255,255,.025); border-radius: 10px; }
.cre-q summary b { font-family: var(--mono); color: var(--muted); margin-left: 2px; }
.cre-qlist { display: flex; flex-direction: column; gap: 6px; padding: 0 9px 9px; }
.cre-qempty { padding: 0 11px 10px; }
.cre-qrow { display: flex; gap: 10px; align-items: flex-start; padding: 6px 7px;
  background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; }
.cre-qthumb-wrap { width: 40px; height: 40px; flex: none; border-radius: 6px; overflow: hidden;
  background: var(--bg); cursor: pointer; }
.cre-qthumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.cre-qthumb.cre-noimg { width: 40px; height: 40px; font-size: 8px; padding: 2px; }
.cre-qbody { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; }
.cre-qwhy { font-size: 12px; color: var(--text); line-height: 1.4;
  overflow-wrap: anywhere; word-break: break-word; }
.cre-qflags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cre-qact { flex: none; align-self: center; }
.cre-qmore { align-self: flex-start; margin-top: 2px; }
.cre-qsub { color: var(--muted); font-weight: 400; font-size: 11px; font-family: var(--mono); }

/* Карточка креатива в очередях scale/kill: одна картинка = одна карточка, цели/
   кампании — переносящимися чипами. Превью 56px (клик → drawer). Кнопка действия
   на узком экране (телефон) переносится под карточку. */
.cre-gcard { align-items: flex-start; flex-wrap: wrap; }
.cre-gcard > .cre-qbody { min-width: 180px; }
.cre-gcard > .cre-qact { align-self: center; margin-left: auto; }
.cre-gthumb { width: 56px; height: 56px; }
.cre-gthumb .cre-qthumb.cre-noimg, .cre-gthumb > .cre-noimg { width: 100%; height: 100%; }
.cre-gtitle { font-size: 12px; color: var(--text); line-height: 1.5; }
.cre-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.cre-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
  padding: 2px 4px 2px 8px; border-radius: 14px; background: var(--panel);
  border: 1px solid var(--border); white-space: nowrap; }
.cre-chip.warn { border-color: rgba(248,81,73,.5); }
.cre-chip.bad { border-color: rgba(248,81,73,.35); background: rgba(248,81,73,.06); }
.cre-chip-lang { font-family: var(--mono); color: var(--muted); font-size: 10px; text-transform: uppercase; }
.cre-chip-name { color: var(--text); max-width: 170px; overflow: hidden;
  text-overflow: ellipsis; }
.cre-chip-lift { font-family: var(--mono); font-size: 10px; }
.cre-chip-lift.pos { color: var(--green); }
.cre-chip-lift.nobench { color: var(--muted); }
.cre-chip-loss { font-family: var(--mono); color: var(--red); font-size: 10px; }
.cre-chip .btn.xs { padding: 0 6px; line-height: 18px; margin-left: 1px; }
/* Кросс-языковые цели (B20): рамка/фон голубым, глобус-язык, бейдж источника
   текстов вместо лифта. */
.cre-chip.xlang { border-color: rgba(88,166,255,.45); background: rgba(88,166,255,.07); }
.cre-chip.xlang .cre-chip-lang { color: var(--blue); text-transform: none; }
.cre-chip-tsrc { font-family: var(--mono); font-size: 10px; white-space: nowrap; }
.cre-chip-tsrc.reused { color: var(--green); }
.cre-chip-tsrc.venice { color: var(--yellow); }
/* Task 1 (16/07): рекомендация уже выполнена сегодня (дневной оверлей журнала) —
   строка приглушена, стрелка-кнопка копии заменена бейджем «✓ сделано сегодня». */
.cre-chip.applied { opacity: .55; }
.cre-chip-applied { font-size: 10px; color: var(--green); white-space: nowrap; }
/* Подзаголовок-разделитель кросс-языковых чипов: занимает всю ширину (перенос),
   отделяет цели своего языка от клонов с переводом. */
.cre-chips-xhead { flex-basis: 100%; margin: 3px 0 0; font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .4px; }
/* Confirm-модал кросс-языковой копии */
.cre-xnote { color: var(--blue); }
.cre-xconfirm { border-left: 2px solid rgba(88,166,255,.4); padding-left: 8px; }

/* Библиотека — таблица rollup + разворот per-campaign */
.cre-lib { margin-top: 6px; }
.cre-lib-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
/* 18/07: заголовок библиотеки — панельный уровень шкалы (15/800, без uppercase). */
.cre-lib-head h3 { margin: 0; font-size: 15px; font-weight: 800; color: var(--text);
  text-transform: none; letter-spacing: 0; }
.cre-controls { flex-wrap: wrap; }
.cre-ltbl td { vertical-align: middle; }
.cre-lx { white-space: nowrap; }
.cre-xt { display: inline-block; width: 14px; color: var(--muted); cursor: pointer;
  user-select: none; margin-right: 4px; }
.cre-xt:hover { color: var(--text); }
.cre-lspark { min-width: 100px; }
.cre-loffers { max-width: 210px; }
.cre-llangs { color: var(--muted); max-width: 120px; overflow: hidden; text-overflow: ellipsis; }
.cre-lsub > td { padding: 0 !important; background: var(--panel2); }
.cre-subwrap { padding: 4px 8px 8px 46px; overflow-x: auto; }
.cre-subtbl { width: 100%; }
.cre-subtbl th { color: var(--muted); font-weight: 600; }
.cre-lfoot td { background: var(--panel2); font-weight: 700; }
.cre-foot-note { color: var(--muted); font-weight: 400; font-size: 11px; }
.cre-dash { color: var(--muted); }

/* Спарклайн profit 14д (SVG, zero-line) + колонка CTR-спарклайна матрицы */
.cre-spark14 { width: 90px; height: 22px; display: block; }
.cre-spark-zero { stroke: var(--muted); stroke-width: .6; stroke-dasharray: 2 2; opacity: .55; }
.cre-spark-th { white-space: nowrap; }
.cre-spark-cell { min-width: 92px; vertical-align: middle; }
.cre-spark-cell .var-spark { width: 88px; height: 20px; }

/* Компакт-сводка вердиктов (цвет фона по dominant) */
.cre-vsum { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center;
  padding: 1px 6px; border-radius: 12px; font-size: 11px; }
.cre-vsum .vt { font-family: var(--mono); white-space: nowrap; }
.cre-vsum.dom-kill { background: rgba(248,81,73,.12); }
.cre-vsum.dom-switch_offer { background: rgba(88,166,255,.12); }
.cre-vsum.dom-refresh { background: rgba(210,153,34,.14); }
.cre-vsum.dom-scale { background: rgba(63,185,80,.12); }
.cre-vsum.dom-keep { background: rgba(63,185,80,.07); }
.cre-vsum.dom-learning { background: rgba(139,148,158,.12); }

/* Бейдж одного вердикта (ячейка/матрица) */
.cre-vb { display: inline-block; font-size: 10px; font-weight: 700; padding: 1px 6px;
  border-radius: 20px; white-space: nowrap; }
.cre-vb.v-kill { background: rgba(248,81,73,.15); color: var(--red); }
.cre-vb.v-switch { background: rgba(88,166,255,.15); color: var(--blue); }
.cre-vb.v-refresh { background: rgba(210,153,34,.18); color: var(--yellow); }
.cre-vb.v-scale { background: rgba(63,185,80,.15); color: var(--green); }
.cre-vb.v-keep { background: rgba(63,185,80,.10); color: var(--green); }
.cre-vb.v-learning { background: rgba(139,148,158,.15); color: var(--muted); }

/* ×пиры (EPC к медиане) */
.cre-vs { font-family: var(--mono); color: var(--muted); white-space: nowrap; }
.cre-vs.pos { color: var(--green); }
.cre-vs.neg { color: var(--red); }

/* Офферы-чипы (цвет по качеству strong/weak/unknown) */
.cre-ochip { display: inline-block; font-size: 10px; padding: 1px 7px; border-radius: 12px;
  white-space: nowrap; border: 1px solid transparent; }
.oq-strong { background: rgba(63,185,80,.14); color: var(--green); border-color: rgba(63,185,80,.35); }
.oq-weak { background: rgba(248,81,73,.14); color: var(--red); border-color: rgba(248,81,73,.35); }
.oq-unknown { background: rgba(139,148,158,.14); color: var(--muted); border-color: rgba(139,148,158,.3); }
.cre-ochip-link { cursor: pointer; }
.cre-ochip-link:hover, .cre-ochip-link:focus-visible { filter: brightness(1.25); outline: none; text-decoration: underline; }

/* F27: секция «Покрытие офферов» */
details.cre-cov { background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  border-left: 3px solid var(--blue); margin: 10px 0; }
/* 18/07: секционный язык (шеврон-квадратик + отделённая шапка при open). */
details.cre-cov > summary { cursor: pointer; list-style: none; padding: 9px 11px;
  font-size: 13.5px; font-weight: 700; color: var(--text); user-select: none;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
details.cre-cov > summary::-webkit-details-marker { display: none; }
details.cre-cov > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
details.cre-cov[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
details.cre-cov[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: 8px; }
details.cre-cov > summary:hover { background: rgba(255,255,255,.025); border-radius: 10px; }
.cre-cov > summary b { font-family: var(--mono); color: var(--blue); }
.cov-hint { padding: 0 11px; margin: 2px 0 8px; }
.cov-langseg { margin: 0 11px 10px; }
.cov-lang-btn { background: none; border: none; color: var(--muted); padding: 4px 11px;
  cursor: pointer; font-size: 12px; font-family: inherit; }
.cov-lang-btn + .cov-lang-btn { border-left: 1px solid var(--border); }
.cov-lang-btn.on { background: var(--panel2); color: var(--text); font-weight: 700; }
.cov-lang-btn b { font-family: var(--mono); color: var(--yellow); margin-left: 3px; font-size: 10px; }
.cov-grouplbl { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px;
  padding: 0 11px; margin: 4px 0 5px; }
.cov-nogaps { padding: 0 11px 6px; }
/* 18/07: строка-карточка кампании — тот же шеврон-квадратик (16px, вложенный
   уровень), открытая «утоплена». */
details.cov-camp { margin: 0 9px 6px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel2); }
details.cov-camp[open] { background: rgba(0, 0, 0, .14); }
details.cov-camp > summary { cursor: pointer; list-style: none; padding: 7px 9px; }
details.cov-camp > summary::-webkit-details-marker { display: none; }
details.cov-camp > summary::before {
  content: '▸'; display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 5px; font-size: 9px; line-height: 1;
  vertical-align: -3px; margin-right: 6px;
  color: var(--muted); background: var(--panel); border: 1px solid var(--border);
  transition: transform .15s ease;
}
details.cov-camp[open] > summary::before {
  transform: rotate(90deg); color: var(--blue); border-color: rgba(88,166,255,.45);
}
details.cov-camp[open] > summary { border-bottom: 1px solid var(--border); }
.cov-camp-h { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; width: calc(100% - 18px); }
.cov-camp-meta { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.cov-camp-meta b { color: var(--text); }
.cov-camp-meta .cov-gapn { color: var(--yellow); }
.cov-camp-act { margin-left: auto; display: inline-flex; gap: 4px; align-items: center; }
.cov-gaps { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 9px 9px; }
.cov-gap { display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
  border: 1px solid var(--border); border-radius: 14px; padding: 2px 4px 2px 2px; background: var(--panel); }
.cov-gap-nc { opacity: .75; }
.cov-gap .cov-q { color: var(--muted); font-size: 9px; }
.cov-nocarrier { color: var(--muted); font-size: 10px; padding: 0 6px; font-style: italic; }
.cov-gap .btn.xs { padding: 1px 7px; }
/* 18/07: вторичные списки — чипы-пилюли в языке .snz-chip (открытый чип
   подсвечен синим), а не безликие гармошки. */
details.cov-full, details.cov-spec { margin: 6px 9px 8px; }
details.cov-full > summary, details.cov-spec > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted);
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 12px;
}
details.cov-full > summary::-webkit-details-marker, details.cov-spec > summary::-webkit-details-marker { display: none; }
details.cov-full > summary:hover, details.cov-spec > summary:hover { color: var(--text); border-color: var(--muted); }
details.cov-full[open] > summary, details.cov-spec[open] > summary {
  color: var(--text); border-color: rgba(88,166,255,.45); background: rgba(88,166,255,.08);
}
details.cov-full > summary::before, details.cov-spec > summary::before {
  content: '▸'; font-size: 9px; color: var(--muted);
  display: inline-block; transition: transform .15s ease;
}
details.cov-full[open] > summary::before, details.cov-spec[open] > summary::before { transform: rotate(90deg); }
.cov-list { padding: 2px 9px 8px; display: flex; flex-direction: column; gap: 3px; }
.cov-listrow { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.cov-listmeta { font-family: var(--mono); font-size: 11px; color: var(--muted); margin-left: auto; }
.cov-listrow .cov-src { margin-left: auto; }
.cov-drbylang { margin: 0 0 4px; display: flex; flex-wrap: wrap; gap: 3px; }
.cov-cre-thumb { cursor: pointer; }

/* Пометка «выгорает у донора» / предупреждения */
.cre-caution { font-size: 10px; color: var(--yellow); white-space: nowrap; }
.cre-warn { color: var(--yellow); }
.cre-fire-inline { font-size: 11px; white-space: nowrap; }

/* Галерея групп */
.cre-grid { display: grid; gap: 12px; margin-top: 10px;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.cre-card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; cursor: pointer; transition: border-color .12s; }
.cre-card:hover, .cre-card:focus-visible { border-color: var(--muted); outline: none; }
.cre-thumb-wrap { position: relative; aspect-ratio: 1 / 1; background: var(--panel2); }
.cre-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.cre-noimg { display: flex; align-items: center; justify-content: center; text-align: center;
  color: var(--muted); font-size: 11px; background: var(--panel2); padding: 8px; }
.cre-thumb.cre-noimg { width: 100%; height: 100%; }
.cre-domb { position: absolute; top: 6px; right: 6px; background: rgba(13,17,23,.82);
  font-size: 12px; padding: 2px 6px; border-radius: 20px; border: 1px solid var(--border); }
.cre-card-body { padding: 8px 9px; }
.cre-card-vsum { margin-bottom: 4px; }
.cre-pl { font-family: var(--mono); font-size: 15px; font-weight: 700; }
.cre-sub { color: var(--muted); font-size: 11px; margin-top: 2px; }
.cre-coffers { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 3px; }

/* Переключатель [Таблица|Галерея] (базовый .seg) + тумбнейл 40px строки таблицы */
.cre-viewseg { margin-left: 4px; }
.cre-tthumb-wrap { display: inline-block; width: 40px; height: 40px; border-radius: 6px;
  overflow: hidden; background: var(--bg); vertical-align: middle; }
.cre-tthumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.cre-tthumb.cre-noimg { width: 40px; height: 40px; font-size: 8px; padding: 2px; }

/* Drawer группы (переиспользует .zdrawer/.zscrim) */
.cre-big-wrap { text-align: center; background: var(--panel2); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px; margin: 4px 0 6px; }
.cre-big { max-width: 100%; max-height: 340px; border-radius: 6px; display: inline-block; }
.cre-big.cre-noimg { min-height: 120px; }
.cre-dr-sum { margin: 8px 0 2px; }
.cre-dr-money { font-family: var(--mono); font-size: 12px; margin-bottom: 6px;
  line-height: 1.5; overflow-wrap: anywhere; }
.cre-texts { display: flex; flex-direction: column; gap: 6px; }
.cre-text { background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; }
.cre-t-title { font-size: 13px; color: var(--text); font-weight: 600; }
.cre-t-desc { font-size: 12px; color: var(--muted); margin-top: 2px; }
.cre-t-brand { font-size: 11px; color: var(--muted); margin-top: 3px; }
/* Блок «Офферы группы» (чипы + качество по языкам) */
.cre-oblk { display: flex; flex-direction: column; gap: 5px; }
.cre-orow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12px; }
.cre-obylang { display: inline-flex; flex-wrap: wrap; gap: 3px; }
.cre-olang { font-size: 10px; padding: 0 5px; border-radius: 8px; }
.cre-osum { color: var(--muted); }
/* График «по каждой кампании» (F16) — контролы + панель (.chart-panel задаёт высоту) */
.cre-series-ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 2px 0 8px; }
.cre-series-ctl .seg button { font-size: 11px; padding: 3px 8px; }
.cre-series-panel { margin-bottom: 4px; }

/* ---- Лайтбокс полноразмерной картинки ---- */
.imglb { position: fixed; inset: 0; background: rgba(0, 0, 0, .82); z-index: 400;
  display: none; align-items: center; justify-content: center; cursor: zoom-out; padding: 24px; }
.imglb.on { display: flex; }
.imglb img { max-width: 96vw; max-height: 92vh; border-radius: 6px; }
/* ---- Вкладка «Вариации» карточки: тумбнейл, тексты, бейджи, спарклайн ---- */
.var-cell { min-width: 160px; }
.var-main { display: flex; align-items: flex-start; gap: 8px; }
.var-thumb-mini { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; flex: none;
  background: var(--panel2); border: 1px solid var(--border); cursor: zoom-in; }
.var-thumb-mini.cre-noimg { width: 44px; height: 44px; font-size: 9px; }
.var-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.var-trend { color: var(--blue); cursor: pointer; font-family: var(--mono); }
.var-trend:hover { text-decoration: underline; }
.var-title { font-size: 12px; color: var(--text); }
.var-brand { font-size: 11px; color: var(--muted); }
.var-badges { display: inline-flex; flex-wrap: wrap; gap: 3px; margin-top: 1px; }
.var-spark-wrap { margin-top: 2px; }
.var-spark { width: 88px; height: 22px; display: block; }

/* ---- Экран «Пороги» (#/thresholds, B22) ---- */
.thr-head { display: flex; flex-direction: column; gap: 6px; }
.thr-toggle-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.thr-toggle-row .note { margin: 0; }
.thr-bt { margin: 10px 0; }
.thr-bt-line { font-size: 13px; line-height: 1.6; }
.thr-bt-line b { color: var(--text); font-family: var(--mono); }
/* 18/07: «разворот по гео» — чип-пилюля вместо нативного маркера. */
.thr-bt-details { margin-top: 8px; }
.thr-bt-details summary {
  cursor: pointer; font-size: 12px; color: var(--muted);
  list-style: none; user-select: none;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 12px;
}
.thr-bt-details summary::-webkit-details-marker { display: none; }
.thr-bt-details summary:hover { color: var(--text); border-color: var(--muted); }
.thr-bt-details[open] summary {
  color: var(--text); border-color: rgba(88,166,255,.45); background: rgba(88,166,255,.08);
}
/* зазор чип→таблица: вертикальный margin на inline-flex summary не работает */
.thr-bt-details[open] .tablewrap { margin-top: 8px; }
.thr-bt-details summary::before {
  content: '▸'; font-size: 9px; color: var(--muted);
  display: inline-block; transition: transform .15s ease;
}
.thr-bt-details[open] summary::before { transform: rotate(90deg); }
/* калибровка сигналов (новые vs текущие) */
.thr-cal { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.thr-cal-head { font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.thr-cal-row { font-size: 12px; line-height: 1.55; display: flex; gap: 8px; flex-wrap: wrap; }
.thr-cal-row + .thr-cal-row { margin-top: 3px; }
.thr-cal-lbl { min-width: 96px; color: var(--text); font-weight: 600; }
.thr-cal-txt { font-family: var(--mono); }
.thr-cal-txt b { color: var(--text); font-family: var(--mono); }
.thr-cal-txt b.pos { color: var(--green); }
.thr-cal-txt b.neg { color: var(--red); }
.thr-tbl th .thr-sub { display: block; font-size: 9px; opacity: .7; font-weight: 400; }
.thr-tbl td { white-space: nowrap; }
/* паспорт-колонка гео залипает слева при горизонтальном скролле 10 метрик */
.thr-tbl thead th.l { position: sticky; left: 0; z-index: 3; }
.thr-tbl tbody td.l { position: sticky; left: 0; z-index: 1; background: var(--panel); }
.thr-tbl tbody tr.thr-fmt-row td.l { background: var(--panel2); }
.thr-val { font-family: var(--mono); font-weight: 700; }
.thr-src { margin-left: 3px; }
.thr-src.thr-dim { opacity: .5; }
.thr-would { font-family: var(--mono); font-size: 11px; color: var(--muted); margin-left: 3px; }
.thr-tier { font-size: 9px; margin-left: 4px; }
.thr-cell.thr-edit { cursor: pointer; }
.thr-cell.thr-edit:hover { background: rgba(88,166,255,.08); }
.thr-cell.has-ov { box-shadow: inset 2px 0 0 var(--yellow); }
.thr-fmt-row td { background: var(--panel2); font-weight: 600; }
.thr-reset {
  margin-left: 4px; border: 0; background: transparent; color: var(--muted);
  cursor: pointer; font-size: 11px; padding: 0 2px; line-height: 1;
}
.thr-reset:hover { color: var(--red); }
.thr-editor { display: inline-flex; align-items: center; gap: 3px; font-family: var(--mono); }
.thr-inp {
  width: 66px; background: var(--panel); color: var(--text);
  border: 1px solid var(--blue); border-radius: 4px; padding: 1px 4px; font-family: var(--mono);
}
.thr-editor .btn.xs { padding: 1px 5px; }

/* --- Экран «Эффективность» (#8 обучающий цикл) ------------------------- */
/* 18/07: тулбар периода — в общем языке панелей (.opt-filter). */
.eff-ctl { margin: 8px 0 12px; display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px; font-size: 12px; color: var(--muted); }
.eff-cards { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0 4px; }
.eff-cards .card { flex: 1 1 180px; min-width: 160px; }
.eff-tbl td.l { font-weight: 600; }
.eff-tbl { margin-bottom: 14px; }
/* Лента действий: карточка на действие, левая цветная полоса = знак импакта. */
.eff-row { background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--muted); border-radius: 8px;
  padding: 8px 12px; margin: 6px 0; }
.eff-row.eff-good { border-left-color: var(--green); }
.eff-row.eff-bad { border-left-color: var(--red); }
.eff-row.eff-neu { border-left-color: var(--muted); }
.eff-row-head { font-size: 13px; margin-bottom: 4px; }
.eff-row-head b { font-weight: 700; }
.eff-row-impact { font-size: 13px; font-family: var(--mono); }
.eff-w { color: var(--muted); }
.eff-sec { color: var(--muted); font-size: 11px; margin-left: 8px; }
.eff-tag { color: var(--muted); font-size: 11px; margin-left: 6px;
  background: var(--panel2); border-radius: 4px; padding: 1px 6px; }

/* --- Экран «Параметры» (2026-07-13) -------------------------------------
   Игорь явно просил «футуристично-хакерский, не скучный» стиль — неоновый
   циан-акцент (--prm-neon) поверх обычной тёмной палитры (--bg/--panel/
   --border не трогаем — остаётся согласовано с остальной админкой), тонкая
   скан-сетка на карточках групп, свечение на активных ползунках/дайлах/
   тоггле. Задизайнено читаемым в первую очередь: текст всегда --text/--muted,
   неон — только акцент на интерактиве и цифрах, не на фоне тела. */
:root { --prm-neon: #39f0ff; --prm-neon-dim: rgba(57,240,255,.35); }

/* --- Переключатель форматов (2026-07-13, задание Игоря «пороги по
   форматам» — «нужен переключатель, чтобы я точно видел, что настраиваю»).
   Заметный ряд «хакерских» вкладок вверху экрана, активная — сплошная
   неоновая заливка+свечение, остальные — контур. Единственный источник
   форматов — data.formats с сервера (datasource.FORMAT_SCOPES), не хардкод. */
.prm-fmt-switch {
  display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 8px;
  padding: 8px; background: rgba(57,240,255,.04);
  border: 1px solid rgba(57,240,255,.18); border-radius: 10px;
}
.prm-fmt-pill {
  font-family: var(--mono); font-size: 12px; font-weight: 700;
  padding: 6px 14px; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--muted); border: 1px solid var(--border);
  transition: all .12s; text-transform: none; letter-spacing: .2px;
}
.prm-fmt-pill:hover { color: var(--text); border-color: var(--prm-neon-dim); }
.prm-fmt-pill.active {
  background: var(--prm-neon); color: #04191c; border-color: var(--prm-neon);
  box-shadow: 0 0 14px 1px var(--prm-neon-dim), 0 0 0 1px var(--prm-neon-dim) inset;
}
.prm-fmt-current {
  font-size: 11.5px; color: var(--muted); margin: 0 0 10px; font-family: var(--mono);
}
.prm-fmt-current b { color: var(--prm-neon); }

.prm-toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 14px; }

/* Лог-панель истории — «терминальная» лента: моноширинный, тонкая неоновая
   левая полоса, лёгкая скан-текстура фона (повторяющийся горизонтальный
   градиент, почти невидимый, но считывается как «датчик/приборка»). */
.prm-history.card {
  padding: 0; overflow: hidden; border-color: rgba(57,240,255,.25);
  box-shadow: 0 0 0 1px rgba(57,240,255,.06), 0 0 18px rgba(57,240,255,.05);
}
.prm-history > summary {
  cursor: pointer; list-style: none; padding: 9px 12px; font-weight: 700;
  font-size: 12px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--prm-neon); display: flex; align-items: center; gap: 6px;
  background: linear-gradient(180deg, rgba(57,240,255,.07), transparent);
}
.prm-history > summary::-webkit-details-marker { display: none; }
/* 18/07: один язык поворота шеврона (неон-скин Игоря сохранён). */
.prm-history > summary::before {
  content: '▸'; display: inline-block; color: var(--muted);
  transition: transform .15s ease;
}
.prm-history[open] > summary::before { transform: rotate(90deg); color: var(--prm-neon); }
.prm-history-feed {
  max-height: 260px; overflow-y: auto; padding: 4px 0 6px;
  background-image: repeating-linear-gradient(
    0deg, rgba(255,255,255,.012) 0px, rgba(255,255,255,.012) 1px,
    transparent 1px, transparent 3px);
}
.prm-hist-row {
  display: flex; gap: 10px; align-items: baseline; padding: 4px 12px;
  font-family: var(--mono); font-size: 12px; border-left: 2px solid transparent;
  /* Мобила (31/07): flex-ряд из неразрывных кусков (дата + бейдж + длинное
     название параметра) не сжимается ниже min-content и распирал ВЕСЬ
     документ шире вьюпорта — страница на телефоне уезжала в горизонтальный
     скролл. Переносим куски на новую строку вместо распора. */
  flex-wrap: wrap; min-width: 0;
}
.prm-hist-row > * { min-width: 0; overflow-wrap: anywhere; }
.prm-hist-row:hover { background: rgba(57,240,255,.05); }
.prm-hist-row.is-set { border-left-color: var(--prm-neon); }
.prm-hist-row.is-reset { border-left-color: var(--yellow); }
.prm-hist-ts { color: var(--muted); flex: 0 0 auto; }
.prm-hist-scope {
  flex: 0 0 auto; font-size: 10px; padding: 0 5px; border-radius: 6px;
  background: rgba(57,240,255,.14); color: var(--prm-neon); white-space: nowrap;
}
.prm-hist-scope.is-global { background: var(--panel2); color: var(--muted); }
.prm-hist-key { color: var(--text); font-weight: 600; flex: 0 0 auto; }
.prm-hist-diff { color: var(--muted); overflow-wrap: anywhere; }
.prm-hist-row.is-set .prm-hist-diff b,
.prm-hist-row.is-reset .prm-hist-diff b { color: var(--prm-neon); }

/* Группа — карточка-аккордеон, тонкая неоновая рамка при наведении/открытии. */
details.prm-group {
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  margin: 8px 0; transition: border-color .15s, box-shadow .15s;
}
details.prm-group[open] {
  border-color: rgba(57,240,255,.3); box-shadow: 0 0 16px rgba(57,240,255,.05);
}
details.prm-group > summary {
  cursor: pointer; list-style: none; padding: 10px 14px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
details.prm-group > summary::-webkit-details-marker { display: none; }
/* 18/07: шеврон-квадратик системы, подсветка при open — неоновая (скин экрана). */
details.prm-group > summary::before {
  content: '▸'; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; line-height: 1;
  color: var(--muted); background: var(--panel2); border: 1px solid var(--border);
  transition: transform .15s ease;
}
details.prm-group[open] > summary::before {
  transform: rotate(90deg); color: var(--prm-neon); border-color: rgba(57,240,255,.45);
}
.prm-group-title { font-weight: 700; font-size: 14px; }
.prm-group-count {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  background: var(--panel2); border-radius: 8px; padding: 1px 7px;
}
.prm-group-body {
  padding: 4px 14px 12px; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px;
}

/* Одна строка-параметр — компактная карточка внутри группы. */
.prm-row {
  background: var(--panel2); border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 11px; min-width: 0; transition: box-shadow .15s, border-color .15s;
}
.prm-row.is-changed { border-color: rgba(210,153,34,.5); }
.prm-row-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 3px; }
.prm-label { font-size: 12.5px; font-weight: 600; flex: 1 1 auto; min-width: 0; }
.prm-badge-scope {
  font-family: var(--mono); font-size: 9.5px; padding: 1px 6px; border-radius: 8px;
  white-space: nowrap; text-transform: uppercase; letter-spacing: .3px;
}
.prm-badge-scope.live { background: rgba(63,185,80,.15); color: var(--green); }
.prm-badge-scope.nightly { background: rgba(88,166,255,.15); color: var(--blue); }
.prm-badge-changed {
  font-family: var(--mono); font-size: 9.5px; padding: 1px 6px; border-radius: 8px;
  background: rgba(210,153,34,.18); color: var(--yellow); white-space: nowrap;
}
/* Источник значения (пороги по форматам): «своё» для этого формата — неон;
   «унаследовано» от общего — приглушённый жёлтый (то же семейство, что
   генерик «изменён», но явно другой оттенок/иконка — не своё значение). */
.prm-badge-own {
  font-family: var(--mono); font-size: 9.5px; padding: 1px 6px; border-radius: 8px;
  background: rgba(57,240,255,.16); color: var(--prm-neon); white-space: nowrap;
  border: 1px solid rgba(57,240,255,.3);
}
.prm-badge-inherited {
  font-family: var(--mono); font-size: 9.5px; padding: 1px 6px; border-radius: 8px;
  background: rgba(210,153,34,.1); color: var(--muted); white-space: nowrap;
  border: 1px dashed rgba(210,153,34,.35); cursor: help;
}
.prm-row.is-own-format { border-color: rgba(57,240,255,.4); }
.prm-reset-btn { font-size: 10.5px; padding: 1px 6px; }

.prm-desc { margin: 2px 0 6px; }
.prm-desc > summary {
  cursor: pointer; list-style: none; font-size: 11px; color: var(--prm-neon);
  opacity: .85;
}
.prm-desc > summary:hover { opacity: 1; }
.prm-desc > summary::-webkit-details-marker { display: none; }
/* 18/07: вторичный .why-язык — поворотный мини-шеврон. */
.prm-desc > summary::before {
  content: '▸'; display: inline-block; margin-right: 4px; color: var(--muted);
  transition: transform .15s ease;
}
.prm-desc[open] > summary::before { transform: rotate(90deg); color: var(--prm-neon); }
.prm-desc-body {
  font-size: 12px; color: var(--muted); line-height: 1.5; margin-top: 4px;
  padding: 6px 8px; background: rgba(0,0,0,.15); border-left: 2px solid var(--prm-neon-dim);
  border-radius: 0 6px 6px 0;
}

.prm-control { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Ползунок — неоновый трек/бегунок со свечением, читаемый на тёмном фоне. */
.prm-range {
  flex: 1 1 90px; min-width: 70px; -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 2px;
  background: linear-gradient(90deg, var(--prm-neon) var(--_p, 0%), #21262d 0);
  outline: none; cursor: pointer;
}
.prm-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%;
  background: var(--prm-neon); box-shadow: 0 0 8px 1px var(--prm-neon-dim);
  border: 2px solid #0a1416; cursor: grab;
}
.prm-range::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; background: var(--prm-neon);
  box-shadow: 0 0 8px 1px var(--prm-neon-dim); border: 2px solid #0a1416; cursor: grab;
}
.prm-range::-moz-range-track { height: 4px; border-radius: 2px; background: #21262d; }
.prm-range:active::-webkit-slider-thumb { cursor: grabbing; }
.prm-num {
  width: 74px; background: #0a1114; color: var(--prm-neon); font-family: var(--mono);
  font-size: 12px; border: 1px solid var(--border); border-radius: 5px; padding: 3px 6px;
}
.prm-num:focus { outline: none; border-color: var(--prm-neon); box-shadow: 0 0 0 2px var(--prm-neon-dim); }
.prm-unit { font-size: 11px; color: var(--muted); font-family: var(--mono); min-width: 24px; }

.prm-text-input {
  flex: 1 1 140px; background: #0a1114; color: var(--text); font-family: var(--mono);
  font-size: 12px; border: 1px solid var(--border); border-radius: 5px; padding: 4px 7px;
}
.prm-text-input:focus { outline: none; border-color: var(--prm-neon); }

/* Круговой дайл — донат через conic-gradient, JS обновляет --pct (0..100) на
   каждый input слайдера. ::before вырезает «дырку», делая кольцо; центр —
   реальный дочерний div (стоит поверх псевдоэлемента по порядку DOM). */
.prm-dial {
  position: relative; width: 54px; height: 54px; border-radius: 50%; flex: 0 0 auto;
  background: conic-gradient(from -135deg, var(--prm-neon) calc(var(--pct, 0) * 2.7deg),
    rgba(255,255,255,.07) 0deg);
  filter: drop-shadow(0 0 5px var(--prm-neon-dim));
}
.prm-dial::before { content: ''; position: absolute; inset: 7px; border-radius: 50%; background: var(--panel2); }
.prm-dial-center {
  position: absolute; inset: 7px; display: flex; align-items: center; justify-content: center;
  text-align: center; font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  color: var(--text); line-height: 1.1; padding: 2px; word-break: break-word;
}

/* Тогл (bool, autothresholds) — неоновый переключатель. */
.prm-toggle { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.prm-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.prm-toggle-track {
  width: 38px; height: 20px; border-radius: 10px; background: #21262d;
  border: 1px solid var(--border); position: relative; transition: background .15s;
  flex: 0 0 auto;
}
.prm-toggle-thumb {
  position: absolute; top: 1px; left: 1px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--muted); transition: transform .15s, background .15s, box-shadow .15s;
}
.prm-toggle input:checked + .prm-toggle-track { background: rgba(57,240,255,.18); border-color: var(--prm-neon); }
.prm-toggle input:checked + .prm-toggle-track .prm-toggle-thumb {
  transform: translateX(18px); background: var(--prm-neon); box-shadow: 0 0 8px var(--prm-neon-dim);
}
.prm-toggle-state { font-family: var(--mono); font-size: 11px; color: var(--muted); }

.prm-meta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; font-size: 10.5px; color: var(--muted); }
.prm-default { font-family: var(--mono); }
.prm-lastchange { font-family: var(--mono); color: var(--yellow); cursor: help; }

/* Секция «Общие для всех форматов» — визуально отделена (приглушённая
   разделительная линия сверху), ВНЕ переключателя форматов: значения тут
   никогда не зависят от выбранной вкладки формата. */
.prm-common-section { margin-top: 22px; padding-top: 14px; border-top: 1px dashed var(--border); }
.prm-common-title {
  font-size: 13px; font-weight: 700; color: var(--text); margin: 0 0 4px;
  display: flex; align-items: center; gap: 8px;
}

@media (max-width: 760px) {
  .prm-group-body { grid-template-columns: 1fr; }
  .prm-control { gap: 6px; }
  .prm-dial { width: 46px; height: 46px; }
  .prm-num { width: 64px; }
  .prm-fmt-switch { padding: 6px; gap: 4px; }
  .prm-fmt-pill { padding: 5px 10px; font-size: 11px; }
}
.eff-src { color: var(--blue); font-size: 12px; }
/* Атрибуция вердикта байера (14/08) — чип в ленте + баннер-тревога блоков */
.eff-ai-approved { color: var(--green); }
.eff-ai-against { color: var(--red); }
.eff-ai-mixed, .eff-ai-neutral { color: var(--orange, #d80); }
.eff-ai-unreviewed { color: var(--muted); }
.warn-banner {
  background: rgba(216, 96, 0, 0.12); border: 1px solid rgba(216, 96, 0, 0.5);
  color: var(--fg); border-radius: 8px; padding: 10px 14px; margin: 10px 0;
  font-weight: 600;
}

/* «Ставки зон» (#/zbid, 14/07) — персональная цена зоны внутри кампании */
.zb-tbl td.num { white-space: nowrap; }
.zb-row { cursor: pointer; }
.zb-row:hover { background: rgba(255,255,255,.03); }
.zb-own { color: var(--prm-neon, #4de2ff); }
.zb-dir { display: inline-block; padding: 1px 7px; border-radius: 10px;
          font-size: 12px; white-space: nowrap; }
.zb-up { background: rgba(46,204,113,.15); color: #2ecc71; border: 1px solid rgba(46,204,113,.35); }
.zb-down { background: rgba(231,76,60,.13); color: #e74c3c; border: 1px solid rgba(231,76,60,.35); }
.zb-hold { background: rgba(255,255,255,.05); color: var(--dim, #8a94a6); border: 1px solid rgba(255,255,255,.12); }
.zb-imp { background: rgba(241,196,15,.12); color: #f1c40f; border: 1px solid rgba(241,196,15,.3); }
.zb-det td { background: rgba(255,255,255,.02); white-space: normal;
              text-align: left; }
/* колонки таблицы — nowrap (см. table.tbl), но раскрытая строка обязана
   ПЕРЕНОСИТЬСЯ: иначе длинное объяснение растягивает таблицу на 2400px и
   гонит горизонтальный скролл (поймано на превью 14/07). */
.zb-reason, .zb-src, .zb-caps { max-width: 1050px; white-space: normal; }
.zb-reason { padding: 6px 0; line-height: 1.5; }
.zb-caps { color: #f1c40f; font-size: 12px; padding-bottom: 6px; }
.zb-src { border-left: 2px solid var(--prm-neon, #4de2ff); padding: 6px 0 6px 10px;
          margin-top: 4px; font-size: 12px; font-family: var(--mono, monospace); }
.zb-src-title { color: var(--dim, #8a94a6); margin-bottom: 4px; }
.zb-src-row { padding: 1px 0; }
.zb-src-w { display: inline-block; min-width: 38px; color: var(--prm-neon, #4de2ff); }

/* ==========================================================================
   Скелет v2 (β) — «Кампании v2», 2026-07-16 (docs/plans/2026-07-16-v2-
   skeleton.md, макет docs/mockups/2026-07-16-v2-mockup.html). Экраны #/v2 и
   #/v2/c/{cid}. Палитра максимально переиспользует существующие переменные
   темы (--panel/--panel2/--border/--bg/--text/--muted/--green/--red/
   --yellow/--blue/--mono) — только --v2-dim/--v2-gold/--v2-purp НОВЫЕ (в
   текущей палитре аналогов нет: приглушённее --muted и золото/фиолет для
   решений kind=guard/os). Все классы — с префиксом .v2- (и два составных
   селектора на СУЩЕСТВУЮЩИЕ классы .num/.sub — см. комментарий ниже — чтобы
   их семантика из остального приложения заработала и здесь, без правки
   глобальных .num/.sub, которых сейчас нет). Старые экраны не тронуты.
   ========================================================================== */
.v2-wrap { --v2-dim: #5f6a80; --v2-gold: #e5c36c; --v2-purp: #b79cff; }
/* .num/.sub нигде глобально не определены (используются точечно внутри
   .tbl/.card) — эти два правила ТОЛЬКО расширяют их на .v2-wrap, не трогая
   остальное приложение. */
.v2-wrap .num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.v2-wrap .sub { display: block; font-family: var(--mono); font-size: 11px; color: var(--v2-dim); margin-top: 1px; }
.v2-dim { color: var(--v2-dim); }

.v2-note {
  background: rgba(210,153,34,.08); border: 1px dashed rgba(210,153,34,.4);
  color: #d9c495; border-radius: 8px; padding: 8px 12px; font-size: 12px; margin: 10px 0;
}

.v2-lbl { font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--v2-dim); font-weight: 600; }

/* ---- шапка аккаунта ---- */
.v2-acct { display: flex; gap: 22px; flex-wrap: wrap; margin: 12px 0 6px; }
.v2-st b { display: block; font-size: 17px; font-weight: 700; }
.v2-acc-c { color: var(--blue); }

/* ---- тренд аккаунта + драйверы (26/08) ---- */
.v2-trend { display: flex; gap: 26px; flex-wrap: wrap; align-items: flex-start;
  margin: 4px 0 12px; padding: 12px 14px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--panel); }
.v2-trend-g { display: flex; flex-direction: column; gap: 4px; min-width: 280px; flex: 1 1 340px; }
.v2-trend-g .v2-spark { width: 100%; height: 56px; }
.v2-drv-wrap { flex: 1 1 420px; display: flex; flex-direction: column; gap: 8px; }
.v2-drv-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; }
.v2-drv-h { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.v2-drv-row { display: grid; grid-template-columns: 96px 1fr; gap: 2px 10px;
  padding: 3px 0; text-decoration: none; color: inherit; align-items: baseline; }
.v2-drv-row:hover .v2-drv-nm { text-decoration: underline; }
.v2-drv-row > b { text-align: right; white-space: nowrap; }
.v2-drv-row .v2-drv-nm { font-size: 13px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.v2-drv-row .sub { grid-column: 2; font-size: 11px; }
@media (max-width: 760px) {
  .v2-drv-cols { grid-template-columns: 1fr; }
  .v2-trend { gap: 12px; }
}

/* ---- список кампаний (#/v2) ---- */
.v2-lhead, .v2-crow {
  display: grid;
  grid-template-columns: minmax(190px,1.4fr) 84px 84px 86px 120px minmax(120px,1fr) minmax(110px,1fr) 112px;
  gap: 10px; align-items: center;
}
.v2-lhead { padding: 4px 14px; margin-top: 10px; }
.v2-crow {
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 11px 14px; margin: 7px 0; text-decoration: none; color: inherit;
  transition: border-color .12s, background .12s;
}
.v2-crow:hover { border-color: #35507e; background: var(--panel2); text-decoration: none; }
.v2-crow:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.v2-crow.v2-paused { opacity: .5; }
.v2-cname { font-weight: 650; font-size: 13.5px; line-height: 1.3; color: var(--text); }
.v2-cname .v2-cid { color: var(--v2-dim); font-weight: 400; font-size: 11px; }
.v2-cell { text-align: right; }
.v2-cell b { font-size: 14px; }
.v2-volcell { font-size: 11.5px; color: var(--muted); }
.v2-volbar { height: 4px; background: var(--panel2); border-radius: 3px; margin-top: 5px; overflow: hidden; max-width: 160px; }
.v2-volbar i { display: block; height: 100%; background: var(--blue); border-radius: 3px; }
.v2-flags { display: flex; flex-wrap: wrap; gap: 4px; }
.v2-decis {
  justify-self: end; text-align: right; background: rgba(88,166,255,.08);
  border: 1px solid rgba(88,166,255,.3); border-radius: 8px; padding: 5px 9px; min-width: 0;
}
.v2-decis b { color: var(--blue); font-size: 12.5px; display: block; }
.v2-decis span { display: block; font-size: 10.5px; color: var(--muted); }
.v2-decis.zero { background: none; border-color: var(--border); }
.v2-decis.zero b { color: var(--v2-dim); }
.v2-listfoot { color: var(--v2-dim); font-size: 12px; margin: 10px 2px; }
.v2-b-gold { background: rgba(229,195,108,.15); color: var(--v2-gold); }

/* ---- панель кампании (#/v2/c/{cid}) ---- */
.v2-back { display: inline-block; margin: 12px 0 8px; font-size: 13px; }
/* 18/07: 19→20px — выравнивание под scr-h-шкалу (бриф №2 разрешает только это). */
.v2-phead h2 { margin: 2px 0 8px; font-size: 20px; }
.v2-phead h2 .v2-cid { color: var(--v2-dim); font-weight: 400; font-size: 12px; }
.v2-chip {
  display: inline-block; font-size: 11.5px; color: var(--muted); background: var(--panel);
  border: 1px solid var(--border); border-radius: 6px; padding: 3px 9px; margin: 0 4px 4px 0;
}
.v2-chip b { color: var(--text); font-weight: 650; }

.v2-kpis { display: flex; gap: 24px; flex-wrap: wrap; align-items: flex-end; }
.v2-kpi b { display: block; font-size: 18px; font-weight: 750; }
.v2-kpi .v2-lbl { margin-bottom: 2px; }
.v2-kpi .sub { font-size: 11px; }
.v2-kpi-spark { margin-left: auto; }
.v2-ratio { font-size: 12px; color: var(--muted); margin-top: 10px; }

.v2-funrow {
  display: grid; grid-template-columns: 150px 86px 1fr 150px; gap: 12px;
  align-items: center; padding: 7px 0; border-top: 1px solid var(--panel2);
}
.v2-funrow:first-of-type { border-top: none; }
.v2-funname { font-size: 12.5px; color: var(--muted); }
.v2-funval { text-align: right; font-weight: 700; }
.v2-funbar { position: relative; height: 12px; background: var(--panel2); border-radius: 4px; }
.v2-funbar i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px; background: var(--green); opacity: .85; }
.v2-funbar i.v2-funbar-low { background: var(--yellow); }
.v2-funbar i.v2-funbar-na { background: var(--v2-dim); opacity: .5; }
.v2-funbar em { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--text); opacity: .7; font-style: normal; }
.v2-funnote { font-size: 11px; color: var(--v2-dim); text-align: right; }
.v2-funverdict { margin-top: 10px; font-size: 12.5px; color: var(--muted); border-top: 1px solid var(--panel2); padding-top: 9px; }

/* ---- решения ---- */
.v2-dcard {
  position: relative; background: var(--panel2); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px 12px 18px; margin: 9px 0; overflow: hidden;
}
.v2-dcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--v2-stripe, var(--v2-dim)); }
.v2-dtop { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.v2-dkind { font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--v2-stripe, var(--v2-dim)); }
.v2-dtitle { font-weight: 650; font-size: 13.5px; color: var(--text); }
.v2-dmoney { margin-left: auto; font-weight: 750; font-size: 13.5px; white-space: nowrap; color: var(--text); }
.v2-dverdict { margin: 7px 0 2px; font-size: 13px; color: var(--text); }
.v2-ev {
  margin: 8px 0 2px; padding: 9px 12px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; font-size: 12.3px; color: var(--muted);
}
.v2-ev div { padding: 2.5px 0; }
/* Лиды и продажи — подсветка (26/07, просьба Игоря «чтобы сразу бросалось в
   глаза»). Продажа зеленее лида: продажа это деньги, лид только обещание. */
.hl-lead, .hl-sale {
  display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 5px;
  font-weight: 700; font-variant-numeric: tabular-nums;
}
.hl-lead { background: rgba(210,153,34,.20); color: #e3b341; }
.hl-sale { background: rgba(63,185,80,.22); color: #56d364; }

/* Фильтр по типу кампании на вкладке «Кампании» (26/07). */
#v2Fmts { display: inline-flex; gap: 4px; flex-wrap: wrap; }
#v2Fmts button b { margin-left: 3px; opacity: .75; }

/* Формат-изоляция в карточке зоны (26/07): подытоги по форматам + группы
   кампаний. Решение принимают ВНУТРИ формата, поэтому формат — заголовок. */
.zfmt { display: flex; gap: 10px; flex-wrap: wrap; margin: 6px 0 4px; }
.zfmt-card {
  flex: 1 1 170px; padding: 8px 12px; border-radius: 8px;
  background: var(--panel2); border: 1px solid var(--border);
}
.zfmt-card.pos { border-color: rgba(63,185,80,.35); }
.zfmt-card.neg { border-color: rgba(248,81,73,.35); }
.zfmt-h { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.zfmt-m { display: flex; align-items: baseline; gap: 8px; margin: 2px 0 3px; }
.zfmt-m b { font-size: 16px; }
.zfmt-sub { font-size: 11.5px; color: var(--muted); }
.zfmt-group { margin-bottom: 12px; }
.zfmt-gh {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 4px 0 5px; font-weight: 700; font-size: 12.5px; color: var(--text);
  border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.zfmt-gsub { font-weight: 400; font-size: 12px; color: var(--muted); }

/* 🔴 Одна кнопка вместо квеста по фильтрам (26/07). Зелёная полоса — первое,
   что видно на экране «Сегодня», если ИИ с чем-то полностью согласен. */
.tdy-aibar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 0; padding: 10px 14px; border-radius: 10px;
  background: rgba(63,185,80,.10); border: 1px solid rgba(63,185,80,.35);
}
.tdy-aibar-ic { font-size: 18px; }
.tdy-aibar-txt { display: flex; flex-direction: column; gap: 2px; }
.tdy-aibar-txt b { font-size: 14px; color: var(--text); }
.tdy-aibar-sub { font-size: 12px; color: var(--muted); }
.tdy-aibar .btn { margin-left: auto; }
.tdy-aibar .btn + .btn { margin-left: 0; }
.tdy-conf { margin: 4px 0 10px 18px; font-size: 13px; color: var(--text); }
.tdy-conf li { padding: 1px 0; }

/* Ряд фильтров по мнению ИИ в ленте «Сегодня» (26/07). */
.tdy-airow { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.tdy-ailab { font-size: 12px; color: var(--muted); margin-right: 2px; }
.tdy-aichip {
  border: 1px solid var(--border); background: var(--panel2); color: var(--text);
  border-radius: 999px; padding: 3px 10px; font-size: 12px; cursor: pointer;
}
.tdy-aichip b { margin-left: 3px; }
.tdy-aichip:hover { border-color: var(--muted); }
.tdy-aichip.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.tdy-aichip.bad b { color: var(--red); }
.tdy-aichip.good b { color: var(--green); }
.tdy-aichip.warn b { color: var(--yellow); }
.tdy-aichip.sortbtn { color: var(--muted); }
.tdy-aichip.bad1 b { color: #d4674a; }
.tdy-aichip.good1 b { color: #6fb36b; }
.tdy-aichip.selall { border-color: var(--accent); color: var(--text); font-weight: 650; }
.tdy-aichip.selall b { color: var(--accent); }

/* Стрелка направления ставки — читается раньше текста (26/07). */
.v2-bidarrow {
  display: inline-flex; align-items: center; gap: 3px; font-size: 13px;
  font-weight: 800; padding: 1px 7px; border-radius: 6px; line-height: 1.5;
}
.v2-bidarrow b { font-size: 11.5px; font-weight: 700; }
.v2-bidarrow.up { color: var(--green); background: rgba(63,185,80,.14); }
.v2-bidarrow.down { color: var(--red); background: rgba(248,81,73,.14); }

/* Объём: сколько купили и какую долю доступного выкупаем. */
.v2-vol {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 5px 0 0; font-size: 12.2px; color: var(--muted);
}
.v2-vol-lab { text-transform: uppercase; font-size: 10.5px; letter-spacing: .05em; }
.v2-vol-n { color: var(--text); font-weight: 650; }
.v2-volbar {
  display: inline-block; width: 84px; height: 7px; border-radius: 4px;
  background: var(--panel2); border: 1px solid var(--border); overflow: hidden;
  vertical-align: middle;
}
.v2-volbar i { display: block; height: 100%; }
.v2-volbar i.low { background: var(--yellow); }
.v2-volbar i.mid { background: var(--green); }
.v2-volbar i.full { background: var(--red); }

/* Оценка ИИ на карточке (26/07): мнение живёт там, где принимается решение,
   а не отдельной вкладкой. */
.v2-ai {
  margin: 6px 0 0; font-size: 12.3px; display: flex; gap: 8px;
  align-items: baseline; flex-wrap: wrap;
}
.v2-ai-badge {
  font-weight: 750; white-space: nowrap; padding: 1px 8px; border-radius: 999px;
  border: 1px solid transparent;
}
.v2-ai-badge b { font-size: 12.5px; margin-right: 2px; }
.v2-ai-why { color: var(--muted); }
.v2-ai-dots { font-size: 9px; letter-spacing: 1px; color: var(--muted); }
.v2-ai-stale {
  font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); border: 1px solid var(--border); border-radius: 4px;
  padding: 0 4px;
}
/* Пятиступенчатая шкала: где стоит оценка — видно позицией, не чтением */
.v2-ai-scale { display: inline-flex; gap: 2px; align-items: center; }
.v2-ai-tick {
  display: inline-block; width: 9px; height: 4px; border-radius: 2px;
  background: var(--panel2); border: 1px solid var(--border);
}
.v2-ai-tick.on { border-color: transparent; }
.v2-ai-tick.on.bad2 { background: var(--red); }
.v2-ai-tick.on.bad1 { background: #d4674a; }
.v2-ai-tick.on.unsure { background: var(--yellow); }
.v2-ai-tick.on.good1 { background: #6fb36b; }
.v2-ai-tick.on.good2 { background: var(--green); }
.v2-ai.bad2 .v2-ai-badge { color: var(--red); background: rgba(248,81,73,.14); border-color: rgba(248,81,73,.35); }
.v2-ai.bad1 .v2-ai-badge { color: #d4674a; background: rgba(212,103,74,.12); }
.v2-ai.unsure .v2-ai-badge { color: var(--yellow); background: rgba(210,153,34,.12); }
.v2-ai.good1 .v2-ai-badge { color: #6fb36b; background: rgba(111,179,107,.12); }
.v2-ai.good2 .v2-ai-badge { color: var(--green); background: rgba(63,185,80,.14); border-color: rgba(63,185,80,.35); }

/* Сигнал «соглашаться или нет» — цветная строка сразу под шапкой карточки
   (26/07). Цвет дублирует смысл текста: читается боковым зрением. */
.v2-head {
  margin: 6px 0 0; font-size: 12.5px; font-weight: 650; letter-spacing: .01em;
}
.v2-head.bad { color: var(--red); }
.v2-head.good { color: var(--green); }
.v2-head.warn { color: var(--yellow, #d29922); }
.v2-head.flat { color: var(--muted); }

/* Денежная таблица пары зона×кампания на карточке (26/07, требование Игоря
   «покажи просто деньги по периодам»). Видна сразу, без раскрытия улик. */
.v2-mt { margin: 8px 0 2px; overflow-x: auto; }
.v2-mt-tbl { width: 100%; border-collapse: collapse; font-size: 12.3px; }
.v2-mt-tbl th {
  text-align: right; font-weight: 600; color: var(--muted); font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em; padding: 2px 8px 4px 0;
  border-bottom: 1px solid var(--border);
}
.v2-mt-tbl th.l, .v2-mt-tbl td.l { text-align: left; }
.v2-mt-tbl td { padding: 3px 8px 3px 0; color: var(--text); white-space: nowrap; text-align: right; }
.v2-mt-tbl td.l { color: var(--muted); }
.v2-mt-tbl tbody tr + tr td { border-top: 1px solid var(--panel2); }
.v2-mt-camp { color: var(--muted); font-size: 11px; }
.v2-mt-trend { margin-top: 5px; font-size: 12px; color: var(--muted); }
.v2-mt-trend.up { color: var(--green); }
.v2-mt-trend.down { color: var(--red); }

.v2-dbtns { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* ---- прошлые действия ---- */
.v2-hrow { display: flex; gap: 12px; align-items: baseline; padding: 8px 0; border-top: 1px solid var(--panel2); font-size: 13px; }
.v2-hrow:first-of-type { border-top: none; }
.v2-hdate { color: var(--v2-dim); font-size: 11.5px; white-space: nowrap; min-width: 44px; }
.v2-heff { margin-left: auto; font-size: 12px; white-space: nowrap; text-align: right; }

.v2-spark { display: block; max-width: 100%; }

@media (max-width: 840px) {
  .v2-lhead { display: none; }
  .v2-crow {
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "name name" "y w7" "d30 vol" "flags flags" "dec dec";
    gap: 8px 12px;
  }
  .v2-crow > .v2-a-name { grid-area: name; }
  .v2-crow > .v2-a-y { grid-area: y; text-align: left; }
  .v2-crow > .v2-a-7 { grid-area: w7; text-align: left; }
  .v2-crow > .v2-a-30 { grid-area: d30; text-align: left; }
  .v2-crow > .v2-a-vol { grid-area: vol; }
  .v2-crow > .v2-a-fl { grid-area: flags; }
  .v2-crow > .v2-a-dec { grid-area: dec; justify-self: start; }
  .v2-crow > .v2-a-sp { display: none; }
  .v2-cell { text-align: left; }
  .v2-cell .v2-lbl { display: block; margin-bottom: 1px; }
  .v2-acct { gap: 14px; }
  .v2-funrow { grid-template-columns: 110px 70px 1fr; gap: 8px; }
  .v2-funnote { grid-column: 2 / 4; text-align: left; }
  .v2-kpi-spark { margin-left: 0; width: 100%; }
}

/* ── v2: группы решений (17/07, фидбек Игоря: плашки-разделы + групповое применение) ── */
.v2-group { background: var(--panel2, #1a2233); border: 1px solid var(--line, #242e44);
  border-radius: 10px; margin: 9px 0; overflow: hidden; }
.v2-group > summary { list-style: none; cursor: pointer; display: flex; align-items: center;
  gap: 12px; padding: 11px 14px 11px 18px; position: relative; user-select: none; }
.v2-group > summary::-webkit-details-marker { display: none; }
.v2-group > summary::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px; background: var(--v2-stripe, #3a4763); }
.v2-gkind { font-weight: 700; font-size: 13.5px; }
.v2-gcount { color: var(--muted, #8c97ad); font-size: 12px; }
.v2-gmoney { margin-left: auto; font-weight: 700; font-size: 13px; }
.v2-gchev { color: var(--muted, #8c97ad); transition: transform .15s; }
.v2-gmoney + .v2-gchev { margin-left: 0; }
.v2-group > summary .v2-gchev { margin-left: auto; }
.v2-group > summary .v2-gmoney { margin-left: auto; }
.v2-group > summary .v2-gmoney ~ .v2-gchev { margin-left: 12px; }
.v2-group[open] > .v2-gchev, .v2-group[open] > summary .v2-gchev { transform: rotate(90deg); }
.v2-group .v2-dcard { margin: 8px 12px; }
.v2-gbar { display: flex; align-items: center; gap: 14px; padding: 8px 14px 0 18px; }
.v2-picklab { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--muted, #8c97ad); cursor: pointer; }
.v2-pick, .v2-pickall { width: 15px; height: 15px; accent-color: #7cacff; cursor: pointer; }
/* Сущностные ссылки карточки решения — зона, домен, группа креативов, ОС.
   Все открывают панель «как эта сущность живёт по всему аккаунту» (фидбек
   Игоря 25/07), поэтому и выглядят одинаково: пунктир = «можно посмотреть
   глубже». .v2-clink — кампания внутри ТЕКСТА вердикта/улик (linkifyEntities,
   25/07): обычная ссылка на панель кампании, не drawer, но того же стиля —
   Игорь не должен угадывать по внешнему виду, что здесь другой канал. */
/* .v2-varlink (креатив, 09/08) и dim-ссылки (гео/устройство/браузер/
   категория) добавлены в общее правило: раньше их не было в списке — клик
   работал, но текст не выглядел кликабельным, ссылку было не найти глазом. */
.v2-zlink, .v2-dlink, .v2-crelink, .v2-oslink, .v2-clink, .v2-varlink,
.v2-geolink, .v2-devlink, .v2-brlink, .v2-catlink { color: inherit; text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.v2-zlink:hover, .v2-dlink:hover, .v2-crelink:hover, .v2-oslink:hover, .v2-clink:hover, .v2-varlink:hover,
.v2-geolink:hover, .v2-devlink:hover, .v2-brlink:hover, .v2-catlink:hover { color: #7cacff; }
@media (prefers-reduced-motion: reduce) { .v2-gchev { transition: none; } }

/* имя кампании в дровере зоны/домена — кликабельная ссылка в панель v2 (17/07) */
.zd-camp-link { color: inherit; text-decoration: underline dotted; text-underline-offset: 3px; }
.zd-camp-link:hover { color: #7cacff; }

/* ── одна система (17/07, план one-system): единые вердикты в v1-строках ── */
.v1v2 { margin: 2px 0 6px; padding: 6px 10px; border-left: 3px solid var(--v2-purp, #8d7bd8);
  background: color-mix(in srgb, var(--panel2, #1a2233) 70%, transparent);
  border-radius: 0 6px 6px 0; }
.v1v2 .num { font-weight: 700; }
.v1v2-ev { margin: 0 0 6px; padding-left: 12px; color: var(--muted, #8c97ad); font-size: 12px; }
.v1v2-ev > div { margin: 1px 0; }
.badv-tbl td.rsn { max-width: 520px; }
.v2-editors { display: flex; gap: 18px; flex-wrap: wrap; margin: 6px 0 2px; }

/* ── кнопки действий всегда видны (17/07, фидбек «строки не помещаются»):
   колонка действий прилипает к правому краю, широкая таблица скроллится ПОД
   ней — работает на всех .tablewrap-таблицах с .act-cell. Редизайн 17/07
   (жалоба «весь аккаунт обрезан»): фон — градиент с ПРОЗРАЧНОЙ левой кромкой
   14px — накрытые данные просвечивают под кнопками, видно что таблица
   продолжается; глухой фон + тень раньше читались как «данных дальше нет». ── */
.tablewrap .tbl td.act-cell, .tablewrap .tbl th.act-cell {
  position: sticky; right: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(22, 27, 34, 0) 0, var(--panel) 14px);
  padding-left: 18px;
}
.tablewrap .tbl thead th.act-cell {
  background: linear-gradient(90deg, rgba(29, 35, 44, 0) 0, var(--panel2) 14px);
  z-index: 3; /* угловая ячейка (sticky top+right) — поверх остального thead */
}
.tablewrap .tbl tr:hover td.act-cell {
  background: linear-gradient(90deg, rgba(29, 35, 44, 0) 0, var(--panel2) 14px);
}
/* Кнопки действий очереди — ВСЕГДА в столбик: sticky-колонка ~130px вместо
   ~240 («весь аккаунт» виден без скролла на десктопе); строки и так 3-строчные
   — высоту это не добавляет. */
.opt-tbl td.act-cell .btn.xs { display: block; margin: 3px 0 3px auto; }
.opt-tbl td.act-cell .btn.xs + .btn.xs { margin-left: auto; }
@media (max-width: 1280px) {
  .opt-tbl a.camp-link { max-width: 16ch; }
  .zsub { max-width: 130px; }
}
.zp-row { display: flex; align-items: center; gap: 8px; margin: 10px 0 6px; }
.zp-row input { width: 110px; font-family: var(--mono); }
.zp-presets { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  color: var(--muted); font-size: 12px; margin-bottom: 6px; }

/* ── линия выполнения запроса (17/07): любой POST — бегущая полоса сверху ── */
#reqbar { position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: 3000; overflow: hidden; pointer-events: none; }
#reqbar::before { content: ""; position: absolute; top: 0; bottom: 0;
  left: -40%; width: 40%;
  background: linear-gradient(90deg, transparent, var(--blue), transparent);
  animation: reqslide 1s linear infinite; }
@keyframes reqslide { to { left: 100%; } }
@media (prefers-reduced-motion: reduce) {
  #reqbar::before { animation: none; left: 0; width: 100%;
    background: var(--blue); opacity: .5; }
}
.btn.ok { background: rgba(63,185,80,.16); border-color: rgba(63,185,80,.55); color: #6fdd82; font-weight: 600; }
.btn.ok:hover { background: rgba(63,185,80,.28); border-color: var(--green); }
/* Контролы #/zbid (кампания/окно/направление/поиск) — тулбар в общем языке
   с .opt-filter; раньше класс .ctl вовсе не имел стилей (голые нативные
   селекты). Используется только на #/zbid. */
.ctl {
  display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px; margin: 8px 0 12px;
  font-size: 12px; color: var(--muted);
}
.ctl select, .ctl input {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font: inherit; max-width: 100%; min-width: 0;
}
/* Бар групповых операций (топ ставок / #/zbid) — тулбар в общем языке с
   .batchbar/.opt-filter (редизайн 17/07). */
.zt-bar {
  display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap;
  background: var(--panel2); border: 1px solid var(--border);
  border-radius: 10px; padding: 6px 10px; margin: 0 0 10px; font-size: 12px;
}
.zt-pick, .zt-pickall { width: 15px; height: 15px; accent-color: #7cacff; cursor: pointer; }
/* Чекбоксы очереди — единый акцент (не трогает v2: селектор скопирован под .opt-tbl). */
.opt-tbl input[type="checkbox"] { accent-color: var(--blue); cursor: pointer; }
/* Тонкий скроллбар таблиц — намёк «двигается», не системная простыня. */
.tablewrap { scrollbar-width: thin; scrollbar-color: #39424d transparent; }
.tablewrap::-webkit-scrollbar { height: 8px; width: 8px; }
.tablewrap::-webkit-scrollbar-thumb { background: #39424d; border-radius: 4px; }
.tablewrap::-webkit-scrollbar-track { background: transparent; }

/* Раскатка 18/07: у всех приведённых к системе шевронов (один язык поворота
   ▸→90°) анимация отключается по prefers-reduced-motion — как у .opt-sec/.bk-chev. */
@media (prefers-reduced-motion: reduce) {
  details.hday > summary::before, .jbatch > summary::before,
  details.cre-q > summary::before, details.cre-cov > summary::before,
  details.cov-camp > summary::before,
  details.cov-full > summary::before, details.cov-spec > summary::before,
  .act-tech > summary::before, .jrow-tech > summary::before,
  .blopt-list > summary::before, .thr-bt-details summary::before,
  .prm-history > summary::before, details.prm-group > summary::before,
  .prm-desc > summary::before, .loco-card > summary::before { transition: none; }
}
.reason-chip { cursor: pointer; }
.reason-chip:hover { filter: brightness(1.25); }

/* --------------------------------------------- Smart Optimization (#/smart) */
.sm-step { padding: 4px 0; font-size: 12.5px; color: var(--tx, #c9d1d9); }
.sm-step .badge { margin-right: 6px; }
.sm-trace .det-body { padding: 8px 12px; }
.sm-npick { margin-left: 8px; }

/* ------------------------------------------------------ ИИ-советник (#/ai) */
.ai-models {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 10px 0 2px;
}
.chip.ai-model {
  border: 1px solid var(--line, #30363d); border-radius: 999px;
  padding: 4px 12px; background: var(--card, #161b22);
  color: var(--tx, #c9d1d9); font: inherit; font-size: 12.5px;
  cursor: pointer;
}
.chip.ai-model.on {
  border-color: var(--accent, #3fb950); color: var(--accent, #3fb950);
  font-weight: 600;
}
.chip.ai-model:disabled { opacity: 0.45; cursor: not-allowed; }
.ai-bar { display: flex; align-items: center; gap: 12px; margin: 12px 0 18px; }
.scr-h3 { font-size: 16px; font-weight: 700; margin: 22px 0 6px; }
.ai-camp { color: var(--muted, #8b949e); font-weight: 400; white-space: nowrap; }
.ai-runmsg { color: var(--muted, #8b949e); }
.ai-list { display: flex; flex-direction: column; gap: 12px; }
.ai-card {
  border: 1px solid var(--line, #30363d); border-radius: 12px;
  padding: 14px 16px; background: var(--card, #161b22);
  border-left: 3px solid var(--accent, #3fb950);
}
.ai-card.ai-done { opacity: 0.6; border-left-color: var(--line, #30363d); }
.ai-card-h { display: flex; align-items: center; gap: 10px; }
.ai-ic { font-size: 20px; line-height: 1; }
.ai-ttl { font-size: 15px; font-weight: 600; flex: 1; }
.ai-imp {
  font-size: 15px; font-weight: 700; color: var(--accent, #3fb950);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ai-why { margin-top: 8px; font-size: 13.5px; line-height: 1.5; color: var(--tx, #c9d1d9); }
.ai-acts { margin-top: 12px; display: flex; gap: 8px; }
.ai-reason-ta {
  width: 100%; margin-top: 10px; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--line, #30363d); background: var(--bg, #0d1117);
  color: var(--tx, #c9d1d9); font: inherit; resize: vertical; box-sizing: border-box;
}

/* ==================== «Сегодня» (#/today, 24/07) ====================
   Единая лента решений по всему аккаунту — экран по умолчанию (Н-1/Н-4/Н-5
   аудита 05-frontend-ux.md). Карточки — .v2-dcard 1:1 (см. выше), это здесь
   только шапка/фильтры/групповая панель/фокус клавиатуры. */
.tdy-wrap { max-width: 900px; margin: 0 auto; }
.tdy-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 14px; }
.tdy-sum { text-align: right; font-size: 12.5px; color: var(--muted); }
.tdy-line1 { font-size: 14px; color: var(--text); }
.tdy-line1 b { color: var(--green); }
.tdy-line2 { margin-top: 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* Фильтры — липкая панель под топбаром (топбар ~40px высотой). */
.tdy-filters {
  position: sticky; top: 40px; z-index: 4;
  display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  padding: 8px 12px; margin: 10px 0 12px;
}
.tdy-kinds { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 auto; }
.tdy-kchip {
  font: inherit; font-size: 11.5px; color: var(--muted); background: var(--panel2);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px; cursor: pointer;
}
.tdy-kchip:hover { color: var(--text); }
.tdy-kchip b { color: var(--text); font-weight: 700; margin-left: 3px; }
.tdy-kchip.on { color: var(--text); border-color: var(--blue); background: rgba(88,166,255,.14); }
.tdy-minmoney { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.tdy-minmoney input {
  width: 68px; background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 6px; font: inherit;
}
#todayCampSel {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font: inherit; max-width: 220px; min-width: 0;
}
.tdy-list { display: flex; flex-direction: column; }
.tdy-list .v2-dcard { margin: 6px 0; }
.tdy-campbadge {
  font-size: 11px; color: var(--muted); background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; padding: 2px 7px; text-decoration: none; white-space: nowrap;
}
.tdy-campbadge:hover { color: var(--blue); border-color: var(--blue); text-decoration: none; }
/* Фокус клавиатуры (j/k) — видимая рамка вокруг карточки, не зависит от :focus
   (карточка сама не фокусируемый элемент — фокус логический, не DOM-focus). */
.tdy-focus { outline: 2px solid var(--blue); outline-offset: 1px; border-radius: 10px; }
/* Групповая панель — тот же .batchbar (см. выше), что и на #/opt/панели
   кампании (единый визуальный язык). На десктопе — липнет СВЕРХУ (под
   фильтрами), на телефоне — снизу (там палец, там и должна быть кнопка). */
.tdy-batchbar { position: sticky; top: 92px; bottom: auto; z-index: 6; }
.tdy-keys { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; font-size: 13px; }
.tdy-keys b { display: inline-block; min-width: 66px; color: var(--blue); font-family: var(--mono); }

@media (max-width: 640px) {
  .tdy-head { flex-direction: column; align-items: flex-start; }
  .tdy-sum { text-align: left; }
  .tdy-line2 { justify-content: flex-start; }
  .tdy-filters { position: static; } /* мобилка: место дороже, чем липкость фильтров */
  /* position:sticky с bottom НЕ держит элемент у низа экрана, если его место
     в потоке — ВЫШЕ (панель стоит сразу под фильтрами, а не в конце ленты):
     sticky-bottom «цепляет» только при скролле ВВЕРХ мимо элемента, а нам
     нужно «всегда видна внизу, пока идёт скролл ленты вниз» — это честный
     fixed, найдено живой проверкой в браузере (смоук 24/07: панель улетала
     за верх экрана). left/right вместо width — не зависит от .tdy-wrap
     max-width. Место под ней — паддинг у ленты, см. .tdy-batch-open ниже. */
  .tdy-batchbar {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; width: auto;
    margin: 0; border-radius: 0; z-index: 50;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -8px 22px rgba(0,0,0,.45);
  }
  /* Класс на <body> — переключает JS (todayUpdateBatchbar), пока панель
     видна: без него последняя карточка ленты пряталась бы под fixed-баром. */
  body.tdy-batch-open .tdy-list { padding-bottom: 104px; }
  .tdy-keys { grid-template-columns: 1fr; }
}

/* Блок «ИИ на твоём компьютере» на вкладке #/ai (фидбек Игоря 25/07: «где,
   режим, когда»). Стоит первым на экране, потому что отвечает на вопрос
   «работает ли это вообще» — раньше пустая вкладка читалась как «ИИ посмотрел
   и ничего не нашёл», хотя канал был попросту не включён. */
.ai-mac { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
          margin: 8px 0 14px; background: var(--panel); }
.ai-mac-l1 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ai-mac-l2 { color: var(--muted); font-size: 13px; margin-top: 6px; line-height: 1.5; }
.ai-mac-l2 code { background: var(--bg2); padding: 1px 5px; border-radius: 4px; }

/* Список сущностей, которые тронет предложение ИИ (фидбек Игоря 25/07:
   «чтобы принять решение я должен видеть список этих зон в кликабельном
   виде»). Каждая зона/домен открывает свою панель по всему аккаунту —
   пачку блокировок нельзя принимать вслепую. */
.ai-ents { margin: 6px 0 0; font-size: 13px; line-height: 1.9; }
.ai-ents-l { color: var(--muted); margin-right: 4px; }
.ai-ent { display: inline-block; padding: 1px 7px; margin: 0 2px 2px 0;
          border: 1px solid var(--line); border-radius: 5px;
          background: var(--bg2); font-variant-numeric: tabular-nums; }
.ai-ent:hover { border-color: #7cacff; }

/* «Кто есть кто» на вкладке ИИ: два канала легко перепутать — оба ИИ, оба
   предлагают, но работают в разных местах и обновляются по разному поводу
   (вопрос Игоря 25/07). Объяснение стоит на экране, а не в подсказке. */
.ai-who { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
          margin: 8px 0 12px; background: var(--panel); font-size: 13px;
          line-height: 1.7; color: var(--muted); }
.ai-who > div + div { margin-top: 5px; }
.ai-who code { background: var(--bg2); padding: 1px 5px; border-radius: 4px; }
.ai-age { color: var(--muted); font-size: 12px; margin-left: 6px; white-space: nowrap; }


/* Глубина разбора ленты (27/07) — «где гарантия, что ИИ всё посмотрит».
   Отдельная строка под мнением ИИ: не сколько оценок, а сколько РАЗБОРОВ. */
.tdy-deprow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 2px 0 8px; font-size: 12px; }
.tdy-dep { padding: 1px 7px; border-radius: 10px; white-space: nowrap;
  border: 1px solid var(--line); color: var(--muted); }
.tdy-dep b { color: var(--fg); }
.tdy-dep.good { border-color: #2e7d32; color: #2e7d32; }
.tdy-dep.good b { color: #2e7d32; }
.tdy-dep.warn { border-color: #b26a00; color: #b26a00; }
.tdy-dep.warn b { color: #b26a00; }
.tdy-dep.bad { border-color: #c62828; color: #c62828; }
.tdy-dep.bad b { color: #c62828; }


/* Кнопка «В список мусора» в карточке зоны (27/07). Отделена от бара обычного
   блока: это решение по всему аккаунту, а не по выбранным кампаниям. */
.zcamp-bar.zgarb { display: block; border-top: 1px dashed var(--line);
  padding-top: 10px; margin-top: 12px; }
.zcamp-bar.zgarb .note { display: block; margin-top: 6px; }

/* 29/07 аудит: тап-цели на телефоне. Главные кнопки действий в строках
   таблиц (.btn.xs) были ~20-22px высоты при рекомендованных ~44px — на
   сенсорном указателе укрупняем без изменения десктопной плотности. */
@media (pointer: coarse) {
  .btn.xs { min-height: 36px; padding-top: 6px; padding-bottom: 6px; }
  .v2-abtn { min-height: 36px; }
  input[type="checkbox"] { width: 18px; height: 18px; }
}

/* 29/07 аудит: поиск по параметрам */
.prm-search { background: var(--bg2, #161b22); color: inherit; border: 1px solid var(--border, #30363d); border-radius: 6px; padding: 4px 10px; font-size: 12px; min-width: 210px; }
.prm-changed-only { font-size: 12px; opacity: .85; display: inline-flex; align-items: center; gap: 5px; margin-right: 4px; }

/* Р3 29/07: вердикт сверки чисел ИИ со складом */
.v2-ai-claims { font-size: 10px; padding: 1px 6px; border-radius: 8px; white-space: nowrap; }
.v2-ai-claims.ok { background: rgba(63,185,80,.12); color: #3fb950; }
.v2-ai-claims.warn { background: rgba(210,153,34,.15); color: #d29922; }
.v2-ai-claims.bad { background: rgba(248,81,73,.15); color: #f85149; }

/* Аккаунт-срез зоны на unblock-карточке (06/08): продажи/ROI/профит 30/90д
   по всему аккаунту — решение «вернуть из блока» живёт в этих числах. */
.v2-zacct { margin: 4px 0 2px; font-size: 12.5px; }
.v2-zacct-lab { color: var(--muted); margin-right: 6px; }
.v2-zacct-sep { color: var(--muted); }

/* ==================================================================== */
/* «Креативы» — контроль выгорания (08/08, заказ Игоря). #/creo (список
   кампаний) + #/creo/c/{id} (карточки вариаций). Свой префикс .creo-*,
   переиспользует общие .card/.tbl/.tablewrap/.badge/.seg/.why/.empty/.note
   (см. app.js). Канон: docs/2026-08-08-creatives-tab.md. */

/* ---- список кампаний (#/creo) ---- */
.creo-listhead { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; }
.creo-tbl .creo-spark-td { text-align: left; }
.creo-camp-link { display: block; color: inherit; }
.creo-camp-link:hover { color: var(--blue); text-decoration: none; }
.creo-cid { color: var(--muted); font-size: 11px; }
.creo-spark { display: block; }
/* стрелка тренда + % — тот же цветовой контракт что creoTrendColor() в JS,
   только классом (для обычного текста, не SVG/canvas). */
.creo-tr-down { color: var(--red); }
.creo-tr-up { color: var(--green); }
.creo-tr-flat { color: var(--blue); }
/* Строки кампаний с хотя бы одним 🔴-баннером — лёгкая красная подложка.
   Фон вешаем на td (не на tr): в table backgrounds ячейки перекрывают фон
   строки, тот же приём что .tbl tr.totals td (style.css выше). */
.creo-tbl tr.creo-burn-row td { background: rgba(248,81,73,.05); }
/* Недостающий вариант палитры бейджей (.b-red/.b-green/.b-yellow/.b-gray уже
   есть) — синий для «плоско/мало данных», намеренно creo-* (не трогаем общий
   набор .b-*, это не Жан-зона). */
.creo-b-blue { background: rgba(88,166,255,.15); color: var(--blue); }
/* Ячейка «Тренд»: две строки — «от пика» (длинный) и «7д» (свежий разворот,
   08/08 ч.3). Колонки «Вчера €/ROI» — лёгкая подложка, чтобы вчерашние
   деньги находились глазом так же быстро, как share на карточке. */
.creo-tr-td { line-height: 1.2; }
.creo-tr-line { font-size: 11px; white-space: nowrap; }
.creo-tr-lbl { color: var(--muted); font-size: 10px; }
.creo-y-td { background: rgba(88,166,255,.05); font-weight: 600; }
/* hover-попап «90 дней» на спарклайне списка */
.creo-pop { position: fixed; z-index: 340; display: none; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
  box-shadow: 0 14px 38px rgba(0,0,0,.55); }
.creo-pop-h { margin-bottom: 8px; font-size: 13px; }
.creo-pop svg { display: block; width: 100%; height: auto; }  /* ч.5: график с осями сам несёт высоту */
/* «7д ↗ +x%» на карточке баннера */
.creo-t7 { font-size: 11px; white-space: nowrap; margin-left: 8px; }

@media (max-width: 840px) {
  .creo-tbl .hide-m { display: none; }
  .creo-tbl .creo-spark { width: 110px; height: 28px; }
}

/* ---- карточка кампании (#/creo/c/{id}) ---- */
.creo-wrap { padding-bottom: 12px; }
.creo-back { display: inline-block; margin: 12px 0 8px; font-size: 13px; }
.creo-head-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.creo-head-top h2 { margin: 0; font-size: 19px; }
.creo-head-money { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 8px;
  font-size: 13px; color: var(--muted); }
.creo-hm-item b { color: var(--text); font-family: var(--mono); margin-left: 4px; }
.creo-chart-wrap { height: 280px; position: relative; }

/* блок «Оффер» [experimental] — жёлто-красная плашка при fatigue_flag */
.creo-offer-fatigue { margin: 6px 0 10px; padding: 8px 10px; border-radius: 8px;
  background: linear-gradient(90deg, rgba(210,153,34,.14), rgba(248,81,73,.10));
  border-left: 3px solid var(--red); font-size: 12.5px; }

.creo-cardhead { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin: 16px 0 8px; }
.creo-cardhead h3 { margin: 0; font-size: 15px; }

/* Цвета вердикта на бейджах — используются и таблицей вариаций (creoVarRowHtml),
   и её дет-строкой (creoVarDetailRow, большой спарклайн той же палитрой). */
.badge.creo-v-burned { background: rgba(248,81,73,.16); color: var(--red); }
.badge.creo-v-fading { background: rgba(210,153,34,.18); color: var(--yellow); }
.badge.creo-v-stable { background: rgba(63,185,80,.16); color: var(--green); }
.badge.creo-v-nodata { background: rgba(88,166,255,.14); color: var(--blue); }

/* ---- таблица вариаций (#/creo/c/{id}) — 08/08 ч.4, заказ Игоря «линиями,
   один в ряд, сортировать по разным параметрам»: сетка карточек (.creo-cards/
   .creo-card*) и сегмент-кнопки сортировки удалены, вместо них — обычная
   sortTh/bindSort таблица (app.js) + лениво вставляемая дет-строка. ---- */
/* Широкий контейнер экранов «Креативов» (ч.6: монитор Игоря 21:9 —
   глобальные 1500px давили таблицу вариаций в кашу). Потолок 2800 —
   чтобы на 3440px строки не растягивались до нечитаемости. */
#view.creo-wide { max-width: 2800px; }
/* Группы колонок (ч.9): всё 7-дневное — единый серый тон, всё «вчера» —
   единый синий; стык групп подчёркнут левой границей. Работает и в thead,
   и в строках — колонка читается сплошной вертикальной полосой. */
.creo-tbl .creo-g7, .creo-var-tbl .creo-g7 { background: rgba(139,148,158,.08); }
.creo-tbl .creo-gy, .creo-var-tbl .creo-gy { background: rgba(88,166,255,.10); font-weight: 600; }
.creo-tbl th.creo-g7, .creo-var-tbl th.creo-g7 { background: rgba(139,148,158,.14); }
.creo-tbl th.creo-gy, .creo-var-tbl th.creo-gy { background: rgba(88,166,255,.16); }
.creo-g7-first { border-left: 2px solid rgba(139,148,158,.5); }
.creo-gy-first { border-left: 2px solid rgba(88,166,255,.5); }
.creo-gy-last { border-right: 2px solid rgba(88,166,255,.35); }

/* ID-кнопка списка кампаний (ч.8): крупная мишень, клик = копия в буфер */
.creo-id-td { width: 96px; }
.creo-id-btn { font-family: var(--mono); font-size: 13px; color: var(--blue);
  background: rgba(88,166,255,.08); border: 1px solid rgba(88,166,255,.25);
  border-radius: 6px; padding: 6px 10px; cursor: pointer; }
.creo-id-btn:hover { background: rgba(88,166,255,.18); }
/* тот же чип как ссылка в шапке кампании (ч.10): номер → статистика ExoClick */
a.creo-exo-link { text-decoration: none; font-size: 14px; padding: 7px 12px; }
a.creo-exo-link:hover { text-decoration: none; color: var(--blue); }
/* ч.8: прокрутка ВСЕЙ страницей, а не внутри фрейма — снимаем внутренний
   скролл tablewrap на экранах «Креативов» (на телефоне ≤840px возвращаем:
   иначе широкая таблица распирает страницу вбок без шанса дотянуться). */
#view.creo-wide .tablewrap { max-height: none; overflow: visible; }
@media (max-width: 840px) {
  #view.creo-wide .tablewrap { max-height: none; overflow-x: auto; }
}
/* легенда над таблицей вариаций */
.creo-vt-legend { font-size: 11.5px; line-height: 1.5; margin: 4px 0 8px; max-width: 1100px; }
/* основание вердикта («−45% от пика») под бейджем */
.creo-vt-basis { display: block; font-size: 10.5px; margin-top: 2px; white-space: nowrap; }
.creo-var-tbl .creo-vt-thumb, .creo-var-tbl .creo-vt-thumb.cre-noimg {
  width: 56px; height: 40px; object-fit: cover; display: block; border-radius: 4px;
  font-size: 8px;
  /* плейсхолдер «нет изображения» не должен вылезать из узкой ячейки в
     соседний тайтл (пойман смоуком 08/08 ч.5) */
  overflow: hidden; line-height: 40px; text-align: center; white-space: nowrap;
}
.creo-vt-thumb-td { width: 60px; }
/* ellipsis тайтла — JS уже режет строку на ~60 символов, CSS дорезает по
   ширине на любом экране (заголовки бывают короче лимита, но всё равно шире
   колонки на телефоне). */
.creo-vt-title { display: inline-block; max-width: 460px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; font-weight: 600; }
/* колонка «Креатив» не должна схлопываться в узком фрейме (ч.6) */
.creo-var-tbl td.l { min-width: 240px; }
.creo-vt-sub { display: block; font-size: 10.5px; margin-top: 2px; }
.creo-vt-subline { font-size: 10.5px; margin-top: 2px; white-space: nowrap; }
.creo-vt-stat-td { white-space: nowrap; }
.creo-vt-stat-td .btn.xs { margin-left: 5px; }
/* строка на паузе — приглушаем ВСЁ, кроме ячейки статуса (иначе не видно
   саму кнопку-переключатель, которой этой строкой и оживляют баннер). */
.creo-var-tbl tr.creo-var-paused td { opacity: .55; }
.creo-var-tbl tr.creo-var-paused td.creo-vt-stat-td { opacity: 1; }
.creo-vt-vcell { cursor: pointer; }
.creo-vt-toggle-td { text-align: center; }

/* дет-строка (лениво вставляется кликом, bindCreoVarTable в app.js) —
   переиспользует общие tr.detail/.det-body (style.css выше даёт фон/паддинг/
   sticky бесплатно); .wl/.wk красим СВОИМ правилом, а не общим
   .why-body .wl/.wk — у того max-width:320px под узкую карточку (см. .why-body
   выше), здесь широкая строка таблицы, сужать незачем. */
.creo-var-det .det-body .wl { margin: 3px 0; line-height: 1.5; }
.creo-var-det .det-body .wk { color: var(--muted); font-weight: 600; margin-right: 4px; }
.creo-var-det .det-body .wl.sub { margin-left: 12px; color: var(--muted); font-size: 11px; }
.creo-vt-bigspark { margin: 8px 0 2px; }

@media (max-width: 840px) {
  .creo-var-tbl .hide-m { display: none; }
}

/* ---- разбор по деньгам (04/09, creo_ladder): колонки списка кампаний,
   ячейка «Деньги» таблицы вариаций, блок причин в дет-строке и drawer'е.
   Свой префикс lad-* — рядом в файле уже живут .cmc-lad* (лестница статусов
   конвейера комиксов), это РАЗНЫЕ вещи. Переиспользует общие .badge/.muted/
   .wl/.wk — нового языка не заводим. ---- */
.creo-lad-head { font-size: 11.5px; margin: 4px 0 8px; display: flex; align-items: center;
  gap: 10px; flex-wrap: wrap; }
.creo-lad-head b { color: var(--text); font-family: var(--mono); }
.creo-lad-asof { font-size: 11px; }
.creo-tbl .creo-lad-td { white-space: nowrap; }
.creo-tbl .creo-lad-eur { font-family: var(--mono); white-space: nowrap; }
/* ячейка «Деньги» в таблице вариаций: три ступени, сумма, вердикт, флаги */
.creo-var-tbl td.creo-lad-td { min-width: 250px; }
.lad-cell { line-height: 1.35; }
.lad-stages, .lad-flags { display: flex; flex-wrap: wrap; gap: 3px; }
.lad-sum { margin: 3px 0 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lad-chip { display: inline-block; font-size: 10.5px; padding: 1px 5px; border-radius: 5px;
  white-space: nowrap; background: rgba(139,148,158,.12); color: var(--muted); }
.lad-chip.lad-down { background: rgba(248,81,73,.16); color: var(--red); }
.lad-chip.lad-up { background: rgba(63,185,80,.16); color: var(--green); }
.lad-chip.lad-flat { background: rgba(88,166,255,.12); color: var(--blue); }
.lad-chip.lad-nd { background: rgba(139,148,158,.12); color: var(--muted); }
.lad-chip.lad-trk-on { background: rgba(63,185,80,.12); color: var(--green); }
.lad-chip.lad-trk-off { background: rgba(139,148,158,.14); color: var(--muted); }
.lad-chip.lad-repl { background: rgba(88,166,255,.16); color: var(--blue); }
.lad-eur { font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--red); }
/* вердикты по деньгам — бейджи вкладки как есть (b-yellow «теряет», b-red
   «выгорел», b-purple «кампания целиком», b-gray — остальное), своих нет */
/* блок причин в дет-строке таблицы и в drawer'е креатива */
.creo-lad-det { margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--border); }
.creo-lad-det .lad-eur { margin-left: 6px; }
.cvd-lad { margin-bottom: 6px; }
.cvd-lad .wl { margin: 3px 0; line-height: 1.5; font-size: 12px; }
.cvd-lad .wk { color: var(--muted); font-weight: 600; margin-right: 4px; }
.cvd-lad .wl.sub { margin-left: 12px; color: var(--muted); font-size: 11px; }

/* ---- модалка «Подобрать замену» (04/09): картинки-кандидаты + тексты.
   Переиспользует .modal-box/.note/.empty/.btn — свои только сетка картинок
   и поля со счётчиком. ---- */
.modal-box.crp-modal { width: min(720px, 96vw); }
.crp-cands { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }
.crp-cand { display: block; width: 150px; cursor: pointer; padding: 6px; border-radius: 8px;
  border: 1px solid var(--border); background: rgba(139,148,158,.06); }
.crp-cand:hover { border-color: var(--blue); }
.crp-img { display: block; width: 100%; height: 100px; object-fit: cover; border-radius: 6px;
  margin: 4px 0; background: rgba(139,148,158,.12); }
.crp-note { display: block; font-size: 10.5px; line-height: 1.35; }
.crp-proven { color: var(--green); }
.crp-fresh { color: var(--muted); }
.crp-texts-head { margin: 10px 0 6px; font-size: 12.5px; display: flex; align-items: center;
  gap: 8px; flex-wrap: wrap; }
.crp-texts.is-hidden { display: none; }
.crp-field { display: block; margin-bottom: 8px; font-size: 12px; color: var(--muted);
  position: relative; }
.crp-count { position: absolute; right: 0; top: 0; font-size: 10.5px; }
.crp-count.over { color: var(--red); font-weight: 600; }
/* поля модалки — как в форме комикса (.cmc-fields input): своего глобального
   правила для input в модалках в файле нет, повторяем тот же вид */
.crp-in { display: block; width: 100%; margin-top: 3px; padding: 6px 8px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit;
  box-sizing: border-box; }
textarea.crp-in { resize: vertical; line-height: 1.45; }

/* ---- офферы кампании (#/creo/c/{id}, под «Оффер×кампания (по редиректам)»)
   бейдж силы по аккаунту (strong/weak/unknown) — переиспользует общие
   .b-green/.b-red/.b-gray (тот же смысл «хорошо/плохо/не знаем», что и везде
   в Пульте, второй набор цветов бейджей ради одной таблицы не заводим). ---- */
.creo-offers { margin-top: 4px; }
.creo-offers-note { margin-top: 6px; font-size: 11px; }

/* ---- Drawer креатива (09/08) — клик по номеру креатива на карточке ленты
   «Сегодня» (openCreativeDrawer, app.js). Переиспользует .zdrawer/.zscrim/
   .zdlabel/.zdsub (drawer зоны/домена/группы), свой префикс .cvd-* только
   для содержимого, которого больше нигде нет. ---- */
.cvd-img { display: block; max-width: 100%; height: auto; max-height: 340px;
  object-fit: contain; border-radius: 8px; border: 1px solid var(--border);
  background: var(--panel2); margin: 0 auto 10px; }
.cvd-noimg { display: flex; align-items: center; justify-content: center;
  min-height: 140px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--panel2); color: var(--muted); font-size: 12px; margin-bottom: 10px; }
.cvd-ad { padding: 2px 0 6px; }
.cvd-ad-line { margin: 4px 0; line-height: 1.45; font-size: 13px; }
.cvd-url { display: block; font-family: var(--mono); font-size: 11.5px; color: var(--blue);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 6px; }
.cvd-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0 4px; }
.cvd-verdict { margin: 4px 0 2px; }
.cvd-reason { margin-top: 6px; line-height: 1.5; font-size: 12.5px; }
/* сетка плиток «цифры» — тот же язык, что .ztt у зоны (подпись мелкая
   приглушённая сверху, значение крупнее снизу), но auto-fill: у вариации
   вдвое больше метрик, фикс repeat(3) как у зоны их бы сплющил. */
.cvd-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.cvd-grid .cell { background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px; }
.cvd-grid .cvd-v { font-family: var(--mono); font-size: 14px; font-weight: 700; margin-top: 4px; }
/* share вчера — самая живая цифра карточки (заказ Игоря «чтобы бросалась в
   глаза»), тот же синий тон, что уже держит колонку «вчера» в таблице
   вариаций (.creo-gy) — не новый акцент, а знакомый глазу. */
.cvd-share-big { grid-column: span 2; background: rgba(88,166,255,.14); border-color: rgba(88,166,255,.45); }
.cvd-share-big .cvd-v { font-size: 1.4em; color: var(--blue); }
.cvd-chart { margin-top: 2px; }
.cvd-chart svg { display: block; width: 100%; height: auto; }
/* .wl/.wk формулы (creoVarFormulaHtml) вне .why-body (max-width:320px — под
   узкую карточку v2, не сюда) и вне .creo-var-det .det-body (та таблица) —
   своя копия правила под ширину дровера, та же причина что app.js:20146. */
.cvd-formula summary { font-size: 11px; color: var(--blue); cursor: pointer; opacity: .85; margin-top: 10px; }
.cvd-formula .wl { margin: 5px 0 0; line-height: 1.5; }
.cvd-formula .wk { color: var(--muted); font-weight: 600; margin-right: 4px; }
.cvd-btns { display: flex; gap: 10px; margin-top: 14px; }

/* ---- Share Advisor (09/08) — модалка «Распределение показов» кнопки
   #creoShareBtn карточки кампании (renderCreoCampaign, app.js). Своя
   компактная таблица .creo-share-tbl (не .creo-var-tbl — вдвое меньше
   колонок, без графика/детали). Ширина/высота модалки шире дефолтных
   440×88vh (см. .modal-box выше) — план обычно 5-8 строк с широкой
   «Причиной», дефолт схлопнул бы таблицу в нечитаемую колонку. Скролл тела —
   бесплатно от базового .modal-body{overflow:auto} (тот же паттерн, что и
   у остальных модалов Пульта, кроме .bp-modal — там своя причина, см. C1
   выше). ---- */
/* ширина под монитор Игоря 21:9 (фидбек 09/08: «обрезается справа») —
   таблице нужны все колонки без горизонтального скролла */
.modal-box.creo-share-modal { width: min(1780px, 96vw); max-height: 88vh; }
.cs-loading { padding: 20px 4px; text-align: center; }
.cs-summary { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.cs-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px;
  border-radius: 999px; background: var(--panel2); border: 1px solid var(--border);
  font-size: 12px; font-family: var(--mono); white-space: nowrap; }
.cs-tbl-wrap { overflow-x: auto; }
table.creo-share-tbl { font-size: 12px; }
.creo-share-tbl th, .creo-share-tbl td { white-space: nowrap; }
.creo-share-tbl th.l, .creo-share-tbl td.l { white-space: normal; }
/* превью 40×26 — вдвое компактнее .creo-vt-thumb (56×40): здесь план на
   просмотр/правку долей, крупная картинка баннера не нужна. */
.cs-thumb, .cs-thumb.cre-noimg {
  width: 40px; height: 26px; object-fit: cover; display: block; border-radius: 3px;
  font-size: 7px; overflow: hidden; line-height: 26px; text-align: center; white-space: nowrap;
}
.cs-thumb-td { width: 44px; }
.cs-sub { font-size: 10px; margin-top: 1px; }
.cs-t7 { font-size: 11px; margin-left: 4px; }
.cs-rpm .muted { font-size: 10.5px; }
.cs-inp { width: 64px; font-family: var(--mono); text-align: right;
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 2px 6px; font-size: 12px; }
/* тон «теста» — синий, как .creo-gy колонок вариаций (тот же язык, не новый акцент) */
.cs-role-test { background: rgba(88,166,255,.15); color: var(--blue); }
/* td.cs-reason: селектор с td обязателен — общий nowrap таблицы иначе
   перебивает по специфичности и причина обрезалась в одну строку
   (фидбек Игоря 09/08 ч.3) */
.creo-share-tbl td.cs-reason { max-width: 300px; white-space: normal; color: var(--muted); line-height: 1.35; font-size: 11px; }
.creo-share-tbl th.cs-sort { cursor: pointer; user-select: none; }
.creo-share-tbl th.cs-sort:hover { color: var(--blue); }
.cs-sum-row { margin-top: 8px; font-size: 13px; }
.cs-sum-row.cs-sum-bad { color: var(--red); font-weight: 700; }
/* бэктест-чип Share Advisor: главный сигнал «стоит ли эта кампания ручного
   Fixed» — прогон по её истории против фактической авто-ротации ExoClick */
.cs-chip.cs-bt.good { background: rgba(63,185,80,.15); border-color: rgba(63,185,80,.5); }
.cs-chip.cs-bt.bad { background: rgba(248,81,73,.12); border-color: rgba(248,81,73,.45); }

/* ==================================================================== */
/* «Тесты креативов» (#/creo/tests, 09/08) — сводка ВСЕХ тестирующихся
   креативов по аккаунту. Свой префикс .ctests-*, переиспользует .creo-tbl/
   .cs-chip/.badge/.tablewrap — та же вкладка «Креативы», не новый язык. */
.ctests-summary { margin: 10px 0 14px; }
/* доля показов на тест — цель 3-10% (зелёный), иначе жёлтый (голодает/ест много) */
.ctests-chip-good { border-color: rgba(63,185,80,.5); background: rgba(63,185,80,.13); }
.ctests-chip-warn { border-color: rgba(210,153,34,.5); background: rgba(210,153,34,.14); }
.ctests-tbl th, .ctests-tbl td { white-space: nowrap; }
.ctests-tbl th.l, .ctests-tbl td.l { white-space: normal; }
.ctests-thumb-td { width: 44px; }
/* превью строки — та же геометрия, что таблица плана Share Advisor (.cs-thumb) */
.ctests-verdict-td { min-width: 150px; }
.ctests-vreason { font-size: 10.5px; margin-top: 2px; max-width: 260px;
  white-space: normal; line-height: 1.35; }
.ctests-act-td { white-space: nowrap; }
.ctests-act-td .btn + .btn { margin-left: 6px; }
/* секции «Отобранные»/«Неудачные» — тот же свёрнутый-details язык, что
   .cre-q (движок), свой цветной борт под исход. */
details.ctests-sec { background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; margin: 10px 0; }
details.ctests-sec-passed { border-left: 3px solid var(--green); }
details.ctests-sec-failed { border-left: 3px solid var(--red); }
details.ctests-sec > summary { cursor: pointer; list-style: none; padding: 9px 11px;
  font-size: 13.5px; font-weight: 700; color: var(--text); }
details.ctests-sec > summary::-webkit-details-marker { display: none; }
details.ctests-sec > summary::before {
  content: '▸'; display: inline-block; margin-right: 6px; color: var(--muted);
}
details.ctests-sec[open] > summary::before { content: '▾'; }
details.ctests-sec > summary:hover { background: rgba(255,255,255,.025); border-radius: 10px; }
details.ctests-sec[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: 8px; }
details.ctests-sec .tablewrap { margin: 0 9px 9px; }
details.ctests-sec summary b { font-family: var(--mono); color: var(--muted); margin-left: 2px; }

/* ==================================================================== */
/* Конвейер тестирования креативов (10/08) — ВЕРХНЯЯ половина #/creo/tests:
   загрузка + запуск в кампании. Свой префикс .ctu-*, переиспользует .panel/
   .btn/.ttl/.badge/.tablewrap/.creo-tbl/.ctests-sec (details архива) — тот
   же визуальный язык, что нижняя половина экрана, не новый стиль. */
.ctu-form { margin-bottom: 14px; }
.ctu-filerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 6px 0 10px; }
.ctu-filebtn { cursor: pointer; }
.ctu-preview { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.ctu-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 6px 3px 10px;
  border-radius: 999px; background: var(--panel2); border: 1px solid var(--border);
  font-size: 11.5px; font-family: var(--mono); white-space: nowrap; }
.ctu-pill-x { background: none; border: 0; color: var(--muted); cursor: pointer;
  font-size: 12px; padding: 0 2px; line-height: 1; }
.ctu-pill-x:hover { color: var(--red); }
.ctu-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px; margin-bottom: 12px; }
.ctu-fields label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.ctu-fields input {
  padding: 6px 8px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); font: inherit; box-sizing: border-box;
}
/* превью строк таблиц конвейера — крупнее .cs-thumb/.ctests-thumb-td (заказ Игоря: 60px) */
.ctu-thumb, .ctu-thumb.ctu-noimg {
  width: 60px; height: 40px; object-fit: cover; display: block; border-radius: 4px;
  font-size: 8px; overflow: hidden; line-height: 40px; text-align: center; white-space: nowrap;
}
.ctu-thumb-td { width: 64px; }
.ctu-descr { font-size: 10.5px; margin-top: 2px; max-width: 260px; white-space: normal; line-height: 1.35; }
.ctu-act-td { white-space: nowrap; }
.ctu-act-td .btn + .btn { margin-left: 6px; }
.ctu-camp-pill { display: inline-block; padding: 1px 6px; border-radius: 999px;
  background: var(--panel2); border: 1px solid var(--border); font-family: var(--mono);
  font-size: 10.5px; margin: 1px 3px 1px 0; }
.ctu-not-deployed { margin-bottom: 14px; }

/* модалка запуска (creoTestLaunchModal) — список кампаний-целей чекбоксами */
.modal-box.ctu-launch-modal { width: min(620px, 96vw); }
.ctu-targets { display: flex; flex-direction: column; gap: 8px; max-height: 50vh; overflow: auto; }
.ctu-target-row { display: flex; align-items: baseline; gap: 8px; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 8px; cursor: pointer; }
.ctu-target-row:hover { background: rgba(255,255,255,.025); }
.ctu-target-name { font-weight: 600; }
.ctu-target-sub { font-size: 11px; }
.ctu-fail-list { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; line-height: 1.5; }

/* ==================================================================== */
/* «Комиксы» (#/comics, 10/08) — ручной реестр офферов HoneyToon. Свой
   префикс .cmc-*, переиспользует .panel/.btn/.badge/.tablewrap/.tbl/
   .modal-box/.hid/.empty/.note. Тема одна — тёмная. */
.cmc-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; }
.cmc-ctl { align-items: center; }
.cmc-ctl input[type="search"] { flex: 1 1 220px; min-width: 180px; max-width: 380px; }
.cmc-ctl .btn.primary { margin-left: auto; }

/* Строка РОДИТЕЛЯ — акцентная подложка. Синий тинт намеренно: красный/зелёный
   в проекте заняты семантикой блока/разблока (tr.hl-*), и семья не должна
   читаться как «решение». Фон на td (а не tr) — чтобы перебивать общий
   tbody tr:hover. */
tr.cmc-parent > td { background: rgba(88,166,255,.10); }
tr.cmc-parent:hover > td { background: rgba(88,166,255,.17); }
/* ПЕРЕВОД — полоса слева + маркер ⤷ и БЕЗ приглушения: языковая версия
   равноправна и может зарабатывать больше родителя (канон DESIGN-плана). */
tr.cmc-child > td:first-child { border-left: 3px solid rgba(88,166,255,.45); }
tr.cmc-row { cursor: pointer; }
.cmc-arrow { color: var(--muted); margin-right: 2px; }
.cmc-lang { display: inline-block; padding: 1px 6px; border-radius: 9px;
  font-size: 10.5px; font-family: var(--mono); font-weight: 700; letter-spacing: .4px;
  background: rgba(139,148,158,.18); color: var(--text); }
.cmc-lang-en { background: rgba(88,166,255,.18); color: var(--blue); }
.cmc-tbl td.cmc-code { font-weight: 700; color: var(--text); letter-spacing: .3px; }
.cmc-tbl td.cmc-title { max-width: 340px; overflow: hidden; text-overflow: ellipsis; }
.cmc-tbl td.cmc-oid { color: var(--muted); }
.cmc-orphan-chip { white-space: nowrap; }
.cmc-act-th { white-space: nowrap; }
.cmc-act-td { white-space: nowrap; }
.cmc-act-td .btn + .btn { margin-left: 4px; }

/* Группы денежных колонок (10/08, заказ Игоря «интересны не 90 дней, а 7 и
   30»): приём вкладки «Креативы» (.creo-g7/.creo-gy) — окно 7д синеватое,
   30д серое, стык групп подчёркнут левой границей, колонка читается сплошной
   вертикальной полосой. Тон кладём background-IMAGE, а не background: под ним
   должны остаться подложка родителя (tr.cmc-parent > td), общий hover и
   var(--panel2) липкой шапки — иначе семья и наведение пропали бы именно в
   денежных колонках. */
.cmc-tbl tbody td.cmc-g7 {
  background-image: linear-gradient(rgba(88,166,255,.10), rgba(88,166,255,.10)); }
.cmc-tbl tbody td.cmc-g30 {
  background-image: linear-gradient(rgba(139,148,158,.08), rgba(139,148,158,.08)); }
.cmc-tbl thead th.cmc-g7 {
  background-image: linear-gradient(rgba(88,166,255,.16), rgba(88,166,255,.16)); }
.cmc-tbl thead th.cmc-g30 {
  background-image: linear-gradient(rgba(139,148,158,.14), rgba(139,148,158,.14)); }
.cmc-tbl .cmc-g7-first { border-left: 2px solid rgba(88,166,255,.5); }
.cmc-tbl .cmc-g30-first { border-left: 2px solid rgba(139,148,158,.5); }
.cmc-tbl .cmc-g30-last { border-right: 2px solid rgba(139,148,158,.35); }

/* строка-деталь (вся введённая информация) — поверх общего tr.detail td */
.cmc-det-sec { margin: 5px 0; }
.cmc-det-lbl { display: block; color: var(--muted); font-size: 10px;
  text-transform: uppercase; letter-spacing: .5px; margin-bottom: 2px; }
.cmc-det-txt { color: var(--text); white-space: pre-wrap; max-width: 900px; }
.cmc-tag { display: inline-block; padding: 1px 7px; border-radius: 9px; font-size: 11px;
  background: rgba(210,168,255,.14); color: var(--purple); margin: 2px 4px 2px 0; }
.cmc-uid { display: inline-block; font-family: var(--mono); font-size: 11px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  padding: 0 6px; margin: 2px 4px 2px 0; color: var(--text); }
.cmc-det-list { margin: 2px 0 0; padding-left: 16px; }
.cmc-det-list li { margin: 1px 0; word-break: break-all; }
.cmc-det-meta { color: var(--muted); font-size: 10.5px; margin-top: 8px; }

/* форма (модалка «Добавить комикс» / редактирование) — язык .ctu-fields */
.modal-box.cmc-form-modal { width: min(720px, 96vw); }
.cmc-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px; }
.cmc-fields > label, .cmc-parent-sel label {
  display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted);
}
.cmc-fields input[type="text"], .cmc-fields input[type="number"],
.cmc-fields select, .cmc-fields textarea {
  width: 100%; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); font: inherit; box-sizing: border-box;
}
.cmc-fields textarea { resize: vertical; line-height: 1.45; }
.cmc-fields input:disabled, .cmc-fields select:disabled { color: var(--muted); }
.cmc-full { grid-column: 1 / -1; }
.cmc-hint { color: var(--muted); font-size: 11px; }
.cmc-lbl { font-size: 12px; color: var(--muted); }
.cmc-lookup { font-size: 11.5px; min-height: 15px; }
.cmc-dup { color: var(--red); font-weight: 700; }
/* черновик: плашка над таблицей + строка в форме (страховка от перезагрузки) */
.cmc-draft-banner {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 7px 10px; font-size: 12px;
  border: 1px solid rgba(210,153,34,.55); border-radius: 8px;
  background: rgba(210,153,34,.10); color: var(--text);
}
.cmc-draft-hint {
  display: flex; align-items: center; gap: 8px; font-size: 11.5px;
  color: var(--yellow);
}
.cmc-parent-block { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
.cmc-radios { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0; }
.cmc-radio { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px;
  border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
  font-size: 12px; color: var(--text); }
.cmc-radio:hover { border-color: var(--muted); }
.cmc-parent-sel { display: flex; flex-direction: column; gap: 4px; }

/* нативные креативы комикса (модалка 🖼, 10/08): зона загрузки + сетка
   превью. Префикс .cmc-crea-*/.cmc-drop-*, переиспользует .modal-box/.btn/
   .empty/.badge. Шире формы (720px) — сетка картинок. */
.modal-box.cmc-crea-modal { width: min(900px, 96vw); }
.cmc-crea-note { font-size: 12px; color: var(--muted); line-height: 1.55; }
.cmc-crea-note b { color: var(--text); font-family: var(--mono); font-size: 12.5px; }
.cmc-crea-fam { font-size: 11.5px; margin-top: 6px; }
.cmc-crea-famid { font-family: var(--mono); }
.cmc-crea-nocode {
  margin-top: 8px; padding: 6px 10px; font-size: 12px; line-height: 1.5;
  border: 1px solid rgba(210,153,34,.55); border-radius: 8px;
  background: rgba(210,153,34,.10); color: var(--text);
}
/* зона перетаскивания: пунктир → подсветка синим на dragover, гашение на
   время отправки (is-busy) и полное выключение без кода комикса (is-off) */
.cmc-drop {
  margin-top: 10px; padding: 16px 12px; text-align: center; cursor: pointer;
  border: 1px dashed var(--border); border-radius: 10px;
  background: rgba(255,255,255,.015);
  transition: border-color .12s, background .12s;
}
.cmc-drop:hover { border-color: var(--muted); }
.cmc-drop.is-over { border-color: var(--blue); background: rgba(88,166,255,.12); }
.cmc-drop.is-busy { opacity: .55; pointer-events: none; }
.cmc-drop.is-off { opacity: .45; pointer-events: none; }
.cmc-drop-main { font-size: 13px; color: var(--text); }
.cmc-drop-btn { cursor: pointer; margin-left: 4px; }
.cmc-drop-sub { font-size: 11px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
/* результаты пред-проверки и ответа сервера — построчно, файлов может быть
   много (тост показал бы только последний) */
.cmc-crea-rej {
  margin-top: 10px; padding: 7px 10px; font-size: 12px;
  border: 1px solid rgba(210,153,34,.45); border-radius: 8px;
  background: rgba(210,153,34,.08);
}
.cmc-crea-rej-ttl { color: var(--yellow); font-weight: 700; margin-bottom: 3px; }
.cmc-crea-rej-row { color: var(--text); line-height: 1.5; word-break: break-word; }
.cmc-crea-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px; margin-top: 12px;
}
.cmc-crea-card {
  display: flex; flex-direction: column; gap: 4px; padding: 7px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--panel2);
}
/* превью: картинка целиком (object-fit: contain) на тёмной подложке — кроп
   врал бы про пропорцию, а она здесь смысловая */
.cmc-crea-thumb {
  height: 104px; border-radius: 6px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.cmc-crea-img { max-width: 100%; max-height: 104px; object-fit: contain; display: block; }
.cmc-crea-thumb .cre-noimg {
  color: var(--muted); font-size: 10.5px; text-align: center; padding: 0 6px;
}
.cmc-crea-line { display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 11px; color: var(--text); }
.cmc-crea-dim { font-family: var(--mono); }
.cmc-crea-ratio { display: inline-block; padding: 0 5px; border-radius: 9px;
  font-size: 10px; font-family: var(--mono);
  background: rgba(88,166,255,.16); color: var(--blue); }
.cmc-crea-own { display: inline-block; padding: 0 5px; border-radius: 9px;
  font-size: 10px; font-family: var(--mono);
  background: rgba(139,148,158,.18); color: var(--muted); }
.cmc-crea-sub { font-size: 10.5px; font-family: var(--mono); color: var(--muted); }
.cmc-crea-noexo { color: var(--yellow); font-family: inherit; }
/* чип тега — три статуса бэкенда: tagged / no_tag_in_exo / error */
.cmc-crea-tag {
  display: inline-block; max-width: 100%; padding: 1px 6px; border-radius: 9px;
  font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: rgba(139,148,158,.18); color: var(--muted);
}
.cmc-crea-tag.is-ok { background: rgba(63,185,80,.15); color: var(--green); }
.cmc-crea-tag.is-warn { background: rgba(210,153,34,.18); color: var(--yellow); }
.cmc-crea-tag.is-bad { background: rgba(248,81,73,.15); color: var(--red); }
.cmc-crea-acts { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.cmc-crea-acts .btn { padding: 2px 6px; }
.cmc-crea-acts .btn + .btn { margin-left: 0; }

/* --- конвейер тестов креативов, Фаза A (10/08) -------------------------
   Чип конвейера в строке семьи, лестница статусов на карточке креатива,
   кнопка копии лендинга с трекингом. Переиспользует .badge/.btn/.muted —
   новых языков не заводим, только свои .cmc-pipe-*/.cmc-ladder-*. */
.cmc-pipe {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 9px;
  font-size: 10.5px; white-space: nowrap; vertical-align: middle;
  background: rgba(139,148,158,.16); color: var(--muted);
}
.cmc-pipe-thin { margin-left: 4px; white-space: nowrap; }
/* хвост трекинга в раскрывашке — моно, ломается по любому символу (длинный) */
.cmc-tail-hint {
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  text-transform: none; letter-spacing: 0; word-break: break-all;
}
.cmc-det-list .cmc-land-copy { margin-left: 6px; vertical-align: baseline; }
/* лестница креатива: серый запас → синий тест → зелёный бой → красный конец */
.cmc-ladder {
  display: inline-block; max-width: 100%; padding: 1px 6px; border-radius: 9px;
  font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: rgba(139,148,158,.18); color: var(--muted);
}
.cmc-ladder.is-bench { background: rgba(139,148,158,.18); color: var(--muted); }
.cmc-ladder.is-queue { background: rgba(88,166,255,.15); color: var(--blue); }
.cmc-ladder.is-fail { background: rgba(248,81,73,.15); color: var(--red); }
/* «в бою» — контур: работает, но не рекорд; «чемпион» — заливка */
.cmc-ladder.is-live {
  background: transparent; color: var(--green);
  box-shadow: inset 0 0 0 1px rgba(63,185,80,.55);
}
.cmc-ladder.is-champ { background: rgba(63,185,80,.18); color: var(--green); font-weight: 700; }
.cmc-ladder.is-burn { background: rgba(248,81,73,.15); color: var(--red); }
.cmc-ladder-live {
  font-size: 10px; font-family: var(--mono); color: var(--muted);
  line-height: 1.45; word-break: break-word;
}
/* форма «В тест» — тот же .cmc-form/.cmc-fields, что форма комикса */
.cmc-enr-final {
  font-size: 10.5px; font-family: var(--mono); word-break: break-all;
  line-height: 1.45; min-height: 14px;
}
.cmc-enr-nolands {
  grid-column: 1 / -1; padding: 7px 10px; font-size: 12px; line-height: 1.5;
  border: 1px solid rgba(210,153,34,.45); border-radius: 8px;
  background: rgba(210,153,34,.08); color: var(--text);
}
/* на карточке креатива теперь до трёх кнопок (В тест / тег / 🗑) — в колонку
   150px одной строкой не влезают, разрешаем перенос */
.cmc-crea-acts { flex-wrap: wrap; }
/* шапка формы «В тест»: превью файла + его паспорт — в семье лежат похожие
   картинки, «какая именно уходит в тест» видно сразу */
.cmc-enr-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cmc-enr-thumb {
  flex: none; width: 116px; height: 68px; border-radius: 6px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.cmc-enr-thumb img { max-width: 100%; max-height: 68px; object-fit: contain; display: block; }
.cmc-enr-thumb .cre-noimg { color: var(--muted); font-size: 10.5px; text-align: center; }
.cmc-enr-head-txt { font-size: 11px; font-family: var(--mono); line-height: 1.5; }
/* «✨ Текст от ИИ» (v4, 11/08) — главный путь заполнения текстов: поля
   открываются пустыми, реестр в них больше не подставляется. Кнопка и её
   подпись стоят НАД полями, во всю ширину сетки. */
.cmc-enr-ai { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cmc-enr-ai .cmc-hint { flex: 1 1 200px; line-height: 1.4; }

/* ==================================================================== */
/* Конвейер v2 (11/08): «Полигоны и роли» + «Очередь скамейки» в шапке
   экрана «Тесты», модалка плана заполнения слотов и чип этапа CTR-сита в
   мониторе. Свой префикс .ctp-*, переиспользует .ctests-sec (details),
   .cs-chip, .creo-tbl, .tablewrap, .note — не новый визуальный язык. */
.ctp-roles-body { padding: 0 11px 10px; }
.ctp-roles-body .note { margin-top: 0; }
.ctp-roles-tbl th, .ctp-roles-tbl td { white-space: nowrap; }
.ctp-roles-tbl th.l, .ctp-roles-tbl td.l { white-space: normal; }
.ctp-roles-tbl tr.ctp-is-poly td { background: rgba(88,166,255,.05); }
.ctp-roles-tbl select.ctp-role-sel {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 6px; font: inherit; font-size: 11.5px;
}
.ctp-algo-td { max-width: 300px; }
.ctp-note { font-size: 10.5px; margin-top: 2px; line-height: 1.35; }
/* режим ротации полигона: Fixed = зелёный, любой другой известный = красный
   (тест не получит своей доли), непрочитанный = серый (повод проверить) */
.ctp-algo {
  display: inline-block; padding: 1px 7px; border-radius: 9px; font-size: 10.5px;
  line-height: 1.5; white-space: normal;
}
.ctp-algo.is-fixed { background: rgba(63,185,80,.15); color: var(--green); font-weight: 700; }
.ctp-algo.is-bad { background: rgba(248,81,73,.15); color: var(--red); }
.ctp-algo.is-unknown { background: rgba(139,148,158,.18); color: var(--muted); }
.ctp-slots { font-family: var(--mono); }
.ctp-slots.is-full { color: var(--yellow); }
/* язык кампании (v4, 11/08): ВЫБОР Игоря, а не эвристика имени. Оба вида —
   кнопки: жёлтая «укажи язык» (полигон/боевая без языка — очередь его
   пропускает) и спокойная «ES» (нажать = сменить). Серое «—» рядом остаётся
   обычным текстом: там выбирать нечего, роли нет. */
.ctp-lang-td { white-space: nowrap; }
.ctp-lang-chip, .ctp-lang-val {
  font: inherit; cursor: pointer; padding: 1px 8px; border-radius: 9px;
  line-height: 1.5; font-size: 10.5px; white-space: nowrap;
}
.ctp-lang-chip {
  border: 1px solid rgba(210,153,34,.5); background: rgba(210,153,34,.14);
  color: var(--yellow); font-weight: 700;
}
.ctp-lang-val {
  border: 1px solid var(--border); background: transparent; color: var(--text);
  font-family: var(--mono); font-weight: 700;
}
.ctp-lang-chip:hover { background: rgba(210,153,34,.24); }
.ctp-lang-val:hover { border-color: var(--blue); color: var(--blue); }
/* мини-модалка «Главный язык кампании» — узкая, один селект */
.modal-box.ctp-lang-modal { width: min(460px, 96vw); }
.ctp-lang-guess { color: var(--yellow); }
.ctp-lang-why {
  margin-top: 10px; font-size: 11.5px; line-height: 1.5; color: var(--muted);
}
/* подсказка «что чинить» — жёлтая, как .cmc-crea-nocode: не ошибка, а шаг */
.ctp-hint {
  margin: 6px 0; padding: 7px 10px; font-size: 12px; line-height: 1.5;
  border: 1px solid rgba(210,153,34,.45); border-radius: 8px;
  background: rgba(210,153,34,.08); color: var(--text);
}
.ctp-warn-list {
  margin: 6px 0 0; padding-left: 18px; font-size: 11.5px; line-height: 1.55;
  color: var(--muted);
}
.ctp-queue { margin: 12px 0 14px; }
.ctp-queue-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ctp-queue-ttl { font-weight: 700; font-size: 13px; }
.ctp-fam-chip { font-family: var(--mono); }
/* модалка плана «кто куда» — с ревизией-2 (11/08) это лист УТВЕРЖДЕНИЯ: в
   каждой строке живут три редактируемых текста объявления, поэтому шире */
.modal-box.ctp-plan-modal { width: min(1120px, 97vw); }
.ctp-plan-wrap { max-height: 56vh; overflow: auto; }
.ctp-plan-tbl th, .ctp-plan-tbl td { white-space: nowrap; }
.ctp-plan-tbl th.l, .ctp-plan-tbl td.l { white-space: normal; }
.ctp-plan-file { font-size: 10.5px; font-family: var(--mono); margin-top: 2px;
  word-break: break-all; }
/* чип «кто пишет тексты» в строке плана (v4): всегда ИИ + язык полигона */
.ctp-txt-chip {
  display: inline-block; margin-left: 5px; padding: 0 6px; border-radius: 9px;
  font-size: 10px; background: rgba(139,148,158,.18); color: var(--muted);
  vertical-align: middle; white-space: nowrap;
}
.ctp-txt-chip.is-ai { background: rgba(88,166,255,.14); color: var(--blue); }
/* панель генерации над таблицей плана */
.ctp-txt-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 6px; }
.ctp-txt-bar-note { font-size: 11.5px; line-height: 1.4; }
/* колонка текстов: три поля + счётчик + пометка «чем написано» */
.ctp-plan-tbl td.ctp-txt-td { white-space: normal; min-width: 290px; }
.ctp-txt-f { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 4px; }
.ctp-txt-in {
  flex: 1 1 auto; min-width: 0; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px;
  font: inherit; font-size: 11.5px; line-height: 1.4;
}
.ctp-txt-in:focus { border-color: var(--blue); outline: none; }
textarea.ctp-txt-in { resize: vertical; }
.ctp-txt-cnt {
  flex: none; width: 42px; text-align: right; font-family: var(--mono);
  font-size: 10px; color: var(--muted); padding-top: 5px;
}
.ctp-txt-cnt.is-full { color: var(--yellow); }
.ctp-txt-note { font-size: 10.5px; line-height: 1.4; color: var(--muted); }
.ctp-txt-note.is-bad { color: var(--red); }
.ctp-txt-warn { color: var(--yellow); }
.ctp-res-list { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; line-height: 1.6; }
.ctp-res-ok { color: var(--green); }
.ctp-res-bad { color: var(--red); }
/* отложен (ИИ был недоступен) — не провал: креатив остался в очереди */
.ctp-res-wait { color: var(--yellow); }
/* этап вердикта: пока идёт CTR-сито — деньги ещё не судят */
.ctp-stage-chip {
  display: inline-block; margin-left: 5px; padding: 0 6px; border-radius: 9px;
  font-size: 10px; background: rgba(88,166,255,.14); color: var(--blue);
  vertical-align: middle;
}
.ctp-sift-reason { font-size: 10.5px; margin-top: 2px; max-width: 260px;
  white-space: normal; line-height: 1.35; }
.ctp-sift-reason.is-drop { color: var(--red); }
.ctp-sift-reason.is-pass { color: var(--green); }
.ctp-sift-reason.is-wait { color: var(--muted); }
/* очередь скамейки на карточке креатива комикса (модалка 🖼) */
.cmc-crea-ckl { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 10.5px; color: var(--muted); }
.cmc-crea-qbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--border); }
.cmc-crea-qhint { font-size: 11px; }

/* ==================================================================== */
/* «Медиатека» (#/media, 11/08) — склад наших картинок: галерея с крупными
   превью + лайтбокс карточки файла. Свой префикс .ctm-*; чипы/сегменты/
   таблицы берём общие (.seg, .tbl, .empty, .note), новых языков не заводим. */
.ctm-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ctm-chips { display: inline-flex; gap: 6px; flex-wrap: wrap; }
/* счётчик-чип: он же фильтр (клик ставит/снимает) — поэтому кнопка, а не span */
.ctm-cnt {
  padding: 2px 9px; border-radius: 11px; cursor: pointer; font-size: 11.5px;
  border: 1px solid var(--border); background: var(--panel); color: var(--muted);
}
.ctm-cnt b { color: var(--text); font-family: var(--mono); }
.ctm-cnt:hover { border-color: var(--muted); }
.ctm-cnt.on { background: var(--panel2); color: var(--text); border-color: var(--blue); }
.ctm-ctl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ctm-ctl input[type="search"] { min-width: 190px; }
.ctm-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 12px; margin-top: 12px;
}
.ctm-card {
  position: relative;
  display: flex; flex-direction: column; gap: 4px; padding: 8px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 10px; background: var(--panel2);
}
.ctm-card:hover { border-color: var(--blue); }
/* убранный файл (сегмент «убранные») — приглушён, чтобы в общем списке
   («все») не спорил взглядом с живыми, но оставался читаемым */
.ctm-card.is-off { opacity: .62; }
.ctm-card.is-off:hover { opacity: 1; }
/* угловая кнопка «🗑 Убрать» / «↩ Вернуть»: поверх превью, видна ВСЕГДА (на
   телефоне hover'а нет — спрятанная под наведение кнопка там не существует) */
.ctm-act {
  position: absolute; top: 12px; right: 12px; z-index: 1; cursor: pointer;
  padding: 1px 7px; border-radius: 9px; font-size: 10.5px; line-height: 17px;
  border: 1px solid var(--border); background: rgba(13,17,23,.78); color: var(--muted);
}
.ctm-act:hover { color: #ff9c95; border-color: rgba(248,81,73,.6); }
.ctm-act.is-back:hover { color: #6fdd82; border-color: rgba(63,185,80,.6); }
/* превью целиком (contain) на тёмной подложке: кроп врал бы про пропорцию, а
   здесь она — смысл (по ней решается, поедет ли файл в ExoClick) */
.ctm-thumb {
  height: 190px; border-radius: 6px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.ctm-img { max-width: 100%; max-height: 190px; object-fit: contain; display: block; }
.ctm-thumb .cre-noimg { color: var(--muted); font-size: 11px; text-align: center; padding: 0 8px; }
.ctm-name {
  font-size: 11.5px; color: var(--text); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.ctm-line { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 11px; }
.ctm-dim { font-family: var(--mono); color: var(--muted); font-size: 10.5px; }
.ctm-code {
  display: inline-block; max-width: 130px; padding: 0 6px; border-radius: 9px;
  font-size: 10.5px; font-family: var(--mono); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
  background: rgba(88,166,255,.16); color: var(--blue);
}
.ctm-chip {
  display: inline-block; max-width: 100%; padding: 1px 6px; border-radius: 9px;
  font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: rgba(139,148,158,.18); color: var(--muted);
}
.ctm-chip.is-ok { background: rgba(63,185,80,.15); color: var(--green); }
.ctm-chip.is-bad { background: rgba(248,81,73,.15); color: var(--red); }
/* жёлтый — «поправимо руками» (нет имени тега в ExoClick), не «сломано» */
.ctm-chip.is-warn { background: rgba(210,153,34,.16); color: var(--yellow); }
/* ступень конвейера: синий — файл в движении (очередь/тест) */
.ctm-chip.is-queue { background: rgba(88,166,255,.15); color: var(--blue); }
/* «в бою» — контуром, а не заливкой: боевых на складе мало, и рамка выделяет
   их сильнее ещё одной цветной плашки. padding на 1px меньше — рамка не
   должна ронять высоту строки чипов */
.ctm-chip.is-live {
  padding: 0 5px; background: transparent; color: var(--green);
  border: 1px solid rgba(63,185,80,.55);
}
.ctm-money { font-size: 10.5px; font-family: var(--mono); color: var(--muted); line-height: 1.45; }

/* --- лайтбокс карточки файла ------------------------------------------
   Свой узел #ctmLb ПОВЕРХ #modal (z 300) — модалка креативов комикса
   открывается прямо с этого экрана кнопкой «+ Загрузить». */
.ctm-lb {
  position: fixed; inset: 0; z-index: 360; display: none;
  background: rgba(0,0,0,.82); align-items: center; justify-content: center; padding: 14px;
}
.ctm-lb.on { display: flex; }
/* На время подтверждения («Убрать файл?») лайтбокс уходит ПОД #modal (z 300):
   confirmModal рисуется в #modal, и без этого вопрос оказался бы под
   затемнением карточки — кликнуть было бы некуда. */
.ctm-lb.is-under { z-index: 290; }
/* Тост (#toast, z 200) лежит ниже лайтбокса — из открытой карточки ответ
   («тег проставлен», «файл вернулся») был бы не виден. Пока карточка открыта,
   поднимаем его над ней. */
body.ctm-lb-on #toast { z-index: 380; }
.ctm-lb-box {
  position: relative; max-width: 96vw; max-height: 92vh; overflow: auto;
  padding: 14px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel);
}
.ctm-lb-x {
  position: absolute; top: 6px; right: 8px; z-index: 1; cursor: pointer;
  border: none; background: transparent; color: var(--muted); font-size: 15px; line-height: 1;
}
.ctm-lb-x:hover { color: var(--text); }
.ctm-lb-in { display: flex; gap: 16px; align-items: flex-start; }
/* Картинка ужимается ПЕРВОЙ (flex-shrink на ней, у панели shrink 0): деньги
   кампаний важнее лишней сотни пикселей превью — при 70vw картинки таблица
   уезжала за край панели и колонки «доход/профит» приходилось доскроливать. */
.ctm-lb-img {
  flex: 0 1 auto; min-width: 160px; max-width: 70vw;
  border-radius: 6px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.ctm-lb-img img { max-width: 100%; max-height: 85vh; object-fit: contain; display: block; }
.ctm-lb-img .cre-noimg { color: var(--muted); font-size: 12px; padding: 40px; }
.ctm-lb-side { flex: 1 0 700px; min-width: 0; max-width: 860px; }
.ctm-lb-name { font-size: 14px; font-weight: 700; word-break: break-word; margin-right: 18px; }
.ctm-lb-comic { font-size: 12px; margin: 4px 0 6px; }
.ctm-lb-facts { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-bottom: 6px; }
.ctm-lb-when { font-size: 11px; margin-top: 6px; }
.ctm-why {
  margin-top: 6px; padding: 6px 9px; font-size: 11.5px; line-height: 1.5;
  border-radius: 8px; word-break: break-word;
  border: 1px solid rgba(248,81,73,.4); background: rgba(248,81,73,.08); color: var(--text);
}
.ctm-lb-acts { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 4px; }
.ctm-lb-sec { font-size: 12px; font-weight: 700; margin: 12px 0 5px; }
.ctm-lb-sec .muted { font-weight: 400; }
.ctm-lb-win { font-size: 10.5px; margin-top: 5px; }
.ctm-c-tbl { font-size: 11.5px; }
.ctm-c-tbl td, .ctm-c-tbl th { padding: 3px 6px; }
.ctm-c-sub { font-size: 10px; font-family: var(--mono); color: var(--muted); }
.ctm-c-tbl td.ctm-w { font-family: var(--mono); color: var(--muted); font-size: 10px; }
.ctm-c-row90 td { color: var(--muted); }
/* Узкий экран: картинка сверху, панель под ней. Порог 1080, а не 900 —
   таблица кампаний просит ~700px, и в двух колонках ниже этой ширины ей
   пришлось бы жить в горизонтальном скролле. */
@media (max-width: 1080px) {
  .ctm-lb-in { flex-direction: column; }
  .ctm-lb-img { max-width: 100%; }
  .ctm-lb-img img { max-width: 86vw; max-height: 44vh; }
  .ctm-lb-side { min-width: 0; max-width: 100%; flex: 1 1 auto; width: 100%; }
}
/* телефон: карточки мельче, иначе в столбик по одной */
@media (max-width: 700px) {
  .ctm-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .ctm-thumb { height: 130px; }
  .ctm-img { max-height: 130px; }
}

/* «Возвраты» (ревизия 20/08 вечер, tasks/2026-08-20-pearls-tab.md): колонка
   «кампания» единой таблицы пар — ширина колонки ограничена, длинное имя
   режется многоточием, полное имя доступно через title на самой ячейке
   (жалоба Игоря на прежние две корзины: «перечисление названий кампаний
   занимает огромное количество места»). */
.tbl td.prl-camp, .tbl th.prl-camp {
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
