/* =========================================================================
   bali-moto UI — общая дизайн-система сайта.

   Извлечена из дашборда «Сегодня» (design handoff «Дашборд Bali Moto»,
   2026-07-26) и распространена на остальные страницы. До неё каждая страница
   писала свои цвета и отступы руками: только у первичной кнопки в шаблонах
   насчитывалось 12+ разных написаний, радиусы скакали md/lg/xl/full, акцент
   был то чёрный, то изумрудный, то синий.

   Правила игры:
     * все классы с префиксом `u-` — так они не могут случайно зацепить
       дашборд (#dash .d-*) и календари (#cal3 .c3-*), у которых своя
       локальная разметка;
     * ни одного селектора по голому тегу — рядом живёт Tailwind Play CDN,
       и переопределять его preflight мы не хотим;
     * токены объявлены на :root, а не на контейнере — иначе элементы вне
       основного потока (боковые панели, тосты, модалки) теряют переменные
       и рендерятся бесцветными. На дашборде на эти грабли уже наступали.
   ========================================================================= */

:root {
  /* --- поверхности --- */
  --u-page:#f4f5f7;
  --u-surface:#ffffff;
  --u-subtle:#fbfcfd;
  --u-hover:#fafbfc;

  /* --- границы --- */
  --u-border:#e4e6ea;
  --u-border-soft:#eceef1;
  --u-hairline:#f1f2f4;

  /* --- текст --- */
  --u-text:#111827;
  --u-text-2:#374151;
  --u-text-3:#4b5563;
  --u-muted:#6b7280;
  --u-faint:#9aa1ab;

  /* --- акценты --- */
  --u-blue:#2563eb; --u-blue-hover:#1d4ed8;
  --u-blue-bg:#eff4ff; --u-blue-bd:#d7e2fe; --u-blue-fg:#1d4ed8;
  --u-red:#dc2626; --u-red-bg:#fef2f2; --u-red-bd:#fecaca; --u-red-fg:#b91c1c;
  --u-amber:#b45309; --u-amber-bg:#fffbeb; --u-amber-bd:#fde68a;
  --u-green:#047857; --u-green-bg:#ecfdf5; --u-green-bd:#bbf7d0;
  --u-grey-bg:#f7f8fa; --u-grey-bd:#e4e6ea; --u-grey-fg:#4b5563;

  /* --- геометрия --- */
  --u-r-sm:8px; --u-r-md:9px; --u-r-lg:11px;

  /* Ширина полосы контента. Одно число на шапку (`.u-topbar-inner`),
     обёртку страницы (`.u-main`) и саму страницу (`.u-page` в desktop.css) —
     разойдясь, они дают либо шапку не по краю контента, либо недостижимую
     ширину списков. Ровно это и было до 07.08.2026: 1440 в разметке против
     1600 в стилях. */
  --u-content:1600px;

  /* --- тени -------------------------------------------------------------
     Три ступени на всю систему. До 07.08.2026 теней в токенах не было
     вовсе, и каждое всплывающее что-нибудь писало свою: по файлам набралось
     полтора десятка разных `box-shadow`, отличавшихся вторым знаком. */
  --u-sh-1:0 1px 2px rgba(16,24,40,.08);      /* приподнятая карточка */
  --u-sh-2:0 8px 24px rgba(16,24,40,.14);     /* выпадашка, поповер */
  --u-sh-3:0 12px 32px rgba(16,24,40,.18);    /* модальное окно, шторка */
  /* Кольцо фокуса — тоже тень, и тоже была написана четырьмя способами. */
  --u-ring:0 0 0 3px rgba(37,99,235,.12);

  /* --- слои -------------------------------------------------------------
     Пять этажей вместо россыпи чисел от 2 до 200. Порядок важен: шапка
     ниже рельса, рельс ниже мобильной оболочки, модальное окно выше всех,
     подтверждение — поверх модального (иначе тост «сохранено» уезжает под
     окно, из которого его вызвали). */
  --u-z-sticky:20;   /* закреплённые шапки таблиц, шапка сайта */
  --u-z-rail:30;     /* рельс разделов, мобильная оболочка */
  --u-z-drop:40;     /* выпадашки и поповеры */
  --u-z-modal:100;   /* модальные окна */
  --u-z-toast:120;   /* всплывающие подтверждения */

  /* --- парные токены тёмной темы (добавлены 07.08.2026) -----------------
     Значения ниже — СВЕТЛЫЕ, то есть те же цвета, что уже стоят по файлам
     руками. Светлая тема от их появления не меняется ни на пиксель: имена
     новые, ими пока никто не пользуется. Они заведены здесь, чтобы тёмному
     слою (static/theme.css) было что переопределять, — и чтобы при
     токенизации экранов хардкод было куда переносить.

     Отдельно про поверхности: на светлом иерархию несёт тень, поэтому
     raised и overlay совпадают с surface. На тёмном тень почти не видна,
     и там же эти три уровня расходятся по светлоте. */
  --u-raised:#ffffff;             /* выпадашка, поповер, закреплённая шапка */
  --u-overlay:#ffffff;            /* модалка, шторка, палитра команд */
  --u-sunken:#f4f5f7;             /* трек прогресса, пустое поле, код */
  --u-scrim:rgba(16,24,40,.45);   /* подложка модального окна */
  --u-border-strong:#8a9099;      /* контур полей и кнопок; 3.2:1 к белому */

  --u-blue-solid:#2563eb;         /* заливка первичной кнопки */
  --u-blue-solid-hover:#1d4ed8;
  --u-on-blue:#ffffff;            /* текст на заливке */

  /* Белый текст поверх цветной заливки — НЕ то же самое, что белая
     поверхность. Раньше и то и другое писалось как #fff, и в тёмной теме
     подпись на синей кнопке уехала бы в цвет карточки.
     ⚠️ В тёмной теме этот токен ПЕРЕВОРАЧИВАЕТСЯ в тёмный: там заливка
     светлеет вместе с акцентом. Разбор — «закон заливки» в theme.css. */
  --u-on-fill:#ffffff;

  /* Текст на подложке, тёмной в ОБЕИХ темах: лайтбокс, индиго-градиент
     ассистента, плашка поверх фотографии. Тему не знает — иначе в тёмной
     он перевернулся бы вместе с --u-on-fill и пропал бы на чёрном. */
  --u-on-dark:#ffffff;

  /* Тёмно-синие чернила пузыря ассистента. Свели бы с --u-text (#111827) —
     сдвинули бы светлую тему на глаз; свой токен даёт тёмной теме
     перевернуться, не трогая светлую. */
  --u-ink-alt:#1d2939;

  /* Мягкая подсветка просроченной строки списка. Была написана литералом
     почти-белым — в тёмной теме строка оставалась светлой, а текст на ней
     светлел вместе с темой: имя байка пропадало. Скан контраста этого не
     видел, потому что фон задан на строке, а не на самой подписи. */
  --u-red-fg-strong:#7f1d1d;      /* густой красный текст заметки и алерта */
  --u-row-red:#fffafa; --u-row-red-hover:#fff5f5;
  /* Фиолетовый есть ровно в одном месте — штриховка «ожидаемое продление»
     в /calendar. Заведён токеном, а не литералом, чтобы у тёмной темы было
     что переопределить: сиреневое на почти-белом там пропадает. */
  --u-violet-bg:#f3e8ff; --u-violet-bg-2:#e9d5ff;
  --u-violet-bd:#a855f7; --u-violet-bd-strong:#7e22ce;

  /* «Инвертированная плашка» — активная вкладка, активный пункт рельса,
     сегмент, тост, кнопка `u-btn--dark`. Приём один: заливка цветом текста,
     надпись цветом страницы. Раньше это и писалось как
     `background:var(--u-text); color:#fff` — и в тёмной теме дало бы светлое
     на светлом (рельс и главная кнопка шапки в том числе). Пара токенов
     переворачивается вместе с темой, поэтому приём остаётся собой. */
  --u-invert:#111827; --u-invert-hover:#1f2937; --u-on-invert:#ffffff;

  /* Заливки статусов. В светлой совпадают с самими акцентами — на белом они
     и так насыщенные. Отдельные имена нужны тёмной: там они светлеют вместе
     с акцентом, а подпись на них становится тёмной («закон заливки»). */
  --u-red-solid:#dc2626;          /* заливка деструктивной кнопки */
  --u-green-solid:#047857;
  --u-amber-solid:#b45309;
  --u-amber-fg:#b45309;           /* текста статуса не было — только фон/граница */
  --u-green-fg:#047857;
  --u-ring-color:#2563eb;         /* сплошное кольцо фокуса, парное к --u-ring */
  --u-accent-warm:#b0522f;        /* тёплый акцент темы: тумблер, «Авто» */

  /* Вторая палитра. Экраны собраны не на тех же значениях, что оболочка:
     роли те же, оттенки свои. Свести их в один набор — 510 видимых точек
     светлой темы, а её менять не просили. Поэтому у второй палитры свои
     имена с нынешними значениями ОДИН В ОДИН: в светлой не меняется ничего,
     а в тёмной обе пары получают одно значение — там разница неразличима. */
  --u-blue-fg-alt:#1849a9;        /* синий текст, 139 мест */
  --u-amber-fg-alt:#93370d;       /* янтарный текст, 127 мест */
  --u-green-fg-alt:#05603a;       /* зелёный текст, 96 мест */
  --u-green-bd-alt:#a6f4c5;       /* зелёная граница, 71 место */
  --u-green-fill-alt:#12b76a;     /* зелёная ЗАЛИВКА, 30 мест */
  --u-amber-fill-alt:#f79009;     /* янтарная ЗАЛИВКА, 22 места */
  --u-border-mid:#d0d5dd;         /* «неактивно»: disabled, штриховая рамка */

  /* Графики: до сих пор каждый экран назначал цвета серий сам. */
  --u-chart-grid:#eceef1; --u-chart-axis:#6b7280;
  --u-chart-1:#2563eb; --u-chart-2:#047857; --u-chart-3:#b45309;
  --u-chart-4:#b0522f; --u-chart-5:#6d5bb5;
}

/* =========================================================================
   1. Каркас страницы
   ========================================================================= */

/* minmax(0,1fr), а не просто 1fr: у grid-элементов min-width по умолчанию
   auto, поэтому одна широкая карточка внутри растягивает всю колонку и
   страница уезжает горизонтально на телефоне (поймано на /rentals: 744px
   вместо 390). Это же касается всех сеток ниже. */
.u-page { display:grid; grid-template-columns:minmax(0,1fr); gap:12px;
  color:var(--u-text); font-size:13px; line-height:1.45;
  font-variant-numeric:tabular-nums; }

/* Полоса контента страницы — обёртка <main> в base.html.
   Класс, а не набор Tailwind-утилит прямо в разметке: ширина полосы это
   решение дизайн-системы, и жить оно должно в одном месте.
   ⚠️ 07.08.2026: в разметке стояло `max-w-[1440px]`, а `desktop.css` обещал
   спискам 1600 — обещание было недостижимо, внешняя обёртка резала раньше.
   Теперь оба числа одно и то же и объявлены здесь. */
.u-main { width:100%; max-width:var(--u-content); margin:0 auto; padding:16px; }
/* Экраны, которым полоса не нужна: помесячный календарь, лента /calendar3,
   рабочее место /park — они строят раскладку во всю ширину окна сами. */
.u-main--wide { max-width:none; }
/* Плотнее по бокам: дашборд и календарь и так делят экран на колонки. */
.u-main--tight { padding-left:12px; padding-right:12px; }
/* Совсем без полей: раскладка внутри экрана рисует свои. */
.u-main--flush { padding:0; }

.u-head { display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; padding:2px 2px 0; }
.u-h1 { font-size:22px; font-weight:650; letter-spacing:-.4px; margin:0; }
.u-sub { margin-top:3px; font-size:12.5px; color:var(--u-muted); }
.u-head-actions { margin-left:auto; display:flex; gap:8px; flex-wrap:wrap; }

.u-grid-main { display:grid; grid-template-columns:minmax(0,1fr) 400px; gap:12px; align-items:start; }
.u-grid-2 { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; align-items:start; }
.u-grid-3 { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; align-items:start; }
.u-grid-4 { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:12px; align-items:start; }
.u-col { display:grid; grid-template-columns:minmax(0,1fr); gap:12px; }

/* =========================================================================
   2. Карточка — базовый контейнер любого блока
   ========================================================================= */

.u-card { border:1px solid var(--u-border); border-radius:var(--u-r-lg);
  background:var(--u-surface); overflow:hidden; }
.u-card-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:13px 16px 11px; border-bottom:1px solid var(--u-border-soft); }
.u-card-title { font-size:15px; font-weight:650; letter-spacing:-.2px; margin:0; }
.u-card-title-sm { font-size:14px; font-weight:650; margin:0; }
.u-card-meta { font-size:12px; color:var(--u-muted); }
.u-card-right { margin-left:auto; }
.u-card-body { padding:14px 16px; }
.u-card-foot { display:flex; align-items:center; gap:12px; padding:10px 16px;
  background:var(--u-subtle); font-size:12px; color:var(--u-muted); }

/* =========================================================================
   3. Кнопки
   ========================================================================= */

.u-btn { display:inline-flex; align-items:center; justify-content:center; gap:6px;
  height:32px; padding:0 12px; border-radius:var(--u-r-md);
  border:1px solid var(--u-border); background:var(--u-surface);
  color:var(--u-text-2); font-size:12.5px; font-family:inherit;
  cursor:pointer; white-space:nowrap; text-decoration:none; transition:background .12s; }
.u-btn:hover { background:var(--u-grey-bg); }
.u-btn:focus-visible { outline:2px solid var(--u-blue); outline-offset:1px; }
.u-btn[disabled] { opacity:.5; cursor:not-allowed; }

.u-btn--sm { height:28px; padding:0 11px; font-size:12px; border-radius:var(--u-r-sm); }
.u-btn--lg { height:38px; padding:0 16px; font-size:13px; }
.u-btn--icon { width:28px; height:28px; padding:0; border-radius:var(--u-r-sm);
  color:var(--u-text-3); font-size:12px; }
.u-btn--block { width:100%; }

.u-btn--primary { background:var(--u-blue-solid); border-color:var(--u-blue-solid); color:var(--u-on-blue); font-weight:600; }
.u-btn--primary:hover { background:var(--u-blue-solid-hover); border-color:var(--u-blue-solid-hover); }
.u-btn--dark { background:var(--u-invert); border-color:var(--u-invert); color:var(--u-on-invert); font-weight:600; }
.u-btn--dark:hover { background:var(--u-invert-hover); border-color:var(--u-invert-hover); }
.u-btn--green { background:var(--u-green-bg); border-color:var(--u-green-bd);
  color:var(--u-green); font-weight:600; }
.u-btn--green:hover { background:#d9fbee; }
.u-btn--danger { background:var(--u-surface); border-color:var(--u-red-bd); color:var(--u-red-fg); }
.u-btn--danger:hover { background:var(--u-red-bg); }

/* =========================================================================
   4. Чипы и тона
   ========================================================================= */

.u-chip { display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600;
  padding:1px 7px; border-radius:5px; border:1px solid var(--u-grey-bd);
  background:var(--u-grey-bg); color:var(--u-grey-fg); white-space:nowrap; }
.u-chip--red { background:var(--u-red-bg); border-color:var(--u-red-bd); color:var(--u-red-fg); }
.u-chip--blue { background:var(--u-blue-bg); border-color:var(--u-blue-bd); color:var(--u-blue-fg); }
.u-chip--amber { background:var(--u-amber-bg); border-color:var(--u-amber-bd); color:var(--u-amber); }
.u-chip--green { background:var(--u-green-bg); border-color:var(--u-green-bd); color:var(--u-green); }

.u-tone-red { color:var(--u-red-fg); }
.u-tone-amber { color:var(--u-amber); }
.u-tone-green { color:var(--u-green); }
.u-tone-blue { color:var(--u-blue-fg); }
.u-muted { color:var(--u-muted); }
.u-faint { color:var(--u-faint); }
.u-num { font-variant-numeric:tabular-nums; }
.u-link { color:var(--u-blue); font-size:11.5px; text-decoration:none; }
.u-link:hover { color:var(--u-blue-hover); text-decoration:underline; }
.u-hidden { display:none !important; }
.u-ta-r { text-align:right; }

/* =========================================================================
   5. Табы-фильтры (как в ленте «Требует внимания»)
   ========================================================================= */

.u-tabs { display:flex; gap:4px; padding:9px 12px; background:var(--u-subtle);
  border-bottom:1px solid var(--u-border-soft); overflow-x:auto; }
.u-tab { display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 10px;
  border-radius:var(--u-r-sm); border:1px solid var(--u-border); background:var(--u-surface);
  color:var(--u-text-2); font-size:12.5px; font-family:inherit; cursor:pointer;
  white-space:nowrap; text-decoration:none; }
.u-tab:hover { border-color:#c9cfd8; }
.u-tab.is-active { background:var(--u-invert); border-color:var(--u-invert); color:var(--u-on-invert); font-weight:600; }
.u-tab-n { opacity:.7; font-variant-numeric:tabular-nums; }

/* Сегментированный переключатель (сортировка) */
.u-seg { display:flex; border:1px solid var(--u-border); border-radius:var(--u-r-sm); overflow:hidden; }
.u-seg > * { height:26px; min-width:28px; padding:0 9px; display:inline-flex;
  align-items:center; justify-content:center;
  font-size:11.5px; border:0; border-left:1px solid var(--u-border); background:var(--u-surface);
  color:var(--u-text-3); cursor:pointer; font-family:inherit; text-decoration:none; }
.u-seg > *:first-child { border-left:0; }
.u-seg > *.is-active { background:var(--u-invert); color:var(--u-on-invert); }

/* =========================================================================
   6. Лента (строка списка с левым акцентом) — основной паттерн списков
   ========================================================================= */

.u-row { display:flex; gap:12px; padding:12px 16px 12px 13px;
  border-bottom:1px solid var(--u-hairline); border-left:3px solid transparent;
  text-decoration:none; color:inherit; }
.u-row:hover { background:var(--u-hover); }
.u-row--red { border-left-color:var(--u-red); background:var(--u-row-red); }
.u-row--red:hover { background:var(--u-row-red-hover); }
.u-row--amber { border-left-color:var(--u-amber); }
.u-row--blue { border-left-color:var(--u-blue); }
.u-row--green { border-left-color:var(--u-green); }
.u-row--grey { border-left-color:var(--u-border-mid); }

.u-row-icon { width:28px; height:28px; flex:none; border-radius:var(--u-r-sm);
  display:flex; align-items:center; justify-content:center; font-size:13px;
  background:var(--u-grey-bg); border:1px solid var(--u-grey-bd); }
.u-row--red .u-row-icon { background:var(--u-red-bg); border-color:var(--u-red-bd); }
.u-row--blue .u-row-icon { background:var(--u-blue-bg); border-color:var(--u-blue-bd); }
.u-row--green .u-row-icon { background:var(--u-green-bg); border-color:var(--u-green-bd); }

.u-row-avatar { width:36px; height:36px; flex:none; border-radius:50%; object-fit:cover;
  border:1px solid var(--u-border); background:var(--u-grey-bg); display:flex;
  align-items:center; justify-content:center; font-size:15px; color:var(--u-muted); }
.u-row-check { flex:none; align-self:flex-start; margin-top:7px; width:15px; height:15px;
  accent-color:var(--u-blue); cursor:pointer; }
.u-row-body { flex:1; min-width:0; }
.u-row-line1 { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.u-row-title { font-size:13.5px; font-weight:600; color:inherit; text-decoration:none; }
.u-row-title:hover { color:var(--u-blue); }
.u-row-line2 { margin-top:3px; font-size:12.5px; color:var(--u-text-2); }
.u-row-note { margin-top:2px; font-size:12px; color:var(--u-muted); }
.u-row-aside { flex:none; width:150px; text-align:right; font-size:13px; font-weight:600; }
.u-row-aside-sub { display:block; margin-top:2px; font-weight:400; font-size:11.5px; }
.u-row-actions { flex:none; display:flex; align-items:flex-start; gap:6px; }

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

.u-table-wrap { overflow-x:auto; }
.u-table { width:100%; border-collapse:collapse; font-size:12.5px; }
.u-table thead th { padding:8px 16px; background:var(--u-subtle); text-align:left;
  border-bottom:1px solid var(--u-border-soft); font-size:11px; font-weight:500;
  color:var(--u-muted); letter-spacing:.03em; text-transform:uppercase; white-space:nowrap; }
.u-table tbody td { padding:10px 16px; border-bottom:1px solid var(--u-hairline);
  vertical-align:middle; }
.u-table tbody tr:hover { background:var(--u-hover); }
.u-table tbody tr:last-child td { border-bottom:0; }
.u-table .u-td-strong { font-weight:600; }
.u-table .u-td-r { text-align:right; }

/* Список «ключ — значение» (карточки-детали, боковые панели) */
.u-kv { margin:0; }
.u-kv > div { display:flex; justify-content:space-between; gap:12px; padding:7px 0;
  border-bottom:1px solid var(--u-hairline); }
.u-kv > div:last-child { border-bottom:0; }
.u-kv dt { font-size:12.5px; color:var(--u-muted); }
.u-kv dd { margin:0; font-size:12.5px; font-weight:600; text-align:right;
  font-variant-numeric:tabular-nums; }

/* =========================================================================
   8. KPI-плитки
   ========================================================================= */

.u-kpis { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  border:1px solid var(--u-border); border-radius:var(--u-r-lg);
  background:var(--u-surface); overflow:hidden; }
.u-kpi { padding:14px 16px; border-right:1px solid var(--u-border-soft);
  display:block; text-decoration:none; color:inherit; }
.u-kpi:last-child { border-right:0; }
.u-kpi:hover { background:var(--u-hover); }
.u-kpi-label { font-size:11.5px; color:var(--u-muted); }
.u-kpi-value { font-size:26px; font-weight:640; letter-spacing:-.6px; margin-top:5px;
  font-variant-numeric:tabular-nums; }
.u-kpi-hint { margin-top:4px; font-size:11.5px; color:var(--u-faint); }

/* =========================================================================
   9. Пустые состояния и баннеры
   ========================================================================= */

.u-empty { padding:34px 20px; text-align:center; }
.u-empty-icon { width:40px; height:40px; margin:0 auto; border-radius:var(--u-r-lg);
  font-size:17px; background:var(--u-green-bg); border:1px solid var(--u-green-bd);
  display:flex; align-items:center; justify-content:center; }
.u-empty-t { margin-top:11px; font-size:14px; font-weight:600; }
.u-empty-n { margin-top:4px; font-size:12.5px; color:var(--u-muted); }
.u-empty-btns { display:flex; gap:8px; justify-content:center; margin-top:14px; flex-wrap:wrap; }
.u-empty--sm { padding:24px 18px; text-align:center; }

.u-note { display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:11px 14px;
  border:1px solid var(--u-border-soft); background:var(--u-grey-bg);
  border-radius:var(--u-r-md); font-size:12.5px; color:var(--u-text-3); }
.u-note--red { border-color:var(--u-red-bd); background:var(--u-red-bg); color:var(--u-red-fg-strong); }
.u-note--amber { border-color:var(--u-amber-bd); background:var(--u-amber-bg); color:var(--u-amber-fg-alt); }
.u-note--green { border-color:var(--u-green-bd); background:var(--u-green-bg); color:var(--u-green); }
.u-note-t { font-weight:600; }

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

.u-form { display:grid; gap:12px; }
/* `align-content:start` — не украшение. Поля в строке формы это ячейки грида,
   и высокая колонка (подсказка под инпутом, вторая строка) растягивала
   соседние: инпут «Гражданство» становился выше инпута «Номер паспорта» в том
   же ряду. Поле прижимается к верху и сохраняет свой рост. */
.u-field { display:grid; gap:4px; align-content:start; }
.u-label { font-size:11.5px; color:var(--u-muted); }
.u-label .u-req { color:var(--u-red); }
.u-input, .u-select, .u-textarea {
  width:100%; min-height:36px; padding:8px 11px; border-radius:var(--u-r-md);
  border:1px solid var(--u-border); background:var(--u-surface); color:var(--u-text);
  font-size:13px; font-family:inherit; }
/* Одна высота у всех однострочных контролов. От `min-height` она получалась
   разной: браузер считает её по содержимому, а содержимое у типов разное —
   в одном ряду стояли текст 37 px, дата 39 и выпадашка 36. Заметно это как
   раз рядом: «Номер паспорта» и «Дата рождения» выглядели полями разного
   размера. Многострочные и файловые исключены — им высота по содержимому. */
.u-input:not(textarea):not([type="file"]), .u-select { height:var(--u-ctl-h, 38px); }
.u-input:focus, .u-select:focus, .u-textarea:focus {
  outline:0; border-color:var(--u-blue); box-shadow:var(--u-ring); }
.u-textarea { min-height:76px; resize:vertical; }
.u-hint { font-size:11px; color:var(--u-faint); }

/* Радио-плитки (уровень бензина, число шлемов, состояние при возврате).
   Без Tailwind-овского peer-checked: сам input скрыт, подсвечивается соседняя
   плитка — так же работает с клавиатуры, потому что фокус остаётся на input. */
.u-choices { display:grid; gap:6px; }
.u-choice { cursor:pointer; position:relative; }
.u-choice input { position:absolute; opacity:0; width:0; height:0; }
.u-choice-box { display:flex; align-items:center; justify-content:center; gap:4px;
  height:38px; padding:0 8px; border:1px solid var(--u-border); border-radius:var(--u-r-md);
  background:var(--u-surface); font-size:13px; font-weight:600; color:var(--u-text-2); text-align:center; }
.u-choice:hover .u-choice-box { background:var(--u-grey-bg); }
.u-choice input:checked + .u-choice-box { background:var(--u-invert); border-color:var(--u-invert); color:var(--u-on-invert); }
.u-choice input:focus-visible + .u-choice-box { outline:2px solid var(--u-blue); outline-offset:1px; }

/* Загрузка файлов — единый вид у нативной кнопки браузера */
.u-file { display:block; width:100%; font-size:12.5px; color:var(--u-text-2); }
.u-file::file-selector-button { margin-right:10px; padding:7px 11px; border-radius:var(--u-r-sm);
  border:1px solid var(--u-border); background:var(--u-grey-bg); color:var(--u-text-2);
  font-size:12.5px; font-family:inherit; cursor:pointer; }
.u-file::file-selector-button:hover { background:var(--u-border-soft); }
.u-form-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
/* Раскладки строк формы. Раньше они писались инлайновым `style=` прямо в
   шаблонах — и на телефоне форма не складывалась в столбик: инлайновый стиль
   сильнее медиазапроса ниже. Поля сжимались до нечитаемого («🛵 Отвезт»),
   подсказки наезжали друг на друга. Модификаторы живут здесь, поэтому
   мобильное правило их перебивает. */
.u-form-row--wide-narrow      { grid-template-columns:minmax(0,2fr) minmax(0,1fr); }
.u-form-row--wide-narrow-narrow { grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr); }
.u-form-row--thirds           { grid-template-columns:repeat(3,minmax(0,1fr)); }
.u-form-actions { display:flex; gap:8px; flex-wrap:wrap; margin-top:4px; }

/* =========================================================================
   11. Боковая панель (карточки-детали) и тост
   ========================================================================= */

/* Боковой шторки в CRM нет. Блок `.u-drawer` (7 правил) лежал здесь
   описанным, но не использованным ни одним шаблоном — снят 07.08.2026.
   Понадобится — берётся из истории git; мёртвые правила в дизайн-системе
   хуже отсутствующих: их читают как «так у нас принято». */

/* --- Модальное окно ------------------------------------------------------
   Разметка — нативный `<dialog class="u-modal">`, механика в static/modal.js.
   Здесь только вид. Обратить внимание:

   * `padding:0` и `border:0` — у `<dialog>` они есть по умолчанию, и без
     сброса шапка окна не доходит до его краёв;
   * ширина через `min()`, а не `max-width`: `<dialog>` ужимается по
     содержимому, и окно с коротким текстом выходило бы уже соседнего;
   * `max-height` в `dvh`, а не `vh` — на телефоне адресная строка съедает
     до 15 % высоты, и низ окна с кнопками уезжал под неё;
   * `z-index` окну НЕ нужен: `showModal()` поднимает его в отдельный слой
     поверх всей страницы, выше любого нашего числа. */
.u-modal { padding:0; border:0; border-radius:var(--u-r-lg);
  background:var(--u-surface); color:var(--u-text);
  box-shadow:var(--u-sh-3);
  width:min(560px, calc(100vw - 32px));
  max-height:calc(100dvh - 64px); overflow:hidden;
  font-size:13px; font-variant-numeric:tabular-nums; }
.u-modal::backdrop { background:rgba(16,24,40,.42); }
.u-modal--sm { width:min(420px, calc(100vw - 32px)); }
/* Окно, открываемое с клавиатуры, ставим ближе к верху: взгляд уже там, а
   центр экрана заставляет его прыгать. */
.u-modal--top { margin-block:8vh auto; }

.u-modal-head { display:flex; align-items:center; gap:8px; padding:12px 16px;
  border-bottom:1px solid var(--u-border-soft); }
.u-modal-title { margin:0; font-size:14px; font-weight:650; }
.u-modal-x { margin-left:auto; flex:none; width:28px; height:28px; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  border:0; border-radius:var(--u-r-sm); background:none; cursor:pointer;
  color:var(--u-muted); font-size:18px; line-height:1; font-family:inherit; }
.u-modal-x:hover { background:var(--u-grey-bg); color:var(--u-text); }
.u-modal-body { padding:16px; overflow-y:auto; max-height:calc(100dvh - 190px); }
.u-modal-foot { display:flex; gap:8px; padding:12px 16px;
  border-top:1px solid var(--u-border-soft); background:var(--u-subtle); }

/* Мелкое поле-фильтр над длинным списком (байки, клиенты в быстрой брони). */
/* Своя высота задаётся переменной: обычный `min-height` слабее `height`
   из общего правила выше и молча не сработал бы. */
.u-input--mini { --u-ctl-h:30px; min-height:30px; padding:5px 10px; font-size:12px; margin-bottom:4px; }

/* --- Внутренности быстрого платежа --------------------------------------
   Раньше это были Tailwind-утилиты в шаблоне и в строках JS одновременно:
   один и тот же результат поиска рисовался двумя разными наборами классов
   в зависимости от того, пришёл он из разметки или из скрипта. */
.qp-results { margin-top:8px; max-height:min(46vh, 300px); overflow-y:auto; }
.qp-none { padding:14px 8px; text-align:center; font-size:12px; color:var(--u-muted); }
.qp-result { display:flex; align-items:center; gap:8px; width:100%;
  padding:8px 10px; border:0; border-bottom:1px solid var(--u-hairline);
  border-radius:var(--u-r-sm); background:none; color:inherit;
  font-family:inherit; font-size:12.5px; text-align:left; cursor:pointer; }
.qp-result:hover, .qp-result:focus-visible { background:var(--u-blue-bg); outline:0; }
.qp-result-b { flex:1; min-width:0; }
.qp-result-t { display:block; font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.qp-result-s { display:block; margin-top:1px; font-size:11.5px; color:var(--u-muted); }
.qp-result-go { flex:none; color:var(--u-faint); }

.qp-picked { display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-bottom:12px; padding:8px 10px;
  border-radius:var(--u-r-sm); background:var(--u-grey-bg); }
.qp-picked-t { font-weight:600; }
.qp-picked-s { margin-top:1px; font-size:11.5px; color:var(--u-muted); }

/* Список «клавиша — что делает» (справка по «?»). Раньше собирался строкой
   в `style.cssText` прямо в JS: поправить его, не трогая скрипт, было
   нельзя, а к дизайн-системе он не имел отношения вовсе. */
.u-keys { display:grid; grid-template-columns:auto 1fr; gap:7px 12px;
  align-items:center; font-size:12.5px; color:var(--u-text-2); }
.u-keys kbd { justify-self:start; padding:2px 6px; border-radius:4px;
  border:1px solid var(--u-border); border-bottom-width:2px;
  background:var(--u-grey-bg); color:var(--u-text-2);
  font:11px/1.4 ui-monospace, Menlo, monospace; }

@media (max-width:640px) {
  /* На телефоне окно — лист снизу: до кнопки в центре экрана большим
     пальцем не дотянуться. */
  .u-modal, .u-modal--sm {
    width:100%; max-width:100%; margin:auto 0 0; border-radius:14px 14px 0 0;
    max-height:88dvh;
    padding-bottom:env(safe-area-inset-bottom, 0px);
  }
  .u-modal--top { margin-block:auto 0; }
}

.u-toast { position:fixed; left:50%; bottom:26px; transform:translateX(-50%); z-index:var(--u-z-toast);
  display:flex; align-items:center; gap:10px; padding:11px 15px; border-radius:var(--u-r-md);
  background:var(--u-invert); color:var(--u-on-invert); font-size:12.5px;
  box-shadow:var(--u-sh-3); }
.u-toast.u-hidden { display:none; }
.u-toast-ok { color:#6ee7b7; }

/* =========================================================================
   12. Шапка сайта (base.html)
   ========================================================================= */

.u-topbar { background:var(--u-surface); border-bottom:1px solid var(--u-border-soft); }
.u-topbar-inner { display:flex; align-items:center; gap:16px; height:56px; padding:0 16px;
  max-width:var(--u-content); margin:0 auto; }
.u-brand { display:flex; align-items:center; gap:9px; font-size:16px; font-weight:600;
  letter-spacing:-.2px; color:inherit; text-decoration:none; flex:none; }
.u-brand-mark { width:26px; height:26px; border-radius:7px; background:var(--u-blue-bg);
  border:1px solid var(--u-blue-bd); display:flex; align-items:center;
  justify-content:center; font-size:14px; }
.u-search { width:100%; max-width:420px; height:36px; padding:0 12px;
  border-radius:var(--u-r-md); border:1px solid var(--u-border); background:var(--u-grey-bg);
  font-size:13px; font-family:inherit; color:var(--u-text); }
.u-search::placeholder { color:var(--u-faint); }
.u-search:focus { outline:0; background:var(--u-surface); border-color:#c9cfd8;
  box-shadow:var(--u-ring); }
/* Выпадашка поиска. Позиционируется от обёртки; содержимое приезжает по
   HTMX, стили строк — в desktop.css (`.sd-*`). Прячется атрибутом `hidden`,
   а не классом: состояние принадлежит элементу, а не стилевому фреймворку. */
.u-search-wrap { position:relative; flex:1; display:flex; justify-content:center; }
.u-search-drop { position:absolute; right:0; top:100%; margin-top:4px;
  width:28rem; max-width:90vw; background:var(--u-surface);
  border:1px solid var(--u-border); border-radius:var(--u-r-md);
  box-shadow:var(--u-sh-2); z-index:var(--u-z-drop);
  /* Прокрутка обязательна: в пустом состоянии здесь лежит список из 22
     разделов, и без ограничения по высоте нижние уезжают за край экрана —
     ровно те, что открывают реже всего и ищут глазами. По горизонтали
     по-прежнему hidden, чтобы не торчали углы за скруглением. */
  max-height:min(70vh, 34rem); overflow-x:hidden; overflow-y:auto; }
.u-search-drop[hidden] { display:none; }

/* Кнопка «сузить панель разделов». По умолчанию скрыта: рельс живёт только
   на компьютере (desktop.css показывает и её, и панель выше 768 px). */
.u-rail-btn { display:none; }
.u-topbar-actions { margin-left:auto; display:flex; align-items:center; gap:10px; flex:none; }
.u-avatar { width:28px; height:28px; border-radius:50%; border:1px solid var(--u-border); }
.u-email { font-size:12px; color:var(--u-text-3); max-width:180px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }

.u-nav { display:flex; justify-content:center; gap:4px; padding:10px 16px;
  border-bottom:1px solid var(--u-border-soft); background:var(--u-subtle); flex-wrap:wrap; }
.u-nav-item { display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 14px;
  border-radius:var(--u-r-sm); font-size:13px; color:var(--u-text-2);
  text-decoration:none; white-space:nowrap; border:0; background:none;
  font-family:inherit; cursor:pointer; }
.u-nav-item:hover { background:var(--u-border-soft); }
.u-nav-item.is-active { background:var(--u-invert); color:var(--u-on-invert); font-weight:600; }
.u-nav-drop { position:absolute; left:0; top:100%; margin-top:4px; min-width:200px;
  background:var(--u-surface); border:1px solid var(--u-border); border-radius:var(--u-r-md);
  box-shadow:var(--u-sh-2); z-index:var(--u-z-drop); padding:5px; }
.u-nav-drop a { display:flex; align-items:center; gap:8px; padding:7px 9px;
  border-radius:6px; font-size:12.5px; color:var(--u-text-2);
  text-decoration:none; white-space:nowrap; }
.u-nav-drop a:hover { background:var(--u-grey-bg); }
.u-nav-drop a.is-active { background:var(--u-blue-bg); color:var(--u-blue-fg); font-weight:600; }

/* =========================================================================
   13. Адаптив
   ========================================================================= */

@media (max-width:1280px) {
  .u-grid-main { grid-template-columns:minmax(0,1fr); }
  .u-grid-4 { grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:860px) {
  .u-grid-2, .u-grid-3, .u-grid-4 { grid-template-columns:minmax(0,1fr); }
  .u-kpis { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .u-head-actions { width:100%; margin-left:0; }
  /* Любая раскладка формы на узком экране — один столбец. */
  .u-form-row,
  .u-form-row--wide-narrow,
  .u-form-row--wide-narrow-narrow,
  .u-form-row--thirds { grid-template-columns:1fr; }
  .u-kpi { border-right:0; border-bottom:1px solid var(--u-border-soft); }
  /* Строка ленты становится карточкой: действие во всю ширину под текстом */
  .u-row { flex-wrap:wrap; }
  .u-row-aside { width:auto; margin-left:auto; }
  .u-row-actions { width:100%; }
  .u-row-actions .u-btn--primary { flex:1; }
}

/* --- Полоса выполнения (раздел «Задачи ассистента») ---------------------
   Одна тонкая полоса, а не сегменты как на мобильном: на десктопе рядом
   стоят точные цифры «план 5 из 12 · факт 2», и клеточки их дублировали бы. */
.u-progress { height:8px; border-radius:999px; background:var(--u-grey-bg);
  overflow:hidden; }
.u-progress > span { display:block; height:100%; border-radius:999px;
  background:var(--u-green); transition:width .4s ease; }

/* --- Чек на подтверждении (раздел «Задачи ассистента») ------------------
   Фото и цифры рядом: сверять сумму, глядя в другую вкладку, невозможно. */
.u-receipt { display:grid; grid-template-columns:minmax(0,160px) minmax(0,1fr);
  gap:14px; align-items:start; }
.u-receipt-photo { position:relative; display:block; border-radius:var(--u-r-lg);
  overflow:hidden; border:1px solid var(--u-border); background:var(--u-grey-bg); }
.u-receipt-photo img { display:block; width:100%; height:auto; max-height:220px;
  object-fit:cover; }
.u-receipt-zoom { position:absolute; right:6px; bottom:6px; padding:3px 7px;
  border-radius:999px; background:rgba(17,24,39,.78); color:var(--u-on-dark);
  font-size:10.5px; font-weight:700; }
.u-receipt-body { min-width:0; }
/* Записано без чека: на месте фото — причина. Место сохраняем то же, чтобы
   строка отчёта не прыгала между «с чеком» и «без чека». */
.u-receipt-photo--none { display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:4px; min-height:120px; padding:12px 10px;
  text-align:center; border-style:dashed; }
.u-receipt-none-icon { font-size:22px; opacity:.7; }
.u-receipt-none-t { font-size:12.5px; font-weight:700; color:var(--u-text); }
.u-receipt-none-why { font-size:11.5px; line-height:1.35; color:var(--u-muted);
  overflow-wrap:anywhere; }
@media (max-width: 640px) {
  .u-receipt { grid-template-columns:minmax(0,1fr); }
  .u-receipt-photo img { max-height:260px; object-fit:contain; }
}

/* --- Таблицы в узком экране ------------------------------------------
   Обёртка с overflow-x-auto сама по себе не спасает: при `w-full` таблица
   ужимается в ширину экрана, и колонка свободного текста схлопывается до
   одного символа — заметка превращается в вертикальную лапшу из букв
   (скриншот владельца с телефона, 30.07.2026: колонка «Заметки» в расходах
   байка).

   Правило простое: колонке с текстом задаём минимальную ширину. Тогда
   таблица становится шире экрана, включается горизонтальная прокрутка —
   и читать можно. Прокрутка честнее, чем нечитаемый столбик. */
.u-cell-text { min-width: 14rem; }

/* Таблица, которую заведомо не втиснуть: числа и даты в несколько колонок.
   Ставим минимум на саму таблицу, чтобы колонки не слипались. */
.u-table-wide { min-width: 34rem; }

/* Полоски-подсказки, что блок можно листать вбок. Без них на телефоне
   не видно, что справа есть ещё колонки или вкладки. */
.u-scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.u-scroll-x::-webkit-scrollbar { height: 3px; }
.u-scroll-x::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,.18); border-radius: 3px;
}

/* Затухание у правого края прокручиваемых вкладок — иначе последняя
   вкладка просто обрывается на краю экрана и выглядит как сломанная
   вёрстка, а не как «листай дальше». Только на узких экранах: на
   десктопе вкладки помещаются целиком. */
.u-tabs-fade { position: relative; }
.u-tabs-fade::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0;
  width: 28px; pointer-events: none;
  background: linear-gradient(to right, rgba(255,255,255,0), var(--u-surface) 70%);
}
@media (min-width: 768px) {
  .u-tabs-fade { border-radius: 0.75rem; overflow: hidden; }
  .u-tabs-fade::after { display: none; }
}

/* --- Таблица → карточки на телефоне ----------------------------------
   Горизонтальная прокрутка работает, но листать вбок неудобно: владелец
   попросил разложить строку в несколько рядов. Ниже 768px строка таблицы
   становится карточкой, а каждая ячейка — парой «подпись: значение».

   Подпись берётся из data-label ячейки (её проставляет шаблон по своему
   же <th>) — иначе после исчезновения шапки непонятно, что за число
   перед тобой.

   Ячейка без data-label выводится во всю ширину без подписи: так ведут
   себя колонки действий (кнопка «удалить») и колонки-иконки, которым
   подпись не нужна. */
@media (max-width: 767px) {
  table.u-stack { display: block; min-width: 0; }
  table.u-stack thead { display: none; }
  table.u-stack tbody { display: block; }

  table.u-stack tr {
    display: block;
    border: 1px solid var(--u-line, var(--u-border));
    border-radius: 10px;
    padding: 10px 12px;
    margin: 0 0 8px;
    background: var(--u-surface);
  }
  table.u-stack tr:last-child { margin-bottom: 0; }

  table.u-stack td {
    display: grid;
    grid-template-columns: minmax(6.5rem, 38%) 1fr;
    gap: 10px;
    align-items: baseline;
    padding: 3px 0 !important;
    border: 0 !important;
    text-align: left !important;
    white-space: normal !important;
    min-width: 0 !important;
    overflow-wrap: anywhere;
  }
  /* Элементы grid по умолчанию не ужимаются ниже своего содержимого
     (min-width:auto). Из-за этого раскрывающиеся заметки <details> в
     колонке «Комментарий» распирали карточку на 100px за край экрана. */
  /* !important здесь оправдан: у части ячеек ширина задана инлайновым
     стилем (например max-width:330px у обрезанной заметки в платежах),
     а инлайн побеждает таблицу стилей. Тот стиль писался под широкую
     таблицу и в карточке распирал её на 120px за край экрана. */
  table.u-stack td * { min-width: 0 !important; max-width: 100% !important; }
  table.u-stack td :is(details, summary, span, div, p, a) {
    overflow-wrap: anywhere;
    white-space: normal !important;
  }

  table.u-stack td::before {
    content: attr(data-label);
    color: var(--u-muted, var(--u-muted));
    font-size: 12px;
    line-height: 1.45;
  }
  /* Ячейка без подписи (действия, иконки) — на всю ширину карточки. */
  table.u-stack td:not([data-label]) { display: block; }
  table.u-stack td:not([data-label]):empty { display: none; }

  /* Внутри карточек прокручивать нечего — гасим полосу у обеих обёрток,
     которые исторически используются в проекте (u-scroll-x и u-table-wrap). */
  .u-scroll-x:has(> table.u-stack),
  .u-table-wrap:has(> table.u-stack) { overflow-x: visible; }

  /* Минимальная ширина нужна была для прокрутки. В карточном режиме она
     наоборот распирает блок — снимаем адресно, чтобы не зависеть от
     порядка правил в файле. */
  table.u-stack.u-table-wide { min-width: 0; }
}

/* --- Заметки на карточках (аренда, байк, клиент) -------------------------
   Разметка — макрос `_notes_block.html`, смысл — `services/notes.py`.
   Классы `nt-*`, а не Tailwind: у Tailwind в проекте есть сборка
   (`tools/build_tailwind.sh`), и новый класс без пересборки молча не
   приезжает на живой сайт. Токены `--u-*` дают тёмную тему бесплатно. */
.nt-head { display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin-bottom:8px; }
.nt-title { margin:0; font-size:12.5px; font-weight:600; letter-spacing:.04em;
  text-transform:uppercase; color:var(--u-muted); }
.nt-list { display:flex; flex-direction:column; gap:8px; margin:0; padding:0; list-style:none; }
.nt-item { padding:9px 11px; border:1px solid var(--u-border); border-radius:var(--u-r-md);
  background:var(--u-surface); }
/* Заметка — то, что человек набрал руками: переносы строк в ней значимы
   («второй контакт» и «отдал шлем» — два разных факта). `pre-line` их
   сохраняет, но не превращает текст в моноширинную простыню. */
.nt-body { font-size:13.5px; line-height:1.45; color:var(--u-text); white-space:pre-line;
  overflow-wrap:anywhere; }
.nt-meta { display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:5px;
  font-size:11.5px; color:var(--u-faint); }
/* Заметка из соседней карточки: видно, но чуть тише — чтобы не путать
   «записано здесь» с «записано у байка». */
.nt-item--borrowed { background:var(--u-grey-bg); border-style:dashed; }
.nt-del { margin-left:auto; }
.nt-del-btn { background:none; border:0; padding:0; font:inherit; font-size:11.5px;
  color:var(--u-faint); cursor:pointer; }
.nt-del-btn:hover { color:var(--u-red-fg, var(--u-red)); text-decoration:underline; }
.nt-form { margin-top:10px; }
.nt-input { min-height:56px; }
.nt-form-row { display:flex; align-items:center; justify-content:space-between; gap:10px;
  flex-wrap:wrap; margin-top:6px; }
