/* =============================================================
 * components.css — общие примитивы UI для всех трёх интерфейсов.
 *
 * Порядок подключения: tokens.css → components.css → CSS интерфейса.
 * Файл интерфейса идёт последним и может переопределить всё, что ниже, —
 * но делать это стоит только ради намеренного отличия, с комментарием почему.
 *
 * До этого файла `.btn` был объявлен трижды и разъехался:
 *   сайт     padding 13px 28px, gap 9px, hover со сдвигом
 *   админка  padding 10px 22px, gap 8px, без сдвига
 *   мини-апп padding 13px 20px, width:100%, БЕЗ transition вообще
 * а `.btn-secondary` вдобавок был прозрачным в вебе и залитым в мини-аппе.
 * ============================================================= */

/* ---------------------------------------------------------------
 * КНОПКИ
 * --------------------------------------------------------------- */

/* Размеры задаются через локальные переменные, а не переопределением padding:
 * так модификатор размера не конфликтует с модификатором вида (.btn-sm.btn-primary). */
.btn {
    --btn-py: 12px;
    --btn-px: 22px;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: var(--btn-py) var(--btn-px);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    text-decoration: none;
    /* Не all: анимируем только то, что реально меняется. all заставляет браузер
     * следить за каждым свойством и мешает предсказуемости. */
    transition: background-color var(--dur-base) var(--ease-standard),
                border-color var(--dur-base) var(--ease-standard),
                color var(--dur-base) var(--ease-standard),
                transform var(--dur-fast) var(--ease-standard),
                opacity var(--dur-base) var(--ease-standard);
}

/* Размеры */
.btn-lg { --btn-py: 14px; --btn-px: 28px; font-size: 15px; }
.btn-sm { --btn-py: 8px;  --btn-px: 16px; font-size: 12px; }
.btn-block { display: flex; width: 100%; }

/* Виды */
.btn-primary { background: var(--brand); color: #1a0900; }
.btn-secondary { background: transparent; color: var(--text-primary); border-color: var(--border-strong); }
.btn-outline { background: transparent; color: var(--text-secondary); border-color: var(--border); }
.btn-danger { background: transparent; color: var(--danger); border-color: var(--danger); }

/* Наведение — только там, где курсор есть.
 * Без этого медиа-запроса на тач-устройстве hover «залипает» после нажатия:
 * браузер оставляет состояние до тапа в другое место. */
@media (hover: hover) {
    .btn-primary:hover { background: var(--brand-hover); }
    .btn-secondary:hover { border-color: var(--accent); color: var(--accent); }
    .btn-outline:hover { border-color: var(--border-strong); color: var(--text-primary); }
    .btn-danger:hover { background: var(--danger); color: #2a0808; }
    .btn:hover:not(:disabled):not(.btn-disabled) { transform: translateY(-1px); }
}

/* Нажатие — одинаковое во всех интерфейсах и на всех устройствах.
 * Раньше отклик на нажатие был только у мини-аппа (:active), а в вебе — только
 * hover, которого на телефоне нет: тап по кнопке вообще ничем не отзывался. */
.btn:active:not(:disabled):not(.btn-disabled) {
    transform: translateY(1px);
    transition-duration: var(--dur-fast);
}

/* Недоступна: и как атрибут, и как класс — в разметке встречаются оба
 * (`<button class="btn btn-disabled" disabled>`). Задаём именно ВИД, а не только
 * прозрачность: на сайте `.btn-disabled` («Нет в наличии») — это заглушка с
 * собственным фоном, и одна лишь opacity оставила бы её прозрачной.
 * Заливка вида (например, .btn-primary) намеренно перебивается: неактивная
 * кнопка не должна выглядеть как нажимаемая. */
.btn:disabled,
.btn-disabled {
    background: var(--surface-2);
    color: var(--text-muted);
    border-color: var(--border);
    cursor: not-allowed;
    pointer-events: none;
    transform: none;
}

/* Фокус с клавиатуры. Обводку не убираем никогда (это единственный способ
 * навигации без мыши), но показываем только при переходе табом, не по клику. */
.btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Иконочная кнопка — круглая: так уже было и в админке (32px), и в мини-аппе (30px),
 * это сложившаяся конвенция проекта. Сведено к 32px. */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-secondary);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--dur-base) var(--ease-standard),
                border-color var(--dur-base) var(--ease-standard),
                color var(--dur-base) var(--ease-standard);
}

@media (hover: hover) {
    .btn-icon:hover { border-color: var(--accent); color: var(--accent); }
    .btn-icon-danger:hover { border-color: var(--danger); color: var(--danger); }
}

.btn-icon-danger { color: var(--danger); }

/* Тач: минимальная цель нажатия 44×44 (иначе промахи).
 * Указатель «грубый» = палец, а не мышь — сюда попадают телефоны и планшеты. */
@media (pointer: coarse) {
    .btn { min-height: 44px; }
    .btn-icon { width: 44px; height: 44px; }
}

/* ---------------------------------------------------------------
 * СКРОЛЛБАРЫ
 *
 * Системный скроллбар не знает про тёмную тему: в кабинете (уведомления,
 * длинные списки) он рисовался светлой полосой поверх тёмного фона.
 * В админке тонкие кастомные скроллбары были давно — здесь то же правило
 * становится общим на все три интерфейса.
 * --------------------------------------------------------------- */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--border-strong) transparent;
}

*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }

*::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: 8px;
    /* Прозрачная рамка + background-clip делают ползунок визуально тоньше
     * дорожки, не сужая область захвата мышью. */
    border: 2px solid transparent;
    background-clip: padding-box;
}

*::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
    background-clip: padding-box;
}

*::-webkit-scrollbar-corner { background: transparent; }

/* ---------------------------------------------------------------
 * ТОСТЫ
 * Разметку создаёт js/toast.js — руками элемент не добавлять.
 * Раньше стилей было четыре (.account-toast / .fav-toast / .zv-toast / .toast)
 * с z-index 80 / 1400 / 3000 / 4000 и разными скруглениями.
 * --------------------------------------------------------------- */
.toast {
    /* Отступ снизу — переменной: мини-апп поднимает тост над своей нижней
     * навигацией, переопределяя только её (см. webapp/css/app.css). */
    --toast-bottom: 24px;

    position: fixed;
    left: 50%;
    bottom: var(--toast-bottom);
    z-index: 4000; /* выше модалок (макс. 1500) — тост не должен ими перекрываться */
    display: flex;
    /* Иконка — к первой строке, а не по центру блока: у длинного текста она
     * иначе уезжает на середину абзаца. */
    align-items: flex-start;
    gap: 9px;
    /* width обязателен. Без него fixed-элемент считает ширину «по содержимому»,
     * а доступной шириной при left: 50% остаётся ТОЛЬКО правая половина экрана —
     * тост схлопывался в узкий столбик и рос вверх на 7 строк. max-width один
     * этого не лечит: он ограничивает, но ширину не задаёт.
     * max-content = «сколько нужно тексту в одну строку», а max-width ниже
     * обрезает до разумного и включает перенос. */
    width: max-content;
    max-width: min(92vw, 460px);
    padding: 12px 18px;
    /* НЕ 999px: тост с длинным текстом становится многострочным, и «таблетка»
     * превращается в круг, который срезает текст по углам. Скругление фиксированное. */
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.45;
    text-align: left;
    /* Длинное слово/ссылка не должны распирать тост за пределы max-width. */
    overflow-wrap: anywhere;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.42);

    /* Скрыт: не перехватывает клики и уезжает вниз. */
    opacity: 0;
    pointer-events: none;
    transform: translateX(-50%) translateY(12px);
    transition: opacity var(--dur-exit) var(--ease-in),
                transform var(--dur-exit) var(--ease-in);
}

/* Появление медленнее ухода: приход должен быть замечен, уход — не задерживать. */
.toast.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
    transition: opacity var(--dur-slow) var(--ease-out),
                transform var(--dur-slow) var(--ease-out);
}

/* Иконка не сжимается и выровнена по высоте первой строки текста. */
.toast i { flex-shrink: 0; line-height: 1.45; }

.toast-success i { color: var(--success); }
.toast-error { border-color: var(--danger); }
.toast-error i { color: var(--danger); }
.toast-warning { border-color: var(--warning); }
.toast-warning i { color: var(--warning); }

/* ---------------------------------------------------------------
 * ФОРМЫ
 *
 * Поле было описано ЧЕТЫРЕЖДЫ и по-разному:
 *   сайт  .form-group input          padding 12px 14px, radius-sm, 14px, transition
 *   сайт  .cabinet input[type=…]     padding 11px 14px, radius 10px (хардкод) — и,
 *                                    имея бОльшую специфичность, перебивало правило
 *                                    выше: поля кабинета отличались от полей сайта
 *   админка .form-group input        padding 10px 13px, radius-sm, без transition
 *   мини-апп .field input            padding 12px 14px, radius-sm, 15px, без transition
 *
 * Поддерживаем три сложившиеся обёртки (.form-group — сайт и админка, .field —
 * мини-апп, .pw-field — поле пароля с «глазом»), чтобы не переименовывать классы
 * в разметке. Для одиночного поля без обёртки есть явный класс .input-text.
 * --------------------------------------------------------------- */

.form-group,
.field {
    margin-bottom: 18px;
}

.form-group > label,
.field > label {
    display: block;
    margin-bottom: 7px;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
}

.form-group input,
.form-group select,
.form-group textarea,
.field input,
.field select,
.field textarea,
.pw-field input,
.input-text {
    width: 100%;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 14px;
    transition: border-color var(--dur-base) var(--ease-standard),
                box-shadow var(--dur-base) var(--ease-standard);
}

/* Поля даты/времени имеют СОБСТВЕННУЮ минимальную ширину (место под «дд.мм.гггг»
 * и иконку календаря). width: 100% её не пересиливает: по умолчанию min-width у
 * flex/grid-элемента = auto, то есть «не уже содержимого». В двухколоночной строке
 * «С даты / По дату» такие поля вылезали за экран и давали горизонтальную прокрутку —
 * особенно после увеличения шрифта до 16px на тач-устройствах (см. ниже).
 * min-width: 0 разрешает им сжиматься. */
input[type="date"],
input[type="datetime-local"],
input[type="time"],
input[type="month"] {
    min-width: 0;
    max-width: 100%;
}

/* Обёртки полей тоже должны уметь сжиматься, иначе ограничение выше не сработает:
 * min-width: auto у самой колонки не даст ей стать уже своего содержимого. */
.field,
.form-group { min-width: 0; }

/* iOS Safari масштабирует страницу при фокусе на поле мельче 16px. На сайте это
 * заметно: тап по полю — и вёрстка «прыгает». Поэтому на устройствах с пальцем
 * поле 16px, на десктопе остаётся компактные 14px. */
@media (pointer: coarse) {
    .form-group input,
    .form-group select,
    .form-group textarea,
    .field input,
    .field select,
    .field textarea,
    .pw-field input,
    .input-text {
        font-size: 16px;
    }
}

/* Фокус: цвет рамки + кольцо. Кольцо важно — одной смены оттенка рамки при
 * навигации с клавиатуры не видно. outline снимаем только потому, что заменяем
 * его собственным видимым индикатором. */
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus,
.field input:focus,
.field select:focus,
.field textarea:focus,
.pw-field input:focus,
.input-text:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-dim);
}

.form-group input::placeholder,
.form-group textarea::placeholder,
.field input::placeholder,
.field textarea::placeholder,
.input-text::placeholder {
    color: var(--text-muted);
}

.form-group textarea,
.field textarea {
    resize: vertical;
    min-height: 70px;
}

/* Неактивное поле отличается от активного: иначе непонятно, почему не печатается. */
.form-group input:disabled,
.form-group select:disabled,
.form-group textarea:disabled,
.field input:disabled,
.field select:disabled,
.field textarea:disabled,
.input-text:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 600px) { .form-row { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------
 * МОДАЛКИ
 *
 * Каркас «подложка + карточка с закреплённой шапкой и прокручиваемым телом»
 * был скопирован трижды, различаясь только цифрами:
 *   .account-modal   z-index 1200, max-width 620, подложка rgba(0,0,0,.6)
 *   .promo-modal     z-index 1300, max-width 620, rgba(0,0,0,.65)
 *   .delivery-modal  z-index 1000, max-width 640, rgba(4,6,10,.72) + blur
 *   .favp-modal      z-index  400, max-width 880, rgba(0,0,0,.62)
 *
 * Сведены ТРИ из них. `.promo-modal` намеренно НЕ здесь: у неё другой каркас —
 * скроллится вся карточка целиком, шапка едет вместе с контентом и крупнее
 * (19px против 16px), внизу своя навигация по акциям. Это «карточка-документ»,
 * а не диалог; загонять её в этот канон — редизайн, а не дедупликация.
 *
 * z-index: единый 1200. Ниже .img-viewer (1500) — просмотрщик картинок должен
 * открываться ПОВЕРХ модалки, из которой его вызвали. Выше всего в вебе (400) и
 * в админке. Тост (4000) намеренно выше всех.
 *
 * Ширина карточки — через --modal-max на контейнере.
 * --------------------------------------------------------------- */

.modal,
.account-modal,
.delivery-modal,
.favp-modal {
    --modal-max: 620px;

    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.delivery-modal { --modal-max: 640px; }
.favp-modal { --modal-max: 880px; } /* таблица статистики — ей нужно шире */

.modal-backdrop,
.account-modal-backdrop,
.delivery-modal-backdrop,
.favp-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(4, 6, 10, 0.7);
    backdrop-filter: blur(3px);
}

.modal-card,
.account-modal-card,
.delivery-modal-card,
.favp-modal-card {
    position: relative;
    width: 100%;
    max-width: var(--modal-max);
    max-height: 90vh;
    /* Колонка + overflow:hidden на карточке — то, что закрепляет шапку:
     * прокручивается только тело. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.modal-head,
.account-modal-head,
.delivery-modal-head,
.favp-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-shrink: 0;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
}

.modal-head h3,
.account-modal-head h3,
.delivery-modal-head h3,
.favp-modal-head h3 {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 16px;
}

.modal-close,
.account-modal-close,
.delivery-modal-close,
.favp-modal-close {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    transition: background-color var(--dur-base) var(--ease-standard),
                color var(--dur-base) var(--ease-standard);
}

@media (hover: hover) {
    .modal-close:hover,
    .account-modal-close:hover,
    .delivery-modal-close:hover,
    .favp-modal-close:hover {
        background: var(--surface-hover);
        color: var(--text-primary);
    }
}

.modal-close:focus-visible,
.account-modal-close:focus-visible,
.delivery-modal-close:focus-visible,
.favp-modal-close:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* flex:1 + min-height:0 — обязательная пара для прокручиваемой середины.
 * Без min-height:0 flex-элемент не сжимается ниже своего содержимого, и
 * overflow-y: auto не включается: тело растягивает карточку и выдавливает
 * подвал (.favp-modal-foot идёт после тела). */
.modal-body,
.account-modal-body,
.delivery-modal-body,
.favp-modal-body {
    flex: 1;
    min-height: 0;
    padding: 16px 18px;
    overflow-y: auto;
}

/* Подвал карточки — не сжимается. */
.modal-foot,
.favp-modal-foot { flex-shrink: 0; }

/* ---------------------------------------------------------------
 * ЧЕКБОКСЫ И РАДИО
 *
 * Системные не используем: их не покрасить под тёмную тему одинаково в разных
 * браузерах. Приём общий — настоящий <input> лежит в разметке (доступность и
 * отправка формы работают штатно), но скрыт, а рисуется соседний элемент.
 *
 * Было три реализации:
 *   сайт     .cb-toggle .cb-box   19px, radius 6px, border 1px
 *   админка  .cb-toggle .cb-box   ТО ЖЕ САМОЕ, скопированное во второй файл
 *   мини-апп .sel-box             24px — и объявлен ДВАЖДЫ в одном файле:
 *                                 radius 7px (мёртвое) и radius 50% (побеждало),
 *                                 из-за чего чекбоксы мини-аппа были круглыми,
 *                                 а в вебе — квадратными
 * Плюс четыре разных способа отметить «выбрано»: input:checked, .checked,
 * .cell-selected .sel-box и .pick-row.selected .sel-box.
 * --------------------------------------------------------------- */

/* ---- Нативный чекбокс/радио БЕЗ обёртки ----
 * В админке 21 место использует «сырой» <input type="checkbox"> (массовый выбор
 * в таблицах, флаги в настройках доставки, тарифы CDEK). Обёрток у них нет, и
 * они рисовались системно — светлыми квадратиками поверх тёмной темы.
 * Оборачивать 21 место в разметке не нужно: appearance: none позволяет покрасить
 * сам элемент. Геометрия и палитра — те же, что у .cb-box, чтобы обёрнутые и
 * необёрнутые выглядели одинаково.
 *
 * Инпуты ВНУТРИ обёрток это не задевает: правило ниже (.cb-toggle input[type=…])
 * специфичнее и прячет их, как и раньше. */
input[type="checkbox"],
input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    margin: 0;
    flex-shrink: 0;
    display: inline-grid;
    place-content: center;
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    cursor: pointer;
    vertical-align: middle;
    transition: background-color var(--dur-fast) var(--ease-standard),
                border-color var(--dur-fast) var(--ease-standard);
}

input[type="checkbox"] { border-radius: 5px; }
input[type="radio"] { border-radius: 50%; }

input[type="checkbox"]::before,
input[type="radio"]::before {
    content: '';
    width: 10px;
    height: 10px;
    background: #fff;
    transform: scale(0);
    transition: transform var(--dur-fast) var(--ease-standard);
}

/* Галочка рисуется clip-path'ом: без иконочного шрифта и без лишнего элемента. */
input[type="checkbox"]::before {
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

input[type="radio"]::before {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

input[type="checkbox"]:checked,
input[type="radio"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

input[type="checkbox"]:checked::before,
input[type="radio"]:checked::before { transform: scale(1); }

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

@media (hover: hover) {
    input[type="checkbox"]:not(:disabled):hover,
    input[type="radio"]:not(:disabled):hover { border-color: var(--accent); }
}

/* ---- Поле выбора файла ----
 * Системная кнопка «Choose file» игнорирует тёмную тему. ::file-selector-button —
 * единственный способ покрасить её, не заменяя поле кастомной конструкцией. */
input[type="file"] {
    width: 100%;
    padding: 8px;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-secondary);
    font-family: var(--font-body);
    font-size: 13px;
    cursor: pointer;
}

input[type="file"]::file-selector-button {
    margin-right: 12px;
    padding: 8px 16px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color var(--dur-base) var(--ease-standard),
                color var(--dur-base) var(--ease-standard);
}

@media (hover: hover) {
    input[type="file"]::file-selector-button:hover {
        border-color: var(--accent);
        color: var(--accent);
    }
}

/* Сам input убираем с глаз, но не из DOM и не из фокусируемых элементов. */
.cb-toggle input[type="checkbox"],
.rb-toggle input[type="radio"],
.archive-toggle input[type="checkbox"],
.cb-row input[type="checkbox"],
.cb-row input[type="radio"],
.rb-row input[type="checkbox"],
.rb-row input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.cb-toggle,
.rb-toggle,
.archive-toggle,
.cb-row,
.rb-row {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    font-size: 14px;
}

/* Квадрат с галочкой. Галочка внутри — иконка, скрытая цветом до отметки:
 * так не прыгает геометрия при выборе. */
.cb-box,
.sel-box {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: 6px;
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    color: transparent;
    font-size: 11px;
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease-standard),
                border-color var(--dur-fast) var(--ease-standard),
                color var(--dur-fast) var(--ease-standard);
}

/* Все четыре способа «отмечено», сведённые в одно место. */
.cb-toggle input:checked + .cb-box,
.archive-toggle input:checked + .cb-box,
.cb-row input:checked + .sel-box,
.sel-box.checked,
.sel-box[aria-pressed="true"],
.cell-selected .sel-box,
.pick-row.selected .sel-box {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

@media (hover: hover) {
    .cb-toggle:hover .cb-box,
    .archive-toggle:hover .cb-box,
    .cb-row:hover .sel-box,
    .sel-box:hover { border-color: var(--accent); }
}

.cb-toggle input:focus-visible + .cb-box,
.archive-toggle input:focus-visible + .cb-box,
.cb-row input:focus-visible + .sel-box,
.sel-box:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Радио — тот же квадрат, но круглый и с точкой вместо галочки. */
.rb-dot {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: border-color var(--dur-fast) var(--ease-standard);
}

.rb-dot::after {
    content: '';
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--accent);
    transform: scale(0);
    transition: transform var(--dur-fast) var(--ease-standard);
}

.rb-toggle input:checked + .rb-dot,
.rb-row input:checked + .rb-dot { border-color: var(--accent); }

.rb-toggle input:checked + .rb-dot::after,
.rb-row input:checked + .rb-dot::after { transform: scale(1); }

/* Тач: попасть пальцем в 20px тяжело. Область нажатия расширяем невидимым
 * псевдоэлементом — сама коробочка остаётся 20px, вид не меняется.
 * (Раздувать её через padding нельзя: рамка ушла бы наружу и коробка стала бы
 * визуально 44px.) */
.sel-box { position: relative; }

@media (pointer: coarse) {
    .sel-box::before {
        content: '';
        position: absolute;
        inset: -12px;
    }

    .cb-toggle,
    .rb-toggle,
    .archive-toggle,
    .cb-row,
    .rb-row { min-height: 44px; }
}

/* ---------------------------------------------------------------
 * ПЕРЕКЛЮЧАТЕЛЬ (Switch, в духе MAX UI)
 *
 * Когда что использовать — это не вкусовщина, а разный смысл:
 *   .switch  — настройка «включено/выключено», действует СРАЗУ (или сохраняется
 *              этой же формой). Тумблер сам по себе сообщает состояние.
 *   .cb-box  — выбор из набора: отметить товары, выбрать типы точек, согласиться
 *              с условием. Чекбокс — про «отмечено», а не про «включено».
 * Радио — выбор ОДНОГО из нескольких.
 *
 * Внутри — настоящий <input type="checkbox">: форма и доступность работают штатно,
 * рисуется .switch-slider. Раньше это жило только в мини-аппе под именем
 * .mobile-toggle и в одном месте (соцсети).
 * --------------------------------------------------------------- */
.switch,
.mobile-toggle {
    position: relative;
    display: inline-block;
    width: 38px;
    height: 21px;
    flex-shrink: 0;
}

.switch input,
.mobile-toggle input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.switch-slider,
.mobile-toggle-slider {
    position: absolute;
    inset: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: pointer;
    transition: background-color var(--dur-base) var(--ease-standard),
                border-color var(--dur-base) var(--ease-standard);
}

.switch-slider::before,
.mobile-toggle-slider::before {
    content: '';
    position: absolute;
    width: 15px;
    height: 15px;
    left: 2px;
    top: 2px;
    background: var(--text-secondary);
    border-radius: 50%;
    transition: transform var(--dur-base) var(--ease-standard),
                background-color var(--dur-base) var(--ease-standard);
}

/* Включено — акцентом, как активное состояние во всём проекте (вкладки, чекбоксы).
 * Прежний .mobile-toggle красился в зелёный: в единой системе «включено» и
 * «успешно» не должны выглядеть одинаково. */
.switch input:checked + .switch-slider,
.mobile-toggle input:checked + .mobile-toggle-slider {
    background: var(--accent-dim);
    border-color: var(--accent);
}

.switch input:checked + .switch-slider::before,
.mobile-toggle input:checked + .mobile-toggle-slider::before {
    transform: translateX(17px);
    background: var(--accent);
}

.switch input:focus-visible + .switch-slider,
.mobile-toggle input:focus-visible + .mobile-toggle-slider {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.switch input:disabled + .switch-slider,
.mobile-toggle input:disabled + .mobile-toggle-slider {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Строка настройки: подпись слева, тумблер справа. */
.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    cursor: pointer;
    font-size: 14px;
}

@media (pointer: coarse) {
    .switch-row { min-height: 44px; }
}

/* ---------------------------------------------------------------
 * ВКЛАДКИ («таблетки»)
 *
 * Семейств было девять, паттерн у всех один, а расходились мелочи:
 *   .auth-tab           padding 10px,      radius 10px
 *   .settings-tab       padding 8px 16px,  radius 18px
 *   .cabinet-tab        padding 10px 18px, radius 20px
 *   .orders-tab-btn     padding 10px 20px, radius 20px
 *   .admin-tab-btn      padding 10px 18px, radius 20px  (единственная с hover)
 *   .settings-subtab-btn padding 9px 15px, radius 20px
 *   .segmented button   padding 8px 16px,  radius 20px, weight 500 (у прочих 600)
 * Правило активного состояния при этом везде было идентичным (§4 документа).
 *
 * Перечисляем сложившиеся классы, чтобы не переименовывать их в разметке.
 * Новые вкладки размечать как .tabs / .tab.
 * --------------------------------------------------------------- */

/* Контейнер: переносится на новую строку (десктоп/широкие экраны). */
.tabs,
.auth-tabs,
.cabinet-tabs,
.settings-tabs,
.orders-tabs,
.admin-tabs,
.section-tabs,
.login-mode-tabs,
.notif-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 18px;
}

/* Контейнер-лента: не переносится, скроллится вбок. Так устроены вкладки
 * мини-аппа — на узком экране перенос съедал бы высоту. Скроллбар скрыт. */
.tabs-scroll,
.settings-subtabs,
.segmented {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    margin-bottom: 16px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.tabs-scroll::-webkit-scrollbar,
.settings-subtabs::-webkit-scrollbar,
.segmented::-webkit-scrollbar {
    display: none;
}

.tab,
.auth-tab,
.cabinet-tab,
.settings-tab,
.orders-tab-btn,
.admin-tab-btn,
.settings-subtab-btn,
.segmented button,
.period-selector a,
.login-mode,
.notif-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    flex-shrink: 0;
    padding: 10px 18px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text-secondary);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--dur-base) var(--ease-standard),
                color var(--dur-base) var(--ease-standard),
                border-color var(--dur-base) var(--ease-standard);
}

.tab i,
.settings-subtab-btn i,
.admin-tab-btn i,
.orders-tab-btn i { font-size: 12px; }

@media (hover: hover) {
    .tab:hover,
    .auth-tab:hover,
    .cabinet-tab:hover,
    .settings-tab:hover,
    .orders-tab-btn:hover,
    .admin-tab-btn:hover,
    .settings-subtab-btn:hover,
    .segmented button:hover,
    .period-selector a:hover,
    .login-mode:hover,
    .notif-tab:hover {
        color: var(--text-primary);
        background: var(--surface-hover);
    }
}

/* Активная — то самое правило, которое и раньше было одинаковым везде. */
.tab.active,
.auth-tab.active,
.cabinet-tab.active,
.settings-tab.active,
.orders-tab-btn.active,
.admin-tab-btn.active,
.settings-subtab-btn.active,
.segmented button.active,
.period-selector a.active,
.login-mode.active,
.notif-tab.active {
    background: var(--accent-dim);
    color: var(--accent);
    border-color: transparent;
}

.tab:focus-visible,
.auth-tab:focus-visible,
.cabinet-tab:focus-visible,
.settings-tab:focus-visible,
.orders-tab-btn:focus-visible,
.admin-tab-btn:focus-visible,
.settings-subtab-btn:focus-visible,
.segmented button:focus-visible,
.login-mode:focus-visible,
.notif-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (pointer: coarse) {
    .tab,
    .auth-tab,
    .cabinet-tab,
    .settings-tab,
    .orders-tab-btn,
    .admin-tab-btn,
    .settings-subtab-btn,
    .segmented button,
    .login-mode,
    .notif-tab { min-height: 44px; }
}

/* ================= Правки 99.5: согласие с политикой ПДн ================= */
/* Единый ряд для всех клиентских форм: канонический .cb-box + ссылка на /privacy.
 * flex вместо inline-flex — ряд занимает свою строку между полями и кнопкой. */
.agree-row {
    display: flex;
    align-items: flex-start;
    margin: 4px 0 14px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--text-secondary);
    text-align: left;
}
.agree-row .cb-box { margin-top: 1px; }
.agree-row a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
