/* Панель Lunessa SMM — рабочая консоль, открывается каждый день.

   Направление: инструмент, а не витрина. Плоские поверхности, один акцент,
   семантический цвет только там, где он означает состояние. Плотность как
   в консолях управления: сводка сверху, детали ниже, числа моноширинные и
   выровнены по колонке (решение Артура 2026-08-29 — «уровня гугл»).

   До этого панель была астрономическим альманахом: зерно бумаги, антиква
   и латунь. Красиво на обложке, но на 13-15 px цифрах давало низкий
   контраст, а «патина и киноварь вместо светофора» не позволяли отличить
   тревогу от нормы с одного взгляда.

   Ночь — рабочая тема по умолчанию, день — та же сетка при свете.
   Имена переменных прежние: страницы, ещё не переведённые на новый
   каркас, продолжают работать без правок. */

:root {
  /* Ночь: холодный графит с синевой */
  --night:    #0E1015;
  --surface:  #161A21;
  --raised:   #1C2029;
  --line:     #292E3A;
  --ink:      #E8EBF2;
  --dim:      #A1A8B7;
  --faint:    #79808F;

  /* Единственный акцент — индиго. Надпись на заливке берёт --on-accent:
     на светлом индиго тёмная, на тёмном белая. */
  --accent:     #91A0FF;
  --accent-dim: #313C69;
  --accent-bg:  #1C2340;
  --on-accent:  #12162B;

  /* Состояния: зелёный, жёлтый, красный. Никакой стилизации — цвет здесь
     значит «хорошо / внимание / плохо» и должен читаться мгновенно. */
  --live:     #55C68D;
  --live-bg:  #13281E;
  --wait:     #A1A8B7;
  --wait-bg:  #21262F;
  --alert:    #F08A7E;
  --alert-bg: #2E1917;
  --alert-ink: #F08A7E;
  --wait-ink:  #A1A8B7;

  --r:        12px;
  --r-sm:     8px;
  --r-lg:     16px;
  --shadow:   0 1px 2px rgba(0,0,0,.5), 0 6px 16px rgba(0,0,0,.35);

  /* Зерно бумаги выведено: на данных оно работало против чтения. Тайл
     оставлен пустым, чтобы старые правила с var(--grain) не ломались. */
  --grain: none;
  --grain-a: 0;

  /* Cormorant убран: серифная антиква в консоли — декор, который замедляет
     чтение. Заголовки и данные теперь одной семьёй, различаются весом. */
  --font-display: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --font-text: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;

  color-scheme: dark light;
}

@media (prefers-color-scheme: light) {
  :root:not([data-panel-theme="dark"]) {
    --night:    #F3F5F8;
    --surface:  #FFFFFF;
    --raised:   #F8F9FC;
    --line:     #E1E5EC;
    --ink:      #161922;
    --dim:      #555C6C;
    --faint:    #838B9B;
    --accent:     #3D4FC4;
    --accent-dim: #C3CBF0;
    --accent-bg:  #E9ECFA;
    --on-accent:  #FFFFFF;
    --live:     #16764A;
    --live-bg:  #E1F1E8;
    --wait:     #555C6C;
    --wait-bg:  #EDF0F5;
    --alert:    #B03227;
    --alert-bg: #FAE5E2;
    --alert-ink: #B03227;
    --wait-ink:  #555C6C;
    --shadow:   0 1px 2px rgba(16,20,32,.06), 0 6px 16px rgba(16,20,32,.08);
  }
}

/* Иконки: контур в маске — цвет берётся от текста пункта. */
:root {
  --ic-instagram: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Crect%20x%3D%223.2%22%20y%3D%223.2%22%20width%3D%2217.6%22%20height%3D%2217.6%22%20rx%3D%225%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%224%22%2F%3E%3Ccircle%20cx%3D%2217.2%22%20cy%3D%226.8%22%20r%3D%22.9%22%20fill%3D%22currentColor%22%20stroke%3D%22none%22%2F%3E%3C%2Fsvg%3E");
  --ic-threads: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%223.6%22%2F%3E%3Cpath%20d%3D%22M15.6%208.4v5.2a2.8%202.8%200%200%200%205.6%200v-1.2a9.2%209.2%200%201%200-3.6%207.3%22%2F%3E%3C%2Fsvg%3E");
  --ic-bots: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Crect%20x%3D%223.8%22%20y%3D%227.4%22%20width%3D%2216.4%22%20height%3D%2212.4%22%20rx%3D%223.4%22%2F%3E%3Cpath%20d%3D%22M12%207.4V4.2%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%223.4%22%20r%3D%221.1%22%2F%3E%3Cpath%20d%3D%22M9%2013v1.6M15%2013v1.6%22%2F%3E%3C%2Fsvg%3E");
  --ic-dialogs: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M20.8%2011.6a8.2%208.2%200%200%201-11.9%207.3L3.6%2020.4l1.6-5.1A8.2%208.2%200%201%201%2020.8%2011.6z%22%2F%3E%3C%2Fsvg%3E");
  --ic-audit: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2210.8%22%20cy%3D%2210.8%22%20r%3D%226.8%22%2F%3E%3Cpath%20d%3D%22M15.8%2015.8L20.4%2020.4%22%2F%3E%3C%2Fsvg%3E");
  --ic-leads: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M3.4%204.6h17.2l-6.6%207.9v6.3l-4%202.2v-8.5z%22%2F%3E%3C%2Fsvg%3E");
  --ic-people: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%229.4%22%20cy%3D%228.2%22%20r%3D%223.4%22%2F%3E%3Cpath%20d%3D%22M3.4%2019.8a6%206%200%200%201%2012%200%22%2F%3E%3Cpath%20d%3D%22M16.4%205.4a3.2%203.2%200%200%201%200%206.2%22%2F%3E%3Cpath%20d%3D%22M17.6%2019.8a5.6%205.6%200%200%200-1.7-4%22%2F%3E%3C%2Fsvg%3E");
  --ic-data: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M4.6%2020.2V11M12%2020.2V3.8M19.4%2020.2v-6.6%22%2F%3E%3C%2Fsvg%3E");
  --ic-book: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M20.4%2014.2A8.4%208.4%200%201%201%209.8%203.6a6.9%206.9%200%200%200%2010.6%2010.6z%22%2F%3E%3Cpath%20d%3D%22M17.6%204.2l.6%201.7%201.7.6-1.7.6-.6%201.7-.6-1.7-1.7-.6%201.7-.6z%22%2F%3E%3C%2Fsvg%3E");
  --ic-spend: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Crect%20x%3D%223.4%22%20y%3D%226.2%22%20width%3D%2217.2%22%20height%3D%2213.4%22%20rx%3D%223.2%22%2F%3E%3Cpath%20d%3D%22M3.4%2010.4h17.2%22%2F%3E%3Ccircle%20cx%3D%2216.6%22%20cy%3D%2214.8%22%20r%3D%221.3%22%20fill%3D%22currentColor%22%20stroke%3D%22none%22%2F%3E%3C%2Fsvg%3E");
  --ic-publisher: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M20.8%203.6L3.8%2010.4l6.7%202.8%202.8%206.7z%22%2F%3E%3Cpath%20d%3D%22M20.8%203.6l-10.3%209.6%22%2F%3E%3C%2Fsvg%3E");
  --ic-today: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%224%22%2F%3E%3Cpath%20d%3D%22M12%203v2M12%2019v2M3%2012h2M19%2012h2M5.6%205.6l1.4%201.4M17%2017l1.4%201.4M18.4%205.6L17%207M7%2017l-1.4%201.4%22%2F%3E%3C%2Fsvg%3E");
  --ic-pen: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M15.5%204.5l4%204-11%2011h-4v-4z%22%2F%3E%3C%2Fsvg%3E");
  --ic-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Crect%20x%3D%224%22%20y%3D%225.5%22%20width%3D%2216%22%20height%3D%2213%22%20rx%3D%222.5%22%2F%3E%3Cpath%20d%3D%22M4%2015l4.5-4%204%203.5%203-2.5L20%2016%22%2F%3E%3C%2Fsvg%3E");
  --ic-star: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M12%203.4l2.6%205.5%206%20.9-4.3%204.1%201%206-5.3-2.8-5.3%202.8%201-6-4.3-4.1%206-.9z%22%2F%3E%3C%2Fsvg%3E");
  --ic-moon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M20.4%2014.2A8.4%208.4%200%201%201%209.8%203.6a6.9%206.9%200%200%200%2010.6%2010.6z%22%2F%3E%3C%2Fsvg%3E");
  --ic-shield: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M12%203.2l7.4%203v5.9c0%204.6-3.1%207.8-7.4%209.3-4.3-1.5-7.4-4.7-7.4-9.3V6.2z%22%2F%3E%3C%2Fsvg%3E");
  --ic-spark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M12%203.2l1.9%206.4%206.4%201.9-6.4%201.9-1.9%206.4-1.9-6.4L3.7%2011.5l6.4-1.9z%22%2F%3E%3C%2Fsvg%3E");
}

* { box-sizing: border-box; }

/* Панель открывают и с телефона: убираем задержку 300 мс на тапе и серую
   вспышку подсветки — вместо неё работают наши :hover и :focus-visible. */
a, button, .btn, input, .nav a {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  background-color: var(--night);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 14.5px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Липкая шапка раздела не должна накрывать то, на что перешли табом. */
:where(a, button, input, select, textarea, [tabindex]) { scroll-margin-top: 5rem; }
.shell { position: relative; z-index: 1; }

/* ── каркас: навигация слева, работа справа ─────────────────────────── */

.shell { display: grid; grid-template-columns: 16.5rem 1fr; min-height: 100vh; }

/* Грид-колонка по умолчанию не уже своего содержимого: без этого широкая
   таблица или полоса столбиков растягивает всю страницу, и вместо
   внутренней прокрутки уезжает вбок весь макет. */
.shell > * { min-width: 0; }

.side {
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}

/* Знак — кнопка обновления. Выглядит как заголовок, но нажимается: панель
   держат открытой часами, и перезагрузить её должно быть проще, чем искать
   кнопку браузера. Поэтому сбрасываем всё, что кнопка приносит с собой. */
.brand {
  padding: .95rem 1rem;
  display: flex; align-items: center; gap: .6rem;
  border-bottom: 1px solid var(--line);
  width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border-width: 0 0 1px 0; cursor: pointer;
}
.brand:hover .mark { transform: rotate(90deg); }
.brand .mark { transition: transform .35s ease; }
@media (prefers-reduced-motion: reduce) {
  .brand .mark { transition: none; }
}
.brand b {
  font-family: var(--font-display);
  font-weight: 600; font-size: 1.05rem; letter-spacing: -.01em;
}
/* Знак живёт в плитке — как на всех значках разделов ниже: сайдбар
   читается одной колонкой иконок, а не текстом вразнобой. */
.brand .mark {
  display: grid; place-items: center; flex: none;
  width: 1.75rem; height: 1.75rem; border-radius: var(--r-sm);
  background: var(--accent); color: var(--on-accent); font-size: .85rem;
}
.brand small {
  font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); margin-left: auto; font-weight: 600;
}

.nav {
  padding: .5rem .55rem .8rem; display: flex; flex-direction: column;
  gap: .1rem; flex: 1; overflow-y: auto;
}
/* Группа — не украшение: пункты собраны по тому, ЧТО с ними делают.
   «Работа» требует решения, «Аналитика» только смотрится. */
.nav .nav-group {
  font-size: .64rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint);
  padding: .9rem .7rem .3rem; margin: 0;
}
.nav .nav-group:first-child { padding-top: .3rem; }
.nav a, .nav .locked {
  display: flex; align-items: center; gap: .6rem; min-height: 2.35rem;
  padding: .45rem .7rem; border-radius: var(--r-sm);
  color: var(--dim); text-decoration: none; font-size: .875rem;
  font-weight: 500;
}
.nav a:hover { background: var(--raised); color: var(--ink); }
/* Выбранный раздел: заливка акцентом и полоска у корешка. Полоска нужна
   вторым признаком — заливку одну не видно при дальтонизме. */
.nav a.on {
  background: var(--accent-bg); color: var(--accent); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--accent);
}
.nav a .label {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Счётчик у раздела: пока его нет, пункт молчит. Число появляется только
   когда там ЖДУТ решения — иначе меню превращается в приборную доску. */
.nav .count {
  min-width: 1.25rem; height: 1.25rem; padding: 0 .35rem; flex: none;
  display: none; place-items: center; border-radius: 999px;
  font-family: var(--font-mono); font-size: .68rem; font-weight: 600;
  background: var(--alert); color: var(--on-accent);
  font-variant-numeric: tabular-nums;
}
.nav .count.is-on { display: grid; }
.nav .count.is-quiet { background: var(--wait-bg); color: var(--dim); }
.nav .locked { color: var(--faint); cursor: default; }
/* Значок раздела рисуется маской: контур наследует цвет пункта, поэтому
   активный, обычный и наведённый не требуют трёх файлов картинки. */
.nav .bullet {
  width: 1.15rem; height: 1.15rem; flex: none;
  background: currentColor; opacity: .85;
  -webkit-mask: var(--ic-dialogs) center / contain no-repeat;
          mask: var(--ic-dialogs) center / contain no-repeat;
}
.nav a.on .bullet { opacity: 1; }
.nav a[href="/panel"] .bullet { -webkit-mask-image: var(--ic-today); mask-image: var(--ic-today); }
.nav a[href="/panel/feed"] .bullet { -webkit-mask-image: var(--ic-instagram); mask-image: var(--ic-instagram); }
.nav a[href="/panel/threads"] .bullet { -webkit-mask-image: var(--ic-threads); mask-image: var(--ic-threads); }
.nav a[href="/panel/bots"] .bullet { -webkit-mask-image: var(--ic-bots); mask-image: var(--ic-bots); }
.nav a[href="/panel/dialogs"] .bullet { -webkit-mask-image: var(--ic-dialogs); mask-image: var(--ic-dialogs); }
.nav a[href="/panel/audit"] .bullet { -webkit-mask-image: var(--ic-audit); mask-image: var(--ic-audit); }
.nav a[href="/panel/leads"] .bullet { -webkit-mask-image: var(--ic-leads); mask-image: var(--ic-leads); }
.nav a[href="/panel/people"] .bullet { -webkit-mask-image: var(--ic-people); mask-image: var(--ic-people); }
.nav a[href="/panel/data"] .bullet { -webkit-mask-image: var(--ic-data); mask-image: var(--ic-data); }
.nav a[href="/panel/book"] .bullet { -webkit-mask-image: var(--ic-book); mask-image: var(--ic-book); }
.nav a[href="/panel/spend"] .bullet { -webkit-mask-image: var(--ic-spend); mask-image: var(--ic-spend); }
.nav a[href="/panel/publisher"] .bullet { -webkit-mask-image: var(--ic-publisher); mask-image: var(--ic-publisher); }
.nav .stage {
  margin-left: auto;
  font-family: ui-monospace, monospace; font-size: .62rem;
  color: var(--faint); letter-spacing: .04em;
}

.side-foot {
  padding: .85rem 1rem; border-top: 1px solid var(--line);
  font-size: .78rem; color: var(--dim);
  display: flex; align-items: center; gap: .6rem;
}
.side-foot a { color: var(--dim); margin-left: auto; }
.side-foot a:hover { color: var(--ink); }
.side-foot .ava {
  width: 2rem; height: 2rem; border-radius: 50%; flex: none;
  background: var(--accent-bg);
}
.side-foot .who { display: grid; line-height: 1.25; min-width: 0; }
.side-foot .who b {
  color: var(--ink); font-size: .85rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.side-foot .who small { color: var(--dim); font-size: .72rem; }

/* ── рабочая область ────────────────────────────────────────────────── */

.work { padding: 1.5rem 2rem 3rem; max-width: 74rem; }

.head {
  display: flex; align-items: center; gap: .9rem;
  margin-bottom: 1.25rem; padding-bottom: .9rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
}
h1 {
  font-family: var(--font-display); font-weight: 600; font-size: 1.6rem;
  margin: 0; letter-spacing: -.02em; line-height: 1.2; text-wrap: balance;
}
.head .sub { color: var(--dim); font-size: .85rem; margin: .1rem 0 0; }
.head .clock {
  margin-left: auto;
  font-family: var(--font-mono); font-size: .72rem; color: var(--dim);
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}

/* ── карточки: состояние читается полосой слева ─────────────────────── */

.cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: .9rem; margin-bottom: 1.75rem;
}

.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1rem 1.1rem;
  position: relative; overflow: hidden;
}
.stat::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--wait);
}
.stat.is-live::before  { background: var(--live); }
.stat.is-alert::before { background: var(--alert); }
.stat.is-accent::before  { background: var(--accent); }

/* Карточку показателя собирают и на div, и на span («Данные»): на span
   строки слипались в одну. Блочность задаём стилем, чтобы не зависеть от
   того, каким тегом её собрали. */
.stat .label, .stat .value, .stat .note { display: block; }
.stat .label {
  font-size: .78rem; color: var(--dim); margin-bottom: .3rem; font-weight: 500;
}
.stat .value {
  font-family: var(--font-mono);
  font-size: 1.6rem; line-height: 1.15; font-variant-numeric: tabular-nums;
  font-weight: 600; letter-spacing: -.02em;
}
.stat .value small { font-size: .8rem; font-weight: 400; color: var(--dim); }
.stat .note { font-size: .78rem; color: var(--dim); margin-top: .35rem; }

/* ── живой индикатор: точка дышит, пока система работает ───────────── */

.pulse {
  width: 7px; height: 7px; border-radius: 50%; background: var(--live);
  display: inline-block; flex: none;
  animation: breathe 2.4s ease-in-out infinite;
}
.pulse.off { background: var(--faint); animation: none; }
@keyframes breathe {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 rgba(78,158,122,.45); }
  50%      { opacity: .55; box-shadow: 0 0 0 5px rgba(78,158,122,0); }
}
@media (prefers-reduced-motion: reduce) {
  .pulse { animation: none; }
}

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

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); margin-bottom: 1.25rem; overflow: hidden;
}
.panel > header {
  display: flex; align-items: center; gap: .7rem;
  padding: .95rem 1.2rem; border-bottom: 1px solid var(--line);
}
.panel > header h2 {
  font-family: var(--font-display); font-weight: 600; font-size: 1rem;
  margin: 0; letter-spacing: -.01em;
}
.panel > header .right { margin-left: auto; font-size: .78rem; color: var(--dim); }
.panel .body { padding: 1.2rem; }
.panel .scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: .85rem; }
th {
  text-align: left; padding: .5rem 1.1rem;
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 600; border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td { padding: .55rem 1.1rem; border-bottom: 1px solid var(--line); }
tr:last-child td { border-bottom: none; }
td.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
td.mono, .mono {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .8rem;
}
td.mono a { color: var(--ink); }
td.mono a:hover { color: var(--accent); }

/* Сегодняшний именинник — единственная строка, по которой надо действовать
   сегодня; завтра поздравление уже запоздает. */
tr.is-today td { background: var(--accent-bg); }
tr.is-today td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* ── столбики расходов по дням ──────────────────────────────────────────
   Без библиотек: столько данных (2 недели) рисуется флексом честнее, чем
   тянуть чарт-движок. Значения продублированы текстом под каждым столбиком —
   график, который читается только глазами, бесполезен для скринридера. */

.bars {
  display: flex; align-items: flex-end; gap: .35rem;
  overflow-x: auto; padding-bottom: .25rem;
}
/* 1.5rem, а не 2.2: на восьми точках столбики переставали влезать, и под
   каждым графиком висела полоса прокрутки ради девяти пикселей. */
.bars .bar { flex: 1 1 0; min-width: 1.5rem; text-align: center; }
.bars .col {
  height: 7rem; display: flex; align-items: flex-end; justify-content: center;
}
.bars .col span {
  display: block; width: 100%; max-width: 2.2rem;
  /* Сплошной цвет, не градиент: в светлой теме --accent-dim почти белый, и
     низ столбика растворялся в карточке. */
  background: var(--accent);
  border-radius: 3px 3px 0 0; min-height: 2px;
}
.bars b {
  display: block; margin-top: .4rem; font-size: .68rem; font-weight: 600;
  font-variant-numeric: tabular-nums; min-height: 1em;
}
.bars i {
  display: block; font-style: normal; font-size: .65rem; color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* Пояснение под таблицей: почему цифры не сходятся. Тон спокойный — это
   не ошибка, а особенность данных. */
.hint {
  margin: 0; font-size: .8rem; color: var(--dim); line-height: 1.55;
  text-wrap: pretty;
}

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

.weeknav { display: flex; gap: .4rem; flex-wrap: wrap; }
.weeknav[hidden] { display: none; }

/* Фильтр по дню недели: грузить картинки одной темы пачкой. */
.dayfilter {
  display: flex; gap: .35rem; flex-wrap: wrap;
  margin: 0 0 .8rem; padding-bottom: .8rem;
  border-bottom: 1px solid var(--line);
}
.dchip {
  padding: .3rem .7rem; border-radius: 999px; cursor: pointer;
  font-size: .82rem; line-height: 1;
  background: var(--raised); color: var(--dim);
  border: 1px solid var(--line); touch-action: manipulation;
}
.dchip:hover { border-color: var(--accent-dim); color: var(--ink); }
.dchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dchip.is-on {
  background: var(--accent-bg); color: var(--accent);
  border-color: var(--accent);
}

.wday { padding: .9rem 0; border-bottom: 1px solid var(--line); }
.wday:last-child { border-bottom: none; padding-bottom: 0; }
.wday:first-child { padding-top: 0; }
/* Дата слева, рубрика справа: заголовок дня читается как «когда — о чём». */
.wday h3 {
  font-family: Georgia, serif; font-weight: 400; font-size: .95rem;
  margin: 0 0 .7rem;
  display: flex; justify-content: space-between;
  align-items: baseline; gap: .75rem;
}
.wtheme-box { display: inline-flex; align-items: baseline; gap: .4rem; min-width: 0; }
.wdate { display: flex; align-items: baseline; gap: .5rem; }
.wdate span { font-family: ui-monospace, monospace; font-size: .75rem;
  color: var(--faint); font-variant-numeric: tabular-nums; }
.wday.is-today h3 { color: var(--accent); }

/* Тема дня — справа в заголовке: рубрика всего дня. Правится на месте,
   поэтому кнопка, а не подпись. */
.wtheme, .wtheme-edit {
  min-width: 0; max-width: 100%; text-align: right;
  font-family: Georgia, "Times New Roman", serif; font-size: .92rem;
  padding: .15rem .5rem; border-radius: var(--r-sm);
}
.wtheme-edit { width: 14rem; }
.wtheme {
  background: none; border: 1px solid transparent; color: var(--ink);
  cursor: text; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wtheme:hover { border-color: var(--line); }
/* Незаполненная тема не кричит: подсказка видна, но не спорит с датой. */
.wtheme.none { color: var(--faint); font-size: .8rem; font-family: inherit; }
.wtheme-edit {
  background: var(--night); color: var(--ink); font: inherit;
  border: 1px solid var(--accent);
}

/* Значок «i» — описание рубрики: о чём генерить контент в этот день.
   Стоит в третьей колонке заголовка (той, что была распоркой), прижат
   к теме, а не к правому краю: он относится к ней, а не к дню. */
/* Цвета здесь --dim, а не --faint, хотя значок задумывался тише. Причина
   измерена на светлой теме (2026-07-20): --faint даёт 2.93:1 к фону, а
   границам управляющих элементов нужно 3:1, тексту — 4.5:1. Приглушённость
   набираем формой (кружок 18px, курсив) и пунктиром, а не блёклостью:
   контраст — не декоративный параметр. */
.wnote-btn {
  width: 1.15rem; height: 1.15rem; padding: 0; flex: none;
  border-radius: 50%; border: 1px solid var(--dim);
  background: none; color: var(--dim);
  font-family: Georgia, serif; font-style: italic; font-size: .72rem;
  line-height: 1; cursor: pointer; touch-action: manipulation;
}
.wnote-btn:hover { border-color: var(--accent); color: var(--accent); }
.wnote-btn[aria-expanded="true"] {
  border-color: var(--accent); color: var(--accent); background: var(--accent-bg);
}
/* Описания ещё нет. Отличаем ПУНКТИРОМ, а не бледностью — пунктир читается
   как «пустая заготовка» и не жертвует контрастом. */
.wnote-btn.none { border-style: dashed; }

.wnote {
  margin: 0 0 .6rem; padding: .6rem .75rem;
  background: var(--surface); border: 1px solid var(--line);
  /* Левая грань акцентом, а не --accent-dim: в светлой теме тот даёт 1.39:1
     и панель теряет опору. */
  border-left: 2px solid var(--accent); border-radius: var(--r-sm);
}
.wnote p {
  margin: 0; font-size: .85rem; line-height: 1.5; color: var(--dim);
  white-space: pre-wrap; cursor: text; border-radius: var(--r-sm);
}
.wnote p:hover { color: var(--ink); }
/* Заглушка отличается курсивом, но остаётся читаемой: это ещё и инструкция,
   что делать дальше. */
.wnote p.empty { font-style: italic; }
.wnote-edit {
  width: 100%; resize: vertical; font: inherit; font-size: .85rem;
  line-height: 1.5; padding: .4rem .5rem; border-radius: var(--r-sm);
  background: var(--night); color: var(--ink); border: 1px solid var(--accent);
}

@media (max-width: 46rem) {
  /* На телефоне противовес не нужен: строка и так узкая, тема уходит
     под дату и выравнивается по левому краю, как остальной текст. */
  .wday h3 { grid-template-columns: 1fr; gap: .3rem; }
  .wtheme, .wtheme-edit { text-align: left; width: 100%; }
  /* Значок не растягиваем на всю ширину вслед за темой — он остаётся
     кружком, иначе превратился бы в полосу. */
  .wnote-btn { width: 1.35rem; height: 1.35rem; }
}

/* minmax(0, 1fr), а не просто 1fr: иначе колонка не может стать уже своего
   содержимого, и слот с длинным текстом раздвигает соседний. Обрезание
   текста многоточием тоже начинает работать только с этим. */
/* ── день: две колонки по времени суток (Утро / Вечер) ────────────────────
   Каждая колонка — один дайпарт: пост сверху, под ним его сторис. Так пост и
   сторис одного времени стоят вместе, а не разнесены (решение Артура
   2026-07-25). Колонки равной ширины — день читается симметрично. */
.wparts {
  display: grid; gap: .8rem 1.5rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.wpart { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.wpart-head {
  font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 500;
}

/* Сторис под своим постом: превью 9:16 слева, подпись со временем справа. */
.wstory { display: flex; align-items: center; gap: .6rem; }
.wstory-drop {
  flex: none; width: 40px; height: 71px;   /* 9:16 */
  display: grid; place-items: center; cursor: pointer; overflow: hidden;
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.wstory-drop:not(.has) { border-style: dashed; }
.wstory-drop:hover { border-color: var(--accent-dim); }
.wstory-drop:focus-within {
  border-color: var(--accent);
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.wstory-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wstory-add { color: var(--faint); font-size: 1.05rem; line-height: 1; text-align: center; }
.wstory-add small { display: block; font-size: .58rem; margin-top: .1rem; }

/* Инпут прячем от глаз, но НЕ от клавиатуры: Tab по-прежнему на него встаёт,
   а focus-within подсвечивает рамку. */
.wstory-file {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.wstory-info { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.wstory-cap { color: var(--dim); font-size: .8rem; }
.wstory-st { font-size: .72rem; line-height: 1.15; }
.wstory-st.muted { color: var(--faint); }
.wstory-st.ok { color: var(--live); }
.wstory-st.wait { color: var(--wait); }
.wstory-st.bad { color: var(--alert); }
.wstory-del {
  flex: none; margin-left: auto; width: 22px; height: 22px; line-height: 1;
  padding: 0; color: var(--faint); background: transparent;
  border: 1px solid var(--line); border-radius: var(--r-sm); cursor: pointer;
}
.wstory-del:hover { color: var(--alert); border-color: var(--alert); }
.wstory-del:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.wslot {
  display: flex; align-items: center; gap: .75rem; width: 100%;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: .55rem .7rem;
}
.wslot:hover { border-color: var(--accent-dim); }
/* Пустой слот приглушён, но не спрятан: он часть сетки, и по нему видно,
   сколько ещё предстоит заполнить. */
.wslot.is-empty { opacity: .62; border-style: dashed; }

/* Картинку тащат прямо на слот. Подсветка должна быть однозначной: с файлом
   под курсором разглядывать тонкую рамку некогда. */
.wslot.over {
  border-color: var(--accent); border-style: solid;
  background: var(--accent-bg); opacity: 1;
  outline: 2px solid var(--accent); outline-offset: -2px;
}
.wslot.over * { pointer-events: none; }   /* дети не крадут dragleave */
.wslot.busy { opacity: .55; cursor: progress; }

/* ── короткое сообщение о результате ────────────────────────────────────── */

.toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%);
  z-index: 20; margin: 0; max-width: min(30rem, calc(100% - 2rem));
  padding: .6rem 1rem; border-radius: var(--r-sm);
  background: var(--raised); color: var(--ink);
  border: 1px solid var(--accent); box-shadow: var(--shadow);
  font-size: .86rem; text-align: center;
}
.toast.bad { border-color: var(--alert); color: var(--alert); }
.toast[hidden] { display: none; }

.wthumb {
  width: 2.6rem; height: 2.6rem; flex: none; border-radius: 4px;
  object-fit: cover; background: var(--surface);
  border: 1px solid var(--line);
}
.wthumb.none {
  display: grid; place-items: center; color: var(--faint); font-size: .9rem;
}
.wmain { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.wtime {
  font-family: ui-monospace, monospace; font-size: .74rem; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.wtext {
  font-size: .82rem; margin-top: .1rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 46rem) {
  /* Узко — колонки утра и вечера в стопку, каждая на всю ширину. */
  .wparts { grid-template-columns: 1fr; }
}

/* ── загрузка картинки ──────────────────────────────────────────────── */

.drop {
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  background: var(--night); cursor: pointer; overflow: hidden;
  display: grid; place-items: center; padding: .5rem;
}
.drop:hover, .drop.over { border-color: var(--accent); }
.drop.busy { opacity: .6; cursor: progress; border-color: var(--accent); }
.drop-empty {
  display: flex; flex-direction: column; gap: .2rem; text-align: center;
  padding: .8rem 1rem; color: var(--dim);
}
.drop-empty b { font-size: .85rem; color: var(--ink); font-weight: 600; }
.drop-empty span { font-size: .74rem; }
.drop-actions { display: flex; gap: .5rem; margin-top: .45rem; }

/* ── карусель: порядок виден и меняется ─────────────────────────────────
   Картинки лежат в ряд слева направо — ровно так, как их пролистает
   подписчик. Первая подписана «обложка»: именно она попадёт в превью. */

.gallery {
  display: flex; gap: .5rem; overflow-x: auto; padding-bottom: .35rem;
  margin-bottom: .5rem;
}
.gallery:empty { display: none; }
.gitem {
  margin: 0; position: relative; flex: none; width: 5.2rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden; background: var(--night);
}
.gitem img { display: block; width: 100%; height: 6.4rem; object-fit: cover; }
.gitem .cover {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--accent); color: var(--on-accent);
  font-size: .62rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; text-align: center; padding: .15rem;
}
.gtools {
  position: absolute; top: .25rem; right: .25rem; display: flex; gap: .2rem;
}
.gtools button {
  width: 1.5rem; height: 1.5rem; padding: 0; font: inherit; font-size: .8rem;
  line-height: 1; cursor: pointer; border-radius: 4px;
  background: rgba(12, 14, 26, .82); color: #E8E9F3;
  border: 1px solid rgba(232, 233, 243, .28);
}
.gtools button:hover:not(:disabled) { background: var(--accent); color: var(--on-accent); }
.gtools button:disabled { opacity: .35; cursor: default; }

.hint-inline {
  font-family: ui-monospace, Consolas, monospace; font-size: .68rem;
  color: var(--accent); text-transform: none; letter-spacing: .02em;
  margin-left: .4rem;
}

/* Счётчик картинок поверх обложки в недельной сетке */
.wthumb-wrap { position: relative; flex: none; }
.wcount {
  position: absolute; right: -.25rem; bottom: -.25rem;
  min-width: 1.15rem; height: 1.15rem; padding: 0 .2rem;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--accent); color: var(--on-accent);
  font-size: .64rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

.ed-meta a { color: var(--accent); }
.ed-meta .bad { color: var(--alert); }

/* ── выбор каналов ──────────────────────────────────────────────────────
   Кнопка-переключатель, а не галочка: она же показывает состояние. Выключен —
   приглушён и перечёркнут, чтобы отличие читалось не только цветом. */

.chan { display: flex; gap: .5rem; flex-wrap: wrap; }
.chan-btn {
  display: inline-flex; align-items: center; gap: .45rem;
  font: inherit; font-size: .85rem; font-weight: 600; cursor: pointer;
  padding: .45rem .8rem; border-radius: var(--r-sm);
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent);
}
.chan-btn svg { flex: none; }
.chan-btn.off {
  background: transparent; color: var(--faint); border-color: var(--line);
}
.chan-btn.off span { text-decoration: line-through; }
.chan-btn:disabled { cursor: default; opacity: .6; }
.chan-btn:not(:disabled):hover { filter: brightness(1.12); }

.ed-field[hidden] { display: none; }

/* ── куда пойдёт пост: видно и переключается прямо в сетке ──────────────── */

.wchans { display: inline-flex; gap: .2rem; margin-left: .45rem; }
.wch {
  display: inline-grid; place-items: center; width: 1.35rem; height: 1.35rem;
  padding: 0; cursor: pointer; border-radius: 4px;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-dim);
}
/* Выключенный канал гасим И перечёркиваем: одного цвета мало, разницу должно
   быть видно и в бледной теме, и тем, кто цвета различает хуже. */
.wch.off {
  background: transparent; color: var(--faint); border-color: var(--line);
  position: relative;
}
.wch.off::after {
  content: ""; position: absolute; left: 12%; right: 12%; top: 47%;
  height: 1px; background: currentColor; transform: rotate(-45deg);
}
.wch:not(:disabled):hover { border-color: var(--accent); color: var(--accent); }
.wch:disabled { cursor: default; opacity: .5; }

/* Карточка для генератора — строка под сторис, в одном с ней ритме: слева
   значок в квадрате, справа подпись в две строки. Раньше это была иконка
   в 22 пиксела внутри плитки поста — пальцем не попасть, а нажимают её
   каждый день. Поэтому кликабельна вся строка целиком. */
.wcard {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--r-sm); padding: .3rem .35rem;
}
.wcard-ico {
  flex: none; width: 40px; height: 34px;
  display: grid; place-items: center; color: var(--faint);
  background: var(--raised); border: 1px dashed var(--line);
  border-radius: var(--r-sm);
}
.wcard-info { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.wcard-cap { color: var(--dim); font-size: .8rem; }
.wcard-hint { color: var(--faint); font-size: .72rem; line-height: 1.15; }
.wcard:hover { border-color: var(--accent-dim); }
.wcard:hover .wcard-ico { color: var(--accent); border-color: var(--accent-dim); }
.wcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── редактор поста ─────────────────────────────────────────────────── */

dialog {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 0; max-width: 62rem; width: calc(100% - 2rem);
  max-height: calc(100vh - 2rem);
  box-shadow: var(--shadow);
}
dialog::backdrop { background: rgba(4, 5, 12, .6); }
.ed {
  padding: 1.1rem 1.4rem 1rem;
  display: flex; flex-direction: column; gap: .85rem;
  max-height: calc(100vh - 2rem);
}

/* Шапка: слева что за пост, справа — куда пойдёт. Каналы наверху, потому что
   это первое решение по посту, а не последнее. */
.ed-head {
  display: flex; align-items: flex-start; gap: 1rem;
  padding-bottom: .85rem; border-bottom: 1px solid var(--line);
}
.ed-title-wrap { flex: 1 1 auto; min-width: 0; }
.ed h2 {
  font-family: Georgia, serif; font-weight: 400; font-size: 1.15rem; margin: 0;
}
.ed-meta { font-size: .8rem; color: var(--dim); margin: .2rem 0 0; }
.ed-head .chan { flex: none; }

/* Прокручивается только середина: шапка и кнопки всегда на виду.
   Отступ по краям — не косметика: без него обводка сфокусированного поля
   упиралась в край прокручиваемой области и срезалась. Нужно не меньше
   4px (отступ обводки 2 + её толщина 2); ставим 6 с запасом. */
.ed-body {
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 1.25rem; overflow-y: auto; min-height: 0; padding: 6px;
  /* Отступ съедает ширину — возвращаем её, чтобы колонки не сузились. */
  margin: -6px -6px 0;
}
.ed-col { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.ed-texts { gap: .9rem; }

.ed label {
  display: block; font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--dim); margin: 0 0 .3rem;
}
.ed-media label:not(:first-child) { margin-top: .8rem; }
.ed textarea, .ed input {
  width: 100%; font: inherit; font-size: .9rem; line-height: 1.55;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .6rem .7rem; resize: vertical;
}
/* Высота полей в строках, а не в пикселях: два текста рядом должны быть
   одинаковыми и вместе умещаться в экран. */
.ed textarea { min-height: 7.5rem; height: 9rem; }

/* Фокус в поле текста — цветом своей сети: сразу видно, для какой пишешь.
   Обводка снаружи, поверх соседей, поэтому и понадобился отступ у .ed-body. */
.ed-field textarea:focus,
.ed-field textarea:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
  border-color: var(--brand);
}
.ed-field[data-field="tg"] { --brand: #229ED9; }   /* синий Телеграма */
.ed-field[data-field="vk"] { --brand: #0077FF; }   /* синий ВКонтакте */
/* Карточка для генератора — ниже полей поста: её здесь не пишут, а копируют
   целиком, и высота в 9rem зря выдавила бы колонку за пределы экрана. */
#ed-card { min-height: 5.5rem; height: 6.5rem; font-size: .82rem; }

.ed textarea:disabled, .ed input:disabled { color: var(--dim); cursor: not-allowed; }
.ed-count { font-size: .72rem; color: var(--faint); margin: .25rem 0 0; text-align: right; }
.ed-actions {
  display: flex; gap: .5rem; flex-wrap: wrap; justify-content: flex-end;
  padding-top: .85rem; border-top: 1px solid var(--line);
}

/* Узкий экран — одна колонка: две рядом здесь только мешают. */
@media (max-width: 52rem) {
  .ed-body { grid-template-columns: 1fr; }
  .ed-head { flex-direction: column; gap: .6rem; }
}

/* ── работа бота: очереди пачек ─────────────────────────────────────── */

.queues { display: grid; gap: .9rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { .queues { grid-template-columns: 1fr; } }

.queue {
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r); padding: .9rem 1rem 1rem;
}
.queue.is-dead { border-color: var(--alert); }
.qhead { display: flex; align-items: center; gap: .5rem; }
.qhead b { font-size: .95rem; }
.qhead .chip { margin-left: auto; }

.qbig { display: flex; align-items: baseline; gap: .4rem; margin: .5rem 0 .45rem; }
.qbig b {
  font-size: 1.9rem; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;   /* цифра меняется каждые 10 сек — не должна прыгать */
}
.qbig span { font-size: .85rem; color: var(--dim); }

.bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .bar i { transition: width .4s ease; }
}

.qwhy { font-size: .8rem; color: var(--dim); margin: .5rem 0 .1rem; }

.qmeta { margin: .6rem 0 0; font-size: .78rem; }
.qmeta > div {
  display: flex; gap: .5rem; padding: .28rem 0;
  border-top: 1px solid var(--line);
}
.qmeta dt { color: var(--dim); }
.qmeta dd { margin: 0 0 0 auto; text-align: right; font-variant-numeric: tabular-nums; }
/* Последняя строка — пульс цикла: молчит он, а не очередь */
.queue.is-dead .qmeta > div:last-child dd { color: var(--alert); font-weight: 600; }

.qnote { font-size: .74rem; color: var(--faint); margin: .55rem 0 0; }

/* ── посты и тумблер воронки ────────────────────────────────────────── */

.hint { font-size: .8rem; color: var(--dim); margin: 0 0 .9rem; }

/* Порядок ленты. Отдельной строкой над плитками: это про весь список, а не
   про конкретный пост (Артур 2026-08-08). */
.sortbar { margin: 0 0 .9rem; }
.sortbar button { font-size: .74rem; padding: .38rem .7rem; }

/* ─── Лента постов: плитки, как в самом Instagram ──────────────────────────
   Обложка сверху, работа под ней. Строка на всю ширину читалась таблицей —
   а это лента, и узнавать пост нужно глазами, по картинке (2026-08-07). */
.posts {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  align-items: start;
}

.post {
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden;
}
/* Нерешённый пост — работа, а не справка: он должен цеплять взгляд. */
.post.is-undecided { border-color: var(--accent-dim); }

.pcover {
  display: block; position: relative; background: var(--night);
  aspect-ratio: 1 / 1;   /* как сетка профиля: там превью тоже квадратные */
}
.pimg { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Обложки может не быть: старый пост, протухшая ссылка Meta. Знак вместо
   картинки честнее пустого прямоугольника. */
.pimg.is-blank {
  display: grid; place-items: center;
  font-size: 2rem; color: var(--faint);
}
.pbadge { position: absolute; left: .5rem; top: .5rem; }
.pcover:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.pbody { display: grid; gap: .45rem; padding: .6rem .7rem .7rem; }
.pcap {
  margin: 0; font-size: .85rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* --dim, а не --faint: «27 комм. · 5 ч назад» — это данные, по которым
   принимают решение. */
.pmeta { margin: 0; font-size: .74rem; color: var(--dim); }
/* В плитке кнопки во всю ширину: пять штук в ряд не помещаются, а обрезанная
   надпись хуже двух рядов. */
.pbody .seg { display: flex; }
.pbody .seg button { flex: 1; padding: .4rem .3rem; font-size: .72rem; }

.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.seg button {
  font: inherit; font-size: .78rem; padding: .45rem .8rem; cursor: pointer;
  background: transparent; color: var(--dim); border: 0;
  /* Панель открывают и с телефона: 33 пикселя мимо пальца, нужно от 44
     (замер 2026-08-04). На мыши лишняя высота не мешает. */
  min-height: 2.75rem;
}
@media (min-width: 900px) {
  .seg button { min-height: 2.1rem; }
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button:hover:not(.on) { background: var(--surface); color: var(--ink); }
/* Не белым по --accent: в светлой теме это 4.2:1, в тёмной 2.8:1 — обе ниже
   нормы. Пара --accent-dim + --ink проверена в обеих темах (7.4 и 5.8). */
.seg button.on { background: var(--accent-dim); color: var(--ink); font-weight: 600; }
.seg button:disabled { opacity: .5; cursor: default; }

.toast {
  position: fixed; bottom: 1.2rem; left: 50%; transform: translateX(-50%);
  background: var(--raised); color: var(--ink);
  border: 1px solid var(--accent-dim); border-radius: var(--r);
  padding: .6rem 1rem; font-size: .85rem; box-shadow: var(--shadow); z-index: 50;
}

@media (max-width: 640px) {
  .pside { margin-left: 0; width: 100%; justify-content: space-between; }
}

/* ── страница Threads: как работает автопилот ───────────────────────── */

.split { display: grid; gap: .9rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 560px) { .split { grid-template-columns: 1fr; } }

.how { margin: 0; padding-left: 1.2rem; font-size: .88rem; }
.how li { margin: 0 0 .65rem; }
.how li:last-child { margin-bottom: 0; }
.how b { color: var(--ink); }

/* ── чипы состояния ─────────────────────────────────────────────────── */

.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .68rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; padding: .16rem .45rem; border-radius: 4px;
  white-space: nowrap;
}
.chip.live  { background: var(--live-bg);  color: var(--live); }
.chip.wait  { background: var(--wait-bg);  color: var(--wait); }
.chip.alert { background: var(--alert-bg); color: var(--alert); }
.chip.accent  { background: var(--accent-bg);  color: var(--accent); }
/* Нейтральный чип. Без модификатора фон прозрачный, и метка читается как
   случайно оставшийся текст рядом с заголовком (2026-08-03). */
.chip.mute  { background: var(--raised);   color: var(--dim); }

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

.btn {
  font: inherit; font-size: .85rem; padding: .5rem 1rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  cursor: pointer; text-decoration: none; display: inline-block;
  transition: border-color .15s, background .15s;
}
.btn:hover { background: var(--raised); }
.btn:hover { border-color: var(--accent-dim); }
.btn.primary {
  background: var(--accent); color: var(--on-accent); border-color: var(--accent);
  font-weight: 600;
}
.btn.primary:hover { filter: brightness(1.06); }

a:focus-visible, button:focus-visible, input:focus-visible, .btn:focus-visible,
textarea:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.empty { color: var(--dim); font-size: .85rem; padding: .5rem 0; }

/* Клавиатурный переход к содержимому: видна только при фокусе, чтобы не
   листать всю навигацию табом на каждой странице. */
.skip {
  position: absolute; left: .75rem; top: -3rem; z-index: 10;
  background: var(--accent); color: var(--on-accent); font-weight: 600;
  padding: .5rem .9rem; border-radius: var(--r-sm); text-decoration: none;
  transition: top .15s ease;
}
.skip:focus-visible { top: .75rem; }
@media (prefers-reduced-motion: reduce) { .skip { transition: none; } }

/* ── узкий экран: навигация сверху ──────────────────────────────────── */

/* ── меню на телефоне: ящик, а не лента ────────────────────────────────
   Раньше на узком экране сайдбар превращался в горизонтальную полосу из
   одиннадцати пунктов — видно было три, остальные за краем. Ящик по кнопке
   показывает все разделы сразу, включая группы и счётчики. */

.navtoggle {
  display: none; position: fixed; z-index: 45; left: .6rem; top: .6rem;
  width: 2.6rem; height: 2.6rem; border-radius: var(--r-sm);
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
  place-items: center; cursor: pointer; box-shadow: var(--shadow);
  touch-action: manipulation;
}
.navtoggle .count.is-on {
  position: absolute; right: -.3rem; top: -.3rem;
  min-width: 1.15rem; height: 1.15rem; padding: 0 .3rem;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--alert); color: var(--on-accent);
  font-family: var(--font-mono); font-size: .65rem; font-weight: 600;
}
.navtoggle .count { display: none; }
.scrim { display: none; }

@media (max-width: 60rem) {
  .shell { grid-template-columns: 1fr; }
  .navtoggle { display: grid; }
  .side {
    position: fixed; z-index: 50; left: 0; top: 0; width: 17.5rem;
    height: 100dvh; transform: translateX(-101%);
    transition: transform .2s ease; box-shadow: var(--shadow);
    overscroll-behavior: contain;
  }
  .shell.nav-open .side { transform: none; }
  .shell.nav-open .scrim {
    display: block; position: fixed; inset: 0; z-index: 46;
    background: rgba(8, 10, 16, .5);
  }
  .work { padding: 3.9rem 1rem 2.5rem; }
  .head .clock { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .side { transition: none; }
}

/* ── на что уходят деньги: строки с долей от общей суммы ─────────────────
   Полоса, а не только число: доли читаются глазом за секунду, а колонка
   цифр требует их сравнивать (2026-07-29). */
.grow { padding: .55rem 0; border-bottom: 1px solid var(--line); }
.grow:last-child { border-bottom: none; }
.grow-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: .75rem; }
.grow-name { font-size: .92rem; }
.grow-sum { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.grow-bar { height: 5px; margin: .35rem 0 .25rem; border-radius: 3px;
  background: var(--raised); overflow: hidden; }
.grow-bar i { display: block; height: 100%; background: var(--accent);
  border-radius: 3px; }
.grow-note { font-size: .74rem; color: var(--dim); }

/* ── воронка заявок ─────────────────────────────────────────────────── */

/* Итоговые числа: крупная цифра, под ней подпись. Auto-fit, чтобы на узком
   экране плитки перестраивались сами, а не резались. */
.steps {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.step {
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: .7rem .8rem;
}
.step b {
  display: block; font-size: 1.55rem; line-height: 1.1; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.step span { font-size: .78rem; color: var(--dim); }

/* Таблица шире экрана прокручивается внутри себя — страница по горизонтали
   не едет. */
.tablewrap { overflow-x: auto; }

/* Фильтры лидов. Отдельно от .chip: тот — статусная метка, а это кнопка,
   и ей нужны состояния наведения и фокуса. */
.filters { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .8rem; }
.fbtn {
  font: inherit; font-size: .84rem; padding: .44rem .8rem;
  background: var(--surface); color: var(--dim);
  border: 1px solid var(--line); border-radius: var(--r);
  cursor: pointer; touch-action: manipulation;
  transition: background .15s, color .15s, border-color .15s;
}
.fbtn:hover { color: var(--ink); border-color: var(--accent-dim); }
/* Выбранный фильтр залит акцентом, текст — цветом фона страницы. Это не
   «белый»: на тёмной теме акцент светлый, и белым по нему было бы не
   прочесть. --night в своей теме всегда контрастен акценту (7.0 и 9.2). */
.fbtn.on {
  background: var(--accent); color: var(--night);
  border-color: var(--accent); font-weight: 600;
}
.fbtn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Текст заявки бывает длинным — переносим по словам, а не растягиваем
   колонку. */
.say { word-break: break-word; min-width: 12rem; }

/* Ссылка на профиль в таблице лидов. Без этого браузер рисует её своим
   синим (#0000EE) — на тёмной теме почти нечитаемо. */
#leads a { color: var(--accent); text-decoration: none; }
#leads a:hover { text-decoration: underline; }
#leads a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: 2px; }
td.nowrap { white-space: nowrap; font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .fbtn { transition: none; }
}

/* ── воронка: ступени ───────────────────────────────────────────────── */

.funnel { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }

/* Сетка, а не flex: во flex процентная ширина полосы схлопывалась до
   ширины контента, и все ступени выходили одинаковыми (2026-08-01).
   Левая колонка отдана полосе, правая — конверсии и подписи. */
.fstep {
  display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  align-items: center; gap: .8rem;
}
.ftrack { min-width: 0; }

.fbar {
  display: flex; align-items: baseline; gap: .6rem;
  padding: .6rem .9rem; border-radius: var(--r-sm);
  color: #fff; box-sizing: border-box;
  /* Полоса пропорциональна числу, но название всегда должно читаться:
     на 22 из 1447 ступень выходила в 128px и обрезалась до «Попроси…»
     (замер 2026-08-02). Разница между ступенями от этого не теряется —
     она видна выше по воронке, где числа крупные. */
  min-width: 13rem; max-width: 100%;
}
.fbar b { font-size: 1.35rem; font-variant-numeric: tabular-nums; }
.fbar span {
  font-size: .82rem; opacity: .95;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Ступени — от холодного к тёплому: путь сужается и «нагревается» к деньгам.
   Оттенки затемнены до контраста ≥4.5 с белым текстом: первый набор давал
   2.94 на жёлтой ступени (замер 2026-08-01). */
/* Запасной фон идёт ПЕРВЫМ: специфичность у него та же, что у цветов ниже,
   и стоя последним он перекрыл бы их все. Нужен он затем, что ключ без
   своего цвета превращается в белый текст на пустом месте — так ступень
   «Оставили заявку» и пропала с глаз (2026-08-25). */
.fbar          { background: #5A5F6B; }
.fbar-asked    { background: #46589F; }
.fbar-razbory  { background: #2A7F5F; }
.fbar-leads    { background: #96631A; }
.fbar-demo     { background: #8A4B2A; }
.fbar-requests { background: #8E3C63; }
.fbar-paid     { background: #A93F3F; }

.fside { display: flex; align-items: baseline; gap: .5rem; min-width: 0; }
.fconv {
  font-size: .8rem; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Две строки, а не многоточие: подсказка объясняет, ЧТО именно считает
   ступень, и обрезанная «упомянули платный разбор — интере…» не объясняет
   ничего (2026-08-25). */
.fhint {
  font-size: .76rem; color: var(--dim); min-width: 0;
  overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2;
}

@media (max-width: 700px) {
  .fstep { grid-template-columns: 1fr; gap: .15rem; }
  .fbar { width: 100% !important; }   /* доля на узком экране только мешает */
  .fside { padding-left: .2rem; }
}

/* Кнопка «оплачено» в таблице лидов. */
.paybtn {
  font: inherit; font-size: .78rem; padding: .28rem .6rem;
  background: var(--raised); color: var(--dim);
  border: 1px solid var(--line); border-radius: 999px;
  cursor: pointer; touch-action: manipulation; white-space: nowrap;
  transition: background .15s, color .15s, border-color .15s;
}
.paybtn:hover:not(:disabled) { color: var(--ink); border-color: var(--accent); }
.paybtn.on {
  background: var(--live-bg); color: var(--live);
  border-color: var(--live); font-weight: 600;
}
.paybtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.paybtn:disabled { opacity: .6; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .paybtn { transition: none; }
}

/* Переключатель периода — над всеми блоками: он меняет и воронку, и итоги,
   и список, поэтому стоит выше их, а не внутри одного из них. */
.filters.period { margin: 0 0 1rem; }

/* ── графики динамики по шагам ──────────────────────────────────────── */

.charts {
  display: grid; gap: .8rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.chart {
  margin: 0; padding: .8rem;
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.chart figcaption {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .5rem; margin-bottom: .6rem;
}
.chart-name { font-size: .85rem; color: var(--dim); }
.chart-last {
  font-size: 1.25rem; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chart-last i { font-size: .72rem; font-style: normal; font-weight: 500; }
.chart-last i.up { color: var(--live); }
.chart-last i.down { color: var(--alert); }

/* Столбики — div-ами, а не canvas: читаются скринридером, масштабируются
   со шрифтом и не тянут библиотеку.

   Селекторы ОБЯЗАТЕЛЬНО от .chart: голый .bar уже занят полосой заполнения
   очереди (см. «Работа бота»), и объявленный здесь второй раз он перебивал
   её высоту — 4 пикселя превращались в 221, и на главной висел пустой серый
   прямоугольник (Артур 2026-08-04: «истый хаос»). */
.chart .bars {
  display: flex; align-items: flex-end; gap: 2px;
  height: 3.2rem;
}
.chart .bar { flex: 1 1 0; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; }
.chart .bar i {
  display: block; width: 100%; background: var(--accent-dim);
  border-radius: 2px 2px 0 0; transition: background .15s;
}
.chart .bar:last-child i { background: var(--accent); }
.chart .bar:hover i { background: var(--accent); }

.bars-x {
  display: flex; justify-content: space-between;
  /* --dim, а не --faint: подписи осей — читаемый текст, а faint давал
     контраст 3.09 при норме 4.5 (замер 2026-08-01). */
  margin-top: .35rem; font-size: .72rem; color: var(--dim);
}

/* Переключатель разреза стоит в шапке блока — компактнее основного. */
.filters.tight { margin: 0; gap: .3rem; }
.filters.tight .fbtn { font-size: .76rem; padding: .22rem .55rem; }

@media (prefers-reduced-motion: reduce) {
  .bar i { transition: none; }
}

/* ── демо-разбор ───────────────────────────────────────────────────────── */

/* Четыре коротких поля в ряд, на узком экране — в столбик. Сетка своя, а не
   .ed-col по одному: дата, время и город читаются как одна строка данных. */
.dm-grid {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.dm-opt { text-transform: none; letter-spacing: 0; color: var(--faint); }
.dm-actions { display: flex; align-items: center; gap: .8rem; margin-top: 1rem; }
.dm-note { font-size: .82rem; color: var(--dim); }
.dm-note.good { color: var(--live); }
.dm-note.bad  { color: var(--alert); }

.dm-link { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.dm-link input {
  flex: 1 1 20rem; min-width: 0; font: inherit; font-size: .85rem;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .45rem .6rem;
}
/* Предпросмотр в пропорции A4: иначе PDF показывается обрезанным по низу,
   и «страница пустая» не отличить от «страница не влезла». */
.dm-preview {
  width: 100%; aspect-ratio: 1 / 1.35; margin-top: .9rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--night);
}
.dm-steps { margin: 0; padding-left: 1.1rem; font-size: .88rem; line-height: 1.6; }
.dm-steps li { margin: .35rem 0; }
.dm-steps b { color: var(--ink); }

/* ── раздел «Данные» ────────────────────────────────────────────────── */

/* Поиск и выгрузка в одной строке: одно сужает выборку, другое её забирает,
   и разводить их по разным углам значило бы прятать связь. */
.dsearch {
  display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
  margin-bottom: .8rem;
}
.dsearch-field { flex: 1 1 16rem; min-width: 0; display: block; }
.dsearch-field input {
  width: 100%; font: inherit; font-size: .85rem;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .45rem .7rem;
}
.dsearch-field input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.dexport {
  font-size: .82rem; padding: .4rem .9rem; white-space: nowrap;
  background: var(--accent-bg); color: var(--ink); text-decoration: none;
  border: 1px solid var(--accent); border-radius: 999px;
}
.dexport:hover { background: var(--accent); color: var(--on-accent); }
.dexport:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dexport { touch-action: manipulation; }

/* Строка кликабельна целиком: колонок шесть, и заводить седьмую с кнопкой
   «открыть» — отнимать место у текста ради того, что и так очевидно. */
.drow { cursor: pointer; touch-action: manipulation; }
/* Имя человека — настоящая кнопка: она и открывает карточку с клавиатуры.
   Выглядит текстом, чтобы не превращать колонку «кто» в ряд кнопок. */
.dwho {
  font: inherit; padding: 0; background: none; border: 0; text-align: left;
  color: var(--ink); cursor: pointer; touch-action: manipulation;
}
.dwho:hover { color: var(--accent); }
.dwho:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: 2px; }
/* Запрос и ответ обрезаем тремя строками. Полный разбор — три тысячи знаков,
   и без обрезки одна строка таблицы занимает пол-экрана: список перестаёт
   быть списком, а он нужен как раз для того, чтобы просматривать подряд.
   Целиком текст открывается в карточке — за тем она и есть.

   Обрезка на ВНУТРЕННЕМ элементе, а не на самой ячейке: display:-webkit-box
   на <td> вынимает её из табличной сетки, и колонки разъезжаются. */
.drow td.say { max-width: 17rem; }
.dclamp {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.drow:hover { background: var(--raised); }
.drow:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dstar { color: var(--accent); }
.dnone { color: var(--faint); font-style: normal; }
.dsignal { min-width: 9rem; }
.dreact { font-size: .95rem; margin-left: .3rem; }
/* Последняя реплика человека под меткой отклика: метка говорит «вопрос»,
   а это — какой именно, без открытия карточки. */
.dsay {
  display: block; margin-top: .25rem; font-size: .76rem; color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 13rem;
}

.dpager {
  display: flex; align-items: center; gap: .8rem; margin-top: .9rem;
  font-size: .82rem; color: var(--dim);
}
.dpager[hidden] { display: none; }
.dpager .fbtn:disabled { opacity: .4; cursor: default; }

/* Карточка человека — модальным окном, а не отдельной страницей: владелец
   просматривает список подряд и возвращается в то же место. */
.dcard {
  width: min(52rem, 92vw); max-height: 88vh; padding: 0;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
}
.dcard::backdrop { background: rgba(0, 0, 0, .55); }
.dcard-head {
  display: flex; align-items: center; gap: .8rem;
  padding: .9rem 1.1rem; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.dcard-head h2 { margin: 0; font-size: 1rem; font-weight: 600; }
.dcard-head a { color: var(--accent); text-decoration: none; }
.dcard-head a:hover { text-decoration: underline; }
.dcard-x {
  margin-left: auto; font: inherit; line-height: 1; cursor: pointer;
  background: none; color: var(--dim); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: .25rem .5rem;
}
.dcard-x { touch-action: manipulation; }
.dcard-x:hover { color: var(--ink); border-color: var(--accent); }
.dcard-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dcard-body { padding: 1.1rem; overflow-y: auto; overscroll-behavior: contain;
  max-height: calc(88vh - 3.6rem); }

.dfacts {
  display: grid; gap: .55rem; margin: 0 0 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.dfacts dt {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--faint);
}
.dfacts dd { margin: .1rem 0 0; font-size: .85rem; }

.dsec { margin-bottom: 1.4rem; }
.dsec h3 {
  margin: 0 0 .5rem; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--dim); font-weight: 600;
}
.dsec h4 { margin: 1rem 0 .4rem; font-size: .78rem; color: var(--faint); font-weight: 500; }
.dsec blockquote {
  margin: 0; padding: .6rem .8rem; font-size: .88rem;
  background: var(--raised); border-left: 2px solid var(--accent-dim);
  border-radius: var(--r-sm); white-space: pre-wrap; word-break: break-word;
}
.dmeta { margin: .3rem 0; font-size: .76rem; color: var(--faint); }
.dmeta a { color: var(--accent); }

/* Части разбора пронумерованы: реакция приходит на конкретное письмо,
   и без номера непонятно, что именно человеку понравилось. */
.dpart { display: flex; gap: .6rem; margin-bottom: .5rem; }
.dpart-no {
  flex: none; width: 1.3rem; height: 1.3rem; font-size: .7rem;
  display: grid; place-items: center; color: var(--faint);
  background: var(--raised); border: 1px solid var(--line); border-radius: 999px;
}
.dpart p {
  margin: 0; font-size: .88rem; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
}

.dlist { list-style: none; margin: 0; padding: 0; }
.dlist li {
  padding: .5rem 0; border-bottom: 1px solid var(--line); font-size: .88rem;
}
.dlist li:last-child { border-bottom: none; }
.dlist p { margin: 0; white-space: pre-wrap; word-break: break-word; }

@media (max-width: 40rem) {
  .dcard { width: 100vw; max-height: 100vh; border-radius: 0; }
  .dcard-body { max-height: calc(100vh - 3.6rem); }
  .dsay { max-width: 10rem; }
}

/* Подпись только для скринридера: поле поиска понятно по плейсхолдеру,
   но плейсхолдер — не имя элемента, и без этого поле читается «edit text». */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── вкладка «Боты»: функциональность разложена блоками ─────────────────
   Каждый блок — будущая настройка (Артур 2026-08-02), поэтому карточка
   выглядит как самостоятельная единица, а не как строка списка: у неё
   заголовок, состояние, пределы и адрес в коде. */

.panel-head {
  display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap;
  padding: 1rem 1.1rem; border-bottom: 1px solid var(--line);
}
.panel-head h2 {
  margin: 0; font-family: Georgia, serif; font-weight: 400; font-size: 1.15rem;
}
.panel-head .sub { margin: .2rem 0 0; }
.bmeta {
  margin-left: auto; text-align: right;
  display: flex; flex-direction: column; gap: .15rem;
  font-size: .78rem; color: var(--dim);
}
.bwhere { color: var(--faint); font-size: .74rem; }

.bgrid {
  display: grid; gap: .8rem; padding: 1rem 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}
.bblock {
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r); padding: .85rem .95rem;
  display: flex; flex-direction: column; gap: .5rem;
  border-left: 3px solid var(--live);
}
/* Выключенный блок глушим целиком, а не только подписью: взгляд должен
   отделять работающее от спящего до чтения. */
.bblock.off { border-left-color: var(--wait); opacity: .72; }
.bblock header {
  display: flex; align-items: baseline; gap: .6rem;
}
.bblock h3 {
  margin: 0; font-size: .95rem; font-weight: 600; line-height: 1.3;
}
.bstate {
  margin-left: auto; flex: none;
  font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--live);
}
.bblock.off .bstate { color: var(--wait); }
.bblock p { margin: 0; font-size: .84rem; color: var(--dim); line-height: 1.55; }
.blimits {
  margin: 0; padding-left: 1.05rem; font-size: .79rem; color: var(--dim);
  display: flex; flex-direction: column; gap: .2rem;
}
.bcode {
  margin-top: auto;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  /* --dim, а не --faint: адрес в коде читают, а не украшают им карточку —
     faint давал контраст 3.09 при норме 4.5 (замер 2026-08-02). */
  font-size: .72rem; color: var(--dim); word-break: break-all;
}

/* ── качество: контролёр, разметка, наблюдения ─────────────────────────── */

.dgrid {
  display: grid; gap: 1rem; margin-bottom: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}
.dbox { min-width: 0; }
.dbox h3, .dsec h4, .body h4 {
  margin: 0 0 .6rem; font-size: .74rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--dim); font-weight: 600;
}
.body h4 { margin-top: 1rem; }

/* Полоски вместо круговой диаграммы: их читает скринридер как обычный
   список, они масштабируются со шрифтом и не требуют библиотеки. */
.dbars { list-style: none; margin: .6rem 0 0; padding: 0; }
.dbars li {
  display: grid; grid-template-columns: 8.5rem 1fr auto; gap: .6rem;
  align-items: center; padding: .2rem 0; font-size: .82rem;
}
.dbar-name { color: var(--dim); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.dbar-track { background: var(--raised); border-radius: 999px; height: .5rem; }
.dbar-track i { display: block; height: 100%; border-radius: 999px;
  background: var(--accent); min-width: 2px; }
.dbars b { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Находки контролёра прячем под сворачивалку: в обычный день их нет,
   и держать пустой блок на виду — тратить место. */
.dfold { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .8rem; }
.dfold summary {
  cursor: pointer; font-size: .82rem; color: var(--dim);
  touch-action: manipulation;
}
.dfold summary:hover { color: var(--ink); }
.dfold summary:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 2px; border-radius: 2px; }
.dfold > div { margin-top: .7rem; }
.dfind { margin: .25rem 0; font-size: .82rem; color: var(--dim); }
.dfind i { color: var(--faint); }

/* Заголовок строки списка. Своя строка, а не .dlist p: у того white-space
   pre-wrap ради текстов людей, и перенос в шаблоне ронял чип на строку ниже
   вместе с отступом (2026-08-03). */
.dtitle {
  display: flex; align-items: center; gap: .45rem; flex-wrap: wrap;
  white-space: normal;
}
.dsimple { margin: .4rem 0 0; padding-left: 1.1rem; font-size: .86rem;
  line-height: 1.6; }
.dcalc { margin-top: 1rem; }
.dcalc:disabled { opacity: .6; cursor: progress; }

/* Описание рилса — раскрытие, а не поле нараспашку: бот отвечает на
   комментарии по смыслу видео (Артур 2026-08-02), но заполняют описание один
   раз, а карточку поста читают каждый день. Свёрнутая строка честно говорит,
   есть описание или нет, и показывает начало. */
.brief { border-top: 1px solid var(--line); }
.brief > summary {
  display: flex; align-items: center; gap: .5rem;
  padding: .55rem .9rem; cursor: pointer;
  font-size: .8rem; color: var(--dim);
  list-style: none;
}
.brief > summary::-webkit-details-marker { display: none; }
/* Треугольник рисуем сами: системный маркер прыгает между браузерами. */
.brief > summary::before {
  content: "›"; display: inline-block; flex: none;
  color: var(--faint); font-size: 1rem; line-height: 1;
  transition: transform .15s ease;
}
.brief[open] > summary::before { transform: rotate(90deg); }
.brief > summary:hover { color: var(--ink); }
.brief > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-sm);
}
@media (prefers-reduced-motion: reduce) {
  .brief > summary::before { transition: none; }
}
.btitle { font-weight: 600; color: var(--ink); flex: none; }
.bmark {
  flex: none;
  font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  padding: .1rem .4rem; border-radius: 999px;
  background: var(--wait-bg); color: var(--wait);
}
.bmark.on { background: var(--live-bg); color: var(--live); }
/* Заголовок и метка не сжимаются: иначе «О чём рилс» ломается пополам,
   когда рядом длинное превью (замер 2026-08-04). Сжимается только превью. */
.bpeek {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  /* Начало описания читают, чтобы не открывать карточку зря, — значит это
     текст, а не подпись: --dim вместо --faint (замер 2026-08-04). */
  color: var(--dim);
}
.bbody { display: grid; gap: .35rem; padding: 0 .9rem .85rem; }
.bbody label { font-size: .78rem; color: var(--dim); line-height: 1.45; }
.bbody textarea {
  width: 100%; resize: vertical; min-height: 4.5rem;
  padding: .6rem .7rem; border-radius: var(--r-sm);
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line);
  font: inherit; font-size: .85rem; line-height: 1.55;
}
.bbody textarea::placeholder { color: var(--faint); }
.bbody textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent;
}
.brief-state { font-size: .74rem; color: var(--dim); min-height: 1.05rem; }

/* Три раздела под рилсом: содержание пишет владелец, описание и закреп
   приходят из Instagram сами — их он только сверяет (Артур 2026-08-08).
   Автоматические разделы тише: это справка, а не работа. */
.fld { display: grid; gap: .3rem; }
.fld + .fld { margin-top: .7rem; padding-top: .6rem; border-top: 1px solid var(--line); }
.fld h4 {
  margin: 0; font-size: .78rem; font-weight: 600; color: var(--ink);
  display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap;
}
/* Пометка «из Instagram» — почему поля нет: заполнять нечего. */
.auto {
  font-size: .68rem; font-weight: 400; color: var(--faint);
  text-transform: lowercase; letter-spacing: .01em;
}
.fval {
  margin: 0; font-size: .78rem; color: var(--dim); line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 9rem; overflow-y: auto;
}
.fval.is-empty { color: var(--faint); font-style: italic; }

/* Тип разбора — строка, а не кнопки: его определяет разметка поста по описанию
   и закрепу (2026-08-07). Читается как справка, поэтому тише подписи. */
.ptopic { margin: 0; font-size: .74rem; color: var(--dim); }

/* Выпадающий список в форме — как поля рядом. Браузерный по умолчанию рвёт
   строку: другая высота, другой фон, свой шрифт. */
.ed select {
  width: 100%; font: inherit; font-size: .9rem; line-height: 1.55;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .6rem 1.9rem .6rem .7rem; appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--dim) 50%),
                    linear-gradient(135deg, var(--dim) 50%, transparent 50%);
  background-position: right 1.05rem center, right .8rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

/* ── выбор города ──────────────────────────────────────────────────────── */

/* Карточка режет всё, что вылезает за её края (overflow:hidden ради
   скруглений), и выпадающий список города обрубался на второй строке —
   прокрутить его было нельзя (Артур 2026-08-23). Форме клипать нечего. */
.panel.pl-host { overflow: visible; }
.pl-wrap { position: relative; }
.pl-list {
  /* Шире поля: адрес с районом и областью не должен ломаться на три
     строки. Вправо не уезжает — упирается в ширину окна. */
  position: absolute; left: 0; right: auto; top: 100%; z-index: 20;
  min-width: min(26rem, 78vw); max-width: 34rem;
  margin: .25rem 0 0; padding: .25rem; list-style: none;
  max-height: 19rem; overflow-y: auto; overscroll-behavior: contain;
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: 0 12px 28px rgba(0, 0, 0, .28);
}
.pl-item {
  padding: .45rem .55rem; border-radius: var(--r-sm); cursor: pointer;
  display: flex; flex-direction: column; gap: .1rem;
}
.pl-item b { font-size: .88rem; font-weight: 600; color: var(--ink); }
/* Тип места рядом с названием: село, станция, район. Без него «Надеждинский»
   в списке не отличить — посёлок это или целый район. */
.pl-item b i {
  font-style: normal; font-weight: 400; font-size: .72rem;
  color: var(--faint); margin-left: .35rem;
}
/* Район и регион — то, чем один Игрим отличается от другого: строкой ниже,
   мелким, но не настолько, чтобы их не читали. */
.pl-item span { font-size: .76rem; color: var(--dim); line-height: 1.35; }
.pl-item:hover, .pl-item.on { background: var(--accent-bg); }
.pl-empty { padding: .5rem .55rem; font-size: .82rem; color: var(--dim); }
.pl-chosen { margin: .35rem 0 0; font-size: .74rem; color: var(--faint); }
.pl-chosen.ok { color: var(--live); }

/* Галочка «акция» — под полями формы, слева от кнопки сборки. Кликается
   вся строка вместе с подписью: попадать в квадратик 14 пикселей мышью
   на ходу неудобно. */
.dm-check {
  display: inline-flex; align-items: center; gap: .55rem;
  margin-top: 1rem; cursor: pointer; user-select: none;
  font-size: .85rem; color: var(--ink);
}
.dm-check input { width: 1rem; height: 1rem; accent-color: var(--accent); margin: 0; }
/* Подписи полей в форме идут капсом и вразрядку — для строки в предложение
   это не годится, читается как крик. */
.dm-check, .dm-check span {
  text-transform: none; letter-spacing: 0; font-size: .85rem; margin-top: 0;
}
.dm-check { margin-top: 1rem; }
.dm-check:hover span { color: var(--accent); }
.dm-check input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Метка акции в списке — кнопка, а не надпись: её переставляют по клику. */
.promo-chip {
  font: inherit; font-size: .74rem; padding: .18rem .5rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--raised); color: var(--dim); cursor: pointer;
}
.promo-chip.accent { background: var(--accent-bg); color: var(--accent);
  border-color: var(--accent-dim); }
.promo-chip:hover { border-color: var(--accent-dim); }
.promo-chip:disabled { opacity: .5; cursor: progress; }

/* ── лента переписки: раздел «Люди» ────────────────────────────────────────
   Один разговор человека, даже если он шёл в трёх местах — под роликом, в
   личке и в наших письмах. Наши реплики отодвинуты вправо: так видно, кто
   говорил последним, не читая подписей (2026-08-25). */
.thread { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.tev {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .5rem .7rem; max-width: 46rem;
}
/* По содержимому, а не во всю колонку: короткое «Да» на всю ширину читается
   как длинная реплика. justify-self, потому что лента — грид. */
.tev-them { background: var(--night); justify-self: start; }
.tev-us { background: var(--accent-bg); justify-self: end; }
.tmeta {
  display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap;
  font-size: .74rem; color: var(--dim); margin-bottom: .25rem;
}
.twhere { font-weight: 700; }
.tnote { opacity: .8; }
.ttext { font-size: .88rem; white-space: pre-wrap; overflow-wrap: anywhere; }

/* Строка человека кликабельна целиком: искать глазами маленькую ссылку в
   списке на сотни строк — лишняя работа. */
.prow { cursor: pointer; }
.prow:hover td { background: var(--accent-bg); }
.prow:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .prow { transition: none; }
}

/* ─── карта разговора: вертикальная воронка (Артур 2026-08-26) ───────────
   Схема нужна, чтобы увидеть путь человека целиком — от даты под рилсом до
   оплаты — и понять, где он обрывается. Поэтому ступени идут строго сверху
   вниз одной линией, а ветки отходят вбок: ветка не должна читаться
   ступенью воронки, иначе конверсия выглядит хуже, чем есть. */
.flow { display: flex; flex-direction: column; gap: 0; margin-top: .2rem; }

.fstep { display: grid; grid-template-columns: 2.2rem 1fr; gap: 0 .9rem; }

/* Колонка с линией и точкой. Линия — псевдоэлемент, чтобы не рисовать её
   у последней ступени и не оставлять хвост в пустоту. */
.frail { position: relative; display: flex; justify-content: center; }
.frail::before {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2px;
  background: var(--line);
}
.fstep:first-child .frail::before { top: .95rem; }
.fstep:last-child .frail::before { bottom: auto; height: .95rem; }
.fdot {
  position: relative; margin-top: .55rem; width: .85rem; height: .85rem;
  border-radius: 50%; background: var(--surface);
  border: 2px solid var(--accent); flex: none;
}
/* Ветка — полая точка и пунктир: видно, что путь уходит в сторону. */
.fstep.side .fdot { border-color: var(--wait); }
.fstep.side .frail::before {
  background: repeating-linear-gradient(
    to bottom, var(--line) 0 4px, transparent 4px 8px);
}

.fbody { padding: .3rem 0 1.15rem; min-width: 0; }
.fhead { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; }
.fhead h3 { margin: 0; font-size: .97rem; font-weight: 600; line-height: 1.3; }
.fwho {
  font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--dim); border: 1px solid var(--line);
  border-radius: 999px; padding: .1rem .45rem;
}
.fwho.bot { color: var(--accent); border-color: var(--accent-dim); }
.fcount {
  margin-left: auto; font-size: .8rem; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.fcount b { color: var(--ink); font-weight: 600; font-size: .95rem; }
/* Падение к предыдущей ступени. Красным не красим: воронка сужается всегда,
   и красное на каждой ступени перестало бы что-либо значить. */
/* --dim, а не --faint: на тёмной теме бледный давал контраст 2.8 — для
   текста в 0.76rem этого мало, а падение здесь читают в первую очередь. */
.fdrop { font-size: .76rem; color: var(--dim); white-space: nowrap; }
.fdrop.bad { color: var(--alert); }

.fwhat {
  margin: .35rem 0 0; font-size: .84rem; color: var(--dim); line-height: 1.55;
}
/* Пример письма — как сообщение в мессенджере: владелец должен видеть его
   глазами человека, а не как строку данных. */
.fsample {
  margin: .6rem 0 0; padding: .6rem .75rem;
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r); border-top-left-radius: var(--r-sm);
  font-size: .84rem; line-height: 1.6; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 15rem; overflow-y: auto;
}
.fsample.them {
  background: var(--accent-bg); border-color: var(--accent-dim);
  border-top-left-radius: var(--r); border-top-right-radius: var(--r-sm);
}
.fcode {
  display: inline-block; margin-top: .5rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: .73rem; color: var(--dim);
}

@media (max-width: 700px) {
  .fstep { grid-template-columns: 1.4rem 1fr; gap: 0 .6rem; }
  .fcount { margin-left: 0; width: 100%; }
}

/* ─── аудит: бот проверяет сам себя (Артур 2026-08-26) ───────────────────
   Здесь главное — быстро понять, всё ли хорошо, и только потом читать
   детали. Поэтому здоровье воронки одним числом наверху, а находки ниже
   карточками, тяжёлые первыми. */
.ahealth {
  border-left: 3px solid var(--live); padding-left: .9rem;
}
.ahealth.warn { border-left-color: var(--wait); }
.ahealth.bad  { border-left-color: var(--alert); }
.abig { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.abig b {
  font-size: 2rem; line-height: 1; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--live);
}
.ahealth.warn .abig b { color: var(--wait); }
.ahealth.bad  .abig b { color: var(--alert); }
.abig span { font-size: .88rem; color: var(--dim); }
.ahealth .sub { margin: .35rem 0 0; }
.atags { display: flex; gap: .5rem; margin-top: .6rem; flex-wrap: wrap; }
.atag {
  font-size: .75rem; padding: .15rem .5rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--dim);
}
.atag.critical { color: var(--alert-ink); border-color: var(--alert); }
.atag.warn { color: var(--wait-ink); }

.afind {
  background: var(--raised); border: 1px solid var(--line);
  border-left: 3px solid var(--wait);
  border-radius: var(--r); padding: .8rem .95rem; margin-top: .6rem;
}
.afind.critical { border-left-color: var(--alert); }
.afind.info { border-left-color: var(--line); }
/* Починенное глушим целиком: взгляд должен отделять живое от истории до
   чтения — тот же приём, что у выключенных блоков на вкладке «Боты». */
.afind.gone { opacity: .55; border-left-color: var(--live); }
.afind header {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
}
.afind h3 {
  margin: 0; font-size: .92rem; font-weight: 600; line-height: 1.35;
  flex: 1 1 14rem; min-width: 0;
}
.alevel {
  font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--wait-ink); flex: none;
}
.afind.critical .alevel { color: var(--alert-ink); }
.awhen { font-size: .76rem; color: var(--dim); flex: none; }
.awho {
  margin: .4rem 0 0; font-size: .84rem; color: var(--dim); line-height: 1.5;
  overflow-wrap: anywhere;
}
.awho a { color: var(--accent); }
.afind footer {
  display: flex; align-items: center; gap: .6rem; margin-top: .55rem;
  flex-wrap: wrap;
}
.afind code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: .72rem; color: var(--dim);
}
.asince, .agone { margin-left: auto; font-size: .75rem; color: var(--dim); }
.agone { color: var(--live); }

.switch {
  display: flex; align-items: center; gap: .4rem;
  font-size: .82rem; color: var(--dim); cursor: pointer;
}
.switch input { accent-color: var(--accent); cursor: pointer; }

/* ─── что говорят люди: обратная связь по разборам (2026-08-27) ──────────
   Промахи первыми и красной чертой: похвалу пишут из вежливости, а «мимо»
   человек называет, только когда это правда, — и чинить надо именно это. */
.fbgroup { margin-top: .9rem; border-left: 3px solid var(--line);
           padding-left: .9rem; }
.fbgroup:first-child { margin-top: 0; }
.fbgroup.miss { border-left-color: var(--alert); }
.fbgroup.hit  { border-left-color: var(--live); }
.fbgroup.ask  { border-left-color: var(--accent); }
.fbgroup h4 {
  margin: 0 0 .35rem; font-size: .8rem; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--dim);
}
.fbgroup.miss h4 { color: var(--alert-ink); }
.fbgroup ul {
  margin: 0; padding-left: 1.05rem; display: flex; flex-direction: column;
  gap: .3rem; font-size: .88rem; line-height: 1.5;
}
.fbgroup i { color: var(--dim); font-style: normal; }
/* --dim, а не --faint: на тёмной теме бледный даёт 2.8, а строка мелкая.
   Третий раз тот же урок за два дня. */
.fbread { margin: .9rem 0 0; font-size: .78rem; color: var(--dim); }
.fbwhen { font-size: .78rem; color: var(--dim); }


/* ─── Диалоги: лента переписок ──────────────────────────────────────────────
   Строка-карточка вместо плотной таблицы: у диалога главное — с кем и на чём
   остановились, и это читается взглядом, а не по колонкам.
   Числового бейджа «непрочитано» тут нет: dm-бот такого поля не отдаёт. */

.head-ico {
  display: flex; align-items: center; justify-content: center;
  width: 2.9rem; height: 2.9rem; border-radius: var(--r-lg);
  background: var(--accent-bg); color: var(--accent);
  font-size: 1.25rem; flex: none;
}
/* Значок раздела в плитке — та же маска, что в меню. */
.head-ico::after {
  content: ""; width: 1.45rem; height: 1.45rem; background: currentColor;
  -webkit-mask: var(--ic-dialogs) center / contain no-repeat;
          mask: var(--ic-dialogs) center / contain no-repeat;
}
.head-ico.ic-instagram::after { -webkit-mask-image: var(--ic-instagram); mask-image: var(--ic-instagram); }
.head-ico.ic-today::after     { -webkit-mask-image: var(--ic-today);     mask-image: var(--ic-today); }
.head-ico.ic-threads::after   { -webkit-mask-image: var(--ic-threads);   mask-image: var(--ic-threads); }
.head-ico.ic-bots::after      { -webkit-mask-image: var(--ic-bots);      mask-image: var(--ic-bots); }
.head-ico.ic-dialogs::after   { -webkit-mask-image: var(--ic-dialogs);   mask-image: var(--ic-dialogs); }
.head-ico.ic-audit::after     { -webkit-mask-image: var(--ic-audit);     mask-image: var(--ic-audit); }
.head-ico.ic-leads::after     { -webkit-mask-image: var(--ic-leads);     mask-image: var(--ic-leads); }
.head-ico.ic-people::after    { -webkit-mask-image: var(--ic-people);    mask-image: var(--ic-people); }
.head-ico.ic-data::after      { -webkit-mask-image: var(--ic-data);      mask-image: var(--ic-data); }
.head-ico.ic-book::after      { -webkit-mask-image: var(--ic-book);      mask-image: var(--ic-book); }
.head-ico.ic-spend::after     { -webkit-mask-image: var(--ic-spend);     mask-image: var(--ic-spend); }
.head-ico.ic-publisher::after { -webkit-mask-image: var(--ic-publisher); mask-image: var(--ic-publisher); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.dlg-bar {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  margin-bottom: .9rem;
}
/* Лента и её панель — одной колонкой, уже страницы: строка диалога
   короткая, и на всю ширину монитора она разъезжается пустотой. */
.dlg-bar, #list { max-width: 62rem; }
.dlg-bar .filters { margin: 0; }
.dlg-tabs .fbtn { display: inline-flex; align-items: center; gap: .45rem; }
.dlg-tabs .fbtn .cnt {
  font-weight: 600; font-size: .72rem; padding: .05rem .4rem;
  border-radius: 999px; background: var(--raised); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.dlg-tabs .fbtn.on .cnt {
  background: color-mix(in srgb, var(--night) 22%, transparent);
  color: inherit;
}
/* Точку заменил значок папки: с ним чип читается, даже когда цвета
   неразличимы, и совпадает со значком в строке диалога. */
.dlg-tabs .dot {
  width: 1.05rem; height: 1.05rem; flex: none;
  background: currentColor;
  -webkit-mask: var(--ic-spark) center / contain no-repeat;
          mask: var(--ic-spark) center / contain no-repeat;
}
.dot.all      { -webkit-mask-image: var(--ic-spark);  mask-image: var(--ic-spark); }
.dot.razbor   { -webkit-mask-image: var(--ic-star);   mask-image: var(--ic-star); }
.dot.natal    { -webkit-mask-image: var(--ic-moon);   mask-image: var(--ic-moon); }
.dot.collab   { -webkit-mask-image: var(--ic-people); mask-image: var(--ic-people); }
.dot.negative { -webkit-mask-image: var(--ic-shield); mask-image: var(--ic-shield); }
.fbtn:not(.on) .dot.razbor   { color: var(--accent); }
.fbtn:not(.on) .dot.natal    { color: var(--live); }
.fbtn:not(.on) .dot.collab   { color: var(--wait); }
.fbtn:not(.on) .dot.negative { color: var(--alert); }

.dlg-search {
  margin-left: auto; position: relative;
  flex: 1 1 9rem; min-width: 9rem; max-width: 16rem;
}
.dlg-search::before {
  content: ""; position: absolute; left: .8rem; top: 50%;
  width: 1rem; height: 1rem; margin-top: -.5rem; pointer-events: none;
  background: var(--faint);
  -webkit-mask: var(--ic-audit) center / contain no-repeat;
          mask: var(--ic-audit) center / contain no-repeat;
}
.dlg-search input {
  width: 100%; padding: .5rem .8rem .5rem 2.1rem;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); color: var(--ink); font: inherit; font-size: .84rem;
}
.dlg-search input::placeholder { color: var(--faint); }
.dlg-search input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.dlg {
  display: flex; align-items: center; gap: .75rem;
  padding: .55rem .8rem; margin-bottom: .3rem;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); color: inherit; text-decoration: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.dlg:hover {
  border-color: var(--accent-dim); background: var(--raised);
  box-shadow: 0 2px 10px rgba(0,0,0,.05);
}
.dlg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.dlg-ico {
  width: 2rem; height: 2rem; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-dim);
}
.dlg-ico.natal    { border-color: var(--live); }
.dlg-ico.collab   { border-color: var(--wait); }
.dlg-ico.negative { border-color: var(--alert); }
.dlg-ico::after {
  content: ""; width: .95rem; height: .95rem; background: currentColor;
  -webkit-mask: var(--ic-star) center / contain no-repeat;
          mask: var(--ic-star) center / contain no-repeat;
}
.dlg-ico.natal    { background: var(--live-bg); color: var(--live); }
.dlg-ico.natal::after    { -webkit-mask-image: var(--ic-moon); mask-image: var(--ic-moon); }
.dlg-ico.collab   { background: var(--wait-bg); color: var(--wait); }
.dlg-ico.collab::after   { -webkit-mask-image: var(--ic-people); mask-image: var(--ic-people); }
.dlg-ico.negative { background: var(--alert-bg); color: var(--alert); }
.dlg-ico.negative::after { -webkit-mask-image: var(--ic-shield); mask-image: var(--ic-shield); }

.dlg-cat {
  font-family: var(--font-mono);
  font-size: .64rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); font-weight: 400; margin-right: .45rem;
}
.dlg-cat::after { content: " ·"; }

.dlg-main { min-width: 0; flex: 1; }
.dlg-who {
  display: block; font-size: .9rem; font-weight: 600; color: var(--accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dlg-who b { color: var(--ink); font-weight: 600; }
.dlg-note {
  display: block; margin-top: .05rem; font-size: .78rem; color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.dlg-when {
  font-family: var(--font-mono); font-size: .72rem; color: var(--dim);
  flex: none; font-variant-numeric: tabular-nums;
}

/* «Ждём» — единственный настоящий сигнал в строке: бот задал вопрос
   и ответа нет. Именно такие диалоги владелец ищет глазами. */
.dlg-flag {
  flex: none; font-size: .7rem; padding: .1rem .5rem; border-radius: 999px;
  background: var(--accent-bg); color: var(--accent);
}

/* Длина переписки. Не «непрочитанные»: такого счётчика у бота нет,
   а этот — реальная сумма наших писем и входящих. */
.dlg-cnt {
  flex: none; min-width: 1.4rem; height: 1.4rem;
  display: grid; place-items: center; padding: 0 .4rem;
  font-family: var(--font-mono); font-size: .72rem; font-weight: 500;
  border-radius: 999px; border: 1px solid var(--accent-dim);
  background: transparent; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.dlg-go { flex: none; color: var(--faint); font-size: 1.1rem; }

@media (max-width: 720px) {
  /* Колонка категории фиксированной ширины съедала строку — на узком
     экране её роль берёт на себя цветная иконка слева. */
  .dlg-cat { display: none; }
  .dlg-search { margin-left: 0; width: 100%; }
  .dlg-search input { width: 100%; }
}

.dlg { animation: dlg-in .32s ease both; }
.dlg:nth-child(1) { animation-delay: 0s; }
.dlg:nth-child(2) { animation-delay: .03s; }
.dlg:nth-child(3) { animation-delay: .06s; }
.dlg:nth-child(4) { animation-delay: .09s; }
.dlg:nth-child(5) { animation-delay: .12s; }
.dlg:nth-child(6) { animation-delay: .15s; }
.dlg:nth-child(7) { animation-delay: .18s; }
.dlg:nth-child(8) { animation-delay: .21s; }
.dlg:nth-child(n+9) { animation-delay: .24s; }

@keyframes dlg-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .dlg { transition: none; animation: none; }
}

/* ── письмо и скрипт голосового ────────────────────────────────────────── */

.vs-block { margin-top: 1rem; }
.vs-block:first-of-type { margin-top: .3rem; }
.vs-head { display: flex; align-items: center; gap: .8rem; margin-bottom: .45rem; }
.vs-head h3 { margin: 0; font-size: .95rem; font-weight: 600; }
.vs-head .btn { margin-left: auto; }
/* Тексты уходят человеку как есть — показываем их так же, как скопируются:
   с переносами строк, без перевёрстки. */
.vs-text {
  margin: 0; padding: .8rem .9rem; white-space: pre-wrap; overflow-wrap: anywhere;
  font: inherit; font-size: .88rem; line-height: 1.6; color: var(--ink);
  background: var(--night); border: 1px solid var(--line);
  border-radius: var(--r-sm); max-height: 22rem; overflow-y: auto;
}
.vs-text:empty::before { content: "пока пусто"; color: var(--faint); }


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

/* Числа дня встают в один ряд: их пять, и колонка по 15rem ломала
   последнюю карточку на отдельную строку. */
#kpi { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }

/* ── службы ───────────────────────────────────────────────────────── */

.svcs {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden; margin-bottom: 1.25rem;
}
.svc { background: var(--surface); padding: .75rem .9rem; display: flex; gap: .6rem; }
.svc .led {
  width: 8px; height: 8px; border-radius: 50%; margin-top: .45rem; flex: none;
  background: var(--live);
}
.svc.is-wait  .led { background: var(--wait); }
.svc.is-alert .led { background: var(--alert); }
.svc b { display: block; font-size: .85rem; font-weight: 600; }
.svc small { display: block; font-size: .78rem; color: var(--faint); }
.svc.is-alert small { color: var(--alert-ink); }

/* ── очередь решений ──────────────────────────────────────────────────
   Полоса слева — вторая примета важности рядом с цветом значка: одной
   заливкой при дальтонизме срочное от обычного не отличить. */

.todo { display: flex; flex-direction: column; }
.todo-row {
  display: flex; align-items: center; gap: .8rem;
  padding: .75rem 1.2rem .75rem .95rem;
  border-bottom: 1px solid var(--line); border-left: 3px solid transparent;
}
.todo-row:last-child { border-bottom: none; }
.todo-row.sev-high { border-left-color: var(--alert); }
.todo-row.sev-mid  { border-left-color: var(--accent); }
.todo-row.sev-low  { border-left-color: var(--line); }
.todo-ico {
  width: 2.1rem; height: 2.1rem; border-radius: var(--r-sm); flex: none;
  display: grid; place-items: center;
  background: var(--wait-bg); color: var(--dim);
}
.todo-row.sev-high .todo-ico { background: var(--alert-bg); color: var(--alert-ink); }
.todo-row.sev-mid  .todo-ico { background: var(--accent-bg); color: var(--accent); }
.todo-txt { flex: 1; min-width: 0; }
.todo-txt b { display: block; font-size: .9rem; font-weight: 600; }
.todo-txt small { color: var(--dim); font-size: .82rem; }
.todo-row .btn { flex: none; }
.todo-none { padding: 1.4rem 1.2rem; color: var(--dim); font-size: .88rem; }

/* Значок под маской: сама маска приходит из --i, поэтому на каждый новый
   пункт не нужно правило в CSS. */
.mico {
  width: 1.15rem; height: 1.15rem; background: currentColor; display: block;
  -webkit-mask: var(--i) center / contain no-repeat;
          mask: var(--i) center / contain no-repeat;
}

/* ── расписание дня ───────────────────────────────────────────────── */

.tl { display: flex; flex-direction: column; }
.tl-row {
  display: grid; grid-template-columns: 3.2rem .6rem 1fr auto;
  gap: .7rem; align-items: center;
  padding: .65rem 1.2rem; border-bottom: 1px solid var(--line);
}
.tl-row:last-child { border-bottom: none; }
.tl-time {
  font-family: var(--font-mono); font-size: .8rem; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.tl-mark {
  width: .6rem; height: .6rem; border-radius: 50%;
  border: 2px solid var(--line); background: var(--surface);
}
.tl-row.done .tl-mark { background: var(--live); border-color: var(--live); }
.tl-row.next .tl-mark { background: var(--accent); border-color: var(--accent); }
.tl-row.risk .tl-mark { background: var(--alert); border-color: var(--alert); }
.tl-txt { min-width: 0; }
.tl-txt b { display: block; font-size: .87rem; font-weight: 500; }
.tl-txt small {
  color: var(--dim); font-size: .8rem; display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-tail {
  font-family: var(--font-mono); font-size: .68rem; color: var(--faint);
  letter-spacing: .03em; white-space: nowrap;
}

/* ── лента бота ───────────────────────────────────────────────────── */

.evts { display: flex; flex-direction: column; }
.evt {
  display: flex; gap: .7rem; align-items: baseline;
  padding: .55rem 1.2rem; border-bottom: 1px solid var(--line);
}
.evt:last-child { border-bottom: none; }
.evt time {
  font-family: var(--font-mono); font-size: .72rem; color: var(--faint);
  flex: none; font-variant-numeric: tabular-nums;
}
.evt p { margin: 0; font-size: .82rem; min-width: 0; }
.evt p b { font-weight: 600; }
.evt p span {
  color: var(--dim); display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 60rem) {
  .svcs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Служб три, колонок две — последняя занимает строку целиком, иначе
     рядом с ней светится пустая ячейка. */
  .svc:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .tl-row { grid-template-columns: 3.2rem .6rem 1fr; }
  .tl-tail { display: none; }
}
