/* Light by default (this block), dark under prefers-color-scheme — the app
   follows the phone/browser's system theme out of the box. A user can
   still pin it explicitly (see the "Тема" setting in the Профиль tab,
   wired up in app.js): that sets data-theme on <html>, which the two
   [data-theme=...] blocks below override with — CSS specificity, not
   source order, is why an explicit choice always wins over the media
   query regardless of which one comes first in this file. */
:root {
  --bg: oklch(97% 0.01 75);
  --surface: oklch(99% 0.006 75);
  --surface-2: oklch(94% 0.012 75);
  --field-bg: oklch(96% 0.006 75);
  --text: oklch(20% 0.02 260);
  --hint: oklch(46% 0.02 260 / 65%);
  --hint-faint: oklch(46% 0.02 260 / 55%);
  --border: oklch(20% 0.02 260 / 12%);
  --accent: oklch(60% 0.19 40);
  --accent-text: oklch(99% 0.01 90);
  --green: oklch(60% 0.19 150);
  --danger: oklch(58% 0.19 20);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: oklch(18% 0.02 260);
    --surface: oklch(24% 0.02 260);
    --surface-2: oklch(28% 0.02 260);
    --field-bg: oklch(26% 0.02 260);
    --text: oklch(97% 0.01 90);
    --hint: oklch(97% 0.01 90 / 50%);
    --hint-faint: oklch(97% 0.01 90 / 40%);
    --border: oklch(97% 0.01 90 / 8%);
    --accent: oklch(70% 0.19 40);
    --accent-text: oklch(18% 0.02 260);
    --green: oklch(73% 0.19 150);
    --danger: oklch(68% 0.19 20);
  }
}

:root[data-theme="light"] {
  --bg: oklch(97% 0.01 75);
  --surface: oklch(99% 0.006 75);
  --surface-2: oklch(94% 0.012 75);
  --field-bg: oklch(96% 0.006 75);
  --text: oklch(20% 0.02 260);
  --hint: oklch(46% 0.02 260 / 65%);
  --hint-faint: oklch(46% 0.02 260 / 55%);
  --border: oklch(20% 0.02 260 / 12%);
  --accent: oklch(60% 0.19 40);
  --accent-text: oklch(99% 0.01 90);
  --green: oklch(60% 0.19 150);
  --danger: oklch(58% 0.19 20);
}

:root[data-theme="dark"] {
  --bg: oklch(18% 0.02 260);
  --surface: oklch(24% 0.02 260);
  --surface-2: oklch(28% 0.02 260);
  --field-bg: oklch(26% 0.02 260);
  --text: oklch(97% 0.01 90);
  --hint: oklch(97% 0.01 90 / 50%);
  --hint-faint: oklch(97% 0.01 90 / 40%);
  --border: oklch(97% 0.01 90 / 8%);
  --accent: oklch(70% 0.19 40);
  --accent-text: oklch(18% 0.02 260);
  --green: oklch(73% 0.19 150);
  --danger: oklch(68% 0.19 20);
}

* { box-sizing: border-box; }

/* Any plain author display rule (even something as generic as `input {
   display: block }` below) beats the browser's built-in [hidden] { display:
   none } in the cascade, regardless of selector specificity — normal author
   rules always outrank normal user-agent rules. Without this, every
   hidden-but-styled element (file inputs behind a custom label, etc.)
   silently leaks back into view. This is a permanent, global guard instead
   of patching each element that hits it one at a time. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Shown from first paint (no JS delay) so a slow auth check never flashes
   the logged-in view or the login form before we know which one to show —
   see the boot sequence at the bottom of app.js. */
#splash-screen {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  background: var(--bg);
}
.pulse-scope { width: 220px; height: 56px; overflow: hidden; }
.pulse-scope svg {
  display: block;
  width: 440px;
  height: 56px;
  animation: pulse-scroll 2.4s linear infinite;
}
.pulse-scope path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 7px var(--accent));
}
@keyframes pulse-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-220px); }
}
.splash-title { font: 800 20px "Manrope", sans-serif; letter-spacing: 0.02em; color: var(--text); }
@media (prefers-reduced-motion: reduce) {
  .pulse-scope svg { animation: none; }
}

#app { display: flex; flex-direction: column; height: 100%; }
/* Top/bottom padding both account for edge-to-edge rendering in the
   Android app (its WebView draws under the status bar and gesture-nav bar
   by default) — safe-area-inset-* is 0 in a normal browser tab, so this is
   a no-op there. Without the top one, the first thing in a tab with no
   header (e.g. "Продукт" on "Добавить") hides under the status bar;
   without the bottom one, the last thing in a long tab (e.g. "Выйти из
   аккаунта" on "Профиль") can end up under the bottom tab bar on devices
   with a tall gesture-nav safe area, where 5.5rem alone isn't enough
   clearance for the tab bar's real height. */
#content { flex: 1; overflow-y: auto; padding: calc(0.5rem + env(safe-area-inset-top)) 1.1rem calc(5.5rem + env(safe-area-inset-bottom)); }

.view { display: none; }
.view.active { display: block; animation: fadeUp 0.35s ease both; }

/* Shared entrance/interaction keyframes (redesign) — kept alongside the
   pre-existing pulse-scroll/spin above rather than merged in, so each
   effect's origin (splash vs. general UI motion) stays easy to trace. */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes popIn {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes floatBlob1 {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(18px, -22px); }
}
@keyframes floatBlob2 {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(-16px, 18px); }
}
@keyframes glowPulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .view.active { animation: none; }
}

/* Toast — a brief, self-dismissing confirmation ("Сохранено", "Вес
   сохранён: 75 кг", ...) for actions that already have their own success
   haptic, so it doesn't need to stay on screen or be dismissed by hand the
   way an inline #foo-status error message does. Always in the DOM (no
   [hidden] toggling, since display:none can't be transitioned) — app.js's
   showToast() only ever flips the .visible class. */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(5.5rem + env(safe-area-inset-bottom));
  transform: translate(-50%, 10px);
  max-width: calc(100% - 2.4rem);
  padding: 0.7rem 1.1rem;
  border-radius: 12px;
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  font-size: 0.9rem;
  text-align: center;
  z-index: 30;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.toast.visible { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity 0.01ms; }
}

/* Bottom nav */
.tabs {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 0.5rem 0.4rem calc(0.5rem + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--border);
  z-index: 10;
}
.tab {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  border: none;
  background: none;
  padding: 4px 2px;
  color: var(--hint-faint);
}
.tab-icon { display: block; }
.tab-label { font: 700 10px "Manrope", sans-serif; }
.tab.active { color: var(--accent); }

/* Global floating "+" (quick add), above the tab bar on every screen */
.fab-add {
  position: fixed;
  right: 20px;
  bottom: calc(76px + env(safe-area-inset-bottom));
  width: 60px;
  height: 60px;
  border: none;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--accent-text);
  box-shadow: 0 8px 20px -6px color-mix(in oklch, var(--accent) 60%, transparent);
  z-index: 15;
  cursor: pointer;
}
.fab-menu-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 0 20px calc(140px + env(safe-area-inset-bottom));
  z-index: 20;
}
.fab-menu { display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.fab-menu-item {
  min-width: 200px;
  padding: 14px 22px;
  border: none;
  border-radius: 999px;
  font: 700 15px "Manrope", sans-serif;
  color: var(--accent-text);
  cursor: pointer;
  box-shadow: 0 6px 16px -4px rgba(0, 0, 0, 0.3);
}
.fab-menu-item-accent { background: var(--accent); }
.fab-menu-item-green { background: var(--green); }

/* Add-food bottom sheet (FAB "Добавить еду" / Today's quick-add buttons) */
.add-via-fab-hint { color: var(--hint); font: 600 12.5px "Manrope", sans-serif; text-align: center; margin: 4px 0 0; }
.sheet-overlay {
  position: fixed;
  inset: 0;
  z-index: 25;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.sheet-card {
  width: 100%;
  max-width: 480px;
  background: var(--surface);
  border-radius: 26px 26px 0 0;
  padding: 16px 18px calc(20px + env(safe-area-inset-bottom));
  box-shadow: 0 -20px 50px -20px rgba(20, 15, 10, 0.4);
  max-height: 88vh;
  overflow-y: auto;
}
.sheet-handle { width: 42px; height: 4px; border-radius: 4px; background: var(--border); margin: 0 auto 14px; }
.sheet-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sheet-title { font: 800 17px "Manrope", sans-serif; color: var(--text); letter-spacing: -0.01em; }
.sheet-close {
  width: 32px;
  height: 32px;
  flex: none;
  border: none;
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--hint);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.quick-grams-row { display: flex; gap: 8px; margin: 10px 0 14px; }
.quick-gram-btn {
  flex: 1;
  padding: 9px 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--field-bg);
  color: var(--text);
  font: 700 12px "Manrope", sans-serif;
  cursor: pointer;
}
.quick-gram-btn:hover { border-color: var(--accent); color: var(--accent); }

/* Header */
.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 4px 4px;
}
.app-title { font: 800 19px "Manrope", sans-serif; letter-spacing: -0.01em; }
.app-date { font: 600 13px "Manrope", sans-serif; color: var(--hint); }

/* Today-tab widget carousel (design handoff) — replaces the old single
   hero-card ring with 4 (web) / 5 (mobile) swipeable stat widgets sharing
   one card shell, plus a dot indicator row below. */
.widget-carousel-wrap { margin-top: 10px; }
.widget-carousel {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.widget-carousel::-webkit-scrollbar { display: none; }
.widget-card {
  flex: 0 0 100%;
  scroll-snap-align: center;
  box-sizing: border-box;
  background: linear-gradient(160deg, var(--surface), var(--surface-2));
  border-radius: 24px;
  padding: 20px 18px 16px;
  box-shadow: 0 10px 30px -18px rgba(20, 15, 10, 0.2);
  min-height: 168px;
}
.widget-header { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; }
.widget-hero-row { display: flex; align-items: baseline; gap: 6px; }
.widget-hero-value { font: 800 34px "Manrope", sans-serif; font-variant-numeric: tabular-nums; }
.widget-hero-value.widget-hero-value-sm { font-size: 30px; }
.widget-hero-hint { font: 700 12px "Manrope", sans-serif; color: var(--hint); }
.widget-eyebrow { font: 700 10px "Manrope", sans-serif; color: var(--hint-faint); text-transform: uppercase; letter-spacing: 0.04em; }
.widget-title { font: 800 15px "Manrope", sans-serif; font-variant-numeric: tabular-nums; }
.widget-footnote { font: 600 11px "Manrope", sans-serif; color: var(--hint-faint); margin: 14px 0 0; }

/* Bar charts (weekly calories / weekly activity widgets) */
.bar-chart { display: flex; align-items: flex-end; gap: 8px; height: 96px; margin-top: 16px; }
.bar-chart.bar-chart-short { height: 84px; }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.bar-track { width: 100%; max-width: 26px; border-radius: 6px; background: var(--surface-2); height: 100%; overflow: hidden; display: flex; align-items: flex-end; }
.bar-fill { width: 100%; border-radius: 6px; transition: height 1s cubic-bezier(0.22, 1, 0.36, 1); }
.bar-label { font: 700 10px "Manrope", sans-serif; }
@media (prefers-reduced-motion: reduce) {
  .bar-fill { transition: none; }
}

/* Remaining-calories ring widget */
.widget-ring-card { display: flex; align-items: center; gap: 18px; }
.ring-wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.ring-track { stroke: var(--surface-2); }
.ring-progress { stroke: var(--accent); transition: stroke-dashoffset 1.1s cubic-bezier(0.22, 1, 0.36, 1); }
@media (prefers-reduced-motion: reduce) {
  .ring-progress { transition: none; }
}
.ring-center {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.ring-center span { font: 800 26px "Manrope", sans-serif; font-variant-numeric: tabular-nums; }
.ring-center small { font: 700 10px "Manrope", sans-serif; color: var(--hint); }
.ring-stats { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.ring-stat-label { display: block; font: 700 11px "Manrope", sans-serif; color: var(--hint); }
.ring-stat-value { display: block; font: 800 17px "Manrope", sans-serif; font-variant-numeric: tabular-nums; margin-top: 1px; }
.ring-stat-value.ring-stat-green { color: var(--green); }

/* Day-balance widget */
.balance-bars { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.balance-bar-header { display: flex; justify-content: space-between; font: 700 11px "Manrope", sans-serif; color: var(--hint); margin-bottom: 6px; }
.balance-bar-header span:last-child { font-variant-numeric: tabular-nums; }
.balance-bar-track { height: 12px; border-radius: 12px; background: color-mix(in oklch, var(--text) 7%, transparent); overflow: hidden; }
.balance-bar-fill { height: 100%; border-radius: 12px; width: 0%; transition: width 1s cubic-bezier(0.22, 1, 0.36, 1); }
.balance-bar-fill.intake { background: var(--accent); }
.balance-bar-fill.expenditure { background: var(--green); }
@media (prefers-reduced-motion: reduce) {
  .balance-bar-fill { transition: none; }
}

/* Dot indicator row */
.widget-dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
.widget-dot {
  width: 6px;
  height: 6px;
  border-radius: 6px;
  border: none;
  padding: 0;
  background: var(--surface-2);
  cursor: pointer;
  transition: width 0.3s ease, background 0.3s ease;
}
.widget-dot.active { width: 20px; background: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .widget-dot { transition: none; }
}

/* Macro chips */
.macro-chips-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 14px 16px;
  margin-top: 12px;
}
.macro-chips { display: flex; justify-content: center; gap: 26px; }
.macro-chip { display: flex; flex-direction: column; gap: 6px; align-items: center; width: 56px; }
.macro-chip-label { display: flex; align-items: center; gap: 4px; font: 700 12px "Manrope", sans-serif; }
.macro-chip b { font-variant-numeric: tabular-nums; }
.dot { display: inline-block; width: 0.6em; height: 0.6em; border-radius: 50%; }
.dot.protein { background: #4c8bf5; }
.dot.fat { background: var(--accent); }
.dot.carbs { background: var(--green); }
.macro-bar { width: 100%; height: 4px; border-radius: 4px; background: color-mix(in oklch, var(--text) 10%, transparent); overflow: hidden; }
.macro-bar-fill { height: 100%; border-radius: 4px; width: 0%; transition: width 1s ease; }
.macro-bar-fill.protein { background: #4c8bf5; }
.macro-bar-fill.fat { background: var(--accent); }
.macro-bar-fill.carbs { background: var(--green); }
@media (prefers-reduced-motion: reduce) {
  .macro-bar-fill { transition: none; }
}

.section-label {
  display: block;
  font: 700 11px "Manrope", sans-serif;
  color: var(--hint-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 16px 0 8px;
}
.section-label.danger-label { color: color-mix(in oklch, var(--danger) 85%, transparent); }

/* Entry list (Today / Записи / История) */
.entry-list { list-style: none; margin: 0; padding: 0; }
.entry {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface);
  border-radius: 14px;
  padding: 10px 12px;
  margin-bottom: 8px;
  gap: 0.6rem;
  animation: fadeUp 0.4s ease both;
}
/* Staggered entrance, 60ms per row, capped at 10 so a long list doesn't
   keep animating rows in for a visually distracting length of time. */
.entry-list .entry:nth-child(1) { animation-delay: 0ms; }
.entry-list .entry:nth-child(2) { animation-delay: 60ms; }
.entry-list .entry:nth-child(3) { animation-delay: 120ms; }
.entry-list .entry:nth-child(4) { animation-delay: 180ms; }
.entry-list .entry:nth-child(5) { animation-delay: 240ms; }
.entry-list .entry:nth-child(n+6) { animation-delay: 300ms; }
@media (prefers-reduced-motion: reduce) {
  .entry { animation: none; }
}
.entry-thumb {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 8px;
  object-fit: cover;
  background: var(--surface-2);
}
.entry-main { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; flex: 1; }
.entry-food {
  font: 600 13px "Manrope", sans-serif;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entry-meta, .entry-macros {
  color: var(--hint);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}
.entry-ingredients {
  color: var(--hint-faint);
  font-size: 0.74rem;
  font-style: italic;
  line-height: 1.4;
}
/* Neutral card background (not accent-tinted) behind a flat, single-color
   line icon (see ICON_SVG in app.js — these are no longer the ✏️/🗑 emoji,
   which come with their own fixed multi-color palette). */
.entry-actions { display: flex; gap: 0.5rem; flex: none; }
.entry-actions button {
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: var(--surface-2);
  color: var(--hint);
  border-radius: 12px;
  width: 2.25rem;
  height: 2.25rem;
}
.entry-actions button:disabled { opacity: 0.4; }
.entry-actions button:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* "Приёмы пищи сегодня" (Питание tab, saved plan state) — a 2-column grid
   of photo tiles, per design_handoff_fitbot_redesign's latest revision
   (replaces the old dot+row mealLine list, which the week view below still
   uses as-is). */
.meal-tile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.meal-tile {
  background: var(--surface);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 8px 22px -16px rgba(20, 15, 10, .35);
  cursor: pointer;
  transition: transform 0.15s ease;
  animation: fadeUp 0.4s ease both;
}
.meal-tile-grid .meal-tile:nth-child(1) { animation-delay: 0ms; }
.meal-tile-grid .meal-tile:nth-child(2) { animation-delay: 70ms; }
.meal-tile-grid .meal-tile:nth-child(3) { animation-delay: 140ms; }
.meal-tile-grid .meal-tile:nth-child(4) { animation-delay: 210ms; }
.meal-tile-grid .meal-tile:nth-child(n+5) { animation-delay: 280ms; }
@media (prefers-reduced-motion: reduce) {
  .meal-tile { animation: none; }
}
@media (hover: hover) {
  .meal-tile:hover { transform: translateY(-2px); }
}
.meal-tile:active { transform: translateY(-2px); }
.meal-tile-photo-wrap { position: relative; height: 104px; background: var(--surface-2); }
.meal-tile-photo { width: 100%; height: 100%; object-fit: cover; display: block; }
.meal-tile-kcal-pill {
  position: absolute;
  top: 8px;
  right: 8px;
  background: var(--accent);
  color: var(--accent-text);
  font: 800 10px "Manrope", sans-serif;
  padding: 3px 7px;
  border-radius: 999px;
}
.meal-tile-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 5px; }
.meal-tile-name {
  font: 800 13px "Manrope", sans-serif;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}
.meal-tile-desc {
  font: 600 11px "Manrope", sans-serif;
  color: var(--hint);
  min-height: 2.4em;
  line-height: 1.2;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.meal-tile-macros { display: flex; gap: 5px; }
.meal-tile-macro-chip {
  flex: 1;
  text-align: center;
  border-radius: 8px;
  padding: 3px 0;
  font: 700 10px "Manrope", sans-serif;
  font-variant-numeric: tabular-nums;
}
.meal-tile-macro-chip.protein { background: color-mix(in oklch, #4c8bf5 12%, transparent); color: #4c8bf5; }
.meal-tile-macro-chip.fat { background: color-mix(in oklch, var(--accent) 12%, transparent); color: var(--accent); }
.meal-tile-macro-chip.carbs { background: color-mix(in oklch, var(--green) 12%, transparent); color: var(--green); }
.meal-tile-actions { display: flex; gap: 6px; margin-top: 2px; }
.meal-tile-actions button {
  flex: 1;
  border: none;
  background: var(--surface-2);
  color: var(--hint);
  border-radius: 8px;
  padding: 6px 0;
  font-size: 13px;
}
.meal-tile-actions button:disabled { opacity: 0.4; }

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

/* Footer stat cards (Today) — "Сожжено" (first) tinted green, "Вес"
   (second) tinted orange, matching the design handoff exactly. */
.footer-cards { display: flex; gap: 10px; margin-top: 16px; }
.footer-card {
  flex: 1;
  background: var(--surface);
  border-radius: 14px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.footer-card:first-child { background: color-mix(in oklch, var(--green) 12%, transparent); }
.footer-card:last-child { background: color-mix(in oklch, var(--accent) 10%, transparent); }
.footer-card-label { font: 700 11px "Manrope", sans-serif; color: var(--hint); }
.footer-card-value { font: 800 16px "Manrope", sans-serif; font-variant-numeric: tabular-nums; }

/* Forms */
form label,
#view-profile label,
#plan-profile-gate label,
#nutrition-profile-gate label {
  display: block;
  font: 600 12px "Manrope", sans-serif;
  color: var(--hint);
  margin-bottom: 1rem;
}

/* "Возраст"/"Рост" sit side by side in the handoff, not stacked. */
.settings-row { display: flex; gap: 8px; }
.settings-row label { flex: 1; }

/* "Тема"/"Язык" segmented pill-groups — replace what used to be a
   <select>; setSegmentedValue()/initSegmentedGroup() in app.js track the
   chosen value via the group's own data-value attribute instead of a
   select's .value, everything downstream of that reads the same as before. */
.segmented-label {
  font: 600 12px "Manrope", sans-serif;
  color: var(--hint);
  margin-bottom: 6px;
}
.segmented-group {
  display: flex;
  gap: 6px;
  background: var(--surface-2);
  border-radius: 10px;
  padding: 4px;
  margin-bottom: 14px;
}
.segmented-btn {
  flex: 1;
  padding: 8px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--hint);
  font: 700 11px "Manrope", sans-serif;
  cursor: pointer;
}
.segmented-btn.active { background: var(--surface); color: var(--text); }
input, select {
  display: block;
  width: 100%;
  margin-top: 0.35rem;
  padding: 0.65rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--field-bg);
  color: var(--text);
  font: 500 14px "Manrope", sans-serif;
}
.password-field { position: relative; }
.password-field input { padding-right: 2.4rem; }
.password-toggle {
  position: absolute;
  right: 0.2rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  font-size: 1rem;
  line-height: 1;
  padding: 0.4rem;
  opacity: 0.6;
  cursor: pointer;
}
.password-toggle:hover { opacity: 1; }
textarea {
  display: block;
  width: 100%;
  margin-top: 0.35rem;
  padding: 0.65rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--field-bg);
  color: var(--text);
  font: 500 14px "Manrope", sans-serif;
  resize: vertical;
}

button.primary {
  width: 100%;
  padding: 0.8rem;
  border: none;
  border-radius: 12px;
  background: var(--accent);
  color: var(--accent-text);
  font: 800 14px "Manrope", sans-serif;
  transition: transform 0.1s ease, background-color 0.15s ease;
}
button.primary:active { transform: scale(0.98); }
@media (prefers-reduced-motion: reduce) {
  button.primary:active { transform: none; }
}
button.primary.small { padding: 0.6rem; font-size: 0.9rem; }
#logout-btn { margin: 1.5rem 0 2rem; color: var(--danger); border-color: var(--danger); }
button.secondary.danger { color: var(--danger); border-color: var(--danger); }
button.secondary.danger:disabled { opacity: 0.45; }
#delete-account-btn { margin-top: 0.3rem; margin-bottom: 1rem; }
#delete-account-scope { margin-bottom: 1.2rem; }
#view-profile label.radio-option {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 0.6rem;
  font-size: 0.85rem;
  color: var(--text);
}
.radio-option input[type="radio"] {
  display: inline-block;
  width: auto;
  margin: 0;
  flex: none;
}
#link-telegram-section { margin-bottom: 1.5rem; }
#link-telegram-submit { margin-top: 0.3rem; }

button.secondary {
  width: 100%;
  padding: 0.7rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: none;
  color: var(--text);
  font: 700 0.85rem "Manrope", sans-serif;
  transition: background-color 0.15s ease;
}
@media (hover: hover) {
  button.secondary:hover { background: var(--surface-2); }
}

.status { margin-top: 0.8rem; font-size: 0.88rem; color: var(--hint); display: flex; align-items: center; gap: 8px; }
.spinner {
  width: 14px;
  height: 14px;
  flex: none;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
}

.divider {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 1.4rem 0;
  color: var(--hint);
  font-size: 0.82rem;
}
.divider::before,
.divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

#add-form {
  background: var(--surface);
  border-radius: 18px;
  padding: 16px;
}
.photo-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--surface);
  color: var(--text);
  font: 700 0.95rem "Manrope", sans-serif;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
@media (hover: hover) {
  .photo-btn:hover { background: var(--surface-2); }
}
.photo-btn-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-text);
}
.photo-btn-label { flex: 1; }

.barcode-confirm {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 14px;
  background: var(--surface);
}
.barcode-confirm p { margin: 0 0 0.8rem; font-size: 0.9rem; }
.barcode-confirm label { margin-bottom: 0.8rem; }

/* Мой план: step-by-step wizard */
.wizard-progress-bar {
  height: 4px;
  border-radius: 4px;
  background: color-mix(in oklch, var(--text) 10%, transparent);
  overflow: hidden;
  margin-bottom: 14px;
}
.wizard-progress-fill {
  height: 100%;
  border-radius: 4px;
  background: var(--accent);
  width: 0%;
  transition: width 0.3s ease;
}
#wizard-progress-fill { background: var(--green); }
@media (prefers-reduced-motion: reduce) {
  .wizard-progress-fill { transition: none; }
}
.wizard-progress {
  font: 700 11px "Manrope", sans-serif;
  color: var(--hint-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 4px;
}
.wizard-step, .n-wizard-step { display: none; }
.wizard-step.active, .n-wizard-step.active { display: block; animation: popIn 0.3s ease both; }
@media (prefers-reduced-motion: reduce) {
  .wizard-step.active, .n-wizard-step.active { animation: none; }
}

/* .n-* variants are the nutrition-plan wizard's own class names — visually
   identical to the workout wizard's, but kept separate so its JS (a
   different document.querySelectorAll scope, see app.js) never collides
   with the workout wizard's global .choice-chip click handler. */
.choice-grid, .n-choice-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.choice-chip, .n-choice-chip {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 16px;
  background: var(--surface);
  color: var(--text);
  font: 700 13px "Manrope", sans-serif;
}
/* Workout wizard chips are green (matches its progress bar/CTA); nutrition
   wizard chips stay orange — the two wizards share no other visual cue for
   "which one am I in", so this accent difference carries that signal. */
.choice-chip.selected { background: var(--green); border-color: var(--green); color: var(--accent-text); }
.n-choice-chip.selected { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }

.wizard-nav { display: flex; gap: 10px; margin-top: 14px; }
.wizard-nav button { flex: 1; }

/* Compact stat ring, used in История */
.totals { display: flex; align-items: center; gap: 1.2rem; padding: 0.4rem 0 0.8rem; }
.ring {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  border: 6px solid var(--accent);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: none;
}
.ring span { font-size: 1.2rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.ring small { color: var(--hint); font-size: 0.65rem; }

.macros { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.85rem; }
.macro b { font-variant-numeric: tabular-nums; }

.history-nav { display: flex; align-items: center; justify-content: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.history-date-label {
  flex: 1;
  text-align: center;
  border: none;
  background: none;
  padding: 0.5rem;
  font: 700 14px "Manrope", sans-serif;
  color: var(--text);
  cursor: pointer;
}
.nav-btn {
  flex: none;
  width: 2.4rem;
  height: 2.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 12px;
  background: var(--surface);
  color: var(--text);
  transition: background-color 0.15s ease;
}
@media (hover: hover) {
  .nav-btn:hover { background: var(--surface-2); }
}
.nav-btn:disabled { opacity: 0.35; }

.inline-form {
  padding: 0.9rem;
  margin-bottom: 0.9rem;
  border-radius: 10px;
  background: var(--surface);
}
.inline-form label { margin-bottom: 0.7rem; }
.inline-form label:last-of-type { margin-bottom: 0.9rem; }

.row3 { display: flex; gap: 0.5rem; }
.row3 label { flex: 1; margin-bottom: 0.9rem; }

/* Cardio/strength quick-log's exercise picker (search-as-you-type over
   GET /api/exercises, see loadExerciseCatalog/handleGetExerciseCatalog
   backend-side) — the dropdown renders in normal flow (not absolutely
   positioned) so it can't get clipped by .sheet-card's own overflow-y
   scroll container. */
.exercise-picker-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 4px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--surface-2);
  border-radius: 12px;
  border: 1px solid var(--border);
}
.exercise-picker-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 8px;
  cursor: pointer;
  font: 600 13px "Manrope", sans-serif;
  color: var(--text);
}
@media (hover: hover) {
  .exercise-picker-item:hover { background: var(--surface); }
}
.exercise-picker-thumb {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  object-fit: cover;
  background: var(--surface);
  flex: none;
}
.exercise-picker-thumb-fallback {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--surface);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}
.exercise-picker-empty {
  padding: 10px 8px;
  color: var(--hint);
  font-size: 0.82rem;
  text-align: center;
}

.week-summary {
  padding: 0.9rem;
  border-radius: 14px;
  background: var(--surface);
  font-size: 0.9rem;
  line-height: 1.6;
  margin-bottom: 4px;
}
.week-summary .row { display: flex; justify-content: space-between; }
.week-summary .row b { font-variant-numeric: tabular-nums; }
.week-summary .empty { color: var(--hint); margin: 0; }

/* "Итоги недели" (Тренировки) — 3 stat cards, workout-count/minutes tinted,
   calories neutral. loadWeekSummary() builds this same shape at runtime. */
.stat-cards { display: flex; gap: 10px; }
.stat-card { flex: 1; background: var(--surface); border-radius: 14px; padding: 12px; }
.stat-card.tint-accent { background: color-mix(in oklch, var(--accent) 10%, transparent); }
.stat-card.tint-green { background: color-mix(in oklch, var(--green) 12%, transparent); }
.stat-card-value { font: 800 20px "Manrope", sans-serif; font-variant-numeric: tabular-nums; }
.stat-card-label { font: 700 11px "Manrope", sans-serif; color: var(--hint); margin-top: 2px; }
.week-summary-trend {
  padding: 0.9rem;
  border-radius: 14px;
  background: var(--surface);
  font-size: 0.9rem;
  margin-top: 10px;
}
.week-summary-trend .row { display: flex; justify-content: space-between; }
.week-summary-trend .row b { font-variant-numeric: tabular-nums; }

.plan-day {
  padding: 0.9rem;
  margin-bottom: 10px;
  border-radius: 12px;
  background: var(--surface);
}
.plan-day-header { font: 700 14px "Manrope", sans-serif; margin-bottom: 10px; }

.plan-exercise-list { list-style: none; margin: 0 0 10px; padding: 0; }
.plan-exercise {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
}
.plan-exercise input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex: none;
  margin: 0;
  accent-color: var(--green);
}
.plan-exercise input[type="checkbox"]:disabled { opacity: 0.35; }
.plan-exercise label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: inherit;
  color: inherit;
}
.plan-exercise-name { font: 600 13px "Manrope", sans-serif; }
.plan-exercise-detail { font: 600 12px "Manrope", sans-serif; color: var(--hint); flex: none; }
.plan-exercise.done .plan-exercise-name { color: var(--hint); text-decoration: line-through; }

.day-carousel-tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin-top: 14px;
  padding-bottom: 8px;
  margin-bottom: 4px;
  scrollbar-width: none;
}
.day-carousel-tabs::-webkit-scrollbar { display: none; }
.day-carousel-tab {
  flex: none;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  font: 700 12px "Manrope", sans-serif;
  color: var(--hint);
}
.day-carousel-tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}
/* Workout day tabs use the green accent instead — same reasoning as the
   wizard chips above. */
#plan-day-tabs .day-carousel-tab.active {
  background: var(--green);
  border-color: var(--green);
}
.day-carousel-track {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
  scrollbar-width: none;
}
.day-carousel-track::-webkit-scrollbar { display: none; }
.day-carousel-track .plan-day {
  flex: 0 0 86%;
  scroll-snap-align: start;
  margin-bottom: 0;
}

.plan-day-footer {
  display: flex;
  align-items: center;
  gap: 10px;
}
.plan-day-timer {
  font: 700 14px "Manrope", sans-serif;
  font-variant-numeric: tabular-nums;
  color: var(--hint);
  flex: none;
}
.plan-start-btn { flex: 1; width: auto; display: flex; align-items: center; justify-content: center; gap: 6px; }
/* :hover repeated here on purpose — button.secondary:hover (see the forms
   section above) otherwise outranks the plain .running rule by one class
   of specificity and silently reverts a running timer's button back to
   the neutral secondary color the instant the pointer sits over it. */
.plan-start-btn.running,
.plan-start-btn.running:hover {
  background: var(--green);
  border-color: var(--green);
  color: var(--accent-text);
}
.plan-start-btn:disabled { opacity: 0.5; }

.plan-disclaimer {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--hint);
  margin: 4px 0 1rem;
}

/* Standalone (non-Telegram) Google login screen */
#login-screen,
#reset-password-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--bg);
  overflow: hidden;
  z-index: 20;
}

/* First-login onboarding: a horizontal slide track (translateX per step,
   same "carousel" motion language as the Today widget carousel/day
   carousel elsewhere) ending in the same profile-gate fields the plan
   wizards already collect — see afterAuthenticated()/startOnboarding() in
   app.js for when this shows instead of #app. */
#onboarding-screen {
  position: fixed;
  inset: 0;
  z-index: 22;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}
.onboarding-header {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 22px 0;
}
.onboarding-wordmark {
  font: 800 15px "Manrope", sans-serif;
  color: var(--text);
  letter-spacing: -0.01em;
}
.onboarding-skip {
  border: none;
  background: none;
  padding: 4px;
  font: 700 12px "Manrope", sans-serif;
  color: var(--hint);
  cursor: pointer;
}
.onboarding-skip:hover { color: var(--accent); }
.onboarding-track {
  flex: 1;
  display: flex;
  transition: transform 0.45s cubic-bezier(0.25, 1, 0.35, 1);
}
@media (prefers-reduced-motion: reduce) {
  .onboarding-track { transition: none; }
}
.onboarding-slide {
  position: relative;
  isolation: isolate;
  flex: 0 0 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px 28px;
  overflow-y: auto;
}
/* Ambient "slow-mo footage" background per slide (design_handoff_fitbot_redesign's
   "Blurred motion background"). No licensed video/photo assets ship with this repo,
   so each slide gets a per-topic tinted gradient instead of real footage — same
   blurred/drifting/legibility-wash treatment the spec describes, just without a
   <video> source. Swap .onboarding-slide-bg-inner's background for a <video> element
   if real clips are ever added, the wash/kenBurns motion stays the same either way. */
.onboarding-slide-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.onboarding-slide-bg-inner {
  position: absolute;
  inset: -20%;
  filter: blur(60px) saturate(1.1);
  animation: kenBurns 28s ease-in-out infinite alternate;
}
/* Three-stop radial gradients (solid center → dim mid → fully transparent)
   instead of a hard center/transparent edge — a 2-stop gradient plus blur()
   still shows a visible ring where the color starts, reading as a blotchy
   stain rather than a soft ambient glow. */
.onboarding-slide-bg-food {
  opacity: 0.4;
  background:
    radial-gradient(circle at 28% 26%, var(--accent) 0%, color-mix(in oklch, var(--accent) 30%, transparent) 45%, transparent 75%),
    radial-gradient(circle at 78% 72%, var(--green) 0%, color-mix(in oklch, var(--green) 25%, transparent) 40%, transparent 70%);
}
.onboarding-slide-bg-gym {
  opacity: 0.42;
  background:
    radial-gradient(circle at 74% 24%, var(--green) 0%, color-mix(in oklch, var(--green) 30%, transparent) 45%, transparent 75%),
    radial-gradient(circle at 24% 76%, var(--accent) 0%, color-mix(in oklch, var(--accent) 22%, transparent) 40%, transparent 70%);
}
.onboarding-slide-bg-progress {
  opacity: 0.4;
  background:
    radial-gradient(circle at 28% 74%, var(--accent) 0%, color-mix(in oklch, var(--accent) 28%, transparent) 45%, transparent 75%),
    radial-gradient(circle at 76% 26%, var(--green) 0%, color-mix(in oklch, var(--green) 22%, transparent) 40%, transparent 70%);
}
.onboarding-slide-bg-profile {
  opacity: 0.3;
  background: radial-gradient(circle at 50% 36%, var(--accent) 0%, color-mix(in oklch, var(--accent) 25%, transparent) 45%, transparent 75%);
}
.onboarding-slide-bg-wash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, color-mix(in oklch, var(--bg) 62%, transparent), color-mix(in oklch, var(--bg) 88%, transparent));
}
@keyframes kenBurns {
  from { transform: scale(1.06) translate3d(-1.5%, 1%, 0); }
  to { transform: scale(1.22) translate3d(2%, -2%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .onboarding-slide-bg-inner { animation: none; }
}
.onboarding-icon-card {
  width: 112px;
  height: 112px;
  border-radius: 30px;
  background: var(--surface);
  box-shadow: 0 18px 38px -22px rgba(20, 15, 10, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  animation: onboardingIconPop 0.5s cubic-bezier(0.3, 1.6, 0.4, 1) both;
}
@keyframes onboardingIconPop {
  from { transform: scale(0.5); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .onboarding-icon-card { animation: none; }
}
.onboarding-slide h2 {
  font: 800 22px "Manrope", sans-serif;
  margin: 0 0 10px;
  letter-spacing: -0.01em;
}
.onboarding-slide p {
  color: var(--hint);
  font-size: 14px;
  line-height: 1.5;
  max-width: 320px;
  margin: 0;
}
/* Slide 4 (profile form) breaks from slides 1-3's centered-hero layout: it's
   a top-aligned form, matching the design spec's "chip + title" header
   instead of a big centered icon card. */
.onboarding-slide-form {
  align-items: stretch;
  justify-content: flex-start;
  text-align: left;
  padding-top: 20px;
}
.onboarding-form-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 6px 0 4px;
}
.onboarding-check-chip {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10px 22px -10px color-mix(in oklch, var(--accent) 60%, transparent);
}
.onboarding-form-header h2 { margin: 0; font-size: 20px; }
.onboarding-form-header p { margin: 2px 0 0; max-width: none; }
.onboarding-form {
  width: 100%;
  max-width: 340px;
  margin-top: 16px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface);
  border-radius: 20px;
  padding: 16px;
  box-shadow: 0 12px 30px -22px rgba(20, 15, 10, 0.35);
  box-sizing: border-box;
}
.onboarding-form-row {
  display: flex;
  gap: 10px;
}
.onboarding-form-row label { flex: 1; }
.onboarding-form-group-label {
  display: block;
  font: 600 11.5px "Manrope", sans-serif;
  color: var(--hint);
  margin-top: 4px;
}
.onboarding-activity-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.onboarding-activity-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--field-bg);
  cursor: pointer;
  text-align: left;
  font-family: "Manrope", sans-serif;
  transition: all 0.2s ease;
}
.onboarding-activity-row span { font: 700 12.5px "Manrope", sans-serif; color: var(--text); }
.onboarding-activity-row small { font: 600 11px "Manrope", sans-serif; color: var(--hint); }
.onboarding-activity-row.selected {
  border-color: var(--accent);
  background: color-mix(in oklch, var(--accent) 10%, transparent);
}
.onboarding-activity-row.selected span { color: var(--accent); }
.onboarding-footer {
  padding: 16px 24px calc(20px + env(safe-area-inset-bottom));
}
.onboarding-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-bottom: 16px;
}
.onboarding-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--border);
  transition: width 0.3s ease, background-color 0.3s ease;
}
.onboarding-dot.active { width: 20px; background: var(--accent); }
.onboarding-nav { display: flex; gap: 10px; }
.onboarding-nav button { flex: 1; }
.login-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(10px);
  pointer-events: none;
}
.login-blob-1 {
  width: 220px;
  height: 220px;
  top: -60px;
  right: -60px;
  background: color-mix(in oklch, var(--accent) 20%, transparent);
  animation: floatBlob1 9s ease-in-out infinite;
}
.login-blob-2 {
  width: 180px;
  height: 180px;
  bottom: -40px;
  left: -50px;
  background: color-mix(in oklch, var(--green) 16%, transparent);
  animation: floatBlob2 11s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .login-blob { animation: none; }
}
.login-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 320px;
  padding: 28px 24px;
  border-radius: 24px;
  background: var(--surface);
  box-shadow: 0 20px 45px -20px rgba(20, 15, 10, 0.25);
  text-align: center;
  animation: fadeUp 0.5s ease both;
}
@media (prefers-reduced-motion: reduce) {
  .login-card { animation: none; }
}
.login-logo {
  width: 56px;
  height: 56px;
  margin: 0 auto 14px;
  border-radius: 16px;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px -6px color-mix(in oklch, var(--accent) 60%, transparent);
}
.login-logo-ring {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 3px solid var(--accent-text);
  animation: glowPulse 1.8s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .login-logo-ring { animation: none; }
}
.login-title { display: block; font: 800 22px "Manrope", sans-serif; letter-spacing: -0.01em; margin-bottom: 0.6rem; }
.login-message { font: 600 13px "Manrope", sans-serif; color: var(--hint); margin: 0 0 1.2rem; line-height: 1.5; }
#google-signin-btn { display: flex; justify-content: center; margin-bottom: 0.6rem; }
#link-code-row { margin-top: 1rem; text-align: left; }
#link-code-row label { display: block; font-size: 0.85rem; color: var(--hint); }
#link-code-submit { width: 100%; margin-top: 0.7rem; }

#email-auth-fields,
#reset-password-screen .login-card { text-align: left; }
#email-auth-fields label,
#reset-password-screen label { display: block; font: 600 12px "Manrope", sans-serif; color: var(--hint); margin-bottom: 0.6rem; }
#email-submit-btn { width: 100%; margin-top: 0.3rem; }
#reset-password-submit { width: 100%; }
.login-links {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0.8rem 0 0;
  font-size: 0.82rem;
}
.login-links a { color: var(--accent); text-decoration: none; }

/* "Профиль" tab: linked Google account card */
.profile-google {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0.7rem 0.9rem;
  margin-bottom: 12px;
  border-radius: 12px;
  background: var(--surface);
}
/* The conic-gradient shows through whenever there's no src (no Google
   picture) — app.js only ever sets/clears .src, it doesn't toggle
   visibility, so an empty/failed image leaves this background visible as
   a placeholder instead of empty space. */
.profile-google-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  flex: none;
  background: conic-gradient(from 0deg, var(--accent), var(--green), oklch(60% 0.19 260), var(--accent));
  object-fit: cover;
}
.profile-google-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.profile-google-name {
  font: 600 13px "Manrope", sans-serif;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-google-email {
  font: 500 12px "Manrope", sans-serif;
  color: var(--hint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-google-badge {
  flex: none;
  font: 700 11px "Manrope", sans-serif;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 3px 9px;
}

/* Recipe modal (tap a planned meal's photo) */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 50;
}
.modal-card {
  width: 100%;
  max-width: 420px;
  max-height: 80vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: 18px;
  padding: 20px;
}
.modal-card h3 { font: 800 15px "Manrope", sans-serif; margin: 0; }
.modal-card .status { margin-top: 10px; }
.recipe-steps { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.recipe-steps li { display: flex; gap: 10px; }
.recipe-steps li::before {
  counter-increment: recipe-step;
  content: counter(recipe-step);
  flex: none;
  width: 20px;
  font: 800 13px "Manrope", sans-serif;
  color: var(--accent);
}
.recipe-steps { counter-reset: recipe-step; }
.recipe-steps span { flex: 1; font: 600 13px "Manrope", sans-serif; color: var(--text); line-height: 1.4; }
.entry-thumb[data-has-recipe] { cursor: pointer; }

/* Exercise technique modal (tap a plan exercise's photo) */
.exercise-modal-image { width: 100%; border-radius: 12px; margin-bottom: 12px; background: var(--surface-2); display: block; }
.exercise-modal-muscle { font: 600 12px "Manrope", sans-serif; color: var(--hint); margin: 6px 0 0; }
.plan-exercise-thumb { width: 40px; height: 40px; border-radius: 10px; object-fit: cover; flex: none; cursor: pointer; background: var(--surface-2); }
