* { box-sizing: border-box; }

/* iOS Safari автоматически инфлейтит шрифт в широких блоках (например, в
   #foods-table с white-space: nowrap, который шире viewport) — отключаем,
   чтобы CSS-размеры из styles.css действительно соблюдались. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* === Темы. Договорено с Yana 2026-05-16: глубокий синий, две палитры,
   переключатель в шапке. Светлая и тёмная используют единый акцент-цвет
   (на тёмной чуть осветлён для контраста). === */
:root {
  --bg: #f3f4f6;
  --surface: #fff;
  --surface-alt: #fafbfc;
  --balance-bg: #fff8ed;
  --text: #1f2328;
  --text-muted: #6b7280;
  --text-faint: #9ca3af;
  --border: #e5e7eb;
  --border-strong: #d0d7de;
  --accent: #1e40af;
  --accent-hover: #1e3a8a;
  --accent-soft: rgba(30,64,175,0.13);
  --group-bg: #dbeafe;
  --group-border: #93c5fd;
  --group-label: #1e3a8a;
  --danger: #ef4444;
  --danger-soft: rgba(239,68,68,0.10);
  /* «Хорошо» и «плохо» — единая палитра со страницей сна (2026-05-23).
   * δ under (дефицит, хорошо) → green-600. δ over (перебор) → orange-400. */
  --success: #16a34a;
  --success-soft: rgba(22,163,74,0.12);
  --warn: #fb923c;
  /* Тёплый «варнинг» баннера partner-mode — отдельная семантика от --warn (δ-перебор). */
  --warning: #b35900;
  --warning-bg: #fff4e0;
  /* «Утопленный» фон (графики/таблицы поверх карточки) — пока прозрачный в обеих темах,
   * заведён как токен, чтобы при желании переопределить per-theme без правки селекторов. */
  --surface-sunken: transparent;
  --shadow-1: 0 1px 2px rgba(15,23,42,0.06);
  --shadow-2: 0 4px 12px rgba(15,23,42,0.04);
  color-scheme: light;
}
[data-theme="dark"] {
  --bg: #0b1220;
  --surface: #131c2e;
  --surface-alt: #0f172a;
  --balance-bg: #1a1a2e;
  --text: #e6edf6;
  --text-muted: #94a3b8;
  --text-faint: #64748b;
  --border: #1f2a44;
  --border-strong: #2a3556;
  --accent: #2563eb;
  --accent-hover: #1d4ed8;
  --accent-soft: rgba(37,99,235,0.22);
  --group-bg: #1e3a8a;
  --group-border: #1e40af;
  --group-label: #93c5fd;
  --danger: #f87171;
  --danger-soft: rgba(248,113,113,0.15);
  /* Тёмная тема: приглушённые версии (земля/сосна), чтобы не ослеплять.
   * Используются и в еде, и в дашборде сна одинаково. */
  --success: #2f7a55;
  --success-soft: rgba(47,122,85,0.20);
  --warn: #b07053;
  --warning: #ffb86c;
  --warning-bg: rgba(255, 184, 108, 0.12);
  --surface-sunken: transparent;
  --shadow-1: 0 1px 2px rgba(0,0,0,0.4);
  --shadow-2: 0 8px 24px rgba(0,0,0,0.25);
  color-scheme: dark;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  max-width: 880px;
  margin: 0 auto;
  padding: 1.5rem;
  background: var(--bg);
  color: var(--text);
  line-height: 1.45;
}

/* Шапка — сетка из 3 рядов:
   - title (h1) + actions (Яна + 🚪 + 🌙) на одной строке
   - page-tabs (.page-tabs nav) — отдельная полоса
   - day-controls (если страница содержит) — третья
   Так нет flex-wrap'а и шапка читается «полосами». */
header {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "title actions"
    "tabs   tabs"
    "controls controls";
  column-gap: 1rem;
  row-gap: 0.5rem;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
}
header > h1 { grid-area: title; }
header > nav.page-tabs { grid-area: tabs; }
header > .auth-info { grid-area: actions; margin-left: 0; }
header > .day-controls { grid-area: controls; margin-top: 0; }
header > #view-hint { grid-area: controls; align-self: end; }

h1 { margin: 0.25rem 0; font-size: 1.5rem; color: var(--text); }
h2 { margin: 1.25rem 0 0.5rem; font-size: 1.1rem; color: var(--text); margin-top: 0.25rem; }

nav a { color: var(--text-muted); text-decoration: none; font-size: 0.95rem; }
nav a:hover { color: var(--text); text-decoration: underline; }

/* Табы основной навигации — горизонтальный ряд под h1, активный таб
   подсвечивается акцентным цветом и снизу-границей. */
nav.page-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin: 0;
  flex-wrap: wrap;
}
nav.page-tabs a {
  padding: 0.5rem 0.9rem;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-size: 0.95rem;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}
/* Первый таб без левого padding — текст «Главная» выровнен по h1 и краю карточек. */
nav.page-tabs a:first-child { padding-left: 0; }
nav.page-tabs a:hover {
  color: var(--text);
  text-decoration: none;
}
nav.page-tabs a.current {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

.big-nav { margin-top: 1.5rem; }
.big-nav a {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: white;
  border-radius: 8px;
  text-decoration: none;
}
.big-nav a:hover { background: var(--accent-hover); }

section { margin: 1.25rem 0; }
main > section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
  box-shadow: var(--shadow-1), var(--shadow-2);
}

/* Авторский `form { display:flex }` (и подобные) перебивает UA-правило
   [hidden]{display:none} по origin-каскаду — возвращаем семантику hidden
   в авторский слой, иначе hidden-форма «протекает» (set-password в ошибке). */
[hidden] { display: none; }

form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 360px;
}
form label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.95rem;
}
input, select {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font: inherit;
  background: var(--surface);
  color: var(--text);
  /* Единая высота для всех типов инпутов — на iOS нативные date/time
     стандартно крупнее, на десктопе текстовые мельче. */
  min-height: 2.25rem;
  line-height: 1.2;
  box-sizing: border-box;
}
/* Чекбоксы/радио НЕ растягиваем под min-height — иначе становятся гигантскими. */
input[type="checkbox"],
input[type="radio"] {
  min-height: 0;
  width: 1rem;
  height: 1rem;
  padding: 0;
  border: 1px solid var(--border-strong);
  -webkit-appearance: auto;
  appearance: auto;
  accent-color: var(--accent);  /* галка/точка в фирменном цвете */
}
/* Сбрасываем нативный вид у date/time/number/search/select, чтобы выглядели
   одинаково с текстовыми инпутами. Сам пикер (нативный календарь/часы)
   по-прежнему открывается — это влияет только на отрисовку самого инпута. */
input[type="date"],
input[type="time"],
input[type="number"],
input[type="search"],
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}
/* Стрелка-шеврон у select (нативную убрали appearance:none). Цвет в SVG закодирован
   как %23… (URL-encoded #), поэтому не считается хардкодом; тёмная тема — свой SVG. */
select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 0.7rem;
  padding-right: 1.85rem;
}
[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input::placeholder { color: var(--text-faint); }
form input { width: 55%; }
form select { width: 55%; }

/* Формы «Добавить ...» в карточках — общий современный стиль:
   горизонтальные подписи через grid, без узкого max-width глобальной формы. */
#meal-form, #add-form {
  max-width: none;
  gap: 0.75rem;
}
#meal-form label,
#add-form label {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.95rem;
}
#meal-form input, #meal-form select,
#add-form input, #add-form select { width: 100%; min-width: 0; }

/* На /day.html форма приёма — 2-колоночная сетка через .form-col. */
#meal-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem 1.5rem;
}
/* На /foods.html и /vendors.html «Добавить» — одноколоночная (поля идут
   подряд сверху вниз), но БЖУ-блок может быть свой 2×2 grid. */
#add-form .bju-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem 1rem;
}
#add-form .bju-grid label { grid-template-columns: 7rem 1fr; }

/* Пустые .msg / .hint раньше работали как невидимые распорки (min-height: 1.2em
   + margin). Прячем глобально — занимают место только когда JS реально что-то
   пишет. */
.msg:empty, .hint:empty { display: none !important; }
#meal-form .form-col {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;  /* иначе grid-ячейка может расширяться из-за длинных значений */
}
#meal-form .form-row-full { grid-column: 1 / -1; }
/* Горизонтальные подписи: «Лейбл [поле]» в одну строку.
   Сетка 5.5rem + 1fr — подпись фиксированной ширины, поле занимает остаток. */
#meal-form label {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.95rem;
}
#meal-form input,
#meal-form select { width: 100%; min-width: 0; }
#meal-form .new-food-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem 1rem;
  margin-top: 0.5rem;
}
/* Сегментированный переключатель базиса БЖУ («на 100 г / на порцию»). */
#meal-form .bju-basis {
  display: inline-flex;
  gap: 0;
  margin: 0.25rem 0 0.25rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
}
#meal-form .bju-basis label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.7rem;
  margin: 0;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--text-muted);
  grid-template-columns: none; /* перебивает общий #meal-form label grid */
}
#meal-form .bju-basis label:has(input:checked) {
  background: var(--accent-soft);
  color: var(--text);
}
#meal-form .bju-basis input[type="radio"] {
  appearance: none;
  width: 0; height: 0;
  margin: 0; padding: 0;
  position: absolute;
  opacity: 0;
}
#meal-form button[type="submit"] { align-self: flex-start; }

/* /profile.html — label слева, input справа. Сетка с фиксированной левой
   колонкой выравнивает все инпуты по вертикали независимо от длины подписи.
   Все 4 формы профиля (общие, антропометрия, цели, пароль) живут по одной
   сетке — иначе «Логин» уезжал бы вправо относительно длинных подписей
   целей («Висцеральный жир, см²»). */
#profile-form, #body-form, #goals-form, #password-form, #suppl-add-form {
  max-width: 480px;
  align-items: stretch;
}
#profile-form label,
#body-form label,
#goals-form label,
#password-form label,
#suppl-add-form label {
  display: grid;
  grid-template-columns: 12rem 1fr;
  align-items: center;
  gap: 0.75rem;
}
#profile-form input, #profile-form select,
#body-form input, #body-form select, #body-form textarea,
#goals-form input, #goals-form select, #goals-form textarea,
#password-form input,
#suppl-add-form input, #suppl-add-form select {
  width: 100%; min-width: 0;
}
#profile-form .form-row-full,
#body-form .form-row-full,
#goals-form .form-row-full,
#password-form .form-row-full,
#suppl-add-form .form-row-full { width: 100%; }
/* Autocomplete-обёртка занимает всю правую колонку grid-лейбла. */
#suppl-add-form .ac-wrap { display: block; }
/* Отступ между кнопкой формы и подписью-подсказкой под ней. */
#suppl-add-section .section-hint { margin-top: 1rem; }
/* Многострочное поле «Комментарий» — лейбл прижат к верху, textarea
   растягивается вниз по желанию пользователя. */
#goals-form label.goal-notes { align-items: start; }
#goals-form textarea {
  min-height: 4.5rem;
  resize: vertical;
  font: inherit;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
}
#goals-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
@media (max-width: 640px) {
  #profile-form label,
  #body-form label,
  #goals-form label,
  #password-form label,
  #suppl-add-form label { grid-template-columns: 1fr; gap: 0.25rem; }
}

button {
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font: inherit;
  margin-top: 0.25rem;
  align-self: flex-start;
  box-shadow: var(--shadow-1);
}
button:hover { background: var(--accent-hover); }
button:active { background: var(--accent-hover); filter: brightness(0.95); }

/* Ссылка-кнопка: анкор с видом первичной кнопки (CTA на публичных страницах,
   напр. «Перейти ко входу» на set-password). */
.btn-link {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: white;
  text-decoration: none;
  border-radius: 8px;
  font: inherit;
  margin-top: 0.5rem;
  box-shadow: var(--shadow-1);
}
.btn-link:hover { background: var(--accent-hover); }
.btn-link:active { background: var(--accent-hover); filter: brightness(0.95); }

#search {
  width: 100%;
  margin-bottom: 0.75rem;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  color: var(--text);
}
th, td {
  text-align: left;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border);
}
th { background: transparent; font-weight: 600; color: var(--text-muted); letter-spacing: 0.02em; }
td:not(:first-child), th:not(:first-child) { text-align: right; width: 4.5rem; }

.msg { font-size: 0.9rem; margin: 0.5rem 0; min-height: 1.2em; }
.msg.ok { color: var(--success); }
.msg.err { color: var(--danger); }
.msg.calc { color: var(--text-muted); }

.hint { font-size: 0.85rem; color: var(--text-muted); margin: 0.25rem 0; }

/* «Пишу в дневник партнёра» — заметный баннер в шапке /day.html.
   Не drama-red, но контрастный, чтобы Yana понимала «я сейчас редактирую Алексея».
   Цвета держим в палитре варнинга (тёплый акцент). */
.partner-mode-banner {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--warning);
  background: var(--warning-bg);
  border: 1px solid var(--warning);
  border-radius: 6px;
  padding: 0.25rem 0.6rem;
}
/* Просмотр чужого дневника без права записи (напр. тренер у подопечного) —
   нейтральный «инфо»-вид, в отличие от оранжевого partner-mode «Пишу в дневник». */
.partner-mode-banner.readonly-banner {
  color: var(--text-muted);
  background: var(--surface-alt);
  border-color: var(--border-strong);
  font-weight: 500;
}
[data-theme="dark"] .partner-mode-banner.readonly-banner {
  color: var(--text-muted);
  background: var(--surface-alt);
  border-color: var(--border-strong);
}

.hidden { display: none !important; }

/* Автодополнение каталога */
.ac-wrap { position: relative; }
.suggestions {
  list-style: none;
  margin: 0;
  padding: 0;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  max-height: 240px;
  overflow-y: auto;
  z-index: 10;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}
.suggestions:empty { display: none; }
/* Флип наверх: когда снизу не хватает места (актуально для нижних полей модалки
   на мобиле). Класс ставится из vendor-autocomplete.js / select-dropdown.js. */
.suggestions.drop-up {
  top: auto;
  bottom: 100%;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.12);
}
.suggestions li {
  padding: 0.4rem 0.6rem;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--text);
}
.suggestions li:hover { background: var(--surface-alt); }
.suggestions li.suggestions-header {
  font-size: 0.85rem;
  color: var(--text-muted);
  background: var(--surface-alt);
  cursor: default;
  font-style: italic;
}
.suggestions li.suggestions-header:hover { background: var(--surface-alt); }
/* Метка блюда из меню ресторана в едином поиске (вендор + вес порции). */
.suggestions li .sug-menu {
  font-size: 0.78rem;
  color: var(--text-muted);
}
/* Подсветка совпавшей с запросом части имени (см. highlightMatch в utils.js):
   в выпадайках подсказок и в строках таблицы каталога. */
.suggestions li mark,
#foods-table mark {
  background: none;
  color: var(--accent);
  font-weight: 600;
}

/* Кастомный dropdown поверх <select> (см. web/js/select-dropdown.js).
   Триггер — readonly text input, чтобы внешне совпадал с обычными input'ами
   (vendor-инпут и пр.). Курсор pointer, текстовый каретик прячем. */
.select-trigger {
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  caret-color: transparent;
}
.select-trigger.placeholder-active { color: var(--text-faint); }

/* Кастомный dropdown для «Чей <X>» в .day-controls — inline, чтобы не
   ломал строку с лейблом «Чей день: [Яна ⌄]». Триггер ужимаем под имя,
   справа — шеврон (символ ⌄). */
.day-controls .select-dropdown-wrap {
  display: inline-flex;
  vertical-align: middle;
}
.day-controls .select-dropdown-wrap::after {
  content: '⌄';
  position: absolute;
  right: 0.6rem;
  top: 50%;
  transform: translateY(-65%);  /* визуально центрируем «⌄» — у него опущенный bottom */
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  pointer-events: none;
}
.day-controls .select-dropdown-wrap .select-trigger {
  width: 7rem;
  padding-right: 1.4rem;  /* место под шеврон */
}
/* Выбранный пункт подсвечиваем, чтобы было видно текущее значение при открытии. */
.select-suggestions li.selected {
  background: var(--accent-soft);
  color: var(--text);
}
.select-suggestions li.selected:hover { background: var(--accent-soft); }

/* Блок ввода нового продукта при добавлении приёма */
.new-food {
  border-left: 3px solid var(--accent);
  padding-left: 0.75rem;
  margin: 0.5rem 0;
}

/* Кнопки действий над приёмом (изменить/удалить).
   НЕ ставим display:flex на <td> — это ломает табличную высоту ячейки
   и border-bottom рисуется не на одной линии с соседями. Кнопки идут
   inline через whitespace-nowrap. */
td.actions { white-space: nowrap; }
td.actions button { margin-right: 0.25rem; }
td.actions button:last-child { margin-right: 0; }
/* Action-кнопки ✎/× и rename/delete в таблицах — нейтральные но видимые,
   на hover акцентный/красный bg + заметная иконка. */
button.edit, button.del,
button.btn-rename, button.btn-delete {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 0.25rem 0.45rem;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  margin: 0;
  box-shadow: none;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
button.edit svg, button.del svg,
button.btn-rename svg, button.btn-delete svg { width: 16px; height: 16px; }
button.edit:hover, button.btn-rename:hover {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: transparent;
}
button.del:hover, button.btn-delete:hover {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: transparent;
}

/* На мобиле (iPhone 13 Pro/14 = 390px, Galaxy S25 = 360px) action-кнопки
   расширяются до 44×44 — это минимум для удобного тапа пальцем (Apple HIG /
   Material Design). SVG-иконка остаётся 16px. */
@media (max-width: 480px) {
  button.edit, button.del,
  button.btn-rename, button.btn-delete {
    min-width: 44px;
    min-height: 44px;
    padding: 0;
  }
}

/* Подсветка ряда при наведении в таблицах — помогает понять «к какой
   строке относятся action-кнопки справа». Только для интерактивных рядов. */
#meals-table tbody tr:not(.meal-group-header):hover > td,
#foods-table tbody tr:not(.editing):hover > td,
#vendors-table tbody tr:hover > td {
  background: var(--surface-alt);
}

/* Фильтры в каталоге — grid. Прямые дети (input/select/button) занимают
   свои grid-cells, lable'ы (для dupe-scan и пр.) рендерятся как flex. */
.filter-row {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) auto auto;
  gap: 0.5rem 0.75rem;
  align-items: center;
  margin-bottom: 0.75rem;
}
.filter-row > input,
.filter-row > select,
.filter-row > button,
.filter-row > label { margin: 0; }
.filter-row > label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  color: var(--text-muted);
  white-space: nowrap;
  min-height: 2.25rem;
  height: 2.25rem;
}
.filter-row select { min-width: 9rem; }
/* Когда выбран первый option (он играет роль placeholder'а) — серый цвет
   текста, как у настоящих input placeholder'ов. Класс добавляет JS при
   изменении значения select'а. */
.filter-row select.placeholder-active { color: var(--text-faint); }

/* Колонка «Ккал» — главная метрика во всех табличках. Bold + полный
   text-color, чтобы выделялась среди БЖУ/Сп/×N (которые auxiliary).
   meals-table: 4-я колонка (Продукт, Источник, Вес, Ккал, ...)
   foods/week/month/year-table: 3-я колонка (Дата, ..., Ккал, ...) */
#meals-table tr > td:nth-child(4),
#meals-table tr > th:nth-child(4),
#foods-table tr > td:nth-child(3),
#foods-table tr > th:nth-child(3),
#week-table tr > td:nth-child(3),
#week-table tr > th:nth-child(3),
#month-table tr > td:nth-child(3),
#month-table tr > th:nth-child(3) {
  font-weight: 600;
  color: var(--text);
}
/* В year-table нет колонки «Ккал» — bold-акцент на «Сред. ккал/день» (col 3) */
#year-table tbody tr > td:nth-child(3),
#year-table thead tr > th:nth-child(3),
#year-table tfoot tr > td:nth-child(2) {
  font-weight: 600;
  color: var(--text);
}


/* Пустые states — SVG-иконка + основной текст + подсказка. Используется
   в /day.html (нет приёмов), /foods.html (пустой каталог), /vendors.html
   (пустой список источников). */
.empty-state {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--text-muted);
}
.empty-state svg {
  width: 56px;
  height: 56px;
  margin: 0 auto 0.75rem;
  display: block;
  color: var(--text-faint);
  opacity: 0.75;
}
.empty-state .empty-title {
  margin: 0;
  font-size: 0.95rem;
  color: var(--text);
}
.empty-state .empty-hint {
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}
/* dupe-scan / vendors-search — не 3 колонки. */
.filter-row:not(:has(select)) { grid-template-columns: minmax(12rem, 1fr) auto; }
.muted { color: var(--text-faint); }
/* Подпись-пояснение сразу под <h2> секции: подтянута к заголовку, мелкий hint-кегль (§2). */
.section-hint { margin-top: -0.25rem; font-size: 0.85rem; }

/* Таблица приёмов на /day.html — колонка «Источник» не должна схлопываться
   на пустых значениях («—»). */
#meals-table th, #meals-table td { vertical-align: top; padding: 0.4rem 0.5rem; }
#meals-table td:nth-child(2) { min-width: 6rem; white-space: nowrap; }  /* Источник */
#meals-table th:nth-child(n+3):nth-child(-n+7),
#meals-table td:nth-child(n+3):nth-child(-n+7) { text-align: right; white-space: nowrap; }

/* Read-only поле (vendor когда выбран существующий продукт) */
input.readonly-field {
  background: var(--surface-alt);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* Таблица каталога продуктов — стабильные ширины колонок,
   чтобы пустая колонка «Источник» не схлопывалась под широкое имя.
   width: 100% + чуть меньше паддингов + разрешённый перенос в «Источнике»
   удерживают таблицу в границах карточки на типичных названиях. */
#foods-table { table-layout: auto; width: 100%; }
#foods-table th, #foods-table td { vertical-align: top; padding: 0.4rem 0.35rem; }
#foods-table td:nth-child(2) { min-width: 5rem; }  /* Источник: можно переносить */
#foods-table td:nth-child(n+3):nth-child(-n+8) { text-align: right; white-space: nowrap; }  /* Ккал/БЖУ/Сп/×N */
#foods-table th:nth-child(n+3):nth-child(-n+8) { text-align: right; }
#foods-table tr.editing td { background: var(--accent-soft); }
#foods-table tr.editing input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.25rem 0.4rem;
  min-height: 1.8rem;
  font-size: 0.9rem;
}
#foods-table tr.editing input.ed-num { text-align: right; }
/* width: 100% распространяется на все input'ы — пусть ячейка диктует ширину,
   не наоборот. Это удерживает таблицу в границах карточки в режиме edit. */
#foods-table button.del:disabled { opacity: 0.3; cursor: not-allowed; }
#foods-table button.del:disabled:hover { color: var(--text-faint); border-color: transparent; background: transparent; }

/* Кликабельные заголовки колонок: сортировка по клику. Стрелка-индикатор
   только у активной колонки (.sort-asc / .sort-desc), у неактивных —
   еле-видимая стрелка-плейсхолдер ⇅, чтобы пользователь понимал что
   колонка кликабельна. */
#foods-table th.sortable,
#vendors-table th.sortable {
  cursor: pointer;
  user-select: none;
  position: relative;
  white-space: nowrap;
}
#foods-table th.sortable:hover,
#vendors-table th.sortable:hover { color: var(--accent); }
#foods-table th.sortable::after,
#vendors-table th.sortable::after {
  content: " ⇅";
  color: var(--text-faint);
  opacity: 0.4;
  font-size: 0.85em;
}
#foods-table th.sortable.sort-asc::after,
#vendors-table th.sortable.sort-asc::after {
  content: " ↑";
  color: var(--accent);
  opacity: 1;
}
#foods-table th.sortable.sort-desc::after,
#vendors-table th.sortable.sort-desc::after {
  content: " ↓";
  color: var(--accent);
  opacity: 1;
}

/* Кликабельная ячейка ×N — открывает модалку с приёмами */
td.meals-count-cell {
  cursor: pointer;
  text-decoration: underline dotted;
  text-decoration-color: var(--text-faint);
  text-underline-offset: 3px;
}
td.meals-count-cell:hover { color: var(--accent); text-decoration-color: var(--accent); }

/* Модалка «Приёмы с этим продуктом» / «Продукты источника» */
.meals-modal {
  min-width: min(640px, 92vw);
  max-width: 92vw;
  padding: 1.25rem;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text);
}
.meals-modal::backdrop { background: rgba(0,0,0,0.5); }
.meals-modal form { max-width: none; position: relative; }
.meals-modal .modal-close-x {
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  background: transparent;
  border: none;
  box-shadow: none;
  outline: none;
  font-size: 1.4rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  margin: 0;
  cursor: pointer;
  color: var(--text-muted);
  min-height: auto;
  border-radius: 6px;
}
.meals-modal .modal-close-x:hover { color: var(--text); background: var(--surface-alt); }
.meals-modal form > h3 { margin-top: 0; }

/* В edit-meal-form поле vendor завёрнуто в .ac-wrap (автокомплит) — без width
   правило form input { width: 55% } съёживает input до интринсики .ac-wrap'а. */
#edit-meal-form .ac-wrap { width: 55%; }
#edit-meal-form .ac-wrap input { width: 100%; }
.meals-modal-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0 0;
  max-height: 60vh;
  overflow-y: auto;
}
.meals-modal-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 0.5rem 0.75rem;
  align-items: baseline;
  padding: 0.35rem 0.25rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.95em;
}
.meals-modal-row:last-child { border-bottom: none; }
.meals-modal-date { color: var(--text-faint); white-space: nowrap; }
.meals-modal-user { font-weight: 500; }
.meals-modal-grams, .meals-modal-kcal { color: var(--text-faint); white-space: nowrap; }
.meals-modal-kcal .muted { white-space: nowrap; }

/* На мобилке 4 колонки не влезают (дата + имя + граммы + "526 ккал · завтрак"),
   уезжает в горизонтальный скролл. Складываем в две строки: дата+юзер сверху,
   граммы+ккал снизу. */
@media (max-width: 640px) {
  .meals-modal { padding: 1rem 0.75rem; }
  .meals-modal-row {
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.6rem;
  }
  .meals-modal-grams { grid-column: 1; }
  .meals-modal-kcal { grid-column: 2; white-space: normal; }
}

/* Аккордеон по продуктам (источники → продукты → приёмы) */
.vendor-food-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.5rem 0.75rem;
  align-items: center;
  padding: 0.5rem 0.5rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
}
.vendor-food-row:hover { color: var(--accent); }
.vendor-food-row .toggle { color: var(--text-faint); width: 1em; display: inline-block; }
.vendor-food-row.open .toggle { color: var(--accent); }
.vendor-food-meals {
  padding: 0.25rem 0 0.5rem 1.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-soft, transparent);
}
.vendor-food-meals .meals-modal-list { margin: 0; max-height: 30vh; }

/* Сканер дублей — пары рядом */
#dupe-threshold { width: 5rem; }
.dupe-pair {
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  gap: 0.75rem 1rem;
  align-items: start;
  padding: 0.5rem 0.75rem;
  margin: 0.5rem 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-alt);
  font-size: 0.9rem;
}
.dupe-score { white-space: nowrap; padding-right: 0.5rem; border-right: 1px solid var(--border); }
.dupe-side { min-width: 0; word-wrap: break-word; }
.dupe-side b { color: var(--text-muted); font-size: 0.85rem; }
.dupe-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.4rem;
  border-top: 1px dashed var(--border);
}
.dupe-actions button {
  font-size: 0.85rem;
  padding: 0.25rem 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  cursor: pointer;
  color: var(--text);
  margin: 0;
  box-shadow: none;
}
.dupe-actions button:hover { background: var(--surface-alt); }
.dupe-actions .dupe-merge-into-a:hover,
.dupe-actions .dupe-merge-into-b:hover { background: var(--accent-soft); border-color: var(--accent); }
.dupe-actions .dupe-dismiss:hover { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }

/* На мобильном grid-у не хватает места — раскладываем вертикально, иначе каждая
   колонка ужимается до 1 символа и word-wrap ломает текст по буквам. */
@media (max-width: 640px) {
  .dupe-pair {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }
  .dupe-score {
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding-right: 0;
    padding-bottom: 0.4rem;
  }
  .dupe-side + .dupe-side {
    padding-top: 0.4rem;
    border-top: 1px dashed var(--border);
  }
}

tfoot th, tfoot td { font-weight: 600; border-top: 2px solid var(--border-strong); background: var(--surface-alt); color: var(--text); border-radius: 6px; }

/* Баланс */
.balance { background: var(--balance-bg); padding: 0.75rem 1rem; border-radius: 8px; }
.balance h2 { margin-top: 0; }
.balance-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.balance-row input { width: 8rem; }
.balance-row button { margin: 0; }

.bmr-info { margin: 0.5rem 0 0.25rem; font-size: 0.85rem; color: var(--text-muted); }
.bmr-info span { font-weight: 600; color: var(--text); }

.delta { margin: 0.5rem 0 0; font-size: 0.95rem; color: var(--text-muted); }
.delta.over { color: var(--warn); font-weight: 600; }
.delta.under { color: var(--success); font-weight: 600; }
.delta.zero { color: var(--text-muted); font-weight: 600; }

/* Шапка: «привет, X / выйти / 🌙» */
.auth-info {
  margin-left: auto;
  font-size: 0.9rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.auth-info span { font-weight: 600; color: var(--text); }
/* Если на странице есть селектор «Чей …» (#view-user), имя залогиненного
   в углу — это дубль. Подпись селектора уже сообщает, чьи данные открыты.
   Оставляем #current-user только там, где селектора нет (profile.html). */
body:has(#view-user) .auth-info #current-user { display: none; }
/* «Выйти» — круглая кнопка-иконка, одного формата с .theme-toggle.
   По дефолту нейтрального цвета (как и тема рядом), но на hover краснеет —
   сигналит «это действие закрывает сессию». Стандартный подход в Gmail/
   Notion/GitHub: красный только при наведении, не как state. */
.auth-info a#logout-btn {
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.auth-info a#logout-btn svg { width: 16px; height: 16px; }
.auth-info a#logout-btn:hover {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: var(--danger);
}

/* Шестерёнка-настройки — той же формы, что logout/theme, но нейтральный hover. */
.auth-info a.settings-link,
.auth-info a.admin-link {
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s, border-color 0.15s;
}
.auth-info a.settings-link svg,
.auth-info a.admin-link svg { width: 16px; height: 16px; }
.auth-info a.settings-link:hover { background: var(--surface-alt); }
/* Админ-иконка — лёгкий акцентный оттенок, чтобы отличалась от шестерёнки. */
.auth-info a.admin-link { color: var(--accent); border-color: var(--accent); }
.auth-info a.admin-link:hover { background: var(--accent-soft); }

/* Гамбургер-меню — круглая кнопка одной формы с theme/logout.
   По дефолту скрыта, показывается на мобилке. */
.menu-toggle {
  display: none;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  margin: 0;
  position: relative;
  z-index: 1001;  /* над меню-overlay */
}
.menu-toggle:hover { background: var(--surface-alt); }
.menu-toggle svg { width: 16px; height: 16px; }

/* Переключатель темы — круглая кнопка с эмодзи. */
.theme-toggle {
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: none;
  margin: 0;
}
.theme-toggle:hover { background: var(--surface-alt); }

/* Страница логина */
body.login-page { max-width: 360px; padding-top: 4rem; }
body.login-page form label { flex-direction: column; align-items: stretch; }
body.login-page form input { width: 100%; }
body.login-page main > section { background: transparent; border: none; box-shadow: none; padding: 0; }

/* Управление «Чей день» + дата на странице сегодня */
.day-controls {
  width: 100%;
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.95rem;
}
.day-controls select,
.day-controls input[type="date"] {
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font: inherit;
  background: var(--surface);
  color: var(--text);
}
.date-nav { display: flex; gap: 0.25rem; align-items: stretch; flex-wrap: wrap; row-gap: 0.4rem; }
.date-nav button,
.date-nav input[type="date"],
.date-nav input[type="month"],
.date-nav input[type="number"] {
  height: 2.25rem;
  padding: 0.3rem 0.7rem;
  background: var(--surface);
  color: var(--accent);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  margin: 0;
  font-size: 0.95rem;
  box-shadow: none;
  box-sizing: border-box;
  line-height: 1.2;
  /* На iOS Safari у нативных input/button своя UA-высота, которая
     игнорирует align-items: stretch родителя и ломает выравнивание. */
  appearance: none;
  -webkit-appearance: none;
}
.date-nav input[type="date"],
.date-nav input[type="month"],
.date-nav input[type="number"] { color: var(--text); }
.date-nav button:hover { background: var(--surface-alt); }
#day-today { font-size: 0.85rem; }

input:disabled { background: var(--surface-alt); color: var(--text-faint); }

/* Будущие дни в таблицах: чуть приглушены */
tr.future td { color: var(--text-faint); }
tr.future a { color: var(--text-muted); }

/* Раскрытие детализации дня на /week.html */
#week-table tr.day-row { cursor: pointer; }
#week-table tr.day-row:hover td { background: var(--surface-alt); }
#week-table td.day-date,
#week-table td.weekday { width: 1%; white-space: nowrap; }
#week-table td.day-date { padding-right: 0.25rem; }
#week-table td.weekday { padding-left: 0.25rem; color: var(--text-muted); }
#week-table td.day-date a {
  color: inherit;
  text-decoration: none;
}
#week-table td.day-date a:hover { text-decoration: underline; }

/* По аналогии — Месяц и Год: ссылки на дату/месяц без подчёркивания + ужатые колонки */
#month-table tbody tr > td:first-child,
#month-table tbody tr > td.weekday { width: 1%; white-space: nowrap; }
#month-table tbody tr > td:first-child { padding-right: 0.25rem; }
#month-table tbody tr > td.weekday { padding-left: 0.25rem; color: var(--text-muted); }
#month-table tbody tr > td:first-child a,
#year-table tbody tr > td:first-child a {
  color: inherit;
  text-decoration: none;
}
#month-table tbody tr > td:first-child a:hover,
#year-table tbody tr > td:first-child a:hover { text-decoration: underline; }
#year-table tbody tr > td:first-child { width: 1%; white-space: nowrap; }
/* Год: в Итого годовая сумма Ккал не нужна — есть только сред./день.
   th colspan=2 покрывает «Месяц» и «Дней». */
#year-table tfoot tr > th:first-child { text-align: left; }
#week-table .expand-toggle {
  display: inline-block;
  width: 1em;
  color: var(--text-muted);
  font-size: 0.85rem;
  margin-right: 0.25rem;
  user-select: none;
}
#week-table tr.day-detail-row > td {
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  padding: 0.5rem 1rem 0.75rem 2.25rem;
}
ul.day-detail {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9rem;
}
ul.day-detail li {
  display: grid;
  grid-template-columns: 3.5rem 5rem 6rem 1fr;
  gap: 0.5rem 1rem;
  padding: 0.15rem 0;
  color: var(--text);
}
ul.day-detail .dt-time { color: var(--text-muted); }
ul.day-detail .dt-label { font-weight: 600; }
ul.day-detail .dt-kcal { text-align: right; }
ul.day-detail .dt-bju { color: var(--text-muted); }
/* Десктоп: Б/Ж/У inline, разделитель "/" */
ul.day-detail .dt-bju > span + span::before {
  content: '/ ';
  margin: 0 0.25rem 0 0.4rem;
  color: var(--text-faint);
}

/* Группировка приёмов по типу на /day.html — баннер без border'ов,
   только плашка цветным фоном. */
.meal-group-header th {
  background: var(--group-bg);
  color: var(--group-label);
  text-align: left;
  font-weight: 600;
  padding: 0.5rem 0.75rem;
  border-top: none !important;
  border-bottom: none !important;
  border-radius: 0;
}
/* Скругляем только внешние углы всей полосы — чтобы группа читалась как
   одна строка, а не как набор отдельных ячеек. */
.meal-group-header th:first-child { border-radius: 6px 0 0 6px; }
.meal-group-header th:last-child { border-radius: 0 6px 6px 0; }
/* И убираем линию снизу у thead, если следом идёт meal-group-header — иначе
   она торчит над баннером. */
#meals-table thead th { border-bottom: none; }
.meal-group-header .mg-label { font-size: 1rem; color: var(--group-label); }
.meal-group-header .mg-time {
  color: var(--group-label);
  opacity: 0.75;
  font-weight: normal;
  font-size: 0.85rem;
  margin-left: 0.6rem;
}
/* Суммы по группе разложены по колонкам (Вес/Ккал/Б/Ж/У) — числа тем же
   цветом что и заголовок группы; «Ккал» (4-я колонка) наследует bold-акцент
   из общего правила таблицы. */

/* Merge-modal (диалог слияния продукта при удалении) */
#merge-modal { padding: 1.25rem; border: 1px solid var(--border-strong); border-radius: 12px; max-width: 560px; width: 95%; background: var(--surface); color: var(--text); }
#merge-modal::backdrop { background: rgba(0,0,0,0.5); }
#merge-modal h3 { margin: 0 0 0.5rem; }
#merge-modal label { display: block; margin-top: 0.5rem; }
#merge-modal input[type="search"] { width: 100%; margin-top: 0.25rem; }
#merge-modal menu { display: flex; justify-content: flex-end; gap: 0.5rem; padding: 0; margin: 1rem 0 0; }
#merge-target-list {
  list-style: none; margin: 0.5rem 0 0; padding: 0;
  border: 1px solid var(--border); border-radius: 8px;
  max-height: 280px; overflow-y: auto; background: var(--surface);
}
#merge-target-list:empty { display: none; }
#merge-target-list li {
  padding: 0.5rem 0.7rem; cursor: pointer; font-size: 0.9rem;
  border-bottom: 1px solid var(--border);
}
#merge-target-list li:last-child { border-bottom: none; }
#merge-target-list li:hover { background: var(--surface-alt); }
#merge-target-list li.selected { background: var(--accent-soft); }
#merge-target-list li.muted { cursor: default; color: var(--text-muted); font-style: italic; }
#merge-target-list li.muted:hover { background: var(--surface); }

/* Edit-meal модалка — узкое окно по ширине формы (~360+padding), без
   пустых полей справа. На мобильных не вылазит за экран благодаря max-width. */
#edit-meal-modal {
  padding: 1.25rem;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  width: 420px;
  max-width: 95vw;
  background: var(--surface);
  color: var(--text);
}
#edit-meal-modal::backdrop { background: rgba(0,0,0,0.5); }

/* Единый ритм отступов в модалке: form gap 0.75rem между всеми элементами,
   все p внутри обнуляются (свои отступы дала бы дефолтная margin браузера),
   пустые .msg/.hint выбрасываются из потока чтобы не создавать «дыр». */
#edit-meal-form {
  max-width: 100%;
  gap: 0.75rem;
}
#edit-meal-form h3 { margin: 0; font-size: 1.1rem; }
#edit-meal-form p { margin: 0; }
#edit-meal-form .modal-food-name {
  font-size: 0.95rem;
  color: var(--text-muted);
}
#edit-meal-form .msg:empty,
#edit-meal-form .hint:empty { display: none !important; }
#edit-meal-form .share-fields { margin-top: 0; }  /* gap'а формы достаточно */
#edit-meal-form menu {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
#edit-meal-form menu button { margin: 0; }

/* Блок «Разделить» в форме добавления и в edit-модалке.
   Чекбокс открывает блок с полями. Применяется на «Сохранить»/«Добавить». */
/* Перебиваем #meal-form label { display: grid; grid-template-columns: 7rem 1fr }
   для share-toggle — иначе чекбокс уезжает в 7rem колонку, текст во вторую,
   и между ними дыра 7rem. */
#meal-form .share-toggle,
.share-block .share-toggle {
  display: inline-block !important;
  grid-template-columns: none !important;
  font-size: 0.95rem;
  color: var(--text-muted);
  cursor: pointer;
  width: auto;
  padding: 0;
  margin: 0;
}
#meal-form .share-toggle input,
.share-block .share-toggle input {
  width: 1rem;
  margin: 0 0.2rem 0 0;
  vertical-align: middle;
}

/* На мобиле — увеличиваем чекбокс «Разделить с другим» и tap-зону label'а
   (Apple HIG / Material рекомендуют ≥44pt). */
@media (max-width: 480px) {
  /* Совсем узкие телефоны: иконки шапки чуть меньше, чтобы пятёрка
     (гамбургер · Админ · Настройки · Выход · Тема) гарантированно вместилась. */
  .auth-info a.settings-link,
  .auth-info a.admin-link,
  .auth-info a#logout-btn,
  .theme-toggle,
  .menu-toggle { width: 1.8rem; height: 1.8rem; }

  #meal-form .share-toggle,
  .share-block .share-toggle {
    padding: 0.5rem 0;  /* вертикальный tap-зон ~44px вместе с чекбоксом */
  }
  #meal-form .share-toggle input,
  .share-block .share-toggle input {
    width: 1.25rem;
    height: 1.25rem;
    margin-right: 0.4rem;
  }
}

/* Когда share-block идёт ПОСЛЕ кнопки submit'а — сидит строго под ней,
   шириной по контенту, без отступа слева. */
.share-block.share-after-submit {
  margin-top: 0.4rem;
  margin-left: 0;
  padding-left: 0;
  justify-self: start;
}
.share-block.share-after-submit .share-toggle {
  font-size: 0.85rem;
  padding-left: 0;
  margin-left: 0;
}
.share-fields {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding: 0.75rem 1rem;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.share-fields label {
  display: grid;
  grid-template-columns: 7.5rem 14rem;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.95rem;
}
/* Перебиваем #meal-form label { grid-template-columns: 5.5rem 1fr } —
   иначе колонка лейбла 5.5rem, «Моя доля, %» переносится на 2 строки,
   а инпут растягивается на всю свободную ширину.
   justify-content: start глушит глобальное form label { justify-content:
   space-between } — иначе grid-колонки растаскиваются по краям и инпут
   улетает в правый край панели вместо позиции сразу за лейблом. */
#meal-form .share-fields label {
  grid-template-columns: 7.5rem 14rem;
  justify-content: start;
}
.share-fields input,
.share-fields select { width: 100%; min-width: 0; }
.share-partner-hint {
  font-size: 0.85rem;
  color: var(--text-muted);
  padding-left: 8rem;  /* 7.5rem лейбл + 0.5rem gap → под старт инпута */
  margin: 0;
}
.share-partner-hint span { font-weight: 600; color: var(--text); }

/* Мобильная адаптация (iPhone 13 Pro = 390px и аналогичные).
   На /day.html таблица «Приёмы» широкая (8 колонок) — упаковываем в
   горизонтально скроллящийся контейнер. Форму держим в 2 колонки, но
   сокращаем padding страницы. */
/* === Меню ресторанов (menus.html) === */
.menus-intro {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin: 0 0 0.75rem;
}
.menu-count { font-size: 0.85rem; }
/* Ряд действия «Пересопоставить приёмы» — кнопка + пояснение. */
.menus-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
}
.menus-actions button { margin: 0; }
/* Резолвер «Привязать записи к меню»: список бот-записей + выпадашки позиций меню. */
.resolver {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem;
  margin: 0 0 1rem;
  background: var(--surface-alt);
}
.resolver-intro { margin: 0 0 0.5rem; color: var(--text-muted); font-size: 0.9rem; }
.resolver-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
}
.resolver-food { flex: 1 1 12rem; min-width: 0; }
.resolver-pick { flex: 1 1 12rem; min-width: 0; }
.resolver-actions { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
.resolver-actions button { margin: 0; }
/* Ряд фильтра меню: ресторан · поиск (гибкий) · счётчик. Селектор ресторана —
   кастомный дропдаун (select-dropdown.js), тянется на всю ширину своей ячейки. */
.menus-filter { grid-template-columns: minmax(9rem, 14rem) minmax(10rem, 1fr) auto; }
.menus-filter .select-dropdown-wrap,
.menus-filter .select-trigger { width: 100%; box-sizing: border-box; }
/* Сортировка — только для мобилы; на десктопе сортируем стрелками заголовков.
   #menu-sort становится кастом-дропдауном (обёртка .menu-sort-wrap) — прячем и то, и то. */
.menu-sort, .menu-sort-wrap { display: none; }
/* Бейдж «в каталоге» — акцентный вариант alias-chip (блюдо уже съедено/повышено). */
.menu-promoted {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-soft);
}
/* Числовые колонки (Ккал/Б/Ж/У/Порция/Ккал·порц = 2–7) — вправо, как в каталоге. */
#menu-table th:nth-child(n+2):nth-child(-n+7),
#menu-table td:nth-child(n+2):nth-child(-n+7) {
  text-align: right;
  white-space: nowrap;
}
#menu-table tr.editing td { background: var(--accent-soft); }
#menu-table tr.editing input { width: 100%; box-sizing: border-box; }
#menu-table tr.editing input.ed-num { text-align: right; }

/* Сортируемые заголовки меню (клик/Enter — сортировка, повторный — реверс).
   На мобильном thead скрыт (§9) — сортировка кликом доступна только на десктопе. */
#menu-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
#menu-table th.sortable::after {
  content: "↕";
  margin-left: 0.25rem;
  opacity: 0.4;
  font-size: 0.85em;
}
#menu-table th.sortable:hover { color: var(--text); }
#menu-table th.sortable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#menu-table th.sorted-asc::after { content: "↑"; opacity: 1; color: var(--accent); }
#menu-table th.sorted-desc::after { content: "↓"; opacity: 1; color: var(--accent); }

/* === Мобильная адаптация (iPhone 13 Pro = 390px и аналогичные) ===
   Решения:
   - body, секции получают меньший padding
   - Форма «Добавить приём» — 1 колонка (на 370px две стало бы по 175px)
   - Таблицы приёмов/недели/месяца/года переключаются с табличного вида
     на карточный: имя/период сверху, БЖУ в одну строку через разделители,
     никакого горизонтального скролла */
@media (max-width: 600px) {
  /* Off-canvas меню с transform: translateX(100%) на iOS Safari расширяет
     вьюпорт вправо — пресекаем горизонтальный скролл. */
  html, body { overflow-x: hidden; }
  body { padding: 0.75rem; }
  main > section { padding: 0.9rem 1rem; }
  h1 { font-size: 1.25rem; }
  h2 { font-size: 1rem; }

  /* Шапка-навигация — мельче, чтобы помещалось */
  nav a { font-size: 0.9rem; }
  .day-controls { gap: 0.5rem; font-size: 0.9rem; }
  .date-nav { gap: 0.2rem; }

  /* Ряд иконок действий (гамбургер · Админ · Настройки · Выход · Тема) на узком
     экране упирался в правый край — уплотняем промежутки, чтобы сдвинуть влево. */
  .auth-info { gap: 0.3rem; }

  /* Табы прячем на мобиле, показываем через гамбургер-меню справа.
     nav сразу позиционируем как закрытую off-canvas-панель — чтобы при
     открытии/закрытии плавно анимировался transform, а не «появлялся»
     элемент через display: none. */
  nav.page-tabs {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 78vw;
    max-width: 320px;
    background: var(--surface);
    border-left: 1px solid var(--border-strong);
    padding: 4.5rem 0 1.25rem;
    z-index: 1000;
    overflow-y: auto;
    box-shadow: -8px 0 32px rgba(0,0,0,0.3);
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
    visibility: hidden;
  }
  .menu-toggle { display: inline-flex; }

  body.menu-open nav.page-tabs {
    transform: translateX(0);
    visibility: visible;
  }

  /* Крестик при открытом меню — фиксированно в правом верхнем углу,
     поверх всего. По дефолту .menu-toggle сидит в auth-info; здесь
     перебрасываем его в правый край и поднимаем над панелью. */
  body.menu-open .menu-toggle {
    position: fixed;
    top: 1.1rem;
    right: 1rem;
    z-index: 1002;
  }

  nav.page-tabs a,
  nav.page-tabs .page-tabs-disabled {
    padding: 0.9rem 1.25rem;
    margin: 0;
    font-size: 1rem;
    border-radius: 0;
    border-bottom: 1px solid var(--border);
    border-left: 3px solid transparent;
    transition: background 0.15s, border-left-color 0.15s, color 0.15s;
  }
  /* Перебиваем глобальный nav.page-tabs a:first-child { padding-left: 0 }
     с десктопного горизонтального ряда — в мобильной панели все пункты
     должны быть выровнены по одной вертикали. */
  nav.page-tabs a:first-child { padding-left: 1.25rem; }
  nav.page-tabs a:hover {
    background: var(--surface-alt);
    text-decoration: none;
  }
  nav.page-tabs a:active { background: var(--accent-soft); }
  nav.page-tabs a.current {
    border-bottom-color: var(--border);
    border-left-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
  }
  /* «Скоро»-пункты — визуально отделены сверху как отдельная группа. */
  nav.page-tabs .page-tabs-disabled:first-of-type {
    margin-top: 0.5rem;
    border-top: 1px dashed var(--border);
  }

  /* Тёмная подложка с blur под меню */
  body.menu-open::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    z-index: 999;
    animation: menu-backdrop-fade 0.25s ease-out;
  }
  @keyframes menu-backdrop-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  /* Блокируем скролл боди когда меню открыто */
  body.menu-open { overflow: hidden; }

  /* Анимированный бургер: вращаем кнопку при открытии */
  .menu-toggle { transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1); }
  body.menu-open .menu-toggle { transform: rotate(90deg); }

  /* Заголовок страницы — одной строкой даже на узких экранах */
  header > h1 { white-space: nowrap; font-size: 1.1rem; }

  /* Главная: разделы в столбик (а не в строку), каждая кнопка на всю ширину. */
  .big-nav { display: flex; flex-direction: column; gap: 0.5rem; }
  .big-nav a { display: block; text-align: center; padding: 0.75rem 1rem; }

  /* Дата/Время в форме — значения слева, не центрируются. На iOS Safari
     для native date/time pickers text-align игнорируется, нужно через
     ::-webkit-date-and-time-value. */
  #meal-form input[type="date"],
  #meal-form input[type="time"] { text-align: left; }
  #meal-form input[type="date"]::-webkit-date-and-time-value,
  #meal-form input[type="time"]::-webkit-date-and-time-value {
    text-align: left;
    margin-right: auto;
  }

  /* === Форма приёма — 1 колонка === */
  #meal-form { grid-template-columns: 1fr; gap: 0.6rem; }
  #meal-form label { grid-template-columns: 5.5rem 1fr; font-size: 0.92rem; }
  #meal-form .new-food-grid { grid-template-columns: 1fr 1fr; gap: 0.5rem; }

  /* Мобилка: переопределяем 7.5rem 14rem с десктопа — на 390px 14rem-инпут
     не влезает. Фиксированная 6rem колонка лейбла, чтобы инпут «Моя доля» и
     селект «С кем» получили одинаковую ширину (max-content давал разные
     первые колонки → разные вторые). */
  .share-fields label,
  #meal-form .share-fields label { grid-template-columns: 6rem 1fr; }
  .share-partner-hint { padding-left: 6.5rem; }

  /* === Таблица приёмов — карточный вид === */
  #meals-table { display: block; font-size: 0.9rem; }
  #meals-table thead { display: none; }
  #meals-table tbody { display: block; }
  #meals-table tr {
    display: block;
    /* padding-left совпадает с meal-group-header чтобы текст «сырники»
       был на одном уровне с «Завтрак». */
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
    position: relative;
  }
  /* Заголовок meal-group остаётся как баннер. На мобиле фон переносим на
     всю строку, а ячейки делаем прозрачными — иначе инлайн-суммы (Вес/Ккал/
     Б/Ж/У) выглядят как отдельные боксы с зазорами. */
  #meals-table tr.meal-group-header {
    padding: 0.4rem 0.6rem;
    background: var(--group-bg);
    border-radius: 6px;
  }
  #meals-table tr.meal-group-header th { background: none; border-radius: 0; }
  /* Первая ячейка (тип + время) — строка-заголовок баннера. */
  #meals-table tr.meal-group-header th:nth-child(1) {
    display: block;
    width: 100%;
    padding: 0;
    margin-bottom: 0.15rem;
  }
  /* Пустая «Источник» и хвостовая actions-ячейка не нужны на мобиле. */
  #meals-table tr.meal-group-header th:nth-child(2),
  #meals-table tr.meal-group-header th:nth-child(8) { display: none; }
  /* Суммы Вес/Ккал/Б/Ж/У — второй строкой инлайном с подписями. */
  #meals-table tr.meal-group-header th:nth-child(n+3):nth-child(-n+7) {
    display: inline;
    width: auto;
    padding: 0;
    text-align: left;
    white-space: normal;
    font-weight: normal;
    font-size: 0.82rem;
    color: var(--group-label);
    opacity: 0.85;
  }
  #meals-table tr.meal-group-header th:nth-child(3)::after { content: ' г'; }
  #meals-table tr.meal-group-header th:nth-child(4)::before { content: ' · '; }
  #meals-table tr.meal-group-header th:nth-child(4)::after { content: ' ккал'; }
  #meals-table tr.meal-group-header th:nth-child(5)::before { content: ' · Б '; }
  #meals-table tr.meal-group-header th:nth-child(6)::before { content: ' Ж '; }
  #meals-table tr.meal-group-header th:nth-child(7)::before { content: ' У '; }

  #meals-table td {
    display: inline;
    border: none;
    padding: 0;
    text-align: left;
    width: auto;
    white-space: normal;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  /* Имя продукта — отдельная строка сверху */
  #meals-table td:nth-child(1) {
    display: block;
    color: var(--text);
    font-size: 0.92rem;
    font-weight: 500;
    margin-bottom: 0.15rem;
    padding-right: 6.25rem;  /* место под actions (2 кнопки 44×44 + gap + 0.6rem right) */
  }
  /* Источник на отдельной строке если есть; «—» (.muted) визуально скрываем */
  #meals-table td:nth-child(2) {
    display: block;
    font-size: 0.82rem;
    margin-bottom: 0.1rem;
  }
  #meals-table td:nth-child(2):has(.muted) { display: none; }
  /* Числовые ячейки — inline с подписями через ::before/::after */
  #meals-table td:nth-child(3)::after { content: 'г'; }
  #meals-table td:nth-child(4)::before { content: ' · '; }
  #meals-table td:nth-child(4)::after { content: ' ккал'; }
  #meals-table td:nth-child(5)::before { content: ' · Б '; }
  #meals-table td:nth-child(6)::before { content: ' Ж '; }
  #meals-table td:nth-child(7)::before { content: ' У '; }
  /* Actions прижимаем в правый верх «карточки» (с учётом padding-right ряда).
     Явный flex-nowrap — чтобы 2 кнопки никогда не переносились на 2 строки
     (Safari в этом строже Chrome). */
  #meals-table td.actions {
    position: absolute;
    top: 0.4rem;
    right: 0.6rem;
    display: flex;
    flex-wrap: nowrap;
    gap: 0.25rem;
  }
  #meals-table td.actions button { margin: 0; }

  /* === Итого: 2-строчная карточка в стиле tfoot недели/месяца ===
     tfoot tr: 1=th«Итого», 2=td пустой vendor, 3=grams, 4=kcal,
     5=protein, 6=fat, 7=carbs, 8=td пустой actions.
     Строка 1: «Итого» ... grams · kcal
     Строка 2: Б X · Ж Y · У Z */
  #meals-table tfoot { display: block; }
  #meals-table tfoot tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.6rem;
    border-top: 2px solid var(--border);
    border-bottom: none;
    margin-top: 0.25rem;
  }
  #meals-table tfoot tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
    order: 4;
  }
  #meals-table tfoot th,
  #meals-table tfoot td {
    font-size: 0.85rem;
    color: var(--text-muted);
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    flex: 0 0 auto;
    font-weight: 400;
  }
  #meals-table tfoot th:first-child {
    order: 1;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
    margin-right: auto;
  }
  /* Скрываем пустые ячейки vendor (2) и actions (8) */
  #meals-table tfoot td:nth-child(2),
  #meals-table tfoot td:nth-child(8) { display: none; }
  /* Ккал — в верхней строке справа от «Итого» */
  #meals-table tfoot td:nth-child(4) {
    order: 2;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #meals-table tfoot td:nth-child(4)::before { content: none; }
  #meals-table tfoot td:nth-child(4)::after {
    content: ' ккал';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  /* Граммы · Б · Ж · У — во второй строке */
  #meals-table tfoot td:nth-child(3) { order: 5; }
  #meals-table tfoot td:nth-child(3)::after { content: ' г'; color: var(--text-muted); }
  #meals-table tfoot td:nth-child(5) { order: 6; }
  #meals-table tfoot td:nth-child(6) { order: 7; }
  #meals-table tfoot td:nth-child(7) { order: 8; }
  #meals-table tfoot td:nth-child(5)::before { content: '· Б '; }
  #meals-table tfoot td:nth-child(6)::before { content: '· Ж '; }
  #meals-table tfoot td:nth-child(7)::before { content: '· У '; }

  /* === Каталог продуктов — карточный вид на мобиле ===
     Чтобы избавиться от горизонтального скролла и iOS-инфлейта шрифта в
     широких блоках. Структура карточки повторяет /day.html (meals-table):
     заголовок-имя сверху, источник мелко, BJU/Ккал/×N инлайн снизу,
     actions прижаты в правый верх. */
  #foods-table { display: block; font-size: 0.9rem; }
  #foods-table thead { display: none; }
  #foods-table tbody { display: block; }
  #foods-table tr {
    display: block;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
    position: relative;
  }
  #foods-table td {
    display: inline;
    border: none;
    padding: 0;
    text-align: left;
    width: auto;
    white-space: normal;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  /* 1) Название продукта — на отдельной строке, основной цвет.
     Правый отступ под actions теперь на всей карточке (tr padding-right). */
  #foods-table td:nth-child(1) {
    display: block;
    color: var(--text);
    font-size: 0.85rem;
    margin-bottom: 0.15rem;
  }
  /* 2) Источник — мелко на отдельной строке; «—» (.muted) скрываем. */
  #foods-table td:nth-child(2) {
    display: block;
    font-size: 0.8rem;
    margin-bottom: 0.1rem;
    min-width: 0;  /* перебиваем десктопный min-width: 7rem */
  }
  #foods-table td:nth-child(2):has(.muted) { display: none; }
  /* 3-8) Числовые ячейки — инлайн с подписями через ::before/::after,
     перебиваем десктопное text-align: right + width 4.5rem. */
  #foods-table td:nth-child(n+3):nth-child(-n+8) {
    text-align: left;
    width: auto;
    white-space: normal;
  }
  /* Ккал (3) — крупнее и bold, главный показатель. */
  #foods-table td:nth-child(3) {
    font-weight: 600;
    color: var(--text);
  }
  #foods-table td:nth-child(3)::after { content: ' ккал'; }
  #foods-table td:nth-child(4)::before { content: ' · Б '; }
  #foods-table td:nth-child(5)::before { content: ' Ж '; }
  #foods-table td:nth-child(6)::before { content: ' У '; }
  /* Сп (7) — показываем только если значение > 0; «0» прячем чтобы не
     засорять карточки безалкогольных продуктов. */
  #foods-table td:nth-child(7)::before { content: ' Сп '; }
  /* ×N (8) — отдельной строкой снизу как «использовано в N приёмах». */
  #foods-table td:nth-child(8) {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.8rem;
  }
  #foods-table td:nth-child(8)::before { content: '× '; }
  /* Actions — отдельной строкой справа ВНИЗУ карточки, в обычном потоке.
     Раньше были absolute в правом верхнем углу и при 3 кнопках наезжали на БЖУ /
     уезжали за край. В потоке кнопки всегда видны и ничего не перекрывают. */
  #foods-table td.actions {
    display: flex;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 0.4rem;
    padding: 0;
    margin-top: 0.4rem;
  }
  #foods-table td.actions button { margin: 0; }
  /* Названия в источниках — тот же размер для консистентности. */
  #vendors-table td:first-child { font-size: 0.85rem; }

  /* Кликабельный ×N на мобиле — чип-кнопка с тач-зоной ≥32px высотой,
     чтобы тыкаемость не зависела от 4-пиксельного dotted-underline десктопа.
     display:block + width:fit-content — чтобы чип всегда был на своей строке,
     а не цеплялся к концу БЖУ-строки и не «прыгал» в зависимости от длины
     названия продукта. */
  #foods-table td.meals-count-cell,
  #vendors-table td.meals-count-cell {
    display: block;
    width: max-content !important;
    padding: 0.25rem 0.7rem;
    min-height: 32px;
    line-height: 1.4;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--surface-alt);
    color: var(--text);
    text-decoration: none;
    margin: 0.15rem 0;
    font-size: 0.85rem;
    white-space: nowrap;
  }
  #foods-table td.meals-count-cell:active,
  #vendors-table td.meals-count-cell:active {
    background: var(--accent-soft);
    border-color: var(--accent);
  }
  /* Префикс '× ' у inUse-чипа держим через ::before (не дублирует базовый
     td:nth-child(8)::before — в чипе display:inline-block, не block). */
  #foods-table td.meals-count-cell::before {
    content: '× ';
    color: var(--text-muted);
  }
  #vendors-table td.meals-count-cell::before {
    content: '× ';
    color: var(--text-muted);
  }

  /* Источники на мобиле: таблица из 3 узких колонок плохо тыкается.
     Делаем карточный вид как у каталога — название блоком, ×N чипом снизу. */
  #vendors-table { display: block; font-size: 0.9rem; }
  #vendors-table thead { display: none; }
  #vendors-table tbody { display: block; }
  #vendors-table tr {
    display: block;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
    position: relative;
  }
  #vendors-table td {
    display: inline;
    border: none;
    padding: 0;
    text-align: left;
    width: auto;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  #vendors-table td:nth-child(1) {
    display: block;
    color: var(--text);
    margin-bottom: 0.15rem;
    padding-right: 6.25rem;  /* место под actions (2 кнопки 44×44 + gap + 0.6rem right) */
  }
  #vendors-table td:nth-child(2) { display: inline-block; }
  #vendors-table td.actions {
    position: absolute;
    display: flex;
    flex-wrap: nowrap;
    gap: 0.25rem;
    top: 0.4rem;
    right: 0.6rem;
    padding: 0;
  }
  #vendors-table tr.editing td { display: block; padding: 0.2rem 0; width: 100%; }
  #vendors-table tr.editing td.actions { position: static; text-align: right; }

  /* В режиме inline-edit на мобиле — инпуты в столбик, иначе 9 ячеек
     в строке не влезут на 360px. */
  #foods-table tr.editing { display: block; padding: 0.6rem; }
  #foods-table tr.editing td {
    display: block;
    padding: 0.2rem 0;
    width: 100%;
    color: var(--text);
    font-size: 0.85rem;
  }
  #foods-table tr.editing td::before,
  #foods-table tr.editing td::after { content: none; }
  /* Подписи в edit-режиме на мобиле — отдельной строкой над инпутом,
     иначе input[list] (нативный комбобокс iOS) уезжает за пределы карточки. */
  #foods-table tr.editing td[data-edit-label]::before {
    content: attr(data-edit-label);
    display: block;
    margin-bottom: 0.2rem;
    color: var(--text-muted);
    font-size: 0.8rem;
  }
  #foods-table tr.editing td.actions {
    position: static;
    text-align: right;
    padding-top: 0.4rem;
  }

  /* === Меню ресторанов — карточный вид на мобиле (паттерн foods-table). === */
  .menus-filter { grid-template-columns: 1fr; }
  .menu-sort-wrap { display: block; }  /* заголовки скрыты → сортировка через кастом-дропдаун */
  #menu-table { display: block; font-size: 0.9rem; }
  #menu-table thead { display: none; }
  #menu-table tbody { display: block; }
  #menu-table tr {
    display: block;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
    position: relative;
  }
  #menu-table td {
    display: inline;
    border: none;
    padding: 0;
    text-align: left;
    width: auto;
    white-space: normal;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  #menu-table td:nth-child(1) {
    display: block;
    color: var(--text);
    font-size: 0.85rem;
    margin-bottom: 0.15rem;
  }
  /* Числовые ячейки (Ккал·2 / Б·3 / Ж·4 / У·5 / Порция·6 / Ккал·порц·7) — inline. */
  #menu-table td:nth-child(n+2):nth-child(-n+7) {
    text-align: left;
    width: auto;
    white-space: normal;
  }
  #menu-table td:nth-child(2) { font-weight: 600; color: var(--text); }
  #menu-table td:nth-child(2)::after { content: ' ккал'; }
  #menu-table td:nth-child(3)::before { content: ' · Б '; }
  #menu-table td:nth-child(4)::before { content: ' Ж '; }
  #menu-table td:nth-child(5)::before { content: ' У '; }
  #menu-table td:nth-child(6)::before { content: ' · '; }
  #menu-table td:nth-child(6)::after { content: ' г'; }
  #menu-table td:nth-child(6):has(.muted)::after { content: none; }
  #menu-table td:nth-child(7)::before { content: ' · '; }
  #menu-table td:nth-child(7)::after { content: ' ккал/порц'; }
  #menu-table td:nth-child(7):has(.muted) { display: none; }
  #menu-table td:nth-child(8) {
    display: block;
    margin-top: 0.2rem;
  }
  #menu-table td:nth-child(8):has(.muted) { display: none; }
  #menu-table td.actions {
    display: flex;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 0.4rem;
    padding: 0;
    margin-top: 0.4rem;
  }
  #menu-table td.actions button { margin: 0; }
  #menu-table tr.editing { display: block; padding: 0.6rem; }
  #menu-table tr.editing td {
    display: block;
    padding: 0.2rem 0;
    width: 100%;
    color: var(--text);
    font-size: 0.85rem;
  }
  #menu-table tr.editing td::before,
  #menu-table tr.editing td::after { content: none; }
  #menu-table tr.editing td[data-edit-label]::before {
    content: attr(data-edit-label);
    display: block;
    margin-bottom: 0.2rem;
    color: var(--text-muted);
    font-size: 0.8rem;
  }
  #menu-table tr.editing td.actions {
    position: static;
    text-align: right;
    padding-top: 0.4rem;
  }

  /* БЖУ-блок на мобиле: лейбл над инпутом (вместо «лейбл слева 7rem»).
     Иначе на 360px ширины инпуту остаётся ~60px и в нём не виден ни placeholder,
     ни вводимое значение. Сохраняем 2×2 сетку по горизонтали. */
  #add-form .bju-grid label {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  /* === Недельная/месячная/годовая таблицы — тоже карточный вид === */
  #week-table, #month-table, #year-table {
    display: block;
    font-size: 0.9rem;
  }
  #week-table thead, #month-table thead, #year-table thead { display: none; }
  #week-table tbody, #month-table tbody, #year-table tbody { display: block; }
  #week-table tr, #month-table tr, #year-table tr {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.15rem 0.5rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
  }
  #week-table td, #month-table td, #year-table td,
  #week-table th, #month-table th, #year-table th {
    display: inline;
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    font-size: 0.85rem;
    white-space: normal;
  }
  /* День/период на видном месте */
  #week-table tr td:first-child,
  #month-table tr td:first-child,
  #year-table tr td:first-child {
    grid-column: 1 / -1;
    font-weight: 600;
    color: var(--text);
    font-size: 0.95rem;
    margin-bottom: 0.1rem;
  }
  /* Δ — справа, выделено */
  #week-table tr td.delta,
  #month-table tr td.delta,
  #year-table tr td.delta {
    grid-column: 1 / -1;
    text-align: right;
    font-size: 0.9rem;
  }
  /* Числовые ячейки внутри inline-row */
  #week-table tr td:nth-child(3)::after,
  #month-table tr td:nth-child(3)::after { content: ' ккал'; }
  #week-table tr td:nth-child(4)::before,
  #month-table tr td:nth-child(4)::before { content: ' · Б '; }
  #week-table tr td:nth-child(5)::before,
  #month-table tr td:nth-child(5)::before { content: ' Ж '; }
  #week-table tr td:nth-child(6)::before,
  #month-table tr td:nth-child(6)::before { content: ' У '; }
  /* Footer (среднее за дни) — рендерится отдельным блоком */
  #week-table tfoot, #month-table tfoot { display: none; }

  /* === Годовые таблицы сна/активности → карточный вид === */
  #sleep-year-table, #activity-year-table { display: block; font-size: 0.9rem; }
  #sleep-year-table thead, #activity-year-table thead { display: none; }
  #sleep-year-table tbody, #activity-year-table tbody,
  #sleep-year-table tfoot, #activity-year-table tfoot { display: block; }
  #sleep-year-table tr, #activity-year-table tr {
    display: block;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
  }
  #sleep-year-table td, #activity-year-table td,
  #sleep-year-table th, #activity-year-table th {
    display: inline;
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    font-size: 0.85rem;
    white-space: normal;
  }
  /* Месяц (tbody) и «За год» (tfoot) — отдельной строкой, жирно */
  #sleep-year-table tbody td:first-child, #activity-year-table tbody td:first-child,
  #sleep-year-table tfoot th:first-child, #activity-year-table tfoot th:first-child {
    display: block;
    font-weight: 600;
    color: var(--text);
    font-size: 0.95rem;
    margin-bottom: 0.1rem;
  }
  /* Подписи числовых ячеек — через ::before/::after (label = заголовок столбца).
   * nth-child считает и th, поэтому правила работают и для tbody, и для tfoot. */
  #sleep-year-table td:nth-child(2)::after  { content: ' ноч.'; }
  #sleep-year-table td:nth-child(3)::before { content: 'сон '; }
  #sleep-year-table td:nth-child(4)::before { content: ' · глуб '; }
  #sleep-year-table td:nth-child(5)::before { content: ' · быстр '; }
  #sleep-year-table td:nth-child(6)::before { content: ' · HRV '; }
  #activity-year-table td:nth-child(2)::after  { content: ' дн.'; }
  #activity-year-table td:nth-child(3)::before { content: 'ккал '; }
  #activity-year-table td:nth-child(4)::before { content: ' · шаги '; }
  #activity-year-table td:nth-child(5)::before { content: ' · '; }
  #activity-year-table td:nth-child(5)::after  { content: ' км'; }
  #activity-year-table td:nth-child(6)::before { content: ' · подъём '; }
  #activity-year-table td:nth-child(6)::after  { content: ' м'; }
  #sleep-year-table tfoot tr, #activity-year-table tfoot tr {
    border-bottom: none;
    border-top: 2px solid var(--border-strong);
  }

  /* Раскрытие детализации дня на /week.html — оставляем работать,
     просто содержимое узкое. */
  #week-table tr.day-detail-row > td {
    grid-column: 1 / -1;
    display: block;
    padding: 0.4rem 0.5rem;
    font-size: 0.85rem;
  }
  ul.day-detail li {
    grid-template-columns: 3rem 4.5rem 5rem 1fr;
    font-size: 0.8rem;
  }
  /* Мобайл: Б/Ж/У стэком по строкам, без слешей */
  ul.day-detail .dt-bju {
    display: flex;
    flex-direction: column;
    line-height: 1.35;
  }
  ul.day-detail .dt-bju > span + span::before { content: none; margin: 0; }

  /* === Неделя: компактные карточки-строки на мобильном ===
     Переопределяем общие правила выше: каждый день — flex-карточка с тремя
     строками. Принудительные line-breaks через ::before / ::after с
     order'ом и flex-basis: 100%. nth-child привязка для day-row:
     1=дата, 2=weekday, 3=ккал, 4=Б, 5=Ж, 6=У, 7=Сп, 8=Потр, 9=Δ. */
  #week-table tr.day-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
  }
  /* Принудительные переносы строк: ::before между ккал и Б, ::after между Сп и Потр */
  #week-table tr.day-row::before,
  #week-table tr.day-row::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #week-table tr.day-row::before { order: 4; }
  #week-table tr.day-row::after { order: 9; }
  #week-table tr.day-row > td {
    font-size: 0.85rem;
    color: var(--text-muted);
    width: auto;
    flex: 0 0 auto;
  }
  #week-table tr.day-row > td:first-child {
    grid-column: auto;
    order: 1;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0;
    padding-right: 0;
  }
  #week-table tr.day-row > td.weekday {
    order: 2;
    color: var(--text-muted);
    margin-right: auto;
    padding-left: 0;
  }
  /* ккал-итог — жирно, в конце строки 1 */
  #week-table tr.day-row > td:nth-child(3) {
    order: 3;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #week-table tr.day-row > td:nth-child(3)::after {
    content: ' ккал';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  /* Строка 2: Б · Ж · У · Сп — все в одной */
  #week-table tr.day-row > td:nth-child(4) { order: 5; }
  #week-table tr.day-row > td:nth-child(5) { order: 6; }
  #week-table tr.day-row > td:nth-child(6) { order: 7; }
  #week-table tr.day-row > td:nth-child(7) { order: 8; }
  #week-table tr.day-row > td:nth-child(4)::before { content: 'Б '; }
  #week-table tr.day-row > td:nth-child(5)::before { content: '· Ж '; }
  #week-table tr.day-row > td:nth-child(6)::before { content: '· У '; }
  #week-table tr.day-row > td:nth-child(7)::before { content: '· Сп '; }
  /* Строка 3: Потр слева, Δ справа */
  #week-table tr.day-row > td:nth-child(8) { order: 10; }
  #week-table tr.day-row > td:nth-child(8)::before { content: 'Расход '; }
  #week-table tr.day-row > td.delta {
    grid-column: auto;
    order: 11;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }

  /* === Итого: показываем tfoot на мобильном тем же 3-строчным шаблоном ===
     В tfoot структура другая (th colspan=2 + 7 td), nth-child: 1=th, 2=ккал,
     3=Б, 4=Ж, 5=У, 6=Сп, 7=Потр, 8=Δ. */
  #week-table tfoot { display: block; }
  #week-table tfoot tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
    border-top: 2px solid var(--border);
    margin-top: 0.25rem;
  }
  #week-table tfoot tr::before,
  #week-table tfoot tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #week-table tfoot tr::before { order: 3; }
  #week-table tfoot tr::after { order: 8; }
  #week-table tfoot th,
  #week-table tfoot td {
    font-size: 0.85rem;
    color: var(--text-muted);
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    flex: 0 0 auto;
    font-weight: 400;
  }
  #week-table tfoot th:first-child {
    order: 1;
    font-size: 0.9rem;
    color: var(--text);
    font-weight: 600;
    margin-right: auto;
  }
  /* Текст «В среднем за дни с данными» длинный — заменяем на «Итого» */
  #week-table tfoot th:first-child { font-size: 0; }
  #week-table tfoot th:first-child::before {
    content: 'В среднем';
    font-size: 0.9rem;
  }
  #week-table tfoot td:nth-child(2) {
    order: 2;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #week-table tfoot td:nth-child(2)::after {
    content: ' ккал';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  #week-table tfoot td:nth-child(3) { order: 4; }
  #week-table tfoot td:nth-child(4) { order: 5; }
  #week-table tfoot td:nth-child(5) { order: 6; }
  #week-table tfoot td:nth-child(6) { order: 7; }
  #week-table tfoot td:nth-child(3)::before { content: 'Б '; }
  #week-table tfoot td:nth-child(4)::before { content: '· Ж '; }
  #week-table tfoot td:nth-child(5)::before { content: '· У '; }
  #week-table tfoot td:nth-child(6)::before { content: '· Сп '; }
  #week-table tfoot td:nth-child(7) { order: 9; }
  #week-table tfoot td:nth-child(7)::before { content: 'Расход '; }
  #week-table tfoot td:nth-child(8) {
    order: 10;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }

  /* === Месяц: тот же 3-строчный шаблон, что и неделя ===
     nth-child в tbody tr: 1=дата, 2=weekday, 3=ккал, 4=Б, 5=Ж, 6=У, 7=Сп, 8=Расход, 9=Δ. */
  #month-table tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
    border-bottom: 1px solid var(--border);
  }
  #month-table tbody tr::before,
  #month-table tbody tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #month-table tbody tr::before { order: 4; }
  #month-table tbody tr::after { order: 9; }
  #month-table tbody tr > td {
    font-size: 0.85rem;
    color: var(--text-muted);
    width: auto;
    flex: 0 0 auto;
    padding: 0;
    border: none;
  }
  #month-table tbody tr > td:first-child {
    grid-column: auto;
    order: 1;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0;
    padding-right: 0;
  }
  #month-table tbody tr > td.weekday {
    order: 2;
    color: var(--text-muted);
    margin-right: auto;
    padding-left: 0;
  }
  #month-table tbody tr > td:nth-child(3) {
    order: 3;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #month-table tbody tr > td:nth-child(3)::after {
    content: ' ккал';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  #month-table tbody tr > td:nth-child(4) { order: 5; }
  #month-table tbody tr > td:nth-child(5) { order: 6; }
  #month-table tbody tr > td:nth-child(6) { order: 7; }
  #month-table tbody tr > td:nth-child(7) { order: 8; }
  #month-table tbody tr > td:nth-child(4)::before { content: 'Б '; }
  #month-table tbody tr > td:nth-child(5)::before { content: '· Ж '; }
  #month-table tbody tr > td:nth-child(6)::before { content: '· У '; }
  #month-table tbody tr > td:nth-child(7)::before { content: '· Сп '; }
  #month-table tbody tr > td:nth-child(8) { order: 10; }
  #month-table tbody tr > td:nth-child(8)::before { content: 'Расход '; }
  #month-table tbody tr > td.delta {
    grid-column: auto;
    order: 11;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }
  /* Итого для месяца */
  #month-table tfoot { display: block; }
  #month-table tfoot tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
    border-top: 2px solid var(--border);
    margin-top: 0.25rem;
  }
  #month-table tfoot tr::before,
  #month-table tfoot tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #month-table tfoot tr::before { order: 3; }
  #month-table tfoot tr::after { order: 8; }
  #month-table tfoot th,
  #month-table tfoot td {
    font-size: 0.85rem;
    color: var(--text-muted);
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    flex: 0 0 auto;
    font-weight: 400;
  }
  #month-table tfoot th:first-child {
    order: 1;
    font-size: 0;
    margin-right: auto;
  }
  #month-table tfoot th:first-child::before {
    content: 'В среднем';
    font-size: 0.9rem;
    color: var(--text);
    font-weight: 600;
  }
  #month-table tfoot td:nth-child(2) {
    order: 2;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #month-table tfoot td:nth-child(2)::after {
    content: ' ккал';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  #month-table tfoot td:nth-child(3) { order: 4; }
  #month-table tfoot td:nth-child(4) { order: 5; }
  #month-table tfoot td:nth-child(5) { order: 6; }
  #month-table tfoot td:nth-child(6) { order: 7; }
  #month-table tfoot td:nth-child(3)::before { content: 'Б '; }
  #month-table tfoot td:nth-child(4)::before { content: '· Ж '; }
  #month-table tfoot td:nth-child(5)::before { content: '· У '; }
  #month-table tfoot td:nth-child(6)::before { content: '· Сп '; }
  #month-table tfoot td:nth-child(7) { order: 9; }
  #month-table tfoot td:nth-child(7)::before { content: 'Расход '; }
  #month-table tfoot td:nth-child(8) {
    order: 10;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }

  /* === Год: 9 колонок (без тотала Ккал) ===
     nth-child в tbody tr: 1=месяц, 2=дней, 3=сред.ккал/день, 4=Б, 5=Ж,
     6=У, 7=Сп, 8=Расход, 9=Δ.
     Раскладка: [месяц · X дн ............... ≈ X/день]
                [сред./день · Б · Ж · У · Сп]
                [Расход X/день ............... Δ]. */
  #year-table tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
    border-bottom: 1px solid var(--border);
  }
  #year-table tbody tr::before,
  #year-table tbody tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #year-table tbody tr::before { order: 4; }
  #year-table tbody tr::after { order: 10; }
  #year-table tbody tr > td {
    font-size: 0.85rem;
    color: var(--text-muted);
    width: auto;
    flex: 0 0 auto;
    padding: 0;
    border: none;
  }
  #year-table tbody tr > td:first-child {
    order: 1;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
    padding-right: 0;
  }
  #year-table tbody tr > td:nth-child(2) {
    order: 2;
    margin-right: auto;
    margin-left: 0.5rem;
    padding-left: 0;
  }
  #year-table tbody tr > td:nth-child(2)::before { content: '· '; }
  #year-table tbody tr > td:nth-child(2)::after { content: ' дн.'; }
  /* Колонка 3 — Сред. ккал/день, headline 1-й строки справа */
  #year-table tbody tr > td:nth-child(3) {
    order: 3;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #year-table tbody tr > td:nth-child(3)::before { content: '≈ '; font-weight: 400; }
  #year-table tbody tr > td:nth-child(3)::after {
    content: '/день';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  /* avg Б Ж У Сп — первый (Б) несёт якорь «сред./день» для всей серии,
     идут одной строкой на 2-й строке карточки */
  #year-table tbody tr > td:nth-child(4) { order: 5; }
  #year-table tbody tr > td:nth-child(5) { order: 6; }
  #year-table tbody tr > td:nth-child(6) { order: 7; }
  #year-table tbody tr > td:nth-child(7) { order: 8; }
  #year-table tbody tr > td:nth-child(4)::before { content: 'сред./день · Б '; }
  #year-table tbody tr > td:nth-child(5)::before { content: '· Ж '; }
  #year-table tbody tr > td:nth-child(6)::before { content: '· У '; }
  #year-table tbody tr > td:nth-child(7)::before { content: '· Сп '; }
  /* 3-я строка: Расход (сред./день) слева, Δ справа */
  #year-table tbody tr > td:nth-child(8) { order: 11; }
  #year-table tbody tr > td:nth-child(8)::before { content: 'Расход '; }
  #year-table tbody tr > td:nth-child(8)::after { content: '/день'; color: var(--text-faint); font-size: 0.75rem; margin-left: 0.15rem; }
  #year-table tbody tr > td.delta {
    grid-column: auto;
    order: 12;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }

  /* Бан на desktop-ужатие первой/второй колонки — на мобиле ячейки flex-карточки,
     иначе width:1% сжимает их до 1% и контент налезает на соседей. */
  #week-table td.day-date,
  #week-table td.weekday,
  #month-table tbody tr > td:first-child,
  #month-table tbody tr > td.weekday,
  #year-table tbody tr > td:first-child { width: auto; }

  /* Итого для года: tfoot карточка по той же 3-строчной схеме.
     В tfoot из-за <th colspan=2> nth-child: 1=th, 2=avg ккал/день,
     3=avg Б, 4=avg Ж, 5=avg У, 6=avg Сп, 7=Расход, 8=Δ. */
  #year-table tfoot { display: block; }
  #year-table tfoot tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.4rem;
    row-gap: 0.2rem;
    padding: 0.6rem 0.25rem;
    border-top: 2px solid var(--border);
    margin-top: 0.25rem;
  }
  #year-table tfoot tr::before,
  #year-table tfoot tr::after {
    content: "";
    flex-basis: 100%;
    height: 0;
  }
  #year-table tfoot tr::before { order: 4; }
  #year-table tfoot tr::after { order: 10; }
  #year-table tfoot th,
  #year-table tfoot td {
    font-size: 0.85rem;
    color: var(--text-muted);
    padding: 0;
    border: none;
    text-align: left;
    width: auto;
    flex: 0 0 auto;
    font-weight: 400;
  }
  #year-table tfoot th:first-child {
    order: 1;
    font-size: 0;
    margin-right: auto;
  }
  #year-table tfoot th:first-child::before {
    content: 'За год';
    font-size: 0.9rem;
    color: var(--text);
    font-weight: 600;
  }
  /* avg ккал/день — headline (1-я строка, справа) */
  #year-table tfoot td:nth-child(2) {
    order: 3;
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
  }
  #year-table tfoot td:nth-child(2)::before { content: '≈ '; font-weight: 400; }
  #year-table tfoot td:nth-child(2)::after {
    content: '/день';
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.8rem;
  }
  /* avg Б Ж У Сп — первый (Б) несёт якорь «сред./день» для всей серии */
  #year-table tfoot td:nth-child(3) { order: 5; }
  #year-table tfoot td:nth-child(4) { order: 6; }
  #year-table tfoot td:nth-child(5) { order: 7; }
  #year-table tfoot td:nth-child(6) { order: 8; }
  #year-table tfoot td:nth-child(3)::before { content: 'сред./день · Б '; }
  #year-table tfoot td:nth-child(4)::before { content: '· Ж '; }
  #year-table tfoot td:nth-child(5)::before { content: '· У '; }
  #year-table tfoot td:nth-child(6)::before { content: '· Сп '; }
  /* 3-я строка: Расход (сред./день) слева, Δ справа */
  #year-table tfoot td:nth-child(7) { order: 11; }
  #year-table tfoot td:nth-child(7)::before { content: 'Расход '; }
  #year-table tfoot td:nth-child(7)::after { content: '/день'; color: var(--text-faint); font-size: 0.75rem; margin-left: 0.15rem; }
  #year-table tfoot td:nth-child(8) {
    order: 12;
    margin-left: auto;
    text-align: right;
    font-size: 0.9rem;
  }
}

/* Если экран ОЧЕНЬ узкий (старые iPhone SE = 320px) — ещё компактнее */
@media (max-width: 340px) {
  #meal-form label { grid-template-columns: 4.5rem 1fr; font-size: 0.85rem; }
}

/* === Сворачивание таблицы на /month.html ============================
   По дефолту видны только thead и tfoot («Итого»). Кнопка-тогл рядом —
   раскрывает 30 строк по дням. Состояние не запоминается между визитами. */
.table-toggle-row {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 0.4rem;
}
button.toggle-btn {
  padding: 0.3rem 0.7rem;
  font-size: 0.85rem;
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  margin: 0;
  align-self: auto;
  box-shadow: none;
}
button.toggle-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
  border-color: var(--accent);
}
#month-table.collapsed tbody { display: none; }
/* В свёрнутом виде нижняя граница thead «прижимается» к tfoot — добавляем
   небольшой визуальный разделитель. */
#month-table.collapsed thead tr {
  border-bottom: 2px solid var(--border);
}

/* === SVG-график на /week.html (Δ-bar diverging) ==========================
   Высота бара = |Δ|, цвет = знак: вверх и warn — перебор, вниз и success —
   дефицит. Нулевая ось по центру + подпись значения у бара. Tooltip — общая
   hit-зона на день. */
:root {
  --chart-grid: rgba(0,0,0,0.06);
  --chart-axis: var(--text-faint);
  /* Календарь цикла (profile): месячные и фаза воды; обычные дни — surface-alt. */
  --cycle-menstrual: #d35c78;
  --cycle-water: #5b9bd5;
}
[data-theme="dark"] {
  --chart-grid: rgba(255,255,255,0.07);
  --chart-axis: var(--text-faint);
  --cycle-menstrual: #c25c72;
  --cycle-water: #5e8fc4;
}

.chart-section .chart-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}
.chart-section .chart-header h2 { margin: 0; }
.chart-section + .chart-section { margin-top: 1.5rem; }

/* Заголовок графика + кнопка info рядом, чтобы заголовок-и-i держались
 * вместе (на одной стороне), а легенда/селектор уезжали вправо. Используется
 * и в .chart-section .chart-header, и в .dash-card .dash-head — поэтому
 * селектор без префикса родителя. */
.chart-title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

/* Кнопка-иконка «i» в заголовке графика. По клику открывает попопер
 * с пояснением. Стилизуется приглушённо, чтобы не перетягивать внимание. */
.chart-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text-faint);
  border-radius: 50%;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
  flex-shrink: 0;
}
/* Внутри dash-head-nav у h2 принудительно min-height: 2.25rem (под высоту
 * date-nav кнопок), и при центрировании в этом «раздутом» боксе иконка
 * смещается на ~3px выше центра. Компенсируем сдвигом ровно в этом контексте,
 * чтобы chart-section (естественная высота h2) не пострадал. */
.dash-head.dash-head-nav .chart-info-btn {
  transform: translateY(3px);
}
.chart-info-btn:hover,
.chart-info-btn:focus-visible {
  color: var(--text);
  background: var(--surface-alt);
  outline: none;
}
.chart-info-btn.is-open {
  color: var(--sleep-good);
  background: var(--surface-alt);
}

/* Попопер с пояснением — встраивается между .chart-header и графиком,
 * толкая контент вниз (не absolute, чтобы корректно работало на мобиле
 * и не вылетало за края на мелких экранах). */
.chart-info-popover {
  margin: 0.25rem 0 0.75rem;
  padding: 0.75rem 0.9rem;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-left: 3px solid var(--sleep-good);
  border-radius: 6px;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text);
  animation: chart-info-slide-down 0.18s ease-out;
}
.chart-info-popover p { margin: 0 0 0.5rem; }
.chart-info-popover p:last-child { margin-bottom: 0; }
.chart-info-popover ul {
  margin: 0 0 0.5rem;
  padding-left: 1.1rem;
}
.chart-info-popover ul:last-child { margin-bottom: 0; }
.chart-info-popover li { margin-bottom: 0.15rem; }
.chart-info-popover strong { color: var(--text); }
.chart-info-popover .info-muted { color: var(--text-muted); font-size: 0.82rem; }
.chart-info-popover .info-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  vertical-align: -1px;
  margin-right: 0.25rem;
}
.chart-info-popover .info-swatch.s-bad  { background: var(--sleep-bad); }
.chart-info-popover .info-swatch.s-norm { background: var(--sleep-norm); }
.chart-info-popover .info-swatch.s-good { background: var(--sleep-good); }
.chart-info-popover .info-swatch.s-none { background: var(--sleep-none); border: 1px solid var(--border); }

@keyframes chart-info-slide-down {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.chart-legend {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 0.9rem;
  font-size: 0.85rem;
  color: var(--text-muted);
  flex-wrap: wrap;
}
.chart-legend li { display: inline-flex; align-items: center; gap: 0.35rem; }
.chart-legend .sw {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background: currentColor;
}
.sw-over  { color: var(--warn); }
.sw-under { color: var(--success); }

.chart-wrap {
  position: relative;
  width: 100%;
}
.chart-svg {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
  -webkit-user-select: none;
}
.chart-sub {
  color: var(--text-muted);
  font-size: 0.85rem;
  margin: 0 0 0.5rem;
}
.chart-grid { stroke: var(--chart-grid); stroke-width: 1; }
.chart-zero-axis { stroke: var(--text-muted); stroke-width: 1; }
.chart-axis { fill: var(--chart-axis); font-size: 11px; font-family: inherit; }
.chart-weekday { fill: var(--text-muted); font-size: 12px; font-family: inherit; }
.chart-delta-label { fill: var(--text-muted); font-size: 11px; font-family: inherit; font-weight: 600; }
.bar-over  { fill: var(--warn); }
.bar-under { fill: var(--success); }
/* Кумулятив-area (month — /month.html): тонкая нейтральная линия + точки,
   полупрозрачная цветная заливка между линией и нулевой осью по знаку
   (warn вверх — накопленный перебор, success вниз — накопленный дефицит). */
.chart-cum-line {
  fill: none;
  stroke: var(--text);
  stroke-width: 1.5;
  opacity: 0.75;
}
.chart-cum-dot {
  fill: var(--text);
  opacity: 0.55;
}
.cum-area-over  { fill: var(--warn);    opacity: 0.18; }
.cum-area-under { fill: var(--success); opacity: 0.18; }
/* Кумулятив-линия (year — /year.html): один стрек по знаку финала + точки по знаку. */
.chart-line       { fill: none; stroke: var(--text); stroke-width: 1.75; }
.chart-line-over  { fill: none; stroke: var(--warn); stroke-width: 1.75; }
.chart-line-under { fill: none; stroke: var(--success); stroke-width: 1.75; }
.chart-dot-over   { fill: var(--warn);    stroke: var(--surface); stroke-width: 1.5; }
.chart-dot-under  { fill: var(--success); stroke: var(--surface); stroke-width: 1.5; }
.chart-dot-zero   { fill: var(--text-muted); stroke: var(--surface); stroke-width: 1.5; }
.chart-hit {
  fill: transparent;
  cursor: pointer;
}
.chart-hit:hover { fill: var(--accent-soft); }

.chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
  font-size: 0.85rem;
  line-height: 1.5;
  box-shadow: var(--shadow-2);
  z-index: 10;
  min-width: 160px;
  max-width: 280px;
}
.chart-tooltip.hidden { display: none; }
.chart-tooltip .tt-date {
  font-weight: 600;
  margin-bottom: 0.2rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.2rem;
}
.chart-tooltip .muted { color: var(--text-muted); font-size: 0.8rem; }
.chart-tooltip .delta { margin: 0; padding: 0; font-size: 0.85rem; }
.chart-tooltip .delta.over  { color: var(--warn); }
.chart-tooltip .delta.under { color: var(--success); }
.chart-tooltip .delta.zero  { color: var(--text-muted); }

/* Мобильный — чуть компактнее, тултип становится липким баннером сверху графика */
@media (max-width: 600px) {
  .chart-section .chart-header { margin-bottom: 0.4rem; }
  .chart-section .chart-header h2 { font-size: 1rem; }
  .chart-legend { font-size: 0.8rem; gap: 0.7rem; }
  .chart-tooltip {
    font-size: 0.8rem;
    min-width: 0;
    max-width: calc(100% - 16px);
    padding: 0.4rem 0.55rem;
  }
}

/* === Главная: дашборд =========================================== */
.dash-card .dash-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.25rem;
}
/* Вариант с навигацией по периодам (Неделя/Месяц в дашборде сна).
   h2 принудительно растягиваем до высоты кнопок навигации (2.25rem)
   и центрируем в нём текст — тогда h2 и .date-nav имеют одинаковую
   высоту и идеально совпадают по вертикали. */
.dash-card .dash-head.dash-head-nav {
  align-items: center;
  flex-wrap: wrap;
}
/* Раньше центрировали через display: inline-flex + align-items: center, но
 * текст всё равно «садился» к верхней кромке (h2 как flex-контейнер с
 * единственным текст-нодом ведёт себя капризно в WebKit/Chromium).
 * Простой line-height = высоте бокса даёт надёжное центрирование одной
 * строки. h2 остаётся обычным block — chart-title его обёртывает. */
.dash-card .dash-head.dash-head-nav h2 {
  min-height: 2.25rem;
  line-height: 2.25rem;
  margin: 0;
}
/* chart-title оборачивает h2 + i-кнопку. Растягиваем до строки навигации,
 * чтобы align-items: center у dash-head-nav сел чисто, а не «к верху». */
.dash-card .dash-head.dash-head-nav .chart-title {
  min-height: 2.25rem;
}
/* Псевдо-инпут с диапазоном дат в .date-nav — выглядит как
   <input type="month"> на /month.html: тот же border/высота/паддинг.
   Для пользователя — однородный «контрол навигации» в дашборде. */
.date-nav .date-nav-label {
  display: inline-flex;
  align-items: center;
  height: 2.25rem;
  padding: 0.3rem 0.7rem;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-size: 0.95rem;
  line-height: 1.2;
  box-sizing: border-box;
  white-space: nowrap;
}
.date-nav button:disabled { opacity: 0.4; cursor: default; }
.date-nav button:disabled:hover { background: var(--surface); }
.dash-card h2 { margin: 0; font-size: 1.1rem; }
.dash-link { font-size: 0.9rem; color: var(--text-muted); text-decoration: none; }
.dash-link:hover { color: var(--accent); text-decoration: underline; }
.dash-date { margin: 0 0 0.9rem; font-size: 0.85rem; }
.dash-note { margin: 0.6rem 0 0; font-size: 0.8rem; }

.dash-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 0.6rem;
}
.dash-tile {
  background: var(--surface-alt, var(--surface));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.6rem 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.dash-tile .t-label {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.dash-tile .t-value {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.15;
}
.dash-tile .t-unit {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 400;
  margin-left: 0.2em;
}
/* Дополнительная info рядом с value — например, абс. часы рядом с % */
.dash-tile .t-extra {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 400;
  margin-left: 0.05em;
  white-space: nowrap;
}
.dash-tile.t-delta .t-value.over  { color: var(--warn); }
.dash-tile.t-delta .t-value.under { color: var(--success); }
/* zero — дельта посчитана, но без изменений. Серый text-muted показывает,
 * что плитка «активная» (т.е. есть с чем сравнивать), но направление пустое. */
.dash-tile.t-delta .t-value.zero  { color: var(--text-muted); }
.dash-tile.t-empty .t-value { color: var(--text-faint); font-weight: 400; }

/* === Плитка БЖУ с донатом ======================================= */
:root {
  /* Палитра БЖУ: серый/приглушённый фиолет/кирпично-розовый — намеренно
   * вне палитры сна (оранж/зелёный/синий заняты под bad/norm/good).
   * Десатурированные оттенки, чтобы не звенели рядом с календарём.
   * Договорено 2026-05-23. */
  --bju-p: #78716c;  /* Белки — тёплый серый (stone-500) */
  --bju-f: #5b4b8a;  /* Жиры — сине-фиолет, пыльный */
  --bju-c: #8e3a5c;  /* Углеводы — кирпично-розовый */
  --bju-track: #e5e7eb;
}
[data-theme="dark"] {
  --bju-p: #a8a29e;  /* Белки — серый посветлее (stone-400) */
  --bju-f: #8a7ab8;  /* Жиры — пыльный сине-фиолет посветлее */
  --bju-c: #b8627e;  /* Углеводы — кирпично-розовый посветлее */
  --bju-track: #1f2a44;
}

/* Цвета типов приёма (борд «Приёмы по типам» на week.html) — отдельная,
 * 4-я палитра. Не БЖУ (роза/индиго/stone — иначе путались бы с донатом над
 * бордом) и не статус (оранж/зелёный/синий — читается как оценка нормы).
 * Тёпло-холодная ось в духе Δ-графика: день тёплый (медовый→терракота),
 * вечер/перекус холодный (пыльно-синий→лаванда). Десатурированные тона. */
:root {
  --meal-breakfast: #d39a5c;  /* медовый/амбер — утро */
  --meal-lunch:     #c77b58;  /* терракота — день */
  --meal-dinner:    #6b86b8;  /* пыльно-синий — вечер */
  --meal-snack:     #9d8bb8;  /* лаванда — перекус */
  --meal-none:      var(--border);
}
[data-theme="dark"] {
  --meal-breakfast: #e0aa6a;
  --meal-lunch:     #d68d6a;
  --meal-dinner:    #7e98c8;
  --meal-snack:     #ab9bc8;
  --meal-none:      var(--border-strong);
}
.meal-seg.m-breakfast { fill: var(--meal-breakfast); }
.meal-seg.m-lunch     { fill: var(--meal-lunch); }
.meal-seg.m-dinner    { fill: var(--meal-dinner); }
.meal-seg.m-snack     { fill: var(--meal-snack); }
.meal-seg.m-none      { fill: var(--meal-none); }
.chart-legend .sw-meal-breakfast { background: var(--meal-breakfast); }
.chart-legend .sw-meal-lunch     { background: var(--meal-lunch); }
.chart-legend .sw-meal-dinner    { background: var(--meal-dinner); }
.chart-legend .sw-meal-snack     { background: var(--meal-snack); }

/* === Состав тела (inbody) — палитра ============================
 * 6-я тематическая палитра, по образцу sleep/activity/meal-types: 6 цветов
 * для линий и стека на /inbody.html. Семантика: метрика = цвет; «больше/
 * меньше» под смысл графика подсвечивается отдельно через .delta.over/.under.
 * Договорено с Yana 2026-06-02.
 *   weight — основная метрика (синий, сильный)
 *   fat    — жир (терракота, тёплый)
 *   smm    — мышцы (зелёный, «жизнь»)
 *   other  — прочая безжировая (серый, нейтральный)
 *   vfa    — висцеральный жир (красный, риск)
 *   phase  — фазовый угол (пыльно-фиолетовый, «качество»)
 *   target — цель/норма (нейтральный серо-голубой, пунктир) */
:root {
  --inbody-weight: #2563eb;
  --inbody-fat:    #c77b58;
  --inbody-smm:    #10b981;
  --inbody-other:  #94a3b8;
  --inbody-vfa:    #e11d48;
  --inbody-phase:  #7c3aed;
  --inbody-target: #94a3b8;
}
[data-theme="dark"] {
  --inbody-weight: #60a5fa;
  --inbody-fat:    #d68d6a;
  --inbody-smm:    #34d399;
  --inbody-other:  #64748b;
  --inbody-vfa:    #f43f5e;
  --inbody-phase:  #a78bfa;
  --inbody-target: #64748b;
}

/* SVG-классы для линий и точек — повторяют паттерн .chart-line-* /
 * .chart-dot-*. Через классы, не через хардкод stroke="#...".  */
.inbody-line-weight { fill: none; stroke: var(--inbody-weight); stroke-width: 2.2; stroke-linejoin: round; }
.inbody-line-fat    { fill: none; stroke: var(--inbody-fat);    stroke-width: 2.2; stroke-linejoin: round; }
.inbody-line-smm    { fill: none; stroke: var(--inbody-smm);    stroke-width: 2.2; stroke-linejoin: round; }
.inbody-line-vfa    { fill: none; stroke: var(--inbody-vfa);    stroke-width: 2.2; stroke-linejoin: round; }
.inbody-line-phase  { fill: none; stroke: var(--inbody-phase);  stroke-width: 2.2; stroke-linejoin: round; }
.inbody-dot-weight  { fill: var(--surface); stroke: var(--inbody-weight); stroke-width: 1.6; }
.inbody-dot-fat     { fill: var(--surface); stroke: var(--inbody-fat);    stroke-width: 1.6; }
.inbody-dot-smm     { fill: var(--surface); stroke: var(--inbody-smm);    stroke-width: 1.6; }
.inbody-dot-vfa     { fill: var(--surface); stroke: var(--inbody-vfa);    stroke-width: 1.6; }
.inbody-dot-phase   { fill: var(--surface); stroke: var(--inbody-phase);  stroke-width: 1.6; }
/* Пунктиры для цели (на графиках веса/жира/СММ) и нормы (на графике VFA). */
.inbody-target-line {
  fill: none;
  stroke: var(--inbody-target);
  stroke-width: 1.2;
  stroke-dasharray: 5,4;
}
.inbody-norm-line {
  fill: none;
  stroke: var(--inbody-target);
  stroke-width: 1.4;
  stroke-dasharray: 6,4;
}
.inbody-target-label { fill: var(--text-muted); font-size: 11px; font-family: inherit; }
/* Оси с цветовой подсказкой — для двойной оси «вес+жир%»: тики
 * слева окрашены под цвет соответствующей линии, чтобы было понятно, что к
 * чему относится. */
.chart-axis.inbody-axis-weight { fill: var(--inbody-weight); }
.chart-axis.inbody-axis-fat    { fill: var(--inbody-fat); }

.chart-legend .sw-inbody-weight { background: var(--inbody-weight); }
.chart-legend .sw-inbody-fat    { background: var(--inbody-fat); }
.chart-legend .sw-inbody-smm    { background: var(--inbody-smm); }
.chart-legend .sw-inbody-other  { background: var(--inbody-other); }
.chart-legend .sw-inbody-vfa    { background: var(--inbody-vfa); }
.chart-legend .sw-inbody-phase  { background: var(--inbody-phase); }
.chart-legend .sw-inbody-target {
  background: transparent;
  border-top: 2px dashed var(--inbody-target);
  border-radius: 0;
  height: 2px;
  margin-top: 5px;
}
/* Полупрозрачная полоса нормы %жира. Заливка прозрачная, чтобы линия с
 * точками читалась поверх. Зону essential fat (<6/14%) намеренно не
 * выводим — для пользователей нерелевантна, съедает пол-графика. */
.inbody-fat-norm-band   { fill: var(--success); opacity: 0.13; }
[data-theme="dark"] .inbody-fat-norm-band { opacity: 0.22; }
.chart-legend .sw.sw-inbody-fat-norm {
  background: var(--success);
  opacity: 0.40;
}

/* === Состав тела (inbody) — компоненты страницы =================
 * Page-specific блоки: «Прогресс к цели», селектор периода, подпись под
 * графиком, таблица замеров. Базовые .dash-card/.dash-tiles/.t-* приходят
 * из общей design-system, тут только дельты к норматива. */

/* Главная цель — три смысловых сабблока, разделённых тонкими линиями:
 * 1) голова: «Главная цель: X» + «цель Y» справа
 * 2) прогресс-бар с тремя метками (старт / сейчас / цель)
 * 3) «Темп»: Нужно/Факт
 * Между сабблоками — 1px разделитель var(--border). Вторичные цели идут
 * после, нормативными .dash-tile (см. ниже). */
.goal-primary {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0.4rem 0 0.9rem;
}

/* Голова: метка слева, цель справа. */
.goal-primary .goal-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-size: 0.95rem;
}
.goal-primary .goal-title {
  font-weight: 600;
  color: var(--text);
}
.goal-primary .goal-target { color: var(--text-muted); }

/* Прогресс-бар с метками по краям и плавающим «сейчас». */
.goal-primary .goal-bar-block {
  display: grid;
  grid-template-rows: auto 12px auto;
  row-gap: 0.4rem;
  padding-bottom: 1.2rem; /* место под подпись «сейчас» */
}
.goal-primary .goal-bar-endpoints {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--text);
}
.goal-primary .goal-bar-endpoints .muted { color: var(--text-faint); }
.goal-primary .goal-bar {
  height: 10px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: visible;  /* маркер «сейчас» выходит вертикально */
  position: relative;
}
.goal-primary .goal-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--inbody-smm), var(--inbody-weight));
  transition: width 250ms ease-out;
  border-radius: 999px;
}
.goal-primary.goal-up .goal-bar-fill {
  background: linear-gradient(90deg, var(--inbody-fat), var(--inbody-smm));
}
/* Подпись «сейчас» — отдельная строка под баром, абсолютно по координате. */
.goal-primary .goal-bar-currentline {
  position: relative;
  height: 0;
}
.goal-primary .goal-bar-current {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 0.85rem;
  white-space: nowrap;
  color: var(--text);
  font-weight: 600;
}
.goal-primary .goal-bar-current .muted { color: var(--text-faint); font-weight: 400; }

/* Подпись «Пройдено 76% · до цели 4,2 п.п.» — над «Темпом». */
.goal-primary .goal-progress-line {
  font-size: 0.9rem;
  color: var(--text-muted);
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.goal-primary .goal-progress-line b { color: var(--text); }

/* Сабблок «Темп» — две строки «Нужно / Факт», выровнены по grid. */
.goal-primary .goal-pace {
  display: grid;
  row-gap: 0.3rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
}
.goal-primary .goal-pace-row {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 0.6rem;
  align-items: baseline;
}
.goal-primary .goal-pace-lbl {
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
}
.goal-primary .goal-pace-val { color: var(--text); }
.goal-primary .goal-pace-val.muted { color: var(--text-muted); }

/* Вторичные цели — те же .dash-tile, что в KPI «Последнего замера». Единая
 * сетка и стили из общей design-system. Сам контейнер использует уже
 * существующий .dash-tiles (минимум 7rem), здесь только верхний margin. */
.goal-secondary.dash-tiles {
  margin-top: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

/* Селектор периода (3/6/9/12/всё) — компактные пилюли. Структура как у
 * .bju-basis, но без скрытых radio'ов: просто кнопки. */
.period-tabs {
  display: inline-flex;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface);
}
.period-tabs button {
  appearance: none;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0.35rem 0.75rem;
  font: inherit;
  font-size: 0.9rem;
  color: var(--text-muted);
  cursor: pointer;
  margin: 0;
  box-shadow: none;
  align-self: auto;
  transition: background-color 0.15s, color 0.15s;
}
.period-tabs button + button { border-left: 1px solid var(--border); }
.period-tabs button:hover { background: var(--accent-soft); color: var(--text); }
.period-tabs button.active {
  background: var(--accent);
  color: #fff;
}

/* Период (Тренды): пилюли + два date-input в одной wrap-flex линии.
 * При выборе пилюли — input'ы обновляются автоматом; при изменении input —
 * пилюли становятся неактивны (режим «свой период»). */
.period-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 0.9rem;
}
.period-range {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.period-range input[type="date"] {
  height: 2rem;
  padding: 0.2rem 0.5rem;
  font-size: 0.85rem;
}

/* «Тренды» — карточка-контейнер для всех 5 графиков. Внутри каждый
 * график живёт в .trend-chart (не отдельной .chart-section, чтобы не
 * дублировать фон/border карточки). Между графиками — тонкий разделитель.
 * Yana 2026-06-03: было «оторвано» — селектор периода в одной карточке,
 * графики в других; теперь всё под одним заголовком «Тренды». */
.inbody-trends .trend-chart + .trend-chart {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.inbody-trends .trend-chart h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}
.inbody-trends .trend-chart .chart-header { margin-bottom: 0.5rem; }
.inbody-trends > #period-coverage {
  margin-top: 0.25rem;
  margin-bottom: 1rem;
}

/* Подпись под графиком (rule-based комментарий: «−0.7 кг за месяц»). */
.chart-note {
  margin: 0.4rem 0 0;
  font-size: 0.9rem;
  color: var(--text-muted);
  min-height: 1.2em;
}
.chart-note b { color: var(--text); }
.chart-note .delta { display: inline; font-weight: 600; }

/* Раскрывающаяся таблица всех замеров — паттерн как у /year.html (collapsed
 * через .collapsed → display:none). Ограничение высоты + скролл, чтобы
 * страница не растягивалась бесконечно на 50+ строках. */
.inbody-table-wrap {
  max-height: 420px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-top: 0.5rem;
}
.inbody-table-wrap.collapsed { display: none; }
#inbody-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
#inbody-table th,
#inbody-table td {
  padding: 0.35rem 0.6rem;
  text-align: right;
  border-bottom: 1px solid var(--border);
}
#inbody-table th {
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--text-muted);
  letter-spacing: 0.03em;
}
#inbody-table td:first-child,
#inbody-table th:first-child { text-align: left; }

.meal-type-note { margin: 0 0 0.75rem; }
.meal-type-charts { display: flex; flex-direction: column; gap: 1.25rem; }
.meal-dist-block { display: flex; flex-direction: column; gap: 0.35rem; }
.meal-dist-caption {
  font-size: 0.82rem;
  color: var(--text-muted);
}
.meal-dist-caption .muted { color: var(--text-faint); }
.meal-snack-summary {
  font-size: 0.8rem;
  color: var(--text-muted);
}
.meal-tt-snack {
  margin-top: 0.15rem;
  font-size: 0.8rem;
}
.meal-dist-svg {
  display: block;
  width: 100%;
  height: 40px;
}
.meal-dist-pct {
  fill: #fff;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
}
.meal-stack-total {
  fill: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  font-family: inherit;
}
.meal-tt-row { display: flex; align-items: center; gap: 0.35rem; }
.meal-tt-sw {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 2px;
  flex: 0 0 auto;
}
.meal-tt-sw.m-breakfast { background: var(--meal-breakfast); }
.meal-tt-sw.m-lunch     { background: var(--meal-lunch); }
.meal-tt-sw.m-dinner    { background: var(--meal-dinner); }
.meal-tt-sw.m-snack     { background: var(--meal-snack); }
.meal-tt-sw.m-none      { background: var(--meal-none); }
.meal-tt-total {
  margin-top: 0.3rem;
  padding-top: 0.3rem;
  border-top: 1px solid var(--border);
}
.dash-tile.dash-bju { grid-column: span 2; }
.dash-tile.dash-bju .bju-body {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}
.bju-empty {
  font-size: 1.35rem;
  color: var(--text-faint);
}
.bju-donut {
  width: 3.2rem;
  height: 3.2rem;
  flex: 0 0 auto;
  transform: rotate(-90deg);
}
.bju-track { stroke: var(--bju-track); }
.bju-seg { transition: stroke-dasharray 0.25s; }
.bju-seg.s-p { stroke: var(--bju-p); }
.bju-seg.s-f { stroke: var(--bju-f); }
.bju-seg.s-c { stroke: var(--bju-c); }
.bju-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.78rem;
  line-height: 1.35;
  min-width: 0;
}
.bju-legend li {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}
.bju-legend b { font-weight: 600; }
.bju-legend .bju-g { color: var(--text-muted); }
.bju-legend .bju-val { font-weight: 500; }
/* 3-цветная палитра статуса как в дашборде сна (--sleep-bad/--sleep-norm/--sleep-good). */
.bju-legend .bju-val.s-norm { color: var(--sleep-norm); font-weight: 600; }
.bju-legend .bju-val.s-bad  { color: var(--sleep-bad);  font-weight: 600; }
.bju-legend .bju-val.s-good { color: var(--sleep-good); font-weight: 600; }
.bju-legend .bju-arrow { font-weight: 700; }
.bju-legend .bju-norm { color: var(--text-faint); font-size: 0.72rem; }
/* Пометка «>50% ккал» у углеводов — единственный сигнал внимания по У. */
.bju-legend .bju-norm.s-bad { color: var(--sleep-bad); font-weight: 600; }
.bju-sw {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 2px;
  flex: 0 0 auto;
}
.bju-sw.s-p { background: var(--bju-p); }
.bju-sw.s-f { background: var(--bju-f); }
.bju-sw.s-c { background: var(--bju-c); }
/* На узких экранах донат уезжает в свою строку без перекрытий с соседями */
@media (max-width: 480px) {
  .dash-tile.dash-bju { grid-column: 1 / -1; }
}

/* Standalone-блок БЖУ на day/week/month — отдельная секция, без grid-обёртки.
   Унаследованный grid-column: span 2 здесь noop, плитка занимает свою ширину сама. */
.bju-section { margin-top: 1.5rem; }
.bju-section h2 { font-size: 1.1rem; margin: 0 0 0.6rem; }
.bju-section .bju-section-sub {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 0.85rem;
  margin-left: 0.25rem;
}
.bju-standalone .dash-tile.dash-bju { grid-column: auto; }
@media (max-width: 600px) {
  .bju-section h2 { font-size: 1rem; }
}

/* Day → блок «Баланс» в две колонки: слева — burn/БМ/Δ, справа — донат БЖУ. */
.balance-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.2rem;
  align-items: start;
}
.balance-grid .balance-main { min-width: 0; }
.balance-grid > #day-bju-card { min-width: 0; }
@media (max-width: 700px) {
  .balance-grid { grid-template-columns: 1fr; gap: 0.8rem; }
}

/* === Дашборд сна ================================================ */
/* Палитра «приглушённых» цветов для дашборда сна. Используется одинаково
 * во всех секциях (плитки, календарь, бары, легенды) — глаз не «прыгает»
 * между секциями. Договорено 2026-05-22: оранж=плохо, зелёный=норма,
 * синий=хорошо. RGB-якоря для гадиента календаря дублируются в JS. */
/* Светлая тема — сочные Tailwind 400/600/500: на белом фоне читаются
 * хорошо. Тёмная тема — приглушённые версии, чтобы не ослеплять. */
:root {
  --sleep-bad:    #fb923c;  /* orange-400 */
  --sleep-norm:   #16a34a;  /* green-600 */
  --sleep-good:   #3b82f6;  /* blue-500 */
  --sleep-none:   var(--border);
}
[data-theme="dark"] {
  --sleep-bad:    #b07053;  /* землистая терракота */
  --sleep-norm:   #2f7a55;  /* тёмная сосна */
  --sleep-good:   #5572c4;  /* приглушённая индиго */
  --sleep-none:   var(--border-strong);
}

/* Агрегатные карточки 7д / 30д */
.sleep-aggregates { margin-top: 1rem; }
.sleep-agg-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}
.sleep-agg-block {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.sleep-agg-title {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
@media (max-width: 640px) {
  .sleep-agg-pair { grid-template-columns: 1fr; }
}

/* Хитмап */
.sleep-heatmap-section { margin-top: 1.5rem; }
.heatmap-metric-label {
  font-size: 0.9rem;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.heatmap-metric-label select {
  font-size: 0.9rem;
  padding: 0.15rem 0.3rem;
}
.sleep-heatmap {
  position: relative;
  overflow-x: auto;
}
/* Лейаут хитмапа: грид 2×2 = месяцы / пусто-левый-угол + ячейки / дни-недели */
.heatmap-wrap {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  gap: 4px 6px;
  min-width: max-content;
  padding: 0.25rem 0;
}
.heatmap-corner { grid-column: 1; grid-row: 1; }
.heatmap-months-row {
  grid-column: 2; grid-row: 1;
  display: grid;
  align-items: end;
  font-size: 0.75rem;
  color: var(--text-muted);
  height: 1.1rem;
}
.heatmap-month-label {
  white-space: nowrap;
}
.heatmap-days-col {
  grid-column: 1; grid-row: 2;
  display: grid;
  grid-template-rows: repeat(7, 14px);
  gap: 2px;
  font-size: 0.7rem;
  color: var(--text-muted);
}
.heatmap-day-label {
  line-height: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  padding-right: 4px;
}
.sleep-heatmap-grid {
  grid-column: 2; grid-row: 2;
  display: grid;
  grid-template-rows: repeat(7, 14px);
  gap: 2px;
}
.sleep-cell {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  background: var(--sleep-none);
  cursor: default;
}
.sleep-cell.inline {
  display: inline-block;
  vertical-align: -3px;
  margin-right: 0.25rem;
}
/* Свотчи легенды (фиксированные цвета концов градиента) */
.sleep-cell-bad   { background: var(--sleep-bad); }
.sleep-cell-norm  { background: var(--sleep-norm); }
.sleep-cell-good  { background: var(--sleep-good); }
.sleep-cell-none  { background: var(--sleep-none); }
.sleep-cell-future { background: transparent; border: 1px dashed var(--border); }
/* Полосатая «штриховка» для дней «спала только утром» (night=null, day>0).
 * Накладывается поверх обычного градиентного фона. */
.sleep-cell-day-only {
  position: relative;
  overflow: hidden;
}
.sleep-cell-day-only::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0 2px,
    rgba(0, 0, 0, 0.35) 2px 3px
  );
  pointer-events: none;
  border-radius: inherit;
}
.sleep-heatmap-legend {
  margin-top: 0.6rem;
  display: flex;
  gap: 0.9rem;
  align-items: center;
  font-size: 0.8rem;
  color: var(--text-muted);
  flex-wrap: wrap;
}
.sleep-heatmap-legend > span { display: inline-flex; align-items: center; }
/* «Градиентная» полоска в легенде хитмапа — мини-бар с переходом
 * оранж → зелёный → синий, показывает, как читать цвета ячеек. */
.sleep-heatmap-legend .hm-gradient-bar {
  display: inline-block;
  width: 80px;
  height: 12px;
  border-radius: 2px;
  vertical-align: -2px;
  background: linear-gradient(to right, var(--sleep-bad), var(--sleep-norm), var(--sleep-good));
}

/* Бары длительности — приглушённые тона, совпадающие с якорями градиента
 * календаря (--sleep-bad / --sleep-norm / --sleep-good). Так глаз не
 * скачет между секциями: один и тот же оттенок «плохо», «норма», «выше». */
.sleep-bar.bar-bad  { fill: var(--sleep-bad); }   /* приглушённый оранж */
.sleep-bar.bar-norm { fill: var(--sleep-norm); }  /* зелёный календаря */
.sleep-bar.bar-good { fill: var(--sleep-good); }  /* синий календаря */
.sleep-bar.bar-none { fill: var(--text-faint); }
.sw-bar-bad  { color: var(--sleep-bad); }
.sw-bar-norm { color: var(--sleep-norm); }
.sw-bar-good { color: var(--sleep-good); }

/* Спец-свотчи с собственной формой/прозрачностью — нужны более
 * специфичные селекторы, чтобы перебить `.chart-legend .sw`. */
.chart-legend .sw.sw-hrv-line {
  background: var(--sleep-good);
  height: 3px;
  align-self: center;
}
.chart-legend .sw.sw-hrv-band {
  background: var(--sleep-good);
  opacity: 0.30;
}
.chart-legend .sw.sw-schedule {
  background: var(--sleep-good);
  opacity: 0.85;
}

/* Стек «Фазы сна» — два мини-графика друг под другом. */
.phases-bars-section .phase-mini { margin-top: 0.9rem; }
.phases-bars-section .phase-mini-title {
  margin: 0 0 0.15rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Фазы — два линейных графика (Глубокий% + Быстрый%) с полосой нормы.
 * Оба графика рисуются одним стандартным синим (--sleep-good).
 * Полоса нормы — бледно-синяя версия того же цвета. */
.phase-line {
  fill: none;
  stroke: var(--sleep-good);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.phase-dot { fill: var(--sleep-good); }
.phase-norm-band {
  fill: var(--sleep-good);
  opacity: 0.15;
}
[data-theme="dark"] .phase-norm-band { opacity: 0.22; }

/* Свотчи легенды фаз — через color: (см. .chart-legend .sw) */
.sw-phase-line { color: var(--sleep-good); }
.chart-legend .sw.sw-phase-norm-band {
  background: var(--sleep-good);
  opacity: 0.30;
}

/* HRV линия — стиль и палитра как в «Фазы сна» (стандартный синий
 * --sleep-good + бледно-синяя полоса нормы). */
.chart-hrv-line {
  fill: none;
  stroke: var(--sleep-good);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.chart-hrv-dot { fill: var(--sleep-good); }
.chart-norm-band {
  fill: var(--sleep-good);
  opacity: 0.15;
}
[data-theme="dark"] .chart-norm-band { opacity: 0.22; }
.chart-norm-label {
  fill: var(--text-muted);
  font-size: 11px;
  font-family: inherit;
}

/* Schedule (засыпание → пробуждение) — горизонтальные полосы по дням.
 * Цвет — стандартный синий (как остальные графики). */
.schedule-bar {
  fill: var(--sleep-good);
  opacity: 0.85;
}
/* Опорная горизонтальная линия в 02:00 — пунктир */
.schedule-ref-line {
  stroke: var(--text-muted);
  stroke-width: 1;
  stroke-dasharray: 4 3;
}

/* Tile footnote — подсказка нормы под значением.
 * Запрещаем wrap внутри строк — переносы только по явному <br>. */
.dash-tile .t-foot {
  font-size: 0.7rem;
  color: var(--text-faint);
  margin-top: 0.1rem;
  line-height: 1.3;
  white-space: nowrap;
}
/* В агрегатах сна t-foot содержит даты плохих ночей — может не влезть
 * в одну строку. Разрешаем перенос только здесь. */
.sleep-aggregates .dash-tile .t-foot {
  white-space: normal;
}
/* Суффикс «· средние» в заголовке секций Неделя/Месяц — приглушённо,
 * меньше основного h2. Сохраняет иерархию, не перетягивает внимание. */
.dash-card .dash-head h2 .h2-suffix {
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-muted);
  margin-left: 0.15rem;
}
/* Покрытие данными под шапкой («Данные за X из Y ночей») — мелкий
 * приглушённый текст, чтобы был знаменатель для среднего. */
.dash-coverage {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.dash-coverage:empty { display: none; }
/* Шире плитки на странице сна, чтобы «Глубокий сон» и «норма 13-23%»
 * помещались в одну строку каждая. */
.sleep-last-night .dash-tiles,
.sleep-aggregates .dash-tiles {
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
}
/* Статусная подсветка значения — приглушённая sleep-палитра (договорено
 * 2026-05-22). Используется только в дашборде сна; на остальных страницах
 * t-status-* не применяется. */
.dash-tile .t-value.t-status-good { color: var(--sleep-good); }
.dash-tile .t-value.t-status-norm { color: var(--sleep-norm); }
.dash-tile .t-value.t-status-bad  { color: var(--sleep-bad); }
.dash-tile .t-value.t-status-none { color: var(--text-faint); }

/* Дата последней ночи в шапке секции */
.sleep-last-night .dash-date {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* ============================================================
   Variant 1 — IA experiment (widget hub + section sub-nav)
   ============================================================ */

/* Section sub-nav: показывается внутри раздела «Еда» под page-tabs */
nav.section-tabs {
  display: flex;
  gap: 0;
  margin: 0 0 1rem;
  padding: 0;
  border-bottom: 1px dashed var(--border);
  flex-wrap: wrap;
}
nav.section-tabs a {
  padding: 0.4rem 0.85rem;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-size: 0.9rem;
  white-space: nowrap;
}
nav.section-tabs a:first-child { padding-left: 0; }
nav.section-tabs a:hover { color: var(--text); }
nav.section-tabs a.current {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
nav.section-tabs .section-tabs-break { display: none; }

/* Mobile: в разделе «Еда» — Каталог/Источники во второй строке */
@media (max-width: 480px) {
  nav.section-tabs.section-tabs-food .section-tabs-break {
    display: block;
    flex-basis: 100%;
    height: 0;
    margin: 0;
    padding: 0;
  }
  nav.section-tabs.section-tabs-food a[data-page="foods"] {
    padding-left: 0;
  }
}

/* Widget grid на главной */
.widget-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: 1rem;
}
.widget {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
  box-shadow: var(--shadow-1), var(--shadow-2);
  text-decoration: none;
  color: inherit;
  transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s;
}
a.widget:hover {
  transform: translateY(-1px);
  border-color: var(--accent);
  box-shadow: 0 4px 14px var(--accent-soft);
}
.widget-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}
.widget-head h2 { margin: 0; font-size: 1.05rem; }
.widget-arrow {
  font-size: 1.1rem;
  color: var(--text-muted);
  transition: transform 0.12s, color 0.12s;
}
a.widget:hover .widget-arrow {
  color: var(--accent);
  transform: translateX(3px);
}
.widget-date {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
}
.widget-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
  gap: 0.5rem;
  margin-top: 0.5rem;
}
/* Виджет сна: 5 плиток в 2 строки (3 + 2). Пятая плитка (Пробуждения)
 * растягивается на 2 колонки, чтобы не зияла пустота справа и был запас
 * под длинный лейбл. */
.widget-sleep .widget-tiles {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.widget-sleep .widget-tiles .dash-tile:nth-child(5) {
  grid-column: span 2;
}
.widget-tiles .dash-tile {
  background: var(--surface-sunken);
  padding: 0.5rem 0.6rem;
}

/* Виджет состава тела: 3 плитки (Вес, %жира, СММ) + строка прогресса
 * главной цели снизу через 1px разделитель. */
.widget-inbody .widget-tiles {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.widget-inbody-goal {
  margin: 0.7rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
  color: var(--text-muted);
}
.widget-inbody-goal:empty { display: none; }
.widget-inbody-goal b { color: var(--text); }

/* Mobile: Ккал + Расход + Δ ккал — в одну строку, БЖУ — отдельной строкой ниже */
@media (max-width: 480px) {
  #widget-food-tiles,
  #widget-food-week-tiles {
    grid-template-columns: repeat(3, 1fr);
    gap: 0.4rem;
  }
  #widget-food-tiles .dash-tile,
  #widget-food-week-tiles .dash-tile {
    padding: 0.4rem 0.5rem;
  }
  #widget-food-tiles .dash-tile .t-value,
  #widget-food-week-tiles .dash-tile .t-value {
    font-size: 1.1rem;
  }
  #widget-food-tiles .dash-tile.dash-bju,
  #widget-food-week-tiles .dash-tile.dash-bju {
    order: 1;
  }
  /* span:2 для 5-й плитки теперь объявлен снаружи media — действует
     в обеих ширинах. Здесь оставлен только ellipsis-фолбэк. */
  .widget-tiles .dash-tile .t-label {
    letter-spacing: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ============================================================
 * Цвета колец Huawei для страницы /activity.html (Движения / Тренировки /
 * Вставания). Виджет на главной теперь — плитки, но кольца ещё рисуются
 * на детальной странице, поэтому переменные остаются глобальными.
 *
 *   красно-оранжевый = active_kcal,
 *   жёлтый           = exercise_min,
 *   синий            = stand_hours.
 * ============================================================ */
:root {
  --activity-ring-move:     #ff5a4d;
  --activity-ring-exercise: #ffc14b;
  --activity-ring-stand:    #4cb6ff;
  --activity-ring-track:    var(--border);
}
[data-theme="dark"] {
  --activity-ring-move:     #ff7a6e;
  --activity-ring-exercise: #ffd166;
  --activity-ring-stand:    #6cc7ff;
}

/* ============================================================
 * Страница /activity.html — секция «выбранный день».
 *
 * Зеркало экрана Huawei «Записи активностей»: крупный SVG с тремя
 * концентрическими кольцами (240px) слева, легенда с цифрами и %
 * справа, плашка Шаги · Расстояние · Подъём внизу. Бейдж «✓ идеальный
 * день» в шапке, если все три кольца закрыты.
 *
 * Кольцевые CSS-переменные уже объявлены выше для виджета — переиспользуем.
 * ============================================================ */

.activity-day-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2rem;
  align-items: center;
  margin: 1rem 0 1.25rem;
}
.activity-day-rings {
  width: 240px;
  height: 240px;
  flex: 0 0 240px;
}
.activity-day-rings svg { display: block; width: 100%; height: 100%; }

.activity-day-legend {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  font-size: 1rem;
  min-width: 0;
}
.activity-day-legend .activity-legend-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.75rem;
}
.activity-day-legend .activity-legend-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}
.activity-day-legend .activity-legend-text {
  min-width: 0;
}
.activity-day-legend .activity-legend-label {
  color: var(--text-muted);
  font-size: 0.85rem;
  margin-bottom: 0.1rem;
}
.activity-day-legend .activity-legend-value {
  font-weight: 600;
  font-size: 1.3rem;
  line-height: 1.1;
}
.activity-day-legend .activity-legend-value .goal {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 0.65em;
  margin-left: 0.15em;
}
.activity-day-legend .legend-pct {
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--surface-sunken);
}
.activity-day-legend .legend-pct.pct-good { color: var(--success); }
.activity-day-legend .legend-pct.pct-norm { color: var(--text); }
.activity-day-legend .legend-pct.pct-low  { color: var(--text-muted); }

/* Низ страницы — три равные плашки шагов/км/подъёма. */
.activity-day-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin-top: 0.5rem;
  padding-top: 1rem;
  border-top: 1px dashed var(--border);
}
.activity-day-stats .activity-stat {
  text-align: center;
  background: var(--surface-sunken);
  padding: 0.85rem 0.75rem;
  border-radius: 10px;
}
.activity-day-stats .activity-stat .s-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.3rem;
}
.activity-day-stats .activity-stat .s-value {
  font-weight: 600;
  font-size: 1.35rem;
  white-space: nowrap;
}
.activity-day-stats .activity-stat .s-value.empty {
  color: var(--text-faint);
  font-weight: 400;
}
.activity-day-stats .activity-stat .s-unit {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 0.7em;
  margin-left: 0.2em;
}

/* Бейдж «✓ идеальный день» в шапке секции — справа от даты, мягко-зелёный. */
.badge-perfect {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--success);
  background: var(--success-soft);
  border: 1px solid color-mix(in srgb, var(--success) 35%, transparent);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
  margin-left: auto;
}
.badge-perfect.hidden { display: none; }

/* Узкие экраны: кольца над легендой, не сбоку. На очень узких — плашки stats
 * в одну колонку, иначе значения вроде «13 608» переносятся. */
@media (max-width: 640px) {
  .activity-day-grid {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 1.25rem;
  }
  .activity-day-rings {
    width: 200px;
    height: 200px;
    flex: 0 0 200px;
  }
  .activity-day-legend {
    width: 100%;
  }
}
@media (max-width: 360px) {
  .activity-day-stats {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
 * Страница /activity.html — аналитика активности.
 *
 * Структура: переключалка периода → сводка-тайлы → heatmap →
 * bar-чарт по метрике → достижения. Использует общие классы
 * .dash-card / .chart-section / .dash-tile / .chart-svg / .chart-legend,
 * специфические — ниже.
 * ============================================================ */

/* Sub-метка после h2 в секциях Неделя/Месяц («· средние») — приглушённая,
 * сразу даёт понять, что плитки в этой секции — средние, не суммы или
 * последние значения. */
.dash-head h2 .dash-sub {
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-muted);
  margin-left: 0.2rem;
}

/* Строка «Данные за N из M дней» — между шапкой и плитками. Поясняет
 * охват средних: если из 7 дней 3 пустых, явно видно «3 из 7». */
.dash-coverage {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.dash-coverage:empty { display: none; }

/* Секция «Год» в дашбордах сна/активности: таблица по месяцам + бар-чарт.
 * Заголовок графика отделяем от таблицы отступом сверху. */
.sleep-year-chart-head,
.activity-year-chart-head {
  margin-top: 1.1rem;
  margin-bottom: 0.4rem;
}
.sleep-year-chart-head .phase-mini-title,
.activity-year-chart-head .phase-mini-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
}
#sleep-year-table,
#activity-year-table { margin-top: 0.2rem; }
/* «Сон» — формат «7ч 33м», шире дефолтных 4.5rem, чтобы не переносился. */
#sleep-year-table td:nth-child(3),
#sleep-year-table th:nth-child(3) { width: 5.5rem; white-space: nowrap; }

/* Сворачивание таблицы «Год» — как у #month-table на /month.html: прячем
   только tbody (месяцы), шапка и строка «За год» остаются. Кнопка-таблетка
   .toggle-btn в .table-toggle-row — те же стили, что у еды. */
#sleep-year-table.collapsed tbody,
#activity-year-table.collapsed tbody { display: none; }
#sleep-year-table.collapsed thead tr,
#activity-year-table.collapsed thead tr { border-bottom: 2px solid var(--border); }

/* Inline date-nav внутри шапки секции (Неделя / Месяц): дата между ← →,
 * чтобы группа смотрелась цельно как у food (там между стрелок инпут). */
.dash-head .date-nav.inline-nav {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
}
.dash-head .date-nav.inline-nav button {
  padding: 0.25rem 0.6rem;
  font-size: 0.85rem;
  margin: 0;
  align-self: auto;
}
.dash-head .date-nav.inline-nav .inline-date {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  min-width: 7rem;
  text-align: center;
}

/* В тайлах сводки/достижений активности label не обрезаем — лучше пусть
 * перенесётся на 2 строки, чем «ВСЕГО ТРЕНИРОВО» c обрезанным «К». */
.dash-card .dash-tile .t-label {
  white-space: normal;
  line-height: 1.15;
}

/* Большие числа в тайлах + подпись «/N» рядом */
.dash-tile .t-num {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
}
.dash-tile .t-sub {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 400;
  margin-left: 0.3rem;
}
.dash-tile .t-foot {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-top: 0.15rem;
}

/* === Heatmap календарь === */
/* Heatmap через CSS Grid (div-cells) — повторяет паттерн sleep:
 *   2×2 grid: corner + months-row + days-col + cells-grid.
 * Ячейки grid-template-columns: repeat(N, 1fr) растягиваются по ширине
 * контейнера, между неделями (колонками) получается естественный зазор. */
.activity-heatmap {
  width: 100%;
  padding: 0.5rem 0;
  overflow-x: auto;
}
/* Размеры/гэпы синхронизированы с sleep-heatmap (14px ячейка, 2px gap,
 * 2px border-radius) — Yana хочет визуальное единство «как в сне».
 * Не трогаем общий .heatmap-days-col / .heatmap-day-label — они уже
 * подходят (sleep тоже 14px). Активити переопределяет только .heat-day-label
 * (свой класс) и .heatmap-cells (свой класс). */
.heat-day-label {
  line-height: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  padding-right: 4px;
}
.heatmap-cells {
  grid-column: 2; grid-row: 2;
  display: grid;
  grid-template-rows: repeat(7, 14px);
  gap: 2px;
}
/* Ячейка фиксированных 14×14 px. Колонки cells-grid идут `1fr` — растягиваются
 * по ширине контейнера, но ячейка остаётся 14px и сидит у левого края своей
 * колонки. Пустое место справа от ячейки = естественный разделитель между
 * неделями, масштабируется с шириной экрана. Тот же приём что в .sleep-cell. */
.heat-cell {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  background: var(--sleep-none);
  cursor: default;
  transition: opacity 0.12s;
}

/* На мобилке min-width: max-content у общего .heatmap-wrap раздувает
 * контейнер шире viewport (label «май» в последней колонке расширяет
 * grid за пределы видимой части → правый край обрезается, нужен скролл).
 * Снимаем min-width — пусть wrap живёт в ширине родителя, 1fr колонки
 * сожмутся, между ячейками гэп станет меньше — но всё видно без скролла. */
@media (max-width: 480px) {
  .activity-heatmap .heatmap-wrap {
    min-width: 0;
    width: 100%;
  }
}
.heat-cell:hover { opacity: 0.7; }
.heat-cell.heat-none   { background: var(--sleep-none); }
.heat-cell.heat-nogoal { background: var(--text-faint); opacity: 0.35; }
.heat-cell.heat-future { background: transparent; border: 1px dashed var(--border); }
.heat-month-label { white-space: nowrap; }

/* === Bar-чарт по дням === */
.chart-metric-label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.chart-metric-label select {
  font-size: 0.9rem;
  padding: 0.25rem 0.5rem;
}

.bar {
  transition: opacity 0.12s;
  cursor: default;
}
.bar:hover { opacity: 0.7; }
/* Цвета баров — sleep-палитра, как в heatmap'е и плитках сна (good/norm/bad). */
.bar.bar-default,
.bar.bar-nogoal  { fill: var(--sleep-norm); opacity: 0.75; }
.bar.bar-good    { fill: var(--sleep-good); }
.bar.bar-norm    { fill: var(--sleep-norm); }
.bar.bar-low     { fill: var(--sleep-bad); }

.grid-line {
  stroke: var(--border);
  stroke-width: 1;
  opacity: 0.5;
}
.grid-label {
  font-size: 10px;
  fill: var(--text-muted);
}
/* Линия среднего значения по периоду — солидная, не dashed (это не цель,
 * а фактический average по дням с данными). Лейбл слева у оси Y. */
.avg-line {
  stroke: var(--text-muted);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  opacity: 0.6;
}
.avg-label {
  font-size: 10px;
  fill: var(--text-muted);
  font-style: italic;
}
.x-label {
  font-size: 10px;
  fill: var(--text-muted);
}
.chart-empty-text {
  font-size: 14px;
  fill: var(--text-muted);
}

/* Disabled-виджеты «скоро» */
.widget-soon {
  opacity: 0.55;
  cursor: default;
  background: transparent;
  border-style: dashed;
  box-shadow: none;
}
.widget-soon:hover { transform: none; border-color: var(--border); box-shadow: none; }
.widget-soon-badge {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
}

/* Variant 1 — расширенный виджет Еды на всю ширину (Сегодня + 7 дней) */
.widget-wide { grid-column: 1 / -1; }
.widget-block + .widget-block {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px dashed var(--border);
}
.widget-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.4rem;
}
.widget-block-head h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
}
.widget-block-head .widget-date {
  margin: 0;
  font-size: 0.85rem;
}
.widget-block .dash-note {
  font-size: 0.8rem;
  margin-top: 0.4rem;
}

/* Disabled-сущности в верхнем nav (Активность/Тренировки/Состав тела — скоро) */
.page-tabs-disabled {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  color: var(--text-faint);
  font-size: 0.95rem;
  cursor: not-allowed;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  user-select: none;
}
.page-tabs-soon {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0 0.45rem;
}

/* div-как-ссылка: курсор pointer для всей карточки */
.widget[data-href] { cursor: pointer; }
.widget[data-href]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Внутренний заголовок «Еда» — отдельная настоящая ссылка */
.widget-title-link {
  color: inherit;
  text-decoration: none;
}
.widget[data-href]:hover .widget-title-link { color: var(--accent); }
/* «Подробнее →» внутри блока «Последние 7 дней» — отдельная ссылка справа в шапке */
.widget-block-link {
  margin-left: auto;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.85rem;
  border-bottom: 1px dotted transparent;
  transition: color 0.12s, border-color 0.12s;
}
.widget-block-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Inline-якоря «↓ к поиску дублей» / «↑ к началу» в каталоге продуктов/источников.
   Каталог разрастается — нужен быстрый прыжок к секции дублей и обратно.
   Кладём ссылки внутрь контентной области: «вниз» — в подвале формы добавления,
   справа от submit, «вверх» — в заголовке секции «Поиск дублей». */
.form-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.section-head h2 { margin: 0; }
.jump-link {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--border-strong);
  white-space: nowrap;
  transition: color 0.12s, border-color 0.12s;
}
.jump-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
html:focus-within { scroll-behavior: smooth; }

/* === Трекер «сухих дней» (alcohol-tracker.js, week/month/year) =============
 * Отвечает на «был ли спирт». Клетки красятся общей heatmap-палитрой сна/
 * активности (--sleep-norm/--sleep-bad/--sleep-none): пусто (нет данных) /
 * зелёный (сухой день) / оранж по граммам (--i = интенсивность дозы). Размеры
 * клеток года синхронны с .activity-heatmap (14px / 2px). См. design-system §1.10. */
.alc-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.4rem;
  font-size: 0.9rem;
  margin-bottom: 0.75rem;
}
.alc-stats b { font-weight: 600; }
.alc-dot { color: var(--text-faint); }

.alc-heat { position: relative; }

/* Неделя — компактный ряд клеток с днём недели и числом. */
.alc-grid-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.3rem;
}
.alc-grid-week .alc-cell {
  min-height: 2.6rem;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.05rem;
}
.alc-grid-week .alc-wd {
  font-size: 0.65rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.alc-grid-week .alc-num { font-size: 0.85rem; font-weight: 600; }

/* Месяц — компактный календарь, фиксированные клетки ~1.7rem, выровнен влево. */
.alc-grid-month {
  display: grid;
  grid-template-columns: repeat(7, 1.7rem);
  gap: 3px;
}
.alc-grid-month .alc-cell { aspect-ratio: 1 / 1; border-radius: 4px; }
.alc-wdhead { margin-bottom: 3px; }
.alc-wdcell {
  width: 1.7rem;
  text-align: center;
  font-size: 0.65rem;
  color: var(--text-muted);
  text-transform: uppercase;
}

/* Год — GitHub-style: недели как колонки (auto-flow), 7 строк сверху вниз. */
.alc-grid-year {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 2px;
  overflow-x: auto;
}
.alc-grid-year .alc-cell { width: 14px; height: 14px; border-radius: 2px; }
.alc-mlabels {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 2px;
  margin-bottom: 4px;
}
.alc-mlabel {
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
  /* Подпись шире 14px-колонки — пусть переползает вправо на пустые колонки,
   * не сжимаясь и не обрезаясь (последний «дек» иначе клипается). */
  width: max-content;
}

/* Палитра клеток — общая heatmap-шкала (как .heat-cell в сне/активности). */
.alc-cell {
  background: var(--surface-alt);
  border: 1px solid transparent;
  cursor: default;
  transition: opacity 0.12s, transform 0.12s;
  outline: none;
}
.alc-cell:hover, .alc-cell:focus-visible { transform: scale(1.08); }
.alc-cell:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft); }
/* Нет данных / будущее — пунктирный пустой контур. */
.alc-none {
  background: transparent;
  border: 1px dashed var(--border);
}
/* Сухой день — мягкий зелёный (--sleep-norm, «норма»). */
.alc-dry {
  background: color-mix(in srgb, var(--sleep-norm) 28%, var(--surface));
}
/* Со спиртом — оранж (--sleep-bad), насыщенность по --i (доза). */
.alc-drink {
  --i: 1;
  background: color-mix(in srgb, var(--sleep-bad) calc(var(--i) * 100%), var(--surface));
}

.alc-empty { padding: 0.5rem 0; }
/* Fixed относительно вьюпорта — позиционируется по clientX/Y из JS, не зависит
 * от offset-родителя (секция трекера может стоять низко на странице). */
.alc-tooltip { position: fixed; z-index: 100; }
.alc-tooltip .tt-date { font-weight: 600; margin-bottom: 0.15rem; }
.alc-tip-list {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  font-size: 0.85rem;
}
/* Длинные названия переносим внутри max-width тултипа; количество
 * («~200 г · 11%») не разрываем — переносится целиком на новую строку. */
.alc-tip-list li { white-space: normal; }
.alc-tip-list li .muted { white-space: nowrap; }

/* Легенда трекера — фоны из той же heatmap-палитры. */
.chart-legend .alc-sw-dry { background: color-mix(in srgb, var(--sleep-norm) 28%, var(--surface)); }
.chart-legend .alc-sw-drink { background: var(--sleep-bad); }
.chart-legend .alc-sw-none {
  background: transparent;
  border: 1px dashed var(--border);
}

@media (max-width: 480px) {
  .alc-grid-year, .alc-mlabels { overflow-x: auto; }
}

/* === Админ-страница (admin.html) === */

/* Элементы только для админов: прячем у всех, кроме body[data-role="admin"].
   Бэкенд всё равно отдаёт 403 — это лишь чтобы не показывать бесполезные кнопки. */
body:not([data-role="admin"]) .admin-only { display: none !important; }

.admin-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem 1rem;
  align-items: end;
  margin-bottom: 1rem;
  max-width: none;  /* перебить глобальный form { max-width: 360px } */
}
/* Перебиваем глобальные form label (space-between/center) и form input (55%):
   подпись над полем, поле во всю ширину ячейки, прижато влево. */
.admin-form label {
  display: flex; flex-direction: column; align-items: stretch;
  justify-content: flex-start; gap: 0.25rem; font-size: 0.9rem;
}
.admin-form input, .admin-form select { width: 100%; min-width: 0; }
.admin-form .form-row-full { grid-column: 1 / -1; display: flex; align-items: center; gap: 0.75rem; }

/* Фиксированная раскладка во всю ширину (как day/foods — не «едет» относительно
   шапки). Я задаю ширины колонок жёстко, а лишнюю ширину отдаю «резиновой» Email
   (width:auto) — слэк уходит в текстовую колонку слева, провала перед «Действиями» нет. */
.admin-table { width: 100%; table-layout: fixed; border-collapse: collapse; margin-top: 0.5rem; }
.admin-table th, .admin-table td {
  text-align: left; padding: 0.5rem 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.admin-table th { font-size: 0.82rem; color: var(--text-muted); font-weight: 600; }
.admin-table th:nth-child(1), .admin-table td:nth-child(1) { width: 10rem; }   /* Имя */
/* Email — забирает слэк (width:auto), но в одну строку с ellipsis (полный в title),
   иначе на узком экране длинный email переносится и строки скачут. */
.admin-table th:nth-child(2), .admin-table td:nth-child(2) {
  width: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.admin-table th:nth-child(3), .admin-table td:nth-child(3) { width: 6rem; }    /* Роль */
.admin-table th:nth-child(4), .admin-table td:nth-child(4) {  /* Группы — фикс, длинное с ellipsis */
  width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.admin-table th:nth-child(5), .admin-table td:nth-child(5) { width: 6.5rem; text-align: right; padding-right: 0; }  /* Действия */
.admin-table tbody tr { transition: background-color 0.12s; }
.admin-table tbody tr:hover { background: var(--surface-alt); }
.admin-table td.actions { white-space: nowrap; }
.admin-table td.actions button { margin: 0 0 0 0.15rem; vertical-align: middle; }

.admin-badge {
  display: inline-block; font-size: 0.75rem; line-height: 1.4;
  padding: 0.05rem 0.45rem; border-radius: 6px; margin-right: 0.3rem;
  background: var(--surface-alt); color: var(--text-muted);
  border: 1px solid var(--border);
}
/* Все бейджи ролей/типов — единый нейтральный вид (без разноцветья).
   Особый цвет только у статуса «ждёт онбординга». */
.admin-badge.is-warn { background: var(--danger-soft); color: var(--danger); border-color: var(--danger); }
/* Чип группы — по содержимому, в одну строку (колонка авто-ширины под него). */
.group-chip { display: inline-block; white-space: nowrap; vertical-align: middle; margin-right: 0.25rem; }

/* === Чип (тег/пилюля) — переиспользуемый компонент. См. design-system.md §  ===
   Базовый вариант .alias-chip: нейтральная пилюля. С модификатором --editable
   получает кнопку удаления ×. Используется для алиасов продуктов (каталог, C2). */
.alias-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.3rem;
}
.alias-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  line-height: 1.4;
  padding: 0.08rem 0.5rem;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.alias-chips--modal { margin-top: 0.5rem; }
.alias-chips--modal .alias-chip { font-size: 0.85rem; padding: 0.2rem 0.6rem; }
.alias-chip__remove {
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
}
.alias-chip__remove:hover { color: var(--danger); }
/* Маркер «есть алиасы» на кнопке управления в строке каталога. */
button.edit.has-aliases { color: var(--accent); }

.admin-group-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem 0.9rem;
  margin-bottom: 0.75rem;
  background: var(--surface);
}
.admin-group-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.admin-group-head strong { margin-right: 0.25rem; }

.admin-members { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.admin-members li { display: flex; align-items: center; gap: 0.5rem; font-size: 0.92rem; }
.admin-members li.empty { color: var(--text-muted); font-style: italic; }

.admin-add-member { display: flex; gap: 0.4rem; margin-top: 0.6rem; flex-wrap: wrap; align-items: center; }
.admin-add-member select { padding: 0.3rem 0.4rem; }

/* Текстовая кнопка-ссылка (промоут/добавить) — не primary, чтобы не шуметь */
.link-btn {
  background: transparent; color: var(--accent); border: 1px solid transparent;
  border-radius: 6px; padding: 0.15rem 0.4rem; font-size: 0.85rem;
  cursor: pointer; box-shadow: none; margin: 0; align-self: auto;
}
.link-btn:hover { background: var(--accent-soft); }

.invite-box-title { margin: 0 0 0.5rem; font-weight: 600; }
.invite-row { display: flex; gap: 0.4rem; align-items: center; }
.invite-row input { flex: 1; min-width: 0; }
.invite-row button { margin: 0; align-self: auto; }

/* --- Редизайн админки: тулбар, группы-аккордеон, модалки --- */

.admin-toolbar {
  display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap;
  margin: 0.5rem 0 0.75rem;
}
.admin-toolbar input[type="search"] { flex: 1; min-width: 12rem; max-width: 28rem; }
.admin-toolbar button { margin: 0; align-self: auto; white-space: nowrap; }

/* Группы как раскрывающиеся строки (<details>) */
details.admin-group {
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 0.5rem;
  background: var(--surface);
  overflow: hidden;
}
details.admin-group > summary {
  display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  padding: 0.6rem 0.8rem; cursor: pointer; list-style: none;
}
details.admin-group > summary::-webkit-details-marker { display: none; }
details.admin-group > summary::before {
  content: '▸'; color: var(--text-muted); transition: transform 0.15s; display: inline-block;
}
details.admin-group[open] > summary::before { transform: rotate(90deg); }
details.admin-group > summary:hover { background: var(--surface-alt); }
details.admin-group > summary strong { margin-right: 0.15rem; }
.group-count { margin-left: auto; color: var(--text-muted); font-size: 0.85rem; }
.admin-group-inner { padding: 0.3rem 0.8rem 0.8rem; border-top: 1px solid var(--border); }
.admin-group-actions { display: flex; gap: 0.5rem; margin-bottom: 0.4rem; }

/* «Группы» — простой текст в ячейке. НЕ flex (иначе td выпадает из табличной
   раскладки: высота схлопывается и нижняя граница «едет вверх» относительно ряда). */
.group-chips { color: var(--text); }

.link-btn.danger { color: var(--danger); }
.link-btn.danger:hover { background: var(--danger-soft); }

.ue-section-label { font-size: 0.82rem; color: var(--text-muted); font-weight: 600; margin: 0.75rem 0 0.3rem; }

/* Формы внутри модалок (создание юзера/группы): подпись над полем, поле во всю ширину */
#create-user-form, #create-group-form { max-width: none; gap: 0.6rem; }
#create-user-form label, #create-group-form label {
  display: flex; flex-direction: column; align-items: stretch;
  justify-content: flex-start; gap: 0.25rem; font-size: 0.9rem;
}
#create-user-form input, #create-user-form select,
#create-group-form input, #create-group-form select { width: 100%; min-width: 0; }

/* Базовый стиль ВСЕХ модалок — чтобы не было дефолтной жирной рамки браузера.
   Конкретные .meals-modal/#merge-modal/#edit-meal-modal перекрывают своими
   правилами (выше по специфичности), так что их вид не меняется. */
dialog {
  padding: 1.25rem;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text);
  max-width: 92vw;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.5); }
dialog > form { position: relative; max-width: none; }
#create-user-modal, #create-group-modal, #user-edit-modal { width: 460px; }

/* Крестик-закрытие в углу модалки (как в .meals-modal, но доступен везде). */
.modal-close-x {
  position: absolute; top: -0.5rem; right: -0.5rem;
  background: transparent; border: none; box-shadow: none; outline: none;
  font-size: 1.4rem; line-height: 1; padding: 0.25rem 0.5rem; margin: 0;
  cursor: pointer; color: var(--text-muted); min-height: auto; border-radius: 6px;
  align-self: auto;
}
.modal-close-x:hover { color: var(--text); background: var(--surface-alt); }

/* Вторичная кнопка в модалках (Отмена, +Добавить) */
dialog button.secondary {
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong);
  box-shadow: none;
}
dialog button.secondary:hover { background: var(--surface-alt); }

/* Редактор пользователя: строка выбора группы + кнопки действий */
.admin-add-row { margin: 0.3rem 0 0.5rem; }
#user-edit-modal .select-trigger,
#user-edit-modal .select-dropdown-wrap,
.admin-add-row select { width: 100%; }
.admin-add-actions { display: flex; gap: 0.5rem; margin-top: 0.2rem; }
.admin-add-actions button { margin: 0; align-self: auto; }

@media (max-width: 600px) {
  .admin-table, .admin-table thead, .admin-table tbody, .admin-table tr, .admin-table td { display: block; }
  .admin-table thead { display: none; }
  .admin-table tr { padding: 0.5rem 0.2rem; border-bottom: 1px solid var(--border); position: relative; }
  .admin-table td { border: none; padding: 0.15rem 0.2rem; }
  .admin-table td.actions { position: absolute; top: 0.4rem; right: 0.2rem; }
  .admin-table td:nth-child(1) { font-weight: 600; padding-right: 6rem; }
  .admin-table td:nth-child(2)::before { content: '✉ '; color: var(--text-faint); }
}

/* ── Цикл (profile.html, секция для sex='f') ─────────────────────────────── */
.cycle-current {
  margin: 0 0 0.75rem;
  padding: 0.625rem 0.875rem;
  border-radius: 10px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  font-size: 15px;
  line-height: 1.4;
  color: var(--text);
}
/* Фаза задержки воды (месячные/предменструальная) — мягкая подсветка акцентом. */
.cycle-current.is-water {
  background: var(--accent-soft);
  border-color: transparent;
}
/* История циклов — список строк с полоской длины цикла. */
.cyc-hist { margin-top: 1.25rem; }
.cyc-hist-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.cyc-hist-meta { font-weight: 400; font-size: 13px; color: var(--text-muted); }

/* Календарь цикла — год-хитмап (недели как колонки, как трекер «сухих дней» в годе). */
.cyc-year-tabs { display: flex; gap: 0.25rem; margin-bottom: 0.6rem; }
.cyc-year {
  font: inherit;
  font-size: 13px;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.cyc-year:hover { color: var(--text); }
.cyc-year.active { background: var(--accent-soft); border-color: transparent; color: var(--accent); font-weight: 600; }
.cyc-cal-scroll { overflow-x: auto; padding-bottom: 4px; }
.cyc-mlabels {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 2px;
  margin-bottom: 4px;
}
.cyc-mlabel { font-size: 0.7rem; color: var(--text-muted); white-space: nowrap; width: max-content; }
.cyc-grid {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 2px;
}
.cyc-cell {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  background: var(--surface-alt);
  border: 1px solid transparent;
  box-sizing: border-box;
  transition: transform 0.12s;
}
.cyc-cell:hover { transform: scale(1.12); }
.cyc-menstrual    { background: var(--cycle-menstrual); }
.cyc-premenstrual { background: var(--cycle-water); }
.cyc-ordinary     { background: var(--border-strong); }
/* Дни до первого цикла / будущее — пустой пунктир. */
.cyc-none { background: transparent; border: 1px dashed var(--border); }
.cyc-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  margin-top: 0.7rem;
  font-size: 13px;
  color: var(--text-muted);
}
.cyc-legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.cyc-sw { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.cyc-sw.cyc-ordinary { border: 1px solid var(--border); }

/* Отметка начала цикла — подпись сверху, дата+кнопка в одном ряду, равной высоты. */
.cycle-mark-label { display: block; margin-bottom: 0.3rem; }
.cycle-mark-row { display: flex; align-items: stretch; gap: 0.75rem; flex-wrap: wrap; }
.cycle-mark-row input { width: auto; }
/* align-self: stretch перебивает глобальное button{align-self:flex-start}, иначе кнопка липнет к верху. */
.cycle-mark-row input,
.cycle-mark-row button { margin: 0; align-self: stretch; }

/* Кнопка-раскрытие «добавить метод контрацепции» (форма скрыта по умолчанию). */
.contra-add-btn {
  align-self: flex-start;
  font: inherit;
  font-size: 14px;
  color: var(--accent);
  background: none;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  padding: 0.4rem 0.8rem;
  margin: 0;
  box-shadow: none;
  cursor: pointer;
}
.contra-add-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
#contra-cancel {
  background: none;
  border: none;
  box-shadow: none;
  margin: 0;
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
}
#contra-cancel:hover { background: none; color: var(--text); text-decoration: underline; }

/* Контрацепция — таймлайн методов (метод · период). */
.contra-list { list-style: none; margin: 0 0 0.75rem; padding: 0; display: flex; flex-direction: column; }
.contra-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 0.6rem;
  font-size: 14px;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
}
.contra-row:last-child { border-bottom: none; }
.contra-main { color: var(--text); }
.contra-when { color: var(--text-muted); white-space: nowrap; font-size: 13px; }
.contra-row.is-active .contra-main { font-weight: 600; }
.contra-row.is-active .contra-when { color: var(--accent); }
.contra-actions { display: inline-flex; align-items: center; gap: 0.5rem; }
.contra-finish {
  font: inherit;
  font-size: 13px;
  color: var(--accent);
  background: none;
  border: none;
  box-shadow: none;       /* перебиваем глобальный button{box-shadow} */
  margin: 0;              /* и button{margin-top} — иначе «ниже» */
  padding: 0;
  align-self: center;
  cursor: pointer;
  white-space: nowrap;
}
.contra-finish:hover { background: none; text-decoration: underline; }  /* без тёмного button:hover */
.contra-list .del { line-height: 1; padding: 0.1rem 0.25rem; font-size: 15px; }

/* ── Страница рецептов ─────────────────────────────────────────── */

/* Снимаем глобальные ограничения form { max-width; display: flex } и
   form input { width: 55% }, которые ломают полноширинную форму рецепта. */
#recipe-meta-form {
  max-width: none;
  gap: 0.75rem;
}
#recipe-meta-form label {
  display: grid;
  grid-template-columns: 6rem 1fr;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.95rem;
}
/* После attachVendorAutocomplete() input оборачивается в .ac-wrap — нужны
   те же overrides что в #edit-meal-form (строка ~816). */
#recipe-meta-form input,
#recipe-meta-form .ac-wrap,
#recipe-meta-form .ac-wrap input { width: 100%; min-width: 0; }

/* Строка поиска ингредиента: [Найти продукт...] [г] [Добавить] */
.ing-search-wrap { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.25rem; }
.ing-search-wrap .ac-wrap { flex: 1; min-width: 0; }
.ing-search-wrap .ac-wrap input { width: 100%; }
.ing-search-wrap input[type="number"] { width: 5.5rem; flex-shrink: 0; padding-block: 0.35rem; }
.ing-search-wrap button { flex-shrink: 0; padding-block: 0.35rem; }

/* Диалог создания нового продукта */
#new-food-form { max-width: none; }

/* Строка ингредиента в списке */
.ingredient-row {
  display: grid;
  grid-template-columns: 1fr 5.5rem auto;
  gap: 0.5rem;
  align-items: center;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
}
.ingredient-row:last-child { border-bottom: none; }
.ingredient-row .ing-name { font-size: 0.9rem; }
.ingredient-row .ing-vendor { font-size: 0.78rem; color: var(--text-muted); }
.ingredient-row input[type="number"] { width: 100%; font-size: 0.9rem; padding: 0.25rem 0.4rem; }
.ingredient-row .ing-remove {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1.1rem;
  padding: 0.1rem 0.3rem;
  border-radius: 6px;
}
.ingredient-row .ing-remove:hover { color: var(--danger); background: var(--surface-alt); }

#ingredients-list { margin: 0.5rem 0 1rem; }
#ingredients-list:empty::after {
  content: 'Ингредиентов пока нет';
  display: block;
  color: var(--text-muted);
  font-size: 0.85rem;
  padding: 0.5rem 0;
}

/* Итоговые макросы */
.recipe-totals {
  background: var(--surface-alt);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
  margin: 0.75rem 0;
  font-size: 0.9rem;
}
.recipe-totals-row {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.recipe-totals-row + .recipe-totals-row {
  margin-top: 0.3rem;
  color: var(--text-muted);
  font-size: 0.82rem;
}
.recipe-totals strong { font-variant-numeric: tabular-nums; }

/* Кнопки редактора */
.recipe-editor-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}
.recipe-editor-actions button { white-space: nowrap; margin: 0; }

/* Карточки в списке рецептов */
.recipe-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
  cursor: pointer;
  transition: background 0.12s;
}
.recipe-card:hover { background: var(--surface-alt); }
.recipe-card.active { border-color: var(--accent); background: var(--accent-soft); }
.recipe-card-name { font-weight: 600; font-size: 0.95rem; margin: 0 0 0.25rem; }
.recipe-card-meta {
  font-size: 0.8rem;
  color: var(--text-muted);
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}
.recipe-card-actions { display: flex; gap: 0.5rem; }
.recipe-card-actions button { font-size: 0.8rem; padding: 0.2rem 0.6rem; margin: 0; }

/* Отступ под заголовком редактора, чтобы кнопка не казалась наплывающей на форму */
#recipe-editor .section-head { margin-bottom: 0.75rem; }

@media (max-width: 480px) {
  .ing-search-wrap { flex-wrap: wrap; }
  .ing-search-wrap .ac-wrap { width: 100%; }
  .ingredient-row { grid-template-columns: 1fr 5rem auto; gap: 0.35rem; }
}

/* === Тренировки (workout.html) ============================================
 * Седьмая тематическая палитра — цвет = «семья» вида спорта. Не путать с
 * meal-types / sleep / inbody: здесь цвет кодирует ТИП тренировки (бег, плавание,
 * велосипед…), используется в heatmap-ячейках, легенде и горизонтальных барах.
 * Оттенки подобраны различимыми и в тон существующей палитре. См. design-system §1.11. */
:root {
  --sport-walk:     #5b8c6b;  /* мягкий зелёный */
  --sport-run:      #e0684a;  /* кораллово-красный */
  --sport-cycle:    #2f80c4;  /* синий */
  --sport-swim:     #17a2b8;  /* бирюзовый */
  --sport-strength: #8a5cb8;  /* фиолетовый */
  --sport-yoga:     #c77b9c;  /* пыльно-розовый */
  --sport-hike:     #b07a3c;  /* охра */
  --sport-other:    #7c8794;  /* серый */
}
[data-theme="dark"] {
  --sport-walk:     #6faa82;
  --sport-run:      #ef8168;
  --sport-cycle:    #5aa0e0;
  --sport-swim:     #3cc0d3;
  --sport-strength: #a887cc;
  --sport-yoga:     #d698b4;
  --sport-hike:     #cb965a;
  --sport-other:    #94a3b8;
}

/* Свотч легенды видов спорта — крошечный квадрат ≤16px (микро-радиус 3px, §1.9). */
.sport-sw {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  vertical-align: -2px;
  margin-right: 0.35rem;
  background: var(--sport-other);
}
.sport-sw.sport-walk     { background: var(--sport-walk); }
.sport-sw.sport-run      { background: var(--sport-run); }
.sport-sw.sport-cycle    { background: var(--sport-cycle); }
.sport-sw.sport-swim     { background: var(--sport-swim); }
.sport-sw.sport-strength { background: var(--sport-strength); }
.sport-sw.sport-yoga     { background: var(--sport-yoga); }
.sport-sw.sport-hike     { background: var(--sport-hike); }
.sport-sw.sport-other    { background: var(--sport-other); }

/* Легенда heatmap видов спорта — как .sleep-heatmap-legend, но со свотчами
 * по семьям спорта (переиспользуем flex-wrap контейнер). */
.workout-legend {
  margin-top: 0.6rem;
  display: flex;
  gap: 0.75rem 0.9rem;
  align-items: center;
  font-size: 0.8rem;
  color: var(--text-muted);
  flex-wrap: wrap;
}
.workout-legend > span { display: inline-flex; align-items: center; }

/* Горизонтальные бары «Разбивка по типам». Каждая строка — метка вида,
 * дорожка-трек с закрашенной долей (ширина ∝ длительности) и значение.
 * Новый компонент — задокументирован в design-system §1.11. */
.sport-bars {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.sport-bar-row {
  display: grid;
  grid-template-columns: 7rem 1fr auto;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.9rem;
}
.sport-bar-label {
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sport-bar-track {
  background: var(--surface-alt);
  border-radius: 6px;
  height: 0.9rem;
  overflow: hidden;
}
.sport-bar-fill {
  height: 100%;
  border-radius: 6px;
  background: var(--sport-other);
  min-width: 3px;
}
.sport-bar-fill.sport-walk     { background: var(--sport-walk); }
.sport-bar-fill.sport-run      { background: var(--sport-run); }
.sport-bar-fill.sport-cycle    { background: var(--sport-cycle); }
.sport-bar-fill.sport-swim     { background: var(--sport-swim); }
.sport-bar-fill.sport-strength { background: var(--sport-strength); }
.sport-bar-fill.sport-yoga     { background: var(--sport-yoga); }
.sport-bar-fill.sport-hike     { background: var(--sport-hike); }
.sport-bar-fill.sport-other    { background: var(--sport-other); }
.sport-bar-value {
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Лента тренировок — таблица. Десктоп: как inbody/meals (right-align числа). */
#workout-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
#workout-table th,
#workout-table td {
  padding: 0.4rem 0.6rem;
  text-align: right;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
#workout-table th {
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--text-muted);
  letter-spacing: 0.03em;
}
#workout-table td:nth-child(1),
#workout-table th:nth-child(1),
#workout-table td:nth-child(2),
#workout-table th:nth-child(2) { text-align: left; }
#workout-table tbody tr:hover > td { background: var(--surface-alt); }
.workout-sport-cell {
  display: inline-flex;
  align-items: center;
}
.workout-table-wrap.collapsed #workout-table tbody tr:nth-child(n+11) { display: none; }

@media (max-width: 600px) {
  /* Карточный view ленты тренировок (§9): thead скрыть, td — блочные строки-
   * карточки с подписями через ::before. */
  #workout-table { display: block; font-size: 0.9rem; }
  #workout-table thead { display: none; }
  #workout-table tbody { display: block; }
  #workout-table tr {
    display: block;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
  }
  #workout-table td {
    display: inline;
    text-align: left;
    border-bottom: none;
    padding: 0;
    white-space: normal;
  }
  /* Тип — заголовок карточки отдельной строкой. */
  #workout-table td:nth-child(2) {
    display: block;
    font-weight: 500;
    margin-bottom: 0.15rem;
  }
  /* Дата/время — второй строкой, приглушённо. */
  #workout-table td:nth-child(1) {
    display: block;
    font-size: 0.82rem;
    color: var(--text-muted);
    margin-bottom: 0.15rem;
  }
  #workout-table td:nth-child(3)::before { content: 'Длит. '; color: var(--text-muted); }
  #workout-table td:nth-child(4):not(:empty)::before { content: ' · '; color: var(--text-muted); }
  #workout-table td:nth-child(5):not(:empty)::before { content: ' · '; color: var(--text-muted); }
  #workout-table td:nth-child(6):not(:empty)::before { content: ' · пульс '; color: var(--text-muted); }
  .sport-bar-row { grid-template-columns: 5.5rem 1fr auto; gap: 0.5rem; }
}

@media (max-width: 480px) {
  .workout-table-wrap { overflow-x: visible; }
}

/* --- Борды лекарств/добавок (/supplements.html) ---
   Один борд на лекарство: годовой календарь квадратиков (GitHub-style, та же
   геометрия, что у трекера «сухих дней» .alc-grid-year). Заполненный квадрат =
   принято в этот день; клик отмечает/снимает приём. */
.med-board { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.med-board:first-child { margin-top: 0.25rem; padding-top: 0; border-top: none; }
.med-board-head {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 0.25rem 0.6rem; margin-bottom: 0.5rem;
}
.med-board-title { font-size: 1rem; font-weight: 600; margin: 0; }
.med-board-meta { font-size: 0.8rem; }

.med-cal-scroll { overflow-x: auto; padding-bottom: 0.25rem; }
.med-mlabels {
  display: grid; grid-auto-flow: column; grid-auto-columns: 14px;
  gap: 2px; margin-bottom: 4px;
}
.med-mlabel { font-size: 0.7rem; color: var(--text-muted); white-space: nowrap; width: max-content; }
.med-cal {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 2px;
}
.med-cell {
  width: 14px; height: 14px; border-radius: 2px;
  background: var(--surface-alt);
  border: 1px solid transparent;
  transition: transform 0.12s;
  outline: none;
}
.med-cell[role="button"] { cursor: pointer; }
.med-taken { background: var(--accent); }
.med-future { background: transparent; border: 1px dashed var(--border); }
.med-cell[role="button"]:hover, .med-cell:focus-visible { transform: scale(1.15); }
.med-cell:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft); }
