/* =============================================================
   АйсФуд — интернет-магазин замороженных полуфабрикатов.
   Дизайн-система: тёмная тема по умолчанию, светлая по выбору.
   Фирменный синий из логотипа, острые углы, моноширинный шрифт
   на технических подписях.
   ============================================================= */

/* ---------- 1. Токены ---------------------------------------- */
:root {
  /* тёмная тема — основная */
  /* Нейтральная тёмная база. Синий подтон гасил золотистую корочку:
     тёплая еда на холодном фоне теряет насыщенность. Синий остался
     фирменным акцентом, но ушёл из нейтрали. */
  --bg:          #121212;
  --surface:     #1A1A1A;
  --surface-2:   #242424;
  --surface-3:   #2E2E2E;
  --line:        #2C2C2C;
  --line-soft:   #202020;
  /* граница элементов управления: WCAG 1.4.11 требует 3:1, а --line даёт 1.25 */
  --line-strong: #6A6A6A;
  --text:        #F0F0F0;
  --text-2:      #A8A8A8;   /* 8.2:1 на поверхности */
  --text-3:      #8E8E8E;   /* 4.7:1 на плитке категории, 5.3 на поверхности */

  --accent:      #35A8FF;   /* фирменный синий: текст, линии, иконки */
  --accent-btn:  #0072D8;   /* фон кнопок под белый текст, 4.8:1 */
  --accent-hi:   #005CB2;   /* ховер темнее базы: на #0090F0 белый текст давал 3.36 */
  --accent-soft: rgba(53,168,255,.14);
  --navy:        #001860;   /* тёмно-синий из логотипа */

  --hit:         #FFC53D;
  --new:         #1E7A42;   /* белый текст 5.37, было 3.22 */
  --sale:        #D4382D;   /* фон плашки под белым текстом, 4.82 */
  --sale-text:   #FF8A7E;   /* тот же смысл, но как ТЕКСТ на поверхности */
  --ok:          #3FA96A;
  --danger:      #FF8F84;   /* текст ошибок на тёмном */

  --shadow:      0 18px 44px rgba(0,0,0,.45);
  --shadow-lift: 0 22px 48px rgba(0,0,0,.5), 0 0 0 1px rgba(53,168,255,.28);
  /* было два синих пятна во весь экран — они и красили страницу в синий */
  --glow-a:      rgba(255,170,80,.055);
  --glow-b:      rgba(0,0,0,.40);
  --grain:       .026;
  /* тёплая подсветка под золотистым продуктом — она и делает еду аппетитной */
  --warm:        rgba(255,168,56,.22);

  --ph-fall:
    radial-gradient(58% 46% at 50% 70%, rgba(255,168,56,.16), transparent 72%),
    linear-gradient(168deg, #262626 0%, #171717 100%);

  /* шрифты: Rubik — заголовки и цены, Onest — весь остальной текст.
     Моноширинного больше нет: он читался технично и холодил еду. */
  --f-display: 'Rubik', system-ui, sans-serif;
  --f-body:    'Onest', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-label:   'Onest', system-ui, sans-serif;

  /* шкала */
  /* Скругления одной шкалой. Было 2 и 4px — интерфейс читался как
     набор острых прямоугольников; плюс по файлу гуляли случайные
     6, 9, 12, 13, 14, 15px. Теперь три ступени и пилюля. */
  --r-sm:   6px;    /* мелочь: галочки, пункты списков */
  --r:      10px;   /* по умолчанию: кнопки, поля, карточки */
  --r-lg:   16px;   /* крупные поверхности: панели, плитки, сводки */
  --r-pill: 999px;
  --pad:  clamp(16px, 3.6vw, 48px);
  --max:  1440px;
  --gap:  clamp(12px, 1.4vw, 20px);
  --ease: cubic-bezier(.22,.61,.36,1);
  --hdr:  71px;    /* высота липкой шапки */
}

:root[data-theme="light"] {
  /* Страница ровно белая: раньше фон #F4F2F0 чередовался с белыми
     блоками, и светлая тема выглядела пятнистой. */
  --bg:          #FFFFFF;
  --surface:     #FFFFFF;
  --surface-2:   #F3F0EC;
  --surface-3:   #E7E2DB;
  --line:        #DCD8D4;
  --line-soft:   #EAE7E4;
  --line-strong: #8E8E8E;
  --text:        #141414;
  --text-2:      #5A5A5A;   /* 7.0:1 на белом */
  --text-3:      #6A6A6A;   /* 4.8:1 на плитке категории, 5.4 на белом */

  --accent:      #0063BE;
  --accent-btn:  #0072D8;
  --accent-hi:   #005AAE;
  --accent-soft: rgba(0,114,216,.10);
  --danger:      #A32217;   /* текст ошибок на белом: 7.47, было 2.21 */
  --sale-text:   #B3271B;   /* «Скидка» как текст на белом */
  --ok:          #14783B;   /* «В наличии» на белом: 5.56, было 2.96 */

  --shadow:      0 14px 34px rgba(12,19,23,.10);
  --shadow-lift: 0 18px 38px rgba(12,40,70,.14), 0 0 0 1px rgba(0,114,216,.22);
  /* чёрное свечение и зерно и делали белую тему серой */
  --glow-a:      rgba(255,170,80,.05);
  --glow-b:      rgba(255,170,80,.03);
  --grain:       0;
  --warm:        rgba(255,150,20,.16);

  --ph-fall:
    radial-gradient(58% 46% at 50% 70%, rgba(255,150,20,.13), transparent 72%),
    linear-gradient(168deg, #FBF8F5 0%, #EAE4DD 100%);
}

/* ---------- 2. Сброс ----------------------------------------- */
/* Сообщаем браузеру, какая схема активна: иначе выпадающие списки
   <select>, скроллбары и автозаполнение рисуются светлыми поверх тёмной темы. */
:root { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--f-body);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* Два фирменных свечения на фоне и зерно поверх: убирают ощущение
   плоской заливки, но не мешают читать текст. */
body::before {
  content: ''; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(58% 40% at 12% 0%, var(--glow-a), transparent 68%),
    radial-gradient(52% 44% at 92% 24%, var(--glow-b), transparent 70%);
}
body::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: var(--grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
h1, h2, h3, h4 { font-weight: 600; line-height: 1.12; letter-spacing: -.02em; }
s { color: var(--text-3); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* цель якорной ссылки не должна прятаться под липкую шапку */
#main, [id] { scroll-margin-top: calc(var(--hdr) + 12px); }
@media (max-width: 760px) {
  /* шапка становится двухэтажной: 44 (кнопки) + 10 + 42 (поиск) + 16 */
  :root { --hdr: 113px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ---------- 3. Типографика ----------------------------------- */
/* Заголовки уступают дорогу товару. Раньше самым громким элементом
   экрана был заголовок секции, а не еда — вес 800 при отрицательном
   трекинге перекрикивал витрину. */
.display { font-family: var(--f-display); font-weight: 800; font-size: clamp(2.1rem, 4.8vw, 3.8rem); line-height: 1; letter-spacing: -.03em; }
.h1 { font-family: var(--f-display); font-weight: 700; font-size: clamp(1.7rem, 3.2vw, 2.5rem); line-height: 1.08; letter-spacing: -.022em; }
.h2 { font-family: var(--f-display); font-weight: 700; font-size: clamp(1.55rem, 2.9vw, 2.5rem); line-height: 1.08; letter-spacing: -.028em; }
.h3 { font-family: var(--f-display); font-size: clamp(1rem, 1.3vw, 1.14rem); font-weight: 600; letter-spacing: -.01em; }
.lead { font-size: clamp(1rem, 1.15vw, 1.12rem); line-height: 1.55; color: var(--text-2); max-width: 60ch; }
.muted { color: var(--text-2); }
.prose { max-width: 68ch; color: var(--text-2); }
/* .wrap объявлен позже и при равной специфичности перебивал max-width */
.wrap.prose { max-width: 68ch; }
.prose p + p { margin-top: 1em; }
/* подпись: не моноширинный, а Onest в верхнем регистре с разрядкой */
.mono { font-family: var(--f-label); font-size: .75rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.num { font-variant-numeric: tabular-nums; }

/* ---------- 4. Раскладка ------------------------------------- */
.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--pad); }
/* Между блоками должно быть заметно больше воздуха, чем внутри них —
   иначе страница читается сплошной лентой без группировки. */
.section { padding-block: clamp(44px, 6vw, 96px); }
.section + .section { padding-top: 0; }
.rule { border-top: 1px solid var(--line); }

/* заголовок секции: название слева, ссылка «все» справа */
/* Заголовок слева, ссылка справа, между ними пусто. Тонкая линия
   тут была, но читалась как случайная царапина, а не как приём. */
.shead {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: baseline; gap: 18px;
  margin-bottom: clamp(22px, 2.8vw, 38px);
}
.shead > .h2      { grid-column: 1; }
.shead > .shead__all { grid-column: 3; }
@media (max-width: 560px) {
  .shead { grid-template-columns: 1fr auto; }
}
/* засечка-градиент слева убрана: лишний декор рядом с заголовком */
.shead__all {
  color: var(--text-2); border: 0; white-space: nowrap;
  font-size: .88rem; display: inline-flex; align-items: center; gap: 7px;
  transition: color .2s var(--ease);
  position: relative;
}
/* Строка в 23px — мелкая цель для пальца. Растим зону нажатия
   накладкой: высота строки и выравнивание с заголовком не меняются. */
.shead__all::before { content: ''; position: absolute; left: -8px; right: -8px; top: -11px; bottom: -11px; }
.shead__all::after { content: '→'; font-size: 1.05em; line-height: 1; }
.shead__all:hover { color: var(--accent); }

/* ---------- 5. Фотослот -------------------------------------- */
/* Фотослот. Реальный кадр подставляется инлайновым background-image
   ВМЕСТЕ с --ph-fall: url() обязан быть записан в самой странице, иначе
   браузер разрешит относительный путь от CSS-файла, а не от документа.
   Нет файла — не рисуется верхний слой, остаётся ледяная заглушка. */
.ph {
  position: relative;
  background-color: var(--surface-2);
  background-image: var(--ph-fall);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  overflow: hidden;
}
/* Диагональной штриховки («иней» поверх слота) здесь больше нет.
   Она задумывалась как текстура пустого слота, но лежала и на
   фотографиях еды — на карточках её сняли сразу, на плитках
   категорий она дожила до жалобы заказчика. Пустой слот и без неё
   выглядит как надо: тёплая подложка --ph-fall. */

/* ---------- 6. Кнопки ---------------------------------------- */
.btn {
  --bg-b: var(--surface-2); --fg-b: var(--text); --bd-b: var(--line);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 20px;
  background: var(--bg-b); color: var(--fg-b); border: 1px solid var(--bd-b);
  border-radius: var(--r);
  /* Строчные, а не капс вразрядку: капсом надпись читается по буквам,
     а не словом, и на длинной кнопке растягивается в ленту. Тот же
     приём уже был у кнопки «В корзину» — теперь он общий. */
  font-family: var(--f-label); font-size: .88rem; font-weight: 600;
  letter-spacing: 0; text-transform: none; white-space: nowrap;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .1s var(--ease);
}
.btn:hover { --bd-b: var(--accent); --fg-b: var(--accent); }
.btn:active { transform: translateY(1px); }
.btn--accent {
  /* Ровная заливка без градиента, блика и цветного свечения. Втроём
     они давали кнопке вид готового шаблона и спорили с фотографиями
     еды, ради которых страница и сделана. Отличать кнопку хватает
     цвета: он единственный такой на странице.
     При наведении заливка ТЕМНЕЕ, а не светлее: светлый синий не даёт
     белому тексту нужного контраста. */
  --bd-b: transparent; --fg-b: #fff;
  background: var(--accent-btn);
}
.btn--accent:hover { --fg-b: #fff; background: var(--accent-hi); }
.btn--ghost { --bg-b: transparent; }
.btn--wide { width: 100%; }
.btn svg { width: 14px; height: 14px; flex: none; }
.btn:disabled, .btn[disabled] {
  opacity: .45; cursor: not-allowed; box-shadow: none;
  filter: grayscale(.6);            /* заливка задана напрямую, opacity мало */
}
.btn:disabled:hover, .btn[disabled]:hover { transform: none; box-shadow: none; filter: grayscale(.6); }

/* кнопка «В корзину» на карточке */
/* кнопка не должна кричать громче цены: строчные вместо капса, ровный фон */
.btn--buy {
  --bd-b: transparent; --fg-b: #fff;
  background: var(--accent-btn); box-shadow: none;
  min-height: 38px; padding: 0 16px;
  font-size: .82rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  border-radius: var(--r);
}
.btn--buy:hover { --fg-b: #fff; background: var(--accent-hi); box-shadow: none; }
/* .btn--buy задаёт background напрямую, поэтому одной сменой --bg-b
   заливку не убрать: зелёный текст оставался на синем градиенте (1.61:1) */
.btn--incart, .btn--incart:hover {
  --bg-b: transparent; --bd-b: var(--ok); --fg-b: var(--ok);
  background: transparent; box-shadow: none;
}

/* нажатое состояние для кнопок-переключателей (избранное на карточке товара) */
.btn[aria-pressed="true"] {
  --bg-b: var(--accent-soft); --bd-b: var(--accent); --fg-b: var(--accent);
  background: var(--accent-soft); box-shadow: none;
}

/* ---------- 7. Шапка ----------------------------------------- */
/* Черты под шапкой нет. Когда страница прокручена, шапка лежит
   поверх содержимого — её край обозначает тень (см. .is-stuck), и
   этого достаточно. Черта же ложилась светлой полоской поперёк
   баннера и дублировала ту же тень. */
.header { position: sticky; top: 0; z-index: 60; background: var(--bg); }
.header__in { display: flex; align-items: center; gap: clamp(10px, 1.4vw, 18px); min-height: 70px; }

.logo { display: inline-flex; align-items: center; gap: 9px; flex: none; position: relative; }
/* Картинка логотипа 24px в высоту, а это ссылка «на главную» — пальцем
   попасть трудно. Растим зону нажатия, не трогая саму картинку. */
.logo::before { content: ''; position: absolute; left: -6px; right: -6px; top: -10px; bottom: -10px; }
.logo__img { height: 30px; width: auto; display: block; }
/* Логотип «АйсФуд 76» синий: «Фуд 76» тёмно-синий и на тёмной шапке тонет.
   Для тёмной темы — осветлённая версия, для светлой — оригинал. */
.logo--dark { display: none; }
:root[data-theme="dark"] .logo--light,
:root:not([data-theme="light"]) .logo--light { display: none; }
:root[data-theme="dark"] .logo--dark,
:root:not([data-theme="light"]) .logo--dark { display: block; }
@media (max-width: 760px) { .logo__img { height: 24px; } }

/* кнопка каталога — главный вход в товары */
.catbtn {
  display: inline-flex; align-items: center; gap: 9px; flex: none;
  min-height: 42px; padding: 0 18px; border-radius: var(--r);
  background: var(--accent-btn); color: #fff; font-weight: 600; font-size: .93rem;
  transition: background .2s var(--ease);
}
.catbtn:hover { background: var(--accent-hi); }
.catbtn__ic { display: grid; gap: 3px; }
.catbtn__ic i { display: block; height: 1.5px; background: #fff; border-radius: 1px; }
.catbtn__ic i:nth-child(1) { width: 14px; }
.catbtn__ic i:nth-child(2) { width: 10px; }
.catbtn__ic i:nth-child(3) { width: 14px; }

.nav { display: flex; gap: clamp(10px, 1.3vw, 20px); }
/* Радиус нужен не самой ссылке — фону у неё нет. Его берёт рамка
   фокуса: outline повторяет border-radius элемента, а при нулевом
   радиусе она вставала острым прямоугольником посреди шапки, где всё
   остальное скруглено. */
.nav a { font-size: .93rem; white-space: nowrap; padding-block: 6px; border-radius: var(--r); color: var(--text-2); transition: color .18s; }
.nav a:hover, .nav a[aria-current="page"] { color: var(--accent); }

.search { position: relative; flex: 1 1 220px; min-width: 0; }
.search input {
  width: 100%; min-height: 42px; padding: 0 14px 0 38px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); color: var(--text);
  transition: border-color .2s;
}
.search input::placeholder { color: var(--text-3); }
.search input:focus { outline: none; border-color: var(--accent); }
.search svg { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--text-3); }

.hactions { display: flex; align-items: center; gap: clamp(6px, 1vw, 14px); flex: none; }
/* Коробка тут 60×57 — заметно выше кнопок каталога и города (42px).
   Одни и те же 10px на ней читаются куда острее, и подложка при
   наведении выглядела квадратом. Берём следующий радиус по шкале —
   на этой высоте он даёт ту же округлость, что 10px на 42px. */
.hact { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-width: 60px; min-height: 54px; padding: 5px 4px; border-radius: var(--r-lg); color: var(--text-2); transition: color .18s var(--ease), background .18s var(--ease); }
.hact:hover { color: var(--accent); background: var(--surface-2); }
.hact svg { width: 25px; height: 25px; }
.hact span { font-size: .7rem; letter-spacing: .01em; }
.hact__n {
  position: absolute; top: 1px; right: 8px; min-width: 19px; height: 19px; padding: 0 5px;
  background: var(--accent-btn); color: #fff; border-radius: var(--r-pill);
  font-family: var(--f-label); font-size: .64rem; font-weight: 700;
  display: grid; place-items: center;
}
@media (max-width: 1080px) { .hact span { display: none; } .hact { min-width: 46px; min-height: 46px; } }

/* переключатель темы */
.theme {
  width: 52px; height: 26px; flex: none; border-radius: var(--r-pill);
  background: var(--surface-2); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; padding: 0 6px;
  position: relative;
}
/* Сам тумблер остаётся 52x26, но зона нажатия расширена до 44px по высоте:
   менять padding нельзя — он задан ниже в этом же правиле и перебивает. */
.theme::before {
  content: ''; position: absolute; left: 0; right: 0; top: -9px; bottom: -9px;
}
/* position нужен: z-index на статическом элементе не работает,
   и ползунок ::after полностью закрывал активную иконку */
.theme svg {
  position: relative; width: 13px; height: 13px; z-index: 1;
  color: var(--text-3); transition: color .2s var(--ease);
}
/* Иконка под ползунком — белая: ползунок синий, серое на нём не читалось.
   Первая svg — луна (тёмная тема), вторая — солнце (светлая). */
.theme svg:first-of-type { color: #fff; }
:root[data-theme="light"] .theme svg:first-of-type { color: var(--text-3); }
:root[data-theme="light"] .theme svg:last-of-type { color: #fff; }
.theme::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px;
  border-radius: 50%; background: var(--accent-btn);
  transition: transform .26s var(--ease);
}
:root[data-theme="light"] .theme::after { transform: translateX(26px); }

.burger { display: none; width: 42px; height: 42px; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: var(--r); }
.burger span { display: block; width: 17px; height: 1.5px; background: var(--text); position: relative; transition: background .2s; }
.burger span::before, .burger span::after { content: ''; position: absolute; left: 0; width: 17px; height: 1.5px; background: var(--text); transition: transform .25s var(--ease), top .25s var(--ease); }
.burger span::before { top: -5px; } .burger span::after { top: 5px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.burger[aria-expanded="true"] span::after { top: 0; transform: rotate(-45deg); }

/* Бургер появляется РОВНО тогда, когда прячется меню. Раньше в полосе
   761–1180px не было ни того, ни другого: навигация была недостижима. */
@media (max-width: 1180px) {
  .nav { display: none; }
  .burger { display: inline-flex; }
}
@media (max-width: 760px) {
  .header__in { min-height: 58px; gap: 10px; flex-wrap: wrap; padding-block: 8px; }
  /* Кнопка «Каталог» без подписи превращалась в те же три полоски, что и
     бургер рядом: две одинаковые кнопки, и какая что открывает — понятно
     только после нажатия. На телефоне она лишняя: категории целиком лежат
     в бургер-меню, а внизу есть вкладка «Каталог». */
  .catbtn { display: none; }
  .hactions .hact { display: none; }
  /* Вправо группу прижимали поиск и навигация, а на телефоне они
     отсюда убраны — она липла к логотипу, и справа пустовало 52px. */
  .hactions { margin-left: auto; }
  /* поиск переезжает на свою строку: он единственный сжимаемый элемент
     шапки и на 360px схлопывался до одной лупы */
  .search { order: 10; flex: 1 0 100%; }
}

/* мобильное меню */
.mnav {
  position: fixed; inset: 0 0 0 auto; z-index: 90;
  /* 340px были шире содержимого: самому длинному названию из пятнадцати
     («Пельмени, вареники и хинкали») нужно 247px, и справа пустовало
     полсотни пикселей, а у среднего пункта — полторы сотни.
     284 = 247 на текст, 24 на поля и небольшой запас. */
  width: min(86vw, 284px);
  background: var(--surface);
  /* Боковой отступ свой, а не общий --pad страницы: тот растёт до 48px
     на широких экранах, и в шторке шириной 340px на поля уходила
     четверть ширины. 12px — названия ближе к краям. */
  padding: 20px 12px 100px;
  transform: translateX(100%); visibility: hidden;
  /* visibility переключаем мгновенно на открытии и с задержкой на закрытии:
     если её плавно «переходить», меню становится видимым не сразу,
     а на страницах без анимации кадров вообще залипает скрытым */
  transition: transform .3s var(--ease), visibility 0s linear .3s;
  display: flex; flex-direction: column; gap: 2px; overflow-y: auto;
  border-left: 1px solid var(--line);
}
/* visibility, а не только сдвиг: иначе закрытое меню остаётся
   в порядке табуляции и с клавиатуры можно уехать за экран */
.mnav[data-open="true"] { transform: none; visibility: visible; transition: transform .3s var(--ease), visibility 0s; }
.mnav a { font-size: 1.02rem; font-weight: 500; padding: 12px 0; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
/* Пятнадцать категорий подряд читаются как список без начала и конца —
   разделяем их теми же двумя группами, что и в каталоге. */
.mnav__t {
  font-family: var(--f-label); font-size: .7rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-3);
  padding: 18px 0 6px;
}
.mnav__t:first-child { padding-top: 0; }
.mnav a:hover { color: var(--accent); }
.mnav__foot { margin-top: 20px; display: grid; }
.mnav__foot a { border: 0; padding: 9px 0; font-size: .95rem; color: var(--text-2); min-height: 44px; }
.scrim { position: fixed; inset: 0; z-index: 80; background: rgba(0,0,0,.55); opacity: 0; visibility: hidden; transition: opacity .28s; }
.scrim[data-open="true"] { opacity: 1; visibility: visible; }

/* ---------- 8. Нижняя панель на мобильном -------------------- */
.tabbar {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 75;
  background: var(--surface); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
/* Пять пунктов: к навигации и корзине добавился профиль — на
   телефоне попасть в кабинет было больше неоткуда, ссылка пряталась
   в бургер-меню под восемнадцатью категориями. */
.tabbar__in { display: grid; grid-template-columns: repeat(5, 1fr); }
/* На 375px каждому пункту достаётся 75px. Подпись держим в одну
   строку: перенос «Избранного» ломал бы высоту всей панели. */
.tabbar a { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 56px; padding-inline: 2px; color: var(--text-2); font-size: .6rem; white-space: nowrap; }
.tabbar a[aria-current="page"], .tabbar a:hover { color: var(--accent); }
.tabbar svg { width: 21px; height: 21px; }
/* В шапке значок стоит рядом с иконкой 24px и там 19px уместны.
   В нижней панели иконка 21px, и тот же значок закрывал её почти
   целиком — 90% от её высоты. Здесь он меньше и садится на угол. */
.tabbar .hact__n {
  top: 5px; right: calc(50% - 14px);
  min-width: 15px; height: 15px; padding: 0 4px;
  font-size: .56rem;
}
@media (max-width: 760px) {
  .tabbar { display: block; }
  /* Значок reCAPTCHA прибит к правому нижнему углу и на телефоне
     ложится прямо на нижнюю панель. Поднимаем его над ней.
     !important здесь неизбежен: положение Google задаёт
     инлайновым стилем, обычное правило его не перебивает. */
  .grecaptcha-badge { bottom: 72px !important; }
  body { padding-bottom: 60px; }
}

/* ---------- 9. Баннеры --------------------------------------
   Слайды показывают картинку целиком: готовый широкий баннер идёт
   как <img> во всю ширину, товарные фото — во второй колонке
   с object-fit: contain. Ничего не обрезается ни на одной ширине.
   ------------------------------------------------------------- */
.hero { position: relative; background: #101010; }

/* Баннер уходит под шапку: она лежит на нём, а не стоит над ним.
   Отрицательный отступ ровно в высоту шапки — картинка начинается
   у самого верха страницы. */
/* Герой лежит внутри <main>, поэтому соседним селектором от шапки его
   не достать — класс ставится прямо на блок.

   Приём работает только на широких экранах. Ниже 900px шапка становится
   двухэтажной (111px), а баннер там всего ~145px в высоту — она бы его
   целиком и съела. На телефоне обычная шапка над обычным баннером. */
@media (min-width: 901px) {
  .hero--top { margin-top: calc(var(--hdr) * -1); }

  /* Затемнение под шапкой, иначе её текст теряется на светлых участках
     фотографии. Поверх слайдов, но под точками и подписями.

     Силу задаёт самый светлый кадр. У «Плоского стаканчика» верх почти
     белый (251,222,198), и на прежних .62/.28 белые ссылки навигации
     давали 3.93:1 — ниже нормы 4.5:1. На .72/.34 выходит 4.9:1, а на
     остальных кадрах и так было от 7:1. Затемнение кончается на 117px,
     впечатанные в баннеры заголовки начинаются ниже — их не задевает. */
  .hero--top::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0;
    height: calc(var(--hdr) + 46px); z-index: 3; pointer-events: none;
    background: linear-gradient(180deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.34) 55%, transparent 100%);
  }
}
.hero__stage { position: relative; }

.hero__track {
  display: flex; align-items: flex-start; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  transition: height .32s var(--ease);
  cursor: grab; touch-action: pan-y pinch-zoom;
}
.hero__track:active { cursor: grabbing; }
.hero__dots { user-select: none; }
.hero__track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.hero__track.is-dragging a, .hero__track.is-dragging img { pointer-events: none; }
.hero__track::-webkit-scrollbar { display: none; }
/* Трек берёт высоту самого высокого слайда, поэтому короткие слайды
   надо растянуть — иначе под ними зияла полоса в 52px. */
.hero__slide { flex: 0 0 100%; scroll-snap-align: start; position: relative; display: flex; align-items: center; align-self: stretch; }
.hero__slide--plain { align-items: center; justify-content: center; }

/* слайд с готовым баннером — текст уже впечатан в кадр */

.hero__banner { width: 100%; height: auto; display: block; }
/* На телефоне баннер 1920x743 растягивается во всю ширину и даёт полосу
   в 145px — рядом с остальной страницей это выглядит мелко, а надписи
   на кадре нечитаемы. Подрезаем до 2.2:1 (170px, содержимое крупнее
   примерно на пятую часть).
   Привязка строго к левому краю: заголовок у всех четырёх баннеров
   слева, при center он обрезается («ЛОСКИЙ ТАКАНЧИК»). Дальше 2.2
   уводить нельзя: у эскимо начинает уходить пачка справа.
   По-хорошему тут нужны отдельные мобильные кадры от дизайнера. */
@media (max-width: 760px) {
  .hero__banner {
    aspect-ratio: 2.2 / 1;
    object-fit: cover;
    object-position: left center;
  }
}
/* Слайды разной высоты: трек подгоняется под активный (см. app.js),
   поэтому баннер везде показывается целиком, без обрезки. */

/* слайд «текст + товар» */
/* В светлой теме этот слайд был голубым, и белый текст шапки на нём
   не читался. Герой теперь тёмный всегда — как сцена, независимо от
   темы страницы. Заодно карусель перестала мигать светлым и тёмным. */

/* На телефоне слайды должны быть примерно одной высоты. Трек берёт
   высоту самого длинного, а текстовый слайд в одну колонку вырастал
   до 406px при баннере в 145px — под баннером зияло 260px пустоты.
   Ставим текст и фото в две колонки и убираем абзац: на 375px он всё
   равно занимал шесть строк, а его смысл повторяет заголовок. */

/* Точки лежат на самом кадре, а не на полосе под ним: полоса
   добавляла тёмный пустой пояс между баннером и содержимым. */
.hero__dots {
  position: absolute; left: 0; right: 0; bottom: 4px; z-index: 5;
  display: flex; gap: 7px; justify-content: center; align-items: center;
  padding: 0;
  /* полоса точек лежит поверх баннера и перехватывала нажатия по нему;
     ловят только сами точки */
  pointer-events: none;
}
/* тап-зона 30x43 вместо полоски в 3px */
/* Отступы разные: сверху 30px нужны только для пальца, снизу 10 —
   иначе точки уезжают от нижнего края кадра. Раньше было 20/20, и
   вместе с bottom: 14px точки висели в 35px от низа. Теперь в 15px. */
.hero__dots button { width: 30px; height: auto; padding: 30px 0 10px; background: none; pointer-events: auto; }
.hero__dots button::before {
  content: ''; display: block; width: 30px; height: 3px; border-radius: 2px;
  /* поверх фотографии ориентир — белый, а не серый цвет разделителей */
  background: rgba(255,255,255,.42);
  box-shadow: 0 1px 3px rgba(0,0,0,.45);
  transition: background .2s var(--ease);
}
.hero__dots button:hover::before { background: rgba(255,255,255,.7); }
.hero__dots button[aria-current="true"]::before { background: #fff; }

/* ---------- 10. Плитки категорий ----------------------------- */
.cats { display: grid; gap: var(--gap); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 620px)  { .cats { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .cats { grid-template-columns: repeat(4, 1fr); } }
.cat {
  position: relative; display: block; border: 0; border-radius: var(--r-lg);
  overflow: hidden; min-height: 190px;
  /* Подложку рисует плитка целиком, а не фотослот в своих границах:
     иначе по нижнему краю слота видна ровная горизонтальная линия —
     там кончается один фон и начинается другой. */
  background-color: var(--surface-2);
  background-image: var(--ph-fall);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.cat .ph { transition: transform .6s var(--ease); }
.cat__name { transition: color .22s var(--ease); }
/* Подпись внизу, а не сверху: взгляд идёт по фото и приходит к
   названию, а не спотыкается о текст поверх еды. */
.cat__name {
  position: absolute; left: 20px; right: 20px; bottom: 20px; z-index: 2;
  font-family: var(--f-display); font-size: clamp(.98rem, 1.2vw, 1.14rem);
  font-weight: 700; line-height: 1.2; letter-spacing: -.022em;
}
.cat .ph {
  position: absolute; inset: 0 0 34% 0;
  /* фото товара с прозрачным фоном — показываем целиком, не режем */
  background-size: contain;
  background-position: center 58%;
  /* Слот держит только кадр. Подложку он не рисует: её значение
     гасим прямо здесь, и второй слой inline-стиля становится none. */
  --ph-fall: none;
  background-color: transparent;
}
/* Раньше плёнка лежала на всём кадре и гасила еду. Теперь растушёвка
   только снизу — ровно там, где под ней текст. */
.cat::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 62%;
  background: linear-gradient(180deg, transparent 0%, var(--surface-2) 62%);
}
:root[data-theme="light"] .cat::after {
  background: linear-gradient(180deg, transparent 0%, var(--surface-2) 62%);
}
.cat__name { z-index: 2; }


/* три крупные плитки категорий */
.cats.cats--3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.cat--big { min-height: 260px; }
@media (min-width: 700px) { .cat--big { min-height: 340px; } }
.cat--big .cat__name { font-size: clamp(1.02rem, 1.35vw, 1.28rem); max-width: 18ch; }

/* плитка без фото — текстовый блок «почему мы» */
.cat--flat { min-height: 0; padding: 24px; display: grid; gap: 9px; align-content: start; background: var(--surface-2); }
.cat--flat::after { display: none; }
.cat--flat .cat__t { font-family: var(--f-display); font-weight: 700; font-size: 1.02rem; letter-spacing: -.02em; }
.cat--flat p { color: var(--text-2); font-size: .89rem; line-height: 1.55; }


/* слайд с готовым баннером: текст уже впечатан в кадр */
.hero__slide--plain::before { display: none; }

/* ---------- 11. Карточка товара ------------------------------ */
/* minmax(0, 1fr), а не 1fr: у 1fr нижняя граница — min-content, то есть
   самое длинное слово в названии товара. На 320px пара колонок требовала
   305px при 288 доступных, и сетка вылезала за контейнер — заметно было
   только по обрезанному краю, потому что body прячет горизонтальную
   прокрутку. */
.pgrid { display: grid; gap: var(--gap); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px)  { .pgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .pgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1360px) { .pgrid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* Лента товаров.
   Ширину карточки задаём от числа колонок, а не от числа товаров:
   раньше на десктопе стоял auto-fit, и лента из десяти позиций
   ужимала карточку до 101px, а соседняя лента из семи — до 152px.
   На одной странице выходило три разных размера.
   Теперь колонок столько же, сколько в сетке каталога, а остальное
   уезжает вбок. --peek оставляет край следующей карточки видимым,
   иначе не понять, что ленту можно листать. */
.rail {
  --cols: 2;
  --peek: 26px;
  display: grid; grid-auto-flow: column;
  grid-auto-columns: calc((100% - var(--peek) - (var(--cols) - 1) * var(--gap)) / var(--cols));
  gap: var(--gap);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-left: 0;
  padding-bottom: 6px; scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; min-width: 0; }
@media (min-width: 700px)  { .rail { --cols: 3; --peek: 32px; } }
@media (min-width: 1100px) { .rail { --cols: 4; } }
@media (min-width: 1360px) { .rail { --cols: 5; } }

/* Полосу прокрутки под лентой не показываем: листают перетаскиванием
   и колесом (app.js), а полоса только занимала место — и вместе с ней
   в системном оформлении вылезали кнопки-стрелки по краям.
   Что справа есть ещё товары, видно по краю следующей карточки (--peek). */
@media (hover: hover) and (pointer: fine) {
  .rail {
    /* Мышью ленту тащат и крутят колесом. Привязка к карточкам при этом
       только мешает: она возвращает прокрутку назад на каждом щелчке
       колеса. Пальцу привязка остаётся — там она к месту. */
    scroll-snap-type: none;
    cursor: grab;
  }
  .rail.is-dragging { cursor: grabbing; user-select: none; }
  /* Лента обрезает по всем четырём сторонам: overflow-x: auto делает её
     контейнером прокрутки. При наведении карточка поднимается на 4px,
     а фото растёт на 5% — уходит на 6.8px вбок. Срезало и то, и тень.
     Даём запас со всех сторон и снимаем его отрицательным полем:
     лента раздаётся до краёв обёртки, содержимое остаётся на месте.
     Только здесь: пальцем карточка не поднимается, а на узком экране
     запас сверху наезжал на заголовок. */
  .rail {
    padding-top: 28px; margin-top: -28px;
    padding-inline: var(--pad); margin-inline: calc(var(--pad) * -1);
  }
}

/* Товар лежит на странице, а не в коробке: рамка и заливка карточки
   читались как элемент интерфейса и спорили с самим продуктом.
   Подложка осталась только под фотографией. */
.card {
  position: relative; display: flex; flex-direction: column;
  background: transparent; border: 0; border-radius: 0;
  transition: transform .28s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-4px); }
  .card:hover .card__ph { box-shadow: var(--shadow-lift); }
  .card:hover .card__ph { transform: scale(1.05); }
  .cat:hover { border-color: transparent; transform: translateY(-4px); box-shadow: var(--shadow-lift); }
  .cat:hover .ph { transform: scale(1.06); }
  .cat:hover .cat__name { color: var(--accent); }
  
}
/* тёплое свечение под продуктом: фото прозрачные, подложка — наша */
.card__ph,
.pdp__main,
.cline .ph {
  --ph-fall:
    radial-gradient(56% 48% at 50% 66%, var(--warm), transparent 72%),
    linear-gradient(168deg, #2A2A2A 0%, #161616 100%);
}
/* Товар показываем целиком (полей вокруг продукта в файлах почти нет).
   Фото карточки и главное фото товара лежат в <img>: фоновую картинку
   поиск по картинкам не индексирует, а снимок продукта — как раз то,
   по чему товар и находят. background-size остался строке корзины,
   где снимок декоративный. */
.pdp__main, .cline .ph {
  background-size: contain;
  background-position: center 62%;
}
.pdp__main img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center 62%;
}

:root[data-theme="light"] .card__ph,
:root[data-theme="light"] .pdp__main,
:root[data-theme="light"] .cline .ph {
  --ph-fall:
    radial-gradient(56% 48% at 50% 66%, var(--warm), transparent 72%),
    linear-gradient(168deg, #FFFFFF 0%, #EFEAE4 100%);
}

.card__tags { position: absolute; top: 6px; left: 6px; z-index: 3; display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.tag { font-family: var(--f-label); font-size: .66rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 3px 8px; border-radius: var(--r-pill); color: #121212; box-shadow: 0 3px 10px rgba(0,0,0,.28); }
.tag--hit  { background: var(--hit); }
.tag--new  { background: var(--new); color: #fff; }
.tag--sale { background: var(--sale); color: #fff; }

.card__fav {
  /* top: 2px центрирует иконку 19px (в рамке padding 6) ровно напротив
     плашки скидки в противоположном углу. */
  position: absolute; top: 2px; right: 6px; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  padding: 6px; border-radius: var(--r); color: var(--text-3);
  transition: color .2s var(--ease), background .2s var(--ease);
}
.card__fav:hover { color: var(--accent); background: rgba(255,255,255,.10); }
.card__fav svg { width: 19px; height: 19px; }
.card__fav.is-on { color: var(--accent); }
.card__fav.is-on svg path { fill: var(--accent); }

.card__ph {
  display: block; position: relative; overflow: hidden;
  aspect-ratio: 1; border-radius: var(--r);
  background: var(--ph-fall);   /* тёплое свечение под фото */
  transform-origin: center 62%;
  transition: transform .5s var(--ease), box-shadow .28s var(--ease);
}
.card__ph img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: center 62%;
}
.card__b { padding: 12px 2px 0; display: flex; flex-direction: column; gap: 4px; flex: 1; }
/* Артикул ушёл вниз и стал тише. Раньше он стоял первой строкой, и
   покупатель читал «АРТ. 1001» раньше названия товара. */
.card__art { margin-top: 10px; color: var(--text-3); font-size: .72rem; letter-spacing: .04em; }
/* Два ряда под имя резервируются всегда, но текст прижат к НИЗУ резерва.
   Просто убрать резерв не помогает: карточки в ряду тянутся до общей
   высоты, и свободное место всё равно копится перед ценой — просвет
   гулял от 33px у длинных названий до 53px у коротких. Прижав текст
   вниз, мы отправляем этот запас под фотографию, где он читается как
   поле, а не как дыра. Цены и кнопки при этом остаются на одной линии. */
.card__name {
  font-size: 1rem; font-weight: 600; line-height: 1.28; letter-spacing: -.012em;
  min-height: 2.56em; display: flex; align-items: flex-end;
  /* «Рулет-пломбир» и подобные длинные слова не должны распирать колонку */
  overflow-wrap: anywhere;
}
.card__name a { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card__name a:hover { color: var(--accent); }
.card__pack {
  color: var(--text-3); font-size: .8rem; letter-spacing: 0; text-transform: none;
  /* line-height и min-height совпадают: пустая строка занимает ровно
     столько же, сколько заполненная, иначе карточки расходятся на 3px.
     1.3 вместо 1.6 — строка и так одна, лишняя высота шла в пустоту. */
  line-height: 1.3; min-height: 1.3em;
}
/* Цена и кнопка стояли в одну строку и дрались за внимание: синяя
   заливка перевешивала цифру. Теперь цена сама по себе, кнопка под ней
   во всю ширину — так в карточке появляется низ. */
/* Цена и кнопка стояли в одну строку и дрались за внимание: синяя
   заливка перевешивала цифру. Кнопка ушла вниз во всю ширину и стала
   тише — сплошной ряд синих плашек читался как шаблон. */
/* 14px здесь складывались с зарезервированными пустыми строками имени
   и граммовки — между названием и ценой набегало 70px. */
.card__foot { margin-top: auto; padding-top: 4px; display: grid; gap: 10px; }
.card__foot .btn { width: 100%; }
.card .btn--buy {
  --fg-b: var(--accent); --bd-b: transparent;
  background: var(--accent-soft); box-shadow: none; font-weight: 600;
}
.card .btn--buy:hover { --fg-b: #fff; background: var(--accent-btn); }
.card__ph + .card__b { padding-top: 12px; }
.price {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.3rem, 1.7vw, 1.5rem); letter-spacing: -.035em;
  white-space: nowrap; font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 9px;
}
.price s { color: var(--text-3); font-family: var(--f-body); font-size: .8rem; font-weight: 400; letter-spacing: 0; }
/* Раньше это была мелкая надпись у левого края, а в соседней карточке
   на её месте стояла кнопка во всю ширину — ряд выглядел рваным.
   Теперь занимает то же место и тот же рост, что кнопка, но пунктиром:
   видно, что нажать нельзя. */
.card__out {
  display: flex; align-items: center; justify-content: center;
  min-height: 38px; padding: 0 12px;
  border: 1px dashed var(--line-strong); border-radius: var(--r);
  color: var(--text-3); font-size: .82rem; font-weight: 600; text-align: center;
}
@media (pointer: coarse) { .card__out { min-height: 44px; } }

/* ---------- 12. Блог ----------------------------------------- */
.post { border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--surface); transition: border-color .22s; }
.post:hover { border-color: var(--accent); }
.post .ph { aspect-ratio: 16/9; }

/* ---------- 13. FAQ ------------------------------------------ */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { list-style: none; cursor: pointer; padding: 18px 44px 18px 0; position: relative; font-size: 1rem; font-weight: 500; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: ''; position: absolute; right: 4px; top: 50%; width: 12px; height: 12px;
  background: linear-gradient(currentColor,currentColor) center/12px 1px no-repeat,
              linear-gradient(currentColor,currentColor) center/1px 12px no-repeat;
  transform: translateY(-50%); transition: transform .26s var(--ease);
}
.faq details[open] summary::after { transform: translateY(-50%) rotate(135deg); }
.faq__a { padding: 0 60px 20px 0; color: var(--text-2); max-width: 76ch; }

/* ---------- 14. Страница каталога ---------------------------- */
.phead { background: var(--surface); border-bottom: 1px solid var(--line); padding-block: clamp(18px, 2.6vw, 34px); }
.crumbs { display: flex; flex-wrap: wrap; gap: 7px; color: var(--text-3); margin-bottom: 14px; }
.crumbs a:hover { color: var(--accent); }

.clayout { display: grid; gap: clamp(18px, 2.4vw, 34px); align-items: start; }
/* колонка не должна распираться содержимым: min-width у элемента сетки
   по умолчанию равен min-content */
.clayout > * { min-width: 0; }
@media (min-width: 1000px) { .clayout { grid-template-columns: 236px 1fr; } }
.filters { display: grid; gap: 20px; }
@media (min-width: 1000px) { .filters { position: sticky; top: calc(var(--hdr) + 12px); } }
.fbox__sum { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 44px; padding: 0 14px; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.fbox__body { display: grid; gap: 20px; padding-top: 18px; }
@media (max-width: 999px) { .fbox[data-open="false"] .fbox__body { display: none; } }
@media (min-width: 1000px) { .fbox__sum { display: none; } .fbox__body { padding-top: 0; } }
.fgroup h2 { font-size: .88rem; margin-bottom: 10px; }
.fgroup ul { display: grid; gap: 8px; }
.fopt { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: .87rem; color: var(--text-2); transition: color .16s; }
.fopt:hover { color: var(--text); }
/* Родной чекбокс — квадрат с острыми углами, и accent-color этого не
   меняет. Рисуем свой: та же шкала скруглений, что у кнопок и полей. */
.fopt input {
  appearance: none; -webkit-appearance: none;
  width: 19px; height: 19px; flex: none; margin: 0;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface);
  display: grid; place-items: center; cursor: pointer;
  transition: background .16s var(--ease), border-color .16s var(--ease);
}
.fopt input::before {
  content: ''; width: 10px; height: 10px; transform: scale(0);
  transition: transform .16s var(--ease);
  background: #fff;
  clip-path: polygon(14% 47%, 0 61%, 40% 100%, 100% 20%, 85% 8%, 38% 71%);
}
.fopt input:checked { background: var(--accent-btn); border-color: var(--accent-btn); }
.fopt input:checked::before { transform: scale(1); }
.fopt input:hover { border-color: var(--accent); }

.ctool { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; padding-bottom: 14px; border-bottom: 1px solid var(--line); margin-bottom: 18px; }
.ctool__l, .ctool__r { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.empty { border: 1px dashed var(--line); border-radius: var(--r-lg); padding: 48px 20px; text-align: center; color: var(--text-2); }
.empty b { display: block; color: var(--text); font-size: 1.05rem; margin-bottom: 6px; }

/* вид «списком» */

/* ---------- 15. Карточка товара (страница) ------------------- */
.pdp { display: grid; gap: clamp(20px, 3vw, 44px); align-items: start; }
@media (min-width: 900px) { .pdp { grid-template-columns: minmax(0,1.05fr) minmax(0,.95fr); } }
.pdp__main { aspect-ratio: 1; border: 1px solid var(--line); border-radius: var(--r-lg); }
/* галерея миниатюр не используется: у каждого товара один кадр */

.buybox { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); padding: 18px; display: grid; gap: 14px; margin: 18px 0; }
/* Подпись под ценой: за упаковку целиком или за штуку. Набрана
   мельче цены — она поясняет, а не спорит с ней. */
.buybox__note { margin-top: -6px; color: var(--text-3); font-size: .84rem; }
.buybox__price { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.buybox__price .price { font-size: 2rem; }
.buybox__row { display: flex; gap: 10px; flex-wrap: wrap; }
.buybox__row .btn { flex: 1 1 160px; }
.perkg { color: var(--text-3); }

.qty { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; flex: none; }
.qty button { width: 40px; height: 44px; color: var(--text-2); font-size: 1.1rem; transition: background .16s, color .16s; }
.qty button:hover { background: var(--surface-2); color: var(--accent); }
.qty output { min-width: 42px; text-align: center; font-family: var(--f-label); font-size: .9rem; }

.tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--line); margin-bottom: 20px; }
.tabs button { padding: 12px 0; color: var(--text-2); font-size: .95rem; position: relative; }
.tabs button[aria-selected="true"] { color: var(--text); }
.tabs button[aria-selected="true"]::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); }
.spec { display: grid; gap: 0; }
.spec div { display: flex; justify-content: space-between; gap: 20px; padding: 11px 0; border-bottom: 1px solid var(--line-soft); font-size: .9rem; }
.spec dt { color: var(--text-2); }
.spec dd { font-weight: 500; text-align: right; }

/* ---------- 16. Корзина -------------------------------------- */
.cart { display: grid; gap: clamp(18px, 2.6vw, 36px); align-items: start; }
@media (min-width: 900px) { .cart { grid-template-columns: 1fr 330px; } }
/* Фото было 84px — товар в нём не разглядеть, а строка выглядела
   прижатой к краю. Даём картинке вырасти и отодвигаем от неё описание.
   Через clamp, а не одним числом: на телефоне ширины и так в обрез, там
   остаётся 92px, на большом экране — 112px. */
.cline {
  display: grid; grid-template-columns: clamp(92px, 11vw, 112px) 1fr;
  gap: clamp(16px, 1.8vw, 22px);
  padding: 16px 0; border-bottom: 1px solid var(--line); align-items: start;
}
.cline .ph { aspect-ratio: 1; border-radius: var(--r); }
.cline__b { display: grid; gap: 8px; }
.cline__top { display: flex; justify-content: space-between; gap: 12px; align-items: start; }
.cline__top .mono { white-space: nowrap; }
.cline__name { font-size: .95rem; font-weight: 500; }
.cline__ctl { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.summary { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); padding: 20px; display: grid; gap: 14px; }
@media (min-width: 900px) { .summary { position: sticky; top: calc(var(--hdr) + 12px); } }
.summary__row { display: flex; justify-content: space-between; gap: 12px; font-size: .92rem; }
.summary__row--total { padding-top: 12px; border-top: 1px solid var(--line); font-size: 1.05rem; font-weight: 600; }
.summary__row--total b { font-family: var(--f-display); font-size: 1.5rem; letter-spacing: -.04em; }

/* подсказка в корзине: до минимального заказа / до бесплатной доставки */
.cart-hint { text-transform: none; letter-spacing: 0; font-size: .8rem; line-height: 1.45; padding: 10px 12px; border-radius: var(--r); }
.cart-hint[data-kind="warn"] { background: rgba(212,56,45,.14); color: var(--danger); }
.cart-hint[data-kind="info"] { background: var(--accent-soft); color: var(--accent); }
.cart-hint[data-kind="ok"]   { background: rgba(63,169,106,.12); color: var(--ok); }
/* Точка отсчёта для списка подсказок под полем адреса. */
.summary .field { display: grid; gap: 6px; position: relative; }
.summary .field input, .summary .field select {
  min-height: 42px; padding: 0 12px; background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--r); color: var(--text); width: 100%;
}
.summary .field input:focus, .summary .field select:focus { outline: none; border-color: var(--accent); }
.summary .field label { color: var(--text-2); }
.field__err { color: var(--danger); font-size: .76rem; }
/* Пояснение под полем: тише подписи, но читаемо. Регистр и разрядку
   сбрасываем — метки полей в админке заглавные, а это обычный текст. */
.field__hint {
  color: var(--text-3); font-size: .76rem; line-height: 1.4;
  text-transform: none; letter-spacing: 0; margin: 0;
}
.err { border-color: var(--danger) !important; }
.form__ok { border: 1px solid var(--ok); background: rgba(63,169,106,.12); color: var(--text); padding: 12px 14px; border-radius: var(--r); font-size: .9rem; }
.buybox__price s { font-size: .95rem; }
.tabs button[role=tab] { cursor: pointer; }

/* ---------- 17. Футер ---------------------------------------- */
.footer { background: var(--surface); border-top: 1px solid var(--line); padding-block: clamp(32px, 4vw, 54px) 22px; color: var(--text-2); margin-top: clamp(32px, 4vw, 60px); }
.footer a:hover { color: var(--accent); }
.footer__grid { display: grid; gap: 28px; }
@media (min-width: 560px) { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px) { .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1.2fr; } }
.footer h3 { color: var(--text); margin-bottom: 13px; font-size: .92rem; }
.footer ul { display: grid; gap: 9px; font-size: .9rem; }
/* Реквизиты продавца: правила дистанционной торговли требуют показывать их
   на видном месте, а не прятать в политике. Тише остального подвала, но
   контраст держим читаемым — это не мелкий шрифт «для галочки». */
.footer__legal {
  margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line);
  font-size: .82rem; line-height: 1.6; color: var(--text-3); max-width: 78ch;
}
.footer__legal a { color: var(--text-2); text-decoration: underline; text-underline-offset: 2px; }
.footer__legal a:hover { color: var(--accent); }

/* ---------- 18. Уведомление ---------------------------------- */
.toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 100;
  transform: translate(-50%, 20px); opacity: 0; visibility: hidden;
  background: var(--accent-btn); color: #fff; padding: 12px 20px; border-radius: var(--r);
  font-size: .88rem; box-shadow: var(--shadow);
  transition: opacity .24s var(--ease), transform .24s var(--ease), visibility .24s;
}
.toast[data-on="true"] { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
@media (max-width: 760px) { .toast { bottom: 74px; } }

/* ---------- 19. Утилиты -------------------------------------- */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 110; background: var(--accent-btn); color: #fff; padding: 10px 16px; border-radius: var(--r); transition: top .2s; }
.skip:focus { top: 12px; }
[hidden] { display: none !important; }
.noscroll { overflow: hidden; }


/* ---------- 20. Появление блоков при скролле ------------------
   Класс навешивает app.js через IntersectionObserver. При
   prefers-reduced-motion всё показывается сразу, без сдвига. */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .55s var(--ease), transform .55s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* подсветка первого экрана под товаром */

/* шапка получает тень, когда страница прокручена */
.header { transition: box-shadow .24s var(--ease), background-color .24s var(--ease); }
.header.is-stuck { box-shadow: 0 10px 30px rgba(0,0,0,.34); }
:root[data-theme="light"] .header.is-stuck { box-shadow: 0 10px 26px rgba(12,40,70,.10); }


/* ---------- 21. Движение ------------------------------------
   Правило одно: анимация объясняет, что произошло, и не задерживает.
   Двигаем только transform и opacity. Всё гасится при
   prefers-reduced-motion — блок в конце файла.
   ------------------------------------------------------------- */

/* Появление карточек в сетке. Узлы заменяются через innerHTML, поэтому
   не transition, а animation: она отыгрывает сама при вставке.
   Ступень 22мс и потолок в 8 шагов — чтобы фильтрация не превращалась
   в ожидание. */
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } }

.pgrid > .card, .rail > .card { animation: riseIn .26s var(--ease) backwards; }
.pgrid > .card:nth-child(2),  .rail > .card:nth-child(2)  { animation-delay: .022s; }
.pgrid > .card:nth-child(3),  .rail > .card:nth-child(3)  { animation-delay: .044s; }
.pgrid > .card:nth-child(4),  .rail > .card:nth-child(4)  { animation-delay: .066s; }
.pgrid > .card:nth-child(5),  .rail > .card:nth-child(5)  { animation-delay: .088s; }
.pgrid > .card:nth-child(6),  .rail > .card:nth-child(6)  { animation-delay: .11s; }
.pgrid > .card:nth-child(7)  { animation-delay: .132s; }
.pgrid > .card:nth-child(n+8) { animation-delay: .154s; }

/* Раскрытие вопроса. Закрытый <details> не рендерит содержимое, поэтому
   transition не с чего начинать — работает только animation при появлении. */
@keyframes faqIn { from { opacity: 0; transform: translateY(-6px); } }
.faq details[open] .faq__a { animation: faqIn .24s var(--ease); }

/* Переключение вкладок на карточке товара */
[data-panel]:not([hidden]) { animation: faqIn .22s var(--ease); }

/* Счётчики в шапке: цифра меняется беззвучно, и заметить это трудно */
@keyframes badgePop { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }
.hact__n.is-bump { animation: badgePop .32s var(--ease); }

/* Сердечко в карточке: отклик на нажатие */
@keyframes favPop { 0% { transform: scale(1); } 40% { transform: scale(1.3); } 100% { transform: scale(1); } }
.card__fav.is-bump svg { animation: favPop .3s var(--ease); }

/* Нажатие любой кнопки — короткий отклик */
.btn:active:not(:disabled) { transform: translateY(1px) scale(.985); }
.qty button:active { transform: scale(.9); }

/* Иконки в шапке слегка подрастают под курсором */
@media (hover: hover) and (pointer: fine) {
  .hact svg { transition: transform .2s var(--ease); }
  .hact:hover svg { transform: translateY(-2px); }
  .shead__all { transition: color .2s var(--ease), transform .2s var(--ease); }
  .shead__all:hover { transform: translateX(3px); }
}

/* Поле поиска подсвечивается мягко, а не скачком */
.search input { transition: border-color .2s var(--ease), background-color .2s var(--ease); }

/* Смена темы.
   Плавно перекрашивать нечем: страницу составляют десятки поверхностей,
   и любой список «крупных» оставляет остальные перещёлкивать мгновенно —
   фон уезжает за 250 мс, а полсотни подложек карточек меняются сразу.
   Рассинхрон и читался как поломка. Поэтому тема меняется за одну
   отрисовку: на время подмены глушим переходы совсем.

   Атрибут ставит и снимает store.js в пределах одного кадра. */
:root[data-theme-switching] *,
:root[data-theme-switching] *::before,
:root[data-theme-switching] *::after {
  transition: none !important;
}
/* кроме самого переключателя: ползунок и иконки едут, иначе нажатие
   остаётся без отклика */
:root[data-theme-switching] .theme::after { transition: transform .26s var(--ease) !important; }
:root[data-theme-switching] .theme svg    { transition: color .2s var(--ease) !important; }

/* Строка корзины исчезает не мгновенно */
@keyframes lineOut { to { opacity: 0; transform: translateX(-14px); } }
.cline.is-leaving { animation: lineOut .22s var(--ease) forwards; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .pgrid > .card, .rail > .card, .faq details[open] .faq__a,
  [data-panel]:not([hidden]), .hact__n.is-bump, .card__fav.is-bump svg,
  .cline.is-leaving { animation: none !important; }
  .btn:active:not(:disabled), .qty button:active { transform: none; }
}


/* ---------- 22. Границы элементов управления ------------------
   var(--line) задумана для разделителей и на контролах даёт 1.25:1
   при норме 3:1 — поле не отличалось от подложки. */
.search input,
.fbox__sum,
.field input,
.field select,
.field textarea,
.summary .field input,
.summary .field select,
.qty {
  border-color: var(--line-strong);
}


/* ---------- 22б. Подсказки адреса ----------------------------- */
/* Список висит под полем и перекрывает то, что ниже, — поэтому он
   вынут из потока, а не раздвигает форму: иначе кнопка «Оформить
   заказ» прыгала бы вниз при каждой набранной букве. */
.sug {
  position: absolute; z-index: 40; top: 100%; left: 0; right: 0;
  margin-top: 6px; padding: 6px; max-height: 268px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow);
}
.sug[hidden] { display: none; }
.sug [role="option"] {
  padding: 10px 11px; border-radius: var(--r-sm);
  font-size: .9rem; line-height: 1.35; color: var(--text-2); cursor: pointer;
}
/* Подсветка одна и для клавиатуры, и для мыши — как в своих списках. */
.sug [role="option"].is-hot { background: var(--surface-2); color: var(--text); }
@media (pointer: coarse) {
  .sug [role="option"] { min-height: 44px; display: flex; align-items: center; }
}


/* Заказ, о котором магазину не написали. Не красная тревога, но и не
   мимо взгляда: письмо не ушло, и заказ легко пропустить. */
.admord__warn {
  padding: 2px 8px; border-radius: var(--r-pill);
  background: rgba(212,56,45,.14); color: var(--sale-text);
  font-size: .72rem; font-weight: 600; white-space: nowrap;
}

/* ---------- 23. Мелкие доработки ------------------------------ */
/* «Скидка» в сводке была цветом плашки — 3.65 на поверхности */
.summary__row [data-save] { color: var(--sale-text); }

/* степпер: минус на единице выключен, удаление — только «Удалить» */
.qty button:disabled { opacity: .35; cursor: not-allowed; }
.qty button:disabled:hover { background: none; color: var(--text-2); }

/* активная подборка видна и снимается */
.chip-filter {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 6px 5px 12px; border-radius: var(--r-pill); margin-left: 12px;
  background: var(--accent-soft); color: var(--accent);
  font-size: .8rem; font-weight: 600;
}
.chip-filter button {
  width: 20px; height: 20px; display: grid; place-items: center;
  border-radius: 50%; color: inherit;
}
.chip-filter button svg { width: 9px; height: 9px; display: block; }
.chip-filter button:hover { background: rgba(0,0,0,.2); }

/* страница «товар не найден» */
.notfound { text-align: center; padding: clamp(48px, 9vw, 110px) 20px; }
.notfound b { display: block; font-family: var(--f-display); font-size: clamp(1.4rem,3vw,2rem); margin-bottom: 12px; }
.notfound p { color: var(--text-2); max-width: 46ch; margin: 0 auto 24px; }


/* ---------- 24. Выбор города ---------------------------------- */
/* Магазин возит по нескольким городам, и от города зависят сроки и
   стоимость. Поэтому город — не украшение в шапке, а первое, что
   человек должен увидеть и при желании поменять. */
.citypick { position: relative; }
.citybtn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 10px; border-radius: var(--r);
  color: var(--text-2); font-size: .88rem; white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.citybtn svg { width: 15px; height: 15px; flex: none; }
.citybtn__c { width: 9px; height: 6px; opacity: .7; }
.citybtn__n { font-weight: 600; color: var(--text); }
.citybtn[aria-expanded="true"],
.citybtn:hover { color: var(--text); background: var(--surface-2); }

.citymenu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 70;
  /* Ширина по содержимому, а не числом: при 152px справа от самой
     длинной строки («Ярославль» с галочкой) оставалось 16px пустоты,
     и любая правка списка городов снова разошлась бы с числом.
     Нижняя граница — чтобы меню из одних коротких названий не
     съёживалось. */
  width: max-content; min-width: 132px;
  padding: 6px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: grid; gap: 2px;
  animation: cityIn .16s var(--ease) both;
}
.citymenu[hidden] { display: none; }
@keyframes cityIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.citymenu button {
  /* Галочка сразу за названием, а не прижата к правому краю: при
     space-between просвет доходил до 112px и гулял от строки к строке.
     Разнобоя не будет — видимая галочка в меню всегда одна, у текущего
     города, у остальных она прозрачная. */
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 9px 11px; border-radius: var(--r-sm);
  font-size: .92rem; text-align: left; color: var(--text-2);
  transition: background .16s var(--ease), color .16s var(--ease);
}
.citymenu button svg { width: 15px; height: 15px; opacity: 0; flex: none; }
.citymenu button:hover { background: var(--surface-2); color: var(--text); }
.citymenu button[aria-checked="true"] { color: var(--accent); font-weight: 600; }
.citymenu button[aria-checked="true"] svg { opacity: 1; }


/* На узких экранах в шапке остаётся только булавка с названием */
@media (max-width: 900px) {
  .citybtn__c { display: none; }
}
@media (max-width: 560px) {
  /* Одна булавка без названия не читается как выбор города. Место под
     подпись освободилось, когда с телефона ушла кнопка «Каталог». */
  .citybtn { padding: 0 8px; gap: 5px; font-size: .82rem; }
}
@media (max-width: 380px) {
  /* На 320px логотипу и группе не хватало трёх пикселей, и группа
     срывалась на свою строку: шапка становилась трёхэтажной, 147px
     вместо 113. Поджимаем промежутки — помещается в один ряд. */
  .header__in { gap: 8px; }
  .hactions { gap: 4px; }
  .citybtn { padding: 0 6px; }
}



/* ---------- 26. Таблица условий по городам -------------------- */
/* Четыре города с разными сроками и суммами — это именно таблица,
   а не список пар: их сравнивают по столбцам. */
.tablewrap { overflow-x: auto; margin-inline: calc(var(--pad) * -1); padding-inline: var(--pad); }
.ctable { width: 100%; min-width: 640px; border-collapse: collapse; font-size: .92rem; }
.ctable th, .ctable td { text-align: left; vertical-align: top; padding: 15px 18px 15px 0; }
.ctable thead th {
  font-family: var(--f-label); font-size: .74rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--text-3);
  padding-bottom: 11px; border-bottom: 1px solid var(--line);
}
.ctable tbody th {
  font-family: var(--f-display); font-weight: 700; font-size: 1.02rem;
  letter-spacing: -.02em; white-space: nowrap;
}
.ctable tbody tr + tr th, .ctable tbody tr + tr td { border-top: 1px solid var(--line-soft); }
.ctable td { color: var(--text-2); line-height: 1.5; }
.ctable .muted { font-size: .84rem; color: var(--text-3); }


/* ---------- 27. Шапка поверх баннера -------------------------- */
/* На главной шапка лежит на баннере, а не отделена от него полосой.
   Пока страница не прокручена — фон прозрачный и текст белый; после
   прокрутки возвращается обычная шапка. Класс --over ставится только
   на страницах с героем. */
@media (min-width: 901px) {
  .header--over:not(.is-solid) {
    background: transparent;
    color: #fff;
  }
  .header--over:not(.is-solid) .nav a,
  .header--over:not(.is-solid) .hact,
  .header--over:not(.is-solid) .citybtn,
  .header--over:not(.is-solid) .citybtn__n,
  .header--over:not(.is-solid) .theme { color: #fff; }
  .header--over:not(.is-solid) .hact span { color: rgba(255,255,255,.82); }
  .header--over:not(.is-solid) .nav a:hover,
  .header--over:not(.is-solid) .hact:hover { color: var(--accent); background: rgba(255,255,255,.14); }

  /* Поле поиска и переключатели на фотографии: полупрозрачное стекло,
     а не белая плашка — иначе шапка снова превращается в полосу. */
  .header--over:not(.is-solid) .search input {
    background: rgba(255,255,255,.12);
    border-color: rgba(255,255,255,.30);
    color: #fff;
  }
  .header--over:not(.is-solid) .search input::placeholder { color: rgba(255,255,255,.66); }
  .header--over:not(.is-solid) .search svg { color: rgba(255,255,255,.72); }
  .header--over:not(.is-solid) .citybtn:hover,
  .header--over:not(.is-solid) .citybtn[aria-expanded="true"] { background: rgba(255,255,255,.14); }
  .header--over:not(.is-solid) .theme { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); }
  .header--over:not(.is-solid) .burger span,
  .header--over:not(.is-solid) .burger span::before,
  .header--over:not(.is-solid) .burger span::after { background: #fff; }
  .header--over:not(.is-solid) .logo__img { filter: brightness(0) invert(1); }

  /* Прокрутили — шапка обычная. Переход мягкий, иначе она моргает. */
  .header--over { transition: background .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease); }
}


/* ---------- 29. Вход в кабинет -------------------------------- */
/* Способ входа выбирается вкладками, а не двумя формами подряд:
   человеку нужен один способ, а не оба сразу. */
/* Вход был свёрстан коробкой .summary из корзины, втиснутой в её же
   двухколоночную раскладку: заголовок, поле и кнопка шли одним потоком
   с общим шагом, и «Получить код» стояла к полю вплотную. Теперь это
   своя карточка по центру со своим ритмом. */
.authwrap { max-width: 460px; margin-inline: auto; display: grid; gap: 22px; }

.auth {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: clamp(20px, 4vw, 30px);
}
.auth__t {
  font-family: var(--f-display); font-weight: 700;
  font-size: 1.3rem; line-height: 1.2; letter-spacing: -.025em;
}
.auth__sub { margin-top: 8px; color: var(--text-2); font-size: .92rem; line-height: 1.5; }


/* gap формы и есть та отбивка, которой не хватало кнопке */
.auth form { margin-top: 20px; display: grid; gap: 16px; }
.auth .field,
.cabpane .field { display: grid; gap: 8px; }
.auth .field label,
.cabpane .field label { font-size: .72rem; letter-spacing: .06em; color: var(--text-3); }
.auth .field input,
.cabpane .field input {
  width: 100%; min-height: 46px; padding: 0 14px; font-size: .95rem;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--r);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.auth .field input:focus,
.cabpane .field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.auth__alt { display: grid; gap: 8px; }

.authmsg { margin-top: 14px; font-size: .88rem; line-height: 1.45; color: var(--text-2); }
.authmsg[data-kind="err"] { color: var(--danger); }
.authmsg[data-kind="ok"]  { color: var(--ok); }

.authout { display: grid; gap: 8px; margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line); }
/* Пара кнопок под полем имени: «Сохранить» и «Пропустить». Столбиком,
   потому что обе широкие и в строку на узком экране не встают. */
.authbtns { display: grid; gap: 8px; }

/* Способы входа под формой: «войти по паролю» и «забыли пароль».
   Отделены чертой — это не продолжение формы, а переход в другой режим. */
.authways { display: grid; gap: 8px; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }
/* Ссылкой, а не кнопкой: сброс пароля — редкое действие, ему незачем
   спорить по весу с основной кнопкой входа. */
.btn--link {
  --bg-b: transparent;
  border: 0; padding: 6px; min-height: 0;
  color: var(--text-3); font-size: .86rem; text-decoration: underline;
  text-underline-offset: 3px; cursor: pointer;
}
.btn--link:hover { color: var(--accent); }

/* Блок пароля в кабинете. Свёрнут по умолчанию: пароль необязателен,
   и незачем показывать два поля тому, кто входит по коду. */
.authpass { margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line); display: grid; gap: 10px; }
.authpass__h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.authpass__h > span:first-child { font-weight: 600; color: var(--text); }
.authpass__s { font-family: var(--f-mono, ui-monospace, monospace); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.authpass__n { margin: 0; font-size: .86rem; color: var(--text-3); line-height: 1.5; }
.authpass form { display: grid; gap: 12px; }

.authperks { display: grid; gap: 12px; }
.authperks > span { color: var(--text-3); }
.authperks ul { display: grid; gap: 10px; font-size: .88rem; color: var(--text-2); }
.authperks li { display: flex; gap: 10px; align-items: flex-start; line-height: 1.45; }
.authperks li::before {
  content: ''; width: 5px; height: 5px; flex: none;
  margin-top: 7px; border-radius: 50%; background: var(--accent);
}

/* Поле для кода: цифры вразрядку, чтобы не путать 0 и O */
#au-c { letter-spacing: .5em; font-family: var(--f-display); font-weight: 700; text-align: center; }

/* Страница входа занята одним делом, поэтому воздуха вокруг карточки
   больше обычного: на экране нет ничего, что спорило бы с формой. */
.authpage { padding-block: clamp(28px, 6vw, 76px); }


/* ---------- 29б. Личный кабинет ------------------------------- */
/* Кабинет — это несколько разных дел в одном месте: настройки учётной
   записи, история покупок, избранное, адреса. Раньше они шли подряд
   одним столбцом, и человек, зашедший посмотреть заказ, сначала
   пролистывал форму имени и форму пароля. Теперь слева выбор раздела,
   справа содержимое; на узком экране колонки складываются, а выбор
   становится лентой кнопок над содержимым. */
.cab { display: grid; gap: 20px; align-items: start; }
@media (min-width: 960px) {
  /* minmax(0,1fr), а не 1fr: иначе длинное название товара распирает
     колонку и ломает сетку. */
  .cab { grid-template-columns: 268px minmax(0, 1fr); gap: 28px; }
}
.cab__wait { color: var(--text-2); }
.cab__wait a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* Общая карточка кабинета: одна рамка и один радиус на всё. */
.cabcard {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: clamp(16px, 2.4vw, 22px);
}

/* --- боковая колонка ------------------------------------------- */
.cab__side { min-width: 0; }
.cabside { padding: 16px; }
@media (min-width: 960px) {
  /* Список разделов остаётся на виду, пока справа листается история. */
  .cabside { position: sticky; top: calc(var(--hdr) + 14px); }
}

.cabme {
  display: flex; align-items: center; gap: 12px;
  padding: 4px 6px 15px; border-bottom: 1px solid var(--line-soft);
}
.cabme__ava {
  width: 44px; height: 44px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent);
  font-family: var(--f-display); font-weight: 700; font-size: 1.05rem;
}
.cabme__b { display: grid; gap: 1px; min-width: 0; }
.cabme__n {
  font-family: var(--f-display); font-weight: 700; font-size: 1rem;
  line-height: 1.2; letter-spacing: -.02em; overflow-wrap: anywhere;
}
.cabme__s { color: var(--text-3); font-size: .78rem; }

/* Блок «сообщите, когда появится» на карточке товара, которого нет. */
.alertbox { margin-top: 16px; display: grid; gap: 10px; }
.alertbox .field { margin: 0; }
.alertbox .cart-hint { margin: 0; }

.cabnav { display: grid; gap: 2px; margin-top: 12px; }
/* Ссылка в панель управления стоит в том же списке, что и разделы
   кабинета, и должна выглядеть так же — отсюда общий селектор. */
.cabnav button, .cabnav a {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 44px; padding: 0 12px;
  border: 0; border-radius: var(--r); background: transparent;
  color: var(--text-2); font: inherit; font-size: .92rem; font-weight: 600;
  text-align: left; cursor: pointer; white-space: nowrap;
  text-decoration: none;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.cabnav button > span, .cabnav a > span { flex: 1 1 auto; min-width: 0; }
.cabnav .cabic { width: 20px; height: 20px; flex: none; }
.cabnav button:hover, .cabnav a:hover { background: var(--surface-2); color: var(--text); }
.cabnav button[aria-current] { background: var(--accent-soft); color: var(--accent); }
/* Счётчик — спокойная цифра, а не плашка уведомления: это справка,
   а не то, что требует немедленного внимания. */
.cabnav b { font-weight: 700; font-size: .76rem; color: var(--text-3); }
.cabnav button[aria-current] b { color: var(--accent); }
.cabnav--out {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-soft);
}

@media (max-width: 959px) {
  /* Шесть разделов столбиком на телефоне — это полэкрана до первой
     полезной строки. Кладём их в ленту с прокруткой. */
  .cabnav {
    grid-auto-flow: column; grid-auto-columns: max-content;
    gap: 6px; overflow-x: auto; scrollbar-width: none;
    margin-inline: -4px; padding-inline: 4px;
  }
  .cabnav::-webkit-scrollbar { display: none; }
  .cabnav--out { grid-auto-flow: row; }
}

/* --- правая колонка -------------------------------------------- */
.cab__main { display: grid; gap: 16px; min-width: 0; }
.cabpane {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: clamp(18px, 3vw, 26px);
}
.cabpane__t {
  font-family: var(--f-display); font-weight: 700;
  font-size: 1.15rem; line-height: 1.2; letter-spacing: -.025em;
}
.cabpane__b { margin-top: 18px; }
/* Обзор собран из собственных карточек, ещё одна рамка вокруг них
   была бы рамкой в рамке. */
.cabpane--bare { border: 0; background: none; padding: 0; }
.cabpane--bare .cabpane__b { margin-top: 0; display: grid; gap: 16px; }
.cabpane .authpass, .cabpane .authout { margin-top: 22px; }
.cabform { margin-top: 18px; display: grid; gap: 16px; }
.cabnote { color: var(--text-3); font-size: .84rem; line-height: 1.55; }
.cabpane__b > .cabnote:last-child { margin-top: 16px; }

/* --- приветствие ------------------------------------------------ */
.cabhead {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  justify-content: space-between; gap: 10px 16px;
}
.cabhead__t {
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.28rem, 2.6vw, 1.7rem); line-height: 1.15; letter-spacing: -.03em;
}
.cabhead__s { margin-top: 6px; color: var(--text-2); font-size: .92rem; }

.cablink {
  display: inline-flex; align-items: center; gap: 7px;
  border: 0; background: none; padding: 4px 0;
  color: var(--accent); font: inherit; font-size: .88rem; font-weight: 600;
  cursor: pointer;
}
.cablink:hover { text-decoration: underline; text-underline-offset: 3px; }
.cablink .cabic { width: 17px; height: 17px; flex: none; }
.cablink--q { font-weight: 500; }

/* --- три быстрых перехода --------------------------------------- */
.cabtiles {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.cabtile {
  display: flex; align-items: center; gap: 12px; padding: 15px;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); color: inherit; font: inherit;
  text-align: left; cursor: pointer;
  transition: border-color .18s var(--ease);
}
.cabtile:hover { border-color: var(--accent); }
.cabtile__b { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.cabtile__b b { font-size: .95rem; font-weight: 600; }
.cabtile__b span { color: var(--text-3); font-size: .8rem; }
.cabtile > .cabic { width: 18px; height: 18px; flex: none; color: var(--text-3); }

/* Значок в подложке — им помечены разделы и обе карточки внизу. */
.cabchip {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  border-radius: 12px; background: var(--accent-soft); color: var(--accent);
}
.cabchip .cabic { width: 22px; height: 22px; }

/* --- ближайшая доставка ----------------------------------------- */
.cabnext__lb { color: var(--text-3); font-size: .78rem; }
.cabnext__n {
  margin-top: 4px; font-family: var(--f-display); font-weight: 700;
  font-size: 1.18rem; line-height: 1.2; letter-spacing: -.025em;
}
.cabnext__w { margin-top: 3px; color: var(--text-2); font-size: .88rem; }
.cabnext__r {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.cabnext__pics { display: flex; gap: 8px; flex: none; }
.cabnext__ph {
  width: 56px; height: 56px; flex: none;
  border-radius: 10px; overflow: hidden;
}
.cabnext__ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cabnext__s { flex: 1 1 140px; color: var(--text-2); font-size: .9rem; }
.cabnext__s b { color: var(--text); font-weight: 700; }
.cabnext__act { display: grid; gap: 6px; justify-items: end; }
@media (max-width: 560px) {
  .cabnext__act { justify-items: stretch; width: 100%; }
  .cabnext__act .btn { width: 100%; }
  .cabnext__act .cablink { justify-content: center; }
}

/* --- ряд товаров ------------------------------------------------ */
.cabrow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 4px;
}
.cabrow__t {
  font-family: var(--f-display); font-weight: 700;
  font-size: 1.02rem; letter-spacing: -.02em;
}
.cabrail {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
}

/* Плоская карточка: фото слева, всё остальное справа. Обычная
   карточка каталога тут была бы вдвое выше и увела бы взгляд от того,
   ради чего человек пришёл, — от заказов. */
.cabprod {
  display: flex; gap: 12px; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface);
  transition: border-color .18s var(--ease);
}
.cabprod:hover { border-color: var(--line-strong); }
.cabprod__ph { width: 76px; height: 76px; flex: none; border-radius: 10px; overflow: hidden; }
.cabprod__ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cabprod__b { display: grid; gap: 2px; align-content: start; flex: 1 1 auto; min-width: 0; }
.cabprod__t { display: flex; align-items: flex-start; gap: 8px; }
.cabprod__n { flex: 1 1 auto; font-size: .88rem; font-weight: 600; line-height: 1.3; }
.cabprod__n:hover { color: var(--accent); }
.cabprod__fav {
  flex: none; width: 26px; height: 26px; margin: -3px -3px 0 0;
  display: grid; place-items: center; border: 0; background: none;
  color: var(--text-3); cursor: pointer; transition: color .18s var(--ease);
}
.cabprod__fav svg { width: 18px; height: 18px; }
.cabprod__fav:hover { color: var(--accent); }
.cabprod__fav[aria-pressed="true"] { color: var(--sale-text); }
.cabprod__fav[aria-pressed="true"] svg path { fill: currentColor; }
.cabprod__p { color: var(--text-3); font-size: .76rem; min-height: 1em; }
.cabprod__pr { font-size: 1rem; margin-top: 2px; }
.cabprod__add { margin-top: 8px; min-height: 36px; font-size: .82rem; }

/* --- две карточки внизу ----------------------------------------- */
.cabduo {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}
.cabduo__i { display: flex; align-items: center; gap: 12px; }
.cabduo__b { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.cabduo__b b { font-size: .92rem; font-weight: 600; }
.cabduo__b span { color: var(--text-3); font-size: .8rem; overflow-wrap: anywhere; }
.cabduo__i .btn { flex: none; }

/* --- сводка и списки -------------------------------------------- */
.cabstat {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px; margin-bottom: 20px;
}
/* Фоном, а не рамкой: рамка внутри рамки карточки читается как
   вложенная таблица. */
.cabstat > div { padding: 13px 15px; border-radius: var(--r); background: var(--surface-2); }
.cabstat dt { color: var(--text-3); font-size: .76rem; }
.cabstat dd {
  margin-top: 3px; font-family: var(--f-display); font-weight: 700;
  font-size: 1.2rem; letter-spacing: -.02em;
}

.cabaddr { display: grid; gap: 10px; }
.cabaddr__i {
  display: flex; align-items: center; gap: 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--r);
}
.cabaddr__b { display: grid; gap: 2px; min-width: 0; }
.cabaddr__b b { font-size: .92rem; font-weight: 600; overflow-wrap: anywhere; }
.cabaddr__b span { color: var(--text-3); font-size: .78rem; }

.cabhelp { display: grid; gap: 8px; }
.cabhelp a {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 2px 12px; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: var(--r); color: inherit;
  transition: border-color .18s var(--ease);
}
.cabhelp a:hover { border-color: var(--accent); }
.cabhelp b { grid-column: 1; font-size: .92rem; font-weight: 600; }
.cabhelp a > span { grid-column: 1; color: var(--text-3); font-size: .78rem; }
.cabhelp a > .cabic {
  grid-column: 2; grid-row: 1 / span 2;
  width: 18px; height: 18px; color: var(--text-3);
}

/* Пустой раздел — первое, что видит новый покупатель. Поэтому он не
   извиняется, а показывает, куда идти дальше. */
.cabempty { display: grid; justify-items: start; gap: 8px; }
.cabempty__t { font-weight: 600; }
.cabempty__s { color: var(--text-2); font-size: .9rem; line-height: 1.5; max-width: 46ch; }
.cabempty .btn { margin-top: 10px; }

.order__a { margin-top: 4px; color: var(--text-3); font-size: .8rem; }
.order__act { margin-top: 14px; }



/* ---------- 30. Каталог из двух разделов ---------------------- */
/* Восемнадцать категорий одним столбцом читаются как свалка, поэтому
   список фильтров разбит заголовками разделов. Выпадающего меню в
   шапке больше нет: «Каталог» ведёт прямо в каталог, а выбирать
   раздел удобнее фильтром, где сразу видно и товары. */

/* Заголовок раздела в списке фильтров */
.fbox li.fgroup {
  font-family: var(--f-label); font-size: .66rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-3);
  margin-top: 14px; padding-bottom: 2px;
}
.fbox li.fgroup:first-child { margin-top: 0; }


/* ---------- 31. Свои выпадающие списки ------------------------ */
/* Раскрытый список у <select> рисует система: посреди тёмной страницы
   открывалось белое окно с системным шрифтом. Родной остаётся в
   разметке ради формы и доступности, но с глаз убран. */
.nsel {
  position: relative;
  /* список может стоять внутри .mono (панель фильтров) — капс и
     разрядка оттуда наследоваться не должны */
  font-family: var(--f-body); text-transform: none; letter-spacing: normal;
}
.nsel__native {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.nsel__btn {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 42px; padding: 0 12px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--r);
  font-size: .92rem; text-align: left;
  transition: border-color .18s var(--ease);
}
.nsel__btn:hover { border-color: var(--accent); }
.nsel__btn[aria-expanded="true"] { border-color: var(--accent); }
.nsel__t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nsel__c { width: 10px; height: 6px; flex: none; opacity: .7; }

.nsel__list {
  /* Ширина по содержимому, а не по кнопке: кнопка сортировки на телефоне
     всего 132px, и длинные пункты («Сначала дешевле») в неё не влезали —
     переносились на две строки, высота скакала, появлялся скролл.
     Раскрываемся от правого края кнопки влево (right:0), чтобы список,
     став шире кнопки, не вылез за правый край экрана. */
  position: absolute; top: calc(100% + 6px); right: 0; left: auto; z-index: 70;
  width: max-content; min-width: 100%; max-width: calc(100vw - 24px);
  max-height: 320px; overflow-y: auto;
  padding: 6px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow);
  animation: cityIn .16s var(--ease) both;
}
.nsel__list[hidden] { display: none; }
.nsel__list [role="option"] {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 9px 11px; border-radius: var(--r-sm);
  font-size: .92rem; color: var(--text-2); cursor: pointer;
  white-space: nowrap;   /* пункт всегда в одну строку */
}
.nsel__list [role="option"] svg { width: 15px; height: 15px; opacity: 0; flex: none; }
/* Текст и галочка внутри пункта — оформление, а не цель нажатия:
   пусть попадание всегда достаётся самому пункту. */
.nsel__list [role="option"] > * { pointer-events: none; }
/* подсветка идёт за клавиатурой и за мышью одинаково */
.nsel__list [role="option"].is-hot { background: var(--surface-2); color: var(--text); }
.nsel__list [role="option"].is-on { color: var(--accent); font-weight: 600; }
.nsel__list [role="option"].is-on svg { opacity: 1; }

/* в панели фильтров каталога список уже и ниже */
/* Именно 190px, а не min(190px, 100%): процент в min-width не
   участвует в расчёте собственной ширины родителя — тот ужимался
   до 232px, а список потом разворачивался до 190 и вылезал за колонку
   на 58px. Узкие экраны разведены правилом ниже. */
.ctool .nsel { min-width: 190px; }
/* На узком экране «232 товара» и «Сортировка» делили одну строку, и
   списку оставалось 232px при нужных 290 — он вылезал за экран на 42px.
   Раньше это было незаметно: колонка каталога сама была шире экрана
   и прятала переполнение. Ставим их в две строки, список тянется
   по остатку и умеет сжиматься. */
@media (max-width: 700px) {
  .ctool { flex-direction: column; align-items: stretch; }
  .ctool .nsel { flex: 1 1 auto; min-width: 0; }
}
.ctool .nsel__btn { min-height: 38px; font-size: .88rem; }
/* Подпись «Сортировка» и список рядом. Раньше их держал <label>, но
   он перехватывал нажатия по пунктам — см. разметку каталога. */
.ctool__sort { display: flex; align-items: center; gap: 8px; }


/* ---------- 32. Догрузка каталога ----------------------------- */
/* Каталог показывается порциями: 232 карточки разом дают страницу
   в 20 000 px и заметную паузу на вёрстке. */
.more { display: flex; justify-content: center; margin-top: clamp(24px, 3vw, 40px); }
.more[hidden] { display: none; }
.more .btn { min-width: min(260px, 100%); }

/* ---------- 33. Касание --------------------------------------
   Мышью в кнопку высотой 38px попадаешь без промаха, пальцем — нет:
   общепринятый минимум 44. Поднимаем только там, где указатель
   грубый, чтобы не разгонять плотную вёрстку на десктопе. */
@media (pointer: coarse) {
  .btn--buy, .nsel__btn, .ctool .nsel__btn, .qty button,
  .cabnav button, .cabnav a { min-height: 44px; }
  /* Пункты списка были 42px — почти норма, но промахнуться легко. */
  .nsel__list [role="option"] { min-height: 44px; padding-block: 11px; }
  .citybtn { height: 44px; }
  .qty button { min-width: 44px; }
}

/* Крошки — обычные ссылки высотой 19px. Как и у «Посмотреть все»,
   растим только зону нажатия: строка и её выравнивание не меняются. */
.crumbs a { position: relative; }
.crumbs a::before { content: ''; position: absolute; left: -6px; right: -6px; top: -12px; bottom: -12px; }

/* ---------- 34. История заказов в кабинете --------------------
   Раньше здесь был список обещаний («тут появится история заказов»),
   и он выглядел как меню, которого нет. Теперь показываем сами заказы. */
.authorders { margin-top: 34px; }
.authorders:empty { display: none; }
.auth__t2 {
  font-family: var(--f-display); font-weight: 700; font-size: 1.05rem;
  letter-spacing: -.02em; margin-bottom: 12px;
}
.orders { display: grid; gap: 12px; }
.order {
  padding: 16px 18px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--line);
}
.order__h { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.order__n { font-weight: 600; font-size: .95rem; }
.order__s {
  font-family: var(--f-label); font-size: .66rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em;
  padding: 4px 9px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--text-2); white-space: nowrap;
}
.order[data-status="new"]        .order__s { background: var(--accent-soft); color: var(--accent); }
.order[data-status="done"]       .order__s { background: rgba(63,169,106,.14); color: var(--ok); }
.order[data-status="cancelled"]  .order__s { background: rgba(212,56,45,.12); color: var(--danger); }
.order__m { margin-top: 6px; color: var(--text-3); font-size: .8rem; }
.order__l { margin-top: 12px; display: grid; gap: 6px; font-size: .88rem; }
.order__l li {
  display: grid; grid-template-columns: 1fr auto auto; gap: 10px;
  align-items: baseline; color: var(--text-2);
}
.ordq { color: var(--text-3); font-size: .82rem; }
.ords { color: var(--text); white-space: nowrap; }
.order__t {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: space-between;
  color: var(--text-3); font-size: .82rem;
}
.order__t b { color: var(--text); font-size: .95rem; }
/* ---------- бонусы ----------
   Блок в корзине и раздел кабинета. Своих цветов не заводим: зелёный
   для начислений — тот же var(--ok), что у выполненного заказа, синий
   акцент — тот же, что у всех подсказок. */
.bonusbox {
  display: grid; gap: 10px; padding-top: 14px; border-top: 1px solid var(--line);
}
.bonusbox__use { color: var(--text); font-size: .89rem; align-items: flex-start; }
.bonusbox .cart-hint a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.summary__row [data-bonus] { color: var(--ok); }
/* Кэшбэк стоит под итогом и в него не входит — набираем мельче,
   чтобы строка не спорила с суммой к оплате. */
.summary__row--back { margin-top: -6px; font-size: .85rem; color: var(--text-3); }
.summary__row--back [data-back] { color: var(--ok); font-weight: 600; }

.bonusnow {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.bonusnow b {
  display: block; margin-top: 2px;
  font-family: var(--f-display); font-size: 2rem; letter-spacing: -.04em;
}
.bonusrules { margin-top: 18px; display: grid; gap: 10px; }
.bonusrules li { display: flex; gap: 10px; color: var(--text-2); font-size: .9rem; line-height: 1.55; }
.bonusrules li::before {
  content: ''; flex: none; width: 6px; height: 6px; margin-top: 9px;
  border-radius: 50%; background: var(--accent);
}
.bonusrules b { color: var(--text); font-weight: 600; }

.bonuslog { margin-top: 14px; display: grid; }
.bonuslog__r {
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  padding: 11px 0; border-top: 1px solid var(--line); font-size: .9rem;
  color: var(--text-2);
}
.bonuslog__r:first-child { border-top: 0; }
.bonuslog__w { display: block; margin-top: 3px; color: var(--text-3); font-size: .78rem; }
.bonuslog__r b { white-space: nowrap; font-weight: 600; color: var(--text); }
.bonuslog__r b[data-plus] { color: var(--ok); }
/* ---------- полоса согласия на куки --------------------------
   Показывается один раз, живёт до ответа. Лежит над нижней панелью
   и поднимает над собой значок reCAPTCHA: углом внизу справа
   пользуются оба. */
.cookiebar {
  position: fixed; z-index: 90; left: 16px; right: 16px; bottom: 16px;
  width: min(620px, calc(100% - 32px)); margin-inline: auto;
  display: grid; gap: 12px; padding: 18px 20px;
  border-radius: var(--r-lg); background: var(--surface);
  border: 1px solid var(--line); box-shadow: var(--shadow-lift);
  animation: cookiein .24s var(--ease) both;
}
@keyframes cookiein { from { opacity: 0; transform: translateY(12px); } }
.cookiebar[data-gone] {
  opacity: 0; transform: translateY(10px);
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.cookiebar__t { color: var(--text-2); font-size: .88rem; line-height: 1.55; }
.cookiebar__act { display: flex; gap: 10px; flex-wrap: wrap; }
.cookiebar__act .btn { flex: 1 1 120px; }
.cookiebar__n { color: var(--text-3); font-size: .78rem; line-height: 1.5; }
.cookiebar__n a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
/* Пока полоса висит, значок reCAPTCHA прячем: они делят один угол,
   а двигать его некуда — на телефоне полоса занимает пол-экрана.
   Требование Google при этом выполнено: полоса сама называет
   reCAPTCHA и ведёт на политику. !important нужен — положение и
   видимость значка заданы инлайновым стилем. */
:root[data-cookiebar] .grecaptcha-badge { visibility: hidden !important; }
@media (max-width: 760px) {
  .cookiebar { bottom: 72px; }
}
@media (prefers-reduced-motion: reduce) {
  .cookiebar { animation: none; }
  .cookiebar[data-gone] { transition: none; }
}
