/* Addy Bite — CSS using Vasilis Baimas palette + base accent color:
   Gray: #F4F3F5 | Mauve/Orchid: #A0688A | Deep Plum: #3D2050 | Coral: #E0706A | Yellow: #F0DC82
   Base accent: #3f37c9 (indigo) — used for primary actions, active nav, reminders */

:root {
  --gray-bg: #F4F3F5;
  --mauve: #A0688A;
  --mauve-light: #C398B2;
  --plum: #3D2050;
  --plum-mid: #5A3070;
  --plum-light: #D4C0DE;
  /* Brand "dark plum" SURFACE colour (filled badges/bars/sidebar/buttons).
     Kept dark in BOTH light and dark themes, unlike --plum which is also the
     heading TEXT colour and flips to light in dark mode. */
  --plum-surface: #3D2050;
  --coral: #E0706A;
  --coral-light: #F2B4B1;
  --yellow: #F0DC82;
  --yellow-light: #FAF1C0;
  /* Base fallback = the default 'lightblue' (Sky Blue) theme, so there's no
     flash of the wrong colour before data-accent is applied. Per-theme blocks
     below override these. */
  --accent: #1a72d0;
  --accent-light: #1e90ff;
  --accent-pale: #e6f1fd;
  /* THE single brand gradient — used for every primary action, tab, icon
     chip, active menu item, FAB and the premium card. Change it here and it
     propagates everywhere. Gold stays reserved for the "Premium" concept. */
  --brand-grad: linear-gradient(159deg, #1e90ff 0%, #99badd 100%);
  --brand-grad-hover: linear-gradient(159deg, #1580f0 0%, #86a9cf 100%);
  /* Text/icon colour on top of the brand gradient (per-theme override below). */
  --on-brand: #0c2c4f;
  /* ONE shadow used across the whole app for a consistent elevation.
     --shadow = resting surfaces (cards, buttons, chips); --shadow-lg =
     floating things (FAB, modals). Redefined for dark mode in premium.css. */
  --shadow: 0 4px 14px rgba(61, 32, 80, 0.10);
  --shadow-lg: 0 12px 30px -8px rgba(61, 32, 80, 0.22);
  --white: #FFFFFF;
  /* Alias used by a few components via var(--card-bg, #fff); define it so it
     tracks the theme (white in light, dark surface in dark) instead of always
     falling back to hardcoded white. */
  --card-bg: #FFFFFF;
  /* The PAGE backdrop, kept distinct from the card surface (--white) so that
     in dark mode cards can sit a shade lighter than the page and stay visible
     (in light mode both are white). */
  --page-bg: #FFFFFF;
  --text: #2A1A35;
  --text-muted: #8A7898;
  --border: rgba(61, 32, 80, 0.12);
  --sidebar-w: 240px;
  --gold: #F5C518;
  --gold-light: #FBE08A;
  --gold-deep: #D9A800;
}

/* ── User-selectable accent themes ───────────────────────────────────────
   The <html> element gets data-accent="<key>" (set in partials/head.php from
   the user's saved choice). Each block re-points the single brand gradient +
   solid accent tokens, so the whole site recolours. Keep these in sync with
   accentThemes() in theme-lib.php. --accent-pale is only overridden for light
   mode here; the dark-mode block in premium.css loads later and wins in dark.
   'lightblue' is the default. */
/* --on-brand = text/icon colour that sits ON the gradient. Light gradients
   (Lavender/Gold/Sky) use dark text; dark gradients (Teal/Ocean/Red) use white.
   --accent is a readable solid (for links, focus rings, active text on white). */
:root[data-accent="violet"] { /* Lavender */
  --brand-grad: linear-gradient(315deg, #9fa4c4 0%, #9e768f 74%);
  --brand-grad-hover: linear-gradient(315deg, #8f94b8 0%, #8b6580 74%);
  --accent: #7d5f73;
  --accent-light: #9fa4c4;
  --accent-pale: #efeaef;
  --on-brand: #2c2434;
}
:root[data-accent="yellow"] { /* Gold */
  --brand-grad: linear-gradient(315deg, #f4c430 0%, #fdd017 74%);
  --brand-grad-hover: linear-gradient(315deg, #e0b41f 0%, #e8bd0a 74%);
  --accent: #9a7000;
  --accent-light: #f4c430;
  --accent-pale: #fdf4d2;
  --on-brand: #3a2c00;
}
:root[data-accent="lightblue"] { /* Sky Blue */
  --brand-grad: linear-gradient(159deg, #1e90ff 0%, #99badd 100%);
  --brand-grad-hover: linear-gradient(159deg, #1580f0 0%, #86a9cf 100%);
  --accent: #1a72d0;
  --accent-light: #1e90ff;
  --accent-pale: #e6f1fd;
  --on-brand: #0c2c4f;
}
:root[data-accent="emerald"] { /* Teal */
  --brand-grad: linear-gradient(159deg, #008080 0%, #009990 100%);
  --brand-grad-hover: linear-gradient(159deg, #006e6e 0%, #00857d 100%);
  --accent: #008080;
  --accent-light: #14b8a6;
  --accent-pale: #e0f3f1;
  --on-brand: #ffffff;
}
:root[data-accent="sunset"] { /* Ocean */
  --brand-grad: linear-gradient(159deg, #007fff 0%, #2a52be 100%);
  --brand-grad-hover: linear-gradient(159deg, #0070e0 0%, #24489f 100%);
  --accent: #0a63d6;
  --accent-light: #3b82f6;
  --accent-pale: #e5eefe;
  --on-brand: #ffffff;
}
:root[data-accent="rose"] { /* Red */
  --brand-grad: linear-gradient(315deg, #e34234 0%, #ff3800 74%);
  --brand-grad-hover: linear-gradient(315deg, #cc3a2d 0%, #e03200 74%);
  --accent: #d1301f;
  --accent-light: #ff5a40;
  --accent-pale: #fde8e5;
  --on-brand: #ffffff;
}

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

/* ── App-like page transitions ──────────────────────────────────────────
   Opt into cross-document View Transitions so moving between pages fades
   smoothly instead of the browser's hard white flash — makes this multi-page
   PHP app feel like a single app when navigating. No-ops in browsers that
   don't support it (graceful), and is disabled under reduced-motion. */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.22s;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Every custom button in this app relies on its own background/border for
   the pressed (:active) state. Without this reset, iOS/Android render
   native button chrome underneath our styles, and its built-in "pressed"
   look shows through as an unwanted translucent flash on tap. */
button {
  -webkit-appearance: none;
  appearance: none;
}

html {
  overflow-x: clip;
}

body {
  font-family: 'Montserrat', system-ui, sans-serif;
  background: var(--white);
  color: var(--text);
  display: flex;
  /* dvh tracks the *visible* viewport, so the layout doesn't run under the
     mobile browser's collapsing toolbar. The vh line stays first as the
     fallback for browsers without dvh. */
  min-height: 100vh;
  min-height: 100dvh;
  font-size: 0.92rem;
  overflow-x: clip;
}

/* Stop the whole document rubber-banding past its ends — in an installed app
   that bounce exposes the native shell's background and can trigger the
   WebView's own pull-to-refresh over our UI. */
html, body {
  overscroll-behavior-y: contain;
}

/* Visible keyboard focus. :focus-visible only matches keyboard/AT focus, never
   a mouse or touch tap, so this costs the visual design nothing while making
   the app navigable by external keyboard, D-pad and switch control. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Inputs style their own focus ring (border + glow); keep the outline off them
   only when it's a pointer focus, but restore it for keyboard users above. */
.form-control-custom:focus:not(:focus-visible) {
  outline: none;
}


/* ── Sidebar ── */
.sidebar {
  width: var(--sidebar-w);
  background: linear-gradient(180deg, #2A1640 0%, var(--plum-surface) 45%, #321A48 100%);
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  z-index: 200;
  transition: transform 0.3s ease, width 0.25s ease;
  overflow-y: auto;
  overflow-x: hidden;
  border-right: 1px solid rgba(245, 197, 24, 0.25);
  box-shadow: 4px 0 28px rgba(20, 8, 32, 0.18);
  /* Full-height drawer: keep its contents clear of the status bar at the top
     and the home indicator at the bottom when running full-bleed. */
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  /* Contain the bounce so dragging the drawer never scrolls the page behind it. */
  overscroll-behavior: contain;
}

/* Sidebar overlay — dims the page behind the sidebar on mobile, tap to close */
.sidebar-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 10, 30, 0.45);
  z-index: 199;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.sidebar-overlay.visible {
  opacity: 1;
  pointer-events: auto;
}

/* Mobile close (×) button inside the sidebar itself */
.sidebar-close-btn {
  display: none;
  background: rgba(255, 255, 255, 0.08);
  border: none;
  color: #fff;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  font-size: 1.1rem;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  flex-shrink: 0;
}

.sidebar-close-btn:hover {
  background: rgba(255, 255, 255, 0.16);
}

/* Desktop collapse toggle — sits in the topbar, always visible at desktop widths */
.sidebar-collapse-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 8px;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.15s;
}

.sidebar-collapse-btn:hover {
  background: var(--gray-bg);
  color: var(--accent);
}

/* Collapsed desktop sidebar: icon rail only */
.sidebar.collapsed {
  width: 72px;
}

.sidebar.collapsed .brand-text,
.sidebar.collapsed .nav-link span.nav-label,
.sidebar.collapsed .profile-name,
.sidebar.collapsed .profile-sub,
.sidebar.collapsed .sidebar-version,
.sidebar.collapsed .sidebar-profile>div:last-child {
  display: none;
}

.sidebar.collapsed .sidebar-brand {
  justify-content: center;
  padding: 1.5rem 0.5rem 1rem;
}

.sidebar.collapsed .sidebar-nav .nav-link {
  justify-content: center;
  padding: 0.65rem;
}

.sidebar.collapsed .sidebar-profile {
  justify-content: center;
  padding: 1rem 0.5rem;
}

.sidebar.collapsed .sidebar-close-btn {
  display: none !important;
}

.main-content {
  transition: margin-left 0.25s ease;
}

.sidebar.collapsed~.main-content {
  margin-left: 72px;
}

.sidebar-brand {
  padding: 1.5rem 1.25rem 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  border-bottom: 1px solid rgba(245, 197, 24, 0.18);
}

.brand-icon {
  width: 28px;
  height: 28px;
  object-fit: contain;
  border-radius: 7px;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px rgba(245, 197, 24, 0.45), 0 2px 8px rgba(0, 0, 0, 0.25);
}

.brand-text {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  color: var(--gold-light);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

.sidebar-nav {
  padding: 1.25rem 0.75rem;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.sidebar-nav .nav-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0.85rem;
  border-radius: 9px;
  color: rgba(255, 255, 255, 0.62);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  border-left: 2.5px solid transparent;
  position: relative;
  transition: all 0.18s ease;
}

.sidebar-nav .nav-link:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  border-left-color: transparent;
  transform: translateX(2px);
}

.sidebar-nav .nav-link.active {
  background: var(--brand-grad);
  color: #fff;
  border-left-color: transparent;
  font-weight: 600;
}

.sidebar-nav .nav-link.active i {
  color: #fff;
}

.sidebar-nav .nav-link i {
  font-size: 1rem;
  width: 1.1rem;
}

/* ── Collapsible nav groups ─────────────────────────────────────────── */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.nav-group-header {
  width: 100%;
  background: none;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.nav-group-chevron {
  margin-left: auto;
  width: auto !important;
  font-size: 0.75rem !important;
  opacity: 0.7;
  transition: transform 0.2s ease;
}

.nav-group.open .nav-group-chevron {
  transform: rotate(180deg);
}

.nav-group-items {
  display: none;
  flex-direction: column;
  gap: 0.3rem;
}

.nav-group.open .nav-group-items {
  display: flex;
}

.nav-group-items .nav-sublink {
  padding-left: 2.1rem;
  font-size: 0.83rem;
}

/* When the desktop sidebar is collapsed to icons, drop the group headers
   and show every child icon inline so nothing becomes unreachable. */
.sidebar.collapsed .nav-group-header {
  display: none;
}

.sidebar.collapsed .nav-group-items {
  display: flex !important;
}

.sidebar.collapsed .nav-group-items .nav-sublink {
  padding-left: 0.85rem;
}

.sidebar-profile {
  padding: 1rem 1.25rem;
  border-top: 1px solid rgba(245, 197, 24, 0.18);
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.sidebar-version {
  text-align: center;
  font-size: 0.68rem;
  font-family: 'JetBrains Mono', monospace;
  color: rgba(255, 255, 255, 0.35);
  padding: 0 1rem 0.6rem;
  letter-spacing: 0.02em;
}

.profile-avatar {
  width: 36px;
  height: 36px;
  background: var(--brand-grad);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.75rem;
  color: #fff;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px rgba(245, 197, 24, 0.35);
}

.profile-name {
  color: #fff;
  font-weight: 600;
  font-size: 0.8rem;
}

.profile-sub {
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.72rem;
}

/* ── Main Content ── */
.main-content {
  margin-left: var(--sidebar-w);
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  min-width: 0;
  max-width: 100%;
}

/* ── Top Bar ── */
.topbar {
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  /* Top padding clears the status bar / notch / Dynamic Island. On the web the
     browser's own chrome pushes the header down and the inset is 0, so this
     resolves to the normal 0.8rem; installed full-bleed (viewport-fit=cover)
     it grows to sit below the system UI instead of underneath it. */
  padding: max(0.8rem, env(safe-area-inset-top)) 1.5rem 0.8rem;
  padding-left: max(1.5rem, env(safe-area-inset-left));
  padding-right: max(1.5rem, env(safe-area-inset-right));
  position: sticky;
  top: 0;
  z-index: 100;
}

.topbar-heading-group {
  min-width: 0;
  flex-shrink: 1;
}

.topbar-heading-text {
  min-width: 0;
}

.topbar-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  color: var(--plum);
  letter-spacing: 0.01em;
}

.topbar-date {
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* Seamless marquee for the header subtitle (set up by partials/loader.php). The
   track holds two identical halves that each fill the width, so translating it
   -50% loops with no empty gap — it always scrolls, whatever the length. */
.topbar-date.marquee {
  overflow: hidden;
  white-space: nowrap;
}
.topbar-date.marquee .marquee-track {
  display: inline-flex;
  animation: topbarDateMarquee 16s linear infinite;
  will-change: transform;
}
.topbar-date.marquee:hover .marquee-track {
  animation-play-state: paused;
}
.topbar-date.marquee .marquee-item {
  flex: none;
  padding-right: 2rem; /* consistent spacing between repeats — the only gap */
}
@keyframes topbarDateMarquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.content-area {
  padding: 1.5rem;
  padding-bottom: calc(1.5rem + env(safe-area-inset-bottom));
}

/* Row of action buttons: they share the width equally — one button fills
   100%, two split 50/50, three split into thirds, etc. Wrap buttons in
   <div class="btn-row">…</div>. */
.btn-row {
  display: flex;
  gap: 0.6rem;
}

.btn-row>.btn {
  flex: 1 1 0;
  min-width: 0;
}

/* ── Card Section ── */
.card-section {
  background: var(--white);
  border-radius: 14px;
  padding: 1.25rem;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* Card hierarchy — a top-level ("main") card carries the elevation shadow;
   any card nested inside another drops the shadow and keeps just its border,
   so shadows never stack. Matches the flat, bordered inner cards used on the
   Streak page. Applies overall wherever cards nest. */
.card-section .card-section,
.card-section .inner-card {
  box-shadow: none;
  border: 1px solid var(--border);
}
.inner-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: none;
}

.section-label {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 1rem;
  color: var(--plum);
  letter-spacing: 0.01em;
}

/* ── Buttons ── */
.btn-plum {
  -webkit-appearance: none;
  appearance: none;
  background: var(--brand-grad);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0.55rem 1.25rem;
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  box-shadow: var(--shadow);
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
  /* Bootstrap's own .btn:active / .btn.active rule outranks our :active
     rule below in specificity. Without these vars, Bootstrap paints the
     pressed state with an undefined (transparent) background, causing
     a see-through flash on tap. Setting them makes Bootstrap agree with us. */
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: transparent;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: transparent;
  --bs-btn-active-border-color: transparent;
  --bs-btn-focus-shadow-rgb: 63, 55, 201;
}

.btn-plum:hover {
  background: var(--brand-grad-hover);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}

.btn-plum:active {
  background: var(--brand-grad-hover);
  color: #fff;
  transform: translateY(0) scale(0.98);
  box-shadow: var(--shadow);
}

.btn-plum:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* While a button is mid-request (spinner shown) it's still disabled, but
   we don't want the generic 50%-opacity "disabled" fade — that reads as
   transparent/washed-out rather than "working". Keep it fully solid. */
.btn-plum.is-loading:disabled {
  opacity: 1;
  background: var(--brand-grad-hover);
  color: #fff;
  cursor: wait;
}

.topbar .btn-plum {
  padding: 0.6rem 1.4rem;
  font-size: 0.9rem;
  border-radius: 9px;
}

.topbar .btn-plum i {
  font-size: 0.95rem;
}

.topbar .btn-plum.btn-icon-only {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
}

.topbar .btn-plum.btn-icon-only i {
  font-size: 1.1rem;
  margin: 0;
}

.btn-plum-outline {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  color: var(--accent);
  border: 1.5px solid var(--accent);
  border-radius: 8px;
  padding: 0.55rem 1.25rem;
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--accent);
  --bs-btn-active-border-color: var(--accent);
}

.btn-plum-outline:hover {
  color: #fff;
  border-color: var(--accent);
  background: var(--accent);
}

.btn-plum-outline:active {
  background: var(--accent);
  color: #fff;
  transform: scale(0.98);
}

.btn-plum-outline:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Discover Food: mode switch (segmented control) ── */
.discover-mode-switch {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.3rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  -webkit-tap-highlight-color: transparent;
}

.discover-mode-btn {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.01em;
  padding: 0.6rem 1.1rem;
  border-radius: 9px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, transform 0.1s ease;
}

.discover-mode-btn i {
  font-size: 0.95rem;
}

.discover-mode-btn:hover {
  color: var(--plum);
  background: rgba(61, 32, 80, 0.05);
}

.discover-mode-btn:active {
  transform: scale(0.97);
  background: rgba(61, 32, 80, 0.09);
}

.discover-mode-btn.active {
  background: var(--gold);
  color: var(--plum);
  box-shadow: var(--shadow);
}

.discover-mode-btn.active:hover {
  background: var(--gold-deep);
}

.discover-mode-btn.active:active {
  background: var(--gold-deep);
  transform: scale(0.97);
}

.empty-hero {
  max-width: 420px;
  margin: 0 auto;
}

.empty-hero-icon {
  font-size: 2.75rem;
  line-height: 1;
  margin-bottom: 0.85rem;
}

.empty-hero-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 1rem;
  color: var(--plum);
  letter-spacing: 0.01em;
  line-height: 1.35;
  margin: 0 0 0.6rem;
}

.empty-hero-text {
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0;
}

/* ── Hamburger menu toggle (mobile + tablet) ── */
.sidebar-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  flex-shrink: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  --bs-btn-hover-color: inherit;
  --bs-btn-hover-bg: var(--gray-bg);
  --bs-btn-hover-border-color: var(--border);
  --bs-btn-active-color: inherit;
  --bs-btn-active-bg: var(--gray-bg);
  --bs-btn-active-border-color: var(--border);
}

.sidebar-toggle i {
  font-size: 1.5rem;
  color: var(--plum);
  line-height: 1;
}

.sidebar-toggle:hover,
.sidebar-toggle:focus {
  background: var(--gray-bg);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}

.sidebar-toggle:active {
  transform: translateY(0);
}

@media (max-width: 991.98px) {
  .sidebar-toggle {
    width: 48px;
    height: 48px;
  }

  .sidebar-toggle i {
    font-size: 1.65rem;
  }
}

@media (max-width: 575.98px) {
  .sidebar-toggle {
    width: 46px;
    height: 46px;
  }

  .sidebar-toggle i {
    font-size: 1.55rem;
  }
}

.btn-accent {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0.45rem 1rem;
  font-weight: 600;
  font-size: 0.85rem;
  transition: all 0.15s;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--accent-light);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--accent-light);
  --bs-btn-active-border-color: transparent;
}

.btn-accent:hover {
  background: var(--accent-light);
  color: #fff;
}

.btn-outline-accent {
  border: 1.5px solid var(--accent);
  color: var(--accent);
  background: transparent;
  border-radius: 8px;
  padding: 0.35rem 0.85rem;
  font-size: 0.82rem;
  font-weight: 600;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--accent);
  --bs-btn-active-border-color: var(--accent);
}

.btn-outline-accent:hover {
  background: var(--accent);
  color: #fff;
}

.btn-coral {
  background: var(--coral);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0.45rem 1rem;
  font-weight: 600;
  font-size: 0.85rem;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #c9605a;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #c9605a;
  --bs-btn-active-border-color: transparent;
}

.btn-coral:hover {
  background: #c9605a;
  color: #fff;
}

.btn-outline-plum {
  border: 1.5px solid var(--plum);
  color: var(--plum);
  background: transparent;
  border-radius: 8px;
  padding: 0.35rem 0.85rem;
  font-size: 0.82rem;
  font-weight: 600;
  --bs-btn-hover-color: var(--yellow);
  --bs-btn-hover-bg: var(--plum);
  --bs-btn-hover-border-color: var(--plum);
  --bs-btn-active-color: var(--yellow);
  --bs-btn-active-bg: var(--plum);
  --bs-btn-active-border-color: var(--plum);
}

.btn-outline-plum:hover {
  background: var(--plum-surface);
  color: var(--yellow);
}

.btn-ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 8px;
  padding: 0.45rem 0.75rem;
  font-size: 0.85rem;
  --bs-btn-hover-color: var(--text-muted);
  --bs-btn-hover-bg: var(--gray-bg);
  --bs-btn-hover-border-color: var(--border);
  --bs-btn-active-color: var(--text-muted);
  --bs-btn-active-bg: var(--gray-bg);
  --bs-btn-active-border-color: var(--border);
}

.btn-ghost:hover {
  background: var(--gray-bg);
}

.btn-ghost-danger {
  background: transparent;
  border: none;
  color: var(--coral);
  padding: 0.2rem 0.4rem;
  border-radius: 6px;
  --bs-btn-hover-color: var(--coral);
  --bs-btn-hover-bg: var(--coral-light);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--coral);
  --bs-btn-active-bg: var(--coral-light);
  --bs-btn-active-border-color: transparent;
}

.btn-ghost-danger:hover {
  background: var(--coral-light);
}

/* ── Weight Hero Stats ── */
.stat-card {
  position: relative;
  background: var(--card-bg);
  border-radius: 18px;
  padding: 1.05rem 1.15rem 1.15rem;
  border: 1px solid var(--border);
  height: 100%;
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

@media (hover: hover) and (min-width: 992px) {
  .stat-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow);
  }
}

/* Standalone icon — no chip/box, just the glyph filled with the theme
   gradient (same brand colour used across the app). */
.stat-icon {
  position: relative;
  z-index: 1;
  display: inline-flex;
  font-size: 1.55rem;
  line-height: 1;
  margin-bottom: 0.7rem;
}
.stat-icon i {
  background: var(--brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.stat-label {
  position: relative;
  z-index: 1;
  font-size: 0.68rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
}

.stat-value {
  position: relative;
  z-index: 1;
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--plum);
  line-height: 1.1;
  margin-top: 0.2rem;
}

.stat-unit {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 600;
  margin-left: 1px;
}

.stat-sub {
  position: relative;
  z-index: 1;
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 0.2rem;
}

/* Icons are plain accent-coloured glyphs (no chip, no corner glow) — set
   above on .stat-icon; the label + value text tell the four stats apart. */

/* ── Progress Bar ── */
.journey-progress {
  height: 10px;
  background: var(--plum-light);
  border-radius: 99px;
}

.journey-progress .progress-bar {
  background: var(--brand-grad);
  border-radius: 99px;
}

/* Progress bars sweep out to their width (ui-motion.js resets to 0 then to the
   rendered value on first view). Keep an easing here so any width change — the
   animated fill included — glides rather than snaps. */
.progress-bar {
  transition: width 1.1s cubic-bezier(.22, 1, .36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .progress-bar { transition: none; }
}

.progress-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1rem;
  font-weight: 600;
  color: var(--plum);
}

.progress-pct.over-target {
  color: #b8433d;
}

.journey-progress .progress-bar.over-target {
  background: linear-gradient(90deg, var(--coral), #b8433d);
}

/* ── Activity Grid ── */
.activity-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}

.activity-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.65rem 0.85rem;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--gray-bg);
  position: relative;
  transition: all 0.15s;
}

.activity-item.done {
  background: var(--plum-surface);
  color: #fff;
  border-color: var(--plum);
}

.activity-item.done.coral {
  background: var(--coral);
  border-color: var(--coral);
}

.activity-item.done.mauve {
  background: var(--mauve);
  border-color: var(--mauve);
}

.activity-item.done.yellow {
  background: var(--plum-surface);
}

.activity-item.done.custom-color {
  background: var(--act-color);
  border-color: var(--act-color);
}

.check-badge {
  margin-left: auto;
  font-size: 1rem;
}

/* ── Calorie Ring ── */
.calorie-card-section {
  min-height: 0;
}

.calorie-card-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  min-height: 220px;
}

.calorie-ring-wrap {
  position: relative;
  width: 150px;
  flex-shrink: 0;
}

.calorie-ring {
  width: 150px;
  height: 150px;
  transform: rotate(-90deg);
}

.calorie-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 100px;
}

.cal-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--plum);
}

.cal-label {
  font-size: 0.65rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.cal-target {
  font-size: 0.62rem;
  color: var(--text-muted);
  line-height: 1.2;
  margin-top: 0.15rem;
}

.calorie-summary-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
}

.calorie-summary-item {
  text-align: center;
  min-width: 64px;
}

.calorie-summary-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1.1;
}

.calorie-summary-num.text-over {
  color: var(--coral);
}

.calorie-summary-label {
  font-size: 0.65rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 0.2rem;
}

.calorie-summary-divider {
  width: 1px;
  height: 30px;
  background: var(--border);
}

@media (max-width: 480px) {
  .calorie-card-body {
    min-height: 0;
    gap: 1rem;
  }

  .calorie-ring-wrap,
  .calorie-ring {
    width: 150px;
  }

  .calorie-ring {
    height: 150px;
  }

  .calorie-center {
    width: 80px;
  }
}

.macro-pills {
  display: flex;
  gap: 0.4rem;
  justify-content: center;
  flex-wrap: wrap;
}

.macro-pill {
  border-radius: 99px;
  padding: 0.2rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
}

.macro-p {
  background: rgba(224, 112, 106, 0.15);
  color: var(--coral);
}

.macro-c {
  background: rgba(240, 220, 130, 0.3);
  color: #7a6a00;
}

.macro-f {
  background: rgba(160, 104, 138, 0.15);
  color: var(--mauve);
}

/* ── Week Table ── */
.week-table-wrap {
  overflow-x: auto;
}

.week-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  white-space: nowrap;
}

.week-table th {
  padding: 0.5rem 0.6rem;
  color: var(--text-muted);
  font-weight: 600;
  text-align: center;
  border-bottom: 2px solid var(--border);
}

.week-table td {
  padding: 0.55rem 0.6rem;
  text-align: center;
  border-bottom: 1px solid var(--border);
}

.week-table tr.today-row {
  background: rgba(61, 32, 80, 0.05);
}

.day-cell {
  text-align: left !important;
}

.day-name {
  font-weight: 600;
  color: var(--plum);
}

.day-num {
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-left: 4px;
}

.weight-cell {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  color: var(--coral);
}

.cals-cell {
  font-family: 'JetBrains Mono', monospace;
}

/* ── Food Log ── */
.food-category-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--mauve);
  margin: 0.75rem 0 0.35rem;
}

.food-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  background: var(--gray-bg);
  margin-bottom: 0.35rem;
}

.food-name {
  font-weight: 600;
  font-size: 0.85rem;
}

.food-macros {
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* ── Add Food Panel ── */
.add-food-panel {
  background: rgba(61, 32, 80, 0.04);
  border: 1.5px dashed var(--plum-light);
  border-radius: 12px;
  padding: 1rem;
}

.afp-title {
  font-weight: 600;
  color: var(--plum);
  font-size: 0.9rem;
}

.afp-block {
  margin-top: 0.85rem;
}

.afp-subhead {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.fp-pill-recent {
  background: var(--accent-pale);
  border-color: transparent;
}

.fp-pill-recent:hover {
  border-color: var(--accent);
  background: var(--accent-pale);
}

/* ── Search box ── */
.afp-search-box {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 0.55rem 0.85rem;
}

.afp-search-box i {
  color: var(--text-muted);
  font-size: 0.9rem;
  flex-shrink: 0;
}

.afp-search-box input,
.afp-search-box textarea {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-family: 'Montserrat', sans-serif;
  font-size: 0.88rem;
  color: var(--text);
  min-width: 0;
}

/* Search field is a textarea so long descriptions (for the AI fetch) wrap
   and stay fully scrollable/editable instead of running off a single line. */
.afp-search-box textarea {
  resize: none;
  line-height: 1.45;
  max-height: 6.5em;
  overflow-y: auto;
  padding: 0;
}

.afp-search-box {
  align-items: flex-start;
}

.afp-search-box i {
  margin-top: 0.15rem;
}

.afp-search-clear {
  border: none;
  background: var(--gray-bg);
  color: var(--text-muted);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  flex-shrink: 0;
  cursor: pointer;
}

/* ── "or browse by type" divider ── */
.afp-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1rem 0 0.75rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.afp-divider::before,
.afp-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── Category tabs (replace the old full-screen "what are you adding" step) ── */
.fp-tabs {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.fp-tabs::-webkit-scrollbar {
  display: none;
}

.fp-tab {
  flex: 1 0 auto;
  border: 1.5px solid var(--border);
  background: var(--white);
  color: var(--text-muted);
  border-radius: 10px;
  padding: 0.55rem 0.9rem;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  transition: all 0.15s;
  white-space: nowrap;
}

.fp-tab:hover {
  border-color: var(--mauve-light);
}

.fp-tab.active {
  background: var(--plum-surface);
  border-color: var(--plum);
  color: var(--white);
}

.fp-pill.active,
.fp-pill-food.active {
  background: var(--coral);
  border-color: var(--coral);
  color: var(--white);
}

/* ── Guided Food Picker (meal type → group → item → qty) ── */
.food-picker {
  margin-top: 0.5rem;
}

.fp-step {
  animation: fpFadeIn 0.15s ease;
}

@keyframes fpFadeIn {
  from {
    opacity: 0;
    transform: translateY(2px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fp-step-label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--plum);
  margin-bottom: 0.6rem;
}

.fp-breadcrumb {
  color: var(--text-muted);
  font-weight: 500;
}

.fp-back-btn {
  border: none;
  background: var(--plum-light);
  color: var(--plum);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  transition: background 0.15s;
}

.fp-back-btn:hover {
  background: var(--mauve-light, var(--plum-light));
}

.fp-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.fp-pill {
  border: 1.5px solid var(--border);
  background: var(--white);
  color: var(--plum);
  border-radius: 99px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.fp-pill:hover {
  border-color: var(--coral);
  background: rgba(226, 111, 91, 0.08);
  transform: translateY(-1px);
}

.fp-pill-lg {
  padding: 0.7rem 1.4rem;
  font-size: 0.9rem;
}

.fp-pill-food small {
  color: var(--text-muted);
  font-weight: 500;
  margin-left: 0.15rem;
}

.fp-selected-name {
  font-weight: 600;
  font-size: 0.95rem;
}

.fp-empty {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.fp-browse-all {
  font-size: 0.82rem;
}

.fp-browse-all a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}

.fp-browse-all a:hover {
  text-decoration: underline;
}

/* ── Forms ── */
.form-control-custom {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  font-size: 0.88rem;
  background: var(--white);
  color: var(--text);
  outline: none;
  font-family: 'Montserrat', sans-serif;
  transition: border-color 0.15s;
}

/* iOS (Safari + WKWebView) auto-zooms into any focused field whose text is
   under 16px and leaves the page zoomed. That's why pinch-zoom used to be
   disabled app-wide — the wrong fix, since it also blocks people who genuinely
   need to zoom. Instead: on touch screens every typable control is exactly
   16px, so focus never triggers the zoom and pinch-zoom stays available.
   Desktop keeps the more compact 0.88rem. */
@media (hover: none) and (pointer: coarse) {
  .form-control-custom,
  .form-select,
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="date"],
  input[type="time"],
  select,
  textarea {
    font-size: 16px;
  }
}

.form-control-custom:focus {
  border-color: var(--mauve);
  box-shadow: 0 0 0 3px rgba(160, 104, 138, 0.12);
}

/* Read-only field (e.g. auto-synced steps): looks locked, not typeable. */
.form-control-custom.is-readonly {
  background: var(--gray-bg);
  color: var(--text-muted);
  cursor: not-allowed;
}
.form-control-custom.is-readonly:focus {
  border-color: var(--border);
  box-shadow: none;
}

.form-label-custom {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.3rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.divider-label {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--mauve);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}

.input-group-custom {
  display: flex;
  gap: 0.35rem;
}

.input-group-custom .unit-sel {
  width: auto;
  min-width: 80px;
}

textarea.form-control-custom {
  resize: vertical;
}

select.form-control-custom {
  appearance: auto;
  cursor: pointer;
}

.date-trigger-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
}

.date-trigger-text {
  font-weight: 600;
}

/* The real <input type="date"> stays in the DOM (so .showPicker()/native
   picker still works) but is visually hidden — the compact pill button
   above is what the user actually sees and taps. */
.date-picker-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
}

.topbar-date-nav {
  position: relative;
  flex-shrink: 0;
}

/* ── Activity Checklist ── */
/* Daily Activities — compact tile grid (icon on top, single-line label). */
.activity-checklist {
  /* Two tiles per row, wrapping. Flex (not grid) so every tile is the SAME
     width and an odd last tile is centred under the pair rather than stretched
     wide — works for any number of activities the user creates (4 → 2+2,
     6 → 2+2+2, 5 → 2+2+1 with the last one centred). */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}
.activity-checklist > .check-row {
  flex: 0 1 calc(50% - 0.3rem);
  min-width: 96px;
}

.check-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  gap: 0.55rem;
  padding: 0.95rem 0.55rem 0.8rem;
  border-radius: 16px;
  border: 1.5px solid var(--border);
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, background 0.18s ease;
  background: var(--white);
  position: relative;
}

.check-row:hover {
  border-color: var(--accent-light);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

/* Active = theme-accent border with a soft accent-pale wash so "done" reads
   at a glance, not just from the corner tick. */
.check-row.checked {
  border-color: var(--accent);
  background: var(--accent-pale);
}

/* Corner check mark — shown only when the activity is done. */
.check-row.checked::after {
  content: '\2713';
  position: absolute;
  top: 4px;
  right: 8px;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--accent);
}

.check-hidden {
  display: none;
}

/* Dashboard checklist: a small tappable check button in each tile. When the
   tile carries its own check button we hide the corner ✓ to avoid doubling. */
.check-row.dash-check::after { content: none; }
.check-mark {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  color: transparent;
  z-index: 1;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.check-row.checked .check-mark { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Activity icon — sits in a soft circular chip that fills with the theme
   gradient when the activity is done. */
.check-box {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  color: var(--text-muted);
  background: var(--gray-bg);
  flex-shrink: 0;
  transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.check-row:hover .check-box { background: var(--accent-pale); color: var(--accent); }
.check-row.checked .check-box {
  background: var(--brand-grad);
  color: var(--on-brand);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12);
}

.check-label {
  font-weight: 600;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--plum);
  max-width: 100%;
  /* Wrap to two lines instead of truncating — labels like "No Maida / Sugar"
     show in full. Reserve two lines so short and long labels stay aligned. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2rem;
}

/* The old inline ✅/○ text is replaced by the ::after corner check above. */
.check-status {
  display: none;
}

/* Metric-linked tiles (steps / weight) update automatically from the day's data,
   so they aren't hand-toggled. A small lock hints at that; the whole tile is still
   tappable to explain what's needed. */
.check-row.metric-locked {
  cursor: help;
}
.metric-lock {
  position: absolute;
  top: 9px;
  left: 9px;
  font-size: 0.68rem;
  line-height: 1;
  color: var(--text-muted);
  opacity: 0.55;
  z-index: 1;
}
.check-row.metric-locked.checked .metric-lock { color: var(--accent); opacity: 0.85; }

/* Transient message shown when tapping an auto-locked tile that's not done yet. */
.metric-toast {
  position: fixed;
  left: 50%;
  bottom: 84px;
  transform: translate(-50%, 12px);
  max-width: min(90vw, 360px);
  background: var(--plum);
  color: #fff;
  padding: 0.7rem 1rem;
  border-radius: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.22));
  opacity: 0;
  pointer-events: none;
  z-index: 4000;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.metric-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ── App-wide toast (assets/js/toast.js) ──────────────────────────────────
   The unified successor to .metric-toast: same bottom-centred pill, plus an
   optional leading icon, an action button, and success/error variants. */
.ab-toast {
  position: fixed;
  left: 50%;
  bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 12px);
  display: flex;
  align-items: center;
  gap: 0.55rem;
  max-width: min(92vw, 400px);
  background: var(--plum);
  color: #fff;
  padding: 0.7rem 1rem;
  border-radius: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.35;
  box-shadow: var(--shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.22));
  opacity: 0;
  pointer-events: none;
  z-index: 4000;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.ab-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
  cursor: pointer;
}
.ab-toast-ico {
  display: inline-flex;
  font-size: 1.05rem;
  line-height: 1;
}
.ab-toast-msg {
  flex: 1 1 auto;
  min-width: 0;
}
.ab-toast-success .ab-toast-ico { color: #4ade80; }
.ab-toast-error { background: #b3261e; } /* readable error red in both themes */
.ab-toast-error .ab-toast-ico { color: #fff; }
.ab-toast-action {
  flex: none;
  margin: -0.15rem -0.3rem -0.15rem 0.15rem;
  background: rgba(255, 255, 255, 0.16);
  border: 0;
  color: #fff;
  font: inherit;
  font-weight: 700;
  padding: 0.35rem 0.65rem;
  border-radius: 8px;
  cursor: pointer;
}
.ab-toast-action:hover { background: rgba(255, 255, 255, 0.26); }
@media (prefers-reduced-motion: reduce) {
  .ab-toast { transition: opacity 0.2s ease; }
}

/* ── Pull-to-refresh indicator (assets/js/pull-refresh.js) ── */
.ptr-indicator {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 4px);
  left: 50%;
  transform: translateX(-50%) translateY(0);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--card-bg, #fff);
  color: var(--accent, #3f37c9);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  opacity: 0;
  z-index: 9998;
  pointer-events: none;
}
.ptr-indicator.ptr-animate {
  transition: transform 0.25s ease, opacity 0.25s ease;
}
.ptr-spinner {
  display: flex;
  font-size: 1.15rem;
  line-height: 1;
}
.ptr-indicator.ptr-armed {
  color: #fff;
  background: var(--accent, #3f37c9);
}
.ptr-indicator.ptr-refreshing .ptr-spinner {
  animation: ptrspin 0.7s linear infinite;
}
@keyframes ptrspin { to { transform: rotate(360deg); } }

/* ── PL-01: make app chrome feel native to touch ──
   Long-pressing a tab, icon or heading in a wrapped app pops the browser's
   "Copy image / Share…" callout and lets chrome text be selected like a
   document — both obvious "this is a webpage" tells. Suppress selection and the
   callout on navigation, controls and labels, while leaving real content
   (logged food, AI insights, input values) fully selectable. */
.sidebar,
.mobile-bottom-nav,
.topbar,
.date-select,
.mbn-item,
.nav-link,
.nav-label,
.section-label,
.topbar-title,
.topbar-date,
.stat-label,
.date-chip,
button,
.btn {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
/* Decorative chrome images (avatar, brand) shouldn't offer Save/Share either. */
.topbar-profile img,
.sidebar-profile img,
.brand-icon img {
  -webkit-touch-callout: none;
}
/* Safety net: form fields and anything explicitly editable stay selectable
   regardless of a non-selecting ancestor. */
input,
textarea,
select,
[contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
}

/* ── Nutrition Preview ── */
.nutrition-preview {
  background: var(--plum-surface);
  color: #fff;
  padding: 0.4rem 0.7rem;
  border-radius: 8px;
  font-size: 0.78rem;
  line-height: 1.5;
  height: 100%;
}

/* ── Food DB ── */
.food-db-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.75rem;
}

.food-db-card {
  background: var(--gray-bg);
  border-radius: 12px;
  padding: 0.9rem;
  border: 1px solid var(--border);
  transition: border-color 0.15s ease;
}

.food-db-card:hover {
  border-color: var(--accent);
}

.fdc-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.fdc-name {
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--plum);
}

.fdc-group-tag {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--accent);
  background: rgba(63, 55, 202, 0.08);
  border-radius: 4px;
  padding: 1px 6px;
  margin-bottom: 0.4rem;
}

.fdc-serving {
  font-size: 0.72rem;
  margin-bottom: 0.5rem;
}

.fdc-macros {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.macro-chip {
  border-radius: 6px;
  padding: 0.15rem 0.45rem;
  font-size: 0.68rem;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
}

.macro-chip.cal {
  background: rgba(224, 112, 106, 0.15);
  color: var(--coral);
}

.macro-chip.prot {
  background: rgba(61, 32, 80, 0.1);
  color: var(--plum);
}

.macro-chip.carb {
  background: rgba(240, 220, 130, 0.4);
  color: #7a6a00;
}

.macro-chip.fat {
  background: rgba(160, 104, 138, 0.15);
  color: var(--mauve);
}

.macro-chip.fiber {
  background: rgba(100, 180, 100, 0.15);
  color: #3a7a3a;
}

.macro-chip.chol {
  background: rgba(37, 117, 252, 0.12);
  color: var(--accent);
}

.fdc-notes {
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 0.4rem;
  font-style: italic;
}

.count-badge {
  display: inline-block;
  background: var(--mauve);
  color: #fff;
  border-radius: 99px;
  padding: 0.1rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  margin-left: 0.4rem;
}

/* ── Food Entry ── */
.food-section {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.75rem;
}

.food-cat-header {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 800;
  color: var(--plum);
  margin-bottom: 0.5rem;
  margin-top: 0.25rem;
}

.food-empty {
  color: var(--text-muted);
  font-size: 0.82rem;
  padding: 0.5rem 0;
}

.food-empty-day {
  text-align: center;
  padding: 1.25rem 0.5rem;
  background: var(--gray-bg);
  border-radius: 10px;
}

.food-entry {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.7rem;
  background: var(--gray-bg);
  border-radius: 8px;
  margin-bottom: 0.35rem;
}

.fe-info {
  flex: 1;
}

.fe-name {
  font-weight: 600;
  font-size: 0.85rem;
}

.fe-macros {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.fe-remove {
  flex-shrink: 0;
}

/* ── Mini Stats ── */
.mini-stat {
  background: var(--white);
  border-radius: 10px;
  padding: 0.85rem 1rem;
  text-align: center;
  border: 1.5px solid var(--border);
}

.mini-stat.calories {
  border-top: 3px solid var(--coral);
}

.mini-stat.protein {
  border-top: 3px solid var(--plum);
}

.mini-stat.carbs {
  border-top: 3px solid #b8a500;
}

.mini-stat.fat {
  border-top: 3px solid var(--mauve);
}

.mini-stat.fiber {
  border-top: 3px solid var(--accent);
}

.mini-stat.sugar {
  border-top: 3px solid var(--gold-deep);
}

.mini-stat.sodium {
  border-top: 3px solid var(--coral);
}

.mini-stat.cholesterol {
  border-top: 3px solid var(--plum-mid);
}

.ms-val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--plum);
}

.ms-label {
  font-size: 0.7rem;
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
}

/* ── Health Alerts ── */
/* Same surface as the AI Report Insight card (.ai-insight-card): white bg,
   soft layered shadow, rounded, subtle accent-pale border. */
.health-alert-card {
  background: var(--white);
  border-radius: 20px;
  padding: 1.1rem;
  border: 1px solid var(--accent-pale);
  box-shadow: var(--shadow);
  height: 100%;
}

/* Colour-variant classes kept for markup compatibility — all alert cards
   look identical now (no accent top-stripe). */
.health-alert-card.coral,
.health-alert-card.mauve,
.health-alert-card.yellow {
  border: 1px solid var(--accent-pale);
}

.hac-title {
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--plum);
  margin-bottom: 0.75rem;
}

.hac-tips {
  list-style: none;
  padding: 0;
}

.hac-tips li {
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 0.25rem 0;
  border-bottom: 1px dashed var(--border);
}

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

.hac-tips li::before {
  content: '→ ';
  color: var(--coral);
  font-weight: 600;
}

/* ── Blood Tests ── */
.blood-test-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.75rem;
}

/* Flat gray tiles — same look as the "Nutrition Today" nutrient-card. No
   coloured left-border/tint; status is still conveyed by the bar + status
   text below (.tc-bar-fill / .tc-status), just like the nutrient bars. */
.test-card {
  background: var(--gray-bg);
  border-radius: 12px;
  padding: 0.9rem;
  border: none;
}

.test-card.red-border,
.test-card.orange-border,
.test-card.green-border {
  background: var(--gray-bg);
}

.tc-name {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.3rem;
}

.tc-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--plum);
}

.tc-unit {
  font-size: 0.7rem;
  color: var(--text-muted);
}

.tc-normal {
  font-size: 0.68rem;
  color: var(--text-muted);
  margin-top: 0.2rem;
  margin-bottom: 0.5rem;
}

.tc-bar {
  height: 6px;
  background: var(--plum-light);
  border-radius: 99px;
  position: relative;
  overflow: visible;
}

.tc-bar-fill {
  height: 100%;
  border-radius: 99px;
  position: absolute;
  top: 0;
  left: 0;
}

.tc-bar-fill.red {
  background: #e05555;
}

.tc-bar-fill.orange {
  background: #e08840;
}

.tc-bar-fill.green {
  background: #4aaa60;
}

.tc-bar-normal {
  position: absolute;
  top: -3px;
  height: 12px;
  width: 2px;
  background: var(--plum-surface);
  border-radius: 2px;
}

.tc-status {
  font-size: 0.72rem;
  font-weight: 600;
  margin-top: 0.45rem;
}

.tc-status.red {
  color: #c03030;
}

.tc-status.orange {
  color: #b05520;
}

.tc-status.green {
  color: #2a8a40;
}

/* Same muted treatment as the "Nutrition Today" date, so the report header
   and the nutrition header read identically. */
.report-date-badge {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
}

/* Report History */
.report-history-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 0.5rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}

.report-history-row:hover {
  background: var(--gray-bg);
  border-radius: 8px;
}

.rhr-date {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: var(--text-muted);
  width: 90px;
  flex-shrink: 0;
}

.rhr-label {
  flex: 1;
  font-weight: 600;
  font-size: 0.88rem;
}

.badge-high {
  background: rgba(224, 112, 106, 0.15);
  color: var(--coral);
  border-radius: 99px;
  padding: 0.15rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
}

.badge-ok {
  background: rgba(74, 170, 96, 0.15);
  color: #2a8a40;
  border-radius: 99px;
  padding: 0.15rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
}

.rhr-arrow {
  color: var(--text-muted);
  transition: transform 0.2s;
}

.report-detail {
  padding: 0.75rem 0.5rem;
  background: var(--gray-bg);
  border-radius: 0 0 10px 10px;
  margin-bottom: 0.5rem;
}

.blood-test-grid.compact {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.test-row-compact {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--border);
}

.trc-name {
  flex: 1;
  font-size: 0.82rem;
}

.trc-val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--plum);
}

.trc-status {
  font-size: 0.9rem;
}

/* ── Progress Page ── */
/* Same surface as the AI Report Insight card (.ai-insight-card): white bg,
   soft layered shadow, rounded, subtle accent-pale border. */
.progress-stat-card {
  background: var(--white);
  border-radius: 20px;
  padding: 1.1rem 1rem;
  border: 1px solid var(--accent-pale);
  box-shadow: var(--shadow);
  text-align: center;
}

/* Colour-variant classes kept for markup compatibility — all cards identical. */
.progress-stat-card.coral,
.progress-stat-card.mauve,
.progress-stat-card.yellow,
.progress-stat-card.plum {
  border: 1px solid var(--accent-pale);
}

.psc-icon {
  font-size: 1.3rem;
  margin-bottom: 0.3rem;
  line-height: 1;
}

/* Every stat icon rendered in the one brand gradient. */
.psc-icon i {
  background: var(--brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.psc-val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.8rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1;
}

.psc-label {
  font-size: 0.72rem;
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 0.25rem;
}

/* ── Heatmap ── */
.heatmap-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}

.heat-cell {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  cursor: default;
}

/* Single-hue purple intensity scale (Less → More) in the brand family. */
.heat-cell.level-0 {
  background: rgba(106, 17, 203, 0.12);
}

.heat-cell.level-1 {
  background: rgba(106, 17, 203, 0.38);
}

.heat-cell.level-2 {
  background: rgba(106, 17, 203, 0.68);
}

.heat-cell.level-3 {
  background: #6a11cb;
}

.heatmap-legend {
  display: flex;
  align-items: center;
  gap: 5px;
}

.legend-cell {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ── Timeline ── */
.timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.timeline-item {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding-bottom: 1.5rem;
  position: relative;
}

.timeline-item:last-child {
  padding-bottom: 0;
}

.timeline-item:not(:last-child)::before {
  content: '';
  position: absolute;
  left: 18px;
  top: 40px;
  bottom: 0;
  width: 2px;
  background: var(--border);
}

.tl-dot {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  flex-shrink: 0;
  color: #fff;
  position: relative;
  z-index: 1;
}

.tl-dot.coral {
  background: var(--coral);
}

.tl-dot.mauve {
  background: var(--mauve);
}

.tl-dot.yellow {
  background: #b8a500;
}

.tl-dot.plum {
  background: var(--plum-surface);
}

.timeline-item.future .tl-dot {
  opacity: 0.5;
}

.tl-date {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.tl-label {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--plum);
}

.tl-weight {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.85rem;
  color: var(--coral);
}

.tl-actual {
  font-size: 0.75rem;
  color: var(--mauve);
  font-weight: 600;
  margin-top: 0.15rem;
}

/* ── BMI ── */
.bmi-card {
  text-align: center;
  padding: 1rem;
  border-radius: 12px;
  background: var(--gray-bg);
  border: 1.5px solid var(--border);
}

.bmi-card.current {
  background: rgba(61, 32, 80, 0.06);
  border-color: var(--plum);
}

.bmi-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-weight: 600;
}

.bmi-val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.8rem;
  font-weight: 600;
  color: var(--plum);
}

.bmi-cat {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.bmi-scale {
  position: relative;
}

.bmi-scale-bar {
  height: 10px;
  background: linear-gradient(90deg, #4aaa60 30%, #e0c840 50%, #e08840 70%, #e05555 100%);
  border-radius: 99px;
  margin-bottom: 4px;
}

.bmi-marker {
  position: absolute;
  top: -6px;
  transform: translateX(-50%);
  font-size: 0.9rem;
  color: var(--plum);
  font-weight: 900;
}

/* ── Alerts ── */
.alert-success-custom {
  background: rgba(74, 170, 96, 0.1);
  border: 1px solid rgba(74, 170, 96, 0.3);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  color: #2a8a40;
  font-size: 0.85rem;
}

.alert-info-custom {
  background: rgba(160, 104, 138, 0.08);
  border: 1px solid rgba(160, 104, 138, 0.2);
  border-radius: 8px;
  padding: 0.6rem 0.85rem;
  color: var(--mauve);
  font-size: 0.8rem;
}

.alert-storage-warning {
  background: rgba(224, 112, 106, 0.12);
  border: 1.5px solid var(--coral);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  color: #a8403a;
  font-size: 0.85rem;
}

.alert-storage-warning code {
  background: rgba(0, 0, 0, 0.08);
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
}

/* ── Empty State ── */
.empty-state {
  text-align: center;
  padding: 2.2rem 1rem;
  color: var(--text-muted);
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The leading glyph becomes an illustrated medallion (PL-04): the contextual
   icon sits in a soft accent gradient disc ringed by two faint concentric halos
   with a couple of floating accent dots, so a blank card reads as a designed
   scene rather than a lone icon. All theme-aware via the accent tokens; the
   icon font owns ::before, so the dots live on ::after. */
.empty-state > i:first-child {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  margin-bottom: 1.5rem;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 32%,
              color-mix(in srgb, var(--accent) 24%, var(--card-bg, #fff)),
              var(--accent-pale));
  color: var(--accent);
  font-size: 1.65rem !important;
  line-height: 1;
  box-shadow:
    0 0 0 10px color-mix(in srgb, var(--accent) 9%, transparent),
    0 0 0 20px color-mix(in srgb, var(--accent) 4%, transparent);
}
/* Floating accent dots: a bright one top-right, a smaller faint one lower-left
   (via the shadow), giving the medallion a hand-placed, illustrated feel. */
.empty-state > i:first-child::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -7px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: -30px 34px 0 -4px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* Browsers without color-mix() fall back to the original flat accent chip. */
@supports not (background: color-mix(in srgb, red, blue)) {
  .empty-state > i:first-child { background: var(--accent-pale); box-shadow: none; }
  .empty-state > i:first-child::after { display: none; }
}

.empty-state p {
  margin-top: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  max-width: 34ch;
}

/* Inline "→" links inside the copy read as a bold accent call-to-action. */
.empty-state p a {
  color: var(--accent);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.empty-state p a:hover { text-decoration: underline; }

/* An explicit pill CTA button (a direct child) coaches the first step. */
.empty-state .es-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.9rem;
  padding: 0.55rem 1.15rem;
  border: 0;
  border-radius: 999px;
  background: var(--brand-grad);
  color: var(--on-brand) !important;
  font-weight: 700;
  font-size: 0.86rem;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: filter 0.15s ease, transform 0.15s ease;
}
.empty-state .es-cta:hover { filter: brightness(1.04); transform: translateY(-1px); }
.empty-state .es-cta:active { transform: scale(0.98); }

/* ── Reminders Page ── */
.reminder-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.reminder-row {
  display: flex;
  align-items: start;
  gap: 0.9rem;
  padding: 0.7rem 0.9rem;
  border-radius: 10px;
  background: var(--gray-bg);
  border: 1px solid var(--border);
  transition: opacity 0.15s;
  flex-direction: column;
}

.reminder-row.disabled {
  opacity: 0.55;
}

.reminder-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.reminder-time {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--accent);
  min-width: 78px;
  flex-shrink: 0;
}

.reminder-info {
  flex: 1;
  min-width: 0;
}

.reminder-title-tag {
  display: inline-block;
  font-weight: 600;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--accent);
  background: rgba(var(--accent-rgb, 63, 55, 202), 0.1);
  border-radius: 4px;
  padding: 1px 6px;
  margin-bottom: 3px;
}

.reminder-label {
  font-weight: 600;
  font-size: 0.88rem;
}

.reminder-days {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.reminder-switch {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
}

.reminder-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.reminder-switch-track {
  position: absolute;
  inset: 0;
  background: #cfc7d6;
  border-radius: 99px;
  cursor: pointer;
  transition: background 0.2s;
}

.reminder-switch-track::before {
  content: '';
  position: absolute;
  width: 18px;
  height: 18px;
  left: 3px;
  top: 3px;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.2s;
}

.reminder-switch input:checked+.reminder-switch-track {
  background: var(--brand-grad);
}

.reminder-switch input:checked+.reminder-switch-track::before {
  transform: translateX(18px);
}

.status-switch-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  height: 38px;
}

.status-switch-text {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-muted);
}

/* Seven circular day toggles spread across the full width (S M T W T F S).
   They flex to share the row and shrink to fit narrow phones, staying circular
   via aspect-ratio (align-items:center stops them from stretching tall). */
.day-picker {
  display: flex;
  gap: 0.3rem;
  align-items: center;
  justify-content: space-between;
}

.day-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 0;
  min-width: 0;
  max-width: 44px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: var(--gray-bg);
  border: 1.5px solid var(--border);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}

.day-chip-input {
  display: none;
}

.day-chip-input:checked+span {
  color: var(--on-brand, #fff);
}

.day-chip:has(.day-chip-input:checked) {
  background: var(--brand-grad);
  border-color: transparent;
}

.day-chip.active {
  background: var(--brand-grad);
  border-color: transparent;
}

.day-chip.active span {
  color: var(--on-brand, #fff);
}

/* Time input: stop the native control from overflowing its field on iOS. */
input[type="time"].form-control-custom,
input[type="date"].form-control-custom {
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
}

/* Save / Cancel share the row 50 / 50. */
.reminder-form-actions,
.food-form-actions {
  display: flex;
  gap: 0.6rem;
}
.reminder-form-actions .btn,
.food-form-actions .btn {
  flex: 1 1 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Accordion edit: the form docks INSIDE the reminder card instead of opening a
   separate card, so editing expands the same card in place — keeping the card's
   existing grey surface (no white flip). */
#reminderFormCard.docked {
  align-self: stretch;
  width: 100%;
  /* !important to beat premium.css's forced .card-section surface + Bootstrap's
     .mb-4 bottom margin, so the edit form blends into the reminder card (no
     inner card / shadow) and doesn't leave a big gap under the buttons. */
  background: transparent !important;
  box-shadow: none !important;
  border: none !important;
  border-top: 1px solid var(--border) !important;
  border-radius: 0 !important;
  padding: 0.9rem 0 0 !important;
  margin: 0.7rem 0 0 !important;
}
/* Zero the Bootstrap grid gutter so the fields align to the card edges instead
   of overflowing (the docked form has no side padding to absorb them). */
#reminderFormCard.docked .row {
  --bs-gutter-x: 0;
  margin-left: 0;
  margin-right: 0;
}
#reminderFormCard.docked #reminderFormTitle {
  display: none;
}

/* ── Manage Activities Page ── */
.activity-row-icon {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  color: #fff;
  background: var(--brand-grad);
  box-shadow: var(--shadow);
  flex-shrink: 0;
}

/* Activity icons all share the one brand gradient (the colour variants used
   to be coral/mauve/gold — now unified). */
.activity-row-icon.coral,
.activity-row-icon.mauve,
.activity-row-icon.yellow {
  background: var(--brand-grad);
}

.activity-row-icon.custom-color {
  background: var(--act-color);
}

/* Subtitle line under the activity name (Your Activities list). */
.reminder-sub {
  font-size: 0.74rem;
  color: var(--text-muted);
  margin-top: 1px;
}

/* Rounded-square control buttons on each activity row (edit / delete / order). */
.act-ctrl-btn {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
}

.act-ctrl-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

.act-ctrl-btn:disabled {
  opacity: 0.4;
  cursor: default;
  transform: none;
}

.act-ctrl-danger:hover {
  border-color: var(--coral);
  color: var(--coral);
}

/* "Your Activities" rows → clean elevated cards (mockup style). */
.activity-row {
  background: var(--card-bg) !important;
  border: 1.5px solid var(--border) !important;
  border-radius: 16px !important;
  padding: 0.8rem 0.9rem !important;
  box-shadow: none !important; /* defined by its border, not a floating shadow */
}

/* Drag handle for reordering activities (replaces the up/down arrows). */
.act-drag-handle {
  flex: none;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.25rem;
  line-height: 1;
  padding: 0.25rem 0.15rem;
  cursor: grab;
  touch-action: none; /* let the pointer drag the row instead of scrolling */
  display: flex;
  align-items: center;
}
.act-drag-handle:active { cursor: grabbing; }
/* Rows glide when shifting to open a gap; no text selection during a drag. */
.activity-row {
  transition: transform 0.16s ease;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.activity-row.dragging {
  transition: none; /* the dragged row follows the finger instantly */
  opacity: 0.97;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.22);
  position: relative;
  z-index: 5;
}

.activity-row .reminder-label {
  font-size: 1rem;
  font-weight: 700;
  color: var(--plum);
}

.color-swatch-row {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  height: 38px;
}

.color-swatch-option {
  position: relative;
  cursor: pointer;
}

.color-swatch-option input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.color-swatch-option span {
  display: block;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid transparent;
  box-shadow: 0 0 0 1px var(--border);
}

.color-swatch-option.plum span {
  background: var(--plum-surface);
}

.color-swatch-option.coral span {
  background: var(--coral);
}

.color-swatch-option.mauve span {
  background: var(--mauve);
}

.color-swatch-option.yellow span {
  background: var(--gold-deep);
}

.color-swatch-option input:checked+span {
  border-color: #fff;
  box-shadow: 0 0 0 2px currentColor, 0 0 0 4px var(--border);
}

/* Custom color swatch: a radio option like the presets, but its dot shows
   a conic-gradient "wheel" until a hex has actually been picked, at which
   point it shows that color instead — same visual language as the presets. */
.color-swatch-option.custom-swatch span {
  background: conic-gradient(from 0deg, #E0706A, #F0DC82, #A0688A, #3D2050, #E0706A);
}

.color-swatch-option.custom-swatch.has-value span {
  background: var(--act-color);
}

/* The native color input that appears once "Custom" is selected. Kept
   small and inline so it reads as part of the swatch row, not a separate
   form field. */
.custom-color-input {
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  background: none;
  flex-shrink: 0;
}

.custom-color-input::-webkit-color-swatch-wrapper {
  padding: 0;
  border-radius: 50%;
}

.custom-color-input::-webkit-color-swatch {
  border: 2px solid var(--border);
  border-radius: 50%;
}

.custom-color-input::-moz-color-swatch {
  border: 2px solid var(--border);
  border-radius: 50%;
}

.icon-picker-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.icon-preview {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--gray-bg);
  border: 1.5px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  color: var(--plum);
  flex-shrink: 0;
}

.icon-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(42px, 1fr));
  gap: 0.4rem;
}

.icon-picker-btn {
  width: 42px;
  height: 42px;
  border-radius: 8px;
  border: 1.5px solid var(--border);
  background: var(--gray-bg);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.05rem;
  cursor: pointer;
  transition: all 0.15s;
}

.icon-picker-btn:hover {
  background: var(--plum-light);
  color: var(--plum);
  border-color: var(--plum);
}

/* ── Confirm sheet ── replaces blocking confirm(); bottom sheet on phones,
   centred dialog on wider screens. See assets/js/confirm-sheet.js. */
.cf-overlay {
  position: fixed;
  inset: 0;
  z-index: 1300; /* above the bottom nav (1000) and sync badge (1200) */
  display: flex;
  align-items: flex-end;         /* sheet rises from the bottom on mobile */
  justify-content: center;
  background: rgba(15, 11, 23, 0);
  transition: background 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.cf-overlay.cf-in { background: rgba(15, 11, 23, 0.5); }

.cf-sheet {
  width: 100%;
  max-width: 460px;
  background: var(--white);
  color: var(--text);
  border-radius: 20px 20px 0 0;
  padding: 1.5rem 1.4rem calc(1.4rem + env(safe-area-inset-bottom));
  box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.3);
  transform: translateY(100%);
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}
.cf-overlay.cf-in .cf-sheet { transform: translateY(0); }

.cf-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--plum);
  margin: 0 0 0.5rem;
  line-height: 1.3;
}
.cf-msg {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.5;
  margin: 0 0 1.4rem;
}
.cf-actions { display: flex; gap: 0.6rem; }
.cf-btn {
  flex: 1;
  min-height: 48px;
  border-radius: 12px;
  border: 0;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.15s, background 0.15s;
}
.cf-cancel { background: var(--gray-bg); color: var(--text); border: 1px solid var(--border); }
.cf-cancel:hover { filter: brightness(0.97); }
.cf-ok { background: var(--accent); color: #fff; }
.cf-ok:hover { filter: brightness(1.06); }
.cf-btn-danger { background: var(--coral); color: #fff; }
.cf-btn:focus-visible { outline: 2px solid var(--plum); outline-offset: 2px; }

/* Wider screens: centre it and let it scale in like a dialog. */
@media (min-width: 560px) {
  .cf-overlay { align-items: center; }
  .cf-sheet {
    border-radius: 18px;
    padding-bottom: 1.4rem;
    transform: translateY(12px) scale(0.96);
    opacity: 0;
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.22s ease;
  }
  .cf-overlay.cf-in .cf-sheet { transform: translateY(0) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .cf-overlay, .cf-sheet { transition: none; }
  .cf-sheet { transform: none; opacity: 1; }
}

/* ── Sync Badge ── an app-style toast that reports save status. On phones it
   sits ABOVE the bottom nav + FAB (both live bottom-right) and is centred so
   it's never hidden behind them; on desktop (no bottom nav) it returns to the
   bottom-right corner. z-index clears the nav (which is ~1000). */
.sync-badge {
  position: fixed;
  bottom: calc(5.75rem + env(safe-area-inset-bottom, 0px));
  left: 50%;
  z-index: 1200;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.15rem;
  border-radius: 99px;
  font-size: 0.85rem;
  font-weight: 700;
  color: #fff;
  box-shadow: 0 10px 30px -6px rgba(0, 0, 0, 0.35), 0 2px 8px rgba(0, 0, 0, 0.18);
  opacity: 0;
  transform: translate(-50%, 14px) scale(0.96);
  transition: opacity 0.24s ease, transform 0.34s cubic-bezier(0.22, 1.2, 0.36, 1);
  pointer-events: none;
  white-space: nowrap;
}

.sync-badge.visible {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}

.sync-badge.state-saving {
  background: var(--mauve);
}

.sync-badge.state-synced {
  background: #2a8a40;
}

.sync-badge.state-failed {
  background: var(--coral);
  pointer-events: auto;
}

.sync-badge i {
  font-size: 1rem;
}

/* Desktop: no bottom nav, so anchor back to the bottom-right corner. */
@media (min-width: 992px) {
  .sync-badge {
    bottom: 1.5rem;
    left: auto;
    right: 1.5rem;
    transform: translate(0, 14px) scale(0.96);
  }
  .sync-badge.visible {
    transform: translate(0, 0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sync-badge {
    transition: opacity 0.2s ease;
    transform: translate(-50%, 0);
  }
  .sync-badge.visible { transform: translate(-50%, 0); }
  @media (min-width: 992px) {
    .sync-badge, .sync-badge.visible { transform: translate(0, 0); }
  }
}

.sync-spinner {
  width: 13px;
  height: 13px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  border-radius: 50%;
  display: inline-block;
  animation: sync-spin 0.7s linear infinite;
}

@keyframes sync-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Inline per-row sync state (small dot next to a save button) */
.inline-sync {
  font-size: 0.75rem;
  font-weight: 600;
  margin-left: 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.inline-sync.saving {
  color: var(--mauve);
}

.inline-sync.synced {
  color: #2a8a40;
}

.inline-sync.failed {
  color: var(--coral);
}

/* ── Responsive ── */
@media (max-width: 991.98px) {
  .sidebar {
    transform: translateX(-100%);
    width: var(--sidebar-w) !important;
  }

  .sidebar.open {
    transform: translateX(0);
    box-shadow: 4px 0 24px rgba(61, 32, 80, 0.25);
  }

  .sidebar.collapsed~.main-content {
    margin-left: 0;
  }

  .main-content {
    margin-left: 0;
  }

  .activity-grid {
    grid-template-columns: 1fr;
  }

  .sidebar-close-btn {
    display: inline-flex;
  }

  /* On mobile, never show the collapsed icon-rail styling — it's full overlay or nothing */
  .sidebar.collapsed .brand-text,
  .sidebar.collapsed .nav-link span.nav-label,
  .sidebar.collapsed .sidebar-version,
  .sidebar.collapsed .sidebar-profile>div:last-child {
    display: inline;
  }

  .sidebar.collapsed .sidebar-brand {
    justify-content: flex-start;
    padding: 1.5rem 1.25rem 1rem;
  }

  .sidebar.collapsed .sidebar-nav .nav-link {
    justify-content: flex-start;
    padding: 0.6rem 0.85rem;
  }

  .sidebar.collapsed .sidebar-profile {
    justify-content: flex-start;
    padding: 1rem 1.25rem;
  }
}

@media (max-width: 575.98px) {
  .content-area {
    padding: 1rem;
  }

  .topbar {
    padding: 0.75rem 1rem;
  }

  .topbar-action-text {
    display: none;
  }

  .topbar .topbar-action-btn {
    width: 38px;
    height: 38px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }

  .topbar .topbar-action-btn i {
    margin: 0 !important;
    font-size: 1.05rem;
  }

  .topbar>.d-flex.align-items-center.gap-3 {
    min-width: 0;
    overflow: hidden;
  }

  .topbar-heading {
    min-width: 0;
    overflow: hidden;
  }

  .topbar-heading .topbar-date {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 46vw;
  }

  .date-trigger-text {
    display: none;
  }

  .date-trigger-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
  }

  .stat-value {
    font-size: 1.4rem;
  }

  .blood-test-grid {
    grid-template-columns: 1fr 1fr;
  }

  .food-db-grid {
    grid-template-columns: 1fr;
  }

  .week-table {
    font-size: 0.75rem;
  }

  .food-row {
    display: block;
  }

  .food-macros {
    margin-top: 0.15rem;
  }
}

/* ── Nutrition Today (dashboard) ── */
.nutrition-today-date {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 600;
}

.nutrient-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75rem;
}

.nutrient-card {
  background: var(--gray-bg);
  border-radius: 12px;
  padding: 0.85rem 0.9rem;
  border: 1.5px solid var(--border);
  border-top: 3px solid var(--plum-light);
}

.nutrient-card-top {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 0.35rem;
}

.nutrient-card-top i {
  font-size: 0.85rem;
}

.nutrient-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1.1;
}

.nutrient-unit {
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--text-muted);
  margin-left: 0.15rem;
}

.nutrient-target {
  font-size: 0.68rem;
  color: var(--text-muted);
  margin-top: 0.15rem;
  margin-bottom: 0.5rem;
}

.nutrient-bar {
  position: relative;
  height: 6px;
  background: var(--plum-light);
  border-radius: 99px;
  overflow: visible;
}

.nutrient-bar-fill {
  height: 100%;
  border-radius: 99px;
  background: var(--mauve);
  transition: width 0.3s ease;
}

.nutrient-bar-min {
  position: absolute;
  top: -2px;
  width: 2px;
  height: 10px;
  background: var(--plum-surface);
  opacity: 0.5;
  border-radius: 1px;
}

/* Status accents: under target, within target, over target */
.nutrient-card.status-good {
  border-top-color: #6FA97C;
}

.nutrient-card.status-good .nutrient-bar-fill {
  background: #6FA97C;
}

.nutrient-card.status-under {
  border: 1.5px solid var(--border);
}

.nutrient-card.status-under .nutrient-bar-fill {
  background: #D9BE4E;
}

.nutrient-card.status-over {
  border-top-color: var(--coral);
}

.nutrient-card.status-over .nutrient-bar-fill {
  background: var(--coral);
}

@media (max-width: 991px) {
  .nutrient-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .nutrient-grid {
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
  }

  .nutrient-value {
    font-size: 1.1rem;
  }
}

/* ── Steps card (dashboard + daily log): shows count vs. target, tints
   its own background by percentage-of-goal, and reveals a checkmark
   once the target is hit. Same status-bucket idea as the Nutrition
   Today cards above, just applied to the whole card's background
   instead of only the border/bar. ── */
.steps-card-section {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-top: 3px solid var(--plum-light);
  border-radius: 14px;
  padding: 1rem 1.1rem;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.steps-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.65rem;
}

.steps-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--plum-light);
  color: var(--plum);
  font-size: 1rem;
  flex-shrink: 0;
}

.steps-card-body {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.steps-card-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1;
}

.steps-card-target {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.steps-card-bar {
  position: relative;
  height: 8px;
  background: rgba(61, 32, 80, 0.1);
  border-radius: 99px;
  margin-top: 0.7rem;
  overflow: hidden;
}

.steps-card-bar-fill {
  height: 100%;
  border-radius: 99px;
  background: var(--mauve);
  transition: width 0.3s ease, background 0.3s ease;
}

.steps-card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0.5rem;
}

.steps-card-pct {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--plum);
}

.steps-card-check {
  display: none;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: #3F7A4E;
}

/* Status accents — under target / getting there / goal reached.
   Background stays the normal card color (var(--gray-bg), set on
   .steps-card-section itself); only the border, bar, and % text change. */
.steps-card-section.status-low {
  border-top-color: var(--coral);
}

.steps-card-section.status-low .steps-card-bar-fill {
  background: var(--coral);
}

.steps-card-section.status-low .steps-card-pct {
  color: var(--coral);
}

.steps-card-section.status-mid {
  border-top-color: #D9BE4E;
}

.steps-card-section.status-mid .steps-card-bar-fill {
  background: #D9BE4E;
}

.steps-card-section.status-mid .steps-card-pct {
  color: #8A7420;
}

.steps-card-section.status-good {
  border-top-color: #6FA97C;
}

.steps-card-section.status-good .steps-card-bar-fill {
  background: #6FA97C;
}

.steps-card-section.status-good .steps-card-pct {
  color: #3F7A4E;
}

.steps-card-section.status-good .steps-card-check {
  display: inline-flex;
}

@media (max-width: 480px) {
  .steps-card-count {
    font-size: 1.5rem;
  }
}

/* ── Upcoming Reminder (dashboard) ── */
.upcoming-reminder-card {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  background: var(--gray-bg);
  border: 1.5px solid var(--border);
  border-radius: 12px;
  padding: 0.85rem 1rem;
}

.upcoming-reminder-icon {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--plum-light);
  color: var(--plum);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
}

.upcoming-reminder-body {
  flex: 1;
  min-width: 0;
}

.upcoming-reminder-label {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1.3;
}

.upcoming-reminder-title {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.1rem;
}

.upcoming-reminder-when {
  flex-shrink: 0;
  text-align: right;
}

.upcoming-reminder-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--plum);
  line-height: 1.2;
}

.upcoming-reminder-day {
  font-size: 0.68rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Quick Add CSS */
.afp-accordion .accordion-item {
  border: 1.5px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

.afp-accordion .accordion-button {
  background: #fff;
  box-shadow: none;
  font-weight: 500;
  padding: 0.55rem 0.85rem;
  font-size: 14px;
}

.afp-accordion .accordion-button:not(.collapsed) {
  background: #fff7f5;
  color: #ff6b57;
}

.afp-accordion .accordion-button:focus {
  box-shadow: none;
}

.afp-accordion .accordion-body {
  padding: 1rem;
}

.afp-accordion .accordion-button::after {
  transition: transform .2s ease;
}


/* ── Floating Quick-add Water button + popup (log.php) ── */
.water-fab {
  position: fixed;
  bottom: calc(5.5rem + env(safe-area-inset-bottom));
  right: 1.5rem;
  z-index: 500;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-grad);
  color: #fff;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.water-fab i {
  font-size: 1.6rem;
}

.water-fab:hover,
.water-fab:focus {
  transform: translateY(-2px) scale(1.03);
  box-shadow: var(--shadow);
}

.water-fab:active {
  transform: scale(0.96);
}

@media (max-width: 575.98px) {
  .water-fab {
    bottom: calc(5rem + env(safe-area-inset-bottom));
    right: 1.1rem;
    width: 56px;
    height: 56px;
  }

  .water-fab i {
    font-size: 1.45rem;
  }
}

.water-popup-overlay {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(42, 26, 53, 0.45);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.water-popup-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.water-popup {
  position: relative;
  background: var(--white);
  border-radius: 18px;
  padding: 1.75rem 1.5rem 1.5rem;
  width: 100%;
  max-width: 320px;
  text-align: center;
  box-shadow: var(--shadow);
  transform: translateY(16px) scale(0.97);
  transition: transform 0.2s ease;
}

.water-popup-overlay.open .water-popup {
  transform: translateY(0) scale(1);
}

.water-popup-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 30px;
  height: 30px;
  border: none;
  background: var(--gray-bg);
  color: var(--text-muted);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
}

.water-popup-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 0.75rem;
  border-radius: 50%;
  background: var(--accent-pale);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
}

.water-popup-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--plum);
  margin-bottom: 0.35rem;
}

.water-popup-sub {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 1.25rem;
}

.water-popup-actions {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
}

.water-popup-actions .btn {
  flex: 1;
}

/* ── Discover Food: API usage badge ── */
.api-usage-badge {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  border-radius: 99px;
  background: var(--accent-pale);
  color: var(--accent);
  font-weight: 600;
  font-size: 0.85rem;
  font-family: 'JetBrains Mono', monospace;
  flex-shrink: 0;
}

.api-usage-badge.at-limit {
  background: rgba(224, 112, 106, 0.15);
  color: var(--coral);
}

.api-usage-badge.api-usage-total {
  background: var(--gray-bg);
  color: var(--text-muted);
  font-weight: 600;
}

.topbar-usage-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.6rem 1.5rem;
  overflow-x: auto;
  background: rgba(255, 255, 255, 0.6);
  border-bottom: 1px solid var(--border);
}

/* Wraps the topbar + usage bar on Discover so they scroll together as one
   pinned unit instead of the usage bar scrolling away independently. The
   inner .topbar drops its own sticky positioning since the wrapper now
   handles it. */
.discover-sticky-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

.discover-sticky-header .topbar {
  position: static;
}

.topbar-usage-bar .api-usage-badge {
  flex-shrink: 0;
}

@media (max-width: 575.98px) {
  .topbar-usage-bar {
    padding: 0.5rem 1rem;
  }

  .topbar-heading-text .topbar-date {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
  }

  .topbar-usage-bar .api-usage-badge {
    padding: 0.4rem 0.65rem;
    font-size: 0.75rem;
    gap: 0.3rem;
  }
}

.discover-card .fdc-macros {
  flex-wrap: wrap;
}

.scan-ai-note {
  font-size: 0.7rem;
  color: var(--accent);
  margin-top: 0.25rem;
  font-weight: 600;
}

.scan-ai-disclaimer {
  font-size: 0.75rem;
  color: var(--text-muted);
  background: var(--accent-pale);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
}

/* ── Vitals: Activity comparison card (steps + calories + distance) ──
   One row per metric: icon, label + value, 7-day sparkline, delta badge
   vs. yesterday. Replaces the old separate Today's/Yesterday's cards. */
.vitals-activity-card {
  display: flex;
  flex-direction: column;
}

.vitals-today-synced {
  font-size: 0.7rem;
  color: var(--text-muted);
  background: var(--gray-bg);
  padding: 0.25rem 0.6rem;
  border-radius: 99px;
  white-space: nowrap;
  flex-shrink: 0;
}

.vitals-activity-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.65rem 0;
}

.vitals-activity-row-divider {
  border-top: 1px solid var(--border);
}

.vitals-activity-main {
  flex: 1;
  min-width: 0;
}

.vitals-activity-spark {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 28px;
  flex-shrink: 0;
}

.vitals-spark-bar {
  width: 6px;
  background: rgba(61, 32, 80, 0.12);
  border-radius: 2px;
}

.vitals-spark-bar.active.plum {
  background: var(--plum-surface);
}

.vitals-spark-bar.active.coral {
  background: var(--coral);
}

.vitals-spark-bar.active.yellow {
  background: var(--gold-deep);
}

.vitals-spark-bar.active.mauve {
  background: var(--mauve);
}

.vitals-activity-delta {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.2rem 0.55rem;
  border-radius: 99px;
  white-space: nowrap;
  min-width: 3.2rem;
  text-align: center;
  flex-shrink: 0;
}

.vitals-activity-delta.up {
  color: #3B6D11;
  background: #EAF3DE;
}

.vitals-activity-delta.down {
  color: #993C1D;
  background: #FAECE7;
}

.vitals-activity-delta-empty {
  color: var(--text-muted);
  background: var(--gray-bg);
}

.vts-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  flex-shrink: 0;
}

.vts-icon.plum {
  background: rgba(61, 32, 80, 0.1);
  color: var(--plum);
}

.vts-icon.coral {
  background: rgba(224, 112, 106, 0.14);
  color: var(--coral);
}

.vts-icon.yellow {
  background: rgba(240, 220, 130, 0.35);
  color: var(--gold-deep);
}

.vts-icon.mauve {
  background: rgba(160, 104, 138, 0.14);
  color: var(--mauve);
}

.vts-val {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--plum);
  line-height: 1.2;
  white-space: nowrap;
}

.vts-val-empty {
  color: var(--text-muted);
  font-weight: 400;
}

.vts-val .stat-unit {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-left: 0.15rem;
}

.vts-label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  margin-bottom: 0.1rem;
}

@media (max-width: 380px) {
  .vts-icon {
    width: 34px;
    height: 34px;
    font-size: 0.95rem;
  }

  .vts-val {
    font-size: 1rem;
  }

  .vts-label {
    font-size: 0.6rem;
  }

  .vitals-activity-spark {
    display: none;
  }
}

/* ── First-Load Splash Screen ── */
.first-load-overlay {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  background: var(--gray-bg);
  transition: opacity 0.4s ease;
}

.first-load-overlay.fade-out {
  opacity: 0;
  pointer-events: none;
}

.first-load-logo {
  width: 96px;
  height: 96px;
  border-radius: 22px;
  object-fit: contain;
  box-shadow: var(--shadow);
  animation: flo-pop 0.5s ease;
}

.first-load-brand {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--plum);
  letter-spacing: 0.02em;
}

.first-load-spinner {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 3px solid var(--accent-pale);
  border-top-color: var(--accent);
  animation: flo-spin 0.8s linear infinite;
}

@keyframes flo-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes flo-pop {
  from {
    transform: scale(0.85);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* ── AI Insights ── */
/* Uniform cards — no accent side-stripe (kept "monotonous" per request). */
.insight-card,
.insight-latest {
  border: 1px solid var(--border);
}

.badge-new {
  display: inline-block;
  background: var(--brand-grad);
  color: #fff;
  border-radius: 99px;
  padding: 0.1rem 0.55rem;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.03em;
}

.insight-summary {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text);
}

.insight-summary p {
  margin: 0 0 1rem 0;
}

.insight-summary p:last-child {
  margin-bottom: 0;
}