/* Токени бренду «Арктика» (брендбук стор. 20, 24-26) */
:root{
  --navy:#050E37; --blue:#0258C9; --cyan:#2DBEF4;
  --sky:#78C9FF; --pale:#CDE2F6; --white:#FFFFFF;
  /* поверхня/текст/рамки — як в адмінці сайту */
  --surface:#F2F7FD; --muted:#5A6A8C; --border:#DBE7F5;
  --blue-600:#024AA8; --blue-700:#033C88;
  /* семантика статусів (м'які тінти: рамка / фон / текст) */
  --ok:#047857; --ok-bg:#ECFDF5; --ok-bd:#A7F3D0;
  --warn:#B45309; --warn-bg:#FFFBEB; --warn-bd:#FDE68A;
  /* danger затемнений #DC2626→#B91C1C: 11px-бейдж «спам» на блідому фоні
     тепер проходить контраст WCAG AA (4.41:1 → 5.9:1) */
  --danger:#B91C1C; --danger-bg:#FEF2F2; --danger-bd:#FECACA;
  /* тіні — рідко й м'яко */
  --shadow-brand:0 18px 40px -20px rgba(2,88,201,.45);
  --shadow-card:0 14px 34px -18px rgba(5,14,55,.22);
  /* радіуси — округло, «повітряний дашборд» */
  --r-lg:24px; --r-md:18px; --r-sm:14px;
  --font-display:"Bebas Neue Cyrillic","Bebas Neue",sans-serif;
  --font-body:"Fira Sans",system-ui,sans-serif;
}
@font-face{font-family:"Bebas Neue Cyrillic";font-weight:400;
  src:url(/static/fonts/BebasNeueCyrillic.woff2) format("woff2");
  font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:400;font-style:normal;
  src:url(/static/fonts/fira-sans-cyrillic-400.woff2) format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
  font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:400;font-style:normal;
  src:url(/static/fonts/fira-sans-latin-400.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2212;font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:500;font-style:normal;
  src:url(/static/fonts/fira-sans-cyrillic-500.woff2) format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
  font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:500;font-style:normal;
  src:url(/static/fonts/fira-sans-latin-500.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2212;font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:700;font-style:normal;
  src:url(/static/fonts/fira-sans-cyrillic-700.woff2) format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
  font-display:swap}
@font-face{font-family:"Fira Sans";font-weight:700;font-style:normal;
  src:url(/static/fonts/fira-sans-latin-700.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2212;font-display:swap}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* тіло на блідо-блакитній поверхні, вага 400 (як адмінка) */
body{margin:0;background:var(--surface);color:var(--navy);
  font:400 16px/1.5 var(--font-body);-webkit-font-smoothing:antialiased}
a{color:var(--blue);text-decoration:none}
h1,h2,h3{font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;letter-spacing:.01em;line-height:.95;
  margin:.2em 0;color:var(--navy)}
h1{font-size:32px} h2{font-size:22px} h3{font-size:19px}

/* Шапка: біла, тонка лінія знизу; на вузьких екранах меню переноситься */
.top{display:flex;align-items:center;flex-wrap:wrap;gap:6px 16px;
  padding:10px 16px;border-bottom:1px solid var(--border);
  position:sticky;top:0;background:var(--white);z-index:5}
.top .logo{height:26px;display:block}
.top nav{display:flex;flex-wrap:wrap;gap:2px 14px;margin:0 auto}
.top nav a{font-family:var(--font-display);text-transform:uppercase;
  font-size:19px;color:var(--navy);padding:4px 2px;
  border-bottom:3px solid transparent}
.top nav a.active{color:var(--blue);border-bottom-color:var(--cyan)}
/* Меню «Ще ▾» (макет): адмін-розділи згорнуті в дропдаун */
.top nav .more{position:relative}
#more-btn{font-family:var(--font-display);text-transform:uppercase;
  font-size:19px;color:var(--navy);padding:4px 2px;background:none;
  border:none;border-bottom:3px solid transparent;cursor:pointer}
#more-btn.active{color:var(--blue);border-bottom-color:var(--cyan)}
.morelist{position:fixed;background:var(--white);
  border:1px solid var(--border);border-radius:var(--r-sm);
  box-shadow:var(--shadow-card);display:flex;flex-direction:column;
  min-width:190px;padding:6px;z-index:9}
.morelist[hidden]{display:none}
.morelist button{font:500 16px/1.2 var(--font-body);text-transform:none;
  text-align:left;padding:12px 14px;border:none;border-radius:10px;
  background:none;cursor:pointer;color:var(--navy);min-height:44px}
.morelist button:hover{background:var(--surface)}
.pill{background:rgba(2,88,201,.10);color:var(--blue);border-radius:999px;
  border:1px solid rgba(2,88,201,.22);
  font:700 12px/1 var(--font-body);padding:4px 10px;vertical-align:middle}

main{max-width:1160px;margin:0 auto;padding:14px 20px 88px}
/* Дві колонки на широких екранах (макет): «Сьогодні», картка клієнта.
   min-width:0 на дітях — грид-трек 1fr не стискається нижче min-content
   свого вмісту без явного перевизначення (класична грід-«роздувка»);
   nowrap-ім'я .qrow2 .who .nm (нижче) інакше тягне трек до довжини
   найдовшого імені й ламає мобільну ширину. */
.cols{display:grid;grid-template-columns:1fr;gap:0 26px}
.cols>*{min-width:0}
@media (min-width:980px){.cols.two{grid-template-columns:1fr 1fr}}
/* Телефон (одна колонка): «Сьогодні» — блоки в робочому порядку оператора:
   пропущені → останні дзвінки → оформлені сьогодні → кому подзвонити → сплячі.
   display:contents розчиняє колонкові обгортки, order шикує секції.
   На десктопі (≥980px) правило не діє — лишаються дві колонки вище.
   Хвиля В (09.08): десктопна перекладка «Сьогодні» (ліва зона —
   пропущені+останні дзвінки, права — оформлені→кому подзвонити→сплячі)
   вирівняла порядок КОЛОНОК під цей самий телефонний порядок — правило
   тут лишилось без змін, лише підтверджено новим тестом. */
@media (max-width:979px){
  .today-cols>div{display:contents}
  /* display:contents розчиняє .today-cols>div — САМЕ ЙОГО ДІТИ (.tsec-
     секції) стають справжніми грід-елементами .cols тут-нижче, не сам
     div. Базове .cols>*{min-width:0} вище цілить у div за DOM-селектором
     і після розчинення фізично не дотягується до нового грід-елемента
     (хто є грід-елементом вирішує layout, не DOM) — той самий блокуючий
     min-content, що й вище, лише на рівень глибше. Без цього рядка
     живий вимір «Сьогодні» на 390px давав scrollWidth 490 (фінальне
     рев'ю Хвилі Д). */
  .today-cols>div>*{min-width:0}
  .today-cols .t-missed{order:1}
  .today-cols .t-recent{order:2}
  .today-cols .t-orders{order:3}
  .today-cols .t-whom{order:4}
  .today-cols .t-sleeping{order:5}
}
/* Рядок заголовка з діями праворуч */
.h-row{display:flex;align-items:center;gap:8px 14px;flex-wrap:wrap;
  margin:6px 0 8px}
.h-row h1{margin-right:auto}
.seeall{font:700 14px/1 var(--font-body);text-transform:none;
  letter-spacing:0;margin-left:8px}
.badge.mut{background:var(--surface);border-color:var(--border);
  color:var(--muted)}

/* Кнопки-пігулки: primary синій з м'яким світінням */
.btn{font:700 16px/1 var(--font-body);border:1.5px solid var(--blue);
  border-radius:999px;padding:12px 20px;cursor:pointer;
  background:var(--white);color:var(--blue);min-height:44px;
  transition:background .12s,box-shadow .12s,border-color .12s}
.btn:hover{background:rgba(2,88,201,.06)}
.btn.primary{background:var(--blue);color:var(--white);border-color:var(--blue);
  box-shadow:var(--shadow-brand)}
.btn.primary:hover{background:var(--blue-600);border-color:var(--blue-600)}
.btn.primary:active{background:var(--blue-700);border-color:var(--blue-700)}
/* рамка була --border #DBE7F5 — на сонці ghost-кнопки зливалися з фоном */
.btn.ghost{border-color:rgba(90,106,140,.55);color:var(--navy);
  background:var(--white)}
.btn.ghost:hover{background:var(--surface)}
/* Небезпечна дія (підтвердження скасування/виходу) — червона суцільна */
.btn.danger{background:var(--danger);color:var(--white);
  border-color:var(--danger)}
.btn.danger:hover{background:#a01818;border-color:#a01818}
/* .ib (Хвиля відповідності макету, Задача 3): іконка-кнопка БЕЗ .btn —
   без цього розширення .od-edit у стані завантаження (renderOrdersDay)
   лишалась би без візуального фідбеку disabled. */
.btn:disabled,.ib:disabled{opacity:.5;box-shadow:none}
/* .small був 36px — менше палечного мінімуму 44px, а саме ним зроблені
   головні робочі кнопки рядків (CRM активно живе на планшеті/телефоні) */
.btn.small{padding:10px 16px;min-height:44px;font-size:14px}
/* М'який синій тінт головної дії рядка (макет .btn.tinted) — бордер
   лишається синій, успадкований від .btn, тінт лише додає фон */
.btn.tinted{background:rgba(2,88,201,.08)}
/* Хвиля Д, Задача 4: фірмові line-іконки дій (icSvg у app.js) —
   БАЗОВО сховані, мобільний/планшет бачать чистий текст кнопки, як і
   раніше. Показ — лише у щільному медіа-блоці нижче (dense-грід,
   pointer:fine): миша+великий екран мають простір під іконку поряд з
   текстом, дотикові тач-зони — ні. */
.btn .ic-svg{display:none}
/* фокус клавіатури — синя рамка (як в адмінці сайту). #more-btn — теж
   сюди: це <button> БЕЗ класу .btn, тож без явного правила фокус лишався
   б системним чорним замість фірмового синього */
.btn:focus-visible,.chip:focus-visible,a:focus-visible,
.qty button:focus-visible,#more-btn:focus-visible{outline:2px solid var(--blue);
  outline-offset:2px}

/* Пошук і фільтри */
.search{width:100%;font:400 17px/1.2 var(--font-body);color:var(--navy);
  border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:13px 16px;margin:8px 0 12px}
.search:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.chip{border:1px solid var(--border);border-radius:999px;background:var(--white);
  color:var(--navy);font:500 14px/1 var(--font-body);padding:8px 14px;
  cursor:pointer}
.chip.active{background:var(--blue);border-color:var(--blue);
  color:var(--white)}
/* Великий чип (макет .chip.big) — вибір способу оплати: від нього
   залежить каса, а тиснуть його водії в рукавицях */
.chip.big,.pay-switch .chip{min-height:44px;padding:12px 18px;
  font-size:15px;font-weight:700}
/* Рядок позиції у формі доставки (макет): назва зверху, керування під нею */
.pick{margin:10px 0}
.pick-nm{font-weight:700;margin-bottom:6px}
.pick-ctl{display:flex;flex-wrap:nowrap;align-items:center;gap:10px}

/* Список клієнтів — білі картки на поверхні */
.rows{display:flex;flex-direction:column;gap:10px}
.row{display:block;border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--white);padding:12px 14px;color:var(--navy)}
.row:active{background:var(--surface)}
.row .nm{font-weight:700}
.row .sub{font-size:14px;color:var(--muted);margin-top:3px}
.row .meta{font-size:14px;color:var(--blue);margin-top:3px}
/* Комірки рядка клієнтів (Хвиля Б): базово — стек, як старі div-рядки;
   таблицею їх розкладає лише щільний режим нижче */
.crow .c-nm,.crow .c-ph,.crow .c-addr,.crow .c-meta,.crow .c-debt{display:block}
/* Рядок став <div data-cid> замість <a href> (Хвиля макета, Задача 2 —
   місце під кнопки дій c-acts, той самий прийом, що .odrow нижче): курсор
   раніше давав браузер сам (посилання), тепер — явно, на БУДЬ-ЯКому
   екрані (не лише dense), інакше миша на вузькому вікні з планшета
   втратила б підказку клікабельності. */
.row.crow[data-cid]{cursor:pointer}
/* Нові dense-only елементи рядка клієнтів (item 2/3, патерн .ic-svg):
   у DOM завжди, база ховає — dense-медіа нижче показує. Шапка колонок
   (.chead) — той самий прийом, що .callhead вище. */
.chead{display:none}
.crow .ph-first,.crow .ph-more{display:none}
.crow .nn-badge{display:none}
.crow .nm-fallback{display:none}
.crow .c-last,.crow .c-cycle,.crow .c-acts{display:none}
.crow .c-debt .d-amt,.crow .c-debt .dash{display:none}
/* Бейджі — м'які тінт-пігулки за семантикою */
.badge{display:inline-block;border-radius:999px;border:1px solid;
  font:700 12px/1.4 var(--font-body);padding:2px 9px;margin-left:6px;
  vertical-align:1px}
.badge.review{background:var(--warn-bg);border-color:var(--warn-bd);
  color:var(--warn)}
.badge.b2b{background:rgba(2,88,201,.08);border-color:rgba(2,88,201,.28);
  color:var(--blue)}
.badge.spam{background:var(--danger-bg);border-color:var(--danger-bd);
  color:var(--danger)}
/* Аліаси бейджів за макетом: warn/ok/danger/blue — семантичні пігулки */
.badge.warn{background:var(--warn-bg);border-color:var(--warn-bd);
  color:var(--warn)}
.badge.ok{background:var(--ok-bg);border-color:var(--ok-bd);color:var(--ok)}
.badge.danger{background:var(--danger-bg);border-color:var(--danger-bd);
  color:var(--danger)}
.badge.blue{background:rgba(2,88,201,.08);border-color:rgba(2,88,201,.28);
  color:var(--blue)}
/* Кольоровий стан замовлення біля імені (макет .st):
   q черга · a на машині · d доставлено · c скасовано */
.st{font-weight:700;white-space:nowrap}
.st.q{color:var(--muted)} .st.a{color:var(--blue)}
.st.d{color:var(--ok)} .st.c{color:var(--danger)}
/* Комірки рядка «Замовлення» (Хвиля Г1 Задача 2, той самий урок Хвилі Б,
   що .crow/.c-*): база — стек, dense-грід — лише в медіа-блоці нижче.
   Клікабельний курсор — лише коли рядок реально веде в картку (data-cid
   з'являється, коли API віддає client_id — тепер завжди, дофікс сервера
   3eeb83e; JS лишився умовним про всяк випадок, курсор іде за тим самим
   атрибутом). .row.odrow[data-cid] (0-3-0), НЕ просто .odrow[data-cid]
   (0-2-0) — та ж специфічність, що й .row.plain нижче: без зайвого
   класу порядок правил у файлі міг би тихо віддати перемогу
   cursor:default. */
.odrow .od-time,.odrow .od-client,.odrow .od-items,.odrow .od-sum,.odrow .od-pay,.odrow .od-state{display:block}
/* .od-time лишається порожнім лише коли й ordered_time — порожній рядок
   (у БД немає ordered_at; delivered_at/cancelled_at/ordered_time — той
   ланцюжок фолбеків у JS, дофікс сервера 3eeb83e) — на мобільному
   .od-time ПЕРШИЙ рядок картки, самотнє порожнє місце перед іменем
   виглядало б глюком (той самий прийом, що .crow .c-debt:empty вище). */
.odrow .od-time:empty{display:none}
.row.odrow[data-cid]{cursor:pointer}
/* Хвиля відповідності макету, Задача 3: dense-only розбивка рядка
   «Замовлення» (dual-render, той самий прийом, що .orow2/.stat-full —
   base лишає СТАРУ комбіновану подачу без змін, нове в DOM завжди,
   база ховає): .od-name/.od-addr — ім'я+адреса ОКРЕМИМИ рядками
   (item 2, замість «Ім'я, Адреса» через кому); .od-time-meta —
   джерело+вікно доставки під ЧАС; .od-cancel-meta — «скасовано …» у
   СТАН (та сама інформація, що metaBits, лише інше місце в dense).
   .od-acts — іконки дій кінця рядка (item 1), заміна .trow лише dense. */
.od-name,.od-addr,.od-time-meta,.od-cancel-meta,.od-acts{display:none}
/* Фікс-раунд (IMPORTANT): orderPaymentHtml() (бейджі оплати) — dense-only
   тепер, база лишає СТАРИЙ інлайновий текст (.pay-text) без змін —
   global constraint «мобільний/base недоторканний» (окреме правило,
   не долучене до групи вище, щоб не ламати підрядок
   ".od-acts{display:none}", на який спирається сусідній CSS-тест). */
.od-pay-badges{display:none}
/* Плашки попереджень (макет .alert): warn амбер, danger червона,
   перша кнопка притиснута праворуч */
.alert{border-radius:var(--r-sm);padding:12px 16px;font-size:14.5px;
  margin:8px 0;display:flex;gap:10px 14px;align-items:center;flex-wrap:wrap}
.alert b{font-weight:700}
.alert.warn{background:var(--warn-bg);border:1px solid var(--warn-bd);
  color:var(--warn)}
.alert.danger{background:var(--danger-bg);border:1px solid var(--danger-bd);
  color:var(--danger)}
.alert.ok{background:var(--ok-bg);border:1px solid var(--ok-bd);
  color:var(--ok)}
.alert .btn{margin-left:auto}
.alert .btn + .btn{margin-left:0}
.alert .hint{flex-basis:100%;font-size:13.5px}
.pager{display:flex;gap:10px;justify-content:center;margin:16px 0}
.count{color:var(--muted);font-size:14px;margin:4px 0 10px}
/* «Клієнти» (Хвиля макета, Задача 2): лічильник дублюється дрібним
   текстом біля h1 (мокет) — лише dense (нижче), база лишає єдиний
   .count над списком, як був. .list-h1 замінює інлайновий
   margin-right:auto (був у h1 напряму) — інлайн-стиль медіа-запит не
   перебʼє, клас — так. */
.list-h1{margin-right:auto}
#list-pageinfo{display:none}
.chip .nn-cnt{display:none}
.pager .pg-short,.pager .pg-pages,.pager .hint{display:none}

/* Картка клієнта */
.card-head{display:flex;align-items:center;gap:10px;margin:8px 0}
.card-head img{width:34px;height:34px}
.fld{display:block;margin:12px 0}
.fld span{display:block;font:700 14px/1.3 var(--font-body);
  color:var(--navy);margin-bottom:5px}
.fld input,.fld textarea{width:100%;font:400 16px/1.4 var(--font-body);
  color:var(--navy);border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:12px 14px}
.fld input:focus,.fld textarea:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
/* Поле дати (Замовлення/Журнал) — за макетом, не браузерний дефолт.
   type=time (Довідники: тихі години заявок, Задача 7) — те саме правило:
   той самий браузерний віджет, та сама причина не пускати дефолт. */
input[type=date],input[type=time]{border:1px solid var(--border);
  border-radius:var(--r-sm);padding:11px 13px;font:700 15px/1 var(--font-body);
  background:var(--white);color:var(--navy)}
/* Обов'язкове поле і inline-помилка (макет): зірка, червона рамка,
   підказка з'являється лише коли поле позначене .invalid */
.fld .req{color:var(--danger)}
.fld input.invalid{border-color:var(--danger);
  box-shadow:0 0 0 3px rgba(185,28,28,.12)}
.fld .hint-err{display:none;color:var(--danger);
  font:700 13px/1.4 var(--font-body);margin-top:4px}
.fld input.invalid + .hint-err,.fld input.invalid ~ .hint-err{display:block}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 10px}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:0 10px}
.switches{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
.section{border-top:1px solid var(--border);margin-top:20px;padding-top:12px}
/* Хвиля відповідності макету, Задача 7 (Картка клієнта) — нові
   dense-only елементи, база ховає (dual-render, той самий прийом, що
   .hint2/.stat-short вище): суфікс «Повторити останнє», 5-й чіп «Тара»,
   лінк «усі N →», новий заголовок+компактні рядки дзвінків. */
.qa-rep-sum{display:none}
.stat-tare{display:none}
.ord-seeall{display:none}
.cc-new-head{display:none}
.callmini{display:none}
/* Хвиля відповідності макету, Задача 8 (Пульс/Карта/Обдзвін) — нові
   dense-only елементи, база ховає (той самий прийом, що вище): примітка
   під боржниками, іконки дій рядка боржника, дублікат зеленої смуги
   всередині картки графіка, вертикальна dense-легенда карти, однорядковий
   рядок «Без мітки на карті», форматований телефон/повне формулювання
   циклу в обдзвоні. */
.pl-note{display:none}
.debt-acts{display:none}
.pulse-sync-inline{display:none}
.mu-line{display:none}
.obd-phone-fmt{display:none}
.obd-cycle-full{display:none}
/* #map-legend раніше носив inline style="display:contents" — переїхало
   сюди зовнішнім правилом (Задача 8): inline-стиль переміг би dense
   #map-legend{display:none} нижче незалежно від порядку в файлі
   (inline завжди сильніший за specificity від будь-якого селектора в
   stylesheet без !important) — той самий урок, що mapview inline-стилі
   деінде вже вчили уникати. Base-поведінка — та сама, що була. */
#map-legend{display:contents}
#map-legend-dense{display:none}
/* Довідники (Хвиля Г2 Задача 4, макет «Ще»): секції Машини/Водії/Товари/
   Види води — база стовпчик (як досі), 3 колонки лише у щільному режимі
   (та сама дисципліна, що .vgrid/.crow/.odrow нижче: база стекає скрізь,
   dense-грід — лише в медіа-блоці pointer:fine нижче). */
.dir-grid{display:block}
/* Секції «Сьогодні» (макет): заголовок h2 без розділювальної лінії */
.tsec{margin-top:22px}
.cols .tsec:first-child{margin-top:0}
.tsec h2{margin-bottom:8px}
/* Іконки заголовків секцій «Сьогодні» (Хвиля макета, Задача 1, item 7):
   icSvg() перед текстом — лише щільний режим (миша+великий екран мають
   на них місце), база бачить чистий текст заголовка, як і раніше. */
.tsec h2 .ic-svg{display:none}
/* Заголовок «Останні дзвінки» з підказкою праворуч (item 3) — база: як
   був простий h2 (single child), нового hint2/лічильника не видно. */
.hint2{display:none}
.cnt-recent{display:none}
.rhint{display:none}
/* Задача 10, item 3: бейдж-лічильник «Оформлені сьогодні» — dense-only
   (той самий прийом, що .cnt-recent вище), базовий заголовок лишається
   без цифри, як був. */
.cnt-orders{display:none}
.addr{border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--white);padding:10px 12px;margin:8px 0;font-size:15px}
.addr .src{font-size:12px;color:var(--muted)}
.addr .tools{display:flex;gap:6px;margin-top:6px}
/* Stat-тайли — білі, обведені, значення синє */
.stat{display:inline-block;background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:8px 12px;margin:3px 4px 3px 0;
  font-size:14px;color:var(--muted)}
.stat b{font-size:18px;color:var(--blue);font-weight:700}
/* у контейнері .stats (Сьогодні/Пульс/Замовлення) — плитки як у макеті */
.stats .stat{padding:10px 14px}
.stats .stat b{display:block;font-size:21px;line-height:1.2;margin-top:2px}
/* акцентні плитки (макет): «Сплачено» зелене, «Борг» помаранчеве */
.stat.ok b{color:var(--ok)}
.stat small{display:block;font:700 11.5px/1.3 var(--font-body);
  color:var(--warn);margin-top:2px}
/* хвиля В: плитки-цифри «Сьогодні» стали <button> — скидаємо UA-стилі
   кнопки (браузер інакше підставляє свій шрифт/центрування/курсор) */
button.stat{font:inherit;text-align:left;cursor:pointer}
/* Хвиля макета (Задача 1, item 1): підпис плитки «Сьогодні» — два
   варіанти в DOM (.stat-full/.stat-short, патерн .ic-svg) — база лишає
   повний підпис карткою, як було; коротка версія («Замовлень» замість
   «Замовлень сьогодні») вмикається лише у щільному режимі нижче, де
   плитка стає однорядковою пігулкою. */
.stat-short{display:none}
/* короткий cyan-обвід секції, куди скролимо кліком по плитці-цифрі
   (хвиля В, задача 3) — БАЗОВО, не в dense-медіа */
.flash{animation:flash-outline .9s ease-out}
@keyframes flash-outline{
  0%{outline:2px solid var(--cyan);outline-offset:4px;border-radius:var(--r-sm)}
  100%{outline:2px solid transparent;outline-offset:4px}
}
table.hist{width:100%;border-collapse:collapse;font-size:14px}
table.hist td{border-top:1px solid var(--border);padding:10px 12px;
  vertical-align:top}
/* числові колонки (макет): праворуч, табличні цифри */
table.hist td.num,table.hist th.num{text-align:right;
  font-variant-numeric:tabular-nums}
.savebar{position:fixed;left:0;right:0;bottom:0;background:var(--white);
  border-top:1px solid var(--border);padding:10px 14px;display:flex;
  gap:10px;justify-content:center;z-index:6}
/* хвиля Г1, задача 4: плашка з'являється лише при незбережених змінах —
   display:flex вище перебиває браузерний [hidden]{display:none}, тому
   потрібне явне правило (той самий урок, що .login[hidden]) */
.savebar[hidden]{display:none}
.savebar .btn{flex:1;max-width:400px}
.savebar .dirty{align-self:center;font:700 13px/1.2 var(--font-body);
  color:var(--warn)}
.savebar .dirty[hidden]{display:none}
/* Тости — стовпчиком у контейнері #toasts (раніше кожен був fixed на одній
   і тій самій позиції: попередження сервера ховались ПІД «Збережено ✓»);
   помилки червоні і живуть довше — див. toast(msg, kind) в app.js. */
#toasts{position:fixed;top:64px;left:50%;transform:translateX(-50%);
  z-index:9;display:flex;flex-direction:column;gap:8px;align-items:center;
  width:min(92vw,480px);pointer-events:none}
.toast{background:var(--navy);color:var(--white);border-radius:var(--r-sm);
  padding:11px 18px;font-weight:700;box-shadow:var(--shadow-card);
  max-width:100%;pointer-events:auto}
.toast.err{background:var(--danger);color:var(--white)}

/* Об'єднання */
.mergecard{border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--white);padding:14px;margin:12px 0}
.mergecard .why{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:9px 11px;font-size:14px;margin-bottom:10px}
.mergecard .ph{border-top:1px solid var(--border);padding:9px 2px}
.mbtns{display:flex;gap:8px;margin-top:10px}
.mbtns .btn{flex:1;min-width:0;padding:12px 8px;font-size:15px}

/* Порожній стан з патерном мінералів */
.empty{text-align:center;color:var(--muted);padding:30px 10px}
.empty .tiles{display:flex;gap:6px;justify-content:center;opacity:.14;
  margin-bottom:12px}
.empty .tiles img{width:44px;height:44px}

/* Вхід */
.login[hidden]{display:none}
.login{position:fixed;inset:0;background:var(--blue);display:flex;
  align-items:center;justify-content:center;z-index:20;padding:16px}
.login-card{background:var(--white);border-radius:28px;padding:26px;
  width:100%;max-width:360px;display:flex;flex-direction:column;gap:12px;
  box-shadow:var(--shadow-card)}
.login-card img{height:30px;align-self:center}
.login-card h1{text-align:center;color:var(--blue)}
.login-card label{font:700 14px/1.3 var(--font-body);color:var(--navy)}
.login-card input{width:100%;margin-top:5px;font:400 17px/1.2
  var(--font-body);border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:13px 14px}
.login-card input:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
/* Смуга плиток-мінералів над заголовком картки входу (бренд-вигляд
   макета, той самий прийом, що .pattern-strip у Пульсі) — суто
   декоративна, тому img-и без alt-тексту. Правило стоїть ПІСЛЯ
   .login-card img (та сама специфічність 0-1-1) — інакше 30px/без
   border-radius звідти тихо перебило б розмір плиток. */
.login-tiles{display:flex;gap:6px;margin:0 0 4px;opacity:.85;
  justify-content:center}
.login-tiles img{width:28px;height:28px;border-radius:6px}
.err{color:var(--danger);font-weight:700;text-align:center}

/* «Сьогодні» */
.src{font-size:12px;color:var(--muted)}
.syncbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:6px 0 12px}
/* Водій: сума до оплати — ГОЛОВНА цифра на точці (макет): «Взяти:» темне
   18px, помаранчева лише сума зі способом (.debt) */
.dr-pay{font:700 18px/1.3 var(--font-body);color:var(--navy);margin-top:5px}
.dr-pay .debt{color:var(--warn)}
/* Задача 10, item 4: борг у боржниках Пульса — амбер+«грн» (мокет:
   «1 590 грн»), той самий клас .debt, що водій/оплата вище, свій скоуп
   (.debtrow) — не дублюємо декларацію, лише додаємо новий контекст.
   Таблиця боржників base-видима (не dense-only synthesized grid, як
   .crow/.odrow) — колір/формат мають бути на будь-якому екрані. */
.debtrow .debt{color:var(--warn);font-weight:700}
/* Позиції точки — окремий темний рядок (макет), клієнт/нотатка — тихіше */
.dr-items{font-size:15px;color:var(--navy);margin-top:5px}
.dr-meta{font-size:14px;color:var(--muted);margin-top:3px}
/* Липкий банер «Немає зв'язку» (макет): [hidden] мусить перемагати flex */
.offline{position:sticky;top:0;z-index:3;background:var(--warn-bg);
  border:1px solid var(--warn-bd);color:var(--warn);
  border-radius:var(--r-sm);padding:10px 14px;font-weight:700;
  font-size:14px;margin-bottom:10px;display:flex;gap:10px;
  align-items:center}
.offline[hidden]{display:none}
.offline .btn{margin-left:auto;min-height:36px;padding:8px 14px}
/* Іконка в кнопці (водій: Дзвінок/Їхати) */
.btn .ic{width:18px;height:18px;vertical-align:-3px;margin-right:6px}
#cash-adjust-btn{white-space:nowrap}
/* Номер точки: у списку і на міні-карті — той самий (Ф11) */
.dr-num{display:inline-flex;width:26px;height:26px;border-radius:50%;
  background:var(--blue);color:var(--white);font:700 14px/1 var(--font-body);
  align-items:center;justify-content:center;margin-right:8px;
  vertical-align:2px;flex:none}
.dr-map-num{display:flex;width:28px;height:28px;border-radius:50%;
  background:var(--blue);color:var(--white);font:700 14px/1 var(--font-body);
  align-items:center;justify-content:center;border:2px solid var(--white);
  box-shadow:0 1px 4px rgba(5,14,55,.35)}
.dr-map-num.done{background:var(--ok)}

/* Міні-карта водія (Задача 8) — лише його точки, під списком адрес */
#drivermap{height:40vh;min-height:260px;border:1px solid var(--border);
  border-radius:16px;margin-top:12px}
/* Маркер свого авто на мапі водія — емодзі без стандартної рамки Leaflet */
.car-marker{background:none;border:none;font-size:24px;line-height:30px;
  text-align:center;filter:drop-shadow(0 1px 2px rgba(0,0,0,.45))}
.trow{display:flex;flex-wrap:wrap;gap:6px;align-items:center;
  margin-top:8px}
/* 16px — щоб iPhone не стрибав авто-зумом при фокусі */
.note-input{flex:1;min-width:130px;font:400 16px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:10px 12px}
.note-input:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.row.plain{cursor:default}
/* Банер-лейбл «Пропущений без відповіді:» (Хвиля макета, Задача 1, item
   2) — dense-only: база лишає окрему секцію з h2 «Пропущені дзвінки»
   (макет її не має, тому лейбл живе В КОЖНОМУ рядку, повношириним
   банером під плитками у щільному режимі). */
.miss-lbl{display:none}
/* Напрям дзвінка словом (макет власника 09.08, Хвиля В): бейдж-пігулка
   з текстом замість самої стрілки — раніше в .row.overdue стрілка була
   ледь помітною, кольору імені бракувало сенсу без підпису поруч. */
.dirb{display:inline-flex;align-items:center;gap:6px;border-radius:999px;
  font:700 12.5px/1 var(--font-body);padding:6px 12px;border:1px solid;
  white-space:nowrap}
.dirb.in{background:var(--ok-bg);color:var(--ok);border-color:var(--ok-bd)}
.dirb.out{background:rgba(2,88,201,.08);color:var(--blue);
  border-color:rgba(2,88,201,.28)}
.dirb.miss{background:var(--danger-bg);color:var(--danger);
  border-color:var(--danger-bd)}
/* Легасі-дзвінки без збігу в calls_sync (Задача 7, картка клієнта) —
   напрям невідомий, нейтральний варіант тим самим кольором, що .badge.mut. */
.dirb.unk{background:var(--surface);color:var(--muted);
  border-color:var(--border)}
/* Пропущений дзвінок у «Останніх» — червонуватий фон рядка (макет),
   видно з першого погляду, не читаючи «Результат». */
.row.missrow{background:var(--danger-bg);border-color:var(--danger-bd)}
/* Комірки рядка дзвінка (Хвиля В, той самий урок Хвилі Б, що .crow/.c-*
   у «Клієнтах»): база — стек, як старий вільний row; таблицею їх
   розкладає лише щільний режим нижче. cc-dur (Хвиля макета, Задача 1,
   item 3) повернуто: today.recent_calls тепер віддає billsec, тире
   більше не вічне — «Розмова» рахує м:сс. */
.callrow2 .cc-dir,.callrow2 .cc-who,.callrow2 .cc-time,.callrow2 .cc-dur,.callrow2 .cc-res,.callrow2 .cc-acts{display:block}
.callrow2 .cc-dir{margin-bottom:6px}
.callrow2 .cc-time,.callrow2 .cc-dur,.callrow2 .cc-res{margin-top:4px;
  color:var(--muted);font-size:13px}
.callrow2 .cc-acts{margin-top:8px}
/* Шапка колонок таблиці (item 3) і однорядковий реєстр «Оформлені
   сьогодні» (item 4) — обидва dense-only (нові елементи макета, база
   без змін: перший — зайвий на стеку карток, другий дублює .nm/.sub). */
.callhead{display:none}
.orow2{display:none}
.ord-more{display:none}
/* Задача 11 (скріншоти власника 11.08): ціна поряд з іменем (.qprice) і
   футер-лінки картки «Кому подзвонити» (.whom-foot) — обидва нові
   dense-only елементи макета, той самий прийом, що .orow2/.ord-more
   вище (база лишає старий вигляд: без ціни в компакт-рядку, старий
   .trow з кнопками-«Усі N»/«▶ Обдзвін» замість цього футера). */
.qprice{display:none}
.whom-foot{display:none}
/* Компактний рядок «Кому подзвонити» (топ-5, макет): ім'я+підрядок зліва,
   кнопка дзвінка справа — однорядковий flex, стек тут не потрібен (не
   багатоколонкова таблиця, як callrow2). */
.qrow2{display:flex;align-items:center;gap:10px}
.qrow2 .who{min-width:0;flex:1}
.qrow2 .who .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Міні-п'ятірка сплячих (Хвиля Д, Задача 3): дві дії замість однієї —
   кнопки в .trow (наявний клас, flex-wrap:wrap рятує вузький екран, дії
   переносяться під ім'я замість обрізання тексту). .trow тут — ЕЛЕМЕНТ
   рядка .qrow2, не блок під .nm/.sub (як у clientRow) — власний
   margin-top:8px там зайвий, зсуває кнопки нижче центру рядка. */
.qrow2 .trow{margin-top:0}
/* Вільний набір «Подзвонити на номер» (запит Анатолія 20.07) — компактний
   блок угорі вкладки, над списками. */
.freedial{padding-top:6px}
.fd-label{font:700 14px/1.3 var(--font-body);color:var(--navy);
  margin-bottom:6px}
.fd-row{display:flex;gap:8px;flex-wrap:wrap}
.fd-row input{flex:1;min-width:140px;font:400 16px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:12px 14px}
.fd-row input:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}

/* Машини */
.vcard{border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--white);padding:14px;margin:12px 0}
.vdot{display:inline-block;width:12px;height:12px;border-radius:50%;
  margin-right:7px;vertical-align:1px}
.vhead{display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;gap:6px}
.vstock{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0}
.vstock .stat b{font-size:20px}
/* Картки авто (Хвиля Г1 Задача 3): база — стек (кожна картка на всю
   ширину, як і раніше), сітка 2-3+ колонки — лише у щільному режимі
   (той самий урок Хвилі Б, що .crow/.odrow/.callrow2: база стекає
   скрізь, dense-грід — лише @media (min-width:1200px) and
   (pointer:fine) нижче). */
.vgrid{display:block}
/* Список вибору машини в черзі «Не розподілені» (Задача 3): одна кнопка
   «→ Обрати машину ▾» — .ddlist випадає під нею (position:absolute від
   .dd), закривається кліком поза ним і Esc (окремий слухач у app.js
   біля viewFleet — той самий принцип, що #more-list, БЕЗ
   getBoundingClientRect, бо рядок черги в звичайному потоці сторінки). */
.dd{position:relative;display:inline-block}
.ddlist{position:absolute;top:calc(100% + 6px);left:0;z-index:6;
  background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-sm);box-shadow:var(--shadow-card);
  min-width:230px;padding:6px;display:flex;flex-direction:column}
.ddlist[hidden]{display:none}
.ddlist button{display:flex;align-items:center;gap:8px;width:100%;
  text-align:left;font:500 15px/1.3 var(--font-body);text-transform:none;
  color:var(--navy);background:none;border:none;border-radius:10px;
  padding:10px 12px;cursor:pointer;min-height:40px}
.ddlist button:hover{background:var(--surface)}
/* Порожні авто (без водія й без адрес на сьогодні) — згорнуті в один
   спільний рядок (Задача 3): пунктирна рамка відрізняє його від .vcard. */
.idle-row{display:flex;align-items:center;gap:6px 10px;flex-wrap:wrap;
  border:1px dashed var(--border);border-radius:var(--r-sm);
  padding:10px 14px;margin:10px 0;font-size:14px;color:var(--muted)}
.idle-row b{color:var(--navy);font-weight:700}
.idle-row .f-idle-toggle{margin-left:auto}
.qty{display:inline-flex;align-items:center;gap:6px}
.qty button{width:44px;height:44px;border-radius:12px;border:1px solid
  var(--border);background:var(--white);color:var(--blue);font:700 20px/1
  var(--font-body);cursor:pointer}
.qty button:hover{background:var(--surface)}
.qty input{width:56px;text-align:center;font:700 16px/1 var(--font-body);
  border:1px solid var(--border);border-radius:12px;padding:8px 4px;
  background:var(--white);color:var(--navy)}

/* Степери водія у формі «Доставлено» (Wave4 T4, спека §4) — більші тап-зони
   (~44px) за операторський .qty (38px): рукавиці/мороз. .dl-row — рядок
   водійського деліверу (кнопка ✕ прибирає рядок ПОВНІСТЮ; операторська
   форма кладе той самий ✕ у наявний .trow, окремого класу не потребує). */
.qty.big button{width:44px;height:44px;font-size:22px}
/* Рядок доставки водія (фікс розмітки 20.07): назва — ОКРЕМИМ рядком зверху
   (щоб не тіснилась у вузьку колонку на телефоні); під нею керування
   (ціна · −/кільк/+ · ✕) одним рядком з переносом за потреби. */
.dl-row{display:block}
.dl-name{font-weight:700;margin-bottom:8px}
.dl-controls{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.dl-controls .dl-remove{margin-left:auto}
/* «Порожні забрали» зі степером −/+ (запит 20.07): поле розтягується на всю
   ширину між кнопками (перекриваємо вузьке .qty input=56px). */
.empties-row{display:flex;flex-wrap:nowrap;align-items:center;width:100%;
  margin-top:4px}
.empties-row .dl-empty{flex:1;min-width:0;width:auto;margin:0 8px;
  font:700 20px/1 var(--font-body);text-align:center;color:var(--navy);
  border:1px solid var(--border);border-radius:12px;background:var(--white)}
.orow{border-top:1px solid var(--border);padding:11px 2px}
/* прострочене в черзі — жовта картка (макет), решта — компактні рядки */
.orow.overdue-q{background:var(--warn-bg);border:1px solid var(--warn-bd);
  border-radius:10px;padding:11px 10px}
/* Хвиля відповідності макету, Задача 5: нові dense-only елементи (item
   1/2/4) — завжди в DOM, база ховає (dual-render, той самий прийом, що
   .od-name/.od-addr/.od-acts Задачі 3). .fleet-chips — обгортка
   РОЗЧИНЕНА на базі (display:contents, той самий трюк, що .today-cols
   .today-col-l Задачі 1): «Звіт по готівці (всі)» лишається прямим
   flex-айтемом .h-row, як і був, лише тепер за одну обгортку глибше в
   DOM — порядок/вигляд бази не змінюється. */
.fleet-chips{display:contents}
.fleet-chips .stat,#fleetmap-toggle-chip{display:none}
/* item 2: нові комірки таблиці «Не розподілені» — стара картка-рядок
   (<b>, .sub, .src, .trow) лишається базовою формою без змін. */
.fq-client,.fq-items,.fq-sum,.fq-when,.fq-machine,.fq-acts{display:none}
/* item 4: dense-only однорядковий запис замовлення в картці авто +
   hover-іконки дій — стара форма (.vorow-old, текст-гроші, завжди
   видимі кнопки) лишається базовою без змін. */
.vorow2,.v-acts{display:none}
/* Гроші в рядку замовлення (макет): сума жирним, «взяти готівку» warn */
.pay{font:700 15px/1.4 var(--font-body);color:var(--navy)}
.pay .debt{color:var(--warn)}
/* Повношира кнопка-панель «Карта розподілу» (макет) */
.maptoggle{border:1px dashed var(--border);border-radius:var(--r-md);
  background:var(--white);padding:12px 16px;width:100%;text-align:left;
  font:700 15px/1 var(--font-body);color:var(--blue);cursor:pointer;
  min-height:48px}
/* Прострочене в черзі (Ф8): «на вчора», яке забули розподілити */
.row.overdue-q{background:var(--warn-bg);border-color:var(--warn-bd)}
.badge.warn2{background:var(--warn-bg);border-color:var(--warn-bd);
  color:var(--warn)}
.orow .st-queued{color:var(--muted);font-weight:700}
.orow .st-assigned{color:var(--blue);font-weight:700}
.orow .st-delivered{color:var(--ok);font-weight:700}
.orow .st-cancelled{color:var(--danger);font-weight:700}
.inline-form{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-md);padding:12px;margin:8px 0}

/* Каса водія (Cash T4) — рядок балансу + видати/прийняти/коригувати/звіт
   у картці авто (Машини) і на /driver; форми самі реюзають .inline-form/
   .trow/.fld/.note-input — тут лише компактна обгортка-відступ. */
.cash-row{border-top:1px solid var(--border);margin-top:10px;padding-top:10px}

/* Останні замовлення в формі «Нове замовлення» + «Повторити» (запит
   Анатолія 20.07) — компактний список над пікером позицій. */
.of-recent{margin:8px 0}
.of-recent-row{justify-content:space-between}

/* Товари під тоглом itemsPicker (Wave3 T3) — компактність після імпорту
   каталогу товарів; .hidden — узагальнений утилітарний клас (без <details>,
   стиль проєкту). */
.hidden{display:none}
.items-toggle{margin:6px 0 2px}

/* Ціна по рядках itemsPicker (Wave4 T3) — вузьке поле поряд зі степером,
   не заважає на мобільній ширині. 16px: менший шрифт змушував iPhone
   стрибати авто-зумом при фокусі. */
.pick-price{width:78px;flex:0 0 78px;text-align:center;
  font:700 16px/1 var(--font-body);color:var(--navy);border:1px solid
  var(--border);border-radius:12px;padding:8px 4px;background:var(--white)}
.pick-price.invalid{border-color:var(--danger);
  box-shadow:0 0 0 3px rgba(185,28,28,.12)}
.pick-price:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}

/* Оплата (Wave4 T3) — блок у формі редагування/фактичної доставки; перемикач
   методу — рядок чипів, той самий стиль, що фільтри списку (.chip). */
.paybox{margin-top:14px}
.pay-switch{margin-top:6px}

/* Баланс клієнта (Wave4 T3, спека §1) — амбер борг / зелена переплата. */
.balance{display:inline-block;font-weight:700;padding:8px 14px;
  border-radius:var(--r-sm);margin:8px 0}
.balance.debt{background:var(--warn-bg);border:1px solid var(--warn-bd);
  color:var(--warn)}
.balance.credit{background:var(--ok-bg);border:1px solid var(--ok-bd);
  color:var(--ok)}

/* Довідники */
.dir-add{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
/* «+ Додати» (Хвиля відповідності макету, Задача 7): кнопка-тогл форми
   додавання — dense-only (база й так завжди показує .dir-add, кнопка їй
   не потрібна). SIP-лінії/сповіщення (dirSection її не використовує —
   свій html без .dir-sechead) її не отримують — keep-list. */
.dir-add-toggle{display:none}
.dir-name{flex:1;min-width:150px;font:400 15px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:11px 13px;background:var(--white)}
.dir-name:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.dir-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.dir-name-cell{flex:1;min-width:120px;font-weight:700;cursor:pointer}
.dir-name-cell.editing{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.dir-rn-input{flex:1;min-width:120px;font:400 15px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--blue);border-radius:var(--r-sm);
  padding:10px 12px;background:var(--white)}
.dir-rn-input:focus{outline:none;box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.dir-tools{display:flex;gap:6px;flex-wrap:wrap}
.dir-row.inactive{opacity:.5}
.dir-add .dir-price{flex:0 0 110px;min-width:90px}
.dir-price-chip{cursor:pointer}
.dir-price-edit{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.dir-price-input{width:100px;font:400 15px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--blue);border-radius:var(--r-sm);
  padding:10px 12px;background:var(--white)}
.dir-price-input:focus{outline:none;box-shadow:0 0 0 3px rgba(2,88,201,.15)}

/* Журнал (спека 2026-07-20, Task 4) — компактна стрічка подій: кольорова
   риска зліва позначає тип (order/edit/cash/vehicle), рядок з client_id
   клікабельний (веде на картку клієнта). #j-daynav ховається БЕЗ власного
   display-правила (лише вкладений .trow його задає) — інакше [hidden]
   програвав би author-стилю, як у .login (див. test_static_css.py). */
.jrow{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;
  border:1px solid var(--border);border-left:4px solid var(--muted);
  border-radius:var(--r-sm);background:var(--white);
  padding:10px 13px;margin:6px 0;font-size:14.5px}
.jrow[data-client]{cursor:pointer}
.jrow[data-client]:active{background:var(--surface)}
.jtime{font-weight:700;color:var(--muted);min-width:44px;
  font-variant-numeric:tabular-nums}
.jactor{font-weight:700;color:var(--navy)}
.jrow .jk{font:700 11px/1.5 var(--font-body);text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted);border:1px solid var(--border);
  border-radius:999px;padding:1px 8px}
.jtext{color:var(--navy)}
.jrow-order{border-left-color:var(--blue)}
.jrow-edit{border-left-color:var(--muted)}
.jrow-cash{border-left-color:var(--ok)}
.jrow-vehicle{border-left-color:var(--warn)}
/* Кінцевий кольоровий бейдж типу (мокет, Хвиля макета Задача 6) — лише
   dense (нижче); на базі лишається старий .jk зліва (без змін). */
.jrow .jbadge{display:none}
/* Шапка колонок (мокет .worktable thead, Задача 6) — DOM-рядок,
   dense-only. .jrow (вище) задає display:flex+картку (0-1-0), пізніше у
   файлі за generic .chead{display:none} (тієї ж специфічності) — без
   явного .jrow.chead (0-2-0) шапка показалась би карткою на мобільному. */
.jrow.chead{display:none}
#j-actor{width:100%;font:400 15px/1.2 var(--font-body);color:var(--navy);
  border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:11px 13px;margin:0 0 12px}
#j-actor:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
/* margin-bottom 6px (не 12px) — той самий візуальний відступ, що раніше
   давав inline style="margin-bottom:6px" на .trow (app.js); винесено в
   клас, бо dense (нижче) має право скинути лише bottom, а inline-стиль
   CSS не перебʼє. Обчислене значення на базі не змінилось. */
#j-daynav .trow{margin:2px 0 6px}
#j-date{font-weight:700;min-width:110px;text-align:center;
  border:1px solid var(--border);border-radius:var(--r-sm);
  padding:11px 13px;background:var(--white);
  font-family:var(--font-body);font-size:15px}

@media (max-width:560px){
  .top{padding:8px 12px}
  .top .logo{height:22px}
  /* меню одним рядком з прокруткою (шапка нижча, тап-зони не тісняться);
     fade праворуч (.top::after) підказує, що далі є ще вкладки */
  .top nav{gap:2px 8px;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .top nav::-webkit-scrollbar{display:none}
  .top nav a{font-size:16px;white-space:nowrap;padding:8px 6px}
  .top::after{content:"";position:absolute;right:0;bottom:0;width:44px;
    height:44px;pointer-events:none;
    background:linear-gradient(90deg,rgba(255,255,255,0),var(--white) 80%)}
  .grid3{grid-template-columns:1fr 1fr}
  h1{font-size:28px}
}
/* Скелетон завантаження (route() ставить на час fetch — раніше екран був
   «мертвий» і оператор клікав ще раз) */
.skelwrap{padding:4px 0}
.skel{border-radius:var(--r-md);border:1px solid var(--border);
  background:linear-gradient(100deg,var(--pale) 40%,var(--surface) 50%,
    var(--pale) 60%);background-size:200% 100%;
  animation:skel 1.1s infinite linear;height:72px;margin:10px 0}
.skel.short{height:40px;max-width:340px}
/* Таблиці історії: обгортка зі своєю прокруткою (довгий рядок більше не
   тягне всю сторінку вбік) + заголовки колонок */
.tablewrap{overflow-x:auto}
table.hist th{font:700 11.5px/1.3 var(--font-body);text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted);text-align:left;padding:6px 4px;
  border-bottom:1px solid var(--border);white-space:nowrap}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
}
@keyframes skel{to{background-position:-200% 0}}

/* Карта — ширша за звичайну сторінку (потребує простору для полотна) */
main:has(#mapwrap){max-width:none;padding-left:16px;padding-right:16px}
#mapwrap{display:flex;flex-direction:column;gap:14px;margin-top:8px}
#bigmap{height:calc(100vh - 190px);min-height:320px;border-radius:var(--r-lg);
  border:1px solid var(--border);overflow:hidden;background:var(--white)}
#bigmap.pin-mode,#fleetmap.pin-mode{cursor:crosshair}
#drivermap.pin-mode{cursor:crosshair}
/* Міні-карта розподілу на вкладці «Машини» — той самий стиль, що #bigmap,
   але нижча (це допоміжний огляд над чергою/машинами, не окрема сторінка) */
#fleetmap{height:45vh;min-height:240px;border-radius:var(--r-lg);
  border:1px solid var(--border);overflow:hidden;background:var(--white);
  margin-top:8px}
#fleet-legend{margin:10px 0 16px}
#mapside{display:flex;flex-direction:column;gap:12px}
.map-banner{background:var(--warn-bg);border:1px solid var(--warn-bd);
  color:var(--warn);border-radius:var(--r-sm);padding:10px 14px;
  font-weight:700;font-size:14px}
.legend{display:flex;flex-wrap:wrap;gap:6px}
.legend-chip{display:inline-flex;align-items:center;gap:6px;
  background:rgba(2,88,201,.08);border:1px solid var(--border);
  border-radius:999px;padding:5px 12px;font:500 13px/1 var(--font-body);
  color:var(--navy)}
.legend-dot{width:10px;height:10px;border-radius:50%;flex:none}
/* Пін-мітка замовлення (макет): крапля з символом усередині */
.pin{position:relative;display:block;width:26px;height:26px;
  border-radius:50% 50% 50% 0;transform:rotate(-45deg);
  border:2px solid var(--white);box-shadow:0 2px 6px rgba(5,14,55,.3)}
.pin i{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;transform:rotate(45deg);
  font:700 12px/1 var(--font-body);color:#fff;font-style:normal}
.map-toggle{display:flex;align-items:center;gap:8px;font:500 14px/1.2
  var(--font-body);color:var(--navy);cursor:pointer}
.map-toggle input{width:18px;height:18px}
/* Іконка авто на карті — біле коло-підложка (читається на будь-якій
   плитці), кольоровий силует фургона всередині (fill — колір машини).
   Назва — лише в title/попапі/легенді, тут написів немає. */
.veh-ico{display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:50%;background:var(--white);
  border:2px solid var(--white);box-shadow:var(--shadow-card)}
.veh-ico svg{width:22px;height:22px;display:block}
.veh-ico.stale{filter:grayscale(1);opacity:.7}

@media (min-width:900px){
  #mapwrap{flex-direction:row;align-items:flex-start}
  #bigmap{flex:1;min-width:0}
  #mapside{flex:0 0 280px;width:280px}
}

/* Телефонія T3: попап вхідного дзвінка — фіксований стек правий-верх,
   поверх усього робочого простору; білі картки в тому ж повітряному
   стилі, що .vcard/.row (рамка+тінь+скруглення), легка поява.
   Фікс-раунд фінального рев'ю Хвилі В: 15 → 55. На 15 попапи ховались
   ПІД #obd/#dlg-back (обидва 50) — під час режиму обдзвону (#obd на
   весь екран) вхідний і пропущений дзвінок ставали повністю невидимими,
   а вхідний дзвінок — найважливіший сигнал (83% замовлень телефоном).
   55 — над #obd/#dlg-back (50), під #phone-panel (60) і #ext-picker
   (61); діапазон (50,60) інакше порожній. Попапи стають і над .login
   (20) — нейтрально: без входу /api/call-events віддає 401, поллер
   мовчить (pollCallEvents: `if (r.ok)` — гілка рендеру попапів просто
   не виконується), lastCallsRaw лишається [], попапів немає фізично. */
#call-popups{position:fixed;top:70px;right:16px;z-index:55;
  display:flex;flex-direction:column;gap:10px;
  width:300px;max-width:calc(100vw - 24px);pointer-events:none}
.call-popup{position:relative;pointer-events:auto;background:var(--white);
  border:1px solid var(--border);border-radius:var(--r-md);
  box-shadow:var(--shadow-card);padding:12px 14px;
  animation:cp-in .18s ease-out}
/* «×» — у правий верхній кут попапа (ревю А3): раніше сидів у ряду
   кнопок cp-actions унизу, губився серед «Картка»/«Передзвонити». */
.call-popup .cp-dismiss{position:absolute;top:8px;right:8px;margin:0}
/* «Пропущений щойно» (Ф6) — червона рамка, щоб не загубився серед карток */
.call-popup.missed{border-color:var(--danger-bd);background:var(--danger-bg)}
.call-popup.missed .cp-head{color:var(--danger)}
@keyframes cp-in{from{opacity:0;transform:translateY(-10px)}
  to{opacity:1;transform:translateY(0)}}
/* «×» (cp-dismiss) absolute, 44px — палечний мінімум, не зменшуємо; тому
   відступаємо текст справа, а не звужуємо кнопку (фінальне рев'ю Хвилі А) */
.call-popup .cp-head{font-weight:700;font-size:15px;padding-right:52px}
.call-popup .cp-addr{font-size:13px;color:var(--muted);margin-top:3px;padding-right:52px}
.call-popup .cp-badges{margin-top:5px}
.call-popup .cp-last{font-size:12px;color:var(--muted);margin-top:5px}
.call-popup .cp-actions{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}

/* Телефони картки клієнта: tel:-лінк + кнопка «Подзвонити через Binotel»
   (.c2c-btn) поруч, той самий трохи менший рядок для кожного номера.
   margin — сюди з інлайн-style="margin:2px 0 6px" (Задача 7): dense
   мусить мати змогу скинути його без !important (той самий урок, що
   #j-daynav .trow у «Журналі», Задача 6). */
.phones{display:flex;flex-wrap:wrap;gap:8px 14px;font-size:15px;
  margin:2px 0 6px}
.ph-item{display:inline-flex;align-items:center;gap:6px}

@media (max-width:560px){
  #call-popups{top:60px;right:8px;left:8px;width:auto;max-width:none}
}

/* Два робочих місця (901/902): чіп обраного внутрішнього номера у шапці
   + міні-вибір поверх усього, коли номерів кілька і вибір ще не збережено
   (localStorage "c2c-ext") або оператор тисне на сам чіп. */
.c2c-ext-chip{cursor:pointer;border:1px solid rgba(2,88,201,.22);
  background:rgba(2,88,201,.10);color:var(--blue);
  font:700 12px/1 var(--font-body);border-radius:999px;padding:8px 12px}
.c2c-ext-chip:hover{background:rgba(2,88,201,.18)}

/* Freedial у шапці (Хвиля макета, Задача 1, item 6): #hdr-dial — dense-
   only чіп (макет узагалі не має блоку .freedial на сторінці, база
   лишає його на місці, як був). Показ — лише у щільному медіа-блоці
   нижче (той самий патерн .ic-svg: база сховано, dense показує). */
#hdr-dial{display:none}
/* Поповер набору — той самий прийом, що #more-list (position:fixed,
   координати рахує JS від getBoundingClientRect кнопки); [hidden]
   мусить перемагати явний display:flex (той самий урок, що .login
   [hidden]/.savebar[hidden]). */
.hdr-dial-pop[hidden]{display:none}
.hdr-dial-pop{position:fixed;background:var(--white);
  border:1px solid var(--border);border-radius:var(--r-sm);
  box-shadow:var(--shadow-card);padding:10px;display:flex;gap:8px;z-index:9}
.hdr-dial-pop input{width:140px;font:400 15px/1.2 var(--font-body);
  color:var(--navy);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:9px 10px}
.hdr-dial-pop input:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}

#ext-picker[hidden]{display:none}
/* Фікс-раунд рев'ю (Хвиля В, Задача 4): пікер робочого місця мусить бути
   НАД будь-яким оверлеєм — без нього дзвінок неможливий (z-index:20 ховав
   пікер ПІД #obd/#dlg-back — «Подзвонити» ставало тихим no-op, доказ
   sandbox-extpicker-under-overlay.png). 61, а не рівно 60 — #phone-panel
   теж стоїть на 60 і йде ПІЗНІШЕ за #ext-picker в index.html, тож рівний
   z-index програв би йому за порядком DOM (той самий клас бага, який щойно
   лагодимо, лише з іншим оверлеєм); 61 гарантує пікер зверху за будь-яких
   обставин, не лише над #obd/#dlg-back (обидва — 50). */
#ext-picker{position:fixed;inset:0;z-index:61;display:flex;
  align-items:center;justify-content:center;background:rgba(5,14,55,.35)}
.ext-picker-box{background:var(--white);border-radius:var(--r-md);
  box-shadow:var(--shadow-card);padding:20px 22px;
  display:flex;flex-direction:column;gap:12px;min-width:220px}
.ext-picker-label{font-weight:700;font-size:15px}
.ext-picker-chips{display:flex;gap:8px;flex-wrap:wrap}

.muted { color: var(--muted); font-size: .9em; }

/* Телефон у браузері (фаза 2) */
#phone-panel {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  background: #fff; border: 1px solid var(--border, #d5e3f1);
  border-radius: 12px; box-shadow: 0 8px 28px rgba(16, 60, 110, .18);
  padding: 14px 16px; min-width: 240px;
}
#phone-panel .ph-head { font-weight: 600; margin-bottom: 6px; }
#phone-panel .ph-peer { font-size: 1.15em; margin-bottom: 4px; }
#phone-panel .ph-who { font-weight: 600; margin-bottom: 8px; }
#phone-panel .ph-crm { display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 10px; }
#phone-panel .ph-timer { float: right; font-variant-numeric: tabular-nums; }
#phone-panel .ph-actions { display: flex; gap: 8px; flex-wrap: wrap; }
#phone-panel .ph-pad {
  display: grid; grid-template-columns: repeat(3, 48px);
  gap: 6px; margin-top: 10px;
}
#phone-chip.ph-ok { border-color: #34a06d; color: #1d7a4f; }
#phone-chip.ph-bad { border-color: #d05252; color: #b03030; }
/* Глушилка вхідних активна — червонуватий чіп, щоб було видно «звук вимкнено» */
#ring-mute-chip.muted-on { background: #fdecec; border-color: #d05252;
  color: #b03030; }

/* Головна кнопка дзвінка — click-to-call (сама обирає браузер чи мобільний
   за перемикачем у шапці); tel:-посилання «З телефону» — фолбек, видимий
   лише на екранах, де tel: реально працює (телефон/планшет). Раніше першою
   стояла мертва на десктопі tel:-кнопка «Подзвонити», а робоча ховалась
   під технічною назвою «☎ Binotel». */
.tel-fallback{display:none}
@media (max-width:700px){.tel-fallback{display:inline-block}}

/* «Пульс» (Ф7): картки і стовпчики бутлів — одна серія бренд-синім,
   «сьогодні» світлішим (день ще триває), підписи лише на максимумі й
   сьогодні (решта — у title при наведенні) */
.chart-card{border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--white);padding:16px;margin:12px 0}
/* заголовок картки — текстовий Fira, НЕ дисплейний капс (макет) */
.chart-card h3{text-transform:none;font-family:var(--font-body);
  font-weight:700;font-size:15px;margin:0 0 2px}
.chart-card .sub{color:var(--muted);font-size:13px;margin-bottom:10px}
/* Смуга бренд-плиток під заголовком «Пульс» (макет) */
.pattern-strip{display:flex;gap:6px;margin:2px 0 12px;opacity:.85}
.pattern-strip img{width:34px;height:34px;border-radius:6px}
/* Діалог підтвердження (макет) — замість системного confirm() */
#dlg-back{position:fixed;inset:0;background:rgba(5,14,55,.38);z-index:50;
  display:flex;align-items:center;justify-content:center;padding:16px}
#dlg-back[hidden]{display:none}
.dlg{background:var(--white);border-radius:var(--r-md);
  box-shadow:var(--shadow-card);padding:22px;max-width:420px;width:100%}
.dlg h3{margin-top:0;text-transform:none;font-family:var(--font-body);
  font-weight:700;font-size:17px;line-height:1.35}
.dlg .sub{color:var(--muted);font-size:14.5px}
.dlg .sub[hidden]{display:none}
.dlg .trow{justify-content:flex-end}
/* Режим обдзвону (Хвиля В, Задача 4): картка по центру — той самий
   патерн, що #dlg-back вище (position:fixed+inset:0+підкладка), лише
   ширша картка з полями клієнта (ім'я/телефон/мета/нотатка/кнопки). */
#obd{position:fixed;inset:0;background:rgba(5,14,55,.45);z-index:50;
  display:flex;align-items:center;justify-content:center;padding:16px}
#obd[hidden]{display:none}
.obd-card{background:var(--white);border-radius:var(--r-lg);
  box-shadow:var(--shadow-card);width:100%;max-width:560px;
  padding:24px 28px}
.obd-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.obd-top h2{font-size:22px}
.obd-prog{margin-left:auto;font:700 13px/1 var(--font-body);
  color:var(--muted)}
.obd-name{font:700 24px/1.2 var(--font-body);margin-top:16px}
.obd-phone{font:700 20px/1.2 var(--font-body);color:var(--blue);
  margin-top:6px}
.obd-meta{color:var(--muted);font-size:14px;margin-top:8px;
  line-height:1.6}
.obd-meta b{color:var(--warn)}
.obd-note{width:100%;font:400 15px/1.3 var(--font-body);
  border:1px solid var(--border);border-radius:var(--r-sm);
  padding:12px 14px;margin-top:14px}
.obd-note:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.obd-btns{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap}
.obd-btns .btn{padding:13px 18px;flex:1;text-align:center}
.obd-skip{display:flex;gap:14px;margin-top:14px;align-items:center;
  font-size:14px}
.obd-hint{font-size:12.5px;color:var(--muted);margin-top:10px}
.bars{display:flex;align-items:flex-end;gap:10px;min-height:150px;
  padding-top:16px}
.bar{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;
  min-width:0}
.bar i{width:100%;max-width:46px;background:var(--blue);
  border-radius:4px 4px 0 0;display:block}
.bar.today i{background:var(--sky)}
.bar .v{font:700 13px/1 var(--font-body);color:var(--navy);
  font-variant-numeric:tabular-nums;min-height:13px}
.bar .d{font:500 12px/1 var(--font-body);color:var(--muted)}
.stats{display:flex;gap:8px;flex-wrap:wrap;margin:8px 0 14px}
/* Підпис рядка плиток (Пульс, хвиля Г2 задача 2): «Сьогодні»/«За 7 днів»
   — без нього однакові підписи плиток («Пропущені без відповіді» тощо)
   у двох рядках не розрізнити */
.stats-label{align-self:center;font-size:13px;font-weight:700;
  color:var(--muted);min-width:70px}
.stat.warn b{color:var(--warn)}
.pulse-ok{background:var(--ok-bg);border:1px solid var(--ok-bd);
  color:var(--ok);border-radius:var(--r-sm);padding:10px 14px;
  font-weight:700;font-size:14px;margin:8px 0}
/* Тара по клієнту (Ф10) — зелений бейдж біля балансу (макет balance ok) */
.balance.tare{background:var(--ok-bg);
  border:1px solid var(--ok-bd);color:var(--ok)}

/* Водій (макет): три головні кнопки рядка однакової ширини */
.dr-btns{display:flex;gap:8px;margin-top:12px}
.dr-btns .btn{flex:1;padding:13px 6px;font-size:16px;text-align:center}

/* ===== СТОРІНКА «НОВЕ ЗАМОВЛЕННЯ» (#/neworder) =====
   Хвиля відповідності макету, Задача 4. Ця сторінка — СПІЛЬНА для всіх
   розмірів (виняток, прописаний у плані хвилі), тож УСІ її правила
   живуть тут, у базовому CSS: у dense-медіа нижче їх свідомо НЕМА.
   Дві колонки дає наявний .cols.two (розходиться від 980px і сам
   складається в одну на телефоні) — власної сітки сторінка не заводить. */
.neworder-head{display:flex;align-items:center;gap:10px 18px;
  flex-wrap:wrap;margin:2px 0 12px}
.pagetitle{margin:0}
/* Смуга клієнта (макет): ім'я, адреса текстом, бейджі, дії праворуч */
.clientstrip{display:flex;gap:8px 18px;align-items:center;flex-wrap:wrap;
  background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-md);padding:12px 18px;margin-bottom:16px}
.clientstrip .n{font-weight:700;font-size:16px}
.clientstrip .s{color:var(--muted);font-size:14px}
.clientstrip .cs-acts{display:flex;gap:8px;flex-wrap:wrap;
  margin-left:auto}
.clientstrip .no-name{font:400 15px/1.4 var(--font-body);color:var(--navy);
  border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);padding:8px 12px;max-width:220px}
/* Текстовий лінк дії («змінити», «+ інші товари ▾») — кнопка, що
   виглядає посиланням: макет уживає саме <a>, але тут це дія, не
   навігація, тож семантика лишається кнопкою. */
.lnk,.lnk-toggle{background:none;border:none;padding:0;cursor:pointer;
  color:var(--blue);font:400 14px/1.4 var(--font-body)}
.lnk:hover,.lnk-toggle:hover{text-decoration:underline}
.lnk-toggle{display:block;padding:11px 16px;font-size:14.5px}
.lnk:focus-visible,.lnk-toggle:focus-visible{outline:2px solid var(--blue);
  outline-offset:2px}
/* Картка-секція (макет .formbox) */
.formbox{background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-md);padding:16px 18px}
.formbox .sechead{display:flex;align-items:center;gap:14px;
  flex-wrap:wrap;margin:0 0 10px}
.formbox .sechead h2{margin:0;font-size:20px}
/* Підпис поля в картці — дрібний сірий капсом (макет), а не темний
   жирний, як у картці клієнта: тут поля другорядні поруч із чіпами. */
.formbox .fld span{font:700 12.5px/1.3 var(--font-body);color:var(--muted);
  text-transform:uppercase;letter-spacing:.04em}
.neworder-cols{align-items:start;margin-bottom:20px}
.no-addrbox{margin-bottom:16px}
.no-addrbox .fld:first-child{margin-top:0}
/* «Що везти»: рядки без внутрішніх відступів картки — суцільний список
   із розділювачами, як у макеті (.itrow). */
.no-items{padding:6px 0 0}
.no-items .sechead{padding:10px 18px 4px}
.no-items .trow{display:flex;align-items:center;gap:12px;
  padding:11px 16px;margin:0;border-top:1px solid var(--border);
  border-radius:0;flex-wrap:nowrap}
.no-items #no-picker>.trow:first-child{border-top:none}
.no-items .items-products{display:contents}
.no-items .items-products.hidden{display:none}
/* «× 180 грн» одним блоком, притиснутим до степера (макет .itrow .price) */
.pick-name{flex:1;min-width:0}
.pick-priced{margin-left:auto;display:inline-flex;align-items:center;
  gap:2px;color:var(--muted);white-space:nowrap}
.pick-mul,.pick-cur{color:var(--muted);white-space:nowrap;font-size:14.5px}
.pick-line{font-weight:700;font-variant-numeric:tabular-nums;
  white-space:nowrap;min-width:86px;text-align:right}
/* Ціна рядка лишається РЕДАГОВАНОЮ (функція Wave4 — макет малює її
   статичним текстом «× 180 грн», але зрізати правку заради пікселів
   не можна): подаємо як текст, рамка проявляється на наведення/фокус. */
/* flex теж перекриваємо: базове .pick-price несе flex:0 0 78px (форма
   редагування), і сам width:42px у флекс-контейнері .pick-priced його не
   переважить — «×» лишався б відірваним від числа. */
.no-items .pick-price{width:42px;flex:0 0 42px;text-align:right;
  border:1px solid transparent;background:none;border-radius:var(--r-sm);
  padding:4px 2px;font:400 14.5px/1.2 var(--font-body);color:var(--muted);
  font-variant-numeric:tabular-nums}
.no-items .pick-price:hover{border-color:var(--border)}
.no-items .pick-price:focus{outline:none;border-color:var(--blue);
  background:var(--white);color:var(--navy);
  box-shadow:0 0 0 3px rgba(2,88,201,.15)}
.no-items .pick-price.invalid{border-color:var(--danger);color:var(--danger)}
.no-items .qty{gap:4px}
.no-items .qty input{width:44px}
/* Підсумок (макет .totalrow) */
.totalrow{display:flex;align-items:baseline;gap:10px;padding:14px 16px;
  border-top:1px solid var(--border);background:var(--surface);
  flex-wrap:wrap}
.totalrow .t{font:400 22px/1 var(--font-display);text-transform:uppercase}
.totalrow .v{font:700 22px/1 var(--font-body);color:var(--blue);
  font-variant-numeric:tabular-nums}
.totalrow .free{font-size:13px;color:var(--ok);font-weight:700}
.totalrow .feehint{font-size:13px;color:var(--muted);font-weight:700}
/* Ряди чіпів «Коли»/«Оплата» + кнопки (макет .quickrow) */
.quickrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center;
  margin-bottom:12px}
.no-side .sechead{margin-top:4px}
.no-date{margin-bottom:12px}
.no-actions{margin-top:16px;margin-bottom:0}
.no-actions .btn.primary{flex:1;padding:14px 8px;font-size:16px;
  justify-content:center;text-align:center}
/* Вузький екран: рядок «Що везти» складається у два поверхи — назва
   зверху, «× ціна»/степер/сума знизу. Одним рядком (як у макеті на
   десктопі) вони не вміщаються в 390px, а горизонтальний пан у цій
   хвилі заборонений: 44px тач-кнопки степера + сума рядка розпирали
   документ до 473px. Це ЄДИНЕ місце сторінки з брейкпоінтом — решта
   розкладки однакова на всіх розмірах. */
@media (max-width:700px){
  .no-items .trow{flex-wrap:wrap;gap:8px 10px}
  .no-items .pick-name{flex:1 1 100%}
  .pick-priced{margin-left:0}
  .pick-line{min-width:0;margin-left:auto}
}

/* ЩІЛЬНИЙ РЕЖИМ — лише великі екрани З МИШЕЮ (ревю 09.08, Хвиля Б).
   Планшет/телефон (coarse pointer) сюди не заходять: їхні 44px тач-зони
   і одноколонкова розкладка лишаються недоторканими. */
@media (min-width:1200px) and (pointer:fine){
  /* Задача 10, item 2: поля 24px на max-width 1720px (виміряно з
     макета computed style на main, top/bottom padding там 16px/260px —
     не чіпаємо, лише left/right), базове 14px 20px 88px лишається під
     1200px і мобільним/планшетом. */
  main{max-width:1720px;padding-left:24px;padding-right:24px}
  /* Задача 10, item 8 (шрифти, питання власника): h1/h2 виміряно на
     мокеті трохи меншими за базові 32px/22px (мокет: 30px/20px) —
     родина/накреслення (Bebas Neue Cyrillic, uppercase) уже збігались
     до цієї задачі, різнились лише px. Дрібна, дешева підгонка тут —
     мобільний/планшет лишаються 32/22 без змін. */
  h1{font-size:30px}
  h2{font-size:20px}
  /* клієнти: рядок стає рядком таблиці (Хвиля макета, Задача 2) — шість
     колонок КЛІЄНТ/ТЕЛЕФОН/АДРЕСА/ОСТАННЯ ПОКУПКА/ЦИКЛ/БОРГ (мокет);
     мета-рядок (c-meta), що ніс ту саму інформацію одним синім рядком,
     ховається — дані переїхали в колонки. position:relative — точка
     відліку для абсолютного оверлею дій (c-acts) нижче, той самий
     прийом, що .callrow2 .cc-acts (Хвиля В). */
  .crow{display:grid;align-items:center;gap:2px 14px;padding:9px 14px;
    position:relative;
    grid-template-columns:minmax(160px,1.3fr) 150px minmax(160px,1.4fr)
      140px 80px 100px}
  .crow .c-addr{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .crow .c-meta{display:none}
  .crow .c-debt{text-align:right}
  .crow .c-last,.crow .c-cycle{display:block;white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis}
  .crow .dash{color:var(--muted)}
  /* ТЕЛЕФОН: перший номер + бейдж «+N» (dual-render — ph-full лишається
     базовим, повним списком номерів, лише для мобільного) */
  .crow .ph-full{display:none}
  .crow .ph-first,.crow .ph-more{display:inline-block}
  /* КЛІЄНТ: порожнє ім'я — показуємо перший номер замість пустого
     рядка (мокет: «+380 95 000 00 04 [без імені]»); base-порожній .nm
     лишається порожнім (як був), dense його ховає і показує фолбек */
  .crow .nm:empty{display:none}
  .crow .nm-fallback{display:inline-block}
  .crow .nn-badge{display:inline-block}
  /* БОРГ: сума помаранчевим (.d-amt) чи «—», пігулка .badge.warn
     («борг N грн») — лише base-варіант, dense її ховає */
  .crow .c-debt .badge{display:none}
  .crow .c-debt .d-amt{display:inline;color:var(--warn);font-weight:700;
    font-variant-numeric:tabular-nums}
  .crow .c-debt .dash{display:inline}
  /* Дії рядка (телефон/+): оверлей праворуч, видимий лише при наведенні
     (мокет .acts) — той самий прийом, що .callrow2 .cc-acts вище. */
  .crow .c-acts{display:flex;opacity:0;transition:opacity .1s;gap:6px;
    position:absolute;right:8px;top:50%;transform:translateY(-50%);
    padding-left:24px;
    background:linear-gradient(90deg,rgba(255,255,255,0),var(--white) 22%)}
  .crow:hover .c-acts{opacity:1}
  /* Кругла іконка-кнопка (мокет .ib) — визначена нижче разом з .odrow
     (Хвиля відповідності макету, Задача 3: селектор РОЗШИРЕНО на
     .odrow .ib, не задубльовано — шукай «.crow .ib,.odrow .ib»). */
  /* Шапка колонок — той самий грід, що .crow (спільний клас, як
     .callrow2.callhead вище), лише текст+рамка знизу */
  .chead{display:grid;border-bottom:1px solid var(--border);
    padding-bottom:6px;margin-bottom:0}
  .chead>span{text-transform:uppercase;font:700 11px/1.3 var(--font-body);
    letter-spacing:.06em;color:var(--muted)}
  /* «Worktable» (item 1, findings.json «Клієнти»): суцільна БІЛА картка
     навколо шапки+рядків+пагінації (мокет .worktable) — окремі картки-
     рядки з проміжками (base .row: рамка+заокруглення+.rows gap:6px)
     мали б зникнути ЛИШЕ тут. Скоуп на #list-results (єдина обгортка,
     лише «Клієнти») — .row/.rows глобальні (карток «Сьогодні» не
     чіпаємо). */
  #list-results{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);overflow:hidden}
  #list-results .rows{gap:0}
  #list-results .row.crow{border:none;border-radius:0;background:none}
  /* тонкий розділювач МІЖ рядками — не перший (той відділяє чейд його
     власним border-bottom) */
  #list-results .row.crow+.row.crow{border-top:1px solid var(--border)}
  /* пагінація — сірий підвал усередині тієї самої картки (мокет .tfoot),
     не окремий блок під нею */
  #list-results .pager{margin:0;padding:11px 14px;
    border-top:1px solid var(--border);background:var(--surface)}
  /* Панель пошуку+чіпів (item 4): один рядок замість двох */
  .list-panel{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
  .list-panel .search{flex:1;min-width:240px;margin:0}
  .list-panel .chips{margin:0}
  /* Лічильник біля h1 (item 4) — h1 більше не штовхає кнопку самотужки
     (.list-h1{margin-right:auto} скинуто), тепер це робить сам
     лічильник — лишається впритул до h1, штовхає «+ Новий клієнт» */
  .list-h1{margin-right:0}
  #list-pageinfo{display:inline;color:var(--muted);font-size:13px;
    margin-right:auto}
  .chip .nn-cnt{display:inline}
  /* Стара .count над списком дублювала б той самий текст, що тепер і
     біля h1 — dense ховає, мобільний лишає як був. Скоуп на #list-results
     (лише «Клієнти») — .count як клас ще й у «Дублікатах»/«Журналі»,
     їх чіпати не можна. */
  #list-results .count{display:none}
  /* Пагінація (item 5): круглі ‹›, «сторінка N з M», підказка праворуч */
  .pager{justify-content:flex-start}
  .pager .pg-full{display:none}
  .pager .pg-short{display:inline;font-size:16px;line-height:1}
  .pager .pg-pages{display:inline;color:var(--muted);font-size:13px}
  .pager .hint{display:inline;margin-left:auto;color:var(--muted);
    font-size:12.5px}
  .pager .btn{width:34px;height:34px;padding:0;border-radius:50%;
    min-height:auto}
  .rows{gap:6px}
  /* відгук миші: рядки списків підсвічуються */
  .row:hover,.orow:hover,.jrow:hover{background:var(--surface)}
  /* компактні робочі кнопки в рядках: миша не потребує 44px */
  .btn.small{min-height:32px;padding:7px 13px;font-size:13.5px}
  .qty button{width:36px;height:36px}
  /* Задача 4: фірмові іконки дій — показ лише тут (базове правило вище
     ховає), перед текстом кнопки */
  .btn .ic-svg{display:inline-block;width:15px;height:15px;
    vertical-align:-2px;margin-right:5px}
  /* компактніші картки списків «Сьогодні» */
  .row{padding:10px 14px}
  /* «Останні дзвінки» (Хвиля В, макет): рядок стає рядком таблиці —
     дир/хто/час/розмова/результат, як .crow вище. minmax замість
     фіксованих px — «✕ пропущений» найдовший текст бейджа не має
     обрізатись. Дії (cc-acts) НЕ в цій сітці — вони оверлей поверх
     рядка, дивись нижче. П'ять колонок (Хвиля макета, Задача 1, item 3:
     cc-dur повернуто — today.recent_calls тепер віддає billsec); who
     звузили під нову колонку. position:relative тут — точка відліку
     для абсолютного оверлею дій нижче. */
  .callrow2{display:grid;align-items:center;gap:4px 14px;position:relative;
    grid-template-columns:minmax(110px,auto) minmax(200px,1.4fr)
      54px 58px minmax(140px,1fr)}
  .callrow2 .cc-dir,.callrow2 .cc-time,.callrow2 .cc-dur,.callrow2 .cc-res{margin:0}
  .callrow2 .cc-time,.callrow2 .cc-dur{font-variant-numeric:tabular-nums;
    white-space:nowrap}
  .callrow2 .cc-who{min-width:0}
  .callrow2 .cc-who .nm,.callrow2 .cc-who .sub{white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis}
  /* Шапка колонок «Напрям/Хто/Час/Розмова/Результат» (item 3) — DOM-
     рядок, dense-only (base: display:none вище). Клас .callrow2 дає їй
     ТУ САМУ сітку колонок, що й даним рядкам (без дублювання значень);
     border-bottom на КОНТЕЙНЕРІ (не на кожній комірці) — суцільна лінія
     під шапкою, а не сегментована по треках через gap. */
  .callhead{display:grid;border-bottom:1px solid var(--border);
    padding-bottom:6px;margin-bottom:6px}
  .callhead>div{text-transform:uppercase;font:700 11px/1.3 var(--font-body);
    letter-spacing:.06em;color:var(--muted)}
  /* Заголовок секції + підказка праворуч (item 3) — сечед стає рядком
     лише тут; hint2/лічильник «N сьогодні»/футер-підказка «Журналі» —
     нові елементи макета, показ лише dense (база сховала вище). */
  .sechead{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  /* .side (мокет): обгортка дії/лінка/підказки праворуч у заголовку
     секції — «+ Додати» (Довідники), «усі N →» і лічильник дзвінків
     (Картка клієнта, Задача 7) усі йдуть крізь неї. margin-left:auto на
     .hint2 (нижче) саме по собі не штовхає, коли .hint2 — ОНУК .sechead
     (усередині .side), не прямий флекс-айтем — потрібен цей рядок. */
  .sechead .side{margin-left:auto;display:flex;gap:8px;align-items:center}
  .hint2{display:inline;margin-left:auto;font-size:12.5px;color:var(--muted)}
  .cnt-recent{display:inline-block}
  .rhint{display:block;font-size:12.5px;color:var(--muted);margin-top:8px}
  /* Іконки заголовків секцій (item 7) — icSvg() перед текстом h2, лише
     тут (база ховає вище). Синій тінт — під фірмові плитки макета. */
  .tsec h2 .ic-svg{display:inline-block;width:18px;height:18px;
    color:var(--blue);vertical-align:-4px;margin-right:8px}
  /* Фікс-раунд рев'ю 2 (09.08, живі виміри): nowrap-рядок сам по собі
     НЕ рятував — min-content .cc-acts (3 кнопки) на 234-302px ширший
     за доступну grid-колонку auto, тож кнопки вилазили за межі рядка й
     ховались під сусідньою карткою «Кому подзвонити» (elementFromPoint
     влучав у сусідній елемент замість кнопки). Фікс: дії ПОВНІСТЮ ПОЗА
     grid-потоком — position:absolute поверх правого краю рядка
     (прив'язка до .callrow2{position:relative} вище), нічого не
     розширює. Градієнт прикриває текст .cc-res/.cc-who під собою (як у
     поштових списках), не блокуючи клік по самих кнопках. Видиме лише
     при наведенні (макет): миша знає, куди навести, дотик — ні, тому
     поза цим блоком (мобільний/планшет) кнопки лишаються в потоці,
     завжди видимими (базове правило вище, без opacity/absolute). */
  .callrow2 .cc-acts{opacity:0;transition:opacity .1s;margin:0;
    position:absolute;right:8px;top:50%;transform:translateY(-50%);
    display:flex;flex-wrap:nowrap;gap:6px;padding-left:24px;
    background:linear-gradient(90deg,rgba(255,255,255,0),var(--white) 22%)}
  .callrow2:hover .cc-acts{opacity:1}
  /* Задача 10, item 7 (питання власника): кнопки дій «Останніх дзвінків»
     — той самий круглий .ib-вигляд, що скрізь (34px/10px, біле тло,
     рамка var(--border) — «в один спільний стиль», як просить бриф),
     раніше лишались повнорозмірними .btn.small із текстом (мокет: .ib).
     Текст ховаємо (.btxt, розмітка app.js), лишаємо іконку — overlay-
     механізм (position:absolute+градієнт, фікс-раунд вище) НЕ чіпаємо,
     це про форму/розмір кнопки, не про верстку рядка. white-space було
     тут окремим правилом до Задачі 10 — злито в одне. */
  .callrow2 .cc-acts .btxt{display:none}
  .callrow2 .cc-acts .btn{white-space:nowrap;width:34px;height:34px;
    padding:0;min-height:auto;border-radius:10px;border-color:var(--border);
    background:var(--white);color:var(--blue);display:inline-flex;
    align-items:center;justify-content:center}
  .callrow2 .cc-acts .btn:hover{background:rgba(2,88,201,.08);
    border-color:var(--blue)}
  .callrow2 .cc-acts .btn .ic-svg{margin-right:0}
  /* .tel-fallback — base display:none (лише ≤700px запасний варіант,
     style.css вище) — правило .btn вище (0-0-3-0) інакше перебило б
     його вищою специфічністю, показавши запасну кнопку в dense, де
     вона взагалі не мала бути. Повертаємо display:none тут (0-0-4-0). */
  .callrow2 .cc-acts .btn.tel-fallback{display:none}
  /* .row:hover вище (0-2-0) інакше перебив би червоний фон пропущеного
     на наведення мишею — тут вужче правило (0-3-0) утримує сигнал,
     трохи світлішим відтінком (макет власника). */
  .row.missrow:hover{background:#FBE7E7}
  /* Finding 2 (фінальне рев'ю 10.08): «Останні дзвінки» лишались
     заокругленими картками-рядками — мокет вимагає суцільні рядки з
     тонкими розділювачами, без карток-рамок (той самий прийом, що
     #list-results/#od-results/.t-orders вище, «worktable»-де-картизація).
     Скоуп ЛИШЕ на .t-recent — .row/.rows глобальні, картки «Пропущені»/
     «Оформлені сьогодні»/«Кому подзвонити» не чіпаємо.
     ОНОВЛЕНО Задачею 10, item 1: «БЕЗ білої обгортки» вище — рішення,
     скасоване прямим замовленням власника («головна знахідка» рев'ю
     10.08 — прозора таблиця на блакитному тлі); .t-recent-box нижче
     додає ту саму білу картку, що #list-results (мокет .worktable). */
  .t-recent .rows{gap:0}
  .t-recent .row.callrow2{border:none;border-radius:0;background:none}
  .t-recent .row.callrow2+.row.callrow2{border-top:1px solid var(--border)}
  /* background:none вище (0-3-0, три класи) переважає базовий
     .row.missrow (0-2-0) — без компенсації червона смуга пропущеного
     зникла б разом із карткою. Відновлюємо фон вищою специфічністю
     (0-4-0), і окремо hover-відтінок (0-5-0, той самий #FBE7E7, що
     .row.missrow:hover вище) — обидва мають перемогти незалежно від
     порядку в файлі. Лише background: мокет тут — повношира смуга
     кольору, не бордюрована картка, тож border навмисно НЕ повертаємо
     (border:none лишається — узгоджено з де-картизацією вище). */
  .t-recent .row.callrow2.missrow{background:var(--danger-bg)}
  .t-recent .row.callrow2.missrow:hover{background:#FBE7E7}

  /* Задача 10, item 1: біла worktable-картка навколо шапки+рядків+
     футера «Останніх дзвінків» — та сама дисципліна, що #list-results
     (обгортка .t-recent-box додана в HTML, app.js — .sechead лишається
     ЗА межами картки, як заголовок «Клієнти» над #list-results, мокет
     тримає h2 поза .worktable). overflow:hidden ріже кутові рядки під
     border-radius картки. */
  .t-recent-box{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);overflow:hidden}
  /* .callhead (base) не несе горизонтального падінгу (він не .row) —
     усередині білої картки шапка мусить вирівнятись з рядками (padding
     14px зліва/справа, як .row нижче); margin-bottom:0 — низ шапки
     тепер задає власний padding-bottom правила вище (border-bottom). */
  .t-recent-box .callhead{padding:10px 14px 6px;margin-bottom:0}
  /* Футер (мокет .tfoot): «Показати ще»+підказка «Журнал» — сірою
     смужкою всередині тієї самої картки (та сама дисципліна, що
     #list-results .pager), не окремим блоком під нею. */
  .t-recent-foot{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding:11px 14px;border-top:1px solid var(--border);
    background:var(--surface)}
  .t-recent-foot .rhint{margin:0;margin-left:auto}
  .t-recent-foot .t-more{margin:0}
  /* Імена в таблиці дзвінків — темний жирний текст (мокет), НЕ синій
     лінк сайтового `a{color:var(--blue)}`; сам <a> лишається (клік у
     картку клієнта далі працює), змінюємо лише колір. .row .nm вже дає
     font-weight:700 (база), тут лише перефарбовуємо. */
  .callrow2 .cc-who .nm a{color:var(--navy)}

  /* ---- Хвиля відповідності макету, Задача 1 («Сьогодні» за макетом) ---- */

  /* item 1: плитки-цифри дня → пігулки в один рядок з h1 (.today-head —
     структурна обгортка навколо .h-row+.stats, БЕЗ власного правила
     поза цим блоком: база лишається стеком, як і була, лише додався
     нейтральний контейнер). display:contents на .h-row не потрібен —
     margin-right:auto на h1 усередині .h-row вже штовхає кнопку/напис
     синку праворуч, .stats — другий флекс-айтем today-head, якому
     власний margin-left:auto штовхає ЙОГО аж до правого краю. */
  .today-head{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
  .today-head .stats{margin-top:0;margin-bottom:0;margin-left:auto}
  /* попередження синку (рідкісний випадок) — завжди на всю ширину,
     інакше стало б флекс-айтемом поряд з h-row/stats і зверстало б
     криво */
  .today-head .alert{flex-basis:100%}
  /* назва+число в один рядок (макет .statchip), а не картка у два поверхи */
  .today-head .stat{display:inline-flex;align-items:baseline;gap:6px;
    padding:8px 14px}
  .today-head .stat b{display:inline;font-size:17px;margin-top:0}
  .today-head .stat-full{display:none}
  .today-head .stat-short{display:inline}
  /* «Пропущені» — червона (danger), НЕ амбер сайтового .stat.warn
     (Машини лишаються амбер; Пульс отримав СВІЙ danger-скоуп у Задачі 8,
     .pulse-stats .stat.warn нижче — той самий принцип, локальний вибір
     кольору за сторінкою) — скоуп на .today-head тримає це локальним для
     «Сьогодні». */
  .today-head .stat.warn{background:var(--danger-bg);
    border-color:var(--danger-bd)}
  .today-head .stat.warn b{color:var(--danger)}

  /* item 2: банер пропущеного — full-width РЯДОК 1 grid'а «Сьогодні»,
     .t-recent — вся висота лівої колонки (РЯДОК 2, треку «left»),
     .today-col-r — вся висота правої (спанить обидва рядки). Дисолвимо
     ЛИШЕ ліву обгортку (.today-col-l) — права не потребує розбиття на
     окремі грід-елементи, її трьом секціям досить лишитись звичайним
     блоковим потоком усередині власної клітинки «right». */
  .today-cols{grid-template-areas:"miss miss" "left right"}
  /* Задача 10, item 1: ліва/права 3:1 (макет: ліва ~1166px, права 360px
     на 1600px екрані) — ОБОВ'ЯЗКОВО .cols.two.today-cols (три класи,
     0-0-3-0), інакше базове .cols.two{grid-template-columns:1fr 1fr}
     (0-0-2-0) переважає голий .today-cols (0-0-1-0) — той самий урок,
     що .cols.two.pulse-grid (Задача 8): живий вимір ловив рівно цей
     регрес (767px/767px замість 3:1 до цього фіксу). */
  .cols.two.today-cols{grid-template-columns:minmax(0,1fr) 360px}
  .today-cols .today-col-l{display:contents}
  /* той самий урок, що .today-cols>div>* на мобільному (390px→490px,
     фінальне рев'ю Хвилі Д): дисолв робить t-missed/t-recent грід-
     елементами — без min-width:0 вузька колонка не стискається нижче
     min-content вмісту (таблиця дзвінків). */
  .today-cols .today-col-l>*{min-width:0}
  .today-cols .t-missed{grid-area:miss}
  .today-cols .t-recent{grid-area:left}
  .today-cols .today-col-r{grid-area:right}
  /* base h2 секції ховаємо — банер сам несе лейбл (.miss-lbl нижче) в
     кожному рядку, окремий заголовок секції над списком зайвий. */
  .t-missed h2{display:none}
  .t-missed .miss-lbl{display:inline;margin-right:2px}
  /* Один рядок замість картки-стеку: .nm/.sub/.trow — флекс-айтеми в
     одну лінію, фон/рамка — danger-токени (виміряно з еталона: піксель
     банера #FEF2F2 = var(--danger-bg) день-в-день, макет теж рахує його
     через var(--danger-bg) — літеральний #FDECEC з тексту задачі НЕ
     збігається ні з тим, ні з тим, тож довіряємо токену). */
  .t-missed .row{display:flex;flex-wrap:wrap;align-items:center;
    gap:6px 14px;background:var(--danger-bg);border-color:var(--danger-bd)}
  .t-missed .row:hover{background:#FBE7E7}
  .t-missed .nm,.t-missed .sub,.t-missed .trow{margin:0}
  /* «дзвонив N р.» лишається — фраза без зайвого номера/«останній X хв
     тому» (мокет: лише ім'я+бейдж часу+«дзвонив N р.» в один рядок) */
  .t-missed .miss-phone,.t-missed .miss-last{display:none}
  .t-missed .tel-fallback{display:none}
  /* порожньо → банер не малюється взагалі (без «Все оброблено ✓» —
     item 2 явно забороняє порожній стан у dense) */
  .t-missed .empty{display:none}

  /* item 4: «Оформлені сьогодні» — однорядковий реєстр у спільній
     білій картці (мокет .box), а не стос окремих карток-рядків. */
  .t-orders .rows{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);padding:2px 0;gap:0}
  .t-orders .row{border:none;border-radius:0;padding:0;background:none}
  .t-orders .row+.row{border-top:1px solid var(--border)}
  /* статус-слово й адреса — у title рядка (нативний тултип), не в
     розмітці dense: .orow2 нижче несе те саме значення компактніше. */
  .t-orders .row>.nm,.t-orders .row>.sub{display:none}
  .orow2{display:flex;align-items:center;gap:10px;padding:10px 16px}
  .orow2 .st{font-size:16px}
  .orow2 .onm{flex:1;min-width:0;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .orow2 .osum{font-weight:700;font-variant-numeric:tabular-nums;
    white-space:nowrap;margin-left:auto}
  .t-orders .row.ord-more{display:block;padding:10px 16px;
    border-top:1px dashed var(--border)}

  /* Задача 10, item 3: круглий бейдж-лічильник біля заголовка (мокет
     h2 .cnt) + один-єдиний лінк «усі N →» ЛИШЕ внизу картки (.ord-more
     нижче) — верхній .seeall у h2 дублював те саме, ховаємо лише тут
     (селектор .t-orders h2 .seeall НЕ чіпає .ord-more — той поза h2). */
  .t-orders h2 .seeall{display:none}
  .t-orders h2 .cnt-orders{display:inline-block}

  /* item 5 → Задача 11 (скріншоти власника 11.08): «Кому подзвонити»
     лишався картковим — щільніші падінги/іконка-ховер (нижче) заводили
     лише вигляд самої КНОПКИ, не рядка. .qbox тут — той самий worktable-
     прийом, що #list-results/.t-recent-box/.t-orders .rows: суцільна
     біла картка з тонким розділювачем МІЖ рядками, без рамки/радіуса/
     фону на кожному окремому. Клас .qbox — у розмітці app.js ЛИШЕ на
     «рядку черги» (компакт-п'ятірка «Кому подзвонити», міні-п'ятірка
     сплячих), НЕ на розгорнутому «Усі N»/повних «Сплячих» (ті лишаються
     старими картками clientRow — поза скоупом задачі). Складене
     «.rows.qbox» (не голий .qbox) — інакше та сама специфічність
     (0-1-0), що dense .rows{gap:6px} вище, лишала б порядок правил у
     файлі єдиним арбітром замість явного tie-break. */
  .rows.qbox{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);padding:2px 0;gap:0}
  .qbox .qrow2{border:none;border-radius:0;background:none;
    padding:10px 16px}
  .qbox .qrow2+.qrow2{border-top:1px solid var(--border)}
  /* .row:hover вище (0-2-0, той самий рядок правил, що #list-results)
     зв'язаний з .qbox .qrow2{background:none} (теж 0-2-0) — пізніший у
     файлі перемагав би завжди, гасячи підсвітку миші й ПІД ЧАС
     наведення. Явний :hover тут (0-3-0) перемагає незалежно від
     порядку. */
  .qbox .qrow2:hover{background:var(--surface)}
  /* Міні-п'ятірка сплячих (Хвиля Д, Задача 3): рядок-привід «Давно не
     замовляли…» — .rows.qbox{padding:2px 0} лишає його притиснутим до
     лівого краю картки без власного горизонтального відступу. */
  .qbox .src{padding:8px 16px 0}
  /* Задача 10, item 7: та сама .ib-форма (34px/10px/біле тло), що
     скрізь — базовий .btn.tinted (мокет .qrow .ib тут БІЛИЙ, не
     тонований) переможений вищою специфічністю нижче. Тінт («головна
     дія рядка», Задача 1 хвилі) лишається на базі/мобільному — це
     перекриття ЛИШЕ dense. */
  .t-whom .qrow2 .c2c-btn{opacity:0;transition:opacity .12s;
    width:34px;height:34px;padding:0;min-height:auto;border-radius:10px;
    border-color:var(--border);background:var(--white);color:var(--blue);
    display:inline-flex;align-items:center;justify-content:center}
  .t-whom .qrow2:hover .c2c-btn{opacity:1}
  .t-whom .qrow2 .c2c-btn:hover{background:rgba(2,88,201,.08);
    border-color:var(--blue)}
  .t-whom .qrow2 .btxt{display:none}
  .t-whom .qrow2 .c2c-btn .ic-svg{margin-right:0}

  /* Задача 11, item 2 (фікс-раунд рев'ю 11.08): «Ім'я · ціна» жирним
     рядком, сіра мета — СВОЇМ рядком нижче (мокет: «Олена М. · 180 грн
     минуло 110 дн · цикл 81 · випаде за 6 дн» — навіть цей короткий
     демо-рядок макета сам займає 2 рядки, живий тест еталона це
     підтвердив). Перша редакція item 2 читала бриф як «мета НЕ
     переноситься» (nowrap+flex:none на .sub) — це стискало ім'я до
     «Ол…» на isFirst-рядку з довгою метою. Правильно — навпаки: .sub
     завжди йде на власний флекс-рядок (flex-basis:100%, тому wrap
     гарантований незалежно від довжини), ім'я (.nm) лишається на
     першому рядку на всю ширину — НІКОЛИ не калічиться метою, коротшає
     трикрапкою лише коли САМЕ ім'я довше за рядок (база, style.css
     рядок 584). Менший розмір .sub (12.5px, той самий, що .hint2/
     .rhint) — узгоджено з компакт-щільністю рядка. */
  .t-whom .qrow2 .qprice{display:inline}
  .t-whom .qrow2 .who{display:flex;flex-wrap:wrap;align-items:baseline;
    gap:2px 8px;min-width:0}
  .t-whom .qrow2 .who .nm{flex:1 1 auto;min-width:0}
  .t-whom .qrow2 .who .sub{flex:1 1 100%;white-space:normal;margin:0;
    font-size:12.5px}

  /* Задача 11, item 4: футер картки за макетом — зліва «Усі N →»
     (.seeall, не сіра кнопка), справа синій «▶ Режим обдзвону» (повний
     текст). Сам рядок — .row всередині .qbox (той самий прийом, що
     .t-orders .row.ord-more): дашед-розділювач замість суцільного.
     Base лишає старий .trow («Усі N»/«▶ Обдзвін») — dense ховає його
     ДИТЯЧИМ комбінатором (.t-whom>.trow), не голим .trow (той клас
     сидить і в десятках інших рядків — clientRow/sleepingRowCompact/
     recentRow/missed-плашка — де його чіпати не можна). */
  .t-whom .whom-foot{border:none;border-radius:0;background:none;
    display:flex;align-items:center;gap:14px;padding:10px 16px;
    border-top:1px dashed var(--border)}
  .t-whom .whom-foot .seeall{margin-left:0}
  .t-whom .whom-foot .whom-obd{margin-left:auto}
  .t-whom>.trow{display:none}

  /* item 6: freedial іде в шапку (#hdr-dial, index.html) — блок на
     сторінці ховаємо; мокет його взагалі не має. */
  .freedial{display:none}
  #hdr-dial{display:inline-block}
  /* «Замовлення» (Хвиля Г1 Задача 2; таблиця з шапкою+іконки-дії — Хвиля
     відповідності макету, Задача 3): рядок — сім колонок — час/клієнт/
     товари/сума/оплата/стан/дії (мокет: <th></th> сьома, порожня,
     заповнюється лише .ib-іконками при наведенні). .trow (стара
     текстова кнопка, base) ховається нижче — .od-acts (нова іконка)
     займає сьому колонку замість неї; edit-box і далі окремим рядком
     на всю ширину (grid-column:1/-1), форма редагування розгортається
     під даними, не в колонці дій. padding-left/right — ВЛАСНІ (не лише
     успадковані від .row): шапка (.chead odrow, живий баг живої
     перевірки) не носить класу .row, тож без цього перша колонка
     («Час») стартувала б впритул до заокругленого краю #od-results і
     обрізалась би overflow:hidden. Лише LEFT/RIGHT (не шорткат
     padding) — .chead{padding-bottom:6px} лишається чинним для шапки
     (той самий верт. відступ, що в .chead crow, Задача 2); TOP/BOTTOM
     рядків даних і далі йдуть від .row{padding:10px 14px} без змін. */
  .odrow{display:grid;align-items:center;gap:4px 14px;
    padding-left:14px;padding-right:14px;
    grid-template-columns:72px minmax(200px,1.6fr) minmax(140px,1fr)
      90px minmax(160px,1.3fr) minmax(110px,150px) 76px}
  .odrow .od-time{font-variant-numeric:tabular-nums;white-space:nowrap}
  /* без цього display:none з базового :empty вище прибрав би порожню
     комірку з grid-потоку — зсуло б усі дані на одну колонку ліворуч
     (od-client потрапив би під час, і так далі). */
  .odrow .od-time:empty{display:block}
  .odrow .od-sum{text-align:right;font-weight:700}
  /* Фікс-раунд живого рев'ю (IMPORTANT 2): колонка od-state вище стала
     minmax замість фіксованих 130px (короткі стани — «у черзі»/
     «доставлено ✓»/«скасовано» — від цього нічого не втрачають), АЛЕ
     реальні назви машин з кольором («Мастер AI7417PM коричневий»,
     test_map_api.py) все одно довші за будь-яку розумну ширину в
     таблиці — жива перевірка ловила бейдж «→ Мастер КА3183МІ», зламаний
     на 2-3 рядки в 130px/56.6px факт. ellipsis — єдиний фікс, що працює
     для БУДЬ-ЯКОЇ довжини назви, не заміна розширенню колонки, а поруч
     із ним. Селектор scoped на .odrow .od-state .badge — глобальний
     .badge (сотні місць) не займаємо. */
  .odrow .od-state .badge{white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;max-width:100%;display:inline-block}
  .odrow .edit-box{grid-column:1/-1}
  /* item 2 (findings.json «Замовлення», комірка клієнта): ім'я жирним
     першим рядком, адреса сірим другим — ОКРЕМИМИ рядками (мокет
     .nm/.sub2), не через кому. Стара комбінована подача (.nm/.sub, з
     комою) ховається ЛИШЕ тут — база лишає її без змін (dual-render,
     той самий прийом, що .t-orders .row>.nm,>.sub у Задачі 1). Ellipsis
     (не перенос) — фіксована/minmax-колонка не має ламати ~60px рядок
     на реальних довгих іменах/адресах (рев'ю: та сама дисципліна, що
     .crow .c-addr). */
  .odrow .od-client>.nm,.odrow .od-client>.sub{display:none}
  .od-name{display:block;font-weight:700;white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis;max-width:100%}
  .od-addr{display:block;font-size:12.5px;color:var(--muted);
    margin-top:2px;font-weight:400;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;max-width:100%}
  /* Фікс-раунд (IMPORTANT): item 3 — .pay-text (старий інлайновий текст
     «до оплати N грн · метод», база) ↔ .od-pay-badges (нові .badge,
     dense) — той самий dual-render прийом, що .nm/.sub ↔ .od-name/
     .od-addr щойно вище. */
  .odrow .od-pay>.pay-text{display:none}
  .od-pay-badges{display:inline}
  /* джерело («оператор»/«сайт»)+вікно доставки — дрібним під ЧАС (item
     2, друга половина «або в СТАН» пішла нижче на cancel-meta);
     72px-колонка тісна для повного тексту — ellipsis, title у розмітці
     (app.js) несе повне значення. */
  .od-time-meta{display:block;font-size:11px;color:var(--muted);
    margin-top:2px;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;max-width:100%}
  /* «скасовано …» переїхало зі старого метарядка клієнта в СТАН (item
     2) — та сама дрібна сіра подача, що od-addr/od-time-meta. */
  .od-cancel-meta{display:block;font-size:12.5px;color:var(--muted);
    margin-top:2px;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;max-width:100%}
  /* item 1: дії кінця рядка — .trow (текст, base) ховається, .od-acts
     (іконки .ib) займає сьому колонку, видима лише при наведенні
     (мокет .acts) — та сама дисципліна, що .crow .c-acts/.callrow2
     .cc-acts вище, але БЕЗ position:absolute — тут є справжня сьома
     колонка (мокет: порожній <th></th>), overlay не потрібен. */
  .odrow .trow{display:none}
  .odrow .od-acts{display:flex;justify-content:flex-end;gap:6px;
    opacity:0;transition:opacity .1s}
  .odrow:hover .od-acts{opacity:1}
  /* Круглий .ib (мокет) — селектор РОЗШИРЕНО з .crow (Задача 2), потім
     .odrow (Задача 3); повний перелік визначено ОДНИМ спільним правилом
     нижче разом із Задачею 5 (.fqrow/.vorow) — не задубльовано (той
     самий підхід, що радить бриф хвилі). */
  /* «Worktable» (item 1): суцільна біла картка навколо шапки+рядків —
     та сама дисципліна, що #list-results (Задача 2, «Клієнти»). Скоуп
     на #od-results — .row/.rows глобальні (картки «Сьогодні» лишаються
     як були). */
  #od-results{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);overflow:hidden}
  #od-results .rows{gap:0}
  #od-results .row.odrow{border:none;border-radius:0;background:none}
  #od-results .row.odrow+.row.odrow{border-top:1px solid var(--border)}
  /* item 4: заголовок+кнопка, навігація+режими, підсумки — в ОДНОМУ
     контрольному рядку (мокет .dayrow), а не трьома. Той самий прийом,
     що .today-head (Задача 1): flex-wrap природно складе в ≤2 рядки
     залежно від довжини вмісту, .stats притиснуто праворуч. */
  .od-controlbar{display:flex;flex-wrap:wrap;align-items:center;
    gap:8px 14px}
  .od-controlbar .stats{margin-top:0;margin-bottom:0;margin-left:auto}
  /* назва+число в один рядок (мокет .statchip), а не картка у два
     поверхи — та сама переробка, що .today-head .stat вище. */
  .od-controlbar .stats .stat{display:inline-flex;align-items:baseline;
    gap:6px;padding:8px 14px}
  .od-controlbar .stats .stat b{display:inline;font-size:17px;
    margin-top:0}
  /* Задача 10, item 5: кнопка «Сьогодні» в наві днів («Замовлення»,
     «Журнал») — тонована (мокет .btn.tinted), НЕ сіра :disabled, коли
     показано сьогоднішній день. Поведінка (disabled — клік ігнорується)
     лишається, вигляд лише тут. Три класи (.btn.od-today:disabled) —
     свідомо вищі за базове `.btn:disabled{opacity:.5}` (0-0-2-0),
     перемагає незалежно від порядку правил у файлі. */
  .btn.od-today:disabled,.btn.j-today:disabled{
    background:rgba(2,88,201,.08);border-color:var(--blue);
    color:var(--blue);opacity:1;cursor:not-allowed}
  /* Картки авто (Хвиля Г1 Задача 3): 2-3+ колонки замість одного стовпця
     — auto-fill сам рахує скільки влізе, без ручних брейкпоінтів під
     конкретну ширину екрана. Хвиля макета, підтягування 3 (Задача 12,
     item 2): 360px → 480px — на мокеті (main max-width 1720px, padding
     24px — Задача 10 item 2, тут вище) при 1600px в'юпорту .vcard2
     сидить у ФІКСОВАНІЙ сітці 1fr 1fr 1fr (3 колонки по ~508px), auto-
     fill з minmax(480px,1fr) при тому самому контейнері (1552px)
     рахує ті самі 3 колонки тієї ж ширини — досі без ручних
     брейкпоінтів, але «вужчі» 360px-плитки з дев'ятьма пунктами
     заростання (owner-скріншот) уже не вміщувались би вузько; у
     пісочниці лише 2 машини з даними — займають 2 з 3 треків, третій
     лишається порожнім (як і на еталонному скріншоті). */
  .vgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(480px,1fr));
    gap:14px}
  /* margin:12px 0 (базовий .vcard) — залишок стекового режиму: у сітці
     проміжок дає gap вище, лишений margin подвоював би вертикальний
     зазор між картками. */
  .vgrid .vcard{margin:0}
  /* item 1: залишки на борту — компактні чіпи в рядок (мокет .sc),
     замість великих плиток у стовпчик (база, style.css вище,
     .vstock/.stat — незмінна). DOM-порядок лишається «підпис, потім
     <b>» (app.js, tile()) — число «перед» назвою тут лише візуально,
     через order:-1 на <b>, база не чіпається. .stxt отримує ellipsis-
     обрізання ~180px (мокет: довгі назви на кшталт «Рідна краплина
     18,9 л» не вигадуємо/не скорочуємо — обрізає сама CSS, повна
     назва — title, app.js). .z0 (нульовий залишок) ховаємо ЛИШЕ тут —
     мокет показує тільки ненульові («Порожні 0» на Мастері зникає),
     база (плитка) лишає нулі, як і раніше. */
  .vstock .sc{display:inline-flex;align-items:baseline;gap:5px;
    background:var(--surface);border-radius:10px;padding:6px 10px;
    font-size:12.5px}
  .vstock .sc b{order:-1;display:inline;font-size:14px;color:var(--navy);
    margin-top:0}
  .vstock .sc .stxt{overflow:hidden;text-overflow:ellipsis;
    white-space:nowrap;max-width:180px}
  /* пояснення «не відмічене завантаження?» ховаємо в компактному чіпі
     (не влізло б в один рядок) — title чіпа (app.js) лишає повну назву
     на ховер, амбер-колір числа (сайтове .stat.warn b) зберігаємо
     явно нижче: специфічність .vstock .sc b (0-2-1) інакше програвала
     б порядку файлу проти цього ж .stat.warn b (та сама 0-2-1, але
     наше правило нижче за файлом і без цього виграло б, стерши амбер
     навігі-кольором). */
  .vstock .sc small{display:none}
  .vstock .stat.warn b{color:var(--warn)}
  .vstock .sc.z0{display:none}

  /* ---- Хвиля відповідності макету, Задача 5 («Машини» за макетом) ---- */

  /* item 1: чіпи-лічильники + чіп-кнопка «Карта розподілу ▸» біля
     заголовка — .fleet-chips стає РЕАЛЬНИМ flex-контейнером лише тут
     (на базі — display:contents, обгортка розчинена, style.css вище).
     margin-left:auto — той самий трюк, що .today-head .stats/
     .od-controlbar .stats (h1 усередині .h-row вже штовхає праворуч,
     тут дублюємо для певності — .fleet-chips тепер сам генерує бокс). */
  .fleet-chips{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
    margin-left:auto}
  /* назва+число в один рядок (мокет .statchip) — та сама переробка, що
     .today-head .stat/.od-controlbar .stats .stat вище. */
  .fleet-chips .stat{display:inline-flex;align-items:baseline;gap:6px;
    padding:8px 14px}
  .fleet-chips .stat b{display:inline;font-size:17px;margin-top:0}
  #fleetmap-toggle-chip{display:inline-block}
  /* «Не розподілені» червона (danger), НЕ амбер сайтового .stat.warn
     (Пульс/картки авто лишаються амбер) — скоуп на .fleet-chips тримає
     це локальним, той самий принцип, що .today-head .stat.warn (Задача 1). */
  .fleet-chips .stat.warn{background:var(--danger-bg);
    border-color:var(--danger-bd)}
  .fleet-chips .stat.warn b{color:var(--danger)}
  /* Стара повношира банер-кнопка — чіп вище і є цим тоглом (item 1). */
  .maptoggle{display:none}

  /* item 2: «Не розподілені» — таблиця (мокет .worktable): шапка КЛІЄНТ/
     ЩО/СУМА/КОЛИ/МАШИНА + порожня 6-та колонка під іконки дій, той самий
     грід, що .chead fqrow (шапка успадковує колонки з класу .fqrow, як
     .chead odrow Задача 3). Стара картка-рядок (<b>, .sub, .src, .trow)
     ховається лише тут — dual-render. */
  .fqrow{display:grid;align-items:center;gap:4px 14px;
    padding-left:14px;padding-right:14px;
    grid-template-columns:minmax(180px,1.6fr) minmax(140px,1fr) 90px
      minmax(130px,170px) minmax(200px,1.3fr) 116px}
  /* Явний display: базове правило (style.css вище) ховає ці класи
     display:none з ТІЄЮ Ж специфічністю — без власного display тут
     властивість успадкувалась би від базового правила незалежно від
     порядку в файлі (CSS не «домальовує» відсутню властивість з
     пізнішого правила). */
  .fq-client{display:block}
  .fq-sum{display:block;text-align:right;font-weight:700}
  .fq-when{display:block;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;max-width:100%}
  .fq-items{display:block;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .fq-machine{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
  .fqrow>b,.fqrow>.badge,.fqrow>.sub,.fqrow>.src{display:none}
  .fqrow .trow{display:none}
  .fqrow .edit-box{grid-column:1/-1}
  /* Дії кінця рядка — іконки лише при наведенні (мокет .acts), та сама
     дисципліна, що .odrow .od-acts/.crow .c-acts. */
  .fqrow .fq-acts{display:flex;justify-content:flex-end;gap:6px;
    opacity:0;transition:opacity .1s}
  .fqrow:hover .fq-acts{opacity:1}
  /* Круглий .ib (мокет) — селектор РОЗШИРЕНО (не задубльовано), той
     самий підхід, що Задача 3 (.crow → .crow,.odrow); Задача 7 додає
     .callmini (картка клієнта, кнопка «▶ запис»); Задача 8 додає
     .debtrow (боржники «Пульсу», кнопка «Подзвонити» іконкою). */
  .crow .ib,.odrow .ib,.fqrow .ib,.vorow .ib,.callmini .ib,
  .debtrow .ib{display:inline-flex;
    align-items:center;justify-content:center;width:34px;height:34px;
    border-radius:10px;border:1px solid var(--border);
    background:var(--white);color:var(--blue);cursor:pointer;flex:none;
    min-height:auto;padding:0}
  .crow .ib:hover,.odrow .ib:hover,.fqrow .ib:hover,.vorow .ib:hover,
  .callmini .ib:hover,.debtrow .ib:hover{background:rgba(2,88,201,.08);
    border-color:var(--blue)}
  .crow .ib .ic-svg,.odrow .ib .ic-svg,.fqrow .ib .ic-svg,
  .vorow .ib .ic-svg,.debtrow .ib .ic-svg{display:inline-block;width:17px;
    height:17px;margin:0}
  /* «Worktable» (item 2): суцільна біла картка навколо шапки+рядків — та
     сама дисципліна, що #list-results/#od-results, З ОДНИМ свідомим
     відхиленням: overflow:VISIBLE (не hidden) — .ddlist (position:
     absolute від .dd усередині .fq-machine) інакше клипався б рамкою
     картки; мокет робить той самий вибір буквально (style="overflow:
     visible" саме на цій таблиці, arctica-crm-maket-desktop.html). */
  #fleet-queue-results{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);overflow:visible}
  /* .orow (база, НЕ .row — черга ніколи не носила картковий .row) вже й
     так «роздільники, не картки» (border-top, без фону/скруглення) —
     жодного reset тут НЕ потрібно, на відміну від #od-results/
     #list-results (там базовий .row МАВ картковий вигляд). Прострочене
     (.overdue-q) — виняток: base дає жовту картку-рамку ПО ВСЬОМУ рядку
     (padding-шорткат, вища специфічність за .fqrow padding-left/right) —
     тут скидаємо: сигнал лишається лише бейджем у КОЛИ (піксель-семпл
     еталона, maket-fleet.png: прострочений рядок БІЛИЙ, колір рядка й
     колір бейджа не дублюються). */
  .fqrow.overdue-q{background:none;border:none;border-radius:0;
    padding:0 14px}

  /* item 4: рядки замовлень у картці авто — dense-only однорядковий
     запис (мокет .vaddr): статус ✓/→ + ім'я·товари (ellipsis) + бейдж
     суми/«взяти готівку» одним рядком; дії — іконки при наведенні
     (СВІДОМЕ відхилення від мокету «без кнопок» — бриф задачі 5 явно
     лишає дії за hover, функціонал не можна різати заради пікселів, той
     самий принцип, що .od-acts/.c-acts/.callrow2 .cc-acts). Стара форма
     (.vorow-old — обгортка навколо старого вмісту, .trow — текстові
     кнопки) ховається лише тут. */
  .vorow .vorow-old,.vorow .trow{display:none}
  /* Фікс-раунд (рев'ю): .orow.vorow — точка відліку для абсолютного
     оверлею дій нижче (той самий прийом, що .crow{position:relative} /
     .callrow2{position:relative}). Без цього .v-acts у потоці РЕЗЕРВУВАВ
     БИ ВИСОТУ навіть при opacity:0 — рядок переставав бути однорядковим
     (порожня смуга під .vorow2 на живому скріншоті), а «однорядковість»
     — уся суть item 4. */
  .orow.vorow{position:relative}
  .vorow2{display:flex;align-items:center;gap:8px;min-width:0}
  .vorow2 .st{flex:none;font-size:15px}
  .vorow2 .onm{flex:1;min-width:0;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .vorow2 .vsum{flex:none}
  /* Оверлей праворуч (мокет .acts), той самий прийом, що .crow .c-acts/
     .callrow2 .cc-acts — ПОЗА grid/flex-потоком .vorow2, нічого не
     розширює; градієнт прикриває .vsum під собою на hover (як там), не
     блокуючи клік по самих кнопках. */
  .v-acts{display:flex;gap:6px;opacity:0;transition:opacity .1s;
    position:absolute;right:8px;top:50%;transform:translateY(-50%);
    padding-left:24px;
    background:linear-gradient(90deg,rgba(255,255,255,0),var(--white) 22%)}
  .orow.vorow:hover .v-acts{opacity:1}
  /* «доставлено N з M» — плитка ховається (не плитка, мокет), текст-
     підпис лишається лише в кнопковому рядку (.hint2 — глобально base-
     hidden/dense-shown, style.css вище/Задача 1, нового правила не
     потребує). */
  .v-progress{display:none}

  /* Довідники (Хвиля Г2 Задача 4): три колонки поруч (макет «Ще») —
     minmax(0,1fr), а не голий 1fr, бо колонки містять .dir-add
     (кілька input+кнопок), чия внутрішня ширина інакше розпирала б
     трек (grid-item за замовчуванням min-width:auto). Задача 7:
     grid-template-rows:auto 1fr — колонка «Водії» ділиться на два ряди
     (водії/вода), рядок 1 підганяється під висоту водіїв, рядок 2
     (вода) лишається впритул до його низу незалежно від висоти сусідніх
     колонок; row-gap:0 (у gap нижче) прибирає щілину МІЖ рядками —
     колонковий проміжок лишається 20px. */
  .dir-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    grid-template-rows:auto 1fr;gap:0 20px}
  /* gap вище вже дає відступ між колонками — лишений margin-top:20px
     (базовий .section) дав би несиметричний зазор зверху колонки.
     Задача 7: секції-довідники стають білими скругленими картками з
     рамкою (мокет .dirbox) — лише тут, база лишає їх пласким стеком
     (.section, style.css вище), як і був. */
  .dir-grid .section{margin-top:0;background:var(--white);
    border:1px solid var(--border);border-radius:var(--r-md);padding:6px 0}
  /* «Види води» — підсекція під «Водіями» в ТІЙ САМІЙ візуальній картці
     (мокет), БЕЗ переміщення DOM: #dir-water лишається на своєму місці
     в розмітці (після #dir-products) — мобільний бачить той самий стек,
     що й був. Явне розміщення в грід-клітинках зшиває обидві секції
     колонки 2 в одну картку: скруглення й межа МІЖ ними прибрані з боку,
     що стикається. */
  #dir-vehicles{grid-column:1;grid-row:1/3}
  #dir-drivers{grid-column:2;grid-row:1;
    border-radius:var(--r-md) var(--r-md) 0 0;border-bottom:none}
  #dir-water{grid-column:2;grid-row:2;
    border-radius:0 0 var(--r-md) var(--r-md);border-top:none}
  #dir-products{grid-column:3;grid-row:1/3}
  /* Заголовок секції (мокет .sechead) — .sechead уже flex-рядок вище
     (глобально dense-only, «Сьогодні» Задача 1) — тут лише внутрішній
     відступ картки. */
  .dir-sechead{padding:10px 16px 4px;margin:0}
  /* «+ Додати» — dense-only кнопка-тогл (база завжди показує форму без
     неї — керується .dir-add/.dir-add.open нижче). */
  .dir-add-toggle{display:inline-block}
  /* Форма додавання згорнута за «+ Додати» — сама форма (.dir-add,
     наявний клас) лишається в ТІЙ САМІЙ позиції розмітки, лише
     dense-only ховається до кліку (база .dir-add{display:flex} — style
     .css вище — лишається завжди розкритою). «Підтягнути з сайту»
     (Товари/Види води) — фікс-раунд рев'ю: ЦЕ НЕ форма ручного
     додавання, а дія синхронізації (мокет тримає її завжди видимою в
     заголовку) — app.js рендерить її через .side (sideExtra), не
     addHtml, тож вона НЕ потрапляє під це правило й нового CSS тут не
     потребує (.sechead .side{display:flex} вище вже її вирівнює). */
  .dir-grid .dir-add{display:none}
  .dir-grid .dir-add.open{display:flex}
  /* Список рядків — суцільна картка без проміжків-карток («worktable»,
     той самий прийом, що #list-results/#j-worktable): тонкий
     роздільник МІЖ рядками, не навколо кожного. */
  .dir-grid .dir-list{gap:0}
  .dir-grid .row.dir-row{border:none;border-radius:0;background:none;
    padding:9px 16px;margin:0}
  .dir-grid .row.dir-row+.row.dir-row{border-top:1px solid var(--border)}

  /* ---- Хвиля відповідності макету, Задача 6 («Журнал» за макетом) ---- */

  /* item 3: заголовок+навігація дня в одному рядку (мокет .dayrow) — та
     сама дисципліна, що .today-head/.od-controlbar: обгортка РОЗЧИНЕНА
     на базі (жодного власного правила там, лише природний стек
     h1→#j-daynav), тут стає flex-рядком; h1 margin-right:auto штовхає
     нав праворуч, як .h-row h1/.today-head. */
  .j-controlbar{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
  .j-controlbar h1{margin-right:auto}
  /* рядок один — зайвий низовий відступ #j-daynav .trow (база, style.css
     вище) тут не потрібен. */
  #j-daynav .trow{margin-bottom:0}

  /* item 3: пошук+чіпи+«Усі люди» одним рядком — .list-panel, той самий
     клас, що «Клієнти» (Задача 2), СЕЛЕКТОР РОЗШИРЕНО (не задубльовано).
     #j-actor — компактна випадайка ~190px (мокет: не на всю ширину);
     базовий width:100% (ID, style.css вище) переважений явним width тут
     (клас+ID у складеному селекторі важить більше за голий ID). */
  .list-panel #j-actor{width:190px;flex:none;margin:0}

  /* item 1: список подій → таблиця (мокет .worktable): суцільна картка,
     шапка ЧАС/ХТО/ЩО СТАЛОСЯ/(бейдж), рядки впритул. Той самий грід, що
     .crow/.odrow/.fqrow — ОДНЕ спільне правило нижче на клас .jrow,
     шапка (.jrow.chead) успадковує ті самі колонки автоматично (як
     .chead crow/.chead odrow/.chead fqrow). Час — minmax, НЕ фіксовані
     px: режим пошуку домальовує дату в ту саму комірку («вчора 14:05»,
     «06.07 09:12») — фіксована вузька колонка ламала б рядок на два. */
  .jrow{display:grid;grid-template-columns:minmax(64px,auto)
    minmax(120px,180px) minmax(220px,1fr) minmax(90px,130px);
    align-items:center;gap:4px 14px}
  /* Шапка (0-2-0, style.css вище ставить .jrow.chead{display:none} на
     базі) — тут вмикається назад як grid і скидає картковий вигляд
     (рамка/скруглення/маржа), успадкований від .jrow, ЛИШЕ собі. */
  .jrow.chead{display:grid;border:none;border-bottom:1px solid var(--border);
    border-radius:0;background:none;margin:0;padding:0 14px 6px}
  /* Рядки даних: суцільна таблиця — рамка/скруглення/маржа геть, тонкий
     роздільник МІЖ рядками (скоуп на #j-rows — не дотягується до
     .chead.jrow, той поза #j-rows, свій border-bottom вище лишається
     єдиною лінією під шапкою). border-left НЕ чіпаємо: колір типу
     (.jrow-order/-edit/-cash/-vehicle, база, style.css вище) має
     лишитись переможцем без спеціальних селекторів. */
  #j-rows .jrow{border-top:none;border-right:none;border-bottom:none;
    border-radius:0;background:none;margin:0;padding:9px 14px}
  #j-rows .jrow+.jrow{border-top:1px solid var(--border)}
  /* «Worktable» — суцільна біла картка навколо шапки+рядків+футера, та
     сама дисципліна, що #list-results/#od-results/#fleet-queue-results. */
  #j-worktable{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);overflow:hidden}

  /* item 2: старий лівий чіп типу (.jk, ВЕЛИКІ літери) і чіп «канал»
     ховаються лише тут — dual-render, .jbadge (кінець рядка, кольоровий,
     малі літери — голий .badge без text-transform) займає їхнє місце,
     мокет. (0-2-0) — б'є .badge{display:inline-block} (0-1-0) незалежно
     від порядку правил у файлі. */
  .jrow .jk,.jrow .jchannel{display:none}
  .jrow .jbadge{display:inline-block;justify-self:end}
  /* Задача 10, item 6: «Хто» — звичайне накреслення (мокет: <td> без
     власного font-weight, успадковує 400 від table), база (.jactor
     нижче, style.css вище) лишається жирною — торкаємось лише dense. */
  .jrow .jactor{font-weight:400}

  /* item 4: лінк на клієнта в тексті — payload вже несе client_id
     (journal.py), але БЕЗ окремого імені клієнта всередині тексту (укр.
     речення готове цілком) — підкреслюємо ВЕСЬ .jtext, чесний
     компроміс без вигаданого лінк-спана чи нового запиту. */
  .jrow .jtext.jlink{text-decoration:underline}

  /* item 5: футер-підказка під списком (мокет .tfoot) — .rhint вже
     base-hidden/dense-shown глобально (style.css вище, «Сьогодні»
     Задача 1); тут лише контейнер отримує вигляд смужки-підвалу (та
     сама дисципліна, що #list-results .pager). */
  #j-tfoot{display:flex;padding:11px 14px;border-top:1px solid var(--border);
    background:var(--surface)}

  /* ---- Хвиля відповідності макету, Задача 7 (Дублікати) ---- */
  /* мета-рядок «Група N з M · вирішено раніше: K» — в одному рядку із
     заголовком (мокет), не окремим сірим рядком під ним. Обгортка без
     власного базового правила (та сама дисципліна, що .today-head) —
     дітям на базі нема різниці, стек лишається таким, як був. */
  .mrg-head{display:flex;align-items:baseline;gap:8px 16px;flex-wrap:wrap}
  .mrg-head h1{margin:0}
  .mrg-head .count{margin:0}
  /* компактна картка ~60% ширини сторінки (мокет .mergebox
     max-width:900px), не на весь екран */
  .mergecard{max-width:900px}
  /* кандидати — дві колонки поруч, кожен своєю бордованою карткою
     (мокет .mcols/.mcl); база лишає .mcols нестильованим div — .ph
     стекають вертикально, як і стекали до цієї задачі. */
  .mergecard .mcols{display:grid;grid-template-columns:1fr 1fr;gap:10px}
  .mergecard .mcols .ph{border:1px solid var(--border);
    border-radius:var(--r-sm);padding:12px 14px}
  /* «Чому підозра:» лейбл жирним — лише тут, база лишає звичайне
     накреслення (успадковане від .why, без власного правила). */
  .mwhy-lbl{font-weight:700}
  /* кнопки звичайної ширини зліва, не розтягнуті на всю картку */
  .mbtns .btn{flex:none;padding:12px 20px;font-size:16px}
  /* «Об'єднати…» — трикрапка лише тут (базовий текст лишається
     «Об'єднати» — той самий рядок іде і в askConfirm-заголовок нижче
     кнопки, де трикрапка зайва). */
  #m-yes::after{content:"…"}

  /* ---- Хвиля відповідності макету, Задача 7 (Картка клієнта) ---- */

  /* Чіпи Фірма/Перевірити/Спам — у рядку імені (мокет). .client-headwrap
     — структурна обгортка (база — жодного правила, стек лишається
     h-row→phones→quickActions, як і був); .h-row/.switches РОЗЧИНЯЮТЬСЯ
     (display:contents) — той самий прийом, що .today-cols .today-col-l
     (Задача 1): їхні діти стають прямими флекс-айтемами обгортки, order
     керує видимою послідовністю НЕЗАЛЕЖНО від DOM (h1 margin-right:0 —
     inline style у розмітці — лишається переможцем і тут, display:
     contents на батькові не чіпає інлайн-стиль дитини). */
  .client-headwrap{display:flex;flex-wrap:wrap;align-items:center;
    gap:8px 14px}
  .client-headwrap .h-row,.client-headwrap .switches{display:contents}
  .client-headwrap [data-sw]{order:1}
  .client-headwrap .phones{order:2;flex-basis:100%;margin:0}
  .client-headwrap .trow{order:3;flex-basis:100%;margin:0}
  /* дубль-бейдж тари біля імені прибрати — той самий бутль тепер чіпом
     нижче, у «Підсумках» (.stat-tare). */
  .balance.tare{display:none}
  /* «Повторити останнє · склад · сума» — суфікс, dense-only. */
  .qa-rep-sum{display:inline}
  /* «Подзвонити» — тонована (мокет .btn.tinted), лише тут: .tinted —
     базово-активний клас (уживаний деінде без dense-гейту), тому колір
     додано напряму на #qa-call, а не через клас. */
  #qa-call{background:rgba(2,88,201,.08)}
  /* 5-й чіп «Тара у клієнта» в Підсумках — dense-only, з'являється лише
     коли сервер віддав c.tare_bottles>0 (JS уже не рендерить чіп інакше). */
  .stat-tare{display:inline-block}
  /* Секції картки — білі скруглені картки з рамкою (мокет .formbox). НЕ
     .formbox (той клас базово-активний — виняток сторінки «Нове
     замовлення», Задача 4) — нова назва, dense-only. */
  .card-sec{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);padding:16px 18px}
  /* Варіант для секцій із таблицею (Замовлення/Дзвінки) — заголовок і
     рядки самі несуть горизонтальний відступ (table.hist td), картці він
     не потрібен. */
  .card-sec.card-sec-table{padding:6px 0 0}
  .card-sec.card-sec-table .sechead{padding:10px 18px 4px;margin:0}
  /* Замовлення: «усі N →» у заголовку секції (мокет), розгортає повний
     список ПРЯМО в картці (JS: .expanded на #ord-table). */
  .ord-seeall{display:inline}
  #ord-table .ord-extra{display:none}
  #ord-table.expanded .ord-extra{display:table-row}
  /* Стан замовлення — піл-бейдж із заливкою (мокет), не голий кольоровий
     текст. Скоуп на #ord-table — та сама .st розмальовує ✓/→ на
     «Сьогодні»/«Машинах» (style.css вище), там пігулку заводити не
     просили. Нейтральний фолбек (немаплені легасі-статуси на кшталт «з
     розмови» — ORDER_ST_CLS[o.status] порожній) — той самий колір, що
     .badge.mut, щоб не лишати їх без рамки взагалі. */
  #ord-table .st{display:inline-block;border-radius:999px;border:1px solid;
    padding:2px 9px;font:700 12px/1.4 var(--font-body);white-space:nowrap;
    background:var(--surface);border-color:var(--border);color:var(--muted)}
  #ord-table .st.a{background:rgba(2,88,201,.08);
    border-color:rgba(2,88,201,.28);color:var(--blue)}
  #ord-table .st.d{background:var(--ok-bg);border-color:var(--ok-bd);
    color:var(--ok)}
  #ord-table .st.c{background:var(--danger-bg);border-color:var(--danger-bd);
    color:var(--danger)}
  /* Дзвінки картки: компактні рядки замість таблиці (мокет, «як на
     Сьогодні») — стара таблиця (.cc-old-table) і старий заголовок
     (.cc-old-head, з лічильником у тексті) ховаються, новий сечед з
     .hint2-лічильником і .callmini займають їхнє місце. */
  .cc-old-head,.cc-old-table{display:none}
  .cc-new-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .callmini{display:block}
  .callmini .cmrow{display:flex;align-items:center;gap:14px;
    padding:9px 18px;border-top:1px solid var(--border)}
  .callmini .cmrow:first-child{border-top:none}
  .callmini .cm-time,.callmini .cm-dur{font-variant-numeric:tabular-nums;
    color:var(--muted);font-size:13px}
  .callmini .cm-dur{margin-left:auto}
  .callmini .rec-play{margin-left:6px}

  /* ---- Хвиля відповідності макету, Задача 8 (Пульс/Карта/Обдзвін) ---- */

  /* Пульс item 3: «Тиждень/Місяць» одразу біля h1 (мокет .dayrow — без
     margin-right:auto штовхання, на відміну від базового .h-row h1). */
  .pulse-hrow h1{margin-right:0}
  /* item 1: плитки → пігулки — той самий компонент, що .today-head/
     .od-controlbar .stats/.fleet-chips вище (Задачі 1/3/5); обидва рядки
     «Сьогодні» і «За 7 днів» позначені .pulse-stats. */
  .pulse-stats .stat{display:inline-flex;align-items:baseline;gap:6px;
    padding:8px 14px}
  .pulse-stats .stat b{display:inline;font-size:17px;margin-top:0}
  .pulse-stats .stat-full{display:none}
  .pulse-stats .stat-short{display:inline}
  /* «Пропущені» — рожевий фон+червона рамка (мокет .statchip.alarm) в
     ОБОХ рядках «Сьогодні»/«За 7 днів» — Задача 8 явно вимагає danger
     тут (на відміну від Задачі 1, де Пульс за межами .today-head
     лишався амбер); .pulse-stats керує цим локально для сторінки. */
  .pulse-stats .stat.warn{background:var(--danger-bg);
    border-color:var(--danger-bd)}
  .pulse-stats .stat.warn b{color:var(--danger)}
  /* item: графік:боржники = 3:2 (мокет .pgrid) — власний клас, не займає
     інші сторінки з .cols.two. Селектор — ОБОВ'ЯЗКОВО .cols.two.pulse-grid
     (три класи, специфічність 0-0-3-0), інакше сайтове базове
     .cols.two{grid-template-columns:1fr 1fr} (специфічність 0-0-2-0,
     min-width:980px) переважає голий .pulse-grid (0-0-1-0) — живий вимір
     у пісочниці ловив рівно цей регрес (767px/767px замість 3:2). */
  .cols.two.pulse-grid{grid-template-columns:3fr 2fr}
  /* item: зелена смуга «Обмін із сайтом» — усередину картки графіка під
     графік (мокет .okline); стара повношира версія (.pulse-sync-outer)
     ховається тут, дублікат усередині картки (.pulse-sync-inline) —
     навпаки, з'являється (dual-render, обидві несуть той самий рядок
     syncBanner з app.js — тож зміст завжди однаковий). */
  .pulse-sync-outer{display:none}
  .pulse-sync-inline{display:block}
  .pulse-sync-inline .alert{margin:14px 0 0}
  /* item: нова примітка під таблицею боржників */
  .pl-note{display:block;color:var(--muted);font-size:13px;margin-top:10px}
  /* item: дії рядка боржника — іконка замість тексту (мокет .acts,
     hover-reveal, та сама дисципліна, що .odrow .od-acts/.fqrow
     .fq-acts вище); стара текстова кнопка ховається лише тут. */
  .debtrow .btn{display:none}
  .debtrow .debt-acts{display:flex;justify-content:flex-end;gap:6px;
    opacity:0;transition:opacity .1s}
  .debtrow:hover .debt-acts{opacity:1}

  /* Карта item 1: підсумок дня пігулками — та сама переробка компонента,
     що .today-head/.od-controlbar/.fleet-chips/.pulse-stats вище. */
  #map-summary .stat{display:inline-flex;align-items:baseline;gap:6px;
    padding:8px 14px}
  #map-summary .stat b{display:inline;font-size:17px;margin-top:0}
  /* item 2: легенда — вертикальний список карткою (мокет .box+.mlrow);
     стара горизонтальна чіп-легенда (#map-legend) ховається лише тут,
     нова (#map-legend-dense) з'являється. */
  #map-legend{display:none}
  #map-legend-dense{display:contents}
  /* Скоуп на #mapside — .legend (клас) РОЗДІЛЯЄ розмітку з міні-картою
     «Машин» (#fleet-legend, viewFleet), яку ЦЯ задача не чіпає: голий
     .legend{...} тут перефарбував би і ту легенду теж. */
  #mapside .legend{flex-direction:column;align-items:stretch;
    background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);padding:2px 0}
  .mlrow{display:flex;align-items:center;gap:9px;padding:8px 16px;
    font-size:13.5px;border-top:1px solid var(--border)}
  .mlrow .r{margin-left:auto;color:var(--muted);
    font-variant-numeric:tabular-nums}
  /* чекбокс — окремим рядком під пунктирним розділювачем (мокет), та
     сама .mlrow подача замість чіп-пігулки бази. */
  .mlrow-check{display:flex;background:none;border:none;border-radius:0;
    border-top:1px dashed var(--border);padding:10px 16px 6px}
  /* item: «Без мітки на карті» — однорядкові пункти з лінком праворуч
     (мокет), картка бази (nm/sub/trow) ховається лише тут. */
  #map-unresolved .row>.nm,#map-unresolved .row>.sub,
  #map-unresolved .row>.trow{display:none}
  #map-unresolved .mu-line{display:flex;align-items:center;gap:8px}
  #map-unresolved .mu-txt{min-width:0;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  #map-unresolved .mu-link{margin-left:auto;flex:none}
  /* «Без мітки на карті» — біла картка-рамка (мокет .box), та сама
     дисципліна, що .legend вище; скоуп на #mapside — .section
     використовується й деінде (Довідники/Картка), там форму не міняємо. */
  #mapside .section{background:var(--white);border:1px solid var(--border);
    border-radius:var(--r-md);border-top:1px solid var(--border);
    padding:10px 16px 12px}
  /* Рядки списку — суцільна картка з тонкими розділювачами, НЕ стос
     окремих карток-рамок (мокет: кожен пункт — просто рядок усередині
     ОДНІЄЇ .section-картки вище) — та сама дисципліна, що .t-orders
     .rows у Задачі 1 (самоперевірка знайшла це під час звірки з
     еталоном: без цього кожен рядок ніс власну рамку/скруглення .row
     бази — «картки в картці», а не пласкі рядки макету). */
  #map-unresolved .rows{gap:0}
  #map-unresolved .row{border:none;border-radius:0;background:none;
    padding:10px 16px}
  #map-unresolved .row+.row{border-top:1px solid var(--border)}

  /* Обдзвін item 3: кнопка «Подзвонили ✓» тонована (мокет .btn.tinted) —
     та сама дисципліна, що #qa-call (Задача 7): колір напряму на ID, не
     клас .tinted (він базово-активний, зачепив би й мобільний оверлей). */
  #obd-mark{background:rgba(2,88,201,.08)}
  /* телефон з пробілами (dual-render, база лишає суцільний рядок) */
  .obd-phone-fmt{display:inline}
  .obd-phone-raw{display:none}
  /* «випаде ЗІ СПИСКУ за N дн» — повне формулювання лише тут */
  .obd-cycle-short{display:none}
  .obd-cycle-full{display:inline}
}
/* міні-карта зверху — компактніша, ніж стара 40vh */
#drivermap{height:30vh;min-height:200px}

/* ── Рядки промокоду (docs/CRM-HANDOFF.md) ──────────────────────────────
   Знижка й подарований бутель приходять із сайту й лишаються НЕЗМІННИМИ:
   їх видно у формі оператора й водія, але редагувати не можна (сервер усе
   одно перевставляє їх із бази). Приглушений фон + замок = «це не поле,
   це факт замовлення», щоб ніхто не шукав, де тут ввести ціну. */
.promo-lines{margin-top:8px;border-top:1px solid var(--border);padding-top:8px}
.promo-line{background:rgba(2,88,201,.05);border-radius:8px;
  padding:8px 10px;gap:8px;align-items:center}
.promo-line+.promo-line{margin-top:4px}
.promo-line .pick-name{color:var(--muted)}
.promo-amt{font-weight:700;font-variant-numeric:tabular-nums;
  white-space:nowrap;margin-left:auto}
.promo-lock{opacity:.55;font-size:13px}
.promo-lines .hint{color:var(--muted);font-size:13px;margin:6px 2px 0}
