/* ====================================================================
 * BOUNTY · КОНСОЛЬ КАБИНЕТОВ — общее ядро оформления (Р-189, Р-190)
 * ====================================================================
 *
 * Один и тот же файл в трёх кабинетах: админ, модератор, партнёр. Байт в
 * байт — расхождение никто не заметит, пока сотрудник поддержки не откроет
 * две панели рядом. Своё кабинета живёт в `own.css`.
 *
 * АДАПТИВНО НА БРЕЙКПОИНТАХ BOOTSTRAP (Р-191). Рабочая колонка — до 1320 px
 * на мониторе, дальше по ширине окна. Ломается там же, где ломаются утилиты
 * Bootstrap: 576 / 768 / 992 / 1200. Свои точки перелома означали бы, что
 * `col-md-6` в разметке и наша сетка расходятся на 20 пикселей, и объяснить
 * это на экране нечем.
 *
 * ВСЕ МЕДИАЗАПРОСЫ ЯДРА СОБРАНЫ В ПОСЛЕДНЕМ РАЗДЕЛЕ. Разложенные по своим
 * компонентам, они читаются как двадцать несвязанных решений; собранные
 * вместе — как один ответ на вопрос «что происходит с экраном, когда он
 * сужается».
 *
 * ПОРЯДОК СЛОЁВ: bootstrap.min.css → tokens.css → ui.css → own.css.
 * Bootstrap даёт reboot, сетку, утилиты и поведение выпадашек; цвет он берёт
 * наш — все `--bs-*` переопределены в tokens.css.
 *
 * ЦВЕТ — ТОЛЬКО ИЗ ТОКЕНОВ (правило №10). Ни одного литерала, кроме белого
 * поверх фирменного градиента: он одинаков в обеих темах по построению.
 */

/* ==================================================================== */
/* 0. Мост к Bootstrap 5.3.3 (Р-190)                                     */
/* ==================================================================== */

/* Bootstrap лежит локально (правило №15) и даёт reboot, сетку, утилиты и
 * готовое поведение окон. Цвет он берёт НАШ: все `--bs-*` переопределены
 * токенами, поэтому «синий Bootstrap» в кабинете не появляется нигде — ни в
 * фокусе поля, ни в ссылке, ни в кнопке.
 *
 * Мост живёт здесь, а не в `tokens.css`: тот — один файл в пяти копиях, и
 * веб-клиент с симбанком Bootstrap не подключают вовсе.
 *
 * Тёмная тема Bootstrap включается атрибутом `data-bs-theme`; его ставит
 * `theme.js` вместе с нашим `data-theme`, одной строкой, — чтобы источник
 * правды остался один и разойтись они не могли.
 */
:root {
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--text);
  --bs-body-font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --bs-body-font-size: 14px;
  --bs-body-line-height: 1.5;
  --bs-emphasis-color: var(--text);
  --bs-secondary-color: var(--text2);
  --bs-tertiary-color: var(--text3);
  --bs-secondary-bg: var(--surface);
  --bs-tertiary-bg: var(--surface3);
  --bs-border-color: var(--border);
  --bs-border-radius: var(--radius);
  --bs-border-radius-sm: var(--radius-sm);
  --bs-link-color: var(--brand-ink);
  --bs-link-hover-color: var(--brand);
  --bs-link-color-rgb: 184, 67, 31;
  --bs-primary: var(--brand);
  --bs-primary-rgb: 226, 88, 47;
  --bs-focus-ring-color: rgba(226, 88, 47, 0.28);
  --bs-focus-ring-width: 3px;
  --bs-heading-color: var(--text);
  --bs-code-color: var(--brand-ink);
}

/* ==================================================================== */
/* 0б. Нейтрализация имён, занятых Bootstrap                             */
/* ==================================================================== */

/* Bootstrap называет своими те же слова, что и мы: `.row`, `.col`, `.card`,
 * `.table`, `.alert`, `.badge`, `.btn`, `.small`. Наши правила лежат ниже и
 * по порядку выигрывают — но только там, где мы что-то объявили. Всё, чего
 * мы НЕ переопределяем, продолжает действовать: отрицательные поля сетки,
 * `width: 100%` у каждого потомка `.row`, `margin-bottom` у таблиц и
 * сообщений. Это не мелочь: `.row > * { width: 100% }` ставит каждую кнопку
 * ряда на свою строку, и ряд перестаёт быть рядом.
 *
 * Поэтому чужое гасится здесь, один раз и явно, а не ловится потом по
 * экранам. Дешевле, чем переименовывать полсотни классов в девяноста шаблонах.
 */
.row,
.col {
  --bs-gutter-x: 0;
  --bs-gutter-y: 0;
  margin: 0;
  padding: 0;
}

.row > * {
  flex-shrink: initial;
  width: auto;
  max-width: none;
  padding-right: 0;
  padding-left: 0;
  margin-top: 0;
}

.col { flex: initial; }

.card { display: block; min-width: 0; }

/* `flex-direction` отдельной строкой и не зря. Bootstrap объявляет
   `.card { display: flex; flex-direction: column }`; `display` мы гасим, а
   направление оставалось бутстраповским — и элемент с классами `card row`
   превращался в СТОЛБИК, выстроенный по центру. Ряд обязан оставаться рядом,
   чем бы он ещё ни был */
.row { flex-direction: row; }

.alert, .badge, table { margin-bottom: 0; }

/* ==================================================================== */
/* 1. Основа страницы                                                    */
/* ==================================================================== */

html {
  /* Полоса прокрутки всегда: страница не должна дёргаться вбок при переходе
     со списка из трёх строк на список из трёхсот */
  overflow-y: scroll;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--bs-body-font-family);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Администратор на стойке попадает пальцем в соседние клетки шахматки по
     десять раз за смену, и каждое второе касание браузер считал двойным.
     `manipulation` оставляет прокрутку и щипок (масштаб нужен, чтобы
     разглядеть скан документа), но убирает зум по двойному тапу вместе с
     задержкой в 300 мс перед нажатием */
  touch-action: manipulation;
}

a {
  color: var(--brand-ink);
  text-decoration: none;
}

a:hover {
  color: var(--brand);
  text-decoration: underline;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text);
}

p { margin: 0 0 10px; }
p:last-child { margin-bottom: 0; }

hr {
  height: 1px;
  margin: 18px 0;
  border: 0;
  background: var(--border);
  opacity: 1;
}

:focus-visible {
  outline: 3px solid var(--bs-focus-ring-color);
  outline-offset: 1px;
  border-radius: var(--radius-xs);
}

::selection { background: var(--brand-bg); }

/* ==================================================================== */
/* 2. Утилиты                                                            */
/* ==================================================================== */

.muted { color: var(--text2); }
.small { font-size: 13px; }
.tiny  { font-size: 12px; line-height: 1.45; }
.nowrap { white-space: nowrap; }
.center { text-align: center; }
.grow  { flex: 1 1 auto; min-width: 0; }
.hidden { display: none !important; }
.break { overflow-wrap: anywhere; }
.num   { text-align: right; font-variant-numeric: tabular-nums; }

.mono, .key, .path {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
}

.key { font-size: 12px; overflow-wrap: anywhere; }

.code {
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text2);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
}

.pre {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 380px;
  overflow: auto;
}

/* Ряд элементов в строку — основной способ поставить кнопку рядом с кнопкой */
.row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.row--tight { gap: 6px; }
.row--top { align-items: flex-start; }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }
.row--muted { color: var(--text2); }
/* `justify-content` без `display: flex` не выравнивает ничего — а именно так
   `.spread` и был написан: на экране броней два переключателя уезжали за край
   и перенестись не умели. Теперь это полноценный ряд с переносом */
.spread {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
}

.col {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 560px;
}

.stack--wide { max-width: none; }

.mt { margin-top: 12px; }
.mt-lg { margin-top: 24px; }
.mb { margin-bottom: 12px; }
.mb-xs { margin-bottom: 6px; }
.mb0 { margin-bottom: 0 !important; }

.plain { margin: 0; padding: 0; list-style: none; }
.plain li + li { margin-top: 6px; }

/* Список дел с фирменной точкой вместо маркера */
.todo { margin: 0; padding: 0; list-style: none; }

.todo li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 6px;
  color: var(--text2);
}

.todo li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gradient-brand);
}

.tags { display: flex; flex-wrap: wrap; gap: 6px; }

.dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand);
  flex: none;
}

/* Ячейка таблицы под кнопки: не тянется и не переносится */
.act, .table__actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}

/* ==================================================================== */
/* 3. Каркас: шапка и рабочая колонка                                    */
/* ==================================================================== */

.shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Шапка липкая целиком: разделы и вошедший видны на любой строке журнала
   из десяти тысяч записей */
.shell__head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--head-bg);
  backdrop-filter: saturate(180%) blur(12px);
  box-shadow: var(--head-shadow);
}

/* Чекбокс выдвижного меню (Р-113). Сам он не виден никогда — видно то, что
   он переключает. Скриптом меню не открывается принципиально: единственный
   способ уйти со страницы не имеет права зависеть от того, загрузился ли
   JavaScript в отеле со слабым интернетом */
.nav-toggle {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* ---- полоса 1: бренд, инструменты, вошедший ---- */

.topbar {
  height: var(--head-a);
  border-bottom: 1px solid var(--border);
}

.topbar__inner,
.topnav__inner,
.page__inner {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--shell-pad);
}

.topbar__inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  flex: none;
}

.brand:hover { color: var(--text); text-decoration: none; }

.brand__mark {
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: url("/static/img/icon.svg") center / cover no-repeat;
  flex: none;
}

.brand__name {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Название кабинета — плашкой, а не мелким текстом под логотипом: три
   кабинета выглядят одинаково, и перепутать вкладки слишком легко */
.brand__kind {
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--brand-bg);
  color: var(--brand-ink);
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.topbar__tools {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.topbar__toggles {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Кнопка выдвижного меню. На широком экране её нет: строка разделов и так
   на виду, а кнопка, открывающая то, что уже открыто, читается как поломка */
.topbar__burger { display: none; }

/* Переключатель бизнеса партнёра */
.switcher { margin: 0; }

.switcher select {
  height: 34px;
  max-width: 260px;
  padding: 0 28px 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text);
  font-size: 13px;
}

.who-btn {
  gap: 8px !important;
  padding: 0 10px 0 4px !important;
}

.who-btn__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.25;
  max-width: 180px;
}

.who-btn__name,
.who-btn__role {
  max-width: 180px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.who-btn__name { font-size: 13px; font-weight: 600; }
.who-btn__role { font-size: 11px; color: var(--text2); }

.lang-btn {
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.04em;
}

/* ---- полоса 2: разделы ---- */

.topnav { height: var(--head-b); }

.topnav__inner {
  height: 100%;
  display: flex;
  align-items: stretch;
  gap: 2px;
}

.topnav__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 100%;
  padding: 0 14px;
  border: 0;
  background: none;
  color: var(--text2);
  font-size: 13.5px;
  font-weight: 600;
  font-family: inherit;
  white-space: nowrap;
  cursor: pointer;
}

.topnav__item:hover {
  color: var(--text);
  background: var(--surface);
  text-decoration: none;
}

/* Текущий раздел — фирменной линией снизу. Заливка целиком спорила бы с
   главной кнопкой страницы, а линия читается мгновенно и не кричит */
.topnav__item--active,
.topnav__item--in { color: var(--text); }

.topnav__item--active::after,
.topnav__item--in::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 0;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: var(--gradient-line);
}

/* Раздел без права виден, но не работает: спрятанный пункт порождает вопрос
   «а где партнёры?» в переписке, а не на экране */
.topnav__item--off {
  color: var(--text3);
  cursor: not-allowed;
}

.topnav__caret { font-size: 9px; opacity: 0.55; }

.topnav__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--surface3);
  color: var(--text2);
  font-size: 11px;
  font-weight: 700;
}

.topnav__count--hot {
  background: var(--error-bg);
  color: var(--error-ink);
}

/* Группа разделов. Открывается наведением и фокусом — без скрипта:
   единственный способ уйти со страницы не имеет права зависеть от того,
   загрузился ли JavaScript */
.topnav__group {
  position: relative;
  display: flex;
}

.topnav__drop {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 70;
  min-width: 236px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity .12s ease, transform .12s ease, visibility .12s;
}

.topnav__group:hover > .topnav__drop,
.topnav__group:focus-within > .topnav__drop {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* Последняя группа прижимается к правому краю: иначе её список уезжает за
   границу рабочей колонки */
.topnav__group--end > .topnav__drop {
  left: auto;
  right: 0;
}

.topnav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13.5px;
}

.topnav__link:hover {
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
}

.topnav__link--active {
  background: var(--brand-bg);
  color: var(--brand-ink);
  font-weight: 650;
}

/* Подпись группы нужна была только выдвижному меню телефона */
.topnav__label { display: none; }

/* ---- рабочая колонка ---- */

.page {
  flex: 1 1 auto;
  padding: 22px 0 72px;
}

.page__inner {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Экран чтения — узкая колонка: документ, длинный текст, форма настройки.
   Строка в 1300 px глазом не читается, её приходится вести пальцем */
.page--read .page__inner { max-width: 880px; }

/* ==================================================================== */
/* 4. Заголовок страницы, разделители, вкладки, панель фильтров           */
/* ==================================================================== */

.page-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.page-head__body { flex: 1 1 auto; min-width: 0; }

.page-head__title {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.page-head__meta {
  margin-top: 4px;
  color: var(--text2);
  font-size: 13px;
}

.page-head__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding-top: 2px;
}

/* Возврат — слева от заголовка, кружком: стрелка в тексте теряется среди
   ссылок карточки, а место у неё обязано быть одно на все экраны */
.page-head__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  padding: 0 12px;
  margin-top: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text2);
  font-size: 13px;
  white-space: nowrap;
  flex: none;
}

.page-head__back:hover {
  background: var(--surface3);
  color: var(--text);
  text-decoration: none;
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
}

.section-head:first-child { margin-top: 0; }

.section-head h2,
.section-head h3,
.section__title,
.sub-title {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.sub-title {
  margin: 18px 0 8px;
  color: var(--text2);
  text-transform: uppercase;
  font-size: 11.5px;
  letter-spacing: 0.08em;
}

.section-head__more {
  font-size: 13px;
  color: var(--text2);
  white-space: nowrap;
}

.section-head__more:hover { color: var(--brand); }

/* Вкладки внутри объекта: описание, фотографии, цены, календарь. На ПК они
   помещаются в строку целиком — прокрутки вбок больше нет */
/* Вкладок у объекта семь, и в строку они просят 865 px. Прокрутка вбок
   разрешена ВСЕГДА, а не под точкой перелома: на 768 px правило под
   `max-width: 767.98` уже не действует, и вместо полосы вбок ехала вся
   страница. Текущую вкладку подводит к краю `panel.js` */
.subnav {
  display: flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow-x: auto;
  scrollbar-width: none;
}

.subnav::-webkit-scrollbar { display: none; }

.subnav__item {
  padding: 7px 13px;
  border-radius: var(--radius-sm);
  color: var(--text2);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.subnav__item:hover {
  background: var(--surface2);
  color: var(--text);
  text-decoration: none;
}

.subnav__item--active {
  background: var(--surface2);
  color: var(--brand-ink);
  box-shadow: var(--shadow-sm);
}

.subnav__item--active::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 5px;
  border-radius: 2px;
  background: var(--gradient-line);
}

/* Панель фильтров — одна строка над списком. Кнопка «Найти» всегда справа,
   и место у неё одно на все списки трёх кабинетов */
/* Перенос — без всяких медиазапросов. Полей у отбора бывает четыре, и на
   планшете в 768 px они требовали 791: правило, стоящее под точкой перелома,
   на самой точке уже не срабатывает. Оборачиваем всегда — тогда неважно,
   сколько полей добавят завтра */
.toolbar {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  box-shadow: var(--shadow-sm);
}

.toolbar__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 170px;
}

.toolbar__field > label {
  color: var(--text2);
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.toolbar__search { flex: 1 1 auto; min-width: 260px; }

.toolbar__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.toolbar__reset {
  font-size: 13px;
  color: var(--text2);
  white-space: nowrap;
}

.result-line {
  color: var(--text2);
  font-size: 13px;
}

/* Строка сходимости в финансах: расхождение обязано быть заметно с порога,
   а не найтись при сверке с бухгалтерией */
.result-line--warn {
  color: var(--error-ink);
  font-weight: 600;
}

/* ==================================================================== */
/* 5. Карточки, сетки, плитки                                            */
/* ==================================================================== */

.card {
  position: relative;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface2);
  box-shadow: var(--shadow-sm);
}

/* Карточка, у которой содержимое во всю ширину: таблица, список диалогов.
   Заголовок при этом остаётся с полями — иначе он прилипает к рамке */
.card--flush { padding: 18px 0 0; }
.card--flush > .card__title,
.card--flush > .card__hint,
.card--flush > .card__head,
.card--flush > .empty,
.card--flush > .row,
.card--flush > .toolbar { padding-left: 20px; padding-right: 20px; }

.card--tight { padding: 14px 16px; }
.card--bare { padding: 0; border: 0; background: none; box-shadow: none; }

.card--link { display: block; color: inherit; transition: border-color .12s ease, transform .12s ease; }
.card--link:hover {
  border-color: var(--border2);
  color: inherit;
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

/* Карточка с фирменным кантом сверху: «здесь главное на экране» */
.card--accent::before,
.card--error::before,
.card--danger::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.card--accent::before { background: var(--gradient-line); }
.card--error::before,
.card--danger::before { background: var(--error); }

.card--error,
.card--danger { border-color: var(--error-bg); }

.card.sticky { position: sticky; top: calc(var(--head-h) + 16px); }

.card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.card__head .card__title { margin-bottom: 2px; }
.card__head .card__hint { margin-bottom: 0; }

.card__title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.card__subtitle {
  font-size: 13px;
  color: var(--text2);
}

.card__hint,
.card__lead {
  margin: 0 0 14px;
  color: var(--text2);
  font-size: 13px;
}

.card__lead { color: var(--text); font-size: 14px; }

.card__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.card--flush > .card__foot { padding: 14px 20px; margin-top: 0; }

/* Сетки. Колонок ровно столько, сколько влезает в фиксированную ширину —
   пересчитывать под экран больше нечего */
.grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.grid--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.cols--aside { grid-template-columns: minmax(0, 1fr) 340px; }

/* Главное слева, решение справа. Правая колонка липкая: чтобы выдать
   ограничение, не приходится прокручивать мимо всей анкеты и обратно */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 16px;
  align-items: start;
}

.split > div { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.split__aside {
  position: sticky;
  top: calc(var(--head-h) + 16px);
}

/* Плитки сводки. Четыре в ряд — ровно та ширина, при которой шестизначное
   число не переносится */
/* Ряд, а не сетка. Сетка с `auto-fit` растягивала ДВЕ плитки на всю ширину
   рабочей колонки — по 660 px на число из двух цифр; экран отзывов выглядел
   так, будто на нём забыли содержимое. Здесь плитка растёт до 360 px и
   больше не тянется: четыре встают в ряд, две остаются двумя плитками */
.stats {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.stat {
  flex: 1 1 200px;
  max-width: 360px;
}

.stat {
  position: relative;
  display: block;
  padding: 16px 18px 16px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface2);
  color: inherit;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* Кант слева, а не заливка: четыре залитых плитки подряд превращают сводку
   в светофор, на котором ничего не выделено */
.stat::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--border2);
}

a.stat:hover {
  border-color: var(--border2);
  color: inherit;
  text-decoration: none;
  box-shadow: var(--shadow-md);
}

a.stat:hover::before { background: var(--gradient-line); }

.stat__value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.stat__label {
  margin-top: 4px;
  color: var(--text2);
  font-size: 12.5px;
}

.stat__hint {
  margin-top: 6px;
  color: var(--text3);
  font-size: 11.5px;
}

.stat--accent::before { background: var(--gradient-line); }
.stat--accent .stat__value { color: var(--brand-ink); }

/* Плитка, за которой стоит работа. Красный кант и красное число — это не
   украшение: на сводке из двенадцати чисел глаз обязан находить его сразу */
.stat--alarm::before { background: var(--error); }
.stat--alarm .stat__value { color: var(--error-ink); }

/* Пары «название — значение»: анкета, реквизиты, свод. Двумя колонками,
   потому что справа почти всегда короткое значение */
.pairs {
  display: grid;
  grid-template-columns: minmax(140px, auto) minmax(0, 1fr);
  gap: 0;
  margin: 0;
}

.pairs dt,
.pairs dd {
  padding: 8px 0;
  border-top: 1px solid var(--border);
  margin: 0;
  min-width: 0;
}

.pairs dt:first-of-type,
.pairs dt:first-of-type + dd { border-top: 0; }

.pairs dt {
  padding-right: 16px;
  color: var(--text2);
  font-size: 13px;
  font-weight: 500;
}

.pairs dd { overflow-wrap: anywhere; }

/* Замечание внутри карточки: не тревога и не ошибка, а «имейте в виду» */
.notice {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text2);
  font-size: 13px;
}

.notice--warning {
  border-left-color: var(--warning);
  background: var(--warning-bg);
  color: var(--warning-ink);
}

/* ==================================================================== */
/* 6. Таблицы                                                            */
/* ==================================================================== */

/* Тень у края говорит, что таблица прокручивается. Без неё колонка,
   обрезанная ровно по краю карточки, читается как «данные кончились», и
   вбок никто не тянет. `background-attachment: local` гасит тень, когда
   прокручивать больше некуда, — обещание кончается вместе с содержимым */
.table-wrap {
  overflow-x: auto;
  border-top: 1px solid var(--border);
  background:
    linear-gradient(to right, var(--surface2), transparent 24px) left center / 100% 100% no-repeat local,
    linear-gradient(to left, var(--surface2), transparent 24px) right center / 100% 100% no-repeat local,
    linear-gradient(to right, var(--scroll-shade), transparent 12px) left center / 100% 100% no-repeat scroll,
    linear-gradient(to left, var(--scroll-shade), transparent 12px) right center / 100% 100% no-repeat scroll;
}

.card--flush > .table-wrap { margin-top: 14px; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

/* ШАПКА ТАБЛИЦЫ НЕ ЛИПКАЯ, И ЭТО НЕ НЕДОДЕЛКА.
   `position: sticky` отсчитывается от ближайшего предка с прокруткой, а это
   `.table-wrap`: `overflow-x: auto` делает контейнер прокручиваемым и по
   вертикали тоже. Отступ от верха страницы превращался в смещение шапки на
   100 px ВНИЗ — прямо поверх первых строк таблицы. Ошибка эта уже была
   поймана однажды и записана в developer-guide; вернуть её ничего не стоит,
   поэтому здесь стоит объяснение, а не просто отсутствие правила. */
thead th {
  padding: 9px 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  color: var(--text2);
  font-size: 11.5px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: left;
  white-space: nowrap;
}

tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

tbody tr:last-child td { border-bottom: 0; }

tbody tr:hover td { background: var(--row-hover); }

/* Строка-ссылка целиком: попадать в мелкое имя мышью двести раз за смену */
.row-link { cursor: pointer; }
.row-link:hover td { background: var(--row-hover); }

/* Строка, потерявшая силу: снятое ограничение, отменённый счёт */
tr.row--muted td,
.row--muted td { color: var(--text3); }

.pager {
  display: flex;
  justify-content: center;
  gap: 10px;
  padding: 4px 0;
}

/* ==================================================================== */
/* 7. Плашки, чипы, переключатели, аватар                                */
/* ==================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface3);
  color: var(--text2);
  font-size: 11.5px;
  font-weight: 650;
  line-height: 1.5;
  white-space: nowrap;
}

a.badge:hover { text-decoration: none; filter: brightness(0.96); }

.badge--success { background: var(--success-bg); color: var(--success-ink); }
.badge--warning { background: var(--warning-bg); color: var(--warning-ink); }
.badge--error   { background: var(--error-bg);   color: var(--error-ink); }
.badge--info    { background: var(--info-bg);    color: var(--info-ink); }
.badge--brand   { background: var(--brand-bg);   color: var(--brand-ink); }
.badge--accent  { background: var(--accent-bg);  color: var(--accent-ink); }
.badge--muted   { background: var(--surface3);   color: var(--text3); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface2);
  color: var(--text2);
  font-size: 12.5px;
  white-space: nowrap;
}

.chip--brand { border-color: transparent; background: var(--brand-bg); color: var(--brand-ink); }
.chip--success { border-color: transparent; background: var(--success-bg); color: var(--success-ink); }
.chip--warning { border-color: transparent; background: var(--warning-bg); color: var(--warning-ink); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips .chip { cursor: pointer; }
.chips .chip input { margin: 0; accent-color: var(--brand); }

/* Переключатель режимов: «все / ждут / решённые». Соседи кнопок, но одна из
   них всегда нажата — поэтому не кнопки */
.seg {
  display: inline-flex;
  flex-wrap: wrap;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  gap: 2px;
}

.seg__item {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 6px 13px;
  border-radius: var(--radius-sm);
  color: var(--text2);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.seg__item:hover { background: var(--surface2); color: var(--text); text-decoration: none; }

.seg__item--active {
  background: var(--surface2);
  color: var(--brand-ink);
  box-shadow: var(--shadow-sm);
}

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--gradient-brand);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  flex: none;
}

.avatar--brand { background: var(--gradient-brand); }

/* ==================================================================== */
/* 8. Формы                                                              */
/* ==================================================================== */

label { color: var(--text); font-size: 13px; }

input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]),
select,
textarea,
.input {
  width: 100%;
  min-height: 38px;
  padding: 8px 11px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.4;
}

select {
  appearance: none;
  padding-right: 30px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text3) 50%),
                    linear-gradient(135deg, var(--text3) 50%, transparent 50%);
  background-position: calc(100% - 16px) calc(50% + 1px), calc(100% - 11px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

textarea { min-height: 84px; resize: vertical; }

input::placeholder, textarea::placeholder { color: var(--text3); }

input:focus, select:focus, textarea:focus {
  border-color: var(--brand);
  outline: 3px solid var(--bs-focus-ring-color);
  outline-offset: 0;
}

input:disabled, select:disabled, textarea:disabled {
  background: var(--surface);
  color: var(--text3);
  cursor: not-allowed;
}

/* Поле ввода прямо в ячейке таблицы: правка настройки, заметка о номере,
   название документа. У `input` есть «естественная» ширина в двадцать
   символов, и в узкой колонке она распирает таблицу вместо того, чтобы
   поле сжалось. `min-width: 0` возвращает решение вёрстке */
td input:not([type="checkbox"]):not([type="radio"]),
td select,
td textarea { min-width: 0; }

.field { display: flex; flex-direction: column; gap: 5px; }

.field > label,
.field__label {
  color: var(--text2);
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.field__hint {
  color: var(--text3);
  font-size: 12px;
}

/* Два поля в строку: даты «с» и «по», цена и валюта */
.fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.checks { display: flex; flex-direction: column; gap: 8px; }

.check {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13.5px;
  cursor: pointer;
}

.check--inline { display: inline-flex; align-items: center; margin-right: 16px; }

.check input {
  margin: 2px 0 0;
  width: 16px;
  height: 16px;
  accent-color: var(--brand);
  flex: none;
}

/* Поле для кода из письма и одноразового пароля: крупно и вразрядку —
   шесть цифр вводят с бумажки и с экрана телефона */
.code-input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]) {
  max-width: 220px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 22px;
  letter-spacing: 0.32em;
  text-align: center;
}

/* Значение, которое нельзя править: выглядит как поле, но им не является */
.static-value {
  min-height: 38px;
  padding: 8px 11px;
  border: 1px dashed var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text2);
}

/* Числовое поле с кнопками. Системные стрелки мелкие и в тёмной теме
   выглядят поломкой */
.stepper {
  display: flex;
  align-items: stretch;
  gap: 0;
  max-width: 190px;
}

.stepper__btn {
  width: 38px;
  border: 1px solid var(--border2);
  background: var(--surface);
  color: var(--text);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.stepper__btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.stepper__btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.stepper__btn:hover { background: var(--surface3); }
.stepper__btn:disabled { color: var(--text3); cursor: not-allowed; }

.stepper input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]) {
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  text-align: center;
  -moz-appearance: textfield;
}

.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ==================================================================== */
/* 9. Кнопки и меню                                                      */
/* ==================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  padding: 0 16px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}

.btn:hover {
  background: var(--surface3);
  color: var(--text);
  text-decoration: none;
}

.btn[aria-disabled="true"], .btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}

/* Главная кнопка экрана — фирменной заливкой. Градиент отдельный
   (`--gradient-action`): на светлом конце заката белый текст не читается */
.btn--primary {
  border-color: transparent;
  background: var(--gradient-action);
  background-size: 160% 160%;
  background-position: 0% 50%;
  color: #fff;
  box-shadow: var(--shadow-brand);
  transition: background-position .3s ease, box-shadow .12s ease;
}

.btn--primary:hover { background-position: 100% 50%; color: #fff; }

.btn--ghost { background: transparent; }
.btn--ghost:hover { background: var(--surface); }

.btn--quiet {
  border-color: transparent;
  background: transparent;
  color: var(--text2);
  font-weight: 500;
}

.btn--quiet:hover { background: var(--surface); color: var(--text); }

.btn--danger {
  border-color: var(--error-bg);
  background: var(--error-bg);
  color: var(--error-ink);
}

.btn--danger:hover { background: var(--error); border-color: var(--error); color: #fff; }

.btn--danger-solid {
  border-color: transparent;
  background: var(--error-ink);
  color: #fff;
}

.btn--danger-solid:hover { background: var(--error); color: #fff; }

.btn--small { height: 30px; padding: 0 11px; font-size: 12.5px; }
.btn--block { width: 100%; }

/* Кнопка-значок: тема, язык, вошедший. Квадратная, чтобы ряд в шапке
   выстроился по одной высоте */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 34px;
  height: 34px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
  list-style: none;
}

.icon-btn:hover { background: var(--surface3); color: var(--text); text-decoration: none; }
.icon-btn::-webkit-details-marker { display: none; }

/* Выпадающее меню на `details` — без скрипта. Закрывается нажатием мимо и
   клавишей Esc, это делает panel.js */
.menu { position: relative; }
.menu[open] > .icon-btn { background: var(--surface3); border-color: var(--border2); }

.menu__body {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 80;
  min-width: 230px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  box-shadow: var(--shadow-lg);
}

.menu__title {
  padding: 6px 10px 4px;
  color: var(--text3);
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13.5px;
}

.menu__item:hover { background: var(--surface); color: var(--text); text-decoration: none; }
.menu__item--on { background: var(--brand-bg); color: var(--brand-ink); font-weight: 650; }

.menu__note {
  padding: 8px 10px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
  color: var(--text3);
  font-size: 11.5px;
}

/* ==================================================================== */
/* 10. Сообщения, пустые экраны, шаги                                    */
/* ==================================================================== */

.alert {
  position: relative;
  padding: 12px 16px 12px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  color: var(--text);
  font-size: 13.5px;
}

.alert::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--border2);
}

.alert a { color: inherit; text-decoration: underline; }

.alert--success { background: var(--success-bg); border-color: transparent; color: var(--success-ink); }
.alert--success::before { background: var(--success); }
.alert--info    { background: var(--info-bg);    border-color: transparent; color: var(--info-ink); }
.alert--info::before { background: var(--info); }
.alert--warning { background: var(--warning-bg); border-color: transparent; color: var(--warning-ink); }
.alert--warning::before { background: var(--warning); }
.alert--error   { background: var(--error-bg);   border-color: transparent; color: var(--error-ink); }
.alert--error::before { background: var(--error); }

.empty {
  padding: 44px 20px;
  text-align: center;
  color: var(--text2);
}

.empty__mark {
  font-size: 30px;
  line-height: 1;
  margin-bottom: 12px;
  opacity: 0.55;
}

.empty__title {
  color: var(--text);
  font-size: 15px;
  font-weight: 650;
}

.empty__text {
  margin: 6px auto 0;
  max-width: 420px;
  font-size: 13px;
}

.empty__actions {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 16px;
}

/* Шаги: анкета партнёра, путь брони. Пройденный — фирменной точкой */
.steps {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.steps__item {
  position: relative;
  padding-left: 26px;
  color: var(--text2);
  font-size: 13.5px;
}

.steps__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 5px;
  width: 12px;
  height: 12px;
  border: 2px solid var(--border2);
  border-radius: 50%;
  background: var(--surface2);
}

.steps__item--done { color: var(--text); }
.steps__item--done::before { border-color: transparent; background: var(--success); }

.steps__item--now { color: var(--text); font-weight: 600; }
.steps__item--now::before { border-color: transparent; background: var(--gradient-brand); }

/* Тот же список, но горизонтально: путь брони от запроса до выезда */
.steps--flow { flex-direction: row; gap: 0; flex-wrap: wrap; }

.steps--flow .steps__item {
  flex: 1 1 0;
  padding: 0 10px 0 0;
  text-align: left;
}

.steps--flow .steps__item + .steps__item::before {
  content: "";
  position: static;
}

.steps--flow .steps__item .steps__title { display: block; font-weight: 600; color: var(--text); }
.steps--flow .steps__item .steps__when { display: block; font-size: 12px; color: var(--text3); }

.legend { display: flex; flex-wrap: wrap; gap: 14px; }

.legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text2);
  font-size: 12.5px;
}

.legend__dot {
  width: 12px;
  height: 12px;
  border-radius: 4px;
  border: 1px solid var(--border2);
  background: var(--surface2);
  flex: none;
}

.legend__dot--blocked { background: var(--surface3); border-color: var(--border2); }
.legend__dot--booked { background: var(--brand); border-color: transparent; }
.legend__dot--hold { background: var(--warning); border-color: transparent; }

/* ==================================================================== */
/* 11. Поверх фирменного градиента                                       */
/* ==================================================================== */

.on-gradient { color: #fff; }
.on-gradient .muted,
.on-gradient .card__hint,
.on-gradient .stat__label { color: rgba(255, 255, 255, 0.84); }
.on-gradient a { color: #fff; text-decoration: underline; }

.on-gradient .btn {
  background: #fff;
  border-color: transparent;
  color: var(--gradient-ink);
  box-shadow: var(--shadow-md);
}

.on-gradient .btn--ghost {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.46);
  color: #fff;
}

/* ==================================================================== */
/* 12. Вход, приглашение, восстановление пароля                          */
/* ==================================================================== */

/* Две половины: слева закат со знаком сервиса, справа форма. Карточка
 * посреди пустого экрана не отвечала на вопрос «это точно кабинет
 * партнёра?» — а панель открывают с чужого ноутбука на стойке.
 *
 * Пропорция зафиксирована: закат ровно 44 % ширины. Сжимать его больше
 * некуда — телефонной версии у кабинета нет (Р-189).
 */
.login {
  display: grid;
  grid-template-columns: 44% minmax(0, 1fr);
  min-height: 100vh;
}

.login__side {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 12px;
  padding: 56px 56px 64px;
  background: var(--gradient-hero);
  color: #fff;
}

.login__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: auto;
  color: #fff;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.login__brand:hover { color: #fff; text-decoration: none; }

.login__mark {
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: url("/static/img/icon.svg") center / cover no-repeat;
  flex: none;
}

.login__lead {
  max-width: 460px;
  font-size: 28px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.025em;
}

.login__note {
  max-width: 460px;
  color: rgba(255, 255, 255, 0.86);
  font-size: 14px;
}

.login__form {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
  background: var(--bg);
}

.login__card { width: 100%; max-width: 420px; }

.login__title { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }

.login__hint {
  margin: 6px 0 22px;
  color: var(--text2);
  font-size: 14px;
}

.login__foot {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  color: var(--text2);
  font-size: 13px;
}

/* Капча. Картинка приходит 340×120 и нарисована попиксельно: растянутая, она
   размывается ровно на цифрах — поэтому в своём размере и по центру */
.captcha {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.captcha__image {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-xs);
  background: #fff;
}

.captcha__row { display: flex; align-items: center; gap: 10px; }

/* Высота 32 px, а не по строке текста: это единственный способ заменить
   нечитаемый код, и промахнуться по нему пальцем нельзя */
.captcha__refresh {
  min-height: 32px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-ink);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
}

.captcha__refresh:hover { text-decoration: underline; }

/* ==================================================================== */
/* 13. Календарь занятости (общий для трёх кабинетов)                    */
/* ==================================================================== */

/* Партнёр им управляет, модератор и админ смотрят. «Свободно» обязано быть
 * одного цвета во всех трёх, иначе разговор поддержки с партнёром
 * начинается с выяснения, у кого что зелёное.
 *
 * Неделя начинается с понедельника — как в календаре на стене у
 * управляющей компании.
 */
.calendar {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 6px;
}

.calendar__dow {
  padding: 4px 0;
  color: var(--text3);
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: center;
}

.calendar__pad { min-height: 1px; }

.calendar__day {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 78px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  font-size: 12px;
}

.calendar__date { font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums; }
.calendar__price { color: var(--text); font-variant-numeric: tabular-nums; }
.calendar__nights,
.calendar__units { color: var(--text3); font-size: 11px; }

.calendar__mark {
  color: var(--text2);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.calendar__day--blocked { background: var(--surface3); color: var(--text3); }
.calendar__day--booked { background: var(--brand-bg); border-color: transparent; }
.calendar__day--booked .calendar__mark { color: var(--brand-ink); }
.calendar__day--hold { background: var(--warning-bg); border-color: transparent; }
.calendar__day--hold .calendar__mark { color: var(--warning-ink); }

/* День, которого коснулось правило цены: фирменная точка в углу */
.calendar__day--ruled { position: relative; }

.calendar__day--ruled::after {
  content: "";
  position: absolute;
  top: 8px;
  right: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gradient-brand);
}

/* ==================================================================== */
/* 14. Переписка (партнёр — с гостем, модератор — с обратившимся)        */
/* ==================================================================== */

/* Список слева, переписка справа. Высота считается от низа шапки:
 * прокручивается лента сообщений, а не страница целиком, поэтому поле ввода
 * всегда на месте и его не приходится догонять прокруткой */
.chat-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 16px;
  align-items: start;
}

.chat-layout__aside {
  position: sticky;
  top: calc(var(--head-h) + 16px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dialog-list { display: flex; flex-direction: column; }

.card > .dialog-list { margin: 0 -20px -18px; }
.card--flush > .dialog-list { margin: 0; }

.dialog-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  color: var(--text);
}

.dialog-item:first-child { border-top: 0; }
.dialog-item:hover { background: var(--surface); color: var(--text); text-decoration: none; }

.dialog-item__photo {
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  background: var(--surface3) center / cover no-repeat;
  flex: none;
}

.dialog-item__photo--support { background: var(--gradient-brand); }

.dialog-item__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.dialog-item__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.dialog-item__name { font-weight: 650; font-size: 13.5px; }

.chat {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--head-h) - 150px);
  min-height: 460px;
  padding: 0;
  overflow: hidden;
}

.chat__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bubble {
  position: relative;
  max-width: 72%;
  padding: 9px 13px;
  border-radius: 14px;
  background: var(--surface);
  font-size: 13.5px;
  align-self: flex-start;
}

.bubble:not(.bubble--mine):not(.bubble--system) { border-bottom-left-radius: 4px; }

.bubble--mine {
  align-self: flex-end;
  background: var(--brand-bg);
  border-bottom-right-radius: 4px;
}

.bubble--system {
  align-self: center;
  max-width: 82%;
  background: none;
  border: 1px dashed var(--border2);
  color: var(--text2);
  font-size: 12.5px;
  text-align: center;
}

.bubble__time { margin-top: 3px; color: var(--text3); font-size: 11px; }

.bubble__photo {
  display: block;
  max-width: 320px;
  margin-bottom: 4px;
  border-radius: var(--radius-sm);
}

.bubble__file {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  font-size: 12.5px;
}

.bubble__menu { position: absolute; top: 4px; right: 6px; opacity: 0; }
.bubble:hover .bubble__menu { opacity: 1; }

.bubble__delete {
  padding: 0;
  border: 0;
  background: none;
  color: var(--text3);
  font-size: 13px;
  cursor: pointer;
}

.bubble__delete:hover { color: var(--error-ink); }

.typing { padding: 0 20px 6px; color: var(--text3); font-size: 12px; }

.composer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface2);
}

.composer__text {
  flex: 1 1 auto;
  min-height: 38px;
  max-height: 160px;
  resize: none;
}

.composer__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--text2);
  font-size: 16px;
  cursor: pointer;
  flex: none;
}

.composer__btn:hover { background: var(--surface3); color: var(--text); }

.composer__btn--send {
  border-color: transparent;
  background: var(--gradient-action);
  color: #fff;
}

.composer__btn--send:hover { color: #fff; filter: brightness(1.08); }

/* ==================================================================== */
/* 15. Фотографии и просмотр документа                                   */
/* ==================================================================== */

/* Снимки объявления: партнёр их грузит, модератор по ним решает. Сетка одна
   и та же — иначе «третье фото сверху» в переписке указывает на разные */
.photos {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.photo {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface2);
  overflow: hidden;
}

.photo__image {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--surface3) center / cover no-repeat;
}

.photo__cover-mark {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--gradient-brand);
  color: #fff;
  font-size: 11px;
  font-weight: 650;
}

.photo__body { padding: 10px 12px; font-size: 12.5px; }

/* Подложка просмотра ОДНА И ТА ЖЕ в обеих темах: скан паспорта на белом
   сливается со страницей, и края документа перестают быть видны — а именно
   по краям чаще всего и обрезают нужное */
.viewer {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 520px;
  padding: 16px;
  border-radius: var(--radius);
  background: var(--viewer-bg);
  overflow: auto;
}

.viewer__placeholder { color: rgba(255, 255, 255, 0.55); font-size: 13px; }

.viewer__image,
.viewer__frame {
  max-width: 100%;
  border-radius: var(--radius-sm);
  background: #fff;
}

.viewer__frame { width: 100%; height: 640px; border: 0; }

.viewer-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}


/* ==================================================================== */
/* 16. АДАПТИВ (Р-191)                                                   */
/* ==================================================================== */

/* Все точки перелома ядра — здесь и только здесь. Разложенные по своим
 * компонентам, они читаются как двадцать несвязанных решений; собранные
 * вместе — как один ответ на вопрос «что происходит с экраном, когда он
 * сужается».
 *
 * Точки — бутстраповские: 1200 (xl), 992 (lg), 768 (md), 576 (sm). Свои
 * означали бы, что `col-md-6` в разметке и наша сетка ломаются в соседних
 * местах, и объяснить это на экране нечем.
 *
 * Порядок сужения один на весь кабинет:
 *   xl — узкие колонки поджимаются, число плиток в ряду падает;
 *   lg — строка разделов уезжает в выдвижное меню, две колонки становятся
 *        одной;
 *   md — всё в один столбец, заголовок страницы переносится;
 *   sm — поля 12 px, кнопки во всю ширину, таблицы плотнее.
 */

/* ---- ≤ 1199.98: ноутбук и планшет лёжа ---- */
@media (max-width: 1199.98px) {
  /* Плитки сводки — строго по две. Свободная раскладка на планшете давала
     три в ряд и четвёртую одну во второй строке: сводка из четырёх чисел
     читается как «три и ещё что-то». Две на две читаются парами */
  .stat { flex-basis: calc(50% - 7px); max-width: none; }

  .split { grid-template-columns: minmax(0, 1fr) 320px; }
  .cols--aside { grid-template-columns: minmax(0, 1fr) 300px; }
  .chat-layout { grid-template-columns: minmax(0, 1fr) 300px; }
  .grid--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .photos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- ≤ 991.98: планшет. Разделы уезжают под кнопку ---- */
@media (max-width: 991.98px) {
  /* Строка разделов превращается в панель, падающую из шапки. Панель, а не
     ящик сбоку: групп четыре, и все они обязаны стоять раскрытыми — иначе
     до раздела два нажатия вместо одного */
  .topbar__burger { display: inline-flex; }

  .topnav {
    height: auto;
    max-height: 0;
    overflow: hidden;
    border-top: 1px solid var(--border);
    background: var(--surface2);
    transition: max-height .2s ease;
  }

  .nav-toggle:checked ~ .shell .topnav {
    max-height: 80vh;
    overflow-y: auto;
  }

  .topnav__inner {
    display: block;
    padding-top: 8px;
    padding-bottom: 12px;
  }

  .topnav__item {
    width: 100%;
    height: auto;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    font-size: 15px;
  }

  /* Заголовок группы в панели не кнопка: раскрывать нечего, всё и так
     развёрнуто. Кнопка, которая ничего не делает, хуже отсутствующей */
  .topnav__group { display: block; }
  .topnav__group > .topnav__item { display: none; }
  .topnav__item--active::after,
  .topnav__item--in::after { display: none; }
  .topnav__item--active { background: var(--brand-bg); color: var(--brand-ink); }

  .topnav__label {
    display: block;
    padding: 14px 12px 4px;
    color: var(--text3);
    font-size: 11px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .topnav__drop {
    position: static;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .topnav__link { padding: 10px 12px; font-size: 15px; }

  /* Две колонки становятся одной. Справка о разговоре встаёт НАД ним, а
     решение по карточке — ПОД разбираемым: в первом случае она отвечает на
     вопрос «о чём это», во втором — завершает чтение */
  /* ТАБЛИЦА ПРОКРУЧИВАЕТСЯ, А НЕ СЖИМАЕТСЯ.
     Без нижнего предела ширины `width: 100%` ужимал шесть колонок в 366 px:
     почта разваливалась на «guest@exa / mple.c / om», а последние колонки
     обрезались вовсе. Это не адаптив, это нечитаемая таблица.

     Предел ставится ПО ЧИСЛУ КОЛОНОК, а не всем подряд: у свода начислений
     их две, и гонять его вбок было бы не за чем. `:has()` считает колонки
     по шапке — иначе пришлось бы помечать классом каждую из сорока таблиц
     трёх кабинетов и помнить про это в каждой новой */
  .table-wrap > table:has(thead th:nth-child(4)) { min-width: 620px; }
  .table-wrap > table:has(thead th:nth-child(5)) { min-width: 760px; }
  .table-wrap > table:has(thead th:nth-child(6)) { min-width: 900px; }
  .table-wrap > table:has(thead th:nth-child(8)) { min-width: 1160px; }

  .split,
  .cols--aside,
  .chat-layout { grid-template-columns: minmax(0, 1fr); }

  .split__aside,
  .chat-layout__aside,
  .card.sticky { position: static; }

  .chat-layout__aside { order: -1; }
  .chat { height: auto; min-height: 60vh; }

  /* Вход: закат из колонки становится полосой над формой. На планшете в
     портрете колонка заката сжималась до 337 px, и «Управление сервисом
     Bounty» вставало в две строки поверх пустой полосы — полоса сверху
     честнее: она про сервис, а не про половину экрана */
  .login { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .login__side { padding: 24px 20px; gap: 8px; }
  .login__brand { margin-bottom: 16px; font-size: 17px; }
  .login__lead { font-size: 20px; }
  .login__note { font-size: 13px; }
  .login__form { padding: 32px 20px 48px; }

  /* Кнопка удаления своей реплики. Наведения на сенсорном экране нет вовсе,
     и спрятанная за `:hover` кнопка там недоступна в принципе */
  .bubble__menu { opacity: 1; }
  .bubble__delete { width: 32px; height: 32px; font-size: 16px; }

  /* Имя вошедшего в шапке уступает место кнопке меню */
  .who-btn__body { display: none; }
  .who-btn { padding: 0 8px !important; }
}

/* ---- ≤ 767.98: телефон лёжа и планшет стоя ---- */
@media (max-width: 767.98px) {
  .grid,
  .cols,
  .cards,
  .fields { grid-template-columns: minmax(0, 1fr); }

  .photos { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Заголовок страницы переносится: название, под ним действия. В строку
     они уже не помещаются, а обрезанное название хуже переноса */
  .page-head {
    flex-wrap: wrap;
    gap: 10px;
  }

  .page-head__title { font-size: 20px; }
  .page-head__actions { width: 100%; flex-wrap: wrap; }

  /* Панель отбора: каждое поле во всю ширину, кнопки строкой снизу */
  .toolbar {
    flex-direction: column;
    align-items: stretch;
    padding: 12px 14px;
  }


  .toolbar__field,
  .toolbar__search { min-width: 0; width: 100%; }
  .toolbar__actions { margin-left: 0; }

  .card { padding: 14px 16px; }
  .card--flush { padding: 14px 0 0; }
  .card--flush > .card__title,
  .card--flush > .card__hint,
  .card--flush > .card__head,
  .card--flush > .empty,
  .card--flush > .row,
  .card--flush > .toolbar { padding-left: 16px; padding-right: 16px; }
  .card--flush > .card__foot { padding: 14px 16px; }
  .card:not(.card--flush) > .dialog-list { margin: 0 -16px -14px; }
  .dialog-item { padding: 12px 16px; }

  thead th { padding: 8px 10px; }
  tbody td { padding: 9px 10px; }

  .pairs { grid-template-columns: minmax(0, 1fr); }
  .pairs dt { padding-bottom: 0; border-top: 1px solid var(--border); }
  .pairs dd { padding-top: 2px; border-top: 0; }
  .pairs dt:first-of-type + dd { border-top: 0; }

  .menu__body { min-width: 0; width: max(220px, 60vw); }

  .bubble { max-width: 88%; }
  .empty { padding: 32px 16px; }
}

/* ---- ≤ 575.98: телефон стоя ---- */
@media (max-width: 575.98px) {
  .page { padding: 14px 0 48px; }
  .page__inner { gap: 12px; }

  .brand__kind { display: none; }
  .brand__name { font-size: 15px; }

  /* Главное действие экрана во всю ширину: кнопка в 90 px посреди пустой
     строки читается как случайно оставшаяся */
  .page-head__actions .btn { flex: 1 1 auto; }

  /* На телефоне плитки остаются ПО ДВЕ, а не в столбик: число в них
     короткое, и четыре плитки столбиком — это четыре экрана прокрутки до
     первой строки содержимого */
  .stats { gap: 10px; }
  .stat { flex-basis: calc(50% - 5px); padding: 12px 14px 12px 16px; }
  .stat__value { font-size: 24px; }

  .photos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .card { padding: 14px; }
  .stack { gap: 12px; }

  /* Календарь остаётся календарём: семь колонок, иначе это уже не неделя.
     Ячейка сжимается до 46 px, и «БРОНЬ» в ней разваливалась на «БРОН / Ь» —
     слово короче не сделаешь, поэтому мельче шрифт и обрезка многоточием.
     Цвет дня при этом никуда не делся, а под сеткой стоят обозначения */
  .calendar { gap: 3px; }
  .calendar__day { min-height: 66px; padding: 5px; font-size: 11px; }
  .calendar__date { font-size: 12px; }
  .calendar__dow { font-size: 10px; }

  .calendar__mark {
    font-size: 9px;
    letter-spacing: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .btn { height: 40px; }
  .btn--small { height: 34px; }
}
