/* ════════════════════════════════════════════════════════════════════
   DeepForm v7 — "Deep" design system.
   Ink and paper. The page is a deep blue-black (dark) or a cool paper
   (light), switched via [data-theme] on <html>, and the accent is the
   opposite pole of whichever it is: white on ink, ink on paper. The day's
   energy and the thing to press are drawn in it, plainly. Colour is kept
   for what it can tell apart: amber carbohydrate, orchid protein, sky fat,
   and the status colours. Headline numbers are set in the display face,
   small data in mono, everything else in the UI face.

   Two accent tokens: --accent fills (with --on-accent on top of it), and
   --accent-ink is the accent as text, a focus ring or a line.
   ════════════════════════════════════════════════════════════════════ */

/* ─── Tokens ─── */
:root, [data-theme="dark"] {
  --bg:        oklch(0.150 0.022 262);
  --bg-2:      oklch(0.125 0.020 262);
  --bg-elev:   oklch(0.215 0.028 262);
  --surface:   oklch(0.198 0.026 262);
  --surface-2: oklch(0.250 0.029 262);
  --surface-hi:oklch(0.305 0.032 262);
  --border:    oklch(0.90 0.03 262 / 0.08);
  --border-hi: oklch(0.90 0.03 262 / 0.17);
  --hairline:  oklch(0.90 0.03 262 / 0.07);

  --t-hi:  oklch(0.975 0.006 262);
  --t-md:  oklch(0.815 0.018 262);
  --t-lo:  oklch(0.675 0.024 262);
  --t-xlo: oklch(0.480 0.026 262);

  --accent:     oklch(0.975 0.006 262);
  --accent-ink: oklch(0.975 0.006 262);
  --accent-dim: oklch(0.975 0.006 262 / 0.10);
  --on-accent:  oklch(0.17 0.025 262);

  /* the day's energy is the accent; the macros are a triad that stays clear
     of the status colours below */
  --c-kcal: oklch(0.975 0.006 262);
  --c-carb: oklch(0.855 0.150 86);    /* amber  */
  --c-prot: oklch(0.770 0.165 338);   /* orchid */
  --c-fat:  oklch(0.790 0.125 236);   /* sky    */
  --track:  oklch(0.90 0.03 262 / 0.10);

  --ok:   oklch(0.82 0.17 152); --ok-dim:   oklch(0.82 0.17 152 / 0.15);
  --warn: oklch(0.80 0.15 58);  --warn-dim: oklch(0.80 0.15 58 / 0.16);
  --bad:  oklch(0.71 0.19 24);  --bad-dim:  oklch(0.71 0.19 24 / 0.17);
  --info: oklch(0.79 0.125 236); --info-dim: oklch(0.79 0.125 236 / 0.16);

  /* energy availability: red = low (deeper when very low), green = adequate,
     amber = abundant */
  --ea-vlow: oklch(0.62 0.22 22);
  --ea-low:  oklch(0.72 0.18 32);
  --ea-ok:   oklch(0.82 0.17 152);
  --ea-high: oklch(0.83 0.15 78);

  --shadow-card: none;
  --shadow-pop:  0 24px 60px -24px oklch(0.05 0.02 262 / 0.9), 0 4px 14px -6px oklch(0.05 0.02 262 / 0.6);
  --shadow-fab:  0 14px 34px -10px oklch(0.05 0.02 262 / 0.85), 0 2px 6px oklch(0.05 0.02 262 / 0.4);
  --scrim:       oklch(0.06 0.02 262 / 0.62);
  /* the login card reads this name */
  --metal: var(--surface);
  --sheen-top: transparent;

  /* the log dock: frosted, with the one filled button */
  --dock-bg:      oklch(0.245 0.032 262 / 0.84);
  --dock-border:  oklch(0.90 0.03 262 / 0.16);
  --dock-fg:      oklch(0.815 0.018 262);
  --dock-fg-hi:   oklch(0.975 0.006 262);
  --dock-press:   oklch(0.90 0.03 262 / 0.12);

  --fui:   "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --fdisp: "Bricolage Grotesque", "Geist", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --fmono: "Geist Mono", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --r-sm: 12px; --r-md: 16px; --r-lg: 24px; --r-xl: 30px; --r-pill: 999px;
  --ease: cubic-bezier(.2,.8,.2,1);
  --spring: cubic-bezier(.3,1.35,.5,1);
  --page-x: 16px;
  /* SN-H-03 — the shell's widths. JUDGEMENT: compact under --shell-medium,
     medium up to --shell-expanded, expanded from it. app.js reads these two
     and puts compact, medium or expanded on .app-root; nothing else repeats
     the numbers. */
  --shell-medium: 600px;
  --shell-expanded: 1024px;
  --shell-max: 1440px;       /* the expanded shell stops growing here */
  --col-gap: 20px;

  /* Where the log dock rests above the bottom edge. On a phone with a home
     indicator it sits partway into that inset, just clear of the bar, the way
     the system's own floating bars do; everywhere else, 12px. */
  --dock-b: max(12px, env(safe-area-inset-bottom, 0px) - 10px);
}

[data-theme="light"] {
  --bg:        oklch(0.968 0.008 262);
  --bg-2:      oklch(0.945 0.010 262);
  --bg-elev:   oklch(0.995 0.003 262);
  --surface:   oklch(1 0 0);
  --surface-2: oklch(0.956 0.009 262);
  --surface-hi:oklch(0.920 0.013 262);
  --border:    oklch(0.25 0.05 262 / 0.07);
  --border-hi: oklch(0.25 0.05 262 / 0.17);
  --hairline:  oklch(0.25 0.05 262 / 0.07);

  --t-hi:  oklch(0.215 0.045 262);
  --t-md:  oklch(0.400 0.040 262);
  --t-lo:  oklch(0.515 0.034 262);
  --t-xlo: oklch(0.680 0.024 262);

  --accent:     oklch(0.215 0.045 262);
  --accent-ink: oklch(0.215 0.045 262);
  --accent-dim: oklch(0.215 0.045 262 / 0.07);
  --on-accent:  oklch(0.99 0.002 262);

  --c-kcal: oklch(0.215 0.045 262);
  --c-carb: oklch(0.74 0.165 72);
  --c-prot: oklch(0.61 0.21 342);
  --c-fat:  oklch(0.61 0.16 248);
  --track:  oklch(0.25 0.05 262 / 0.08);

  --ok:   oklch(0.53 0.15 152); --ok-dim:   oklch(0.53 0.15 152 / 0.13);
  --warn: oklch(0.58 0.14 55);  --warn-dim: oklch(0.58 0.14 55 / 0.14);
  --bad:  oklch(0.54 0.20 24);  --bad-dim:  oklch(0.54 0.20 24 / 0.12);
  --info: oklch(0.52 0.15 248); --info-dim: oklch(0.52 0.15 248 / 0.12);

  --ea-vlow: oklch(0.50 0.21 24);
  --ea-low:  oklch(0.62 0.20 30);
  --ea-ok:   oklch(0.58 0.16 152);
  --ea-high: oklch(0.70 0.16 68);

  --shadow-card: 0 1px 2px oklch(0.25 0.05 262 / 0.04), 0 12px 28px -20px oklch(0.25 0.05 262 / 0.22);
  --shadow-pop:  0 18px 44px -18px oklch(0.25 0.05 262 / 0.32), 0 3px 10px -4px oklch(0.25 0.05 262 / 0.12);
  --shadow-fab:  0 14px 30px -10px oklch(0.25 0.05 262 / 0.5), 0 2px 6px oklch(0.25 0.05 262 / 0.2);
  --scrim:       oklch(0.20 0.04 262 / 0.42);

  --dock-bg:      oklch(1 0 0 / 0.82);
  --dock-border:  oklch(0.25 0.05 262 / 0.10);
  --dock-fg:      oklch(0.400 0.040 262);
  --dock-fg-hi:   oklch(0.215 0.045 262);
  --dock-press:   oklch(0.25 0.05 262 / 0.08);
}

* { box-sizing: border-box; }
/* Height chain uses 100% (not 100dvh): in iOS/Android standalone mode dvh can
   be computed against a phantom browser toolbar, leaving a dead black band at
   the bottom of the screen.
   html carries the app background so any viewport gap (keyboard dismissal,
   rotation, overscroll) paints as the app, never as black. */
html, body { margin: 0; padding: 0; height: 100%; }
html { background: var(--bg); overscroll-behavior: none; }
/* On iOS 26 that is not enough. A home-screen app with a translucent status
   bar is given the whole screen to draw on but a layout viewport one status
   bar short of it (WebKit bug 301108): 100%, dvh and svh all stop that far
   above the bottom edge, and so does anything fixed, because iOS pins fixed
   boxes to the end of the document rather than the screen. lvh is the unit
   that still measures the screen, so the document is made that tall and the
   full-screen layers take their height from it instead of from `bottom: 0`.
   Where nothing is wrong lvh and 100% are the same number. */
@media (display-mode: standalone) {
  @supports (-webkit-touch-callout: none) and (height: 100lvh) {
    html { height: max(100%, 100lvh); }
    .app-root, .sheet-scrim, .login-wrap { bottom: auto; height: max(100%, 100lvh); }
  }
}
body {
  font-family: var(--fui);
  background: var(--bg);
  color: var(--t-hi);
  font-size: 14px;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
  overscroll-behavior: none;
}

.num { font-family: var(--fmono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.dim { color: var(--t-md); }
.muted { color: var(--t-lo); }
.ok { color: var(--ok); } .warn { color: var(--warn); } .bad { color: var(--bad); }

/* Touch first. `manipulation` drops the double-tap-to-zoom wait, so a tap acts
   when it lands; chrome is not selectable, so a long press on a button never
   raises the text-selection callout. Fields stay selectable. */
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
input:focus-visible, textarea:focus-visible { outline: none; }

/* ─── App shell ─── */
.app-root {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background: var(--bg);
  overflow: hidden; overflow: clip;
}
.screen {
  color: var(--t-hi);
  height: 100%; width: 100%;
  max-width: 480px; margin: 0 auto;
  display: flex; flex-direction: column;
  position: relative;
  /* clip, not hidden: the closed log sheet is parked below the bottom edge by
     a transform, which still counts as scrollable overflow. `hidden` stops a
     finger scrolling to it but not the browser, which will scroll this box to
     reveal a focused field — and take the header off screen with it. */
  overflow: hidden; overflow: clip;
}

/* ─── The day pager ───
   The day on screen is the middle page of three on a track that follows the
   finger sideways; the days either side of it sit a page-width and a gap
   away, already built, and come into view as it moves. `pan-y` leaves the
   up-and-down scroll to the browser and hands every sideways movement to the
   pager; it has to sit on the scroller itself, because the browser stops
   looking for touch-action at the nearest scroll container. */
.pager { position: relative; flex: 1; min-height: 0; overflow: hidden; overflow: clip; }
.pager-track { position: relative; height: 100%; will-change: transform; }
/* the page slips under the header instead of being cut off by it */
.pager::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 16px; z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom, var(--bg), transparent); }
/* --slot is where the page lies from the day on screen: −1, 0 or 1. The gap
   is the pager's `gap` in app.js. */
.page { position: absolute; top: 0; bottom: 0; width: 100%; left: calc(var(--slot) * (100% + 28px)); }
.screen-scroll {
  height: 100%; overflow-y: auto; overflow-x: hidden;
  scrollbar-width: none; touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}
.screen-scroll::-webkit-scrollbar { display: none; }

/* Pull to refresh (components.js usePullRefresh): the mark that shows in the
   gap a pulled-down page leaves. Placed and faded by the hook; --pull is how
   far to the point where letting go syncs, 0 to 1, and the ring fills with
   it, turning green once it is there. */
.pull-mark {
  position: absolute; top: 0; left: 50%; z-index: 3; pointer-events: none;
  width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  background: var(--bg-elev); border: 1px solid var(--border-hi); color: var(--t-md);
  opacity: 0; transform: translate3d(-50%,-16px,0); --pull: 0;
}
.pull-mark svg { transform: rotate(calc(-90deg + var(--pull) * 180deg)); }
.pull-mark circle { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: calc(100 - var(--pull) * 85); transition: stroke .2s; }
.pull-mark.ready, .pull-mark.spin { color: var(--ok); }
.pull-mark.spin svg { animation: spin .8s linear infinite; }

/* ─── Top bar: one row ─── */
.top-bar { position: relative; z-index: 5; }
.app-header {
  display: flex; align-items: center; gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) var(--page-x) 8px;
}
.app-header .brand { position: relative; flex: none; }
.brand-mark { display: block; width: 36px; height: 36px; }
.brand-mark .bm-tile { fill: var(--surface-2); }
.brand-mark .bm-glyph { fill: none; stroke: var(--t-hi); stroke-width: 3.4; stroke-linejoin: round; }
.app-header .v2-tag { position: absolute; right: -7px; bottom: -4px; padding: 1px 4px; font-size: 8.5px; line-height: 1.2; background: var(--bg); border-color: var(--border-hi); border-radius: 6px; }

.date-trigger {
  flex: 0 1 auto; min-width: 0; min-height: 48px;
  display: flex; align-items: center; gap: 7px;
  padding: 0 8px; margin-left: -2px; border-radius: var(--r-md); text-align: left;
  transition: background .16s;
}
.date-trigger.open { background: var(--surface); }
@media (hover: hover) { .date-trigger:hover { background: var(--surface); } }
.date-meta { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.date-title { font-family: var(--fdisp); font-size: 23px; font-weight: 700; letter-spacing: -0.035em; line-height: 1.05; color: var(--t-hi); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.date-rel { font-size: 12px; color: var(--t-lo); line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.date-trigger .chev { flex: none; align-self: flex-start; margin-top: 9px; color: var(--t-lo); transition: transform .3s var(--ease); }
.date-trigger.open .chev { transform: rotate(180deg); }

.header-actions { display: flex; gap: 6px; align-items: center; flex: none; margin-left: auto; }
/* the narrowest phones: the engine pill keeps its icon and drops its word */
@media (max-width: 359px) { .engine-pill span { display: none; } .engine-pill { padding: 0 11px; } }
/* 36px pills in a 44px row: the ::after carries the hit area to full height */
.today-pill, .engine-pill { position: relative; height: 36px; border-radius: var(--r-pill); font-size: 12.5px; font-weight: 600; white-space: nowrap; transition: transform .16s var(--ease), background .16s; }
.today-pill::after, .engine-pill::after { content: ""; position: absolute; inset: -4px -2px; }
.today-pill:active, .engine-pill:active { transform: scale(0.94); }
.today-pill { padding: 0 13px; background: var(--accent-dim); color: var(--accent-ink); animation: pop-in .26s var(--ease); }
.engine-pill { display: inline-flex; align-items: center; gap: 6px; padding: 0 13px 0 11px; background: var(--surface); border: 1px solid var(--border); color: var(--t-hi); }
.engine-pill svg { color: var(--t-md); }

.icon-btn {
  width: 36px; height: 36px; border-radius: 50%; flex: none;
  display: grid; place-items: center; color: var(--t-md);
  transition: background .16s, color .16s, transform .16s var(--ease);
}
.icon-btn.big { width: 44px; height: 44px; margin-right: -10px; }
@media (hover: hover) { .icon-btn:hover { color: var(--t-hi); background: var(--surface); } }
.icon-btn:active { transform: scale(0.9); }
.icon-btn:disabled { opacity: 0.4; cursor: default; }
.spin svg { animation: spin 0.8s linear infinite; }

/* Sync state, and the button that syncs. A dot while all is well; it grows a
   word only when there is something to say. */
.live-dot {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-width: 32px; height: 44px; padding: 0 6px;
  font-size: 10.5px; color: var(--t-lo);
  font-family: var(--fmono); letter-spacing: 0.06em; font-weight: 500; text-transform: uppercase; white-space: nowrap;
  transition: color .2s;
}
.live-dot:active { opacity: 0.6; }
.live-dot i { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-dim); transition: background .2s, box-shadow .2s; }
.live-dot.offline i { background: var(--t-lo); box-shadow: 0 0 0 3px var(--track); }
.live-dot.busy i { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-dim); animation: pulse 1.1s ease-in-out infinite; }
.live-dot.err { color: var(--bad); }
.live-dot.err i { background: var(--bad); box-shadow: 0 0 0 3px var(--bad-dim); }
@keyframes pulse { 50% { opacity: 0.35; } }

/* ─── Section ─── */
.section { padding: 14px var(--page-x) 0; }
.day-view > .section:first-child, .day-view > .col > .section:first-child { padding-top: 14px; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 18px;
  box-shadow: var(--shadow-card);
}

/* entrance: sections settle in one after another, replayed per day */
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.day-view > .section, .day-view > .col > .section { animation: rise .5s var(--ease) backwards; }
.day-view > .section:nth-child(2) { animation-delay: .06s; }
.day-view > .section:nth-child(3) { animation-delay: .12s; }
.day-view > .section:nth-child(4) { animation-delay: .18s; }
.day-view > .section:nth-child(5) { animation-delay: .24s; }
/* arriving from another day: in from the side that day lies on */
@keyframes slide-next { from { opacity: 0; transform: translateX(30px); } to { opacity: 1; transform: none; } }
@keyframes slide-prev { from { opacity: 0; transform: translateX(-30px); } to { opacity: 1; transform: none; } }
.day-view.from-next > .section, .day-view.from-next > .col > .section { animation-name: slide-next; animation-duration: .38s; }
.day-view.from-prev > .section, .day-view.from-prev > .col > .section { animation-name: slide-prev; animation-duration: .38s; }
.day-view.from-next > .section:nth-child(n), .day-view.from-prev > .section:nth-child(n) { animation-delay: 0s; }
.day-view.from-next > .section:nth-child(n+2), .day-view.from-prev > .section:nth-child(n+2) { animation-delay: .04s; }
/* a neighbour, built out of sight: nothing to arrive from */
.day-view.quiet > .section, .day-view.quiet > .col > .section { animation: none; }
.dock-clear { height: calc(96px + var(--dock-b)); }

/* a region that folds open and shut — animates height without measuring it */
.fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .34s var(--ease); }
.fold.open { grid-template-rows: 1fr; }
.fold-inner { overflow: hidden; min-height: 0; }

/* ─── Collapsible card ─── */
.card.disclosure { padding: 0; overflow: hidden; }
.disc-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 18px; text-align: left; -webkit-tap-highlight-color: transparent; }
.disc-head:active { opacity: 0.7; }
.disc-title { font-family: var(--fdisp); font-size: 16.5px; font-weight: 650; letter-spacing: -0.02em; color: var(--t-hi); white-space: nowrap; }
.disc-summary { flex: 1; min-width: 0; text-align: right; font-size: 12.5px; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .2s; }
.disclosure.open:not(.keep) .disc-summary { opacity: 0; }
.disc-chev { display: grid; place-items: center; color: var(--t-lo); transition: transform .34s var(--ease); }
.disclosure.open .disc-chev { transform: rotate(180deg); }
.disc-always { padding: 0 18px 18px; }
.disc-body { padding: 16px 18px 18px; border-top: 1px solid var(--hairline); }
.disc-caption { font-size: 12px; color: var(--t-lo); margin-bottom: 12px; }

/* a card with a title that does not fold — same header metrics as .disc-head */
.card-head { display: flex; align-items: center; gap: 10px; padding: 18px; }
.card-head .disc-title { margin: 0; }

/* The day's activities share one card, a row each — the same grid as a meal
   row, so the two cards' times and right-hand numbers line up. */
.disc-always.flush { padding: 0; }
.act-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 13px; padding: 15px 18px; border-top: 1px solid var(--hairline); }
.act-time { width: 40px; font-family: var(--fmono); white-space: nowrap; }
.act-time .ts { font-size: 11px; color: var(--t-md); letter-spacing: 0.02em; font-weight: 500; }
.act-time .dur { font-size: 10.5px; color: var(--t-lo); margin-top: 5px; }
.act-body { min-width: 0; }
.act-name-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.act-name { font-size: 14.5px; color: var(--t-hi); font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.act-fuel { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 8px; margin-top: 7px; font-size: 11px; color: var(--t-md); white-space: nowrap; }
.act-fuel.quiet { color: var(--t-lo); }
.act-stats { display: flex; gap: 14px; }
.act-stat { text-align: right; min-width: 32px; }
.act-stat .n { font-family: var(--fdisp); font-size: 20px; font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; line-height: 1; }
.act-stat .u { font-size: 10px; color: var(--t-lo); letter-spacing: 0.06em; text-transform: uppercase; margin-top: 4px; font-family: var(--fmono); }
.act-stat.quiet .n { color: var(--t-lo); font-weight: 400; }

/* a row's extra line, the width of the row under its name and numbers; and
   what sits above and below the rows (the v2 athlete profile's sweat and
   sodium — none of this exists in v1 or the general profile) */
.act-extra { grid-column: 2 / -1; margin-top: -5px; }
.act-sweat { font-size: 11.5px; line-height: 1.5; color: var(--t-md); }
.band-btn { all: unset; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; min-height: 24px; display: inline-flex; align-items: center; }
.band-btn:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 4px; }
.v2-explain { margin-top: 18px; font-size: 12.5px; line-height: 1.5; color: var(--t-md); }
.v2-explain-h { font-weight: 600; color: var(--t-hi); margin-bottom: 4px; }
.v2-explain p { margin: 0 0 6px; }
.act-why { margin-top: 4px; font-size: 11px; line-height: 1.45; color: var(--t-lo); }
.act-sweat-src { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; font-size: 11px; color: var(--t-lo); }
.act-head { padding: 0 18px 14px; }
.cond-chip { position: relative; display: inline-flex; align-items: center; min-height: 34px; padding: 0 13px; border-radius: var(--r-pill); background: var(--surface-2); font-size: 12px; color: var(--t-md); white-space: pre; transition: transform .16s var(--ease); }
.cond-chip::after { content: ""; position: absolute; inset: -5px 0; }
.cond-chip:active { transform: scale(0.96); }
.cond-chip strong { color: var(--t-hi); font-weight: 600; }
.weigh-btn { position: relative; flex: none; min-height: 28px; padding: 0 11px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--t-hi); font-size: 11.5px; font-weight: 600; white-space: nowrap; transition: transform .16s var(--ease); }
.weigh-btn::after { content: ""; position: absolute; inset: -8px -4px; }
.weigh-btn:active { transform: scale(0.95); }
.weigh-btn.done { background: transparent; box-shadow: inset 0 0 0 1px var(--border-hi); color: var(--t-md); font-weight: 500; }
.act-foot { padding: 13px 18px 16px; border-top: 1px solid var(--hairline); }
.act-foot .v2-line:first-child { margin-top: 0; }
.act-foot .v2-line.src { font-size: 11.5px; color: var(--t-lo); }

/* on-bike carbs logged against a ride's prescription */
.ride-state { flex: none; font-size: 10.5px; font-weight: 600; padding: 3px 8px; border-radius: var(--r-pill); transition: background .3s, color .3s; }
.ride-state.under, .ride-state.none { background: var(--surface-2); color: var(--t-md); }
.ride-state.met   { background: var(--ok-dim); color: var(--ok); }
.ride-state.over  { background: oklch(from var(--ea-high) l c h / 0.16); color: var(--ea-high); }

/* ─── Calendar ─── */
.cal-popover { margin: 4px var(--page-x) 6px; background: var(--bg-elev); border: 1px solid var(--border-hi); border-radius: var(--r-lg); padding: 14px; box-shadow: var(--shadow-pop); transform-origin: top center; animation: pop-in .26s var(--ease); }
@keyframes pop-in { from { opacity: 0; transform: translateY(-6px) scale(0.98); } to { opacity: 1; transform: none; } }
.cal-month-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 12px; }
.cal-month-row .mname { font-family: var(--fdisp); font-size: 16px; font-weight: 650; letter-spacing: -0.02em; flex: 1; text-align: center; }
.cal-nav {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--t-md);
  transition: color .14s, background .14s;
}
@media (hover: hover) { .cal-nav:hover { color: var(--t-hi); background: var(--surface-hi); } }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-grid .wkd { font-size: 11px; color: var(--t-xlo); text-align: center; padding: 4px 0; }
.cal-cell { aspect-ratio: 1; display: grid; place-items: center; border-radius: 50%; transition: background .14s, color .14s; font-size: 13.5px; font-variant-numeric: tabular-nums; color: var(--t-md); position: relative; }
@media (hover: hover) { .cal-cell.in:hover { background: var(--surface-hi); color: var(--t-hi); } }
.cal-cell.out { color: var(--t-xlo); }
.cal-cell.today { box-shadow: inset 0 0 0 1px var(--border-hi); color: var(--t-hi); font-weight: 600; }
.cal-cell.active { background: var(--accent); color: var(--on-accent); font-weight: 700; }
.cal-cell .micro { position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); width: 3px; height: 3px; border-radius: 50%; background: var(--t-lo); }
.cal-cell.active .micro { background: var(--on-accent); }

/* the kind of day, in the hue app.js hands it; the text is set per theme so it
   reads on paper as well as on ink */
.day-tag { font-size: 11px; padding: 3px 9px; border-radius: var(--r-pill); font-weight: 600;
  background: oklch(0.74 0.13 var(--h, 220) / 0.16); color: oklch(0.82 0.13 var(--h, 220)); }
[data-theme="light"] .day-tag { color: oklch(0.44 0.12 var(--h, 220)); }

/* ─── Banners ─── */
.banner { display: flex; gap: 9px; align-items: flex-start; margin: 2px var(--page-x) 8px; padding: 12px 14px; border-radius: var(--r-md); font-size: 12.5px; line-height: 1.45; }
.banner.warn { background: var(--warn-dim); color: var(--warn); }
.banner.bad  { background: var(--bad-dim);  color: var(--bad); }
.banner svg { flex-shrink: 0; margin-top: 1px; }

/* ════════════════════════════════════════════════════════════════════
   HERO — everything about how the day is going, read in one look, straight
   on the page with no card around it. A thin dial for energy around the
   number left to eat; the three macros as small dials of the same shape
   under it, each in its own colour; then two tiles, energy availability
   and bodyweight.
   ════════════════════════════════════════════════════════════════════ */
.hero { padding: 4px 0 0; }
/* as wide as the phone allows, and never so tall that a short screen loses the
   macros under it */
.hero-gauge { position: relative; width: min(66vw, 252px, 36vh); min-width: 168px; aspect-ratio: 1; margin: 0 auto; }

/* The dial: an arc open at the foot, lit in one flat colour. No glow, no
   scale, no ornament — the number inside it is the thing being read. */
.gauge-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.gauge-svg .g-track { fill: none; stroke: var(--track); stroke-linecap: round; }
.gauge-svg .g-prog { fill: none; stroke-linecap: round; transition: stroke-dashoffset 1.1s cubic-bezier(.22,.8,.2,1), stroke .4s, opacity .25s; }
.gauge-svg .empty { opacity: 0; }

.gauge-center { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; pointer-events: none; }
.gc-val { font-family: var(--fdisp); font-size: clamp(44px, 14.4vw, 60px); font-weight: 650; letter-spacing: -0.045em; line-height: 0.95; font-variant-numeric: tabular-nums; color: var(--t-hi); }
.gc-val.over { color: var(--warn); }
.gc-unit { font-size: 13.5px; font-weight: 500; color: var(--t-md); margin-top: 7px; }
/* in the mouth of the dial */
.gauge-foot { position: absolute; left: 0; right: 0; bottom: 6%; text-align: center; font-size: 12px; color: var(--t-lo); white-space: nowrap; pointer-events: none; }
.gauge-foot strong { color: var(--t-md); font-weight: 500; }

.hero-note { display: flex; justify-content: center; margin-top: -4px; min-height: 18px; font-size: 12px; color: var(--t-lo); }
.hero-note .planned-note { display: inline-flex; align-items: center; gap: 6px; color: var(--warn); }
.hero-note .planned-note i { width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid currentColor; box-sizing: border-box; }

.macro-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 12px; }
.macro { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 100%; padding: 8px 2px 10px; border-radius: 20px; text-align: center; transition: background .2s, transform .16s var(--ease); }
button.macro:active { transform: scale(0.96); }
button.macro.open { background: var(--surface); }
.macro-g { position: relative; width: 66px; height: 66px; margin-bottom: 4px; }
.macro-v { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--fdisp); font-size: 18px; font-weight: 650; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--t-hi); }
.macro-l { font-size: 13px; font-weight: 600; color: var(--t-hi); }
.macro-s { font-size: 11.5px; color: var(--t-lo); white-space: nowrap; }

/* The dials again, at the header's foot while the hero is scrolled away
   (rings.js GapStrip). It hangs over the top of the page rather than
   lengthening the header, so the page does not jump when it comes and goes.
   The dials settle into place from a little larger and a little lower, as if
   come up from the page — all four together, on one long decelerating curve,
   and the fade on the same clock so nothing arrives ahead of anything else.
   Going, it is quicker and does not travel. */
.gap-strip {
  --gap-in: cubic-bezier(.16, 1, .3, 1);
  position: absolute; top: 100%; left: 0; right: 0;
  display: flex; justify-content: center; gap: clamp(22px, 9vw, 44px);
  padding: 2px var(--page-x) 8px; background: var(--bg);
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease-out, visibility 0s .2s;
}
.gap-strip.on { opacity: 1; visibility: visible; transition: opacity .45s var(--gap-in); }
/* the page slips under it as it does under the header */
.gap-strip::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 16px; pointer-events: none;
  background: linear-gradient(to bottom, var(--bg), transparent); }
.gap-g { width: 34px; height: 34px; will-change: transform;
  transform: translateY(10px) scale(1.3); transition: transform .2s ease-out; }
.gap-strip.on .gap-g { transform: none; transition: transform .6s var(--gap-in); }
.gap-strip.on:active .gap-g { transform: scale(0.92); transition-duration: .16s; }

.ea-note { padding: 14px 4px 2px; font-size: 12.5px; line-height: 1.5; color: var(--t-md); }
.ea-note p { margin: 0 0 6px; }
.ea-note p:last-child { margin-bottom: 0; }
.ea-note-h { font-size: 12.5px; font-weight: 600; color: var(--t-hi); margin-bottom: 6px; }

/* ─── Tiles: energy availability and bodyweight ─── */
.tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 14px; }
.tiles.one { grid-template-columns: minmax(0, 1fr); }
.tile.skeleton { border-color: transparent; }
.tile {
  display: flex; flex-direction: column; gap: 9px; min-width: 0; min-height: 124px;
  padding: 15px 15px 14px; border-radius: 22px; text-align: left;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-card);
  transition: transform .16s var(--ease), border-color .2s;
}
button.tile:active { transform: scale(0.975); }
button.tile.open { border-color: var(--border-hi); }
.tile-h { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-height: 20px; font-size: 12.5px; font-weight: 500; color: var(--t-lo); }
.tile-v { font-family: var(--fdisp); font-size: 28px; font-weight: 700; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--t-hi); white-space: nowrap; }
.tile-v .u { font-family: var(--fui); font-size: 12.5px; font-weight: 500; letter-spacing: 0; color: var(--t-lo); margin-left: 4px; }
.tile-v.none { color: var(--t-xlo); }
.tile-s { font-size: 11.5px; line-height: 1.35; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-foot { margin-top: auto; }
.tile-chip { flex: none; padding: 3px 8px; border-radius: var(--r-pill); font-size: 11px; font-weight: 600; line-height: 1.2; background: var(--surface-2); color: var(--t-md); white-space: nowrap; }
.tile-chip.warn { background: var(--warn-dim); color: var(--warn); }
.tile-chip.go { background: var(--accent); color: var(--on-accent); }

/* availability: where the number falls on the four zones */
.ea-scale { position: relative; display: flex; gap: 3px; height: 6px; }
.ea-scale i { height: 100%; border-radius: 3px; opacity: 0.28; transition: opacity .3s; }
.ea-scale i.on { opacity: 1; }
.ea-scale b { position: absolute; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: var(--t-hi); box-shadow: 0 0 0 3px var(--surface); transition: left .8s var(--ease); }

/* bodyweight: the last few weeks as a line */
.spark { display: block; width: 100%; height: 30px; overflow: visible; }
.spark .sp-line { fill: none; stroke: var(--accent-ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.spark .sp-area { fill: var(--accent-ink); opacity: 0.10; stroke: none; }
.spark-dot { position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: var(--accent-ink); box-shadow: 0 0 0 3px var(--surface); }
.spark-wrap { position: relative; }

.onbike-stats { display: grid; grid-template-columns: repeat(3, 1fr); }
.onbike-stats .ob-cell { padding: 0 10px; position: relative; }
.onbike-stats .ob-cell:first-child { padding-left: 0; }
.onbike-stats .ob-cell + .ob-cell::before { content: ""; position: absolute; left: 0; top: 2px; bottom: 2px; width: 1px; background: var(--hairline); }
.onbike-stats .ob-cell .l { font-size: 11.5px; color: var(--t-lo); white-space: nowrap; }
.onbike-stats .ob-cell .v { font-family: var(--fdisp); font-size: 18px; font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; margin-top: 5px; }

/* Cold start / no reading for the selected day — stands in for the dial. */
.weight-prompt { display: flex; flex-direction: column; gap: 10px; padding: 20px 18px 18px; border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--border); }
.weight-prompt .wp-title { font-family: var(--fdisp); font-size: 20px; font-weight: 700; letter-spacing: -0.03em; color: var(--t-hi); }
.est-retake { margin-top: 10px; padding: 12px 14px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-2); font-size: 12.5px; line-height: 1.5; color: var(--t-md); }
.est-retake-actions { display: flex; gap: 8px; margin-top: 10px; }
.est-retake-actions .photo-btn { flex: 1; }
.weight-prompt.compact { gap: 8px; padding: 16px 16px 14px; margin-top: 12px; }
.weight-prompt.compact .wp-title { font-size: 16px; }
.weight-prompt.compact .w-save { margin-top: 4px; height: 46px; }
.weight-prompt .wp-body { font-size: 13px; line-height: 1.5; color: var(--t-md); }

/* ─── Weighing in (app/weight.js) ───
   The pad is the number itself with a step either side of it: a weigh-in is
   nearly always the last one nudged by a few hundred grams. */
.w-pad { display: grid; grid-template-columns: 56px minmax(0, 1fr) 56px; align-items: center; gap: 8px; padding: 8px; border-radius: 26px; background: var(--surface-2); }
.w-step { width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--surface-hi); color: var(--t-hi); transition: transform .14s var(--ease), background .16s; touch-action: none; }
.w-step:active { transform: scale(0.9); background: var(--border-hi); }
.w-step svg { width: 20px; height: 20px; }
.w-num { display: flex; align-items: baseline; justify-content: center; gap: 6px; min-width: 0; }
.w-num input { width: 4.2ch; min-width: 0; padding: 0; border: 0; background: none; outline: none; text-align: right;
  font-family: var(--fdisp); font-size: 46px; font-weight: 700; letter-spacing: -0.04em; line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--t-hi);
  -moz-appearance: textfield; appearance: textfield; }
.w-num input::-webkit-outer-spin-button, .w-num input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.w-num input::placeholder { color: var(--t-xlo); }
.w-num span { font-size: 15px; font-weight: 500; color: var(--t-lo); }
.w-days { display: flex; gap: 6px; margin-top: 12px; overflow-x: auto; scrollbar-width: none; }
.w-days::-webkit-scrollbar { display: none; }
.w-day { position: relative; flex: none; display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--t-md); font-size: 13px; font-weight: 600; white-space: nowrap; transition: background .2s, color .2s; }
.w-day.on { background: var(--accent); color: var(--on-accent); }
.w-day input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; }
.w-check { margin-top: 12px; padding: 12px 14px; border-radius: var(--r-md); background: var(--warn-dim); color: var(--warn); font-size: 12.5px; line-height: 1.45; }
.w-save { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 52px; margin-top: 12px; border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent); font-size: 15px; font-weight: 600; transition: transform .2s var(--ease), opacity .2s; }
.w-save:active:not(:disabled) { transform: scale(0.97); }
.w-save:disabled { opacity: 0.35; cursor: default; }
.w-hint { margin-top: 9px; font-size: 11.5px; line-height: 1.45; color: var(--t-lo); text-align: center; }

.w-sec { margin-top: 22px; }
.w-sec-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.w-sec-h h3 { margin: 0; font-family: var(--fdisp); font-size: 16.5px; font-weight: 650; letter-spacing: -0.02em; }
.w-sec-h .v2-seg { padding: 3px; border-radius: var(--r-pill); }
.w-sec-h .v2-seg { flex: none; }
.w-sec-h .v2-seg button { flex: none; min-width: 46px; min-height: 32px; padding: 0 11px; border-radius: var(--r-pill); font-size: 12px; overflow: visible; }
.w-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.w-stat { padding: 12px 12px 11px; border-radius: var(--r-md); background: var(--surface-2); min-width: 0; }
.w-stat .l { font-size: 11.5px; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w-stat .v { margin-top: 5px; font-family: var(--fdisp); font-size: 19px; font-weight: 650; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.w-stat .v small { font-family: var(--fui); font-size: 11px; font-weight: 500; letter-spacing: 0; color: var(--t-lo); margin-left: 2px; }
.w-line { margin-top: 10px; font-size: 12.5px; line-height: 1.5; color: var(--t-md); }
.w-line strong { color: var(--t-hi); font-weight: 600; }

.w-chart { position: relative; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.w-chart svg { display: block; width: 100%; height: 168px; overflow: visible; }
.w-chart .grid { stroke: var(--hairline); stroke-width: 1; vector-effect: non-scaling-stroke; }
.w-chart .goal { stroke: var(--c-fat); stroke-width: 1.5; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.w-chart .trend { fill: none; stroke: var(--accent-ink); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.w-chart .area { fill: var(--accent-ink); opacity: 0.08; }
.w-chart .cursor { stroke: var(--border-hi); stroke-width: 1; vector-effect: non-scaling-stroke; }
.w-pt { position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; background: var(--t-lo); opacity: 0.7; }
.w-pt.on { width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; background: var(--accent-ink); opacity: 1; box-shadow: 0 0 0 3px var(--bg-elev); }
.w-ylab { position: absolute; right: 0; transform: translateY(-50%); padding-left: 4px; font-family: var(--fmono); font-size: 10.5px; color: var(--t-lo); background: var(--bg-elev); }
.w-ylab.goal { color: var(--c-fat); }
.w-xlab { display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--t-lo); }
.w-read { min-height: 18px; margin-bottom: 6px; font-size: 12.5px; color: var(--t-md); }
.w-read strong { color: var(--t-hi); font-weight: 600; }
.w-key { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: 11.5px; color: var(--t-lo); }
.w-key span { display: inline-flex; align-items: center; gap: 6px; }
.w-key i { width: 14px; height: 0; border-top: 2.5px solid var(--accent-ink); border-radius: 2px; }
.w-key i.dot { width: 7px; height: 7px; border: 0; border-radius: 50%; background: var(--t-lo); }
.w-key i.goal { border-top: 1.5px dashed var(--c-fat); }

/* how well the log is being kept: the two counts the engine actually needs */
.w-keep { display: flex; flex-direction: column; gap: 12px; }
.w-keep-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; align-items: baseline; }
.w-keep-row .nm { font-size: 13px; color: var(--t-hi); }
.w-keep-row .ct { font-family: var(--fmono); font-size: 12px; color: var(--t-md); }
.w-keep-row .pips { grid-column: 1 / -1; display: flex; gap: 3px; }
.w-keep-row .pips i { flex: 1; height: 6px; border-radius: 3px; background: var(--track); }
.w-keep-row .pips i.on { background: var(--accent-ink); }
.w-keep-row .why { grid-column: 1 / -1; font-size: 11.5px; line-height: 1.45; color: var(--t-lo); }

.w-hist { display: flex; flex-direction: column; border-radius: var(--r-md); background: var(--surface-2); overflow: hidden; }
.w-hist-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; min-height: 48px; padding: 6px 14px; text-align: left; transition: background .16s; }
.w-hist-row + .w-hist-row { border-top: 1px solid var(--hairline); }
.w-hist-row:active { background: var(--surface-hi); }
.w-hist-row.on { background: var(--accent-dim); }
.w-hist-row .d { font-size: 13.5px; color: var(--t-hi); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w-hist-row .dl { font-family: var(--fmono); font-size: 11.5px; color: var(--t-lo); }
.w-hist-row .k { font-family: var(--fdisp); font-size: 16px; font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; min-width: 62px; text-align: right; }
.w-hist-row .k small { font-family: var(--fui); font-size: 11px; font-weight: 500; color: var(--t-lo); margin-left: 3px; }
.w-more { align-self: center; min-height: 44px; padding: 0 14px; font-size: 13px; font-weight: 600; color: var(--t-md); }

/* ─── Meal timeline ─── */
/* The day's meals share one card. Each meal is a row in it, divided by a
   hairline — not a card inside a card. */
.card.meals-card { padding: 0; overflow: hidden; }
.meal-list { display: flex; flex-direction: column; }
.meal-in { animation: rise .45s var(--ease) backwards; }
.meal-card { position: relative; cursor: pointer; border-top: 1px solid var(--hairline); -webkit-tap-highlight-color: transparent; }
.meal-card:not(.expanded) .meal-row:active { opacity: 0.7; }
.meal-card .meal-row { padding: 15px 18px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 13px; }
.meal-card .timepin { width: 40px; display: flex; flex-direction: column; justify-content: center; }
.meal-card .timepin .ts { font-size: 11px; color: var(--t-md); font-family: var(--fmono); letter-spacing: 0.02em; font-weight: 500; }
.meal-card .body { min-width: 0; }
.meal-card .body .kind { font-size: 14.5px; color: var(--t-hi); font-weight: 600; letter-spacing: -0.01em; }
.meal-card .body .macros { font-size: 11px; color: var(--t-md); font-family: var(--fmono); margin-top: 7px; display: flex; gap: 11px; }
.meal-card .body .macros span { display: inline-flex; align-items: center; gap: 5px; }
.meal-card .body .macros .swatch { width: 7px; height: 7px; border-radius: 50%; }
.meal-card .kcal-block { display: flex; align-items: center; gap: 7px; }
.meal-card .kcal { text-align: right; }
.meal-card .kcal .n { font-family: var(--fdisp); font-size: 20px; font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; line-height: 1; }
.meal-card .kcal .u { font-size: 10px; color: var(--t-lo); letter-spacing: 0.06em; text-transform: uppercase; margin-top: 4px; font-family: var(--fmono); }
.meal-card .meal-chev { width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--r-sm); color: var(--t-lo); transition: transform .3s var(--ease), color .15s; }
/* one-tap "eaten" on a planned row. Pulled into the row's own padding so the
   target is 44px without the row growing. */
.meal-card .meal-quick { width: 44px; height: 44px; margin: -8px -10px -8px -4px; display: grid; place-items: center; flex: none; }
.meal-card .meal-quick::before { content: ""; grid-area: 1 / 1; width: 30px; height: 30px; border-radius: 50%; background: var(--ok-dim); transition: transform .2s var(--spring), background .2s; }
.meal-card .meal-quick svg { grid-area: 1 / 1; position: relative; color: var(--ok); }
.meal-card .meal-quick:active::before { transform: scale(0.84); background: oklch(from var(--ok) l c h / 0.3); }
/* direct child only: an open group must not turn its items' chevrons too */
.meal-card.expanded > .meal-row .meal-chev { transform: rotate(180deg); color: var(--t-hi); }
/* A slot logged more than once: one row of totals, its items nested under it
   on a recessed band so they read as parts of the row above. */
/* how many items, as a badge on the slot name; on a narrow phone a long slot
   with a "1 planned" chip wraps the chip under the name rather than into the kcal */
.meal-group > .meal-row .kind-row { flex-wrap: wrap; row-gap: 5px; }
.meal-group .group-count { display: inline-grid; place-items: center; min-width: 18px; height: 17px; padding: 0 5px; margin-left: -2px; border-radius: 9px; background: var(--surface-hi); color: var(--t-md); font-family: var(--fmono); font-size: 10.5px; font-weight: 600; line-height: 1; box-sizing: border-box; }
.meal-group-list { background: var(--surface-2); border-top: 1px solid var(--hairline); animation: slidedown .28s var(--ease); }
.meal-group-list > .meal-card:first-child { border-top: 0; }
.meal-card.in-group .meal-row { padding-left: 26px; }
.meal-card.in-group .kind { font-size: 13.5px; font-weight: 500; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meal-card.in-group .kcal .n { font-size: 17px; }
.meal-card.in-group .meal-detail { padding-left: 26px; }
.meal-card .meal-detail .slot-pills { margin-bottom: 2px; }
.meal-card .meal-detail { padding: 4px 18px 18px; border-top: 1px solid var(--hairline); cursor: default; animation: slidedown .28s var(--ease); }
@keyframes slidedown { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.meal-card .detail-label { font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--t-lo); font-weight: 600; padding: 12px 0 7px; }
.meal-card .food-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.meal-card .food-list li { display: flex; gap: 9px; align-items: flex-start; font-size: 13px; color: var(--t-hi); line-height: 1.45; padding: 4px 0; }
.meal-card .food-list .bullet { color: var(--accent-ink); flex-shrink: 0; font-family: var(--fmono); font-weight: 700; line-height: 1.45; }
.meal-empty { background: transparent; border: 1px dashed var(--border-hi); border-radius: var(--r-lg); padding: 26px 22px; text-align: center; color: var(--t-lo); font-size: 13px; line-height: 1.5; }
.meals-card .meal-empty { border: 0; border-top: 1px solid var(--hairline); border-radius: 0; }

/* meal state chips */
.state-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; font-family: var(--fmono); padding: 2px 6px; border-radius: var(--r-sm); line-height: 1; flex-shrink: 0; }
.state-chip.planned { background: var(--warn-dim); color: var(--warn); }
.state-chip.planned i { width: 5px; height: 5px; border-radius: 50%; border: 1.5px solid currentColor; box-sizing: border-box; }
.state-chip.eaten { background: var(--ok-dim); color: var(--ok); }
.state-chip.eaten i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.meal-card.planned .kcal .n { color: var(--warn); }
.meal-card .kind-row { display: flex; align-items: center; gap: 8px; }

/* detail action bar */
.meal-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 13px; padding-top: 13px; border-top: 1px solid var(--hairline); }
.meal-act { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 9px 14px; border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--border); color: var(--t-md); font-size: 12.5px; font-weight: 600; transition: color .14s, border-color .14s, background .14s; }
@media (hover: hover) { .meal-act:hover { background: var(--surface-hi); color: var(--t-hi); } }
@media (hover: hover) { .meal-act.edit:hover { color: var(--accent-ink); border-color: var(--border-hi); } }
.meal-act.danger { margin-left: auto; }
@media (hover: hover) { .meal-act.danger:hover { color: var(--bad); border-color: var(--bad-dim); background: var(--bad-dim); } }
.meal-act.confirm-eaten { background: var(--ok-dim); color: var(--ok); border-color: oklch(from var(--ok) l c h / 0.3); margin-right: auto; }
@media (hover: hover) { .meal-act.confirm-eaten:hover { background: oklch(from var(--ok) l c h / 0.24); } }

/* edit chrome */
.meal-edit { animation: slidedown .18s ease-out; }
.edit-section-label { font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--t-lo); font-weight: 600; padding: 13px 0 8px; display: flex; align-items: baseline; justify-content: space-between; }
.edit-section-label .hint { font-size: 10.5px; text-transform: none; letter-spacing: 0.01em; color: var(--t-xlo); font-weight: 500; font-family: var(--fmono); }
.meal-detail .slot-pills { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; padding: 4px; background: var(--surface-2); border-radius: var(--r-md); }
.meal-detail .slot-pill { min-height: 40px; padding: 0 2px; border-radius: var(--r-sm); background: transparent; color: var(--t-lo); font-size: 12px; font-weight: 600; transition: background .14s, color .14s; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meal-detail .slot-pill.active { background: var(--surface-hi); color: var(--t-hi); }
.edit-meta { display: flex; gap: 8px; align-items: stretch; margin-top: 8px; }
.edit-meta .time-field { flex: none; width: 104px; min-height: 48px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: 0 10px; font-size: 16px; color: var(--t-hi); font-family: var(--fmono); outline: none; text-align: center; transition: border-color .14s; }
.edit-meta .time-field:focus { border-color: var(--accent-ink); }
.edit-meta .compose-state { flex: 1; margin: 0; }
.edit-rows { display: flex; flex-direction: column; gap: 7px; }
.edit-food-row { display: grid; grid-template-columns: 1fr 84px 44px; gap: 7px; align-items: center; }
/* 16px: anything smaller and iOS zooms the page when the field takes focus */
.edit-food-row .ef { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 0 11px; height: 44px; font-size: 16px; color: var(--t-hi); outline: none; min-width: 0; transition: border-color .14s; }
.edit-food-row .ef:focus { border-color: var(--accent-ink); }
.edit-food-row .ef.qty { font-family: var(--fmono); text-align: center; }
.edit-food-row .rm { width: 44px; height: 44px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--surface-2); border: 1px solid var(--border); color: var(--t-lo); transition: color .14s, background .14s, border-color .14s; }
@media (hover: hover) { .edit-food-row .rm:hover { color: var(--bad); border-color: var(--bad-dim); background: var(--bad-dim); } }
.add-food-btn { display: inline-flex; align-items: center; gap: 6px; margin-top: 9px; min-height: 44px; padding: 9px 14px; border-radius: var(--r-sm); align-self: flex-start; background: transparent; border: 1px dashed var(--border-hi); color: var(--t-md); font-size: 11px; font-weight: 600; font-family: var(--fmono); letter-spacing: 0.03em; transition: color .14s, border-color .14s; }
@media (hover: hover) { .add-food-btn:hover { color: var(--accent-ink); border-color: var(--accent-ink); } }
.edit-footer { display: flex; gap: 8px; margin-top: 15px; align-items: center; }
.edit-footer .save { flex: 1; background: var(--accent); color: var(--on-accent); min-height: 48px; padding: 11px; border-radius: var(--r-md); font-size: 12px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; display: inline-flex; align-items: center; justify-content: center; gap: 7px; box-shadow: 0 1px 0 var(--sheen-top) inset; }
.edit-footer .save:disabled { opacity: 0.4; cursor: default; }
.edit-footer .save.dirty { box-shadow: 0 0 0 3px var(--accent-dim), 0 1px 0 var(--sheen-top) inset; }
.edit-footer .cancel { background: var(--surface-hi); color: var(--t-md); min-height: 48px; padding: 11px 16px; border-radius: var(--r-md); font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; font-family: var(--fmono); }
.edit-reest-note { font-size: 11.5px; color: var(--t-lo); font-family: var(--fmono); line-height: 1.45; margin-top: 11px; display: flex; gap: 7px; align-items: flex-start; }
.edit-reest-note svg { flex-shrink: 0; margin-top: 1px; color: var(--accent-ink); }

/* ─── Micros ─── */
.micros-grid { display: flex; flex-direction: column; gap: 8px; padding: 4px 2px; }
.micro-row { display: grid; grid-template-columns: 78px 1fr 38px; gap: 11px; align-items: center; }
.micro-row .nm { font-size: 11px; color: var(--t-md); }
.micro-row .bar { position: relative; height: 5px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; }
.micro-row .bar .fill { position: absolute; top: 0; left: 0; bottom: 0; border-radius: var(--r-pill); transition: width .3s; }
.micro-row .bar .fill.ok { background: var(--ok); }
.micro-row .bar .fill.warn { background: var(--warn); }
.micro-row .bar .fill.bad { background: var(--bad); }
.micro-row .bar .fill.none { background: var(--t-xlo); }
.micro-row .pct { font-size: 11px; font-family: var(--fmono); color: var(--t-md); text-align: right; }

/* ─── Log dock ─── */
/* Along the bottom edge, where the thumb is. The middle is the way in for a
   meal you describe; the two sides skip straight to the camera and to the
   saved list. The page fades out under it rather than being cut off by it. */
.screen::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 20;
  height: calc(84px + var(--dock-b)); pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--bg) 78%);
}
.dock {
  position: absolute; left: var(--page-x); right: var(--page-x); bottom: var(--dock-b); z-index: 30;
  display: grid; grid-template-columns: 64px minmax(0, 1fr) 64px; gap: 6px; align-items: center;
  padding: 6px; border-radius: 34px;
  background: var(--dock-bg); border: 1px solid var(--dock-border);
  -webkit-backdrop-filter: blur(18px) saturate(1.5); backdrop-filter: blur(18px) saturate(1.5);
  box-shadow: var(--shadow-fab);
  transition: transform .32s var(--spring), opacity .2s;
  animation: dock-in .55s var(--spring) .3s backwards;
}
.dock.hidden { transform: translateY(28px) scale(0.96); opacity: 0; pointer-events: none; }
@keyframes dock-in { from { opacity: 0; transform: translateY(30px) scale(0.94); } to { opacity: 1; transform: none; } }
.dock-main {
  height: 52px; min-width: 0; border-radius: 26px; padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--accent); color: var(--on-accent);
  font-size: 15px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap;
  transition: transform .2s var(--spring);
}
.dock-main span { overflow: hidden; text-overflow: ellipsis; }
.dock-main svg { flex: none; }
.dock-main:active { transform: scale(0.96); }
.dock-side {
  height: 52px; border-radius: 26px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  color: var(--dock-fg); font-size: 10.5px; font-weight: 600; line-height: 1;
  transition: transform .2s var(--spring), background .16s, color .16s;
}
.dock-side svg { width: 19px; height: 19px; }
/* The narrowest phones (320pt). The dock gives the middle button the room its
   longer off-day label needs, and the hero pulls its numbers in a size. */
@media (max-width: 359px) {
  :root { --page-x: 12px; }
  .dock { grid-template-columns: 56px minmax(0, 1fr) 56px; }
  .dock-main { font-size: 14px; padding: 0 10px; }
  .dock-main.wide svg { display: none; }
  .macro-g { width: 58px; height: 58px; }
  .macro-v { font-size: 16px; }
  .macro-s { font-size: 11px; }
  .tile { padding: 13px 12px 12px; }
  .tile-v { font-size: 25px; }
  .w-pad { grid-template-columns: 50px minmax(0, 1fr) 50px; }
  .w-step { width: 50px; height: 50px; }
  .w-num input { font-size: 40px; }
}
@media (hover: hover) { .dock-side:hover { color: var(--dock-fg-hi); } }
.dock-side:active { transform: scale(0.92); background: var(--dock-press); color: var(--dock-fg-hi); }

/* ─── Sheets ─── */
.sheet-scrim {
  position: fixed; inset: 0; z-index: 40; background: var(--scrim);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; visibility: hidden; transition: opacity .3s, visibility 0s .3s;
}
.sheet-scrim.open { opacity: 1; visibility: visible; transition: opacity .3s; }

/* The extra box-shadow below the sheet is the same colour as the sheet: when
   the spring overshoots, it shows more sheet rather than a gap at the bottom. */
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 41;
  max-height: 90%; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  background: var(--bg-elev); border-top: 1px solid var(--border-hi);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: 0 18px calc(18px + env(safe-area-inset-bottom));
  box-shadow: 0 60px 0 0 var(--bg-elev), 0 -18px 50px -20px oklch(0.05 0.02 262 / 0.6);
  transform: translateY(calc(100% + 24px)); visibility: hidden;
  transition: transform .3s cubic-bezier(.4,0,.8,.6), visibility 0s .3s;
}
.sheet.open { transform: none; visibility: visible; transition: transform .5s cubic-bezier(.22,1.18,.36,1); }
.sheet.dragging { transition: none; }
.sheet-grab { touch-action: none; cursor: grab; padding-top: 9px; margin: 0 -18px; padding-left: 18px; padding-right: 18px; position: sticky; top: 0; z-index: 2; background: var(--bg-elev); border-radius: var(--r-xl) var(--r-xl) 0 0; }
.sheet-handle { width: 38px; height: 4px; border-radius: 2px; background: var(--border-hi); margin: 0 auto 8px; }
.sheet-head { display: flex; align-items: center; gap: 10px; min-height: 44px; padding-bottom: 12px; }
/* The title is a few fixed words and is never cut short: it takes its own
   width and the gap after it takes the slack. It used to be an ellipsis box
   (flex: 1, overflow: hidden), and on iOS that box cut the start of the title
   off — "Log a meal" read "g a meal". */
.sheet-head h2 { margin: 0 auto 0 0; flex: none; font-family: var(--fdisp); font-size: 21px; font-weight: 700; letter-spacing: -0.035em; white-space: nowrap; }
.sheet-head .icon-btn { background: var(--surface-2); width: 36px; height: 36px; position: relative; }
.sheet-head .icon-btn::after { content: ""; position: absolute; inset: -4px; }

.log-sheet .log-date-note { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; padding: 10px 12px; border-radius: var(--r-md); background: var(--warn-dim); color: var(--warn); font-size: 12.5px; }
.log-sheet .log-date-note svg { flex-shrink: 0; }
.log-sheet .meal-selector { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; padding: 4px; background: var(--surface-2); border-radius: var(--r-md); margin-bottom: 12px; }
.log-sheet .meal-pill { min-height: 42px; padding: 10px 2px; border-radius: var(--r-sm); background: transparent; color: var(--t-lo); transition: background .2s, color .2s, transform .2s var(--ease); min-width: 0; }
.log-sheet .meal-pill:active { transform: scale(0.94); }
.log-sheet .meal-pill.active { background: var(--surface-hi); color: var(--t-hi); }
.log-sheet .meal-pill-label { font-size: 12px; font-weight: 600; white-space: nowrap; }
/* font-size: 16px prevents iOS Safari from auto-zooming on focus */
.log-sheet .field { width: 100%; box-sizing: border-box; background: var(--surface-2); border: 1px solid transparent; border-radius: var(--r-md); padding: 14px; font-size: 16px; line-height: 1.4; color: var(--t-hi); outline: none; transition: border-color .15s, background .15s; font-family: inherit; resize: none; overflow-y: auto; max-height: 160px; min-height: 52px; }
.log-sheet .field::placeholder { color: var(--t-lo); }
.log-sheet .field:focus { border-color: var(--accent-ink); }
.log-sheet .row2 { display: flex; gap: 8px; margin-top: 10px; }
.log-sheet .photo-btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 44px; border-radius: var(--r-md); background: var(--surface-2); border: 1px solid transparent; color: var(--t-md); font-size: 13px; font-weight: 600; white-space: nowrap; transition: color .15s, background .15s, border-color .15s, transform .2s var(--ease); }
.log-sheet .photo-btn:active { transform: scale(0.95); }
.log-sheet .photo-btn.has-photo { color: var(--accent-ink); border-color: var(--accent-ink); background: var(--accent-dim); }
.log-sheet .submit-btn { background: var(--accent); color: var(--on-accent); padding: 10px 18px; border-radius: var(--r-md); font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 7px; transition: opacity .2s, transform .2s var(--ease); }
.log-sheet .submit-btn:active:not(:disabled) { transform: scale(0.97); }
.log-sheet .submit-btn:disabled { opacity: 0.35; cursor: default; }
.log-sheet .submit-btn.wide { width: 100%; height: 52px; border-radius: var(--r-pill); margin-top: 10px; font-size: 15px; transition: opacity .2s, transform .2s var(--ease), background .25s, color .25s; }
.log-sheet .submit-btn.quiet { background: var(--surface-2); color: var(--t-md); height: 44px; font-size: 13px; }
.log-sheet .photo-strip { display: flex; gap: 10px; align-items: center; padding: 8px; background: var(--surface-2); border-radius: var(--r-md); margin-bottom: 10px; animation: slidedown .28s var(--ease); }
.log-sheet .photo-thumb { position: relative; width: 56px; height: 56px; border-radius: var(--r-sm); overflow: hidden; background: var(--bg); flex-shrink: 0; }
.log-sheet .photo-thumb img { width: 100%; height: 100%; object-fit: cover; }
.log-sheet .photo-remove { position: absolute; top: 2px; right: 2px; width: 24px; height: 24px; border-radius: 50%; background: rgba(0,0,0,0.7); color: #fff; display: grid; place-items: center; }
.log-sheet .photo-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.log-sheet .photo-status { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--t-hi); }
.log-sheet .photo-status .status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); }
.log-sheet .photo-hint { font-size: 11.5px; color: var(--t-lo); }
.est-wait { height: 150px; margin-top: 12px; }

.compose-state { display: flex; gap: 3px; padding: 4px; background: var(--surface-2); border-radius: var(--r-md); margin-bottom: 8px; }
.compose-state button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 9px; border-radius: var(--r-sm); background: transparent; color: var(--t-lo); font-size: 12px; font-weight: 600; transition: background .2s, color .2s; }
.compose-state button.active { background: var(--surface-hi); }
.compose-state button.active.s-eaten { color: var(--ok); }
.compose-state button.active.s-planned { color: var(--warn); }
.sheet-head .compose-state { margin: 0; padding: 3px; border-radius: var(--r-pill); }
.sheet-head .compose-state button { flex: none; min-height: 34px; padding: 6px 13px; border-radius: var(--r-pill); }

/* estimate result box */
.est-box { background: var(--surface-2); border: 1px solid var(--border-hi); border-radius: var(--r-lg); padding: 14px; margin-top: 12px; animation: rise .4s var(--ease); }
.est-box.err { border-color: var(--bad); }
.est-foods { font-size: 13px; color: var(--t-md); margin-bottom: 12px; line-height: 1.45; }
.est-macros { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.est-macros .em { background: var(--surface); border-radius: var(--r-sm); padding: 10px 4px 9px; text-align: center; }
.est-macros .em-v { font-family: var(--fdisp); font-size: 19px; font-weight: 650; color: var(--t-hi); letter-spacing: -0.03em; }
.est-macros .em-v .unit { font-size: 10px; color: var(--t-lo); font-weight: 400; margin-left: 1px; }
.est-macros .em-l { font-size: 11px; color: var(--t-lo); margin-top: 3px; }
.est-note { font-size: 11.5px; color: var(--t-lo); margin-top: 10px; line-height: 1.45; }
.est-actions { display: flex; gap: 8px; margin-top: 13px; }
.est-actions .confirm { flex: 1; background: var(--accent); color: var(--on-accent); height: 50px; border-radius: var(--r-pill); font-size: 14px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 7px; transition: transform .2s var(--ease); }
.est-actions .confirm:active { transform: scale(0.97); }
.est-actions .discard { background: var(--surface-hi); color: var(--t-md); padding: 0 20px; border-radius: var(--r-pill); font-size: 13px; font-weight: 600; }
.est-impact { margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--hairline); }
.est-impact .ei-head { font-size: 11.5px; color: var(--t-lo); margin-bottom: 10px; }
.ei-row { display: grid; grid-template-columns: 34px 1fr auto; gap: 9px; align-items: center; margin-bottom: 8px; }
.ei-row .ei-name { font-size: 11px; color: var(--t-md); }
.ei-row .ei-bar { position: relative; height: 5px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; }
.ei-row .ei-bar .now { position: absolute; top: 0; left: 0; bottom: 0; background: var(--ei-hue); opacity: 0.45; }
.ei-row .ei-bar .add { position: absolute; top: 0; bottom: 0; background: var(--ei-hue); transform-origin: left; animation: grow .6s var(--ease) .15s backwards; }
@keyframes grow { from { transform: scaleX(0); } }
.ei-row .ei-bar .over { position: absolute; top: 0; right: 0; bottom: 0; background: var(--bad); }
.ei-row .ei-bar .goalmark { position: absolute; top: -2px; bottom: -2px; right: 0; width: 1.5px; background: var(--t-md); opacity: 0.5; }
.ei-row .ei-vals { font-size: 11px; font-family: var(--fmono); color: var(--t-md); text-align: right; white-space: nowrap; }
.ei-row .ei-vals strong { color: var(--t-hi); font-weight: 600; }
.ei-chip { display: inline-block; margin-left: 6px; padding: 1px 5px; border-radius: 4px; font-size: 10.5px; font-weight: 600; }
.ei-chip.under { background: var(--surface-hi); color: var(--t-md); }
.ei-chip.ok { background: var(--ok-dim); color: var(--ok); }
.ei-chip.over { background: var(--bad-dim); color: var(--bad); }

.spinner { width: 12px; height: 12px; border: 1.5px solid currentColor; border-top-color: transparent; border-radius: 50%; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* toast */
/* sits above the log dock rather than over it */
.toast { position: absolute; left: 14px; right: 14px; bottom: calc(76px + var(--dock-b)); max-width: 444px; margin: 0 auto; background: var(--bg-elev); border: 1px solid var(--border-hi); border-radius: var(--r-lg); padding: 13px 15px; z-index: 50; display: flex; gap: 11px; align-items: center; box-shadow: var(--shadow-pop); animation: toast-in .45s var(--spring); }
@keyframes toast-in { from { opacity: 0; transform: translateY(16px) scale(0.96); } to { opacity: 1; transform: none; } }
.toast .check { width: 24px; height: 24px; border-radius: 50%; background: var(--ok-dim); color: var(--ok); display: grid; place-items: center; flex-shrink: 0; }
.toast .tbody { flex: 1; }
.toast .tt { font-size: 10.5px; color: var(--t-md); font-family: var(--fmono); letter-spacing: 0.06em; }
.toast .ts { font-size: 13px; color: var(--t-hi); margin-top: 2px; font-family: var(--fmono); }
.toast.undo { border-color: var(--border-hi); }
.toast.undo .check { background: var(--bad-dim); color: var(--bad); }
.toast .undo-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-hi); color: var(--t-hi); min-height: 44px; padding: 8px 16px; border-radius: var(--r-md); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; font-family: var(--fmono); flex-shrink: 0; }

.skeleton { background: linear-gradient(90deg, var(--surface) 0%, var(--surface-2) 50%, var(--surface) 100%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: var(--r-md); }
@keyframes shimmer { to { background-position: -200% 0; } }

/* ─── Login gate ─── */
.login-wrap { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: radial-gradient(120% 80% at 50% -10%, var(--bg-elev) 0%, var(--bg) 45%, var(--bg-2) 100%); padding: 24px; }
.login-card { width: 100%; max-width: 340px; background: var(--metal); border: 1px solid var(--border); border-radius: var(--r-xl); padding: 30px 24px; text-align: center; box-shadow: var(--shadow-pop); }
.login-card .brand-mark { margin: 0 auto 18px; width: 60px; height: 60px; }
.login-card h1 { font-family: var(--fdisp); font-size: 26px; font-weight: 700; margin: 0 0 5px; letter-spacing: -0.04em; }
.login-card .sub { font-size: 12px; color: var(--t-lo); margin-bottom: 22px; }
.login-card .field { width: 100%; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: 13px 15px; font-size: 14px; color: var(--t-hi); outline: none; transition: border-color .15s; margin-bottom: 10px; }
.login-card .field:focus { border-color: var(--accent-ink); }
.login-card .go { width: 100%; background: var(--accent); color: var(--on-accent); min-height: 50px; padding: 13px; border-radius: var(--r-pill); font-size: 15px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.login-card .go:disabled { opacity: 0.5; cursor: default; }
.login-card .err { font-size: 11px; color: var(--bad); margin-top: 12px; min-height: 14px; font-family: var(--fmono); }

/* ── saved meals (app/library.js) ───────────────────────────────────────────
   Deliberately a flat list. The previous version composed meals out of parts,
   which needed quantity steppers and a serving/gram toggle on every row for a
   use case that wanted neither. A row is one saved meal; + adds one. */

.lib-sheet { margin-top: 12px; border: 1px solid var(--border-hi); border-radius: var(--r-lg); background: var(--surface-2); overflow: hidden; animation: rise .35s var(--ease); }
.lib-head { display: flex; gap: 8px; align-items: center; padding: 10px; border-bottom: 1px solid var(--hairline); }
.lib-head .lib-search { flex: 1; min-height: 0; padding: 9px 12px; font-size: 16px; background: var(--surface); }
.lib-body { max-height: 46vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.lib-empty { font-size: 12.5px; color: var(--t-lo); padding: 16px 14px; text-align: center; line-height: 1.5; }
.lib-err { font-size: 11px; color: var(--bad); padding: 8px 12px; }

.lib-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-bottom: 1px solid var(--hairline); flex-wrap: wrap; }
.lib-row:last-child { border-bottom: 0; }
.lib-row.picked { background: var(--accent-dim); }
.lib-thumb-btn { padding: 0; border: 0; background: none; flex: none; line-height: 0; width: 34px; height: 34px; border-radius: var(--r-sm); overflow: hidden; }
.lib-thumb-btn img.lib-thumb { opacity: 0; transition: opacity .3s; }
.lib-thumb-btn img.lib-thumb.ready { opacity: 1; }
.lib-thumb { width: 34px; height: 34px; border-radius: var(--r-sm); object-fit: cover; background: var(--surface-hi); flex: none; }
.lib-thumb-blank { display: inline-flex; align-items: center; justify-content: center; color: var(--t-xlo); }
.lib-text { flex: 1; min-width: 0; }
.lib-name { font-size: 13px; color: var(--t-hi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-meta { font-size: 11px; font-family: var(--fmono); color: var(--t-lo); margin-top: 2px; }

/* loading: placeholder rows in the shape of the real ones, then the real ones
   settle in over them. .lib-bone is the shimmer, tuned for the sheet's own
   surface — .skeleton is drawn for the page behind it and vanishes here. */
.lib-bone { background: var(--surface-hi) linear-gradient(90deg, transparent 0%, color-mix(in oklch, var(--t-hi) 10%, transparent) 50%, transparent 100%) 0 0 / 200% 100%; animation: shimmer 1.4s linear infinite; }
.lib-bone-line { height: 11px; width: 38%; border-radius: var(--r-pill); }
.lib-bone-line.sm { height: 9px; margin-top: 7px; }
.lib-bone-add { width: 44px; height: 44px; border-radius: 50%; flex: none; }
.lib-skel { animation: rise .35s var(--ease) backwards; }
.lib-row-in { animation: rise .4s var(--ease) backwards; }

/* 44px targets: this gets used outdoors, with cold hands, on a phone. */
.lib-add { width: 44px; height: 44px; border-radius: 50%; background: var(--accent); color: var(--on-accent); border: 0; display: inline-flex; align-items: center; justify-content: center; flex: none; transition: transform .2s var(--spring); }
.lib-add:active { transform: scale(0.88); }
.lib-row { transition: background .2s; }
.lib-count { min-width: 44px; height: 40px; border-radius: var(--r-pill); background: var(--surface-hi); color: var(--t-hi); border: 0; font-family: var(--fmono); font-size: 12px; flex: none; }
.lib-archive { width: 40px; height: 44px; margin-right: -6px; border-radius: var(--r-sm); color: var(--t-xlo); background: none; border: 0; display: inline-flex; align-items: center; justify-content: center; flex: none; }
@media (hover: hover) { .lib-archive:hover { color: var(--bad); } }

/* the label photo, opened. Not a thumbnail — it is the only surviving record
   of a packet that went in the bin, so it opens big enough to read. */
.lib-photo-open { flex: 1 1 100%; padding: 8px 0 2px; }
.lib-photo-open img { width: 100%; max-height: 62vh; object-fit: contain; border-radius: var(--r-sm); background: var(--bg-2); }
.lib-photo-cap { font-size: 11px; color: var(--t-lo); margin-top: 6px; line-height: 1.45; }

.lib-picks { border-top: 1px solid var(--border-hi); background: var(--bg-elev); padding: 10px 12px; }
.lib-total { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-family: var(--fmono); font-size: 11px; color: var(--t-hi); flex-wrap: wrap; }
.lib-total .submit-btn { padding: 10px 16px; }

/* saving the estimate you just ran */
.est-save { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-top: 9px; min-height: 44px; padding: 10px; border-radius: var(--r-sm); background: none; border: 1px dashed var(--border-hi); color: var(--t-md); font-size: 12.5px; font-weight: 600; }
@media (hover: hover) { .est-save:hover { color: var(--accent-ink); border-color: var(--accent-ink); } }
.est-save-form { margin-top: 9px; }
.est-save-form .field { width: 100%; box-sizing: border-box; background: var(--surface); border: 1px solid var(--border-hi); border-radius: var(--r-sm); padding: 10px 12px; font-size: 16px; color: var(--t-hi); outline: none; }
.est-save-row { display: flex; gap: 8px; margin-top: 8px; }
.est-save-go { flex: 1; background: var(--accent); color: var(--on-accent); border: 0; padding: 11px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600; }
.est-save-go:disabled { opacity: 0.45; }
.est-save-cancel { background: var(--surface-hi); color: var(--t-md); border: 0; padding: 11px 16px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600; }
.est-saved { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 9px; padding: 10px; font-size: 12.5px; font-weight: 600; color: var(--ok); text-align: center; }

@media (max-width: 430px) {
  .lib-name { white-space: normal; }
}

/* Motion is decoration here, never information — every animated value is also
   on screen as a number — so with reduced motion it all simply lands at once. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; transition-duration: .01ms !important; transition-delay: 0s !important; }
  .spinner, .spin svg { animation-duration: .8s !important; }
}

/* ════════════════════════════════════════════════════════════════════
   v2 engine — the settings sheet and the cards in app/v2.js
   ════════════════════════════════════════════════════════════════════ */
.v2-tag { font-family: var(--fmono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--t-lo); border: 1px solid var(--border-hi); border-radius: var(--r-sm); padding: 2px 6px; }

/* a segmented choice: every option a full thumb target */
.v2-seg { display: flex; min-width: 0; background: var(--surface-2); border-radius: var(--r-md); padding: 4px; gap: 3px; }
.v2-seg button { flex: 1; min-width: 0; min-height: 40px; padding: 0 6px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background .2s, color .2s, transform .16s var(--ease); }
.v2-seg button:active { transform: scale(0.96); }
.v2-seg button.on { background: var(--surface-hi); color: var(--t-hi); box-shadow: 0 1px 2px oklch(0.05 0.02 262 / 0.18); }
/* five or six options: three to a row, so none is cut to an ellipsis */
.v2-seg.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }

.v2-settings { display: flex; flex-direction: column; gap: 10px; padding-bottom: 6px; }
.v2-set-h { font-family: var(--fdisp); font-size: 16.5px; font-weight: 650; letter-spacing: -0.02em; color: var(--t-hi); margin-top: 18px; }
.v2-set-h:first-child { margin-top: 0; }
.v2-field { display: flex; flex-direction: column; gap: 7px; }
.v2-field-l { font-size: 13px; font-weight: 500; color: var(--t-md); }
.v2-hint { font-size: 12px; line-height: 1.45; color: var(--t-lo); }
.v2-nums { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.v2-nums.three { grid-template-columns: repeat(3, 1fr); }
.v2-num { display: flex; flex-direction: column; gap: 5px; position: relative; min-width: 0; }
.v2-num span { font-size: 12px; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2-num input { width: 100%; min-width: 0; height: 46px; border-radius: var(--r-md); background: var(--surface-2); border: 1px solid var(--border); color: var(--t-hi); padding: 0 44px 0 12px; font-size: 16px; }
.v2-num input:focus { outline: none; border-color: var(--accent-ink); }
.v2-num em { position: absolute; right: 11px; bottom: 15px; font-style: normal; font-size: 11px; color: var(--t-lo); font-family: var(--fmono); pointer-events: none; }
/* iOS draws a date field at its own width and centres it; hold it to the column */
.v2-num input[type="date"] { -webkit-appearance: none; appearance: none; padding-right: 10px; font-family: inherit; text-align: left; }
.v2-num input[type="date"]::-webkit-date-and-time-value { text-align: left; }
.v2-text { width: 100%; height: 46px; border-radius: var(--r-md); background: var(--surface-2); border: 1px solid var(--border); color: var(--t-hi); padding: 0 12px; font-size: 16px; }
.v2-text:focus { outline: none; border-color: var(--accent-ink); }
.v2-check { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--t-md); min-height: 44px; cursor: pointer; }
.v2-check input { width: 22px; height: 22px; accent-color: var(--accent-ink); flex: none; margin: 0; }
.v2-conds { display: grid; }
.v2-link { align-self: flex-start; min-height: 44px; font-size: 13.5px; font-weight: 600; color: var(--t-hi); padding: 6px 0; text-decoration: underline; text-decoration-color: var(--border-hi); text-underline-offset: 3px; }

/* ride weigh-in: bottles drunk as a count and a size, and the result */
.v2-bottles { display: flex; align-items: stretch; gap: 8px; }
.v2-bottles .v2-seg { flex: 1; }
.v2-step { flex: none; display: flex; align-items: center; gap: 2px; padding: 4px; background: var(--surface-2); border-radius: var(--r-md); }
.v2-step button { width: 40px; height: 40px; border-radius: var(--r-sm); display: grid; place-items: center; color: var(--t-hi); transition: background .16s; }
.v2-step button:active { background: var(--surface-hi); }
.v2-step button:disabled { opacity: 0.35; }
.v2-step .n { min-width: 30px; text-align: center; font-family: var(--fmono); font-size: 15px; font-weight: 600; color: var(--t-hi); }
.v2-nums.three .v2-num input { padding-right: 34px; }
.weigh-result { padding: 13px 14px; border-radius: var(--r-md); background: var(--surface-2); }

/* the things used once a month: a plain list at the foot of the sheet */
.set-rows { display: flex; flex-direction: column; background: var(--surface-2); border-radius: var(--r-md); overflow: hidden; }
.set-row { display: flex; align-items: center; gap: 13px; min-height: 56px; padding: 8px 14px; text-align: left; transition: background .16s; }
.set-row + .set-row { border-top: 1px solid var(--hairline); }
.set-row:active { background: var(--surface-hi); }
.set-row:disabled { opacity: 0.45; cursor: default; }
.set-ico { flex: none; width: 20px; display: grid; place-items: center; color: var(--t-md); }
.set-ico svg { width: 16px; height: 16px; }
.set-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 14px; font-weight: 600; color: var(--t-hi); }
.set-txt small { font-size: 11.5px; font-weight: 400; color: var(--t-lo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* the three engines: a comparison whose rows are the switch */
.v2-eng { display: flex; flex-direction: column; }
.v2-eng-row { display: grid; grid-template-columns: minmax(0, 2.1fr) repeat(4, minmax(0, 1fr)); align-items: center; gap: 4px; width: 100%; min-height: 46px; padding: 0 8px; border-radius: var(--r-sm); font-size: 13px; color: var(--t-md); text-align: right; transition: background .2s, color .2s; }
.v2-eng-row.head { min-height: 0; padding-bottom: 6px; font-size: 10.5px; font-family: var(--fmono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--t-lo); }
.v2-eng-row .nm { display: flex; align-items: center; gap: 9px; text-align: left; white-space: nowrap; }
.v2-eng-row.on { background: var(--surface-2); color: var(--t-hi); font-weight: 600; }
.v2-eng-row:disabled { opacity: 0.5; cursor: default; }
button.v2-eng-row:active { background: var(--surface-hi); }
.v2-radio { flex: none; width: 14px; height: 14px; border-radius: 50%; box-sizing: border-box; border: 1.5px solid var(--t-xlo); transition: border .2s; }
.v2-eng-row.on .v2-radio { border: 4.5px solid var(--accent-ink); }
.v2-eng-hint { margin-top: 8px; }
.v2-line { font-size: 12.5px; line-height: 1.5; color: var(--t-md); margin-top: 10px; }
.v2-line.bad { color: var(--bad); }
.v2-line strong { color: var(--t-hi); font-weight: 600; }

/* day complete: the foot of the meals card */
.v2-complete { display: flex; align-items: center; gap: 12px; padding: 13px 16px 14px; border-top: 1px solid var(--hairline); }
.v2-complete-mark { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-style: normal; }
.v2-complete-mark svg { width: 13px; height: 13px; }
.v2-complete-mark.in   { background: var(--ok-dim); color: var(--ok); }
.v2-complete-mark.out  { background: var(--track); color: var(--t-lo); }
.v2-complete-mark.wait { background: var(--track); color: var(--t-md); }
.v2-complete-txt { flex: 1; min-width: 0; font-size: 13px; color: var(--t-hi); }
.v2-complete-txt .num span { display: inline-block; white-space: nowrap; }
.v2-complete-txt .v2-hint { margin-top: 3px; }
.v2-complete-btn { flex: none; min-height: 44px; padding: 0 14px; border-radius: var(--r-md); font-size: 13px; font-weight: 600; background: var(--accent); color: var(--on-accent); display: inline-flex; align-items: center; gap: 6px; transition: transform .16s var(--ease); }
.v2-complete-btn:active { transform: scale(0.95); }
.v2-complete-btn.quiet { background: var(--surface-hi); color: var(--t-hi); }
.v2-complete-btn:disabled { opacity: 0.4; }

/* 7-day energy: logged against each day's own target */
.wk-chart { margin: 2px 0 16px; }
.wk-plot { position: relative; height: 112px; display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--border-hi); }
.wk-band, .wk-target { position: absolute; left: 0; right: 0; pointer-events: none; }
.wk-band { background: color-mix(in oklch, var(--ok) 26%, transparent); box-shadow: inset 0 1px 0 color-mix(in oklch, var(--ok) 65%, transparent), inset 0 -1px 0 color-mix(in oklch, var(--ok) 65%, transparent); }
.wk-target { height: 0; border-top: 1px solid var(--t-lo); }
.wk-col { position: relative; z-index: 1; display: flex; align-items: flex-end; justify-content: center; height: 100%; min-width: 0; padding: 0; border-radius: var(--r-sm) var(--r-sm) 0 0; transition: background .16s; }
.wk-col:active { background: var(--surface-2); }
.wk-bar { width: min(24px, 56%); border-radius: 6px 6px 0 0; background: var(--c-kcal); transform-origin: bottom; animation: bar-up .6s var(--ease) backwards; }
.wk-bar.out { background: transparent; box-shadow: inset 0 0 0 1.5px var(--t-lo); }
@keyframes bar-up { from { transform: scaleY(0); } }
.wk-labels { display: grid; grid-template-columns: repeat(7, 1fr); padding-top: 7px; font-size: 11px; font-weight: 500; color: var(--t-lo); text-align: center; line-height: 1; }
.wk-labels .sel { color: var(--t-hi); font-weight: 700; }
.wk-key { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: 11.5px; color: var(--t-lo); }
.wk-key span { display: inline-flex; align-items: center; gap: 6px; }
.wk-sw { width: 10px; height: 10px; border-radius: 3px; background: var(--c-kcal); }
.wk-sw.out { background: transparent; box-shadow: inset 0 0 0 1.5px var(--t-lo); }
.wk-sw.band { width: 14px; background: linear-gradient(var(--t-lo), var(--t-lo)) center / 100% 1px no-repeat, color-mix(in oklch, var(--ok) 26%, transparent); box-shadow: inset 0 1px 0 color-mix(in oklch, var(--ok) 65%, transparent), inset 0 -1px 0 color-mix(in oklch, var(--ok) 65%, transparent); }

.v2-tiers { display: flex; flex-direction: column; }
.v2-tier { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; padding: 10px 0; border-top: 1px solid var(--hairline); }
.v2-tier:first-child { border-top: 0; }
.v2-tier .nm { font-size: 13.5px; color: var(--t-hi); min-width: 0; }
.v2-tier .ref { display: block; font-size: 10.5px; color: var(--t-lo); font-family: var(--fmono); margin-top: 2px; }
.v2-tier .measured { display: block; font-size: 10.5px; color: var(--t-lo); margin-top: 1px; }
.v2-tier .val { font-size: 12px; color: var(--t-md); text-align: right; white-space: nowrap; }
.v2-chip { font-size: 11px; font-weight: 600; padding: 4px 9px; border-radius: var(--r-pill); white-space: nowrap; min-width: 92px; text-align: center; }
.v2-chip.ok { background: var(--ok-dim); color: var(--ok); }
.v2-chip.ok.soft { background: transparent; box-shadow: inset 0 0 0 1px var(--ok-dim); }
.v2-chip.warn { background: var(--warn-dim); color: var(--warn); }
.v2-chip.bad { background: var(--bad-dim); color: var(--bad); }
.v2-chip.none { background: var(--track); color: var(--t-lo); }
/* what the nutrients card found, named while it is closed */
.v2-flagged { display: flex; flex-wrap: wrap; gap: 6px; }
.v2-flagged .v2-chip { min-width: 0; }
.disclosure.open .disc-always:has(> .when-closed) { display: none; }

.v2-supp { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 48px; padding: 6px 0; border-bottom: 1px solid var(--hairline); font-size: 13.5px; }
.v2-recent { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 0 2px; }
.v2-pill { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px; border-radius: var(--r-pill); background: var(--surface-hi); color: var(--t-hi); font-size: 12.5px; font-weight: 600; transition: transform .16s var(--ease); }
.v2-pill:active { transform: scale(0.95); }
.v2-pill:disabled { opacity: 0.5; }
.v2-supp-form { display: flex; flex-direction: column; gap: 9px; padding-top: 10px; align-items: stretch; }
.v2-supp-form .v2-pill { align-self: flex-start; }
.v2-supp-form .v2-num input, .v2-supp-form .v2-text { background: var(--surface); }
.v2-supp-form .v2-num input { padding-right: 30px; }
.est-actions .confirm:disabled { opacity: 0.4; }

/* ─── SN-H-03: the shell at medium and expanded widths ───
   Compact is the single column above, unchanged. Medium sets the day beside
   a panel of insights; expanded gives the day, its meals and the insights a
   region each. The panel sticks under the header and scrolls on its own:
   the page scroller is a size container, so 100cqh is its height. */
.app-root.medium .screen, .app-root.expanded .screen { max-width: none; }
.app-root.expanded .screen { max-width: var(--shell-max); }
.app-root.medium .screen-scroll, .app-root.expanded .screen-scroll { container-type: size; }
.day-view.medium, .day-view.expanded {
  display: grid; column-gap: var(--col-gap); align-items: start;
  padding: 0 calc(var(--page-x) - 4px);
}
.day-view.medium { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.day-view.expanded { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.day-view.medium > .dock-clear, .day-view.expanded > .dock-clear { grid-column: 1 / -1; }
.col { min-width: 0; }
.col .section { padding-left: 4px; padding-right: 4px; }
.col-side {
  position: sticky; top: 0; max-height: 100cqh; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; touch-action: pan-y; padding-bottom: 24px;
}
/* medium: the dock sits under the day, the column that holds the meals */
.app-root.medium .dock { right: auto; width: calc((100% - 2 * var(--page-x) + 8px - var(--col-gap)) * 0.6 - 8px); }
/* expanded: no dock; logging starts from the header, and its sheet opens
   over the meals column instead of rising across the whole width */
.app-root.expanded .dock, .app-root.expanded .screen::after, .day-view.expanded > .dock-clear { display: none; }
.header-log {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px;
  border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent); font-size: 13.5px; font-weight: 600;
}
.header-log svg { width: 16px; height: 16px; }
.app-root.medium .sheet { left: 50%; right: auto; width: min(560px, 100%); margin-left: max(-280px, -50%); }
.app-root.expanded .sheet { left: 50%; right: auto; width: min(560px, 100%); margin-left: max(-280px, -50%); }
.app-root.expanded .sheet.log-sheet {
  width: calc((min(100vw, var(--shell-max)) - 2 * var(--page-x) - 2 * var(--col-gap)) / 3 + 24px);
  margin-left: 0; transform-origin: top;
  left: calc(50% - (min(100vw, var(--shell-max)) - 2 * var(--page-x) - 2 * var(--col-gap)) / 6 - 12px);
  top: 72px; bottom: 16px; max-height: none; border-radius: var(--r-xl); border: 1px solid var(--border-hi);
}
.app-root.medium .toast, .app-root.expanded .toast { max-width: 444px; }
.app-root.expanded .toast { bottom: 24px; }

/* SN-H-05 — touch targets of 44 px or more. These controls draw smaller
   than that; an invisible hit area brings each up to 44 px without moving
   anything around them. */
.band-btn, .cond-chip, .engine-pill, .day-step, .live-dot, .v2-pill, .weigh-btn, .today-pill { position: relative; }
.band-btn::after, .cond-chip::after, .engine-pill::after, .day-step::after, .live-dot::after,
.v2-pill::after, .weigh-btn::after, .today-pill::after {
  content: ""; position: absolute; right: auto; bottom: auto; left: 50%; top: 50%;
  width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%);
}
.day-step { margin: 0 -6px; }
/* a phone already has the swipe; the step buttons are for a mouse */
@media (pointer: coarse) { .app-root.compact .day-step { display: none; } }

/* SN-H-06 — a photo dragged over the log sheet */
.log-drop { position: relative; border-radius: var(--r-lg); outline: 2px dashed transparent; outline-offset: 6px; transition: outline-color .15s; }
.log-drop.on { outline-color: var(--accent-ink); }
.log-drop-hint { display: flex; align-items: center; gap: 8px; justify-content: center; padding: 10px; margin-bottom: 8px;
  border-radius: var(--r-md); background: var(--surface-2); color: var(--accent-ink); font-size: 13px; font-weight: 600; }
.log-drop-hint svg { width: 18px; height: 18px; }

/* SN-H-07 — choosing between two devices' versions of a meal */
.merge-sheet { display: flex; flex-direction: column; gap: 12px; }
.merge-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.merge-opt { display: flex; flex-direction: column; gap: 4px; text-align: left; padding: 12px; min-height: 44px;
  border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-2); color: var(--t-md); font-size: 12.5px; line-height: 1.4; }
.merge-opt.on { border-color: var(--accent-ink); color: var(--t-hi); }
.merge-who { font-size: 11px; font-weight: 600; color: var(--t-lo); }
.merge-opt.on .merge-who { color: var(--accent-ink); }
