      /* ---------- Pet care screen ---------- */
      .pet-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
      .pet-head .ph-name { font-size: 28px; font-weight: 800; }
      .pet-head .ph-hearts { font-size: 20px; letter-spacing: 2px; }
      .pet-stage {
        display: flex; align-items: center; gap: 14px; margin: 8px 0 4px;
        padding: 10px 12px; border: 3px solid #4cb944; border-radius: 24px; box-shadow: var(--shadow);
        /* v74: no painted sun/clouds in the backdrop gradient — the
           injected SVG scenery (anim.js) owns the ONE sun and the
           drifting clouds. The old gradient sun sat at 88%/16%,
           directly under the speaker button, and read as a second
           sun cut in half (owner QA 2026-10-27). */
        background: linear-gradient(180deg, #8fd8ff 0%, #c8f2ff 54%, #93e77e 54.5%, #63d64f 100%);
      }
      .pet-face { width: 148px; height: 148px; flex: 0 0 auto; }
      .pet-face svg { width: 100%; height: 100%; display: block; }
      .pet-art { width: 100%; height: 100%; }
      .pet-pixi-host { position: absolute; inset: 0; z-index: 1; }
      .pet-pixi-host canvas { display: block; }
      .pet-colors { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 12px 0 2px; }
      .pet-colors .pc-label { font-size: 18px; font-weight: 800; color: var(--ink-soft); }
      .pc-row { display: flex; gap: 9px; flex-wrap: wrap; }
      .pc-swatch { width: 46px; height: 46px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 2px 6px rgba(35,50,70,.28); padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
      .pc-swatch.active { border-color: #ffb703; transform: scale(1.14); box-shadow: 0 0 0 3px #ffb703, 0 2px 6px rgba(35,50,70,.28); }
      /* v67: the bubble is a COMIC speech bubble in every context —
         near-white fill, thick ink outline, two-layer tail.
         v78: rounder, softer cloud shape (bi: the square box looked
         plain) — a big friendly radius everywhere it appears. */
      .bubble {
        flex: 1 1 auto; position: relative; text-align: left;
        background: #fffdf4; border: 3px solid var(--ink); border-radius: 32px;
        padding: 12px 16px; box-shadow: 0 3px 0 rgba(35, 50, 70, .16);
      }
      .bubble::before {
        content: ""; position: absolute; left: -15px; top: 50%; transform: translateY(-50%);
        border: 10px solid transparent; border-right-color: var(--ink); border-left: 0;
      }
      .bubble::after {
        content: ""; position: absolute; left: -8px; top: 50%; transform: translateY(-50%);
        border: 7px solid transparent; border-right-color: #fffdf4; border-left: 0;
      }
      .bubble .b-text { font-size: 23px; font-weight: 800; line-height: 1.3; }
      .bubble .b-big { font-size: 62px; font-weight: 800; line-height: 1.1; color: var(--cat-dark); }
      /* v78: the target group inside the bubble — glyph with its
         name (word / shape name) beside it, so the whole target
         reads with the question. A row, not a column: a stacked
         label made the bubble tall enough to rest on the pet. */
      .bubble .b-target { display: flex; flex-direction: row; align-items: center; gap: 5px; flex: 0 0 auto; }
      .bubble .b-big-label { font-size: 15px; font-weight: 800; line-height: 1.15; color: var(--cat-dark); white-space: nowrap; }
      .bubble .b-big svg { width: 1em; height: 1em; display: block; }
      /* v78: bath — the speech bubble floats in the yard above the
         pet (yard.js placeSpeechBubble sets its top); stage rules
         still supply the tail, which keeps pointing down at the pet. */
      #screen-pet .game-yard .bubble { position: absolute; left: 8px; right: 8px; margin: 0; }
      /* the in-yard perch sits higher above the pet (30px), so its
         tail stretches longer to keep pointing the pet out */
      #screen-pet .game-yard .bubble::before { bottom: -23px; border-width: 13px; }
      #screen-pet .game-yard .bubble::after { bottom: -15px; border-width: 9px; }
      /* v67 typewriter: the full line is laid out from the first
         frame; unrevealed characters are merely transparent. Words
         stay whole — lines never break mid-word (FIT-FIRST). */
      .cb-word { white-space: nowrap; }
      .cb-ch.cb-off { color: transparent; }
      /* v67 idle hint: a soft pulse (transform-free, so it can never
         fight the tray-walk or count-round positioning), and the
         stage pet's glance uses the standalone scale property for
         the same reason. Visual only — see home.js. */
      .bubble.cb-hint, .cbubble.cb-hint { animation: cbHintPulse .9s ease-in-out 3; }
      @keyframes cbHintPulse { 50% { filter: brightness(1.05); box-shadow: 0 0 0 4px rgba(255, 183, 3, .5), 0 3px 0 rgba(35, 50, 70, .16); } }
      #petFace.cb-look { animation: cbLook 2.6s ease; }
      @keyframes cbLook { 0%, 100% { scale: 1; } 30%, 60% { scale: 1.07; } }
      @media (prefers-reduced-motion: reduce) { .bubble.cb-hint, .cbubble.cb-hint, #petFace.cb-look { animation: none; } }
      .bubble .b-speak { margin-top: 8px; min-height: 56px; padding: 8px 20px; font-size: 19px; }
      .bubble .b-speak svg { width: 26px; height: 26px; }

      .mode-panel { display: none; }
      .mode-panel.active { display: block; animation: fadein .25s ease; }
      .trace-wrap { width: min(calc(var(--stage-w) * 0.88), 330px); margin: 10px auto 2px; }
      .trace-stack { position: relative; border: 3px solid var(--line); border-radius: 24px; overflow: hidden; background: #fffef8; line-height: 0; }
      .trace-stack canvas { width: 100%; height: auto; display: block; }
      #traceDraw { position: absolute; inset: 0; touch-action: none; }
      .trace-bar-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
      .trace-bar { flex: 1; height: 14px; background: #e8f4ff; border: 2px solid var(--line); border-radius: 999px; overflow: hidden; }
      .trace-bar > div { height: 100%; width: 0%; background: linear-gradient(90deg, #ffd23c, #0dc2ab); transition: width .15s ease; }
      .trace-pct { font-weight: 800; font-size: 18px; color: var(--ink-soft); min-width: 50px; text-align: right; }
      /* v95 (bi photo QA 2026-10-29 08:26 — "the button row and the
         drawing frame are unreasonable"): the old flex row wrapped
         unpredictably (Check pushed to its own row, ghost pair
         uneven, long JA labels shrank to 12.5px). The actions are
         now a deterministic GRID: Check full-width primary on top,
         Demo | Retry as an equal pair below, all one height family,
         all the board's width — the same stack at every frame and
         every language. */
      /* v99: compacted heights (Check 46, ghosts 44 — the tap
         floor) so the board above them gets the pixels; see the
         --trace-w note in layout.css. */
      #screen-pet #mode-trace .trace-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 5px; }
      #screen-pet #mode-trace .trace-actions button { white-space: nowrap; min-width: 0; width: 100%; }
      #screen-pet #mode-trace .trace-check-btn { grid-column: 1 / -1; min-height: 46px; padding: 7px 26px; font-size: 19px; }
      #screen-pet #mode-trace .trace-actions .ghost-btn { min-height: 44px; padding: 7px 10px; font-size: 17px; }
      /* v95 fit pass: the whole stack (board + progress + ghost
         pair + Check + pick + msg) must end above the floating
         bottom bar — at 414x736 the mode box is only 433 tall, so
         the msg reserves a slimmer line and the ghost labels stay
         on ONE line (a wrapped 2-line ghost row cost 26px and
         pushed the pick row under the bar). */
      #screen-pet #mode-trace .msg { min-height: 22px; margin-top: 4px; font-size: 15.5px; }
      /* trace.js moves Demo+Retry into its own #traceGhostRow
         (inline flex, centred) above the actions — v95 gives that
         row the stack's width and makes the pair EQUAL halves, so
         the whole control column shares one width. */
      #screen-pet #mode-trace #traceGhostRow { width: var(--trace-w, 100%); margin-left: auto; margin-right: auto; }
      #screen-pet #mode-trace #traceGhostRow .ghost-btn { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 7px 6px; font-size: 15.5px; white-space: nowrap; }
      #screen-pet #mode-trace .trace-pick-row { margin-top: 5px; }
      #screen-pet #mode-trace .trace-pick-row .ghost-btn { width: 100%; min-height: 44px; padding: 7px 10px; font-size: 17px; }
      .msg.miss { color: #d6336c; }
      .ghost-btn { background: var(--card); color: var(--ink); border: 3px solid var(--line); border-radius: 999px; padding: 10px 20px; font-size: 17px; font-weight: 800; cursor: pointer; box-shadow: 0 3px 0 var(--line); }
      .ghost-btn:active { transform: translateY(2px); box-shadow: none; }
      .word-pic { font-size: 84px; text-align: center; margin-top: 2px; line-height: 1.15; }
      .word-slots { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 2px; min-height: 64px; }
      .word-slot { width: 52px; height: 60px; border-radius: 14px; border: 3px dashed var(--line); background: #fff; display: flex; align-items: center; justify-content: center; font-size: 34px; font-weight: 900; color: var(--ink); }
      .word-slot.filled { border-style: solid; border-color: var(--teal); background: #e6fffa; }
      .word-tiles { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
      .word-tile { min-width: 56px; height: 64px; padding: 0 8px; border-radius: 16px; border: 3px solid var(--sky); background: #bdeaff; font-size: 32px; font-weight: 900; color: var(--ink); box-shadow: 0 4px 0 var(--sky-dark); cursor: pointer; }
      .word-tile:active { transform: translateY(3px); box-shadow: none; }
      .word-tile.used { opacity: 0; pointer-events: none; }
      .word-target { text-align: center; font-size: 30px; font-weight: 900; color: var(--ink); line-height: 1.9; min-height: 57px; margin-top: -4px; }
      .letter-word { text-align: center; font-size: 23px; font-weight: 800; color: var(--ink); line-height: 1.9; margin-top: 8px; }
      .letter-word .lw-pic { font-size: 26px; }
      /* Kanji + furigana (JP round 1): furigana sits on top of the kanji,
         small and tight; containers grow their line box so rt is never cut. */
      ruby { ruby-align: center; }
      rt { font-size: .52em; font-weight: 700; line-height: 1.05; letter-spacing: .02em; }
      .slot .s-word:has(ruby) { line-height: 1.9; }
      .pick-opt:has(ruby) { line-height: 1.9; }
      .sentence-text:has(ruby) { line-height: 1.95; }
      .game-yard {
        /* v98: overflow visible (was hidden) + isolation — the
           painted backdrop bleeds to the screen edges on the
           ::before below and the injected scenery layer bleeds
           with it (layout.css); the yard's box and every game
           geometry stay in the column. */
        position: relative; height: 300px; margin: 10px 0 2px; overflow: visible; isolation: isolate;
        border-radius: 24px; border: 3px solid #2f9e44;
        /* v74: sun + sky clouds removed from the painted backdrop
           (the yard's injected SVG scenery owns the one sun and the
           drifting clouds); the ground flower dots stay.
           v88 (addendum 1): the backdrop gradient itself now matches
           the stage's — this yard used to carry its own horizon at
           34%, and because the injected ground SVG has NO sky fill
           of its own, that painted grass showed through the SVG's
           transparent sky as a flat green band cutting the scene
           (measured at 390x844, yard 496 tall: band y329-406, the
           34% line at y329 exactly). With the stage's 54% horizon
           the painted horizon hides behind the drawn hills, exactly
           as on the stage. */
        background:
          radial-gradient(circle at 7% 90%, #ff8fb2 0 5px, rgba(255, 143, 178, 0) 8px),
          radial-gradient(circle at 30% 94%, #ffd93c 0 5px, rgba(255, 217, 60, 0) 8px),
          radial-gradient(circle at 68% 91%, #ffffff 0 5px, rgba(255, 255, 255, 0) 8px),
          radial-gradient(circle at 93% 93%, #ff6b6b 0 5px, rgba(255, 107, 107, 0) 8px),
          /* v94 (bi photo QA 2026-10-29 06:35 — "the butterfly game's
             sky is not seamless", same on bath/maze): the slim strip
             above ends its sky at #c8f2ff (responsive.css), but this
             yard restarted the sky from the deep #8fd8ff, so a hard
             horizontal step cut the sky at the strip/yard join on
             every yard game. The yard's sky now STARTS where the
             strip's ends — #c8f2ff held to the horizon — one
             continuous sheet of sky; the deep blue lives only at
             the top of the strip, as in a real sky. */
          /* v95 (bi photo QA 2026-10-29 08:21/08:34 — "the maze
             background is still not seamless"): the v94 sheet fixed
             the strip->yard TOP edge, but the painted horizon at
             54/54.5% was a hard straight line that still showed
             wherever the drawn hills dip below it, over greens that
             are not the hills' own. The backdrop now has NO horizon:
             sky held to 58%, then a long soft fade to the front
             hill's grass family, completed at 84% — the whole fade
             band hides behind the two drawn hill paths (.75/.85
             opacity), so it reads as hill shading, never as a line. */
          linear-gradient(180deg, #c8f2ff 0%, #c8f2ff 58%, #a8e6a1 71%, #6fca5e 84%, #63d64f 100%);
      }
      /* v98: the yard's backdrop, bled to the screen edges behind
         the yard's own box (which keeps the identical painting, so
         the join is invisible). The yard is centred in the
         viewport, so 50% - 50vw lands on the left screen edge. */
      .game-yard::before {
        content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw; z-index: -1;
        background:
          radial-gradient(circle at 7% 90%, #ff8fb2 0 5px, rgba(255, 143, 178, 0) 8px),
          radial-gradient(circle at 30% 94%, #ffd93c 0 5px, rgba(255, 217, 60, 0) 8px),
          radial-gradient(circle at 68% 91%, #ffffff 0 5px, rgba(255, 255, 255, 0) 8px),
          radial-gradient(circle at 93% 93%, #ff6b6b 0 5px, rgba(255, 107, 107, 0) 8px),
          linear-gradient(180deg, #c8f2ff 0%, #c8f2ff 58%, #a8e6a1 71%, #6fca5e 84%, #63d64f 100%);
      }
      .game-yard[hidden] { display: none; }
      .game-yard .pet-face {
        position: absolute; left: 10px; bottom: 12px; width: 168px; height: 168px; z-index: 3;
        transition: transform .5s ease-in-out;
      }
      .game-score { font-size: 21px; font-weight: 800; color: var(--ink-soft); margin-top: 10px; min-height: 28px; text-align: center; }
      /* Chase butterflies (v68): the number/letter rides IN a balloon
         hanging from the butterfly — string + swaying balloon body,
         one unit that glides together. Never a detached badge. */
      .chase-fly {
        position: absolute; z-index: 5; width: 92px; height: 124px; border: none; border-radius: 50%;
        font-size: 25px; font-weight: 800; color: #233246; cursor: pointer;
        display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
        background: none;
        filter: drop-shadow(0 4px 4px rgba(35,50,70,.25));
      }
      /* v78 addendum (bi QA on the v77 build): NO white disc/halo
         behind the butterfly — the bare butterfly + string +
         balloon, as originally designed. The wings FOLD around the
         body axis (rotateY), they do not rock flat; the body dips
         with each fold. Flap tempo follows the flight (yard.js
         chaseFlap sets the duration per glide leg; leaving and
         marked butterflies flutter fast via the state rules). */
      .chase-fly .cf-fly { display: inline-block; font-size: 44px; line-height: 1.1; padding: 0 7px; animation: wingFlap .5s ease-in-out infinite alternate; }
      .chase-fly.cf-leaving .cf-fly { animation-duration: .16s !important; }
      .chase-fly.cf-marked .cf-fly { animation-duration: .18s !important; }
      @keyframes wingFlap {
        from { transform: perspective(200px) rotateY(-36deg) rotate(-3deg) translateY(1px); }
        to { transform: perspective(200px) rotateY(36deg) rotate(3deg) translateY(-3px); }
      }
      .chase-fly .cf-balloon {
        display: flex; flex-direction: column; align-items: center; pointer-events: none;
        transform-origin: 50% -4px; animation: balloonSway 1.9s ease-in-out infinite alternate;
      }
      .chase-fly .cf-balloon::before {
        content: ""; width: 2px; height: 11px; border-radius: 2px;
        background: repeating-linear-gradient(180deg, rgba(35,50,70,.55) 0 3px, rgba(35,50,70,.28) 3px 6px);
      }
      @keyframes balloonSway { from { transform: rotate(-3.6deg); } to { transform: rotate(3.6deg); } }
      .chase-fly .cf-num {
        position: relative; width: 47px; height: 55px;
        border-radius: 50% 50% 50% 50% / 55% 55% 45% 45%;
        background: radial-gradient(circle at 32% 26%, #ffc2cf 0 16%, #ff7086 46%, #f43f5e 100%);
        display: flex; align-items: center; justify-content: center;
        font-size: 26px; font-weight: 800; color: #fff; text-shadow: 0 1px 2px rgba(120,10,35,.45);
        box-shadow: inset -4px -6px 10px rgba(160,10,40,.25), 0 3px 6px rgba(35,50,70,.25);
      }
      .chase-fly .cf-num::before {
        content: ""; position: absolute; top: -4px; left: 50%; transform: translateX(-50%);
        border: 4px solid transparent; border-top: none; border-bottom: 5px solid #f43f5e;
      }
      /* tapped-right: the glide freezes (yard animator skips marked
         props) and the balloon wiggles while the pet runs over */
      .chase-fly.cf-marked .cf-balloon { animation-duration: .45s; }
      .bath-bubble.cf-marked { box-shadow: 0 0 0 4px rgba(255,183,3,.8), inset 0 0 14px rgba(255,255,255,.8); }
      /* v77: the caught butterfly no longer shrinks away in place —
         only its balloon bursts; the butterfly itself flutters off
         the yard via yardFlyOut (.cf-leaving below). */
      .chase-fly.caught .cf-balloon { animation: none; }
      .chase-fly.caught .cf-balloon::before { opacity: 0; }
      .chase-fly.caught .cf-num { animation: balloonBurst .3s ease-out forwards; }
      /* v77: leaving props are owned by yardFlyOut's WAAPI flight;
         entering bath bubbles fade/rise in via WAAPI too. */
      .chase-fly.cf-leaving, .bath-bubble.cf-leaving { pointer-events: none; }
      .chase-fly.cf-leaving .cf-fly { animation-duration: .16s; }
      @keyframes balloonBurst { 35% { transform: scale(1.3); opacity: 1; } 100% { transform: scale(1.9); opacity: 0; } }
      .yard-burst {
        position: absolute; z-index: 8; pointer-events: none; line-height: 1;
        font-size: 17px; color: #ffb703; transform: translate(-50%,-50%);
        text-shadow: 0 1px 2px rgba(35,50,70,.35);
      }
      /* Bath bubbles: the hit-box stays still; only the letter inside bobs */
      .bath-bubble {
        position: absolute; z-index: 5; border-radius: 50%; cursor: pointer;
        background: radial-gradient(circle at 32% 28%, rgba(255,255,255,.95) 0 12%, rgba(190,235,255,.55) 45%, rgba(140,205,255,.4));
        border: 3px solid rgba(120,190,240,.75);
        display: flex; align-items: center; justify-content: center;
        font-size: 40px; font-weight: 800; color: #1c5d8f;
        box-shadow: inset 0 0 14px rgba(255,255,255,.8);
      }
      .bath-bubble .bb-ch { display: block; animation: bubbleBob 2.4s ease-in-out infinite alternate; }
      @keyframes bubbleBob { from { transform: translateY(-3px); } to { transform: translateY(3px); } }
      .bath-bubble.popped { animation: bubblePop .3s ease-out forwards; }
      @keyframes bubblePop { to { transform: scale(1.5); opacity: 0; } }
      .dirt-spot {
        position: absolute; z-index: 4; border-radius: 50%; pointer-events: none;
        background: radial-gradient(circle, rgba(122,84,40,.55), rgba(122,84,40,.15) 70%, transparent);
      }
      .pet-face.is-dirty .pet-svg, .pet-face.is-dirty .pet-pixi-host { filter: sepia(.45) saturate(.75) brightness(.94); }
      /* v23: legacy-SVG fallback flip so the pet faces the tray from
         either side (the Pixi renderer flips via setDirection). */
      .pet-face.face-left #petArt { transform: scaleX(-1); }
      .pet-face.is-shaking .pet-svg, .pet-face.is-shaking .pet-pixi-host { animation: petShakeDry .12s ease-in-out 9 alternate; }
      @keyframes petShakeDry { from { transform: rotate(-4.5deg) translateX(-4px); } to { transform: rotate(4.5deg) translateX(4px); } }
      .pet-face.game-pounce .pet-svg, .pet-face.game-pounce .pet-pixi-host { animation: gamePounce .45s ease-in-out 1; }
      @keyframes gamePounce { 35% { transform: translateY(-30px) scale(1.06); } 70% { transform: translateY(2px) scale(.98); } }
      @media (max-width: 520px) {
        .game-yard { height: 272px; }
        .game-yard .pet-face { width: 148px; height: 148px; }
        .chase-fly { width: 82px; height: 110px; }
        .chase-fly .cf-fly { font-size: 38px; }
        .chase-fly .cf-num { width: 42px; height: 49px; font-size: 23px; }
      }
      @media (prefers-reduced-motion: reduce) {
        .chase-fly .cf-fly, .bath-bubble .bb-ch, .chase-fly .cf-balloon { animation: none; }
        .game-yard .pet-face { transition: none; }
        .maze-goal .food-art, #screen-pet .tray-mini.flop, .food-btn.refill { animation: none; }
      }

      /* v54: the fed counter is a big-number badge right by the bowl —
         the numeral dwarfs the label so a pre-reader can read the
         count at a glance; it updates the instant anything changes. */
      .bowl-count {
        width: fit-content; max-width: 94%; margin: 10px auto 0;
        font-size: 16px; font-weight: 700; color: var(--ink-soft);
        background: #fff3c4; border: 3px solid #ffd23f; border-radius: 999px;
        padding: 1px 16px 4px; text-align: center;
      }
      .bowl-count b { font-size: 30px; font-weight: 900; color: var(--ink); vertical-align: -4px; white-space: nowrap; }
      .pond { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; margin-top: 14px; }
      /* v23: eaten pond items collapse out of the layout (they stay in
         the DOM — index-based flows like auto-eat and divide rely on
         child order) so the visible pile stays small; refills pop in. */
      .food-btn.gone { display: none !important; }
      /* v100 (bi photo QA 2026-10-29 15:50 — count pond tiles
         collapsed out and everything slid left): in the NON-heap
         count pond a .gone tile keeps its grid box as an invisible
         placeholder, so no neighbour ever moves; pondRefill in
         count.js swaps the earliest placeholder for the refill in
         the same DOM position. Heap/bowl ponds (absolute slots)
         and the feed pond keep the collapse rule above. */
      #mode-count .pond:not(.heap) .food-btn.gone,
      #mode-feed .pond:not(.heap) .food-btn.gone { display: flex !important; visibility: hidden; pointer-events: none; }
      .food-btn.refill { animation: foodPop .28s ease-out; }
      @keyframes foodPop { from { transform: scale(.35); opacity: 0; } to { transform: scale(1); opacity: 1; } }
      /* v23: counting questions with many objects group them in tens. */
      /* (selectors carry #mode-count so they outrank the .dense* sizing
         rules — otherwise the denser SVG caps break the rows of ten) */
      #mode-count .pond.banded { display: flex; flex-wrap: wrap; gap: 4px 3px; align-items: flex-start; }
      #mode-count .pond.banded .food-btn {
        flex: 0 0 calc((100% - 39px) / 10 - 1px); min-height: 24px; min-width: 0;
        padding: 1px; border-width: 2px; border-radius: 8px; box-sizing: border-box;
      }
      #mode-count .pond.banded .food-btn:nth-child(10n) { margin-right: 9px; }
      #mode-count .pond.banded .food-btn svg { max-width: 15px; max-height: 15px; }
      #mode-count .pond.banded.compact .food-btn { min-height: 19px; border-radius: 7px; }
      #mode-count .pond.banded.compact .food-btn svg { max-width: 13px; max-height: 13px; }
      .food-btn {
        background: #bdeaff; border: 3px solid #57b6f7; border-radius: 20px;
        min-height: 76px; min-width: 0; padding: 6px 2px; display: flex; align-items: center; justify-content: center;
        transition: transform .15s ease, opacity .3s ease;
      }
      .food-btn svg { width: 100%; max-width: 52px; height: auto; }
      .food-btn:active { transform: scale(.9); }
      .food-btn.eaten { opacity: 0; transform: scale(.3) translateY(14px); pointer-events: none; }
      /* v54: HEAP presentation for the feeding variants — the pond is
         a bowl (interior + front wall drawn by the pond itself) and
         the items are absolutely placed in three depth rows by
         heapSlotPos() in count.js: back row higher/smaller, front row
         overlapping it, the bowl wall tucking the front row's bottom
         edge so the pile reads as sitting INSIDE the bowl. Refills
         DROP in from above instead of popping at a grid end. */
      #mode-count .pond.heap { position: relative; display: block; height: 168px; margin-top: 10px; }
      #mode-count .pond.heap::before {
        content: ""; position: absolute; left: 4%; right: 4%; top: 4%; bottom: 10%; z-index: 0;
        background: radial-gradient(ellipse 92% 100% at 50% 28%, #ffedd6, #ffd3a3 68%, #ffc384);
        border-radius: 50%;
        box-shadow: inset 0 -16px 24px rgba(190, 110, 30, .35), inset 0 10px 16px rgba(255, 255, 255, .55);
      }
      #mode-count .pond.heap::after {
        content: ""; position: absolute; left: 1%; right: 1%; bottom: 0; height: 19%; z-index: 3;
        background: linear-gradient(180deg, #ff9a66, #f06423);
        border: 3px solid #d14d12; border-top: none;
        border-radius: 8px 8px 60px 60px / 6px 6px 44px 44px;
        box-shadow: 0 4px 0 rgba(35, 50, 70, .15);
        pointer-events: none;
      }
      #mode-count .pond.heap .food-btn {
        position: absolute; width: 68px; height: 58px; min-height: 0; padding: 3px;
        border-radius: 46% 54% 52% 48% / 56% 58% 42% 44%;
        /* the fish lie IN the bowl, not in icon bubbles: only a soft
           watery sheen + a faint rim keep the tap target readable */
        background: radial-gradient(circle at 50% 42%, rgba(255, 255, 255, .5), rgba(190, 230, 255, .18) 72%);
        border-color: rgba(87, 182, 247, .45);
        transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(var(--sc, 1));
      }
      #mode-count .pond.heap .food-btn svg { max-width: 46px; }
      #mode-count .pond.heap .food-btn:active { transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(calc(var(--sc, 1) * .9)); }
      #mode-count .pond.heap .food-btn.eaten { transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(.3); }
      #mode-count .pond.heap .food-btn.refill { animation: foodDrop .38s ease-out; }
      @keyframes foodDrop {
        0% { transform: translate(-50%, -140%) rotate(var(--rot, 0deg)) scale(.6); opacity: 0; }
        55% { opacity: 1; }
        78% { transform: translate(-50%, -43%) rotate(var(--rot, 0deg)) scale(calc(var(--sc, 1) * 1.06)); }
        100% { transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(var(--sc, 1)); opacity: 1; }
      }
      .progress-dots { display: flex; justify-content: center; gap: 7px; flex-wrap: wrap; margin-top: 14px; }
      .progress-dots span { width: 20px; height: 20px; border-radius: 50%; background: var(--line); border: 2px solid var(--line); }
      .progress-dots span.on { background: var(--cat); border-color: var(--cat-dark); }
      .add-eq { font-size: 40px; font-weight: 800; margin-top: 12px; letter-spacing: 2px; min-height: 48px; }
      .add-eq .q { color: var(--coral-dark); }


/* v52: care landing hint (mode-care) — one friendly line under the
   stage; the pet itself is the affordance, this just names it. */
.care-hint {
  margin: 10px auto 4px;
  max-width: 92%;
  text-align: center;
  font-size: clamp(17px, 4.6vw, 22px);
  font-weight: 700;
  color: #5b4a2f;
  line-height: 1.35;
}
