/* СВОЁ КАБИНЕТА МОДЕРАТОРА: то, чего в двух других кабинетах нет вовсе.
 *
 * Общее лежит в `ui.css` — он одинаков во всех трёх кабинетах байт в байт.
 * Сюда попадает только то, что встречается в одном кабинете: разъехавшийся
 * общий блок никто не заметит, пока сотрудник поддержки не откроет две
 * панели рядом.
 *
 * Правило простое: элемент появился во ВТОРОМ кабинете — переезжает в ядро,
 * во все три копии сразу. Порядок и проверка — docs/panels-ui.md.
 *
 * Адаптив своего кабинета — рядом со своим блоком; общие точки перелома
 * лежат в последнем разделе `ui.css` (Р-191).
 * Цвет — только из tokens.css (правило №10).
 */

/* ==================================================================== */
/* 1. Очередь                                                            */
/* ==================================================================== */

/* Задача, занятая коллегой. Приглушена, но читается: «занято» без имени
   выглядит поломкой, «занято Ирой» — рабочей ситуацией */
.taken {
  margin-top: 4px;
  color: var(--info-ink);
  font-size: 12px;
}

/* Задача с жалобой или с пометкой автопроверки: красным, но не плашкой —
   плашка в списке из ста строк превращает очередь в новогоднюю гирлянду */
.flagged { color: var(--error-ink); }

/* ОБЪЕКТЫ (Р-273): строка окна изменений и новые правки в журнале карточки.
 *
 * Обложка маленькая намеренно: список отвечает «стоит ли открыть», и узнать
 * объект по снимку быстрее, чем по названию, но разглядывать его здесь не
 * нужно — для этого есть карточка. */
.listing-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 220px;
}

.listing-cell__cover {
  flex: 0 0 auto;
  width: 48px;
  height: 36px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface3);
}

/* Правка после последней проверки: ради этих строк карточку и открыли, и
 * найти их глазами в журнале из тридцати действий надо сразу */
.row--new td {
  background: var(--accent-bg);
}

/* РЕШЕНИЕ ПО ОБЪЕКТУ — ПОЛОСОЙ СВЕРХУ (Р-274).
 *
 * Одна колонка: решение стоит над тем, что разбирают, а не липкой правой
 * колонкой, которая на телефоне уезжала под всю страницу. Внутри — строки:
 * текст забирает место, поля делят остаток, кнопки держатся рядом, и всё это
 * переносится само, как только ширины не хватает. Отдельной вёрстки под
 * телефон почти не нужно — только кнопки там растягиваются во всю ширину. */
.decision {
  padding-top: 4px;
  padding-bottom: 4px;
}

.decision__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  padding: 14px 0;
}

.decision__row + .decision__row { border-top: 1px solid var(--border); }

/* В строке формы поля выравниваются по верху — их подписи стоят в одну
 * линию, даже когда под одним полем есть подсказка, а под другим нет. Кнопка
 * при этом прижата к низу строки: вровень с полями, а не с подписями */
form.decision__row { align-items: flex-start; }
form.decision__row .decision__actions { align-self: flex-end; }

.decision__text { flex: 1 1 360px; min-width: 0; }
.decision__text--full { flex-basis: 100%; }

.decision__field { flex: 1 1 260px; min-width: 0; }
.decision__field--wide { flex: 2 1 380px; }

.decision__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.decision__note { flex: 1 1 320px; margin: 0; }

@media (max-width: 575.98px) {
  .decision__actions,
  .decision__actions .btn { width: 100%; }
}

/* Приманка для роботов (Р-277): поле уезжает за край экрана, а не прячется
 * `display:none` — скрытые отображением поля роботы пропускают давно */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ======================================================================
 * M16 — АФИША «СОБЫТИЯ» (Р-280)
 * ====================================================================== */

/* Номер строки в списке афиши (находка №169). Сквозной по всему списку, а не
   по загруженной части: в афише на месяц строк несколько сотен, и «посмотри
   двести седьмое» — единственный способ договориться о строке вслух. Колонка
   узкая и приглушённая: это ориентир, а не данные события */
.events-list .num { width: 1%; white-space: nowrap; }
.events-list td.num { color: var(--text3); }

/* Обложка события в строке списка. Без неё тридцать строк отличаются
   только названиями, а модератор ищет глазами ту самую вечеринку */
.row-photo {
  display: block;
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface3);
}

.row-photo--empty { border: 1px dashed var(--border2); }

/* Снимки события — сеткой, а не строкой: при пяти штуках строка на узком
   экране уезжала за край карточки */
.photo-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}

/* Снимок: превью, подпись обложки и кнопки под ним */
.event-photo {
  display: grid;
  gap: 6px;
  justify-items: start;
  margin: 0;
  min-width: 0;
}

.event-photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface3);
}

/* --- Дни события ------------------------------------------------------
 *
 * Строками, а не чипами. Кнопка «Отменить день» внутри бейджа выглядела
 * ошибкой вёрстки: бейдж — это метка состояния, и нажимать внутри него
 * нечего. Здесь у каждого дня своя строка: дата, состояние, действие.
 */
.daylist {
  display: grid;
  gap: 6px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.daylist__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  min-width: 0;
}

.daylist__date { font-weight: 600; font-variant-numeric: tabular-nums; }
.daylist__state { color: var(--text2); font-size: 12.5px; margin-right: auto; }

/* Отменённый день остаётся в списке (правило №6) и приглушён: он есть в
   истории афиши, и «его просто нет» было бы неправдой */
.daylist__item--off { background: transparent; border-style: dashed; }
.daylist__item--off .daylist__date { color: var(--text3); text-decoration: line-through; }

/* --- Форма ради одной кнопки -----------------------------------------
 *
 * Каждое действие над событием уходит по своему адресу, поэтому кнопку
 * приходится заворачивать в форму. И форма перекашивает ряд дважды:
 *
 * 1. `<button>` внутри блочной формы — строчный элемент: под кнопкой
 *    остаётся место под выносные элементы букв, и форма выходит выше
 *    самой кнопки. Лечится `display: flex`.
 * 2. У формы есть унаследованный `margin-bottom: 14px`. В ряду с
 *    `align-items: center` он растягивает строку флексбокса до 52 px:
 *    формы прижимаются к её верху, а соседняя ссылка-кнопка честно
 *    встаёт по центру — на семь пикселей ниже. Лечится `margin: 0`.
 *
 * Без обоих правил ряд «Снять с публикации · Перевести · Открыть в
 * сервисе · Удалить» едет по высоте.
 */
.form-btn { display: flex; margin: 0; }

/* Отмена всего — к правому краю ряда, а не вплотную к действиям:
   «Удалить» рядом с «Перевести» нажимают вместо неё */
.push { margin-left: auto; }

/* --- Языки и SEO события (Р-286) --------------------------------------
 *
 * Отвечает на вопрос «чего нет», а не «что есть». Список готовых переводов
 * на него не отвечает: язык без перевода в нём просто отсутствует, и понять
 * это можно только сверив четыре кода глазами. Поэтому строка есть у
 * КАЖДОГО языка, и у каждого словом сказано, что с текстом и что с тегами.
 */
.lang-state { width: 100%; }
.lang-state td, .lang-state th { vertical-align: middle; }

/* Свёрнутый язык. Развернут тот, на котором сомневаются: четыре текста с
   шестью тегами каждый превратили бы карточку в простыню */
.fold {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  padding: 10px 14px;
  margin-top: 8px;
}

.fold > summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

.fold > summary::-webkit-details-marker { display: none; }

/* Треугольник свой: браузерный маркер стоит вне флексбокса и ломает ряд */
.fold > summary::before {
  content: "▸";
  color: var(--text3);
  font-size: 11px;
}

.fold[open] > summary::before { content: "▾"; }

.fold__body { margin-top: 10px; }

/* Отказ генерации — строкой, а не в логах: человек, нажавший «Перевести»,
   должен видеть причину там же, где нажимал */
.lang-error { color: var(--error-ink); font-size: 12.5px; margin-top: 6px; }

/* ==================================================================== */
/* 6. Сведения в строку, чеки, люди (Р-363, Р-364)                       */
/* ==================================================================== */

/* СВЕДЕНИЯ В СТРОКУ. Карточки платежа, брони и человека собраны в один
   столбец (Р-274), и пары «название — значение» столбиком на широком экране
   давали узкую ленту слева и пустоту справа. Здесь пары встают плитками в
   ряд и сами переносятся: на мониторе — пять-шесть в строку, на телефоне —
   по одной. Подпись над значением, а не слева: так плитка не разъезжается
   на длинной почте */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 14px 24px;
  margin: 0;
}

.facts > div { min-width: 0; }
.facts--wide { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

.facts dt {
  margin: 0 0 3px;
  color: var(--text2);
  font-size: 12.5px;
  font-weight: 500;
}

.facts dd { margin: 0; overflow-wrap: anywhere; }

/* Действие с деньгами — строкой над пояснением: поля в строку и с переносом
   (Р-345), кнопка в конце */
.money-action {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 16px;
}

.money-action .field { flex: 1 1 240px; min-width: 0; margin: 0; }
.money-action__buttons { display: flex; flex-wrap: wrap; gap: 8px; }

/* Поиск людей: строка поиска и вкладки видов одной полосой */
.people-search {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.people-search .field { flex: 1 1 320px; min-width: 0; margin: 0; }

/* Человек в списке: имя и почта столбиком, чтобы длинная почта не рвала
   таблицу, но читалась целиком */
.person-cell { display: flex; flex-direction: column; min-width: 0; }
.person-cell__name { font-weight: 600; }
.person-cell__sub { color: var(--text2); font-size: 12.5px; overflow-wrap: anywhere; }

/* Ограничения человека: история строками с действием справа */
.restriction-list { display: flex; flex-direction: column; gap: 10px; margin: 0 0 14px; }

.restriction-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.restriction-item__body { flex: 1 1 320px; min-width: 0; }

/* Пустой список внутри карточки человека: не на полэкрана, как пустой
   раздел, а строкой — у карточки таких блоков пять */
.card--flush > .empty--small { padding: 14px 20px 18px; text-align: left; }
.card--flush > .card__hint:last-child { padding-bottom: 16px; }

/* Вариант выбора внутри поля — обычный текст, а не подпись поля: правило
   ядра `.field > label` красило радиокнопки «вернуть всё / часть» капсом
   мелкого заголовка, и выбор читался как ещё одна подпись */
.field > label.check {
  color: var(--text);
  font-size: 13.5px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

/* ФИНАНСЫ (M24, M24а, Р-406). Только токены темы: своих цветов у раздела нет
   (docs/themes.md, docs/design.md). */

/* Строка сходимости: расхождение в деньгах обязано быть заметно с порога,
   а не найтись при сверке с бухгалтерией. В ядре этого кабинета её не было —
   раздел приехал из админ-панели */
.result-line--warn {
  color: var(--error-ink);
  font-weight: 600;
}

/* Быстрые периоды — над карточками, с отступом от фильтра */
.finance-presets { margin: 0 0 12px; }

/* Поиск партнёра и валюта — одной строкой над таблицей, внутри карточки */
.finance-partners-bar { margin: 0 20px 12px; }

/* Полоса месяца: одна серия, один цвет. Значение — текстом рядом, цветом
   текста, а не цветом полосы; масштаб — самый большой месяц своей валюты.
   Тонкая полоса с закруглённым концом данных, начало — у базовой линии */
.finance-bar-col { min-width: 220px; width: 40%; }

.finance-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.finance-bar__track { flex: 1 1 auto; min-width: 80px; }

.finance-bar__fill {
  display: block;
  height: 8px;
  border-radius: 0 4px 4px 0;
  background: var(--brand);
}

.finance-bar__value {
  flex: 0 0 auto;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media print {
  .finance-presets,
  .finance-partners-bar { display: none; }
  .finance-bar__fill { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* СТРОКА РАЗДЕЛОВ НА ДЕСКТОПЕ (Р-406). С «Финансами» разделов четырнадцать,
   и при полях по 14 px строка становилась шире рабочей колонки (1272 px):
   «Брони» уезжали за край, а с ними и вся страница — вбок. Поля сужены до
   10 px — так строка целиком помещается от ширины колонки (1320 px). На
   промежуточных ширинах (992–1319 px) строка прокручивается внутри себя,
   страница при этом не едет никогда (docs/panels-ui.md §4). Групп-выпадашек
   у модератора нет, поэтому прокрутка ничего не обрезает */
@media (min-width: 992px) {
  .topnav__inner {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
  }
  .topnav__item {
    flex: 0 0 auto;
    padding: 0 10px;
  }
}

/* --- Пуш-уведомления в настройках (Р-424) --------------------------- */

.push-switch { margin: 4px 0 12px; }

/* «На этом устройстве»: состояние словами и одна кнопка. Блок рисует
   `push.js` ядра; браузер пушей не умеет или они не настроены — блока нет */
.push-device {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding: 12px;
  margin-bottom: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.push-device__text { min-width: 0; }
.push-device__title { font-weight: 600; }
.push-device[data-state="on"] { border-color: var(--success); }
.push-device[data-state="denied"] { border-color: var(--warning-ink); }

/* Сегменты-радио: тот же вид, что у вкладок `.seg`, выбранное — подложкой
   (как в кабинете партнёра) */
.seg--radio .seg__item { position: relative; cursor: pointer; }
.seg--radio .seg__item input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.seg--radio .seg__item:has(input:checked) {
  background: var(--brand-bg);
  color: var(--brand-ink);
  box-shadow: var(--shadow-sm);
}
.seg--radio .seg__item:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 1px; }

/* Ошибка под полем формы — тот же цвет, что у плашки ошибки (M25, Р-425) */
.field__hint--error { color: var(--error-ink); }
