/* Besfo — токены дизайн-системы.
   Нормативный источник значений: besfo_design_system.md */
:root {
    /* Бренд-цвета (красный) */
    --color-brand: #F02525;
    --color-brand-hover: #E91000;

    /* Три остановки градиента шапки. Вынесены в собственные токены и НЕ
       ссылаются на --color-brand: фирменный #F02525 остается как есть в
       кнопках и акцентах, а фон шапки опущен на ступень по светлоте ради
       контраста с белым текстом.
       Было: #D81E1E → #F02525 → #FF3B3B, то есть 5.09 → 4.20 → 3.53:1.
       Норма для обычного текста 4.5:1, и две остановки из трех ее не брали.
       Хуже того, контраст плавал по ширине шапки: слева текст проходил,
       справа нет. Теперь все три остановки выше нормы, тон и направление
       градиента сохранены — ушла только яркость, примерно на 7% светлоты. */
    /* Брендовый красный, затемненный до уровня, на котором держит белый
       текст (5.98:1). Фирменный #F02525 дает только 4.2:1 и для подписей на
       кнопках не годится. Тот же цвет — темный край градиента шапки, поэтому
       он объявлен один раз и используется обоими. */
    --color-brand-strong: #C41A1A;
    /* Кнопка действия. Светлый край — по умолчанию, темный — при наведении.
       Фирменный #F02525 светлее обоих, но белый текст на нем дает 4.2:1 при
       норме 4.5, поэтому в качестве светлого края взят #E91000 (4.63:1).
       Тот же #E91000 работает текстом на белом фоне — у кнопки в состоянии
       «уже в корзине» контраст тот же 4.63:1. */
    /* Подложка плашки скидки. Насыщенность подобрана по контрасту, а не на
       глаз: темный красный на ней дает 4.71:1 при норме 4.5. Ступенью гуще
       (18% красного) уже 4.38 — провал. Светлый #E91000 текстом на этой
       подложке дает всего 3.64, поэтому текст именно темный. */
    --color-discount-bg: #FCDDDD;

    /* Темная плашка вспомогательных действий и ее состояние при наведении.
       Красный в проекте принадлежит покупке, поэтому сортировка, номера
       страниц, переключатель вида и кнопка фильтра выделяются темнотой, а не
       цветом. */
    --color-dark-action: #1A1A1A;
    --color-dark-action-hover: #000000;

    --color-cta: #E91000;
    --color-cta-hover: #C41A1A;

    --shadow-popover: 0 8px 24px rgba(0, 0, 0, .18);

    --header-grad-from: var(--color-brand-strong);   /* 5.98:1 с белым */
    --header-grad-mid:  #D81E1E;   /* 5.09:1 */
    --header-grad-to:   #E62020;   /* 4.57:1 */
    --header-gradient: linear-gradient(135deg, var(--header-grad-from) 0%, var(--header-grad-mid) 50%, var(--header-grad-to) 100%);

    /* Текст */
    /* ── Типографическая шкала (документ дизайн-системы) ────────────────
       Каждой роли отвечает пара «кегль + межстрочный», менять их поодиночке
       нельзя. Значения плавно переходят от мобильных к десктопным: clamp
       рассчитан так, что при ширине окна 360px получается ровно мобильное
       значение из таблицы, при 1440px — ровно десктопное. Отношение падает
       с ростом кегля (1.5 у Body → 1.25 у H1), как и требует документ:
       мелкому тексту нужно больше воздуха, крупным заголовкам меньше. */
    --font-main: 'Inter', -apple-system, BlinkMacSystemFont, Arial, sans-serif;

    /* Роль стоит на МИНИМУМЕ на обоих концах: 22/28 на 360 и 28/36 на 1440.
       Мобильный конец — пол шкалы, ниже 22 для H1 ничего нет: 20 и 18 заняты
       Price и H2.
       Десктопный конец — пол иерархии: H2 и Price на широком экране обе стоят
       на 24, и уже на 25 заголовок сравнялся бы с ними, а различать уровни
       одним весом система запрещает. 28 дает разрыв над H2 ровно +4px — тот
       же, что на мобильном конце, где 22 против 18.
       Наклон рампы у H1 и H2 теперь совпадает (0.556vw), поэтому разрыв
       держится постоянным на ЛЮБОЙ ширине, а не только на краях.
       Интервал 36, а не 35 по точному отношению 1.25: межстрочные в шкале
       кратны четырем, и выпадать из этого ряда ради одной цифры не стоит.
       Отношение выходит 1.286 — все еще меньше, чем 1.33 у H2, то есть
       правило «отношение падает с ростом кегля» соблюдено. */
    --text-h1:      clamp(22px, 20.000px + 0.556vw, 28px);   /* 22 → 28 */
    --lh-h1:        clamp(28px, 25.333px + 0.741vw, 36px);   /* 1.286  */
    --fw-h1: 700;

    --text-h2:      clamp(18px, 16.000px + 0.556vw, 24px);   /* 18 → 24 */
    --lh-h2:        clamp(24px, 21.333px + 0.741vw, 32px);   /* 1.3    */
    --fw-h2: 600;

    --text-price:   clamp(20px, 18.667px + 0.370vw, 24px);   /* 20 → 24 */
    --lh-price:     clamp(24px, 22.667px + 0.370vw, 28px);   /* 1.2    */
    --fw-price: 700;

    /* Body 14/20 на всех ширинах, БЕЗ clamp. Прежде роль росла 14 → 16 к
       десктопу, и читаемый текст — описание, отзывы — оказывался крупнее
       всего остального на странице: интерфейс идет ролью Interface, а она
       на десктопе 14. Разрыв в 2px читался как сбой набора.
       Кегль теперь совпадает с Interface, роли различает вес: 400 против
       500. Это сочетание в системе уже есть — названием товара в карточке
       сетки набирается ровно 14/20/400. */
    --text-body:    14px;
    --lh-body:      20px;
    --fw-body: 400;

    --text-ui:      clamp(13px, 12.667px + 0.093vw, 14px);   /* 13 → 14 */
    --lh-ui:        clamp(18px, 17.333px + 0.185vw, 20px);   /* 1.4    */
    --fw-ui: 500;

    /* Цена в сетке карточек — фиксированные 20/24. Не clamp: карточка и так
       меняет ширину сама, а кегль внутри нее должен быть предсказуемым.
       Ступень существует в шкале — на ней стоит Price для мобильных.
       Почему не Price целиком: 24px это масштаб страницы товара, где цена
       главный элемент экрана. В мини-карточке она конкурирует с фотографией.
       Почему не Body: 16px отличается от названия и рейтинга на два пикселя,
       и цена перестает выделяться. */
    --text-price-card: 20px;
    --lh-price-card:   24px;

    --text-caption: clamp(11px, 10.667px + 0.093vw, 12px);   /* 11 → 12 */
    --lh-caption:   clamp(14px, 13.333px + 0.185vw, 16px);   /* 1.3    */
    --fw-caption: 500;

    /* Глубокий графитовый вместо чистого черного — по документу: снижает
       утомляемость при чтении длинных списков артикулов. */
    --color-text: #1A1A1A;
    --color-text-secondary: #6B7280;

    /* Вторичный текст НА СЕРОЙ ПЛАШКЕ. Обычный #6B7280 там не проходит:
       4.43:1 на плашке в покое и 3.66:1 при наведении, когда она темнеет.
       #5A6068 дает 5.82 и 4.81 — норма выдержана в обоих состояниях. */
    --color-text-on-plate: #5A6068;

    /* Заглушка «нет фотографии». Два цвета, а не один: у знака и у подписи
       разные нормы контраста. Оба взяты предельно светлыми — заглушка не
       должна спорить с товарами вокруг, у которых снимки есть.
       Камера — нетекстовый элемент, норма 3:1, #8E8E8E дает 3.01.
       Подпись — текст, норма 4.5:1, #707070 дает 4.54.
       Светлее нельзя: следующий шаг уводит ниже нормы. */
    --color-placeholder-mark: #8E8E8E;
    --color-placeholder-text: #707070;   /* артикулы, OEM, кросс-коды, подписи — по документу */
    --color-text-muted: #929292;
    --color-icon: #8b9096;

    /* Темные фоны (подвал) */
    --color-dark: #1F1E1C;
    --color-dark-secondary: #2D2C2A;
    --color-dark-hover: #454442;

    /* Светлые фоны/границы */
    --color-white: #ffffff;
    /* Знак на заглушке вместо фотографии. Подобран по различимости: на
       подложке #F5F5F5 дает 1.47:1 — виден, но не спорит с ценой и
       названием рядом. Требований по контрасту к нему нет, изображение
       декоративное. */
    /* Звезда рейтинга. Знак декоративный — смысл несет число рядом, поэтому
       требований по контрасту к нему нет, важна только узнаваемость. */
    --color-rating: #F5A623;

    --color-placeholder: #CCCCCC;

    --color-gray-light: #F5F5F5;
    --color-border: #E0E0E0;
    /* Серая кнопка в нажатии. На ступень темнее наведения и не более: смена
       заливки на темную с белым текстом читалась как вспышка чужой кнопки. */
    --color-gray-pressed: #D2D2D2;
    --color-border-lighter: #E5E5E5;
    --color-separator: #949494;        /* разделитель «—» в крошках, стрелки аккордеона */
    --color-divider-strong: #EEEEEE;   /* границы строк аккордеона каталога на мобилке */
    /* Синий у кнопки «Еще» — единственный синий во всей палитре, красной
       по бренду. Решение оставить его синим еще будет пересматриваться;
       менять цвет здесь, в двух строках, на месте применения ничего не
       завязано.
       Базовый затемнен с rgb(66,139,249) — тот давал 3.34:1 при норме 4.5.
       Ховер раньше задавался прозрачностью 80%, и это работало против
       контраста: прозрачность поверх белого ОСВЕТЛЯЕТ, фактический цвет
       выходил #68A2FA с контрастом 2.58:1 — хуже, чем в покое. Теперь
       ховер темнее базового, как и положено ссылке. */
    --color-action: #156FF8;           /* 4.51:1 на белом */
    --color-action-hover: #0F5AC7;     /* 6.35:1 на белом */
    /* Подсветка при наведении поверх темного/цветного фона. Полупрозрачный
       белый, а не конкретный цвет: работает на любом оттенке градиента шапки
       и не требует совпадать с ним. */
    --color-overlay-hover: rgba(255, 255, 255, .22);

    /* Кольцо фокуса. Двухцветное намеренно: одноцветное пришлось бы
       подбирать под каждый фон, а у нас их три — красная шапка, белый
       контент, темный подвал. Белая полоса читается на красном и темном,
       темная обводка вокруг нее — на белом. Работает на любом фоне без
       вариантов под каждый блок. */
    /* Счетчик товаров. Кружку нужны ДВА контраста сразу: с цифрой внутри
       (мелкий текст, норма 4.5:1) и с фоном, на котором он лежит (элемент
       интерфейса, норма 3:1).
       Чистый черный, а не --color-dark (#1F1E1C): тот дает цифре сколько
       угодно, но с красной шапкой у него 2.78:1 у левого края — ниже нормы,
       кружок подсасывается к фону. Разница между #1F1E1C и #000000 на глаз
       почти неразличима, а по контрасту это 2.78 против 3.51:1, то есть
       переход через порог. Поэтому здесь отдельный токен, а не общий темный.
       Красная заливка, которая раньше стояла в мобильной панели, отделялась
       от белого фона, но давала цифре только 4.2:1 — теперь счетчик везде
       одинаковый и проходит на обоих фонах. */
    --color-badge-bg: #000000;         /* 3.51–4.59:1 с шапкой, 21:1 с белой панелью */
    --color-badge-text: var(--color-white);

    --focus-ring-inner: var(--color-white);
    --focus-ring-outer: var(--color-dark);
    --color-scrollbar-track: #E8E8E8;
    --color-divider: #f2f2f2;

    /* Spacing-токены (8pt Grid, шаг 8px, 4px допустим только для микро-отступов) */
    /* ── РОЛИ ОТСТУПОВ ───────────────────────────────────────────────────
       Шкала говорит, какие числа допустимы. Роли говорят, КАКОЕ из них где.
       Без этого каждый новый элемент — отдельное решение «тут восемь или
       шестнадцать?», и ритм расползается по проекту.

       В стилях пишется роль, а не число. Число меняется в одном месте. */
    --gap-tight:     4px;   /* внутри строки: иконка и подпись, звезда и оценка */
    --gap-inner:     8px;   /* между строками одного смыслового куска */
    --gap-block:    16px;   /* между смысловыми кусками внутри компонента */
    --gap-component: 24px;  /* между компонентами в одном блоке */
    --gap-section:  32px;   /* между блоками страницы */
    --gap-page:     64px;   /* перед подвалом, в конце содержимого */

    --pad-box:      16px;   /* внутренняя набивка компонента */
    --pad-box-lg:   24px;   /* набивка крупного блока: панель покупки, всплывающая карточка */
    /* Набивка окна (<dialog>): вход, отзыв, вопрос, город, возврат, аналоги.
       Решение заказчика 17.09.2026: у всплывающих окон отступ от границ
       больше, чем у блоков страницы. Окно перекрывает страницу, и воздух по
       краю отделяет его содержимое от затемненного фона. */
    --pad-box-xl:   32px;

    --space-xs: 4px;    /* иконка+текст, цена+старая цена */
    --space-sm: 8px;    /* плотная связь: теги, заголовок+цена */
    --space-md: 16px;   /* стандартный внутренний паддинг, строки форм */
    /* Все ступени фиксированные. Раньше --space-lg/xl/xxl были clamp'ами
       (16-24, 24-32, 32-56) — то есть на промежуточных ширинах окна давали
       19.7px, 27.3px и подобное. Значений между ступенями шкала не
       допускает, и плавающий отступ нарушал ее на любой ширине, кроме двух
       крайних. Адаптивность отступов обеспечивают брейкпоинты, а не
       интерполяция. */
    --space-lg: 24px;   /* межколоночный gutter, средние блоки */
    --space-xl: 32px;   /* крупный внутренний отступ (поп-апы, корзина) */
    --space-xxl: 56px;  /* разделение секций на главной */
    --space-giant: 64px; /* глобальные отступы перед подвалом/между "этажами" */

    /* Safe-margin контейнера. Раньше это число было захардкожено в трех
       местах (.container, .catalog-panel .container и ::before-разделитель
       в подвале) и переопределялось в каждой media query отдельно — из-за
       чего разделитель в подвале на планшете оставался на 32px, когда
       контейнер уже ушел на 16px. Теперь все считает одна переменная:
       переопределяем ее в media query один раз, и все три места едут
       синхронно. Значения — из сетки 16/24/32. */
    --container-pad: 32px;

    /* Высота мобильной нижней панели. Нужна в двух местах сразу — сама
       панель и padding-bottom у body, который резервирует под нее место.
       Держать одним числом обязательно, иначе они расходятся при правках. */
    --mobile-nav-height: 60px;

    /* Радиус скругления крупных блоков страницы (шапка, подвал). Отдельно
       от 8px у кнопок, инпута и пунктов каталога: там радиус элемента
       интерфейса, тут — радиус «этажа» страницы, и меняться они должны
       независимо друг от друга. Значение из той же шкалы 4-8-16-24. */
    --radius-block: 16px;

    /* Статусы наличия для будущего каталога. Типографики здесь намеренно
       нет: раньше тут лежал ВТОРОЙ набор кеглей и интервалов
       (--h1-size-desktop, --card-*, --oem-*, --price-*) — 18 токенов,
       дублировавших шкалу выше и не примененных нигде. Два источника
       правды по типографике хуже, чем ни одного: рано или поздно кто-то
       возьмет значение из мертвого набора. Артикулы, OEM и цены берут
       роли Caption и Price из шкалы, цвет — --color-text-secondary. */
    --color-status-ok: #1D883C;   /* "В наличии" — 4.53:1 на белом */
    /* Тег совместимости в отзыве. Три состояния, и цвет в них НЕСЕТ смысл,
       поэтому рядом всегда стоит слово — цветом одним пользоваться нельзя.
       «Подошло» берет зеленый статуса, «не подошло» — подложку скидки с
       темно-красным. Для «пришлось допилить» своей пары не было: замер
       #7A4A00 на #FFF4E5 дает 6.88:1. */
    /* Шильдики происхождения. Оформлены как значок скидки: светлая подложка
       с темным текстом того же тона. Пары подобраны по замеру, не на глаз:
       #16702F на #E6F4EA — 5.45:1, #0F5AC7 на #E7F0FE — 5.53:1, при норме
       4.5 для текста. Значок скидки для сравнения дает 5.06:1. */
    /* Цвета сервисов входа. Фирменные и неприкосновенные: кнопку «Войти с
       Яндекс ID» нельзя перекрасить в наши цвета, ее узнают по цвету.
       Белым по обоим: 16.1:1 на черном Яндекса и 3.2:1 на зеленом Сбера —
       второе ниже 4.5, поэтому надпись там набрана весом H2 и кеглем 14, а
       это уже «крупный текст», для которого норма 3:1. */
    --color-vkid:   #0077FF;
    --color-yandex: #000000;
    --color-sber:   #21A038;

    --color-mark-original:    #16702F;
    --color-mark-original-bg: #E6F4EA;
    --color-mark-analog:      #0F5AC7;
    --color-mark-analog-bg:   #E7F0FE;

    --color-status-warn:    #7A4A00;
    --color-status-warn-bg: #FFF4E5;
    --color-status-ok-bg:   #E6F4EA;
    --color-status-neutral: var(--color-text-secondary);

    /* Сетка каталога. Заданы только ЧИСЛО колонок и промежуток — ширина
       колонки при CSS Grid получается сама из repeat(12, minmax(0, 1fr)).
       Раньше здесь лежали еще и ширины: 98px для колонки и 158px для
       мобильной карточки. Обе неверны: их посчитали от внешней ширины
       контейнера, забыв вычесть боковые отступы. 12 × 98 + 11 × 24 = 1440,
       но контента при отступах 32 остается 1376 — не хватает ровно двух
       отступов. Реальная колонка (1376 − 11 × 24) / 12 = 92.67px, а мобильная
       карточка при отступе 24 равна 150px, а не 158. Числа, которые нельзя
       использовать не пересчитав, лучше не хранить вовсе. */
    --grid-columns-desktop: 12;
    --grid-gutter-desktop: 24px;
    --grid-cards-mobile: 2;
    --grid-gutter-mobile: 12px;
  }

  @media (max-width: 1024px){
  :root { --container-pad: 16px; }
  }

  @media (max-width: 640px){
  :root { --container-pad: 24px; }
  }
