/* ============================================================================
   EFFISCORE — мобільний шар. Створено 16.08.2026 (BUG-009).

   ПРАВИЛО ЦЬОГО ФАЙЛА: у ньому немає жодного правила поза `@media`.
   Тому питання «чи я зламав десктоп або телевізор» має механічну відповідь:
   прибрати один рядок <link> у index.html — і застосунок стає точно таким, як
   був. Жоден інший файл стилів такої властивості не має.

   Пороги ті самі, що в `js/viewport.js`, і саме в тому самому синтаксисі:
     max-width: 1024px  АБО  (pointer: coarse) and (max-width: 1400px)
                       — вузький екран або будь-який дотиковий пристрій
     max-width: 767px  — саме телефон
   Якщо міняєш поріг — міняй в обох місцях, інакше на одній ширині екран
   складеться з двох різних версій.

   Чому 1024 ВКЛЮЧНО — рівно 1024 це iPad у ландшафті, і при межі 1023 він
   випадав із мобільного шару цілком (42 з 42 елементів дотику по 32px).

   ЧОМУ ДРУГА УМОВА ПРО ВКАЗІВНИК (17.08.2026). iPad Pro 11 у ландшафті — це
   1194px, тобто ширший за 1024, і він отримував інтерфейс, розрахований на
   мишку: кнопки по 32px і текст 10px на пристрої, яким керують пальцем.
   Ширина тут узагалі не те, що треба питати: розмір елемента керування
   визначає НЕ скільки місця на екрані, а чим по ньому тикають.
   `pointer: coarse` — це «палець», і він правдивий на будь-якому планшеті
   незалежно від орієнтації. Стеля 1400px лишена, щоб великий дотиковий
   монітор (якщо колись буде) не втратив десктопну розкладку; телевізор у
   цеху під цю умову не потрапляє ніколи — ним керує Mac, тобто вказівник
   там `fine`.

   Токени — з tokens.css, нових кольорів тут немає навмисно: мобільна версія
   має бути тим самим продуктом, а не схожим на нього.
   ============================================================================ */

@media (max-width: 1024px), (pointer: coarse) and (max-width: 1400px) {

  /* ---- 1. Оболонка --------------------------------------------------- */

  :root {
    --m-nav-h: 58px;                    /* висота нижньої панелі */
    --m-pad: 12px;                      /* бічне поле сторінки */
    --m-tap: 44px;                      /* мінімум для пальця (Apple HIG) */
  }

  /* Місце під нижню панель. Без цього останній рядок таблиці або кнопка
     назавжди ховаються під панеллю: сторінка «закінчилась», а частина її
     вмісту фізично недосяжна. safe-area — під смугу-індикатор iPhone. */
  body.m-mode #app {
    padding-bottom: calc(var(--m-nav-h) + env(safe-area-inset-bottom, 0px));
  }
  /* Прокрутка тільки вертикальна. Горизонтальний скрол сторінки на телефоні
     читається як поломка навіть тоді, коли він «задуманий»: людина губить
     ліву колонку й не розуміє, куди поділось ім'я.
     Правило стоїть і на `html`, і на `body` (17.08.2026). За специфікацією
     значення з `body` «піднімається» на вікно, коли в `html` стоїть
     `visible`, — і в Chrome цього справді досить. Але в СПРАВЖНЬОМУ Safari
     на iPhone після відкриття вікна входу сторінка лишалась зсунутою вбік:
     «EFFISCORE» і кнопка «Увійти» виїжджали за край і не поверталися.
     Chrome із емуляцією пристрою цього не відтворює взагалі — знайдено лише
     в симуляторі. `overflow-x: hidden` на самому `html` прибиває вікно до
     нуля незалежно від того, хто й навіщо намагався його прокрутити. */
  html:has(body.m-mode), body.m-mode { overflow-x: hidden; max-width: 100%; }
  /* Смуга безпеки: жоден нащадок не має права бути ширшим за екран. */
  body.m-mode #app { max-width: 100%; }

  /* ---- 2. Шапка ------------------------------------------------------ */

  /* Вкладки переїхали вниз, до великого пальця. Тут лишається впізнавання
     («де я») і службові значки. */
  .nav {
    gap: 8px;
    padding: 8px var(--m-pad);
    padding-top: calc(8px + env(safe-area-inset-top, 0px));
  }
  .nav .tabs { display: none; }
  .nav .spacer { flex: 1; }
  .nav .brand { font-size: 15px; }

  /* Шапка переноситься на другий рядок, а не стискає вміст. Стиснення тут
     коштувало б читабельності: на знімку 402px перемикач складу вже ламався
     на «DE-» / «6» у два рядки й друга кнопка виїжджала за край. */
  .nav { flex-wrap: wrap; row-gap: 6px; }

  /* «Шлях проєкту» — значком. Підпис у 132px забирав третину шапки на 320px,
     а сама сторінка довідкова: її шукають свідомо, не натрапляють.
     Підпис саме ХОВАЄТЬСЯ (`display:none`), а не зменшується до нуля кеглем:
     `font-size: 0` дає елемент із текстом у 0px, і будь-яка перевірка «чи
     немає на екрані дрібного тексту» чесно на нього лається. Прилад не має
     ловити наші ж хитрощі замість справжніх дефектів. */
  .nav-roadmap, .nav-faq {
    width: var(--m-tap); height: var(--m-tap);
    padding: 0; margin: 0; justify-content: center; flex: none;
  }
  .nav-roadmap .lb, .nav-faq .lb { display: none; }
  .nav-roadmap::before, .nav-faq::before { font-size: 15px; }

  /* Усе, що в шапці натискають, — не менше 44px. */
  .nav button, .nav-acq-alert, .session button, .notif-bell {
    min-height: var(--m-tap);
  }
  .notif-bell { width: var(--m-tap); height: var(--m-tap); font-size: 17px; }
  /* Лічильник аномалій — теж читабельний текст, а не декор, тому 12px. Але
     рівно 12px: збільшивши його «щоб пройшла перевірка на дрібний шрифт», я
     зробив із позначки другу кнопку — червоне коло перетягувало увагу з назви
     розділу на кожному екрані. Мінімальний розмір — це підлога, а не мета. */
  .notif-badge {
    font-size: var(--fs-12); min-width: 17px; height: 17px; line-height: 17px;
    padding: 0 4px; top: -2px; right: -2px;
  }

  /* Перемикач складу: не стискається й не переносить назву. */
  .tv-wh { margin-left: 0; flex: none; }
  /* Місце під нього тримається ЗАЗДАЛЕГІДЬ. Перемикач і значок сесії
     монтуються після відповіді сервера (`/api/warehouses`, `/api/session`), і
     доки їх немає, сусіди в шапці стоять лівіше, а потім стрибають убік.
     Lighthouse рахує це зсувом розкладки нарівні з вертикальним. Порожня
     коробка невидима (прозора рамка), але місце вже займає. */
  /* Розміри тут — ЗМІРЯНІ, а не приблизні (17.08.2026). Спершу стояло 112×44
     і 76×44 «на око»; заповнений перемикач складу виявився 118×46, а значок
     сесії 65×44. Різниця в шість пікселів по ширині переносила сусіда на
     НОВИЙ РЯДОК, шапка виростала, і банер разом з усім вмістом з'їжджав
     униз — зсув розкладки 0.206 при нормі 0.1 і мінус 14 пунктів
     продуктивності в Lighthouse. «Майже вгадане» місце для елемента, що
     приїде пізніше, гірше за незарезервоване: воно створює зсув там, де його
     не чекають. */
  .tv-wh:empty { display: inline-flex; min-width: 118px; min-height: 46px; border-color: transparent; }
  .tv-wh { min-height: 46px; }
  .session:empty { display: inline-flex; min-width: 65px; min-height: var(--m-tap); }
  .tv-wh .wh {
    font-size: var(--fs-13); padding: 0 12px;
    min-height: var(--m-tap); white-space: nowrap;
  }

  .session { flex: none; gap: 6px; }

  /* ---- 3. Нижня панель ------------------------------------------------ */

  .mnav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky);
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    /* minmax(0,1fr), а не 1fr: 1fr це minmax(auto,1fr), і найдовший підпис
       розсунув би колонки нерівно — та сама пастка, що вже коштувала
       правого краю монітора на ТВ (CLAUDE.md). */
    background: rgba(10, 14, 20, 0.94);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mtab {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; min-height: var(--m-nav-h);
    border: 0; background: transparent; color: var(--text-dim);
    font-family: inherit; font-size: var(--fs-12); font-weight: 600;
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .mtab .ico { font-size: 15px; line-height: 1; opacity: .8; }
  .mtab .lb { line-height: 1.1; }
  .mtab.active { color: var(--c-pick); }
  .mtab.active .ico { opacity: 1; }
  /* Смужка активного розділу — зверху, бо знизу її з'їдає safe-area. */
  .mtab.active::before {
    content: ""; position: absolute; margin-top: -1px;
    transform: translateY(calc(var(--m-nav-h) / -2 + 1px));
    width: 26px; height: 2px; border-radius: 2px; background: var(--c-pick);
  }

  /* ---- 4. Гостьова смуга ---------------------------------------------- */

  .demo-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 8px var(--m-pad); font-size: var(--fs-12); line-height: var(--lh-ui);
  }
  .demo-bar .btn { min-height: var(--m-tap); flex: none; }

  /* ---- 5. Форми: iOS не має збільшувати сторінку ---------------------- */

  /* Mobile Safari сам зумить сторінку при фокусі в поле з кеглем < 16px і
     назад НЕ повертає — людина лишається на збільшеній сторінці з
     горизонтальним скролом. Це не косметика, це поламана навігація.

     СЕЛЕКТОР ЧЕРЕЗ `body.m-mode` НАВМИСНО (17.08.2026). Спершу тут стояло
     просто `input, select, textarea` — специфічність (0,0,1). У style.css є
     `.modal input { font-size: 15px }` — специфічність (0,1,1), тобто вона
     ПЕРЕМАГАЛА, і поля вікна входу лишались 15-піксельними. Наслідок побачив
     тільки справжній Safari в симуляторі: після тапу в «Логін» сторінка
     збільшувалась, лівий край з «EFFISCORE» виїжджав за екран, нижня панель
     розділів зникала — і так лишалось навіть після перезавантаження, бо
     Safari пам'ятає масштаб для сайту. У Chrome з емуляцією пристрою цього
     немає взагалі: він поважає `maximum-scale` і не зумить по фокусу.
     Правило нижче має специфічність (0,2,1) і перекриває будь-яке правило
     з одного класу — а таких у проєкті ще кілька. */
  body.m-mode input, body.m-mode select, body.m-mode textarea { font-size: 16px; }
  body.m-mode input:not([type="checkbox"]):not([type="radio"]),
  body.m-mode select { min-height: var(--m-tap); }

  /* ---- 6. Загальні розміри дотику ------------------------------------ */

  .btn, .seg button, .tab { min-height: var(--m-tap); }
  .seg { flex-wrap: wrap; }

  /* ---- 7. Сторінка ---------------------------------------------------- */

  .page { padding: var(--m-pad); gap: 10px; min-width: 0; max-width: 100%; }
  .controls { flex-wrap: wrap; gap: 8px; }

  /* `.tools` — нерозривна група кнопок роботи з даними (11.08.2026): на
     десктопі вона навмисно `flex-wrap: nowrap`, щоб «звук» і «CSV» не
     переповзали ліворуч під вкладки перегляду й розкладка не міняла СМИСЛ
     від ширини вікна. На телефоні ця причина зникає — там і так усе в один
     стовпець, лівого й правого боку не існує, — а нерозривність лишається і
     стає єдиним джерелом горизонтального скролу Manager: група в 564px на
     екрані 402px. Тому саме тут, і тільки тут, вона розривається. */
  /* Селектор саме `.controls .tools`: правило-джерело теж із двох класів, і
     одинарний `.tools` програв би йому за специфічністю — мовчки, бо
     синтаксично все правильно. */
  .controls .tools { flex-wrap: wrap; margin-left: 0; }

  /* ---- 8. Мобільний рейтинг (board-mobile.js) ------------------------- */

  .mb { display: flex; flex-direction: column; gap: 10px; padding: 10px var(--m-pad) 0; }

  .mb-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .mb-when { display: flex; gap: 6px; align-items: center; }
  .mb-ctl {
    background: var(--c-surface-1); color: var(--text); border: var(--b-1);
    border-radius: var(--r-2); padding: 0 10px; min-height: var(--m-tap);
    font-family: inherit; font-size: 16px;
  }
  .mb-meta { display: flex; align-items: center; gap: 8px; margin-left: auto; }
  .mb-meta .dim { font-size: var(--fs-12); color: var(--text-dim); }

  /* Ліги — чотири рівні колонки, усі видимі одночасно. Смуга з горизонтальним
     гортанням тут була б гіршою: невидима четверта ліга нічим себе не виказує,
     і людина просто не дізнається, що вона є. Підпис без розрядки (--ls-caps
     навмисно не застосовано), бо саме розрядка не давала «STAPLER» влізти
     в чверть екрана на 320px. */
  .mb-leagues {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px;
  }
  .mb-lg {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 1px; min-height: var(--m-tap); padding: 4px 2px;
    border: var(--b-1); border-radius: var(--r-2); background: var(--c-surface-1);
    color: var(--text-dim); font-family: inherit; font-size: var(--fs-12);
    font-weight: 700; letter-spacing: 0; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .mb-lg .lb { line-height: 1.1; }
  /* БЕЗ `opacity`. Прозорість тут гасила `--text-dim` до контрасту ~4.0 на
     тлі панелі — нижче порогу WCAG AA (4.5), і Lighthouse чесно знизив
     доступність з 98 до 94. Токен `--c-text-2` для того й існує, щоб підпис
     був тихішим за основний текст, лишаючись читабельним: приглушувати його
     ще й прозорістю означає робити руками те, для чого вже є токен, — і
     робити гірше. */
  .mb-lg .n { font-size: var(--fs-12); font-weight: 600; color: var(--c-text-2); }
  .mb-lg.on .n { color: inherit; }
  .mb-lg.on { color: var(--c-bg); }
  .mb-lg.on.pick { background: var(--c-pick); border-color: var(--c-pick); }
  .mb-lg.on.pack { background: var(--c-pack); border-color: var(--c-pack); }

  .mb-list { display: flex; flex-direction: column; gap: 6px; }

  /* Рядок. Кожна клітинка отримує ЯВНИЙ grid-column — інакше, коли сусід
     ховається (немає руху, немає бейджів), сітка зсуває решту підряд у перші
     вільні колонки й ім'я з'їжджає в колонку аватара. Ця пастка вже коштувала
     розваленого рядка на ТВ (CLAUDE.md). */
  .mb-row {
    position: relative; overflow: hidden;
    display: grid; align-items: center;
    grid-template-columns: 24px 34px minmax(0, 1fr) auto;
    gap: 10px; padding: 9px 12px 9px 8px; min-height: 56px;
    border: 0; border-radius: var(--r-2); background: var(--c-surface-2);
    color: var(--text); font-family: inherit; text-align: left;
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .mb-row .bar {
    position: absolute; inset: 0 auto 0 0; width: 100%;
    transform-origin: left center; z-index: 0;
    background: linear-gradient(90deg, currentColor, transparent);
    opacity: .10; pointer-events: none;
  }
  .mb-list.pick .mb-row .bar { color: var(--c-pick); }
  .mb-list.pack .mb-row .bar { color: var(--c-pack); }
  .mb-row > * { position: relative; z-index: 1; }

  .mb-row .rk {
    grid-column: 1; text-align: center;
    font-size: var(--fs-14); font-weight: 700; color: var(--text-3);
  }
  .mb-row .av {
    grid-column: 2; width: 34px; height: 34px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-12); font-weight: 700; color: oklch(0.18 0.02 258);
  }
  .mb-row .who { grid-column: 3; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .mb-row .nml { display: flex; align-items: center; gap: 6px; min-width: 0; }
  /* Ім'я — головний елемент екрана, тому воно НЕ обрізається: переносить
     рядок. Обрізане ім'я — це і є той дефект, заради якого писалась мобільна
     версія; ellipsis тут був би тим самим дефектом під іншою назвою. */
  .mb-row .nm {
    font-size: var(--fs-16); font-weight: 650; line-height: 1.15;
    overflow-wrap: anywhere;
  }
  .mb-row .sub { font-size: var(--fs-12); color: var(--text-2); line-height: 1.25; }
  .mb-row .mks { display: flex; gap: 4px; flex: none; }
  .mb-row .mk {
    font-size: var(--fs-12); font-weight: 700; line-height: 1;
    padding: 2px 5px; border-radius: var(--r-1);
    background: var(--c-surface-3); color: var(--text-2);
  }

  .mb-row .num {
    grid-column: 4; display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  }
  .mb-row .sc { font-size: var(--fs-21); font-weight: 700; line-height: 1; }
  .mb-list.pick .mb-row .sc { color: var(--c-pick); }
  .mb-list.pack .mb-row .sc { color: var(--c-pack); }
  /* Прочерк не має бути пофарбований у колір ліги: кольорова риска читається
     як значення. Специфічність навмисно піднята до рівня правил ліги вище —
     інакше вони перемагають за порядком і «немає даних» виглядає як бал. */
  .mb-list .mb-row .sc.dash { color: var(--text-3); font-size: var(--fs-16); }
  .mb-row .mv { font-size: var(--fs-12); font-weight: 700; }
  .mb-row .mv.up { color: var(--c-up); }
  .mb-row .mv.down { color: var(--c-down); }

  /* Подіум позначає МІСЦЕ — номер і рейку зліва, а не весь рядок. Спроба
     пофарбувати рядок цілком (через currentColor) зробила ім'я третього
     бронзовим: на темному тлі це помітно тьмяніше за біле, тобто третє місце
     читалось гірше за четверте. Нагорода не має коштувати контрасту. */
  .mb-row.p1 { box-shadow: inset 3px 0 0 var(--c-gold); }
  .mb-row.p2 { box-shadow: inset 3px 0 0 var(--c-silver); }
  .mb-row.p3 { box-shadow: inset 3px 0 0 var(--c-bronze); }
  .mb-row.p1 .rk { color: var(--c-gold); }
  .mb-row.p2 .rk { color: var(--c-silver); }
  .mb-row.p3 .rk { color: var(--c-bronze); }
  .mb-row.p1 .rk, .mb-row.p2 .rk, .mb-row.p3 .rk { font-size: var(--fs-16); }

  .mb-empty { padding: 28px 12px; text-align: center; color: var(--text-2); font-size: var(--fs-14); }
  .mb-foot {
    margin: 4px 0 0; padding: 10px 0 2px; border-top: var(--b-hair);
    font-size: var(--fs-12); color: var(--text-3); line-height: var(--lh-ui);
  }
  .mb-foot b { color: var(--text-2); }

  /* ---- 9. Manager: таблиця з пріоритетом колонок ---------------------- */

  /* Смуга «Фільтри й дії». Згортається ПЕРША `.controls` (роль, період,
     пошук, кнопки роботи з даними) — друга лишається завжди, бо в ній
     вкладки Рейтинг / Перевірка / Чит-детектор, тобто навігація, а не
     настройки. */
  .m-ctlbar {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 100%; min-height: var(--m-tap); padding: 0 12px;
    border: var(--b-1); border-radius: var(--r-2); background: var(--c-surface-1);
    color: var(--text); font-family: inherit; font-size: var(--fs-13); font-weight: 600;
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .m-ctlbar .car { color: var(--text-3); transition: transform var(--t-fast) var(--ease-out); }
  .m-ctlbar[aria-expanded="true"] .car { transform: rotate(180deg); }
  .page.m-collapsed > .controls:first-of-type { display: none; }
  /* Вибір власника 16.08.2026 з двох показаних макетів. Закріплені колонки на
     телефоні — #, Ім'я, Score (набір задає COLS_LOCKED у manager.js, там же
     пояснено чому саме ці три). Зсуви `left` рахуються наперед під ці ширини,
     як і на десктопі: 26 + 112 + 52 = 190px, тобто половина екрана лишається
     під колонки, що гортаються. Десктопні 46/96/210 = 352px з 402 не лишали
     під них нічого. */
  .grid-rankings th:nth-child(1), .grid-rankings td:nth-child(1) { width: 26px; min-width: 26px; max-width: 26px; padding: 8px 4px; }
  .grid-rankings th:nth-child(2), .grid-rankings td:nth-child(2) { width: 112px; min-width: 112px; max-width: 112px; padding: 8px 6px; }
  .grid-rankings th:nth-child(3), .grid-rankings td:nth-child(3) { width: 58px; min-width: 58px; max-width: 58px; padding: 8px 6px; }
  .grid-rankings th:nth-child(2), .grid-rankings td:nth-child(2) { left: 26px; }
  .grid-rankings th:nth-child(3), .grid-rankings td:nth-child(3) { left: 138px; }
  /* Закріплені клітинки НЕ дають своєму вмісту вилізти за межі.
     Без цього підпис «SCORE» (45px у капсі) виходив зі своєї 52-піксельної
     колонки й малювався поверх заголовка сусідньої, що саме проїжджав під
     ним: на екрані виходило «SCOREНЕСОК». Помітно лише в прокрученому стані,
     тому знімок «як відкрилось» цього не показував. */
  .grid-rankings th:nth-child(1), .grid-rankings th:nth-child(2), .grid-rankings th:nth-child(3),
  .grid-rankings td:nth-child(1), .grid-rankings td:nth-child(3) { overflow: hidden; }
  .grid-rankings th { font-size: var(--fs-12); letter-spacing: 0; }
  /* Тінь-розділювач переїжджає на третю колонку разом із набором. */
  .grid-rankings th:nth-child(3), .grid-rankings td:nth-child(3) {
    box-shadow: 4px 0 6px -3px rgba(0, 0, 0, .75);
  }

  /* Ім'я переносить рядок замість трьох крапок. У колонці 112px «Vladimer
     Kobaneishvili» обрізається рівно на прізвищі — а прізвище тут і є те,
     що відрізняє людину від однофамільця. Два рядки коштують висоти, але
     висота на телефоні безкоштовна: вниз можна гортати. */
  .grid-rankings td:nth-child(2) .nm-txt {
    white-space: normal; overflow: visible; text-overflow: clip;
    overflow-wrap: break-word; line-height: 1.15;
  }
  .grid-rankings td, .grid-rankings th { font-size: var(--fs-13); }

  /* Центрування, скорочення й закріплений перший стовпець — тепер базова
     поведінка `.grid` для всіх ширин (18.08.2026, `style.css`). Тут лишається
     тільки те, що дійсно міняється саме на вузькому екрані. */

  /* ЗНАЧКІВ ДОВІДКИ В ЗАГОЛОВКАХ НА ТЕЛЕФОНІ НЕМАЄ — і це рішення, а не
     недогляд (17.08.2026). На десктопі значок абсолютно позиціюється всередині
     заголовка (`style.css`) і працює нормально — там і колонка ширша, і
     клацають мишею, а не пальцем. На телефоні той самий підхід не рятує:
     Спроба перша: значок у потоці. Область дотику 44px розширювала КОЛОНКУ на
     46px — тобто з'їдала саме ту ширину, заради якої заголовки й скорочували.
     Спроба друга: значок абсолютно, `padding-right: 42px` під нього. У вузьких
     службових колонках («#» — 26px) відступ виявився більшим за саму колонку,
     і значок вилазив на сусідню: замість пояснення виходило накладання.
     Обидві спроби вперлись в одне: пояснення до КОЖНОГО стовпця не вміщається
     в рядок заголовків фізично. Тому на телефоні пояснення переїжджає в ОДИН
     значок над таблицею — там воно не коштує ширини жодній колонці, і дотик
     у нього повний. Заголовки лишаються голими й вузькими. */
  .grid th .gl { display: none; }
  /* `:has(.gl)` бачить елемент у DOM навіть коли він `display:none` — тому
     базове правило (`style.css`) звільняло б під невидимий значок 22px саме
     там, де кожен піксель на рахунку. Повертаємо звичайний правий відступ. */
  .grid th:has(.gl) { padding-right: 5px; }

  /* Легенда скорочень: один значок біля підпису над таблицею. На десктопі
     вона теж є (там же, `manager.js`), але не єдиний спосіб пояснення —
     значки при кожному заголовку там нікуди не зникають. */
  .m-legend {
    display: inline-flex; align-items: center; gap: 4px;
    min-height: var(--m-tap); font-size: var(--fs-12); color: var(--text-2);
  }
  .m-legend .gl { display: inline-flex; }

  /* ПЕРШИЙ СТОВПЕЦЬ У «Перевірці» та Чит-детекторі закріплений скрізь
     (`style.css`); тут — лише вужча ширина під 112px-колонку рейтингу поруч
     і прибраний аватар, якому на телефоні просто немає де влізти. */
  #q-checkers th:first-child, #q-checkers td:first-child,
  #q-packers th:first-child, #q-packers td:first-child,
  .grid.cheat th:first-child, .grid.cheat td:first-child {
    max-width: 124px;
    box-shadow: 4px 0 6px -3px rgba(0, 0, 0, .75);
  }
  /* Без аватара: на телефоні він забирає 34px зі 124, тобто третину місця
     під саме ім'я (перенесення рядка — вже загальне правило, style.css). */
  #q-checkers td:first-child .avatar, #q-packers td:first-child .avatar,
  .grid.cheat td:first-child .avatar { display: none; }
  /* Рядок таблиці теж натискається (відкриває картку) — тому й він не менший
     за палець. */
  .grid-rankings tbody tr { min-height: var(--m-tap); }
  .grid-rankings tbody td { padding-top: 10px; padding-bottom: 10px; }

  /* Прокрутка таблиці: висота під екран, а не під `100vh - 215px` (на
     телефоні це давало вікно, вище за сам екран, і сторінка отримувала
     другий, вкладений скрол). */
  .table-scroll { max-height: none; overflow-x: auto; overflow-y: visible; }

  /* Таблиця мусить гортатись УСЕРЕДИНІ своєї коробки, а не тягнути за собою
     сторінку. Сама по собі `.table-scroll { overflow:auto }` цього не робить:
     `.page` — це flex-колонка, а flex-елемент за замовчуванням має
     `min-width: auto`, тобто НЕ звужується менше за свій вміст. Таблиця на
     2232px чесно розсовувала контейнер, і горизонтально їхала вся сторінка
     разом із шапкою. Явний `min-width: 0` повертає flex-елементу право
     бути вужчим за вміст — і прокрутка нарешті дістається таблиці. */
  .page > *, #m-content, .table-scroll { min-width: 0; max-width: 100%; }

  /* ---- 10. Огляд команди (review.js) ---------------------------------- */
  /* Той самий дефект, що в картці: `repeat(auto-fit, minmax(330px, 1fr))`
     створює доріжку 330px навіть у вікні 320 — сітка ширша за екран ще до
     вмісту. Це третє місце в застосунку з тією ж помилкою (dp-grid, rv-grid,
     і колонки Manager), і всі три давали однаковий симптом. */
  /* Той самий дефект зустрічається в застосунку ЧОТИРИ рази — `dp-grid` (430),
     `rv-grid` (330), `rv-charts` (460) і колонки Manager. Решта сіток із
     фіксованим мінімумом (112 · 120 · 132 · 150 · 168px) у 320px влазять і
     нічого не ламають, тому їх не чіпаємо. */
  .rv-grid { grid-template-columns: minmax(0, 1fr); padding: 12px var(--m-pad); gap: 10px; }
  .rv-charts { grid-template-columns: minmax(0, 1fr); padding: 12px var(--m-pad); gap: 10px; }
  /* 72px, а не 60: найдовший підпис ліги — «Stapler» — це рівно 64px, і в
     колонці 60px він малювався поверх графіка. Спіймано новою перевіркою
     «текст вилазить за свою коробку», доданою того ж дня; до неї такий дефект
     проходив повз прилад повністю. */
  .rv-chline { grid-template-columns: 72px minmax(0, 1fr); gap: 8px; }
  .rv-chart { padding: 4px 10px 12px; }
  /* Заголовок панелі «Пікінг — динаміка» згортає графік, тобто це кнопка,
     а не підпис — і мусить бути завбільшки з палець. */
  .rv-cht[data-fold] { min-height: var(--m-tap); }

  /* Перемикач масштабу графіка («масштаб: авто · дні · тижні · місяці»).
     Кнопки були 36×19 і 51×19 — удвічі нижчі за палець. Знайдено 17.08.2026
     проходом ПО ПЕРІОДАХ: цього перемикача просто немає на одноденному
     періоді, а всі попередні виміри робились саме на ньому. Тобто дефект
     жив у стані екрана, до якого прилад жодного разу не дійшов. */
  .rv-gran { margin-left: 0; flex-wrap: wrap; gap: 6px; width: 100%; }
  .rv-gran button { min-height: var(--m-tap); padding: 0 12px; font-size: var(--fs-13); }
  /* Імена в оглядах команди переносяться, а не обрізаються: «Anastasiia
     Khudaiiar…» і «Bekmyrza Abdilashimo…» — це рівно той дефект, з якого
     почалась уся робота, просто на іншому екрані. */
  .rv-nm { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }

  /* ---- 11. Картка працівника (deep.js) -------------------------------- */
  /* Головний екран за рішенням власника: з телефона треба не «глянути бал»,
     а розібратись у показниках людини. Тому нічого не ховаємо — усі дванадцять
     чисел, усі вісім панелей, тренд і порівняння з лігою лишаються. Міняється
     лише те, як вони вкладені: один стовпець замість двох. */

  /* ГОЛОВНА ПРИЧИНА ГОРИЗОНТАЛЬНОГО СКРОЛУ НА ЦЬОМУ ЕКРАНІ.
     `repeat(auto-fit, minmax(430px, 1fr))` при ширині вікна 320 усе одно
     створює доріжку 430px — auto-fit прибирає ЗАЙВІ доріжки, але не звужує
     мінімум. Тобто сітка була ширша за екран на 110px ще до вмісту. */
  .dp-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 0 var(--m-pad); }

  /* Шапка картки перестає бути липкою: на телефоні вона займає до третини
     екрана (аватар, ім'я, період, дві групи вкладок), і в липкому вигляді
     з'їдала б саме те місце, заради якого людина сюди прийшла. */
  /* Шапка в дві смуги замість чотирьох: «Назад» і людина — в одну, період і
     вкладки — у другу. Розкладка «як перенесеться» давала «Назад» окремим
     рядком, потім людину, потім період, потім вкладки — і перше число картки
     починалось нижче другого екрана прокрутки. */
  .dp-top {
    position: static; gap: 8px; padding: 10px var(--m-pad);
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  }
  .dp-top #dp-back { grid-column: 1; grid-row: 1; }
  .dp-who { grid-column: 2 / -1; grid-row: 1; }
  .dp-period { grid-column: 1 / 3; grid-row: 2; }
  .dp-tabs { grid-column: 3; grid-row: 2; }
  .dp-roles { grid-column: 1 / -1; grid-row: 3; margin-left: 0; }
  .dp-sub { gap: 6px; margin-top: 2px; }
  .dp-who { min-width: 0; }
  /* Позначка «⇄ Універсал · пікінг 5,6 год · пакінг 2,1 год» має
     `white-space: nowrap` — на десктопі правильно, бо розривати її посередині
     безглуздо. На 402px вона довша за екран, і оскільки сторінка навмисно не
     гортається вбік, half тексту ставав НЕДОСЯЖНИМ: не «незручно», а втрачена
     інформація. Знайдено у справжньому Safari на симуляторі — прилад міряв
     картку людини БЕЗ цієї ознаки й чесно давав ✓ (16.08.2026). */
  .dp-sub .tag.dual { white-space: normal; }
  .dp-sub > * { min-width: 0; }
  .dp-period select { width: 100%; }
  .dp-name { font-size: var(--fs-18); }
  .dp-photo { width: 40px; height: 40px; }
  .dp-lgs { padding: 10px var(--m-pad) 0; }
  .dp-lgs button { min-height: var(--m-tap); }

  /* Дванадцять чисел — по два в рядок. Один стовпець (наслідок minmax(150px))
     розтягував їх на шість екранів прокрутки до першого графіка. */
  .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 10px var(--m-pad); }

  .chart-wrap, .dp-cmp, .dp-hrs { padding-left: 10px; padding-right: 10px; }
  .panel-title { padding: 10px 12px; flex-wrap: wrap; gap: 6px; }

  /* Вісь дат у тренді: підпис «01.08» — це ~34px при ширині стовпчика 22px
     (16 днів на 402px). Підписи налазили один на одного суцільною смугою
     «01.02.03.04.08…», і це не читалось узагалі. Прилад такого не ловить:
     текст не обрізаний і не дрібний, він просто накладений — тому знайдено
     оком, а не вимірюванням.
     Лишаємо кожен четвертий день як опору для ока; літера дня тижня (2 знаки)
     влазить у стовпчик і лишається в кожного. `visibility`, а не `display`:
     прибраний з потоку підпис змінив би висоту стовпчика й збив би вирівнювання
     сусідів. */
  .dp-days .dp-dl { visibility: hidden; }
  .dp-days .dp-dc:nth-child(4n + 1) .dp-dl { visibility: visible; }
  /* …але коли стовпчиків мало, ховати нічого не треба. За квартал і рік
     `buckets.py` дає тренд по тижнях або місяцях — це 6–12 стовпчиків
     завширшки 45–60px, і підпис «06.07» (34px) у них вільно вміщається.
     Правило «кожен четвертий» лишало на графіку два підписи з шести й
     перетворювало вісь на загадку. Кількісний запит: якщо перший стовпчик
     одночасно входить у останні вісім — значить їх усього не більше восьми. */
  .dp-days .dp-dc:first-child:nth-last-child(-n + 8) .dp-dl,
  .dp-days .dp-dc:first-child:nth-last-child(-n + 8) ~ .dp-dc .dp-dl { visibility: visible; }

  /* «Проти своєї ліги»: підпис на власний рядок, смуга — на всю ширину під ним.
     У чотириколонковій розкладці (128px підпис + смуга + два числа) на 402px
     смузі лишалось близько 40px — тобто саме порівняння, заради якого панель
     існує, перетворювалось на риску завширшки з палець. Підпис угорі коштує
     один рядок висоти й повертає смузі всю ширину екрана. */
  .dp-c {
    grid-template-columns: minmax(0, 1fr) auto auto auto;
    gap: 4px 8px; padding: 8px 4px;
  }
  .dp-cl { grid-column: 1 / -1; }
  .dp-cgap, .dp-cr { font-size: var(--fs-12); }

  /* Назва служби доставки — на власний рядок над смугами. Колонка в 92px
     різала «DE_DPD_NORTH0…», «MSF_SELF_AMXL…» і «DE_WARENPOST…» рівно там, де
     починається відмінність між ними; три однакові обрізки поспіль — це не
     таблиця, а загадка. Ширшати колонці нікуди: поруч три смуги порівняння. */
  .mxrow { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px 10px; }
  .mxk {
    grid-column: 1 / -1;
    white-space: normal; overflow: visible; text-overflow: clip;
    overflow-wrap: anywhere; font-size: var(--fs-13);
  }

  /* Ініціали в аватарі — теж текст, і теж мають читатись. `clamp(10px, 1vw…)`
     на 402px дає рівно нижню межу, 10px. */
  .avatar { font-size: var(--fs-12); }

  /* Іконка-пояснення. Видимий кружечок лишається 16px (більший виглядав би
     як кнопка дії), але НАТИСКАЄТЬСЯ саме `.gl` — на ньому обробник, — тож
     їй і дається повний розмір пальця. Від'ємні поля не дають цьому розміру
     розсунути рядок, у якому вона стоїть. */
  .gl {
    width: var(--m-tap); height: var(--m-tap);
    align-items: center; justify-content: center;
    margin: -14px 0 -14px -6px;
  }
  /* …АЛЕ від'ємні поля означають, що область у 44px виступає на 14px угору й
     униз за свій рядок. У заголовку панелі під ним стоїть пояснення дрібним
     шрифтом — і область іконки лягала просто на нього: тап по початку
     пояснення відкривав би підказку замість того, щоб нічого не робити.
     Знайдено 17.08.2026 новою перевіркою «сусіди налазять» — тобто прилад
     спіймав наслідок моєї ж попередньої правки.
     Рішення без винятків для приладу: пояснення переїжджає на власний рядок
     (`flex-basis: 100%`), а сам рядок заголовка стає не нижчим за палець —
     тоді 44px іконки поміщаються в нього ЦІЛКОМ і нічого не перекривають. */
  .panel-title { min-height: var(--m-tap); row-gap: 8px; }
  .panel-title .muted { flex-basis: 100%; }
  .panel-title .gl { margin-top: 0; margin-bottom: 0; }
}

/* ==========================================================================
   Саме телефон
   ========================================================================== */

@media (max-width: 767px) {

  :root { --m-pad: 10px; }

  /* Дрібніше за 12px на телефоні не читається — критерій приймання.
     Тут не «зробити все крупним», а підняти саме нижню межу. */
  .small, .dim.small, .pill, .muted { font-size: var(--fs-12); }

  .nav .brand { font-size: 14px; }
  .page { padding: var(--m-pad) var(--m-pad) 0; }

  /* Аватар у таблиці Manager — тільки на планшеті й ширше. У колонці 112px він
     забирає 34px, лишаючи імені 66: «Kobaneishvili» не вміщалось у рядок і
     ламалось посеред слова на «Kobaneis / hvili». Аватар тут декоративний —
     людину в таблиці шукають за іменем, а не за кольоровим кружечком; у
     рейтингу, де рядок один на людину і його треба впізнати за секунду,
     аватар лишається. */
  .grid-rankings td:nth-child(2) .avatar { display: none; }

  /* Ім'я того, хто ввійшов, — не на 375px. Воно нічого не вирішує (кнопка
     «Вийти» поруч і без нього каже, що сесія є), а «Viktoriia Kornieieva»
     з'їдає половину шапки. */
  .session .who { display: none; }

  /* Шапка в дві СВІДОМІ смуги, а не «як перенесеться».
     Без цього на 402px переносилась одна кнопка «Вийти» — другий рядок на
     одну кнопку виглядає як недоробка. Розпірка, що вже є в розмітці між
     сигналами й службовими кнопками, перетворюється на розрив рядка: угорі
     впізнавання і те, що вимагає уваги (назва, дзвіночок аномалій), нижче —
     керування (склад, вихід, довідка). Нічого не ховається. */
  .nav .spacer { flex-basis: 100%; height: 0; }
  /* Дзвіночок — до правого краю свого рядка. Він стояв упритул до назви
     продукту, а решта рядка лишалась порожньою: два предмети в лівому куті й
     280px порожнечі праворуч читаються як недороблена розкладка, а червоний
     лічильник упритул до логотипа перетягує на себе увагу, якої вартий
     заголовок розділу. Рознесені по краях, вони обидва на місці: ліворуч
     «де я», праворуч «що вимагає уваги». */
  #nav-notify { margin-left: auto; }
  /* Той самий прийом для другого рядка: довідка й склад ліворуч, вихід із
     сесії — до правого краю. Інакше три предмети тиснуться вліво, а третина
     ширини лишається порожньою — рядок читається як обрізаний. */
  .session { margin-left: auto; }

  /* Шапка на телефоні НЕ липка. У дві смуги вона займає ~110px з 681 — 16 %
     екрана назавжди, і разом із нижньою панеллю це чверть висоти під те, що
     не є вмістом. Навігація вже внизу й нікуди не дівається, тому шапка може
     чесно поїхати вгору разом зі сторінкою. */
  .nav { position: static; padding-bottom: 6px; }
}

/* ==========================================================================
   ПЛАНШЕТ — 768…1024
   Той самий мобільний шар вище (розміри дотику, нижня панель, кегль), але
   розкладка НЕ телефонна. Критерій приймання каже прямо: планшет не має
   виглядати розтягнутим телефоном — а один стовпець на 1024px це саме воно.
   Тут повертаються два стовпці там, де вони поміщаються: у мінімум 330px
   на планшеті влазить дві колонки, у 402px телефона — жодної.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1024px),
       (min-width: 768px) and (pointer: coarse) and (max-width: 1400px) {

  .dp-grid, .rv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Графіки динаміки лишаються на всю ширину: у них горизонтальна вісь на
     десятки поділок, і половина планшета робить із них ту саму кашу
     з дат, що на телефоні. */
  .rv-charts { grid-template-columns: minmax(0, 1fr); }
  .stat-row { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* Місця вистачає — підпис довідкової сторінки повертається. */
  .nav-roadmap, .nav-faq { width: auto; padding: 5px 12px; }
  .nav-roadmap .lb, .nav-faq .lb { display: inline; }
  .session .who { display: inline; }
  /* І шапка знову в один рядок: розрив був потрібен лише телефону. */
  .nav .spacer { flex-basis: auto; flex: 1; height: auto; }

  /* Вісь дат: на планшеті стовпчик удвічі ширший, тому підписів можна
     показати вдвічі більше, ніж на телефоні. */
  .dp-days .dp-dc:nth-child(2n + 1) .dp-dl { visibility: visible; }

  /* Ім'я в таблиці Manager знову вміщається в один рядок. */
  .grid-rankings th:nth-child(2), .grid-rankings td:nth-child(2) { width: 180px; min-width: 180px; max-width: 180px; }
  .grid-rankings th:nth-child(3), .grid-rankings td:nth-child(3) { left: 206px; }
}
