/* ==========================================================================
   base.css — каркас фронтенд-модернизации agroday.ru (шаг 2 плана).

   Назначение: проектный level базы — дизайн-токены, базовые типографика и
   ссылки, утилиты, сетка, карточки, таблицы, шимы совместимости (alert /
   nav-tabs / list-group / accordion / spinner), uv-формы, GoToTop, иконки,
   футер. Подключается в base.html ПЕРЕД fragments.css.

   Портировано из static/css/base.css uvelir.info (3463 строк): Design System,
   typography/display/spacing-утилиты, uv-grid, shims, uv-form, GoToTop,
   uv-footer, uv-card, uv-table; uv-ic-* и uv-soc-* — из fragments.css
   эталона (~735). Палитра переведена с ювелирного синего на зелёный бренд
   agroday: синие литералы эталона заменены на var(--uv-primary*) /
   rgba(var(--uv-primary-rgb), …).

   НЕ вошло (придёт со своими страницами позже): CKEditor-контент, article
   detail, комментарии, sidebar, push-toggle, action bar, video feed,
   карточка-досье, легаси-табы, ticker/quotes, модалки и тултипы.

   Шрифты Jost + Exo 2 self-hosted (static/fonts/{jost,exo2}/): body ссылается
   на 'Jost','Jost Fallback' с весом 420 (см. комментарий у body).

   2026-09-17
   ========================================================================== */

/* Design System
   Общие CSS-переменные всех страниц. Состав = объединение: всё, что уже
   живёт в :root fragments.css agroday, плюс --uv-primary-soft (декор).
   Формат: значение + короткий мотив в комментарии.
   ========================================================================== */

:root {
    /* ── Бренд ──
       forest — бренд agroday, 7.13:1 на белом (WCAG AAA для текста). */
    --uv-primary: #166534;
    /* Компоненты цвета для rgba(): hex в rgba() подставить нельзя,
       а прозрачный бренд-цвет нужен полутора сотням правил. */
    --uv-primary-rgb: 22, 101, 52;
    --uv-primary-dark: #14532D;    /* 9.1:1 на белом — текст и hover заливки */
    --uv-primary-hover: #0F3D22;   /* глубокий hover, текст на primary-плашках */
    /* Светлый тон бренда — ТОЛЬКО декор: градиенты и подсветки, не текст
       (2.0:1 на белом). Пара к тёмному --uv-dark в футере и героях. */
    --uv-primary-soft: #74C69D;

    --uv-dark: #16241C;            /* тёмная подложка: футер, тултипы; зелёный подтон бренда */
    --uv-dark-soft: #24352B;       /* приподнятая тёмная поверхность поверх --uv-dark */

    /* ── Текст ── */
    --uv-text: #2c2c2c;            /* базовый текст форм и таблиц */
    --uv-text-dark: #1a1a1a;       /* заголовки, акцентный текст */
    --uv-text-secondary: #555;     /* вторичный текст, card-text */
    --uv-text-muted: #6C757D;      /* подписи, мета */
    --uv-text-hint: #adb5bd;       /* плейсхолдеры и даты */

    /* Белый разведён по ролям: поверхность и текст поверх бренд-подложки —
       разные вещи, которые расходятся при первой же смене темы. */
    --uv-surface: #fff;
    --uv-text-inverse: #fff;
    --uv-bg-warm: #f8f9fa;
    --uv-border: #dee2e6;
    --uv-border-light: #e9ecef;

    /* ── Semantic status colors ──
       Пара «цвет + тёмный»: сам цвет красит заливку, рамку и значок, тёмный —
       текст поверх собственной полупрозрачной подложки. На плашке с заливкой
       .08–.12 базовый оттенок даёт ниже порога WCAG AA (4.5).
       success разведён с брендом (teal против forest): иначе «зелёный статус»
       и «зелёная кнопка» перестают различаться. */
    --uv-success: #0F766E;         /* teal-700, 5.5:1 на белом */
    --uv-success-rgb: 15, 118, 110;
    --uv-success-dark: #134E4A;    /* текст поверх полупрозрачного success, ≥5:1 */
    --uv-danger: #dc3545;
    --uv-danger-rgb: 220, 53, 69;
    --uv-danger-dark: #be2130;
    --uv-warning: #d68910;
    --uv-warning-rgb: 214, 137, 16;
    --uv-warning-dark: #8d5a0b;

    /* ── Тени ──
       Нейтральные — высота над плоскостью. */
    --uv-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06);
    --uv-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.1);
    --uv-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.14);

    /* Брендовое свечение — подсветка активного и наведённого */
    --uv-shadow-primary-sm: 0 2px 8px rgba(var(--uv-primary-rgb), .12);
    --uv-shadow-primary: 0 3px 12px rgba(var(--uv-primary-rgb), .25);
    --uv-shadow-primary-lg: 0 4px 16px rgba(var(--uv-primary-rgb), .35);

    /* Кольцо фокуса — одно на весь проект, иначе подсветка ввода разъезжается */
    --uv-shadow-focus: 0 0 0 3px rgba(var(--uv-primary-rgb), .15);
    --uv-shadow-focus-danger: 0 0 0 3px rgba(var(--uv-danger-rgb), .25);

    /* ── Radius scale ──
       pill намеренно 999px, а не половина высоты: браузер обрезает радиус
       до половины меньшей стороны, поэтому одно значение даёт стадион на
       элементе любого размера. */
    --uv-radius-xs: 4px;
    --uv-radius-sm: 6px;
    --uv-radius-md: 8px;
    --uv-radius-lg: 10px;
    --uv-radius-xl: 12px;
    --uv-radius-2xl: 16px;
    --uv-radius-3xl: 20px;
    --uv-radius-pill: 999px;
    --uv-radius-circle: 50%;

    /* ── Motion ──
       Длительность и кривая разведены: свойство в transition своё у каждого
       правила, а составной токен это не выражал и его обходили. */
    --uv-duration-fast: .15s;
    --uv-duration-base: .2s;
    --uv-duration-slow: .3s;
    --uv-duration-slower: .5s;
    --uv-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
    --uv-ease-out: cubic-bezier(.22, 1, .36, 1);

    /* Анимации отдельной шкалой: у @keyframes другой масштаб времени —
       появление карточки и бесконечный шиммер не ложатся на одну ступень. */
    --uv-anim-fast: .3s;
    --uv-anim-base: .4s;
    --uv-anim-slow: .5s;
    --uv-anim-loop-fast: .75s;
    --uv-anim-loop: 2s;
    --uv-anim-loop-slow: 4s;

    /* ── Typography scale ── */
    --uv-fs-h1: 2rem;
    --uv-fs-h2: 1.5rem;
    --uv-fs-h3: 1.25rem;
    --uv-fs-h4: 1.1rem;
    --uv-fs-h5: 1rem;
    --uv-fs-body: 1rem;
    --uv-fs-small: .875rem;
    --uv-fs-xs: .78rem;
    --uv-fs-micro: .7rem;
    --uv-fs-h1-mobile: 1.65rem;
    --uv-fs-h2-mobile: 1.25rem;

    --uv-fs-display: 2.5rem;       /* крупные заголовки и счётчики футера */

    /* Расширенная текстовая палитра */
    --uv-text-body: #3d4852;
    --uv-text-dim: #606f7b;
    --uv-text-soft: #8795a1;
    --uv-text-light: #b8c2cc;
    --uv-text-black: #111;

    /* ── Font weight scale ── */
    --uv-fw-thin: 200;
    --uv-fw-light: 300;
    --uv-fw-normal: 400;
    --uv-fw-medium: 500;
    --uv-fw-semibold: 600;
    --uv-fw-bold: 700;

    /* ── Line heights ── */
    --uv-lh-none: 1;         /* заголовки в одну строку, счётчики, иконки */
    --uv-lh-compact: 1.25;   /* body global — UI, навигация, карточки */
    --uv-lh-base: 1.5;       /* параграфы в интерфейсе */
    --uv-lh-content: 1.7;    /* длинные тексты: статьи, законодательство */

    /* ── Spacing scale (совпадает со шкалой Bootstrap 5 для миграции 1:1) ── */
    --uv-space-1: .25rem;    /* 4px */
    --uv-space-2: .5rem;     /* 8px */
    --uv-space-3: 1rem;      /* 16px */
    --uv-space-4: 1.5rem;    /* 24px */
    --uv-space-5: 3rem;      /* 48px */

    /* Дефолтный gap сетки uv-grid. Переопределяется классами .uv-grid-gap-*
       или инлайн style="--uv-grid-gap: 2rem" на конкретной сетке. */
    --uv-grid-gap: var(--uv-space-3);

    /* ── Шкала брейкпоинтов ──
       Четыре точки, других быть не должно. Читаются из JS
       (getComputedStyle(document.documentElement).getPropertyValue('--uv-bp-lg')),
       чтобы скрипты и вёрстка переключались на одной ширине.

       ВНИМАНИЕ: в media-условиях эти переменные использовать НЕЛЬЗЯ — var()
       там не работает. Поэтому в медиа-запросах стоят те же значения
       литералами, а их соответствие шкале держит гейт тестов.

       Диапазоны не должны пересекаться: min-width берёт точку шкалы,
       max-width — точку минус 0.02px (иначе на границе срабатывают оба). */
    --uv-bp-sm: 576px;
    --uv-bp-md: 768px;
    --uv-bp-lg: 992px;
    --uv-bp-xl: 1200px;

    /* ── Слои ──
       Числа 1000+ достались от Bootstrap: сам фреймворк удалён, а его
       раскладка осталась в разметке. Ниже 100 — локальный порядок внутри
       компонента, шкала туда не лезет. */
    --uv-z-content: 100;      /* над потоком страницы, под любым фиксированным UI */
    --uv-z-dropdown: 1000;
    --uv-z-sticky: 1020;      /* шапка */
    --uv-z-fixed: 1040;       /* плавающие кнопки, подложка мобильного меню */
    --uv-z-offcanvas: 1045;
    --uv-z-popover: 1050;     /* всплывает поверх фиксированного: cookie, поисковые списки */
    --uv-z-modal: 1055;
    --uv-z-overlay: 1080;     /* командная палитра — поверх всего */
}

/* Наследие bootstrap-reboot (тема демонтирована 2026-09-24): дизайн-система
   рассчитана на border-box. Универсальное правило ушло вместе с темой, и весь
   сайт съехал в content-box: padding прилипал к заданным ширинам, а вложенные
   .row каскадом добавляли отрицательные маргины — до +67px горизонтального
   overflow на мобильном. */
*, *::before, *::after {
    box-sizing: border-box;
}

/* ── Базовые стили: body, ссылки, медиа ──
   Адаптация эталона под Jost и зелёный бренд.
   420: переменный шрифт позволяет дробные веса; Jost 400 зрительно тоньше
   прежнего тела, 420 возвращает плотность, не выглядя полужирным. */
body {
    font-family: 'Jost', 'Jost Fallback', sans-serif;
    font-weight: 420;
    line-height: var(--uv-lh-compact);
    color: var(--uv-text-dark);
    font-size: var(--uv-fs-body);
}

/* h1-h6 наследуют шрифт от body (Jost). Правило появлялось как перекрытие
   canvas h1-h6{futura-pt}; тема удалена 2026-09-24 — остаётся страховкой,
   чтобы любой будущий внешнинный css не уводил заголовки мимо дизайн-системы. */
h1, h2, h3, h4, h5, h6 { font-family: inherit; }

a {
    text-decoration: underline;
    color: var(--uv-primary);
    transition: color var(--uv-duration-base);
}

a:hover {
    color: var(--uv-primary-hover);
}

img {
    max-width: 100%;
    height: auto;
}

iframe {
    border: 0 !important;
}

/* ── Typography Utilities ──
   Размеры и веса шрифта (замена легаси .text-0..9 / .font-weight-*)
   ========================================================================== */
.uv-text-xs      { font-size: var(--uv-fs-xs) !important; }
.uv-text-sm      { font-size: var(--uv-fs-small) !important; }
.uv-text-base    { font-size: var(--uv-fs-body) !important; }
.uv-text-lg      { font-size: var(--uv-fs-h4) !important; }
.uv-text-xl      { font-size: var(--uv-fs-h2) !important; }
.uv-text-2xl     { font-size: var(--uv-fs-h1) !important; }
.uv-text-3xl     { font-size: var(--uv-fs-display) !important; }

/* Font weight classes */
.uv-fw-thin      { font-weight: var(--uv-fw-thin) !important; }
.uv-fw-light     { font-weight: var(--uv-fw-light) !important; }
.uv-fw-normal    { font-weight: var(--uv-fw-normal) !important; }
.uv-fw-medium    { font-weight: var(--uv-fw-medium) !important; }
.uv-fw-semibold  { font-weight: var(--uv-fw-semibold) !important; }
.uv-fw-bold      { font-weight: var(--uv-fw-bold) !important; }

/* Font style */
.uv-italic       { font-style: italic !important; }

/* Text transform */
.uv-text-uppercase   { text-transform: uppercase !important; }
.uv-text-lowercase   { text-transform: lowercase !important; }
.uv-text-capitalize  { text-transform: capitalize !important; }
.uv-text-normal-case { text-transform: none !important; }

/* Text decoration */
.uv-text-decoration-none { text-decoration: none !important; }
.uv-text-truncate {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
}

/* Lead paragraph (замена Bootstrap .lead) */
.uv-lead {
    font-size: var(--uv-fs-h3);
    font-weight: var(--uv-fw-normal);
    line-height: var(--uv-lh-content);
}

/* Текстовая ссылка (акцентный цвет, подчёркивание по hover) */
.uv-link {
    color: var(--uv-primary);
    text-decoration: none;
    transition: color var(--uv-duration-base);
}
.uv-link:hover { color: var(--uv-primary-dark); text-decoration: underline; }

/* ── Text Color Utilities ──
   Семантические цвета текста (замена легаси .text-grey-* / .text-black)
   ========================================================================== */
.uv-color-body   { color: var(--uv-text-body) !important; }
.uv-color-dim    { color: var(--uv-text-dim) !important; }
.uv-color-soft   { color: var(--uv-text-soft) !important; }
.uv-color-light  { color: var(--uv-text-light) !important; }
.uv-color-black  { color: var(--uv-text-black) !important; }
.uv-text-muted   { color: var(--uv-text-muted) !important; }
.uv-text-dark    { color: var(--uv-text-dark) !important; }
.uv-text-primary { color: var(--uv-primary) !important; }
.uv-text-danger  { color: var(--uv-danger)     !important; }
.uv-text-success { color: var(--uv-success)    !important; }
.uv-text-warning { color: var(--uv-warning)    !important; }
.uv-text-light   { color: var(--uv-text-light) !important; }
.uv-text-white   { color: var(--uv-text-inverse) !important; }
.uv-text-body    { color: var(--uv-text-body)  !important; }

/* Выравнивание текста по ширине.
   Используется CKEditor 5 alignment plugin и paste-handler: на paste-in весь
   контент получает class="uv-text-justify" на блоках <p>.
   inter-word улучшает кириллицу (без него куски слов плывут);
   hyphens:auto работает в Chrome/Edge при <html lang="ru">. */
.uv-text-justify {
    text-align: justify;
    text-justify: inter-word;
    hyphens: auto;
}

/* ── Display & Flex Utilities ──
   ========================================================================== */

/* — Display — */
.uv-d-none          { display: none !important; }
.uv-d-block         { display: block !important; }
.uv-d-inline        { display: inline !important; }
.uv-d-inline-block  { display: inline-block !important; }
.uv-d-flex          { display: flex !important; }
.uv-d-inline-flex   { display: inline-flex !important; }
.uv-d-grid          { display: grid !important; }

/* — Flex direction — */
.uv-flex-row         { flex-direction: row !important; }
.uv-flex-column      { flex-direction: column !important; }
.uv-flex-row-reverse { flex-direction: row-reverse !important; }

/* — Flex wrap — */
.uv-flex-wrap   { flex-wrap: wrap !important; }
.uv-flex-nowrap { flex-wrap: nowrap !important; }

/* — Justify content — */
.uv-justify-start   { justify-content: flex-start !important; }
.uv-justify-center  { justify-content: center !important; }
.uv-justify-end     { justify-content: flex-end !important; }
.uv-justify-between { justify-content: space-between !important; }
.uv-justify-around  { justify-content: space-around !important; }

/* — Align items — */
.uv-items-start    { align-items: flex-start !important; }
.uv-items-center   { align-items: center !important; }
.uv-align-items-center { align-items: center !important; }  /* длинный алиас uv-items-center */
.uv-items-end      { align-items: flex-end !important; }
.uv-items-stretch  { align-items: stretch !important; }
.uv-items-baseline { align-items: baseline !important; }

/* — Align self — */
.uv-self-start  { align-self: flex-start !important; }
.uv-self-center { align-self: center !important; }
.uv-self-end    { align-self: flex-end !important; }

/* — Flex grow/shrink — */
.uv-flex-1      { flex: 1 1 0% !important; }
.uv-flex-auto   { flex: 1 1 auto !important; }
.uv-flex-none   { flex: none !important; }
.uv-grow-0      { flex-grow: 0 !important; }
.uv-grow-1      { flex-grow: 1 !important; }
.uv-shrink-0    { flex-shrink: 0 !important; }

/* — Text alignment — */
.uv-text-start  { text-align: start !important; }
.uv-text-center { text-align: center !important; }
.uv-text-end    { text-align: end !important; }

/* — Misc layout — */
.uv-w-100       { width: 100% !important; }
.uv-w-75        { width: 75% !important; }
.uv-h-100       { height: 100% !important; }
.uv-h-auto      { height: auto !important; }
.uv-overflow-hidden  { overflow: hidden !important; }
.uv-overflow-auto    { overflow: auto !important; }
.uv-position-relative { position: relative !important; }
.uv-clearfix::after  { content: ""; display: table; clear: both; }

/* — Border radius — */
.uv-rounded        { border-radius: var(--uv-radius-sm) !important; }
.uv-rounded-sm     { border-radius: var(--uv-radius-xs) !important; }
.uv-rounded-lg     { border-radius: var(--uv-radius-xl) !important; }
.uv-rounded-circle { border-radius: var(--uv-radius-circle) !important; }
.uv-rounded-pill   { border-radius: var(--uv-radius-pill) !important; }
.uv-rounded-0      { border-radius: 0 !important; }

/* — Box shadow — */
.uv-shadow      { box-shadow: var(--uv-shadow-md) !important; }
.uv-shadow-sm   { box-shadow: var(--uv-shadow-sm) !important; }
.uv-shadow-lg   { box-shadow: var(--uv-shadow-lg) !important; }
.uv-shadow-none { box-shadow: none !important; }

/* — Background — */
.uv-bg-light { background-color: var(--uv-bg-warm) !important; }
.uv-bg-white { background-color: var(--uv-surface) !important; }
.uv-bg-primary      { background-color: var(--uv-primary) !important; }
.uv-bg-primary-soft { background-color: rgba(var(--uv-primary-rgb), .08) !important; }

/* — Text decoration / whitespace — */
.uv-no-underline  { text-decoration: none !important; }
.uv-text-nowrap   { white-space: nowrap !important; }

/* — Borders — */
.uv-border          { border: 1px solid var(--uv-border) !important; }
.uv-border-0        { border: 0 !important; }
.uv-border-top      { border-top: 1px solid var(--uv-border) !important; }
.uv-border-bottom   { border-bottom: 1px solid var(--uv-border) !important; }
.uv-border-top-0    { border-top: 0 !important; }
.uv-border-start-0  { border-left: 0 !important; }
.uv-border-end-0    { border-right: 0 !important; }
.uv-border-primary  { border-color: var(--uv-primary) !important; }
.uv-border-dark     { border-color: var(--uv-text-dark) !important; }
.uv-border-success  { border-color: var(--uv-success) !important; }

/* — Opacity — */
.uv-opacity-90 { opacity: .9 !important; }
.uv-opacity-75 { opacity: .75 !important; }
.uv-opacity-50 { opacity: .5 !important; }

/* — Position offsets — */
.uv-bottom-0 { bottom: 0 !important; }
.uv-top-0    { top: 0 !important; }
.uv-end-0    { right: 0 !important; }

/* — Divider (замена легаси .divider) — */
.uv-divider {
    border: 0;
    border-top: 1px solid var(--uv-border);
    margin: 1.5rem 0;
}
/* Divider с центральным элементом (иконкой): <div class="uv-divider-icon"><i></i></div> */
.uv-divider-icon {
    display: flex;
    align-items: center;
    text-align: center;
    color: var(--uv-text-muted);
    margin: 1.5rem 0;
}
.uv-divider-icon::before,
.uv-divider-icon::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--uv-border);
}
.uv-divider-icon > * { margin: 0 .75rem; }

/* — Misc utilities — */
.uv-cursor-pointer { cursor: pointer !important; }
.uv-list-unstyled  { list-style: none !important; padding-left: 0 !important; margin: 0 !important; }
.uv-lh-1           { line-height: var(--uv-lh-none) !important; }
.uv-lh-base        { line-height: var(--uv-lh-base) !important; }
.uv-w-auto         { width: auto !important; }
.uv-va-middle      { vertical-align: middle !important; }
.uv-align-middle   { vertical-align: middle !important; }
.uv-align-content-center { align-content: center !important; }
.uv-font-monospace { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important; }
/* Exo 2 для кодов и номеров: цифры в нём одной ширины, колонка не пляшет */
.uv-font-exo { font-family: 'Exo 2', 'Exo 2 Fallback', sans-serif; }

/* Короткий код в ячейке таблицы — ОКВЭД, ОКПО и подобное */
.uv-code-chip {
    background: var(--uv-bg-warm);
    padding: .15rem .4rem;
    border-radius: var(--uv-radius-xs);
    font-size: var(--uv-fs-xs);
}
.uv-hide-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.uv-hide-scrollbar::-webkit-scrollbar { display: none; }

/* — Aspect ratio (замена BS .ratio/.ratio-16x9) — */
.uv-ratio { position: relative; width: 100%; }
.uv-ratio::before { content: ""; display: block; padding-top: 56.25%; }
.uv-ratio > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.uv-ratio-16x9::before { padding-top: 56.25%; }
.uv-ratio-4x3::before  { padding-top: 75%; }
.uv-ratio-1x1::before  { padding-top: 100%; }

/* — Accessibility — */
.uv-visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* — Float — */
.uv-float-start { float: left  !important; }
.uv-float-end   { float: right !important; }

/* — Images — */
.uv-img-fluid { max-width: 100%; height: auto; display: block; }

/* ── Responsive Display: md (≥768px) ── */
@media (min-width: 768px) {
    .uv-d-md-none         { display: none !important; }
    .uv-d-md-block        { display: block !important; }
    .uv-d-md-flex         { display: flex !important; }
    .uv-d-md-inline-flex  { display: inline-flex !important; }
    .uv-d-md-grid         { display: grid !important; }
    .uv-flex-md-row       { flex-direction: row !important; }
    .uv-flex-md-column    { flex-direction: column !important; }
    .uv-text-md-start     { text-align: start !important; }
    .uv-text-md-center    { text-align: center !important; }
    .uv-items-md-center   { align-items: center !important; }
    .uv-pe-md-2           { padding-right: var(--uv-space-2) !important; }
    .uv-ps-md-2           { padding-left: var(--uv-space-2) !important; }
    .uv-float-md-start    { float: left !important; }
    .uv-float-md-end      { float: right !important; }
}

/* ── Responsive Display: lg (≥992px) ── */
@media (min-width: 992px) {
    .uv-d-lg-none         { display: none !important; }
    .uv-d-lg-block        { display: block !important; }
    .uv-d-lg-flex         { display: flex !important; }
    .uv-d-lg-inline-flex  { display: inline-flex !important; }
    .uv-flex-lg-row       { flex-direction: row !important; }
    .uv-text-lg-start     { text-align: start !important; }
    .uv-d-lg-table-cell   { display: table-cell !important; }
    .uv-float-lg-start    { float: left !important; }
}

/* ── Responsive Display: xl (≥1200px) ── */
@media (min-width: 1200px) {
    .uv-d-xl-none      { display: none !important; }
    .uv-d-xl-block     { display: block !important; }
    .uv-text-xl-start  { text-align: start !important; }
}

/* ── Spacing Utilities ──
   Значения совпадают со шкалой Bootstrap 5 для миграции 1:1 (mb-2 → uv-mb-2)
   ========================================================================== */

/* — Margin: all sides — */
.uv-m-0  { margin: 0 !important; }
.uv-m-1  { margin: var(--uv-space-1) !important; }
.uv-m-2  { margin: var(--uv-space-2) !important; }
.uv-m-3  { margin: var(--uv-space-3) !important; }
.uv-m-4  { margin: var(--uv-space-4) !important; }
.uv-m-5  { margin: var(--uv-space-5) !important; }
.uv-m-auto { margin: auto !important; }

/* — Margin: top — */
.uv-mt-0 { margin-top: 0 !important; }
.uv-mt-1 { margin-top: var(--uv-space-1) !important; }
.uv-mt-2 { margin-top: var(--uv-space-2) !important; }
.uv-mt-3 { margin-top: var(--uv-space-3) !important; }
.uv-mt-4 { margin-top: var(--uv-space-4) !important; }
.uv-mt-5 { margin-top: var(--uv-space-5) !important; }

/* — Margin: bottom — */
.uv-mb-0 { margin-bottom: 0 !important; }
.uv-mb-1 { margin-bottom: var(--uv-space-1) !important; }
.uv-mb-2 { margin-bottom: var(--uv-space-2) !important; }
.uv-mb-3 { margin-bottom: var(--uv-space-3) !important; }
.uv-mb-4 { margin-bottom: var(--uv-space-4) !important; }
.uv-mb-5 { margin-bottom: var(--uv-space-5) !important; }

/* — Margin: start (left in LTR) — */
.uv-ms-0 { margin-inline-start: 0 !important; }
.uv-ms-1 { margin-inline-start: var(--uv-space-1) !important; }
.uv-ms-2 { margin-inline-start: var(--uv-space-2) !important; }
.uv-ms-3 { margin-inline-start: var(--uv-space-3) !important; }
.uv-ms-4 { margin-inline-start: var(--uv-space-4) !important; }
.uv-ms-5 { margin-inline-start: var(--uv-space-5) !important; }
.uv-ms-auto { margin-inline-start: auto !important; }

/* — Margin: end (right in LTR) — */
.uv-me-0 { margin-inline-end: 0 !important; }
.uv-me-1 { margin-inline-end: var(--uv-space-1) !important; }
.uv-me-2 { margin-inline-end: var(--uv-space-2) !important; }
.uv-me-3 { margin-inline-end: var(--uv-space-3) !important; }
.uv-me-4 { margin-inline-end: var(--uv-space-4) !important; }
.uv-me-5 { margin-inline-end: var(--uv-space-5) !important; }
.uv-me-auto { margin-inline-end: auto !important; }

/* — Margin: horizontal (x) — */
.uv-mx-0 { margin-inline: 0 !important; }
.uv-mx-1 { margin-inline: var(--uv-space-1) !important; }
.uv-mx-2 { margin-inline: var(--uv-space-2) !important; }
.uv-mx-3 { margin-inline: var(--uv-space-3) !important; }
.uv-mx-4 { margin-inline: var(--uv-space-4) !important; }
.uv-mx-5 { margin-inline: var(--uv-space-5) !important; }
.uv-mx-auto { margin-inline: auto !important; }

/* — Margin: vertical (y) — */
.uv-my-0 { margin-block: 0 !important; }
.uv-my-1 { margin-block: var(--uv-space-1) !important; }
.uv-my-2 { margin-block: var(--uv-space-2) !important; }
.uv-my-3 { margin-block: var(--uv-space-3) !important; }
.uv-my-4 { margin-block: var(--uv-space-4) !important; }
.uv-my-5 { margin-block: var(--uv-space-5) !important; }
.uv-my-auto { margin-block: auto !important; }

/* — Padding: all sides — */
.uv-p-0  { padding: 0 !important; }
.uv-p-1  { padding: var(--uv-space-1) !important; }
.uv-p-2  { padding: var(--uv-space-2) !important; }
.uv-p-3  { padding: var(--uv-space-3) !important; }
.uv-p-4  { padding: var(--uv-space-4) !important; }
.uv-p-5  { padding: var(--uv-space-5) !important; }

/* — Padding: top — */
.uv-pt-0 { padding-top: 0 !important; }
.uv-pt-1 { padding-top: var(--uv-space-1) !important; }
.uv-pt-2 { padding-top: var(--uv-space-2) !important; }
.uv-pt-3 { padding-top: var(--uv-space-3) !important; }
.uv-pt-4 { padding-top: var(--uv-space-4) !important; }
.uv-pt-5 { padding-top: var(--uv-space-5) !important; }

/* — Padding: bottom — */
.uv-pb-0 { padding-bottom: 0 !important; }
.uv-pb-1 { padding-bottom: var(--uv-space-1) !important; }
.uv-pb-2 { padding-bottom: var(--uv-space-2) !important; }
.uv-pb-3 { padding-bottom: var(--uv-space-3) !important; }
.uv-pb-4 { padding-bottom: var(--uv-space-4) !important; }
.uv-pb-5 { padding-bottom: var(--uv-space-5) !important; }

/* — Padding: start — */
.uv-ps-0 { padding-inline-start: 0 !important; }
.uv-ps-1 { padding-inline-start: var(--uv-space-1) !important; }
.uv-ps-2 { padding-inline-start: var(--uv-space-2) !important; }
.uv-ps-3 { padding-inline-start: var(--uv-space-3) !important; }
.uv-ps-4 { padding-inline-start: var(--uv-space-4) !important; }
.uv-ps-5 { padding-inline-start: var(--uv-space-5) !important; }

/* — Padding: end — */
.uv-pe-0 { padding-inline-end: 0 !important; }
.uv-pe-1 { padding-inline-end: var(--uv-space-1) !important; }
.uv-pe-2 { padding-inline-end: var(--uv-space-2) !important; }
.uv-pe-3 { padding-inline-end: var(--uv-space-3) !important; }
.uv-pe-4 { padding-inline-end: var(--uv-space-4) !important; }
.uv-pe-5 { padding-inline-end: var(--uv-space-5) !important; }

/* — Padding: horizontal (x) — */
.uv-px-0 { padding-inline: 0 !important; }
.uv-px-1 { padding-inline: var(--uv-space-1) !important; }
.uv-px-2 { padding-inline: var(--uv-space-2) !important; }
.uv-px-3 { padding-inline: var(--uv-space-3) !important; }
.uv-px-4 { padding-inline: var(--uv-space-4) !important; }
.uv-px-5 { padding-inline: var(--uv-space-5) !important; }

/* — Padding: vertical (y) — */
.uv-py-0 { padding-block: 0 !important; }
.uv-py-1 { padding-block: var(--uv-space-1) !important; }
.uv-py-2 { padding-block: var(--uv-space-2) !important; }
.uv-py-3 { padding-block: var(--uv-space-3) !important; }
.uv-py-4 { padding-block: var(--uv-space-4) !important; }
.uv-py-5 { padding-block: var(--uv-space-5) !important; }

/* — Gap (flex/grid containers) — */
.uv-gap-0 { gap: 0 !important; }
.uv-gap-1 { gap: var(--uv-space-1) !important; }
.uv-gap-2 { gap: var(--uv-space-2) !important; }
.uv-gap-3 { gap: var(--uv-space-3) !important; }
.uv-gap-4 { gap: var(--uv-space-4) !important; }
.uv-gap-5 { gap: var(--uv-space-5) !important; }

/* ── Responsive Spacing: md (≥768px) ── */
@media (min-width: 768px) {
    .uv-mt-md-0 { margin-top: 0 !important; }
    .uv-mt-md-3 { margin-top: var(--uv-space-3) !important; }
    .uv-mt-md-4 { margin-top: var(--uv-space-4) !important; }
    .uv-mb-md-0 { margin-bottom: 0 !important; }
    .uv-mb-md-2 { margin-bottom: var(--uv-space-2) !important; }
    .uv-mb-md-3 { margin-bottom: var(--uv-space-3) !important; }
    .uv-mb-md-4 { margin-bottom: var(--uv-space-4) !important; }
    .uv-my-md-4 { margin-block: var(--uv-space-4) !important; }
    .uv-my-md-5 { margin-block: var(--uv-space-5) !important; }
    .uv-p-md-3  { padding: var(--uv-space-3) !important; }
    .uv-p-md-4  { padding: var(--uv-space-4) !important; }
    .uv-px-md-4 { padding-inline: var(--uv-space-4) !important; }
    .uv-py-md-3 { padding-block: var(--uv-space-3) !important; }
    .uv-py-md-4 { padding-block: var(--uv-space-4) !important; }
    .uv-gap-md-3 { gap: var(--uv-space-3) !important; }
}

/* ── Responsive Spacing: lg (≥992px) ── */
@media (min-width: 992px) {
    .uv-mt-lg-0 { margin-top: 0 !important; }
    .uv-mt-lg-4 { margin-top: var(--uv-space-4) !important; }
    .uv-mb-lg-0 { margin-bottom: 0 !important; }
    .uv-mb-lg-4 { margin-bottom: var(--uv-space-4) !important; }
    .uv-my-lg-5 { margin-block: var(--uv-space-5) !important; }
    .uv-p-lg-4  { padding: var(--uv-space-4) !important; }
    .uv-p-lg-5  { padding: var(--uv-space-5) !important; }
    .uv-px-lg-5 { padding-inline: var(--uv-space-5) !important; }
    .uv-gap-lg-4 { gap: var(--uv-space-4) !important; }
}

/* Clear + spacer (легаси Canvas-класс, 90+ вхождений в шаблонах agroday) */
.h10-clearfix { clear: both; height: 10px; }

/* ── Grid Layout System ──
   CSS Grid вместо BS5 row/col-*.
   Миграция: row + col-md-4 ×3 → uv-grid uv-grid-3

   Переопределение gap на месте:  style="--uv-grid-gap: 2rem"
   Ширина сайдбара на месте:      style="--uv-sidebar-w: 320px"
   ========================================================================== */

.uv-grid {
    display: grid;
    gap: var(--uv-grid-gap, var(--uv-space-3));
}

/* Без min-width: 0 grid items расширяются до min-content и переполняют трек */
.uv-grid > * {
    min-width: 0;
}

/* Gap modifiers */
.uv-grid-gap-0  { --uv-grid-gap: 0; }
.uv-grid-gap-sm { --uv-grid-gap: var(--uv-space-2); }
.uv-grid-gap-lg { --uv-grid-gap: var(--uv-space-4); }

/* Фиксированное число колонок.
   minmax(0, 1fr) вместо 1fr: items не переполняют контейнер при наличии
   длинного контента (1fr = minmax(auto, 1fr) — auto не сжимается ниже min-content). */
.uv-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.uv-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.uv-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Auto-fill: колонки оборачиваются сами.
   min(100%, Npx) защищает от выхода за ширину контейнера на малых экранах. */
.uv-grid-auto-sm { grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr)); }
.uv-grid-auto    { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
.uv-grid-auto-lg { grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }

/* Sidebar layouts.
   --sidebar:     main (1fr) | sidebar 280px — эквивалент col-md-9/col-md-3
   --sidebar-end: main (1fr) | sidebar 350px — эквивалент col-md-8/col-md-4
   minmax(0, 1fr) на main — предотвращает расширение главной колонки за трек */
.uv-grid-sidebar     { grid-template-columns: minmax(0, 1fr) 280px; }
.uv-grid-sidebar-end { grid-template-columns: minmax(0, 1fr) 350px; }

/* Media row: фиксированное фото слева (240px) + контент (1fr).
   Для list-строк с фото-превью. Сворачивается в 1 колонку на мобиле. */
.uv-grid-media { grid-template-columns: 240px minmax(0, 1fr); align-items: start; }

/* Sidebar column: содержимое не выходит за пределы колонки */
.uv-grid-sidebar     > :last-child,
.uv-grid-sidebar-end > :last-child { overflow: clip; }

/* Span helpers (для дочерних элементов) */
.uv-col-span-2   { grid-column: span 2 / span 2; }
.uv-col-span-3   { grid-column: span 3 / span 3; }
.uv-col-span-all { grid-column: 1 / -1; }

/* Align helpers */
.uv-grid-align-start   { align-items: start; }
.uv-grid-align-center  { align-items: center; }
.uv-grid-align-stretch { align-items: stretch; }

/* ── Responsive breakpoints ──
   xs  <576px    — 1 column everywhere
   sm  576–767px — --3/4 → 2col, sidebar → 1col
   md  768–991px — --4 → 3col
   lg+ 992px+    — full layout                   */

/* xs: <576px */
@media (max-width: 575.98px) {
    .uv-grid-2,
    .uv-grid-3,
    .uv-grid-4,
    .uv-grid-media,
    .uv-grid-sidebar,
    .uv-grid-sidebar-end { grid-template-columns: 1fr; }

    .uv-col-span-2,
    .uv-col-span-3 { grid-column: span 1; }
}

/* sm: 576px–767px */
@media (min-width: 576px) and (max-width: 767.98px) {
    .uv-grid-3,
    .uv-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    .uv-grid-sidebar,
    .uv-grid-sidebar-end { grid-template-columns: 1fr; }

    /* span-3 в 2-колоночной сетке = full width */
    .uv-col-span-3 { grid-column: 1 / -1; }
}

/* md: 768px–991px */
@media (min-width: 768px) and (max-width: 991.98px) {
    .uv-grid-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ── Card System ──
   Универсальные карточки нового кода. Миграция: card → uv-card,
   card-body → uv-card-body
   ========================================================================== */

.uv-card {
    background: var(--uv-surface);
    border: 1px solid var(--uv-border);
    border-radius: var(--uv-radius-sm);
    overflow: hidden;
}

.uv-card-header {
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--uv-border);
    font-size: var(--uv-fs-small);
    font-weight: var(--uv-fw-semibold);
    color: var(--uv-text-dark);
    background: var(--uv-bg-warm);
}

.uv-card-body {
    padding: 1rem;
}

.uv-card-footer {
    padding: .75rem 1rem;
    border-top: 1px solid var(--uv-border);
    background: var(--uv-bg-warm);
}

.uv-card-title {
    margin: 0 0 .5rem;
    font-size: var(--uv-fs-h4);
    font-weight: var(--uv-fw-semibold);
    color: var(--uv-dark);
}

.uv-card-text {
    margin: 0;
    font-size: var(--uv-fs-small);
    color: var(--uv-text-secondary);
    line-height: var(--uv-lh-base);
}

.uv-card-img {
    display: block;
    width: 100%;
    height: auto;
}

/* — Card modifiers — */
.uv-card-shadow   { box-shadow: var(--uv-shadow-sm); border-color: transparent; }
.uv-card-flat     { border-color: transparent; background: var(--uv-bg-warm); }
.uv-card-hover    { transition: all var(--uv-duration-slow) var(--uv-ease); }
.uv-card-hover:hover {
    box-shadow: var(--uv-shadow-md);
    border-color: transparent;
    transform: translateY(-2px);
}

.uv-card-compact .uv-card-header { padding: .5rem .75rem; }
.uv-card-compact .uv-card-body   { padding: .75rem; }
.uv-card-compact .uv-card-footer { padding: .5rem .75rem; }

.uv-card-horizontal {
    display: flex;
    align-items: stretch;
}
.uv-card-horizontal .uv-card-img {
    width: auto;
    max-width: 200px;
    object-fit: cover;
}
.uv-card-horizontal .uv-card-body {
    flex: 1;
}

/* ── Tables ──
   uv-table, uv-table-responsive, uv-table-striped,
   uv-table-bordered, uv-table-hover, uv-table-dark
   ========================================================================== */
.uv-table {
    width: 100%;
    margin-bottom: 1rem;
    color: var(--uv-text);
    vertical-align: top;
    border-color: var(--uv-border);
    border-collapse: collapse;
}
.uv-table > :not(caption) > * > * {
    padding: .5rem .75rem;
    background-color: transparent;
    border-bottom-width: 1px;
    border-bottom-color: var(--uv-border);
}
.uv-table > tbody { vertical-align: inherit; }
.uv-table > thead { vertical-align: bottom; }
.uv-table > thead > * > * {
    font-weight: var(--uv-fw-semibold);
    border-bottom: 2px solid var(--uv-border);
}

.uv-table-bordered > :not(caption) > * { border-width: 1px 0; }
.uv-table-bordered > :not(caption) > * > * {
    border-width: 0 1px;
    border-color: var(--uv-border);
}

.uv-table-striped > tbody > tr:nth-of-type(odd) > * {
    background-color: rgba(0, 0, 0, .03);
}

.uv-table-hover > tbody > tr:hover > * {
    background-color: rgba(0, 0, 0, .05);
}

.uv-table-dark {
    color: var(--uv-text-inverse);
    border-color: #4d5154;
}
.uv-table-dark > :not(caption) > * > * {
    border-bottom-color: #4d5154;
    background-color: #212529;
}

/* Красная шапка таблицы (замена легаси .thead-red) */
.uv-thead-danger th {
    background-color: var(--uv-danger);
    color: var(--uv-text-inverse);
    border-color: var(--uv-danger);
}

/* — Таблица внутри карточки —
   Приглушённая шапка на тёплом фоне и подсветка строки. `border-collapse:
   separate` обязателен: со `collapse` браузер не скругляет углы шапки. */
.uv-table-card {
    border-collapse: separate;
    border-spacing: 0;
    margin-bottom: 0;
    font-size: var(--uv-fs-small);
}
.uv-table-card thead th {
    background: var(--uv-bg-warm);
    /* Явно, а не наследованием от `.uv-table` (`vertical-align: top`): иначе
       заголовок, перенесённый на две строки, встаёт не по центру соседних. */
    vertical-align: middle;
    color: var(--uv-text-muted);
    font-weight: var(--uv-fw-semibold);
    font-size: var(--uv-fs-xs);
    text-transform: uppercase;
    letter-spacing: .05em;
    padding: .55rem .75rem;
    border-bottom: 1px solid var(--uv-border);
}
.uv-table-card thead th:first-child { border-radius: var(--uv-radius-md) 0 0 0; }
.uv-table-card thead th:last-child  { border-radius: 0 var(--uv-radius-md) 0 0; }
.uv-table-card tbody td {
    padding: .55rem .75rem;
    border-bottom: 1px solid rgba(0,0,0,.04);
    color: var(--uv-text);
    vertical-align: middle;
}
.uv-table-card tbody tr:last-child td { border-bottom: none; }
.uv-table-card tbody tr:hover td { background: rgba(var(--uv-primary-rgb), .02); }

.uv-table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* ============================================================
   Alert component shims
   Джанговские messages и легаси-шаблоны выводят бутстраповские
   классы .alert-* — держим контракт до перевода разметки на uv-alert.
   ============================================================ */
.alert {
    position: relative;
    padding: .75rem 1rem;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    border-radius: var(--uv-radius-xs);
    font-size: .9rem;
}
.alert-dismissible { padding-right: 3rem; }
.alert-dismissible .btn-close { position: absolute; top: 0; right: 0; padding: .75rem 1rem; }
.fade { transition: opacity var(--uv-duration-fast) linear; }
.fade.show { opacity: 1; }
.alert-info    { color: #055160; background-color: #cff4fc; border-color: #b6effb; }
.alert-success { color: #0a3622; background-color: #d1e7dd; border-color: #a3cfbb; }
.alert-warning { color: #664d03; background-color: #fff3cd; border-color: #ffda6a; }
.alert-danger  { color: #58151c; background-color: #f8d7da; border-color: #f1aeb5; }
/* Плашка бренд-цвета собрана из rgba(--uv-primary-rgb), а не из светлых
   синих литералов эталона: при смене палитры не остаётся сиротского голубого. */
.alert-primary { color: var(--uv-primary-hover); background-color: rgba(var(--uv-primary-rgb), .1); border-color: rgba(var(--uv-primary-rgb), .28); }

/* ============================================================
   Nav tabs shims
   ============================================================ */
.nav { display: flex; flex-wrap: wrap; padding-left: 0; margin-bottom: 0; list-style: none; }
.nav-link {
    display: block;
    padding: .5rem .75rem;
    color: var(--uv-primary);
    text-decoration: none;
    transition: color var(--uv-duration-fast);
}
.nav-link:hover { color: var(--uv-primary-dark); }
.nav-tabs {
    border-bottom: 1px solid var(--uv-border);
    gap: 0;
}
.nav-tabs .nav-item { margin-bottom: -1px; }
.nav-tabs .nav-link {
    border: 1px solid transparent;
    border-top-left-radius: var(--uv-radius-xs);
    border-top-right-radius: var(--uv-radius-xs);
    color: var(--uv-text-secondary);
}
.nav-tabs .nav-link:hover {
    border-color: var(--uv-border) var(--uv-border) transparent;
    color: var(--uv-primary);
}
.nav-tabs .nav-link.active {
    color: var(--uv-text);
    background-color: var(--uv-surface);
    border-color: var(--uv-border) var(--uv-border) var(--uv-surface);
    font-weight: var(--uv-fw-semibold);
}

/* ============================================================
   List group shims
   ============================================================ */
.list-group { display: flex; flex-direction: column; padding-left: 0; margin-bottom: 0; }
.list-group-item {
    position: relative;
    display: block;
    padding: .5rem 1rem;
    color: var(--uv-text);
    background-color: var(--uv-surface);
    border: 1px solid var(--uv-border);
}
.list-group-item + .list-group-item { border-top-width: 0; }
.list-group-flush .list-group-item { border-right: 0; border-left: 0; border-radius: 0; }
.list-group-flush .list-group-item:first-child { border-top: 0; }

/* ============================================================
   Accordion shims
   В agroday живёт легаси-разметка `.card-header.accordion-header` +
   `.collapse.show` (12+ шаблонов): правило `.collapse:not(.show)` —
   её контракт видимости, без него блоки не схлопываются. Правило
   `.accordion-collapse…` из эталона покрывается им же.
   ============================================================ */
.accordion-header { margin: 0; }
.accordion-button {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 1rem;
    font-size: .95rem;
    font-weight: var(--uv-fw-semibold);
    color: var(--uv-text);
    background-color: var(--uv-surface);
    border: 0;
    border-radius: 0;
    overflow-anchor: none;
    cursor: pointer;
    transition: color var(--uv-duration-fast), background-color var(--uv-duration-fast);
}
.accordion-button:not(.collapsed) {
    color: var(--uv-primary-dark);
    background-color: rgba(var(--uv-primary-rgb), .06);
}
.accordion-body { padding: 1rem; }
.collapse:not(.show) { display: none; }

/* ============================================================
   Spinner shim
   ============================================================ */
.spinner-border {
    display: inline-block;
    width: 2rem;
    height: 2rem;
    vertical-align: text-bottom;
    border: .25em solid currentColor;
    border-right-color: transparent;
    border-radius: var(--uv-radius-circle);
    animation: spin var(--uv-anim-loop-fast) linear infinite;
}
.spinner-border-sm { width: 1rem; height: 1rem; border-width: .2em; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================
   uv-* form components (вывод crispy; текущий pack — bootstrap5,
   компоненты готовят переход на uv-вывод)
   ============================================================ */

.uv-field { margin-bottom: 1rem; }

.uv-label {
    display: inline-block;
    margin-bottom: .35rem;
    font-weight: var(--uv-fw-medium);
    font-size: .9rem;
    color: var(--uv-text);
}
.uv-label-required .uv-label-asterisk,
.uv-label-asterisk { color: var(--uv-danger); margin-left: 2px; }

.uv-input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: .375rem .75rem;
    font-size: var(--uv-fs-body);
    font-family: inherit;
    line-height: var(--uv-lh-base);
    color: var(--uv-text);
    background-color: var(--uv-surface);
    border: 1px solid #ced4da;
    border-radius: var(--uv-radius-xs);
    transition: border-color var(--uv-duration-fast) ease-in-out, box-shadow var(--uv-duration-fast) ease-in-out;
    appearance: none;
}
.uv-input:focus {
    border-color: var(--uv-primary);
    outline: 0;
    box-shadow: var(--uv-shadow-focus);
}
.uv-input::placeholder { color: var(--uv-text-hint); opacity: 1; }
.uv-input:disabled { background-color: var(--uv-border-light); opacity: 1; }
.uv-input-invalid,
.uv-input--invalid { border-color: var(--uv-danger); }
.uv-input-invalid:focus,
.uv-input--invalid:focus { border-color: var(--uv-danger); box-shadow: var(--uv-shadow-focus-danger); }
textarea.uv-input { min-height: 80px; resize: vertical; }

.uv-select {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: .375rem 2.25rem .375rem .75rem;
    font-size: var(--uv-fs-body);
    font-family: inherit;
    line-height: var(--uv-lh-base);
    color: var(--uv-text);
    background-color: var(--uv-surface);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 16px 12px;
    border: 1px solid #ced4da;
    border-radius: var(--uv-radius-xs);
    appearance: none;
    transition: border-color var(--uv-duration-fast), box-shadow var(--uv-duration-fast);
}
.uv-select:focus {
    border-color: var(--uv-primary);
    outline: 0;
    box-shadow: var(--uv-shadow-focus);
}
.uv-select-invalid,
.uv-select--invalid { border-color: var(--uv-danger); }
.uv-select-invalid:focus,
.uv-select--invalid:focus { border-color: var(--uv-danger); box-shadow: var(--uv-shadow-focus-danger); }

.uv-check {
    display: block;
    min-height: 1.5rem;
    padding-left: 1.5em;
    margin-bottom: .125rem;
}
.uv-check-input {
    float: left;
    margin-left: -1.5em;
    width: 1em;
    height: 1em;
    margin-top: .25em;
    vertical-align: top;
    background-color: var(--uv-surface);
    border: 1px solid rgba(0,0,0,.25);
    border-radius: .25em;
    appearance: none;
    transition: background-color var(--uv-duration-fast), border-color var(--uv-duration-fast), box-shadow var(--uv-duration-fast);
}
.uv-check-input[type="radio"] { border-radius: var(--uv-radius-circle); }
.uv-check-input:checked {
    background-color: var(--uv-primary);
    border-color: var(--uv-primary);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
}
.uv-check-input[type="radio"]:checked {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e");
}
.uv-check-input-invalid,
.uv-check-input--invalid { border-color: var(--uv-danger); }
.uv-check-input:focus { box-shadow: var(--uv-shadow-focus); outline: 0; }
.uv-check-label { cursor: pointer; }

/* Группы чекбоксов/радио (uv/field.html, ветки is_checkboxselectmultiple
   и is_radioselect). Пак кладёт внутрь группы безымянный div виджета,
   внутри которого по div на вариант — flex-раскладку несёт именно он. */
.uv-check-group,
.uv-radio-group,
.uv-check-group > div,
.uv-radio-group > div {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

/* Файл-инпут (uv/field.html, ветка is_file) — в стиле uv-input */
.uv-file-input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: .375rem .75rem;
    font-size: var(--uv-fs-body);
    font-family: inherit;
    line-height: var(--uv-lh-base);
    color: var(--uv-text);
    background-color: var(--uv-surface);
    border: 1px dashed #ced4da;
    border-radius: var(--uv-radius-xs);
    cursor: pointer;
}
.uv-file-input:focus {
    border-color: var(--uv-primary);
    outline: 0;
    box-shadow: var(--uv-shadow-focus);
}

/* Обёртка non-field errors (uv/errors.html) — плашка в духе uv-alert-danger */
.uv-form-errors {
    margin-bottom: 1rem;
    padding: .75rem 1rem;
    font-size: var(--uv-fs-small);
    line-height: var(--uv-lh-base);
    color: var(--uv-danger-dark);
    background-color: rgba(var(--uv-danger-rgb), .08);
    border: 1px solid rgba(var(--uv-danger-rgb), .35);
    border-radius: var(--uv-radius-sm);
}
.uv-form-errors ul { padding: 0; list-style: none; }

.uv-field-hint {
    display: block;
    margin-top: .25rem;
    font-size: var(--uv-fs-small);
    color: var(--uv-text-muted);
}
.uv-field-error {
    display: block;
    margin-top: .25rem;
    font-size: var(--uv-fs-small);
    color: var(--uv-danger);
}

/* ── Input Group ── */
.uv-input-group {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    width: 100%;
}
.uv-input-group > .uv-input,
.uv-input-group > .uv-select {
    position: relative;
    flex: 1 1 auto;
    width: 1%;
    min-width: 0;
}
.uv-input-group > .uv-input:not(:first-child),
.uv-input-group > .uv-select:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.uv-input-group > .uv-input:not(:last-child),
.uv-input-group > .uv-select:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.uv-input-group-text {
    display: flex;
    align-items: center;
    padding: .375rem .75rem;
    font-size: var(--uv-fs-body);
    font-weight: var(--uv-fw-normal);
    line-height: var(--uv-lh-base);
    color: var(--uv-text);
    text-align: center;
    white-space: nowrap;
    background-color: var(--uv-bg-warm);
    border: 1px solid #ced4da;
    border-radius: var(--uv-radius-xs);
}
.uv-input-group > .uv-input-group-text:not(:last-child),
.uv-input-group > .uv-btn:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.uv-input-group > .uv-input-group-text:not(:first-child),
.uv-input-group > .uv-btn:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.uv-input-group > .uv-input-group-text + .uv-input,
.uv-input-group > .uv-input-group-text + .uv-select {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
/* merged borders — avoid double border between adjacent elements */
.uv-input-group > * + * { margin-left: -1px; }

.uv-input-group-lg > .uv-input,
.uv-input-group-lg > .uv-input-group-text,
.uv-input-group-lg > .uv-btn {
    padding: .5rem 1rem;
    font-size: 1.125rem;
    border-radius: var(--uv-radius-xs);
}
.uv-input-group-lg > .uv-input-group-text:not(:last-child),
.uv-input-group-lg > .uv-btn:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.uv-input-group-lg > .uv-input-group-text:not(:first-child),
.uv-input-group-lg > .uv-btn:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.uv-input-group-lg > .uv-input:not(:first-child),
.uv-input-group-lg > .uv-select:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}
.uv-input-group-lg > .uv-input:not(:last-child),
.uv-input-group-lg > .uv-select:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

/* ── Invalid Feedback ── */
.uv-invalid-feedback {
    display: block;
    width: 100%;
    margin-top: .25rem;
    font-size: var(--uv-fs-small);
    color: var(--uv-danger);
}

/* ── Multi-select ── */
.uv-select[multiple],
.uv-select-multiple {
    background-image: none;
    height: auto;
    padding: .375rem .75rem;
}

/* ── Check Switch (toggle) ── */
.uv-check-switch {
    padding-left: 2.5em;
}
.uv-check-switch .uv-check-input {
    width: 2em;
    margin-left: -2.5em;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(0,0,0,.25)'/%3e%3c/svg%3e");
    background-position: left center;
    border-radius: 2em;
    transition: background-position var(--uv-duration-fast) ease-in-out, background-color var(--uv-duration-fast) ease-in-out;
}
.uv-check-switch .uv-check-input:checked {
    background-position: right center;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
}

/* ══════════════════════════════════════════════════════════════
   Дополнения (phase-6 эталона) — uv-collapse, uv-accordion-body,
   uv-nav-link-табы, автономный uv-dropdown
   ══════════════════════════════════════════════════════════════ */

/* ── Collapse ── */
.uv-collapse:not(.show) { display: none !important; }

/* ── Accordion body ── */
.uv-accordion-body {
    padding: 1rem 1.25rem;
}
.uv-accordion-body-show-border-top.show {
    border-top: 1px solid var(--uv-border);
}

/* ── Tab nav — активное состояние (вне .uv-navbar) ── */
.uv-nav-item .uv-nav-link {
    display: block;
    padding: .5rem .75rem;
    color: var(--uv-text-body);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    transition: color var(--uv-duration-fast), border-color var(--uv-duration-fast);
}
.uv-nav-item .uv-nav-link:hover {
    color: var(--uv-primary);
    border-bottom-color: var(--uv-primary);
}
.uv-nav-item .uv-nav-link.active,
.uv-nav-item .uv-nav-link[aria-selected="true"] {
    color: var(--uv-primary);
    font-weight: var(--uv-fw-semibold);
    border-bottom-color: var(--uv-primary);
}

/* ── Автономный dropdown (вне .uv-navbar) ── */
.uv-dropdown { position: relative; display: inline-block; }
.uv-dropdown-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: var(--uv-z-dropdown);
    min-width: 10rem;
    padding: .5rem 0;
    background-color: var(--uv-surface);
    border: 1px solid var(--uv-border);
    border-radius: var(--uv-radius-sm);
    box-shadow: var(--uv-shadow-md);
}
.uv-dropdown-menu.show { display: block; }
.uv-dropdown-item {
    display: block;
    width: 100%;
    padding: .375rem 1rem;
    font-size: var(--uv-fs-body);
    color: var(--uv-text-body);
    text-decoration: none;
    white-space: nowrap;
    background-color: transparent;
    border: 0;
    cursor: pointer;
}
.uv-dropdown-item:hover,
.uv-dropdown-item:focus {
    background-color: var(--uv-bg-warm);
    color: var(--uv-primary);
}
.uv-dropdown-item.active {
    background-color: var(--uv-primary);
    color: var(--uv-text-inverse);
}

/* ── List group ── */
.uv-list-group {
    display: flex;
    flex-direction: column;
    padding: 0;
    margin: 0;
    list-style: none;
}
.uv-list-group-item {
    display: block;
    padding: .5rem 1rem;
    text-decoration: none;
    color: var(--uv-text-dark);
    background-color: var(--uv-surface);
    border: 1px solid var(--uv-border);
    border-top-width: 0;
}
.uv-list-group-item:first-child { border-top-width: 1px; border-radius: var(--uv-radius-sm) var(--uv-radius-sm) 0 0; }
.uv-list-group-item:last-child  { border-radius: 0 0 var(--uv-radius-sm) var(--uv-radius-sm); }
.uv-list-group-flush .uv-list-group-item { border-left: 0; border-right: 0; border-radius: 0; }
.uv-list-group-flush .uv-list-group-item:first-child { border-top-width: 0; }

/* ── GoToTop (замена Canvas SEMICOLON.initialize.goToTop) ──
   Разметка agroday: <div id="gotoTop" class="bi bi-chevron-up"></div>.
   Видимость переключает JS (display), кнопка плавает поверх контента. */
#gotoTop {
    display: none;
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: var(--uv-z-fixed);
    width: 2.5rem;
    height: 2.5rem;
    line-height: 2.5rem;
    text-align: center;
    font-size: var(--uv-fs-body);
    color: var(--uv-text-inverse);
    background: rgba(0, 0, 0, .35);
    border-radius: var(--uv-radius-circle);
    cursor: pointer;
    transition: background var(--uv-duration-base), opacity var(--uv-duration-slow);
}

#gotoTop:hover {
    background: rgba(0, 0, 0, .6);
}

/* ── Tooltip / Popover (замена удалённого bootstrap-плагина) ──
   Ноду создаёт vanilla-plugins.js (блок 11) и кладёт в body:
   абсолютное позиционирование над триггером, одна нода за раз. */
.uv-tooltip,
.uv-popover {
    position: absolute;
    z-index: var(--uv-z-popover);
    max-width: 14rem;
    padding: .35rem .6rem;
    background: var(--uv-dark);
    color: var(--uv-text-inverse);
    font-size: var(--uv-fs-xs);
    line-height: var(--uv-lh-compact);
    border-radius: var(--uv-radius-sm);
    box-shadow: var(--uv-shadow-md);
    pointer-events: none;
}

.uv-popover {
    max-width: 20rem;
    padding: .5rem .75rem;
}

/* ── Icon Color Utilities ──
   Семантические и брендовые тинты иконок для навигации, меню, контактов.
   Фирменные цвета внешних сервисов (VK, Telegram, …) — константы самих
   брендов, к палитре проекта не относятся и токенами не становятся.
   Употребляется в шаблонах уже сейчас (соц-провайдеры allauth).
   ========================================================================== */
.uv-ic-blue { color: #1991eb !important; }
.uv-ic-red { color: #F73B3B !important; }
.uv-ic-gray { color: var(--uv-text-secondary) !important; }
.uv-ic-green { color: var(--uv-success) !important; }
.uv-ic-yellow { color: var(--uv-warning) !important; }
.uv-ic-firebrick { color: #B22222 !important; }
.uv-ic-orange { color: #e67e22 !important; }
.uv-ic-primary { color: var(--uv-primary) !important; }
.uv-ic-purple { color: #8e44ad !important; }
.uv-ic-muted { color: var(--uv-text-soft) !important; }
.uv-ic-danger { color: var(--uv-danger) !important; }
/* Значок-заглушка: различим, но не спорит с содержимым строки */
.uv-ic-faint { color: var(--uv-border) !important; }
.uv-ic-success { color: #198d00 !important; }
.uv-ic-check { color: #2d8a4e !important; }

/* Иконка с круглым фоном (замена легаси i-uv-rounded) */
.uv-icon-round {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--uv-radius-circle);
    background: var(--uv-primary);
    color: var(--uv-text-inverse);
    font-size: .95rem;
}

/* Brand icon colors */
.uv-ic-vk { color: #45668e !important; }
.uv-ic-ok { color: #ed812b !important; }
.uv-ic-google { color: #ea4335 !important; }
.uv-ic-facebook { color: #3b5998 !important; }
.uv-ic-instagram { color: #c13584 !important; }
.uv-ic-telegram { color: #0088cc !important; }
.uv-ic-twitter { color: #1da1f2 !important; }
.uv-ic-whatsapp { color: #128C7E !important; }
.uv-ic-viber { color: #7360f2 !important; }
.uv-ic-yandex { color: red !important; }

/* ── Соцсети логина: hover-набор uv-soc-* ──
   Из fragments.css эталона (~735). Базовые стили .uv-login-social пока живут
   в fragments.css agroday (дубликат правил безвреден: значения совпадают);
   при чистке fragments этот блок остаётся здесь. */
.uv-login-social a.uv-soc-vk:hover { border-color: #0077ff; color: #0077ff; background: rgba(0,119,255,.06); box-shadow: 0 4px 12px rgba(0,119,255,.1); }
.uv-login-social a.uv-soc-ok:hover { border-color: #ee8208; color: #ee8208; background: rgba(238,130,8,.06); box-shadow: 0 4px 12px rgba(238,130,8,.1); }
.uv-login-social a.uv-soc-yandex:hover { border-color: #fc3f1d; color: #fc3f1d; background: rgba(252,63,29,.06); box-shadow: 0 4px 12px rgba(252,63,29,.1); }

/* ── Site footer (uv-footer-*) ──
   Тёмный футер с навигацией и счётчиками, сетка снаружи — uv-grid uv-grid-4.
   Нейтральные серые переведены с сине-серых эталона на зелёно-серые в тон
   --uv-dark #16241C; акцент hover — --uv-primary-soft (декор на тёмном). */
.uv-footer{background:var(--uv-dark);color:#c5d0ca;font-size: var(--uv-fs-small);line-height:var(--uv-lh-content)}
.uv-footer a{color:#c5d0ca;text-decoration:none;transition:color var(--uv-duration-base) ease}
.uv-footer a:hover{color:var(--uv-primary-soft)}
.uv-footer-top{padding:2.5rem 0 1.5rem;border-bottom:1px solid rgba(255,255,255,.08)}
.uv-footer-logo{display:block;margin-bottom:1rem}
.uv-footer-logo img{height:44px;width:auto;opacity:.9;transition:opacity var(--uv-duration-base)}
.uv-footer-logo:hover img{opacity:1}
.uv-footer-desc{color:#98a89f;font-size: var(--uv-fs-small);margin-bottom:1.25rem;max-width:380px}
.uv-footer-stats{display:flex;gap:2rem;margin-bottom:.5rem}
.uv-footer-stat{text-align:center}
.uv-footer-stat-num{display:block;font-size: var(--uv-fs-h1-mobile);font-weight: var(--uv-fw-bold);color:var(--uv-primary-soft);line-height:var(--uv-lh-compact)}
.uv-footer-stat-label{font-size: var(--uv-fs-micro);text-transform:uppercase;letter-spacing:.06em;color:#88a091}
.uv-footer-heading{font-size: var(--uv-fs-xs);font-weight: var(--uv-fw-bold);text-transform:uppercase;letter-spacing:.08em;color:var(--uv-text-inverse);margin-bottom:1rem;position:relative;padding-bottom:.6rem}
.uv-footer-heading::after{content:"";position:absolute;bottom:0;left:0;width:32px;height:2px;background:linear-gradient(90deg,var(--uv-primary),var(--uv-primary-soft));border-radius: var(--uv-radius-xs)}
.uv-footer-nav{list-style:none;padding:0;margin:0}
.uv-footer-nav li{margin-bottom:.55rem}
.uv-footer-nav a{display:inline-flex;align-items:center;gap:.45rem;font-size: var(--uv-fs-small)}
.uv-footer-nav a i{font-size: var(--uv-fs-micro);color:var(--uv-primary-soft);opacity:.7;transition:opacity var(--uv-duration-base)}
.uv-footer-nav a:hover i{opacity:1}
.uv-footer-contact-item{display:flex;align-items:flex-start;gap:.65rem;margin-bottom:.85rem;font-size: var(--uv-fs-small)}
.uv-footer-contact-item i{color:var(--uv-primary-soft);font-size: var(--uv-fs-small);margin-top:.15rem;flex-shrink:0}
.uv-footer-social{display:flex;gap:.5rem;margin-top:1rem}
.uv-footer-social a{width:36px;height:36px;border-radius: var(--uv-radius-circle);border:1px solid rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;font-size: var(--uv-fs-body);color:#c5d0ca;transition:all var(--uv-duration-base) ease}
.uv-footer-social a:hover{border-color:var(--uv-primary-soft);color:var(--uv-primary-soft);background:rgba(var(--uv-primary-rgb), .1);transform:translateY(-2px)}
.uv-footer-bottom{padding:1.25rem 0;font-size: var(--uv-fs-xs);color:var(--uv-text-muted)}
.uv-footer-bottom a{color:#88a091;transition:color var(--uv-duration-base)}
.uv-footer-bottom a:hover{color:var(--uv-primary-soft)}
.uv-footer-bottom-links{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.uv-footer-bottom-links span{color:#4a5e53}
.uv-footer-counters{display:flex;align-items:center;gap:.75rem;justify-content:flex-end}
@media (max-width: 767.98px) {
    .uv-footer-stats{gap:1.5rem}
    .uv-footer-stat-num{font-size: var(--uv-fs-h3)}
    .uv-footer-counters{justify-content:flex-start;margin-top:.75rem}
}

/* ── Reduced motion ──
   Декоративная бесконечная анимация останавливается, функциональный спиннер
   замедляется (он индикатор загрузки — полностью гасить нельзя), мгновенные
   переходы .fade перестают мигать. */
@media (prefers-reduced-motion: reduce) {
    .fade { transition: none; }
    .spinner-border,
    .spinner-border-sm { animation-duration: var(--uv-anim-loop-slow); }
}

/* ── Клавиатурный фокус ──
   Единый видимый контур для всего, чем можно управлять с клавиатуры.
   :focus-visible (а не :focus) — чтобы контур появлялся при Tab и не появлялся
   при клике мышью. Поля ввода сюда не входят: у них своя индикация
   (цвет рамки + свечение), добавлять им ещё и контур незачем.
   Идёт последним в файле: при равной специфичности выигрывает порядок. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
label:focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
[role="link"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid var(--uv-primary);
    outline-offset: 2px;
    border-radius: var(--uv-radius-xs);
}

/* На тёмной подложке зелёный контур сливается — там ведём белым. */
.uv-bg-primary a:focus-visible,
.uv-bg-primary button:focus-visible,
.uv-footer a:focus-visible,
.uv-navbar a:focus-visible {
    outline-color: var(--uv-surface);
}

/* ── Мобильные тач-таргеты шапки ≥44px ──
   Минимальная зона пальца (WCAG 2.5.5): бургер, кнопка поиска и крестик
   офф-канваса/поисковой строки на <992px, пункты мобильного меню — по
   высоте. Сами компоненты стилизованы в fragments.css, здесь только
   минимумы: min-* перекрывает их width/height без !important, а
   inline-<a> поиска получает flex, чтобы min-размеры применились. */
@media (max-width: 991.98px) {
    .uv-navbar .uv-nav-toggler,
    .uv-navbar .uv-btn-close,
    .uv-search-toggle {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .uv-navbar .uv-offcanvas .uv-nav-link { min-height: 44px; }
}

/* ==== Каркас страницы: #wrapper / #content (порт из uvelir base.css) ==== */
/* Блок выпал при первом портировании дизайн-системы — сайт становился
   «резиновым»: без max-width каркас растягивается на всю ширину окна
   (замечено на проде 2026-09-28). 1080px — не вкусовщина: под неё ужата
   десктоп-шапка (см. комментарий в fragments.css у десктоп-navbar).
   overflow: clip не создаёт scroll-контейнер — sticky у .uv-navbar
   продолжает работать. */
#wrapper {
    position: relative;
    width: 100%;
    max-width: 1080px;
    margin: 0 auto;
    background-color: var(--uv-surface);
    overflow: clip;   /* страховка: ничто не выходит за пределы wrapper */
}

#content {
    position: relative;
    background-color: var(--uv-surface);
}

/* Ответственные картинки в контенте (страховка от чужой разметки) */
:where(#wrapper) img {
    max-width: 100%;
    height: auto;
}

/* ==== uv-container (порт из uvelir base.css) ==== */
/* Базовое определение: контекстное (.uv-navbar .uv-nav>.uv-container) в
   fragments.css опирается на него — без него контейнер не центрируется
   и не получает боковой padding вне навбара. Токены — наши. */
.uv-container {
    width: 100%;
    box-sizing: border-box;   /* padding не расширяет width за пределы wrapper */
    margin-inline: auto;
    padding-inline: var(--uv-space-3);
}

/* ============================================================
   Секционные заголовки и контент-ряды главной/списков.
   Миграция templates/pages/index.html (первый шаблон постраничного
   перевода): паттерны портированы из homepage.css эталона, токены —
   наши. Дальше эти классы — канонические замены легаси:
     .fancy-title.title-bottom-border → .uv-section-title
     .article-container/.article-frame → .uv-hero-card
     float-строки «фото+текст»        → .uv-feed-item
     сайдбар выставок (float+style)   → .uv-event-card
     .tagcloud                        → .uv-chips / a.uv-chip
   ============================================================ */

/* ── Section Headers: заголовок секции + акцентная линия снизу,
      справа — опциональный ряд ссылок «все материалы» ── */
.uv-section-title {
    display: flex;
    align-items: center;
    gap: var(--uv-space-3);
    margin-bottom: var(--uv-space-3);
    padding-bottom: .75rem;
    border-bottom: 2px solid var(--uv-border);
    position: relative;
}
.uv-section-title::after {
    content: "";
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 80px;
    height: 2px;
    background: var(--uv-primary);
}
.uv-section-title h2,
.uv-section-title h3 {
    margin: 0;
    font-size: var(--uv-fs-h4);
    font-weight: var(--uv-fw-bold);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--uv-dark);
    white-space: nowrap;
}
.uv-section-title h2 a,
.uv-section-title h3 a {
    color: inherit;
    text-decoration: none;
    transition: color var(--uv-duration-base);
}
.uv-section-title h2 a:hover,
.uv-section-title h3 a:hover { color: var(--uv-primary); }
.uv-section-links {
    display: flex;
    gap: var(--uv-space-2);
    margin-left: auto;
    flex-wrap: wrap;
}
.uv-section-links a {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: var(--uv-fs-xs);
    font-weight: var(--uv-fw-medium);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--uv-text-muted);
    text-decoration: none;
    padding: .25rem .6rem;
    border: 1px solid var(--uv-border);
    border-radius: var(--uv-radius-xs);
    transition: color var(--uv-duration-slow) var(--uv-ease), border-color var(--uv-duration-slow) var(--uv-ease), background var(--uv-duration-slow) var(--uv-ease);
}
.uv-section-links a:hover {
    color: var(--uv-primary-dark);
    border-color: var(--uv-primary);
    background: rgba(var(--uv-primary-rgb), .04);
}

/* На узких экранах заголовок (nowrap) и ссылки секции не помещаются
   в одну строку: ссылки переносятся вниз без отступа слева. */
@media (max-width: 575.98px) {
    .uv-section-title { flex-wrap: wrap; row-gap: .5rem; }
    .uv-section-links { margin-left: 0; }
}

/* ── Hero-карточки: 2 акцентных материала с фото и градиентной
      подложкой (замена Canvas .article-container/.article-frame) ── */
.uv-hero-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--uv-space-2);
}
.uv-hero-card {
    position: relative;
    border-radius: var(--uv-radius-sm);
    overflow: hidden;
    background: var(--uv-dark);  /* без фото карточка остаётся читаемой */
}
.uv-hero-card > a {
    display: block;
    text-decoration: none;
    color: var(--uv-text-inverse);
}
.uv-hero-card img {
    width: 100%;
    height: 175px;
    object-fit: cover;
    display: block;
    transition: transform var(--uv-duration-slower) var(--uv-ease);
}
.uv-hero-card:hover img { transform: scale(1.04); }
.uv-hero-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: .85rem;
    background: linear-gradient(0deg, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .25) 50%, transparent 100%);
}
.uv-hero-meta {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: .3rem;
    font-size: var(--uv-fs-small);
    opacity: .85;
}
.uv-hero-title {
    margin: 0;
    font-size: var(--uv-fs-body);
    font-weight: var(--uv-fw-semibold);
    line-height: var(--uv-lh-compact);
    text-transform: uppercase;
}

/* ── Featured-карточка Вестника (порт homepage.css эталона uvelir.info;
      .uv-hero-overlay/.uv-hero-meta/.uv-hero-title выше — общая база,
      здесь усиления под большую карточку) ── */
.uv-hero-featured {
    position: relative;
    border-radius: var(--uv-radius-sm);
    overflow: hidden;
    margin-bottom: .75rem;
}
.uv-hero-featured > a {
    display: block;
    text-decoration: none;
    color: var(--uv-text-inverse);
}
.uv-hero-featured img {
    width: 100%;
    height: 380px;
    object-fit: cover;
    display: block;
    transition: transform var(--uv-duration-slower) var(--uv-ease);
}
.uv-hero-featured:hover img { transform: scale(1.03); }
.uv-hero-featured .uv-hero-overlay {
    background: linear-gradient(0deg, rgba(10, 10, 20, .85) 0%, rgba(10, 10, 20, .4) 40%, transparent 70%);
    padding: 1.5rem;
}
.uv-hero-featured .uv-hero-meta { margin-bottom: .5rem; }
.uv-hero-featured .uv-hero-meta time {
    background: rgba(255, 255, 255, .15);
    padding: .2rem .5rem;
    border-radius: var(--uv-radius-xs);
    backdrop-filter: blur(4px);
}
.uv-hero-featured .uv-hero-title {
    font-size: var(--uv-fs-h2);
    font-weight: var(--uv-fw-bold);
    /* базовый .uv-hero-title uppercase; у featured обычный регистр, как на эталоне */
    text-transform: none;
    color: var(--uv-text-inverse);
    text-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}

/* Малые hero-карточки: оверлей, мета, заголовок (порт homepage.css эталона) */
.uv-hero-card .uv-card-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(0deg, rgba(10, 10, 20, .82) 0%, rgba(10, 10, 20, .25) 50%, transparent 100%);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: .85rem;
}
.uv-hero-card .uv-card-meta {
    font-size: var(--uv-fs-small);
    opacity: .8;
    margin-bottom: .3rem;
}
.uv-hero-card .uv-card-meta time {
    background: rgba(255, 255, 255, .15);
    padding: .15rem .4rem;
    border-radius: var(--uv-radius-xs);
}
.uv-hero-card .uv-card-title {
    font-size: var(--uv-fs-body);
    font-weight: var(--uv-fw-semibold);
    line-height: var(--uv-lh-compact);
    color: var(--uv-text-inverse);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── Плашки рубрик (порт homepage.css эталона). :empty — категория новости
      бывает NULL, default_if_none даёт пустую плашку, прячем её ── */
.uv-section-badge {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-size: var(--uv-fs-micro);
    font-weight: var(--uv-fw-semibold);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .1rem .4rem;
    border-radius: var(--uv-radius-xs);
    background: none;
    color: var(--uv-text-muted);
    border: 1px solid var(--uv-border);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--uv-duration-slow) var(--uv-ease), border-color var(--uv-duration-slow) var(--uv-ease);
}
.uv-section-badge:hover {
    color: var(--uv-primary-dark);
    border-color: var(--uv-primary);
}
.uv-section-badge i {
    font-size: var(--uv-fs-micro);
}
.uv-section-badge:empty { display: none; }
/* Плашка на тёмном оверлее hero — залитая */
.uv-section-badge-hero {
    font-size: var(--uv-fs-micro);
    padding: .1rem .45rem;
    background: rgba(var(--uv-primary-rgb), .85);
    color: var(--uv-text-inverse);
    border-color: transparent;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.uv-section-badge-hero:hover {
    color: var(--uv-text-inverse);
    opacity: .9;
}

/* ── Анимации появления (прогрессивное улучшение: без JS контент видим;
      скрипт включения — в templates/pages/index.html) ── */
.uv-animate {
    opacity: 1;
    transform: none;
}
body.uv-anim-ready .uv-animate {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--uv-duration-slower) ease, transform var(--uv-duration-slower) ease;
}
body.uv-anim-ready .uv-animate.uv-visible {
    opacity: 1;
    transform: translateY(0);
}
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(1) { transition-delay: .05s; }
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(2) { transition-delay: .1s; }
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(3) { transition-delay: .15s; }
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(4) { transition-delay: .2s; }
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(5) { transition-delay: .25s; }
body.uv-anim-ready .uv-stagger > .uv-animate:nth-child(6) { transition-delay: .3s; }

@media (max-width: 767.98px) {
    .uv-hero-grid { grid-template-columns: 1fr; }
    .uv-hero-featured img { height: 240px; }
    .uv-hero-featured .uv-hero-title { font-size: 1.15rem; }
    .uv-hero-card img { height: 200px; }
}

@media (min-width: 768px) and (max-width: 991.98px) {
    .uv-hero-featured img { height: 300px; }
    .uv-hero-card img { height: 150px; }
    .uv-hero-card .uv-card-title {
        font-size: var(--uv-fs-small);
        -webkit-line-clamp: 2;
    }
}

/* ── Feed-ряды «картинка слева + текст»: новости, пресс-релизы,
      статьи (замена float-start/clearfix-строк) ── */
.uv-feed-item {
    display: flex;
    gap: var(--uv-space-3);
    padding: var(--uv-space-2) 0;
    border-bottom: 1px solid var(--uv-border-light);
}
.uv-feed-item:first-child { padding-top: 0; }
.uv-feed-item:last-child { border-bottom: none; }
.uv-feed-thumb {
    flex-shrink: 0;
    width: 120px;
    border-radius: var(--uv-radius-sm);
    overflow: hidden;
    text-decoration: none;
}
.uv-feed-thumb img {
    width: 100%;
    height: auto;
    display: block;
    transition: transform var(--uv-duration-slow) var(--uv-ease);
}
.uv-feed-item:hover .uv-feed-thumb img { transform: scale(1.05); }
.uv-feed-body {
    flex: 1;
    min-width: 0;
}
.uv-feed-meta {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-size: var(--uv-fs-xs);
    color: var(--uv-text-muted);
    margin-bottom: .25rem;
}
/* мета-строка в одну линию: дата и просмотры не сжимаются,
   рубрика ужимается с многоточием */
.uv-feed-meta time, .uv-feed-views { white-space: nowrap; flex-shrink: 0; }
.uv-feed-category {
    color: var(--uv-primary-dark);
    font-weight: var(--uv-fw-semibold);
    text-transform: uppercase;
    letter-spacing: .03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
.uv-feed-views {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: .2rem;
}
.uv-feed-title {
    margin: 0 0 .25rem;
    font-size: var(--uv-fs-h4);
    font-weight: var(--uv-fw-medium);
    line-height: var(--uv-lh-compact);
}
.uv-feed-title a {
    color: var(--uv-text-dark);
    text-decoration: none;
    transition: color var(--uv-duration-base);
}
.uv-feed-title a:hover { color: var(--uv-primary-dark); }
.uv-feed-excerpt {
    margin: 0;
    font-size: var(--uv-fs-small);
    color: var(--uv-text-muted);
    line-height: var(--uv-lh-base);
}
@media (max-width: 575.98px) {
    .uv-feed-thumb { width: 96px; }
}

/* ── Карточка выставки в сайдбаре (замена float + inline-рамки баннера) ── */
.uv-event-card {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    border: 1px solid var(--uv-border);
    border-left: 3px solid var(--uv-primary);
    border-radius: var(--uv-radius-sm);
    padding: .85rem;
    margin-bottom: .75rem;
    background: var(--uv-surface);
    transition: border-color var(--uv-duration-slow) var(--uv-ease), box-shadow var(--uv-duration-slow) var(--uv-ease), transform var(--uv-duration-slow) var(--uv-ease);
}
.uv-event-card:hover {
    border-left-color: var(--uv-primary-dark);
    box-shadow: var(--uv-shadow-sm);
    transform: translateX(2px);
}
.uv-event-banner {
    display: block;
    margin: 0;
    flex-shrink: 0;
    border-radius: var(--uv-radius-xs);
}
.uv-event-body { min-width: 0; }
.uv-event-detail {
    font-size: var(--uv-fs-small);
    color: var(--uv-text-muted);
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-bottom: .3rem;
}
.uv-event-detail i { color: var(--uv-primary); }
.uv-event-title {
    margin: 0;
    font-size: var(--uv-fs-body);
    font-weight: var(--uv-fw-semibold);
    line-height: var(--uv-lh-compact);
}
.uv-event-title a {
    color: var(--uv-text-dark);
    text-decoration: none;
    transition: color var(--uv-duration-base);
}
.uv-event-title a:hover { color: var(--uv-primary-dark); }

/* На <400px баннер разворачивается на всю ширину, текст — под ним */
@media (max-width: 399.98px) {
    .uv-event-card { flex-wrap: wrap; }
    .uv-event-banner { width: 100%; }
}

/* ── Чипы: облако рубрик/тегов (замена Canvas .tagcloud) ── */
.uv-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--uv-space-2);
}
a.uv-chip {
    display: inline-flex;
    align-items: center;
    padding: .3rem .7rem;
    font-size: var(--uv-fs-xs);
    font-weight: var(--uv-fw-medium);
    color: var(--uv-text-body);
    background: var(--uv-bg-warm);
    border: 1px solid var(--uv-border);
    border-radius: var(--uv-radius-pill);
    text-decoration: none;
    transition: color var(--uv-duration-base), border-color var(--uv-duration-base), background var(--uv-duration-base);
}
a.uv-chip:hover {
    color: var(--uv-primary-dark);
    border-color: var(--uv-primary);
    background: rgba(var(--uv-primary-rgb), .05);
}
