
  :root {
    --ink: #2b1140;
    --accent: #ff6bb5;
    --accent-2: #ffd166;
    --grass: #93d4a4;
    --grass-mid: #7bc78d;
    --grass-far: #5fa775;
    --sky: #cfeefe;
    --sky-warm: #ffe4a8;
    --path: #d9b377;
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0;
    padding: 0;
    height: 100svh;
    overflow: hidden;
    font-family: "Comic Sans MS", "Chalkboard SE", "Baloo", system-ui, sans-serif;
    color: var(--ink);
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    background: var(--sky);
  }

  /* The stage is the full viewport — perspective park scene */
  #yard {
    position: fixed;
    inset: 0;
    cursor: pointer;
    overflow: hidden;
    background-color: #bfe3a0;
    background-image: url('./assets/grassland-bg.webp');
    background-size: cover;
    background-position: center bottom;
  }
  /* Day/night color wash over the whole scene (the grassland photo stays
     put; JS fades this tint per time of day). Sits above the photo, below
     the sun/moon. */
  #sky-tint {
    position: absolute; inset: 0; pointer-events: none; z-index: 0;
    background: transparent;
    transition: background 2000ms ease;
  }
  /* Sun + moon: separate elements that glide along an arc — NOT baked into
     the photo — so they rise and set. Behind the birds + clouds (z 2). */
  #sun, #moon {
    position: absolute; width: 84px; height: 84px; margin: -42px;
    border-radius: 50%; pointer-events: none; z-index: 1;
    transition: left 4s ease-in-out, top 4s ease-in-out, opacity 2.4s ease;
    will-change: left, top, opacity;
  }
  #sun {
    background: radial-gradient(circle at 50% 45%, #fff6c0 0%, #ffe07a 46%, #ffc23d 74%, rgba(255,180,40,0) 100%);
    filter: drop-shadow(0 0 18px rgba(255,210,90,0.85));
  }
  #moon {
    opacity: 0;
    background: radial-gradient(circle at 42% 40%, #ffffff 0%, #eef3ff 52%, #cdd8f2 78%, rgba(205,216,242,0) 100%);
    filter: drop-shadow(0 0 14px rgba(210,225,255,0.7));
  }

  /* Path going from foreground (wide, bottom) to vanishing point at horizon */
  .path {
    position: absolute;
    left: 50%;
    bottom: 0;
    /* Use a clip-path trapezoid to fake perspective */
    width: 70vw;
    height: 64%;
    transform: translateX(-50%);
    background: linear-gradient(180deg,
      transparent 0%,
      rgba(217, 179, 119, 0.6) 6%,
      rgba(217, 179, 119, 0.95) 100%);
    clip-path: polygon(48% 0%, 52% 0%, 100% 100%, 0% 100%);
    pointer-events: none;
    z-index: 0;
  }

  /* Far fence at horizon */
  .horizon {
    position: absolute;
    left: 0; right: 0;
    top: 36%;
    height: 14px;
    background:
      repeating-linear-gradient(90deg,
        rgba(216, 163, 115, 0.7) 0 6px,
        rgba(216, 163, 115, 0.95) 6px 7px,
        rgba(216, 163, 115, 0.7) 7px 12px,
        transparent 12px 14px);
    border-bottom: 2px solid rgba(120, 80, 40, 0.5);
    pointer-events: none;
    z-index: 1;
  }

  .cloud {
    position: absolute;
    left: -12vw;
    z-index: 2;
    width: calc(96px * var(--cloud-scale, 1));
    height: calc(46px * var(--cloud-scale, 1));
    pointer-events: none;
    opacity: 0.95;
    filter: drop-shadow(0 3px 3px rgba(0,0,0,0.08));
    will-change: transform;
    /* translateX composites on the GPU; animating `left` forced a
       relayout every frame for the life of the page. */
    animation: cloudCross linear infinite;
  }
  /* Three overlapping soft white puffs make one rounded cloud. */
  .cloud i {
    position: absolute;
    bottom: 0;
    border-radius: 50%;
    background: radial-gradient(circle at 38% 34%, #ffffff 0%, #f2f7ff 70%, #e4edfa 100%);
  }
  .cloud i:nth-child(1) { left: 0;   width: 55%; height: 78%; }
  .cloud i:nth-child(2) { left: 24%; width: 62%; height: 100%; }
  .cloud i:nth-child(3) { left: 55%; width: 48%; height: 70%; }
  @keyframes cloudCross {
    0%   { transform: translateX(0); }
    100% { transform: translateX(120vw); }
  }

  /* Background birds — small bluebird sprite cycling 4 frames. JS
     spawns them at random intervals; CSS animates the cross. */
  .bg-bird {
    position: absolute;
    left: -10vw;
    pointer-events: none;
    z-index: 2;
    background-image: url('./assets/smallbird-fly-1.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    animation: birdFly linear forwards;
    will-change: transform;
  }
  /* Bluebird sprites face right, so animate left -> right (composited) */
  @keyframes birdFly {
    0%   { transform: translateX(0); }
    100% { transform: translateX(120vw); }
  }

  /* Ball-stealing bird (the swoop one) — eagle sprite cycle */
  #bird {
    position: absolute;
    width: 80px;
    height: 80px;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 8;
    background-image: url('./assets/eagle-fly-1.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    filter: drop-shadow(0 5px 5px rgba(0,0,0,0.3));
    transform-origin: center;
    will-change: transform;
    display: none;
  }
  #bird.show { display: block; }

  /* Pet Eagle — owned via the shop upgrade, periodically swoops on
     squirrels. Reuses eagle-fly-N.webp but with a warm gold drop-
     shadow + a 💛 above so it reads as "yours, not a threat". */
  .dragon-fireball {
    position: absolute;
    width: 60px; height: 60px;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 40;
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    transform-origin: center;
    filter: drop-shadow(0 0 7px rgba(255,140,0,0.85)) drop-shadow(0 0 16px rgba(255,90,0,0.5));
    will-change: transform;
  }
  .pet-eagle {
    position: absolute;
    width: 80px;
    height: 80px;
    left: 0;
    top: 0;
    will-change: transform;
    pointer-events: none;
    z-index: 8;
    background-image: url('./assets/eagle-fly-1.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    filter:
      drop-shadow(0 0 6px #ffd166)
      drop-shadow(0 0 14px rgba(255,209,102,0.5))
      drop-shadow(0 5px 5px rgba(0,0,0,0.3));
    transform-origin: center;
  }
  .pet-eagle::after {
    content: "💛";
    position: absolute;
    left: 50%;
    top: -22%;
    transform: translateX(-50%);
    font-size: 22px;
    pointer-events: none;
    animation: clapHint 0.7s ease-in-out infinite alternate;
    filter: drop-shadow(0 2px 2px rgba(0,0,0,0.25));
  }

  /* Dog jump — uses the `translate` property so it stacks with
     the JS-driven `transform: scale(±s, s)` (depth + face-left). */
  @keyframes dogJump {
    0%, 100% { translate: 0 0; }
    35%      { translate: 0 -42px; }
    65%      { translate: 0 -52px; }
  }
  #dog.jumping { animation: dogJump 720ms ease-out; }

  /* Park decor — trees + bushes scattered with depth */
  .decor {
    position: absolute;
    pointer-events: none;
    transform-origin: bottom center;
    filter: drop-shadow(0 4px 6px rgba(0,0,0,0.18));
    z-index: 1;
  }
  .decor img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  /* Player (the princess throwing the ball) anchored bottom-left of
     foreground. Default princess (Rose) is set in CSS so there's no
     flash on first paint; the princess selector overrides it from JS. */
  #player {
    position: absolute;
    left: 14%;
    bottom: 3%;
    width: 130px;
    height: 150px;
    z-index: 8;
    pointer-events: none;
    background-image: url('./assets/sprites/princess-rose/idle.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center bottom;
    filter: drop-shadow(0 6px 6px rgba(0,0,0,0.3));
  }
  @media (max-width: 600px) {
    #player { width: 100px; height: 116px; left: 8%; }
  }

  /* The dog — an <img> with a FIXED base size. Depth + facing are
     applied via transform: scale(±s, s) so the browser keeps a single
     decoded bitmap warm and just composites it. JS updates left/top
     each frame; width/height never mutate. Matches wolf-run's player. */
  #dog {
    position: absolute;
    width: 110px;
    height: 110px;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 7;
    object-fit: contain;
    object-position: center bottom;
    transform-origin: bottom center;
    transition: none;
    will-change: transform;
  }

  /* Dog shadow under the dog (separate so it doesn't flip with the dog) */
  #dog-shadow {
    position: absolute;
    width: 60px;
    height: 14px;
    left: 0;
    top: 0;
    background: radial-gradient(ellipse at center, rgba(0,0,0,0.35), transparent 70%);
    pointer-events: none;
    z-index: 6;
    transform-origin: top center;
    will-change: transform;
  }

  /* Squirrels — JS spawns these dynamically (up to 3 at once). The
     background-image is set per-frame by the global anim tick so all
     squirrels stay in sync. */
  .squirrel-actor {
    position: absolute;
    width: 80px;
    height: 80px;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 7;
    background-image: url('./assets/squirrel-run-1.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center bottom;
    transform-origin: bottom center;
    filter: drop-shadow(0 5px 5px rgba(0,0,0,0.3));
    will-change: transform;
  }
  /* Facing flip now folds into the JS transform (placeSquirrel). */
  /* "Jump out of the tree!" pop when a hidden squirrel wakes for a
     new ball. Uses the `translate`+`scale` properties so it stacks
     with the existing transform: scaleX(-1) for face-left. */
  @keyframes sqJumpOut {
    0%   { translate: 0 0;     scale: 0.4; }
    35%  { translate: 0 -38px; scale: 1.20; }
    70%  { translate: 0 -8px;  scale: 1.0; }
    100% { translate: 0 0;     scale: 1; }
  }
  .squirrel-actor.jumping { animation: sqJumpOut 420ms ease-out; }

  /* The ball — drawn as inline SVG so it doesn't render as a tennis
     racket on iOS. JS scales it via width/height. */
  #ball {
    position: absolute;
    width: 36px;
    height: 36px;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 9;
    transform-origin: top left;
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.3));
    will-change: transform;
  }
  #ball svg { width: 100%; height: 100%; display: block; }
  #ball-shadow {
    position: absolute;
    width: 36px;
    height: 12px;
    left: 0;
    top: 0;
    border-radius: 50%;
    background: rgba(0,0,0,0.28);
    pointer-events: none;
    z-index: 5;
    transform-origin: top left;
    filter: blur(2px);
    will-change: transform;
  }
  .hidden { display: none !important; }

  /* Park Friends — translucent, name-tagged ghost dogs of other players
     in the same park (ambient multiplayer). Positioned via transform in
     JS (ghostFrame); the tag stays upright + readable at any depth. */
  .park-ghost {
    position: absolute;
    left: 0; top: 0;
    width: 0; height: 0;
    pointer-events: none;
    will-change: transform;
  }
  .park-ghost-dog {
    position: absolute;
    left: -55px; top: -110px;
    width: 110px; height: 110px;
    object-fit: contain;
    object-position: center bottom;
    transform-origin: bottom center;
    opacity: 0.6;
    /* Cool tint so a friend's puppy reads as "not mine" at a glance. */
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.25)) saturate(0.85) brightness(1.05) hue-rotate(-8deg);
  }
  .park-ghost-tag {
    position: absolute;
    left: 0; top: 0;
    transform-origin: center bottom;
    white-space: nowrap;
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(20, 28, 65, 0.72);
    color: #fff;
    font-size: 12px;
    font-weight: bold;
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  }

  /* HUD — the score pill. Tucked flush under the shared #kg-topbar so
     it reads as part of the persistent header instead of a white blob
     floating in the middle of the navy sky. We dropped the redundant
     "🐶 Dog Park" h1 (page title is in the browser tab + kg-topbar's
     Home button gives the context). */
  header {
    position: fixed;
    top: 56px;
    left: 8px;
    right: auto;
    text-align: left;
    padding: 0;
    pointer-events: none;
    z-index: 30;
  }
  /* topbar.css pushes every `header` down 64px (for games whose header
     is in normal flow). Ours is FIXED at top:56px already — without this
     higher-specificity override the HUD floats 64px into the sky. */
  body:has(#kg-topbar) header#park-hud { padding-top: 0 !important; }
  h1 { display: none; }
  #hud {
    display: inline-flex;
    gap: 8px;
    background: rgba(20, 28, 65, 0.62);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.18);
    padding: 4px 10px;
    border-radius: 999px;
    /* 13px floor — the old 11px floor was too small for a 7-year-old
       on a phone. */
    font-size: clamp(13px, 2.4vw, 15px);
    font-weight: bold;
    box-shadow: 0 2px 6px rgba(0,0,0,0.25);
    pointer-events: none;
    flex-wrap: nowrap;
    justify-content: flex-start;
    white-space: nowrap;
  }
  #hud b              { color: #fff; }
  #hud .combo b       { color: #ffd166; }
  #hud .treats b      { color: #ffd166; }
  #hud .joy b         { color: #ffb1d6; }

  /* #home-btn and #music-btn are now hidden (the shared kg-topbar
     provides both — kg-topbar uses #music-btn as a click-proxy target,
     so we keep it in the DOM but invisible). */
  #home-btn, #music-btn { display: none !important; }

  /* Shop + Cabin: small icon buttons stacked vertically in the top-
     right, below the kg-topbar. Saves a row of the header for the
     title and stops the old overlapping-pill mess. */
  #shop-btn, #cabin-btn {
    position: fixed;
    right: 8px;
    width: 44px; height: 44px; padding: 0;
    border-radius: 50%;
    border: 3px solid var(--accent);
    background: #fff;
    color: var(--ink);
    box-shadow: 0 3px 0 var(--accent);
    z-index: 40;
    cursor: pointer;
    font-weight: bold;
    font-family: inherit;
    font-size: 22px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* Inside the round button we only render the emoji — the text label
     stays in aria-label for screen readers. */
  #shop-btn  { top: 60px;  right: 60px; background: linear-gradient(135deg, #ffd166, #ffa83c); border-color: #d99a10; box-shadow: 0 3px 0 #d99a10; }
  #cabin-btn { top: 60px;  right: 8px;  background: linear-gradient(135deg, #c69664, #8b5e3c); border-color: #6b4424; box-shadow: 0 3px 0 #6b4424; color: #fff; }
  #pepper-btn {
    display: none;
    position: fixed;
    top: 112px;
    right: 8px;
    width: 44px; height: 44px;
    border-radius: 50%;
    border: 3px solid #c8311a;
    background: linear-gradient(135deg, #ff6f4a, #d9301f);
    box-shadow: 0 3px 0 #8a1a0a;
    color: #fff;
    font-size: 22px;
    /* Below the shop/cabin overlays (z 50) — at the old 60 the pepper
       button floated over an open shop and could burn a pepper "from
       inside" the menu. */
    z-index: 45;
    cursor: pointer;
    padding: 0;
    line-height: 1;
  }
  #pepper-btn.show { display: flex; align-items: center; justify-content: center; }
  #pepper-btn:active { translate: 0 2px; box-shadow: 0 1px 0 #8a1a0a; }
  #pepper-btn.active {
    box-shadow: 0 3px 0 #8a1a0a, 0 0 0 4px rgba(255,140,90,0.45);
  }
  #pepper-btn .pep-count {
    position: absolute;
    bottom: -4px; right: -4px;
    background: #fff;
    color: #c8311a;
    border: 2px solid #c8311a;
    border-radius: 999px;
    font-size: 12px;
    font-weight: bold;
    padding: 0 4px;
    min-width: 16px;
    text-align: center;
    line-height: 14px;
  }
  #shop-btn:active, #cabin-btn:active { translate: 0 2px; box-shadow: 0 1px 0 currentColor; }
  /* Cabin button pulses during sunset/night so the kid can see they
     have an easy escape (go inside) when squirrels start showing up. */
  #cabin-btn.pulse { animation: cabinPulse 1.4s ease-in-out infinite; }
  @keyframes cabinPulse {
    0%,100% { transform: scale(1);    box-shadow: 0 3px 0 #6b4424, 0 0 0 0 rgba(255,209,102,0.6); }
    50%     { transform: scale(1.08); box-shadow: 0 3px 0 #6b4424, 0 0 0 10px rgba(255,209,102,0); }
  }
  /* Daily challenge — a single pill below the HUD, only shows when
     a challenge is active. Goes green + bigger briefly when done. */
  #challenge-line {
    display: none;
    margin-top: 6px;
    background: rgba(255,255,255,0.92);
    color: #2a4a5a;
    padding: 4px 12px;
    border-radius: 999px;
    font-size: clamp(13px, 2.4vw, 15px);
    font-weight: bold;
    box-shadow: 0 2px 5px rgba(0,0,0,0.12);
    pointer-events: none;
  }
  #challenge-line.show { display: inline-block; }
  #challenge-line.done {
    background: linear-gradient(135deg, #c2efb0, #84d97a);
    color: #2c5a1f;
    animation: challengeDonePop 700ms ease;
  }
  @keyframes challengeDonePop {
    0%   { transform: scale(1);    }
    35%  { transform: scale(1.18); }
    100% { transform: scale(1);    }
  }
  /* Far Flag — small marker that occasionally drops in the deep grass.
     Land the ball near it for bonus treats. */
  .far-flag {
    position: absolute;
    left: 0; top: 0;
    width: 38px; height: 50px;
    pointer-events: none;
    z-index: 6;
    animation: flagBob 1.4s ease-in-out infinite;
    filter: drop-shadow(0 2px 2px rgba(0,0,0,0.3));
  }
  .far-flag svg { display: block; }
  @keyframes flagBob {
    0%,100% { transform: translateY(0) rotate(-3deg); }
    50%     { transform: translateY(-3px) rotate(3deg); }
  }
  /* Sleep button — shows up below the cabin during sunset/night so
     the kid can fast-forward to morning instead of riding it out.
     Sits OUTSIDE the cabin card so it never overlaps the decorate
     palette or close button. */
  #cabin-sleep-btn {
    display: none;
    margin-top: 14px;
    padding: 12px 24px;
    border-radius: 999px;
    border: 3px solid #2b3d6a;
    background: linear-gradient(135deg, #6789c9, #3a5394);
    color: #fff;
    font-family: inherit;
    font-size: 16px;
    font-weight: bold;
    cursor: pointer;
    box-shadow: 0 3px 0 #2b3d6a;
    z-index: 5;
  }
  #cabin-sleep-btn.show { display: inline-block; }
  #cabin-sleep-btn:active { translate: 0 2px; box-shadow: 0 1px 0 #2b3d6a; }
  /* Full-screen fade used by the sleep transition. */
  #sleep-fade {
    position: fixed;
    inset: 0;
    background: #0b1736;
    color: #fff;
    /* Above the shared topbar (z 9900) so the blackout really blacks
       out — Pause/Help staying tappable mid-sleep looked broken. Still
       below the .game-version badge (99999). */
    z-index: 9999;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 64px;
    opacity: 0;
    transition: opacity 700ms ease;
    pointer-events: none;
  }
  #sleep-fade.show { display: flex; }
  #sleep-fade.fade-in { opacity: 1; }

  /* Shop modal */
  #shop {
    position: fixed; inset: 0;
    background: rgba(20,30,50,0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 50;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
    overflow-y: auto;
  }
  #shop.show { display: flex; }
  /* Dragon upgrade menu (its own overlay above the shop) */
  #dragon-menu {
    position: fixed; inset: 0; background: rgba(20,30,50,0.6);
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
    z-index: 60; display: none; align-items: center; justify-content: center;
    padding: 16px; overflow-y: auto;
  }
  #dragon-menu.show { display: flex; }
  #dragon-card {
    background: #fff; border-radius: 22px; border: 5px solid #7a5cff;
    width: min(560px, 96vw); max-height: calc(100svh - 32px); overflow-y: auto;
    padding: 16px 18px 18px; box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  }
  #dragon-card h2 { margin: 0 0 4px; font-size: clamp(22px,5vw,30px); color: #7a5cff; text-align: center; }
  #dragon-treats { text-align: center; font-weight: bold; color: #c98a3a; margin-bottom: 10px; }
  .dragon-row {
    display: flex; align-items: center; gap: 10px; background: #f4f1ff;
    border: 2px solid #d8cffd; border-radius: 12px; padding: 8px 10px; margin-bottom: 6px;
  }
  .dragon-row img { width: 60px; height: 60px; object-fit: contain; }
  .dragon-row .info { flex: 1; line-height: 1.25; font-size: clamp(13px,2.6vw,15px); }
  .dragon-row .info b { color: #6a4cff; }
  .dragon-row.owned { background: #e9f7ec; border-color: #4ec96b; }
  .dragon-row.locked { opacity: 0.55; }
  .dragon-row button {
    font-family: inherit; font-weight: bold; border: 3px solid #7a5cff;
    background: #fff; color: var(--ink); border-radius: 999px; padding: 6px 12px;
    cursor: pointer; box-shadow: 0 3px 0 #7a5cff; min-width: 86px; font-size: 14px;
  }
  .dragon-row button:disabled { opacity: 0.55; cursor: default; box-shadow: 0 1px 0 #7a5cff; }
  #dragon-close {
    display: block; width: 100%; margin-top: 12px; font-family: inherit; font-weight: bold;
    font-size: clamp(18px,4vw,22px); padding: 10px; border-radius: 14px;
    border: 3px solid #7a5cff; background: #fff; color: #6a4cff; cursor: pointer; box-shadow: 0 3px 0 #7a5cff;
  }
  #shop-card {
    background: #fff;
    border-radius: 22px;
    border: 5px solid var(--accent);
    width: min(900px, 96vw);
    max-height: calc(100svh - 32px);
    overflow-y: auto;
    padding: 16px 18px 18px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  }
  #shop-card h2 {
    margin: 0 0 6px;
    font-size: clamp(22px, 5vw, 30px);
    color: #d660b0;
    text-align: center;
  }
  #shop-treats {
    text-align: center;
    font-size: clamp(15px, 3vw, 19px);
    margin-bottom: 10px;
    color: #c98a3a;
    font-weight: bold;
  }
  .shop-section h3 {
    margin: 12px 0 6px;
    font-size: clamp(15px, 3vw, 18px);
    color: #1f6f9a;
  }
  .shop-row {
    display: flex; align-items: center; gap: 10px;
    background: #f4f9ff;
    border: 2px solid #cde3f3;
    border-radius: 12px;
    padding: 8px 10px;
    margin-bottom: 6px;
    font-size: clamp(13px, 2.6vw, 15px);
  }
  .shop-row .icon { font-size: 26px; }
  .shop-row .info { flex: 1; line-height: 1.25; }
  .shop-row .info b { color: #1f6f9a; }
  .shop-row button {
    font-family: inherit; font-weight: bold;
    border: 3px solid var(--accent);
    background: #fff; color: var(--ink);
    border-radius: 999px;
    padding: 6px 12px; cursor: pointer;
    box-shadow: 0 3px 0 var(--accent);
    font-size: 14px; min-width: 76px;
  }
  .shop-row button:disabled { opacity: 0.55; cursor: default; box-shadow: 0 1px 0 var(--accent); }
  .shop-row.owned { background: #e9f7ec; border-color: var(--good, #4ec96b); }
  .breed-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .breed-tile {
    background: #f4f9ff; border: 3px solid var(--accent);
    border-radius: 14px; padding: 8px 6px; text-align: center;
    cursor: pointer; font-family: inherit; color: var(--ink);
    font-size: clamp(12px, 2.4vw, 14px); line-height: 1.25;
  }
  .breed-tile img { width: 64px; height: 64px; object-fit: contain; display: block; margin: 0 auto; }
  .breed-tile.locked { opacity: 0.7; background: #eee; border-style: dashed; }
  .breed-tile.selected { background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #fff; border-color: #d660b0; }
  .breed-tile .price { color: #c98a3a; font-weight: bold; }
  .breed-tile.selected .price { color: #fff; }
  #shop-close {
    display: block; width: 100%; margin-top: 12px;
    font-family: inherit; font-weight: bold;
    font-size: clamp(18px, 4vw, 22px);
    padding: 12px; border-radius: 16px;
    border: 4px solid var(--accent);
    background: linear-gradient(135deg, var(--accent), #d660b0);
    color: #fff; cursor: pointer;
    box-shadow: 0 5px 0 #b04ea0;
  }

  /* Charge meter while holding to throw. Sits ABOVE the SIC 'EM pill
     (bottom ~30px, ~60px tall) — at the old bottom:28px the pulsing
     button hid the meter exactly when a squirrel was on screen. */
  #charge-meter {
    position: fixed;
    left: 50%; transform: translateX(-50%);
    bottom: calc(104px + env(safe-area-inset-bottom, 0px));
    width: min(70vw, 360px);
    height: 14px;
    background: rgba(255,255,255,0.5);
    border: 2px solid #fff;
    border-radius: 999px;
    z-index: 26;
    overflow: hidden;
    display: none;
    box-shadow: 0 2px 6px rgba(0,0,0,0.18);
  }
  #charge-meter.show { display: block; }
  #charge-fill {
    height: 100%; width: 0;
    background: linear-gradient(90deg, #4ec96b, #ffd166, #ee5066);
    transition: width 60ms linear;
  }

  /* Day/night palette overlay over the yard. JS picks the gradient. */
  #yard {
    transition: background 1500ms ease;
  }

  /* Frisbee power-up icon floating in the grass */
  .frisbee-pickup {
    position: absolute;
    pointer-events: auto;
    cursor: pointer;
    z-index: 6;
    background-image: url('./assets/frisbee.webp');
    background-size: contain;
    background-repeat: no-repeat;
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.25));
    animation: boneBob 1100ms ease-in-out infinite;
  }

  /* Skunk lying in the grass — passive hazard */
  .skunk-actor {
    position: absolute;
    pointer-events: none;
    z-index: 6;
    background-image: url('./assets/skunk.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center bottom;
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.3));
  }

  /* Raccoon "boss" sprite — moved + flipped via the JS transform
     (placeRaccoon); size/depth are fixed at spawn. */
  .raccoon-actor {
    position: absolute;
    left: 0;
    top: 0;
    pointer-events: none;
    z-index: 7;
    background-image: url('./assets/raccoon.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center bottom;
    transform-origin: center;
    will-change: transform;
    filter: drop-shadow(0 5px 5px rgba(0,0,0,0.35));
  }

  /* Bones lying on the grass — tap to collect */
  .bone-pickup {
    position: absolute;
    pointer-events: auto;
    cursor: pointer;
    z-index: 6;
    background-image: url('./assets/bone.webp');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center bottom;
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.25));
    animation: boneBob 1400ms ease-in-out infinite;
  }
  @keyframes boneBob {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -4px; }
  }

  /* "Squirrel!" alert button — only visible while a squirrel is on
     the screen. Tapping it sends the dog to chase the squirrel. */
  #sicem-btn {
    position: fixed;
    bottom: calc(30px + env(safe-area-inset-bottom, 0px));
    left: 50%;
    transform: translateX(-50%);
    font-family: inherit;
    font-weight: bold;
    font-size: clamp(17px, 4vw, 24px);
    padding: 14px 28px;
    border-radius: 999px;
    border: 4px solid #b8242b;
    background: linear-gradient(135deg, #ff8a3c, #ee5066);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 6px 0 #b8242b, 0 10px 18px rgba(0,0,0,0.25);
    z-index: 35;
    display: none;
    text-shadow: 0 2px 0 rgba(0,0,0,0.25);
    -webkit-tap-highlight-color: transparent;
    animation: sicemPulse 0.7s ease-in-out infinite;
  }
  #sicem-btn.show { display: block; }
  #sicem-btn:active {
    box-shadow: 0 2px 0 #b8242b, 0 4px 8px rgba(0,0,0,0.25);
    translate: 0 4px;
  }
  @keyframes sicemPulse {
    0%, 100% { transform: translateX(-50%) scale(1) rotate(-2deg); }
    50%      { transform: translateX(-50%) scale(1.07) rotate(2deg); }
  }

  #hint {
    position: absolute;
    top: 36%;
    left: 50%;
    transform: translateX(-50%);
    color: rgba(0,0,0,0.65);
    background: rgba(255,255,255,0.85);
    padding: 8px 18px;
    border-radius: 999px;
    font-weight: bold;
    font-size: clamp(14px, 2.6vw, 20px);
    pointer-events: none;
    text-align: center;
    box-shadow: 0 3px 6px rgba(0,0,0,0.15);
    z-index: 25;
    transition: opacity 600ms ease;
  }
  #hint.gone { opacity: 0; }

  /* Pop-up bubbles for bark / squirrel chitter / +score */
  .bubble {
    position: absolute;
    background: #fff;
    border: 3px solid var(--accent-2);
    border-radius: 14px;
    padding: 4px 12px;
    font-size: 16px;
    font-weight: bold;
    color: #d6336c;
    box-shadow: 0 3px 8px rgba(0,0,0,0.18);
    pointer-events: none;
    /* Long banners wrap instead of clipping offscreen at phone widths. */
    white-space: normal;
    max-width: min(82vw, 340px);
    text-align: center;
    z-index: 28;
    animation: bubblePop 1100ms ease-out forwards;
    transform: translate(-50%, 0);
  }
  .bubble.angry { border-color: #ee5066; color: #b8242b; }
  .bubble.score { border-color: #4ec96b; color: #2a8c3f; }
  @keyframes bubblePop {
    0%   { transform: translate(-50%, 0) scale(0.4); opacity: 0; }
    20%  { transform: translate(-50%, -8px) scale(1.1); opacity: 1; }
    80%  { transform: translate(-50%, -28px) scale(1); opacity: 1; }
    100% { transform: translate(-50%, -42px) scale(0.95); opacity: 0; }
  }

  /* Tap ripple where you throw */
  .ripple {
    position: absolute;
    width: 60px; height: 60px;
    border: 3px solid #fff;
    border-radius: 50%;
    pointer-events: none;
    transform: translate(-50%, -50%);
    animation: rippleOut 700ms ease-out forwards;
    z-index: 6;
  }
  @keyframes rippleOut {
    0%   { opacity: 0.95; transform: translate(-50%, -50%) scale(0.3); }
    100% { opacity: 0;    transform: translate(-50%, -50%) scale(2.4); }
  }

  /* Sun ray / treat indicator after combo */
  .combo-pop {
    position: absolute;
    left: 50%;
    top: 36%;
    transform: translate(-50%, -50%);
    font-weight: bold;
    color: #fff;
    background: linear-gradient(135deg, var(--accent-2), #ff8a3c);
    padding: 8px 22px;
    border-radius: 999px;
    box-shadow: 0 4px 0 #b27a00;
    font-size: clamp(18px, 4vw, 28px);
    z-index: 29;
    animation: comboPop 1400ms ease forwards;
    pointer-events: none;
    text-shadow: 0 2px 0 rgba(0,0,0,0.2);
  }
  @keyframes comboPop {
    0%   { transform: translate(-50%, -20%) scale(0.4); opacity: 0; }
    20%  { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
    80%  { transform: translate(-50%, -55%) scale(1.0); opacity: 1; }
    100% { transform: translate(-50%, -100%) scale(0.9); opacity: 0; }
  }

  /* Heart particle — floats up + fades when the dog is petted or
     after a clean fetch. Pure flavor. */
  .heart-float {
    position: absolute;
    font-size: clamp(28px, 6vw, 44px);
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 30;
    animation: heartFloat 1300ms ease-out forwards;
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.25));
  }
  @keyframes heartFloat {
    0%   { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
    25%  { transform: translate(-50%, -70%) scale(1.1); opacity: 1; }
    100% { transform: translate(-50%,-140%) scale(0.9); opacity: 0; }
  }

  /* Visual cue on critters carrying the ball — a tennis ball above their
     head, bobbing, so the player notices the squirrel/bird is the thief.
     Uses the same inline-SVG ball as the real ball (NOT the 🎾 emoji, which
     renders as a tennis RACKET on iOS — see #ball). */
  .squirrel-actor.has-ball::after,
  #bird.has-ball::after {
    content: "";
    display: block;
    width: clamp(22px, 4.4vw, 32px);
    height: clamp(22px, 4.4vw, 32px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 36'%3E%3Cdefs%3E%3CradialGradient id='g' cx='35%25' cy='32%25' r='70%25'%3E%3Cstop offset='0%25' stop-color='%23fffd8a'/%3E%3Cstop offset='55%25' stop-color='%23dfd538'/%3E%3Cstop offset='100%25' stop-color='%23928817'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='18' cy='18' r='17' fill='url(%23g)' stroke='%235e560a' stroke-width='0.8'/%3E%3Cpath d='M3 13 Q18 4 33 13' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round'/%3E%3Cpath d='M3 23 Q18 32 33 23' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    position: absolute;
    left: 50%;
    top: -34%;
    transform: translateX(-50%);
    pointer-events: none;
    animation: clapHint 0.7s ease-in-out infinite alternate;
    filter: drop-shadow(0 2px 2px rgba(0,0,0,0.25));
  }
  @keyframes clapHint {
    0%   { transform: translateX(-50%) translateY(0)    scale(1.0); opacity: 0.9; }
    100% { transform: translateX(-50%) translateY(-6px) scale(1.12); opacity: 1; }
  }

  /* ===== Cabin overlay (Phase A) — log-cabin scene where the puppy
     lives. Sibling of #shop. Background painted entirely with CSS:
     warm wood-plank wall + darker wood floor + brick fireplace +
     potted plants in the corners. The puppy renders inside as an
     <img> using the same per-breed sprite path the yard uses. */
  #cabin {
    position: fixed; inset: 0;
    background: rgba(20,30,50,0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 50;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16px;
    overflow-y: auto;
  }
  #cabin.show { display: flex; }
  #cabin-card {
    position: relative;
    width: min(760px, 100vw - 8px);
    max-height: calc(100svh - 96px);
    aspect-ratio: 5 / 4;
    border-radius: 22px;
    border: 6px solid #6b4424;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    overflow: hidden;
    /* Wall: two horizontal-plank gradients stacked.
       Floor: solid bottom strip with grain via repeating gradient. */
    background:
      /* dark wood floor at the bottom 28% */
      linear-gradient(
        180deg,
        transparent 0%, transparent 72%,
        #6b4424 72%, #5a3618 100%
      ),
      /* wood plank texture across the wall */
      repeating-linear-gradient(
        180deg,
        #c69664 0px, #c69664 36px,
        #b58552 36px, #b58552 38px,
        #c69664 38px, #c69664 74px,
        #ad7f4b 74px, #ad7f4b 76px
      );
  }
  /* Floor planks — laid down on top of the floor strip */
  #cabin-card::before {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 28%;
    background:
      repeating-linear-gradient(
        90deg,
        #6b4424 0px, #6b4424 70px,
        #5a3618 70px, #5a3618 72px,
        #6b4424 72px, #6b4424 140px,
        #4a2c12 140px, #4a2c12 142px
      );
    pointer-events: none;
  }
  /* Fireplace — brick-textured rectangle on the back wall, top-center */
  .cabin-fireplace {
    position: absolute;
    left: 50%;
    top: 14%;
    transform: translateX(-50%);
    width: 32%;
    height: 42%;
    border-radius: 14px 14px 4px 4px;
    border: 4px solid #7a3a18;
    background:
      /* fire opening — dark gradient inside */
      radial-gradient(ellipse at 50% 75%, #2a0a00 0%, #5a1a05 30%, transparent 60%),
      /* brick pattern */
      repeating-linear-gradient(
        90deg,
        #b35a30 0px, #b35a30 30px,
        #8a3f1d 30px, #8a3f1d 32px
      ),
      repeating-linear-gradient(
        180deg,
        #b35a30 0px, #b35a30 22px,
        #8a3f1d 22px, #8a3f1d 24px
      );
    box-shadow: inset 0 -4px 0 #7a3a18, 0 4px 0 #5a2a10;
  }
  /* Logs + flames inside the fireplace opening. The emoji 🔥 is
     hidden (font-size: 0) — we draw the fire with layered CSS so it
     looks like an actual fire instead of one big emoji. */
  .cabin-fireplace .fire-inner {
    position: absolute;
    left: 50%;
    bottom: 6%;
    transform: translateX(-50%);
    width: 70%;
    height: 70%;
    font-size: 0;            /* hide the emoji text node */
    pointer-events: none;
  }
  /* Two stacked logs at the base — overlapping circles + a dark base */
  .cabin-fireplace .fire-inner::before {
    content: "";
    position: absolute;
    left: 6%; right: 6%; bottom: 0;
    height: 22%;
    border-radius: 50% / 30%;
    background:
      radial-gradient(ellipse at 28% 50%, #b8855a 0 22%, transparent 28%),
      radial-gradient(ellipse at 72% 50%, #b8855a 0 22%, transparent 28%),
      linear-gradient(180deg, #6b4424 0%, #3a2008 100%);
    box-shadow:
      0 -2px 4px rgba(255,140,30,0.55),
      inset 0 1px 0 rgba(255,200,120,0.4);
  }
  /* Main flame body — teardrop shape with hot core and orange halo */
  .cabin-fireplace .fire-inner::after {
    content: "";
    position: absolute;
    left: 50%; bottom: 18%;
    transform: translateX(-50%);
    width: 80%; height: 78%;
    border-radius: 50% 50% 38% 38% / 60% 60% 40% 40%;
    background:
      /* yellow-white hot core */
      radial-gradient(ellipse at 50% 78%, #fff8c2 0%, #ffe69c 14%, transparent 32%),
      /* orange middle */
      radial-gradient(ellipse at 50% 70%, #ffb14a 0%, #ff7a1a 38%, transparent 60%),
      /* red outer halo */
      radial-gradient(ellipse at 50% 60%, #ff5a1a 0%, #d9301f 55%, transparent 78%);
    filter: blur(1.2px);
    animation: flameMain 1.1s ease-in-out infinite alternate;
    mix-blend-mode: screen;
  }
  /* A smaller secondary flame for liveliness — offsets from the main */
  .cabin-fireplace .fire-inner > .flame-tongue {
    position: absolute;
    left: 55%; bottom: 30%;
    width: 28%; height: 38%;
    border-radius: 50% 50% 40% 40% / 70% 70% 30% 30%;
    background:
      radial-gradient(ellipse at 50% 70%, #fff5a8 0%, #ffd166 22%, transparent 50%),
      radial-gradient(ellipse at 50% 60%, #ff8a3c 0%, #d9301f 60%, transparent 90%);
    filter: blur(0.6px);
    transform: translateX(-50%);
    animation: flameTongue 0.85s ease-in-out infinite alternate;
    mix-blend-mode: screen;
    opacity: 0.9;
  }
  @keyframes flameMain {
    0%   { transform: translateX(-50%) scale(1, 1) translateY(0);     opacity: 0.92; }
    50%  { transform: translateX(-50%) scale(1.04, 1.08) translateY(-2px); opacity: 1; }
    100% { transform: translateX(-50%) scale(0.96, 0.92) translateY(1px);  opacity: 0.85; }
  }
  @keyframes flameTongue {
    0%   { transform: translateX(-50%) scale(1, 0.95) translate(0, 0);    opacity: 0.85; }
    50%  { transform: translateX(-50%) scale(1.1, 1.15) translate(2px, -3px); opacity: 1; }
    100% { transform: translateX(-50%) scale(0.85, 1.05) translate(-2px, -1px); opacity: 0.75; }
  }
  /* Inherit-compat: the old fireFlicker keyframe name is kept in case
     any other element still references it. Safe to remove later. */
  @keyframes fireFlicker {
    0%   { transform: translateX(-50%) scale(1) translateY(0); }
    50%  { transform: translateX(-50%) scale(1.06) translateY(-2px); }
    100% { transform: translateX(-50%) scale(0.97) translateY(0); }
  }
  /* Mantel above the fireplace */
  .cabin-fireplace::before {
    content: "";
    position: absolute;
    left: -8%; right: -8%; top: -10px;
    height: 12px;
    background: linear-gradient(180deg, #8b5e3c 0%, #6b4424 100%);
    border-radius: 4px;
    box-shadow: 0 2px 0 #5a3618;
  }
  /* Potted plants — emoji absolute-positioned in the bottom corners */
  .cabin-plant {
    position: absolute;
    bottom: 16%;
    font-size: clamp(40px, 10vw, 64px);
    pointer-events: none;
    filter: drop-shadow(0 4px 4px rgba(0,0,0,0.25));
  }
  .cabin-plant.left  { left:  6%; }
  .cabin-plant.right { right: 6%; }
  /* Window — square with painted-blue panes, top-right */
  .cabin-window {
    position: absolute;
    top: 12%;
    right: 8%;
    width: 14%;
    aspect-ratio: 1 / 1;
    background: linear-gradient(135deg, #aee0ff 0%, #67b8ec 60%, #d6eef9 100%);
    border: 5px solid #6b4424;
    border-radius: 6px;
    box-shadow: inset 0 0 0 2px #fff, 0 4px 0 #5a3618;
  }
  .cabin-window::before, .cabin-window::after {
    content: "";
    position: absolute;
    background: #6b4424;
  }
  .cabin-window::before { left: 50%; top: 0; bottom: 0; width: 4px; transform: translateX(-50%); }
  .cabin-window::after  { top: 50%; left: 0; right: 0; height: 4px; transform: translateY(-50%); }
  /* Puppy area — center-bottom of the room. The <img> is set per breed. */
  #cabin-puppy {
    position: absolute;
    left: 50%;
    bottom: 18%;
    width: clamp(120px, 30%, 200px);
    aspect-ratio: 1 / 1;
    transform: translateX(-50%);
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    pointer-events: none;
    filter: drop-shadow(0 6px 6px rgba(0,0,0,0.3));
  }
  /* Name banner above the puppy */
  #cabin-name-banner {
    position: absolute;
    left: 50%;
    top: 4%;
    transform: translateX(-50%);
    background: rgba(255,255,255,0.92);
    border: 3px solid #d99a10;
    border-radius: 999px;
    padding: 6px 14px 6px 16px;
    font-weight: bold;
    color: #5a3618;
    font-size: clamp(14px, 3.2vw, 18px);
    display: flex;
    align-items: center;
    gap: 8px;
    box-shadow: 0 3px 0 #b27a00;
    z-index: 3;
    max-width: 80%;
  }
  #cabin-name-banner .puppy-name {
    text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 60vw;
  }
  #cabin-rename-btn {
    background: #fff;
    border: 2px solid #d99a10;
    color: #5a3618;
    border-radius: 999px;
    font-family: inherit;
    font-size: 12px;
    font-weight: bold;
    padding: 2px 8px;
    cursor: pointer;
    line-height: 1;
  }
  #cabin-rename-btn:active { translate: 0 1px; }
  /* Close button — same style as #shop-close but stuck to top-right of card */
  #cabin-close {
    position: absolute;
    top: 8px; right: 8px;
    z-index: 3;
    background: #fff;
    border: 3px solid #6b4424;
    color: #6b4424;
    border-radius: 999px;
    width: 36px; height: 36px;
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
    box-shadow: 0 3px 0 #5a3618;
    line-height: 1;
  }
  #cabin-close:active { translate: 0 2px; box-shadow: 0 1px 0 #5a3618; }

  /* ===== Decorate mode — tap-to-place room decorations ===== */
  /* Decorate toggle button — bottom-left of the card, mirrors #cabin-close */
  #cabin-decorate-btn {
    position: absolute;
    bottom: 8px; left: 8px;
    z-index: 5;
    background: #fff;
    border: 3px solid #6b4424;
    color: #6b4424;
    border-radius: 999px;
    padding: 7px 13px;
    font-family: inherit;
    font-size: clamp(12px, 3vw, 15px);
    font-weight: bold;
    cursor: pointer;
    box-shadow: 0 3px 0 #5a3618;
    line-height: 1;
  }
  #cabin-decorate-btn:active { translate: 0 2px; box-shadow: 0 1px 0 #5a3618; }
  #cabin-card.decorating #cabin-decorate-btn {
    background: #d99a10; color: #fff; border-color: #b27a00;
    box-shadow: 0 3px 0 #b27a00;
  }
  /* Keep the puppy in front of placed decorations */
  #cabin-puppy { z-index: 2; }
  /* Placed decoration — emoji positioned by % within the card. The
     --decor-scale CSS var is set per item so a couch (1.7×) renders
     visibly larger than a yo-yo (0.9×). */
  .cabin-decor {
    --decor-scale: 1;
    position: absolute;
    z-index: 1;
    font-size: calc(clamp(30px, 7vw, 52px) * var(--decor-scale));
    transform: translate(-50%, -50%);
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;
    filter: drop-shadow(0 3px 3px rgba(0,0,0,0.25));
    line-height: 1;
  }
  #cabin-card.decorating .cabin-decor {
    pointer-events: auto;
    cursor: pointer;
    animation: decorWiggle 0.7s ease-in-out infinite alternate;
  }
  @keyframes decorWiggle {
    0%   { transform: translate(-50%,-50%) rotate(-6deg); }
    100% { transform: translate(-50%,-50%) rotate(6deg); }
  }
  .cabin-decor.poof { animation: decorPoof 0.22s ease-in forwards; }
  @keyframes decorPoof {
    0%   { transform: translate(-50%,-50%) scale(1);   opacity: 1; }
    100% { transform: translate(-50%,-50%) scale(1.8); opacity: 0; }
  }
  /* Hint strip — only while decorating */
  #cabin-decor-hint {
    position: absolute;
    left: 50%; top: 16%;
    transform: translateX(-50%);
    z-index: 5;
    display: none;
    background: rgba(255,255,255,0.94);
    border: 3px solid #d99a10;
    border-radius: 12px;
    padding: 5px 12px;
    font-size: clamp(13px, 2.6vw, 15px);
    font-weight: bold;
    color: #5a3618;
    text-align: center;
    max-width: 84%;
    box-shadow: 0 2px 0 #b27a00;
  }
  #cabin-card.decorating #cabin-decor-hint { display: block; }
  /* Decoration palette — horizontal scroll strip pinned to card bottom */
  #cabin-palette {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 4;
    display: none;
    gap: 6px;
    padding: 8px 8px 8px 132px;  /* left pad clears the Decorate button */
    background: rgba(255,248,238,0.97);
    border-top: 4px solid #6b4424;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  #cabin-card.decorating #cabin-palette { display: flex; }
  .palette-item {
    flex: 0 0 auto;
    font-size: clamp(22px, 5.5vw, 32px);
    background: #fff;
    border: 3px solid #e6c79a;
    border-radius: 12px;
    width: clamp(42px, 10vw, 54px);
    height: clamp(42px, 10vw, 54px);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    line-height: 1;
    padding: 0;
  }
  .palette-item:active { translate: 0 1px; }
  .palette-item.selected {
    border-color: #d99a10;
    background: #fff0c8;
    box-shadow: 0 0 0 3px rgba(217,154,16,0.45);
    transform: scale(1.08);
  }

  /* Name-prompt modal (first-visit + rename). Smaller floating card on
     top of the cabin overlay so the cabin stays visible behind it. */
  #name-prompt {
    position: fixed; inset: 0;
    background: rgba(20,30,50,0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 60;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
  }
  #name-prompt.show { display: flex; }
  #name-prompt-card {
    background: #fff;
    border-radius: 18px;
    border: 5px solid #d99a10;
    width: min(360px, 92vw);
    padding: 18px 18px 16px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    text-align: center;
  }
  #name-prompt-card h3 {
    margin: 0 0 10px;
    color: #5a3618;
    font-size: clamp(18px, 4.4vw, 22px);
  }
  #puppy-name-input {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 12px;
    font-family: inherit;
    font-size: clamp(15px, 3.4vw, 18px);
    border: 3px solid #ffd166;
    border-radius: 12px;
    color: #5a3618;
    background: #fff8e1;
    outline: none;
    margin-bottom: 12px;
  }
  #puppy-name-input:focus { border-color: var(--accent); }
  #name-prompt-actions { display: flex; gap: 10px; justify-content: center; }
  #name-prompt-actions button {
    font-family: inherit;
    font-weight: bold;
    border-radius: 999px;
    padding: 8px 18px;
    border: 3px solid var(--accent);
    background: #fff;
    color: var(--ink);
    cursor: pointer;
    box-shadow: 0 3px 0 var(--accent);
  }
  #name-prompt-actions button.primary {
    background: linear-gradient(135deg, #ffd166, #ffa83c);
    border-color: #d99a10;
    box-shadow: 0 3px 0 #d99a10;
  }
  #name-prompt-actions button:active { translate: 0 2px; box-shadow: 0 1px 0 var(--accent); }

  #author {
    position: fixed;
    bottom: calc(6px + env(safe-area-inset-bottom, 0px));
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
    color: rgba(60,40,80,0.55);
    font-style: italic;
    pointer-events: none;
    z-index: 8;
  }

  /* Princess select — appears after Start. Adapted from wolf-run's
     selector. Saves the chosen princess to localStorage so it persists
     across sessions; reopen via the Shop. */
  #princess-select {
    position: fixed; inset: 0;
    z-index: 8500;
    display: flex; align-items: center; justify-content: center;
    background: radial-gradient(ellipse at center, rgba(40,20,60,0.85) 0%, rgba(20,10,30,0.95) 100%);
    padding: 16px;
    overflow-y: auto;
    transition: opacity 0.4s ease;
  }
  #princess-select.hide { opacity: 0; pointer-events: none; }
  #princess-select .ps-col {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 18px;
    max-width: 760px;
    width: 100%;
  }
  #princess-select h2 {
    color: #ffe5b8;
    font-size: clamp(20px, 5vw, 36px);
    margin: 0;
    text-shadow: 2px 2px 0 #5e2a82, 4px 4px 0 rgba(0,0,0,0.4);
    text-align: center;
  }
  #princess-select .ps-cards {
    display: flex; gap: 12px; justify-content: center;
    align-items: stretch;
    width: 100%;
    flex-wrap: nowrap;
  }
  #princess-select .ps-card {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 10px 8px 12px;
    background: linear-gradient(180deg, rgba(255,255,255,0.10), rgba(255,255,255,0.04));
    border: 3px solid rgba(255,255,255,0.18);
    border-radius: 18px;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.15s, background 0.15s;
    color: #fff; text-align: center;
  }
  #princess-select .ps-card:hover { transform: translateY(-4px); border-color: rgba(255,255,255,0.4); }
  #princess-select .ps-card.selected {
    border-color: #ffd95a;
    background: linear-gradient(180deg, rgba(255,217,90,0.20), rgba(255,217,90,0.06));
    transform: translateY(-6px);
    box-shadow: 0 0 24px rgba(255,217,90,0.45);
  }
  #princess-select .ps-card img {
    width: 100%;
    height: clamp(80px, 30vh, 220px);
    object-fit: contain;
    pointer-events: none;
  }
  #princess-select .ps-name {
    font-size: clamp(12px, 3.2vw, 20px);
    font-weight: bold;
    line-height: 1.05;
  }
  #princess-select .ps-vibe {
    font-size: clamp(10px, 2.4vw, 14px);
    opacity: 0.85;
  }
  #princess-play-btn {
    margin-top: 6px;
    background: linear-gradient(180deg, #c69664 0%, #8b5e3c 100%);
    color: #fff;
    border: 4px solid #5a3618;
    box-shadow: 0 4px 0 #5a3618;
    border-radius: 999px;
    padding: 10px 26px;
    font-family: inherit;
    font-size: clamp(14px, 3.6vw, 22px);
    font-weight: bold;
    cursor: pointer;
    transition: transform 0.12s;
  }
  #princess-play-btn:disabled { opacity: 0.5; cursor: default; }
  #princess-play-btn:not(:disabled):active { transform: translateY(2px); box-shadow: 0 2px 0 #5a3618; }

  /* Princess-Run-style title screen — full-bleed painted hero art that
     doubles as the asset-loading curtain. */
  #title-screen {
    position: fixed; inset: 0;
    z-index: 9000;
    display: grid; place-items: center;
    transition: opacity 0.5s ease;
    background: #6fc1e4;
    overflow: hidden;
  }
  #title-screen.hide {
    opacity: 0;
    pointer-events: none;
  }
  #title-screen #title-art {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    /* Square art with the princess + dog at the bottom. On wide screens
       "cover" crops top & bottom, so anchor to the bottom to keep the
       characters in frame; the cropped-off top is just sky. */
    object-position: center bottom;
    z-index: 0;
    pointer-events: none;
  }
  #title-screen #title-text {
    position: absolute; z-index: 1;
    left: 50%; top: 6vh;
    transform: translateX(-50%);
    text-align: center;
    pointer-events: none;
    user-select: none;
    line-height: 0.9;
    font-family: "Fredoka", "Comic Sans MS", system-ui, sans-serif;
    font-weight: 800;
    width: max-content;
  }
  #title-screen #title-text .row1,
  #title-screen #title-text .row2 {
    display: block;
    color: #fff7d6;
    letter-spacing: 2px;
    text-shadow:
      -3px 0 0 #2d5430, 3px 0 0 #2d5430,
      0 -3px 0 #2d5430, 0 3px 0 #2d5430,
      -3px -3px 0 #2d5430, 3px 3px 0 #2d5430,
      -3px 3px 0 #2d5430, 3px -3px 0 #2d5430,
      0 6px 0 rgba(0,0,0,0.35),
      0 12px 22px rgba(0,0,0,0.55);
    animation: title-bob 2.4s ease-in-out infinite alternate;
  }
  #title-screen #title-text .row1 {
    font-size: clamp(28px, 7.5vw, 90px);
    color: #ffe18f;
    margin-bottom: 4px;
  }
  #title-screen #title-text .row2 {
    font-size: clamp(36px, 9.5vw, 116px);
    color: #ffdf63;
    letter-spacing: 3px;
    animation-delay: 0.2s;
  }
  @keyframes title-bob {
    from { transform: translateY(0)    rotate(-1deg); }
    to   { transform: translateY(-6px) rotate(1deg); }
  }
  #title-screen .title-actions {
    position: absolute; z-index: 1;
    left: 50%; bottom: 10vh;
    transform: translateX(-50%);
    display: flex; flex-direction: column;
    align-items: center; gap: 14px;
  }
  #title-screen .wood-btn {
    appearance: none;
    border: none;
    cursor: pointer;
    font-family: "Georgia", "Times New Roman", serif;
    font-weight: 900;
    font-size: clamp(20px, 3.4vw, 34px);
    letter-spacing: 0.06em;
    color: #4a2a14;
    text-shadow: 0 1px 0 rgba(255, 240, 210, 0.7);
    padding: 0.5em 1.6em;
    border-radius: 18px;
    background: linear-gradient(180deg, #fbe6b1 0%, #f1c878 45%, #d99a3f 100%);
    box-shadow:
      0 0 0 4px #4a2a14,
      0 0 0 7px #b6803a,
      inset 0 4px 0 rgba(255, 250, 220, 0.65),
      inset 0 -6px 8px rgba(120, 60, 20, 0.45),
      0 8px 14px rgba(0, 0, 0, 0.45);
    transition: transform 0.12s ease;
  }
  #title-screen .wood-btn:hover  { transform: translateY(-2px); }
  #title-screen .wood-btn:active { transform: translateY(2px); }
  #title-screen .wood-btn:disabled {
    cursor: wait;
    filter: saturate(0.5) brightness(0.85);
  }
