/* =========================================================
   Tiny Tummies — design system
   "First foods" palette: colour coding a tired parent can
   read without reading. Milk = bottle blue, food = pea
   green, allergens = soft clay, guidance = honey.
   Night feed mode follows the phone's dark setting, tuned
   for low glare at 3am.
   ========================================================= */

:root{
  --bg:#f6f7f2;            /* soft celery white */
  --card:#ffffff;
  --card-2:#eef0e8;
  --line:rgba(47,58,52,0.10);
  --text:#2f3a34;          /* deep spruce */
  --muted:#666d67;
  --on-accent:#fff;        /* text on a milk, food, or sickness button */

  /* 1.1: milk, food, and sickness are a shade deeper in light mode, so
     their text and white labels on them reach 4.5 to 1. They were about
     3.5 ("Start a breastfeed", "Sick") and 4.1 (white Milk and Food). */
  --pea:#42734c;           /* food */
  --pea-soft:#e4efe4;
  --bottle:#3b6aaf;        /* milk */
  --bottle-soft:#e6edf8;
  --clay:#a84b3a;          /* allergens / caution */
  --clay-soft:#f7e6e1;
  --honey:#c98f2d;         /* guidance */
  --honey-soft:#f7eeda;

  --radius-sm:12px;
  --radius-md:18px;
  --radius-lg:26px;

  --font-display: ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;

  --shadow: 0 1px 2px rgba(47,58,52,0.05), 0 4px 16px rgba(47,58,52,0.06);
}

/* Night feed mode — dim, warm, low glare */
@media (prefers-color-scheme: dark){
  :root{
    --bg:#1e1c19;
    --card:#2a2723;
    --card-2:#343029;
    --line:rgba(255,251,242,0.09);
    --text:#ece7dc;
    --muted:#9f9989;
    /* The dark-mode accents are pale, and white on them was 2.5 to 1; the
       background colour on them is over 6 to 1 (1.1). */
    --on-accent:var(--bg);

    --pea:#7fae86;
    --pea-soft:#2c352c;
    --bottle:#7f9fd0;
    --bottle-soft:#282e3a;
    --clay:#d08a77;
    --clay-soft:#3a2c27;
    --honey:#d3a955;
    --honey-soft:#38311f;

    --shadow: none;
  }
}
/* 1.1: the same palette when the night look is on by the clock (data-night). */
:root[data-night]{
    --bg:#1e1c19;
    --card:#2a2723;
    --card-2:#343029;
    --line:rgba(255,251,242,0.09);
    --text:#ece7dc;
    --muted:#9f9989;
    /* The dark-mode accents are pale, and white on them was 2.5 to 1; the
       background colour on them is over 6 to 1 (1.1). */
    --on-accent:var(--bg);

    --pea:#7fae86;
    --pea-soft:#2c352c;
    --bottle:#7f9fd0;
    --bottle-soft:#282e3a;
    --clay:#d08a77;
    --clay-soft:#3a2c27;
    --honey:#d3a955;
    --honey-soft:#38311f;

    --shadow: none;
  }


*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html,body{ margin:0; padding:0; }
body{
  background:var(--bg); color:var(--text);
  font-family:var(--font-ui); font-size:16px; line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
button{ font-family:inherit; color:inherit; }
/* When a sheet is open, freeze the page behind it so it can't scroll under the backdrop. */
body.sheet-open{ overflow:hidden; }
body.sheet-open main{ overflow:hidden; touch-action:none; }
.hidden{ display:none !important; }

h1,h2{ font-family:var(--font-display); letter-spacing:-0.01em; }

/* ============ Sign-in ============ */
/* 1.1: the sign-in opening, a cot mobile. Every piece rests in its finished
   place; the motion only starts when playSignInScene() adds .play, after the
   splash has gone, so nothing plays unseen behind it.

   The mobile is real CSS 3D: a ring turning about its cord, seen slightly
   from below (as from the cot), with the five log shapes hanging from it.
   They're flat cut-outs, so they turn edge-on as they go round, like the
   felt shapes on a real one. */
.sign-in-screen{
  position:fixed; inset:0; z-index:100; overflow:hidden;
  display:flex; flex-direction:column;
}
/* The sky, shared with the loading screen (.splash). */
.sign-in-screen, .splash{
  --sky-top:#fdf5e8; --sky-bottom:#f3f3ea;
  --glow:rgba(255,196,110,0.40);
  --wood:#c99d6c; --wood-dark:#a87c4f; --string:rgba(90,80,64,0.45);
  background:linear-gradient(var(--sky-top), var(--sky-bottom) 75%);
}
@media (prefers-color-scheme: dark){
  .sign-in-screen, .splash{
    --sky-top:#0e1520; --sky-bottom:#1a2228;
    --glow:rgba(175,195,255,0.17);
    --wood:#9a7756; --wood-dark:#7a5c40; --string:rgba(230,225,210,0.32);
  }
}
:root[data-night] .sign-in-screen, :root[data-night] .splash{
  --sky-top:#0e1520; --sky-bottom:#1a2228;
  --glow:rgba(175,195,255,0.17);
  --wood:#9a7756; --wood-dark:#7a5c40; --string:rgba(230,225,210,0.32);
}

/* The mobile and the name, centred together in the space above the card. */
.scene{
  position:relative; flex:1 1 auto; min-height:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding-top:env(safe-area-inset-top);
}
.scene-glow{
  position:absolute; left:50%; top:42%; width:420px; height:420px; margin:-210px 0 0 -210px;
  border-radius:50%; background:radial-gradient(circle, var(--glow) 0%, transparent 64%);
  pointer-events:none;
}
.scene-stars{ display:none; position:absolute; width:300px; left:50%; margin-left:-150px; top:calc(env(safe-area-inset-top) + 24px); fill:#fff4d6; }

/* Its own layer above the glow, and the swing kept inside the 3D scene:
   otherwise the browser sliced the moving shapes against the glow. */
.cot-mobile{ position:relative; z-index:1; isolation:isolate; width:300px; height:320px; flex:0 0 auto; }
.cm-drop{ position:absolute; left:50%; top:76px; width:0; height:0; }
/* The cord runs up off the top of the screen, whatever its height. */
.cm-cord{ position:absolute; left:-0.75px; bottom:58px; width:1.5px; height:100vh; background:var(--string); }
/* Where the cord meets the ring's own cords, above its centre. */
.cm-bead{ position:absolute; left:-7px; top:-66px; width:14px; height:14px; border-radius:50%; background:var(--wood-dark); }
.cm-stage{ position:absolute; left:0; top:0; perspective:620px; }
.cm-tilt{ transform-style:preserve-3d; transform:rotateX(-17deg); }
.cm-spin{ transform-style:preserve-3d; transform:rotateY(18deg); }
.cm-ring{
  position:absolute; left:-108px; top:-108px; width:216px; height:216px; box-sizing:border-box;
  border-radius:50%; border:5px solid var(--wood);
  transform:rotateX(90deg);
}
.cm-hang{
  position:absolute; left:0; top:0; transform-style:preserve-3d;
  transform:rotateY(calc(var(--i) * 72deg)) translateZ(108px);
}
/* A cord from each hanging point up to the bead: 123px long, leaning in by
   atan(108 / 58), so they meet 58px above the ring's centre. */
.cm-cone{ position:absolute; left:-0.6px; bottom:0; width:1.2px; height:123px; background:var(--string); transform-origin:50% 100%; transform:rotateX(61.8deg); }
/* Each shape turns back by exactly as much as the ring has turned, so all
   five always face you, like double-sided felt toys. Without this, two of
   them were always edge-on. */
.cm-face{ position:absolute; left:0; top:0; transform-style:preserve-3d; transform:rotateY(calc(-18deg - var(--i) * 72deg)); }
.cm-knot{ position:absolute; left:-3.5px; top:-3.5px; width:7px; height:7px; border-radius:50%; background:var(--wood-dark); }
.cm-swing{ position:absolute; left:0; top:0; transform-origin:0 0; transform-style:preserve-3d; }
.cm-string{ position:absolute; left:-0.75px; top:0; width:1.5px; height:var(--len); background:var(--string); }
.cm-charm{
  position:absolute; left:-30px; top:calc(var(--len) - 4px); width:60px; height:60px;
  filter:drop-shadow(0 3px 4px rgba(40,40,30,0.18));
}

.scene-hero{ position:relative; display:flex; flex-direction:column; align-items:center; text-align:center; padding:0 28px; margin-top:6px; }
.scene-name{ font-family:var(--font-display); font-size:clamp(28px, 8.4vw, 34px); font-weight:800; color:var(--text); margin:0 0 4px; }
.scene-sub{ color:var(--muted); font-size:15px; margin:0; max-width:300px; line-height:1.45; text-wrap:balance; }

.sign-in-card{
  position:relative; z-index:2; flex:0 0 auto; max-height:72vh; overflow-y:auto;
  padding:22px 24px calc(18px + env(safe-area-inset-bottom));
  border-radius:28px 28px 0 0;
  background:var(--card);
  background:color-mix(in srgb, var(--card) 90%, transparent);
  -webkit-backdrop-filter:blur(24px) saturate(170%); backdrop-filter:blur(24px) saturate(170%);
  box-shadow:0 -8px 30px rgba(30,40,30,0.10);
  text-align:center;
}
.sign-in-card > *{ max-width:360px; margin-left:auto; margin-right:auto; }
/* 1.2.0 App Review: Apple's logo, from Apple's own files, beside the title,
   as Apple's guidelines for a custom Sign in with Apple button ask. The
   left-aligned logo file is drawn at the button's full height (it carries
   its own padding), and the title is in the system font. The logo shown
   always matches the button's colour, under the same rules as the button. */
.apple-button{
  width:100%; height:50px; padding:0 20px 0 8px; border:none; border-radius:999px;
  display:flex; align-items:center; justify-content:center;
  background:#000; color:#fff; font-family:var(--font-ui); font-weight:500; font-size:19px;
  letter-spacing:0; cursor:pointer;
}
.apple-button .apple-logo{ height:50px; width:auto; display:block; flex:none; }
.apple-button .apple-logo-on-white{ display:none; }
.apple-button:active{ opacity:0.85; }
/* Apple's own rule: the white button on a dark background. */
@media (prefers-color-scheme: dark){
  .apple-button{ background:#fff; color:#000; }
  .apple-button .apple-logo-on-black{ display:none; }
  .apple-button .apple-logo-on-white{ display:block; }
}
:root[data-night] .apple-button{ background:#fff; color:#000; }
:root[data-night] .apple-button .apple-logo-on-black{ display:none; }
:root[data-night] .apple-button .apple-logo-on-white{ display:block; }
.sign-in-privacy{ color:var(--muted); font-size:12px; margin-top:16px; line-height:1.6; }

/* Night: moonlit, with a few stars. */
@media (prefers-color-scheme: dark){ .scene-stars{ display:block; } }
:root[data-night] .scene-stars{ display:block; }

/* Short phones (SE): a smaller mobile; and while the email form is open,
   the name steps aside so nothing overlaps. */
@media (max-height:700px){
  .cot-mobile{ transform:scale(0.78); margin:-34px 0 -30px; }
  .sign-in-screen.email-open .scene-hero{ opacity:0; transition:opacity 0.2s; }
}
@media (max-height:600px){ .cot-mobile{ transform:scale(0.62); margin:-58px 0 -54px; } }

/* The opening, about 2.5 seconds; then the mobile keeps turning gently. */
.sign-in-screen.play .scene-glow{ animation:tt-fade 1.2s ease 0.1s both; }
.sign-in-screen.play .cm-drop{ animation:cm-drop 1.35s cubic-bezier(.25,.9,.3,1) 0.1s both; }
.sign-in-screen.play .cm-spin{ animation:cm-spin-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-spin 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-face.f0{ animation:cm-face0-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-face0 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-face.f1{ animation:cm-face1-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-face1 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-face.f2{ animation:cm-face2-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-face2 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-face.f3{ animation:cm-face3-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-face3 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-face.f4{ animation:cm-face4-in 2.6s cubic-bezier(.15,.6,.3,1) 0.1s both, cm-face4 40s linear 2.7s infinite; }
.sign-in-screen.play .cm-swing{ animation:cm-swing var(--sw) ease-in-out calc(var(--i) * -0.7s) infinite alternate; }
.sign-in-screen.play .scene-name{ animation:tt-up 0.6s cubic-bezier(.2,.8,.2,1) 1.25s both; }
.sign-in-screen.play .scene-sub{ animation:tt-up 0.6s cubic-bezier(.2,.8,.2,1) 1.42s both; }
.sign-in-screen.play .scene-stars{ animation:tt-fade 1.2s ease 0.6s both, tt-twinkle 3.4s ease-in-out 2s infinite; }
.sign-in-screen.play .sign-in-card{ animation:tt-card 0.7s cubic-bezier(.2,.85,.25,1) 1.75s both; }

@keyframes tt-fade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes cm-drop{
  0%{ transform:translateY(-70vh); }
  72%{ transform:translateY(10px); }
  88%{ transform:translateY(-3px); }
  100%{ transform:translateY(0); }
}
/* Ends on the resting angle (18deg) so the slow turn carries on from it. */
@keyframes cm-spin-in{ from{ transform:rotateY(-342deg); } to{ transform:rotateY(18deg); } }
@keyframes cm-spin{ from{ transform:rotateY(18deg); } to{ transform:rotateY(378deg); } }
@keyframes cm-face0-in{ from{ transform:rotateY(342deg); } to{ transform:rotateY(-18deg); } }
@keyframes cm-face0{ from{ transform:rotateY(-18deg); } to{ transform:rotateY(-378deg); } }
@keyframes cm-face1-in{ from{ transform:rotateY(270deg); } to{ transform:rotateY(-90deg); } }
@keyframes cm-face1{ from{ transform:rotateY(-90deg); } to{ transform:rotateY(-450deg); } }
@keyframes cm-face2-in{ from{ transform:rotateY(198deg); } to{ transform:rotateY(-162deg); } }
@keyframes cm-face2{ from{ transform:rotateY(-162deg); } to{ transform:rotateY(-522deg); } }
@keyframes cm-face3-in{ from{ transform:rotateY(126deg); } to{ transform:rotateY(-234deg); } }
@keyframes cm-face3{ from{ transform:rotateY(-234deg); } to{ transform:rotateY(-594deg); } }
@keyframes cm-face4-in{ from{ transform:rotateY(54deg); } to{ transform:rotateY(-306deg); } }
@keyframes cm-face4{ from{ transform:rotateY(-306deg); } to{ transform:rotateY(-666deg); } }
@keyframes cm-swing{ from{ transform:rotate(-5deg); } to{ transform:rotate(5deg); } }
@keyframes tt-up{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:translateY(0); } }
@keyframes tt-twinkle{ 0%,100%{ opacity:1; } 50%{ opacity:0.5; } }
@keyframes tt-card{ from{ transform:translateY(105%); } to{ transform:translateY(0); } }
/* Reduce Motion: the finished scene, still. */
@media (prefers-reduced-motion: reduce){
  .sign-in-screen.play *, .sign-in-screen.play{ animation:none !important; }
}

/* ============ Header ============ */
header{
  padding:calc(16px + env(safe-area-inset-top)) 20px 6px;
}
header h1{ font-size:27px; font-weight:800; margin:0; line-height:1.2; }
/* Today's title is the greeting, kept to one line so the header is the same
   height on every tab and the child switcher never moves (1.1). */
header h1.greeting-title{ font-size:clamp(20px, 6.4vw, 27px); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* A fixed height, so the header is the same on every tab. */
.header-top{ display:flex; justify-content:space-between; align-items:center; gap:12px; min-height:44px; }

.child-chips{ display:flex; gap:8px; overflow-x:auto; padding-bottom:6px; scrollbar-width:none; }
.child-chips::-webkit-scrollbar{ display:none; }
.child-chip{
  flex:0 0 auto; display:flex; align-items:center; gap:7px;
  padding:8px 14px 8px 8px; border-radius:999px; border:1.5px solid var(--line);
  background:var(--card); font-size:14px; font-weight:600; cursor:pointer;
}
.child-chip .avatar{
  width:26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--card-2); font-size:13px; font-weight:700;
  font-family:var(--font-display);
}
.child-chip.active{ border-color:var(--pea); background:var(--pea-soft); }
.child-chip.active .avatar{ background:var(--pea); color:#fff; }
.child-chip.add{ padding:8px 14px; color:var(--muted); border-style:dashed; }
.child-chip.all .avatar{ font-size:12px; }

/* 1.1: up to three children, all visible at once, each in its own colour. */
.child-seg{ display:flex; gap:4px; width:100%; padding:4px; border-radius:18px; background:var(--card-2); }
.child-seg-btn{
  flex:1 1 0; min-width:0; border:none; background:transparent; border-radius:14px;
  padding:7px 8px; cursor:pointer; color:var(--muted); font-family:var(--font-display);
  display:flex; flex-direction:column; align-items:center; gap:1px; min-height:44px; justify-content:center;
}
.child-seg-btn .nm{ font-size:15px; font-weight:800; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.child-seg-btn .nm i{ display:inline-block; width:9px; height:9px; border-radius:50%; background:var(--kid); margin-right:6px; vertical-align:1px; }
.child-seg-btn .age{ font-size:11.5px; font-weight:600; }
.child-seg-btn.all{ flex:0 0 auto; padding:7px 14px; font-weight:800; font-size:14px; }
.child-seg-btn.on{ background:var(--card); color:var(--text); box-shadow:0 1px 4px rgba(0,0,0,.12), inset 0 -3px 0 var(--kid, var(--pea)); }
.sheet-for{ margin:-6px 0 14px; font-size:14px; font-weight:800; color:var(--muted); font-family:var(--font-display); }
.sheet-for i{ display:inline-block; width:9px; height:9px; border-radius:50%; background:var(--kid); margin-right:6px; vertical-align:1px; }
.child-seg-btn.all.on{ box-shadow:0 1px 4px rgba(0,0,0,.12), inset 0 -3px 0 var(--pea); }

/* ============ Tabs ============ */
/* 1.1: the child chips, sticky at the top in place of the old tab row. */
.chips-bar{
  /* Sticks below the clock and Dynamic Island, not under them (1.1 UAT). */
  position:sticky; top:env(safe-area-inset-top); z-index:20;
  padding:6px 20px 4px;
  background:var(--bg); /* fallback for iOS 15.x */
  background:color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
}
.chips-bar:empty, .chips-bar .child-chips:empty{ padding:0; }
body.no-switcher .chips-bar{ display:none; }
/* A frosted strip behind the clock and Dynamic Island, so the page scrolling
   underneath never shows through behind the status bar. */
body::before{
  content:''; position:fixed; top:0; left:0; right:0; z-index:21; pointer-events:none;
  height:env(safe-area-inset-top);
  background:var(--bg);
  background:color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
}

/* 1.1: the tabs, floating at the bottom. Below the backdrop and sheets
   (60 and 70), so an open sheet always covers it. */
.viewtabs-bar{
  position:fixed; left:12px; right:12px; z-index:50;
  bottom:calc(10px + env(safe-area-inset-bottom));
  padding:5px; border-radius:30px;
  background:var(--card); /* fallback for iOS 15.x */
  background:color-mix(in srgb, var(--card) 86%, transparent);
  -webkit-backdrop-filter:blur(18px); backdrop-filter:blur(18px);
  border:1px solid var(--line);
  box-shadow:0 4px 18px rgba(47,58,52,0.16);
}
.viewtabs{ display:flex; gap:2px; }
.viewtab{
  flex:1; min-width:0; border:none; background:transparent; border-radius:24px;
  display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:7px 0 6px; font-size:10.5px; font-weight:600; color:var(--muted); cursor:pointer;
  white-space:nowrap; font-family:var(--font-ui);
  transition:color 0.2s ease, background 0.2s ease;
}
.viewtab svg{
  width:22px; height:22px; display:block;
  fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round;
}
/* The keyboard pushes fixed elements up on iOS; the bar steps aside instead. */
body.kb-open .viewtabs-bar{ display:none; }
.viewtab.active{
  background:var(--pea-soft); color:var(--pea);
  /* a gentle spring as the pill settles under the tapped tab */
  animation:tab-pill 0.32s cubic-bezier(.34,1.56,.64,1);
}
@keyframes tab-pill{
  0%{ transform:scale(0.9); }
  100%{ transform:scale(1); }
}

/* min-height: tall enough that, with the switcher stuck at the top, even a
   short page can stay there, so switching child never snaps the page back
   (settleForChildSwitch). */
main{ min-height:100vh; box-sizing:border-box; padding:12px 16px calc(112px + env(safe-area-inset-bottom)); overflow-x:hidden; -ms-overflow-style:none; scrollbar-width:none; }
main::-webkit-scrollbar{ display:none; }
.tab{ display:none; }
.tab.active{ display:block; }

/* Directional slide transitions between tabs */
/* Incoming-only tab entrance — no outgoing layer, so no ghosting overlap. */
.tab.tab-enter-right{ animation:tab-enter-right 0.26s cubic-bezier(.3,.9,.3,1); }
.tab.tab-enter-left{ animation:tab-enter-left 0.26s cubic-bezier(.3,.9,.3,1); }
@keyframes tab-enter-right{ from{ opacity:0; transform:translateX(20px); } to{ opacity:1; transform:translateX(0); } }
@keyframes tab-enter-left{ from{ opacity:0; transform:translateX(-20px); } to{ opacity:1; transform:translateX(0); } }
/* Today fades in without the slide (1.1 UAT). A transform on the tab makes
   it the box that position:fixed is measured from, so for the length of the
   slide the docked log buttons sat at the bottom of Today's content, mid
   screen, and then jumped down to the bottom of the screen. */
#tab-today.tab-enter-right, #tab-today.tab-enter-left{ animation:tab-fade 0.22s ease; }
@keyframes tab-fade{ from{ opacity:0; } to{ opacity:1; } }

/* Every tab's first element sits the same distance below the tab bar.
   Without this, each section's own top margin leaks through and the gap
   varies per tab (History was 22px, Allergens 14px, the rest 4px). */
.tab > *:first-child{ margin-top:0; }

/* ============ Cards & stats ============ */
.card{
  background:var(--card); border-radius:var(--radius-md);
  padding:16px; margin-bottom:12px; box-shadow:var(--shadow);
}
.card h3{ margin:0 0 4px; font-size:15px; font-family:var(--font-display); }
.card .card-sub{ color:var(--muted); font-size:13px; margin:0; }

.stat-row{ display:flex; gap:10px; margin-bottom:12px; }
.stat{
  flex:1; border-radius:var(--radius-md); padding:14px 12px;
  box-shadow:var(--shadow);
}
.stat .num{
  font-family:var(--font-display); font-size:28px; font-weight:800; line-height:1.1;
}
.stat .num small{ font-size:14px; font-weight:700; }
.stat .lbl{ font-size:12px; font-weight:600; margin-top:2px; opacity:0.85; }
.stat.milk{ background:var(--bottle-soft); color:var(--bottle); }
.stat.food{ background:var(--pea-soft); color:var(--pea); }

.milk-range-track{
  width:100%; height:10px; border-radius:999px; background:var(--card-2); overflow:hidden;
}
.milk-range-fill{
  height:100%; border-radius:999px; background:var(--bottle);
  transition:width 0.3s ease;
}
.settings-toggle{ width:20px; height:20px; accent-color:var(--pea); }

/* Quick actions */
.quick-actions{ display:flex; gap:8px; margin-bottom:16px; }
.quick-actions button{
  flex:1; min-width:0; border:none; border-radius:var(--radius-md); padding:11px 2px 10px;
  /* 14px, up from 12: these are the buttons used most, often one-handed and
     half asleep (1.1). */
  font-size:14px; font-weight:700; font-family:var(--font-display);
  cursor:pointer; box-shadow:var(--shadow); white-space:nowrap;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  min-height:62px;
}
.quick-actions .qa-e{ font-size:21px; line-height:1; }
/* The smallest iPhones are 320 points wide, where "Nappy" at 14px fills its
   button edge to edge. */
@media (max-width:340px){ .quick-actions button{ font-size:13px; } }
.quick-actions .log-milk{ background:var(--bottle); color:var(--on-accent); }
.quick-actions .log-food{ background:var(--pea); color:var(--on-accent); }
.quick-actions .log-medicine{ background:var(--card); color:var(--text); box-shadow:var(--shadow); }
.quick-actions button:active{ transform:scale(0.98); }

.toggle-field{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  background:var(--card-2); border-radius:var(--radius-sm); padding:12px 14px;
  cursor:pointer;
}
.toggle-label{ font-size:14px; font-weight:600; }

.unit-seg{ display:flex; background:var(--card-2); border-radius:999px; padding:3px; }
.unit-seg button{
  flex:1; border:none; background:transparent; border-radius:999px;
  padding:7px 4px; font-size:12.5px; font-weight:700; color:var(--muted);
  cursor:pointer; font-family:var(--font-ui); white-space:nowrap;
}
.unit-seg button.on{ background:var(--card); color:var(--text); box-shadow:var(--shadow); }

.feed-gap{
  font-size:12.5px; line-height:1.5; border-radius:var(--radius-sm);
  padding:10px 12px; margin-bottom:16px;
}
.feed-gap.ok{ background:var(--pea-soft); color:var(--pea); }
.feed-gap.close{ background:var(--honey-soft); color:var(--honey); }
.primary.medicine{ background:var(--text); color:var(--bg); }
.primary.sickness{ background:var(--clay); color:var(--on-accent); }
.quick-actions .log-sick{ background:var(--clay-soft); color:var(--clay); }
.entry.sickness .dot{ background:var(--clay-soft); }
.day-total{
  font-size:11.5px; font-weight:700; color:var(--bottle);
  background:var(--bottle-soft); border-radius:999px; padding:3px 9px;
}
.day-label-row{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  margin:18px 4px 8px;
}
.day-label-row .day-label{ margin:0; }
.reminder-card{ border-left:4px solid var(--honey); }

/* ============ Medication courses ============ */
.course-card{ border-left:4px solid var(--text); }
.course-progress{ font-size:12.5px; color:var(--muted); margin:2px 0 12px; }
.dose-row{
  display:flex; align-items:center; gap:10px;
  padding:9px 0; border-bottom:1px solid var(--line);
}
.dose-row:last-of-type{ border-bottom:none; }
.dose-time{ font-size:14px; font-weight:700; width:52px; flex:0 0 auto; }
.dose-state{ flex:1; font-size:12.5px; color:var(--muted); }
.dose-btn{
  flex:0 0 auto; border:1.5px solid var(--line); background:var(--card);
  color:var(--text); font-size:12.5px; font-weight:700; font-family:var(--font-ui);
  border-radius:999px; padding:6px 14px; cursor:pointer;
}
.dose-row.given .dose-time{ color:var(--pea); }
.dose-row.given .dose-state{ color:var(--pea); }
.dose-row.missed .dose-time{ color:var(--clay); }
.dose-row.missed .dose-state{ color:var(--clay); }
.course-done{
  background:var(--pea-soft); color:var(--pea); border-radius:var(--radius-sm);
  padding:12px; text-align:center; font-size:13px; font-weight:700;
}
.time-row{ display:flex; gap:8px; align-items:center; margin-bottom:8px; }
.time-row input{ flex:1; }
.time-remove{
  flex:0 0 40px; border:none; background:var(--card-2); color:var(--muted);
  border-radius:var(--radius-sm); padding:12px 0; cursor:pointer; font-size:15px;
}

/* ============ Timeline ============ */
.day-label{
  font-size:12px; font-weight:700; color:var(--muted);
  text-transform:uppercase; letter-spacing:0.06em;
  margin:18px 4px 8px;
}
.entry{
  display:flex; align-items:center; gap:12px;
  background:var(--card); border-radius:var(--radius-md);
  padding:12px 14px; margin-bottom:8px; box-shadow:var(--shadow);
  animation:entry-in 0.34s cubic-bezier(.3,.9,.3,1) both;
}
.entry:active{ transform:scale(0.985); transition:transform 0.1s; }
@keyframes entry-in{
  from{ opacity:0; transform:translateY(8px); }
  to{ opacity:1; transform:translateY(0); }
}
/* Stagger the first several so a list cascades in rather than popping at once.
   Capped low so a long history doesn't feel slow to appear. */
.entry:nth-child(1){ animation-delay:0s; }
.entry:nth-child(2){ animation-delay:0.03s; }
.entry:nth-child(3){ animation-delay:0.06s; }
.entry:nth-child(4){ animation-delay:0.09s; }
.entry:nth-child(5){ animation-delay:0.12s; }
.entry:nth-child(6){ animation-delay:0.15s; }
.entry:nth-child(n+7){ animation-delay:0.17s; }
.entry .dot{
  width:38px; height:38px; flex:0 0 auto; border-radius:12px;
  display:flex; align-items:center; justify-content:center; font-size:19px;
}
.entry.milk .dot{ background:var(--bottle-soft); }
.entry.food .dot{ background:var(--pea-soft); }
.entry.medicine .dot{ background:var(--card-2); }
.entry .body{ flex:1; min-width:0; }
.entry .title{ font-weight:600; font-size:15px; }
.entry .meta{ font-size:12.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.entry .time{ font-size:12.5px; color:var(--muted); flex:0 0 auto; }
.entry .del{
  flex:0 0 auto; border:none; background:none; color:var(--muted);
  font-size:16px; padding:6px; cursor:pointer; border-radius:8px;
}
.entry .del:active{ background:var(--card-2); }
.entry .body{ cursor:pointer; }
.entry .body:active{ opacity:0.6; }

.detail-row{
  display:flex; justify-content:space-between; gap:16px;
  padding:11px 0; border-bottom:1px solid var(--line);
}
.detail-row:last-of-type{ border-bottom:none; }
.detail-row .k{ font-size:13px; font-weight:700; color:var(--muted); flex:0 0 auto; }
.detail-row .v{ font-size:14px; text-align:right; word-break:break-word; }

/* ============ Nutrition panel (barcode lookups) ============ */
.nutri-panel{
  background:var(--card-2); border-radius:var(--radius-md);
  padding:14px; margin-bottom:16px;
}
.nutri-panel h4{
  margin:0 0 10px; font-size:13px; font-family:var(--font-display);
  font-weight:800;
}
.nutri-row{
  display:flex; align-items:center; gap:10px; margin-bottom:8px;
}
.nutri-row .n-label{ flex:1; font-size:13.5px; font-weight:600; }
.nutri-row .n-val{ font-size:13.5px; color:var(--muted); }
.n-pill{
  font-size:10.5px; font-weight:800; padding:3px 9px; border-radius:999px;
  text-transform:uppercase; letter-spacing:0.04em;
}
.n-pill.low{ background:var(--pea-soft); color:var(--pea); }
.n-pill.med{ background:var(--honey-soft); color:var(--honey); }
.n-pill.high{ background:var(--clay-soft); color:var(--clay); }
.nutri-note{
  font-size:11.5px; color:var(--muted); line-height:1.5;
  margin:10px 0 0; padding-top:10px; border-top:1px solid var(--line);
}
.nutri-additives{ font-size:12.5px; color:var(--muted); margin:8px 0 0; line-height:1.5; }

/* ============ Allergens ============ */
.tab-note{ font-size:13px; color:var(--muted); margin:10px 4px 14px; line-height:1.5; }
.allergen-row{
  display:flex; align-items:center; gap:12px;
  background:var(--card); border-radius:var(--radius-md);
  padding:13px 14px; margin-bottom:8px; box-shadow:var(--shadow);
  cursor:pointer;
}
.allergen-row .emoji{ font-size:20px; width:28px; text-align:center; }
.allergen-row .name{ flex:1; font-weight:600; font-size:15px; }
.status-pill{
  font-size:11.5px; font-weight:700; padding:5px 11px; border-radius:999px;
}
.status-pill.not_yet_tried{ background:var(--card-2); color:var(--muted); }
.status-pill.introduced{ background:var(--bottle-soft); color:var(--bottle); }
.status-pill.tolerated{ background:var(--pea-soft); color:var(--pea); }
.status-pill.reaction_noted{ background:var(--clay-soft); color:var(--clay); }

.status-legend-toggle{
  display:flex; align-items:center; gap:5px; width:100%;
  background:none; border:none; padding:0 2px 12px; text-align:left;
  font-size:13px; font-weight:600; color:var(--muted); cursor:pointer;
}
.status-legend{
  background:var(--card); border-radius:var(--radius-md); padding:12px 14px;
  margin-bottom:12px; box-shadow:var(--shadow);
}
.legend-row{
  display:flex; align-items:center; gap:10px; padding:7px 0;
  border-bottom:1px solid var(--line); font-size:13px; color:var(--muted);
}
.legend-row:last-child{ border-bottom:none; }
.legend-row .status-pill{ flex:0 0 auto; }

/* ============ Guidance ============ */
.guide-card{
  background:var(--card); border-radius:var(--radius-md);
  padding:16px; margin-bottom:12px; box-shadow:var(--shadow);
  border-left:4px solid var(--honey);
}
.guide-card h3{
  margin:0 0 6px; font-size:15.5px; font-family:var(--font-display);
}
.guide-card p{ margin:0 0 10px; font-size:14px; color:var(--text); line-height:1.55; }
.guide-card a{
  color:var(--honey); font-weight:600; font-size:13.5px; text-decoration:none;
}
/* 1.2: a link styled as a button ("Write a review" in Settings) keeps the
   button's colour and size, not the gold of a text link. */
.guide-card a.sign-out-btn{ color:var(--clay); font-size:14px; }
.disclaimer{
  font-size:12px; color:var(--muted); line-height:1.6;
  margin:16px 4px; text-align:center;
}
.email{ font-size:13px; color:var(--muted); word-break:break-all; margin:0 0 10px; }
.sign-out-btn{
  border:1.5px solid var(--line); background:none; color:var(--clay);
  font-weight:600; font-size:14px; border-radius:999px; padding:9px 18px; cursor:pointer;
}
.danger-btn{
  width:100%; margin-top:8px; border:1.5px solid var(--clay); background:none; color:var(--clay);
  font-weight:700; font-size:14px; border-radius:999px; padding:11px 18px; cursor:pointer;
  font-family:var(--font-ui);
}
.danger-btn:active{ background:var(--clay-soft); }
.settings-row{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:14px; }
.settings-row .lbl{ font-size:14px; font-weight:600; }
.settings-row .val{ color:var(--muted); font-size:13.5px; text-align:right; }

/* ============ Empty states ============ */
.empty{
  text-align:center; padding:36px 24px; color:var(--muted);
}
.empty .big{ font-size:44px; margin-bottom:8px; }
.empty p{ font-size:14px; margin:0 0 16px; line-height:1.55; }
.empty .primary{ width:auto; padding:12px 24px; }
/* Today with nothing logged yet: smaller, so Growth, Milestones, and
   Vaccinations below it are still on screen rather than pushed off it (1.1). */
.empty.compact{ padding:18px 24px 6px; }
.empty.compact .big{ font-size:30px; margin-bottom:4px; }

/* ============ Tiny Tummies Plus sheet ============ */
.plus-badge{
  display:inline-block; background:var(--honey); color:#fff;
  font-size:11px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase;
  padding:4px 10px; border-radius:999px; margin-bottom:10px;
}
.plus-feature{
  display:flex; gap:14px; align-items:flex-start;
  padding:14px 0; border-bottom:1px solid var(--line);
}
.plus-feature:last-child{ border-bottom:none; }
.plus-feature-emoji{ font-size:28px; flex:0 0 auto; line-height:1.2; }
.plus-feature-title{ font-size:15px; font-weight:700; color:var(--text); margin-bottom:3px; }
.plus-feature-body{ font-size:13px; color:var(--muted); line-height:1.5; }

/* ============ Milk schedule strip (Today) ============ */
.schedule-strip{ margin-bottom:16px; }
.schedule-label{
  font-size:12px; font-weight:700; color:var(--muted);
  text-transform:uppercase; letter-spacing:0.04em; margin:0 2px 8px;
}
.schedule-slots{
  display:flex; gap:8px; overflow-x:auto; padding-bottom:2px;
  -ms-overflow-style:none; scrollbar-width:none;
}
.schedule-slots::-webkit-scrollbar{ display:none; }
.schedule-slot{
  flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:2px;
  border:1px solid var(--line); background:var(--card); border-radius:var(--radius-md);
  padding:9px 14px; cursor:pointer; font-family:var(--font-ui);
  transition:transform 0.12s ease, background 0.15s ease;
}
.schedule-slot:active{ transform:scale(0.96); }
.slot-time{ font-size:14px; font-weight:700; color:var(--text); }
.slot-mark{ font-size:13px; color:var(--muted); }
.schedule-slot.done{ background:var(--pea-soft); border-color:transparent; }
.schedule-slot.done .slot-time{ color:var(--pea); }
.schedule-slot.done .slot-mark{ color:var(--pea); }
.schedule-slot.missed{ opacity:0.6; }

/* ============ Onboarding tour ============ */
.onboarding{
  position:fixed; inset:0; z-index:150;
  background:var(--bg);
  display:flex; flex-direction:column;
}
.onboarding.hidden{ display:none; }
.onboarding-skip{
  position:absolute; top:calc(14px + env(safe-area-inset-top)); right:18px; z-index:2;
  border:none; background:none; color:var(--muted); font-size:15px; font-weight:600;
  font-family:var(--font-ui); cursor:pointer; padding:6px 10px;
}
.onboarding-track{
  position:relative; flex:1; overflow:hidden;
}
.onboarding-slide{
  position:absolute; top:0; left:0; width:100%; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:0 36px; box-sizing:border-box;
  opacity:0; transform:translateX(30px);
  transition:opacity 0.3s ease, transform 0.3s cubic-bezier(.3,.9,.3,1);
  pointer-events:none;
}
.onboarding-slide.current{
  opacity:1; transform:translateX(0); pointer-events:auto;
}
.onboarding-slide.past{
  opacity:0; transform:translateX(-30px);
}
.onboarding-emoji{ font-size:82px; margin-bottom:24px; animation:splash-pulse 2.4s ease-in-out infinite; }
.onboarding-slide h2{
  font-family:var(--font-display); font-size:26px; font-weight:800;
  color:var(--text); margin:0 0 14px;
}
.onboarding-slide p{
  font-size:16px; line-height:1.6; color:var(--muted); margin:0; max-width:340px;
}
.onboarding-footer{
  padding:0 24px calc(28px + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; align-items:center; gap:20px;
}
.onboarding-dots{ display:flex; gap:8px; }
.onboarding-dot{
  width:8px; height:8px; border-radius:50%; background:var(--line);
  transition:background 0.2s, transform 0.2s;
}
.onboarding-dot.on{ background:var(--pea); transform:scale(1.25); }
.onboarding-next{ width:100%; max-width:360px; }

/* ============ Splash (covers the auth check) ============ */
/* 1.1: the same cot mobile as sign-in, shorter, and running from the first
   paint with no script. It finishes at 1.45s, and a signed-in splash stays
   1.5s so it's seen whole. It waits 0.25s before it drops, so
   a signed-out launch (where the splash goes as soon as the session check
   answers, usually sooner) cuts straight to the sign-in opening without
   showing the start of this one first. */
.splash{
  position:fixed; inset:0; z-index:200;
  display:flex; flex-direction:column;
  transition:opacity 0.4s ease;
}
.splash.hidden{ display:flex !important; opacity:0; pointer-events:none; }
.splash .scene{ width:100%; }
.splash .scene-glow{ animation:tt-fade 0.6s ease both; }
.splash .cm-drop{ animation:cm-drop 0.85s cubic-bezier(.25,.9,.3,1) 0.25s both; }
.splash .cm-spin{ animation:cm-spin-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-spin 40s linear 1.45s infinite; }
.splash .cm-face.f0{ animation:cm-face0-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-face0 40s linear 1.45s infinite; }
.splash .cm-face.f1{ animation:cm-face1-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-face1 40s linear 1.45s infinite; }
.splash .cm-face.f2{ animation:cm-face2-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-face2 40s linear 1.45s infinite; }
.splash .cm-face.f3{ animation:cm-face3-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-face3 40s linear 1.45s infinite; }
.splash .cm-face.f4{ animation:cm-face4-in 1.2s cubic-bezier(.15,.6,.3,1) 0.25s both, cm-face4 40s linear 1.45s infinite; }
.splash .cm-swing{ animation:cm-swing var(--sw) ease-in-out calc(var(--i) * -0.7s) infinite alternate; }
.splash .scene-name{ animation:tt-up 0.5s cubic-bezier(.2,.8,.2,1) 0.4s both; }
.splash .scene-sub{ animation:tt-up 0.5s cubic-bezier(.2,.8,.2,1) 0.5s both; }
.splash .scene-stars{ animation:tt-fade 0.8s ease 0.2s both, tt-twinkle 3.4s ease-in-out 1.2s infinite; }
@media (prefers-reduced-motion: reduce){
  .splash *{ animation:none !important; }
}

/* ============ Sheets & forms ============ */
.backdrop{
  position:fixed; inset:0; z-index:60; background:rgba(20,24,20,0.42);
  opacity:1; transition:opacity 0.22s;
}
.backdrop.hidden{ display:block !important; opacity:0; pointer-events:none; }
.sheet{
  position:fixed; left:0; right:0; bottom:0; z-index:70;
  background:var(--card); border-radius:var(--radius-lg) var(--radius-lg) 0 0;
  padding:10px 20px calc(22px + env(safe-area-inset-bottom));
  transform:translateY(105%); transition:transform 0.26s cubic-bezier(.3,.9,.3,1);
  max-height:88vh; overflow-y:auto;
  -ms-overflow-style:none; scrollbar-width:none;
}
.sheet::-webkit-scrollbar{ display:none; }
.sheet.open{ transform:translateY(0); }
.sheet-handle{
  position:relative;
  width:44px; height:5px; border-radius:3px; background:var(--line);
  margin:2px auto 12px; cursor:grab;
}
.sheet-handle:active{ cursor:grabbing; }
/* Bigger invisible grab zone around the thin handle for easy thumb targeting */
.sheet-handle::before{
  content:''; position:absolute; left:-60px; right:-60px; top:-14px; bottom:-14px;
}
.sheet h2{ font-size:20px; font-weight:800; margin:0 0 16px; }
.sheet-emoji{ font-size:18px; }
.sheet-note{
  font-size:12px; color:var(--muted); line-height:1.55;
  background:var(--clay-soft); border-radius:var(--radius-sm); padding:10px 12px;
}

.field{ display:block; margin-bottom:16px; }
.field > span{
  display:block; font-size:12.5px; font-weight:700; color:var(--muted);
  margin-bottom:7px;
}
.field > span em{ font-weight:500; font-style:normal; opacity:0.8; }
.field input[type="text"], .field input[type="date"],
.field input[type="datetime-local"], .field input[type="number"]{
  width:100%; padding:13px 14px; font-size:16px; color:var(--text);
  background:var(--card-2); border:1.5px solid transparent; border-radius:var(--radius-sm);
  font-family:var(--font-ui); appearance:none; -webkit-appearance:none;
}
.field input:focus{ outline:none; border-color:var(--pea); }

.input-with-button{ display:flex; gap:8px; }
.input-with-button input{ flex:1; }
.scan-btn{
  flex:0 0 52px; border:none; border-radius:var(--radius-sm);
  background:var(--card-2); cursor:pointer; padding:0;
  display:flex; align-items:center; justify-content:center;
  color:var(--muted);
}
.scan-btn svg{ width:23px; height:23px; display:block; }

.chip-row{ display:flex; gap:8px; overflow-x:auto; padding-bottom:2px; scrollbar-width:none; }
.chip-row::-webkit-scrollbar{ display:none; }
.chip-row.wrap{ flex-wrap:wrap; overflow:visible; }
.chip{
  flex:0 0 auto; padding:8px 14px; border-radius:999px; cursor:pointer;
  border:1.5px solid var(--line); background:var(--card); font-size:13.5px; font-weight:600;
}
.chip.on{ border-color:var(--pea); background:var(--pea-soft); color:var(--pea); }
.chip.suggested{
  border-color:var(--honey); box-shadow:0 0 0 1px var(--honey) inset;
  animation:chip-suggest-pulse 1.6s ease-in-out infinite;
}
@keyframes chip-suggest-pulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.65; } }
#milk-quick-chips{ margin-bottom:10px; }
#milk-quick-chips .chip.on{ border-color:var(--bottle); background:var(--bottle-soft); color:var(--bottle); }

.stepper-row{ display:flex; align-items:center; gap:10px; }
.stepper-row input{ flex:1; }
.stepper-row .unit{ font-size:14px; font-weight:700; color:var(--muted); }

.reaction-row{ display:flex; gap:8px; }
.reaction{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:12px 4px; font-size:24px; cursor:pointer;
  border:1.5px solid var(--line); border-radius:var(--radius-sm); background:var(--card);
}
.reaction small{ font-size:11.5px; font-weight:600; color:var(--muted); }
.reaction.on{ border-color:var(--pea); background:var(--pea-soft); }
.reaction.on small{ color:var(--pea); }

.status-options{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.status-option{
  padding:12px 8px; font-size:13.5px; font-weight:600; cursor:pointer;
  border:1.5px solid var(--line); border-radius:var(--radius-sm); background:var(--card);
}
.status-option.on{ border-color:var(--pea); background:var(--pea-soft); color:var(--pea); }

.primary{
  width:100%; padding:15px; border:none; border-radius:999px;
  background:var(--pea); color:var(--on-accent); font-size:16px; font-weight:700;
  font-family:var(--font-display); cursor:pointer;
  transition:transform 0.12s ease, opacity 0.12s ease;
}
.primary:active{ opacity:0.88; transform:scale(0.98); }
.primary.milk{ background:var(--bottle); }
.primary.food{ background:var(--pea); }
.primary:disabled{ opacity:0.5; }
.sign-out-btn, .chip, .child-chip{ transition:transform 0.12s ease, background 0.15s ease, color 0.15s ease; }
.sign-out-btn:active, .chip:active, .child-chip:active{ transform:scale(0.97); }

/* ============ Toast ============ */
#toast{
  position:fixed; left:50%; bottom:calc(96px + env(safe-area-inset-bottom));
  transform:translateX(-50%) translateY(0); z-index:110;
  background:var(--text); color:var(--bg);
  padding:11px 18px; border-radius:999px; font-size:14px; font-weight:600;
  max-width:86vw; text-align:center; box-shadow:0 6px 24px rgba(0,0,0,0.25);
  animation:toast-in 0.34s cubic-bezier(.34,1.56,.64,1);
  display:inline-flex; align-items:center; gap:14px;
}
.toast-undo{
  border:none; background:none; color:var(--honey); font-weight:800;
  font-size:14px; font-family:var(--font-ui); cursor:pointer; padding:2px 4px;
  flex:0 0 auto;
}
#toast.hidden{
  display:block !important;
  pointer-events:none;
  animation:toast-out 0.22s ease forwards;
}
/* Don't play the out-animation on first paint before the toast has ever shown */
#toast:not(.shown).hidden{ animation:none; opacity:0; }
@keyframes toast-in{
  from{ opacity:0; transform:translateX(-50%) translateY(16px) scale(0.95); }
  to{ opacity:1; transform:translateX(-50%) translateY(0) scale(1); }
}
@keyframes toast-out{
  from{ opacity:1; transform:translateX(-50%) translateY(0); }
  to{ opacity:0; transform:translateX(-50%) translateY(10px); }
}

/* ============ Barcode scanning ============ */
body.scanner-active{ background:transparent !important; }
body.scanner-active #app, body.scanner-active .sheet, body.scanner-active .backdrop{ display:none !important; }
#scan-overlay{
  position:fixed; inset:0; z-index:120;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:18px;
}
#scan-frame-group{ display:flex; flex-direction:column; align-items:center; gap:18px; }
.scan-frame{
  width:72vw; max-width:300px; aspect-ratio:1.4;
  border:3px solid rgba(255,255,255,0.9); border-radius:20px;
  box-shadow:0 0 0 100vmax rgba(0,0,0,0.35);
}
.scan-hint{ color:#fff; font-size:14px; font-weight:600; text-shadow:0 1px 4px rgba(0,0,0,0.5); margin:0; }
.scan-cancel{
  border:none; background:rgba(255,255,255,0.92); color:#222;
  font-size:15px; font-weight:700; padding:12px 28px; border-radius:999px; cursor:pointer;
}

.scan-result-card{
  width:84vw; max-width:340px; background:var(--card); border-radius:var(--radius-lg);
  padding:24px 20px 20px; text-align:center; box-shadow:0 12px 40px rgba(0,0,0,0.3);
}
.scan-loading{ color:var(--muted); font-size:14px; margin:0; }
.scan-result-name{ font-family:var(--font-display); font-size:19px; font-weight:800; margin-bottom:6px; }
.scan-result-sub{ color:var(--muted); font-size:13.5px; margin:0 0 18px; line-height:1.5; }
.scan-result-actions{ display:flex; gap:8px; margin-bottom:10px; }
.scan-again-btn, .scan-log-btn{
  flex:1; border:none; border-radius:999px; padding:12px 8px; font-size:13.5px; font-weight:700; cursor:pointer;
  font-family:var(--font-ui);
}
.scan-again-btn{ background:var(--card-2); color:var(--text); }
.scan-log-btn{ background:var(--pea); color:var(--on-accent); }
.scan-done-btn{
  border:none; background:none; color:var(--muted); font-size:13px;
  font-weight:600; padding:6px; cursor:pointer; font-family:var(--font-ui);
}

/* ============ A11y & motion ============ */
:focus-visible{ outline:2px solid var(--pea); outline-offset:2px; }
@media (prefers-reduced-motion: reduce){
  *{ transition:none !important; animation:none !important; }
}
/* 1.1 UAT (A7): the same, from the iPhone's own setting. The app's web view
   on the phone doesn't report the media query, so Swift passes the setting
   on and applyReduceMotion() sets this class. */
html.reduce-motion *{ transition:none !important; animation:none !important; }


/* ============ Product lookup results ============ */
.lookup-list{ display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.lookup-hit{
  display:flex; flex-direction:column; align-items:flex-start; gap:2px;
  text-align:left; width:100%; border:1px solid var(--line); background:var(--card);
  border-radius:var(--radius-sm); padding:11px 14px; cursor:pointer;
}
.lookup-hit:active{ background:var(--card-2); }
.lookup-hit-name{ font-size:14px; font-weight:600; color:var(--text); }
.lookup-hit-brand{ font-size:12px; color:var(--muted); }


.hist-search{
  width:100%; margin-bottom:10px; padding:10px 14px; border-radius:999px;
  border:1px solid var(--line); background:var(--card); font-size:14px;
  font-family:var(--font-ui); color:var(--text); box-sizing:border-box;
}
.hist-first-tried{
  font-size:13px; font-weight:600; color:var(--pea); margin:0 0 10px; padding:8px 12px;
  background:var(--pea-soft); border-radius:var(--radius-sm);
}
/* One line per matching food, under the spoon. */
.hist-first-tried span{ display:block; }
.hist-first-tried span:first-of-type{ display:inline; }
.hist-first-tried .more{ font-weight:600; opacity:0.8; }

/* ============ History filters ============ */
/* 1.1: History's week strip. */
.hist-week{
  display:flex; align-items:center; justify-content:space-between;
  margin:0 2px 6px; font-size:13px; font-weight:700;
}
.hist-week-btn{
  width:32px; height:32px; border-radius:50%; border:none; padding:0;
  background:var(--card); box-shadow:var(--shadow); color:var(--text);
  font-size:20px; line-height:1; cursor:pointer;
}
.hist-week-btn:disabled{ opacity:0.3; cursor:default; }
.hist-strip{ display:flex; gap:4px; margin-bottom:12px; touch-action:pan-y; }
.hist-day{
  flex:1; min-width:0; border:none; background:transparent; border-radius:14px;
  padding:6px 0 5px; display:flex; flex-direction:column; align-items:center; gap:1px;
  font-family:var(--font-ui); font-size:11px; color:var(--muted); cursor:pointer;
}
.hist-day b{ font-size:17px; font-weight:700; color:var(--text); }
.hist-day i{ width:5px; height:5px; border-radius:3px; background:var(--pea); margin-top:2px; }
.hist-day i.none{ background:transparent; }
.hist-day.on{ background:var(--pea); color:rgba(255,255,255,0.85); }
.hist-day.on b{ color:#fff; }
.hist-day.on i{ background:#fff; }

/* 1.1: the records card on Today (Milestones and Vaccinations), and the
   Vaccinations sheet. */
.records-card{ padding:4px 0; margin-top:16px; overflow:hidden; }
.rec-row{
  width:100%; display:flex; align-items:center; gap:12px; padding:11px 16px;
  border:none; background:none; font-family:inherit; text-align:left; cursor:pointer; color:var(--text);
}
.rec-row + .rec-row{ border-top:1px solid var(--line); }
.rec-row .e{ font-size:20px; flex:0 0 auto; }
.rec-row .tx{ flex:1; min-width:0; font-size:14.5px; font-weight:700; }
.rec-row .tx small{ display:block; font-size:12.5px; font-weight:500; color:var(--muted); margin-top:1px; }
.rec-row .side{ font-size:12px; font-weight:600; color:var(--muted); }
.rec-row .chev{ color:var(--muted); font-size:18px; }
.vx-card{ background:var(--card-2); border-radius:var(--radius-md); padding:12px 14px; margin-bottom:8px; }
.vx-card.due{ box-shadow:inset 0 0 0 2px var(--honey-soft); background:var(--card); }
.vx-head{ display:flex; justify-content:space-between; align-items:center; gap:8px; margin-bottom:4px; }
.vx-head b{ font-size:15px; }
.vx-pill{ font-size:11.5px; font-weight:700; padding:3px 9px; border-radius:999px; white-space:nowrap; }
.vx-pill.given{ background:var(--pea-soft); color:var(--pea); }
.vx-pill.part{ background:var(--pea-soft); color:var(--pea); }
.vx-pill.due{ background:var(--honey-soft); color:var(--honey); }
.vx-pill.upcoming{ background:var(--card); color:var(--muted); }
.vx-doses{ font-size:13px; line-height:1.6; }
.vx-doses a{ color:var(--bottle); text-decoration:none; }
.vx-doses .missing{ color:var(--muted); }
.vx-act{
  margin-top:8px; border:none; border-radius:12px; padding:9px 12px; width:100%;
  font-family:inherit; font-size:13.5px; font-weight:700; cursor:pointer;
  background:var(--card); color:var(--text);
}
.vx-card.due .vx-act{ background:var(--pea); color:#fff; }
.vx-note{ font-size:12px; color:var(--muted); line-height:1.5; margin:6px 0 0; }
.vx-dose-row{
  display:flex; align-items:center; gap:12px; padding:11px 2px;
  border-bottom:1px solid var(--line); font-size:15px; font-weight:600; cursor:pointer;
}
.vx-dose-row input{ width:20px; height:20px; flex:0 0 auto; accent-color:var(--pea); }

.hist-filter-bar{
  display:flex; gap:6px; overflow-x:auto; margin-bottom:10px; padding-bottom:2px;
  -webkit-overflow-scrolling:touch;
}
.hist-filter-bar::-webkit-scrollbar{ display:none; }
.hist-chip{
  flex:0 0 auto; border:1px solid var(--line); background:var(--card);
  border-radius:999px; padding:7px 13px; font-size:12.5px; font-weight:600;
  font-family:var(--font-ui); color:var(--muted); cursor:pointer; white-space:nowrap;
}
.hist-chip.on{ background:var(--pea); color:#fff; border-color:var(--pea); }
.hist-select{
  width:100%; margin-bottom:12px; padding:10px 12px; border-radius:var(--radius-sm);
  border:1px solid var(--line); background:var(--card); font-size:13.5px;
  font-family:var(--font-ui); color:var(--text);
}


/* ---------------------------------------------------------------------
   Composition bar for "What's actually in this".
   Built only from the macronutrients declared on the pack by law, so it
   sums to 100g with no estimated figures. Sugars are called out in text
   rather than as a segment, because they sit inside carbohydrate and a
   segment would double-count them.
   --------------------------------------------------------------------- */
.comp-bar{
    display:flex; width:100%; height:14px; border-radius:7px; overflow:hidden;
    background:var(--bottle-soft, #eef2f6); margin:2px 0 10px;
}
.comp-bar span{ display:block; height:100%; }
.comp-bar span:first-child{ border-radius:7px 0 0 7px; }
.comp-bar span:last-child{ border-radius:0 7px 7px 0; }

.comp-legend{ display:flex; flex-wrap:wrap; gap:6px 14px; margin:0 0 10px; }
.comp-key{ display:inline-flex; align-items:center; font-size:12px; color:var(--muted); }
.comp-key i{
    width:9px; height:9px; border-radius:50%; margin-right:5px; flex:none;
}

.nutri-details{ margin:6px 0 0; }
.nutri-details summary{
    font-size:12.5px; color:var(--bottle, #4a86c5); cursor:pointer;
    padding:3px 0; list-style:none;
}
.nutri-details summary::-webkit-details-marker{ display:none; }
.nutri-details summary:before{ content:'▸ '; }
.nutri-details[open] summary:before{ content:'▾ '; }
.nutri-details p{
    font-size:12.5px; line-height:1.5; color:var(--muted);
    margin:4px 0 0; padding:8px 10px; background:rgba(0,0,0,.03);
    border-radius:8px; word-break:break-word;
}

/* The two lines that stay visible in the food panel: they carry the weight, so
   they read as content rather than footnotes. */
.nutri-key{
    font-size:13px; line-height:1.5; color:var(--text, #22322B);
    margin:0 0 7px;
}
.nutri-key strong{ color:var(--ink, #1b2b23); }
.nutri-aside{ color:var(--muted); }

/* "Show the full label" collapses everything reference-grade, so the product
   name stays on screen. */
.nutri-more{ margin:4px 0 8px; }
.nutri-more > div{ padding-top:4px; }

/* Salt note in the food sheet. Deliberately quiet: it reports what guidance
   says and must never read as a telling-off. */
.salt-note{
    font-size:12px; line-height:1.45; color:var(--muted);
    margin:6px 0 0; padding:8px 10px;
    background:rgba(217,124,124,.08);
    border-radius:8px;
}

/* The "this is not advice" card at the top of Guidance. */
.guide-card.guide-intro{
    background:var(--bottle-soft, #eef2f6);
}
.guide-card.guide-intro p{ font-size:13px; line-height:1.5; }

/* =====================================================================
   Colour themes (Tiny Tummies Plus)
   =====================================================================
   Set on <html data-theme="..."> from app.js, read from the person's own
   user_metadata, so each member of a household picks their own.

   What a theme changes: the base tones and the brand accent. What it
   deliberately does NOT change: green for food, blue for milk, clay for
   allergens. Those are colour coding rather than decoration, and a parent
   who has learned that blue means milk should not have to relearn it because
   they liked a different background.

   Every theme defines both a light and a dark variant. Skipping dark would
   leave a themed app unreadable at 3am, which is when it is most used.
   ===================================================================== */

/* --- Slate: cooler, greyer, less green --- */
[data-theme="slate"]{
  --bg:#e9eef6;
  --card:#fbfcfe;
  --card-2:#d6dfec;
  --line:rgba(40,46,56,0.10);
  --text:#2b313a;
  --muted:#59616b;
  --honey:#5b7b9a;
  --honey-soft:#e4ebf2;
}
@media (prefers-color-scheme: dark){
  [data-theme="slate"]{
    --bg:#191b1f;
    --card:#24272d;
    --card-2:#2d3138;
    --line:rgba(240,244,250,0.09);
    --text:#e6e9ee;
    --muted:#939aa6;
    --honey:#83a3c2;
    --honey-soft:#22303c;
  }
}
/* 1.1: the same palette when the night look is on by the clock (data-night). */
:root[data-theme="slate"][data-night]{
    --bg:#191b1f;
    --card:#24272d;
    --card-2:#2d3138;
    --line:rgba(240,244,250,0.09);
    --text:#e6e9ee;
    --muted:#939aa6;
    --honey:#83a3c2;
    --honey-soft:#22303c;
  }


/* --- Blush: warm pink, softer --- */
[data-theme="blush"]{
  --bg:#fbecea;
  --card:#fffaf9;
  --card-2:#f5d8d3;
  --line:rgba(70,45,45,0.10);
  --text:#3a2e2d;
  --muted:#6c5e5d;
  --honey:#c0687c;
  --honey-soft:#f8e5e9;
}
@media (prefers-color-scheme: dark){
  [data-theme="blush"]{
    --bg:#201b1b;
    --card:#2c2525;
    --card-2:#362d2d;
    --line:rgba(255,245,244,0.09);
    --text:#eee3e1;
    --muted:#a49694;
    --honey:#d68a9b;
    --honey-soft:#3a2830;
  }
}
/* 1.1: the same palette when the night look is on by the clock (data-night). */
:root[data-theme="blush"][data-night]{
    --bg:#201b1b;
    --card:#2c2525;
    --card-2:#362d2d;
    --line:rgba(255,245,244,0.09);
    --text:#eee3e1;
    --muted:#a49694;
    --honey:#d68a9b;
    --honey-soft:#3a2830;
  }


/* --- Dusk: deep indigo, calmest at night --- */
[data-theme="dusk"]{
  --bg:#eeeaf9;
  --card:#fcfbff;
  --card-2:#ddd7f2;
  --line:rgba(45,42,66,0.10);
  --text:#2f2c40;
  --muted:#5f5c72;
  --honey:#6f63a8;
  --honey-soft:#e9e6f5;
}
@media (prefers-color-scheme: dark){
  [data-theme="dusk"]{
    --bg:#1a1922;
    --card:#25232f;
    --card-2:#2e2b3a;
    --line:rgba(245,244,255,0.09);
    --text:#e8e5f0;
    --muted:#9893ac;
    --honey:#9a8fd4;
    --honey-soft:#2b2740;
  }
}
/* 1.1: the same palette when the night look is on by the clock (data-night). */
:root[data-theme="dusk"][data-night]{
    --bg:#1a1922;
    --card:#25232f;
    --card-2:#2e2b3a;
    --line:rgba(245,244,255,0.09);
    --text:#e8e5f0;
    --muted:#9893ac;
    --honey:#9a8fd4;
    --honey-soft:#2b2740;
  }


/* =====================================================================
   Collapsible settings sections
   =====================================================================
   Settings reached nine cards and will keep growing, so the whole tab had
   become a long scroll past things nobody was looking for. Each card is
   turned into a <details> at render time by makeSettingsCollapsible(), which
   means no card has to know about this and new ones get it for free.

   Native <details> rather than a custom control: iOS animates it, it is
   keyboard and screen reader accessible without any work, and it survives
   the tab being re-rendered.
   ===================================================================== */

.guide-card > summary{
  list-style:none;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  font-family:var(--font-display);
  font-size:17px;
  font-weight:700;
  color:var(--text);
  padding:2px 0;
  -webkit-tap-highlight-color:transparent;
}
.guide-card > summary::-webkit-details-marker{ display:none; }

/* A chevron that turns, rather than the default triangle, which looks like a
   browser control rather than part of the app. */
.guide-card > summary::after{
  content:"";
  width:9px; height:9px;
  border-right:2px solid var(--muted);
  border-bottom:2px solid var(--muted);
  transform:rotate(45deg);
  margin-right:4px;
  transition:transform .18s ease;
  flex:0 0 auto;
}
.guide-card[open] > summary::after{ transform:rotate(-135deg); }

/* The heading is now inside the summary, so its own margins would push the
   chevron out of line. */
.guide-card > summary h3{ margin:0; font-size:inherit; }

.guide-card[open] > summary{ margin-bottom:12px; }

/* =====================================================================
   Email sign-in panel
   =====================================================================
   The .field style is built for sheets, where inputs sit on a card against
   a left-aligned label. On the sign-in screen that reads as a form dropped
   into the middle of a landing page: a narrow white box beside two
   full-width pills.

   Matched to the buttons instead: same width, same pill radius, same
   vertical rhythm, centred like everything else on the screen.
   ===================================================================== */

#email-sign-in-panel{ text-align:center; }

#email-sign-in-panel .field{
  display:block;
  margin:0 0 10px;
}
#email-sign-in-panel .field > span{
  display:block;
  text-align:center;
  font-size:13px;
  color:var(--muted);
  margin:0 0 8px;
  font-weight:600;
}
#email-sign-in-panel input{
  width:100%;
  padding:15px 18px;
  border:1px solid var(--line);
  border-radius:999px;
  background:var(--card);
  color:var(--text);
  font-family:var(--font-ui);
  font-size:16px;              /* 16px or iOS zooms the page on focus */
  text-align:center;
  box-sizing:border-box;
  -webkit-appearance:none;
}
#email-sign-in-panel input:focus{
  outline:none;
  border-color:var(--pea);
}
/* The code, spaced out so six digits are easy to check against the email. */
#email-sign-in-panel #otp-code{
  letter-spacing:6px;
  font-weight:700;
  font-size:20px;
}
#otp-status{ text-align:center; }

/* Hide scrollbars everywhere.
   
   Apple's guidelines do not require a visible scroll indicator, and iOS itself
   shows one only briefly while scrolling. A persistent webview scrollbar is a
   browser artefact rather than a platform convention, and it makes the app
   look like a web page. Scrolling still works exactly as before; only the
   indicator is hidden. */
*::-webkit-scrollbar{ width:0; height:0; display:none; }
*{ scrollbar-width:none; -ms-overflow-style:none; }


/* Nappies: honey, the one accent not already meaning something on this row.
   Milk is blue, food green, sickness clay, medicine neutral. */
.quick-actions .log-nappy{ background:var(--nappy-soft); color:var(--nappy-ink); }

.nappy-choices{ display:grid; grid-template-columns:repeat(3, 1fr); gap:10px; margin-top:6px; }
.nappy-choices button{
  border:none; border-radius:var(--radius-md); background:var(--card-2);
  padding:18px 4px 14px; cursor:pointer; font-family:var(--font-display);
  font-size:14px; font-weight:700; color:var(--text);
  display:flex; flex-direction:column; align-items:center; gap:6px;
}
.nappy-choices .ne{ font-size:30px; line-height:1; }
.nappy-choices button:active{ transform:scale(0.97); background:var(--nappy-soft); }
.nappy-choices button.on{ background:var(--nappy-soft); box-shadow:inset 0 0 0 2px var(--nappy); }

/* "Wet and dirty" puts two emoji in a dot built for one, so it is shrunk to fit. */
.entry.nappy .dot{ background:var(--nappy-soft); display:flex; align-items:center; justify-content:center; }
/* Each emoji in its own box, centred on its own middle. Negative letter
   spacing pushed the pair right and let the droplet ride higher than the poo. */
.entry.nappy .dot span{ display:block; line-height:1; }
.entry.nappy .dot.pair{ font-size:15px; gap:1px; }
/* An empty date input on iOS has no text to give it height, so it collapsed to
   a thin bar beside the full-height text fields. */
.field input[type="date"],
.field input[type="datetime-local"]{
  min-height:44px; display:block; width:100%; box-sizing:border-box;
}

/* Nappies keep their honey in every theme, the way milk stays blue and food
   stays green. --honey is the theme accent and changes with the theme. */
:root{ --nappy:#c98f2d; --nappy-soft:rgba(201,143,45,0.16); }
/* Honey text on the honey tint was 2.3 to 1, the hardest label on Today to
   read; the deeper ink is 4.7 to 1. In the dark, the honey itself already
   reads clearly, so it stays (1.1). */
:root{ --nappy-ink:#845e1e; }
@media (prefers-color-scheme: dark){ :root{ --nappy-ink:var(--nappy); } }
/* 1.1: the same palette when the night look is on by the clock (data-night). */
:root[data-night]{ --nappy-ink:var(--nappy); }


/* =====================================================================
   Today, built for 3am (1.1 UI review)

   Three fixed zones: Now at the top, the day in the middle, and the log
   buttons docked above the tab bar where a thumb reaches while holding a
   baby. Cards that need attention never push the buttons around again.
   ===================================================================== */

/* Now: the last feed, nappy, and medicine, readable at arm's length. */
.now-panel{
  background:var(--card); border-radius:var(--radius-md); box-shadow:var(--shadow);
  padding:6px 16px; margin-bottom:12px; border-left:4px solid var(--kid, var(--pea));
}
.now-row{ display:flex; align-items:center; gap:12px; padding:9px 0; }
.now-row + .now-row{ border-top:1px solid var(--line); }
.now-e{ font-size:22px; line-height:1; flex:0 0 26px; text-align:center; }
.now-main{ display:flex; flex-direction:column; min-width:0; flex:1 1 auto; }
.now-k{ font-size:12px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:0.05em; }
.now-ago{ font-family:var(--font-display); font-size:21px; font-weight:800; line-height:1.15; font-variant-numeric:tabular-nums; white-space:nowrap; }
.now-detail{ margin-left:auto; text-align:right; font-size:14px; font-weight:700; color:var(--text); min-width:0; flex:0 1 46%; }
.now-detail small{ display:block; font-size:12px; font-weight:600; color:var(--muted); margin-top:2px; }
/* Who logged it, in a shared household (the old "Latest for" card's job). */
.now-by{ font-weight:600; color:var(--muted); white-space:nowrap; }
/* All children: each child's name over their own Today tile. */
.all-child + .all-child{ margin-top:16px; }
.all-child-name{ font-family:var(--font-display); font-size:16px; font-weight:800; margin:0 2px 8px; }
.all-child-name i{ display:inline-block; width:9px; height:9px; border-radius:50%; background:var(--kid); margin-right:7px; vertical-align:1px; }
.all-child-empty{ margin:4px 0; font-size:14px; color:var(--muted); }

/* One card that needs you; the rest wait behind "+2 more". */
.needs-you > .card, .needs-you > .guide-card, .needs-you > div{ margin-bottom:10px; }
.needs-more{ margin:0 2px 8px; }
.needs-more > summary{
  list-style:none; cursor:pointer; font-size:13.5px; font-weight:700; color:var(--muted);
  padding:8px 4px; min-height:44px; display:flex; align-items:center;
}
.needs-more > summary::-webkit-details-marker{ display:none; }
.needs-more > summary::after{ content:" \203A"; margin-left:4px; }
.needs-more[open] > summary::after{ content:""; }
.needs-more[open] > summary{ margin-bottom:6px; }

/* The day so far, with its totals on the same line as the heading. */
#tab-today .day-label{ display:flex; justify-content:space-between; align-items:baseline; gap:10px; flex-wrap:wrap; }
.day-totals{ text-transform:none; letter-spacing:0; font-weight:700; color:var(--text); font-size:13px; }

/* Entries open on a tap anywhere on the row. */
.entry{ cursor:pointer; }

/* Records: one row, opening a sheet. */
.records-row{
  width:100%; display:flex; align-items:center; gap:12px; margin:16px 0 12px; padding:14px 16px;
  border:none; border-radius:var(--radius-md); background:var(--card); box-shadow:var(--shadow);
  font-family:inherit; text-align:left; cursor:pointer; color:var(--text); min-height:56px;
}
.records-row .e{ font-size:20px; flex:0 0 auto; }
.records-row .tx{ flex:1; min-width:0; font-size:15px; font-weight:800; font-family:var(--font-display); }
.records-row .tx small{ display:block; font-size:12.5px; font-weight:600; color:var(--muted); margin-top:1px; font-family:var(--font-ui); }
.records-row .chev{ color:var(--muted); font-size:20px; }
#sheet-records .records-card{ margin-top:4px; border-left:none; }

/* Log: a tray docked at the bottom that runs down behind the floating tab
   bar (z-index 50, about 70pt tall with its gap), so nothing shows through
   between the two. */
.today-dock{
  position:fixed; left:0; right:0; bottom:0; z-index:45;
  display:flex; flex-direction:column; gap:8px;
  padding:10px 12px calc(84px + env(safe-area-inset-bottom));
  border-radius:24px 24px 0 0; box-shadow:0 -4px 18px rgba(47,58,52,0.10);
  background:var(--bg); /* fallback for iOS 15.x */
  background:color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
}
.today-dock .quick-actions{ margin:0; }
.dock-spacer{ height:120px; }
.dock-top{
  width:100%; min-height:48px; border:none; border-radius:var(--radius-md);
  background:var(--bottle); color:var(--on-accent);
  font-family:var(--font-display); font-size:16px; font-weight:800; cursor:pointer;
  box-shadow:var(--shadow);
}
/* Text colour, not the milk blue: blue on its own tint is 3.5 to 1 in light mode. */
.dock-top.breast{ background:var(--bottle-soft); color:var(--text); }
.dock-top:active{ transform:scale(0.98); }
/* Both feeds side by side, for a baby who has bottles and breastfeeds. */
.dock-top-row{ display:flex; gap:8px; }
.dock-top-row .dock-top{ flex:1 1 0; min-width:0; font-size:15px; line-height:1.15; padding:6px 8px; }
.dock-top small{ display:block; font-family:var(--font-ui); font-size:12px; font-weight:700; opacity:0.85; margin-top:1px; }
.dock-top:disabled{ opacity:0.6; }
body.kb-open .today-dock{ display:none; }
/* The toast rises above the dock on Today, so it never covers a button. */
body.on-today #toast{ bottom:calc(var(--dock-h, 230px) + 10px); }

/* 1.1: on a long sheet, the save button stays in view at the bottom instead
   of below the notes, reminders, and allergen chips most people skip. */
.sheet .primary[id^="save-"]{
  /* bottom:0, not the home-bar allowance: the sheet's own bottom padding
     already clears the home bar, and adding it twice made the button ride
     up over the last row, hiding the 4 hours reminder pill (1.1 UAT). */
  position:sticky; bottom:0; z-index:2;
  box-shadow:0 -6px 16px var(--card), 0 4px 14px rgba(0,0,0,0.12);
}
/* While the keyboard is up the sheet is short, so a pinned button covered
   the box being typed in (the name sheet, 1.1 UAT). It goes back in line. */
body.kb-open .sheet .primary[id^="save-"]{ position:static; box-shadow:none; }
/* On the smallest iPhones the detail goes under the time, not beside it. */
@media (max-width:360px){
  .now-row{ flex-wrap:wrap; row-gap:2px; }
  .now-detail{ flex:1 0 100%; margin-left:38px; text-align:left; }
  .now-detail small{ display:inline; margin-left:6px; }
}

/* =====================================================================
   Frosted look, iOS 26 style (1.1, from the approved concept)

   --glass is the frosted fill. It sits in front of a blur, so the content
   scrolling underneath shows through softly; a thin light edge on top
   gives the glass its rim. Without backdrop-filter (very old WebKit) the
   colour-mix fallback is a near-solid fill, as before.
   ===================================================================== */
:root{
  /* 1.1 UAT: 62% let too much show through behind the tab labels. */
  --glass:color-mix(in srgb, var(--card) 82%, transparent);
  --glass-edge:rgba(255,255,255,0.7);
  --glass-shadow:0 8px 24px rgba(47,58,52,0.16);
}
@media (prefers-color-scheme: dark){ :root{ --glass-edge:rgba(255,245,230,0.14); --glass-shadow:0 8px 24px rgba(0,0,0,0.45); } }
:root[data-night]{ --glass-edge:rgba(255,245,230,0.14); --glass-shadow:0 8px 24px rgba(0,0,0,0.45); }

.viewtabs-bar{
  background:var(--card);
  background:var(--glass);
  -webkit-backdrop-filter:blur(30px) saturate(180%); backdrop-filter:blur(30px) saturate(180%);
  border:1px solid var(--glass-edge);
  box-shadow:var(--glass-shadow), inset 0 1px 0 var(--glass-edge);
  transition:right 0.5s cubic-bezier(.32,.72,0,1);
}
.today-dock{
  background:var(--bg);
  background:color-mix(in srgb, var(--bg) 70%, transparent);
  -webkit-backdrop-filter:blur(20px) saturate(170%); backdrop-filter:blur(20px) saturate(170%);
  border-top:1px solid var(--glass-edge);
}

/* Tucked: only the tab you're on, at the left. Tapping it brings the rest
   back (wireTabBarTuck). Never on Today, where the dock sits above it. */
/* 1.1 UAT: this used to snap, because right:auto and display:none can't
   animate. Now the bar's right edge slides in to a fixed pill width while
   the other tabs shrink and fade, all on the same easing, so it reads as
   one smooth movement both ways. */
.viewtabs{ transition:gap 0.5s cubic-bezier(.32,.72,0,1); }
/* Labels are clipped only while tucked: on a 320-wide phone "Guidance" is a
   little wider than its tab and clipping cut it off. Coming back, the labels
   wait 0.2s to fade in, so they don't spill out while the tabs regrow. */
.viewtab{ transition:color 0.2s ease, background 0.2s ease, flex-grow 0.5s cubic-bezier(.32,.72,0,1), opacity 0.3s ease 0.2s, padding 0.5s cubic-bezier(.32,.72,0,1); }
body.tabs-mini .viewtabs-bar{ right:calc(100vw - 12px - 112px); }
body.tabs-mini .viewtabs{ gap:0; }
body.tabs-mini .viewtab:not(.active){ overflow:hidden; flex-grow:0; flex-basis:0; padding-left:0; padding-right:0; opacity:0; pointer-events:none; transition-delay:0s; }
@media (prefers-reduced-motion: reduce){ .viewtabs-bar, .viewtabs, .viewtab{ transition:none; } }

/* The header group: Reminders, Search, and on Foods the scanner. */
.hdr-capsule{
  display:flex; gap:2px; padding:3px; border-radius:999px; flex:0 0 auto;
  background:var(--card);
  background:var(--glass);
  -webkit-backdrop-filter:blur(20px) saturate(170%); backdrop-filter:blur(20px) saturate(170%);
  border:1px solid var(--glass-edge);
  box-shadow:var(--glass-shadow), inset 0 1px 0 var(--glass-edge);
}
.hdr-btn{
  /* 44 points: Apple's smallest comfortable tap, for one thumb at 3am. */
  position:relative; width:44px; height:44px; border-radius:50%; border:none; background:transparent;
  color:var(--text); display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
}
.hdr-btn svg{ width:21px; height:21px; display:block; }
.hdr-btn:active{ background:var(--card-2); }
.hdr-badge{
  position:absolute; top:4px; right:3px; min-width:17px; height:17px; padding:0 4px; border-radius:9px;
  background:var(--nappy-ink); color:var(--bg); font-size:10.5px; font-weight:800; line-height:17px; text-align:center;
  font-family:var(--font-display);
}

/* Reminders and Search sheets. */
.rem-grp{ font-size:12px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:0.06em; margin:16px 2px 8px; }
.rem-row{ display:flex; align-items:center; gap:12px; background:var(--card-2); border-radius:var(--radius-md); padding:11px 14px; margin-bottom:8px; min-height:56px; }
.rem-e{ font-size:20px; flex:0 0 auto; }
.rem-tx{ flex:1; min-width:0; font-weight:700; font-size:15px; }
.rem-tx small{ display:block; font-weight:600; font-size:13px; color:var(--muted); margin-top:1px; }
.rem-act{ flex:0 0 auto; border:1.5px solid var(--line); background:var(--card); color:var(--text); border-radius:999px; padding:8px 14px; min-height:44px; font:700 14px var(--font-ui); cursor:pointer; }
.rem-note{ font-size:13.5px; color:var(--muted); line-height:1.5; margin:12px 2px 4px; }
/* The search box with the scanner beside it, the same height. */
.search-row{ display:flex; align-items:center; gap:8px; margin-bottom:10px; }
.search-row .hist-search{ flex:1; min-width:0; margin-bottom:0; min-height:44px; }
.search-scan-btn{
  flex:0 0 auto; width:44px; height:44px; border-radius:50%; padding:0; cursor:pointer;
  border:1px solid var(--line); background:var(--card); color:var(--text);
  display:flex; align-items:center; justify-content:center;
}
.search-scan-btn svg{ width:22px; height:22px; display:block; }
.search-scan-btn:active{ transform:scale(0.94); }
/* Foods: how many of the 14 have been tried. A count, never a verdict. */
.allergen-progress{ margin:0 2px 14px; }
.allergen-progress p{ margin:0 0 6px; font-size:14px; font-weight:700; color:var(--text); }
.allergen-progress-bar{ height:6px; border-radius:3px; background:var(--card-2); overflow:hidden; }
.allergen-progress-bar span{ display:block; height:100%; border-radius:3px; background:var(--pea); }
.search-day{ font-size:12px; font-weight:700; color:var(--muted); margin:10px 4px 4px; }
#search-results .entry{ margin-bottom:4px; }
/* One line per food or medicine, opening to its dated entries. */
.search-group{ width:100%; border:none; text-align:left; cursor:pointer; font-family:var(--font-ui); color:var(--text); }
.search-group .chev{ margin-left:auto; color:var(--muted); font-size:20px; transition:transform .2s; }
.search-group[aria-expanded="true"] .chev{ transform:rotate(90deg); }
.search-group-list{ margin:0 0 10px 12px; }
.search-product{ width:100%; border:1px dashed var(--line); text-align:left; cursor:pointer; font-family:var(--font-ui); color:var(--text); margin-top:12px; }

/* 1.1.1: Siri and Shortcuts sheet. */
.siri-group{ margin-bottom:14px; }
.siri-group-title{ font-size:12.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); margin:0 0 6px; }
.siri-row{ background:var(--card); border:1px solid var(--line); border-radius:var(--radius-sm); padding:10px 14px; margin-bottom:6px; }
.siri-say{ font-size:15px; font-weight:600; color:var(--text); }
.siri-note{ font-size:12.5px; color:var(--muted); margin-top:2px; }
.siri-shortcuts-link{ display:block; width:100%; text-align:center; text-decoration:none; box-sizing:border-box; }

/* =====================================================================
   1.2: iPhone Duo and wide screens
   ===================================================================== */
/* The Duo can put system controls down one side, so the left and right
   insets differ and are no longer zero. Each side is padded on its own. */
header{ padding-left:calc(20px + env(safe-area-inset-left)); padding-right:calc(20px + env(safe-area-inset-right)); }
.chips-bar{ padding-left:calc(20px + env(safe-area-inset-left)); padding-right:calc(20px + env(safe-area-inset-right)); }
main{ padding-left:calc(16px + env(safe-area-inset-left)); padding-right:calc(16px + env(safe-area-inset-right)); }
.viewtabs-bar{ left:calc(12px + env(safe-area-inset-left)); right:calc(12px + env(safe-area-inset-right)); }
body.tabs-mini .viewtabs-bar{ right:calc(100vw - 12px - env(safe-area-inset-left) - 112px); }
.today-dock{ padding-left:calc(12px + env(safe-area-inset-left)); padding-right:calc(12px + env(safe-area-inset-right)); }
.sheet{ padding-left:calc(20px + env(safe-area-inset-left)); padding-right:calc(20px + env(safe-area-inset-right)); }

/* Open, the Duo is 951 points wide (669 if turned upright), and an iPad is
   wider still. A phone
   layout stretched that far puts the times a long way from what they
   belong to, so Today splits into two panes. The gap between them is where
   the Duo folds when it's opened like a book (951 by 669): when it's half
   open, nothing you tap sits on the crease. 600 is above the Duo's outer
   screen (466) and any iPhone in portrait. */
@media (min-width:600px){
  :root{ --pane-gap:40px; --wide-max:1100px; --tabs-w:520px; --side:max(env(safe-area-inset-left), env(safe-area-inset-right)); }
  /* Both sides take the larger inset, so the gap between the panes stays on
     the fold. Opened like a book, the Duo puts its status strip down one
     side, and padding only that side moved the gap 22 points off the fold. */
  main{ padding-left:calc(16px + var(--side)); padding-right:calc(16px + var(--side)); }
  #tab-today.active:has(> .today-now){
    display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:"now day" "more day" "spacer spacer";
    grid-template-rows:auto 1fr auto; column-gap:var(--pane-gap); align-items:start;
    max-width:var(--wide-max); margin:0 auto;
  }
  .today-now{ grid-area:now; }
  .today-day{ grid-area:day; }
  .today-more{ grid-area:more; }
  #tab-today .dock-spacer{ grid-area:spacer; }
  /* The day list starts level with the Now panel, not a line below it. */
  .today-day > .day-label:first-child{ margin-top:0; }

  /* The log buttons stay docked at the bottom, as on a phone, but in one
     row: the feed buttons on the left, the five log buttons on the right,
     split at the fold. One row also leaves more of the day in view. */
  .today-dock{
    flex-direction:row; align-items:stretch; column-gap:var(--pane-gap);
    padding-left:max(calc(12px + var(--side)), calc((100vw - var(--wide-max)) / 2));
    padding-right:max(calc(12px + var(--side)), calc((100vw - var(--wide-max)) / 2));
  }
  .today-dock > *{ flex:1 1 0; min-width:0; }
  .today-dock > .dock-top{ min-height:0; }

  /* The tabs keep a phone's width, centred. */
  .viewtabs-bar{
    left:max(calc(12px + env(safe-area-inset-left)), calc(50vw - var(--tabs-w) / 2));
    right:max(calc(12px + env(safe-area-inset-right)), calc(50vw - var(--tabs-w) / 2));
  }
  body.tabs-mini .viewtabs-bar{ right:calc(100vw - max(calc(12px + env(safe-area-inset-left)), calc(50vw - var(--tabs-w) / 2)) - 112px); }

  /* The other tabs, the All children view, and sheets keep a readable width. */
  #tab-history, #tab-allergens, #tab-guidance, #tab-settings,
  #tab-today:not(:has(> .today-now)){ max-width:640px; margin:0 auto; }
  .sheet{ width:min(100%, 600px); margin:0 auto; }
  /* On Today the toast centres over the left pane, above the feed buttons,
     so its Undo isn't on the fold. */
  body.on-today #toast{ left:25%; max-width:calc(50vw - 48px); }
}

/* =====================================================================
   1.2: the iPhone Duo side strip
   ===================================================================== */
/* Built with the iOS 27.1 SDK, the app reaches the edge of the Duo's
   screen, and iOS keeps a strip down one side for the status bar and the
   camera: on the outer screen, and inside in landscape. Apple moves tab
   bars and toolbars into that strip, so there's more height for content
   and the buttons are under the right thumb. iOS can't move ours (they're
   part of the web page), so sizeSideRail() spots the strip from the safe
   area and sets body.side-rail, data-rail (which side), and --rail-w.
   The tabs and the Reminders and Search buttons stack at the bottom of the
   strip, clear of the status bar at its top. The log buttons stay where
   they are: at 3am they never move. */
body.side-rail main{ padding-bottom:calc(24px + env(safe-area-inset-bottom)); }
body[data-rail="right"] header, body[data-rail="right"] .chips-bar{ padding-right:calc(20px + var(--rail-w)); }
body[data-rail="left"] header, body[data-rail="left"] .chips-bar{ padding-left:calc(20px + var(--rail-w)); }
body[data-rail="right"] main{ padding-right:calc(16px + var(--rail-w)); }
body[data-rail="left"] main{ padding-left:calc(16px + var(--rail-w)); }
/* The dock stops at the strip, rather than running behind it. */
body[data-rail="right"] .today-dock{ right:var(--rail-w); }
body[data-rail="left"] .today-dock{ left:var(--rail-w); }
/* The dock no longer has the tab bar to run behind. */
body.side-rail .today-dock{ padding-bottom:calc(12px + env(safe-area-inset-bottom)); }

body.side-rail .viewtabs-bar,
body.side-rail.tabs-mini .viewtabs-bar{
  left:auto; right:auto; width:56px; padding:4px;
  bottom:calc(10px + env(safe-area-inset-bottom));
}
body[data-rail="right"] .viewtabs-bar{ right:calc((var(--rail-w) - 56px) / 2); }
body[data-rail="left"] .viewtabs-bar{ left:calc((var(--rail-w) - 56px) / 2); }
body.side-rail .viewtabs{ flex-direction:column; gap:2px; }
body.side-rail .viewtab{ flex:0 0 auto; height:48px; padding:0; justify-content:center; }
/* Icons only, as Apple's own side bars are. The name is still read out. */
body.side-rail .viewtab span{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
/* The tab bar never tucks away in the strip: it doesn't cover anything. */
body.side-rail.tabs-mini .viewtab:not(.active){ overflow:visible; flex-grow:0; flex-basis:auto; opacity:1; pointer-events:auto; }

/* Reminders and Search sit 12 points above the tabs. 260 is the tab bar's
   height: five 48-point tabs, their gaps, padding, and border. */
body.side-rail .hdr-capsule{
  position:fixed; z-index:50; flex-direction:column; width:50px; align-items:center;
  bottom:calc(10px + 260px + 12px + env(safe-area-inset-bottom));
}
body[data-rail="right"] .hdr-capsule{ right:calc((var(--rail-w) - 50px) / 2); }
body[data-rail="left"] .hdr-capsule{ left:calc((var(--rail-w) - 50px) / 2); }
body.kb-open.side-rail .hdr-capsule{ display:none; }

/* The toast keeps clear of the strip, and sits lower without the tab bar. */
body.side-rail #toast{ bottom:calc(24px + env(safe-area-inset-bottom)); }
body[data-rail="right"] #toast{ margin-left:calc(var(--rail-w) / -2); }
body[data-rail="left"] #toast{ margin-left:calc(var(--rail-w) / 2); }
body.side-rail.on-today #toast{ bottom:calc(var(--dock-h, 230px) + 10px); }

/* Open in landscape, both sides take the strip's width, so the gap between
   the panes stays on the fold. */
@media (min-width:600px){
  body.side-rail{ --side:var(--rail-w); }
  /* The dock stops at the strip on one side, so the other side is padded
     by the strip's width to keep the split between its halves on the fold. */
  body[data-rail="right"] .today-dock{
    padding-left:max(calc(12px + var(--rail-w)), calc((100vw - var(--wide-max)) / 2));
    padding-right:max(12px, calc((100vw - var(--wide-max)) / 2 - var(--rail-w)));
  }
  body[data-rail="left"] .today-dock{
    padding-right:max(calc(12px + var(--rail-w)), calc((100vw - var(--wide-max)) / 2));
    padding-left:max(12px, calc((100vw - var(--wide-max)) / 2 - var(--rail-w)));
  }
  body.side-rail main{ padding-left:calc(16px + var(--rail-w)); padding-right:calc(16px + var(--rail-w)); }
  /* The greeting and child switcher line up with the panes below them. */
  body.side-rail header, body.side-rail .chips-bar{ padding-left:calc(16px + var(--rail-w)); padding-right:calc(16px + var(--rail-w)); }
  body.side-rail.on-today #toast{ margin-left:0; }
}

/* 1.3: Reduce Transparency. The frosted surfaces become solid, as iOS's own
   bars do, so text on them never sits over the page moving underneath. The
   web view may not report prefers-reduced-transparency, so Swift also hands
   over the iPhone setting and applyReduceMotion() in app.js sets
   html.reduce-transparency. The two blocks match. */
@media (prefers-reduced-transparency: reduce){
  .sign-in-card, .viewtabs-bar, .hdr-capsule{ background:var(--card) !important; }
  .chips-bar, body::before, .today-dock{ background:var(--bg) !important; }
  .sign-in-card, .viewtabs-bar, .hdr-capsule, .chips-bar, body::before, .today-dock{
    -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
  }
}
html.reduce-transparency .sign-in-card, html.reduce-transparency .viewtabs-bar, html.reduce-transparency .hdr-capsule{ background:var(--card) !important; }
html.reduce-transparency .chips-bar, html.reduce-transparency body::before, html.reduce-transparency .today-dock{ background:var(--bg) !important; }
html.reduce-transparency .sign-in-card, html.reduce-transparency .viewtabs-bar, html.reduce-transparency .hdr-capsule,
html.reduce-transparency .chips-bar, html.reduce-transparency body::before, html.reduce-transparency .today-dock{
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
}
