    /* ============================================================
       Sprout Count — enhancement styles (added on top of the base).
       Text size, easy-reading font, sticky drawer headers,
       recent foods, starter-carb hint, plate-total pill, portion
       buttons, feedback modal, print styles.
       ============================================================ */

    /* Easy-reading (dyslexia-friendly) font toggle */
    body.easy-font, body.easy-font button, body.easy-font input, body.easy-font textarea,
    body.easy-font h1, body.easy-font h2, body.easy-font h3, body.easy-font .display,
    body.easy-font .greeting-text, body.easy-font .meal-item-title {
      font-family: 'Atkinson Hyperlegible', 'Nunito', system-ui, sans-serif !important;
      letter-spacing: 0.012em;
    }
    body.easy-font { word-spacing: 0.06em; }

    /* Compact 3-across segmented control (text size) */
    .seg-chip {
      flex: 1 1 0; min-width: 0; padding: 9px 4px; text-align: center;
      background: var(--bg); border: 2px solid var(--bg2); color: var(--ink);
      border-radius: 12px; font-weight: 800; font-size: 0.82rem; cursor: pointer;
      font-family: 'Nunito', sans-serif;
    }
    body.theme-night .seg-chip { background: #1B2140; border-color: #262C52; }
    .seg-chip.active { border-color: var(--sky); background: var(--sky); color: #fff; }
    .bread-slice-note {
      font-size: 0.68rem; color: var(--ink-soft); font-weight: 700; line-height: 1.4;
      margin: 8px 0 0;
    }

    /* Carb Detective: level selector + play/reveal cards. Reuses the app's
       existing colour tokens throughout (mint/sky/sun/berry) rather than
       introducing a new palette, and the level-locked state mirrors how
       other "not yet available" states already look elsewhere. */
    .detective-level-row {
      display: flex; gap: 6px; margin-bottom: 12px;
    }
    .detective-level-btn {
      flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
      background: var(--card); border: 2px solid var(--bg2); border-radius: 14px;
      padding: 8px 4px; cursor: pointer; font-family: 'Nunito', sans-serif;
    }
    body.theme-night .detective-level-btn { background: #1B2140; border-color: #262C52; }
    .detective-level-btn.active { border-color: var(--sky); background: rgba(63,169,245,0.14); }
    .detective-level-btn.locked { opacity: 0.55; cursor: not-allowed; }
    .detective-level-icon { font-size: 1.2rem; }
    .detective-level-name { font-weight: 800; font-size: 0.72rem; color: var(--ink); }
    .detective-level-btn.active .detective-level-name { color: var(--sky); }
    .detective-level-progress { font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); }

    .detective-card {
      background: var(--bg); border-radius: 18px; padding: 20px 16px; text-align: center; position: relative;
    }
    .detective-streak-badge {
      position: absolute; top: 10px; right: 12px;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.8rem; color: var(--sun-ink);
    }
    .detective-food-emoji { font-size: 3.2rem; line-height: 1; margin-bottom: 4px; }
    .detective-food-name { font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 1.1rem; margin-bottom: 12px; }
    .detective-question { font-size: 0.78rem; font-weight: 700; color: var(--ink-soft); margin-bottom: 8px; }
    .detective-guess-display {
      font-family: 'Baloo 2', sans-serif; font-size: 2rem; font-weight: 800; color: var(--sky); margin-bottom: 4px;
    }
    #detectiveSlider { width: 100%; accent-color: var(--sky); margin: 4px 0 4px; }

    .detective-reveal-badge {
      display: inline-flex; align-items: center; gap: 6px;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.9rem;
      padding: 6px 16px; border-radius: 100px; margin-bottom: 14px;
    }
    .detective-reveal-badge.close { background: rgba(0,137,123,0.2); color: #4FD6C4; }
    .detective-reveal-badge.ok { background: rgba(255,201,60,0.2); color: var(--sun-ink); }
    .detective-reveal-badge.off { background: rgba(216,27,96,0.2); color: var(--berry); }
    .detective-reveal-numbers { display: flex; justify-content: center; gap: 24px; margin-bottom: 14px; }
    .detective-reveal-label { font-size: 0.64rem; color: var(--ink-soft); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
    .detective-reveal-val { font-family: 'Baloo 2', sans-serif; font-size: 1.4rem; font-weight: 800; }
    .detective-reveal-val.yours { color: var(--sky); }
    .detective-reveal-val.real { color: var(--sun-ink); }

    /* Higher or Lower: styled like an actual deck of playing cards rather
       than matching the app's own palette — the point is it reads as
       "cards", so the card faces are cream/white with red or black suit
       pips, and the back is a classic red pattern, deliberately different
       from the app's mint/sky/sun theme used everywhere else. */
    .hol-topbar {
      display: flex; justify-content: space-between; align-items: center;
      font-family: 'Baloo 2', sans-serif; font-weight: 700; font-size: 0.85rem;
      margin-bottom: 12px;
    }
    .hol-streak { color: var(--sun-ink); font-weight: 800; }
    .hol-table {
      display: flex; justify-content: center; align-items: center; gap: 12px;
      margin-bottom: 14px; perspective: 1000px;
    }
    .hol-card-slot { width: 108px; height: 152px; }
    .hol-card {
      width: 100%; height: 100%; position: relative;
      transform-style: preserve-3d; transition: transform 0.6s cubic-bezier(0.4,0.2,0.2,1);
    }
    .hol-card.hol-flipped { transform: rotateY(180deg); }
    .hol-card-face {
      position: absolute; inset: 0; border-radius: 10px;
      backface-visibility: hidden;
      box-shadow: 0 6px 16px rgba(0,0,0,0.35);
      display: flex; flex-direction: column;
    }
    .hol-card-front { background: #FBF8F1; padding: 6px; color: #222; }
    .hol-pip { position: absolute; font-size: 0.95rem; font-weight: 800; line-height: 1; }
    .hol-corner-tl { top: 6px; left: 6px; }
    .hol-corner-br { bottom: 6px; right: 6px; transform: rotate(180deg); }
    .hol-pip.red { color: #D81B60; }
    .hol-pip.black { color: #1F2A44; }
    .hol-card-center {
      flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    }
    .hol-card-emoji { font-size: 2rem; line-height: 1; }
    .hol-card-name { font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.68rem; color: #1F2A44; text-align: center; }
    .hol-card-carb-label { font-size: 0.5rem; color: #6B7280; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; }
    .hol-card-carb-val { font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 1rem; color: var(--mint); }
    .hol-card-back {
      background:
        repeating-linear-gradient(45deg, rgba(255,255,255,0.08) 0 6px, transparent 6px 12px),
        linear-gradient(135deg, #C41E3A, #8B0000);
      transform: rotateY(180deg);
      display: flex; align-items: center; justify-content: center;
      border: 3px solid rgba(255,255,255,0.5);
      font-size: 1.7rem;
    }
    .hol-hidden-start .hol-card { transform: rotateY(180deg); }
    .hol-hidden-start .hol-card.hol-flipped { transform: rotateY(0deg); }
    .hol-vs { font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.78rem; color: var(--ink-soft); }
    .hol-question {
      text-align: center; font-size: 0.8rem; font-weight: 700; color: var(--ink);
      margin-bottom: 10px; line-height: 1.4;
    }
    .hol-question b { color: var(--sun-ink); }
    .hol-result {
      text-align: center; font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.82rem;
      padding: 7px; border-radius: 10px; margin-bottom: 10px; min-height: 18px;
    }
    .hol-result.correct { background: rgba(0,137,123,0.2); color: #4FD6C4; }
    .hol-result.wrong { background: rgba(216,27,96,0.2); color: var(--berry); }
    .hol-guess-row { display: flex; gap: 10px; }
    .hol-guess-btn {
      flex: 1; padding: 12px; border-radius: 12px; border: none;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.88rem; color: #fff;
      cursor: pointer;
    }
    .hol-guess-btn.hol-higher { background: var(--sky); }
    .hol-guess-btn.hol-lower { background: var(--berry); }
    .hol-guess-btn:active { transform: scale(0.97); }

    /* Sticky section headers inside the settings drawer */
    .drawer .drawer-section-label {
      position: sticky; top: 0; z-index: 6;
      background: var(--card); margin-top: 20px;
      padding-top: 10px;
    }
    /* Keep the drawer close button tappable above sticky headers */
    .drawer .close-btn { z-index: 8; }

    /* Starter-carb "typical value" hint, shown under the food picker */
    .starter-carb-hint {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      margin: 0 0 14px; padding: 8px 10px;
      background: var(--sprout-green-tint); border: 1.5px dashed rgba(14,140,122,0.4);
      border-radius: 12px;
    }
    .starter-carb-hint[hidden] { display: none; }
    body.theme-night .starter-carb-hint { border-color: rgba(46,196,182,0.45); }

    /* .squash-dilute-* block removed 2026-08 — dead CSS, no matching
       markup anywhere in index.html or any JS file (verified via
       cross-reference audit). Was styling for a squash/dilution-ratio
       helper that was never wired up or was fully removed elsewhere. */
    .starter-carb-hint-text {
      display: flex; align-items: flex-start; gap: 8px;
      flex: 1 1 140px; min-width: 0;
    }
    .starter-carb-hint-icon {
      flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
      background: var(--card); border: 2px dashed #fff;
      box-shadow: 0 0 0 1.5px rgba(14,140,122,0.35);
      display: flex; align-items: center; justify-content: center;
      font-size: 1.4rem; margin-top: 1px;
    }
    body.theme-night .starter-carb-hint-icon { background: #1B2140; }
    .starter-carb-hint-body {
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.76rem;
      color: var(--ink-soft); line-height: 1.35; min-width: 0; flex: 1 1 auto;
    }
    /* Source line — a quiet button until you want the evidence. */
    .footer-version { font-size: 0.72rem; opacity: 0.85; }
    .footer-report-btn {
      background: none; border: none; padding: 0; cursor: pointer;
      font-family: inherit; font-size: inherit; font-weight: 800;
      color: inherit; text-decoration: underline;
      -webkit-tap-highlight-color: transparent;
    }
    .footer-report-btn:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .starter-carb-src {
      display: inline-flex; align-items: center; gap: 4px;
      margin-top: 5px; padding: 3px 9px;
      border: 1.5px solid rgba(14,140,122,0.28); border-radius: 100px;
      background: var(--sprout-green-tint); color: var(--sprout-green-deep);
      font-family: 'Nunito', sans-serif; font-size: 0.63rem; font-weight: 800;
      cursor: pointer; -webkit-tap-highlight-color: transparent;
      transition: border-color 0.15s ease, transform 0.12s ease;
    }
    .starter-carb-src:active { transform: scale(0.96); }
    .starter-carb-src:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    body.theme-night .starter-carb-src { color: #2EC4B6; border-color: rgba(46,196,182,0.35); }
    body.theme-contrast .starter-carb-src, body.theme-contrast-light .starter-carb-src {
      color: var(--ink); background: var(--bg2); border-color: var(--ink-soft);
    }
    .starter-carb-src-caret { font-size: 0.6rem; transition: transform 0.18s ease; }
    .starter-carb-src[aria-expanded="true"] .starter-carb-src-caret { transform: rotate(180deg); }

    /* The evidence panel itself. */
    .starter-carb-srclist {
      flex: 1 1 100%; width: 100%; margin-top: 8px;
      padding: 10px 12px; border-radius: var(--radius-md);
      background: var(--card); border: 1.5px solid var(--bg2);
      animation: srcOpen 0.22s ease both;
    }
    .starter-carb-srclist[hidden] { display: none; }
    body.theme-night .starter-carb-srclist { background: #1B2140; border-color: #262C52; }
    @keyframes srcOpen {
      from { opacity: 0; transform: translateY(-4px); }
      to { opacity: 1; transform: translateY(0); }
    }
    @media (prefers-reduced-motion: reduce) {
      .starter-carb-srclist { animation: none; }
      .starter-carb-src-caret { transition: none; }
    }
    .starter-src-bar-row {
      display: flex; align-items: flex-start; justify-content: space-between;
      gap: 10px; margin-bottom: 7px;
    }
    .starter-src-head {
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.76rem;
      color: var(--ink); line-height: 1.3;
    }
    .starter-src-close {
      flex: 0 0 auto; position: relative;
      width: 24px; height: 24px; padding: 0; border-radius: 50%;
      border: 1.5px solid var(--bg2); background: transparent;
      color: var(--ink-soft); font-size: 0.7rem; line-height: 1; cursor: pointer;
      -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    }
    /* Small circle, comfortable 44px touch area. */
    .starter-src-close::before {
      content: ''; position: absolute; top: 50%; left: 50%;
      width: 44px; height: 44px; transform: translate(-50%, -50%);
    }
    .starter-src-close:hover { background: var(--bg2); color: var(--ink); }
    .starter-src-close:active { transform: scale(0.9); }
    .starter-src-close:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .starter-src-actions {
      display: flex; gap: 8px; margin-top: 9px;
    }
    .starter-src-action {
      flex: 1 1 0; padding: 7px 8px; border-radius: 100px; cursor: pointer;
      border: 1.5px solid var(--bg2); background: transparent; color: var(--ink-soft);
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.7rem;
      -webkit-tap-highlight-color: transparent;
      transition: border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    }
    .starter-src-action:hover { border-color: var(--sprout-green); color: var(--ink); }
    .starter-src-action:active { transform: scale(0.96); }
    .starter-src-action:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    @media (prefers-reduced-motion: reduce) {
      .starter-src-close, .starter-src-action { transition: none; }
    }
    .starter-src-list { list-style: none; margin: 0; padding: 0; }
    .starter-src-caveat {
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.7rem;
      color: var(--ink-soft); line-height: 1.45; margin-bottom: 9px;
    }
    .starter-src-row {
      display: grid; width: 100%;
      grid-template-columns: 1fr auto;
      grid-template-areas: 'tag tag' 'name val';
      gap: 1px 8px; padding: 9px 4px;
      border-top: 1px solid var(--bg2);
      border-left: none; border-right: none; border-bottom: none;
      background: transparent; text-align: left; cursor: pointer;
      border-radius: 8px;
      -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, transform 0.1s ease;
    }
    li:first-child > .starter-src-row { border-top: none; padding-top: 2px; }
    .starter-src-row:hover { background: var(--bg2); }
    .starter-src-row:active { transform: scale(0.98); }
    .starter-src-row:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    @media (prefers-reduced-motion: reduce) { .starter-src-row { transition: none; } }
    .starter-src-tag {
      grid-area: tag;
      display: inline-block; width: fit-content; margin-bottom: 3px;
      padding: 2px 8px; border-radius: 100px;
      background: #FFF4D6; color: #8A5A00;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.6rem;
      text-transform: uppercase; letter-spacing: 0.04em;
    }
    body.theme-night .starter-src-tag { background: rgba(255,193,7,0.16); color: #FFD98A; }
    body.theme-contrast .starter-src-tag, body.theme-contrast-light .starter-src-tag {
      background: var(--bg2); color: var(--ink);
    }
    .starter-src-name {
      grid-area: name;
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.7rem;
      color: var(--ink-soft); line-height: 1.3;
    }
    .starter-src-name-estimate { font-style: italic; }
    .starter-src-val {
      grid-area: val; align-self: center;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.8rem;
      color: var(--ink);
    }
    /* .starter-src-more / .starter-src-foot removed 2026-08 — dead CSS,
       unreferenced in any JS or HTML (verified via cross-reference audit). */
    .starter-src-empty {
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.7rem;
      color: var(--ink-soft); line-height: 1.45;
    }
    .starter-carb-choice-row {
      display: flex; gap: 8px; flex-wrap: wrap; flex: 0 0 auto; width: 100%;
    }
    .starter-carb-use-btn {
      flex: 1 1 auto; background: var(--sprout-green); color: #fff; border: none;
      border-radius: 100px; padding: 8px 14px; font-family: 'Baloo 2', sans-serif;
      font-weight: 800; font-size: 0.82rem; cursor: pointer;
    }
    .starter-carb-use-btn:active { transform: scale(0.95); }
    body.theme-contrast .starter-carb-use-btn, body.theme-contrast-light .starter-carb-use-btn {
      background: var(--ink-soft); color: var(--bg);
    }
    /* Secondary, quieter option next to Use — same size so neither reads as
       "the" answer, since some parents will know their exact packaging
       number and others will want the guess. */
    .starter-carb-own-btn {
      flex: 1 1 auto; background: var(--card); color: var(--ink);
      border: 1.5px solid var(--sprout-green); border-radius: 100px; padding: 8px 14px;
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.78rem; cursor: pointer;
      -webkit-tap-highlight-color: transparent;
    }
    body.theme-night .starter-carb-own-btn { background: #1B2140; }
    .starter-carb-own-btn:active { transform: scale(0.95); }
    body.theme-contrast .starter-carb-own-btn, body.theme-contrast-light .starter-carb-own-btn {
      background: transparent; color: var(--ink); border-color: var(--ink);
    }
    /* Portion verification — two chips tucked under the weight stepper. */
    .portion-chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
    .field-subtitle {
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.86rem;
      color: var(--ink); margin: 0 0 6px;
    }
    .portion-method-btn {
      flex: 1 1 90px; min-width: 0; padding: 7px 6px; border-radius: 100px;
      border: 2px solid #E0A200; background: var(--card); color: var(--ink-soft);
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.76rem;
      cursor: pointer; -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    }
    body.theme-night .portion-method-btn { background: #1B2140; }
    .portion-method-btn:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .portion-method-btn:active { transform: scale(0.96); }
    .portion-chips .portion-method-btn.active {
      border-color: var(--sprout-green); background: var(--sprout-green); color: #fff;
    }
    body.theme-contrast .portion-chips .portion-method-btn.active,
    body.theme-contrast-light .portion-chips .portion-method-btn.active {
      background: var(--ink-soft); color: var(--bg); border-color: var(--ink-soft);
    }
    /* Guessing is a legitimate last resort, so it stays — but it shouldn't look
       like an equal third of the row. Dashed and muted, never scolding. */
    .portion-method-btn[data-method="guide"] {
      border-style: dotted; opacity: 0.82; font-weight: 700;
    }
    .portion-chips .portion-method-btn[data-method="guide"].active {
      border-style: dotted; opacity: 1;
    }
    /* Gentle idle nudge while no method has been picked yet — much slower
       and lower-contrast than the skip warning below, just a quiet "this is
       waiting for you" rather than an alert. Stops the instant one is tapped. */
    .portion-chips.unanswered .portion-method-btn {
      animation: portionSoftPulse 2.4s ease-in-out infinite;
    }
    body.theme-night .portion-chips.unanswered .portion-method-btn {
      animation-name: portionSoftPulseNight;
    }
    @keyframes portionSoftPulse {
      0%, 100% { box-shadow: none; }
      50% { box-shadow: 0 0 0 4px rgba(90, 179, 106, 0.38); }
    }
    @keyframes portionSoftPulseNight {
      0%, 100% { box-shadow: none; }
      50% { box-shadow: 0 0 0 4px rgba(120, 200, 135, 0.45); }
    }
    @media (prefers-reduced-motion: reduce) {
      .portion-chips.unanswered .portion-method-btn { animation: none; }
    }
    /* Bread's preset picker (Thin/Medium/Thick) — same pill language as
       portion-method-btn above, two lines instead of one so a flat,
       pre-computed carb value sits under each label. [hidden] override
       included immediately, learned the hard way earlier today. */
    .bread-preset-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
    .bread-preset-row[hidden] { display: none; }
    .bread-preset-btn {
      flex: 1 1 90px; min-width: 0; padding: 8px 6px; border-radius: 100px;
      border: 2px solid var(--bg2); background: var(--card); color: var(--ink-soft);
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.76rem;
      cursor: pointer; text-align: center; -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    }
    .bread-preset-btn .preset-amt { display: block; font-family: 'Baloo 2', sans-serif; font-size: 0.95rem; margin-top: 2px; }
    .bread-preset-btn:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .bread-preset-btn:active { transform: scale(0.96); }
    .bread-preset-btn.active {
      border-color: var(--sprout-green); background: var(--sprout-green); color: #fff;
    }
    body.theme-contrast .bread-preset-btn.active,
    body.theme-contrast-light .bread-preset-btn.active {
      background: var(--ink-soft); color: var(--bg); border-color: var(--ink-soft);
    }
    /* Small, low-key badge — this is genuinely just a "here's why" aside,
       not something that needs to compete with the button below it. */
    .bread-preset-guess-chip {
      display: inline-block;
      background: rgba(255, 201, 60, 0.15);
      border: 1.5px dashed var(--sun);
      color: var(--ink-soft);
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.72rem;
      padding: 6px 12px; border-radius: 100px;
      margin: 4px 0 12px;
    }
    .bread-preset-guess-chip[hidden] { display: none; }
    /* Deliberately as visually prominent as "Add a drink" — same recipe
       (tinted fill, 2px border, brand-blue text) — so escaping the presets
       for a real weighed/label number is never something a person has to
       hunt for in a line of small print. */
    .bread-own-numbers-btn {
      display: flex; width: 100%; align-items: center; justify-content: center; gap: 6px;
      background: rgba(63, 169, 245, 0.08);
      border: 2px solid rgba(63, 169, 245, 0.4);
      border-radius: 12px;
      color: var(--sky);
      padding: 12px 16px;
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.9rem;
      cursor: pointer; margin-bottom: 16px;
      transition: all 0.2s ease;
      -webkit-tap-highlight-color: transparent;
    }
    .bread-own-numbers-btn[hidden] { display: none; }
    .bread-own-numbers-btn:active { transform: scale(0.98); }
    .bread-own-numbers-btn:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    body.theme-night .bread-own-numbers-btn {
      background: rgba(63, 169, 245, 0.15);
    }
    /* Same "look here" language, reused for the carbs field right after
       adding a brand-new food, so it's obvious where to enter its numbers. */
    #carbsInput.needs-carbs-highlight {
      animation: portionPulse 0.55s ease 3;
    }
    body.theme-night #carbsInput.needs-carbs-highlight {
      animation-name: portionPulseNight;
    }
    @media (prefers-reduced-motion: reduce) {
      #carbsInput.needs-carbs-highlight { animation: none; box-shadow: 0 0 0 4px rgba(224,162,0,0.3); }
    }
    .portion-guide {
      margin: -4px 0 10px; padding: 8px 11px; border-radius: 12px;
      background: var(--sprout-green-tint);
      font-family: 'Nunito', sans-serif; font-size: 0.74rem; font-weight: 700;
      color: var(--ink-soft); line-height: 1.45;
    }
    .portion-guide[hidden] { display: none; }
    .portion-chips[hidden] { display: none; }
    .portion-guide ul { margin: 0; padding-left: 18px; }
    .portion-guide li { margin: 2px 0; }

    /* "Could be between X and Y" ranges + estimate warnings */
    .live-preview-range {
      flex: 1 1 100%; width: 100%;
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.78rem;
      color: var(--ink-soft); line-height: 1.4; margin-top: 2px;
    }
    .live-preview-range[hidden] { display: none; }
    .live-preview-fav-note {
      flex: 1 1 100%; width: 100%;
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.74rem;
      color: var(--ink-soft); line-height: 1.4; margin-top: 4px; opacity: 0.85;
    }
    .live-preview-fav-note[hidden] { display: none; }
    .result-est-note {
      margin-top: 10px; padding: 8px 10px; border-radius: 12px;
      background: rgba(255,255,255,0.22);
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.76rem;
      line-height: 1.4;
    }
    .result-est-note[hidden] { display: none; }
    /* ============================================================
       REX APPROVES STAMP. See the matching comment in index.html above
       #rexApprovesStamp for the full trigger/revert notes. Fires on a
       small random chance per log (not every time — #sproutSays
       already mentions Rex in its own wording now, so this is a rare
       extra surprise rather than a guaranteed second mention).
       Styled as a small stamp/badge rather than matching
       .result-est-note's info-box look, so it reads as a fun aside
       rather than another informational line.
       ============================================================ */
    .rex-approves-stamp {
      display: inline-block;
      margin-top: 8px; padding: 5px 12px; border-radius: 999px;
      background: rgba(255,255,255,0.22);
      font-family: 'Baloo 2', sans-serif; font-weight: 800; font-size: 0.78rem;
      animation: rexApprovesPop 0.3s ease-out;
    }
    .rex-approves-stamp[hidden] { display: none; }
    @keyframes rexApprovesPop {
      0% { opacity: 0; transform: scale(0.85) translateY(4px); }
      100% { opacity: 1; transform: scale(1) translateY(0); }
    }
    @media (prefers-reduced-motion: reduce) {
      .rex-approves-stamp { animation: none; }
    }
    /* END REX APPROVES STAMP */
    .meal-item-range {
      font-size: 0.72rem; color: var(--ink-soft); font-weight: 800; margin-top: 2px;
    }
    /* A guessed carb value or an eyeballed portion — the colour does the
       flagging so there's no extra symbol for a child to decode. */
    button.meal-item-range {
      font-family: 'Nunito', sans-serif; text-align: left; cursor: pointer;
      -webkit-tap-highlight-color: transparent;
    }
    button.meal-item-range:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .range-why-cue { text-decoration: underline; opacity: 0.85; margin-left: 2px; }
    .meal-item-why {
      margin-top: 5px; padding: 7px 9px; border-radius: 9px;
      background: #FFF4D6; color: #8A5A00;
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 0.72rem;
      line-height: 1.45;
    }
    .meal-item-why[hidden] { display: none; }
    body.theme-night .meal-item-why { background: rgba(255,193,7,0.14); color: #FFD98A; }
    body.theme-contrast .meal-item-why, body.theme-contrast-light .meal-item-why {
      background: var(--bg2); color: var(--ink);
    }
    .meal-item-range.is-guess, .caregiver-item-details.is-guess {
      display: inline-block; color: #8A5A00; background: #FFF4D6;
      border: 1.5px dotted #DC2626; border-radius: 7px;
      padding: 1px 7px; margin-top: 3px;
    }
    body.theme-night .meal-item-range.is-guess { color: #FFD98A; background: rgba(255,193,7,0.16); }
    body.theme-contrast .meal-item-range.is-guess, body.theme-contrast-light .meal-item-range.is-guess {
      color: var(--ink); background: var(--bg2);
    }
    .meal-total-range {
      font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 0.76rem;
      color: var(--ink-soft); text-align: right; margin-top: 4px; line-height: 1.4;
    }

    /* Floating plate-total pill (jump to meal log) */
    .plate-total-pill {
      position: fixed; left: 16px; bottom: 22px; z-index: 4;
      display: inline-flex; align-items: center; gap: 8px;
      background: linear-gradient(135deg, var(--sprout-green), var(--sprout-green-deep));
      color: #fff; border: none; border-radius: 100px;
      padding: 11px 16px; font-family: 'Baloo 2', sans-serif; font-weight: 800;
      font-size: 0.95rem; cursor: pointer; box-shadow: 0 6px 18px rgba(0,89,78,0.34);
      opacity: 0; visibility: hidden; transform: translateY(8px) scale(0.9);
      transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
      max-width: calc(100vw - 120px);
    }
    .plate-total-pill.visible { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
    .plate-total-pill:active { transform: scale(0.94); }
    .plate-total-pill .plate-pill-arrow { font-weight: 900; }
    body.theme-contrast .plate-total-pill, body.theme-contrast-light .plate-total-pill {
      background: var(--ink-soft); color: var(--bg);
    }
    @media (prefers-reduced-motion: reduce) { .plate-total-pill { transition: opacity 0.15s linear; } }

    /* Feedback modal bits */
    .feedback-type-row { display: flex; gap: 8px; margin: 6px 0 14px; }
    .feedback-type-btn {
      flex: 1 1 0; min-width: 0; padding: 10px 4px; border-radius: 12px;
      border: 2px solid var(--bg2); background: var(--bg); color: var(--ink);
      font-weight: 800; font-size: 0.82rem; cursor: pointer; font-family: 'Nunito', sans-serif;
      -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease;
    }
    body.theme-night .feedback-type-btn { background: #1B2140; border-color: #262C52; }
    .feedback-type-btn:hover { border-color: var(--sky); }
    .feedback-type-btn:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    .feedback-type-btn:active { transform: scale(0.95); }
    /* Selected state. Three classes deep so it always beats the per-theme
       overrides above (which used to win in Night mode and hide the highlight).
       color/ring use --card so the text stays legible in every theme. */
    .feedback-type-row .feedback-type-btn.active {
      border-color: var(--sky); background: var(--sky); color: var(--card);
      box-shadow: inset 0 0 0 2px var(--card), 0 3px 10px rgba(0,0,0,0.18);
    }
    @media (prefers-reduced-motion: reduce) {
      .feedback-type-btn { transition: none; }
      .feedback-type-btn:active { transform: none; }
    }
    /* Close ✕ on the feedback card */
    #feedbackModal .modal-content { position: relative; }
    #feedbackModal .feedback-close-x {
      position: absolute; top: 12px; right: 12px; z-index: 2;
      width: 34px; height: 34px; padding: 0; line-height: 1;
      display: flex; align-items: center; justify-content: center;
      border: none; border-radius: 50%; background: var(--bg);
      color: var(--ink-soft); font-size: 17px; font-weight: 900; cursor: pointer;
      -webkit-tap-highlight-color: transparent;
      transition: background-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    }
    #feedbackModal .feedback-close-x:hover { background: var(--bg2); color: var(--ink); }
    #feedbackModal .feedback-close-x:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
    #feedbackModal .feedback-close-x:active { transform: scale(0.92); }
    @media (prefers-reduced-motion: reduce) {
      #feedbackModal .feedback-close-x { transition: none; }
      #feedbackModal .feedback-close-x:active { transform: none; }
    }
    .feedback-grownup-note {
      display: flex; align-items: center; gap: 8px; font-size: 0.78rem; font-weight: 800;
      color: var(--mint); background: var(--sprout-green-tint); border-radius: 12px;
      padding: 9px 11px; margin-bottom: 14px; line-height: 1.35;
    }
    .feedback-textarea {
      width: 100%; min-height: 92px; resize: vertical; padding: 11px;
      border-radius: 12px; border: 2px solid var(--bg2); background: var(--bg);
      color: var(--ink); font-weight: 700; font-family: 'Nunito', sans-serif;
      font-size: 0.95rem; outline: none;
    }
    .feedback-textarea:focus { border-color: var(--sky); }
    .feedback-privacy-note { font-size: 0.72rem; color: var(--ink-soft); font-weight: 700; margin: 10px 0 0; line-height: 1.4; }

    /* Barcode-scan chip button — kept static here (rather than injected by
       barcode/scanner.js at runtime) so it renders correctly from the very
       first paint. scanner.js and off-client.js are now lazy-loaded only
       when this chip is first tapped (see index.html + scanner.js
       injectButton()), so their styles can't be relied on to exist yet.
       This is the only rule scanner.js's own injectStyles() used to define
       that needs to exist before that script has loaded. */
    .barcode-scan-chip-pinned{flex:0 0 auto;width:58px;height:64px;border-radius:14px;
      border:2px solid var(--sky);background:linear-gradient(160deg,#E7F5FF,var(--sky));
      color:#08405E;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
      -webkit-tap-highlight-color:transparent;
      box-shadow:0 2px 6px rgba(63,169,245,0.45);transition:transform 0.12s ease;}
    .barcode-scan-chip-pinned .pinned-chip-icon{font-size:23px;line-height:1;}
    .barcode-scan-chip-pinned:active{transform:scale(0.9);}
    .barcode-scan-chip-pinned:focus-visible{outline:3px solid var(--sky);outline-offset:2px;}
    .barcode-scan-chip-pinned:disabled{opacity:0.55;cursor:wait;}
    body.theme-night .barcode-scan-chip-pinned{background:linear-gradient(160deg,#123049,#1E5C86);color:#DCEEFB;}


/* Scanned meal items show a camera marker instead of the rename affordance:
   the product name comes from the barcode and is not editable, so offering
   "tap to name" would be a promise the app no longer keeps. */
.scanned-hint {
  font-size: 0.72rem;
  opacity: 0.75;
  margin-left: 4px;
}


/* An item the app could not put a number on. Deliberately reads as words
   rather than a figure — "0g" would be a claim, and the whole point is that
   no claim can be made. Amber rather than red: it is a caveat, not an error. */
.uncounted-val {
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--sunny, #F59E0B);
  white-space: nowrap;
}


/* The way out when no carb figure exists anywhere. Understated on purpose —
   it should be findable when needed, not an easier option than reading the
   packet. */
.uncounted-add-btn {
  margin-top: 8px;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1.5px solid var(--ink-soft);
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-weight: 700;
  font-size: 0.78rem;
  cursor: pointer;
}
.uncounted-add-btn:hover,
.uncounted-add-btn:focus-visible {
  border-color: var(--sky);
  color: var(--sky);
}


/* ====================================================================
   DRINKS STATION v2
   Ported 1:1 from drinks-station-mockup-v2.html (12 Aug 2026).

   The mockup's :root was literally this app's theme-night palette, so
   every var() below is already the app's own token and themes for free.
   The one thing that could NOT come across verbatim is the mockup's
   hardcoded rgba(255,255,255,.04) / rgba(0,0,0,.28) surfaces: those
   assume a dark background and go invisible (or unreadable) in the
   light, rainbow, caregiver and high-contrast themes. They are mapped
   onto three new per-theme tokens declared in css/main.css:
     --dv-surface  faint raised panel
     --dv-line     hairline / dashed rule
     --dv-inset    recessed well (maths box, result panel)
   Same appearance in theme-night as the mockup, correct everywhere else.
   ==================================================================== */

.drinks-v2 { font-weight: 700; }

.drinks-v2 .dv-head-actions { display: flex; align-items: center; gap: 12px; }
.dv-reset-btn {
  background: none; border: none; color: var(--ink-soft); font: inherit;
  font-size: .72rem; font-weight: 800; cursor: pointer;
  text-decoration: underline; padding: 4px;
}

/* ---- steps ---------------------------------------------------------- */
.dv-step { margin-bottom: 14px; }
.dv-step:last-child { margin-bottom: 0; }
.dv-step-head {
  display: flex; align-items: center; gap: 6px; width: 100%;
  background: none; border: none; padding: 0; color: inherit; font: inherit;
  text-align: left; cursor: pointer;
}
.dv-badge {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: var(--sprout-green); color: #fff; font-size: .72rem; font-weight: 800;
  display: grid; place-items: center;
}
.dv-badge.done { background: var(--sky); color: var(--card); }
.dv-badge.todo { background: var(--dv-line); color: var(--ink-soft); }
.dv-step-title { font-size: .95rem; font-weight: 800; flex: 1; }
.dv-step-answer { font-size: .82rem; font-weight: 800; color: var(--sky); white-space: nowrap; }
/* The open/closed chevron. Was .8rem — a ~10px glyph doing the job of
   telling you whether a step is open, which is the single most important
   piece of state on the screen. Now 1.35rem in a 32px box, which also gives
   the header's tap target a sensible visual anchor at the right-hand edge.
   Colour lifted from --ink-soft to --sky so it reads as a control rather
   than decoration. */
.dv-chev {
  color: var(--sky);
  font-size: 1.35rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 26px, not 32: at 32 the extra width tipped "What's on your plate?
     (optional)" onto a second line. The glyph is what needed to grow, not
     the box — a -6px margin-right lets it sit flush to the card edge and
     claw back the space the title lost. */
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  margin-right: -6px;
  /* The box stays 26px, but the arrow inside it is scaled up. A transform
     is purely visual — it takes no layout space — so the glyph can be made
     properly legible without pushing the title onto a second line, which is
     what capping the box at 26px was working around in the first place.
     At 1.35rem the triangle occupies only a fraction of its em square and
     read as a speck on a phone. */
  transform: scale(1.75);
  transform-origin: center;
  transition: transform .18s ease;
}
/* Rotated when the step is open, so a collapsed step always looks the same
   "tap me to open" way — whether it's still to come, or was answered and
   tucked away, or got closed by an accidental tap on the header. */
/* MUST repeat the scale from the base rule. `transform` is one property,
   not a list that merges — writing rotate() alone here silently discards
   the scale(1.75) above and an open chevron shrinks to a third of a
   collapsed one. Change the scale in the base rule and change it here too. */
.dv-step[data-state="open"] .dv-chev { transform: rotate(180deg) scale(1.75); }
.dv-step-body { margin-top: 10px; }
.dv-step[data-state="collapsed"] .dv-step-body { display: none; }
/* Brief fade-out applied by collapseStepSoftly() in food-station.js —
   data-state passes through "collapsing" for STEP_COLLAPSE_FADE_MS before
   landing on "collapsed" (which is what actually applies display:none
   above) — softens the single-open accordion's force-close of a sibling
   step so it reads as a handoff rather than an instant snap, matching the
   existing fade-IN on open (dvIn keyframe, further down this file).
   Selector keys off data-state="collapsing" specifically, NOT "open" plus
   a class — "collapsing" matches neither the open-state selector below
   (whose dvIn animation would otherwise override this transition on the
   same opacity/transform properties, silently cancelling the fade-out)
   nor the collapsed-state display:none rule above, so the body stays
   visible for exactly the fade's duration. The .fs-step-collapsing class
   JS also adds is a belt-and-braces hook for anything else that might
   want to target the transitional moment; this rule doesn't depend on it.
   Timing (140ms) is set in JS as STEP_COLLAPSE_FADE_MS and must stay
   roughly matched to this transition's duration, or the element will
   either flash unstyled or get cut off mid-fade. Skipped entirely under
   prefers-reduced-motion (checked in JS, not here, since the state flip
   itself needs to skip the delay too, not just the visual). */
.dv-step[data-state="collapsing"] .dv-step-body { opacity: 0; transform: translateY(-3px); transition: opacity .14s ease-in, transform .14s ease-in; }
.dv-step[data-state="locked"] { opacity: .42; pointer-events: none; }
.dv-step[data-state="locked"] .dv-step-body { display: none; }

/* Food Station's own hard gate: a locked step is fully
   invisible, not just dimmed. Scoped to .food-station-step only — Drinks
   Station shares the plain .dv-step[data-state="locked"] rule above
   (faded-but-visible) and that stays untouched. This is what makes Step 3
   genuinely not there until Step 2's Continue button is tapped, matching
   the intended pre-mockup behaviour. */
.food-station-step[data-state="locked"] { display: none; }

/* Drinks Station gets the same hard-hide treatment — a locked step is
   genuinely not there, not just faded. Scoped to .drinks-station-step only, same
   reasoning as the food-only rule above: nothing else shares .dv-step's
   plain faded-locked look by accident. */
.drinks-station-step[data-state="locked"] { display: none; }

/* ---- scrolling picker (same pattern as the food station) ------------ */
.dv-search {
  width: 100%; padding: 11px 14px; border-radius: 14px;
  border: 2px solid var(--bg2); background: var(--bg2); color: var(--ink);
  font: inherit; font-weight: 700; font-size: .9rem; margin-bottom: 10px;
}
.dv-search::placeholder { color: var(--ink-soft); font-weight: 700; }
.dv-rail { display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 8px; scrollbar-width: none; }
.dv-rail::-webkit-scrollbar { display: none; }
.dv-chip {
  flex: 0 0 auto; min-width: 76px; padding: 10px 12px; border-radius: 16px;
  background: var(--bg2); border: 2px solid transparent; color: var(--ink);
  font: inherit; font-weight: 800; font-size: .76rem; text-align: center; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 4px; line-height: 1.15;
}
.dv-chip .dv-emo { font-size: 1.35rem; }
.dv-chip .dv-sub { font-size: .64rem; font-weight: 700; color: var(--ink-soft); }
.dv-chip[aria-pressed="true"] { border-color: var(--sky); background: var(--sprout-green-tint); }
.dv-chip:focus-visible { outline: 3px solid var(--sun); outline-offset: 2px; }
.dv-rail-hint { font-size: .7rem; font-weight: 700; color: var(--ink-soft); margin: 2px 0 0; }

/* ---- "last time" — INFORMATION ONLY, never a shortcut button --------
   Nothing here is tappable and nothing here fills a field in. It is a
   memory jog sitting above the ordinary picker, not a way around it. */
.dv-lasttime {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px; padding: 8px 12px;
  border-radius: 12px; background: var(--dv-surface); border: 1px dashed var(--dv-line);
  font-size: .74rem; font-weight: 700; color: var(--ink-soft);
}
.dv-lasttime b { color: var(--ink); }

/* .dv-prefill carries its own display:flex, so without this line a leftover
   dilution summary would stay visible after switching straight from squash to
   another drink. (.dv-sf, the old sugar-free checkbox, is gone — sugar-free is
   a required chip question now, see .dv-choice below.) */
.dv-dilute[hidden], .dv-maths[hidden],
.dv-stepper[hidden], .dv-prefill[hidden], .dv-lasttime[hidden] { display: none !important; }

/* ---- required questions inside Step 1 --------------------------------
   The sugar-free question and the squash dilution question are the same
   kind of thing: something that has to be answered before Step 1 counts,
   asked as chips rather than a tick. They share a shell and share the
   .dv-ratio chip. Amber stays reserved for the squash warning; the
   sugar-free question is an ordinary question, so it wears sky. */
.dv-choice[hidden] { display: none !important; }
.dv-choice {
  margin-top: 12px; padding: 12px; border-radius: 16px;
  background: var(--sprout-green-tint); border: 1.5px solid var(--sky);
}
.dv-choice h3 { margin: 0 0 3px; font-size: .86rem; font-family: 'Baloo 2', Nunito, sans-serif; font-weight: 800; color: var(--sky); }
.dv-choice p { margin: 0 0 10px; font-size: .74rem; font-weight: 700; color: var(--ink-soft); line-height: 1.4; }
.dv-choice .dv-ratio[aria-pressed="true"] { border-color: var(--sky); background: var(--sprout-green-tint); }

/* ---- nutrition-label pointer (manual-entry path only) -----------------
   Small illustrative "where to look" graphic, brought back from an older
   design for the "I know the carbs" path — pairs a
   plain example nutrition-facts rectangle with the "Carbohydrate" row
   highlighted, alongside the existing pointer copy. The SVG carries no
   real data (30g is a placeholder, not this food's actual figure) so it
   can never be mistaken for a live value. */
.fs-label-hint[hidden] { display: none !important; }
.fs-label-hint {
  display: flex; align-items: center; gap: 12px;
  margin: 4px 0 12px; padding: 10px; border-radius: 14px;
  background: var(--dv-surface); border: 1.5px solid var(--dv-line);
}
.fs-label-hint-icon { flex: 0 0 auto; width: 58px; height: auto; }
.fs-label-hint-txt { margin: 0; font-size: .78rem; font-weight: 700; color: var(--ink-soft); line-height: 1.4; }
.fs-label-hint-txt strong { color: var(--ink); }

/* .fs-manual-heading (a plain <p> replacing #fsOwnBtn) was here briefly
   (25 Aug 2026) but removed the same day once the nutrition-label hint
   above was added — its own copy ("See Carbohydrate... Type that number
   below") already said the same thing the heading did, one line down. */

/* ---- Step 1's front door: "what do you know already?" ---------------
   The real first decision, replacing a carousel
   sitting next to a demoted "skip, it's optional" button that three
   rounds of restyling that button couldn't fix — the button was never
   the wrong element, Step 1 was asking the wrong question first. Shares
   .dv-choice's shell/colours for visual consistency with the rest of the
   app's required-question pattern, but sized up: this is the single most
   important decision on the screen, not a minor sub-question, so it gets
   two large equal-weight cards rather than compact inline chips. Neither
   card carries extra visual weight over the other on purpose — this is a
   fork, not a default with an opt-out link beside it. */
.fs-knowledge-choice { margin-top: 0; }
.fs-knowledge-cards { gap: 10px; }
.fs-knowledge-btn.dv-ratio {
  position: relative;
  flex: 1 1 45%; display: flex; flex-direction: column; align-items: center;
  gap: 4px; padding: 18px 10px; min-height: 128px; text-align: center;
}
/* Numbered corner badge ("1" / "2" on the two "What do you know
   already?" cards) removed — the two cards are an
   equal-weight fork (pick whichever matches your situation), not
   sequential steps, and the numbering read as implying an order that
   doesn't exist. An icon-only alternative was mocked up and also
   rejected on looks, so the badge is gone entirely rather than
   replaced. Markup: the <span class="fs-knowledge-badge"> elements
   removed from both cards in index.html. */
.fs-knowledge-icon { font-size: 1.7rem; line-height: 1; margin-bottom: 2px; }
/* Image variant for sprout-thinking.svg / sprout-calculator.svg — sized
   up from smaller values that both read as "too small". Tested 52/64/72/80/88px live: the card has no fixed
   height (flex column, grows to fit content) so nothing hard-clips even
   at 88px, but by 88px the icon starts crowding the card's top border
   and the card grows noticeably taller than the barcode shortcut beneath
   it. 72px is the largest size that still leaves comfortable padding on
   all sides. */
.fs-knowledge-icon-img { width: 72px; height: 72px; object-fit: contain; }
.fs-knowledge-title { font-size: .88rem; font-weight: 800; color: var(--ink); }
.fs-knowledge-btn .dv-r-sub { font-size: .68rem; margin-top: 3px; }
.fs-knowledge-btn[aria-pressed="true"] {
  border-color: var(--sky); background: var(--sprout-green-tint);
}
/* Barcode shortcut — a lighter-weight link under the two knowledge
   cards, not a third fs-knowledge-btn — scanning is
   really the fastest form of EITHER answer above, not a third kind of
   knowledge, so it shouldn't visually compete with the fork itself —
   same demotion the rest of the app gives to "a faster way" affordances
   next to a required question. #barcodeScanChip keeps its id;
   barcode/scanner.js finds and wires it purely by that id, unaffected by
   this class name change from the old .barcode-scan-chip-pinned. */
/* Filled to match the two knowledge cards' solid look — wanted it
   reading as equally important to "I know the carbs" /
   "I need to work it out", not a lesser afterthought — same
   var(--dv-inset) fill those cards use. Kept the dashed border rather
   than adopting their border:2px-solid-transparent-until-pressed
   treatment — the dash is what still visually marks this as a
   shortcut/alternate path
   rather than a third fork option, even though it's no longer visually
   lighter-weight than the two cards above it. */
.fs-barcode-shortcut {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 10px; padding: 10px 12px; border-radius: 12px;
  background: var(--dv-inset); border: 1.5px dashed var(--dv-line);
  color: var(--sky); font: inherit; font-weight: 700; font-size: .8rem;
  cursor: pointer;
}
.fs-barcode-icon {
  width: 20px; height: 15px; flex: 0 0 auto;
  /* Flat white (confirmed via screenshot against the
     actual dark panel on screen) rather than var(--sky) — the icon was
     genuinely hard to spot at a glance against this panel's dark
     background even though it technically passed a contrast-ratio check.
     Caveat worth flagging if this surfaces again: this panel's background
     (--sprout-green-tint over --card) is a pale near-white in the
     default/rainbow/caregiver themes, not dark like the theme shown here
     — white bars would likely wash out there the way --sky did here.
     Left as a flat colour rather than per-theme for now since fixing the
     reported visibility issue in the dark theme took
     priority; if a light-theme visibility complaint comes in, this is
     where to add a per-theme override. */
  color: #fff;
}
.fs-barcode-shortcut:active { transform: scale(0.98); }
.fs-barcode-shortcut:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.fs-barcode-shortcut:disabled { opacity: .55; cursor: wait; }

/* ============================================================
   FAVOURITES SHORTCUT ON THE FRONT DOOR — see the
   matching comment block in index.html above #favShortcutBtn for the
   full revert note. This block (down to "END") can be deleted as one
   unit; nothing else needs to change. Mirrors .fs-barcode-shortcut's
   layout properties directly (padding, gap, border-radius, fill) rather
   than sharing a class, so the two remain independently revertable —
   removing this block cannot affect the barcode shortcut's own styling,
   and vice versa. Accent colour is var(--sun) (gold) instead of
   var(--sky) purely so the two shortcuts are visually distinguishable
   from each other at a glance, matching the approved mockup.
   ============================================================ */
.fs-fav-shortcut {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 10px; padding: 10px 12px; border-radius: 12px;
  background: var(--dv-inset); border: 1.5px dashed var(--sun);
  color: var(--sun-ink); font: inherit; font-weight: 700; font-size: .8rem;
  cursor: pointer;
}
.fs-fav-shortcut-icon { font-size: 1.05rem; line-height: 1; flex: 0 0 auto; }
.fs-fav-shortcut:active { transform: scale(0.98); }
.fs-fav-shortcut:focus-visible { outline: 3px solid var(--sun); outline-offset: 2px; }
/* END favourites shortcut on the front door */

/* ---- squash dilution — mandatory, not optional ---------------------- */
.dv-dilute {
  margin-top: 12px; padding: 12px; border-radius: 16px;
  background: rgba(255, 201, 60, .10); border: 1.5px solid rgba(255, 201, 60, .45);
}
.dv-dilute h3 { margin: 0 0 3px; font-size: .86rem; font-family: 'Baloo 2', Nunito, sans-serif; font-weight: 800; color: var(--sun-ink); }
.dv-dilute p { margin: 0 0 10px; font-size: .74rem; font-weight: 700; color: var(--ink-soft); line-height: 1.4; }
.dv-ratios { display: flex; gap: 7px; flex-wrap: wrap; }
.dv-ratio {
  flex: 1 1 auto; padding: 9px 6px; border-radius: 12px; background: var(--dv-inset);
  border: 2px solid transparent; color: var(--ink); font: inherit; font-weight: 800;
  font-size: .76rem; cursor: pointer;
}
.dv-ratio .dv-r-sub { display: block; font-size: .62rem; font-weight: 700; color: var(--ink-soft); margin-top: 2px; }
.dv-ratio[aria-pressed="true"] { border-color: var(--sun); background: rgba(255, 201, 60, .18); }
/* "Not sure" shares its 1:4 factor with a confident direct pick, but must
   never look the same once selected — the caregiver still doesn't know
   the actual ratio, and the UI shouldn't imply otherwise. Dashed instead
   of solid, plus the maths line below carries an explicit "assumed" tag
   (see .dv-assumed-tag). */
.dv-ratio[data-ratio-id="?"][aria-pressed="true"] {
  border-style: dashed;
  border-color: rgba(214, 108, 26, .75);
  background: rgba(214, 108, 26, .12);
}
.dv-maths {
  margin-top: 10px; padding: 9px 11px; border-radius: 11px; background: var(--dv-inset);
  font-size: .78rem; font-weight: 800; line-height: 1.5;
}
.dv-maths .dv-was { color: var(--ink-soft); text-decoration: line-through; }
.dv-maths .dv-now { color: var(--sun-ink); font-size: 1rem; }
.dv-assumed-tag {
  display: inline-block; margin-top: 4px; padding: 3px 8px; border-radius: 999px;
  background: rgba(214, 108, 26, .15); color: #A85416; font-size: .66rem;
  font-weight: 800; letter-spacing: .02em;
}

/* ---- amount --------------------------------------------------------- */
.dv-stepper { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.dv-sbtn {
  width: 46px; height: 46px; border-radius: 14px; border: none; background: var(--sprout-green);
  color: #fff; font-size: 1.3rem; font-weight: 800; cursor: pointer; flex: 0 0 auto;
  display: grid; place-items: center; padding: 0;
}
.dv-valbox { flex: 1; background: var(--bg2); border-radius: 14px; padding: 9px; text-align: center; }
.dv-valbox input {
  width: 100%; background: none; border: none; color: var(--ink);
  font-family: 'Baloo 2', Nunito, sans-serif; font-size: 1.5rem; font-weight: 800; text-align: center;
}
.dv-valbox input:focus { outline: none; }
.dv-u { font-size: .68rem; font-weight: 700; color: var(--ink-soft); }

/* ---- carbs — the "must agree" step ----------------------------------
   .dv-prefill is a real button, not a static box. It must be TAPPED to
   accept the number, every single time. There is no state in which this
   value silently becomes "answered" on its own. */
.dv-linkish {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 100%; padding: 13px 12px; border-radius: 14px;
  background: var(--sprout-green); border: none; color: #fff; font: inherit;
  font-weight: 800; font-size: .92rem; text-align: center; cursor: pointer;
  box-shadow: 0 4px 10px rgba(14, 140, 122, .3);
}
.dv-linkish:active { transform: scale(0.98); }
.dv-linkish-badge {
  font-size: .66rem; font-weight: 800; text-transform: uppercase; letter-spacing: .02em;
  background: rgba(255, 255, 255, .22); padding: 3px 9px; border-radius: 20px;
}
.dv-linkish-main { font-size: .9rem; }
.dv-or-divider { text-align: center; font-size: .68rem; font-weight: 700; color: var(--ink-soft); margin: 10px 0 8px; }
/* Clearly the secondary option next to the solid green "own bottle"
   button, but with real button affordance — a visible border and a
   tap-hint strip, not muted static-looking text. */
.dv-prefill {
  display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: 14px;
  background: var(--dv-surface); border: 2px solid var(--sky);
  width: 100%; text-align: left; font: inherit; cursor: pointer; color: inherit;
}
.dv-prefill:active { transform: scale(0.98); background: var(--sprout-green-tint); }
.dv-prefill .dv-big { font-family: 'Baloo 2', Nunito, sans-serif; font-size: 1.3rem; font-weight: 800; color: var(--sky); }
.dv-prefill .dv-src { font-size: .66rem; font-weight: 800; color: var(--sky); text-transform: uppercase; letter-spacing: .02em; display: block; margin-bottom: 2px; }
.dv-prefill .dv-txt { font-size: .72rem; font-weight: 700; color: var(--ink-soft); line-height: 1.35; }
.dv-prefill .dv-tap-hint {
  font-size: .68rem; font-weight: 800; color: var(--card); margin-top: 6px;
  display: inline-block; background: var(--sky); padding: 4px 9px; border-radius: 20px;
}

/* ---- result --------------------------------------------------------- */
.dv-result {
  margin-top: 14px; padding: 14px; border-radius: var(--radius-md); text-align: center;
  background: var(--dv-inset);
}
.dv-result .dv-n { font-family: 'Baloo 2', Nunito, sans-serif; font-size: 2rem; font-weight: 800; color: var(--sky); display: block; }
.dv-result .dv-l { font-size: .76rem; font-weight: 700; color: var(--ink-soft); }

/* ============================================================
   QUICK-LOG NAMING PROMPT (added 25 Aug 2026) — see the matching
   comment block in index.html above #fsNamePrompt for the full
   revert note. This entire block (down to the "END" comment) can
   be deleted as a single unit with nothing else needing to change.
   ============================================================ */
.fs-name-prompt[hidden] { display: none !important; }
.fs-name-prompt {
  margin-top: 12px; padding: 12px; border-radius: 14px;
  background: rgba(63,169,245,0.10); border: 1.5px dashed var(--sky);
  display: flex; flex-direction: column; gap: 8px;
}
@media (prefers-reduced-motion: no-preference) {
  .fs-name-prompt { animation: fsNamePromptIn .2s ease-out; }
  @keyframes fsNamePromptIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
}
.fs-name-prompt-label { font-size: .78rem; font-weight: 800; color: var(--ink); }
.fs-name-prompt-sub { font-size: .72rem; color: var(--ink-soft); font-weight: 600; margin-top: -4px; }
.fs-name-prompt-row { display: flex; gap: 8px; }
.fs-name-prompt-input {
  flex: 1; min-width: 0; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--dv-line);
  /* Was .85rem (13.6px) — under Safari's 16px auto-zoom-on-focus
     threshold. TO REVERT: back to .85rem. */
  background: var(--dv-inset); color: var(--ink); font: inherit; font-size: 1rem;
}
.fs-name-prompt-input::placeholder { color: var(--ink-soft); opacity: .7; }
.fs-name-prompt-input:focus-visible { outline: 2px solid var(--sky); border-color: var(--sky); }
.fs-name-prompt-save {
  padding: 10px 16px; border-radius: 10px; border: none;
  background: var(--sky); color: white; font: inherit; font-weight: 800;
  font-size: .82rem; cursor: pointer; white-space: nowrap;
}
.fs-name-prompt-save:active { transform: scale(0.97); }
.fs-name-prompt-save:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.fs-name-prompt-skip {
  align-self: flex-end; background: none; border: none; color: var(--ink-soft);
  font: inherit; font-size: .72rem; font-weight: 700; cursor: pointer;
  text-decoration: underline; padding: 2px;
}
.fs-name-prompt-skip:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
/* END quick-log naming prompt */

.drinks-v2 .drink-go-btn { width: 100%; margin-top: 12px; }

@media (prefers-reduced-motion: no-preference) {
  .dv-step[data-state="open"] .dv-step-body { animation: dvIn .18s ease-out; }
  @keyframes dvIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
}

/* ====================================================================
   FOOD STATION — food-station-mockup.html (14 Aug 2026)

   The step shell, chips, required-question panels, steppers, prefill
   button and result block are the Drinks Station's .dv-* classes,
   reused rather than duplicated: the mockup's own CSS comment says the
   shell was "lifted wholesale from the Drinks Station", so two copies
   of it would only be two things to drift apart.

   Only what is genuinely food-only lives here. Every colour is a
   per-theme var() — a hardcoded rgba(255,255,255,…) looks right in
   theme-night and vanishes in the light, rainbow, caregiver and
   high-contrast themes.
   ==================================================================== */

.food-station-step .dv-step-opt {
  font-size: .7rem; font-weight: 700; color: var(--ink-soft);
}
/* "(optional)" is guidance for ANSWERING the step. Once it's answered and
   collapsed the word is noise, and it was competing with the answer chip for
   width — "What's on your plate?" wrapped to two lines the moment you picked
   a food. Hiding it once the step closes fixes the wrap and says something
   truer at the same time. */
.food-station-step:not([data-state="open"]) .dv-step-opt { display: none; }

/* Step 1's body is the app's real picker, not the mockup's stub rail, so
   the picker keeps its own layout and only loses the header it used to
   carry (that job belongs to .dv-step-head now). */
.food-station-step .food-emoji-picker {
  background: none; border: none; padding: 0; margin: 0; box-shadow: none;
}
.food-station-step .food-picker-purpose {
  font-size: .72rem; font-weight: 700; color: var(--ink-soft);
  line-height: 1.4; margin: 0 0 10px;
}

/* Skip lives above the food grid now — buried at the
   bottom of a scrolling chip grid, it wasn't obvious the picker could be
   skipped at all without scrolling past every chip first. Originally
   given full solid-button weight, same as .dv-linkish elsewhere, so it
   wouldn't read as fine print.

   Downgraded to outline weight: at the very top of Step 1 — the first
   thing the whole flow shows — a big solid-blue full-width button reads
   as "start here", directly fighting the "What's on your plate?" heading
   and the carousel below it for primary-action attention. A real packet
   number is still more accurate than a CoFID typical value, so this stays
   a real, easy-to-find button — just outline weight instead of solid, so
   the carousel is unambiguously the visual default and this is
   unambiguously the deliberate detour around it. */
.fs-skip-row { display: flex; justify-content: center; margin: 0 0 4px; }
.fs-skip-btn.dv-linkish {
  margin-top: 4px;
  background: transparent; color: var(--sky);
  border: 2px solid var(--sky); box-shadow: none;
}
.fs-skip-btn .dv-linkish-badge { background: var(--dv-inset); color: var(--sky); }
body.theme-night .fs-skip-btn.dv-linkish { background: transparent; }
.fs-skip-btn:focus-visible { outline: 3px solid var(--sun); outline-offset: 2px; }
/* The divider between Skip and the grid — matches the approved mockup:
   centred text with a line either side, not bare
   caption text. Exists so Skip-then-grid reads as two equally valid
   starting points ("or pick a food below"), not as Skip being the
   recommended default with the grid as an afterthought. */
.fs-skip-divider {
  text-align: center; font-size: .68rem; font-weight: 700; color: var(--ink-soft);
  margin: 14px 0; display: flex; align-items: center; gap: 8px;
}
.fs-skip-divider::before, .fs-skip-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--dv-line);
}

/* The portion guide, and the bread panel's escape hatch. */
.fs-guide {
  margin-top: 10px; padding: 9px 11px; border-radius: 11px; background: var(--dv-inset);
  font-size: .72rem; font-weight: 700; color: var(--ink-soft); line-height: 1.6;
}
.fs-guide[hidden] { display: none !important; }
.fs-guide ul { margin: 0; padding-left: 18px; }

.food-station-step .bread-own-numbers-btn {
  display: block; width: 100%; margin-top: 10px; background: none; border: none;
  color: var(--ink-soft); font: inherit; font-size: .72rem; font-weight: 800;
  text-decoration: underline; cursor: pointer; padding: 6px 0 0;
}

/* Three portion chips have longer labels than the drinks station's two, so
   they get a floor width to stop "📦 Packet says" wrapping to three lines
   on a narrow phone. */
.food-station-step #portionCheck .dv-ratio { flex: 1 1 30%; min-width: 96px; }

/* The evidence disclosure — the one addition to the mockup, agreed 14 Aug.
   Deliberately quiet: it sits under the prefill button as a secondary way
   in, never competing with the two required buttons above it. */
.fs-src-evidence { margin-top: 8px; }
.fs-src-evidence[hidden] { display: none !important; }

/* Step 2's gate button. Reuses .go-btn's look (same visual weight as the
   final Add button) but sits mid-step, not at the foot of the card, so it
   needs its own top margin instead of .go-btn's. Appears once the carbs
   figure is settled; tapping it is the ONLY way Step 3 is revealed
   (see .food-station-step[data-state="locked"] above). */
.fs-continue-btn { margin-top: 14px; margin-bottom: 0; }
.fs-continue-btn[hidden] { display: none !important; }

/* Drinks Station's own Continue gate buttons — same look, same rules. */
.dv-continue-btn { margin-top: 14px; margin-bottom: 0; }
.dv-continue-btn[hidden] { display: none !important; }

/* The result block is .dv-result, but food adds the favourite/scanned
   provenance note on its own line under the caption. */
.dv-result .fs-fav-note { display: block; margin-top: 6px; }
.dv-result .fs-fav-note[hidden] { display: none !important; }
.dv-result .fs-fav-note b { color: var(--ink); }

/* The mockup's readonly slice box must not look like a field you can type
   into — it is driven entirely by the − / + either side of it. */
#breadPresetSliceCount { cursor: default; }
