/* Оформлення медичного модуля. Окремим файлом, а не в styles.css: той зараз
   править інша сесія, і правка в чотири руки вже двічі коштувала часу.
   І не всередині med.js: CSS у рядку JS ламає перевірку осиротілих викликів —
   вона бачила var() і color-mix() як виклики неіснуючих функцій, 38 хибних тривог. */
/* ⚠ ВИРІЗ ТЕЛЕФОНА. Плашка стоїть найпершою в #app, тобто саме вона впирається
   в годинник і камеру. Без запасу зверху текст ховається під ними — власник
   показав знімком: видно «ПОКАЗОВИЙ ПРОХІД… о не зберігається», а заголовок
   екрана наполовину під вирізом.
   Той самий запас у застосунку вже стоїть на .header і .overlay — беремо ту саму
   змінну, щоб не розійтись. */
.med-flag{background:var(--text);color:var(--bg);font-size:11px;font-weight:700;
  text-align:center;padding:calc(5px + var(--safe-t)) 5px 5px;letter-spacing:.3px;
  position:relative;display:flex;align-items:center;justify-content:center;gap:8px}
/* Хрестик праворуч, поверх тексту: у вузькому екрані підпис займає всю ширину,
   і місця «поруч» для кнопки просто немає. */
.med-flag-x{position:absolute;right:4px;top:50%;transform:translateY(-50%);
  background:transparent;border:0;color:inherit;opacity:.75;cursor:pointer;
  display:flex;align-items:center;padding:6px}
.med-flag-x:hover{opacity:1}
.med-note{border-left:3px solid var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent);
  padding:10px 12px;font-size:13px;margin-bottom:12px}
.med-note b{display:block;margin-bottom:3px}
.med-warn{border-left:3px solid var(--danger);background:color-mix(in srgb,var(--danger) 10%,transparent);
  padding:10px 12px;font-size:13px;margin-bottom:12px}
.med-warn b{display:block;margin-bottom:3px}
.med-pill{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;
  font-size:11.5px;font-weight:700;white-space:nowrap}
.med-p-new{background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent-2)}
.med-p-work{background:color-mix(in srgb,var(--pend) 15%,transparent);color:var(--pend)}
.med-p-ok{background:color-mix(in srgb,var(--ok) 15%,transparent);color:var(--ok)}
.med-p-warn{background:color-mix(in srgb,var(--warn) 18%,transparent);color:var(--warn)}
.med-p-bad{background:color-mix(in srgb,var(--danger) 14%,transparent);color:var(--danger)}
.med-sla{font-size:11.5px;font-weight:700}
.med-sla.ok{color:var(--ok)}.med-sla.warn{color:var(--warn)}.med-sla.bad{color:var(--danger)}
.med-kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;
  border-bottom:1px solid var(--line-2);font-size:14px}
.med-kv:last-child{border-bottom:none}
.med-kv span{color:var(--muted)}.med-kv b{font-weight:700;text-align:right}
/* Рядок, який можна правити: поле займає праву частину і ВИГЛЯДАЄ як поле —
   інакше ніхто не здогадається, що туди можна натиснути. */
.med-kv-edit{align-items:center}
.med-kv-edit input,.med-kv-edit select{flex:1 1 55%;min-width:0;max-width:62%;
  border:1px solid var(--line);background:var(--surface);color:var(--text);
  border-radius:0;padding:6px 8px;font:inherit;font-size:14px;text-align:left}
/* 🔴 УСІ ПОЛЯ РЯДКА ОДНАКОВІ (17.09.2026). Власник: «поля з даними не мають іти до
   упору, а всі однаково в один ряд». Звичайні поля були до 62% з текстом праворуч,
   а переліки (звання, частина, відділ, посада) — кнопкою на всю ширину.
   Тепер будь-яке поле рядка — одна ширина, один лівий край, текст ліворуч. */
.med-kv-edit>span{flex:1 1 auto;min-width:0}
.med-kv-edit>:not(span){flex:0 0 60%;width:60%;max-width:60%;min-width:0;box-sizing:border-box}
.med-kv-edit>.picker-btn{min-height:0;padding:6px 8px;font-size:14px;border-radius:0}
.med-kv-edit>div input{width:100%;max-width:100%}
.med-step{display:flex;gap:10px;padding:10px 0;border-bottom:1px solid var(--line-2);font-size:13.5px}
.med-step .n{flex:0 0 22px;height:22px;border-radius:999px;background:var(--surface-2);
  color:var(--muted);font-size:11px;font-weight:800;display:flex;align-items:center;justify-content:center}
.med-step.done .n{background:var(--ok);color:#fff}
.med-step.now .n{background:var(--accent);color:#fff}
.med-step b{display:block;font-weight:700}
.med-step i{font-style:normal;color:var(--muted);font-size:12.5px}
.med-fld{display:block;margin-bottom:12px}
.med-fld>span{display:block;font-size:12.5px;font-weight:700;color:var(--muted);margin-bottom:5px}
.med-fld input,.med-fld select,.med-fld textarea{width:100%;padding:12px;border:1px solid var(--line);
  background:var(--surface);font:inherit;font-size:15px;color:var(--text);border-radius:0}
.med-fld textarea{min-height:76px;resize:vertical}

/* ⚠ Рядок зі строком висів ПОСЕРЕДИНІ рядка, хоча решта тексту зліва.
   Причина: сам рядок — це <button>, а в кнопки типове вирівнювання по центру;
   решту тексту рятували вкладені блоки, а цей лежав прямо в кнопці.
   Побачив на знімку, а не в розмітці — у розмітці все виглядало правильно. */
.med-sla{text-align:left}

/* Картка хворого — історія візитів. Те, заради чого модуль існує і що я
   пропустив у першому показі: медик читає це ПЕРЕД тим, як щось призначати. */
/* Знімок рентгена в особовій справі. Той самий вигляд, що й запис візиту:
   для медика це такий самий рядок історії, тільки джерело — тека на Диску. */
.med-shot{border-left:2px solid var(--line);padding:8px 0 8px 12px;margin-top:10px}
.med-shot:first-of-type{border-left-color:var(--accent)}
.med-shot-top{display:flex;justify-content:space-between;gap:12px;align-items:baseline;margin-bottom:4px}
.med-shot-top b{font-weight:700;font-size:14px}
.med-shot-top span{color:var(--muted);font-size:12.5px;white-space:nowrap}
/* Назва файлу може бути довга і без пробілів — рвемо, а не розсуваємо картку. */
.med-shot-name{color:var(--muted);font-size:12.5px;margin-bottom:6px;overflow-wrap:anywhere}
.med-shot .btn{text-align:center;text-decoration:none}
.med-visit{border-left:2px solid var(--line);padding:8px 0 8px 12px;margin-top:10px}
.med-visit:first-of-type{border-left-color:var(--accent)}
.med-visit-top{display:flex;justify-content:space-between;gap:12px;align-items:baseline;margin-bottom:4px}
.med-visit-top b{font-weight:700;font-size:14px}
.med-visit-top span{color:var(--muted);font-size:12.5px;white-space:nowrap}
.med-visit-line{color:var(--muted);font-size:13px;line-height:1.5}
.med-p-grey{background:var(--surface-2);color:var(--muted)}

/* ── ДОШКА СТАТУСІВ. Стовпці як у CRM, але гортаються вбік ────────────────────
   ⚠ Тягати пальцем не даємо навмисно: на 375 пікселях це промах на промаху, а
   кожен промах міняє стан живої заявки. Переміщення — кнопкою. */
/* Зовнішня коробка лише гортається; рядок стовпців — усередині. */
.med-board-in { display: flex; gap: 10px; align-items: stretch; min-height: 100%; }
/* 🔴 Відступ зверху — 0 (власник 24.09.2026: «перший рядок суцільний, без дірок»): шапка
   прилипає до краю вмісту дошки, і 4px відступу були щілиною, крізь яку над темною смугою
   проїжджали картки. */
.med-board { padding: 0 0 10px;
  -webkit-overflow-scrolling: touch; }
.med-col { flex: 0 0 210px; background: var(--surface-2); border: 1px solid var(--line);
  padding: 8px; display: flex; flex-direction: column; gap: 8px; }
/* ⚠ ШАПКА СТОВПЦЯ ЇДЕ ЗА ЛЮДИНОЮ. Власник: «коли я гортаю вниз, перший рядок
   має бути закріплений і крутитися разом зі мною». На довгому стовпці інакше
   незрозуміло, у якому ти статусі: назви лишились угорі, а картки під ними всі
   схожі.
   ⚠ top: 0 — бо прилипає вона до верху ДОШКИ, а не сторінки: саме дошка тепер
   те, що гортається. Спершу я поставив 55 (заміряна висота смуги пошуку) —
   і не спрацювало взагалі, бо рахунок іде не від сторінки.
   ⚠ Від'ємні поля компенсують падінг стовпця, щоб тло смуги дотягувалось до
   країв, — інакше крізь щілини по боках видно картки, що проїжджають під нею. */
.med-col-h { display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  position: sticky; top: 0; z-index: 6;
  /* ⚠ ТЕМНА, А НЕ СІРА. Власник: «першу строку ти закріпив, але давай її якось
     відділимо, чорною чи що, щоб виглядало нормально і око не ламало».
     Сіре тло шапки збігалося з тлом стовпця, і закріплений рядок читався як
     частина списку — картки просто зникали під ним без пояснення. Темна смуга
     каже сама за себе: це заголовок, а не ще одна картка. */
  background: var(--text); color: var(--bg);
  margin: -8px -8px 0; padding: 9px 10px;
  /* Суцільна смуга: тінь того самого кольору по 6px ліворуч і праворуч перекриває
     рамку стовпця (1px) і половину проміжку між стовпцями (5 з 10px) — сусідні шапки
     сходяться, і картки під ними не видно в щілинах. */
  box-shadow: -6px 0 0 var(--text), 6px 0 0 var(--text); }
.med-col-h b { font-weight: 700; }
.med-col-h span { color: var(--bg); opacity: .65; font-weight: 700; }
.med-col-empty { color: var(--faint); font-size: 12px; padding: 10px 0; text-align: center; }
.med-cardlet { background: var(--surface); border: 1px solid var(--line); }
/* Плановий огляд — синя смуга. Стоїть ДО «особливого»: якщо заявка і те, і
   те, червона смуга тривоги важливіша. */
.med-cardlet.check { border-left: 3px solid var(--med-check); }
.med-cardlet.special { border-left: 3px solid var(--danger); }
.med-cardlet-b { display: block; width: 100%; text-align: left; background: transparent;
  border: none; font: inherit; color: inherit; padding: 9px 10px; cursor: pointer; }
.med-cardlet-b b { display: block; font-size: 13.5px; font-weight: 700; }
.med-cardlet-b span { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.med-cardlet-b i { display: block; font-size: 11.5px; color: var(--faint); font-style: normal; margin-top: 3px; }
/* Підвид усередині стовпця «Особливий стан»: лазарет, домашнє лікування, інше. */
.med-cardlet-b .med-kind-sub { display: block; width: max-content; max-width: 100%; margin: 0 0 4px; padding: 2px 8px;
  border-radius: 6px; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.med-move { width: 100%; border: none; border-top: 1px solid var(--line); background: transparent;
  font: inherit; font-size: 11.5px; font-weight: 700; color: var(--accent-2); padding: 7px 8px;
  cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 4px; }
.med-move:active { background: var(--surface-2); }
.med-move svg { vertical-align: -2px; }

/* ── ГІСТОГРАМА: СТОВПЦІ, А НЕ СМУГИ ─────────────────────────────────────────
   ⚠ Спершу я зробив горизонтальні смуги і назвав це гістограмою. Власник
   поправив, і поправив по суті: горизонтальна смуга читається як «наскільки
   заповнено», а гістограма — це порівняння висот. Для питання «чого більше»
   потрібні саме стовпці: око порівнює висоти швидше за довжини, бо всі вони
   починаються з однієї лінії.
   Висота стовпця рахується в пікселях від сталої висоти поля, а не у відсотках:
   відсоток від батька, у якого висота задана вмістом, дає нуль. */
.med-cols { display: flex; align-items: flex-end; gap: 6px; padding: 6px 0 0; }
.med-col2 { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; min-width: 0; }
.med-col2 .v { font-size: 13px; font-weight: 800; line-height: 1.1; margin-bottom: 4px; }
.med-col2 .b { width: 100%; background: var(--accent); border-radius: 2px 2px 0 0; }
.med-col2 .b.bad { background: var(--danger); }
.med-col2 .b.zero { background: var(--line); }
.med-cols-base { height: 2px; background: var(--line); margin-top: 0; }
.med-cols-lbl { display: flex; gap: 6px; margin-top: 6px; }
.med-cols-lbl span { flex: 1 1 0; min-width: 0; font-size: 10px; line-height: 1.15;
  text-align: center; color: var(--muted); overflow-wrap: anywhere; }

/* Кільцева діаграма: показує ЧАСТКУ від цілого, і саме тому стоїть лише на
   «Звідки заявки». Загальне число — у центрі, щоб його не шукати по підписах. */
.med-donut { display: flex; justify-content: center; padding: 6px 0 10px; }
.med-share { color: var(--muted); font-weight: 400; }

/* ── ДОШКА НА ВЕСЬ ЕКРАН І РОБОТА З НОУТБУКА ──────────────────────────────────
   Власник: якщо обрано «Стовпцями», при вході в «Заявки» дошка має займати
   майже весь екран; і окремо — щоб застосунок був придатний з ноутбука.

   ⚠ ЗНІМАЄМО МЕЖУ ШИРИНИ ТІЛЬКИ ДЛЯ ДОШКИ, а не для всього застосунку. Списки
   лишаються вузькими навмисно: рядок на весь монітор читати важче, ніж рядок
   у колонці, і на телефоні вигляд не має відрізнятись. Дошка — інша річ: її
   сенс у тому, щоб бачити всі стовпці одразу. */
.page.med-wide { max-width: 100%; padding-left: 10px; padding-right: 10px; }
/* ⚠ ДОШКА ГОРТАЄТЬСЯ САМА, А НЕ РАЗОМ ЗІ СТОРІНКОЮ. Це не оформлення, а єдиний
   спосіб виконати вимогу «шапка стовпця закріплена і крутиться зі мною».
   Чому: у дошки вже стоїть overflow-x для гортання вбік, а елемент із overflow
   стає для своїх нащадків тим, відносно чого рахується прилипання. Тобто шапка
   всередині стовпця прилипала до ДОШКИ, а гортали ми сторінку — і шапка просто
   їхала вгору разом із усім. Заміряно: після прокрутки на 800 верх шапки був
   -588, тобто вона пішла за екран.
   Тому вертикальну прокрутку віддаємо самій дошці: висота фіксована, всередині
   гортається і вгору-вниз, і вбік, а шапки стовпців прилипають до її верху.
   ⚠ 300 — та сама межа, що була: шапка, пошук, нижнє меню і рядок підказки. */
/* ⚠ ВИСОТА БІЛЬШЕ НЕ ВІДНІМАЄТЬСЯ ЧИСЛОМ. Було calc(100dvh - 300px) — число,
   підібране під шапку, пошук, меню і підпис під дошкою. Підпис прибрали, і
   внизу лишилась порожня смуга; власник побачив це одразу: «таблиця не на весь
   екран іде». Будь-яке таке число застаріває при першій же зміні поруч.
   Тепер дошка просто займає ВСЕ, що лишилось: сторінка — колонка на всю висоту,
   дошка в ній тягнеться. min-height: 0 обовʼязково, інакше елемент, що
   розтягується, не дає собі стиснутись до розміру батька і прокрутка не
   зʼявляється взагалі. */
.page.med-wide { display: flex; flex-direction: column; height: 100%; }
.med-wide .med-board { flex: 1 1 auto; min-height: 0; overflow: auto; }
.med-wide .med-col { flex: 0 0 220px; }

/* На широкому екрані стовпці ділять ширину порівну і гортати не треба взагалі.
   220px — нижня межа, за якою підпис заявки перестає читатись. */
@media (min-width: 1000px) {
  .med-wide .med-col { flex: 1 1 0; min-width: 190px; }
}

/* ⚠ ГОРТАННЯ ВБІК ЛИШАЄТЬСЯ ЗАВЖДИ, і це виправлення справжньої вади, а не смак.
   Було `overflow-x: visible` від 1000 пікселів — на думку, що стовпці однаково
   вміщаються. Не вміщаються: сім стовпців по 200 плюс шість проміжків дають
   1460 при доступних 1420, і сьомий стовпець «Не вийшов на зв'язок» просто
   зрізало правим краєм — на знімку його не було видно цілком. З `auto` він або
   вміщається, або до нього можна догорнути; зникнути він не може.
   190 замість 200 — щоб на екрані 1440 сім стовпців таки вмістились без смуги
   гортання: 7×190 + 6×10 = 1390 при 1420 доступних. */
.med-wide .med-board { overflow-x: auto; }

/* ══════════════ КОЛИ ВІДКРИЛИ З НОУТБУКА ══════════════════════════════════
   ⚠ ЗАСТОСУНОК ЗРОБЛЕНО ПІД ТЕЛЕФОН, і на широкому екрані це видно одразу:
   вузька колонка 760 пікселів посередині, а обабіч — порожньо на пів екрана.
   Вміст при цьому не більший, лише поля довкола. Виглядає як розтягнутий
   телефон, а не як робочий застосунок.

   ⚠ ПРАВИЛА ЛИШЕ ДЛЯ МЕДИЧНОГО МОДУЛЯ. Оболонка спільна з УДЗ, і міняти її
   ширину означало б перемалювати чужий модуль без прохання. Тому чіпляємось
   за клас `.med-page`, який модуль кладе на свою сторінку сам.

   ⚠ МЕЖА 1100, А НЕ 760. На 800–1000 (планшет, півекрана на ноутбуці) дві
   колонки дають по 400 пікселів — картка з гістограмою в них не читається.
   Краще одна широка колонка, ніж дві тісні. */
@media (min-width: 1100px) {
  .med-page { max-width: 1240px; padding: 16px 20px 0; }

  /* ⚠ СПИСОК — ОДНА КОЛОНКА, І ЦЕ РІШЕННЯ ВЛАСНИКА, А НЕ ЗАМОВЧУВАННЯ.
     Я був зробив дві колонки, щоб «використати ширину». Власник подивився на
     проді і сказав прямо: «заявки не должни бить в два столбца, расширь в 1 и
     просто больше данних з заявки виведи». Тобто ширина потрібна не для того,
     щоб умістити ДВА рядки поруч, а щоб в ОДНОМУ рядку вміщалось більше про
     людину. Друга сесія попереджала про це до правки — і мала рацію.
     Тому тут не лишилось нічого: список успадковує звичайну одну колонку,
     просто ширшу разом зі сторінкою. */

  /* «Зведення» — дві колонки. Календар, гістограми і кільце стоять поруч, а не
     стрічкою на пів екрана вниз: власник дивиться на них разом, а не по черзі. */
  .med-page:has(.cal-card) {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 20px; align-content: start;
    /* ⚠ ЧОТИРИ КАРТКИ ОДНАКОВІ ЗА РОЗМІРОМ. Власник: «ці 4 блоки теж мають бути
       однакові, переробіть, щоб були одного розміру». Раніше тут стояло
       align-items: start, і кожна картка була заввишки рівно під свій вміст —
       гістограма вища, кільце нижче, склад ще нижчий. Виглядало як недороблена
       сітка.
       stretch вирівнює картки в межах рядка, а min-height — між рядками. Число
       підібране під найвищу з чотирьох, щоб жодну не обрізало. */
    align-items: stretch;
  }
  /* На всю ширину лишається те, що ділити не можна: плитки, заголовок розділу,
     пошук із фільтрами і підсумковий рядок. */
  .med-page:has(.cal-card) > .kpis,
  .med-page:has(.cal-card) > .stats-title,
  .med-page:has(.cal-card) > .filters,
  .med-page:has(.cal-card) > .list-meta,
  .med-page:has(.cal-card) > .hint,
  /* ⚠ КАЛЕНДАР — НА ОБИДВІ КОЛОНКИ. У половині ширини клітинка дня стискається
     до розміру, у якому число вже не прочитати, а сам місяць — головне, на що
     тут дивляться. Пряма вимога власника: «календарь все равно должен бить на
     всю ширину как 2 столбца. только он» — саме він, решта карток лишається
     у дві колонки. */
  .med-page:has(.cal-card) > .cal-card { grid-column: 1 / -1; }
  .med-page:has(.cal-card) > .card:not(.cal-card) { min-height: 330px; }

  /* ⚠ І ОДРАЗУ ВИСОТА КЛІТИНКИ. Клітинка дня квадратна (`aspect-ratio: 1`), і це
     правильно на телефоні: там ширина клітинки — сьома частина від 390. Коли
     календар розтягнувся на 1200, клітинка стала 165×165, а місяць — заввишки
     на півтора екрана, з величезними порожніми полями довкола числа. Знімок це
     показав одразу. Тому на широкому екрані клітинка перестає бути квадратом. */
  /* ⚠ ВИСОТА ВІД ЕКРАНА, А НЕ СТАЛА. Було 74 пікселі — на моєму знімку
     місяць уміщався, а у власника при 100% масштабі нижні тижні пішли під
     нижнє меню. Стала висота підходить рівно під ту висоту вікна, на якій її
     підбирали, і ні під яку іншу.
     Тепер клітинка міряється від висоти вікна: 5.5vh, але не менша за 30 і не
     більша за 56 — нижче числа не читаються, вище місяць знову не вміщається. */
  .med-page .cal-card .cal-cell { aspect-ratio: auto; height: clamp(30px, 5.5vh, 56px); }
  .med-page .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Панель фільтрів: чотири пікери в рядок замість сітки 2×2 — на широкому
     екрані вони й так уміщуються, а панель стає вдвічі нижчою. */
  .med-page .filter-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* ⚠ ДОДАТКОВІ ПОЛЯ ЗАЯВКИ. На телефоні їх немає взагалі (правило нижче ховає
     рядок), бо там кожен зайвий рядок відсуває наступну заявку за край екрана.
     На ноутбуці місце є — і замість порожнечі посередині рядка людина бачить
     номер, телефон, терміновість і звідки заявка прийшла. */
  .med-page .rec-wide { display: flex; }

  /* ⚠ У СТОРІНКИ ТУТ ІНШІ ПАДІНГИ (16/20 замість 12/12), тому від'ємні поля
     липкої смуги мусять збігтись із ними — інакше тло не дотягнеться до країв
     і крізь щілини по боках буде видно текст, що проїжджає під смугою. */
  .med-page .med-back { margin: -16px -20px 0; padding: 16px 20px 8px; }
  /* Падінг зверху тут 16, а не 12, тому смуга на чотири пікселі вища: 16+46+8. */
  .med-page .med-back + .filters { top: 70px; }

  /* Гістограми вищі: місце є, а вища смуга точніше показує різницю. */
  .med-page .med-cols { height: 180px !important; }
  .med-page .med-cols-lbl span { font-size: 11.5px; }

  /* Накладка (картка заявки, картка хворого) теж не має бути на весь екран:
     читати рядок завдовжки 1400 пікселів незручно. */
  /* ⚠ НАКЛАДКА НЕ ВСЕРЕДИНІ СТОРІНКИ. Її кладуть у `body`, а не в `.med-page`,
     тому `.med-page .overlay` не спрацював би НІКОЛИ — правило було б мертве.
     Чіпляємось за плашку показу: вона теж у body і теж тільки в медичного. */
  body:has(.med-page) .overlay .form-body > * {
    max-width: 900px; margin-left: auto; margin-right: auto;
  }
}

/* Миша, а не палець: підсвічування рядка під курсором. На телефоні цього блоку
   не буде взагалі — hover там або не існує, або «залипає» після дотику. */
@media (hover: hover) and (pointer: fine) {
  .med-page .rec:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
  .med-page .pill:hover,
  .med-page .field-sel:hover { border-color: var(--accent); }
  .med-page .med-cardlet:hover { border-color: var(--accent); }
}

/* ══════════════ ПЕРЕТЯГУВАННЯ КАРТОК ПО ДОШЦІ ═════════════════════════════
   Власник: «переделай етот вид, что би там можно било мишкой или с телефона
   рукой передвигать их. и кнопку убери она дает только в одну сторону».

   ⚠ touch-action: pan-y — НЕ ОФОРМЛЕННЯ, А УМОВА РОБОТИ ПАЛЬЦЕМ. Пояснення
   повністю — у коментарі до boardView() в med.js. Коротко: гортання
   вгору-вниз лишається браузеру, рух убік забирає застосунок. */
.med-cardlet.drag { touch-action: pan-y; cursor: grab; }

/* Картка, яку зараз тягнуть, лишається на місці бліда — щоб було видно,
   ЗВІДКИ забрали, поки двійник летить за пальцем. */
.med-cardlet.is-dragging { opacity: .3; border-style: dashed; }

/* Двійник, що летить за вказівником. pointer-events: none обовʼязково: інакше
   під пальцем завжди був би він сам, і стовпець-приймач не визначався б. */
.med-cardlet.drag-ghost {
  position: fixed; left: 0; top: 0; z-index: 70; pointer-events: none;
  opacity: .95; rotate: -1.5deg;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .3);
}

/* Стовпець під вказівником. Підсвічування має бути помітним саме на телефоні,
   де палець закриває половину екрана, — тому рамка, а не лише відтінок. */
.med-col.is-over {
  outline: 2px dashed var(--accent); outline-offset: -2px;
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-2));
}

/* Поки тягнемо — не даємо браузеру виділяти текст під пальцем і мишкою. */
body.med-dragging { cursor: grabbing; user-select: none; -webkit-user-select: none; }
body.med-dragging .med-cardlet.drag,
body.med-dragging .med-cardlet-b { cursor: grabbing; }

/* Рядок «Скасувати» після переміщення. Стоїть НАД дошкою, а не спливає знизу:
   спливне зникає само, а тут людина має встигнути помітити промах. */
.med-undo {
  display: flex; align-items: center; gap: 8px; margin: 0 0 8px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
  font-size: 13px;
}
/* Той самий рядок, але про СПРАВЖНЮ заявку: попередження, а не підтвердження. */
.med-undo > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.med-undo-go {
  flex: 0 0 auto; background: transparent; border: 1px solid var(--accent);
  color: var(--accent); font-weight: 700; font-size: 12.5px;
  padding: 5px 10px; border-radius: 8px; cursor: pointer;
}
.med-undo-x {
  flex: 0 0 auto; background: transparent; border: 0; color: var(--muted);
  display: flex; align-items: center; padding: 4px; cursor: pointer;
}

/* Додаткові поля в рядку заявки. Схований за замовчуванням — показує його лише
   правило для широкого екрана вище. */
.rec-wide {
  display: none; flex-wrap: wrap; gap: 4px 18px; margin-top: 6px;
  font-size: 12px; color: var(--muted);
}
.rec-wide > span { white-space: nowrap; }
.rec-wide > span > b { font-weight: 700; color: var(--text); }
/* Підпис поля. `i` тут не курсив, а просто другий рівень тексту — саме так
   зроблено в решті модуля (див. .med-cardlet-b i). */
.rec-wide > span > i { font-style: normal; }

/* Позначка справжньої заявки — щоб вона не губилась серед показових. */

/* ══════════════ ЛИПКА КНОПКА «НАЗАД» ══════════════════════════════════════
   Прокрутка живе в `.content` (flex: 1; overflow-y: auto), тому `top: 0` — це
   верх видимої частини сторінки, одразу під шапкою модуля. Смуга з тлом
   сторінки, а не прозора: інакше під кнопкою просвічував би текст, що їде. */
.med-back {
  position: sticky; top: 0; z-index: 26;
  margin: -12px -12px 0;            /* компенсуємо падінги .page, щоб тло було на всю ширину */
  padding: 12px 12px 8px;
  background: var(--bg);
}
.med-back .btn { display: inline-flex; align-items: center; gap: 6px; }

/* ⚠ ДВІ ЛИПКІ СМУГИ НА ОДНОМУ НУЛІ. У картотеці одразу за кнопкою йде пошук із
   фільтрами, і він теж липкий з `top: 0`. Без зміщення вони накладаються — я це
   вже отримав: смуга закінчувалась на 146, а фільтри починались на 131.
   Числа заміряні в браузері, не на око: 12 + 46 (висота кнопки) + 8 = 66. */
.med-back + .filters { top: 66px; }

/* Позначка на картці дошки: заявка справжня, і статус їй поки нікуди зберігати.
   Стоїть ДО перетягування, а не після — див. коментар у boardView(). */

/* ── ЗАЯВКА — ОКРЕМА КАРТКА, А НЕ РЯДОК У СТРІЧЦІ ─────────────────────────────
   Власник: «заявки слитие в одну кашу». І він правий: спільний вигляд списку
   малює лише тонку риску знизу, а в медичній заявці чотири-пʼять рядків тексту
   різного розміру — риски між ними не видно взагалі, усе читається як один
   суцільний абзац.
   Тому в медичному модулі кожна заявка — картка з власною межею і проміжком.
   ⚠ Правило звужене до `.med-page`: спільний список УДЗ виглядає так, як і був. */
.med-page .rec-list { display: flex; flex-direction: column; gap: 10px; }
.med-page .rec.med-rec {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 12px 14px;
  box-shadow: var(--shadow);
}
.med-page .rec.med-rec:active { background: var(--surface-2); }

/* Смуга збоку відповідає на питання «чи це справжня людина» ще до читання. */
/* ⚠ Смуги «справжня заявка» більше немає: власник сказав, що всі заявки мають
   іти як справжні. Лишилась тільки червона — особливий випадок. */
.med-page .rec.med-rec.check {
  border-left: 3px solid var(--med-check);
  background: color-mix(in srgb, var(--med-check) 6%, var(--surface));
}
.med-page .rec.med-rec.special { border-left: 3px solid var(--danger); }

/* ══════════════ ДОСТУПНІСТЬ ═══════════════════════════════════════════════
   Розбір за скілом `accessibility-craft` дав три справжні провали, і всі три —
   наслідок того, що кнопку-стрілку замінили жестом.

   ⚠ 1. ТЕКСТ ЛИШЕ ДЛЯ ПРОГРАМИ ЧИТАННЯ ЕКРАНА. Не `display: none` і не
   `visibility: hidden` — обидва ховають вміст і від читалки теж. Потрібен саме
   цей прийом: вузол лишається в дереві доступності, але не займає місця. */
.med-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  border: 0;
}

/* ⚠ 2. ВИДИМОГО ФОКУСА В ЗАСТОСУНКУ НЕ БУЛО ВЗАГАЛІ. У styles.css є лише
   `.inp:focus` — тобто людина, яка ходить із клавіатури, не бачила, ДЕ вона
   зараз, на жодній кнопці, вкладці чи картці. Це вимога WCAG 2.4.7, і без неї
   перетягування з клавіатури безглузде: перш ніж натиснути стрілку, треба
   бачити, яку картку тримаєш.
   `:focus-visible`, а не `:focus` — щоб рамка не спалахувала від миші.
   Обмежено медичним модулем: styles.css спільний з УДЗ, а міняти чужий модуль
   без прохання не можна. Про те, що діра загальна, сказано власнику окремо. */
.med-page :focus-visible,
.med-back :focus-visible {
  outline: 3px solid var(--accent-2);
  outline-offset: 2px;
}

/* ⚠ 3. КАРТКА, ЯКУ ТРИМАЄ КЛАВІАТУРА, має бути помітна не лише рамкою: на
   дошці з сімома стовпцями рамка губиться серед меж стовпців. */
.med-cardlet:has(.med-cardlet-b:focus-visible) {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}

/* Статус і галочка CRM — в одному стовпчику справа, як у списку УДЗ. */
.med-page .med-rec-right { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* ══════════ ЩО ЗГОРТАЄТЬСЯ — МАЄ ПРО ЦЕ СКАЗАТИ ═══════════════════════════
   ⚠ Власник: «тут має бути намальована стрілка вниз, щоб зрозуміло, що якщо
   натиснути — розкриється». Він правий: заголовок без жодної позначки нічим не
   відрізняється від звичайного підпису, і натиснути на нього нікому не спаде.
   Рідну позначку браузера ховаємо і малюємо свою: вона однакова в усіх
   браузерах і повертається при розкритті, тобто показує ще й ПОТОЧНИЙ стан. */

/* ══════════ СТАЛА СІТКА В РЯДКУ ЗАЯВКИ ══════════════════════════════════════
   ⚠ Головне тут — що поле НЕ ЗНИКАЄ, коли воно порожнє. Раніше правило
   «порожнє не показуємо» давало картки різної висоти: заявка з QR-коду мала
   одні поля, з CRM інші, і список читався як набір різних карток. Тепер
   чотири комірки стоять завжди, а порожня показує прочерк. */
.rec-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 14px; margin-top: 6px; }
.rec-cell { min-width: 0; display: flex; gap: 6px; align-items: baseline;
  font-size: 12.5px; overflow: hidden; }
.rec-cell > i { font-style: normal; color: var(--faint); flex: 0 0 auto; }
/* ⚠ НА ТЕЛЕФОНІ ЗНАЧЕННЯ ПЕРЕНОСИТЬСЯ, А НЕ ОБРІЗАЄТЬСЯ. У комірці 154 пікселі,
   і «Найближчими днями» з обрізанням перетворювалось на «Найближ…» — тобто поле
   є, а прочитати його не можна. Хай краще картка буде на рядок вища. */
.rec-cell > b { font-weight: 600; color: var(--text); min-width: 0;
  overflow-wrap: anywhere; }
/* На широкому екрані місця вистачає, і однорядкові комірки тримають сітку
   рівною. */
@media (min-width: 1100px) {
  .med-page .rec-cell > b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
/* Прочерк не має важити стільки ж, скільки значення: інакше око читає його
   як дані. */
.rec-cell > b.none { color: var(--faint); font-weight: 400; }

/* На ноутбуці місця більше — усі поля в один ряд. З 23.09.2026 їх три:
   телефон переїхав у рядок під назвою (.med-who), поруч із ПІБ. */
@media (min-width: 1100px) {
  .med-page .rec-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ══════════ ПІБ І ТЕЛЕФОН ПІД ПОЗИВНИМ (23.09.2026) ═════════════════════════
   Власник: заявка — «з позивним, ПІБ і номером телефону». Назва лишається
   позивним, під нею дрібніше — ПІБ · телефон. Переноситься, а не обрізається:
   на телефоні 390 px довге ПІБ з номером у рядок не влазить, а обрізаний номер
   — це номер, за яким не подзвониш. */
.med-who { font-size: 12.5px; line-height: 1.35; color: var(--muted); margin-top: 2px; overflow-wrap: anywhere; }
/* Ліва частина рядка має право стискатись — інакше довге ПІБ виштовхнуло б
   статус за край картки. */
/* ⚠ text-align: left ОБОВʼЯЗКОВО: рядок — це <button>, а в кнопці текст за
   замовчуванням по центру. Поки ліва частина мала ширину свого вмісту, цього не
   було видно; розтягнута — центрувала назву і скаргу (спіймано знімком 390 px). */
.med-rec-who { min-width: 0; flex: 1 1 auto; text-align: left; }
.med-cardlet-b .med-who { font-size: 11.5px; margin-top: 1px; }
/* ⚠ У шапці картки цього рядка немає навмисно — див. overlay() у med.js
   (26.08.2026, власник: «верх текст убрать»). */

/* ══════════ РИСКА МІЖ РОБОЧИМИ І ЗАКРИТИМИ ══════════════════════════════════
   Власник: закриті мають бути видні, але окремо — «щоб було видно, що нових
   заявок немає, а це старі». Тому не просто відступ: горизонтальна лінія з
   підписом посередині читається як межа, а відступ — як випадкова порожнеча. */
.med-split { display: flex; align-items: center; gap: 10px; margin: 18px 0 6px; }
.med-split::before, .med-split::after {
  content: ''; flex: 1 1 auto; height: 1px; background: var(--line);
}
.med-split > span {
  flex: 0 0 auto; font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint);
}
/* Закриті трохи приглушені: вони на екрані для довідки, а не для роботи. */
.med-closed .rec-name { color: var(--muted); }
.med-closed .rec { opacity: .82; }

/* ══════════ ПОЛЕ ДІАГНОЗУ З ПІДКАЗКОЮ МКХ-10 ════════════════════════════════
   Зроблено як стаття засудження в УДЗ: набираєш — бачиш збіги, обираєш —
   підтягується код і повна назва. Перелік лежить НАД полем за потоком, тому
   ховається при втраті фокуса: інакше він висить над рештою форми. */
/* 🔴 ТУТ БУВ ВЛАСНИЙ ВИПАДНИЙ ПЕРЕЛІК ДІАГНОЗІВ (.med-diag*). Прибрано
   24.08.2026 разом із самим віджетом: поле «Діагноз» тепер відкриває те саме
   вікно вибору, що й «Стаття засудження» в УДЗ (Options.openPicker), а його
   стилі живуть у styles.css як .picker-btn / .picker-list / .picker-row.
   Свій віджет коштував пів дня і трьох невдалих спроб власника вибрати діагноз:
   спершу `display:''` вмикав `display:none` звідси ж, потім перелік мовчав, поки
   не надрукуєш два знаки. Довелось викинути і зробити так, як просили спочатку. */

/* ══════════ ОБЛІК ЛІКІВ У НАЙМЕНШИХ ОДИНИЦЯХ ════════════════════════════════
   Власник 24.08.2026: «в упаковці може бути 50 таблеток, у ній 5 пластинок.
   вони дали не пластинку, а 4 з них вирізали — а це воно не враховує».
   Звідси три речі на екрані, яких раніше не було: одиниця біля числа, швидкі
   кнопки «пластинка / упаковка» і рядок складу з будовою під назвою. */
.med-qty { display: flex; align-items: center; gap: 8px; }
.med-qty > input { flex: 1 1 auto; min-width: 0; }
.med-qty > select { flex: 1 1 auto; min-width: 0; }
.med-qty-u { flex: 0 0 auto; color: var(--muted); font-size: 13px; font-weight: 700; }
.med-qty-fast { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

/* Дрібна кнопка: у застосунку її не було, а тут потрібна — «пластинка · 10»
   поруч із полем не може важити стільки ж, скільки «Створити заявку». */
.btn.small { padding: 5px 10px; font-size: 12.5px; width: auto; display: inline-flex; }

.med-stock-row { padding: 8px 0; border-bottom: 1px solid var(--line-2); }
.med-stock-row:last-child { border-bottom: none; }
.med-stock-row .hint { margin-top: 2px; }
/* Позиція без описаної упаковки — не помилка, але й не норма: видно, що її ще
   не описали, і це не змішується зі звичайним поясненням. */
.med-faint { color: var(--faint); font-style: italic; }

/* Телефон в анкеті — рівно як у публічній формі за QR: прибитий «+38» і десять
   цифр. Раніше тут стояло вільне поле на 20 знаків, куди лізли дужки й пробіли,
   і «+380 (67) 12» виглядало заповненим. */
.med-tel { display: flex; align-items: stretch; }
.med-tel-pre { display: flex; align-items: center; padding: 0 13px;
  border: 1px solid var(--line); border-right: none; background: var(--surface-2);
  color: var(--muted); font-weight: 700; font-size: 15px; }
.med-fld .med-tel input { border-left: none; letter-spacing: .08em; }

/* Захист від повторення 24.08.2026: клас `.field-sel` з УДЗ прибиває висоту
   38px і display:flex (він писався для div, не для справжнього select), а
   `.med-fld select` додає 12px відступу всередину. Разом це обрізало текст у
   полях вікна «Комбінований тест». Якщо колись знову зійдуться — не обріже. */
.med-fld select.field-sel, .modal-body select.field-sel {
  display: block; height: auto; padding: 12px; }

/* Кілька препаратів за один прийом. Власник: «потрібно після вибраного щоб
   зʼявлявся плюс, щоб додати ще». Рядки додаються, а не перемальовуються —
   інакше стерли б уже вписане в попередніх. */
.med-meds-row { padding-bottom: 6px; }
/* Ліки — меню з пошуком (як «Діагноз»), кнопка на всю ширину рядка (24.09.2026). */
.med-drug-btn { width: 100%; }
.med-meds-row + .med-meds-row { border-top: 1px dashed var(--line-2); padding-top: 10px; }
.med-meds > .btn.small { margin-top: 2px; }

/* Рентген: поле знімка зʼявляється лише після «робили». */
.med-xray { margin-top: 8px; }
.med-xray-prev { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.med-xray-prev img { max-width: 100%; max-height: 220px; border: 1px solid var(--line); }

/* ══════════ ВИДАЧА ЛІКІВ: ОДИН РЯДОК ЗАМІСТЬ ТРЬОХ ══════════════════════════
   Власник 24.08.2026 прислав знімок: під полем «Скільки видали» стояли кнопка
   упаковки, окремим рядком підказка і ще нижче «Додати ще». Три рядки на те, що
   читається за секунду. Тепер усе в одну лінію з переносом. */
.med-qty-fast { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.med-qty-note { margin: 0; }
/* «＋ Додати ще» окремим рядком під довідкою — власник 24.08.2026 по знімку.
   Перший рядок відповідає на «скільки в упаковці і скільки лишилось», другий —
   це вже інша дія, про інший препарат. */
.med-qty-more { margin-top: 6px; }

/* 🔴 ОДНАКОВІ КНОПКИ. Власник: «упаковка і додати ще не одного розміру».
   Так і було: обидві мали клас .btn.small, але «Додати ще» ще й font-weight:700,
   а різна жирність при однаковому padding дає різну ширину напису і різну
   висоту рядка. Тому висоту і відступи прибиваємо однаковими явно, а виділення
   лишається кольором — воно й було потрібне. */
.med-qty-fast .btn.small, .med-qty-more .btn.small {
  min-height: 30px; padding: 5px 12px; line-height: 18px;
  align-items: center; justify-content: center; }

/* «Додати ще» — єдина дія в цьому рядку, тому вона й виділена кольором.
   Решта поруч — довідка, а не дія. */
.btn.small.med-add-more { color: var(--accent); border-color: var(--accent); font-weight: 700; }
.btn.small.med-add-more:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* ══════════ ЧЕРНЕТКА АНКЕТИ ═════════════════════════════════════════════════
   Власник 24.08.2026: анкета має памʼятати набране при перемиканні вкладок.
   Смуга потрібна не для краси: без неї людина не розуміє, ЧОМУ в полях уже щось
   стоїть, і може прийняти чужу чернетку за нову анкету. */
.med-draft { display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 0 0 12px; padding: 10px 12px; font-size: 13px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-left: 3px solid var(--accent); color: var(--text); }
.med-draft > span { flex: 1 1 220px; min-width: 0; }

/* Дві дії про ту саму людину в одному рядку, кожна на пів ширини — власник
   24.08.2026. На вузькому екрані стають одна під одною самі: два написи по
   25 знаків поруч на телефоні не вміщаються. */
.med-two { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.med-two > .btn { width: 100%; margin: 0; white-space: normal; min-height: 44px; }
/* 🔴 БУЛО: нижче 560 px пара кнопок ставала стовпчиком. Власник просив саме
   рядок — «на половину ширини, а на другу половину постав». Накладка картки
   вужча за 560, тому правило спрацьовувало ЗАВЖДИ і його прохання не
   виконувалось ніколи. Лишаємо два стовпці; переносимо на стовпчик лише на
   зовсім вузьких екранах, де 44 px висоти вже не вистачить на підпис. */
@media (max-width: 340px) { .med-two { grid-template-columns: 1fr; } }
/* 🔴 ТРЕТЯ КНОПКА — НА ВСЮ ШИРИНУ (власник 17.09.2026): «якщо 3 кнопки, не
   роби їх як на 4 розраховано, щоб потім одне місце було зайвим. одну з них
   на ширину двох роби». Непарна остання кнопка займає обидва стовпці, і
   порожнього огризка в ряду не лишається. */
.med-two > .btn:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* Поле з помилкою — червона рамка. Показуємо лише коли дата вже повна:
   сваритись на кожен набраний знак означає сваритись увесь час. */
.med-bad input { border-color: var(--danger, #dc2626); }

/* ══════════ ДВІ ДІЇ ВНИЗУ АНКЕТИ ════════════════════════════════════════════
   Власник 24.08.2026: «в кінці там де створити анкету зроби на пів ширини і
   додай другий варіант "Очистити анкету"».
   Обидві по половині — це не косметика: рівна ширина каже, що вибір справжній,
   а не «головна кнопка і щось дрібне поруч». На вузькому екрані стають одна під
   одною, бо дві кнопки по 45 пікселів завширшки не натиснути пальцем. */
.med-actions { display: flex; gap: 10px; }
.med-actions > .btn { flex: 1 1 0; min-width: 0; margin: 0; }
/* «Очистити анкету» — квадратна кнопка з гумкою, закріплена праворуч над нижнім
   меню: стерти можна будь-коли, не гортаючи до кінця форми (власник 24.09.2026). */
.med-clear-fab { position: fixed; right: 16px; bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  width: 48px; height: 48px; min-width: 48px; padding: 0; margin: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); box-shadow: 0 2px 10px rgba(0,0,0,.18); }
@media (max-width: 380px) {
  .med-actions { flex-direction: column; }
}

/* ══════════ ВІКНО З ФОРМОЮ — ШИРШЕ ══════════════════════════════════════════
   Власник 24.08.2026 прислав знімок вікна «Нове звернення · Мельник Андрій
   Вікторович» і сказав: «шире сделай». На знімку видно чому — заголовок
   переноситься на два рядки, поля стиснуті, збоку смуга прокрутки. У вікні при
   цьому ціла анкета: діагноз, рентген, ліки.
   ⚠ Ширшими стають ЛИШЕ вікна з полями форми. Підтвердження на один рядок
     («Очистити анкету?») розтягнуте на пів екрана читалось би гірше, а не краще.
     Тому :has(.med-fld), а не загальна ширина всіх вікон. `:has` у цьому файлі
     уже вживається в десяти місцях, нової залежності не зʼявляється. */
/* 🔴 ПЕРЕПИСАНО 24.08.2026 ЗА ПРЯМИМ СЛОВОМ ВЛАСНИКА. Спершу він сказав
   «зроби ширше в півтора раза для ноута і 90 відсотків екрана для телефона»,
   а тоді сам себе виправив: «хоча ні. давай скрізь на 90 відсотків від
   максимуму скрізь».
   Тому 90 відсотків ширини екрана — УСІМ вікнам, а не лише тим, що з формою.
   ⚠ Це стосується і вікна підтвердження: на широкому моніторі питання на один
     рядок теж стане на 90 відсотків екрана. Я вважав це зайвим і зробив був
     інакше — але це його екран і його рішення, а моє «краще знаю» тут не
     аргумент. Сказав йому наслідок вголос; захоче назад — один рядок.
   ⚠ max-width, а не width: у .modal-card уже стоїть width:100%, і саме
     max-width досі тримав його на 420. Міняємо межу, а не спосіб. */
.modal-card,
.modal-card:has(.med-fld) { max-width: 90vw; }

/* ══════════ ТЕЛЕФОН — ВОРОТА АНКЕТИ ═════════════════════════════════════════
   Власник 24.08.2026: «поки це поле не заповнене, жодне інше поле в анкеті
   заповнювати не можна, крім ПІБ» і «перевіряти, чи немає вже такого за
   номером — якщо знайшлось, пропонувати перейти в його анкету».
   Сенс, який він назвав сам: не заповнювати повну анкету навпроти живої
   людини, щоб аж наприкінці зʼясувати, що заявка на неї вже є. */
.med-gate { display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: -4px 0 12px; padding: 9px 12px; font-size: 13px;
  background: var(--surface-2); border-left: 3px solid var(--line);
  color: var(--muted); }
.med-gate > span { flex: 1 1 220px; min-width: 0; }
/* Порожній рядок (телефон введено, збігів немає) не показуємо: інакше під полем
   висіла сіра смуга без тексту (власник 24.09.2026: «що це означає?»). */
.med-gate:empty { display: none; }
/* Знайшли людину — це вже не підказка, а причина зупинитись. */
.med-gate.found { background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-left-color: var(--accent); color: var(--text); font-weight: 500; }
/* Перевірити не вдалось — окремий стан, не плутати з «нікого немає». */
.med-gate.warn { background: color-mix(in srgb, var(--danger, #dc2626) 10%, transparent);
  border-left-color: var(--danger, #dc2626); color: var(--text); }

/* ⚠ Закрите поле видно ОЧИМА, а не лише по тому, що воно не натискається.
   Екран, який виглядає робочим і мовчить у відповідь, гірший за явно закритий.
   Гасимо саме ПОЛЯ, не картки: у першій картці поруч лежать ПІБ і телефон, які
   лишаються доступними. */
.med-fld.med-locked { opacity: .45; }
.med-fld.med-locked > span { color: var(--muted); }

/* ══════════ ТАБЕЛЬ ЧЕРГУВАНЬ ════════════════════════════════════════════════
   Власник 24.08.2026 зі знімком шкільного табеля: місяць, люди в рядках, дні в
   стовпцях, зафарбовані клітинки. Було — перелік із написом «на зміні». */
.med-month { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.med-month-t { font-size: 16px; text-transform: capitalize; }

/* На місяці з 31 дня таблиця не вміщається — гортається вбік. Перший стовпець
   при цьому лишається на місці, інакше не видно, чий це рядок. */
.med-tab-wrap { overflow-x: auto; border: 1px solid var(--line); background: var(--surface); }
.med-tab { border-collapse: collapse; width: max-content; min-width: 100%; }
.med-tab th, .med-tab td { border: 1px solid var(--line-2); padding: 0; text-align: center; }
.med-tab th { font-size: 12px; font-weight: 700; color: var(--muted);
  padding: 6px 0; min-width: 26px; background: var(--surface-2); }
.med-tab td { height: 30px; min-width: 26px; }

.med-tab-name { position: sticky; left: 0; z-index: 2; background: var(--surface);
  text-align: left !important; padding: 6px 10px !important; min-width: 190px;
  border-right: 2px solid var(--line) !important; }
.med-tab th.med-tab-name { background: var(--surface-2); }
.med-tab-name b { display: block; font-size: 14px; }
.med-tab-name span { display: block; font-size: 11.5px; color: var(--muted); }

/* Зафарбована клітинка — це і є чергування. Колір той самий, що у застосунку
   означає дію, а не тривогу. */
.med-tab td.on { background: var(--accent); }
.med-tab th.wknd, .med-tab td.wknd { background: color-mix(in srgb, var(--muted) 12%, transparent); }
.med-tab td.on.wknd { background: var(--accent); }
.med-tab th.today, .med-tab td.today { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.med-tab td:hover { background: color-mix(in srgb, var(--accent) 25%, transparent); }
.med-tab td.on:hover { background: color-mix(in srgb, var(--accent) 70%, transparent); }

/* ══════════ СТОРІНКА НЕ ЇДЕ ВБІК — ТІЛЬКИ НА ТЕЛЕФОНІ ═══════════════════════
   🔴 Власник 25.08.2026 прислав знімок із телефона: уся сторінка зсунута —
      шапка, поле пошуку, стовпці і нижнє меню поїхали ліворуч.
      «щоб воно не могло так. щоб було жорстко закріплено».

   🔴 І ОДРАЗУ МОЯ ПОМИЛКА, ЯКУ ВІН СПІЙМАВ: перша версія цього правила діяла на
      ВСІХ ширинах. Він сказав прямо: «я говорил только за вид с телефона. с
      ноута все било хорошо а щас с ноута стало только хуже».
      Я взяв вузьку скаргу і полагодив ширше, ніж просили, — і зіпсував те, що
      працювало. Тому тепер усе, що стосується зсуву, живе ВСЕРЕДИНІ медіа-запиту
      для вузьких екранів, а ноутбук лишається точно таким, яким був.

   ЗАМІРЯНО, А НЕ ВГАДАНО: у вигляді «Стовпцями» на вузькому екрані документ
   ширший за екран і сторінку реально можна посунути; у вигляді «Списком» —
   рівно нуль. Тобто справа саме в дошці.

   ⚠ clip, А НЕ hidden. `hidden` зробив би документ контейнером прокрутки і
     зламав `position: sticky` у шапок стовпців — власник просив їх окремо.
   ⚠ ГОРТАННЯ ДОШКИ ЛИШАЄТЬСЯ: стовпці гортаються ВСЕРЕДИНІ .med-board. Це
     єдиний спосіб побачити сім статусів на телефоні. */
@media (max-width: 700px) {
  html:has(.med-page), body:has(.med-page) { overflow-x: clip; }
  /* Дошка не ширша за своє місце, а ряд стовпців усередині займає рівно стільки,
     скільки треба, і гортається в межах дошки — тобто розсувати документ їй
     просто нічим. */
  .med-board { max-width: 100%; width: 100%; overflow-x: auto;
    /* 🔴 ОСЬ ЦЕ — НАЙІМОВІРНІША СПРАВЖНЯ ПРИЧИНА, і вона не та, яку я лагодив
       учора. Власник: «іноді може так зсуватись» — саме ІНОДІ, не завжди.
       На iOS, коли гортаєш вбік і впираєшся в кінець, жест не зупиняється: він
       «перетікає» на батьківський елемент, а далі на документ. Тобто гортання
       дошки штовхає всю сторінку — разом із шапкою і нижнім меню. Саме тому
       зсув випадковий: він трапляється лише коли догортав до краю і смикнув ще.
       `contain` обриває це перетікання на самій дошці.
       ⚠ У проєкті цей прийом уже вживається: у `.content` стоїть
         `overscroll-behavior: contain` рівно з тієї ж причини. Я просто не
         поставив його дошці, коли робив гортання стовпців.
       ⚠ ЧЕСНО: відтворити зсув у себе я НЕ ЗМІГ. Контрольний дослід показав, що
         моя перевірка не бачить різниці ні з учорашнім замком, ні без нього —
         тобто вчорашня правка нічого не доводила. Тому це названо найімовірнішою
         причиною, а не полагодженим. Підтвердити може лише телефон власника. */
    overscroll-behavior-x: contain; }
  .med-board-in { width: max-content; }
  /* Той самий обрив на рівні документа: якщо жест усе-таки дійшов сюди,
     сторінці нема куди «відскакувати» вбік. */
  body:has(.med-page) { overscroll-behavior-x: none; }
}

/* ══════════ КАРТКА ЛЮДИНИ: ВКЛАДКИ ══════════════════════════════════════════
   Власник 25.08.2026 прислав знімок картки студента: вкладки згори, блоки
   всередині. Заявка стала однією з вкладок, а не всім екраном. */
/* 🔴 БУЛА ГОРИЗОНТАЛЬНА ПРОКРУТКА — 26.08.2026, скарга власника: «вкладки з
   телефона не влазять і слітають, крутяться». Так і було: flex + nowrap +
   overflow-x. Чотири підписи по 14px жирним із полями 14px дають близько 420 px,
   а екран телефона — 360. Смуга їхала вбік, активна вкладка виїжджала за край,
   і кожен дотик по сусідній спершу гортав, а не перемикав.

   Тепер СІТКА рівними частками: скільки вкладок — стільки колонок, і жодна не
   виходить за екран. Ширину колонки задає minmax(0, 1fr), інакше довгий підпис
   роздуває колонку і сітка знову тікає вбік.
   Підпис переноситься на два рядки замість того, щоб штовхати сусіда, а розмір
   спадає плавно через clamp: на вузькому телефоні 11.5px, на широкому — ті самі
   14px, що й були. Кількість колонок ставить JS у --tabs: вкладки будуються
   з переліку, і зашите число розійшлося б із ним при першій же новій вкладці. */
/* 🔴 ВКЛАДКИ — КНОПКИ, І ВОНИ ЇДУТЬ ЗА ЕКРАНОМ. Власник 26.08.2026: «4 вкладки
   раздели как на скрине и сделай кнопками и что би они вверху били прикреплени
   и когда вниз идем они шли за мной».
   ⚠ position: sticky, а не fixed. Картка відкривається накладкою, яка гортається
   всередині себе; fixed прибив би смугу до вікна браузера і вона висіла б поверх
   інших екранів. sticky тримає її вгорі САМЕ цього вмісту.
   ⚠ top: 0 і фон обовʼязкові разом: без фону вміст просвічує крізь смугу, і на
   гортанні літери накладаються на літери. */
.med-tabs { position: sticky; top: 0; z-index: 5;
  display: grid; grid-template-columns: repeat(var(--tabs, 4), minmax(0, 1fr));
  gap: 6px; background: var(--bg); padding: 8px 0 10px; margin: -12px 0 12px;
  border-bottom: 2px solid var(--line); }
/* 🔴 НАД СМУГОЮ НІЧОГО НЕ ПРОСВІЧУЄ (власник 24.09.2026: «верхня смуга теж не повинна
   нічого пропускати крізь себе — скрізь казав: прикріплений рядок із фоном, без
   прозорості»). Вікно картки (.form-body) має відступ 12px, і прилипле тримається
   ВСЕРЕДИНІ відступу: смуга ставала на 12px нижче краю, і в щілину над нею видно було
   вміст («Заявка M-32»). Заміряно на стенді: край вікна 89.5, смуга 101.5.
   top: -12px ставить її впритул до краю; ::before заливає ті самі 12px обабіч. */
.form-body > .med-tabs { top: -12px; }
.med-tabs::before { content: ''; position: absolute; top: -12px; bottom: 0; left: -12px; right: -12px;
  background: var(--bg); z-index: -1; }
/* ⚠ КНОПКИ, А НЕ ПІДКРЕСЛЕНІ НАПИСИ — так просив власник, і так вони РОЗДІЛЕНІ
   між собою: на знімку він обвів кожну окремо і провів межі. Раніше вкладки
   стояли впритул і читались як один сірий рядок. */
.med-tab-b { min-width: 0; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 4px; font: inherit;
  font-size: clamp(10.5px, 2.8vw, 14px);
  font-weight: 700; line-height: 1.15; text-align: center;
  white-space: normal; overflow-wrap: anywhere; word-break: break-word;
  color: var(--muted); cursor: pointer; }
/* ⚠ ЧИСЛА ТУТ ПІДІБРАНІ ЗАМІРОМ, А НЕ НА ОКО. На 360px смуга дає 84px на вкладку;
   при полях 6px і шрифті 11.5px найдовший підпис «Відвідування» виходив за свою
   клітинку і наїжджав на сусідню — це видно було на знімку, а не в коді. Поля 3px
   і 10.5px лишають на текст 78px, і він вміщається. */
.med-tab-b:hover { color: var(--text); }
.med-tab-b.active { color: #fff; background: var(--accent); border-color: var(--accent); }
.med-tabs-pane > .card:first-child { margin-top: 0; }

/* Порожня вкладка — сіра. Власник 25.08.2026: «Відвідування зроби сірим, якщо
   немає історії». Натиснути можна: заборонити відкрити означало б сховати сам
   факт, що історії немає. */
.med-tab-b.empty { color: var(--faint); }
.med-tab-b.empty::after { content: ' · порожньо'; font-size: 11px; font-weight: 400; }
/* На телефоні слово «порожньо» подвоює довжину підпису і з'їдає ту саму ширину,
   заради якої й робилась сітка. Сірий колір цю ж річ каже без жодного місця. */
@media (max-width: 430px) { .med-tab-b.empty::after { content: ''; } }
.med-tab-b.empty.active { color: var(--muted); border-bottom-color: var(--line); }
/* 🔴 КРАПКА «НЕ ЗАПОВНЕНО» НА ВКЛАДЦІ (власник 24.09.2026: «якщо в даних пацієнта чи
   здоровʼї щось не заповнено — червона або помаранчева крапка залежно від критичності
   даних, на плашці»). Червона — бракує критичного, помаранчева — решти. Кут плашки, а не
   текст: підпис на телефоні й так ледь вміщається. Біла обводка — щоб помаранчеву було
   видно і на помаранчевій активній вкладці. */
.med-tab-b { position: relative; }
.med-tab-dot { position: absolute; top: 6px; right: 6px; width: 10px; height: 10px; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--surface); pointer-events: none; }
.med-tab-dot.red { background: var(--danger); }
.med-tab-dot.orange { background: var(--accent); }


/* Шапка людини стоїть НАД смугою вкладок і видна на будь-якій із них: алергію
   не можна ховати за дотик, бо ліки видають на цьому ж екрані. */
/* Шапка: хто це, одним поглядом. Розмір спадає згори вниз — так око читає
   природно, і не треба жодних підписів «Вік:», «Звання:». */
.med-head { padding-bottom: 12px; }
.med-head-1 { font-size: 15px; font-weight: 700; color: var(--text); }
.med-head-2 { font-size: 13.5px; color: var(--muted); margin-top: 3px; }
.med-head-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.med-state { font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  background: var(--surface-2); color: var(--text); }
.med-tel-a { font-size: 13.5px; color: var(--muted); text-decoration: none; }
.med-tel-a:hover { color: var(--text); }

/* Прапорці — тільки те, що змінює рішення просто зараз. Порожніх немає взагалі:
   рядок «Контузії: —» забирає місце і не додає нічого. Алергія червона, бо ліки
   видають на цьому ж екрані. */
.med-flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* 🔴 ПЛАНОВИЙ ОГЛЯД (16.09.2026) — фіолетова мітка в рядку, на дошці, у дні календаря
   і серед прапорців картки. НЕ синій: синім (--pend) уже фарбується статус «Взято в роботу»,
   і медик читав би огляд як статус. Свій токен для обох тем, текст — контраст понад 6:1. */
:root { --med-check: #a78bfa; }
[data-theme="light"] { --med-check: #6d28d9; }
.med-p-check { background: color-mix(in srgb, var(--med-check) 16%, transparent); color: var(--med-check); }
/* Блоком завширшки з текст: рядок заявки — це кнопка, і вона центрує вміст. */
.med-kind-check { display: block; width: max-content; max-width: 100%; text-align: left; margin-bottom: 4px; padding: 2px 8px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--med-check); background: color-mix(in srgb, var(--med-check) 14%, transparent); }
.med-flags .med-flag.check { background: var(--med-check); color: var(--ink); }
[data-theme="light"] .med-flags .med-flag.check { color: #fff; }
.day-row.check { box-shadow: inset 3px 0 0 var(--med-check); padding-left: 10px; }
.med-flag { font-size: 12px; padding: 3px 8px; border-radius: 6px;
  background: var(--surface-2); color: var(--muted); }
.med-flag.bad { background: color-mix(in srgb, var(--danger, #dc2626) 16%, transparent);
  color: var(--danger, #dc2626); font-weight: 700; }

/* Підпис розділу — це підпис, а не крик. КАПС із розрідженням на вузькому
   екрані читається гірше і перетягує увагу на себе. */
.med-sec-t { font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 10px; }

/* Видалення заявки — дрібна кнопка праворуч, а не смуга на всю ширину.
   Розмір відповідає тому, як часто її тиснуть; незворотність стереже
   підтвердження двома натисками. */
/* 🔴 БУЛА ЧЕРВОНА КНОПКА З РАМКОЮ — 26.08.2026, власник: «виглядає криво і не
   до чого». Обведена червона кнопка внизу картки читається як заклик: око
   чіпляється за неї, хоч тиснуть її раз на місяць. Рамка ще й не збігалася з
   рештою екрана — там суцільні кнопки або чистий текст, обведених немає ніде.

   Тепер це ТИХА ДІЯ: сірий текст із ледь помітним червонястим підкресленням,
   без рамки і без тла. Червоною вона стає РІВНО в ту мить, коли справді
   небезпечна — після першого натиску, коли підпис міняється на «Точно? Ще раз».
   Тобто колір показує стан, а не існування кнопки. */
/* Дві дії в одному рядку: головна 70%, незворотна 30%.
   ⚠ Ширина тут несе зміст, а не красу: більша кнопка та, яку тиснуть щодня,
   менша та, яку тиснуть раз і назавжди. Власник назвав саме ці числа. */
/* ⚠ ОДНАКОВА ВИСОТА — не оформлення, а вада, яку власник бачив двічі, перш ніж
   сказати вголос. Причина: ліворуч у парі посилання (тег a), праворуч кнопка
   (тег button). Різні типові поля і різна базова лінія тексту, тому при
   однакових ширинах висоти розходились. align-items тут мало: висоту задає
   вміст, тому вирівнюємо і його. */
.med-pair { display: flex; align-items: stretch; gap: 8px; margin-top: 10px; }
/* Заголовок розділу з дією праворуч. Значок притиснутий до правого краю,
   бо дія тут другорядна: головне в розділі — самі знімки. */
.med-sec-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.med-sec-head .section-title { margin: 0; }
.med-refresh { flex: 0 0 auto; }
/* ⚠ Обертання лише поки триває запит. Без нього людина не відрізняє «думає»
   від «нічого не сталось» і тисне ще раз — саме так і народжуються шість
   однакових звернень у журналі. */
/* Кнопка «оновити» у шапці відкритої картки — праворуч, а заголовок посередині
   між нею і «← Назад». */
.form-head h2 { flex: 1; }
.form-head .med-refresh { margin-left: auto; flex: 0 0 auto; }
.med-refresh.крутиться svg,
.icon-btn.крутиться svg { animation: med-spin 0.9s linear infinite; }
@keyframes med-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .med-refresh.крутиться svg,
  .icon-btn.крутиться svg { animation: none; opacity: 0.5; }
}
.med-pair-main { flex: 0 1 70%; }
.med-pair-side { flex: 0 1 30%; }
/* На вузькому екрані підпис «Відкрити заявку M-1044» не влазить у 70% —
   даємо йому переносити слова, а не виїжджати за край картки. */
.med-pair .btn { white-space: normal; line-height: 1.2;
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; box-sizing: border-box; margin: 0; }

.med-del-row { display: flex; justify-content: flex-end; margin: 10px 0 2px; }
.med-del-row .btn.small.danger {
  border: none; background: transparent; box-shadow: none;
  padding: 6px 2px; font-size: 13px; font-weight: 600; color: var(--muted);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--danger, #dc2626) 40%, transparent); }
.med-del-row .btn.small.danger:hover,
.med-del-row .btn.small.danger:focus-visible {
  color: var(--danger, #dc2626); background: transparent;
  text-decoration-color: var(--danger, #dc2626); }
/* Мить підтвердження — єдина, коли дія справді за один дотик від незворотності. */
.med-del-row .btn.small.danger.armed {
  color: #fff; font-weight: 700; text-decoration: none;
  background: var(--danger, #dc2626); border-radius: 8px; padding: 6px 12px; }
.med-del-row .btn.small.danger[disabled] {
  color: var(--faint); text-decoration: none; background: transparent; }

/* Скарга — головний текст картки. Підпис дрібний згори, значення на всю
   ширину: медик відкриває картку саме заради цього рядка. */
.med-lead { padding: 4px 0 12px; border-bottom: 1px solid var(--line-2); }
.med-lead-l { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--faint); margin-bottom: 6px; }
.med-lead-v { font-size: 16px; line-height: 1.45; color: var(--text); }
.med-lead-i { width: 100%; box-sizing: border-box; resize: vertical;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 0; padding: 8px 10px; font: inherit; font-size: 15px; line-height: 1.45; }

/* Голосом замість набирання. Кнопка ПІД полем, а не над ним: над полем вона
   читалась би як «наговоріть, і не чіпайте руками», а тут — як «можна ще й
   голосом». Заповнює воно, стверджує людина. */
.med-voice{display:flex;flex-direction:column;gap:6px}
.med-voice-b{align-self:flex-start}
/* Увімкнений мікрофон має бути видно з іншого кінця кімнати: медик тримає
   телефон у витягнутій руці і говорить, а не дивиться в екран. */
.med-voice-b.on{background:var(--accent);color:#fff;border-color:var(--accent)}
/* Чорновий текст — те, що воно ЗАРАЗ чує. Без нього кнопка на пʼять секунд
   завмирає і виглядає як зависла. */
.med-voice-live{min-height:1em;font-style:italic;overflow-wrap:anywhere}
.med-voice-no{color:var(--muted)}
.med-voice-meds{display:flex;flex-direction:column;gap:6px;margin-top:10px}
/* «Прибрати тестові заявки»: рядок із галочкою (17.09.2026). */
.med-purge-row { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; border-bottom: 1px solid var(--line, rgba(0,0,0,.08)); font-size: 13.5px; }
.med-purge-row input { margin-top: 3px; width: 18px; height: 18px; flex: none; }

/* ══════════ НЕЗАПОВНЕНЕ — ЛЕДЬ ПОМІТНО ══════════════════════════════════════
   🔴 Власник 18.09.2026: «підсвічуй, ледь-ледь, якщо щось не заповнено».
   Саме ледь: медик має бачити прогалини боковим зором, а не читати екран у
   плямах. Підсвічуємо лише порожні поля вводу і перелік без вибраного. */
.overlay input:placeholder-shown,
.overlay textarea:placeholder-shown,
.overlay .picker-btn.empty,
.med-page input:placeholder-shown,
.med-page textarea:placeholder-shown,
.med-page .picker-btn.empty,
/* Перелік без вибору — теж порожнє (24.09.2026): «не вказано» тепер так само ледь жовте. */
.overlay .med-fld select:has(> option:checked[value=""]),
.overlay .med-kv-edit select:has(> option:checked[value=""]),
.med-page .med-fld select:has(> option:checked[value=""]) {
  background: var(--surface); border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); }
/* 🔴 НЕ БЕЖЕВИМ, А ПОМАРАНЧЕВОЮ РАМКОЮ (власник 24.09.2026: «бежевий — це те, що не
   заповнено? поміняй на зрозуміліше»). Заливка в 6% помаранчевого читалась як просто
   колір фону. Рамка і смужка зліва — як «сюди ще треба вписати». Поле пошуку — не
   анкета: порожнім воно буває завжди, рамки на ньому немає. */
.med-page input.search-inp:placeholder-shown { background: var(--surface); border-color: var(--line); box-shadow: none; }
/* Обране значення в переліку — звичайним текстом, а не кольором підказки.
   🔴 Власник: «чому після позивного вибраний текст не чорний, а сірий?»
   Причина: правило .med-kv span фарбує БУДЬ-ЯКИЙ span усередині рядка, а
   значення переліку теж лежить у span. */
.med-kv .picker-btn .picker-val { color: var(--text); }
.med-kv .picker-btn.empty .picker-val { color: var(--faint); }

/* Назва частини корпусу під номером (23.09.2026). Звичайна підказка поля:
   дрібно, приглушено, у формі — під полем, у картці — під значенням. */
.med-unit-name { margin-top: 4px; font-size: 12.5px; line-height: 1.35; color: var(--muted); overflow-wrap: anywhere; }
.med-kv b .med-unit-name { display: block; font-weight: 400; }
/* У рядку картки поле частини загорнуте разом із назвою: обгортка бере ті самі
   60% ширини, а кнопка переліку всередині виглядає так само, як без обгортки. */
.med-kv-edit>.med-unit-box { display: flex; flex-direction: column; align-items: stretch; }
.med-kv-edit>.med-unit-box>.picker-btn { min-height: 0; padding: 6px 8px; font-size: 14px; border-radius: 0; width: 100%; }

/* Стрілки кроку назад/вперед і схована підказка результату прийому. */
.med-krok-back svg { transform: rotate(180deg); }
.med-krok { flex: 0 0 auto; }
.med-krok:disabled { opacity: .35; }
/* Стрілки й «Оновити» у шапці вікна — однією групою праворуч. */
.med-head-acts { display: flex; gap: 6px; margin-left: auto; flex: 0 0 auto; align-items: center; }
.form-head h2 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.icon-btn:disabled { opacity: .35; cursor: default; }
.med-tip-hidden { display: none; }
/* Підпис, у якого є пояснення: ледь помітна точка, щоб було видно, що є що
   подивитись затиснувши. */
.med-fld.has-tip>span::after, .med-kv-edit.has-tip>span::after {
  content: '·'; color: var(--accent); margin-left: 4px; font-weight: 700;
}

/* ══════════ ШАПКА МЕДМОДУЛЯ НА ТЕЛЕФОНІ (18.09.2026) ═════════════════════════
   🔴 Власник, два знімки з телефона: «кнопка оновити на телефоні не видна і
   незручна». Причини дві:
   1. Шапка медмодуля не лежить у .header, тож правило, яке на iPhone з екрана
      «Додому» відсуває шапку від годинника й батареї, її не чіпало — заголовок
      «Заявки» заїжджав під рядок стану.
   2. Напис «роль · пошта» займав пів ширини, і кнопки тіснились до заголовка.
   На вузькому екрані напис ховаємо (він є в «Ще → Акаунт»), кнопки — 44 px,
   щоб у них потрапляв палець. */
.med-top { padding-top: calc(6px + var(--safe-t)); }
@media (display-mode: standalone) {
  .med-top { padding-top: max(calc(var(--safe-t) + 6px), 50px); }
}
@media (max-width: 560px) {
  .med-top { padding-left: 14px; padding-right: 10px; gap: 8px; }
  .med-top .tb-title { font-size: 26px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .med-top .tb-left { min-width: 0; flex: 1 1 auto; }
  .med-top .tb-right { gap: 6px; flex: 0 0 auto; }
  .med-top .tb-right > .hint { display: none; }
  .med-top .tb-right .icon-btn { width: 44px; height: 44px; }
}

/* ── ПОШУК ЛЮДИНИ В CRM ПІД ПОЛЕМ ТЕЛЕФОНУ (23.09.2026) ─────────────────────
   Власник: «анимировано показывать, что идет поиск … если находится, то тоже
   анимированно, что все супер … а если нет — тоже, мол заполняй все сам».
   Три стани: пошук (крутилка), знайдено (зелене, спливає, поля блимають),
   немає (жовте, легкий струс). Поля, які дає CRM, під час пошуку приглушені. */
.med-crm-find { display: flex; align-items: center; gap: 10px; margin: -4px 0 12px; padding: 10px 12px;
  border-radius: 10px; font-size: 14px; line-height: 1.35; border: 1px solid transparent; }
.med-crm-find::before { content: ''; flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; }
.med-crm-find.is-search { background: color-mix(in srgb, var(--pend) 10%, transparent);
  border-color: color-mix(in srgb, var(--pend) 30%, transparent); color: var(--pend); }
.med-crm-find.is-search::before { border: 2.5px solid color-mix(in srgb, var(--pend) 25%, transparent);
  border-top-color: var(--pend); animation: med-crm-spin .8s linear infinite; }
.med-crm-find.is-ok { background: color-mix(in srgb, var(--ok) 12%, transparent);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent); color: var(--ok); font-weight: 600;
  animation: med-crm-pop .45s cubic-bezier(.2, 1.4, .4, 1); }
.med-crm-find.is-ok::before { background: var(--ok) center / 12px no-repeat
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.5l2.5 2.5L10 3.5' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.med-crm-find.is-none { background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-color: color-mix(in srgb, var(--warn) 35%, transparent); color: var(--warn); font-weight: 600;
  animation: med-crm-shake .5s ease-in-out; }
.med-crm-find.is-none::before { background: var(--warn) center / 12px no-repeat
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 2.5v4.5M6 9.3v.2' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); }
.med-fld.med-crm-wait input, .med-fld.med-crm-wait button { opacity: .45; }
.med-fld.med-crm-filled input, .med-fld.med-crm-filled button { animation: med-crm-flash 1.6s ease-out; }
@keyframes med-crm-spin { to { transform: rotate(360deg); } }
@keyframes med-crm-pop { 0% { transform: scale(.92); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes med-crm-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 50% { transform: translateX(4px); } 75% { transform: translateX(-2px); } }
@keyframes med-crm-flash { 0% { background: color-mix(in srgb, var(--ok) 28%, transparent); } 100% { background: inherit; } }
@media (prefers-reduced-motion: reduce) {
  .med-crm-find, .med-crm-find::before, .med-fld.med-crm-filled input, .med-fld.med-crm-filled button { animation: none !important; }
}

/* Комбо-тест розкривається у формі, як список (24.09.2026). */
.med-test { margin: 4px 0 12px; }
.med-test-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.med-test-chev { display: inline-flex; transition: transform .15s; }
.med-test.open .med-test-chev { transform: rotate(180deg); }
.med-test-b { border: 1px solid var(--line); border-top: 0; padding: 12px; background: var(--surface); }
.med-test-foot { margin-top: 8px; }

/* «Що за прийом» — дві кнопки на всю ширину, обрана залита (24.09.2026). */
.med-seg { display: flex; gap: 8px; }
.med-seg > .btn { flex: 1 1 0; margin: 0; min-height: 48px; }
.med-seg > .btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ══════════ КАЛЕНДАРИК (24.09.2026) ══════════════════════════════════════════════
   Кнопка — праворуч від поля, заввишки як поле медмодуля. Вікно — свій календар
   українською (див. вибратиДату в med.js). */
.med-date-row > input { flex: 1 1 auto; width: auto !important; min-width: 0; }
.med-date-row > .date-cal-btn { width: 48px; height: 48px; border-radius: 0; box-shadow: none; }
.med-kv-edit .med-date-row > .date-cal-btn { width: 40px; height: 40px; }
.med-cal-head { display: flex; gap: 6px; align-items: center; margin-bottom: 10px; }
.med-cal-head select { flex: 1 1 auto; min-width: 0; padding: 10px; border: 1px solid var(--line);
  background: var(--surface); color: var(--text); font: inherit; font-size: 15px; }
.med-cal-nav { flex: 0 0 44px; height: 44px; margin: 0; padding: 0; font-size: 22px; line-height: 1; }
.med-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.med-cal-wd { text-align: center; font-size: 12px; font-weight: 700; color: var(--muted); padding: 4px 0; }
.med-cal-d { min-height: 42px; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  font: inherit; font-size: 15px; cursor: pointer; }
.med-cal-d:hover:not(:disabled) { border-color: var(--accent); }
.med-cal-d.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.med-cal-d:disabled { opacity: .35; cursor: default; }

/* ══════════ ОДНАКОВІ ПРОМІЖКИ В БЛОЦІ ЛІКІВ (24.09.2026) ══════════════════════════
   Власник: «чому десь кнопки мають відступ від поля, а десь ні? зроби скрізь однаково».
   Було: «Скільки видали» впритул під вибором ліків (0px), «Прибрати» — впритул, «Упаковка»
   і «Додати ще» — по 6px. Тепер у рядку все стовпчиком з одним проміжком 8px, і власних
   відступів у дітей немає. */
.med-meds-row { display: flex; flex-direction: column; gap: 8px; }
.med-meds-row > * { margin-top: 0 !important; margin-bottom: 0 !important; }
.med-meds > .btn.small { margin-top: 8px; }
/* Ті самі 8px і всередині поля кількості: «Упаковка · N» і «＋ Додати ще» мали по 6px. */
.med-meds .med-qty-fast, .med-meds .med-qty-more { margin-top: 8px !important; }
/* ══════════ ЗРУЧНІСТЬ НА ТЕЛЕФОНІ (23.09.2026, пробна гілка ux/mobile-trial) ══════════
   Джерела: Nielsen Norman Group — ціль для пальця щонайменше 1 см (≈44 px), між
   сусідніми цілями ≥ 8 px. Заміри на екрані 375 px до правки:
   · «Крок назад / уперед / Оновити» в картці — 40×40 з проміжком 4–6 px;
   · вкладки картки — проміжок 6 px; «Центр» і «Статус» у картці — 32–34 px заввишки;
   · кнопка діагнозу — 38 px; «Фільтри» — 40 px завширшки;
   · у списку довге ПІБ виштовхувало статус і значок CRM за край екрана (3 з 6
     карток, значок на 379–408 px при ширині 375);
   · телефон у картці списку рвався посередині номера: «+38067100000 / 4». */
@media (max-width: 600px) {
  .form-head .icon-btn, .med-head-acts .icon-btn { width: 44px; height: 44px; }
  /* Проміжок між стрілками: у файлі вище стоїть `.med-top .tb-right { gap: 6px }`,
     тож і тут той самий селектор — інакше він перемагає. */
  .med-head-acts, .tb-right, .med-top .tb-right { gap: 8px; }
  /* 16 px у полях медмодуля: `.med-kv-edit select` (14 px) і `.med-fld select`
     (15 px) вище в цьому файлі перебивали правило зі styles.css. */
  .med-kv-edit input, .med-kv-edit select, .med-kv-edit textarea,
  .med-fld input, .med-fld select, .med-fld textarea { font-size: 16px; }
  .med-tabs { gap: 8px; }
  .med-kv-edit select { min-height: 44px; }
  .picker-btn { min-height: 44px; }
  .filter-fab { min-width: 44px; min-height: 44px; }
  /* ПІБ стискається і переноситься, а статус і значок CRM лишаються на екрані. */
  .med-page .rec-top > :first-child { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; text-align: left; }
  /* ПІБ переноситься, а не обрізається трьома крапками: медику потрібне повне імʼя
     (styles.css тримає .rec-name в один рядок — для спільного списку УДЗ). */
  .med-page .rec-top .rec-name { white-space: normal; overflow: visible; text-overflow: clip; text-align: left; }
  /* Назва над значенням: значення отримує всю ширину комірки, і номер телефону
     вміщається одним рядком замість розриву посеред цифр. Обидва — ліворуч. */
  .med-page .rec-cell { flex-direction: column; gap: 0; align-items: flex-start; }
  .med-page .rec-cell > i, .med-page .rec-cell > b { text-align: left; }
}

/* ══════════ КНОПКИ ЗА ІЄРАРХІЄЮ (23.09.2026, пробна гілка ux/mobile-trial) ══════════
   Carbon (IBM), Helios (HashiCorp), SubUX: одна головна дія на екран — залита;
   решта — обведена (другорядна) або просто текст (рідкісна). Ширина — за
   написом, ряд — ліворуч; на всю ширину — лише у вікнах. Напис звичайними
   літерами, не ВЕЛИКИМИ. Висота ≥ 44 px (NN/g) — відступами, а не шириною.
   Власник: «не делай кнопки всегда такими большими». */
.med-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-start; margin-top: 10px; }
.med-acts > .btn { width: auto; margin: 0; min-height: 44px; padding: 10px 16px;
  text-transform: none; letter-spacing: 0; font-size: 14px; }
.med-acts > .btn + .btn { margin-top: 0; }
.btn.btn-sec { background: transparent; border: 1.5px solid var(--line); color: var(--text); font-weight: 600; }
.btn-text { background: none; border: none; color: var(--accent); font: inherit; font-weight: 600;
  font-size: 14px; padding: 10px 2px; min-height: 44px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }
/* Вікно «Чим закінчився прийом?»: поля результату, перенесені з форми. */
.med-finish .modal-body .med-fld { margin-bottom: 12px; }
.med-finish .modal-foot .btn { text-transform: none; letter-spacing: 0; font-size: 14px; }
/* Шрифт кнопок — той самий, що в тексті: заголовковий шрифт застосунку створений
   під ВЕЛИКІ літери, і малі кириличні в ньому криві («ЗавеРШити»). */
.med-acts > .btn, .med-finish .modal-foot .btn, .btn-text {
  font-family: 'Mulish', -apple-system, 'Segoe UI', Roboto, sans-serif; }

/* ══════════ СМУГА ЗАГОЛОВКІВ ДОШКИ — СУЦІЛЬНА (23.09.2026, пробна гілка) ══════════
   Власник: «первая строка … черние надписи виглядят без фона, между ними зазори,
   не сплошним фоном идут». Заміри на екрані 1280 px при прокрутці дошки:
   · між заголовками стовпців — проміжки по 12 px (10 px відступу + дві рамки),
     і в них видно картки, що їдуть під смугою;
   · над смугою просвічує текст картки: Chrome прибиває sticky до верху ВМІСТУ
     контейнера, тобто нижче його верхнього відступу (4 px), і в цій щілині видно,
     що прокручується.
   Тому: верхній відступ дошки — зовні (margin), а кожен заголовок тягне свою
   чорну смугу через проміжок до сусіда (тінь без розмиття) і закриває щілину над
   собою тлом сторінки. Останньому стовпцю тягнутись нікуди. */
.med-board { padding-top: 0; margin-top: 4px; }
.med-col-h { box-shadow: 12px 0 0 var(--text), 0 -6px 0 var(--bg), 12px -6px 0 var(--bg); }
.med-col:last-child .med-col-h { box-shadow: 0 -6px 0 var(--bg); }
/* Дві кнопки картки — в одному ряду: «Переназначити» ліворуч, «Завершити прийом»
   праворуч, одна висота, одна лінія (власник 23.09: «не так же криво»). */
.med-acts-split { justify-content: space-between; align-items: center; flex-wrap: nowrap; }
/* ПІБ у картці списку — переноситься ЛИШЕ між словами (23.09.2026). Попереднє
   «overflow-wrap: anywhere» на вузькому екрані рвало імʼя посеред слова
   («Бонда / р Сергій Микол / айович» на 256 px). Якщо поруч зі статусом місця
   менше, ніж на ~160 px, статус і значок CRM ідуть рядком нижче. */
@media (max-width: 600px) {
  .med-page .rec-top { flex-wrap: wrap; row-gap: 6px; }
  .med-page .rec-top > :first-child { flex: 1 1 160px; overflow-wrap: break-word; }
}

/* ІМʼЯ В ШАПЦІ КАРТКИ НА ТЕЛЕФОНІ (23.09.2026). Поруч «Назад» і три круглі
   кнопки, на імʼя лишалось 85 px — і замість «Мельник Олег Іванович» було
   «Мель…»: не видно, чию картку відкрито. На вузькому екрані імʼя — окремим
   рядком під кнопками, повністю. */
@media (max-width: 600px) {
  .form-head:has(> h2) { flex-wrap: wrap; row-gap: 6px; }
  .form-head > h2 { order: 5; flex: 1 1 100%; white-space: normal; overflow: visible;
    text-overflow: clip; overflow-wrap: break-word; font-size: 18px; line-height: 1.25; margin: 0; }
}

/* 🔴 «КОМБО-ТЕСТ НЕ ЗДАНО» — ВИДНО ЗДАЛЕКУ (власник 24.09.2026: «хай анкети, що так потрапили в
   цей статус, відрізняються візуально»). Синім — окремо від огляду СЗЧ (фіолетовий) і особливого
   стану (червоний): така заявка теж в особливому стані, і смуга мусить перебити червону. */
.med-kind-test { display: block; width: max-content; max-width: 100%; text-align: left; margin-bottom: 4px; padding: 2px 8px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--pend); background: color-mix(in srgb, var(--pend) 14%, transparent); }
.med-page .rec.med-rec.test-wait, .med-page .rec.test-wait, .med-cardlet.special.test-wait, .med-cardlet.test-wait {
  border-left: 3px solid var(--pend); background: color-mix(in srgb, var(--pend) 7%, var(--surface)); }
.med-flags .med-flag.test { background: var(--pend); color: #fff; }
