/* Mesa styles */
:root{
  --bg:#f4eddf;
  --card:#fffaf0;
  --paper:#fbf5e8;
  --ink:#342d25;
  --ink-soft:#6e6253;
  --muted:#998d7d;
  --line:#dfd1bb;
  --sage:#7f9364;
  --sage-deep:#566b43;
  --sage-tint:#edf1df;
  --sage-rgb:127,147,100;
  --terra:#be6c45;
  --terra-tint:#f4dfcf;
  --gold:#c79a48;
  --berry:#9a665e;
  /* Day-balance signal colours (owner 2026-09-08) — FIXED semantic scale, deliberately NOT the
     seasonal accent (--sage*), so a "good day" always reads green regardless of the month theme:
     green = balanced/good, yellow-green = minor deviation (week can still balance), amber = a
     real outlier. */
  --balance-good:#5f8a4f;
  --balance-minor:#94991f;
  --balance-off:#cf8a30;
  --shadow:0 10px 24px rgba(73,54,32,.10);
  --shadow-soft:0 3px 10px rgba(73,54,32,.07);
  --radius:14px;
  --font-serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --font-script:"Snell Roundhand","Bradley Hand","Segoe Script",cursive;
  --monthly-art:none;
  /* This variable is used as a background-image layer, so its neutral value
     must be the image keyword `none` (not the color value `transparent`). */
  --season-wash:none;
  /* Today copy is split by surface: watercolor, eyebrow, paper-card title,
     paper-card detail, and the closing profile note. Each month maps these. */
  --today-art-heading:#3c3228;
  --today-art-kicker:#566b43;
  --today-card-title:#342d25;
  --today-card-detail:#6e6253;
  --today-note-text:#4d4135;
  --today-note-bg:rgba(255,250,240,.74);
  --today-note-border:rgba(176,146,105,.38);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{margin:0;padding:0;}
body{
  font-family:var(--font-serif);
  background:
    radial-gradient(circle at 18% 12%, rgba(255,255,255,.62) 0 1px, transparent 1.5px),
    radial-gradient(circle at 78% 42%, rgba(116,87,44,.08) 0 1px, transparent 1.6px),
    linear-gradient(90deg, rgba(109,79,42,.035) 1px, transparent 1px),
    var(--bg);
  background-size:22px 22px, 31px 31px, 34px 34px, auto;
  color:var(--ink);
  min-height:100vh;
  padding:0;
  display:block;
}

/* Month-specific watercolor artwork is deliberately held behind a warm paper veil.
   The artwork changes automatically with the calendar while the translucent UI cards
   retain their quiet, highly legible character. */
/* Citrus is Mesa's January winter note; February shifts to the softer, more playful
   artichoke watercolor, while grapes make September's harvest cue unmistakable. */
/* Every month carries a related accent triad. Existing components consume these
   tokens for active tabs, confirmation controls, links, and success states. */
body[data-month="1"]{--monthly-art:url("../assets/monthly-backgrounds/february.png");--sage:#b87346;--sage-deep:#8d4e2e;--sage-tint:#f5e4d6;--sage-rgb:184,115,70;--today-art-heading:#6d3d27;--today-art-kicker:#8d4e2e;--today-card-title:#39291f;--today-card-detail:#6b5444;--today-note-text:#5e3a28;--today-note-bg:rgba(255,247,235,.80);--today-note-border:rgba(141,78,46,.24);}
body[data-month="2"]{--monthly-art:url("../assets/monthly-backgrounds/february-artichokes.png");--sage:#876b86;--sage-deep:#654f67;--sage-tint:#efe6ef;--sage-rgb:135,107,134;--today-art-heading:#503d52;--today-art-kicker:#654f67;--today-card-title:#372f38;--today-card-detail:#655c66;--today-note-text:#4c3c50;--today-note-bg:rgba(253,247,252,.80);--today-note-border:rgba(101,79,103,.24);}
body[data-month="3"]{--monthly-art:url("../assets/monthly-backgrounds/march.png");--sage:#78966c;--sage-deep:#536e4d;--sage-tint:#eaf0e4;--sage-rgb:120,150,108;--today-art-heading:#395942;--today-art-kicker:#536e4d;--today-card-title:#30372b;--today-card-detail:#5c6657;--today-note-text:#38553f;--today-note-bg:rgba(247,251,241,.80);--today-note-border:rgba(83,110,77,.24);}
body[data-month="4"]{--monthly-art:url("../assets/monthly-backgrounds/april.png");--sage:#b8626d;--sage-deep:#894550;--sage-tint:#f5e3e5;--sage-rgb:184,98,109;--today-art-heading:#703b45;--today-art-kicker:#894550;--today-card-title:#412a2f;--today-card-detail:#73575c;--today-note-text:#693640;--today-note-bg:rgba(255,246,247,.80);--today-note-border:rgba(137,69,80,.24);}
body[data-month="5"]{--monthly-art:url("../assets/monthly-backgrounds/may.png");--sage:#b85c69;--sage-deep:#8d3f51;--sage-tint:#f6e0e5;--sage-rgb:184,92,105;--today-art-heading:#713443;--today-art-kicker:#8d3f51;--today-card-title:#40282f;--today-card-detail:#75545d;--today-note-text:#68313f;--today-note-bg:rgba(255,246,248,.80);--today-note-border:rgba(141,63,81,.24);}
body[data-month="6"]{--monthly-art:url("../assets/monthly-backgrounds/june.png");--sage:#4e8b7d;--sage-deep:#32685d;--sage-tint:#dff0eb;--sage-rgb:78,139,125;--today-art-heading:#24584f;--today-art-kicker:#32685d;--today-card-title:#283a36;--today-card-detail:#526761;--today-note-text:#23564d;--today-note-bg:rgba(242,251,248,.80);--today-note-border:rgba(50,104,93,.24);}
body[data-month="7"]{--monthly-art:url("../assets/monthly-backgrounds/july.png");--sage:#b96548;--sage-deep:#8b422f;--sage-tint:#f5e2d9;--sage-rgb:185,101,72;--today-art-heading:#743b29;--today-art-kicker:#8b422f;--today-card-title:#3d2b24;--today-card-detail:#6c5448;--today-note-text:#703a29;--today-note-bg:rgba(255,247,241,.80);--today-note-border:rgba(139,66,47,.24);}
body[data-month="8"]{--monthly-art:url("../assets/monthly-backgrounds/august.png");--sage:#827154;--sage-deep:#5f523d;--sage-tint:#f0eadb;--sage-rgb:130,113,84;--today-art-heading:#4f4634;--today-art-kicker:#5f523d;--today-card-title:#373229;--today-card-detail:#625c4f;--today-note-text:#4c4432;--today-note-bg:rgba(253,250,240,.80);--today-note-border:rgba(95,82,61,.24);}
body[data-month="9"]{--monthly-art:url("../assets/monthly-backgrounds/september-grapes.png");--sage:#95627a;--sage-deep:#6d3f58;--sage-tint:#f2e2e9;--sage-rgb:149,98,122;--today-art-heading:#4d2942;--today-art-kicker:#6d3f58;--today-card-title:#3c2935;--today-card-detail:#6d5964;--today-note-text:#4a2b40;--today-note-bg:rgba(255,248,246,.84);--today-note-border:rgba(109,63,88,.28);}
body[data-month="10"]{--monthly-art:url("../assets/monthly-backgrounds/october.png");--sage:#b46b3d;--sage-deep:#864722;--sage-tint:#f6e2d1;--sage-rgb:180,107,61;--today-art-heading:#6d3518;--today-art-kicker:#864722;--today-card-title:#40291e;--today-card-detail:#704f3d;--today-note-text:#653317;--today-note-bg:rgba(255,247,239,.82);--today-note-border:rgba(134,71,34,.25);}
body[data-month="11"]{--monthly-art:url("../assets/monthly-backgrounds/november.png");--sage:#89624b;--sage-deep:#644432;--sage-tint:#f1e3da;--sage-rgb:137,98,75;--today-art-heading:#fff8eb;--today-art-kicker:#f4d7b3;--today-card-title:#3e2d25;--today-card-detail:#6d5548;--today-note-text:#fff7e9;--today-note-bg:rgba(67,44,32,.58);--today-note-border:rgba(255,237,211,.34);}
body[data-month="12"]{--monthly-art:url("../assets/monthly-backgrounds/december.png");--sage:#5f8469;--sage-deep:#3e6148;--sage-tint:#e3eee4;--sage-rgb:95,132,105;--today-art-heading:#fff9ed;--today-art-kicker:#ebce8e;--today-card-title:#2e392f;--today-card-detail:#556458;--today-note-text:#fff8e8;--today-note-bg:rgba(37,67,48,.62);--today-note-border:rgba(244,224,177,.38);}

/* ---------- App root: fills the real viewport (no more desktop phone frame) ---------- */
.phone{
  width:100%;height:100vh;height:100dvh;
  /* Kept as explicit longhand layers rather than a shorthand with a custom URL.
     Safari's installed-PWA renderer can discard that shorthand layer, leaving the
     paper fallback visible but not the monthly illustration. */
  background-color:var(--bg);
  background-image:
    linear-gradient(90deg, rgba(155,116,68,.07) 0 1px, transparent 1px),
    radial-gradient(circle at 10% 20%, rgba(255,255,255,.44), transparent 28%),
    linear-gradient(180deg, rgba(255,250,240,.12), rgba(255,250,240,.04)),
    var(--monthly-art),
    var(--season-wash);
  /* Keep motifs clear of the fixed tab bar, with the image edge hidden directly
     underneath its 88px height rather than leaving a visible paper strip. */
  background-position:32px 0,center,center,center bottom 88px,center;
  background-size:34px 34px,auto,auto,cover,cover;
  background-repeat:repeat,no-repeat,no-repeat,no-repeat,no-repeat;
  position:relative;
  overflow:hidden;
  display:flex;flex-direction:column;
  padding-bottom:env(safe-area-inset-bottom);
}

/* ---------- App body ---------- */
.app{flex:1;position:relative;overflow:hidden;}
.screen{
  position:absolute;inset:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:6px 18px 108px;opacity:0;transform:translateY(8px);
  pointer-events:none;transition:opacity .28s ease, transform .28s ease;
}
.screen.active{opacity:1;transform:none;pointer-events:auto;}
.screen::-webkit-scrollbar{display:none;}

h1{font-family:var(--font-script);font-size:34px;line-height:1.04;margin:6px 0 2px;font-weight:500;color:#2f281f;}
h2{font-family:var(--font-script);font-size:25px;margin:22px 0 10px;font-weight:500;color:#3c3228;}
.sub{color:var(--muted);font-size:13.5px;margin:0 0 4px;}
#todayPlanNote{margin:16px 0 0!important;padding:8px 12px;text-align:center;color:var(--today-note-text)!important;background:var(--today-note-bg);border:1px solid var(--today-note-border);border-radius:12px;box-shadow:0 4px 12px rgba(73,54,32,.08);text-shadow:none!important;}
.day-cue{color:var(--balance-minor);font-weight:600;}
/* Stronger day-cue variant for a genuinely high reading (currently: total-fat 'over',
   PER_DAY_BANDS.fat state.js) — reuses --terra, the app's existing over/high accent
   (.ring-over, .spark .col.over), so this introduces no new color, just a second calm
   tone alongside the amber .day-cue default. Never the whole app going red — one inline
   word, same weight/size as .day-cue. */
.day-cue-over{color:var(--balance-off);font-weight:700;}
.day-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:7px;vertical-align:middle;}
.day-dot-ok{background:var(--balance-good);}
.day-dot-minor{background:var(--balance-minor);}
.day-dot-off{background:var(--balance-off);}
/* Persistent "day closed" trace (item 4) — a quiet, STATIC single leaf on the Week day
   header, distinct from day-dot above (a quality signal). No animation, no streak, no
   pass/fail color: it only ever marks "every plannable slot here is accounted for". */
.day-closed-leaf{display:inline-block;width:9px;height:13px;margin-right:5px;vertical-align:middle;opacity:.85;}
.day-closed-leaf svg{width:100%;height:100%;}
.day-closed-leaf .leaf-body{fill:var(--sage-deep);stroke:rgba(var(--sage-rgb),.4);stroke-width:.6;}
.eyebrow{font-size:11px;font-weight:700;letter-spacing:1.7px;text-transform:uppercase;color:var(--sage-deep);}

/* Today’s watercolor layer has a scoped text palette, so pale September art cannot
   inherit a broad white subtitle rule intended for richer winter paintings. */
#today .topbar h1,#today > .row.between h2{color:var(--today-art-heading);text-shadow:0 1px 9px rgba(255,250,240,.32);}
#today .topbar .eyebrow{color:var(--today-art-kicker);text-shadow:0 1px 7px rgba(255,250,240,.36);}
#today .meal .info .t,#todayProgressCard .ring .big,#todayProgressCard .macro .mhead b,#todayRecordsCard .today-extras-title b{color:var(--today-card-title);}
#today .meal .info .d,#todayProgressCard .macro .mhead > span,#todayRecordsCard .today-extras-title small,#todayRecordsCard .logitem .li-t small{color:var(--today-card-detail);}

.card{background:rgba(255,250,240,.88);border-radius:var(--radius);box-shadow:var(--shadow-soft);padding:16px;margin-top:12px;border:1px solid rgba(176,146,105,.38);}
.row{display:flex;align-items:center;gap:12px;}
.between{justify-content:space-between;}
.pill{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;padding:5px 9px;border-radius:999px;background:var(--sage-tint);color:var(--sage-deep);border:1px solid rgba(var(--sage-rgb),.16);}
.pill.terra{background:var(--terra-tint);color:#b25e35;}
.pill.gold{background:#f6edd6;color:#9a7414;}
.pill.berry{background:#f1e2ea;color:#7c4360;}
.pill.ghost{background:#eef0ec;color:var(--ink-soft);}

/* top bar with profile switch */
.topbar{display:flex;align-items:center;justify-content:space-between;margin-top:6px;}
/* When the row runs out of room (a long display name in the person-switcher below), the
   date+greeting block is what gives way — it wraps, the switcher and avatar can't. It
   keeps the default min-width:auto so it still floors at its own min-content (the widest
   word of the greeting), which is what stops this from clipping "morning" on a 320px
   screen; past that floor flex hands the remaining squeeze back to .top-actions.
   .top-actions gets min-width:0 instead, because a flex item that won't shrink below its
   content is exactly what shoved the avatar button off the 375px screen. */
.topbar > :first-child{flex-shrink:99;}
.top-actions{display:flex;align-items:center;gap:8px;min-width:0;}
/* The segmented control is used with BOTH fixed labels (Female/Male, Just me/Me + partner,
   This week/Next week, Today/Yesterday) and — since the person-switcher was unified into
   render.js:personSwitcherHtml() — user-typed display names up to state.js
   DISPLAY_NAME_MAX_LEN (24 chars). Nothing here can assume the labels are short, so the
   pill and its buttons both get min-width:0 — a flex item's default min-width:auto means
   its text is an unbreakable floor it will widen the whole row to honour — and the
   buttons ellipsize what no longer fits. No-op for the fixed-label uses, and the only
   thing standing between a long name and a broken row for the person-switcher. */
.seg{display:flex;background:#e8dcc8;border-radius:999px;padding:3px;border:1px solid rgba(176,146,105,.32);min-width:0;max-width:100%;}
.seg button{border:0;background:transparent;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);padding:7px 13px;border-radius:999px;cursor:pointer;transition:.2s;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.seg button.on{background:var(--card);color:var(--ink);box-shadow:var(--shadow-soft);}
/* Person-switcher mounts (render.js:renderPersonSwitchers) that share their row with
   something else — Today's topbar, where the avatar button sits beside it, and the
   .row.between heading rows on Week/Insights/Log. Shrinking alone isn't enough there:
   flex would hand the pill whatever's left after two long names claim their share, so
   give it a ceiling and let the ellipsis above do the rest. max-width, NOT flex-basis:
   the pill has to keep sizing to its content so ordinary names ("Elena"/"Andrea") still
   hug it — a 184px basis would make it claim the full budget on every screen, and on
   Today that claim comes back as a shrink that ellipsizes names which fit fine. Profile's
   #profWhoSeg is deliberately NOT matched — it's a full-width control on its own row
   (inline width:100%), which is where a long name stays fully readable. */
.topbar [data-person-switcher],
.row.between > [data-person-switcher]{flex:0 1 auto;max-width:184px;}
/* A floor on each half, because flex shrinks the two names in proportion to their own
   widths: pair a short name with a long one ("Sofia"/"Bartholomew") on a 320px screen and
   the SHORT one is the one that collapses — it has the least to give — leaving an active
   pill reading "S…" next to a comfortable "Bartho…". 4.5em keeps roughly four characters
   on both sides; once a half hits it, flex hands the rest of the squeeze to its sibling,
   so the two degrade together instead of one being wiped out. */
[data-person-switcher] button{min-width:4.5em;}
.avatar{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;font-weight:700;color:#fff;font-size:15px;background:linear-gradient(135deg,var(--sage),var(--sage-deep));}
.profile-icon-btn{width:38px;height:38px;flex:0 0 auto;border:1px solid rgba(176,146,105,.36);border-radius:50%;display:grid;place-items:center;background:var(--card);box-shadow:var(--shadow-soft);color:var(--sage-deep);font:inherit;font-weight:800;cursor:pointer;padding:0;}
.profile-icon-btn span{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;background:linear-gradient(135deg,var(--sage),var(--sage-deep));color:#fff;font-size:13px;}

/* calorie ring */
.today-glance{width:100%;min-height:58px;margin-top:13px;padding:9px 12px;border:1px solid rgba(127,147,100,.2);border-radius:14px;background:linear-gradient(100deg,rgba(237,241,223,.9),rgba(255,250,240,.92));display:grid;grid-template-columns:minmax(105px,1fr) auto 16px;align-items:center;gap:9px;font:inherit;text-align:left;color:var(--ink);cursor:pointer;box-shadow:0 3px 10px rgba(93,75,45,.04);}
.today-glance:active{transform:scale(.99);}
.today-glance-copy{min-width:0;display:flex;flex-direction:column;gap:2px;}
.today-glance-label{font-size:11px;font-weight:700;color:var(--ink-soft);}
.today-glance-copy b{font-size:15px;letter-spacing:-.15px;white-space:nowrap;}
.today-glance-macros{display:flex;align-items:center;gap:7px;}
.today-glance-macro{position:relative;min-width:31px;padding-left:7px;display:flex;flex-direction:column;font-style:normal;line-height:1.12;}
.today-glance-macro:before{content:"";position:absolute;left:0;top:2px;bottom:2px;width:3px;border-radius:99px;background:var(--sage);}
.today-glance-macro span{font-size:9px;font-weight:700;color:var(--muted);}
.today-glance-macro em{margin-top:2px;font-size:11px;font-style:normal;font-weight:800;color:var(--ink-soft);}
.today-glance-macro.glance-c:before{background:var(--gold);}.today-glance-macro.glance-f:before{background:var(--terra);}
.today-glance-chev{font-size:15px;color:var(--muted);transform:rotate(-90deg);}
.ring-wrap{display:flex;align-items:center;gap:18px;}
.ring{position:relative;width:128px;height:128px;flex:0 0 128px;}
.ring svg{transform:rotate(-90deg);}
.ring .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;}
.ring .big{font-size:27px;font-weight:700;letter-spacing:-.5px;}
.ring .lbl{font-size:11px;color:var(--muted);margin-top:1px;}

.macros{flex:1;display:flex;flex-direction:column;gap:11px;}
.macro .mhead{display:flex;justify-content:space-between;font-size:12.5px;margin-bottom:5px;}
.macro .mhead b{font-weight:600;}
.bar{height:8px;border-radius:999px;background:#eef0ec;overflow:hidden;}
.bar > i{display:block;height:100%;border-radius:999px;}
.b-p{background:var(--sage);}
.b-c{background:var(--gold);}
.b-f{background:var(--terra);}

/* meal cards */
.meal{display:flex;gap:13px;align-items:center;cursor:pointer;flex-wrap:wrap;}
.meal .thumb{width:60px;height:60px;border-radius:14px;flex:0 0 60px;display:grid;place-items:center;font-size:28px;background:#f3ead9;border:1px solid rgba(176,146,105,.28);overflow:hidden;}
.meal .thumb .meal-thumb-art{display:block;width:100%;height:100%;object-fit:cover;}
.meal .info{flex:1;min-width:0;}
.meal .info .t{font-weight:600;font-size:15px;}
.meal .info .d{font-size:12.5px;color:var(--muted);margin-top:2px;}
.meal .kcal{font-size:13px;font-weight:700;color:var(--ink);}
.meal .tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:7px;}
.swap{border:0;background:#eef0ec;color:var(--ink-soft);font:inherit;font-size:11px;font-weight:600;padding:6px 10px;border-radius:999px;cursor:pointer;}
.swap:active{transform:scale(.95);}
.meal.done{opacity:.62;}
.meal.done .thumb{filter:grayscale(.35);}
.meal.skipped{opacity:.55;}
.confirmed-tag{font-size:12px;font-weight:700;color:var(--sage-deep);margin-top:8px;}
.skipped-tag{font-size:12px;font-weight:700;color:var(--muted);margin-top:8px;}
/* FIX 2 (feedback): the confirmed/skipped tag row also carries an Undo ghost button —
   44px tap target (ground rule 4), visually quiet so the status text stays the focus. */
.tag-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:4px;}
.tag-row .confirmed-tag,.tag-row .skipped-tag{margin-top:0;}
.tag-controls{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end;}
.tag-undo{min-height:44px;min-width:64px;padding:0 12px;border:1px solid var(--line);background:#fff;border-radius:12px;font:inherit;font-size:12px;font-weight:700;color:var(--sage-deep);cursor:pointer;}
.tag-undo:active{transform:scale(.96);}

.meta-line{display:flex;gap:14px;font-size:12px;color:var(--muted);margin-top:4px;flex-wrap:wrap;}

/* FIX 1 (feedback): Confirm/Skip round buttons directly on the Today cards — same color
   language as .swap (sage=confirm, terra=skip) but round like .sv-stepper button, sized to
   the 44px tap-target minimum (ground rule 4) since these sit right next to the card's own
   recipe-open tap target. */
.today-actions{margin-top:9px;}
.ta-actions{display:flex;gap:10px;}
.ta-btn{width:44px;height:44px;border-radius:50%;border:0;font-size:17px;font-weight:700;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.ta-btn:active{transform:scale(.92);}
.ta-confirm{background:var(--sage);color:#fff;}
.ta-swap{background:#eef0ec;color:var(--ink-soft);}
.ta-skip{background:#f6e6dc;color:#b25e35;}
.today-actions .tag-row{margin-top:0;}

/* BOOST CHIP (v1, manual-only nutrition nudge): calm sage pill, never terra/warning — this
   is an invitation, not a correction. Its own small ✕ dismisses for the day, same visual
   convention as .basics-banner-card's .bb-x. Both buttons stopPropagation (inline, at the
   call site) so tapping either never also triggers the card's own recipe-open tap. */
.boost-chip{display:flex;align-items:center;gap:4px;margin-top:9px;}
.boost-chip-btn{border:1px solid rgba(var(--sage-rgb),.28);background:var(--sage-tint);color:var(--sage-deep);font:inherit;font-size:12px;font-weight:700;padding:0 12px;height:36px;border-radius:999px;cursor:pointer;}
.boost-chip-btn:active{transform:scale(.96);}
.boost-chip-x{border:0;background:none;color:var(--sage-deep);opacity:.55;font-size:13px;cursor:pointer;padding:0 8px;height:36px;line-height:1;}

/* nutrient coverage chips */
.nutri{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;}
.nutri .n{background:#fff;border:1px solid var(--line);border-radius:16px;padding:11px 13px;}
.nutri .n .nt{font-size:12px;color:var(--ink-soft);display:flex;justify-content:space-between;}
.nutri .n .ndetail{display:flex;flex-wrap:wrap;gap:3px 9px;margin-top:7px;font-size:10.5px;color:var(--muted);}
.nutri .n .ndetail b{color:var(--ink-soft);}
.nutri .n .nbar{height:6px;border-radius:999px;background:#eef0ec;margin-top:8px;overflow:hidden;}
.nutri .n .nbar i{display:block;height:100%;border-radius:999px;background:var(--sage);}
.nutri .n.low .nbar i{background:var(--terra);}

/* shared meals + macro-split additions */
.pill.together{background:var(--sage-tint);color:var(--sage-deep);}
.pill.mini{padding:3px 7px;font-size:9.5px;}
/* MEAL-BUILDER: the "Meal" pill (a recipe-of-recipes) + its dish-name subtitle in recipe rows. */
.pill.sage{background:var(--sage-tint);color:var(--sage-deep);}
.altrow .ad.meal-dishes{color:var(--sage-deep);font-style:italic;margin-top:0;}
/* library.js: delete affordance on custom-food/custom-recipe/builder-ingredient rows —
   sized to the app's 44px tap-target minimum (ground rule 4), unlike the smaller inline
   log-action buttons (.la-skip etc.) it visually echoes. */
.lib-del{width:44px;height:44px;min-width:44px;flex:0 0 44px;border:0;border-radius:12px;background:#f6e6dc;color:#b25e35;font-size:15px;font-weight:700;cursor:pointer;}
.lib-del:active{transform:scale(.94);}
.lib-edit{width:44px;height:44px;min-width:44px;flex:0 0 44px;border:0;border-radius:12px;background:var(--sage-tint);color:var(--sage-deep);font-size:17px;font-weight:700;cursor:pointer;}
.lib-edit.is-pref{background:var(--terra-tint);color:#b25e35;}
.lib-edit:active{transform:scale(.94);}
/* Ingredient-row actions stack VERTICALLY in one 44px column rather than sitting side by
   side. Adding "Add to pantry" as a third inline button cost the row's text block 56px of
   its 195px (29%), pushing names onto two lines and adding 17px to every row — ~2,300px of
   extra scrolling across the ingredient list. Stacking restores the text block to exactly
   its pre-button 195px for +2px of row height, while keeping full 44px tap targets (unlike
   .lib-recipe-actions below, which shrinks to 34px to fit four verbs). */
.lib-food-actions{display:flex;flex-direction:column;gap:6px;flex:0 0 44px;align-self:center;}
.lib-recipe-actions{display:grid;grid-template-columns:repeat(2,34px);grid-auto-rows:34px;gap:6px;flex:0 0 74px;align-self:center;}
.lib-recipe-actions .lib-edit,.lib-recipe-actions .lib-del{width:34px;height:34px;min-width:34px;flex:0 0 34px;border-radius:10px;font-size:14px;padding:0;}
.lib-recipe-actions .lib-del{font-size:13px;}
/* RECIPE-MARKET: icon buttons (inline Lucide SVG) for the recipe-row actions. Centre the glyph
   and size it so nothing overflows the 34px square the way the old "Add"/"Remove" text did. */
.lib-recipe-actions .lib-edit,.lib-recipe-actions .lib-del,.lib-recipe-actions .lib-add-book{display:flex;align-items:center;justify-content:center;}
.lib-recipe-actions .licon{width:18px;height:18px;display:block;}
/* Market view: a single Add / Re-add icon button, right-aligned (no 2-col reserve). */
.lib-recipe-actions.market{display:flex;justify-content:flex-end;align-items:center;flex:0 0 40px;}
.lib-add-book{width:34px;height:34px;min-width:34px;flex:0 0 34px;border:0;border-radius:10px;background:var(--sage-deep,#6b7f5e);color:#fff;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;}
.lib-add-book:active{transform:scale(.94);}
/* Market view: a recipe already in the book shows a quiet, non-interactive check — no remove. */
.lib-inbook-check{width:34px;height:34px;display:flex;align-items:center;justify-content:center;color:var(--sage-deep,#6b7f5e);opacity:.55;}
.lib-inbook-check .licon{width:18px;height:18px;}
.field textarea.inp{display:block;}
.stackbar{height:8px;border-radius:999px;background:#eef0ec;overflow:hidden;display:flex;}
.stackbar i{display:block;height:100%;}
.macro-cal-list{display:grid;gap:8px;}
.macro-cal-row{display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:10px;min-height:34px;padding:8px 0;border-bottom:1px solid rgba(223,209,187,.72);}
.macro-cal-row:last-child{border-bottom:0;}
.macro-cal-row span{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:var(--ink-soft);min-width:0;}
.macro-cal-row b{font-size:13px;color:var(--ink);white-space:nowrap;}
.macro-cal-row em{font-style:normal;font-size:12px;color:var(--muted);white-space:nowrap;text-align:right;}
.macro-dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex:0 0 9px;}
.cap-note{font-size:10px;color:var(--muted);margin-top:4px;min-height:13px;}
.filter-compact{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;}
.filter-toggle{border:1px solid rgba(var(--sage-rgb),.38);background:var(--sage-tint);color:var(--sage-deep);border-radius:999px;min-height:40px;padding:0 14px;font:inherit;font-size:12px;font-weight:800;cursor:pointer;}
.filter-toggle:active{transform:scale(.96);}
.filter-summary{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:8px;}
.filter-clear{border:0;background:transparent;color:var(--terra);font:inherit;font-size:12px;font-weight:800;min-height:32px;padding:0 4px;cursor:pointer;}
.filter-clear.full{display:block;margin-top:10px;padding:0 2px;}
.filter-panel{border-top:1px solid rgba(223,209,187,.78);margin-top:8px;padding-top:10px;}
.filter-label{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:8px 0 6px;}

/* Recipe Library refinement workspace */
.recipe-search{display:flex;align-items:center;gap:9px;margin-top:12px;padding:0 13px;min-height:44px;border:1px solid var(--line);border-radius:12px;background:rgba(255,250,240,.95);color:var(--muted);}
.recipe-search svg{width:18px;height:18px;flex:0 0 18px;}
.recipe-search input{width:100%;min-width:0;border:0;outline:0;background:transparent;color:var(--ink);font:inherit;font-size:15px;padding:10px 0;}
.recipe-search input::-webkit-search-decoration,.recipe-search input::-webkit-search-cancel-button{-webkit-appearance:none;}
.recipe-filter-toolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;position:relative;}
#libRecipeFilterBar{position:relative;}
.recipe-filter-toggle{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 12px;border:1px solid rgba(var(--sage-rgb),.38);border-radius:12px;background:var(--sage-tint);color:var(--sage-deep);font:inherit;font-size:12px;font-weight:800;cursor:pointer;}
.recipe-filter-toggle svg{width:17px;height:17px;}
.recipe-filter-toggle:active,.recipe-filter-chip:active,.recipe-filter-summary-chip:active{transform:scale(.97);}
.recipe-filter-count{font-size:12px;font-weight:700;color:var(--muted);white-space:nowrap;}
.recipe-filter-summary{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:7px;}
.recipe-filter-summary-chip{display:inline-flex;align-items:center;gap:4px;min-height:32px;border:1px solid rgba(199,154,72,.28);border-radius:999px;padding:0 9px;background:#f6edd6;color:#8d6812;font:inherit;font-size:11px;font-weight:800;cursor:pointer;}
.recipe-filter-summary-chip span{font-size:15px;line-height:1;}
.recipe-filter-clear{min-height:32px;border:0;background:transparent;padding:0 4px;color:var(--terra);font:inherit;font-size:12px;font-weight:800;cursor:pointer;}
.recipe-filter-panel{position:absolute;z-index:15;left:0;right:0;top:calc(100% + 6px);max-width:620px;max-height:calc(100dvh - 330px);overflow-y:auto;padding:12px 14px 14px;border:1px solid rgba(176,146,105,.38);border-radius:12px;background:var(--card);box-shadow:var(--shadow);}
.recipe-filter-group + .recipe-filter-group{margin-top:12px;padding-top:10px;border-top:1px solid rgba(223,209,187,.7);}
.recipe-filter-group .filter-label{margin-top:0;}
.recipe-filter-subhead{font-size:11px;color:var(--ink-soft);font-weight:700;margin:8px 0 5px;}
.recipe-filter-options{display:flex;gap:6px;flex-wrap:wrap;}
.recipe-filter-chip{min-height:44px;border:1px solid rgba(176,146,105,.35);border-radius:10px;padding:0 11px;background:rgba(255,250,240,.78);color:var(--ink-soft);font:inherit;font-size:12px;font-weight:700;cursor:pointer;}
.recipe-filter-chip.on{border-color:var(--sage);background:var(--sage);color:#fff;}
.recipe-filter-sheet .sheet-body{padding-bottom:34px;}
.recipe-filter-sheet-count{margin-top:5px;font-size:12px;font-weight:700;color:var(--muted);}
.recipe-filter-sheet-controls{margin-top:11px;}
.library-action-row{display:flex;gap:8px;margin-top:10px;}
.library-action{flex:1;min-width:0;min-height:38px;padding:0 10px;border:1px solid rgba(var(--sage-rgb),.38);border-radius:10px;background:rgba(255,250,240,.95);color:var(--sage-deep);font:inherit;font-size:12px;font-weight:800;cursor:pointer;white-space:nowrap;}
.library-action:active{transform:scale(.97);}
.ingredient-filter-toolbar{margin-top:10px;}
.ingredient-filter-panel{position:relative;left:auto;right:auto;top:auto;max-width:none;max-height:none;margin-top:6px;}
.active-filter-label{cursor:default;}
@media (max-width:640px){
  .recipe-filter-panel{display:none;}
  .ingredient-filter-panel{display:block;}
}

/* macro split editor */
.pill.chip-preset{border:0;-webkit-appearance:none;appearance:none;font:inherit;cursor:pointer;}
.pill.chip-preset:active{transform:scale(.96);}
.pill.chip-preset.chipsel{background:var(--sage);color:#fff;}
/* Swap sheet: specific-protein sub-row nested under the "Protein" chip (progressive
   disclosure) — a light indent + top rule so it reads as children of Protein, not a stray row.
   Deliberately does NOT restyle the shared .chiprow (pills already wrap on their own). */
.swap-protein-subrow{margin-top:8px;padding:8px 0 0 10px;border-top:1px solid rgba(127,147,100,.18);}
.swap-protein-note{margin:8px 0 0 2px;}
.split-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--line);}
.split-row:last-of-type{border-bottom:0;}
.split-dot{width:9px;height:9px;border-radius:50%;display:inline-block;margin-right:8px;flex:0 0 9px;}
.split-label{font-size:13.5px;font-weight:600;display:flex;align-items:center;}

/* week grid */
.week-toolbar{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;margin-top:10px;}
.week-tool{border:1.5px solid var(--sage);border-radius:11px;min-height:44px;padding:0 7px;font:inherit;font-size:11.5px;font-weight:800;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.week-tool:has(.week-tool-icon){display:flex;align-items:center;justify-content:center;gap:4px;}
.week-tool-icon{font-size:14px;line-height:1;flex:0 0 auto;}
.week-standalone-link{border:0;background:transparent;color:var(--sage-deep);font:inherit;font-weight:800;font-size:inherit;padding:0 0 0 4px;text-decoration:underline;cursor:pointer;}
.week-tool.primary{background:var(--sage);color:#fff;box-shadow:var(--shadow-soft);}
.week-tool.ghost{background:rgba(255,250,240,.78);color:var(--sage-deep);box-shadow:none;}
.week-tool:active{transform:scale(.98);}
.week-quality{margin-top:10px;border:1px solid rgba(127,147,100,.18);border-radius:14px;background:rgba(237,241,223,.7);overflow:hidden;}
.week-quality-toggle{width:100%;min-height:44px;border:0;background:transparent;padding:10px 13px;display:flex;align-items:center;justify-content:space-between;gap:10px;font:inherit;color:var(--sage-deep);cursor:pointer;text-align:left;}
.week-quality-toggle b{display:block;font-size:12px;color:var(--sage-deep);}
.week-quality-toggle small{display:block;margin-top:2px;font-size:12.5px;line-height:1.35;color:var(--ink-soft);}
.week-quality-toggle .chev{display:inline-block;font-size:12px;color:var(--muted);transition:transform .2s ease;}
.week-quality.open .week-quality-toggle .chev{transform:rotate(180deg);}
.week-quality-signals{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;padding:0 13px 11px;}
.week-quality-signal{min-width:0;padding:8px 8px 7px;border-radius:9px;background:rgba(255,255,255,.62);border:1px solid rgba(127,147,100,.12);}
.week-quality-signal b,.week-quality-signal em{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.week-quality-signal b{font-size:10px;color:var(--ink-soft);}
.week-quality-signal em{margin-top:2px;font-size:11px;font-style:normal;font-weight:800;color:var(--sage-deep);}
.signal-variety em{color:#a96c35;}.signal-protein em{color:var(--sage-deep);}.signal-fiber em{color:#647e61;}
.week-quality-panel{padding:0 13px 13px;}
.week-quality-panel[hidden]{display:none;}
.week{display:flex;flex-direction:column;gap:10px;}
.day{background:rgba(255,250,240,.92);border:1px solid rgba(176,146,105,.38);border-radius:var(--radius);padding:13px 15px;cursor:pointer;}
.day .dh{display:flex;justify-content:space-between;align-items:center;}
.day .dn{font-weight:700;font-size:14px;}
.day .dk{font-size:12px;color:var(--muted);display:flex;align-items:center;gap:2px;}
.day .dmeals{font-size:12.5px;color:var(--ink-soft);margin-top:6px;line-height:1.45;}
.day.today{border:1.5px solid var(--sage);background:linear-gradient(180deg,#fffaf0,#f1eddc);}
.day .chev{display:inline-block;font-size:11px;margin-left:2px;transition:transform .2s ease;color:var(--muted);}
.day.expanded .chev{transform:rotate(180deg);}
.day.expanded .dmeals{display:none;}
.day-meals{display:none;flex-direction:column;gap:4px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line);}
.day.expanded .day-meals{display:flex;}
.day-meal-row{display:flex;align-items:center;gap:8px;padding:9px 4px;border-radius:12px;cursor:pointer;min-height:44px;}
.day-meal-row:active{background:#f4f2ea;}
.day-meal-row .dm-e{font-size:20px;width:28px;text-align:center;flex:0 0 28px;}
.day-meal-row .dm-t{flex:1 1 auto;font-size:13.5px;min-width:0;line-height:1.35;}
.day-meal-row .dm-t small{display:block;color:var(--muted);font-size:11px;margin-top:1px;}
/* RECIPE-MARKET: tappable "add from the Market" hint on a starved slot — reads like the muted
   sub-label above, but underlined + accent-coloured to signal it's an action. */
.day-meal-row .dm-t .dm-market-hint{display:block;margin-top:1px;padding:0;border:0;background:none;color:var(--accent,#6b7f5e);font-size:11px;text-align:left;text-decoration:underline;cursor:pointer;min-height:0;}
.day-meal-row .dm-k{font-size:12px;font-weight:700;color:var(--ink-soft);flex:0 0 auto;}
/* Two-week horizon: inline per-meal swap icon on the Week screen's day rows (works on
   whichever week — current or next — is displayed; render.js:openWeekSwap). 44x44
   tap target (ground rule: iPhone Safari targets >=44px); event.stopPropagation() on the
   button's onclick keeps the row's own openRecipe() tap separate. */
/* Keep planner controls discoverable without making every recipe title a narrow column.
   A compact two-column action cluster uses the same controls, but takes a predictable
   60px instead of a full horizontal run of 3–4 buttons. */
.day-meal-row .dm-actions{display:grid;grid-template-columns:repeat(2,28px);gap:4px;flex:0 0 60px;align-items:center;}
.day-meal-row .dm-swap,.day-meal-row .dm-pin,.day-meal-row .dm-rule,.day-meal-row .dm-log,.day-meal-row .dm-extras{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border:0;font-size:14px;line-height:1;cursor:pointer;border-radius:9px;color:var(--ink-soft);}
.day-meal-row .dm-pin.on{background:rgba(199,154,72,.18);color:#9b6b1f;}
/* B5: catch-up log button (◯/✓/∅) replacing pin/routine on past current-week rows —
   `.on` marks confirmed OR skipped (anything non-null) so the row visually reads as
   "handled" at a glance, same treatment as the pin's `.on` state. */
.day-meal-row .dm-log{font-size:16px;}
.day-meal-row .dm-log.on{background:rgba(var(--sage-rgb),.16);color:var(--sage-deep);}
/* B3: sides/extras button — same 34x34 compact convention as pin/routine/swap/log. */
.day-meal-row .dm-extras{font-size:16px;}
.day-meal-row .dm-swap:active,.day-meal-row .dm-pin:active,.day-meal-row .dm-rule:active,.day-meal-row .dm-log:active,.day-meal-row .dm-extras:active{background:#e9e4d7;}

/* recipe detail */
.hero{height:170px;border-radius:18px;margin-top:8px;display:grid;place-items:center;font-size:74px;background:linear-gradient(135deg,#f6efd9,#edf1df);border:1px solid rgba(176,146,105,.38);}
.why{background:rgba(var(--sage-rgb),.12);border-radius:14px;padding:14px;font-size:13px;color:var(--sage-deep);line-height:1.5;border:1px solid rgba(var(--sage-rgb),.18);}
.why b{color:var(--sage-deep);}
ul.ing{list-style:none;padding:0;margin:8px 0 0;}
ul.ing li{display:flex;justify-content:space-between;padding:11px 2px;border-bottom:1px solid var(--line);font-size:14px;}
ul.ing li:last-child{border-bottom:0;}
ol.steps{margin:6px 0 0;padding-left:20px;}
ol.steps li{font-size:14px;line-height:1.55;margin-bottom:10px;color:var(--ink-soft);}

/* task D1: recipe-detail optionGroups chips — reuse .pill.ghost.chip-preset/.chipsel's
   look (renderRecipeOptionsChips, render.js) but sized to the 44px tap-target minimum
   (ground rule 4) since these sit in the main scroll flow, unlike the denser macro-split
   preset row .pill.chip-preset otherwise ships at. */
.recipe-opt-chip{min-height:44px;padding:0 14px;}

/* servings / portion scaling */
.serve-row{display:flex;gap:10px;margin-top:10px;}
.serve-card{flex:1;background:#fff;border:1px solid var(--line);border-radius:16px;padding:11px 10px;text-align:center;transition:.2s;}
.serve-card.me{border-color:var(--sage);background:var(--sage-tint);}
.serve-card .sv-name{font-size:12px;font-weight:700;color:var(--ink-soft);}
.sv-stepper{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:8px;}
.sv-stepper button{width:30px;height:30px;border-radius:50%;border:1px solid var(--line);background:#fff;font-size:16px;font-weight:700;color:var(--sage-deep);cursor:pointer;line-height:1;}
.sv-stepper button:active{transform:scale(.9);}
.sv-stepper .sv-val{font-size:14px;font-weight:700;min-width:34px;}
.sv-stepper .sv-unit{font-size:12px;font-weight:600;color:var(--muted);margin:0 -4px;}
/* Meal (recipe-of-recipes) "Made of" rows — per-component portion steppers so a logged meal can be
   tweaked (remove a sub-recipe, change its portion). render-recipe.js:updateMealDetail. */
.madeof-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 0;border-bottom:1px solid var(--line);}
.madeof-row:last-child{border-bottom:0;}
.madeof-name{cursor:pointer;font-weight:600;flex:1;min-width:0;}
.madeof-right{display:flex;align-items:center;gap:12px;flex-shrink:0;}
.madeof-step{display:flex;align-items:center;gap:8px;}
.madeof-btn{width:28px;height:28px;border-radius:50%;border:1px solid var(--line);background:#fff;font-size:16px;font-weight:700;color:var(--sage-deep);cursor:pointer;line-height:1;padding:0;}
.madeof-btn:active{transform:scale(.9);}
.madeof-portion{font-size:13px;font-weight:700;min-width:38px;text-align:center;}
.madeof-kcal{font-size:13px;color:var(--muted);min-width:56px;text-align:right;}
.madeof-removed{opacity:.5;}
.madeof-removed .madeof-name{text-decoration:line-through;}
/* Keyboard entry (owner request, 2026-09-03): the "made of" value is now a typeable input
   (component portion, extra portion/grams) — same look-and-feel treatment as the
   `.sv-stepper input.sv-val` convention just above (centered, bold, no chrome), font-size
   forced to >=16px so iPhone Safari doesn't auto-zoom on focus. The unit (× or g) is a
   separate static label so only the number itself is editable. */
.madeof-step input.madeof-portion-input{font-size:16px;font-weight:700;width:2.6em;border:0;background:transparent;color:inherit;text-align:center;padding:2px 0;box-sizing:border-box;-webkit-appearance:none;appearance:none;}
.madeof-step input.madeof-portion-input:focus{outline:2px solid var(--sage);outline-offset:1px;border-radius:6px;background:#fff;}
.madeof-unit{font-size:12px;font-weight:600;color:var(--muted);}
/* FIX 2 (feedback): the stepper's value is now directly typeable (owner: "permetti di
   scrivere direttamente l'importo"). Same look as the plain .sv-val span it replaces
   (centered, bold, no chrome) except font-size is forced to >=16px — iPhone Safari
   auto-zooms the page on focusing any input under 16px, which would be jarring inside a
   bottom sheet. `input.sv-val` (type + class) beats the plain `.sv-stepper .sv-val`
   two-class rule above on specificity, so this reliably wins regardless of source order. */
.sv-stepper input.sv-val{font-size:16px;width:4.4em;border:0;background:transparent;color:inherit;text-align:center;padding:2px 0;box-sizing:border-box;-webkit-appearance:none;appearance:none;}
.sv-stepper input.sv-val:focus{outline:2px solid var(--sage);outline-offset:1px;border-radius:6px;background:#fff;}
.sv-unit{font-size:13px;font-weight:600;color:var(--ink-soft);margin-left:-6px;}

/* log screen */
.quick{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;margin-top:6px;}
.quick button{border:1px solid var(--line);background:#fff;border-radius:16px;padding:12px 4px;font:inherit;font-size:11px;font-weight:600;color:var(--ink-soft);cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:5px;min-height:44px;}
.quick button .qi{font-size:22px;}
/* log picker: selected meal-slot button (buildLogPickerSheet, render-today.js) — same
   sage "selected" language as .seg button.on/.pill.chipsel elsewhere in the app. */
.quick button.on{border-color:var(--sage);background:var(--sage-tint);color:var(--sage-deep);}
/* Inline unit picker on the add-meal food extras (item / tbsp / tsp / cup / g) — small chips under
   the row's macros, plus the live "= N g" so grams (the anchor) stay visible. */
/* An extra row in an "In this meal" list (a food extra/recipe extra in the add-meal sheet, or a
   meal-builder row): name + compact ✕ on top, amount/portion stepper (+ unit picker, where one
   applies) on a full-width line below (render-today.js) — stops the controls crushing the name
   at narrow widths. Shared by openAddMealSheetForContext's extras and mealBuilderRowHtml. */
.altrow.meal-extra-row{align-items:flex-start;flex-wrap:wrap;}
.meal-extra-row .an-row{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.meal-extra-row .an-row .an{min-width:0;overflow-wrap:anywhere;}
.meal-extra-controls{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin-top:9px;}
.meal-extra-controls .sv-stepper{margin:0;}
.meal-extra-remove{flex:0 0 auto;padding:4px 8px;line-height:1;}
.meal-extra-units{display:flex;flex-wrap:wrap;gap:5px;margin-top:0;align-items:center;}
.meal-extra-units button{border:1px solid var(--line);background:#fff;border-radius:10px;padding:3px 9px;font:inherit;font-size:10.5px;font-weight:600;color:var(--ink-soft);cursor:pointer;min-height:0;}
.meal-extra-units button.on{border-color:var(--sage);background:var(--sage-tint);color:var(--sage-deep);}
.meal-extra-units .meal-extra-grams{font-size:10.5px;color:var(--muted);margin-left:2px;}
.logitem{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--line);}
#todaySoFar .logitem:last-child,#todayRecordsList .logitem:last-child{border-bottom:0;}
.logitem .li-i{width:42px;height:42px;border-radius:12px;background:var(--terra-tint);display:grid;place-items:center;font-size:20px;flex:0 0 42px;}
.logitem .li-t{flex:1;font-size:14px;}
.logitem .li-t small{display:block;color:var(--muted);font-size:12px;margin-top:1px;}
.logitem .li-k{font-weight:700;font-size:13px;}
/* FIX 2c (feedback): per-row remove (✕) in "Today so far" — 44px tap target, quiet
   ghost look (echoes .lib-del but without the warning tint until pressed). */
.li-x{width:44px;height:44px;min-width:44px;flex:0 0 44px;border:0;border-radius:12px;background:#eef0ec;color:var(--ink-soft);font-size:14px;font-weight:700;cursor:pointer;}
.li-x:active{transform:scale(.94);background:#f6e6dc;color:#b25e35;}

/* barcode scanner */
.scanner-box{position:relative;aspect-ratio:16/11;border-radius:16px;overflow:hidden;background:#2f281f;border:1px solid rgba(176,146,105,.38);}
.scanner-video{width:100%;height:100%;object-fit:cover;display:block;}
.scanner-frame{position:absolute;left:4%;right:4%;top:34%;height:32%;border:2px solid rgba(255,250,240,.94);border-radius:12px;box-shadow:0 0 0 999px rgba(0,0,0,.18);}
.scanned-product-card{display:flex;gap:12px;align-items:center;padding:12px;margin-top:12px;}
.scanned-product-img{width:64px;height:64px;object-fit:cover;border-radius:14px;border:1px solid var(--line);background:#fff;flex:0 0 64px;}

/* insights */
.stat{display:grid;grid-template-columns:repeat(2,1fr);gap:11px;}
.stat .s{background:#fff;border:1px solid var(--line);border-radius:18px;padding:14px;}
.stat .s .sv{font-size:24px;font-weight:700;letter-spacing:-.5px;}
.stat .s .sl{font-size:12px;color:var(--muted);margin-top:2px;}
.stat .s .sd{font-size:11.5px;font-weight:600;margin-top:6px;}
.up{color:var(--sage-deep);} .dn2{color:#b25e35;} .sd.calm{color:var(--muted);}
.spark{display:flex;align-items:flex-end;gap:6px;height:80px;margin-top:6px;}
.spark .col{flex:1;background:var(--sage-tint);border-radius:6px 6px 0 0;position:relative;}
.spark .col b{position:absolute;bottom:-20px;left:0;right:0;text-align:center;font-size:10px;color:var(--muted);font-weight:600;}
.spark .col.hi{background:var(--sage);}
/* task D1: an un-logged day in the Insights 7-day bar chart — visually distinct (pale,
   flat) from a real short bar so it doesn't read as "a bad day". */
.spark .col.empty{background:#eef0ec;}
/* task C1: per-day nutrient-band bars — 'over' (too high, e.g. free sugars past the cap)
   and 'under' (too low, e.g. fiber short of the floor) reuse the existing terra palette
   instead of introducing new colors; 'hi' (sage, above) still means in-band. */
.spark .col.over{background:var(--terra);}
.spark .col.under{background:var(--terra-tint);}
/* task C1: 5 rows share one card, so each row's bar chart is shorter than the single
   #insightsBarsCard kcal chart; margin-bottom reserves room for the absolutely-positioned
   day-letter labels (.spark .col b, bottom:-20px) so rows never overlap. */
.spark.compact{height:34px;margin-top:4px;margin-bottom:22px;}

/* weekly adherence band */
.band{display:flex;gap:8px;margin-top:14px;}
.band .dwrap{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;}
.band .dot{width:100%;height:16px;border-radius:999px;background:#eef0ec;}
.band .dot.filled{background:var(--sage);}
.band .dot.soft{background:var(--sage-tint);}
.band .dl{font-size:10px;color:var(--muted);font-weight:600;}

/* AI vs computed micro-labels */
.badge-mini{display:inline-flex;align-items:center;font-size:10px;font-weight:700;padding:3px 8px;border-radius:999px;background:rgba(var(--sage-rgb),.14);color:var(--sage-deep);letter-spacing:.2px;margin-left:6px;vertical-align:middle;}
.chip-computed{display:inline-flex;align-items:center;font-size:10px;font-weight:700;padding:3px 8px;border-radius:999px;background:var(--sage-tint);color:var(--sage-deep);letter-spacing:.2px;margin-left:6px;vertical-align:middle;}

/* T3: small leading line-SVG icon on Profile/Insights <h2> section headers — same stroke
   idiom as the tabbar (viewBox 0 0 24 24, stroke=currentColor, stroke-width 2), just
   recolored to the sage accent and sized down to sit inline with the script h2 font. */
.h2-ic{width:18px;height:18px;stroke:var(--sage-deep);vertical-align:-3px;margin-right:7px;}

.profile-hub-switcher,.profile-editor-switcher{width:100%;margin-top:14px;}
.profile-hub{display:flex;flex-direction:column;gap:10px;margin-top:16px;}
.settings-row{
  width:100%;min-height:78px;border:1px solid rgba(176,146,105,.38);
  background:rgba(255,250,240,.92);border-radius:14px;box-shadow:var(--shadow-soft);
  padding:13px 14px;display:grid;grid-template-columns:36px minmax(0,1fr) 18px;align-items:center;gap:12px;
  color:var(--ink);font:inherit;text-align:left;cursor:pointer;
}
.settings-row:active{transform:scale(.99);}
.settings-ic{
  width:36px;height:36px;border-radius:12px;background:var(--sage-tint);color:var(--sage-deep);
  display:grid;place-items:center;flex:0 0 36px;
}
.settings-ic svg{width:20px;height:20px;}
.settings-copy{min-width:0;display:flex;flex-direction:column;gap:3px;}
.settings-copy b{font-size:15px;font-weight:700;color:var(--ink);}
.settings-copy small{font-size:12.5px;line-height:1.35;color:var(--muted);white-space:normal;}
.settings-chev{font-size:26px;line-height:1;color:var(--muted);}

/* Claim provenance is deliberately visible: guidance, estimates and Mesa settings are
   different kinds of information and should never look interchangeable. */
.why-link{border:0;background:transparent;color:var(--sage-deep);font:inherit;font-size:12px;font-weight:700;padding:4px 0;cursor:pointer;text-decoration:underline;text-underline-offset:2px;}
.how-legend{display:flex;gap:7px;flex-wrap:wrap;margin:14px 0;}
.claim-badge{display:inline-flex;align-items:center;border-radius:999px;padding:4px 8px;font-size:10px;line-height:1;font-weight:800;letter-spacing:.02em;}
.claim-badge.guideline{background:#e7f0df;color:#49653d;}
.claim-badge.estimate{background:#f6ead5;color:#7b5a2b;}
.claim-badge.rule{background:#f4e3da;color:#8a4f34;}
.how-card{background:rgba(255,250,240,.92);border:1px solid rgba(176,146,105,.38);border-radius:14px;box-shadow:var(--shadow-soft);padding:15px 16px;margin-top:12px;scroll-margin-top:16px;}
.how-card h2{margin:8px 0 6px;font-size:23px;}
.how-card p,.how-card li{font-size:13px;line-height:1.52;color:var(--ink-soft);}
.how-card ul{margin:8px 0;padding-left:20px;}

/* profile / onboarding */
.opt{display:flex;align-items:center;gap:12px;padding:13px 14px;border:1px solid rgba(176,146,105,.38);background:rgba(255,250,240,.9);border-radius:14px;margin-top:9px;cursor:pointer;transition:.15s;min-height:44px;}
.opt .ck{width:22px;height:22px;border-radius:7px;border:2px solid var(--line);flex:0 0 22px;display:grid;place-items:center;color:#fff;font-size:13px;}
.opt.sel{border-color:var(--sage);background:var(--sage-tint);}
.opt.sel .ck{background:var(--sage);border-color:var(--sage);}
.opt .ot{font-size:14px;font-weight:600;}
.opt .od{font-size:12px;color:var(--muted);margin-top:1px;}
.field{margin-top:14px;}
.field label{font-size:12.5px;font-weight:600;color:var(--ink-soft);}
.field .inp{margin-top:6px;background:rgba(255,250,240,.95);border:1px solid var(--line);border-radius:12px;padding:12px 14px;font-size:14px;color:var(--ink);display:flex;justify-content:space-between;align-items:center;}
.cta{display:block;width:100%;border:0;background:var(--sage);color:#fff;font:inherit;font-weight:700;font-size:15px;padding:15px;border-radius:14px;margin-top:18px;cursor:pointer;box-shadow:var(--shadow);min-height:44px;}
.cta:active{transform:scale(.99);}
/* Editor save/cancel action bar — a slim frozen bar sitting flush ON TOP of the tab bar so
   Save/Cancel stay reachable without scrolling to the end of a long recipe/ingredient form
   (owner: save-only-at-bottom is confusing; keep it frozen but at the bottom, band a touch
   smaller). Fixed at bottom:88px (= the tabbar height) hugs the tabbar's top edge. Sticky can't
   reach the tabbar here — the `.screen` scroller's 108px bottom padding always sits below a
   sticky bar at end-of-scroll, leaving a gap. No ancestor carries a transform, so position:fixed
   resolves against the viewport correctly (once the screen's open transition settles). The
   in-flow spacer after it gives the last field room to scroll clear of the fixed bar. */
.editor-actionbar{position:absolute;left:0;right:0;bottom:88px;z-index:29;display:flex;gap:8px;align-items:stretch;
  padding:8px 18px;background:var(--bg);border-top:1px solid var(--line);box-shadow:0 -6px 16px rgba(60,50,30,.10);}
.editor-actionbar .cta{margin-top:0;box-shadow:none;padding:11px 15px;min-height:0;}
.editor-actionbar .cta.editor-save{flex:1 1 auto;}
.editor-actionbar .cta.ghostbtn{flex:0 0 auto;width:auto;padding-left:20px;padding-right:20px;}
.editor-actionbar-spacer{height:76px;}
/* The bar is position:fixed, so hide it the instant its screen goes inactive (before the 0.28s
   opacity fade would) — otherwise a fixed element could flash over another screen mid-transition. */
/* Hidden whenever the recipe editor isn't open (JS empties it on exit) — it's a global element now,
   not scoped to a screen, so visibility is driven by whether it has content. */
.editor-actionbar:empty{display:none;}
.ghostbtn{background:rgba(255,250,240,.72);color:var(--sage-deep);border:1.5px solid var(--sage);box-shadow:none;}

.banner{background:rgba(240,232,211,.92);color:var(--ink);border-radius:14px;padding:16px;margin-top:12px;box-shadow:var(--shadow-soft);border:1px solid rgba(176,146,105,.42);}
.banner .bt{font-family:var(--font-script);font-weight:500;font-size:24px;line-height:1.1;color:var(--sage-deep);}
.banner .bd{font-size:12.5px;color:var(--ink-soft);margin-top:5px;line-height:1.45;}
.banner .ai{font-size:10.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);font-weight:700;display:flex;align-items:center;}

/* bottom nav */
.tabbar{
  position:absolute;left:0;right:0;bottom:0;height:88px;
  background:rgba(244,237,223,.94);backdrop-filter:saturate(160%) blur(18px);
  border-top:1px solid rgba(176,146,105,.45);
  display:flex;align-items:flex-start;justify-content:space-around;padding:10px 6px 0;z-index:30;
}
.tab{border:0;background:none;font:inherit;display:flex;flex-direction:column;align-items:center;gap:3px;color:var(--muted);cursor:pointer;width:60px;}
.tab svg{width:24px;height:24px;}
.tab .tl{font-size:10px;font-weight:600;}
.tab.on{color:var(--sage-deep);}
.tab.add{margin-top:-14px;}
.tab.add .fab{width:54px;height:54px;border-radius:50%;background:linear-gradient(135deg,var(--terra),#9f5635);color:#fff;display:grid;place-items:center;box-shadow:0 8px 20px rgba(190,108,69,.34);}
.tab.add .fab svg{width:28px;height:28px;}

.backbtn{display:inline-flex;align-items:center;gap:5px;border:0;background:none;font:inherit;font-size:14px;font-weight:600;color:var(--sage-deep);cursor:pointer;margin-top:4px;padding:6px 0;min-height:44px;}

/* toast */
.toast{position:absolute;left:50%;bottom:104px;transform:translateX(-50%) translateY(20px);background:var(--ink);color:#fff;font-size:13px;font-weight:600;padding:11px 18px;border-radius:999px;opacity:0;transition:.3s;z-index:80;box-shadow:var(--shadow);pointer-events:none;max-width:82%;text-align:center;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

/* A brief, tactile acknowledgement for an explicit food log. The little pressed-paper
   composition is deliberately made from gradients, SVG and pseudo-elements: it stays
   sharp on every screen without loading an image or asking the main thread to draw. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
.log-reward-layer{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:81;}
.log-reward{
  position:absolute;left:var(--reward-x);top:var(--reward-y);width:0;height:0;
  color:var(--sage-deep);contain:layout style;
  animation:log-reward-life 1.55s linear both;
}
.log-reward:before{
  content:"";position:absolute;left:-66px;top:-66px;width:132px;height:132px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,250,224,.92) 0 15%,rgba(218,227,186,.46) 36%,rgba(199,154,72,.13) 57%,transparent 70%);
  opacity:0;transform:scale(.28);animation:log-reward-bloom .72s cubic-bezier(.16,.76,.22,1) both;
}
.log-reward:after{
  content:"";position:absolute;left:-2px;top:-2px;width:4px;height:4px;border-radius:50%;background:#fff9cf;
  box-shadow:-43px -33px 0 -1px rgba(255,249,207,.9),45px -25px 0 -1px rgba(199,154,72,.78),35px 37px 0 -1px rgba(255,249,207,.84),-39px 31px 0 -1px rgba(199,154,72,.7);
  opacity:0;transform:scale(.2) rotate(-12deg);animation:log-reward-glints .78s ease-out .12s both;
}
.log-reward-stamp{
  position:absolute;left:-29px;top:-29px;width:58px;height:58px;display:grid;place-items:center;
  border:1px solid rgba(86,107,67,.5);border-radius:47% 53% 45% 55% / 55% 45% 54% 46%;
  background:
    radial-gradient(circle at 31% 24%,rgba(255,255,255,.94) 0 6%,transparent 24%),
    linear-gradient(145deg,#fffdf4 0%,#eef2dd 46%,#d8e2bd 100%);
  box-shadow:0 12px 25px rgba(73,54,32,.2),0 3px 7px rgba(73,54,32,.16),inset 0 0 0 4px rgba(255,255,255,.5);
  opacity:0;transform:translateY(-12px) scale(1.32) rotate(-12deg);
  animation:log-reward-stamp .46s cubic-bezier(.18,.82,.22,1.22) forwards;will-change:transform,opacity;
}
.log-reward-stamp:before{
  content:"";position:absolute;inset:6px;border:1px dashed rgba(86,107,67,.34);
  border-radius:51% 49% 55% 45% / 46% 57% 43% 54%;
}
.log-reward-stamp svg{position:relative;width:34px;height:34px;overflow:visible;filter:drop-shadow(0 1px 0 rgba(255,255,255,.92));}
.log-reward-stamp .seal-branch{fill:none;stroke:currentColor;stroke-width:2.45;stroke-linecap:round;stroke-linejoin:round;}
.log-reward-stamp .seal-leaf{fill:currentColor;stroke:none;opacity:.78;}
.log-reward-leaf{
  position:absolute;left:-9px;top:-14px;width:var(--leaf-width,18px);height:var(--leaf-height,27px);
  overflow:visible;opacity:0;filter:drop-shadow(0 2px 2px rgba(73,54,32,.12));
  transform:translate(0,0) rotate(var(--leaf-rotate)) scale(.12);
  animation:log-reward-leaf .98s cubic-bezier(.16,.76,.22,1) var(--leaf-delay) both;
  will-change:transform,opacity;
}
.log-reward-leaf .leaf-body{fill:var(--leaf-color,var(--sage));stroke:rgba(var(--sage-rgb),.45);stroke-width:.62;}
.log-reward-leaf .leaf-vein{fill:none;stroke:rgba(69,88,52,.54);stroke-width:.66;stroke-linecap:round;}
.log-reward-message{
  position:absolute;left:var(--reward-message-x,0);top:43px;width:max-content;max-width:min(232px,calc(100vw - 32px));
  padding:9px 13px 9px 29px;border:1px solid rgba(127,147,100,.3);border-radius:13px;
  background:linear-gradient(135deg,rgba(255,253,247,.98),rgba(247,241,224,.98));
  box-shadow:0 9px 24px rgba(73,54,32,.15),inset 0 1px 0 rgba(255,255,255,.9);
  color:var(--ink);font-size:12px;font-weight:700;line-height:1.28;text-align:left;
  opacity:0;transform:translate(-50%,9px) scale(.96);
  animation:log-reward-message .3s cubic-bezier(.2,.8,.25,1) .39s forwards;
  will-change:transform,opacity;
}
.log-reward-message:before{
  content:"";position:absolute;left:11px;top:50%;width:9px;height:9px;border-radius:48% 52% 45% 55%;
  background:var(--sage);box-shadow:inset 0 0 0 2px rgba(255,255,255,.45);
  transform:translateY(-50%) rotate(-18deg);
}
.log-reward--complete{
  inset:0;width:auto;height:auto;display:grid;place-items:center;--reward-x:auto;--reward-y:auto;
  background:radial-gradient(circle at 50% 48%,rgba(255,250,230,.72),rgba(237,241,223,.28) 29%,transparent 62%);
  animation:log-reward-complete-life 2.2s ease both;
}
.log-reward--complete:before{
  left:50%;top:50%;width:330px;height:330px;
  background:radial-gradient(circle,rgba(255,251,226,.88),rgba(218,227,186,.38) 38%,rgba(199,154,72,.1) 57%,transparent 70%);
  transform:translate(-50%,-50%) scale(.55);animation:log-reward-complete-bloom .92s cubic-bezier(.16,.76,.22,1) both;
}
.log-reward--complete:after{left:50%;top:50%;animation-duration:1.05s;}
.log-reward-wreath{
  position:relative;width:216px;height:216px;display:grid;place-items:center;opacity:0;
  transform:scale(.68) rotate(-5deg);
  animation:log-reward-wreath .58s cubic-bezier(.18,.82,.22,1.16) forwards;will-change:transform,opacity;
}
.log-reward-wreath:before,.log-reward-wreath:after{
  content:"";position:absolute;inset:29px;border-radius:50%;border:1px solid rgba(127,147,100,.32);
  opacity:0;transform:scale(.72);animation:log-reward-ring .52s ease-out .18s forwards;
}
.log-reward-wreath:after{inset:36px;border-color:rgba(199,154,72,.42);border-style:dashed;animation-delay:.27s;}
.log-reward-wreath .log-reward-leaf{
  left:99px;top:93px;width:var(--leaf-width,19px);height:var(--leaf-height,30px);filter:drop-shadow(0 3px 3px rgba(73,54,32,.13));
  transform:rotate(var(--leaf-rotate)) translateY(-78px) scale(.08);
  animation-name:log-reward-wreath-leaf;animation-duration:.72s;animation-delay:var(--leaf-delay);
}
.log-reward-wreath .log-reward-message{
  top:181px;bottom:auto;left:50%;width:max-content;max-width:min(250px,calc(100vw - 28px));
  padding:10px 15px 10px 34px;white-space:nowrap;font-size:13px;letter-spacing:.05px;
  animation-delay:.58s;
}
.log-reward-wreath .log-reward-message:before{left:13px;width:11px;height:11px;background:var(--gold);}
.log-reward-wreath-seal{
  position:relative;width:94px;height:94px;display:grid;place-items:center;border:1px solid rgba(86,107,67,.45);
  border-radius:47% 53% 49% 51% / 52% 47% 53% 48%;
  background:
    radial-gradient(circle at 34% 24%,rgba(255,255,255,.9),transparent 28%),
    linear-gradient(145deg,rgba(255,253,244,.98),rgba(224,232,199,.98));
  box-shadow:0 14px 32px rgba(73,54,32,.18),inset 0 0 0 6px rgba(255,255,255,.5);
  color:var(--sage-deep);
}
.log-reward-wreath-seal:before{
  content:"";position:absolute;inset:9px;border:1px dashed rgba(86,107,67,.33);
  border-radius:50%;
}
.log-reward-wreath-seal svg{position:relative;width:52px;height:52px;overflow:visible;filter:drop-shadow(0 1px 0 #fff);}
.log-reward-wreath-seal .seal-branch{fill:none;stroke:currentColor;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;}
.log-reward-wreath-seal .seal-leaf{fill:currentColor;stroke:none;opacity:.76;}
/* Quality variant (item 1) — a warmer, richer botanical treatment for a day that closed
   BOTH complete and balanced (dayBalanceOverall==='balanced'). Still two positive states
   only, never a third/negative one: this only ever adds warmth on top of the same wreath,
   it never subtracts from or recolors the plain-completion look into something lesser. */
.log-reward--quality:before{
  background:radial-gradient(circle,rgba(255,247,214,.92),rgba(226,196,140,.42) 38%,rgba(199,154,72,.16) 57%,transparent 70%);
}
.log-reward-wreath--quality:before{border-color:rgba(199,154,72,.58);}
.log-reward-wreath--quality:after{border-color:rgba(190,108,69,.48);}
.log-reward-wreath--quality .log-reward-wreath-seal{color:var(--gold);}
.log-reward-wreath--quality .log-reward-message{
  white-space:normal;text-align:center;max-width:min(216px,calc(100vw - 28px));
}
@keyframes log-reward-life{0%,86%{opacity:1;}100%{opacity:0;}}
@keyframes log-reward-bloom{0%{opacity:0;transform:scale(.28);}35%{opacity:1;}100%{opacity:0;transform:scale(1.18);}}
@keyframes log-reward-glints{0%{opacity:0;transform:scale(.2) rotate(-12deg);}42%{opacity:1;}100%{opacity:0;transform:scale(1.6) rotate(16deg);}}
@keyframes log-reward-stamp{
  0%{opacity:0;transform:translateY(-12px) scale(1.32) rotate(-12deg);}
  52%{opacity:1;transform:translateY(2px) scale(.91) rotate(2deg);}
  76%{opacity:1;transform:translateY(-1px) scale(1.045) rotate(-1deg);}
  100%{opacity:1;transform:translateY(0) scale(1) rotate(0);}
}
@keyframes log-reward-leaf{
  0%{opacity:0;transform:translate(0,0) rotate(var(--leaf-rotate)) scale(.12);}
  24%{opacity:1;}
  68%,82%{opacity:1;transform:translate(var(--leaf-x),var(--leaf-y)) rotate(calc(var(--leaf-rotate) + var(--leaf-turn))) scale(var(--leaf-scale,1));}
  100%{opacity:0;transform:translate(var(--leaf-x),var(--leaf-y)) rotate(calc(var(--leaf-rotate) + var(--leaf-turn) + 4deg)) scale(var(--leaf-scale,1));}
}
@keyframes log-reward-message{to{opacity:1;transform:translate(-50%,0) scale(1);}}
@keyframes log-reward-complete-life{0%,88%{opacity:1;}100%{opacity:0;}}
@keyframes log-reward-complete-bloom{0%{opacity:0;transform:translate(-50%,-50%) scale(.55);}45%{opacity:1;}100%{opacity:0;transform:translate(-50%,-50%) scale(1.08);}}
@keyframes log-reward-wreath{to{opacity:1;transform:scale(1) rotate(0);}}
@keyframes log-reward-ring{to{opacity:1;transform:scale(1);}}
@keyframes log-reward-wreath-leaf{
  0%{opacity:0;transform:rotate(var(--leaf-rotate)) translateY(-38px) scale(.08);}
  58%{opacity:1;}
  100%{opacity:1;transform:rotate(var(--leaf-rotate)) translateY(-78px) scale(var(--leaf-scale,1));}
}
@media (prefers-reduced-motion:reduce){
  .log-reward,.log-reward:before,.log-reward:after,.log-reward-stamp,.log-reward-wreath,.log-reward-wreath:before,.log-reward-wreath:after,.log-reward-leaf,.log-reward-message{animation:none;}
  .log-reward--complete{background:none;}
  .log-reward:before,.log-reward:after,.log-reward-wreath:before,.log-reward-wreath:after{display:none;}
  .log-reward-stamp,.log-reward-wreath,.log-reward-message{opacity:1;transform:translate(-50%,0);}
  .log-reward-stamp{transform:scale(1);}
  .log-reward-wreath{transform:scale(1);}
  .log-reward-leaf{display:none;}
}

/* bottom sheet */
.sheet-backdrop{position:absolute;inset:0;background:rgba(52,45,37,.42);opacity:0;pointer-events:none;transition:opacity .25s ease;z-index:70;}
.sheet-backdrop.show{opacity:1;pointer-events:auto;}
.sheet{position:absolute;left:0;right:0;bottom:0;background:var(--paper);border-radius:22px 22px 0 0;box-shadow:0 -10px 40px rgba(73,54,32,.26);transform:translateY(100%);visibility:hidden;transition:transform .32s cubic-bezier(.32,.72,0,1),visibility 0s linear .32s;z-index:71;max-height:75%;display:flex;flex-direction:column;border-top:1px solid rgba(176,146,105,.42);}
.sheet.show{transform:translateY(0);visibility:visible;transition:transform .32s cubic-bezier(.32,.72,0,1);}
.sheet.tall{max-height:88%;}
.sheet-handle{width:38px;height:5px;border-radius:999px;background:var(--line);margin:10px auto 0;flex:0 0 auto;}
.sheet-body{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:4px 18px 30px;}

/* swap alternatives */
.altrow{display:flex;align-items:center;gap:12px;padding:13px;border:1px solid rgba(176,146,105,.38);border-radius:14px;margin-top:10px;cursor:pointer;background:rgba(255,250,240,.9);min-height:44px;}
.altrow:active{transform:scale(.98);}
.altrow .ae{font-size:26px;width:48px;text-align:center;flex:0 0 48px;}
/* Recipe book + Market use the same small watercolor art as Today. It stays clipped inside its
   own warm-paper tile, so list rows keep their calm, tidy rhythm even when a painting is detailed. */
.altrow .ae.recipe-list-art{height:48px;display:grid;place-items:center;overflow:hidden;border:1px solid rgba(176,146,105,.26);border-radius:12px;background:#fbf5e8;}
.recipe-list-image{display:block;width:100%;height:100%;object-fit:cover;}
/* Swap sheet "top pick" — row 0 of Best matches heros visually (same data/onclick) so the
   sheet reads as "here's your best match, or browse" instead of five identical rows. */
.altrow-hero{padding:17px;border-color:rgba(199,154,72,.55);background:linear-gradient(180deg,rgba(199,154,72,.12),rgba(255,250,240,.95));box-shadow:var(--shadow-soft);}
.altrow-hero .ae{font-size:34px;width:56px;flex:0 0 56px;}
.altrow-hero .at .an{font-size:16px;}
.altrow-hero-badge{display:inline-block;margin:0 0 4px;}
.ingredient-icon{width:48px;height:48px;display:block;object-fit:cover;border-radius:10px;background:#fbf5e8;}
.ingredient-icon-lg{width:112px;height:112px;display:block;object-fit:cover;border-radius:20px;background:#fbf5e8;}
.detail-title-row h1,.detail-title-row h2{min-width:0;margin:0;overflow-wrap:anywhere;}
.detail-title-row .backbtn{flex:0 0 auto;margin:0;}
.detail-hero{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:14px;width:100%;max-width:460px;margin-top:10px;padding:12px 14px;border:1px solid rgba(176,146,105,.38);border-radius:var(--radius);background:rgba(255,250,240,.92);box-shadow:var(--shadow-soft);}
.detail-hero-media{display:grid;place-items:center;width:104px;min-height:104px;}
.detail-hero .ingredient-icon-lg{width:96px;height:96px;border-radius:18px;}
.detail-hero-body{min-width:0;}
.detail-hero-badges{display:flex;flex-wrap:wrap;align-items:center;gap:6px;}
.detail-hero-badges .pill{margin:0;}
.ingredient-detail-intro{margin-top:10px;padding:14px;}
.ingredient-detail-top{display:grid;grid-template-columns:148px minmax(0,1fr);gap:16px;align-items:center;}
.ingredient-detail-image{display:grid;place-items:center;width:148px;height:148px;overflow:hidden;border-radius:14px;background:linear-gradient(135deg,#f6e8d1,#edf1df 55%,#dfebcd);}
.ingredient-detail-image .ingredient-icon-lg{width:140px;height:140px;padding:5px;border-radius:12px;background:transparent;filter:drop-shadow(0 9px 7px rgba(73,54,32,.14));}
.ingredient-detail-copy{min-width:0;}
.ingredient-detail-copy h1,.ingredient-detail-copy h2{margin:3px 0 5px;overflow-wrap:anywhere;}
.ingredient-detail-copy .sub{margin:0;}
.ingredient-detail-copy .detail-hero-badges{margin-top:9px;}
.ingredient-detail-nutrition{margin-top:14px;}
.recipe-detail-hero{max-width:560px;}
.recipe-hero-media{width:124px;min-height:124px;border-radius:20px;background:#fbf5e8;overflow:hidden;font-size:54px;}
.recipe-image{width:100%;height:100%;display:block;object-fit:contain;border-radius:inherit;background:#fbf5e8;padding:4px;}
.recipe-detail-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;}
.recipe-action{min-height:42px;padding:0 13px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--sage-deep);font:inherit;font-size:13px;font-weight:700;cursor:pointer;}
.recipe-action:active{transform:scale(.97);}
.recipe-action-primary{background:var(--sage);border-color:var(--sage);color:#fff;}
.recipe-action-quiet{color:var(--ink-soft);font-weight:600;}
.recipe-action-danger{color:#b25e35;background:#fff8f4;border-color:#efd4c7;}
.recipe-section{margin-top:22px;}
.recipe-section-heading h2,.recipe-section h2{margin:0;}
.recipe-section-heading .sub{margin:0;}
.recipe-options-section{padding:13px 14px;border:1px solid var(--line);border-radius:16px;background:#fffaf3;}
.recipe-options-section:before{content:'Make it your way';display:block;font-size:13px;font-weight:700;color:var(--ink-soft);margin-bottom:2px;}
.recipe-options-section .row{margin-top:7px!important;}
.recipe-meal-card{margin-top:14px;padding:14px;}
.recipe-why-section{padding-bottom:8px;}

@media (max-width:420px){
  .detail-hero{grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px 12px;}
  .detail-hero-media{width:86px;min-height:86px;}
  .detail-hero .ingredient-icon-lg{width:78px;height:78px;border-radius:14px;}
  .recipe-hero-media{width:92px;min-height:92px;font-size:42px;}
  .detail-hero-badges{justify-content:flex-start;}
  .ingredient-detail-intro{padding:12px;}
  .ingredient-detail-top{grid-template-columns:116px minmax(0,1fr);gap:12px;}
  .ingredient-detail-image{width:116px;height:116px;border-radius:12px;}
  .ingredient-detail-image .ingredient-icon-lg{width:110px;height:110px;border-radius:10px;}
  .ingredient-detail-copy .detail-hero-badges{margin-top:7px;}
}

/* task C5: icon picker grid on the new/edit ingredient form */
.icon-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(56px,1fr));gap:8px;max-height:260px;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:2px;}
.image-picker-groups{max-height:300px;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:2px 4px 2px 2px;}
.image-picker-group + .image-picker-group{margin-top:12px;padding-top:11px;border-top:1px solid rgba(176,146,105,.22);}
.image-picker-group .icon-grid{max-height:none;overflow:visible;}
.image-picker-group-title{margin:0 0 7px 2px;color:var(--muted);font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;}
.icon-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-width:44px;min-height:44px;padding:5px;border:2px solid transparent;border-radius:12px;background:rgba(255,250,240,.9);cursor:pointer;font:inherit;-webkit-appearance:none;appearance:none;}
.icon-tile:active{transform:scale(.95);}
.icon-tile .ingredient-icon{width:36px;height:36px;margin:0 auto;}
.detail-hero-action{margin-top:10px;}
.recipe-lead-image-row{gap:12px;align-items:center;margin-top:6px;flex-wrap:wrap;}
.recipe-image-preview{width:54px;height:54px;display:grid;place-items:center;border-radius:12px;background:#fbf5e8;overflow:hidden;border:1px solid rgba(176,146,105,.26);flex:0 0 54px;}
.recipe-image-preview .recipe-image{padding:2px;}
.recipe-image-preview-lg{width:82px;height:82px;border-radius:16px;flex-basis:82px;}
.recipe-image-preview-lg .recipe-image{padding:3px;}
.recipe-builder-identity{display:grid;grid-template-columns:minmax(0,1fr) 72px;gap:10px;align-items:start;}
.recipe-builder-identity .field{margin-bottom:10px;}
.recipe-builder-panel{margin-top:12px;border:1px solid var(--line);border-radius:14px;background:rgba(255,255,255,.58);overflow:hidden;}
.recipe-builder-panel summary{min-height:46px;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 13px;cursor:pointer;color:var(--ink-soft);font-size:13px;font-weight:800;list-style:none;}
.recipe-builder-panel summary::-webkit-details-marker{display:none;}
.recipe-builder-panel summary::after{content:'⌄';font-size:13px;color:var(--muted);transition:transform .16s ease;order:3;}
.recipe-builder-panel[open] summary{border-bottom:1px solid var(--line);}
.recipe-builder-panel[open] summary::after{transform:rotate(180deg);}
.recipe-builder-panel summary span{margin-left:auto;font-size:11px;font-weight:600;color:var(--muted);text-align:right;}
.recipe-builder-panel-body{padding:12px 13px 14px;}
.recipe-builder-panel-body > h2:first-child{margin-top:0!important;}
/* Recipe editor choices use the same compact, outlined language as Library filters.
   The selected state remains unmistakable, while unselected choices stop reading as
   large pill CTAs in a dense editing form. */
.recipe-builder-panel .pill.chip-preset{min-height:44px;border:1px solid rgba(176,146,105,.35);border-radius:10px;padding:0 11px;background:rgba(255,250,240,.78);color:var(--ink-soft);font-size:12px;font-weight:700;}
.recipe-builder-panel .pill.chip-preset.chipsel{border-color:var(--sage);background:var(--sage);color:#fff;}
.food-builder-panel{margin-top:12px;border:1px solid var(--line);border-radius:14px;background:rgba(255,255,255,.58);overflow:hidden;}
.food-builder-panel summary{min-height:46px;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 13px;cursor:pointer;color:var(--ink-soft);font-size:13px;font-weight:800;list-style:none;}
.food-builder-panel summary::-webkit-details-marker{display:none;}
.food-builder-panel summary::after{content:'⌄';font-size:13px;color:var(--muted);transition:transform .16s ease;order:3;}
.food-builder-panel[open] summary{border-bottom:1px solid var(--line);}
.food-builder-panel[open] summary::after{transform:rotate(180deg);}
.food-builder-panel summary span{margin-left:auto;font-size:11px;font-weight:600;color:var(--muted);text-align:right;}
.food-builder-panel-body{padding:12px 13px 14px;}
.food-builder-panel .pill.chip-preset{min-height:44px;border:1px solid rgba(176,146,105,.35);border-radius:10px;padding:0 11px;background:rgba(255,250,240,.78);color:var(--ink-soft);font-size:12px;font-weight:700;}
.food-builder-panel .pill.chip-preset.chipsel{border-color:var(--sage);background:var(--sage);color:#fff;}
.ingredient-detail-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;}
.ingredient-detail-action{min-height:42px;padding:0 13px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--sage-deep);font:inherit;font-size:13px;font-weight:700;cursor:pointer;}
.ingredient-detail-action:active{transform:scale(.97);}
.ingredient-detail-action-primary{background:var(--sage);border-color:var(--sage);color:#fff;}
.ingredient-detail-action-quiet{color:var(--ink-soft);font-weight:600;}
.ingredient-detail-action-danger{color:#b25e35;background:#fff8f4;border-color:#efd4c7;}
.recipe-image-tile{width:44px;height:44px;display:block;object-fit:contain;border-radius:10px;background:#fbf5e8;padding:2px;}
.recipe-image-tile-auto{width:44px;height:44px;display:grid;place-items:center;border-radius:10px;background:var(--paper);color:var(--sage-deep);font-size:11px;font-weight:700;border:1px dashed rgba(127,147,100,.42);}
.icon-tile.sel{border-color:var(--sage);background:var(--sage-tint);}
.icon-tile-label{font-size:9px;color:var(--muted);text-align:center;line-height:1.1;}
.icon-tile.sel .icon-tile-label{color:var(--sage-deep);font-weight:700;}
.altrow .at{flex:1;min-width:0;}
.altrow .at .an{font-weight:600;font-size:14px;}
.altrow .at .ad{font-size:12px;color:var(--muted);margin-top:2px;}
.altrow .at .ad b{color:var(--sage-deep);}
.altrow .tags{margin-top:7px;}

/* shopping list (Defect C redesign: "in cart" dims but never strikes through — that used
   to read as "done/have it", the opposite of what the tick actually meant; "already-home"
   rows are a real greyed section now, not a dropped row + summary sentence) */
.shop-cat{font-size:11.5px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);margin:18px 0 4px;}
.shop-cat:first-child{margin-top:6px;}
.shop-item{display:flex;align-items:center;gap:12px;padding:12px 2px;border-bottom:1px solid var(--line);cursor:pointer;min-height:44px;}
.shop-item .sck{width:22px;height:22px;border-radius:7px;border:2px solid var(--line);flex:0 0 22px;display:grid;place-items:center;color:#fff;font-size:13px;}
.shop-item.in-cart .sck{background:var(--sage);border-color:var(--sage);}
.shop-item .sname{flex:1;font-size:14px;}
.shop-item .sqty{font-size:13px;font-weight:700;color:var(--ink-soft);white-space:nowrap;}
.shop-item.in-cart{opacity:.55;}
.shop-item.in-cart .sname{color:var(--muted);}
.shop-item.in-cart .sqty{color:var(--muted);}
.shop-item-static{cursor:default;}
.shop-item.already-home{cursor:default;opacity:.6;gap:8px;}
.shop-item.already-home .sck{background:var(--sage);border-color:var(--sage);}

/* onboarding */
.onboard{position:absolute;inset:0;background:var(--bg);z-index:44;display:flex;flex-direction:column;padding:56px 24px 30px;}
.onboard.hidden{display:none;}
.ob-skip{position:absolute;top:20px;right:20px;border:0;background:none;font:inherit;font-size:13px;font-weight:600;color:var(--muted);cursor:pointer;padding:8px;min-height:44px;}
.ob-slides{flex:1;display:flex;flex-direction:column;justify-content:center;}
.ob-slide{display:none;text-align:center;}
.ob-slide.active{display:block;}
.ob-emoji{font-size:56px;text-align:center;margin-bottom:8px;}
.ob-dots{display:flex;justify-content:center;gap:7px;margin:18px 0 4px;}
.ob-dots .d{width:7px;height:7px;border-radius:50%;background:var(--line);transition:.2s;}
.ob-dots .d.on{background:var(--sage);width:20px;border-radius:4px;}

/* login gate (Phase 3A.2) — fixed so it blocks the whole viewport regardless of where it
   sits in the DOM; :not([hidden]) rather than a bare .login-gate{display:flex} because an
   author-stylesheet display rule would otherwise outrank the UA's own [hidden]{display:none}
   in the cascade and defeat the hidden attribute entirely. */
.login-gate{position:fixed;inset:0;z-index:95;background:var(--bg);flex-direction:column;align-items:center;justify-content:center;padding:24px;text-align:center;}
.login-gate:not([hidden]){display:flex;}
.login-gate-emoji{font-size:56px;margin-bottom:8px;}
.login-gate h1{margin-bottom:2px;}
.login-gate #loginGateButton{width:100%;max-width:300px;}
.login-gate #loginGateError{color:var(--terra);min-height:0;}
body.gate-open{overflow:hidden;}

/* ---------- segmented donut ring + arc popover + eaten chips
   + cute log button + meal state tags + profile tint stripe (home-screen redesign) ---------- */

/* segmented donut ring */
.ring-wrap{position:relative;}
.ring-arc{}
.macro-pct{font-size:10px;font-weight:700;opacity:.7;}
.macro-pct-p{color:var(--sage-deep);}
.macro-pct-c{color:#9a7414;}
.macro-pct-f{color:#b25e35;}
.ring-over{color:var(--terra);}

/* arc tap popover */
.arc-popover{
  position:fixed;top:0;left:0;background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:10px 14px;box-shadow:0 6px 20px rgba(73,54,32,.15);font-size:12px;z-index:100;
  white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .2s;
}
.arc-popover.show{opacity:1;pointer-events:auto;}
.arc-popover .ap-label{font-weight:700;font-size:13px;display:flex;align-items:center;gap:6px;}
.arc-popover .ap-dot{width:8px;height:8px;border-radius:50%;display:inline-block;}
.arc-popover .ap-detail{color:var(--muted);font-size:11px;margin-top:3px;}

/* Phase 3 D3b: "targets are an estimate" banner — calm/informational (soft gold wash, the
   same "off/estimate" family as the balance dots), NEVER red/alarm. Hidden when empty. */
.basics-banner:empty{display:none;}
.basics-banner-card{display:flex;align-items:center;gap:9px;background:#f6edd6;border:1px solid rgba(154,116,20,.28);border-radius:12px;padding:9px 11px;margin:0 0 12px;}
.basics-banner-card .bb-leaf{font-size:15px;flex:0 0 auto;}
.basics-banner-card .bb-text{flex:1;font-size:12px;line-height:1.35;color:#7a5c14;}
.basics-banner-card .bb-add{flex:0 0 auto;border:0;background:var(--sage);color:#fff;font:inherit;font-weight:700;font-size:12px;padding:7px 11px;border-radius:9px;cursor:pointer;min-height:34px;}
.basics-banner-card .bb-x{flex:0 0 auto;border:0;background:none;color:#9a7414;font-size:14px;cursor:pointer;padding:4px 2px;line-height:1;min-height:34px;}

/* Phase 3 D2: end-of-week "week in review" card — warm but calm (soft sage wash), never a
   scoreboard. Hidden when empty (rendered only Fri-Sun on the current week with data). */
.week-review:empty{display:none;}
.week-review-card{background:var(--sage-tint);border-color:rgba(var(--sage-rgb),.3);margin-top:12px;}
.week-review-card .wr-head{display:flex;align-items:center;gap:7px;font-size:14px;font-weight:700;color:var(--sage-deep);}
.week-review-card .wr-leaf{font-size:15px;}
.week-review-card .wr-adh{font-size:13.5px;color:var(--ink-soft);margin-top:7px;}
.week-review-card .wr-adh b{color:var(--sage-deep);}
.week-review-card .wr-sub{margin:5px 0 0;}
/* Phase 3 D5: the warm JOINT couple line — aggregate shared outcome, never a comparison. */
.week-review-card .wr-couple{margin:8px 0 0;padding-top:8px;border-top:1px solid rgba(var(--sage-rgb),.22);font-size:13px;font-weight:600;color:var(--sage-deep);}

/* Today's one whole-day action is deliberately OUTSIDE its scrollable screen.  It stays
   above the tab bar, while chart and meal cards remain information-first. */
.today-keystone-dock{position:absolute;left:18px;right:18px;bottom:96px;z-index:29;display:none;padding:9px 10px 10px;border:1px solid rgba(var(--sage-rgb),.32);border-radius:18px;background:linear-gradient(135deg,rgba(255,253,247,.96),rgba(var(--sage-rgb),.13));box-shadow:0 12px 28px rgba(73,54,32,.17),inset 0 1px 0 rgba(255,255,255,.72);backdrop-filter:blur(14px);}
.today-keystone-dock.is-visible{display:block;animation:todayDockIn .22s ease-out;}
.today-keystone-dock:empty{display:none;}
.today-keystone .ks-btn{margin:0;min-height:46px;padding:12px 14px;border:1px solid rgba(255,255,255,.38);border-radius:12px;background:linear-gradient(135deg,var(--sage),var(--sage-deep));box-shadow:0 6px 14px rgba(var(--sage-rgb),.28);letter-spacing:.05px;}
.today-keystone .ks-btn.ghostbtn{background:rgba(255,250,240,.88);color:var(--sage-deep);border:1.5px solid rgba(var(--sage-rgb),.7);box-shadow:none;}
.today-keystone .ks-sub{margin:7px 4px 0;text-align:center;font-size:11.5px;color:var(--ink-soft);}
.today-keystone .ks-settled{display:flex;align-items:center;justify-content:center;gap:8px;font-size:13px;font-weight:600;color:var(--sage-deep);padding:5px 3px;}
.today-keystone .ks-check{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--sage-tint);color:var(--sage-deep);font-size:12px;font-weight:700;}
@keyframes todayDockIn{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}

/* Luxury pass: an inset-paper nutrition panel and quieter, tactile meal controls. */
#today{padding-bottom:188px;}
#todayProgressCard{position:relative;padding:16px 17px 17px;background:linear-gradient(135deg,rgba(255,253,247,.95),rgba(var(--sage-rgb),.10));border-color:rgba(var(--sage-rgb),.28);box-shadow:0 12px 28px rgba(73,54,32,.11),inset 0 1px 0 rgba(255,255,255,.8);}
.nutrition-kicker{display:flex;justify-content:space-between;align-items:center;margin:0 1px 11px;color:var(--sage-deep);font-size:11px;font-weight:800;letter-spacing:1.15px;text-transform:uppercase;}
.nutrition-kicker small{font-size:9px;font-weight:600;letter-spacing:.35px;text-transform:none;color:var(--muted);}
#todayProgressCard .ring-wrap{gap:16px;}
#todayProgressCard .ring{border-radius:50%;background:radial-gradient(circle at 36% 28%,rgba(255,255,255,.92),rgba(var(--sage-rgb),.07) 67%,rgba(var(--sage-rgb),.13));box-shadow:inset 0 0 0 1px rgba(var(--sage-rgb),.15),0 6px 15px rgba(73,54,32,.08);}
#todayProgressCard .ring-track{stroke:rgba(var(--sage-rgb),.13);}
#todayProgressCard .ring-protein{stroke:var(--sage);}
#todayProgressCard .ring .big{font-size:28px;letter-spacing:-.8px;color:var(--today-card-title);}
#todayProgressCard .ring .lbl{font-size:10px;max-width:82px;text-align:center;line-height:1.2;}
#todayProgressCard .macros{gap:12px;}
#todayProgressCard .macro .mhead{margin-bottom:6px;font-size:12px;}
#todayProgressCard .macro .mhead > span{color:var(--today-card-detail);font-weight:600;}
#todayProgressCard .macro .mhead b{font-size:12.5px;color:var(--today-card-title);}
#todayProgressCard .bar{height:7px;background:rgba(var(--sage-rgb),.10);box-shadow:inset 0 1px 2px rgba(73,54,32,.06);}
#today .meal{border-color:rgba(176,146,105,.32);box-shadow:0 6px 18px rgba(73,54,32,.075),inset 0 1px 0 rgba(255,255,255,.65);}
#today .meal .thumb{background:linear-gradient(145deg,#fffaf0,var(--sage-tint));box-shadow:inset 0 1px 0 rgba(255,255,255,.85),0 3px 8px rgba(73,54,32,.06);}
#today .meal .info .t{letter-spacing:.05px;}
.meal-act-btn{background:rgba(255,253,247,.84);border-color:rgba(176,146,105,.38);box-shadow:0 2px 5px rgba(73,54,32,.05);}
.meal-log-btn{box-shadow:0 5px 12px rgba(var(--sage-rgb),.28),inset 0 1px 0 rgba(255,255,255,.25);}

/* Today only surfaces stand-alone drinks/quick adds here — planned meals already have a
   status on their own cards. The details element keeps this pleasant but out of the way. */
#todayRecordsCard{margin-top:14px;padding:0;overflow:hidden;}
#todayRecordsCard summary{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:58px;padding:10px 14px;cursor:pointer;list-style:none;}
#todayRecordsCard summary::-webkit-details-marker{display:none;}
#todayRecordsCard summary::after{content:"";width:7px;height:7px;margin-left:2px;border-right:1.5px solid var(--sage-deep);border-bottom:1.5px solid var(--sage-deep);transform:rotate(45deg) translateY(-2px);transition:transform .18s ease;}
#todayRecordsCard[open] summary::after{transform:rotate(225deg) translate(-2px,-1px);}
.today-extras-title{display:flex;align-items:center;gap:9px;min-width:0;}
.today-extras-title b{display:block;font-size:13.5px;color:var(--today-card-title);}
.today-extras-title small{display:block;margin-top:2px;color:var(--today-card-detail);font-size:10.5px;}
.today-extras-spark{display:grid;place-items:center;width:30px;height:30px;border-radius:11px;background:var(--sage-tint);color:var(--sage-deep);font-size:15px;flex:0 0 auto;}
#todayRecordsCard summary .pill{margin-left:auto;white-space:nowrap;}
#todayRecordsList{padding:0 14px 8px;border-top:1px solid rgba(176,146,105,.22);}
#todayRecordsCard .logitem{gap:8px;padding:8px 0;}
#todayRecordsCard .logitem .li-i{width:32px;height:32px;flex-basis:32px;border-radius:10px;font-size:15px;overflow:hidden;}
#todayRecordsCard .logitem .li-i .ingredient-icon{width:32px;height:32px;border-radius:9px;background:transparent;}
#todayRecordsCard .logitem .li-t{font-size:12.5px;line-height:1.2;}
#todayRecordsCard .logitem .li-t small{font-size:10.5px;line-height:1.25;margin-top:2px;}
#todayRecordsCard .logitem .li-k{font-size:12px;}
#todayRecordsCard .logitem .li-x{width:36px;height:36px;min-width:36px;border-radius:10px;font-size:13px;}

/* meal card action buttons row */
.meal-actions-row{display:flex;align-items:center;gap:8px;flex-shrink:0;}
.meal-act-btn{
  width:36px;height:36px;border-radius:12px;border:1.5px solid var(--border);
  background:var(--card);color:var(--muted);font-size:16px;
  display:grid;place-items:center;cursor:pointer;flex-shrink:0;
  transition:transform .12s, border-color .15s, color .15s;transform-origin:center;
}
.meal-act-btn:active{transform:scale(.88);}
.meal-act-btn:hover{border-color:var(--sage);color:var(--sage);}
.meal-act-btn.act-skip:hover{border-color:var(--muted);color:var(--text);}

/* cute meal log button */
.meal-log-btn{
  width:44px;height:44px;border-radius:14px;border:0;
  background:linear-gradient(135deg,var(--sage),var(--sage-deep));color:#fff;font-size:18px;
  display:grid;place-items:center;cursor:pointer;flex-shrink:0;
  box-shadow:0 3px 8px rgba(86,107,67,.28);transition:transform .12s;transform-origin:center;
}
.meal-log-btn:active{transform:scale(.88);}
.meal-log-btn .log-icon{display:block;line-height:1;}

/* Today keeps the familiar spacious meal cards and full-size actions. A small padding
   reduction removes dead space without squeezing recipe details or tap targets. */
#today .meal{padding:14px;gap:11px;}

/* meal card states (confirmed/skipped visual treatment) */
.meal.state-done{border-left:3px solid var(--sage);opacity:.8;}
.meal.state-skipped{opacity:.5;border-left:3px solid var(--muted);}
.meal.state-skipped .thumb{filter:grayscale(.35);}
.state-tag{font-size:10px;font-weight:700;margin-top:5px;}
.state-tag.tag-done{color:var(--sage-deep);}
.state-tag.tag-skipped{color:var(--muted);}

/* profile color tint stripe */
.tint-stripe{height:3px;border-radius:2px;margin:4px 0 2px;transition:background .3s;}
.tint-stripe.tint-elena{background:var(--sage);}
.tint-stripe.tint-partner{background:var(--gold);}

/* remove the "Calories by macro" card (superseded by segmented donut ring) */
#todayMacroCalCard{display:none !important;}

/* boot loading overlay: hides the app until real data is painted, with a
   guaranteed CSS-only fallback in case JS never gets to hide it */
#bootLoader{
  position:fixed;inset:0;z-index:9999;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  background:var(--bg);
  transition:opacity .22s ease;
  animation:bootLoaderAutoHide .01s linear 4s forwards;
}
#bootLoader .boot-mark{
  font-family:var(--font-script);font-size:34px;color:var(--sage-deep);
}
#bootLoader .boot-spinner{
  width:22px;height:22px;border-radius:50%;
  border:2.5px solid var(--line);border-top-color:var(--sage);
  animation:bootSpin .8s linear infinite;
}
#bootLoader.gone{
  opacity:0;pointer-events:none;
  animation:none;
}
@keyframes bootSpin{
  to{transform:rotate(360deg);}
}
@keyframes bootLoaderAutoHide{
  to{opacity:0;pointer-events:none;}
}
