/* Контент пульт — рабочее место редактора.

   Это не витрина, а пульт: один человек идёт по плану из 164 карточек
   каждый день. Поэтому место на экране отдано работе, а не заголовкам, и
   цветом здесь говорят только те вещи, которые требуют решения.

   Правило статусов: «Опубликовано» встречается 30 раз на экран, поэтому
   оно не имеет права быть ярким — иначе список превращается в мозаику,
   в которой не видно единственной сломанной карточки. Заливку получает
   только то, что требует вмешательства (ошибка, сверка, частичная
   отправка); остальное — цветной корешок слева и приглушённый текст. */

:root {
  color-scheme: light;
  --ink: #17231f;
  --muted: #69746f;
  --faint: #8d968f;
  --paper: #f2f0e9;
  --card: #fffdf8;
  --line: #e2dfd5;
  --line-soft: #ece9e0;
  --sunk: #f7f5ee;
  --green: #1f6550;
  --green-dark: #144838;
  --green-soft: #e8efe9;
  --accent: #e7a33e;
  --accent-ink: #7c4a0a;
  --accent-soft: #fbf1de;
  --danger: #ad3c32;
  --danger-ink: #6d2019;
  --danger-soft: #f7e2df;

  --radius-lg: 16px;
  --radius: 11px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(23,35,31,.04), 0 12px 28px rgba(23,35,31,.05);
  --shadow-sm: 0 1px 2px rgba(23,35,31,.05);

  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-feature-settings: "cv05" 1, "ss01" 1;
}

* { box-sizing: border-box; }
body { margin: 0; color: var(--ink); background: var(--paper); min-height: 100vh; -webkit-font-smoothing: antialiased; }
a { color: inherit; }
.is-hidden { display: none !important; }
:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* ---------- Шапка ---------------------------------------------------- */
.portal-header {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; gap: 20px;
  padding: 0 clamp(16px, 3vw, 32px);
  min-height: 56px;
  background: rgba(255,253,248,.92);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(12px);
}
.brand { display: flex; align-items: center; gap: 9px; text-decoration: none; font-weight: 750; font-size: .95rem; letter-spacing: -.01em; white-space: nowrap; }
.brand span { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; color: white; background: var(--green); font-size: .72rem; font-weight: 800; letter-spacing: .02em; }
.tenant-meta { display: flex; align-items: baseline; gap: 8px; margin-right: auto; padding-left: 20px; border-left: 1px solid var(--line); min-width: 0; }
.tenant-meta strong { font-size: .92rem; font-weight: 650; white-space: nowrap; }
.tenant-meta small { color: var(--faint); font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Навигация — вкладки: где я нахожусь, видно без заголовка страницы. */
nav { display: flex; align-items: stretch; gap: 2px; }
nav a, .link-button { border: 0; background: none; color: var(--muted); font: inherit; font-size: .88rem; text-decoration: none; cursor: pointer; }
nav a { display: inline-flex; align-items: center; padding: 0 11px; height: 55px; border-bottom: 2px solid transparent; white-space: nowrap; }
nav a:hover { color: var(--ink); background: var(--sunk); }
nav a.is-current { color: var(--ink); font-weight: 650; border-bottom-color: var(--green); }
nav .link-button { padding: 0 11px; }
nav .link-button:hover, .link-button:hover { color: var(--green); }

.shell { width: min(1320px, 94vw); margin: 24px auto 64px; }
.auth-shell { width: min(440px, 100%); margin: 9vh auto; }

/* ---------- Общие поверхности ---------------------------------------- */
.card, .loading-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-sm); }
.card + .card { margin-top: 14px; }
.card h2, .card h3 { font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; }
.eyebrow { margin: 0 0 6px; color: var(--faint); font-size: .7rem; font-weight: 750; letter-spacing: .14em; text-transform: uppercase; }
h1, h2, h3 { margin: 0 0 10px; line-height: 1.2; letter-spacing: -.02em; }
h1 { font-size: clamp(1.5rem, 2.4vw, 1.9rem); font-weight: 780; }
p { color: var(--muted); line-height: 1.55; }

form { display: grid; gap: 14px; }
label { display: grid; gap: 6px; font-size: .82rem; font-weight: 650; color: var(--ink); }
/* font-weight is reset explicitly: `font: inherit` otherwise pulls the
   650 weight off the wrapping <label>, which is barely visible in a
   one-line setting but makes a full publication text render bold. */
input, textarea, select {
  width: 100%; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 9px 12px; background: white; color: var(--ink);
  font: inherit; font-size: .92rem; font-weight: 400;
  transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { min-height: 110px; resize: vertical; line-height: 1.6; }
/* Браузер задаёт fieldset `min-inline-size: min-content`, и обычная
   ширина этого не отменяет. Из-за этого блок «Материал» не сжимался до
   своей колонки и вылезал за край карточки, обрезая кнопку. Сброс
   общий: любой fieldset в сетке ведёт себя так же. */
fieldset { min-inline-size: 0; }
input:focus, textarea:focus, select:focus { outline: 0; border-color: var(--green); box-shadow: 0 0 0 3px rgba(31,101,80,.13); }
input::placeholder, textarea::placeholder { color: #b3b8b3; }

.button-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
button, .button {
  border: 0; border-radius: var(--radius); padding: 9px 16px;
  background: var(--green); color: white; font: inherit; font-size: .88rem; font-weight: 650;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background .12s ease;
}
button:hover, .button:hover { background: var(--green-dark); }
button.secondary, .button.secondary { color: var(--ink); background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
button.secondary:hover, .button.secondary:hover { background: var(--sunk); }
button.danger { background: var(--danger); }
button:disabled { opacity: .5; cursor: not-allowed; }

.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; align-items: start; }
.page-head { display: flex; justify-content: space-between; gap: 20px; align-items: baseline; margin-bottom: 16px; }
.page-head h1 { font-size: clamp(1.4rem, 2.2vw, 1.75rem); margin: 0; }
.page-head p { margin: 4px 0 0; font-size: .88rem; }
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 18px 0; }
.step { height: 5px; border-radius: 99px; background: #dcd9cf; }
.step.done { background: var(--green); }
/* Плашка статуса на этой странице держит не статус, а название
   сообщества («HOME OFFICE Набережные Челны»), а .status выше по файлу
   стоит на nowrap — из-за этого карточка площадки не сжималась до своей
   трети сетки и её содержимое выходило за рамку. Здесь имя переносится. */
.integration { display: grid; gap: 12px; min-height: 210px; }
.integration > * { min-width: 0; }
.integration .status { white-space: normal; }
/* Крупное число подстраивается под ширину: «58 800,00 ₽» в админке при
   фиксированных 2rem не влезало в колонку карточки на телефоне и
   вытягивало всю страницу в горизонтальный скролл. */
.metric { font-size: clamp(1.5rem, 4.6vw, 2rem); font-weight: 800; letter-spacing: -.03em; overflow-wrap: anywhere; }
.check-row { display: flex; align-items: flex-start; gap: 10px; font-size: .9rem; font-weight: 500; }
.check-row input { width: auto; margin-top: 3px; }
.publication-preview { white-space: pre-wrap; padding: 16px; border-left: 3px solid var(--accent); background: var(--sunk); border-radius: var(--radius-sm); font-size: .92rem; line-height: 1.6; }
/* minmax(0, 1fr), а не 1fr: у первой колонки внутри длинный ответ
   площадки, и на 1fr она не сжималась — две кнопки решения уезжали за
   край карточки. */
.reconciliation-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; border-top: 1px solid var(--line-soft); padding: 16px 0; }
/* Ответ площадки здесь такой же, как в карточке (дамп параметров API без
   пробелов), и ломать его нужно по тем же правилам — иначе одна длинная
   строка вылезает за край карточки. */
.reconciliation-item p { overflow-wrap: anywhere; }
.muted { color: var(--muted); }
.error { color: var(--danger); font-weight: 650; }
.toast { position: fixed; right: 20px; bottom: 20px; max-width: 420px; padding: 12px 16px; border-radius: var(--radius); color: white; background: var(--ink); font-size: .88rem; box-shadow: 0 12px 30px rgba(23,35,31,.25); opacity: 0; transform: translateY(8px); pointer-events: none; transition: .18s ease; }
.toast.show { opacity: 1; transform: translateY(0); }

/* ---------- Статусы --------------------------------------------------- */
/* Ровно один визуальный вес на состояние: спокойное — текстом, требующее
   решения — заливкой. */
.status { display: inline-flex; align-items: center; width: fit-content; gap: 6px; padding: 3px 8px; border-radius: 7px; background: transparent; color: var(--muted); font-size: .76rem; font-weight: 650; white-space: nowrap; }
.status::before { content: ""; width: 5px; height: 5px; border-radius: 99px; background: currentColor; opacity: .9; }
.status--ok { color: var(--green-dark); background: var(--green-soft); }
.status--warn { color: var(--accent-ink); background: var(--accent-soft); }
.status--error { color: var(--danger-ink); background: var(--danger-soft); }
.status--muted, .status--neutral { color: var(--muted); background: #eceae2; }
.status.warning { color: var(--accent-ink); background: var(--accent-soft); }

/* ---------- Строка состояния (вместо баннера во всю ширину) ----------- */
.notice { margin: 0 0 14px; padding: 10px 14px; border-radius: var(--radius); border-left: 3px solid var(--green); background: var(--green-soft); color: var(--ink); font-size: .85rem; line-height: 1.5; }
.notice--warn { border-left-color: var(--accent); background: var(--accent-soft); }
/* Текст отказа приходит от площадки и бывает длинным и без пробелов —
   ответ VK на HO-2026-035 был дампом параметров API. Даём переносить по
   любому месту, иначе блок растянет карточку вширь. */
.publish-failures { margin-top: 14px; }
.publish-failures strong { display: block; margin-bottom: 6px; }
.publish-failures p { margin: 0 0 6px; overflow-wrap: anywhere; }
.publish-failures p:last-child { margin-bottom: 0; }
.empty { margin: 0; padding: 22px 0; text-align: center; color: var(--muted); font-size: .9rem; }
.stack { display: grid; gap: 14px; }
.filter-row { display: flex; gap: 12px; align-items: end; flex-wrap: wrap; margin-bottom: 18px; }
.filter-row label { flex: 1 1 200px; }

/* ---------- Верстак: план слева, карточка справа --------------------- */
.workbench { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 14px; align-items: start; }
.workbench__list { position: sticky; top: 70px; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
/* clip, а не hidden: hidden сделал бы редактор скролл-контейнером, и
   липкая панель действий прилипала бы к его дну — то есть не была бы
   видна вовсе. clip обрезает так же, но контекст прокрутки не создаёт. */
.workbench__editor { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow); overflow: clip; }

.list-filters { display: grid; gap: 8px; padding: 10px; border-bottom: 1px solid var(--line-soft); background: var(--sunk); }
.list-filters input, .list-filters select { padding: 7px 10px; border-radius: var(--radius-sm); font-size: .85rem; background: white; }

.pub-rows { max-height: min(56vh, 620px); overflow-y: auto; overscroll-behavior: contain; }
/* Сетка, а не поток: тема слева, дата справа на своей колонке, поэтому
   строки не пляшут, даже когда у части карточек расписания нет. */
.pub-row {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) auto; align-items: start;
  gap: 0 10px; width: 100%; text-align: left;
  padding: 9px 12px 9px 0; border: 0; border-bottom: 1px solid var(--line-soft);
  border-radius: 0; background: none; color: var(--ink); font: inherit; cursor: pointer;
  transition: background .1s ease;
}
.pub-row::before { content: ""; grid-row: 1 / span 2; align-self: stretch; width: 3px; border-radius: 0 3px 3px 0; background: transparent; }
.pub-row:hover { background: var(--sunk); }
.pub-row.is-active { background: var(--green-soft); }
.pub-row.is-active::before { background: var(--green); }
/* white-space сбрасывается явно: строка списка — это <button>, а кнопки
   выше по файлу держат nowrap, из-за чего тема уезжала поверх даты.
   Две строки максимум, дальше многоточие: иначе одна длинная тема
   растягивает строку вдвое и ритм списка ломается. */
.pub-row__topic {
  grid-column: 2; grid-row: 1;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  white-space: normal; font-size: .88rem; font-weight: 600; line-height: 1.35; letter-spacing: -.01em;
}
.pub-row__meta { grid-column: 2; grid-row: 2; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; color: var(--faint); font-size: .76rem; font-weight: 500; }
.pub-row__meta .status { padding: 0; background: none; font-size: .76rem; font-weight: 600; }
.pub-row__meta .status--warn { color: var(--accent-ink); }
.pub-row__meta .status--error { color: var(--danger-ink); }
.pub-row time { grid-column: 3; grid-row: 1; color: var(--faint); font-size: .76rem; font-variant-numeric: tabular-nums; white-space: nowrap; padding-top: 1px; }
.list-create { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 10px; border-top: 1px solid var(--line-soft); background: var(--sunk); }
.list-create input { font-size: .85rem; padding: 7px 10px; }

/* ---------- Карточка -------------------------------------------------- */
/* Липкая шапка карточки: тема, состояние и решения по ней остаются на
   месте, пока читаешь текст длиной в два экрана. */
.editor-head {
  position: sticky; top: 56px; z-index: 3;
  display: flex; justify-content: space-between; align-items: start; gap: 16px;
  padding: 14px 22px; border-bottom: 1px solid var(--line);
  background: rgba(255,253,248,.95); backdrop-filter: blur(8px);
}
.editor-head__title { min-width: 0; }
.editor-head h2 { margin: 0 0 3px; font-size: 1.18rem; font-weight: 720; letter-spacing: -.02em; line-height: 1.25; }
.editor-head p { margin: 0; color: var(--faint); font-size: .8rem; font-variant-numeric: tabular-nums; }
.editor-head__actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
.editor-hints { display: grid; gap: 6px; padding: 0 22px 18px; }
.editor-hints:empty { display: none; }
.editor-hints .notice { margin: 0; padding: 8px 12px; font-size: .8rem; }

#editorForm { gap: 0; padding: 0; }

/* Ярус 1 — текст: единственное, ради чего эту страницу открывают. */
.channel-tabs { display: flex; gap: 2px; padding: 10px 22px 0; border-bottom: 1px solid var(--line-soft); background: var(--sunk); }
.channel-tab { display: flex; align-items: center; gap: 6px; padding: 8px 13px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: none; color: var(--muted); font-size: .85rem; font-weight: 600; }
.channel-tab:hover { background: rgba(255,255,255,.7); color: var(--ink); }
.channel-tab.is-active { color: var(--ink); background: var(--card); box-shadow: inset 0 -2px 0 var(--green); }
.channel-tab__mark { font-size: .74rem; color: var(--faint); }
.channel-tab.is-active .channel-tab__mark { color: var(--green); }
.channel-body { display: grid; gap: 6px; padding: 16px 22px 0; }
.channel-body textarea { min-height: 260px; border-color: transparent; background: var(--sunk); font-size: .92rem; }
.channel-body textarea:focus { background: white; }
.channel-body__hint { order: 2; color: var(--faint); font-size: .78rem; font-weight: 500; }
.channel-body__hint--warn { color: var(--accent-ink); }

/* Ярус 2 — параметры: нужны реже текста, поэтому в две тихие колонки. */
.editor-note { display: grid; gap: 6px; font-size: .82rem; font-weight: 650; }
/* Расписание и заметка — одна колонка, материал — вторая: у материала
   вдвое больше содержимого, и без этой группировки под расписанием
   оставалась дыра в пол-экрана. */
/* minmax(min(100%, 320px), 1fr), а не minmax(320px, 1fr): вторая форма
   переполняет контейнер, как только он сам уже 320px (узкое окно,
   зум 150%). min-width: 0 на элементах — вторая половина того же
   правила: по умолчанию элемент сетки не сжимается уже своего
   min-content и вылезает за колонку. */
.editor-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 14px; padding: 18px 22px; align-items: start; }
.editor-grid > * { min-width: 0; }
.editor-col { display: grid; gap: 14px; align-content: start; min-width: 0; }
.editor-col > * { min-width: 0; }
.media-box { margin: 0; border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 16px 18px; display: grid; gap: 12px; background: var(--sunk); }
/* Тот же сброс внутри блока. Строка списка файлов — флексбокс из
   подписей в одну строку; без min-width: 0 её минимальная ширина
   поднималась до 515px и задирала весь блок обратно за колонку.
   Многоточие в подписи от этого не спасает: оно ограничивает
   отрисовку, а не минимальный размер. */
.media-box > *, .media-files > li { min-width: 0; }
.media-box legend { padding: 0; margin-bottom: 2px; color: var(--faint); font-size: .7rem; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; }
.media-state { margin: 0; color: var(--muted); font-size: .8rem; line-height: 1.45; overflow-wrap: anywhere; }
.media-state--ok { color: var(--green-dark); }
.media-state--warn { color: var(--accent-ink); }
/* Итог блока — это вывод, а не ещё одна строка подписи: отделяем
   его чертой, чтобы «что уйдёт в пост» читалось само по себе. */
.media-box .media-state:last-child { padding-top: 10px; border-top: 1px solid var(--line-soft); }
.schedule-fields { display: flex; gap: 10px; flex-wrap: wrap; }
.schedule-fields label { flex: 1 1 130px; min-width: 0; }
/* min-width: 0 — у поля даты своя внутренняя минимальная ширина (154px в
   Chrome), и в узкой колонке оно вылезало из своей подписи. */
.schedule-fields input { min-width: 0; background: white; font-variant-numeric: tabular-nums; }

/* Нативный <input type="file"> здесь не жилец: он приносит английскую
   надпись браузера в русский интерфейс и не сжимается уже ~350px, чем и
   ломал колонку. Поле остаётся в разметке (клик по зоне открывает
   диалог, клавиатура и скринридер работают как раньше), но показываем
   свою зону — в неё же можно перетащить файлы. */
.media-upload { display: grid; gap: 10px; }
.media-drop {
  position: relative; display: grid; gap: 3px; justify-items: center;
  padding: 16px 14px; border: 1px dashed #d5d1c4; border-radius: var(--radius);
  background: white; text-align: center; cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.media-drop input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; opacity: 0; cursor: pointer; }
.media-drop:hover, .media-drop.is-over { border-color: var(--green); background: var(--green-soft); }
.media-drop:focus-within { border-color: var(--green); box-shadow: 0 0 0 3px rgba(31,101,80,.13); }
.media-drop__text { color: var(--ink); font-size: .84rem; font-weight: 600; }
.media-drop__text b { color: var(--green); font-weight: 650; }
.media-drop__hint { color: var(--faint); font-size: .75rem; font-weight: 500; line-height: 1.4; }
/* Строка подтверждения появляется, только когда файлы выбраны: до
   этого момента кнопка «Загрузить» — мёртвый элемент, который
   занимает место и ничего не сообщает. */
.media-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 9px 12px; border-radius: var(--radius); background: var(--green-soft); }
.media-pick__text { flex: 1 1 150px; min-width: 0; color: var(--green-dark); font-size: .81rem; font-weight: 600; overflow-wrap: anywhere; }
.media-pick button { padding: 7px 13px; font-size: .82rem; }
.media-pick .link-button { padding: 0; color: var(--muted); font-size: .8rem; }

.media-files { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
/* Строка переносится, а не сжимается: на узкой колонке кнопки уходят на
   вторую строку, и «Фото · JPG · 2,1 МБ» остаётся читаемым — обратный
   порядок (сжать подпись, сохранить кнопки) давал «Ф…» и «Ви…». */
.media-files li { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; padding: 8px 10px; border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: white; font-size: .82rem; }
.media-files__name { flex: 0 0 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.media-files__meta { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--faint); font-variant-numeric: tabular-nums; }
/* Публикатор берёт ровно один файл — первый. Пометка ставит это на сам
   файл, а не только в текст под списком. */
.media-files__mark { flex: none; padding: 2px 7px; border-radius: 6px; background: var(--green-soft); color: var(--green-dark); font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.media-files a { flex: none; color: var(--green); font-weight: 600; text-decoration: none; }
.media-files a:hover { text-decoration: underline; }
.media-files__remove { flex: none; color: var(--faint); font-size: .8rem; }
.media-files__remove:hover { color: var(--danger); }
/* Ссылка на материал бывает длиной в экран (VK CDN): пусть ломается
   внутри поля, а не растягивает колонку. */
.media-box textarea { min-height: 62px; font-size: .8rem; line-height: 1.45; word-break: break-all; background: white; }

.editor-foot { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; padding: 16px 22px 20px; border-top: 1px solid var(--line-soft); background: var(--sunk); align-items: start; }
.editor-foot .card { padding: 16px 18px; box-shadow: none; }
.editor-foot h3 { margin: 0 0 12px; color: var(--faint); font-size: .7rem; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; }

/* ---------- Показатели ------------------------------------------------ */
.metric-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 12px 16px; }
.metric-row--wide { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
.metric-cell { display: grid; gap: 1px; align-content: start; }
.metric-cell__value { font-size: 1.45rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.03em; line-height: 1.15; }
.metric-cell__label { color: var(--faint); font-size: .76rem; }
.links { display: flex; gap: 10px; flex-wrap: wrap; margin: 14px 0 0; font-size: .82rem; }
.links a { color: var(--green); font-weight: 600; }

/* ---------- История --------------------------------------------------- */
.history { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; max-height: 300px; overflow-y: auto; color: var(--muted); font-size: .82rem; line-height: 1.45; }
.history li { padding-left: 12px; border-left: 2px solid var(--line); }
.history time { color: var(--faint); font-variant-numeric: tabular-nums; }
.history strong { color: var(--ink); font-weight: 650; }
.history-note { margin: 12px 0 0; color: var(--faint); font-size: .78rem; }
.history-toggle { margin-top: 10px; color: var(--green); font-size: .8rem; font-weight: 650; }

/* ---------- Таблицы и аналитика --------------------------------------- */
.table-scroll { overflow-x: auto; margin: 0 -6px; padding: 0 6px; }
.pub-table { width: 100%; border-collapse: collapse; font-size: .88rem; }
.pub-table th { padding: 9px 12px; text-align: left; color: var(--faint); font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; border-bottom: 1px solid var(--line); white-space: nowrap; }
.pub-table td { padding: 11px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.pub-table tbody tr[data-open] { cursor: pointer; }
.pub-table tbody tr[data-open]:hover { background: var(--sunk); }
.cell-id { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--faint); }
.cell-topic strong { display: block; }
.cell-topic small { color: var(--muted); }
.cell-schedule { white-space: nowrap; color: var(--muted); }
.cell-metric { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pager { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 9px 12px; border-top: 1px solid var(--line-soft); color: var(--faint); font-size: .78rem; font-variant-numeric: tabular-nums; }
.pager button { padding: 4px 10px; font-size: .85rem; }
.funnel-step + .funnel-step { margin-top: 14px; }
.funnel-step__head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 5px; font-size: .85rem; font-variant-numeric: tabular-nums; }
.funnel-track { height: 8px; border-radius: 99px; background: #e6e3da; overflow: hidden; }
.funnel-bar { height: 100%; border-radius: 99px; background: var(--green); }

/* ---------- Поддержка и админка -------------------------------------- */
.admin-metrics { margin-bottom: 14px; }
.admin-metrics .card { min-height: 118px; }
.admin-metrics p { margin: 4px 0 0; }
.support-workbench { display: grid; grid-template-columns: minmax(260px, 360px) minmax(0, 1fr); gap: 14px; margin-top: 14px; align-items: start; }
.support-inbox { display: grid; gap: 7px; }
/* white-space сбрасывается явно — та же ловушка, что у строки списка
   публикаций: строка обращения это <button>, а кнопки выше по файлу
   держат nowrap. Название проекта в одну строку задавало колонке
   минимальную ширину и распирало карточку входящих на 65px. */
.support-thread { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; padding: 11px 12px; text-align: left; white-space: normal; color: var(--ink); background: var(--sunk); }
.support-thread > * { min-width: 0; }
.support-thread:hover, .support-thread.is-active { background: var(--green-soft); }
.support-thread span { color: var(--muted); font-size: .75rem; }
.support-thread small { grid-column: 1 / -1; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-card { display: grid; gap: 16px; }
.chat-head { display: flex; justify-content: space-between; gap: 16px; align-items: start; }
.chat-head select { width: auto; min-width: 130px; }
.chat-messages { display: grid; gap: 9px; max-height: 55vh; min-height: 180px; overflow-y: auto; padding: 4px; }
.chat-message { justify-self: start; max-width: min(78%, 680px); padding: 10px 13px; border-radius: 4px 13px 13px 13px; background: var(--sunk); line-height: 1.5; overflow-wrap: anywhere; }
.chat-message--admin { justify-self: end; border-radius: 13px 4px 13px 13px; background: var(--green-soft); }
.chat-message small { display: block; margin-bottom: 4px; color: var(--faint); font-size: .7rem; }
.chat-compose { grid-template-columns: 1fr auto; align-items: end; border-top: 1px solid var(--line-soft); padding-top: 14px; }
.chat-compose textarea { min-height: 72px; }
.inline-form { display: grid; grid-template-columns: minmax(95px, 1fr) minmax(100px, 1fr) auto; gap: 6px; }
.inline-form input, .inline-form button { padding: 7px 8px; font-size: .8rem; }

@media (max-width: 1080px) {
  .tenant-meta { display: none; }
  nav { margin-left: auto; overflow-x: auto; }
}

@media (max-width: 860px) {
  .portal-header { align-items: stretch; flex-wrap: wrap; padding-top: 8px; min-height: 0; }
  .brand { padding-bottom: 8px; }
  nav { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  nav a { height: 42px; }
  /* minmax(0, 1fr), а не 1fr: одна колонка на телефоне всё равно не
     сжимается уже своего содержимого, и таблица с nowrap-заголовками
     растягивала страницу за край экрана. */
  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .page-head { display: block; }
  .shell { width: 94vw; margin-top: 16px; }
  .metric-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filter-row { display: grid; }
  /* Одна колонка на телефоне: список перестаёт быть липким и просто
     стоит над карточкой, чтобы не было скролла внутри скролла. */
  .workbench { grid-template-columns: minmax(0, 1fr); }
  .support-workbench { grid-template-columns: minmax(0, 1fr); }
  .chat-compose { grid-template-columns: minmax(0, 1fr); }
  /* Решение по сверке — под текстом отказа, а не рядом: две кнопки
     рядом с ним не помещаются ни в один телефон. */
  .reconciliation-item { grid-template-columns: minmax(0, 1fr); }
  .workbench__list { position: static; }
  .pub-rows { max-height: 40vh; }
  .editor-head, .channel-body, .editor-note, .editor-grid, .editor-hints, .editor-foot { padding-left: 14px; padding-right: 14px; }
  .editor-head { position: static; }
  .editor-head__actions { justify-content: flex-start; }
  .channel-tabs { padding-left: 14px; padding-right: 14px; overflow-x: auto; }
  .channel-body textarea { min-height: 200px; }
}

@media (max-width: 560px) {
  /* На узком экране заголовок карточки должен занимать всю
     ширину. Иначе кнопки сжимают тему до одного-двух слов в строке. */
  .editor-head { display: block; }
  .editor-head__actions { margin-top: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
