/* Оформление панели поверх app.css: плотность и починенные таблицы.
 *
 * Почему отдельным файлом, а не правкой app.css: app.css правится в другой зоне
 * и его версия в base.html поднимается вместе с ним; здесь же лежит слой,
 * который меняет плотность и поведение таблиц целиком, и его удобно снимать
 * одной ссылкой, если что-то поедет.
 *
 * Цвета светлой темы — в theme-light.css, он подключён всегда и включается
 * атрибутом data-theme="light" на <html>.
 */

:root {
  --topbar-h: 56px;
  --color-bg: #090c0f;
  --color-bg-elevated: #0f1418;
  --color-bg-card: #131a20;
  --color-border: #202830;
  --color-border-strong: #333e48;
}
body { font-size: 13px; line-height: 1.45; }

/* ==================================================================== *
 * Каркас: узкая колонка навигации, низкий топбар, минимум полей
 * ==================================================================== */
.shell { grid-template-columns: 210px minmax(0, 1fr); }
@media (max-width: 1200px) { .shell { grid-template-columns: 198px minmax(0, 1fr); } }
.sidebar { padding: 14px 10px 12px; }
.sidebar-brand { padding: 0 8px; }
.brand { font-size: 18px; gap: 9px; }
.wrab-logo, .brand-mark { width: 30px; height: 30px; flex-basis: 30px; }
.nav-label { margin: 22px 10px 8px; font-size: 10.5px; letter-spacing: .8px; }
.sidebar nav { gap: 2px; }
.nav-link { min-height: 36px; padding: 7px 10px; border-radius: 6px; gap: 10px; font-size: 12.5px; }
.nav-group-links { gap: 2px; }
.sidebar-foot { padding-top: 18px; }
.account-row { padding: 12px 4px 0; }
.identity { gap: 8px; }
.avatar { width: 26px; height: 26px; }
/* В узкой колонке кнопке выхода хватает 34 px, а почте нужен каждый пиксель. */
.sidebar .icon-button { min-width: 34px; height: 34px; }

.topbar { height: var(--topbar-h); padding: 0 22px; gap: 12px; }
.content { padding: 20px 22px 20px; max-width: none; }
@media (max-width: 1200px) { .topbar { padding: 0 18px; } .content { padding: 18px 18px 18px; } }

.account-actions { display: flex; align-items: center; flex: 0 0 auto; }
.account-actions form { display: flex; }
.theme-toggle .icon-sun, .theme-toggle .icon-moon { display: inline-grid; place-items: center; }
/* Кнопка темы стоит в топбаре рядом с автообновлением. Топбар низкий (56 px),
   поэтому кнопка меньше обычной иконочной. */
.topbar .theme-toggle { min-width: 32px; height: 32px; padding: 6px; margin-left: 4px; }
/* На странице входа топбара нет — кнопка висит в углу. */
.theme-toggle-float { position: fixed; top: 14px; right: 14px; z-index: 50;
  border-color: var(--color-border); background: var(--color-bg-elevated); }

/* ==================================================================== *
 * Заголовки
 * ==================================================================== */
.page-head { margin-bottom: 20px; gap: 18px; }
.page-head h1 { font-size: clamp(22px, 1.7vw, 27px); margin: 6px 0 6px; letter-spacing: -.7px; }
.page-head p { font-size: 12.5px; line-height: 1.55; max-width: 78ch; }
.eyebrow { font-size: 11px; letter-spacing: 1.1px; }
.section-heading { margin-bottom: 12px; }
.section-heading h2, .panel-head h2 { font-size: 15px; }

/* ==================================================================== *
 * Плитки и панели
 * ==================================================================== */
.kpis { gap: 10px; margin-bottom: 18px; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); }
@media (max-width: 620px) { .kpis { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } }
.kpi { min-height: 92px; padding: 13px 14px; border-radius: 7px; }
.kpi strong { font-size: 23px; margin-top: 7px; letter-spacing: -.5px; }
.portal-summary { padding: 15px 0; margin-bottom: 22px; border-radius: 8px; }
.summary-value { font-size: 23px; margin: 8px 0 3px; }

.panel { margin-top: 12px; border-radius: 7px; overflow: clip; }
.panel-head { padding: 12px 14px; }
.machine-grid { grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); gap: 9px; padding: 12px; }
.machine-card { padding: 12px 13px; border-radius: 7px; }
.quick { gap: 9px; }
.quick-card { padding: 13px 14px; border-radius: 7px; }

/* ==================================================================== *
 * Таблицы
 *
 * Было: table { min-width: 780px } внутри .table-wrap { overflow: auto } —
 * на телефоне за краем молча пряталось до 7500 px (сумма платежа, канал,
 * оплачено до), в окне 1100 — до 1700 px.
 * ==================================================================== */
table { min-width: 0; table-layout: auto; }
/* Адрес и порт не переносим никогда: разорванный посередине IP читается как
   другой адрес. Переносится только то, что состоит из слов — такие ячейки
   помечает скрипт (wrap), а настоящие фразы ещё и не сжимаются в столбик (wide). */
th, td { white-space: nowrap; }
td.wrap, th.wrap, td.empty, td[colspan] { white-space: normal; }
td.wide, td.empty, td[colspan] { overflow-wrap: anywhere; }
@media (min-width: 761px) { td.wide { min-width: 200px; } }

/* Цифры выравниваем по разрядам: столбик должен читаться столбиком. */
td strong, td b, td .mono, .kpi strong, .summary-value, .tt-numbers b,
.money-lines b, .money-lines strong { font-variant-numeric: tabular-nums; }

@media (min-width: 761px) {
  th { padding: 7px 12px; font-size: 10.5px; letter-spacing: .5px; text-transform: uppercase;
       background: #0c1216; }
  td { padding: 7px 12px; font-size: 12px; line-height: 1.5; }
  tbody tr:nth-child(even) td { background: #ffffff04; }
  tbody tr:hover td { background: #56dbcb08; }
  /* Идентификаторы моноширинным: адреса и порты сравниваются глазом по столбцу. */
  td a { font-family: var(--font-mono); font-size: 11.5px; }
  td.mono { font-size: 11.5px; }
  /* Торец строки красит состояние: лежащий слот виден боковым зрением. */
  tbody tr:has(.status-pill.down) td:first-child { box-shadow: inset 2px 0 0 var(--color-danger); }
  tbody tr:has(.status-pill.unknown) td:first-child { box-shadow: inset 2px 0 0 #5c6b77; }
  .status-pill { padding: 2px 7px; font-size: 10.5px; }
}
@media (max-width: 1000px) and (min-width: 761px) { th, td { padding: 7px 8px; } }

/* Если таблица всё-таки не влезла, скрипт вешает .is-scrollable: у края тень,
   первая колонка (адрес входа) остаётся на месте — иначе при прокрутке
   непонятно, чья это строка. */
.table-wrap.is-scrollable { position: relative; background:
  linear-gradient(to right, var(--color-bg-elevated) 30%, #11161b00),
  linear-gradient(to right, #11161b00, var(--color-bg-elevated) 70%) 100% 0,
  radial-gradient(farthest-side at 0 50%, #0006, transparent),
  radial-gradient(farthest-side at 100% 50%, #0006, transparent) 100% 0;
  background-repeat: no-repeat; background-size: 40px 100%, 40px 100%, 16px 100%, 16px 100%;
  background-attachment: local, local, scroll, scroll; }
@media (min-width: 761px) {
  .table-wrap.is-scrollable tbody td:first-child,
  .table-wrap.is-scrollable thead th:first-child {
    position: sticky; left: 0; z-index: 3; background: var(--color-bg-elevated);
    box-shadow: 1px 0 0 var(--color-border); }
  .table-wrap.is-scrollable thead th:first-child { z-index: 5; background: #0c1216; }
}

/* Когда таблица влезла целиком, прокрутка не нужна — и тогда шапка прилипает
   к топбару. У длинных списков (36 слотов, платежи за месяц) это единственный
   способ не терять, что за колонка перед глазами. Ради этого .panel переведена
   с overflow: hidden на clip: hidden создаёт scroll-контейнер и убивает sticky. */
.table-wrap.can-stick { overflow: visible; }
@media (min-width: 761px) {
  .table-wrap.can-stick thead th { position: sticky; top: var(--topbar-h); z-index: 4;
                                   background: #0c1216; }
}

.slot-cell { padding: 2px 6px; font-size: 10.5px; }
.slot-cells { gap: 4px; }
.empty { color: var(--color-fg-dim); }

/* ==================================================================== *
 * Телефон: строка таблицы разворачивается в карточку «поле → значение».
 * Подписи скрипт берёт из <thead>, разметку шаблонов трогать не пришлось.
 * Поля идут в два столбца — в один страница росла втрое.
 * ==================================================================== */
@media (max-width: 760px) {
  .content { padding: 16px 12px 18px; }
  .page-head h1 { font-size: 25px; }

  .table-wrap, .table-wrap.is-scrollable { overflow: visible; background: none; }
  table, thead, tbody { display: block; }
  thead { display: none; }
  td, th { white-space: normal; }
  tbody tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px 14px;
             margin: 0 12px 8px; padding: 11px 13px; border: 1px solid var(--color-border);
             border-radius: 10px; background: var(--color-bg-card); }
  tbody tr:last-child { margin-bottom: 14px; }
  tbody tr:nth-child(even) td, tbody tr:hover td { background: none; }
  tbody tr:has(.status-pill.down) td:first-child,
  tbody tr:has(.status-pill.unknown) td:first-child { box-shadow: none; }
  tbody tr:has(.status-pill.down) { border-color: #fb929255; }
  td { display: block; min-width: 0; padding: 0; border: 0; font-size: 13px; line-height: 1.4;
       overflow-wrap: anywhere; }
  td::before { content: attr(data-label); display: block; margin-bottom: 1px;
               color: var(--color-fg-dim); font-size: 10.5px; line-height: 1.25; font-weight: 400; }
  td:not([data-label])::before { display: none; }
  /* Строку целиком занимают фразы и действия; короткие значения (дата, сумма,
     порт) стоят парами, иначе карточка растёт вдвое. */
  td.wide, td:has(.row-actions), td:has(.row-form), td:has(form) { grid-column: 1 / -1; }
  td.empty, td[colspan] { grid-column: 1 / -1; padding: 30px 8px; text-align: center; }
  td.empty::before, td[colspan]::before { display: none; }
  td form { width: 100%; }
  td .row-actions, td .row-form { justify-content: flex-start; }
  .table-wrap.can-stick thead th { position: static; }

  /* Широкая матрица — исключение: разложить сетку в карточки значит потерять
     её смысл, поэтому её листают вбок, а первая колонка стоит на месте. */
  .table-wrap.keep-table { overflow-x: auto; }
  .table-wrap.keep-table table, .table-wrap.keep-table thead,
  .table-wrap.keep-table tbody, .table-wrap.keep-table tr { display: revert; }
  .table-wrap.keep-table thead { display: table-header-group; }
  .table-wrap.keep-table tbody tr { display: table-row; margin: 0; padding: 0;
    border: 0; border-radius: 0; background: none; }
  .table-wrap.keep-table td { display: table-cell; padding: 9px 10px; font-size: 12px;
    border-bottom: 1px solid var(--color-border); }
  .table-wrap.keep-table td::before { display: none; }
  .table-wrap.keep-table th { display: table-cell; }
  .table-wrap.keep-table tbody td:first-child, .table-wrap.keep-table thead th:first-child {
    position: sticky; left: 0; z-index: 3; background: var(--color-bg-elevated);
    box-shadow: 1px 0 0 var(--color-border); }
}

/* ==================================================================== *
 * Пол по кеглю: 9-10 px в служебных подписях не читается ни на телефоне,
 * ни на большом мониторе (было 1059 таких мест).
 * ==================================================================== */
.nav-group-title { font-size: 11px; }
.kpi small, .summary-caption, .summary-label, .section-heading p, .section-note,
.machine-numbers, .machine-meta, .tenant-details span, .meter-label, .page-footer,
.tag, .status-pill, .count-badge, .tt-numbers span, .tt-foot, .identity small,
.chip, .mini, .topbar-product, .crumb, .live-status, .op-actions small,
.field small, .summary-value small, .tenant-card footer, .login-foot,
.slot-cell, .large-state, .quick-card span { font-size: 11px; }
.summary-value .summary-badge { font-size: 10px; }
.content small { font-size: 11px; }
.chart-axis, .chart-scale, .chart-tip-time { font-size: 10.5px; }

/* ==================================================================== *
 * Кабинет арендатора и карточки
 * ==================================================================== */
/* auto-fill, а не auto-fit: у арендатора обычно один-два входа, и при auto-fit
   единственная карточка растягивалась на всю ширину — спарклайн в 1150 px. */
.portal-grid { grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 12px; }
@media (min-width: 1280px) { .portal-grid { grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); } }
.tenant-tiles { grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
.machine-grid { grid-template-columns: repeat(auto-fill, minmax(238px, 1fr)); }
/* Логин бывает почтой, а колонка навигации узкая: рвать адрес пополам нельзя,
   поэтому обрезаем многоточием — целиком он остаётся в подсказке. */
.identity, .identity > div { min-width: 0; }
.identity strong { display: block; min-width: 0; font-size: 11.5px; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
.tenant-card { padding: 15px 16px 0; border-radius: 8px; background: var(--color-bg-elevated); }
.tenant-card h2 { font-size: 17px; margin: 12px 0 4px; }
.tenant-rate strong { font-size: 30px; }
.tenant-usage { margin: 16px 0 12px; }
.tenant-card footer { margin: auto -16px 0; padding: 9px 16px; }
.tenant-card footer > span, .tenant-card footer > a { white-space: nowrap; }
.tenant-tiles { gap: 10px; }
.tenant-tile { padding: 14px 15px; border-radius: 8px; }

/* ==================================================================== *
 * Формы, кнопки, график
 * ==================================================================== */
.secondary, .primary { min-height: 34px; padding: 7px 12px; border-radius: 6px; font-size: 12px; }
.field input, .field select, .field textarea { min-height: 36px; }
.op > summary { padding: 11px 14px; }
.op-body { padding: 0 14px 14px; }
.chip { padding: 5px 10px; }
.ops, .howto { gap: 7px; }
.steps { gap: 9px; }
/* «Отменить запись» в деньгах стояла сплошной колонкой красных кнопок и
   перетягивала на себя всю страницу. Действие редкое — пусть и выглядит так. */
.btn-danger { border-color: transparent; background: none; color: var(--color-fg-dim); }
.btn-danger:hover { border-color: #fb92923b; background: #fb92920a; color: var(--color-danger); }

.chart { height: 244px; padding: 12px; }
.legend { padding: 0 14px 12px; }
.chart-window { padding: 0 14px 12px; }

/* ==================================================================== *
 * Цели на телефоне (было 233 ссылки и кнопки ниже 32 px)
 * ==================================================================== */
@media (max-width: 760px) {
  td { font-size: 13px; }
  td a, .tt-foot > a, .pager a, .panel-head > a, .hint-bar > a,
  .service-title, .service-endpoint button, .portal-inline button, .copy-box button {
    display: inline-flex; align-items: center; min-height: 34px; }
  .status-pill { padding: 6px 10px; }
  .chip, .periods a, .periods button { min-height: 38px; }
  .icon-button { min-width: 44px; height: 44px; }
  .nav-link { min-height: 48px; }
}
