/* ============================================================
   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.

   It ends where the keyboard starts (--kb, app.js), as a sheet does.
   Full height, the composer sat under the keys and the phone scrolled
   the whole screen to find it — and again with every key, as the box
   resized itself. */
.chat-screen {
  position: fixed; inset: 0 0 var(--kb, 0px) 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: 500;
  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(--btn), var(--btn-2));
  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: 500;
  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;   /* replaced by the global :focus-visible ring below */
  /* Grows with what is typed, laid out by the browser. Measured from
     script it was collapsed to nothing and regrown on every key, and
     the log above it jumped each time (views-coach.js). */
  field-sizing: content; min-height: calc(1.45em + 16px);
}
.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-ink); animation: chatdot .9s infinite; }
.chat-send {
  background: linear-gradient(180deg, var(--btn), var(--btn-2)); color: var(--on-accent);
  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: 500; 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; container-type: inline-size;
  padding: var(--pad-card);
  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; }
/* The section-label size (11.5px); no Latin tracking on Arabic. */
.ds-label {
  flex: 1; min-width: 0;
  font-size: .72rem; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-mute);
}
html[dir="rtl"] .ds-label, html[dir="rtl"] .ds-chip span { letter-spacing: 0; text-transform: none; }
/* The verdict's chip names wrap rather than end in an ellipsis. */
.daysum .ds-chip span { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.25; }

/* 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: 600; 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); }

/* 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: var(--pair-y);
}
.ds-chip b {
  font-size: .84rem; font-weight: 750; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ds-chip span {
  font-size: .72rem; font-weight: 600; 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); }
/* Over the plan (owner): the calorie figure alone, in red, with an
   arrow beside it so colour is never the only sign. */
.daysum .ds-chip.over b { color: var(--danger-ink); }
/* Each figure centred over its name, whatever sits beside it — an
   arrow, a tick. */
/* The figure alone in the middle column, so it sits exactly over its
   name; a tick or an arrow goes in the column beside it. */
.daysum .ds-chip b { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: 3px; }
.daysum .ds-chip .ds-n { grid-column: 2; }
.daysum .ds-chip b > svg, .daysum .ds-chip b > .tone-mark { grid-column: 3; justify-self: start; margin: 0; }
.daysum .ds-chip.over b svg { flex: none; }
/* At phone-card width, five equal columns leave fewer than 50px per
   caption in Arabic. Give the figures a balanced 3 + 2 grid instead. */
@container (max-width: 21rem) {
  .daysum .ds-strip { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px 6px; }
  .daysum .ds-chip { grid-column: span 2; }
  .daysum .ds-chip:nth-child(n + 4) { grid-column: span 3; }
}

/* Nothing done yet is not an error: no red, no mark — the figure says
   it, and toneMark gives a tick only to what is done (BRAND.md). */
.ds-chip.off b { color: var(--text); }
.ds-chip b .tone-mark { display: inline-grid; vertical-align: -2px; margin-inline-start: 4px; }
.ds-chip b .tone-mark svg { width: 12px; height: 12px; }
/* Said once under the figures: part of the calorie total is the plan's. */
.ds-borrowed { margin: 10px 0 0; font-size: .78rem; line-height: 1.5; color: var(--text-dim); }

/* a way into the two goals that are a skill rather than a number */
/* A ring that starts something wears a small play badge and breathes
   slowly. Both say "this does something" without a sentence explaining
   it, which is what sat here before. */
.dial-badge {
  position: absolute; inset-inline-end: -1px; bottom: -1px;
  width: 17px; height: 17px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--c); color: var(--on-bright);
  border: 2px solid var(--page);
  pointer-events: none;
}
.dial-badge svg { margin-inline-start: 1px; }   /* optical centring of a triangle */

.goal-dial.runnable::before {
  content: ''; position: absolute; inset: -3px;
  border-radius: 50%; border: 2px solid var(--c);
  opacity: .35;
  animation: dial-breathe 2.8s var(--ease) infinite;
}
@keyframes dial-breathe {
  0%, 100% { transform: scale(1);    opacity: .30; }
  50%      { transform: scale(1.07); opacity: .06; }
}
@media (prefers-reduced-motion: reduce) {
  .goal-dial.runnable::before { animation: none; opacity: .32; }
}

/* 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: 600;
  color: var(--ci); margin-inline-end: 4px;
}
.goal-name .reps {
  font-weight: 500; 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 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: 750;
  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 ----------
   Scoped to the element it was written for. Unscoped, its 6px bottom
   margin reached every <div class="lbl"> in the app — the word under
   the hero number on Progress and the calorie caption on Today — and
   .hero-meta .lbl only ever overrode the size and the colour, so the
   gap under those two was a plate-picker's and nobody had chosen it. */
label.lbl {
  display: block; font-size: .78rem; font-weight: 500;
  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: 500;
  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: 750;
  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: 750; 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: 750;
  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: 500; }
.food-k {
  flex: 0 0 auto; font-size: .72rem; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* ---------- editing a planned meal ---------- */
/* Emitted by views-core.js and never styled, so the browser default
   applied: 40px of padding-inline-start on top of the 36px .meal-body
   already has. 76px of indent out of a 296px card. */
.meal-items { list-style: none; margin: 0; padding: 0; }

/* Protein, carbs, fat, fibre: the day summary's own four-figure strip
   (.ds-strip / .ds-chip), value over name, so no separators and no
   line breaking in the middle of a figure. See nutriLine(). */
.nutri-strip { margin-top: 10px; }
.nutri-strip b { font-size: .95rem; color: var(--text); }
.nutri-strip b small { font-size: .72rem; font-weight: 500; color: var(--text-dim); }
.nutri-strip .nutri-na { color: var(--text-mute); font-weight: 500; }
html[dir="rtl"] .nutri-strip .ds-chip span { letter-spacing: 0; text-transform: none; font-size: .72rem; }
/* Inside a card that already has its own lines, the strip needs none. */
.meal-body .nutri-strip, .day-nutri .nutri-strip,
.edit-total + .nutri-strip { border-top: none; padding-top: 0; }
.meal-nutri-est + .edit-hint, .meal-nutri-est + .lg-src { margin-top: 8px; }
.meal-nutri-est { margin: 6px 0 0; }

/* The meal list and its foot: one line between them and none inside. */
.meal-list > .meal:last-child { border-bottom: none; }
.meal-foot { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--hairline-dim); }
/* The day's totals: the card's one tinted panel, headed by the
   calories, its four figures as tiles like a meal's but larger. */
.day-nutri {
  padding: var(--pad-panel); border-radius: var(--r-md);
  background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.day-kcal { font-size: 1.35rem; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.day-kcal small { font-size: .74rem; font-weight: 500; color: var(--text-dim); }
.day-nutri .nutri-strip {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 0;
}
.day-nutri .nutri-strip .ds-chip {
  padding: 10px 4px; border-radius: var(--r-sm); background: var(--glass-strong); text-align: center;
}

/* Something eaten outside the meals: a heading, then a grouped list in
   a box of its own — name over time, calories with their unit, and a
   full-size way to take it off. Lines only between rows. */
.extra-list {
  padding: 0 var(--pad-panel); border-radius: var(--r-md);
  background: var(--sunk-ink); border: 1px solid var(--edge);
}
.extra-row {
  display: flex; align-items: center; gap: 8px; min-height: 52px;
  border-bottom: 1px solid var(--hairline-dim); font-size: .84rem;
}
.extra-row:last-child { border-bottom: none; }
.extra-what { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--pair-y); padding: 8px 0; }
.extra-n { font-size: .92rem; font-weight: 500; overflow-wrap: anywhere; }
.extra-at { color: var(--text-mute); font-size: .76rem; font-variant-numeric: tabular-nums; }
.extra-kcal { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }
.extra-kcal small { font-weight: 500; color: var(--text-dim); }
.extra-kcal.nutri-na { font-weight: 500; color: var(--text-mute); }
.extra-row .item-x { min-width: 44px; min-height: 44px; margin-inline-end: -10px; }

/* The two ways in, side by side: adding what was eaten is the tinted
   one with a filled plus; the craving timer the neutral one. Each is
   at least as wide as its own words, so where a wider font (a phone's
   own, or Linux's while Thmanyah loads) cannot fit both on one row,
   they take a full row each rather than the label running out of its
   button. */
.foot-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; container-type: inline-size; }
.foot-acts > .foot-btn { flex: 1 1 calc(50% - 4px); min-width: max-content; }
.foot-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 0; min-height: 48px; padding: 8px 10px; border-radius: var(--r-sm);
  font: inherit; font-size: .88rem; font-weight: 600; text-align: center; cursor: pointer;
  transition: transform .16s var(--ease);
}
.foot-btn:active { transform: scale(.97); }
.foot-btn.log-extra {
  background: var(--accent-wash); color: var(--accent-ink);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
}
.foot-btn.meal-craving { background: var(--sunk-ink); color: var(--text); border: 1px solid var(--edge); }
.add-dot, .foot-ico { display: inline-grid; place-items: center; width: 24px; height: 24px; flex: none; }
.add-dot { border-radius: 50%; background: var(--btn); color: var(--on-accent); }
.foot-ico { color: var(--text-dim); }

/* The review sheet. */
.lg-said { margin: 0 0 14px; padding: 10px 12px; border-radius: 12px; background: var(--glass-sunk); font-size: .92rem; }
.lg-block { margin: 0 0 14px; }
.lg-block > .section-label { margin: 0 0 6px; }
.lg-q-text { margin: 0 0 8px; font-weight: 600; font-size: .9rem; }
/* An answer is not an add-on: ink, not dim, and a firmer edge. */
.chip-btn.q { color: var(--text); font-weight: 600; border-color: var(--edge); min-height: 44px; }
.lg-items .item-food { text-decoration: none; cursor: default; }
.lg-add { display: flex; align-items: center; min-height: 44px; margin-top: 2px; font-size: .86rem; }
.lg-src { margin-top: 8px; color: var(--text-mute); }
.lg-photo { margin: 0; color: var(--warn-ink); }
/* The photo: two real buttons side by side, the camera and the gallery. */
.lg-photo-or { margin: 4px 0 6px; }
.lg-photo-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0 0 14px; }
.lg-photo-acts .lg-photo-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; min-height: 44px; margin: 0; white-space: normal;
}
/* The photo that was read, beside what it was read as. */
.lg-photo-box {
  display: grid; grid-template-columns: 88px 1fr; gap: 6px 12px; align-items: start;
  margin: 0 0 10px; padding: var(--pad-panel); border-radius: var(--r-md);
  background: var(--sunk-ink); border: 1px solid var(--edge);
}
.lg-photo-img { grid-row: span 2; width: 88px; height: 88px; object-fit: cover; border-radius: var(--r-sm); }
.lg-photo-box:not(:has(img)) { grid-template-columns: 1fr; }
.lg-photo-rm { justify-self: start; min-height: 44px; font-size: .86rem; color: var(--text-dim); }
/* "Log it" stays in reach however long the list is: the sheet's one
   filled button, in a foot that sticks to the bottom of the sheet. */
.lg-foot {
  position: sticky; bottom: calc(-22px - env(safe-area-inset-bottom));
  margin: 16px -16px 0; padding: 12px 16px calc(22px + env(safe-area-inset-bottom));
  /* Solid, not the sheet's glass: what scrolls under it must not read
     through the button that logs it. */
  background: var(--page); border-top: 1px solid var(--hairline-dim);
  display: flex; flex-direction: column; align-items: stretch; gap: 4px;
}
.lg-foot .link-btn { min-height: 44px; font-size: .86rem; color: var(--text-dim); }

/* The add-food sheet's four optional packet figures, two by two. */
.af-label { margin: 24px 0 8px; }
.af-unit { color: var(--text-dim); font-weight: 500; }
.af-grid + .edit-hint { margin-top: 8px; }
.af-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.af-grid input { width: 100%; min-width: 0; }

/* The meal editor's quick add-ons: ordinary chips, wrapping. */
.addon-lbl { margin: 14px 0 6px; }
.addons { display: flex; flex-wrap: wrap; gap: 6px; }


/* Distilled: what is in the meal is a quiet list — no box, no rules. */
.meal-items li {
  font-size: .9rem; line-height: 1.45; padding: 3px 0; color: var(--text-dim);
}
.meal-body > .meal-items { margin: 2px 0 4px; }

/* The one way in: tinted, not filled — the screen keeps its single
   filled button — full width, icon beside its words. */
/* Two equals, side by side: eaten as planned, or something else. */
.meal-acts-main { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
@container (max-width: 12rem) { .meal-acts-main { grid-template-columns: 1fr; } }
.meal-body .btn.meal-act-main {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-width: 0; min-height: 48px; margin: 0; padding: 10px 12px; white-space: normal; line-height: 1.25;
  border-radius: var(--r-sm); font-weight: 600;
}
.meal-body .btn.tonal.meal-act-main {
  background: var(--accent-wash); color: var(--accent-ink);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  box-shadow: none; border-radius: var(--r-sm); font-weight: 600;
}

/* The tools: one row of equal cells, each an icon in a tinted circle
   over a short name, the way a map's place card lays out its actions. */
/* Keep the actions together on a phone; enlarged text may wrap them
   when a 44px target no longer fits. */
.meal-body { container-type: inline-size; }
.meal-tools {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px; margin-top: 8px;
}
@container (max-width: 8rem) {
  .meal-tools { grid-template-columns: minmax(0, 1fr); }
}

/* The day's four figures follow the same rule: four across when they
   fit, two by two when they do not, one column with very big text —
   never a clipped number or a label cut to "بر…". */
.meal-foot { container-type: inline-size; }
.day-nutri .nutri-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.day-nutri .ds-chip span {
  white-space: normal; overflow: visible; overflow-wrap: normal; text-transform: none; letter-spacing: 0;
}
@container (min-width: 21rem) {
  .day-nutri .nutri-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@container (max-width: 12rem) {
  .day-nutri .nutri-strip { grid-template-columns: minmax(0, 1fr); }
}
.meal-tool {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-width: 0; min-height: 72px; padding: 10px 4px;
  background: var(--sunk-ink); color: var(--text);
  border: 1px solid var(--edge); border-radius: var(--r-sm);
  font: inherit; font-size: .76rem; font-weight: 600; line-height: 1.2; text-align: center;
  cursor: pointer; transition: transform .16s var(--ease), background .18s var(--ease);
}
.tool-ico {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent-wash); color: var(--accent-ink);
}
.tool-lbl { overflow-wrap: normal; word-break: normal; max-width: 100%; }
.meal-tool:active { transform: scale(.96); }
.meal-tool.on { background: var(--accent-wash); color: var(--accent-ink); }
html[dir="rtl"] .meal-tool[data-skipmeal] svg { transform: scaleX(-1); }

/* The tools, on show as a toolbar: an icon in brand ink over a short
   name, no boxes. Four or five equal targets share a row at phone width. */
.meal-body .meal-tools {
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px;
  margin-block-start: 6px; margin-inline-start: -36px; margin-inline-end: 0;
}
@container (min-width: 12rem) {
  .meal-body .meal-tools:not(:has(> :nth-child(5))) {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  }
}
@container (min-width: 13.75rem) {
  .meal-body .meal-tools:has(> :nth-child(5)) {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  }
}
.meal-body .meal-tool {
  flex-direction: column; justify-content: center; gap: 4px;
  min-height: 56px; padding: 6px 2px; border: 0; background: transparent;
  font-size: .74rem; font-weight: 600; color: var(--text-dim); border-radius: var(--r-sm);
}
.meal-body .meal-tool:active { background: var(--sunk-ink); }
.meal-body .meal-tool .tool-ico { width: auto; height: auto; background: none; color: var(--accent-ink); }
.meal-body .meal-tool.on { background: var(--accent-wash); color: var(--accent-ink); }
@container (max-width: 14rem) {
  html[lang="en"] .meal-body .meal-tools:has(> :nth-child(5)) .meal-tool:first-child .tool-lbl {
    font-size: .68rem; letter-spacing: -.025em;
  }
}

/* The day's totals as a card of their own: the card's padding and
   corners, the tint that sets them apart. */
.card.day-nutri { padding: var(--pad-card); border-radius: var(--r-lg); }

/* Eaten today, as a widget (Health's grammar in Sahha's clothes): the
   card's own glass, a small title in brand ink, the figure large with
   the target and what is left beside it, a teal ring, and the four
   figures as one quiet row under a hairline — no tiles. */
.card.day-nutri.eaten-widget {
  container-type: inline-size;
  background: var(--glass); border: 1px solid var(--hairline); box-shadow: var(--shadow);
}
.ew-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.ew-text { display: flex; flex-direction: column; gap: var(--pair-y); min-width: 0; }
/* The heading is the section label every other card uses. */
.ew-title { margin: 0 0 6px; }
.ew-least { font-size: .8rem; font-weight: 600; letter-spacing: 0; color: var(--text-dim); }
.ew-left.over { color: var(--text); font-weight: 600; }
/* Past the target the ring stops reading as success: the "not there
   yet" amber, with the words beside it saying how far over. */
.ew-ring.over .ew-arc { stroke: var(--warn); }
.eaten-widget .day-kcal { font-size: 2rem; font-weight: 600; letter-spacing: -.03em; line-height: 1.05; }
.eaten-widget .day-kcal small { font-size: .8rem; font-weight: 500; letter-spacing: 0; color: var(--text-dim); }
.ew-left { font-size: .84rem; color: var(--text-dim); }
/* The ring, larger, with how far along written in its middle. */
.ew-ring-wrap { position: relative; flex: none; width: 88px; height: 88px; display: grid; place-items: center; }
.ew-ring { position: absolute; inset: 0; width: 88px; height: 88px; transform: rotate(-90deg); }
.ew-pct { position: relative; font-size: .95rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--accent-ink); }
.ew-ring.over + .ew-pct { color: var(--warn-ink); }
html[dir="rtl"] .ew-ring { transform: rotate(-90deg) scaleY(-1); }
.ew-track, .ew-arc { fill: none; stroke-width: 6; }
.ew-track { stroke: var(--sunk-ink); }
.ew-arc { stroke: var(--accent); stroke-linecap: round; transition: stroke-dashoffset .5s var(--ease); }
@media (prefers-reduced-motion: reduce) { .ew-arc { transition: none; } }
.eaten-widget .nutri-strip {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 0;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline-dim);
}
@container (min-width: 19rem) { .eaten-widget .nutri-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.eaten-widget .nutri-strip .ds-chip {
  background: transparent; border: 0; border-radius: 0; padding: 0 6px; text-align: center;
}
.eaten-widget .nutri-strip .ds-chip + .ds-chip { border-inline-start: 1px solid var(--hairline-dim); }
.eaten-widget .nutri-strip b { font-size: .98rem; }
.eaten-widget .meal-nutri-est { margin-top: 10px; }

/* Before anything is logged: a plate, a sentence and the way in, in
   place of a zero and an empty ring. */
.ew-empty-row { display: flex; align-items: center; gap: 14px; }
.ew-empty-ico {
  flex: none; width: 52px; height: 52px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 13%, transparent);
}
.ew-empty-line { font-size: 1.02rem; font-weight: 600; line-height: 1.35; }
.ew-first { margin-top: 14px; width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; }

/* The extras, folded: one row saying how many and what they add; the
   list opens under it. */
.extra-group { margin-top: 14px; }
.extra-group > summary {
  display: flex; align-items: center; gap: 8px; min-height: 44px; list-style: none; cursor: pointer;
}
.extra-group > summary::-webkit-details-marker { display: none; }
.extra-sum-name { flex: 1 1 auto; font-size: .9rem; font-weight: 600; }
.extra-sum-meta { font-size: .84rem; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.extra-group > summary::after {
  content: ""; width: 7px; height: 7px; margin-inline-start: 4px;
  border-right: 1.8px solid var(--text-mute); border-bottom: 1.8px solid var(--text-mute);
  transform: rotate(45deg) translateY(-2px); transition: transform .18s var(--ease);
}
.extra-group[open] > summary::after { transform: rotate(-135deg) translateY(-1px); }
.extra-group[open] > .extra-list { margin-top: 6px; }

/* A settled meal's Edit (and bring-back): full-width buttons. */
.meal-settled { display: grid; gap: 8px; margin-top: 10px; }
.meal-body .meal-settled .btn { display: block; width: 100%; margin: 0; min-height: 48px; }

/* The two ways in at the foot: tinted, borderless, the same height. */
.foot-btn.log-extra, .foot-btn.meal-craving { border: 0; min-height: 48px; }
.foot-btn.meal-craving { background: var(--sunk-ink); }
.foot-btn .add-dot { width: auto; height: auto; background: none; color: currentColor; border-radius: 0; }
@container (max-width: 17rem) {
  .foot-acts .foot-btn { gap: 4px; padding-inline: 6px; font-size: .82rem; white-space: nowrap; }
  .foot-acts .foot-btn svg { width: 16px; height: 16px; }
}

/* "Up next", said in a word on a pill of its own. */
.now-pill {
  display: inline-block; margin-inline-start: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--accent-wash); color: var(--accent-ink);
  font-size: .72rem; font-weight: 700; letter-spacing: 0; text-transform: none; vertical-align: 1px;
}
.kcal-tag small { font-size: .7rem; font-weight: 500; color: var(--text-dim); }

/* The evening card, when meals are unlogged: said plainly, with the
   way to log them beside it. */
.ds-unlogged { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.ds-catchup { min-height: 44px; font-weight: 600; color: var(--accent-ink); }

/* A meal whose time passed with nothing logged: a quiet tag, in words. */
.meal-late {
  display: inline-block; margin-inline-start: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--sunk-ink); color: var(--text-dim);
  font-size: .72rem; font-weight: 600; letter-spacing: 0; text-transform: none; vertical-align: 1px;
}
.ew-pct { display: flex; flex-direction: column; align-items: center; line-height: 1.1; }
.ew-pct small { font-size: .7rem; font-weight: 600; color: var(--text-dim); }

/* A corner add that says what it adds: "Log weight", "Add a scan". */
.icon-corner.word {
  width: auto; height: 34px; padding: 0 12px; gap: 4px; border-radius: 999px;
  display: inline-flex; align-items: center; font: inherit; font-size: .78rem; font-weight: 600;
  color: var(--accent-ink); background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.icon-corner.word svg { width: 14px; height: 14px; }
.card.with-corner-end:has(> .icon-corner.word) > .card-head { padding-inline-end: 132px; }

/* The way back on a toast: a real button, reachable while it shows. */
.toast-act {
  pointer-events: auto; border: 0; background: none; padding: 6px 2px; min-height: 36px;
  font: inherit; font-weight: 700; color: var(--accent-ink); cursor: pointer;
}

/* With no scan the organ is a drawing, not a reading: no colour of
   health, no glow — nothing that says "yours looks healthy". */
.liver-card.no-scan .liver-glow { display: none; }
.liver-card.no-scan .liver-card-visual { filter: grayscale(1) contrast(.9); opacity: .72; }

/* An open meal still to come keeps the circle's place but not the
   circle: "Ate it" below says the same thing. */
.meal-check.held { visibility: hidden; }

/* Eaten is done, not cancelled: the name stays readable. Only a skipped
   meal is struck through. */
.meal.done .meal-name { text-decoration: none; color: var(--text-dim); }

/* 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; }
.kcal-tag.edited {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-ink);
}

.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.no.on {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  border-color: color-mix(in srgb, var(--danger) 42%, transparent);
}

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

/* ---------- 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(--ci); }
.shield .ico { color: var(--text-mute); }
.avoid-tile.on .shield .ico { color: var(--ci); }
.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-ink); }
.metric-glyph .ico { color: var(--ci); }
.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; }
.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; }

/* 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; }

/* ---------- saying it, and checking before eating ----------
   The mic sits inside the box at its end, a 44px target, and says it is
   listening by its pressed state as well as its tint. The check is a
   quiet panel: what is left, or by how much the day goes over — that
   one with an arrow and the danger ink, never the colour alone. */
.lg-say { position: relative; }
.lg-say textarea { padding-inline-end: 56px; }
.lg-mic {
  position: absolute; inset-block-start: 6px; inset-inline-end: 6px;
  inline-size: 44px; block-size: 44px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--hairline); background: var(--glass-sunk); color: var(--accent-ink);
}
.lg-mic.on { background: var(--accent-wash); border-color: var(--accent); }
.lg-mic.on svg { animation: lgMicPulse 1.1s var(--ease) infinite; }
@keyframes lgMicPulse { 50% { transform: scale(1.15); } }
@media (prefers-reduced-motion: reduce) { .lg-mic.on svg { animation: none; } }
.lg-check-open { display: block; margin: 10px auto 0; min-block-size: 44px; font-size: .86rem; color: var(--accent-ink); }
.lg-check-box { margin: 14px 0 4px; padding: 12px 14px; border-radius: 14px; background: var(--glass-sunk); border: 1px solid var(--hairline-dim); }
.lg-check-line { display: flex; align-items: center; gap: 6px; margin: 0; font-weight: 600; font-size: .95rem; }
.lg-check-box.over .lg-check-line { color: var(--danger-ink); }
.lg-check-warn { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; }
.lg-check-warn svg, .lg-check-line svg { flex: none; }
