/* fonts.css */
/* =====================================================
   Шрифт интерфейса.

   На технике Apple берём системный SF Pro: он там уже стоит, отрисован лучше
   любого веб-шрифта и не стоит ни байта трафика. Всем остальным отдаём Inter —
   это ближайший к SF Pro свободный шрифт с полной кириллицей. Раньше стек
   заканчивался на Segoe UI и Roboto, поэтому одно и то же приложение на iPhone,
   Android и в браузере выглядело тремя разными продуктами.

   Порядок в стеке важен: -apple-system стоит первым, поэтому на iOS и macOS
   Inter даже не скачивается — браузер грузит только те шрифты, которыми
   реально что-то нарисовано.

   Файлы лежат рядом, а не на fonts.googleapis.com: приложение открывается
   внутри Telegram, где сторонний домен это лишний DNS, лишний TLS и лишняя
   зависимость от того, доступен ли Google из сети пользователя.
   ===================================================== */

:root {
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    Inter, "Segoe UI", Roboto, system-ui, sans-serif;
}

/* Один переменный файл на все насыщенности от 400 до 800: отдельные файлы под
   каждый вес весили бы вместе больше, а половина из них так и не пригодилась. */

/* size-adjust выравнивает Inter по SF Pro. У Inter строчные выше при том же
   кегле, поэтому без поправки текст на Android выглядел бы крупнее, чем на
   iPhone, при одинаковом font-size в CSS. 96% приводит высоту строчных к
   пропорциям SF Pro. Браузеры без поддержки просто игнорируют строку. */

/* cyrillic — основной сабсет: интерфейс русский, эти буквы нужны сразу. */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  size-adjust: 96%;
  src: url(/static/fonts/inter-cyrillic.woff2) format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* latin — цифры, единицы измерения, латиница в названиях продуктов. */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  size-adjust: 96%;
  src: url(/static/fonts/inter-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext нужен из-за знака рубля U+20BD: он живёт именно здесь, а цены в
   подписке и админке без него рисовались бы системным шрифтом вперемешку. */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  size-adjust: 96%;
  src: url(/static/fonts/inter-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* theme.css */
/* =====================================================
   Nutrition AI — дизайн-система
   Чистый, спокойный UI: светлый по умолчанию / тёмный для
   тёмной темы Telegram. Цвет — ТОЛЬКО для акцентов
   (кольцо калорий, активная вкладка, кнопки, прогресс).
   Здесь живут токены и унифицированные примитивы:
     .card         — карточка-контейнер
     .btn-primary  — основная кнопка
     input/select  — поля ввода
   ===================================================== */
:root {
  /* Акценты (используются точечно) */
  --color-primary: #22c55e;     /* зелёный — основной акцент */
  --color-primary-2: #38bdf8;   /* голубой — углеводы / графики */
  --color-accent: #f59e0b;      /* янтарь — белок / предупреждения */
  --color-danger: #ef4444;      /* красный — жиры / перебор */

  /* Поверхности (нейтральные, почти белые) */
  --bg-app: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #f7f8fa;         /* вложенные плитки */
  --border: #e7e9ee;
  --border-strong: #d8dbe2;

  /* Текст */
  --text-primary: #11151c;
  --text-secondary: #5b6470;
  --text-muted: #98a1ad;

  /* Трек прогресса / поля */
  --fill-track: #eceef2;
  --fill-input: #f7f8fa;

  /* Геометрия */
  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-pill: 999px;

  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;

  /* Движение */
  --dur: 0.22s;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Тени — мягкие, едва заметные */
  --shadow-card: 0 1px 2px rgba(16, 24, 40, 0.04),
    0 6px 16px rgba(16, 24, 40, 0.06);
  --shadow-float: 0 8px 28px rgba(16, 24, 40, 0.14);

  --nav-h: 64px;
}

body.tg-dark-theme {
  --color-primary: #34d27b;
  --color-primary-2: #4cc2f1;
  --color-accent: #f5b22d;
  --color-danger: #f06a60;

  --bg-app: #0d1117;
  --surface: #161b22;
  --surface-2: #1c232d;
  --border: #262d38;
  --border-strong: #323a47;

  --text-primary: #e9edf2;
  --text-secondary: #aab2bd;
  --text-muted: #6b7480;

  --fill-track: #232b36;
  --fill-input: #1c232d;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 18px rgba(0, 0, 0, 0.35);
  --shadow-float: 0 10px 32px rgba(0, 0, 0, 0.55);
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

/* Шрифт задан на body, но элементы управления его не наследуют: у браузера для
   них своё семейство. Без этой строки текст в кнопках набирался системным
   Arial — рядом с обычным текстом на SF Pro / Segoe UI разница видна сразу. */
button,
textarea {
  font-family: inherit;
}

/* Служебный класс скрытия. Его ставит JS почти в каждом модуле, но своего
   правила у него не было: правила были только точечные (.view, .pane и ещё
   пара). Скрытая карточка оставалась в потоке пустой белой плашкой — так на
   «Сводке» и появлялся пустой блок над виджетом серии. */
.hidden { display: none !important; }

html {
  scroll-behavior: smooth;
  /* Резервируем место под полосу прокрутки всегда — иначе при появлении/
     исчезновении скролла контент «прыгает» по ширине между разделами. */
  scrollbar-gutter: stable;
  overflow-x: hidden;
}

body {
  margin: 0;
  /* Сам стек и подключение Inter — в fonts.css. */
  font-family: var(--font-ui);
  color: var(--text-primary);
  background: var(--bg-app);
  min-height: 100vh;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Графики-канвасы всегда вписаны в ширину карточки (без переполнения вправо).
   Высоту задаём явно, чтобы canvas не масштабировался по соотношению сторон. */
canvas { max-width: 100%; }

/* ----------------- КАРТОЧКИ ----------------- */
.card,
.glass-card,
.mc-card,
.recipe-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

.glass-card {
  padding: var(--spacing-md);
  margin-bottom: var(--spacing-md);
}

/* ----------------- КНОПКИ ----------------- */
.btn-primary {
  border: none;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  color: #fff;
  font-weight: 650;
  font-size: 15px;
  padding: 12px 22px;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.btn-primary:active { transform: scale(0.97); filter: brightness(0.96); }

/* ----------------- ПОЛЯ ВВОДА ----------------- */
input,
select {
  width: 100%;
  border: 1px solid var(--border);
  background: var(--fill-input);
  color: var(--text-primary);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-size: 15px;
  font-family: inherit;
  outline: none;
  transition: border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}
input::placeholder { color: var(--text-muted); }
input:focus,
select:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent);
}
select { appearance: none; -webkit-appearance: none; }

/* app.css */
/* =====================================================
   Каркас приложения: сетка страницы, hero-кольцо калорий,
   макросы и шкалы целей, формы и нижняя навигация.
   Списки приёмов, оверлеи, скелетоны — в meal_list.css,
   overlays.css, loading.css.
   Опирается на примитивы из theme.css (.card / .btn-primary / поля).
   ===================================================== */

/* ----------------- Каркас ----------------- */
.main-content {
  padding: var(--spacing-md);
  padding-bottom: calc(var(--nav-h) + 40px);
  max-width: 600px;
  margin: 0 auto;
}
.container { width: 100%; }

.page-header { margin: 4px 2px 16px; }
.page-title {
  font-size: 28px;
  font-weight: 800;
  margin: 0;
  letter-spacing: -0.6px;
}

.view { animation: viewIn var(--dur) var(--ease); }
.view.hidden { display: none; }
@keyframes viewIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Заголовок карточки. */
.card-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 14px;
  color: var(--text-primary);
}
.card-title svg {
  width: 19px;
  height: 19px;
  color: var(--color-primary);
  flex: none;
}

/* ----------------- Hero: кольцо калорий ----------------- */
.hero-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  padding: 18px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Кнопка-подсказка «сменить дату» в углу карточки (вся карточка кликабельна). */
.hero-cal {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hero-cal svg { width: 16px; height: 16px; }
.hero-cal:active { transform: scale(0.94); }
/* Быстрый возврат к сегодняшнему дню (виден, когда выбран не сегодня). */
.hero-today {
  position: absolute;
  top: 10px;
  right: 48px;
  z-index: 1;
  height: 30px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 12px;
  border: none;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 14%, var(--surface-2));
  color: var(--color-primary);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.hero-today.hidden { display: none; }
.hero-today svg { width: 14px; height: 14px; }
.hero-today:active { transform: scale(0.95); }
.ring-wrap { position: relative; width: 132px; height: 132px; flex: none; }
#kcal-ring { display: block; width: 132px; height: 132px; }
.ring-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ring-value {
  font-size: 31px;
  font-weight: 800;
  letter-spacing: -1px;
  line-height: 1;
}
/* Перебор нормы — тоном глубже, как хвост кольца: «+250» тем же чёрным
   читалось бы как остаток, а красным — как авария. */
.ring-value.over { color: var(--hc-kcal-ink, #15803d); }
.ring-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  margin-top: 5px;
}

/* Макросы — нейтральные плитки, значение акцентным цветом. */
.macros { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.macro {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 10px 13px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-secondary);
  white-space: nowrap;
}
.macro .v { font-weight: 800; font-size: 15px; color: var(--text-primary); }
.macro .v.p { color: var(--color-accent); }
.macro .v.f { color: var(--color-danger); }
.macro .v.c { color: var(--color-primary-2); }

/* Виджет шапки: остаток калорий + баланс Б/Ж/У. */
.hero-kpi { display: flex; flex-direction: column; gap: 2px; }
.hero-kpi-val {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.5px;
  line-height: 1;
  color: var(--text-primary);
}
.hero-kpi-val.over { color: var(--color-danger); }
.hero-kpi-sub {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}
/* Прибавка к норме за тренировку: кликабельна и ведёт в «Активность», где видно,
   из какой тренировки она сложилась. */
.hero-kpi-bonus {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-primary);
  cursor: pointer;
  margin-top: 3px;
}
.macro-balance { display: flex; flex-direction: column; gap: 7px; }
.mb-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
}
.mb-bar {
  display: flex;
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.mb-seg { height: 100%; transition: width 0.6s var(--ease); }
.mb-seg.p { background: var(--color-accent); }
.mb-seg.f { background: var(--color-danger); }
.mb-seg.c { background: var(--color-primary-2); }
.mb-legend {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  font-size: 11px;
  color: var(--text-secondary);
}
.mb-legend span { display: flex; align-items: center; gap: 4px; }
.mb-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.mb-dot.p { background: var(--color-accent); }
.mb-dot.f { background: var(--color-danger); }
.mb-dot.c { background: var(--color-primary-2); }

/* Полоска «Жиры» в таблице целей — кликабельна, заполнение разбито по типам. */
.goal-fat { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.fat-info {
  width: 12px;
  height: 12px;
  vertical-align: -2px;
  margin-left: 1px;
  opacity: 0.45;
}
.bar-fat { display: flex; }
.bar-fat > span { border-radius: 0; }
.fat-seg { height: 100%; transition: width 0.6s var(--ease); }
.fat-seg.unsat { background: var(--color-primary); }
.fat-seg.sat { background: color-mix(in srgb, var(--color-accent) 80%, var(--text-muted)); }
.fat-seg.unk { background: color-mix(in srgb, var(--text-muted) 50%, transparent); }

/* Затемнение и размытие фона под тултипом. */
.fat-tip-backdrop {
  position: fixed;
  inset: 0;
  z-index: 199;
  background: rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: fat-tip-backdrop-in 0.16s var(--ease);
}
@keyframes fat-tip-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Тултип-описание разбивки жиров (поповер, не модалка). */
.fat-tip {
  position: fixed;
  z-index: 200;
  width: min(290px, calc(100vw - 32px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 14px 15px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.22);
  animation: fat-tip-in 0.16s var(--ease);
}
@keyframes fat-tip-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
.fat-tip-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 800;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.fat-tip-title i { width: 15px; height: 15px; }
.fat-tip-desc {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
  margin-bottom: 13px;
}
.fat-tip-row { margin-bottom: 11px; }
.fat-tip-row:last-child { margin-bottom: 0; }
.fat-tip-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--text-secondary);
  margin-bottom: 5px;
}
.fat-tip-head > span:last-child { font-weight: 700; color: var(--text-primary); }
.fat-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: 0;
}
.fat-dot.unsat { background: var(--color-primary); }
.fat-dot.sat { background: color-mix(in srgb, var(--color-accent) 80%, var(--text-muted)); }
.fat-dot.unk { background: color-mix(in srgb, var(--text-muted) 50%, transparent); }
.fat-tip .bar > span.b-unsat { background: var(--color-primary); }
.fat-tip .bar > span.b-sat { background: color-mix(in srgb, var(--color-accent) 80%, var(--text-muted)); }
.fat-tip .bar > span.b-unk { background: color-mix(in srgb, var(--text-muted) 50%, transparent); }
.fat-tip .bar.under > span { background: var(--color-accent); }
/* Итоговая подпись-статус в тултипе нутриента. Перебор — янтарём лимита, а не
   красным: повод присмотреться, а не авария. */
.fat-tip-note { font-size: 12px; font-weight: 700; color: var(--text-secondary); margin-top: 10px; }
.fat-tip-note.over { color: var(--hc-warn-ink, #b45309); }
.fat-tip-note.under { color: var(--color-accent); }

/* ----------------- Прогресс целей ----------------- */
.goal-progress { display: flex; flex-direction: column; gap: 14px; }
.goal-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 6px;
}
.goal-row span:last-child { font-weight: 600; color: var(--text-primary); }
.bar {
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.bar > span {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  transition: width 0.6s var(--ease);
}
/* Шкалы сверх нормы или лимита (app_nutrients.js, lappedBar): заливка до
   границы ровным краем, засечка и хвост тоном глубже — как у колец карточки
   «Сегодня». Норма — зелёный хвост, лимит — янтарь с тёмно-янтарным. */
.bar.is-lapped { position: relative; }
.bar.is-lapped > span { border-radius: 0; }
.bar.is-limit > span { background: var(--color-accent); }
.bar-lap {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  background: var(--hc-kcal-deep, #15803d);
}
.bar.is-limit > .bar-lap { background: var(--hc-warn-deep, #d97706); }
.bar-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--surface);
}

/* ----------------- Формы ----------------- */
.form-row { display: flex; gap: 10px; }
.form-row input { flex: 1; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.form-grid label {
  grid-column: 1 / -1;
  font-size: 13px;
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.form-grid button,
.form-grid label,
.form-grid .full { grid-column: 1 / -1; }
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  color: var(--text-secondary);
}
.checkbox-row input { width: auto; }

/* ----------------- Нижняя навигация ----------------- */
.bottom-nav {
  position: fixed;
  left: 50%;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(560px, calc(100% - 24px));
  height: var(--nav-h);
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 0 6px;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-float);
  z-index: 1000;
}
.nav-item {
  border: none;
  background: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 600;
  flex: 1;
  padding: 7px 0;
  border-radius: var(--r-md);
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease-spring);
}
.nav-item svg {
  width: 22px;
  height: 22px;
  transition: transform var(--dur) var(--ease-spring);
}
.nav-item.active { color: var(--color-primary); }
.nav-item.active svg { transform: translateY(-1px) scale(1.06); }
.nav-item:active { transform: scale(0.92); }

/* Затемнение у нижнего края экрана на величину отступа меню от низа:
   гасит контент, просвечивающий в зазоре под плавающим меню.
   Лежит ниже nav (1000) и перекрывается subview/sheet своими фонами. */
.bottom-fade {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(12px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--bg-app) 40%, transparent);
  pointer-events: none;
  z-index: 999;
}


/* ----------------- Адаптив ----------------- */
/* На узких экранах сохраняем компактную раскладку (кольцо слева, показатели
   справа) — как на десктопе; лишь чуть уменьшаем кольцо, чтобы всё поместилось. */
@media (max-width: 400px) {
  .hero-card { gap: 14px; padding: 16px; }
  .ring-wrap, #kcal-ring { width: 112px; height: 112px; }
  .ring-value { font-size: 27px; }
  .hero-kpi-val { font-size: 23px; }
}

/* Приложение для телефона: меню, «+» и «Сегодня» свои у оболочки
   (docs/MOBILE_APP.md, «Своя основа (v2)»). Mini App открыт во вкладках
   «Прогресс» и «Профиль» и до низа экрана не тянется. */
body.perek-app .bottom-nav,
body.perek-app .bottom-fade,
/* :not(.tg-webapp) — та же специфичность, что у показа «+» в web.css,
   который идёт в сборке позже и иначе перебивает скрытие. */
body.perek-app:not(.tg-webapp) .fab-add { display: none; }
body.perek-app .main-content { padding-bottom: 24px; }

/* Эмодзи, нарисованные иконкой (js/app_emoji.js, только в приложении): по
   размеру строки, цвет по смыслу, как у своих экранов приложения. */
.emo-ic {
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
  stroke-width: 2.2;
  flex-shrink: 0;
}
.emo-fire, .emo-amber, .emo-protein { color: var(--color-accent); }
.emo-green { color: var(--color-primary); }
.emo-water, .emo-blue { color: var(--color-primary-2); }
.emo-coral { color: var(--color-danger); }
.emo-violet { color: #8b5cf6; }
.emo-plain { color: var(--text-secondary); }
.emo-muted { color: var(--text-muted); }
.emo-gold { color: #d4a106; }
.emo-silver { color: #8a94a3; }
.emo-bronze { color: #b0703f; }
.emo-inherit { color: inherit; }

/* meal_list.css */
/* =====================================================
   Списки приёмов и рецептов: группы по типу приёма,
   карточка слота и свёрнутый вид чипами, бейджи.
   ===================================================== */

/* ----------------- Списки (приёмы / рецепты) ----------------- */
.list { display: flex; flex-direction: column; gap: 12px; }

/* ----------------- Группы приёмов (Завтрак/Обед/…) ----------------- */
.meal-group { display: flex; flex-direction: column; }
.mg-head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border: none;
  background: none;
  cursor: pointer;
  padding: 2px 4px 0;
  color: var(--text-primary);
  font: inherit;
}
.mg-head:active { opacity: 0.6; }
.mg-title {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 800;
  font-size: 16px;
  letter-spacing: -0.3px;
}
.mg-title svg { width: 18px; height: 18px; color: var(--color-primary); flex: none; }
.mg-meta { display: inline-flex; align-items: center; gap: 9px; flex: none; }
.mg-kcal { font-size: 13px; font-weight: 700; color: var(--text-secondary); }
.mg-chev {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  transform: rotate(180deg);
  transition: transform var(--dur) var(--ease);
}
.meal-group.collapsed .mg-chev { transform: rotate(0deg); }

/* Плавное сворачивание через grid-template-rows (0fr ↔ 1fr). */
.mg-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.3s var(--ease);
}
.meal-group.collapsed .mg-body { grid-template-rows: 0fr; }
.mg-inner {
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 10px;
}
/* overflow:hidden нужен ТОЛЬКО на время сворачивания и в свёрнутом состоянии,
   иначе он срезает мягкую тень карточек по бокам/снизу. В развёрнутом покое
   держим overflow:visible — тогда box-shadow приёмов отображается целиком. */
.meal-group.collapsed .mg-inner,
.meal-group.animating .mg-inner { overflow: hidden; }

/* ----------------- Карточка слота (подробный вид) -----------------
   Слот — одна карточка: строка времени у каждого приёма, продукты строками
   со своими ккал, внизу одна строка БЖУ. Строка продукта — кнопка: открывает
   шторку приёма на этом продукте. */
/* Переключатель вида (список / чипы) в строке вкладок: два плоских
   значка без подложки, включённый темнее (подложка с тенью выглядела объёмной). */
.mc-switch { flex: none; display: inline-flex; gap: 2px; }
.mc-switch-btn {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-muted);
  opacity: 0.6;
  cursor: pointer;
}
.mc-switch-btn svg { width: 15px; height: 15px; }
.mc-switch-btn.on { color: var(--text-secondary); opacity: 1; }
.mc-switch-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

.mc-card { padding: 10px 14px 12px; display: flex; flex-direction: column; }
.mc-meal + .mc-meal { margin-top: 6px; }
.mc-meal.needs-clarification .mc-time { color: var(--color-accent); }

.mc-time {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  border-radius: 8px;
}
.mc-time:focus-visible,
.mc-row:focus-visible,
.mc-chip:focus-visible,
.mc-question:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.mc-line { flex: 1; height: 1px; background: var(--border); }
.mc-tkcal { margin-left: auto; font-weight: 500; }
.mc-photo {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 6px;
}
.mc-photo svg { width: 14px; height: 14px; }
.mc-photo:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.mc-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  width: calc(100% + 12px);
  margin: 0 -6px;
  padding: 5px 6px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
}
.mc-row:active { background: var(--surface-2); }
.mc-name { min-width: 0; }
.mc-amount { margin-left: 5px; color: var(--text-muted); font-size: 12px; white-space: nowrap; }
.mc-kcal { flex: none; color: var(--text-secondary); font-size: 13px; font-variant-numeric: tabular-nums; }
.mc-pill {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-left: 6px;
  padding: 1px 6px 1px 8px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  vertical-align: 1px;
}
.mc-pill svg,
.mc-chip-chev { width: 12px; height: 12px; transition: transform var(--dur) var(--ease); }
.mc-dish[aria-expanded="true"] .mc-pill svg,
.mc-dish[aria-expanded="true"] .mc-chip-chev { transform: rotate(180deg); }
.mc-ings { margin: 0 0 4px 2px; padding-left: 12px; border-left: 2px solid var(--fill-track); }
.mc-ings[hidden] { display: none; }
.mc-ings .mc-row { padding-top: 3px; padding-bottom: 3px; font-size: 13px; color: var(--text-secondary); }

/* Лучшее блюдо дня: название не трогаем, под ним серая строка с листиком. */
.mc-best {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 1px;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.35;
}
.mc-best svg { width: 12px; height: 12px; color: var(--color-primary); flex: none; }

.mc-question {
  display: block;
  width: 100%;
  padding: 3px 0;
  border: none;
  background: none;
  color: var(--color-accent);
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  text-align: left;
  cursor: pointer;
}

/* Строка БЖУ: три части разнесены по всей ширине, цвет только у точек. */
.mc-macros {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
  color: var(--text-muted);
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.mc-macro b { font-weight: 600; color: var(--text-secondary); }
.mc-dot { display: inline-block; width: 6px; height: 6px; margin-right: 5px; border-radius: 50%; vertical-align: 1px; }
.mc-dot.p { background: var(--color-accent); }
.mc-dot.f { background: var(--color-danger); }
.mc-dot.c { background: var(--color-primary-2); }
@media (max-width: 340px) {
  .mc-macros { flex-wrap: wrap; white-space: normal; }
}

/* ----------------- Свёрнутый вид: карточка на приём, чипы ----------------- */
.mc-chipcard .mc-time { font-size: 13px; color: var(--text-secondary); }
.mc-clock { display: inline-flex; align-items: center; gap: 5px; }
.mc-clock svg { width: 14px; height: 14px; color: var(--text-muted); flex: none; }
.mc-tkcal-big { font-size: 16px; font-weight: 800; color: var(--color-primary); }
.mc-tkcal-big small { margin-left: 2px; font-size: 10.5px; font-weight: 600; color: var(--text-muted); }
.mc-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.mc-chip {
  display: inline-block;
  max-width: 100%;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-primary);
  font: inherit;
  font-size: 13px;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
}
.mc-chip .mc-amount { margin-left: 4px; }
.mc-chip svg { vertical-align: -2px; }
.mc-chip:active { border-color: var(--border-strong); }
.mc-chip-book { width: 13px; height: 13px; margin-right: 5px; color: var(--text-muted); flex: none; }
.mc-chip-leaf { width: 13px; height: 13px; margin-left: 5px; color: var(--color-primary); flex: none; }
.mc-chip-chev { margin-left: 4px; color: var(--text-muted); flex: none; }
.mc-ing-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  width: 100%;
  margin: 0;
  padding: 7px 8px;
  border: 1px dashed var(--border-strong);
  border-radius: 12px;
}
.mc-ing-chips .mc-chip { padding: 3px 8px; background: var(--surface); font-size: 12px; }
/* Под чипами строка БЖУ прижата влево, как и чипы: растянутая по ширине,
   она упиралась в правый край, до которого рваный ряд чипов не доходит. */
.mc-chipcard .mc-macros { justify-content: flex-start; gap: 16px; margin-top: 10px; }
.mc-chip.mc-question {
  width: auto;
  padding: 4px 10px;
  border-color: color-mix(in srgb, var(--color-accent) 35%, transparent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent);
  font-size: 13px;
}
.mc-chip-q { width: 13px; height: 13px; margin-right: 5px; flex: none; }

@media (hover: hover) and (pointer: fine) {
  .mc-row:hover { background: var(--surface-2); }
  .mc-chip:hover { border-color: var(--border-strong); }
  .mc-time:hover { color: var(--text-secondary); }
  .mc-switch-btn:not(.on):hover { color: var(--text-secondary); }
}

/* Бейджи. */
.badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  margin: 0 6px 6px 0;
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
  border: 1px solid color-mix(in srgb, var(--color-primary) 28%, transparent);
}
.badge.variant {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
  border-color: color-mix(in srgb, var(--color-accent) 28%, transparent);
}

/* overlays.css */
/* =====================================================
   Всплывающие слои и пустые состояния: тост, лайтбокс фото,
   CTA-кнопки «добавить приём» / «поделиться отчётом»,
   модалка-пояснение про пищевой день.
   ===================================================== */

/* ----------------- Toast ----------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-h) + 24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(16px);
  background: var(--text-primary);
  color: var(--surface);
  padding: 10px 18px;
  border-radius: var(--r-pill);
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow-float);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-spring);
  z-index: 3500;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ----------------- Лайтбокс фото ----------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 3000;
  background: rgba(0, 0, 0, 0.9);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.lightbox.show { display: flex; }
.lightbox-stage {
  flex: 1;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.lightbox-stage img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--r-md);
  object-fit: contain;
}
.lightbox-strip {
  display: flex;
  gap: 8px;
  padding-top: 14px;
  overflow-x: auto;
  max-width: 100%;
}
.lightbox-strip img {
  width: 60px;
  height: 60px;
  border-radius: var(--r-sm);
  object-fit: cover;
  opacity: 0.55;
  border: 2px solid transparent;
  cursor: pointer;
  flex: none;
}
.lightbox-strip img.active { opacity: 1; border-color: var(--color-primary); }
.lightbox-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: 16px;
  width: 38px;
  height: 38px;
  border-radius: var(--r-pill);
  border: none;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: 22px;
  cursor: pointer;
}

/* ----------------- Пустые состояния ----------------- */
.empty {
  text-align: center;
  color: var(--text-muted);
  padding: 22px 16px 8px;
  font-size: 14px;
  line-height: 1.5;
}

/* ----------------- Кнопка «Добавить приём» (уводит в чат с ботом) ------- */
.add-entry-btn {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 2px 0 14px;
  padding: 13px 16px;
  border: 1px dashed color-mix(in srgb, var(--color-primary) 45%, var(--border));
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
  color: var(--color-primary);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.add-entry-btn:active { transform: scale(0.98); }
.add-entry-btn svg { width: 18px; height: 18px; }

/* ----------------- Кнопка «Поделиться отчётом за день» ----------------- */
.share-day-btn {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 4px;
  padding: 13px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 15px;
  font-weight: 650;
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.share-day-btn:active { transform: scale(0.98); }
.share-day-btn:disabled { opacity: 0.6; cursor: default; }
.share-day-btn svg { width: 18px; height: 18px; color: var(--color-primary); }

/* Пояснение про персональный «пищевой день» — приглушённая строка в самом низу,
   без карточки, но кликабельная (по тапу — модалка с подробностями). */
.food-day-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  margin: 16px 0 2px;
  padding: 2px 6px;
  background: none;
  border: 0;
  font: inherit;
  font-size: 12px;
  line-height: 1.45;
  text-align: left;
  color: var(--text-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity var(--dur) var(--ease);
}
.food-day-note[hidden] { display: none; }
.food-day-note:active { opacity: 0.55; }
.food-day-note > svg { width: 14px; height: 14px; flex: none; margin-top: 1px; opacity: 0.75; }
.food-day-note .fdn-chev { margin-top: 1px; opacity: 0.5; }

/* Тело модалки-пояснения (заголовок использует общие .nm-head/.nm-close). */
.info-body p {
  margin: 0 0 13px;
  font-size: 14px;
  line-height: 1.52;
  color: var(--text-secondary);
}
.info-body p:last-child { margin-bottom: 2px; }
.info-body b { color: var(--text-primary); font-weight: 700; }

/* ----------------- Выбор канала шеринга (история / чат) ---------------- */
.share-opts { display: flex; flex-direction: column; gap: 8px; padding-bottom: 6px; }
.share-opt {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 16px);
  background: var(--surface);
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.share-opt:active { transform: scale(0.985); }
.share-opt-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-primary) 12%, var(--surface));
  color: var(--color-primary);
}
.share-opt-ico svg { width: 19px; height: 19px; }
.share-opt-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.share-opt-txt b { font-size: 15px; font-weight: 650; }
.share-opt-txt span { font-size: 12.5px; color: var(--text-muted); }
.share-opt-chev { width: 16px; height: 16px; margin-left: auto; opacity: 0.4; }

/* ----------------- Шеринг в веб-версии (превью карточки) ---------------- */
/* В браузере делимся через системное «Поделиться», поэтому сперва показываем
   саму карточку: тап по кнопке под ней — уже «свежий» жест для navigator.share
   (иначе iOS отклоняет вызов после ожидания рендера). */
.share-web {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 6px;
}
.share-web-img {
  width: 100%;
  max-height: 46vh;
  object-fit: contain;
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.share-web .btn-soft,
.share-web .btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  text-decoration: none;
}

/* onboarding_gate.css */
/* =====================================================
   Заглушка на весь экран до прохождения онбординга.
   Сам мастер онбординга оформлен в onboarding.css.
   ===================================================== */

/* ----------------- Онбординг-заглушка на весь экран -------------------- */
.welcome-splash {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow-y: auto;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 22px
    calc(28px + env(safe-area-inset-bottom, 0px));
  background: radial-gradient(120% 78% at 50% 0%,
    color-mix(in srgb, var(--color-primary) 16%, var(--bg-app)) 0%,
    var(--bg-app) 58%);
}
.welcome-splash.show { display: flex; animation: viewIn var(--dur) var(--ease); }
html:has(.welcome-splash.show) { overflow: hidden; }
html:has(.welcome-splash.show) body { overflow: hidden; }

.ws-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: 14px;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: pointer;
}
.ws-close svg { width: 20px; height: 20px; }

.ws-inner {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.ws-icon {
  width: 76px;
  height: 76px;
  border-radius: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
  background: color-mix(in srgb, var(--color-primary) 16%, var(--surface));
  color: var(--color-primary);
  box-shadow: var(--shadow-card);
}
.ws-icon svg { width: 40px; height: 40px; }
.ws-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--text-primary);
  margin: 0 0 10px;
}
.ws-text {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0 0 20px;
}
.ws-steps {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ws-steps li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-primary);
  text-align: left;
}
.ws-num {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary);
  color: #fff;
  font-size: 13px;
  font-weight: 800;
}
.ws-cta {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.ws-cta svg { width: 20px; height: 20px; flex: none; }
.ws-skip {
  margin-top: 14px;
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 10px;
}

/* loading.css */
/* =====================================================
   Состояния загрузки: скелетоны-заглушки и плашка
   «не удалось загрузить» с кнопкой повтора.
   ===================================================== */

/* ----------------- Скелетоны загрузки ----------------- */
/* Мягкое «дыхание» + бегущий блик: пока грузятся показатели, вместо нулей
   видно дружелюбную анимацию, и не кажется, что что-то сломалось. */
@keyframes skel-shimmer { 100% { transform: translateX(100%); } }
.skel {
  display: block;
  position: relative;
  overflow: hidden;
  background: var(--fill-track);
  border-radius: var(--r-sm);
}
.skel::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--surface) 70%, transparent),
    transparent
  );
  animation: skel-shimmer 1.3s var(--ease) infinite;
}
.skel-ring-num { width: 60px; height: 30px; border-radius: 8px; }
.goal-skel-row { display: flex; flex-direction: column; }
.skel-row { display: flex; align-items: center; gap: 12px; }
.skel-circle { border-radius: 50%; flex: none; }
@media (prefers-reduced-motion: reduce) {
  .skel::after { animation: none; }
}

/* Мягкая плашка «не удалось загрузить» с кнопкой повтора. */
.load-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 22px 16px;
  color: var(--text-secondary);
}
.load-error i { width: 30px; height: 30px; color: var(--text-muted); }
.load-error-t { font-size: 14px; font-weight: 600; }
.load-error .btn-primary { padding: 10px 20px; }


/* controls.css */
/* =====================================================
   Базовые элементы управления: поля форм, сегмент-контрол,
   переключатели (switch).
   ===================================================== */

/* ----------------- Поля форм (новый лейаут) ----------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
}
.field-label {
  font-size: 13px;
  color: var(--text-secondary);
  font-weight: 600;
}
.field-row {
  display: flex;
  gap: 11px;
}
.field-row .field { flex: 1; min-width: 0; }
.form-stack { display: flex; flex-direction: column; gap: 14px; }
.form-stack .btn-primary { width: 100%; margin-top: 4px; }
.field-hint { font-size: 11.5px; color: var(--text-muted); }

/* ----------------- Сегмент-контрол (пол, стиль) ----------------- */
.segmented {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--fill-track);
  border-radius: var(--r-sm);
}
.seg-btn {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 6px;
  border-radius: 9px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}
.seg-btn.active {
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: var(--shadow-card);
}
.seg-btn.accent.active { color: var(--color-primary); }

/* Сегмент-переключатель верхнего уровня (Тело / Тренды). */
.seg-tabs { margin-bottom: var(--spacing-md); }
.pane { animation: viewIn var(--dur) var(--ease); }
.pane.hidden { display: none; }

/* ----------------- Переключатель (switch) ----------------- */
.switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 14.5px;
  color: var(--text-primary);
  padding: 4px 0;
}
.switch {
  position: relative;
  display: inline-flex;
  flex: none;
  width: 50px;
  height: 30px;
  cursor: pointer;
}
.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}
.switch-track {
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  border: 1px solid var(--border);
  transition: background var(--dur) var(--ease);
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(16, 24, 40, 0.3);
  transition: transform var(--dur) var(--ease-spring);
}
.switch input:checked + .switch-track {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.switch input:checked + .switch-track::after { transform: translateX(20px); }

/* Свитч со знаком внутри бегунка — для согласий, где важно видеть не просто
   «что-то включено», а подтверждено оно или нет: зелёная галочка во включённом
   состоянии, красный крестик в выключенном. Оба знака нарисованы на самом
   .switch (у .switch-track псевдоэлементы уже заняты дорожкой и бегунком) и
   едут вместе с бегунком, поэтому координаты отсчитываются от .switch —
   это на 1px больше, чем у бегунка, из-за рамки дорожки. */
.switch-check::before,
.switch-check::after {
  content: "";
  position: absolute;
  z-index: 1;
  pointer-events: none;
  transition: transform var(--dur) var(--ease-spring), opacity var(--dur) var(--ease);
}
/* Крестик: плюс из двух полосок, повёрнутый на 45°. Размеры полосок берём
   ровно по контейнеру: при 11px в блоке 12px центрирование давало по половине
   пикселя с каждой стороны, и на мониторе без ретины крест выходил кривым —
   одна перекладина резкая, вторая размытая и толще. */
.switch-check::before {
  top: 9px;
  left: 9px;
  width: 12px;
  height: 12px;
  background:
    linear-gradient(var(--color-danger), var(--color-danger)) center / 2px 12px no-repeat,
    linear-gradient(var(--color-danger), var(--color-danger)) center / 12px 2px no-repeat;
  transform: rotate(45deg);
}
/* Галочка: две границы повёрнутого прямоугольника. Координаты целые — по той
   же причине, что и у крестика. */
.switch-check::after {
  top: 8px;
  left: 12px;
  width: 6px;
  height: 10px;
  border: solid var(--color-primary);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0.4);
  opacity: 0;
}
.switch-check:has(input:checked)::before {
  transform: translateX(20px) rotate(45deg) scale(0.4);
  opacity: 0;
}
.switch-check:has(input:checked)::after {
  transform: translateX(20px) rotate(45deg) scale(1);
  opacity: 1;
}
/* Состояние читается только через :has(). Там, где его нет, знаки убираем
   совсем: обычный свитч лучше, чем красный крестик поверх включённого. */
@supports not selector(:has(*)) {
  .switch-check::before,
  .switch-check::after { content: none; }
}

/* плавное скрытие блока (беременность/ГВ только для женского пола) */
.collapsible.hidden { display: none; }

/* ----------------- Горизонтальная лента ----------------- */
/* Обвязка для лент, которые шире экрана (ступени лиги, значки наград). Сама
   прокрутка остаётся на элементе; обвязка отвечает на два вопроса, на которые
   голая лента не отвечала: «там есть ещё?» — растушёванный край вместо ровно
   обрезанного значка, и «чем крутить с мыши?» — стрелки у краёв и колесо
   (App.hrail в webapp/static/js/ui.js). Стрелки показываем только там, где
   есть курсор: пальцем лента листается и без них. */
.h-rail-wrap { position: relative; }
.h-rail { --h-rail-fade: 32px; }
.h-rail[data-more="start"] {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--h-rail-fade));
  mask-image: linear-gradient(to right, transparent 0, #000 var(--h-rail-fade));
}
.h-rail[data-more="end"] {
  -webkit-mask-image: linear-gradient(to left, transparent 0, #000 var(--h-rail-fade));
  mask-image: linear-gradient(to left, transparent 0, #000 var(--h-rail-fade));
}
.h-rail[data-more="both"] {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--h-rail-fade),
    #000 calc(100% - var(--h-rail-fade)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--h-rail-fade),
    #000 calc(100% - var(--h-rail-fade)), transparent 100%);
}
.h-rail-arrow {
  position: absolute;
  top: 50%;
  display: none;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-top: -15px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-secondary);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  z-index: 2;
}
.h-rail-arrow svg { width: 16px; height: 16px; }
.h-rail-arrow:hover { border-color: var(--border-strong); color: var(--text-primary); }
.h-rail-prev { left: -4px; }
.h-rail-next { right: -4px; }
@media (hover: hover) and (pointer: fine) {
  .h-rail-arrow:not([hidden]) { display: grid; }
}

/* meal_day.css */
/* =====================================================
   Раздел «Приёмы»: вкладки, полоска недели с кольцами дней,
   карточка выбранного дня (калории, Б/Ж/У, нутриенты) и выбор даты.
   Вид согласован с владельцем на стенде 06.10.2026 («С2»).
   ===================================================== */

/* Тёмный тон жиров для перебора: у главной жиры фиолетовые и свой тон есть
   (--hc-fat-deep), а в дневнике жиры красные. */
:root { --md-fat-deep: #b91c1c; }
body.tg-dark-theme { --md-fat-deep: #dc2626; }

/* ----------------- Вкладки «Приёмы / Рецепты» ----------------- */
/* Текстом с зелёным подчёркиванием; справа переключатель вида дневника. */
.meals-tabs {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 2px 2px 12px;
}
.mt-tab {
  position: relative;
  padding: 6px 0;
  border: none;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.2px;
  cursor: pointer;
}
.mt-tab.active { color: var(--text-primary); }
.mt-tab.active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--color-primary);
}
.mt-tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 4px; }
.mt-sp { flex: 1; }

/* ----------------- Неделя ----------------- */
.day-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-bottom: 12px;
}
.day-nav-arrow {
  flex: none;
  width: 24px;
  height: 36px;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.day-nav-arrow svg { width: 17px; height: 17px; }
.day-nav-arrow:disabled { opacity: 0.3; cursor: default; }
.day-strip {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  min-width: 0;
}
.day-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 2px 0;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  font: inherit;
  cursor: pointer;
}
.day-cell:disabled { opacity: 0.35; cursor: default; }
.day-dow { font-size: 11px; font-weight: 600; color: var(--text-muted); }
.day-cell.is-today .day-dow { color: var(--color-primary); }

/* Число дня в кольце заполненности нормы — форма прежнего кольца (30 px,
   толщина 3,5 px; владелец 07.10). Фон кольца — из JS: заполнение, сверх
   нормы — тёмный «второй круг», пустой день — серая дорожка. */
.day-ring {
  position: relative;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-primary);
}
.day-ring > i {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
}
/* Выбранный день — зелёная черта под кольцом. */
.day-mark { width: 16px; height: 3px; border-radius: 2px; background: transparent; }
.day-cell.active .day-mark { background: var(--color-primary); }

/* ----------------- Карточка дня ----------------- */
.day-summary {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 11px 14px 4px;
}
.ds-dhead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ds-dhead .ds-title { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.ds-dhead .ds-date-btn svg { width: 14px; height: 14px; color: var(--text-muted); }
.ds-count { margin-left: auto; font-size: 12.5px; font-weight: 500; color: var(--text-muted); }
.ds-big { display: flex; align-items: baseline; gap: 5px; margin-top: 2px; }
.ds-big b {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.6px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.ds-big span { font-size: 13px; font-weight: 600; color: var(--text-muted); }

/* Шкала с перебором: заливка и поверх слева тёмный «второй круг». */
.ds-lap { position: relative; overflow: hidden; background: var(--fill-track); }
.ds-lap > i { position: absolute; left: 0; top: 0; bottom: 0; display: block; border-radius: inherit; }
.ds-kbar { height: 5px; margin-top: 7px; border-radius: 3px; }
.ds-mbar { height: 3px; margin-top: 3px; border-radius: 2px; }

/* Б/Ж/У: название и число в одну строку, колонки по ширине текста. */
.ds-m3 {
  display: grid;
  grid-template-columns: auto auto auto;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
}
.ds-mc { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ds-ml {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ds-ml b { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.ds-ml small { margin-left: -2px; font-size: 11px; font-weight: 500; }

/* Раскрытие нутриентов: строка-кнопка и плавное открытие. */
.ds-nmore {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  margin-top: 10px;
  padding: 7px 0 6px;
  border: none;
  border-top: 1px solid var(--border);
  background: none;
  color: var(--text-secondary);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.ds-nmore svg { width: 14px; height: 14px; transition: transform var(--dur) var(--ease); }
.day-summary.open .ds-nmore svg { transform: rotate(180deg); }
.ds-nut { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s var(--ease); }
.day-summary.open .ds-nut { grid-template-rows: 1fr; }
.ds-nut-in { min-height: 0; overflow: hidden; }
.ds-nut-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; padding: 4px 0 12px; }
.ds-nrow { cursor: pointer; }
.ds-nrow .blur { filter: blur(4px); }
.ds-nrow svg { width: 11px; height: 11px; color: var(--text-muted); align-self: center; }

/* ----------------- Бережный режим: кольцо с отметкой и подпись ----------------- */
.day-summary .ds-top { display: flex; align-items: center; gap: 14px; padding: 2px 0 8px; }
.day-summary .ds-ring {
  --pct: 0deg;
  --ring-color: var(--color-primary);
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(var(--ring-color) var(--pct), var(--fill-track) 0);
  display: flex;
  align-items: center;
  justify-content: center;
}
.day-summary .ds-ring > span {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 800;
  color: var(--text-primary);
}
.day-summary .ds-info { flex: 1; min-width: 0; position: relative; }
.day-summary .ds-top .ds-title { font-weight: 700; font-size: 15px; }
.day-summary .ds-sub { font-size: 12.5px; color: var(--text-secondary); margin-top: 3px; }
.day-summary .ds-date-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Кнопка-дата: открывает календарь для выбора любой даты. */
.ds-date-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: var(--text-primary);
  font: inherit;
}
.ds-date-btn svg { width: 15px; height: 15px; color: var(--color-primary); flex: none; }
.ds-date-btn:active { opacity: 0.6; }
.ds-today-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: none;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 14%, var(--surface-2));
  color: var(--color-primary);
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  cursor: pointer;
}
.ds-today-btn svg { width: 13px; height: 13px; }
.ds-today-btn:active { opacity: 0.65; }

/* «Добавить приём пищи» в дневнике — белая строка с зелёным текстом. */
#pane-diary .add-entry-btn {
  margin: 0 0 14px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: 14.5px;
}

/* meal_sheet.css */
/* =====================================================
   Карточка приёма пищи (bottom-sheet): заголовок, макро-плитки,
   состав, нутриенты, фото, действия и редактор даты/времени.
   ===================================================== */

/* ----------------- Bottom-sheet (карточка приёма, iOS-стиль) ----------------- */
.ms-questions { margin: 16px 0; padding: 16px; border: 1px solid var(--color-accent, #c99736); border-radius: 16px; }
.ms-question-help, .ms-question-status { font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
.ms-question + .ms-question { margin-top: 18px; }
.ms-question p { margin: 12px 0; line-height: 1.5; }
.ms-question-options { display: flex; flex-wrap: wrap; gap: 8px; }
.ms-question-options button { min-height: 44px; flex: 1 1 120px; }
.ms-question-options button:disabled { opacity: .55; }
.sheet-overlay {
  position: fixed;
  inset: 0;
  z-index: 2500;
  display: none;
}
.sheet-overlay.show { display: block; }
.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 11, 16, 0.5);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.sheet-overlay.open .sheet-backdrop { opacity: 1; }
.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--shadow-float);
  padding: 10px 18px calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateY(100%);
  transition: transform 0.34s var(--ease-spring);
  will-change: transform;
}
.sheet-overlay.open .sheet { transform: translateY(0); }
.sheet-handle {
  width: 40px;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--border-strong);
  margin: 4px auto 14px;
}

/* Заголовок карточки приёма. */
.ms-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.ms-type {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.4px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
.ms-type svg {
  width: 21px;
  height: 21px;
  color: var(--color-primary);
  flex: none;
}
.ms-time { font-size: 13px; color: var(--text-secondary); margin-top: 4px; }
.ms-kcal-big {
  text-align: right;
  flex: none;
}
.ms-kcal-big b { font-size: 24px; font-weight: 800; color: var(--color-primary); }
.ms-kcal-big span { display: block; font-size: 11px; color: var(--text-muted); }

/* Макро-плитки. */
.ms-macros {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 16px;
}
.ms-macro {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 7px 4px;
}
.ms-macro b { font-size: 15px; font-weight: 800; }
.ms-macro span { font-size: 10px; color: var(--text-muted); }
.ms-macro.p b { color: var(--color-accent); }
.ms-macro.f b { color: var(--color-danger); }
.ms-macro.c b { color: var(--color-primary-2); }

.ms-section-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  margin: 18px 0 10px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.ms-section-title svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
  flex: none;
}

/* Состав. Каждое блюдо — карточка, раскрывается по тапу. */
.ms-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Ингредиенты одного блюда — под общим заголовком, с левым акцентом. */
.ms-dish { display: flex; flex-direction: column; gap: 8px; }
.ms-dish-label {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.2px;
}
.ms-dish-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-left: 11px;
  border-left: 2px solid color-mix(in srgb, var(--color-primary) 30%, transparent);
}
.ms-item {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.ms-item.open {
  background: var(--surface);
  border-color: var(--border-strong);
}
.ms-item-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  background: none;
  border: none;
  text-align: left;
  font-size: 14px;
  cursor: pointer;
  color: inherit;
}
.ms-item-main { min-width: 0; flex: 1; }
.ms-item-name {
  color: var(--text-primary);
  font-weight: 600;
  line-height: 1.3;
}
.ms-item-aside {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.ms-item-kcal {
  color: var(--color-primary);
  font-weight: 800;
  font-size: 15px;
  line-height: 1;
}
.ms-item-kcal span {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  margin-left: 3px;
}
.ms-item-grams {
  color: var(--text-muted);
  font-size: 12px;
}
.ms-item-chev {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--text-muted);
  transition: transform 0.22s ease;
}
.ms-item.open .ms-item-chev { transform: rotate(180deg); }

.ms-item-body {
  display: none;
  padding: 2px 14px 14px;
  border-top: 1px solid var(--border);
  margin-top: -1px;
}
.ms-item.open .ms-item-body {
  display: block;
  animation: ms-item-reveal 0.22s ease;
}
@keyframes ms-item-reveal {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

.ms-item-macros {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  padding-top: 12px;
}
.ii-cell {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 6px 4px;
}
.ii-cell b { font-size: 14px; font-weight: 800; color: var(--text-primary); }
.ii-cell span { font-size: 10px; color: var(--text-muted); }
.ii-cell.p b { color: var(--color-accent); }
.ii-cell.f b { color: var(--color-danger); }
.ii-cell.c b { color: var(--color-primary-2); }

.ms-item-scale,
.ms-meal-scale {
  display: flex;
  gap: 6px;
  padding: 10px 3px;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  margin-top: 10px;
}
/* Переключатель масштаба для всего приёма — отделён от макро-плиток. */
.ms-meal-scale {
  margin-top: -6px;
  margin-bottom: 16px;
}
.ms-scale-btn {
  flex: 1;
  padding: 8px;
  font-size: 12px;
  font-weight: 700;
  border-radius: var(--r-sm);
  border: none;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}
.ms-scale-btn.active {
  background: var(--color-primary);
  color: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

/* Полезность (нутриенты). */
.ms-nutri {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.ms-nutri-row {
  display: flex;
  justify-content: space-between;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 9px 12px;
  font-size: 13px;
  color: var(--text-secondary);
}
.ms-nutri-row b { color: var(--text-primary); font-weight: 700; }

/* Фото в карточке. */
.ms-photos { display: flex; gap: 8px; flex-wrap: wrap; }
.ms-photo {
  width: 76px;
  height: 76px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--border);
  cursor: pointer;
}

/* Действия. Три кнопки в одном ряду ломали подписи на две-три строки и давали
   разную высоту, поэтому равные по смыслу «Повторить» и «В избранное» стоят
   парой одинаковых плиток, а удаление — тихой строкой под ними: оно нужно
   редко и не должно спорить с зелёным «Сохранить» выше. */
.ms-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 22px;
}
/* Карточка рецепта кладёт в этот же блок одну кнопку — ей вся ширина. */
.ms-actions > :only-child { grid-column: 1 / -1; }
.ms-act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease),
    border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ms-act svg { width: 17px; height: 17px; flex: none; color: var(--color-primary); }
.ms-act:active { transform: scale(0.97); }
.ms-act:disabled { opacity: 0.6; cursor: default; }
/* Уже в избранном — залитая звезда и мягкая зелёная плитка: состояние видно
   без чтения подписи. */
.ms-act.on {
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-primary) 32%, transparent);
  color: var(--color-primary);
}
.ms-act.on svg { fill: currentColor; color: currentColor; }
.ms-act .ms-act-ic { display: inline-flex; }
.ms-act.pop .ms-act-ic { animation: ms-act-pop 0.42s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)); }
@keyframes ms-act-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.35) rotate(-9deg); }
  100% { transform: scale(1) rotate(0); }
}

.ms-remove {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  margin-top: 10px;
  padding: 12px;
  border: none;
  border-radius: var(--r-pill);
  background: none;
  color: var(--color-danger);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.ms-remove svg { width: 16px; height: 16px; }
/* В карточке рецепта удаление лежит внутри .ms-actions и отступ уже есть. */
.ms-actions .ms-remove { margin-top: 0; }
.ms-remove:active { background: color-mix(in srgb, var(--color-danger) 10%, transparent); }

.btn-ghost {
  flex: 1;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-primary);
  border-radius: var(--r-pill);
  font-weight: 650;
  font-size: 14px;
  padding: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.btn-ghost svg { width: 17px; height: 17px; }
.btn-ghost:active { transform: scale(0.97); }
.btn-ghost.danger { color: var(--color-danger); border-color: color-mix(in srgb, var(--color-danger) 30%, transparent); }

/* Редактирование времени в карточке. */
.ms-time-edit {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  align-items: center;
}
.ms-time-edit input { flex: 1; }

/* Редактор дня/времени/типа приёма в карточке. */
.ms-edit { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.ms-type-seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.ms-type-btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 10px 4px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease),
    background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ms-type-btn svg { width: 18px; height: 18px; }
.ms-type-btn.active {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, var(--surface));
  color: var(--color-primary);
}
.ms-edit-grid { position: relative; display: flex; gap: 10px; }
.ms-day-btn {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  padding: 11px 13px;
  cursor: pointer;
}
.ms-day-btn svg { width: 16px; height: 16px; color: var(--color-primary); flex: none; }
.ms-day-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Время рядом с датой — такая же кнопка, но уже: «18:30» шире не нужно. */
#ms-time-btn { flex: 0 0 118px; }
.ms-save {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.ms-save svg { width: 17px; height: 17px; }

/* ----------------- Кнопка-ссылка (CTA в пустых блоках) ----------------- */
.link-btn {
  display: inline-block;
  margin-top: 8px;
  border: none;
  background: none;
  color: var(--color-primary);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  padding: 0;
}

/* Правка фактически съеденного веса без нового распознавания. */
.ms-portion-form { display: flex; flex-wrap: wrap; align-items: end; gap: 10px; padding-top: 12px; }
.ms-portion-form label { flex: 1 1 120px; font-size: 13px; color: var(--text-secondary); }
.ms-portion-grams { display: block; width: 100%; height: 44px; box-sizing: border-box; margin-top: 6px; padding: 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--fill-input); color: var(--text-primary); font-size: 16px; }
/* Кнопка ростом с поле, в одну строку: общий .btn-soft растягивался (flex: 1)
   и переносил «Сохранить вес» на две строки — выше поля вдвое (владелец, 05.10). */
.ms-portion-form button { flex: 0 0 auto; height: 44px; min-height: 0; padding: 0 18px; border-radius: 10px; white-space: nowrap; }
.ms-portion-status { flex-basis: 100%; font-size: 13px; color: var(--text-secondary); }

/* nutrients.css */
/* =====================================================
   Нутриенты: расширенная сводка на главной и модалка
   с разбивкой по приёмам.
   ===================================================== */

/* ----------------- Расширенная сводка нутриентов ----------------- */
.nutri-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 9px;
}
.nutri-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 13px 12px 11px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur) var(--ease);
}
.nutri-tile:active { transform: scale(0.98); }
/* Полоска заполненности по верхнему краю плитки. */
.nutri-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--fill-track);
}
.nutri-fill {
  display: block;
  height: 100%;
  background: var(--color-primary);
  transition: width 0.6s var(--ease);
}
/* Перебор лимита — как у колец на карточке «Сегодня»: заливка до лимита,
   засечка и хвост тоном глубже, без сигнального красного. Янтарь — цвет, в
   который лимит и так краснеет на подходе (80 %) на карточке «Сегодня». */
.nutri-fill.over { background: var(--color-accent); }
.nutri-fill.under { background: var(--color-accent); }
.nutri-lap, .nm-lap {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  background: var(--hc-warn-deep, #d97706);
}
.nutri-tick, .nm-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--surface-2);
}
.nutri-val { font-size: 17px; font-weight: 800; color: var(--text-primary); }
.nutri-val i { font-size: 11px; font-weight: 600; color: var(--text-muted); font-style: normal; margin-left: 2px; }
.nutri-label { font-size: 11.5px; color: var(--text-secondary); }

/* Пустое состояние: данных о нутриентах ещё нет. Занимает всю ширину сетки. */
.nutri-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 5px;
  padding: 16px 14px 8px;
}
.nutri-empty-ic {
  width: 46px;
  height: 46px;
  margin-bottom: 5px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--color-primary) 12%, var(--surface-2));
  color: var(--color-primary);
}
.nutri-empty-ic svg { width: 24px; height: 24px; }
.nutri-empty-t { font-size: 14px; font-weight: 700; color: var(--text-primary); }
.nutri-empty-s { font-size: 12.5px; line-height: 1.45; color: var(--text-muted); max-width: 280px; }

/* ----------------- Модалка нутриентов (разбивка по приёмам) ----------------- */
.nm-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.nm-h-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.4px;
}
.nm-h-date { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.nm-close {
  width: 32px;
  height: 32px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-secondary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.nm-close svg { width: 18px; height: 18px; }
.nm-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: 18px;
}
.nm-chip {
  padding: 7px 13px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
.nm-chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.nm-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.nm-total-val {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -1px;
  color: var(--text-primary);
}
.nm-total-val i {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  font-style: normal;
  margin-left: 3px;
}
.nm-total-val.over { color: var(--hc-warn-ink, #b45309); }
.nm-total-val.under { color: var(--color-accent); }
.nm-total-ref { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.nm-track {
  position: relative;
  height: 8px;
  margin-top: 10px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.nm-fill-main {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  transition: width 0.6s var(--ease);
}
/* С хвостом заливка упирается в засечку ровным краем, скругляет полоса. */
.nm-track.over .nm-fill-main { border-radius: 0; background: var(--color-accent); }
.nm-track.under .nm-fill-main { background: var(--color-accent); }
.nm-tick { background: var(--surface); }
.nm-status { margin-top: 8px; font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.nm-status.over { color: var(--hc-warn-ink, #b45309); }
.nm-status.under { color: var(--color-accent); }
.nm-desc { margin-top: 10px; font-size: 12.5px; line-height: 1.5; color: var(--text-secondary); }
.nm-list-title {
  margin: 20px 0 12px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
}
.nm-list { display: flex; flex-direction: column; gap: 13px; }
.nm-row { display: flex; flex-direction: column; gap: 5px; }
.nm-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.nm-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nm-val { flex: none; font-size: 14px; font-weight: 800; color: var(--text-primary); }
.nm-val i { font-size: 11px; font-weight: 600; color: var(--text-muted); font-style: normal; margin-left: 2px; }
.nm-sub { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); }
.nm-sub svg { width: 13px; height: 13px; flex: none; }
.nm-bar { height: 6px; border-radius: var(--r-pill); background: var(--fill-track); overflow: hidden; }
.nm-fill {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  transition: width 0.6s var(--ease);
}
.nm-empty { padding: 18px 4px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* body_stats.css */
/* =====================================================
   Вкладка «Тело»: ключевые показатели, прогноз веса
   и энергобаланс.
   ===================================================== */

/* ----------------- Ключевые показатели (вкладка «Тело») ----------------- */
.stat-row { display: flex; }
.stat-tile {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  text-align: center;
  padding: 0 4px;
}
.stat-tile + .stat-tile { border-left: 1px solid var(--border); }
.stat-val { font-size: 20px; font-weight: 800; letter-spacing: -0.5px; color: var(--text-primary); }
.stat-label { font-size: 11px; color: var(--text-muted); }
.stat-delta {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  letter-spacing: -0.2px;
}
.stat-delta.down { color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 13%, transparent); }
.stat-delta.up { color: var(--color-primary-2); background: color-mix(in srgb, var(--color-primary-2) 15%, transparent); }

/* Кнопки-действия (мягкие). */
.row-btns { display: flex; gap: 10px; margin-top: 12px; }
.btn-soft {
  flex: 1;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-primary);
  border-radius: var(--r-pill);
  font-weight: 650;
  font-size: 14px;
  padding: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  transition: transform var(--dur) var(--ease);
}
.btn-soft svg { width: 17px; height: 17px; color: var(--color-primary); }
.btn-soft:active { transform: scale(0.97); }

/* ----------------- Прогноз веса (похудение/набор) ----------------- */
.fc-card { position: relative; overflow: hidden; }
.fc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.fc-head .card-title { margin-bottom: 0; }
.fc-badge {
  flex: none;
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--r-pill);
}
.fc-badge.cutting {
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
}
.fc-badge.bulking {
  color: var(--color-primary-2);
  background: color-mix(in srgb, var(--color-primary-2) 16%, transparent);
}

/* Hero-строка: крупный темп слева + компактный чип цели справа. */
.fc-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin: 2px 0 12px;
}
.fc-goal-chip { margin-left: auto; }

/* Темп изменения веса — крупная цифра. */
.fc-rate { display: flex; flex-direction: column; gap: 1px; flex: none; }
.fc-rate-val { font-size: 27px; font-weight: 800; letter-spacing: -0.6px; line-height: 1.05; }
.fc-rate-val i { font-size: 13px; font-weight: 700; font-style: normal; margin-left: 3px; }
.fc-rate.down .fc-rate-val { color: var(--color-primary); }
.fc-rate.up .fc-rate-val { color: var(--color-primary-2); }
.fc-rate-sub { font-size: 12.5px; color: var(--text-muted); }

/* Компактный чип цели справа от темпа. */
.fc-goal-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  text-align: right;
  padding: 7px 11px;
  border-radius: var(--r-sm);
  min-width: 0;
}
.fc-goal-chip .gc-main {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
  font-weight: 800;
  white-space: nowrap;
}
.fc-goal-chip .gc-main svg { width: 14px; height: 14px; flex: none; }
.fc-goal-chip .gc-sub { font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.fc-goal-chip.ok {
  background: color-mix(in srgb, var(--color-primary) 9%, transparent);
}
.fc-goal-chip.ok .gc-main { color: var(--color-primary); }
.fc-goal-chip.warn {
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.fc-goal-chip.warn .gc-main { color: var(--color-accent); }
.fc-goal-chip.muted { background: var(--surface-2); }
.fc-goal-chip.muted .gc-main { color: var(--text-secondary); }
.fc-goal-chip.muted .gc-main svg { color: var(--text-muted); }

/* Энергобаланс одной полоской: приход (заливка) против нормы (метка). */
.fc-balance { margin-bottom: 10px; }
.fc-bal-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
.fc-bal-name { font-size: 12.5px; font-weight: 650; color: var(--text-secondary); }
.fc-bal-val { font-size: 16px; font-weight: 800; }
.fc-bal-val i { font-size: 10px; font-weight: 600; color: var(--text-muted); font-style: normal; margin-left: 3px; }
.fc-bal-val.down { color: var(--color-primary); }
.fc-bal-val.up { color: var(--color-primary-2); }
.fc-bal-val.flat { color: var(--text-primary); }
.fc-bal-track {
  position: relative;
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  overflow: hidden;
}
.fc-bal-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: var(--r-pill);
  transition: width var(--dur) var(--ease);
}
.fc-bal-fill.down { background: var(--color-primary); }
.fc-bal-fill.up { background: var(--color-primary-2); }
.fc-bal-fill.flat { background: var(--text-muted); }
/* Метка нормы расхода поверх полосы. */
.fc-bal-mark {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--text-secondary);
}
.fc-bal-cap {
  display: flex;
  justify-content: space-between;
  margin-top: 5px;
  font-size: 11px;
  color: var(--text-muted);
}
.fc-bal-cap b { font-weight: 700; color: var(--text-secondary); }

.fc-chart { width: 100%; height: 128px; display: block; touch-action: none; }

/* Подсказка про интерактивность графика. */
.fc-scrub {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-muted);
}
.fc-scrub svg { width: 13px; height: 13px; flex: none; opacity: 0.8; }

/* Раскрывающаяся справка «как считается». */
.fc-info { margin-top: 4px; }
.fc-info summary {
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text-secondary);
  padding: 6px 0;
  user-select: none;
}
.fc-info summary::-webkit-details-marker { display: none; }
.fc-info summary svg { width: 15px; height: 15px; flex: none; color: var(--color-primary); }
.fc-info summary::after {
  content: "";
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.fc-info[open] summary::after { transform: rotate(-135deg); }
.fc-info p {
  margin: 2px 0 2px;
  font-size: 11.5px;
  color: var(--text-muted);
  line-height: 1.45;
}

/* Заблокированное состояние: размытый пример + оверлей с инструкцией. */
.fc-blur {
  filter: blur(7px);
  opacity: 0.6;
  pointer-events: none;
  user-select: none;
}
.fc-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.fc-overlay-card {
  text-align: center;
  max-width: 320px;
}
.fc-overlay-icon {
  width: 46px;
  height: 46px;
  margin: 0 auto 12px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
  color: var(--color-primary);
}
.fc-overlay-icon i { width: 24px; height: 24px; }
.fc-overlay-title { font-size: 16px; font-weight: 800; margin-bottom: 6px; }
.fc-overlay-text { font-size: 13px; color: var(--text-secondary); line-height: 1.4; }
.fc-missing {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: inline-flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
}
.fc-missing li {
  position: relative;
  padding-left: 22px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.fc-missing li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 7px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-primary);
}

/* forecast_path.css */
/* Путь к целевому весу в карточке «Прогноз веса»: тропа, лента дней, график
   (webapp/static/js/forecast_path.js). Виден один вид, остальные спрятаны. */
.fp { position: relative; }
.fp-pane { display: none; }
.fp[data-view="trail"] .fp-pane[data-pane="trail"],
.fp[data-view="days"] .fp-pane[data-pane="days"],
.fp[data-view="chart"] .fp-pane[data-pane="chart"] { display: block; }
.fp[data-view="trail"] .fp-stage,
.fp[data-view="days"] .fp-stage { cursor: pointer; }
.fp-pane[data-pane="trail"],
.fp-pane[data-pane="days"] { animation: fp-in 0.28s var(--ease); }
@keyframes fp-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Нижняя строка: подсказка и переключатель видов. */
.fp-bar { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.fp-hint { font-size: 11px; color: var(--text-muted); }
.fp-switch {
  display: inline-flex; gap: 2px; margin-left: auto; padding: 3px;
  border-radius: var(--r-pill); background: var(--surface-2);
}
.fp-sw {
  width: 34px; height: 28px; border: 0; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-muted); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.fp-sw svg { width: 16px; height: 16px; }
.fp-sw[aria-pressed="true"] { background: var(--surface); color: var(--color-primary); box-shadow: var(--shadow-card); }

/* ----------------------------------------------------------- тропа ---- */
.fp-trail { width: 100%; height: auto; display: block; overflow: visible; }
.fp-g0 { stop-color: color-mix(in srgb, var(--color-primary) 80%, #000); }
.fp-g1 { stop-color: color-mix(in srgb, var(--color-primary) 70%, #fff); }
.fp-road { fill: none; stroke: var(--fill-track); stroke-width: 14; stroke-linecap: round; }
.fp-road-dots { fill: none; stroke: var(--border-strong); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 1 7; }
.fp-road-done { fill: none; stroke: url(#fp-trail-grad); stroke-width: 14; stroke-linecap: round; }
.fp-m { fill: var(--border-strong); transform-box: fill-box; transform-origin: center; }
.fp-m.on { fill: #fff; }
.fp-m.pop { animation: fp-pop 0.35s var(--ease-spring); }
@keyframes fp-pop { 50% { transform: scale(2.1); } }
.fp-flag { transform-box: fill-box; transform-origin: 50% 100%; transform: scale(0); }
.fp-flag.show { transform: scale(1); transition: transform 0.5s cubic-bezier(0.34, 1.7, 0.64, 1); }
.fp-flag line { stroke: var(--text-primary); stroke-width: 2.4; stroke-linecap: round; }
.fp-cloth { fill: var(--color-primary); transform-box: fill-box; transform-origin: 0 50%; animation: fp-wave 2.4s ease-in-out infinite; }
@keyframes fp-wave { 50% { transform: skewY(-6deg) scaleX(0.92); } }
.fp-mk-o { fill: var(--surface); stroke: color-mix(in srgb, var(--color-primary) 80%, #000); stroke-width: 3; }
.fp-mk-i { fill: color-mix(in srgb, var(--color-primary) 80%, #000); }
.fp-halo { fill: var(--color-primary); opacity: 0; transform-box: fill-box; transform-origin: center; }
.fp-halo.on { animation: fp-halo 1.8s ease-out infinite; }
@keyframes fp-halo { 0% { opacity: 0.45; transform: scale(1); } 100% { opacity: 0; transform: scale(2.6); } }
.fp-lbl { font-size: 11px; font-weight: 600; fill: var(--text-muted); }
.fp-lbl-b { font-size: 12px; font-weight: 800; fill: var(--text-primary); }
.fp-plus { opacity: 0; }
.fp-plus rect { fill: color-mix(in srgb, var(--color-primary) 80%, #000); }
.fp-plus text { font-size: 11px; font-weight: 700; fill: #fff; }
.fp-plus.go { animation: fp-rise 1.8s ease-out forwards; }
@keyframes fp-rise {
  0% { opacity: 0; transform: translateY(4px); }
  15% { opacity: 1; transform: translateY(-4px); }
  75% { opacity: 1; transform: translateY(-10px); }
  100% { opacity: 0; transform: translateY(-18px); }
}
.fp-split { display: flex; justify-content: space-between; gap: 10px; margin-top: 2px; }
.fp-split > div { display: flex; flex-direction: column; gap: 1px; }
.fp-split > div:last-child { text-align: right; }
.fp-k { font-size: 11px; font-weight: 650; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; }
.fp-n { font-size: 17px; font-weight: 800; letter-spacing: -0.3px; font-variant-numeric: tabular-nums; }
.fp-n-g { color: var(--color-primary); }
.fp-s { font-size: 12px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------- лента дней ---- */
.fp-pane[data-pane="days"] { position: relative; }
.fp-days-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; margin: 2px 0 10px; }
.fp-big { font-size: 13px; font-weight: 700; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.fp-big b { font-size: 32px; font-weight: 800; letter-spacing: -1px; line-height: 1; color: var(--text-primary); margin-right: 4px; }
.fp-ahead { text-align: right; font-size: 12.5px; color: var(--text-secondary); line-height: 1.35; }
.fp-ahead b { font-size: 15px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.fp-cal { position: relative; padding-top: 16px; }
.fp-months { position: absolute; top: 0; left: 0; right: 0; height: 14px; font-size: 10.5px; font-weight: 600; color: var(--text-muted); }
.fp-months span { position: absolute; top: 0; white-space: nowrap; }
.fp-cells {
  display: grid; grid-auto-flow: column;
  grid-template-rows: repeat(var(--fp-rows, 7), var(--fp-cell, 13px));
  grid-auto-columns: var(--fp-cell, 13px); gap: var(--fp-gap, 3px);
}
.fp-c {
  border-radius: 28%; background: var(--fill-track); position: relative;
  transition: background 0.25s ease, transform 0.35s cubic-bezier(0.34, 1.8, 0.64, 1), box-shadow 0.3s;
}
.fp-c.x { background: transparent; }
.fp-c.on { background: var(--color-primary); }
.fp-c.pop { transform: scale(1.35); }
.fp-c.glow { box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent); }
.fp-c.wave { background: var(--border-strong); }
.fp-c.today { background: var(--surface); box-shadow: inset 0 0 0 2.5px var(--color-primary); }
.fp-c.today::after {
  content: ""; position: absolute; inset: -4px; border-radius: 6px;
  border: 2px solid var(--color-primary); opacity: 0;
}
.fp-c.today.beat::after { animation: fp-beat 1.6s ease-out infinite; }
@keyframes fp-beat { 0% { opacity: 0.8; transform: scale(0.7); } 100% { opacity: 0; transform: scale(1.5); } }
.fp-c.goal {
  background: var(--text-primary); display: flex; align-items: center; justify-content: center;
  transform: scale(0);
}
.fp-c.goal.show { transform: scale(1); }
.fp-c.goal svg { width: 70%; height: 70%; fill: var(--surface); }
.fp-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 10px; font-size: 11px; color: var(--text-muted); }
.fp-legend span { display: inline-flex; align-items: center; gap: 5px; }
.fp-legend [hidden] { display: none; }
.fp-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.fp-li-on { background: var(--color-primary); }
.fp-li-today { background: var(--surface); box-shadow: inset 0 0 0 2px var(--color-primary); }
.fp-li-off { background: var(--fill-track); }
/* Плашка «+3 дня к цели» встаёт над клетками будущих дней, не над числами. */
.fp-toast {
  position: absolute; right: 0; top: 22px; z-index: 1;
  padding: 5px 10px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 80%, #000); color: #fff;
  font-size: 12px; font-weight: 700; white-space: nowrap;
  opacity: 0; transform: translateY(-6px) scale(0.9); pointer-events: none;
  transition: opacity 0.3s, transform 0.4s cubic-bezier(0.34, 1.7, 0.64, 1);
}
.fp-toast.show { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .fp *, .fp *::before, .fp *::after { animation: none !important; transition: none !important; }
}

/* progress_page.css */
/* =====================================================
   Раздел «Прогресс»: карточка веса, строка прогноза, полка игры одной
   строкой и список редкого (body.js, streak.js). Строки списка и прогноза —
   те же .pf-row, что в «Профиле» (profile.css).
   ===================================================== */

/* ----------------- Карточка веса ----------------- */
.wc { display: flex; flex-direction: column; gap: 10px; }
.wc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wc-head .card-title { margin-bottom: 0; }
.wc-date { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }
.wc-big {
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -1.5px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.wc-big small { font-size: 17px; font-weight: 700; letter-spacing: 0; margin-left: 4px; color: var(--text-secondary); }
.wc-delta { font-size: 14px; font-weight: 650; color: var(--color-primary); margin-top: -2px; }
.wc-goal { display: flex; flex-direction: column; gap: 5px; }
.wc-bar { height: 10px; border-radius: var(--r-pill); background: var(--fill-track); overflow: hidden; }
.wc-bar i {
  display: block;
  height: 100%;
  min-width: 10px;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  transition: width 0.6s var(--ease);
}
.wc-bar-cap {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.wc-bar-cap b { font-weight: 650; color: var(--text-secondary); }
.wc-nudge {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
  color: var(--text-primary);
  font-size: 13px;
  line-height: 1.4;
}
.wc-nudge svg { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--color-accent); }
.wc-empty { margin: 0; font-size: 13.5px; color: var(--text-secondary); line-height: 1.4; }

/* Степпер: −  94,0 кг  +  [Записать]. */
.wc-entry { display: flex; align-items: center; gap: 8px; border-radius: var(--r-md); }
.wc-step {
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text-primary);
  font-size: 21px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  transition: transform var(--dur) var(--ease);
}
.wc-step:active { transform: scale(0.92); }
.wc-val, .wc-input {
  flex: 1;
  min-width: 0;
  height: 42px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: 22px;
  font-weight: 800;
  text-align: center;
  font-variant-numeric: tabular-nums;
  cursor: text;
}
.wc-val small { font-size: 13px; font-weight: 600; color: var(--text-muted); margin-left: 3px; }
.wc-input {
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  font-size: 20px;
}
.wc-save { flex: none; padding: 11px 18px; }
/* Подсветка степпера по переходу из шага дня «Встань на весы». */
.wc-flash { animation: wc-flash 1.4s var(--ease); }
@keyframes wc-flash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  25% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-primary) 35%, transparent); }
}
.wc-chart { width: 100%; display: block; margin-top: 2px; }

/* Подписи строк переносятся, а не обрезаются многоточием: «калории, БЖУ и
   вес за любой пер…» читается хуже двух строк. */
#progress-more .pf-row-sub, .wc-fc .pf-row-sub {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.35;
}

/* Метка Premium в строке вместо стрелки. */
.wc-prem {
  flex: none;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  color: var(--color-accent);
}

/* ----------------- Полка игры одной строкой ----------------- */
#progress-hub { margin-bottom: var(--spacing-md); }
#progress-hub:empty { display: none; }
.pg-skeleton { height: 92px; }
.pg-game {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr));
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: center;
  transition: transform var(--dur) var(--ease);
}
.pg-game:active { transform: scale(0.985); }
.pg-cell {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 12px 6px;
}
.pg-cell + .pg-cell { border-left: 1px solid var(--border); }
.pg-cell b {
  max-width: 100%;
  font-size: 15px;
  font-weight: 800;
  color: var(--text-primary);
  overflow-wrap: anywhere;
  line-height: 1.15;
}
.pg-cell > span:last-child { font-size: 11.5px; color: var(--text-muted); line-height: 1.25; }
.pg-ic {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pg-ic svg { width: 18px; height: 18px; }
.pg-ic img { width: 32px; height: 32px; object-fit: contain; }
.pg-fire { background: color-mix(in srgb, #f97316 15%, transparent); color: #f97316; }
.pg-fire.dim { background: var(--surface-2); color: var(--text-muted); }
.pg-award { background: color-mix(in srgb, #6366f1 15%, transparent); color: #6366f1; }

/* Кнопки подэкрана «Замеры и состав тела». */
.ms-btns { margin: 0 0 var(--spacing-md); }

/* trends.css */
/* =====================================================
   Вкладка «Тренды»: мини-карточки динамики, панель периода
   и большой график в подразделе.
   ===================================================== */

/* ----------------- Мини-тренды («Динамика») ----------------- */
.trend-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px;
}
/* Одинокая карточка не должна растягиваться на половину — занимает всю ширину. */
.trend-grid .trend-card:only-child { grid-column: 1 / -1; }
.trend-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  padding: 11px 12px 6px;
}
.trend-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.trend-card-head span { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.trend-delta {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}
.trend-card-val {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-top: 2px;
  color: var(--text-primary);
}
.trend-card-val i {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  font-style: normal;
  margin-left: 2px;
}
.trend-spark { width: 100%; height: 46px; display: block; margin-top: 8px; }

/* ----------------- Тренды: панель, чипы-отделы, сетка карточек ----------------- */
.trends-bar { margin-bottom: 10px; }

/* Период: сегмент-кнопки + иконка календаря для кастомного диапазона. */
.period-row { display: flex; gap: 8px; align-items: stretch; }
.period-row .segmented { flex: 1; min-width: 0; }
.cal-btn {
  flex: 0 0 auto;
  width: 46px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-sm);
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
.cal-btn svg { width: 19px; height: 19px; }
.cal-btn.active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.cal-btn:active { transform: scale(0.95); }

/* Пилюля с выбранным диапазоном дат. */
.range-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  border: 1px solid color-mix(in srgb, var(--color-primary) 32%, transparent);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 600;
  padding: 7px 12px;
  border-radius: var(--r-pill);
  cursor: pointer;
}
.range-pill svg { width: 15px; height: 15px; color: var(--color-primary); }
.range-pill .range-x { color: var(--text-muted); }

/* Пикер кастомного диапазона (подраздел). */
.range-picker { display: flex; flex-direction: column; gap: 14px; }
.rp-presets { display: flex; gap: 8px; }
.rp-presets .chip { flex: 1; text-align: center; }
.range-picker .field { font-weight: 600; }

.chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin-bottom: 14px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 15px;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.chip:active { transform: scale(0.96); }

.tcards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px;
}
.tcard {
  display: flex;
  flex-direction: column;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 12px 12px 6px;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tcard:active { transform: scale(0.98); }
.tcard.empty { opacity: 0.55; cursor: default; box-shadow: none; }
.tcard-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.tcard-name { font-size: 12.5px; color: var(--text-secondary); font-weight: 600; }
.tcard-delta {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}
.tcard-val {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-top: 3px;
  color: var(--text-primary);
}
.tcard-val i {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  font-style: normal;
  margin-left: 2px;
}
.tcard-spark { width: 100%; height: 44px; display: block; margin-top: 8px; }
.tcard-nodata { font-size: 11px; color: var(--text-muted); margin: 8px 0 6px; }

/* ----------------- Тренды: большой график (подраздел) ----------------- */
.tdetail { display: flex; flex-direction: column; gap: 14px; }
.tdetail-card { margin-bottom: 0; padding: 12px 6px 6px; }
.tdetail-chart {
  width: 100%;
  height: 240px;
  display: block;
  touch-action: none;
}
.tstat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.tstat {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 11px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.tstat-val {
  font-size: 17px;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -0.3px;
}
.tstat-label { font-size: 11px; color: var(--text-muted); }
.tdetail-hint { font-size: 12px; color: var(--text-muted); text-align: center; }

/* activity.css */
/* =====================================================
   Раздел «Активность»: расход за период, карточки упражнений,
   история тренировок и подробности по тапу.
   Общие примитивы (.tcard, .tstat, .chip) берём из trends.css —
   раздел должен выглядеть частью того же приложения, а не отдельной вкладкой.
   ===================================================== */

#view-activity.is-loading { opacity: 0.6; transition: opacity var(--dur) var(--ease); }

.act-periods { margin-bottom: 10px; }
#act-tabs { margin-bottom: 14px; }

/* ----------------- Главное число периода ----------------- */
.act-hero { display: flex; flex-direction: column; gap: 12px; }
.act-hero-top { display: flex; flex-direction: column; gap: 2px; }
.act-hero-num {
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -1.2px;
  color: var(--text-primary);
  line-height: 1.05;
}
.act-hero-unit {
  font-size: 14px;
  font-weight: 650;
  color: var(--text-muted);
  margin-left: 6px;
  letter-spacing: 0;
}
.act-hero-cap { font-size: 12.5px; color: var(--text-secondary); font-weight: 600; }
.act-hero-today {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-secondary);
  border-top: 1px solid var(--border);
  padding-top: 11px;
}
.act-hero-today b { color: var(--text-primary); }
.act-hero-today svg { width: 17px; height: 17px; color: var(--color-accent); }
.act-hero-note {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--text-muted);
}
.act-hero-note svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 1px; }

.act-tiles { margin-bottom: 14px; }
.act-chart-card { padding-bottom: 10px; }
.act-chart {
  width: 100%;
  height: 190px;
  display: block;
  /* Вертикальную прокрутку страницы оставляем системе, горизонтальное ведение
     забираем себе — им человек листает подсказку по столбикам. */
  touch-action: pan-y;
}
.act-chart-legend {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
  font-size: 10.5px;
  color: var(--text-muted);
}
.act-chart-legend i {
  flex: 0 0 auto;
  width: 14px;
  height: 0;
  border-top: 1.5px dashed var(--color-accent);
}
.act-chart-legend b { margin-left: auto; font-weight: 600; opacity: 0.7; }

/* ----------------- Заголовок блока со ссылкой ----------------- */
.act-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 18px 2px 9px;
}
.act-block-head span {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
  letter-spacing: -0.2px;
}
.act-link {
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  padding: 0;
}

/* ----------------- Строка тренировки ----------------- */
.act-list { display: flex; flex-direction: column; gap: 9px; }
.act-row {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 12px 13px;
  cursor: pointer;
  transition: transform var(--dur) var(--ease);
}
.act-row:active { transform: scale(0.985); }
.act-row-icon {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(34, 197, 94, 0.12);
  color: var(--color-primary);
}
.act-row-icon svg { width: 18px; height: 18px; }
.act-row-main { flex: 1; min-width: 0; }
.act-row-title {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.act-row-meta { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.act-row-kcal {
  flex: 0 0 auto;
  font-size: 15px;
  font-weight: 800;
  color: var(--text-primary);
  text-align: right;
}
.act-row-kcal span {
  display: block;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
}
.act-row-chev { width: 16px; height: 16px; color: var(--text-muted); flex: 0 0 auto; }

/* ----------------- Карточка упражнения ----------------- */
.act-ex-cards { margin-bottom: 4px; }
.act-ex .tcard-name { display: inline-flex; align-items: center; gap: 5px; }
.act-ex-icon { width: 13px; height: 13px; color: var(--color-primary); }
/* Подпись метрики под числом. Без неё «60 кг» у жима не отличить от тоннажа,
   а «7.35 км» — от суммы за месяц. */
.act-ex-metric {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-top: 1px;
}
.act-ex-sub { font-size: 10.5px; color: var(--text-muted); margin-top: 3px; }
.act-ex-when { font-size: 10px; color: var(--text-muted); margin-top: 2px; }
/* Без спарклайна карточка заканчивается текстом, и нижний отступ под график
   выглядит обрезанным. */
.act-ex.no-spark { padding-bottom: 12px; }
/* Рост и падение подсвечиваем нейтрально по смыслу «больше/меньше»: в силовых
   рост объёма — прогресс, но у разгрузочной недели снижение это план, а не провал. */
.tcard-delta.is-up { color: var(--color-primary); }
.tcard-delta.is-down { color: var(--text-muted); }

/* ----------------- Пустой раздел ----------------- */
.act-empty { text-align: center; padding: 26px 18px; }
.act-empty-icon {
  width: 54px;
  height: 54px;
  margin: 0 auto 14px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(34, 197, 94, 0.12);
  color: var(--color-primary);
}
.act-empty-icon svg { width: 26px; height: 26px; }
.act-empty-title {
  font-size: 17px;
  font-weight: 800;
  color: var(--text-primary);
  margin-bottom: 7px;
}
.act-empty-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
  margin-bottom: 16px;
}
.act-empty-text i { color: var(--text-primary); font-style: normal; font-weight: 600; }

/* ----------------- Подробности (подраздел) ----------------- */
/* Дата — кнопка: тап открывает нативный календарь и переносит запись на
   выбранный день. Скрытый <input type="date"> лежит рядом и позиционируется
   от этой обёртки, иначе на iOS календарь всплывает не у кнопки. */
.act-wo-head { position: relative; }
.act-wo-date {
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur) var(--ease);
}
.act-wo-date:active { transform: scale(0.97); }
.act-wo-date .tstat-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--color-primary);
}
.act-wo-date .tstat-label svg { width: 11px; height: 11px; }

.act-sess-card { padding: 4px 0; margin-bottom: 0; }
.act-sess {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}
.act-sess:last-child { border-bottom: none; }
.act-sess-date {
  flex: 0 0 68px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text-secondary);
}
/* Время — второй строкой под датой: в один день тренировок может быть две, и
   различает их только оно. */
.act-sess-date span {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
}
.act-sess-body { flex: 1; font-size: 13px; color: var(--text-primary); }
.act-sess-kcal { flex: 0 0 auto; font-size: 11.5px; color: var(--text-muted); }

.act-ex-list { padding: 4px 0; margin-bottom: 0; }
.act-exrow {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.act-exrow:last-child { border-bottom: none; }
.act-exrow-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.act-exrow-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
}
.act-exrow-name svg { width: 14px; height: 14px; color: var(--color-primary); }
.act-exrow-kcal { font-size: 12.5px; font-weight: 700; color: var(--text-secondary); }
.act-exrow-meta { font-size: 12px; color: var(--text-secondary); margin-top: 3px; }
.act-exrow-note { font-size: 11px; color: var(--text-muted); margin-top: 3px; line-height: 1.35; }

.act-comment {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
  margin-bottom: 0;
}
.act-comment svg { width: 16px; height: 16px; color: var(--color-primary); flex: 0 0 auto; margin-top: 1px; }

.act-hint {
  display: flex;
  gap: 7px;
  align-items: flex-start;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-muted);
  padding: 0 2px;
}
.act-hint svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 1px; }

/* ----------------- Действия с тренировкой ----------------- */
/* Те же плитки и тихая строка удаления, что у приёма в дневнике
   (meal_sheet.css: .ms-actions, .ms-act, .ms-remove). Подпись «Разобрать с
   ассистентом» длиннее плитки на узком телефоне: переносим на вторую строку,
   а не обрезаем, высоту ряда выравнивает сетка. */
.act-wo-actions .ms-act {
  white-space: normal;
  text-align: center;
  line-height: 1.25;
}
.act-wo-actions .ms-act .ms-act-ic { flex: none; }
.act-wo-remove:disabled,
.act-wo-actions .ms-act:disabled { opacity: 0.55; cursor: default; }

/* ----------------- Объявление о переезде «Рецептов» ----------------- */
.moved-notice {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent);
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface));
}
.moved-notice-icon { color: var(--color-primary); flex: 0 0 auto; margin-top: 1px; }
.moved-notice-icon svg { width: 20px; height: 20px; }
.moved-notice-body { flex: 1; min-width: 0; }
.moved-notice-title {
  font-size: 14.5px;
  font-weight: 750;
  color: var(--text-primary);
  margin-bottom: 4px;
}
.moved-notice-text { font-size: 12.5px; line-height: 1.45; color: var(--text-secondary); }
.moved-notice-actions { display: flex; gap: 8px; margin-top: 11px; }
.moved-notice-actions .chip.primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* -------- Шаги из телефона (steps_card.js, docs/MOBILE_APP.md, макет S2) -------- */
.steps-card { margin-bottom: 14px; }
.steps-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.steps-title { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 15px; }
.steps-title svg { width: 18px; height: 18px; color: var(--color-primary); }
.steps-source {
  font-size: 11px; font-weight: 700; color: var(--color-primary);
  background: rgba(34, 197, 94, 0.12);
  border-radius: var(--r-pill); padding: 3px 8px;
}
.steps-num { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; }
.steps-num b { font-size: 34px; font-weight: 800; letter-spacing: -0.02em; }
.steps-num span { font-size: 14px; color: var(--text-muted); }
.steps-bar { height: 10px; background: var(--fill-track); border-radius: var(--r-pill); overflow: hidden; margin: 10px 0 8px; }
.steps-bar i { display: block; height: 100%; background: var(--color-primary); border-radius: var(--r-pill); }
.steps-meta { font-size: 13px; color: var(--text-muted); }
.steps-week { display: flex; justify-content: space-between; align-items: flex-end; height: 86px; margin-top: 8px; }
.steps-day { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 34px; font-size: 11px; color: var(--text-muted); }
.steps-day b { display: block; width: 22px; border-radius: 7px; background: rgba(34, 197, 94, 0.28); }
.steps-day.is-goal b { background: rgba(34, 197, 94, 0.6); }
.steps-day.is-today b { background: var(--color-primary); }
.steps-note { display: flex; align-items: flex-start; gap: 7px; margin-top: 10px; font-size: 11.5px; line-height: 1.35; color: var(--text-muted); }
.steps-note svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 1px; }
.steps-manual {
  margin-top: 8px; padding: 6px 0; border: 0; background: none;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--text-secondary);
}
.steps-hint { margin: 8px 0 12px; font-size: 14px; color: var(--text-secondary); line-height: 1.4; }
.steps-card.is-empty .steps-connect { width: 100%; }
.steps-form { display: flex; gap: 8px; margin-top: 10px; }
.steps-form input {
  flex: 1; min-width: 0; height: 44px; padding: 0 12px; font: inherit; font-size: 16px;
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--fill-input); color: var(--text-primary);
}
.steps-form .btn-primary { height: 44px; padding: 0 16px; }

/* «ⓘ» у источника шагов: список программ и подсказка, раскрывается в карточке. */
.steps-source-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.steps-source-btn svg { width: 13px; height: 13px; }
.steps-why {
  margin: 8px 0 4px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--surface-2, rgba(0, 0, 0, 0.04));
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
  /* Название программы бывает пакетом без пробелов: переносить, а не вылезать. */
  overflow-wrap: anywhere;
}
.steps-why p { margin: 0; }
.steps-why p + p, .steps-why ul + p { margin-top: 6px; }
.steps-why ul { margin: 4px 0 0; padding-left: 16px; }
.steps-why b { color: var(--text-primary); font-weight: 600; }
.steps-why-head { font-weight: 600; color: var(--text-primary); }

/* date_sheet.css */
/* =====================================================
   Выбор даты и времени (шторка). Оболочка (.sheet-overlay/.sheet)
   переиспользуется из meal_sheet.css — здесь только внутренности календаря.
   ===================================================== */
.dp-sheet { max-width: 420px; margin: 0 auto; }
.dp-title {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.3px;
  text-align: center;
  margin-bottom: 10px;
}
.dp-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.dp-month {
  font-size: 15px;
  font-weight: 700;
  text-transform: capitalize;
}
.dp-arrow {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.dp-arrow:active { transform: scale(0.92); }
.dp-arrow svg { width: 18px; height: 18px; }

.dp-week,
.dp-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.dp-week {
  margin-bottom: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-align: center;
}
/* Клетки квадратные и не мельче 40px: календарь открывается пальцем, и на
   узких экранах промах по соседнему дню обиднее лишней высоты шторки. */
.dp-day {
  aspect-ratio: 1;
  min-height: 40px;
  border: none;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.dp-day:active { transform: scale(0.92); }
.dp-day.empty { background: none; pointer-events: none; }
.dp-day:disabled { color: var(--text-muted); opacity: 0.4; cursor: default; }
.dp-day.today { box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.dp-day.active {
  background: var(--color-primary);
  color: #fff;
  box-shadow: none;
}

.dp-time {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 14px;
}
.dp-time svg { width: 17px; height: 17px; color: var(--text-muted); }
.dp-colon { font-weight: 800; color: var(--text-muted); }
.dp-select {
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-primary);
}

.dp-actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
}
.dp-actions button { flex: 1; }
.dp-cancel {
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  padding: 12px 22px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  cursor: pointer;
  transition: transform var(--dur) var(--ease);
}
.dp-cancel:active { transform: scale(0.97); }

/* subview.css */
/* =====================================================
   Полноэкранные подразделы и шторки: блокировка фонового
   скролла, «Факты обо мне».

   Карточка пользователя, ряды настроек и формы профиля живут
   в profile.css и profile_edit.css.
   ===================================================== */

/* ----------------- Полноэкранный подраздел ----------------- */
.subview {
  position: fixed;
  inset: 0;
  z-index: 2400;
  background: var(--bg-app);
  display: none;
  flex-direction: column;
  overflow-y: auto;
  padding: calc(12px + env(safe-area-inset-top, 0px)) var(--spacing-md)
    calc(32px + env(safe-area-inset-bottom, 0px));
}
.subview.show { display: flex; animation: viewIn var(--dur) var(--ease); }
/* Пока подраздел открыт — гасим фоновый скролл и зарезервированный gutter
   у <html>, иначе справа видны сразу две полосы прокрутки. */
html:has(.subview.show) { overflow: hidden; scrollbar-gutter: auto; }
html:has(.subview.show) body { overflow: hidden; }
/* Пока открыта шторка (приём пищи / рецепт) — фоновую страницу не скроллим,
   прокручивается только содержимое самой шторки. Gutter держим stable, иначе
   при открытии/закрытии шторки контент «прыгает» по ширине на ширину скролла. */
html:has(.sheet-overlay.show) { overflow: hidden; scrollbar-gutter: stable; }
html:has(.sheet-overlay.show) body { overflow: hidden; }
.subview-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
}
.subview-back {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 0;
}
.subview-back svg { width: 20px; height: 20px; }
.subview-title { font-size: 18px; font-weight: 800; letter-spacing: -0.4px; }
.subview-close {
  margin-left: auto;
  flex: none;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.subview-close svg { width: 19px; height: 19px; }
.subview-close:active { filter: brightness(0.95); }
.subview-body { display: flex; flex-direction: column; gap: 14px; }
.subview-body .btn-primary { width: 100%; margin-top: 6px; }
.subview-body .form-grid { gap: 12px; }

/* ----------------- Факты обо мне ----------------- */
.facts-usage {
  display: flex; flex-direction: column; gap: 9px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 13px 15px; box-shadow: var(--shadow-card);
}
.facts-usage-top { display: flex; align-items: baseline; justify-content: space-between; }
.facts-usage-label { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.facts-usage-val {
  font-size: 13px; font-weight: 800; color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.facts-usage-track {
  height: 6px; border-radius: 999px; background: var(--fill-track); overflow: hidden;
}
.facts-usage-fill {
  height: 100%; border-radius: 999px; background: var(--color-primary);
  transition: width var(--dur) var(--ease);
}
.facts-usage-fill.warn { background: var(--color-accent); }
.facts-usage-fill.full { background: var(--color-danger); }

.fact-limit-note {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 13px; line-height: 1.4; color: var(--text-secondary);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-accent) 28%, transparent);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.fact-limit-note i { width: 18px; height: 18px; color: var(--color-accent); flex: none; margin-top: 1px; }

.fact-add { display: flex; flex-direction: column; gap: 12px; padding: 14px; }
.fact-add textarea, .fact-edit-text {
  width: 100%; resize: none; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--fill-input); color: var(--text-primary);
  padding: 11px 13px; font: inherit; font-size: 14px; line-height: 1.4;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.fact-add textarea::placeholder, .fact-edit-text::placeholder { color: var(--text-muted); }
.fact-add textarea:focus, .fact-edit-text:focus {
  outline: none; border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.fact-add-row { display: flex; align-items: center; gap: 10px; }
.fact-cat-select {
  flex: 1; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--fill-input); color: var(--text-primary);
  padding: 9px 12px; font: inherit; font-size: 13px; cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}
.fact-cat-select:focus { outline: none; border-color: var(--color-primary); }
.fact-counter {
  font-size: 12px; color: var(--text-muted); flex: none;
  font-variant-numeric: tabular-nums;
}

.facts-empty {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-align: center; padding: 30px 18px; color: var(--text-muted);
}
.facts-empty i { width: 30px; height: 30px; opacity: 0.65; margin-bottom: 3px; }
.facts-empty span { font-size: 14px; font-weight: 600; color: var(--text-secondary); }
.facts-empty small { font-size: 12px; line-height: 1.4; max-width: 250px; }

.facts-list { display: flex; flex-direction: column; gap: 8px; }
.fact-item {
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 12px 14px;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.fact-item:hover { border-color: var(--border-strong); box-shadow: var(--shadow-card); }
.fact-item.editing {
  flex-direction: column; gap: 12px;
  border-color: color-mix(in srgb, var(--color-primary) 40%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 12%, transparent);
}
.fact-main { flex: 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.fact-text {
  font-size: 14px; color: var(--text-primary); line-height: 1.4;
  overflow-wrap: anywhere;
}
.fact-chip {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  font-size: 11px; font-weight: 700; letter-spacing: 0.01em;
  border-radius: 999px; padding: 3px 9px 3px 7px;
  color: var(--text-secondary);
  background: var(--surface-2); border: 1px solid var(--border);
}
.fact-chip i { width: 12px; height: 12px; }
.fact-chip[data-cat="food"] {
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-primary) 26%, transparent);
}
.fact-chip[data-cat="measurements"] {
  color: var(--color-primary-2);
  background: color-mix(in srgb, var(--color-primary-2) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-primary-2) 26%, transparent);
}
.fact-chip[data-cat="goals"] {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-accent) 26%, transparent);
}
.fact-chip[data-cat="lifestyle"] {
  color: #a855f7;
  background: color-mix(in srgb, #a855f7 12%, transparent);
  border-color: color-mix(in srgb, #a855f7 26%, transparent);
}
.fact-chip[data-cat="style"] {
  color: #38bdf8;
  background: color-mix(in srgb, #38bdf8 12%, transparent);
  border-color: color-mix(in srgb, #38bdf8 26%, transparent);
}

.fact-actions { display: flex; gap: 4px; flex: none; }
.fact-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: none; background: transparent;
  border-radius: 8px; color: var(--text-muted); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.fact-icon:hover { background: var(--surface-2); color: var(--text-secondary); }
.fact-icon.danger:hover {
  color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}
.fact-icon svg { width: 16px; height: 16px; }
.fact-edit-actions { display: flex; gap: 8px; width: 100%; }
.fact-btn-ghost, .fact-btn-save {
  flex: 1; border-radius: var(--r-sm); padding: 10px 0; font: inherit;
  font-size: 14px; font-weight: 600; cursor: pointer; border: 1px solid var(--border);
  transition: filter var(--dur) var(--ease);
}
.fact-btn-ghost { background: var(--surface-2); color: var(--text-secondary); }
.fact-btn-save { background: var(--color-primary); color: #fff; border-color: transparent; }
.fact-btn-save:active { filter: brightness(0.95); }

/* recipes.css */
/* =====================================================
   Раздел «Рецепты»: фильтр по категориям, карточки-превью,
   детальная карточка (bottom-sheet) с фото и вариантами.
   Базовые примитивы (.card-тень, .chip, .ii-cell, .btn-soft,
   .btn-ghost, .sheet) — из theme.css / meal_sheet.css.
   ===================================================== */

/* ----------------- Фильтр категорий ----------------- */
.recipes-filter { margin-bottom: 4px; }
.chip-count {
  margin-left: 7px;
  font-size: 11px;
  font-weight: 700;
  opacity: 0.7;
}
.chip.active .chip-count { opacity: 0.9; }

/* ----------------- Верхняя панель: поиск + теги ----------------- */
.recipes-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.recipes-search {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 40px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.recipes-search svg { width: 17px; height: 17px; color: var(--text-muted); flex: none; }
.recipes-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: none;
  font-size: 14px;
  color: var(--text-primary);
}
.recipes-tags-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 40px;
  padding: 0 13px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.recipes-tags-toggle svg { width: 15px; height: 15px; }
.recipes-tags-toggle.active {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
}
.recipes-tags-toggle.hidden { display: none; }

/* Сворачиваемая панель тегов. */
.recipes-tags {
  display: none;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: 10px;
  padding: 11px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.recipes-tags.open { display: flex; }
.rt-empty { font-size: 12.5px; color: var(--text-muted); }
.tag-chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 11px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.tag-chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.tag-chip.active .chip-count { opacity: 0.9; }

/* ----------------- Сетка карточек ----------------- */
.recipes-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.recipes-grid .empty { grid-column: 1 / -1; }
.recipe-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--dur) var(--ease);
}
.recipe-card:active { transform: scale(0.985); }

.rc-photo {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--surface-2) center / cover no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
}
.rc-photo.empty svg { width: 34px; height: 34px; color: var(--text-muted); }
.rc-photo-spin {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 24px;
  height: 24px;
}

.rc-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 11px 12px;
}
.rc-cat {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--color-primary);
}
.rc-cat svg { width: 12px; height: 12px; flex: none; }
.rc-name {
  font-size: 14.5px;
  font-weight: 800;
  letter-spacing: -0.3px;
  line-height: 1.25;
  color: var(--text-primary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.rc-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.rc-tag {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: var(--r-pill);
  padding: 2px 7px;
}
.rc-kcal { font-size: 12px; color: var(--text-secondary); margin-top: 1px; }
.rc-kcal b { font-size: 13.5px; font-weight: 800; color: var(--text-primary); }

/* Сентинел бесконечной прокрутки. */
.recipes-sentinel {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 10px 0;
}

/* Чипы ингредиентов (в шторке). */
.recipe-ings { display: flex; flex-wrap: wrap; gap: 6px; }
.recipe-ing {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 4px 10px;
}

/* Теги рецепта в шторке. */
.rs-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
.rs-tag {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-primary) 24%, transparent);
  border-radius: var(--r-pill);
  padding: 3px 10px;
}

/* ----------------- Спиннеры ----------------- */
.rs-spin,
.rc-photo-spin {
  display: inline-block;
  border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--color-primary) 28%, transparent);
  border-top-color: var(--color-primary);
  animation: rs-spin 0.8s linear infinite;
}
.rs-spin { width: 26px; height: 26px; }
@keyframes rs-spin { to { transform: rotate(360deg); } }

/* ----------------- Детальная карточка (sheet) ----------------- */
.rs-loading { text-align: center; color: var(--text-muted); padding: 30px 0; }
.rs-title {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.4px;
  line-height: 1.25;
  color: var(--text-primary);
  margin: 14px 0 4px;
}
.rs-notes {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* Фото-обложка. */
.rs-photo { margin-top: 2px; }
.rs-photo.has-photo { position: relative; }
.rs-photo.has-photo img {
  width: 100%;
  height: 210px;
  object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  display: block;
  cursor: pointer;
}
.rs-photo-edit {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: none;
  border-radius: var(--r-pill);
  background: rgba(8, 11, 16, 0.6);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.rs-photo-edit svg { width: 15px; height: 15px; }

/* Плейсхолдер/состояние генерации. */
.rs-photo.empty,
.rs-photo.pending {
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-2);
  min-height: 180px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 22px 16px;
  text-align: center;
}
.rs-photo-ph {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.rs-photo-ph svg { width: 30px; height: 30px; color: var(--text-muted); }
.rs-photo-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  width: 100%;
}
.rs-photo-actions .btn-soft { flex: 1; min-width: 150px; }
.rs-photo-hint { font-size: 11.5px; color: var(--text-muted); }
.rs-photo-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  font-size: 13.5px;
  color: var(--text-secondary);
  line-height: 1.4;
}
.rs-photo-state i { font-style: normal; font-size: 11.5px; color: var(--text-muted); }
.rs-photo-skip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 8px;
}
.rs-photo-skip svg { width: 15px; height: 15px; }

/* Выбор категории чипами. */
.rs-cats { display: flex; flex-wrap: wrap; gap: 8px; }
.rs-cat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
.rs-cat svg { width: 15px; height: 15px; flex: none; }
.rs-cat.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* Варианты рецепта. */
.rs-variants { display: flex; flex-direction: column; gap: 10px; }
.rs-variant {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 11px 12px;
}
.rs-variant-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 9px;
}
.rs-variant-label { font-size: 13.5px; font-weight: 700; color: var(--text-primary); }
.rv-grams { font-size: 12px; color: var(--text-muted); }
.rs-variant-head .rv-portions {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent, var(--text-primary));
  margin-left: auto;
  margin-right: 8px;
}
.rs-variant-macros {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}
.rs-variant-sub {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  margin: 9px 0 5px;
}
.rs-ings-detail {
  margin-top: 10px;
  border-top: 1px solid var(--border);
  padding-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.rs-ing-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  font-size: 12px;
}
.rs-ing-name { color: var(--text-primary); font-weight: 600; flex: 1 1 auto; }
.rs-ing-grams { color: var(--text-muted); }
.rs-ing-kcal { color: var(--text-muted); flex: 1 1 100%; }

/* billing.css */
/* Биллинг-UI в мини-аппе: вход в админку, карточка подписки, премиум-гейт. */

/* Стрелка-вход в админку (в шапке, только для админа) */
.page-header { position: relative; }
.admin-entry {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--color-primary);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
.admin-entry.hidden { display: none; }
.admin-entry i { width: 18px; height: 18px; }
.admin-entry-arrow { opacity: 0.6; }

/* Карточка подписки в профиле */
.pf-plan {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  cursor: pointer;
}
.pf-plan-icon {
  width: 40px; height: 40px;
  border-radius: 12px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  color: var(--color-accent);
  flex-shrink: 0;
}
.pf-plan-info { flex: 1; min-width: 0; }
.pf-plan-title { font-weight: 600; color: var(--text-primary); }
.pf-plan-badge {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 4px;
  font-size: 13px;
}
.pf-plan-badge i { width: 14px; height: 14px; }
.pf-plan-badge.premium { color: var(--color-accent); }
.pf-plan-badge.free { color: var(--text-secondary); }
.pf-plan-hint { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.pf-plan-cta {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 13px;
  color: var(--color-primary);
  flex-shrink: 0;
}
.pf-plan-cta i { width: 16px; height: 16px; }

/* Вход в админ-панель из профиля (только для админа) */
.pf-admin {
  display: flex; align-items: center; gap: 12px; width: 100%;
  text-align: left; padding: 14px 16px; cursor: pointer; margin-top: 14px;
}
.pf-admin-ic {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 12px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.pf-admin-ic i { width: 21px; height: 21px; }
.pf-admin-info { flex: 1; min-width: 0; }
.pf-admin-title { font-weight: 600; color: var(--text-primary); }
.pf-admin-sub { font-size: 12.5px; color: var(--text-secondary); margin-top: 2px; }
.pf-admin-chev { color: var(--text-muted); flex-shrink: 0; width: 18px; height: 18px; }

/* Премиум-гейт (заглушка вместо премиум-раздела) */
.premium-gate { text-align: center; padding: 32px 20px; }
.pg-icon {
  width: 64px; height: 64px; margin: 0 auto 16px;
  border-radius: 20px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  color: var(--color-accent);
}
.pg-icon i { width: 32px; height: 32px; }
.pg-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.pg-text { color: var(--text-secondary); margin-bottom: 20px; line-height: 1.4; }

/* ---------------- Экран подписки (subview) ----------------
   Компактная вёрстка: умещается на экран телефона без скролла.
   Раскладку включает класс на контейнере (App.markSubview): :has() понимают не
   все вебвью, в которых открывается мини-апп, а отступы нужны везде. */
.sv-sub .subview-body,
.subview-body:has(.sub-hero) { gap: 0; }

.sub-hero { text-align: center; padding: 0 0 12px; }
/* Серьёзный монохромный бейдж: чёрная плашка (инверсия в тёмной теме),
   без «детского» градиента и псевдо-дороговизны. */
.sub-crown {
  width: 46px; height: 46px; margin: 0 auto 8px;
  border-radius: 13px; display: grid; place-items: center;
  background: var(--text-primary);
  color: var(--surface);
  box-shadow: var(--shadow-card);
}
.sub-crown i { width: 22px; height: 22px; }
.sub-title { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
.sub-price {
  margin-top: 2px; font-size: 14px; font-weight: 600; color: var(--text-secondary);
}
/* Полная сумма годового тарифа под ценой за месяц: она должна быть видна, но не
   спорить с главным числом. */
.sub-price-total {
  margin-top: 2px; font-size: 12px; color: var(--text-tertiary, var(--text-secondary));
  opacity: .8;
}
/* Преимущества: сворачиваемый список — 1-й блок целиком, 2-й наполовину + blur. */
.sub-benefits-wrap {
  position: relative;
  background: var(--surface-2); border-radius: 14px;
  margin-bottom: 14px; overflow: hidden;
}
.sub-benefits-list {
  display: flex; flex-direction: column;
  padding: 4px 14px;
  transition: max-height 0.35s ease;
}
.sub-benefits-collapsed .sub-benefits-list {
  max-height: 116px; /* 1-й блок целиком + ~половина 2-го */
}
.sub-benefits-expanded .sub-benefits-list {
  max-height: 420px;
}
.sub-benefit {
  display: flex; gap: 12px; align-items: center;
  padding: 10px 0;
}
.sub-benefit + .sub-benefit { border-top: 1px solid var(--border); }
.sub-benefit > i {
  width: 20px; height: 20px; color: var(--color-primary); flex-shrink: 0;
}
.sub-benefit-t { font-weight: 600; font-size: 14px; line-height: 1.2; }
.sub-benefit-d { color: var(--text-secondary); font-size: 12.5px; line-height: 1.25; margin-top: 1px; }

/* Плавное многослойное размытие (progressive blur): три слоя с нарастающим
   радиусом размытия, каждый замаскирован ниже предыдущего, плюс мягкий
   уход в цвет фона у самого низа. */
.sub-benefits-fade { display: none; }
.sub-benefits-collapsed .sub-benefits-fade,
.sub-benefits-collapsed .sub-benefits-fade::before,
.sub-benefits-collapsed .sub-benefits-fade::after {
  content: '';
  display: block; pointer-events: none;
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 92px;
}
.sub-benefits-collapsed .sub-benefits-fade {
  z-index: 1;
  backdrop-filter: blur(0.6px);
  -webkit-backdrop-filter: blur(0.6px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 32%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 32%);
}
.sub-benefits-collapsed .sub-benefits-fade::before {
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 38%, #000 72%);
  mask-image: linear-gradient(to bottom, transparent 38%, #000 72%);
}
.sub-benefits-collapsed .sub-benefits-fade::after {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  background: linear-gradient(to bottom,
    transparent 52%,
    color-mix(in srgb, var(--surface-2) 60%, transparent) 78%,
    var(--surface-2) 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 58%, #000 90%);
  mask-image: linear-gradient(to bottom, transparent 58%, #000 90%);
}
.sub-benefits-collapsed { padding-bottom: 34px; }

/* Кнопка раскрытия / сворачивания списка — мягкая «таблетка» без кружка,
   с плоским (приплюснутым) шевроном. */
.sub-benefits-toggle {
  display: none;
  place-items: center;
  width: 48px; height: 24px;
  border: none; border-radius: 999px;
  background: color-mix(in srgb, var(--text-primary) 6%, transparent);
  color: var(--text-secondary);
  cursor: pointer; box-shadow: none;
  transition: transform 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.sub-benefits-toggle i, .sub-benefits-toggle svg {
  width: 22px; height: 13px; stroke-width: 2;
}
.sub-benefits-toggle:active { background: color-mix(in srgb, var(--text-primary) 11%, transparent); }
.sub-benefits-collapsed .sub-benefits-toggle {
  display: grid;
  position: absolute; bottom: 8px; left: 50%;
  transform: translateX(-50%); z-index: 2;
}
.sub-benefits-collapsed .sub-benefits-toggle:active {
  transform: translateX(-50%) scale(0.94);
}
.sub-benefits-expanded .sub-benefits-toggle {
  display: grid;
  margin: 4px auto 6px;
}

/* Способы оплаты: полноширинные карточки — текст не обрезается. */
.sub-pm-grid { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.sub-pm {
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border: 1.5px solid var(--border); border-radius: 14px;
  background: var(--surface); color: var(--text-primary);
  cursor: pointer; position: relative; text-align: left;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.sub-pm:active { transform: scale(0.98); }
.sub-pm.active {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 6%, var(--surface));
}
.sub-pm .pm-logo {
  flex-shrink: 0; width: 38px; height: 38px;
  display: grid; place-items: center;
  background: none; border: none; box-shadow: none;
}
.sub-pm .pm-logo img { height: 30px; width: auto; display: block; }
.sub-pm .pm-logo i { width: 26px; height: 26px; color: var(--text-primary); }
.sub-pm .pm-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.sub-pm .pm-label {
  font-size: 14px; font-weight: 600; line-height: 1.2;
}
.sub-pm .pm-sub {
  font-size: 12px; color: var(--text-secondary); line-height: 1.25;
  display: flex; align-items: center; gap: 3px; flex-wrap: wrap;
}
.sub-pm .pm-sub-icon { height: 12px; width: auto; display: inline-block; vertical-align: middle; }

/* Знак Telegram Stars как единица валюты рядом с суммой: тянется за размером
   текста, поэтому одинаково садится и в шапке, и на тарифах, и в кнопке. */
.stars-mark {
  height: 0.95em; width: auto;
  display: inline-block; vertical-align: -0.11em;
}

/* Кнопка оплаты — всегда в вёрстке: на нативную MainButton не полагаемся, в
   fullscreen на телефонах Telegram убирает нижнюю панель вместе с ней. Панель
   липнет к низу прокрутки, иначе на длинном экране до кнопки надо долистывать. */
/* Собственный нижний отступ подраздела отдаём панели: иначе кнопка «висит»
   над пустой полосой вместо того, чтобы прижаться к краю экрана. */
.subview.sv-pay,
.subview:has(.sub-pay-bar) { padding-bottom: 0; }
/* Тело подраздела растягиваем на всю высоту — тогда margin-top: auto уводит
   панель вниз даже на коротком контенте, где прокрутки нет вовсе. */
.sv-pay .subview-body,
.subview-body:has(.sub-pay-bar) { flex: 1 0 auto; }
.sub-pay-bar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin: auto calc(-1 * var(--spacing-md)) 0;
  padding: 10px var(--spacing-md)
    calc(10px + env(safe-area-inset-bottom, 0px) + var(--tg-safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--bg-app) 62%, transparent);
}
.sub-pay-bar-terms { background: var(--bg-app); }
.sub-pay-cta { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.subview-body .sub-pay-cta { margin-top: 0; }
.sub-pay-cta i { width: 18px; height: 18px; }

.sub-note {
  color: var(--text-secondary); text-align: center; font-size: 14px;
  padding: 12px; background: var(--surface-2); border-radius: 12px;
}

/* Пояснение к бесплатному доступу: пробный период и подарочный премиум */
.sub-free-note {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  background: color-mix(in srgb, var(--accent, #34c759) 12%, transparent);
  border-radius: 12px;
  font-size: 13px; line-height: 1.4; color: var(--text-primary);
}
/* lucide подменяет <i data-lucide> на <svg>, поэтому нужны оба селектора */
.sub-free-note i, .sub-free-note svg {
  width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px;
  color: var(--accent, #34c759);
}
.sub-free-note b { font-weight: 600; }

/* Когда начнётся оплаченный доступ поверх ещё действующего бесплатного */
/* На этом экране gap у .subview-body обнулён — отступы задаём сами. */
.sub-keep-note {
  margin: 12px 2px 14px;
  font-size: 12.5px; line-height: 1.35; color: var(--text-secondary);
}

/* Автопродление и управление картой */
.sub-autorenew {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; margin-bottom: 12px;
  background: var(--surface-2); border-radius: 12px;
  font-size: 13px; color: var(--text-primary); cursor: pointer; line-height: 1.25;
}
.sub-autorenew .switch { flex-shrink: 0; }
/* Переключатель автопродления над кнопкой оплаты (с 30.09.2026 месяц с ним
   дешевле): включили — цена в шапке «падает» на новое место. */
.sub-autorenew-pay { margin: 0 0 10px; }
.sub-autorenew-label {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-weight: 600;
}
.sub-auto-pill {
  padding: 2px 8px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  background: rgba(52, 199, 89, .15); color: var(--success, #34c759);
}
.sub-price-drop .sub-price-now {
  display: inline-block; animation: sub-price-drop .7s ease;
}
@keyframes sub-price-drop {
  0% { transform: translateY(-8px); opacity: 0; }
  55% { transform: translateY(0) scale(1.12); opacity: 1; color: var(--success, #34c759); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sub-price-drop .sub-price-now { animation: none; }
}
.sub-card-block {
  display: flex; flex-direction: column; gap: 8px; margin-top: 12px;
}
.sub-card-block .sub-autorenew { margin-bottom: 0; }

/* Условия автосписания — прямо над кнопкой «Подписаться»: согласие даётся её
   нажатием, поэтому текст должен быть на глазах в этот момент, а не отдельным
   блоком выше. Мелким, но с выделенной суммой: полная формулировка обязательна
   для эквайринга, читать её как заголовок никто не должен. */
.sub-terms {
  margin-bottom: 8px;
  font-size: 11.5px; line-height: 1.35; color: var(--text-secondary);
  text-align: center;
}
.sub-terms b { font-weight: 600; color: var(--text-primary); }
/* Разовая оплата — вторая по важности, поэтому текстовой кнопкой под основной.
   Прятать её нельзя: выбор должен быть виден, иначе «Подписаться» перестаёт быть
   выбором. */
.sub-pay-once {
  display: block; width: 100%;
  margin-top: 8px; padding: 6px 0;
  background: none; border: 0;
  font-size: 13px; font-weight: 500; color: var(--text-secondary);
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.sub-pay-once:active { opacity: .6; }

/* Контакты для возврата/отмены подписки */
.sub-support-note {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 12px; padding: 10px 12px;
  font-size: 12.5px; line-height: 1.35; color: var(--text-secondary);
}
.sub-support-note i { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.sub-support-note a { color: var(--accent, #34c759); font-weight: 600; text-decoration: none; }

/* «Вернуть деньги»: тихая ссылка внизу экрана, по нажатию — форма заявки
   (billing/refund_request.py). Не кнопка на виду: это путь к нам вместо
   спора в банке, а не приглашение вернуть деньги. */
.sub-refund-link {
  display: block; width: 100%;
  margin-top: 14px; padding: 6px 0;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-secondary);
  text-decoration: underline; text-underline-offset: 3px;
}
.sub-refund-link:active { opacity: .6; }
.sub-refund {
  margin-top: 12px; padding: 14px;
  background: var(--surface-2); border-radius: 12px;
}
.sub-refund h3 { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
.sub-refund p {
  margin: 0 0 12px; font-size: 13px; line-height: 1.4; color: var(--text-secondary);
}
/* Причины — карточки со своим кружком: системное радио с accent-color
   выглядело чужим (тёмное кольцо вокруг зелёной точки). Выбранную строку
   подсвечивает класс is-on из JS: :has() есть не во всех встроенных браузерах. */
.sub-refund-reasons { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.sub-refund-reason {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: 12px;
  background: var(--surface); border: 1.5px solid var(--border);
  font-size: 15px; line-height: 1.25; color: var(--text-primary); cursor: pointer;
  transition: border-color .15s, background-color .15s;
  -webkit-tap-highlight-color: transparent;
}
.sub-refund-reason.is-on {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
}
.sub-refund-reason input {
  -webkit-appearance: none; appearance: none;
  flex-shrink: 0; width: 20px; height: 20px; margin: 0;
  border: 2px solid var(--border-strong); border-radius: 50%;
  background: var(--surface);
  transition: border-color .15s, box-shadow .15s, background-color .15s;
}
.sub-refund-reason input:checked {
  border-color: var(--color-primary);
  background: var(--color-primary);
  box-shadow: inset 0 0 0 3px var(--surface);
}
.sub-refund-reason input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.sub-refund-hint {
  margin: 0 0 10px; padding: 10px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent, #34c759) 12%, transparent);
  font-size: 13px; line-height: 1.4; color: var(--text-primary);
}
.sub-refund textarea {
  display: block; width: 100%; box-sizing: border-box; resize: vertical;
  padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border, rgba(0, 0, 0, .12));
  background: var(--bg-app); color: var(--text-primary);
  font: inherit; font-size: 14px;
}
.sub-refund-actions { display: flex; gap: 8px; margin-top: 12px; }
.sub-refund-actions .btn-soft { flex: 0 0 auto; padding-inline: 18px; }
.sub-refund-actions .btn-primary { flex: 1; white-space: nowrap; }
/* display у ссылки и формы перебил бы атрибут hidden */
.sub-refund-link[hidden], .sub-refund[hidden], .sub-refund-hint[hidden] { display: none; }
.sub-refund-sent {
  margin-top: 14px; font-size: 13px; line-height: 1.4;
  color: var(--text-secondary); text-align: center;
}

/* ---------------- Промокод (только веб-версия) ----------------
   В Telegram код отправляют боту сообщением; в браузере ввод живёт на экране
   подписки. По умолчанию это одна тихая строка-ссылка: у большинства кода нет,
   и пустое поле рядом с ценой только отвлекало бы от оплаты. */
.sub-promo { margin-top: 12px; }
.sub-promo-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  border: none; background: none; padding: 4px 0; cursor: pointer;
  font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--text-secondary);
}
.sub-promo-toggle[hidden] { display: none; }
.sub-promo-toggle i { width: 15px; height: 15px; }
.sub-promo-form { display: flex; gap: 8px; align-items: stretch; }
.sub-promo-form[hidden] { display: none; }
.sub-promo-form input {
  flex: 1; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--fill-input); color: var(--text-primary);
  /* 16px — иначе iOS зумит страницу при фокусе на поле. */
  font-size: 16px; padding: 11px 12px;
  text-transform: uppercase; outline: none;
}
.sub-promo-form input:focus { border-color: var(--color-primary); }
.sub-promo-form .btn-soft { flex: none; width: auto; padding: 0 16px; }
.sub-promo-applied {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px; padding: 10px 12px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--text-primary); font-size: 13.5px;
}
.sub-promo-applied i { width: 16px; height: 16px; color: var(--color-primary); }

/* Уведомление «отключите VPN» перед переходом на страницу банка */
.vpn-notice {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center; padding: 24px;
  background: color-mix(in srgb, var(--text-primary) 55%, transparent);
  backdrop-filter: blur(2px);
  opacity: 0; transition: opacity 0.2s ease;
}
.vpn-notice.show { opacity: 1; }
.vpn-card {
  width: 100%; max-width: 340px; text-align: center;
  padding: 28px 24px; border-radius: 20px;
  background: var(--surface); box-shadow: var(--shadow-card);
}
.vpn-icon {
  width: 56px; height: 56px; margin: 0 auto 16px;
  border-radius: 16px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  color: var(--color-accent);
}
.vpn-icon i { width: 28px; height: 28px; }
.vpn-title { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.vpn-text { color: var(--text-secondary); font-size: 14px; line-height: 1.4; }
.vpn-bar {
  height: 3px; margin-top: 18px; border-radius: 999px;
  background: var(--surface-2); overflow: hidden;
}
.vpn-bar > span {
  display: block; height: 100%; width: 100%;
  background: var(--color-primary);
  transform-origin: left;
  animation: vpn-progress 1.8s linear forwards;
}
@keyframes vpn-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* Окно «банк недоступен» (bank_reach.js): совет и кнопки столбиком. */
.bank-blocked .bank-status { margin-top: 10px; }
.bank-blocked .bank-status:empty { display: none; }
.bank-blocked .bank-actions { display: grid; gap: 10px; margin-top: 18px; }
.bank-blocked .bank-actions .btn-primary,
.bank-blocked .bank-actions .btn-soft { width: 100%; }

/* Тумблер тарифов: Месяц / Год */
.sub-plan-toggle { display: flex; gap: 8px; }
.sub-plan {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 8px; border-radius: 14px; cursor: pointer;
  border: 1.5px solid var(--border, rgba(128,128,128,.25));
  background: var(--surface);
  color: var(--text-primary); line-height: 1.15;
}
.sub-plan.active {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
}
.sub-plan-name { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.sub-plan-price { font-size: 12px; color: var(--text-secondary); }
.sub-plan-save {
  font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 999px;
  background: rgba(52,199,89,.15); color: #34c759;
}
.sub-offer-badge { background: rgba(255,59,48,.12) !important; color: #ff3b30 !important; }

/* Узкие экраны. Высота свёрнутого списка подобрана под подписи в одну строку,
   а на 320-360px они переносятся на две — и вместо «полутора пунктов» остаётся
   один обрезанный. Даём строку запаса и ужимаем горизонтальные отступы. */
@media (max-width: 370px) {
  .sub-benefits-collapsed .sub-benefits-list { max-height: 140px; }
  .sub-benefit { gap: 10px; }
  .sub-benefit-d { font-size: 12px; }
  .sub-pm { padding: 11px 12px; gap: 10px; }
  .sub-pay-cta { font-size: 14.5px; }
  .sub-plan { padding: 9px 6px; }
}

/* Низкие экраны (iPhone SE, вебвью с панелями сверху и снизу): шапка и списки
   ужимаются, чтобы кнопка оплаты осталась в поле зрения без прокрутки. */
@media (max-height: 700px) {
  .sub-crown {
    width: 40px; height: 40px; border-radius: 12px; margin-bottom: 6px;
  }
  .sub-crown i { width: 20px; height: 20px; }
  .sub-title { font-size: 18px; }
  .sub-hero { padding-bottom: 8px; }
  .sub-benefits-collapsed .sub-benefits-list { max-height: 104px; }
  .sub-benefits-wrap { margin-bottom: 10px; }
  .sub-benefit { padding: 8px 0; }
  .sub-support-note { margin-top: 8px; padding: 8px 10px; }
}

/* ---------------- Детальные нутриенты (клетчатка и типы жиров) ----------------
   На бесплатном тарифе значений нет вообще — бэкенд их не отдаёт. Вместо
   пустоты показываем «пломбу»: размытое правдоподобное число и замок. */
.nutri-tile.locked .nutri-val {
  filter: blur(6px);
  opacity: 0.5;
  user-select: none;
}
.nutri-tile.locked .nutri-label { display: inline-flex; align-items: center; }
.nutri-fill.locked {
  width: 58%;
  background: color-mix(in srgb, var(--text-muted) 45%, transparent);
}
.nutri-lock,
.field-lock {
  width: 12px;
  height: 12px;
  flex: none;
  margin-left: 5px;
  vertical-align: -1px;
  color: var(--text-muted);
}

/* Поповер-апселл: размытое превью шкал + одна кнопка. */
.tip-locked {
  filter: blur(5px);
  opacity: 0.45;
  pointer-events: none;
  user-select: none;
}
.tip-cta {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 9px 12px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--text-primary);
  color: var(--surface);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Строка в карточке приёма: прочерк вместо числа. */
.ms-nutri-row b.ms-nutri-locked {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--text-muted);
  font-weight: 600;
}
.ms-nutri-locked i { width: 12px; height: 12px; }

/* Настройки закрытых нутриентов в профиле — видны, но не редактируются. */
.field.locked,
.switch-row.locked { cursor: pointer; }
.field.locked .field-lbl,
.switch-row.locked > span { display: inline-flex; align-items: center; }
.field.locked input,
.switch-row.locked .switch { opacity: 0.5; pointer-events: none; }

/* plan_forecast.css */
/* Карточка «куда ведёт план»: дата достижения целевого веса.
   Одни стили на два экрана — конец онбординга и экран подписки (plan_forecast.js).
   Дата здесь главная, поэтому она и набрана крупнее всего остального.
   Префикс plf-, а не pf-: последний занят профилем (profile.css, profile_edit.css). */
.plf-card {
  margin: 18px auto 0;
  max-width: 360px;
  padding: 16px 16px 14px;
  border-radius: var(--r-md, 14px);
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--color-primary) 26%, transparent);
  text-align: center;
}
.plf-top {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--text-secondary);
}
.plf-top svg { width: 15px; height: 15px; }
.plf-date {
  margin-top: 6px;
  font-size: 24px; font-weight: 800; line-height: 1.15;
  letter-spacing: -0.5px;
  color: var(--color-primary);
}
.plf-sub {
  margin-top: 6px;
  font-size: 14px; font-weight: 600; color: var(--text-primary);
}
.plf-note {
  margin-top: 10px;
  font-size: 12px; line-height: 1.45; color: var(--text-muted);
}

/* streak.css */
/* =====================================================
   Стрик и награды: живое пламя, неделя-точки, вехи,
   достижения. Анимации мягкие, уважают reduced-motion.
   ===================================================== */

/* -------- Пламя (общее) -------- */
/* Живой огонёк рисует flame.js на canvas внутри .flame-img. Пока его нет
   (маски грузятся, скрипт не доехал) — тот же огонёк статичной картинкой. */
.flame-img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  background: url('/static/img/streak/flame.webp') center / contain no-repeat;
}
.flame-img.is-live { background: none; }
.flame-img.dim:not(.is-live) { filter: grayscale(1) brightness(1.15); opacity: 0.8; }
.flame-img canvas {
  display: block;
  width: 100%;
  height: 100%;
}
/* Холст салюта на веху серии: шире огонька (доля та же, что SALUTE_ZOOM в
   flame.js) и намеренно выходит за его границы — иначе сноп искр обрезало бы
   по краю значка. Лежит под числом дней и появляется только в день вехи. */
.flame-img canvas.flame-fx {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 260%;
  /* Общий сброс держит canvas в ширине родителя (theme.css) — здесь он должен
     из неё выйти, иначе сноп искр обрезается по бокам, а вверх летит. */
  max-width: none;
  height: 260%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* -------- Виджет на «Сводке» -------- */
.streak-card {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 12px 16px;
  margin-bottom: var(--spacing-md);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-spring);
}
.streak-card:active { transform: scale(0.98); }

.streak-flame {
  position: relative;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
}
/* Тёплое свечение позади пламени — «дышит». */
.streak-flame::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(251, 146, 60, 0.35), transparent 70%);
  animation: glowPulse 2.2s ease-in-out infinite;
}
/* Погасшая серия — без свечения. Класс, а не :has(): селектор поддерживают не
   все вебвью, а промах здесь оставил бы оранжевый ореол вокруг серого пламени. */
.streak-flame.is-dim::before { display: none; }

@keyframes glowPulse {
  0%, 100% { opacity: 0.55; transform: scale(0.92); }
  50%      { opacity: 1;    transform: scale(1.08); }
}

.streak-flame-num {
  position: absolute;
  left: 50%;
  bottom: 4px;
  transform: translateX(-50%);
  font-size: 13px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 3px rgba(135, 55, 16, 0.53);
}
/* На сером пламени тёплая тень читалась рыжим ореолом вокруг цифр — когда
   серия не горит, тень тоже нейтральная. */
.streak-flame.is-dim .streak-flame-num {
  text-shadow: 0 1px 3px rgba(71, 85, 105, 0.5);
}

.streak-widget-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.streak-widget-title { font-size: 14px; color: var(--text-primary); }
.streak-widget-title b { font-weight: 800; }
.streak-chev { color: var(--text-muted); flex: 0 0 auto; }

/* -------- Неделя -------- */
/* В виджете (без подписей) — компактные точки; на экране раздела — аккуратные
   скруглённые плитки с подписью дня и галочкой на записанных днях. */
.streak-week { display: flex; gap: 7px; }
.sw-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.sw-label {
  font-style: normal;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
}
.sw-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-style: normal;
  font-size: 9px;
  font-weight: 800;
  line-height: 1;
  background: var(--fill-track);
  animation: dotPop 0.4s var(--ease-spring) backwards;
  animation-delay: calc(var(--i) * 55ms);
}

.sw-dot.logged {
  background: linear-gradient(180deg, #fbbf24, #f97316);
  color: #fff;
  box-shadow: 0 1px 4px rgba(249, 115, 22, 0.4);
}
.sw-dot.frozen {
  background: linear-gradient(180deg, #7dd3fc, #38bdf8);
  color: #fff;
}
.sw-dot.today {
  background: transparent;
  border: 2px dashed var(--border-strong);
  animation: dotPop 0.4s var(--ease-spring) backwards,
    todayPulse 1.8s ease-in-out infinite 0.5s;
  animation-delay: calc(var(--i) * 55ms), 0.6s;
}
.sw-dot.missed { background: var(--fill-track); opacity: 0.6; }
.sw-dot.future { background: var(--fill-track); opacity: 0.35; }

/* Плитки на экране раздела */
.streak-week.labeled { gap: 6px; }
.streak-week.labeled .sw-day { flex: 1; gap: 7px; }
.streak-week.labeled .sw-dot {
  width: 100%;
  height: 38px;
  border-radius: 12px;
  font-size: 14px;
  box-shadow: none;
}
.streak-week.labeled .sw-dot.logged {
  box-shadow: 0 3px 10px rgba(249, 115, 22, 0.28);
}
/* Записанный день — подпись тёплым акцентом. */
.sw-day:has(.sw-dot.logged) .sw-label,
.sw-day:has(.sw-dot.frozen) .sw-label {
  color: var(--color-accent);
  font-weight: 700;
}
/* Сегодня без записи — мягкая плитка с акцентной рамкой (без «дашей»). */
.streak-week.labeled .sw-dot.today {
  border: 1.5px solid var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
}
/* Сегодняшний день явно помечен пилюлей-подписью (в любом состоянии). */
.streak-week.labeled .sw-day.is-today .sw-label {
  color: #fff;
  background: var(--color-primary);
  border-radius: var(--r-pill);
  padding: 1px 7px;
  font-weight: 700;
}
/* Пропущенные — спокойная светлая заливка (без стыда). */
.streak-week.labeled .sw-dot.missed {
  background: var(--surface-2);
  opacity: 1;
}
/* Будущие — нейтральные пустые плитки-контуры, отличимы от пропусков. */
.streak-week.labeled .sw-dot.future {
  background: transparent;
  border: 1.5px solid var(--border);
  opacity: 1;
}

@keyframes dotPop {
  from { transform: scale(0.2); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
@keyframes todayPulse {
  0%, 100% { border-color: var(--border-strong); }
  50%      { border-color: var(--color-primary); }
}

/* -------- Полка прогресса (вкладка «Прогресс») -------- */
/* Три карточки одним столбцом: серия, неделя в лиге, награды. Полка стоит прямо
   во вкладке, а не в подразделе: место в таблице недели должно быть видно без
   тапа, иначе за ним никто не идёт. */
.hub {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.hub-card {
  box-sizing: border-box;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
/* Место полки, пока едут данные: без него вкладка прыгает на высоту трёх
   карточек, когда ответ приходит. */
.hub-skeleton {
  height: 232px;
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
/* Плоские блоки без теней — как список достижений; поспокойнее и компактнее. */
.streak-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
/* Компактная шапка: пламя слева, число и статус — справа. */
.streak-hero-top {
  display: flex;
  align-items: center;
  gap: 12px;
}
.streak-hero-head { flex: 1; min-width: 0; }
.streak-hero-count {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-secondary);
  line-height: 1.1;
}
.streak-hero-count b {
  margin-right: 3px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -1px;
  vertical-align: -2px;
  background: linear-gradient(180deg, #fbbf24, #f97316);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.streak-hero:not(.lit) .streak-hero-count b {
  background: none;
  -webkit-text-fill-color: currentColor;
  color: var(--text-primary);
}
.streak-hero-flame {
  position: relative;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
}
/* Лёгкое свечение за пламенем у активной серии — единственный тёплый акцент. */
.streak-hero.lit .streak-hero-flame::before {
  content: '';
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(251, 146, 60, 0.35), transparent 65%);
  animation: glowPulse 2.2s ease-in-out infinite;
}

/* Искры: всплывают из основания пламени и тают. */
.streak-sparks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.spark {
  position: absolute;
  left: calc(18% + var(--s) * 13%);
  bottom: 26%;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #fbbf24;
  opacity: 0;
  animation: sparkFloat 2.6s ease-in infinite;
  animation-delay: calc(var(--s) * 0.42s);
}
.spark:nth-child(even) { width: 3px; height: 3px; background: #fb923c; }
/* День вехи: искры идут гуще. Салюта из виджета здесь нет намеренно — блок
   подрезает всё, что выходит за его края, и сноп обрубало бы на полпути. */
.streak-hero.milestone .spark { animation-duration: 1.5s; }
@keyframes sparkFloat {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  12%  { opacity: 0.9; }
  100% { transform: translate(calc((var(--s) - 2.5) * 5px), -40px) scale(0.3); opacity: 0; }
}
.streak-hero-status { margin-top: 4px; font-size: 13px; color: var(--text-muted); }
.streak-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}
/* Компактный календарь недели прямо в блоке серии. */
.streak-hero-week {
  width: 100%;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.streak-week-cap {
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}

/* -------- Защита серии: лёгкая второстепенная строка -------- */
.streak-shield {
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
}
.shield-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
.shield-ico {
  flex: 0 0 auto;
  font-style: normal;
  font-size: 15px;
  color: #38bdf8;
}
.shield-label { color: var(--text-secondary); }
.shield-hint {
  margin-left: auto;
  padding: 0;
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  color: var(--color-accent);
  background: none;
  border: 0;
  cursor: pointer;
}
.shield-note {
  margin-top: 8px;
  padding: 9px 11px;
  border-radius: var(--r-sm);
  background: rgba(56, 189, 248, 0.08);
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-secondary);
}

/* -------- Ближайшая цель: награда, строка и полоса -------- */
/* Значок будущей награды слева от полосы — в пунктирной рамке, чтобы читался
   как «ещё не твой». Полоса без картинки в конце показывала движение
   неизвестно к чему. */
.ms-goal-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.ms-award {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1.5px dashed color-mix(in srgb, var(--color-accent) 55%, transparent);
  border-radius: 14px;
}
.ms-award img { width: 34px; height: 34px; object-fit: contain; }
.ms-goal-body { flex: 1; min-width: 0; }
.ms-goal {
  display: block;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--text-primary);
}
/* Баллы недели — единственная зелёная строка в карточке серии: она про лигу,
   а не про сам огонёк. */
.ms-bonus {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: color-mix(in srgb, var(--color-primary) 75%, var(--text-primary));
}
.ms-bonus > svg { flex: 0 0 auto; width: 13px; height: 13px; }
.ms-bar {
  display: block;
  height: 7px;
  margin-top: 7px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.ms-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, #fbbf24, #f97316);
  transition: width 0.9s var(--ease);
}

/* -------- Рекорд и всего дней в шапке серии -------- */
/* Два числа справа от огонька. Раньше они лежали внутри раскрытого списка
   достижений — то есть их видел только тот, кто догадался его раскрыть. */
.hub-stats {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: right;
}
.hub-stats span { font-size: 10.5px; color: var(--text-muted); }
.hub-stats b {
  margin-right: 4px;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--text-secondary);
}

/* -------- Вечерний отсчёт и кнопка записи -------- */
/* Не «ты не записал», а сколько времени у дня осталось: торопит время, а не
   упрёк. Тот же тон, что у вечернего напоминания бота. */
.hub-cta {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.hub-cta-note {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--text-secondary);
}
.hub-cta-note > svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  color: var(--color-accent);
}
.hub-cta .streak-cta { width: 100%; margin-top: 0; justify-content: center; }

/* Защита серии переехала внутрь карточки серии: отдельной карточкой она стояла
   выше лиги и цели, хотя нужна раз в месяц. */
.hub-shield {
  margin-top: 11px;
  padding: 0;
  border: 0;
  background: none;
}
.hub-shield .shield-row { font-size: 12px; }
.hub-shield .shield-ico { font-size: 13px; }

/* -------- Обещание сезона -------- */
/* Печать — вещь третьего класса: не плоский бейдж достижения и не камень
   ступени. Пока обещание не сдержано, она показана приглушённой: это не
   «сломалась картинка», а «ещё не твоя». */
.pl-seal {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
}
.pl-seal img { width: 100%; height: 100%; object-fit: contain; }
.pl-seal > i[data-lucide] { width: 22px; height: 22px; color: var(--color-accent); }
.pl-seal.dim img { filter: grayscale(0.85) opacity(0.5); }
.pl-head { cursor: default; }

.pl-ask {
  margin-top: 13px;
  font-size: 14px;
  font-weight: 700;
}
/* Три ступени в ряд: нижняя массовая, верхняя редкая — её и подсвечиваем. */
.pl-steps { display: flex; gap: 8px; margin-top: 10px; }
.pl-step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 4px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text-primary);
  font: inherit;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-spring);
}
.pl-step:active { transform: scale(0.97); }
.pl-step > b { font-size: 14px; font-weight: 750; }
.pl-step > span { font-size: 10.5px; color: var(--text-secondary); text-align: center; }
.pl-step.top {
  border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
  background: color-mix(in srgb, var(--color-accent) 7%, var(--surface));
}
.pl-step.top > span { color: color-mix(in srgb, var(--color-accent) 80%, var(--text-primary)); font-weight: 700; }
.pl-note {
  margin-top: 9px;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--text-muted);
}

.pl-run { margin-top: 13px; }
.pl-run-title { font-size: 13.5px; font-weight: 650; }
.pl-run-note { margin-top: 7px; font-size: 12px; color: var(--text-secondary); }
.pl-done {
  margin-top: 12px;
  font-size: 15px;
  font-weight: 800;
  color: color-mix(in srgb, var(--color-primary) 75%, var(--text-primary));
}
/* Сорванное обещание: ни красного, ни рамки. Просто тише. */
.hub-pledge.broken .hub-head-body > b { color: var(--text-secondary); }

/* -------- Праздник за сдержанное слово -------- */
.pl-celebrate {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(17, 21, 28, 0.55);
  animation: plFade 0.25s var(--ease);
}
.pl-celebrate-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 320px;
  padding: 24px 20px 20px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-float);
  text-align: center;
  animation: plPop 0.35s var(--ease-spring);
}
.pl-celebrate-seal {
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 48%,
    rgba(249, 115, 22, 0.18), transparent 66%);
}
.pl-celebrate-seal img { width: 100%; height: 100%; object-fit: contain; }
.pl-celebrate-title { font-size: 21px; font-weight: 800; letter-spacing: -0.4px; }
.pl-celebrate-sub { font-size: 13.5px; line-height: 1.35; color: var(--text-secondary); }
.pl-celebrate-perk {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 6px 11px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  font-size: 12.5px;
  font-weight: 650;
  color: color-mix(in srgb, var(--color-primary) 78%, var(--text-primary));
}
.pl-celebrate-perk > svg { width: 15px; height: 15px; }
.pl-celebrate-card .btn-primary { width: 100%; margin-top: 12px; }

@keyframes plFade { from { opacity: 0; } }
@keyframes plPop {
  from { transform: scale(0.88) translateY(12px); opacity: 0; }
}

/* -------- Шапка карточки (лига, награды) -------- */
.hub-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.hub-tier {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--surface-2);
}
.hub-tier img { width: 42px; height: 42px; object-fit: contain; }
.hub-tier > i { width: 21px; height: 21px; color: var(--text-secondary); }
.hub-head-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hub-head-body > b { font-size: 14.5px; font-weight: 700; }
.hub-head-body > span { font-size: 12.5px; color: var(--text-secondary); }
.hub-title { font-size: 14.5px; font-weight: 700; }
.hub-count {
  margin-left: auto;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-secondary);
}
.hub-chev { flex: 0 0 auto; width: 18px; height: 18px; color: var(--text-muted); }

/* -------- Мини-таблица недели -------- */
/* Строки те же, что на экране лиги (league.css): подиум, своя строка и
   позывной обязаны выглядеть одинаково в обоих местах, иначе это читается как
   две разные таблицы. Здесь они только уже и плотнее. */
.hub-table {
  margin: 12px -16px 0;
  border-top: 1px solid var(--border);
}
.hub-table .lg-row { padding: 7px 16px; font-size: 13.5px; }
.hub-table .lg-av { flex: 0 0 26px; width: 26px; height: 26px; font-size: 12px; }
.hub-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 11px;
}
/* «Догоняю» — то, ради чего сюда возвращаются до воскресенья. */
.hub-gap {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 650;
  color: color-mix(in srgb, var(--color-primary) 75%, var(--text-primary));
}
.hub-gap > svg { flex: 0 0 auto; width: 14px; height: 14px; }
.hub-gap.first { color: var(--color-accent); }
.hub-link {
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 650;
  color: var(--color-accent);
  cursor: pointer;
}

/* -------- Лента наград -------- */
.hub-rail {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px -16px 0;
  padding: 0 16px 10px;
  overflow-x: auto;
  scrollbar-width: none;
}
.hub-rail::-webkit-scrollbar { display: none; }
.hub-badge { flex: 0 0 auto; width: 46px; height: 46px; }
/* Следующая награда — в пунктирной рамке и с дробью: она ещё не открыта, но
   показана настоящим значком, а не замком. */
.hub-next {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1.5px dashed var(--border-strong);
  border-radius: 16px;
}
.hub-next .hub-badge { width: 34px; height: 34px; }
.hub-next > i {
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%);
  padding: 1px 6px;
  border-radius: var(--r-pill);
  background: var(--text-secondary);
  color: #fff;
  font-size: 9.5px;
  font-style: normal;
  font-weight: 700;
}

/* Витрина наград вынесена в achievements.css. */

/* -------- Доступность -------- */
@media (prefers-reduced-motion: reduce) {
  .streak-flame::before,
  .streak-hero.lit .streak-hero-flame::before,
  .sw-dot,
  .spark { animation: none !important; }
  .ms-fill { transition: none; }
  .pl-celebrate,
  .pl-celebrate-card { animation: none; }
}

/* day_score.css */
/* =====================================================
   Оценка дня на «Сводке»: счёт и полоса из групп баллов.
   Легенда и строка о том, что можно добрать, раскрываются
   по нажатию (day_score.js).

   Карточка кликабельная целиком, поэтому это <button>:
   нажатие и фокус должны работать с клавиатуры, а не
   только мышью.

   На сводке оценка дня и пламя серии сидят в одной рамке
   (.day-card, index.html). Сами .day-score и .streak-card
   остаются самостоятельными карточками для стендов.
   ===================================================== */

/* Рамка плоская — без тени и белой подложки. Карточкой с тенью на сводке
   остаётся только «Сегодня»: когда плавает каждый блок, всё кажется одинаково
   важным. */
.day-card {
  display: flex;
  align-items: stretch;
  margin-bottom: var(--spacing-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  background: transparent;
  transition: transform var(--dur) var(--ease);
}
/* :active срабатывает и у предков нажатой кнопки: сжимается вся рамка, а не
   половина карточки внутри неё. */
.day-card:active { transform: scale(0.98); }
.day-card > .day-score,
.day-card > .streak-card {
  margin: 0;
  border: 0;
  border-radius: var(--r-lg);
  background: none;
  box-shadow: none;
}
.day-card > .day-score:active,
.day-card > .streak-card:active { transform: none; }

.day-card.is-joined > .day-score {
  flex: 1;
  min-width: 0;
  padding-right: 6px;
}
/* Справа от полосы, за тонким разделителем, — огонёк с числом дней и под ними
   «дня подряд». Число внутри пламени без подписи читалось вторым счётом рядом
   с «71 из 100». Полная строка серии и значок лиги остаются на экране серии:
   рядом с оценкой им не хватает ширины телефона. */
.day-card.is-joined > .streak-card {
  position: relative;
  flex: none;
  width: auto;
  display: grid;
  grid-template-columns: auto auto;
  align-content: center;
  justify-content: center;
  align-items: center;
  gap: 0 4px;
  padding: 10px 12px 10px 10px;
}
/* Раскрытый разбор вытягивает рамку вниз — серия остаётся на уровне
   заголовка, а не повисает посередине списка. */
.day-card.is-joined > .day-score.is-open + .streak-card {
  align-content: start;
  padding-top: 12px;
}
.day-card.is-joined > .streak-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 1px;
  background: var(--border);
}
.day-card.is-joined .streak-flame,
.day-card.is-joined .streak-widget-info,
.day-card.is-joined .streak-tier,
.day-card.is-joined .streak-chev { display: none; }
.streak-joined { display: none; }
.day-card.is-joined .streak-joined { display: contents; }
/* Контурный огонёк: оранжевый, пока серия горит, серый — если сегодня ещё
   ничего не записано. */
.streak-joined-ic {
  width: 18px;
  height: 18px;
  color: #f97316;
  stroke-width: 2.2;
}
body.tg-dark-theme .streak-joined-ic { color: #fb923c; }
.streak-joined.is-dim .streak-joined-ic { color: var(--text-muted); }
.streak-joined b {
  font-size: 16px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.streak-joined small {
  grid-column: 1 / -1;
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-muted);
  text-align: center;
  white-space: nowrap;
}

.day-score {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  margin-bottom: var(--spacing-md);
  font-family: inherit;
  text-align: left;
  color: var(--text-primary);
  cursor: pointer;
  transition: transform var(--dur) var(--ease);
}
.day-score:active { transform: scale(0.98); }
.day-score:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Цветок дня: пять мазков, по одному на группу баллов (day_score.js). Заливка
   мазка — доля набранных баллов группы, поэтому он говорит то же, что полоса,
   но одним взглядом и без чтения цифр. */
/* Цветок тише полосы: меньше и светлее зелёным. Ярким и в 36 px он первым
   забирал взгляд, а главное в карточке — счёт. Отступ сверху ставит его по
   центру заголовка с полосой. */
:root { --ds-flower: #6dd694; }
body.tg-dark-theme { --ds-flower: #2ea862; }
.ds-flower {
  flex: none;
  width: 28px;
  height: 28px;
  margin-top: 4px;
}

/* Всё остальное содержимое карточки — во второй колонке. */
.ds-body {
  flex: 1;
  min-width: 0;
}

/* Заголовок и счёт не рвутся посередине: на узком телефоне рядом с серией
   «71 из 100» целиком переходит на вторую строку, а не «День собран / на /
   71 из / 100». */
.ds-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  margin-bottom: 8px;
}
.ds-title {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}
.ds-score {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Полоса из пяти постоянных отрезков: flex-grow отрезка равен максимуму его
   группы, заливка внутри — набранной доле. Так видно и вес стороны в ста
   баллах, и где именно недобрано. */
.ds-bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ds-bar {
  flex: 1;
  display: flex;
  gap: 3px;
  height: 8px;
}
.ds-bar span {
  display: block;
  min-width: 0;
  height: 100%;
  border-radius: 3px;
  background: var(--fill-track);
  overflow: hidden;
}
.ds-bar i {
  display: block;
  height: 100%;
  border-radius: 3px;
  transition: width var(--dur) var(--ease);
}

/* Раскрывающаяся часть. Высота едет через grid-template-rows 0fr → 1fr:
   так не нужно знать высоту содержимого, а подсказка бывает в одну строку
   и в две. Отступ — у легенды, а не у обёртки: паддинг обёртки остался бы
   виден и у свёрнутой карточки. */
.ds-more {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows var(--dur) var(--ease),
    visibility 0s linear var(--dur);
}
.ds-more-in {
  min-height: 0;
  overflow: hidden;
}
.day-score.is-open .ds-more {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows var(--dur) var(--ease);
}

/* Разбор: строка на отрезок полосы. Сверху название и «4 из 10», под ними
   мелко — за что эти баллы. Точка стоит на уровне названия, пояснение
   начинается под названием, а не под точкой. */
.ds-legend {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ds-row {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto;
  column-gap: 8px;
  row-gap: 1px;
  align-items: center;
}
.ds-dot {
  width: 8px;
  height: 8px;
  border-radius: 3px;
}
.ds-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
}
.ds-pts {
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ds-pts b {
  font-weight: 600;
  color: var(--text-primary);
}
.ds-about {
  grid-column: 2 / -1;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--text-secondary);
}

.ds-hint {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-secondary);
}
.ds-hint b {
  color: var(--text-primary);
  font-weight: 600;
}

.ds-chev {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  transition: transform var(--dur) var(--ease);
}
.day-score.is-open .ds-chev { transform: rotate(180deg); }

/* day_bloom.css */
/* =====================================================
   «День собран на 100%» (day_bloom.js): цветок дня
   распускается на весь экран. Тёмный фон одинаковый в
   светлой и тёмной теме: на нём цветок и светится.
   Слои снизу вверх: затемнение → сцена с цветком →
   холст с искрами → подписи.
   ===================================================== */

.dbl {
  position: fixed;
  inset: 0;
  /* Выше шторок и поздравлений (до 4000), ниже тостов. */
  z-index: 5000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 16px calc(56px + env(safe-area-inset-bottom));
  color: #fff;
  overflow: hidden;
  outline: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}

.dbl-shade {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 50% 40%, rgba(22, 26, 38, 0.72), rgba(3, 4, 8, 0.93) 70%);
  -webkit-backdrop-filter: blur(10px) saturate(0.7);
  backdrop-filter: blur(10px) saturate(0.7);
  animation: dblFade 0.55s ease-out both;
}
@keyframes dblFade { from { opacity: 0; } to { opacity: 1; } }

.dbl-fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

/* ----- Сцена ----------------------------------------- */
.dbl-stage {
  position: relative;
  z-index: 1;
  flex: none;
  width: min(80vw, 50vh, 380px);
  height: min(80vw, 50vh, 380px);
}

/* Тёплое свечение и медленно вращающееся цветное кольцо за цветком —
   те же пять цветов, что у лепестков. */
.dbl-halo {
  position: absolute;
  inset: -30%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 228, 160, 0.4),
    rgba(255, 196, 120, 0.12) 50%, transparent 74%);
  opacity: 0;
  transform: scale(0.55);
  transition: opacity 1s ease, transform 1.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.dbl-halo::after {
  content: '';
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  background: conic-gradient(#22c55e, #4ade80, #38bdf8, #f59e0b, #8b5cf6, #22c55e);
  filter: blur(38px);
  opacity: 0.42;
  animation: dblSpin 16s linear infinite;
  will-change: transform;
}

.dbl-rays {
  position: absolute;
  inset: -62%;
  border-radius: 50%;
  background: repeating-conic-gradient(rgba(255, 240, 205, 0.13) 0deg 2.5deg,
    transparent 2.5deg 15deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 22%, transparent 74%);
  mask-image: radial-gradient(closest-side, #000 22%, transparent 74%);
  opacity: 0;
  transition: opacity 1.6s ease 0.1s;
  animation: dblSpin 70s linear infinite;
  will-change: transform;
}
@keyframes dblSpin { to { transform: rotate(360deg); } }

.dbl-ring {
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  border: 2px solid rgba(255, 246, 220, 0.9);
  box-shadow: 0 0 26px rgba(255, 226, 160, 0.55), inset 0 0 26px rgba(255, 226, 160, 0.35);
  opacity: 0;
}
.dbl-ring-2 {
  border-color: rgba(167, 139, 250, 0.7);
  box-shadow: 0 0 30px rgba(56, 189, 248, 0.45);
}

.dbl-flash {
  position: absolute;
  inset: 18%;
  border-radius: 50%;
  background: radial-gradient(closest-side, #fff, rgba(255, 244, 214, 0.85) 32%,
    rgba(255, 214, 140, 0) 72%);
  opacity: 0;
  pointer-events: none;
}

.dbl-fly {
  position: absolute;
  inset: 0;
  transition: transform 0.62s cubic-bezier(0.55, 0, 0.25, 1), opacity 0.22s ease 0.42s;
  will-change: transform;
}
/* Тени у цветка нет намеренно: фильтр на родителе пересчитывал бы все пять
   анимируемых лепестков на каждом кадре, а на тёмном фоне её и не видно. */
.dbl-bloom {
  position: absolute;
  inset: 0;
}

.dbl-petal,
.dbl-flower,
.dbl-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  -webkit-user-drag: none;
}

/* Лепесток — вся картинка под маской своего сектора. Растёт из середины
   с поворотом по часовой стрелке и пружинит на месте. */
.dbl-petal {
  opacity: 0;
  will-change: transform, opacity;
}
.dbl-petal.on {
  animation: dblPetal 0.78s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}
@keyframes dblPetal {
  0% { opacity: 0; transform: rotate(-44deg) scale(0.1); filter: brightness(2.6); }
  40% { opacity: 1; }
  62% { transform: rotate(5deg) scale(1.08); filter: brightness(1.35); }
  82% { transform: rotate(-1.5deg) scale(0.985); filter: brightness(1.05); }
  100% { opacity: 1; transform: none; filter: none; }
}

/* Когда встал последний лепесток, под ними проявляется цельная картинка:
   на стыках масок остаются полупрозрачные швы, у цельной их нет. */
.dbl-flower {
  opacity: 0;
  transition: opacity 0.3s ease;
}
.dbl.settled .dbl-flower { opacity: 1; }
.dbl.settled .dbl-petal { visibility: hidden; transition: visibility 0s linear 0.35s; }
.dbl.settled .dbl-bloom { animation: dblBreathe 6s ease-in-out infinite; }
@keyframes dblBreathe {
  0%, 100% { transform: none; }
  50% { transform: scale(1.03) rotate(2deg); }
}

.dbl.bloomed .dbl-halo { opacity: 1; transform: none; }
.dbl.bloomed .dbl-rays { opacity: 1; }
.dbl.bloomed .dbl-ring { animation: dblRing 1.05s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.dbl.bloomed .dbl-ring-2 { animation-delay: 0.14s; animation-duration: 1.25s; }
.dbl.bloomed .dbl-flash { animation: dblFlash 0.9s ease-out both; }
@keyframes dblRing {
  0% { opacity: 0.95; transform: scale(0.22); }
  100% { opacity: 0; transform: scale(1.6); }
}
@keyframes dblFlash {
  0% { opacity: 0; transform: scale(0.3); }
  22% { opacity: 0.95; }
  100% { opacity: 0; transform: scale(1.9); }
}

/* Картинка не загрузилась: крупно распускается векторный цветок карточки. */
.dbl.no-img .dbl-petal,
.dbl.no-img .dbl-flower { display: none; }
.dbl-svg { opacity: 0; }
.dbl.bloomed .dbl-svg { animation: dblPetal 0.9s cubic-bezier(0.2, 0.8, 0.25, 1) both; }

/* ----- Подписи --------------------------------------- */
.dbl-copy {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  max-width: 360px;
  margin-top: clamp(18px, 4.5vh, 40px);
  text-align: center;
  pointer-events: none;
}
.dbl-title {
  font-size: 28px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateY(14px) scale(0.96);
  transition: opacity 0.6s ease 0.12s, transform 0.9s cubic-bezier(0.34, 1.56, 0.64, 1) 0.12s;
}
.dbl-score {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 232, 178, 0.92);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.6s ease 0.3s, transform 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.3s;
}
.dbl.bloomed .dbl-title,
.dbl.bloomed .dbl-score { opacity: 1; transform: none; }

.dbl-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
}
.dbl-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px 5px 9px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--r-pill, 999px);
  background: rgba(255, 255, 255, 0.07);
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.88);
  opacity: 0;
  transform: translateY(8px) scale(0.9);
  transition: opacity 0.35s ease, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.dbl-chip i {
  width: 8px;
  height: 8px;
  border-radius: 3px;
  background: var(--c);
  box-shadow: 0 0 10px var(--c);
}
.dbl-chip.on {
  opacity: 1;
  transform: none;
  animation: dblChip 1s ease-out both;
}
@keyframes dblChip {
  0% { border-color: var(--c); box-shadow: 0 0 14px -2px var(--c); }
  100% { border-color: rgba(255, 255, 255, 0.1); box-shadow: 0 0 14px -2px transparent; }
}

.dbl-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(20px + env(safe-area-inset-bottom));
  z-index: 3;
  font-size: 12.5px;
  text-align: center;
  color: rgba(255, 255, 255, 0.46);
  opacity: 0;
  transition: opacity 0.8s ease 1.6s;
  pointer-events: none;
}
.dbl.bloomed .dbl-hint { opacity: 1; }

/* ----- Уход ------------------------------------------ */
.dbl.out { pointer-events: none; }
.dbl.out .dbl-shade { animation: dblFadeOut 0.5s ease 0.1s both; }
@keyframes dblFadeOut { from { opacity: 1; } to { opacity: 0; } }
.dbl.out .dbl-copy,
.dbl.out .dbl-hint,
.dbl.out .dbl-halo,
.dbl.out .dbl-rays,
.dbl.out .dbl-fx {
  opacity: 0;
  transition: opacity 0.22s ease;
}
.dbl.out-home .dbl-fly { opacity: 0; }
.dbl.out-away .dbl-fly {
  opacity: 0;
  transform: scale(0.7);
  transition: transform 0.4s ease-in, opacity 0.3s ease 0.05s;
}

/* Маленький цветок карточки принимает улетевший цветок. */
.ds-flower.dbl-pop { animation: dblPop 0.7s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes dblPop {
  0% { transform: scale(1.45); filter: brightness(1.6) drop-shadow(0 0 10px rgba(255, 220, 140, 0.8)); }
  100% { transform: none; filter: none; }
}

/* Собранный день: цветок в карточке чуть светится — на него можно нажать и
   посмотреть праздник ещё раз. */
.day-score.is-full .ds-flower {
  filter: drop-shadow(0 0 5px rgba(250, 204, 21, 0.45));
}

/* Без движения: цветок и подписи сразу на месте, только плавное появление. */
.dbl.calm .dbl-petal { display: none; }
.dbl.calm .dbl-svg { animation: none; opacity: 1; }
.dbl.calm .dbl-flower,
.dbl.calm .dbl-title,
.dbl.calm .dbl-score,
.dbl.calm .dbl-chip,
.dbl.calm .dbl-hint,
.dbl.calm .dbl-halo { transition: none; animation: none; }
.dbl.calm .dbl-halo::after,
.dbl.calm .dbl-rays,
.dbl.calm .dbl-ring,
.dbl.calm .dbl-flash,
.dbl.calm .dbl-bloom { animation: none; }
.dbl.calm .dbl-ring,
.dbl.calm .dbl-flash { display: none; }
.dbl.calm.out .dbl-fly { transition: opacity 0.2s ease; }

/* coaching.css */
/* Карточка «Сегодня», недельный маршрут и разбор недели.
   Карточка должна читаться одним взглядом, поэтому в ней всего три уровня
   текста и одна заметная кнопка. Ничего красного и никаких предупреждений:
   пропуск шага это нормальный исход, а не ошибка. */

/* Размеров шрифта в карточке ровно четыре: 11 — служебный ярлык, 13 — всё
   второстепенное, 14 — то, что нажимают, 15 — сам вопрос. Дробных значений тут
   было семь, и карточка выглядела собранной из чужих кусков.
   Строк в карточке тоже ровно четыре: шапка, вопрос, ответы, неделя. Всё
   служебное живёт в шапке — отдельная строка под «зачем» и «пропустить» стоила
   треть высоты карточки и оттесняла калории под сгиб экрана. */
.today-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}

/* Карточка убрана под раскрытие: свёрнутой она не спорит с дневником, а
   раскрытой выглядит ровно как раньше — ярлык, цена в минутах, вопрос, «зачем»
   и одна заметная кнопка. Раскрытие меняет только объём, не оформление. */
.today-disclosure > summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.today-disclosure > summary::-webkit-details-marker { display: none; }
.today-sum-copy { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1; }
/* Свёрнутый вопрос — не больше двух строк: иначе карточка снова становится
   самым высоким блоком экрана. Раскрытая показывает текст целиком. */
.today-sum-copy .today-what {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.today-disclosure[open] .today-sum-copy .today-what { display: block; }
.today-chev {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  transition: transform var(--dur) var(--ease);
}
.today-disclosure[open] .today-chev { transform: rotate(180deg); }
.today-detail {
  display: grid;
  gap: 12px;
  padding: 12px 15px 13px;
  border-top: 1px solid var(--border);
}
.today-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; }
.today-controls .today-skip { margin-left: 0; padding: 6px 0; }
.today-detail button:disabled { opacity: 0.5; cursor: wait; }

/* Ярлык, «зачем», цена в минутах и выход — всё в одной строке. По центру, а не
   по базовой линии: в строке есть иконка, и по базовой линии она съезжает. */
.today-head {
  display: flex;
  align-items: center;
  gap: 7px;
}

/* «Шаг на сегодня» — это ярлык карточки, а не заголовок мысли. Когда он был
   одного размера с самим заданием, взгляд цеплялся за служебные слова, а
   действие терялось: главным в карточке должен читаться текст задания. */
.today-title {
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted, #8b94a3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.today-time {
  flex: none;
  font-size: 11px;
  line-height: 1;
  color: var(--text-muted, #8b94a3);
  white-space: nowrap;
}

.today-what {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.today-cta {
  width: 100%;
}

/* «Зачем» — иконка без подписи: словами она занимала целую строку, а нужна от
   силы один раз. Отрицательные поля дают палец 26×26, не раздувая строку. */
.today-why-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin: -6px -6px -6px -2px;
  border: 0;
  background: none;
  color: var(--text-muted, #8b94a3);
  cursor: pointer;
}

.today-why-btn i {
  width: 15px;
  height: 15px;
}

.today-why-btn.open {
  color: var(--color-primary, #22c55e);
}

/* Пропуск — выход из карточки, а не второе главное действие, поэтому обычный
   приглушённый текст у правого края. */
.today-skip {
  flex: none;
  margin-left: auto;
  border: 0;
  background: none;
  padding: 4px 0 4px 8px;
  font-size: 13px;
  line-height: 1;
  color: var(--text-muted, #8b94a3);
  cursor: pointer;
}

/* Раскрытие через grid-строку 0fr → 1fr: так же, как свёрнутые группы приёмов
   в дневнике, и без магических max-height. Отрицательный отступ гасит gap
   карточки, пока блок закрыт, чтобы под строкой не висела пустая полоса. */
.today-why-wrap {
  display: grid;
  grid-template-rows: 0fr;
  margin-top: -6px;
  transition: grid-template-rows var(--dur, 0.22s) var(--ease, ease);
}

.today-why-wrap.open {
  grid-template-rows: 1fr;
}

.today-why-inner {
  overflow: hidden;
  padding-top: 6px;
}

.today-why {
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-muted, #8b94a3);
}

.today-why.dim {
  margin-top: 4px;
  opacity: 0.7;
}

.today-options {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.today-opt {
  border: 1px solid var(--border, rgba(140, 150, 170, 0.28));
  background: transparent;
  border-radius: 999px;
  padding: 7px 12px;
  font-size: 14px;
  line-height: 1.2;
  color: inherit;
  cursor: pointer;
}

.today-opt:active {
  transform: scale(0.98);
}

.today-done {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  line-height: 1.45;
}

.today-done i {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: #22c55e;
  margin-top: 2px;
}

.today-feedback {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text-muted, #8b94a3);
}

.tf-btn {
  border: 1px solid var(--border, rgba(140, 150, 170, 0.28));
  background: transparent;
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 13px;
  color: inherit;
  cursor: pointer;
}

/* --- Предложение убрать шаги совсем --- */
/* Занимает место пропущенной карточки и уходит само. Ничего тревожного: это
   выход из механики, а не удаление данных, поэтому тон приглушённый, а кнопка
   такая же обводка, как у остальных второстепенных кнопок карточки. */

.today-hide {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-muted, #8b94a3);
}

.today-hide-q {
  flex: 1 1 auto;
  min-width: 0;
}

.today-hide-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border, rgba(140, 150, 170, 0.28));
  background: transparent;
  border-radius: 999px;
  padding: 6px 10px 6px 12px;
  font-size: 13px;
  line-height: 1;
  color: inherit;
  cursor: pointer;
}

.today-hide-btn:active {
  transform: scale(0.98);
}

/* Секунды до исчезновения — в самой кнопке: так видно, что предложение уйдёт
   само, и не нужна отдельная строка про таймер. */
.today-hide-left {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--border, rgba(140, 150, 170, 0.22));
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* --- Режим без цифр --- */

.gentle-word {
  font-size: 18px;
  line-height: 1.25;
  font-weight: 650;
}

.gentle-hint {
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted, #8b94a3);
}

/* --- Неделя: строка в подвале карточки «Сегодня» --- */

.today-week {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border, rgba(140, 150, 170, 0.18));
}

/* Когда шага дня нет, строка живёт сама по себе — в карточке. */
#week-route.glass-card {
  padding: 12px 16px;
}
#week-route .today-week {
  padding-top: 0;
  border-top: 0;
}

.wr-dots {
  display: flex;
  gap: 5px;
  flex: none;
}

.wr-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1.5px solid var(--border, rgba(140, 150, 170, 0.4));
}

.wr-dot.on {
  background: #22c55e;
  border-color: #22c55e;
}

.wr-label {
  font-size: 13px;
  color: var(--text-muted, #8b94a3);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wr-more {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  flex: none;
  border: 0;
  background: none;
  padding: 2px 0;
  font-size: 13px;
  color: var(--accent, #22c55e);
  cursor: pointer;
}

.wr-more i {
  width: 15px;
  height: 15px;
}

/* --- Итоги недели ---
   Одна карточка с разделами, а не лента из четырёх glass-card. Заголовки
   разделов — 15/700, как .card-title в остальном приложении: раньше они были
   13 muted, а текст 15, и иерархия читалась задом наперёд. */

.wk-view {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 24px;
}

.wk-card {
  display: flex;
  flex-direction: column;
  padding: 4px 0 8px;
}

.wk-head {
  text-align: left;
  padding: 14px 16px 12px;
}

.wk-dots {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
}

.wk-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fill-track, rgba(140, 150, 170, 0.28));
}

.wk-dot.on {
  background: var(--color-primary, #22c55e);
}

.wk-days {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
}

.wk-days b {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.wk-days-cap,
.wk-note {
  font-size: 13px;
  line-height: 1.35;
  color: var(--text-muted, #8b94a3);
  margin-top: 4px;
}

.wk-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border-top: 1px solid var(--border, rgba(140, 150, 170, 0.18));
}

.wk-section-title {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-primary, inherit);
}

.wk-text {
  font-size: 15px;
  line-height: 1.45;
}

.wk-extra {
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-muted, #8b94a3);
}

.wk-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.wk-chip {
  border: 1px solid var(--border, rgba(140, 150, 170, 0.28));
  background: transparent;
  border-radius: 999px;
  padding: 7px 12px;
  font-size: 14px;
  line-height: 1.2;
  color: inherit;
  cursor: pointer;
}

.wk-chip.on {
  border-color: var(--color-primary, #22c55e);
  color: var(--color-primary, #22c55e);
}

.wk-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
}

.wk-actions .btn-primary {
  flex: 1 1 auto;
}

.wk-decline {
  border: 0;
  background: none;
  padding: 10px 4px;
  font-size: 13px;
  color: var(--text-muted, #8b94a3);
  cursor: pointer;
}

/* nutrition_game.css */
/* =====================================================
   Детектив тарелки (nutrition_game.js) — обучающий раунд
   в подразделе профиля. Токены, карточки и иконки общие
   с остальным приложением: theme.css + lucide, никаких
   собственных цветов.

   Промах красим янтарём, а не красным: в обучающем деле
   это подсказка, а не ошибка. По той же причине нет ни
   таймера, ни «жизней».
   ===================================================== */

.ng {
  display: flex;
  flex-direction: column;
  gap: 14px;
  outline: none;
}
.ng h2 {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.4px;
  outline: none;
}
.ng p { margin: 0; }

/* A single heading in the shared subview bar; no separate splash screen. */
.subview.sv-learning .subview-head { margin-top: 0; flex-shrink: 0; }
.subview.sv-learning .subview-body { flex-shrink: 0; }
.ng-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 18px; line-height: 1.25; }
.ng-title svg, .ng-title i { width: 22px; height: 22px; flex: none; color: var(--color-primary); }
.sv-learning .subview-title { min-width: 0; }
.sv-learning .subview-back span { display: none; }
.sv-learning .subview-back { flex: none; }
.ng-tagline { color: var(--text-secondary); font-size: 13px; line-height: 1.4; }
@media (max-width: 360px) {
  .ng-title { font-size: 16px; gap: 6px; }
  .ng-title svg, .ng-title i { width: 20px; height: 20px; }
}
@media (min-width: 900px) {
  .subview.sv-learning .subview-head { padding: 12px 18px; }
  .subview.sv-learning .subview-body { padding: 16px 18px; }
}

/* ----------------- Загрузка ----------------- */
.ng-load { display: flex; justify-content: center; gap: 7px; padding: 64px 0; }
.ng-load span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fill-track);
  animation: ngPulse 1s var(--ease) infinite;
}
.ng-load span:nth-child(2) { animation-delay: 0.15s; }
.ng-load span:nth-child(3) { animation-delay: 0.3s; }
@keyframes ngPulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50% { opacity: 1; transform: none; }
}

/* ----------------- Заставка и итог ----------------- */
.ng-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 4px 0 2px;
  text-align: center;
}
.ng-hero-ic {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 22px;
  background: color-mix(in srgb, var(--color-primary) 13%, transparent);
  color: var(--color-primary);
  animation: ngPop 0.5s var(--ease-spring) both;
}
.ng-hero-ic i, .ng-hero-ic svg { width: 30px; height: 30px; }
.ng-hero p {
  max-width: 34em;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-secondary);
}
/* Итог дела — янтарь: это отметка о завершении, а не «зелёный = правильно». */
.ng-hero-win .ng-hero-ic {
  background: color-mix(in srgb, var(--color-accent) 15%, transparent);
  color: var(--color-accent);
}
@keyframes ngPop {
  from { opacity: 0; transform: scale(0.6) rotate(-12deg); }
  to { opacity: 1; transform: none; }
}

/* ----------------- Карта трёх дел ----------------- */
.ng-cases {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.ng-case { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.ng-case + .ng-case { border-top: 1px solid var(--border); }
.ng-case-ic {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--text-muted);
}
.ng-case-ic i, .ng-case-ic svg { width: 17px; height: 17px; }
.ng-case-txt { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.ng-case-txt b { font-size: 14px; font-weight: 650; }
.ng-case-txt span { font-size: 12px; color: var(--text-muted); }
.ng-case-mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
}
.ng-case-mark i, .ng-case-mark svg { width: 13px; height: 13px; }
.ng-case[data-state="now"] .ng-case-ic,
.ng-case[data-state="now"] .ng-case-mark {
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.ng-case[data-state="done"] .ng-case-ic {
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
}
.ng-case[data-state="done"] .ng-case-mark { background: var(--color-primary); color: #fff; }
.ng-case[data-state="next"] { opacity: 0.6; }

/* ----------------- Шапка вопроса ----------------- */
.ng-bar { display: flex; align-items: center; gap: 10px; }
.ng-bar-ic {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.ng-bar-ic i, .ng-bar-ic svg { width: 17px; height: 17px; }
.ng-bar-txt { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.ng-bar-txt b {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ng-bar-txt span { font-size: 11.5px; color: var(--text-muted); }
.ng-bar-count {
  flex: none;
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.ng-bar-count i { font-style: normal; font-size: 12px; font-weight: 700; color: var(--text-muted); }

.ng-dots { display: flex; gap: 5px; }
.ng-dot {
  flex: 1;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  transition: background var(--dur) var(--ease);
}
.ng-dot.is-full { background: var(--color-primary); }
.ng-dot.is-now { background: color-mix(in srgb, var(--color-primary) 40%, var(--fill-track)); }

.ng-streak {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
  font-size: 12px;
  font-weight: 700;
  animation: ngPop 0.4s var(--ease-spring) both;
}
.ng-streak i, .ng-streak svg { width: 14px; height: 14px; }

/* ----------------- Ситуация и вопрос ----------------- */
/* Снимок — часть вопроса, а не иллюстрация: кадр сверху, подпись снизу.
   Место под фото держим aspect-ratio, чтобы при загрузке не прыгала вёрстка. */
.ng-shot {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  overflow: hidden;
}
.ng-shot-img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--fill-track);
  border-bottom: 1px solid var(--border);
}
.ng-shot-cap {
  display: flex;
  gap: 11px;
  padding: 13px 15px;
  font-size: 14.5px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.ng-shot-cap i, .ng-shot-cap svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  color: var(--text-muted);
}
/* Разбор: кадр сжат до миниатюры, чтобы объяснение помещалось на экран. */
.ng-shot.is-tight { display: flex; align-items: center; gap: 12px; padding: 10px 12px; }
.ng-shot.is-tight .ng-shot-img {
  flex: none;
  width: 72px;
  aspect-ratio: 1 / 1;
  border: 0;
  border-radius: var(--r-sm);
}
.ng-shot.is-tight .ng-shot-cap {
  padding: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
}
.ng-shot.is-tight .ng-shot-cap i, .ng-shot.is-tight .ng-shot-cap svg { display: none; }

.ng .ng-prompt { font-size: 18px; }

.ng-choices { display: grid; gap: 9px; }
.ng-choice {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  color: var(--text-primary);
  font: inherit;
  font-size: 14.5px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.ng-choice:hover:not(:disabled) { border-color: var(--border-strong); }
.ng-choice:active:not(:disabled) { transform: scale(0.985); }
.ng-choice:disabled { cursor: default; box-shadow: none; }
.ng-choice-txt { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ng-key {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 700;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ng-tick {
  display: grid;
  place-items: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: #fff;
  animation: ngPop 0.3s var(--ease-spring) both;
}
.ng-tick i, .ng-tick svg { width: 14px; height: 14px; }
.ng-choice.is-right {
  border-color: color-mix(in srgb, var(--color-primary) 55%, var(--border));
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface));
}
.ng-choice.is-right .ng-key,
.ng-choice.is-right .ng-tick { background: var(--color-primary); color: #fff; }
.ng-choice.is-miss {
  border-color: color-mix(in srgb, var(--color-accent) 55%, var(--border));
  background: color-mix(in srgb, var(--color-accent) 9%, var(--surface));
}
.ng-choice.is-miss .ng-key,
.ng-choice.is-miss .ng-tick { background: var(--color-accent); color: #fff; }
.ng-choice.is-dim { opacity: 0.5; }

/* ----------------- Разбор ответа ----------------- */
.ng-verdict {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 15px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  outline: none;
  animation: ngRise 0.28s var(--ease) both;
}
.ng-verdict b {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 750;
}
.ng-verdict b i, .ng-verdict b svg { width: 16px; height: 16px; }
.ng-verdict p { font-size: 14px; line-height: 1.5; color: var(--text-secondary); }
.ng-verdict.is-ok {
  border-color: color-mix(in srgb, var(--color-primary) 34%, var(--border));
  background: color-mix(in srgb, var(--color-primary) 7%, var(--surface));
}
.ng-verdict.is-ok b { color: var(--color-primary); }
.ng-verdict.is-miss {
  border-color: color-mix(in srgb, var(--color-accent) 34%, var(--border));
  background: color-mix(in srgb, var(--color-accent) 7%, var(--surface));
}
.ng-verdict.is-miss b { color: var(--color-accent); }
@keyframes ngRise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ----------------- Итог дела ----------------- */
.ng-score { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.ng-score .ng-dots { width: min(220px, 70%); }
.ng-score span { font-size: 13px; font-weight: 650; color: var(--text-secondary); }

.ng-badge {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  animation: ngRise 0.35s var(--ease) 0.05s both;
}
.ng-badge-ic {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--color-primary) 13%, transparent);
  color: var(--color-primary);
}
.ng-badge-ic i, .ng-badge-ic svg { width: 20px; height: 20px; }
.ng-badge-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ng-badge-txt b { font-size: 14.5px; font-weight: 700; }
.ng-badge-txt span { font-size: 12px; color: var(--text-muted); }

.ng-review {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.ng-review summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 12px 15px;
  font-size: 14px;
  font-weight: 650;
  cursor: pointer;
  list-style: none;
}
.ng-review summary::-webkit-details-marker { display: none; }
.ng-review summary i, .ng-review summary svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  transition: transform var(--dur) var(--ease);
}
.ng-review[open] summary i, .ng-review[open] summary svg { transform: rotate(90deg); }
.ng-review-row { display: flex; gap: 10px; padding: 12px 15px; border-top: 1px solid var(--border); }
.ng-review-ic {
  display: grid;
  place-items: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-accent) 15%, transparent);
  color: var(--color-accent);
}
.ng-review-ic.is-ok {
  background: color-mix(in srgb, var(--color-primary) 15%, transparent);
  color: var(--color-primary);
}
.ng-review-ic i, .ng-review-ic svg { width: 13px; height: 13px; }
.ng-review-txt { font-size: 13px; line-height: 1.5; color: var(--text-secondary); }
.ng-review-txt b {
  display: block;
  margin-bottom: 3px;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--text-primary);
}

/* ----------------- Кнопки, заметки, ошибка ----------------- */
.ng .btn-primary { width: 100%; min-height: 48px; margin-top: 4px; }
.ng-soft {
  width: 100%;
  min-height: 46px;
  padding: 12px 18px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-primary);
  font: inherit;
  font-size: 14.5px;
  font-weight: 650;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.ng-soft:active { transform: scale(0.98); background: var(--surface-2); }
.ng .btn-primary:disabled, .ng-soft:disabled, .ng-choice:disabled { opacity: 0.65; }
.ng-choice.is-right:disabled, .ng-choice.is-miss:disabled, .ng-choice.is-dim:disabled { opacity: 1; }
.ng-choice.is-dim:disabled { opacity: 0.5; }

.ng-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-muted);
}
.ng-note i, .ng-note svg { flex: none; width: 15px; height: 15px; margin-top: 1px; }

.ng-error:not(:empty) {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 15px;
  border: 1px solid color-mix(in srgb, var(--color-danger) 30%, var(--border));
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--color-danger) 7%, var(--surface));
  font-size: 13.5px;
  line-height: 1.45;
}

.ng-choice:focus-visible,
.ng-soft:focus-visible,
.ng .btn-primary:focus-visible,
.ng-review summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

@media (max-width: 360px) {
  .ng h2 { font-size: 18px; }
  .ng .ng-prompt { font-size: 16.5px; }
  .ng-choice { padding: 12px; gap: 9px; font-size: 14px; }
  .ng-shot-cap { padding: 12px 13px; gap: 9px; font-size: 14px; }
  .ng-hero-ic { width: 56px; height: 56px; border-radius: 19px; }
  .ng-hero-ic i, .ng-hero-ic svg { width: 26px; height: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  .ng *, .ng *::before, .ng *::after { animation: none !important; transition: none !important; }
}

/* Learning library, comparison cards and editable teaching records. */
.ng-stage { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ng-stage > * { min-width: 0; }
.ng-modules { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.ng-module {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 16px; min-width: 0; border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface); color: var(--text-primary);
  text-align: left; font: inherit; cursor: pointer; transition: transform .18s, border-color .18s;
}
.ng-module:hover:not(:disabled) { border-color: var(--color-primary); transform: translateY(-2px); }
.ng-module:disabled { opacity: .6; cursor: default; }
.ng-module b { font-size: 15px; line-height: 1.3; overflow-wrap: anywhere; }
.ng-module > span:not(.ng-module-icon):not(.ng-module-progress) { font-size: 12.5px; line-height: 1.4; color: var(--text-secondary); }
.ng-module small { margin-top: auto; font-size: 11.5px; color: var(--text-muted); }
.ng-module-icon, .ng-scenario-icon, .ng-entry-icon {
  display: grid; place-items: center; flex: none; width: 42px; height: 42px;
  border-radius: 14px; color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, var(--surface));
}
.ng-module-icon svg, .ng-module-icon i, .ng-scenario-icon svg, .ng-scenario-icon i { width: 23px; height: 23px; }
.ng-module:nth-child(3n+2) .ng-module-icon { color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 12%, var(--surface)); }
.ng-module-progress { width: 100%; height: 4px; background: var(--fill-track); border-radius: 6px; overflow: hidden; }
.ng-module-progress i { display: block; height: 100%; background: var(--color-primary); }
.ng-daily {
  display: flex; flex-direction: column; gap: 8px; padding: 16px;
  border-radius: var(--r-lg); border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--border));
  background: linear-gradient(130deg, color-mix(in srgb, var(--color-primary) 9%, var(--surface)), var(--surface));
}
.ng-daily small { color: var(--color-primary); font-size: 12px; font-weight: 700; }
.ng-daily h3 { font-size: 19px; line-height: 1.25; margin: 0; }
.ng-daily p { font-size: 12px; line-height: 1.5; color: var(--text-secondary); }
.ng-collection { display: flex; gap: 9px; align-items: center; color: var(--text-secondary); font-size: 12px; line-height: 1.5; }
.ng-collection svg, .ng-collection i { width: 20px; height: 20px; flex: none; color: var(--color-primary); }
.ng-scenario { display: flex; flex-direction: column; gap: 14px; padding: 20px; border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface-2); }
.ng-scenario p { font-size: 15px; line-height: 1.55; }
.ng-choices.is-compare { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.ng-choices.is-compare.is-three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ng-choices.is-compare .ng-choice { flex-direction: column; justify-content: flex-start; align-items: center; padding: 16px 10px; text-align: center; }
.ng-choices.is-compare:not(.is-three) .ng-choice:last-child { grid-column: 1 / -1; flex-direction: row; padding: 13px; }
.ng-choice-txt small { display: block; font-size: 12px; margin-top: 6px; color: var(--text-secondary); }
.ng-choice-txt strong { display: block; font-size: 16px; margin-top: 10px; color: var(--text-primary); }
.ng-food-icon { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 18px; background: var(--surface-2); color: var(--color-accent); }
.ng-food-icon i, .ng-food-icon svg { width: 28px; height: 28px; }
.ng-choice.is-selected { border-color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 9%, var(--surface)); }
.ng-choice.is-selected .ng-key { background: var(--color-primary); color: #fff; }
.ng-key i, .ng-key svg { width: 14px; height: 14px; }
.ng-number-form { display: flex; flex-direction: column; gap: 10px; padding: 18px; border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); }
.ng-number-form label { color: var(--text-secondary); font-size: 13px; }
.ng-number-row { display: flex; align-items: center; gap: 12px; }
.ng-number-row input { width: 100%; min-width: 0; padding: 12px; border: 2px solid var(--border); border-radius: var(--r-md); background: var(--surface-2); color: var(--text-primary); font: inherit; font-size: 28px; font-weight: 750; }
.ng-number-row input:focus { outline: 0; border-color: var(--color-primary); }
.ng-number-row > span { flex: none; color: var(--text-secondary); font-size: 14px; }
.ng-text-button { border: 0; background: none; color: var(--text-secondary); font: inherit; font-size: 13px; padding: 10px; cursor: pointer; }
.ng-sources { margin-top: 5px; font-size: 12px; }
.ng-sources summary { cursor: pointer; color: var(--text-secondary); }
.ng-sources a { display: block; padding-top: 9px; color: var(--color-primary); overflow-wrap: anywhere; }
.ng-reward { display: flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: 8px; padding: 18px; border-radius: var(--r-lg); background: color-mix(in srgb, var(--color-primary) 10%, var(--surface)); color: var(--color-primary); }
.ng-reward span { flex-basis: 100%; text-align: center; color: var(--text-secondary); font-size: 13px; }
.ng-reward i, .ng-reward svg { width: 22px; height: 22px; }
.ng-entry { display: flex; width: 100%; gap: 12px; align-items: center; text-align: left; padding: 16px; border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); color: var(--text-primary); font: inherit; cursor: pointer; }
.ng-entry > span:nth-child(2) { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.ng-entry b { font-size: 14px; }
.ng-entry small { font-size: 11px; color: var(--color-primary); font-weight: 700; }
.ng-entry > span:nth-child(2) > span { font-size: 12px; line-height: 1.4; color: var(--text-secondary); }
.ng-entry > svg, .ng-entry > i { width: 17px; height: 17px; flex: none; color: var(--text-muted); }
.ng-entry-icon i, .ng-entry-icon svg { width: 24px; height: 24px; }
.ng-loop-entry {
  padding: 18px;
  border: 1px solid color-mix(in srgb, var(--color-primary) 22%, var(--border));
  border-radius: var(--r-lg);
  background: linear-gradient(145deg, color-mix(in srgb, var(--color-primary) 6%, var(--surface)), var(--surface));
}
.ng-loop-heading { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.ng-loop-heading > span { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 650; color: var(--text-secondary); }
.ng-loop-heading svg, .ng-loop-heading i { width: 16px; height: 16px; color: var(--color-primary); }
.ng-loop-heading small { font-size: 11px; color: var(--text-secondary); }
/* Вопрос и переход к нему — одна кнопка: рядом стоит «Записать еду», и без
   общего нажатия заголовок читается как подпись к чужому действию. */
.ng-curiosity { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 8px 12px; width: 100%; padding: 12px 10px 10px; margin: 0 -10px; border: 0; border-radius: var(--r-md); background: none; text-align: left; font: inherit; color: var(--text-primary); cursor: pointer; transition: background var(--dur) var(--ease), transform var(--dur) var(--ease); }
.ng-curiosity-ic { display: grid; place-items: center; flex: none; grid-row: span 2; width: 40px; height: 40px; border-radius: 50%; color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 12%, var(--surface)); }
.ng-curiosity-ic.has-badge { background: none; }
.ng-curiosity-ic img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ng-curiosity-ic i, .ng-curiosity-ic svg { width: 22px; height: 22px; }
.ng-curiosity b { font-size: 18px; font-weight: 750; line-height: 1.3; letter-spacing: -.3px; text-wrap: balance; }
.ng-curiosity > span:not(.ng-curiosity-ic) { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 650; color: var(--color-primary); }
.ng-curiosity > span:not(.ng-curiosity-ic) svg { width: 17px; height: 17px; transition: transform .2s ease; }
.ng-curiosity:hover { background: color-mix(in srgb, var(--color-primary) 7%, transparent); }
.ng-curiosity:hover > span:not(.ng-curiosity-ic) svg { transform: translateX(3px); }
.ng-curiosity:active { transform: scale(.985); background: color-mix(in srgb, var(--color-primary) 10%, transparent); }
.ng-curiosity:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ng-loop-note { margin: 4px 0 0; font-size: 12px; line-height: 1.45; color: var(--text-secondary); }
.ng-loop-entry > .btn-primary { margin-top: 14px; width: 100%; }
.ng-loop-entry > .ng-text-button { display: flex; align-items: center; gap: 6px; padding: 12px 0 0; }
.ng-loop-entry > .ng-text-button svg { width: 16px; height: 16px; }
.ng-meal-win { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; padding-bottom: 15px; border-bottom: 1px solid var(--border); }
.ng-meal-win > svg, .ng-meal-win > i { width: 32px; height: 32px; padding: 7px; border-radius: 50%; background: var(--color-primary); color: #fff; flex: none; }
.ng-meal-win > span { display: flex; flex-direction: column; gap: 4px; }
.ng-meal-win b { font-size: 15px; }
.ng-meal-win span span { font-size: 12px; color: var(--text-secondary); line-height: 1.4; }
.ng-just-saved .ng-meal-win > svg { animation: ngPop .5s var(--ease-spring) both; }
/* Тот же приём, что у «Играть» в библиотеке (.ng-daily): одинаковая мысль —
   одинаковая карточка, иначе два экрана предлагают раунд по-разному. */
.ng-next-round {
  padding: 16px;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--border));
  background: linear-gradient(130deg, color-mix(in srgb, var(--color-primary) 9%, var(--surface)), var(--surface));
}
.ng-next-round small { color: var(--color-primary); font-size: 12px; font-weight: 700; }
.ng-next-round h3 { margin: 7px 0 14px; font-size: 19px; line-height: 1.25; letter-spacing: -.3px; }
.ng-next-round .ng-soft { width: 100%; }
/* Бонус ждёт записи еды: янтарь — это ожидание, а не ошибка. Серой сноской
   рядом с зелёной наградой это читалось как «награды не будет». */
.ng-pending {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 4px 10px;
  padding: 14px 16px;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in srgb, var(--color-accent) 32%, var(--border));
  background: color-mix(in srgb, var(--color-accent) 8%, var(--surface));
}
.ng-pending i, .ng-pending svg { width: 20px; height: 20px; color: var(--color-accent); }
.ng-pending b { font-size: 14.5px; font-weight: 750; color: var(--color-accent); }
.ng-pending span { grid-column: 2; font-size: 12.5px; line-height: 1.45; color: var(--text-secondary); }
/* Последний вопрос в раунде: подпись уже сказала об этом словами, шапке
   остаётся только акцент на счётчике. */
.ng-bar.is-last .ng-bar-count { color: var(--color-primary); }
.ng-bar.is-last .ng-bar-count i { color: color-mix(in srgb, var(--color-primary) 60%, var(--text-muted)); }
/* ----------------- Знаки тем ----------------- */
/* Картинка занимает место контурной иконки целиком: подложка ей не нужна —
   круг нарисован в самом файле. Пока значок не загрузился (или не загрузится
   вовсе), в том же месте стоит иконка со своей плашкой. */
.ng-module-icon.has-badge, .ng-bar-ic.has-badge,
.ng-badge-ic.has-badge, .ng-entry-icon.has-badge { background: none; padding: 0; }
.ng-module-icon.has-badge img, .ng-bar-ic.has-badge img,
.ng-badge-ic.has-badge img, .ng-entry-icon.has-badge img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ----------------- Отклик на верный ответ ----------------- */
/* Ровно два места и по одному разу: кольцо у отмеченного ответа и лучи у
   собранного раунда. Бесконечных эффектов здесь нет намеренно — учебный экран
   читают, а не смотрят; язык лучей и четырёхлучевой звезды общий с лигами
   (league_fx.css), чтобы праздник в приложении был один. */
.ng-tick.is-hit { position: relative; }
.ng-tick.is-hit::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 2px solid var(--color-primary);
  animation: ngRing 0.6s var(--ease) both;
}
@keyframes ngRing {
  from { opacity: 0.8; transform: scale(0.65); }
  to { opacity: 0; transform: scale(1.5); }
}

.ng-hero.is-perfect .ng-hero-ic { position: relative; }
.ng-hero.is-perfect .ng-hero-ic::after {
  content: '';
  position: absolute;
  top: -7px;
  right: -10px;
  width: 15px;
  height: 15px;
  background: var(--color-accent);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
  animation: ngTwinkle 1s var(--ease) 0.2s both;
}
@keyframes ngTwinkle {
  0% { opacity: 0; transform: scale(0.3) rotate(0deg); }
  45% { opacity: 1; transform: scale(1) rotate(35deg); }
  100% { opacity: 0; transform: scale(0.75) rotate(70deg); }
}
/* Лучи держатся на маске: без неё вместо венчика был бы залитый круг под
   значком, поэтому рисуем их только там, где маска поддерживается. */
@supports ((-webkit-mask: radial-gradient(#000, #000)) or (mask: radial-gradient(#000, #000))) {
  .ng-hero.is-perfect .ng-hero-ic::before {
    content: '';
    position: absolute;
    inset: -19px;
    background: repeating-conic-gradient(from 9deg,
      color-mix(in srgb, var(--color-accent) 45%, transparent) 0deg 2.5deg,
      transparent 2.5deg 36deg);
    -webkit-mask: radial-gradient(closest-side, transparent 57%, #000 63%, #000 88%, transparent 94%);
    mask: radial-gradient(closest-side, transparent 57%, #000 63%, #000 88%, transparent 94%);
    animation: ngRays 0.9s var(--ease) both;
    pointer-events: none;
  }
}
@keyframes ngRays {
  0% { opacity: 0; transform: scale(0.55) rotate(-18deg); }
  35% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.16) rotate(8deg); }
}

/* Карточка входа живёт вне .ng, поэтому общий выключатель движения её не
   касается — гасим её анимации отдельно. */
@media (prefers-reduced-motion: reduce) {
  .ng-just-saved .ng-meal-win > svg { animation: none; }
  .ng-curiosity, .ng-curiosity svg { transition: none; }
  .ng-curiosity:hover > span svg, .ng-curiosity:active { transform: none; }
}

.ng-meal-entry { margin-top: 14px; }
.ng-module:focus-visible, .ng-text-button:focus-visible, .ng-entry:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }
@media (max-width: 360px) {
  .ng-curiosity b { font-size: 16.5px; }
  .ng-curiosity { gap: 6px 10px; }
  .ng-curiosity-ic { width: 34px; height: 34px; }
  .ng-next-round h3 { font-size: 17.5px; }
  .ng-loop-entry, .ng-next-round { padding: 14px; }
  .ng-meal-win { gap: 9px; }
  .ng-module { padding: 12px; }
  .ng-modules { gap: 9px; }
  .ng-module b { font-size: 13px; }
  .ng-module > span:not(.ng-module-icon):not(.ng-module-progress) { font-size: 12px; }
  .ng-choices.is-three .ng-choice { padding: 12px 7px; font-size: 12.5px; }
  .ng-choices.is-three .ng-food-icon { width: 40px; height: 40px; }
  .ng-choices.is-three .ng-choice-txt small { font-size: 11px; }
  .ng-scenario { padding: 16px; }
}

/* achievements.css */
/* =====================================================
   Витрина наград: «Ближайшие» строками, плитки по группам и
   сам значок достижения. Витрина одна на всё приложение — её
   открывают и профиль, и полка прогресса, поэтому второго
   списка достижений (строками) здесь больше нет.
   ===================================================== */

/* =====================================================
   Нарисованный бейдж достижения.
   Картинка (scripts/gen_achievement_badges.py) с запасной иконкой lucide, если
   она не загрузилась. Размер задаёт место показа, здесь — только поведение.
   Закрытым сервер отдаёт замок, поэтому гасить их фильтром не нужно.
   ===================================================== */

.ach-badge {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
}
.ach-badge-img { width: 100%; height: 100%; object-fit: contain; }
.ach-badge > i[data-lucide] {
  width: 62%;
  height: 62%;
  color: var(--color-accent);
}
.ach-badge.locked > i[data-lucide] { color: var(--text-muted); }

/* =====================================================
   Экран «Достижения» в профиле: плитки-бейджи по группам.
   Открытые — цветные, закрытые — с полосой прогресса.
   ===================================================== */

.ab-view { display: flex; flex-direction: column; gap: 10px; }

.ab-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
}
.ab-head > b { font-size: 20px; line-height: 1; }
.ab-head > span {
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-muted);
}

/* Связь с недельной таблицей: новый бейдж приносит баллы. Полоса зелёная, а не
   янтарная: это про баллы и лигу, а не про саму награду. */
.ab-bonus {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  font-size: 12px;
  font-weight: 600;
  color: color-mix(in srgb, var(--color-primary) 75%, var(--text-primary));
}
.ab-bonus > svg { flex: 0 0 auto; width: 14px; height: 14px; }

.ab-section {
  margin: 6px 0 -2px;
  padding: 0 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
}

/* -------- Печати сезонов -------- */
/* Награда третьего класса: не плоский бейдж и не камень ступени. Полученная —
   в цвете, непройденный сезон — серым силуэтом с датой: дыру в коллекции уже
   не закрыть, и это единственный честный способ показать дефицит. */
.ab-seals {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
}
.ab-seal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  box-sizing: border-box;
  padding: 12px 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: center;
}
.ab-seal.open {
  border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
  background: color-mix(in srgb, var(--color-accent) 5%, var(--surface));
}
.ab-seal-img { display: grid; place-items: center; width: 58px; height: 58px; }
.ab-seal-img img { width: 100%; height: 100%; object-fit: contain; }
/* Сезон без своей картинки (или она не загрузилась) — пустой оттиск, а не дыра. */
.ab-seal-img.none {
  border: 1.5px dashed var(--border-strong);
  border-radius: 50%;
}
.ab-seal:not(.open) .ab-seal-img img { filter: grayscale(0.9) opacity(0.45); }
.ab-seal-title { font-size: 12px; font-weight: 650; line-height: 1.25; }
.ab-seal:not(.open) .ab-seal-title { color: var(--text-secondary); }
.ab-seal-note { font-size: 10.5px; color: var(--text-muted); }
.ab-seal.open .ab-seal-note {
  color: color-mix(in srgb, var(--color-accent) 80%, var(--text-primary));
  font-weight: 700;
}

/* -------- Ближайшие награды -------- */
/* Три строки над сеткой: до чего осталось меньше всего. Значок здесь
   настоящий, а не замок, — это ответ на «что я получу», и картинка в нём
   половина ответа. */
.ab-soon {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.ab-soon-row { display: flex; align-items: center; gap: 12px; padding: 11px 15px; }
.ab-soon-row + .ab-soon-row { border-top: 1px solid var(--border); }
.ab-soon-badge { width: 34px; height: 34px; }
.ab-soon-body { flex: 1; min-width: 0; }
.ab-soon-title { display: block; font-size: 13.5px; font-weight: 650; }
.ab-soon-bar {
  display: block;
  height: 5px;
  margin-top: 6px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.ab-soon-bar > i {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--color-accent);
}
.ab-soon-prog {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.ab-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
}

.ab-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: center;
}
.ab-badge { width: 54px; height: 54px; }
.ab-title {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.25;
}
.ab-tile:not(.open) .ab-title { color: var(--text-secondary); }
.ab-done {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  font-weight: 700;
  color: var(--color-primary);
}
.ab-done > i { width: 12px; height: 12px; }
.ab-prog {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.ab-bar {
  display: block;
  height: 4px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.ab-bar > i {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--color-primary);
}

/* league.css */
/* =====================================================
   Лига и баллы недели. Спокойные плитки, никакой «зоны
   выбывания»: подсвечена только граница подъёма.
   ===================================================== */

.lg-view { display: flex; flex-direction: column; gap: 10px; }

/* -------- Значок ступени -------- */
/* Оправа: очень светлый круг в цвет ступени. Эмблема сама по себе яркая и с
   контуром, поэтому подложка нужна только чтобы значок держал форму на любом
   фоне. Она же — система координат для слоя эффектов (league_fx.css). */
.lg-badge {
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  color: var(--tint);
  background: color-mix(in srgb, var(--tint) 9%, var(--surface));
}
/* Эмблема слегка выходит за круг: так значок не выглядит наклейкой в кружке. */
.lg-badge-img {
  width: 104%;
  height: 104%;
  object-fit: contain;
  display: block;
}
.lg-badge > i[data-lucide] { width: 26px; height: 26px; }
.lg-badge-lg { width: 72px; height: 72px; }
.lg-badge-lg > i[data-lucide] { width: 34px; height: 34px; }
.lg-badge-sm { width: 40px; height: 40px; }
.lg-badge-sm > i[data-lucide] { width: 20px; height: 20px; }

/* -------- Шапка: своя лига крупно и живая -------- */
/* Первое, что видно при открытии раздела. Эмблема со своим эффектом, название
   лиги, свои баллы и место — дальше уже таблица. */
.lg-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px 0 12px;
  text-align: center;
}
.lg-badge-hero {
  width: 132px;
  height: 132px;
  --fx-k: 1.1px;
  margin-bottom: 4px;
  background: radial-gradient(circle at 50% 45%,
    color-mix(in srgb, var(--tint) 22%, transparent),
    transparent 68%);
}
.lg-badge-hero .lg-badge-img { width: 100%; height: 100%; }
.lg-hero-name {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.lg-hero-line { font-size: 15px; color: var(--text-secondary); }
.lg-hero-line b { font-size: 17px; color: var(--text-primary); }
.lg-hero-time { font-size: 12.5px; color: var(--text-muted); }

/* -------- Лента ступеней -------- */
/* Горизонтальный список всех лиг: своя подсвечена, любую можно посмотреть.
   Лента выходит за поля карточки, чтобы ступени доезжали до самого её края,
   и вылет обязан совпадать с полями: было -18px при полях в 16px, и на
   телефоне лента вылезала за экран на два пикселя. */
.lg-strip {
  display: flex;
  gap: 8px;
  margin: 0 -16px 4px;
  padding: 2px 16px 8px;
  overflow-x: auto;
  scrollbar-width: none;
}
/* На ПК подраздел — модалка со своими полями (web_desktop.css). */
@media (min-width: 900px) {
  .lg-strip { margin-inline: -22px; padding-inline: 22px; }
}
.lg-strip::-webkit-scrollbar { display: none; }
.lg-strip-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  width: 66px;
  padding: 8px 4px 6px;
  border: 1px solid transparent;
  border-radius: 16px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity var(--dur) var(--ease);
}
.lg-strip-item.mine { opacity: 0.85; }
.lg-strip-item.on {
  opacity: 1;
  border-color: color-mix(in srgb, var(--tint) 45%, transparent);
  background: color-mix(in srgb, var(--tint) 8%, var(--surface));
  color: var(--text-primary);
  font-weight: 600;
}
.lg-badge-xs { width: 34px; height: 34px; }
.lg-badge-xs > i[data-lucide] { width: 17px; height: 17px; }

/* -------- Смысл ступени и её перк -------- */
.lg-meaning { padding: 13px 16px; }
.lg-meaning-text { font-size: 14px; line-height: 1.4; }
.lg-perk {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--color-primary);
}
.lg-perk > i { width: 15px; height: 15px; }

/* -------- Заглушка платной части -------- */
.lg-lock {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 16px 16px;
  text-align: center;
}
.lg-lock-ic {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  color: #fff;
  background: linear-gradient(145deg, #fbbf24, #d97706);
}
.lg-lock-ic > i { width: 21px; height: 21px; }
.lg-lock-t { font-size: 15px; font-weight: 700; }
.lg-lock-x { font-size: 13px; line-height: 1.4; color: var(--text-secondary); }
.lg-lock .btn-primary { width: 100%; margin-top: 4px; }
.lg-lock-note { font-size: 11.5px; line-height: 1.35; color: var(--text-muted); }

/* -------- Лестница ступеней -------- */
.lg-ladder { display: flex; flex-direction: column; gap: 8px; }
.lg-step {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  opacity: 0.62;
}
.lg-step.done { opacity: 0.85; }
.lg-step.now {
  opacity: 1;
  border: 1px solid color-mix(in srgb, var(--color-primary) 45%, transparent);
}
.lg-step-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lg-step-info > b {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14.5px;
}
.lg-step-info > span {
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-secondary);
}
.lg-now {
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 15%, transparent);
  color: var(--color-primary);
  font-size: 10.5px;
  font-style: normal;
  font-weight: 700;
  text-transform: uppercase;
}
.lg-step-perk {
  font-size: 11.5px;
  font-style: normal;
  color: var(--text-muted);
}

/* Разрыв в местах (подиум → своя строка): не просто многоточие, а сколько
   человек между ними — league.js. */
.lg-gap {
  padding: 4px 16px 6px;
  color: var(--text-muted);
  font-size: 11.5px;
  text-align: center;
}
.lg-goal {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--color-primary);
  font-weight: 600;
}
.lg-goal > i { width: 14px; height: 14px; }

/* -------- Пояснения между блоками -------- */
.lg-note {
  padding: 0 4px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-muted);
}
.lg-section {
  margin: 8px 0 -2px;
  padding: 0 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
}

/* -------- Таблица -------- */
.lg-table { padding: 4px 0; overflow: hidden; }
.lg-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 14px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 14.5px;
  text-align: left;
  cursor: pointer;
}
.lg-row:active { background: color-mix(in srgb, var(--color-primary) 6%, transparent); }
.lg-row + .lg-row { border-top: 1px solid var(--border); }
/* Таблица «раздаётся» сверху вниз — короткая радость при каждом открытии
   экрана. backwards, а не forwards: если анимаций нет вовсе, строка просто
   стоит видимой на месте, а не остаётся прозрачной. */
@keyframes lg-row-in {
  from { opacity: 0; transform: translateY(6px); }
}
.lg-row {
  animation: lg-row-in 0.3s var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 28ms);
}
@media (prefers-reduced-motion: reduce) {
  .lg-row { animation: none; }
}
body.calm-preview .lg-row { animation: none; }
.lg-table-head { display: flex; align-items: baseline; gap: 8px; }
.lg-peek { font-size: 11.5px; font-style: normal; font-weight: 500;
  color: var(--text-muted); }
.lg-rank {
  display: grid;
  place-items: center;
  flex: 0 0 22px;
  height: 22px;
  border-radius: 50%;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--text-muted);
}
/* Подиум: первые три места — медали, а не цветные цифры. Цветом их различить не
   получалось: зона повышения красит целые строки, и в нижних лигах она
   накрывает весь подиум разом. */
.lg-row.m1 .lg-rank,
.lg-row.m2 .lg-rank,
.lg-row.m3 .lg-rank {
  color: #fff;
  font-size: 12px;
  /* Белая цифра на светлом металле теряется — тень возвращает ей контур. */
  text-shadow: 0 1px 1px rgba(15, 23, 42, 0.4);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.2);
}
/* Блик в левом верхнем углу — то, что отличает медаль от цветного кружка. */
.lg-row.m1 .lg-rank,
.lg-row.m2 .lg-rank,
.lg-row.m3 .lg-rank {
  background-image: radial-gradient(circle at 32% 24%,
    rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 52%);
}
.lg-row.m1 .lg-rank { background-color: #dd9316; }
.lg-row.m2 .lg-rank { background-color: #98a3b1; }
.lg-row.m3 .lg-rank { background-color: #b2703f; }
/* У первого места медаль ещё и светится — на весь экран это единственное
   место, где позволено похвастаться. */
.lg-row.m1 .lg-rank {
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.2),
    0 0 0 3px color-mix(in srgb, #f59e0b 16%, transparent);
}

/* Кружок с первой буквой имени (league.js): фотографий у участников нет, но
   десять одинаковых строк без единого пятна цвета читаются как ведомость. */
.lg-av {
  display: grid;
  place-items: center;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tint) 16%, var(--surface));
  color: color-mix(in srgb, var(--tint) 72%, var(--text-primary));
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}
.lg-av > i[data-lucide] { width: 15px; height: 15px; }
/* -------- Печать сезона в чужой строке -------- */
/* Единственная награда, которую видно НЕ в своём профиле. Кольцо вокруг
   кружка с буквой и маленькая печать у имени: тот, у кого её нет, замечает
   разницу, а объясняет её карточка участника. */
.lg-row.sealed .lg-av {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 70%, transparent);
}
/* Картинку печати подставляет разметка: сезон меняется четыре раза в год, и
   зашитый в стили файл через три месяца показывал бы прошлую осень. */
.lg-seal {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-left: 6px;
  background: center / contain no-repeat;
}

.lg-who {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
}
.lg-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Своя строка подписана словом, а не только подсветкой: в чужом списке имён
   человек ищет себя глазами, и заливка одна этого не решает. */
.lg-you {
  flex: 0 0 auto;
  margin-left: 6px;
  padding: 2px 6px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 18%, var(--surface));
  color: color-mix(in srgb, var(--color-primary) 62%, var(--text-primary));
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
}
/* Серия — единственный тёплый акцент в строке: рядом с зелёным он и держит
   таблицу от того, чтобы стать зелёно-белой. */
.lg-row-streak {
  flex: 0 0 auto;
  margin-left: 6px;
  font-size: 11.5px;
  font-style: normal;
  color: color-mix(in srgb, #f59e0b 55%, var(--text-muted));
}
.lg-points {
  flex: 0 0 auto;
  padding-left: 6px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
/* Первое место греется золотом: единственная строка, которой это позволено, —
   и таблица перестаёт быть ровным списком. */
.lg-row.m1 {
  background: linear-gradient(90deg,
    color-mix(in srgb, #f59e0b 11%, transparent), transparent 58%);
}
/* Зона повышения: не заливка строк, а тонкая рейка по левому краю. Залитый
   блок из десяти строк (в Бронзе наверх уходят все видимые места) спорил с
   белым и переставал что-либо значить; рейка читается как скобка «вот эти
   уходят выше» и стоит почти нисколько чернил. Рисуем её, только когда под
   чертой кто-то есть (league.js). */
.lg-row.up {
  box-shadow: inset 2px 0 0 color-mix(in srgb, var(--color-primary) 40%, transparent);
}
.lg-row.me {
  background: color-mix(in srgb, var(--color-primary) 9%, transparent);
  box-shadow: inset 3px 0 0 var(--color-primary);
  font-weight: 700;
}
.lg-row.me .lg-rank { color: var(--text-secondary); }

/* Граница подъёма: тонкая линия с подписью, куда ведёт. */
.lg-divider {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 16px;
  border-top: 1px dashed color-mix(in srgb, var(--color-primary) 45%, transparent);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--color-primary);
  text-transform: uppercase;
}
.lg-divider > i { width: 13px; height: 13px; }

.lg-empty {
  padding: 18px 16px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-secondary);
}

/* -------- Списки (мои баллы, правила) -------- */
.lg-list { overflow: hidden; }
.lg-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 11px 16px;
  font-size: 14px;
}
.lg-item + .lg-item { border-top: 1px solid var(--border); }
.lg-item-title { flex: 1 1 auto; }
.lg-item-detail { font-size: 12px; color: var(--text-muted); }
.lg-item-points {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--text-secondary);
}
/* В правилах справа стоит пояснение («+10, до 4 приёмов в день»), а не число —
   жирным оно перетягивало бы на себя всю строку. */
#lg-rules .lg-item-points {
  font-size: 12.5px;
  font-weight: 600;
  text-align: right;
}

.lg-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin: 6px 0 0;
  padding: 4px 2px;
  border: 0;
  background: none;
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}
.lg-toggle > i:first-child { width: 16px; height: 16px; color: var(--text-muted); }
.lg-toggle > span { flex: 1 1 auto; }
.lg-chev {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  transition: transform var(--dur) var(--ease);
}
.lg-toggle.open .lg-chev { transform: rotate(180deg); }

/* -------- Общий чат -------- */
.lg-chat {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--border);
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.lg-chat > i:first-child {
  width: 22px;
  height: 22px;
  color: var(--color-primary);
}
.lg-chat span {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
}
.lg-chat span span { font-size: 12.5px; color: var(--text-muted); }
.lg-chat-go { width: 16px; height: 16px; margin-left: auto; color: var(--text-muted); }

.lg-switch { padding: 4px 16px 12px; }
.lg-hint {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.35;
  color: var(--text-muted);
}

/* -------- Значок лиги в виджете серии на сводке -------- */
/* Ответ на «в какой я лиге» без отдельной карточки: маленькая эмблема справа.
   Здесь она без оправы: карточка серии и так белая, а круг в цвет ступени
   рядом с пламенем читался как вторая кнопка. Эмблема яркая и с контуром —
   на карточке держит форму сама. */
.streak-tier {
  display: grid;
  place-items: center;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  color: var(--tint);
}
.streak-tier > i { width: 16px; height: 16px; }
.streak-tier .lg-badge-img { width: 100%; height: 100%; }

/* Стенд /dev/league: «спокойный режим» кнопкой, без системной настройки. */
body.calm-preview .lg-badge.loud { animation: none; }
body.calm-preview .lg-badge-shine { opacity: 0; }

/* Закрытая лига: замок вместо эмблемы, серая подложка без подсветки. */
.lg-badge-locked {
  color: var(--text-muted);
  background: var(--surface-2);
}
.lg-badge-locked .lg-badge-img { filter: grayscale(0.25); }

/* league_details.css */
/* =====================================================
   Нижняя часть экрана лиги: свёрнутые блоки (разбор по
   дням, ступени, правила, чат) и карточка участника.
   Вынесено из league.css: там верхняя, «горячая» часть
   экрана, и держать всё в одном файле стало нечитаемо.
   ===================================================== */

/* -------- Свёрнутые блоки внизу экрана -------- */
.lg-fold { display: flex; flex-direction: column; gap: 8px; }
/* display перебивает атрибут hidden — без этой строки все блоки открыты. */
.lg-fold[hidden] { display: none; }
.lg-toggle > b {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--color-primary);
}
.lg-toggle > b + .lg-chev { margin-left: 8px; }

/* Разбор недели по дням: столбики кликабельны — внутри строки за что дали. */
.lg-days {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 12px 12px 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.lg-day {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.lg-day-bar {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 54px;
  border-radius: 6px;
  background: var(--surface-2);
  overflow: hidden;
}
.lg-day-bar > i {
  display: block;
  width: 100%;
  border-radius: 6px;
  background: color-mix(in srgb, var(--color-primary) 70%, transparent);
}
.lg-day.today .lg-day-bar > i { background: var(--color-primary); }
.lg-day.today .lg-day-name { color: var(--color-primary); font-weight: 700; }
.lg-day.future { opacity: 0.45; cursor: default; }
.lg-day-pts { font-variant-numeric: tabular-nums; font-weight: 600; }
.lg-day-head { text-align: center; padding: 4px 0 8px; }
.lg-day-head b { font-size: 26px; }

/* Строка разбора: заголовок с пояснением слева, «получено / максимум» справа. */
.lg-item-title > i {
  display: block;
  font-size: 11.5px;
  font-style: normal;
  line-height: 1.3;
  color: var(--text-muted);
}
.lg-item-points > i {
  margin-left: 3px;
  font-size: 12px;
  font-style: normal;
  font-weight: 500;
  color: var(--text-muted);
}
.lg-item.full .lg-item-points { color: var(--color-primary); }
.lg-item-value { font-size: 12.5px; font-weight: 600; text-align: right; }

/* -------- Карточка участника -------- */
.lgm-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 4px 0 10px;
  text-align: center;
}
.lgm-name { font-size: 20px; font-weight: 800; }
.lgm-tier { font-size: 13.5px; color: var(--text-secondary); }
.lgm-facts { display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; }
.lgm-fact { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.lgm-fact > i { width: 16px; height: 16px; color: var(--text-muted); }
.lgm-badges { display: flex; flex-wrap: wrap; gap: 8px; }
.lgm-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-size: 12.5px;
}
.lgm-badge-ico { width: 22px; height: 22px; margin: -3px 0; }

/* Как добрать баллы: действие, цена, короткая подсказка. */
.lg-tips { padding: 4px 0; }
.lg-tip {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
}
.lg-tip + .lg-tip { border-top: 1px solid var(--hairline); }
.lg-tip > [data-lucide] { width: 18px; height: 18px; color: var(--accent); flex: none; }
.lg-tip-t { flex: 1; min-width: 0; font-size: 14px; }
.lg-tip-t i {
  display: block; font-style: normal;
  font-size: 12px; color: var(--text-muted); margin-top: 2px;
}
.lg-tip-p {
  flex: none; font-size: 15px; font-weight: 700;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.lg-more {
  width: 100%; display: flex; align-items: center; justify-content: center;
  gap: 4px; padding: 10px; border: 0; background: none;
  border-top: 1px solid var(--hairline);
  color: var(--text-muted); font-size: 13px; cursor: pointer;
}
.lg-more.open .lg-chev { transform: rotate(180deg); }
.lg-tips .lg-fold { padding: 0; }
.lg-zero { margin-bottom: 10px; }

/* league_fx.css */
/* =====================================================
   Эффект ступени: у каждой свой и про её эмблему.
   Один слой на два места — шапку раздела «Лига» и
   поздравление с подъёмом, — поэтому все расстояния
   заданы через --fx-k: множитель подгоняет эффект под
   размер значка, а геометрия остаётся общей.
   ===================================================== */

.lg-fx {
  position: absolute;
  inset: -35%;
  overflow: visible;
  pointer-events: none;
  --fx-k: 1px;
}
.lg-fx > i {
  position: absolute;
  display: block;
  opacity: 0;
}

/* Четырёхлучевая звёздочка: круг читался бы как пузырь, а он занят сапфиром. */
.lg-fx .fx-star {
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%,
    41% 59%, 0% 50%, 41% 41%);
}

@keyframes fxTwinkle {
  0%, 100% { opacity: 0; transform: scale(.35) rotate(0deg); }
  50% { opacity: 1; transform: scale(1.1) rotate(45deg); }
}
@keyframes fxSweep {
  0%, 58% { opacity: 0; transform: translateX(0) rotate(20deg); }
  63% { opacity: .95; }
  100% { opacity: 0; transform: translateX(calc(var(--fx-k) * 210)) rotate(20deg); }
}

/* -------- Бронза: крошки от надкусанного крекера -------- */
.lg-fx[data-tier="bronze"] > i {
  top: 62%;
  width: calc(var(--fx-k) * 9);
  height: calc(var(--fx-k) * 8);
  border-radius: calc(var(--fx-k) * 3);
  background: linear-gradient(140deg, #d97706, #92400e);
  animation: fxCrumb 2.8s ease-in infinite;
}
.lg-fx[data-tier="bronze"] > i:nth-child(1) { left: 30%; animation-delay: 0s; }
.lg-fx[data-tier="bronze"] > i:nth-child(2) { left: 64%; animation-delay: .5s; }
.lg-fx[data-tier="bronze"] > i:nth-child(3) { left: 70%; animation-delay: 1.1s; }
.lg-fx[data-tier="bronze"] > i:nth-child(4) { left: 24%; animation-delay: 1.7s; }
.lg-fx[data-tier="bronze"] > i:nth-child(n+5) { display: none; }
@keyframes fxCrumb {
  0% { opacity: 0; transform: translateY(calc(var(--fx-k) * -12)) rotate(0deg); }
  22% { opacity: .95; }
  75% { opacity: .9; }
  100% { opacity: 0; transform: translateY(calc(var(--fx-k) * 46)) rotate(210deg); }
}

/* -------- Серебро: блик по гладкой скорлупе -------- */
.lg-fx[data-tier="silver"] > i:nth-child(1) {
  top: 4%;
  left: -30%;
  width: calc(var(--fx-k) * 34);
  height: 92%;
  background: linear-gradient(90deg, transparent,
    rgba(255, 255, 255, 0.9), transparent);
  transform: rotate(20deg);
  animation: fxSweep 3.6s ease-in-out infinite;
}
.lg-fx[data-tier="silver"] > i:nth-child(2),
.lg-fx[data-tier="silver"] > i:nth-child(3) {
  width: calc(var(--fx-k) * 13);
  height: calc(var(--fx-k) * 13);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%,
    41% 59%, 0% 50%, 41% 41%);
  background: linear-gradient(140deg, #fff, #cbd5e1);
  animation: fxTwinkle 2.4s ease-in-out infinite;
}
.lg-fx[data-tier="silver"] > i:nth-child(2) { top: 24%; left: 20%; animation-delay: .3s; }
.lg-fx[data-tier="silver"] > i:nth-child(3) { top: 58%; left: 74%; animation-delay: 1.2s; }
.lg-fx[data-tier="silver"] > i:nth-child(n+4) { display: none; }

/* -------- Золото: капля мёда срывается с соты -------- */
.lg-fx[data-tier="gold"] > i:nth-child(1) {
  top: 58%;
  left: 47%;
  width: calc(var(--fx-k) * 13);
  height: calc(var(--fx-k) * 17);
  border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%;
  background: linear-gradient(180deg, #fbbf24, #d97706);
  animation: fxDrip 3.4s cubic-bezier(0.6, 0, 0.9, 0.4) infinite;
}
.lg-fx[data-tier="gold"] > i:nth-child(2),
.lg-fx[data-tier="gold"] > i:nth-child(3) {
  width: calc(var(--fx-k) * 12);
  height: calc(var(--fx-k) * 12);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%,
    41% 59%, 0% 50%, 41% 41%);
  background: linear-gradient(140deg, #fff, #fbbf24);
  animation: fxTwinkle 2.6s ease-in-out infinite;
}
.lg-fx[data-tier="gold"] > i:nth-child(2) { top: 20%; left: 18%; animation-delay: .2s; }
.lg-fx[data-tier="gold"] > i:nth-child(3) { top: 52%; left: 76%; animation-delay: 1.1s; }
.lg-fx[data-tier="gold"] > i:nth-child(n+4) { display: none; }
@keyframes fxDrip {
  0%, 25% { opacity: 0; transform: translateY(0) scaleY(.6); }
  35% { opacity: 1; transform: translateY(calc(var(--fx-k) * 4)) scaleY(1); }
  85% { opacity: .9; }
  100% { opacity: 0; transform: translateY(calc(var(--fx-k) * 40)) scaleY(1.4); }
}

/* -------- Сапфир: пузырьки, как в лесной ягоде -------- */
.lg-fx[data-tier="sapphire"] > i {
  top: 72%;
  width: calc(var(--fx-k) * 11);
  height: calc(var(--fx-k) * 11);
  border-radius: 50%;
  border: 1.5px solid rgba(96, 165, 250, 0.95);
  background: rgba(191, 219, 254, 0.4);
  animation: fxBubble 4s ease-in infinite;
}
.lg-fx[data-tier="sapphire"] > i:nth-child(1) { left: 24%; animation-delay: 0s; }
.lg-fx[data-tier="sapphire"] > i:nth-child(2) { left: 70%; animation-delay: .8s; }
.lg-fx[data-tier="sapphire"] > i:nth-child(3) { left: 16%; animation-delay: 1.6s; }
.lg-fx[data-tier="sapphire"] > i:nth-child(4) { left: 78%; animation-delay: 2.4s; }
.lg-fx[data-tier="sapphire"] > i:nth-child(n+5) { display: none; }
@keyframes fxBubble {
  0% { opacity: 0; transform: translateY(0) translateX(0); }
  20% { opacity: .95; }
  80% { opacity: .8; }
  100% { opacity: 0;
    transform: translateY(calc(var(--fx-k) * -60)) translateX(calc(var(--fx-k) * 8)); }
}

/* -------- Рубин: вспышки на гранях -------- */
.lg-fx[data-tier="ruby"] > i {
  width: calc(var(--fx-k) * 18);
  height: calc(var(--fx-k) * 18);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%,
    41% 59%, 0% 50%, 41% 41%);
  background: linear-gradient(140deg, #fff, #fb7185);
  animation: fxTwinkle 2.2s ease-in-out infinite;
}
.lg-fx[data-tier="ruby"] > i:nth-child(1) { top: 18%; left: 16%; animation-delay: 0s; }
.lg-fx[data-tier="ruby"] > i:nth-child(2) { top: 46%; left: 78%; animation-delay: .6s; }
.lg-fx[data-tier="ruby"] > i:nth-child(3) { top: 72%; left: 22%; animation-delay: 1.2s; }
.lg-fx[data-tier="ruby"] > i:nth-child(4) { top: 8%; left: 62%; animation-delay: 1.7s; }
.lg-fx[data-tier="ruby"] > i:nth-child(n+5) { display: none; }

/* -------- Изумруд: листья планируют вниз -------- */
.lg-fx[data-tier="emerald"] > i {
  top: 46%;
  width: calc(var(--fx-k) * 16);
  height: calc(var(--fx-k) * 10);
  border-radius: 0 100% 0 100%;
  background: linear-gradient(135deg, #34d399, #059669);
  animation: fxLeaf 4.4s ease-in infinite;
}
.lg-fx[data-tier="emerald"] > i:nth-child(1) { left: 18%; animation-delay: 0s; }
.lg-fx[data-tier="emerald"] > i:nth-child(2) { left: 72%; animation-delay: 1.4s; }
.lg-fx[data-tier="emerald"] > i:nth-child(3) { left: 12%; animation-delay: 2.8s; }
.lg-fx[data-tier="emerald"] > i:nth-child(n+4) { display: none; }
@keyframes fxLeaf {
  0% { opacity: 0; transform: translate(0, calc(var(--fx-k) * -14)) rotate(0deg); }
  18% { opacity: .95; }
  78% { opacity: .9; }
  100% { opacity: 0;
    transform: translate(calc(var(--fx-k) * 18), calc(var(--fx-k) * 52)) rotate(200deg); }
}

/* -------- Бриллиант: радужные блики бегут по граням -------- */
.lg-fx[data-tier="diamond"] > i:nth-child(1) {
  top: 2%;
  left: -30%;
  width: calc(var(--fx-k) * 46);
  height: 96%;
  background: linear-gradient(90deg, transparent,
    rgba(125, 211, 252, .55), rgba(255, 255, 255, .92),
    rgba(196, 181, 253, .55), transparent);
  transform: rotate(20deg);
  animation: fxSweep 2.8s ease-in-out infinite;
}
.lg-fx[data-tier="diamond"] > i:nth-child(n+2) {
  width: calc(var(--fx-k) * 20);
  height: calc(var(--fx-k) * 20);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%,
    41% 59%, 0% 50%, 41% 41%);
  background: linear-gradient(140deg, #fff, #38bdf8);
  animation: fxTwinkle 2.6s ease-in-out infinite;
}
.lg-fx[data-tier="diamond"] > i:nth-child(2) { top: 10%; left: 14%; animation-delay: .1s; }
.lg-fx[data-tier="diamond"] > i:nth-child(3) { top: 44%; left: 80%; animation-delay: .9s; }
.lg-fx[data-tier="diamond"] > i:nth-child(4) { top: 76%; left: 20%; animation-delay: 1.5s;
  background: linear-gradient(140deg, #fff, #c084fc); }
.lg-fx[data-tier="diamond"] > i:nth-child(n+5) { display: none; }

/* Значок дышит по-своему: у каждой ступени свой характер движения. */
.lg-anim[data-tier] > .lg-badge-img { animation-delay: .9s; animation-iteration-count: infinite; }
.lg-anim[data-tier="bronze"] > .lg-badge-img { animation-name: fxBob; animation-duration: 2.6s; }
.lg-anim[data-tier="silver"] > .lg-badge-img { animation-name: fxWobble; animation-duration: 3.4s; }
.lg-anim[data-tier="gold"] > .lg-badge-img { animation-name: fxBob; animation-duration: 3s; }
.lg-anim[data-tier="sapphire"] > .lg-badge-img { animation-name: fxFloat; animation-duration: 3.6s; }
.lg-anim[data-tier="ruby"] > .lg-badge-img { animation-name: fxPulse; animation-duration: 2.8s; }
.lg-anim[data-tier="emerald"] > .lg-badge-img { animation-name: fxFloat; animation-duration: 4s; }
.lg-anim[data-tier="diamond"] > .lg-badge-img { animation-name: fxShimmer; animation-duration: 3.2s; }
.lg-anim > .lg-badge-img { animation-timing-function: ease-in-out; }

@keyframes fxBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}
@keyframes fxWobble {
  0%, 100% { transform: rotate(-3deg); }
  50% { transform: rotate(3deg); }
}
@keyframes fxFloat {
  0%, 100% { transform: translateY(0) rotate(-1.5deg); }
  50% { transform: translateY(-6px) rotate(1.5deg); }
}
@keyframes fxPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}
@keyframes fxShimmer {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.14) saturate(1.1); }
}

/* Спокойный режим и стенд: движения нет вовсе. */
@media (prefers-reduced-motion: reduce) {
  .lg-fx { display: none; }
  .lg-anim > .lg-badge-img { animation: none; }
}
body.calm-preview .lg-fx { display: none; }
body.calm-preview .lg-anim > .lg-badge-img { animation: none; }

/* league_celebrate.css */
/* =====================================================
   Поздравление с подъёмом в лигу (league_celebrate.js).
   Появляется раз в неделю максимум — здесь можно и нужно
   быть заметным, но без мигания и без тряски.
   ===================================================== */

.lgc {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(9, 12, 17, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: lgcIn 0.22s ease-out both;
}
.lgc.out { animation: lgcOut 0.2s ease-in both; }
@keyframes lgcIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes lgcOut { from { opacity: 1; } to { opacity: 0; } }

.lgc-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.lgc-card {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: min(340px, 100%);
  padding: 26px 22px 20px;
  border-radius: 26px;
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  text-align: center;
  overflow: hidden;
  animation: lgcCard 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes lgcCard {
  from { opacity: 0; transform: translateY(18px) scale(0.94); }
  to { opacity: 1; transform: none; }
}



.lgc-badge {
  position: relative;
  /* Эффект ступени крупнее, чем в шапке: карточка поздравления больше. */
  --fx-k: 1.15px;
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  color: #fff;
  color: var(--tint);
  /* У поздравления подложки нет: эмблема — главный герой экрана, и круг вокруг
     неё только уменьшал бы её. */
  background: none;
  animation: lgcBadge 0.75s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
}
.lgc-badge > i { width: 42px; height: 42px; }
.lgc-badge .lg-badge-img { width: 100%; height: 100%; }
@keyframes lgcBadge {
  0% { opacity: 0; transform: scale(0.3) rotate(-25deg); }
  60% { opacity: 1; transform: scale(1.12) rotate(4deg); }
  100% { opacity: 1; transform: none; }
}

.lgc-kicker {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.lgc-name {
  font-size: 27px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.lgc-meaning {
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-secondary);
}
.lgc-perk {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--tint) 12%, transparent);
  color: color-mix(in srgb, var(--tint) 75%, var(--text-primary));
  font-size: 12.5px;
  font-weight: 700;
}
.lgc-perk > i { width: 15px; height: 15px; }
.lgc-sub { font-size: 12.5px; color: var(--text-muted); }
.lgc-ok { width: 100%; margin-top: 8px; }

/* Спокойный режим: никакого движения, только карточка. */
@media (prefers-reduced-motion: reduce) {
  .lgc, .lgc-card, .lgc-badge { animation: none; }
}

/* Камень в поздравлении крупнее: это главный герой экрана. */

/* streak_celebrate.css */
/* =====================================================
   Праздник большой вехи серии (streak_celebrate.js).
   Месяц, сотня и годовщины — реже, чем подъём в лигу,
   поэтому здесь можно громче. Но без мигания и тряски.
   ===================================================== */

.stc {
  position: fixed;
  inset: 0;
  z-index: 121;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(9, 12, 17, 0.68);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: stcIn 0.24s ease-out both;
}
.stc.out { animation: stcOut 0.2s ease-in both; }
@keyframes stcIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes stcOut { from { opacity: 1; } to { opacity: 0; } }

.stc-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.stc-card {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: min(340px, 100%);
  padding: 26px 22px 20px;
  border-radius: 26px;
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  text-align: center;
  animation: stcCard 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes stcCard {
  from { opacity: 0; transform: translateY(18px) scale(0.94); }
  to { opacity: 1; transform: none; }
}

/* Пламя — главный герой карточки, поэтому без подложки и крупнее, чем где бы
   то ни было ещё. Салют над ним отыгрывает flame.js: холст снопа выходит за
   границы значка, и карточка его не подрезает. */
.stc-flame {
  position: relative;
  width: 120px;
  height: 120px;
  animation: stcFlame 0.75s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
}
/* Тёплое свечение за пламенем — дышит, как в виджете, только шире. */
.stc-flame::before {
  content: '';
  position: absolute;
  inset: -18px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(250, 131, 41, 0.3), transparent 70%);
  animation: glowPulse 2.2s ease-in-out infinite;
}
@keyframes stcFlame {
  0% { opacity: 0; transform: scale(0.3); }
  60% { opacity: 1; transform: scale(1.1); }
  100% { opacity: 1; transform: none; }
}

.stc-kicker {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.stc-days {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
/* Число крупнее слов: с расстояния читается именно оно. */
.stc-days b {
  font-size: 40px;
  font-weight: 800;
  vertical-align: -3px;
  background: linear-gradient(180deg, #fee49b, #fa8329);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.stc-meaning {
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-secondary);
}
.stc-ok { width: 100%; margin-top: 10px; }

/* Спокойный режим: никакого движения, только карточка. */
@media (prefers-reduced-motion: reduce) {
  .stc, .stc-card, .stc-flame { animation: none; }
  .stc-flame::before { animation: none; }
}

/* diet_report.css */
/* Разбор питания за неделю: карточки нутриентов, план и источники.
   Столбики дней рисуются div'ами, а не canvas: их восемь на карточку и они
   статичные, а canvas на каждый нутриент означал бы восемь контекстов и
   перерисовку при каждом открытии. */

.rp { display: flex; flex-direction: column; gap: 18px; padding-bottom: 24px; }

.rp-head { display: flex; flex-direction: column; gap: 8px; }
.rp-period { font-size: 13px; color: var(--text-muted); }
.rp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rp-chip {
  font-size: 12px; padding: 4px 10px; border-radius: 999px;
  background: var(--card-2, rgba(127,127,127,.12)); color: var(--text);
}

.rp-block { display: flex; flex-direction: column; gap: 10px; }
.rp-block h3 { font-size: 15px; margin: 0; }
.rp-until { font-size: 12px; color: var(--text-muted); margin: -4px 0 0; }
.rp-empty { font-size: 14px; color: var(--text-muted); margin: 0; }

/* --- План --- */
.rp-action {
  display: grid; grid-template-columns: 26px 1fr; gap: 10px;
  padding: 12px; border-radius: 12px;
  background: var(--card, rgba(127,127,127,.08));
}
.rp-action-num {
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600;
  background: var(--accent, #34c759); color: #fff;
}
.rp-action-body { display: flex; flex-direction: column; gap: 4px; }
.rp-action-body h4 { margin: 0; font-size: 14px; }
.rp-action-what { margin: 0; font-size: 14px; }
.rp-action-why, .rp-action-effect {
  margin: 0; font-size: 12.5px; color: var(--text-muted);
}

/* --- Цели --- */
.rp-goal-row { display: flex; flex-direction: column; gap: 5px; }
.rp-goal-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 13px;
}
.rp-goal-head b { font-variant-numeric: tabular-nums; }
.rp-goal-track {
  height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--fill-track, rgba(127,127,127,.2));
}
.rp-goal-fill { height: 100%; background: var(--accent, #34c759); }

/* --- Источники --- */
.rp-source {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--card, rgba(127,127,127,.08));
}
.rp-source-head {
  display: flex; justify-content: space-between; gap: 10px; font-size: 14px;
}
.rp-source-head b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.rp-source-names { font-size: 12px; color: var(--text-muted); }

/* --- Нутриенты --- */
.rp-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}
.rp-card {
  padding: 12px; border-radius: 12px;
  background: var(--card, rgba(127,127,127,.08));
  display: flex; flex-direction: column; gap: 8px;
}
.rp-card h4 { margin: 0; font-size: 13px; color: var(--text-muted); }
.rp-value {
  font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.rp-goal { font-size: 12px; font-weight: 400; color: var(--text-muted); }
.rp-nodata { font-size: 12.5px; color: var(--text-muted); }

/* Колонки делят ширину карточки поровну и ужимаются вместе с ней: grid на
   `repeat(7, 1fr)` не давал колонке стать уже своего содержимого, поэтому
   график распирало числами и подписи уезжали на соседнюю карточку. Заодно
   раскладка перестала зависеть от того, сколько дней в периоде. */
.rp-bars { display: flex; gap: 4px; align-items: end; }
.rp-bar-col {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
/* Трек тянется на всю колонку, столбик центрируется внутри: без явной ширины
   у трека столбик с width:100% считал бы проценты от нулевой ширины. */
.rp-bar-track {
  width: 100%; height: 64px;
  display: flex; align-items: flex-end; justify-content: center;
}
.rp-bar {
  width: 100%; max-width: 12px; border-radius: 3px 3px 0 0;
  background: var(--accent, #34c759);
}
.rp-bar-empty { background: var(--fill-track, rgba(127,127,127,.25)); }
.rp-bar-day {
  font-size: 10px; color: var(--text-muted);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rp-bars-unit {
  font-size: 11px; color: var(--text-muted); text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- Ожидание --- */
.rp-wait { gap: 12px; }
.rp-wait-title { margin: 0; font-size: 15px; font-weight: 600; }
.rp-wait-note { margin: 0; font-size: 13.5px; color: var(--text-muted); }

/* --- Цель действия и итоги прошлой недели --- */
.rp-measure {
  margin-top: 6px; padding-top: 8px;
  border-top: 1px dashed var(--line, rgba(127,127,127,.25));
  display: flex; flex-direction: column; gap: 5px;
}
.rp-measure-head {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: 12.5px; color: var(--text-muted);
}
.rp-measure-head b { color: var(--text); font-variant-numeric: tabular-nums; }
.rp-measure-now { font-size: 11.5px; color: var(--text-muted); }

.rp-done {
  display: flex; flex-direction: column; gap: 5px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--card, rgba(127,127,127,.08));
}
.rp-done-head {
  display: flex; justify-content: space-between; gap: 10px; font-size: 13.5px;
}
.rp-done-head b { font-variant-numeric: tabular-nums; }
.rp-done-note { font-size: 11.5px; color: var(--text-muted); }
.rp-done-ok .rp-goal-fill { background: var(--accent, #34c759); }
.rp-done-up .rp-goal-fill { background: var(--warn, #ff9f0a); }
.rp-done-flat .rp-goal-fill { background: var(--fill-track, rgba(127,127,127,.3)); }

/* meal_plan.css */
/* План питания: лента дней, карточки приёмов, замена блюда, покупки, настройка.
   Префикс .mp-. Цвета — только токены темы, чтобы тёмная тема Telegram
   не требовала отдельных правил.

   Плотность (переделка 29.09.2026): на первом экране телефона должны влезать
   день и все его приёмы. Поэтому карточка в покое — две строки (что за блюдо и
   из чего), КБЖУ и рецепт раскрываются по нажатию, а покупки, файл и заметки
   живут ниже приёмов свёрнутыми строками. */

.mp { display: flex; flex-direction: column; gap: 10px; padding-bottom: 28px; }
.mp .spin { animation: mp-spin 0.9s linear infinite; }
.mp svg { flex: 0 0 auto; }

/* --- лента дней ---
   overflow-x прокрутки режет всё за краем ленты, в том числе тень выбранного
   дня (0 4px 12px: 8px вверх, 16px вниз, 12px вбок). Поэтому поле под тень —
   внутренним отступом, а отрицательные поля возвращают ленту на прежнее место. */
.mp-strip {
  display: flex; gap: 6px; overflow-x: auto;
  margin: -6px -12px -14px; padding: 8px 12px 16px;
  scrollbar-width: none;
}
.mp-strip::-webkit-scrollbar { display: none; }
.mp-dchip {
  flex: 0 0 auto; min-width: 58px; padding: 6px 10px; border-radius: 12px;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  border: 1px solid var(--border, #e7e9ee); background: var(--surface, #fff);
  color: var(--text-secondary, #5b6470); font: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--dur, .22s) ease, border-color var(--dur, .22s) ease;
}
.mp-dchip b { font-size: 13px; font-weight: 600; }
.mp-dchip small {
  display: inline-flex; align-items: center; min-height: 14px;
  font-size: 11px; color: var(--text-muted, #98a1ad);
}
.mp-dchip small svg { width: 13px; height: 13px; color: var(--color-primary, #22c55e); }
.mp-dchip.active {
  background: var(--color-primary, #22c55e); border-color: transparent; color: #fff;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--color-primary, #22c55e) 30%, transparent);
}
.mp-dchip.active small, .mp-dchip.active small svg { color: rgba(255,255,255,.85); }
.mp-dchip:active { transform: scale(0.96); }

/* Цвета приёмов — те же, что в файле плана: тип видно, не читая. */
.mp-m-breakfast { --meal: #f59e0b; }
.mp-m-lunch { --meal: #f2674a; }
.mp-m-dinner { --meal: #d9468f; }
.mp-m-snack { --meal: #22a06b; }

/* --- шапка дня ---
   Вместо строки серых цифр (29.09, «скучно выглядит»): калории крупно на
   тёплой подложке в тон Зуму, БЖУ плашками, у сегодня — ход дня. */
.mp-hero {
  display: flex; flex-direction: column; gap: 10px; padding: 12px 14px;
  border-radius: 16px; border: 1px solid var(--border, #e7e9ee);
  background: linear-gradient(135deg,
    color-mix(in srgb, #ff7057 9%, var(--surface, #fff)),
    color-mix(in srgb, #ffce54 13%, var(--surface, #fff)));
}
.mp-hero-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mp-hero-kcal { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.mp-hero-kcal b {
  font-size: 28px; font-weight: 800; line-height: 1; letter-spacing: -0.02em;
  color: var(--text-primary, #11151c); font-variant-numeric: tabular-nums;
}
.mp-hero-kcal span { font-size: 12.5px; color: var(--text-secondary, #5b6470); }
.mp-hero-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  font-size: 12px; color: var(--text-secondary, #5b6470); white-space: nowrap;
}
.mp-hero-meta span { display: inline-flex; align-items: center; gap: 4px; }
.mp-hero-meta svg { width: 13px; height: 13px; color: #f2674a; }
.mp-hero-chips { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 6px; }
.mp-chipn {
  display: flex; flex-direction: column; align-items: center; gap: 0; padding: 5px 2px;
  border-radius: 10px; background: color-mix(in srgb, var(--tile, #8e8e93) 13%, var(--surface, #fff));
}
.mp-chipn b { font-size: 15px; font-weight: 700; color: var(--text-primary, #11151c); font-variant-numeric: tabular-nums; }
.mp-chipn small { font-size: 10.5px; color: var(--text-secondary, #5b6470); }
.mp-hero-prog { display: flex; align-items: center; gap: 10px; }
.mp-hero-bar, .mp-row-bar {
  display: block; flex: 1; height: 6px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--text-muted, #98a1ad) 24%, transparent);
}
.mp-hero-bar i, .mp-row-bar i {
  display: block; height: 100%; border-radius: inherit; background: var(--color-primary, #22c55e);
  transition: width .4s var(--ease, ease);
}
.mp-hero-prog em { font-style: normal; font-size: 12px; color: var(--text-secondary, #5b6470); white-space: nowrap; }
.mp-adapt {
  margin: 0; display: flex; align-items: center; gap: 6px; padding: 7px 10px;
  border-radius: 10px; font-size: 12.5px; color: var(--text-secondary, #5b6470);
  background: color-mix(in srgb, var(--color-primary-2, #38bdf8) 10%, transparent);
}
.mp-adapt svg { width: 14px; height: 14px; color: var(--color-primary-2, #38bdf8); }

/* --- карточка приёма --- */
.mp-cards { display: flex; flex-direction: column; gap: 8px; }
.mp-card {
  position: relative; border-radius: 16px; border: 1px solid var(--border, #e7e9ee);
  background: var(--surface, #fff); padding: 10px 12px 12px 14px;
  display: flex; flex-direction: column; gap: 6px;
  transition: background var(--dur, .22s) ease, border-color var(--dur, .22s) ease;
}
/* Полоска цвета приёма слева, как в файле. */
.mp-card::before {
  content: ""; position: absolute; left: -1px; top: 14px; bottom: 14px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--meal, var(--color-primary, #22c55e));
}
.mp-card.mp-enter {
  animation: mp-card-in 0.3s var(--ease, ease) backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes mp-card-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.mp-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 30px; }
.mp-kind {
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 5px; min-width: 0;
  font-size: 12px; color: var(--text-muted, #98a1ad); font-variant-numeric: tabular-nums;
}
.mp-kind svg { width: 15px; height: 15px; color: var(--meal, var(--color-primary, #22c55e)); }
.mp-kind b { font-weight: 700; color: var(--meal, var(--text-secondary, #5b6470)); }
.mp-kind span::before { content: "·"; margin-right: 5px; }

/* Зум у блюда: на подложке цвета приёма, у съеденного — с галочкой. */
.mp-card-main.has-zum { flex-direction: row; align-items: center; gap: 12px; }
.mp-card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mp-zum {
  position: relative; flex: 0 0 auto; width: 56px; height: 56px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--meal, #8e8e93) 13%, transparent);
}
.mp-zum img { width: 52px; height: 52px; object-fit: contain; }
.mp-zum-ok {
  position: absolute; right: -4px; bottom: -4px; width: 20px; height: 20px; padding: 3px;
  box-sizing: border-box; border-radius: 50%; border: 2px solid var(--surface, #fff);
  background: var(--color-primary, #22c55e); color: #fff;
}
.mp-card.is-eaten .mp-zum img, .mp-card.is-covered .mp-zum img { opacity: .6; filter: saturate(.5); }
.mp-acts { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }

.mp-card-main {
  position: relative; display: flex; flex-direction: column; gap: 2px; width: 100%;
  padding: 0 22px 2px 0; border: none; background: none; text-align: left;
  font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.mp-title { font-size: 15px; font-weight: 600; color: var(--text-primary, #11151c); line-height: 1.3; }
.mp-line { font-size: 13px; color: var(--text-secondary, #5b6470); line-height: 1.4; }
.mp-chev {
  width: 16px; height: 16px; color: var(--text-muted, #98a1ad);
  transition: transform var(--dur, .22s) ease;
}
.mp-card-main .mp-chev { position: absolute; right: 0; top: 2px; }
/* Раскрытая карточка показывает состав списком — строка-сводка его дублирует. */
.mp-card.is-open .mp-line { display: none; }
.mp-card.is-open .mp-card-main .mp-chev,
.is-open > .mp-row .mp-chev { transform: rotate(180deg); }

/* Записанный приём остаётся на месте, но перестаёт звать к действию. */
.mp-card.is-eaten, .mp-card.is-covered { background: var(--surface-2, rgba(127,127,127,.06)); }
.mp-card.is-eaten .mp-title, .mp-card.is-covered .mp-title { color: var(--text-secondary, #5b6470); }

.mp-eat {
  display: inline-flex; align-items: center; gap: 4px; height: 30px; padding: 0 12px;
  border-radius: 999px; border: none; cursor: pointer; font: inherit;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  background: color-mix(in srgb, var(--color-primary, #22c55e) 14%, transparent);
  color: var(--color-primary, #22c55e);
  transition: transform var(--dur, .22s) var(--ease-spring, ease);
}
.mp-eat svg { width: 14px; height: 14px; }
.mp-eat:active { transform: scale(0.94); }
.mp-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--surface-2, rgba(127,127,127,.1)); color: var(--text-secondary, #5b6470);
}
.mp-ic svg { width: 15px; height: 15px; }
.mp-ic:active { transform: scale(0.92); }
.mp-state {
  display: inline-flex; align-items: center; gap: 4px; font-size: 12px;
  color: var(--text-muted, #98a1ad); white-space: nowrap;
}
.mp-state svg { width: 14px; height: 14px; }
.mp-state.ok { color: var(--color-primary, #22c55e); font-weight: 600; }

/* --- подробности по нажатию ---
   Состав — строками с разделителями (нажатие показывает товары справочника),
   рецепт — отдельным блоком обычным цветом, КБЖУ — плитками: строку мелких
   серых цифр под рецептом не читали. */
.mp-details {
  display: flex; flex-direction: column; gap: 10px; margin-top: 6px; padding-top: 4px;
  border-top: 1px solid var(--border, #e7e9ee);
}
.mp-ing { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.mp-ing-row { border-bottom: 1px solid var(--border, #e7e9ee); }
.mp-ing-row:last-child { border-bottom: none; }
.mp-ing-main {
  width: 100%; display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border: none; background: none; font: inherit; color: inherit; text-align: left;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.mp-ing-name { flex: 1; min-width: 0; font-size: 14.5px; color: var(--text-primary, #11151c); }
.mp-ing-amt {
  display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mp-ing-amt b { font-size: 14px; font-weight: 600; color: var(--text-primary, #11151c); }
.mp-ing-amt small { font-size: 11.5px; color: var(--text-muted, #98a1ad); }
.mp-ing-ic { width: 15px; height: 15px; color: var(--text-muted, #98a1ad); opacity: .7; }
.mp-ing-row.is-open .mp-ing-ic { color: var(--color-primary, #22c55e); opacity: 1; }

.mp-prod {
  margin: 0 0 10px; padding: 8px 10px; border-radius: 10px;
  background: var(--surface-2, rgba(127,127,127,.07));
}
.mp-prod-h { display: block; font-size: 11.5px; font-weight: 600; color: var(--text-muted, #98a1ad); margin-bottom: 4px; }
.mp-prod ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.mp-prod li { display: flex; flex-direction: column; gap: 1px; }
.mp-prod-t { font-size: 13.5px; color: var(--text-primary, #11151c); }
.mp-prod-t b { font-weight: 600; margin-right: 5px; }
.mp-prod-m { font-size: 12px; color: var(--text-muted, #98a1ad); font-variant-numeric: tabular-nums; }

.mp-cook {
  padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--color-accent, #f59e0b) 9%, transparent);
}
.mp-cook-h {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 4px;
  font-size: 12px; font-weight: 600; color: var(--color-accent, #f59e0b);
}
.mp-cook-h svg { width: 14px; height: 14px; }
.mp-cook p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--text-primary, #11151c); }

.mp-nut { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 6px; }
.mp-nut-t {
  display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 7px 2px;
  border-radius: 10px; background: color-mix(in srgb, var(--tile, #8e8e93) 11%, transparent);
}
.mp-nut-t b { font-size: 15px; font-weight: 700; color: var(--text-primary, #11151c); font-variant-numeric: tabular-nums; }
.mp-nut-t span { font-size: 11px; color: var(--text-secondary, #5b6470); }
.mp-nut-k { --tile: var(--color-primary, #22c55e); }
.mp-nut-p { --tile: #0a84ff; }
.mp-nut-f { --tile: #ff9f0a; }
.mp-nut-c { --tile: #bf5af2; }
.mp-nut-v { --tile: #34a853; }

/* --- замена блюда --- */
.mp-swap {
  display: flex; flex-direction: column; gap: 6px; margin-top: 6px; padding-top: 8px;
  border-top: 1px solid var(--border, #e7e9ee);
}
.mp-swap-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12.5px; font-weight: 600; color: var(--text-secondary, #5b6470);
}
.mp-swap-head .mp-ic { width: 26px; height: 26px; }
.mp-muted {
  margin: 0; display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--text-muted, #98a1ad);
}
.mp-muted svg { width: 14px; height: 14px; }
.mp-opts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.mp-opt {
  width: 100%; display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
  border-radius: 10px; border: 1px solid var(--border, #e7e9ee);
  background: var(--surface-2, rgba(127,127,127,.05)); text-align: left;
  font: inherit; color: inherit; cursor: pointer;
}
.mp-opt:active { transform: scale(0.98); }
.mp-opt-t { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.mp-opt-t b { font-size: 14px; font-weight: 600; }
.mp-opt-t em { font-style: normal; font-size: 11.5px; color: var(--text-muted, #98a1ad); }
.mp-opt-l { font-size: 12.5px; color: var(--text-secondary, #5b6470); }
.mp-invent { display: flex; gap: 6px; }
.mp-invent input {
  flex: 1; min-width: 0; height: 34px; padding: 0 10px; border-radius: 10px;
  border: 1px solid var(--border, #e7e9ee); background: var(--fill-input, #f7f8fa);
  color: var(--text-primary, #11151c); font: inherit; font-size: 13.5px;
}
.mp-invent-go {
  display: inline-flex; align-items: center; gap: 4px; height: 34px; padding: 0 12px;
  border-radius: 10px; border: none; cursor: pointer; font: inherit; font-size: 13px;
  font-weight: 600; white-space: nowrap;
  background: var(--color-primary, #22c55e); color: #fff;
}
.mp-invent-go svg { width: 14px; height: 14px; }

/* --- свёрнутые строки: покупки, заметки --- */
.mp-row {
  width: 100%; display: flex; align-items: center; gap: 8px; padding: 11px 12px;
  border-radius: 14px; border: 1px solid var(--border, #e7e9ee);
  background: var(--surface, #fff); font: inherit; font-size: 14px; font-weight: 600;
  color: var(--text-primary, #11151c); cursor: pointer; text-align: left;
}
.mp-row > svg:first-child { width: 18px; height: 18px; color: var(--color-primary, #22c55e); }
.mp-row span { flex: 1; }
.mp-row em { font-style: normal; font-size: 12.5px; font-weight: 400; color: var(--text-muted, #98a1ad); }
/* Покупки — плиткой: значок на подложке, подпись с ходом покупок. */
.mp-row-tile { gap: 12px; padding: 10px 12px; border-radius: 16px; }
.mp-row .mp-row-ic {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--color-primary, #22c55e) 14%, transparent);
  color: var(--color-primary, #22c55e);
}
.mp-row-ic svg { width: 19px; height: 19px; }
.mp-row .mp-row-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mp-row-t b { font-size: 14.5px; font-weight: 600; }
.mp-row-t small { font-size: 12px; font-weight: 400; color: var(--text-muted, #98a1ad); }
.mp-row .mp-row-bar { flex: none; height: 4px; margin-top: 4px; }
.mp-row-quiet { border-color: transparent; background: none; font-weight: 500; font-size: 13px; color: var(--text-secondary, #5b6470); padding: 8px 4px; }
.mp-row-quiet > svg:first-child { width: 16px; height: 16px; color: var(--text-muted, #98a1ad); }
.mp-shop.is-open .mp-row { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }

.mp-shop-body {
  display: flex; flex-direction: column; gap: 2px; padding: 4px 12px 12px;
  border: 1px solid var(--border, #e7e9ee); border-top: none;
  border-radius: 0 0 14px 14px; background: var(--surface, #fff);
}
.mp-shop-body h4 { margin: 10px 0 2px; font-size: 12px; font-weight: 600; color: var(--text-muted, #98a1ad); }
.mp-pantry {
  margin: 8px 0 0; display: flex; align-items: flex-start; gap: 6px;
  font-size: 12.5px; color: var(--text-secondary, #5b6470);
}
.mp-pantry svg { width: 14px; height: 14px; margin-top: 2px; color: var(--text-muted, #98a1ad); }
.mp-list { list-style: none; margin: 0; padding: 0; }
.mp-li { display: flex; align-items: center; gap: 4px; border-bottom: 1px solid var(--border, #e7e9ee); }
.mp-li:last-child { border-bottom: none; }
.mp-li-main {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 6px 0;
  border: none; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.mp-li-main > svg { width: 18px; height: 18px; color: var(--text-muted, #98a1ad); }
.mp-li-t { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: 14px; }
.mp-li-t small { font-size: 11.5px; color: var(--text-muted, #98a1ad); }
.mp-li-main b { font-size: 13px; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.mp-li.is-got .mp-li-main > svg { color: var(--color-primary, #22c55e); }
.mp-li.is-got .mp-li-t > span, .mp-li.is-got b { text-decoration: line-through; color: var(--text-muted, #98a1ad); }
.mp-share { margin-top: 10px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.mp-share svg { width: 16px; height: 16px; }

/* --- низ: файл, пересборка, новое меню ---
   Тремя плитками в ряд: текстовые ссылки под покупками терялись. */
.mp-foot { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.mp-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px 11px;
  border-radius: 16px; border: 1px solid var(--border, #e7e9ee); background: var(--surface, #fff);
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.2; text-align: center;
  color: var(--text-primary, #11151c); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur, .22s) var(--ease-spring, ease), border-color var(--dur, .22s) ease;
}
.mp-tile > span {
  width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--tile, #8e8e93) 14%, transparent); color: var(--tile, #8e8e93);
}
.mp-tile svg { width: 17px; height: 17px; }
.mp-tile:nth-child(1) { --tile: #0a84ff; }
.mp-tile:nth-child(2) { --tile: #f59e0b; }
.mp-tile:nth-child(3) { --tile: var(--color-primary, #22c55e); }
.mp-tile.on { border-color: var(--tile, #8e8e93); }
.mp-tile:active { transform: scale(0.96); }
.mp-link {
  display: inline-flex; align-items: center; gap: 5px; padding: 8px 2px;
  border: none; background: none; font: inherit; font-size: 13px;
  color: var(--text-secondary, #5b6470); cursor: pointer;
}
.mp-link svg { width: 15px; height: 15px; }
.mp-notes-body { padding: 0 4px 4px 28px; font-size: 13px; color: var(--text-secondary, #5b6470); }
.mp-notes-body p { margin: 0 0 6px; }
.mp-notes-body ul { margin: 0; padding-left: 16px; }
.mp-notes-body li { margin: 2px 0; }

/* --- пересборка дня --- */
.mp-regen { padding: 12px; display: flex; flex-direction: column; gap: 8px; border-radius: 14px; border: 1px solid var(--border, #e7e9ee); background: var(--surface, #fff); }
.mp-row-btns { display: flex; gap: 8px; }
.mp-row-btns .btn-primary, .mp-row-btns .btn-soft { flex: 1; }

/* --- настройка нового меню --- */
/* Настройки — карточками, выбор одного из трёх — сегментами во всю ширину:
   россыпь пилюль разной длины на пяти строках выглядела неряшливо. */
.mp-form { display: flex; flex-direction: column; gap: 12px; }
/* Шапка формы — закатной подложкой с Зумом, в тон файлу плана. */
.mp-form-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 8px 12px 16px; border-radius: 18px;
  background: linear-gradient(120deg,
    color-mix(in srgb, #ff4f8b 13%, var(--surface, #fff)),
    color-mix(in srgb, #ffa03c 13%, var(--surface, #fff)) 55%,
    color-mix(in srgb, #ffce54 18%, var(--surface, #fff)));
}
.mp-form-hd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mp-form-hd b { font-size: 18px; color: var(--text-primary, #11151c); }
.mp-form-hd span { font-size: 13px; line-height: 1.35; color: var(--text-secondary, #5b6470); }
.mp-form-zum { flex: 0 0 auto; width: 84px; height: auto; margin: -8px 0 -10px; }
.mp-set {
  display: flex; flex-direction: column; gap: 14px; padding: 14px;
  border-radius: 16px; border: 1px solid var(--border, #e7e9ee);
  background: var(--surface, #fff);
}
.mp-group { display: flex; flex-direction: column; gap: 7px; }
.mp-label { font-size: 13px; font-weight: 600; color: var(--text-secondary, #5b6470); }
.mp-seg {
  display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 3px;
  padding: 3px; border-radius: 12px; background: var(--surface-2, rgba(127,127,127,.1));
}
.mp-seg-b {
  min-width: 0; height: 34px; padding: 0 6px; border: none; border-radius: 9px;
  background: none; color: var(--text-secondary, #5b6470); font: inherit; font-size: 13.5px;
  white-space: nowrap; overflow: hidden; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background var(--dur, .22s) ease, color var(--dur, .22s) ease;
}
.mp-seg-b.on {
  background: var(--surface, #fff); color: var(--text-primary, #11151c); font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
/* Шкала «готовлю — доставка»: четыре шага, подпись в две строки. */
.mp-seg-2l .mp-seg-b {
  height: auto; min-height: 44px; padding: 5px 4px; white-space: normal;
  font-size: 13px; line-height: 1.2;
}
.mp-hint { font-size: 12.5px; color: var(--text-muted, #98a1ad); }
div.mp-ing-main { cursor: default; }
body.tg-dark-theme .mp-seg-b.on {
  background: color-mix(in srgb, var(--color-primary, #22c55e) 22%, transparent);
  color: var(--color-primary, #22c55e); box-shadow: none;
}
.mp-chips-sm { gap: 6px; }
.mp-chips-sm .mp-chip { height: 30px; padding: 0 11px; font-size: 13px; }
.mp-chips-sm .mp-chip-input { height: 30px; font-size: 13px; }
.mp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.mp-chip {
  display: inline-flex; align-items: center; gap: 4px; height: 34px; padding: 0 12px;
  border-radius: 999px; border: 1px solid var(--border, #e7e9ee);
  background: var(--surface, #fff); color: var(--text-primary, #11151c);
  font: inherit; font-size: 13.5px; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.mp-chip svg { width: 13px; height: 13px; }
.mp-chip.on {
  border-color: transparent; font-weight: 600;
  background: color-mix(in srgb, var(--color-primary, #22c55e) 16%, transparent);
  color: var(--color-primary, #22c55e);
}
.mp-chip:active { transform: scale(0.96); }
.mp-chip-input {
  width: 92px; height: 34px; padding: 0 12px; border-radius: 999px;
  border: 1px dashed var(--border-strong, #d8dbe2); background: none;
  color: var(--text-primary, #11151c); font: inherit; font-size: 13.5px;
}
.mp-chip-input:focus { width: 150px; outline: none; border-style: solid; border-color: var(--color-primary, #22c55e); }
.mp-more { align-self: center; padding: 2px 0; }
.mp-back { align-self: center; }
.mp-input {
  width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 12px;
  border: 1px solid var(--border, #e7e9ee); background: var(--fill-input, #f7f8fa);
  color: var(--text-primary, #11151c); font: inherit; font-size: 14px; resize: vertical;
}
.mp-cta { width: 100%; }
.mp-cta:disabled { opacity: .5; }
.mp-note { margin: 0; font-size: 12.5px; color: var(--text-muted, #98a1ad); }
.mp-error { margin: 0; font-size: 13px; color: var(--color-danger, #ef4444); }
.mp-warn {
  display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 12px;
  background: rgba(245,158,11,.12); font-size: 13.5px;
}
.mp-warn svg { width: 18px; height: 18px; color: var(--color-accent, #f59e0b); }
.mp-gate { text-align: center; }

/* --- сборка плана ---
   Минуту ожидания держит не спиннер, а видимый ход работы: дышащая плашка,
   бегущая полоса и два шага, которые повторяют стадии задания. */
.mp-progress {
  display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center;
  padding: 36px 16px; color: var(--text-secondary, #5b6470); font-size: 13.5px;
}
.mp-progress b { color: var(--text-primary, #11151c); font-size: 15px; }
.mp-orb {
  position: relative; width: 104px; height: 104px; border-radius: 34px;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-primary, #22c55e);
  background: linear-gradient(135deg,
    color-mix(in srgb, #ff7057 18%, transparent),
    color-mix(in srgb, #ffce54 24%, transparent));
  animation: mp-orb-breathe 2.4s ease-in-out infinite;
}
/* Зум наводит объектив, пока план собирается. */
.mp-orb img { width: 92px; height: auto; }
@keyframes mp-orb-breathe {
  0%, 100% { transform: scale(1); box-shadow: 0 6px 18px color-mix(in srgb, #ff7057 18%, transparent); }
  50% { transform: scale(1.06); box-shadow: 0 10px 26px color-mix(in srgb, #ff7057 30%, transparent); }
}
.mp-progress-bar {
  width: 100%; max-width: 240px; height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--fill-track, rgba(127,127,127,.2));
}
.mp-progress-bar span {
  display: block; width: 45%; height: 100%; border-radius: 999px;
  background: var(--color-primary, #22c55e);
  animation: mp-sweep 1.5s ease-in-out infinite;
}
@keyframes mp-sweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(222%); }
}
.mp-steps {
  list-style: none; margin: 2px 0 0; padding: 0; width: 100%; max-width: 280px;
  display: flex; flex-direction: column; gap: 10px; text-align: left;
}
.mp-step {
  display: flex; align-items: center; gap: 10px; font-size: 13px;
  color: var(--text-muted, #98a1ad);
  animation: mp-step-in 0.32s var(--ease, ease) backwards;
  animation-delay: calc(var(--i, 0) * 90ms);
}
@keyframes mp-step-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.mp-step-ic {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--border-strong, #d8dbe2); color: var(--text-muted, #98a1ad);
}
.mp-step-ic svg { width: 14px; height: 14px; }
.mp-step.now { color: var(--text-primary, #11151c); font-weight: 600; }
.mp-step.now .mp-step-ic {
  border-color: var(--color-primary, #22c55e); color: var(--color-primary, #22c55e);
  animation: mp-step-pulse 1.7s ease-in-out infinite;
}
.mp-step.done .mp-step-ic {
  background: var(--color-primary, #22c55e); border-color: transparent; color: #fff;
}
@keyframes mp-step-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary, #22c55e) 35%, transparent); }
  70% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--color-primary, #22c55e) 0%, transparent); }
}
@keyframes mp-spin { to { transform: rotate(360deg); } }

/* --- кнопка на главной --- */
.mp-dash-cta {
  display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 10px;
  padding: 10px 12px; border-radius: 12px; border: 1px dashed var(--border-strong, #d8dbe2);
  background: var(--surface-2, #f7f8fa); color: var(--text-primary, #11151c);
  font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; text-align: left;
}
.mp-dash-cta > svg:first-child { width: 18px; height: 18px; color: var(--color-primary, #22c55e); }
.mp-dash-cta span { flex: 1; }
.mp-dash-cta em {
  font-style: normal; font-size: 11px; padding: 2px 8px; border-radius: 999px;
  background: rgba(245,158,11,.16); color: var(--color-accent, #f59e0b);
}
.mp-dash-chev { width: 16px; height: 16px; color: var(--text-muted, #98a1ad); }

/* Меньше движения — по просьбе системы: смысл остаётся, анимации выключаются. */
@media (prefers-reduced-motion: reduce) {
  .mp-card.mp-enter, .mp-step { animation: none; }
  .mp-orb, .mp-step.now .mp-step-ic, .mp-progress-bar span { animation: none; }
  .mp .spin { animation-duration: 2s; }
  .mp-chev { transition: none; }
}

/* profile.css */
/* =====================================================
   Профиль — экран просмотра (mobile-first)
   Плотная информативная выкладка: карточка пользователя с
   ключевыми метриками, карточка дневной нормы КБЖУ и
   сгруппированные ряды настроек с подписями-значениями.
   Формы редактирования — в profile_edit.css.
   ===================================================== */

/* ----------------- Карточка пользователя ----------------- */
.pf-user { padding: 0; overflow: hidden; }

.pf-head {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 15px 16px 14px;
}
.pf-avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  flex: none;
  object-fit: cover;
  border: 1px solid var(--border);
}
.pf-avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-2));
  border: none;
}
.pf-head-main { flex: 1; min-width: 0; }
.pf-name {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pf-handle {
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Кнопка-карандаш у имени: тот же вход в «Личные данные», что и метрики. */
.pf-head-edit {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-secondary);
  cursor: pointer;
}
.pf-head-edit i, .pf-head-edit svg { width: 16px; height: 16px; }
.pf-head-edit:active { filter: brightness(0.95); }

/* ----------------- Полоса метрик (вес / рост / возраст / ИМТ) ----------------- */
.pf-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--border);
}
.pf-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 11px 3px 12px;
  border: none;
  border-left: 1px solid var(--border);
  background: none;
  cursor: pointer;
  font: inherit;
}
.pf-stat:first-child { border-left: none; }
.pf-stat:active { background: var(--surface-2); }
.pf-stat[disabled] { cursor: default; }
.pf-stat-val {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
/* Единица измерения приглушена, чтобы взгляд цеплялся за число. */
.pf-stat-val em {
  font-style: normal;
  font-size: 11px;
  font-weight: 650;
  color: var(--text-muted);
  margin-left: 2px;
}
.pf-stat-lbl {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.02em;
  color: var(--text-muted);
}
.pf-stat.empty .pf-stat-val { color: var(--text-muted); font-weight: 700; }
.pf-stat-lbl[data-tone="ok"] { color: var(--color-primary); }
.pf-stat-lbl[data-tone="warn"] { color: var(--color-accent); }
.pf-stat-lbl[data-tone="bad"] { color: var(--color-danger); }

/* ----------------- Карточка дневной нормы ----------------- */
.pf-goal { padding: 14px 16px 16px; }
.pf-goal-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.pf-goal-title {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.pf-goal-edit {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: none;
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  color: var(--color-primary);
  cursor: pointer;
}
.pf-goal-edit i, .pf-goal-edit svg { width: 15px; height: 15px; }
.pf-goal-edit:active { opacity: 0.6; }

.pf-goal-main {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 13px;
}
.pf-goal-kcal {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -1.1px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.pf-goal-kcal em {
  font-style: normal;
  font-size: 13px;
  font-weight: 650;
  color: var(--text-secondary);
  margin-left: 5px;
  letter-spacing: 0;
}
.pf-goal-tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 5px;
  margin-left: auto;
}
.pf-tag {
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  white-space: nowrap;
}
.pf-tag.accent {
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-primary) 26%, transparent);
}

/* Стек-полоса Б/Ж/У: доли считаются по калорийности, а не по граммам. */
.pf-macro-bar {
  display: flex;
  gap: 2px;
  height: 9px;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--fill-track);
}
.pf-macro-bar span { display: block; min-width: 2px; }
.pf-macro-legend {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 11px;
}
.pf-macro-item { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pf-macro-name {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
}
.pf-macro-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.pf-macro-val {
  font-size: 14.5px;
  font-weight: 750;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.pf-macro-val em {
  font-style: normal;
  font-size: 11px;
  font-weight: 650;
  color: var(--text-muted);
  margin-left: 4px;
}

/* Цели не заданы — вместо цифр приглашение их задать. */
.pf-goal-empty {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.pf-goal-empty:active { opacity: 0.7; }
.pf-goal-empty-ic {
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.pf-goal-empty-ic i, .pf-goal-empty-ic svg { width: 20px; height: 20px; }
.pf-goal-empty-txt { flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-secondary); line-height: 1.4; }
.pf-goal-empty-txt b { display: block; font-size: 14.5px; color: var(--text-primary); margin-bottom: 2px; }

/* ----------------- Группы настроек ----------------- */
.pf-section {
  margin: 20px 4px 8px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.pf-group { padding: 0; overflow: hidden; }
.pf-row {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border: none;
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
/* Разделитель начинается после иконки — привычный iOS-приём, экономит воздух. */
.pf-row + .pf-row::before {
  content: "";
  position: absolute;
  left: 58px;
  right: 0;
  top: 0;
  height: 1px;
  background: var(--border);
}
.pf-row:active { background: var(--surface-2); }
.pf-row-ic {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 9px;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  color: var(--text-secondary);
}
.pf-row-ic i, .pf-row-ic svg { width: 17px; height: 17px; }
.pf-row-ic[data-tone="green"] {
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.pf-row-ic[data-tone="blue"] {
  background: color-mix(in srgb, var(--color-primary-2) 15%, transparent);
  color: var(--color-primary-2);
}
.pf-row-ic[data-tone="amber"] {
  background: color-mix(in srgb, var(--color-accent) 15%, transparent);
  color: var(--color-accent);
}
.pf-row-ic[data-tone="violet"] {
  background: color-mix(in srgb, #a855f7 14%, transparent);
  color: #a855f7;
}
.pf-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pf-row-title { font-size: 15px; font-weight: 600; color: var(--text-primary); }
.pf-row-sub {
  font-size: 12.5px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Раздел не заполнен — подпись подсвечена, чтобы было видно, куда зайти. */
.pf-row-sub.todo { color: var(--color-accent); font-weight: 600; }
.pf-row-chev { width: 17px; height: 17px; flex: none; color: var(--text-muted); }

/* ----------------- Мелочи экрана ----------------- */
.pf-plan, .pf-admin, .pf-logout { margin-bottom: var(--spacing-md); }
.pf-admin { margin-top: 0; }

/* На широких экранах карточка пользователя и норма встают в две колонки:
   мобильная вёрстка иначе растягивается в пустую полосу. */
@media (min-width: 720px) {
  .pf-top { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-md); }
  .pf-top > .glass-card { margin-bottom: 0; }
  .pf-goal { display: flex; flex-direction: column; justify-content: center; }
}

/* Кнопка «Открыть MAX» в привязке (profile_account.js): ссылка, а не кнопка, —
   приложение MAX Safari открывает только по настоящей ссылке. */
.pf-max-open {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 12px; text-decoration: none;
}
.pf-max-open svg { width: 18px; height: 18px; }
.pf-max-open[aria-disabled="true"] { opacity: 0.6; pointer-events: none; }

/* profile_edit.css */
/* =====================================================
   Профиль — формы редактирования (mobile-first)
   Контролы рассчитаны на палец: шаговый ввод чисел вместо
   системного number-инпута, крупные карточки-варианты
   вместо мелких сегментов, чипы для списков и липкая
   кнопка сохранения у нижнего края.
   ===================================================== */

/* ----------------- Шаговый ввод числа ----------------- */
.stp {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.stp-top {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}
.stp-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stp-lock { width: 12px; height: 12px; color: var(--text-muted); flex: none; }
.stp-unit { font-size: 12px; color: var(--text-muted); flex: none; }
/* Правая подпись — живой пересчёт (доля калорий, возраст по дате и т.п.). */
.stp-aside {
  margin-left: auto;
  flex: none;
  font-size: 12px;
  font-weight: 650;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.stp-ctl {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.stp-ctl:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.stp-btn {
  flex: none;
  width: 44px;
  display: grid;
  place-items: center;
  border: none;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.stp-btn i, .stp-btn svg { width: 17px; height: 17px; pointer-events: none; }
.stp-btn:active { background: var(--surface-2); color: var(--color-primary); }
.stp-input {
  flex: 1;
  min-width: 0;
  width: 100%;
  border: none;
  background: none;
  text-align: center;
  padding: 11px 2px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
}
.stp-input:focus { border: none; box-shadow: none; outline: none; }
/* Системные стрелки не нужны: шаг задают кнопки по краям. */
.stp-input::-webkit-outer-spin-button,
.stp-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.stp.locked .stp-ctl { opacity: 0.6; }
.stp.locked .stp-btn, .stp.locked .stp-input { pointer-events: none; }

/* Сетка из нескольких степперов в строку (макросы, лимиты). */
.stp-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.stp-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.stp-grid.cols-3 .stp-btn { width: 34px; }
.stp-grid.cols-3 .stp-input { font-size: 15px; }
@media (max-width: 359px) {
  .stp-grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
}

/* ----------------- Карточки-варианты ----------------- */
.opt-list { display: flex; flex-direction: column; gap: 8px; }
.opt-card {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 13px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}
.opt-card:active { transform: scale(0.995); }
.opt-ic {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 11px;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  color: var(--text-secondary);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.opt-ic i, .opt-ic svg { width: 18px; height: 18px; }
.opt-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.opt-title { font-size: 15px; font-weight: 650; color: var(--text-primary); }
.opt-sub { font-size: 12.5px; line-height: 1.35; color: var(--text-muted); }
.opt-check {
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  display: grid;
  place-items: center;
  color: transparent;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
.opt-check i, .opt-check svg { width: 13px; height: 13px; }

.opt-card.active {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 7%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 12%, transparent);
}
.opt-card.active .opt-ic {
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
  color: var(--color-primary);
}
.opt-card.active .opt-check {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* ----------------- Чипы-список (аллергены) ----------------- */
.chips-field {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 9px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.chips-field:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.chip-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 6px 5px 11px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-accent) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-accent) 28%, transparent);
  color: var(--color-accent);
  font-size: 13px;
  font-weight: 650;
  max-width: 100%;
}
.chip-tag span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip-del {
  width: 18px;
  height: 18px;
  flex: none;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
  color: inherit;
  cursor: pointer;
  padding: 0;
}
.chip-del i, .chip-del svg { width: 11px; height: 11px; pointer-events: none; }
.chips-input {
  flex: 1;
  min-width: 96px;
  width: auto;
  border: none;
  background: none;
  padding: 5px 2px;
  font-size: 14.5px;
  color: var(--text-primary);
}
.chips-input:focus { border: none; box-shadow: none; outline: none; }

/* ----------------- Живой баланс макросов ----------------- */
.mbal {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.mbal-top { display: flex; align-items: baseline; gap: 8px; }
.mbal-label { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.mbal-val {
  margin-left: auto;
  font-size: 14px;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.mbal-delta { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.mbal-delta.ok { color: var(--color-primary); }
.mbal-delta.off { color: var(--color-accent); }
.mbal-hint { font-size: 12px; line-height: 1.4; color: var(--text-muted); }
.mbal-fix {
  align-self: flex-start;
  border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--color-primary);
  font: inherit;
  font-size: 12.5px;
  font-weight: 650;
  padding: 7px 13px;
  cursor: pointer;
}
.mbal-fix:active { filter: brightness(0.96); }

/* ----------------- Липкая кнопка сохранения ----------------- */
.subview:has(.pf-savebar) { padding-bottom: 0; }
.subview-body:has(.pf-savebar) { flex: 1 0 auto; }
.pf-savebar {
  position: sticky;
  bottom: 0;
  z-index: 3;
  margin: auto calc(-1 * var(--spacing-md)) 0;
  padding: 10px var(--spacing-md)
    calc(10px + env(safe-area-inset-bottom, 0px) + var(--tg-safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--bg-app) 62%, transparent);
}
.subview-body .pf-savebar .btn-primary { width: 100%; margin-top: 0; }
.pf-savebar .btn-primary[disabled] { opacity: 0.55; pointer-events: none; }

/* На ПК подраздел — центрированная модалка, там панель не липнет. */
@media (min-width: 900px) {
  .subview:has(.pf-savebar) { padding-bottom: 40px; }
  .subview-body:has(.pf-savebar) { flex: 0 1 auto; }
  .pf-savebar { position: static; margin: 0; padding: 0; background: none; }
}

/* ----------------- Подписи и заметки в формах ----------------- */
.pf-note {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 11px 13px;
}
.pf-note i, .pf-note svg { width: 16px; height: 16px; flex: none; margin-top: 1px; color: var(--text-muted); }
.pf-note.accent {
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  border-color: color-mix(in srgb, var(--color-accent) 26%, transparent);
}
.pf-note.accent i, .pf-note.accent svg { color: var(--color-accent); }

/* Карточка-обёртка группы полей внутри формы. */
.pf-fieldset {
  display: flex;
  flex-direction: column;
  gap: 13px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
}
.pf-fieldset-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
/* Дата рождения: системный пикер, но в оформлении остальных полей. */
.pf-date { display: flex; flex-direction: column; gap: 7px; }
.pf-date input { padding: 11px 13px; font-size: 15px; font-weight: 600; }

/* Переключатели нутриентов и уведомлений внутри форм. */
.pf-fieldset .switch-row { padding: 2px 0; font-size: 14px; }
.pf-fieldset .switch-row.locked > span { color: var(--text-muted); }

/* profile_tone.css */
/* Тон общения · аватар: персонаж крупным планом, лента лиц и живая переписка.
   Выбор делается глазами: человек листает лица, читает реплику и оставляет то,
   что ему приятно слышать каждый день (см. profile_tone.js). */

/* ----------------- Герой ----------------- */

.tone-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 4px 0 14px;
}
.tone-hero-stage {
  position: relative;
  height: 250px;
  display: grid;
  place-items: end center;
  padding-bottom: 6px;
}
/* Свечение цвета персонажа лежит «сценой» под фигурой: оно отделяет прозрачный
   PNG от фона и делает ленту разной на вид, когда позы похожи. */
.tone-hero-glow {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 240px;
  height: 200px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 70%,
    color-mix(in srgb, var(--tone-accent) 40%, transparent) 0%,
    color-mix(in srgb, var(--tone-accent) 12%, transparent) 55%,
    transparent 74%);
}
.tone-hero-face {
  position: relative;
  height: 244px;
  width: auto;
  max-width: 92%;
  object-fit: contain;
  filter: drop-shadow(0 12px 16px rgba(0, 0, 0, 0.20));
}
.tone-hero-face.swap { animation: tone-pop 320ms var(--ease); }
@keyframes tone-pop {
  0% { opacity: 0; transform: scale(0.9) translateY(10px); }
  100% { opacity: 1; transform: none; }
}
.tone-hero-name {
  margin-top: 6px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.tone-hero-hint {
  margin-top: 4px;
  max-width: 300px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
}

/* Вариант без персонажа: на месте лица значок чата. Кружок того же размера и
   с тем же акцентом, чтобы лента не «спотыкалась» на нём. */
.tone-faceless {
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tone-accent) 22%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--tone-accent) 38%, transparent);
  color: var(--tone-accent);
}
.tone-hero-face.tone-faceless {
  width: 156px;
  height: 156px;
  filter: none;
  /* Сцена выравнивает фигуру по низу (она в полный рост), а кружок должен
     стоять в середине свечения, иначе висит над пустым пятном. */
  align-self: center;
  /* Отрицательный отступ подгоняет кружок к центру свечения: сцена прижимает
     содержимое к низу ради фигур в полный рост, а у кружка низа нет. */
  margin-bottom: -18px;
}
.tone-hero-face.tone-faceless i { width: 68px; height: 68px; }
.tone-pick .tone-faceless {
  width: 60px;
  height: 60px;
  border: 2px solid transparent;
  opacity: 0.62;
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.tone-pick .tone-faceless i { width: 26px; height: 26px; }
.tone-pick.active .tone-faceless {
  opacity: 1;
  border-color: var(--tone-accent);
  transform: scale(1.06);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--tone-accent) 16%, transparent);
}
.tone-msg-face.tone-faceless { width: 34px; height: 34px; }
.tone-msg-face.tone-faceless i { width: 17px; height: 17px; }

/* ----------------- Лента лиц ----------------- */

.tone-picker {
  display: flex;
  gap: 10px;
  padding: 4px 2px 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.tone-picker::-webkit-scrollbar { display: none; }

.tone-pick {
  flex: 0 0 auto;
  width: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.tone-pick img {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 12%;
  background: color-mix(in srgb, var(--tone-accent) 16%, var(--surface-2));
  border: 2px solid transparent;
  opacity: 0.62;
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.tone-pick.active img {
  opacity: 1;
  border-color: var(--tone-accent);
  transform: scale(1.06);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--tone-accent) 16%, transparent);
}
.tone-pick.active { color: var(--text-primary); font-weight: 700; }

/* ----------------- Апселл (тариф без персонажа) ----------------- */

/* Карточка стоит между лентой лиц и перепиской: она объясняет, почему тап по
   лицу ничего не сохранил, но не закрывает собой ни ленту, ни реплики — ради
   них раздел и открывают на бесплатном тарифе. */
.tone-gate {
  margin: 2px 0 16px;
  padding: 14px 16px 16px;
  border: 1px solid color-mix(in srgb, var(--color-primary) 30%, var(--border));
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
}
.tone-gate-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
}
.tone-gate-head i {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  color: var(--color-primary);
}
.tone-gate-text {
  margin: 6px 0 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
}
.tone-gate .btn-primary { width: 100%; }

/* ----------------- Переписка ----------------- */

.tone-demo { margin: 2px 0 18px; }
.tone-demo-title {
  display: block;
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tone-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}
.tone-tab {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 8px 6px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
.tone-tab i { width: 14px; height: 14px; }
.tone-tab.active {
  background: color-mix(in srgb, var(--color-primary) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--color-primary) 45%, var(--border));
  color: var(--text-primary);
  font-weight: 600;
}

.tone-chat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  cursor: pointer;
}
.tone-msg {
  max-width: 86%;
  padding: 10px 13px;
  font-size: 13.5px;
  line-height: 1.45;
}
/* Реплика человека справа, ответ персонажа слева: та же геометрия, что в чате
   бота, поэтому раздел читается как предпросмотр, а не как таблица примеров. */
.tone-msg.mine {
  align-self: flex-end;
  border-radius: 16px 16px 4px 16px;
  background: color-mix(in srgb, var(--color-primary) 16%, var(--surface-2));
  color: var(--text-primary);
}
.tone-msg.theirs {
  align-self: flex-start;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  min-height: 76px;
  padding: 11px 14px 11px 11px;
  border-radius: 16px 16px 16px 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-primary);
}
.tone-msg-face {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 12%;
  background: var(--surface);
}
.tone-msg-text { flex: 1; min-width: 0; }
.tone-replay {
  align-self: flex-start;
  font-size: 11.5px;
  color: var(--text-muted);
}

/* ----------------- Личные правила общения ----------------- */

.tone-rules-box textarea {
  width: 100%;
  resize: none;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  color: var(--text-primary);
  padding: 11px 13px;
  font: inherit;
  font-size: 14px;
  line-height: 1.4;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tone-rules-box textarea::placeholder { color: var(--text-muted); }
.tone-rules-box textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.tone-rule-add { display: flex; align-items: center; gap: 10px; }
.tone-rule-add .btn-primary { flex: 1; }

.tone-rules { display: flex; flex-direction: column; gap: 8px; }
.tone-rule {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px 10px 13px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.tone-rule > span {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.tone-rules-empty {
  font-size: 13px;
  color: var(--text-muted);
  padding: 4px 0 2px;
}

/* tg-fullscreen.css */
/* =====================================================
   Telegram Mini App — Fullscreen & Safe-area
   Telegram пробрасывает в :root:
     --tg-safe-area-inset-*          — челка / статус-бар
     --tg-content-safe-area-inset-*  — собственный UI Telegram
   Класс body.tg-fullscreen ставит JS только на мобильных.
   На ПК (tg-platform-desktop) fullscreen не запрашивается.
   ===================================================== */

/* В fullscreen контент уходит под системный бар — отступаем сверху,
   снизу освобождаем место под плавающую навигацию + safe-area. */
body.tg-fullscreen .main-content {
  padding-top: calc(
    8px
    + var(--tg-safe-area-inset-top, 0px)
    + max(52px, var(--tg-content-safe-area-inset-top, 0px))
  );
  padding-bottom: calc(var(--nav-h) + 56px + var(--tg-safe-area-inset-bottom, 0px));
}

body.tg-webapp .container {
  padding-left: var(--tg-safe-area-inset-left, 0px);
  padding-right: var(--tg-safe-area-inset-right, 0px);
}

/* Полноэкранные подразделы (настройки/формы) — как основные разделы,
   оставляем сверху место под системный бар Telegram. */
body.tg-fullscreen .subview {
  padding-top: calc(
    8px
    + var(--tg-safe-area-inset-top, 0px)
    + max(52px, var(--tg-content-safe-area-inset-top, 0px))
  );
  padding-bottom: calc(32px + var(--tg-safe-area-inset-bottom, 0px));
}
/* Липкая панель оплаты сама держит нижний отступ с safe-area, поэтому
   собственный padding подраздела ей мешает — кнопка повисает над пустотой. */
body.tg-fullscreen .subview.sv-pay,
body.tg-fullscreen .subview:has(.sub-pay-bar) { padding-bottom: 0; }
/* Заголовок подраздела встаёт туда же, где заголовок раздела (brand-капсула):
   по центру, в зоне системного бара, тем же размером. Кнопка «Назад» остаётся
   на своём уровне — в шапке подраздела под баром. */
body.tg-fullscreen .subview-title {
  --brand-h: 36px;
  --tg-bar-h: max(48px, var(--tg-content-safe-area-inset-top, 48px));
  position: fixed;
  top: calc(var(--tg-safe-area-inset-top, 0px) + (var(--tg-bar-h) - var(--brand-h)) / 2);
  left: 50%;
  transform: translateX(-50%);
  height: var(--brand-h);
  max-width: 64vw;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 2410;
}

/* В fullscreen у Telegram в шапке свои «Назад»/«…»/«✕» — собственный крестик
   их только дублирует. Шапка подраздела остаётся пустым отступом. */
body.tg-fullscreen .subview-close { display: none; }

/* Плавающая навигация поднимается над системной зоной жестов. */
body.tg-fullscreen .bottom-nav {
  bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--tg-safe-area-inset-bottom, 0px));
}
body.tg-fullscreen .toast {
  bottom: calc(var(--nav-h) + 28px + env(safe-area-inset-bottom, 0px) + var(--tg-safe-area-inset-bottom, 0px));
}

/* Онбординг-заглушка: контент и крестик не заходят под системный бар. */
body.tg-fullscreen .welcome-splash {
  padding-top: calc(
    16px
    + var(--tg-safe-area-inset-top, 0px)
    + max(52px, var(--tg-content-safe-area-inset-top, 0px))
  );
  padding-bottom: calc(28px + var(--tg-safe-area-inset-bottom, 0px));
}
body.tg-fullscreen .ws-close {
  top: calc(
    6px
    + var(--tg-safe-area-inset-top, 0px)
    + max(48px, var(--tg-content-safe-area-inset-top, 48px))
  );
}

/* Brand-капсула: скрыта по умолчанию, видна только в fullscreen,
   где она заменяет заголовок страницы. */
.tg-brand { display: none; }
body.tg-fullscreen .page-header { display: none; }

body.tg-fullscreen .tg-brand {
  --brand-h: 36px;
  --tg-bar-h: max(48px, var(--tg-content-safe-area-inset-top, 48px));
  position: fixed;
  top: calc(var(--tg-safe-area-inset-top, 0px) + (var(--tg-bar-h) - var(--brand-h)) / 2);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--brand-h);
  max-width: 64vw;
  padding: 0 16px;
  z-index: 1100;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  color: var(--text-primary);
  font-weight: 700;
  user-select: none;
  pointer-events: none;
  transition: background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

/* При прокрутке капсула получает фон-подложку. */
body.tg-fullscreen.tg-scrolled .tg-brand {
  background: var(--surface);
  border-color: var(--border);
  box-shadow: var(--shadow-float);
}
body.tg-fullscreen .tg-brand .tg-brand-icon {
  width: 20px;
  height: 20px;
  color: var(--color-primary);
}
body.tg-fullscreen .tg-brand .tg-brand-name {
  font-size: 15px;
  line-height: 1;
  white-space: nowrap;
}

/* Просмотр фото: крестик и фото — ниже собственной панели Telegram (её
   кнопки справа сверху перекрывали крестик), лента миниатюр — над нижней
   кромкой. */
body.tg-fullscreen .lightbox {
  padding-top: calc(var(--tg-safe-area-inset-top, 0px) + max(52px, var(--tg-content-safe-area-inset-top, 0px)) + 46px);
  padding-bottom: calc(16px + var(--tg-safe-area-inset-bottom, 0px));
}
body.tg-fullscreen .lightbox-close {
  top: calc(var(--tg-safe-area-inset-top, 0px) + max(52px, var(--tg-content-safe-area-inset-top, 0px)));
}

/* web.css */
/* =====================================================
   Веб-версия вне Telegram: экран входа по почте, выход из
   профиля, юридический футер и кнопка быстрого добавления.
   Форма приёма — в web_meal.css, раскладка под ПК — в
   web_desktop.css. Токены дизайн-системы — из theme.css.
   ===================================================== */

/* ----------------- Поля ввода в браузере ----------------- */
/* Safari на iPhone зумит страницу при фокусе на поле, если его шрифт меньше
   16px, и обратно уже не отдаёт: экран остаётся «уехавшим» вправо. В Telegram
   этого не видно — там зум подавляет user-scalable=no из viewport, а обычный
   Safari его игнорирует с iOS 10. Поэтому 16px ставим только вне Telegram
   (класс web-mode вешает web_auth.js), не трогая раскладку мини-аппа. */
body.web-mode input,
body.web-mode select,
body.web-mode textarea { font-size: 16px; }

/* ----------------- Экран входа ----------------- */
.login-screen {
  position: fixed;
  inset: 0;
  z-index: 4000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px 22px;
  overflow-y: auto;
  background: radial-gradient(120% 78% at 50% 0%,
    color-mix(in srgb, var(--color-primary) 14%, var(--bg-app)) 0%,
    var(--bg-app) 55%);
}
.login-screen.show { display: flex; }
.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: 28px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: center;
}
.login-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto;
  border-radius: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--color-primary) 14%, var(--surface));
  color: var(--color-primary);
}
.login-icon i, .login-icon svg { width: 32px; height: 32px; }
.login-title { font-size: 20px; font-weight: 800; color: var(--text-primary); }
.login-sub { font-size: 13.5px; color: var(--text-secondary); line-height: 1.45; }
/* Норма с лендинга: главное на экране — само число, ради него человек и шёл. */
.login-norm {
  border: 1px solid color-mix(in srgb, var(--color-primary) 30%, var(--border));
  background: color-mix(in srgb, var(--color-primary) 8%, var(--surface));
  border-radius: var(--r-md);
  padding: 12px 14px;
}
.login-norm[hidden] { display: none; }
.login-norm-num {
  font-size: 26px;
  font-weight: 800;
  color: var(--color-primary);
  line-height: 1.15;
}
.login-norm-cap {
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.4;
  margin-top: 4px;
}
.login-step { display: flex; flex-direction: column; gap: 12px; }
.login-step[hidden] { display: none; }
/* После явной web-CTA почта становится первым действием, Telegram остаётся
   ниже как рабочий запасной путь. DOM общий с обычным входом, меняется порядок. */
#login-step-email.email-first #login-email-block { order: 1; }
#login-step-email.email-first #login-or { order: 2; }
#login-step-email.email-first #login-tg { order: 3; }
#login-step-email.email-first #login-tg-sub { order: 4; }
#login-step-email #login-try-meal { order: 5; }
#login-step-email.email-first #login-email-toggle { display: none; }
.login-step input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  color: var(--text-primary);
  font-size: 16px;
  padding: 13px 14px;
  outline: none;
  text-align: center;
}
.login-step input:focus { border-color: var(--color-primary); }
#login-code { letter-spacing: 8px; font-weight: 700; font-size: 22px; }
.login-error {
  font-size: 13px;
  color: var(--color-danger);
  min-height: 16px;
}
.login-linkbtn {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 13.5px;
  cursor: pointer;
  padding: 6px;
}
.login-linkbtn:disabled { opacity: 0.55; cursor: default; }
/* Разделитель между Telegram и почтой — тихий, без карточки. */
.login-or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 2px 0;
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: lowercase;
}
.login-or[hidden] { display: none; }

/* Вход без регистрации. Стоит первым и оформлен как главное действие: это
   единственный путь, не зависящий ни от почты, ни от Telegram, а Telegram в
   России заблокирован и треть переходов в него не доезжает. Блок скрыт до
   ответа сервера — мелькнувшая и исчезнувшая кнопка хуже её отсутствия. */
#login-guest-block[hidden] { display: none; }
#login-guest-block { display: grid; gap: 8px; }

/* Согласие с документами. Мелкое, но обязательное: для аккаунта без формы это
   единственный момент, когда человек его даёт. */
.login-legal {
  margin-top: 14px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--text-secondary);
  text-align: center;
}
.login-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.login-or::before, .login-or::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}
.login-or span { flex: none; line-height: 1; }
/* Вход по почте: вторичная кнопка, заметнее текстовой ссылки. */
.login-email-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 14.5px;
  font-weight: 650;
  padding: 12px 14px;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.login-email-btn:hover {
  background: color-mix(in srgb, var(--fill-track) 55%, var(--surface));
  border-color: color-mix(in srgb, var(--text-secondary) 25%, var(--border));
}
.login-email-btn:active { filter: brightness(0.98); }
.login-email-btn[hidden] { display: none; }
.login-tg-note {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.45;
  margin-top: 4px;
}
.login-tg-note a { color: var(--color-primary); font-weight: 600; text-decoration: none; }

/* Кнопка «Войти/Открыть через Telegram» */
.btn-tg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  border: none;
  border-radius: var(--r-sm);
  background: linear-gradient(180deg, #2aabee 0%, #229ed9 100%);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  padding: 13px 14px;
  cursor: pointer;
  text-decoration: none;
  transition: filter var(--dur) var(--ease);
}
.btn-tg:active { filter: brightness(0.95); }
.btn-tg i, .btn-tg svg { width: 18px; height: 18px; }

/* Ожидание подтверждения из Telegram */
.login-tg-wait {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-size: 13.5px;
  color: var(--text-secondary);
}
.login-tg-wait[hidden] { display: none; }
/* Маленький спиннер (экран входа/ожидание подтверждения Telegram). */
.wm-spinner {
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--fill-track);
  border-top-color: var(--color-primary);
  animation: wm-spin 0.8s linear infinite;
}

/* ----------------- Профиль: опасная кнопка --------- */
/* Иконка и текст — одной строкой по центру: без flex подставленный lucide <svg>
   встаёт по базовой линии текста, съезжает вниз и липнет к первой букве. */
.btn-danger-soft {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--color-danger) 35%, var(--border));
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--color-danger) 8%, var(--surface));
  color: var(--color-danger);
  font-size: 14.5px;
  font-weight: 650;
  line-height: 1.25;
  padding: 12px 14px;
  cursor: pointer;
}
.btn-danger-soft i, .btn-danger-soft svg {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
}
.btn-danger-soft:disabled { opacity: 0.55; cursor: default; }


/* ----------------- Профиль: выход (только веб) ----------------- */
.pf-logout {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  border: none;
  cursor: pointer;
  padding: 14px 16px;
  font-size: 14.5px;
  font-weight: 650;
  color: var(--color-danger);
}
.pf-logout i, .pf-logout svg { width: 17px; height: 17px; }

/* ----------------- Профиль: удаление аккаунта (account_delete.js) ----- */
/* Тихая ссылка внизу, а не карточка: нажать её случайно не должны. */
.pf-delete {
  display: block;
  margin: 4px auto var(--spacing-md);
  padding: 8px 12px;
  border: none;
  background: none;
  color: var(--color-danger);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.acc-del .field-hint { margin: 0 0 12px; }
.acc-del .btn-danger-soft { margin-top: 8px; }

/* Аккаунт удаляется: экран поверх всего, пока человек не восстановит или не выйдет. */
.acc-deleting {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--bg-app);
}
.acc-deleting-card {
  width: 100%;
  max-width: 380px;
  text-align: center;
}
.acc-deleting-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-danger);
  background: rgba(239, 68, 68, 0.1);
}
.acc-deleting-icon svg, .acc-deleting-icon i { width: 28px; height: 28px; }
.acc-deleting h2 { margin: 0 0 10px; font-size: 22px; color: var(--text-primary); }
.acc-deleting p { margin: 0 0 8px; color: var(--text-secondary); font-size: 15px; line-height: 1.45; }
.acc-deleting .btn-primary { width: 100%; margin-top: 16px; }
.acc-deleting-exit {
  margin-top: 10px;
  padding: 10px;
  border: none;
  background: none;
  color: var(--text-secondary);
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
}

/* ----------------- Юридический футер профиля ------------------------- */
.pf-legal { margin: 22px 4px 8px; text-align: center; }
.pf-legal-links {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px;
  margin-bottom: 8px;
}
.pf-legal-links a {
  color: var(--text-secondary); font-size: 12.5px; text-decoration: none;
}
.pf-legal-links a:active { opacity: 0.6; }
.pf-legal-copy { color: var(--text-muted); font-size: 11px; line-height: 1.5; }
.pf-legal-support {
  margin-bottom: 8px; color: var(--text-secondary); font-size: 12.5px; line-height: 1.5;
}
.pf-legal-support a { color: var(--accent, #34c759); font-weight: 600; text-decoration: none; }

/* ----------------- Быстрое добавление приёма (FAB, только веб) --------- */
/* В Telegram приём добавляется перепиской с ботом, поэтому кнопку показываем
   только в веб-версии (нет класса tg-webapp). */
.fab-add { display: none; }
body:not(.tg-webapp) .fab-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  right: 16px;
  bottom: calc(var(--nav-h) + 24px + env(safe-area-inset-bottom, 0px));
  z-index: 1200;
  width: 56px;
  height: 56px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--color-primary);
  color: #fff;
  box-shadow: var(--shadow-float);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.fab-add svg { width: 26px; height: 26px; }
.fab-add-label { display: none; }
.fab-add:active { transform: scale(0.94); }

/* web_meal.css */
/* =====================================================
   Веб-версия: форма добавления приёма — текст, фото, выбор
   пищевой даты, живой прогресс распознавания и итог.
   Экран ожидания и итога (.wm-scan / .wm-product / .wm-done)
   переиспользует форма тренировки (web_activity.js): это тот
   же процесс, только по упражнениям.
   ===================================================== */

/* ----------------- Форма приёма (веб) ----------------- */
.wm-hint { font-size: 13.5px; color: var(--text-secondary); line-height: 1.5; }
.wm-textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  color: var(--text-primary);
  /* 16px — иначе Safari на iPhone зумит страницу при фокусе (см. web.css). */
  font-size: 16px;
  font-family: inherit;
  padding: 12px 13px;
  resize: vertical;
  outline: none;
}
.wm-textarea:focus { border-color: var(--color-primary); }
.wm-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.wm-photos:empty { display: none; }
.wm-photo {
  position: relative;
  width: 84px;
  height: 84px;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--border);
}
.wm-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wm-photo-x {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.wm-photo-x i, .wm-photo-x svg { width: 13px; height: 13px; }
.wm-actions { display: flex; gap: 10px; }
.wm-submit { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.wm-submit i, .wm-submit svg { width: 18px; height: 18px; }

/* ---- Выбор пищевой даты записи ---- */
.wm-datebar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 10px 12px;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.wm-datebar.changed {
  border-color: color-mix(in srgb, var(--color-primary) 45%, var(--border));
  background: color-mix(in srgb, var(--color-primary) 6%, var(--surface));
}
.wm-datebar-ic {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--color-primary) 14%, var(--surface));
  color: var(--color-primary);
}
.wm-datebar-ic i, .wm-datebar-ic svg { width: 18px; height: 18px; }
.wm-datebar-txt { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.wm-datebar-cap { font-size: 11.5px; color: var(--text-muted); }
.wm-datebar-day { font-size: 14.5px; font-weight: 700; color: var(--text-primary); }
.wm-date-change {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  border-radius: var(--r-pill);
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 12px;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--dur) var(--ease);
}
.wm-date-change i, .wm-date-change svg { width: 14px; height: 14px; }
.wm-date-change:active { border-color: var(--color-primary); }

/* ---- Прогресс распознавания (живой) ---- */
.wm-progress {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 16px;
  overflow: hidden;
}
/* display:flex перебивает браузерное [hidden] — скрываем явно. */
.wm-progress[hidden],
.wm-result[hidden],
.wm-submit[hidden] { display: none; }

.wm-scan { display: flex; align-items: center; gap: 13px; }
.wm-orb {
  position: relative;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: linear-gradient(135deg, var(--color-primary),
    color-mix(in srgb, var(--color-primary) 45%, #35d0a5));
  animation: wm-orb-pulse 1.9s ease-out infinite;
}
.wm-orb i, .wm-orb svg { width: 22px; height: 22px; animation: wm-orb-spin 3.4s linear infinite; }
@keyframes wm-orb-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary) 45%, transparent); }
  70% { box-shadow: 0 0 0 13px color-mix(in srgb, var(--color-primary) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary) 0%, transparent); }
}
@keyframes wm-orb-spin { to { transform: rotate(360deg); } }
.wm-scan-info { min-width: 0; flex: 1; }
.wm-stage-title { font-size: 14.5px; font-weight: 700; color: var(--text-primary); }
.wm-stage-sub { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }

.wm-bar {
  position: relative;
  height: 7px;
  border-radius: 999px;
  background: var(--fill-track);
  overflow: hidden;
}
.wm-bar-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 8%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-primary),
    color-mix(in srgb, var(--color-primary) 50%, #35d0a5));
  transition: width 0.5s var(--ease);
}
.wm-bar.indeterminate .wm-bar-fill {
  width: 38%;
  animation: wm-bar-slide 1.25s ease-in-out infinite;
}
@keyframes wm-bar-slide {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}

/* Можно закрыть страницу: заметно, без крика. */
.wm-leave {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface));
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
}
.wm-leave i, .wm-leave svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 1px;
  color: var(--color-primary);
}

.wm-products { display: flex; flex-direction: column; }
.wm-products:empty { display: none; }
.wm-product {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  font-size: 13.5px;
  color: var(--text-secondary);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.wm-product.in { opacity: 1; transform: none; }
.wm-p-name { flex: 1; min-width: 0; }
.wm-p-kcal { color: var(--text-muted); font-size: 11.5px; white-space: nowrap; }
.wm-product.done { color: var(--text-primary); }

/* Индикатор статуса продукта: пусто → спиннер → галочка */
.wm-p-dot {
  position: relative;
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--fill-track);
  box-sizing: border-box;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.wm-product.run .wm-p-dot {
  border-color: var(--fill-track);
  border-top-color: var(--color-primary);
  animation: wm-spin 0.8s linear infinite;
}
.wm-product.done .wm-p-dot {
  border-color: var(--color-primary);
  background: var(--color-primary);
  animation: wm-pop 0.3s var(--ease-spring);
}
.wm-product.done .wm-p-dot::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
@keyframes wm-spin { to { transform: rotate(360deg); } }
@keyframes wm-pop {
  0% { transform: scale(0.4); }
  60% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

.wm-tip {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-muted);
  border-top: 1px dashed var(--border);
  padding-top: 12px;
  min-height: 17px;
  line-height: 1.4;
}
.wm-tip i, .wm-tip svg { width: 15px; height: 15px; flex: none; color: var(--color-primary); }
.wm-tip-text { opacity: 0; transition: opacity 0.4s var(--ease); }
.wm-tip-text.in { opacity: 1; }

/* Итог */
.wm-result { display: flex; flex-direction: column; gap: 12px; }
.wm-done-day {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-primary);
}
.wm-done-day i, .wm-done-day svg { width: 16px; height: 16px; flex: none; }
.wm-result-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.wm-result-actions .btn-soft,
.wm-result-actions .btn-primary {
  flex: 1 1 130px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.wm-result-actions i, .wm-result-actions svg { width: 17px; height: 17px; }
.wm-done {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--color-primary) 30%, var(--border));
  border-radius: var(--r-md);
  padding: 14px 15px;
  font-size: 14px;
  color: var(--text-primary);
  line-height: 1.45;
}
.wm-done i, .wm-done svg { width: 20px; height: 20px; flex: none; color: var(--color-primary); }
.wm-items {
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 15px;
}
.wm-item {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
  color: var(--text-secondary);
}
.wm-item span:last-child { color: var(--text-primary); font-weight: 600; white-space: nowrap; }
.wm-comment { font-size: 13px; color: var(--text-muted); line-height: 1.5; }

/* meal_quality.css */
/* =====================================================
   Оценка состава приёма: кольцо с баллом, короткий вывод
   и разбор под кнопкой. Показывается на экране «Приём
   сохранён» сразу после итога.

   Кольцо намеренно маленькое (76 px): на этом экране
   главное — сама запись, а балл её дополняет, а не
   перебивает. Числа набраны tabular-nums, иначе балл
   «7,4» и «10» прыгают по ширине при повторной записи.
   ===================================================== */

.mq {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mq-top {
  display: flex;
  align-items: center;
  gap: 14px;
}

.mq-ring {
  position: relative;
  width: 76px;
  height: 76px;
  flex: none;
  margin: 0;
}
.mq-ring figcaption {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.mq-ring b {
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.mq-ring span {
  margin-top: -2px;
  font-size: 10.5px;
  color: var(--text-muted);
}

.mq-copy { min-width: 0; }
.mq-copy h4 {
  margin: 0 0 3px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.mq-copy p {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
}

.mq-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.mq-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--fill-track);
  color: var(--text-secondary);
}
.mq-chip svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
/* Зелёный и красный здесь означают вклад строки в балл, а не «хорошая» и
   «плохая» еда: рядом всегда стоит число, а не оценка человека. */
.mq-chip.up {
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
  color: #15803d;
}
.mq-chip.down {
  background: color-mix(in srgb, var(--color-danger) 14%, transparent);
  color: #b3261e;
}
body.tg-dark-theme .mq-chip.up { color: #6ee7a2; }
body.tg-dark-theme .mq-chip.down { color: #ffa49c; }

.mq-why {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-primary);
  cursor: pointer;
}
.mq-why svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--dur) var(--ease);
}
.mq-why[aria-expanded="true"] svg { transform: rotate(180deg); }

.mq-detail {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.mq-detail[hidden] { display: none; }

.mq-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 10px;
  align-items: baseline;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--text-secondary);
}
.mq-row b {
  color: var(--text-primary);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.mq-track {
  grid-column: 1 / -1;
  height: 5px;
  margin-top: 3px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.mq-track i {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
}

.mq-src {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--text-muted);
}

/* scan_progress.css */
/* =====================================================
   Ожидание разбора еды (scan_progress.js).

   Один экран на веб-версию и на лендинги: разбор идёт около
   минуты, и всё это время человек должен видеть работу —
   стадию, состав тарелки, калории по одной позиции и
   растущий промежуточный итог.

   Палитры у приложения и у домов лендингов разные, поэтому
   цвета берутся токенами с запасным вариантом: в приложении
   объявлены --color-primary/--surface/--text-primary, на
   лендинге — --primary/--card/--text. Своих цветов файл не
   вводит.
   ===================================================== */

.sp {
  display: grid;
  gap: 14px;
  --sp-accent: var(--color-primary, var(--primary, #22c55e));
  /* Второй тон градиента — светлее того же акцента, а не отдельный цвет: на
     карамельной теме лендинга примесь зелёного давала грязный переход. */
  --sp-accent-2: color-mix(in srgb, var(--sp-accent) 62%, #ffffff);
  --sp-surface: var(--surface-2, var(--bg-2, #f7f8fa));
  --sp-track: var(--fill-track, var(--bg-2, #eceef2));
  --sp-text: var(--text-primary, var(--text, #11151c));
  --sp-text-2: var(--text-secondary, var(--text-2, #5b6470));
  --sp-text-3: var(--text-muted, var(--text-3, #98a1ad));
  --sp-line: var(--border, rgba(0, 0, 0, 0.12));
  --sp-ease: cubic-bezier(0.22, 1, 0.36, 1);
}
.sp[hidden] { display: none; }

/* ----------------- Шапка: стадия ----------------- */
.sp-head { display: flex; align-items: center; gap: 12px; }
.sp-orb {
  position: relative;
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: linear-gradient(135deg, var(--sp-accent), var(--sp-accent-2));
  animation: sp-pulse 2s ease-out infinite;
}
.sp-orb svg { width: 21px; height: 21px; animation: sp-spin 6s linear infinite; }
@keyframes sp-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sp-accent) 42%, transparent); }
  70% { box-shadow: 0 0 0 13px color-mix(in srgb, var(--sp-accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sp-accent) 0%, transparent); }
}
@keyframes sp-spin { to { transform: rotate(360deg); } }

.sp-head-text { min-width: 0; flex: 1; }
.sp-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--sp-text);
  line-height: 1.3;
}
.sp-sub { margin-top: 2px; font-size: 12.5px; color: var(--sp-text-3); }

/* Счётчик готовых позиций: короткий ответ на вопрос «сколько ещё ждать». */
.sp-count {
  flex: none;
  padding: 5px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sp-accent) 12%, transparent);
  color: color-mix(in srgb, var(--sp-accent) 78%, var(--sp-text));
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.sp-count[hidden] { display: none; }

/* ----------------- Полоса ----------------- */
.sp-bar {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background: var(--sp-track);
  overflow: hidden;
}
.sp-bar-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 8%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--sp-accent), var(--sp-accent-2));
  transition: width 0.6s var(--sp-ease);
}
/* Пока состав не распознан, честного процента нет — полоса просто дышит. */
.sp-bar.is-idle .sp-bar-fill {
  width: 36%;
  animation: sp-slide 1.4s ease-in-out infinite;
}
@keyframes sp-slide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(320%); }
}

/* ----------------- Список позиций ----------------- */
.sp-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.sp-list:empty { display: none; }
.sp-item {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--r-sm, 12px);
  background: var(--sp-surface);
  font-size: 14px;
  color: var(--sp-text-2);
  animation: sp-fade 0.35s var(--sp-ease) both;
  transition: background 0.3s var(--sp-ease), color 0.3s var(--sp-ease);
}
.sp-name { min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.sp-name em {
  font-style: normal;
  font-weight: 500;
  color: var(--sp-text-3);
  margin-left: 6px;
  font-size: 12.5px;
}
.sp-kcal {
  white-space: nowrap;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--sp-text-3);
}
.sp-item.is-done { color: var(--sp-text); }
.sp-item.is-done .sp-kcal { color: var(--sp-text); font-weight: 700; }
.sp-item.is-run {
  background: color-mix(in srgb, var(--sp-accent) 9%, var(--sp-surface));
  color: var(--sp-text);
}

/* Точка статуса: пусто → спиннер → галочка. */
.sp-dot {
  position: relative;
  width: 18px;
  height: 18px;
  flex: none;
  box-sizing: border-box;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--sp-line) 70%, transparent);
  transition: border-color 0.2s var(--sp-ease), background 0.2s var(--sp-ease);
}
.sp-item.is-run .sp-dot {
  border-color: color-mix(in srgb, var(--sp-line) 70%, transparent);
  border-top-color: var(--sp-accent);
  animation: sp-spin 0.8s linear infinite;
}
.sp-item.is-done .sp-dot {
  border-color: var(--sp-accent);
  background: var(--sp-accent);
  animation: sp-pop 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.sp-item.is-done .sp-dot::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
@keyframes sp-pop {
  0% { transform: scale(0.4); }
  60% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Заготовки строк на первом шаге: состав ещё не распознан. */
.sp-item.is-skel {
  grid-template-columns: 18px minmax(0, 1fr);
  animation-delay: calc(var(--i, 0) * 90ms);
}
.sp-item.is-skel .sp-dot { border-style: dashed; }
.sp-skel {
  height: 11px;
  border-radius: 999px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--sp-line) 45%, transparent) 0%,
    color-mix(in srgb, var(--sp-line) 18%, transparent) 50%,
    color-mix(in srgb, var(--sp-line) 45%, transparent) 100%);
  background-size: 220% 100%;
  animation: sp-shimmer 1.5s linear infinite;
}
.sp-item.is-skel:nth-child(2) .sp-skel { width: 74%; }
.sp-item.is-skel:nth-child(3) .sp-skel { width: 56%; }
@keyframes sp-shimmer {
  0% { background-position: 120% 0; }
  100% { background-position: -120% 0; }
}
@keyframes sp-fade { from { opacity: 0; transform: translateY(6px); } }

/* ----------------- Промежуточный итог ----------------- */
.sp-partial {
  margin: 0;
  padding: 11px 13px;
  border-radius: var(--r-sm, 12px);
  background: color-mix(in srgb, var(--sp-accent) 10%, transparent);
  color: var(--sp-text-2);
  font-size: 13.5px;
  line-height: 1.4;
}
.sp-partial[hidden] { display: none; }
.sp-partial b {
  font-size: 16px;
  color: var(--sp-text);
  font-variant-numeric: tabular-nums;
}
.sp-partial-note { color: var(--sp-text-3); }

.sp-note {
  margin: 0;
  padding-top: 12px;
  border-top: 1px dashed var(--sp-line);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--sp-text-3);
}

@media (prefers-reduced-motion: reduce) {
  .sp-orb,
  .sp-orb svg,
  .sp-item.is-run .sp-dot,
  .sp-item.is-done .sp-dot,
  .sp-skel { animation: none; }
  .sp-bar.is-idle .sp-bar-fill { animation: none; width: 18%; }
  .sp-item { animation: none; transition: none; }
}

/* meal_journey.css */
/* =====================================================
   Первый разбор еды до регистрации: ввод, ожидание, итог.

   Экран показывается человеку, который ещё ничего о нас не
   знает, поэтому он собран из тех же примитивов, что и
   дневник (карточка, плитки макросов, кнопки), а ожидание —
   общий компонент scan_progress.css.
   ===================================================== */

.first-meal-screen {
  position: fixed;
  inset: 0;
  z-index: 12000;
  overflow-y: auto;
  background: var(--bg-app);
  /* Едва заметное тёплое пятно сверху: пустой серый экран до первого действия
     выглядит как страница с ошибкой, а не как начало продукта. */
  background-image: radial-gradient(120% 60% at 50% -10%,
    color-mix(in srgb, var(--color-primary) 12%, transparent), transparent 70%);
  /* Поля намеренно узкие: почти весь трафик приходит с телефона, и на 375 px
     каждые лишние 6 px по краю — это минус строка состава на экране. */
  padding: 32px 14px;
  color: var(--text-primary);
}
.first-meal-panel {
  max-width: 560px;
  margin: auto;
  padding-bottom: 40px;
  animation: journey-rise 0.4s var(--ease) both;
}
.first-meal-panel h1 {
  font-size: clamp(28px, 6vw, 38px);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 12px 0 10px;
}
.first-meal-panel h2 { font-size: 24px; margin: 0 0 12px; }
.first-meal-panel .btn-primary,
.first-meal-panel .btn-soft {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.first-meal-panel .btn-primary { width: 100%; margin-top: 16px; min-height: 50px; }
.first-meal-panel .btn-primary i, .first-meal-panel .btn-primary svg,
.first-meal-panel .btn-soft i, .first-meal-panel .btn-soft svg {
  width: 17px;
  height: 17px;
  flex: none;
}
/* Спиннер в кнопке прячет и подпись, и иконку рядом с ней. */
.first-meal-panel .is-busy svg { visibility: hidden; }
/* Шапка экрана: слева дом, справа вход для тех, у кого дневник уже есть. */
.journey-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.journey-login {
  flex: none;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.journey-login:hover { color: var(--text-primary); border-color: var(--border-strong); }
.journey-login:active { transform: scale(0.97); }

.journey-norm {
  margin: 16px 0; padding: 16px; border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface);
}
.journey-norm > span { display: block; color: var(--text-secondary); font-size: 14px; }
.journey-norm strong { display: block; margin: 6px 0 12px; font-size: 32px; font-variant-numeric: tabular-nums; }
.journey-norm strong small { font-size: 16px; font-weight: 500; }
.journey-norm .btn-soft { width: 100%; min-height: 46px; }
.journey-norm .wm-hint { margin-bottom: 0; }
.journey-norm-remaining { padding: 12px; border-radius: var(--r-sm); background: var(--surface); font-size: 14px; line-height: 1.5; }

/* Вторичное действие — текстом. Две одинаковые пилюли подряд под зелёной
   кнопкой стирали разницу между «сохранить» и «переделать». */
.journey-link {
  display: block;
  margin: 16px auto 0;
  padding: 8px 12px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: color-mix(in srgb, var(--text-secondary) 30%, transparent);
  transition: color var(--dur) var(--ease);
}
.journey-link:hover { color: var(--text-primary); }
.first-meal-panel textarea { width: 100%; box-sizing: border-box; }
@keyframes journey-rise { from { opacity: 0; transform: translateY(10px); } }

.journey-eyebrow {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--color-primary);
}

/* ----------------- Ввод ----------------- */
.journey-form {
  margin-top: 18px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.journey-form .field span { font-size: 13px; font-weight: 600; color: var(--text-secondary); }
.journey-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0 0; }
.journey-tabs [aria-pressed="true"] { box-shadow: inset 0 0 0 2px currentColor; }
.journey-form .journey-tabs .btn-soft { flex: 1 1 140px; justify-content: center; }

/* Миниатюра выбранного снимка: имя файла с телефона человеку ничего не говорит. */
.journey-photo {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  animation: journey-rise 0.3s var(--ease) both;
}
.journey-photo[hidden] { display: none; }
.journey-photo img {
  width: 52px;
  height: 52px;
  flex: none;
  object-fit: cover;
  border-radius: var(--r-sm);
}
.journey-photo span { flex: 1; font-size: 13.5px; color: var(--text-secondary); }
.journey-photo button {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

/* ----------------- Итог разбора ----------------- */
/* Итог въезжает лесенкой: карточка, кнопка, подсказки. Анимация живёт на
   самих элементах, а не на классе от JS, — иначе результат, пришедший в
   свёрнутой вкладке, остался бы невидимым до возврата на страницу. */
#fm-result:empty { display: none; }
#fm-result > * { animation: journey-rise 0.4s var(--ease) both; }
#fm-result > *:nth-child(2) { animation-delay: 60ms; }
#fm-result > *:nth-child(3) { animation-delay: 110ms; }
#fm-result > *:nth-child(4) { animation-delay: 160ms; }

.journey-card {
  padding: 16px 14px;
  margin: 20px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.first-meal-panel .journey-card { box-shadow: var(--shadow-card); }
.journey-card h3 { margin: 0 0 10px; font-size: 18px; }
.journey-card .btn-soft, .journey-card .btn-primary { margin: 8px 6px 0 0; }

/* «Как вернуться к дневнику»: гостю без входа (guest_return.js). Кнопки во всю
   ширину столбиком — три равноправных способа, и палец не промахивается. */
.guest-return .gr-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.guest-return .gr-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  flex: none; width: 100%; margin: 0; text-decoration: none; box-sizing: border-box;
}
.guest-return .gr-btn svg { width: 18px; height: 18px; }
.guest-return a.gr-btn[aria-disabled="true"] { opacity: 0.6; pointer-events: none; }
.guest-return .gr-note { margin: 0 0 6px; font-size: 13px; }
.guest-return .gr-mail-form { display: flex; flex-direction: column; gap: 8px; }
.guest-return .gr-mail-form[hidden] { display: none; }
.guest-return .gr-status:empty { display: none; }

/* Шапка итога держится в трёх строках: блюдо, калории с разбросом, Б/Ж/У.
   Уверенность словом отсюда убрана: на витрине это лишний бейдж рядом с
   названием, а честность разброса и так видна в самой строке калорий. */
.journey-dish {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.journey-total {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 7px;
  margin-top: 2px;
}
.journey-total b {
  font-size: 36px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.journey-total span { font-size: 14px; font-weight: 600; color: var(--text-secondary); }
.journey-total em {
  font-style: normal;
  font-size: 12.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.journey-macros { display: flex; gap: 6px; margin: 10px 0 0; }
.journey-macro {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 5px;
  padding: 7px 9px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--text-secondary);
  white-space: nowrap;
}
.journey-macro b { font-size: 13.5px; font-weight: 800; color: var(--text-primary); }
.journey-macro.m-p b { color: var(--color-accent); }
.journey-macro.m-f b { color: var(--color-danger); }
.journey-macro.m-c b { color: var(--color-primary-2); }

/* ----------------- Состав и порции ----------------- */
.journey-portions { margin-top: 6px; }
.journey-portion {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 74px;
  align-items: center;
  gap: 8px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.journey-portion:last-child { border-bottom: 0; }
/* Отметка позиции — кружок с галочкой, тот же знак, которым в ожидании
   отмечались посчитанные продукты. Системный квадрат тут выглядел чужим:
   у него своя палитра, свой размер и вид, разный в каждом браузере. */
.journey-portion input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.journey-portion input[type="checkbox"]:checked {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.journey-portion input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 3px;
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.journey-portion input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.journey-portion span { overflow-wrap: anywhere; }
.journey-portion-name { font-size: 14.5px; font-weight: 600; line-height: 1.3; }
/* Вклад позиции и происхождение веса: ровное число без оговорки выглядит
   измеренным, хотя вес чаще всего прикинут по фото. */
.journey-portion-name em {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.journey-portion-name em:empty { display: none; }
/* Снятая галочка гасит строку: видно, что позиция уже не в итоге. */
.journey-portion:has(input[type="checkbox"]:not(:checked)) .journey-portion-name { opacity: 0.45; }

.journey-grams { position: relative; display: block; }
.journey-grams input[type="number"] {
  width: 100%;
  min-width: 0;
  min-height: 42px;
  padding: 8px 22px 8px 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  box-sizing: border-box;
  background: var(--fill-input);
  color: inherit;
  font-size: 16px;
  font-weight: 600;
  text-align: right;
  transition: border-color var(--dur) var(--ease);
}
.journey-grams input[type="number"]:focus {
  outline: none;
  border-color: var(--color-primary);
}
.journey-grams i {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-style: normal;
  font-size: 13px;
  color: var(--text-muted);
  pointer-events: none;
}

/* Кнопка пересчёта загорается, только когда есть что пересчитывать. */
.journey-recount { transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease); }
.journey-recount.is-ready {
  border-color: color-mix(in srgb, var(--color-primary) 55%, var(--border));
  color: var(--color-primary);
}

/* Ожидание внутри кнопки: без него нажатие выглядит непринятым. */
.first-meal-panel .btn-primary.is-busy,
.first-meal-panel .btn-soft.is-busy {
  position: relative;
  color: transparent;
}
.first-meal-panel .is-busy::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, #fff 45%, transparent);
  border-top-color: #fff;
  animation: journey-spin 0.8s linear infinite;
}
.first-meal-panel .btn-soft.is-busy::after {
  border-color: color-mix(in srgb, var(--text-secondary) 35%, transparent);
  border-top-color: var(--color-primary);
}
@keyframes journey-spin { to { transform: rotate(360deg); } }

.journey-shortcut { display: flex; width: 100%; align-items: center; gap: 12px; justify-content: space-between; text-align: left; background: none; color: inherit; padding: 14px 0; border: 0; border-bottom: 1px solid var(--border, #e1e6de); font: inherit; cursor: pointer; }
.journey-shortcut span:first-child { flex: 1; overflow-wrap: anywhere; }
.journey-shortcut span:last-child { flex-shrink: 0; font-size: 12px; }
/* Юридическая строка: своя типографика вместо браузерного синего. */
.journey-legal {
  margin-top: 22px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}
.journey-legal a {
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--text-secondary) 35%, transparent);
}
.journey-legal a:hover { color: var(--text-primary); }
#fm-status:not(:empty) { margin: 20px 0; }
#fm-status.is-error {
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--color-danger) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--color-danger) 28%, var(--border));
  color: var(--text-primary);
  animation: journey-rise 0.3s var(--ease) both;
}
#fm-progress { margin: 22px 0; }
.wm-result ~ #wm-shortcuts { margin-top: 24px; }
[data-saved="1"] #wm-shortcuts { display: none; }

/* Ниже 400 px подпись и число в плитке уже не помещаются в одну строку — там
   значение уходит под подпись, а плитки остаются в один ряд. */
@media (max-width: 400px) {
  .journey-macro { flex-direction: column; align-items: flex-start; gap: 2px; }
}

@media (max-width: 320px) {
  .journey-macros { flex-wrap: wrap; }
  .journey-macro { flex: 1 1 calc(50% - 4px); }
}

@media (prefers-reduced-motion: reduce) {
  .first-meal-panel,
  .journey-photo,
  #fm-result > * { animation: none; }
  .first-meal-panel .is-busy::after { animation-duration: 2s; }
}

/* web_desktop.css */
/* =====================================================
   Адаптация под ПК (mobile-first сохраняем без изменений).
   Загружается последним из CSS — уверенно перекрывает базовые
   мобильные правила из app.css / meal_*.css / recipes.css.
   Всё под медиазапросами: на телефонах ничего не меняется.
   ===================================================== */
@media (min-width: 900px) {
  :root {
    --side-w: 240px;
    --content-max: 760px;
  }

  /* Контент отодвигается вправо от боковой панели и центрируется. */
  body { padding-left: var(--side-w); }
  .main-content {
    max-width: var(--content-max);
    padding: 28px var(--spacing-lg);
    padding-bottom: 48px;
    margin: 0 auto;
  }

  /* Нижняя «плавающая» навигация превращается в левый сайдбар. */
  .bottom-nav {
    left: 0;
    top: 64px;
    bottom: 0;
    transform: none;
    width: var(--side-w);
    height: auto;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 4px;
    padding: 12px;
    border: 0;
    border-right: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    background: var(--bg-app);
  }
  .nav-item {
    flex: none;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    font-size: 14.5px;
    padding: 11px 14px;
    border-radius: var(--r-md);
  }
  .nav-item svg { width: 21px; height: 21px; }
  .nav-item.active {
    background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  }
  .nav-item.active svg { transform: none; }

  /* Лого-капсула становится шапкой сайдбара (иначе она скрыта вне fullscreen). */
  .tg-brand {
    display: flex;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1001;
    width: var(--side-w);
    height: 64px;
    padding: 0 20px;
    align-items: center;
    gap: 10px;
    border-right: 1px solid var(--border);
    background: var(--bg-app);
    color: var(--text-primary);
    font-weight: 800;
    font-size: 17px;
    letter-spacing: -0.4px;
  }
  .tg-brand .tg-brand-icon { width: 22px; height: 22px; color: var(--color-primary); }
  .tg-brand .tg-brand-name { font-size: 17px; }

  /* Затемнение у нижнего края и так не нужно без плавающего меню. */
  .bottom-fade { display: none; }

  /* Оставляем внизу сайдбара место под кнопку добавления приёма. */
  .bottom-nav { padding-bottom: 76px; }

  /* FAB превращается в полноширинную кнопку внизу бокового меню. */
  body:not(.tg-webapp) .fab-add {
    left: 12px;
    right: auto;
    bottom: 16px;
    width: calc(var(--side-w) - 24px);
    height: 48px;
    gap: 8px;
    padding: 0 16px;
    border-radius: var(--r-md);
    font-size: 14.5px;
    font-weight: 700;
  }
  .fab-add svg { width: 20px; height: 20px; }
  .fab-add-label { display: inline; }

  /* Тосты центрируем над контентной областью, а не над всем окном. */
  .toast { left: calc(50% + var(--side-w) / 2); }

  /* Сводка: двухколоночная «дашборд»-раскладка.
     :not(.hidden) — иначе ID-специфичность перебила бы .view.hidden,
     и «Сводка» не скрывалась бы при переходе в другой раздел. */
  #view-dashboard:not(.hidden) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-md);
    align-items: start;
  }
  #view-dashboard > .hero-card,
  #view-dashboard > .share-day-btn,
  #view-dashboard > .food-day-note { grid-column: 1 / -1; }
  #view-dashboard > .glass-card { margin-bottom: 0; }

  /* Рецепты: больше карточек в ряд. */
  .recipes-grid { grid-template-columns: repeat(3, 1fr); }

  /* Шторки (приём / рецепт / нутриенты / инфо) — центрированные модалки. */
  .sheet {
    left: 50%;
    right: auto;
    top: 50%;
    bottom: auto;
    width: min(560px, calc(100vw - 48px));
    max-height: 85vh;
    border-radius: var(--r-lg);
    transform: translate(-50%, -50%) scale(0.96);
    transition: transform 0.28s var(--ease-spring), opacity var(--dur) var(--ease);
    opacity: 0;
    padding: 20px 22px 24px;
  }
  .sheet-overlay.open .sheet { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .sheet-handle { display: none; }

  /* Полноэкранный подраздел (форма приёма, настройки, пикеры) на ПК
     превращается в центрированное модальное окно с затемнением фона —
     иначе форма растягивается на весь экран и выглядит «мобильной». */
  .subview {
    align-items: center;
    padding: 40px 24px;
    background: rgba(8, 11, 16, 0.5);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
  }
  .subview-head,
  .subview-body {
    width: 100%;
    max-width: 520px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-float);
  }
  /* Авто-поля сверху/снизу центрируют панель по вертикали, но оставляют
     прокрутку, если содержимое выше окна. */
  .subview-head {
    margin-top: auto;
    margin-bottom: 0;
    padding: 18px 22px;
    gap: 12px;
    border-bottom: 1px solid var(--border);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
  }
  .subview-body {
    margin-bottom: auto;
    padding: 22px;
    border-top: none;
    border-radius: 0 0 var(--r-lg) var(--r-lg);
  }
  .subview-title { font-size: 17px; }
  /* Панель оплаты на ПК липнуть к низу окна не должна: подраздел здесь —
     модалка по центру, поэтому возвращаем ей обычные отступы карточки. */
  .subview.sv-pay,
  .subview:has(.sub-pay-bar) { padding-bottom: 40px; }
  .sv-pay .subview-body,
  .subview-body:has(.sub-pay-bar) { flex: 0 1 auto; }
  .sub-pay-bar { position: static; margin: 0; padding: 0; background: none; }
  /* В центрированной модалке крестик «Закрыть» — основной способ выйти,
     а «Назад» со стрелкой избыточен, поэтому его прячем. */
  .subview-back { display: none !important; }
}

/* Более широкие экраны — просторнее контент и ещё больше рецептов. */
@media (min-width: 1280px) {
  :root { --content-max: 900px; }
  .recipes-grid { grid-template-columns: repeat(4, 1fr); }
}

/* Наведение мышью (только устройства с курсором — тач не затрагивается). */
@media (hover: hover) and (pointer: fine) {
  .recipe-card,
  .tcard,
  .nutri-tile,
  .share-day-btn,
  .add-entry-btn {
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
      border-color var(--dur) var(--ease);
  }
  .recipe-card:hover,
  .tcard:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-float);
    border-color: var(--border-strong);
  }
  .nutri-tile:hover { border-color: var(--border-strong); }
  .share-day-btn:hover,
  .add-entry-btn:hover { border-color: var(--color-primary); }
  .nav-item:hover { color: var(--text-primary); }
  .fab-add:hover { filter: brightness(1.05); box-shadow: var(--shadow-float); }
  .btn-primary:hover { filter: brightness(1.04); }
  .btn-ghost:hover,
  .btn-soft:hover { border-color: var(--border-strong); }
  .pf-row:hover,
  .pf-stat:not([disabled]):hover { background: var(--surface-2); }
  .opt-card:not(.active):hover { border-color: var(--border-strong); }
  .stp-btn:hover { background: var(--surface-2); color: var(--color-primary); }
  .day-cell:not(.active):not(:disabled):hover { background: var(--surface-2); }
  .chip:hover,
  .seg-btn:not(.active):hover { color: var(--text-primary); }
}

/* onboarding.css */
/* Мастер первичной настройки веб-версии (пол/возраст/рост/вес/цель/…).
   Полноэкранный поверх всего, с прогресс-баром, шагами-карточками и итогом. */

.onb {
  position: fixed;
  inset: 0;
  z-index: 3200;
  display: none;
  flex-direction: column;
  background:
    radial-gradient(120% 80% at 50% -10%,
      color-mix(in srgb, var(--color-primary) 12%, transparent) 0%,
      transparent 60%),
    var(--bg-app);
  padding: calc(16px + env(safe-area-inset-top, 0px)) 0
    calc(16px + env(safe-area-inset-bottom, 0px));
}
.onb.show { display: flex; animation: onbIn var(--dur) var(--ease); }
@keyframes onbIn { from { opacity: 0; } to { opacity: 1; } }
html.onb-open { overflow: hidden; }
html.onb-open body { overflow: hidden; }

/* Обёртка шагов: на мобильных просто заполняет экран колонкой (как раньше),
   на ПК превращается в центрированную карточку (см. медиазапрос ниже). */
.onb-panel {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
}

/* fullscreen Telegram: не заезжаем под системный бар */
body.tg-fullscreen .onb {
  padding-top: calc(16px + var(--tg-content-safe-area-inset-top, 48px));
}

/* -------- Прогресс -------- */
.onb-top { padding: 0 20px 8px; }
.onb-progress {
  height: 6px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--text-muted) 24%, transparent);
  overflow: hidden;
}
.onb-progress-bar {
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--color-primary), var(--color-primary-2));
  transition: width var(--dur) var(--ease);
}

/* -------- Тело шага -------- */
.onb-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 20px 8px;
  display: flex;
  flex-direction: column;
  /* safe: центрируем, когда контент помещается, но не обрезаем верх, если
     список вариантов выше экрана (иначе первый пункт уезжает под прогресс). */
  justify-content: safe center;
}
.onb-step-head { margin-bottom: 16px; text-align: center; }
.onb-step-title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.5px;
  line-height: 1.2;
}
.onb-step-sub {
  margin-top: 8px;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.45;
}

/* -------- Интро / итог -------- */
.onb-hero { text-align: center; animation: onbFade var(--dur) var(--ease); }
@keyframes onbFade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.onb-hero-icon,
.onb-done-ic {
  width: 76px;
  height: 76px;
  margin: 0 auto 18px;
  border-radius: 24px;
  display: grid;
  place-items: center;
  color: #fff;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-2));
  box-shadow: var(--shadow-float);
}
.onb-hero-icon svg, .onb-done-ic svg { width: 38px; height: 38px; }
.onb-done-ic {
  background: linear-gradient(135deg, var(--color-primary), #16a34a);
  animation: onbPop var(--ease-spring) 0.4s;
}
@keyframes onbPop { 0% { transform: scale(0.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
.onb-hero-title { font-size: 26px; font-weight: 800; letter-spacing: -0.6px; line-height: 1.15; }
.onb-hero-sub {
  margin: 12px auto 0;
  max-width: 340px;
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1.5;
}
.onb-hero-list {
  list-style: none;
  margin: 22px auto 0;
  padding: 0;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: left;
}
.onb-hero-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14.5px;
  font-weight: 600;
}
.onb-hero-list li svg {
  width: 20px; height: 20px; flex-shrink: 0;
  color: var(--color-primary);
}

/* -------- Карточки выбора -------- */
.onb-cards { display: flex; flex-direction: column; gap: 10px; }
.onb-cards-2 { flex-direction: row; }
.onb-cards-2 .onb-card { flex: 1; flex-direction: column; text-align: center; padding: 22px 14px; }
.onb-cards-2 .onb-card-ic { margin: 0 auto 4px; }
.onb-cards-2 .onb-card-check { position: absolute; top: 10px; right: 10px; }

.onb-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
    transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.onb-card:active { transform: scale(0.985); }
/* Активная карточка: не только рамка+галочка, но и мягкая заливка и цветная
   иконка — так выбор виден сразу, даже не глядя на галочку сбоку. */
.onb-card.active {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 20%, transparent);
}
.onb-card-ic {
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 14px;
  display: grid; place-items: center;
  background: var(--surface-2);
  color: var(--color-primary);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.onb-card.active .onb-card-ic {
  background: color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.onb-card-ic svg { width: 24px; height: 24px; }
.onb-card-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.onb-card-label { font-size: 16px; font-weight: 700; }
.onb-card-desc { font-size: 13px; color: var(--text-muted); line-height: 1.35; }
.onb-card-check {
  margin-left: auto;
  width: 24px; height: 24px; flex-shrink: 0;
  border-radius: var(--r-pill);
  display: grid; place-items: center;
  background: var(--color-primary);
  color: #fff;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--dur) var(--ease), transform var(--ease-spring) var(--dur);
}
.onb-card-check svg { width: 15px; height: 15px; }
.onb-card.active .onb-card-check { opacity: 1; transform: scale(1); }

/* -------- Числовой ввод -------- */
.onb-num {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: 8px;
}
.onb-step-btn {
  width: 54px; height: 54px; flex-shrink: 0;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  display: grid; place-items: center;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.onb-step-btn:active { transform: scale(0.9); border-color: var(--color-primary); }
.onb-step-btn svg { width: 22px; height: 22px; }
.onb-num-val {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 140px;
  justify-content: center;
}
.onb-num-val input {
  width: 116px;
  border: none;
  background: transparent;
  text-align: right;
  font-size: 52px;
  font-weight: 800;
  letter-spacing: -1.5px;
  color: var(--text-primary);
  padding: 0;
}
.onb-num-val input:focus { outline: none; box-shadow: none; }
.onb-num-val input::-webkit-outer-spin-button,
.onb-num-val input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.onb-num-val input[type=number] { -moz-appearance: textfield; }
.onb-unit { font-size: 18px; font-weight: 700; color: var(--text-muted); }

/* -------- Итог: КБЖУ -------- */
.onb-result { text-align: center; animation: onbFade var(--dur) var(--ease); }
.onb-calc {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 40px 0;
  color: var(--text-muted);
  font-size: 15px;
}
.onb-calc-err { color: #ef4444; }
.onb-calc-err svg { width: 34px; height: 34px; }
.onb-spinner {
  width: 40px; height: 40px;
  border-radius: var(--r-pill);
  border: 3px solid color-mix(in srgb, var(--color-primary) 25%, transparent);
  border-top-color: var(--color-primary);
  animation: onbSpin 0.8s linear infinite;
}
@keyframes onbSpin { to { transform: rotate(360deg); } }
.onb-kcal {
  margin: 22px auto 4px;
  font-size: 54px;
  font-weight: 800;
  letter-spacing: -2px;
  line-height: 1;
  color: var(--color-primary);
}
.onb-kcal span {
  display: block;
  margin-top: 6px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-muted);
}
.onb-macros {
  display: flex;
  gap: 10px;
  margin: 22px auto 0;
  max-width: 360px;
}
.onb-macro {
  flex: 1;
  padding: 14px 8px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.onb-macro-v { font-size: 22px; font-weight: 800; letter-spacing: -0.5px; }
.onb-macro-v i { font-style: normal; font-size: 13px; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.onb-macro-l { font-size: 12.5px; color: var(--text-muted); font-weight: 600; }

/* -------- Футер -------- */
.onb-footer { padding: 10px 20px 4px; }
.onb-footer-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.onb-next {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  order: 2;
}
.onb-next svg { width: 18px; height: 18px; }
.onb-next:disabled { opacity: 0.55; }
.onb-back {
  order: 1;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 12px 8px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.onb-back svg { width: 18px; height: 18px; }
.onb-skip {
  order: 3;
  flex-basis: 100%;
  margin-top: 2px;
  padding: 10px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* -------- Адаптация под ПК -------- */
/* Мастер из полноэкранной страницы становится центрированной карточкой
   на мягком градиентном фоне. Мобильная версия не затрагивается. */
@media (min-width: 900px) {
  .onb { justify-content: center; padding: 40px 24px; }
  .onb-panel {
    flex: none;
    max-width: 460px;
    max-height: calc(100vh - 80px);
    margin: auto;
    overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-float);
  }
  .onb-top { padding: 18px 26px 10px; }
  .onb-body { padding: 22px 26px; justify-content: flex-start; }
  .onb-footer { padding: 8px 26px 20px; }
}

/* Наведение мышью для карточек выбора и кнопок мастера. */
@media (hover: hover) and (pointer: fine) {
  .onb-card:hover { border-color: var(--border-strong); }
  .onb-card.active:hover { border-color: var(--color-primary); }
  .onb-step-btn:hover { border-color: var(--color-primary); }
  .onb-back:hover,
  .onb-skip:hover { color: var(--text-primary); }
}

/* nudges.css */
/* Полноэкранные модалки-подсказки: «на главный экран» и «пригласить друга».
   Стиль повторяет welcome-splash, чтобы выглядеть как часть онбординга. */
.nudge {
  position: fixed;
  inset: 0;
  z-index: 3200;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow-y: auto;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 22px
    calc(28px + env(safe-area-inset-bottom, 0px));
  background: radial-gradient(120% 78% at 50% 0%,
    color-mix(in srgb, var(--color-primary) 16%, var(--bg-app)) 0%,
    var(--bg-app) 58%);
}
.nudge.show { display: flex; animation: viewIn var(--dur) var(--ease); }
html:has(.nudge.show) { overflow: hidden; }
html:has(.nudge.show) body { overflow: hidden; }

.nudge-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: 14px;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: pointer;
}
.nudge-close svg { width: 20px; height: 20px; }

.nudge-inner {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.nudge-art { width: 186px; max-width: 60%; margin-bottom: 18px; }
.na-svg { width: 100%; height: auto; display: block; overflow: visible; }

.nudge-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--text-primary);
  margin: 0 0 10px;
}
.nudge-text {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0 0 18px;
}
.nudge-note {
  width: 100%;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: 14px;
  padding: 12px 14px;
  margin: 0 0 18px;
}
.nudge-note b { color: var(--text-primary); font-weight: 700; }
.nudge-hint svg { width: 16px; height: 16px; vertical-align: -3px; }

.nudge-cta {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.nudge-cta svg { width: 20px; height: 20px; flex: none; }
.nudge-secondary {
  margin-top: 14px;
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 10px;
}

/* --- Блок «скопировать ссылку» (альтернатива нативному шэрингу) --- */
.nudge-copy {
  width: 100%;
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.nudge-copy-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--fill-input);
  color: var(--text-secondary);
  font-size: 13px;
  padding: 10px 12px;
  outline: none;
  text-overflow: ellipsis;
}
.nudge-copy-input:focus { border-color: var(--color-primary); }
.nudge-copy-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 13.5px;
  font-weight: 650;
  padding: 0 14px;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.nudge-copy-btn svg { width: 16px; height: 16px; }
.nudge-copy-btn:active { filter: brightness(0.97); }

/* --- Иллюстрация «телефон + иконка приложения» --- */
.na-home .na-body {
  fill: var(--surface);
  stroke: color-mix(in srgb, var(--color-primary) 32%, var(--surface-2));
  stroke-width: 3;
}
.na-home .na-line {
  stroke: color-mix(in srgb, var(--text-muted) 45%, transparent);
  stroke-width: 3;
  stroke-linecap: round;
}
.na-home .na-dots rect {
  fill: color-mix(in srgb, var(--color-primary) 15%, var(--surface-2));
}
.na-home .na-app { fill: var(--color-primary); }
.na-home .na-app-glyph { stroke: #fff; }
.na-home .na-badge circle {
  fill: var(--color-primary);
  stroke: var(--bg-app);
  stroke-width: 3;
}
.na-home .na-badge-t {
  fill: #fff;
  font-size: 15px;
  font-weight: 800;
  font-family: inherit;
}

/* --- Иллюстрация «подарок» --- */
.na-gift .na-box { fill: var(--color-primary); }
.na-gift .na-lid { fill: color-mix(in srgb, var(--color-primary) 80%, #000); }
.na-gift .na-ribbon { stroke: #fff; stroke-width: 4; }
.na-gift .na-bow { fill: #fff; }
.na-gift .na-spark path {
  fill: color-mix(in srgb, var(--color-primary) 55%, var(--surface));
}

/* =====================================================
   ПК: модалка-подсказка — компактная центрированная карточка с затемнением
   фона вместо полноэкранного градиента (нативнее для десктопа).
   ===================================================== */
@media (min-width: 900px) {
  .nudge {
    padding: 40px 24px;
    background: rgba(8, 11, 16, 0.5);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
  }
  .nudge-inner {
    max-width: 420px;
    padding: 32px 30px 28px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-float);
  }
  .nudge-art { width: 156px; margin-bottom: 14px; }
  .nudge-title { font-size: 21px; }
}

/* brand.css */
/* Знак бренда картинкой (perek.us). Рисуем маской, а не <img>: SVG в <img> не
   наследует currentColor, а знак нужен и белым на цветной плашке (шапка
   лендинга), и цветным на светлом фоне (капсула в Mini App). */
.brand-mark-img {
  display: block;
  width: 20px;
  height: 20px;
  background: currentColor;
  -webkit-mask: var(--mark) center / contain no-repeat;
  mask: var(--mark) center / contain no-repeat;
}
.tg-brand .brand-mark-img { width: 18px; height: 18px; }
body.tg-fullscreen .tg-brand .brand-mark-img { width: 20px; height: 20px; }
@media (min-width: 900px) {
  .tg-brand .brand-mark-img { width: 22px; height: 22px; }
}

/* home_compact.css */
/* compact_home_v1: порядок блоков на главной — сперва дневник, потом
   необязательный навигатор. Файл меняет ТОЛЬКО раскладку: размеры, цвета,
   шрифты и примитивы (кольцо, .bar, .glass-card, чипы) берём из дизайн-системы
   (theme.css, app.css), чтобы главная не выглядела собранной из чужих кусков. */

/* Шапка карточки: дата и возврат к сегодня. Кольцо и остаток — строкой ниже,
   поэтому сама карточка больше не flex-строка. */
#view-dashboard .hero-card { display: block; padding: 12px 18px 18px; cursor: default; }
.dash-summary-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }

/* Календарь стал чипом с датой: положение в строке новое, вид — тот же
   .hero-cal из дизайн-системы (плитка --surface-2, приглушённая иконка). */
.dash-summary-head .hero-cal {
  position: static;
  width: auto;
  height: 30px;
  gap: 6px;
  padding: 0 12px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-secondary);
}
.dash-summary-head .hero-today { position: static; margin-left: auto; }

.dash-energy { display: flex; align-items: center; gap: var(--spacing-md); }
/* Кольцо и подпись под ним — одна колонка: «1526 из 2200 ккал» относится к
   кольцу, а не к шкалам справа. */
.ring-col { display: flex; flex-direction: column; align-items: center; flex: none; }
.ring-caption { margin-top: 6px; font-size: 11px; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
/* Без нормы и в режиме без цифр подписи нет — пустая строка иначе поднимала бы
   кольцо над серединой карточки. */
.ring-caption:empty { display: none; }
.dash-figures { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
/* Приглашение задать норму и прибавка за тренировку бывают редко: пустой
   контейнер не должен занимать место над шкалами. */
.dash-figures .macros:empty { display: none; }
/* Подпись под числом ограничена шириной просвета кольца на её высоте: если
   текст всё же окажется длиннее, он перенесётся по центру, а не наедет на дугу. */
#view-dashboard .ring-label { max-width: 96px; line-height: 1.2; text-align: center; }

/* Шкалы Б/Ж/У рисует общий App.renderMacros (те же .goal-row и .bar, что в
   дневной сводке). Здесь только раскладка: три строки во всю ширину колонки,
   подпись слева, цифры справа. Тремя колонками в трети карточки на каждую
   оставалось около 55 px, и «317 / 160 г» обрезалось многоточием. */
.dash-macros { display: flex; flex-direction: column; gap: 11px; }
/* Без целей строка пустая — иначе под остатком висит полоса отступа. */
.dash-macros:empty { display: none; }
.dash-macros .goal-row { gap: 6px; margin-bottom: 5px; font-size: 12px; }
/* Режется подпись, а не цифры: «Углеводы» узнаётся и наполовину, «317 / 160 г»
   без последнего знака — нет. */
.dash-macros .goal-row span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-macros .goal-row span:last-child { flex: none; white-space: nowrap; }
.dash-macros .goal-skel-row + .goal-skel-row { margin: 0; }

/* «План питания под норму» — подвал карточки, а не вставленная в неё плитка:
   пунктирная рамка поверх фона --surface-2 внутри карточки читалась как чужой
   элемент, наклеенный сверху. Тот же приём, что у строки недели в карточке
   «Сегодня»: волосяная линия сверху, приглушённый текст и шеврон. */
#dash-plan-cta .mp-dash-cta {
  margin: 14px 0 0;
  padding: 12px 0 0;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  background: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
}
#dash-plan-cta .mp-dash-cta:active { opacity: 0.6; }

/* Одно действие под шапкой. В Telegram плавающей кнопки нет вовсе, поэтому
   на главной это единственный способ добавить еду. */
.dash-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-bottom: var(--spacing-md);
}
.dash-add svg { width: 20px; height: 20px; }
body[data-view="dashboard"] .fab-add { display: none; }

/* Последние приёмы: та же карточка, что и остальные блоки экрана. */
.dash-diary { margin-bottom: var(--spacing-md); }
.dash-diary-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 8px; }
.dash-diary-head h2 { font-size: 15px; font-weight: 700; margin: 0; }
.dash-diary-head .link-btn { display: inline-flex; align-items: center; gap: 3px; margin: 0; font-size: 13px; }
.dash-diary-head svg { width: 15px; height: 15px; }
#dash-recent-meals { padding: 0 16px; }
.dash-meal {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 0;
  background: none;
  border: none;
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur) var(--ease);
}
.dash-meal:active { transform: scale(0.99); }
.dash-meal + .dash-meal { border-top: 1px solid var(--border); }
.dash-meal-copy { flex: 1; min-width: 0; }
.dash-meal-name { display: block; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Тип приёма — иконкой, как в дневнике: подпись «Обед» рядом с иконкой
   читается быстрее, чем одно слово среди цифр. */
.dash-meal-time { display: flex; align-items: center; gap: 5px; margin-top: 4px; font-size: 12px; color: var(--text-secondary); }
.dash-meal-time svg { width: 14px; height: 14px; flex: none; color: var(--text-muted); }
.dash-meal-kcal { flex: none; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.dash-meal-kcal small { font-size: 11px; font-weight: 600; color: var(--text-muted); margin-left: 3px; }
/* Раскрытие дня целиком. Строки за пределами первых двух въезжают по очереди:
   рост карточки читается как движение, а не как рывок высоты. */
.dash-meal.is-fresh {
  animation: dash-meal-in 0.28s var(--ease) backwards;
  animation-delay: calc((var(--row, 0) - 2) * 45ms);
}
@keyframes dash-meal-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
.dash-meal-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 100%;
  padding: 12px 0 14px;
  border: none;
  border-top: 1px solid var(--border);
  background: none;
  color: var(--color-primary);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.dash-meal-more svg {
  width: 16px;
  height: 16px;
  transition: transform var(--dur) var(--ease);
}
.dash-meal-more svg.up { transform: rotate(180deg); }

.dash-meal-empty, .dash-meal-retry {
  display: block;
  width: 100%;
  padding: 18px 0;
  background: none;
  border: none;
  color: var(--text-secondary);
  font: inherit;
  font-size: 13px;
  text-align: left;
}
.dash-meal-retry { color: var(--color-primary); font-weight: 700; cursor: pointer; }

/* Нутриенты убраны под раскрытие: заголовок остаётся .card-title, чтобы
   свёрнутая карточка читалась так же, как развёрнутая. */
#view-dashboard #nutrient-card { padding: 0 16px; }
#nutrient-card > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#nutrient-card > summary::-webkit-details-marker { display: none; }
#nutrient-card > summary .card-title { flex: 1; min-width: 0; margin: 0; }
#nutrient-card > summary .nutri-chev { flex: none; width: 18px; height: 18px; color: var(--text-muted); transition: transform var(--dur) var(--ease); }
#nutrient-card[open] > summary .nutri-chev { transform: rotate(180deg); }
#nutrient-summary { padding-bottom: 16px; }

/* Достижения открываются и из «Прогресса»: на главной серия живёт карточкой,
   но искать её там, где лежит вся остальная динамика, тоже логично. */
/* Полка прогресса и карточка практики — блоки одного ряда, и расстояние
   между ними держит контейнер, а не сами блоки: у карточки практики своего
   верхнего отступа не было, и она прилипала к «Наградам» вплотную, хотя
   внутри полки карточки стоят через 12px (.hub). */
.progress-tools {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: var(--spacing-md);
}

/* Кольцо здесь 112 px (app.css), просвет на высоте подписи — около 84 px по
   хорде, а «ККАЛ СЪЕДЕНО» в 10 px занимало 88 и наезжало на дугу. */
@media (max-width: 400px) {
  #view-dashboard .hero-card { padding: 10px 14px 16px; }
  #view-dashboard .ring-label { font-size: 9px; letter-spacing: 0.2px; margin-top: 4px; max-width: 82px; }
  .dash-energy { gap: 12px; }
}

/* Самые узкие экраны: рядом с кольцом остаётся около 130 px, и «Углеводы
   317 / 160 г» в 12 px туда уже не встают одной строкой. */
@media (max-width: 360px) {
  .dash-macros .goal-row { font-size: 11px; }
}

/* ПК: главная стала линейным сценарием (кольцо → действие → дневник), и в две
   колонки он читается вразнобой. Ширину ограничиваем, чтобы строки не
   растягивались на весь экран. */
@media (min-width: 900px) {
  #view-dashboard:not(.hidden) {
    display: flex;
    flex-direction: column;
    gap: 0;
    max-width: 640px;
    margin-inline: auto;
  }
  #view-dashboard > * { width: 100%; }
  #view-dashboard > .glass-card { margin-bottom: var(--spacing-md); }
  /* Колонка Б/Ж/У тут вдвое шире телефонной — мелкий шрифт в ней выглядит
     случайным, а строки стоит развести пошире: места хватает. */
  .dash-macros { gap: 14px; }
  .dash-macros .goal-row { font-size: 13px; }
}

/* Кто просил меньше движения — получает мгновенное раскрытие. */
@media (prefers-reduced-motion: reduce) {
  .dash-meal.is-fresh { animation: none; }
  .dash-meal-more svg { transition: none; }
}

/* Шаги за сегодня (steps_card.js): такой же подвал карточки, как план ниже. */
#dash-steps .steps-home {
  display: flex; align-items: center; gap: 8px; width: 100%;
  margin: 14px 0 0; padding: 12px 0 0;
  border: 0; border-top: 1px solid var(--border); border-radius: 0; background: none;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--text-secondary); text-align: left;
}
#dash-steps .steps-home svg { width: 18px; height: 18px; color: var(--color-primary); flex: 0 0 auto; }
#dash-steps .steps-home span { flex: 1; }
#dash-steps .steps-home .steps-home-chev { color: var(--text-muted); }
#dash-steps .steps-home:active { opacity: 0.6; }
#dash-steps:not(:empty) + #dash-plan-cta .mp-dash-cta { margin-top: 10px; padding-top: 10px; }

/* home_card.css */
/* Виды карточки «Сегодня» (home_card.js): иконки в кольцах, кольца-матрёшка,
   компактная строка, «добрать / не больше», плитки и дополнения к прежнему
   виду. Плюс пилюля клетчатки в шапке, строка «главное сейчас», экран выбора
   вида и разовая подсказка. Подключается после home_compact.css: раскладку
   карточки задаёт он, здесь только содержимое видов. */

/* Цвета нутриентов — одной светлоты и насыщенности, чтобы кольца не спорили.
   Белки — янтарь, углеводы — голубой, жиры — лиловый (розово-красные жиры на
   полном кольце выглядели как перебор), клетчатка — олива: бирюза терялась
   между зелёным калорий и голубым углеводов, а олива желтее и тех и других. У каждого есть
   глубокий тон (-deep) — им рисуется второй круг, когда съедено больше нормы.
   Перебор — не чужой цвет, а тот же тоном глубже с засечкой на границе: это
   повод присмотреться, а не авария. Терракоту пробовали — на голубых углеводах
   она спорила с кольцом, а рядом с янтарём белка путалась с ним (21.09.2026).
   Лимиты (сахар, соль, насыщенные жиры) с 80 % янтарные (--color-accent), за
   лимитом к янтарю добавляется хвост --hc-warn-deep. */
:root {
  --hc-protein: #f5a524; --hc-protein-t: #fdf1dc; --hc-protein-ink: #b45309; --hc-protein-deep: #d97706;
  --hc-fat: #a78bfa; --hc-fat-t: #ede9fe; --hc-fat-ink: #6d28d9; --hc-fat-deep: #7c3aed;
  --hc-carbs: #4db5f5; --hc-carbs-t: #e0f2fe; --hc-carbs-ink: #0369a1; --hc-carbs-deep: #0284c7;
  --hc-fiber: #a3b845; --hc-fiber-t: #f1f5de; --hc-fiber-ink: #5f6f12; --hc-fiber-deep: #849a2a;
  --hc-kcal-t: #dcfce7; --hc-kcal-ink: #15803d; --hc-kcal-deep: #15803d;
  --hc-warn-deep: #d97706; --hc-warn-ink: #b45309;
  --hc-limit: #a3acb9;
}
body.tg-dark-theme {
  --hc-protein: #f5b22d; --hc-protein-t: rgba(245, 178, 45, 0.18); --hc-protein-ink: #f7c75e; --hc-protein-deep: #e0941a;
  --hc-fat: #b39dfb; --hc-fat-t: rgba(179, 157, 251, 0.2); --hc-fat-ink: #c4b5fd; --hc-fat-deep: #8b5cf6;
  --hc-carbs: #5cc0f5; --hc-carbs-t: rgba(92, 192, 245, 0.18); --hc-carbs-ink: #7dd3fc; --hc-carbs-deep: #2ea3e6;
  --hc-fiber: #b5c95a; --hc-fiber-t: rgba(181, 201, 90, 0.18); --hc-fiber-ink: #cddc7f; --hc-fiber-deep: #95ab35;
  --hc-kcal-t: rgba(52, 210, 123, 0.18); --hc-kcal-ink: #4ade80; --hc-kcal-deep: #16a34a;
  --hc-warn-deep: #c98314; --hc-warn-ink: #f7c75e;
  --hc-limit: #6b7480;
}

.hc-n-kcal { --hc-c: var(--color-primary); --hc-t: var(--hc-kcal-t); --hc-ink: var(--hc-kcal-ink); --hc-deep: var(--hc-kcal-deep); }
.hc-n-protein { --hc-c: var(--hc-protein); --hc-t: var(--hc-protein-t); --hc-ink: var(--hc-protein-ink); --hc-deep: var(--hc-protein-deep); }
.hc-n-fat, .hc-n-unsaturated_fat { --hc-c: var(--hc-fat); --hc-t: var(--hc-fat-t); --hc-ink: var(--hc-fat-ink); --hc-deep: var(--hc-fat-deep); }
.hc-n-carbs { --hc-c: var(--hc-carbs); --hc-t: var(--hc-carbs-t); --hc-ink: var(--hc-carbs-ink); --hc-deep: var(--hc-carbs-deep); }
.hc-n-fiber { --hc-c: var(--hc-fiber); --hc-t: var(--hc-fiber-t); --hc-ink: var(--hc-fiber-ink); --hc-deep: var(--hc-fiber-deep); }
.hc-n-sugar, .hc-n-salt, .hc-n-saturated_fat {
  --hc-c: var(--hc-limit); --hc-t: var(--fill-track); --hc-ink: var(--text-secondary); --hc-deep: var(--text-secondary);
}

/* ----------------- Примитивы: кольцо и шкала ----------------- */
.hc-ring { display: block; }
.hc-ring-track { fill: none; stroke: var(--hc-t, var(--fill-track)); }
.hc-ring-fill, .hc-ring-lap {
  fill: none;
  stroke: var(--hc-c, var(--color-primary));
  stroke-linecap: round;
  transition: stroke-dashoffset 0.6s var(--ease);
}
.hc-ring-lap { stroke: var(--hc-deep, var(--hc-c)); }
/* При переборе заливка кончается там, где начинается хвост: скруглённый край
   ушёл бы под хвост и просвечивал каймой. Засечка — цвета карточки. */
.hc-ring-fill.is-cut { stroke-linecap: butt; }
.hc-ring-tick { stroke: var(--surface); }

.hc-bar {
  position: relative;
  display: block;
  flex: 1;
  min-width: 0;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--fill-track);
  overflow: hidden;
}
.hc-bar > i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--hc-c, var(--color-primary));
  transition: width 0.6s var(--ease);
}
.hc-bar-kcal > i, .hc-bar-goal > i { background: var(--color-primary); }
.hc-bar-limit > i { background: var(--hc-limit); }
.hc-bar-warn > i, .hc-bar-over > i { background: var(--color-accent); }
/* Сверх нормы или лимита (home_card.js, bar): заливка до границы ровным
   краем, за засечкой — хвост тоном глубже. */
.hc-bar.is-lapped > i:first-child { border-radius: 0; }
.hc-bar > i.hc-bar-lap {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  border-radius: 0;
  background: var(--hc-deep, var(--hc-kcal-deep));
}
.hc-bar-kcal > i.hc-bar-lap, .hc-bar-goal > i.hc-bar-lap { background: var(--hc-kcal-deep); }
.hc-bar-over > i.hc-bar-lap { background: var(--hc-warn-deep); }
.hc-bar-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--surface);
}
/* У лимита конец шкалы помечен: видно, что это потолок, а не цель. За
   лимитом потолок — засечка внутри шкалы, конец уже не помечаем. */
.hc-bar-limit, .hc-bar-warn, .hc-bar-over { overflow: visible; }
.hc-bar.is-lapped { overflow: hidden; }
.hc-bar-limit::after, .hc-bar-warn::after, .hc-bar-over::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -1px;
  width: 2px;
  height: 12px;
  border-radius: 2px;
  background: var(--text-secondary);
  opacity: 0.5;
}
.hc-bar.is-lapped::after { display: none; }
/* Подпись в тесной клетке: не режется многоточием — home_card.js подставляет
   короткую форму, если полная не влезла. */
.hc-fit { display: block; min-width: 0; overflow: hidden; white-space: nowrap; }
.hc-lock { width: 12px; height: 12px; margin-left: 3px; color: var(--text-muted); vertical-align: -1px; }

/* ----------------- Иконки в кольцах (по умолчанию) ----------------- */
.hc-cap {
  margin-bottom: 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hc-irings { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.hc-iring { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }
.hc-iring-ring { position: relative; width: 100%; max-width: 64px; aspect-ratio: 1; }
.hc-iring-ring .hc-ring { width: 100%; height: 100%; }
.hc-iring-ring > svg:not(.hc-ring), .hc-iring-ring > i {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  transform: translate(-50%, -50%);
  color: var(--hc-ink);
}
.hc-iring-val {
  margin-top: 8px;
  font-size: 19px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.hc-iring.hc-over .hc-iring-val { color: var(--hc-ink); }
/* Подпись перебора длиннее («г углев. сверх») — на узком экране она
   переносится на вторую строку, а не выходит за клетку. */
.hc-iring-sub { margin-top: 4px; font-size: 11px; line-height: 1.25; color: var(--text-secondary); text-wrap: balance; }

/* ----------------- Кольца-матрёшка ----------------- */
.hc-rings { display: flex; align-items: center; gap: 14px; }
.hc-rings-col { display: flex; flex-direction: column; align-items: center; flex: none; }
.hc-nest { position: relative; width: 148px; aspect-ratio: 1; }
.hc-nest-svg { display: block; width: 100%; height: 100%; }
.hc-nest-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.hc-nest-center b { font-size: 21px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.hc-nest-center.hc-over b { color: var(--hc-ink); }
.hc-nest-center span {
  margin-top: 3px;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hc-rings-cap { margin-top: 6px; font-size: 11px; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.hc-legend { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 13px; }
.hc-leg { display: flex; gap: 8px; }
.hc-dot { width: 9px; height: 9px; margin-top: 4px; border-radius: 50%; flex: none; background: var(--hc-c); }
.hc-leg-body { flex: 1; min-width: 0; }
.hc-leg-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; column-gap: 6px; }
.hc-leg-name { font-size: 12.5px; color: var(--text-secondary); }
.hc-leg-val { font-size: 12.5px; font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hc-leg-val b { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.hc-leg-sub { display: block; margin-top: 2px; font-size: 11px; color: var(--text-muted); }
.hc-leg.hc-over .hc-leg-sub { color: var(--hc-ink); }

/* ----------------- Строка калорий (компактный вид и «добрать») ----------------- */
.hc-kline { display: flex; align-items: baseline; gap: 7px; margin-bottom: 10px; }
.hc-kline-num { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.hc-kline.hc-over .hc-kline-num { color: var(--hc-ink); }
.hc-kline-label { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.hc-kline-of { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hc-bar-kcal { height: 8px; }

.hc-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.hc-pill {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px 0 8px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  font-size: 12px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hc-pill b { font-weight: 700; color: var(--text-primary); }
.hc-pill.hc-over b { color: var(--hc-ink); }
.hc-pill small { font-size: 12px; font-weight: 600; color: var(--text-muted); }

/* ----------------- Добрать / не больше ----------------- */
.hc-gl-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 16px 0 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.hc-gl-head.is-goal { color: var(--hc-kcal-ink); }
.hc-gl-head svg { width: 14px; height: 14px; }
.hc-gl-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 30px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
}
button.hc-gl-row { cursor: pointer; -webkit-tap-highlight-color: transparent; }
button.hc-gl-row:active { opacity: 0.6; }
.hc-gl-name {
  display: flex;
  align-items: center;
  width: 92px;
  flex: none;
  overflow: hidden;
  white-space: nowrap;
  font-size: 12.5px;
  color: var(--text-secondary);
}
.hc-gl-right {
  width: 84px;
  flex: none;
  text-align: right;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hc-gl-right.is-goal { font-weight: 700; color: var(--hc-kcal-ink); }
.hc-gl-right.is-done { color: var(--text-muted); }
.hc-gl-right.is-warn { font-weight: 700; color: var(--hc-protein-ink); }
.hc-gl-right.is-over { font-weight: 700; color: var(--hc-warn-ink); }
.hc-gl-right.is-locked { color: var(--text-muted); }

/* ----------------- Плитки ----------------- */
.hc-ghead { display: flex; align-items: center; gap: 14px; }
.hc-ghead-ring { position: relative; width: 72px; height: 72px; flex: none; }
.hc-ghead-ring > b {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.hc-ghead-body { min-width: 0; display: flex; flex-direction: column; }
.hc-ghead-top { display: flex; align-items: baseline; gap: 7px; }
.hc-ghead-top b { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.hc-ghead-top.hc-over b { color: var(--hc-ink); }
.hc-ghead-top span { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.hc-ghead-cap { margin-top: 5px; font-size: 11.5px; font-weight: 600; color: var(--text-muted); }
.hc-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 16px; }
.hc-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 13px 10px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  overflow: hidden;
  font: inherit;
  color: inherit;
  text-align: left;
}
button.hc-tile { cursor: pointer; -webkit-tap-highlight-color: transparent; }
button.hc-tile:active { transform: scale(0.98); }
.hc-tile > .hc-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  border-radius: 0;
  overflow: hidden;
}
.hc-tile > .hc-bar::after { display: none; }
.hc-tile-label {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: 11.5px;
  color: var(--text-secondary);
}
.hc-tile-label > svg:first-child, .hc-tile-label > i:first-child {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--hc-ink);
}
.hc-tile-val { font-variant-numeric: tabular-nums; white-space: nowrap; }
.hc-tile-val b { font-size: 17px; font-weight: 800; color: var(--text-primary); }
.hc-tile.hc-over .hc-tile-val b { color: var(--hc-ink); }
.hc-tile-val small { font-size: 11px; font-weight: 600; color: var(--text-muted); }
.hc-tile.is-locked .hc-tile-val b { font-size: 13px; color: var(--text-muted); }

/* ----------------- Дополнения к прежнему виду ----------------- */
.hero-extra { margin-top: 14px; }
.hc-more {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-secondary);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-more-t { flex: 1; }
.hc-sdots { display: inline-flex; gap: 4px; }
.hc-sdot { width: 8px; height: 8px; border-radius: 50%; background: var(--hc-limit); }
.hc-sdot.is-goal { background: var(--color-primary); }
.hc-sdot.is-warn { background: var(--color-accent); }
.hc-sdot.is-over { background: var(--hc-warn-deep); }
.hc-sdot.is-locked { background: var(--fill-track); }
.hc-more-chev { width: 16px; height: 16px; color: var(--text-muted); transition: transform var(--dur) var(--ease); }
.hc-more[aria-expanded="true"] .hc-more-chev { transform: rotate(180deg); }
.hc-more-list { display: flex; flex-direction: column; padding: 6px 12px 0; }
.hc-more-list[hidden] { display: none; }
.hc-lrow {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 34px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-lrow > svg:first-child, .hc-lrow > i:first-child { width: 15px; height: 15px; flex: none; color: var(--hc-ink); }
.hc-lrow-name {
  width: 92px;
  flex: none;
  overflow: hidden;
  white-space: nowrap;
  font-size: 12.5px;
  color: var(--text-secondary);
}
.hc-lrow-val, .hc-meter-val {
  flex: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hc-lrow-val b, .hc-meter-val b { font-weight: 700; color: var(--text-primary); }

.hc-meters {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.hc-meter {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-meter-name {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  font-size: 11px;
  color: var(--text-secondary);
}
.hc-meter-name > svg, .hc-meter-name > i { width: 13px; height: 13px; flex: none; color: var(--hc-ink); }
.hc-meter-val { font-size: 12.5px; }
.hc-meter .hc-bar { flex: none; height: 4px; margin-top: 2px; }
.hc-meter .hc-bar::after { top: -2px; height: 8px; }

/* ----------------- Шапка: клетчатка ----------------- */
.hc-fiber-slot { margin-left: auto; display: inline-flex; }
.hc-fiber {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px 0 2px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--hc-t);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-fiber:active { opacity: 0.7; }
/* Кружок заполнения почти во всю высоту пилюли: яблоко внутри — 15 px и чуть
   толще линией, иначе блик и хвостик сливаются в пятно. */
.hc-fiber-ring { position: relative; width: 26px; height: 26px; flex: none; }
.hc-fiber-ring .hc-ring { width: 100%; height: 100%; }
.hc-fiber-ring .hc-ring-tick { stroke: var(--hc-t); }
.hc-fiber-ring > svg:not(.hc-ring), .hc-fiber-ring > i {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 15px;
  height: 15px;
  transform: translate(-50%, -50%);
  color: var(--hc-ink);
  stroke-width: 2.3;
}
.hc-fiber-label { color: var(--hc-ink); }
.hc-fiber-val { font-weight: 600; color: var(--text-muted); }
.hc-fiber-val b { font-weight: 700; color: var(--text-primary); }
.hc-fiber.is-locked {
  padding: 0 11px 0 9px;
  border: 1px dashed color-mix(in srgb, var(--hc-fiber) 45%, transparent);
  background: transparent;
  color: var(--hc-fiber-ink);
}
.hc-fiber.is-locked > svg:first-child, .hc-fiber.is-locked > i:first-child { width: 14px; height: 14px; }
.hc-fiber.is-locked .hc-fiber-label { color: var(--hc-fiber-ink); }

/* ----------------- Главное сейчас ----------------- */
/* Две строки: что главное и сколько ещё, а под ними — что будет по нажатию.
   Строка «План питания под норму» ведёт туда же, поэтому, пока видна эта,
   та прячется: две кнопки подряд в одно окно выглядели как два разных дела. */
.hero-focus { margin-top: 14px; }
.hero-card.has-focus #dash-plan-cta { display: none; }
.hc-focus {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--hc-c) 14%, var(--surface));
  font: inherit;
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hc-focus:active { opacity: 0.7; }
.hc-focus-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  background: var(--surface);
}
.hc-focus-ic > svg, .hc-focus-ic > i { width: 17px; height: 17px; color: var(--hc-ink); }
.hc-focus-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.hc-focus-t b { font-size: 13.5px; font-weight: 700; }
.hc-focus-t small { font-size: 12px; font-weight: 600; color: var(--hc-ink); }
.hc-focus-chev { width: 15px; height: 15px; flex: none; color: var(--hc-ink); }

/* ----------------- Скелет выбранного вида ----------------- */
.hc-skel { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; padding-top: 22px; }
.hc-skel-cell { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.hc-skel-ring { width: 60px; height: 60px; border-radius: 50%; }
.hc-skel-line { width: 40px; height: 14px; }

/* ----------------- Узкие экраны ----------------- */
@media (max-width: 400px) {
  .hc-nest { width: 128px; }
  .hc-rings { gap: 12px; }
  .hc-iring-val { font-size: 17px; }
  .hc-gl-name, .hc-lrow-name { width: 80px; }
  .hc-gl-right { width: 76px; }
}
@media (max-width: 380px) {
  /* В трёх колонках плиток иконка отнимает место у подписи — оставляем слово. */
  .hc-tile-label > svg:first-child, .hc-tile-label > i:first-child { display: none; }
}
@media (max-width: 350px) {
  /* Подпись не помещается рядом с датой — остаются кружок с листиком и
     цифры: листик и так говорит, что это клетчатка. */
  .hc-fiber-label { display: none; }
  .hc-meters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ----------------- Экран выбора вида ----------------- */
.hc-pk-intro { margin: 0 0 14px; font-size: 13px; color: var(--text-secondary); }
/* Ширину слайда и боковые поля задаёт home_card.js (fit): проценты в padding
   и во flex-basis считаются от разных коробок, и слайд выходил бы уже. */
.hc-pk-track {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 6px 0 10px;
  overflow-x: auto;
  overflow-y: hidden;
  box-sizing: border-box;
  transition: height var(--dur) var(--ease);
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.hc-pk-track::-webkit-scrollbar { display: none; }
.hc-pk-slide {
  flex: 0 0 var(--hc-slide, 300px);
  scroll-snap-align: center;
  opacity: 0.55;
  transition: opacity var(--dur) var(--ease);
  cursor: pointer;
}
.hc-pk-slide.is-focused { opacity: 1; }
.hc-pk-card {
  width: 340px;
  box-sizing: border-box;
  margin: 0;
  padding: 12px 16px 16px;
  zoom: var(--hc-zoom, 1);
  pointer-events: none;
}
.hc-pk-slide.is-current .hc-pk-card { box-shadow: 0 0 0 2px var(--color-primary), var(--shadow-card); }
.hc-pk-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.hc-pk-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-secondary);
}
.hc-pk-chip svg { width: 15px; height: 15px; }
.hc-pk-card .hero-extra, .hc-pk-card .hc-more, .hc-pk-card .hc-meters { margin-top: 14px; }

/* Прежний вид в превью: то же кольцо и шкалы, но без canvas. */
.hc-classic { display: flex; align-items: center; gap: 16px; }
.hc-cl-ring { position: relative; width: 116px; height: 116px; flex: none; }
.hc-cl-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.hc-cl-center b { font-size: 26px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.hc-cl-ring.hc-over .hc-cl-center b { color: var(--hc-ink); }
.hc-cl-center small {
  margin-top: 5px;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hc-cl-rows { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.hc-cl-top { display: flex; justify-content: space-between; gap: 6px; margin-bottom: 5px; font-size: 12px; color: var(--text-secondary); }
.hc-cl-top b { font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.hc-cl-row .hc-bar { height: 8px; }

.hc-pk-meta { display: flex; flex-direction: column; align-items: center; margin-top: 8px; text-align: center; }
.hc-pk-name { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; color: var(--text-primary); }
.hc-pk-badge {
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--hc-kcal-t);
  color: var(--hc-kcal-ink);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 20px;
}
.hc-pk-desc { margin-top: 4px; font-size: 12.5px; color: var(--text-secondary); }
.hc-pk-dots { display: flex; gap: 6px; margin-top: 12px; }
.hc-pk-dot { width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--border-strong); transition: width var(--dur) var(--ease); }
.hc-pk-dot.on { width: 18px; background: var(--color-primary); }
.hc-pk-choose {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 16px;
}
.hc-pk-choose:disabled { opacity: 1; background: var(--surface-2); color: var(--text-secondary); box-shadow: none; }
.hc-pk-choose svg { width: 18px; height: 18px; }
.hc-pk-opts { margin-top: 16px; padding: 4px 14px; }
.hc-pk-opt { display: flex; align-items: center; gap: 12px; min-height: 64px; cursor: pointer; }
.hc-pk-opt + .hc-pk-opt { border-top: 1px solid var(--border); }
.hc-pk-opt-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  background: var(--hc-t);
  color: var(--hc-ink);
}
.hc-pk-opt-ic svg { width: 18px; height: 18px; }
.hc-pk-opt-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hc-pk-opt-t { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.hc-pk-opt-s { margin-top: 2px; font-size: 12px; color: var(--text-secondary); }

/* ----------------- Разовая подсказка ----------------- */
.hc-hint {
  position: relative;
  margin: 2px 0 var(--spacing-md);
  padding: 14px 14px 10px;
  border-radius: var(--r-md);
  background: var(--text-primary);
  color: var(--surface);
  box-shadow: var(--shadow-float);
  animation: viewIn var(--dur) var(--ease);
}
.hc-hint::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 36px;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  background: inherit;
  transform: rotate(45deg);
}
.hc-hint-body { display: flex; align-items: flex-start; gap: 10px; }
.hc-hint-body > svg:first-child, .hc-hint-body > i:first-child {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 1px;
  color: var(--color-primary);
}
.hc-hint-t { font-size: 13.5px; font-weight: 700; }
.hc-hint-s { margin-top: 3px; font-size: 12px; line-height: 1.4; opacity: 0.78; }
.hc-hint-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.hc-hint-btn {
  height: 40px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: inherit;
  opacity: 0.8;
  cursor: pointer;
}
.hc-hint-btn.primary { opacity: 1; background: var(--color-primary); color: #052e16; font-weight: 700; }

/* ----------------- Вода: только тем, кто её записывает ----------------- */
/* Маленький стакан с волной и «1 / 2,4 л» шрифтом подписи (home_card.js,
   waterGlass). Без фона и без слова «Вода»: первая версия пилюлей спорила с
   кольцами (владелец, 27.09.2026). Синий глубже голубого углеводов, чтобы
   рядом с их кольцом вода не читалась как углеводы. */
:root { --hc-water: #3b8ff6; --hc-water-2: #9ccdff; }
body.tg-dark-theme { --hc-water: #5aa6ff; --hc-water-2: #2f5f99; }

.hc-water-slot { display: inline-flex; }
/* В строке «Осталось на сегодня» стакан висит справа поверх пустого места и
   высоты строке не добавляет. */
.hc-cap { position: relative; }
.hc-cap .hc-water-slot { position: absolute; right: 0; top: 50%; transform: translateY(-50%); }
.dash-summary-head .hc-water-slot { margin-left: auto; }
.dash-summary-head .hc-water-slot:not(.hidden) ~ .hc-fiber-slot { margin-left: 0; }
/* В шапке втроём тесно: у клетчатки остаются кружок и число. */
.dash-summary-head.has-water .hc-fiber-label { display: none; }

.hc-water {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hc-water-of { font-weight: 600; color: var(--text-muted); }
.hc-water-val { display: inline-block; }
.hc-water-glass { width: 13px; height: 17px; flex: none; overflow: visible; }
.hc-water-rim { fill: none; stroke: var(--text-muted); stroke-width: 1.6; stroke-linejoin: round; opacity: 0.8; }
.hc-water-fill { transform: translateY(26.8px); transition: transform 1.4s cubic-bezier(0.2, 0.8, 0.2, 1); }
.hc-water-wave { animation: hc-water-wave 3.2s linear infinite; }
.hc-water-front { fill: var(--hc-water); }
.hc-water-back { fill: var(--hc-water-2); animation-duration: 4.6s; animation-direction: reverse; }
/* Ориентир дня набран — ободок в цвет воды. */
.hc-water.is-done .hc-water-rim { stroke: var(--hc-water); opacity: 1; }
.hc-water-drop { fill: var(--hc-water); opacity: 0; }
/* Новая запись воды с прошлого показа: капля падает в стакан, он качается,
   число чуть подпрыгивает. */
.hc-water.is-new .hc-water-drop { animation: hc-water-drop 0.9s cubic-bezier(0.5, 0, 0.9, 0.5) 0.15s 1 both; }
.hc-water.is-new .hc-water-glass { transform-origin: 50% 100%; animation: hc-water-wobble 0.7s ease-out 0.9s 1; }
.hc-water.is-new .hc-water-val { animation: hc-water-pop 0.5s ease-out 1.1s 1; }

@keyframes hc-water-wave { from { transform: translateX(0); } to { transform: translateX(11px); } }
@keyframes hc-water-drop {
  0% { opacity: 0; transform: translateY(-4px); }
  15% { opacity: 1; }
  80% { opacity: 1; transform: translateY(15px); }
  100% { opacity: 0; transform: translateY(17px); }
}
@keyframes hc-water-wobble {
  0%, 100% { transform: rotate(0); }
  30% { transform: rotate(-7deg); }
  60% { transform: rotate(5deg); }
  80% { transform: rotate(-2deg); }
}
@keyframes hc-water-pop { 50% { transform: scale(1.15); } }

@media (prefers-reduced-motion: reduce) {
  .hc-water-wave,
  .hc-water.is-new .hc-water-drop, .hc-water.is-new .hc-water-glass, .hc-water.is-new .hc-water-val { animation: none; }
  .hc-water-fill { transition: none; }
}
