/* ТОП-ТОЗА. Оформление — как ФинРепорт: светлый фон, белые карточки со
   скруглением, зелёный акцент, тонкие линии, шрифт Inter.
   Сначала телефон (цех и дорога), потом компьютер.

   Два правила, которые не отменяет никакая перекраска:
   1) цвет несёт смысл — красный это тревога, зелёный «готово», янтарный «ждёт»;
   2) у мойщика мокрые руки, у водителя одна рука на телефоне: кнопки на
      телефоне не уменьшаются, какой бы мелкой ни была вёрстка на компьютере. */
:root {
  color-scheme: light;
  /* палитра ФинРепорта */
  --em: #00B956;            /* главный акцент: действие, выбранное, «готово» */
  --em-dark: #00A04A;
  --em-soft: rgba(0,185,86,.12);
  --blue: #2563EB;          /* ссылки и второстепенные действия */
  --blue-dark: #1D4ED8;
  --link: #2563EB;
  --text: #16192A;
  --muted: #667085;        /* 4,8:1 на белом: читается на солнце и за мокрым стеклом */
  --line: #EAEDF3;
  --bg: #F4F6F9;
  --panel: #FFFFFF;
  --nav-bg: rgba(255, 255, 255, .96);
  --red: #F0455A;
  --green: #00B956;
  --amber: #F59E0B;
  --gold-bg: #FEF3C7;
  --gold-ink: #92400E;
  --font: Inter, "Golos Text", -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
  --radius: 16px;
  --radius-sm: 10px;
  --shadow: 0 1px 2px rgba(16,24,40,.05), 0 1px 3px rgba(16,24,40,.04);
  --shadow-md: 0 10px 30px -8px rgba(16,24,40,.12);
  --nav: 58px;
  --head-h: 48px;           /* высота шапки: её же знает липкий поиск */
  --ease-out: cubic-bezier(.23, 1, .32, 1);

  /* ---- шкала текста ----
     Одна роль — один размер. До неё заголовок блока встречался шестью
     размерами (18, 17, 16, 15, 14, 13), крупное число — четырьмя
     (26, 24, 20, 17), подпись — тремя. Глаз читает такой разнобой как
     неряшливость, даже когда не может назвать причину.
     Роль, а не размер: «заголовок карточки», а не «пятнадцать пикселей».
     Понадобится крупнее — меняем здесь, и меняется везде разом */
  --t-page: 20px;      /* заголовок экрана: «Сводка», «Заказы» */
  --t-group: 12px;     /* заголовок группы блоков, ПРОПИСНЫМИ: «ПОКАЗАТЕЛИ» */
  --t-card: 15px;      /* заголовок карточки: «Расходы по статьям» */
  --t-big: 26px;       /* главное число экрана: «259 600 сом» */
  --t-val: 17px;       /* обычное число в карточке */
  --t-body: 14px;      /* основной текст, строки таблиц */
  --t-sub: 13px;       /* подпись под строкой, пояснение */
  --t-cap: 12px;       /* метка над числом, мелкая подпись */
  --t-micro: 11px;     /* единицы, служебные пометки */
  --w-bold: 700;
  --w-semi: 600;
  --w-mid: 500;
  --track-caps: .06em; /* разрядка для ПРОПИСНЫХ: без неё они слипаются */
  /* ---- цвета, которые раньше стояли в правилах числами ----
     Значения ТЕ ЖЕ, что были: светлая тема не изменилась ни на оттенок.
     Вынесены ради тёмной темы — зашитый белый фон остался бы белым пятном */
  --panel-2: #FFFFFF;      /* поверхность: карточка, лист, шапка */
  --on-accent: #FFFFFF;    /* текст на цветной кнопке */
  --line-2: #DDE1E9;
  --line-3: #D7DDE7;
  --line-4: #F1F3F8;
  --muted-2: #475467;
  --red-2: #D62B42;
  --bad-bg: #FEF2F2;
  --bad-bg-2: #FEE2E2;
  --bad-ink: #991B1B;
  --bad-line: #FCA5A5;
  --ok-bg: #ECFDF3;
  --ok-bg-2: #D1FAE5;
  --ok-bg-3: #E8F6EC;
  --ok-bg-4: #F6FBF8;
  --ok-ink: #065F46;
  --ok-ink-2: #2E7D32;
  --ok-line: #C9E6D2;
  --ok-line-2: #A7F3D0;
  --green-2: #0AC463;
  --warn-line: #FDE68A;
  --bg-2: #EDF1F6;
  --bg-3: #EEF0F3;
  --bg-soft: #F8FAFC;
  --ink: #16181D;
}
/* ===== Тёмная тема =====
   Берётся в двух случаях: человек выбрал её сам (data-theme="dark") или
   выбрал «Системную» (атрибута нет), а система тёмная. data-theme="light"
   держит светлую даже при тёмной системе: выбор человека сильнее системы.

   Зелёный и красный осветлены. Исходные #00B956 и #F0455A на тёмном фоне
   дают контраст ниже нормы, и «должен 2400» читалось бы хуже соседнего
   обычного текста — то есть тревожное стало бы незаметнее спокойного. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --text: #ECEEF5;
    --muted: #99A2B7;
    --muted-2: #B6BDCE;
    --bg: #12151F;
    --bg-2: #1E2232;
    --bg-3: #1E2232;
    --bg-soft: #161A26;
    --panel: #1A1E2C;
    --nav-bg: rgba(26, 30, 44, .96);
    --panel-2: #1A1E2C;
    --line: #2A3042;
    --line-2: #343B50;
    --line-3: #343B50;
    --line-4: #2A3042;
    --em: #19D06E;
    --em-dark: #14B85F;
    --em-soft: rgba(25,208,110,.16);
    --green: #19D06E;
    --green-2: #19D06E;
    --red: #FF6B7E;
    --red-2: #FF6B7E;
    --amber: #FBBF24;
    --blue: #7FA8FF;
    --blue-dark: #6E99F5;
    --link: #7FA8FF;
    --ok-bg: #12301F;
    --ok-bg-2: #12301F;
    --ok-bg-3: #12301F;
    --ok-bg-4: #141B24;
    --ok-ink: #7EE8AE;
    --ok-ink-2: #7EE8AE;
    --ok-line: #1F4C33;
    --ok-line-2: #1F4C33;
    --bad-bg: #3A1D22;
    --bad-bg-2: #4A2127;
    --bad-ink: #FFB4BD;
    --bad-line: #6B2B35;
    --warn-line: #6B5420;
    --gold-bg: #3A2F12;
    --gold-ink: #F5D98B;
    --ink: #0B0D12;
    --shadow: 0 1px 2px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
    --shadow-md: 0 12px 34px -8px rgba(0,0,0,.65);
  }
}
:root[data-theme="dark"] {
    color-scheme: dark;
    --text: #ECEEF5;
    --muted: #99A2B7;
    --muted-2: #B6BDCE;
    --bg: #12151F;
    --bg-2: #1E2232;
    --bg-3: #1E2232;
    --bg-soft: #161A26;
    --panel: #1A1E2C;
    --nav-bg: rgba(26, 30, 44, .96);
    --panel-2: #1A1E2C;
    --line: #2A3042;
    --line-2: #343B50;
    --line-3: #343B50;
    --line-4: #2A3042;
    --em: #19D06E;
    --em-dark: #14B85F;
    --em-soft: rgba(25,208,110,.16);
    --green: #19D06E;
    --green-2: #19D06E;
    --red: #FF6B7E;
    --red-2: #FF6B7E;
    --amber: #FBBF24;
    --blue: #7FA8FF;
    --blue-dark: #6E99F5;
    --link: #7FA8FF;
    --ok-bg: #12301F;
    --ok-bg-2: #12301F;
    --ok-bg-3: #12301F;
    --ok-bg-4: #141B24;
    --ok-ink: #7EE8AE;
    --ok-ink-2: #7EE8AE;
    --ok-line: #1F4C33;
    --ok-line-2: #1F4C33;
    --bad-bg: #3A1D22;
    --bad-bg-2: #4A2127;
    --bad-ink: #FFB4BD;
    --bad-line: #6B2B35;
    --warn-line: #6B5420;
    --gold-bg: #3A2F12;
    --gold-ink: #F5D98B;
    --ink: #0B0D12;
    --shadow: 0 1px 2px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
    --shadow-md: 0 12px 34px -8px rgba(0,0,0,.65);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* Скрытое — скрыто. Браузер прячет [hidden] слабым правилом display:none, и
   любой наш класс с display:flex его перебивает: так на экране входа висела
   пустая рамка «Приложение для Android», хотя файл не выложен */
[hidden] { display: none !important; }
html, body { height: 100%; }
body { margin: 0; font: 15px/1.45 var(--font); color: var(--text); font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(900px 420px at 85% -10%, rgba(0,185,86,.055), transparent 60%),
    radial-gradient(700px 380px at -10% 30%, rgba(37,99,235,.04), transparent 55%),
    var(--bg);
  background-attachment: scroll; }
a { color: var(--link); text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
svg { display: block; }
.wrap { max-width: 760px; margin: 0 auto; background: var(--panel); min-height: 100%;
  padding-bottom: calc(var(--nav) + env(safe-area-inset-bottom) + 16px); }

/* ---------- шапка ---------- */
.head { position: sticky; top: 0; z-index: 5; background: var(--panel);
  padding-top: env(safe-area-inset-top); box-shadow: inset 0 -1px 0 var(--line); }
.top { display: flex; align-items: center; gap: 12px; padding: 10px 16px; min-height: var(--head-h); }
.top .ttl { flex: 1; text-align: center; font-size: 14px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; }
.top .side { min-width: 64px; display: flex; white-space: nowrap; }
.top .side.r { justify-content: flex-end; }
.ico { color: var(--link); background: none; border: 0; padding: 4px; cursor: pointer; font-size: 15px; }
/* Телефон: в цеху жмут мокрым пальцем — цель не меньше 44 точек (обход
   бригадиром 08.11.2026: «Обновить», сканер, «Назад» были по 30). Отрицательный
   отступ сверху и снизу держит прежнюю высоту шапки */
body:not(.pc-body) .ico { min-height: 44px; margin-top: -7px; margin-bottom: -7px;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
/* Ширину 44 — только значкам: у текстовых кнопок («Без бирки», «＋ Новый»)
   своя ширина больше, а заданная 44 позволяла сжать их и наложить текст на
   соседнюю кнопку (проверка 08.11.2026) */
body:not(.pc-body) .ico.obnovit, body:not(.pc-body) #skan { min-width: 44px; }
/* В шапке «Обновить» занимает в строке столько же, сколько при 30 (34 с
   отступом): лишнее уходит в пустой край шапки справа. Иначе на 320–360
   точках обрезались заголовки «Сотрудники», «Экипажи», «Клиенты» */
body:not(.pc-body) .top .ico.obnovit { margin-left: 0; margin-right: -10px; }
/* «Обновить» в шапке: крутится, пока идёт обновление, — видно, что нажатие
   принято, и второй раз жать незачем */
.ico.obnovit { display: inline-flex; align-items: center; margin-left: 4px; }
.ico.obnovit.idet svg { animation: obnovit-krug .8s linear infinite; }
/* Экраны без шапки (касса, деньги экипажа, заработок, сводка) — кнопка в
   правом верхнем углу их верхнего блока */
.sky { position: relative; }
.sky > .ico.obnovit { position: absolute; right: 10px; top: calc(8px + env(safe-area-inset-top)); margin: 0; }
/* Цель на телефоне 44, а значок — там же, где был при 30: середина не сдвинулась */
body:not(.pc-body) .sky > .ico.obnovit { right: 3px; top: calc(1px + env(safe-area-inset-top)); }
@keyframes obnovit-krug { to { transform: rotate(360deg); } }

/* Шапка с главными числами. В ФинРепорте это белая плитка с зелёным
   акцентом, а не цветная заливка: на солнце читается лучше */
.sky { background: var(--panel); color: var(--text);
  padding: 16px 16px 18px; padding-top: calc(14px + env(safe-area-inset-top));
  box-shadow: inset 0 -1px 0 var(--line); }
.sky .who { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; font-weight: 600; }
.sky .name { font-size: 26px; font-weight: 700; margin-top: 4px; letter-spacing: -.03em; color: var(--em); }
.figs { display: flex; margin-top: 16px; gap: 8px; }
/* min-width: 0 — плитки ряда одной ширины, длинная цифра их не раздвигает:
   она уменьшается сама (уместитьЦифры в app.js) */
.figs > div { flex: 1 1 0; min-width: 0; text-align: center; background: var(--bg-2); border: 1px solid var(--line-3);
  border-radius: var(--radius-sm); padding: 10px 6px; }
.figs .label { font-size: 11px; color: var(--muted); }
.figs .value { font-size: 20px; font-weight: 700; margin-top: 2px; letter-spacing: -.02em; }

/* ---------- поиск ---------- */
.search { padding: 10px 16px; position: sticky; top: calc(var(--head-h) + env(safe-area-inset-top)); z-index: 4;
  background: var(--panel); box-shadow: inset 0 -1px 0 var(--line); }
.search input { width: 100%; height: 44px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); padding: 0 12px; outline: none; font-size: 16px; transition: border-color .15s, box-shadow .15s; }
.search input:focus { border-color: var(--em); box-shadow: 0 0 0 3px var(--em-soft); }

/* ---------- строки ---------- */
.group { font-size: 17px; font-weight: 600; padding: 18px 16px 6px; display: flex; align-items: baseline; gap: 8px;
  letter-spacing: -.01em; }
.group small { font-size: 13px; color: var(--muted); font-weight: 400; }
/* Роль внутри точки. Без неё шестнадцать человек шли одной лентой, и роль
   повторялась в каждой строке; теперь она названа один раз и видно, где
   кончается цех и начинаются водители */
.subgroup { font-size: 13px; font-weight: 600; color: var(--muted); padding: 14px 16px 4px;
  display: flex; align-items: baseline; gap: 6px; }
.subgroup small { font-size: 12px; font-weight: 400; }
/* Разделитель между строками чуть темнее линии ФинРепорта: в цеху (влажное
   стекло, блики) и на солнце волосяная #EAEDF3 на белом пропадает, и соседние
   заказы сливаются в одно полотно */
.row { display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  box-shadow: inset 0 -1px 0 var(--line-2); }
a.row, button.row { color: inherit; width: 100%; text-align: left; background: none; border: 0; cursor: pointer; }
a.row:active, button.row:active { background: var(--em-soft); }
.row .body { flex: 1; min-width: 0; }
.row .ttl { font-size: 15px; }
.row .sub { color: var(--muted); font-size: 13px; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; }
.row .val { font-weight: 600; white-space: nowrap; text-align: right; }
/* Строка места с «изменить» и «убрать»: на телефоне кнопки отнимали у текста всё, вес обрезался до «1…» */
@media (max-width: 600px) {
  .row.place-acts { flex-wrap: wrap; }
  .row.place-acts .body { flex: 1 0 100%; }
  .row.place-acts .val { margin-right: auto; }
}
/* Число с единицей («40 м²», «3 кг») не разрываем по строкам: «40» в конце одной, «м²» в начале другой */
.nw { white-space: nowrap; }
/* Размер места — второй строкой под названием, тем же цветом, что и название: его ищут глазами */
.sub.place-size { color: var(--text); font-size: 15px; }
.row .val small { display: block; font-weight: 400; color: var(--muted); font-size: 12px; }
.chev { color: var(--muted); flex: none; }
.empty { padding: 32px 16px; text-align: center; color: var(--muted); }
.muted { color: var(--muted); }
.off { opacity: .5; }

/* Значки состояния. Три разных сообщения, а не три оттенка:
     красный — «вмешайся», янтарный — «ждёт, но идёт», серый — просто пометка.
   Спокойные делаем мягкими (светлая заливка, тёмный текст — читаются и на
   солнце, и в печати), а красный оставляем громким: на доске цеха и на улице
   его должно выхватывать боковым зрением */
.pill { display: inline-block; border-radius: 999px; padding: 2.5px 9px; font-size: 11px; font-weight: 600;
  letter-spacing: .1px; color: var(--muted-2); background: var(--line); vertical-align: 1px; }
.pill.green { background: var(--ok-bg-2); color: var(--ok-ink); }
.pill.grey { background: var(--line); color: var(--muted-2); }
.pill.amber { background: var(--gold-bg); color: var(--gold-ink); }
.pill.red { background: var(--red-2); color: var(--on-accent); }
/* Значок на заливке своего цвета становится сплошным — иначе «🟠 дольше 2 суток 7»
   читается так, будто семёрка часть названия, а не счётчик дел */
.row.warn .pill.amber, details.alert.amber > summary .pill.amber { background: var(--amber); color: var(--on-accent); }
.row.calm .pill.green, .row.done .pill.grey { background: var(--panel); }

/* Строка-заголовок группы прав в форме роли. Правило живёт ЗДЕСЬ, а не в
   pc.css под `.pc`: лист с формой рисуется в body, вне `.pc`, и правило
   с этим префиксом до него не достаёт. Цвет букв задаём рядом с фоном:
   раньше фон был зашит светлым (var(--bg2) не существует, работал
   запасной #f6f6f6), а цвет наследовался от темы — в тёмной теме
   выходило белое по белому, семь строк подряд */
.grphead { background: var(--bg-soft); color: var(--text); }

.kv { display: flex; gap: 12px; padding: 10px 16px; box-shadow: inset 0 -1px 0 var(--line); }
.kv .k { width: 120px; color: var(--muted); flex: none; }
.kv .v { flex: 1; min-width: 0; word-break: break-word; }

/* ---------- кнопки и формы ---------- */
/* Кнопки как в ФинРепорте — зелёный градиент и мягкая тень. Высота 44 остаётся:
   её держат мокрые руки мойщика и одна рука водителя, а не красота */
.btn { display: inline-flex; align-items: center; justify-content: center;
  height: 44px; padding: 0 18px; border-radius: var(--radius-sm); border: 0;
  background: linear-gradient(180deg, var(--green-2), var(--em)); color: var(--on-accent);
  font-weight: 600; cursor: pointer; transition: transform 120ms var(--ease-out), box-shadow .15s;
  box-shadow: 0 1px 2px rgba(0,140,64,.3), inset 0 1px 0 rgba(255,255,255,.18); }
.btn:active { transform: scale(.97); }
.btn.ghost { background: var(--panel); color: var(--text); border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(16,24,40,.04); }
/* Опасное действие не кричит: громким на экране должно быть то, что требует
   вмешательства, а не кнопка, по которой и так нажимают осознанно */
.btn.danger { background: var(--bad-bg-2); color: var(--bad-ink); box-shadow: inset 0 0 0 1.5px var(--bad-line); }
.btn.full { width: 100%; }
.btn:disabled { opacity: .5; }
.actions { display: flex; gap: 8px; flex-wrap: wrap; padding: 12px 16px; }
/* Кнопки карточки заказа на телефоне — ровной сеткой; на компьютере у
   карточки своя ширина, и растянутые на пол-экрана кнопки там ни к чему */
body:not(.pc-body) .actions.acts2 { display: grid; grid-template-columns: 1fr 1fr; }
body:not(.pc-body) .actions.acts2 .btn { min-width: 0; padding: 0 10px; }
body:not(.pc-body) .actions.acts2 .btn.wide { grid-column: 1 / -1; }
.row.swrow { flex-wrap: wrap; }
.actions.swbtns { padding: 0; flex: 1 0 100%; display: grid; grid-template-columns: 1fr 1fr; }
.actions.swbtns .btn { min-width: 0; padding: 0 8px; line-height: 1.15; text-align: center; }
.link { background: none; border: 0; color: var(--link); padding: 0; cursor: pointer; }
.link.red { color: var(--red); }

.field { padding: 8px 16px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 4px; }
.field input, .field select, .field textarea { width: 100%; min-height: 44px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 8px 12px; background: var(--panel-2); font-size: 16px; outline: none; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--em);
  box-shadow: 0 0 0 3px var(--em-soft); }
.field textarea { min-height: 72px; resize: vertical; }
.field .snimok { gap: 8px; cursor: pointer; }
.hint { font-size: 12px; color: var(--muted); padding: 0 16px; }

/* ---------- лист снизу (форма поверх экрана) ---------- */
.sheet-bg { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 20; display: flex;
  align-items: flex-end; justify-content: center; animation: fade 180ms var(--ease-out); }
.sheet { background: var(--panel); width: 100%; max-width: 560px; max-height: 92vh; overflow: auto;
  border-radius: 16px 16px 0 0; padding: 8px 0 calc(16px + env(safe-area-inset-bottom));
  animation: up 260ms var(--ease-out); }
.sheet h3 { margin: 8px 16px 4px; font-size: 18px; }
.sheet .err { color: var(--red); padding: 4px 16px; font-size: 14px; }
/* Низ листа на телефоне: кнопки поровну во всю ширину — «Сохранить» и
   «Отмена» стояли двумя маленькими кнопками слева, в главную целились.
   Если кнопок нечётно, первая (главная) занимает ряд целиком */
body:not(.pc-body) .sheet .actions.foot { display: grid; grid-template-columns: 1fr 1fr; }
body:not(.pc-body) .sheet .actions.foot > .btn { min-width: 0; padding: 0 10px; }
body:not(.pc-body) .sheet .actions.foot > .btn:first-child:nth-last-child(odd) { grid-column: 1 / -1; }
/* Код заказа — тот, что написан на ковре. Моноширинный нарочно: цифры
   одинаковой ширины легче сверять с надписью на изнанке, а в обычном шрифте
   единица узкая и строка «пляшет» */
.code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .92em; letter-spacing: .02em; color: var(--muted); }
.row .ttl .code, .ttl .code { color: var(--text); font-weight: 600; }

/* Наклейка показывается ПОВЕРХ окна упаковки, своим слоем. Нельзя делать
   её обычным .sheet-bg: функция sheet() сносит все прежние окна, и показ
   наклейки убил бы окно со списком ковров — бригадир нажал «печать», увидел
   наклейку, закрыл, а галочек уже нет */
.label-bg { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 30; display: flex;
  align-items: center; justify-content: center; padding: 16px; animation: fade 180ms var(--ease-out); }
.label-bg .box { background: var(--panel); border-radius: 14px; max-width: 420px; width: 100%;
  max-height: 92vh; overflow: auto; padding: 14px 16px calc(14px + env(safe-area-inset-bottom)); }
/* Кнопка печати в строке списка: прижата вправо, не растягивает строку */
.pechat { flex: none; margin-left: auto; padding: 4px 8px; }

@keyframes fade { from { opacity: 0 } }
@keyframes up { from { transform: translateY(30px); opacity: 0 } }
@media (min-width: 700px) { .sheet-bg { align-items: center; } .sheet { border-radius: 16px; } }
/* Лист с таблицей: права роли — 44 строки на 5 столбцов, и в 560 точках
   названия разделов переносятся по три строки. На телефоне остаётся
   во всю ширину, как и остальные листы */
.sheet.wide { max-width: 980px; }

/* Плашка «нет сети» (offline.js): сверху, во всю ширину, не закрывает
   экран. Красная — когда что-то не прошло и водителю надо звонить */
.offbar { position: sticky; top: 0; z-index: 25; display: block; width: 100%; border: 0;
  padding: 8px 16px; font: inherit; font-size: 13px; text-align: center; cursor: pointer;
  background: var(--gold-bg); color: var(--gold-ink); }
.offbar.bad { background: var(--bad-bg-2); color: var(--bad-ink); }

/* ---------- нижние вкладки ---------- */
nav.tabs { position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; background: var(--nav-bg);
  backdrop-filter: blur(10px); box-shadow: 0 -1px 0 var(--line);
  padding-bottom: env(safe-area-inset-bottom); }
nav.tabs .in { max-width: 760px; margin: 0 auto; display: flex; height: var(--nav); }
nav.tabs a { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; font-size: 12px; color: var(--muted); }
nav.tabs a.on { color: var(--em); }
/* Значок — свой рисунок, не эмодзи: размер задаём мы, а цвет он берёт у
   ссылки (currentColor), и выбранная вкладка зеленеет целиком. 22 точки чуть
   больше прежних 20: рисунок из тонких линий выглядит легче цветного эмодзи
   и в прежнем размере терялся */
nav.tabs a .g { line-height: 1; }
nav.tabs a .g svg { width: 22px; height: 22px; display: block; }
/* Кружок непрочитанного поверх значка чата. Приклеен к значку, а не к подписи:
   подписи у вкладок разной длины, и кружок у них гулял бы по строке */
nav.tabs a .g { position: relative; display: inline-block; }
.navdot { position: absolute; top: -4px; left: 11px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 999px; background: var(--red-2); color: var(--on-accent);
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
  box-sizing: border-box; }

.toast { position: fixed; left: 50%; bottom: calc(var(--nav) + 20px + env(safe-area-inset-bottom));
  transform: translateX(-50%); background: var(--ink); color: var(--on-accent); padding: 10px 16px; border-radius: 10px;
  z-index: 30; font-size: 14px; max-width: 90vw; animation: fade 180ms; }
.toast.err { background: var(--red); }

table.hist { width: 100%; border-collapse: collapse; font-size: 14px; }
table.hist td, table.hist th { padding: 8px 16px; text-align: left; box-shadow: inset 0 -1px 0 var(--line); }
table.hist th { font-size: 12px; color: var(--muted); font-weight: 500; }
table.hist td.n { text-align: right; white-space: nowrap; }
table.hist th.n { text-align: right; }
table.hist.vol { font-size: 13px; }
table.hist.vol td, table.hist.vol th { padding: 8px 3px; }
table.hist.vol td:first-child, table.hist.vol th:first-child { padding-left: 12px; white-space: nowrap; }
table.hist.vol td:last-child, table.hist.vol th:last-child { padding-right: 12px; }
/* «без замера: N» переносится, а не раздвигает столбец даты */
table.hist.vol td:first-child .muted { white-space: normal; }
table.hist.vol tr:last-child th { font-size: 14px; font-weight: 600; color: var(--text); }

/* Переключатель периода в сводке: выбранное всюду зелёное — один цвет выбора */
.seg { display: flex; border-radius: var(--radius-sm); overflow: hidden; margin: 14px 0 0; border: 1px solid var(--line); }
.seg button { flex: 1; height: 38px; border: 0; font: inherit; font-size: 14px; cursor: pointer;
  background: var(--panel); color: var(--muted); border-right: 1px solid var(--line); }
.seg button:last-child { border-right: 0; }
.seg button.on { background: var(--em); color: var(--on-accent); font-weight: 600; }

/* Фильтр по этапу в заказах водителя: лента фишек со счётчиками.
   Высота 44 — водитель жмёт одной рукой, часто на ходу и на холоде */
.myfilter { display: flex; gap: 8px; overflow-x: auto; padding: 10px 16px 2px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.myfilter::-webkit-scrollbar { display: none; }
.fchip { flex: none; height: 44px; padding: 0 16px; border-radius: 22px; border: 1px solid var(--line);
  background: var(--panel); font: inherit; font-size: 14px; color: var(--text); cursor: pointer; white-space: nowrap; }
.fchip small { color: var(--muted); font-size: 13px; margin-left: 4px; }
.fchip.on { background: var(--em); border-color: var(--em); color: var(--on-accent); font-weight: 600; }
.fchip.on small { color: rgba(255,255,255,.8); }

/* Снимки места: пятна и повреждения */
.photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; margin-bottom: 12px; }
.photos figure { margin: 0; }
.photos img { width: 100%; height: 120px; object-fit: cover; border-radius: var(--radius-sm); display: block; background: var(--bg-3); }
.photos figcaption { font-size: 12px; color: var(--muted); margin-top: 4px; line-height: 1.35; }

/* Карточка ФинРепорта: белое поле со скруглением и мягкой тенью.
   На телефоне применяем к «листам» и выделенным блокам */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden; }
.card + .card { margin-top: 12px; }

/* Строки-состояния. Раньше цвет писали прямо в разметке шестнадцатеричным
   кодом, и перекраска до них не доходила. Теперь состояние — это класс */
.row.alarm { background: var(--bad-bg); box-shadow: inset 3px 0 0 var(--red), inset 0 -1px 0 var(--line-2); }
.rq-stale { opacity: .5; }
.rq-similar { margin: 8px 16px; padding: 10px 12px; background: var(--gold-bg); border: 1px solid var(--warn-line); border-radius: 10px; font-size: 14px; }
.rq-similar .ttl { font-weight: 600; margin-bottom: 6px; }
.rq-similar-row { margin-bottom: 6px; }
.rq-similar .sub { font-size: 13px; opacity: .85; }
.row.warn { background: var(--gold-bg); box-shadow: inset 3px 0 0 var(--amber), inset 0 -1px 0 var(--line-2); }
.row.calm { background: var(--ok-bg); box-shadow: inset 3px 0 0 var(--em), inset 0 -1px 0 var(--line-2); }
.row.done { background: var(--bg); box-shadow: inset 3px 0 0 var(--line), inset 0 -1px 0 var(--line-2); }

/* Раскрывающийся блок тревоги: заголовок цветной, строки внутри белые */
details.alert > summary { padding: 12px 16px; cursor: pointer; font-weight: 600; list-style: none; }
details.alert > summary::-webkit-details-marker { display: none; }
details.alert.red > summary { background: var(--bad-bg); box-shadow: inset 3px 0 0 var(--red); }
details.alert.amber > summary { background: var(--gold-bg); box-shadow: inset 3px 0 0 var(--amber); }
details.alert .row { background: var(--panel); }
details.alert .row.alarm, a.row.alarm:active { background: var(--bad-bg); }
details.alert .row.warn, a.row.warn:active { background: var(--gold-bg); }
details.alert .row.calm, a.row.calm:active { background: var(--ok-bg); }
details.alert .row.done, a.row.done:active { background: var(--bg); }
/* Отклик у цветной строки — потемнением, а не подменой цвета */
a.row.alarm:active, a.row.warn:active, a.row.calm:active, a.row.done:active { filter: brightness(.96); }
/* В кассе ссылка висит на внутреннем блоке строки, и нажатие не отзывалось
   ничем: оператор жал второй раз, не поняв, что первое нажатие прошло */
.row:has(> a.body:active) { background: var(--em-soft); }

/* Галочка в списках: главный элемент доски цеха и листов выдачи.
   Мокрый или замёрзший палец промахивается по 24 пикселям, поэтому 28
   с запасом по месту вокруг — это та же забота, что и высота кнопок 44 */
input.tick { width: 28px; height: 28px; accent-color: var(--em); margin: 2px; }
label.row:has(input.tick) { cursor: pointer; }
label.row:active { background: var(--em-soft); }

/* ---------- чат ---------- */
/* Отступ снизу больше обычного: под лентой стоит строка ввода, и без него
   последнее сообщение пряталось бы под ней — а читают всегда последнее */
/* Лента прокручивается сама, а не вместе со страницей. Высоту ей задаёт
   chatFitBox() по месту — по тому, где лента началась и где стоит строка
   ввода. Пока прокручивалась страница, «перейти к последнему сообщению» не
   работало вовсе: box.scrollTop у неподвижного блока ничего не меняет, и
   человек открывал переписку на самом старом сообщении */
.chatbox { padding: 8px 12px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.msg { display: flex; margin: 6px 0; }
.msg.mine { justify-content: flex-end; }
.bub {
  max-width: 78%; padding: 8px 12px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line);
  word-break: break-word;
}
/* Переносы строк сохраняем только внутри самого текста сообщения. Когда
   pre-wrap стоял на всём пузыре, он показывал ещё и отступы HTML-шаблона:
   пузырь на три строки занимал 279 точек вместо 82 */
.bub .txt { white-space: pre-wrap; }
.bub .sub { font-size: 12px; line-height: 1.3; }
.bub .sub b { font-size: 13px; }
.msg.mine .bub { background: var(--green-bg, var(--ok-bg-3)); border-color: var(--green, var(--ok-line)); }
.chatsend {
  position: fixed; left: 0; right: 0; bottom: 56px; display: flex; gap: 8px;
  padding: 8px 12px; background: var(--bg); border-top: 1px solid var(--line);
}
.chatsend input { flex: 1; min-width: 0; }
/* Кнопка «новые сообщения». Висит над строкой ввода, чтобы её видели, но не
   закрывает последние слова ленты: человек читает середину, и низ ему сейчас
   не нужен — нужен способ туда вернуться */
.newmsgs {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 126px;
  z-index: 5; border: 0; border-radius: 999px; padding: 7px 16px;
  background: var(--green, var(--ok-ink-2)); color: var(--on-accent); font: inherit; font-size: 13px;
  font-weight: 600; box-shadow: 0 2px 10px rgba(0,0,0,.18); cursor: pointer;
}
/* Разделитель дня в переписке. Серая плашка по центру, как в обычных
   мессенджерах: человек узнаёт её без объяснений */
.chatday { display: flex; justify-content: center; margin: 14px 0 8px; }
.chatday span { background: var(--line); color: var(--muted-2); border-radius: 999px;
  padding: 3px 12px; font-size: 11px; font-weight: 600; }
/* Неотправленное: красным, и это ссылка — нажатие посылает заново тем же
   ключом, так что второго сообщения не появится */
.msg .fail { color: var(--red-2); font-weight: 600; }
/* Подряд идущие сообщения одного человека идут вплотную, а между репликами
   разных людей отступ больше: именно этот перепад показывает, где сменился
   говорящий. При одинаковых отступах лента читается как список строк */
.msg.cont { margin-top: -3px; }
.msg + .msg:not(.cont) { margin-top: 12px; }
/* У продолжения срезан тот угол, которым пузырь «смотрит» на предыдущий: видно,
   что это одна речь, даже когда разницу в отступах не разглядеть */
.msg.cont .bub { border-top-left-radius: 6px; }
.msg.mine.cont .bub { border-top-left-radius: 14px; border-top-right-radius: 6px; }
/* Имя — над первым пузырём реплики и только в общей комнате. Цветом, а не
   жирным: в ленте из двух десятков сообщений жирный сам становится шумом */
.bub .who { font-size: 12px; font-weight: 600; color: var(--em-dark); margin-bottom: 2px; }
/* Галочки на своём сообщении: серая — записано, зелёные — дочитали. Класс не
   .tick: так зовут галочку-поле в списках цеха, и правило задело бы её */
.seen { white-space: nowrap; color: var(--muted); font-weight: 600; }
.seen.on { color: var(--em-dark); }
/* Кружок с инициалами в списке переписок: то же узнавание, что от аватара, и ни
   одного файла. Цвет выводится из имени — у человека он всегда один и тот же */
.ava { width: 42px; height: 42px; flex: 0 0 42px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  color: var(--on-accent); font-size: 15px; font-weight: 600; }
.ava.all { background: var(--muted-2); }
/* Черта между переписками начинается после кружка, а не от края экрана. Мелочь,
   но именно она отличает список людей от строк отчёта. Цвет тот же #DDE1E9, что
   у остальных строк: он нарочно темнее линии — в цеху волосяная на белом пропадает */
.row.chatrow { box-shadow: none; padding-bottom: 0; }
.row.chatrow .body { padding-bottom: 12px; box-shadow: inset 0 -1px 0 var(--line-2); }
.chatrow .line { display: flex; align-items: baseline; gap: 8px; }
.chatrow .line .ttl, .chatrow .line .sub { flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chatrow .when { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* ---- командная строка ⌘K ----
   Цвета только токенами: зашитый белый фон остался бы белым пятном в тёмной
   теме. Поверх всего (z-index выше листа): пока палитра открыта, она и есть
   экран, а переход её закрывает до смены адреса */
.cmdbg { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 30;
  display: flex; align-items: flex-start; justify-content: center; padding: 10vh 16px 16px; }
.cmdbox { background: var(--panel-2); width: 100%; max-width: 620px; border-radius: var(--radius);
  box-shadow: var(--shadow-md); overflow: hidden; display: flex; flex-direction: column; }
.cmdinp { border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--text);
  font: inherit; font-size: 17px; padding: 16px 18px; outline: none; width: 100%; }
.cmdlist { max-height: 52vh; overflow: auto; padding: 6px; }
.cmdrow { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%;
  background: transparent; border: 0; border-radius: var(--radius-sm); padding: 9px 12px;
  text-align: left; cursor: pointer; font: inherit; color: var(--text); }
.cmdrow:hover { background: var(--line-4); }
.cmdrow.on { background: var(--em-soft); }
.cmdt { font-size: 15px; }
.cmds { font-size: 13px; color: var(--muted); }
.cmdempty { padding: 18px; color: var(--muted); font-size: 14px; text-align: center; }
.cmdfoot { border-top: 1px solid var(--line); padding: 8px 14px; color: var(--muted); font-size: 12px; }

/* Метка ТЕСТОВОГО СТЕНДА (public/js/stand.js): плашка поверх страницы, сквозь
   неё можно нажимать — раскладку экранов она не трогает. Цвета — токенами
   предупреждения, чтобы в тёмной теме плашка оставалась читаемой */
.stand-dev {
  position: fixed; top: 6px; left: 50%; transform: translateX(-50%); z-index: 2147483000;
  pointer-events: none; max-width: calc(100vw - 24px);
  background: var(--gold-bg); color: var(--gold-ink); border: 2px solid var(--amber);
  border-radius: 999px; padding: 4px 14px; font: 600 12px/1.4 var(--font);
  text-align: center; box-shadow: var(--shadow-md);
}

/* Лист занят: что он делает, пока кнопка погашена. Без этого на плохой связи
   нажатие выглядело непринятым */
.sheet-busy { display: flex; align-items: center; gap: 8px; margin: 10px 16px 0; font-size: var(--t-sub); color: var(--muted); line-height: 1.35; }
.sheet-busy[hidden] { display: none; }
.sheet-busy::before { content: ''; flex: none; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--em); animation: sheet-busy-spin .8s linear infinite; }
@keyframes sheet-busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sheet-busy::before { animation: none; } }

/* Отметки «не забрал» в заявке: кто, почему, когда. Одинаковы на телефоне и на
   компьютере; цвета из палитры, чтобы читались и в тёмной теме */
.rq-fails { margin-top: 6px; display: flex; flex-direction: column; gap: 5px; }
.rq-fail { font-size: var(--t-sub); line-height: 1.35; color: var(--text); }
.rq-fail b { font-weight: var(--w-semi); }
.rq-times { color: var(--gold-ink); font-weight: var(--w-semi); }
.rq-why { font-size: var(--t-cap); color: var(--muted); line-height: 1.35; }

/* Меню действий заявки: в прежнем виде его нет, ссылки стоят в строке как обычно */
.btn.rq-dots, .rq-sheet-t, .rq-sheet-close { display: none; }
.rq-sheet:not(.sheet-bg), .rq-sheet:not(.sheet-bg) > .rq-sheet-list { display: contents; }

/* ===== Телефон директора (08.11.2026): у каждого раздела свой блок ===== */
/* --- [Д-СВОДКА] --- */
/* Сводка директора (телефон). Подписи плиток крупнее и темнее — 11px бледно-серым не читались */
html body:not(.pc-body) .sky.d-dash .who { font-size: 12px; }
html body:not(.pc-body) .sky.d-dash .figs .label { font-size: 13px; color: var(--text); }
/* Плитка «Тревог» листает к тревогам */
.sky.d-dash .d-jump { cursor: pointer; }
/* Кнопки периода — палец попадает (44px) */
html body:not(.pc-body) .sky.d-dash .seg button { height: 44px; }
/* Плашки этапов: ссылки — крупнее, чтобы попадать пальцем */
.d-stages { flex-wrap: wrap; gap: 6px; }
/* html.design-ios .pill (design-ios.css) сильнее простого .d-stages .pill — поднимаем вес */
html body:not(.pc-body) .d-stages .pill { font-size: 13px; }
html body:not(.pc-body) .d-stages a.pill { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; text-decoration: none; }
/* Строки точки: подпись слева, главная цифра справа, пояснение мелко под ней */
html body:not(.pc-body) #app .d-kv { align-items: center; color: inherit; text-decoration: none; }
html body:not(.pc-body) #app .d-kv .k { width: auto; flex: 1 1 auto; }
html body:not(.pc-body) #app .d-kv .v { flex: 0 1 auto; text-align: right; }
.d-kv .d-sub { font-size: 13px; color: var(--muted); font-weight: 400; }
a.d-kv { min-height: 44px; }
/* .group small красит серым сильнее простого класса — поднимаем вес */
.d-loss, .row .val.d-loss, .group small.d-loss, html body:not(.pc-body) .group small.d-loss { color: var(--red); }
/* Свёрнутые блоки (пустая точка, правки, средний м²): заголовок — нажимаемый */
details.d-pt > summary, details.d-fold > summary { list-style: none; cursor: pointer; }
details.d-pt > summary::-webkit-details-marker, details.d-fold > summary::-webkit-details-marker { display: none; }
details.d-pt > summary small, details.d-fold > summary small { flex: 1 1 auto; }
/* «Экипаж не отмечается»: кнопка звонка рядом с текстом */
a.body.d-body { color: inherit; text-decoration: none; }
.btn.d-call { flex: none; min-height: 44px; padding: 0 14px; display: inline-flex; align-items: center; }
/* Заказы: тревоги одной строкой «⚠ Тревог N ›», раскрываются на месте */
details.d-alfold > summary { list-style: none; cursor: pointer; min-height: 44px; }
details.d-alfold > summary::-webkit-details-marker { display: none; }
details.d-alfold[open] > summary .chev { transform: rotate(90deg); }
/* Настройки: переходы к группам и «подробнее» */
.d-jumps { flex-wrap: wrap; }
.d-jumps .btn { min-height: 44px; }
details.d-more > summary { list-style: none; cursor: pointer; }
/* .row .sub красит серым сильнее — поднимаем вес; высота 44px под палец */
.row details.d-more > summary.sub { color: var(--link); min-height: 44px; display: flex; align-items: center; padding: 0; margin: 0; }
details.d-more > summary::-webkit-details-marker { display: none; }
input.d-num { border: 1px solid var(--line); }
input.d-num.d-changed { border: 2px solid var(--amber); }
input.d-num.d-saved { border: 2px solid var(--green); box-shadow: 0 0 0 3px var(--ok-bg-2); }
/* Имя точки не рвём на две строки («9 / км»): пояснение уходит ниже */
.group.d-ptitle { flex-wrap: wrap; row-gap: 2px; }
.group.d-ptitle .d-pname { white-space: nowrap; }
/* --- [/Д-СВОДКА] --- */
/* --- [Д-ЗАКАЗЫ] --- */
/* Строка должника: справа крупно «долг N», мелко «из M» */
html body:not(.pc-body) .row .val.dolg-val .dolg { color: var(--red); }
/* Плитка долга в карточке выданного с недоплатой — красная, чтобы бросалась в глаза */
html.design-ios body:not(.pc-body) .figs > div.dolg-est,
html body:not(.pc-body) .figs > div.dolg-est { background: var(--bad-bg); }
html body:not(.pc-body) .figs > div.dolg-est .value,
html body:not(.pc-body) .figs > div.dolg-est .label { color: var(--red); }
/* «Позвонить» и «WhatsApp» под клиентом — две кнопки в пол-экрана */
html body:not(.pc-body) .actions.zv-btns { display: grid; grid-template-columns: 1fr 1fr; padding-top: 0; }
html body:not(.pc-body) .actions.zv-btns > .btn { min-width: 0; min-height: 44px; padding: 0 8px; text-decoration: none; }
/* «изменить» и «убрать» у места: крупнее и порознь, чтобы не промахнуться */
html body:not(.pc-body) .row > button.link[data-measure],
html body:not(.pc-body) .row > button.link[data-rmplace] { min-height: 44px; padding: 0 10px; flex: none; }
html body:not(.pc-body) .row > button.link[data-rmplace] { margin-left: 14px; }
html body:not(.pc-body) .sub > button.link[data-photos] { min-height: 40px; padding: 8px 0; }
/* Звонок в строке заявки — круглая кнопка 44×44 */
html.design-ios body:not(.pc-body) #app .rq-acts > .btn.rq-call,
html body:not(.pc-body) .rq-acts > .btn.rq-call { flex: 0 0 44px; width: 44px; min-width: 44px; height: 44px; padding: 0; border-radius: 22px; font-size: 18px; text-decoration: none; }
/* Замечание: «Разобрано» под текстом во всю ширину */
html body:not(.pc-body) .row.zm-row { flex-wrap: wrap; }
html body:not(.pc-body) .row.zm-row > .body { flex: 1 0 100%; }
html body:not(.pc-body) .row.zm-row > .btn { flex: 1 0 100%; margin-top: 8px; }
/* Готовые ответы в листе разбора — в ряд, по касанию */
.actions.zm-gotovo > .btn { flex: 1 1 auto; min-height: 44px; padding: 0 10px; }
/* Экран «Увезли»: кнопки под текстом строки, «отменить» — полноценная цель для пальца */
.row.uvz-row { flex-wrap: wrap; }
.row.uvz-row > .body { flex: 1 0 100%; }
.uvz-acts { display: flex; gap: 8px; flex: 1 0 100%; }
.uvz-acts > .btn { flex: 1 1 0; min-height: 44px; }
.uvz-itog { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; font-size: 13px; }
.uvz-itog.ok { color: var(--ok-ink); }
.uvz-itog.net { color: var(--bad-ink); }
.uvz-otmena { flex: none; min-height: 44px; padding: 0 4px; background: none; border: 0; color: var(--muted); font: inherit; text-decoration: underline; }
.uvz-nomer { display: inline-flex; align-items: center; min-height: 44px; padding-right: 8px; }
.uvz-den { flex: none; height: 44px; padding: 0 12px; border: 1px solid var(--line); border-radius: 22px; background: var(--panel); color: var(--text); font-size: 15px; }
/* --- [/Д-ЗАКАЗЫ] --- */
/* --- [Д-КАССА] --- */
/* Касса: подписи плиток крупнее (11px не читались на ходу) — только у кассы, не у всех .figs */
.figs.kassa-figs .label { font-size: 13px; }
/* «Сегодня» над плитками: плитки за день, крупная цифра — за все дни */
.sky .who.kassa-den { margin-top: 14px; }
.sky .figs.kassa-figs { margin-top: 6px; }
/* Итог «Дольше суток» — красным, как строка просрочки в списке */
.sky .who.kassa-alarm { color: var(--red); margin-top: 6px; }
/* Заголовки дней в оплатах экипажа — тише и меньше, чем разделы карточки */
.group.kassa-day, html.design-ios .group.kassa-day { font-size: 13px; font-weight: 600; color: var(--muted); padding-top: 10px; }
/* «на карту N» под суммой: .val не переносится, и длинная подпись сжимала имена слева */
html body:not(.pc-body) .row .val small.kassa-card { white-space: normal; max-width: 120px; margin-left: auto; }
/* Имена экипажа под шапкой карточки — вместо длинной шапки */
body:not(.pc-body) .kassa-who { padding: 0 16px 6px; font-size: 15px; color: var(--muted); }
/* --- [/Д-КАССА] --- */
/* --- [Д-ЕЩЁ] --- */
/* «Мой вход» на «Ещё»: свёрнутая строка вместо восьми служебных пунктов сверху */
details.moi-vhod > summary { list-style: none; cursor: pointer; }
details.moi-vhod > summary::-webkit-details-marker { display: none; }
details.moi-vhod[open] > summary .chev { transform: rotate(90deg); }
/* Метка у пункта «Ещё» (заявки, табель, замечания, ошибки) — не сжимается */
.row > .pill[data-metka] { flex: none; }
/* Сотрудники: звонок прямо из строки, палец попадает с первого раза */
.row.staff-tap { cursor: pointer; }
.row .staff-call { flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--green); color: var(--on-accent); }
.row .staff-call svg { width: 22px; height: 22px; }
/* Клиенты на телефоне: адрес одной строкой, иначе карточка в полэкрана */
html body:not(.pc-body) .row.client-row .sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* «Дубль?» в карточке клиента — одна строка внизу, раскрывается нажатием */
details.client-dubl > summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; }
/* --- [/Д-ЕЩЁ] --- */
/* --- [Д-ТАБЕЛЬ] --- */
/* Табель и зарплата на телефоне: день и месяц стрелками, «Вышел» зелёным,
   «⋯» бригадира сбоку, итог «Осталось выдать» наверху */
body:not(.pc-body) .actions.д-день { align-items: center; flex-wrap: nowrap; }
body:not(.pc-body) .actions.д-день > b { flex: 1; text-align: center; font-size: var(--t-val); }
body:not(.pc-body) .actions.д-день > .btn { min-width: 44px; padding: 0 14px; font-size: 20px; }
html body:not(.pc-body) .row.д-табель-строка { gap: 8px; }
html.design-wise body:not(.pc-body) .btn.д-вышел,
body:not(.pc-body) .btn.д-вышел { background: var(--green); color: var(--on-accent); border: 0; box-shadow: none; }
body:not(.pc-body) .btn.д-ещё { width: 44px; min-width: 44px; padding: 0; font-size: 20px; flex: none; }
html.design-wise body:not(.pc-body) .btn.д-ещё { border-color: var(--line); }
body:not(.pc-body) .row.д-итог .ttl { font-size: var(--t-big); font-weight: 700; margin: 2px 0; }
body:not(.pc-body) .д-таблетки { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
body:not(.pc-body) .д-таблетки > .btn { height: 44px; padding: 0 14px; }
body:not(.pc-body) .row[data-rates] { cursor: pointer; }
/* --- [/Д-ТАБЕЛЬ] --- */

/* --- [РУЧНОЙ МАРШРУТ] порядок адресов на экране экипажа. Строки остаются прямыми
   соседями .row, обёрток нет: иначе ломаются углы карточек Wise --- */
#app .м-номер { flex: none; min-width: 22px; text-align: center; font-weight: 700; color: var(--muted); }
#app .м-ссылка { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; color: inherit; text-decoration: none; border-radius: inherit; }
/* Нажимается вся строка, как раньше a.row: ссылка растянута на поля карточки, кроме стрелок */
#app .row.м-строка { position: relative; }
#app .м-ссылка::before { content: ""; position: absolute; inset: 0; border-radius: inherit; }
#app .м-ссылка > * { position: relative; }
#app .м-ссылка:active::before { background: var(--em-soft); }
html.design-ios #app .м-ссылка:active::before { background: var(--ios-fill); }
#app .м-стрелки { position: relative; z-index: 1; flex: none; align-self: center; display: flex; flex-direction: column; margin: -6px -8px -6px 0; }
#app .м-стрелка { flex: none; min-width: 44px; min-height: 44px; width: 48px; padding: 0; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 10px; color: var(--em); cursor: pointer; touch-action: manipulation; user-select: none; -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent; }
#app .м-стрелка:active:not(:disabled) { background: var(--em-soft); }
#app .м-стрелка:disabled { opacity: .3; color: var(--muted); cursor: default; }
#app .м-стрелка svg { width: 26px; height: 26px; display: block; pointer-events: none; }
#app .row.м-заявка { flex-direction: column; align-items: stretch; gap: 8px; }
#app .м-заявка-верх { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
#app .м-заявка-верх .ttl { overflow-wrap: anywhere; }
#app .м-заявка-верх .м-стрелки { align-self: flex-start; margin-top: -10px; }
#app .м-заявка-кнопки { display: flex; gap: 8px; }
#app .м-заявка-кнопки .btn { flex: 1; min-width: 0; }
html #app .row.м-подсветка, html.design-ios #app .row.м-подсветка { background: var(--em-soft); transition: background .3s; }
.м-связь { color: var(--red); }
.м-невидимо { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  html #app .row.м-подсветка, html.design-ios #app .row.м-подсветка { transition: none; }
}
/* --- [/РУЧНОЙ МАРШРУТ] --- */

/* --- [СОСТАВ ЭКИПАЖЕЙ] перевод, замена, второй в пару (владелец 10.11.2026).
   Нажимаемое — не ниже 44 px: водитель и оператор держат телефон одной рукой --- */
.row.cm-row { flex-wrap: wrap; padding-top: 4px; padding-bottom: 8px; }
.cm-head { display: flex; align-items: center; gap: 12px; flex: 1 1 100%; min-width: 0; min-height: 44px;
  background: none; border: 0; padding: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.cm-names { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 100%; min-width: 0; padding: 0 16px 8px; }
.row.cm-row .cm-names { padding: 0; }
.cm-name { min-height: 44px; max-width: 100%; padding: 0 14px; border-radius: 22px; border: 1px solid var(--line);
  background: var(--bg-soft, var(--bg)); color: var(--text); font: inherit; font-size: 15px; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-name:active { background: var(--em-soft); }
.cm-name.cm-pair { color: var(--em-dark); border-style: dashed; }
.cm-name-txt { display: inline-flex; align-items: center; min-height: 32px; color: var(--text); }
.cm-acts { display: flex; flex-direction: column; gap: 8px; padding: 8px 16px; }
.cm-act.btn { width: 100%; height: 56px; justify-content: flex-start; font-size: 16px; }
.group.cm-q { font-size: 15px; padding-top: 14px; }
.cm-pick { display: flex; flex-wrap: wrap; gap: 8px; padding: 2px 16px 6px; }
.cm-pick > button { min-height: 44px; min-width: 64px; max-width: 100%; padding: 6px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit; font-size: 15px;
  cursor: pointer; text-align: left; }
.cm-pick > button.on { background: var(--em); border-color: var(--em); color: var(--on-accent); font-weight: 600; }
.cm-sub { display: block; font-size: 12px; color: var(--muted); font-weight: 400; }
.cm-pick > button.on .cm-sub { color: inherit; opacity: .85; }
.cm-pick > button:disabled { cursor: default; opacity: .6; background: var(--bg-soft, var(--bg)); }
.cm-day { padding: 0 16px 4px; font-weight: 600; }
.cm-swap { display: flex; align-items: flex-start; gap: 10px; min-height: 44px; margin: 8px 16px 0; padding: 10px 12px;
  border-radius: var(--radius-sm); background: var(--em-soft); cursor: pointer; }
.cm-swap input { width: 22px; height: 22px; flex: none; margin: 0; accent-color: var(--em); }
.cm-preview { margin: 10px 16px 0; color: var(--muted); font-size: 14px; }
.cm-warn { margin: 8px 16px 0; padding: 8px 12px; border-radius: var(--radius-sm); background: var(--gold-bg); color: var(--gold-ink); font-size: 13px; }
.link.cm-fix { min-height: 44px; padding: 0 6px; }
.cm-danger { margin-top: 24px; padding: 16px; border-top: 1px solid var(--line); }
/* --- [/СОСТАВ ЭКИПАЖЕЙ] --- */

/* УРОВЕНЬ КЛИЕНТА: золото / серебро / бронза (ЛОГИКА.md, «Клиенты»).
   Цвета — переменными, а не прямо в разметке: в тёмной теме светлая плашка
   выжигает глаза, и правило «цвет задаётся палитрой, а не числом в коде»
   здесь ровно для этого. Рядом с цветом ВСЕГДА буква: на солнце и у тех, кто
   плохо различает цвета, читается буква, а не оттенок */
:root {
  --lvl-gold-bg: #fdf3df; --lvl-gold-fg: #6d430e; --lvl-gold-br: #c9942f; --lvl-gold-line: #d99e2b;
  --lvl-silver-bg: #eceef1; --lvl-silver-fg: #343941; --lvl-silver-br: #8f959d; --lvl-silver-line: #8d949d;
  --lvl-bronze-bg: #f7f0e8; --lvl-bronze-fg: #5f3c1e; --lvl-bronze-br: #b89a7c; --lvl-bronze-line: #b4906c;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --lvl-gold-bg: #3a2c12; --lvl-gold-fg: #f3d79a; --lvl-gold-br: #8a6a2a; --lvl-gold-line: #c9942f;
    --lvl-silver-bg: #2a2d31; --lvl-silver-fg: #dfe3e8; --lvl-silver-br: #70767e; --lvl-silver-line: #8d949d;
    --lvl-bronze-bg: #322820; --lvl-bronze-fg: #e3cbb3; --lvl-bronze-br: #7a5f45; --lvl-bronze-line: #b4906c;
  }
}
:root[data-theme="dark"] {
  --lvl-gold-bg: #3a2c12; --lvl-gold-fg: #f3d79a; --lvl-gold-br: #8a6a2a; --lvl-gold-line: #c9942f;
  --lvl-silver-bg: #2a2d31; --lvl-silver-fg: #dfe3e8; --lvl-silver-br: #70767e; --lvl-silver-line: #8d949d;
  --lvl-bronze-bg: #322820; --lvl-bronze-fg: #e3cbb3; --lvl-bronze-br: #7a5f45; --lvl-bronze-line: #b4906c;
}
.lvl {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 6px; border: 1px solid;
  font-size: 12px; font-weight: 700; line-height: 1; vertical-align: middle;
  flex: none;
}
.lvl-gold { background: var(--lvl-gold-bg); color: var(--lvl-gold-fg); border-color: var(--lvl-gold-br); }
.lvl-silver { background: var(--lvl-silver-bg); color: var(--lvl-silver-fg); border-color: var(--lvl-silver-br); }
.lvl-bronze { background: var(--lvl-bronze-bg); color: var(--lvl-bronze-fg); border-color: var(--lvl-bronze-br); }
/* Плашка с названием — в карточке, где место есть */
.lvl-tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px; border: 1px solid; font-size: 12px;
}
