/* Шрифты подключены в <head> index.html через preconnect + link, а не здесь
   через @import. Причина измерена: @import грузится только после разбора CSS,
   то есть на один круг позже, и текст успевает отрисоваться системным шрифтом,
   а потом подменяется — это и давало сдвиг макета. */

/* Визуальный язык — ../DESIGN.md, доказательная база — ../RESEARCH.md.
   Правила ниже расставлены не по вкусу, а по названным признакам шаблонности
   из impeccable.style (Пол Бакаус) и скилла frontend-design у Anthropic. */

:root {
  /* Inter, Space Grotesk, Geist, Instrument Serif, Poppins, Montserrat названы
     переиспользованными — их здесь нет намеренно.
     Отдельная ловушка: западные списки «шрифтов 2026» почти все без кириллицы.
     Bricolage Grotesque и Satoshi пришлось снять именно поэтому — заголовки
     молча падали на Georgia, и это не было видно, пока не замерил ширину строки.
     Unbounded и Onest кириллицу поддерживают и в списках переиспользованных
     не значатся. */
  --font-display: 'Unbounded', Georgia, serif;
  --font-body: 'Onest', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  --bg: #0b0d09;
  --bg-raised: #14170f;
  --bg-sunken: #070903;

  /* Один доминирующий цвет и один резкий акцент — вместо трёхточечного
     градиента. Фиолет убран из основной палитры: violet-градиент назван
     самым надёжным признаком AI-генерации в 2026 сразу двумя источниками.
     Он остаётся только там, где кодирует смысл — верхний уровень новизны. */
  --lime: #c6f432;
  --lime-deep: #8fae1c;
  --clay: #d96e3c;
  --mint: #7be38a;
  --violet: #9b6bd8;

  --ink: #f4f6ee;
  --ink-soft: #9ba394;
  /* Приглушённый текст. Был #6b7264 — 4.02 к вдавленному фону и 3.64
     к поднятому, то есть ниже нормы WCAG AA (4.5) для мелкого текста.
     Lighthouse ловил это на счётчиках в опроснике, но цвет системный,
     и тускло было везде — от подписей осей до метаданных заведений.
     #7b8374 даёт 5.09 и 4.61: норма выполняется на обоих фонах,
     а приглушённость на глаз сохраняется. */
  --ink-dim: #7b8374;
  --line: rgba(244, 246, 238, 0.1);
  --line-accent: rgba(198, 244, 50, 0.26);
  --good: #7be38a;
  --bad: #e8705f;

  /* Радиусы разные по назначению, а не одно значение на всём.
     Одинаковое скругление везде названо признаком отсутствия иерархии. */
  --r-tile: 6px;
  --r-input: 10px;
  --r-card: 14px;
  --r-pill: 999px;

  /* Ритм отступов неравномерный: одинаковый шаг всюду «делает страницу плоской». */
  --s-tight: 8px;
  --s-base: 16px;
  --s-loose: 28px;
  --s-section: 52px;

  --nav-h: 68px;
}

/* Этап 0 · FOODOS_DESIGN_PROPOSALS + FOODOS-TOKENS-MAP.
   Алиасы --foodos-* поверх существующих переменных — контракт токенов
   запрещает удалять или переименовывать то, что уже есть выше.
   Единственный разрешённый способ ссылаться на эти значения из новых
   Proposal-компонентов — имена ниже, не «сырые» --lime/--bg-raised и т.п. */
:root {
  /* Цвет: 1:1 маппинг на тёмную палитру, без новых значений. */
  --foodos-color-bg: var(--bg);
  --foodos-color-surface: var(--bg-raised);
  --foodos-color-ink: var(--ink);
  --foodos-color-ink-soft: var(--ink-soft);
  --foodos-color-ink-dim: var(--ink-dim);
  /* Контраст --lime на тёмном проверяется визуально на Этапе 1;
     если проиграет — кандидат шафран оформляется отдельным L1 Proposal,
     здесь пока не меняем. */
  --foodos-color-accent: var(--lime);
  --foodos-color-positive: var(--good);
  --foodos-color-line: var(--line);

  /* Типографика: точные алиасы существующих правил, а не новая шкала.
     Каждая строка — то, что уже стоит ниже по файлу:
       display = h1/.panel-title · title = .section-h · head = h2 · body = body.
     Межбуквенное расстояние в шорткат font не входит и остаётся у правил.
     Этап 4 (005): title и head приведены к реальным значениям — раньше
     здесь стояли 1.25 и 17px, которых в файле нет; применение таких токенов
     молча поменяло бы интерлиньяж и размер, а токен обязан быть алиасом. */
  --foodos-type-display: 700 clamp(30px, 8vw, 40px) / 1.03 var(--font-display);
  --foodos-type-title: 600 20px / 1.55 var(--font-display);
  --foodos-type-head: 600 19px / 1.55 var(--font-display);
  --foodos-type-body: 400 15px / 1.55 var(--font-body);
  --foodos-type-caption: 500 12px / 1.3 var(--font-body);

  /* Motion: числа из FOODOS-TOKENS-MAP.md, не «на глаз». */
  --foodos-motion-spring-default: 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
  --foodos-motion-spring-heavy: 300ms cubic-bezier(0.34, 1.3, 0.64, 1);
  --foodos-motion-enter: 240ms cubic-bezier(0.22, 1, 0.36, 1);
  --foodos-motion-fade: 180ms ease-out;
  --foodos-motion-settle: 90ms ease-in-out;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Любое правило display у класса перебивает атрибут hidden, и скрытый раздел
   продолжает рисоваться. Здесь это ловил .levels { display: flex }. */
[hidden] {
  display: none !important;
}

html {
  background: var(--bg);
}

body {
  background: var(--bg);
  color: var(--ink);
  font: var(--foodos-type-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Декоративное радиальное свечение убрано: `radial-gradient background halo`
   и `decorative radial spotlight glow` — два отдельных признака шаблонности
   у Impeccable, и «dark mode with glowing accents» третий.
   Вместо свечения — едва заметная зернистость, которая даёт поверхности
   материальность вместо ощущения пластиковой заливки. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

.shell {
  position: relative;
  z-index: 1;
  max-width: 620px;
  margin: 0 auto;
  padding: 26px 18px calc(var(--nav-h) + 40px);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

button {
  font: inherit;
  cursor: pointer;
  color: inherit;
}

/* ── Нижняя навигация ──────────────────────────────── */
.tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  height: var(--nav-h);
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
  background: rgba(11, 13, 9, 0.88);
  backdrop-filter: blur(20px);
  border-top: 1px solid var(--line);
}

.tabs button {
  flex: 1;
  min-height: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  /* Семь вкладок вместо шести (решение PO 20.08): на 360 px каждая
     получает по 51 px, поэтому подпись мельче и отступы уже. Иконка
     остаётся 20 px — она и опознаётся быстрее подписи. */
  padding: 4px 2px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-dim);
  background: none;
  border: none;
  border-radius: 12px;
  transition: color 0.18s ease;
}

.tabs button::before {
  content: '';
  width: 20px;
  height: 20px;
  background: currentColor;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}

/* Иконки — инлайновые SVG-маски, не эмодзи (бриф §25). */
.tabs button[data-tab='home'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 10.5L12 3l9 7.5V20a1 1 0 01-1 1h-5v-6H9v6H4a1 1 0 01-1-1z'/%3E%3C/svg%3E");
}
.tabs button[data-tab='taste'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l7.5 5.5-2.9 8.9H7.4L4.5 8.5z'/%3E%3Ccircle cx='12' cy='12' r='2.6'/%3E%3C/svg%3E");
}
.tabs button[data-tab='remix'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20V10M4 10a4 4 0 018 0v10M12 10h8M20 10V4M16 20h8'/%3E%3C/svg%3E");
}
/* Сезон — лист: раздел про то, что растёт и созревает сейчас.
   Прежняя булавка осталась от «Города», который стал подразделом. */
.tabs button[data-tab='season'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 20C5 20 3 15 3 11c6 0 9 2 10 5'/%3E%3Cpath d='M13 20c6 0 8-5 8-9-6 0-9 2-10 5'/%3E%3Cpath d='M12 20v-6'/%3E%3C/svg%3E");
}

.tabs button[data-tab='city'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 6-9 12-9 12s-9-6-9-12a9 9 0 0118 0z'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
.tabs button[data-tab='kitchen'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 3v7a3 3 0 003 3v8M7 3v6M4 3v6M17 3c-2 0-3 2-3 5s1 4 3 4v9'/%3E%3C/svg%3E");
}
/* Свои рецепты — раскрытая тетрадь: не «плюс» и не «звезда», а именно
   то, чем раздел является. */
.tabs button[data-tab='recipes'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 5a2 2 0 012-2h5v18H6a2 2 0 01-2-2z'/%3E%3Cpath d='M20 5a2 2 0 00-2-2h-5v18h5a2 2 0 002-2z'/%3E%3Cpath d='M8 8h1M15 8h1'/%3E%3C/svg%3E");
}

.tabs button[data-tab='trends'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 17l6-6 4 4 8-8'/%3E%3Cpath d='M15 7h6v6'/%3E%3C/svg%3E");
}
/* Бар — коктейльный бокал: единственная фигура, которую здесь ни с чем
   не спутать. */
.tabs button[data-tab='bar'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16l-8 8z'/%3E%3Cpath d='M12 12v7M8 21h8'/%3E%3C/svg%3E");
}

.tabs button[data-tab='habits'] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 17l5-6 4 4 5-8 4 5'/%3E%3C/svg%3E");
}

.tabs button.active {
  color: var(--lime);
}

/* Ремикс — центральное действие: до создания должен быть один тап, а не поиск
   нужной вкладки (бриф §20). Выделяем его не подложкой, а самим глифом —
   он единственный залит градиентом и потому читается как главная кнопка. */
/* Центральная вкладка крупнее остальных, но не подсвечена акцентом:
   раньше лайм горел на ней всегда, и на экране оказывалось два акцента
   сразу — активная вкладка и эта. Приоритет иконки теперь задаётся
   размером, а цвет остаётся признаком «вы здесь». */
.tabs button.center::before {
  width: 26px;
  height: 26px;
}

.tabs button.center {
  color: var(--ink-soft);
}

.tabs button.center.active {
  color: var(--lime);
}

/* Лента приходит асинхронно, и до её появления страница была пустой —
   отсюда прыжок макета на 0.42 CLS: заголовок уезжал вверх, когда
   подгружался герой. Резервируем высоту заранее. */
#home-feed:empty {
  min-height: 70vh;
}

/* Подвал скрыт, пока идёт первый рендер: он последний в потоке, и его
   появление наверху с последующим уездом вниз давало весь CLS страницы.
   Скрытого элемента в потоке нет, а ниже него ничего не стоит — поэтому
   его появление уже ничего не двигает. См. inline-скрипт в index.html. */
.booting .foot {
  display: none;
}

/* Пометка устаревших данных: не красная тревога, но и не сноска петитом —
   человек должен её прочитать до того, как поверит списку. */
.stale-note {
  margin-bottom: 12px;
  padding: 10px 12px;
  border-left: 2px solid var(--lime);
  border-radius: 0 8px 8px 0;
  background: var(--bg-sunken);
}

/* Подменю внутри вкладки. Горизонтальный ряд под шапкой: у человека
   на мобильном нет места на второй уровень навигации внизу, а сверху
   он читается как продолжение заголовка. */
.subtabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  margin: 0 -20px 4px;
  padding: 0 20px 10px;
  scrollbar-width: none;
}

.subtabs::-webkit-scrollbar {
  display: none;
}

.subtabs button {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 16px;
  font: inherit;
  font-size: 14px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.subtabs button.active {
  background: var(--lime);
  border-color: var(--lime);
  color: #0b0d09;
  font-weight: 500;
}

/* Подборка топ-50: свёрнута, потому что их девять и разворачивать все сразу
   значит показать простыню из четырёхсот строк. */
.top-block {
  margin-bottom: 10px;
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.top-block summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  cursor: pointer;
}

/* Картинка приёма. Квадрат: на схемах важна вся композиция — руки, инструмент
   и продукт, — и кадрировать её нельзя, как и схему состава. */
.tech-photo {
  display: block;
  width: 100%;
  max-width: 340px;
  aspect-ratio: 1 / 1;
  margin: 0 0 12px;
  object-fit: contain;
  border-radius: var(--r-inner, 12px);
  background: var(--bg-sunken);
}

/* Отмеченная утварь: свёрнута, чтобы не мешать отмечать остальное,
   но доступна — отметку надо уметь снять. */
.kit-marked {
  margin-top: 14px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

.kit-marked summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
}

.kit-marked[open] summary {
  margin-bottom: 10px;
}

/* ── Сезон и разделы каталога ────────────────────────
   Список блюд, по которому человек идёт глазами: имя крупно, кухня и время
   мельче и приглушённее. Строки — кнопки: тап открывает разбор. */
.season-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0;
}

.season-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 52px;
  padding: 10px 14px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.season-item b {
  font-size: 15px;
  font-weight: 500;
}

.season-item span {
  font-size: 12.5px;
  color: var(--ink-dim);
}

/* Заведение не открывается по тапу: разбирать ресторан нечего.
   Оставляем ту же строку, но без вида кнопки. */
.season-item.static {
  cursor: default;
}

/* Плитки разделов: короткое имя и число блюд. Число здесь не украшение —
   по нему видно, что за разделом действительно что-то есть. */
.section-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0;
}

.section-chip {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-height: 44px;
  padding: 0 14px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.section-chip span {
  font-size: 12px;
  color: var(--ink-dim);
}

.section-chip.on {
  background: var(--lime);
  border-color: var(--lime);
  color: #0b0d09;
}

.section-chip.on span {
  color: #0b0d09;
  opacity: 0.7;
}

.section-note {
  margin: 14px 0 4px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

.missing-note {
  margin-top: 18px;
  padding-left: 12px;
  border-left: 2px solid var(--line);
}

/* ── FOODOS-DESIGN-007 (Этап 6) · RemixVerbs ───────────
   Ряд глаголов над полем вопроса. Тише поля: это ярлыки перехода между
   уже посчитанными версиями, а не действие — поэтому без акцента,
   на подложке карточки, с рамкой в её же тон. */
.verbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
}

.verbs-label {
  font: var(--foodos-type-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--foodos-color-ink-dim);
  margin-right: 2px;
}

.verb {
  min-height: 34px;
  padding: 0 13px;
  font: inherit;
  font-size: 13.5px;
  color: var(--foodos-color-ink-soft);
  background: transparent;
  /* Запасное значение для браузеров без color-mix (Safari < 16.2). */
  border: 1px solid rgba(244, 246, 238, 0.16);
  border: 1px solid color-mix(in srgb, var(--tint) 22%, transparent);
  border-radius: var(--r-pill);
  transition: color var(--foodos-motion-fade), border-color var(--foodos-motion-fade);
}

.verb:hover {
  color: var(--foodos-color-ink);
  border-color: rgba(244, 246, 238, 0.32);
  border-color: color-mix(in srgb, var(--tint) 45%, transparent);
}

/* Вопрос по версии. Поле неброское: это помощь на случай затыка,
   а не главное действие карточки — главным остаётся оценка. */
.ask {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.ask input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 14px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.ask input::placeholder {
  color: var(--ink-dim);
}

.ask button {
  min-height: 44px;
  padding: 0 18px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
}

.ask button:disabled {
  color: var(--ink-dim);
}

.ask-answer {
  margin-top: 10px;
  padding: 12px 14px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border-left: 2px solid var(--lime);
  border-radius: 0 10px 10px 0;
}

/* Слот визуала блюда: снимок и схема лежат друг на друге, показывается один.
   Оба грузятся заранее — переключение должно быть мгновенным, иначе человек
   жмёт кнопку и смотрит на пустоту. */
.dish-visual {
  position: relative;
}

.dish-visual .dish-scheme,
.dish-visual[data-view='scheme'] .dish-photo:not(.dish-scheme) {
  display: none;
}

.dish-visual[data-view='scheme'] .dish-scheme {
  display: block;
}

/* Схему нельзя кадрировать. Снимок блюда живёт в полосе 21:9 и обрезается
   по краям без потери — еда остаётся едой. У схемы обрезанный край это
   пропавший продукт: в полосе 21:9 борщ лишался сметаны сверху и дна
   кастрюли снизу. Поэтому в режиме схемы слот становится квадратным,
   а картинка вписывается целиком. */
.dish-visual[data-view='scheme'] .dish-scheme {
  aspect-ratio: 1 / 1;
  max-height: 420px;
  object-fit: contain;
  object-position: center;
  background: transparent;
}

.visual-switch {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(11, 13, 9, 0.82);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(6px);
}

.visual-switch button {
  min-height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.visual-switch button.active {
  background: var(--lime);
  color: #0B0512;
}

/* ── Схема состава · взрыв-схема §6 ─────────────────
   Язык из visual/diagrams: компоненты разнесены вдоль вертикальной оси
   сборки, каждый на выноске. Ось нарисована фоном, а не элементом, чтобы
   не появляться в дереве доступности: для чтения с экрана это обычный
   нумерованный список «продукт — что держит». */
.exploded {
  position: relative;
  margin-top: 18px;
  padding: 0;
  list-style: none;
}

/* Ось сборки: пунктир проходит через центры узлов и обрывается на основе. */
.exploded::before {
  content: '';
  position: absolute;
  left: 21px;
  top: 22px;
  bottom: 22px;
  width: 1px;
  background: repeating-linear-gradient(
    to bottom,
    var(--lime) 0 4px,
    transparent 4px 9px
  );
  opacity: 0.45;
}

.ex-row {
  position: relative;
  display: grid;
  grid-template-columns: 44px 22px 1fr;
  align-items: center;
  gap: 0;
  padding: 7px 0;
}

/* Узел перекрывает ось — так линия читается как проходящая за компонентом,
   а не сквозь него. */
.ex-node {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--bg);
  color: var(--lime);
}

.ex-node svg {
  width: 22px;
  height: 22px;
}

/* Выноска: линия с засечкой на конце, как на технической схеме. */
.ex-lead {
  position: relative;
  height: 1px;
  background: var(--line);
}

.ex-lead::after {
  content: '';
  position: absolute;
  right: 0;
  top: -3px;
  width: 1px;
  height: 7px;
  background: var(--lime);
  opacity: 0.7;
}

.ex-label {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-left: 10px;
  min-width: 0;
}

.ex-label b {
  font-size: 15px;
  line-height: 1.25;
}

.ex-label i {
  font-style: normal;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--ink-dim);
}

.ex-label .ex-unknown {
  opacity: 0.65;
}

/* Продукт без роли не притворяется разобранным: узел приглушён. */
.ex-vague .ex-node {
  border-style: dashed;
  color: var(--ink-dim);
}

/* Основа: сюда всё собирается, поэтому узел заметнее прочих. */
.ex-base .ex-node {
  border-color: var(--lime);
  color: var(--lime);
}

.ex-base .ex-label b {
  color: var(--lime);
}

/* ── Лента главной · §5 ────────────────────────────── */
.feed {
  padding: 20px;
  margin-bottom: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.feed.lead-card {
  border-color: var(--line-accent);
  background: linear-gradient(180deg, rgba(198, 244, 50, 0.06), transparent 60%), var(--bg-raised);
}

/* ── Полка кухни ───────────────────────────────────────
   Горизонтальный ряд вместо столбика: шесть карточек в столбик — это ещё
   один экран прокрутки, а претензия к вертикальной простыне уже записана
   в RESEARCH §0. Ряд скроллится внутри себя, страница по горизонтали — нет.

   FOODOS-DESIGN-003 (Этап 3): «полки визуально вторичны» — обёртка теряет
   свою рамку и фон карточки (герой их сохраняет), полка больше не спорит
   с ним по весу. Сами .shelf-card остаются кликабельными карточками
   со своей рамкой — вес снят только с внешнего контейнера. */
.feed.shelf {
  padding-right: 0;
  background: transparent;
  border-color: transparent;
}

.shelf-row {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 2px 20px 6px 0;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.shelf-row::-webkit-scrollbar {
  display: none;
}

.shelf-card {
  flex: 0 0 148px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 0 10px;
  overflow: hidden;
  text-align: left;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 14px;
  color: var(--ink);
  cursor: pointer;
  scroll-snap-align: start;
}

.shelf-card:hover {
  border-color: var(--line-accent);
}

.shelf-card b {
  padding: 8px 10px 0;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.25;
}

.shelf-card span {
  padding: 0 10px;
  font: 400 11px var(--font-mono);
  color: var(--ink-dim);
}

.dish-photo.shelf {
  aspect-ratio: 4 / 3;
  border-radius: 0;
}

/* ── Снимок блюда ──────────────────────────────────────
   Кадры сняты на том же фоне #0B0512, поэтому подложка под ними не нужна:
   картинка растворяется в карточке, а не лежит плиткой поверх неё. */
.dish-photo {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  background: var(--bg-sunken);
}

.dish-photo.lead {
  aspect-ratio: 16 / 10;
  object-position: center 58%;
  margin: -20px -20px 14px;
  width: calc(100% + 40px);
  border-radius: var(--r-card) var(--r-card) 0 0;
}

.dish-photo.dish {
  aspect-ratio: 21 / 9;
  object-position: center 60%;
  margin-bottom: 14px;
  border-radius: var(--r-inner, 12px);
}

@media (prefers-reduced-motion: no-preference) {
  .dish-photo {
    animation: photo-in 420ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
  }
}

@keyframes photo-in {
  from { opacity: 0; transform: scale(1.015); }
  to { opacity: 1; transform: none; }
}

.feed-label {
  margin-bottom: 10px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.feed h2 {
  margin-bottom: 8px;
  font-size: 22px;
  line-height: 1.15;
}

.feed-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 10px;
  font: 400 12.5px var(--font-mono);
  color: var(--ink-dim);
}

.feed p {
  font-size: 14.5px;
  color: var(--ink-soft);
}

.feed .ing-grid {
  margin: 14px 0 4px;
}

.ghost-btn {
  margin-top: 14px;
  min-height: 44px;
  padding: 11px 18px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--lime);
  background: transparent;
  border: 1px solid var(--line-accent);
  border-radius: 12px;
  transition: background 0.16s ease;
}

.ghost-btn:hover {
  background: rgba(198, 244, 50, 0.08);
}

/* Полоска под названием оси показывает, насколько сильно человек её любит. */
.taste-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.taste-chips span {
  position: relative;
  padding: 8px 13px 10px;
  font-size: 13.5px;
  background: var(--bg-sunken);
  border-radius: 10px;
  overflow: hidden;
}

.taste-chips span::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: var(--w);
  background: var(--lime);
}

/* ── FOODOS-DESIGN-002 (Этап 2) · TasteFingerprint ─────
   .radial — контейнер главного визуала экрана Вкус, был здесь и раньше
   (задаёт размер, не трогаем). Внутри теперь кольцо засечек, не радар:
   .radial svg по-прежнему ловит любой вложенный <svg>, поэтому специального
   модификатора размера не нужно. */
.radial {
  display: grid;
  place-items: center;
  margin: 6px 0 10px;
}

.radial svg {
  width: 100%;
  max-width: 300px;
  height: auto;
}

/* Бейдж-контейнер для двух маленьких мест: герой Главной и шапка блюда
   в Ремиксе. Сам размер задаётся здесь — .fingerprint внутри всегда
   заполняет родителя (см. ниже), поэтому один и тот же SVG одинаково
   ужимается что в бейдж 40px, что в 300px главного визуала. */
.fingerprint-badge {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}

.dish-head-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.fingerprint-wrap {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: center;
  transition: transform var(--foodos-motion-spring-default);
}

/* «Дышит»: JS раз в 3.4 с переключает этот класс на всех отпечатках сразу —
   сам масштаб небольшой (1.5%), чтобы читалось как жизнь, а не как рывок. */
.fingerprint-wrap.breathe {
  transform: scale(1.015);
}

/* ── FOODOS-DESIGN-010 (Этап 9) · Усталость ────────────
   Отпечаток «вянет», когда одно и то же блюдо разбирается по кругу.
   Меняется только жизнь картинки — прозрачность и дыхание (класс .breathe
   такому отпечатку не выдаётся вовсе). Длины засечек и форма остаются
   точными: это по-прежнему профиль человека, а не иллюстрация к упрёку.
   Ни процентов, ни счётчиков, ни достижений. */
.fingerprint-wrap.wilted {
  opacity: 0.45;
  transition: opacity var(--foodos-motion-enter);
}

.fp-fatigue {
  margin-top: 10px;
  font-size: 13.5px;
  text-align: center;
  color: var(--foodos-color-ink-dim);
}

.fingerprint {
  display: block;
  width: 100%;
  height: 100%;
}

.fp-core {
  fill: none;
  stroke: var(--foodos-color-line);
  stroke-width: 0.6;
}

.fp-tick {
  stroke: var(--foodos-color-ink-dim);
  stroke-width: 2.2;
  stroke-linecap: round;
  animation: fp-in var(--foodos-motion-enter) backwards;
}

/* Сильная ось (value ≥0.55 и confidence ≥0.25) — единственное место
   в отпечатке, где используется акцент. Остальные засечки — petal-off. */
.fp-tick.strong {
  stroke: var(--foodos-color-accent);
}

@keyframes fp-in {
  from {
    opacity: 0;
  }
}

/* ── Эволюция вкуса ────────────────────────────────── */
.evo {
  width: 100%;
  height: 110px;
}

.evo .mid {
  stroke: rgba(255, 255, 255, 0.12);
  stroke-dasharray: 3 4;
}

.evo-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 12px 0 10px;
  font: 400 12px var(--font-mono);
  color: var(--ink-soft);
}

.evo-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.evo-legend i {
  width: 12px;
  height: 3px;
  border-radius: 2px;
}

/* ── Книга вкуса · §7 ──────────────────────────────── */
.book-stat {
  display: flex;
  gap: 10px;
  margin-bottom: 14px;
}

.book-stat div {
  flex: 1;
  padding: 14px 10px;
  text-align: center;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
}

.book-stat b {
  display: block;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  color: var(--lime);
}

.book-stat span {
  font: 400 10.5px var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.book-item {
  position: relative;
  padding: 18px;
  margin-bottom: 10px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}

/* Полоска слева убрана: `side-tab accent border` назван самым узнаваемым
   признаком сгенерированного интерфейса. Уровень и так подписан в шапке
   карточки — дублировать его цветной планкой незачем. */
.book-item::before {
  content: '';
  position: absolute;
  right: 18px;
  top: 20px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}
.book-item[data-level='10']::before { background: #8fd6a4; }
.book-item[data-level='30']::before { background: #c6f432; }
.book-item[data-level='60']::before { background: #ffab5c; }
.book-item[data-level='90']::before { background: #b96bff; }

.bi-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
  font: 400 11.5px var(--font-mono);
  color: var(--ink-dim);
}

.bi-level {
  color: var(--lime);
  font-weight: 500;
}

.book-item h3 {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.bi-base {
  margin: 4px 0 12px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

.book-item .ing-grid {
  margin-top: 12px;
}

/* ── FOODOS-DESIGN-009 (Этап 8) · Журнал записи ────────
   Отметка и заметка отделены от карточки чертой: выше — что предложило
   приложение, ниже — что человек с этим сделал. Тон приглушённый, акцента
   нет: это его пометки на полях, а не ещё одно предложение. */
.bi-journal {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--foodos-color-line);
}

.bi-statuses {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}

.bi-status {
  min-height: 36px;
  padding: 0 14px;
  font: inherit;
  font-size: 13.5px;
  color: var(--foodos-color-ink-soft);
  background: transparent;
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-pill);
  transition: color var(--foodos-motion-fade), border-color var(--foodos-motion-fade);
}

/* Выбранная отметка становится ярче обводкой и текстом, но не заливкой:
   акцент на экране Вкус уже занят, а отметка — это состояние, а не действие. */
.bi-status.on {
  color: var(--foodos-color-ink);
  border-color: var(--foodos-color-ink-dim);
}

.bi-note {
  display: block;
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  font-size: 13.5px;
  color: var(--foodos-color-ink);
  background: var(--bg-sunken);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-input);
  resize: vertical;
}

.bi-note::placeholder {
  color: var(--foodos-color-ink-dim);
}

.bi-note-date {
  margin-top: 6px;
  font: var(--foodos-type-caption);
  color: var(--foodos-color-ink-dim);
}

/* ── Пустые состояния · §23 ────────────────────────── */
.empty {
  padding: 24px 20px;
  background: var(--bg-raised);
  border: 1px dashed var(--line-accent);
  border-radius: var(--r-card);
}

.empty p {
  margin-bottom: 8px;
  font-size: 14.5px;
}

/* ── Типографика ───────────────────────────────────── */
.kicker,
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.kicker {
  color: var(--lime-deep);
  font-weight: 600;
}

/* FOODOS-DESIGN-005 (Этап 4): роли заголовков названы токенами.
   Значения те же — токены выше выставлены как точные алиасы этих правил,
   поэтому переход ничего не двигает на экране. */
h1,
.panel-title {
  font: var(--foodos-type-display);
  letter-spacing: -0.03em;
  margin: 14px 0 12px;
}

h2 {
  font: var(--foodos-type-head);
  letter-spacing: -0.02em;
}

.section-h {
  font: var(--foodos-type-title);
  letter-spacing: -0.02em;
  margin: 34px 0 6px;
}

.lede {
  color: var(--ink-soft);
  font-size: 15px;
  margin-bottom: 22px;
}

.muted {
  color: var(--ink-soft);
  font-size: 14px;
}

.small {
  font-size: 13px;
}

/* ── Ввод и кнопки ─────────────────────────────────── */
.dish-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

@media (min-width: 520px) {
  .dish-form {
    flex-direction: row;
  }
}

input[type='text'] {
  flex: 1;
  min-height: 52px;
  padding: 15px 17px;
  font: 400 16px var(--font-body);
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 14px;
  transition: border-color 0.16s ease;
}

input[type='text']::placeholder {
  color: var(--ink-dim);
}

input[type='text']:focus {
  outline: none;
  border-color: var(--line-accent);
}

#submit-btn,
.primary-btn,
.step-btn {
  min-height: 52px;
  padding: 15px 24px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: #0b0512;
  background: var(--lime);
  border: none;
  border-radius: 14px;
  transition: opacity 0.16s ease, transform 0.12s ease;
}

.primary-btn {
  width: 100%;
  margin-top: 16px;
}

#submit-btn:active,
.primary-btn:active,
.step-btn:active {
  transform: scale(0.985);
}

#submit-btn:disabled {
  opacity: 0.5;
  cursor: progress;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}

.chips button {
  min-height: 36px;
  padding: 8px 13px;
  font-size: 13.5px;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: color 0.16s ease, border-color 0.16s ease;
}

.chips button:hover {
  color: var(--lime);
  border-color: var(--line-accent);
}

.chips button.active {
  color: #0b0512;
  background: var(--lime);
  border-color: var(--lime);
  font-weight: 600;
}

.engine-note {
  margin-top: 16px;
  padding: 12px 14px;
  font-size: 13px;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line-accent);
  border-radius: var(--r-input);
}

/* ── Карточки ──────────────────────────────────────── */
.card {
  margin-top: 20px;
  padding: 20px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.status {
  margin-top: 20px;
  padding: 16px 18px;
  font-size: 14.5px;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.status.error {
  color: var(--bad);
  border-color: rgba(255, 107, 122, 0.3);
}

.tag {
  padding: 5px 11px;
  font: 500 11.5px/1 var(--font-mono);
  color: var(--lime);
  background: rgba(198, 244, 50, 0.1);
  border-radius: 999px;
  white-space: nowrap;
}

.dish-head,
.dna-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.axis-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 14px;
}

.axis-pill {
  padding: 6px 11px;
  font: 400 12.5px/1 var(--font-mono);
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border-radius: 8px;
}

.axis-pill b {
  color: var(--ink);
  font-weight: 500;
}

/* ── FOODOS-DESIGN-001 (Этап 1) · RemixDial ────────────
   Навигация по уже готовым версиям поверх книжных разворотов ниже —
   сами развороты (.spread/.level) не трогаем ни в разметке, ни в цвете
   подложки: это отдельный Proposal 005 (иерархия), не этот. */
.remix-dial {
  margin-top: 20px;
}

.dial-progress {
  margin-bottom: 8px;
  font: var(--foodos-type-caption);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--foodos-color-ink-dim);
}

.dial-track {
  position: relative;
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-pill);
}

/* Индикатор — единственный элемент, использующий акцент внутри диала:
   «один акцент на экран» держим уже сейчас, не дожидаясь Proposal 005. */
.dial-indicator {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(25% - 4px);
  background: var(--foodos-color-accent);
  border-radius: var(--r-pill);
  transition: transform var(--foodos-motion-spring-default);
}

.dial-stop {
  position: relative;
  z-index: 1;
  flex: 1;
  min-height: 44px;
  min-width: 44px;
  font: var(--foodos-type-caption);
  letter-spacing: 0.02em;
  color: var(--foodos-color-ink-soft);
  background: transparent;
  border: 0;
  border-radius: var(--r-pill);
  transition: color var(--foodos-motion-fade);
}

.dial-stop.pending {
  color: var(--foodos-color-ink-dim);
  cursor: default;
}

/* Текст активного стопа поверх заливки-акцента: акцент светлый (лайм),
   поэтому для контраста берём цвет фона приложения, а не основной текст. */
.dial-stop.active {
  color: var(--foodos-color-bg);
  font-weight: 600;
}

/* Поиск по каталогу — на всю ширину, крупный: им пользуются с телефона,
   стоя у плиты, и попасть в него надо с первого раза. */
.menu-search {
  margin: 16px 0 10px;
}

.menu-search input {
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  font: inherit;
  font-size: 15px;
  color: var(--foodos-color-ink);
  background: var(--bg-sunken);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-pill);
}

.menu-search input::placeholder {
  color: var(--foodos-color-ink-dim);
}

/* Сезонный продукт — кнопка: по нажатию показываются блюда с ним.
   Выглядит как строка списка, но ведёт себя как ссылка, поэтому курсор
   и подсветка рамкой при наведении обязательны. */
.season-items .item {
  width: 100%;
  text-align: left;
  color: inherit;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-input);
  cursor: pointer;
}

.season-items .item:hover {
  border-color: var(--line-accent);
}

/* ── Тест вкуса ────────────────────────────────────────
   Семнадцать осей плитками: видно сразу, что пройдено, а что нет,
   и куда человек попадает по каждой. Полоска под именем — его граница,
   а не «уровень прокачки»: у вкуса нет правильного значения. */
.quiz-axes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 12px 0 18px;
}

@media (min-width: 520px) {
  .quiz-axes {
    grid-template-columns: repeat(3, 1fr);
  }
}

.quiz-axis {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  text-align: left;
  color: var(--foodos-color-ink);
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color var(--foodos-motion-fade);
}

.quiz-axis:hover,
.quiz-axis.active {
  border-color: var(--line-accent);
}

.quiz-axis b {
  font-size: 14.5px;
  font-weight: 600;
}

.quiz-axis-meta {
  font: 400 10.5px var(--font-mono);
  color: var(--foodos-color-ink-dim);
}

.quiz-axis-bar {
  display: block;
  height: 3px;
  margin-top: 2px;
  background: var(--bg-sunken);
  border-radius: 999px;
  overflow: hidden;
}

.quiz-axis-bar > span {
  display: block;
  height: 100%;
  background: var(--foodos-color-accent);
}

.quiz-card h3 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  margin-bottom: 4px;
}

.quiz-q {
  padding: 14px 0;
  border-top: 1px solid var(--foodos-color-line);
}

.quiz-q p {
  margin-bottom: 10px;
  font-size: 14.5px;
}

.quiz-answers {
  display: flex;
  gap: 6px;
}

.quiz-btn {
  flex: 1;
  min-height: 42px;
  font: inherit;
  font-size: 13.5px;
  color: var(--foodos-color-ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-pill);
  transition: color var(--foodos-motion-fade), border-color var(--foodos-motion-fade);
}

/* Выбранный ответ обводится, но не заливается: на экране «Вкус» акцент
   уже занят отпечатком, а ответов на странице десять. */
.quiz-btn.on {
  color: var(--foodos-color-ink);
  border-color: var(--foodos-color-accent);
}

/* ── Меню плитками: один вид на все разделы ────────────
   Блюдо, коктейль, приём — всё показывается одинаково: снимок сверху,
   имя и состав под ним. Раньше каждая вкладка рисовала своё, и приложение
   выглядело собранным из кусков. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 14px;
}

@media (min-width: 560px) {
  .tile-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.tile {
  display: flex;
  flex-direction: column;
  padding: 0 0 12px;
  overflow: hidden;
  text-align: left;
  color: var(--foodos-color-ink);
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color var(--foodos-motion-fade);
}

.tile:hover {
  border-color: var(--line-accent);
}

.tile-photo {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--bg-sunken);
}

.tile-photo-empty {
  background: var(--bg-sunken);
}

.tile-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px 0;
}

.tile-body b {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.tile-parts {
  font-size: 12px;
  line-height: 1.35;
  color: var(--foodos-color-ink-soft);
}

.tile-meta {
  font: 400 10.5px var(--font-mono);
  color: var(--foodos-color-ink-dim);
}

/* Обзор трендов — справка под блюдами, свёрнутая по умолчанию. */
.trends-review {
  margin-top: 26px;
  padding: 14px 16px;
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-card);
}

.trends-review > summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  cursor: pointer;
  list-style: none;
}

.trends-review > summary::-webkit-details-marker {
  display: none;
}

/* ── Бар: меню с фотографиями ──────────────────────────
   Сначала здесь был плотный список строк — и это оказалось ошибкой:
   коктейль выбирают глазами, по цвету и форме бокала. Стало меню из плиток,
   у каждой свой снимок. Две колонки на телефоне: плитка шириной в пол-экрана
   даёт снимок ~180 px, этого хватает, чтобы отличить негрони от дайкири. */
.bar-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

@media (min-width: 560px) {
  .bar-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.bar-tile {
  display: flex;
  flex-direction: column;
  padding: 0 0 12px;
  overflow: hidden;
  text-align: left;
  color: var(--foodos-color-ink);
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color var(--foodos-motion-fade);
}

.bar-tile:hover {
  border-color: var(--line-accent);
}

.bar-photo {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--bg-sunken);
}

.bar-photo-empty {
  background: var(--bg-sunken);
}

.bar-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px 0;
}

.bar-body b {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.bar-parts {
  font-size: 12px;
  line-height: 1.35;
  color: var(--foodos-color-ink-soft);
}

.bar-meta {
  font: 400 10.5px var(--font-mono);
  color: var(--foodos-color-ink-dim);
}

/* ── Рецепт блюда: книжный разворот ────────────────────
   Тот же язык, что у версий ремикса, — «Мировая кухня»: снимок во всю
   ширину, заголовок капсом в разрядку, три пиктограммы, состав плитками,
   шаги в кружках. Отличие одно: у рецепта нет уровня новизны, поэтому
   подложка нейтральная, а в бейдже стоит кухня. */
.recipe-sheet {
  padding: 0 0 calc(20px + env(safe-area-inset-bottom));
}

.recipe-spread {
  margin: 0;
  padding: 0 20px 20px;
  --tint: var(--foodos-color-accent);
  --ground: var(--foodos-color-surface);
}

/* Снимок выходит за поля листа и стыкуется с его скруглением сверху —
   в книге фото тоже идёт в обрез, а не плиткой внутри поля. */
.recipe-photo {
  aspect-ratio: 4 / 3;
  object-position: center 58%;
  margin: 0 -20px 18px;
  width: calc(100% + 40px);
  border-radius: 22px 22px 0 0;
}

.recipe-spread .spread-head {
  margin-bottom: 22px;
}

.recipe-spread .axis-strip {
  justify-content: center;
}

.recipe-scheme {
  aspect-ratio: 1 / 1;
  border-radius: var(--r-card);
}

/* ── Уровни новизны как книжные развороты ──────────────
   Приём из «Мировой кухни» / Simplissime: у каждого рецепта своя плотная
   подложка. Здесь она несёт смысл — цвет подложки кодирует уровень новизны,
   от мятного к фиолетовому. Это единственное место, где цвет заливает
   поверхность, и он же заменяет собой запрещённый градиент на карточке. */
.levels {
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Разворот идёт от края до края и без скруглений — в книге модули стыкуются
   встык, граница видна только по смене цвета. Скруглённая карточка с зазором
   мгновенно превращает печатную страницу обратно в веб-интерфейс. */
.spread {
  position: relative;
  margin: 0 -18px;
  padding: 30px 22px 22px;
  --tint: #7be38a;
  --ground: #0e1a13;
  background: var(--ground);
}

.level[data-level='10'] { --tint: #8fd6a4; --ground: #16241b; }
.level[data-level='30'] { --tint: #c6f432; --ground: #1b2110; }
.level[data-level='60'] { --tint: #ffab5c; --ground: #241a11; }
.level[data-level='90'] { --tint: #b96bff; --ground: #1c1230; }

.spread-head {
  text-align: center;
  margin-bottom: 26px;
}

.level-badge {
  display: inline-block;
  margin-bottom: 14px;
  padding: 5px 12px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.1em;
  color: var(--ground);
  background: var(--tint);
  border-radius: 999px;
}

/* Заголовок капсом в широкую разрядку, тонким весом — прямая цитата
   из «Мировой кухни»: там он именно такой и центрирован по колонке. */
.spread h3 {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 500;
  line-height: 1.24;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 20px;
}

/* Три пиктограммы под заголовком: порции · сборка · всего.
   В книге это вилка с ножом, кастрюля и сотейник с цифрой под каждым. */
.meta-row {
  display: flex;
  justify-content: center;
  gap: 34px;
  padding-bottom: 20px;
  margin-bottom: 18px;
  border-bottom: 1px solid rgba(244, 246, 238, 0.14);
  border-bottom: 1px solid color-mix(in srgb, var(--tint) 20%, transparent);
}

.meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  text-align: center;
}

.meta svg {
  width: 26px;
  height: 26px;
  color: var(--tint);
}

.meta b {
  font: 600 15px/1 var(--font-display);
}

.meta span {
  font: 400 10px/1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.spread p.summary {
  color: var(--ink-soft);
  font-size: 14.5px;
  margin-bottom: 15px;
}

.spread-block {
  margin-bottom: 22px;
}

.spread-block h4 {
  margin-bottom: 12px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* ── Раскладка продуктов ─────────────────────────────
   Каждый ингредиент — отдельная плитка с воздухом вокруг, как разложенные
   на столе продукты. Список строкой не показывает, что именно покупать. */
/* Продукты лежат прямо на цветной подложке, без плиток и рамок —
   как разложенные на бумаге предметы. Рамка вокруг каждого превратила бы
   раскладку обратно в таблицу карточек. */
.ing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 22px 12px;
  padding: 6px 0 4px;
}

.ing-grid.dim {
  opacity: 0.5;
}

.ing {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}

.ing svg {
  width: 46px;
  height: 46px;
  color: var(--tint, var(--lime));
  /* Мягкая тень под предметом — в книге продукты лежат на бумаге
     и отбрасывают тень, без неё раскладка выглядит плоской наклейкой. */
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45));
}

/* Название продукта — основной контент, а не подпись: читаемость важнее
   компактности сетки, поэтому не мельче 13 px. */
.ing figcaption b {
  display: block;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.28;
}

.ing figcaption span {
  display: block;
  margin-top: 4px;
  font: 400 11.5px/1.2 var(--font-mono);
  color: var(--ink-soft);
}

/* ── Шаги в кружках ──────────────────────────────────── */
.steps {
  list-style: none;
  counter-reset: step;
}

.steps li {
  display: flex;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.steps li:last-child {
  border-bottom: none;
}

.steps li::before {
  counter-increment: step;
  content: counter(step);
  flex: none;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  font: 500 12px/1 var(--font-mono);
  color: var(--tint);
  border: 1px solid rgba(244, 246, 238, 0.32);
  border: 1px solid color-mix(in srgb, var(--tint) 45%, transparent);
  border-radius: 50%;
}

.steps p {
  font-size: 14.5px;
  padding-top: 2px;
}

.sn {
  display: none;
}

.deltas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 15px;
}

.delta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 11px;
  font: 500 12px/1 var(--font-mono);
  border-radius: 8px;
  background: var(--bg-sunken);
}

.delta.up { color: var(--lime); }
.delta.down { color: var(--violet); }

.delta small {
  font-weight: 400;
  opacity: 0.7;
}

.block {
  margin-bottom: 14px;
}

.block h4 {
  margin-bottom: 7px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.block ul,
.block ol {
  padding-left: 19px;
  font-size: 14.5px;
}

.block li {
  margin-bottom: 5px;
}

.block li span.why {
  color: var(--ink-soft);
}

.warn {
  margin-top: 12px;
  padding: 11px 13px;
  font-size: 13px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border-radius: 10px;
}

.rate {
  display: flex;
  gap: 8px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.rate button {
  flex: 1;
  min-height: 46px;
  padding: 12px;
  font-size: 14.5px;
  font-weight: 600;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 12px;
  transition: border-color 0.16s ease, color 0.16s ease;
}

.rate button:first-child:hover:not(:disabled) {
  color: var(--lime);
  border-color: var(--line-accent);
}

.rate button:last-child:hover:not(:disabled) {
  color: var(--violet);
  border-color: rgba(168, 60, 255, 0.35);
}

.rate button:disabled {
  opacity: 0.45;
  cursor: default;
}

.rate.done {
  color: var(--ink-soft);
  font-size: 13.5px;
}

/* ── Вкусовой профиль ──────────────────────────────── */
.dna-axes {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px 0;
}

.dna-row {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr) 40px;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}

@media (max-width: 380px) {
  .dna-row {
    grid-template-columns: 108px minmax(0, 1fr) 36px;
    font-size: 12px;
  }
}

.dna-row .name {
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar {
  position: relative;
  height: 8px;
  background: var(--bg-sunken);
  border-radius: 999px;
  overflow: hidden;
}

/* Оси разложены по градиенту от лайма к фиолету — цвет несёт смысл,
   а не превращает экран в радугу (бриф §18). */
.bar span {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 999px;
  background: var(--lime);
  background-size: 1700% 100%;
  transition: width 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

.dna-row .conf {
  text-align: right;
  font: 400 11px var(--font-mono);
  color: var(--ink-dim);
}

details {
  margin-top: 10px;
  font-size: 14px;
}

summary {
  cursor: pointer;
  color: var(--lime);
  font-weight: 500;
  min-height: 32px;
}

.evidence {
  margin-top: 12px;
  list-style: none;
  font-size: 13px;
  color: var(--ink-soft);
}

.evidence li {
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.evidence li:last-child {
  border-bottom: none;
}

.evidence b {
  color: var(--ink);
}

/* ── Город ─────────────────────────────────────────── */
.modes {
  display: flex;
  gap: 7px;
  margin: 16px 0 18px;
}

.modes button {
  flex: 1;
  min-height: 44px;
  padding: 11px 8px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  transition: all 0.16s ease;
}

.modes button.active {
  color: #0b0512;
  background: var(--lime);
  border-color: var(--lime);
  font-weight: 600;
}

.places,
.seasonal {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.place {
  padding: 16px 18px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.place-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.place-head b {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.place .meta {
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-dim);
}

.place .why {
  margin-top: 8px;
  font-size: 13px;
  color: var(--lime);
}

.rate-badge {
  font: 600 13px var(--font-mono);
  color: var(--mint);
  white-space: nowrap;
}

.seasonal .item {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.seasonal .dot {
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 8px;
  border-radius: 50%;
  background: var(--ink-dim);
}

.seasonal .item[data-locality='местное'] .dot { background: var(--lime); }
.seasonal .item[data-locality='российское'] .dot { background: var(--violet); }

.seasonal b {
  font-size: 15px;
  font-weight: 600;
}

.seasonal .why {
  margin-top: 3px;
  font-size: 13px;
  color: var(--ink-soft);
}

.sources {
  margin-top: 26px;
}

.sources ul {
  margin-top: 10px;
  padding-left: 18px;
  font-size: 12.5px;
  color: var(--ink-dim);
}

.sources a {
  color: var(--lime);
}

/* ── Перевод кухни ─────────────────────────────────── */
.translation {
  margin-top: 14px;
  padding: 20px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.translation .lead {
  font-size: 15px;
  margin-bottom: 16px;
}

.tr-block {
  margin-bottom: 13px;
}

.tr-block h4 {
  margin-bottom: 5px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.tr-block .row {
  font-size: 14px;
}

.tr-block.known .row { color: var(--mint); }
.tr-block.fresh .row { color: var(--lime); }
.tr-block.missing .row { color: var(--ink-dim); }

.analogue {
  margin-top: 14px;
  padding: 12px 14px;
  font-size: 14px;
  background: var(--bg-sunken);
  border-radius: 10px;
}

/* ── Кухня ─────────────────────────────────────────── */
/* Инвентарь раскладкой предметов, а не строками: видно каждую вещь. */
.kit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 10px;
  margin: 16px 0;
}

.kit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-height: 108px;
  padding: 15px 8px 11px;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 14px;
  text-align: center;
  transition: border-color 0.16s ease, background 0.16s ease;
}

.kit svg {
  width: 34px;
  height: 34px;
  color: var(--ink-dim);
  transition: color 0.16s ease;
}

.kit .nm {
  font-size: 12px;
  line-height: 1.25;
  color: var(--ink-soft);
}

.kit .st {
  font: 400 9.5px/1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.kit[data-state='хорошее'] {
  border-color: rgba(123, 227, 138, 0.45);
  background: rgba(123, 227, 138, 0.07);
}
.kit[data-state='хорошее'] svg { color: var(--mint); }
.kit[data-state='хорошее'] .nm { color: var(--ink); }
.kit[data-state='хорошее'] .st { color: var(--mint); }

.kit[data-state='плохое'] {
  border-color: rgba(255, 107, 122, 0.45);
  background: rgba(255, 107, 122, 0.07);
}
.kit[data-state='плохое'] svg { color: var(--bad); }
.kit[data-state='плохое'] .nm { color: var(--ink); }
.kit[data-state='плохое'] .st { color: var(--bad); }

.budget-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 22px 0 6px;
  flex-wrap: wrap;
}

.verdict-group {
  margin-top: 22px;
}

.verdict-group h3 {
  margin-bottom: 11px;
  font: 500 10.5px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.verdict {
  position: relative;
  display: flex;
  gap: 14px;
  padding: 15px 17px 15px 20px;
  margin-bottom: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.verdict .vg {
  flex: none;
  width: 32px;
  height: 32px;
  margin-top: 2px;
  color: var(--ink-dim);
}

.verdict[data-v='buy'] .vg { color: var(--lime); }
.verdict[data-v='replace'] .vg { color: #ff9d3c; }
.verdict[data-v='dont-buy'] .vg { color: var(--bad); opacity: 0.7; }

.verdict .vbody {
  min-width: 0;
  flex: 1;
}

/* Здесь полоска тем более лишняя: глиф предмета уже окрашен по вердикту. */
.verdict::before {
  content: none;
}

.verdict[data-v='buy']::before { background: var(--lime); }
.verdict[data-v='replace']::before { background: #ff9d3c; }
.verdict[data-v='dont-buy']::before { background: var(--bad); }
.verdict[data-v='keep']::before { background: var(--ink-dim); }
.verdict[data-v='keep'] { opacity: 0.7; }

.verdict .top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 15.5px;
  font-weight: 600;
}

.verdict .price {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 400;
  color: var(--ink-dim);
  white-space: nowrap;
}

.verdict p {
  margin-top: 6px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* ── FOODOS-DESIGN-008 (Этап 7) · «Не покупай» ─────────
   Первый блок экрана Кухня и самая крупная цифра на нём. Заменил прежнюю
   строку .saved, которая стояла третьей и весила столько же, сколько всё
   остальное. Сумма набрана крупно потому, что это и есть ответ экрана,
   а не сноска к плану покупок. Ачивок, медалей и поздравлений здесь нет:
   человеку показывают его деньги и причину по каждой вещи. */
.dont-buy {
  padding: 20px;
  margin-bottom: 4px;
  background: var(--foodos-color-surface);
  border: 1px solid var(--foodos-color-line);
  border-radius: var(--r-card);
}

.dont-buy-label {
  font: var(--foodos-type-caption);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--foodos-color-ink-dim);
}

.dont-buy-sum {
  margin: 6px 0 8px;
  font: var(--foodos-type-display);
  letter-spacing: -0.03em;
  color: var(--foodos-color-ink);
}

.dont-buy-note {
  font-size: 14.5px;
  color: var(--foodos-color-ink-soft);
}

/* ── Привычки и тренировка ─────────────────────────── */
.note {
  padding: 15px 17px;
  margin-bottom: 8px;
  font-size: 14.5px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border: 1px solid var(--line-accent);
  border-radius: var(--r-card);
}

.note.quiet {
  border-color: var(--line);
  color: var(--ink-soft);
}

.repeat {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 17px;
  margin-bottom: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
  font-size: 14px;
}

.repeat .saved-time {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--mint);
  white-space: nowrap;
}

.ladder-head h3 {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 18px;
}

.ladder-goal {
  margin: 5px 0 16px;
  font-size: 14px;
  color: var(--ink-soft);
}

.step {
  display: flex;
  gap: 13px;
  padding: 16px 17px;
  margin-bottom: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
}

/* Приглушаем цветом, а не прозрачностью. `opacity: 0.5` режет контраст
   вдвое разом у всего содержимого: текст пройденной ступени опускался
   примерно до 2.4:1 при норме 4.5 — Lighthouse поймал это на вкладке
   «Вкус». Цветом тот же смысл передаётся, а читаемость остаётся
   проверяемой. */
.step[data-state='пройдена'],
.step[data-state='закрыта'] {
  color: var(--ink-dim);
}

.step[data-state='пройдена'] .why,
.step[data-state='закрыта'] .why,
.step[data-state='пройдена'] .try,
.step[data-state='закрыта'] .try {
  color: var(--ink-dim);
}

.step[data-state='закрыта'] b {
  color: var(--ink-soft);
}

.step[data-state='текущая'] {
  border-color: var(--line-accent);
}

.step .num {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  font: 600 13px var(--font-mono);
  color: var(--ink-dim);
  background: var(--bg-sunken);
  border-radius: 50%;
}

.step[data-state='пройдена'] .num {
  color: #0b0512;
  background: var(--mint);
}

.step[data-state='текущая'] .num {
  color: #0b0512;
  background: var(--lime);
}

.step b {
  font-family: var(--font-display);
  font-size: 15.5px;
  font-weight: 600;
}

.step .try {
  margin-top: 5px;
  font-size: 14px;
}

.step .why {
  margin-top: 5px;
  font-size: 13px;
  color: var(--ink-soft);
}

.step-btn {
  margin-top: 12px;
  min-height: 44px;
  padding: 11px 18px;
  font-size: 14.5px;
}

/* ── Режим дня ─────────────────────────────────────── */
.q {
  margin-bottom: 16px;
}

.q p {
  margin-bottom: 8px;
  font-size: 14.5px;
}

.q .opts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.q .opts button {
  min-height: 40px;
  padding: 9px 13px;
  font-size: 13px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: all 0.16s ease;
}

.q .opts button.active {
  color: #0b0512;
  background: var(--lime);
  border-color: var(--lime);
  font-weight: 600;
}

/* Вопрос с множественным выбором отличается от одиночного не подписью,
   а плотностью: шестнадцать кухонь набором мелких чипов, чтобы список
   не превращался в лестницу на пол-экрана. */
.q-multi {
  padding-bottom: 16px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

.q-multi .opts button {
  min-height: 34px;
  padding: 6px 11px;
  font-size: 12.5px;
  border-radius: 999px;
}

.q-hint {
  margin: -4px 0 8px;
}

.q-count {
  display: inline-block;
  min-width: 20px;
  padding: 1px 6px;
  font: 500 11px/1.5 var(--font-mono);
  text-align: center;
  color: #0b0512;
  background: var(--lime);
  border-radius: 999px;
  vertical-align: middle;
}

.mode-badge {
  margin-top: 16px;
  padding: 15px 17px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-accent);
  border-radius: 14px;
  font-size: 14px;
}

.mode-badge b {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--lime);
}

/* ── План постепенной смены ────────────────────────── */
.plan-step {
  display: flex;
  gap: 13px;
  padding: 16px;
  margin-top: 8px;
  background: var(--bg-sunken);
  border-radius: 14px;
}

.plan-step .num {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  font: 600 12.5px var(--font-mono);
  color: #0b0512;
  background: var(--lime);
  border-radius: 50%;
}

.plan-step b {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
}

.plan-step .what {
  margin-top: 4px;
  font-size: 14px;
}

.plan-step .why {
  margin-top: 5px;
  font-size: 13px;
  color: var(--ink-soft);
}

.disclaimer {
  margin-top: 14px;
  padding: 12px 14px;
  font-size: 12.5px;
  color: var(--ink-dim);
  background: var(--bg-sunken);
  border-radius: 10px;
}

/* ── Подвал и тост ─────────────────────────────────── */
.foot {
  margin-top: 44px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-dim);
}

.foot p {
  margin-bottom: 8px;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-h) + 16px);
  transform: translateX(-50%);
  max-width: min(92vw, 460px);
  padding: 14px 19px;
  font-size: 14px;
  font-weight: 500;
  color: #0b0512;
  background: var(--lime);
  border-radius: 14px;
  z-index: 40;
}

/* ── Движение объясняет действие, а не украшает ────── */
/* ── Движение ──────────────────────────────────────────
   Раньше здесь было одно правило на пять разных сущностей: карточки, уровни,
   заведения, шаги и вердикты выезжали одинаково, 0.34 s, на 10 px. Это прямо
   названный признак AI-моушена — «одинаковая анимация появления у всего
   с одним таймингом» (RESEARCH §E). Убрано.

   Осталось движение, которое сообщает состояние, а не украшает:

   1. Уровни ремикса появляются по очереди — потому что они и считаются
      по очереди. Бесплатный тариф GigaChat даёт один поток, четыре версии
      приходят последовательно за 6–8 секунд. Задержка здесь не декоративная:
      она показывает реальный порядок работы системы.
   2. Лист снизу выезжает, потому что это лист, который вы вытянули.
   3. Новая строка в списке покупок подсвечивается — иначе у полки непонятно,
      добавилось ли что-нибудь.

   Тайминги разные по назначению: лист 320 ms, результат 240 ms,
   микро-состояние 140 ms. Одинаковая длительность на всё и делает интерфейс
   плоским. */

@media (prefers-reduced-motion: no-preference) {
  .level {
    animation: level-in 240ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
    /* --i приходит из разметки: индекс уровня новизны, 0…3 */
    animation-delay: calc(var(--i, 0) * 90ms);
  }

  @keyframes level-in {
    from {
      opacity: 0;
      transform: translateY(8px);
    }
  }

  .store-list li.fresh {
    animation: item-in 140ms ease-out both;
  }

  @keyframes item-in {
    from {
      opacity: 0;
      background: rgba(198, 244, 50, 0.14);
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

:focus-visible {
  outline: 2px solid var(--lime);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ── §22 Онбординг ─────────────────────────────────────
   Лист снизу, а не модальное окно по центру: большой палец достаёт до кнопок,
   а список кухонь не упирается в клавиатуру. Приложение под ним видно —
   человек с первой секунды понимает, куда попал, а не смотрит в заставку. */
.onb {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(7, 3, 14, 0.72);
  backdrop-filter: blur(6px);
}

body.onb-open {
  overflow: hidden;
}

.onb-sheet {
  width: min(560px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  padding: 22px 20px calc(20px + env(safe-area-inset-bottom));
  background: var(--bg-raised);
  border: 1px solid var(--line-accent);
  border-bottom: none;
  border-radius: 22px 22px 0 0;
}

@media (prefers-reduced-motion: no-preference) {
  .onb-sheet {
    animation: onb-rise 320ms cubic-bezier(0.2, 0.8, 0.3, 1) both;
  }
}

@keyframes onb-rise {
  from { transform: translateY(18px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.onb-progress {
  height: 2px;
  margin-bottom: 18px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}

.onb-progress span {
  display: block;
  height: 100%;
  background: var(--grad);
  transition: width 0.32s cubic-bezier(0.2, 0.8, 0.3, 1);
}

.onb-sheet h2 {
  margin: 6px 0 8px;
  font-family: var(--font-display);
  font-size: 25px;
  letter-spacing: -0.02em;
}

.onb-body {
  margin: 18px 0 20px;
}

.onb-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.onb-chips button {
  min-height: 38px;
  padding: 8px 13px;
  font-size: 13px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: all 0.16s ease;
}

.onb-chips button.active {
  color: #0b0512;
  background: var(--lime);
  border-color: var(--lime);
  font-weight: 500;
}

/* Число блюд рядом с кухней: подсказка о размере, а не украшение.
   Прозрачность заменена на явный цвет — Lighthouse справедливо ловил на ней
   недостаточный контраст, а на активном лаймовом чипе полупрозрачный тёмный
   текст читался ещё хуже. */
.onb-count {
  font: 400 11px var(--font-mono);
  color: var(--ink-dim);
}

.onb-chips button.active .onb-count {
  color: #2c3a06;
}

.onb-actions {
  display: flex;
  gap: 10px;
  align-items: center;
}

.onb-actions .primary-btn {
  flex: 1;
}

/* ── Город: полки вместо простыни ──────────────────────
   Было тридцать пять заведений и двадцать четыре сезонных позиции одним
   столбцом — шесть экранов вертикальной прокрутки, прямо названная претензия
   из RESEARCH §0. Стало: ряд на кухню и группа на сезонную категорию. */
.city-shelf {
  margin-bottom: 20px;
}

.city-shelf .feed-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.shelf-mark {
  padding: 2px 7px;
  font: 500 9.5px/1.6 var(--font-mono);
  letter-spacing: 0.06em;
  color: #0b0512;
  background: var(--lime);
  border-radius: 999px;
  text-transform: uppercase;
}

.place-card {
  flex: 0 0 208px;
  padding: 13px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  scroll-snap-align: start;
}

.place-card[open] {
  border-color: var(--line-accent);
}

.place-card summary {
  display: flex;
  flex-direction: column;
  gap: 3px;
  cursor: pointer;
  list-style: none;
}

.place-card summary::-webkit-details-marker {
  display: none;
}

.place-card summary b {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.2;
}

.place-meta {
  font: 400 11.5px var(--font-mono);
  color: var(--lime);
}

.place-type {
  font-size: 12px;
  color: var(--ink-dim);
}

.place-body {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.place-body .meta {
  font-size: 12px;
  color: var(--ink-soft);
}

.place-body .why {
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--ink-dim);
}

/* Сезонное: группы, первая раскрыта. */
.season-group {
  margin-bottom: 8px;
  padding: 12px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.season-group summary {
  display: flex;
  align-items: baseline;
  gap: 8px;
  cursor: pointer;
  list-style: none;
}

.season-group summary::-webkit-details-marker {
  display: none;
}

.season-group summary::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.6px solid var(--lime);
  border-bottom: 1.6px solid var(--lime);
  transform: rotate(-45deg);
  transition: transform 0.18s ease;
}

.season-group[open] summary::before {
  transform: rotate(45deg);
}

.season-items {
  margin-top: 12px;
}

.why.personal {
  color: var(--lime);
}

/* Хвост полок города — под раскрытие: наверху свои кухни и сильнейшие. */
.city-more {
  margin-bottom: 20px;
}

.city-more > summary {
  padding: 12px 14px;
  font-size: 13.5px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  cursor: pointer;
  list-style: none;
}

.city-more > summary::-webkit-details-marker {
  display: none;
}

.city-more[open] > summary {
  margin-bottom: 16px;
  color: var(--lime);
  border-color: var(--line-accent);
}

/* ══ Десктоп · §26 ═════════════════════════════════════
   Было: та же колонка 620 px по центру и нижняя панель, растянутая на весь
   экран, — «растянутый мобильный», прямо названная претензия из RESEARCH §0.
   Стало: навигация уходит в левую колонку, лента раскладывается в две
   неравные колонки. Асимметрия здесь не украшение: одинаковые колонки дают
   ровно ту же плоскую сетку, от которой уходим.

   Порог 1024 px, а не 768: на планшете в портрете нижняя навигация под
   большим пальцем удобнее боковой. */
@media (min-width: 1024px) {
  .tabs {
    top: 0;
    right: auto;
    bottom: 0;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    width: 208px;
    height: 100vh;
    padding: 28px 16px;
    border-top: none;
    border-right: 1px solid var(--line);
  }

  .tabs button {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    width: 100%;
    min-height: 46px;
    padding: 10px 14px;
    font-size: 14px;
    text-align: left;
  }

  .tabs button::before {
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
  }

  .tabs button.active {
    background: var(--bg-raised);
  }

  /* Центральная кнопка на десктопе перестаёт быть центральной: в вертикальном
     списке «центр» ничего не значит, поэтому Ремикс выделяется цветом. */
  .tabs button.center::before {
    width: 18px;
    height: 18px;
  }

  .shell {
    max-width: 1180px;
    margin-left: 208px;
    padding: 44px 48px 64px;
  }

  /* Лента: две неравные колонки. Ведущая карточка и полки кухонь занимают
     всю ширину — им нужен размах; остальное укладывается плиткой. */
  #home-feed {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    gap: 16px;
    align-items: start;
    /* dense, потому что полки занимают всю ширину: без плотной упаковки
       рядом с одиночной карточкой оставалась дыра в половину экрана.
       Порядок карточек в ленте при этом не смысловой — секции независимы. */
    grid-auto-flow: dense;
  }

  #home-feed > .feed.lead-card,
  #home-feed > .feed.shelf {
    grid-column: 1 / -1;
  }

  /* На широком экране пропорция 16:10 даёт картинку в пол-окна: на телефоне
     это герой, на десктопе — заставка, за которой не видно самой ленты.
     Поэтому здесь ограничение по высоте, а не только по пропорции. */
  .dish-photo.lead {
    aspect-ratio: 21 / 9;
    max-height: 300px;
  }

  /* Полки шире — в ряд помещается больше карточек, и горизонтальная
     прокрутка перестаёт быть обязательной. */
  .shelf-card {
    flex-basis: 172px;
  }

  .panel-title {
    font-size: 42px;
  }

  /* Разворот рецепта: раскладка продуктов и шаги рядом, а не друг под другом —
     на широком экране колонка текста в 1100 px нечитаема. */
  .levels {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
  }

  /* Профиль вкуса: радар и оси рядом. */
  .dna-card {
    display: grid;
    grid-template-columns: 340px 1fr;
    gap: 24px;
    align-items: start;
  }

  .dna-head,
  .dna-card > .muted {
    grid-column: 1 / -1;
  }

  .kit-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }

  .onb-sheet {
    align-self: center;
    border-radius: 22px;
    border-bottom: 1px solid var(--line-accent);
  }

  .onb {
    align-items: center;
  }
}

/* Очень широкие экраны: колонка текста не должна расползаться до края —
   строка длиннее ~90 знаков перестаёт читаться. */
@media (min-width: 1600px) {
  .shell {
    max-width: 1320px;
  }

  #home-feed {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}

/* ── Свои рецепты ──────────────────────────────────────
   Форма намеренно скучная: три поля и кнопка. Всё интересное происходит
   после разбора, а не в самом вводе. */
.rec-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}

.rec-row {
  display: flex;
  gap: 10px;
}

.rec-row select {
  flex: 1;
}

.rec-row input[type='number'] {
  width: 96px;
}

textarea,
select,
input[type='number'] {
  padding: 13px 15px;
  font: 400 15px var(--font-body);
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  resize: vertical;
}

textarea:focus,
select:focus,
input[type='number']:focus {
  outline: none;
  border-color: var(--line-accent);
}

.rec-actions {
  display: flex;
  gap: 10px;
}

.rec-similar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0;
}

/* Заголовок блока — отдельная строка, а не первый элемент в ряду карточек:
   иначе короткая метка и длинное название блюда встают бок о бок и читаются
   как одна строка. */
.rec-similar > .feed-label {
  flex: 0 0 100%;
}

.rec-sim {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 12px;
  text-align: left;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
}

.rec-sim:hover {
  border-color: var(--line-accent);
}

.rec-sim b {
  font-size: 13.5px;
  font-weight: 500;
}

.rec-sim span {
  font: 400 11px var(--font-mono);
  color: var(--ink-dim);
}

.rec-sug {
  padding: 13px 0;
  border-top: 1px solid var(--line);
}

.rec-sug b {
  font-size: 15px;
}

.rec-sug p {
  margin: 4px 0 10px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

.rec-steps {
  margin: 10px 0 0 18px;
  font-size: 14px;
  color: var(--ink-soft);
}

.rec-steps li {
  margin-bottom: 5px;
}

.rec-card-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.ghost-btn.danger {
  color: var(--bad);
  border-color: rgba(232, 112, 95, 0.3);
}

/* Пустое состояние: говорит, что делать, а не констатирует пустоту. */
.feed.empty {
  color: var(--ink-soft);
  border-style: dashed;
}

/* ── Приёмы ────────────────────────────────────────────
   Зона свёрнута, приём внутри свёрнут: тридцать два приёма в развёрнутом
   виде — это опять простыня, от которой мы ушли в «Городе». */
/* Карточка утвари: сворачивается, когда инвентарь отмечен, — дальше экран
   про приёмы, а не про список из 57 плиток. */
.kitchen-card > summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  cursor: pointer;
  list-style: none;
}

.kitchen-card > summary::-webkit-details-marker {
  display: none;
}

.kitchen-card > summary b {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.kitchen-card > summary::after {
  content: '▾';
  margin-left: auto;
  color: var(--foodos-color-ink-dim);
  transition: transform var(--foodos-motion-fade);
}

.kitchen-card[open] > summary::after {
  transform: rotate(180deg);
}

.tech-zone {
  margin-bottom: 8px;
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.tech-zone > summary,
.tech > summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  cursor: pointer;
  list-style: none;
}

.tech-zone > summary::-webkit-details-marker,
.tech > summary::-webkit-details-marker {
  display: none;
}

.tech-zone > summary::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.6px solid var(--lime);
  border-bottom: 1.6px solid var(--lime);
  transform: rotate(-45deg);
  transition: transform 0.18s ease;
}

.tech-zone[open] > summary::before {
  transform: rotate(45deg);
}

.tech-zone-lede {
  margin: 8px 0 12px;
}

.tech {
  padding: 12px 0;
  border-top: 1px solid var(--line);
}

.tech-zone > .tech:first-of-type {
  border-top: none;
}

.tech-meta {
  font: 400 11px var(--font-mono);
  color: var(--ink-dim);
}

/* Отметка «это про то, что вы сейчас учите» — единственное место, где приём
   спорит с алфавитным порядком. */
.tech-mark {
  padding: 2px 8px;
  font: 500 10.5px/1.6 var(--font-mono);
  border-radius: 999px;
}

.tech-mark.train {
  color: #0b0512;
  background: var(--lime);
}

.tech-mark.love {
  color: var(--mint);
  border: 1px solid rgba(123, 227, 138, 0.35);
}

.tech-body {
  padding-top: 10px;
}

.tech-gives {
  font-size: 14px;
  color: var(--ink-soft);
}

.tech-axes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0;
}

.tech-axes span {
  padding: 3px 9px;
  font: 400 11.5px var(--font-mono);
  color: var(--ink-dim);
  background: var(--bg-sunken);
  border-radius: 999px;
}

.tech-mistake {
  margin-top: 10px;
  padding: 10px 12px;
  font-size: 13.5px;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border-left: 2px solid var(--bad);
  border-radius: 0 var(--r-input) var(--r-input) 0;
}

.tech-ready {
  color: var(--good);
}

/* ── Тренды ────────────────────────────────────────────
   Вердикт стоит рядом с названием, а не прячется внутри: половина пользы
   раздела — сказать, что тренд пустой. */
.trend {
  margin-bottom: 8px;
  padding: 13px 15px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.trend > summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  cursor: pointer;
  list-style: none;
}

.trend > summary::-webkit-details-marker {
  display: none;
}

.trend-verdict {
  padding: 2px 8px;
  font: 500 10.5px/1.6 var(--font-mono);
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
}

.trend[data-verdict='стоит'] .trend-verdict {
  color: var(--good);
  border-color: rgba(123, 227, 138, 0.35);
}

.trend[data-verdict='мимо'] {
  opacity: 0.72;
}

.trend[data-verdict='мимо'] .trend-verdict {
  color: var(--bad);
  border-color: rgba(232, 112, 95, 0.3);
}

.trend-why {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* Возраст снимка. Просроченный — предупреждение, а не мелкий шрифт. */
#trends-note.stale {
  color: var(--bad);
}

/* ── §24 Я в магазине ──────────────────────────────────
   Тот же лист снизу, что у онбординга: у полки телефон держат одной рукой,
   и всё важное должно быть в нижней трети экрана. */
.store-takes {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin-bottom: 18px;
  padding-bottom: 4px;
  scrollbar-width: none;
}

.store-takes::-webkit-scrollbar {
  display: none;
}

.store-take {
  flex: 0 0 150px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 11px 13px;
  text-align: left;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
}

.store-take:hover {
  border-color: var(--line-accent);
}

.store-take b {
  font-size: 14px;
  font-weight: 500;
}

.store-take span {
  font: 400 10.5px var(--font-mono);
  color: var(--lime);
}

.store-take em {
  font-style: normal;
  font-size: 12px;
  color: var(--ink-dim);
  line-height: 1.35;
}

.store-idea {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--line);
}

.store-idea b {
  display: block;
  font-size: 14.5px;
}

.store-form {
  display: flex;
  gap: 8px;
  margin: 12px 0;
}

.store-form input {
  flex: 1;
  min-height: 44px;
}

.store-list {
  list-style: none;
  margin-bottom: 12px;
}

.store-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}

.store-list li.done span {
  color: var(--ink-dim);
  text-decoration: line-through;
}

.store-list li span {
  flex: 1;
  font-size: 15px;
}

.store-list li em {
  font-style: normal;
  font: 400 10.5px var(--font-mono);
  color: var(--ink-dim);
}

/* Галочка крупная: её жмут в магазине, часто не глядя. */
.store-check {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  font-size: 15px;
  color: #0b0512;
  background: transparent;
  border: 1.5px solid var(--line);
  border-radius: 9px;
}

.store-list li.done .store-check {
  background: var(--lime);
  border-color: var(--lime);
}

.store-del {
  padding: 4px 8px;
  font-size: 18px;
  color: var(--ink-dim);
  background: none;
  border: none;
}

.feed-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ── Композиционная вариативность ──────────────────────
   Претензия из RESEARCH §0: все карточки одной ширины и плотности, отчего
   лента читается как таблица. Иерархия задаётся тремя весами:
     герой   — фото во всю ширину, крупный заголовок;
     полка   — горизонтальный ряд, тоже во всю ширину;
     сводка  — компактная карточка: мельче шрифт, плотнее отступы.
   На экране от 520 px сводки встают парой, и лента перестаёт быть столбиком
   одинаковых прямоугольников. */
.feed.compact {
  padding: 15px 16px;
}

.feed.compact h2 {
  font-size: 18px;
}

.feed.compact p {
  font-size: 14px;
}

@media (min-width: 520px) and (max-width: 1023px) {
  #home-feed {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    align-items: start;
    grid-auto-flow: dense;
  }

  #home-feed > .feed {
    margin-bottom: 0;
    grid-column: 1 / -1;
  }

  /* Парой встают только сводки — им хватает половины ширины. */
  #home-feed > .feed.compact {
    grid-column: auto;
  }
}

/* ── Подвал: права субъекта ПД ─────────────────────────
   Кнопки удаления и просмотра данных стоят в подвале каждого экрана,
   а не прячутся в настройках: право по ст. 14 152-ФЗ должно быть доступным,
   а не спрятанным. */
.foot-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
}

.foot-actions a,
.linkish {
  padding: 0;
  font: 400 13px var(--font-body);
  color: var(--ink-soft);
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
}

.foot-actions a:hover,
.linkish:hover {
  color: var(--lime);
  border-color: var(--line-accent);
}

.linkish.danger:hover {
  color: var(--bad);
  border-color: rgba(232, 112, 95, 0.4);
}

.me-card {
  margin-top: 14px;
}

.me-card h3 {
  margin-bottom: 8px;
  font-size: 16px;
}

/* ── Документ (политика) ───────────────────────────── */
.doc .doc-p {
  margin-bottom: 14px;
  color: var(--ink-soft);
}

.doc-list {
  margin: 0 0 14px 18px;
  color: var(--ink-soft);
}

.doc-list li {
  margin-bottom: 6px;
}

.doc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.doc-table th,
.doc-table td {
  padding: 9px 8px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}

.doc-table th {
  font: 500 10.5px/1.6 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.doc-table td {
  color: var(--ink-soft);
}

.doc a {
  color: var(--lime);
}

/* Продукт, чужой для кухни блюда. Пометка, а не запрет: на верхних уровнях
   новизны чужеродность — замысел, и решает человек, а не мы за него. */
.ing.unusual {
  border-color: rgba(217, 110, 60, 0.4);
}

.unusual-mark {
  display: block;
  margin-top: 2px;
  font: 400 9.5px/1.4 var(--font-mono);
  color: var(--clay);
}
