/* ===== ADelivery — клиентский PWA. Использует токены из ../styles.css =====
   Пластика 1-в-1 с мобилкой (mobile/lib/theme.dart): радиусы --r-*, тени
   --shadow-card/--shadow-float, типографика AppText, тёмная тема через
   [data-theme="dark"] на <html>. */
/* Локальные токены витрины (обе темы): фирменная бирюза сегмента «Продукты»
   и тёплая плашка «Закрыто» — раньше жили хардкодами (#2CB6A6,
   rgba(44,182,166,.14)) и не имели тёмных пар. Тёмная бирюза чуть светлее —
   тот же приём, что brand #FF6B00→#FF8A3D в styles.css. */
:root { --teal: #2CB6A6; --teal-soft: rgba(44, 182, 166, .14); --warn-soft: rgba(255, 179, 0, .14); }
[data-theme="dark"] { --teal: #3ECDBB; --teal-soft: rgba(62, 205, 187, .17); --warn-soft: rgba(255, 197, 51, .15); }
/* Полупрозрачные оттенки бренда. var(--accent) — hex, альфу из него не
   вытащить, а ореолы/рамки/свечения мобилки построены именно на brand с
   альфой (0.55 рамка чипа, 0.32 ореол активной категории, 0.14/0.18 свечение
   пустого состояния). Пары для тёмной темы обязательны: там brand светлее
   (#FF8A3D), и «светлый» оранжевый на тёмном фоне выглядит грязным. */
:root { --accent-ring: rgba(255,107,0,.55); --accent-halo: rgba(255,107,0,.32); --accent-glow: rgba(255,107,0,.14); --accent-glow0: rgba(255,107,0,0); }
[data-theme="dark"] { --accent-ring: rgba(255,138,61,.55); --accent-halo: rgba(255,138,61,.32); --accent-glow: rgba(255,138,61,.18); --accent-glow0: rgba(255,138,61,0); }

/* ===== Дизайн-проект 09.2026: шрифты бренда ===== Geist — весь текст,
   Playfair Display Bold Italic — одно акцентное слово и цены. Самохостинг из
   ../fonts/ (Google Fonts из Абхазии ненадёжен), woff2 ≈ 46 КБ на начертание,
   swap — текст виден сразу системным шрифтом. Включаем только клиентскому
   вебу (body.app-body--client): курьерский веб тоже грузит этот CSS, а
   кабинетам палитру и шрифты не тащим. В Playfair Display знака ₽ нет — его
   браузер берёт из следующего в стеке Geist (подстановка по глифу), так и
   задумано. Цифры — lining (lnum), иначе 3/5/7 уходят под базовую линию. */
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 400; font-display: swap; src: url(../fonts/Geist-Regular.woff2) format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 500; font-display: swap; src: url(../fonts/Geist-Medium.woff2) format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 600; font-display: swap; src: url(../fonts/Geist-SemiBold.woff2) format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 700 900; font-display: swap; src: url(../fonts/Geist-Bold.woff2) format('woff2'); }
@font-face { font-family: 'Playfair Display'; font-style: italic; font-weight: 700; font-display: swap; src: url(../fonts/PlayfairDisplay-BoldItalic.woff2) format('woff2'); }
.app-body--client { --font: 'Geist', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-family: var(--font); }
/* Цены — Playfair bold italic (брендбук): карточка блюда, строка меню, итог
   корзины и чекаута, сумма заказа, пилюля корзины, Маркет. Вес 700 — у
   Playfair нет 800, синтетический был бы «жирнее жирного». */
.app-body--client .dcard__price, .app-body--client .mitem__price, .app-body--client .total-line .big,
.app-body--client .ocard__price, .app-body--client .cart-pill__sum, .app-body--client .mrow__price,
.app-body--client .msheet__price > b, .app-body--client .t-price, .app-body--client .up-card__price {
  font-family: 'Playfair Display', var(--font); font-style: italic; font-weight: 700; font-variant-numeric: lining-nums; letter-spacing: 0; }

/* Жесты как в нативном приложении: manipulation убирает 300мс задержку и
   double-tap-zoom (пинч и прокрутка остаются), callout/выделение выключены —
   долгий тап по карточке больше не даёт системную лупу и «Скопировать».
   Выделение возвращаем там, где текст реально копируют (см. ниже). */
.app-body { background: var(--app-bg) no-repeat; background-color: var(--bg); -webkit-tap-highlight-color: transparent; line-height: 1.4; overscroll-behavior-y: none; touch-action: manipulation; -webkit-touch-callout: none; }
/* Поля ввода, чат и текстовые блоки заказа — выделяемы (иначе не скопировать
   номер заказа, адрес, сообщение). */
.app-body input, .app-body textarea, #msgs, .card, .ocard__comp, .cart-item, .chg-diff { -webkit-user-select: text; user-select: text; }
/* Фото не «отрываются» долгим тапом и не тащатся мышью — как в приложении. */
/* Запрет выделения — только на сенсорных экранах: на десктопе он мешал
   копировать адрес, номер заказа и состав (мышью текст должен выделяться). */
@media (hover: none) and (pointer: coarse) {
  .app-body { -webkit-user-select: none; user-select: none; }
  input, textarea, #msgs, .ocard__comp, .h1, .rcard__name, .dcard__name,
  .card { -webkit-user-select: text; user-select: text; }
}
.dcard__img, .rcard__img, .rhead__img, .mitem__img { -webkit-touch-callout: none; -webkit-user-drag: none; user-select: none; }
/* 100dvh дублирует 100vh: в Safari на iPhone 100vh считается по СВЁРНУТОЙ
   панели браузера, из-за чего экран оказывается выше видимой области. */
#app { min-height: 100vh; min-height: 100dvh; }

/* Сплэш по дизайн-проекту (09.2026): кремовый фон брендбука, эмблема «A.» и
   всадник, скачущий шестью кадрами (img/brand/emblem_1..6.svg). */
.app-splash { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; background: #FFF0E4; }
.app-splash__logo { width: 220px; height: 169px; background: url(img/brand/emblem_1.svg) center/contain no-repeat; animation: splash-gallop .54s steps(1) infinite; }
@keyframes splash-gallop {
  0% { background-image: url(img/brand/emblem_1.svg); } 16.6% { background-image: url(img/brand/emblem_2.svg); }
  33.3% { background-image: url(img/brand/emblem_3.svg); } 50% { background-image: url(img/brand/emblem_4.svg); }
  66.6% { background-image: url(img/brand/emblem_5.svg); } 83.3% { background-image: url(img/brand/emblem_6.svg); }
}
/* Мягкий пульс логотипа — на медленной сети сплэш не выглядит зависшим. */
@keyframes splash-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }

/* ---- общий каркас экрана ---- */
/* Низ экрана = высота плавающего меню (92px) ПЛЮС home-indicator: без
   --safe-bottom последняя карточка на iPhone уезжает под меню. Бока —
   max(16px, вырез): в ландшафте на iPhone контент не лезет под «уши».
   (--safe-left/--safe-right живут в styles.css; fallback 0px — на случай
   старого закешированного styles.css у уже установленного PWA.) */
.scr { max-width: 680px; margin-inline: auto; min-height: 100vh; min-height: 100dvh; padding-bottom: calc(var(--safe-bottom) + 92px); }
.scr--pad { padding: calc(12px + var(--safe-top)) max(16px, var(--safe-right, 0px)) calc(var(--safe-bottom) + 92px) max(16px, var(--safe-left, 0px)); }
/* Когда висит плавающая плашка активного заказа — резервируем под неё низ,
   иначе она перекрывает последнюю карточку/строку. Класс ставит renderOrderPill. */
body.has-order-pill .scr { padding-bottom: calc(var(--safe-bottom) + 158px); }
body.has-order-pill .scr--pad { padding-bottom: calc(var(--safe-bottom) + 158px); }
/* Верхний инсет: при статус-баре black-translucent шапка не уедет под чёлку.
   Фон — --canvas (верхняя точка фонового градиента, задаёт index.html):
   --bg на тёплом верхе давал цветную «ступеньку» под статус-баром. */
.bar { position: sticky; top: 0; z-index: 20; background: var(--canvas); padding: calc(var(--safe-top) + 10px) max(16px, var(--safe-right, 0px)) 8px max(16px, var(--safe-left, 0px)); }
.bar__row { display: flex; align-items: center; gap: 10px; }
/* Заголовки = AppText: h1 22/800/-0.3, h2 18/700 (theme.dart, AppText). */
.h1 { font-size: 22px; font-weight: 800; letter-spacing: -0.3px; line-height: 1.2; }
.h2 { font-size: 18px; font-weight: 700; line-height: 1.25; margin: 16px 0 8px; }
.muted { color: var(--muted); }
.spacer { flex: 1; }
.center-empty { text-align: center; color: var(--muted); padding: 48px 16px; }

/* ---- типографика-утилиты (шкала AppText из мобилки) ---- */
.t-display { font-size: 28px; font-weight: 800; letter-spacing: -0.5px; line-height: 1.15; }
.t-h1 { font-size: 22px; font-weight: 800; letter-spacing: -0.3px; line-height: 1.2; }
.t-h2 { font-size: 18px; font-weight: 700; line-height: 1.25; }
.t-h3 { font-size: 16px; font-weight: 700; line-height: 1.3; }
.t-body-m { font-size: 15px; font-weight: 600; line-height: 1.4; }
.t-secondary { font-size: 13px; font-weight: 500; color: var(--text-secondary); line-height: 1.35; }
.t-caption { font-size: 12px; font-weight: 500; color: var(--text-secondary); line-height: 1.3; }
.t-price { font-size: 16px; font-weight: 800; line-height: 1.2; }

/* ---- кнопки/инпуты (как в кабинете) ---- */
.btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; border:none; border-radius:var(--r-input); font:inherit; font-size:16px; font-weight:700; cursor:pointer; background:var(--accent); color:var(--on-accent); padding:0 18px; height:50px; width:100%; }
.btn:active { background:var(--accent-press); } .btn:disabled { opacity:.55; }
.btn--ghost { background:transparent; color:var(--accent); border:1.5px solid var(--line); }
.btn--ghost:active { background:var(--soft); }
/* Тональная кнопка (AppButtonVariant.tonal): brandSoft + brand. */
.btn--tonal { background:var(--soft); color:var(--accent); }
.btn--tonal:active { background:var(--soft); filter:brightness(.96); }
.btn--danger { background:var(--danger); color:var(--on-accent); }
.btn--danger:active { background:var(--danger); filter:brightness(.9); }
.btn--sm { height:38px; width:auto; padding:0 14px; font-size:14px; border-radius:var(--r-pill); }
/* Занятая кнопка: спиннер 20px строго вместо текста, геометрия не прыгает
   (как AppButton busy в мобилке, widgets/common.dart). */
.btn--busy { color:transparent !important; pointer-events:none; position:relative; }
.btn--busy::after { content:""; position:absolute; inset:0; margin:auto; width:20px; height:20px; border-radius:50%; border:2.4px solid var(--on-accent); border-top-color:transparent; animation:btn-spin .7s linear infinite; }
.btn--ghost.btn--busy::after, .btn--tonal.btn--busy::after { border-color:var(--accent); border-top-color:transparent; }
/* Занятая кнопка — всадник галопом (дизайн-проект 09.2026, идея 22; то же,
   что AppButton(busy) в приложении): ::before — спрайт-маска цветом текста
   кнопки (keyframes gallop ниже). Круглый спиннер ::after остаётся только при
   reduce-motion — статичный всадник не сказал бы «идёт работа». */
.btn--busy::before { content:""; position:absolute; inset:0; margin:auto; width:30px; height:22px; background:var(--on-accent);
  -webkit-mask:url(img/brand/rider_sprite.svg) 0 0 / 600% 100% no-repeat; mask:url(img/brand/rider_sprite.svg) 0 0 / 600% 100% no-repeat;
  animation:gallop .54s steps(6, end) infinite; }
.btn--ghost.btn--busy::before, .btn--tonal.btn--busy::before { background:var(--accent); }
.btn--busy::after { display:none; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
/* Поля как в мобилке (inputDecorationTheme): заливка surfaceAlt БЕЗ рамки,
   фокус — рамка brand 1.5px. */
.inp { width:100%; height:50px; padding:0 16px; font-size:16px; border:1.5px solid transparent; border-radius:var(--r-input); background:var(--surface-alt); color:var(--text); outline:none; font-family:var(--font); transition:border-color .15s, box-shadow .15s; }
.inp::placeholder { color:var(--text-tertiary); }
/* Многострочное поле: height:50px от .inp прижимал текст к верхней рамке и
   резал вторую строку. Даём высоту по контенту + честные вертикальные
   отступы (line-height 1.4, как у остального текста) и наследуем шрифт —
   иначе Safari подставляет системный monospace-подобный textarea-шрифт. */
textarea.inp { height:auto; min-height:64px; padding:12px 16px; line-height:1.4; resize:vertical; font-family:inherit; }
/* Фокус: рамка бренда + мягкое кольцо (одинаково для мыши и клавиатуры). */
.inp:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--soft); }
.err { background:var(--danger-soft); color:var(--danger); border-radius:var(--r-input); padding:10px 14px; font-size:14px; margin:8px 0; }
.field { margin-bottom: 12px; } .field label { display:block; font-size:13px; color:var(--muted); margin-bottom:6px; }
.note { font-size:13px; color:var(--muted); line-height:1.5; margin-top:10px; }

/* ---- вход ---- */
.auth-wrap { min-height:100vh; min-height:100dvh; display:flex; align-items:center; justify-content:center; padding:24px; }
.auth { width:min(420px,100%); background:var(--card); border-radius:var(--r-sheet); box-shadow:var(--shadow-card); padding:30px 24px; }
.auth__logo { width:56px; height:56px; border-radius:16px; margin:0 auto 14px; background:url(icon.svg) center/58% no-repeat, var(--grad); }
/* Лого-лок на входе (дизайн-проект, идея 15): кремовая плитка — эмблема +
   вордмарк («A» Playfair оранжевым + DELIVERY) + подпись, редкие копыта фоном.
   Плитка кремовая в обеих темах: это знак, а не поверхность интерфейса. */
.auth__lock { position:relative; overflow:hidden; background:#FFF0E4; color:#1C1A18; border-radius:20px; padding:20px 16px 16px; margin:-8px -6px 18px; text-align:center; }
.auth__lock .hoof-pat { color:#1C1A18; opacity:.06; }
.auth__emblem { position:relative; width:120px; height:92px; margin:0 auto; background:url(img/brand/emblem.svg) center/contain no-repeat; }
.wordmark { position:relative; font-weight:700; font-size:21px; line-height:1; letter-spacing:.16em; text-transform:uppercase; margin-top:8px; }
.wordmark b { font-family:'Playfair Display', Georgia, serif; font-style:italic; font-weight:700; color:#FF6B00; letter-spacing:0; font-size:1.2em; text-transform:none; margin-right:.04em; }
.auth__lock small { position:relative; display:block; font-size:12.5px; font-weight:500; opacity:.68; margin-top:7px; letter-spacing:.01em; }
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.auth h1 { text-align:center; font-size:22px; } .auth .sub { text-align:center; color:var(--muted); margin-bottom:20px; font-size:14px; }

/* ---- чипы города/адреса ---- */
/* Чип-фильтр = плоская пилюля 36px без тени (в мобилке это Container с
   заливкой, а не карточка): ряд чипов с тенями выглядел «пузырчатым» и
   ронял плавность скролла ленты на iPhone. */
.chip { display:inline-flex; align-items:center; gap:6px; height:36px; background:var(--card); border:1px solid var(--line); border-radius:var(--r-pill); padding:0 14px; font-size:14px; font-weight:600; cursor:pointer; box-shadow:none; }
/* Выбранный фильтр — мягкая брендовая заливка + рамка в бренде с альфой
   (читается и на светлом, и на тёмном фоне, в отличие от прозрачной). */
.chip--soft { background:var(--soft); border-color:var(--accent-ring); color:var(--accent); font-weight:700; }
.addr-line { display:flex; align-items:center; gap:8px; background:var(--card); border-radius:var(--r-card); padding:12px 14px; box-shadow:var(--shadow-card); cursor:pointer; margin-top:10px; }

/* ---- сегменты ---- */
.seg { display:flex; gap:8px; margin:14px 0 6px; }
.seg button { flex:1; height:46px; border:none; border-radius:var(--r-input); background:var(--card); color:var(--muted); font-weight:700; font-size:15px; box-shadow:var(--shadow-card); cursor:pointer; }
.seg button.on { background:var(--soft); color:var(--accent); }
/* Недоступный вариант (напр. самовывоз без онлайн-оплаты): гасим сильнее и
   снимаем тень — кнопка перестаёт выглядеть нажимаемой, а не «просто бледной». */
.seg button:disabled { opacity:.45; box-shadow:none; cursor:not-allowed; }

/* ---- карточки ресторанов ---- */
.rcard { background:var(--card); border-radius:var(--r-card-lg); overflow:hidden; box-shadow:var(--shadow-card); margin-bottom:14px; cursor:pointer; }
/* Фото в «паспарту»: 6px белого поля вокруг снимка и собственный радиус 16 —
   ровно как RestaurantCard в мобилке (Padding.fromLTRB(6,6,6,0) + FoodImage
   radius 16). Фото «во всю карточку» встык — главный признак веб-страницы. */
.rcard__img { width:100%; aspect-ratio:16/9; object-fit:cover; background:var(--soft); display:block; border-radius:16px; }
/* Тело карточки выровнено по фото (12/12 вместо 14) — иначе текст «вылезает»
   левее снимка (мобилка: fromLTRB(12,10,12,12)). */
.rcard__b { padding:10px 12px 12px; }
/* Название = AppText.h2 (18/700/1.25), мета = AppText.secondary (13/500). */
.rcard__name { font-weight:700; font-size:18px; line-height:1.25; }
.rcard__meta { color:var(--muted); font-size:13px; font-weight:500; margin-top:3px; display:flex; gap:10px; flex-wrap:wrap; }
.badge-self { font-size:11px; font-weight:700; color:var(--accent); background:var(--soft); padding:2px 8px; border-radius:var(--r-pill); }

/* ---- ресторан / меню ---- */
.rhead__img { width:100%; aspect-ratio:16/9; object-fit:cover; background:var(--soft); }
.mitem { display:flex; gap:12px; padding:12px 0; border-bottom:1px solid var(--line); cursor:pointer; }
.mitem:last-child { border-bottom:none; }
.mitem__img { width:72px; height:72px; border-radius:var(--r-input); object-fit:cover; background:var(--soft); flex:none; }
.mitem__name { font-weight:700; } .mitem__desc { color:var(--muted); font-size:13px; margin-top:2px; }
.mitem__price { font-weight:800; font-size:16px; margin-top:6px; }
/* Сетка блюд 2 колонки (паритет с приложением): фото + пилл-цена + бейдж. */
.dish-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:12px; margin-bottom:6px; }
/* Ритм секций меню плотнее (паритет с мобилкой): межсекционный зазор ~16px
   (6px низ сетки + 10px верх заголовка), заголовок→сетка — 8px от .h2. */
.h2[id^="cat"] { margin-top:10px; }
/* --- Компакт-лента (напитки/соусы/добавки): горизонтальный скролл вместо
   сетки 2xN — паритет с мобилкой. Скроллбар скрыт, мягкий snap; вертикальный
   паддинг — чтобы тень/бейджи не резались overflow'ом. --- */
.dish-row { display:flex; gap:10px; overflow-x:auto; -webkit-overflow-scrolling:touch; margin:0 -16px; padding:2px 16px 8px; scroll-snap-type:x proximity; scroll-padding-left:16px; scrollbar-width:none; -ms-overflow-style:none; }
.dish-row::-webkit-scrollbar { display:none; }
.dcard--sm { flex:0 0 104px; width:104px; scroll-snap-align:start; }
.dcard--sm .dcard__ph { border-radius:var(--r-input); }
.dcard--sm .dcard__name { font-size:12px; line-height:1.25; margin-top:6px; min-height:30px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; word-break:break-word; }
.dcard__prow { display:flex; align-items:center; justify-content:space-between; gap:6px; margin-top:3px; }
.dcard__pr { font-weight:800; font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.dcard__addsm { flex:none; width:26px; height:26px; padding:0; border:none; border-radius:50%; background:var(--soft); color:var(--accent); font-size:18px; line-height:1; font-weight:700; cursor:pointer; display:flex; align-items:center; justify-content:center; transition:transform .12s ease, background-color .15s ease; }
.dcard__addsm:active { transform:scale(.9); }
.dcard--sm .dcard__qty { right:5px; top:5px; min-width:20px; height:20px; padding:0 6px; border-radius:10px; font-size:11.5px; }
.dcard--sm .dcard__badge { left:5px; top:5px; font-size:9.5px; padding:2px 6px; }
.dcard--sm .dcard__price--off { left:5px; bottom:5px; font-size:10.5px; font-weight:700; padding:3px 7px; }
.dcard { cursor:pointer; }
.dcard__ph { position:relative; aspect-ratio:1; border-radius:var(--r-card); overflow:hidden; background:var(--soft); }
.dcard__img { width:100%; height:100%; object-fit:cover; display:block; }
/* Пилл-цена = AppText.price (16/800) + floatingShadow, как в cards.dart. */
.dcard__price { position:absolute; left:8px; bottom:8px; background:var(--card); color:var(--text); font-weight:800; font-size:16px; line-height:1.2; padding:5px 10px; border-radius:var(--r-pill); box-shadow:var(--shadow-float); }
.dcard__badge { position:absolute; left:8px; top:8px; font-size:11px; font-weight:700; padding:3px 8px; border-radius:var(--r-pill); }
.dcard__badge--hit { background:var(--soft); color:var(--accent); }
.dcard__badge--new { background:var(--info-soft); color:var(--info); }
.dcard__badge--spicy { background:var(--danger-soft); color:var(--danger); }
/* Название блюда = AppText.h3 (16/700/1.3) с воздухом 8px до фото — в мобилке
   подпись читается как заголовок, а 14px превращали сетку в «каталог». */
.dcard__name { font-weight:700; font-size:16px; line-height:1.3; margin-top:8px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
/* Круглая «+» поверх фото (cards.dart: 40×40, surface, floatingShadow,
   PressScale .88) — парная пиллу цены слева-снизу. Позицию задаёт разметка. */
.dcard__add { position:absolute; right:8px; bottom:8px; width:40px; height:40px; padding:0; border:none; border-radius:50%; background:var(--card); color:var(--text); box-shadow:var(--shadow-float); font-size:22px; font-weight:600; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; transition:transform .12s ease, background-color .15s ease; }
.dcard__add:active { transform:scale(.92); }
/* Тёмная тема: --shadow-float там равен none, и пилюли/кнопки поверх фото
   теряли границу — тонули в тёмных снимках. Держим их стеклянной рамкой
   (ровно этот приём в cards.dart: border только при AppColors.dark). */
[data-theme="dark"] .dcard__price, [data-theme="dark"] .dcard__add, [data-theme="dark"] .up-card__add { border:1px solid var(--glass-border); }
.card { background:var(--card); border-radius:var(--r-card); box-shadow:var(--shadow-card); padding:14px 16px; margin-bottom:12px; }

/* ---- корзина ---- */
.qty { display:inline-flex; align-items:center; gap:10px; }
.qty button { width:32px; height:32px; border-radius:10px; border:1.5px solid transparent; background:var(--input-bg); font-size:18px; font-weight:700; cursor:pointer; color:var(--accent); }
.cart-item { display:flex; gap:10px; align-items:flex-start; padding:12px 0; border-bottom:1px solid var(--line); }
.cart-item:last-child { border-bottom:none; }
.row-line { display:flex; justify-content:space-between; padding:5px 0; }
.row-line b { font-weight:800; }
.total-line { display:flex; justify-content:space-between; align-items:center; margin-top:8px; padding-top:12px; border-top:1px solid var(--line); }
.total-line .big { font-size:22px; font-weight:800; }

/* ---- нижняя навигация (floating) ---- */
/* Бока — max(12px, вырез): в ландшафте на iPhone панель не подлезает под «уши». */
.nav { position:fixed; left:0; right:0; bottom:0; z-index:30; padding:0 max(12px, var(--safe-right, 0px)) calc(var(--safe-bottom) + 10px) max(12px, var(--safe-left, 0px)); pointer-events:none; }
.nav__in { max-width:560px; margin-inline:auto; background:var(--glass-bg); -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(180%); backdrop-filter:blur(var(--glass-blur)) saturate(180%); border:1px solid var(--glass-border); border-radius:24px; box-shadow:var(--glass-shadow); display:flex; pointer-events:auto; overflow:hidden; }
.nav__b { flex:1; border:none; background:transparent; padding:8px 0; display:flex; flex-direction:column; align-items:center; gap:2px; color:var(--muted); font-size:11px; font-weight:600; cursor:pointer; position:relative; }
.nav__b.on { color:var(--accent); }
/* Активная вкладка = «таблетка» 56×32 r16 под иконкой (AppBottomNav: pill
   brandSoft, easeOutCubic 280мс). Раньше активность показывал только цвет —
   это и читалось как сайт, а не приложение. Ширина/высота живут на .nav__ic,
   поэтому иконке внутри нужен явный размер, иначе SVG растянется на всю
   таблетку. */
.nav__ic { display:flex; align-items:center; justify-content:center; width:56px; height:32px; border-radius:16px; background:transparent; transition:background-color .28s cubic-bezier(.33,0,.2,1), color .28s cubic-bezier(.33,0,.2,1); }
.nav__ic svg { width:24px; height:24px; display:block; }
.nav__b.on .nav__ic { background:var(--soft); color:var(--accent); }
.nav__badge { position:absolute; top:4px; left:calc(50% + 8px); min-width:16px; height:16px; padding:0 4px; border-radius:var(--r-pill); background:var(--accent); color:var(--on-accent); font-size:10px; font-weight:700; display:flex; align-items:center; justify-content:center; }

/* ---- статусы заказа ---- */
.steps { display:flex; flex-direction:column; gap:0; }
.step { display:flex; gap:12px; align-items:flex-start; }
/* Точка шага — капля из эмблемы (дизайн-проект, идея 12), а не круг. */
.step__dot { width:15px; height:14px; background:var(--line); margin-top:3px; flex:none;
  -webkit-mask:url(img/brand/drop.svg) center/contain no-repeat; mask:url(img/brand/drop.svg) center/contain no-repeat; }
.step.done .step__dot { background:var(--accent); }
.step__line { width:2px; flex:1; background:var(--line); margin:2px 0; min-height:18px; }
.step.done .step__line { background:var(--accent); }
.ostatus { font-size:13px; font-weight:700; padding:4px 10px; border-radius:var(--r-pill); background:var(--soft); color:var(--accent); }

/* ---- шторки ---- */
.sheet-back { position:fixed; inset:0; background:rgba(20,18,16,.45); z-index:50; display:flex; align-items:flex-end; justify-content:center; }
.sheet { background:var(--glass-strong); -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(180%); backdrop-filter:blur(var(--glass-blur)) saturate(180%); border-top:1px solid var(--glass-border); width:min(560px,100%); border-radius:var(--r-sheet) var(--r-sheet) 0 0; padding:18px 18px calc(var(--safe-bottom) + 18px); max-height:92vh; max-height:92dvh; overflow-y:auto; overscroll-behavior:contain; }
@media(min-width:600px){ .sheet-back{align-items:center;} .sheet{border-radius:var(--r-dialog);} }
/* Экранная клавиатура (iOS не сжимает layout-viewport, поэтому fixed-слои
   уезжали под неё): --kb и .kb-open ставит app.js по visualViewport.
   Шторку поднимаем над клавиатурой и укорачиваем, нижнее меню и плавающие
   плашки на время ввода прячем — как делает нативная форма. */
.sheet-back { bottom: var(--kb, 0px); }
.sheet { max-height: calc(92dvh - var(--kb, 0px)); }
@media (max-width: 899.98px) {
  body.kb-open .nav,
  body.kb-open .cart-pill,
  body.kb-open #orderPill { display:none; }
  body.kb-open .co-cta { position:static; padding-bottom:16px; }
}
/* Пока фон заблокирован шторкой (body position:fixed), «резинка» страницы
   не должна оставлять белую полосу под контентом. */
/* Фон приложения повторяем: голый var(--bg) давал вспышку «персиковый →
   серый» при открытии каждой шторки. */
body.sheet-open { overflow:hidden; background:var(--app-bg) no-repeat; background-color:var(--bg); }
.sheet h3 { font-size:18px; margin-bottom:12px; }
.sheet__grip { width:38px; height:4px; border-radius:2px; background:var(--line); margin:0 auto 14px; }
/* Ряд кнопок в шторке подтверждения (замена системного confirm()). */
.sheet__actions { display:flex; gap:10px; margin-top:16px; }
.sheet__actions .btn { flex:1; width:auto; }
.opt { display:flex; align-items:center; gap:10px; padding:10px 0; border-bottom:1px solid var(--line); }
.opt:last-child { border-bottom:none; }
.opt .spacer { flex:1; }

/* ---- тост: как снекбар мобилки — радиус 16, слайд снизу 250ms, иконка ---- */
.toast { position:fixed; left:50%; bottom:calc(var(--safe-bottom) + 96px); transform:translate(-50%,12px); display:flex; align-items:center; gap:10px; background:var(--toast-bg); color:var(--toast-text); padding:12px 18px; border-radius:16px; font-size:14px; line-height:1.35; z-index:80; opacity:0; transition:opacity .25s ease, transform .25s cubic-bezier(.2,.8,.3,1); pointer-events:none; max-width:90%; box-shadow:var(--shadow-float); }
.toast.on { opacity:1; transform:translate(-50%,0); }
/* С плашкой активного заказа меню выше — тост иначе всплывает прямо под ней. */
body.has-order-pill .toast { bottom:calc(var(--safe-bottom) + 158px); }
.toast--err { background:var(--danger); color:var(--on-accent); }
.toast__ic { width:18px; height:18px; flex:none; }
/* Тост с действием «Отменить» — кнопка справа, кликабельна (в отличие от текста). */
.toast--action { pointer-events:auto; }
.toast__undo { border:none; background:none; color:var(--accent); font-weight:700; font-size:14px; cursor:pointer; padding:2px 4px; margin-left:6px; flex:none; }

.sg { display:inline-flex; gap:6px; flex-wrap:wrap; }
.sg button { border:1.5px solid transparent; background:var(--input-bg); border-radius:var(--r-pill); padding:7px 13px; font-size:14px; cursor:pointer; color:var(--text); }
.sg button.on { background:var(--soft); border-color:transparent; color:var(--accent); font-weight:700; }
/* Номинал сдачи меньше итога — серый и некликабельный (невалидную не выбрать). */
.sg button:disabled { opacity:.4; cursor:not-allowed; }

/* Ссылка-раскрытие свёрнутого блока (промокод, сдача): иконка + текст, как ряд-карточка. */
.disclose { display:flex; align-items:center; gap:10px; width:100%; background:var(--card); border:1px solid var(--line); border-radius:var(--r-card); box-shadow:var(--shadow-card); padding:14px 16px; font-size:15px; font-weight:600; color:var(--accent); cursor:pointer; text-align:left; }
.disclose svg { width:20px; height:20px; flex:none; }
.disclose__hint { margin-left:auto; color:var(--muted); font-weight:500; font-size:13px; }
.suggest { border:1px solid var(--line); border-radius:var(--r-input); margin-top:6px; overflow:hidden; }
.suggest div { padding:11px 14px; border-bottom:1px solid var(--line); cursor:pointer; font-size:14px; }
.suggest div:last-child { border-bottom:none; }
.back-btn { width:40px; height:40px; border-radius:var(--r-input); border:none; background:var(--card); box-shadow:var(--shadow-card); font-size:20px; cursor:pointer; color:var(--text); }
.rating-star { color:var(--star); }
/* Автоподсказки адреса (выпадающий список под полем «Адрес») */
.addr-wrap { position:relative; }
.addr-sug { position:absolute; left:0; right:0; top:100%; z-index:30; background:var(--card); border:1px solid var(--line); border-radius:var(--r-input); box-shadow:var(--shadow-card); margin-top:4px; overflow:hidden; max-height:240px; overflow-y:auto; overscroll-behavior:contain; }
.addr-sug:empty { display:none; }
.addr-sug__i { padding:11px 14px; border-bottom:1px solid var(--line); cursor:pointer; font-size:14px; }
.addr-sug__i:last-child { border-bottom:none; }
.addr-sug__i:active, .addr-sug__i:hover { background:var(--soft); }

/* ===== Горизонтальные ленты: без скроллбара, как в мобилке ===== */
.hscroll { display:flex; gap:8px; overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; -ms-overflow-style:none; overscroll-behavior-x:contain; }
.hscroll::-webkit-scrollbar { display:none; }
.hscroll--lg { gap:12px; }
.hscroll > * { flex:none; }

/* Контейнер сообщений чата: докрутка не дёргает страницу под ним. */
#msgs { overscroll-behavior:contain; }

/* ===== Скелетоны с бегущим бликом (widgets/skeleton.dart: 1.3s,
   surfaceAlt→divider→surfaceAlt, stops 30/50/70) ===== */
.skel { border-radius:12px; background:linear-gradient(90deg, var(--surface-alt) 30%, var(--line) 50%, var(--surface-alt) 70%) var(--surface-alt); background-size:200% 100%; animation:skel-shimmer 1.3s linear infinite; }
@keyframes skel-shimmer { from { background-position:150% 0; } to { background-position:-50% 0; } }
/* Обёртка списка скелетонов: появление с задержкой 300ms — анти-мигание
   (SkeletonList в мобилке). */
.skel-wrap { animation:skel-in .2s ease .3s backwards; }
@keyframes skel-in { from { opacity:0; } }
/* Кирпичики для макетов, повторяющих реальные карточки. */
.skel--photo { aspect-ratio:16/9; border-radius:0; }         /* фото rcard (внутри .rcard) */
/* Скелет фото повторяет «паспарту» настоящей карточки — иначе на загрузке
   макет дёргается: серый прямоугольник встык, а через миг фото с полями. */
.rcard .skel--photo { margin:6px 6px 0; border-radius:16px; }
.skel--thumb { width:72px; height:72px; border-radius:var(--r-input); flex:none; } /* фото mitem */
.skel--circle { border-radius:50%; }
.skel--line { height:14px; }
.skel--line-lg { height:18px; }
.skel--w80 { width:80%; } .skel--w60 { width:60%; } .skel--w40 { width:40%; }

/* ===== Пустые состояния (widgets/empty_state.dart): круг 96 + эмодзи 44 +
   заголовок + подпись + тональная CTA ===== */
.empty { display:flex; flex-direction:column; align-items:center; text-align:center; padding:48px 32px 24px; }
/* Не плоский круг, а слоёное свечение 112px (EmptyState: широкий брендовый
   ореол 112 + плотное тёплое ядро 88 со стопами .55→1). Плоская заливка
   выглядела «заглушкой», свечение — фирменной паузой. */
.empty__circle { width:112px; height:112px; border-radius:50%; display:grid; place-items:center; font-size:44px; line-height:1;
  background:
    radial-gradient(circle, var(--soft) 0 43%, transparent 79%),
    radial-gradient(circle, var(--accent-glow) 0, var(--accent-glow0) 100%); }
.empty__title { font-size:18px; font-weight:700; line-height:1.25; margin-top:16px; }
.empty__sub { font-size:13px; font-weight:500; color:var(--muted); line-height:1.35; margin-top:6px; max-width:34ch; }
.empty .btn { width:auto; margin-top:20px; }
/* Ошибка загрузки (ErrorState): ПЛОСКИЙ круг 96 surfaceAlt + 📡 + текст +
   «Повторить» — ошибка намеренно без брендового свечения (мобилка так же). */
.empty--error .empty__circle { width:96px; height:96px; background:var(--surface-alt); }
.empty--error .empty__msg { font-size:15px; line-height:1.4; margin-top:16px; max-width:36ch; }

/* ===== Появление списков: fadeInUp со stagger (JS ставит animation-delay
   первым ~8 элементам при первом рендере) ===== */
@keyframes fadeInUp { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }
.fin { animation:fadeInUp .3s ease both; }

/* ===== Живые нажатия: scale(.97), как Material-ripple в мобилке ===== */
.pressable, .btn, .chip, .seg button, .sg button, .rcard, .dcard, .opt, .back-btn, .qty button, .addr-line { transition:transform .12s ease, box-shadow .12s ease, background-color .15s ease, opacity .15s ease, filter .15s ease; }
.pressable:active, .btn:active, .chip:active, .seg button:active, .sg button:active, .rcard:active, .dcard:active, .opt:active, .back-btn:active, .qty button:active, .addr-line:active { transform:scale(.97); }
/* Карточкам на нажатии дополнительно приглушаем тень. Чипы и «назад» из
   списка убраны: они теперь плоские (тень:none), и «приглушение» давало бы
   у них обратный эффект — тень ПОЯВЛЯЛАСЬ бы под пальцем. */
.rcard:active, .addr-line:active, .seg button:active { box-shadow:0 1px 6px rgba(28,27,25,.05); }

/* ===== Единый видимый фокус для клавиатуры ===== */
.btn:focus-visible, .chip:focus-visible, .seg button:focus-visible, .sg button:focus-visible, .nav__b:focus-visible, .back-btn:focus-visible, .qty button:focus-visible, .opt:focus-visible, .rcard:focus-visible, .dcard:focus-visible, .mitem:focus-visible, .addr-line:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

/* ===== Микро-блок (JS-обвязка: тост/скелетоны/confirmSheet) ===== */
/* Шторка подтверждения (#csheet) живёт ПОВЕРХ обычной шторки (z-index 50). */
.sheet-back--top { z-index:60; }
/* Скелет карточки блюда в сетке 2 колонки (квадратное фото, как .dcard__ph). */
.skel--dish { aspect-ratio:1; border-radius:var(--r-card); }

/* === витрина === Главная как в мобилке (home.dart + widgets/cards.dart):
   пилюли поверх фото карточки, глас-сегмент со скользящим тамбом,
   SVG-сердечко, «Рекомендуем», истории. Только токены — работает в 2 темах. */

/* -- карточка заведения: мета пилюлями поверх фото (RestaurantCard) -- */
.rcard__ph { position:relative; margin:6px 6px 0; border-radius:16px; overflow:hidden; }
.rcard__pill { position:absolute; font-size:13px; font-weight:600; line-height:1.2; padding:5px 10px; border-radius:var(--r-pill); pointer-events:none; }
/* Рейтинг — тёмный скрим _photoScrim (#1C1B19 70%), белый текст, ★ = --star. */
.rcard__pill--rate { left:10px; bottom:10px; background:rgba(28,27,25,.7); color:#fff; }
/* Время доставки — тёмный скрим, как у рейтинга. Раньше здесь было «стекло»
   с backdrop-filter, но на iPhone каждый блюр над фото в ленте — отдельный
   слой композитинга: скролл витрины заметно дёргался. Плотная пилюля читается
   на любом снимке и стоит ноль. */
.rcard__pill--time { right:10px; top:10px; background:rgba(28,27,25,.72); color:#fff; }
/* Закрытое заведение: ч/б фото (greyscale-матрица мобилки) + тёмная пилюля. */
.rcard__pill--closed { right:10px; top:10px; background:rgba(28,27,25,.7); color:#fff; }
.rcard__img--closed { filter:grayscale(1); }
/* Вся карточка закрытого — приглушённая (28.07): серое фото + притушенный
   текст, но карточка кликабельна — внутри доступен предзаказ ко времени. */
.rcard--closed .rcard__img { filter:grayscale(1); opacity:.9; }
.rcard--closed .rcard__b { opacity:.6; }
/* Баннер закрытия на странице заведения: клиент видит «Закрыто» ещё до
   набора корзины (паритет с пилюлей на карточке витрины). */
.rest-closed { display:flex; align-items:center; gap:8px; margin:0 0 10px; padding:10px 12px; border-radius:14px; background:var(--warn-soft); color:var(--text); font-weight:600; font-size:14px; }
.rest-closed svg { flex:none; width:18px; height:18px; opacity:.7; }
/* Серый вариант (28.07): «Сейчас закрыто · откроется …» + подстрока про
   доступность только предзаказа ко времени. */
.rest-closed--grey { background:var(--surface-alt); }
.rest-closed__sub { font-weight:500; font-size:12.5px; color:var(--text-secondary); margin-top:2px; }
.rcard__self { position:absolute; left:10px; top:10px; }
/* Чип «Домашняя кухня» (лайт-режим партнёра) — рядом с названием заведения */
.rcard__litechip { vertical-align:2px; margin-left:2px; white-space:nowrap; }
/* Одна строка категорий с многоточием (как в мобильной карточке). */
.rcard__meta--1l { display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Горизонтальный вариант для ленты «Вы заказывали» (RestaurantCard 300px). */
.rcard--h { flex:none; width:300px; margin-bottom:4px; }

/* -- сердечко избранного: кружок 36px + pop (cards.dart). Заливка glass-strong
   и светлая рамка остались, backdrop-filter снят: он висел на КАЖДОЙ карточке
   ленты и съедал плавность скролла на iPhone. Полупрозрачная заливка поверх
   фото и без блюра выглядит «стеклянной». -- */
.rcard__fav { position:absolute; right:10px; bottom:10px; width:36px; height:36px; border-radius:50%; display:flex; align-items:center; justify-content:center; cursor:pointer; background:var(--glass-strong); border:1px solid var(--glass-border); }
.rcard__fav svg { width:20px; height:20px; fill:none; stroke:var(--muted); stroke-width:2; transition:fill .15s ease, stroke .15s ease; }
.rcard__fav.on svg { fill:var(--accent); stroke:var(--accent); }
.rcard__fav.pop svg { animation:fav-pop .3s ease; }
@keyframes fav-pop { 0% { transform:scale(1); } 40% { transform:scale(1.35); } 100% { transform:scale(1); } }

/* -- сегмент «Рестораны|Продукты»: стекло + скользящий тамб с пружиной
   (_BusinessSegmentedControl: GlassPanel r16, p4). Свой акцент на сегмент:
   рестораны — бренд, «Продукты» — зелёно-бирюзовый (#2CB6A6), чтобы
   переключение читалось мгновенно (паритет с мобилкой). -- */
/* Дорожка сегмента — плотная surfaceAlt вместо стекла: блюр здесь стоял
   поверх скроллящейся витрины и пересчитывался на каждый кадр. */
.seg2 { --seg-accent:var(--accent); --seg-ring:rgba(232,95,0,.22); position:relative; display:flex; padding:4px; margin:14px 0 6px; border-radius:16px; background:var(--surface-alt); border:1px solid var(--line); }
.seg2.grocery { --seg-accent:var(--teal); --seg-ring:rgba(44,182,166,.35); }
[data-theme="dark"] .seg2.grocery { --seg-ring:rgba(62,205,187,.38); }
/* Тамб — мягкая брендовая заливка (в «Продуктах» бирюзовая) с карточной
   тенью: активный сегмент виден мгновенно, даже когда на него не смотришь. */
.seg2__thumb { position:absolute; top:4px; left:4px; width:calc(50% - 4px); height:calc(100% - 8px); background:var(--soft); border-radius:12px; box-shadow:var(--shadow-card), inset 0 0 0 1.5px var(--seg-ring); transition:transform .3s cubic-bezier(.34,1.56,.64,1), background-color .25s ease, box-shadow .25s ease; }
.seg2.grocery .seg2__thumb { transform:translateX(100%); background:var(--teal-soft); }
.seg2 button { flex:1; position:relative; z-index:1; display:inline-flex; align-items:center; justify-content:center; gap:7px; height:40px; border:none; background:none; font:inherit; font-size:15px; font-weight:600; color:var(--muted); cursor:pointer; transition:color .15s ease; }
/* Текст активного — в акценте СЕГМЕНТА (бренд / бирюза «Продуктов»), а не
   нейтральный: подпись и иконка теперь одного цвета, как в мобилке. */
/* Подпись активного сегмента оставляем тёмной: акцент на мягкой заливке
   тамба давал контраст ~2.4:1 — «Рестораны» читались хуже неактивных.
   Цветом акцента остаётся иконка (правило ниже). */
.seg2 button.on { font-weight:700; color:var(--text); }
.seg2 button svg { width:18px; height:18px; }
.seg2 button.on svg { color:var(--seg-accent); }

/* -- лента сортировки: ведущая подпись «⇅ Сортировка» (_sortChips) -- */
.sort-lead { display:inline-flex; align-items:center; gap:4px; color:var(--muted); font-size:13px; font-weight:600; }

/* -- «Рекомендуем»: широкая фото-карточка 260×120 с градиентом и чипом
   (_RecommendationCard, home.dart) -- */
.rec-card { position:relative; width:260px; height:120px; border-radius:20px; overflow:hidden; cursor:pointer; background-color:var(--soft); background-position:center; background-size:cover; }
.rec-card__grad { position:absolute; inset:0; background:linear-gradient(180deg, transparent 35%, rgba(28,27,25,.7)); }
.rec-card__label { position:absolute; top:10px; left:10px; background:var(--soft); color:var(--accent); font-size:12px; font-weight:700; padding:4px 10px; border-radius:var(--r-pill); }
.rec-card__b { position:absolute; left:12px; right:12px; bottom:10px; }
.rec-card__name { color:#fff; font-size:15px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-shadow:0 1px 3px rgba(0,0,0,.4); }
.rec-card__sub { color:rgba(255,255,255,.7); font-size:12px; font-weight:600; margin-top:1px; }
.rec-card:active { transform:scale(.97); transition:transform .12s ease; }

/* -- просмотр историй: заполнение активного сегмента (пауза удержанием =
   animationPlayState:paused, поэтому анимация, а не transition) -- */
@keyframes story-fill { to { width:100%; } }

/* === путь покупателя === Страница заведения, шторка блюда, корзина, чекаут,
   трекинг — паритет с restaurant.dart / dish_sheet.dart / cart.dart /
   checkout.dart / status_timeline.dart. Только токены — корректно в 2 темах. */

/* -- кнопка «назад»: круг с SVG-стрелкой (CircleBorder + arrow_back_rounded
   из мобилки) вместо белого квадрата с «‹». На ПЛОСКИХ экранах (заголовок на
   фоне --bg) — простая заливка surfaceAlt без рамки и без блюра: размывать
   там нечего, а слой композитинга блюр создавал. Стеклянный вариант остался
   только там, где кнопка лежит поверх фото — см. .rhead__back ниже. -- */
.back-btn { border-radius:50%; background:var(--surface-alt); border:none; box-shadow:none; display:inline-flex; align-items:center; justify-content:center; flex:none; color:var(--text); }
.back-btn svg { width:20px; height:20px; }

/* -- hero заведения: градиент-скрим снизу, скруглённый низ, кнопки и пилюли
   поверх фото (SliverAppBar 240px из restaurant.dart) -- */
.rhead { position:relative; margin:0 -16px 12px; border-radius:0 0 22px 22px; overflow:hidden; background:var(--soft); }
.rhead .rhead__img { display:block; width:100%; aspect-ratio:16/9; max-height:280px; object-fit:cover; border-radius:0; }
.rhead--noimg .rhead__img { aspect-ratio:auto; height:150px; background:var(--grad); }
.rhead::after { content:""; position:absolute; inset:0; background:linear-gradient(to top, rgba(0,0,0,.38), transparent 55%); pointer-events:none; }
/* Кнопки поверх обложки — полупрозрачное «стекло» с рамкой, но БЕЗ
   backdrop-filter: на sticky-обложке с параллаксом блюр перерисовывался на
   каждый кадр скролла. Плотности glass-strong хватает, чтобы стрелка и
   сердечко читались на любом фото. */
.rhead__back { position:absolute; left:12px; top:calc(var(--safe-top) + 10px); z-index:2; background:var(--glass-strong); border:1px solid var(--glass-border); box-shadow:var(--shadow-card); }
.rhead__fav { position:absolute; right:12px; top:calc(var(--safe-top) + 10px); z-index:2; width:40px; height:40px; border-radius:50%; display:flex; align-items:center; justify-content:center; cursor:pointer; background:var(--glass-strong); border:1px solid var(--glass-border); }
.rhead__fav svg { width:22px; height:22px; fill:none; stroke:var(--muted); stroke-width:2; transition:fill .15s ease, stroke .15s ease; }
.rhead__fav.on svg { fill:var(--accent); stroke:var(--accent); }
.rhead__fav.pop svg { animation:fav-pop .3s ease; }
.rhead__pills { position:absolute; left:12px; right:12px; bottom:12px; display:flex; align-items:center; gap:8px; z-index:2; }
.rhead__pill { font-size:13px; font-weight:600; line-height:1.2; padding:5px 10px; border-radius:var(--r-pill); }
.rhead__pill--rate { background:rgba(28,27,25,.7); color:#fff; }
/* Пара к рейтингу: тёмный скрим вместо блюра (см. .rcard__pill--time). */
.rhead__pill--time { background:rgba(28,27,25,.72); color:#fff; }

/* -- hero-переход фото карточка→обложка (View Transitions; iOS18+/Chrome111+,
   без поддержки — чистый фоллбэк без анимации) -- */
::view-transition-group(rest-photo) { animation-duration:.35s; }
::view-transition-old(rest-photo), ::view-transition-new(rest-photo) { animation-duration:.35s; height:100%; object-fit:cover; }

/* -- sticky-категории: скрытый скроллбар, активный чип «soft».
   padding-top учитывает --safe-top: в установленном PWA с чёлкой прилипшие
   чипы иначе оказывались ПОД текстом статус-бара (top:0 + inset). -- */
/* Липкая лента прилипает поверх ПРОКРУЧИВАЕМОГО меню — блюр здесь был самым
   дорогим на странице (пересчёт на каждый кадр). Плотный --bg: та же роль
   «лента отделяет себя от контента», ноль композитинга, ноль полупрозрачных
   артефактов при инерционном скролле iOS. */
.catbar { position:sticky; top:0; z-index:5; display:flex; gap:8px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding:calc(8px + var(--safe-top)) 16px 8px; margin:0 -16px 4px; background:var(--bg); scrollbar-width:none; -ms-overflow-style:none; }
.catbar::-webkit-scrollbar { display:none; }
/* Чип категории 1-в-1 с _CategoryTab: высота 36, 14/600, неактивный —
   surfaceAlt без рамки. */
.catbar__chip { flex:none; display:inline-flex; align-items:center; height:36px; padding:0 14px; border-radius:var(--r-pill); border:none; background:var(--surface-alt); color:var(--text); font:inherit; font-weight:600; font-size:14px; white-space:nowrap; cursor:pointer; transition:background-color .18s cubic-bezier(.33,0,.2,1), color .18s cubic-bezier(.33,0,.2,1), box-shadow .18s ease, transform .12s ease; }
.catbar__chip:active { transform:scale(.94); }
/* Активная категория — СПЛОШНАЯ заливка акцентом + мягкий ореол под ней
   (мобилка: accent с альфой .32, смещение 0/3, размытие 10). Бледная плашка
   «soft» терялась в ряду и не давала понять, где ты находишься. */
.catbar__chip.on { background:var(--accent); color:var(--on-accent); border-color:transparent; box-shadow:0 3px 10px var(--accent-halo); }
/* Магазины (business_type != restaurant): актив катбара — зелёно-бирюзовый,
   как _CategoryTab в мобилке. */
.catbar.grocery .catbar__chip.on { background:var(--teal); color:#fff; box-shadow:0 3px 10px rgba(44,182,166,.32); }
/* Ховер красит только НЕактивные: у активного текст уже на заливке акцента,
   и перекраска в тот же акцент делала подпись невидимой. */
@media (hover:hover) { .catbar.grocery .catbar__chip:not(.on):hover { background:var(--teal-soft); color:var(--teal); } }

/* -- инфостроки «О заведении» (Icons.place/payments/schedule в brand) -- */
.irow { display:flex; align-items:center; gap:10px; padding:6px 0; font-size:14px; line-height:1.4; }
.irow__ic { width:20px; height:20px; color:var(--accent); flex:none; }
.irow__ic svg { width:20px; height:20px; }
.irow__chev { width:18px; height:18px; color:var(--muted); flex:none; }
.irow__chev svg { width:18px; height:18px; }

/* -- карточки блюд: ховер-тень (десктоп), «Закончилось», «можно настроить» -- */
@media (hover:hover) { .dcard:hover .dcard__ph { box-shadow:var(--shadow-hover); } }
.dcard__ph { transition:box-shadow .15s ease; }
.dcard--off { opacity:.45; cursor:default; }
.dcard--off:active { transform:none; }
.dcard__price--off { background:rgba(28,27,25,.7); color:#fff; }
.dcard__custom { display:inline-block; font-size:11px; font-weight:700; color:var(--accent); background:var(--soft); padding:2px 8px; border-radius:var(--r-pill); margin-top:4px; }

/* -- шторка блюда: фото 16/10 radius 16 + sticky-CTA с градиентом-скримом
   (низ шторки не уезжает у блюд с длинным списком опций) -- */
.isheet__img { width:100%; aspect-ratio:16/10; object-fit:cover; border-radius:var(--r-card); background:var(--soft); margin-bottom:12px; display:block; }
.isheet__cta { position:sticky; bottom:0; display:flex; align-items:center; gap:10px; margin:8px -18px calc(-1 * (var(--safe-bottom) + 18px)); padding:16px 18px calc(var(--safe-bottom) + 16px); background:linear-gradient(to bottom, transparent, var(--card) 40%); }

/* -- анимация шторок: въезд снизу + фейд подложки; закрытие через .closing
   (десктоп, где шторка по центру, — scale+fade) -- */
.sheet-back { animation:sheet-fade .2s ease; }
.sheet-back .sheet { animation:sheet-up .28s cubic-bezier(.2,.8,.3,1); }
@keyframes sheet-fade { from { opacity:0; } }
@keyframes sheet-up { from { transform:translateY(100%); } }
.sheet-back.closing { animation:none; opacity:0; pointer-events:none; transition:opacity .22s ease; }
.sheet-back.closing .sheet { animation:none; transform:translateY(100%); transition:transform .24s cubic-bezier(.4,0,1,1); }
@media (min-width:600px) {
  .sheet-back .sheet { animation:sheet-pop .22s ease; }
  .sheet-back.closing .sheet { transform:scale(.96); opacity:0; transition:transform .18s ease, opacity .18s ease; }
}
@keyframes sheet-pop { from { transform:scale(.96); opacity:0; } }

/* -- плавающая пилюля корзины на странице заведения (_FloatingCartButton):
   слайд снизу, кружок-счётчик, полоска прогресса до минимума -- */
.cart-pill { position:fixed; left:50%; bottom:calc(var(--safe-bottom) + 84px); transform:translate(-50%,140%); width:min(536px, calc(100% - 32px)); height:56px; border-radius:28px; background:var(--accent); color:var(--on-accent); display:flex; align-items:center; gap:10px; padding:0 18px 0 12px; box-shadow:var(--shadow-float); cursor:pointer; z-index:29; overflow:hidden; opacity:0; pointer-events:none; transition:transform .25s cubic-bezier(.2,.8,.3,1), opacity .2s ease, bottom .2s ease; }
.cart-pill.on { transform:translate(-50%,0); opacity:1; pointer-events:auto; }
/* Плашка активного заказа видна — пилюля корзины поднимается выше неё. */
body.has-order-pill .cart-pill { bottom:calc(var(--safe-bottom) + 150px); }
.cart-pill__n { width:32px; height:32px; border-radius:50%; background:rgba(255,255,255,.25); display:flex; align-items:center; justify-content:center; font-weight:800; font-size:14px; flex:none; }
.cart-pill__t { flex:1; min-width:0; text-align:left; font-weight:700; font-size:15px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cart-pill__sum { font-weight:800; font-size:15px; flex:none; }
.cart-pill__bar { position:absolute; left:0; bottom:0; height:3px; background:rgba(255,255,255,.55); border-radius:2px; transition:width .3s ease; }

/* -- корзина: миниатюры 56×56, шапка-ссылка на заведение, прогресс до
   минимума (полоса 6px вместо красной плашки-«ошибки») -- */
.cart-item__img { width:56px; height:56px; border-radius:12px; object-fit:cover; background:var(--soft); flex:none; }
.cart-item__img--ph { display:flex; align-items:center; justify-content:center; color:var(--accent); }
.cart-item__img--ph svg { width:26px; height:26px; }
.cart-rest { display:flex; align-items:center; gap:10px; cursor:pointer; }
.minbar__track { height:6px; border-radius:3px; background:var(--surface-alt); overflow:hidden; }
.minbar__fill { height:100%; border-radius:3px; background:var(--accent); transition:width .3s ease; }

/* -- апселл «Добавьте ещё» в корзине -- */
.up-card { flex:none; width:110px; cursor:pointer; }
.up-card__ph { position:relative; width:110px; height:96px; border-radius:12px; overflow:hidden; background:var(--soft); }
.up-card__ph img { width:100%; height:100%; object-fit:cover; }
.up-card__add { position:absolute; right:6px; bottom:6px; width:28px; height:28px; border:none; border-radius:50%; background:var(--card); color:var(--text); box-shadow:var(--shadow-float); font-size:18px; line-height:1; cursor:pointer; }
.up-card__name { font-size:12.5px; font-weight:600; line-height:1.25; margin-top:6px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.up-card__price { font-size:13px; font-weight:800; margin-top:2px; }

/* -- чекаут: заголовки секций с иконками, карточки оплаты с рамкой и
   галочкой, зелёная карточка применённого промокода -- */
.sec-h { display:flex; align-items:center; gap:8px; font-size:15px; font-weight:800; margin-bottom:8px; }
.sec-h__ic { width:20px; height:20px; color:var(--accent); flex:none; }
.sec-h__ic svg { width:20px; height:20px; }
.pay-opt { display:flex; align-items:center; gap:10px; padding:12px; border:2px solid var(--line); border-radius:var(--r-card); margin-bottom:8px; cursor:pointer; transition:border-color .15s ease, transform .12s ease; }
.pay-opt:last-child { margin-bottom:0; }
.pay-opt:active { transform:scale(.98); }
.pay-opt.on { border-color:var(--accent); }
.pay-opt__ck { width:22px; height:22px; color:var(--success); flex:none; }
.pay-opt__ck svg { width:22px; height:22px; }
.promo-ok { display:flex; align-items:center; gap:8px; background:var(--success-soft); color:var(--success); border-radius:var(--r-input); padding:10px 12px; font-weight:600; font-size:14px; }
/* «Ваши промокоды» в чекауте: персональный код — тапабельная строка с
   пунктирной рамкой купона; галочка справа намекает «применить». */
.mypromo { display:flex; align-items:center; gap:10px; width:100%; border:1.5px dashed var(--accent-ring); background:transparent; border-radius:var(--r-input); padding:10px 12px; font:inherit; font-size:14px; color:var(--text); cursor:pointer; }
.mypromo + .mypromo { margin-top:8px; }
.mypromo:active { background:var(--accent-glow); }
.mypromo__code { font-weight:800; letter-spacing:.5px; color:var(--accent); white-space:nowrap; }
.mypromo__go { display:inline-flex; color:var(--accent); }
.mypromo__go svg { width:20px; height:20px; }
.promo-ok svg { width:20px; height:20px; flex:none; }
.promo-ok__x { border:none; background:none; color:var(--success); font-size:20px; line-height:1; cursor:pointer; padding:0 2px; flex:none; }

/* -- трекинг: таймлайн 5 сегментов с пульсом текущего (status_timeline.dart),
   ETA-баннер, карточка оценки с крупными звёздами -- */
.tl__title { font-size:20px; font-weight:800; line-height:1.2; }
.tl__sub { color:var(--muted); font-size:13.5px; margin-top:3px; }
.tl__row { display:flex; gap:6px; margin-top:12px; }
.tl__seg { flex:1; height:4px; border-radius:2px; background:var(--surface-alt); }
.tl__seg.done { background:var(--accent); }
.tl__seg.cur { background:var(--accent); animation:seg-pulse 1.2s ease-in-out infinite alternate; }
@keyframes seg-pulse { from { opacity:.45; } to { opacity:1; } }
.tl__labels { display:flex; gap:6px; margin-top:6px; }
.tl__labels span { flex:1; font-size:10px; font-weight:500; color:var(--muted); text-align:center; }
.tl__labels span.cur { color:var(--text); font-weight:700; }
@media (prefers-reduced-motion: reduce) { .tl__seg.cur { animation:none; } }
.eta-b { display:flex; align-items:center; gap:10px; background:var(--soft); border-radius:14px; padding:12px 14px; margin-bottom:12px; font-size:14px; }
.eta-b svg { width:22px; height:22px; color:var(--accent); flex:none; }
.eta-b b { font-weight:800; }
/* «Курьер у двери»: брендовый баннер над картой (order:courier_near, 8 с) */
.near-b { display:flex; align-items:center; gap:10px; background:var(--grad); color:#fff; border-radius:14px; padding:12px 14px; margin-bottom:12px; font-size:14px; box-shadow:0 6px 18px rgba(255,122,26,.35); animation:near-in .35s ease; }
.near-b svg { width:22px; height:22px; color:#fff; flex:none; }
.near-b b { font-weight:800; }
@keyframes near-in { from { opacity:0; transform:translateY(-8px); } to { opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce) { .near-b { animation:none; } }
.rate-row { display:flex; justify-content:center; gap:8px; margin-top:10px; }
.rate-star { cursor:pointer; transition:transform .1s ease; color:var(--star); }
.rate-star:active { transform:scale(1.15); }
.rate-star svg { width:42px; height:42px; }

/* -- главная кнопка: полный стадиум + градиент brand→brandDeep + мягкое
   свечение; disabled — КАТЕГОРИЧЕСКИ другой (серый), а не блёклая копия -- */
.btn { border-radius:var(--r-pill); }
.btn:not(.btn--sm) { height:52px; }
.btn:not(.btn--ghost):not(.btn--tonal):not(.btn--danger) { background:linear-gradient(135deg, var(--accent), var(--accent-press)); box-shadow:0 8px 20px rgba(232,95,0,.30); }
.btn:not(.btn--ghost):not(.btn--tonal):not(.btn--danger):active { filter:brightness(.94); }
/* .btn.btn — поднимаем специфичность выше градиентного правила. */
.btn.btn:disabled:not(.btn--busy) { background:var(--line); color:var(--muted); box-shadow:none; opacity:1; filter:none; }

/* -- степпер количества: единая пилюля surfaceAlt (QtyStepper из мобилки)
   вместо двух квадратиков с рамкой; знаки цвета текста, не accent -- */
.qty { background:var(--surface-alt); border-radius:var(--r-pill); gap:0; padding:0; }
.qty button { width:44px; height:40px; border:none; border-radius:var(--r-pill); background:transparent; color:var(--text); font-size:19px; font-weight:600; cursor:pointer; }
.qty button:active { background:var(--line); transform:scale(.94); }
.qty span { min-width:28px; text-align:center; font-weight:700; font-size:15px; }

/* === профиль и вход === Профиль плитками (profile.dart _tilesCard/_tileRow),
   аватар-инициал, заказы карточками (orders.dart _orderCard), вход: маска
   телефона, код из 5 ячеек (CodeInput), шаг Telegram, переключатель темы.
   Только токены — корректно в обеих темах. */

/* -- карточка-группа тайлов: иконка в кружке 40 + текст + шеврон;
   разделитель 1px с отступом слева 64 (divider indent из мобилки) -- */
.tiles { background:var(--card); border-radius:16px; box-shadow:var(--shadow-card); margin-bottom:12px; overflow:hidden; }
.tile { position:relative; display:flex; align-items:center; gap:12px; width:100%; padding:10px 12px; border:none; background:none; font:inherit; font-size:15px; font-weight:600; color:var(--text); text-align:left; text-decoration:none; cursor:pointer; transition:background-color .15s ease; }
.tile:active { background:var(--surface-alt); }
.tile + .tile::after { content:""; position:absolute; left:64px; right:16px; top:0; height:1px; background:var(--line); }
.tile__ic { width:40px; height:40px; border-radius:50%; background:var(--surface-alt); color:var(--muted); display:flex; align-items:center; justify-content:center; flex:none; }
.tile__ic svg { width:20px; height:20px; }
.tile__t { flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tile__chev { width:18px; height:18px; color:var(--text-tertiary); flex:none; }
.tile__chev svg { width:18px; height:18px; display:block; }
/* Опасная зона: красный текст, кружок danger-soft, без шеврона. */
.tile--danger { color:var(--danger); }
.tile--danger .tile__ic { background:var(--danger-soft); color:var(--danger); }

/* -- шапка профиля: аватар-инициал 64 (кружок brandSoft, буква brand) -- */
.phead { display:flex; align-items:center; gap:14px; margin-bottom:18px; }
.pavatar { width:64px; height:64px; border-radius:50%; background:var(--soft); color:var(--accent); display:flex; align-items:center; justify-content:center; font-size:26px; font-weight:800; flex:none; }
/* Гостевой профиль: круг 96 с фирменным логотипом + приветствие (_guest). */
.pguest { display:flex; flex-direction:column; align-items:center; text-align:center; padding:10px 0 22px; }
.pguest__logo { width:96px; height:96px; border-radius:50%; background:var(--soft); display:flex; align-items:center; justify-content:center; }

/* -- строки адресов в шторке «Мои адреса» + круглые икон-кнопки -- */
.arow { display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid var(--line); cursor:pointer; }
.arow:last-child { border-bottom:none; }
.icobtn { width:36px; height:36px; border:none; border-radius:50%; background:var(--surface-alt); color:var(--muted); display:flex; align-items:center; justify-content:center; cursor:pointer; flex:none; transition:transform .12s ease, background-color .15s ease; }
.icobtn:active { transform:scale(.92); background:var(--line); }
.icobtn svg { width:17px; height:17px; }
.icobtn--danger { color:var(--danger); }

/* -- переключатель темы (settings.dart «Внешний вид»): 3 плитки -- */
.tseg { display:flex; gap:8px; }
.tseg button { flex:1; display:flex; flex-direction:column; align-items:center; gap:6px; padding:12px 4px 10px; border:1.5px solid transparent; border-radius:var(--r-input); background:var(--surface-alt); color:var(--muted); font:inherit; font-size:13px; font-weight:600; cursor:pointer; transition:background-color .15s ease, color .15s ease, border-color .15s ease; }
.tseg button svg { width:20px; height:20px; }
.tseg button.on { background:var(--soft); color:var(--accent); border-color:var(--accent); font-weight:700; }

/* -- заказы: «светофор» статусов + карточка с датой, раскрывашкой состава
   и пилюлями-действиями (orders.dart _statusStyle/_orderCard) -- */
.ostatus { display:inline-flex; align-items:center; gap:4px; flex:none; }
.ostatus svg { width:14px; height:14px; flex:none; }
.ostatus--done { background:var(--success-soft); color:var(--success); }
.ostatus--cancel { background:var(--danger-soft); color:var(--danger); }
/* Светофор статусов (19.08): ждёт / готов / в пути. */
.ostatus--wait { background:var(--surface-alt); color:var(--muted-t, var(--text-2, #8a7b6d)); }
.ostatus--ready { background:rgba(46,141,255,.12); color:#2e8dff; }
.ostatus--road { background:rgba(245,166,35,.16); color:#c97f0a; }
.ocard__meta { color:var(--muted); font-size:13px; margin-top:4px; }
.ocard__toggle { display:inline-flex; align-items:center; gap:3px; color:var(--accent); font-size:13px; font-weight:700; margin-top:8px; cursor:pointer; }
.ocard__toggle svg { width:16px; height:16px; transform:rotate(90deg); transition:transform .2s ease; }
.ocard__toggle.open svg { transform:rotate(-90deg); }
.ocard__comp { margin-top:6px; border-top:1px solid var(--line); padding-top:4px; }
.ocard__foot { display:flex; align-items:center; gap:8px; margin-top:10px; }
.ocard__price { flex:1; min-width:0; font-size:19px; font-weight:800; }
.obtn { display:inline-flex; align-items:center; gap:6px; height:40px; padding:0 14px; border:none; border-radius:var(--r-pill); font:inherit; font-size:13px; font-weight:700; cursor:pointer; flex:none; transition:transform .12s ease; }
.obtn:active { transform:scale(.95); }
.obtn svg { width:18px; height:18px; flex:none; }
.obtn--rate { background:var(--soft); color:var(--accent); }
.obtn--rate svg { color:var(--star); }
.obtn--rep { background:var(--accent-press); color:var(--on-accent); }

/* -- вход: крупный заголовок шага, появление шага, код из 5 ячеек, таймер -- */
.step-h { font-size:22px; font-weight:800; text-align:center; letter-spacing:-.3px; margin:2px 0 6px; }
.astep { animation:fadeInUp .25s ease both; }
.code { position:relative; display:flex; justify-content:center; gap:10px; margin:8px 0 2px; }
/* Скрытое настоящее поле — во весь блок ячеек: тап = нативный фокус, работают
   backspace/вставка/автоподстановка one-time-code; текст и каретка прозрачны. */
.code__hid { position:absolute; inset:0; width:100%; height:100%; opacity:0; border:none; background:none; color:transparent; caret-color:transparent; font-size:16px; z-index:2; padding:0; outline:none; }
.code__hid::selection { background:transparent; }
.code__c { width:48px; height:58px; border-radius:14px; background:var(--input-bg); border:1.5px solid transparent; display:flex; align-items:center; justify-content:center; font-size:24px; font-weight:700; color:var(--text); transition:border-color .15s ease, opacity .15s ease; }
.code__c.on { border-color:var(--accent); }
.code--busy .code__c { opacity:.55; }
.code-resend { text-align:center; font-size:14px; font-weight:600; margin-top:14px; }
.code-resend a { color:var(--accent); text-decoration:none; }

/* SVG-иконки внутри обычных кнопок (чат-отправка, «Повторить заказ»…). */
.btn svg { width:20px; height:20px; flex:none; }

/* === десктоп === Витрина ≥900px: широкий контейнер, верхняя навигация
   (рестайл ТОГО ЖЕ DOM, что и нижние табы), сетки карточек, 2 колонки
   корзины/чекаута, ховеры. Всё живёт в @media — мобильная и планшетная
   вёрстка не меняются ни на пиксель. Только токены — корректно в 2 темах. */

/* Обёртка 2 колонок корзины/чекаута: на телефоне прозрачна для потока
   (порядок блоков прежний), сетка включается только в @media ниже. */
.co-cols { display: contents; }

/* Обёртка главной кнопки «Оформить»/«Заказать». На десктопе прозрачна для
   потока (кнопка живёт в липкой правой колонке .co-side как раньше). На
   телефоне (< 900px, ниже) становится фикс-панелью, прижатой к низу. */
.co-cta { display: contents; }

/* -- мобильный чекаут/корзина: главная кнопка оформления/заказа ПРИЖАТА к
   низу экрана над нижним меню — паритет с приложением, где CTA всегда на
   виду (раньше .co-side был sticky только на ≥900px, и на телефоне кнопка
   уходила в конец потока). Фикс-панель с safe-area и мягким скримом сверху,
   z-index ниже .nav (30) — панель встаёт над меню, не перекрывая его.
   Десктоп (≥900px) не трогаем — там CTA липкий в правой колонке. -- */
@media (max-width: 899.98px) {
  .co-cta {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 28;
    display: flex; justify-content: center;
    padding: 20px 16px calc(var(--safe-bottom) + 84px);
    background: linear-gradient(to bottom, transparent, var(--bg) 20px);
    pointer-events: none;
  }
  .co-cta > .btn { width: 100%; max-width: 648px; margin: 0; box-shadow: var(--shadow-float); pointer-events: auto; }
  /* Резерв под фикс-панель, чтобы кнопка не перекрывала последние поля/кнопку
     «Очистить» (92px базового резерва под .nav здесь мало). */
  .scr--pad.scr--co { padding-bottom: calc(var(--safe-bottom) + 164px); }

  /* -- активный заказ: в .nav появляется плашка #orderPill (см. navBar в
     app.js), из-за неё меню становится выше (~137px). Базовый bottom-отступ
     кнопки (84px) рассчитан только на .nav__in — с плашкой кнопка ныряла ПОД
     неё и клиент её не видел. Приподнимаем CTA над плашкой + докидываем резерв
     низа контенту. Специфичность (body.has-order-pill …) перебивает правила
     выше. -- */
  body.has-order-pill .co-cta { padding-bottom: calc(var(--safe-bottom) + 146px); }
  body.has-order-pill .scr--pad.scr--co { padding-bottom: calc(var(--safe-bottom) + 226px); }
}

/* Кадр просмотра историй: на телефоне — во весь экран, как раньше
   (инлайн-стили оверлея переехали в классы ради десктопного варианта ниже). */
.story-ov { position:fixed; inset:0; z-index:90; background:#000; overflow:hidden; touch-action:none; user-select:none; -webkit-user-select:none; display:flex; }
.story-frame { position:relative; width:100%; height:100%; overflow:hidden; }

/* Карта трекинга (инлайн-стиль переехал в класс — десктопу нужна выше). */
.trackmap { height:240px; border-radius:16px; overflow:hidden; margin-bottom:12px; background:var(--card); }

/* Центрированный диалог (≥600px): грип-полоска — жест-аффорданс тача,
   в диалоге без drag-жеста она только путает. */
@media (min-width:600px) { .sheet__grip { display:none; } }

/* -- ховеры: базовая грамматика десктопа (hover:hover не срабатывает на
   таче — мобилка не меняется); transition уже объявлен на этих классах -- */
@media (hover:hover) {
  .rcard:hover:not(:active) { transform:translateY(-4px); box-shadow:var(--shadow-hover); }
  /* :not(.on) — у активного чипа текст лежит на заливке акцента, красить его
     в акцент значило бы стереть подпись. */
  .chip:not(.chip--soft):hover { border-color:var(--accent); color:var(--accent); }
  .catbar__chip:not(.on):hover { background:var(--soft); color:var(--accent); }
  .tile:hover, .opt:hover, .arow:hover { background:var(--surface-alt); }
  .btn--ghost:hover:not(:disabled), .btn--tonal:hover:not(:disabled) { filter:brightness(.97); }
  .btn:not(.btn--ghost):not(.btn--tonal):hover:not(:disabled):not(.btn--busy) { filter:brightness(1.05); }
  .up-card:hover .up-card__ph { box-shadow:var(--shadow-hover); }
  .nav__b:hover { color:var(--text); }
  .qty button:hover, .icobtn:hover { background:var(--line); }
}

/* -- горизонтальные ленты: мышке возвращаем тонкий скроллбар по ховеру
   (на таче он по-прежнему скрыт); drag-скролл вешает bindHDrag в app.js -- */
@media (hover:hover) and (min-width:900px) {
  .hscroll:hover { scrollbar-width:thin; scrollbar-color:var(--line) transparent; }
  .hscroll:hover::-webkit-scrollbar { display:block; height:6px; }
  .hscroll:hover::-webkit-scrollbar-thumb { background:var(--line); border-radius:3px; }
  .hscroll:hover::-webkit-scrollbar-track { background:transparent; }
}

@media (min-width:900px) {
  /* -- широкий контейнер витринных экранов (главная, заведение); формы
     (вход/заказы/профиль) остаются на 680px — им ширина вредит.
     !important перебивает инлайновый padding-top:0 страницы заведения,
     чтобы контент не нырял под верхнюю навигацию. -- */
  .scr--wide { max-width:1140px; padding-top:72px !important; }
  .scr, .scr--pad { padding-top:72px; padding-bottom:24px; }
  /* Плашка заказа на десктопе живёт в углу — резерв низа не нужен. */
  body.has-order-pill .scr, body.has-order-pill .scr--pad { padding-bottom:24px; }

  /* -- нижние табы → верхний навбар: рестайл того же DOM (navBar в app.js),
     логика bindNav/renderTabBadge работает без единой правки -- */
  .nav { top:0; bottom:auto; padding:10px 24px; }
  .nav__in { max-width:1140px; border-radius:16px; justify-content:flex-end; }
  /* Логотип слева — псевдоэлементом, DOM не трогаем. */
  .nav__in::before { content:'ADelivery'; font-weight:800; font-size:17px; letter-spacing:-0.3px; color:var(--accent); margin-right:auto; align-self:center; padding-left:16px; }
  .nav__b { flex:none; flex-direction:row; gap:8px; padding:8px 16px; font-size:14px; }
  /* Иконка снова 20×20 без «таблетки»: на верхнем навбаре подпись стоит РЯДОМ
     с иконкой, и пилюля 56×32 под одной иконкой выглядела бы огрызком.
     Активность на десктопе показывает подсветка всей кнопки. */
  .nav__ic { width:20px; height:20px; border-radius:10px; }
  .nav__b.on .nav__ic { background:none; }
  .nav__b.on { background:var(--soft); border-radius:12px; }
  .nav__ic svg { width:20px; height:20px; }
  .nav__badge { position:static; margin-left:2px; }
  /* Плашка активного заказа — в правый нижний угол (инлайновые центр и
     ширину перебиваем !important). */
  #orderPill { position:fixed; left:auto; right:24px; bottom:24px; width:360px; max-width:360px !important; margin:0 !important; z-index:31; }

  /* -- главная: компактная шапка в 2 колонки (приветствие и чипы слева,
     адрес и поиск справа) — витрина поднимается выше сгиба -- */
  .scr--wide .home-head { display:grid; grid-template-columns:minmax(0,1fr) 420px; column-gap:24px; align-items:center; }
  .scr--wide .home-head > .h1 { grid-column:1; grid-row:1; }
  .scr--wide .home-head > .home-head__sub { grid-column:1; grid-row:2; }
  .scr--wide .home-head > .bar__row { grid-column:1; grid-row:3; }
  .scr--wide .home-head > .addr-line { grid-column:2; grid-row:1 / span 2; margin-top:0; }
  .scr--wide .home-head > .field { grid-column:2; grid-row:3; align-self:center; }

  /* -- сетка заведений 2–3 колонки (тот же DOM #rlist; minmax схлопывает
     обратно в 1–2 колонки на узких окнах) -- */
  #rlist { display:grid; grid-template-columns:repeat(auto-fill, minmax(300px, 1fr)); gap:16px; align-items:start; }
  #rlist .rcard { margin-bottom:0; }
  #rlist .empty { grid-column:1 / -1; }
  #rlist .skel-wrap { display:contents; }

  /* -- страница заведения: hero не на всю ширину, меню 4–5 плиток в ряд,
     sticky-категории встают под верхний навбар -- */
  .rhead { margin:12px 0; border-radius:22px; }
  .rhead .rhead__img { aspect-ratio:21/9; max-height:320px; }
  .catbar { top:56px; }
  /* Перебиваем инлайновый scroll-margin-top:56px заголовков секций. */
  .h2[id^="cat"] { scroll-margin-top:128px !important; }
  .dish-grid { grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); gap:16px; }
  /* Компакт-лента на широком экране: карточки чуть крупнее, шире зазор. */
  .dish-row { gap:12px; }
  .dcard--sm { flex-basis:118px; width:118px; }

  /* -- корзина/чекаут: состав и формы слева, липкий итог с CTA справа
     (CTA всегда на экране — конверсия не теряется на длинной форме) -- */
  /* margin-inline:auto дублируем от .scr явно — двухколоночный экран обязан
     стоять по центру независимо от набора классов на корневом контейнере. */
  .scr--pad.scr--co { max-width:1000px; margin-inline:auto; }
  .co-cols { display:grid; grid-template-columns:minmax(0,1fr) 360px; gap:0 20px; align-items:start; }
  .co-side { position:sticky; top:72px; }

  /* -- плавающая пилюля корзины: в правый нижний угол (по центру широкого
     экрана она закрывала ряд блюд, на который смотрит пользователь) -- */
  .cart-pill { left:auto; right:32px; bottom:32px; transform:translateY(140%); width:360px; }
  .cart-pill.on { transform:translateY(0); }
  body.has-order-pill .cart-pill { bottom:100px; }

  /* -- трекинг: высокая карта (главный экран ожидания заказа) -- */
  .trackmap { height:420px; }

  /* -- истории: телефонная колонка 9/16 на затемнении (как Instagram/VK
     на десктопе), а не портретный кадр во весь ландшафтный экран -- */
  .story-ov { background:rgba(10,8,6,.88); }
  .story-frame { margin:auto; width:auto; height:min(90vh, 800px); aspect-ratio:9/16; border-radius:20px; }
}

/* === бенчмарк-полировка === «Откроется в …», бейдж «Промо», счётчик блюда,
   кнопка «Позвонить курьеру», обещание ETA, pull-to-refresh. Только токены —
   корректно в обеих темах. */

/* -- бейдж «Промо» на продвигаемых заведениях: фирменный градиент слева-сверху
   (честность выдачи, как стикер спонсорских позиций у топов) -- */
.rcard__pill--promo { left:10px; top:10px; background:var(--grad); color:#fff; font-size:11px; font-weight:700; padding:4px 9px; letter-spacing:.2px; }
/* Редкий случай «Промо» + «Доставка заведения» вместе: сдвигаем второй бейдж. */
.rcard__pill--promo ~ .rcard__self { left:78px; }

/* -- кружок-счётчик «в корзине N» на фото блюда (Wolt/Додо/Я.Еда);
   pop-анимация переиспользует fav-pop -- */
.dcard__qty { position:absolute; right:8px; top:8px; min-width:24px; height:24px; padding:0 7px; border-radius:12px; background:var(--accent); color:var(--on-accent); font-size:13px; font-weight:800; display:flex; align-items:center; justify-content:center; box-shadow:var(--shadow-float); pointer-events:none; }
.dcard__qty.pop { animation:fav-pop .3s ease; }

/* -- круглые кнопки «Позвонить»/«Чат» в карточке курьера (трекинг) -- */
.cbtn { width:44px; height:44px; border:none; border-radius:50%; background:var(--soft); color:var(--accent); display:inline-flex; align-items:center; justify-content:center; cursor:pointer; flex:none; text-decoration:none; transition:transform .12s ease, filter .15s ease; }
.cbtn:active { transform:scale(.92); filter:brightness(.95); }
.cbtn svg { width:20px; height:20px; }

/* -- обещание времени в чекауте: строка с часами у секции «Когда доставить» -- */
.co-eta { display:flex; align-items:center; gap:8px; margin-top:10px; font-size:13.5px; color:var(--muted); }
.co-eta svg { width:18px; height:18px; color:var(--accent); flex:none; }
.co-eta b { color:var(--text); font-weight:700; }

/* -- pull-to-refresh: плавающий кружок со всадником (дизайн-проект, идеи 7/22):
   при протяжке конь «набирает ход» — кадры 1→6 через --f (ставит JS), у
   порога (.ptr--ready) всадник брендовый, после отпускания (.ptr--go) —
   галоп (.gallop ниже) -- */
.ptr { position:fixed; left:50%; top:calc(var(--safe-top) + 10px); z-index:70; transform:translate(-50%,-56px); pointer-events:none; }
.ptr__c { width:44px; height:44px; border-radius:50%; background:var(--card); box-shadow:var(--shadow-float); display:flex; align-items:center; justify-content:center; color:var(--muted); transition:color .15s ease; }
.ptr--ready .ptr__c, .ptr--go .ptr__c { color:var(--accent); }
.ptr--go .gallop--frame { animation:gallop .54s steps(6, end) infinite; }

/* ---- Предложение заведения изменить заказ (контракт «order change»):
   заметная карточка на экране заказа — акцентная рамка, diff-список,
   старый→новый итог, таймер 5 минут и пара кнопок. ---- */
.chg-card { border:1.5px solid var(--accent); box-shadow:0 6px 18px rgba(232,95,0,.14); }
.chg-head { display:flex; align-items:center; gap:10px; font-size:16px; font-weight:800; line-height:1.25; }
.chg-head__ic { width:34px; height:34px; border-radius:50%; background:var(--soft); color:var(--accent); display:flex; align-items:center; justify-content:center; flex:none; }
.chg-head__ic svg { width:18px; height:18px; }
.chg-note { color:var(--muted); font-size:13.5px; font-style:italic; margin-top:8px; }
.chg-diff { margin-top:10px; padding-top:6px; border-top:1px solid var(--line); }
.chg-row { display:flex; justify-content:space-between; gap:10px; padding:4px 0; font-size:14px; font-weight:600; }
.chg-row--add { color:var(--success); }
.chg-row--del { color:var(--danger); }
.chg-total { display:flex; justify-content:space-between; align-items:center; margin-top:8px; padding-top:10px; border-top:1px solid var(--line); font-size:15px; }
.chg-total b { font-size:18px; font-weight:800; }
.chg-warn { background:var(--info-soft); color:var(--info); border-radius:var(--r-input); padding:8px 12px; font-size:13px; font-weight:600; margin-top:10px; }
.chg-timer { text-align:center; color:var(--muted); font-size:13px; font-weight:600; margin-top:10px; min-height:18px; }
.chg-timer--low { color:var(--danger); }
.chg-actions { display:flex; gap:10px; margin-top:10px; }
/* Бейдж «есть предложение» на плавающей плашке активного заказа. */
.pill-chg { color:var(--accent); font-size:12px; font-weight:700; margin-top:2px; }

/* === витрина-полировка === Кросс-фейд каталога при смене сегмента,
   капсула поиска с лупой и × очистки, поиск по меню заведения.
   Только токены (+фирменный teal) — обе темы. */

/* -- кросс-фейд каталога: fade + сдвиг 24px со стороны выбранного сегмента -- */
.seg-fade-r { animation:seg-fade-r .25s cubic-bezier(.2,.8,.3,1) both; }
.seg-fade-l { animation:seg-fade-l .25s cubic-bezier(.2,.8,.3,1) both; }
@keyframes seg-fade-r { from { opacity:0; transform:translateX(24px); } }
@keyframes seg-fade-l { from { opacity:0; transform:translateX(-24px); } }

/* -- счётчики: «· N» в катбаре и заголовках секций меню -- */
.catbar__n { opacity:.55; font-weight:600; margin-left:4px; }
.h2__n { color:var(--muted); font-weight:600; font-size:14px; margin-left:6px; }

/* Чипы сортировки — тоже в акценте сегмента (мобилка красит их через
   _segmentAccent): в «Продуктах» актив бирюзовый. Ключ — класс grocery
   на #segBox, его уже переключает обработчик сегмента. */
#segBox.grocery ~ .hscroll .chip--soft { background:var(--teal-soft); border-color:rgba(44,182,166,.55); color:var(--teal); }
@media (hover:hover) { #segBox.grocery ~ .hscroll .chip:not(.chip--soft):hover { border-color:var(--teal); color:var(--teal); } }

/* -- капсула поиска (главная и меню заведения): лупа слева внутри, круглая
   кнопка × очистки при непустом, мягкое свечение фокуса -- */
.search-box { position:relative; }
/* Поиск — главный элемент первого экрана, поэтому он КАРТОЧКА-пилюля (52,
   surface + рамка + мягкая тень), а не утопленное поле формы: так он читается
   как «строка приложения», а не как ввод логина. Лупа в бренде — точка входа
   видна с полувзгляда. */
.search-box .inp { height:52px; border-radius:var(--r-pill); background:var(--card); border:1px solid var(--line); box-shadow:var(--shadow-card); padding-left:46px; padding-right:44px; }
.search-box .inp:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--soft); }
.search-box__ic { position:absolute; left:15px; top:50%; transform:translateY(-50%); width:22px; height:22px; color:var(--accent); pointer-events:none; }
.search-box__ic svg { width:22px; height:22px; display:block; }
.search-box__x { position:absolute; right:8px; top:50%; transform:translateY(-50%); width:34px; height:34px; border:none; border-radius:50%; background:transparent; color:var(--muted); display:none; align-items:center; justify-content:center; cursor:pointer; padding:0; transition:background-color .15s ease, transform .12s ease; }
.search-box__x.on { display:flex; }
.search-box__x:active { background:var(--surface-alt); transform:translateY(-50%) scale(.9); }
.search-box__x svg { width:15px; height:15px; }
@media (hover:hover) { .search-box__x:hover { background:var(--surface-alt); color:var(--text); } }

/* === полировка-детали === Адрес-строка с подписью и SVG-пином, шевроны
   вместо текстовых стрелок, SVG-звёзды оценки с каскад-pop. Только токены. */

/* -- адрес-строка на главной: пин 20px в бренде + caption «Куда доставить?»
   12px над адресом (паттерн Wolt/Додо) + шеврон вниз (тап открывает шторку) -- */
.addr-line__ic { width:20px; height:20px; color:var(--accent); flex:none; }
.addr-line__ic svg { width:20px; height:20px; display:block; }
.addr-line__cap { font-size:12px; font-weight:500; color:var(--muted); line-height:1.2; }
.addr-line__t { font-weight:600; font-size:14.5px; margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.addr-line__chev, .pill-chev { width:18px; height:18px; color:var(--muted); flex:none; }
.addr-line__chev svg, .pill-chev svg { width:18px; height:18px; display:block; }
.addr-line__chev svg { transform:rotate(90deg); }

/* -- звёзды оценки (шторка «Оцените заказ»): SVG IC.star в токенах вместо
   текстовых ★; выбранные — --star, каскад-pop ставит popStars в app.js -- */
.rstar { display:inline-block; padding:2px 3px; cursor:pointer; color:var(--text-tertiary); transition:color .15s ease, transform .12s ease; }
.rstar svg { width:34px; height:34px; display:block; }
.rstar.on { color:var(--star); }
.rstar:active { transform:scale(.88); }
.rstar.pop svg { animation:fav-pop .3s ease both; }

/* === праздник «заказ принят» === Порт _OrderCelebration (checkout.dart):
   тёпло-тёмный скрим (одинаков в обеих темах, как в мобилке), брендовый круг
   с мягким ореолом вырастает пружиной, галочка РИСУЕТСЯ росчерком
   (stroke-dashoffset), два расходящихся кольца, залп конфетти
   (бренд/золото/бирюза/белый). Оверлей перекрывает тапы — защита от двойных
   действий, пока заказ уводится на трекинг (~1.8с, тайминг в app.js). */
/* Въезд без fill-режима: заполняющая анимация перебивала бы transition
   фейд-аута .cel.out (animations выигрывают у transitions по каскаду). */
.cel { position:fixed; inset:0; z-index:95; display:flex; flex-direction:column; align-items:center; justify-content:center; background:rgba(20,19,17,.84); animation:cel-in .25s ease; }
.cel.out { opacity:0; transition:opacity .25s ease; }
@keyframes cel-in { from { opacity:0; } }
.cel__stage { position:relative; width:116px; height:116px; }
.cel__circle { position:absolute; inset:0; border-radius:50%; background:var(--accent); display:flex; align-items:center; justify-content:center; box-shadow:0 0 0 16px rgba(255,122,26,.16), 0 0 80px 34px rgba(255,122,26,.32); animation:cel-pop .45s cubic-bezier(.34,1.56,.64,1) .08s backwards; }
.cel__circle svg { width:60px; height:60px; }
@keyframes cel-pop { from { transform:scale(0); } }
/* Росчерк: длина пути галочки ~31 (dasharray с запасом 34), после круга. */
.cel__check { stroke-dasharray:34; stroke-dashoffset:34; animation:cel-draw .35s cubic-bezier(.33,1,.68,1) .46s forwards; }
@keyframes cel-draw { to { stroke-dashoffset:0; } }
.cel__ring { position:absolute; inset:0; border-radius:50%; border:3px solid rgba(255,196,107,.85); opacity:0; animation:cel-ring .7s cubic-bezier(.33,1,.68,1) .5s; }
.cel__ring--2 { border-color:rgba(255,255,255,.6); animation-delay:.68s; }
@keyframes cel-ring { 0% { transform:scale(1); opacity:.9; } 100% { transform:scale(2.5); opacity:0; } }
/* Конфетти-квадратик: вылет из-за круга на (--dx,--dy), «гравитация» +46px
   к концу пути, вращение на --rot; задержки и палитру раздаёт app.js. */
.cel__conf { position:absolute; left:50%; top:50%; width:9px; height:12px; margin:-6px 0 0 -4px; border-radius:2.5px; opacity:0; animation:cel-conf .95s cubic-bezier(.22,.9,.36,1) both; }
@keyframes cel-conf {
  0% { opacity:0; transform:translate(0,0) rotate(0deg) scale(.4); }
  12% { opacity:1; }
  72% { opacity:1; }
  100% { opacity:0; transform:translate(var(--dx), calc(var(--dy) + 46px)) rotate(var(--rot)) scale(1); }
}
.cel__t { margin-top:26px; text-align:center; padding:0 24px; animation:cel-label .3s ease .55s backwards; }
@keyframes cel-label { from { opacity:0; transform:translateY(12px); } }
.cel__title { color:#fff; font-size:24px; font-weight:800; letter-spacing:.2px; line-height:1.15; }
.cel__sub { color:rgba(255,255,255,.7); font-size:15px; font-weight:500; margin-top:6px; line-height:1.3; }

/* ===== Чат: «парящая» строка ввода как в Telegram (владелец 31.07) =====
   Контейнер — прозрачная полоса ПОВЕРХ ленты #msgs, прижат к низу и
   поднимается вместе с клавиатурой iOS (--kb ставит app.js по visualViewport,
   как у шторок). Сам контейнер клики пропускает (pointer-events:none) —
   ловят их три парящих элемента: круглая скрепка и pill-поле на «мокром
   стекле», кнопка отправки — брендовая заливка со стрелкой вверх. */
.chatbar { position:fixed; left:0; right:0; bottom:var(--kb, 0px); z-index:30; display:flex; align-items:center; gap:8px; max-width:680px; margin-inline:auto; padding:8px max(16px, var(--safe-right, 0px)) calc(var(--safe-bottom) + 10px) max(16px, var(--safe-left, 0px)); pointer-events:none; }
/* Клавиатура открыта — home-indicator закрыт ею, нижний инсет не нужен. */
body.kb-open .chatbar { padding-bottom:8px; }
.chatbar__btn, .chatbar__field { pointer-events:auto; background:rgba(255,255,255,.6); border:1px solid rgba(255,255,255,.55); -webkit-backdrop-filter:blur(16px) saturate(1.4); backdrop-filter:blur(16px) saturate(1.4); box-shadow:0 6px 20px rgba(28,27,25,.14); }
[data-theme="dark"] .chatbar__btn, [data-theme="dark"] .chatbar__field { background:rgba(35,30,26,.55); border-color:rgba(255,255,255,.08); box-shadow:0 6px 20px rgba(0,0,0,.4); }
.chatbar__btn { flex:none; width:48px; height:48px; padding:0; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--text); cursor:pointer; }
.chatbar__btn svg { width:22px; height:22px; }
.chatbar__field { flex:1; min-width:0; height:48px; border-radius:24px; padding:0 18px; font-size:16px; font-family:var(--font); color:var(--text); outline:none; }
.chatbar__field::placeholder { color:var(--text-tertiary); }
.chatbar__field:focus { border-color:var(--accent-ring); }
/* Отправка — брендовый круг (в обеих темах), стрелка цветом текста-на-бренде. */
.chatbar__send, [data-theme="dark"] .chatbar__send { background:var(--accent); border-color:transparent; color:var(--on-accent); box-shadow:var(--shadow); }
/* Спиннер busy (скрепка при загрузке фото): у стекла — брендовый,
   у брендовой отправки — контрастный (базовый .btn--busy красит текст). */
.chatbar__btn.btn--busy::after { border-color:var(--accent); border-top-color:transparent; }
.chatbar__send.btn--busy::after { border-color:var(--on-accent); border-top-color:transparent; }
.chatbar__btn.btn--busy::before { background:var(--accent); }
.chatbar__send.btn--busy::before { background:var(--on-accent); }

/* Чекаут: заметный баннер «Заведение сейчас закрыто — оформляем предзаказ»
   (владелец 31.07). Тёплая плашка --warn-soft, как «Закрыто» на витрине. */
.co-closed { background:var(--warn-soft); border:1px solid var(--accent-ring); border-radius:var(--r-card); padding:12px 14px; margin-bottom:12px; font-size:14px; font-weight:600; line-height:1.45; color:var(--text); }

/* ===== Баннер главной v2 ===== Кастомный промо-блок из админки: фон —
   фото со скримом либо градиент с мягкими декоративными кругами; текст и
   кнопка-пилюля красятся text_color инлайном (color на .banner2 + inherit).
   Пластика карточек приложения: радиус --r-card-lg, тень --shadow-card —
   токены сами дают обе темы. */
.banner2 { position:relative; overflow:hidden; border-radius:var(--r-card-lg); box-shadow:var(--shadow-card); margin:12px 0; min-height:120px; display:flex; }
.banner2--tap { cursor:pointer; }
/* Скрим фото-стиля: плотнее слева, где текст, — прозрачнее справа, чтобы
   снимок оставался виден (паттерн hero-баннеров Wolt/Я.Еды). */
.banner2__scrim { position:absolute; inset:0; background:linear-gradient(90deg, rgba(0,0,0,.55), rgba(0,0,0,.12)); pointer-events:none; }
/* Декор градиент-стиля: три полупрозрачных круга разного размера по углам —
   глубина без картинки (radial-gradient, никаких доп. запросов). */
.banner2__deco { position:absolute; inset:0; pointer-events:none; background:
  radial-gradient(circle 120px at 88% -18%, rgba(255,255,255,.14), rgba(255,255,255,0) 70%),
  radial-gradient(circle 90px at 72% 118%, rgba(255,255,255,.14), rgba(255,255,255,0) 70%),
  radial-gradient(circle 64px at 22% 128%, rgba(255,255,255,.10), rgba(255,255,255,0) 70%); }
.banner2__body { position:relative; flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; align-items:flex-start; padding:16px 18px; }
.banner2__title { font-weight:800; font-size:20px; line-height:1.22; letter-spacing:-.2px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.banner2__sub { font-size:13.5px; font-weight:500; line-height:1.35; opacity:.92; margin-top:3px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
/* Кнопка-пилюля на «стекле»: полупрозрачная заливка + светлая рамка читаются
   и на фото, и на любом цвете градиента; цвет текста наследует text_color. */
.banner2__btn { border:1px solid rgba(255,255,255,.35); border-radius:var(--r-pill); background:rgba(255,255,255,.24); color:inherit; font:inherit; font-size:13.5px; font-weight:700; padding:8px 14px; margin-top:10px; cursor:pointer; transition:background-color .15s ease, transform .12s ease; }
.banner2__btn:active { transform:scale(.96); }
@media (hover:hover) { .banner2__btn:hover { background:rgba(255,255,255,.32); } }

/* ===== Маркет · личный закупщик (волна 09.2026) ===== Включается только у
   заведений с is_procurement (разметка mrow, mkt-…, ptag, класс .mkt у
   катбара): блок-вход на витрине, каталог-список покупок, стикер «Закупка»,
   конь-маскот, правило замены и уточнение в корзине, лента «поход в
   магазин» переиспользует .tl__*. Только токены — корректно в обеих темах. */

/* -- силуэт коня из брендбука: PNG как маска, цвет — currentColor (в
   мобилке Image.asset с colorBlendMode.srcIn). Файл img/market-horse.png —
   копия mobile/assets/market/horse_1.png. -- */
.mkt-horse { display:inline-block; width:18px; height:16px; background:currentColor; -webkit-mask:url(img/market-horse.png) center/contain no-repeat; mask:url(img/market-horse.png) center/contain no-repeat; vertical-align:-2px; flex:none; }
.mkt-horse--md { width:22px; height:19px; }
.mkt-horse--lg { width:56px; height:48px; color:var(--text); }
.mkt-horse--hero { position:absolute; left:50%; top:50%; width:120px; height:104px; transform:translate(-50%,-50%); color:rgba(255,255,255,.85); }
.rhead--noimg .rhead__img { position:relative; }

/* -- стикер «Закупка» (ProcurementTag мобилки): оранжевый ярлык r8, белый
   конь + подпись 11.5/800; --c — только конь для тесных строк -- */
.ptag { display:inline-flex; align-items:center; gap:5px; padding:4px 9px; border-radius:8px; background:var(--accent); color:#fff; font-size:11.5px; font-weight:800; letter-spacing:.2px; line-height:1; white-space:nowrap; flex:none; vertical-align:middle; }
.ptag .mkt-horse { width:16px; height:14px; vertical-align:0; }
.ptag--c { padding:4px 6px; }

/* -- блок-вход «Маркет · купим за вас» на витрине (идея 1): широкая карточка
   с конём на брендовом градиенте, обещания-чипы, шеврон. На десктопе
   растягивается на все колонки сетки #rlist. -- */
.mkt-entry { display:flex; align-items:center; gap:14px; background:var(--card); border-radius:var(--r-card-lg); box-shadow:var(--shadow-card); padding:12px 14px 12px 12px; margin-bottom:14px; cursor:pointer; transition:transform .12s ease, box-shadow .12s ease; }
.mkt-entry:active { transform:scale(.985); }
.mkt-entry__art { width:72px; height:72px; border-radius:18px; background:var(--grad); display:flex; align-items:center; justify-content:center; color:#fff; flex:none; box-shadow:0 6px 16px rgba(255,122,26,.28); }
.mkt-entry__art .mkt-horse { width:46px; height:40px; }
.mkt-entry__b { flex:1; min-width:0; }
.mkt-entry__title { font-size:18px; font-weight:800; line-height:1.2; letter-spacing:-.2px; }
.mkt-entry__dot { color:var(--accent); }
.mkt-entry__sub { color:var(--muted); font-size:13px; font-weight:500; line-height:1.35; margin-top:3px; }
.mkt-entry__chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.mkt-chip { display:inline-flex; align-items:center; gap:4px; background:var(--soft); color:var(--accent); font-size:12px; font-weight:700; padding:4px 9px; border-radius:var(--r-pill); white-space:nowrap; }
.mkt-chip--off { background:var(--surface-alt); color:var(--muted); }
.mkt-entry__chev { width:18px; height:18px; color:var(--muted); flex:none; }
.mkt-entry__chev svg { width:18px; height:18px; display:block; }
.mkt-entry--closed .mkt-entry__art { filter:grayscale(1); opacity:.7; box-shadow:none; }
.mkt-entry--closed .mkt-entry__b { opacity:.7; }
@media (hover:hover) { .mkt-entry:hover:not(:active) { transform:translateY(-3px); box-shadow:var(--shadow-hover); } }
@media (min-width:900px) { #rlist .mkt-entry { grid-column:1 / -1; margin-bottom:0; } }

/* -- лента отделов Маркета (идея 9): актив — бренд даже при business_type
   grocery (правило стоит ПОСЛЕ .catbar.grocery — при равной специфичности
   побеждает порядок) -- */
.catbar.mkt .catbar__chip.on { background:var(--accent); color:var(--on-accent); box-shadow:0 3px 10px var(--accent-halo); }
@media (hover:hover) { .catbar.mkt .catbar__chip:not(.on):hover { background:var(--soft); color:var(--accent); } }

/* -- каталог-список покупок (идея 2): карточка-список, строка = пиктограмма
   48 + текст + цена-кнопка + круглый «+». Ячейки children[j] ↔ c.items[j]
   — контракт поиска по меню и refreshDishQty. -- */
.mkt-list { background:var(--card); border-radius:var(--r-card); box-shadow:var(--shadow-card); padding:2px 12px; margin-bottom:8px; }
.mrow { display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid var(--line); cursor:pointer; }
.mrow:last-child { border-bottom:none; }
.mrow__ic { position:relative; width:48px; height:48px; border-radius:12px; background:var(--surface-alt); display:flex; align-items:center; justify-content:center; flex:none; transition:background-color .15s ease; }
.mrow--in .mrow__ic { background:var(--soft); }
.mrow__img { width:100%; height:100%; object-fit:cover; border-radius:12px; display:block; }
.mrow__emo { font-size:26px; line-height:1; }
.mrow__qty { position:absolute; right:-6px; top:-6px; min-width:20px; height:20px; padding:0 6px; border-radius:10px; background:var(--accent); color:var(--on-accent); font-size:11.5px; font-weight:800; display:flex; align-items:center; justify-content:center; box-shadow:var(--shadow-float); pointer-events:none; }
.mrow__qty.pop { animation:fav-pop .3s ease; }
.mrow__b { flex:1; min-width:0; }
.mrow__name { font-weight:700; font-size:15px; line-height:1.3; }
.mrow__badge { display:inline-block; vertical-align:1px; margin-left:6px; font-size:10.5px; font-weight:700; color:var(--accent); background:var(--soft); padding:2px 7px; border-radius:var(--r-pill); white-space:nowrap; }
.mrow__hint { color:var(--muted); font-size:12.5px; margin-top:2px; line-height:1.3; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.mrow__r { display:flex; align-items:center; gap:10px; flex:none; }
/* Цена — кнопка «почему такая цена?» (идея 26): пунктир под цифрой намекает на тап. */
.mrow__price { border:none; background:none; font:inherit; font-weight:800; font-size:15px; color:var(--text); cursor:pointer; padding:4px 0; white-space:nowrap; text-decoration:underline dotted var(--text-tertiary); text-underline-offset:3px; }
.mrow__price s { opacity:.55; font-weight:500; font-size:13px; }
.unit-sfx { color:var(--muted); font-weight:600; font-size:.82em; }
.mrow__add { width:36px; height:36px; padding:0; border:none; border-radius:50%; background:var(--soft); color:var(--accent); font-size:22px; line-height:1; font-weight:600; cursor:pointer; display:flex; align-items:center; justify-content:center; flex:none; transition:transform .12s ease, background-color .15s ease, color .15s ease; }
.mrow__add:active { transform:scale(.9); }
/* «Улетело в корзину» (идея 6): «+» пружинит и на миг заливается брендом. */
.mrow__add.pop { animation:mkt-pop .38s cubic-bezier(.34,1.56,.64,1); }
@keyframes mkt-pop { 0% { transform:scale(1); } 40% { transform:scale(1.32); background:var(--accent); color:var(--on-accent); } 100% { transform:scale(1); } }
.mrow--off { opacity:.5; cursor:default; }
.mrow__off { font-size:12.5px; font-weight:700; color:var(--muted); background:var(--surface-alt); padding:4px 9px; border-radius:var(--r-pill); white-space:nowrap; }
@media (hover:hover) {
  .mrow:not(.mrow--off):hover .mrow__name { color:var(--accent); }
  .mrow__add:hover { background:var(--accent); color:var(--on-accent); }
  .mrow__price:hover { color:var(--accent); }
}

/* -- своя строка (идея 13): «что · ≈ цена · кол-во · Добавить» -- */
.cline__row { display:flex; align-items:center; gap:8px; margin-top:8px; }
.cline__row .inp { width:auto; flex:1; min-width:0; }
.cline__row .qty { flex:none; }
.cline__row .btn--sm { flex:none; height:40px; }
.mkt-cline-cta { margin:6px 0 10px; }
.mkt-cline-cta__ic { font-size:18px; line-height:1; }

/* -- правило замены (идея 5): «Если нет: Заменить · Спросить · Убрать» -- */
.pol { display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:8px; }
.pol__lead { font-size:12.5px; color:var(--muted); font-weight:600; margin-right:2px; }
.pol__b { border:1.5px solid transparent; background:var(--surface-alt); color:var(--text); border-radius:var(--r-pill); padding:5px 11px; font:inherit; font-size:12.5px; font-weight:600; cursor:pointer; transition:background-color .15s ease, color .15s ease, transform .12s ease; }
.pol__b.on { background:var(--soft); color:var(--accent); font-weight:700; }
.pol__b:active { transform:scale(.95); }

/* -- уточнение курьеру (идея 20): компактное поле + чипы истории -- */
.inp--note { height:40px; font-size:14px; margin-top:8px; padding:0 12px; border-radius:12px; }
.mchips { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
.mchip { border:1px dashed var(--accent-ring); background:transparent; color:var(--accent); border-radius:var(--r-pill); padding:4px 10px; font:inherit; font-size:12px; font-weight:600; cursor:pointer; max-width:100%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mchip:active { background:var(--accent-glow); }
.cart-item__img--emo { display:flex; align-items:center; justify-content:center; font-size:26px; background:var(--surface-alt); }
.cart-item--mkt { align-items:flex-start; }

/* -- бренд + пожелание (02.09): два поля под правилом замены, чипы истории
   под своим полем; на широком экране — рядом -- */
.mkt-fields { display:grid; gap:0 10px; }
@media (min-width:640px) { .mkt-fields { grid-template-columns:1fr 1fr; align-items:start; } }
.cline__row--bn { flex-wrap:wrap; }
.cline__row--bn .inp { flex:1 1 160px; }

/* -- своя строка без цены (02.09): «цену назовёт курьер» — мягкая плашка
   вместо суммы (корзина, чекаут, экран заказа, «Докинуть») -- */
.pend { display:inline-block; font-size:11.5px; font-weight:700; line-height:1.3; color:var(--accent); background:var(--soft); padding:4px 9px; border-radius:var(--r-pill); white-space:nowrap; vertical-align:middle; }
/* в строке формы плашка ужимается с многоточием (SE 375: степпер и «Добавить»
   не должны вылезать за карточку) */
.cline__row .pend { margin-right:auto; flex:0 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; }

/* -- пиктограммы-эмодзи (02.09): тёплая плашка под эмодзи там, где нет фото
   (строка каталога, корзина); «в списке» — по-прежнему брендовая заливка
   (.mrow--in — две составные части, побеждает по специфичности) -- */
:root { --mkt-plate: #FBEFDF; }
[data-theme="dark"] { --mkt-plate: #3A2F23; }
.mrow__ic--emo, .cart-item__img--emo { background:var(--mkt-plate); }

/* -- «почему такая цена?» (идея 26): карточка ориентира полки -- */
.why-link { border:none; background:none; color:var(--accent); font:inherit; font-size:13px; font-weight:700; cursor:pointer; padding:0; text-decoration:underline dotted; text-underline-offset:3px; white-space:nowrap; }
.why-card { background:var(--surface-alt); border-radius:var(--r-card); padding:12px 14px; margin-top:8px; }
.why-row { display:flex; justify-content:space-between; gap:12px; padding:5px 0; font-size:14px; }
.why-row + .why-row { border-top:1px solid var(--line); }
.why-row b { white-space:nowrap; }
.why-note { color:var(--muted); font-size:12.5px; line-height:1.4; margin-top:8px; }
.msheet__head { display:flex; align-items:center; gap:12px; }
.msheet__emo { font-size:34px; line-height:1; flex:none; }
.msheet__emo:empty { display:none; }
.msheet__price { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px; font-size:18px; }

/* -- пустые состояния Маркета (идея 3): конь в фирменном ореоле -- */
.mkt-empty .empty__circle { color:var(--text); }

/* -- шторка «Докинуть в заказ» (идея 22): компактный степпер в строке -- */
.qty--sm button { width:32px; height:32px; font-size:17px; }
.qty--sm span { min-width:22px; font-size:14px; }
.mrow--ao { cursor:default; }

/* -- апселл без фото у Маркета: эмодзи отдела вместо пустого квадрата -- */
.up-card__emo { display:flex; align-items:center; justify-content:center; width:100%; height:100%; font-size:34px; }

/* ===== Дизайн-проект 09.2026: бегущий всадник, капля, копыта ===== Общий
   класс .gallop — спрайт-маска шести кадров галопа (img/brand/rider_sprite.svg:
   кадры в одном боксе 636×460, без «прыганья»); цвет — currentColor, размер —
   модификаторами. steps(6) за .54s — те же 11 к/с, что на сплэше;
   reduce-motion → первый кадр (см. медиа-блок ниже). Курьерский веб грузит
   этот же файл, поэтому пути к картинкам относительные от /app/. */
.gallop { display:inline-block; width:44px; height:32px; flex:none; background-color:currentColor;
  -webkit-mask:url(img/brand/rider_sprite.svg) 0 0 / 600% 100% no-repeat; mask:url(img/brand/rider_sprite.svg) 0 0 / 600% 100% no-repeat;
  animation:gallop .54s steps(6, end) infinite; }
@keyframes gallop { from { -webkit-mask-position:0 0; mask-position:0 0; } to { -webkit-mask-position:120% 0; mask-position:120% 0; } }
.gallop--sm { width:28px; height:20px; }
.gallop--lg { width:88px; height:64px; }
.gallop--xl { width:132px; height:96px; }
.gallop--still { animation:none; }
/* Кадр «вручную» через --f (0…5): pull-to-refresh разгоняет коня под пальцем. */
.gallop--frame { animation:none; -webkit-mask-position:calc(var(--f, 0) * 20%) 0; mask-position:calc(var(--f, 0) * 20%) 0; }

/* Следы копыт под пустым блоком — четыре затухающих отпечатка (hoof.svg). */
.hoofs { display:flex; justify-content:center; gap:14px; margin-top:16px; color:var(--muted); pointer-events:none; }
.hoofs i { width:13px; height:14px; background:currentColor; -webkit-mask:url(img/brand/hoof.svg) center/contain no-repeat; mask:url(img/brand/hoof.svg) center/contain no-repeat; }
.hoofs i:nth-child(1) { opacity:.55; transform:rotate(-10deg); }
.hoofs i:nth-child(2) { opacity:.4; transform:rotate(8deg) translateY(-3px); }
.hoofs i:nth-child(3) { opacity:.26; transform:rotate(-10deg); }
.hoofs i:nth-child(4) { opacity:.14; transform:rotate(8deg) translateY(-3px); }
/* Паттерн «копыто» слоем (баннер, лого-лок): два сдвинутых повтора маски дают
   шахматную сетку; прозрачность задаёт хозяин (не выше 10–12 % по брендбуку). */
.hoof-pat { position:absolute; inset:0; pointer-events:none; background:currentColor; opacity:.1;
  -webkit-mask:url(img/brand/hoof.svg) 0 0 / 52px 57px repeat, url(img/brand/hoof.svg) 26px 28px / 52px 57px repeat;
  mask:url(img/brand/hoof.svg) 0 0 / 52px 57px repeat, url(img/brand/hoof.svg) 26px 28px / 52px 57px repeat; }

/* Капля вместо круга (идея 12): подложка — наклонный овал из эмблемы
   (drop.svg) псевдоэлементом под содержимым; isolation держит z-index:-1
   внутри элемента, а не под стеклом меню. Первые адресаты: бейдж таббара,
   аватар профиля, подложка гостя, кружки пустых состояний. */
.nav__badge { isolation:isolate; background:transparent; border-radius:0; }
.nav__badge::before { content:""; position:absolute; inset:-2px -3px; z-index:-1; background:var(--accent);
  -webkit-mask:url(img/brand/drop.svg) center/100% 100% no-repeat; mask:url(img/brand/drop.svg) center/100% 100% no-repeat; }
/* На десктопе бейдж стоит в потоке (position:static выше, ≥900px) — без
   relative капля-подложка прилипала бы ко всей кнопке вкладки. */
@media (min-width:900px) { .nav__badge { position:relative; } }
.pavatar, .pguest__logo { position:relative; isolation:isolate; border-radius:0; background:transparent; }
.pavatar::before, .pguest__logo::before { content:""; position:absolute; inset:0; z-index:-1; background:var(--soft);
  -webkit-mask:url(img/brand/drop.svg) center/100% 100% no-repeat; mask:url(img/brand/drop.svg) center/100% 100% no-repeat; }

/* Эмблема «A.» + всадник, читаемая в обеих темах: буква — маска currentColor
   (emblem_letter.svg), всадник — картинка в том же viewBox (rider_in_emblem.svg),
   поэтому слои совпадают пиксель в пиксель. Гость в профиле. */
.emb { display:block; position:relative; width:64px; height:49px; color:var(--text); background:url(img/brand/rider_in_emblem.svg) center/contain no-repeat; }
.emb::before { content:""; position:absolute; inset:0; background:currentColor; -webkit-mask:url(img/brand/emblem_letter.svg) center/contain no-repeat; mask:url(img/brand/emblem_letter.svg) center/contain no-repeat; }

/* Пустые состояния со всадником (идея 22): капля вместо круга, всадник стоит
   (первый кадр), под блоком — следы копыт. Ошибка сети — тот же всадник в
   плоской серой капле + «Повторить». */
.empty__circle--rider { border-radius:0; background:transparent; position:relative; isolation:isolate; color:var(--accent); }
.empty__circle--rider::before { content:""; position:absolute; inset:0; z-index:-1; background:var(--soft);
  -webkit-mask:url(img/brand/drop.svg) center/100% 100% no-repeat; mask:url(img/brand/drop.svg) center/100% 100% no-repeat; }
.empty--error .empty__circle--rider { background:transparent; color:var(--muted); }
.empty--error .empty__circle--rider::before { background:var(--surface-alt); }

/* Дефолтный баннер бренда (идея 11) — когда админ не задал промо: оранжевая
   плитка, кремовые копыта 12 %, скачущий кремовый всадник справа. */
.banner2--brand { background:#FF6B00; color:#FFF0E4; align-items:center; }
.banner2--brand .hoof-pat { color:#FFF0E4; opacity:.12; }
.banner2--brand .banner2__body { padding-right:4px; }
.banner2__rider { position:relative; flex:none; display:flex; align-items:center; justify-content:center; padding:0 16px 0 4px; color:#FFF0E4; }
/* Акцентное слово курсивом Playfair: «Что закажем сегодня?», «Привезём быстро». */
.accent-w, .banner2__title em { font-family:'Playfair Display', Georgia, serif; font-style:italic; font-weight:700; }
.accent-w { color:var(--accent); font-size:1.18em; line-height:1; }
.banner2__title em { font-size:1.1em; }

/* Кнопка «Поделиться» на обложке заведения (идея 37) — левее сердечка;
   .busy — пока качается карточка для системного листа. */
.rhead__share { right:60px; }
.rhead__share svg { fill:none; stroke:var(--muted); }
.rhead__share.busy svg { opacity:.4; }

/* ===== Маркет, волна 4 (08.09.2026): фундамент веба — «бумага и крафт» =====
   Токены и классы для зон W1a/W1b (каталог, корзина, чекаут, трекинг, заказы).
   Корневой класс .mkt ставится на экран (.scr.mkt) ТОЛЬКО у Маркета
   (isProc / isMarketOrder / cartIsMarket) — рестораны не меняются ни на пиксель.
   Светлая тема — «бумага и крафт»: фон #FFF7EF, панели #F3E6D6, линии #E4D2BC,
   «чернила» #1C1A18, «карандаш» #5A5450. Тёмная — «ночной магазин» (ключ, как
   во всём app.css, — [data-theme="dark"] на <html>): тёплый уголь #24211D /
   #2E2A25 / #3A342D, кремовые чернила #FFF0E4, карандаш #B9AEA2, плашки отделов
   с обводкой 1 px (--mkt-plate-glow = accent с альфой .35). Кассовый чек
   (.receipt) — ВСЕГДА кремовый с чёрным, как настоящий чек на столе. */
:root { --mkt-paper:#FFF7EF; --mkt-kraft:#F3E6D6; --mkt-kraft-line:#E4D2BC; --mkt-ink:#1C1A18; --mkt-pencil:#5A5450; --mkt-plate-glow:transparent; --mkt-receipt-paper:#FFF7EF; --mkt-receipt-ink:#1C1A18; --mkt-receipt-pencil:#5A5450; }
[data-theme="dark"] { --mkt-paper:#24211D; --mkt-kraft:#2E2A25; --mkt-kraft-line:#3A342D; --mkt-ink:#FFF0E4; --mkt-pencil:#B9AEA2; --mkt-plate-glow:rgba(255,138,61,.35); }

/* -- экран Маркета: перекрашиваем токены фона/карточек/линий — всё, что уже
   сверстано на var(--bg)/var(--card)/var(--line) (катбар, .mkt-list, строки
   mrow, корзина, сметы), само становится бумагой и крафтом; --muted →
   «карандаш». Фон кладём фиксированным слоем на весь вьюпорт (::before с
   z-index:-1), иначе на десктопе бумага заканчивалась бы на границе колонки
   680px. isolation:isolate обязателен: у <html> свой фон (--canvas), поэтому
   фон body рисуется обычным блоком и без своего контекста наложения накрыл
   бы слой с отрицательным z-index. Шторки/нав/пилюля (fixed, z ≥ 29) живут
   вне .scr — их палитра не меняется. -- */
.scr.mkt { --bg:var(--mkt-paper); --surface:var(--mkt-kraft); --card:var(--mkt-kraft); --line:var(--mkt-kraft-line); --muted:var(--mkt-pencil); position:relative; isolation:isolate; }
.scr.mkt::before { content:''; position:fixed; inset:0; z-index:-1; background:var(--mkt-paper); pointer-events:none; }
/* Панель «крафт» (KraftPanel мобилки): r14, рамка 1 px kraftLine. */
.mkt-kraft { background:var(--mkt-kraft); border:1px solid var(--mkt-kraft-line); border-radius:14px; padding:12px 14px; }
/* Линованная бумага (LinedPaperPainter корзины): линия каждые 28 px — под
   шапку витрины, записку-корзину и итоги. */
.mkt-lined { background-image:repeating-linear-gradient(to bottom, transparent 0, transparent 27px, var(--mkt-kraft-line) 27px, var(--mkt-kraft-line) 28px); }
/* В тёмной теме плашки эмодзи Маркета получают свечение 1 px (идея 10). */
[data-theme="dark"] .scr.mkt .mrow__ic--emo, [data-theme="dark"] .scr.mkt .cart-item__img--emo { box-shadow:inset 0 0 0 1px var(--mkt-plate-glow); }

/* -- пастели отделов (marketDeptColor мобилки — те же 8 пар light/dark):
   класс .mkt-dept--N (N = 0..7, считает mktDeptClass(name) в app.js) задаёт
   --plate плитке стеллажа, ценнику и любой плашке отдела. -- */
.mkt-dept--0 { --plate:#FFF1E5; } .mkt-dept--1 { --plate:#FFF0C2; } .mkt-dept--2 { --plate:#FFF7DB; } .mkt-dept--3 { --plate:#E8F3E2; }
.mkt-dept--4 { --plate:#FFE7E6; } .mkt-dept--5 { --plate:#EFE9F9; } .mkt-dept--6 { --plate:#F3ECDD; } .mkt-dept--7 { --plate:#E4F1F8; }
[data-theme="dark"] .mkt-dept--0 { --plate:#3A2A1C; } [data-theme="dark"] .mkt-dept--1 { --plate:#3B3118; } [data-theme="dark"] .mkt-dept--2 { --plate:#3A3522; } [data-theme="dark"] .mkt-dept--3 { --plate:#24331F; }
[data-theme="dark"] .mkt-dept--4 { --plate:#3E2427; } [data-theme="dark"] .mkt-dept--5 { --plate:#2E283E; } [data-theme="dark"] .mkt-dept--6 { --plate:#34301F; } [data-theme="dark"] .mkt-dept--7 { --plate:#20303A; }

/* -- стеллаж отделов на входе (идея 1): панель-крафт, плитки 4 в ряд (3 на
   узких экранах), gap 0 — каждая плитка «стоит» на своей полке: линия 3 px
   снизу через linear-gradient, без промежутков между колонками она сливается
   в сплошную полку на весь ряд; при 12 отделах выходит ровно три полки, при
   другом числе — по одной на ряд. Вдоль нижней полки бежит маленький всадник
   (.mkt-shelf__rider со спрайтом .gallop--sm): один пробег ~2.2 с, дальше
   статичный первый кадр. Разметка (W1a):
   <div class="mkt-shelf"><button class="mkt-tile" data-cat="i">
     <span class="mkt-tile__plate mkt-dept--N">🥛</span>
     <span class="mkt-tile__name">Молочное и яйца</span>
     <span class="mkt-tile__n">12 позиций</span></button>…
   <span class="mkt-shelf__rider"><i class="gallop gallop--sm"></i></span></div> -- */
.mkt-shelf { position:relative; display:grid; grid-template-columns:repeat(4, 1fr); gap:0; padding:8px 6px 24px; margin:0 0 10px; border-radius:16px; background:var(--mkt-kraft); border:1px solid var(--mkt-kraft-line); }
@media (max-width:399px) { .mkt-shelf { grid-template-columns:repeat(3, 1fr); } }
.mkt-tile { position:relative; display:flex; flex-direction:column; align-items:center; text-align:center; gap:5px; padding:8px 4px 12px; border:none; background:linear-gradient(to top, var(--mkt-kraft-line) 0, var(--mkt-kraft-line) 3px, transparent 3px) no-repeat; color:var(--text); font:inherit; cursor:pointer; transition:transform .12s ease; }
.mkt-tile:active { transform:scale(.95); }
.mkt-tile__plate { width:52px; height:52px; border-radius:16px; display:flex; align-items:center; justify-content:center; font-size:28px; line-height:1; background:var(--plate, var(--mkt-plate)); box-shadow:inset 0 0 0 1px var(--mkt-plate-glow), 0 3px 0 -1px rgba(28,26,24,.08); }
.mkt-tile__name { font-size:12px; font-weight:700; line-height:1.2; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.mkt-tile__n { font-size:11px; color:var(--muted); font-weight:500; line-height:1; }
@media (hover:hover) { .mkt-tile:hover .mkt-tile__name { color:var(--accent); } }
.mkt-shelf__rider { position:absolute; left:10px; bottom:3px; color:var(--mkt-pencil); pointer-events:none; animation:mktRide 2.2s ease-in-out 1 forwards; }
.mkt-shelf__rider .gallop { animation-iteration-count:4; }
@keyframes mktRide { from { left:10px; } to { left:calc(100% - 44px); } }

/* -- ценник с дырочкой (идея 3, ShelfTagBorder мобилки): тайл 58 px цвета
   отдела (--plate из .mkt-dept--N), отверстие r=4 слева — radial-gradient,
   сквозь него виден фон ленты; эмодзи 22 + подпись 11. Активный — оранжевый
   бренда с кремовым текстом (константы бренда, обе темы). Ставится на
   .catbar__chip внутри .catbar.mkt (W1a) — правила ниже перебивают чип-пилюлю
   по специфичности; .shelf-tag__b — бейдж «сколько уже в списке». -- */
.shelf-tag, .catbar.mkt .catbar__chip.shelf-tag { position:relative; display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; height:58px; min-width:64px; padding:4px 10px 4px 16px; border:none; border-radius:9px 12px 12px 9px; background:radial-gradient(circle at 8px 50%, transparent 4px, var(--plate, var(--mkt-kraft)) 4.6px); color:var(--text); font:inherit; font-size:11px; font-weight:700; line-height:1.1; white-space:nowrap; cursor:pointer; flex:none; box-shadow:0 1px 0 var(--mkt-kraft-line); transition:transform .12s ease, box-shadow .18s ease; }
.shelf-tag:active { transform:scale(.95); }
.shelf-tag__emo { font-size:22px; line-height:1; }
.shelf-tag__t { max-width:96px; overflow:hidden; text-overflow:ellipsis; }
.shelf-tag.on, .catbar.mkt .catbar__chip.shelf-tag.on { --plate:#FF6B00; background:radial-gradient(circle at 8px 50%, transparent 4px, #FF6B00 4.6px); color:#FFF0E4; box-shadow:0 4px 12px var(--accent-halo); }
@media (hover:hover) { .catbar.mkt .catbar__chip.shelf-tag:not(.on):hover { background:radial-gradient(circle at 8px 50%, transparent 4px, var(--plate, var(--mkt-kraft)) 4.6px); color:var(--accent); } }
.shelf-tag__b { position:absolute; right:-4px; top:-5px; min-width:18px; height:18px; padding:0 5px; border-radius:9px 9px 9px 2px; background:var(--accent); color:var(--on-accent); font-size:10.5px; font-weight:800; display:flex; align-items:center; justify-content:center; box-shadow:var(--shadow-float); }
.shelf-tag.on .shelf-tag__b { background:#FFF0E4; color:#FF6B00; }
.catbar.mkt.catbar--tags { padding-top:calc(10px + var(--safe-top)); padding-bottom:8px; gap:10px; }

/* -- кассовый чек (идея 16): всегда кремовая бумага с чёрными чернилами.
   Зубчатые края — ::before/::after с парой диагональных градиентов (плитка
   12×12, видна половина: период 12 px, зуб 6 px; сверху зубцы вверх, снизу —
   вниз, в выемках виден фон экрана). Отточия — border-bottom: 1px dotted у
   .receipt__row, текст «стоит» на линии поверх неё (фон бумаги закрывает
   точки под словами). «Итого» — курсив Playfair. Водяной знак — маска
   эмблемы «A.» 6 %. Разметку целиком собирает receiptHTML(o) в app.js. -- */
/* Тень — drop-shadow, а не box-shadow: она обходит контур вместе с зубцами,
   иначе на бумаге того же цвета (#FFF7EF) края чека растворялись бы. */
.receipt { position:relative; margin:14px 0; padding:16px 16px 18px; background:var(--mkt-receipt-paper); color:var(--mkt-receipt-ink); font-family:var(--font); filter:drop-shadow(0 2px 3px rgba(28,26,24,.16)); }
.receipt::before, .receipt::after { content:''; position:absolute; left:0; right:0; height:6px; background-repeat:repeat-x; background-size:12px 12px; pointer-events:none; }
.receipt::before { top:-6px; background-position:0 0; background-image:linear-gradient(to bottom right, transparent 50%, var(--mkt-receipt-paper) 50%), linear-gradient(to bottom left, transparent 50%, var(--mkt-receipt-paper) 50%); }
.receipt::after { bottom:-6px; background-position:0 100%; background-image:linear-gradient(to top right, transparent 50%, var(--mkt-receipt-paper) 50%), linear-gradient(to top left, transparent 50%, var(--mkt-receipt-paper) 50%); }
.receipt > * { position:relative; }
.receipt__wm { position:absolute; left:50%; top:50%; width:150px; height:115px; transform:translate(-50%,-50%); background:var(--mkt-receipt-ink); -webkit-mask:url(img/brand/emblem.svg) center/contain no-repeat; mask:url(img/brand/emblem.svg) center/contain no-repeat; opacity:.06; pointer-events:none; }
.receipt__head { display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:10px; }
.receipt__title { font-size:14px; font-weight:800; letter-spacing:.04em; text-transform:uppercase; }
.receipt__date { font-size:12px; color:var(--mkt-receipt-pencil); white-space:nowrap; }
.receipt__row { display:flex; justify-content:space-between; align-items:flex-end; gap:6px; margin:0 0 7px; border-bottom:1px dotted var(--mkt-receipt-pencil); font-size:14px; line-height:1.3; font-variant-numeric:tabular-nums; }
.receipt__row > span { position:relative; top:4px; background:var(--mkt-receipt-paper); padding:0 4px; }
.receipt__row > span:first-child { margin-left:-4px; min-width:0; }
.receipt__row > span:last-child { margin-right:-4px; white-space:nowrap; font-weight:700; }
.receipt__row--sum { margin-top:10px; font-weight:600; }
.receipt__row--sum > span:last-child { font-weight:800; }
.receipt__row--risk > span { color:var(--mkt-receipt-pencil); }
.receipt__diff { color:var(--mkt-receipt-pencil); font-size:12.5px; line-height:1.35; margin:6px 0 2px; }
.receipt__total { display:flex; justify-content:space-between; align-items:baseline; margin-top:12px; padding-top:10px; border-top:1px dashed var(--mkt-receipt-pencil); }
.receipt__total em { font-family:'Playfair Display', Georgia, serif; font-style:italic; font-weight:700; font-size:20px; }
.receipt__total b { font-size:20px; font-weight:800; font-variant-numeric:lining-nums tabular-nums; }
.receipt__photos { display:flex; flex-wrap:wrap; gap:8px; margin:8px 0 6px; }
.receipt__ph { width:56px; height:56px; object-fit:cover; border-radius:8px; border:1px solid rgba(28,26,24,.12); cursor:zoom-in; display:block; }
/* Тег «🧾 чек» в списке заказов (W1b) — та же кремовая бумага в миниатюре. */
.receipt-tag { display:inline-flex; align-items:center; gap:4px; font-size:11.5px; font-weight:700; color:var(--mkt-receipt-ink); background:var(--mkt-receipt-paper); border:1px solid var(--mkt-kraft-line); padding:2px 8px; border-radius:6px; white-space:nowrap; vertical-align:middle; }

/* -- сумка Маркета (идея 13): контейнер под inline-svg из mktBagSVG(size)
   (mktBagHTML(count, size) собирает целиком); .bump — «раздувается»
   1→1.08→1 за 260 мс (mktBagBump(el) перезапускает), под сумкой на 300 мс
   вспыхивает след копыт (.mkt-bag__trail = .hoofs). Счётчик — капля. -- */
.mkt-bag { position:relative; display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px; color:currentColor; flex:none; }
.mkt-bag svg { width:100%; height:100%; display:block; }
.mkt-bag.bump { animation:mktBump .26s ease-out; }
@keyframes mktBump { 0% { transform:scale(1); } 50% { transform:scale(1.08); } 100% { transform:scale(1); } }
.mkt-bag__n { position:absolute; right:-8px; top:-6px; min-width:18px; height:18px; padding:0 5px; border-radius:9px 9px 9px 2px; background:var(--accent); color:var(--on-accent); font-size:10.5px; font-weight:800; line-height:18px; text-align:center; pointer-events:none; }
.mkt-bag__trail { position:absolute; left:50%; top:100%; transform:translateX(-50%); margin:0; gap:5px; opacity:0; pointer-events:none; }
.mkt-bag__trail i { width:8px; height:9px; }
.mkt-bag.bump .mkt-bag__trail { animation:mktTrail .3s ease-out; }
@keyframes mktTrail { 0% { opacity:.8; } 100% { opacity:0; } }
/* Пилюля корзины и вкладка «Сумка» в контексте Маркета (W1b переключает класс). */
.cart-pill.mkt .mkt-bag { color:var(--on-accent); }
.nav__item .mkt-bag { width:24px; height:24px; }

/* -- закреплённое поле «Что купить?» (идея 7): липкое под шапкой, выше ленты
   отделов (z 6 > 5); лента отделов, идущая следом (соседний .catbar), сама
   сдвигается на высоту поля (58 px + чёлка; на десктопе — под навбар 56 px).
   .mkt-search__chips — ряд чипов отделов под полем, .mkt-hl — подсветка
   совпавшего куска названия, .mkt-dept-hit — карточка «🥛 Молочное · 14 →». -- */
.mkt-search { position:sticky; top:0; z-index:6; margin:0 -16px; padding:calc(6px + var(--safe-top)) 16px 6px; background:var(--bg); }
.mkt-search .search-box .inp { height:46px; background:var(--mkt-kraft); border-color:var(--mkt-kraft-line); box-shadow:none; }
.mkt-search .search-box .inp:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--soft); }
/* Высота поля переменная: с рядом чипов отделов (поиск) она растёт на 38 px,
   поэтому сдвиг ленты берём из замера --mkt-search-h (mktSyncSearchH в app.js;
   замер уже включает чёлку). Без токена — запасные 62 px = 6+46+4+6 паддингов
   и поля, иначе поле (z 6) накрывало бы ценники (z 5) ровно во время поиска. */
.scr.mkt .mkt-search ~ .catbar { top:var(--mkt-search-h, calc(62px + var(--safe-top))); padding-top:4px; }
@media (min-width:900px) { .mkt-search { top:56px; } .scr.mkt .mkt-search ~ .catbar { top:calc(56px + var(--mkt-search-h, 62px)); } }
.mkt-search__chips { display:flex; gap:6px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding:6px 0 0; scrollbar-width:none; -ms-overflow-style:none; }
.mkt-search__chips::-webkit-scrollbar { display:none; }
.mkt-hl { color:var(--accent); font-weight:800; }
.mkt-dept-hit { display:flex; align-items:center; gap:10px; width:100%; margin:0 0 8px; padding:10px 12px; border:1px solid var(--mkt-kraft-line); border-radius:14px; background:var(--mkt-kraft); color:var(--text); font:inherit; font-size:14px; font-weight:700; text-align:left; cursor:pointer; }
.mkt-dept-hit__emo { font-size:22px; line-height:1; flex:none; }
.mkt-dept-hit__t { flex:1; min-width:0; }
.mkt-dept-hit__n { color:var(--muted); font-weight:500; }
.mkt-dept-hit__go { color:var(--accent); font-weight:800; }

/* -- W1a, витрина: чипы отделов под полем поиска живут на бумаге (--surface-alt
   у Маркета не переопределён — красим сами), а ценник отдела без находок
   гаснет, оставаясь на месте: лента не «прыгает» при наборе. -- */
.scr.mkt .mkt-search__chips .catbar__chip { background:var(--mkt-kraft); color:var(--mkt-pencil); height:32px; font-size:13px; }
.scr.mkt .mkt-search__chips .catbar__chip.on { background:var(--accent); color:var(--on-accent); box-shadow:0 3px 10px var(--accent-halo); }
.shelf-tag--off, .catbar.mkt .catbar__chip.shelf-tag--off { opacity:.38; }
/* Прыжок к отделу: над лентой-ценниками стоит ещё и поле «Что купить?», так
   что липкая стопка Маркета глубже обычной (58+70 на телефоне, 114+70 под
   верхним навбаром десктопа) — вывеска отдела не должна нырять под неё.
   Порог подсветки активного ценника (TH в bindCatbar) держим тем же. */
.scr.mkt .h2 { scroll-margin-top:calc(128px + var(--safe-top)); }
/* !important — потому что десктопное правило `.h2[id^="cat"]` выше (строка
   с «Перебиваем инлайновый scroll-margin-top») тоже стоит с !important. */
@media (min-width:900px) { .scr.mkt .h2[id^="cat"] { scroll-margin-top:190px !important; } }
/* Строка «Моё обычное» и подсветка находки: имя не должно рвать бейджи. */
.mrow__nm { overflow-wrap:anywhere; }

/* -- полка «⭐ Моё обычное» (идея 20): панель-крафт со строками mrow, подпись
   «брали 3 раза · 12 авг» (.mkt-usual__meta), пометка «брали» у позиций в
   отделах (.mkt-taken), плашка «Повторить прошлый список · 8 позиций ·
   1 240 ₽» (.mkt-repeat, кнопка). -- */
.mkt-usual { background:var(--mkt-kraft); border:1px solid var(--mkt-kraft-line); border-radius:16px; padding:10px 12px 4px; margin:0 0 10px; }
.mkt-usual__head { display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:15px; font-weight:800; padding:2px 0 6px; }
.mkt-usual__head small { font-size:12px; font-weight:500; color:var(--muted); }
.mkt-usual .mrow { border-bottom-color:var(--mkt-kraft-line); }
.mkt-usual__meta { font-size:11.5px; color:var(--muted); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mkt-taken { display:inline-block; vertical-align:1px; margin-left:6px; font-size:10.5px; font-weight:700; color:var(--muted); background:var(--mkt-paper); border:1px dashed var(--mkt-kraft-line); padding:1px 6px; border-radius:var(--r-pill); white-space:nowrap; }
.mkt-repeat { display:flex; align-items:center; gap:10px; width:100%; margin:0 0 10px; padding:10px 12px; border:1px dashed var(--accent-ring); border-radius:14px; background:var(--soft); color:var(--text); font:inherit; text-align:left; cursor:pointer; transition:transform .12s ease; }
.mkt-repeat:active { transform:scale(.985); }
.mkt-repeat__ic { font-size:22px; line-height:1; flex:none; }
.mkt-repeat__t { flex:1; min-width:0; font-size:14px; font-weight:700; line-height:1.25; }
.mkt-repeat__t small { display:block; font-size:12px; font-weight:500; color:var(--muted); margin-top:1px; }
.mkt-repeat__go { color:var(--accent); font-weight:800; white-space:nowrap; }

/* -- бюджет «не больше N ₽» (идея 19): чипы в корзине (budgetChipsHTML +
   bindBudgetChips), «своя сумма» раскрывается в поле на месте чипа; подпись
   .mkt-budget__over — список уже выше лимита; строка «Бюджет 2 000 ₽ · сейчас
   1 860 ₽» на экране заказа (.mkt-budget__line, .over — красная) и баннер
   превышения (.mkt-budget__banner) по сокету order:budget. -- */
.mkt-budget { display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:10px 0 4px; }
.mkt-budget__lead { font-size:12.5px; color:var(--muted); font-weight:600; margin-right:2px; }
.mkt-budget__chip { border:1.5px solid transparent; background:var(--surface-alt); color:var(--text); border-radius:var(--r-pill); padding:6px 12px; font:inherit; font-size:12.5px; font-weight:600; cursor:pointer; transition:background-color .15s ease, color .15s ease, transform .12s ease; }
.scr.mkt .mkt-budget__chip { background:var(--mkt-kraft); border-color:var(--mkt-kraft-line); }
.mkt-budget__chip.on, .scr.mkt .mkt-budget__chip.on { background:var(--soft); border-color:var(--accent-ring); color:var(--accent); font-weight:700; }
.mkt-budget__chip:active { transform:scale(.95); }
.mkt-budget__inp { width:118px; height:36px; padding:0 12px; font-size:14px; border-radius:var(--r-pill); }
.mkt-budget__over { width:100%; font-size:12.5px; font-weight:600; color:var(--danger); }
.mkt-budget__line { display:flex; justify-content:space-between; gap:10px; font-size:13.5px; padding:5px 0; }
.mkt-budget__line b { font-weight:700; white-space:nowrap; }
.mkt-budget__line.over, .mkt-budget__line.over b { color:var(--danger); }
.mkt-budget__banner { display:flex; align-items:flex-start; gap:10px; margin:10px 0; padding:12px 14px; border-radius:14px; background:var(--danger-soft); color:var(--danger); font-size:13.5px; font-weight:600; line-height:1.35; }
[data-theme="dark"] .mkt-budget__banner { background:rgba(255,107,112,.14); }

/* -- «Собрано 7 из 12» (идея 18): подпись + полоска; ширина заливки —
   inline из mktProgressHTML(o); живёт по сокету order:items (обновление на
   месте по data-mkt-progress="<orderId>", без перечитывания заказа).
   .pick-dot — круглая галочка «в корзине» у строки клиента/курьера
   ([data-pick-item="<itemId>"] переключает .on по тому же сокету). -- */
.mkt-progress { margin:8px 0; }
.mkt-progress__t { display:flex; justify-content:space-between; align-items:baseline; gap:8px; font-size:13px; font-weight:700; margin-bottom:5px; }
.mkt-progress__t small { color:var(--muted); font-weight:500; font-variant-numeric:tabular-nums; }
.mkt-progress__bar { height:6px; border-radius:3px; background:var(--surface-alt); overflow:hidden; }
.scr.mkt .mkt-progress__bar { background:var(--mkt-kraft-line); }
.mkt-progress__fill { height:100%; width:0; border-radius:3px; background:var(--accent); transition:width .3s ease; }
.mkt-progress--done .mkt-progress__t { color:var(--accent); }
.pick-dot { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:50%; border:1.5px solid var(--mkt-kraft-line); background:transparent; vertical-align:-4px; margin-right:6px; flex:none; transition:background-color .15s ease, border-color .15s ease; }
.pick-dot::after { content:''; width:5px; height:9px; border:solid var(--on-accent); border-width:0 2px 2px 0; transform:rotate(45deg) translate(-1px,-1px); opacity:0; }
.pick-dot.on { background:var(--accent); border-color:var(--accent); }
.pick-dot.on::after { opacity:1; }
.picked .mrow__name, .picked > span:first-child { color:var(--muted); }
/* reduce-motion: сумка не раздувается, след не мигает, всадник стоит. */
@media (prefers-reduced-motion: reduce) {
  .mkt-bag.bump, .mkt-bag.bump .mkt-bag__trail, .mkt-shelf__rider, .mkt-shelf__rider .gallop { animation:none !important; }
  .mkt-progress__fill { transition:none; }
}

/* ===== Маркет, волна 4 — W1b: сумка в таббаре и пилюле, корзина-сумка,
   чекаут, трекинг и список заказов закупки. Только при классах, которые
   ставит app.js в контексте Маркета (.nav__b--bag, .cart-pill.mkt, .scr.mkt);
   рестораны не задеты. ===== */
/* Вкладка «Сумка» (идея 13): сумка в контейнере иконки .nav__ic (24 px; на
   десктопе, где меню сверху и иконки 20 px, — 20). Счётчик — общий .nav__badge. */
.nav__ic .mkt-bag { width:24px; height:24px; }
@media (min-width:900px) { .nav__ic .mkt-bag { width:20px; height:20px; } }
/* Плавающая пилюля Маркета: бумажная сумка с каплей-счётчиком вместо кружка;
   капля — инверсией цветов пилюли, иначе оранжевое на оранжевом сливалось бы. */
.cart-pill.mkt { padding-left:16px; }
.cart-pill__bag { display:flex; align-items:center; flex:none; margin-right:4px; }
.cart-pill.mkt .mkt-bag { width:30px; height:30px; }
.cart-pill.mkt .mkt-bag__n { background:var(--on-accent); color:var(--accent); }
.cart-pill.mkt .mkt-bag__trail { color:var(--on-accent); }
/* Корзина-сумка (идея 19): чипы бюджета — под свободной строкой в той же
   карточке, отделены пунктиром. */
.mkt-budget__wrap { margin-top:12px; padding-top:10px; border-top:1px dashed var(--mkt-kraft-line); }
/* Чек в раскрывашке карточки списка заказов (идея 16): бумага чуть уже
   отступов карточки; тег «🧾 чек» — в строке метаданных. */
.ocard__comp .receipt { margin:10px 0 6px; }
.ocard__meta .receipt-tag { font-size:11px; padding:1px 7px; }
/* Трекинг (идея 18): прогресс сборки в ленте похода — отбит пунктиром от
   подписей шагов; галочка у строки состава стоит по базовой линии текста. */
.tl__labels + .mkt-progress { margin:12px 0 0; padding-top:10px; border-top:1px dashed var(--line); }
.row-line .pick-dot { vertical-align:-3px; }
/* Плашка «Повторить прошлый список» под маскотом пустой сумки (идея 20). */
#mktLast { padding:0 0 16px; }
#mktLast .mkt-repeat { margin:0; }

/* ===== Доступность: prefers-reduced-motion — глушим декоративное движение
   (въезды, слайды шторок, пульсы, бегущий блик скелетонов). Функциональные
   индикаторы не трогаем: спиннеры (.btn--busy, .ptr) и прогресс историй
   несут смысл, а не украшение. Конфетти/полёт в корзину/View Transitions
   проверяют reduce сами в JS. ===== */
@media (prefers-reduced-motion: reduce) {
  .fin, .astep,
  .skel, .skel-wrap,
  .app-splash__logo,
  .sheet-back, .sheet-back .sheet,
  .seg-fade-l, .seg-fade-r,
  .rcard__fav.pop svg, .rhead__fav.pop svg, .dcard__qty.pop, .rstar.pop svg,
  .mrow__qty.pop, .mrow__add.pop { animation: none !important; }
  /* Всадник (дизайн-проект): статичный первый кадр вместо галопа — везде,
     включая pull-to-refresh и дефолтный баннер. В занятых кнопках всадника
     прячем и возвращаем прежний спиннер — он функциональный индикатор. */
  .gallop, .ptr--go .gallop--frame { animation: none !important; }
  .btn--busy::before { display: none; }
  .btn--busy::after { display: block; }
  /* Закрытие шторки — мгновенно, без слайда/фейда. */
  .sheet-back.closing, .sheet-back.closing .sheet { transition: none !important; }
  /* Праздник «заказ принят» → простая галочка с фейдом: круг и подпись без
     анимаций, галочка дорисована, кольца/конфетти скрыты (JS их и не кладёт,
     CSS — второй пояс). Фейд самого оверлея (.cel/.out) оставляем — смысловой. */
  .cel__circle, .cel__check, .cel__t { animation: none !important; }
  .cel__check { stroke-dashoffset: 0; }
  .cel__ring, .cel__conf { display: none; }
  /* Пилюля корзины: без слайда через весь экран — только фейд. */
  .cart-pill { transition: opacity .2s ease; }
  /* Тамб сегмента «Рестораны|Продукты» — без проезда. */
  .seg2__thumb { transition: none; }
}
