/* ============================================================
   Единая система интерфейса. Профиль «Спокойный контроль».

   Ощущение: самостоятельный аналитический продукт, а не встроенный
   кабинет площадки. Почти белый холодный лист, белые карточки,
   насыщенный синий на действии, оранжевый на росте и точках роста,
   зеленый и красный - только на смысле числа.

   Правила:
   1. Глубина: белая карточка на светлом листе плюс мягкая тень.
      Обводка тонкая и только там, где тени мало.
   2. Синий - единственный цвет обычного действия. Оранжевый занимает
      5-8 процентов экрана и означает рост или слабое место, а не «нажми».
   3. Доля цветов: 70 белого и почти белого, 20 нейтрального серо-синего,
      7 синего, 3 оранжевого и статусов. Премиальность дает воздух и
      ограничение палитры, а не темный фон.
   4. Цифры набираются табличными знаками везде, где их сравнивают глазами.
   5. Радиусы крупные: 10 на управлении, 16 на карточках, 20 на слоях.
   ============================================================ */

:root {
  /* ---- бренд ---- */
  --brand-primary: #2563EB;
  --brand-primary-hover: #1D4ED8;
  --brand-primary-pressed: #1E40AF;
  --brand-primary-soft: #EFF6FF;
  --brand-primary-border: #BFDBFE;

  /* ---- акцент: рост, точки роста, слабые места ---- */
  --accent-orange: #F97316;
  --accent-orange-dark: #C2410C;
  --accent-orange-soft: #FFF7ED;
  --accent-orange-border: #FED7AA;

  /* ---- поверхности ---- */
  --bg-app: #F6F8FC;
  --bg-surface: #FFFFFF;
  --bg-subtle: #F8FAFC;
  --bg-hover: #F1F5F9;
  --bg-selected: #EFF6FF;

  /* ---- текст ---- */
  --text-heading: #172033;
  --text-primary: #334155;
  --text-secondary: #64748B;
  --text-muted: #94A3B8;
  --text-disabled: #CBD5E1;
  --text-link: #1D4ED8;

  /* ---- границы ---- */
  --border-default: #E2E8F0;
  --border-strong: #CBD5E1;

  /* ---- статусы ---- */
  --success: #15803D;
  --success-soft: #F0FDF4;
  --success-border: #BBF7D0;
  --warning: #B45309;
  --warning-soft: #FFFBEB;
  --warning-border: #FDE68A;
  --error: #DC2626;
  --error-soft: #FEF2F2;
  --error-border: #FECACA;
  --info: #2563EB;
  --info-soft: #EFF6FF;

  /* ---- ряды графиков ---- */
  --chart-blue: #2563EB;
  --chart-orange: #F97316;
  --chart-green: #16A34A;
  --chart-purple: #7C3AED;
  --chart-cyan: #0891B2;
  --chart-yellow: #D97706;
  --chart-red: #DC2626;
  --chart-gray: #64748B;

  /* Метки модулей. Нужны графикам, значкам и тегам внутри аналитики.
     В левом меню не применяются: там все пункты серые, активный синий. */
  --mod-doctor: var(--accent-orange);
  --mod-autoload: var(--chart-blue);
  --mod-bidder: var(--chart-purple);
  --mod-rivals: var(--chart-cyan);
  --mod-hours: var(--chart-yellow);

  /* ---- Рабочие имена, которыми пользуется вся разметка ----
     Один слой псевдонимов вместо переименования тысячи строк: смысл
     остался прежним, значение теперь берется из палитры выше. */
  --canvas: var(--bg-app);
  --surface: var(--bg-surface);
  --sunken: var(--bg-subtle);
  --sunken-2: var(--bg-hover);

  --ink: var(--text-heading);
  --ink-2: var(--text-primary);
  --ink-3: var(--text-secondary);
  --ink-4: var(--text-muted);

  --line: var(--border-default);
  --line-soft: #EFF3F9;
  --line-strong: var(--border-strong);

  --blue: var(--brand-primary);
  --blue-dark: var(--brand-primary-hover);
  --blue-deep: var(--text-link);
  --blue-press: var(--brand-primary-pressed);
  --blue-soft: var(--brand-primary-soft);
  --blue-line: var(--brand-primary-border);

  --green: var(--chart-green);
  --green-ink: var(--success);
  --green-soft: var(--success-soft);
  --alarm: var(--error);
  --alarm-soft: var(--error-soft);
  --warn: var(--warning);
  --warn-soft: var(--warning-soft);
  --violet: var(--chart-purple);

  --control: var(--bg-subtle);
  --control-line: var(--border-strong);
  --focus: rgba(37, 99, 235, 0.20);

  /* Старые имена, на которые ссылается разметка внутри скриптов.
     Держим их живыми, иначе цвет молча теряется и текст падает в черный. */
  --green-dark: var(--success);
  --dim: var(--text-secondary);

  --r-s: 10px;   /* кнопки, поля */
  --r-m: 16px;   /* карточки */
  --r-l: 20px;   /* всплывающие слои */

  --shadow-card: 0 1px 3px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.04);
  --shadow-lift: 0 2px 6px rgba(15, 23, 42, 0.06), 0 12px 28px rgba(15, 23, 42, 0.10);
  --shadow-pop: 0 12px 40px rgba(15, 23, 42, 0.18);

  /* Заголовки набираются Geologica: широкие, чуть техничные буквы, за счет
     них раздел читается как заголовок даже боковым зрением. Шрифт с
     характером, поэтому он и стоит только на заголовках.

     Все остальное, и особенно цифры, набирается Inter. У него самые ровные
     табличные знаки: в столбце сумм цифры стоят строго друг под другом, а
     единица не оставляет дыру. Для кабинета, где половина экрана - числа,
     это важнее характера шрифта.

     Оба лежат своими файлами в web/fonts, см. fonts.css. Там же запасным
     лежит Golos Text: чтобы поменять пару, хватит этих двух строк. */
  --display: Geologica, Inter, -apple-system, "Segoe UI", Arial, sans-serif;
  --body: Inter, Geologica, -apple-system, "Segoe UI", Arial, sans-serif;

  /* шаг сетки 4px */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s6: 24px; --s8: 32px; --s12: 48px;

  --side: 254px;
  --head: 62px;
  --brand: 62px;
}

*, *::before, *::after { box-sizing: border-box; }

html { color-scheme: light; }

/* Кому тяжело от движения, тому его и не показываем */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* На касании не ждем полсекунды перед нажатием */
button, .btn, .pill, .fsel, a { touch-action: manipulation; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--blue); color: #fff; padding: 10px 16px; border-radius: 0 0 var(--r-s) 0;
}
.skip:focus { left: 0; text-decoration: none; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--display); font-weight: 700; letter-spacing: -0.02em; margin: 0; }
a { color: var(--blue-deep); text-decoration: none; }
a:hover { text-decoration: underline; }
.hidden { display: none !important; }

/* Цифры одной ширины везде, где они сравниваются глазами */
.num, table, input, .kpi__v, .fun__v, .ind__v, .hub__v { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

::selection { background: var(--blue); color: #fff; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }

/* ---------- кнопки ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font: inherit; font-weight: 700; font-size: 14px;
  color: #fff; background: var(--blue);
  border: 1px solid var(--blue); border-radius: var(--r-s);
  padding: 9px 18px; cursor: pointer; white-space: nowrap;
  transition: background .14s ease, border-color .14s ease, box-shadow .14s ease;
}
.btn:hover { background: var(--blue-dark); border-color: var(--blue-dark); text-decoration: none; }
.btn:active { background: var(--blue-press); border-color: var(--blue-press); }
.btn:disabled, .btn[disabled] { opacity: .45; cursor: default; }
.btn:disabled:hover, .btn[disabled]:hover { background: var(--blue); border-color: var(--blue); }
.btn--light { color: var(--ink); background: var(--surface); border-color: var(--line-strong); }
.btn--light:hover { background: var(--sunken); border-color: var(--line-strong); color: var(--ink); }
.btn--ghost { color: var(--ink-2); background: transparent; border-color: transparent; }
.btn--ghost:hover { background: var(--sunken-2); border-color: transparent; color: var(--ink); }
.btn--wide { width: 100%; }
.btn--sm { padding: 7px 14px; font-size: 13px; }

/* ---------- поля ---------- */

.field { margin-bottom: var(--s3); }
.field label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; }
.field .hint, .note { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; margin: var(--s2) 0 0; }

input[type="text"], input[type="password"], input[type="date"], input[type="number"], textarea, select {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink);
  background: var(--control); border: 1px solid var(--control-line);
  border-radius: var(--r-s); padding: 10px 12px;
  transition: border-color .14s ease, box-shadow .14s ease, background .14s ease;
}
input::placeholder, textarea::placeholder { color: var(--ink-4); }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--focus); background: var(--surface); }

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

.msg { border-radius: var(--r-s); padding: 10px 13px; font-size: 13.5px; margin-top: var(--s3); }
.msg--err { background: var(--alarm-soft); color: var(--alarm); }
.msg--ok { background: var(--green-soft); color: var(--green-ink); }
.msg--wait { background: var(--sunken-2); color: var(--ink-2); }
.empty, .loading { padding: var(--s8) var(--s4); text-align: center; color: var(--ink-2); }
.sep { height: 1px; background: var(--line); margin: var(--s6) 0; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

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

.gate {
  min-height: 100vh; display: grid; place-items: center; padding: var(--s6);
  background: var(--canvas);
}
.gate__card {
  width: 100%; max-width: 430px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-l); padding: var(--s8);
  box-shadow: var(--shadow-lift);
}
.gate__logo { display: block; margin: 0 auto var(--s4); border-radius: 14px; }
.gate__card h1 { font-size: 24px; margin-bottom: 6px; }
.gate__card .sub { margin: 0 0 var(--s6); color: var(--ink-2); font-size: 14px; }
.gate__lock { font-size: 12px; color: var(--ink-3); line-height: 1.5; margin-top: var(--s4); }
/* Дорога к настройкам входа прямо с ворот: без нее человек с пустым
   кабинетом не мог добраться ни до телеграма, ни до смены пароля. */
.gate__check {
  display: flex; align-items: center; gap: 8px; font-size: 13px;
  color: var(--ink-2); margin: 0 0 var(--s3);
}
.gate__check input { width: 16px; height: 16px; accent-color: var(--blue); }
.gate__link { display: inline-block; margin-top: 6px; font-weight: 600; }

/* ============================================================
   Список клиентов: первый экран после пароля
   ============================================================ */

.hub { min-height: 100vh; padding: var(--s12) var(--s6); }
.hub__head {
  max-width: 1760px; margin: 0 auto var(--s6);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
}
.hub__head h1 { font-size: clamp(24px, 3vw, 32px); }
.hub__row { display: flex; align-items: center; gap: var(--s2); }

.hub__grid {
  max-width: 1760px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr)); gap: var(--s4);
}
.hub__card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  padding: var(--s4) var(--s4) var(--s3);
  display: flex; flex-direction: column; gap: var(--s3);
  box-shadow: var(--shadow-card);
  transition: box-shadow .16s ease, transform .16s ease;
}
.hub__card:hover { box-shadow: var(--shadow-lift); transform: translateY(-1px); }

.hub__top { display: flex; align-items: center; gap: var(--s3); }
.hub__ava {
  width: 44px; height: 44px; flex: none; border-radius: 50%;
  color: #fff; font-weight: 800; font-size: 15px; display: grid; place-items: center;
}
.hub__who { min-width: 0; }
.hub__name {
  font-weight: 700; font-size: 15px; line-height: 1.25;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.hub__id { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.hub__note-own { opacity: .8; font-style: italic; }

.hub__facts {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2);
  padding: var(--s3); background: var(--sunken); border-radius: var(--r-s);
}
.hub__fact { min-width: 0; }
.hub__k { font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.hub__v { font-size: 15px; font-weight: 800; margin-top: 2px; white-space: nowrap; }
.hub__wait { color: var(--ink-4); font-weight: 400; }
.hub__bad { color: var(--alarm); }

/* Подвал прижат к низу: карточки в ряду разной высоты из-за длины имени,
   а кнопка «Открыть» должна стоять на одной линии во всем ряду. */
.hub__foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.hub__note { font-size: 11.5px; color: var(--ink-3); line-height: 1.35; }
.hub__note .ic { width: 13px; height: 13px; margin-right: 4px; vertical-align: -2px; }
.hub__open .ic { margin-left: 5px; }
.hub__x .ic, .hub__add .ic { margin-right: 6px; }
/* Список клиентов: пустой экран стоит в белой карточке, как и раньше */
.hub .art {
  max-width: 1760px; margin: 0 auto; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-m); box-shadow: var(--shadow-card);
}
.hub__note--ok { color: var(--green-ink); }
.hub__note--bad { color: var(--alarm); }

.hub__open, .hub__add {
  font: inherit; font-size: 13.5px; font-weight: 700; color: #fff;
  background: var(--blue); border: 1px solid var(--blue); border-radius: var(--r-s);
  padding: 9px 17px; cursor: pointer; white-space: nowrap;
  transition: background .14s ease, border-color .14s ease;
}
.hub__open:hover, .hub__add:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.hub__tools { display: flex; gap: 2px; margin-top: -6px; }
.hub__x {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--ink-3);
  background: none; border: 0; padding: 5px 8px; border-radius: 7px; cursor: pointer;
}
.hub__x:hover { color: var(--blue-deep); background: var(--blue-soft); }
/* В шапке списка это полноценное действие, а не мелкая ссылка у карточки */
.hub__head .hub__x {
  font-size: 13.5px; padding: 9px 16px; border-radius: var(--r-s);
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink);
}
.hub__head .hub__x:hover { background: var(--sunken); color: var(--ink); }
.hub__tools .hub__x:last-child:hover { color: var(--alarm); background: var(--alarm-soft); }

.hub__empty {
  max-width: 1760px; margin: 0 auto var(--s4); padding: var(--s8);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  box-shadow: var(--shadow-card); color: var(--ink-2);
}
.hub__form {
  max-width: 480px; margin: var(--s6) auto 0; padding: var(--s6);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  box-shadow: var(--shadow-card);
}
.hub__h2 { font-family: var(--display); font-weight: 700; margin: 0 0 var(--s3); font-size: 18px; }
.hub__field { margin-bottom: var(--s3); }
.hub__field label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; }
.hub__hint { font-size: 12px; color: var(--ink-3); line-height: 1.45; margin: var(--s2) 0 0; }
.hub__msg { border-radius: var(--r-s); padding: 9px 12px; font-size: 13px; margin-top: var(--s2); }
.hub__msg--err { background: var(--alarm-soft); color: var(--alarm); }
.hub__msg--ok { background: var(--green-soft); color: var(--green-ink); }
.hub__msg--wait { background: var(--sunken-2); color: var(--ink-2); }

/* ============================================================
   Каркас приложения: полоса бренда во всю ширину, под ней
   боковая колонка и рабочая область
   ============================================================ */

.app {
  display: grid;
  grid-template-columns: var(--side) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  min-height: 100vh;
}

.brandbar {
  grid-column: 1 / -1;
  position: sticky; top: 0; z-index: 30;
  min-height: var(--brand);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2) var(--s6) var(--s2) var(--s4);
}
.brandbar__logo { display: inline-flex; align-items: center; }
/* Знак повторяет значок вкладки: один образ везде. Подписи рядом нет -
   продукт называет себя знаком, а не словом «авито». */
.brandbar__mark { width: 28px; height: 28px; flex: none; border-radius: 8px; }
.brandbar__spacer { flex: 1 1 auto; }

.brandbar__back {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-2);
  background: var(--sunken); border: 1px solid transparent; border-radius: var(--r-s);
  padding: 8px 14px; cursor: pointer; white-space: nowrap;
  transition: background .14s ease, color .14s ease;
}
.brandbar__back:hover { background: var(--blue-soft); color: var(--blue-deep); }

/* карточка клиента справа: кружок с инициалами, имя, номер */
.brandbar__who { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
.brandbar__ava {
  width: 34px; height: 34px; flex: none; border-radius: 50%;
  background: var(--blue);
  color: #fff; font-weight: 800; font-size: 13px; display: grid; place-items: center;
}
.brandbar__lines { min-width: 0; line-height: 1.25; }
.brandbar__name {
  font-size: 13.5px; font-weight: 700; max-width: 220px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.brandbar__id { font-size: 11.5px; color: var(--ink-3); }

/* Боковая колонка: белая, отделена линией, разделы группами */
.side {
  grid-column: 1; grid-row: 2;
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: var(--s3) var(--s3) var(--s8);
  /* Высота фиксированная, а не по содержимому: иначе белая колонка
     обрывалась бы на последнем разделе и ниже проступал лист. */
  position: sticky; top: var(--brand); align-self: start;
  height: calc(100vh - var(--brand)); overflow-y: auto;
  scrollbar-width: thin;
}

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav__group {
  font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-4); padding: var(--s4) var(--s3) var(--s1);
}
.nav__group:first-child { padding-top: var(--s2); }
.nav button {
  position: relative;
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px var(--s3); border: 0; background: none; border-radius: var(--r-s);
  cursor: pointer; text-align: left; font: inherit; font-size: 14px; color: var(--ink-2);
  transition: background .13s ease, color .13s ease;
}
.nav button:hover { background: var(--sunken); color: var(--ink); }
.nav button.is-on { background: var(--blue-soft); color: var(--blue-deep); font-weight: 700; }
/* Полоска слева: активный раздел виден периферийным зрением, без вчитывания */
.nav button.is-on::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--blue);
}
/* Значок раздела: цвет берет у пункта, поэтому отдельных правил на состояния
   не нужно. В покое приглушен, чтобы строка читалась словом, а не картинкой. */
.nav__i { width: 19px; height: 19px; flex: none; opacity: .62; transition: opacity .13s ease; }
.nav button:hover .nav__i { opacity: .9; }
.nav button.is-on .nav__i { opacity: 1; }
.nav__t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* рабочая область */
.work { grid-column: 2; grid-row: 2; min-width: 0; display: flex; flex-direction: column; }

/* шапка страницы: заголовок, период, действия */
.top {
  position: sticky; top: var(--brand); z-index: 20;
  background: var(--canvas);
  border-bottom: 1px solid var(--line);
}
.top__in {
  min-height: var(--head); padding: var(--s2) var(--s6);
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
}
/* Путь до раздела. Тихий целиком: заголовок страницы разделы пишут сами,
   и крупный текст в шапке был бы вторым таким же заголовком строкой выше. */
.top__title { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.top__crumb { font-size: 13.5px; font-weight: 600; color: var(--ink-3); white-space: nowrap; }
.top__crumb::after { content: "/"; padding-left: 7px; color: var(--ink-4); }
.top__now { font-size: 13.5px; font-weight: 700; color: var(--ink-2); white-space: nowrap; }
.top__tools { margin-left: auto; display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }

/* Потолка по ширине нет: на большом мониторе он оставлял справа пустую
   полосу в пол-экрана, а прижат контент был к левому краю. Разъехаться
   содержимому не дают сами блоки: карточки идут сеткой, таблицы листаются
   внутри своей коробки, у абзацев своя мера строки. */
.main { padding: var(--s6); max-width: none; }

/* Пара блоков в ряд на широком экране. Раньше воронка, показатели и узкие
   карточки шли друг под другом во всю ширину, и справа оставалось пустое
   поле в пол-экрана. Ниже 1360 они снова встают столбиком. */
.cols2 { display: grid; gap: var(--s4); align-items: start; }
/* Без этого широкая таблица внутри колонки не дает ей сжаться и растягивает
   всю страницу: у ячейки грида ширина по содержимому, а не по колонке. */
.cols2 > * { min-width: 0; }
@media (min-width: 1360px) {
  .cols2 { grid-template-columns: 1fr 1fr; gap: var(--s6); }
}
/* Пара, которой мало половины экрана: делится только на очень широком */
@media (max-width: 1639px) {
  .cols2--wide { grid-template-columns: 1fr; }
}
/* Листы разборов - сплошные таблицы, разделы кабинета - карточки.
   Разница только в воздухе сверху, дальше оформление общее. */
.pane--sheet { padding-top: var(--s4); }

/* ---------- общие карточки ---------- */

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: var(--s4) var(--s6) var(--s6);
  margin-bottom: var(--s4); box-shadow: var(--shadow-card);
}
.card > h2, .card > h3 { font-size: 17px; margin-bottom: var(--s3); }
.card--flat { padding: 0; overflow: hidden; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: var(--s3); }
/* Пара «название - значение» держится в разумной мере: на большом мониторе
   карточка шире тысячи пикселей, и значение улетало к дальнему краю. */
.kv { display: flex; justify-content: space-between; gap: var(--s3); padding: 8px 0; border-bottom: 1px solid var(--line-soft); max-width: 760px; }
.kv:last-child { border-bottom: 0; }
.kv span:first-child { color: var(--ink-2); }
.kv span:last-child { font-weight: 700; text-align: right; }

/* ---------- таблицы, один вид на все приложение ----------

   Коробка таблицы держит рамку и выбор сортировки, а прокручивается только
   сама таблица внутри нее. Из-за этого шапка со столбцами и остается на
   виду: липкий заголовок прилипает к своему контейнеру прокрутки, а не к
   окну, и без ограничения по высоте не работал вовсе. */

.tablebox {
  border: 1px solid var(--line); border-radius: var(--r-m);
  background: var(--surface); box-shadow: var(--shadow-card);
  margin-bottom: var(--s4); overflow: hidden;
}
.tablebox > .scroll {
  border: 0; border-radius: 0; box-shadow: none; margin: 0;
  /* Высоту режем только у длинных таблиц: короткие остаются как были */
  max-height: calc(100vh - 200px);
}

.scroll {
  overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-m);
  background: var(--surface); margin-bottom: var(--s4); box-shadow: var(--shadow-card);
  /* Тень у края появляется, только когда вбок действительно есть что
     листать: в таблице объявлений за краем остаются расходы и цена заявки,
     и без этой подсказки их просто не находят. Две «заслонки» едут вместе с
     содержимым и гасят тень, когда доехали до края. */
  background-image:
    linear-gradient(to right, var(--surface), rgba(255, 255, 255, 0)),
    linear-gradient(to left, var(--surface), rgba(255, 255, 255, 0)),
    radial-gradient(farthest-side at 0 50%, rgba(15, 23, 32, .13), rgba(15, 23, 32, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(15, 23, 32, .13), rgba(15, 23, 32, 0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 26px 100%, 26px 100%, 13px 100%, 13px 100%;
  background-attachment: local, local, scroll, scroll;
}
table { border-collapse: collapse; width: 100%; font-size: 13.5px; }
th, td { padding: 9px var(--s3); text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line-soft); }
th:first-child, td:first-child, th.t, td.t { text-align: left; }
/* Клетка с текстом, а не с числом: отзыв или длинное название переносится
   по словам и держится в разумной ширине, а не растягивает таблицу. */
th.wrap, td.wrap { white-space: normal; min-width: 240px; max-width: 460px; }
td.wrap { line-height: 1.45; padding-top: 11px; padding-bottom: 11px; }
th.nowrap, td.nowrap { white-space: nowrap; }
.clamp { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
/* Шапка светлая: заливка во всю ширину спорила бы с цифрами внутри.
   Читается она регистром и весом, а держится линией снизу. */
thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--sunken); color: var(--ink-3);
  font-weight: 700; font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  border-bottom: 1px solid var(--line); white-space: normal;
}

/* Явный выбор сортировки над таблицей. Стрелки в заголовках работают, но
   их замечает не каждый. На листе объявлений сортировки нет вовсе: там ее
   сняли, см. sortable: false у обеих таблиц. */
.sortbar {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
  padding: var(--s2) var(--s3); border-bottom: 1px solid var(--line-soft);
  background: var(--sunken); font-size: 12.5px;
}
.sortbar__k { color: var(--ink-3); }
.sortbar__sel {
  width: auto; min-width: 150px; padding: 5px 10px; font-size: 12.5px;
  background: var(--surface); border-radius: var(--r-s);
}
.sortbar__dir {
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink-2); border-radius: var(--r-s); padding: 5px 12px;
}
.sortbar__dir:hover { border-color: var(--blue-line); color: var(--blue-deep); }
.sortbar__dir:disabled { opacity: .45; cursor: default; border-color: var(--line); }
.sortbar__dir:disabled:hover { border-color: var(--line); color: var(--ink-2); }
.sortbar__dir::before { content: '↓ '; }
.sortbar__dir[data-dir="up"]::before { content: '↑ '; }

/* Заголовок-кнопка: сортировка столбца. Кнопка наследует у ячейки все,
   кроме курсора, поэтому шапка выглядит как прежде, пока в нее не ткнули. */
th .th__b {
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; text-align: inherit;
}
th .th__b:hover { color: var(--blue-deep); }
th .th__b .ic { width: 12px; height: 12px; opacity: .35; }
th .th__b:hover .ic { opacity: .75; }
th.is-sorted .th__b { color: var(--blue-deep); }
th.is-sorted .th__b .ic { opacity: 1; }

tbody tr:hover td { background: var(--blue-soft); }
tbody tr:last-child td { border-bottom: 0; }
tr.total td { background: var(--sunken-2); font-weight: 800; color: var(--ink); }
tr.total:hover td { background: var(--sunken-2); }
.dim { color: var(--ink-2); }
td.fact { font-weight: 700; }
/* Проценты в таблицах - это доли и конверсии, а не рост. Зеленый в системе
   означает «выросло», поэтому здесь он вводил в заблуждение: доля 1,26 %
   светилась зеленым как достижение. Оставляем вес, цвет обычный. */
td.cv { color: var(--ink); font-weight: 700; }
td.zero { color: var(--ink-4); }
td a { color: var(--blue-deep); border-bottom: 1px solid var(--blue-line); text-decoration: none; }
td a:hover { border-bottom-color: var(--blue); text-decoration: none; }

.wide-first td:first-child, .wide-first th:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  max-width: 320px; overflow: hidden; text-overflow: ellipsis;
}
.wide-first thead th:first-child { background: var(--sunken); z-index: 3; }
.wide-first tbody tr:hover td:first-child { background: var(--blue-soft); }
.wide-first tr.total td:first-child { background: var(--sunken-2); }

/* Метки светофора в разборе. Своего вида у них не было вовсе: класс в
   разметке стоял, а правил под него не существовало, и метки выходили
   обычным серым текстом вперемешку. Вид тот же, что у меток статуса. */
.badge {
  display: inline-block; border-radius: 999px; padding: 2px 9px;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
  background: var(--sunken-2); color: var(--ink-2);
}
.badge + .badge { margin-left: 4px; }
.badge--bad { background: var(--alarm-soft); color: var(--alarm); }
.badge--off { background: var(--warn-soft); color: var(--warn); }
.badge--on { background: var(--green-soft); color: var(--green-ink); }

.tag--ok { background: var(--green-soft); color: var(--green-ink); }
.tag--off { background: var(--sunken-2); color: var(--ink-2); }
.tag--bad { background: var(--alarm-soft); color: var(--alarm); }
.plus { color: var(--green-ink); font-weight: 700; }
.minus { color: var(--alarm); font-weight: 700; }
.calcd { text-decoration: underline dotted var(--warn); text-underline-offset: 3px; cursor: help; }

/* ---------- показатели строкой, как в ведомости ---------- */

/* Показателей всегда четыре, поэтому сетка идет парами: при трех колонках
   четвертый оставался один в ряду и рядом зияла пустота. */
.ind { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--s8) var(--s12); }
@media (min-width: 760px) { .ind { grid-template-columns: 1fr 1fr; } }
.ind__head { display: flex; align-items: baseline; gap: var(--s2); }
.ind__k { font-size: 15px; font-weight: 700; }
.ind__fill { flex: 1; border-bottom: 1px dotted var(--line-strong); transform: translateY(-4px); min-width: 20px; }
.ind__v { font-size: 15px; font-weight: 800; white-space: nowrap; }
.bars { margin-top: var(--s3); display: grid; gap: 7px; }
.bar { display: grid; grid-template-columns: 150px minmax(50px, 1fr) auto; gap: var(--s3); align-items: center; }
.bar__k { font-size: 12.5px; color: var(--ink-2); line-height: 1.25; }
.bar__track { height: 6px; background: var(--sunken-2); border-radius: 999px; overflow: hidden; }
.bar__fill { height: 100%; background: var(--blue); border-radius: 999px; }
.bar__v { font-size: 12.5px; white-space: nowrap; }
.bonus { font-size: 12.5px; margin-top: var(--s2); }
.bonus b { color: var(--green-ink); font-weight: 700; }

/* воронка тремя колонками, как в кабинете Авито */
.fun { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--s6); align-items: start; }
.fun__t { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.fun__hint {
  width: 16px; height: 16px; border-radius: 50%; background: var(--sunken-2); color: var(--ink-3);
  font-size: 10px; display: inline-grid; place-items: center; cursor: help; font-weight: 800;
}
.fun__line { display: flex; align-items: baseline; gap: var(--s2); margin-top: 4px; flex-wrap: wrap; }
.fun__v { font-size: 28px; font-weight: 800; letter-spacing: -0.03em; }
.fun__d { font-size: 12.5px; color: var(--ink-2); margin-top: 4px; }
.delta { font-size: 12.5px; font-weight: 700; }
.delta--up { color: var(--green-ink); }
.delta--down { color: var(--alarm); }
/* Ступень воронки: доля просмотров, дошедших до заявки. Стоит своей строкой
   под числом, ширина по тексту. */
.conv {
  margin: 7px 0 0; display: inline-flex; align-items: center; gap: 5px;
  background: var(--brand-primary-soft); border: 1px solid var(--brand-primary-border);
  border-radius: 999px; padding: 3px 10px;
  font-size: 12.5px; font-weight: 700; color: var(--text-link); white-space: nowrap;
}

/* карточки показателей */
.kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: var(--s3); margin-bottom: var(--s4); }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  padding: var(--s3) var(--s4); box-shadow: var(--shadow-card);
}
.kpi__k { font-size: 12px; color: var(--ink-2); }
.kpi__k .ic { width: 14px; height: 14px; margin-right: 5px; vertical-align: -2px; }
.kpi__v { font-size: 25px; font-weight: 800; letter-spacing: -0.03em; margin-top: 3px; }
.kpi__n { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
/* Плитка, требующая внимания. Красим оранжевым, а не брендовым синим:
   синий в этой системе означает «обычное действие», а не тревогу, и
   залитая синим плитка спорила с кнопками. Текст на оранжевом темный:
   белый по #F97316 читается хуже. */
.kpi--green {
  background: var(--accent-orange-soft);
  border-color: var(--accent-orange-border);
  border-left: 3px solid var(--accent-orange);
  color: var(--ink);
}
.kpi--green .kpi__k { color: var(--accent-orange-dark); font-weight: 700; }
.kpi--green .kpi__n { color: var(--ink-2); }

/* ---------- шапка раздела кабинета ----------

   Разделы кабинета рисуют свою шапку сами: заголовок, кнопка выгрузки,
   переключатель вкладок и строка фильтров. Раньше этих правил не было
   вовсе, и вкладки выходили системными серыми кнопками браузера. */

.head {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-bottom: var(--s3);
}
.head h1 { font-size: 26px; letter-spacing: -0.03em; }

/* Выгрузка - действие второго ряда, поэтому уходит вправо и остается тихой */
.head > .pill { margin-left: auto; }

/* Переключатель вкладок: одна дорожка, выбранное поднято белым */
.tabs {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--sunken-2); border-radius: 12px;
  margin-bottom: var(--s4); max-width: 100%; overflow-x: auto;
}
.tabs button {
  font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink-2);
  background: none; border: 0; border-radius: 9px;
  padding: 7px 16px; cursor: pointer; white-space: nowrap;
  transition: background .13s ease, color .13s ease;
}
.tabs button:hover { color: var(--ink); }
.tabs button.is-on {
  background: var(--surface); color: var(--ink); font-weight: 700;
  box-shadow: 0 1px 3px rgba(10, 26, 43, 0.10);
}

.fbar { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; margin-bottom: var(--s4); }

/* Карточка с графиком: у нее свои поля, потому что подписи дней и месяцев
   рисуются внутри картинки и лишний воздух снизу выглядел бы провалом. */
.card--plot { padding: var(--s4); }

/* Заголовок блока на общей странице: слева имя, справа его настройки.
   Отбивает блоки друг от друга, раз вкладок между ними больше нет. */
.block__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
  margin: var(--s8) 0 var(--s3);
}
.block__head h2 { font-size: 19px; }

/* Разбивка расходов по услугам: точка цвета, название, отточие, сумма.
   Отточие ведет глаз от названия к сумме через пустое место строки. */
.legend__k { display: flex; align-items: center; gap: var(--s2); font-size: 14px; }
.legend__dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.legend__total { border-top: 1px solid var(--line); margin-top: var(--s2); padding-top: var(--s3); }
.legend__total .ind__k, .legend__total .ind__v { font-weight: 800; }

/* Секция раздела: та же карточка, что и .card, но заголовок внутри крупнее */
.block {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: var(--s4) var(--s6) var(--s6);
  margin-bottom: var(--s4); box-shadow: var(--shadow-card);
}
.block > h2 { font-size: 17px; margin-bottom: var(--s4); }

/* ---------- фильтры и всплывающие слои ---------- */

.filters { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.pill {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 7px 14px; cursor: pointer;
  transition: background .13s ease, border-color .13s ease, color .13s ease;
}
.pill:hover { border-color: var(--blue-line); color: var(--blue-deep); background: var(--blue-soft); }
.pill--on { background: var(--blue); border-color: var(--blue); color: #fff; }
.pill--on:hover { background: var(--blue-dark); border-color: var(--blue-dark); color: #fff; }
.pill--muted { color: var(--ink-3); cursor: default; }
.pill--muted:hover { background: var(--surface); border-color: var(--line); color: var(--ink-3); }

.fsel {
  position: relative; font: inherit; font-size: 14px; font-weight: 600; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-s);
  padding: 9px 14px; cursor: pointer; display: inline-flex; align-items: center; gap: var(--s2);
  transition: border-color .13s ease, background .13s ease;
}
.fsel:hover { border-color: var(--line-strong); }
.fsel--filled { color: var(--ink); }
.fsel--open { border-color: var(--blue); box-shadow: 0 0 0 3px var(--focus); }
.fsel__chev { width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg) translate(-2px, -2px); opacity: .5; }
.fsel--open .fsel__chev { transform: rotate(-135deg); }

.pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-l);
  box-shadow: var(--shadow-pop); padding: var(--s4); cursor: default;
}
/* Кнопки в правой части шапки: слой раскрывается влево, иначе календарь
   шириной в два месяца уезжал бы за край экрана. */
.top__tools .pop { left: auto; right: 0; }
.pop--menu { min-width: 250px; max-height: 330px; overflow: auto; padding: 6px; }
.pop__item { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 8px 10px; border-radius: 8px; cursor: pointer; font: inherit; font-size: 14px; color: var(--ink); }
.pop__item:hover { background: var(--sunken); }
.pop__item.is-on { font-weight: 700; background: var(--blue-soft); color: var(--blue-deep); }

.dp__pills { display: flex; gap: 6px; margin-bottom: var(--s3); }
.dp__months { display: flex; gap: var(--s6); }
.dp__m { width: 236px; }
.dp__cap { display: flex; align-items: center; justify-content: center; gap: var(--s2); font-weight: 700; margin-bottom: var(--s2); font-size: 14px; }
.dp__grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.dp__dow { font-size: 11px; color: var(--ink-4); text-align: center; padding-bottom: 5px; }
.dp__d { height: 32px; border: 0; background: none; cursor: pointer; font: inherit; font-size: 13px; border-radius: 8px; color: var(--ink); }
.dp__d:hover { background: var(--sunken-2); }
.dp__d[disabled] { color: var(--ink-4); cursor: default; }
.dp__d[disabled]:hover { background: none; }
/* Отрезок закрашивается сплошь: с просветами между клетками он читался
   бы как набор отдельных дней, а не как выбранный промежуток. */
.dp__d.in { background: var(--blue-soft); border-radius: 0; }
.dp__d.edge { background: var(--blue); color: #fff; border-radius: 8px; }
.dp__nav {
  border: 0; background: none; cursor: pointer; color: var(--ink-3);
  width: 28px; height: 28px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
}
.dp__nav:hover { background: var(--sunken-2); color: var(--ink); }
.dp__nav svg { display: block; }

/* ---------- листы аналитики ---------- */

.sheet__head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s4); }
.sheet__head h2 { font-size: 22px; }
.sheet__head p { margin: 4px 0 0; color: var(--ink-2); font-size: 13px; max-width: 74ch; }
.sheet__tools { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; justify-content: flex-end; }

.funnel { display: grid; gap: 6px; }
.step { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--s3); }
/* Дорожка светло-серая, залитая часть синяя: на светло-синей дорожке
   заливка терялась и ступени воронки читались одинаковыми. */
.step__bar { height: 42px; background: var(--sunken-2); border-radius: var(--r-s); display: flex; align-items: center; padding: 0 var(--s3); font-weight: 700; position: relative; overflow: hidden; }
.step__fill { position: absolute; inset: 0 auto 0 0; background: var(--blue); opacity: .38; }
.step__t { position: relative; }
.step__v { font-size: 18px; font-weight: 800; min-width: 100px; text-align: right; }
.step__cv { color: var(--green-ink); font-size: 12.5px; font-weight: 700; padding-left: var(--s3); }

.heat th, .heat td { padding: 5px 6px; font-size: 12.5px; text-align: center; }
.heat td:first-child, .heat th:first-child { text-align: left; padding-left: var(--s3); }

.bar-progress { height: 6px; background: var(--sunken-2); border-radius: 999px; overflow: hidden; margin-top: var(--s2); }
.bar-progress__in { height: 100%; width: 100%; background: var(--blue); transform: scaleX(0); transform-origin: left; transition: transform .3s; }

/* ---------- полоса ожидания лимита ----------

   Полоса заполняется ровно столько, сколько осталось ждать: доля
   закрашенного равна доле прожитого. Плавность короткая, иначе заливка
   отстает от подписи в процентах и они спорят друг с другом. */

.wait { display: flex; align-items: center; gap: var(--s3); max-width: 340px; margin: var(--s4) auto 0; }
.wait .bar-progress { flex: 1; height: 8px; margin-top: 0; }
.wait__pct { font-size: 12.5px; font-weight: 700; color: var(--ink-2); min-width: 40px; text-align: right; }
.bar-progress--wait .bar-progress__in { transition: transform .14s linear; }

/* Дошли до конца: запрос ушел, время ответа неизвестно. Замершая на сотне
   полоса врала бы, что вот-вот, поэтому дальше идет бегущая заливка. */
.bar-progress--run .bar-progress__in {
  width: 38%; transform: none; transition: none;
  animation: barrun 1.05s ease-in-out infinite alternate;
}
@keyframes barrun { from { margin-left: 0; } to { margin-left: 62%; } }
/* Кому движение мешает, тому вместо бега просто приглушенная полоса:
   застывшая на месте бегущая заливка читалась бы как зависание. */
@media (prefers-reduced-motion: reduce) {
  .bar-progress--run .bar-progress__in { width: 100%; opacity: .35; }
}
.load { display: grid; place-items: center; min-height: 46vh; text-align: center; }
.load .card { max-width: 440px; }

/* ---------- графики ---------- */

.charts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap: var(--s3); margin-bottom: var(--s4); }
.chart {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: var(--s3) var(--s4); box-shadow: var(--shadow-card);
}
.chart__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2); margin-bottom: var(--s2); }
.chart__t { font-size: 13.5px; font-weight: 700; }
.chart__n { font-size: 11.5px; color: var(--ink-3); text-align: right; }
.chart__plot { position: relative; }
.chart__svg { display: block; width: 100%; height: 168px; overflow: visible; }
.chart__scale { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--ink-3); margin-top: 4px; }
.chart__cap { position: absolute; top: 0; left: 0; font-size: 11px; color: var(--ink-4); pointer-events: none; }
.chart__tip {
  position: absolute; top: -4px; z-index: 5; pointer-events: none;
  background: var(--ink); color: #fff; border-radius: 8px; padding: 5px 9px;
  font-size: 12px; line-height: 1.3; white-space: nowrap;
  display: flex; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow-card);
}
.chart__tip span { opacity: .7; font-size: 11px; }

/* ---------- обозреватель методов ---------- */

.explorer { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: var(--s4); align-items: start; }
.explorer__list { border: 1px solid var(--line); border-radius: var(--r-m); max-height: 70vh; overflow: auto; background: var(--surface); box-shadow: var(--shadow-card); }
.explorer__list button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 8px 12px; cursor: pointer; font: inherit; font-size: 12.5px; color: var(--ink); border-bottom: 1px solid var(--line-soft); }
.explorer__list button:hover { background: var(--sunken); }
.explorer__list button.is-on { background: var(--blue-soft); color: var(--blue-deep); font-weight: 700; }
.explorer__sec { padding: 8px 12px; font-weight: 800; background: var(--sunken-2); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); position: sticky; top: 0; z-index: 1; }
.verb { font-weight: 800; margin-right: 5px; font-size: 10.5px; }
.verb--GET { color: var(--green-ink); }
.verb--POST { color: var(--blue-deep); }
.verb--PUT { color: var(--warn); }
.verb--DELETE { color: var(--alarm); }
pre.out { margin: 0; padding: var(--s4); background: #172033; color: #CBD5E1; border-radius: var(--r-m); font-family: Consolas, monospace; font-size: 12px; line-height: 1.5; max-height: 58vh; overflow: auto; white-space: pre-wrap; word-break: break-word; }
textarea.body { min-height: 120px; font-family: Consolas, monospace; font-size: 12.5px; }

/* ---------- биддер ---------- */

/* Состояния правила помечаются словом, а не цветной точкой: «цель
   недостижима» и «бюджет исчерпан» надо читать, а не расшифровывать. */
.tag {
  display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; padding: 3px 10px;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
/* Значок внутри метки берет ее цвет: у метки он уже осмысленный */
.tag .ic { width: 13px; height: 13px; vertical-align: 0; color: inherit; }
td .ic { vertical-align: -2px; }
a .ic { margin-left: 4px; }
/* ---------- список правил карточками ----------

   Таблица здесь не годилась: у каждого объявления своя жизнь - позиция,
   коридор ставки, бюджет, расписание, - и строка таблицы заставляла бы
   бегать глазами по двенадцати колонкам. Карточка показывает то же самое
   четырьмя блоками, которые читаются с одного взгляда. */

.bid__search {
  width: 100%; margin-bottom: var(--s4);
}
.bid__list { display: grid; gap: var(--s4); }

.bid__group {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  box-shadow: var(--shadow-card); overflow: hidden;
}
.bid__ghead {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding: var(--s3) var(--s4); background: var(--sunken); border-bottom: 1px solid var(--line);
}
.bid__ghead.is-off { opacity: .6; }
.bid__ghead--loose { background: var(--surface); }
.bid__gname { font-family: var(--display); font-weight: 700; font-size: 16px; }
.bid__gfacts { display: flex; align-items: center; gap: var(--s4); font-size: 12.5px; color: var(--ink-2); margin-left: var(--s3); flex-wrap: wrap; }
.bid__gtools { display: flex; gap: var(--s2); margin-left: auto; }
.bid__empty { padding: var(--s6) var(--s4); color: var(--ink-3); font-size: 13.5px; text-align: center; }

/* Тумблер. Своя разметка вместо галочки: включение правила стоит денег,
   и оно должно выглядеть как рубильник, а не как отметка в списке. */
.bid__switch {
  width: 38px; height: 22px; flex: none; border-radius: 999px; cursor: pointer;
  background: var(--line-strong); border: 0; padding: 0; position: relative;
  transition: background .14s ease;
}
.bid__switch::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; transition: transform .14s ease;
}
.bid__switch.is-on { background: var(--green); }
.bid__switch.is-on::after { transform: translateX(16px); }
.bid__switch:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.bid__bar { display: block; width: 90px; height: 5px; border-radius: 999px; background: var(--sunken-2); overflow: hidden; margin-top: 4px; }
.bid__bar-in { display: block; height: 100%; background: var(--blue); border-radius: 999px; }
.bid__bar-in.is-full { background: var(--alarm); }
.bid__budget { display: inline-flex; flex-direction: column; }

.bid__card { padding: var(--s4); border-bottom: 1px solid var(--line-soft); }
.bid__card:last-child { border-bottom: 0; }
.bid__card.is-off { background: var(--sunken); }
.bid__card.is-off .bid__title { color: var(--ink-2); }

.bid__top { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.bid__pick { width: 16px; height: 16px; accent-color: var(--blue); flex: none; }
.bid__who { min-width: 0; }
.bid__title { font-weight: 700; font-size: 15px; color: var(--ink); border: 0; }
.bid__title:hover { color: var(--blue-deep); text-decoration: none; }
.bid__sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.bid__sub a { border: 0; }
.bid__fill { flex: 1; }
.bid__tools { display: flex; gap: var(--s2); }

.bid__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: var(--s3) var(--s4); margin-top: var(--s3);
}
.bid__cell { min-width: 0; }
.bid__k { font-size: 11.5px; color: var(--ink-3); }
.bid__v { font-size: 19px; font-weight: 800; letter-spacing: -.02em; margin-top: 2px; }
.bid__note { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }

/* Позиция - главное число карточки, поэтому она пилюлей и цветом:
   зеленая внутри цели, оранжевая мимо, серая когда объявления нет. */
.bid__pos {
  display: inline-block; margin-top: 2px; padding: 2px 12px; border-radius: 999px;
  font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums;
  background: var(--warn-soft); color: var(--warn);
}
.bid__pos.is-ok { background: var(--green-soft); color: var(--green-ink); }
.bid__pos.is-lost { background: var(--sunken-2); color: var(--ink-3); font-size: 14px; padding: 5px 12px; }

/* Полоса позиций: зона цели и точка, где мы сейчас */
.bid__range { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s3); }
.bid__edge { font-size: 11px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.bid__track { position: relative; flex: 1; height: 8px; border-radius: 999px; background: var(--sunken-2); }
.bid__zone { position: absolute; top: 0; height: 100%; border-radius: 999px; background: var(--green-soft); border: 1px solid var(--green); }
.bid__dot {
  position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%;
  background: var(--warn); border: 2px solid var(--surface); transform: translate(-50%, -50%);
}
.bid__dot.is-ok { background: var(--green-ink); }

.bid__last { margin-top: var(--s3); font-size: 12.5px; color: var(--ink-2); }
.bid__foot { display: flex; gap: var(--s2); margin-top: var(--s3); flex-wrap: wrap; }

/* Полоса массовой правки: появляется, только когда что-то отмечено */
.bid__bulk {
  position: sticky; bottom: var(--s4); z-index: 5;
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-top: var(--s4); padding: var(--s3) var(--s4);
  background: var(--ink); color: #fff; border-radius: var(--r-m); box-shadow: var(--shadow-pop);
}
.bid__bulk .pill { background: transparent; border-color: rgba(255, 255, 255, .35); color: #fff; }
.bid__bulk .pill:hover { background: rgba(255, 255, 255, .12); color: #fff; border-color: rgba(255, 255, 255, .5); }
.bid__bulkrow { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: var(--s3); align-items: center; margin-bottom: var(--s3); }
.bid__bulklabel { display: flex; align-items: center; gap: var(--s2); font-size: 13.5px; cursor: pointer; }
.bid__bulklabel input { width: 16px; height: 16px; accent-color: var(--blue); }
.bid__bulkfield { transition: opacity .14s ease; }
.bid__two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); }

/* Расписание */
.bid__sched { margin-top: var(--s6); border-top: 1px solid var(--line-soft); padding-top: var(--s4); }
.bid__sched h3 { font-size: 15px; margin-bottom: var(--s3); }
.bid__days { display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s3); }
.bid__day {
  min-width: 46px; padding: 7px 10px; border-radius: var(--r-s); cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .04em;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink-3);
}
.bid__day.is-on { background: var(--blue-soft); border-color: var(--blue-line); color: var(--blue-deep); }
.bid__windows { display: grid; gap: var(--s2); margin-bottom: var(--s3); }
.bid__window { display: flex; align-items: center; gap: var(--s2); }
.bid__window input { width: 120px; }
.bid__wk { font-size: 12.5px; color: var(--ink-2); }

/* ---------- окно поверх экрана ---------- */

.bmodal {
  position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(10, 26, 43, .45); padding: var(--s4);
}
.bmodal__win {
  width: 100%; max-width: 620px; max-height: 88vh; display: flex; flex-direction: column;
  background: var(--surface); border-radius: var(--r-l); box-shadow: var(--shadow-pop); overflow: hidden;
}
.bmodal__head {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4); border-bottom: 1px solid var(--line);
}
.bmodal__head h3 { font-size: 18px; }
.bmodal__x {
  margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--ink-3);
  padding: 4px; border-radius: 8px; display: grid; place-items: center;
}
.bmodal__x:hover { background: var(--sunken-2); color: var(--ink); }
.bmodal__body { padding: var(--s4); overflow-y: auto; }
.bmodal__foot {
  display: flex; justify-content: flex-end; gap: var(--s2);
  padding: var(--s3) var(--s4); border-top: 1px solid var(--line); background: var(--sunken);
}

.bid__form { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: var(--s6); align-items: start; }
.bid__form h3 { font-size: 15px; margin-bottom: var(--s3); }
.bid__flags { display: grid; gap: var(--s2); margin-top: var(--s4); }
.bid__check { display: flex; align-items: center; gap: var(--s2); font-size: 13.5px; cursor: pointer; }
.bid__check input { width: 16px; height: 16px; accent-color: var(--blue); }
.bid__row-tools { display: flex; gap: var(--s2); justify-content: flex-end; position: relative; }
.bid__chart { width: 100%; height: auto; display: block; }

/* ============================================================
   Значки и картинки состояний
   ============================================================

   Значок это квадрат, закрашенный currentColor, а картинка задает ему
   форму маской. Отсюда главное свойство: один файл годится и серому
   пункту меню, и зеленой строке роста, потому что цвет берется с места,
   куда значок поставлен. Тегом img так не выйдет: картинку не покрасить.

   Размер по умолчанию 18: на нем толщина линии значка совпадает с весом
   текста рядом. Крупнее ставим только там, где значок несет смысл сам,
   а не подпирает слово. */

.ic {
  display: inline-block; width: 18px; height: 18px; flex: none;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  vertical-align: -3px;
}
.ic--sm { width: 15px; height: 15px; }
.ic--lg { width: 22px; height: 22px; }
.ic--xl { width: 26px; height: 26px; }
.ic--dim { opacity: .5; }

/* Состояние красится смыслом, а не местом: зеленое это хорошо,
   красное это потеря, серое это «неизвестно». */
.ic--ok { color: var(--green-ink); }
.ic--bad { color: var(--alarm); }
.ic--warn { color: var(--warn); }
.ic--unknown, .ic--paused, .ic--offline { color: var(--ink-3); }
.ic--limit, .ic--syncing { color: var(--blue-deep); }
.ic--noaccess { color: var(--ink-2); }

.btn .ic { width: 15px; height: 15px; vertical-align: -2px; }
.pill .ic, .fsel .ic, .hub__x .ic, .hub__open .ic { width: 14px; height: 14px; vertical-align: -2px; }
.fsel .ic { margin-right: 5px; color: var(--ink-3); }

/* значок у показателя воронки и у строки ведомости */
.fun__t .ic, .ind__k .ic { color: var(--ink-3); margin-right: 5px; }
.legend__k .ic { width: 17px; height: 17px; }
.hub__k .ic { width: 12px; height: 12px; margin-right: 4px; opacity: .7; vertical-align: -1px; }

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

   Раньше на месте отсутствующих данных стояла одна серая надпись, и это
   читалось как поломка. Теперь картинка, строка о том, что случилось, и
   пояснение, почему так, - человек понимает, ждать ему или чинить. */

.art { padding: var(--s6) var(--s4); text-align: center; }
/* Меряем картинку высотой, а не шириной: рисунки разной формы, и по ширине
   вертикальный сейф выходил бы вдвое крупнее лежачего календаря. */
.art__img { height: 132px; width: auto; max-width: 90%; display: block; margin: 0 auto var(--s3); }
.art__t { font-size: 15px; font-weight: 700; }
.art__s {
  font-size: 13px; color: var(--ink-2); line-height: 1.5;
  margin: 5px auto 0; max-width: 440px;
}
.art .btn, .art .pill { margin-top: var(--s4); }
.art--sm { padding: var(--s6) var(--s4); }
.art--sm .art__img { height: 96px; }

/* Картинка при отказе Авито стоит слева от объяснения: отказ читают, а не
   разглядывают, поэтому текст остается главным. */
.msg--art { display: flex; align-items: center; gap: var(--s4); }
.msg--art .art__img { height: 68px; width: auto; margin: 0; flex: none; }
.msg--art > div { min-width: 0; }

/* ---------- советы по времени ----------

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

.advice { display: grid; gap: var(--s3); margin-top: var(--s3); }
.advice__row { display: flex; gap: var(--s3); align-items: flex-start; }
.advice__ic {
  width: 34px; height: 34px; flex: none; border-radius: 10px;
  display: grid; place-items: center; font-size: 17px;
  background: var(--blue-soft);
}
.advice__t { font-weight: 700; font-size: 14px; }
.advice__s { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin-top: 2px; }
.sheet__sub { font-size: 17px; margin: var(--s6) 0 var(--s2); }

/* ---------- узкие экраны ---------- */

@media (max-width: 1000px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  .brandbar { padding-left: var(--s4); padding-right: var(--s4); }
  /* Разделов два десятка: во всю высоту они съели бы весь первый экран,
     поэтому на узком меню - своя полоса прокрутки. */
  .side {
    grid-column: 1; grid-row: 2;
    position: static; height: auto; max-height: 38vh; overflow-y: auto;
    border-right: 0; border-bottom: 1px solid var(--line);
    padding: var(--s2) var(--s3);
  }
  .work { grid-column: 1; grid-row: 3; }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .nav__group { width: 100%; padding-top: var(--s2); }
  .nav button { width: auto; }
  .nav button.is-on::before { display: none; }
  .main { padding: var(--s4); }
  .explorer { grid-template-columns: minmax(0, 1fr); }
  .dp__months { flex-direction: column; }
}

@media (max-width: 620px) {
  .art__img { height: 108px; }
  .msg--art { display: block; }
  .msg--art .art__img { margin: 0 0 var(--s2); }
  .brandbar__name { max-width: 130px; }
  .top__in { padding: var(--s2) var(--s4); }
  .hub { padding: var(--s6) var(--s4); }
  .hub__grid { grid-template-columns: minmax(0, 1fr); }
  .card { padding: var(--s4); }
  .gate__card { padding: var(--s6); }
}

/* ============================================================
   Автозагрузка

   Слева список объявлений, справа выбранное целиком, поле за полем. Так
   задумано: таблица в сотню колонок влезает только в электронную книгу, а
   работать с ней глазами невозможно - в готовых решениях это самое больное
   место. Здесь виден один объект целиком, а общее для всех ставится кнопкой
   «Поставить всем».
   ============================================================ */

.feed__bar {
  display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-bottom: var(--s4);
}
.feed__cat {
  flex: 1 1 320px; min-width: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-m);
  padding: 10px 14px; font-size: 13.5px; color: var(--ink-2);
}
.feed__cat b { color: var(--ink); font-weight: 700; }
.feed__cat .ic { width: 15px; height: 15px; vertical-align: -3px; margin-right: 8px; color: var(--ink-3); }

.feed__acts { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s3); }
.feed__state { font-size: 12px; color: var(--ink-3); margin-left: auto; }

.feed__split {
  display: grid; grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
  gap: var(--s4); align-items: start;
}
.feed__list {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 74vh; overflow-y: auto; padding-right: 4px;
}
.feed__row {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-s);
  padding: 10px 12px; font: inherit; color: var(--ink);
}
.feed__row:hover { border-color: var(--line-strong); }
.feed__row.is-on { border-color: var(--blue); background: var(--bg-selected); }
.feed__row.is-off { opacity: .5; }
.feed__rowtop { display: block; font-size: 13.5px; line-height: 1.35; }
.feed__rowsub { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 3px; }

.feed__form {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: var(--s6);
}
.feed__formtop {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; margin-bottom: var(--s4);
}
.feed__formtop h2 { font-size: 18px; min-width: 0; }
.feed__gr { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); margin-bottom: var(--s3); }
.feed__field { margin-bottom: var(--s4); }
.feed__req { color: var(--alarm); font-weight: 600; }
.feed__tag {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 10.5px; color: var(--ink-4); background: var(--sunken-2);
  border-radius: 4px; padding: 1px 5px; font-weight: 400;
}
.feed__under { display: flex; align-items: baseline; gap: var(--s3); margin-top: 5px; }
.feed__under .hint { flex: 1; min-width: 0; margin: 0; }
.feed__all {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--blue-deep); white-space: nowrap;
}
.feed__all:hover { text-decoration: underline; }
.feed__more {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  font-weight: 600; color: var(--ink-2); margin-bottom: var(--s3);
}
.feed__more .ic { width: 14px; height: 14px; vertical-align: -3px; margin-right: 6px; transition: transform .15s; }
.feed__more.is-on .ic { transform: rotate(180deg); }

.feed__checks { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.feed__check { display: flex; align-items: center; gap: 6px; font-size: 13.5px; cursor: pointer; }
.feed__check input { width: 15px; height: 15px; accent-color: var(--blue); }

.feed__photos { display: flex; flex-direction: column; gap: var(--s2); }
.feed__thumbs { display: flex; flex-wrap: wrap; gap: 8px; }
.feed__thumb { position: relative; width: 82px; height: 62px; }
.feed__thumb img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: var(--r-s); border: 1px solid var(--line);
}
.feed__thumbx {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px;
  border-radius: 50%; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink-2); cursor: pointer; line-height: 1; font-size: 14px;
}
.feed__thumbx:hover { color: var(--alarm); border-color: var(--alarm); }
.feed__gal { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; }
.feed__galitem { padding: 0; border: 2px solid transparent; border-radius: var(--r-s); cursor: pointer; background: none; }
.feed__galitem img { width: 100%; height: 88px; object-fit: cover; border-radius: var(--r-s); display: block; }
.feed__galitem.is-on { border-color: var(--blue); }

.feed__bads { margin: var(--s2) 0 0; padding-left: 18px; }
.feed__bads li { cursor: pointer; padding: 2px 0; }
.feed__bads li:hover { text-decoration: underline; }

.feed__link { display: flex; gap: var(--s2); align-items: center; margin-bottom: var(--s3); }
.feed__link input { flex: 1; min-width: 0; }
.feed__url { font-size: 11.5px; word-break: break-all; text-align: right; font-weight: 400; }

.feed__hours { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 6px; margin-bottom: var(--s3); }
.feed__days { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--s4); }
.feed__hour {
  padding: 7px 4px; text-align: center; cursor: pointer; font: inherit; font-size: 12.5px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-s); color: var(--ink-2);
}
.feed__hour:hover { border-color: var(--blue-line); }
.feed__hour.is-on { background: var(--blue); border-color: var(--blue); color: #fff; }
.feed__days .feed__hour { min-width: 52px; }

.feed__item { border-bottom: 1px solid var(--line-soft); padding: var(--s3) 0; }
.feed__item:last-child { border-bottom: 0; }
.feed__itemtop { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.feed__itemsub { font-size: 12px; color: var(--ink-3); margin-top: 3px; }
.feed__item .msg { margin-top: 6px; }

.feed__mask {
  position: fixed; inset: 0; z-index: 60; background: rgba(15, 23, 42, .45);
  display: flex; align-items: flex-start; justify-content: center; padding: 6vh var(--s4);
}
.feed__win {
  background: var(--surface); border-radius: var(--r-m); width: min(720px, 100%);
  max-height: 80vh; display: flex; flex-direction: column; box-shadow: var(--shadow-lift);
}
.feed__winhead {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s4) var(--s6); border-bottom: 1px solid var(--line);
}
.feed__winhead h2 { font-size: 17px; }
.feed__winx { background: none; border: 0; font-size: 24px; line-height: 1; cursor: pointer; color: var(--ink-3); }
.feed__winx:hover { color: var(--ink); }
.feed__winbody { padding: var(--s4) var(--s6) var(--s6); overflow-y: auto; }
.feed__cats { display: flex; flex-direction: column; gap: 2px; margin-top: var(--s3); }
.feed__cat1 {
  text-align: left; background: none; border: 0; border-radius: var(--r-s);
  padding: 8px 10px; cursor: pointer; font: inherit; font-size: 13px; color: var(--ink-2);
}
.feed__cat1:hover { background: var(--blue-soft); color: var(--blue-deep); }

@media (max-width: 900px) {
  .feed__split { grid-template-columns: minmax(0, 1fr); }
  .feed__list { max-height: 260px; }
}

.feed__nopic {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border: 1px dashed var(--line-strong);
  border-radius: var(--r-s); font-size: 11px; color: var(--ink-4);
}
