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

:root {
  /* Только светлая тема (2026-10-13): тёмной у приложения нет, системная её не включает. */
  color-scheme: light;
  --bg: #F6F4EF;          /* кремовый фон страницы */
  --card: #FFFFFF;        /* карточки продуктов и плитки */
  --tile: #EFECE4;        /* вторая по тишине подложка: кнопки в карточках */
  --fg: #1C1B19;
  --hint: #625D53;        /* подписи под цифрами, второстепенный текст */
  --line: #DDD8CC;
  --accent: #2F6B3F;      /* зелёный: главное действие и отметки */
  --on-accent: #FFFFFF;
  --yes: #2F6B3F;
  --no: #A8543D;
  --no-soft: #F2E9E3;     /* мягкая подложка для сохранённого */
  --no-line: #DFC7BA;
  /* Радиусы: пять ступеней на всё приложение (было семнадцать, от 3 до 24 px, и соседние
     карточки не сходились углами). */
  --r-xs: 8px;       /* мелочь: бейджи, миниатюры, полосы прогресса */
  --r-s: 12px;       /* поля ввода, плашки, маленькие кнопки */
  --r-m: 16px;       /* кнопки и карточки — основной радиус */
  --r-l: 20px;       /* крупные карточки и фото блюда */
  --r-pill: 999px;   /* чипы и таблетки */
  --radius: var(--r-m);  /* прежнее имя, оставлено для старых правил */

  /* Высоты: кнопка, поле, чип, касание. Раньше 36, 38, 44, 46, 48, 52, 54, 56 вперемешку. */
  --h-btn: 52px;     /* кнопки действий: «Дальше», «Готовить по шагам», нижние панели */
  --h-input: 48px;   /* поля ввода и выпадающие списки */
  --h-chip: 40px;    /* чипы, таблетки, маленькие кнопки в строке */
  --h-tap: 44px;     /* кнопка-значок: меньше пальцем не попасть */

  /* Выбранное состояние: два варианта. Заливка — у чипов, дней и таблеток; мягкая подсветка
     с рамкой — у карточек выбора (цель, приём пищи). Навигация (вкладки, ряд дней) — своя. */
  --sel-bg: var(--accent);
  --sel-fg: var(--on-accent);
  --sel-soft: color-mix(in srgb, var(--accent) 12%, var(--card));
  --sel-line: var(--accent);

  /* Отступ сверху в полноэкранном режиме Телеграма (Bot API 8.0): системная строка плюс его
     плавающие кнопки «Закрыть»/«Назад» и меню. Переменные ставит сам Телеграм; вне
     полноэкранного режима и в браузере они пустые — отступ 0. */
  --safe-top: calc(var(--tg-safe-area-inset-top, 0px) + var(--tg-content-safe-area-inset-top, 0px));

  /* Шрифтовая шкала: шесть размеров на всё приложение. До этого их было четырнадцать,
     от 12 до 30, и соседние экраны не сходились друг с другом — один и тот же по смыслу
     заголовок был то 21, то 27, то 30. Разницу между строками делаем весом и цветом,
     а не лишним кеглем. */
  --t-title: 26px;   /* заголовок страницы: h1 */
  --t-head: 20px;    /* заголовок блока внутри страницы, имя меню в карточке */
  --t-lead: 18px;    /* название в строке списка — то, что ищут глазами */
  --t-body: 16px;    /* текст, кнопки, строки списков */
  --t-meta: 14px;    /* подписи: время, количество, пояснения */
  --t-label: 12px;   /* мелкие метки и всё, что набрано капслоком */
  /* Два особых размера вне шкалы: текст шага у плиты (читают с расстояния) и крупная цифра. */
  --t-step: 24px;
  --t-display: 56px;
}


/* touch-action: manipulation — двойной тап больше не увеличивает страницу;
   overscroll-behavior — экран не «оттягивается» за край, от чего нижняя панель
   уезжала вверх-вниз. */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }

html, body { overscroll-behavior: none; }

/* Кнопки и поля сами шрифт страницы не наследуют — браузер ставит системный, и кнопка
   выглядела «чужой» рядом с текстом. Одно правило на всё приложение. */
button, input, select, textarea { font-family: inherit; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: var(--t-body)/1.45 "Golos Text", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}

.page {
  max-width: 560px;
  margin: 0 auto;
  padding: calc(16px + var(--safe-top)) 16px calc(32px + env(safe-area-inset-bottom));
}
/* Полоса под кнопками Телеграма закрашена фоном: прокручиваемое не просвечивает под ними. */
body::before {
  content: ""; position: fixed; left: 0; right: 0; top: 0; height: var(--safe-top);
  background: var(--bg); z-index: 50; pointer-events: none;
}


h1 { font-size: var(--t-title); line-height: 1.2; margin: 4px 0 6px; }
h2 { font-size: var(--t-meta); margin: 22px 0 8px; color: var(--hint); font-weight: 600; }
p { margin: 8px 0; }
a { color: var(--accent); text-decoration: none; }

/* Спрятанное — спрятано. Иначе display у класса (.actions — flex) перебивает
   атрибут hidden, и «Снять отметки» висит над пустым списком отметок. */
[hidden] { display: none !important; }

.hint { color: var(--hint); font-size: var(--t-meta); }
.small { font-size: var(--t-label); }
.center { text-align: center; }
.head { margin-bottom: 16px; }

.warn {
  background: color-mix(in srgb, #e8a33d 16%, var(--bg));
  border-radius: var(--r-m);
  padding: 10px 12px;
  font-size: var(--t-meta);
}


/* --- Обложка: пока фотографий нет, вместо них плашка с названием --- */

.cover {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-m);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
/* Цветная плашка — только без фото. Под фотографией её край проступал
   пиксельной линией: высота блока дробная, и фото не покрывало её целиком. */
.cover.noimg {
  background: linear-gradient(135deg,
    hsl(var(--tint) 46% 62%), hsl(calc(var(--tint) + 40) 52% 46%));
}
.cover img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.glyph { font-size: 30px; filter: drop-shadow(0 1px 4px rgba(0, 0, 0, .3)); }

.card { width: 72px; height: 72px; }
/* Без фотографии обложка не должна занимать полэкрана впустую. */
.hero.noimg { aspect-ratio: 16 / 5; }
.hero .glyph { font-size: 44px; }

/* --- Кнопки --- */

.actions { margin: 22px 0 10px; display: flex; flex-direction: column; gap: 10px; }
.actions form { margin: 0; }

/* Две кнопки на всё приложение: акцентная — то, ради чего экран; тихая — всё
   остальное. Рамок нет: на карточном фоне они спорили с краями карточек. */
.big, .quiet {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  min-height: var(--h-btn);
  border: 0;
  border-radius: var(--r-m);
  padding: 14px 16px;
  font: 600 var(--t-body)/1.2 inherit;
  text-align: center;
  cursor: pointer;
}
.big { background: var(--accent); color: var(--on-accent); }
.quiet { background: var(--tile); color: var(--fg); }
.big svg, .quiet svg {
  flex: none;
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Кнопка отзывается на палец: чуть проседает и светлеет, и так же плавно
   возвращается. Быстро — 120 мс, иначе ощущается как задержка. */
.big, .quiet {
  transition: transform .12s ease-out, opacity .12s ease-out, background .12s ease-out;
}
.big:active, .quiet:active { transform: scale(.97); opacity: .9; }
.quiet:disabled { opacity: .4; transform: none; }

/* --- Список блюд в категории --- */

/* Карточка блюда в списке: фотография слева, название и время справа. Крупнее,
   чем строка недели, — здесь по фотографии и выбирают. */
.dishes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.dish-tile { scroll-margin-top: 12px; }
.dish-tile form { margin: 0; }
.dish-tile a, .dish-tile button {
  display: flex; align-items: center; gap: 14px;
  padding: 10px;
  border-radius: var(--r-l);
  background: var(--card);
  color: inherit;
}
.dish-tile button { width: 100%; border: 0; font: inherit; text-align: left; cursor: pointer; }
.dish-tile a:active, .dish-tile button:active { transform: scale(.99); }
.tile-photo { width: 84px; height: 84px; border-radius: var(--r-m); flex: none; }
.dish-tile-text { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.dish-tile-text b { font-size: var(--t-lead); font-weight: 600; line-height: 1.25; }
.dish-tile-text .meta { font-size: var(--t-meta); color: var(--hint); }
/* «Сейчас выбран» у салата, который уже стоит к этому ужину: пришли менять —
   надо видеть, что меняем. Цветом, а не серым: это не подпись, а метка. */
.dish-tile-text .kind {
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--accent);
}

/* --- Ужин на сегодня: одно блюдо --- */

/* Сердце поверх фотографии, в углу: тёмная подложка, чтобы контур читался
   на любом снимке. */
/* Сердце — в верхней полосе, рядом с «назад»: сохранение относится к блюду. */
.fav {
  width: 44px; height: var(--h-tap);
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--fg);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.fav svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.fav.on svg { fill: var(--no); stroke: var(--no); }
.fav { transition: transform .15s cubic-bezier(.2, .8, .3, 1.4); }
.fav:active { transform: scale(.88); }
/* Сохранили — сердце коротко подпрыгивает. Класс ставит скрипт: иначе оно
   прыгало бы и при каждом открытии уже сохранённого блюда. */
.fav.бам svg { animation: сердце .32s ease-out; }
@keyframes сердце {
  0% { transform: scale(1); }
  45% { transform: scale(1.28); }
  100% { transform: scale(1); }
}
.fav:disabled { opacity: .5; }

/* Шапка: карточка во всю ширину с названием экрана и входом в избранное. */
/* Шапка — подпись раздела, а не кнопка. Раньше это была карточка со скруглением,
   то есть ровно то, чем в приложении выглядит всё нажимаемое: люди жали по
   названию и ничего не получали. Теперь фона у неё нет, а название — тихая
   подпись над заголовком (он и так называет экран словами покрупнее).
   Профиль теперь вкладка внизу, а не кружок здесь: безымянный кружок не читался
   как кнопка. */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  height: 44px;
  /* Отступ как у полей страницы: пока шапка была карточкой, её отделяла своя
     подложка, а у строки текста её нет — вплотную к следующему блоку она
     читается как его часть. */
  margin-bottom: 16px;
}
.brand {
  min-width: 0;
  font-size: var(--t-meta); font-weight: 600; color: var(--hint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.saved {
  flex: none;
  display: inline-flex; align-items: center; gap: 8px;
  height: var(--h-tap); padding: 0 8px 0 12px;
  border-radius: var(--r-s);
  background: var(--tile);
  color: var(--fg);
  font-size: var(--t-meta); font-weight: 600;
}
.saved svg {
  width: 20px; height: 20px;
  fill: var(--no); stroke: var(--no); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Число — кружком: его видно и когда слово не помещается. */
.saved .badge {
  min-width: 24px; height: 24px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--no);
  color: #fff;
  font-size: var(--t-label); font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.saved svg {
  width: 20px; height: 20px;
  fill: var(--no); stroke: var(--no); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.saved b { font-size: var(--t-meta); font-weight: 600; font-variant-numeric: tabular-nums; }

/* Кружок профиля в шапке — на месте прежнего «Избранного». Буква имени крупно:
   на маленьком круге она читается лучше любого значка. */
.avatar {
  flex: none;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--tile);
  color: var(--fg);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-lead); font-weight: 700;
  transition: transform .12s ease-out;
}
.avatar svg {
  width: 24px; height: 24px;
  fill: none; stroke: var(--hint); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.avatar:active { transform: scale(.92); }
.avatar.big { width: 64px; height: 64px; font-size: var(--t-title); }
.avatar.big svg { width: 34px; height: 34px; }

/* Страница профиля: кружок и имя в одну строку. */
.me { display: flex; align-items: center; gap: 14px; margin: 8px 0 20px; }
.me-text { min-width: 0; }
.me h1 { margin: 0; }
.me-text p { margin: 2px 0 0; }
.me-facts { margin-top: 18px; }
.me-facts a.fact { color: inherit; }

/* Избранное строкой на входе в «Экспресс блюдо»: листается вбок, не занимая экран. */
.saved-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 22px 0 8px;
}
.saved-head h2 { margin: 0; }
/* История просмотров: день — тихая подпись над карточками этого дня. */
.history-day { margin: 22px 0 10px; font-size: var(--t-meta); font-weight: 600; color: var(--hint); }
.history-day:first-of-type { margin-top: 4px; }
.saved-head .all { font-size: var(--t-meta); font-weight: 600; }
.fav-strip {
  list-style: none; margin: 0 -16px; padding: 0 16px;
  display: flex; gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Прилипание считает край прокрутки, а не край текста, и без этой строки
     полоса при открытии сама уезжает на ширину поля: первая карточка встаёт
     вплотную к краю, хотя пролистать ещё нечего. */
  scroll-padding: 0 16px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.fav-strip::-webkit-scrollbar { display: none; }
.fav-strip li { flex: none; width: 124px; scroll-snap-align: start; }
.fav-strip a { display: block; color: inherit; }
.fav-cover { width: 124px; height: 88px; margin-bottom: 6px; }
.fav-strip b {
  display: block;
  font-size: var(--t-meta); font-weight: 600; line-height: 1.25;
  /* Две строки на название: дальше многоточие, иначе карточки разной высоты. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.fav-strip .meta { font-size: var(--t-label); color: var(--hint); }

.plain { display: block; color: inherit; }
/* Снимок узнаётся и невысокой полосой, а экран нужен под продукты. */
.hero { width: 100%; aspect-ratio: 39 / 23; margin-bottom: 14px; }
.tonight-hero.noimg { aspect-ratio: 16 / 7; }
.tonight-hero .glyph { font-size: 56px; }

h1 { font-size: var(--t-title); line-height: 1.2; letter-spacing: -.01em; margin: 0 0 16px; }

/* Четыре факта о блюде плитками: цифра крупно, подпись под ней. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 24px;
}
.facts .fact { border-radius: var(--r-m); }
.fact {
  background: var(--card);
  border-radius: var(--r-m);
  padding: 10px 8px;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  text-align: center;
}
.fact svg {
  width: 20px; height: 20px;
  fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.fact b { font-size: var(--t-body); font-weight: 600; line-height: 1.2; }
/* Подпись — название шкалы: иначе «Средне» у сложности и у цены не различить. */
.fact span { font-size: var(--t-label); line-height: 1.2; color: var(--hint); }

.picks-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
}
.picks-head h2 { font-size: var(--t-head); font-weight: 700; margin: 0; color: var(--fg); }
.picks-how { margin: 0 0 12px; font-size: var(--t-meta); line-height: 1.45; color: var(--hint); }

/* Строка продукта — целиком кнопка: 56px высотой, в неё попадают не глядя.
   Отмеченный продукт — зелёный кружок с галочкой и зелёная рамка. */
.picks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.pick {
  display: flex; align-items: center; gap: 12px;
  min-height: var(--h-btn);
  padding: 8px 16px 8px 12px;
  background: var(--card);
  border: 1.5px solid var(--card);
  border-radius: var(--r-m);
  cursor: pointer;
}
.pick input { position: absolute; opacity: 0; pointer-events: none; }
.pick .mark {
  flex: none;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.pick .mark svg {
  width: 16px; height: 16px;
  fill: none; stroke: transparent; stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
}
.pick .what { flex: 1; min-width: 0; font-size: var(--t-body); font-weight: 500; }
.pick .amount { color: var(--hint); font-size: var(--t-meta); white-space: nowrap; }

/* Вид отметки идёт за самой галочкой: класс .want переключает скрипт, :has —
   страховка для браузеров без него. Снятая галочка должна гаснуть сразу. */
.pick.want, .pick:has(input:checked) { border-color: var(--accent); }
.pick.want .mark, .pick:has(input:checked) .mark {
  background: var(--accent); border-color: var(--accent);
}
.pick.want .mark svg, .pick:has(input:checked) .mark svg { stroke: var(--on-accent); }
/* Скрипт снял класс — гасим, даже если :has ещё говорит обратное. */
.pick:not(.want):has(input:not(:checked)) { border-color: var(--card); }
.pick:not(.want):has(input:not(:checked)) .mark {
  background: transparent; border-color: var(--line);
}
.pick:not(.want):has(input:not(:checked)) .mark svg { stroke: transparent; }
.pick:active { opacity: .8; }

/* Нижняя панель: главное действие и два тихих под ним. Прилипает к низу экрана. */
.bottom {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  margin: 0 auto;
  max-width: 560px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  /* Панель не отрезана от страницы линией: тот же фон, а сверху растушёвка,
     чтобы список уходил под кнопки плавно. */
  background: var(--bg);
  /* Рядов может быть два: при выборе ужина на неделю под главным действием стоят
     рецепт и «Другое блюдо», а над ними — строка о том, куда встанет выбранное. */
  display: flex; flex-direction: column; gap: 10px;
}
.bottom-note {
  margin: 0;
  text-align: center;
  font-size: var(--t-meta); color: var(--hint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Мягкая растушёвка над панелью — вместо жёсткого края. */
.bottom::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 100%;
  height: 24px;
  background: linear-gradient(to top, var(--bg), transparent);
  pointer-events: none;
}
/* Под панелью не должно оставаться спрятанного текста. */
body:has(.bottom) .page { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
/* Панель с двумя рядами выше — и прячет под собой больше страницы. */
body:has(.bottom-note) .page { padding-bottom: calc(230px + env(safe-area-inset-bottom)); }
/* Один ряд из двух колонок: рецепт и следующее блюдо. */
.bottom-row { display: flex; gap: 10px; width: 100%; }
.bottom-row > * { flex: 1 1 0; min-width: 0; }
.bottom-row form { margin: 0; }
.bottom-row .quiet { font-size: var(--t-meta); }
.quiet .подпись { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Сохранённое блюдо: кнопка окрашивается, сердце заливается. */
.quiet.on { background: var(--no-soft); color: var(--no); }
.quiet.on svg { fill: var(--no); stroke: var(--no); }

/* Плашка вместо модального окна: сказать «сохранено» — не повод останавливать
   человека окном, которое надо закрывать. Встаёт над нижней панелью. */
.toast {
  position: fixed;
  left: 50%; bottom: calc(24px + env(safe-area-inset-bottom));
  transform: translate(-50%, 8px);
  margin: 0;
  max-width: calc(100% - 32px);
  padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--fg);
  color: var(--bg);
  font-size: var(--t-meta);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s, transform .2s;
}
.toast.видно { opacity: .94; transform: translate(-50%, 0); }
body:has(.bottom) .toast { bottom: calc(160px + env(safe-area-inset-bottom)); }

/* --- Готовим по шагам --- */

.back {
  display: inline-flex; align-items: center; gap: 6px;
  height: var(--h-tap); padding: 0 12px 0 8px;
  margin: 0 0 8px -8px;
  border-radius: var(--r-s);
  color: var(--accent);
  font-size: var(--t-meta); font-weight: 600;
}
.back svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Шапка экрана готовки: маленькое фото, название и одна строка фактов. */
.cook-head { display: flex; align-items: center; gap: 14px; margin-bottom: 24px; }
.cook-head h1 { font-size: var(--t-head); line-height: 1.25; margin: 0 0 4px; }
.cook-head .meta { margin: 0; font-size: var(--t-meta); color: var(--hint); }
.thumb { width: 72px; height: 72px; border-radius: var(--r-s); flex: none; }
.thumb .glyph { font-size: 30px; }

.cook { scroll-margin-top: 12px; margin-bottom: 24px; }
.steps-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0 0 12px;
}
.steps-head h2 { font-size: var(--t-head); font-weight: 700; margin: 0; color: var(--fg); }
.step-count { font-size: var(--t-meta); font-weight: 600; color: var(--hint); }

/* По сегменту на шаг: видно, сколько пройдено и сколько осталось. */
.segments { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; margin-bottom: 12px; }
.segments span { height: 6px; border-radius: var(--r-pill); background: var(--line); transition: background .2s; }
.segments span.done { background: var(--accent); }
.cook:not(.по-шагам) .segments { display: none; }

.step-cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.step {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  border-radius: var(--r-l);
  background: var(--card);
  padding: 22px 20px;
}
.step .num {
  flex: none;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--t-lead); font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.step .text { margin: 6px 0 0; line-height: 1.5; }

/* Пошаговый режим: виден только текущий шаг, крупно — читается с расстояния от плиты. */
.по-шагам .step { display: none; min-height: 180px; }
.по-шагам .step.now { display: flex; }  /* без анимации: первый шаг виден сразу, а не из пустоты; листание анимируют .вправо/.влево */
.по-шагам .step .text { font-size: var(--t-head); line-height: 1.5; }
@keyframes шаг { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: none; } }

.step-nav { display: flex; gap: 10px; margin-top: 12px; }
.step-nav .quiet { flex: 1 1 0; height: var(--h-btn); font-size: var(--t-lead); }
.step-nav .big { flex: 2 1 0; height: var(--h-btn); font-size: var(--t-lead); }
.step-nav button:disabled { opacity: .35; }
/* «Приготовил» — под стрелками и во всю ширину: это не шаг карусели, а отдельное
   действие, и появляется оно, только когда рецепт дочитан до конца. */
#приготовил { width: 100%; height: var(--h-btn); margin-top: 10px; font-size: var(--t-lead); }

/* Список продуктов на экране готовки: отмечают то, что уже положили в кастрюлю. */
.need { margin-bottom: 24px; }
.checks {
  list-style: none; margin: 0; padding: 4px 0;
  background: var(--card);
  border-radius: var(--r-m);
}
.check {
  display: flex; align-items: center; gap: 12px;
  min-height: var(--h-btn);
  padding: 6px 16px 6px 14px;
  cursor: pointer;
}
.check input { position: absolute; opacity: 0; pointer-events: none; }
.check .box {
  flex: none;
  width: 26px; height: 26px;
  border-radius: var(--r-xs);
  border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.check .box svg {
  width: 16px; height: 16px;
  fill: none; stroke: transparent; stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
}
.check .what { flex: 1; min-width: 0; font-size: var(--t-body); }
.check b { font-size: var(--t-body); font-variant-numeric: tabular-nums; }
.check:has(input:checked) { color: var(--hint); }
.check:has(input:checked) .box { background: var(--accent); border-color: var(--accent); }
.check:has(input:checked) .box svg { stroke: var(--on-accent); }
.check:has(input:checked) .what, .check:has(input:checked) b { text-decoration: line-through; }

/* Салат к блюду: карточка с фотографией и кнопкой замены под ней. */
.salad-head { font-size: var(--t-head); font-weight: 700; margin: 24px 0 12px; color: var(--fg); }
.salad {
  background: var(--card);
  border-radius: var(--r-m);
  padding: 12px;
  display: flex; flex-direction: column; gap: 12px;
}
.salad-dish { display: flex; align-items: center; gap: 14px; color: inherit; min-width: 0; }
.salad-dish .cover { width: 72px; height: 72px; border-radius: var(--r-s); }
.salad-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.salad-text b { font-size: var(--t-lead); font-weight: 600; line-height: 1.3; }
.salad-text .meta { font-size: var(--t-meta); color: var(--hint); }
.salad-swap { border-radius: var(--r-s); font-size: var(--t-meta); min-height: var(--h-chip); }
/* Пока грузится другой салат — строка притухает, это и есть ответ на нажатие. */
#салат-блок.меняется .salad-swap { opacity: .6; }
/* Пока меняем салат — строка чуть гаснет: видно, что нажатие услышано. */
#салат-блок.меняется { opacity: .5; transition: opacity .1s; }

/* Строка-инструкция над продуктами. Значки в ней — те же, что на кнопках строки. */
.picks-how {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin: 0 0 10px;
  color: var(--hint); font-size: var(--t-label); line-height: 1.5;
}
/* Легенда и размер порции справа от заголовка: переносятся — встают одна под другой,
   без осиротевшей точки-разделителя. */


.picks-how .dot { width: 17px; height: 17px; margin: 0 3px 0 1px; }
.picks-how .dot svg { width: 11px; height: 11px; }

/* Нижний ряд: отложить блюдо и посмотреть другое. В Телеграме его заменяют
   нативные кнопки, поэтому здесь ряд обычный, в конце страницы. */


.bar-row 
.bar-row .big { flex: 1; width: auto; }

.wide {
  border: 0;
  border-radius: var(--r-m);
  padding: 15px 10px;
  font: 600 var(--t-body)/1.2 inherit;
  background: var(--card);
  color: var(--fg);
  text-align: center;
  cursor: pointer;
}


/* Плашка вместо попапа: в обычном браузере нативного попапа Телеграма нет. */
.toast {
  position: fixed;
  left: 50%; bottom: calc(84px + env(safe-area-inset-bottom));
  transform: translate(-50%, 8px);
  margin: 0;
  max-width: calc(100% - 32px);
  padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--fg);
  color: var(--bg);
  font-size: var(--t-meta);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s, transform .2s;
}
.toast.видно { opacity: .94; transform: translate(-50%, 0); }
body:has(.bottom) .toast { bottom: calc(160px + env(safe-area-inset-bottom)); }

/* --- Избранное --- */

.saved-title { font-size: var(--t-title); line-height: 1.15; margin: 0 0 6px; }
.saved-count { margin: 0 0 20px; font-size: var(--t-meta); }

/* Фильтры-пилюли: выбранная — тёмная, остальные светлые. */
.tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.tab {
  display: inline-flex; align-items: center;
  height: var(--h-tap); padding: 0 16px;
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--fg);
  font-size: var(--t-meta); font-weight: 600;
}
.tab.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.tab { transition: transform .12s ease-out, background .12s ease-out; }
.tab:active { transform: scale(.96); }

.saved-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.saved-card {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--card);
  border-radius: var(--r-l);
  padding: 12px;
}
/* Блюдо и сердечко — одной строкой, действия — под ними, как в списке на неделю. */
.saved-main { display: flex; align-items: center; gap: 12px; }
.saved-acts .act { flex: none; padding: 0 18px; }
/* Блюдо уже в списке или места нет: не кнопка, а состояние — нажимать нечего. */
.act.done { background: transparent; color: var(--hint); cursor: default; }
.act.done svg { stroke: var(--accent); }
.saved-dish { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; color: inherit; }
.big-thumb { width: 88px; height: 88px; border-radius: var(--r-m); }
.saved-text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.saved-text .kind {
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--hint);
}
.saved-text b { font-size: var(--t-lead); font-weight: 600; line-height: 1.3; }
.saved-text .meta { font-size: var(--t-meta); color: var(--hint); }

/* Убрать из избранного — залитое сердце на мягкой подложке. */
.drop {
  flex: none;
  width: 44px; height: var(--h-tap);
  border: 0; border-radius: 50%;
  background: var(--no-soft);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.drop svg { width: 22px; height: 22px; fill: var(--no); stroke: var(--no); stroke-width: 2; }
.drop { transition: transform .12s ease-out, opacity .12s ease-out; }
.drop:active { transform: scale(.9); opacity: .7; }

/* Убранное блюдо остаётся строкой с возвратом: сердечко легко задеть. */
.saved-card.gone {
  flex-direction: row; align-items: center; justify-content: space-between;
  background: transparent;
  border: 1.5px dashed var(--line);
  min-height: 56px;
  padding: 6px 8px 6px 16px;
  justify-content: space-between;
}
.gone-text { font-size: var(--t-meta); color: var(--hint); }
.вернуть {
  height: var(--h-tap); padding: 0 14px;
  border: 0; border-radius: var(--r-s);
  background: transparent;
  color: var(--accent);
  font: 700 var(--t-meta)/1.2 inherit;
  cursor: pointer;
}

/* Пустой экран: понятно, откуда здесь берутся блюда. */
.empty {
  background: var(--card);
  border-radius: var(--r-l);
  padding: 32px 24px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center;
}
.empty-mark {
  width: 64px; height: 64px;
  border-radius: 50%;
  background: var(--no-soft);
  display: flex; align-items: center; justify-content: center;
}
.empty-mark svg { width: 30px; height: 30px; fill: var(--no); stroke: var(--no); stroke-width: 2; }
.empty b { font-size: var(--t-lead); }
.empty p { margin: 0; font-size: var(--t-meta); line-height: 1.5; color: var(--hint); }
.empty .big { margin-top: 4px; width: auto; padding: 0 20px; height: var(--h-btn); }

/* --- Список на неделю --- */

/* Анкета над списком: почему блюда именно эти. Не заполнена — зовём цветом. */
.anketa {
  display: flex; align-items: center; gap: 12px;
  padding: 14px;
  margin-bottom: 18px;
  border-radius: var(--r-m);
  background: var(--card);
  color: var(--fg);
}
.anketa.zovem { background: color-mix(in srgb, var(--accent) 12%, var(--bg)); }
.anketa:active { transform: scale(.99); }
.anketa-icon { flex: none; width: 28px; height: 28px; }
.anketa-icon svg {
  width: 28px; height: 28px;
  fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.anketa-text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.anketa-text b { font-size: var(--t-body); font-weight: 600; }
.anketa-hint { font-size: var(--t-meta); line-height: 1.35; color: var(--hint); }
.anketa-go {
  margin-left: auto; flex: none;
  width: 20px; height: 20px;
  fill: none; stroke: var(--hint); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Список покупок: отдел — заголовок, под ним строки «продукт … сколько». */
.shop-dept {
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--hint);
  margin: 20px 0 8px;
}
.shop { list-style: none; margin: 0; padding: 0; background: var(--card); border-radius: var(--r-m); }
.shop li + li { border-top: 1px solid var(--line); }
/* Нажимается вся строка: в магазине телефон держат одной рукой, и попасть надо
   пальцем, а не в квадратик 20 на 20. */
.shop-row {
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border: 0; border-radius: inherit;
  background: transparent;
  color: var(--fg);
  font: 400 var(--t-body)/1.35 inherit;
  text-align: left;
  cursor: pointer;
}
.shop-row:active { background: var(--tile); }
.tick {
  flex: none;
  width: 24px; height: 24px;
  border: 2px solid var(--line);
  border-radius: var(--r-xs);
  display: flex; align-items: center; justify-content: center;
  transition: background .12s ease-out, border-color .12s ease-out;
}
.tick svg {
  width: 16px; height: 16px;
  fill: none; stroke: var(--on-accent); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0;
}
.pick.plain { cursor: default; }
.pick.plain .what { padding-left: 2px; }

.shop-name { min-width: 0; flex: 1 1 auto; }
.shop-amount { flex: none; color: var(--hint); white-space: nowrap; }
/* Куплено: галочка залита, строка зачёркнута и притушена — но остаётся на месте,
   чтобы список не прыгал под рукой. */
.shop-row.done .tick { background: var(--accent); border-color: var(--accent); }
.shop-row.done .tick svg { opacity: 1; }
.shop-row.done .shop-name { text-decoration: line-through; color: var(--hint); }
.shop-row.done .shop-amount { opacity: .6; }

/* Сводка под шапкой: сколько ужинов и во что это выльется в магазине. */
.week-head { margin-bottom: 14px; }
.week-head h1 { margin-bottom: 2px; }
.week-sum { margin: 0 0 14px; }

/* Полка меню: набор ужинов — строкой со стопкой фотографий, по ним он и узнаётся. */
.menus { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.menu-card { scroll-margin-top: 12px; }
.menu-link {
  display: flex; align-items: center; gap: 14px;
  min-height: 104px;
  padding: 12px 12px 12px 14px;
  border-radius: var(--r-l);
  background: var(--card);
  color: inherit;
}
.menu-link:active { transform: scale(.99); }
/* Стопка внахлёст: «несколько блюд вместе» читается сразу и занимает одну ячейку.
   Считаем с конца — тогда при одном-двух блюдах передняя карточка стоит на месте. */
.menu-fan { position: relative; flex: none; width: 100px; height: 80px; }
.menu-fan[data-n="1"] { width: 68px; }
.menu-fan[data-n="2"] { width: 84px; }
.menu-photo {
  position: absolute; left: 0; top: 12px;
  width: 68px; height: 68px;
  border: 3px solid var(--card);  /* просвет между карточками — цветом подложки */
  border-radius: var(--r-m);
}
.menu-fan .menu-photo:nth-last-child(2) { left: 16px; top: 6px; }
.menu-fan .menu-photo:nth-last-child(3) { left: 32px; top: 0; opacity: .85; }
.menu-text { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; }
.menu-text b { font-size: var(--t-head); font-weight: 800; line-height: 1.2; }
.menu-text .meta { font-size: var(--t-meta); color: var(--hint); }
/* Названия блюд — одной строкой: в карточке они подпись к фотографиям, не список. */
.menu-dishes {
  font-size: var(--t-meta); color: var(--hint); opacity: .85;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-go {
  flex: none;
  width: 20px; height: 20px;
  fill: none; stroke: var(--hint); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Меню, которое ещё собирают: рамка цвета акцента, чтобы на полке его не спутать
   с сохранёнными. А только что сохранённое на миг подсвечивается. */
.menu-card.draft .menu-link { box-shadow: inset 0 0 0 2px var(--accent); }
.menu-text .kind {
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--accent);
}
@keyframes fresh-card { from { box-shadow: inset 0 0 0 2px var(--accent); } to { box-shadow: inset 0 0 0 2px transparent; } }
.menu-card.fresh .menu-link { animation: fresh-card 2.4s ease-out; }

/* Сохранить меню: главное действие страницы, поэтому акцентная кнопка, а под ней —
   зачем это нужно. Объяснение под кнопкой, а не в заголовке: до низа списка человек
   уже понял, что у него за ужины, и вопрос у него ровно один — «а дальше что». */
.week-save { margin: 16px 0 0; display: flex; flex-direction: column; gap: 10px; }
.week-save .hint { margin: 0; text-align: center; }

.week { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
/* Карточка ужина: блюдо сверху, действия под чертой. Ни дня, ни даты — список это
   набор идей, а не расписание. Подписанные кнопки, а не два значка: «заменить»
   и «убрать» одинаковыми квадратиками различались только рисунком, и убрать можно
   было, метясь в замену. */
.dish-row {
  display: flex; flex-direction: column; gap: 12px;
  border-radius: var(--r-l);
  background: var(--card);
  padding: 12px;
  scroll-margin-top: 12px;
}
.dish-link { display: flex; align-items: center; gap: 14px; min-width: 0; color: inherit; }
.week-photo { width: 92px; height: 92px; border-radius: var(--r-m); }
.dish-text { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 8px; }
.dish-text b { font-size: var(--t-lead); font-weight: 700; line-height: 1.25; }
.dish-text .meta { font-size: var(--t-meta); line-height: 1.35; color: var(--hint); }
/* Блюдо разошлось с анкетой. Не плашкой во всю ширину, как .warn: это замечание
   об одной строке, и стоять оно должно внутри неё, рядом с «Заменить». */
.row-warn { margin: 0; font-size: var(--t-meta); line-height: 1.35; color: var(--no); }
/* Под ужин уже сходили в магазин. Не тревога, а цена правки — поэтому тихим цветом
   и со значком корзины, чтобы строка читалась как «это про покупки». */
.row-note {
  display: flex; gap: 8px;
  margin: 0;
  font-size: var(--t-meta); line-height: 1.35; color: var(--hint);
}
.row-note svg {
  flex: none;
  width: 16px; height: 16px; margin-top: 2px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Салат при ужине: строка поменьше и притушенная — это добавка к вечеру, а не
   второй вечер. Крестик убирает её одну, ужин остаётся. */
.row-salad {
  display: flex; align-items: center; gap: 10px;
  padding: 10px;
  border-radius: var(--r-m);
  background: var(--tile);
}
.row-salad-link { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; color: inherit; }
.salad-thumb { width: 44px; height: 44px; border-radius: var(--r-s); }
.row-salad-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.row-salad-text .kind {
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--hint);
}
.row-salad-text b { font-size: var(--t-meta); font-weight: 600; line-height: 1.3; }
/* Два действия у салата: заменить и снять. Оба значками без подписей — строка
   узкая, а рядом уже стоят подписанные «Заменить» и «Убрать» самого ужина, и
   повторять их словами было бы вдвойне шумно. */
.salad-act {
  flex: none;
  width: 36px; height: var(--h-chip);
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--hint);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.salad-act svg {
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.salad-act:active { transform: scale(.9); opacity: .7; }

/* Убранный салат остаётся строкой с возвратом — как ужин и как избранное. */
.row-salad.gone {
  justify-content: space-between;
  background: transparent;
  border: 1.5px dashed var(--line);
  padding: 6px 6px 6px 14px;
}
/* Салата ещё нет: пунктир, как у «Добавить ужин», только тише и мельче. */
.add-salad {
  gap: 10px;
  background: transparent;
  border: 1.5px dashed var(--line);
  color: var(--hint);
  font-size: var(--t-meta);
}
.add-salad:active { transform: scale(.99); }
.add-salad-plus {
  flex: none;
  width: 32px; height: 32px;
  border-radius: var(--r-s);
  background: var(--tile);
  display: flex; align-items: center; justify-content: center;
}
.add-salad-plus svg {
  width: 18px; height: 18px;
  fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round;
}

/* «Взять салат на неделю»: та же галочка, что и у продуктов блюда. */
.salad-take {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 2px 2px;
  font-size: var(--t-meta); line-height: 1.35;
  cursor: pointer;
}
.salad-take input { position: absolute; opacity: 0; pointer-events: none; }
.salad-take .mark {
  flex: none;
  width: 24px; height: 24px;
  border: 2px solid var(--line);
  border-radius: var(--r-xs);
  display: flex; align-items: center; justify-content: center;
  transition: background .12s ease-out, border-color .12s ease-out;
}
.salad-take .mark svg {
  width: 16px; height: 16px;
  fill: none; stroke: var(--on-accent); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0;
}
.salad-take input:checked + .mark { background: var(--accent); border-color: var(--accent); }
.salad-take input:checked + .mark svg { opacity: 1; }

.dish-acts { display: flex; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line); }
.act {
  flex: 1 1 auto;
  height: var(--h-tap); padding: 0 14px;
  border: 0; border-radius: var(--r-s);
  background: var(--tile);
  color: var(--fg);
  font: 600 var(--t-meta)/1.2 inherit;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer;
  transition: transform .12s ease-out, opacity .12s ease-out;
}
.act svg {
  flex: none;
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.act:active { transform: scale(.98); opacity: .9; }
/* «Убрать» — рядом, но тише: действие редкое, и попадать в него случайно нельзя. */
.ghost { flex: none; background: transparent; color: var(--hint); }
.ghost svg { stroke-width: 2.4; }
/* Убранный ужин остаётся строкой с возвратом: крестик легко задеть. */
.dish-row.gone {
  flex-direction: row; align-items: center; justify-content: space-between;
  background: transparent;
  border: 1.5px dashed var(--line);
  min-height: 56px;
  padding: 6px 6px 6px 16px;
}
/* «Добавить ужин»: строка, которой ещё нет, — поэтому пунктиром. */
.week-add {
  display: flex; align-items: center; gap: 12px;
  margin-top: 10px;
  padding: 10px 12px;
  border: 1.5px dashed var(--line);
  border-radius: var(--r-m);
  color: var(--fg);
}
.week-add:active { transform: scale(.99); }
.week-plus {
  flex: none;
  width: 44px; height: var(--h-tap);
  border-radius: var(--r-s);
  background: var(--tile);
  display: flex; align-items: center; justify-content: center;
}
.week-plus svg {
  width: 22px; height: 22px;
  fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round;
}
.week-add-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.week-add-text b { font-size: var(--t-body); font-weight: 600; }
/* --- Анкета --- */

/* «У нас разные порции»: галочка сама раскрывает список по едокам — без скрипта,
   чтобы анкета работала и с выключенным JavaScript. */
.pill-switch {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px;
  font-size: var(--t-meta); color: var(--hint);
  cursor: pointer;
}
.pill-switch input { position: absolute; opacity: 0; pointer-events: none; }
.pill-switch .mark {
  flex: none;
  width: 22px; height: 22px;
  border: 2px solid var(--line);
  border-radius: var(--r-xs);
  display: flex; align-items: center; justify-content: center;
}
.pill-switch .mark svg {
  width: 14px; height: 14px;
  fill: none; stroke: var(--on-accent); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0;
}
.pill-switch input:checked + .mark { background: var(--accent); border-color: var(--accent); }
.pill-switch input:checked + .mark svg { opacity: 1; }
#разные-порции + .portions { display: none; }
#разные-порции:has(input:checked) + .portions { display: flex; }


.anketa-form h2 { font-size: var(--t-lead); color: var(--fg); margin: 24px 0 10px; }
.chips-form { display: flex; flex-wrap: wrap; gap: 8px; }
/* Ответ — плашка целиком: попасть в неё легче, чем в кружок радиокнопки. */
.pill {
  display: inline-flex; align-items: center;
  min-height: var(--h-chip);
  padding: 0 16px;
  border-radius: var(--r-pill);
  background: var(--card);
  font-size: var(--t-body);
  cursor: pointer;
  transition: background .12s ease-out, color .12s ease-out;
}
.pill input { position: absolute; opacity: 0; pointer-events: none; }
.pill.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.pill:active { transform: scale(.97); }
/* Едоки: ответ — одна цифра, и плашка по ширине текста выходила овалом, причём у каждой
   цифры своим. Здесь настоящие круги: ширина равна высоте. */
#едоки .pill { flex: none; width: 44px; padding: 0; justify-content: center; }
/* Порции: по строке на едока — «Вы», «2-й человек». */
.portions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.portion-row { display: flex; flex-direction: column; gap: 6px; }
/* display у строки перебивает hidden — прячем явно, иначе видны все шесть. */
.portion-row[hidden] { display: none; }
.portion-who { font-size: var(--t-label); color: var(--hint); }
.portion-row .pill { flex: 1 1 0; justify-content: center; padding: 0 10px; font-size: var(--t-meta); }
/* Место под нижнюю панель с «Сохранить»: последняя строка не должна уходить под неё. */
.anketa-form { padding-bottom: 116px; }

/* --- Категории: вход в экспресс-блюдо --- */

/* Две плитки в ряд: попасть пальцем легко, и на экран влезают все разделы. */
.cats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cat {
  display: flex; align-items: center; gap: 12px;
  min-height: 72px;
  padding: 12px 14px;
  border-radius: var(--r-m);
  background: var(--card);
  color: var(--fg);
  transition: transform .12s ease-out, background .12s ease-out;
}
.cat:active { transform: scale(.97); background: var(--tile); }
/* «Всё равно» — во всю ширину и первым: большинству разницы нет. */
.cat.wide { margin-bottom: 8px; min-height: 76px; }
.cat-icon { flex: none; font-size: 26px; line-height: 1; }
.cat-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cat-text b { font-size: var(--t-body); font-weight: 600; }
.cat-hint { font-size: var(--t-meta); line-height: 1.3; color: var(--hint); }
.cat-go {
  margin-left: auto;
  flex: none;
  width: 20px; height: 20px;
  fill: none; stroke: var(--hint); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Шапка экрана блюда: категория и выход обратно к плиткам одной кнопкой.
   Здесь, в отличие от подписи раздела, нажимать как раз нужно — поэтому
   подложка стоит всегда, а не только под пальцем. */
.brand-link {
  min-width: 0;
  display: inline-flex; align-items: center; gap: 4px;
  height: 40px; margin-left: -4px; padding: 0 12px 0 6px;
  border-radius: var(--r-pill);
  background: var(--tile);
  color: var(--fg);
}
.brand-link .brand { color: var(--fg); }
.brand-link svg {
  flex: none;
  width: 22px; height: 22px;
  fill: none; stroke: var(--accent); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.brand-link:active { transform: scale(.97); }

/* --- Нижнее меню разделов --- */

.tabs-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  margin: 0 auto;
  max-width: 560px;
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
  background: var(--bg);
  display: flex;
  gap: 6px;
}
/* Растушёвка над меню — тем же приёмом, что у нижней панели на экране блюда. */
.tabs-bar::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 100%;
  height: 20px;
  background: linear-gradient(to top, var(--bg), transparent);
  pointer-events: none;
}
.tab-item {
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 8px 4px;
  border-radius: var(--r-m);
  color: var(--hint);
  font-size: var(--t-label); font-weight: 600;
  text-align: center;
  transition: transform .12s ease-out, background .12s ease-out, color .12s ease-out;
}
.tab-item svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.tab-item.on { background: var(--card); color: var(--accent); }
.tab-item:active { transform: scale(.97); }

/* Страница с одним лишь меню внизу: место под него и пустота сверху. */
body:has(.tabs-bar) .page { padding-bottom: calc(92px + env(safe-area-inset-bottom)); }

/* --- «Что приготовим?» ---
   Одно блюдо на экране, строка поиска сверху и условия плашками под ней. Число у чипа —
   цена выбора до нажатия; чип, после которого не остаётся блюд, гаснет и не нажимается.
   Режим экрана (карточка, выбор продуктов, фильтры) выбирает адрес — см. _builder.html. */

.ex-sub { margin: 0 0 4px; }
/* Строка поиска и плашки прилипают к верху: условия видно и менять, пока листаешь список. */
.ex-bar {
  position: sticky; top: var(--safe-top); z-index: 6;
  margin: 0 -16px; padding: 10px 16px 8px;
  background: var(--bg);
}
.ex-line { display: flex; gap: 10px; margin: 0; }
.ex-field {
  position: relative; flex: 1; min-width: 0; display: block; color: var(--hint);
}
.ex-field svg {
  position: absolute; left: 16px; top: 17px; width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.ex-field input {
  width: 100%; height: var(--h-input); padding: 0 16px 0 46px;
  border: 1.5px solid var(--line); border-radius: var(--r-l);
  background: var(--card); color: var(--fg);
  font: inherit; -webkit-appearance: none; appearance: none;
}
.ex-field input:focus { outline: none; border-color: var(--accent); }
.ex-field input::-webkit-search-cancel-button { -webkit-appearance: none; }
/* Правая кнопка: фильтры, а при выборе продуктов — «Готово». */
#ex-side { flex: none; display: flex; }
.ex-side {
  position: relative; min-width: 54px; height: var(--h-input); padding: 0 16px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-l); background: var(--tile); color: var(--fg);
  font-weight: 600;
}
.ex-side svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.ex-side svg .fill { fill: currentColor; stroke: none; }
.ex-done { background: var(--fg); color: var(--bg); }
.ex-badge {
  position: absolute; top: 6px; right: 6px;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-xs);
  background: var(--accent); color: var(--on-accent);
  font-size: var(--t-label); font-weight: 700; line-height: 18px; text-align: center;
}
#ex-hidden { display: none; }

.ex-tokens { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 10px; }
.ex-tok {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: var(--h-chip); padding: 0 12px 0 14px; border-radius: var(--r-l);
  background: var(--tile); color: var(--fg);
  font-size: var(--t-meta); font-weight: 600;
}
.ex-tok.want { background: color-mix(in srgb, var(--accent) 18%, var(--bg)); color: var(--accent); }
.ex-tok.not { background: var(--no-soft); color: var(--no); }
.ex-tok.not span { text-decoration: line-through; }
.ex-tok svg {
  width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round;
}

.ex-title { margin: 18px 0 10px; font-size: var(--t-label); color: var(--hint); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.ex-res { display: flex; align-items: baseline; justify-content: space-between; min-height: 24px; }
.ex-res .ex-title { margin: 12px 0 10px; }
.ex-reset { font-size: var(--t-meta); font-weight: 600; color: var(--fg); text-decoration: underline; text-underline-offset: 3px; }
/* Перерисовывается — чуть гаснет: видно, что нажатие дошло. */
#ex-body.ждём { opacity: .6; transition: opacity .15s; }
#ex-body, #ex-overlay { overflow-anchor: none; }

/* Карточки, как в поиске TikTok (дизайн «Экспресс: карточки и лента», 2026-10-21): две в ряд,
   обложка 3:4 со временем, две строки названия с хэштегами и строка «автора». */
.xs-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 8px;
}
.xs-card { display: flex; flex-direction: column; min-width: 0; color: inherit; -webkit-user-drag: none; }
.xs-cover {
  position: relative; display: block; aspect-ratio: 3 / 4; border-radius: var(--r-xs); overflow: hidden;
  background: var(--tile);
}
.xs-cover.noimg, .xs-dot.noimg, .xf-photo.noimg {
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, hsl(var(--tint) 46% 62%), hsl(calc(var(--tint) + 40) 52% 46%));
}
.xs-cover.noimg .glyph { font-size: 44px; }
.xs-cover img, .xs-dot img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
}
.xs-cover::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 34%; pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, .42), rgba(0, 0, 0, 0));
}
.xs-time {
  position: absolute; left: 7px; bottom: 7px; z-index: 1;
  display: inline-flex; align-items: center; gap: 4px;
  color: #FFFFFF; font-size: var(--t-label); font-weight: 600; line-height: 1;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.xs-time svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.xs-tag {
  position: absolute; left: 6px; top: 6px; z-index: 1; padding: 3px 6px; border-radius: var(--r-xs);
  background: rgba(14, 21, 18, .72); color: #FFFFFF; font-size: var(--t-label); font-weight: 600; line-height: 1.25;
}
.xs-cap {
  margin: 8px 2px 0; min-height: 38px;
  font-size: var(--t-meta); line-height: 19px; font-weight: 500; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.xs-cap b { font-weight: 700; }
.xs-by {
  display: flex; align-items: center; gap: 5px; margin: 6px 2px 0; min-height: 20px;
  font-size: var(--t-label); line-height: 1.2; color: var(--hint);
}
.xs-ava {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; background: var(--tile); font-size: 11px; line-height: 1;
}
.xs-who { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.xs-fav { flex: none; width: 15px; height: 15px; fill: none; stroke: var(--hint); stroke-width: 2; stroke-linejoin: round; }
.xs-fav.on { fill: var(--no); stroke: var(--no); }

/* Ряды «Избранное» и «Недавно смотрели»: кружки с подписью, листаются вбок. */
.xs-row .ex-title { margin-bottom: 6px; }
.xs-strip {
  list-style: none; margin: 0 -16px; padding: 0 12px;
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none;
}
.xs-strip::-webkit-scrollbar { display: none; }
.xs-strip li { flex: 0 0 80px; }
.xs-strip a {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 4px 4px 8px;
  color: inherit; border-radius: var(--r-s);
}
.xs-dot { position: relative; width: 60px; height: 60px; border-radius: 50%; overflow: hidden; background: var(--tile); }
.xs-dot .glyph { font-size: 26px; }
.xs-dot-name {
  min-height: 30px; font-size: var(--t-label); line-height: 1.25; text-align: center;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Лента (static/feed.js): одно блюдо на весь экран, вверх — следующее, вниз — прошлое.
   Справа кнопки на стекле, снизу подписи на тени. Нижнее меню и страница под лентой. */
html.xf-open, html.xf-open body { overflow: hidden; }
.xf {
  position: fixed; inset: 0; z-index: 40; overflow: hidden; touch-action: none;
  background: #0E1512; color: #F4F6F1; user-select: none; -webkit-user-select: none;
  animation: xf-in var(--dur-base) var(--ease-out) both;
}
.xf.уходит { animation: xf-out 180ms var(--ease-exit) both; }
@keyframes xf-in { from { transform: scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes xf-out { to { transform: scale(.97); opacity: 0; } }
.xf .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.xf-track { position: absolute; inset: 0; will-change: transform; }
.xf-item { position: absolute; inset: 0; overflow: hidden; }
.xf-item[data-at="-1"] { transform: translateY(-100%); }
.xf-item[data-at="1"] { transform: translateY(100%); }
.xf-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; -webkit-user-drag: none; }
.xf-photo .glyph { font-size: 96px; }
.xf-shade {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to top, rgba(8, 14, 11, .9) 0, rgba(8, 14, 11, .66) 24%, rgba(8, 14, 11, .3) 44%, rgba(8, 14, 11, 0) 62%),
    linear-gradient(to bottom, rgba(8, 14, 11, .5) 0, rgba(8, 14, 11, 0) 20%);
}
.xf-text {
  position: absolute; left: 16px; right: 96px; bottom: calc(22px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 6px; text-shadow: 0 1px 14px rgba(0, 0, 0, .4);
}
.xf-text p, .xf-text h2 { margin: 0; }
.xf-cap { font-size: var(--t-label); line-height: 16px; letter-spacing: .1em; text-transform: uppercase; color: #F6D84C; font-weight: 600; }
.xf-name { font-size: var(--t-title); line-height: 1.1; font-weight: 800; color: #F4F6F1; text-wrap: balance; }
.xf-meta { font-size: var(--t-meta); line-height: 1.3; font-weight: 600; color: rgba(244, 246, 241, .88); }
.xf-tags { font-size: var(--t-meta); line-height: 1.3; font-weight: 700; }
.xf-menu { font-size: var(--t-meta); color: #DCE5DF; }
.xf-glass {
  background: rgba(14, 21, 18, .44); color: #FFFFFF;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.xf-back {
  position: absolute; left: 12px; top: calc(12px + var(--safe-top)); z-index: 2;
  width: var(--h-tap); height: var(--h-tap); border: 0; border-radius: 50%; padding: 0;
  display: grid; place-items: center; cursor: pointer;
}
.xf-back svg, .xf-ring svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.xf-rail {
  position: absolute; right: 6px; bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.xf-btn {
  width: 80px; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 0; border: 0; background: transparent; color: #FFFFFF; cursor: pointer;
  font-size: var(--t-label); font-weight: 600; line-height: 1.1; text-shadow: 0 1px 8px rgba(0, 0, 0, .55);
}
.xf-btn:disabled { opacity: .4; cursor: default; }
.xf-ring { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; }
.xf-btn:active .xf-ring { transform: scale(.9); }
/* Сердце — та же кнопка, что везде (fav.js), только крупнее и на стекле. */
.xf .xf-heart {
  width: 62px; height: 62px; background: rgba(14, 21, 18, .44); color: #FFFFFF;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: 0 12px 22px -10px rgba(0, 0, 0, .6);
}
.xf .xf-heart svg { width: 30px; height: 30px; }
.xf .xf-heart.on { background: var(--no); color: #FFFFFF; }
.xf .xf-heart.on svg { fill: #FFFFFF; }
.xf-burst {
  position: absolute; left: 50%; top: 44%; z-index: 3; width: 132px; height: 132px; margin: -66px 0 0 -66px;
  pointer-events: none; opacity: 0; color: var(--no); filter: drop-shadow(0 10px 24px rgba(0, 0, 0, .35));
}
.xf-burst svg { width: 100%; height: 100%; fill: currentColor; stroke: #FFFFFF; stroke-width: 1; stroke-linejoin: round; }
.xf-burst.go { animation: xf-burst .62s cubic-bezier(.2, 1.3, .4, 1) both; }
@keyframes xf-burst {
  0% { opacity: 0; transform: scale(.3) rotate(-12deg); }
  24% { opacity: 1; transform: scale(1.14) rotate(-6deg); }
  52% { opacity: 1; transform: scale(1) rotate(-8deg); }
  100% { opacity: 0; transform: translateY(-46px) scale(1.4) rotate(-8deg); }
}
.xf-coach {
  position: absolute; left: 50%; top: 38%; z-index: 2; width: 262px; margin-left: -131px;
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px 16px 16px;
  border-radius: var(--r-l); background: rgba(8, 14, 11, .58); text-align: center; pointer-events: none;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  font-size: var(--t-label); color: #C9D8CE;
}
.xf-coach[hidden] { display: none; }
.xf-coach b { font-size: var(--t-body); line-height: 1.25; color: #F4F6F1; }
.xf-coach-up svg { width: 30px; height: 30px; fill: none; stroke: #F4F6F1; stroke-width: 2; stroke-linecap: round; }
.xf-coach-up { animation: xf-coach 1.2s ease-in-out infinite; }
@keyframes xf-coach { 0%, 100% { transform: translateY(7px); opacity: .55; } 50% { transform: translateY(-7px); opacity: 1; } }
/* Плашка избранного над лентой и слева от кнопок. */
/* В ленте — та же кнопка, главная: внизу слева, подписи блюда встают над ней. */
.xf .xf-put {
  position: absolute; left: 16px; right: 96px; bottom: calc(20px + env(safe-area-inset-bottom)); z-index: 2;
  width: auto; box-shadow: 0 12px 22px -10px rgba(0, 0, 0, .6);
}
.xf-can-put .xf-text { bottom: calc(20px + var(--h-btn) + 16px + env(safe-area-inset-bottom)); }
html.xf-open .fav-toast { z-index: 41; bottom: calc(24px + env(safe-area-inset-bottom)); left: 16px; transform: none; }
html.xf-open .fav-toast.видно { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .xf, .xf.уходит, .xf-burst.go, .xf-coach-up { animation: none; }
  .xf-burst.go { opacity: 0; }
}

.ex-empty {
  background: var(--card); border-radius: var(--r-l); padding: 24px; min-height: 280px;
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
}
.ex-empty b { font-size: var(--t-head); }
.ex-empty .big { margin-top: 10px; }

/* Строка блюда в поиске: фото, название, состав, время. */
.ex-rows { display: flex; flex-direction: column; }
.ex-row {
  display: flex; align-items: center; gap: 14px; min-height: 76px; padding: 10px 2px;
  border-bottom: 1px solid var(--line); color: inherit;
}
.ex-thumb { width: 52px; height: 52px; border-radius: var(--r-m); }
.ex-thumb .glyph { font-size: var(--t-lead); }
.ex-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ex-row-text b { font-size: var(--t-body); font-weight: 600; line-height: 1.25; }
.ex-row-text .meta {
  font-size: var(--t-meta); color: var(--hint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ex-row-time { flex: none; font-size: var(--t-meta); color: var(--hint); font-variant-numeric: tabular-nums; }
.ex-all { margin-top: 12px; }

/* Поиск: продукты с «Есть» и «Без». */
.ex-prods { list-style: none; margin: 0; padding: 0; }
.ex-prods li {
  display: flex; align-items: center; gap: 8px; min-height: 60px;
  border-bottom: 1px solid var(--line);
}
.ex-prod-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ex-prod-text b { font-weight: 600; }
.ex-prod-text .meta { font-size: var(--t-label); color: var(--hint); }
.ex-pill {
  flex: none; display: flex; align-items: center; height: var(--h-chip); padding: 0 14px; border-radius: var(--r-s);
  font-size: var(--t-meta); font-weight: 600;
}
.ex-pill.yes { background: color-mix(in srgb, var(--accent) 18%, var(--bg)); color: var(--accent); }
.ex-pill.no { background: var(--no-soft); color: var(--no); }
.ex-pill.yes.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.ex-pill.no.on { background: var(--no); color: var(--bg); }

/* Выбор продуктов и панель фильтров прячут нижнее меню: внизу у них своя кнопка. */
body:has(.ex-flag[data-mode="entry"]) .tabs-wrap,
body:has(.ex-filters) .tabs-wrap { display: none; }
body:has(.ex-flag[data-mode="entry"]) .page { padding-bottom: 96px; }
.ex-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 8;
  max-width: 560px; margin: 0 auto;
  padding: 10px 16px calc(12px + env(safe-area-inset-bottom));
  background: var(--bg); border-top: 1px solid var(--line);
}
.ex-foot .big.off { background: var(--tile); color: var(--hint); cursor: default; }
.ex-entry .hint b { color: var(--fg); font-weight: 600; }

/* Панель фильтров во весь экран. */
body:has(.ex-filters) { overflow: hidden; }
.ex-filters {
  position: fixed; inset: 0; z-index: 40; max-width: 560px; margin: 0 auto;
  padding-top: var(--safe-top);
  background: var(--bg); display: flex; flex-direction: column;
  animation: ex-вход .3s cubic-bezier(.2, .8, .2, 1);
}
@keyframes ex-вход { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.ex-filters-head {
  flex: none; display: flex; align-items: center; gap: 10px; padding: 14px 12px 8px;
}
.ex-filters-head b { flex: 1; font-size: var(--t-head); }
.ex-round {
  width: 44px; height: var(--h-tap); border-radius: var(--r-l); background: var(--tile); color: var(--fg);
  display: flex; align-items: center; justify-content: center;
}
.ex-round svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.ex-filters-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 16px 24px; }
.ex-filters .ex-foot { position: static; border-top: 1px solid var(--line); }
@media (prefers-reduced-motion: reduce) {
  .ex-track, .ex-filters { transition: none; animation: none; }
}

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  /* 44 — наименьшее, во что пальцем попадают не целясь: при 40 и зазоре 8 легко
     задеть соседний чип. */
  min-height: var(--h-chip);
  padding: 0 14px;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--line);
  background: var(--card);
  color: inherit;
  font-size: var(--t-meta);
  text-decoration: none;
}
.chip:active { transform: scale(.97); }
.chip-icon { font-size: var(--t-body); }
.chip-n { font-size: var(--t-label); color: var(--hint); }
/* Отмеченное — цветом и крестиком: снять можно там же, где отметил. */
.chip.on {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
.chip.on .chip-n { color: inherit; opacity: .75; }
/* Флекс и display:block у svg — иначе значок садится на базовую линию текста
   и стоит выше середины чипа. */
.chip-x { display: flex; align-items: center; }
.chip-x svg {
  display: block;
  width: 14px; height: 14px;
  fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round;
}
/* Не сочетается с уже выбранным: гаснет, но остаётся на месте — видно, что
   выбор сузился, а не что продукты пропали. */
.chip.off { opacity: .35; pointer-events: none; }

/* --- «Меню» и «Продукты» --------------------------------------------------
   Дизайн «Новый главный экран: весь день — завтрак, обед, перекус, ужин»: те же токены,
   что у всего приложения, а радиусы — как в артбордах AppDay: 18 у карточек блюд и дней
   недели, 16 у итогов и списков покупок, 14 у плиток и дней, 12 у переключателя и кнопок
   в строке, 999 у «таблеток». Данные рисует plan.js из /api/state; здесь только вёрстка. */

.pm-loading { padding: 40px 0; text-align: center; }
.pm-ic { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.pm-cover { position: relative; overflow: hidden; display: block; flex: none; }
.pm-cover.noimg { background: linear-gradient(135deg, hsl(var(--tint) 46% 62%), hsl(calc(var(--tint) + 40) 52% 46%)); }
.pm-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.pm-top-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pm-top h1 { margin: 0; }
/* Неделя «таблеткой»: стрелок нет, пока сервер отдаёт одну неделю — только подпись. */
.pm-range {
  background: var(--card); border-radius: var(--r-pill); padding: 6px 12px;
  font-size: var(--t-meta); font-weight: 600; white-space: nowrap;
}
.pm-prefs {
  display: inline-flex; align-items: center; gap: 4px; margin: 6px 0 12px; max-width: 100%;
  font-size: var(--t-meta); color: var(--hint);
}
.pm-prefs span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-prefs .pm-ic { width: 16px; height: 16px; }
.pm-seg { position: relative; display: flex; width: 210px; padding: 3px; border-radius: var(--r-s); background: var(--tile); }
.pm-seg-pill {
  position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc(50% - 3px);
  border-radius: var(--r-xs); background: var(--card); box-shadow: 0 1px 2px rgba(0, 0, 0, .16);
  transition: transform .3s cubic-bezier(.2, .8, .2, 1);
}
.pm-seg.на-неделе .pm-seg-pill { transform: translateX(100%); }
.pm-seg button {
  position: relative; flex: 1 1 0; height: 34px; border: 0; background: transparent;
  color: var(--hint); font: 600 var(--t-meta)/1 inherit; cursor: pointer; transition: color .2s;
}
.pm-seg button.on { color: var(--fg); }

/* Ряд недели липнет к верху; выбранный день — белая «таблетка», которая переезжает. */
.pm-days { position: sticky; top: var(--safe-top); z-index: 3; background: var(--bg); margin: 0 -16px; padding: 12px 16px 10px; }
.pm-days-in { position: relative; display: flex; }
.pm-day-pill {
  position: absolute; top: 0; bottom: 0; left: 0; border-radius: var(--r-m); background: var(--fg);
  transition: transform .32s cubic-bezier(.2, .8, .2, 1);
}
.pm-day {
  position: relative; flex: 1 1 0; min-width: 0; height: 60px; border: 0; background: transparent;
  color: var(--fg); font: inherit; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  transition: color .2s;
}
.pm-wd { font-size: var(--t-label); font-weight: 600; letter-spacing: .04em; color: var(--hint); transition: color .2s; }
.pm-n { font-size: var(--t-lead); font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.pm-dot { width: 5px; height: 5px; border-radius: 50%; background: transparent; transition: background .2s; }
.pm-dot.today { background: var(--accent); }
.pm-dot.bad { background: var(--no); }
.pm-day.on { color: var(--bg); }
.pm-day.on .pm-wd { color: color-mix(in srgb, var(--bg) 75%, transparent); }
.pm-day.on .pm-dot.today { background: var(--bg); }
/* Выбранный день — белая «таблетка» с зелёным, без чёрной заливки (2026-10-13), как активная вкладка. */
.pm-day-pill { background: var(--card); }
.pm-day.on, .pm-day.on .pm-wd { color: var(--accent); }
.pm-day.on .pm-dot.today { background: var(--accent); }

.pm-day-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 4px 0 10px; }
.pm-day-head b { font-size: var(--t-head); font-weight: 700; }
.pm-day-head .hint { margin: 0; }
/* Итоги дня — одна карточка с тремя ячейками и разделителями, а не три плитки. */
.pm-stats { display: grid; grid-template-columns: repeat(3, 1fr); padding: 12px 4px; border-radius: var(--r-m); background: var(--card); }
.pm-stat { display: flex; flex-direction: column; align-items: center; gap: 1px; text-align: center; padding: 0 4px; }
.pm-stat + .pm-stat { border-left: 1px solid var(--line); }
.pm-stat b { font-size: var(--t-lead); font-weight: 700; line-height: 1.25; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pm-stat span { font-size: var(--t-label); color: var(--hint); line-height: 1.3; }
.pm-note {
  display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 10px 12px;
  border-radius: var(--r-m); background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  font-size: var(--t-meta); line-height: 1.4;
}
.pm-note .pm-ic { color: var(--accent); width: 18px; height: 18px; }
.pm-note span { flex: 1; }
.pm-note-act {
  flex: none; height: var(--h-chip); padding: 0 14px; border: 0; border-radius: var(--r-s);
  background: var(--accent); color: var(--on-accent); font: 600 var(--t-meta)/1 inherit; cursor: pointer;
}
.pm-pane.из-справа { animation: pm-справа .25s ease-out; }
.pm-pane.из-слева { animation: pm-слева .25s ease-out; }
@keyframes pm-справа { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes pm-слева { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }

/* Приём пищи: значок своего цвета, название капсом, ккал, плюс — и ниже блюдо или пустая строка. */
.pm-meal { margin-top: 20px; }
.pm-meal-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.pm-meal-ico { flex: none; width: 30px; height: 30px; border-radius: var(--r-s); display: flex; align-items: center; justify-content: center; }
.pm-meal-ico .pm-ic { width: 18px; height: 18px; }
.pm-meal-ico.b { --c: #9A6B1F; background: #F6EBD3; color: var(--c); }
.pm-meal-ico.l { --c: #2F6B3F; background: #E2EDE3; color: var(--c); }
.pm-meal-ico.s { --c: #A8543D; background: #F2E9E3; color: var(--c); }
.pm-meal-ico.d { --c: #4A5878; background: #E4E7EF; color: var(--c); }
.pm-meal-name { font-size: var(--t-label); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.pm-meal-kcal { margin-left: auto; font-size: var(--t-meta); color: var(--hint); font-variant-numeric: tabular-nums; }
.pm-meal-add {
  flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%; background: var(--card);
  color: var(--accent); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.pm-meal-add .pm-ic { width: 16px; height: 16px; stroke-width: 2.4; }
.pm-dish { display: flex; align-items: center; gap: 2px; padding: 10px 4px 10px 10px; border-radius: var(--r-l); background: var(--card); overflow: hidden; }
.pm-dish + .pm-dish { margin-top: 8px; }
.pm-cooked { display: inline-block; margin-top: 4px; font-size: var(--t-label); font-weight: 600; color: var(--accent); }
.pm-dish.cooked .pm-thumb { opacity: .55; }
.pm-dish.cooked b { color: var(--hint); }
.pm-dish.bad { box-shadow: inset 0 0 0 1.5px var(--no-line); }
.pm-dish-link { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 12px; color: inherit; }
.pm-thumb { width: 64px; height: 64px; border-radius: var(--r-s); }
.pm-dish-text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pm-dish-text b {
  font-size: var(--t-body); font-weight: 700; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pm-dish-text .meta { font-size: var(--t-meta); line-height: 1.3; color: var(--hint); }
.pm-bad { font-size: var(--t-label); color: var(--no); }
.pm-swap {
  flex: none; width: 44px; height: var(--h-tap); border: 0; border-radius: var(--r-s); background: transparent;
  color: var(--hint); cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.pm-swap .pm-ic { width: 18px; height: 18px; stroke-width: 2.2; }
.pm-swap:active { background: var(--tile); }
.pm-empty {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 12px;
  border: 1.5px dashed var(--line); border-radius: var(--r-l); background: transparent;
  color: var(--hint); font: var(--t-meta)/1.3 inherit; text-align: left; cursor: pointer;
}
.pm-empty.soon { opacity: .6; }
/* Сколько суточной нормы закрывает меню дня. */
.pm-norm { margin: 10px 0 0; padding: 12px 14px; border-radius: var(--r-m); background: var(--card); }
.pm-norm-who { display: flex; gap: 6px; margin: 0 0 10px; overflow-x: auto; scrollbar-width: none; }
.pm-who {
  flex: none; height: 32px; padding: 0 12px; border: 0; border-radius: var(--r-pill); background: var(--tile);
  color: var(--hint); font-family: inherit; font-size: var(--t-meta); font-weight: 600; cursor: pointer;
}
.pm-who.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.pm-norm-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pm-norm-top b { font-size: var(--t-body); }
.pm-norm-top span { font-size: var(--t-meta); color: var(--hint); }
.pm-norm-bar { height: 6px; margin: 8px 0 0; border-radius: var(--r-pill); background: var(--tile); overflow: hidden; }
.pm-norm-bar span { display: block; height: 100%; border-radius: var(--r-pill); background: var(--accent); transition: width .3s ease; }
.pm-norm.low .pm-norm-bar span { background: color-mix(in srgb, var(--accent) 55%, var(--hint)); }
.pm-norm.over .pm-norm-bar span, .pm-norm.over .pm-norm-top b { background: var(--no); color: var(--no); }
.pm-norm.over .pm-norm-top b { background: none; }
/* Нормы нет (не ответили «о себе») — та же карточка, но приглашение и ссылка на шаг анкеты. */
.pm-norm-ask { display: flex; align-items: center; gap: 12px; color: var(--fg); text-decoration: none; transition: transform .12s ease-out; }
.pm-norm-ask:active { transform: scale(.98); }
.pm-norm-ask-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pm-norm-ask-text b { font-size: var(--t-body); font-weight: 600; line-height: 1.3; }
.pm-norm-ask-text span { font-size: var(--t-meta); color: var(--hint); line-height: 1.35; }
.pm-norm-ask .pm-ic { flex: none; color: var(--hint); stroke: currentColor; fill: none; stroke-width: 2; }
.pm-macros { display: flex; gap: 14px; font-size: var(--t-meta); }
/* Норма в две строки (2026-10-13): «1 790 ккал · 85%» и короткое БЖУ справа. */
.pm-norm-top .pm-norm-pct { font-weight: 400; }
.pm-norm-top .pm-norm-bju { font-size: var(--t-label); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pm-macro i { color: var(--hint); font-style: normal; }
.pm-macro b { color: var(--hint); font-weight: 600; margin-right: 2px; }
/* Салат к обеду и ужину — под блюдом, карточка поменьше. */
.pm-salad { margin-top: 8px; padding-top: 8px; padding-bottom: 8px; }
.pm-salad .pm-thumb { width: 48px; height: 48px; border-radius: var(--r-s); }
.pm-add-salad { margin-top: 8px; padding: 8px 12px; }
.pm-plus {
  flex: none; width: 28px; height: 28px; border-radius: var(--r-xs); background: var(--tile); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.pm-plus .pm-ic { width: 16px; height: 16px; stroke-width: 2.4; }

/* Неделя списком: карточка на день, сегодняшний обведён. */
.pm-wk { display: flex; flex-direction: column; gap: 10px; }
.pm-wk-sum { margin: 0 0 2px; }
.pm-wk-day { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; border-radius: var(--r-l); background: var(--card); color: inherit; transition: transform .12s ease-out; }
.pm-wk-day:active { transform: scale(.99); }
.pm-wk-day.today { box-shadow: inset 0 0 0 2px var(--accent); }
.pm-wk-head { display: flex; align-items: baseline; gap: 8px; }
.pm-wk-head b { font-size: var(--t-lead); font-weight: 700; }
.pm-wk-badge { font-size: var(--t-label); font-weight: 600; color: var(--accent); }
.pm-wk-kcal { margin-left: auto; font-size: var(--t-meta); color: var(--hint); }
.pm-wk-line { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pm-wk-thumb { width: 28px; height: 28px; border-radius: var(--r-xs); }
.pm-wk-kind { flex: none; width: 62px; font-size: var(--t-label); color: var(--hint); }
.pm-wk-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--t-meta); font-weight: 500; }
.pm-wk-name.none { color: var(--hint); }

/* Продукты: итог, отделы капсом, список отдела — одна карточка с разделителями. */
.pm-shop-page h1 { margin-bottom: 6px; }
.pm-sum { margin-top: 14px; padding: 14px; border-radius: var(--r-m); background: var(--card); }
.pm-sum-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pm-sum-row b { font-size: var(--t-head); font-weight: 700; }
.pm-bar { height: 6px; margin-top: 10px; border-radius: var(--r-xs); background: var(--tile); overflow: hidden; }
.pm-bar span { display: block; height: 100%; border-radius: var(--r-xs); background: var(--accent); transition: width .3s ease; }
.pm-delta, .pm-done { margin: 10px 0 0; font-size: var(--t-meta); color: var(--hint); }
.pm-dept { margin: 20px 0 8px; font-size: var(--t-label); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--hint); }
.pm-shop-list { list-style: none; margin: 0; padding: 0; background: var(--card); border-radius: var(--r-m); }
.pm-shop-list li + li { border-top: 1px solid var(--line); }
.pm-shop {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 11px 14px;
  border: 0; border-radius: inherit; background: transparent; color: var(--fg);
  font: inherit; text-align: left; cursor: pointer;
}
.pm-shop:active { background: var(--tile); }
.pm-tick {
  flex: none; width: 24px; height: 24px; border-radius: var(--r-xs); border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  transition: background .12s ease-out, border-color .12s ease-out;
}
.pm-tick .pm-ic { width: 16px; height: 16px; stroke: var(--on-accent); stroke-width: 3; opacity: 0; }
.pm-shop.done .pm-tick { background: var(--accent); border-color: var(--accent); }
.pm-shop.done .pm-tick .pm-ic { opacity: 1; }
.pm-shop-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pm-shop-name { font-size: var(--t-body); line-height: 1.3; }
.pm-shop-for { font-size: var(--t-label); line-height: 1.35; color: var(--hint); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pm-shop-amount { flex: none; font-size: var(--t-meta); color: var(--hint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pm-shop.done .pm-shop-name { text-decoration: line-through; color: var(--hint); }
.pm-shop.warn .pm-shop-for { color: var(--no); }
.pm-shop.fresh .pm-shop-name::after { content: " · новое"; color: var(--accent); font-weight: 400; font-size: var(--t-meta); }
.pm-ask { margin: 12px 0 0; padding: 12px 14px; border-radius: var(--r-m); background: var(--card); }
.pm-ask p { margin: 4px 0 10px; }
.pm-ask-act { display: flex; gap: 8px; }
.pm-ask-act .big, .pm-ask-act .quiet { min-height: var(--h-chip); padding: 0 12px; font-size: var(--t-meta); }
.pm-empty-card { margin-top: 24px; padding: 20px; border-radius: var(--r-l); background: var(--card); display: flex; flex-direction: column; gap: 8px; }
.pm-empty-card b { font-size: var(--t-head); }

/* Плашка («Отменить») — «таблетка» над нижним меню, как в дизайне. */
.pm-toast {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: auto; max-width: calc(100% - 32px); bottom: calc(96px + env(safe-area-inset-bottom));
  border-radius: var(--r-pill); padding: 10px 16px; text-align: left; pointer-events: none;
}
.pm-toast.видно { pointer-events: auto; }
.pm-toast button { border: 0; background: transparent; color: inherit; font: 700 var(--t-meta)/1 inherit; text-decoration: underline; cursor: pointer; padding: 6px 0; }

/* Число на вкладке «Продукты»: сколько ещё купить. Сидит на значке, а не на самой вкладке:
   иначе виден он или нет, нижнее меню меняло высоту, и на главной оно было выше, чем на
   остальных экранах. */
.tab-ico { position: relative; display: flex; }
.tab-badge {
  position: absolute; top: -7px; left: 12px;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-xs);
  background: var(--accent); color: var(--on-accent);
  font-size: var(--t-label); font-weight: 700; line-height: 18px; text-align: center;
}

/* --- Блюдо: продукты и рецепт по шагам --------------------------------------
   Дизайн «блюдо, продукты и рецепт по шагам»: верхняя полоса, фото во всю ширину,
   факты, продукты с порциями, шаги по одному, внизу — панель с действиями. */

body:has(.dp-top) .page { padding-top: var(--safe-top); }
.dp-top {
  position: sticky; top: var(--safe-top); z-index: 6;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 0 -16px; padding: 6px 8px;
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.dp-back {
  display: flex; align-items: center; gap: 4px;
  height: var(--h-tap); padding: 0 12px 0 6px; border-radius: var(--r-s);
  color: var(--accent); font-size: var(--t-meta); font-weight: 600;
}
.dp-back svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.sh-cover { width: 100%; height: 232px; margin: 12px 0 0; border-radius: var(--r-l); }
.sh-cover.noimg .glyph { font-size: 64px; }
.sh-body { padding: 18px 0 8px; }
.kind { font-size: var(--t-label); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--hint); }
h1.sh-name { font-size: var(--t-title); line-height: 1.2; font-weight: 700; margin: 4px 0 14px; letter-spacing: -.01em; }
.sh-body .facts { margin-bottom: 0; }
.note {
  display: flex; align-items: flex-start; gap: 10px; margin-top: 12px; padding: 10px 12px;
  border-radius: var(--r-m); background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  font-size: var(--t-meta); line-height: 1.4;
}
.note svg { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; margin-top: 1px; }
.sh-body .warn { margin: 12px 0 0; }

.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 26px 0 10px; }
.sec-head h2 { font-size: var(--t-head); font-weight: 700; margin: 0; color: var(--fg); }
.sh-body .need { margin-bottom: 0; }
.sh-body .cook { margin-bottom: 8px; }
.por { display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: var(--r-pill); background: var(--card); }
.por button {
  width: 32px; height: 32px; border: 0; border-radius: 50%; background: var(--tile); color: var(--fg);
  font-size: var(--t-lead); font-weight: 600; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.por button:active { transform: scale(.92); }
.por span { min-width: 84px; text-align: center; font-size: var(--t-meta); font-weight: 600; }

/* Шаг: номер и крупный текст; под текстом — таймер, если в шаге названо время. */
.step-body { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.timer {
  display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px;
  border: 0; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg)); color: var(--accent);
  font: 600 var(--t-meta)/1 inherit; cursor: pointer; font-variant-numeric: tabular-nums;
}
.timer svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.timer.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.step-cards { touch-action: pan-y; }
.done-card {
  display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 14px; border-radius: var(--r-m);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg)); font-size: var(--t-meta); line-height: 1.4;
}
.done-card svg { flex: none; width: 24px; height: 24px; fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Нижняя панель блюда: заменить и убрать иконками, рядом — «Готовить по шагам». */
.dp-bar { background: var(--bg); border-top: 1px solid var(--line); gap: 0; }
.dp-bar::before { display: none; }
.dp-row { display: flex; gap: 8px; width: 100%; }
.dp-row .big { flex: 1 1 auto; width: auto; }
.icon-btn {
  flex: none; width: 52px; height: var(--h-btn); border: 0; border-radius: var(--r-m);
  background: var(--tile); color: var(--fg); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.icon-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn:active { transform: scale(.95); }
.icon-btn.lab { width: auto; min-width: 60px; padding: 0 6px; flex-direction: column; gap: 3px; font: 600 var(--t-label)/1 inherit; }
.dp-row .big { white-space: nowrap; min-width: 0; padding: 0 12px; }
.dp-row .big svg { flex: none; }
body:has(.dp-bar) .page { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
@media (prefers-reduced-motion: reduce) { .step-cards { scroll-behavior: auto; } }

/* --- Продукты простым списком и экран «Готовить по шагам» -----------------------------
   Дизайн «готовить по шагам — отдельный экран»: на странице блюда — состав и подсказка,
   шаги — на своём экране: шапка с названием, один шаг крупно, внизу «Назад» и «Дальше». */

.ing { list-style: none; margin: 0; padding: 0; border-radius: var(--r-m); background: var(--card); }
.ing li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 11px 14px; font-size: var(--t-body); }
.ing li + li { border-top: 1px solid var(--line); }
.ing-am { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dp-steps-hint { margin: 14px 2px 0; }
.dp-steps-hint a { font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

.cook-page { display: flex; flex-direction: column; min-height: calc(100dvh - 190px); padding-top: 16px; }
.cook-head { display: flex; align-items: center; gap: 14px; }
.ck-thumb { width: 72px; height: 72px; border-radius: var(--r-s); flex: none; }
.ck-text { min-width: 0; }
.ck-name { font-size: var(--t-head); line-height: 1.25; font-weight: 700; margin: 0 0 4px; letter-spacing: 0; }
.ck-text .hint { margin: 0; }
.cook-page .cook { flex: 1 0 auto; display: flex; flex-direction: column; margin-bottom: 0; }
.cook-page .sec-head.ck-first { margin-top: 22px; }
/* Шаг занимает весь свободный экран: ни карточки, ни фона — просто номер и крупный текст. */
.cook-page .step-vp { flex: 1 0 auto; display: flex; touch-action: pan-y; }
.cook-page .step-cards { flex: 1; }
.cook-page .step { flex-direction: column; gap: 18px; min-height: 0; padding: 18px 0 8px; border-radius: 0; background: transparent; }
.cook-page .по-шагам .step.now, .cook-page.по-шагам .step.now { flex: 1; }
.cook-page .step .num { width: 44px; height: 44px; }
.cook-page .step-body { gap: 20px; }
.cook-page .step .text { margin: 0; font-size: var(--t-step); line-height: 1.45; }
.cook.по-шагам .step.вправо { animation: шаг-вправо .34s cubic-bezier(.2, .8, .2, 1) both; }
.cook.по-шагам .step.влево { animation: шаг-влево .34s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes шаг-вправо { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes шаг-влево { from { transform: translateX(-40px); opacity: 0; } to { transform: none; opacity: 1; } }
.dp-bar.step-nav .dp-row { gap: 10px; }
.dp-bar.step-nav .quiet { flex: 1 1 0; width: auto; height: var(--h-btn); font-size: var(--t-lead); }
.dp-bar.step-nav .big { flex: 2 1 0; width: auto; height: var(--h-btn); font-size: var(--t-lead); }
.dp-bar.step-nav button:disabled { opacity: .35; }
/* Экран шагов — без нижнего меню разделов; на нём свои кнопки. */
@media (prefers-reduced-motion: reduce) { .cook.по-шагам .step.вправо, .cook.по-шагам .step.влево { animation: none; } }

/* --- Знакомство: анкета первого запуска ---------------------------------------
   Один вопрос на экран, крупно; внизу «Назад» и «Дальше». Чипы и карточки — на токенах
   приложения, радиусы как у меню: 14 у плиток, 18 у карточки блюда, 999 у чипов. */

body:has(.st-bar) .page { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
.st-loading { padding: 40px 0; text-align: center; }
.st-head { display: flex; align-items: center; gap: 12px; margin: 4px 0 14px; }
.st-mark { width: 36px; height: 36px; border-radius: var(--r-s); background: var(--tile); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.st-mark svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.st-seg { margin-bottom: 22px; }
.st-seg span.done { background: var(--accent); }
h1.st-q { font-size: var(--t-title); line-height: 1.2; margin: 0 0 8px; letter-spacing: -.01em; }
.st-hint { margin: 0 0 22px; }
.st-center { text-align: center; margin: 12px 0 0; }
.st-count { display: flex; align-items: center; justify-content: center; gap: 28px; padding: 18px 0 4px; }
.st-count b { font-size: var(--t-display); line-height: 1; min-width: 70px; text-align: center; font-variant-numeric: tabular-nums; }
.st-round {
  width: 56px; height: 56px; border: 0; border-radius: 50%; background: var(--tile); color: var(--fg);
  font: 600 var(--t-step)/1 inherit; cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.st-round:active { transform: scale(.94); }
.st-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.st-chip {
  min-height: var(--h-chip); padding: 0 16px; border: 1.5px solid var(--line); border-radius: var(--r-pill);
  background: var(--card); color: var(--fg); font: var(--t-body)/1 inherit; cursor: pointer;
}
.st-chip.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
/* «Что и когда планировать?»: приёмы пищи плитками 2×2, дни в ряд, неделя сеткой. */
.st-sec + .st-sec { margin-top: 20px; }
.st-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.st-sec-head .st-sub { margin: 0; }
.st-sec-head span { font-size: var(--t-meta); color: var(--hint); }
.st-meals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.st-meal {
  position: relative; min-width: 0; display: flex; align-items: center; gap: 10px; min-height: 64px; padding: 10px;
  border: 1.5px solid var(--line); border-radius: var(--r-m); background: var(--card); color: var(--fg);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .18s ease, background .18s ease, transform .12s ease-out;
}
.st-meal:active { transform: scale(.98); }
.st-meal.on { border-color: var(--sel-line); background: var(--sel-soft); box-shadow: inset 0 0 0 1px var(--sel-line); }
.st-meal-ico {
  flex: none; width: 36px; height: 36px; border-radius: var(--r-s); display: flex; align-items: center; justify-content: center;
  background: var(--tile); color: var(--hint); transition: background .18s, color .18s;
}
.st-meal.on .st-meal-ico { background: var(--accent); color: var(--on-accent); }
.st-meal-ico svg, .st-g-ico svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.st-meal-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.st-meal-text b { padding-right: 20px; font-size: var(--t-body); line-height: 1.2; white-space: nowrap; }
.st-meal-text span { font-size: var(--t-meta); line-height: 1.25; color: var(--hint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-meal-check {
  position: absolute; top: 8px; right: 8px; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center; transition: background .18s, border-color .18s;
}
.st-meal-check svg { width: 12px; height: 12px; fill: none; stroke: transparent; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; transition: stroke .18s; }
.st-meal.on .st-meal-check { background: var(--accent); border-color: var(--accent); }
.st-meal.on .st-meal-check svg { stroke: var(--on-accent); }
.st-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.st-day {
  height: var(--h-chip); border: 1.5px solid var(--line); border-radius: var(--r-s); background: var(--card); color: var(--fg);
  font-family: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer;
  transition: background .18s, border-color .18s, color .18s, transform .12s ease-out;
}
.st-day:active { transform: scale(.94); }
.st-day.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.st-presets { display: flex; gap: 6px; margin-top: 8px; }
.st-preset {
  flex: 1 1 0; height: var(--h-chip); border: 0; border-radius: var(--r-s); background: transparent; color: var(--hint);
  font-family: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer; transition: background .18s, color .18s;
}
.st-preset.on { background: var(--tile); color: var(--fg); }
.st-week { margin-top: 18px; padding: 14px 14px 12px; border-radius: var(--r-m); background: var(--card); }
.st-week-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.st-week-top b { font-size: var(--t-body); }
.st-week-top span { font-size: var(--t-meta); color: var(--hint); }
.st-grid { display: grid; grid-template-columns: 28px repeat(7, 1fr); row-gap: 4px; align-items: center; }
.st-g-day { text-align: center; font-size: var(--t-label); font-weight: 600; color: var(--hint); transition: color .18s; }
.st-g-day.on { color: var(--fg); }
.st-g-ico { width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; color: var(--hint); transition: color .18s; }
.st-g-ico.on { color: var(--accent); }
.st-g-ico svg { width: 16px; height: 16px; }
.st-cell { display: flex; justify-content: center; }
.st-cell span { width: 13px; height: 13px; border-radius: var(--r-xs); background: var(--tile); transition: background .2s; }
.st-cell span.on, .st-legend i.on { background: var(--accent); }
.st-cell span.soon, .st-legend i.soon { background: color-mix(in srgb, var(--accent) 40%, var(--tile)); }
.st-week-note { margin: 12px 0 0; font-size: var(--t-meta); line-height: 1.4; color: var(--hint); }
.st-legend { display: flex; gap: 14px; margin-top: 8px; font-size: var(--t-label); color: var(--hint); }
.st-legend i { display: inline-block; width: 10px; height: 10px; border-radius: var(--r-xs); margin-right: 6px; vertical-align: -1px; }
@media (prefers-reduced-motion: reduce) {
  .st-meal, .st-meal-ico, .st-meal-check, .st-meal-check svg, .st-day, .st-preset, .st-g-day, .st-g-ico, .st-cell span { transition: none; }
}
/* БЖУ на порцию под фактами блюда. */
.macros-line { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 0 0 14px; font-size: var(--t-meta); }
.macros-line b { color: var(--hint); font-weight: 600; margin-right: 2px; }
.macros-line i { color: var(--hint); font-style: normal; }
/* Карточки остальных едоков. */
.st-eater { margin-top: 18px; padding: 14px; border-radius: var(--r-m); background: var(--card); }
.st-eater:first-child { margin-top: 0; }
.st-eater .st-sub { margin-top: 14px; }
.st-eater .st-sub:first-child { margin-top: 0; }
.st-eater-row { margin-top: 12px; }
.st-eater-warn { margin: 10px 0 0; font-size: var(--t-meta); }
.st-eater .st-field input[type=text] { font-family: inherit; }
.st-select {
  width: 100%; height: var(--h-input); padding: 0 12px; border: 1.5px solid var(--line); border-radius: var(--r-s);
  background: var(--bg); color: var(--fg); font-family: inherit; font-size: var(--t-body);
}
/* «О вас»: три числовых поля в ряд. */
.st-fields { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; }
.st-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.st-field span { font-size: var(--t-label); color: var(--hint); font-weight: 600; }
.st-field input {
  width: 100%; height: var(--h-input); padding: 0 12px; border: 1.5px solid var(--line); border-radius: var(--r-s);
  background: var(--card); color: var(--fg); font-family: inherit; font-size: var(--t-body);
}
.st-field input:focus { outline: none; border-color: var(--accent); }
.st-none { margin-top: 14px; width: 100%; border-radius: var(--r-m); border-style: dashed; }
.st-sub { margin: 18px 0 10px; font-size: var(--t-label); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--hint); }
.st-sub:first-child { margin-top: 0; }
.st-search { display: block; margin: 14px 0 10px; }
.st-search input {
  width: 100%; height: var(--h-input); padding: 0 16px; border: 1.5px solid var(--line); border-radius: var(--r-m);
  background: var(--card); color: var(--fg); font: inherit; -webkit-appearance: none; appearance: none;
}
.st-search input:focus { outline: none; border-color: var(--accent); }
.st-goals { display: flex; flex-direction: column; gap: 10px; }
.st-goal {
  display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; border: 1.5px solid var(--line);
  border-radius: var(--r-m); background: var(--card); color: var(--fg); font: inherit; text-align: left; cursor: pointer;
}
.st-goal b { font-size: var(--t-body); }
.st-goal span { font-size: var(--t-meta); color: var(--hint); }
.st-goal.on { border-color: var(--sel-line); background: var(--sel-soft); box-shadow: inset 0 0 0 1px var(--sel-line); }
.st-dish { border-radius: var(--r-l); background: var(--card); overflow: hidden; }
.st-photo { display: block; position: relative; height: 240px; }
.st-photo.noimg { background: linear-gradient(135deg, hsl(var(--tint) 46% 62%), hsl(calc(var(--tint) + 40) 52% 46%)); }
.st-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.st-dish-body { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px 16px; }
.st-dish-body b { font-size: var(--t-head); line-height: 1.25; }
.st-vote { display: flex; gap: 10px; margin-top: 14px; }
.st-vote .quiet, .st-vote .big { flex: 1 1 0; width: auto; }
.st-skip { display: block; margin: 12px auto 0; border: 0; background: transparent; color: var(--hint); font: 600 var(--t-meta)/1 inherit; text-decoration: underline; text-underline-offset: 3px; padding: 10px; cursor: pointer; }
.st-link { border: 0; background: transparent; color: var(--accent, #3a6b47); font: 600 var(--t-meta)/1.4 inherit; text-decoration: underline; text-underline-offset: 3px; padding: 6px 2px; cursor: pointer; }
.st-sub-gap { margin-top: 28px; text-align: center; }
.st-done { padding: 40px 8px; text-align: center; }
.st-done b { font-size: var(--t-head); }
.st-bar .dp-row { gap: 10px; }
.st-bar .quiet { flex: 1 1 0; width: auto; height: var(--h-btn); font-size: var(--t-lead); }
.st-bar .big { flex: 2 1 0; width: auto; height: var(--h-btn); font-size: var(--t-lead); }
.st-bar button:disabled { opacity: .5; }
.anketa-redo { flex: none; font-size: var(--t-meta); font-weight: 600; color: var(--accent); white-space: nowrap; }

/* Профиль: анкета строками «метка — значение», каждая ведёт на свой шаг. */
.prof-rows { background: var(--card, #fff); border-radius: var(--r-m); margin: 16px 0; overflow: hidden; }
.prof-row { display: grid; grid-template-columns: 112px 1fr 18px; gap: 10px; align-items: center; padding: 14px 16px; text-decoration: none; color: var(--fg); border-bottom: 1px solid var(--line, rgba(0,0,0,.08)); }
.prof-label { font-size: var(--t-meta); color: var(--hint); }
.prof-value { font-size: var(--t-body); font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.prof-row .anketa-go { width: 18px; height: 18px; }
.prof-all { display: block; text-align: center; padding: 14px; font-size: var(--t-meta); font-weight: 600; color: var(--accent); text-decoration: none; }

/* Экран шагов: свёрнутые продукты над карточкой шага. */
.ck-ings { margin: 12px 0 4px; border-radius: var(--r-m); background: var(--card); }
.ck-ings summary { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; font-size: var(--t-body); font-weight: 600; cursor: pointer; list-style: none; }
.ck-ings summary::-webkit-details-marker { display: none; }
.ck-ings summary::after { content: "▾"; color: var(--hint); margin-left: 8px; }
.ck-ings[open] summary::after { content: "▴"; }
.ck-ings summary span { margin-left: auto; font-size: var(--t-meta); color: var(--hint); font-weight: 400; }
.ck-ings .ing { border-radius: 0 0 var(--r-m) var(--r-m); border-top: 1px solid var(--line); max-height: 40vh; overflow: auto; }

/* Продукты: «Покупаем на» и «Поделиться». */
.pm-when { margin: 14px 0 4px; display: flex; flex-direction: column; gap: 8px; }
.pm-when-t { font-size: var(--t-meta); font-weight: 600; color: var(--hint); }
.pm-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pm-chip { border: 1px solid var(--line); background: var(--card); color: var(--fg); border-radius: var(--r-pill); min-height: var(--h-chip); padding: 0 14px; font: 600 var(--t-meta)/1 inherit; cursor: pointer; }
.pm-chip.on { background: var(--sel-bg); border-color: var(--sel-bg); color: var(--sel-fg); }
.pm-chip-set { background: var(--tile); }
.pm-share { display: block; width: 100%; margin: 20px 0 8px; padding: 14px; border: 0; border-radius: var(--r-m); background: var(--tile); color: var(--fg); font: 600 var(--t-body)/1 inherit; cursor: pointer; }

.ex-note { margin: -6px 0 14px; padding: 10px 12px; border-radius: var(--r-s); background: var(--tile); font-size: var(--t-meta); line-height: 1.4; color: var(--fg); }

.st-more { display: block; width: 100%; margin-top: 12px; padding: 14px; border: 1px dashed var(--line); border-radius: var(--r-m); background: transparent; color: var(--accent); font: 600 var(--t-body)/1 inherit; cursor: pointer; }
.pm-wk-bad { display: block; font-size: var(--t-label); font-weight: 600; color: var(--no); }

/* =====================================================================================
   Премиальная анимация (2026-10-12, из дизайн-системы, раздел Motion). Нажатие, отклик на
   выбор, переходы страниц, загрузка. Правила ниже перекрывают прежние переходы по порядку;
   вибрация и тип перехода — static/motion.js.
   ===================================================================================== */

:root {
  /* Кривые: выход — быстрый старт и мягкая посадка; пружина — с перелётом на 1–2 %. */
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-soft-spring: cubic-bezier(.3, 1.25, .5, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --ease-exit: cubic-bezier(.4, 0, 1, 1);
  /* Длительности: нажатие короче всего, страница дольше всего. */
  --dur-press: 90ms;
  --dur-fast: 160ms;
  --dur-base: 240ms;
  --dur-page: 320ms;
  --dur-slow: 420ms;
}

/* --- Нажатие: вниз быстро и ровно, вверх — пружиной ------------------------------ */
.big, .quiet, .icon-btn, .pm-note-act, .pm-share, .st-round, .pm-meal-add, .pm-swap,
.pm-chip, .st-chip, .pm-who, .st-day, .st-preset, .pm-day, .tab-item, .pm-seg button,
.st-meal, .st-goal, .pm-shop, .pm-empty, .pm-dish-link, .pm-wk-day, .dish-tile a, .dish-tile button {
  transition:
    transform var(--dur-base) var(--ease-spring),
    filter var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}
/* Кнопки: −3 %, чуть темнее. Прозрачность не трогаем — кнопка «выцветала». */
:is(.big, .quiet, .icon-btn, .pm-note-act, .pm-share):active {
  transform: scale(.97); opacity: 1; filter: brightness(.94);
  transition-duration: var(--dur-press); transition-timing-function: var(--ease-out);
}
/* Мелкое — глубже, крупное — едва заметно: ход пальца одинаковый на глаз. */
:is(.pm-chip, .st-chip, .pm-who, .st-day, .st-preset, .pm-meal-add, .pm-swap, .st-round):active {
  transform: scale(.94); transition-duration: var(--dur-press); transition-timing-function: var(--ease-out);
}
:is(.pm-swap, .pm-meal-add):active { background: var(--tile); }
:is(.st-meal, .st-goal, .pm-shop, .pm-empty, .pm-dish-link, .pm-wk-day, .dish-tile a, .dish-tile button, .tab-item):active {
  transform: scale(.985); transition-duration: var(--dur-press); transition-timing-function: var(--ease-out);
}
:is(.big, .quiet, .pm-chip, .st-chip, .st-day, .st-round):disabled { transform: none; filter: none; }

/* Фокус с клавиатуры: кольцо выезжает, а не вспыхивает. */
:is(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
  transition: outline-offset var(--dur-fast) var(--ease-out);
}

/* --- Отклик на выбор: класс .just ставит скрипт на то, что тронули сейчас ----------
   Не на .on: экран перерисовывается целиком, и «прыгали» бы все выбранные чипы разом. */
@keyframes ds-pop { 0% { transform: scale(.92); } 60% { transform: scale(1.04); } 100% { transform: scale(1); } }
@keyframes ds-draw { from { stroke-dashoffset: 22; } to { stroke-dashoffset: 0; } }
@keyframes ds-strike { from { background-size: 0% 1.5px; } to { background-size: 100% 1.5px; } }
@keyframes ds-num-up { from { transform: translateY(40%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ds-num-down { from { transform: translateY(-40%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ds-fade-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

:is(.pm-chip, .st-chip, .pm-who, .st-day, .st-preset).just { animation: ds-pop var(--dur-base) var(--ease-spring); }
:is(.st-meal, .st-goal).just .st-meal-check, :is(.st-meal, .st-goal).just .st-meal-ico { animation: ds-pop var(--dur-base) var(--ease-spring); }

/* Покупка: квадрат пружинит, галочка прорисовывается, название зачёркивается слева направо. */
.pm-shop .pm-shop-name { align-self: flex-start; max-width: 100%; background: linear-gradient(currentColor, currentColor) 0 58% / 0% 1.5px no-repeat; }
.pm-shop.done .pm-shop-name { text-decoration: none; background-size: 100% 1.5px; }
.pm-tick .pm-ic polyline { stroke-dasharray: 22; stroke-dashoffset: 0; }
.pm-shop.just .pm-tick { animation: ds-pop var(--dur-base) var(--ease-spring); }
.pm-shop.done.just .pm-tick .pm-ic { opacity: 1; }
.pm-shop.done.just .pm-tick .pm-ic polyline { animation: ds-draw var(--dur-base) var(--ease-out) 60ms both; }
.pm-shop.done.just .pm-shop-name { animation: ds-strike var(--dur-base) var(--ease-out) 80ms both; }
.pm-tick { transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
.pm-bar span, .pm-norm-bar span { transition: width var(--dur-slow) var(--ease-out); }

/* Число в счётчике уезжает в сторону шага. */
.st-count b { display: inline-block; overflow: hidden; }
.st-count b.just-up { animation: ds-num-up var(--dur-base) var(--ease-out); }
.st-count b.just-down { animation: ds-num-down var(--dur-base) var(--ease-out); }

/* --- «Таблетки» дня и вида: едут с лёгким перелётом. Элемент таблетки не пересоздавать —
   менять только transform, иначе переезда нет. ------------------------------------- */
.pm-day-pill, .pm-seg-pill { transition: transform var(--dur-slow) var(--ease-soft-spring); }
.pm-day, .pm-wd, .pm-seg button { transition: color var(--dur-base) var(--ease-out); }

/* Смена дня внутри экрана: панель въезжает со стороны движения. */
.pm-pane.из-справа { animation: ds-pane-r var(--dur-page) var(--ease-out); }
.pm-pane.из-слева { animation: ds-pane-l var(--dur-page) var(--ease-out); }
@keyframes ds-pane-r { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes ds-pane-l { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }

/* Анкета: новый шаг въезжает со стороны движения, строки — одна за другой. */
#start.шаг-вперёд > :is(.st-q, .st-hint, .st-body) { animation: ds-pane-r var(--dur-page) var(--ease-out) both; }
#start.шаг-назад > :is(.st-q, .st-hint, .st-body) { animation: ds-pane-l var(--dur-page) var(--ease-out) both; }
#start:is(.шаг-вперёд, .шаг-назад) > .st-hint { animation-delay: 30ms; }
#start:is(.шаг-вперёд, .шаг-назад) > .st-body { animation-delay: 60ms; }

/* --- Плашка: поднимается пружиной, уходит быстро и прямо ---------------------------- */
.toast {
  transform: translate(-50%, 12px) scale(.96);
  transition: opacity var(--dur-fast) var(--ease-exit), transform var(--dur-fast) var(--ease-exit);
}
.toast.видно {
  opacity: .96; transform: translate(-50%, 0) scale(1);
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-base) var(--ease-spring);
}

/* --- Переходы между страницами (View Transitions, без сборки) -----------------------
   Вкладка ↔ вкладка — растворение; вглубь (блюдо, рецепт) — сдвиг справа; назад — слева.
   Тип перехода ставит Uzhin.motion.pageTypes() в <head>. Нижнее меню не двигается. */
@view-transition { navigation: auto; }
.tabs-wrap { view-transition-name: tabs; }
::view-transition-group(tabs) { animation: none; }
/* Меню есть только на одной стороне (вглубь — к блюду, назад — на вкладку): оно уходит вниз
   вместе со старой страницей и поднимается с новой, а не висит поверх перехода. */
::view-transition-old(tabs):only-child { animation: ds-vt-tabs-out var(--dur-fast) var(--ease-exit) both; }
::view-transition-new(tabs):only-child { animation: ds-vt-tabs-in var(--dur-page) var(--ease-out) both; }
@keyframes ds-vt-tabs-out { to { opacity: 0; transform: translateY(100%); } }
@keyframes ds-vt-tabs-in { from { opacity: 0; transform: translateY(100%); } }
::view-transition-old(root) { animation: ds-vt-fade-out var(--dur-fast) var(--ease-exit) both; }
::view-transition-new(root) { animation: ds-vt-fade-in var(--dur-page) var(--ease-out) both; }
html:active-view-transition-type(push)::view-transition-old(root) { animation: ds-vt-out-left var(--dur-page) var(--ease-in-out) both; }
html:active-view-transition-type(push)::view-transition-new(root) { animation: ds-vt-in-right var(--dur-page) var(--ease-out) both; }
html:active-view-transition-type(pop)::view-transition-old(root) { animation: ds-vt-out-right var(--dur-page) var(--ease-in-out) both; }
html:active-view-transition-type(pop)::view-transition-new(root) { animation: ds-vt-in-left var(--dur-page) var(--ease-out) both; }
@keyframes ds-vt-fade-out { to { opacity: 0; } }
@keyframes ds-vt-fade-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes ds-vt-out-left { to { opacity: 0; transform: translateX(-12%); } }
@keyframes ds-vt-in-right { from { opacity: 0; transform: translateX(28%); } }
@keyframes ds-vt-out-right { to { opacity: 0; transform: translateX(28%); } }
@keyframes ds-vt-in-left { from { opacity: 0; transform: translateX(-12%); } }
/* Где переходов страниц нет — страница просто мягко проявляется. */
@supports not (view-transition-name: none) { .page { animation: ds-fade-up var(--dur-page) var(--ease-out) both; } }

/* --- Загрузка: скелетон вместо «Загружаем…» ----------------------------------------- */
.ds-skel-page { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.ds-skel-row { display: flex; align-items: center; gap: 12px; padding: 10px; border-radius: var(--r-l); background: var(--card); }
.ds-skel-lines { flex: 1; display: flex; flex-direction: column; gap: 8px; }
@keyframes ds-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.ds-skeleton {
  display: block; border-radius: var(--r-m); min-height: 16px;
  background: linear-gradient(90deg, var(--tile) 30%, color-mix(in srgb, var(--tile) 45%, var(--card)) 50%, var(--tile) 70%) 0 0 / 200% 100%;
  animation: ds-shimmer 1.4s linear infinite;
}
/* Появление списка: строки одна за другой, по 30 мс, не больше восьми. */
.ds-stagger > * { animation: ds-fade-up var(--dur-base) var(--ease-out) both; }
.ds-stagger > :nth-child(2) { animation-delay: 30ms; } .ds-stagger > :nth-child(3) { animation-delay: 60ms; }
.ds-stagger > :nth-child(4) { animation-delay: 90ms; } .ds-stagger > :nth-child(5) { animation-delay: 120ms; }
.ds-stagger > :nth-child(6) { animation-delay: 150ms; } .ds-stagger > :nth-child(7) { animation-delay: 180ms; }
.ds-stagger > :nth-child(n+8) { animation-delay: 210ms; }

/* --- Меньше движения: всё мгновенно, цвет и прозрачность остаются ------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important; transition-duration: 1ms !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
  :is(.big, .quiet, .pm-chip, .st-chip, .st-meal, .pm-shop, .tab-item):active { transform: none; }
  .ds-skeleton { animation: none; }
}

/* =====================================================================================
   Шапки и избранное (2026-10-12). Две шапки на всё приложение и одно сердце.
   ===================================================================================== */

/* --- Раздел (вкладка): крупный заголовок слева, одно действие справа, подпись под ним. */
.hd-tab { margin: 4px 0 16px; }
.hd-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: var(--h-tap); }
.hd-tab h1, h1.hd-big {
  margin: 0; font-size: var(--t-title); line-height: 1.15; font-weight: 700; letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.hd-sub { margin: 4px 0 0; font-size: var(--t-meta); line-height: 1.4; color: var(--hint); }
.hd-act { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: none; }

/* --- Вложенный экран: липкая полоса. Слева круглая «назад», в середине название — оно
   проявляется, когда крупный заголовок уехал под полосу, справа действие (сердце).
   В Телеграме «назад» — кнопка клиента, наша убрана, а места остаются на своих местах. */
.hd-nav {
  position: sticky; top: var(--safe-top); z-index: 4;
  display: grid; grid-template-columns: var(--h-tap) minmax(0, 1fr) var(--h-tap);
  grid-template-areas: "back title act"; align-items: center; gap: 8px;
  margin: -16px -16px 12px; padding: 8px 16px;
  background: var(--bg);
  transition: box-shadow var(--dur-fast) var(--ease-out);
}
.hd-nav.под-ней { box-shadow: 0 1px 0 var(--line); }
.hd-btn {
  width: var(--h-tap); height: var(--h-tap); border: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--tile); color: var(--fg); cursor: pointer;
}
.hd-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.hd-back { grid-area: back; }
.hd-title {
  grid-area: title; min-width: 0; text-align: center;
  font-size: var(--t-body); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transform: translateY(6px);
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.hd-nav.заголовок-уехал .hd-title { opacity: 1; transform: none; }
.hd-nav > .hd-act { grid-area: act; }
h1.hd-big + .hd-sub { margin-bottom: 16px; }
h1.hd-big:not(:has(+ .hd-sub)) { margin-bottom: 16px; }
:is(.hd-btn, .avatar.hd-avatar):active { transform: scale(.92); transition-duration: var(--dur-press); }
.hd-btn { transition: transform var(--dur-base) var(--ease-spring), background-color var(--dur-fast) var(--ease-out); }

/* Профиль: имя заголовком, аватар — действие справа. */
.avatar.hd-avatar { width: var(--h-tap); height: var(--h-tap); font-size: var(--t-lead); }

/* --- Сердце: одна кнопка «в избранное» везде. Круг на tile; в избранном — терракотовая
   заливка на no-soft. Включение: сердце пружинит (.8 → 1.18 → 1), от него расходится кольцо. */
.heart {
  position: relative; flex: none;
  width: var(--h-tap); height: var(--h-tap); padding: 0; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--tile); color: var(--fg); cursor: pointer;
  transition: transform var(--dur-base) var(--ease-spring), background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.heart--lg { width: var(--h-btn); height: var(--h-btn); }
.heart--card { background: var(--card); }
.heart svg {
  width: 22px; height: 22px; overflow: visible;
  fill: transparent; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round;
  transition: fill var(--dur-fast) var(--ease-out);
}
.heart--lg svg { width: 24px; height: 24px; }
.heart.on { background: var(--no-soft); color: var(--no); }
.heart.on svg { fill: var(--no); }
.heart:active { transform: scale(.9); transition-duration: var(--dur-press); transition-timing-function: var(--ease-out); }
.heart:disabled { opacity: .5; }
.heart::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--no); opacity: 0; pointer-events: none;
}
@keyframes heart-in { 0% { transform: scale(.8); } 55% { transform: scale(1.18); } 100% { transform: scale(1); } }
@keyframes heart-out { 0% { transform: scale(1); } 40% { transform: scale(.82); } 100% { transform: scale(1); } }
@keyframes heart-ring { from { transform: scale(.7); opacity: .8; } to { transform: scale(1.6); opacity: 0; } }
.heart.on.just svg { animation: heart-in 420ms var(--ease-spring); }
.heart.on.just::after { animation: heart-ring 480ms var(--ease-out); }
.heart.just:not(.on) svg { animation: heart-out var(--dur-base) var(--ease-out); }

/* Плашка избранного (static/fav.js) — та же «таблетка», что в меню. */
.fav-toast { width: max-content; white-space: nowrap; }
.fav-toast button { border: 0; background: transparent; color: inherit; font: 700 var(--t-meta)/1 inherit; font-family: inherit; text-decoration: underline; cursor: pointer; padding: 6px 0; }

/* --- Движение на остальных экранах (2026-10-13): то же нажатие, что у кнопок меню. --- */
:is(.tab, .act, .cat, .prof-row, .ex-pill, .ex-tok, .ex-row, .ex-open, .por button, .saved-dish, .dish-tile a, .вернуть) {
  transition: transform var(--dur-base) var(--ease-spring), background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
:is(.tab, .act, .ex-pill, .ex-tok, .por button, .вернуть):active { transform: scale(.94); opacity: 1; transition-duration: var(--dur-press); transition-timing-function: var(--ease-out); }
:is(.cat, .prof-row, .ex-row, .ex-open, .saved-dish):active { transform: scale(.985); transition-duration: var(--dur-press); transition-timing-function: var(--ease-out); }
/* Порции на странице блюда: число уезжает в сторону шага, как в анкете. */
#порций-число { display: inline-block; }
#порций-число.just-up { animation: ds-num-up var(--dur-base) var(--ease-out); }
#порций-число.just-down { animation: ds-num-down var(--dur-base) var(--ease-out); }
/* Экспресс: новое блюдо и список проявляются после подмены частей экрана. */
@keyframes ds-swap-in { from { opacity: .4; transform: translateY(6px); } to { opacity: 1; transform: none; } }
#ex-body.ds-swap-in { animation: ds-swap-in var(--dur-base) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { #ex-body.ds-swap-in, #порций-число.just-up, #порций-число.just-down { animation: none; } }

/* --- Анкета, «Что вам нравится?»: колода карточек (2026-10-13) ----------------------
   Сверху карточка, под ней ещё две — выглядывают снизу, меньше и тише. Карточку смахивают
   (start.js): она идёт за пальцем, наклоняется, проступает штамп ответа, кнопка ответа
   подрастает. Улетает за порогом, иначе пружиной возвращается. Следующая поднимается. */
.st-taste { --yes: 0; --nope: 0; }
.st-deck-meta { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; }
.st-deck-bar { flex: 1; height: 4px; border-radius: var(--r-pill); background: var(--tile); overflow: hidden; }
.st-deck-bar span { display: block; height: 100%; border-radius: inherit; background: var(--accent); animation: st-deck-grow var(--dur-slow) var(--ease-out); }
@keyframes st-deck-grow { from { width: var(--from); } }
.st-deck-n { flex: none; font-size: var(--t-meta); font-weight: 600; color: var(--hint); font-variant-numeric: tabular-nums; }

.st-deck { position: relative; height: clamp(300px, 50vh, 392px); touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.st-card {
  position: absolute; inset: 0 0 24px; display: flex; flex-direction: column;
  border-radius: var(--r-l); background: var(--card); overflow: hidden;
  box-shadow: 0 0 0 1px var(--line), 0 18px 36px -24px rgba(28, 27, 25, .45);
  transform-origin: 50% 100%;
  transform: translateY(calc(var(--n) * 12px)) scale(calc(1 - var(--n) * .05));
  transition: transform var(--dur-slow) var(--ease-soft-spring), opacity var(--dur-base) var(--ease-out);
}
.st-card:not(.st-card--top) { pointer-events: none; }
.st-card:not(.st-card--top) .st-photo::after { content: ""; position: absolute; inset: 0; background: var(--bg); opacity: calc(var(--n) * .18); }
.st-card--top { cursor: grab; will-change: transform; }
.st-card--top.тянут { cursor: grabbing; transition: none; }
.st-card--top.улетает { transition: transform 320ms var(--ease-in-out), opacity 320ms var(--ease-exit); }
.st-card .st-photo { flex: 1; height: auto; min-height: 0; }
.st-card .st-photo img { -webkit-user-drag: none; pointer-events: none; }
.st-card .st-dish-body { flex: none; }
.st-card .st-dish-body b { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* После голоса колода поднимается на одну ступень; новая нижняя карточка проявляется. */
@keyframes st-deck-up {
  from { transform: translateY(calc((var(--n) + 1) * 12px)) scale(calc(1 - (var(--n) + 1) * .05)); opacity: var(--from-o, 1); }
}
/* backwards, не both: после подъёма анимация не держит transform, иначе он перебивает
   инлайновый transform полёта и смахивания — карточка не улетала, а просто гасла. */
.st-deck.сдвиг .st-card { animation: st-deck-up var(--dur-slow) var(--ease-soft-spring) backwards; }
.st-deck.сдвиг .st-card[style*="--n:2"] { --from-o: 0; }

/* Штампы ответа: проступают по ходу пальца. */
.st-stamp {
  position: absolute; top: 18px; padding: 6px 12px; border: 3px solid; border-radius: var(--r-s);
  background: color-mix(in srgb, var(--card) 88%, transparent);
  font-size: var(--t-lead); font-weight: 800; line-height: 1; letter-spacing: .06em; text-transform: uppercase;
  pointer-events: none;
}
.st-stamp--yes { left: 16px; color: var(--accent); opacity: var(--yes); transform: rotate(-12deg) scale(calc(.85 + var(--yes) * .15)); }
.st-stamp--no { right: 16px; color: var(--no); opacity: var(--nope); transform: rotate(12deg) scale(calc(.85 + var(--nope) * .15)); }

/* Три круглые кнопки: «Не хочу» и «Нравится» крупные, «Пропустить» поменьше между ними. */
.st-vote { display: flex; justify-content: center; align-items: flex-start; gap: 22px; margin-top: 10px; }
.st-vote-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 72px; padding: 0; border: 0; background: none;
  color: var(--hint); font-family: inherit; font-size: var(--t-label); font-weight: 600; cursor: pointer;
}
.st-vote-ico {
  width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--card); box-shadow: inset 0 0 0 1.5px var(--line);
  transition: transform var(--dur-base) var(--ease-spring), background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.st-vote-ico svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.st-pass .st-vote-ico { width: 48px; height: 48px; margin-top: 8px; color: var(--hint); }
.st-pass .st-vote-ico svg { width: 22px; height: 22px; }
.st-no .st-vote-ico { color: var(--no); transform: scale(calc(1 + var(--nope) * .14)); }
.st-yes .st-vote-ico { color: var(--accent); transform: scale(calc(1 + var(--yes) * .14)); }
.st-no .st-vote-ico { background: color-mix(in srgb, var(--no-soft) calc(var(--nope) * 100%), var(--card)); }
.st-yes .st-vote-ico { background: color-mix(in srgb, var(--accent) calc(var(--yes) * 100%), var(--card)); }
.st-yes .st-vote-ico svg { fill: color-mix(in srgb, var(--on-accent) calc(var(--yes) * 100%), transparent); }
.st-vote-btn:active .st-vote-ico { transform: scale(.9); transition-duration: var(--dur-press); }
.st-yes:active .st-vote-ico { background: var(--accent); color: var(--on-accent); }
.st-no:active .st-vote-ico { background: var(--no-soft); }

/* Конец колоды: галочка пружинит, от неё расходится кольцо. */
.st-done--taste { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.st-done-mark {
  position: relative; width: 72px; height: 72px; margin-bottom: 8px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: var(--accent); color: var(--on-accent);
  animation: heart-in 520ms var(--ease-spring) both;
}
.st-done-mark svg { width: 34px; height: 34px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 22; animation: ds-draw var(--dur-base) var(--ease-out) 200ms both; }
.st-done-mark::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--accent); animation: heart-ring 600ms var(--ease-out) 120ms both; }
.st-done--taste b, .st-done--taste p { animation: ds-fade-up var(--dur-page) var(--ease-out) 160ms both; }

@media (prefers-reduced-motion: reduce) {
  .st-card { transition: none; }
  .st-deck.сдвиг .st-card, .st-deck-bar span, .st-done-mark, .st-done-mark svg, .st-done-mark::after { animation: none; }
}

/* --- Нижнее меню: светлая плавающая полоса (2026-10-13, дизайн «Меню · сегодня») ------
   Белая полоса над страницей с отступом от краёв, без обводки и тени; фон под ней прозрачный.
   Радиусы проекта: r-l у полосы (как у карточек блюд), r-m у вкладки. Четыре вкладки одной
   ширины, у каждой значок и под ним подпись. Открытый раздел — зелёный на светло-зелёной
   подложке, остальные — hint. Анимаций перехода нет, только отклик на нажатие. */
:root { --nav-bg: var(--card); --nav-ink: var(--hint); }

.tabs-wrap {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 5;
  padding: 28px 12px calc(12px + env(safe-area-inset-bottom));
  pointer-events: none;
  /* Плавная дымка под полосой (2026-10-15): сверху прозрачно, к низу экрана — фон страницы
     почти сплошной, а то, что прокручивается под меню, слегка размыто. Размытие проявляется
     той же растушёвкой, без резкой границы. */
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--bg) 0%, transparent) 0%,
    color-mix(in srgb, var(--bg) 55%, transparent) 45%,
    color-mix(in srgb, var(--bg) 85%, transparent) 100%);
}
.tabs-wrap::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 60%);
  mask-image: linear-gradient(to bottom, transparent, #000 60%);
}
.tabs-bar {
  position: static; margin: 0 auto; pointer-events: auto;
  max-width: 536px; padding: 6px; gap: 4px; align-items: stretch;
  border-radius: var(--r-l); background: var(--nav-bg); box-shadow: none;
}
.tabs-bar::before { display: none; }
body:has(.tabs-wrap) .page { padding-bottom: calc(104px + env(safe-area-inset-bottom)); }
body:has(.tabs-wrap) .toast:not(.pm-toast) { bottom: calc(96px + env(safe-area-inset-bottom)); }

.tab-item {
  flex: 1 1 0; min-width: 0; padding: 8px 4px;
  flex-direction: column; gap: 4px;
  border-radius: var(--r-m); color: var(--nav-ink); background: transparent;
  font-size: var(--t-label); font-weight: 600; white-space: nowrap;
  transition: transform .12s ease-out;
}
.tab-item svg { width: 22px; height: 22px; flex: none; stroke-width: 2; }
.tab-item .tab-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.tab-item.on { background: color-mix(in srgb, var(--accent) 12%, var(--card)); color: var(--accent); }
.tab-item:active { transform: scale(.97); }

/* Число «сколько купить» — на значке, с белой обводкой под цвет полосы. */
.tab-badge { top: -6px; left: 13px; box-shadow: 0 0 0 2px var(--nav-bg); }
/* В открытых «Продуктах» число не нужно — список перед глазами. */
.tab-item.on .tab-badge { display: none; }

/* --- Иерархия шрифтов экрана «Меню» (2026-10-13) -----------------------------------
   Четыре ступени, разница — размером и цветом, жирный только у главного:
   1 заголовок экрана 26/700 · 2 название блюда 18/600 (то, что ищет глаз) ·
   3 салат 16/500 · 4 подписи 14 и 12 в hint. */
.pm-range { font-weight: 500; }
.pm-n { font-weight: 600; }
.pm-day.on .pm-n { font-weight: 700; }
.pm-meal-head { margin-bottom: 6px; }
.pm-meal-name { color: var(--hint); font-weight: 400; }
.pm-meal-kcal { font-size: var(--t-label); font-weight: 400; }
.pm-dish:not(.pm-salad) .pm-dish-text b { font-size: var(--t-lead); font-weight: 600; line-height: 1.25; }
.pm-salad .pm-dish-text b { font-size: var(--t-body); font-weight: 500; }
.pm-empty { font-weight: 500; }
.pm-norm-top b { font-weight: 600; }
.pm-norm-top .pm-norm-bju { font-weight: 500; }
.tab-item { font-weight: 500; }
.tab-item.on { font-weight: 600; }

/* Шапка и ряд дней ближе друг к другу (2026-10-13): было 16 + 12 px пустоты, стало 4. */
.pm-top .hd-tab { margin-bottom: 0; }
.pm-top + .pm-days { padding-top: 4px; }

/* «Добавить салат…» — обычным весом, как на макете (2026-10-13). */
.pm-add-salad { font-weight: 400; }

/* --- Анкета: живее (2026-10-13) ------------------------------------------------------
   Значок шага, стол с тарелками, галочки в чипах, заливка отрезка прогресса, выпрыгивающие
   клетки недели и финальный экран «Собираем ваше меню». Движение — на переменных motion. */

/* Значок шага: круг 56 в цвете приёма пищи; при смене шага пружинит, линии прорисовываются. */
.pm-meal-ico.st-emblem { width: 56px; height: 56px; margin: 0 0 14px; border-radius: 50%; }
.st-emblem svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.st-emblem.fresh { animation: heart-in 520ms var(--ease-spring) both; }
.st-emblem.fresh svg * { stroke-dasharray: 1; stroke-dashoffset: 1; animation: st-draw 700ms var(--ease-out) 160ms forwards; }
@keyframes st-draw { to { stroke-dashoffset: 0; } }

/* Отрезок пройденного шага заливается слева направо. */
.st-seg span.растёт {
  background: linear-gradient(var(--accent), var(--accent)) left / 0% 100% no-repeat, var(--line);
  animation: st-seg-fill 520ms var(--ease-out) 120ms forwards;
}
@keyframes st-seg-fill { to { background-size: 100% 100%; } }

/* Стол: круглая столешница и тарелки по кругу — по одной на каждого. */
.st-table { position: relative; width: 196px; height: 196px; margin: 0 auto -6px; }
.st-table-top { position: absolute; inset: 50px; border-radius: 50%; background: var(--tile); }
.st-plate {
  position: absolute; left: 50%; top: 50%; width: 32px; height: 32px; margin: -16px 0 0 -16px; border-radius: 50%;
  background: var(--card); box-shadow: 0 0 0 1.5px var(--line), inset 0 0 0 7px var(--card), inset 0 0 0 8.5px var(--line);
  transform: rotate(var(--a)) translateY(-78px);
  transition: transform var(--dur-slow) var(--ease-soft-spring);
}
.st-plate.появилась { animation: st-plate-in 460ms var(--ease-spring) both; animation-delay: calc(var(--k, 0) * 45ms); }
@keyframes st-plate-in { from { opacity: 0; scale: .2; } }

/* Чип выбран — слева проявляется галочка; у только что нажатого она пружинит. */
.st-chip.on::before {
  content: ""; display: inline-block; width: 14px; height: 14px; margin: 0 6px 0 -4px; vertical-align: -2px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='5 12 10 17 19 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='5 12 10 17 19 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.st-chip.on.just::before { animation: st-check-in var(--dur-base) var(--ease-spring) both; }
@keyframes st-check-in { from { width: 0; margin-right: 0; opacity: 0; scale: .3; } }

/* Сетка недели: зажжённая сейчас клетка выпрыгивает. */
.st-cell > span.появилась { animation: ds-pop var(--dur-base) var(--ease-spring); }

/* Финал: «Собираем ваше меню» — тарелка с бегущим ободком и строки, что учтено. */
.st-final {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  padding: calc(24px + var(--safe-top, 0px)) 24px calc(24px + env(safe-area-inset-bottom));
  background: var(--bg); animation: ds-fade-up var(--dur-page) var(--ease-out) both;
}
.st-final-in { width: 100%; max-width: 360px; }
.st-final h2 { margin: 18px 0 16px; font-size: var(--t-title); line-height: 1.15; font-weight: 700; letter-spacing: -.01em; color: var(--fg); }
.st-final-plate {
  position: relative; display: block; width: 64px; height: 64px; border-radius: 50%;
  background: var(--card); box-shadow: inset 0 0 0 1.5px var(--line);
}
.st-final-plate::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%;
  border: 3px solid transparent; border-top-color: var(--accent); border-right-color: var(--accent);
  animation: st-spin 1.1s linear infinite;
}
.st-final-plate span { position: absolute; inset: 14px; border-radius: 50%; background: var(--tile); }
@keyframes st-spin { to { transform: rotate(360deg); } }
.st-final ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.st-final li {
  display: flex; align-items: center; gap: 12px; font-size: var(--t-body); line-height: 1.35; color: var(--fg);
  animation: ds-fade-up var(--dur-page) var(--ease-out) both; animation-delay: calc(300ms + var(--k) * 380ms);
}
.st-final-tick {
  flex: none; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--on-accent);
  animation: heart-in 420ms var(--ease-spring) both; animation-delay: calc(380ms + var(--k) * 380ms);
}
.st-final-tick svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1; animation: st-draw 300ms var(--ease-out) forwards; animation-delay: calc(480ms + var(--k) * 380ms); }

@media (prefers-reduced-motion: reduce) {
  .st-emblem.fresh, .st-plate.появилась, .st-cell > span.появилась, .st-chip.on.just::before, .st-final, .st-final li, .st-final-tick { animation: none; }
  .st-emblem.fresh svg *, .st-final-tick svg { animation: none; stroke-dashoffset: 0; }
  .st-seg span.растёт { animation: none; background: var(--accent); }
  .st-plate { transition: none; }
  .st-final-plate::before { animation-duration: 3s; }
}

/* --- Анкета: «о себе» и «кто ещё ест» без клавиатуры (2026-10-14) ----------------------
   Пол — две плитки; выбор ставит типичные значения, их двигают ползунком и ± по одному.
   Активность — сетка 2×2, внизу сразу норма. У человека за столом — имя и аллергии на виду,
   «не ест» и норма раскрываются. */
.st-sexes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.st-sex {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 88px; border: 1px solid var(--line); border-radius: var(--r-l); background: var(--card);
  color: var(--fg); font: 600 var(--t-body)/1.2 inherit; cursor: pointer;
}
.st-sex-mark { font-size: var(--t-head); line-height: 1; color: var(--hint); }
.st-sex.on { border-color: var(--sel-line); background: var(--sel-soft); box-shadow: inset 0 0 0 1px var(--sel-line); }
.st-sex.on .st-sex-mark { color: var(--accent); }

.st-slides { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; padding: 16px; border-radius: var(--r-l); background: var(--card); }
.st-slide-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: var(--t-meta); color: var(--hint); }
.st-slide-val { display: flex; align-items: center; gap: 6px; }
.st-slide-val b { min-width: 72px; text-align: center; font-size: var(--t-lead); color: var(--fg); font-variant-numeric: tabular-nums; }
.st-tick {
  width: 32px; height: 32px; border: 0; border-radius: var(--r-pill); background: var(--tile); color: var(--fg);
  font: 600 var(--t-lead)/1 inherit; cursor: pointer;
}
.st-slide input[type=range] { width: 100%; margin: 8px 0 0; accent-color: var(--accent); height: 28px; }

.st-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.st-act {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-height: 76px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r-m); background: var(--card); color: var(--fg); text-align: left; cursor: pointer;
}
.st-act b { font-size: var(--t-meta); font-weight: 700; }
.st-act span { font-size: var(--t-label); line-height: 1.3; color: var(--hint); }
.st-act.on { border-color: var(--sel-line); background: var(--sel-soft); box-shadow: inset 0 0 0 1px var(--sel-line); }

.st-norm:empty { display: none; }
.st-norm { margin: 14px 0 0; padding: 14px 16px; border-radius: var(--r-m); background: var(--sel-soft); color: var(--fg); font-size: var(--t-body); text-align: center; }
.st-norm b { font-size: var(--t-head); color: var(--accent); }

.st-eater-head { display: flex; align-items: center; gap: 10px; }
.st-eater-num {
  flex: none; width: var(--h-tap); height: var(--h-tap); border-radius: var(--r-pill); background: var(--tile);
  display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--hint);
}
.st-name {
  flex: 1; min-width: 0; height: var(--h-input); padding: 0 14px; border: 1px solid var(--line); border-radius: var(--r-s);
  background: var(--bg); color: var(--fg); font-size: var(--t-body);
}
.st-mini { margin: 14px 0 8px; font-size: var(--t-label); font-weight: 700; color: var(--hint); text-transform: uppercase; letter-spacing: .06em; }
.st-chips-sm { gap: 6px; }
.st-chips-sm .st-chip { min-height: 36px; padding: 0 12px; font-size: var(--t-meta); }
.st-adds { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.st-add {
  min-height: var(--h-chip); padding: 0 14px; border: 1px dashed var(--line); border-radius: var(--r-pill);
  background: transparent; color: var(--accent); font: 600 var(--t-meta)/1 inherit; cursor: pointer;
}
/* Внутри карточки человека вложенные плашки — на фоне страницы, иначе белое сливается с белым. */
.st-eater :is(.st-slides, .st-sex, .st-act) { background: var(--bg); }
.st-eater .st-sex.on, .st-eater .st-act.on { background: var(--sel-soft); }

/* --- Анкета: возраст, рост, вес — плитки и линейка (2026-10-14) -----------------------
   Три плитки-переключателя (что указываем) и одна линейка под ними: крупное число, шкала
   с делениями, зелёная стрелка посередине. Шкалу листают пальцем, она встаёт на деление. */
.st-measure { margin-top: 16px; padding: 12px 12px 16px; border-radius: var(--r-l); background: var(--card); }
.st-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; border-radius: var(--r-m); background: var(--tile); }
.st-metric {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 4px; border: 0; border-radius: var(--r-s);
  background: transparent; color: var(--hint); font-family: inherit; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-base) var(--ease-spring);
}
.st-metric > span { font-size: var(--t-label); font-weight: 600; }
.st-metric b { font-size: var(--t-body); font-weight: 700; color: var(--fg); font-variant-numeric: tabular-nums; }
.st-metric i { margin-left: 3px; font-size: var(--t-label); font-style: normal; font-weight: 500; color: var(--hint); }
.st-metric.on { background: var(--card); color: var(--accent); box-shadow: 0 1px 3px rgba(28, 27, 25, .14); }
.st-metric:active { transform: scale(.96); transition-duration: var(--dur-press); }

.st-ruler-val { margin: 18px 0 6px; text-align: center; font-size: var(--t-body); font-weight: 600; color: var(--hint); }
.st-ruler-val b {
  font-size: var(--t-display); line-height: 1; font-weight: 700; letter-spacing: -.02em; color: var(--fg); font-variant-numeric: tabular-nums;
}
.st-ruler-wrap { position: relative; margin: 0 -12px; }
.st-ruler {
  overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 24%, #000 76%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 24%, #000 76%, transparent);
  cursor: grab; outline: none; touch-action: pan-x;
}
.st-ruler::-webkit-scrollbar { display: none; }
.st-ruler-track { display: flex; width: max-content; height: 62px; padding: 0 calc(50% - 5px); }
.st-ruler-track > span { position: relative; flex: none; width: 10px; height: 100%; scroll-snap-align: center; cursor: pointer; }
.st-ruler-track > span::before {
  content: ""; position: absolute; top: 6px; left: 50%; width: 2px; height: 12px; margin-left: -1px; border-radius: 1px;
  background: color-mix(in srgb, var(--hint) 35%, transparent);
}
.st-ruler-track > span.d5::before { height: 20px; background: color-mix(in srgb, var(--hint) 60%, transparent); }
.st-ruler-track > span.d10::before { height: 28px; background: var(--hint); }
.st-ruler-track > span.d10::after {
  content: attr(data-v); position: absolute; top: 40px; left: 50%; transform: translateX(-50%);
  font-size: var(--t-label); font-weight: 600; color: var(--hint); font-variant-numeric: tabular-nums;
}
.st-ruler-needle {
  position: absolute; top: 0; left: 50%; width: 4px; height: 38px; margin-left: -2px; border-radius: var(--r-pill);
  background: var(--accent); pointer-events: none;
}
.st-ruler-needle::before {
  content: ""; position: absolute; top: -7px; left: 50%; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%; background: var(--accent);
}
.st-ruler:focus-visible + .st-ruler-needle { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }
/* Сменили меру — число и шкала проявляются. */
.st-metric.just { animation: ds-pop var(--dur-base) var(--ease-spring); }
.st-eater .st-measure { background: var(--bg); }
.st-eater .st-metric.on { background: var(--card); }

/* --- Тени: три уровня высоты (2026-10-14, дизайн-система «Elevation») -------------------
   Фон кремовый, карточки белые — по яркости они почти равны (1,08:1), и граница карточки
   теряется. Поэтому: 0 — плоско (чипы, плашки на tile, поля, строки внутри карточки);
   1 — лежит на странице (карточки, списки, итоги); 2 — парит (плашка «Отменить», верхняя
   карточка колоды). Тень тёплая — цвет fg, не чёрный; две тени: короткая даёт контур,
   длинная — объём. Внутри карточки белое на белом делит линия, а не тень. */
:root {
  --shadow-1: 0 1px 2px rgba(28, 27, 25, .06), 0 2px 8px -2px rgba(28, 27, 25, .06);
  --shadow-2: 0 10px 28px -12px rgba(28, 27, 25, .28), 0 2px 6px -2px rgba(28, 27, 25, .10);
}
:is(.pm-dish, .pm-stats, .pm-norm, .pm-sum, .pm-shop-list, .pm-wk-day, .pm-ask, .pm-empty-card, .pm-range,
    .saved-card, .cat, .prof-rows, .st-measure, .st-week, .st-sex, .st-act, .st-meal, .st-vote-ico,
    .dish-tile a, .dish-tile button) { box-shadow: var(--shadow-1); }
/* Состояния, которые рисуют обводку тенью, держат и уровень. */
.pm-dish.bad { box-shadow: inset 0 0 0 1.5px var(--no-line), var(--shadow-1); }
.pm-wk-day.today { box-shadow: inset 0 0 0 2px var(--accent), var(--shadow-1); }
:is(.st-meal, .st-sex, .st-act).on { box-shadow: inset 0 0 0 1px var(--sel-line), var(--shadow-1); }
.st-vote-ico { box-shadow: inset 0 0 0 1.5px var(--line), var(--shadow-1); }
/* Карточки внутри карточки человека — на фоне страницы, без тени: они уже на белом. */
.st-eater :is(.st-measure, .st-sex, .st-act) { box-shadow: none; }
.st-eater :is(.st-sex, .st-act).on { box-shadow: inset 0 0 0 1px var(--sel-line); }
/* Нажатие: карточка «вдавливается» — тень на ступень ниже. */
:is(.pm-dish:has(.pm-dish-link:active), .dish-tile a:active, .dish-tile button:active, .cat:active, .pm-wk-day:active) { box-shadow: 0 1px 1px rgba(28, 27, 25, .05); }
/* Уровень 2: парят над страницей. */
.toast { box-shadow: var(--shadow-2); }
.st-card { box-shadow: 0 0 0 1px var(--line), var(--shadow-1); }
.st-card--top { box-shadow: 0 0 0 1px var(--line), var(--shadow-2); }
.pm-seg-pill, .st-metric.on { box-shadow: var(--shadow-1); }

/* --- Меню: карточка недели и польза блюд (дизайн «Меню · как в проекте», 2026-10-14) ---
   Сверху — «Настроить меню» (порции на зелёном значке) и «Качества недели» (стопка квадратов),
   под ними дни: фото ужина в кружке, салат на его краю, пунктир — ужин не выбран.
   Выбранный день — мягкая зелёная подложка, без тёмной таблетки. */
:root {
  --perk-energy: #c27c1a; --perk-protein: #c4573b; --perk-calcium: #4f6fb5;
  --perk-fiber: #2f8a4c; --perk-iron: #b0466b;
}
.wc { margin-top: 12px; padding: 8px; border-radius: var(--r-l); background: var(--card); box-shadow: var(--shadow-1); }
.wc-row { display: flex; gap: 8px; }
.wc-setup, .wc-perks {
  display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 12px;
  border: 0; border-radius: var(--r-m); background: var(--card); box-shadow: inset 0 0 0 1px var(--line);
  color: var(--fg); font: inherit; text-decoration: none; cursor: pointer;
}
.wc-setup { flex: 1 1 auto; min-width: 0; }
.wc-ic { display: flex; color: var(--fg); }
.wc-setup-t { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wc-badge {
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--on-accent); font-size: 12px; font-weight: 600;
}
.wc-chev { display: flex; color: var(--hint); margin-right: -4px; }
.wc-perks { flex: none; padding: 0 14px 0 10px; }
.wc-perks b { font-size: 16px; font-weight: 600; }
.wc-stack { display: flex; }
.wk-sq {
  width: 26px; height: 26px; border-radius: var(--r-xs); display: flex; align-items: center; justify-content: center;
  color: #fff; box-shadow: 0 0 0 2px var(--card);
}
.wk-sq + .wk-sq { margin-left: -12px; }
.wk-sq svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.wk-sq.energy { background: var(--perk-energy); } .wk-sq.protein { background: var(--perk-protein); }
.wk-sq.calcium { background: var(--perk-calcium); } .wk-sq.fiber { background: var(--perk-fiber); }
.wk-sq.iron { background: var(--perk-iron); }

.wc-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-top: 8px; }
.wc-day {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px 0 5px;
  border: 0; border-radius: var(--r-m); background: none; font: inherit; color: var(--fg); cursor: pointer;
  transition: background .2s, color .2s;
}
.wc-day.on { background: color-mix(in srgb, var(--accent) 12%, var(--card)); color: var(--accent); }
.wc-wd { font-size: 12px; font-weight: 500; color: var(--hint); line-height: 16px; }
.wc-day.on .wc-wd { color: var(--accent); }
.wc-plate { position: relative; width: 38px; height: 38px; }
.wc-dish { width: 38px; height: 38px; border-radius: var(--r-xs); }
.wc-none { display: block; width: 38px; height: 38px; border-radius: var(--r-xs); box-sizing: border-box; border: 1.5px dashed var(--line); }
.wc-salad { position: absolute; right: -5px; bottom: -3px; width: 18px; height: 18px; border-radius: calc(var(--r-xs) / 2); box-shadow: 0 0 0 2px var(--card); }
.wc-day.on .wc-salad { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 12%, var(--card)); }
.wc-n { font-size: 16px; font-weight: 600; line-height: 20px; }
.wc-day.on .wc-n { font-weight: 700; }
.wc + .pm-pane { margin-top: 4px; }

/* Польза на карточке блюда: квадраты 16px с белой иконкой в одну строку и подпись «Железо и ещё 2». */
.perk-row { display: flex; align-items: center; gap: 3px; margin-top: 2px; overflow: hidden; white-space: nowrap; }
.perk { flex: none; display: flex; }
.perk svg {
  box-sizing: border-box; width: 16px; height: 16px; padding: 2.5px; border-radius: 5px;
  fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round;
}
.perk.energy svg { background: var(--perk-energy); } .perk.protein svg { background: var(--perk-protein); }
.perk.calcium svg { background: var(--perk-calcium); } .perk.fiber svg { background: var(--perk-fiber); }
.perk.iron svg { background: var(--perk-iron); }
.perk-name { flex: 0 1 auto; min-width: 0; margin-left: 4px; overflow: hidden; text-overflow: ellipsis; font-size: 12px; font-weight: 500; line-height: 16px; color: var(--hint); }

/* Фото основного блюда крупнее — в карточке стало на строку больше; салат остаётся 48px. */
.pm-dish:not(.pm-salad) .pm-thumb { width: 84px; height: 84px; border-radius: var(--r-m); }
.pm-dish:not(.pm-salad) .pm-dish-link { gap: 14px; }

/* --- Страница блюда — аккуратный вариант (2026-10-15, холст «Рецепт · аккуратный вариант») ---
   Фото сверху с «назад» и сердцем поверх; приём цветной меткой; факты и БЖУ — одной белой
   карточкой; аллергены и покупки — карточкой со значками; продукты и «Как готовить» — тоже
   карточками. Нижняя панель — белая плавающая полоса над дымкой, как нижнее меню разделов. */
.rv-hero { position: relative; }
.rv-hero .sh-cover { height: 264px; margin: 0; }
.rv-hero .hd-nav {
  position: absolute; top: 12px; left: 12px; right: 12px; z-index: 2;
  margin: 0; padding: 0; background: transparent; box-shadow: none;
}
.rv-hero .hd-title { display: none; }
.rv-hero :is(.hd-btn, .heart) { background: rgba(255, 255, 255, .92); box-shadow: 0 1px 3px rgba(28, 27, 25, .12); }
.rv-hero .heart.on { background: var(--no-soft); }

.rv-kind { display: flex; align-items: center; gap: 8px; padding: 0 4px; font-size: var(--t-meta); color: var(--hint); }
.rv-meal {
  display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: var(--r-pill);
  font-size: var(--t-label); font-weight: 600; background: #E4E7EF; color: #4A5878;
}
.rv-meal--breakfast { background: #F6EBD3; color: #9A6B1F; }
.rv-meal--lunch, .rv-meal--salad { background: #E2EDE3; color: #2F6B3F; }
.rv-meal--snack { background: #F2E9E3; color: #A8543D; }
.rv-name { margin: 8px 0 0; padding: 0 4px; font-size: var(--t-title); font-weight: 700; line-height: 1.2; letter-spacing: -.01em; }

.rv-card { display: block; margin: 16px 0 0; border-radius: var(--r-m); background: var(--card); }
.rv-card svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Вариант «без линий»: строка фактов под названием, питание — карточкой без разделителей,
   аллергены — мягкой плашкой, о покупках — тихой строкой. */
.rv-metas { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 10px 0 0; padding: 0 4px; font-size: var(--t-meta); color: var(--hint); }
.rv-meta { display: inline-flex; align-items: center; gap: 6px; }
.rv-meta svg { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.rv-meta b { font-weight: 600; color: var(--fg); }
.rv-nutr { display: flex; align-items: center; gap: 6px; padding: 14px 14px 14px 18px; }
.rv-kcal { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rv-kcal b { font-size: var(--t-title); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.rv-kcal span { font-size: var(--t-label); color: var(--hint); white-space: nowrap; }
.rv-chip { flex: none; min-width: 60px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 6px; border-radius: var(--r-s); background: var(--bg); }
.rv-chip b { font-size: var(--t-body); font-weight: 600; font-variant-numeric: tabular-nums; }
.rv-chip span { font-size: var(--t-label); color: var(--hint); }
.rv-allergy { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0 0; padding: 12px 14px; border-radius: var(--r-m); background: var(--no-soft); color: var(--fg); font-size: var(--t-meta); line-height: 1.4; }
.rv-allergy b { font-weight: 600; }
.rv-allergy svg, .rv-quiet svg { flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.rv-allergy svg { width: 20px; height: 20px; color: var(--no); }
.rv-quiet { display: flex; align-items: center; gap: 8px; margin: 10px 0 0; padding: 0 6px; font-size: var(--t-meta); color: var(--hint); }
.rv-quiet svg { width: 18px; height: 18px; }
.rv-quiet--ok svg { color: var(--accent); }
.rv-nutr + .rv-quiet, .rv-metas + .rv-quiet { margin-top: 16px; }

.rv-need { padding: 12px 16px 4px; }
.rv-need .sec-head { margin: 0; padding: 0 0 8px; }
.rv-need .sec-head h2 { font-weight: 600; }
.rv-need .por { background: var(--tile); }
.rv-need .por button { width: var(--h-tap); height: var(--h-tap); background: var(--card); font-weight: 500; }
.rv-need .ing { border-radius: 0; background: transparent; }
.rv-need .ing li { padding: 13px 0; }
.rv-need .ing b { font-variant-numeric: tabular-nums; white-space: nowrap; }

.rv-steps { display: flex; align-items: center; gap: 12px; padding: 14px 16px; color: var(--fg); text-decoration: none; transition: transform .12s ease-out; }
.rv-steps:active { transform: scale(.98); }
.rv-steps-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rv-steps-text b { font-size: var(--t-body); font-weight: 600; }
.rv-steps-text span { font-size: var(--t-meta); color: var(--hint); }
.rv-steps svg { flex: none; width: 20px; height: 20px; color: var(--hint); }

.bottom.rv-bar {
  padding: 28px 12px calc(12px + env(safe-area-inset-bottom));
  border-top: 0; pointer-events: none;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--bg) 0%, transparent) 0%,
    color-mix(in srgb, var(--bg) 55%, transparent) 45%,
    color-mix(in srgb, var(--bg) 85%, transparent) 100%);
}
.bottom.rv-bar::before {
  display: block; inset: 0; bottom: auto; height: 100%; z-index: -1;
  background: none;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 60%);
  mask-image: linear-gradient(to bottom, transparent, #000 60%);
}
.rv-bar > * { pointer-events: auto; }
.rv-bar :is(.dp-row, .bottom-row) {
  gap: 6px; padding: 6px; border-radius: var(--r-l); background: var(--card);
  box-shadow: 0 1px 3px rgba(28, 27, 25, .06); box-sizing: border-box;
}
.rv-bar .icon-btn svg { width: 22px; height: 22px; stroke-width: 2; }
body:has(.dp-bar.rv-bar) .page { padding-bottom: calc(120px + env(safe-area-inset-bottom)); }

/* Экран шагов: шапка — «назад» и блюдо одной липкой строкой (2026-10-15). */
.ck-nav { display: flex; align-items: center; gap: 12px; margin-bottom: 0; }
.ck-nav .cook-head { flex: 1; min-width: 0; gap: 12px; margin: 0; }
.ck-nav .ck-thumb { width: var(--h-tap); height: var(--h-tap); border-radius: var(--r-xs); margin: 0; }
.ck-nav .ck-text { flex: 1; min-width: 0; }
.ck-nav .ck-name { margin: 0 0 2px; font-size: var(--t-body); font-weight: 600; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-nav .hint { font-size: var(--t-meta); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-nav + .cook-page { padding-top: 0; }

/* --- Калории и баланс дня: «два кольца» и шторка с расшифровкой (2026-10-15) -----------
   Холст «Оценка дня»: два одинаковых кольца (калории — доля нормы, баланс — оценка из 100),
   итог с советами; по нажатию — шторка: показатели, советы с действиями, неделя графиком. */
:root { --bal: #C98A2E; }
.bal-card { padding: 14px 16px 16px; }
.bal-card .pm-norm-who { margin-bottom: 14px; }
.bal-open { display: block; width: 100%; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.bal-pair { display: flex; align-items: center; gap: 16px; }
.bal-m { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
.bal-m-text { min-width: 0; display: flex; flex-direction: column; }
.bal-m-text b { font-size: 15px; font-weight: 600; }
.bal-m-text span { font-size: var(--t-label); line-height: 1.3; color: var(--hint); font-variant-numeric: tabular-nums; }
.bal-ring { position: relative; flex: none; width: 64px; height: 64px; }
.bal-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.bal-ring circle { fill: none; stroke-width: 6; }
.bal-ring-track { stroke: var(--tile); }
.bal-ring-fill { stroke-linecap: round; transition: stroke-dasharray var(--dur-base, .25s) ease-out; }
.bal-ring b { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.bal-ring--lg { width: 64px; height: 64px; }
.bal-ring--lg b { font-size: 20px; }
.bal-more { display: flex; align-items: center; gap: 6px; margin-top: 14px; font-size: var(--t-meta); color: var(--hint); }
.bal-more b { color: var(--accent); font-weight: 600; }
.bal-more .pm-ic { margin-left: auto; flex: none; color: var(--accent); }
.bal-open:active .bal-pair { transform: scale(.99); }

html.bs-open, html.bs-open body { overflow: hidden; }
.bs-wrap { position: fixed; inset: 0; z-index: 60; }
.bs-dim { position: absolute; inset: 0; background: rgba(28, 27, 25, .38); opacity: 0; transition: opacity .25s ease-out; }
.bs-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; max-width: 560px; max-height: calc(100dvh - 24px - var(--safe-top, 0px)); margin: 0 auto;
  display: flex; flex-direction: column; border-radius: 24px 24px 0 0; background: var(--card);
  transform: translateY(100%); transition: transform .26s cubic-bezier(.2, .8, .2, 1);
}
.bs-wrap.on .bs-dim { opacity: 1; }
.bs-wrap.on .bs-sheet { transform: none; }
.bs-handle { align-self: center; flex: none; width: 40px; height: 4px; margin: 8px 0 4px; border-radius: var(--r-pill); background: var(--line); }
.bs-body { overflow-y: auto; overscroll-behavior: contain; padding: 4px 16px calc(24px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 16px; }
.bs-body svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.bs-body .bal-ring circle { stroke-width: 6; }
.bs-head { display: flex; align-items: center; gap: 14px; }
.bs-head-text { flex: 1; min-width: 0; }
.bs-head-text h2 { margin: 0; font-size: var(--t-head); font-weight: 700; }
.bs-head-text p { margin: 2px 0 0; font-size: var(--t-meta); color: var(--hint); }
.bs-close { flex: none; width: var(--h-tap); height: var(--h-tap); border: 0; border-radius: 50%; background: var(--tile); color: var(--fg); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.bs-head--week .bs-head-text { text-align: center; }
.bs-link { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: 0; border-radius: var(--r-m); background: var(--bg); color: var(--fg); font: 600 15px/1.3 inherit; text-align: left; cursor: pointer; }
.bs-link > svg:first-child { flex: none; color: var(--accent); }
.bs-link > span { flex: 1; min-width: 0; }
.bs-link .pm-ic { flex: none; color: var(--hint); }
.bs-link--day > span { display: flex; flex-direction: column; gap: 2px; }
.bs-link--day > span span { font-size: var(--t-meta); font-weight: 400; color: var(--hint); }
.bs-row { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; }
.bs-row + .bs-row { border-top: 1px solid var(--tile); }
.bs-row-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bs-row-top b { font-size: var(--t-body); font-weight: 600; }
.bs-chip { flex: none; display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--r-pill); font-size: var(--t-label); font-weight: 600; }
.bs-chip.ok { background: #E2EDE3; color: var(--accent); }
.bs-chip.mid { background: #F6EBD3; color: #7A5416; }
.bs-chip.bad { background: var(--no-soft); color: var(--no); }
.bs-bar { height: 6px; border-radius: var(--r-pill); background: var(--tile); overflow: hidden; }
.bs-bar span { display: block; height: 100%; border-radius: var(--r-pill); }
.bs-bar .ok { background: var(--accent); }
.bs-bar .mid { background: var(--bal); }
.bs-bar .bad { background: var(--no); }
.bs-val { font-size: var(--t-meta); color: var(--hint); font-variant-numeric: tabular-nums; }
.bs-sub { margin: 0; font-size: var(--t-body); font-weight: 600; }
.bs-tips { display: flex; flex-direction: column; gap: 8px; margin-top: -8px; }
.bs-tip { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: var(--r-m); background: var(--bg); }
.bs-tip-ic.pm-meal-ico { width: 40px; height: 40px; }
.bs-tip-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bs-tip-t b { font-size: 15px; font-weight: 600; line-height: 1.3; }
.bs-tip-t > span { font-size: var(--t-label); color: var(--hint); line-height: 1.35; }
.bs-act { flex: none; display: inline-flex; align-items: center; height: 40px; padding: 0 14px; border-radius: var(--r-s); background: var(--card); color: var(--fg); font-size: var(--t-meta); font-weight: 600; text-decoration: none; }
.bs-act.main { background: var(--accent); color: var(--on-accent); }
.bs-good { margin: 0; font-size: var(--t-meta); color: var(--accent); }
.bs-foot { margin: 0; font-size: var(--t-label); line-height: 1.4; color: var(--hint); }
.bs-chart { padding: 4px 0 0; }
.bs-plot { position: relative; height: 180px; }
.bs-grid { position: absolute; left: 0; right: 0; border-top: 1px solid var(--tile); }
.bs-grid--goal { border-top: 1px dashed #B9CFBD; }
.bs-grid--base { border-color: var(--line); }
.bs-glab { position: absolute; right: 0; transform: translateY(-100%); padding-bottom: 2px; font-size: 11px; color: var(--hint); }
.bs-glab--goal { color: var(--accent); }
.bs-cols { position: absolute; top: 0; bottom: 0; left: 0; right: 34px; display: flex; gap: 4px; }
.bs-col { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 4px; padding: 0; border: 0; background: transparent; font: inherit; color: inherit; cursor: pointer; }
.bs-col.empty { cursor: default; }
.bs-colbar { width: 28px; max-width: 100%; border-radius: 4px 4px 0 0; background: #B9CFBD; }
.bs-col.on .bs-colbar { background: var(--accent); }
.bs-colv { font-size: var(--t-label); font-weight: 600; font-variant-numeric: tabular-nums; visibility: hidden; }
.bs-col.on .bs-colv { visibility: visible; }
.bs-days { display: flex; gap: 4px; margin-top: 8px; padding-right: 34px; }
.bs-days span { flex: 1; text-align: center; font-size: var(--t-label); font-weight: 600; color: var(--hint); }
.bs-days span.on { color: var(--accent); }
.bs-days span.empty { opacity: .5; }
.bs-weak { background: var(--bg); }
.bs-dots { display: flex; gap: 3px; margin-top: 4px; }
.bs-dots i { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--tile); }
.bs-dots i.bad { background: var(--no); }
.bs-dots i.none { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
@media (prefers-reduced-motion: reduce) { .bs-sheet, .bs-dim, .bal-ring-fill { transition: none; } }
