/* ============================================================
   styles.css — iOS-style glass UI, RTL-aware, light + dark
   ============================================================ */

:root {
  color-scheme: light dark;

  /* mesh backdrop — glass needs something behind it to refract */
  --mesh-1: #6ee7b7;
  --mesh-2: #38bdf8;
  --mesh-3: #a78bfa;
  --mesh-4: #fcd34d;
  --page:   #eef2f0;

  --text:      #0f1a17;
  --text-dim:  #5b6b66;
  --text-mute: #8a9a95;

  /* the glass itself */
  --glass:        rgba(255, 255, 255, .62);
  --glass-strong: rgba(255, 255, 255, .78);
  --glass-sunk:   rgba(255, 255, 255, .38);
  --hairline:     rgba(255, 255, 255, .65);
  --hairline-dim: rgba(15, 26, 23, .07);
  --shadow:       0 1px 1px rgba(15,26,23,.04), 0 8px 28px rgba(15,26,23,.09);
  --shadow-lift:  0 2px 6px rgba(15,26,23,.06), 0 18px 48px rgba(15,26,23,.14);

  --accent:      #0e9c8f;
  --accent-2:    #3dd598;
  --accent-ink:  #0b6b62;
  --accent-wash: rgba(14, 156, 143, .12);

  /* end-of-day verdict tones */
  --ds-good:  #0b6b62;
  --ds-mixed: #b45309;
  --ds-bad:   #be123c;

  --water:   #38bdf8;
  --move:    #fb923c;
  --veg:     #4ade80;
  --coffee:  #a97142;
  --sleep:   #818cf8;
  --resist:  #f472b6;
  --med:     #22d3ee;
  --gold:    #eab308;
  --danger:  #e11d48;
  --warn:    #d97706;

  --r-xl: 28px;
  --r-lg: 22px;
  --r-md: 16px;
  --r-sm: 12px;

  --font: 'SF Pro Text', 'SF Pro Display', -apple-system, BlinkMacSystemFont,
          system-ui, 'Segoe UI', Roboto, sans-serif;
  --font-ar: 'SF Arabic', 'SF Arabic Text', -apple-system, BlinkMacSystemFont,
             'Geeza Pro', 'Noto Naskh Arabic', 'Noto Sans Arabic', Tahoma, sans-serif;
  --ease: cubic-bezier(.32, .72, 0, 1);
}

/* Dark tokens live in three places on purpose:
   · the media query, for anyone who has not chosen (guarded so an
     explicit "light" choice still wins)
   · the [data-theme="dark"] block, for an explicit choice
   Keeping them in sync matters — change one, change the other. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --mesh-1: #065f52;
    --mesh-2: #0c4a6e;
    --mesh-3: #4c1d95;
    --mesh-4: #78350f;
    --page:   #070b0a;

    --text:      #f0f5f3;
    --text-dim:  #a3b3ae;
    --text-mute: #6b7b76;

    --glass:        rgba(30, 41, 38, .58);
    --glass-strong: rgba(38, 50, 46, .74);
    --glass-sunk:   rgba(12, 20, 18, .42);
    --hairline:     rgba(255, 255, 255, .10);
    --hairline-dim: rgba(255, 255, 255, .07);
    --shadow:       0 1px 1px rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.42);
    --shadow-lift:  0 2px 8px rgba(0,0,0,.4), 0 22px 54px rgba(0,0,0,.55);

    --accent:      #3dd598;
    --accent-2:    #6ee7b7;
    --accent-ink:  #9df3cf;
    --accent-wash: rgba(61, 213, 152, .14);

    --ds-good:  #6ee7b7;
    --ds-mixed: #fbbf24;
    --ds-bad:   #fb7185;

    --ds-good:  #6ee7b7;
    --ds-mixed: #fbbf24;
    --ds-bad:   #fb7185;
  }
}

:root[data-theme="dark"] {
    --mesh-1: #065f52;
    --mesh-2: #0c4a6e;
    --mesh-3: #4c1d95;
    --mesh-4: #78350f;
    --page:   #070b0a;

    --text:      #f0f5f3;
    --text-dim:  #a3b3ae;
    --text-mute: #6b7b76;

    --glass:        rgba(30, 41, 38, .58);
    --glass-strong: rgba(38, 50, 46, .74);
    --glass-sunk:   rgba(12, 20, 18, .42);
    --hairline:     rgba(255, 255, 255, .10);
    --hairline-dim: rgba(255, 255, 255, .07);
    --shadow:       0 1px 1px rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.42);
    --shadow-lift:  0 2px 8px rgba(0,0,0,.4), 0 22px 54px rgba(0,0,0,.55);

    --accent:      #3dd598;
    --accent-2:    #6ee7b7;
    --accent-ink:  #9df3cf;
    --accent-wash: rgba(61, 213, 152, .14);
}

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

html, body {
  margin: 0; padding: 0;
  min-height: 100%;
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Both axes: sideways is what the phone's edge-swipe rides on, and
     letting it through means a stray horizontal drag walks out of the
     app entirely. */
  overscroll-behavior: contain;
}
html[dir="rtl"] body { font-family: var(--font-ar); }

/* The page colour lives on <html>; <body> stays transparent so the
   negative z-index mesh shows through it rather than being painted over. */
html { background: var(--page); }
body { background: transparent; }

/* ---------- mesh backdrop ---------- */
/* The colour is masked away from the top third, so the greeting and the
   first card sit on a plain background instead of a wash. */
#mesh {
  position: fixed; inset: -20vh -20vw; z-index: -1;
  pointer-events: none;
  filter: blur(64px) saturate(150%);
  opacity: .5;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 30%, #000 62%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0, transparent 30%, #000 62%, #000 100%);
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) #mesh { opacity: .5; } }
:root[data-theme="dark"] #mesh { opacity: .5; }
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
#mesh i {
  position: absolute; display: block;
  border-radius: 50%;
  animation: drift 26s var(--ease) infinite alternate;
}
#mesh i:nth-child(1) { width: 58vw; height: 58vw; left: -6vw;  top: -4vh;  background: var(--mesh-1); }
#mesh i:nth-child(2) { width: 52vw; height: 52vw; right: -8vw; top: 12vh;  background: var(--mesh-2); animation-delay: -6s; }
#mesh i:nth-child(3) { width: 60vw; height: 60vw; left: 4vw;   bottom: 2vh; background: var(--mesh-3); animation-delay: -13s; opacity: .8; }
#mesh i:nth-child(4) { width: 40vw; height: 40vw; right: 2vw;  bottom: 14vh; background: var(--mesh-4); animation-delay: -19s; opacity: .6; }

@keyframes drift {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(4vw, 6vh, 0) scale(1.16); }
}
@media (prefers-reduced-motion: reduce) {
  #mesh i { animation: none; }
}

/* ---------- shell ---------- */
#app {
  max-width: 560px;
  margin: 0 auto;
  padding: 0 15px calc(104px + env(safe-area-inset-bottom));
}

/* Plain greeting, no bar — it scrolls away with the content. */
.topbar {
  display: flex; align-items: center; gap: 12px;
  padding: calc(16px + env(safe-area-inset-top)) 2px 12px;
  background: none;
}
.topbar .brand { flex: 1; min-width: 0; }
.topbar h1 {
  font-size: 1.5rem; margin: 0; letter-spacing: -.022em; font-weight: 700;
}
.topbar .sub { font-size: .8rem; color: var(--text-dim); margin-top: 2px; }

/* ---------- glass primitives ---------- */
.glass {
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}

.card {
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
  border-radius: var(--r-lg);
  padding: 16px;
  margin-bottom: 12px;
}
.card.tall { padding: 20px 16px; }
.card.flush { padding: 0; overflow: hidden; }

/* a small icon action in the card's trailing top corner */
.card.with-corner-end { position: relative; }
/* keep the header text clear of the icon */
.card.with-corner-end > .card-head { padding-inline-end: 44px; }
.icon-corner {
  position: absolute; top: 12px; inset-inline-end: 12px; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text-dim); transition: .16s var(--ease);
}
.icon-corner:active { transform: scale(.92); }
.icon-corner svg { width: 18px; height: 18px; }
/* an unread dot when the readings have never been entered */
.icon-corner .dot {
  position: absolute; top: 1px; inset-inline-end: 1px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--glass-strong);
}

.card > h2, .card-head h2, .section-label {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-mute); margin: 0 0 12px; font-weight: 700;
}
html[dir="rtl"] .card > h2,
html[dir="rtl"] .card-head h2,
html[dir="rtl"] .section-label { letter-spacing: 0; }

.card-head {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px;
}
.card-head h2 { margin: 0; flex: 1; }
.card-head .sub { font-size: .74rem; color: var(--text-mute); font-weight: 600; }

/* standalone label above a run of goal cards */
.section-label { display: block; padding: 4px 4px 8px; margin: 0; }

.hero-title { font-size: 1.05rem; font-weight: 650; letter-spacing: -.01em; }

/* ---------- language switch ---------- */
.langtoggle {
  display: flex; gap: 2px; padding: 3px; border-radius: 999px;
  background: var(--glass-sunk);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--hairline);
}
.langtoggle button {
  padding: 5px 13px; border-radius: 999px; border: none; background: none;
  font: inherit; font-size: .78rem; font-weight: 650; color: var(--text-dim);
  cursor: pointer; transition: .18s var(--ease);
}
.langtoggle button.on {
  background: var(--glass-strong); color: var(--text);
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
}

/* ---------- liver widget ---------- */
.liver-stage {
  position: relative;
  display: grid; place-items: center;
  padding: 6px 0 2px;
  perspective: 900px;
}
.liver-tilt {
  transform-style: preserve-3d;
  animation: liverFloat 9s var(--ease) infinite alternate;
  will-change: transform;
}
@keyframes liverFloat {
  from { transform: rotateY(-13deg) rotateX(7deg) translateY(-3px); }
  to   { transform: rotateY(13deg)  rotateX(-4deg) translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .liver-tilt { animation: none; transform: none; }
}
.liver-stage svg { display: block; width: 100%; max-width: 280px; height: auto; overflow: visible; }

.liver-glow {
  position: absolute; inset: 12% 16%; z-index: -1;
  border-radius: 50%;
  filter: blur(34px);
  opacity: .55;
}

/* readout: score leading, grade badges stacked trailing */
.liver-readout {
  display: flex; align-items: center; gap: 14px;
  margin-top: 10px;
}
.liver-score-block { flex: 1; min-width: 0; }
.liver-score { font-size: 2.5rem; font-weight: 700; letter-spacing: -.035em; line-height: 1; }
.liver-score small { font-size: .95rem; font-weight: 600; color: var(--text-mute); }
.liver-stage-label { font-size: .82rem; color: var(--text-dim); margin-top: 5px; line-height: 1.3; }

.liver-badges {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px;
  align-items: flex-end;
}
.liver-badges .badge { white-space: nowrap; }

/* ---------- goal cards: bento grid ---------- */
.bento {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 12px;
}

.goal {
  display: flex; align-items: center; gap: 13px;
  padding: 14px;
  border-radius: var(--r-lg);
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
  transition: transform .2s var(--ease);
}
.goal.done { border-color: color-mix(in srgb, var(--c) 45%, transparent); }
.goal:active { transform: scale(.992); }

/* the wide tile spans the grid — used for the 8-cup water goal */
.goal.wide { grid-column: 1 / -1; }

/* compact tiles stack vertically so two fit per row */
.goal.tile {
  flex-direction: column; align-items: stretch; gap: 0;
  padding: 13px;
}
.goal.tile .goal-top {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 7px;
}
.goal.tile .goal-body { flex: 0 0 auto; }
.goal.tile .goal-name { font-size: .87rem; line-height: 1.25; }
.goal.tile .goal-count { font-size: .76rem; }
.goal.tile .goal-actions { gap: 8px; }   /* 8 - 2 - 2 = 4px clear between hit areas */
/* 40 drawn, 44 tapped. A full 44px circle crowds the half-width tile
   next to the dial, so the visible control stays smaller and the hit
   area is padded out to the minimum — the 8px gap leaves 4px clear
   between the minus and the plus, so the two never overlap. */
.goal.tile .stepper { width: 40px; height: 40px; font-size: 1rem; }
.goal.tile .stepper::after { content: ''; position: absolute; inset: -2px; }
.goal.tile .pips { margin-top: 7px; }

.goal-dial { position: relative; flex: 0 0 auto; width: 54px; height: 54px; }
/* Direct child only: this rotation starts the progress ring at twelve
   o'clock, and must not reach the icon nested inside .glyph — which it
   did, quietly rendering every goal icon on its side. */
.goal-dial > svg { transform: rotate(-90deg); display: block; }
html[dir="rtl"] .goal-dial > svg { transform: rotate(-90deg) scaleY(-1); }
.goal-dial .glyph {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 1.15rem; line-height: 1;
}
.goal.tile .goal-dial { width: 44px; height: 44px; }
.goal.tile .goal-dial .glyph { font-size: 1rem; }

.goal-body { flex: 1; min-width: 0; }
.goal-name { font-weight: 650; font-size: .96rem; letter-spacing: -.01em; }
.goal-count { font-size: .8rem; color: var(--text-dim); margin-top: 1px; }
.goal-count b { color: var(--c); font-weight: 700; }

.goal-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* 44px, not 36. These are the most-tapped controls in the app and they
   sat below both Apple's 44pt and Android's 48dp minimum. Padding the
   hit area instead would have overlapped the minus and plus, which is
   worse than a small target: the tap lands on whichever is on top. */
.stepper {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text); font-size: 1.15rem; font-weight: 600; line-height: 1;
  cursor: pointer; transition: .15s var(--ease);
  font-family: var(--font);
}
.stepper { position: relative; }        /* so the padded hit area anchors */
.stepper:active { transform: scale(.9); }
.stepper.plus { background: color-mix(in srgb, var(--c) 22%, transparent); border-color: color-mix(in srgb, var(--c) 40%, transparent); color: var(--c); }
.stepper:disabled { opacity: .32; cursor: default; }

/* pips — one dot per unit, for small targets like 8 cups */
.pips { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 9px; }
.pip {
  width: 100%; max-width: 22px; height: 8px; border-radius: 999px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  flex: 1 1 14px; transition: .25s var(--ease);
}
.pip.on { background: var(--c); border-color: transparent; box-shadow: 0 0 10px color-mix(in srgb, var(--c) 55%, transparent); }

/* ---------- things to stay away from ----------
   Tiles rather than a checklist: each carries its reason and a running
   clean streak, so marking one is a small win instead of a chore. */
/* All six visible at once, in two rows. This used to carry .hscroll as
   well, whose display:flex won the cascade and turned it into a rail
   that clipped the third tile mid-word — on the section that carries
   two of the day's points. */
.avoid-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
}
.avoid-tile {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 13px 8px 11px; border-radius: var(--r-md); cursor: pointer;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  font: inherit; color: var(--text); text-align: center;
  transition: .2s var(--ease);
}
.avoid-tile:active { transform: scale(.96); }
.avoid-tile.on {
  background: color-mix(in srgb, var(--c) 13%, transparent);
  border-color: color-mix(in srgb, var(--c) 40%, transparent);
}

.avoid-tile .shield {
  position: relative; width: 42px; height: 42px; margin-bottom: 3px;
  display: grid; place-items: center; font-size: 1.35rem; line-height: 1;
  border-radius: 14px;
  background: var(--glass); border: 1px solid var(--hairline);
  filter: grayscale(.55) opacity(.75);
  transition: .2s var(--ease);
}
.avoid-tile.on .shield { filter: none; }
.avoid-tile .seal {
  position: absolute; bottom: -4px; inset-inline-end: -4px;
  width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--c); color: #fff; font-size: .62rem; font-weight: 700;
  font-style: normal; border: 2px solid var(--glass-strong);
  animation: pop .28s var(--ease);
}
@keyframes pop { from { transform: scale(0); } }

.avoid-name { font-size: .78rem; font-weight: 650; line-height: 1.2; }
.avoid-streak {
  font-size: .62rem; font-weight: 700; margin-top: 3px;
  color: var(--text-mute);
}
.avoid-tile.on .avoid-streak { color: var(--c); }

/* ---------- meds ---------- */
.med {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--hairline-dim);
}
.med:last-child { border-bottom: none; }
.med-pill {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 12px;
  display: grid; place-items: center; font-size: 1.05rem;
  background: color-mix(in srgb, var(--med) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--med) 32%, transparent);
}
.med-body { flex: 1; min-width: 0; }
.med-name { font-weight: 650; font-size: .94rem; }
.med.taken .med-name { text-decoration: line-through; color: var(--text-dim); }
.med-dose { font-size: .78rem; color: var(--text-dim); }
.med-time {
  font-size: .78rem; font-weight: 700; color: var(--text-dim);
  font-variant-numeric: tabular-nums; white-space: nowrap;
  align-self: flex-start; padding-top: 2px;
}

/* one chip per dose time, so a twice-daily drug stays a single card */
.dose-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.dose-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 11px; border-radius: 999px; cursor: pointer;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text-dim); font: inherit; font-size: .78rem; font-weight: 650;
  font-variant-numeric: tabular-nums;
  transition: .16s var(--ease);
}
.dose-chip:active { transform: scale(.94); }
.dose-chip .tick { font-size: .72rem; }
.dose-chip.on {
  background: color-mix(in srgb, var(--med) 20%, transparent);
  border-color: color-mix(in srgb, var(--med) 42%, transparent);
  color: var(--text);
}
.dose-chip.on .tick { color: var(--med); }

.med-manage {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 0; border-bottom: 1px solid var(--hairline-dim);
}
.med-manage:last-of-type { border-bottom: none; }
.icon-btn {
  width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center; cursor: pointer;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text-dim); font-size: .95rem;
}
.icon-btn.danger { color: var(--danger); }

/* ---------- generic ---------- */
.bar {
  height: 9px; border-radius: 999px; overflow: hidden;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.bar > i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  transition: width .5s var(--ease);
}
html[dir="rtl"] .bar > i { background: linear-gradient(270deg, var(--accent-2), var(--accent)); }

.btn {
  display: block; width: 100%; text-align: center; cursor: pointer;
  border: none; border-radius: 15px; padding: 15px;
  font: inherit; font-weight: 650; font-size: .96rem;
  color: #fff;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 34%, transparent);
  transition: transform .16s var(--ease);
}
.btn:active { transform: scale(.985); }
.btn.ghost {
  background: var(--glass-sunk); color: var(--text);
  border: 1px solid var(--hairline); box-shadow: none;
}
.btn.danger { background: none; color: var(--danger); border: 1px solid var(--hairline); box-shadow: none; }
.btn.sm { padding: 11px; font-size: .88rem; border-radius: 13px; }

.field { margin-bottom: 12px; }
.field label { display: block; font-size: .78rem; color: var(--text-dim); margin-bottom: 5px; font-weight: 600; }
.field input, .field select, .field textarea {
  width: 100%; padding: 13px; border-radius: 14px;
  border: 1px solid var(--hairline);
  background: var(--glass-sunk);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: var(--text); font: inherit;
}
.field input:focus, .field select:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.row2 { display: flex; gap: 10px; }
.row2 > * { flex: 1; }

.seg { display: flex; gap: 6px; flex-wrap: wrap; }
.seg button {
  flex: 1; min-width: 84px; padding: 11px 8px; border-radius: 13px;
  border: 1px solid var(--hairline); background: var(--glass-sunk);
  font: inherit; font-size: .82rem; font-weight: 600; color: var(--text);
  text-align: center; cursor: pointer; transition: .16s var(--ease);
}
.seg button.on {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: #fff; border-color: transparent;
}
.seg.stack button { flex: 1 1 100%; text-align: start; }

.note { font-size: .78rem; color: var(--text-dim); line-height: 1.55; }
.note.warn { color: var(--warn); }

.kv {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--hairline-dim); font-size: .9rem;
}
.kv:last-child { border-bottom: none; }
.kv span { color: var(--text-dim); }
.kv b { font-weight: 650; white-space: nowrap; }

.badge {
  display: inline-block; font-size: .7rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: var(--accent-wash); color: var(--accent-ink);
}
.badge.gold   { background: color-mix(in srgb, var(--gold) 20%, transparent); color: var(--gold); }
.badge.warn   { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.badge.danger { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }

.quote { font-size: 1rem; line-height: 1.55; font-weight: 550; }

.statrow { display: flex; gap: 8px; margin-top: 12px; }
.stat {
  flex: 1; border-radius: var(--r-md); padding: 10px 8px; text-align: center;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.stat b { display: block; font-size: 1.1rem; letter-spacing: -.02em; }
.stat span { font-size: .66rem; color: var(--text-mute); }

.ring { flex: 0 0 auto; position: relative; width: 96px; height: 96px; }
.ring > svg { transform: rotate(-90deg); }
html[dir="rtl"] .ring > svg { transform: rotate(-90deg) scaleY(-1); }
.ring .val {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px;
  font-size: 1.3rem; font-weight: 700; letter-spacing: -.02em; line-height: 1;
}
.ring .val small {
  font-size: .6rem; font-weight: 600; color: var(--text-mute);
  line-height: 1; letter-spacing: 0;
}

.hero { display: flex; align-items: center; gap: 16px; }
.hero-meta { flex: 1; min-width: 0; }
.hero-meta .big { font-size: 1.55rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; }
.hero-meta .lbl { font-size: .78rem; color: var(--text-dim); }

/* ---------- tab bar ---------- */

/* The hidden attribute is only a user-agent rule, so the display
   declaration below outranks it. Onboarding, the lock screen and the
   sign-in screen all set hidden, and all three had the tab bar sitting
   over them regardless. */
.tabbar[hidden] { display: none; }

.tabbar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 30;
  display: flex; justify-content: center;
  padding: 0 12px calc(10px + env(safe-area-inset-bottom));
  pointer-events: none;
}
.tabbar .inner {
  display: flex; width: 100%; max-width: 330px; pointer-events: auto;
  padding: 6px; border-radius: 999px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(28px) saturate(190%);
  backdrop-filter: blur(28px) saturate(190%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-lift);
}
.tabbar button {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 7px 2px; border: none; background: none; cursor: pointer;
  color: var(--text-mute); font: inherit; font-size: .6rem; font-weight: 650;
  border-radius: 999px; transition: .18s var(--ease);
}
.tabbar button.on { color: var(--accent); background: var(--accent-wash); }
.tabbar svg { width: 21px; height: 21px; }

/* ---------- sheet ---------- */
.sheet-bg {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(8, 14, 12, .38);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  display: flex; align-items: flex-end; justify-content: center;
  animation: fade .2s var(--ease);
}
.sheet {
  width: 100%; max-width: 560px; max-height: 86vh; overflow-y: auto;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: 8px 16px calc(22px + env(safe-area-inset-bottom));
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(30px) saturate(190%);
  backdrop-filter: blur(30px) saturate(190%);
  border: 1px solid var(--hairline); border-bottom: none;
  box-shadow: var(--shadow-lift);
  animation: up .3s var(--ease);
}
.sheet .grabber {
  width: 38px; height: 5px; border-radius: 999px; margin: 6px auto 14px;
  background: var(--text-mute); opacity: .35;
}
.sheet h3 { margin: 0 0 14px; font-size: 1.08rem; letter-spacing: -.015em; }
@keyframes fade { from { opacity: 0 } }
@keyframes up { from { transform: translateY(24px) } }

.opt {
  display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
  padding: 13px; border: 1px solid var(--hairline); border-radius: var(--r-md);
  background: var(--glass-sunk); margin-bottom: 8px; text-align: start; width: 100%;
  font: inherit; color: var(--text);
}
.opt.on { border-color: var(--accent); background: var(--accent-wash); }
.opt-body { flex: 1; min-width: 0; }
.opt-body b { display: block; font-weight: 650; margin-bottom: 3px; }
.opt-body small { color: var(--text-dim); font-size: .77rem; }

/* ---------- chart ---------- */
.chart { width: 100%; height: auto; display: block; overflow: visible; }
.chart .grid { stroke: var(--hairline-dim); stroke-width: 1; }
.chart .line { fill: none; stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.chart .dot { fill: var(--accent); }
.chart .goal { stroke: var(--gold); stroke-width: 1.5; stroke-dasharray: 5 5; }
.chart text {
  fill: var(--text-mute); font-size: 12px; font-family: var(--font);
  font-variant-numeric: tabular-nums;
}
.chart .goal-label { fill: var(--gold); font-weight: 600; }

/* ---------- learn / plan ---------- */
.learn-card { margin-bottom: 14px; }
.learn-card:last-child { margin-bottom: 0; }
.learn-card h3 { margin: 0 0 6px; font-size: .97rem; letter-spacing: -.01em; }
.learn-card p { margin: 0; font-size: .86rem; color: var(--text-dim); line-height: 1.6; }

.dayrow { display: flex; gap: 10px; align-items: baseline; padding: 10px 0; border-bottom: 1px solid var(--hairline-dim); font-size: .85rem; }
.dayrow:last-child { border-bottom: none; }
.dayrow .dname { flex: 0 0 74px; font-weight: 650; color: var(--text-mute); font-size: .76rem; }
.dayrow .dmeals { flex: 1; color: var(--text-dim); }
.dayrow.today .dname { color: var(--accent); }

/* ---------- shopping list ---------- */
.shopcat { margin-bottom: 18px; }
.shopcat:last-child { margin-bottom: 0; }
.shopcat h4 {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 8px; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-mute);
}
html[dir="rtl"] .shopcat h4 { letter-spacing: 0; }
.shop-icon { font-size: .95rem; }

.shop-items {
  border-radius: var(--r-md); overflow: hidden;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.shop-row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 9px 12px; border-bottom: 1px solid var(--hairline-dim);
}
.shop-row:last-child { border-bottom: none; }
.shop-name { flex: 1; min-width: 0; font-size: .85rem; }
.shop-qty {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700; color: var(--accent-ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font-size: .77rem; border-radius: 999px; padding: 5px 11px; color: var(--text-dim);
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}

/* ---------- misc ---------- */
.toast {
  position: fixed; inset-inline: 0; bottom: calc(96px + env(safe-area-inset-bottom));
  z-index: 50; display: flex; justify-content: center; pointer-events: none;
}
.toast > div {
  padding: 11px 20px; border-radius: 999px; font-size: .85rem; font-weight: 600;
  background: var(--glass-strong); color: var(--text);
  -webkit-backdrop-filter: blur(24px) saturate(180%); backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--hairline); box-shadow: var(--shadow-lift);
  animation: up .24s var(--ease);
}

.toggle { position: relative; width: 50px; height: 30px; flex: 0 0 auto; }
.toggle input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; z-index: 2; cursor: pointer; }
.toggle i {
  position: absolute; inset: 0; border-radius: 999px; transition: .22s var(--ease);
  background: var(--glass-sunk); border: 1px solid var(--hairline);
}
.toggle i::after {
  content: ''; position: absolute; top: 3px; inset-inline-start: 3px;
  width: 22px; height: 22px; border-radius: 50%; background: #fff;
  box-shadow: 0 2px 5px rgba(0,0,0,.24); transition: .22s var(--ease);
}
.toggle input:checked + i { background: linear-gradient(180deg, var(--accent-2), var(--accent)); border-color: transparent; }
.toggle input:checked + i::after { transform: translateX(20px); }
html[dir="rtl"] .toggle input:checked + i::after { transform: translateX(-20px); }

.remrow { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--hairline-dim); }
.remrow:last-child { border-bottom: none; }
/* also covers .secrow, whose label previously had no flex — which left
   its toggle sitting against the text instead of at the row's end */
.remrow .rlabel, .secrow .rlabel { flex: 1; font-size: .88rem; }
.secrow .toggle { margin-inline-start: auto; }
.remrow input[type="time"] {
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  border-radius: 10px; padding: 6px 9px; font-size: .82rem; color: var(--text); font-family: var(--font);
}

.center { text-align: center; }
.mt { margin-top: 12px; }
.mb0 { margin-bottom: 0; }
.onb-step { animation: fade .24s var(--ease); }
.empty { text-align: center; padding: 18px 8px; color: var(--text-mute); font-size: .86rem; }

/* the every-day / clear pair in the medication form */
.btn.ghost.on {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-ink);
}


/* ---------- spotlight: the daily motivation, above everything ---------- */
.card.spotlight {
  position: relative; overflow: hidden;
  padding: 20px 18px 20px 20px;
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--accent) 26%, transparent),
      color-mix(in srgb, var(--mesh-3) 22%, transparent));
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
  box-shadow: var(--shadow-lift);
}
.spotlight-text {
  position: relative;
  font-size: 1.14rem; font-weight: 620; line-height: 1.48;
  letter-spacing: -.015em;
}

/* ---------- medication card ---------- */
.medcard {
  border-radius: var(--r-md);
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  padding: 13px; margin-bottom: 10px;
}
.medcard:last-child { margin-bottom: 0; }
.medcard.complete { opacity: .72; }
.medcard-top { display: flex; align-items: center; gap: 11px; }
.medcard-id { flex: 1; min-width: 0; }
.med-progress {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.medcard-next {
  display: flex; align-items: center; gap: 10px; margin-top: 11px;
  padding-top: 11px; border-top: 1px solid var(--hairline-dim);
}
.next-label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.next-tag {
  font-size: .62rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-mute);
}
html[dir="rtl"] .next-tag { letter-spacing: 0; }
.next-time {
  font-size: 1.15rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.take-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
  padding: 10px 16px; border-radius: 999px; border: none; cursor: pointer;
  font: inherit; font-size: .84rem; font-weight: 650; color: #fff;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 32%, transparent);
  transition: transform .16s var(--ease);
}
.take-btn:active { transform: scale(.95); }
.take-btn .tick { display: grid; place-items: center; width: 15px; height: 15px; }
.take-btn svg { width: 15px; height: 15px; }
.medcard-done {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hairline-dim);
  font-size: .82rem; font-weight: 650; color: var(--accent-ink);
}

/* ---------- collapsible meal rows ---------- */
.meal { border-bottom: 1px solid var(--hairline-dim); padding: 4px 0; }
.meal:last-child { border-bottom: none; }
.meal-head { display: flex; align-items: center; gap: 10px; padding: 9px 0; }
.meal-check {
  flex: 0 0 auto; width: 26px; height: 26px; padding: 0; cursor: pointer;
  border-radius: 50%; border: 2px solid var(--text-mute);
  display: grid; place-items: center; background: none;
  color: #fff; transition: .18s var(--ease);
}
.meal-check.on { background: var(--accent); border-color: var(--accent); }
.meal-check svg { opacity: 0; width: 14px; height: 14px; }
.meal-check.on svg { opacity: 1; }

.meal-title {
  flex: 1; min-width: 0; text-align: start; cursor: pointer;
  background: none; border: none; font: inherit; color: inherit; padding: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.meal-slot {
  font-size: .64rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); font-weight: 700;
}
html[dir="rtl"] .meal-slot { letter-spacing: 0; }
.meal.isnext .meal-slot { color: var(--accent); }
.meal-name { font-weight: 650; letter-spacing: -.01em; line-height: 1.25; }
.meal.done .meal-name { text-decoration: line-through; color: var(--text-dim); }
.meal.done .meal-check { opacity: .8; }

.chev {
  flex: 0 0 auto; width: 28px; height: 28px; padding: 0; cursor: pointer;
  border: none; background: none; color: var(--text-mute);
  display: grid; place-items: center;
  transition: transform .22s var(--ease);
}
.chev svg { width: 17px; height: 17px; }
.chev.up { transform: rotate(180deg); }

.meal-body { padding: 0 0 12px 36px; animation: fade .2s var(--ease); }
html[dir="rtl"] .meal-body { padding: 0 36px 12px 0; }
.meal-body .btn { width: auto; display: inline-block; margin-top: 9px; padding: 7px 14px; }

.link-btn {
  background: none; border: none; cursor: pointer; padding: 0;
  font: inherit; font-size: .76rem; font-weight: 650; color: var(--accent-ink);
}

/* ---------- shopping list ---------- */
.shopcat-head {
  display: flex; align-items: center; gap: 9px; width: 100%; cursor: pointer;
  padding: 11px 12px; border-radius: var(--r-md);
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  font: inherit; color: var(--text);
}
.shopcat.open .shopcat-head { border-radius: var(--r-md) var(--r-md) 0 0; border-bottom: none; }
.shopcat-name { flex: 1; min-width: 0; text-align: start; font-size: .87rem; font-weight: 650; }
.shopcat-count {
  font-size: .74rem; font-weight: 700; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.shopcat-count.all { color: var(--accent-ink); }

.shop-items {
  border-radius: 0 0 var(--r-md) var(--r-md);
  border: 1px solid var(--hairline-dim); border-top: none;
  overflow: hidden;
}
.shop-row {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  padding: 10px 12px; border-bottom: 1px solid var(--hairline-dim);
  background: none; border-left: none; border-right: none; border-top: none;
  font: inherit; color: var(--text); text-align: start;
}
.shop-row:last-child { border-bottom: none; }
.shop-box {
  flex: 0 0 auto; width: 21px; height: 21px; border-radius: 6px;
  border: 2px solid var(--text-mute); display: grid; place-items: center;
  color: #fff; transition: .16s var(--ease);
}
.shop-box svg { opacity: 0; width: 12px; height: 12px; }
.shop-row.on .shop-box { background: var(--accent); border-color: var(--accent); }
.shop-row.on .shop-box svg { opacity: 1; }
.shop-row.on .shop-name { text-decoration: line-through; color: var(--text-mute); }

/* ---------- plan comparison ---------- */
.cmp { margin-bottom: 14px; }
.cmp:last-child { margin-bottom: 0; }
.cmp-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.cmp-label { font-size: .85rem; color: var(--text-dim); }
.cmp-val { font-size: .85rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.cmp-val.met { color: var(--accent-ink); }

/* ---------- home customisation ---------- */
.secrow {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--hairline-dim);
}
.secrow:last-child { border-bottom: none; }
.secrow.off .rlabel { color: var(--text-mute); }
.secrow .icon-btn:disabled { opacity: .3; cursor: default; }

/* ---------- calendar ---------- */
.date-btn {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  padding: 13px; border-radius: 14px;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  font: inherit; color: var(--text); text-align: start;
}
.date-btn svg { width: 18px; height: 18px; color: var(--text-dim); flex: 0 0 auto; }

.cal {
  border-radius: var(--r-md); padding: 10px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.cal-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cal-month { flex: 1; text-align: center; font-weight: 650; font-size: .95rem; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-grid.weekdays { margin-bottom: 4px; }
.cal-wd {
  text-align: center; font-size: .64rem; font-weight: 700;
  color: var(--text-mute); padding: 4px 0;
}
.cal-cell {
  aspect-ratio: 1; display: grid; place-items: center; cursor: pointer;
  border-radius: 10px; border: 1px solid transparent; background: none;
  font: inherit; font-size: .84rem; color: var(--text);
  font-variant-numeric: tabular-nums;
  transition: .14s var(--ease);
}
.cal-cell.empty { cursor: default; }
.cal-cell:disabled { opacity: .25; cursor: default; }
.cal-cell.now { border-color: color-mix(in srgb, var(--accent) 50%, transparent); font-weight: 700; }
.cal-cell.sel {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: #fff; font-weight: 700; border-color: transparent;
}

/* concrete examples under each avoid tile */
.avoid-eg {
  font-size: .63rem; color: var(--text-mute); line-height: 1.3;
  margin-top: 1px;
}
/* six tiles read better two-up than three-up now they carry examples */
.avoid-grid { grid-template-columns: repeat(2, 1fr); }
.avoid-tile { padding: 12px 9px 10px; }

/* ---------- More: grouped menu ---------- */
.card.menu { padding: 0; overflow: hidden; }
.menu-row {
  display: flex; align-items: center; gap: 12px; width: 100%; cursor: pointer;
  padding: 13px 15px; border: none; border-bottom: 1px solid var(--hairline-dim);
  background: none; font: inherit; color: var(--text); text-align: start;
}
.menu-row:last-child { border-bottom: none; }
.menu-row:active { background: var(--glass-sunk); }
.menu-glyph {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center; font-size: 1rem;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.menu-label { flex: 1; min-width: 0; font-size: .92rem; font-weight: 550; }
.menu-value { font-size: .82rem; color: var(--text-mute); white-space: nowrap; }
.menu-chev { flex: 0 0 auto; display: grid; place-items: center; color: var(--text-mute); }
.menu-chev svg { width: 16px; height: 16px; transform: rotate(-90deg); }
html[dir="rtl"] .menu-chev svg { transform: rotate(90deg); }

/* ---------- More: subpage ---------- */
.back-btn {
  display: inline-flex; align-items: center; gap: 3px; cursor: pointer;
  background: none; border: none; padding: 4px 0 0; margin-bottom: 4px;
  font: inherit; font-size: .9rem; font-weight: 600; color: var(--accent-ink);
}
.back-chev { display: grid; place-items: center; }
.back-chev svg { width: 18px; height: 18px; transform: rotate(90deg); }
html[dir="rtl"] .back-chev svg { transform: rotate(-90deg); }
.subpage-title {
  font-size: 1.4rem; font-weight: 700; letter-spacing: -.02em;
  margin: 2px 0 14px; text-transform: none; color: var(--text);
}

/* ---------- the daily nudge ----------
   No card, no border, no fill. It reads as a line someone said to you
   rather than another tile competing with the ones below it. */
.card.spotlight {
  background: none !important;
  border: none;
  box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  /* 16px horizontally like every other card: at 4px the motivation
     text began 12px to the left of all the text under it, so the
     column had two left edges. Bottom margin was 4px for the same
     reason — every other card leaves 12. */
  padding: 4px 16px 14px;
  margin-bottom: 12px;
}
.spotlight-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
}
.tone-tag {
  flex: 1; font-size: .6rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .1em; color: var(--accent-ink); opacity: .8;
}
html[dir="rtl"] .tone-tag { letter-spacing: 0; }
.spotlight-next {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; font-size: 1rem; line-height: 1;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text-dim); font-family: var(--font);
  transition: transform .3s var(--ease);
}
.spotlight-next:active { transform: rotate(180deg) scale(.9); }

.craving-btn {
  margin-top: 12px; cursor: pointer;
  padding: 8px 15px; border-radius: 999px;
  background: none; border: 1px solid var(--hairline-dim);
  font: inherit; font-size: .8rem; font-weight: 650; color: var(--text-dim);
}
.craving-btn:active { transform: scale(.96); }

/* tone shows only in the accent, since there is no fill to tint */
.card.spotlight.tone-kind  { --tone: var(--accent); }
.card.spotlight.tone-funny { --tone: var(--gold); }
.card.spotlight.tone-harsh { --tone: var(--danger); }
.card.spotlight.tone-fact  { --tone: var(--water); }
.card.spotlight .tone-tag { color: var(--tone); opacity: 1; }
.card.spotlight .spotlight-text {
  padding-inline-start: 13px;
  border-inline-start: 3px solid var(--tone);
}

.craving-line { font-size: 1.1rem; font-weight: 650; line-height: 1.45; }
.craving-do { font-size: .88rem; color: var(--text-dim); margin: 8px 0 0; line-height: 1.5; }

/* ---------- horizontal rails ---------- */
/* The rail stays inside the card's padding rather than bleeding to its
   edge — bleeding meant the last tile was sliced flush against the
   border, which read as a layout bug rather than as "scroll for more". */
.hscroll {
  display: flex; gap: 9px; overflow-x: auto; overflow-y: hidden;
  padding-bottom: 4px; padding-inline-end: 4px;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 2px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.hscroll::-webkit-scrollbar { display: none; }
.hscroll > * { flex: 0 0 auto; scroll-snap-align: start; }

/* compact dose cards, in time order */
.dosechip {
  width: 124px; cursor: pointer; text-align: start;
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 12px 10px; border-radius: var(--r-md);
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  font: inherit; color: var(--text);
  transition: .16s var(--ease);
}
.dosechip:active { transform: scale(.97); }
.dosechip.on {
  background: color-mix(in srgb, var(--med) 15%, transparent);
  border-color: color-mix(in srgb, var(--med) 38%, transparent);
}
.dosechip-time {
  font-size: 1.15rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.dosechip-name { font-size: .82rem; font-weight: 650; line-height: 1.2; margin-top: 3px; }
.dosechip.on .dosechip-name { text-decoration: line-through; color: var(--text-dim); }
.dosechip-dose { font-size: .7rem; color: var(--text-mute); line-height: 1.2; }
.dosechip-state {
  display: flex; align-items: center; gap: 5px; margin-top: 7px;
  font-size: .68rem; font-weight: 700; color: var(--text-mute);
}
.dosechip.on .dosechip-state { color: var(--med); }
.dosechip-state svg { width: 12px; height: 12px; }
.dosechip-state i { font-style: normal; }

/* ---------- drag to reorder ---------- */
.drag-handle {
  flex: 0 0 auto; width: 30px; height: 30px; display: grid; place-items: center;
  color: var(--text-mute); cursor: grab; touch-action: none;
}
.drag-handle svg { width: 20px; height: 20px; }
.secrow { touch-action: pan-y; transition: transform .12s var(--ease); }
.secrow.dragging {
  position: relative; z-index: 5; cursor: grabbing;
  background: var(--glass-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-lift); transition: none;
}

/* ---------- lock screen ---------- */
.lockscreen {
  min-height: 78vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 12px; text-align: center;
  padding: 0 8px;
}
.lock-mark { font-size: 2.6rem; }
.lock-title { font-size: 1.1rem; font-weight: 650; margin: 0; }
.pin-input {
  width: 168px; text-align: center; letter-spacing: .6em; text-indent: .6em;
  font-size: 1.6rem; font-weight: 700; padding: 14px 10px;
  border-radius: 16px; border: 1px solid var(--hairline);
  background: var(--glass); color: var(--text);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
}
.lockscreen .btn { max-width: 220px; }

/* ---------- first-run sign in ---------- */
.signin-mark { font-size: 2.4rem; text-align: center; margin-bottom: 6px; }
/* beats `.card > h2`, which would otherwise make this a small caps label */
.card > h2.signin-title {
  font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em;
  text-align: center; margin: 0 0 8px; text-transform: none; color: var(--text);
}
.signin-intro { text-align: center; }
.signin-skip {
  display: block; width: 100%; text-align: center;
  margin-top: 14px; padding: 8px; color: var(--text-mute);
}

/* ---------- liver: compare slider ---------- */
.liver-compare {
  display: flex; align-items: center; gap: 10px; margin-top: 6px;
}
.cmp-end {
  flex: 0 0 auto; font-size: .66rem; font-weight: 700;
  color: var(--text-mute); white-space: nowrap;
}
#liverSlide {
  flex: 1; min-width: 0; -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 999px; background: var(--glass-sunk);
  border: 1px solid var(--hairline-dim); outline: none;
}
#liverSlide::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 50%; cursor: grab;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  border: 2px solid var(--glass-strong);
  box-shadow: 0 2px 8px rgba(0,0,0,.2);
}
#liverSlide::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%; cursor: grab; border: 2px solid #fff;
  background: var(--accent);
}
.liver-explain { display: block; width: 100%; text-align: center; margin-top: 12px; padding: 6px; }

.detail-block { padding: 12px 0; border-bottom: 1px solid var(--hairline-dim); }
.detail-block:last-of-type { border-bottom: none; }
.detail-head { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; }
.detail-head b { flex: 1; font-size: .95rem; }

/* ---------- measurements ---------- */
.metric-row {
  display: flex; align-items: center; gap: 12px; width: 100%; cursor: pointer;
  padding: 11px 0; border: none; border-bottom: 1px solid var(--hairline-dim);
  background: none; font: inherit; color: var(--text); text-align: start;
}
.metric-row:last-child { border-bottom: none; }
.metric-glyph {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 11px;
  display: grid; place-items: center; font-size: 1rem;
  background: color-mix(in srgb, var(--c) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--c) 30%, transparent);
}
.metric-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.metric-name { font-size: .9rem; font-weight: 650; }
.metric-sub { font-size: .72rem; color: var(--text-mute); }
.metric-val { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.metric-val b { font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.metric-val b.good { color: var(--accent-ink); }
.metric-val b.bad { color: var(--warn); }
.metric-val i { font-style: normal; font-size: .66rem; font-weight: 600; color: var(--text-mute); margin-inline-start: 3px; }
.metric-delta { font-size: .68rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.metric-delta.good { color: var(--accent-ink); }
.metric-delta.bad { color: var(--warn); }
.seg .muted { color: var(--text-mute); font-weight: 500; }

/* ---------- onboarding ---------- */
.onb-bar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 14px;
  padding: calc(env(safe-area-inset-top) + 16px) 4px 16px;
}
.onb-skip { flex: 0 0 auto; font-size: .84rem; }

.onb-dots { flex: 1; display: flex; gap: 6px; }
.onb-dot {
  height: 4px; flex: 1; border-radius: 999px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  transition: .3s var(--ease);
}
.onb-dot.done { background: color-mix(in srgb, var(--accent) 45%, transparent); border-color: transparent; }
.onb-dot.on { background: var(--accent); border-color: transparent; }

.onb-slide { text-align: center; }
.onb-glyph { font-size: 3rem; line-height: 1; margin-bottom: 12px; }
.card > h2.onb-title {
  font-size: 1.5rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.2;
  text-transform: none; color: var(--text); margin: 0 0 10px;
}
.onb-body { font-size: .97rem; line-height: 1.6; color: var(--text-dim); margin: 0; }
.onb-medical {
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--hairline-dim);
  font-size: .74rem;
}

/* ---------- fridge ---------- */
/* how you want to eat — one emphasis, picked once */
.styles { display: grid; gap: 8px; }
.style {
  display: grid; gap: 3px; text-align: start;
  padding: 12px 14px; border-radius: 14px;
  border: 1px solid var(--hairline-dim); background: var(--glass-sunk);
  color: var(--text); font: inherit; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.style b { font-size: 15px; font-weight: 650; }
.style small { font-size: 12.5px; line-height: 1.45; color: var(--text-dim); }
.style.on { border-color: var(--accent); background: var(--accent-wash); }
.style.on b { color: var(--accent-ink); }

.ing-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
.ing {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 6px; border-radius: var(--r-md); cursor: pointer;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
  font: inherit; color: var(--text); text-align: center;
  transition: .16s var(--ease);
}
.ing:active { transform: scale(.95); }
.ing.on {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.ing-glyph { font-size: 1.3rem; line-height: 1; filter: grayscale(.5) opacity(.7); transition: .16s var(--ease); }
.ing.on .ing-glyph { filter: none; }
.ing-name { font-size: .68rem; font-weight: 600; line-height: 1.2; }

.suggest {
  padding: 12px; border-radius: var(--r-md); margin-bottom: 9px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.suggest:last-child { margin-bottom: 0; }
.suggest.full { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.suggest-top { display: flex; align-items: baseline; gap: 10px; margin-bottom: 3px; }
.suggest-slot {
  flex: 1; font-size: .62rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-mute);
}
html[dir="rtl"] .suggest-slot { letter-spacing: 0; }
.suggest-score { font-size: .74rem; font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.suggest-name { font-size: .95rem; font-weight: 650; letter-spacing: -.01em; }
.suggest-missing { font-size: .76rem; color: var(--text-dim); margin-top: 3px; }
.suggest.full .suggest-missing { color: var(--accent-ink); font-weight: 600; }

/* ---------- lab photo ---------- */
.lab-shot {
  border-radius: var(--r-md); overflow: hidden; margin-top: 12px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.lab-shot.empty {
  display: grid; place-items: center; min-height: 130px;
  color: var(--text-mute); font-size: .84rem;
}
.lab-shot img { display: block; width: 100%; height: auto; }
.lab-field { margin-bottom: 10px; }
.lab-field label {
  display: block; font-size: .8rem; color: var(--text-dim);
  margin-bottom: 4px; font-weight: 600;
}
.lab-field input {
  width: 100%; padding: 11px 13px; border-radius: 12px;
  border: 1px solid var(--hairline); background: var(--glass-sunk);
  color: var(--text); font: inherit;
}

/* ============================================================
   the coach — a full chat screen
   ============================================================

   A fixed three-row grid: header, scrolling log, composer. Only the
   middle row scrolls, so the composer stays put when the keyboard
   opens and the header never slides away mid-conversation. */
.chat-screen {
  position: fixed; inset: 0; z-index: 60;
  display: grid; grid-template-rows: auto 1fr auto;
  /* An auto column would size itself to the widest thing inside — and
     the starter chips are a scrolling row that never runs out of
     content, which quietly made the whole screen wider than the phone. */
  grid-template-columns: 100%;
  background: var(--page);
}
/* Both elements: leaving the scrollbar on <html> pinches the fixed
   chat screen in from the edge on desktop. */
html.chat-lock, body.chat-lock { overflow: hidden; }

.chat-top {
  display: flex; align-items: center; gap: 10px;
  padding: calc(env(safe-area-inset-top) + 10px) 14px 10px;
  border-bottom: 1px solid var(--hairline-dim);
  background: var(--glass); backdrop-filter: blur(20px) saturate(160%);
}
.chat-title { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.chat-title b { font-size: 1rem; }
.chat-title small {
  font-size: .68rem; color: var(--text-dim); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-top .icon-btn.on { color: var(--accent-ink); }
html[dir="rtl"] .back-arrow { transform: scaleX(-1); }

.chat-log {
  min-width: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 16px 14px 8px;
  display: flex; flex-direction: column; gap: 18px;
}

/* The user gets a bubble; the coach gets the full column, the way every
   assistant does it — its answers are long enough that a bubble just
   adds a margin you have to read around. */
.msg { display: flex; gap: 9px; max-width: 100%; }
.msg.me { justify-content: flex-end; }
.msg.me .msg-body {
  max-width: 84%; padding: 10px 14px;
  border-radius: 18px; border-end-end-radius: 6px;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: #fff;
}
.msg-avatar {
  flex: 0 0 auto; width: 27px; height: 27px; border-radius: 50%;
  display: grid; place-items: center; margin-top: 1px;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--accent-ink);
}
.msg-wrap { min-width: 0; flex: 1; }

.msg-body { font-size: .92rem; line-height: 1.6; }
.msg-body p { margin: 0 0 .6em; }
.msg-body p:last-child { margin-bottom: 0; }
.msg-body ul { margin: 0 0 .6em; padding-inline-start: 1.15em; }
.msg-body li { margin-bottom: .25em; }
.msg-body code {
  font-family: ui-monospace, Menlo, monospace; font-size: .85em;
  padding: 1px 5px; border-radius: 5px; background: var(--glass-sunk);
}

.msg-copy {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 7px; padding: 4px 9px; border-radius: 999px;
  background: transparent; border: 1px solid var(--hairline-dim);
  color: var(--text-dim); font: inherit; font-size: .7rem; font-weight: 600;
  cursor: pointer; opacity: .75;
}
.msg-copy:active { transform: scale(.95); }

/* three dots while a reply is on its way */
.msg-body.typing { display: flex; gap: 4px; padding: 8px 2px; }
.msg-body.typing i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--text-dim);
  animation: chatdot 1.2s infinite ease-in-out;
}
.msg-body.typing i:nth-child(2) { animation-delay: .16s; }
.msg-body.typing i:nth-child(3) { animation-delay: .32s; }
@keyframes chatdot {
  0%, 60%, 100% { opacity: .25; transform: translateY(0); }
  30%           { opacity: .9;  transform: translateY(-3px); }
}

.chat-hello {
  margin: auto 0; text-align: center; padding: 0 20px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.chat-mark {
  width: 54px; height: 54px; border-radius: 18px; display: grid; place-items: center;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--accent-ink);
}
.chat-hello b { font-size: 1.15rem; }
.chat-hello p { margin: 0; color: var(--text-dim); font-size: .86rem; max-width: 26ch; }

.chat-foot {
  min-width: 0;
  padding: 8px 12px calc(env(safe-area-inset-bottom) + 10px);
  border-top: 1px solid var(--hairline-dim);
  background: var(--glass); backdrop-filter: blur(20px) saturate(160%);
}
.chat-chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; min-width: 0; }
.chat-chips::-webkit-scrollbar { display: none; }
.chat-chips:not(:empty) { padding-bottom: 8px; }

.chat-composer {
  display: flex; align-items: flex-end; gap: 7px;
  padding: 5px 5px 5px 14px; border-radius: 24px;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
}
html[dir="rtl"] .chat-composer { padding: 5px 14px 5px 5px; }
.chat-composer textarea {
  flex: 1; min-width: 0; resize: none; border: none; background: none;
  color: var(--text); font: inherit; font-size: .92rem; line-height: 1.45;
  padding: 8px 0; max-height: 140px; outline: none;
}
.chat-mic, .chat-send {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer; border: none;
}
.chat-mic { background: transparent; color: var(--text-dim); }
.chat-mic.live { color: var(--danger); animation: chatdot .9s infinite; }
.chat-send {
  background: linear-gradient(180deg, var(--accent-2), var(--accent)); color: #fff;
  transition: opacity .15s;
}
.chat-send:disabled { opacity: .3; }
.chat-send:not(:disabled):active { transform: scale(.92); }

.chip-btn {
  flex: 0 0 auto; cursor: pointer; white-space: nowrap;
  padding: 7px 13px; border-radius: 999px;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  font: inherit; font-size: .78rem; font-weight: 600; color: var(--text-dim);
}
.chip-btn:active { transform: scale(.95); }

/* ---------- end of day ----------
   Still the one card that means the day is closed, but it now belongs
   to the theme rather than overriding it: the app's own surface, with
   the verdict's colour washed in behind and carried by the type. The
   tones are tokens, so they flip in dark like every other colour. */
.daysum {
  --ds-tone: var(--ds-good);
  position: relative; overflow: hidden;
  padding: 16px 16px 14px;
  background:
    radial-gradient(115% 85% at 90% -15%,
      color-mix(in srgb, var(--ds-tone) 15%, transparent), transparent 62%),
    var(--glass-strong);
  border: 1px solid color-mix(in srgb, var(--ds-tone) 26%, var(--hairline));
}
.daysum.v-mixed { --ds-tone: var(--ds-mixed); }
.daysum.v-bad   { --ds-tone: var(--ds-bad); }

.ds-top { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.ds-label {
  flex: 1; min-width: 0;
  font-size: .64rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-mute);
}

/* the score as a bar of segments — readable without being read */
.ds-meter { display: flex; gap: 3px; flex: 0 0 auto; }
.ds-meter i {
  width: 9px; height: 4px; border-radius: 2px;
  background: color-mix(in srgb, var(--text) 14%, transparent);
}
.ds-meter i.on { background: var(--ds-tone); }

.ds-verdict {
  font-size: 1.45rem; font-weight: 800; line-height: 1.1;
  letter-spacing: -.02em; color: var(--ds-tone);
  margin-bottom: 6px;
}
.ds-say { margin: 0; font-size: .88rem; line-height: 1.5; color: var(--text); }

.ds-ask {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 10px; padding: 5px 11px; border-radius: 999px;
  background: var(--glass-sunk); border: 1px solid var(--hairline);
  color: var(--text-dim); font: inherit; font-size: .72rem; font-weight: 700;
  cursor: pointer;
}
.ds-ask:active { transform: scale(.96); }

/* Five figures on one line instead of five stacked rows. */
.ds-strip {
  display: flex; gap: 6px; margin-top: 12px;
  padding-top: 11px; border-top: 1px solid var(--hairline-dim);
}
.ds-chip {
  flex: 1 1 0; min-width: 0; text-align: center;
  display: flex; flex-direction: column; gap: 1px;
}
.ds-chip b {
  font-size: .84rem; font-weight: 800; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ds-chip span {
  font-size: .58rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-mute);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ds-chip.ok b  { color: var(--accent-ink); }
.ds-chip.mid b { color: var(--ds-mixed); }
.ds-chip.off b { color: var(--danger); }

/* ---------- challenge and points ---------- */
.challenge { padding: 14px 16px; }
.challenge.done { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }

.ch-top { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.ch-label {
  flex: 1; min-width: 0;
  font-size: .64rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-mute);
}
.pts {
  flex: 0 0 auto;
  font-size: .7rem; font-weight: 800; color: var(--accent-ink);
  padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* text and buttons share a row until the phone is too narrow for it */
.ch-body { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* a way into the two goals that are a skill rather than a number */
/* The ring is the control, so this is a hint, not a button. */
.goal-hint {
  display: flex; align-items: center; gap: 4px;
  margin-top: 5px; font-size: 11.5px; font-weight: 600;
  color: var(--text-mute); line-height: 1.2;
}
.goal-hint svg { flex: none; opacity: .8; }

/* A tappable ring needs to look tappable and answer the finger. */
.goal-dial {
  padding: 0; border: 0; background: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .16s var(--ease);
}
.goal-dial::after { content: ''; position: absolute; inset: -6px; border-radius: 50%; }
.goal-dial:active { transform: scale(.93); }
.goal-dial .goal-arc { transition: stroke-dashoffset .3s linear; }
.goal-dial.live .goal-arc { transition: stroke-dashoffset 1s linear; }
.goal-dial.held .glyph { opacity: .55; }

.goal.running { border-color: color-mix(in srgb, var(--c) 45%, transparent); }
.goal-clock {
  font-variant-numeric: tabular-nums; font-weight: 700;
  color: var(--c); margin-inline-end: 4px;
}
.goal-name .reps {
  font-weight: 600; color: var(--text-mute); margin-inline-start: 5px;
}

@media (prefers-reduced-motion: reduce) {
  .goal-dial, .goal-dial .goal-arc { transition: none; }
}

/* one pulse at the moment a goal completes */
.goal.landed { animation: goalLand .55s cubic-bezier(.2,.8,.25,1); }
@keyframes goalLand {
  0%   { transform: none; }
  35%  { transform: scale(1.035); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) { .goal.landed { animation: none; } }

/* the home routine */
.routine { margin: 4px 0 2px; }
.rmove {
  display: flex; gap: 12px; padding: 11px 0;
  border-bottom: 1px solid var(--hairline-dim);
}
.rmove:last-child { border-bottom: none; }
.rmove-n {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; margin-top: 1px;
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent-ink); font-size: .72rem; font-weight: 800;
}
.rmove-body { min-width: 0; }
.rmove-body b { display: block; font-size: .9rem; margin-bottom: 2px; }
.rmove-body b i {
  font-style: normal; font-weight: 700; font-size: .74rem;
  color: var(--accent-ink); margin-inline-start: 7px;
}
.rmove-body small { font-size: .78rem; line-height: 1.45; color: var(--text-dim); }

/* the rung the points are on, and how far the next one is */
.ch-rung { margin: 10px 0 12px; }
.ch-rung-top {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px;
}
.ch-rung-top b { font-size: .82rem; }
.ch-rung-top span {
  margin-inline-start: auto; font-size: .7rem; color: var(--text-dim);
  text-align: end;
}
.ch-track {
  height: 4px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 10%, transparent);
}
.ch-track i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  transition: width .5s cubic-bezier(.2,.8,.25,1);
}
html[dir="rtl"] .ch-track i { margin-inline-start: auto; }

.pts { border: none; cursor: pointer; }

/* the ladder, in full */
.rungs { margin: 6px 0 4px; }
.rung {
  display: flex; gap: 12px; padding: 10px 0;
  border-bottom: 1px solid var(--hairline-dim);
  opacity: .55;
}
.rung:last-child { border-bottom: none; }
.rung.done { opacity: 1; }
.rung.here b { color: var(--accent-ink); }
.rung-dot {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; margin-top: 2px;
  border: 1.5px solid var(--hairline);
  background: var(--glass-sunk); color: var(--accent-ink);
}
.rung.done .rung-dot { border-color: transparent; background: color-mix(in srgb, var(--accent) 18%, transparent); }
.rung-dot svg { width: 12px; height: 12px; }
.rung-body { min-width: 0; }
.rung-body b { display: block; font-size: .88rem; margin-bottom: 2px; }
.rung-body b i {
  font-style: normal; font-weight: 700; font-size: .72rem;
  color: var(--text-mute); margin-inline-start: 6px;
}
.rung-body small { font-size: .76rem; line-height: 1.45; color: var(--text-dim); }

.suggest-head {
  margin: 18px 0 8px; font-size: .72rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-mute);
}
.suggest-tick { color: var(--accent-ink); }
.suggest-tick svg { width: 15px; height: 15px; }

.ch-text {
  /* basis kept small so two buttons still fit beside it at 375px —
     at 55% the accepted state wrapped and left a hole in the card */
  flex: 1 1 38%; min-width: 108px; margin: 0;
  font-size: .93rem; font-weight: 600; line-height: 1.35;
}
.ch-acts { flex: 0 0 auto; display: flex; gap: 6px; margin-inline-start: auto; }
.ch-acts .btn { width: auto; padding: 8px 13px; font-size: .8rem; }
.ch-done {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 800; color: var(--accent-ink); font-size: .84rem;
}
.ch-done svg { width: 15px; height: 15px; }
.ch-hide {
  background: none; border: none; cursor: pointer; padding: 4px 6px;
  color: var(--text-mute); font-size: .85rem; line-height: 1;
}
.ch-won { margin: 9px 0 0; font-size: .72rem; color: var(--text-dim); }

/* ---------- the urge timer ---------- */
.urge { text-align: center; }
.urge h3 { margin-bottom: 6px; }
.urge .note { margin-bottom: 18px; }

.urge-stage {
  position: relative; width: 200px; height: 200px; margin: 0 auto 14px;
  display: grid; place-items: center;
}
.urge-ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.ur-track { fill: none; stroke: var(--hairline); stroke-width: 5; }
.ur-fill {
  fill: none; stroke: var(--accent); stroke-width: 5; stroke-linecap: round;
  transition: stroke-dashoffset 1s linear;
}

/* A breath to follow: six seconds in, six out, which is about the rate
   that settles the nervous system down. */
.urge-breath {
  position: absolute; width: 96px; height: 96px; border-radius: 50%;
  background: radial-gradient(circle at 40% 35%,
    color-mix(in srgb, var(--accent) 40%, transparent),
    color-mix(in srgb, var(--accent) 12%, transparent));
}
.urge-breath.on { animation: breathe 12s ease-in-out infinite; }
@keyframes breathe {
  0%, 100% { transform: scale(.72); opacity: .5; }
  50%      { transform: scale(1.18); opacity: .95; }
}

.urge-clock {
  position: relative; font-size: 2rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.urge-line {
  min-height: 2.6em; margin: 0 0 14px; font-size: .9rem;
  line-height: 1.45; color: var(--text-dim);
}
.urge-tally { font-size: .8rem; color: var(--text-dim); margin: 0 0 14px; }

/* ---------- picking a plate ---------- */
.lbl {
  display: block; font-size: .78rem; font-weight: 600;
  color: var(--text-dim); margin-bottom: 6px;
}
.items { display: flex; flex-direction: column; gap: 6px; }
.item-row {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; border-radius: 12px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.item-food {
  flex: 1 1 auto; min-width: 0; text-align: start;
  background: none; border: none; padding: 2px 0;
  color: var(--text); font: inherit; font-size: .82rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-decoration: underline; text-decoration-style: dotted;
  text-underline-offset: 3px; cursor: pointer;
}
.item-qty {
  flex: 0 0 52px; width: 52px; padding: 6px 6px; text-align: center;
  border-radius: 9px; border: 1px solid var(--hairline);
  background: var(--glass-strong); color: var(--text); font: inherit; font-size: .82rem;
}
.item-unit {
  flex: 0 0 auto; max-width: 92px; padding: 6px 4px;
  border-radius: 9px; border: 1px solid var(--hairline);
  background: var(--glass-strong); color: var(--text); font: inherit; font-size: .76rem;
}
.item-kcal {
  flex: 0 0 40px; text-align: end; font-size: .8rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.item-x {
  flex: 0 0 auto; background: none; border: none; cursor: pointer;
  color: var(--text-mute); font-size: .8rem; padding: 2px 3px;
}

.edit-total {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 14px; padding-top: 11px;
  border-top: 1px solid var(--hairline-dim);
}
.edit-total span { flex: 1; color: var(--text-dim); font-size: .84rem; }
.edit-total b { font-size: 1.5rem; font-weight: 800; font-variant-numeric: tabular-nums; }

.food-list { max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }
.food-row-wrap {
  display: flex; align-items: stretch;
  border-bottom: 1px solid var(--hairline-dim);
}
.food-row-wrap .food-row { border-bottom: none; }
.food-del {
  flex: 0 0 auto; background: none; border: none; cursor: pointer;
  color: var(--text-mute); font-size: .78rem; padding: 0 8px;
  position: relative;
}
.food-del::after { content: ''; position: absolute; inset: -6px -4px; }
.food-mine {
  font-style: normal; font-size: .62rem; font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent-ink); margin-inline-start: 5px;
}

.food-row {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 10px 4px; background: none; border: none;
  border-bottom: 1px solid var(--hairline-dim);
  color: var(--text); font: inherit; text-align: start; cursor: pointer;
}
.food-name { flex: 1; min-width: 0; font-size: .88rem; font-weight: 600; }
.food-k {
  flex: 0 0 auto; font-size: .72rem; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* ---------- an estimate you can see inside ---------- */
.breakdown {
  margin: 0 0 14px; padding: 10px 12px; border-radius: 14px;
  background: var(--glass-sunk); border: 1px solid var(--hairline-dim);
}
.bd-row {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 0; font-size: .8rem;
}
.bd-row + .bd-row { border-top: 1px solid var(--hairline-dim); }
.bd-item { flex: 1; min-width: 0; }
.bd-portion { flex: 0 0 auto; color: var(--text-dim); font-size: .74rem; }
.bd-kcal {
  flex: 0 0 auto; min-width: 42px; text-align: end;
  font-weight: 700; font-variant-numeric: tabular-nums;
}
.bd-miss {
  margin: 8px 0 0; font-size: .72rem; line-height: 1.4;
  color: var(--danger);
}

/* ---------- what the kitchen changed ---------- */
#fridgeApply { display: flex; align-items: center; justify-content: center; gap: 8px; }
#fridgeApply:disabled { opacity: .45; }

.card.applied { border-color: color-mix(in srgb, var(--accent) 34%, transparent); }
.applied-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--hairline-dim);
}
.applied-row:last-of-type { border-bottom: none; }
.applied-slot {
  flex: 0 0 34%; font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-dim);
}
.applied-swap { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.applied-swap s { font-size: .76rem; color: var(--text-dim); opacity: .7; }
.applied-swap b { font-size: .9rem; }

/* ---------- editing a planned meal ---------- */
.meal-acts { display: flex; gap: 8px; }
.meal-acts .btn.on {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  color: var(--accent-ink);
}

/* A skipped meal is settled, not outstanding — dimmed rather than
   struck through, since it is still there to un-skip. */
.meal.skipped .meal-name,
.meal.skipped .kcal-tag { opacity: .45; }
.meal.skipped .meal-name { text-decoration: line-through; }
.meal.skipped .meal-check { opacity: .4; }
.meal-acts .btn { flex: 1; }
.kcal-tag.edited {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-ink);
}
.kcal-row { display: flex; gap: 8px; align-items: center; }
.kcal-row input { flex: 1; min-width: 0; }
.kcal-row .btn { width: auto; flex: 0 0 auto; }
.edit-hint {
  margin: -4px 0 14px; font-size: .76rem; color: var(--text-dim); line-height: 1.45;
}

/* custom ingredients carry a delete affordance */
.ing { position: relative; }
.ing-x {
  position: absolute; top: -6px; inset-inline-end: -6px;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: .6rem;
  background: var(--glass-strong); border: 1px solid var(--hairline);
  color: var(--danger);
}
.ing.no.on {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  border-color: color-mix(in srgb, var(--danger) 42%, transparent);
}
.ing.no.on .ing-glyph { filter: grayscale(1) opacity(.55); }

.ate-row {
  padding: 8px 0; border-bottom: 1px solid var(--hairline-dim);
  font-size: .86rem; color: var(--text-dim);
}
.ate-row:last-child { border-bottom: none; }

.sync-good { color: var(--accent-ink); }
.sync-bad { color: var(--danger); }

/* ---------- outlined icon set ---------- */
.ico { display: block; flex: 0 0 auto; }
.menu-glyph .ico, .metric-glyph .ico, .shield .ico,
.goal-dial .glyph .ico, .med-pill .ico { color: currentColor; }
.goal-dial .glyph { color: var(--c); }
.shield .ico { color: var(--text-mute); }
.avoid-tile.on .shield .ico { color: var(--c); }
.avoid-tile .shield { filter: none; }          /* line art needs no grey-out */
.avoid-tile.on .shield { background: color-mix(in srgb, var(--c) 14%, transparent); }
.med-pill .ico { color: var(--med); }
.metric-glyph .ico { color: var(--c); }
.menu-glyph .ico { color: var(--text-dim); }
.shop-icon { display: inline-flex; color: var(--text-mute); }
.seg .ico { display: inline-block; vertical-align: -3px; margin-inline-end: 5px; }
.lab-field label .ico { display: inline-block; vertical-align: -3px; margin-inline-end: 5px; }
.lock-mark .ico, .signin-mark .ico { margin: 0 auto; color: var(--accent); }

/* ---------- onboarding: art above, buttons pinned below ---------- */
/* The flow is exactly the height of the display and does not scroll as
   a page. #app carries 104px of bottom padding for the tab bar, which
   is not on screen here — left in place, that padding alone put every
   step over the viewport and gave the whole flow a scrollbar. */
html.onboarding #app {
  height: 100dvh;
  padding-bottom: 0;
  overflow: hidden;
}
.onb-root {
  display: flex; flex-direction: column;
  height: 100%;
}
/* Only the middle scrolls, and only when a step genuinely needs it —
   the details form on a short phone. The progress row and the buttons
   stay put. min-height:0 is what allows a flex child to shrink below
   its content and become the scroller. */
.onb-stage {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* The intro slides fill the stage and centre themselves in it. The form
   cards keep their natural height — stretching those left a short step
   like the pace picker as one tall empty card. */
.onb-stage > .onb-fancy { flex: 1 1 auto; }
.onb-stage > .card { flex: 0 0 auto; }


.onb-slide {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 4px 6px;
}
.onb-art-unused {
  width: 100%; max-width: 340px; aspect-ratio: 4 / 3;
  margin-bottom: 18px; color: var(--accent-ink);
  border-radius: var(--r-xl); overflow: hidden;
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}


.onb-slide .onb-title {
  font-size: 1.6rem; font-weight: 700; letter-spacing: -.028em;
  line-height: 1.18; margin: 0 0 10px; text-transform: none; color: var(--text);
}
.onb-slide .onb-body { max-width: 34ch; }

/* the footer sits at the bottom of the screen, clear of the home bar */
.onb-actions {
  flex: 0 0 auto;
  padding: 14px 4px calc(10px + env(safe-area-inset-bottom));
  margin-top: auto;
  /* transparent: the buttons are solid enough to read on their own,
     and the scrim was a visible band across the bottom of the two
     form steps */
  background: none;
}
.onb-actions.row2 { display: flex; gap: 10px; }
.onb-actions.row2 > .btn { flex: 1; }
.onb-back[hidden] { display: none; }


/* ============================================================
   touch targets
   ============================================================

   Several controls are drawn small on purpose — a 26px tick beside a
   meal, a 28px chevron, the language pills — and at those sizes they
   are below the 44px a thumb actually needs. Rather than inflating the
   artwork, each grows an invisible pad around itself. The control looks
   exactly the same and is simply easier to hit.

   Measured before: tick 26, chevron 28, refresh 30, language 43x29,
   back 55x26, steppers 36.                                          */
/* Only the ones drawn in normal flow. .icon-corner is already
   position:absolute and forcing it to relative dropped it back into the
   flow, where it sat on top of the card's heading. */
.meal-check, .chev, .spotlight-next, .stepper, .icon-btn, .back-btn,
.link-btn, .item-x, .ch-hide, .ing-x, .msg-copy, .craving-btn,
.langtoggle button, .meal-title, .seg button, .date-btn {
  position: relative;
}
.meal-check::after, .chev::after, .spotlight-next::after, .stepper::after,
.icon-btn::after, .back-btn::after, .link-btn::after, .item-x::after,
.ch-hide::after, .ing-x::after, .msg-copy::after, .craving-btn::after,
.langtoggle button::after, .meal-title::after, .icon-corner::after {
  content: '';
  position: absolute;
  /* the pad is centred on the control, so it never shifts the layout */
  inset: -9px;
}

/* Two of these sit close enough together that a -9px pad would overlap
   the neighbour and steal its taps. */
/* No pad on the full-size stepper: at 44px it already meets the
   minimum, and -5px each side made the minus and plus hit areas overlap
   by 2px — a tap in that band landed on whichever came later in the DOM. */
.stepper::after { inset: 0; }
.item-x::after  { inset: -7px; }
.ing-x::after   { inset: -6px; }

/* Vertical only, so the pad does not reach across to the control next
   to it. The short text links need more of it: some are only 18px tall. */
.link-btn::after { inset: -12px -4px; }
.msg-copy::after, .back-btn::after, .craving-btn::after { inset: -8px -4px; }
.meal-title::after { inset: -6px -2px; }
.langtoggle button::after { inset: -8px -2px; }


/* ============================================================
   onboarding — the fancy pass
   ============================================================

   Apple HIG: clarity, deference, depth. With no illustration to defer
   to, the content is the type, so it gets the large-title treatment
   and real space around it. Depth comes from light — three wide,
   blurred colour fields drifting behind the glass — rather than from
   anything drawn. 4pt spacing throughout, continuous corners, spring
   motion, and every animation removed for reduced-motion.            */

/* The app's own mesh, brought up so it carries the design where there
   are no cards to carry it.

   It is still held off the top of the screen. That band has to stay the
   flat page colour for two reasons: the status bar takes its colour
   from --page, so any wash up there and the phone's bar no longer
   matches the app; and colour arriving right at the notch reads as a
   coloured header rather than as light in the room. */
html.onboarding #mesh {
  opacity: .82;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 14%, #000 40%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0, transparent 14%, #000 40%, #000 100%);
}
/* html is the root, so it carries both classes — a descendant selector
   here would never match. */
html.onboarding[data-theme="dark"] #mesh { opacity: .62; }
@media (prefers-color-scheme: dark) {
  html.onboarding:not([data-theme="light"]) #mesh { opacity: .62; }
}

.onb-fancy { position: relative; display: flex; flex-direction: column; }

/* --- the type --- */
.onb-hero {
  flex: 1 1 auto;
  display: flex; flex-direction: column; justify-content: center;
  padding: 32px 4px 24px;
  text-align: start;
}

/* A step counter is a numeric run: it reads 01 / 03 in both languages.
   Left to the paragraph direction it came out "03 / 01" in Arabic. */
.onb-eyebrow {
  display: block; margin-bottom: 20px;
  direction: ltr; unicode-bidi: isolate;
  font-size: .78rem; font-weight: 800; letter-spacing: .16em;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}
.onb-eyebrow i { font-style: normal; opacity: .35; margin: 0 2px; }
html[dir="rtl"] .onb-eyebrow { text-align: right; }

/* Large-title proportions: tight tracking, tight leading, and enough
   size that it is the first and only thing read. */
.onb-fancy .onb-title {
  margin: 0 0 16px;
  font-size: clamp(2rem, 8.6vw, 2.7rem);
  font-weight: 800;
  letter-spacing: -.032em;
  line-height: 1.08;
  max-width: 16ch;
  text-wrap: balance;
}
.onb-fancy .onb-body {
  margin: 0;
  font-size: 1.02rem;
  line-height: 1.62;
  color: var(--text-dim);
  max-width: 34ch;
}
.onb-extra { margin-top: 20px; }
.onb-fancy .onb-medical { margin: 0; }

.onb-cta {
  border-radius: 14px;   /* continuous-corner proportion for a 56px control */
  font-size: 1.02rem;
  font-weight: 700;
  padding: 16px 20px;
  transition: transform .22s cubic-bezier(.2, .8, .25, 1), filter .22s;
}
.onb-cta:active { transform: scale(.97); filter: brightness(.97); }

/* --- choreography: each part a beat behind the last --- */
.onb-eyebrow, .onb-fancy .onb-title, .onb-fancy .onb-body, .onb-extra {
  animation: onbRise .62s cubic-bezier(.2, .8, .25, 1) both;
  animation-delay: var(--d, 0ms);
}
@keyframes onbRise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

/* --- the step dots, refined into a track --- */
.onb-fancy ~ .onb-bar .onb-dot,
.onb-bar .onb-dot {
  transition: width .32s cubic-bezier(.2, .8, .25, 1), background .32s;
}
.onb-bar .onb-dot.on { width: 22px; border-radius: 999px; }

@media (prefers-reduced-motion: reduce) {
  .onb-eyebrow, .onb-fancy .onb-title, .onb-fancy .onb-body,
  .onb-extra { animation: none; }
  .onb-cta { transition: none; }
}

/* A dose past its hour reads as overdue rather than upcoming. */
.next-tag.overdue { color: var(--warn); }

/* The rule behind the three numbers above it. */
.streak-rule { margin-top: 12px; margin-bottom: 0; font-size: 13px; line-height: 1.5; }
