/* ============================================================
   TechSpark CRM — мобильный слой.

   Подключается на каждой странице ПОСЛЕ /tailwind.css:
     <link rel="stylesheet" href="/tailwind.css" />
     <link rel="stylesheet" href="/mobile.css" />

   Принципы:
   1. Десктоп (>=1024px) НЕ ТРОГАЕМ вообще. Все правила живут внутри
      @media (max-width: 1023px) или уже. Ни одно правило не должно
      менять вид на широком экране — это гарантия отсутствия регрессий.
   2. Утилиты Tailwind перебиваем через !important, потому что специфичность
      одноклассовых утилит равна нашей. Это осознанный override-слой, а не
      небрежность: другого способа адаптировать 34 страницы без правки
      каждой разметки нет.
   3. Разметку страниц не переписываем. Классы-хуки (.ts-mcards, .ts-msheet,
      .ts-mgrid-2, .ts-xscroll) проставляет рантайм — /mobile.js — по
      эвристикам. Так адаптация не отстаёт от новых страниц.

   Брейкпоинты:
     <1024px  — «мобильная оболочка»: sidebar → drawer, app bar, таб-бар.
                Сюда попадают и планшеты в портрете (768–1023).
     <768px   — таблицы превращаются в карточки.
     <640px   — телефон: одноколоночность, bottom sheet вместо модалок.
   ============================================================ */

:root {
  --ts-appbar-h: 56px;
  --ts-tabbar-h: 56px;
  --ts-safe-b: env(safe-area-inset-bottom, 0px);
  --ts-safe-t: env(safe-area-inset-top, 0px);
}

/* ============================================================
   1. ОБЩИЕ ЗАЩИТЫ
   ============================================================ */
@media (max-width: 1023px) {
  html,
  body {
    max-width: 100%;
    /* Горизонтальный скролл страницы целиком — главный признак «сайт не
       адаптирован». Широкие блоки (таблицы, недельная сетка) скроллятся
       внутри своих .overflow-x-auto контейнеров, а не тянут body.
       Именно `clip`, а не `hidden`: hidden делает body скролл-контейнером,
       и тогда position:sticky у шапок таблиц начинает считаться от него —
       прилипание ломается. clip обрезает, не создавая контейнер. */
    overflow-x: clip;
  }

  /* Серый мигающий прямоугольник при тапе по ссылкам/кнопкам в iOS/Android. */
  a,
  button,
  [role='button'] {
    -webkit-tap-highlight-color: rgba(79, 70, 229, 0.15);
  }

  /* Длинные слова (email, названия групп, ID) не должны распирать карточку. */
  h1,
  h2,
  h3,
  td,
  th,
  p {
    overflow-wrap: anywhere;
  }
}

/* ============================================================
   2. ОБОЛОЧКА: drawer + app bar + bottom tab bar
   ------------------------------------------------------------
   На десктопе sidebar.js строит: body.flex > [aside.ts-sidebar] [#ts-main].
   На мобиле тот же DOM переиспользуется: aside становится выезжающим
   drawer'ом (position:fixed + translateX), #ts-main занимает всю ширину.
   ============================================================ */

/* Элементы оболочки, существующие только в мобильном режиме,
   на десктопе скрыты полностью. */
.ts-appbar,
.ts-tabbar,
.ts-scrim,
.ts-fab {
  display: none;
}

@media (max-width: 1023px) {
  /* body.flex ставит sidebar.js (aside + main в строку) — на мобиле эта
     раскладка не нужна. Обязательно вместе с .ts-shell: на /login.html
     body.flex стоит в самой разметке и центрирует форму входа, ломать его
     нельзя. .ts-shell есть только там, где отработал sidebar.js. */
  body.ts-shell.flex {
    display: block !important;
  }

  /* ---------- 2.1 Drawer ---------- */
  .ts-sidebar {
    position: fixed !important;
    top: 0;
    left: 0;
    z-index: 70;
    width: min(84vw, 300px) !important;
    height: 100vh; /* фолбэк для браузеров без dvh */
    height: 100dvh;
    min-height: 0 !important;
    transform: translateX(-100%);
    transition: transform 240ms cubic-bezier(0.32, 0.72, 0, 1);
    box-shadow: 0 0 28px rgba(0, 0, 0, 0.35);
    padding-top: var(--ts-safe-t);
    /* Инерционный скролл длинного меню на iOS. */
    overscroll-behavior: contain;
  }
  body.ts-drawer-open .ts-sidebar {
    transform: translateX(0);
  }
  /* Пока drawer не открывали ни разу — гасим transition, чтобы он не
     «прилетал» слева на первой отрисовке страницы. */
  body:not(.ts-drawer-ready) .ts-sidebar {
    transition: none;
  }

  /* Затемнение под drawer'ом. */
  .ts-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(17, 24, 39, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 240ms ease;
  }
  body.ts-drawer-open .ts-scrim {
    opacity: 1;
    pointer-events: auto;
  }
  /* Блокировка прокрутки фона, пока открыт drawer. */
  body.ts-drawer-open {
    overflow: hidden;
  }

  /* Пункты меню в drawer — крупнее, палец не должен промахиваться. */
  .ts-sidebar nav a {
    padding-top: 0.625rem !important;
    padding-bottom: 0.625rem !important;
    font-size: 0.9375rem !important;
  }

  /* ---------- 2.2 Основная колонка ---------- */
  #ts-main {
    min-height: 100vh; /* фолбэк для браузеров без dvh */
    min-height: 100dvh;
    padding-top: calc(var(--ts-appbar-h) + var(--ts-safe-t));
    /* Место под таб-бар, иначе последний блок уезжает под него. */
    padding-bottom: calc(var(--ts-tabbar-h) + var(--ts-safe-b));
  }

  /* Десктопный header sidebar.js (заголовок + поиск w-80 + колокольчик)
     на телефоне не помещается — его заменяет .ts-appbar. */
  .ts-desktop-header {
    display: none !important;
  }

  /* ---------- 2.3 App bar ---------- */
  .ts-appbar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 60;
    height: calc(var(--ts-appbar-h) + var(--ts-safe-t));
    padding: var(--ts-safe-t) 0.25rem 0;
    background: #111827;
    color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  }
  .ts-appbar__btn {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    font-size: 19px;
    line-height: 1;
    background: transparent;
    color: #fff;
    border: 0;
    cursor: pointer;
  }
  .ts-appbar__btn:active {
    background: rgba(255, 255, 255, 0.14);
  }
  .ts-appbar__title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding-left: 0.125rem;
  }
  /* Режим поиска: поле разворачивается на всю ширину app bar. */
  .ts-appbar__search {
    display: none;
    flex: 1 1 auto;
    min-width: 0;
    height: 38px;
    border: 0;
    border-radius: 10px;
    padding: 0 0.75rem;
    /* 16px — ниже этого значения iOS Safari зумит страницу при фокусе. */
    font-size: 16px;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    outline: none;
  }
  .ts-appbar__search::placeholder {
    color: rgba(255, 255, 255, 0.55);
  }
  .ts-appbar.is-searching .ts-appbar__title,
  .ts-appbar.is-searching .ts-appbar__btn[data-act='search'] {
    display: none;
  }
  .ts-appbar.is-searching .ts-appbar__search {
    display: block;
  }

  /* ---------- 2.4 Bottom tab bar ---------- */
  .ts-tabbar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    height: calc(var(--ts-tabbar-h) + var(--ts-safe-b));
    padding-bottom: var(--ts-safe-b);
    background: #ffffff;
    border-top: 1px solid #e5e7eb;
    box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.06);
  }
  .ts-tabbar__item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 4px 2px;
    font-size: 10px;
    line-height: 1.15;
    color: #6b7280;
    text-decoration: none;
    background: none;
    border: 0;
    cursor: pointer;
    position: relative;
  }
  .ts-tabbar__item span:first-child {
    font-size: 19px;
    line-height: 1;
  }
  .ts-tabbar__item.is-active {
    color: #4f46e5;
    font-weight: 600;
  }
  .ts-tabbar__item.is-active::before {
    content: '';
    position: absolute;
    top: 0;
    left: 22%;
    right: 22%;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: #4f46e5;
  }
  .ts-tabbar__label {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Счётчик на иконке таба (заявки, согласования и т.п.). */
  .ts-tabbar__dot {
    position: absolute;
    top: 4px;
    left: 50%;
    margin-left: 4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: #f59e0b;
    color: #fff;
    font-size: 9px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
  }

  /* ---------- 2.5 FAB (главное действие страницы) ---------- */
  .ts-fab {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    right: 16px;
    bottom: calc(var(--ts-tabbar-h) + var(--ts-safe-b) + 16px);
    z-index: 55;
    width: 54px;
    height: 54px;
    border-radius: 999px;
    border: 0;
    background: #4f46e5;
    color: #fff;
    font-size: 26px;
    line-height: 1;
    box-shadow: 0 6px 18px rgba(79, 70, 229, 0.45);
    cursor: pointer;
  }
  .ts-fab:active {
    transform: scale(0.94);
  }
  /* Пока открыт drawer или модалка — FAB прячем, он мешает. */
  body.ts-drawer-open .ts-fab,
  body.ts-modal-open .ts-fab {
    display: none;
  }
}

/* ============================================================
   3. КОМПАКТНАЯ ВЁРСТКА КОНТЕНТА (телефон)
   ============================================================ */
@media (max-width: 639px) {
  /* Страницы задают main.px-6 py-6 — на 375px это съедает 48px ширины. */
  main.px-6,
  main.px-4 {
    padding-left: 0.75rem !important;
    padding-right: 0.75rem !important;
  }
  main.py-6 {
    padding-top: 0.875rem !important;
    padding-bottom: 0.875rem !important;
  }

  /* Внутренние отступы карточек. */
  .p-8 {
    padding: 1.25rem !important;
  }
  .p-6 {
    padding: 1rem !important;
  }
  .px-6:not(main):not(.ts-keep-pad) {
    padding-left: 0.875rem !important;
    padding-right: 0.875rem !important;
  }
  .px-5:not(.ts-keep-pad) {
    padding-left: 0.875rem !important;
    padding-right: 0.875rem !important;
  }

  /* Заголовки страниц: text-2xl (24px) в мобильной вёрстке слишком
     доминирует над содержимым. */
  h1.text-2xl {
    font-size: 1.25rem !important;
    line-height: 1.75rem !important;
  }
  .text-3xl {
    font-size: 1.5rem !important;
    line-height: 2rem !important;
  }

  /* Собственные градиентные шапки страниц (index/students/student/matching):
     на телефоне поджимаем, чтобы не занимали пол-экрана. */
  header.bg-gradient-to-r .px-6 {
    padding-left: 0.875rem !important;
    padding-right: 0.875rem !important;
  }
  header.bg-gradient-to-r .py-5,
  header.bg-gradient-to-r .py-4 {
    padding-top: 0.75rem !important;
    padding-bottom: 0.75rem !important;
  }

  /* «Шапка раздела»: заголовок слева, кнопка справа — на телефоне в столбик,
     кнопка на всю ширину (её легко нажать большим пальцем). */
  .ts-mstack {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .ts-mstack > button,
  .ts-mstack > a.ts-mbtn {
    width: 100%;
  }

  /* Сетки без адаптивных префиксов (проставляет mobile.js). */
  .ts-mgrid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  .ts-mgrid-1 {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* Двухколоночные KPI-плитки: цифра 2xl + подпись. Ужимаем цифру. */
  .ts-mgrid-2 .text-2xl {
    font-size: 1.25rem !important;
    line-height: 1.75rem !important;
  }
}

/* ------------------------------------------------------------
   3.1 Прилипающие шапки таблиц.
   `sticky top-0` прилипает к верху вьюпорта — то есть УХОДИТ под
   фиксированный app bar. Сдвигаем на его высоту.
   ------------------------------------------------------------ */
@media (max-width: 1023px) {
  body.ts-shell .sticky.top-0 {
    top: calc(var(--ts-appbar-h) + var(--ts-safe-t)) !important;
  }
  /* Прилипающий подвал модалки (кнопки «Сохранить/Отмена») не должен
     наезжать на таб-бар. */
  body.ts-shell .sticky.bottom-0 {
    bottom: 0 !important;
  }
}

/* ------------------------------------------------------------
   3.2 Собственные шапки страниц.
   Заголовок из <header> дублируется в app bar (mobile.js переносит
   туда его текст, включая динамический — имя ученика), поэтому в
   самой шапке он лишний.
   ------------------------------------------------------------ */
@media (max-width: 639px) {
  .ts-mirrored-title {
    display: none !important;
  }

  /* Группа действий, прижатая вправо через ml-auto: на узком экране
     разворачиваем во всю ширину отдельной строкой, иначе фильтры,
     поиск и кнопка «Добавить» не умещаются в одну линию. */
  header .flex-wrap > .ml-auto,
  main .flex-wrap > .ml-auto {
    width: 100%;
    margin-left: 0 !important;
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }
  /* Поля поиска с фиксированной шириной (w-72/w-80) шире экрана. */
  input.w-72,
  input.w-80,
  input.w-64 {
    width: 100% !important;
    flex: 1 1 100%;
  }
}

/* ============================================================
   4. ГОРИЗОНТАЛЬНЫЕ СКРОЛЛ-ЛЕНТЫ (фильтры, табы, чипы)
   ------------------------------------------------------------
   Ряды из 4–8 маленьких кнопок («Все / Активные / Пауза / Ушли / Архив»)
   при flex-wrap превращаются в три рваные строки. Лента со свайпом
   компактнее и привычнее на телефоне.
   ============================================================ */
@media (max-width: 1023px) {
  .ts-xscroll {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Лента должна доезжать до края экрана — иначе непонятно, что она скроллится. */
    scroll-snap-type: x proximity;
  }
  .ts-xscroll::-webkit-scrollbar {
    display: none;
  }
  .ts-xscroll > * {
    flex: 0 0 auto;
    scroll-snap-align: start;
  }
}

/* ============================================================
   5. ТАБЛИЦЫ → КАРТОЧКИ
   ------------------------------------------------------------
   Таблица на 8–10 колонок на телефоне нечитаема даже со скроллом.
   mobile.js проставляет каждой ячейке data-th (из <thead>) и вешает
   на таблицу .ts-mcards — здесь строка превращается в карточку
   «подпись → значение».
   ============================================================ */
@media (max-width: 767px) {
  table.ts-mcards {
    display: block;
    width: 100% !important;
  }
  table.ts-mcards thead {
    /* Заголовки не нужны — они переехали в data-th каждой ячейки.
       display:none, а не visibility, чтобы не занимали место. */
    display: none;
  }
  table.ts-mcards tbody,
  table.ts-mcards tfoot {
    display: block;
  }
  table.ts-mcards tr {
    display: block;
    margin: 0 0 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid #e5e7eb;
    border-radius: 0.625rem;
    background: #fff;
  }
  /* Цветовую заливку строки (просрочка, отменённые) сохраняем как левую
     полосу — фон карточки остаётся белым и текст читается. */
  table.ts-mcards tr[class*='bg-'] {
    border-left-width: 4px;
  }
  table.ts-mcards td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    width: auto !important;
    padding: 0.3rem 0 !important;
    border: 0 !important;
    text-align: right !important;
    white-space: normal !important;
  }
  table.ts-mcards td::before {
    content: attr(data-th);
    flex: 0 0 40%;
    text-align: left;
    color: #6b7280;
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    line-height: 1.4;
  }
  /* Ячейки без подписи в шапке (кнопки действий, иконки) — во всю ширину. */
  table.ts-mcards td[data-th='']::before,
  table.ts-mcards td.ts-mfull::before {
    display: none;
  }
  table.ts-mcards td.ts-mfull {
    justify-content: flex-start;
    text-align: left !important;
  }
  /* Первая ячейка — «заголовок карточки»: имя ученика, название группы. */
  table.ts-mcards td.ts-mtitle {
    display: block;
    padding-bottom: 0.4rem !important;
    margin-bottom: 0.25rem;
    border-bottom: 1px solid #f3f4f6 !important;
    font-weight: 600;
    font-size: 0.9375rem;
    text-align: left !important;
  }
  table.ts-mcards td.ts-mtitle::before {
    display: none;
  }
  /* Строка-заглушка («Загружаю…», «Ничего не найдено») — без карточки. */
  table.ts-mcards tr.ts-mplain {
    border: 0;
    background: transparent;
    padding: 0;
  }
  table.ts-mcards tr.ts-mplain td {
    display: block;
    text-align: center !important;
  }
  table.ts-mcards tr.ts-mplain td::before {
    display: none;
  }
  /* Контейнер, который на десктопе давал горизонтальный скролл, больше
     не нужен — карточки укладываются по ширине. */
  .ts-mcards-host {
    overflow-x: visible !important;
    background: transparent !important;
    box-shadow: none !important;
  }
}

/* ============================================================
   6. МОДАЛКИ → BOTTOM SHEET
   ------------------------------------------------------------
   На телефоне центрированное окно с max-w-md выглядит как обрезок и
   при открытой клавиатуре уезжает. Шторка снизу — нативный паттерн:
   палец рядом, кнопки внизу, есть куда скроллить.
   ============================================================ */

/* ------------------------------------------------------------
   6.1 Общее для ВСЕЙ мобильной полосы (<1024px), не только телефона.
   Два бага, из-за которых кнопки формы были недостижимы:
     1) оверлеи модалок в разметке — `z-50`, а app bar и таб-бар — 60.
        Оболочка накрывала окно, и подвал с «Создать»/«Сохранить»
        оказывался под таб-баром.
     2) у большинства модалок нет потолка по высоте: высокая форма
        (новый ученик, добавление занятий) просто уезжала за нижний
        край экрана, доскроллить до кнопок было нельзя.
   ------------------------------------------------------------ */
@media (max-width: 1023px) {
  .ts-msheet {
    /* Выше app bar и таб-бара (60). Оболочка корректно уходит под
       затемнение — так и должно быть, пока открыто модальное окно. */
    z-index: 80 !important;
  }
  .ts-msheet > .ts-msheet-card {
    display: flex;
    flex-direction: column;
    /* −40px: оверлей в разметке идёт с `p-4`, окно должно уместиться
       внутри его отступов. */
    max-height: calc(100vh - 40px); /* фолбэк для браузеров без dvh */
    max-height: calc(100dvh - 40px);
    /* По умолчанию прокручивается всё окно целиком. Если mobile.js смог
       выделить тело между шапкой и подвалом — прокрутка уезжает туда
       (.ts-has-body ниже), а подвал с кнопками остаётся приколот. */
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .ts-msheet > .ts-msheet-card.ts-has-body {
    overflow: hidden;
  }
  .ts-msheet > .ts-msheet-card > .ts-msheet-body {
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
}

/* ------------------------------------------------------------
   6.2 Телефон: окно превращается в шторку снизу.
   ------------------------------------------------------------ */
@media (max-width: 639px) {
  .ts-msheet {
    align-items: flex-end !important;
    justify-content: stretch !important;
    padding: 0 !important;
  }
  .ts-msheet > .ts-msheet-card {
    width: 100% !important;
    max-width: 100% !important;
    max-height: 92vh; /* фолбэк для браузеров без dvh */
    max-height: 92dvh;
    margin: 0 !important;
    border-radius: 1rem 1rem 0 0 !important;
    /* Домашний индикатор iPhone (X и новее, в т.ч. 11) перекрывает нижние
       ~34px. Без этого отступа кнопка «Создать» лежит прямо под ним и
       нажимается через раз. */
    padding-bottom: var(--ts-safe-b);
    /* Выезд снизу. */
    animation: ts-sheet-in 220ms cubic-bezier(0.32, 0.72, 0, 1);
  }
  /* У пары окон отступ задан на самой карточке (`p-6`) — сохраняем его,
     добавляя безопасную зону сверху, а не затирая. */
  .ts-msheet > .ts-msheet-card.p-6 {
    padding-bottom: calc(1.5rem + var(--ts-safe-b));
  }
  /* «Ручка» шторки — визуальная подсказка, что окно можно закрыть свайпом вниз. */
  .ts-msheet > .ts-msheet-card::before {
    content: '';
    flex: 0 0 auto;
    width: 36px;
    height: 4px;
    margin: 8px auto 2px;
    border-radius: 999px;
    background: #d1d5db;
  }
  @keyframes ts-sheet-in {
    from {
      transform: translateY(100%);
    }
    to {
      transform: translateY(0);
    }
  }
  /* Ряды кнопок в шторке — на всю ширину и покрупнее. */
  .ts-msheet .ts-msheet-card button:not(.ts-icon-btn) {
    min-height: 42px;
  }
}

/* ============================================================
   7. ФОРМЫ И ТАЧ-ТАРГЕТЫ
   ============================================================ */
@media (max-width: 1023px) {
  /* 16px — порог, ниже которого iOS Safari зумит вьюпорт при фокусе в поле.
     Зум после этого не откатывается и ломает вёрстку до перезагрузки. */
  input:not([type='checkbox']):not([type='radio']),
  select,
  textarea {
    font-size: 16px !important;
  }
  input:not([type='checkbox']):not([type='radio']):not(.ts-appbar__search),
  select,
  textarea {
    min-height: 42px;
  }
  /* Чекбоксы/радио в списках (журнал посещаемости) — увеличиваем. */
  input[type='checkbox'],
  input[type='radio'] {
    width: 20px;
    height: 20px;
  }

  /* Кнопки: минимальная область нажатия. Мелкие иконочные кнопки
     (×, ↻, ←/→) исключены — им хватает 32px и они стоят вплотную. */
  button:not(.ts-icon-btn):not(.ts-appbar__btn):not(.ts-tabbar__item),
  a.ts-mbtn {
    min-height: 38px;
  }

  /* Ряды полей внутри форм: label над полем — читаемее, чем в две колонки. */
  .ts-mform-1 {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

/* ============================================================
   8. ТОЧЕЧНЫЕ ПРАВКИ РАЗДЕЛОВ
   ============================================================ */
@media (max-width: 767px) {
  /* --- Канбан заявок (/leads.html) ---
     2 колонки по 170px нечитаемы. Делаем ленту со свайпом: колонка
     почти во весь экран, snap по краям — как в Trello. */
  #kanban.ts-kanban-mobile {
    display: flex !important;
    gap: 0.625rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 0.5rem;
  }
  #kanban.ts-kanban-mobile::-webkit-scrollbar {
    display: none;
  }
  #kanban.ts-kanban-mobile > .kanban-col {
    flex: 0 0 82vw;
    scroll-snap-align: center;
    min-height: 0 !important;
  }

  /* --- Таблицы-матрицы (журнал, абонементы, оплаты в финансах) ---
     В карточки они не разворачиваются (см. isMatrixTable в mobile.js) —
     листаются вбок с закреплённой колонкой имени. На телефоне колонку
     имени поджимаем, чтобы в кадр попадало больше дат. */
  .jr-col-name {
    min-width: 104px !important;
    max-width: 104px !important;
  }
  th.sticky.left-0,
  td.sticky.left-0 {
    min-width: 120px !important;
  }
  /* Ячейка отметки посещаемости — главный тач-таргет преподавателя на
     занятии. 26×24px пальцем не попасть. */
  .att-cell {
    min-width: 34px !important;
    height: 34px !important;
    line-height: 32px !important;
    font-size: 14px !important;
  }

  /* --- Недельная сетка расписания (/schedule.html) ---
     Колонка часов остаётся на месте при горизонтальном скролле,
     иначе непонятно, к какому времени относится занятие. */
  #schedule-grid {
    min-width: 720px !important;
  }
  #schedule-grid .day-col {
    min-width: 92px;
  }
}


/* ============================================================
   9. ПЕЧАТЬ / ДЕСКТОП-ЗАЩИТА
   ------------------------------------------------------------
   На всякий случай: если mobile.js по ошибке проставил хук-классы,
   на широком экране они не должны ничего менять — все правила выше
   уже внутри @media, здесь только явный сброс оболочки.
   ============================================================ */
@media (min-width: 1024px) {
  .ts-appbar,
  .ts-tabbar,
  .ts-scrim,
  .ts-fab {
    display: none !important;
  }
}
