/* =========================================================
   TEAM VOICE — УЗКИЙ ЭКРАН (каркас /app/ и приложение целиком)

   Зачем файл. Каркас /app/ — три колонки фиксированной ширины:
   рельс серверов (72), панель каналов (240), основная область
   (растягивается), участники (240) плюс зазоры и отступы body.
   Минимум — 594 px, поэтому на телефоне (360/390 px) правая колонка
   просто уезжала за экран (замер ДО: `scrollWidth` 594 против окна 390,
   семь узлов за правым краем). Ширины колонок — не оформление, а размеры
   каркаса, они лежат в `@layer layout` внутри app.css; править их там
   значило бы менять раскладку и на широком экране.

   Какой подход. Тот же интерфейс, а не отдельная мобильная версия:
   на узкой ширине боковые панели становятся ШТОРКАМИ поверх основной
   области, а в шапке появляются три кнопки (серверы, каналы, участники).
   Основная область (чат, голосовая область, беседа, друзья) занимает всю
   ширину. Ширина шире 768 px не затронута вообще — этим же интерфейсом
   пользуется десктопное приложение в WebView2.

   Слои. Список слоёв объявлен один раз в tokens.css и повторён здесь
   ИМЕННО В ТОМ ЖЕ ПОРЯДКЕ: повторная инструкция `@layer` только добавляет
   файл в уже зафиксированный порядок (правила не переезжают в другой слой)
   и не заводит новых слоёв. Уточнения к правилам каркаса лежат в том же
   слое, что и сами правила (`layout`), уточнения к кнопкам — в
   `components`: чем общее правило, тем раньше слой.

   Цвета — только токенами из tokens.css.
   ========================================================= */
@layer tokens, base, layout, components, features, pages;

/* Кнопки панелей, верхняя полоса и подложка шторок. Вне media-запроса —
   потому что это ДОБАВЛЕНИЕ к каркасу: на широком экране их просто нет
   (`display: none`), и раскладка 1440/1280/1024/800 остаётся прежней. */
@layer layout {
    .panel-toggle {
        display: none;
    }

    .panel-backdrop {
        display: none;
    }

    .mobile-bar {
        display: none;
    }
}

/* ------------------------------------------------------------------
   Видимый фокус для всего, до чего можно добраться с клавиатуры.
   Раньше кольцо было только у части элементов (`#user-status-trigger`,
   `.status-item`, поля ввода, ползунки, флажки, ссылки страниц входа):
   у остальных оставался браузерный `outline`, который на тёмном стекле
   почти не виден. Правило лежит в слое `base` (общее для всех страниц) и
   не отменяет существующие `:focus-visible`: у тех же правил в app.css
   такой же вес, но `box-shadow`-кольцо остаётся на месте, а `outline`
   рисуется ПОВЕРХ него тем же акцентом — вид кольца один и тот же.
   ------------------------------------------------------------------ */
@layer base {
    :focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 2px;
    }
}

/* ------------------------------------------------------------------
   «Работает только по наведению» — доступный путь.
   В app.css (слой components) панель кнопок и ползунок громкости
   демонстрации показываются ТОЛЬКО при наведении на сцену
   (`.screen-stage:hover .screen-stage-controls`). С клавиатуры до них было
   не добраться: Tab попадал в невидимые кнопки. Добавляем `:focus-within` —
   тот же показ, когда фокус внутри сцены. Правило действует на ЛЮБОЙ
   ширине: на широком экране оно ничего не меняет, пока фокус не в сцене.
   ------------------------------------------------------------------ */
@layer components {
    .screen-stage:focus-within .screen-stage-controls,
    .screen-stage:focus-within .screen-stage-volume {
        opacity: 1;
    }
}

/* ------------------------------------------------------------------
   Телефон и узкий планшет: --bp-md (768px).
   ------------------------------------------------------------------ */
@media (max-width: 768px) {

    @layer layout {

        /* --- Верхняя полоса: единственная кнопка, которая всегда на виду --
           Шторку открывает кнопка, а кнопка внутри закрытой шторки её не
           откроет: без постоянной полосы список каналов недостижим, пока не
           выбран канал (живая проверка выложенной страницы это и показала).
           Полоса лежит в потоке первым элементом каркаса, поэтому «съедает»
           высоту у основной области, а не накрывает её. ---------------- */
        .mobile-bar {
            display: flex;
            align-items: center;
            gap: 8px;
            flex: 0 0 auto;
            height: 56px;
            padding: 0 8px;
            background: var(--bg-panel);
            border-bottom: 1px solid var(--border);
            color: var(--text-primary);
        }
        /* Кнопки панелей живут в верхней полосе — это ЕДИНСТВЕННЫЙ вход в
           панели (см. templates/servers/_panel_toggles.html): квадратный вид и
           цель касания заданы здесь, поэтому правило и называет полосу.
           Кроме полосы на узком экране есть ещё кнопка «Открыть список
           каналов» в пустом состоянии — она с подписью и со своим оформлением
           (ниже), а на широком экране кнопок панелей нет вовсе: полоса скрыта,
           а `.panel-toggle { display: none }` из app.css (слой layout, вне
           media-запроса) гасит в том числе кнопку пустого состояния. */
        .mobile-bar .panel-toggle {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            /* Цель касания: не меньше 44x44 (требование задачи). */
            width: 44px;
            height: 44px;
            padding: 0;
            background: none;
            border: 1px solid transparent;
            border-radius: var(--radius-md);
            color: var(--text-icon);
            font-size: 18px;
            cursor: pointer;
        }
        .panel-toggle:hover {
            background: var(--bg-hover);
            color: var(--text-normal);
        }
        .panel-toggle[aria-expanded="true"] {
            background: var(--accent-soft);
            border-color: var(--border-strong);
            color: var(--text-primary);
        }

        /* Кнопка полосы спрятана, когда открывать нечего. Атрибут ставит
           static/js/features/panel-drawer.js: syncBarToggles() — по факту
           показа панели (`getComputedStyle`), а не по строке inline-стиля.
           ПОЧЕМУ так, а не правилом `body:has(#panel[style*="none"])`: строка
           стиля зависит от того, как её сериализует браузер, а снятие
           inline-стиля (`style.display = ''`) вообще убирает атрибут — на этом
           уже один раз сломалось открытие шторки. Атрибут `hidden` — один
           источник правды и для CSS, и для решения «можно ли закрыть шторку»,
           поэтому правило стоит сразу после вида кнопок. */
        .mobile-bar .panel-toggle[hidden] {
            display: none;
        }

        /* Кнопка «Открыть список каналов» в пустом состоянии: не квадратная
           иконка, а кнопка с подписью. `display` назван явно и селектором
           конкретнее общего правила выше — иначе вид кнопки решал бы порядок
           правил в этом же media-запросе. */
        .empty-state .panel-toggle {
            display: inline-flex;
            width: auto;
            min-height: 44px;
            margin-top: 8px;
            padding: 0 14px;
            gap: 8px;
            border-color: var(--border-strong);
        }
        .mobile-bar-title {
            font-weight: 600;
            font-size: 15px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        /* --- Основная область — на всю ширину, во всю высоту ----------
           ПОЧЕМУ здесь меняется направление главной оси. Каркас на широком
           экране — ЧЕТЫРЕ колонки в ряд (`body { display: flex }` в app.css,
           слой layout), и верхней полосы среди них нет: она спрятана
           (`display: none`). На узком экране полоса появляется — и если ось
           остаётся горизонтальной, полоса становится ПЯТОЙ КОЛОНКОЙ: она
           занимает ширину по содержимому (замер 500 px: 145 px), а основная
           область начинается не с нуля, а от её правого края (замер: `left`
           145, ширина 355 вместо 500). Это и было на снимке владельца: полоса
           сверху, а область сдвинута вправо и зажата в 355 px.
           Полоса лежит в потоке ПЕРВЫМ элементом каркаса, поэтому колонка —
           это ровно «полоса сверху, область под ней на всю ширину и на всю
           оставшуюся высоту»: `flex: 1` у `.main-area` из app.css сам занимает
           остаток (замер 500x1126 — полоса 500x56, область 500x1070 под ней,
           полоса управления голосом внутри области, низ не обрезан).

           ПОЧЕМУ селектор называет полосу, а не просто `body`. `body` есть и
           на девяти ДРУГИХ страницах, и там это центрирующая обёртка
           (`auth.css`: `display: flex; align-items: center; justify-content:
           center`): смена оси переставила бы карточку входа из центра вверх.
           Это поймал слепок `tools/mobile_audit.py`: правило `body` дало
           отличия на login/register/profile/settings/styleguide/home/chat/
           voice. Полоса `.mobile-bar` есть ТОЛЬКО в каркасе `/app/`
           (templates/servers/app.html), поэтому `:has(> .mobile-bar)` — это
           ровно «каркас приложения», и ни одна другая страница правило не
           видит. Здесь же он и нужен: на широком экране полосы нет вовсе
           (`display: none`), значит признак честно описывает узкий каркас.
           Правило живёт только в этом media-запросе: шире 768 px направление
           оси прежнее, и раскладка 1440 остаётся ровно такой, как была
           (слепок getComputedStyle: 0 отличий на 1440/1280/1024/800). ----- */
        body:has(> .mobile-bar) {
            flex-direction: column;
            gap: 0;
            padding: 0;
        }
        .main-area {
            width: 100%;
            height: 100%;
            border: none;
            border-radius: 0;
        }

        /* --- Панели каркаса: шторки поверх основной области -----------
           Рельс серверов и панель каналов выезжают слева, участники —
           справа. Панели начинаются ПОД верхней полосой: кнопка, которая их
           закрывает, остаётся видимой и доступной. `z-index` подобран под
           существующую шкалу app.css: меню канала и карточка пользователя
           (9998/9999) и модальные окна (10000) остаются ВЫШЕ шторок, поэтому
           всплывающие окна по-прежнему перекрывают панель, а не наоборот. */
        .servers-rail,
        .channels-panel,
        .members-panel {
            position: fixed;
            top: 56px;
            bottom: 0;
            height: auto;
            max-width: 100vw;
            z-index: 40;
            /* Панель поверх области — тень отделяет её от содержимого. */
            box-shadow: var(--panel-shadow), var(--inset-highlight);
        }
        .servers-rail {
            left: 0;
            width: 72px;
            transform: translateX(-110%);
            visibility: hidden;
            transition: transform var(--transition-base),
                        visibility var(--transition-base);
        }
        .channels-panel {
            left: 0;
            /* Ширина — доля экрана, но не шире прежних 240 px: на телефоне
               список каналов не должен занимать весь экран. */
            width: min(280px, 78vw);
            transform: translateX(-110%);
            visibility: hidden;
            transition: transform var(--transition-base),
                        visibility var(--transition-base);
        }
        .servers-rail.drawer-open {
            transform: none;
            visibility: visible;
        }
        .channels-panel.drawer-open {
            transform: none;
            visibility: visible;
        }

        /* Участники — справа. Своё состояние (`drawer-open`), потому что
           открыть их можно и при закрытых каналах. */
        aside.members-panel {
            right: 0;
            width: min(280px, 78vw);
            transform: translateX(110%);
            visibility: hidden;
            transition: transform var(--transition-base),
                        visibility var(--transition-base);
        }
        aside.members-panel.drawer-open {
            transform: none;
            visibility: visible;
        }

        /* Панель переписок (#dm-panel) — тот же .channels-panel, но у неё две
           особенности, и обе важны для возврата к списку переписок на узком
           экране.
           1. Прячет её класс .is-hidden (dm.css, слой components; он ВЫШЕ слоя
              layout) — отсюда `body:has(...)`, который поднимает вес правила
              выше `.dm-panel.is-hidden`, сохраняя саму логику: в режиме личных
              сообщений одна панель видна, вторая скрыта.
           2. Выехать ей мешает общее правило шторки `.channels-panel.drawer-open`
              (выше в этом блоке): у панели переписок тот же класс, и он держит
              `transform: translateX(-110%)` и `visibility: hidden`. Вес
              `:has()`-селектора равен весу его аргумента — те же (0,2,0), а
              выигрывает позднее правило, то есть общее. Поэтому панель
              переписок названа с id: `#dm-panel.drawer-open`.
           Раньше здесь стоял `body:has(.dm-panel.drawer-open) > .dm-panel`:
           дочерний комбинатор не совпадал вообще (панель ЛС лежит в каркасе не
           первым уровнем), а `.dm-mode` в body не ставит никто — то есть в
           режиме ЛС шторка переписок не открывалась ни при каких условиях, и
           вернуться из беседы к списку было нечем (владелец). */
        #dm-panel.drawer-open,
        body:has(.dm-panel.drawer-open) > .dm-panel,
        body.dm-mode > .dm-panel.drawer-open {
            transform: none;
            visibility: visible;
        }

        /* Шапка под шторки: не ниже цели касания и с воздухом по краям,
           чтобы кнопки не липли к рамке экрана. */
        .main-header,
        .server-header {
            min-height: 56px;
            padding-left: 8px;
            padding-right: 8px;
            gap: 4px;
        }
        /* Порядок шапки сервера: НАЗВАНИЕ первым, на всю строку, а кнопки —
           под ним. Почему так, а не «всё в одну строку»: в шапке каналов
           пять органов управления — три кнопки панелей (44 px), шестерёнка
           управления сервером и «Пригласить». Замер на 390 px при ширине
           панели 280 px: в одну строку они не влезают, название сжималось до
           22 px («T…»), а шестерёнка и «Пригласить» уезжали на вторую строку
           и оставались невидимыми. С переносом названия наверх влезает всё,
           и остаётся воздух. Заголовки канала и беседы — тоже на своей строке
           (иначе имя канала ужималось до «g…»). */
        .server-header .name,
        .main-header > span:not(.voice-header-meta):not(.hash) {
            order: -1;
            flex: 1 1 100%;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        /* Высоту шапки каналов снимаем: она была жёстко 48 px из app.css,
           а теперь строк две. */
        .server-header {
            height: auto;
            flex-wrap: wrap;
        }
        /* Кнопки шапки сервера — тоже цели касания. */
        .server-header .invite-btn,
        .server-header .tv-manage-btn {
            min-width: 44px;
            min-height: 44px;
        }

        /* --- Подложка шторки -----------------------------------------
           Пока открыта панель КАНАЛОВ или УЧАСТНИКОВ, область вокруг
           затемнена и нажатие по ней закрывает панель (обработчик —
           static/js/features/panel-drawer.js). Рельс серверов подложки не
           заводит: он тонкий, и основная область остаётся рабочей.

           Панель лежит ВЫШЕ подложки, поэтому содержимое шторки доступно
           для нажатия. Нажатие по самой области ловит `#main-area`. ---- */
        .panel-backdrop {
            display: block;
            position: fixed;
            inset: 0;
            z-index: 30;
            padding: 0;
            background: var(--overlay-soft);
            border: none;
            cursor: pointer;
            opacity: 0;
            pointer-events: none;
            transition: opacity var(--transition-base);
        }
        body:has(.channels-panel.drawer-open) .panel-backdrop,
        body:has(.members-panel.drawer-open) .panel-backdrop {
            opacity: 1;
            pointer-events: auto;
        }

        /* --- Цели касания: не меньше 44x44 --------------------------- */
        .icon-btn,
        .user-actions .icon-btn,
        .user-avatar-link,
        .user-avatar,
        .invite-btn {
            min-width: 44px;
            min-height: 44px;
        }
        .user-avatar {
            width: 44px;
            height: 44px;
        }
        .user-info {
            min-height: 44px;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        .user-panel {
            gap: 4px;
            padding: 8px;
        }
        .members-search {
            min-height: 44px;
        }
        /* Пункт меню статуса и строка участника: строка списка — тоже цель
           касания, а на палец 32 px мало. */
        .status-item {
            min-height: 44px;
            align-items: center;
        }
        .channel,
        .member {
            min-height: 44px;
        }

        /* --- Голосовая панель ---------------------------------------
           Полоса управления голосом — шесть кнопок в ряд: на 360 px они
           ужимались до 40 px и меньше. Разрешаем перенос и задаём минимум. */
        .voice-controlbar {
            flex-wrap: wrap;
            gap: 8px;
            padding: 8px 12px;
        }
        .voice-controlbar-info {
            min-width: 0;
            flex: 1 1 100%;
        }
        .voice-conn-title,
        .voice-status {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .vqc-btn {
            min-width: 44px;
            min-height: 44px;
        }
        /* Кнопки управления демонстрацией поверх сцены: 32x32 из app.css —
           на палец мелко, а сцена занимает почти весь экран телефона. */
        .screen-stage-btn {
            width: 44px;
            height: 44px;
        }
        /* Подсказка о звуке демонстрации — длинная строка: на узкой ширине
           занимает свою строку и переносится, а не растягивает полосу. */
        .voice-sysaudio {
            flex: 1 1 100%;
            white-space: normal;
            font-size: 12px;
            line-height: 1.35;
        }
        .voice-controlbar-right {
            flex: 1 1 100%;
        }

        /* --- Шкала громкости микрофона -------------------------------
           Минимум 320 px из app.css (слой features) шире телефона: на
           360 px блок вылезал за экран на 34 px. На узкой ширине минимум
           снимаем, а строку с подписью разрешаем переносить. ---------- */
        .mic-volume-wrap {
            min-width: 0;
            width: 100%;
            flex-wrap: wrap;
            gap: 8px;
            padding: 10px 12px;
        }
        .mic-volume-wrap label {
            white-space: normal;
        }
        .mic-volume-wrap input[type="range"] {
            min-width: 120px;
        }

        /* --- Плитки голосовой области --------------------------------
           Голосовая область считает раскладку в JS (voice/grid.js), но
           пустая область и подпись «в канале никого» тоже должны
           переноситься, а не растягивать каркас. --------------------- */
        .voice-empty {
            padding: 16px;
            text-align: center;
            /* Запас 200 px из app.css плюс высокий блок подсказок внизу
               выдавливали полосу управления за нижний край (проверено
               снимком: «Подключиться» уезжала под экран). Пустое состояние
               сжимается — подпись и кнопка остаются на виду. */
            min-height: 0;
        }
        .voice-empty .voice-empty-icon {
            width: 64px;
            height: 64px;
            font-size: 26px;
        }
        .empty-state {
            padding: 16px;
            text-align: center;
        }
        .empty-state h2,
        .empty-state p {
            overflow-wrap: anywhere;
        }

        /* --- Окна и модальные окна ----------------------------------
           Модалка шире экрана не влезала и её нельзя было закрыть: крестик
           уезжал за край. Ограничиваем ширину окна экраном и разрешаем
           прокрутку содержимого. ------------------------------------- */
        .modal-content,
        .settings-modal,
        .share-modal {
            max-width: 100%;
            width: 100%;
        }
        .settings-modal-backdrop {
            padding: 0;
        }
        .settings-modal-body,
        .share-modal-body,
        .tv-manage-body {
            overflow-x: hidden;
        }
        .modal-close,
        .settings-modal-close,
        .user-card-close {
            min-width: 44px;
            min-height: 44px;
        }
    }
}

/* ------------------------------------------------------------------
   Очень узкий экран (≤ 360 px): числа и подписи в одну колонку.
   Отдельный порог — --bp-sm (480px) в шкале tokens.css для страниц уже
   занят, а каркасу нужна своя граница: 360 и уже.
   ------------------------------------------------------------------ */
@media (max-width: 380px) {

    @layer layout {

        .voice-controlbar-buttons {
            flex-wrap: wrap;
        }
        .panel-toggle {
            width: 44px;
            height: 44px;
        }
        .main-header,
        .server-header {
            padding-left: 4px;
            padding-right: 4px;
        }
    }
}

/* ------------------------------------------------------------------
   Цели касания на ОСТАЛЬНЫХ страницах (не на каркасе /app/).

   Замер ДО на 390 px: /settings/ — 27 целей меньше 44x44 (переключатели
   16x16, поля 33 px, кнопки 29 px), /profile/ — кнопки 40 px, /user/1/ —
   ссылки 37 px, вход и регистрация — текстовая ссылка 20 px в высоту,
   витрина — крестики 20x22 и кнопки 24–43 px.

   Скоуп — по классу body страницы и по контексту окна: правило не
   «размазано» по всем страницам, а называет, где именно действует.
   Порог — тот же --bp-md (768px), что и у шторок: на широком экране
   размеры не меняются вовсе. Слои: это уточнения к правилам страниц,
   поэтому `pages` (там же, где лежат сами страницы), а для элементов
   витрины и окна настроек — `components` (там их рисует app.css).
   ------------------------------------------------------------------ */
@media (max-width: 768px) {

    @layer components {

        /* --- Окно настроек в приложении (#settings-modal) ------------ */
        #settings-modal .checkbox,
        .settings-page .checkbox {
            min-height: 44px;
            align-items: center;
            padding: 4px 0;
        }
        #settings-modal select,
        .settings-page select {
            min-height: 44px;
        }
        #settings-modal button,
        .settings-page button {
            min-height: 44px;
        }
        #settings-modal input[type="range"],
        .settings-page input[type="range"] {
            min-height: 44px;
        }
        /* Ползунок в окне настроек: сам трек тонкий, но палец должен
           попадать по всей строке. */
        #settings-modal .row,
        .settings-page .row {
            gap: 8px;
        }

        /* --- Витрина компонентов: демонстрации должны быть
           работоспособны пальцем. Меняются только размеры целей
           касания, вид компонента не переделывается. ---------------- */
        .sg-section .icon-btn,
        .sg-section .sg-reply-cancel,
        .sg-section .sg-vi-close,
        .sg-section .user-card-close,
        .sg-section .vph-close,
        .sg-section .jump-to-bottom {
            min-width: 44px;
            min-height: 44px;
        }
        .sg-section .user-card-btn,
        .sg-section .context-menu-volume-reset,
        .sg-section .invite-btn,
        .sg-section .voice-btn,
        .sg-section button.btn-pill {
            min-height: 44px;
        }
        .sg-section .members-search,
        .sg-section .form-input,
        .sg-section .context-menu-volume-slider {
            min-height: 44px;
        }
    }

    @layer pages {

        /* --- Профиль и публичный профиль ---------------------------- */
        body.profile-page .form-input,
        body.profile-page .form-group input,
        body.profile-page .form-group textarea,
        body.profile-page input[type="text"],
        body.profile-page input[type="email"],
        body.profile-page textarea,
        body.user-profile-page .form-input {
            min-height: 44px;
        }
        body.profile-page .avatar-upload-btn {
            min-height: 44px;
            display: inline-flex;
            align-items: center;
        }
        body.profile-page .btn-primary,
        body.profile-page .btn-secondary,
        body.profile-page a.btn-secondary,
        body.user-profile-page a {
            min-height: 44px;
            display: inline-flex;
            align-items: center;
        }

        /* --- Вход и регистрация -------------------------------------
           Ссылка «Зарегистрироваться» / «Войти» — текстом 20 px в высоту:
           на палец мимо. Делаем её строкой-целью, вид не меняем. ------ */
        body.login-page a,
        body.register-page a {
            min-height: 44px;
            display: inline-flex;
            align-items: center;
        }
        /* Поля входа/регистрации: 43 px в высоту — не хватало 1 px. */
        body.login-page input,
        body.register-page input {
            min-height: 44px;
        }

        /* --- Домашняя страница ------------------------------------- */
        body.home-page a,
        body.home-page button {
            min-height: 44px;
        }

        /* --- Страница канала и голосовая страница -------------------
           Переносят длинные подписи, чтобы каркас не растягивался. --- */
        body.channel-page .header,
        body.voice-page .header {
            overflow-wrap: anywhere;
        }

        /* --- Ссылки-возвраты в шапках страниц -----------------------
           «← В приложение» и «← На главную» были текстом 19–31 px в высоту:
           на палец мимо. Строка становится целью касания, вид тот же. */
        body.settings-page .settings-page-shell header a,
        body.profile-page .back-link,
        body.voice-page .header a,
        body.channel-page .header a,
        body.styleguide-page .sg-header a,
        body.user-profile-page .actions a {
            min-height: 44px;
            display: inline-flex;
            align-items: center;
        }

        /* --- Фокус на узкой ширине: иконки-кнопки 32 px из app.css ----------
           Кнопки «настройки», «выйти», «скачать» и стрелка «вниз» в чате
           были 32 px: палец мимо. ------------------------------------- */
        .icon-btn,
        .user-actions .icon-btn {
            min-width: 44px;
            min-height: 44px;
        }

        /* --- Страница текстового канала: поле ввода -----------------
           Отдельная страница (/chat/<id>/), поле 36 px в высоту. ----- */
        body.channel-page .input-row input {
            min-height: 44px;
        }

        /* --- Ссылка витрины «наверх» и прочие текстовые ссылки ----- */
        body.styleguide-page .sg-header a {
            padding: 0 4px;
        }

        /* --- Голосовая страница: кнопки управления ------------------
           36–39 px в высоту на 390 px. Минимум задаётся честно только при
           `border-box`: у страницы голосового канала свой `* { box-sizing:
           content-box }` в voice-page.css, из-за него `min-height: 44px`
           превращалось в 43 px по замеру. ---------------------------- */
        body.voice-page * {
            box-sizing: border-box;
        }
        body.voice-page button {
            min-height: 44px;
        }

        /* --- Пустой голосовой канал: кнопка приглашения и «Подключиться» ---
           В приложении это .voice-btn (43 px по замеру на 390 px). ------- */
        .voice-btn,
        .voice-empty button {
            min-height: 44px;
        }

        /* --- Подсказка о правах доступа: кнопки «Проверить снова» --- */
        .voice-permission-hint button {
            min-height: 44px;
        }

        /* --- Ввод сообщения в чате канала и в беседе -----------------
           Поле 36 px в высоту, а это главный орган управления на
           телефоне: поднимаем до цели касания. Ширина не меняется,
           потому что она и так во всю строку. ----------------------- */
        .input-wrapper input,
        .input-wrapper textarea {
            min-height: 44px;
        }
    }
}
