/* Оформление простое и функциональное (спека 1).

   Палитра тёплая зелёная: решение владельца 26 августа по двум образцам.
   Раскладка — направление «ритм»: приёмы, волны и разделы делит волосяная
   линия и воздух, вес несут размер и регистр. Рамок нет нигде, где их
   можно не ставить: на 390 px рамка в рамке съедает 28 px ширины,
   а читают отсюда список покупок стоя в магазине.

   ЦВЕТ ЗНАЧИТ, А НЕ УКРАШАЕТ. Зелёный — действие: кнопки, ссылки, текущий
   пункт. Жёлтый — место: «сегодня» в ленте, ближайшая волна покупок,
   главное число карточки. Два акцента не спорят, пока значат разное;
   как только жёлтый начнёт красить кнопки, оба перестанут сообщать. */

/* ОБЕ ПАЛИТРЫ ОБЪЯВЛЕНЫ ЗДЕСЬ И ТОЛЬКО ЗДЕСЬ — по одному значению на цвет.
   Три блока ниже ничего не объявляют, они лишь ВЫБИРАЮТ набор. Значение,
   записанное дважды, разойдётся при первой правке (урок 9); имя,
   назначенное дважды, — нет.

   Сторож — `ThemeTokenTests`: сверяет, что у каждого `--light-*` есть
   `--dark-*`, и что оба блока выбора назначают один и тот же перечень
   имён. Прогон страницу не рисует, `@media` и `[data-theme]` ему не видны
   по построению (урок 29), поэтому проверяется текст правила. */
/* ОБЕ ПАЛИТРЫ ОБЪЯВЛЕНЫ ЗДЕСЬ И ТОЛЬКО ЗДЕСЬ — по одному значению на цвет.
   Три блока ниже ничего не объявляют, они лишь ВЫБИРАЮТ набор. Значение,
   записанное дважды, разойдётся при первой правке (урок 9); имя,
   назначенное дважды, — нет.

   Сторожа в `TemplateHygieneTests`: у каждого `--light-*` есть `--dark-*`,
   оба блока выбора назначают один перечень имён, и явный выбор стоит после
   системного. Прогон страницу не рисует, `@media` и `[data-theme]` ему
   не видны по построению (урок 29), поэтому проверяется текст правила. */
:root {
  --light-bg: #eceedc;
  --light-fg: #2e3c1d;
  --light-muted: #586042;
  --light-line: #c7cbb4;
  --light-accent: #4a5c28;
  --light-accent-hover: #33401b;
  --light-button: #4a5c28;
  --light-button-fg: #eceedc;
  --light-button-hover: #33401b;
  --light-mark: #755800;
  --light-mark-rule: #d9b23a;
  --light-bad: #9d3a29;
  --light-good: #3d6b34;

  /* Тёмная снята с НИЖНЕЙ части образца (решение владельца 27 августа):
     фон #15221c — тон 150, светлота 11 %. До этого стояло 138° и 5 %,
     то есть зелёный был уведён в желтизну и перетемнён разом.

     Текст СЧИТАЕТСЯ НАЛОЖЕНИЕМ, а не подбирается: основной — белый 95 %
     поверх фона, второстепенный — 62 %, линия — 14 %. «Как будто чуть
     прозрачный текст» — это буквально описание того, как он получен,
     отсюда и характер: тон 150 при насыщенности 3 %.

     Буквальную копию образца брать нельзя: самый светлый текст в его
     подвале — 31 % светлоты, там он почти нечитаем. Это рекламный рендер,
     читаемость ему не нужна, а список покупок читают в магазине. */
  --dark-bg: #15221c;
  --dark-fg: #f3f4f4;
  --dark-muted: #a6aba9;
  --dark-line: #36413c;
  --dark-accent: #98cdb2;
  --dark-accent-hover: #c0e3d1;
  /* Заливка кнопок в тёмной теме — жёлтая, а не зелёная (выбор владельца
     27 августа из двух показанных вариантов). Отсюда отдельная пара имён:
     ссылка и кнопка в тёмной теме разного цвета, в светлой — одного,
     и подстановкой одного токена это не выражается.

     Цена названа вслух: жёлтый теперь и действие, и место («сегодня»,
     ближайшая волна). Различает их форма — заливка против волосяной
     полосы, — а не цвет. */
  --dark-button: #e8c34a;
  --dark-button-fg: #15221c;
  --dark-button-hover: #f1d67e;
  --dark-mark: #e8c34a;
  --dark-mark-rule: #d9a92e;
  --dark-bad: #e2988d;
  --dark-good: #98cd98;

  --bg: var(--light-bg);
  --fg: var(--light-fg);
  --muted: var(--light-muted);
  --line: var(--light-line);
  --accent: var(--light-accent);
  --accent-hover: var(--light-accent-hover);
  --button: var(--light-button);
  --button-fg: var(--light-button-fg);
  --button-hover: var(--light-button-hover);
  --mark: var(--light-mark);
  --mark-rule: var(--light-mark-rule);
  --bad: var(--light-bad);
  --good: var(--light-good);
}

/* Умолчание — тема системы. Явный выбор «светлая» её перебивает. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: var(--dark-bg);
    --fg: var(--dark-fg);
    --muted: var(--dark-muted);
    --line: var(--dark-line);
    --accent: var(--dark-accent);
    --accent-hover: var(--dark-accent-hover);
    --button: var(--dark-button);
    --button-fg: var(--dark-button-fg);
    --button-hover: var(--dark-button-hover);
    --mark: var(--dark-mark);
    --mark-rule: var(--dark-mark-rule);
    --bad: var(--dark-bad);
    --good: var(--dark-good);
  }
}

/* Явный выбор «тёмная» — ПОСЛЕ медиазапроса: вес селекторов одинаков,
   и решает порядок. Иначе выбор не сработал бы у того, у кого система
   светлая, — то есть ровно у того, кто его сделал. */
:root[data-theme="dark"] {
  --bg: var(--dark-bg);
  --fg: var(--dark-fg);
  --muted: var(--dark-muted);
  --line: var(--dark-line);
  --accent: var(--dark-accent);
  --accent-hover: var(--dark-accent-hover);
  --button: var(--dark-button);
  --button-fg: var(--dark-button-fg);
  --button-hover: var(--dark-button-hover);
  --mark: var(--dark-mark);
  --mark-rule: var(--dark-mark-rule);
  --bad: var(--dark-bad);
  --good: var(--dark-good);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Числа стоят столбцами почти везде: КБЖУ, граммы, порции, баланс дня.
     Без табличных цифр колонка «1840 из 1900» дрожит по ширине знаков. */
  font-variant-numeric: tabular-nums;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  /* Ряд по центру: он единственное содержимое полосы с тех пор, как ушёл
     бренд слева, и прижатый к краю выглядел бы обрезанным
     (решение владельца 26 августа) */
  justify-content: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--line);
}

/* Переносится не только сама шапка, но и список ссылок внутри неё.
   Без `flex-wrap` он выстраивался в одну строку и выпирал за экран —
   горизонтальная прокрутка на телефоне, то есть отказ по критерию
   готовности этапа 6. Нашёл владелец на боевом; поводом стал девятый
   пункт «Покупки», но причина была здесь с самого начала */
.site-header nav {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: baseline;
}
.site-header .who { color: var(--muted); }

a { color: var(--accent); }
a:hover { color: var(--accent-hover); }

main { max-width: 46rem; margin: 0 auto; padding: 1.5rem 1rem 4rem; }

h1 { font-size: 1.5rem; line-height: 1.25; letter-spacing: -0.01em; margin: 0 0 0.5rem; }
h2 { font-size: 1.25rem; line-height: 1.3; letter-spacing: -0.01em; }

/* Подпись раздела: мелко, в верхнем регистре, вразрядку, приглушённо.

   Одно правило на весь проект, а не три похожих: так набраны и категории
   списка покупок, и приёмы пищи в ленте, и разделы карточки рецепта.
   Разъехавшись, они читались бы как три разных вида заголовка. */
.label, .wave h3, .feed-day h4 {
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); font-weight: 600; margin: 0;
}

.messages { list-style: none; margin: 0; padding: 0.5rem 1rem; }
.messages li { padding: 0.5rem 0.75rem; border-left: 3px solid var(--accent); }
.messages li.error { border-left-color: var(--bad); }
.messages li.success { border-left-color: var(--good); }

/* Формы */
.stack p { margin: 0 0 0.9rem; }
.stack label { display: block; font-weight: 600; }
.stack input, .stack textarea {
  width: 100%; padding: 0.5rem; font: inherit;
  border: 1px solid var(--line); border-radius: 4px;
  background: var(--bg); color: var(--fg);
}
.stack .helptext { display: block; color: var(--muted); font-size: 0.87rem; }
.stack ul.errorlist { margin: 0.2rem 0; padding-left: 1rem; color: var(--bad); }

/* Цель для пальца — не меньше 44 px. Отмечают приёмы и покупки стоя,
   одной рукой, часто в перчатке: кнопка в 40 px промахивается. */
button {
  min-height: 44px; padding: 0.5rem 1rem; font: inherit; cursor: pointer;
  border: 1px solid var(--button); border-radius: 4px;
  background: var(--button); color: var(--button-fg);
}
button:hover { background: var(--button-hover); border-color: var(--button-hover); }
.warn { border-left: 3px solid var(--bad); padding-left: 0.75rem; }

/* Списки с действиями */
.rows { list-style: none; padding: 0; }
/* СТРОКА СПИСКА: содержимое сверху, действия отдельной строкой снизу —
   всегда, на любой ширине.

   Раньше действия стояли справа от содержимого и переносились сами, когда
   не помещались. Значит их место зависело от ДЛИНЫ НАЗВАНИЯ БЛЮДА: «Пицца»
   оставляла кнопку справа, «Лосось с начинкой и пюре из цветной капусты»
   сбрасывал её вниз. Один и тот же список выглядел по-разному в соседних
   строках. Нашёл владелец глазами 27 августа; прогон такого не видит
   по построению — он не рисует и ширин не считает (урок 29). */
.rows li {
  display: flex; flex-direction: column; align-items: stretch; gap: 0.5rem;
  padding: 0.7rem 0; border-bottom: 1px solid var(--line);
}
/* Перенос — всегда, а не только в медиазапросе: «узкий экран» это
   не только телефон, это ещё и длинное название в `select`, и увеличенный
   шрифт, и половина экрана в сплите. Панель «Добавить партию» дала
   горизонтальную прокрутку на боевом именно так — нашёл владелец на
   этапе 8, глазами. Тестом это не ловится по построению: прогон не рисует. */
.inline {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
}

/* РЯД ДЕЙСТВИЙ: равные доли, то же правило, что в верхней полосе.

   `flex` раздаёт ширину по длине подписи, и рядом вставали кнопки разного
   размера: «Убрать» вдвое уже «Не приготовлено». Сетка с автозаполнением
   даёт равные ячейки и не растягивает одинокую кнопку на всю строку —
   `auto-fill`, а не `auto-fit`: пустые дорожки остаются пустыми.

   10rem — не украшение: столько нужно самой длинной подписи
   («Не приготовлено») и полю даты, которое ниже 10rem обрезает
   собственный виджет. */
.actions {
  display: grid; gap: 0.5rem; align-items: center;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
.actions > * { margin: 0; }
/* Внутри ячейки почти всегда форма с одной кнопкой: без растяжения кнопка
   осталась бы шириной по подписи, и равные ячейки не дали бы равных кнопок. */
.actions form { margin: 0; }
.actions button { width: 100%; }

/* Вторичное действие не спорит с главным. В строке одна залитая кнопка —
   та, ради которой строка и существует; «Убрать», «Не приготовлено»,
   «Не ел» и отмены выглядят обводкой. Три залитых прямоугольника подряд
   не сообщают, какой из них обычный путь. */
button.quiet {
  background: none; color: var(--accent); border-color: var(--line);
}
button.quiet:hover {
  background: none; color: var(--accent-hover); border-color: var(--accent);
}
/* Ни один элемент управления не шире того, во что положен. Правило общее,
   а не про ту панель, где увидели: `select` без `min-width: 0` не сжимается
   ниже самого длинного варианта, а варианты здесь — названия блюд
   вроде «Мидии с сырно-чесночной шапочкой». */
select, input, textarea, button { max-width: 100%; }
select { min-width: 0; }
.rows form, .inline form { margin: 0; }
/* Правило про поля ввода, а не про все input: чекбокс, растянутый
   на 12rem и с отступом в полстроки, уводит галочку от подписи. */
.inline input:not([type="checkbox"]):not([type="radio"]) {
  flex: 1 1 12rem; padding: 0.5rem; font: inherit;
  border: 1px solid var(--line); border-radius: 4px;
  background: var(--bg); color: var(--fg); }

/* Ссылки-действия */
.cta { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; margin-top: 1.5rem; }
a.button {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0.5rem 1rem; text-decoration: none;
  border: 1px solid var(--button); border-radius: 4px;
  background: var(--button); color: var(--button-fg);
}
/* Второстепенное действие выглядит ссылкой, а не второй кнопкой: две
   залитые кнопки рядом — это выбор без подсказки, какая главная.
   Форма при этом настоящая, с токеном в теле (урок 17). */
.linkform { margin: 0; }
.linkform button {
  min-height: 0; padding: 0; border: none; background: none;
  color: var(--accent); font: inherit; cursor: pointer; text-decoration: underline;
}
.linkform button:hover { background: none; color: var(--accent-hover); }

.badge {
  padding: 0.1rem 0.5rem; border-radius: 999px;
  background: var(--button); color: var(--button-fg); text-decoration: none;
}

.muted { color: var(--muted); font-size: 0.9rem; }

/* Таблицы состава и справочников (этап 3) */
.grid { width: 100%; border-collapse: collapse; margin: 0.5rem 0 1.5rem; }
.grid th, .grid td { padding: 0.45rem 0.5rem 0.45rem 0.1rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: baseline; }
.grid th { font-size: 0.85rem; color: var(--muted); font-weight: 600; }
.grid .num, .grid th.num { text-align: right; white-space: nowrap; color: var(--muted); }
.grid tr.total td { font-weight: 600; border-top: 2px solid var(--line); border-bottom: none; }

.num { text-align: right; }

/* Главное число карточки: калорийность порции. Жёлтая полоса значит
   «вот оно» — то же, что «сегодня» в ленте и ближайшая волна в покупках. */
.lead {
  font-size: 1.35rem; line-height: 1.2;
  padding-left: 0.7rem; border-left: 4px solid var(--mark-rule);
}
.lead b { font-weight: 700; }
.lead-macros { display: block; font-size: 0.95rem; color: var(--muted); }
.tag {
  display: inline-block; padding: 0 0.4rem; margin-left: 0.3rem;
  font-size: 0.75rem; border: 1px solid var(--line); border-radius: 3px;
  color: var(--muted);
}
.note { border-left: 3px solid var(--accent); padding-left: 0.75rem; color: var(--muted); }

/* На телефоне широкая таблица должна прокручиваться, а не ломать страницу:
   список покупок в магазине — обязательный сценарий (спека 1) */
@media (max-width: 30rem) {
  .grid { display: block; overflow-x: auto; }
  /* На узком экране шапка иначе занимает четыре строки и уводит список
     покупок за первый экран — а его читают стоя в магазине */
  .site-header { padding: 0.6rem 0.8rem; }
  .site-header nav { gap: 0.35rem 0.75rem; font-size: 0.95rem; }
  /* Отступы внутри кнопки ужимаются раньше, чем слово начнёт переноситься:
     на 390 px доля кнопки 86 px, и 0.4rem по краям оставляют слову 73 px
     против 60 при прежних 0.6rem. «Питание» занимает 59 */
  .site-header nav.doings { gap: 0.3rem; }
  .site-header nav.doings a { padding: 0.5rem 0.4rem; }
}

/* Избранное */
.fav { margin: 0; }
.fav button { padding: 0.3rem 0.7rem; font-size: 0.9rem; white-space: nowrap; }
.fav button.fav-off { background: none; color: var(--accent); }
.fav button.fav-off:hover { background: none; color: var(--accent-hover); }

.archived-block { margin-top: 0.4rem; }
.archived-block summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.archived-block ul { margin: 0.3rem 0 0; }

/* Фотографии рецепта */
.photos { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1rem 0; }
.photos img { max-width: 100%; max-height: 18rem; border-radius: 4px; }

/* Импорт рецепта (этап 3б) */
.import-split { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
.import-source { flex: 1 1 20rem; }
.import-form { flex: 2 1 26rem; }
.import-source pre {
  white-space: pre-wrap; font: 0.9rem/1.5 inherit;
  padding: 0.75rem; border: 1px solid var(--line); border-radius: 4px;
  max-height: 32rem; overflow-y: auto;
}
.hint { font-size: 0.85rem; color: var(--muted); }

/* Четыре класса пометок — у каждого своё действие, поэтому и свой цвет */
.mark-product_unknown      { background: rgba(157, 58, 41, 0.10); }
.mark-measure_unknown      { background: rgba(217, 178, 58, 0.20); }
.mark-amount_defaulted     { background: rgba(61, 107, 52, 0.12); }
.mark-product_without_kbju { background: rgba(157, 58, 41, 0.20); }
.mark-excluded             { opacity: 0.55; }

/* Список покупок (этап 6).

   Читают его с телефона в магазине, одной рукой, часто в перчатке. Отсюда
   всё остальное: строка — цель для касания во всю ширину, а не галочка
   в пять миллиметров; шрифт крупный; горизонтальной прокрутки нет вовсе,
   поэтому здесь список, а не таблица. Это критерий готовности этапа,
   а не полировка. */
.wave { margin: 1.5rem 0; }
.wave h2 { margin-bottom: 0.1rem; }
.wave h3 { margin: 1rem 0 0.3rem; }
/* Ближайшая волна помечена жёлтым — тем же, чем «сегодня» в ленте: это
   «где вы сейчас». Класс ставит шаблон по `forloop.first`, а не стили
   по `:first-of-type`: под тем же классом идут «Куплено сверх плана»
   и «Уже куплено», и выборка по порядку пометила бы их, стоило первой
   волне исчезнуть. */
.wave--now > h2 { padding-left: 0.7rem; border-left: 4px solid var(--mark-rule); }
.wave--now > p { padding-left: 0.7rem; }
ul.buy { list-style: none; margin: 0; padding: 0; }
ul.buy li { border-bottom: 1px solid var(--line); }
ul.buy li > form { margin: 0; }
ul.buy li button,
ul.buy li > span:first-child {
  display: flex; align-items: baseline; gap: 0.6rem; width: 100%;
  min-height: 44px; padding: 0.85rem 0.2rem; font-size: 1.05rem; text-align: left;
  background: none; color: inherit; border: none; cursor: pointer;
}
ul.buy li button:hover { background: none; color: inherit; }
ul.buy li button:disabled { cursor: default; opacity: 1; }
ul.buy .tick { width: 1.2rem; flex: none; color: var(--accent); }
ul.buy .what { flex: 1 1 auto; }
ul.buy .how-much { flex: none; color: var(--muted); white-space: nowrap; }
ul.buy li.done .what { text-decoration: line-through; opacity: 0.6; }
ul.buy li > p { margin: 0 0 0.6rem 1.8rem; font-size: 0.85rem; }
/* Строки без формы (сверх плана, уже куплено, обычно есть дома) выровнены
   с отмечаемыми: разъехавшиеся колонки читаются как разные списки */
ul.buy li > span.what { padding-left: 1.8rem; }
/* Заголовок волны называет период покупки; период — второстепенная
   часть заголовка, тем же весом, но тише */
.wave h2 .period { color: var(--muted); font-weight: inherit; white-space: nowrap; }
/* «Куплено» спрашивает «сколько» (этап 10). Строка-summary выглядит как
   прежняя кнопка — тот же ряд «значок · продукт · сколько», чтобы список
   не менял вида от того, спрашивает он или нет. Маркер раскрытия убран:
   значок ○ и есть маркер. */
ul.buy li details.buy-ask > summary {
  display: flex; align-items: baseline; gap: 0.6rem; width: 100%;
  min-height: 44px; padding: 0.85rem 0.2rem; font-size: 1.05rem;
  cursor: pointer; list-style: none;
}
ul.buy li details.buy-ask > summary::-webkit-details-marker { display: none; }
ul.buy li details.buy-ask[open] > summary .tick { color: var(--mark-rule); }
/* Ответы на «сколько» — гибкой строкой, как `.inline`: две кнопки-числа
   и поле разной природы, равные доли здесь не подходят */
.buy-how {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  margin: 0 0 0.8rem 1.8rem;
}
.buy-how form { margin: 0; }
.buy-how form.inline { flex: 1 1 14rem; }
.buy-how form.inline input[type="text"] { flex: 1 1 5rem; }
.buy-how button { min-height: 40px; }

/* Карточка готовки (этап 10): рецепт в объёме сессии. Несколько карточек
   на странице источников блюда делит воздух и линия, как всё в проекте */
.cook-card { margin: 1.5rem 0 2rem; }
.cook-card + .cook-card { padding-top: 1.5rem; border-top: 1px solid var(--line); }
.cook-card h2:not(.label) { margin-bottom: 0.2rem; }
/* Отчёт бота на странице плана — раскрыт по умолчанию: ради него сюда
   и смотрят после генерации; свернуть можно */
.bot-report { margin-top: 0.8rem; }
.bot-report summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.bot-report p { margin: 0.4rem 0 0; white-space: pre-line; }

/* План готовки (этап 6): что готовить и на сколько разойдётся */
ul.rows.cook li { align-items: flex-start; padding: 0.9rem 0; }
.cook-what { display: flex; flex-direction: column; gap: 0.15rem; }
.cook-what strong { font-weight: 600; font-size: 1.05rem; line-height: 1.35; }
.cook-what .muted { font-size: 0.88rem; }

/* Ссылки на производные плана — сразу под заголовком: то, что лежит ниже
   суточной раскладки, на месячном плане не находят */
.plan-links { display: flex; flex-wrap: wrap; gap: 1rem; margin: 0.5rem 0 1rem; }

/* ─── Этап 8: полировка ─────────────────────────────────────────────── */

/* Навигатор дней плана. Сеткой, а не строкой ссылок: на телефоне месячный
   план это тридцать целей для касания вплотную друг к другу. Минимальный
   размер цели — 44 px. */
nav.days {
  display: flex; flex-wrap: wrap; gap: 0.3rem;
  margin: 0.5rem 0 1rem;
}
nav.days a, nav.days strong {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 0.3rem;
  border: 1px solid var(--line); border-radius: 4px;
  text-decoration: none; font-weight: normal;
}
nav.days .day-now {
  background: var(--button); color: var(--button-fg); border-color: var(--button);
  font-weight: 600;
}
/* Сегодняшний день — рамкой, а не заливкой: заливка спорила бы с текущим */
nav.days .day-today { border-color: var(--mark-rule); border-width: 2px; }

/* Чат с ботом */
.chat-topic { display: flex; flex-wrap: wrap; gap: 1rem; align-items: baseline; }
.bot-block { display: block; }
.bot-line { border-left: 3px solid var(--line); padding-left: 0.75rem; margin: 0.8rem 0; }
.bot-line--user { border-left-color: var(--accent); }
.bot-line p { margin: 0.2rem 0; }
.ask-bot { border-left: 3px solid var(--accent); padding-left: 0.75rem; color: var(--muted); }

.balance-all summary { cursor: pointer; color: var(--accent); }
.balance-all { margin: 1rem 0 2rem; }

/* На узком экране разъезжается всё, что стояло в строку. Проверяется
   глазами на боевом: прогон не рисует, и `@media` тестом не ловится
   по построению. */
@media (max-width: 30rem) {
  nav.days { gap: 0.25rem; }
  .chat-topic { gap: 0.5rem; }
}

/* ─── Этап 9: верхняя полоса дел ─────────────────────────────────────── */

/* Полоса перечисляет дела, а не разделы, поэтому кнопки крупные и равные:
   это цели для пальца, а не список ссылок.

   РАВНЫЕ ДОЛИ, А НЕ ШИРИНА ПО СОДЕРЖИМОМУ. `flex` по умолчанию раздаёт
   ширину по длине подписи, и ряд получался ступенькой: «Кухня» вдвое уже
   «Личного кабинета», а вчетвером они требовали 470 px и переносились
   на второй ряд. `flex: 1 1 0` делит ширину поровну независимо от слова.
   Нашёл владелец на макете; тестом это не ловится по построению —
   прогон не рисует и ширин не считает (урок 29).

   Ряд при этом не шире содержимого страницы: без потолка четыре кнопки
   растянулись бы на всю ширину монитора, а колонка текста под ними —
   на 46rem. */
.site-header nav.doings {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  align-items: stretch; justify-content: center;
  width: 100%; max-width: 46rem; margin: 0 auto;
}
.site-header nav.doings a {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 1 1 0; min-width: 0; text-align: center;
  padding: 0.5rem 0.6rem; min-height: 44px;
  border: 1px solid var(--line); border-radius: 4px;
  text-decoration: none;
}

/* Полоса «Кухни»: два раздела под одной кнопкой верхнего ряда */
nav.tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; }
nav.tabs a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0.4rem 0.9rem; border: 1px solid var(--line); border-radius: 4px;
  text-decoration: none;
}
nav.tabs .tab-now {
  background: var(--button); color: var(--button-fg); border-color: var(--button);
}

/* Приглашение обязано быть заметным сразу, а не быть счётчиком где-то сбоку */
.invite-banner {
  border: 2px solid var(--accent); border-radius: 4px;
  padding: 0.6rem 0.9rem; margin: 0 0 1rem;
}

/* ─── Лента дня ───────────────────────────────────────────────────────── */

/* До этой правки у ленты не было НИ ОДНОГО правила: `.feed-day`, `.slot`,
   `.by-portion` и `.feed-balance` стояли в разметке, а в стилях их не было.
   Главный экран этапа 9 рисовался потоком заголовков без единой границы
   между приёмами, и «сегодня» отличалось только словом в теге. */
.feed-day { margin: 0 0 2rem; }
.feed-day h2 {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.5rem;
  margin: 0 0 1rem;
}
/* Сегодняшний день — жёлтой полосой: «где вы сейчас». Прошедшие и будущие
   помечены линией того же места, чтобы заголовки не разъезжались влево. */
.feed-day > h2 { padding-left: 0.7rem; border-left: 4px solid var(--line); }
.feed-day--today > h2 { border-left-color: var(--mark-rule); }
.feed-day--today > h2 .tag {
  border: none; padding: 0; margin: 0; color: var(--mark);
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em;
}

.slot { display: flex; flex-direction: column; gap: 0.5rem; margin: 0 0 1.1rem; }
.slot + .slot, .feed-day h4 + ul.rows.cook {
  border-top: 1px solid var(--line); padding-top: 0.9rem;
}
.feed-day h4 { margin-top: 0.9rem; }
.slot .rows { margin: 0; }
.slot .rows li { border-bottom: none; padding: 0; }
/* Название блюда — самое крупное в строке, едоки уходят строкой ниже.
   В разметке они лежат в одном `<span>` подряд: блочный `<strong>`
   разводит их по строкам, не трогая шаблон. */
.slot .rows li > span > strong { display: block; font-size: 1.05rem; line-height: 1.35; }
.slot .rows li > span .muted { font-size: 0.88rem; }
.slot p { margin: 0; }

/* Точечная правка — исключение, поэтому и выглядит ссылкой, а не кнопкой */
.by-portion summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.by-portion form { margin: 0.4rem 0; }

/* Дневной баланс, а не окно недели: окно скользящее, и факт этого дня
   входит в окна следующих семи */
.feed-balance {
  display: flex; flex-direction: column; gap: 0.15rem;
  border-top: 1px solid var(--line); padding-top: 0.9rem; margin: 0.9rem 0 0;
}
.feed-balance p {
  display: flex; justify-content: space-between; gap: 1rem;
  margin: 0; font-size: 0.9rem; color: var(--muted);
}
.feed-balance p span + span { color: var(--fg); white-space: nowrap; }

/* Метки подгрузки ленты. «Вниз» срабатывает сама по появлению в поле
   зрения, «вверх» — по нажатию: прошедшие дни нужны утром, а не при
   каждом открытии. */
.feed-more { margin: 1rem 0; text-align: center; color: var(--muted); }
.feed-more--up button {
  background: none; color: var(--accent); border-color: var(--line);
}
.feed-more--up button:hover { background: none; color: var(--accent-hover); }

/* Разделы формы едока — свои htmx-цели, оформления не несут */
.slots, .macros { display: block; }

/* ─── Выбор темы (личный кабинет) ────────────────────────────────────── */

/* Настройка, которую трогают один раз, а не действие суточного цикла:
   кнопки выглядят ссылками. Три залитых прямоугольника спорили бы
   с «Съели всё», ради которого экран и сделан. */
.theme-pick {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.8rem; align-items: center;
  margin: 0 0 1.5rem;
}
.theme-pick button {
  min-height: 44px; padding: 0 0.4rem; border: none; background: none;
  color: var(--accent); font: inherit; font-size: 0.95rem;
  cursor: pointer; text-decoration: underline;
}
.theme-pick button:hover { background: none; color: var(--accent-hover); }
/* Выбранная — весом и цветом текста, без подчёркивания: подчёркнутое
   читается как «сюда можно нажать», а нажимать уже некуда */
.theme-pick button.theme-now {
  color: var(--fg); font-weight: 600; text-decoration: none; cursor: default;
}
