/* ═══════════════════════════════════════════════════
   WHAYLE — BRUTALIST SPORT v5
   Black · White · Signal Orange · Scoreboard typography
═══════════════════════════════════════════════════ */
:root{
  /* Backgrounds — true black, no undertone */
  --bg:#0A0A0A;--bg2:#111111;
  --surface:#141414;

  /* BRUTALIST — white is the primary identity signal, orange is heat */
  --whale:#FFFFFF;--whale-2:#E0E0E0;--whale-ink:#000000;

  /* HEAT accent — orange, reserved for the LOG action and alerts */
  --accent:#FF3B1F;--accent-2:#E62E10;--accent-ink:#000000;

  /* Backward-compat shims — most signals resolve to whale-blue, effort moments stay orange */
  --lime:var(--whale);--lime2:var(--whale-2);--lime3:rgba(255,255,255,0.10);
  --cyan:var(--text2);--coral:var(--accent);--amber:var(--accent);--purple:#FFFFFF;--blue:var(--whale);
  --teal:var(--whale);--teal3:rgba(255,255,255,0.10);
  --navy:var(--bg);

  /* Text — hard contrast */
  --text:#FFFFFF;--text2:#999999;--text3:#555555;

  /* Surfaces — flat, no transparency */
  --glass:#141414;--glass2:#1A1A1A;--glass3:#222222;

  /* Borders — visible, structural */
  --border:#1F1F1F;--border2:#2A2A2A;
  --line:#1F1F1F;--line2:#2A2A2A;

  /* Shape — sharp edges */
  --radius:4px;--radius-sm:2px;

  /* ─── MOTION DESIGN TOKENS ─── */
  /* Strong custom curves — built-in `ease` is weak and lacks intent.
     Following Emil Kowalski's principle: ease-out for UI (starts fast,
     feels responsive). Never use ease-in for UI — it delays the
     initial movement, exactly when the user is watching most closely. */
  --ease-out:        cubic-bezier(0.23, 1, 0.32, 1);     /* hover, button release, list reveal */
  --ease-in-out:     cubic-bezier(0.77, 0, 0.175, 1);    /* mid-screen movement, morph */
  --ease-drawer:     cubic-bezier(0.32, 0.72, 0, 1);     /* iOS-style drawer / sheet slide */
  --ease-spring:     cubic-bezier(0.34, 1.56, 0.64, 1);  /* gentle overshoot for delight moments */
  --ease-snap:       cubic-bezier(0.4, 0, 0.2, 1);       /* material-style smooth */

  /* Standard durations — keep UI under 300ms (Emil's rule).
     Shorter = faster perceived performance. */
  --dur-instant:  60ms;   /* button press feedback peak */
  --dur-fast:    160ms;   /* button press total, tooltip, micro-feedback */
  --dur-base:    220ms;   /* hover, color, generic UI transition */
  --dur-slow:    320ms;   /* sheet open, modal entry, page transition */
  --dur-drawer:  420ms;   /* full-screen sheet (asymmetric — exit ~280ms) */
}

/* ─── BRUTALIST OVERRIDE — kills inline gradients globally ─── */
.pod-card,.rank-banner,#auth-invite-banner,
.food-hero,.food-log-card,.food-item-premium,.food-card-premium,.ai-search-card{
  background-image:none!important;
}

/* ─── RESET ─── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;height:100%}
body{
  font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;
  background:var(--bg);color:var(--text);
  min-height:100vh;overflow-x:hidden;overflow-y:auto;
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}
button,a,input,select,textarea{-webkit-tap-highlight-color:transparent;outline:none}
button:focus,button:focus-visible{outline:none;box-shadow:none}

/* ─── BACKGROUND — flat black ─── */
body::before{display:none}
.grain{display:none}

/* ─── LAYOUT ─── */
.app{position:relative;z-index:1}
.page{display:none}.page.active{display:block}
.wrap{max-width:1020px;margin:0 auto;padding:0 20px 110px}

/* ─── ANIMATIONS ─── */
@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes slideUpSheet{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}
@keyframes scaleIn{from{opacity:0;transform:scale(0.96)}to{opacity:1;transform:scale(1)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.35}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
@keyframes staggerIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.anim-up{animation:fadeUp var(--dur-slow) var(--ease-out) both}
.anim-in{animation:fadeIn var(--dur-base) var(--ease-out) both}
.delay-1{animation-delay:60ms}.delay-2{animation-delay:120ms}.delay-3{animation-delay:180ms}.delay-4{animation-delay:240ms}

/* ─── REDUCED MOTION GUARD ─── */
/* Respects user's OS-level motion preference (iOS Settings → Accessibility →
   Motion → Reduce Motion). Applied broadly — strips animation and shrinks
   transition durations to ~10ms so things still feel instant rather than dead. */
@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after{
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* ─── TYPOGRAPHY — Bebas display, Inter body, JetBrains for numbers ─── */
.display{font-family:'Bebas Neue','Inter',sans-serif;font-weight:400;line-height:0.92;letter-spacing:0.01em;text-transform:uppercase}
.heading{font-family:'Inter',sans-serif;font-weight:800;letter-spacing:-0.01em;text-transform:uppercase;font-size:13px}
.label{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:1.4px;text-transform:uppercase;color:var(--text2)}

/* ─── CARDS — Apple Health × Whayle: soft elevation, calm surface ─── */
.card{
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.05);
  border-radius:18px;
  padding:22px;
  box-shadow:
    0 2px 16px rgba(0,0,0,0.22),
    inset 0 1px 0 rgba(255,255,255,0.04);
  transition:border-color var(--dur-base) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             transform var(--dur-base) var(--ease-out);
  position:relative;overflow:hidden;
}
.card::before{display:none}
.card:hover{
  border-color:rgba(255,255,255,0.10);
}
.glass{
  background:var(--surface);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  border:1px solid var(--line);
}

/* ─── BUTTONS — sharp, structural, uppercase ─── */
/* Press feedback model:
   • hover  → subtle background/border shift, --dur-base
   • active → scale(0.97) for haptic-feel response, --dur-instant (60ms)
   The scale press is much more "responsive" than translateY because the
   whole button moves together — your finger feels heard. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:44px;padding:0 20px;
  border-radius:var(--radius);
  font-family:'Inter',sans-serif;font-size:12px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;
  cursor:pointer;
  /* Animate ONLY transform + background + border-color → GPU-friendly,
     leaves layout/paint untouched. transform:scale = compositor-only. */
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
  border:none;text-decoration:none;white-space:nowrap;
  will-change:transform;
}
.btn:active{transform:scale(0.97)}
.btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.btn-primary{
  background:var(--accent);color:var(--accent-ink);
}
.btn-primary:hover{background:var(--accent-2)}
.btn-ghost{
  background:transparent;color:var(--text);
  border:1px solid var(--line2);
}
.btn-ghost:hover{background:var(--surface);border-color:var(--text2)}
.btn-danger{background:transparent;color:var(--accent);border:1px solid var(--accent)}
.btn-danger:hover{background:var(--accent);color:var(--accent-ink)}
.btn-sm{height:36px;padding:0 14px;font-size:11px}
.btn-icon{
  width:40px;height:40px;padding:0;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--line);
  color:var(--text);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
  font-size:14px;
}
.btn-icon:hover{background:var(--glass2);border-color:var(--line2)}
.btn-icon:active{transform:scale(0.94)}
/* .btn-google removed — Google sign-in now uses .btn-ghost so it harmonises
   with the surrounding dark UI. The standard .btn type ramp (12px / 700 /
   uppercase / 1px tracking) reads well on dark for both buttons. */
.btn-full{width:100%}

/* ─── FORM ─── */
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:16px}
.field-label{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;color:var(--text2);letter-spacing:1.4px;text-transform:uppercase}
.field input,.field select,.field textarea{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:0 14px;height:44px;
  font-family:'Inter',sans-serif;font-size:15px;font-weight:500;color:var(--text);
  outline:none;transition:border-color 0.15s;width:100%;
  -webkit-appearance:none;appearance:none;
}
.field textarea{height:auto;padding:14px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--accent);
  background:var(--surface);
}
.field input::placeholder,.field textarea::placeholder{color:var(--text3)}
/* Match readability for non-.field inputs used on Food page */
#food-search::placeholder,#manual-name::placeholder,#manual-cal::placeholder,#manual-prot::placeholder,#manual-carb::placeholder,#manual-fat::placeholder{color:var(--text3);opacity:1}
/* ── Food page — flat brutalist cards ── */
.ai-search-card{position:relative;padding:22px;margin-bottom:16px;border-radius:18px;background:var(--surface);border:1px solid rgba(255,255,255,0.05);box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04)}
.ai-search-card::before{display:none}
.ai-search-head{display:flex;align-items:center;gap:8px;font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:1.4px;color:var(--accent);margin-bottom:14px}
.ai-search-head .dot{width:6px;height:6px;border-radius:0;background:var(--accent);box-shadow:none;animation:pulse-dot 1.6s ease-in-out infinite}
@keyframes pulse-dot{0%,100%{opacity:1}50%{opacity:0.35}}
.food-card-premium{background:var(--surface);border:1px solid rgba(255,255,255,0.05);border-radius:18px;padding:22px;margin-bottom:18px;box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04)}
.field select option{background:var(--bg2);color:var(--text)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:480px){.field-row{grid-template-columns:1fr}}
.field-hint{font-size:11px;color:var(--text3);margin-top:2px}

/* ─── RADIO OPTIONS ─── */
.option-grid{display:flex;flex-direction:column;gap:8px}
.option-card{
  display:flex;align-items:center;gap:12px;
  padding:14px 16px;
  border:1px solid var(--line);border-radius:var(--radius);
  cursor:pointer;transition:border-color 0.15s;
  background:var(--surface);
}
.option-card:hover{border-color:var(--line2);background:var(--surface)}
.option-card.selected{border-color:var(--accent);background:var(--surface)}
.option-card input{display:none}
.option-dot{width:16px;height:16px;border-radius:0;border:2px solid var(--text3);flex-shrink:0;transition:all 0.15s}
.option-card.selected .option-dot{border-color:var(--accent);background:var(--accent);box-shadow:inset 0 0 0 3px var(--bg)}
.option-text strong{display:block;font-size:13px;font-weight:700;color:var(--text);letter-spacing:-0.01em}
.option-text span{font-size:11px;color:var(--text3);margin-top:2px;display:block}

/* ─── DIVIDER ─── */
.divider{display:flex;align-items:center;gap:14px;color:var(--text3);font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:1.4px;text-transform:uppercase;margin:20px 0}
.divider::before,.divider::after{content:'';flex:1;height:1px;background:var(--line)}

/* ─── HEADER ─── */
.header{
  display:flex;align-items:center;justify-content:space-between;
  /* Header self-handles iOS status-bar clearance via env(safe-area-inset-top)
     so the WHAYLE wordmark + avatar never overlap the time/cellular icons.
     Works in BOTH Safari browser mode AND installed PWA — the previous
     setup applied env() to body only inside @media(display-mode:standalone),
     which left browser users (testers who hadn't installed yet) staring at
     a header sitting under the status bar (Aish caught 2026-05-10).
     The body padding-top in the PWA media query has been REMOVED to avoid
     the 60px double-pad bug (May 9 incident); headerless pages
     (#page-onboard, #page-account-setup, #page-auth, .loading-page) carry
     their own explicit env() padding in the standalone block.
     Sheets (.food-sheet-head, #train-sheet .sheet-head) are position:fixed
     and bake their own env() — unaffected. */
  padding:calc(14px + env(safe-area-inset-top)) 20px 14px;
  border-bottom:none;
  position:sticky;top:0;z-index:100;
  background:var(--bg);
  backdrop-filter:none;-webkit-backdrop-filter:none;
}
.header-logo{
  font-family:'Bebas Neue','Inter',sans-serif;font-size:24px;font-weight:400;
  color:var(--text);letter-spacing:0.04em;text-transform:uppercase;
  display:flex;align-items:center;gap:8px;cursor:pointer;
}
.header-logo span{font-size:24px}
.header-right{display:flex;align-items:center;gap:8px}
.header-user{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  padding:2px 4px 2px 0;
  border-radius:999px;
  border:none;
  background:transparent;
  transition:opacity 0.15s;
}
.header-user:hover{opacity:0.78;background:transparent;border:none}
.header-user #header-username{font-size:13px;font-weight:500;color:var(--text2);letter-spacing:0.01em}
.avatar{
  width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:'Bebas Neue','Inter',sans-serif;font-weight:400;font-size:15px;letter-spacing:0.02em;
  flex-shrink:0;background:var(--accent);color:var(--accent-ink);
  overflow:hidden;
}

/* ─── BOTTOM NAV ─── */
.sidebar{display:none}
.dash-layout{display:block}
.bottom-nav{
  position:fixed;bottom:0;left:0;right:0;z-index:100;
  background:var(--bg);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  border-top:1px solid var(--line);
  display:flex;padding:6px 0 env(safe-area-inset-bottom);
  /* GPU compositor layer hints (transform:translateZ + will-change) were
     here to "fix" iOS Safari's mid-scroll fixed-element ghost. On iOS 17+
     they made it worse: a separately-composited layer can decouple from
     the page during momentum scrolls, so the nav rendered in the middle
     of the content for a frame before snapping back. Plain position:fixed
     handles this better in current Safari builds. Re-add only if a fresh
     bug shows up after revert testing. */
}
.bnav-btn{
  flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:8px 4px;cursor:pointer;border:none;
  background:transparent;color:var(--text3);
  font-family:'Inter',sans-serif;
  -webkit-tap-highlight-color:transparent;-webkit-appearance:none;appearance:none;outline:none;
  /* Tab switches happen many times daily — Emil's framework says go
     light on animation here. Color is the tell, not motion. Keep it
     under --dur-fast so taps feel instant. */
  transition:color var(--dur-fast) var(--ease-out),
             transform var(--dur-instant) var(--ease-out);
}
.bnav-btn:focus,.bnav-btn:focus-visible,.bnav-btn:hover{background:transparent;outline:none;box-shadow:none}
.bnav-btn:active{background:transparent;outline:none;box-shadow:none;transform:scale(0.92)}
.bnav-btn.active{color:var(--accent)}
.bnav-icon{font-size:16px;line-height:1;display:block;background:transparent;font-weight:700}
.bnav-label{font-size:9px;font-weight:700;letter-spacing:1.2px;text-transform:uppercase;font-family:'JetBrains Mono',monospace}

/* ─── COLUMN LAYOUT HELPERS (all screen sizes) ─── */
.d-col{display:flex;flex-direction:column;gap:16px}

/* ─── SIDEBAR (desktop) ─── */
@media(min-width:768px){
  .bottom-nav{display:none}
  .dash-layout{display:grid;grid-template-columns:220px 1fr;gap:0;min-height:100vh}
  .sidebar{
    display:block;
    background:var(--bg);
    backdrop-filter:none;-webkit-backdrop-filter:none;
    border-right:1px solid var(--line);
    padding:24px 0;
    position:sticky;top:57px;height:calc(100vh - 57px);overflow-y:auto;
  }
  .sidebar-nav{display:flex;flex-direction:column;gap:3px;padding:0 14px}
  .snav-btn{
    display:flex;align-items:center;gap:12px;
    padding:11px 14px;border-radius:var(--radius);
    cursor:pointer;border:none;background:transparent;
    color:var(--text2);
    font-family:'Inter',sans-serif;font-size:12px;font-weight:700;letter-spacing:0.6px;text-transform:uppercase;
    transition:all 0.15s;width:100%;text-align:left;
    -webkit-tap-highlight-color:transparent;outline:none;
  }
  .snav-btn:focus,.snav-btn:focus-visible{outline:none;box-shadow:none}
  .snav-btn:hover{background:var(--surface);color:var(--text)}
  .snav-btn.active{background:transparent;color:var(--accent);border-left:3px solid var(--accent);padding-left:11px}
  .snav-icon{font-size:16px;width:20px;text-align:center}
  .dash-content{padding:32px 28px 80px}
  /* ─ desktop grid utilities ─ */
  .wrap{max-width:1320px;padding:0 28px 80px}
  .d-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start}
  /* Single-column stack for 768–1023px (sidebar present but not wide enough for 2-col) */
  .dash-home-grid{display:flex;flex-direction:column;gap:16px}
}
/* Dashboard 2-column only when there's room beside the 220px sidebar */
@media(min-width:1100px){
  .dash-home-grid{display:grid;grid-template-columns:1.15fr 1fr;gap:20px;align-items:start}
  #dash-nutrition-card{grid-column:1;grid-row:1}
  #dash-calories-card {grid-column:2;grid-row:1;align-self:stretch}
  #dash-protein-card  {grid-column:2;grid-row:2}
  #dash-recovery-card {grid-column:2;grid-row:3}
  #dash-activity-card {grid-column:2;grid-row:4}
  #dash-pod-rank-card {grid-column:1;grid-row:2/6}
}
@media(max-width:900px){
  /* Activity Today 4-card grid: stack to single column before cards get cramped */
  #section-activity .d-grid-2{display:flex;flex-direction:column;gap:20px}
}
@media(max-width:767px){
  /* Extra bottom room so content never tucks under the fixed bottom nav */
  .dash-content{padding:20px 0 calc(110px + env(safe-area-inset-bottom))}
  .wrap{padding:0 16px calc(110px + env(safe-area-inset-bottom))}
  /* Desktop grids stack to single column on mobile */
  .d-grid-2{display:flex;flex-direction:column;gap:16px}
  /* Dashboard mobile: single column, HTML order is the display order */
  .dash-home-grid{display:flex;flex-direction:column;gap:16px}
  #dash-nutrition-card,#dash-calories-card,#dash-protein-card,
  #dash-recovery-card,#dash-activity-card,#dash-pod-rank-card{
    grid-column:unset;grid-row:unset
  }
  /* Activity tabs scroll on narrow screens */
  .activity-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;width:max-content;max-width:100%}
  .activity-tabs .tab{flex:none;white-space:nowrap}
}

/* ─── SECTION ─── */
.section-header{margin:10px 0 28px}
.section-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:30px;font-weight:400;margin-bottom:6px;letter-spacing:0.01em;line-height:1}
.section-sub{font-size:13px;color:var(--text2);font-weight:400;letter-spacing:0.01em}

/* ─── RING ─── */
.ring-wrap{display:flex;align-items:center;gap:24px}
.ring-info{flex:1}
.macro-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-size:12px}
.macro-name{width:54px;color:var(--text2);font-weight:500}
.macro-track{flex:1;height:4px;background:rgba(255,255,255,0.07);border-radius:2px;overflow:hidden}
.macro-fill{height:100%;border-radius:2px;transition:width 0.7s cubic-bezier(0.22,1,0.36,1)}
.macro-val{width:48px;text-align:right;font-weight:600;font-size:11px;color:var(--text2)}

/* ─── PROGRESS ─── */
.progress-track{height:6px;background:rgba(255,255,255,0.07);border-radius:3px;overflow:hidden;margin:8px 0}
.progress-fill{height:100%;border-radius:3px;transition:width 0.7s cubic-bezier(0.22,1,0.36,1)}

/* ─── FOOD ─── */
.food-input-area{
  background:var(--surface);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  border:1px solid var(--line);border-radius:var(--radius);
  padding:18px;margin-bottom:12px;
  position:relative;overflow:hidden;
}
.food-input-area::before{display:none}
.food-search-row{display:grid;grid-template-columns:1fr auto;gap:10px;margin-bottom:12px}
.food-list{display:flex;flex-direction:column;gap:6px}

/* ─── FOOD HERO — APPLE HEALTH × WHAYLE TEST SURFACE ───
   Apple Health iOS 17/18 surface treatment carried over selectively:
   • Soft 18px corners (not pure brutalist 0, not iOS 22px max — middle ground)
   • Surface elevated against bg with subtle outer shadow + inset highlight
     (Apple Health cards float gently — depth without garish drop shadow)
   • Generous padding 28px (was 24)
   • Removed the orange top-border "active panel" bar (felt loud); category
     identity now carried by the small orange remaining-kcal pill below ring
   • Macro bars: 3px → 6px tall, rounded fully (Apple Health treatment),
     subtle category color variation (PROT warm, CARB amber, FAT cream)
   • Macro labels: monospace stays for "data feel" but lighter weight (500),
     slightly less aggressive tracking
   • Calorie ring stroke: 4px → 5px (chunkier, friendlier, like Apple's
     activity rings — but still single color, no rainbow gradient)
   Whayle identity preserved: Bebas Neue display "INTAKE" header, orange heat,
   monospace data-side labels, dark substrate. */
.food-hero{
  position:relative;overflow:hidden;
  padding:28px 24px;margin-bottom:20px;
  border-radius:18px;
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.05);
  box-shadow:
    0 2px 16px rgba(0,0,0,0.25),
    inset 0 1px 0 rgba(255,255,255,0.04);
}
.food-hero::before{display:none}
.food-hero-top{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:22px;gap:12px;position:relative}
.food-hero-eyebrow{
  display:flex;align-items:center;gap:8px;
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;
  text-transform:uppercase;letter-spacing:1.4px;color:var(--text2);margin-bottom:10px;
}
.food-hero-eyebrow .dot{
  width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px rgba(255,59,31,0.18);
  animation:pulse-dot 1.6s ease-in-out infinite;
}
/* Title pulled back from 52px → 32px — Apple Health treats screen labels
   as section headers, not display-massive. The calorie number is the data
   anchor; the title is just the chapter mark. Bebas Neue stays (Whayle
   identity), but at this size it reads refined instead of shouting. */
.food-hero-title{
  font-family:'Bebas Neue','Inter',sans-serif;font-weight:400;font-size:32px;
  letter-spacing:0.02em;line-height:1;margin-bottom:6px;text-transform:uppercase;
}
.food-hero-date{
  font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text3);
  font-weight:500;letter-spacing:1px;text-transform:uppercase;
}
.food-hero-body{display:grid;grid-template-columns:auto 1fr;gap:28px;align-items:center;position:relative}
@media(max-width:480px){.food-hero-body{grid-template-columns:1fr;gap:24px}}
.food-ring-wrap{position:relative;width:152px;height:152px;flex-shrink:0;justify-self:center}
.food-ring-wrap svg{width:100%;height:100%;transform:rotate(-90deg)}
.food-ring-track{stroke:rgba(255,255,255,0.06);stroke-width:5;fill:none}
.food-ring-fill{
  stroke:var(--whale);stroke-width:5;fill:none;stroke-linecap:round;
  stroke-dasharray:276.46;stroke-dashoffset:276.46;filter:none;
  transition:stroke-dashoffset 0.8s cubic-bezier(0.22,1,0.36,1),stroke 0.3s;
}
.food-ring-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
.food-ring-num{
  font-family:'Bebas Neue','Inter',sans-serif;font-size:48px;font-weight:400;
  line-height:0.9;color:var(--text);letter-spacing:0.01em;
  font-variant-numeric:tabular-nums;
}
.food-ring-label{
  font-family:'JetBrains Mono',monospace;font-size:9px;text-transform:uppercase;
  letter-spacing:1.4px;color:var(--text3);margin-top:6px;font-weight:500;
}
/* Remaining-kcal pill — Apple Health-style soft accent chip */
.food-ring-rem{
  display:inline-block;
  font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--accent);
  font-weight:600;margin-top:8px;letter-spacing:0.4px;text-transform:uppercase;
  white-space:nowrap;max-width:120px;
  background:rgba(255,59,31,0.08);
  padding:3px 10px;border-radius:999px;
}
.food-macros-grid{display:flex;flex-direction:column;gap:14px;width:100%;min-width:0}
.food-macro-row{display:flex;align-items:center;gap:12px}
.food-macro-dot{display:none}
.food-macro-name{
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;
  color:var(--text2);letter-spacing:1.2px;text-transform:uppercase;
  width:42px;flex-shrink:0;
}
/* Macro bars — softer, taller, fully rounded (Apple Health treatment) */
.food-macro-track{
  flex:1;height:6px;background:rgba(255,255,255,0.06);
  border-radius:999px;overflow:hidden;min-width:0;
}
.food-macro-fill{
  height:100%;border-radius:999px;
  transition:width 0.7s cubic-bezier(0.22,1,0.36,1);
  background:var(--text)!important;
}
.food-macro-val{
  font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:600;
  color:var(--text);white-space:nowrap;flex-shrink:0;min-width:78px;
  text-align:right;letter-spacing:0.3px;font-variant-numeric:tabular-nums;
}
.food-macro-val .unit{color:var(--text3);font-size:9px;font-weight:500;margin-left:2px}

/* ─── WELLNESS HERO — Apple Health × Whayle treatment ───
   Same surface treatment as food-hero: 18px corners, soft elevation,
   gentle shadow + inset highlight. Title 44px → 32px (calm). Tile bars
   become rounded pills. Removed accent top border (felt loud). */
.wellness-hero{
  position:relative;padding:28px 24px;margin-bottom:20px;
  border-radius:18px;
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.05);
  box-shadow:
    0 2px 16px rgba(0,0,0,0.25),
    inset 0 1px 0 rgba(255,255,255,0.04);
}
.wellness-hero-head{margin-bottom:20px}
.wellness-hero-eyebrow{
  display:flex;align-items:center;gap:8px;
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;
  text-transform:uppercase;letter-spacing:1.4px;color:var(--text2);margin-bottom:10px;
}
.wellness-hero-eyebrow .dot{
  width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px rgba(255,59,31,0.18);
  animation:pulse-dot 1.6s ease-in-out infinite;
}
.wellness-hero-title{
  font-family:'Bebas Neue','Inter',sans-serif;font-weight:400;font-size:32px;
  letter-spacing:0.02em;line-height:1;margin-bottom:6px;text-transform:uppercase;color:var(--text);
}
.wellness-hero-date{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text3);font-weight:500;letter-spacing:1px;text-transform:uppercase}
.wellness-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:560px){.wellness-tiles{grid-template-columns:repeat(2,1fr);gap:10px}}
/* Tile — softer corners (12px), tinted surface, hover/active feedback */
.wellness-tile{
  position:relative;padding:16px 14px 14px;
  border:1px solid rgba(255,255,255,0.05);
  border-radius:12px;
  background:rgba(255,255,255,0.025);
  display:flex;flex-direction:column;gap:5px;min-width:0;
  transition:transform 0.08s ease,background 0.2s,border-color 0.2s;
  cursor:pointer;
}
.wellness-tile:hover{border-color:rgba(255,255,255,0.10);background:rgba(255,255,255,0.04)}
.wellness-tile:active{transform:scale(0.98)}
.wellness-tile-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:2px}
.wellness-tile-name{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:1.2px;color:var(--text2)}
.wellness-tile-unit{font-family:'JetBrains Mono',monospace;font-size:8px;font-weight:500;text-transform:uppercase;letter-spacing:1px;color:var(--text3)}
.wellness-tile-stat{font-family:'Bebas Neue','Inter',sans-serif;font-size:30px;font-weight:400;line-height:0.95;color:var(--text);letter-spacing:0.01em;font-variant-numeric:tabular-nums}
.wellness-tile-goal{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);font-weight:500;letter-spacing:0.4px;margin-top:3px}
/* Bar 2px → 4px tall, rounded pill (matches food macro bars) */
.wellness-tile-bar{height:4px;background:rgba(255,255,255,0.06);border-radius:999px;overflow:hidden;margin-top:10px}
.wellness-tile-fill{height:100%;background:var(--text);width:0%;border-radius:999px;transition:width 0.7s cubic-bezier(0.22,1,0.36,1)}
/* Burnt tile — soft orange tint instead of hard top border */
.wellness-tile.wellness-tile-accent{background:rgba(255,59,31,0.05);border-color:rgba(255,59,31,0.15)}
.wellness-tile.wellness-tile-accent .wellness-tile-fill{background:var(--accent)}
.wellness-tile.wellness-tile-accent .wellness-tile-name{color:var(--accent)}

/* ─── FOOD LOG LIST ─── */
.food-log-card{
  position:relative;padding:18px;margin-bottom:16px;
  border-radius:var(--radius);
  background:var(--surface);
  border:1px solid var(--line);
  box-shadow:none;
}
.food-log-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.food-log-eyebrow{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:1.4px;color:var(--text2)}
.food-log-count{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text);font-weight:600;letter-spacing:0.3px}

/* ── YESTERDAY totals row ──
   4-up grid sitting between the head row and the items list. Each cell
   is one macro: KCAL · PROT · CARB · FAT. Brutalist styling — flat,
   bold numbers in Bebas, mono label below. Matches the Train tab's
   sessions-stat grid in feel so the two surfaces stay related. */
.food-yesterday-totals{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:8px;
  margin-bottom:14px;
}
.fy-stat{
  background:rgba(255,255,255,0.03);
  border:1px solid rgba(255,255,255,0.06);
  border-radius:12px;
  padding:12px 10px;
  text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:4px;
}
.fy-stat-num{
  font-family:'Bebas Neue','Inter',sans-serif;
  font-size:24px;line-height:1;letter-spacing:0.02em;
  color:var(--text);
}
.fy-stat-lbl{
  font-family:'JetBrains Mono',monospace;
  font-size:9px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--text3);font-weight:600;
}
.food-item-premium{
  display:flex;align-items:center;gap:12px;
  padding:14px 16px;
  background:rgba(255,255,255,0.03);
  border:1px solid rgba(255,255,255,0.06);
  border-radius:14px;
  transition:background 0.15s ease,border-color 0.15s ease;
  animation:fadeUp 0.2s ease;
  position:relative;overflow:hidden;
}
.food-item-premium:hover{background:rgba(255,255,255,0.05);border-color:rgba(255,255,255,0.10);transform:none}
.food-item-premium::before{display:none}
.food-item-info{flex:1;min-width:0}
.food-item-name{font-family:'Inter',sans-serif;font-size:14px;font-weight:700;color:var(--text);margin-bottom:4px;letter-spacing:-0.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:none}
.food-item-meta{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.food-pill{
  display:inline-flex;align-items:center;gap:3px;
  padding:0;
  font-family:'JetBrains Mono',monospace;
  font-size:10px;font-weight:500;
  background:transparent;border:none;
  color:var(--text3);letter-spacing:0.4px;
}
.food-pill.p,.food-pill.c,.food-pill.f{background:transparent;border:none;color:var(--text2)}
.food-pill.t{color:var(--text3);background:transparent;border:none;padding:0}
.food-item-cal{display:flex;flex-direction:column;align-items:flex-end;flex-shrink:0;gap:0}
.food-item-cal-num{font-family:'Bebas Neue','Inter',sans-serif;font-size:24px;font-weight:400;color:var(--text);line-height:1;letter-spacing:0.02em;font-variant-numeric:tabular-nums}
.food-item-cal-unit{font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--text3);font-weight:500;text-transform:uppercase;letter-spacing:1.2px}
.food-item-remove{
  background:transparent;border:1px solid var(--line);
  color:var(--text3);cursor:pointer;padding:0;font-size:12px;
  width:26px;height:26px;border-radius:var(--radius);flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  transition:all 0.15s;
}
.food-item-remove:hover{background:transparent;border-color:var(--accent);color:var(--accent)}
.food-empty-premium{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  padding:32px 20px;
  border-radius:var(--radius);
  background:transparent;
  border:1px dashed var(--line2);
}
.food-empty-title{font-family:'Inter',sans-serif;font-size:13px;font-weight:800;color:var(--text);margin-bottom:4px;letter-spacing:1px;text-transform:uppercase}
.food-empty-text{font-size:12px;color:var(--text2);max-width:240px;line-height:1.5}

/* ─── FOOD SEARCH FLOW (cuisine / dish / portion) ─── */
/* All three pill/btn variants share a press model:
   • hover: subtle border/color shift, --dur-base
   • active: scale(0.96-0.98), --dur-instant
   The :active state was inconsistent — translateY on cuisine-btn,
   scale on dish-btn, nothing on serving-pill. Now they all snap
   together so the food flow feels rhythmic. */
.serving-pill{
  padding:8px 14px;border-radius:999px;font-size:12px;font-weight:700;
  background:rgba(255,255,255,0.04);
  border:1px solid rgba(255,255,255,0.08);
  color:var(--text2);cursor:pointer;font-family:'Inter',sans-serif;
  letter-spacing:0.4px;text-transform:uppercase;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
}
.serving-pill:hover{background:rgba(255,255,255,0.07);color:var(--text);border-color:rgba(255,255,255,0.12)}
.serving-pill:active{transform:scale(0.96)}
.serving-pill.active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);box-shadow:none}
/* Snap-label serving dropdown menu — used by the LOG FOOD label flow.
   Each row is a flex row with multiplier label + gram weight on the right.
   .selected highlights the option matching the current grams in the input. */
.snap-label-serving-opt{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;padding:10px 12px;border-radius:10px;
  background:transparent;border:none;cursor:pointer;
  font-family:'Inter',sans-serif;font-size:14px;font-weight:600;
  color:var(--text);text-align:left;
  transition:background var(--dur-instant) var(--ease-out);
}
.snap-label-serving-opt:hover{background:rgba(255,255,255,0.05)}
.snap-label-serving-opt.selected{background:rgba(255,59,31,0.12);color:var(--accent)}
.snap-label-serving-opt .snap-label-serving-grams{
  font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:500;
  color:var(--text3);letter-spacing:0.4px;
}
.snap-label-serving-opt.selected .snap-label-serving-grams{color:var(--accent);opacity:0.8}
.cuisine-btn{
  padding:10px 16px;border-radius:999px;font-size:12px;font-weight:700;letter-spacing:0.6px;text-transform:uppercase;
  background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);
  color:var(--text2);cursor:pointer;font-family:'Inter',sans-serif;
  display:flex;align-items:center;gap:6px;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
}
.cuisine-btn:hover{background:rgba(255,255,255,0.07);border-color:rgba(255,255,255,0.12);color:var(--text)}
.cuisine-btn:active{transform:scale(0.97)}
.dish-btn{
  padding:14px 16px;border-radius:14px;font-size:13px;font-weight:600;
  background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);
  color:var(--text);cursor:pointer;text-align:left;
  font-family:'Inter',sans-serif;display:flex;justify-content:space-between;align-items:center;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out);
}
.dish-btn:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.10)}
.dish-btn:active{transform:scale(0.98)}
.dish-btn .dish-hint{font-size:11px;color:var(--text3);font-weight:400}
/* A "logged before" search row — a food resurfaced from your history because
   you've logged it before. Slightly brighter than a plain dish-btn so it
   reads as pinned, but deliberately NOT accent-coloured: resurfacing is a
   convenience, not a "heat" moment. Tapping it pre-fills the portion builder. */
.dish-btn-logged{
  background:rgba(255,255,255,0.06);
  border-color:rgba(255,255,255,0.13);
}
.dish-btn-logged:hover{background:rgba(255,255,255,0.09);border-color:rgba(255,255,255,0.18)}
.dish-logged-main{display:flex;flex-direction:column;gap:3px;min-width:0}
.dish-logged-tag{
  font-size:9px;font-weight:700;letter-spacing:0.7px;text-transform:uppercase;
  color:var(--text3);
}
/* "Show more options" button at the end of the dish list. Visually
   distinct from real dish rows — dashed border, centered, accent text —
   so it reads as an action affordance, not another result. Clicking
   asks the AI for additional dishes that aren't already shown. */
.dish-more-btn{
  padding:13px 16px;border-radius:14px;font-size:12px;font-weight:600;
  background:transparent;border:1px dashed rgba(255,255,255,0.14);
  color:var(--text2);cursor:pointer;text-align:center;
  font-family:'Inter',sans-serif;letter-spacing:0.4px;
  display:flex;justify-content:center;align-items:center;gap:6px;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
}
.dish-more-btn:hover{background:rgba(255,255,255,0.04);border-color:rgba(255,255,255,0.22);color:var(--text)}
.dish-more-btn:active{transform:scale(0.98)}
.dish-more-btn:disabled{opacity:0.5;cursor:wait}

/* ─── Loading skeletons + thinking dots (food picker) ─── */
/* Skeleton dish cards mimic the size/shape of real .dish-btn rows so the
   layout doesn't jump when results arrive. Subtle shimmer keeps the user
   confident the app is working — fixes the "looks like it hung" perception
   when AI proxy takes 3-8s to respond. */
.dish-skeleton{
  height:46px;border-radius:var(--radius);background:var(--surface);
  border:1px solid var(--line);position:relative;overflow:hidden;
  opacity:0.85;
}
.dish-skeleton::before{
  content:'';position:absolute;inset:0;
  background:linear-gradient(90deg,
    transparent 0%,
    rgba(255,255,255,0.06) 50%,
    transparent 100%);
  transform:translateX(-100%);
  animation:shimmer 1.4s ease-in-out infinite;
}
.dish-skeleton:nth-child(2)::before{animation-delay:0.18s}
.dish-skeleton:nth-child(3)::before{animation-delay:0.36s}
.dish-skeleton:nth-child(4)::before{animation-delay:0.54s}
@keyframes shimmer{
  0%{transform:translateX(-100%)}
  100%{transform:translateX(100%)}
}
/* Three-dot bouncing "thinking" indicator. Used next to a status label
   ("Analyzing photo", "Searching dishes") to make it obvious work is
   in flight. */
.thinking-dots{display:inline-flex;gap:4px;align-items:center;vertical-align:middle;margin-left:6px}
.thinking-dots span{
  width:5px;height:5px;border-radius:50%;background:var(--accent);
  animation:thinkBounce 1.05s ease-in-out infinite both;
}
.thinking-dots span:nth-child(2){animation-delay:0.16s}
.thinking-dots span:nth-child(3){animation-delay:0.32s}
@keyframes thinkBounce{
  0%,80%,100%{transform:translateY(0);opacity:0.35}
  40%{transform:translateY(-4px);opacity:1}
}

/* ─── SIGNATURE: LOG button + food sheet ─── */
/* The most important button in the app — the daily ritual entry point.
   Press feel uses a deeper scale (0.98 × bigger surface = same perceived
   movement). Hover lifts subtly to invite the tap. */
.food-log-cta{
  width:100%;display:flex;align-items:center;justify-content:space-between;
  padding:28px 24px;margin-bottom:16px;
  background:var(--accent);color:var(--accent-ink);
  border:none;border-radius:var(--radius);cursor:pointer;
  font-family:'Bebas Neue','Inter',sans-serif;text-align:left;
  transition:transform var(--dur-fast) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out);
  position:relative;overflow:hidden;
  box-shadow:0 4px 0 rgba(0,0,0,0.15);
  will-change:transform;
}
.food-log-cta:hover{background:var(--accent-2);transform:translateY(-1px);box-shadow:0 6px 0 rgba(0,0,0,0.18)}
.food-log-cta:active{transform:translateY(2px) scale(0.995);box-shadow:0 1px 0 rgba(0,0,0,0.15);transition-duration:var(--dur-instant)}
.food-log-cta-label{font-size:64px;line-height:0.85;letter-spacing:0.02em;font-weight:400}
.food-log-cta-sub{position:absolute;left:24px;bottom:18px;font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:1.6px;text-transform:uppercase;color:var(--accent-ink);opacity:0.72}
.food-log-cta-plus{font-family:'Inter',sans-serif;font-size:56px;font-weight:300;line-height:1;color:var(--accent-ink)}
@media(max-width:480px){
  .food-log-cta{padding:24px 20px}
  .food-log-cta-label{font-size:54px}
  .food-log-cta-plus{font-size:44px}
}

.food-sheet{
  /* Full-viewport OPAQUE modal that starts BELOW the WHAYLE banner so
     the app identity stays visible. `top` is set dynamically from JS to
     match the real header height (accounts for safe-area insets, font
     rendering, etc.). The sheet IS the scroll container so the sticky
     sheet-head with the × is always the topmost visible in-sheet chrome.
     Animation: slide-up + fade with iOS-style drawer curve — feels native
     mobile rather than the old flat opacity-only fade. */
  position:fixed;top:0;left:0;right:0;bottom:0;z-index:1500;display:none;
  background:var(--bg);
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  animation:slideUpSheet var(--dur-drawer) var(--ease-drawer) both;
}
.food-sheet.open{display:block}
/* Hide the WHAYLE banner whenever ANY sheet is open. The sheet sits at
   top:0 (full viewport height down to bottom-nav). The banner is
   position:sticky with z-index:100 — it forms its OWN stacking context,
   so even though the sheet is z-index:1500 the banner can render on top
   of it (Aish reported this: WHAYLE banner overlapping the LOG FOOD
   title). visibility:hidden keeps the banner's layout slot in the body
   so we don't get a scroll-position shift, but removes the visual layer
   so the sheet is the topmost thing on screen. The bottom-nav stays
   visible (sheet's bottom edge is set above it) so users can still
   switch tabs without an extra close click. */
/* When any sheet is open, take the page header fully out of the layout.
   Was visibility:hidden — but iOS Safari has a known compositor bug where
   visibility:hidden text glyphs from a position:sticky element ghost through
   a position:fixed overlay sitting above them. Aish saw this on the Train
   sheet: the header's "Whayle" + "@username" text bled through the
   "LOG A SESSION" title at the same y-position. display:none kills the
   element entirely so there are no glyphs left for Safari to mis-composite.
   Layout shift is invisible because the sheet is position:fixed and covers
   everything below it. */
body.sheet-open .header{display:none}
/* Sheet sits BETWEEN the (now-invisible) banner area at top and the
   bottom nav at bottom. Bottom nav stays visible for one-tap tab
   switching (goSection() closes the sheet and navigates). */
.food-sheet-panel{
  /* Just styling — no positioning. Centered on wide screens. */
  width:100%;max-width:720px;
  margin:0 auto;
  min-height:100%;
  background:var(--bg);
  padding:0 18px calc(32px + env(safe-area-inset-bottom));
}
/* Head sticks to the top of the sheet's scroll context. The safe-area
   inset is baked into padding-top so the × always lands below the iOS
   notch — impossible to hide behind app chrome. */
.food-sheet-head{
  position:sticky;top:0;z-index:5;
  background:var(--bg);
  display:flex;align-items:center;justify-content:space-between;
  /* The sheet now covers from viewport top:0 (it used to start below the
     WHAYLE banner, which left a visible gap when iOS layout settled mid-
     animation). So this head IS the topmost visible chrome and must
     clear the iOS notch / status bar. Bake env(safe-area-inset-top) into
     the top padding. The 14px fallback keeps the title off the edge on
     Android / desktop where the inset is 0. */
  padding:calc(14px + env(safe-area-inset-top)) 0 12px;
  margin-bottom:6px;border-bottom:1px solid var(--line);
}
.food-sheet-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:28px;letter-spacing:0.02em;color:var(--text);text-transform:uppercase;line-height:1}
.food-sheet-close{
  width:36px;height:36px;border-radius:var(--radius);
  background:transparent;border:1px solid var(--line);
  color:var(--text);cursor:pointer;font-size:22px;font-weight:300;
  display:flex;align-items:center;justify-content:center;
  transition:border-color 0.15s;
}
.food-sheet-close:hover{border-color:var(--accent);color:var(--accent)}
.food-sheet-section-label{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:1.4px;text-transform:uppercase;color:var(--text2);margin-bottom:10px}

/* ─── Saved-meals library panel (#saved-meals-all-view) ─────────────────
   Sort tabs use the same Apple-Health-style raised-active-pill pattern as
   the train-mode-toggle. Rows are full-width tappable cards with name +
   macros on the left and edit/delete icons on the right. */
.saved-meals-sort-btn{
  flex:1;border:0;border-radius:10px;
  padding:9px 6px;
  font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:500;
  letter-spacing:1.2px;text-transform:uppercase;
  color:var(--text2);background:transparent;cursor:pointer;
  transition:background 0.12s, color 0.12s;
}
.saved-meals-sort-btn.active{
  background:var(--bg);color:var(--text);
  box-shadow:0 1px 2px rgba(0,0,0,0.3);
}
.saved-meal-row{
  display:flex;align-items:center;gap:10px;
  padding:14px 14px;margin-bottom:8px;
  background:var(--bg2,#0f1216);
  border:1px solid var(--line);border-radius:var(--radius);
  transition:border-color 0.12s, transform 0.08s;
}
.saved-meal-row:active{ transform:scale(0.99) }
.saved-meal-row-body{
  flex:1;min-width:0;cursor:pointer;
  display:flex;flex-direction:column;gap:4px;
}
.saved-meal-row-name{
  font-family:'Inter',sans-serif;font-size:14px;font-weight:600;
  color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.saved-meal-row-meta{
  font-family:'JetBrains Mono',monospace;font-size:10px;
  color:var(--text3);letter-spacing:0.4px;
  font-variant-numeric:tabular-nums;
}
.saved-meal-row-meta .kcal{ color:var(--text2);font-weight:600 }
.saved-meal-row-actions{
  display:flex;gap:6px;flex-shrink:0;
}
.saved-meal-row-btn{
  width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid var(--line);border-radius:8px;
  color:var(--text2);cursor:pointer;
  transition:border-color 0.12s, color 0.12s;
}
.saved-meal-row-btn:hover{ border-color:var(--text2);color:var(--text) }
.saved-meal-row-btn.danger:hover{ border-color:var(--coral,var(--accent));color:var(--coral,var(--accent)) }
.food-manual-details{margin-top:14px;position:relative}
.food-manual-details::before{
  content:"OR LOG IT YOURSELF";
  display:block;
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:1.4px;
  color:var(--text2);
  margin-bottom:10px;
  padding-top:14px;
  border-top:1px solid var(--line);
}
.food-manual-details summary{
  list-style:none;cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;
  padding:16px 18px;background:var(--surface);border:1px solid var(--whale);border-radius:var(--radius);
  font-family:'Inter',sans-serif;font-size:13px;font-weight:700;letter-spacing:0.8px;text-transform:uppercase;color:var(--text);
  transition:background 0.15s,border-color 0.15s;
}
.food-manual-details summary:hover{background:var(--glass2);border-color:var(--whale-2)}
.food-manual-details summary::-webkit-details-marker{display:none}
.food-manual-details summary .chev{font-size:22px;font-weight:300;color:var(--whale);transition:transform 0.15s}
.food-manual-details[open] summary{border-color:var(--accent)}
.food-manual-details[open] summary .chev{transform:rotate(45deg);color:var(--accent)}

/* ─── WATER ───
   Water-blue token. The rest of Whayle is monochrome + accent-orange, so
   blue is reserved for the water tracking surfaces. Picked a mid-bright
   blue that reads cleanly on the dark substrate without clashing with the
   accent in the same view. */
:root{
  /* 2026-06-04: muted water palette. Original was #4FA8FF (HSL 212, 100%, 65%)
     which on the dark substrate read as one of the brightest elements on
     screen, visually competing with --accent. Dropped saturation ~35% and
     lightness ~15% to keep the cool/water identity intact while letting the
     accent stay the loudest signal in the system. The three tokens still
     cluster as a family (mid, dark, light). */
  --water:#3A82C7;
  --water-dark:#1F5587;
  --water-light:#6FA8DA;
}
.water-cups{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}
.cup{
  width:32px;height:44px;border-radius:var(--radius);
  border:1px solid var(--line2);
  background:transparent;
  cursor:pointer;
  transition:all 0.15s;
}
.cup:hover{border-color:var(--text2)}
.cup.filled{background:var(--water);border-color:var(--water)}

/* Water level transitions are driven by Motion One (window.Motion) — see
   _animateWaterLevel in app.html. We do NOT set CSS transitions on fill /
   meniscus / shimmer here because the JS spring would fight the CSS
   transition. Only the static opacity transition stays. */
#water-fill, #water-meniscus, #water-shimmer{
  transition: opacity 500ms ease-out;
}
/* Gentle surface motion — the meniscus rocks ±0.3px continuously so the
   water surface feels alive even when the level is steady. Subtle, not
   a "wave". */
@keyframes water-surface-rock { 0%,100%{transform:translateY(0)} 50%{transform:translateY(0.5px)} }
#water-meniscus, #water-shimmer{ animation:water-surface-rock 2.8s ease-in-out infinite }

/* Over-target spill — clean, minimal. Three drops trickling from the rim
   on staggered cycles + a small puddle pool. Earlier iteration tried to
   render a dramatic full cascade with side-streams and a dome of water,
   which Aish found cheap-looking. This is the "tasteful" version: an
   unmistakable signal that you're over your goal without turning the
   glass into a fountain. */
@keyframes water-drop-fall {
  0%{transform:translateY(0);opacity:0}
  10%{opacity:1}
  85%{opacity:1}
  100%{transform:translateY(88px);opacity:0}
}
.water-drip-1{animation:water-drop-fall 1.6s cubic-bezier(0.4,0,1,1) infinite 0.00s}
.water-drip-2{animation:water-drop-fall 1.6s cubic-bezier(0.4,0,1,1) infinite 0.55s}
.water-drip-3{animation:water-drop-fall 1.6s cubic-bezier(0.4,0,1,1) infinite 1.10s}
/* Soft pulse on the puddle so it breathes — subtle. */
@keyframes water-puddle-breathe { 0%,100%{transform:scale(1)} 50%{transform:scale(1.06)} }
#water-spill-puddle-group{ animation:water-puddle-breathe 2.2s ease-in-out infinite;transform-origin:40px 102px }
/* Smooth fade on the whole spill group when overTarget toggles. */
#water-spill-drops, #water-spill-puddle-group{
  transition: opacity 400ms ease-out;
}
#water-spill-puddle, #water-spill-puddle-outer, #water-spill-puddle-shine{
  transition: rx 500ms cubic-bezier(0.22,0.61,0.36,1);
}

/* Custom goal popover — small floater under the goal badge with a number
   stepper. position:absolute relative to the goal badge's wrapper. */
.water-goal-popover{
  position:absolute; top:calc(100% + 8px); right:0; z-index:30;
  background:#0F0F0F; border:1.5px solid rgba(255,255,255,0.10);
  border-radius:14px; padding:14px; min-width:200px;
  box-shadow:0 12px 36px rgba(0,0,0,0.5);
}
.water-goal-popover input[type="number"]{
  width:100%; padding:10px 12px; background:rgba(255,255,255,0.04);
  border:1px solid var(--line); border-radius:10px; color:var(--text);
  font-family:'Bebas Neue','Inter',sans-serif; font-size:18px; letter-spacing:0.04em;
  outline:none; box-sizing:border-box;
}
.water-goal-popover input[type="number"]:focus{border-color:var(--water)}

/* ─── BADGE ─── */
.badge{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:var(--radius);font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:600;letter-spacing:1px;text-transform:uppercase}
.badge-teal{background:var(--surface);color:var(--text);border:1px solid var(--line2)}
.badge-amber{background:var(--surface);color:var(--text);border:1px solid var(--line2)}
.badge-purple{background:var(--surface);color:var(--text);border:1px solid var(--line2)}

/* ─── POD ─── */
/* ─── POD CARDS — Apple Health × Whayle ─── */
.pod-card{
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.06);
  border-radius:18px;padding:22px 24px;cursor:pointer;
  box-shadow:
    0 2px 16px rgba(0,0,0,0.22),
    inset 0 1px 0 rgba(255,255,255,0.04);
  transition:transform 0.12s ease,
             border-color 0.2s ease,
             box-shadow 0.2s ease;
  position:relative;overflow:hidden;margin-bottom:14px;
}
.pod-card::after{display:none}
.pod-card:hover{
  border-color:rgba(255,255,255,0.12);
  box-shadow:
    0 4px 24px rgba(0,0,0,0.3),
    inset 0 1px 0 rgba(255,255,255,0.05);
}
.pod-card:active{transform:scale(0.99)}
.pod-avatar{
  width:56px;height:56px;border-radius:14px;
  display:flex;align-items:center;justify-content:center;font-size:28px;flex-shrink:0;
  background:rgba(255,255,255,0.04);
  border:1px solid rgba(255,255,255,0.08);
  box-shadow:none
}
.pod-name{font-family:'Bebas Neue','Inter',sans-serif;font-size:22px;font-weight:800;letter-spacing:-0.01em;line-height:1.05;text-transform:uppercase}
.pod-meta{color:var(--text3);display:flex;align-items:center;gap:6px}
.pod-members{display:flex;align-items:center;margin-top:10px;gap:0}
.pod-member-avatar{
  width:30px;height:30px;border-radius:50%;
  border:2px solid var(--surface);
  display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:800;margin-left:-8px;font-family:'Bebas Neue','Inter',sans-serif;
  box-shadow:0 2px 6px rgba(0,0,0,0.35)
}
.pod-member-avatar:first-child{margin-left:0}
/* Pod action buttons — Apple Health × Whayle. Matches .pod-card surface
   treatment (soft 18px corners, outer shadow + inner highlight) so the
   tile row reads as a continuation of the cards below, not as a
   different visual language stacked on top. */
.pod-actions{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:22px}
.pod-action-btn{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;padding:18px 8px;border-radius:18px;cursor:pointer;
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.06);
  box-shadow:
    0 2px 16px rgba(0,0,0,0.22),
    inset 0 1px 0 rgba(255,255,255,0.04);
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             box-shadow var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
  font-family:'Inter',sans-serif;color:var(--text2)
}
.pod-action-btn:hover{
  border-color:rgba(255,255,255,0.12);
  color:var(--text);
  box-shadow:
    0 4px 24px rgba(0,0,0,0.3),
    inset 0 1px 0 rgba(255,255,255,0.05);
}
.pod-action-btn:active{transform:scale(0.96)}
.pod-action-btn .pa-icon{font-size:22px;line-height:1;opacity:0.9}
.pod-action-btn .pa-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.8px}

/* ─── CYCLE ─── Apple Health × Whayle: muted dark cards, accent only on
   the active phase. No per-phase pinks/greens/yellows/purples — those
   clashed with the rest of the app. */
.cycle-phase-card{
  border-radius:14px;
  padding:14px 16px;
  border:1px solid var(--line);
  margin-bottom:0;
  background:rgba(255,255,255,0.02);
  display:flex;flex-direction:column;gap:4px;
  transition:border-color 0.15s,background 0.15s;
}
.cycle-phase-card.active{
  border-color:var(--accent);
  background:rgba(255,59,31,0.06);
}
.cycle-phase-name{
  font-family:'Bebas Neue','Inter',sans-serif;
  font-size:13px;font-weight:800;letter-spacing:0.04em;
  color:var(--text);
  text-transform:uppercase;
  display:flex;align-items:center;gap:6px;
}
.cycle-phase-card.active .cycle-phase-name{color:var(--accent)}
.cycle-phase-days{
  font-family:'JetBrains Mono',monospace;
  font-size:9.5px;font-weight:500;
  letter-spacing:0.8px;text-transform:uppercase;
  color:var(--text3);
  margin-left:auto;
}
.cycle-phase-desc{
  font-size:11px;color:var(--text2);line-height:1.45;
}
.cycle-phase-adj{
  font-family:'JetBrains Mono',monospace;
  font-size:10px;font-weight:600;
  letter-spacing:0.8px;
  color:var(--text2);
  margin-top:2px;
}
.cycle-phase-card.active .cycle-phase-adj{color:var(--accent)}
.cycle-phase-here{
  font-family:'JetBrains Mono',monospace;
  font-size:9px;font-weight:700;
  letter-spacing:1.4px;text-transform:uppercase;
  color:var(--accent);
  margin-top:2px;
}

/* ─── ACHIEVEMENTS ─── */
.achievement-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(min-width:500px){.achievement-grid{grid-template-columns:repeat(4,1fr)}}
.achievement-badge{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:14px;background:rgba(255,255,255,0.03);
  border:1px solid rgba(255,255,255,0.06);border-radius:var(--radius-sm);
  text-align:center;transition:all 0.2s;
}
.achievement-badge.earned{border-color:rgba(255,59,31,0.15);background:rgba(255,59,31,0.04)}
.achievement-badge.locked{opacity:0.25;filter:grayscale(1)}
.achievement-icon{font-size:30px}
.achievement-name{font-size:10px;font-weight:700;color:var(--text2);letter-spacing:0.5px;text-transform:uppercase}

/* ─── TOAST ─── */
/* Pill toast that snaps in from below with a subtle spring overshoot
   (ease-spring, a delight moment — toasts confirm something happened).
   Asymmetric timing: enter is springy (--dur-base + --ease-spring),
   exit is quicker and clean (--dur-fast + --ease-out) so the toast
   feels eager-but-polite. */
.toast{
  position:fixed;bottom:90px;left:50%;
  transform:translateX(-50%) translateY(60px) scale(0.96);
  opacity:0;pointer-events:none;display:none;
  background:rgba(20,20,22,0.95);
  border:1px solid rgba(255,255,255,0.08);
  color:rgba(255,255,255,0.92);
  padding:11px 22px;border-radius:100px;
  font-size:13px;font-weight:500;letter-spacing:0.1px;
  z-index:9999;
  transition:opacity var(--dur-fast) var(--ease-out),
             transform var(--dur-base) var(--ease-spring);
  white-space:nowrap;max-width:90vw;text-align:center;overflow:hidden;text-overflow:ellipsis;
  box-shadow:0 8px 32px rgba(0,0,0,0.4);
}
.toast.show{opacity:1;pointer-events:none;transform:translateX(-50%) translateY(0) scale(1)}
@media(min-width:768px){.toast{bottom:30px}}

/* ─── STREAK WIDGET ─── */
/* v2 — vertical block matching the other dashboard cards. Uses the same
   --glass / --border tokens so it sits flush with Today's Macros, Activity,
   Food Quality. Accent border on hover/active hints tappability without
   stealing attention. */
.streak-bar{display:block;width:100%;background:var(--glass);border:1px solid var(--border);border-radius:var(--radius);padding:18px 18px 16px;margin-bottom:16px;cursor:pointer;-webkit-appearance:none;appearance:none;font:inherit;color:inherit;text-align:left;-webkit-tap-highlight-color:rgba(255,59,31,0.10);transition:border-color 120ms ease,background 120ms ease}
.streak-bar:hover,.streak-bar:active{border-color:rgba(255,59,31,0.32);background:rgba(255,255,255,0.04)}
.streak-fire{font-size:18px;flex-shrink:0}
.streak-count{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;font-weight:800;color:rgba(255,255,255,0.85);line-height:1}
.streak-label{font-size:11px;color:var(--text3)}
.streak-days{display:flex;gap:5px;align-items:center}
.streak-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.10);flex-shrink:0}
.streak-dot.done{background:var(--lime)}
.streak-dot.today{background:var(--lime)}

/* ─── SAVED MEALS ─── */
.saved-meals-wrap{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.saved-meal-chip{
  display:inline-flex;align-items:center;gap:8px;
  background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);
  border-radius:10px;padding:6px 10px 6px 14px;cursor:pointer;font-size:12px;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out);
}
.saved-meal-chip:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12)}
.saved-meal-chip:active{transform:scale(0.96)}
.saved-meal-chip-name{font-weight:600;color:var(--text)}
.saved-meal-chip-cal{color:var(--text3);font-size:11px}
.saved-meal-chip-del{
  width:32px;height:32px;margin:-6px -6px -6px 0;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:13px;
  color:var(--text3);cursor:pointer;flex-shrink:0;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
}
.saved-meal-chip-del:hover{color:var(--accent);background:rgba(255,59,31,0.15)}
.saved-meal-chip-del:active{transform:scale(0.88)}

/* ─── MUSIC CARD ─── */
.music-member{display:flex;align-items:center;gap:12px;padding:10px;border-radius:var(--radius-sm);background:rgba(255,255,255,0.02);border:1px solid rgba(255,255,255,0.04);margin-bottom:8px;transition:all 0.2s}
.music-member:hover{background:rgba(255,255,255,0.04)}
.music-album-art{width:44px;height:44px;border-radius:8px;background:rgba(255,255,255,0.06);flex-shrink:0;object-fit:cover;overflow:hidden;display:flex;align-items:center;justify-content:center}
.music-album-art img{width:100%;height:100%;object-fit:cover;border-radius:8px}
.music-track-info{flex:1;min-width:0}
.music-track-name{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.music-track-artist{font-size:11px;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.music-member-name{font-size:10px;color:var(--text3);font-weight:500;margin-top:2px}
.music-playing-icon{display:flex;align-items:flex-end;gap:2px;height:14px;flex-shrink:0}
.music-playing-icon span{display:block;width:3px;background:var(--lime);border-radius:1px;animation:musicBar 0.8s ease-in-out infinite}
.music-playing-icon span:nth-child(1){height:6px;animation-delay:0s}
.music-playing-icon span:nth-child(2){height:10px;animation-delay:0.15s}
.music-playing-icon span:nth-child(3){height:4px;animation-delay:0.3s}
.music-playing-icon span:nth-child(4){height:8px;animation-delay:0.45s}
@keyframes musicBar{0%,100%{height:4px}50%{height:14px}}
.music-service-badge{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;padding:2px 6px;border-radius:4px}
.music-badge-spotify{background:rgba(30,215,96,0.12);color:#1DB954}
.music-badge-apple{background:rgba(252,60,68,0.12);color:#FC3C44}
.music-history-item{display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid rgba(255,255,255,0.03)}
.music-history-item:last-child{border-bottom:none}

/* ─── POD CHALLENGE ─── */
.challenge-hero{background:var(--surface);border:1px solid rgba(255,255,255,0.05);border-radius:18px;padding:22px;margin-bottom:18px;box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04)}
.challenge-type-badge{display:inline-block;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:1.2px;color:var(--text2);background:rgba(255,255,255,0.05);border-radius:8px;padding:3px 10px;margin-bottom:10px}
.challenge-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:18px;font-weight:800;margin-bottom:4px}
.challenge-ends{font-size:11px;color:var(--text3);margin-bottom:16px}
.challenge-row{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.challenge-pos{font-family:'Bebas Neue','Inter',sans-serif;font-size:12px;font-weight:800;width:22px;color:var(--text3);flex-shrink:0}
.challenge-bar-wrap{flex:1}
.challenge-bar{height:6px;background:rgba(255,255,255,0.07);border-radius:3px;overflow:hidden;margin-top:3px}
.challenge-bar-fill{height:100%;border-radius:3px;transition:width 0.8s ease}
.challenge-val{font-size:12px;font-weight:700;min-width:44px;text-align:right;flex-shrink:0}

/* ─── ACTIVITY FEED ─── */
.feed-item{display:flex;align-items:flex-start;gap:10px;padding:10px 0;border-bottom:1px solid rgba(255,255,255,0.05)}
.feed-item:last-child{border-bottom:none}
.feed-icon{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.07)}
.feed-text{font-size:12px;color:var(--text2);line-height:1.45;flex:1}
.feed-text strong{color:var(--text)}
.feed-ago{font-size:10px;color:var(--text3);flex-shrink:0;white-space:nowrap;margin-top:1px}

/* ─── WEEKLY AI SUMMARY ─── */
.ai-summary-card{background:var(--surface);border:1px solid rgba(255,255,255,0.05);border-radius:18px;padding:22px;margin-bottom:18px;box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04)}
.ai-summary-header{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.ai-summary-icon{font-size:20px}
.ai-summary-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:15px;font-weight:800}
.ai-summary-date{font-size:11px;color:var(--text3)}
.ai-summary-body{font-size:13px;color:var(--text2);line-height:1.65}
.ai-summary-body p{margin-bottom:8px}
.ai-summary-body p:last-child{margin-bottom:0}

/* ─── MODAL ─── */
/* Backdrop fades + modal scales up from 96% with --ease-out. The 96% start
   is intentional: scale(0) feels "popped" from nothing while 96% feels
   like the content was already there, just snapping into focus. */
.modal-overlay{
  position:fixed;inset:0;
  background:rgba(0,0,0,0.78);
  z-index:1000;display:flex;align-items:center;justify-content:center;
  padding:20px;opacity:0;pointer-events:none;
  transition:opacity var(--dur-base) var(--ease-out);
}
.modal-overlay.open{opacity:1;pointer-events:all}
.modal{
  background:rgba(20,20,20,0.98);
  border:1px solid rgba(255,255,255,0.06);
  border-radius:20px;padding:28px;
  width:100%;max-width:480px;max-height:88vh;overflow-y:auto;
  transform:translateY(12px) scale(0.96);
  opacity:0;
  transition:transform var(--dur-slow) var(--ease-out),
             opacity var(--dur-base) var(--ease-out);
  position:relative;
  box-shadow:0 24px 64px rgba(0,0,0,0.5),inset 0 1px 0 rgba(255,255,255,0.04);
  will-change:transform,opacity;
}
.modal::before{display:none}
.modal-overlay.open .modal{transform:translateY(0) scale(1);opacity:1}
.modal-close{
  position:absolute;top:14px;right:14px;
  background:var(--glass2);border:1px solid var(--border);color:var(--text3);
  cursor:pointer;font-size:16px;
  width:40px;height:40px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;z-index:2;
  transition:transform var(--dur-instant) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out);
}
.modal-close:hover{color:var(--text);background:var(--glass3)}
.modal-close:active{transform:scale(0.92)}
.modal-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:22px;font-weight:800;margin-bottom:8px;letter-spacing:-0.02em}
.modal-sub{font-size:13px;color:var(--text2);margin-bottom:22px;line-height:1.6}

/* ─── LOADING / SPLASH SCREEN ─── */
.loading-page{
  position:fixed;inset:0;
  background:var(--bg);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  z-index:9998;gap:16px;transition:opacity 0.5s ease-out;
  overflow:hidden;
}
/* Loading splash backdrop — kept as a stub but emptied. The previous
   indigo/orange radial-gradient stack here was the same "AI mockup" tell
   stripped from #page-auth, so we let the splash sit on flat --bg too. */
.loading-page::before{
  content:'';position:absolute;inset:0;
  background:transparent;
  pointer-events:none;
}
.loading-page::after{display:none}
.loading-page.hidden{opacity:0;pointer-events:none}
.loading-whale{animation:float 2.5s ease-in-out infinite;position:relative;z-index:1;filter:drop-shadow(0 4px 24px rgba(255,255,255,0.35));display:inline-flex;line-height:0}
.loading-whale svg{width:64px;height:64px}
.loading-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:32px;font-weight:800;color:rgba(255,255,255,0.92);letter-spacing:-0.03em;position:relative;z-index:1}
.loading-tagline{font-size:14px;color:var(--text2);font-weight:400;letter-spacing:0.04em;position:relative;z-index:1}
.loading-spinner{width:28px;height:28px;border:2.5px solid rgba(255,255,255,0.06);border-top-color:rgba(255,59,31,0.5);border-radius:50%;animation:spin 0.8s linear infinite;position:relative;z-index:1;margin-top:8px}
.loading-msg{font-size:13px;color:var(--text3);font-weight:400;position:relative;z-index:1}
/* Floating bubbles decoration */
@keyframes bubbleUp{0%{transform:translateY(0) scale(1);opacity:0.3}100%{transform:translateY(-120px) scale(0.3);opacity:0}}
.splash-bubble{position:absolute;border-radius:50%;background:rgba(255,59,31,0.07);animation:bubbleUp 3s ease-in infinite;pointer-events:none}
.splash-bubble:nth-child(1){width:12px;height:12px;bottom:15%;left:20%;animation-delay:0s}
.splash-bubble:nth-child(2){width:8px;height:8px;bottom:10%;left:55%;animation-delay:0.8s}
.splash-bubble:nth-child(3){width:10px;height:10px;bottom:20%;left:75%;animation-delay:1.6s}
.splash-bubble:nth-child(4){width:6px;height:6px;bottom:12%;left:35%;animation-delay:2.2s}

/* ─── TABS — Apple Health × Whayle segmented control ───
   Soft trough container with a "raised tile" active state. The active tab
   sits visually on top of the trough thanks to a subtle elevation + inset
   highlight, mirroring how iOS segmented controls behave in Apple Health.
   This replaces the prior brutalist hard-white-on-black tab pill that
   clashed with the soft-card aesthetic everywhere else. */
.tabs{
  display:flex;gap:4px;
  background:rgba(255,255,255,0.025);
  border:1px solid rgba(255,255,255,0.05);
  border-radius:14px;padding:4px;margin-bottom:22px;
  overflow:hidden;
}
.tab{
  flex:1;padding:10px 14px;border:none;background:transparent;
  color:var(--text3);
  font-family:'JetBrains Mono',monospace;
  font-size:11px;font-weight:600;letter-spacing:1.4px;text-transform:uppercase;
  cursor:pointer;border-radius:10px;
  transition:background var(--dur-base) var(--ease-out),
             color     var(--dur-base) var(--ease-out),
             box-shadow var(--dur-base) var(--ease-out),
             transform var(--dur-instant) var(--ease-out);
  text-align:center;white-space:nowrap;
}
.tab:hover:not(.active){color:var(--text2)}
.tab:active{transform:scale(0.98)}
.tab.active{
  background:var(--surface);
  color:var(--text);
  box-shadow:
    0 2px 6px rgba(0,0,0,0.28),
    inset 0 1px 0 rgba(255,255,255,0.06);
}
/* Pod detail tabs — scrollable row, don't compress */
#pod-detail .tabs{
  overflow-x:auto;-webkit-overflow-scrolling:touch;
  flex-wrap:nowrap;
  /* hide scrollbar visually but keep it functional */
  scrollbar-width:none;-ms-overflow-style:none;
}
#pod-detail .tabs::-webkit-scrollbar{display:none}
#pod-detail .tab{flex:none;white-space:nowrap;font-size:11px;padding:8px 14px}

/* ─── TOGGLE ─── */
.toggle-switch{position:relative;width:46px;height:26px;cursor:pointer}
.toggle-switch input{opacity:0;width:0;height:0;position:absolute}
.toggle-track{position:absolute;inset:0;border-radius:13px;background:rgba(255,255,255,0.1);transition:background 0.3s}
.toggle-switch input:checked~.toggle-track{background:var(--accent)}
.toggle-switch input:checked~.toggle-thumb{background:var(--accent-ink)}
.toggle-thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:white;box-shadow:0 1px 4px rgba(0,0,0,0.3);transition:transform 0.3s}
.toggle-switch input:checked~.toggle-thumb{transform:translateX(20px)}

/* ─── ONBOARDING STEPS ─── */
.step-indicator{display:flex;gap:6px;justify-content:center;margin-bottom:28px}
.step-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.12);transition:all 0.3s}
.step-dot.active{background:var(--lime);width:28px;border-radius:4px;box-shadow:0 0 12px rgba(255,59,31,0.4)}
.step-dot.done{background:var(--lime2)}

/* ─── EMPTY STATE ─── */
.empty-state{text-align:center;padding:44px 20px;color:var(--text3)}
.empty-icon{font-size:42px;margin-bottom:14px;display:block}
.empty-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:17px;font-weight:700;color:var(--text2);margin-bottom:8px}
.empty-text{font-size:13px;line-height:1.7}

/* ─── WHALE MARK — reusable silhouette ─── */
.whale-mark{display:inline-block;color:var(--whale);opacity:0.55;line-height:0}
.whale-mark svg{width:100%;height:100%;display:block;fill:currentColor}
.whale-mark.sm{width:28px;height:18px}
.whale-mark.md{width:56px;height:32px}
.whale-mark.lg{width:96px;height:56px}
.whale-mark.xl{width:140px;height:80px}

/* ─── CODE BOX ─── */
.code-box{background:var(--lime3);border:2px dashed var(--border2);border-radius:var(--radius-sm);padding:24px;text-align:center}
.code-value{font-family:'Bebas Neue','Inter',sans-serif;font-size:34px;font-weight:800;color:var(--lime);letter-spacing:8px;margin-bottom:8px}
.code-hint{font-size:12px;color:var(--text3);font-weight:500}

/* ─── MISC UTILITIES ─── */
.gap-3{gap:12px}.gap-2{gap:8px}
.flex{display:flex;align-items:center}.flex-between{justify-content:space-between}.flex-wrap{flex-wrap:wrap}
.mb-4{margin-bottom:24px}.mb-3{margin-bottom:16px}.mb-2{margin-bottom:10px}
.mt-3{margin-top:16px}
.text-center{text-align:center}
hr.sep{border:none;border-top:1px solid var(--border);margin:22px 0}

/* ─── CHART ─── */
.chart-bar{flex:1;border-radius:4px 4px 0 0;min-height:4px;transition:height 0.6s cubic-bezier(0.22,1,0.36,1);position:relative;cursor:pointer;opacity:0.7}
.chart-bar:last-child{opacity:1}
.chart-bar:hover{opacity:1}
.chart-bar:hover::after{content:attr(data-tip);position:absolute;top:-30px;left:50%;transform:translateX(-50%);background:var(--glass3);border:1px solid var(--border);border-radius:8px;padding:4px 8px;font-size:10px;font-weight:600;white-space:nowrap;pointer-events:none;backdrop-filter:none}

/* ─── SCROLLBAR ─── */
::-webkit-scrollbar{width:3px;height:3px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.08);border-radius:2px}

/* ─── AI COACH FAB + PANEL ─── */
.coach-fab{
  position:fixed;bottom:calc(82px + env(safe-area-inset-bottom));right:18px;z-index:200;
  width:56px;height:56px;border-radius:50%;
  background:var(--whale);color:var(--whale-ink);
  border:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 28px rgba(255,255,255,0.28), 0 2px 6px rgba(0,0,0,0.4);
  transition:transform var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out),
             background var(--dur-fast) var(--ease-out);
  will-change:transform;
}
.coach-fab:hover{background:var(--whale-2);transform:translateY(-2px);box-shadow:0 16px 36px rgba(255,255,255,0.4), 0 2px 6px rgba(0,0,0,0.4)}
.coach-fab:active{transform:translateY(0) scale(0.94)}
.coach-fab.open{transform:rotate(45deg) scale(1.02);box-shadow:0 8px 22px rgba(255,255,255,0.28)}
.coach-fab .coach-fab-label{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;font-weight:400;letter-spacing:0.04em;line-height:1}
.coach-overlay{
  position:fixed;inset:0;z-index:199;background:rgba(0,0,0,0);
  pointer-events:none;
  transition:background var(--dur-slow) var(--ease-out);
  touch-action:none;overscroll-behavior:contain;
}
.coach-overlay.open{background:rgba(0,0,0,0.6);pointer-events:all}
body.coach-locked{overflow:hidden;position:fixed;width:100%;touch-action:none}
.coach-panel{
  position:fixed;bottom:0;left:0;right:0;z-index:300;
  background:rgba(20,20,20,0.98);
  border:1px solid rgba(255,255,255,0.06);border-bottom:none;
  border-radius:20px 20px 0 0;
  padding:0 0 env(safe-area-inset-bottom);
  height:72dvh;min-height:420px;max-height:82dvh;display:flex;flex-direction:column;
  transform:translateY(105%);
  /* iOS-style drawer curve — feels like the panel is being lifted by an
     invisible finger rather than just sliding mechanically. Asymmetric
     timing handled by JS — close transition uses a faster --dur-slow. */
  transition:transform var(--dur-drawer) var(--ease-drawer);
  box-shadow:0 -8px 32px rgba(0,0,0,0.4);
  visibility:hidden;pointer-events:none;
  will-change:transform;
  overscroll-behavior:contain;
  will-change:transform;
}
.coach-panel.open{visibility:visible;pointer-events:auto}
.coach-panel.open{transform:translateY(0)}
.coach-handle{width:32px;height:3px;border-radius:2px;background:rgba(255,255,255,0.1);margin:12px auto 0;flex-shrink:0}
.coach-ph{
  display:flex;align-items:center;justify-content:space-between;
  padding:14px 22px 12px;border-bottom:1px solid rgba(255,255,255,0.08);flex-shrink:0;
}
.coach-ph-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:15px;font-weight:700;color:rgba(255,255,255,0.8);display:flex;align-items:center;gap:8px}
.coach-ph-sub{font-size:11px;color:var(--text3);margin-top:2px}
.coach-msgs{flex:1;overflow-y:auto;padding:14px 18px;display:flex;flex-direction:column;gap:10px;min-height:0}
.cmsg{max-width:88%;line-height:1.55;font-size:13px;animation:fadeUp 0.25s ease}
.cmsg.user{
  align-self:flex-end;
  background:rgba(255,59,31,0.16);
  border:1px solid rgba(255,59,31,0.32);
  border-radius:16px 16px 4px 16px;padding:10px 14px;color:var(--text);
}
.cmsg.ai{
  align-self:flex-start;
  background:rgba(255,255,255,0.06);
  border:1px solid rgba(255,255,255,0.12);
  border-radius:4px 16px 16px 16px;padding:10px 14px;color:var(--text);
}
.cmsg.ai.thinking{opacity:0.5}
.coach-dots span{width:5px;height:5px;border-radius:50%;background:var(--lime);display:inline-block;animation:pulse 1s infinite}
.coach-dots span:nth-child(2){animation-delay:0.2s}.coach-dots span:nth-child(3){animation-delay:0.4s}
.coach-input-row{
  display:flex;gap:10px;padding:10px 16px 14px;border-top:1px solid rgba(255,255,255,0.08);flex-shrink:0;
}
.coach-input-row input{
  flex:1;background:rgba(255,255,255,0.08);
  border:1px solid rgba(255,255,255,0.12);border-radius:100px;
  padding:10px 18px;font-family:'Inter',sans-serif;font-size:16px;color:var(--text);
  outline:none;transition:all 0.2s;backdrop-filter:none;
  touch-action:manipulation;
}
.coach-input-row input:focus{border-color:var(--lime);background:rgba(255,255,255,0.12);box-shadow:0 0 0 3px rgba(255,59,31,0.1)}
.coach-input-row input::placeholder{color:var(--text3)}
.coach-send{
  width:40px;height:40px;border-radius:50%;background:var(--lime);color:var(--bg);
  border:none;cursor:pointer;font-size:17px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
  transition:all 0.2s;flex-shrink:0;
  box-shadow:0 4px 16px rgba(255,59,31,0.4);
}
.coach-send:hover{transform:scale(1.1);box-shadow:0 6px 24px rgba(255,59,31,0.55)}
.coach-quick{display:flex;gap:7px;flex-wrap:wrap;padding:10px 18px 0;flex-shrink:0}
.coach-chip{
  background:rgba(255,255,255,0.07);border:1px solid rgba(255,255,255,0.12);
  border-radius:100px;padding:5px 12px;font-size:11px;font-weight:600;color:var(--text2);
  cursor:pointer;white-space:nowrap;transition:all 0.15s;
}
.coach-chip:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.1);color:rgba(255,255,255,0.7)}
@media(min-width:768px){
  .coach-fab{bottom:30px}
  .coach-panel{
    left:auto;right:22px;bottom:22px;width:360px;
    height:auto;min-height:unset;max-height:520px;
    border-bottom:1px solid rgba(255,255,255,0.14);
    border-radius:22px;
    transform:translateY(calc(100% + 80px));
  }
  .coach-panel.open{transform:translateY(0)}
  .coach-handle{display:none}
}

/* ─── POD RANK BANNER — Apple Health × Whayle ─── */
.rank-banner{
  border-radius:18px;padding:22px;margin-bottom:18px;
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.05);
  box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04);
  position:relative;overflow:hidden;
}
.rank-banner::before{display:none}
.rank-num{
  font-family:'Bebas Neue','Inter',sans-serif;font-size:42px;font-weight:400;line-height:1;
  color:var(--text);letter-spacing:0.01em;
  font-variant-numeric:tabular-nums;
}
/* ─── INSIGHT CHIPS — flat soft surface, no decorative gradients ─── */
.insight-card{
  border-radius:14px;padding:14px 16px;margin-bottom:10px;
  background:rgba(255,255,255,0.04);
  border:1px solid rgba(255,255,255,0.06);
  font-size:12px;color:var(--text2);line-height:1.55;
  display:flex;gap:10px;align-items:flex-start;
}
.insight-card.red{border-color:rgba(255,59,31,0.25);background:rgba(255,59,31,0.06)}
.insight-card.green{border-color:rgba(255,255,255,0.10);background:rgba(255,255,255,0.04)}
.insight-card.blue{border-color:rgba(255,255,255,0.10);background:rgba(255,255,255,0.04)}
.insight-card.amber{border-color:rgba(255,59,31,0.20);background:rgba(255,59,31,0.05)}

/* ─── MOMENT TOAST (top) ─── */
.moment-toast{
  position:fixed;top:72px;left:50%;z-index:500;
  transform:translateX(-50%) translateY(-100px);opacity:0;display:none;pointer-events:none;
  background:rgba(255,59,31,0.18);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  border:1px solid rgba(255,59,31,0.45);
  padding:11px 22px;border-radius:100px;
  font-size:13px;font-weight:700;color:var(--text);
  box-shadow:0 8px 40px rgba(0,0,0,0.5);
  transition:opacity 0.35s ease,transform 0.4s cubic-bezier(0.34,1.56,0.64,1);
  white-space:nowrap;
}
.moment-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ─── DASHBOARD POD RANK ─── */
.dash-pod-rank{
  background:rgba(255,255,255,0.03);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  border:1px solid rgba(255,255,255,0.06);border-radius:var(--radius);
  padding:18px 20px;transition:all 0.2s;
  position:relative;overflow:hidden;
}
.dash-pod-rank:hover{background:rgba(255,255,255,0.04)}
.dash-pod-rank::before{display:none}

/* ─── AUTH PAGE SPECIAL ─── */
/* ─── MOBILE SPACING IMPROVEMENTS ─── */
@media(max-width:480px){
  /* Bottom nav: more breathing room, safe area for notched phones */
  .bottom-nav{padding:8px 0 calc(4px + env(safe-area-inset-bottom))}
  .bnav-btn{padding:6px 2px;gap:3px}
  .bnav-label{font-size:9px}

  /* Cards: slightly more padding */
  .card{padding:18px 16px}

  /* Section headers */
  .section-title{font-size:20px}

  /* Wrap: tighter horizontal, but not too tight */
  .wrap{padding:0 14px 110px}

  /* Onboarding steps: slightly less padding on mobile */
  #page-onboard .glass{padding:20px 16px !important}

  /* Food input area */
  .food-input-area{padding:16px 14px}
  /* Stack the search row on narrow phones so the barcode-scan button
     never gets shoved off-screen. Input spans the full first row; the
     Search + barcode buttons sit side-by-side on the second row. */
  .food-search-row{grid-template-columns:1fr auto !important;gap:8px}
  .food-search-row>input{grid-column:1 / -1}

  /* Modal: full-width on mobile */
  .modal{max-width:calc(100vw - 24px);max-height:calc(100vh - 40px);padding:20px 16px}

  /* Streak bar */
  .streak-bar{padding:10px 12px}

  /* Water cups: slightly smaller on small screens */
  .cup{width:36px;height:36px;font-size:14px;border-radius:8px}

  /* Pod cards */
  .pod-card{border-radius:14px}

  /* Tabs: ensure scrollable */
  .tabs{gap:1px;padding:2px}
  .tab{padding:7px 10px;font-size:11px}

  /* Profile section spacing */
  .field{margin-bottom:12px}
  .field-label{font-size:11px;margin-bottom:4px}
  .field input,.field select,.field textarea{font-size:16px}

}

/* Extra small screens (iPhone SE, etc.) */
@media(max-width:360px){
  .wrap{padding:0 10px calc(120px + env(safe-area-inset-bottom))}
  .card{padding:14px 12px}
  .section-title{font-size:18px}
  .btn{height:40px;padding:0 16px;font-size:12px}
  .btn-sm{height:34px;padding:0 14px}
  .bottom-nav{padding:6px 0 calc(4px + env(safe-area-inset-bottom))}
}

/* PWA standalone mode: extra top padding for status bar.
   2026-05-10: removed body{padding-top:env()} — .header now bakes
   safe-area into its own padding so it works in BOTH browser and PWA
   modes. Keeping body padding here would double-pad the header in PWA
   mode and push WHAYLE ~60px below the status bar (the May-9 incident).
   Headerless pages (auth / loading / onboard / account-setup) still need
   their own env() padding because they don't get any header clearance. */
@media(display-mode:standalone){
  .bottom-nav{padding-bottom:calc(8px + env(safe-area-inset-bottom))}
  #page-auth{padding-top:env(safe-area-inset-top)}
  #page-onboard{padding-top:env(safe-area-inset-top)}
  #page-account-setup{padding-top:env(safe-area-inset-top)}
  .loading-page{padding-top:env(safe-area-inset-top)}
}

/* Auth page — flat black to match landing.html's brutalist aesthetic.
   The previous indigo / orange / lavender radial-gradient stack read as a
   classic "AI mockup" tell (purple-to-blue glow). Stripped to a solid
   surface so the WHAYLE wordmark + orange bar accent sit on the same
   true-black canvas as the rest of the brand. */
#page-auth{
  background:var(--bg);
}

/* ══════════════════════════════════════════════════════════════════════
   TRAIN TAB — workouts + recovery mirror
   ══════════════════════════════════════════════════════════════════════ */

/* Train hero — Apple Health × Whayle. Same surface treatment as food/wellness. */
.train-hero{
  background:var(--surface);
  border:1px solid rgba(255,255,255,0.05);
  border-radius:18px;
  padding:24px;margin-bottom:20px;
  box-shadow:
    0 2px 16px rgba(0,0,0,0.25),
    inset 0 1px 0 rgba(255,255,255,0.04);
}
.train-hero-head{margin-bottom:20px}
.train-hero-eyebrow{
  display:flex;align-items:center;gap:8px;
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;
  text-transform:uppercase;letter-spacing:1.4px;color:var(--text2);margin-bottom:10px;
}
.train-hero-eyebrow .dot{
  width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px rgba(255,59,31,0.18);
  animation:pulse-dot 1.6s ease-in-out infinite;
}
.train-hero-title{font-family:'Bebas Neue','Inter',sans-serif;font-weight:400;font-size:32px;letter-spacing:0.02em;line-height:1;margin-bottom:6px;text-transform:uppercase;color:var(--text)}
.train-hero-date{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text3);font-weight:500;letter-spacing:1px;text-transform:uppercase}
.train-hero-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:560px){.train-hero-stats{grid-template-columns:repeat(2,1fr);gap:10px}}
/* Stat tile — softer 12px corners, tinted bg, hover/active */
.train-hero-stat{
  background:rgba(255,255,255,0.025);
  border:1px solid rgba(255,255,255,0.05);
  border-radius:12px;padding:14px 12px;min-height:82px;
  display:flex;flex-direction:column;justify-content:space-between;
  transition:transform 0.08s ease,background 0.2s,border-color 0.2s;
}
.train-hero-stat:hover{background:rgba(255,255,255,0.04);border-color:rgba(255,255,255,0.10)}
.train-hero-stat-num{font-family:'Bebas Neue','Inter',sans-serif;font-size:30px;font-weight:400;line-height:0.95;color:var(--text);letter-spacing:0.01em;font-variant-numeric:tabular-nums}
.train-hero-stat-label{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:1.2px;color:var(--text2)}
/* Active stat — soft orange tint instead of hard top border */
/* AVG/WK accent tile — keep the same neutral surface as the other stats so
   the row reads as a uniform 2×2 grid; signal "this one is the headline"
   purely through the numeric color, not a tinted background. */
.train-hero-stat.train-hero-stat-accent .train-hero-stat-num{color:var(--accent)}

/* LOG CTA */
.train-log-cta-wrap{margin:14px 0}
.train-log-cta{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:18px 16px;border-radius:var(--radius);
}
.train-log-cta-label{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;font-weight:400;letter-spacing:0.06em;text-transform:uppercase}
.train-log-cta-sub{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:1.2px;text-transform:uppercase;opacity:0.85}

/* Generic Train card */
.train-card{background:var(--surface);border:1px solid rgba(255,255,255,0.05);border-radius:18px;padding:22px;margin-bottom:18px;box-shadow:0 2px 16px rgba(0,0,0,0.22),inset 0 1px 0 rgba(255,255,255,0.04)}
.train-card-head{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:14px}
.train-card-title{display:flex;align-items:center;gap:8px;font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:1.4px;color:var(--text)}
.train-card-title .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);animation:pulse-dot 1.6s ease-in-out infinite}
.train-card-sub{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:0.6px;color:var(--text3)}
.train-card-legend{display:flex;align-items:center;gap:4px}
.heat-lgd{font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--text3);letter-spacing:0.8px;margin:0 4px}

/* Heatmap — GitHub-style grid */
.train-heatmap-wrap{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}
.train-heatmap-months{display:grid;grid-template-columns:repeat(53,11px);gap:2px;padding:0 0 4px 0;min-width:max-content;font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--text3);letter-spacing:0.6px;text-transform:uppercase}
.train-heatmap-months .mo-lbl{grid-row:1;text-align:left}
/* grid-auto-flow:column — JS fills cells column-by-column (col0/Sun..Sat then
   col1/Sun..Sat...). Without this override the default row-flow scatters cells
   across the wrong positions while month labels stay correct, causing today's
   session to render in the middle of the heatmap instead of the right edge. */
.train-heatmap{display:grid;grid-template-columns:repeat(53,11px);grid-template-rows:repeat(7,11px);grid-auto-flow:column;gap:2px;min-width:max-content}
.heat-sq{width:11px;height:11px;border-radius:2px;background:var(--line);display:inline-block}
.heat-sq-0{background:var(--line)}
.heat-sq-1{background:rgba(255,59,31,0.28)}
.heat-sq-2{background:rgba(255,59,31,0.5)}
.heat-sq-3{background:rgba(255,59,31,0.75)}
.heat-sq-4{background:var(--accent)}
.heat-sq[data-day]{cursor:pointer;transition:transform 0.1s}
.heat-sq[data-day]:hover{transform:scale(1.25);outline:1px solid var(--text)}

/* Muscle balance chips. Default = neutral pill. Top-hit muscles get a
   subtle accent TINT (not solid orange) — orange-on-everything was reading
   as "alert state" rather than "this muscle is your most-trained group". */
.train-balance-chips{display:flex;flex-wrap:wrap;gap:6px}
.train-balance-chip{
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:600;
  letter-spacing:1.2px;text-transform:uppercase;
  padding:6px 10px;border:1px solid rgba(255,255,255,0.08);border-radius:999px;
  color:var(--text2);background:rgba(255,255,255,0.03);
}
.train-balance-chip.hit{
  color:var(--accent);
  background:rgba(255,59,31,0.08);
  border-color:rgba(255,59,31,0.22);
}
.train-balance-chip .bc-count{margin-left:6px;opacity:0.7;font-weight:700}

/* Recent sessions list */
.train-sessions{display:flex;flex-direction:column;gap:8px}
.train-empty{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text3);letter-spacing:0.6px;padding:16px 0;text-align:center}
.train-session{
  display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius);
  background:transparent;
}
.train-session-date{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);letter-spacing:0.6px;text-align:center;min-width:46px}
.train-session-date .day{display:block;font-family:'Bebas Neue','Inter',sans-serif;font-size:22px;color:var(--text);line-height:1}
.train-session-body{display:flex;flex-direction:column;gap:4px;min-width:0}
.train-session-type{font-family:'Bebas Neue','Inter',sans-serif;font-size:18px;text-transform:uppercase;color:var(--text);letter-spacing:0.02em}
.train-session-meta{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);letter-spacing:0.6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.train-session-right{display:flex;gap:6px;align-items:center}
.train-session-dur{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;color:var(--accent)}
/* v3 (2026-05-10): bumped from 28px / text3 / line border to 34px /
   subtle accent / accent-tinted border so the destructive affordance is
   actually discoverable. Aish flagged: "I want the option of deleting a
   session" — turned out the button existed but read as decorative. New
   styling makes it scan as "delete" at a glance without screaming. */
.train-session-del{
  background:rgba(255,59,31,0.06);
  border:1px solid rgba(255,59,31,0.22);
  color:rgba(255,59,31,0.85);
  width:34px;height:34px;border-radius:8px;cursor:pointer;
  font-size:18px;font-weight:300;line-height:1;
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  transition:background var(--dur-base) var(--ease-out),border-color var(--dur-base) var(--ease-out),color var(--dur-base) var(--ease-out),transform var(--dur-instant) var(--ease-out);
}
.train-session-del:hover{background:rgba(255,59,31,0.18);border-color:var(--accent);color:var(--accent)}
.train-session-del:active{transform:scale(0.92)}

/* Coach */
.train-coach-card{border-color:var(--accent)}
/* v4 (2026-05-11): brought max-height back down 560 → 380. 560 was eating
   too much vertical space on the train tab — Aish flagged the chatbox felt
   too big. The "land on latest" issue is now solved JS-side via a deferred
   instant scroll after history replay (see _renderCoachHistory in app.html),
   so a tall log isn't needed to keep the latest exchange visible.
   scroll-behavior:smooth applies only to user-initiated scrolls — JS that
   sets scrollTop=scrollHeight is instant by default. */
.train-coach-log{display:flex;flex-direction:column;gap:10px;margin-bottom:10px;max-height:380px;overflow-y:auto;scroll-behavior:smooth}
.train-coach-log:empty{display:none}
.coach-msg{padding:10px 12px;border-radius:10px;max-width:92%;font-size:13px;line-height:1.5}
.coach-msg.user{background:var(--accent);color:var(--accent-ink);align-self:flex-end;margin-left:auto;border:1px solid var(--accent)}
.coach-msg.bot{background:transparent;color:var(--text);border:1px solid var(--line)}
.coach-msg.bot.loading{color:var(--text3);font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:0.6px}
.train-coach-input-row{display:grid;grid-template-columns:1fr auto auto;gap:8px}
.train-coach-input-row input{
  background:var(--bg);border:1px solid var(--line2);border-radius:var(--radius);
  padding:0 14px;height:44px;color:var(--text);font-size:14px;outline:none;
  font-family:'Inter',sans-serif;min-width:0;
}
.train-coach-input-row input:focus{border-color:var(--accent)}
/* Mic button — same height as the Ask button, square. Listening state pulses
   with the accent so the user sees we're capturing. Mirrors the food mic. */
.train-coach-mic{
  width:44px;height:44px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  background:var(--bg);border:1px solid var(--line2);border-radius:var(--radius);
  color:var(--text2);cursor:pointer;
  transition:background var(--dur-base) var(--ease-out),border-color var(--dur-base) var(--ease-out),color var(--dur-base) var(--ease-out);
}
.train-coach-mic:hover{background:rgba(255,255,255,0.04);color:var(--text);border-color:rgba(255,255,255,0.16)}
.train-coach-mic.listening{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);animation:pulse 1.2s ease-in-out infinite}
/* Empty-state welcome inside the coach log — only visible when no messages
   have been added. Becomes invisible once the first message lands (since
   .train-coach-log:empty rule above). For the case where we DO want to
   show a welcome with messages already, .coach-msg.welcome is a regular
   bot-style row that lives inside the log permanently. */
.coach-msg.welcome{
  background:rgba(255,255,255,0.03);border:1px dashed rgba(255,255,255,0.10);
  color:var(--text2);font-size:12px;line-height:1.55;
}
/* Whale avatar before bot messages. Uses a small inline SVG-like glyph via
   ::before so we don't bloat HTML. The actual whale silhouette uses an inline
   svg in the markup for fidelity — this is just the spacing reservation. */
.coach-msg.bot{position:relative;padding-left:38px}
.coach-msg.bot::before{
  content:'';position:absolute;left:10px;top:11px;
  width:18px;height:18px;border-radius:50%;
  background:rgba(255,255,255,0.04);
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M4 40 C 4 22, 28 14, 42 20 L 58 6 L 56 28 C 62 32, 62 50, 46 54 C 28 58, 8 54, 4 40 Z' fill='%23ffffff' opacity='0.65'/><circle cx='44' cy='34' r='2.6' fill='%230a0a0e'/></svg>");
  background-size:14px 14px;background-repeat:no-repeat;background-position:center;
  border:1px solid rgba(255,255,255,0.06);
}
/* Welcome message gets the same avatar treatment for visual consistency. */
.coach-msg.welcome{padding-left:38px}
.coach-msg.welcome::before{
  content:'';position:absolute;left:10px;top:11px;
  width:18px;height:18px;border-radius:50%;
  background:rgba(255,255,255,0.04);
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M4 40 C 4 22, 28 14, 42 20 L 58 6 L 56 28 C 62 32, 62 50, 46 54 C 28 58, 8 54, 4 40 Z' fill='%23ffffff' opacity='0.65'/><circle cx='44' cy='34' r='2.6' fill='%230a0a0e'/></svg>");
  background-size:14px 14px;background-repeat:no-repeat;background-position:center;
  border:1px solid rgba(255,255,255,0.06);
}
/* Streaming "typing" caret — a subtle blinking bar appended via .streaming
   class on a bot message while tokens arrive. Removed when stream completes. */
.coach-msg.bot.streaming::after{
  content:'';display:inline-block;width:2px;height:14px;
  background:var(--accent);margin-left:3px;vertical-align:middle;
  animation:blink 1s step-end infinite;
}
@keyframes blink{50%{opacity:0}}
.train-coach-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.coach-chip{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:0.6px;
  padding:6px 10px;border:1px solid var(--line);border-radius:999px;
  color:var(--text2);background:transparent;cursor:pointer;
}
.coach-chip:hover{border-color:var(--accent);color:var(--accent)}
/* Accent variant for the "build me a program" chip — distinguishes the
   action-style entry point from the Q&A chips beneath it. Uses a subtle
   accent fill instead of the standard transparent background. */
.coach-chip-accent{
  border-color:rgba(255,59,31,0.4);
  background:rgba(255,59,31,0.08);
  color:var(--accent);
}
.coach-chip-accent:hover{border-color:var(--accent);background:rgba(255,59,31,0.15);color:var(--accent)}

/* ─── Program view (full-screen) ─── */
.program-view-head{
  display:flex;align-items:flex-start;gap:14px;
  padding:calc(20px + env(safe-area-inset-top)) 18px 18px;
  border-bottom:1px solid rgba(255,255,255,0.05);
}
.program-view-close{
  width:36px;height:36px;border-radius:50%;flex-shrink:0;
  background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);
  color:var(--text);font-size:22px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:background var(--dur-base) var(--ease-out);
}
.program-view-close:hover{background:rgba(255,255,255,0.08)}
.program-view-body{padding:18px}
.program-day{
  background:var(--surface);border:1px solid rgba(255,255,255,0.05);border-radius:16px;
  padding:18px;margin-bottom:12px;
  box-shadow:0 2px 16px rgba(0,0,0,0.18),inset 0 1px 0 rgba(255,255,255,0.04);
  transition:border-color var(--dur-base) var(--ease-out);
}
.program-day-today{border-color:rgba(255,59,31,0.3);box-shadow:0 0 0 1px rgba(255,59,31,0.15),0 4px 20px rgba(255,59,31,0.08)}
.program-day-rest{opacity:0.65}
.program-day-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
.program-day-day{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);letter-spacing:1.4px;text-transform:uppercase}
.program-day-type{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;letter-spacing:0.4px;color:var(--text);text-transform:uppercase;line-height:1}
.program-day-meta{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text2);letter-spacing:0.4px;margin-top:4px}
.program-day-today-badge{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:600;color:var(--accent);background:rgba(255,59,31,0.12);border:1px solid rgba(255,59,31,0.3);border-radius:999px;padding:3px 8px;letter-spacing:1px;text-transform:uppercase;flex-shrink:0}
.program-ex{
  display:grid;grid-template-columns:1fr auto;gap:8px 14px;align-items:baseline;
  padding:10px 0;border-top:1px solid rgba(255,255,255,0.04);
}
.program-ex:first-child{border-top:none}
.program-ex-name{font-family:'Inter',sans-serif;font-size:13px;font-weight:600;color:var(--text);line-height:1.3}
.program-ex-notes{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);margin-top:3px;letter-spacing:0.3px;line-height:1.4}
.program-ex-prescription{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text2);letter-spacing:0.3px;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.program-day-cta{margin-top:14px}

/* v2 — exercise swap affordance + inline loading spinner + swap-modal
   options. Swap icon is the small ⇄ glyph next to exercise names that
   have alternatives; the row gets a subtle hover state to telegraph that
   it's tappable. */
.program-ex-swap-icon{
  display:inline-block;margin-left:6px;
  color:var(--text3);font-size:11px;font-weight:400;
  transition:color var(--dur-base) var(--ease-out);
}
.program-ex[onclick]:hover{background:rgba(255,255,255,0.02);border-radius:8px}
.program-ex[onclick]:hover .program-ex-swap-icon{color:var(--accent)}
.program-swap-opt{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:14px 16px;background:rgba(255,255,255,0.03);
  border:1px solid rgba(255,255,255,0.06);border-radius:14px;
  font-family:'Inter',sans-serif;font-size:14px;font-weight:600;color:var(--text);
  cursor:pointer;text-align:left;
  transition:background var(--dur-base) var(--ease-out),border-color var(--dur-base) var(--ease-out);
}
.program-swap-opt:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12)}
.program-swap-opt:active{transform:scale(0.98)}
/* Inline loader spinner — sits inside #program-inline-loading on the train tab. */
.program-spinner{
  width:36px;height:36px;flex-shrink:0;
  border:3px solid rgba(255,255,255,0.08);
  border-top-color:var(--accent);
  border-radius:50%;
  animation:spin 0.8s linear infinite;
}

/* Recovery mirror */
.train-recovery-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
@media(max-width:560px){.train-recovery-tiles{grid-template-columns:repeat(2,1fr);gap:8px}}
.train-recovery-tile{
  display:flex;flex-direction:column;gap:4px;align-items:flex-start;
  padding:14px;border:1px solid var(--line);border-radius:var(--radius);
  background:transparent;cursor:pointer;text-align:left;
  transition:border-color 0.15s;
}
.train-recovery-tile:hover{border-color:var(--line2)}
.train-recovery-label{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:1.4px;color:var(--text2)}
.train-recovery-num{font-family:'Bebas Neue','Inter',sans-serif;font-size:32px;font-weight:400;line-height:0.9;color:var(--text);font-variant-numeric:tabular-nums}
.train-recovery-goal{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text3);letter-spacing:0.4px}

/* ─── Train sheet (full-viewport panel; mirrors food/wellness sheet) ─── */
/* Backdrop is no longer used — sheet sits between header (top) and bottom-nav
   (bottom) so navigation stays visible. Hide it so legacy markup is harmless. */
#train-sheet-backdrop.sheet-backdrop{display:none !important}
#train-sheet.sheet{
  /* Full-viewport opaque panel. JS sets `top` (header bottom) and `bottom`
     (bottom-nav top) dynamically via positionSheetBelowHeader() so both
     chrome regions remain visible. The sheet IS the scroll container. */
  position:fixed;top:0;left:0;right:0;bottom:0;z-index:1500;display:none;
  background:var(--bg);
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  animation:fadeIn 0.18s ease;
}
#train-sheet.sheet.open{display:block}
#train-sheet .sheet-head{
  display:flex;align-items:center;justify-content:space-between;
  /* Top padding bakes in env(safe-area-inset-top) so the title clears the
     iOS notch / status bar on iPhone PWAs. Matches the equivalent rule on
     .food-sheet-head — both sheets need this since the page header is
     display:none while a sheet is open (via body.sheet-open .header rule). */
  padding:calc(14px + env(safe-area-inset-top)) 20px 12px;
  border-bottom:1px solid var(--line);
  position:sticky;top:0;background:var(--bg);z-index:5;
  margin-bottom:6px;
}
#train-sheet .sheet-title{font-family:'Bebas Neue','Inter',sans-serif;font-size:22px;letter-spacing:0.02em;text-transform:uppercase}
#train-sheet .sheet-close{
  background:transparent;border:1px solid var(--line);color:var(--text);
  width:36px;height:36px;border-radius:8px;font-size:18px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
#train-sheet .sheet-body{padding:18px 20px calc(28px + env(safe-area-inset-bottom))}
#train-sheet textarea{
  width:100%;background:transparent;border:1px solid var(--line);border-radius:var(--radius-sm,2px);
  padding:14px 14px;color:var(--text);font-size:13px;font-family:'Inter',sans-serif;
  line-height:1.55;resize:vertical;outline:none;min-height:84px;
  transition:border-color 0.12s;
}
#train-sheet textarea::placeholder{color:var(--text3)}
#train-sheet textarea:focus{border-color:var(--text2)}

/* ─── Train sheet — editorial layout, generous breathing room ───
   Sections separated by hairline rules. Section labels lead with a small
   accent tick. Controls lean light (subtle borders, restrained padding)
   so the orange ACTIVE state pops without the rest fighting for attention. */
.train-sheet-label{
  font-family:'JetBrains Mono',monospace;
  font-size:10px;font-weight:500;letter-spacing:2px;text-transform:uppercase;
  color:var(--text3);
  display:flex;align-items:center;gap:12px;
  margin:36px 0 16px;
  padding-top:24px;
  border-top:1px solid var(--line);
}
.train-sheet-label::before{
  content:'';width:18px;height:1px;background:var(--accent);flex-shrink:0;
}
.train-sheet-label:first-child{margin-top:0;padding-top:0;border-top:none}

/* Apple-Health-style segmented control — recessed track with a raised
   active tile. Used for the Train sheet's Lift / Run-Cardio mode toggle
   AND for the Today / Yesterday backfill toggles in the Food + Train
   sheets (via the .seg-toggle alias). One ruleset, three call sites. */
.train-mode-toggle, .seg-toggle{
  display:grid;grid-template-columns:repeat(2,1fr);gap:4px;
  background:var(--bg2,#0f1216);
  border:1px solid var(--line);
  border-radius:14px;
  padding:4px;
}
.train-mode-btn, .seg-toggle-btn{
  font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:500;
  letter-spacing:1.4px;text-transform:uppercase;
  padding:11px 6px;
  border:0;border-radius:10px;
  color:var(--text2);background:transparent;cursor:pointer;
  transition:background 0.15s,color 0.15s,box-shadow 0.15s;
  text-align:center;
}
.train-mode-btn:hover, .seg-toggle-btn:hover{color:var(--text)}
.train-mode-btn.active, .seg-toggle-btn.active{
  background:var(--bg);
  color:var(--text);
  font-weight:700;
  box-shadow:0 1px 2px rgba(0,0,0,0.35),0 0 0 1px var(--line2);
}

/* Add breathing room between the mode toggle and the first label inside
   each mode panel ("Day type" for lift, "Activity" for cardio). The label's
   own margin-top would normally collapse through the wrapper; giving the
   wrapper padding-top prevents the collapse and adds the visual gap. */
#train-mode-lift,
#train-mode-cardio{padding-top:14px}

/* Distance input — single line, KM unit on the right, JetBrains for the
   numeric display. Mirrors the duration display vibe but compact. */
.train-distance-row{
  display:flex;align-items:center;gap:14px;
  margin:6px 0 4px;
  padding:14px 18px;
  border:1px solid var(--line);border-radius:14px;
  background:var(--bg2,#0f1216);
}
.train-distance-row input{
  flex:1;
  background:transparent;border:0;outline:0;
  font-family:'Bebas Neue','Inter',sans-serif;
  font-size:38px;line-height:1;color:var(--text);
  font-variant-numeric:tabular-nums;
  letter-spacing:0.01em;
  padding:0;margin:0;
  -moz-appearance:textfield;
}
.train-distance-row input::-webkit-outer-spin-button,
.train-distance-row input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.train-distance-row input::placeholder{color:var(--text3)}
.train-distance-unit{
  font-family:'JetBrains Mono',monospace;
  font-size:11px;color:var(--text3);
  letter-spacing:1.6px;text-transform:uppercase;font-weight:500;
}

/* Day-type pills — slimmer, lighter borders, even spacing */
.train-type-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
@media(max-width:440px){.train-type-grid{grid-template-columns:repeat(3,1fr);gap:6px}}
.train-type-pill{
  font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:500;
  letter-spacing:1.2px;text-transform:uppercase;
  padding:11px 4px;
  border:1px solid var(--line);border-radius:var(--radius-sm,2px);
  color:var(--text2);background:transparent;cursor:pointer;
  transition:border-color 0.12s,color 0.12s,background 0.12s;
  text-align:center;
}
.train-type-pill:hover{border-color:var(--line2);color:var(--text)}
.train-type-pill.active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:700}

/* Muscle chips — auto-fit grid so rows are evenly aligned */
.train-muscle-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(82px, 1fr));
  gap:8px;
}
.train-muscle-chip{
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;
  letter-spacing:1.2px;text-transform:uppercase;
  padding:9px 6px;
  border:1px solid var(--line);border-radius:999px;
  color:var(--text2);background:transparent;cursor:pointer;
  transition:background 0.12s,color 0.12s,border-color 0.12s;
  text-align:center;
}
.train-muscle-chip:hover{border-color:var(--line2);color:var(--text)}
.train-muscle-chip.active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:700}

/* Duration — display centered with steppers, presets below tightly aligned */
.train-duration-row{
  display:flex;align-items:center;justify-content:center;
  gap:28px;margin:6px 0 18px;
}
.train-dur-btn{
  width:44px;height:44px;border-radius:var(--radius-sm,2px);
  background:transparent;border:1px solid var(--line2);color:var(--text);
  font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:600;cursor:pointer;
  /* touch-action:manipulation kills the 300ms tap-delay on iOS Safari that
     made rapid taps feel laggy. transition:transform on a tight curve adds
     tactile press feedback — 70ms is fast enough to feel "instant" but
     visible enough to confirm the tap. (2026-05-11 anti-rage-click pass.) */
  touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;
  transition:transform 70ms ease-out,background 70ms ease-out,border-color 120ms ease-out,color 120ms ease-out;
  transition:border-color 0.12s,color 0.12s;
}
.train-dur-btn:hover{border-color:var(--accent);color:var(--accent)}
.train-dur-btn:active{transform:scale(0.92);background:rgba(255,59,31,0.12);border-color:var(--accent);color:var(--accent)}

/* Food portion-stepper circular −/+ buttons.
   Bumped from 42 → 44px (Apple HIG minimum) and given a tight :active
   press state because rage-click telemetry on May 11 showed 5 users
   mashing these buttons 22+ times in 7 days — the old inline styles had
   :hover but no :active, so on touch devices nothing visually responded
   to the tap. (2026-05-11 anti-rage-click pass.) */
.qty-step{
  width:44px;height:44px;border-radius:50%;
  background:rgba(255,255,255,0.04);
  border:1px solid rgba(255,255,255,0.08);
  color:var(--text);
  font-size:22px;font-weight:300;
  cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;
  transition:transform 70ms ease-out,background 70ms ease-out,border-color 120ms ease-out;
}
.qty-step:hover{background:rgba(255,255,255,0.08);border-color:rgba(255,255,255,0.14)}
.qty-step:active{
  transform:scale(0.90);
  background:rgba(255,59,31,0.15);
  border-color:var(--accent);
  color:var(--accent);
}
.train-dur-display{
  font-family:'Bebas Neue','Inter',sans-serif;
  font-size:64px;line-height:0.9;color:var(--text);
  display:flex;align-items:baseline;gap:8px;
  font-variant-numeric:tabular-nums;
  min-width:140px;text-align:center;justify-content:center;
  letter-spacing:0.01em;
}
/* Phantom mirror "min" on the LEFT, same metrics as the visible unit on
   the right. This balances the flex row so the NUMBER sits truly centered
   between the −5 / +5 steppers, instead of being skewed left by the unit
   label. visibility:hidden keeps it out of the picture but reserves space. */
.train-dur-display::before{
  content:"min";
  font-size:11px;
  font-family:'JetBrains Mono',monospace;
  letter-spacing:1.6px;text-transform:uppercase;font-weight:500;
  visibility:hidden;
  pointer-events:none;
}
.train-dur-unit{
  font-size:11px;color:var(--text3);font-family:'JetBrains Mono',monospace;
  letter-spacing:1.6px;text-transform:uppercase;font-weight:500;
}
.train-dur-quick{display:flex;gap:6px;justify-content:center;flex-wrap:wrap}
.dur-quick-btn{
  font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:500;letter-spacing:1px;
  padding:6px 12px;border:1px solid var(--line);border-radius:999px;
  color:var(--text3);background:transparent;cursor:pointer;
  touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;
  transition:transform 70ms ease-out,background 70ms ease-out,border-color 120ms ease-out,color 120ms ease-out;
  min-width:44px;
  transition:border-color 0.12s,color 0.12s;
}
.dur-quick-btn:hover{border-color:var(--accent);color:var(--accent)}
.dur-quick-btn:active{transform:scale(0.94);background:rgba(255,255,255,0.06)}
.dur-quick-btn.active{border-color:var(--text);color:var(--text)}

/* Intensity — slimmer 4-up row, same hierarchy as day type */
.train-intensity-row{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.train-int-btn{
  font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:500;
  letter-spacing:1.2px;text-transform:uppercase;
  padding:11px 4px;border:1px solid var(--line);border-radius:var(--radius-sm,2px);
  color:var(--text2);background:transparent;cursor:pointer;
  transition:border-color 0.12s,color 0.12s;
  text-align:center;
}
.train-int-btn:hover{border-color:var(--line2);color:var(--text)}
.train-int-btn.active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:700}

/* Save button — generous breathing space above */
#train-save-btn{margin-top:32px !important;height:52px;font-size:13px;letter-spacing:1.6px}

/* Pod comparison — train tab */
.pod-train-compare{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.pod-train-row{
  display:grid;grid-template-columns:auto 1fr auto auto;gap:12px;align-items:center;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius);
}
.pod-train-row .rank{font-family:'Bebas Neue','Inter',sans-serif;font-size:20px;color:var(--accent);min-width:24px;text-align:center}
.pod-train-row .who{font-family:'Inter',sans-serif;font-size:14px;color:var(--text);font-weight:600}
.pod-train-row .who small{display:block;font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--text3);letter-spacing:0.6px;font-weight:400;margin-top:2px}
.pod-train-row .num{font-family:'Bebas Neue','Inter',sans-serif;font-size:22px;color:var(--text)}
.pod-train-row .unit{font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--text3);letter-spacing:0.6px;text-transform:uppercase}

/* Train sheet — anatomical body viewer (image + invisible hotspot overlay).
   Image swaps based on userProfile.gender (man / woman). Hotspots glow gold when a muscle chip is active. */
.train-body-views{
  display:flex;
  justify-content:center;
  margin:18px 0 24px;
  padding:8px;
  border:1px solid rgba(255,255,255,0.06);
  border-radius:18px;
  background:rgba(0,0,0,0.45);
}
.train-body-image-wrap{
  position:relative;
  width:100%;
  max-width:380px;
  /* Match image aspect ratio (1024×1536 = 2:3) so overlay aligns pixel-perfect */
  aspect-ratio:1024/1536;
  display:block;
}
.train-body-img{
  display:block;
  width:100%;
  height:100%;
  object-fit:contain;
  user-select:none;
  -webkit-user-drag:none;
  filter:grayscale(0.85) brightness(0.78) contrast(1.05);
}
.train-body-overlay{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  pointer-events:none;
}
.train-body-overlay [data-mus]{
  fill:transparent;
  stroke:none;
  transition:fill 0.32s ease, filter 0.32s ease, opacity 0.32s ease;
  opacity:0;
}
.train-body-overlay [data-mus].active{
  fill:url(#hotspot-grad);
  filter:url(#hotspot-glow) drop-shadow(0 0 24px rgba(230,57,70,0.75)) drop-shadow(0 0 48px rgba(230,57,70,0.45));
  opacity:1;
  mix-blend-mode:screen;
  animation:hotspot-pulse 1.6s ease-in-out infinite;
}
@keyframes hotspot-pulse{
  0%,100%{ filter:url(#hotspot-glow) drop-shadow(0 0 24px rgba(230,57,70,0.75)) drop-shadow(0 0 48px rgba(230,57,70,0.45)); }
  50%{ filter:url(#hotspot-glow) drop-shadow(0 0 32px rgba(230,57,70,0.95)) drop-shadow(0 0 64px rgba(230,57,70,0.65)); }
}

/* Voice mic button — listening state. The mic button glows accent and
   pulses while webkitSpeechRecognition is active, so the user knows the
   mic is hot AND that tapping it again will cancel the recording. The
   pulse is a ring expanding outward — same idiom iOS uses for active
   recording so the affordance reads instantly. */
.btn.voice-listening{
  color: var(--accent) !important;
  border-color: var(--accent) !important;
  animation: voice-pulse 1.2s ease-in-out infinite;
}
@keyframes voice-pulse{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(255, 59, 31, 0.45); }
  50%     { box-shadow: 0 0 0 6px rgba(255, 59, 31, 0); }
}

/* ═══════════════════════════════════════════════════════════════
   COMPONENT PRIMITIVES — scrub input
   added 2026-05-19. ports of componentry components to vanilla.
   not auto-rendered anywhere yet — instantiate new ScrubInput(...)
   where needed.
═══════════════════════════════════════════════════════════════ */

/* ─── SCRUB INPUT ───
   Pill-shaped draggable number. JS class adds .scrubbing during
   the drag. Defaults size matches the body-text Bebas Neue used
   elsewhere in the app. Suffix/prefix slots render small, gray. */
.scrub-input{
  display:inline-flex; align-items:baseline; gap:4px;
  padding:6px 14px;
  background:var(--bg2);
  border:1px solid var(--border2);
  border-radius:999px;
  font-family:'Bebas Neue',Impact,sans-serif;
  font-size:28px; line-height:1;
  color:var(--text);
  cursor:ew-resize;
  user-select:none;
  /* swallow scroll on touch — required for drag to register cleanly
     on the food/training pages where the user might otherwise
     accidentally pull-to-refresh or scroll vertically */
  touch-action:none;
  transition:border-color 160ms var(--ease-out),
             background 160ms var(--ease-out);
  font-variant-numeric:tabular-nums;
  -webkit-tap-highlight-color:transparent;
}
.scrub-input:hover{ border-color:var(--accent); }
.scrub-input.scrubbing{
  border-color:var(--accent);
  background:rgba(255,59,31,0.08);
}
.scrub-prefix,.scrub-suffix{
  color:var(--text3); font-size:12px;
  letter-spacing:0.05em; text-transform:uppercase;
  font-family:'Inter',sans-serif;
  position:relative; top:-2px;
}
/* modifier — leaderboard-scale variant for hero pill displays */
.scrub-input--big{ font-size:44px; padding:8px 18px; }

/* ── Saved meals CTA card (2026-06-30) ─────────────────────────
   Replaces the easy-to-miss "view all (N)" text link on the LOG FOOD
   sheet with a bold, tappable card so people actually notice their
   saved meals. Accent used intentionally as a "quick-log this" heat cue. */
.saved-meals-cta{
  display:flex;align-items:center;gap:12px;width:100%;text-align:left;cursor:pointer;
  background:var(--bg2);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px;margin-top:8px;
  transition:border-color .15s ease,background .15s ease,transform .08s ease;
  -webkit-tap-highlight-color:transparent;appearance:none;-webkit-appearance:none;
}
.saved-meals-cta:hover{border-color:var(--accent);background:rgba(255,59,31,0.055)}
.saved-meals-cta:active{transform:scale(0.99)}
.saved-meals-cta.is-empty{cursor:default;pointer-events:none;opacity:0.7}
.saved-meals-cta.is-empty .sm-cta-icon{opacity:0.6}
.saved-meals-cta .sm-cta-icon{
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  width:36px;height:36px;border-radius:9px;
  background:rgba(255,59,31,0.12);color:var(--accent);
}
.saved-meals-cta .sm-cta-icon svg{width:19px;height:19px}
.saved-meals-cta .sm-cta-text{display:flex;flex-direction:column;min-width:0;flex:1}
.saved-meals-cta .sm-cta-title{
  font-family:'Bebas Neue','Inter',sans-serif;font-weight:800;letter-spacing:0.05em;
  font-size:16px;line-height:1.1;color:var(--text);text-transform:uppercase;
}
.saved-meals-cta .sm-cta-sub{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:0.5px;
  color:var(--text2);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.saved-meals-cta .sm-cta-chev{color:var(--accent);font-size:20px;font-weight:700;flex-shrink:0;line-height:1}
