* { box-sizing: border-box; }

/* --- Универсальные всплывающие уведомления (тосты) --- */
.toast-root {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%); /* по центру вверху экрана */
    z-index: 2000;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    max-width: min(480px, 92vw);
    pointer-events: none; /* клики ловят сами тосты, контейнер прозрачен */
}
.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border-radius: 8px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .18);
    color: #fff;
    font-size: 14px;
    animation: toast-in .25s ease-out;
}
.toast-success { background: #16a34a; }
.toast-error   { background: #dc2626; }
.toast-info    { background: #2563eb; }
.toast-msg { flex: 1 1 auto; word-break: break-word; }
.toast-close {
    background: transparent;
    border: none;
    color: inherit;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    opacity: .85;
    padding: 0;
}
.toast-close:hover { opacity: 1; }
.toast-hide { animation: toast-out .25s ease-in forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-12px); } }
body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: #f4f6f8;
    color: #222;
    line-height: 1.5;
}
.container { max-width: 1000px; margin: 0 auto; padding: 0 16px; }
/* container-wide применяется для страниц с большим объёмом данных:
   таблиц поверок, графиков, админских списков и журнала импортов.
   Расширяется на всю ширину экрана с фиксированными отступами 24px. */
.container-wide {
    max-width: none;
    padding: 0 24px;
}
/* --- Шапка из двух строк ---
   Первая строка: только название системы.
   Вторая строка: меню слева, пользователь и выход справа.
   На мобильных нав-строка переносится на 2 ряда (flex-wrap), а сами
   меню тоже могут переноситься, чтобы ничего не вылезало за экран. */
.topbar { background: #fff; border-bottom: 1px solid #e1e4e8; }
.topbar-brand { padding: 14px 24px 10px; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
/* Версия ПО — мелким шрифтом, прижата к правому краю брендовой строки. */
.app-version { font-size: 11px; color: #9aa0a6; white-space: nowrap; }
.brand {
    font-weight: 700;
    font-size: 18px;
    text-decoration: none;
    color: #1a73e8;
    letter-spacing: 0.2px;
}
.topbar-nav {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    gap: 16px;
    padding: 0 24px;
    flex-wrap: wrap;
    border-top: 1px solid #f1f3f5; /* мягкий разделитель с брендовой строкой */
}
.topbar-nav-left,
.topbar-nav-right {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}
.topbar-nav-right { gap: 16px; }

/* Пункты меню как вкладки Material/Google Play.
   Аналогично вкладкам «Таблица/Графики» внутри страниц — это даёт
   единый визуальный язык: куда бы пользователь ни перешёл, навигация
   везде в одинаковом стиле. Активный пункт — синий с подчёркиванием. */
.nav-tab {
    /*
        inline-flex (вместо inline-block) — чтобы иконка и подпись
        выровнялись по вертикали независимо от высот глифов. Без этого
        иконка съезжает на пару пикселей вверх относительно базовой
        линии текста.
    */
    display: inline-flex;
    align-items: center;
    padding: 12px 18px;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.25px;
    color: #5f6368;
    text-decoration: none;
    border-bottom: 3px solid transparent;
    margin-bottom: -1px; /* перекрывает .topbar-nav border-top на 1px */
    transition: color .15s, background .15s, border-color .15s;
}
.nav-tab:hover {
    color: #1a73e8;
    background: rgba(26, 115, 232, 0.04);
}
.nav-tab.nav-tab-active {
    color: #1a73e8;
    border-bottom-color: #1a73e8;
}
/* Иконки в шапке навигации. font-size задаёт размер глифа Bootstrap
   Icons (это шрифт, не SVG), margin-right — отбивка от текста. Цвет
   наследуется от .nav-tab, поэтому hover/active автоматически окрашивают
   и иконку тоже. */
.nav-icon {
    font-size: 16px;
    margin-right: 8px;
    /* line-height: 1 убирает паразитное вертикальное пространство глифа,
       чтобы иконка прижалась к тексту без избыточного зазора сверху-снизу. */
    line-height: 1;
}
.user-info { color: #555; }
.role { font-size: 11px; padding: 2px 8px; border-radius: 10px; margin-left: 4px; }
.role-admin { background: #fde8e8; color: #b91c1c; }
.role-user { background: #e0f2fe; color: #075985; }
main { padding: 24px 0; }
h1 { margin-top: 0; }
.alert { padding: 10px 14px; border-radius: 6px; margin-bottom: 16px; }
.alert-success { background: #e6f7ec; color: #1b5e20; border: 1px solid #b7e1c2; }
.alert-error { background: #fde8e8; color: #b91c1c; border: 1px solid #f5b5b5; }
.form { display: flex; flex-direction: column; gap: 12px; max-width: 420px; background: #fff; padding: 20px; border-radius: 8px; border: 1px solid #e1e4e8; }
/* Обёртка для центрирования «узких» страниц без верхней навигации
   (вход / регистрация / подтверждение email / сброс пароля). Кладёт
   контент в колонку шириной до 420px и центрирует по горизонтали.
   Заголовок и нижние подписи тоже центрируются. */
.center-card-page {
    max-width: 420px;
    margin: 40px auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
    text-align: center;
}
.center-card-page h1 { margin: 0; }
.center-card-page .form { margin: 0 auto; width: 100%; text-align: left; }
.center-card-page p { margin: 0; color: #555; }
/* Форма импорта шире обычной — чтобы совпадала по ширине с progress-box ниже. */
.form-import { max-width: 720px; }
/* fieldset формы импорта прозрачен; внутри него — лейбл и кнопка справа. */
.form-import fieldset { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.form-import .btn-submit { align-self: flex-end; margin-top: 4px; padding: 10px 20px; }
.form label { display: flex; flex-direction: column; font-size: 14px; color: #333; gap: 4px; }
.form label.checkbox { flex-direction: row; align-items: center; gap: 8px; }
.form input, .form select { padding: 8px 10px; border: 1px solid #d0d7de; border-radius: 6px; font-size: 14px; }
.form input:focus, .form select:focus { outline: none; border-color: #1a73e8; }
.form small { color: #777; font-weight: normal; }
.btn { display: inline-block; padding: 8px 16px; background: #1a73e8; color: #fff; border: none; border-radius: 6px; text-decoration: none; cursor: pointer; font-size: 14px; }
.btn:hover { background: #1660c1; }
.btn-secondary { background: #e1e4e8; color: #333; }
.btn-secondary:hover { background: #cfd5db; }
.form-actions { display: flex; gap: 8px; }
.link-button { background: none; border: none; color: #1a73e8; cursor: pointer; padding: 0; font: inherit; }
.link-button:hover { text-decoration: underline; }
.link-button.danger { color: #b91c1c; }
.inline { display: inline; }
.page-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.users-table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; border: 1px solid #e1e4e8; }
.users-table th, .users-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #eef0f2; font-size: 15px; }
.users-table th { background: #f8f9fa; font-weight: 600; }
.users-table .actions { display: flex; gap: 12px; }

/* /mi-types — компактная плотность таблицы. На странице 50 строк,
   при стандартной высоте (~38px) она перекрывает 2 экрана; уменьшаем
   до ~26px на строку, чтобы видеть больше типов без скролла. Кегль не
   меняем (читаемость важнее), только вертикальные отступы. */
.mi-types-table th,
.mi-types-table td {
    padding: 4px 12px;
}
/* Чекбокс «Импорт» был набран с большой высотой из-за дефолтного
   line-height. Прижимаем его, чтобы строки таблицы стали одинаково
   низкими независимо от наличия чекбокса. */
.mi-types-table .checkbox-wrap { line-height: 1; }

/* Кликабельные заголовки сортируемых колонок. По умолчанию выглядят
   как обычный текст заголовка (наследуют цвет/жирность от .users-table
   th), при ховере подсвечиваются. */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}
.th-sort:hover { color: #1a73e8; }
/* Активная колонка сортировки — синий цвет (тот же, что у активной
   вкладки в шапке), чтобы пользователь сразу видел, по какому полю
   сейчас отсортировано. */
.th-sort-active { color: #1a73e8; }
.sort-arrow { font-size: 10px; line-height: 1; }

/* Панель массовых операций над таблицей типов СИ.
   Тонкая строка над таблицей: подпись + три кликабельные ссылки.
   Визуально не «кнопочная», чтобы не привлекать лишнего внимания —
   это вспомогательное действие, основные взаимодействия идут через
   сами чекбоксы в строках. */
.bulk-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 12px 0 8px;
    font-size: 13px;
}
.bulk-label { color: #6b7280; }
.bulk-link {
    color: #1a73e8;
    text-decoration: none;
    cursor: pointer;
}
.bulk-link:hover { text-decoration: underline; }

/* статус-бейдж в журнале импортов */
.status { font-size: 11px; padding: 2px 8px; border-radius: 10px; display: inline-block; }
.status-running { background: #fef3c7; color: #92400e; }
.status-success { background: #d1fae5; color: #065f46; }
.status-error   { background: #fde8e8; color: #b91c1c; }

/* прогресс-бар импорта */
.progress-box { background: #fff; padding: 20px; border-radius: 8px; border: 1px solid #e1e4e8; margin: 16px 0 24px; max-width: 720px; }
.progress-box h3 { margin: 0 0 10px; font-size: 16px; }
.progress-bar { background: #eef0f2; height: 22px; border-radius: 11px; overflow: hidden; }
.progress-fill { background: #1a73e8; height: 100%; width: 0%; transition: width .3s ease; color: #fff; text-align: center; font-size: 12px; line-height: 22px; font-weight: 600; }
.progress-fill.ok  { background: #16a34a; }
.progress-fill.err { background: #b91c1c; }
.progress-stage { margin: 10px 0 6px; color: #444; font-size: 14px; }
.progress-stage-row { display: flex; align-items: center; gap: 10px; margin: 10px 0 6px; }
.progress-stage-row .progress-stage { margin: 0; }
/* loading-spinner-small — компактный вариант для прогресса импорта.
   Отдельный класс вместо переопределения .loading-spinner-inline через каскад,
   потому что переопределение зависело от родительского селектора и могло не
   применяться при определённых порядках обновления DOM. */
.loading-spinner-small {
    width: 18px;
    height: 18px;
    border: 2px solid #e1e4e8;
    border-top-color: #1a73e8;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    flex-shrink: 0;
}
/* Прогресс-статистика — 6 компактных плашек в одну строку.
   Раньше min-width:110px давал суммарно ~860px при ширине бокса 720px и
   последняя плашка («скорость») переносилась на новую строку. Уменьшаем шрифты
   и min-width, разрешаем горизонтальный скролл как fallback. */
.progress-stats { display: flex; gap: 8px; flex-wrap: nowrap; margin-top: 10px; overflow-x: auto; }
.progress-stats > div {
    background: #f8f9fa;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 11px;
    color: #555;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 0;
    white-space: nowrap;
}
.progress-stats > div strong { font-size: 14px; color: #111; }
.progress-message { margin-top: 12px; }
.alert-warn { background: #fef3c7; color: #92400e; border: 1px solid #fcd34d; padding: 10px 14px; border-radius: 6px; }

/* --- страница /verifications --- */

/* блок фильтров — нативное <details>, без анимации (раньше пробовал плавное
   раскрытие через grid-template-rows: 0fr↔1fr — давало дёрганья на длинном
   контенте, отказались). */
.filter-block {
    background: #fff;
    border: 1px solid #e1e4e8;
    border-radius: 8px;
    margin: 16px 0;
}
.filter-block summary {
    cursor: pointer;
    font-weight: 600;
    color: #333;
    padding: 12px 16px;
    list-style: none;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 8px;
}
.filter-block summary::-webkit-details-marker { display: none; }
/* Своя стрелка — поворачивается мгновенно вместе с открытием. */
.filter-block summary::before {
    content: '▶';
    font-size: 10px;
    color: #6e7681;
    display: inline-block;
}
.filter-block[open] summary::before { transform: rotate(90deg); }

/* Обёртка для страниц «с управляющими блоками» (mi-types, import).
   Ограничивает ширину контента, чтобы блоки не растягивались на 2000px+
   на широких мониторах и подсказки оставались читаемыми. На узких
   экранах ужмётся естественно.

   /mi-types — 1100px (более компактная страница с фильтрами).
   /import   — 1800px: таблице операций нужен воздух, чтобы названия
   типов СИ в колонке «Операция» и подписи в «Подробнее» не упирались
   друг в друга. Если разрешение монитора меньше 1800px — блок ужмётся
   до ширины окна, горизонтального скролла страницы не будет. */
.mi-types-page         { max-width: 1100px; }
.import-launch-block,
#progress-section      { max-width: 1800px; }

/* Страница /settings — узкая колонка, прижатая к левому краю
   (никакого margin: 0 auto). Левый край совпадает с другими страницами
   за счёт общих отступов .container/.container-wide. */
.settings-page {
    max-width: 720px;
}
/* Чекбокс + подпись одной строкой, чтобы галка визуально «прилипала»
   к заголовку настройки. gap=10px чуть шире обычного — для удобства
   клика по чеку отдельно от текста. */
.settings-check {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    margin: 0 0 4px;
}
.settings-check input[type="checkbox"] {
    /* Чуть крупнее дефолтного — единственный элемент на странице,
       его не должно быть «трудно попасть курсором». */
    width: 16px;
    height: 16px;
    cursor: pointer;
}

/* Статическая шапка для filter-block без <summary> (когда блок не сворачивается,
   например «Запуск импорта»). Визуально совпадает с .filter-block summary, но
   без курсора-указателя и без стрелки. */
.filter-block-head {
    font-weight: 600;
    color: #333;
    padding: 12px 16px;
    user-select: none;
}

.filter-form { padding: 0 16px 12px; }
.filter-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 16px; }
.filter-grid label { display: flex; flex-direction: column; font-size: 13px; color: #444; gap: 4px; }
.filter-grid input, .filter-grid select { padding: 6px 8px; border: 1px solid #d0d7de; border-radius: 4px; font-size: 13px; }
.filter-actions { display: flex; gap: 12px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
.filter-summary { color: #555; }

/* Вариант сетки на 2 колонки (CSV-форма, форма импорта). На узких экранах
   разваливается в одну колонку — медиа-запросы в конце файла. */
.filter-grid-2 { grid-template-columns: 1fr 1fr; }

/* CSV-загрузка: «файл слева — кнопка справа» одной строкой.
   Файл забирает всё свободное место, кнопка прижата к правому краю. */
.csv-upload-row {
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
}
.csv-upload-row > label {
    /* flex-basis 320px = «не сжимайся уже этого», расти можно, но не больше 75%
       ширины блока — иначе на широком экране поле выглядит «бесконечным»,
       а кнопка прижата к правому краю. */
    flex: 1 1 320px;
    max-width: 75%;
    display: flex;
    flex-direction: column;
    font-size: 13px;
    color: #444;
    gap: 4px;
}
/* Модификатор compact: label не растягивается, занимает место по содержимому.
   Используется когда поле короткое (например, «Год поверки»), чтобы кнопка
   стояла сразу за полем, а не убегала к правому краю. */
.csv-upload-row.compact > label {
    flex: 0 0 auto;
    max-width: none;
}
.csv-upload-row > label input,
.csv-upload-row > label select {
    padding: 6px 8px;
    border: 1px solid #d0d7de;
    border-radius: 4px;
    font-size: 13px;
    background: #fff;
}
/* Короткие числовые/текстовые поля (например, «Год поверки») не должны
   тянуться на всю ширину label. file-input и обычный text оставляем как есть —
   они могут содержать длинные имена. */
.csv-upload-row > label input[type="number"] {
    max-width: 140px;
}
.csv-upload-row > .btn { flex: 0 0 auto; align-self: end; }

/* Подсказка под формой — растягиваем по всей ширине, отступы и фон,
   чтобы она «склеивалась» с блоком и не висела одинокой строкой. */
.filter-hint {
    display: block;
    margin: 12px 0 0;
    padding: 10px 12px;
    background: #f6f8fa;
    border-left: 3px solid #d0d7de;
    border-radius: 0 4px 4px 0;
    color: #555;
    font-size: 13px;
    line-height: 1.5;
}

/* графики */
/* На широком экране две карточки рядом, пропорции 1:2 —
   «Организации-поверители» занимают 1/3, «Типы СИ» 2/3 ширины.
   Сетка тянется на всю ширину контейнера (контейнер с .container-wide
   уже занимает весь экран с фиксированными отступами 24px). */
.charts-grid {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 16px;
    margin: 16px 0 24px;
}
.chart-card { background: #fff; padding: 0; border-radius: 8px; border: 1px solid #e1e4e8; min-width: 0; overflow: hidden; display: flex; flex-direction: column; }
/* Заголовок чарта — слегка серый фон, чтобы отделить от строк-полос. */
.chart-card h3 {
    margin: 0;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    background: #f6f8fa;
    border-bottom: 1px solid #e1e4e8;
    color: #24292f;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.chart-card h3 small { font-weight: normal; color: #6e7681; font-size: 11px; }
.chart-card-title { flex: 1; min-width: 0; }
/* Чекбокс «по выбранной организации» в заголовке Типы СИ — обычная Material-плашка. */
.chart-card-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: normal;
    color: #5f6368;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.chart-card-toggle input[type=checkbox] {
    width: 14px;
    height: 14px;
    accent-color: #1a73e8;
    cursor: pointer;
}

/* hbar-row-clickable: курсор и активное состояние для строк, по которым
   можно нажать (организации в drill-down). Подсветка hover уже задана для
   всех .hbar-row выше. */
.hbar-row-clickable { cursor: pointer; }
/* hbar-row-selected: выделение выбранной для drill-down строки.
   Тонкий синий бордер слева + чуть более насыщенный фон. */
.hbar-row-selected {
    background: #e8f0fe !important; /* перебиваем зебру */
    box-shadow: inset 3px 0 0 #1a73e8;
}

/* Карточка во время AJAX-перезагрузки: приглушается + показывается спиннер.
   Используем псевдоэлементы — не нужно вмешиваться в DOM при reload. */
.chart-card-loading { position: relative; pointer-events: none; }
.chart-card-loading::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.6);
    z-index: 1;
}
.chart-card-loading::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 36px;
    height: 36px;
    margin: -18px 0 0 -18px;
    border: 3px solid #e1e4e8;
    border-top-color: #1a73e8;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    z-index: 2;
}
.chart-empty { color: #888; font-size: 13px; padding: 14px; margin: 0; }
.chart-note { font-size: 12px; color: #555; background: #fef3c7; border-left: 3px solid #fbbf24; padding: 8px 10px; border-radius: 4px; margin: 0 14px 12px; }
.chart-note code { background: #fff; padding: 1px 4px; border-radius: 3px; }

/* горизонтальная гистограмма */
.hbar-chart { display: flex; flex-direction: column; gap: 0; padding: 4px 0; }
/* hbar-row: лейбл колонка увеличена (220px → 420px max), чтобы длинные названия
   типов СИ и организаций умещались целиком без обрезки многоточием. На узких
   экранах сжимается до 200px. Уплотнили вертикально: padding 4px вместо gap 6px,
   зебра-фон для чтения длинных списков. */
.hbar-row {
    display: grid;
    grid-template-columns: minmax(200px, 420px) 1fr 70px;
    gap: 12px;
    align-items: center;
    font-size: 12px;
    padding: 4px 14px;
}
.hbar-row:nth-child(even) { background: #fafbfc; }
.hbar-row:hover { background: #f1f7ff; }
.hbar-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #444; }
.hbar-track { background: #f1f3f5; height: 16px; border-radius: 4px; overflow: hidden; }
.hbar-fill { background: #1a73e8; height: 100%; border-radius: 4px; transition: width .3s; }

/* hbar-row-stack: вариант полосы для «Типы СИ» — две полосы друг над другом
   в одной ячейке (грид-колонка track), без фоновой подложки. Сверху первичные
   (оранжевая), снизу всего (синяя). Обе шкалы относительно общего максимума. */
.hbar-row-stack { align-items: center; }
.hbar-track-stack {
    /* width:100% обязателен — без него flex-контейнер схлопывается по содержимому,
       и дочерние полосы со «width: X%» вычисляются от нуля → невидимы. Грид-родитель
       (.hbar-row, 1fr колонка) ширину контейнеру явно не передаёт. */
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 3px;
    background: transparent;
    height: auto;
    overflow: visible;
}
.hbar-track-stack .hbar-fill-primary,
.hbar-track-stack .hbar-fill-total {
    height: 7px;
    border-radius: 3px;
    transition: width .3s;
    /* min-width 1px — чтобы абсолютно нулевые значения тоже оставляли
       видимый «след», не теряясь в потоке. */
    min-width: 0;
}
.hbar-track-stack .hbar-fill-primary { background: #f59e0b; }
.hbar-track-stack .hbar-fill-total   { background: #1a73e8; }
.hbar-count { text-align: right; font-weight: 600; color: #111; }
.hbar-primary { font-weight: 600; color: #f59e0b; font-size: 11px; }

/* плашка-пояснение под графиками */
.chart-note-bottom {
    background: #f8f9fa;
    border: 1px solid #e1e4e8;
    color: #555;
    padding: 10px 14px;
    border-radius: 6px;
    font-size: 12px;
    margin-top: 12px;
}
.chart-note-bottom code { background: #fff; padding: 1px 4px; border-radius: 3px; }

/* таблица поверок */
/* Таблица поверок: ограничена по высоте, скроллится сама внутри.
   Это нужно чтобы пагинация и кнопка экспорта всегда были видны внизу
   экрана независимо от объёма данных. Под широким экраном считаем высоту
   от viewport минус пространство шапки + фильтров + пагинации (~310px).
   min-height: 300px — на маленьких окнах оставляем минимум видимости. */
.tab-pane-active[data-tab-pane="table"] .table-wrap {
    height: calc(100vh - 310px);
    min-height: 300px;
    overflow: auto;
}
.table-wrap { overflow-x: auto; margin: 12px 0; }
/* Заголовок таблицы прилипает к верху прокручиваемой области, чтобы названия
   колонок не уезжали при вертикальном скролле. */
.verifications-table thead th {
    position: sticky;
    top: 0;
    background: #f6f8fa;
    z-index: 1;
}
.verifications-table { font-size: 12px; }
.verifications-table th, .verifications-table td { padding: 6px 8px; }
.verifications-table .nowrap { white-space: nowrap; }
.sort-link { text-decoration: none; color: inherit; display: inline-block; }
.sort-link:hover { color: #1a73e8; }
.sort-link.sort-current { color: #1a73e8; }

/* пагинация */
.pager { display: flex; gap: 12px; align-items: center; margin: 16px 0; flex-wrap: wrap; }
/* Кнопка экспорта — справа от пагинации (margin-left:auto), цвет «зелёный Excel». */
.btn-export {
    margin-left: auto;
    background: #1f7a44;
    color: #fff;
    border-color: #1f7a44;
}
.btn-export:hover { background: #176837; }
/* Состояние во время экспорта: кнопка становится «Отмена», цвет красный. */
.btn-export-cancel,
.btn-export.btn-export-cancel {
    background: #d93025;
    border-color: #d93025;
}
.btn-export-cancel:hover,
.btn-export.btn-export-cancel:hover { background: #b8261d; }

/* Модалка экспорта (полупрозрачный фон + карточка по центру). */
.export-modal {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
}
.export-modal[hidden] { display: none; }
.export-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(2px);
}
.export-modal-card {
    position: relative;
    z-index: 1;
    background: #fff;
    border-radius: 10px;
    padding: 32px 36px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    min-width: 320px;
    max-width: 480px;
    text-align: center;
}
.export-modal-title { font-size: 16px; font-weight: 600; color: #111; }
.export-modal-status { font-size: 13px; color: #555; min-height: 18px; }

/* Режим «ошибка»: прячем спиннер, заголовок краснеет, текст ошибки крупнее. */
.export-modal-error .loading-spinner { display: none; }
.export-modal-error .export-modal-title { color: #d93025; }
.export-modal-error .export-modal-title::before { content: '⚠ '; }
.export-modal-error .export-modal-status { color: #333; font-size: 14px; white-space: pre-wrap; }

/* --- горизонтальные вкладки в стиле Google Play (Material) --- */
.tabs-layout {
    /* Без боковой колонки: контент во всю ширину контейнера. */
    margin-top: 16px;
    display: block;
}

/* Полоска навигации с тонкой нижней линией — фон отделяющей полосы между табами и контентом. */
.tabs-nav {
    position: relative;
    display: flex;
    gap: 0;
    border-bottom: 1px solid #e1e4e8;
    background: transparent;
    /* На мобильных, если кнопок станет много, можно горизонтально проскроллить. */
    overflow-x: auto;
    overflow-y: hidden;
    /* Прячем нативный скроллбар, но скролл работает. */
    scrollbar-width: none;
}
.tabs-nav::-webkit-scrollbar { display: none; }

.tab-btn {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 12px 24px;
    /* Шрифт чуть крупнее обычной кнопки, без жирности — как у Play Store. */
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.25px;
    text-transform: none;
    color: #5f6368; /* серый Material */
    cursor: pointer;
    white-space: nowrap;
    transition: color .15s ease;
    /* В тонком плоском стиле никаких теней, фонов, рамок. */
}
.tab-btn:hover {
    background: rgba(26, 115, 232, 0.04); /* лёгкая синяя подсветка ховера */
    color: #1a73e8;
}
.tab-btn.tab-active {
    color: #1a73e8;
    background: transparent;
}

/* Плавающий индикатор — единственная подсвеченная линия. JS двигает её
   через transform + width, переходы делают «скольжение» между вкладками. */
.tab-indicator {
    position: absolute;
    bottom: -1px; /* перекрываем border-bottom родителя на 1px */
    left: 0;
    height: 3px;
    width: 0;
    background: #1a73e8;
    border-radius: 3px 3px 0 0;
    transform: translateX(0);
    transition: transform .25s cubic-bezier(.4, 0, .2, 1), width .25s cubic-bezier(.4, 0, .2, 1);
    pointer-events: none;
}

.tabs-body { padding-top: 16px; }
.tab-pane { display: none; }
.tab-pane-active { display: block; }

/* Плейсхолдер «загружаются графики» — крупный спиннер по центру. */
.charts-placeholder {
    background: #fff;
    border: 1px solid #e1e4e8;
    border-radius: 8px;
    padding: 40px 16px;
    text-align: center;
    color: #555;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.loading-spinner-inline {
    width: 36px;
    height: 36px;
    border: 3px solid #e1e4e8;
    border-top-color: #1a73e8;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

@media (max-width: 768px) {
    .tab-btn { padding: 10px 16px; }
}

/* --- /вкладки --- */

/* Высота сетки графиков — на оставшееся вертикальное пространство.
   100vh минус приблизительная высота шапки + фильтров + вкладок + отступы.
   Минимум 400px на случай очень короткого окна. */
.tab-pane-active[data-tab-pane="charts"] .charts-grid {
    height: calc(100vh - 400px);
    min-height: 400px;
    align-items: start; /* дочерние не растягиваются на всю высоту сетки */
}

/* «Организации-поверители» (первая карточка в сетке) — занимает всю
   высоту сетки. Это даёт «опорную высоту», под которую подстраивается соседняя.
   :first-child безопасен, потому что в JS «Организации» всегда рендерятся
   первой, «Типы СИ» — второй. */
.charts-grid > .chart-card:first-child {
    align-self: stretch;
    /* high — заполняет всё, скролл уже задан ниже */
}

/* «Типы СИ» — высота по содержимому, но не больше высоты сетки
   (= высоты «Организаций»). Если данных мало, карточка короткая;
   если много, упирается в max-height и скроллится внутри. */
.charts-grid > .chart-card:nth-child(2) {
    align-self: start;
    max-height: 100%;
}

/* Прокручиваемая внутренность карточки занимает всю оставшуюся высоту
   карточки. */
.chart-card-scroll .hbar-chart-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}
/* мягкий скроллбар */
.hbar-chart-scroll::-webkit-scrollbar { width: 8px; }
.hbar-chart-scroll::-webkit-scrollbar-thumb { background: #d0d7de; border-radius: 4px; }
.hbar-chart-scroll::-webkit-scrollbar-thumb:hover { background: #afb8c1; }

/* loading overlay — показывается при тяжёлых переходах */
.loading-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, 0.75);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    z-index: 9999;
    backdrop-filter: blur(2px);
}
.loading-overlay[hidden] { display: none; }
.loading-spinner {
    width: 48px;
    height: 48px;
    border: 4px solid #e1e4e8;
    border-top-color: #1a73e8;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}
.loading-text { font-size: 15px; color: #111; font-weight: 600; }
.loading-hint { font-size: 12px; color: #555; max-width: 320px; text-align: center; }
@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Узкий экран (< 1024px): «Типы СИ» уходят под «Организации-поверители».
   Высоту тоже отменяем — две карточки в стопку не должны делить один экран. */
@media (max-width: 1024px) {
    .charts-grid { grid-template-columns: 1fr; }
    .tab-pane-active[data-tab-pane="charts"] .charts-grid {
        height: auto;
        min-height: 0;
    }
    .chart-card-scroll .hbar-chart-scroll {
        max-height: 480px; /* возвращаем разумный max в режиме стека */
        flex: none;
    }
    /* Таблица тоже отказывается от fixed-height на узком экране:
       пусть страница скроллится целиком, это естественнее для телефонов. */
    .tab-pane-active[data-tab-pane="table"] .table-wrap {
        height: auto;
        min-height: 0;
    }
}
@media (max-width: 768px) {
    .filter-grid { grid-template-columns: 1fr 1fr; }
}

/* --- mi_types page + selected types import (итерация 2) --- */
.checkbox-wrap { display: inline-flex; align-items: center; cursor: pointer; }
.checkbox-wrap input[type=checkbox] { width: 18px; height: 18px; cursor: pointer; }
.muted { color: #888; }

.progress-bar-secondary { margin-top: 10px; }
.progress-current-type { font-size: 14px; margin: 8px 0 4px; color: #444; }

.typelog { margin-top: 16px; }
.typelog summary { cursor: pointer; padding: 8px 0; font-weight: 500; }
.typelog table { margin-top: 8px; font-size: 13px; }
.status-success { background: #2e7d32; color: #fff; padding: 2px 8px; border-radius: 4px; }
.status-error   { background: #c62828; color: #fff; padding: 2px 8px; border-radius: 4px; }
.status-no_data { background: #757575; color: #fff; padding: 2px 8px; border-radius: 4px; }
.status-skipped { background: #ed6c02; color: #fff; padding: 2px 8px; border-radius: 4px; }
