/**
 * Общий слой: то, что должно выглядеть одинаково на всех экранах.
 *
 * Появился после аудита: `.btn` был определён в ВОСЬМИ файлах с разной
 * высотой (40, 44, 46px), `.num` — в шести. Из-за этого кнопка «Продолжить»
 * в онбординге была на 2 пиксела выше кнопки «В корзину» на витрине,
 * а кнопки в кабинете продавца — на 4 ниже остальных. По одному экрану
 * это незаметно, но при переходе между ними интерфейс «дёргается».
 *
 * Подключается ПОСЛЕ tokens.css и ПЕРЕД файлом конкретного экрана,
 * чтобы экран мог переопределить частный случай, если он обоснован.
 *
 * Правило: сюда попадает только то, что встречается минимум на трёх
 * экранах. Всё остальное живёт в файле своего экрана — общий слой,
 * куда сваливают всё подряд, через месяц становится вторым desktop.css.
 */

/* border-box для всего.
 *
 * Без него граница прибавляется к высоте, и `<a class="btn">` с рамкой
 * 0,67px становится 45,33px против ровных 44 у `<button>`. Разница
 * ползучая: на глаз читается как «кнопки съехали», а причина не в
 * кнопках. Некоторые файлы экранов задают это сами, но не все —
 * поэтому здесь, один раз, для всех. */
*, *::before, *::after { box-sizing: border-box; }

/* Сглаживание шрифта — та самая «яблочная» чёткость текста. Ставим на
   уровне html, чтобы работало на всех экранах без повторения. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body { font-family: var(--font-sans); }

/* Материал: полупрозрачная поверхность с размытием фона (шапка, поповеры).
   Требует фон под собой — сам по себе не «стекло», а стекло НАД контентом. */
.material {
  background: var(--material-bg);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
  border-color: var(--material-border);
}

/* ══ Кнопки ═════════════════════════════════════════════════════
   44px — минимальная цель для пальца. На десктопе это тоже
   комфортно, поэтому единая высота вместо «46 для мыши, 44 для
   пальца»: разница в 2 пиксела не улучшает ничего, а расхождение
   между экранами видно. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: 0 var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 600;
  /* Фиксированная межстрочность обязательна. Без неё <a class="btn">
     наследует line-height: normal и вырастает до 45,33px, а <button>
     остаётся 44 — «Заказать снова» была выше соседней кнопки на глаз. */
  line-height: 1;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t), border-color var(--t),
              transform var(--t), box-shadow var(--t), color var(--t);
}
/* Едва заметное «нажатие» — тактильность без прыжков размера. */
.btn:active:not(:disabled):not([aria-disabled='true']) { transform: scale(.985); }
.btn:disabled,
.btn[aria-disabled='true'] { opacity: .5; cursor: not-allowed; }

.btn-primary { background: var(--c-primary); color: var(--c-on-primary, #fff); }
.btn-primary:hover:not(:disabled) { background: var(--c-primary-hover); }
.btn-accent  { background: var(--c-accent-fill);  color: var(--c-on-accent, #fff); }
.btn-accent:hover:not(:disabled)  { background: var(--c-accent-fill-hover); }
.btn-ok      { background: var(--c-ok);      color: #fff; }
.btn-warn    { background: var(--c-warn);    color: #fff; }
/* Ghost — на hairline-рамке, при наведении рамка чуть плотнее. */
.btn-ghost   { background: var(--c-card); border-color: var(--c-border-strong); color: var(--c-fg); }
.btn-ghost:hover:not(:disabled) { border-color: var(--c-fg); }

/* Уменьшенная кнопка — только по бокам. Низкая кнопка это промах
   пальцем, и «компактность» не стоит потерянного нажатия. */
.btn-sm { padding: 0 var(--s-3); font-size: var(--fs-xs); }
.btn-block { width: 100%; }

/* ══ Поля ввода ═════════════════════════════════════════════════
   46px, а не 44: у поля внутри текст, и на 44 он визуально прижат
   к рамке. Разница заметна именно на полях, поэтому здесь она
   осмысленна — в отличие от кнопок. */
.field-h { height: 46px; }

/* Цвет текста в полях задаём ЯВНО, не полагаясь на наследование.
   Поле поиска стоит в тёмной шапке, где `color: #fff`, а фон у самого
   поля белый — текст наследовал белый и становился невидимым на белом,
   контраст 1.00:1. Пользователь: «печатаю в поле для ввода но не вижу
   свой текст».

   Ошибка тихая: пустое поле с плейсхолдером выглядит нормально, беда
   видна только когда человек начал печатать. Поэтому правило общее —
   любое поле на любом экране, где бы оно ни стояло. */
input, textarea, select {
  color: var(--c-fg);
  /* Safari и iOS раскрашивают текст в полях через text-fill-color,
     и он перебивает `color`: без этой строки на телефоне текст
     остался бы белым, хотя на десктопе всё выглядит верно. */
  -webkit-text-fill-color: var(--c-fg);
}
/* Выключенное поле — приглушённый текст, но всё ещё читаемый:
   продавец должен видеть, что там записано, даже если правка запрещена. */
input:disabled, textarea:disabled, select:disabled {
  color: var(--c-muted-fg);
  -webkit-text-fill-color: var(--c-muted-fg);
  opacity: 1;               /* iOS иначе гасит поле до 0.4 и текст пропадает */
}

/* ══ Свой список выбора ═════════════════════════════════════════
   Внутренность нативного `<select>` рисует операционная система —
   CSS туда не достаёт вообще. На Windows это серый список 11-м
   шрифтом, чужой рядом с остальным интерфейсом. Поэтому `select.js`
   прячет настоящий селект (оставляя его источником правды) и
   подставляет вот эту кнопку со своим выпадающим списком.

   Настоящий селект скрываем `clip-path`, а НЕ `display: none`:
   скрытый через display элемент выпадает из формы и перестаёт
   участвовать в валидации. Он должен остаться в потоке. */
/* Настоящий селект скрываем `clip-path`, а НЕ `display: none`:
   скрытый через display элемент выпадает из формы и перестаёт
   участвовать в валидации. Он должен остаться в потоке.

   `!important` здесь оправдан: файл экрана подключается ПОСЛЕ base.css
   и задаёт селектам свои размеры (`.sel { height: 40px }` на витрине).
   Без него скрытый селект оставался шириной 25px и занимал место
   в flex-строке — четыре невидимых огрызка рядом с кнопками. */
.pk-native {
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  min-width: 0 !important; max-width: 1px !important;
  flex: none !important;
  padding: 0 !important; border: 0 !important; margin: -1px !important;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  pointer-events: none;
}

.pk-btn {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
  /* Растём и сжимаемся по месту, но НЕ требуем 100% ширины.
     Кнопка встаёт туда, где был `<select>`, а тот бывает и в flex-строке
     (`.selects` на витрине), и в ячейке сетки (`.gr-field` в гараже).
     С `width: 100%` во flex-строке каждая кнопка требовала всю ширину
     и переносилась на свою строку — четыре селекта подбора встали
     столбиком. `flex-basis: 0` вместо auto: иначе длинная надпись вроде
     «Land Cruiser Prado» делала бы свою кнопку шире соседних. */
  flex: 1 1 0;
  height: 46px;                 /* как у поля ввода: стоят в одном ряду */
  padding: 0 var(--s-3);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-card);
  color: var(--c-fg);
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--t), box-shadow var(--t);
}
.pk-btn:hover:not(.is-disabled) { border-color: var(--c-muted-fg); }
.pk-btn[aria-expanded='true'] {
  border-color: var(--c-accent);
  box-shadow: var(--shadow-focus);
}

/* Текст занимает всё место и обрезается многоточием: «Land Cruiser
   Prado» на узком экране не должен выдавливать стрелку за край. */
.pk-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Подсказка «Выберите марку» — приглушённая, чтобы её не путали
   с выбранным значением. */
.pk-btn.is-empty .pk-text { color: var(--c-muted-fg); font-weight: 400; }

.pk-btn.is-disabled {
  background: var(--c-muted);
  color: var(--c-muted-fg);
  cursor: not-allowed;
}

/* Кнопка становится на место `<select>`, поэтому размер берёт у него.
   На витрине селекты подбора 40px и шрифтом 13px — они стоят в плотной
   строке фильтров, где 46px ломают ритм. Экран задаёт это своим классом
   на самом селекте, а кнопка подхватывает по соседству: писать высоту
   в каждом экранном файле пришлось бы четыре раза. */
.sel + .pk-btn { height: 40px; font-size: var(--fs-sm); }

/* Вне flex-строки `flex: 1 1 0` не действует, и кнопка сжимается до
   содержимого: «2020» занимает четверть поля, а рамка обрывается по
   тексту. Класс ставит `select.js`, глядя на display родителя — по
   именам классов перечислять нельзя, у каждого экрана они свои
   (`.gr-field` в гараже, `.of-field` в онбординге, и так далее). */
.pk-btn.is-block { width: 100%; flex: none; }

.pk-arrow {
  flex: none;
  width: 8px; height: 8px;
  border-right: 1.5px solid var(--c-muted-fg);
  border-bottom: 1.5px solid var(--c-muted-fg);
  transform: translateY(-2px) rotate(45deg);
}
.pk-btn[aria-expanded='true'] .pk-arrow {
  transform: translateY(2px) rotate(225deg);
}

/* ── Сам выпадающий список ──
   Лежит в `body`, position: absolute — иначе его обрезал бы
   `overflow` карточки, внутри которой стоит поле.

   Ширину задаёт скрипт по ширине поля, здесь её нет: `min-width`
   ломал совпадение — на мобильной витрине поле 159px, а список
   растягивался до 200 и торчал за край поля. Список шире своего
   поля читается как чужой элемент. */
.pk-pop {
  position: absolute;
  z-index: 60;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-card);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.pk-search {
  padding: var(--s-2);
  border-bottom: 1px solid var(--c-border);
  background: var(--c-bg, #F1F5F9);
}
.pk-input {
  width: 100%;
  height: 34px;
  padding: 0 var(--s-2);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm);
  background: var(--c-card);
  color: inherit;
  font: inherit;
  font-size: var(--fs-sm);
}

/* Высота списка ограничена, дальше прокрутка: 32 марки во весь экран
   превращают выбор в стену текста. */
.pk-list {
  max-height: 264px;
  overflow-y: auto;
  overscroll-behavior: contain;   /* прокрутка не «протекает» на страницу */
}

.pk-opt {
  padding: 9px var(--s-3);
  font-size: var(--fs-sm);
  line-height: 1.35;
  cursor: pointer;
  /* Длинные подписи двигателей («Электро 220 кВт (299 л.с.)»)
     переносим, а не обрезаем: по обрезанной строке нельзя выбрать. */
  overflow-wrap: anywhere;
}
/* Подсветка клавиатурой и мышью — одна и та же: человек не должен
   гадать, что выберется по Enter. */
.pk-opt.is-cur { background: var(--c-muted); }
.pk-opt.is-sel { font-weight: 600; }
.pk-opt.is-sel::after {
  content: '✓';
  float: right;
  margin-left: var(--s-2);
  color: var(--c-ok);
  font-weight: 700;
}
.pk-opt.is-off { color: var(--c-muted-fg); cursor: not-allowed; }

.pk-empty {
  margin: 0;
  padding: var(--s-3);
  color: var(--c-muted-fg);
  font-size: var(--fs-sm);
}
.pk-empty[hidden] { display: none; }

/* На телефоне пункты выше: 9px по вертикали дают цель 33px,
   а палец требует 44. На мышином экране такой размер лишний —
   в списке из 32 позиций он добавляет 350px прокрутки. */
@media (hover: none) and (pointer: coarse), (max-width: 720px) {
  .pk-opt { padding: 13px var(--s-3); }
  .pk-list { max-height: 60vh; }
}


/* ══ Числа ══════════════════════════════════════════════════════
   Табличные цифры обязательны для сумм, артикулов и таймеров:
   иначе «284 000» и «184 000» имеют разную ширину, колонка «дышит»,
   а глаз не может сравнить числа по вертикали. */
.num { font-variant-numeric: tabular-nums; }

/* Артикул — тоже табличными, плюс разрядка: «0 986 424 558» читают
   и диктуют по телефону, слипшиеся цифры для этого не годятся. */
.art { font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* ══ Метки состояния ════════════════════════════════════════════ */
.chip {
  display: inline-block;
  padding: 3px var(--s-2);
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
}
.chip-live   { background: var(--c-ok-bg);   color: var(--c-ok); }
.chip-wait   { background: var(--c-warn-bg); color: var(--c-warn); }
.chip-off    { background: var(--c-muted);   color: var(--c-muted-fg); }
.chip-hidden { background: var(--c-err-bg);  color: var(--c-err); }

/* ══ Фокус ══════════════════════════════════════════════════════
   Видимый фокус нужен всем интерактивным элементам: без него
   навигация с клавиатуры превращается в угадывание. Именно
   :focus-visible, а не :focus — иначе рамка появляется после
   каждого щелчка мышью и мешает. */
:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
}

/* ══ Ссылка «к содержимому» (WCAG 2.4.1) ════════════════════════
   Спрятана над экраном и выезжает только при получении фокуса: мышью
   её никто не увидит, а с клавиатуры она первая по Tab и позволяет
   не протабывать шапку с поиском и меню на каждой странице заново.
   `main` получает tabindex="-1" в разметке — без него фокус остаётся
   на самой ссылке, и следующий Tab уводит обратно в шапку. */
.skip-link {
  position: absolute;
  top: -60px;
  left: var(--s-3);
  z-index: 200;
  padding: 10px var(--s-4);
  border-radius: 0 0 var(--r-md) var(--r-md);
  background: var(--c-accent-fill);
  color: var(--c-on-accent);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: top .15s ease;
}

.skip-link:focus { top: 0; }

/* Цель перехода не должна получать рамку фокуса: она не интерактивна,
   рамка вокруг всей области содержимого выглядит поломкой. */
#main-content:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* ══ Шапка десктопных страниц покупателя ════════════════════════
   Лежит здесь, а не в desktop.css, потому что нужна на пяти экранах:
   витрина, карточка детали, корзина, заказы, гараж. Раньше её знал
   только desktop.css, а «Мои заказы» и «Гараж» его не подключают —
   и рисовали собственные .mo-header / .gr-header с ПОБАЙТОВО теми же
   правилами. Из-за этого при переходе с витрины в заказы менялся весь
   верх страницы: другая высота, другой фон, ссылки вместо кнопок.
   Правило проекта: в base.css попадает то, что встречается минимум
   на трёх экранах. */
/* Контейнер страницы. Тоже переехал из desktop.css — без него шапка
   на «Заказах» и в «Гараже» растеклась бы по всей ширине экрана. */
.wrap {
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 var(--s-4);
}

.top {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--material-bg);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
  border-bottom: 1px solid var(--c-border);
  color: var(--c-fg);
}

.top-in {
  height: var(--hdr-h);
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.logo {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--c-fg);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: var(--ls-tight);
  white-space: nowrap;
  text-decoration: none;
}

.logo-mark {
  width: 26px; height: 26px;
  flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--c-accent-fill);
}

.top-acts { display: flex; align-items: center; gap: var(--s-1); margin-left: auto; }

.icon-btn {
  position: relative;
  height: 40px; min-width: 40px;
  padding: 0 var(--s-3);
  display: inline-flex; align-items: center; gap: var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-fg);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--t), color var(--t);
}

.icon-btn:hover { background: var(--c-muted); }

/* Текущая страница отмечена явно: иначе в одинаковом ряду кнопок
   неясно, где ты находишься. */
.icon-btn[aria-current="page"] { background: var(--c-muted); font-weight: 600; }

.badge-count {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--c-accent-fill);
  color: var(--c-on-accent);
  font-size: 11px;
  font-weight: 700;
}

/* ══ Общие мелочи ═══════════════════════════════════════════════ */
[hidden] { display: none !important; }

/* Уважение к системной настройке: анимации отключены, но не
   переходы состояний целиком — иначе интерфейс начинает
   «прыгать» без объяснений. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══ Скидка ═══════════════════════════════════════════════════════
   Перечёркнутая старая цена и бейдж процента. В базовом слое, потому
   что появляются на шести экранах: обе витрины, обе карточки детали,
   оба кабинета. Красный намеренно «магазинный»: палитра совпадает с
   ошибочной, но именно её покупатель выучил как знак скидки на всех
   маркетплейсах — изобретать свою значило бы остаться непонятым. */
.price-old {
  color: var(--c-muted-fg);
  font-weight: 400;
  text-decoration: line-through;
}
.disc-badge {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--r-sm);
  background: var(--c-err-bg);
  color: var(--c-err);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
