/* ≤980px: только навигация — горизонтальное меню не влезает, включаем бургер */
@media screen and (max-width: 980px) {
    /* Краевой отступ контента — тот же токен, что у закреплённых капсул
       (таб-бар). Раньше здесь стояло 15px против 14px у таб-бара, и карточки
       не совпадали с ним по боковым границам */
    body {
        padding: 0 var(--edge-gap);
    }
    /* На мобильном шапка липкая и во всю ширину, без «просветов» */
    #header {
        justify-content: space-between;
        position: sticky;
        top: 0;
        margin: 0 calc(-1 * var(--edge-gap)) 40px;
        padding: 8px var(--edge-gap);
        border-radius: 0;
        border: 0;
        box-shadow: none;
        /* Цвет браузерной зоны (theme-color = --bg-top) перетекает в шапку:
           сверху сплошной --bg-top, к низу плавно проступает блюр (--bg-blur).
           Переход растянут почти на всю высоту — короткий читался как граница */
        background:
            linear-gradient(to bottom, var(--bg-top) 25%, transparent 85%),
            var(--bg-blur);
    }
    /* Мягкий градиент-«шлейф» под липкой шапкой вместо жёсткой линии: контент
       уходит под шапку плавно, от цвета фона в прозрачность */
    #header::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: 100%;
        height: 18px;
        background: linear-gradient(to bottom, var(--bg-top), transparent);
        pointer-events: none;
    }
    .logo-wrapper img {
        max-width: 180px;
    }
    /* Индикатор сети прижат к бургеру, плашка офлайна — под липкой шапкой */
    #net-status {
        margin-right: 10px;
        padding: 4px 10px;
        font-size: 12px;
    }
    /* Плашка во всю ширину окна: боковые маржины гасят паддинг body тем же
       токеном. С жёстким -15px на экранах ≤480 (там паддинг был 12) она
       вылезала за края на 3px и давала горизонтальный скролл всей странице */
    #offline-note {
        margin: -26px calc(-1 * var(--edge-gap)) 20px;
        border-radius: 0;
    }
    /* Бургер не нужен: шторку открывает «Ещё» в нижнем таб-баре.
       У гостя ни шторки, ни таб-бара нет */
    .menu-burger {
        display: none;
    }
    /* Нижний таб-бар: основные пункты роли + «Ещё» (открывает шторку).
       z-index выше контролов Leaflet (1000), чтобы карта его не перекрывала */
    body.app-shell #tabbar {
        display: flex;
        position: fixed;
        left: var(--edge-gap);
        right: var(--edge-gap);
        bottom: calc(var(--edge-gap) + env(safe-area-inset-bottom));
        z-index: 1100;
        padding: 6px;
        gap: 2px;
        border-radius: var(--radius-capsule);
        background: var(--bg-blur);
        -webkit-backdrop-filter: saturate(180%) blur(20px);
        backdrop-filter: saturate(180%) blur(20px);
        border: 1px solid var(--separator);
        box-shadow: var(--shadow-card);
    }
    .tabbar-item {
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 3px;
        padding: 7px 2px 6px;
        /* радиус на ступень меньше капсулы таб-бара */
        border-radius: var(--radius-card);
        font-size: 11px;
        font-weight: 500;
        white-space: nowrap;
        color: var(--text-secondary);
        text-decoration: none;
        -webkit-tap-highlight-color: transparent;
    }
    .tabbar-item span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .tabbar-item svg {
        width: 22px;
        height: 22px;
        flex: none;
    }
    .tabbar-item:hover,
    .tabbar-item:focus {
        text-decoration: none;
        color: var(--text-secondary);
    }
    /* Без font-weight: активное состояние и так читается цветом и подложкой,
       а жирная подпись шире обычной — «Монтажи» переставало влезать
       в пункт и обрезалось многоточием на узких экранах */
    .tabbar-item.active {
        color: var(--tint);
        background: var(--tint-soft);
    }
    /* Контент не прячется под таб-баром */
    body.app-shell {
        padding-bottom: calc(86px + env(safe-area-inset-bottom));
    }
    /* Меню — затемняющий оверлей на весь экран; карточка прижата вниз, к
       большому пальцу (над таб-баром), «Обновить приложение» — над карточкой */
    .menu-wrapper {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(25, 18, 42, 0.45);
        -webkit-backdrop-filter: blur(8px);
        backdrop-filter: blur(8px);
        /* Слой внутри stacking context шапки; поверх карты шторку выносит
           подъём самой шапки (body.menu-open #header) */
        z-index: 111;
        padding: 24px 16px calc(100px + env(safe-area-inset-bottom));
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.22s ease, visibility 0.22s;
    }
    .menu-wrapper.active {
        opacity: 1;
        visibility: visible;
    }
    /* Сервисная ссылка «Обновить приложение» (webapp) — над карточкой меню */
    .menu-wrapper #pwa-hard-refresh-item {
        order: -1;
        margin: 0 0 14px;
    }
    /* Карточка меню «пружинно» поднимается снизу */
    .menu-wrapper ul {
        max-height: 100%;
        overflow: auto;
        transform-origin: bottom center;
        transform: scale(0.85) translateY(16px);
        opacity: 0;
        transition: transform 0.34s cubic-bezier(0.34, 1.45, 0.64, 1), opacity 0.16s ease;
    }
    .menu-wrapper.active ul {
        transform: none;
        opacity: 1;
    }
    /* Админка Битрикса не адаптирована под мобильные — в бургере не показываем */
    .menu-wrapper ul li.hide-mobile {
        display: none;
    }
    /* Пункты подъезжают каскадом; задержки только на открытие —
       закрывается всё разом, без ожидания */
    .menu-wrapper ul li {
        opacity: 0;
        transform: translateY(10px);
        transition: opacity 0.22s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .menu-wrapper.active ul li {
        opacity: 1;
        transform: none;
    }
    .menu-wrapper.active ul li:nth-child(1) { transition-delay: 0.03s; }
    .menu-wrapper.active ul li:nth-child(2) { transition-delay: 0.06s; }
    .menu-wrapper.active ul li:nth-child(3) { transition-delay: 0.09s; }
    .menu-wrapper.active ul li:nth-child(4) { transition-delay: 0.12s; }
    .menu-wrapper.active ul li:nth-child(5) { transition-delay: 0.15s; }
    .menu-wrapper.active ul li:nth-child(6) { transition-delay: 0.18s; }
    .menu-wrapper.active ul li:nth-child(7) { transition-delay: 0.21s; }
    /* Уважение к системной настройке «уменьшить движение» */
    @media (prefers-reduced-motion: reduce) {
        .menu-wrapper,
        .menu-wrapper ul,
        .menu-wrapper ul li,
        .menu-wrapper.active ul li:nth-child(n) {
            transition-duration: 0.01s;
            transition-delay: 0s;
        }
    }
    /* Пока меню открыто: страница не скроллится, а у шапки отключаем
       backdrop-filter — иначе она становится containing block для
       fixed-шторки и ломает её геометрию и блюр */
    body.menu-open {
        overflow: hidden;
    }
    body.menu-open #header {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        /* Шторка — потомок sticky-шапки, т.е. живёт в её stacking context:
           без подъёма шапки меню тонет под полноэкранной картой (1000).
           1090 — выше карты и её оверлеев, но под таб-баром (1100) */
        z-index: 1090;
    }
    /* Отдельного крестика нет: бургер остаётся поверх затемнения
       и его полоски складываются в крестик */
    .menu-burger {
        z-index: 112;
    }
    .menu-burger span,
    .menu-burger:before,
    .menu-burger:after {
        transition: transform 0.22s ease, opacity 0.15s ease, top 0.22s ease;
    }
    body.menu-open .menu-burger {
        background: var(--bg-card);
        box-shadow: var(--shadow-card);
    }
    body.menu-open .menu-burger:before {
        top: 17px;
        transform: rotate(45deg);
    }
    body.menu-open .menu-burger span {
        opacity: 0;
        transform: scaleX(0.4);
    }
    body.menu-open .menu-burger:after {
        top: 17px;
        transform: rotate(-45deg);
    }
    #header ul {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        font-size: 20px;
        padding: 0;
        margin: 0;
        background: var(--bg-card);
        border-radius: 16px;
        box-shadow: var(--shadow-card);
        overflow: hidden;
    }
    #header ul li {
        margin: 0;
        border-bottom: 1px solid var(--separator);
    }
    #header ul li:last-child {
        border-bottom: 0;
        padding: 14px 18px;
        margin: 0;
        font-size: 16px;
    }
    #header ul li a {
        display: block;
        padding: 14px 18px;
        border-radius: 0;
        font-size: 18px;
    }
    #header ul li a.active {
        background: var(--tint-soft);
    }
    /* Карта замеров: колонки не влезают — складываем в одну */
    .mmap-cols {
        grid-template-columns: 1fr;
        gap: 0;
    }
    /* Открытая карта — во весь экран (как отдельный экран приложения):
       легенда сверху, карта на всю высоту, снизу отступ под таб-бар,
       возврат — плавающая кнопка «К списку» */
    .mmap.map-open {
        position: fixed;
        inset: 0;
        z-index: 1000;
        margin: 0;
        /* Без нижнего отступа: карта уходит под плавающую капсулу таб-бара */
        padding: 0;
        background: var(--bg-top);
        display: flex;
        flex-direction: column;
    }
    /* Зум-контролы Leaflet поднимаем над таб-баром: 80 + margin-bottom 16
       контрола = 96 от низа карты, то есть --edge-gap над таб-баром
       (таб-бар 67.7 + его отступ 14 = 81.7) */
    .mmap.map-open .leaflet-bottom {
        bottom: calc(80px + env(safe-area-inset-bottom));
    }
    /* Карта на мобильном во всю ширину, поэтому её оверлеи стоят на том же
       --edge-gap, что таб-бар и кнопка «К списку», а не на десктопных 16 */
    .mmap.map-open .measure-map.leaflet-container .leaflet-right .leaflet-control-zoom {
        margin-right: var(--edge-gap);
    }
    /* Легенда — компактной карточкой поверх карты (снизу слева, над таб-баром),
       как оверлей на десктопной карте: заголовок + строки «точка · подпись · число».
       Карта при этом занимает весь экран от самого верха */
    .mmap.map-open .mmap-legend {
        position: absolute;
        /* Те же отступы, что у зум-контрола: слева --edge-gap, снизу 96
           (= 80px подъёма .leaflet-bottom + 16px отступа контрола) —
           оверлеи стоят на одной линии */
        left: var(--edge-gap);
        bottom: calc(96px + env(safe-area-inset-bottom));
        z-index: 1001;
        display: block;
        margin: 0;
        padding: 10px 14px 8px;
        background: var(--bg-blur);
        -webkit-backdrop-filter: saturate(180%) blur(20px);
        backdrop-filter: saturate(180%) blur(20px);
        border: 1px solid var(--separator);
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        /* Ширина ограничена так, чтобы легенда не наезжала на зум-контрол:
           слева 14 + справа 14 инсета зума + 38 его ширины + 16 зазора = 82.
           При max-width: 280 на 320px экране она перекрывала кнопки зума */
        max-width: min(280px, calc(100% - 82px));
    }
    .mmap.map-open .mmap-legend .mmap-legend-title {
        display: block;
    }
    .mmap.map-open .mmap-legend .mmap-chip {
        display: flex;
        background: transparent;
        border: 0;
        box-shadow: none;
        padding: 2px 0;
        font-size: 12px;
        gap: 7px;
    }
    .mmap.map-open .measure-map {
        display: block;
        flex: 1;
        height: auto;
        min-height: 0;
        border-radius: 0;
        box-shadow: none;
    }
    /* На менеджерских картах списки живут внутри .mmap —
       в полноэкранном режиме карты им не место */
    .mmap.map-open .mmap-cols,
    .mmap.map-open .mmap-panel {
        display: none;
    }
    .mmap.map-open .mmap-map-close {
        display: block;
        position: absolute;
        top: calc(var(--edge-gap) + env(safe-area-inset-top));
        right: var(--edge-gap);
        z-index: 1001;
        padding: 8px 14px;
        border: 0;
        border-radius: 100px;
        background: var(--bg-card);
        color: var(--tint);
        font-size: 14px;
        font-weight: 600;
        box-shadow: var(--shadow-card);
    }
    /* Спойлер карты действует на всём диапазоне таб-бара (≤980), а не только
       на телефонах: между 601 и 980px раньше зависал «полудесктоп» — карта
       инлайном под легендой без кнопки «Показать карту» */
    .measure-map {
        height: 420px;
        /* Карта свёрнута, пока не нажали «Показать карту» — тайлы
           не грузятся вообще */
        display: none;
    }
    .mmap.map-open .measure-map {
        display: block;
    }
    /* Карта в спойлере ниже — попапу оставляем меньше высоты.
       Селектор с .leaflet-container обязателен: базовое правило в
       template_styles.css тоже с ним (иначе его перебивал leaflet.css),
       и без префикса это правило проиграло бы ему по специфичности */
    .leaflet-container .leaflet-popup-content {
        max-height: 280px;
    }
    .mmap-map-toggle {
        display: block;
        width: 100%;
        margin-bottom: 12px;
        padding: 13px 16px;
        border: 0;
        border-radius: var(--radius-card);
        background: var(--bg-card);
        box-shadow: var(--shadow-card);
        color: var(--tint);
        font-size: 15px;
        font-weight: 600;
        text-align: center;
    }
    /* Кнопка живёт наверху списка, вне .mmap, — прячем её по состоянию блока
       карты. Без :has() ничего не ломается: открытая карта и так лежит
       поверх страницы фиксированным оверлеем и накрывает кнопку */
    body:has(.mmap.map-open) .mmap-map-toggle {
        display: none;
    }
    /* Легенда относится к карте — прячем её вместе с картой под кнопку
       «Показать карту»; в открытой карте её показывает правило
       карточки-оверлея выше (display: block) */
    .mmap-legend {
        display: none;
    }
    /* Меню фильтра раскрывается вниз, а внизу закреплён таб-бар (z-index 1100):
       на невысоких экранах 320px меню уходили под него на 55px и нижние
       пункты списка сотрудников были недоступны */
    .nice-select-menu {
        max-height: 40vh;
    }
    /* Таблицы сотрудников: компактные карточки.
       Шапка: точка-индикатор синхронизации + ФИО + кнопки копировать/обновить.
       Остальные поля — под спойлером «Подробнее».
       Порог именно 980, а не 600: min-content таблицы — 923px, поэтому при 768
       она вылезала за экран на 169px (колонки «Пароль» и «Обновить пароль»
       уходили за край, и вместе с ними уезжала sticky-капсула шапки).
       980 — тот же порог, на котором рейл сменяется таб-баром */
    .emp-sync table,
    .emp-sync tbody,
    .emp-sync tr,
    .emp-sync td {
        display: block;
    }
    .emp-sync thead {
        display: none;
    }
    .emp-sync table {
        background: none;
        box-shadow: none;
        border-radius: 0;
        overflow: visible;
    }
    .emp-sync tbody tr {
        position: relative;
        display: flex;
        flex-direction: column;
        background: var(--bg-card);
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        padding: 6px 14px;
        margin-bottom: 12px;
    }
    /* Глушим десктопный hover — на таче он «залипает» серым */
    .emp-sync table tbody tr:hover td {
        background: transparent;
    }
    .emp-sync td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 9px 0;
        border-bottom: 1px solid var(--separator);
    }
    .emp-sync td:first-child {
        display: none;
    }
    .emp-sync td:before {
        content: attr(data-label);
        color: var(--text-secondary);
        font-size: 13px;
        flex: none;
    }
    /* Шапка карточки: ФИО всегда первой строкой */
    .emp-sync td.emp-name {
        order: -1;
        justify-content: flex-start;
        font-weight: 600;
        font-size: 16px;
        border-bottom: 0;
        /* Справа резерв под одну кнопку «копировать» (58 + инсет 14 + запас) */
        padding: 10px 80px 10px 22px;
    }
    .emp-sync td.emp-name:before {
        display: none;
    }
    /* Синхронизация — цветная точка слева от ФИО
       (цвет берётся из inline-стиля через currentColor) */
    .emp-sync td[data-label="Синхронизация"] {
        position: absolute;
        left: 14px;
        top: 22px;
        padding: 0;
        border: 0;
    }
    .emp-sync td[data-label="Синхронизация"]:before {
        display: none;
    }
    .emp-sync td[data-label="Синхронизация"] span {
        display: block;
        width: 10px;
        height: 10px;
        border-radius: 50%;
        font-size: 0;
        background: currentColor;
        box-shadow: 0 0 6px currentColor;
    }
    /* В шапке карточки остаётся только «копировать» — действие безобидное.
       Инсет считается от бордер-бокса строки, поэтому паддинг карточки (14)
       заложен в right вручную: иначе кнопка свисала бы в паддинг */
    .emp-sync .copy-pswd {
        position: absolute;
        top: 12px;
        right: 14px;
        width: auto;
        padding: 0 8px;
        gap: 4px;
    }
    /* Подпись «pwd» — на мобильном пароль скрыт под спойлером,
       без неё непонятно, что копирует кнопка */
    .emp-sync .copy-pswd:after {
        content: 'pwd';
        font-size: 11px;
        font-weight: 600;
        line-height: 1;
    }
    /* Смена пароля — под самим паролем и только в развёрнутой карточке.
       В шапке рядом с «копировать» это была безымянная иконка-близнец:
       непонятно, что она делает, и её жали по ошибке — а нажатие
       генерирует пользователю новый пароль */
    .emp-sync td[data-label="Обновить пароль"] {
        position: static;
        padding: 8px 0 0;
        border: 0;
        justify-content: flex-end;
    }
    .emp-sync td[data-label="Обновить пароль"]:before {
        display: none;
    }
    /* Пароля у пользователя ещё нет — кнопки и её пустой строки тоже */
    .emp-sync td:has(.upd-passwrd:empty) {
        display: none;
    }
    .emp-sync .upd-passwrd {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        width: auto;
        height: 28px;
        padding: 0 10px;
        background: var(--fill);
        border-radius: 8px;
        color: var(--text-secondary);
        font-size: 12px;
        font-weight: 600;
        text-align: left;
    }
    .emp-sync .upd-passwrd:after {
        content: 'Сменить пароль';
    }
    .emp-sync .upd-passwrd .ic-sync {
        width: 14px;
        height: 14px;
        margin: 0;
    }
    /* Свёрнутая карточка: пароля не видно — не показываем и смену пароля */
    .emp-sync tr.collapsed td[data-label="Обновить пароль"] {
        display: none;
    }
    /* Свёрнутое состояние: детали скрыты, кнопки остаются */
    .emp-sync tr.collapsed td[data-label="ID-B24"],
    .emp-sync tr.collapsed td[data-label="Логин"] {
        display: none;
    }
    .emp-sync tr.collapsed td[data-label="Пароль"] {
        padding: 0;
        border: 0;
    }
    .emp-sync tr.collapsed td[data-label="Пароль"]:before,
    .emp-sync tr.collapsed td[data-label="Пароль"] .pswd-container {
        display: none;
    }
    /* Спойлер — компактная ссылка СЛЕВА с шевроном. Справа внизу карточки
       сидит «Сменить пароль»: когда спойлер стоял там же, в свёрнутом виде
       они оказывались почти в одной точке и по паролю попадали случайно */
    .emp-sync .emp-toggle {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 5px;
        color: var(--text-secondary);
        font-size: 12px;
        font-weight: 500;
        margin-top: 4px;
        padding: 2px 0 8px;
        border: 0;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }
    .emp-sync .emp-toggle:before {
        display: none;
    }
    .emp-sync .emp-toggle:after {
        content: '';
        width: 6px;
        height: 6px;
        border-right: 1.5px solid currentColor;
        border-bottom: 1.5px solid currentColor;
        transform: translateY(-2px) rotate(45deg);
        transition: transform .2s;
    }
    .emp-sync tr:not(.collapsed) .emp-toggle:after {
        transform: translateY(1px) rotate(225deg);
    }
    /* В развёрнутом виде спойлер отделён от полей и не липнет к ним */
    .emp-sync tr:not(.collapsed) .emp-toggle {
        margin-top: 0;
        padding-top: 9px;
    }
}

/* ≤600px: мобильная раскладка — карточки на всю ширину, контролы ужимаются */
@media screen and (max-width: 600px) {
    html, body {
        min-width: 320px;
    }
    #page-wrapper {
        min-width: 0;
    }
    .calc-wrapper .calc-block .line {
        margin-right: 0;
        width: 100%;
    }
    .calc-wrapper .result {
        width: 100%;
    }
    /* Карта замеров: чипы легенды компактнее, отступы карточек меньше */
    .mmap-chip {
        padding: 6px 11px;
        font-size: 13px;
        gap: 6px;
    }
    .mmap-col h2 {
        font-size: 18px;
    }
    .mmap-acc-head {
        padding: 13px 14px;
    }
    .mmap-acc-item {
        padding: 11px 14px;
    }
    /* Ничего внутри карточек не должно вылезать за экран */
    .calc-wrapper .line input,
    .calc-wrapper .line select,
    .calc-wrapper .line .select2-container {
        max-width: 100% !important;
    }
    .calc-wrapper .top-wrap-selects {
        max-width: 100%;
    }
    /* Блоки внутри карточки — не шире самой карточки */
    .calc-wrapper .line > div {
        max-width: 100%;
        min-width: 0;
    }
    .measure {
        max-width: 100%;
    }
    /* Страховка от горизонтального скролла всей страницы */
    body {
        overflow-x: hidden;
        overflow-x: clip;
    }
}

/* ≤480px: узкие экраны — ужимаем контролы, чтобы карточка целиком влезала */
@media screen and (max-width: 480px) {
    /* Боковой отступ здесь не переопределяем: он приходит из --edge-gap
       блоком выше и совпадает с закреплённым таб-баром */
    #header {
        margin-bottom: 36px;
    }
    h1 {
        font-size: 26px;
    }
    .calc-wrapper .calc-block .top-label {
        font-size: 11px;
    }
    .calc-wrapper .result h3 {
        font-size: 15px;
    }
}

@media screen and (max-width: 350px) {
    /* Пункт таб-бара тут всего 54px: «Монтажи» при кегле 11 занимает 50 из 50 */
    .tabbar-item {
        font-size: 10px;
    }
}

/* ---------- Калькулятор: адаптив карточек ----------
   Ступени 700 / 440 / 390 / 360 из утверждённого макета. Подвал карточки
   (три колонки на ≤1120) задан в template_styles.css рядом с базовыми правилами */

/* ≤700: телефон — контролы 44px под палец, поля по два в ряд, короткие подписи */
@media screen and (max-width: 700px) {
    .calc-wrapper .lab-full {
        display: none;
    }
    .calc-wrapper .lab-short {
        display: inline;
    }
    /* Два поля в ряд вместо одного: 60% минус узкое поле рядом */
    .calc-wrapper .row-b > .grow {
        flex: 1 1 calc(60% - 40px);
        min-width: 45%;
    }
    .calc-wrapper .row-b > .w60 {
        width: 60px;
    }
    /* Каскад оборудования/работ: каждый селект на своей строке (пара 45%+45%
       ловила порог округления и на части ширин вставала в строку с обрезкой),
       последний селект делит строку со стоимостью */
    .calc-wrapper .row-b.row-stack > .grow {
        flex: 1 1 100%;
        min-width: 0;
    }
    .calc-wrapper .row-b.row-stack > .grow.grow-last {
        flex: 1 1 0;
        min-width: 55%;
    }
    /* Цена дожимается вправо компактной ячейкой */
    .calc-wrapper .price-cell {
        flex: 0 0 auto;
        min-width: 84px;
        margin-left: auto;
    }
    .calc-wrapper .price-cell .f-label {
        width: 100%;
    }
    .calc-wrapper .price-cell .price-num {
        font-size: 17px;
    }
    .calc-wrapper .calc-block .sec-title {
        font-size: 19px;
    }
    .calc-wrapper .calc-block .sec-sum {
        font-size: 15px;
    }
    .calc-wrapper .pos-num {
        font-size: 22px;
        line-height: 30px;
    }
    .calc-wrapper .pos-num-quiet {
        font-size: 18px;
    }
    .calc-wrapper .pos-val {
        height: 30px;
    }
    .calc-wrapper .pos-cap {
        gap: 8px;
    }
    .calc-wrapper .calc-block .line {
        padding: 52px 12px 12px;
    }
    .calc-wrapper .calc-block .line .head-title {
        left: 8px;
    }
    .calc-wrapper .calc-block .line .del-line {
        right: 12px;
    }
    .calc-wrapper .calc-block .line .head-qty {
        right: 46px;
    }
    .calc-wrapper .calc-block input[type="text"],
    .calc-wrapper .calc-block .ctrl-in,
    .calc-wrapper .sel-ghost,
    .calc-wrapper .kp-modal .kp-field input,
    .calc-wrapper .info-line input[type="text"],
    .calc-wrapper .info-line input[type="date"],
    .calc-wrapper .info-line input[type="datetime-local"],
    .calc-wrapper .info-line select:not(.select2-hidden-accessible),
    .calc-wrapper .select2-container--default .select2-selection--single,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single {
        height: 44px;
        /* без min-height высоту держит базовые 40px из template_styles.css */
        min-height: 44px;
        line-height: 42px;
    }
    .calc-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single .select2-selection__rendered {
        line-height: 42px;
    }
    .calc-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single .select2-selection__arrow {
        height: 42px;
    }
    /* Кол-во и поля габаритов свою высоту держат сами */
    .calc-wrapper .calc-block .line .head-qty input.ctrl-in {
        height: 32px;
        line-height: 30px;
    }
    /* Схема остаётся рядом с полями: в столбик карточка становится слишком длинной */
    .calc-wrapper .main .panel-params {
        grid-template-columns: minmax(100px, 1fr) minmax(0, 176px);
        gap: 14px;
        margin-top: 8px;
    }
    .calc-wrapper .main .panel-params .scheme-box {
        width: 100%;
        max-width: 230px;
        min-width: 100px;
        justify-self: center;
    }
    .calc-wrapper .calc-block .dim-field .ctrl-in {
        width: 46px;
        height: 40px;
        line-height: 40px;
        font-size: 14px;
    }
    .calc-wrapper .dim-label {
        padding-right: 0;
        font-size: 12.5px;
        white-space: nowrap;
    }
    .calc-wrapper .dim-field {
        gap: 5px;
        padding: 0 7px;
    }
    .calc-wrapper .dim-field::after {
        font-size: 11px;
    }
    .calc-wrapper .dim-badge {
        width: 18px;
        height: 18px;
        border-radius: 5px;
        font-size: 10px;
    }
    .calc-wrapper .dim-sec-title {
        font-size: 10px;
        padding: 6px 8px 0;
    }
    .calc-wrapper .dim-field + .dim-field::before {
        left: 34px;
    }
    /* Переключатели бортика и кромки: на телефоне рядом с полем размера они не
       помещаются, поэтому уходят на свою строку внутри той же строки габаритов
       и делят её поровну — крупная зона нажатия. Пустой слот скрыт (:empty),
       поэтому строки без бортика/кромки высоту не набирают */
    .calc-wrapper .dim-field {
        flex-wrap: wrap;
        height: auto;
        min-height: 40px;
    }
    .calc-wrapper .dim-edge {
        order: 1;
        flex: 1 0 100%;
        margin: 0 0 6px;
    }
    .calc-wrapper .edge-toggle {
        flex: 1 1 0;
        min-width: 68px;
        height: 28px;
        padding: 0 6px;
        font-size: 11px;
    }
    .calc-wrapper .edge-toggle-x {
        min-width: 19px;
        height: 14px;
        margin-left: 5px;
        font-size: 10px;
    }
    .calc-wrapper .dims-cap .edges-total {
        font-size: 11px;
    }
    .calc-wrapper .main .panel-params .scheme-box.over-2 {
        padding-top: 11px;
    }
    .calc-wrapper .main .panel-params .dims.over-50 {
        padding-top: 7px;
    }
    .calc-wrapper .main .panel-params .dims.over-35 {
        padding-top: 1px;
    }
    .calc-wrapper .scheme-hint {
        font-size: 10px;
    }
}

/* ≤440: подвал в две колонки, стоимость — на всю ширину */
@media screen and (max-width: 440px) {
    .calc-wrapper .pos-foot {
        grid-template-columns: 1fr 1fr;
    }
    .calc-wrapper .pos-cell-price {
        grid-column: 1 / -1;
    }
    .calc-wrapper .calc-block input[type="text"],
    .calc-wrapper .calc-block .ctrl-in,
    .calc-wrapper .sel-ghost,
    .calc-wrapper .kp-modal .kp-field input,
    .calc-wrapper .info-line input[type="text"],
    .calc-wrapper .info-line input[type="date"],
    .calc-wrapper .info-line input[type="datetime-local"],
    .calc-wrapper .info-line select:not(.select2-hidden-accessible),
    .calc-wrapper .select2-container--default .select2-selection--single,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single {
        height: 38px;
        min-height: 38px;
        line-height: 36px;
        font-size: 14px;
    }
    .calc-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single .select2-selection__rendered {
        line-height: 36px;
        font-size: 14px;
    }
    .calc-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow,
    .calc-wrapper .calc-block .select2-container--default .select2-selection--single .select2-selection__arrow {
        height: 36px;
    }
    .calc-wrapper .calc-block .line .head-qty input.ctrl-in {
        height: 32px;
        line-height: 30px;
        font-size: 14px;
    }
    .calc-wrapper .calc-block .dim-field .ctrl-in {
        height: 40px;
        line-height: 40px;
    }
    .calc-wrapper .row-b > .w60 .ctrl-in {
        padding: 0 6px;
    }
    .calc-wrapper .f-label {
        font-size: 11.5px;
    }
    /* Панель просмотра КП: на узком экране заголовок и кнопки ужимаются,
       документу отдаётся почти вся ширина */
    .kp-view-bar {
        padding-left: 10px;
        padding-right: 10px;
    }
    .kp-view-title {
        font-size: 13px;
    }
    .kp-view-bar .bttn {
        padding: 0 12px;
        font-size: 13px;
    }
    .kp-view-doc {
        padding-left: 8px;
        padding-right: 8px;
    }
}

/* ≤390: схема не влезает рядом с полями — уходит под них горизонтальной */
@media screen and (max-width: 390px) {
    .calc-wrapper .main .panel-params {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
    }
    .calc-wrapper .main .panel-params .scheme-box {
        max-width: 100%;
        min-width: 0;
        justify-self: stretch;
    }
    /* Обе ориентации лежат в DOM, переключение — только классом */
    .calc-wrapper .scheme-box .sch-portrait {
        display: none !important;
    }
    .calc-wrapper .scheme-box .sch-landscape {
        display: block !important;
        max-width: 300px;
        margin: 0 auto;
    }
    /* В шапке карточки подпись «Кол-во» упирается в сегмент материала — оставляем
       только поле и «шт» (на 375 они уже стояли вплотную) */
    .calc-wrapper .calc-block .line .head-qty > span:first-child {
        display: none;
    }
    .calc-wrapper .main .panel-params .dims.over-2,
    .calc-wrapper .main .panel-params .dims.over-50,
    .calc-wrapper .main .panel-params .dims.over-35,
    .calc-wrapper .main .panel-params .scheme-box.over-2,
    .calc-wrapper .main .panel-params .scheme-box.over-50,
    .calc-wrapper .main .panel-params .scheme-box.over-35 {
        padding-top: 0;
    }
    .calc-wrapper .dim-label {
        font-size: 13px;
    }
    .calc-wrapper .calc-block .dim-field .ctrl-in {
        width: 64px;
    }
    /* Кнопки модалки КП в колонку: рядом «Сформировать КП» не влезает и
       вылезает за кнопку (nowrap). Главная — сверху, «Отмена» под ней */
    .kp-modal-actions {
        flex-direction: column-reverse;
    }
    .kp-modal-actions .bttn,
    .kp-modal-actions .kp-submit {
        flex: none;
        width: 100%;
    }
}

/* ≤360: самые узкие — у кол-ва остаётся только поле и «шт» */
@media screen and (max-width: 360px) {
    .calc-wrapper .row-b > .grow {
        flex: 1 1 calc(60% - 36px);
        min-width: 45%;
    }
    .calc-wrapper .row-b > .w60 {
        width: 52px;
    }
    .calc-wrapper .calc-block .line {
        padding: 50px 10px 10px;
    }
    .calc-wrapper .calc-block .line .head-title {
        left: 6px;
        gap: 6px;
    }
    .calc-wrapper .calc-block .line .head-title .mat-btn {
        padding: 0 9px;
        font-size: 12px;
    }
    .calc-wrapper .calc-block .line .del-line {
        right: 10px;
    }
    .calc-wrapper .calc-block .line .head-qty {
        right: 42px;
    }
    .calc-wrapper .dim-field {
        gap: 6px;
        padding: 0 8px;
    }
    .calc-wrapper .calc-block .dim-field .ctrl-in {
        width: 56px;
        font-size: 14px;
    }
    .calc-wrapper .dim-field::after {
        font-size: 12px;
    }
    .calc-wrapper .pos-foot {
        gap: 12px 10px;
    }
    .calc-wrapper .pos-num {
        font-size: 20px;
    }
    .calc-wrapper .pos-num-quiet {
        font-size: 16px;
    }
    .calc-wrapper .calc-block .sec-title {
        font-size: 17px;
    }
    .calc-wrapper .calc-block .sec-sum {
        font-size: 14px;
    }
    .calc-wrapper .sum-seg-btn {
        padding: 0 6px;
        font-size: 11px;
    }
    .calc-wrapper .sum-bar-val {
        font-size: 19px;
    }
    .calc-wrapper .sum-bar-more {
        padding: 0 11px;
        font-size: 12px;
    }
    .calc-wrapper .sum-total-value {
        font-size: 30px;
    }
}
