/* Стили курьерки GORBA «Яблочная доставка» (delivery.prjmngrgrbadmn.online/src/styles.css), взяты без изменений как основа вида teamdash. Наши дополнения — в teamdash.css. */
/* ==================================================================
   Яблочная доставка · оболочка и компоненты
   Токены и компоненты взяты из демо (демо/index-v2.html) — это
   утверждённый заказчиком вид. Здесь добавлено только то, чего в демо
   не было: состояния экранов (states.js) и баннер обновления.
   ================================================================== */

/* ==== токены (дизайн-система v1, база GORBA) ==== */
:root{
  color-scheme:dark;
  /* Низ экрана: панель вкладок, отступ содержимого под ней и просвет
     до главной кнопки. Раньше это были три несвязанных числа в трёх
     правилах (88 px отступа, -8 px у кнопки, 12 px у панели), и любая
     правка одного разъезжалась с остальными — кнопка вставала то на
     20 px выше панели, то ниже кромки экрана (репорты №93, №95). */
  --tabbar-h:56px;                                        /* высота панели */
  --tabbar-b:calc(12px + env(safe-area-inset-bottom));    /* её отступ от низа окна */
  --actbar-gap:10px;                                      /* просвет «кнопка — панель» */
  /* Отступ содержимого снизу равен месту, которое занимают панель и просвет.
     Тогда липкая кнопка стоит на одной высоте и пока висит над текстом,
     и когда прокрутка дошла до конца и она встала в поток: просвет до
     панели один и тот же, кнопка не подпрыгивает. */
  --screen-pb:calc(var(--tabbar-h) + var(--tabbar-b) + var(--actbar-gap));
  --bg:#1a1822; --panel:#211f2c; --panel2:#1d1b27; --row:#26232f; --rowh:#2a2736;
  --ink:#e7e5ee; --dim:#a39fb0; --dim2:#6d697c; --line:#343040; --line2:#463f56;
  /* зелёный посветлел 25.09: аватар в красной строке доски был 4,22 к 1 */
  --accent:#9b93d6; --green:#8ebc9a; --red:#d68a92; --blue:#8fb0d6; --amber:#d4b678;
  /* заливка полос и точек: в тёмной теме совпадает с текстовыми */
  --green-fill:#7fbb92; --amber-fill:#d8b467; --red-fill:#d98790; --blue-fill:#6d9fe0;
  /* текст поверх цветных подложек: в тёмной теме подложки светлые, поэтому текст тёмный */
  --on-accent:#1a1822; --on-green:#122318; --on-red:#2a1013;
  --accent-t:rgba(155,147,214,.14); --green-t:rgba(130,181,143,.13);
  --red-t:rgba(214,138,146,.13); --blue-t:rgba(143,176,214,.12); --amber-t:rgba(212,182,120,.13);
  --accent-b:rgba(155,147,214,.42); --green-b:rgba(130,181,143,.42);
  --red-b:rgba(214,138,146,.42); --blue-b:rgba(143,176,214,.35); --amber-b:rgba(212,182,120,.4);
  /* Тревожные цвета отдельными именами: половина экранов писалась через
     --danger и --warn, а объявлений не было ни одного. Браузер выбрасывает
     объявление с неизвестной переменной целиком, поэтому красная точка зоны
     была прозрачной, число просроченных — белым, а блок с недостачей
     выглядел спокойнее блока без неё (аудит UX 11.09, п. 2.1).
     Это псевдонимы палитры, а не новые цвета: в светлой теме они меняются
     вместе с --red и --amber. */
  --danger:#d68a92; --warn:#d4b678;
  --shadow:0 1px 2px rgba(0,0,0,.34),0 8px 26px rgba(0,0,0,.32);
  --shadow-float:0 2px 6px rgba(0,0,0,.4),0 16px 48px rgba(0,0,0,.45);
  --glass:rgba(33,31,44,.86);
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:ui-sans-serif,-apple-system,"SF Pro Text","Segoe UI",Roboto,sans-serif;
  --r-card:16px; --r-sheet:22px; --r-chip:8px; --r-pill:999px;
  /* шкала кеглей тома 1 (11 — нижняя граница подписей): новый код — только ими */
  --fs-11:11px; --fs-12:12px; --fs-13:13px; --fs-15:15px; --fs-17:17px; --fs-19:19px;
  --fs-22:22px; --fs-34:34px; --fs-40:40px;
  --ease:cubic-bezier(.32,.72,0,1);

  /* текст на плашках тёмной темы до 4,5:1 (полный аудит 25.09): «срочно»
     на доске было 4,27, счётчик бокового меню — 3,88 */
  --red-badge:var(--red-fill); --green-ink:var(--green); --tag-ink:var(--dim);
  --danger-ink:#d9939b; --accent-ink:#afa9de;
}
[data-theme="light"]{
  color-scheme:light;
  --bg:#f1f0f6; --panel:#fbfafe; --panel2:#f5f4fa; --row:#f0eff5; --rowh:#eceaf4;
  --ink:#2c2b36; --dim:#676473; --dim2:#9a97a8; --line:#d9d6e3; --line2:#c6c2d5;
  /* текстовые: тёмные, чтобы читались на светлом */
  /* синий и акцент затемнены 24.09: было 4,16 и 4,50 к 1 — на грани нормы 4,5.
     25.09 — ещё серый, зелёный, красный, янтарный и акцент: на подкрашенных
     подложках (строка «просрочено», чипы, аватары, ярлыки «КЕШ» и «ВЫДАЧА
     ДЕНЕГ», выбранный пункт меню, синий аватар) было 3,7–4,46 к 1, теперь от 4,6 */
  --accent:#5950b9; --green:#286b44; --red:#a93141; --blue:#46639a; --amber:#825e0f;
  /* заливка: чистые и сочные, иначе полосы выглядят грязно */
  --green-fill:#34b06a; --amber-fill:#f0b23c; --red-fill:#e35563; --blue-fill:#4f82d6;
  --on-accent:#fff; --on-green:#fff; --on-red:#fff;
  --accent-t:rgba(106,97,196,.10); --green-t:rgba(52,176,106,.15);
  --red-t:rgba(227,85,99,.14); --blue-t:rgba(90,121,184,.10); --amber-t:rgba(240,178,60,.22);
  --accent-b:rgba(106,97,196,.34); --green-b:rgba(52,176,106,.45);
  --red-b:rgba(227,85,99,.42); --blue-b:rgba(90,121,184,.30); --amber-b:rgba(196,140,25,.45);
  --danger:#a93141; --warn:#825e0f;
  /* текст на плашках светлой темы до 4,5:1 (полный аудит 25.09): белое на
     --red-fill было 3,65, зелёная сумма — 4,18, серый ярлык — 4,23 */
  --red-badge:#c14854; --green-ink:var(--green); --tag-ink:#666372;
  --danger-ink:var(--danger); --accent-ink:var(--accent);
  --shadow:0 1px 2px rgba(40,36,60,.08),0 8px 26px rgba(40,36,60,.12);
  --shadow-float:0 2px 8px rgba(40,36,60,.08),0 18px 50px rgba(40,36,60,.14);
  --glass:rgba(251,250,254,.9);
}
*{box-sizing:border-box;margin:0;padding:0}
/* Скрытое обязано быть скрытым. Браузерное [hidden] — правило слабое, и любой
   свой display его перебивает: .field{display:block} показывал менеджеру
   «Зачем забираем» и «Сумму» на всех типах заявки, .btn — кнопку «Добавить
   ещё кадр» до первого снимка (аудит 08.09). */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg); color:var(--ink); font-family:var(--sans);
  font-size:14px; line-height:1.45; letter-spacing:.01em; min-height:100dvh;
}
::selection{background:var(--accent-t)}
button{-webkit-tap-highlight-color:transparent;touch-action:manipulation}
h1,h2,h3,.h-scr{text-wrap:balance}
/* видимый фокус для клавиатуры (мышью не мешает) */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
/* кликабельные карточки: сброс кнопочных стилей, семантика сохранена */
button.as-card{
  display:block;width:100%;text-align:left;font:inherit;color:inherit;
  background:none;border:0;padding:0;cursor:pointer;
}

/* ==== оболочка ==== */
.app{
  /* Высота окна: в браузере это 100dvh, а в мини-приложении Telegram —
     то, что отдаёт сам Telegram (`viewportStableHeight`, ставится в
     `--app-h` из platform.js). Разница не косметическая: после `expand()`
     и при наехавшей шапке чата рабочая высота меньше 100dvh, и низ
     макета вместе с главной кнопкой уезжал за кромку экрана — кнопка
     пропадала, стоило докрутить карточку до конца (репорт №93). */
  width:100%;max-width:480px;margin:0 auto;height:var(--app-h,100dvh);
  display:flex;flex-direction:column;position:relative;overflow:hidden;overflow:clip;
  background:var(--bg);border-left:1px solid var(--line);border-right:1px solid var(--line);
}
@media(max-width:520px){.app{border:0}}

.appbar{
  flex:none;display:flex;align-items:center;gap:10px;
  padding:calc(8px + env(safe-area-inset-top)) 16px 6px;
  background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);position:relative;z-index:var(--z-appbar);
}
.appbar .ttl{font-size:16px;font-weight:700;letter-spacing:-.02em;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.appbar .ttl small{display:block;font-size:11px;font-weight:500;color:var(--dim);letter-spacing:0}
#appbarSlot{display:flex;align-items:center;gap:8px;flex:none}
.iconb{
  width:38px;height:38px;border-radius:50%;border:1px solid var(--line2);background:var(--panel);
  color:var(--ink);cursor:pointer;font-size:15px;display:flex;align-items:center;justify-content:center;
  transition:transform .25s var(--ease);position:relative;flex:none;
}
.iconb:active{transform:scale(.92)}
.iconb .bdg{
  position:absolute;top:-3px;right:-3px;min-width:17px;height:17px;border-radius:9px;
  background:var(--red-badge);color:var(--on-red);font-size:11px;font-weight:700;font-family:var(--mono);
  display:flex;align-items:center;justify-content:center;padding:0 4px;
}
.cashpill{
  display:inline-flex;align-items:center;gap:6px;border-radius:var(--r-pill);cursor:pointer;
  background:var(--green-t);border:1px solid var(--green-b);color:var(--green-ink);
  font-family:var(--mono);font-size:12.5px;font-weight:700;padding:8px 12px;flex:none;
  transition:transform .25s var(--ease);
}
.cashpill:active{transform:scale(.95)}
/* полоса офлайна: одна на всё приложение, с числом действий в очереди */
.offline-strip{
  flex:none;display:flex;align-items:center;justify-content:center;gap:8px;
  background:var(--amber-t);border-bottom:1px solid var(--amber-b);color:var(--amber);
  font-size:12.5px;font-weight:600;padding:7px 12px;
}
.offline-strip.hidden{display:none}

/* Ширина задана явно, и это не перестраховка. Внутри .view лежит только
   абсолютно позиционированный .screen, то есть собственного содержимого
   у неё нет. В такой ситуации Chrome 151 считает ширину flex-элемента
   по содержимому — то есть нулевой, — и весь экран становится невидимым:
   разметка на месте, читается скриптом, а человек смотрит в пустоту.
   Ровно так это и выглядело у заказчика 07.09. */
.view{flex:1;width:100%;position:relative;overflow:hidden;overflow:clip}
.screen{
  position:absolute;inset:0;overflow-y:auto;overscroll-behavior:contain;
  padding:12px 16px var(--screen-pb);-webkit-overflow-scrolling:touch;
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

.tabbar{
  position:absolute;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));z-index:var(--z-tabbar);
  display:flex;gap:2px;background:var(--glass);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid var(--line2);border-radius:var(--r-pill);padding:3px;box-shadow:var(--shadow-float);
}
.tabbar.hidden{display:none}
/* Одна вкладка — панели нет, и полоса под содержимым, отмеренная под неё,
   превращается в пустоту высотой в треть экрана. */
body.no-tabbar{--screen-pb:calc(24px + env(safe-area-inset-bottom))}
body.no-tabbar .view::after{display:none}
/* Панели нет — кнопка садится на 12 px от низа окна, по той же арифметике. */
body.no-tabbar .actbar-slot{bottom:calc(12px + env(safe-area-inset-bottom) - var(--screen-pb))}
.tabbar button{
  flex:1;border:0;background:transparent;cursor:pointer;font:inherit;color:var(--dim);
  font-size:11px;font-weight:600;border-radius:var(--r-pill);padding:5px 2px 4px;
  display:flex;flex-direction:column;align-items:center;gap:3px;
  transition:color .3s var(--ease),background .3s var(--ease);position:relative;
}
.tabbar button .ic{font-size:17px;line-height:1}
/* значки Phosphor: svg берёт цвет из текста, размер — от места */
.ic svg,.iconbtn svg{display:block}
.tabbar button .ic svg{width:24px;height:24px}
.iconbtn svg{width:24px;height:24px}
.btn svg,.desk-mobile svg{vertical-align:-3px;margin-right:2px}
.tabbar button.on{color:var(--accent);background:var(--accent-t)}
.tabbar button .bdg{
  /* от центра, а не от края: вкладок стало вчетверо меньше, они втрое шире,
     и отсчёт от края уводил цифру на пустое место посреди кнопки.

     Цвет не красный: на вкладке это счёт работы, а не тревога. Рядом
     с красной цифрой колокольчика две одинаковые метки читались как две
     беды, хотя вторая означала «у вас две заявки» (аудит UX 11.09, п. 3.6). */
  position:absolute;top:2px;left:calc(50% + 4px);min-width:15px;height:15px;border-radius:8px;
  background:var(--accent);color:var(--on-accent);font-size:11px;font-weight:700;font-family:var(--mono);
  display:flex;align-items:center;justify-content:center;padding:0 3px;
}
/* Происшествия — как раз тревога: они краснеют */
.tabbar button .bdg.alarm{background:var(--red-badge);color:var(--on-red)}

/* ==== общие компоненты (из дизайн-системы) ==== */
.h-scr{font-size:20px;font-weight:700;letter-spacing:-.03em;margin:2px 0 10px;line-height:1.2}
/* Район — в строке с названием, а не отдельной строкой (Юрий 19.09:
   «4 строки уместить в две»). `nowrap` держал его одной строкой, и у
   клиента с длинным названием и районом с уточнением хвост уезжал за
   правый край экрана — на 320 px на 26 px наружу (осмотр максимально
   заполненных карточек 22.09). Переносим по словам: короткий район
   по-прежнему встаёт в строку с названием, длинный переходит на свою. */
.h-scr .area-inline{font-size:13px;font-weight:500;color:var(--dim);letter-spacing:0;margin-left:6px;
  white-space:normal;overflow-wrap:anywhere}
.h-scr .area-inline.own-line{display:block;margin-left:0;margin-top:3px;line-height:1.35}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:4px;min-height:32px}
.card-head .card-chips{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap;margin-left:auto}
.sub-scr{font-size:13px;color:var(--dim);margin-bottom:14px}
/* Номер заявки под заголовком: моноширинный, нажимается целиком и копируется.
   Рядом — ссылка на эту же заявку, чтобы кинуть её в переписку (23.09). */
/* Строка меток под названием: номер (нажимается и копируется), тип, «отменена»;
   справа — кнопка «Ссылка» (владелец 26.09: тип стоял один на всю строку,
   а ссылка выглядела меткой) */
.ordno{display:flex;align-items:center;flex-wrap:wrap;gap:8px 8px;margin:-6px 0 12px}
.ordno-btn{
  border:1px solid var(--line2);background:var(--row);color:var(--ink);
  border-radius:var(--r-chip);padding:3px 9px;font:inherit;font-size:12.5px;cursor:pointer;
  font-family:var(--mono);font-weight:600;font-variant-numeric:tabular-nums;
  transition:color .25s var(--ease),border-color .25s var(--ease);
}
.ordno-btn{position:relative}
/* на касание — 44 px по высоте (том 9), а видом номер остаётся меткой в ряд с типом */
.ordno-btn::after{content:"";position:absolute;inset:-10px -4px}
/* Одиночные ссылки-кнопки на телефоне («Создать учётную запись», «Отметить всё
   прочитанным», «Обновить», «Повторить»): видимая строка 19 px, палец промахивается.
   Невидимая рамка до ~45 px, как у номера заявки. Только там, где рядом нет других
   нажимаемых строк: в таблицах рамки налезли бы друг на друга (бой 27.09) */
@media (pointer:coarse){
  #goRegister,[data-read-all],.fresh-refresh,[data-action="retry-stale"]{position:relative}
  #goRegister::after,[data-read-all]::after,.fresh-refresh::after,[data-action="retry-stale"]::after{content:"";position:absolute;inset:-13px -6px}
}
.ordno-btn:hover{border-color:var(--accent-b);color:var(--accent)}
.ordno-btn:active{transform:scale(.96)}
.ordno .ordno-link{margin-left:auto;display:inline-flex;align-items:center;gap:8px}
.stack{display:grid;gap:12px}
.row-flex{display:flex;gap:8px;flex-wrap:wrap;align-items:stretch}
.row-flex .btn{white-space:nowrap;padding-left:14px;padding-right:14px}
.spacer{height:14px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ── деньги ────────────────────────────────────────────────────────────
   Сумма — вторая по важности вещь в строке после имени клиента, а была
   приглушена везде, где она главное: в ленте, у менеджера, в кассе, на
   доске и в поиске — 12–13 px серым (аудит UX 11.09, п. 3.1). Одно правило
   на всё приложение: моноширинные табличные цифры, размер не меньше
   основного текста строки, цвет основного текста. Цветом остаются только
   смыслы: зелёный — в кошельке, синий — к получению, красный — недостача. */
.money{
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:14.5px;font-weight:600;color:var(--ink);white-space:nowrap;
}
.money.dim{color:var(--dim);font-weight:500;font-size:13px}
.money.take{color:var(--blue)}
.money.have{color:var(--green)}
.money.bad{color:var(--red)}

.seg,.segmented{display:flex;gap:4px;background:var(--panel2);border:1px solid var(--line);border-radius:var(--r-pill);padding:4px;margin-bottom:14px}
.seg button,.segmented button{flex:1;border:0;cursor:pointer;font:inherit;font-size:13px;font-weight:600;color:var(--dim);background:transparent;border-radius:var(--r-pill);padding:8px;min-height:36px;transition:background .3s var(--ease),color .3s var(--ease)}
.seg button.on,.segmented button.on{background:var(--panel);color:var(--ink);box-shadow:var(--shadow)}
.seg .cnt{font-family:var(--mono);font-size:11px;opacity:.7;margin-left:3px}
/* переключатель списка не уезжает с прокруткой: чтобы перейти к своим,
   приходилось листать наверх (репорт №15) */
.seg.sticky{position:sticky;top:0;z-index:var(--z-band);background:var(--bg);box-shadow:0 8px 8px -8px var(--bg)}
/* поля полосы по краям экрана: иначе её фон не доходит до границ и в углах
   остаются просветы, сквозь которые тоже видно содержимое */
.seg.sticky{margin-left:-14px;margin-right:-14px;padding-left:14px;padding-right:14px}
/* липкая полоса ленты: пилюля лежит на плотной полосе во всю ширину, карточки
   уходят под неё целиком, а не просвечивают по краям (Юрий 19.09, №82) */
.seg-band{position:sticky;top:-12px;z-index:var(--z-band);background:var(--bg);margin:0 -14px 8px;padding:12px 14px 6px;
  box-shadow:0 10px 12px -10px rgba(0,0,0,.16)}
/* Щель над липкой полосой. Полоса прилипает на -12 px, и когда экран
   смещён сверху (мини-приложение Telegram со своей шапкой, увеличенный
   масштаб), между ней и шапкой остаётся зазор, в котором мелькает
   прокручивающийся текст — карточка словно наезжает на полосу
   (скрин владельца 23.09). Достраиваем фон вверх тем же цветом:
   полоса закрывает всё, что под ней, при любом смещении. */
.seg-band::before,.seg.sticky::before,.incbar::before{
  content:"";position:absolute;left:0;right:0;bottom:100%;height:20px;
  background:var(--bg);pointer-events:none;
}
.seg-band::before{left:0;right:0}
.seg.sticky,.incbar{position:sticky}
/* Содержимое уходит под полосу плавно, а не обрывается по линейке: резкий
   срез читается как «карточка наехала на переключатель» (владелец 23.09). */
.seg-band::after,.seg.sticky::after{
  content:"";position:absolute;left:0;right:0;top:100%;height:14px;pointer-events:none;
  background:linear-gradient(180deg,var(--bg),transparent);
}
.seg-band .seg{margin:0}
/* просроченная заявка кричит: красная рамка с пульсом и наверх списка (репорт №28) */
.order.late{border-color:var(--red);animation:lateFrame 1.6s ease-in-out infinite}
@keyframes lateFrame{0%,100%{box-shadow:0 0 0 0 rgba(255,90,90,0)}50%{box-shadow:0 0 0 4px rgba(255,90,90,.35)}}
.order .tm{display:block;padding:0 14px 8px;font-size:12.5px;color:var(--dim);font-variant-numeric:tabular-nums}
.order .tm.red{color:var(--red);font-weight:600}
@media(prefers-reduced-motion:reduce){.order.late{animation:none;box-shadow:0 0 0 3px rgba(255,90,90,.35)}}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid var(--line2);cursor:pointer;
  font:inherit;font-weight:700;font-size:14px;border-radius:var(--r-pill);padding:11px 16px;
  color:var(--ink);background:var(--row);user-select:none;
  transition:transform .25s var(--ease),background .3s var(--ease),filter .3s var(--ease);
}
.btn:active{transform:scale(.97)}
.btn:disabled{opacity:.45;pointer-events:none}
.btn-primary{background:var(--accent);border-color:transparent;color:var(--on-accent);box-shadow:inset 0 1px 0 rgba(255,255,255,.18)}
.btn-good,.btn.good{background:var(--green-fill);border-color:transparent;color:var(--on-green)}
.btn-danger{background:var(--red-t);border-color:var(--red-b);color:var(--red)}
.btn-ghost{background:color-mix(in srgb,var(--ink) 4%,transparent);border-color:var(--line2)}
/* Кнопка во всю ширину — тот же шаг, что у «Взять» (владелец 22.09):
   была 14,5 px при внутренних 12/20, высота выходила 45. Кегль оставляем,
   высоту равняем на 42 и ставим её явно, а не через отступы: иначе
   у кнопок со значком и без он разъезжается на пиксель-другой. */
.btn-block,.btn.block{width:100%;min-height:42px;padding:9px 20px;font-size:14.5px}
.btn-small,.btn.small{padding:8px 14px;font-size:13px;min-height:40px}

.chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;padding:3px 9px;border-radius:var(--r-chip);border:1px solid var(--line2);background:var(--row);color:var(--dim)}
.chip .d{width:7px;height:7px;border-radius:50%;background:var(--dim2)}
.z-g{background:var(--green-t)!important;border-color:var(--green-b)!important;color:var(--green)!important}
.z-g .d{background:var(--green-fill)}
.z-y{background:var(--amber-t)!important;border-color:var(--amber-b)!important;color:var(--amber)!important}
.z-y .d{background:var(--amber-fill)}
.z-r{background:var(--red-t)!important;border-color:var(--red-b)!important;color:var(--red)!important}
.z-r .d{background:var(--red-fill)}
.chip-src{font-family:var(--mono);font-size:11px;font-weight:500}
.chip.tchip{font-size:13.5px;font-weight:700;padding:5px 11px;font-family:var(--mono);letter-spacing:.01em}
.badge-urgent{display:inline-flex;align-items:center;font-size:11px;font-weight:700;letter-spacing:.09em;padding:3px 9px;border-radius:var(--r-chip);text-transform:uppercase;background:var(--red-badge);color:var(--on-red)}
.badge-hour{display:inline-flex;align-items:center;font-size:11px;font-weight:700;letter-spacing:.09em;padding:3px 9px;border-radius:var(--r-chip);text-transform:uppercase;background:var(--amber-fill);color:#332708}
.badge-flag{display:inline-flex;align-items:center;font-size:11px;font-weight:700;letter-spacing:.09em;padding:3px 9px;border-radius:var(--r-chip);text-transform:uppercase;background:var(--accent-t);color:var(--accent);border:1px solid var(--accent-b)}
/* плашка приоритета перед типом — с зазором, а не встык (репорт №59) */
.badge-urgent+*,.badge-hour+*{margin-left:6px}
.badge-type{display:inline-flex;align-items:center;font-weight:700;padding:3px 10px;border-radius:var(--r-chip);letter-spacing:.01em;text-transform:uppercase;font-size:11px}
.badge-type.tovar{background:var(--blue-t);color:var(--blue);border:1px solid var(--blue-b)}
.badge-type.kesh{background:var(--green-t);color:var(--green);border:1px solid var(--green-b)}
.badge-type.gibrid{background:var(--accent-t);color:var(--accent);border:1px solid var(--accent-b)}
.badge-type.zabor{background:var(--amber-t);color:var(--amber);border:1px solid var(--amber-b)}
.badge-type.payout{background:var(--red-t);color:var(--red);border:1px solid var(--red-b)}

.order{display:block;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow);overflow:hidden;transition:transform .3s var(--ease),opacity .5s var(--ease)}
.order.t-tovar{border-left:4px solid var(--blue-fill)}
.order.t-kesh{border-left:4px solid var(--green-fill)}
.order.t-gibrid{border-left:4px solid var(--accent)}
.order.t-zabor{border-left:4px solid var(--amber-fill)}
.order.t-payout{border-left:4px solid var(--red-fill)}
.order.urgent{border-color:var(--red-b)}
.lockline{display:block;margin:6px 12px 0;padding-top:6px;border-top:1px dashed var(--line);font-size:12px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.order .who,.order .items{display:block}
button.as-card:active .order{transform:scale(.985)}
.order:active{transform:scale(.985)}
.order .top{display:flex;align-items:center;gap:6px;padding:8px 12px 0;flex-wrap:wrap}
.order .who{padding:4px 12px 2px;font-size:15px;font-weight:700;letter-spacing:-.015em}
.order .who small{display:block;font-weight:400;font-size:12px;color:var(--dim);margin-top:1px}
.order .items{padding:3px 12px 0}
.order .item{display:flex;justify-content:space-between;gap:10px;padding:5px 0;border-top:1px dashed var(--line);font-size:13px;overflow-wrap:anywhere}
.order .item:first-child{border-top:0}
.order .item .q{color:var(--dim);font-size:12px}
.order .item .pr{
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:14.5px;font-weight:600;color:var(--ink);flex:none;white-space:nowrap;
}
.order .foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 12px 10px}
/* Пара кнопок в подвале: сетка пополам. Правило `.two` (0,1,0) проигрывало
   правилу `.order .foot` (0,2,0), и вместо двух равных кнопок получались две
   узкие пилюли по краям — главное действие выходило уже второстепенного
   (аудит UX 11.09, п. 2.2). */
.order .foot.two{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.order .foot.two .btn{width:100%;padding-left:8px;padding-right:8px}
/* на 360 px «Заявка и история» в паре кнопок переносилась на две строки
   (прогон В1+ 21.09): подпись длиннее половины карточки на 14 px — ужимаем
   шрифт пары на узких экранах, не сам текст */
@media (max-width:379px){.order .foot.two .btn{font-size:13.5px}}
/* Одна кнопка в подвале — на всю ширину и справа от края не жмётся */
.order .foot>.btn:only-child{flex:1}
.order .age{font-size:12.5px;color:var(--dim)}
/* Кнопка «Взять» в ленте. Была 46 px / 15 px / 700 и занимала 61 % строки —
   самое крупное пятно карточки, крупнее имени клиента, набранного тем же
   кеглем и весом (владелец 22.09: «реально гигант»). Разобрали геометрию:
   · 42 px — выше рабочего минимума в 36 и почти равно ориентиру Apple (44),
     значит курьер на ходу и в перчатке попадает как раньше;
   · 14,5 / 650 — тише имени клиента (15/700), в карточке снова один
     первый голос, и это тот, к кому ехать;
   · ровно половина строки — слева «висит …», справа действие. Раньше
     слово из пяти букв плавало посреди 221 px пустоты. */
.take{
  border:0;cursor:pointer;font-family:inherit;font-weight:700;font-size:14.5px;
  color:var(--on-accent);background:var(--accent);border-radius:var(--r-pill);
  min-height:42px;padding:0 18px;flex:0 0 50%;
  display:inline-flex;align-items:center;justify-content:center;
  transition:transform .25s var(--ease);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16);
}
/* на узком экране половина строки не вмещает «висит 94 ч 19 мин» рядом:
   кнопке отдаём меньше, возраст остаётся в одну строку */
@media (max-width:359px){.take{flex:0 0 44%;padding:0 12px}}
.take:active{transform:scale(.94)}
.take:disabled{opacity:.4;pointer-events:none}

.timer{display:flex;align-items:center;gap:12px;padding:13px 15px;border-radius:14px;border:1px solid var(--line);background:var(--panel2)}
.timer .val{font-family:var(--mono);font-size:24px;font-weight:700;letter-spacing:-.02em;line-height:1}
.timer .lim{font-size:12px;color:var(--dim);margin-top:3px}
.timer.z-g2 .val{color:var(--green)} .timer.z-y2 .val{color:var(--amber)} .timer.z-r2 .val{color:var(--red)}
.zonebar{height:6px;border-radius:3px;background:var(--row);overflow:hidden;margin-top:8px}
.zonebar i{display:block;height:100%;border-radius:3px;background:var(--green-fill);transition:width 1s linear}
.timer.z-y2 .zonebar i{background:var(--amber-fill)} .timer.z-r2 .zonebar i{background:var(--red-fill)}

.chain{position:relative;padding-left:26px;margin-top:6px}
.chain::before{content:"";position:absolute;left:8px;top:8px;bottom:8px;width:2px;border-radius:1px;background:var(--line2)}
.ph{position:relative;padding:6px 0 10px}
.ph .dot{position:absolute;left:-26px;top:11px;width:18px;height:18px;border-radius:50%;background:var(--panel);border:2px solid var(--dim2);display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--on-green)}
.ph.done .dot{background:var(--green-fill);border-color:var(--green-fill)}
/* неуспешный шаг — крест на красном, нейтральный (пауза, возврат в ленту) — серая
   точка: зелёная галочка у «не доставил» читалась как успех (замечание 14.09) */
.ph.bad .dot{background:var(--red-fill);border-color:var(--red-fill);color:var(--on-red)}
.ph.flat .dot{background:var(--panel);border-color:var(--dim);color:var(--dim)}
.ph.now .dot{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 5px var(--accent-t)}
.ph .t{font-size:13.5px;font-weight:600}
.ph .m{font-size:12px;color:var(--dim);margin-top:1px}
.ph .cmt{
  margin-top:6px;font-size:12.5px;background:var(--row);border:1px solid var(--line);
  border-radius:10px;padding:8px 11px;line-height:1.5;
  overflow-wrap:anywhere;word-break:break-word;   /* длинные слова и ссылки не рвут вёрстку */
}
.ph .cmt b{color:var(--accent);font-weight:600}
.ph .photo{margin-top:5px;width:52px;height:52px;border-radius:10px;border:1px solid var(--line2);background:linear-gradient(135deg,var(--row),var(--panel2));display:flex;align-items:center;justify-content:center;color:var(--dim);font-size:18px;overflow:hidden}
.ph .photo img{width:100%;height:100%;object-fit:cover}
.addcmt{border:0;background:transparent;color:var(--accent);font:inherit;font-size:13px;font-weight:600;cursor:pointer;padding:10px 0;min-height:40px}

/* Панель объявлена один раз. Было два правила: первое с тенью и радиусом
   16, второе ниже — с радиусом 14, без тени и со своим отступом. Побеждало
   второе, панели теряли тень и выбивались из радиуса карточек, а отступы
   приходилось дописывать инлайном в каждом экране (аудит UX 11.09, п. 2.3). */
.panel{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--shadow);padding:11px 13px;margin:0 0 10px;
}
.kpi{display:block;width:100%;text-align:left;font:inherit;color:inherit;border-radius:var(--r-card);border:1px solid var(--line);background:var(--panel);padding:10px 12px;box-shadow:var(--shadow);overflow:hidden}
.kpi .n{display:block;font-family:var(--mono);font-size:clamp(17px,5.6vw,25px);font-weight:700;line-height:1.05;overflow-wrap:anywhere}
.kpi .l{display:block;font-size:11px;color:var(--dim);margin-top:4px;line-height:1.3}
.kpi.red{border-color:var(--red-b);background:linear-gradient(180deg,var(--red-t),var(--panel))}
.kpi.red .n{color:var(--red)} .kpi.amber .n{color:var(--amber)} .kpi.accent .n{color:var(--accent)} .kpi.green .n{color:var(--green)}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:8px}

.exc{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--line);border-left:3px solid var(--red-fill);border-radius:12px;background:var(--panel)}
.exc.warn{border-left-color:var(--amber-fill)} .exc.info{border-left-color:var(--blue)} .exc.ok{border-left-color:var(--green-fill)}
.exc .b{font-size:13px;font-weight:600;overflow-wrap:anywhere}
.exc .m{font-size:12px;color:var(--dim);margin-top:2px}

.raw{border:1px dashed var(--line2);border-radius:12px;padding:10px 12px;background:var(--panel2)}
.raw .src{font-size:11px;color:var(--dim);margin-bottom:3px;font-weight:600;letter-spacing:.04em}
.raw .txt{font-family:var(--mono);font-size:12px;color:var(--dim);line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
.rawbox{margin-bottom:12px}
.rawbox summary{cursor:pointer;font-size:12.5px;color:var(--dim);padding:8px 0;min-height:40px;display:flex;align-items:center}
.rawbox summary::marker{color:var(--accent)}

/* display:block обязателен: из 31 поля 22 — это <label>, а label строчный,
   и его margin-bottom молча не работает. Внутри сетки .row он становится
   блоком сам, поэтому парные поля стояли ровно, а одиночные липли
   к соседям (форма заявки, замечание владельца 14.09) */
.field{display:block;margin-bottom:12px}
.field label,.field .lbl-like{display:block;font-size:12.5px;font-weight:600;margin-bottom:5px;color:var(--dim)}
.inp{width:100%;font:inherit;font-size:16px;color:var(--ink);background:var(--panel2);border:1px solid var(--line2);border-radius:12px;padding:12px 13px;outline:0;transition:border-color .3s var(--ease),box-shadow .3s var(--ease)}
.inp:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-b)}
.inp::placeholder{color:var(--dim)}
.field .err{font-size:12px;color:var(--red);margin-top:4px}
select.inp{appearance:none;-webkit-appearance:none;padding-right:38px}

.sync{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dim)}
.sync .ok{color:var(--green)} .sync .wait{color:var(--amber)}

/* строки-чеки: позиции заявки и пачка кассиру */
.crow{display:flex;width:100%;text-align:left;align-items:center;gap:11px;padding:12px 13px;border:0;border-top:1px solid var(--line);background:transparent;color:inherit;font:inherit}
button.crow{cursor:pointer}
.crow:first-child{border-top:0}
.crow .cb{width:24px;height:24px;border-radius:8px;border:2px solid var(--dim2);flex:none;display:flex;align-items:center;justify-content:center;color:var(--on-green);font-size:12px}
.crow.on .cb{background:var(--green-fill);border-color:var(--green-fill)}
.crow .nm{flex:1;font-size:14px;font-weight:600;min-width:0;text-align:left;overflow-wrap:anywhere}
.crow .nm small{display:block;font-weight:400;font-size:11.5px;color:var(--dim)}
.crow .sum{font-family:var(--mono);font-size:14px;font-weight:600;flex:none;white-space:nowrap}
.crow .sum.bad{color:var(--red)}

/* Главное действие всегда под большим пальцем: курьер приехал и не должен
   скроллить. Липнет полоса, а не сама кнопка: раньше кнопка плыла над
   содержимым с восьмипиксельной каймой цвета фона и обрубала текст под собой
   ровным прямоугольником — подпись под таймером и вторая позиция уходили в
   никуда (осмотр 09.09). Полоса растворяет содержимое кверху: видно, что
   текст уходит ПОД кнопку, а не оборван. */
/* Липкая главная кнопка. Отступ считается от СОДЕРЖИМОГО, а не от окна:
   у `.screen` снизу ещё `--screen-pb`, чтобы текст не прятался под плавающей
   панелью. Поэтому «встать над панелью» — это отрицательное смещение, и
   считается оно из тех же переменных, что и сама панель: сдвинешь панель —
   кнопка поедет за ней, а не останется висеть на 20 px выше (репорт №95).
   Отсюда и `bottom:0`: отступ содержимого ровно на месте панели с просветом.

   Подложки у кнопки нет по решению владельца 22.09 (репорт №94): полоса
   с фоном, рамкой и тенью читалась как отдельная плашка и резала глаз.
   Текст под кнопкой не обрывается — его растворяет градиент `.view::after`,
   он лежит ниже (z-index 20), чем сама кнопка. */
.actbar-slot{
  position:sticky;z-index:var(--z-actbar);
  bottom:0;
  margin:10px 0 0;padding:0;background:none;border:0;box-shadow:none;
}
/* Главная кнопка шага — единственное действие экрана, её держим крупной
   намеренно: 46 px против 42 у остальных (решение владельца 22.09). */
.btn.actbar{min-height:46px;font-size:15px;font-weight:700;box-shadow:var(--shadow-float)}
/* Подсказка под кнопкой: была --dim2, то есть 3.3:1 — ниже нормы для
   текста. Тот же серый, что и остальная мета (аудит UX 11.09, п. 3.8). */
.hintline{font-size:12px;color:var(--dim);margin-top:5px}
.backlink{border:0;background:transparent;color:var(--accent);font:inherit;font-size:14px;font-weight:600;cursor:pointer;padding:8px 6px 8px 0;margin-left:-6px;min-height:36px;display:inline-flex;align-items:center;gap:6px}
.daynote{font-size:12.5px;color:var(--dim);margin:-6px 0 12px;text-align:center;text-wrap:balance}
.section-title{font-size:14px;font-weight:700;margin:2px 0 10px}
/* тело уведомления — строками: клиент, потом кто и сколько */
.notif .body small{white-space:pre-line}
/* Пара «метка — значение». Значение прижато вправо, и пока оно короткое
   («товар + кеш», «12 мин»), это читается как таблица. Длинный район в две
   строки при выравнивании по правому краю рвался лесенкой и упирался в
   край карточки (осмотр максимально заполненных карточек 22.09).
   Поэтому: метка не сжимается, значение переносится по словам и
   выравнивается по левому краю своей колонки — рваного края больше нет. */
.kv{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:13.5px;padding:2px 0}
.kv span{color:var(--dim);flex:none}
.kv b{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:700;
      text-align:right;overflow-wrap:anywhere;min-width:0}
/* Длинное значение (район с уточнением, адрес) не пытаемся уместить в одну
   строку справа: метка встаёт сверху, значение под ней во всю ширину и по
   левому краю. Так же это выглядит в бумажной накладной. */
.kv.stack{flex-direction:column;align-items:flex-start;gap:2px}
.kv.stack b{text-align:left;font-family:var(--sans);font-weight:600}

/* переключатель (звук, тихие часы) */
.sw-row{
  display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  border:0;border-top:1px solid var(--line);padding:12px 0;background:transparent;
  font:inherit;color:inherit;text-align:left;cursor:pointer;
}
.sw-row:first-child{border-top:0}
.sw-row .lbl{font-size:14px;font-weight:600}
.sw-row .lbl small{display:block;font-weight:400;font-size:11.5px;color:var(--dim)}
.tgl{width:51px;height:31px;border-radius:var(--r-pill);background:var(--row);border:1px solid var(--line2);position:relative;flex:none;transition:background .3s var(--ease),border-color .3s var(--ease)}
.tgl i{position:absolute;top:1px;left:1px;width:27px;height:27px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.35);transition:transform .3s var(--ease)}
.sw-row.on .tgl{background:var(--accent);border-color:var(--accent)}
.sw-row.on .tgl i{transform:translateX(20px)}

/* ==== модалки-шторки ==== */
.sheet-veil{
  position:absolute;inset:0;z-index:var(--z-sheet);background:rgba(10,8,16,.5);
  opacity:0;pointer-events:none;transition:opacity .4s var(--ease);
  display:flex;align-items:flex-end;
}
.sheet-veil.on{opacity:1;pointer-events:auto}
.sheet{
  width:100%;background:var(--panel);border:1px solid var(--line2);border-bottom:0;
  border-radius:var(--r-sheet) var(--r-sheet) 0 0;box-shadow:var(--shadow-float);
  padding:10px 18px calc(18px + env(safe-area-inset-bottom));max-height:86%;overflow-y:auto;
  overscroll-behavior:contain;
  transform:translateY(40px);transition:transform .45s var(--ease);
}
.sheet-veil.on .sheet{transform:none}
/* На большом экране шторка снизу на 1900 px — это мобильный жест не по адресу:
   окно по центру читаемой ширины (репорты №25, №42) */
body.deskmode .sheet-veil{align-items:center;justify-content:center;padding:24px}
body.deskmode .sheet{
  max-width:560px;border-radius:var(--r-sheet);border-bottom:1px solid var(--line2);
  max-height:88vh;transform:translateY(16px) scale(.985);
}
body.deskmode .sheet .grab{display:none}
body.deskmode .sheet-veil.on .sheet{transform:none}
.sheet .grab{width:38px;height:4px;border-radius:2px;background:var(--line2);margin:4px auto 14px}
.sheet h3{font-size:var(--fs-17);font-weight:700;letter-spacing:-.02em;margin-bottom:4px}
.sheet .sub{font-size:13px;color:var(--dim);margin-bottom:14px}
/* вопрос внутри открытой шторки: «похожий клиент есть», «за ним деньги» —
   форму не закрываем, блок встаёт сверху и уходит после ответа */
.confirm-inline{margin:4px 0 14px;padding:12px 14px;border:1px solid var(--amber-b);border-radius:14px;background:var(--amber-t)}
.confirm-inline.danger{border-color:var(--red-b);background:var(--red-t)}
.confirm-inline .txt{font-size:14px;line-height:1.4}
.confirm-inline .row2{display:flex;gap:8px;margin-top:10px}
.confirm-inline .btn{flex:1;padding:11px 12px}

/* камера: превью снимка перед отправкой */
.cam{
  border-radius:16px;overflow:hidden;border:1px solid var(--line2);position:relative;
  aspect-ratio:4/3;background:radial-gradient(circle at 30% 35%, var(--rowh), var(--panel2) 70%);
  display:flex;align-items:center;justify-content:center;margin-bottom:14px;
  color:var(--dim);font-size:13px;text-align:center;padding:14px;
}
.cam img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cam .hint{
  position:absolute;left:12px;right:12px;bottom:12px;text-align:center;
  background:rgba(10,8,16,.55);color:#fff;font-size:12px;font-weight:600;
  border-radius:10px;padding:7px 10px;backdrop-filter:blur(6px);
}
.money-opt{display:flex;width:100%;text-align:left;align-items:center;gap:12px;padding:13px 14px;cursor:pointer;background:transparent;color:inherit;font:inherit;border:1px solid var(--line);border-radius:13px;margin-bottom:8px;transition:border-color .3s var(--ease),background .3s var(--ease)}
.money-opt.on{border-color:var(--accent-b);background:var(--accent-t)}
.money-opt .r{width:20px;height:20px;border-radius:50%;border:2px solid var(--dim2);flex:none}
.money-opt.on .r{border-color:var(--accent);background:var(--accent);box-shadow:inset 0 0 0 4px var(--panel)}
.money-opt b{font-size:14px;display:block}
.money-opt span{font-size:12px;color:var(--dim)}

/* тост */
.toast-zone{position:absolute;left:0;right:0;top:calc(58px + env(safe-area-inset-top));z-index:var(--z-toast);display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;padding:0 16px}
.toast{
  display:inline-flex;align-items:center;gap:9px;background:var(--glass);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  border:1px solid var(--line2);border-radius:var(--r-card);padding:10px 17px;
  font-size:13px;font-weight:600;box-shadow:var(--shadow-float);max-width:100%;text-align:left;
  animation:toastIn .5s var(--ease);
}
.toast.out{animation:toastOut .4s var(--ease) forwards}
@keyframes toastIn{from{opacity:0;transform:translateY(-14px) scale(.95)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(-10px) scale(.96)}}
.toast .i{color:var(--green);display:inline-flex} .toast .i.ok{color:var(--green)}
.toast .i.err{color:var(--red)} .toast .i.warn{color:var(--amber)} .toast .i.acc{color:var(--accent)}
/* заднее в стопке — только край карточки: текст не просвечивает (том 2, полный аудит 25.09) */
.toast.behind{overflow:hidden}
.toast.behind > *{visibility:hidden}
.toast .n{margin-left:auto;padding:0 6px;border-radius:8px;background:var(--rowh);color:var(--dim);font-size:12px;font-variant-numeric:tabular-nums}

/* ==== состояния экранов (states.js) — этого в демо не было ==== */
.state{
  text-align:center;padding:40px 22px;border:1px dashed var(--line2);
  border-radius:var(--r-card);color:var(--dim);background:var(--panel2);
}
.state-title{color:var(--ink);font-size:15px;font-weight:700;margin-bottom:4px}
.state-hint{font-size:12.5px;color:var(--dim);line-height:1.5;max-width:280px;margin:0 auto}
.state-meta{font-size:11px;color:var(--dim);font-family:var(--mono);margin-top:10px;overflow-wrap:anywhere}
.state .btn{margin-top:14px}
.state-error{border-color:var(--red-b);background:linear-gradient(180deg,var(--red-t),var(--panel2))}
.state-offline{border-color:var(--amber-b);background:linear-gradient(180deg,var(--amber-t),var(--panel2))}
.state-forbidden{border-color:var(--line2)}

/* скелетон: человек видит, что данные едут, а не что всё сломалось */
.skeleton{display:grid;gap:12px}
.sk-card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
  padding:16px 15px;display:grid;gap:10px;box-shadow:var(--shadow);
}
.sk-card.tall{height:180px}
.sk-line{
  height:12px;border-radius:6px;
  background:linear-gradient(90deg,var(--row) 25%,var(--rowh) 37%,var(--row) 63%);
  background-size:400% 100%;animation:skWave 1.4s linear infinite;
}
.sk-line.w60{width:60%} .sk-line.w40{width:40%} .sk-line.w50{width:50%} .sk-line.w70{width:70%} .sk-line.w80{width:80%} .sk-line.w100{width:100%}
.sk-line.h{height:16px} .sk-line.big{height:28px;border-radius:8px}
.sk-btn{height:52px;border-radius:var(--r-pill);background:linear-gradient(90deg,var(--row) 25%,var(--rowh) 37%,var(--row) 63%);background-size:400% 100%;animation:skWave 1.4s linear infinite}
@keyframes skWave{from{background-position:100% 0}to{background-position:0 0}}
/* Полоса «данные едут» под шапкой: появляется через 300 мс после начала
   запроса — короткие ответы её не показывают, долгие видно. Один
   индикатор на всё приложение, без колёс в каждом углу (18.09) */
.netbar{position:absolute;left:0;right:0;bottom:-1px;height:2px;overflow:hidden;pointer-events:none;opacity:0;transition:opacity .2s ease}
.netbar.on{opacity:1}
.netbar::before{content:"";position:absolute;top:0;bottom:0;left:-40%;width:40%;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--accent),transparent);animation:netbar 1.1s cubic-bezier(.4,0,.6,1) infinite}
@media(prefers-reduced-motion:reduce){
  .netbar::before{animation:none;left:0;width:100%;background:var(--accent);opacity:.7}
  .sk-line,.sk-btn{animation:none}
}
@keyframes netbar{to{left:100%}}
.cam-wait{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;min-height:160px;color:var(--dim);font-size:13px}
.cam-wait .sk-line{width:40%}

/* баннер принудительного обновления (updates.js) */
.update-banner{
  position:fixed;left:12px;right:12px;bottom:calc(84px + env(safe-area-inset-bottom));z-index:var(--z-banner);
  max-width:456px;margin:0 auto;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:var(--accent);color:var(--on-accent);border-radius:var(--r-card);padding:12px 14px;
  font-size:13.5px;font-weight:600;box-shadow:var(--shadow-float);
}
.update-banner .btn{background:var(--panel);color:var(--ink);border-color:transparent}

/* ── экран кассира (Ф3.1.4) ────────────────────────────────────────────────
   Построчная сверка: суммы выровнены в колонку, чтобы взгляд шёл сверху вниз
   и расхождение находилось без чтения каждой строки. */
.pack-rows{list-style:none;margin:0;padding:2px 14px 8px}
.pack-row{
  display:grid;grid-template-columns:1fr 108px 92px;align-items:center;gap:10px;
  padding:9px 0;border-bottom:1px solid var(--line);
}
.pack-row:last-child{border-bottom:none}
.pack-row-who span{font-size:14.5px;font-weight:600}
.pack-row-who small{display:block;margin-top:1px}
.pack-row-input input{
  width:100%;padding:9px 10px;font-size:15px;font-variant-numeric:tabular-nums;
  text-align:right;border:1px solid var(--line);border-radius:10px;
  background:var(--panel);color:var(--ink);
}
.pack-row-input input:focus{outline:2px solid var(--accent);outline-offset:1px}
.pack-row-diff{
  font-size:12.5px;text-align:right;color:var(--dim);
  font-variant-numeric:tabular-nums;
}
.pack-row.short .pack-row-diff{color:var(--danger);font-weight:600}
.pack-row.over .pack-row-diff{color:var(--warn);font-weight:600}
.pack-row.short .pack-row-input input{border-color:var(--danger)}

.pack-total{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:8px;margin:0 14px 10px;padding:10px 12px;border-radius:12px;
  background:var(--panel2,var(--panel));font-size:13px;
  font-variant-numeric:tabular-nums;
}
.pack-total strong{font-size:14px}
.pack-total.warn{background:color-mix(in srgb,var(--danger) 12%,transparent)}
.pack-total.warn strong{color:var(--danger)}

/* Подпись только для читалок: у поля суммы виден клиент, но не связь с ним. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

@media (max-width:420px){
  .pack-row{grid-template-columns:1fr 92px;grid-template-areas:"who input" "diff diff"}
  .pack-row-who{grid-area:who}
  .pack-row-input{grid-area:input}
  .pack-row-diff{grid-area:diff;text-align:left}
}

/* ── съёмка: несколько кадров и путь при отказе камеры ────────────────────
   Полоска со счётчиком вместо галереи миниатюр: курьер снимает на ходу,
   и разглядывать превью ему некогда — важно знать, что кадр засчитан. */
.cam-strip{
  margin:8px 0 4px;padding:6px 10px;border-radius:10px;
  background:var(--panel2,var(--panel));font-size:12.5px;color:var(--dim);
  text-align:center;
}
body.deskmode .search-back{display:none}
.search-back{margin:0 0 8px}
.cam-thumbs{display:flex;gap:8px;overflow-x:auto;padding:2px 0 6px;scrollbar-width:none}
.cam-thumbs::-webkit-scrollbar{display:none}
.cam-thumb{position:relative;flex:0 0 64px;width:64px;height:64px;border-radius:10px;overflow:hidden;border:2px solid var(--line2);background:var(--row)}
.cam-thumb.on{border-color:var(--accent)}
.cam-thumb img{width:100%;height:100%;object-fit:cover;display:block;cursor:pointer}
/* «Убрать кадр»: вид прежний — кружок 22 px в углу, а нажимается квадрат
   44×44 вокруг него (том 9; было 22×22 — промах пальцем выбирал сам кадр,
   сверка 26.09). Квадрат выходит за край миниатюры, поэтому обрезает
   картинку она сама, а не рамка, и ряду дан запас сверху */
.cam-thumbs{padding:12px 12px 8px 0;gap:12px}
.cam-thumb{overflow:visible}
.cam-thumb img{border-radius:var(--r-chip)}
.cam-thumb .x{position:absolute;top:-9px;right:-9px;width:44px;height:44px;border:0;background:transparent;
  padding:0;cursor:pointer;color:#fff;display:grid;place-items:center}
/* «убрать» — корзина, не крестик: крестик у нас «закрыть окно» (том 9) */
.cam-thumb .x .x-dot{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:rgba(0,0,0,.6)}
/* кадры шага в цепочке — строкой, каждый открывается на весь экран */
.shots{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.shots .photo{margin:0;padding:0;border:1px solid var(--line2);cursor:pointer;font:inherit}
.shots .photo.denied{cursor:default;display:flex;align-items:center;justify-content:center;color:var(--dim)}
.shots .photo img{display:block}
/* просмотрщик */
.viewer{position:fixed;inset:0;z-index:var(--z-overlay);background:rgba(6,5,10,.94);display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease;touch-action:pan-y}
.viewer.on{opacity:1} .viewer.out{opacity:0}
.viewer .v-stage{max-width:100vw;max-height:100vh;display:flex;align-items:center;justify-content:center;width:100%;height:100%}
.viewer .v-stage img{max-width:100vw;max-height:100vh;object-fit:contain;display:block}
.viewer .v-wait{display:flex;flex-direction:column;align-items:center;gap:10px;color:var(--dim);font-size:13px}
.viewer .v-wait .sk-line{width:120px}
.viewer .v-close{position:absolute;top:calc(10px + env(safe-area-inset-top));right:12px;width:40px;height:40px;border-radius:50%;border:0;background:rgba(255,255,255,.12);color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.viewer .v-count{position:absolute;top:calc(20px + env(safe-area-inset-top));left:0;right:0;text-align:center;color:#fff;font-size:13px;pointer-events:none;font-variant-numeric:tabular-nums}
.viewer .v-nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:64px;border:0;border-radius:12px;background:rgba(255,255,255,.1);color:#fff;font-size:30px;cursor:pointer}
.viewer .v-nav.prev{left:8px} .viewer .v-nav.next{right:8px}
@media(prefers-reduced-motion:reduce){.viewer{transition:none}}
.reasons{display:grid;gap:8px;margin:10px 0}
.btn.wide{width:100%;justify-content:center}
.money-kept{
  display:block;margin-top:2px;font-weight:600;
  color:color-mix(in srgb,var(--danger) 80%,var(--ink));
}
.rejected{margin:0 0 14px;padding-left:20px;display:grid;gap:10px;font-size:14px}
.rejected .dim{display:block;margin-top:2px}

/* ── первый вход ──────────────────────────────────────────────────────────
   Одна мысль на экран крупно: человек читает это на складе между заявками,
   одной рукой, и мелкий текст в этот момент просто пролистывают. */
.onb{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  padding:28px 22px 20px;min-height:calc(100dvh - 190px);
}
.onb-icon{font-size:52px;line-height:1;margin-bottom:18px;color:var(--accent);display:flex;justify-content:center}
.onb-title{margin:0 0 10px;font-size:22px;letter-spacing:-.02em;line-height:1.2}
.onb-body{margin:0;font-size:15px;line-height:1.5;color:var(--dim);max-width:34ch}
.onb-dots{display:flex;gap:7px;margin:22px 0 auto}
.onb-dots span{
  width:7px;height:7px;border-radius:50%;background:var(--line);
  transition:background .2s,width .2s;
}
.onb-dots span.on{width:18px;border-radius:4px;background:var(--accent)}
.onb-foot{display:grid;gap:8px;width:100%;margin-top:24px}

/* ── рабочее место управляющего (Ф7.1, Ф7.2) ──────────────────────────────
   Плотность вместо карточек: у управляющего смена на экране целиком, и десять
   заявок карточками — это уже прокрутка, на которой теряется красная строка.
   Ниже 720px таблицы честно переходят в карточки: на телефоне шесть колонок
   не читаются, а горизонтальная прокрутка прячет как раз то, что важно. */
.panel h3{margin:0 0 6px;font-size:14.5px;letter-spacing:-.01em}
.panel.danger{border-color:color-mix(in srgb,var(--danger) 45%,var(--line))}
.panel.danger h3{color:var(--danger)}
.panel.warn{border-color:color-mix(in srgb,var(--warn) 45%,var(--line))}

.grid{width:100%;border-collapse:collapse;font-size:13.5px}
.grid th{
  text-align:left;font-weight:600;font-size:11.5px;text-transform:uppercase;
  letter-spacing:.04em;color:var(--dim);padding:4px 8px 6px;
  border-bottom:1px solid var(--line);
}
.grid td{padding:8px;border-bottom:1px solid var(--line);vertical-align:top}
.grid tr:last-child td{border-bottom:none}
.grid td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.grid td.cash{font-weight:600}
.grid tr.row-red td{background:color-mix(in srgb,var(--danger) 7%,transparent)}

.zdot{
  display:inline-block;width:8px;height:8px;border-radius:50%;
  margin-right:6px;vertical-align:baseline;background:var(--dim);
}
.zdot.green{background:var(--green-fill)}
.zdot.yellow{background:var(--amber-fill)}
.zdot.red{background:var(--danger)}
.zdot.excluded{background:var(--line)}

.zones{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:6px 0 8px}
.zones .z{
  text-align:center;padding:10px 4px;border-radius:12px;
  background:var(--panel2,color-mix(in srgb,var(--ink) 4%,transparent));
}
.zones .z b{display:block;font-size:22px;line-height:1.1;font-variant-numeric:tabular-nums}
.zones .z span{font-size:11px;color:var(--dim)}
.zones .z.green b{color:var(--green)}
.zones .z.yellow b{color:var(--amber)}
.zones .z.red b{color:var(--danger)}

.chips{list-style:none;display:flex;flex-wrap:wrap;gap:6px;margin:0 0 10px;padding:0}
.chips li{
  display:flex;align-items:center;gap:6px;padding:5px 10px;border-radius:999px;
  background:color-mix(in srgb,var(--danger) 10%,transparent);font-size:12.5px;
}
.chips li b{font-variant-numeric:tabular-nums}

.tag{
  display:inline-block;margin-left:5px;padding:1px 7px;border-radius:999px;
  font-size:11px;background:color-mix(in srgb,var(--ink) 8%,transparent);
  color:var(--tag-ink);vertical-align:middle;
}
.tag.urgent{background:color-mix(in srgb,var(--danger) 15%,transparent);color:var(--danger-ink)}
.tag.warn{background:var(--amber-t);color:var(--amber)}

/* «Разбор» на доске и «Сохранить» в порогах: мишень 26 px по высоте.
   Вид остаётся мелким, а нажимаемая область дотягивает до нормы. */
.btn.tiny{padding:9px 12px;font-size:12.5px;border-radius:var(--r-pill);min-height:40px}
.timeline{margin:0 0 6px;padding-left:18px;font-size:13.5px}
.timeline li{margin-bottom:8px;line-height:1.45}
.timeline small,.timeline em{display:block;color:var(--dim);font-size:12px}
.pauses{list-style:none;margin:0 0 10px;padding:0;font-size:13.5px}
.pauses li{padding:5px 0;border-bottom:1px solid var(--line)}

.checks{display:grid;gap:2px;margin:6px 0 12px}
.check{display:flex;align-items:center;gap:10px;padding:9px 4px;font-size:14.5px}
.check input{width:20px;height:20px;accent-color:var(--accent)}
/* Подпись поля — прямой потомок: правило `.field span` красило подписью
   любой span внутри, включая подсказки и значения. */
.field>span{display:block;font-size:12px;font-weight:600;color:var(--dim);margin-bottom:4px}
.field textarea{
  width:100%;padding:10px;font:inherit;font-size:15px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);resize:vertical;
}
.order.waiting{border-color:color-mix(in srgb,var(--danger) 40%,var(--line))}
.obligations{font-weight:600}
.danger-text{color:var(--danger)}
.counter.warn{color:var(--danger);font-weight:600}

/* Ширина КОНТЕЙНЕРА, а не окна: в веб-версии на мониторе приложение живёт
   в колонке 480 px при широком окне — таблица сжата, а правило по ширине
   окна молчало, и пять колонок ломались по буквам (репорт №6, 17.09) */
.app{container-type:inline-size}
@container (max-width:720px){
  /* Таблица в карточки: шесть колонок на телефоне не читаются, а боковая
     прокрутка прячет ровно то, ради чего экран открыли */
  .grid thead{display:none}
  .grid,.grid tbody,.grid tr,.grid td{display:block;width:100%}
  .grid tr{
    padding:8px 0;border-bottom:1px solid var(--line);
  }
  .grid td{border:none;padding:2px 0}
  .grid td.num{text-align:left}
  .zones{grid-template-columns:repeat(2,1fr)}
}

@media (min-width:900px){
  /* За столом места больше: две колонки панелей вместо ленты вниз */
  #view{max-width:1180px;margin:0 auto}
}

/* ── настройки и поиск ────────────────────────────────────────────────────
   Поле правится прямо в строке: открывать шторку ради одной цифры — лишний
   шаг там, где человек уже смотрит на нужную строку. */
.cell-input{
  width:110px;padding:10px 10px;font:inherit;font-size:15px;text-align:right;min-height:44px;
  font-variant-numeric:tabular-nums;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);color:var(--ink);
}
.cell-input:focus{outline:2px solid var(--accent);outline-offset:1px}
.field input[type="search"]{
  width:100%;padding:10px 12px;font:inherit;font-size:15px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);
}
.search-field{margin-bottom:12px}
/* Шапку жмут на ходу и в перчатке: 34 px — меньше минимальной мишени.
   Кнопка выросла до 44, вид остался прежним (аудит UX 11.09, п. 4.1). */
.iconbtn{
  width:36px;height:36px;border-radius:10px;border:1px solid var(--line2);
  background:var(--panel);color:var(--ink);font-size:16px;line-height:1;
  cursor:pointer;position:relative;display:inline-flex;
  align-items:center;justify-content:center;flex:none;
}
.iconbtn:active{transform:scale(.96)}
/* цифра непрочитанных на звонке: тот же красный, что и на вкладках */
.iconbtn .bdg{
  position:absolute;top:-6px;right:-6px;min-width:16px;height:16px;border-radius:8px;
  background:var(--red-badge);color:var(--on-red);font-size:11px;font-weight:700;font-family:var(--mono);
  display:flex;align-items:center;justify-content:center;padding:0 4px;line-height:1;
}

/* ── колокольчик: лист уведомлений в шторке ─────────────────────────────
   Строка целиком нажимаемая; непрочитанное — с точкой, срочное — с красной.
   Список ограничен по высоте: после отпуска в нём тридцать строк, и шторка
   не должна уезжать за экран вместе с кнопкой «Закрыть». */
/* Список уведомлений прокручивается, а под ним — кнопки «Отметить всё» и
   «Закрыть». Без растворения нижняя карточка обрывалась ровно по краю
   списка, и казалось, что текст обрезан, а не прокручивается
   (обход всех шторок 22.09). Маска гасит последние 18 px. */
.belllist{display:grid;gap:6px;margin-bottom:12px;max-height:58vh;overflow:auto;overscroll-behavior:contain;
  padding-bottom:4px;
  -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 18px),transparent);
  mask-image:linear-gradient(to bottom,#000 calc(100% - 18px),transparent)}
/* прокрутили до конца — маска не нужна, последняя карточка видна целиком */
.belllist.at-end{-webkit-mask-image:none;mask-image:none}
.notif{
  display:flex;align-items:flex-start;gap:10px;width:100%;text-align:left;
  border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  font:inherit;border-radius:14px;padding:11px 12px 11px 13px;cursor:pointer;
  transition:background .3s var(--ease),border-color .3s var(--ease);
}
.notif:active{background:var(--row)}
.notif .dot{width:8px;height:8px;border-radius:50%;background:transparent;flex:none;margin-top:6px}
.notif.unread{border-color:var(--line2);background:var(--panel)}
.notif.unread .dot{background:var(--accent)}
.notif.unread.urgent .dot{background:var(--red-fill)}
.notif .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.notif .body b{font-size:13.5px;font-weight:600}
.notif .body small{font-size:12.5px;color:var(--dim);overflow-wrap:anywhere}
.notif .body time{font-size:11.5px;color:var(--dim);font-family:var(--mono)}
.notif .chev{color:var(--dim);align-self:center;font-size:18px;flex:none;width:12px}
.grid tr[data-open]{cursor:pointer}
.grid tr[data-open]:hover td{background:color-mix(in srgb,var(--ink) 4%,transparent)}

/* ── сводка дня в кассе ──────────────────────────────────────────────────
   Три тождества денежного контура. Спокойный вид по умолчанию: расхождение
   по заявкам в середине дня — норма, и красная рамка на нём приучила бы
   не смотреть на этот блок вообще. Тревожный вид — только когда разошлись
   кошельки или касса: это уже потерянные деньги. */
.daybox{border:1px solid var(--line);border-radius:12px;padding:12px 14px;
  margin:0 0 14px;background:var(--panel)}
.daybox.alarm{border-color:var(--red);background:color-mix(in srgb,var(--red) 6%,var(--panel))}
.daybox .t{font-weight:600;margin-bottom:8px}
.daybox .ident{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;
  padding:4px 0;border-top:1px solid var(--line)}
.daybox .ident:first-of-type{border-top:0}
.daybox .ident .n{min-width:88px;color:var(--dim)}
.daybox .ident .v{font-variant-numeric:tabular-nums}
.daybox .ident.ok .v{color:var(--green)}
.daybox .ident.bad .v{color:var(--red)}
.daybox .ident .m{flex-basis:100%;font-size:12px;color:var(--dim)}
.daybox .hint{margin:8px 0 0;font-size:12px}

/* ── журнал действий (Ф7.5.1) ────────────────────────────────────────────
   Читают его в споре, вслух и быстро: кто, когда, что. Поэтому строка —
   не ячейки таблицы, а короткий абзац, а рамки поиска стоят выше списка
   и всегда на виду. */
.jfilters{margin-bottom:12px}
.jfilters .field{margin:8px 0 6px}
.jfilters select{
  width:100%;padding:10px 12px;font:inherit;font-size:15px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);
}
.jrow2{display:grid;grid-template-columns:1fr 1fr;gap:10px}

.jfilters .chips{margin:10px 0 4px}
button.chip{cursor:pointer;font:inherit;font-size:13px;font-weight:600;
  padding:10px 14px;min-height:44px}
button.chip.on{
  border-color:var(--accent);color:var(--ink);
  background:color-mix(in srgb,var(--accent) 18%,transparent);
}

.jlist{list-style:none;margin:0 0 12px;padding:0;display:grid;gap:6px}
.jrow{
  padding:10px 12px;border-radius:12px;background:var(--panel);
  border:1px solid var(--line);
}
/* Административные записи заметны сами по себе: выдача прав и правка
   справочников — то, что в разборе ищут первым */
.jrow.adm{border-left:3px solid var(--accent)}
/* ── роль рядом с именем (владелец 23.09) ────────────────────────────────
   «Курьер Антон», «Менеджер Саша Стефанов». Роль — приглушённое слово перед
   именем, не плашка: в строке шага (время · кто · причина) любая подложка
   спорит с содержимым и ломает ритм строки. Имя остаётся основным цветом и
   весом строки, поэтому одно с другим не сливается, а высота строки не
   меняется вовсе — ничего не съезжает ни на 320 px, ни в терминале. */
.who-r{
  color:var(--dim);font-weight:500;white-space:nowrap;   /* «Управляющий» не рвётся пополам */
  font-size:.94em;letter-spacing:.01em;
}
.who-n{color:inherit}
/* В комментарии автор набран цветом ссылки: роль там гасим сильнее, иначе
   две яркие части спорят за внимание в короткой строке */
.ph .cmt b .who-r,.cmt b .who-r{color:var(--dim);font-weight:500}
/* Строка шага и разбора сама набрана приглушённым — в ней роль того же
   цвета, что и имя, и «Курьер Павел Курьеров» читается одним словом.
   Поэтому здесь наоборот: имя возвращаем к основному цвету, роль гасим
   на ступень. Вес и высота строки не меняются, поэтому не съезжает ничего */
.ph .m .who-n,.timeline small .who-n{color:var(--ink)}
.ph .m .who-r,.timeline small .who-r{color:var(--dim)}

.jhead{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.jwho{font-size:13px;font-weight:600}
.jtext{font-size:14.5px;margin-top:2px}
.jmeta{display:flex;gap:10px;margin-top:4px;font-size:12.5px;color:var(--dim)}
.jsum{font-variant-numeric:tabular-nums;color:var(--ink);font-weight:600}
.jlink{
  margin-top:4px;padding:8px 0;border:0;background:none;cursor:pointer;
  font:inherit;font-size:13px;color:var(--accent);min-height:40px;
}

.two{display:grid;grid-template-columns:1fr 1fr;gap:8px}

@media (max-width:420px){
  /* .two (кнопки в подвале карточки) на телефоне складывается в столбик —
     двум кнопкам с длинными подписями рядом тесно. А вот фильтры журнала
     (.jrow2) остаются в две колонки: четыре списка столбиком занимали весь
     экран, и до первой записи журнала надо было прокрутить страницу целиком. */
  .two{grid-template-columns:1fr}
  .jrow2{gap:8px}
}

/* ==== недостающая половина вида ═══════════════════════════════════════════
   Аудит 08.09: 26 классов стояли в разметке впустую — правил для них не было
   вовсе. Причина одна и системная: стили писались в соглашении «.btn-primary»,
   а экраны — в соглашении «class="btn primary"». Селектор с дефисом не
   совпадает с двумя классами через пробел никогда, и вторая половина вида
   молча не применялась: поля рисовались голыми браузерными, подписи шли в
   полный рост и вплотную к рамке карточки, «Сохранить» была неотличима от
   «Отмена». Расхождение видно даже внутри самого файла: .btn.wide написан
   через пробел, .btn-block — через дефис. Ниже — то, чего не хватало. */

/* Поля ввода. Стиль был только у .inp, textarea и input[type=search]; обычные
   text/number/tel/date и select внутри .field не имел никто — 34 поля на
   девяти экранах. 16px не вкусовщина: на меньшем размере iOS зумит страницу
   при фокусе, и человек теряет форму из виду. Чекбоксы исключены — у них
   свой размер в .check, ячейки настроек и строки пачки тоже живут отдельно. */
.field input:not([type=checkbox]):not([type=radio]),
.field select,
.item-row input,
.item-row select,
input.search{
  width:100%;font:inherit;font-size:16px;color:var(--ink);background:var(--panel2);
  border:1px solid var(--line2);border-radius:12px;padding:11px 12px;outline:0;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.field input:not([type=checkbox]):not([type=radio]):focus,
.field select:focus,.item-row input:focus,.item-row select:focus,input.search:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-b);
}
.field input::placeholder,.item-row input::placeholder,input.search::placeholder{color:var(--dim)}
.field select,.item-row select{appearance:none;-webkit-appearance:none;padding-right:38px}

/* Поле даты на iOS. Safari рисует его по-своему: текст по центру, своя
   высота, свой внутренний отступ — и в ряду с обычным списком поле
   оказывается выше соседа и с текстом не у того края (замечание владельца
   14.09, форма заявки). Снимаем родную отрисовку и задаём ту же высоту,
   что у select, — иначе grid их не выровняет, потому что растягивается
   обёртка .field, а не само поле внутри неё. */
.field input[type="date"],.field select{min-height:44px;box-sizing:border-box}
.field input[type="date"]{
  -webkit-appearance:none;appearance:none;display:block;text-align:left;
}
.field input[type="date"]::-webkit-date-and-time-value{text-align:left;margin:0}
.field input[type="date"]::-webkit-calendar-picker-indicator{opacity:.55}

/* Подсказка внутри поля: <small> под полем ввода шёл в полный размер
   строкой без отступа — читался как часть подписи следующего поля */
.field small{display:block;font-size:12.5px;font-weight:400;color:var(--dim);
  line-height:1.4;margin-top:6px}

/* Блок позиций кончается подсказкой; без отступа она прилипает к подписи
   следующего поля */
#itemsBlock{margin-bottom:14px}

/* Подпись и приглушённый текст. .hint не был определён вовсе (33 места):
   текст шёл в полный рост и в полный цвет. Внутри карточки ему нужен ещё и
   отступ — у .order его нет, отступы живут на её частях (.top, .who, .foot),
   поэтому подсказка вставала вплотную к рамке. */
.hint{font-size:12.5px;color:var(--dim);line-height:1.45;margin-top:6px}
.dim{color:var(--dim)}
.order>.hint{padding:0 14px;margin-top:4px}

/* Пары полей рядом: «Доставка / Красная зона» и «Дата / Срочность» задуманы
   в строку, а без правила вставали друг под друга и растягивали форму. */
.pair,.row{display:grid;grid-template-columns:1fr 1fr;gap:10px}

/* Шапка шторки: заголовок и пояснение под ним. */
.sheet-head{margin-bottom:16px}
.sheet-head h2{font-size:var(--fs-17);font-weight:700;letter-spacing:-.02em;margin-bottom:6px}
.sheet-head .dim{font-size:13px;line-height:1.5}

/* Поиск и кнопка рядом с ним в одну строку. */
.toolbar{display:flex;gap:8px;align-items:center;margin-bottom:14px}
.toolbar .search{flex:1;min-width:0}
.toolbar .btn{flex:none;white-space:nowrap}

/* Кнопки внизу карточки клиента: их три, на телефоне они обязаны переноситься,
   а не уезжать за скруглённый край. */
.row-actions{display:flex;flex-wrap:wrap;gap:8px;padding:10px 14px 13px}
.row-actions .btn{flex:1 1 auto}

/* Заголовок блока с кнопкой справа: «Позиции   + позиция». */
.block-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:16px 0 8px;font-weight:700}

/* Позиция заявки: пять полей и крестик. Сеткой по областям, а не в строку —
   в ленту шириной с телефон пять полей не встают, и строка уезжала бы в
   горизонтальную прокрутку ровно там, где менеджер набирает заявку. */
.item-row{
  display:grid;gap:8px;margin-bottom:10px;padding:12px;
  background:var(--panel2);border:1px solid var(--line);border-radius:14px;
  grid-template-columns:1fr 1fr 40px;
  grid-template-areas:
    "name name drop"
    "qty  price price"
    "src  src   src"
    "serial serial serial";
}
/* те же области и для шторки правки состава (order.js): там поля зовутся
   iname/iqty/iprice/iserial и без этого ложились автопотоком — «цена»
   превращалась в пустой квадрат, серийник уезжал (аудит В1+, 21.09) */
.item-row [name=name],.item-row [name=iname]{grid-area:name}
.item-row [name=qty],.item-row [name=iqty]{grid-area:qty}
.item-row [name=price],.item-row [name=iprice]{grid-area:price}
.item-row [name=source]{grid-area:src}
.item-row [name=serial],.item-row [name=iserial]{grid-area:serial}
.item-row [data-drop],.item-row [data-drop-item]{grid-area:drop}

/* Мелкие кнопки, которых не было: «+ позиция» и крестик у позиции. */
.btn.icon{padding:0;width:40px;height:40px;font-size:20px;flex:none}

/* Серийники чипами, а не строкой в подбор: их сверяют глазами по одному. */
/* Позиции в карточке склада: маркер «disc» рисовался в четырёх пикселях
   от края карточки, поверх рамки. Свой значок внутри строки (п. 2.5). */
.order ul.items{list-style:none;margin:0;padding:4px 14px 0}
.order ul.items li{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;
  padding:5px 0;border-top:1px dashed var(--line);font-size:14.5px;
}
.order ul.items li:first-child{border-top:0}
.order ul.items li .src{font-family:var(--mono);font-size:11.5px;color:var(--dim);font-style:normal}

/* Серийник — главное действие выдачи: его сверяют с коробкой. Был 12 px
   серым, то есть мельче и тише названия клиента (аудит UX 11.09, п. 3.2). */
.serials{display:flex;flex-wrap:wrap;gap:6px;padding:8px 14px 0}
.serials code{
  font-family:var(--mono);font-size:16px;font-weight:700;letter-spacing:.04em;
  background:var(--row);border:1px solid var(--line2);border-radius:8px;
  padding:6px 10px;color:var(--ink);
}

/* Пачка инкассации — свой цвет ярлыка, как у остальных типов заявок. */
.badge-type.pickup{background:var(--amber-t);color:var(--amber);border:1px solid var(--amber-b)}

/* Пустое состояние в разборе расхождений (свои имена, не .state-*). */
.empty{text-align:center;padding:22px 16px}
.empty-title{font-size:15px;font-weight:700;color:var(--ink);margin-bottom:4px}
.empty-hint{font-size:12.5px;color:var(--dim);line-height:1.5;max-width:280px;margin:0 auto}

/* Плитка «без норматива» — не тревога, а пропуск в настройке: она обязана
   быть спокойнее зелёной, иначе ноль в ней читается как достижение. */
.zones .z.gray{color:var(--dim)}
/* Сумма в происшествии — то, ради чего его открывают. */
.hint.amount{font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}

/* Переключатель типа заявки: пять кнопок в ленту шириной с телефон не встают.
   Раньше flex:1 давил их до двух строк текста — теперь строка прокручивается
   вбок, а там где кнопок две-три, они по-прежнему занимают всю ширину. */
/* Полоса типов шире экрана: из пяти видно два с половиной, и ничто
   не намекало, что её можно тянуть. Тень у правого края появляется, пока
   есть что прокручивать (аудит UX 11.09, п. 2.6). */
.seg,.segmented{
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  background-image:linear-gradient(to left,var(--panel2),transparent 24px);
  background-position:right center;background-repeat:no-repeat;
  background-size:26px 100%;background-attachment:local;
}
.seg::-webkit-scrollbar,.segmented::-webkit-scrollbar{display:none}
.seg button,.segmented button{flex:1 0 auto;white-space:nowrap}

/* ==== отступы и мелочи после осмотра всех ролей 09.09 ═══════════════════ */

/* Карточки в списках стояли вплотную: у .order не было отступа вовсе, и лента
   заявок читалась одной простынёй без границ между делами. */
.order + .order,
.order + .panel,
.panel + .order{margin-top:8px}
/* лента: карточки-кнопки тоже соседи, у них тот же зазор */
button.as-card + button.as-card{margin-top:8px}

/* Счётчик над списком («4 заявки на сегодня», «В работе: 1») висел левее
   карточек — строка и список начинались с разных мест. */
.counter{margin:2px 0 8px}

/* Списки выбора: appearance выключен ради единого вида, а стрелку рисовать
   забыли — поле «Все виды» ничем не отличалось от поля ввода, и было неясно,
   что по нему вообще можно нажать. Рисуем шеврон фоном. */
select.inp,
.field select,
.item-row select{
  background-image:
    linear-gradient(45deg,transparent 50%,var(--dim) 50%),
    linear-gradient(135deg,var(--dim) 50%,transparent 50%);
  background-position:calc(100% - 19px) center,calc(100% - 13px) center;
  background-size:6px 6px,6px 6px;
  background-repeat:no-repeat;
}

/* ── Доска смены на телефоне (владелец 23.09) ───────────────────────────
   Таблица на узком экране разворачивалась в «метка — значение»: шесть
   строк на заявку и колонка подписей в половину ширины. Здесь заявка —
   карточка в три строки: номер и клиент, курьер, время · сумма · разбор. */
.shiftlist{display:flex;flex-direction:column;gap:8px}
.shiftcard{
  background:var(--row);border:1px solid var(--line);border-radius:12px;
  padding:10px 12px;display:flex;flex-direction:column;gap:4px;
}
.shiftcard.red{border-color:var(--red-b)}
.sc-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:14px}
.sc-no{font-family:var(--mono);font-weight:700;color:var(--dim)}
.sc-client{font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.sc-who{font-size:12.5px;color:var(--dim)}
.sc-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px}
.sc-time{color:var(--ink);font-variant-numeric:tabular-nums}
.sc-foot .money{font-weight:600}
.sc-foot .btn{margin-left:auto}
/* «Показать ещё» — тихая кнопка под списком, во всю ширину блока */
.shiftlist + .more{margin-top:8px;width:100%;justify-content:center}

/* Настройка правится в одну строку: подпись сверху, поле и «Сохранить» рядом.
   Разложенные по трём этажам, восемь порогов занимали три экрана. */
.setting-edit{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.setting-edit .cell-input{flex:0 0 auto}

@container (max-width:720px){
  /* Таблица, свёрнутая в карточки, теряла шапку — и значения оставались без
     имён: «2 · Учебный клиент · — · 0 мин · 0 ₽» не читается никак. Подпись
     берём из самой ячейки, поэтому она не может разойтись с данными. */
  .grid tr{padding:10px 0}
  /* Строкой, а не сеткой: в ячейке кроме текста бывает значок зоны, и в
     сетке каждая часть становилась отдельной клеткой — точка уезжала в
     колонку значения, а имя клиента падало на строку ниже. */
  .grid td[data-label]{
    display:flex;flex-wrap:wrap;gap:4px 10px;align-items:baseline;padding:3px 0;
  }
  .grid td[data-label]::before{
    content:attr(data-label);
    flex:0 0 auto;min-width:92px;
    color:var(--dim);font-size:12px;font-weight:600;
  }
  .grid td.num[data-label]{text-align:left}
  /* ячейка без подписи (кнопка разбора) занимает всю ширину строки */
  .grid td:not([data-label]){padding-top:6px}
  .grid td.setting-edit{display:flex}
}

/* Под плавающей навигацией оставался просвет, и в него подглядывала
   обрезанная строка содержимого — на каждом экране, где список длиннее
   окна. Растворяем низ ленты в фон: текст уходит вниз, а не обрывается
   на полуслове. Ниже полосы действия (22) и самой навигации (30). */
.view::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:124px;z-index:var(--z-fade);
  pointer-events:none;
  background:linear-gradient(180deg,transparent,var(--bg) 62%);
}

/* «Ещё» — те же разделы, что и внизу, только списком в шторке. Строка целиком
   нажимаемая: попадать в мелкое слово одной рукой на ходу невозможно. */
.morelist{display:grid;gap:6px;margin-bottom:12px}
.morelist button{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  font:inherit;font-size:15px;font-weight:600;
  border-radius:var(--r-chip);padding:14px;cursor:pointer;min-height:48px;
  transition:background .3s var(--ease),border-color .3s var(--ease);
}
.morelist button .ic{font-size:17px;width:24px;text-align:center;color:inherit;flex:none;display:flex;justify-content:center}
.morelist button[aria-current]{border-color:var(--accent);color:var(--accent)}
.morelist button[aria-current] .ic{color:var(--accent)}
.morelist button:active{background:var(--row)}

/* ── выбор дня и календарь на экране заявок ─────────────────────────────
   Число в клетке — весь смысл календаря: без него дни открывают наугад,
   чтобы понять, есть ли там что-нибудь. */
/* плашка дня — компактная, в строку справа (Юрий 19.09, №85): стрелки и
   дата с календарём, одна на все списки по дням */
/* Плашка дня. Раньше это были три одинаковые коробки подряд — «‹», дата,
   «›»: один фон, одна рамка, одно скругление 10 px. Дата ничем не отличалась
   от стрелок, хотя делает совсем другое — раскрывает календарь, и ничто на
   это не намекало. А рядом, в той же строке, «Все / Мои» — капсулы: два
   разных скругления в одном ряду (владелец 24.09, «посмотри глазами»).
   Теперь это один орган управления: общая капсула, стрелки внутри неё
   приглушены, дата — светлая кнопка со значком календаря и шевроном. */
.daypick{
  display:inline-flex;align-items:center;gap:2px;margin:0;flex:none;
  background:var(--panel2);border:1px solid var(--line2);border-radius:999px;padding:3px;
}
.daypick button{
  border:0;background:none;color:var(--ink);
  font:inherit;border-radius:999px;cursor:pointer;min-height:36px;
  transition:transform .25s var(--ease),background .3s var(--ease),color .3s var(--ease);
}
.daypick button:active{transform:scale(.97)}
.daypick-arrow{flex:none;width:28px;font-size:17px;line-height:1;color:var(--dim)}
.daypick-arrow:hover{background:var(--row);color:var(--ink)}
.daypick-label{
  flex:none;font-size:13.5px;font-weight:700;padding:0 11px;background:var(--panel);
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
}
.daypick-label:hover{background:var(--rowh)}
.daypick-label .cal-i{color:var(--accent);flex:none}
.daypick-label .cal-c{color:var(--dim);flex:none;transition:transform .2s var(--ease)}
.daypick-label[aria-expanded="true"]{background:var(--accent-t)}
.daypick-label[aria-expanded="true"] .cal-c{transform:rotate(180deg)}
.daypick-label:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.listbar .counter{margin:0}

.calendar{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
  padding:12px;margin-bottom:12px;
}
.cal-head{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-bottom:10px;font-weight:700;font-size:14.5px;
}
.cal-nav{
  width:34px;height:34px;flex:none;border:1px solid var(--line2);background:var(--panel2);
  color:var(--ink);border-radius:10px;font:inherit;font-size:18px;line-height:1;cursor:pointer;
}
.cal-nav:active{transform:scale(.95)}
.cal-week{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;margin-bottom:4px}
.cal-week span{text-align:center;font-size:11px;font-weight:600;color:var(--dim)}
.cal-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}
.cal-cell{
  aspect-ratio:1;border:1px solid transparent;background:var(--panel2);color:var(--ink);
  border-radius:var(--r-chip);cursor:pointer;font:inherit;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  transition:transform .2s var(--ease),background .3s var(--ease),border-color .3s var(--ease);
}
.cal-cell.empty{background:transparent;cursor:default}
.cal-cell b{font-size:13.5px;font-weight:600}
.cal-cell i{font-style:normal;font-size:11px;font-weight:700;font-family:var(--mono);color:var(--accent)}
.cal-cell.now{border-color:var(--line2)}
.cal-cell.on{background:var(--accent);color:var(--on-accent);border-color:transparent}
/* дни внутри выбранного периода: тише краёв, но видно, что они входят */
.cal-cell.in-range{background:var(--accent-t);border-color:var(--accent-b)}
.cal-cell.in-range i{color:var(--accent)}
.cal-cell.on i{color:var(--on-accent)}
.cal-cell:active{transform:scale(.94)}

/* счёт и фильтр в одной строке: два переключателя подряд съели бы экран */
.listbar{position:relative;display:flex;align-items:center;justify-content:space-between;gap:10px;margin:2px 0 10px}
/* Календарь дня всплывает под плашкой, а не встаёт блоком в поток: в
   терминале блок растягивался на всю ширину раздела и клетки становились
   квадратами во весь экран (владелец 23.09). Ширина фиксирована — столько
   же, сколько у календаря периода в «Требует действия» */
.daycal{
  position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-pop);
  width:320px;max-width:calc(100vw - 28px);
}
/* в полосе дня плашка стоит справа — календарь прижимается к ней */
.listbar .daycal{left:auto;right:0}
/* Слой — цельная карточка: подсказка «Выберите начало периода» жила выше
   календаря на голом фоне и читалась как оторванная строка (владелец 23.09) */
.daycal{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
  padding:8px;box-shadow:var(--shadow-float);
}
.daycal .calendar{margin:0;padding:0;border:0;background:none;box-shadow:none}
.daycal .hint{margin:0 2px 8px;font-size:12.5px}
/* 320 px (старые маленькие телефоны): «Все / Мои» и плашка дня не влезали в
   одну строку — правая стрелка уезжала за край (проверка боя 21.09) */
@media (max-width:349px){.listbar{flex-wrap:wrap}.listbar .daypick{margin-left:auto}}
.listbar .counter{margin:0}
.seg.tiny{margin:0;flex:none;padding:3px}
.seg.tiny button{font-size:12.5px;padding:8px 12px;min-height:36px}
/* Календарь периода всплывает НАД содержимым и ничего не двигает
   (владелец 23.09: «должен просто быть поверх и не трогать другое»).
   Блоком в потоке он занимал строку и сдвигал весь список вниз. */
.incbar{position:relative}
.incal{
  /* слой между плавающей навигацией (30) и шторкой (40): календарь обязан
     накрывать список и панель, но сам уходить под шторку, если та открыта */
  position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-pop);width:320px;max-width:calc(100vw - 28px);
  background:var(--panel);border:1px solid var(--line2);border-radius:var(--r-card);
  padding:8px;box-shadow:var(--shadow-float);
}
.incal .hint{margin:0 0 8px}
/* липкая полоса — свой слой с z-band, и календарь внутри неё уходил ПОД
   нижнюю навигацию: на 320 дни 21–30 прятались за вкладками (проверка окон
   24.09). Пока календарь открыт, полоса поднимается на слой календаря */
.incbar:has(.incal){z-index:var(--z-pop)}
/* то же в терминале: полоса заявок — слой z-band-low, а шапка таблицы под
   ней — z-band, и строка колонок ложилась поверх дней недели и первой
   недели месяца (проверка окон 24.09, 1440 и 1920) */
.desk-toolbar:has(.daycal){z-index:var(--z-pop)}
/* месяц внутри слоя периода — обычный блок: вложенный всплывающий слой
   отрывал подсказку «Выберите начало периода» в отдельную карточку над
   календарём (проверка окон 24.09) */
.incal .daycal{position:static;width:auto;max-width:none;padding:0;border:0;background:none;box-shadow:none}
/* на узком экране — от края до края полосы фильтров */
@media (max-width:420px){.incal{left:0;right:0;width:auto}}

/* «Требует действия»: состояние и порядок в одной строке, как тулбар
   заявок, а не два переключателя во всю ширину друг под другом (№76) */
.incbar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:12px;
  position:sticky;top:0;z-index:var(--z-band);background:var(--bg);padding:2px 0 10px;box-shadow:0 8px 8px -8px var(--bg)}
.incbar .seg button{flex:none}
/* период и порядок стоят в строку с состоянием, а не двумя полосами
   во всю ширину: поле `.pick` по умолчанию тянется, как поле ввода */
.incbar .pick{width:auto;flex:none;min-width:150px;max-width:210px;
  font-size:13px;background:var(--panel);border-radius:999px;min-height:40px}
.incbar .hint{margin:0;flex-basis:100%}
.incbar .desk-days input[type=date]{min-height:40px;max-width:150px}
body.deskmode .incbar .desk-days input[type=date]{min-height:34px}
body.deskmode .incbar{top:-14px;padding-top:6px}
body.deskmode .incbar .pick{min-height:34px;padding-top:6px;padding-bottom:6px}

/* ==== рабочее место под большой экран (Ф7, 15.09) ====
   Оболочка та же — шапка, шторка, тосты, — но телефонная рамка 480 px
   снимается, а внутри .view живёт сетка «навигация слева · работа справа».
   Вложенные экраны получают свой .screen с собственной прокруткой. */
body.deskmode .app{max-width:none;border:0}
body.deskmode .screen{padding-bottom:24px}
body.deskmode .view::after{display:none}
/* правило «за столом — колонка 1180 по центру» писалось для мобильных экранов
   на мониторе; у рабочего места своя сетка на всю ширину */
body.deskmode #view{max-width:none;margin:0}
/* «Ещё» в шапке дублирует навигацию слева */
body.deskmode #goMore{display:none}
.desk{position:absolute;inset:0;display:grid;grid-template-columns:224px minmax(0,1fr);background:var(--bg)}
.desk-nav{
  display:flex;flex-direction:column;gap:4px;padding:14px 10px;
  border-right:1px solid var(--line);background:var(--panel2);overflow-y:auto;
}
.desk-brand{font-size:15px;font-weight:700;letter-spacing:-.02em;padding:4px 10px 12px}
.desk-brand small{display:block;font-size:11px;font-weight:500;color:var(--dim);letter-spacing:0}
.desk-menu{display:flex;flex-direction:column;gap:2px}
.desk-menu button{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  border:1px solid transparent;background:transparent;color:var(--ink);
  font:inherit;font-size:14px;font-weight:600;border-radius:12px;padding:9px 10px;
  cursor:pointer;min-height:40px;transition:background .25s var(--ease),color .25s var(--ease);
}
.desk-menu button:hover{background:var(--rowh)}
.desk-menu button.on{background:var(--accent-t);color:var(--accent);border-color:var(--accent-b)}
.desk-menu button .ic{width:20px;text-align:center;color:inherit;font-size:15px;flex:none;display:flex;justify-content:center}
.desk-menu button .ic svg{width:20px;height:20px}
.desk-menu button.on .ic{color:var(--accent)}
.desk-menu button .bdg{
  margin-left:auto;min-width:20px;height:20px;border-radius:10px;padding:0 6px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent-t);color:var(--accent-ink);font-family:var(--mono);font-size:11px;font-weight:700;
}
.desk-menu button .bdg.alarm{background:var(--red-badge);color:var(--on-red)}
/* учётки: люди, между которыми переключаются за одним столом */
.desk-accounts{margin-top:auto;padding-top:10px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:2px}
.desk-acc-title{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);padding:2px 10px 6px}
.desk-acc{display:flex;align-items:center;gap:2px}
.desk-acc > button:first-child{
  flex:1;min-width:0;text-align:left;border:1px solid transparent;background:transparent;color:var(--ink);
  font:inherit;border-radius:10px;padding:6px 10px;cursor:pointer;
}
.desk-acc > button:first-child b{display:block;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.desk-acc > button:first-child small{display:block;font-size:11px;color:var(--dim)}
.desk-acc > button:first-child:hover{background:var(--rowh)}
.desk-acc.on > button:first-child{background:var(--accent-t);border-color:var(--accent-b)}
.desk-acc.on b{color:var(--accent)}
.desk-acc .x{border:0;background:transparent;color:var(--dim);font:inherit;font-size:15px;cursor:pointer;padding:6px;border-radius:8px}
.desk-acc .x:hover{color:var(--red);background:var(--red-t)}
.desk-acc-add{border:1px dashed var(--line2);background:transparent;color:var(--dim);font:inherit;font-size:12.5px;border-radius:10px;padding:7px 10px;cursor:pointer;text-align:left;margin-top:4px}
.desk-acc-add:hover{color:var(--ink);border-color:var(--accent-b)}
.desk-mobile{padding:10px;font-size:12.5px;color:var(--dim);text-decoration:none;border-radius:10px;display:flex;align-items:center;gap:6px}
.desk-mobile .ic{display:flex}
.desk-mobile:hover{background:var(--rowh);color:var(--ink)}
.desk-main{position:relative;overflow:hidden;min-width:0}
.desk-main.sec-board,.desk-main.sec-orders{overflow:hidden}
/* Встроенный мобильный экран на всю ширину: его карточки раскладываются
   сеткой в две-три колонки, а всё «ленточное» — переключатели, счётчики,
   поиск, формы, состояния — тянется на всю строку. Логика экранов не
   меняется, только раскладка: две версии на одной логике не разъезжаются. */
.desk-main > .screen{
  display:flex;flex-wrap:wrap;gap:12px;align-content:flex-start;align-items:stretch;
  padding:18px 24px 24px;max-width:1480px;
}
/* сетка гридом здесь не годится: Chrome считает высоту строки без учёта
   кнопок во вложенном гриде .foot.two, и нижняя часть карточки обрезается */
.desk-main > .screen > *{flex:1 1 100%;min-width:0}
/* Карточки: ширина фиксирована долей ряда — неполный последний ряд больше
   не растягивается на 540 px; высота в ряду одна (align-items:stretch),
   кнопки прижаты к низу — карточка с «активных заявок 4» и без него стоят
   вровень (репорты №38–40, общий корень) */
.desk-main > .screen > :is(.order,.panel,.kpi){flex:0 0 calc(33.333% - 8px);max-width:calc(33.333% - 8px);margin:0}
.desk-main > .screen > .order{display:flex;flex-direction:column}
.desk-main > .screen > .order > .foot:last-child{margin-top:auto}
@media(max-width:1250px){.desk-main > .screen > :is(.order,.panel,.kpi){flex-basis:calc(50% - 6px);max-width:calc(50% - 6px)}}
/* раскрытая пачка у кассира и любая форма — одной колонкой читаемой ширины */
.desk-main > .screen > form,.desk-main > .screen > .order:only-child{flex-basis:100%;max-width:760px}
/* То же, когда карточка в разделе одна, но рядом стоит полоса фильтров:
   `:only-child` в этом случае не срабатывал, и единственная заявка висела
   обрубком в треть экрана (владелец 23.09). `:has` читается так: в экране
   нет второй карточки — значит она одна */
.desk-main > .screen:not(:has(> .order ~ .order)) > .order{flex-basis:100%;max-width:760px}
/* журнал: фильтры слева узкой колонкой, лента записей — всё остальное */
.desk-main > .screen > .panel.jfilters{flex:0 0 320px;max-width:320px;position:sticky;top:0}
.desk-main > .screen > .jlist{flex:1 1 480px;max-width:900px;margin:0}
/* профиль и пороги — это формы и настройки, не картотека: одна читаемая
   колонка по центру, а не мобильные блоки, растянутые на 1900 px (№36, №37) */
.desk-main.sec-profile > .screen,.desk-main.sec-settings > .screen{display:block;max-width:820px;margin:0 auto}
.desk-main.sec-profile > .screen > *,.desk-main.sec-settings > .screen > *{max-width:none}
.desk-main.sec-profile > .screen .panel,.desk-main.sec-settings > .screen .panel{margin-bottom:12px}
/* поиск: таблица на всю ширину читаемой полосы, без карточной сетки */
.desk-main.sec-search > .screen{display:block;max-width:1100px}
/* ══════════════════════════════════════════════════════════════════════
   ВИД РАБОЧЕГО МЕСТА (23.09, владелец: «мобильную заредизайнили, а в вебе
   до сих пор огромные кнопки»)

   Своя вёрстка под большой экран есть только у трёх разделов: доски, заявок
   и отчётов. Остальные девять — «Требует действия», касса, склад, люди,
   клиенты, журнал, пороги, поиск, профиль — показывают те же экраны, что
   и телефон, разложенные в колонки. Поэтому пара кнопок, которая на
   телефоне честно делит строку пополам, на мониторе превращается в две
   плашки по 235 px, а редкое действие («Роли», «Поднять выше») кричит
   громче содержимого карточки.

   Ниже — правила, которые лечат причину, а не каждый экран: в терминале
   кнопка не растягивается под ширину карточки, высоты считаются под мышь
   (цель 32–36 px вместо 44 под палец), а главное действие остаётся одно.
   Телефона это не касается — всё внутри `body.deskmode`.
   ══════════════════════════════════════════════════════════════════════ */

/* 1. Высоты под мышь. Сегменты и поля терминала уже были 34–36 — кнопки
      и пункты меню равняются на них, а не на мобильные 44. */
body.deskmode .btn{min-height:40px;font-size:13.5px;padding:7px 14px}
body.deskmode .btn-small,body.deskmode .btn.small{min-height:32px;font-size:12.5px;padding:5px 11px}
body.deskmode .btn-block,body.deskmode .btn.block{min-height:40px;font-size:13.5px;padding:7px 16px}
/* высоту пункта меню держал не min-height, а внутренний отступ: 9 px сверху
   и снизу при кегле 14 дают те же 40 — поэтому ужимаем именно отступ */
body.deskmode .desk-menu button{min-height:36px;font-size:13.5px;padding:6px 10px}
body.deskmode .field input,body.deskmode .field select,body.deskmode .field textarea{min-height:34px}

/* 2. Действия карточки — строкой справа, по содержимому. Две кнопки во всю
      ширину читаются как основное содержимое карточки, хотя это управление. */
body.deskmode .order .foot,body.deskmode .order .row-actions{
  justify-content:flex-start;gap:8px;flex-wrap:wrap;
}
/* Подряд идущие ряды кнопок одной карточки — это одна группа действий,
   а не два разных блока: между ними обычный просвет, а не отступ секции */
body.deskmode .order .foot + .foot,
body.deskmode .order .foot + .row-actions{margin-top:8px}
body.deskmode .order .foot.two{display:flex;grid-template-columns:none}
body.deskmode .order .foot .btn,body.deskmode .order .row-actions .btn{
  flex:0 0 auto;width:auto;min-height:32px;font-size:13px;padding:6px 14px;
}
body.deskmode .order .foot.two .btn{padding-left:14px;padding-right:14px}
body.deskmode .order .foot>.btn:only-child{flex:0 0 auto}
/* Кнопки прижимаются к низу карточки — иначе в ряду, где у одного клиента
   есть адрес, а у другого нет, кнопки стоят на разной высоте и ряд читается
   как сломанный. Правило было только для `.foot`, но у клиентов хвост
   карточки называется `.row-actions`, а у случаев подряд идут два `.foot`
   («Заявка и история» и «Закрыть случай») — прижимаем первый из хвоста. */
body.deskmode .desk-main > .screen > .order > .foot:first-of-type,
body.deskmode .desk-main > .screen > .order > .row-actions:last-child{margin-top:auto}

/* 3. Одно громкое действие на карточку. Когда рядом две залитые кнопки,
      глаз не понимает, какая главная; вторая становится тихой. */
body.deskmode .order .foot .btn-ghost,body.deskmode .order .row-actions .btn-ghost{
  background:transparent;border-color:var(--line2);color:var(--dim);
}
body.deskmode .order .foot .btn-ghost:hover,body.deskmode .order .row-actions .btn-ghost:hover{
  color:var(--ink);border-color:var(--accent-b);background:var(--rowh);
}

/* 4. Колонка профиля и порогов: кнопка по содержимому, а не во всю полосу
      в 800 px — «Начать смену» шириной с экран выглядит как баннер. */
body.deskmode .desk-main.sec-profile .btn-block,
body.deskmode .desk-main.sec-settings .btn-block{width:auto;min-width:210px}
body.deskmode .desk-main.sec-profile .panel>.btn-block,
body.deskmode .desk-main.sec-profile>.screen>.btn-block{display:inline-flex}

/* 5. Таблицы плотнее: строка 44 px под палец на мониторе съедает треть
      списка. 38 px — и день целиком виден без прокрутки. */
body.deskmode .grid.wide td,body.deskmode .grid.wide th{padding:7px 10px}
body.deskmode .desk-table{font-size:13px}

/* ── Верхняя полоса рабочего места ──────────────────────────────────────
   Название раздела в ней повторяло подсвеченный пункт меню, а имя сервиса
   стояло ниже, в боковой панели, — вместе это читалось как перепутанные
   местами заголовки (владелец 23.09). В терминале полоса оставляет только
   то, чего в меню нет: дату и счёт слева, колокольчик и поиск справа.
   На телефоне всё как было: там меню нет, и заголовок экрана —
   единственный ответ на «где я». */
body.deskmode .appbar{padding:9px 16px}
/* Прячем только название раздела — оно повторяет подсвеченный пункт меню.
   Не display:none: экранному диктору подсветка ничего не говорит, и
   заголовок ему по-прежнему читается. */
body.deskmode .appbar .ttl #appTitleText{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
/* А дата и счёт («23 сентября · 4 заявки в работе») в меню не показаны —
   они остаются и становятся основной строкой полосы */
body.deskmode .appbar .ttl small{font-size:13px;color:var(--dim);font-weight:500}

/* каркас первого кадра: та же сетка, что у настоящего раздела, иначе
   загрузка выглядит сломанной вёрсткой, а не ожиданием */
.desk-boot .desk-nav .skeleton{padding:8px 10px}
.desk-boot .screen{
  display:flex;flex-wrap:wrap;gap:12px;align-content:flex-start;padding:18px 24px;
}
.desk-boot .sk-bar{
  flex:1 1 100%;height:44px;border-radius:var(--r-card);
  background:linear-gradient(90deg,var(--row) 25%,var(--rowh) 37%,var(--row) 63%);
  background-size:400% 100%;animation:skWave 1.4s linear infinite;
}
/* высота близка к настоящей карточке раздела, иначе на её месте
   появляется рывок, когда данные доезжают. Только для карточек прямо
   в ряду первого кадра: с 26.09 каркас рисуется в форме раздела, и это
   правило ужимало каждую его карточку до трети места — плитки доски
   вставали узкими столбиками 54–80 px (снимок владельца 27.09) */
.desk-boot .screen > .sk-card{flex:0 0 calc(33.333% - 8px);max-width:calc(33.333% - 8px);min-height:150px}
@media(max-width:1250px){
  .desk-boot .screen > .sk-card{flex-basis:calc(50% - 6px);max-width:calc(50% - 6px)}
}

/* доска */
.desk-board{position:absolute;inset:0;overflow-y:auto;padding:18px 24px 24px}
.desk-kpis{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;margin-bottom:14px}
.desk-kpis .kpi .n{font-size:24px}
.desk-cols{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:14px;align-items:start}
.desk-col{min-width:0}
/* Боковая колонка прилипает, но если она выше окна — крутится внутри себя,
   иначе страница растягивалась на длину списка свободных, а левая колонка
   при прокрутке оставалась пустой (репорт №58, 19.09) */
.desk-col.side{position:sticky;top:0;max-height:100vh;overflow-y:auto;scrollbar-width:thin}
.desk-col.side .grid th{white-space:nowrap}
.desk-col .panel{overflow-x:auto}
.grid.wide td,.grid.wide th{padding:9px 10px;white-space:nowrap}
.grid.wide td.who{white-space:normal;min-width:200px}
.grid.wide td.who .as-link{font-weight:600}
.grid.wide th.num{text-align:right}
.as-link{
  background:none;border:0;padding:0;font:inherit;color:var(--ink);cursor:pointer;
  text-decoration:underline;text-decoration-color:var(--line2);text-underline-offset:3px;
}
.as-link:hover{color:var(--accent);text-decoration-color:var(--accent)}
.grid td small{display:block;font-size:11.5px}

/* заявки: таблица слева, панель справа */
.desk-orders{position:absolute;inset:0;display:grid;grid-template-columns:minmax(0,1fr) 0;transition:grid-template-columns .3s var(--ease)}
.desk-orders.with-pane{grid-template-columns:minmax(0,1fr) minmax(400px,470px)}
.desk-list{overflow-y:auto;padding:14px 24px 24px;min-width:0}
.desk-toolbar{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:12px;
  position:sticky;top:-14px;z-index:var(--z-band-top);background:var(--bg);padding:8px 0 8px;
}
/* «Заявки»: прокручивается только таблица. Её высота — остаток окна под
   отборами, а не «экран минус 190 px»: при крупном масштабе отборы выше, и
   прокручивался ещё и весь список — шапка колонок уезжала вместе с ним и
   ложилась поверх отборов (владелец 26.09). Отборы теперь и слоем выше
   шапки: на совсем низком окне она уходит под них, а не поверх */
.desk-orders .desk-list{display:flex;flex-direction:column}
.desk-orders .desk-list > *{flex:none}
.desk-orders .desk-list > .desk-tablewrap{flex:1 1 auto;min-height:120px;max-height:none}
.desk-toolbar .seg{margin:0;padding:3px;flex:none}
.desk-toolbar .seg button{flex:none;padding:7px 11px;min-height:34px;font-size:12.5px;white-space:nowrap}
.desk-toolbar .seg button i{font-style:normal;font-family:var(--mono);font-size:11px;opacity:.7;margin-left:2px}
.desk-days{position:relative;display:flex;align-items:center;gap:4px;flex:none}
.desk-days input[type=date],.desk-toolbar select,.desk-toolbar input[type=search]{
  font:inherit;font-size:13px;color:var(--ink);background:var(--panel);border:1px solid var(--line2);
  border-radius:10px;padding:7px 10px;min-height:34px;
}
.desk-toolbar input[type=search]{flex:1;min-width:160px}
.desk-toolbar .btn-primary{margin-left:auto;flex:none}
.desk-tablewrap{overflow-x:auto;margin:0 -8px;padding:0 8px}
/* рядом с открытой карточкой таблице тесно: второстепенные колонки уходят,
   остальное не режется, а прокручивается */
.with-pane .desk-table .c-age,.with-pane .desk-table .c-area,.with-pane .desk-table .c-courier{display:none}
/* ноутбук с масштабом 125–150 % — это 1024–1200 CSS-px: без этого таблица
   заявок уезжала за край и терялись «Состояние» и «Сумма» (владелец 19.09).
   Второстепенные колонки уходят, отчётные таблицы плотнее */
/* длинное имя клиента и «оговорка» в отчёте переносятся, а не растягивают
   таблицу за край экрана */
.desk-table td.c-client{white-space:normal;min-width:180px;max-width:360px}
.rtable td:last-child,.rtable th:last-child{white-space:normal;min-width:200px}
@media (max-width:1199px){
  /* доска: шесть KPI в ряд не помещаются (деньги переносились на две строки),
     две колонки тоже — таблица «В работе» теряла «Сумму» и «разбор» */
  .desk-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}
  .rkpis{grid-template-columns:repeat(3,minmax(0,1fr))}
  .desk-cols{grid-template-columns:1fr}
  .desk-col.side{position:static;max-height:none;overflow:visible}
  /* заявки с открытой карточкой: список прячется, панель во всю ширину */
  /* список скрыт (display:none) и в сетке не участвует — панель стала бы
     первым элементом и села в нулевую колонку; поэтому колонка одна */
  .desk-orders.with-pane{grid-template-columns:minmax(0,1fr)}
  .desk-orders.with-pane .desk-list{display:none}
  .desk-table .c-age,.desk-table .c-area{display:none}
  .desk-table td,.desk-table th{padding:8px 6px}
  .rtable{font-size:12px}
  .grid.wide.rtable td:last-child,.grid.wide.rtable th:last-child{min-width:88px;max-width:170px;white-space:normal}
  .rtable td,.rtable th{padding:6px 4px}
  .grid.wide.rtable th,.grid.wide.rtable td{white-space:normal;line-height:1.2}
  .grid.wide.rtable td.num,.grid.wide.rtable td.money{white-space:nowrap}
  .desk-tablewrap{scrollbar-width:thin;padding-bottom:4px}
}
/* мобильный переключатель «Заявки дня / Новая» в панели лишний: список
   и так слева, панель открыта ради формы */
.desk-pane-body .segmented[role=tablist]{display:none}
.desk-pane-body .seg,.desk-pane-body .segmented{flex-wrap:wrap;overflow:visible}
.desk-pane-body .seg button,.desk-pane-body .segmented button{flex:1 1 auto;white-space:nowrap}
/* Тип заявки: пять кнопок в панели 430 px. Было 3 + 2 — в первом ряду
   узкие, во втором широкие, и ряды не совпадали по сетке (скрин владельца
   23.09). Теперь две ровные колонки, а пятая кнопка занимает обе: все
   кнопки одной ширины, ряды выровнены. */
.desk-pane-body .segmented[role=radiogroup]{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px;
}
/* Скругление «пилюлей» рассчитано на один ряд кнопок. На трёх рядах оно
   превращает блок в овал: углы срезаны, края не совпадают ни с кнопками
   внутри, ни с полями под ним (скрин владельца 23.09). Для многострочного
   переключателя радиус карточный, как у полей формы. */
.desk-pane-body .segmented[role=radiogroup]{border-radius:14px}
.desk-pane-body .segmented[role=radiogroup] button{
  padding:10px 6px;white-space:normal;border-radius:10px;
}
.desk-pane-body .segmented[role=radiogroup] button:nth-child(5){grid-column:1 / -1}
/* панель заявки: строка позиции — в одну линию, места хватает */
/* панель 450 px: областями в три строки — «товар · ×», «кол-во · цена ·
   откуда», «серийник»; четыре поля в одну линию ужимали «откуда» и
   серийник до 105 px (владелец 19.09, №75) */
.desk-pane-body .item-row{
  grid-template-columns:64px 110px minmax(0,1fr) 40px;
  grid-template-areas:"name name name drop" "qty price src src" "serial serial serial serial";align-items:center;
}
.desk-pane-body .item-row > *{min-width:0}
.desk-pane-body .item-row [data-drop]{justify-self:end}
.desk-col.side .grid td:not(:first-child){white-space:nowrap}
.desk-table tbody tr{cursor:pointer}
.desk-table tbody tr:hover td{background:var(--rowh)}
/* выбранная строка — тон с акцентной полосой слева; просроченная — красная
   полоса и точка, без сплошной заливки: две метки читаются по-разному и не
   путаются, а выбранное видно даже у просроченной (репорты №46, №47) */
.desk-table tbody tr.sel td{background:var(--accent-t)}
.desk-table tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
.desk-table tbody tr.row-red td{background:transparent}
.desk-table tbody tr.row-red td:first-child{box-shadow:inset 3px 0 0 var(--red-fill)}
.desk-table tbody tr.row-red.sel td{background:var(--accent-t)}
.desk-table tbody tr.row-red.sel td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
.desk-table tbody tr:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.desk-table td b{font-weight:600}
.desk-pane{
  display:flex;flex-direction:column;border-left:1px solid var(--line);background:var(--panel2);min-width:0;
}
.desk-pane-head{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:10px 12px 10px 18px;border-bottom:1px solid var(--line);font-size:14px;
}
.desk-pane-body{position:relative;flex:1;min-height:0}
.desk-pane-body > .screen{padding:14px 18px 24px}

/* отчёты */
.desk-reports{position:absolute;inset:0;overflow-y:auto;padding:14px 24px 24px}
.desk-rtabs{top:-14px;margin-bottom:8px}
.desk-rfilters{position:static;padding-top:0;margin-bottom:14px}
.desk-rtabs .rhint{font-size:12.5px}
.desk-rtabs .btn-ghost{margin-left:auto;flex:none}
.desk-days.quiet input[type=date]{color:var(--dim)}
.rkpis{grid-template-columns:repeat(6,minmax(0,1fr));align-items:stretch}
.rkpis.three{grid-template-columns:repeat(3,minmax(0,1fr));max-width:720px}
/* Правило «три в ряд до 1199 px» выше по файлу перебивалось базовым
   repeat(6…) — на ноутбуке 1024 плитки резали числа: «6 556 35…»
   вместо 6 556 350 (полный аудит 25.09). Повтор — после базового */
@media (max-width:1199px){.rkpis{grid-template-columns:repeat(3,minmax(0,1fr))}}
.rkpis .kpi{display:flex;flex-direction:column;gap:4px;min-width:0}
.rkpis .kpi .l{order:0;font-size:12px;text-transform:uppercase;letter-spacing:.04em}
.rkpis .kpi .n{order:1;font-size:22px;white-space:nowrap}
.rkpis .kpi small{order:2;font-size:11px;line-height:1.35;white-space:normal}
.rkpis .kpi.quiet .n,.rkpis .kpi.quiet .l{color:var(--dim)}
.rnote{font-size:12.5px;line-height:1.45;margin:8px 0 14px;max-width:900px}
.rtable td.num,.rtable th.num{text-align:right;font-variant-numeric:tabular-nums}
.rtable td.rg{color:var(--green);font-weight:600}
.rtable td.ry{color:var(--amber);font-weight:600}
.rtable td.rr{color:var(--red);font-weight:600}
.rtable tfoot td{border-top:2px solid var(--line2);padding-top:10px}
.rtable tbody tr[data-pick],.rtable tbody tr[data-open]{cursor:pointer}
.rtable tbody tr:not([data-pick]):not([data-open]){cursor:default}
.rtable tbody tr:not([data-pick]):not([data-open]):hover td{background:transparent}
.desk-reports .desk-tablewrap + .desk-tablewrap{margin-top:18px}
.rbar-col{width:220px;min-width:120px}
.rbar{display:block;height:8px;border-radius:4px;background:var(--dim2);min-width:2px}
.rbar.g-not_delivered{background:var(--red-fill)}
.rbar.g-cancel{background:var(--amber-fill)}
.rbar.g-loss{background:var(--red)}
.rbar.g-store{background:var(--blue-fill)}
.rpanel{margin:14px 0;max-width:900px}
.rpanel h3{margin:0 0 8px;font-size:14px}
.rlist{margin:0 0 8px;padding-left:18px;font-size:13.5px;line-height:1.5}

/* Ф5.2.8: профиль курьера — четыре недели */
.wk{display:flex;align-items:flex-end;gap:10px;padding:6px 0 8px}
.wkc{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;min-width:0}
.wkc .n{font-family:var(--mono);font-size:11px;color:var(--dim)}
.wkc .bar{display:block;width:100%;max-width:48px;border-radius:6px 6px 3px 3px;background:var(--line2)}
.wkc .bar.green{background:var(--green-fill)} .wkc .bar.yellow{background:var(--amber-fill)} .wkc .bar.red{background:var(--red-fill)}
.wkc .l{font-size:11px;color:var(--dim)}
.wkc .t{font-family:var(--mono);font-size:11px}
.ok-text{color:var(--green)}
/* Ф5.2.8: динамика — столбики с зонами */
.rchart{display:flex;align-items:flex-end;gap:6px;padding:8px 4px 0;overflow-x:auto;max-width:100%}
.rcol{display:flex;flex-direction:column;align-items:center;gap:4px;min-width:34px;flex:1 0 34px}
.rcol .rn{font-family:var(--mono);font-size:11px;color:var(--dim)}
.rcol .rl{font-size:11px;color:var(--dim);white-space:nowrap}
.rstack{display:flex;flex-direction:column;justify-content:flex-end;width:100%;max-width:44px;background:var(--line);border-radius:6px 6px 3px 3px;overflow:hidden;position:relative}
.zstack{display:flex;flex-direction:column;width:100%}
.zstack .zs,.zs.none{display:block;width:100%}
.zs.green{background:var(--green-fill)} .zs.yellow{background:var(--amber-fill)} .zs.red{background:var(--red-fill)} .zs.excluded{background:var(--dim2)} .zs.none{background:transparent}
.rfail{display:block;width:100%;background:var(--red);border-top:1px solid var(--panel)}
/* загрузка — тепловая карта */
.rmode{margin:4px 0 12px;max-width:260px}
table.heat{width:auto;border-collapse:separate;border-spacing:2px;font-family:var(--mono);font-size:11.5px}
table.heat tbody th,table.heat tfoot th{width:1%;white-space:nowrap}
table.heat th{font:600 11px var(--font,inherit);color:var(--dim);text-align:center;padding:2px 3px}
table.heat tbody th{text-align:left;padding-right:8px}
table.heat td.hc{width:30px;height:28px;text-align:center;border-radius:5px;background:color-mix(in srgb,var(--blue-fill) calc(var(--k) * 100%),var(--panel));color:var(--ink)}
table.heat td.hc i{font-style:normal;color:var(--dim)}
table.heat td.num,table.heat tfoot td{text-align:right;color:var(--dim);padding:2px 4px}
table.heat tfoot th{text-align:left}
@media(prefers-color-scheme:dark){table.heat td.hc{background:color-mix(in srgb,var(--blue-fill) calc(var(--k) * 85%),var(--panel))}}

/* невысокое окно (ноутбук): навигация плотнее, чтобы учётки и «мобильная
   версия» не уезжали под нижний край без видимой прокрутки (обход 17.09) */
@media(max-height:820px){
  .desk-nav{padding:10px 8px;gap:2px}
  .desk-brand{padding:2px 10px 8px;font-size:14px}
  .desk-menu button{padding:4px 10px;font-size:13px;min-height:30px}
  .desk-menu{gap:1px}
  .desk-acc-title{display:none}
  .desk-acc > button:first-child{padding:4px 10px}
  .desk-acc-add,.desk-mobile{padding:6px 10px}
}

/* узкое окно: навигация сверху, панель заявки во всю ширину */
@media(max-width:980px){
  .desk{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}
  .desk-nav{flex-direction:row;flex-wrap:wrap;border-right:0;border-bottom:1px solid var(--line);padding:8px 10px}
  .desk-brand{display:none}
  .desk-menu{flex-direction:row;flex-wrap:wrap;gap:4px}
  .desk-menu button{width:auto;padding:7px 10px;min-height:36px;font-size:13px}
  .desk-mobile{margin-top:0}
  .desk-accounts{margin-top:0;border-top:0;padding-top:0;flex-direction:row;flex-wrap:wrap;align-items:center}
  .desk-acc-title{display:none}
  .desk-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}
  .rkpis{grid-template-columns:repeat(3,minmax(0,1fr))}
  .desk-cols{grid-template-columns:1fr}
  .desk-col.side{position:static}
  /* список скрыт (display:none) и в сетке не участвует — панель стала бы
     первым элементом и села в нулевую колонку; поэтому колонка одна */
  .desk-orders.with-pane{grid-template-columns:minmax(0,1fr)}
  .desk-orders.with-pane .desk-list{display:none}
  /* меню — одной строкой с прокруткой вбок, а не в три строки: при крупном
     масштабе оно занимало до 40 % высоты окна, и таблице «Заявок» оставалось
     полторы сотни точек (владелец 26.09) */
  .desk-nav{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;gap:8px;
    /* край строки растворяется — видно, что разделы продолжаются вбок */
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent)}
  .desk-menu,.desk-accounts{flex-wrap:nowrap;flex:none}
  .desk-menu button,.desk-acc,.desk-acc-add,.desk-mobile{flex:none;white-space:nowrap}
}

/* ── графики отчётов (core/charts.js, 17.09) ─────────────────────────────
   Свой SVG в токенах темы. Карточка графика — тот же панельный стиль, что
   у KPI; сетка карточек сама складывается в одну колонку на узком экране. */
.chart-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:0 0 14px}
.chart-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:14px 16px 12px;box-shadow:var(--shadow);min-width:0}
.chart-card.wide{grid-column:1/-1}
.chart-title{margin:0 0 10px;font-size:13px;font-weight:600;letter-spacing:.01em;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.chart-title small{font-weight:500;color:var(--dim);font-size:12px;margin-left:8px}
.chart{width:100%;height:auto;display:block;overflow:visible}
/* график под настоящую ширину карточки: подписи постоянного размера (сверка 26.09) */
.chart-fit{width:100%;min-width:0}
.chart-fit.refit .grow{animation:none}
.chart-fit.refit .draw{animation:none;stroke-dashoffset:0}
.heat-scroll{max-width:100%;overflow-x:auto;overscroll-behavior-x:contain}
.chart text{fill:var(--dim);font-size:11px}
.chart text.val{fill:var(--ink);font-size:11px;font-weight:600}
.chart text.tick{fill:var(--dim)}
.chart text.thr{font-size:11px;font-weight:600}
.chart .grid{stroke:var(--line);stroke-width:1}
.chart .axis{stroke:var(--line2);stroke-width:1}
.chart .track{fill:var(--line);opacity:.55}
.chart .hover{fill:transparent;cursor:crosshair}
.chart .hover:hover{fill:var(--ink);opacity:.05}
.chart-readout{margin-left:auto;font-family:var(--mono);font-weight:500;color:var(--dim);font-size:12.5px;white-space:nowrap}
.chart-readout.on{color:var(--ink)}
/* появление: столбики вырастают, линии прорисовываются, кольцо доворачивается,
   полосы вытягиваются — 450 мс, как в BoardUI; при reduced-motion выключено */
.chart .grow{animation:chart-grow .45s cubic-bezier(.2,.8,.2,1) both}
.chart .draw{stroke-dasharray:1;stroke-dashoffset:1;animation:chart-draw .7s cubic-bezier(.2,.8,.2,1) forwards}
.donut.sweep{animation:chart-sweep .55s cubic-bezier(.2,.8,.2,1) both}
.hbar-fill.grow-x{transform-origin:left center;animation:chart-grow-x .45s cubic-bezier(.2,.8,.2,1) both}
@keyframes chart-grow{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes chart-grow-x{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes chart-draw{to{stroke-dashoffset:0}}
@keyframes chart-sweep{from{transform:rotate(-40deg);opacity:0}to{transform:rotate(0);opacity:1}}
@media(prefers-reduced-motion:reduce){.chart .grow,.chart .draw,.donut.sweep,.hbar-fill.grow-x{animation:none;stroke-dashoffset:0}}
.donut .track{stroke:var(--line)}
.chart.heat text.cell{fill:var(--dim);font-size:11px}
.chart.heat text.cell.on{fill:var(--ink);font-weight:700}
.chart-legend{display:flex;flex-wrap:wrap;gap:6px 14px;margin:8px 0 2px;font-size:12px;color:var(--dim)}
.chart-key{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.chart-key i{width:10px;height:10px;border-radius:3px;display:inline-block;flex:0 0 auto}
.chart-key b{color:var(--ink);font-family:var(--mono);font-weight:600}
.chart-key small{color:var(--dim);font-size:11px;font-variant-numeric:tabular-nums}
.chart-empty{padding:26px 10px;text-align:center;color:var(--dim);font-size:13px}
/* рейтинг полосами */
.hbars,.rangebars{display:flex;flex-direction:column;gap:6px}
.hbar-row{display:grid;grid-template-columns:minmax(140px,240px) 1fr auto;align-items:center;gap:10px;min-height:22px;border-radius:6px;padding:2px 4px}
.hbar-row[data-pick]{cursor:pointer}
.hbar-row[data-pick]:hover,.hbar-row[data-pick]:focus-visible{background:var(--rowh)}
.hbar-label{font-size:12.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}
.hbar-label small{display:block;color:var(--dim);font-size:11px;font-weight:500}
.hbar-track{display:block;height:14px;background:var(--line);border-radius:5px;overflow:hidden;min-width:60px}
.hbar-fill{display:flex;height:100%;min-width:3px;border-radius:5px;overflow:hidden}
.hbar-fill i{display:block;height:100%}
.hbar-val{font-family:var(--mono);font-size:12px;color:var(--ink);white-space:nowrap;min-width:56px;text-align:right}
/* норматив против факта: три вложенные полосы и две метки границ */
.range-track{position:relative;display:block;height:16px;background:var(--line);border-radius:5px;min-width:60px}
.range-track i{position:absolute;left:0;top:0;height:100%;border-radius:5px}
.range-track .r90{background:var(--blue-t);border:1px solid var(--blue-b)}
.range-track .r75{background:var(--blue-b)}
.range-track .r50{background:var(--blue-fill)}
.range-track .mark{position:absolute;top:-3px;width:2px;height:22px;border-radius:1px}
.range-track .mark.g{background:var(--green-fill)}
.range-track .mark.r{background:var(--red-fill)}
.range-legend{display:flex;gap:14px;font-size:12px;color:var(--dim);margin-top:8px;flex-wrap:wrap}
/* кольцо */
.donut-wrap{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.donut{flex:0 0 auto}
.donut text.donut-n{fill:var(--ink);font-size:22px;font-weight:700}
.donut text.donut-l{fill:var(--dim);font-size:11px}
.donut-list{display:flex;flex-direction:column;gap:6px;font-size:12.5px;color:var(--dim);min-width:0}
/* искра в KPI */
.rkpis .kpi .spark{order:3;margin-top:4px;width:100%;max-width:160px;height:30px}
@media(max-width:900px){.chart-grid{grid-template-columns:1fr}.hbar-row{grid-template-columns:minmax(90px,130px) 1fr auto}}

/* ── Свой выпадающий список (владелец 24.09) ────────────────────────────
   Поле-кнопка повторяет обычное поле ввода один в один: человек не должен
   видеть разницу между «сюда пишут» и «отсюда выбирают». Отличие одно —
   шеврон справа и подсветка, пока список раскрыт. */
/* Обёртка поля-кнопки — тоже прямой span внутри .field, а там правило
   подписи: без этого кнопка наследовала кегль 12 px и полужирный. */
.pickwrap{display:block}
.field>span.pickwrap{font-size:inherit;font-weight:inherit;color:inherit;margin-bottom:0}
.pick{
  display:flex;align-items:center;gap:8px;width:100%;min-height:44px;
  font:inherit;font-size:16px;text-align:left;color:var(--ink);
  background:var(--panel2);border:1px solid var(--line2);border-radius:12px;
  padding:10px 12px;cursor:pointer;box-sizing:border-box;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.pick .pick-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pick svg{flex:none;color:var(--dim);transition:transform .2s var(--ease)}
.pick.empty .pick-v{color:var(--dim)}
.pick:hover{border-color:var(--line)}
.pick:focus-visible,.pick[aria-expanded="true"]{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-b);outline:0;
}
.pick[aria-expanded="true"] svg{transform:rotate(180deg)}
body.deskmode .pick{min-height:34px;font-size:14px;padding:6px 10px}
/* в терминале строки списка тесней: мышь целится точнее пальца */
body.deskmode .pickopt{min-height:36px;padding:7px 10px;font-size:14px}
body.deskmode .pick-q{font-size:14px;padding:7px 10px}

/* Слой списка: над содержимым и над шторкой (40) — список бывает и внутри
   шторки, например выбор курьера при назначении. */
.pickpop{
  position:fixed;z-index:var(--z-pick);box-sizing:border-box;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
  padding:8px;box-shadow:var(--shadow-float);
  max-height:340px;overflow:auto;overscroll-behavior:contain;
}
.picklist{display:flex;flex-direction:column;gap:2px}
#sheet .picklist{max-height:52vh;overflow:auto;overscroll-behavior:contain;margin:0 -4px;padding:0 4px}
.pickopt{
  display:flex;align-items:center;gap:10px;width:100%;min-height:44px;
  font:inherit;font-size:15px;text-align:left;color:var(--ink);
  background:none;border:0;border-radius:var(--r-chip);padding:9px 10px;cursor:pointer;
}
.pickopt:hover{background:var(--row)}
.pickopt:focus-visible{background:var(--row);outline:2px solid var(--accent);outline-offset:-2px}
.pickopt.on{background:var(--accent-t)}
.pickopt svg{flex:none;color:var(--accent)}
/* длинное название клиента не должно рвать строку списка на четыре */
.po-l{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.po-l,.po-l small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.po-l small{color:var(--dim);font-size:12.5px}
.po-n{flex:none;font-style:normal;font-size:13px;color:var(--dim)}
.pick-find{padding:2px 2px 6px;position:sticky;top:-8px;background:var(--panel);z-index:var(--z-local)}
#sheet .pick-find{background:var(--panel);top:0;padding-top:0}
.pick-q{
  width:100%;box-sizing:border-box;font:inherit;font-size:15px;color:var(--ink);
  background:var(--panel2);border:1px solid var(--line2);border-radius:var(--r-chip);padding:9px 10px;outline:0;
}
.pick-q:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-b)}
.pick-none{margin:10px;color:var(--dim);font-size:14px;text-align:center}
/* календарь в том же слое: своя карточка ему не нужна — слой уже карточка */
.pickpop.pickcal{padding:10px}
.pickcal .calendar{margin:0;padding:0;border:0;background:none;box-shadow:none}
.cal-cell.off{opacity:.3;cursor:default}

/* Заголовок-кнопка: по нему сортируют. Выглядит как обычный заголовок, пока
   на него не навели — иначе шапка таблицы превращается в ряд кнопок и спорит
   с содержимым (владелец 24.09: «в заявках сплошной поток»). */
.th-sort{
  display:inline-flex;align-items:center;gap:4px;
  font:inherit;color:inherit;background:none;border:0;padding:0;
  cursor:pointer;text-transform:inherit;letter-spacing:inherit;
}
.th-sort:hover{color:var(--ink)}
.th-sort.on{color:var(--accent)}
.th-sort i{font-style:normal;font-size:11px;line-height:1}
.th-sort:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.num .th-sort{justify-content:flex-end}
/* Кнопки-списки в полосе фильтров терминала. Скругление капсулой, а не
   как у поля: в этой строке всё остальное — капсулы (плашка дня, «Все /
   Мои / Свободные»), и прямоугольные углы посреди них читаются как чужие
   (та же придирка владельца, что к переключателю типа 23.09). */
.desk-toolbar .pick,.desk-toolbar input[type=search]{border-radius:999px}
.desk-toolbar .pick{
  flex:none;width:auto;min-width:130px;max-width:190px;
  font-size:13px;background:var(--panel);
}
.desk-toolbar input[type=search]{padding-left:14px}

/* Полоса отборов на телефоне: прокручивается вбок, чтобы три кнопки не
   забирали у списка вторую строку экрана (владелец 24.09). */
.chipbar{
  display:flex;gap:6px;align-items:center;margin:0 0 10px;
  overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
  padding-bottom:2px;
}
.chipbar::-webkit-scrollbar{display:none}
.chip-pick{
  flex:none;width:auto;min-height:32px;padding:5px 10px;font-size:12.5px;
  border-radius:999px;background:var(--panel2);border:1px solid var(--line2);
  color:var(--dim);cursor:pointer;font-family:inherit;
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap;
}
.chip-pick .pick-v{max-width:150px}
.chip-pick svg{width:12px;height:12px}
.chip-pick.set{color:var(--ink);background:var(--accent-t);border-color:transparent}
.chip-pick.set svg{color:var(--accent)}
.chip-pick.reset{color:var(--dim)}
.chip-pick:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* Одна высота на всю полосу отбора: рядом стоят капсула дня, полоса
   состояний, списки и поиск — разнобой в 4–8 px в одном ряду виден сразу. */
body.deskmode .desk-toolbar .seg.tiny{padding:2px}
body.deskmode .desk-toolbar .pick,
body.deskmode .desk-toolbar input[type=search]{min-height:40px}
body.deskmode .daypick{padding:4px}
body.deskmode .daypick button{min-height:32px}
body.deskmode .desk-toolbar .btn-primary{min-height:40px}

/* Список, открытый изнутри шторки, живёт над ней: у шторки слой 40 */
.pickpop{z-index:var(--z-pick)}

/* ══ МАКЕТ 24.09 (аудит): показ владельцу, до его решения в прод не идёт ══ */
.nowrap{white-space:nowrap}
/* сообщения: ожидание — часы, отказ — «!», ошибка висит с крестиком */
.toast .i.wait{color:var(--dim)}
.toast .i.warn{color:var(--amber)}
.toast.err{border-color:var(--red-b);pointer-events:auto;padding-right:8px}
.toast .x{margin-left:4px;border:0;background:transparent;color:var(--dim);width:30px;height:30px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;flex:none}
.toast .x:hover{background:var(--rowh);color:var(--ink)}
/* комментарий: переносы строк сохраняются, длинный — свёрнут */
.note-text{white-space:pre-line}
.note-text.clamp{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}
.note-more{border:0;background:none;padding:8px 0 0;font:inherit;font-size:13px;font-weight:600;color:var(--accent);cursor:pointer}
.crow small.serial{margin-top:2px}
/* закреплённый низ листа: решение всегда на экране */
/* Слои по именам (аудит 24.09, том 2 «этаж по имени»): одиннадцать чисел
   без имён породили четыре дефекта на бою 24.09 — списки внутри окон уходили
   под окно. Значения прежние: вид не меняется. Новое окно выбирает этаж по
   смыслу, а не подбирает число. */
:root{
  --z-local:1;      /* внутри всплывающего списка */
  --z-foot:3;       /* закреплённый низ листа и панели — выше содержимого, ниже списков */
  --z-band-low:5;   /* липкая полоса под другой липкой полосой */
  --z-band:6;       /* липкие полосы и шапки таблиц в содержимом */
  --z-band-top:7;   /* отборы над таблицей — выше шапки её колонок */
  --z-appbar:20;    /* шапка приложения */
  --z-fade:20;      /* затухание внизу экрана */
  --z-actbar:22;    /* закреплённые кнопки действий над затуханием */
  --z-tabbar:30;    /* нижняя навигация */
  --z-pop:35;       /* календарь и списки в потоке экрана */
  --z-sheet:40;     /* лист и окно */
  --z-pick:45;      /* список, открытый изнутри листа, — над листом */
  --z-banner:36;    /* баннер обновления — над навигацией, под окнами */
  --z-tip:70;       /* подсказки: графика и кнопок */
  --z-overlay:80;   /* просмотр фото */
  --z-toast:85;     /* сообщения — над всем, кроме «Сеанс закрыт» */
  --z-reauth:90;    /* «Сеанс закрыт — войдите снова» — над всем */
}
.sheet-foot{position:sticky;bottom:calc(-18px - env(safe-area-inset-bottom));z-index:var(--z-foot);
  margin:16px -18px calc(-18px - env(safe-area-inset-bottom));
  padding:12px 18px calc(16px + env(safe-area-inset-bottom));
  background:var(--panel);box-shadow:0 -16px 16px -8px var(--panel);display:grid;gap:8px}
/* «Отмена» в листах — тише вариантов ответа и отделена */
.sheet > .btn-ghost.btn-block:last-child,.sheet .sheet-foot .btn-ghost{
  border-color:transparent;background:transparent;color:var(--dim)}
.sheet > .btn-ghost.btn-block:last-child{margin-top:8px}
/* ошибка — у поля */
.field-err,.field>span.field-err{display:block;color:var(--red);font-size:12.5px;font-weight:600;margin-top:4px;text-transform:none;letter-spacing:0}
input[aria-invalid="true"]{border-color:var(--red-b)!important;box-shadow:0 0 0 3px var(--red-t)}
.setting-state.err{color:var(--red);font-weight:600}
/* числовые поля без системных стрелок */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
/* бейджи и счётчики — не мельче 11 px */
.badge-urgent,.badge-hour,.badge-flag{font-size:11px}
.seg .cnt,.chip-src,.desk-toolbar .seg button i,.tabbar button{font-size:11px}
.iconb .bdg,.iconbtn .bdg{font-size:11px;min-width:18px;height:18px}
.tabbar button .bdg{font-size:11px;min-width:17px;height:17px}
.raw .src,.tag,.cal-cell i,.th-sort i{font-size:11px}
.chart text.val,.chart text.thr,.chart.heat text.cell{font-size:11px}
/* терминал: сумма не режется, колонки соразмерны */
.desk-table td.num{white-space:nowrap}
.desk-table td.c-client{min-width:230px}
.desk-table td.c-area{white-space:normal;min-width:150px;max-width:220px}
/* панель заявки: кнопки закреплены внизу */
.desk-pane-body .office-acts{position:sticky;bottom:-24px;z-index:var(--z-foot);margin:12px -18px -24px;
  padding:12px 18px 16px;background:var(--panel2);box-shadow:0 -16px 16px -8px var(--panel2)}
/* новая заявка: количество вмещает 1000, итог заметен, кнопка всегда видна */
.desk-pane-body .item-row{grid-template-columns:84px 110px minmax(0,1fr) 40px}
#sumHint{font-size:14px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.desk-pane-body #newOrder button[type=submit]{position:sticky;bottom:0;z-index:var(--z-foot);box-shadow:0 -14px 18px -6px var(--panel2),0 10px 0 0 var(--panel2)}
/* доска: свободные — без постоянного подчёркивания, имя слева */
.as-link{text-align:left;text-decoration:none}
.as-link:hover{text-decoration:underline}
/* отчёты: вывод словами над графиками */
.rverdict{margin:0 0 16px;padding:16px 20px;border-radius:var(--r-card);background:var(--panel);border:1px solid var(--line);display:grid;gap:8px}
.rverdict .row{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.rverdict .v{font-size:18px;font-weight:700;letter-spacing:-.015em;line-height:1.3;text-wrap:balance}
.rverdict .k{font-family:var(--mono);font-size:20px;font-weight:700;white-space:nowrap}
.rverdict.bad .k{color:var(--red)}
.rverdict .s{font-size:13.5px;color:var(--dim)}
.rverdict .k .u{color:var(--dim);font-size:15px;font-weight:600}
/* легенда бублика: длинное имя — многоточием, не за карточку */
.donut-list{min-width:0}
.donut-list .chart-key{display:flex;align-items:baseline;gap:6px;min-width:0;max-width:100%}
.donut-list .chart-key .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.donut-list .chart-key b,.donut-list .chart-key small{flex:none}
/* пороги: поля в одну колонку по всей странице */
table.settings{table-layout:fixed;width:100%}
table.settings td.setting-edit{display:table-cell;width:290px;white-space:nowrap}
table.settings .cell-input{width:130px;vertical-align:middle}
table.settings .setting-state{display:inline-block;width:130px;margin-left:10px;white-space:normal;vertical-align:middle;font-size:12.5px}
/* заявки управляющего на узком экране: «Все/Мои» и день — одной строкой */
.dl-short{display:none}
@media (max-width:360px){
  .listbar{flex-wrap:nowrap}
  .listbar .dl-long{display:none}
  .listbar .dl-short{display:inline}
  .listbar .daypick-label svg:first-child{display:none}
}
/* вариант на выбор: светлый терминал, «Требует действия» — тёмным блоком */
:root.v-darkblock body.deskmode .panel.danger{background:#211f2c;border-color:#211f2c;color:#e7e5ee}
:root.v-darkblock body.deskmode .panel.danger h3{color:#f0a3ab}
:root.v-darkblock body.deskmode .panel.danger .chips li{background:rgba(255,255,255,.08);color:#e7e5ee}
:root.v-darkblock body.deskmode .panel.danger .btn-primary{background:#b8b0f0;color:#1a1822}

/* ══ МАКЕТ 24.09, вторая волна — после сверки глазами с томами «Стиль Г» ══ */
/* тосты: снизу по центру стопкой (том 2), над главной кнопкой и вкладками */
.toast-zone{top:auto;bottom:calc(var(--screen-pb) + 64px);height:0;display:block;padding:0}
body.no-tabbar .toast-zone{bottom:calc(var(--screen-pb) + 64px)}
body.deskmode .toast-zone{bottom:24px}
.toast-zone .toast{position:absolute;left:50%;bottom:0;translate:-50% 0;transform-origin:bottom center;
  width:max-content;max-width:min(92vw,460px);pointer-events:auto;
  transition:translate .3s var(--ease),scale .3s var(--ease),opacity .2s}
@keyframes toastIn{from{opacity:0;transform:translateY(14px) scale(.96)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(8px) scale(.97)}}
.toast.out{animation:toastOut .2s cubic-bezier(.4,0,1,1) forwards}
.toast .act{margin-left:8px;border:0;border-radius:999px;background:var(--ink);color:var(--bg);font:inherit;font-size:13px;font-weight:700;
  padding:6px 14px;cursor:pointer;flex:none}
/* лист: подложка размывает страницу, вход с масштаба и размытия, уход вдвое быстрее (том 1) */
.sheet-veil{transition:opacity .35s var(--ease),backdrop-filter .35s var(--ease)}
.sheet-veil.on{backdrop-filter:blur(6px) saturate(120%);-webkit-backdrop-filter:blur(6px) saturate(120%)}
.sheet-veil:not(.on){transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,1,1)}
.sheet{opacity:0;transition:transform .45s var(--ease),opacity .25s var(--ease),filter .3s var(--ease);filter:blur(4px)}
.sheet-veil.on .sheet{opacity:1;filter:none}
.sheet-veil:not(.on) .sheet{transition:transform .2s cubic-bezier(.4,0,1,1),opacity .2s cubic-bezier(.4,0,1,1),filter .2s}
body.deskmode .sheet{transform:scale(.965)}
body.deskmode .sheet-veil.on .sheet{transform:none}
@media (prefers-reduced-transparency:reduce){.sheet-veil.on{backdrop-filter:none;-webkit-backdrop-filter:none}}
/* окна с причинами — лист действий: варианты одной пластиной, «Отмена» — отдельной (том 3) */
.sheet .stack{gap:0;border:1px solid var(--line);border-radius:var(--r-chip);overflow:hidden;background:var(--panel2)}
.sheet .stack > .btn{border:0;border-radius:0;background:transparent;min-height:48px;font-weight:600;box-shadow:none}
.sheet .stack > .btn + .btn{border-top:1px solid var(--line)}
.sheet .stack ~ .btn-ghost.btn-block:last-child{margin-top:8px;border:1px solid var(--line);border-radius:var(--r-chip);
  background:var(--panel2);color:var(--ink);font-weight:700;min-height:48px}
/* подвал окна в терминале: «Отмена» слева, главная справа, счётчик изменений (том 3) */
.foot-count{font-size:13px;color:var(--dim);text-align:center}
body.deskmode .sheet-foot{display:flex;align-items:center;justify-content:flex-end;gap:8px}
body.deskmode .sheet-foot .btn{width:auto;min-width:120px;flex:none}
body.deskmode .sheet-foot .btn-ghost{order:1}
body.deskmode .sheet-foot .btn-primary{order:2}
body.deskmode .sheet-foot .foot-count{order:0;margin-right:auto;text-align:left}
/* графики: ярлык вида, вывод — заголовком, что считается — строкой под ним (том 2) */
/* вид графика — тихой подписью: залитая плашка была громче самого вывода (сверка 26.09) */
.chart-kind{display:block;margin-bottom:4px;color:var(--dim);font-size:var(--fs-12);font-weight:500;letter-spacing:.01em}
.chart-card .chart-title{font-size:16px;font-weight:700;letter-spacing:-.01em;line-height:1.3;margin:0 0 4px;text-wrap:balance}
.chart-sub{margin:0 0 12px;font-size:12.5px;color:var(--dim);line-height:1.45}
.chart-readout{font-size:13px}
/* подсказка: одна на срез, стекло, курсор — вертикальной линией */
.chart-tip{position:fixed;z-index:var(--z-tip);pointer-events:none;min-width:150px;max-width:280px;padding:10px 12px;border-radius:12px;
  background:var(--glass);backdrop-filter:blur(16px) saturate(160%);-webkit-backdrop-filter:blur(16px) saturate(160%);
  border:1px solid var(--line2);box-shadow:var(--shadow-float);font-size:12.5px;opacity:0;transition:opacity .12s}
.chart-tip.on{opacity:1}
.chart-tip b{display:block;font-size:13px;margin-bottom:4px}
.chart-tip .r{display:flex;justify-content:space-between;gap:14px;color:var(--dim);line-height:1.6}
.chart-tip .r .v{color:var(--ink);font-family:var(--mono);font-weight:600;white-space:nowrap}
.chart line.cursor{stroke:var(--dim2);stroke-width:1;pointer-events:none}
/* ══ МАКЕТ 24.09 — правило ошибок v2 ══ */
.toast.err .tx{display:grid;gap:2px}
.toast.err .tx b{font-weight:700}
.toast.err .tx small{font-weight:500;color:var(--dim);font-size:12.5px;line-height:1.35}
.state-meta{margin-top:10px;font-size:11.5px;color:var(--dim);font-family:var(--mono)}
.ro-val{padding:12px 14px;border:1px dashed var(--line2);border-radius:12px;color:var(--ink);font-size:15px;line-height:1.35}
.ro-val small{display:block;margin-top:4px;font-size:12.5px;color:var(--dim)}

/* ── Вход и пароль (том 10, аудит 24.09) ─────────────────────────────── */
.pw-wrap{position:relative}
.pw-wrap .inp{padding-right:96px}
.pw-eye{position:absolute;right:6px;top:50%;translate:0 -50%;height:34px;padding:0 12px;border:0;border-radius:9px;
  background:transparent;color:var(--accent);font:inherit;font-size:13.5px;font-weight:600;cursor:pointer}
.pw-eye:hover{background:var(--accent-t)}
.pw-caps{margin-top:6px;font-size:12.5px;font-weight:600;color:var(--amber)}
.pw-rules{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:4px;font-size:12.5px;color:var(--dim)}
.pw-rules li{display:flex;align-items:center;gap:8px}
.pw-rules li::before{content:"";width:8px;height:8px;border-radius:50%;border:1.5px solid var(--line2);flex:none;
  transition:background .2s var(--ease),border-color .2s var(--ease)}
.pw-rules li.ok{color:var(--ink)}
.pw-rules li.ok::before{background:var(--green-fill);border-color:var(--green-fill)}
.inp.bad,.field input.bad{border-color:var(--red)!important;box-shadow:0 0 0 3px var(--red-t)!important}
#loginErr,#reErr{min-height:0;margin:-4px 0 10px;font-size:13px;font-weight:600;color:var(--red)}
#loginErr:empty,#reErr:empty{display:none}
.login-lock{display:flex;flex-direction:column;gap:2px;margin:0 0 12px;padding:12px 14px;border-radius:14px;
  background:var(--red-t);border:1px solid var(--red-b);font-size:13.5px}
.login-lock b{font-weight:700;color:var(--ink)}
.login-lock span{color:var(--dim)}
.login-lock .t{font-family:var(--mono);font-weight:700;color:var(--red)}
.linkbtn{display:block;margin:12px auto 0;border:0;background:none;color:var(--accent);font:inherit;font-size:13.5px;
  font-weight:600;cursor:pointer;padding:6px 8px;border-radius:8px}
.linkbtn:hover{background:var(--accent-t)}
.reauth-veil{position:fixed;inset:0;z-index:var(--z-reauth);display:grid;place-items:center;padding:16px;
  background:color-mix(in srgb,var(--bg) 55%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  animation:reauth-in .26s var(--ease)}
.reauth{width:min(400px,100%);background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sheet);
  padding:22px 20px 16px;box-shadow:var(--shadow-float)}
.reauth h2{margin:0 0 6px;font-size:19px;font-weight:700}
.reauth .sub{margin:0 0 14px;color:var(--dim);font-size:13.5px;line-height:1.45}
.who-chip{display:inline-flex;align-items:center;gap:8px;margin:0 0 12px;padding:4px 12px 4px 4px;border-radius:var(--r-pill);
  background:var(--row);font-size:13.5px;font-weight:600;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.who-chip .av{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:var(--accent-t);color:var(--accent);font-size:12px;font-weight:700;text-transform:uppercase}
@keyframes reauth-in{from{opacity:0}to{opacity:1}}

/* ── «Снизить прозрачность» и «Повысить контраст» (аудит 24.09) ─────────
   Уменьшение движения учтено давно, эти две настройки телефона — нет.
   По умолчанию вид не меняется. */
@media (prefers-reduced-transparency: reduce){
  :root{--glass:var(--panel)}
  .appbar,.tabbar,.sheet-veil,.reauth-veil,.toast,.chart-tip{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
  .sheet-veil{background:rgba(10,8,16,.72)}
  .reauth-veil{background:var(--bg)}
}
@media (prefers-contrast: more){
  :root{--dim:#c9c5d6;--line:#5a536c;--line2:#6d6583}
  [data-theme="light"]{--dim:#4f4c5c;--line:#b5b0c6;--line2:#9d97b3}
}
.pw-field + .field-err{margin:-6px 0 12px}
.pw-field + .field-err:empty{display:none}

/* ── Заглушка загрузки не мигает (аудит 24.09, том 3) ─────────────────
   Экран приходил за 20–50 мс, и серая заглушка вспыхивала на один кадр.
   Теперь до 300 мс её не видно, дальше она плавно проявляется: быстрый
   ответ просто подменяет пустоту, медленный показывает, что данные едут.
   Отрисовку экрана не задерживаем — экраны ищут элементы сразу после неё. */
.skeleton{animation:skShow .25s ease 1s both}
@keyframes skShow{from{opacity:0}to{opacity:1}}
.viewer .skeleton,.cam-wait .skeleton{animation:none}

/* ── Числовые поля без системных стрелок ▲▼ (как системные списки) ─── */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}

/* ── Кадры шага (том 9): заглушка, проявление, «повторить» ────────────── */
.shots .photo{width:58px;height:58px;border-radius:10px;overflow:hidden;background:var(--row);color:var(--dim);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px}
.shots .photo.loading{background:linear-gradient(90deg,var(--row) 0%,var(--rowh) 50%,var(--row) 100%);
  background-size:200% 100%;animation:skWave 1.3s linear infinite}
.shots .photo img{opacity:0;filter:blur(6px);transition:opacity .25s var(--ease),filter .35s var(--ease)}
.shots .photo img.in{opacity:1;filter:none}
.shots .photo small{font-size:11px;line-height:1;font-weight:600}
.shots .photo.failed{color:var(--amber);cursor:pointer}
.shots .photo.failed:hover{background:var(--rowh)}
@media (prefers-reduced-motion:reduce){.shots .photo.loading{animation:none}.shots .photo img{transition:none;filter:none}}

/* ── Форма заявки (аудит 24.09, том 8) ──────────────────────────────────
   Подписи у полей позиции постоянные, количество — со «−» и «+»,
   ошибки — у поля и сводкой сверху. Области сетки — на обёртках полей. */
.item-row{grid-template-columns:116px minmax(0,1fr) 40px}
.item-row .ir{display:flex;flex-direction:column;gap:4px;min-width:0}
.item-row .ir > span{font-size:11.5px;font-weight:600;color:var(--dim)}
.item-row .ir-name{grid-area:name} .item-row .ir-qty{grid-area:qty} .item-row .ir-price{grid-area:price}
.item-row .ir-src{grid-area:src} .item-row .ir-serial{grid-area:serial}
.item-row [data-drop],.item-row [data-drop-item]{align-self:end}
.desk-pane-body .item-row{grid-template-columns:116px 132px minmax(0,1fr) 40px;align-items:end}
.qty{display:flex;align-items:stretch;border:1px solid var(--line2);border-radius:12px;background:var(--panel2);overflow:hidden;min-width:0}
.qty input,.item-row .qty input{border:0;border-radius:0;box-shadow:none;background:transparent;text-align:center;
  padding:11px 0;min-width:0;width:100%;font-variant-numeric:tabular-nums}
.qty input:focus,.item-row .qty input:focus{box-shadow:none;border:0}
.qty button{flex:none;width:36px;border:0;background:transparent;color:var(--accent);font:inherit;font-size:19px;font-weight:700;cursor:pointer;line-height:1}
.qty button:hover{background:var(--accent-t)}
.qty:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-b)}
.qty:has(input.bad){border-color:var(--red)}
input[data-money]{font-variant-numeric:tabular-nums}
.item-row + .field-err{display:block;margin:-4px 4px 10px}
.err-sum{margin:0 0 14px;padding:12px 14px;border-radius:14px;background:var(--red-t);border:1px solid var(--red-b)}
.err-sum b{display:block;margin-bottom:6px;font-size:14px}
.err-sum ul{margin:0;padding-left:18px;display:grid;gap:2px}
.linkish{border:0;background:none;padding:2px 0;color:var(--ink);font:inherit;font-size:13.5px;text-align:left;
  text-decoration:underline;text-underline-offset:2px;text-decoration-color:var(--red-b);cursor:pointer}
#sumHint.bad{color:var(--red)}
/* список заявок: день и отборы одной строкой, отборы листаются вбок */
.listbar.one{flex-wrap:nowrap;justify-content:flex-start}
.listbar.one .chipbar{flex:1;min-width:0;margin:0}
@media (max-width:349px){.listbar.one{flex-wrap:nowrap}.listbar.one .daypick{margin-left:0}}
/* типы заявки на телефоне — сеткой 3 + 2, как в терминале, а не полосой за край */
#newOrder .segmented[role=radiogroup]{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:4px;border-radius:14px;overflow:visible}
#newOrder .segmented[role=radiogroup] button{grid-column:span 2;white-space:normal;border-radius:10px;padding:9px 4px;line-height:1.2}
#newOrder .segmented[role=radiogroup] button:nth-child(4),#newOrder .segmented[role=radiogroup] button:nth-child(5){grid-column:span 3}
/* поля строки позиции одной высоты: кнопка «откуда» была ниже полей ввода,
   и её подпись съезжала вниз относительно соседних */
.item-row .pick{min-height:46px}
.desk-pane-body .item-row{align-items:start}
/* конфликт правок (том 7): три исхода в одну строку, на узком — столбиком */
.confirm-inline .row3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:10px}
.confirm-inline .row3 .btn{padding:10px 8px;white-space:normal;line-height:1.2}
@media (max-width:380px){.confirm-inline .row3{grid-template-columns:1fr}}
/* «Изменения не сохранены» (сверка 26.09): в подвале окна — во всю ширину,
   над его кнопками; на терминале подвал — строка кнопок справа */
.sheet-foot .leave-ask{margin:0 0 4px}
body.deskmode .sheet-foot:has(.leave-ask){flex-wrap:wrap}
body.deskmode .sheet-foot .leave-ask{flex:1 1 100%;order:-1}
body.deskmode .sheet-foot .leave-ask .btn{min-width:0}
/* варианты ответа — кнопками с рамкой, а не тихим текстом «Отмены» подвала */
.sheet .sheet-foot .leave-ask .btn-ghost{border-color:var(--line2);background:transparent;color:var(--ink)}
/* телефон: «Сохранить» — во всю ширину, под ней «Не сохранять · Остаться» */
body:not(.deskmode) .leave-ask .row3{grid-template-columns:1fr 1fr}
body:not(.deskmode) .leave-ask .row3 .btn-primary{grid-column:1/-1}

/* ── Журнал: поиск и одна строка отборов (аудит 24.09) ───────────────── */
.jfilters.one{margin-bottom:10px}
.jfilters.one .jsearch{margin:0 0 8px}
.jfilters.one .chipbar{margin:0}
.desk-main > .screen > .jfilters.one{flex:1 1 100%;max-width:900px}
.desk-main .jfilters.one .chipbar{flex-wrap:wrap;overflow:visible}
/* абзацы, набранные с новой строки, так и показываются (аудит 24.09) */
.cmt-t{white-space:pre-line;overflow-wrap:anywhere}

/* ── Живые данные (том 7, аудит 24.09) ──────────────────────────────────
   Новые заявки не сдвигают ленту под пальцем — копятся в пилюле; без сети
   прежние данные остаются под вуалью с временем. */
.newpill{position:sticky;top:58px;z-index:var(--z-band);display:flex;align-items:center;gap:6px;margin:0 auto 10px;
  width:max-content;padding:7px 14px;border:0;border-radius:var(--r-pill);background:var(--accent);color:var(--on-accent);
  font:inherit;font-size:13px;font-weight:700;box-shadow:var(--shadow-float);cursor:pointer;animation:toastIn .25s var(--ease)}
.stale-note{display:flex;align-items:center;gap:8px;margin:0 0 10px;padding:9px 12px;border-radius:12px;
  background:var(--amber-t);border:1px solid var(--amber-b);font-size:13px;color:var(--ink)}
.stale-note svg{color:var(--amber);flex:none}
/* сбой обновления при живой сети: прежние данные и «Повторить» справа (сверка 26.09) */
.stale-note .btn{margin-left:auto;flex:none}
.stale-note.failed{background:var(--red-t);border-color:var(--red-b)}
.stale-note.failed svg{color:var(--red)}
.stale-note ~ .stack,.stale-note ~ .desk-table,.stale-note ~ .board{opacity:.62;filter:saturate(.6)}

/* ── Таблицы терминала (том 4, аудит 24.09) ─────────────────────────────
   Шапка длинных таблиц закреплена: таблица прокручивается в своей рамке,
   названия колонок остаются на месте. */
.desk-orders .desk-tablewrap{max-height:calc(100dvh - 190px);overflow:auto;overscroll-behavior:contain}
.desk-reports .desk-tablewrap{max-height:560px;overflow:auto;overscroll-behavior:contain}
.desk-orders .desk-tablewrap thead th,.desk-reports .desk-tablewrap thead th{
  position:sticky;top:0;z-index:var(--z-band);background:var(--bg);box-shadow:0 1px 0 var(--line)}
/* свежесть — тихая строка с точкой «канал живой»; жёлтого текста нет: когда
   данные устарели, над ними встаёт плашка (сверка 26.09) */
.fresh{font-size:var(--fs-12);color:var(--dim);white-space:nowrap;margin-left:auto;display:inline-flex;align-items:center;gap:8px}
.fresh[hidden]{display:none}
.fresh::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--green-fill);flex:none}
.fresh-line{display:flex;justify-content:flex-end;margin:-4px 0 6px}
kbd{display:inline-block;min-width:18px;padding:1px 5px;margin-left:6px;border-radius:5px;border:1px solid currentColor;
  font-family:var(--mono);font-size:11px;font-weight:700;line-height:1.35;text-align:center;opacity:.7}
.keys{display:grid;grid-template-columns:auto 1fr;gap:10px 14px;margin:6px 0 16px;align-items:center}
.keys dt kbd{margin:0;font-size:13px;opacity:1;padding:3px 8px;min-width:30px}
.keys dd{margin:0;color:var(--ink)}

/* ── Аватары (том 9): инициалы на цвете из имени; люди — круг, клиенты — квадрат ── */
.av{--s:24px;width:var(--s);height:var(--s);flex:none;display:inline-grid;place-items:center;border-radius:50%;
  font-size:max(11px, calc(var(--s) * .42));font-weight:700;letter-spacing:0;line-height:1;
  background:var(--av-bg,var(--accent-t));color:var(--av-fg,var(--accent))}
.av-org{border-radius:calc(var(--s) * .28)}
.av[data-c="0"]{--av-bg:color-mix(in srgb,var(--accent) 20%,transparent);--av-fg:var(--accent)}
.av[data-c="1"]{--av-bg:color-mix(in srgb,var(--blue-fill) 20%,transparent);--av-fg:var(--blue)}
.av[data-c="2"]{--av-bg:color-mix(in srgb,var(--green-fill) 20%,transparent);--av-fg:var(--green)}
.av[data-c="3"]{--av-bg:color-mix(in srgb,var(--amber-fill) 22%,transparent);--av-fg:var(--amber)}
.av[data-c="4"]{--av-bg:color-mix(in srgb,var(--red-fill) 18%,transparent);--av-fg:var(--red)}
.av[data-c="5"]{--av-bg:color-mix(in srgb,var(--blue-fill) 12%,var(--accent-t));--av-fg:var(--ink)}
.av[data-c="6"]{--av-bg:color-mix(in srgb,var(--green-fill) 12%,var(--amber-t));--av-fg:var(--ink)}
.av[data-c="7"]{--av-bg:var(--row);--av-fg:var(--ink)}
.with-av{display:inline-flex;align-items:center;gap:8px;min-width:0}
.with-av .av{--s:24px}
.desk-col.side .with-av .av{--s:24px}
.desk-col.side .with-av{gap:6px}
/* строка с аватаром клиента: квадрат слева, название и район справа */
.who.with-av-row{display:flex;align-items:center;gap:10px}
/* колонка «имя и подпись» — только она: правило задевало и сам аватар
   (тоже span), делало его колонкой, и инициалы уезжали к верхнему краю
   кружка («буквы в иконках», владелец 26.09) */
.who.with-av-row > span:not(.av){display:flex;flex-direction:column;min-width:0}
/* метка состояния (скрыт, на паузе, ждёт роль) — справа в строке имени */
.who.with-av-row > .tag,.who.with-av-row > .badge-urgent{margin-left:auto;flex:none;align-self:flex-start}
.who.with-av-row > .tag + .tag,.who.with-av-row > .badge-urgent + .tag{margin-left:0}
/* «Доступ»: пароль и отключение — наверху, права ниже, «Сохранить права» — в подвале */
.access-acts .row2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.access-acts .row2 .btn{white-space:normal;line-height:1.2}
@media (max-width:360px){.access-acts .row2{grid-template-columns:1fr}}
.daybox .ident.pending .v{color:var(--dim)}
/* склад: счётчик и порядок — одной строкой */
.countbar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:6px 0 8px}
.countbar .counter{margin:0;flex:1;min-width:0}
/* поиск: недавние запросы чипами, результаты на телефоне — карточками */
.chipbar.wrap{flex-wrap:wrap;overflow:visible;margin-bottom:12px}
.order.found .top{justify-content:space-between}
/* название экрана — настоящий заголовок для программ чтения, вид прежний */
.appbar .ttl h1{display:inline;margin:0;font:inherit;letter-spacing:inherit}
/* «Пороги»: было → стало и откат под полем; причина — одним полем сверху */
.setting-was{display:block;margin-top:4px;font-size:12px;color:var(--dim);white-space:normal}
.why-field{max-width:640px}

/* ── Уведомления по уровням (том 4, аудит 24.09) ─────────────────────── */
.notif.unread.lv-critical .dot{background:var(--red-fill)}
.notif.unread.lv-urgent .dot{background:var(--amber-fill)}
.notif.lv-digest{opacity:.85}
.notif.lv-critical{box-shadow:inset 3px 0 0 var(--red-fill)}
.notif-more{display:block;width:100%;margin:-2px 0 8px;padding:8px 12px;border:0;border-radius:10px;background:transparent;
  color:var(--accent);font:inherit;font-size:13px;font-weight:600;text-align:left;cursor:pointer}
.notif-more:hover{background:var(--accent-t)}
.notif-more.digest{margin-top:8px;background:var(--row);color:var(--ink)}
.kinds{margin-top:14px;border-top:1px solid var(--line);padding-top:10px}
.kinds summary{cursor:pointer;font-weight:600;font-size:14px;padding:4px 0}
.kind-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 0;border-bottom:1px solid var(--line)}
.kind-row:last-of-type{border-bottom:0}
.kind-row .lbl{display:flex;flex-direction:column;min-width:0;font-size:13.5px}
.kind-row .lv{font-size:11px;color:var(--dim)}
.kind-row .lv-critical{color:var(--red)} .kind-row .lv-urgent{color:var(--amber)}
.kind-locked{font-size:12.5px;white-space:nowrap}

/* ── Лист выбора (том 3): варианты — одной пластиной, «Отмена» — отдельно ── */
.actlist{display:flex;flex-direction:column;border-radius:var(--r-chip);overflow:hidden;background:var(--row);border:1px solid var(--line)}
.actlist .act-opt{border:0;border-bottom:1px solid var(--line);background:transparent;color:var(--ink);font:inherit;
  font-size:15px;font-weight:600;padding:13px 16px;min-height:48px;text-align:center;cursor:pointer;width:100%}
.actlist .act-opt:last-child{border-bottom:0}
.actlist .act-opt:hover{background:var(--rowh)}
.actlist .act-opt:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.act-cancel{display:block;width:100%;margin-top:8px;border:1px solid var(--line);border-radius:var(--r-chip);background:var(--panel2);
  color:var(--accent);font:inherit;font-size:15px;font-weight:700;padding:13px;min-height:48px;cursor:pointer}
.act-cancel:hover{background:var(--row)}
.actlist.reasons{gap:0;margin:10px 0 0}

/* ── Откуда число (том 7): плитка доски — кнопка с пояснением ─────────── */
.desk-kpis .kpi{position:relative;cursor:pointer;transition:border-color .2s var(--ease),background .2s var(--ease)}
.desk-kpis .kpi:hover{border-color:var(--line2)}
.kpi-i{position:absolute;top:8px;right:8px;color:var(--dim);opacity:.55;line-height:0}
.desk-kpis .kpi:hover .kpi-i,.desk-kpis .kpi:focus-visible .kpi-i{opacity:1}
.origin-text{margin:0 0 10px;font-size:14.5px;line-height:1.5;color:var(--ink)}
/* Правило формы для новых элементов (аудит 24.09): скругления — только
   токены --r-card / --r-sheet / --r-chip / --r-pill, кривая движения —
   var(--ease) на вход и cubic-bezier(.4,0,1,1) на уход. Старое не
   перекрашиваем: правило для того, что добавляется */
/* мелкий переключатель не выходит за край на 320 px: сжимается и листается
   вбок (найдено обходом 24.09 — «Случаи»: «Поднято выше» уезжало на 16 px) */
.seg.tiny{max-width:100%;min-width:0}
/* длинный комментарий в истории — пять строк и «Показать весь» */
.cmt-t.clamp{display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
.cmt .note-more{display:block;margin-top:4px}

/* ── Таблица по тому 4 «Стиля Г» (владелец 26.09: «для всех отчётов») ──
   Одно значение в ячейке, единица — в шапке мелко; сортировка по шапке;
   итог — липкой строкой снизу; плотность строк 32 · 44 · 56 выбирает
   человек; первый столбец остаётся на месте, если таблицу листают вбок.
   Разметку строит web/src/components/rtable.js. */
.rt{margin-top:16px}
.rt-bar{display:flex;align-items:center;gap:8px;margin:0 0 8px;flex-wrap:wrap}
.rt-bar h3{margin:0;font-size:var(--fs-15);font-weight:700;white-space:nowrap}
.rt-bar .sp{flex:1}
.rt-bar .seg{margin:0}
.rt-sort{display:inline-flex;align-items:flex-end;gap:4px;max-width:100%;font:inherit;color:inherit;letter-spacing:inherit;
  text-transform:inherit;text-align:inherit;background:none;border:0;padding:0;cursor:pointer}
th.num .rt-sort{justify-content:flex-end}
.rt-sort svg{flex:none;opacity:0;transition:opacity .15s var(--ease),transform .15s var(--ease)}
.rt-sort:hover svg,.rt-sort:focus-visible svg,.rt-sort.on svg{opacity:1}
.rt-sort.on{color:var(--ink)}
.rt-sort.asc svg{transform:rotate(180deg)}
/* единица — мелко под названием, как в эталоне тома 4 («Долг» / «шт.») */
.rt-l{display:inline-flex;flex-direction:column;align-items:flex-start}
th.num .rt-l{align-items:flex-end}
.rt-u{display:block;font-size:var(--fs-11);line-height:1.2;text-transform:none;letter-spacing:0;font-weight:500;color:var(--dim)}
.rt-t td,.rt-t th{vertical-align:middle}
.rt-t.rt-dense tbody td{height:32px;padding-top:2px;padding-bottom:2px}
.rt-t.rt-normal tbody td{height:44px;padding-top:4px;padding-bottom:4px}
.rt-t.rt-loose tbody td{height:56px;padding-top:8px;padding-bottom:8px}
.rt-t tfoot td{position:sticky;bottom:0;z-index:var(--z-band);background:var(--bg);font-weight:700;
  border-top:0;box-shadow:0 -1px 0 var(--line2)}
.rt-t td.rt-first,.rt-t th.rt-first{position:sticky;left:0;z-index:1;background:var(--bg);max-width:320px;text-align:left}
.rt-t tbody tr:hover td.rt-first{background:var(--rowh)}
.rt-t thead th.rt-first{z-index:calc(var(--z-band) + 1)}
.rt-t tfoot td.rt-first{z-index:calc(var(--z-band) + 1)}
.rt-t td.rt-text,.rt-t th.rt-text{text-align:left}
.rt-txt{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.rt-t td.rt-text .rt-txt{font-weight:500;max-width:260px}
.rt-count{display:flex;align-items:center;gap:8px;margin:8px 2px 0;font-size:var(--fs-13);color:var(--dim)}
.rt-pop-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:4px;
  padding:8px 8px 4px;border-top:1px solid var(--line);font-size:var(--fs-13)}
/* пять плиток — ряд закрыт: в строку, а на ноутбуке 3 + 2 на всю ширину */
.rkpis.five{grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:1199px){
  .rkpis.five{grid-template-columns:repeat(6,minmax(0,1fr))}
  .rkpis.five .kpi{grid-column:span 2}
  .rkpis.five .kpi:nth-child(n+4){grid-column:span 3}
}
/* последняя колонка такой таблицы — число: 200 px «оговорки» ей не нужны */
.grid.wide.rtable.rt-t td:last-child,.grid.wide.rtable.rt-t th:last-child{min-width:0;max-width:none}
/* имя обрезается многоточием, полностью — в подсказке (том 4) */
.rt-t td.rt-first .rt-txt{max-width:260px}
/* ноутбук: заголовки переносятся в две строки, отступы плотнее — семь
   столбцов влезают без прокрутки вбок */
.grid.wide.rtable.rt-t th{white-space:normal;line-height:1.25;vertical-align:bottom}
@media (max-width:1199px){
  body.deskmode .grid.wide.rtable.rt-t td{padding-left:8px;padding-right:8px}
  body.deskmode .grid.wide.rtable.rt-t th{padding-left:8px;padding-right:8px}
  .rt-t td.rt-first .rt-txt,.rt-t td.rt-text .rt-txt{max-width:170px}
}
/* «Столбцы» — по надписи, а не во всю строку, как выбор в фильтрах */
.rt-bar .rt-colsbtn{flex:none;width:auto;min-width:0;border-radius:999px}

/* ── Доска смены: «Сейчас» и «День» (владелец 26.09) ────────────────────
   Сверху — плитки того, что требует человека; плитка — вход на уровень
   ниже. Под ними — весь день одной полосой по группам «Заявок», группа —
   ссылка на список с этим отбором. Разметку строит components/shiftday.js. */
.now-tile{position:relative;border-radius:var(--r-card);border:1px solid var(--line);background:var(--panel);
  box-shadow:var(--shadow);min-width:0;transition:border-color .2s var(--ease)}
.now-tile:hover{border-color:var(--line2)}
.now-go{display:flex;flex-direction:column;gap:4px;width:100%;height:100%;padding:12px 12px 12px;text-align:left;
  font:inherit;color:inherit;background:none;border:0;border-radius:inherit;cursor:pointer;min-width:0}
.now-go:not([data-incidents]):not([data-jump]):not([data-free]):not([data-day-go]):not([data-cashbox]){cursor:default}
.now-go:active{transform:scale(.985)}
.now-tile .n{display:block;font-family:var(--mono);font-size:var(--fs-22);font-weight:700;line-height:1.05;
  overflow-wrap:anywhere;font-variant-numeric:tabular-nums}
.now-tile .l{display:block;font-size:var(--fs-13);color:var(--ink);font-weight:600;line-height:1.3}
.now-tile .s{display:block;font-size:var(--fs-12);color:var(--dim);line-height:1.3}
.now-tile.red{border-color:var(--red-b);background:linear-gradient(180deg,var(--red-t),var(--panel))}
.now-tile.red .n{color:var(--red)}
.now-tile.amber .n{color:var(--amber)}
.now-tile.accent .n{color:var(--accent)}
.now-i{position:absolute;top:4px;right:4px;width:28px;height:28px;display:grid;place-items:center;border:0;
  background:none;color:var(--dim);opacity:.6;border-radius:50%;cursor:help}
.now-i:hover,.now-i:focus-visible{opacity:1;background:var(--row)}
/* телефон: 2 × 2, числа крупнее; «i» — только на терминале */
.shift-now{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0 0 12px}
.shift-now .now-tile .n{font-size:clamp(var(--fs-17),6.4vw,var(--fs-22))}
.shift-now .now-go{min-height:96px}
/* терминал: шесть в ряд, на узком — по три */
.desk-kpis.now-row{grid-template-columns:repeat(6,minmax(0,1fr))}
@media (max-width:1250px){.desk-kpis.now-row{grid-template-columns:repeat(3,minmax(0,1fr))}}
.desk-kpis.now-row .now-go{padding-right:32px}
/* суммы в плитках — одной строкой: на 1440 «8 020 230 ₽» уводило «₽» вниз */
.desk-kpis.now-row .now-tile .n{font-size:clamp(var(--fs-17),1.45vw,var(--fs-22));white-space:nowrap}

/* «День»: полоса и подписи-ссылки */
.shift-day{margin-bottom:12px}
.shift-day h3{margin-bottom:8px}
.daybar{display:flex;height:10px;border-radius:var(--r-chip);overflow:hidden;background:var(--row);gap:2px}
.daybar i{display:block;min-width:4px}
.dg-free{background:var(--accent)}
.dg-work{background:var(--blue-fill)}
.dg-money{background:var(--amber-fill)}
.dg-done{background:var(--green-fill)}
.dg-bad{background:var(--red-fill)}
.day-keys{display:flex;flex-wrap:wrap;gap:8px 8px;margin-top:8px}
.day-key{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:4px 8px;border:1px solid var(--line2);
  border-radius:var(--r-chip);background:var(--row);color:var(--ink);font:inherit;font-size:var(--fs-13);cursor:pointer;
  transition:border-color .2s var(--ease)}
.day-key:hover{border-color:var(--accent-b)}
.day-key i{width:8px;height:8px;border-radius:50%;flex:none}
.day-key b{font-family:var(--mono);font-variant-numeric:tabular-nums}
.day-key.zero{color:var(--dim)}
.day-key.zero i{opacity:.45}
.day-cash{margin-top:8px}
body.deskmode .shift-day{padding:12px 16px}
body.deskmode .shift-day .day-key{min-height:30px;font-size:var(--fs-13)}
/* переход к части доски — короткая подсветка, чтобы глаз нашёл, куда пришёл */
.panel.flash{animation:panelFlash 1.2s var(--ease)}
@keyframes panelFlash{0%,100%{box-shadow:var(--shadow)}30%{box-shadow:0 0 0 3px var(--accent-b)}}
@media (prefers-reduced-motion:reduce){.panel.flash{animation:none}}

/* итог заявки — наверху карточки, под строкой меток (сверка 26.09) */
.card-result{margin:0 0 12px}
/* поиск: найденное подсвечено, прежняя выдача — под вуалью, пока едет новая */
mark{background:var(--amber-t);color:inherit;border-radius:var(--r-chip);padding:0 1px;box-shadow:0 0 0 1px var(--amber-b) inset}
.found-list{transition:opacity .2s var(--ease)}
.found-list.is-loading{opacity:.5}
.found-hit{margin-top:4px}

/* вывод отчёта — первой строкой, словами (тома 1 и 3) */
.rverdict{margin:0 0 12px;font-size:var(--fs-15);font-weight:600;line-height:1.4;color:var(--ink);max-width:980px;text-wrap:pretty}
/* отчёт перегружается — прежний под вуалью, а не пустота */
#rBody.is-loading{opacity:.55;transition:opacity .2s var(--ease);pointer-events:none}

/* окно «разбор»: заявка и вывод — сверху, шаги — ниже (сверка 26.09) */
.dispute-verdict{margin:0 0 12px}
.dispute-h{font-size:var(--fs-13);font-weight:700;color:var(--dim);margin:16px 0 8px}

/* ── значки, цели нажатия, метки (сверка 26.09, тома 1 и 9) ─────────── */
/* типы заявок — нейтральной меткой: цвет у нас значит состояние (красный —
   просрочено, зелёный — в норме), а «выдача денег» была красной, «кеш» —
   зелёным (владелец отметил «Делать») */
.badge-type,.badge-type.tovar,.badge-type.kesh,.badge-type.gibrid,.badge-type.zabor,.badge-type.payout,.badge-type.pickup{
  background:var(--row);color:var(--ink);border:1px solid var(--line2)}
/* миниатюры кадров — обрезка по центру без искажения */
.shots .photo img{width:100%;height:100%;object-fit:cover}
/* превью камеры — кадр целиком, в его пропорциях: портрет не режется */
.cam img{object-fit:contain}
/* кнопки со значком «+» — значок и слово в строку */
.with-i,.addcmt,.desk-acc-add{display:inline-flex;align-items:center;gap:8px}
.th-sort svg{flex:none;opacity:0;transition:transform .15s var(--ease),opacity .15s var(--ease)}
.th-sort.on svg{opacity:1}
.th-sort.asc svg{transform:rotate(180deg)}
.qty button,.daypick-arrow,.cal-nav,.viewer .v-nav{display:inline-grid;place-items:center}
/* цели нажатия: пальцем — 44 px, мышью — 36 px, вид прежний */
.toast .x{width:36px;height:36px}
.daypick-arrow{min-width:36px;min-height:36px}
.cal-nav{width:36px;height:36px}
.viewer .v-close{width:44px;height:44px}
.btn.icon{width:44px;height:44px}
.desk-acc .x{min-width:32px;min-height:32px;display:inline-grid;place-items:center}
@media (pointer:coarse){
  .toast .x{width:44px;height:44px}
  .daypick-arrow{min-width:44px;min-height:44px}
  .cal-nav{width:44px;height:44px}
  .qty button{width:44px}
}
/* стрелки дня на терминале — пилюля компактная (30 px), а нажимается 38 px:
   зона нажатия невидимым краем, вид прежний */
.daypick-arrow{position:relative}
.daypick-arrow::after{content:"";position:absolute;inset:-4px 0}
.qty input,.item-row .qty input{min-width:36px}
/* «Пороги»: когда вступает в силу — под названием */
.setting-effect{display:block;margin-top:4px;font-size:var(--fs-12);color:var(--dim);font-weight:400;line-height:1.35}

/* нажатая кнопка работает, а не выключена: крутилка и прежняя яркость (том 3) */
.btn.is-busy:disabled,button.is-busy:disabled{opacity:1;cursor:progress}
.spin{display:inline-block;width:1em;height:1em;margin-right:8px;border:2px solid currentColor;border-right-color:transparent;
  border-radius:50%;vertical-align:-.15em;animation:spin .8s linear infinite;flex:none}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spin{animation-duration:2.4s}}
/* уведомления по уровням: срочное — заметнее, критичное — висит до действия */
.toast.lvl-urgent{border-color:var(--amber-b);box-shadow:var(--shadow-float),0 0 0 1px var(--amber-b)}
.toast.lvl-critical{border-color:var(--red-b);box-shadow:var(--shadow-float),0 0 0 2px var(--red-b)}
.toast .more{display:block;font-size:var(--fs-12);color:var(--dim);margin-top:2px}

/* язычок окна тянется: зона захвата шире полоски, браузер не прокручивает под пальцем */
.sheet .grab{position:relative;touch-action:none;cursor:grab}
.sheet .grab::after{content:"";position:absolute;inset:-14px -70px}

/* данные едут: прежнее — под вуалью, выбор уже отмечен (сверка 26.09) */
.is-loading{opacity:.5;transition:opacity .2s var(--ease);pointer-events:none}

/* полоса очереди: «Повторить сейчас» — кнопкой в самой полосе */
.strip-retry{margin-left:8px;border:0;background:transparent;color:inherit;font:inherit;font-weight:700;
  text-decoration:underline;cursor:pointer;min-height:32px}

/* ── доска на ноутбуке 1024–1199 (сверка 26.09) ─────────────────────────
   «Свободные» и «На смене» уезжали под всю таблицу «В работе» — теперь
   две колонки: таблица слева, списки справа; у таблицы шапка закреплена,
   «разбор» — тихой «⋯» вместо кнопки в каждой строке, имя курьера — с
   многоточием, полностью — в подсказке */
.desk-tablewrap.board-live{max-height:calc(100dvh - 300px);min-height:220px;overflow:auto;overscroll-behavior:contain}
.desk-tablewrap.board-live thead th{position:sticky;top:0;z-index:var(--z-band);background:var(--panel)}
.row-more{width:32px;height:32px;display:inline-grid;place-items:center;border:0;background:transparent;color:var(--dim);
  border-radius:var(--r-chip);cursor:pointer}
.row-more:hover{background:var(--row);color:var(--ink)}
td.c-act{width:1%;white-space:nowrap}
@media (min-width:981px) and (max-width:1199px){
  .desk-cols{grid-template-columns:minmax(0,1fr) 250px}
  .desk-col.side .panel{padding-left:12px;padding-right:12px}
  .desk-board td.c-cour .nm{display:inline-block;max-width:48px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
  .desk-board .grid.wide td.who{white-space:nowrap}
  .desk-board td.who .as-link{max-width:98px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;vertical-align:bottom}
  .desk-board td.who small{white-space:normal}
  /* норматив — в подсказке у времени: пяти колонкам на ноутбуке тесно */
  .desk-board .nrm{display:none}
  .desk-board .board-live td,.desk-board .board-live th{padding-left:4px;padding-right:4px}
  .desk-board .board-live td.who{min-width:0;max-width:150px}
}

/* ── заглушки в форме своего экрана (сверка 26.09, том 3) ─────────────── */
.sk-tile{min-height:84px}
.sk-board,.sk-report,.sk-rows{display:grid;gap:16px}
.sk-board .sk-tiles,.sk-report .sk-tiles{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px}
.sk-board .sk-cols{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:16px;align-items:start}
.sk-report .sk-charts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.sk-report .sk-chart{height:240px}
.sk-bar{height:44px;border-radius:var(--r-card);background:linear-gradient(90deg,var(--row) 25%,var(--rowh) 37%,var(--row) 63%);
  background-size:400% 100%;animation:skWave 1.4s linear infinite}
.sk-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.sk-grid .sk-card{min-height:130px}
@media (max-width:1250px){
  .sk-board .sk-tiles,.sk-report .sk-tiles{grid-template-columns:repeat(3,minmax(0,1fr))}
  .sk-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:1199px){.sk-board .sk-cols{grid-template-columns:minmax(0,1fr) 250px}}
@media (max-width:980px){.sk-board .sk-cols,.sk-report .sk-charts{grid-template-columns:1fr}}
body:not(.deskmode) .sk-grid{grid-template-columns:1fr}
body:not(.deskmode) .sk-board .sk-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}
body:not(.deskmode) .sk-board .sk-cols{grid-template-columns:1fr}
@media (prefers-reduced-motion:reduce){.sk-bar{animation:none}}
/* отступы — те же, что у экрана под ней (.desk-main > .screen 18 px, .desk-list и
   .desk-reports 14 px): заглушка сменяется данными без сдвига; меняются вместе */
.desk-skel{position:absolute;inset:0;overflow:hidden;padding:18px 24px 24px}
.desk-skel.tight{padding-top:14px}
.sk-ghost{visibility:hidden}
.sk-ghost::before{content:none}
/* на терминале списки разделов — сеткой карточек, и заглушка тоже сеткой */
body.deskmode .desk-main > .screen > .skeleton:not(.sk-rows):not(.sk-board):not(.sk-report){
  flex:1 1 100%;grid-template-columns:repeat(3,minmax(0,1fr))}
body.deskmode .desk-main > .screen > .skeleton:not(.sk-rows):not(.sk-board):not(.sk-report) .sk-card{min-height:130px}
@media (max-width:1250px){body.deskmode .desk-main > .screen > .skeleton:not(.sk-rows):not(.sk-board):not(.sk-report){grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ── тома 1–2, мелочи (сверка 26.09) ───────────────────────────────────── */
/* крупная сумма: единица рядом серым 17/600 (А3.5) */
.big-sum{font-size:var(--fs-34);font-weight:700;letter-spacing:-.02em;line-height:1.1}
.big-sum.mid{font-size:var(--fs-22)}
.unit{font-family:var(--sans);font-size:var(--fs-17);font-weight:600;color:var(--dim);letter-spacing:0}
.now-tile .n .unit{font-size:var(--fs-15)}
/* знак со словом у числа или имени в таблице (А2.5) */
.rt-mk{display:inline-flex;vertical-align:-2px;margin-left:4px;color:var(--dim)}
.rt-mk.rr{color:var(--red)} .rt-mk.ry{color:var(--amber)} .rt-mk.rg{color:var(--green)}
.rt-cellrow{display:flex;align-items:center;gap:4px;min-width:0}
.rt-cellrow .rt-txt{min-width:0}
.rt-cellrow .rt-mk{flex:none;margin-left:0}
.rt-legend{margin:8px 2px 0;font-size:var(--fs-12);color:var(--dim);line-height:1.5}
.rt-legend .rt-mk{margin:0 2px 0 0}
/* «Четыре недели»: доля в норме числом под датой */
.wkc .p{font-family:var(--mono);font-size:var(--fs-11);font-weight:600}
.wkc .p.green{color:var(--green)} .wkc .p.yellow{color:var(--amber)} .wkc .p.red{color:var(--red)} .wkc .p.none{color:var(--dim)}

/* ── тома 1–2: окна, слои, наведение, ширина (сверка 26.09) ───────────── */
/* крестик окна: липкий в правом углу, текст шапки его обтекает; касание 44 */
.sheet-x{position:sticky;top:4px;float:right;z-index:var(--z-local);width:36px;height:36px;margin:-2px -6px 0 12px;
  display:grid;place-items:center;border:0;border-radius:50%;background:var(--row);color:var(--dim);cursor:pointer}
.sheet-x::after{content:"";position:absolute;inset:-4px}
.sheet-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* слой растёт из кнопки за 500 мс и уходит за 200 (Б1, Б3) */
@keyframes popIn{from{opacity:0;transform:translateY(-6px) scale(.965)}to{opacity:1;transform:none}}
@keyframes popInUp{from{opacity:0;transform:translateY(6px) scale(.965)}to{opacity:1;transform:none}}
@keyframes popOut{to{opacity:0;transform:scale(.98)}}
.pickpop,.pop-in{animation:popIn .5s var(--ease) both}
.pickpop.up{animation-name:popInUp}
.daycal.pop-in,.incal.pop-in{transform-origin:top left}
.listbar .daycal.pop-in{transform-origin:top right}
.pickpop.is-leaving{animation:popOut .2s cubic-bezier(.4,0,1,1) both;pointer-events:none}
/* подсказка из стекла вместо системной (Б1, «Подсказка») */
.tip{position:fixed;z-index:var(--z-tip);pointer-events:none;max-width:280px;padding:8px 12px;border-radius:var(--r-chip);
  background:var(--glass);border:1px solid var(--line2);box-shadow:var(--shadow-float);color:var(--ink);
  font-size:var(--fs-13);font-weight:500;line-height:1.4;white-space:pre-line;
  backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
  opacity:0;visibility:hidden;transform:translateY(2px);transition:opacity .2s var(--ease),transform .2s var(--ease),visibility 0s .2s}
.tip.on{opacity:1;visibility:visible;transform:none;transition:opacity .2s var(--ease),transform .2s var(--ease)}
@media (prefers-reduced-transparency:reduce){.tip{backdrop-filter:none;-webkit-backdrop-filter:none;background:var(--panel)}}
/* наведение — фон темнее, только мышью (А7.4) */
@media (hover:hover) and (pointer:fine){
  .btn:not(:disabled):hover{background:var(--rowh)}
  .btn-ghost:not(:disabled):hover{background:color-mix(in srgb,var(--ink) 9%,transparent)}
  .btn-primary:not(:disabled):hover,.take:not(:disabled):hover{background:var(--accent);filter:brightness(1.08)}
  .btn-good:not(:disabled):hover,.btn.good:not(:disabled):hover{background:var(--green-fill);filter:brightness(1.06)}
  .btn-danger:not(:disabled):hover{background:color-mix(in srgb,var(--red) 16%,transparent)}
  .iconbtn:not(:disabled):hover{background:var(--rowh)}
  .seg button:not(.on):not(:disabled):hover,.segmented button:not(.on):not(:disabled):hover{color:var(--ink);background:color-mix(in srgb,var(--ink) 6%,transparent)}
  .cal-cell:not(.empty):not(.off):not(.on):not(:disabled):hover{background:var(--rowh)}
  .chipbar > button:not(.on):hover{border-color:var(--accent-b);color:var(--ink)}
  .sheet-x:hover{background:var(--rowh);color:var(--ink)}
}
/* ширина терминала: поле 32 на широком, содержимое до 1480 (А9.2, А9.3) */
@media (min-width:1280px){
  .desk-board,.desk-reports,.desk-list,.desk-main > .screen,.desk-skel{padding-left:32px;padding-right:32px}
}
.desk-board > *,.desk-reports > *{max-width:1480px}
/* между разделами терминала — 28: «сейчас и день» → списки, графики → таблица (А9.5) */
body.deskmode .shift-day{margin-bottom:28px}
@media (min-width:1200px){.desk-cols{gap:28px}}
body.deskmode .desk-reports .rt{margin-top:28px}

/* ── графики: ось справа, «сейчас», пропуски, ступени (сверка 26.09) ─── */
.chart text.unit{fill:var(--dim2)}
.chart .track.missing{fill:none;stroke:var(--line2);stroke-dasharray:3 3;opacity:1}
.chart text.gap-l{fill:var(--dim);font-size:11px}
.chart text.now{font-size:11px;font-weight:600;paint-order:stroke;stroke:var(--panel);stroke-width:3px;stroke-linejoin:round}
.chart text.peak{paint-order:stroke;stroke:var(--panel);stroke-width:3px;stroke-linejoin:round}
.chart.heat text.tot{font-weight:700;fill:var(--ink)}

/* ── том 3: ожидание и подача (сверка 26.09) ─────────────────────────── */
/* заглушка видна с 1 с; при «Уменьшении движения» — тоже с 1 с, но без
   плавности: общее правило снимало задержку, и заглушка снова мигала (З13) */
@keyframes skShowStep{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .skeleton{animation:skShowStep 1s step-end both!important}
  .sk-say{animation:skShowStep 4s step-end both!important}
}
/* держится, пока не прошло 500 мс показа; новое уже на месте, но скрыто */
.skeleton.sk-held,.sk-held .skeleton{animation:none!important;opacity:1}
.sk-holding > :not(.sk-held){visibility:hidden}
/* содержимое встаёт блоками по очереди, шаг 50 мс, не больше пяти (С3) */
@keyframes riseIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.rise-in > :nth-child(-n+5){animation:riseIn .35s var(--ease) both}
.rise-in > :nth-child(2){animation-delay:50ms} .rise-in > :nth-child(3){animation-delay:100ms}
.rise-in > :nth-child(4){animation-delay:150ms} .rise-in > :nth-child(5){animation-delay:200ms}
/* одна волна на весь экран: фон привязан к окну, а не к каждой полосе (С2) */
.sk-line,.sk-btn,.sk-bar,.desk-boot .sk-bar{background-attachment:fixed}
/* с 4 с — словами, что ждём (Ж5) */
.sk-say{grid-column:1/-1;margin:4px 0 0;font-size:var(--fs-13);color:var(--dim);opacity:0;animation:skShow .3s ease 4s both}
/* «Загружаем кадр…» — не с первого кадра, а с 300 мс (Ж1) */
.viewer .v-wait{animation:skShow .25s ease .3s both}
/* журнал: день заголовком, время слева моноширинным, вид словом (Д4) */
.jday{list-style:none;margin:12px 2px 2px;font-size:var(--fs-13);font-weight:700;color:var(--ink)}
.jday:first-child{margin-top:0}
.jrow{display:grid;grid-template-columns:44px minmax(0,1fr);gap:8px;align-items:start}
.jtime{font-family:var(--mono);font-size:var(--fs-12);color:var(--dim);padding-top:1px;font-variant-numeric:tabular-nums}
.jbody{min-width:0}
.jkind{flex:none;font-size:var(--fs-11);color:var(--dim);white-space:nowrap}
.jkind::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:4px;vertical-align:1px;background:var(--dim2)}
.jkind.k-order::before{background:var(--blue-fill)} .jkind.k-money::before{background:var(--green-fill)}
.jkind.k-incident::before{background:var(--red-fill)} .jkind.k-access::before,.jkind.k-login::before{background:var(--accent)}
/* № заявки в строке таблицы и в «Смене» */
.ono{font-family:var(--mono);font-size:var(--fs-12);color:var(--dim);margin-right:6px}
.sc-sub{font-size:var(--fs-12);color:var(--dim);margin-top:2px}
/* сводка кассы: время проверки у заголовка, вывод — первой строкой */
.daybox-at{margin-left:8px;font-weight:500;color:var(--dim);font-size:var(--fs-12)}
.daybox-say{margin:4px 0 8px}
.rbuilt{margin-top:8px}

/* ── том 3: окна изнутри (сверка 26.09) ─────────────────────────────── */
/* ширина по задаче: S 400 — подтверждение и ввод строки, M 560 — форма, L 760 (Ок9) */
body.deskmode .sheet[data-size="s"]{max-width:400px}
body.deskmode .sheet[data-size="l"]{max-width:760px}
/* шапка окна стоит, прокручивается тело (Ок3); контекст — мелко над названием (Ок1) */
.sheet > .sheet-head{position:sticky;top:-10px;z-index:var(--z-local);background:var(--panel);
  margin:-10px 0 16px;padding:10px 0 8px}
.sheet-ctx{margin:0 0 2px;font-size:var(--fs-12);color:var(--dim)}
.sheet-x{z-index:var(--z-foot)}
/* подтверждение: подвал без липкой тени — окно короткое */
.sheet[data-size="s"] .sheet-foot{box-shadow:none;margin-top:12px}
/* колокольчик: «прочитать всё» — в шапке, дни — заголовками */
.bell-head{flex-direction:row!important;align-items:baseline;gap:12px;flex-wrap:wrap}
.bell-head h2{margin:0}
.bell-head .as-link{font-size:var(--fs-13);margin-left:auto;margin-right:44px}
.bell-day{margin:12px 2px 6px;font-size:var(--fs-12);font-weight:700;color:var(--dim);text-transform:none}
.bell-day:first-child{margin-top:0}
/* просмотр кадра: подпись снизу, превью размыто, кадр проявляется, сбой — «Повторить» */
.viewer .v-cap{position:absolute;left:50%;bottom:calc(16px + env(safe-area-inset-bottom));translate:-50% 0;max-width:min(92%,640px);
  padding:8px 14px;border-radius:var(--r-pill);background:rgba(20,18,28,.72);color:#fff;font-size:var(--fs-13);text-align:center;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.viewer .v-img{max-width:100%;max-height:100%;object-fit:contain;opacity:0;filter:blur(14px);transition:opacity .7s var(--ease),filter .7s var(--ease)}
.viewer .v-img.v-blur{opacity:.75}
.viewer .v-img.on{opacity:1;filter:none}
.viewer .v-err{color:#e8e6ef}
.viewer .v-err svg{opacity:.8}
@media (prefers-reduced-motion:reduce){.viewer .v-img{filter:none;opacity:1}}

/* подтверждение: его действие — главное, справа и последним, даже разрушительное (Ок4) */
body.deskmode .sheet[data-size="s"] .sheet-foot #askOk{order:2}
body.deskmode .sheet[data-size="s"] .sheet-foot #askCancel{order:1}

/* ── том 4: таблицы, поиск, отчёты (сверка 26.09) ─────────────────────── */
/* шапка числовой колонки — справа, над числами (п. 15: «На смене», поиск) */
.grid th.num{text-align:right}
/* длинное имя — многоточием, полностью — в подсказке (п. 17) */
.desk-table td.c-client{max-width:300px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (min-width:1200px){.board-live td.who .as-link{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;vertical-align:bottom}}
/* сравнение с прошлым периодом под числом плитки (п. 21) */
.kpi .delta{display:block;margin-top:2px;font-size:var(--fs-11);color:var(--dim);font-weight:500}
.kpi .delta.good{color:var(--green)} .kpi .delta.bad{color:var(--red)}
/* без дыр в ряду графиков: последняя одиночная половинная — на всю ширину (п. 21) */
.chart-grid > .chart-card:not(.wide):nth-child(odd of :not(.wide)):last-child{grid-column:1/-1}
/* поиск: отборы по состоянию, подсказка про раскладку */
.found-facets{margin:4px 0 8px}
.found-alt{margin:4px 0 6px}

/* ── том 8: навигация и клавиатура (сверка 26.09) ─────────────────────── */
/* меню терминала — группами */
.desk-group{display:block;margin:12px 10px 4px;font-size:var(--fs-11);font-weight:600;color:var(--dim2);letter-spacing:.02em}
.desk-group:first-child{margin-top:0}
.desk-keys{border:0;background:transparent;font:inherit;cursor:pointer;width:100%;text-align:left}
.desk-keys kbd,.q-kbd{font-family:var(--mono);font-size:var(--fs-11);padding:1px 6px;border:1px solid var(--line2);border-radius:var(--r-chip);color:var(--dim);background:var(--row)}
.desk-keys kbd{margin-left:auto}
/* «/» — на самом поле поиска «Заявок» */
.q-wrap{position:relative;display:inline-flex;align-items:center;flex:1 1 200px;min-width:0}
.q-wrap input{width:100%;padding-right:34px}
.q-kbd{position:absolute;right:10px;pointer-events:none}
.q-wrap:focus-within .q-kbd{display:none}
/* «Перейти к содержанию» — видна только с клавиатуры */
.skip{position:fixed;left:12px;top:-60px;z-index:var(--z-reauth);padding:10px 14px;border-radius:var(--r-pill);background:var(--accent);color:var(--on-accent);font-weight:700;text-decoration:none;transition:top .2s var(--ease)}
.skip:focus{top:12px}
#view:focus{outline:none}

/* ── том 8: формы (сверка 26.09) ──────────────────────────────────────── */
/* сегмент вместо списка из 2–5 вариантов */
.segfield{display:flex;gap:4px;padding:3px;border:1px solid var(--line2);border-radius:var(--r-pill);background:var(--row)}
.segfield [data-seg]{flex:1;min-height:40px;border:0;border-radius:var(--r-pill);background:transparent;color:var(--dim);
  font:inherit;font-size:var(--fs-13);font-weight:600;cursor:pointer;padding:6px 10px;white-space:nowrap}
.segfield [data-seg].on{background:var(--panel);color:var(--ink);box-shadow:var(--shadow)}
.segfield.vertical{flex-direction:column;border-radius:var(--r-card);padding:4px}
.segfield.vertical [data-seg]{border-radius:var(--r-chip);text-align:left;padding:10px 12px}
@media (hover:hover) and (pointer:fine){.segfield [data-seg]:not(.on):hover{color:var(--ink);background:color-mix(in srgb,var(--ink) 6%,transparent)}}
body.deskmode .segfield [data-seg]{min-height:32px}
/* «−» и «+» на границе — погашены */
.qty button:disabled{opacity:.35;cursor:default}
/* дата цифрами в календаре */
.pickcal-type{display:flex;align-items:center;gap:8px;margin:0 0 8px;font-size:var(--fs-12);color:var(--dim)}
.pickcal-type .pick-q{flex:1;min-width:0}
/* счётчик длины */
.len-count{display:block;margin-top:4px;font-size:var(--fs-11);color:var(--dim);text-align:right}
.len-count.near{color:var(--amber)}
/* необязательное / обязательное поле */
.opt{margin-left:6px;font-size:var(--fs-11);font-weight:500;color:var(--dim2)}

/* сегмент в паре полей: на узком экране — на всю строку, иначе три варианта
   ломались в два ряда (проверка ш51) */
@media (max-width:640px){.pair > .field:has(> .segfield),.row > .field:has(> .segfield){grid-column:1/-1}}
.segfield{flex-wrap:nowrap}
/* сегмент внутри поля — не подпись: правило `.field>span` делало его блоком */
.field > .segfield{display:flex;margin:0;color:inherit;font-weight:inherit;font-size:inherit}
.field > .segfield.vertical{flex-direction:column}
@media (max-width:640px){.pair:has(> .field > .segfield),.row:has(> .field > .segfield){grid-template-columns:1fr}}

/* ── том 7: живые данные (сверка 26.09) ───────────────────────────────── */
/* свежесть: серая точка после минуты, жёлтая и «Обновить» после двух */
.fresh.warm::before{background:var(--dim2)}
.fresh.stale::before{background:var(--amber-fill)}
.fresh .fresh-refresh{margin-left:8px;font-size:var(--fs-12)}
/* данные, которые могли устареть, — бледнее; без сети — тоже, под плашкой */
.data-stale .now-tile .n,.data-stale .desk-table td,.data-stale .board-live td{opacity:.62}
.desk-board:has(.stale-note) :is(.desk-kpis,.shift-day,.desk-cols),
#deskList:has(.stale-note) .desk-tablewrap{opacity:.62;filter:saturate(.6);transition:opacity .3s var(--ease)}
.state-auto{margin-top:8px;font-size:var(--fs-12);color:var(--dim)}

/* ── том 10: вход и аккаунт; откат из журнала (сверка 26.09) ──────────── */
/* регистрация — ссылкой под «Войти», а не второй кнопкой той же ширины */
.reg-line{margin:14px 0 0;text-align:center;font-size:var(--fs-13);color:var(--dim)}
.reg-line .as-link{font-size:inherit}
.jroll{display:flex;align-items:center;gap:10px;margin-top:6px;font-size:var(--fs-12)}

/* ── том 9: значки и иллюстрации (сверка 26.09) ───────────────────────── */
/* аватар в таблицах — 20 (по тому), в остальном — 24 */
.grid .av,.desk-table .av,.rtable .av{--s:20px}
/* цвета аватаров — не цвета зон: красный, жёлтый и зелёный кружок курьера
   читался как «просрочено / на грани / в норме» рядом с точкой зоны */
.av[data-c="2"]{--av-bg:color-mix(in srgb,#5fa8b8 22%,transparent);--av-fg:#5fa8b8}
.av[data-c="3"]{--av-bg:color-mix(in srgb,#b08bd8 22%,transparent);--av-fg:#b08bd8}
.av[data-c="4"]{--av-bg:color-mix(in srgb,#c98bb0 20%,transparent);--av-fg:#c98bb0}
.av svg{width:calc(var(--s) * .5);height:calc(var(--s) * .5)}
/* пустой экран: знак в круге над словами */
.state-ic{width:48px;height:48px;margin:0 auto 10px;border-radius:50%;display:grid;place-items:center;background:var(--row);color:var(--dim)}
.chip-pick[data-unorder]{display:inline-flex;align-items:center;gap:4px}

/* «i» у плиток на телефоне — цель пальцем 44 (том 9), знак тот же */
.shift-now .now-i{width:44px;height:44px;top:0;right:0}
.shift-now .now-go{padding-right:44px}
/* журнал на узком экране: вид записи уходит на следующую строку, а не за край (обход ш54) */
.jhead{flex-wrap:wrap;row-gap:2px}
.jkind{max-width:100%}

/* ══ «Заявки дня» на телефоне: день и два значка (репорт №115, вариант 3
   по выбору владельца 27.09) ══
   Плашка дня забирала 62–72 % строки, «Все курьеры» и порядок уезжали за
   край. Дата теперь без капсулы и без второй подложки — кнопка текстом;
   отборы — в шторке за значком с числом выбранного, порядок — своим значком
   с точкой, когда он не «как в ленте». Календарь раскрывается под датой. */
.listbar.tools{flex-wrap:nowrap;justify-content:space-between;gap:8px}
.listbar.tools .daycal{left:0;right:auto}
.listbar.tools .daycal.pop-in{transform-origin:top left}
.daynav{display:inline-flex;align-items:center;min-width:0;margin-left:-8px}
.daynav button{
  border:0;background:none;color:var(--ink);font:inherit;cursor:pointer;border-radius:999px;
  min-height:36px;display:inline-flex;align-items:center;justify-content:center;position:relative;
  transition:transform .25s var(--ease),background .3s var(--ease),color .3s var(--ease);
}
.daynav button:active{transform:scale(.97)}
.daynav button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.daynav-arrow{flex:none;width:36px;color:var(--dim)}
.daynav-arrow:hover{background:var(--row);color:var(--ink)}
.daynav-label{gap:6px;padding:0 8px;font-size:14.5px;font-weight:700;letter-spacing:-.015em;white-space:nowrap;min-width:0}
.daynav-label span{overflow:hidden;text-overflow:ellipsis}
.daynav-label .cal-i{flex:none;color:var(--accent)}
.daynav-label .cal-c{flex:none;color:var(--dim);transition:transform .2s var(--ease)}
.daynav-label:hover{background:var(--row)}
.daynav-label[aria-expanded="true"]{background:var(--accent-t)}
.daynav-label[aria-expanded="true"] .cal-c{transform:rotate(180deg)}
/* пальцем — 44 px в высоту (том 9): невидимым краем, строка не растёт */
@media (pointer:coarse){
  .daynav button{min-height:40px}
  .daynav-arrow{width:40px}
  .daynav button::after{content:"";position:absolute;inset:-2px 0}
}
@media (max-width:360px){.daynav-label .cal-i{display:none}}
.lb-tools{display:flex;gap:8px;flex:none}
.iconbtn.lb-ic{width:42px;height:36px;border-radius:999px;background:var(--panel2)}
.iconbtn.lb-ic svg{width:20px;height:20px;color:var(--dim)}
.iconbtn.lb-ic.set{background:var(--accent-t);border-color:var(--accent-b)}
.iconbtn.lb-ic.set svg{color:var(--accent)}
.iconbtn.lb-ic .bdg{background:var(--accent);color:var(--on-accent)}
.iconbtn.lb-ic .dot{position:absolute;top:5px;right:7px;width:7px;height:7px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 2px var(--panel2)}
.iconbtn.lb-ic:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media (pointer:coarse){.iconbtn.lb-ic{width:46px;height:40px}.iconbtn.lb-ic::after{content:"";position:absolute;inset:-2px 0}}
/* шторка «Отбор заявок»: разделы с вариантами-капсулами, число — сколько заявок */
.fsec{margin-top:16px}
.fsec-t{font-size:13px;font-weight:700;color:var(--dim);margin:0 0 8px}
.fopts{display:flex;flex-wrap:wrap;gap:6px}
.fopt{
  display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 12px;
  border-radius:999px;border:1px solid var(--line2);background:var(--panel2);color:var(--ink);
  font:inherit;font-size:13.5px;cursor:pointer;
  transition:transform .2s var(--ease),background .25s var(--ease),border-color .25s var(--ease);
}
.fopt i{font-style:normal;font-family:var(--mono);font-size:12px;line-height:1;color:var(--dim);position:relative;top:1px}   /* цифра — на строке подписи, а не выше */
.fopt.zero{color:var(--dim)}
.fopt.on{background:var(--accent-t);border-color:var(--accent-b);font-weight:600}
.fopt.on svg{flex:none;color:var(--accent)}
.fopt:active{transform:scale(.97)}
.fopt:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media (pointer:coarse){.fopt{min-height:40px}}
.fsheet-foot{grid-template-columns:auto 1fr}

/* ══ Загрузочный экран (репорт №116; вариант А и чередование — выбор
   владельца 27.09) ══
   Встаёт, только если старт дольше 0,4 с — на быстрой сети не мелькает, до
   этого видна рамка первого кадра. Картинки сменяются по 2 с по кругу:
   маршрут → смартфон «доставлено» → секундомер; движение каждой длится ровно
   2 с, поэтому начинается с начала, когда картинка появляется. С 5-й секунды —
   «Сеть медленная» и «Обновить», после выкатки — «Обновляем приложение…».
   Уходит плавно, как только на месте первый экран: дальше ожидание
   показывает заглушка раздела. Классы на <html> ставят boot.js, app.js и
   core/updates.js. Надписи внутри — splash-note-*, а не splash-slow/-upd:
   те же имена у классов на <html>, и правило «надпись скрыта» прятало
   страницу целиком (стенд 27.09). */
.splash{
  position:fixed;inset:0;z-index:95;display:none;flex-direction:column;align-items:center;justify-content:center;
  padding:24px;text-align:center;background:var(--bg);color:var(--ink);transition:opacity .3s var(--ease);
}
html.splash-on .splash{display:flex;animation:splashIn .25s ease backwards}
html.app-ready .splash{opacity:0;pointer-events:none}
@keyframes splashIn{from{opacity:0}}
.splash-seq{position:relative;flex:none;width:176px;height:112px}
body.deskmode .splash-seq{width:220px;height:140px}
.splash-it{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;animation:splashSeq 6s linear infinite}
.splash-it.spl-phone{animation-delay:2s}
.splash-it.spl-clock{animation-delay:4s}
@keyframes splashSeq{0%{opacity:0}4%{opacity:1}30%{opacity:1}36%{opacity:0}100%{opacity:0}}
.splash-vis{position:relative;flex:none}
body.deskmode .splash-vis{transform:scale(1.25)}
.splash-vis svg{display:block;overflow:visible}
.splash-name{margin-top:20px;font-size:var(--fs-19);font-weight:700;letter-spacing:-.02em}
body.deskmode .splash-name{font-size:23px}
.splash-sub{display:none;margin-top:2px;font-size:var(--fs-13);color:var(--dim)}
body.deskmode .splash-sub{display:block}
.splash-note-upd{display:none;margin-top:12px;font-size:var(--fs-13);color:var(--dim)}
html.splash-upd .splash-note-upd{display:block}
.splash-note-slow{display:none;margin-top:18px;max-width:290px}
html.splash-slow:not(.splash-upd) .splash-note-slow{display:block}
.splash-note-slow p{font-size:13.5px;line-height:1.45;margin:0 0 12px}
/* маршрут: точка-курьер бежит от старта к метке, след закрашивается */
.spl-r-base{fill:none;stroke:var(--line);stroke-width:3;stroke-linecap:round;stroke-dasharray:1 7}
.spl-r-run{fill:none;stroke:var(--accent);stroke-width:3;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100;animation:splRun 2s cubic-bezier(.5,0,.3,1) infinite}
.spl-r-start{fill:var(--bg);stroke:var(--dim);stroke-width:2.5}
.spl-r-pin{fill:var(--accent)}
.spl-r-hole{fill:var(--bg)}
.spl-r-dot{
  position:absolute;left:0;top:0;width:12px;height:12px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 5px var(--accent-t);offset-path:path("M14 72 C 50 72, 54 30, 90 30 S 130 62, 156 44");
  offset-anchor:50% 50%;offset-rotate:0deg;animation:splDot 2s cubic-bezier(.5,0,.3,1) infinite;
}
@keyframes splRun{0%{stroke-dashoffset:100;opacity:1}72%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
@keyframes splDot{0%{offset-distance:0%;opacity:0}6%{opacity:1}72%{offset-distance:100%;opacity:1}100%{offset-distance:100%;opacity:0}}
/* смартфон «доставлено»: телефон поднимается, на экране рисуется галочка */
.spl-ph{animation:splPhIn 2s ease infinite}
.spl-ph-body{fill:var(--bg);stroke:var(--accent);stroke-width:4}
.spl-ph-top{fill:var(--dim)}
.spl-ph-okbg{fill:var(--accent-t);transform-box:fill-box;transform-origin:center;animation:splOkBg 2s ease infinite}
.spl-ph-ok{fill:none;stroke:var(--accent);stroke-width:4.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:100;stroke-dashoffset:100;animation:splOk 2s cubic-bezier(.6,0,.3,1) infinite}
@keyframes splPhIn{0%{transform:translateY(8px);opacity:0}14%{transform:none;opacity:1}88%{opacity:1}100%{opacity:0}}
@keyframes splOkBg{0%,22%{transform:scale(.4);opacity:0}38%,100%{transform:scale(1);opacity:1}}
@keyframes splOk{0%,34%{stroke-dashoffset:100}60%,100%{stroke-dashoffset:0}}
/* секундомер: стрелка обегает круг, дуга набирается следом */
.spl-c-top{fill:var(--dim)}
.spl-c-track{fill:none;stroke:var(--line);stroke-width:7}
.spl-c-arc{fill:none;stroke:var(--accent);stroke-width:7;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100;
  transform:rotate(-90deg);transform-box:fill-box;transform-origin:center;animation:splArc 2s linear infinite}
.spl-c-hand{stroke:var(--ink);stroke-width:3.5;stroke-linecap:round;transform-box:view-box;transform-origin:50px 64px;animation:splHand 2s linear infinite}
.spl-c-hub{fill:var(--ink)}
@keyframes splArc{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
@keyframes splHand{to{transform:rotate(360deg)}}
/* «меньше движения»: движение гасит общее правило выше — остаётся один
   маршрут, уже пройденный, без смены картинок */
@media (prefers-reduced-motion:reduce){
  .splash-it.spl-route{opacity:1}
  .spl-r-run{stroke-dashoffset:0}
  .spl-r-dot{offset-distance:100%}
}

/* ── Распознано с фото (владелец 30.09): плашка под кадрами шага, как
   комментарий шага; столбик «что — значение — с какого фото — копировать».
   Сворачивается заголовком (одна настройка на устройство), «Все коды» —
   IMEI и серийники шага столбиком, работает и в свёрнутой. ── */
.ph .rec{margin-top:7px;background:var(--row);border:1px solid var(--line);border-radius:10px;
  padding:0 2px 2px 11px;font-size:12.5px;line-height:1.4}
.rec-top{display:flex;align-items:center;gap:4px}
.rec-tog{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;gap:6px;border:0;background:none;
  font:inherit;color:var(--dim);padding:6px 0;min-height:40px;cursor:pointer;text-align:left}
.rec-tog span{overflow-wrap:anywhere}
.rec-tog svg{flex:none;transition:transform .2s var(--ease)}
.rec:not(.folded) .rec-tog svg{transform:rotate(180deg)}
.rec-all{flex:none;display:inline-flex;align-items:center;gap:5px;border:0;background:none;color:var(--accent);
  font:inherit;font-weight:600;padding:6px 8px;min-height:40px;border-radius:8px;cursor:pointer;white-space:nowrap}
.rec-all:hover{background:var(--rowh)}
.rec.folded .rec-list{display:none}
.rec-r{display:grid;grid-template-columns:62px minmax(0,1fr) auto 40px;align-items:center;gap:6px;
  min-height:40px;border-top:1px solid var(--line)}
.rec-k{color:var(--dim)}
.rec-v{border:0;background:none;padding:6px 0;text-align:left;font:inherit;font-size:13px;color:var(--ink);
  cursor:pointer;overflow-wrap:anywhere;min-width:0}
.rec-v.code{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:.01em}
.rec-src{font-size:11px;color:var(--dim);white-space:nowrap}
.rec-cp{width:40px;height:40px;display:flex;align-items:center;justify-content:center;border:0;background:none;
  color:var(--dim);border-radius:8px;cursor:pointer}
.rec-cp:hover{background:var(--rowh);color:var(--ink)}
.rec-v:active,.rec-cp:active,.rec-all:active{color:var(--accent)}
@media (prefers-reduced-motion:reduce){.rec-tog svg{transition:none}}
/* Узкий телефон (320): IMEI в строку не влезал и рвался посередине —
   подпись и «фото N» строкой выше, значение целиком ниже */
.ph .rec{container-type:inline-size}
@container (max-width:280px){
  .rec-r{grid-template-columns:auto minmax(0,1fr) 40px;grid-template-areas:"k s cp" "v v cp";
    column-gap:6px;row-gap:0;padding-top:6px}
  .rec-k{grid-area:k;font-size:11.5px}
  .rec-src{grid-area:s}
  .rec-v{grid-area:v;padding-top:0}
  .rec-cp{grid-area:cp}
}
/* Форма создания без поля серийника (владелец 30.09: IMEI читает
   распознавание фото) — сетка позиции без его ряда */
.item-row.no-serial{grid-template-areas:"name name drop" "qty price price" "src src src"}
.desk-pane-body .item-row.no-serial{grid-template-areas:"name name name drop" "qty price src src"}
/* Метки заявки из чата (бот-сборщик, владелец 01.10): оранжевые, текстом как
   написали; срочность не меняют — поэтому не заливка «Срочно», а контур */
.badge-tag{display:inline-block;vertical-align:middle;font-size:11px;font-weight:600;line-height:1.35;
  padding:2px 8px;border-radius:var(--r-chip);background:var(--amber-t);color:var(--amber);
  border:1px solid var(--amber-b);max-width:16em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.badge-urgent+.badge-tag,.badge-hour+.badge-tag{margin-left:6px}
.badge-tag+*{margin-left:6px}
