/* Pawville: the 3D town fills the screen; the icon bar sits along the top (Dylan's sketch), the joystick under your
   left thumb and the action button on the right. Windows (Town Hall, the calendar, friends, the map...) are white
   sheets over the town. */
:root { --ink: #1d3557; --muted: #6b7a90; --line: #e3eaf0; --teal: #2ec4b6; --pink: #ff5d8f; --gold: #ffd166; --panel: rgba(29, 53, 87, 0.78); }
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; overflow: hidden; background: #4aa8ff; font-family: 'Fredoka', 'Trebuchet MS', sans-serif; color: var(--ink);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; overscroll-behavior: none; }
button { font: inherit; cursor: pointer; }
#view { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }
.muted { color: var(--muted); font-weight: 400; }
.btn { font-weight: 700; font-size: 17px; border: 0; border-radius: 14px; padding: 9px 18px; background: var(--teal); color: #fff; }
.btn.alt { background: #e3eaf0; color: var(--ink); } .btn.pink { background: var(--pink); } .btn.gold { background: var(--gold); color: var(--ink); }
.btn.small { font-size: 14px; padding: 6px 12px; border-radius: 11px; }
.btn:disabled { opacity: .5; cursor: default; }
.hidden { display: none !important; }

/* ---- the top: back, sound, and the icon bar ---- */
#top { position: fixed; left: 0; right: 0; top: 0; z-index: 5; display: flex; align-items: flex-start; gap: 10px; pointer-events: none;
  padding: max(8px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-right)) 0 max(10px, env(safe-area-inset-left)); }
.tb { display: flex; gap: 6px; pointer-events: auto; }
.round-btn { width: 44px; height: 44px; padding: 0; border-radius: 50%; background: var(--panel); color: #fff; font-size: 20px; border: 2px solid rgba(255, 255, 255, 0.25); }
#bar { pointer-events: auto; margin: 0 auto; display: flex; gap: 4px; background: rgba(255, 255, 255, 0.86); border: 2px solid #fff; border-radius: 18px; padding: 4px; box-shadow: 0 6px 18px rgba(20, 40, 80, 0.22);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
#bar button { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 64px; padding: 4px 6px 3px; border: 2px solid transparent; border-radius: 13px; background: none; color: var(--ink); }
#bar button span { font-size: 26px; line-height: 1.05; }
#bar button b { font-size: 11.5px; font-weight: 600; white-space: nowrap; }
#bar button.on { background: #e6f8f6; border-color: var(--teal); }
#bar .dot { position: absolute; top: 3px; right: 9px; width: 11px; height: 11px; border-radius: 50%; background: #ff3d5a; border: 2px solid #fff; }
/* (a narrow screen: smaller icons, no labels) */
@media (max-width: 760px), (max-height: 430px) {
  #bar button { min-width: 44px; padding: 4px 3px; } #bar button b { display: none; } #bar button span { font-size: 23px; }
  .round-btn { width: 40px; height: 40px; font-size: 18px; }
}
@media (max-width: 480px) { #top { flex-wrap: wrap; } #bar { order: 3; margin: 0; width: 100%; justify-content: space-between; } #bar button { min-width: 0; flex: 1; } }

/* where you are ("Downtown"), and the arrow that shows you the way */
#where { position: fixed; left: 50%; top: calc(max(8px, env(safe-area-inset-top)) + 70px); translate: -50% 0; z-index: 4; pointer-events: none; font-size: 22px; font-weight: 700; color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); opacity: 0; transition: opacity 0.6s; white-space: nowrap; }
#where.on { opacity: 1; }
#guide { position: fixed; left: 50%; top: calc(max(8px, env(safe-area-inset-top)) + 106px); translate: -50% 0; z-index: 4; display: flex; align-items: center; gap: 8px; background: var(--panel); color: #fff;
  border-radius: 999px; padding: 4px 6px 4px 14px; font-weight: 600; font-size: 16px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25); width: max-content; max-width: calc(100vw - 24px); }
#guide[hidden] { display: none; }
/* (the special days: at midnight into Halloween or the birthday party, a button that reloads the town for it, game.js dayCheck) */
.newday { position: fixed; left: 50%; top: calc(max(8px, env(safe-area-inset-top)) + 150px); translate: -50% 0; z-index: 6; border: 0; border-radius: 999px; padding: 10px 20px; font: inherit; font-weight: 700; font-size: 17px;
  background: var(--gold); color: var(--ink); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3); max-width: calc(100vw - 24px); cursor: pointer; }
/* following a friend (live friends in town) */
#follow { position: fixed; left: 50%; top: calc(max(8px, env(safe-area-inset-top)) + 150px); translate: -50% 0; z-index: 4; display: flex; align-items: center; gap: 8px; background: #1a9e86; color: #fff;
  border-radius: 999px; padding: 4px 6px 4px 14px; font-weight: 600; font-size: 16px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25); width: max-content; max-width: calc(100vw - 24px); }
#follow[hidden] { display: none; }
#follow.come { background: #5b4fa8; border: 2px solid #ffd166; } /* (a friend next to you walked into a game: you're going too) */
#follow button { border: 0; background: rgba(255, 255, 255, 0.25); color: #fff; width: 30px; height: 30px; border-radius: 50%; padding: 0; }
/* 💬 say something to friends in town (only while one is here) */
.say { position: absolute; right: calc(max(18px, env(safe-area-inset-right)) + 14px); bottom: calc(max(26px, env(safe-area-inset-bottom)) + 108px); width: 64px; height: 64px; pointer-events: auto; border-radius: 50%;
  padding: 0; font-size: 30px; border: 3px solid rgba(255, 255, 255, 0.9); background: radial-gradient(circle at 35% 30%, #fff3b0, #ffb703); box-shadow: 0 4px 0 rgba(0, 0, 0, 0.2); }
.say[hidden] { display: none; }
.tag.live { box-shadow: 0 0 0 2px #ffd166; }
#guide-arrow { display: inline-block; font-size: 22px; color: var(--gold); transition: rotate 0.15s; }
#guide-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#guide button { border: 0; background: rgba(255, 255, 255, 0.2); color: #fff; width: 30px; height: 30px; border-radius: 50%; padding: 0; }
@media (max-height: 430px) { #where { top: 60px; font-size: 18px; } #guide { top: 92px; font-size: 14px; } }
/* (a phone held upright: the icon bar wraps onto a second row down to ~106px, so the place name went behind it) */
@media (max-width: 480px) { #where { top: calc(max(8px, env(safe-area-inset-top)) + 106px); font-size: 18px; } #guide { top: calc(max(8px, env(safe-area-inset-top)) + 140px); left: 0; right: 0; margin: 0 auto; translate: none; width: fit-content; max-width: calc(100vw - 24px); }
  #follow { top: calc(max(8px, env(safe-area-inset-top)) + 192px); } #guide-text { white-space: normal; } } /* ("the train is quicker!" was cut off) */

/* ---- name tags and speech bubbles over people ---- */
#tags { position: fixed; inset: 0; pointer-events: none; z-index: 2; overflow: hidden; }
#tags > div { position: absolute; left: 0; top: 0; white-space: nowrap; will-change: transform; }
.tag { font-size: 13px; font-weight: 700; color: #fff; background: rgba(29, 53, 87, 0.72); border-radius: 10px; padding: 2px 9px; }
.tag.mayor { background: rgba(155, 93, 229, 0.85); }
.tag.friend { background: rgba(255, 93, 143, 0.85); } .tag.online { box-shadow: 0 0 0 2px #7dffb0; }
.bubble { font-size: 15px; font-weight: 600; color: var(--ink); background: #fff; border-radius: 14px; padding: 6px 12px; max-width: 260px; white-space: normal !important; text-align: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); animation: bub 0.25s cubic-bezier(.2, 1.6, .4, 1) both; }
.bubble::after { content: ''; position: absolute; left: 50%; bottom: -8px; margin-left: -8px; border: 8px solid transparent; border-bottom: 0; border-top-color: #fff; }
@keyframes bub { from { opacity: 0; scale: 0.6; } to { opacity: 1; scale: 1; } }

/* ---- touch controls ---- */
#controls { position: fixed; inset: 0; z-index: 3; pointer-events: none; }
#joyzone { position: absolute; left: 0; bottom: 0; width: 50%; top: 130px; pointer-events: auto; touch-action: none; }
.joy-base { position: absolute; left: max(110px, calc(env(safe-area-inset-left) + 100px)); top: auto; bottom: max(30px, env(safe-area-inset-bottom)); width: 130px; height: 130px; margin: -65px 0 0 -65px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.22)); border: 3px solid rgba(255, 255, 255, 0.55); opacity: 0.5; pointer-events: none; transition: opacity 0.2s; }
.joy-base:not(.on) { bottom: max(30px, env(safe-area-inset-bottom)); margin: 0 0 0 -65px; }
.joy-base.on { opacity: 1; bottom: auto; transition: none; margin-top: var(--half, -65px) !important; }
.joy-knob { position: absolute; left: 50%; top: 50%; width: 62px; height: 62px; margin: -31px 0 0 -31px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, #e6e0ff); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35); }
@media (pointer: fine) { .joy-base:not(.on) { display: none; } }
/* the jump button (bottom right, like Roblox) and the action button beside it */
.jump { position: absolute; right: max(18px, env(safe-area-inset-right)); bottom: max(26px, env(safe-area-inset-bottom)); width: 92px; height: 92px; pointer-events: auto; border-radius: 50%; padding: 0;
  display: grid; place-items: center; align-content: center; color: #fff; border: 3px solid rgba(255, 255, 255, 0.85); background: radial-gradient(circle at 35% 30%, rgba(160, 200, 255, 0.75), rgba(40, 80, 160, 0.7));
  box-shadow: 0 5px 0 rgba(0, 0, 0, 0.22); touch-action: none; }
.jump span { font-size: 34px; line-height: 0.9; } .jump b { font-size: 12px; font-weight: 700; }
.jump:active { translate: 0 3px; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.22); }
@media (hover: hover) and (pointer: fine) { .jump { display: none; } .act { right: max(18px, env(safe-area-inset-right)) !important; } }
#keys-hint { position: fixed; left: max(12px, env(safe-area-inset-left)); bottom: max(12px, env(safe-area-inset-bottom)); z-index: 4; background: var(--panel); color: #fff; border-radius: 12px; padding: 7px 12px;
  font-size: 13.5px; pointer-events: none; transition: opacity 0.8s; max-width: calc(100vw - 180px); }
#keys-hint[hidden] { display: none; } #keys-hint.off { opacity: 0; }
#keys-hint kbd { font: inherit; font-weight: 700; background: rgba(255, 255, 255, 0.2); border-radius: 5px; padding: 0 5px; }
.act { position: absolute; right: calc(max(18px, env(safe-area-inset-right)) + 104px); bottom: max(24px, env(safe-area-inset-bottom)); width: 118px; height: 118px; pointer-events: auto; border-radius: 50%; padding: 0;
  display: grid; place-items: center; align-content: center; color: #fff; font-size: 36px; line-height: 1; border: 4px solid rgba(255, 255, 255, 0.9);
  background: radial-gradient(circle at 35% 30%, #ffe29a, #ff9f1c); box-shadow: 0 6px 0 rgba(0, 0, 0, 0.25), 0 8px 20px rgba(0, 0, 0, 0.3); animation: act-in 0.3s cubic-bezier(.2, 1.6, .4, 1) both; }
.act[hidden] { display: none; }
.act b { font-size: 13px; font-weight: 700; margin-top: 4px; line-height: 1.15; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); max-width: 104px; text-align: center; white-space: normal; }
.act.talk { background: radial-gradient(circle at 35% 30%, #d9c2ff, #8a4fe0); } .act.go { background: radial-gradient(circle at 35% 30%, #9dffcf, #1a9e86); }
.act.build { background: radial-gradient(circle at 35% 30%, #ffb3c8, #e6457a); } .act.train { background: radial-gradient(circle at 35% 30%, #ffd0a0, #e65a28); }
.act.wait { filter: saturate(0.4) brightness(0.95); }
@keyframes act-in { from { scale: 0.5; opacity: 0; } to { scale: 1; opacity: 1; } }
@media (max-height: 430px) { .act { width: 96px; height: 96px; font-size: 30px; right: calc(max(18px, env(safe-area-inset-right)) + 86px); } .act b { font-size: 11.5px; } .joy-base { scale: 0.85; }
  .jump { width: 76px; height: 76px; } .jump span { font-size: 28px; } .say { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 88px); } .say.decor { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 160px); } }
/* a phone held upright: the action button goes above Jump, clear of the joystick (Alex's play-test: steering right
   pressed "Get out" of a moving fire truck), and 💬 and the rest move up one */
@media (max-width: 480px) and (min-height: 600px) {
  #controls .act { right: calc(max(18px, env(safe-area-inset-right)) - 2px); bottom: calc(max(26px, env(safe-area-inset-bottom)) + 104px); width: 96px; height: 96px; font-size: 30px; }
  #controls .act b { font-size: 11.5px; max-width: 88px; }
  #controls .say { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 212px); } #controls .say.decor { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 286px); }
  /* (riding: the stop and Hop off sat on the joystick and against Jump, in three squashed lines; now one tidy row above them; body: the plain #ride rules come later in this file) */
  body #ride { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 148px); font-size: 16px; gap: 8px; padding: 8px 8px 8px 14px; max-width: calc(100vw - 24px); white-space: nowrap; }
  body #ride .big { font-size: 16px; padding: 9px 12px; }
  body #ride-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  body:has(#ride:not([hidden])) #toast { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 214px); }
  /* (messages: in the space left of the buttons on the right, since the action button sits up here now: "Back to the real
     time of day" covered "Ride the gondola" at the gondola station, the mountain audit, 2026-10-19) */
  body #toast { left: max(12px, env(safe-area-inset-left)); right: calc(max(18px, env(safe-area-inset-right)) + 102px); translate: none; margin: 0 auto; width: fit-content; max-width: none; }
}

/* riding the train */
#ride { position: fixed; left: 50%; bottom: max(24px, env(safe-area-inset-bottom)); translate: -50% 0; z-index: 4; display: flex; align-items: center; gap: 12px; background: var(--panel); color: #fff;
  border-radius: 20px; padding: 10px 12px 10px 18px; font-size: 19px; font-weight: 600; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3); }
#ride[hidden] { display: none; }
#ride .big { font-size: 18px; font-weight: 700; border: 0; border-radius: 14px; padding: 10px 18px; background: var(--gold); color: var(--ink); }

#toast { position: fixed; left: 50%; bottom: max(150px, calc(env(safe-area-inset-bottom) + 140px)); translate: -50% 0; z-index: 6; background: var(--panel); color: #fff; font-size: 17px; font-weight: 600;
  padding: 8px 16px; border-radius: 14px; pointer-events: none; opacity: 0; transition: opacity 0.3s; width: max-content; max-width: min(720px, calc(100vw - 2 * (max(18px, env(safe-area-inset-right)) + 88px))); text-align: center; }
/* (max-width: clear of the round buttons on the right, as far in from the left, so it stays centered: on an upright iPad
   "Umbrella up!..." ran under 💬, 2026-10-24) */
/* (width: max-content: with left: 50% a box only gets half the screen before it wraps, so on a phone messages squeezed into a narrow column) */
#toast.on { opacity: 1; }
/* (admin mode's 🛠️ ADMIN tag, shared/admin.js, sits over everything at the bottom left: on a phone a window reaches down
   there, and the tag covered the calendar's days; the windows say "(admin)" themselves) */
body:has(.sheet:not(.hidden)) #pm-admin-tag { display: none !important; }
/* 🍬 trick-or-treat candy (candy.js): the big picture card, the bag button up top with its count, the bag window */
#candy-card { position: fixed; left: 50%; top: 42%; z-index: 7; translate: -50% -50%; display: flex; flex-direction: column; align-items: center; gap: 2px;
  width: max-content; min-width: 220px; max-width: calc(100vw - 32px); padding: 14px 26px 16px; /* (max-content: with left: 50% it only got half the screen and wrapped on an upright phone) */
  border-radius: 26px; background: linear-gradient(#ffb347, #ff7a1a); border: 4px solid #fff; color: #fff;
  box-shadow: 0 10px 30px rgba(40, 10, 60, 0.45); text-align: center; pointer-events: auto; opacity: 0; scale: 0.6; transition: opacity 0.25s, scale 0.3s cubic-bezier(.3, 1.6, .5, 1); }
#candy-card[hidden] { display: none; }
#candy-card.on { opacity: 1; scale: 1; }
#candy-card.fly { transition: transform 0.5s ease-in, opacity 0.5s ease-in; opacity: 0.2; }
#candy-card .cc-pic { font-size: 96px; line-height: 1.1; filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3)); }
#candy-card .cc-title { font-size: 26px; text-shadow: 0 2px 0 rgba(120, 40, 0, 0.45); }
#candy-card .cc-what { font-size: 20px; font-weight: 600; }
#candy-card .cc-pts { margin-top: 4px; font-size: 16px; font-weight: 700; background: rgba(60, 20, 90, 0.55); border-radius: 12px; padding: 2px 10px; }
#candy-card .cc-pts[hidden] { display: none; }
@media (max-height: 430px) { #candy-card { top: 46%; padding: 8px 20px 10px; } #candy-card .cc-pic { font-size: 64px; } #candy-card .cc-title { font-size: 21px; } #candy-card .cc-what { font-size: 17px; } }
#b-candy { position: relative; background: linear-gradient(#ffb347, #ff7a1a); }
#b-candy[hidden] { display: none; }
#b-candy i { position: absolute; right: -5px; top: -5px; min-width: 20px; height: 20px; padding: 0 4px; border-radius: 10px; background: #fff; color: #c2410c; font: 700 12px/20px Fredoka, sans-serif; font-style: normal; }
#b-candy.bounce { animation: candy-bounce 0.6s ease-out; }
@keyframes candy-bounce { 0% { scale: 1; } 30% { scale: 1.35; } 60% { scale: 0.9; } 100% { scale: 1; } }
.candy-bag { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; margin: 6px 0 4px; }
.cb-treat { position: relative; display: flex; flex-direction: column; align-items: center; padding: 8px 4px 10px; border-radius: 18px; background: #fff3e0; border: 2px solid #ffcc80; }
.cb-treat .cb-pic { font-size: 54px; line-height: 1.15; }
.cb-treat b { font-size: 15px; text-align: center; }
.cb-treat i { position: absolute; top: 6px; right: 8px; font: 700 16px Fredoka, sans-serif; font-style: normal; color: #c2410c; }
@media (prefers-reduced-motion: reduce) { #candy-card, #candy-card.fly { transition: opacity 0.2s; } #b-candy.bounce { animation: none; } }
#toast.over { z-index: 13; } /* ("costs 🐾 100" over the open shop: it showed behind it, Mia's play-test) */
/* (a short screen, like a phone held sideways: messages keep clear of the column of round buttons on the right, and as
   much on the left so they stay centered; "Umbrella up! Tap ☂️ to fold it away..." ran 33 px under 💬, 2026-10-24) */
@media (max-height: 430px) { #toast { max-width: calc(100vw - 2 * (max(18px, env(safe-area-inset-right)) + 86px)); } }
/* (with a friend's 📻 card up on a short screen, messages go low, between the joystick and the buttons: one sat on Go there, 2026-10-30) */
@media (max-height: 430px) { body:has(#radio:not([hidden])) #toast { bottom: max(10px, env(safe-area-inset-bottom)); max-width: calc(100vw - 2 * (max(18px, env(safe-area-inset-right)) + 172px)); } }
/* (🛠️ Build mode at home on a phone held upright: the card goes up under the top bar, the width of the screen. Between
   the joystick and the buttons it was 130 px wide, a tall column right over the messages, "Build mode! Walk up to
   something..." and "It doesn't fit there...", 2026-10-24. !important: its place is set on the card itself, game.js) */
@media (max-width: 480px) and (min-height: 600px) { #buildbar { top: calc(max(8px, env(safe-area-inset-top)) + 146px); bottom: auto !important; max-width: calc(100vw - 24px) !important; } }
#fade { position: fixed; inset: 0; z-index: 30; background: #fff; opacity: 0; pointer-events: none; transition: opacity 0.5s; display: grid; place-items: center; }
#fade.on { opacity: 1; pointer-events: auto; }
#fade.dark { background: #0b0f2a; color: #fff; }
#fade-text { font-size: 30px; font-weight: 700; text-align: center; padding: 20px; }

/* ---- windows ---- */
/* (their own pop-in: polish.css's pm-pop moves `translate`, which these use to stay centered) */
@keyframes pv-pop { from { opacity: 0; scale: 0.9; } to { opacity: 1; scale: 1; } }
.sheet { position: fixed; z-index: 12; left: 50%; top: 50%; translate: -50% -50%; width: min(620px, calc(100vw - 20px)); max-height: calc(100vh - 20px); max-height: calc(100dvh - 20px); overflow-y: auto;
  background: #fff; border-radius: 22px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35); padding: 18px 20px 20px; -webkit-overflow-scrolling: touch; animation: pv-pop 0.32s cubic-bezier(.2, 1.4, .4, 1) both;
  -webkit-user-select: text; user-select: text; }
.sheet .x { position: sticky; float: right; top: 0; margin: -6px -8px 0 8px; width: 40px; height: 40px; border-radius: 50%; border: 0; background: #eef2f6; color: var(--ink); font-size: 18px; z-index: 2; }
.sheet h2 { margin: 0 0 6px; font-size: 25px; } .sheet h3 { margin: 16px 0 6px; font-size: 18px; }
.sheet p { margin: 6px 0; line-height: 1.4; } .sheet .hint { color: var(--muted); font-size: 14px; margin-top: 0; }
#mapbox .map-wx { margin-left: 10px; font-size: 14px; font-weight: 600; color: var(--muted); white-space: nowrap; } /* (Skye's forecast, in the title line: game.js openMap) */
@media (max-width: 700px), (max-height: 600px) { #mapbox .map-wx { display: none; } } /* (a phone: no room in the title; the board and the Calendar have it) */
.sheet .server { font-size: 15px; font-weight: 600; background: #fff0f6; color: #8a2a52; border-radius: 12px; padding: 6px 10px; margin: 4px 0 8px; } /* (the ice cream truck's server, taking your order) */
.tabs { display: flex; gap: 6px; margin: 8px 0 10px; } .tabs button { flex: 1; font-weight: 700; font-size: 15px; border: 2px solid var(--line); background: #fff; color: var(--ink); border-radius: 12px; padding: 7px; }
.tabs button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.news { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.news li { display: flex; gap: 12px; align-items: flex-start; background: #f5f8fb; border-radius: 14px; padding: 10px 12px; }
.news li.new { background: #fff6dc; box-shadow: inset 0 0 0 2px #ffd166; }
.news .e { font-size: 30px; line-height: 1; } .news b { display: block; font-size: 16px; } .news .when { font-size: 12px; color: var(--muted); }
.news p { margin: 3px 0 0; font-size: 14.5px; }
.issue { margin: 0 0 10px; border-radius: 16px; } .issue h3, .issue summary { margin: 4px 0 8px; font-size: 17px; } .issue .when { font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 6px; }
.issue summary { cursor: pointer; padding: 10px 12px; background: #f5f8fb; border-radius: 14px; list-style-position: inside; } details.issue[open] summary { margin-bottom: 8px; }
.issue.new h3::after, .issue.new summary::after { content: ' NEW'; font-size: 11px; font-weight: 700; color: #b26b00; background: #ffd166; border-radius: 8px; padding: 1px 6px; margin-left: 6px; vertical-align: 2px; }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.stat { background: #f5f8fb; border-radius: 14px; padding: 10px 12px; text-align: center; }
.stat .n { font-size: 26px; font-weight: 700; color: #7b5cff; display: block; line-height: 1.1; } .stat .e { font-size: 22px; } .stat span:last-child { font-size: 13px; color: var(--muted); }
.cal-head { display: flex; align-items: center; gap: 8px; margin: 6px 0; } .cal-head b { flex: 1; text-align: center; font-size: 19px; }
.cal-head button { width: 40px; height: 40px; border-radius: 50%; border: 0; background: #eef2f6; font-size: 18px; }
.cal-head button:disabled { opacity: 0.3; }
.cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal .dow { font-size: 12px; color: var(--muted); text-align: center; font-weight: 600; }
.cal .d { min-height: 52px; border-radius: 10px; background: #f5f8fb; padding: 3px 4px; font-size: 12px; position: relative; overflow: hidden; }
.cal .d.out { background: none; } .cal .d.today { box-shadow: inset 0 0 0 2px var(--teal); } .cal .d .num { font-weight: 700; }
.cal .d .ev { display: block; font-size: 16px; line-height: 1.1; }
.cal .d.has { cursor: pointer; } .cal .d.pick { box-shadow: inset 0 0 0 3px var(--pink); }
#cal-day { margin-top: 8px; min-height: 40px; }
.event { border-radius: 16px; padding: 12px 14px; margin: 8px 0; background: #f5f8fb; }
.event.now { background: linear-gradient(135deg, #fff1df, #f2e6ff); box-shadow: inset 0 0 0 2px var(--gold); }
.event .eh { display: flex; align-items: center; gap: 10px; } .event .eh .e { font-size: 36px; } .event .eh b { font-size: 19px; display: block; } .event .badge { font-size: 12px; font-weight: 700; border-radius: 8px; padding: 2px 8px; background: var(--ink); color: #fff; }
.event ul { margin: 6px 0 0; padding-left: 18px; } .event li { margin: 3px 0; font-size: 14.5px; }
.friends { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.friends li { display: flex; align-items: center; gap: 10px; background: #f5f8fb; border-radius: 14px; padding: 6px 10px; }
.friends img { width: 52px; height: 52px; border-radius: 12px; background: #fff3c4; }
.friends .nm { flex: 1; min-width: 0; } .friends .nm b { display: block; } .friends .nm span { font-size: 13px; color: var(--muted); }
.feed li { font-size: 14.5px; }
.who-card { display: flex; gap: 14px; align-items: center; } .who-card img { width: 96px; height: 96px; border-radius: 18px; background: #fff3c4; }
.row-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.emotes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; } .emotes button { border: 2px solid var(--line); background: #fff; border-radius: 12px; padding: 6px 10px; font-size: 15px; font-weight: 600; color: var(--ink); }
.emotes button.on { border-color: var(--pink); background: #ffe3ec; } /* (a pick: the birthday wishes board, holiday.js) */
.big-e { font-size: 64px; text-align: center; display: block; }
.places { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; } .places button { border: 2px solid var(--line); background: #fff; border-radius: 12px; padding: 6px 10px; font-size: 14px; font-weight: 600; color: var(--ink); min-height: 44px; }
.map-wrap { position: relative; width: 100%; aspect-ratio: 1 / 1; max-height: 66vh; margin: 0 auto; border-radius: 16px; overflow: hidden; background: #7cc56a; }
#mapbox { width: min(680px, calc(100vw - 20px)); }
#map { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; } /* (drag and pinch are the map's: map.js) */
/* the map's ＋ － 📍 buttons, and the card for the place you tapped (map.js): big enough for small fingers (44 px+) */
.map-zoom { position: absolute; left: 8px; bottom: 8px; display: flex; flex-direction: column; gap: 6px; z-index: 2; }
.map-card:not([hidden]) ~ .map-zoom { display: none; } /* (bottom left, clear of the map's top; the card covers them while it's up) */
/* the map's filters (map.js: a row over the map that scrolls sideways when it doesn't fit) and the list's sections */
.map-chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 10px; scrollbar-width: none; } .map-chips::-webkit-scrollbar { display: none; }
.map-chips button { flex: none; min-height: 44px; border-radius: 22px; border: 2px solid #d9d3ea; background: #fff; font: 700 15px Fredoka, sans-serif; padding: 0 12px; color: var(--ink); }
.map-chips button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.ml-sec { margin: 10px 0 4px; } .ml-sec summary { font-weight: 700; font-size: 17px; cursor: pointer; padding: 6px 2px; min-height: 32px; list-style-position: inside; }
.ml-sec summary span { display: inline-block; min-width: 24px; padding: 0 7px; border-radius: 11px; background: #ece8f7; font-size: 14px; text-align: center; margin-left: 4px; }
/* you on the map (map.js): your animal's face in a bright pink circle with a glow, a ring pulsing outward, a small arrow
   on its edge the way you face; a white edge and a dark outline so it shows on grass, roads, sand and water */
.map-me { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; z-index: 1; }
.map-me .mm-dot { position: absolute; left: -19px; top: -19px; width: 38px; height: 38px; box-sizing: border-box; border-radius: 50%; background: #ff3d7f; border: 3px solid #fff; box-shadow: 0 0 0 2px rgba(43, 33, 96, 0.6), 0 0 14px 6px rgba(255, 61, 127, 0.8); display: grid; place-items: center; }
.map-me .mm-dot b { font-size: 20px; line-height: 1; font-weight: 400; }
.map-me .mm-ring { position: absolute; left: -19px; top: -19px; width: 38px; height: 38px; box-sizing: border-box; border-radius: 50%; border: 4px solid #ff3d7f; opacity: 0; animation: mm-pulse 1.8s ease-out infinite; }
.map-me .mm-dir { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-origin: 0 0; }
.map-me .mm-dir i { position: absolute; left: -9px; top: -35px; width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent; border-bottom: 14px solid #2b2160; filter: drop-shadow(0 0 1.2px #fff) drop-shadow(0 0 1.2px #fff) drop-shadow(0 0 1px #fff); }
.map-me.flash .mm-dot { animation: mm-flash 0.42s ease-in-out 4 alternate; }
@keyframes mm-pulse { 0% { transform: scale(1); opacity: 0.9; } 100% { transform: scale(2.9); opacity: 0; } }
@keyframes mm-flash { to { transform: scale(1.4); box-shadow: 0 0 0 2px rgba(43, 33, 96, 0.6), 0 0 22px 12px rgba(255, 61, 127, 0.95); } }
@media (prefers-reduced-motion: reduce) { .map-me .mm-ring { animation: none; opacity: 0.45; transform: scale(1.6); } .map-me.flash .mm-dot { animation: none; } }
.map-zoom button { width: 46px; height: 46px; border-radius: 14px; border: 2px solid rgba(43, 33, 96, 0.25); background: rgba(255, 255, 255, 0.92); font-size: 24px; font-weight: 700; color: var(--ink); padding: 0; line-height: 1; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18); }
.map-card { position: absolute; z-index: 2; left: 8px; right: 8px; bottom: 8px; display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 12px; background: #fff; border-radius: 18px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28); color: var(--ink); }
.map-card[hidden] { display: none; }
.map-card .mc-e { font-size: 40px; line-height: 1; }
.map-card .mc-t { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.map-card .mc-t b { font-size: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.map-card .mc-t span { font-size: 15px; font-weight: 600; opacity: 0.8; }
.map-card button { min-height: 48px; border: 0; border-radius: 14px; font-size: 17px; font-weight: 700; padding: 0 14px; white-space: nowrap; }
.map-card .mc-go { background: #ff8c1a; color: #fff; box-shadow: 0 3px 0 #c76a0f; }
.map-card .mc-stop { background: #e9e4f5; color: var(--ink); }
.map-card .mc-jump { background: #7b5cff; color: #fff; box-shadow: 0 3px 0 #5537c9; }
/* (two buttons: the name and ✕ on the first row, the buttons sharing the next: the map is narrow on a phone on its side) */
.map-card.two { flex-wrap: wrap; } .map-card.two .mc-t { flex-basis: calc(100% - 110px); } .map-card.two .mc-x { order: 1; } .map-card.two .mc-go, .map-card.two .mc-jump { order: 2; flex: 1; padding: 0 8px; }
.map-card .mc-x { background: #f1eef8; color: var(--ink); width: 48px; padding: 0; }
/* (an upright phone: a taller map, and the card's 🧭 button on a row of its own so the name fits) */
@media (max-width: 480px) and (orientation: portrait) { .map-wrap { aspect-ratio: 4 / 5; max-height: 64vh; }
  .map-card { flex-wrap: wrap; row-gap: 6px; } .map-card .mc-e { font-size: 32px; } .map-card .mc-t b { font-size: 16px; }
  .map-card .mc-x { order: 2; } .map-card .mc-go, .map-card .mc-stop { order: 3; flex: 1 1 100%; font-size: 16px; } }
@media (orientation: landscape) and (max-height: 600px) {
  #mapbox { width: min(900px, calc(100vw - 20px)); display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto auto auto minmax(0, 1fr); column-gap: 14px; } /* (✕, the title, the hint, the filters, the list) */
  #mapbox h2, #mapbox .hint, .map-chips { grid-column: 2; } .map-chips { gap: 6px; padding-bottom: 6px; } /* (one row that scrolls sideways: wrapped, it left no room for the list) */ #mapbox .x { grid-column: 2; justify-self: end; }
  .map-wrap { grid-row: 1 / span 5; grid-column: 1; height: calc(100dvh - 60px); width: auto; max-height: none; }
  /* (the places' list fills the rest of the column and scrolls by itself, the map staying put: it was in a row of its own
     under the map, the one-line hint stretched to fill the map's height above it, so on a phone the list started past the
     window's bottom edge, the phone bug hunt 2026-10-23) */
  #map-list { grid-column: 2; grid-row: 5; min-height: 0; overflow-y: auto; }
  /* (the map's a small square here too: the card's 🧭 button on its own row, or the name was cut to "R." (the UAT)) */
  .map-card { flex-wrap: wrap; row-gap: 6px; } .map-card .mc-e { font-size: 32px; } .map-card .mc-t b { font-size: 16px; }
  .map-card .mc-x { order: 2; } .map-card .mc-go, .map-card .mc-stop { order: 3; flex: 1 1 100%; font-size: 16px; }
}

/* ---- building your house (a strip of choices at the bottom; the camera looks at the house) ---- */
#builder, #decor { position: fixed; left: 50%; bottom: max(10px, env(safe-area-inset-bottom)); translate: -50% 0; z-index: 8; width: min(760px, calc(100vw - 16px)); max-height: 46vh; display: flex; flex-direction: column;
  background: #fff; border-radius: 20px; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.35); overflow: hidden; animation: pv-pop 0.32s cubic-bezier(.2, 1.4, .4, 1) both; }
.b-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid #eef2f6; } .b-head b { font-size: 18px; } .b-head .grow { flex: 1; }
/* (the buttons on one line each, the title wraps instead: on an upright phone "Rent it! ✓" broke onto two lines, the town UAT 2026-10-23) */
.b-head .btn { white-space: nowrap; flex: none; } .b-head b { min-width: 0; }
@media (max-width: 480px) { .b-head { gap: 6px; padding: 8px 10px; } .b-head b { font-size: 16px; } .b-head .btn { font-size: 16px; padding: 9px 13px; } }
.b-rows { overflow-y: auto; padding: 6px 12px 12px; -webkit-overflow-scrolling: touch; }
.b-row { margin: 6px 0; } .b-row > b { display: block; font-size: 14px; margin-bottom: 4px; }
@media (max-height: 520px) { #builder, #decor { max-height: 54vh; } }
/* decorating your house */
.b-head .bucks { font-weight: 700; color: #1d5a3a; background: #fff3c4; border-radius: 10px; padding: 3px 10px; font-size: 15px; }
.d-tabs { display: flex; gap: 6px; padding: 8px 12px 0; } .d-tabs button { flex: 1; border: 2px solid #e3eaf0; background: #fff; border-radius: 12px; padding: 7px 6px; font-weight: 700; font-size: 14px; color: var(--ink); }
.d-tabs button.on { border-color: #2ec4b6; background: #e6f8f6; }
.f-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; margin-top: 6px; }
.f-grid button { border: 2px solid #e3eaf0; background: #fff; border-radius: 14px; padding: 8px 6px; display: grid; gap: 2px; justify-items: center; color: var(--ink); font-size: 14px; font-weight: 600; }
.f-grid button .e { font-size: 28px; } .f-grid button small { color: #1d5a3a; font-weight: 700; } .f-grid button.cant small { color: #c0392b; } .f-grid button.cant { opacity: 0.7; }
#place { position: fixed; left: 50%; bottom: max(14px, env(safe-area-inset-bottom)); translate: -50% 0; z-index: 8; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center;
  background: #fff; border-radius: 18px; padding: 8px 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); max-width: calc(100vw - 260px); }
#place .hint { color: var(--muted); font-size: 13px; }
#place-colors { display: flex; gap: 8px; align-items: center; justify-content: center; flex-basis: 100%; } #place-colors:empty { display: none; } /* (the piece's colors, a row of their own under its name: inside.js colorDots) */
/* (the piece's name on a row of its own, so the Turn / Put it here buttons keep one layout whatever its name; on an
   upright phone the card goes across the screen above the joystick instead of a tall narrow card over it: the play-test) */
#place b { flex-basis: 100%; text-align: center; }
@media (orientation: portrait) and (max-width: 600px) { #place { left: 12px; right: 12px; translate: none; max-width: none; bottom: calc(max(14px, env(safe-area-inset-bottom)) + 170px); }
  #place.top { bottom: auto; top: calc(env(safe-area-inset-top) + 128px); } #place.top .hint { display: none; } } /* (the piece is down in the lower half: game.js placeCardOutOfTheWay) */
.say.decor { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 182px); background: radial-gradient(circle at 35% 30%, #ffd0e0, #ff5d8f); }
.say.cruise { background: radial-gradient(circle at 35% 30%, #d6ecff, #3a86ff); }
.say.umb { background: radial-gradient(circle at 35% 30%, #e0f0ff, #5aa9e6); }
.say.snowball { background: radial-gradient(circle at 35% 30%, #ffffff, #a8c8e8); } #b-umb:not([hidden]) + #b-snow { transform: translateY(-94px); } /* (snowballs.js: above the umbrella when both are out) */ .say.umb.shut { background: radial-gradient(circle at 35% 30%, #f2f2f2, #9aa1ad); opacity: 0.85; }
.umb-pick { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 10px 0; }
.umb-pick button { width: 58px; height: 58px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2); padding: 0; cursor: pointer; }
.umb-pick button.on { box-shadow: 0 0 0 4px #ffd166, 0 2px 0 rgba(0, 0, 0, 0.2); transform: scale(1.08); }
.say.cruise.on { background: radial-gradient(circle at 35% 30%, #d9ffe6, #2ecc71); box-shadow: 0 0 0 4px #fff, 0 0 18px #2ecc71; animation: cruise-pulse 1.6s ease-in-out infinite; }
@keyframes cruise-pulse { 50% { transform: scale(1.07); } }

/* ---- the Mayor talking ---- */
#talk { position: fixed; left: 50%; bottom: max(14px, env(safe-area-inset-bottom)); translate: -50% 0; z-index: 9; width: min(620px, calc(100vw - 20px)); background: #fff; border-radius: 22px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35); padding: 14px 16px; animation: pv-pop 0.32s cubic-bezier(.2, 1.4, .4, 1) both; }
#talk .who { display: flex; align-items: center; gap: 10px; } #talk img { width: 64px; height: 64px; border-radius: 16px; background: #f2e6ff; }
#talk .who b { display: block; font-size: 19px; color: #7b3fd1; } #talk .who small { color: var(--muted); }
#talk p { font-size: 19px; line-height: 1.4; margin: 10px 0; min-height: 2.8em; }
#talk .foot { display: flex; justify-content: flex-end; gap: 8px; }
@media (max-height: 520px) {
  #place { flex-wrap: nowrap; padding: 5px 8px; gap: 6px; max-width: calc(100vw - 230px); } #place .hint { display: none; }
  #place .btn { font-size: 14px; padding: 6px 10px; white-space: nowrap; min-height: 44px; } /* (a finger's worth: they were 29 px tall on a phone) */ #place b { font-size: 14px; white-space: nowrap; flex-basis: auto; } /* (sideways: one row) */ #place-colors { flex-basis: auto; gap: 5px; } #place-colors button { width: 34px !important; height: 34px !important; } #place .pc-name { display: none; }
}
@media (max-height: 430px) { .say.decor { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 160px); } }
/* walking into a game (or back out): the buttons step aside so you can watch */
body.cine #controls, body.cine #top, body.cine #where, body.cine #guide, body.cine #keys-hint { opacity: 0; pointer-events: none !important; transition: opacity 0.4s; }
body.cine #controls *, body.cine #top * { pointer-events: none !important; } /* (#top too: the bar and the round buttons turn their own taps back on, so the hidden 🔑 My House could still be tapped mid-walk, 2026-10-23) */
/* Pawville Scoops: the treats and the flavors */
.f-grid button.on { box-shadow: inset 0 0 0 3px var(--pink); background: #fff0f5; }
.chips.flavors .chip { display: inline-flex; align-items: center; gap: 6px; }
.chips.flavors .sw { display: inline-block; width: 18px; height: 18px; border-radius: 50%; border: 2px solid rgba(0, 0, 0, 0.12); }
.pick-now { font-size: 18px; font-weight: 700; text-align: center; min-height: 26px; }
#panel .foot { display: flex; gap: 8px; align-items: center; margin-top: 10px; } #panel .foot .grow { flex: 1; }
.logbook { background: #f3e4c3; color: #3b2a18; border: 1px solid #c9ad7a; border-radius: 10px; padding: 14px 16px; font-size: 18px; line-height: 1.5; } .sheet .logbook p, #panel .logbook p { margin: 0; line-height: 1.5; } /* (Captain Splash's old logbook, gondola-scenery.js) */
/* (the keys hint steps aside while the Mayor talks, a window is open, or you're building) */
body:has(#talk:not(.hidden)) #keys-hint, body:has(.sheet:not(.hidden)) #keys-hint, body:has(#builder:not(.hidden)) #keys-hint { display: none; }

/* ---------- your own music (🎧 My Music), a friend DJing, and the dance moves ---------- */
#tunes-ui { position: fixed; left: max(10px, env(safe-area-inset-left)); top: calc(max(8px, env(safe-area-inset-top)) + 66px); z-index: 4; display: grid; gap: 6px; justify-items: start; max-width: min(380px, calc(100vw - 20px)); }
#nowplaying, #radio { display: flex; align-items: center; gap: 6px; background: linear-gradient(135deg, #7b5cff, #ff5d8f); color: #fff; border-radius: 16px; padding: 4px 4px 4px 6px; box-shadow: 0 4px 14px rgba(20, 10, 60, 0.3); font-weight: 600; }
#nowplaying[hidden], #radio[hidden], #rental[hidden], #held[hidden] { display: none; }
/* (the beach rental you're carrying: ✕ when you're done with it, and it goes back to the shack: shack.js) */
#rental { display: flex; align-items: center; gap: 8px; background: linear-gradient(135deg, #2fa4d8, #2ec4b6); color: #fff; border-radius: 16px; padding: 4px 4px 4px 12px; box-shadow: 0 4px 14px rgba(10, 40, 60, 0.3); font-weight: 600; font-size: 15px; }
#rental #b-rental-x { border: 0; color: #fff; font: inherit; background: rgba(255, 255, 255, 0.25); width: 30px; height: 30px; border-radius: 50%; padding: 0; cursor: pointer; }
/* (a treat or a balloon you're holding: ✕ puts it down, or lets it fly: 🐞 #74) */
#held { display: flex; align-items: center; gap: 8px; background: linear-gradient(135deg, #ff8fb0, #ffb347); color: #fff; border-radius: 16px; padding: 4px 4px 4px 12px; box-shadow: 0 4px 14px rgba(60, 20, 30, 0.3); font-weight: 600; font-size: 15px; }
#held #b-held-x { border: 0; color: #fff; font: inherit; background: rgba(255, 255, 255, 0.25); width: 30px; height: 30px; border-radius: 50%; padding: 0; cursor: pointer; }
#nowplaying button { border: 0; background: none; color: #fff; font: inherit; font-size: 15px; padding: 4px 6px; max-width: 280px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#nowplaying #b-np-x, #radio #b-radio-x { background: rgba(255, 255, 255, 0.25); width: 30px; height: 30px; border-radius: 50%; padding: 0; flex: none; }
#np-text { animation: np-bop 0.6s ease-in-out infinite alternate; display: inline-block; }
@keyframes np-bop { to { transform: translateY(-2px); } }
#radio { flex-wrap: wrap; padding: 8px 8px 8px 12px; background: linear-gradient(135deg, #1d1638, #3b2a7a); border: 2px solid #ff5d8f; font-size: 15px; }
#radio-text { flex: 1 1 200px; }
#radio .btns { display: flex; gap: 6px; }
#radio button { border: 0; border-radius: 12px; background: #fff; color: var(--ink); font: inherit; font-size: 14px; padding: 6px 10px; }
#radio button.on { background: #00f5d4; }
@media (max-width: 480px) { #tunes-ui { top: calc(max(8px, env(safe-area-inset-top)) + 236px); } } /* (under the place name, the arrow and Follow) */
@media (max-height: 430px) { #tunes-ui { top: 56px; } #radio { font-size: 13px; padding: 5px 6px 5px 10px; } }
/* (chips.js: a few seconds after they change, the chips fold down to their icon; a tap opens one again. Wes: "I don't
   like text crowding regular game play.") */
.chip-icon { display: none; font-size: 20px; line-height: 1; }
#held.folded, #rental.folded, #nowplaying.folded, #radio.folded, #follow.folded { padding: 0; gap: 0; cursor: pointer; opacity: 0.85; width: 42px; height: 42px; border-radius: 50%; justify-content: center; }
:is(#held, #rental, #nowplaying, #radio, #follow).folded > :not(.chip-icon) { display: none; }
:is(#held, #rental, #nowplaying, #radio, #follow).folded > .chip-icon { display: block; }
#moves { position: fixed; left: 50%; bottom: max(18px, calc(env(safe-area-inset-bottom) + 10px)); translate: -50% 0; z-index: 5; display: flex; gap: 6px; padding: 6px; background: rgba(29, 22, 56, 0.82); border-radius: 18px; max-width: calc(100vw - 260px); overflow-x: auto; scrollbar-width: none; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3); }
#moves[hidden] { display: none; }
#moves button { flex: none; border: 0; border-radius: 13px; background: rgba(255, 255, 255, 0.14); color: #fff; display: grid; justify-items: center; padding: 4px 8px; min-width: 58px; font: inherit; }
#moves button span { font-size: 24px; line-height: 1.1; } #moves button b { font-size: 11px; font-weight: 600; white-space: nowrap; }
#moves button.on { background: #fff; color: var(--ink); box-shadow: 0 0 0 3px #ff5d8f; }
/* (a phone held upright: the row of moves sits left of the round buttons and scrolls sideways; across the whole width its
   right end, Side step and on, was under "Stop dancing", 2026-10-24) */
@media (max-width: 600px) { #moves { left: 10px; translate: none; max-width: calc(100vw - 122px); bottom: calc(max(18px, env(safe-area-inset-bottom)) + 150px); }
  body:has(#moves:not([hidden])) #toast { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 222px); } } /* (and messages go above the row, not on it) */
/* (an iPad held upright: the row of moves goes up above the joystick and the round buttons, and messages above it; down
   at the bottom its right end was under Stop dancing, 2026-10-24) */
@media (min-width: 601px) and (max-width: 1000px) and (min-height: 900px) {
  #moves { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 168px); max-width: calc(100vw - 2 * (max(18px, env(safe-area-inset-right)) + 106px)); }
  body:has(#moves:not([hidden])) #toast { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 248px); }
}
.tunes { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; margin-top: 8px; }
.tunes button { display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto auto; column-gap: 8px; align-items: center; text-align: left; border: 2px solid #e3eaf0; background: #fff; border-radius: 16px; padding: 8px 10px; color: var(--ink); font: inherit; }
.tunes button .e { grid-row: 1 / 3; font-size: 30px; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: linear-gradient(135deg, var(--c1, #7b5cff), var(--c2, #ff5d8f)); }
.tunes button b { font-size: 16px; } .tunes button small { color: #5b6b7a; font-size: 13px; }
.tunes button.on { border-color: #ff5d8f; background: #fff0f5; box-shadow: 0 0 0 2px #ff5d8f; }
@media (max-height: 450px) and (min-width: 601px) { #moves { max-width: calc(100vw - 440px); bottom: 10px; } #moves button { min-width: 44px; padding: 4px 6px; } #moves button b { display: none; } }

/* ---------- the Dance-off (danceoff.js): four lanes of moves sliding down to the circles ---------- */
body.danceoff #controls, body.danceoff #moves, body.danceoff #keys-hint, body.danceoff #where { display: none !important; }
body:has(#panel:not(.hidden)) #tunes-ui { visibility: hidden; }
#moves button.off { background: linear-gradient(135deg, #ffd166, #ff8c42); color: var(--ink); }
#danceoff { position: fixed; right: max(14px, env(safe-area-inset-right)); top: calc(max(8px, env(safe-area-inset-top)) + 78px); bottom: max(14px, env(safe-area-inset-bottom)); width: min(400px, 46vw); z-index: 5;
  display: flex; flex-direction: column; gap: 8px; background: rgba(26, 16, 64, 0.78); border: 3px solid #ff5d8f; border-radius: 24px; padding: 10px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); color: #fff; }
#danceoff[hidden] { display: none; }
.do-top { display: flex; align-items: center; gap: 10px; }
#do-score { font-size: 28px; font-weight: 700; min-width: 70px; }
#do-combo { flex: 1; font-size: 16px; font-weight: 600; color: #ffd166; }
#do-x { border: 0; background: rgba(255, 255, 255, 0.2); color: #fff; width: 36px; height: 36px; border-radius: 50%; font: inherit; font-size: 16px; padding: 0; }
.do-field { position: relative; flex: 1; overflow: hidden; border-radius: 16px; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.06) 0 25%, rgba(255, 255, 255, 0.02) 25% 50%); }
.do-line { position: absolute; left: 0; right: 0; bottom: 22px; height: 48px; background: rgba(255, 255, 255, 0.12); border-top: 2px solid rgba(255, 255, 255, 0.5); border-bottom: 2px solid rgba(255, 255, 255, 0.5); }
#do-cues i { position: absolute; top: 0; width: 48px; height: 48px; margin-left: 0; display: grid; place-items: center; font-style: normal; font-size: 28px; border-radius: 50%;
  background: hsl(var(--h) 85% 58%); box-shadow: 0 0 12px hsl(var(--h) 90% 60%), inset 0 -4px 0 rgba(0, 0, 0, 0.2); will-change: transform; }
#do-cues i.hit { animation: do-hit 0.35s ease-out forwards; }
#do-cues i.miss { filter: grayscale(1); opacity: 0.4; }
@keyframes do-hit { to { scale: 1.8; opacity: 0; } }
.do-judge { position: absolute; left: 0; right: 0; top: 38%; text-align: center; font-size: 30px; font-weight: 700; pointer-events: none; opacity: 0; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); }
.do-judge.pop { animation: do-pop 0.6s ease-out; }
.do-judge.perfect { color: #ffd166; } .do-judge.great { color: #7dffb0; } .do-judge.good { color: #7fd6ff; } .do-judge.miss { color: #ff8fa3; }
@keyframes do-pop { 0% { opacity: 0; scale: 0.6; } 20% { opacity: 1; scale: 1.15; } 100% { opacity: 0; scale: 1; } }
.do-count { position: absolute; left: 0; right: 0; top: 20%; text-align: center; font-size: 64px; font-weight: 700; color: #fff; pointer-events: none; text-shadow: 0 3px 10px rgba(0, 0, 0, 0.5); }
.do-count.pop { animation: do-pop 0.9s ease-out forwards; }
.do-pads { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.do-pads button { border: 0; border-radius: 16px; padding: 8px 2px; font: inherit; color: #fff; background: hsl(var(--h) 80% 50%); box-shadow: 0 4px 0 hsl(var(--h) 70% 32%); display: grid; justify-items: center; touch-action: none; user-select: none; -webkit-user-select: none; }
.do-pads button span { font-size: 30px; line-height: 1.1; } .do-pads button b { font-size: 12px; font-weight: 600; white-space: nowrap; }
.do-pads button.down { translate: 0 3px; box-shadow: 0 1px 0 hsl(var(--h) 70% 32%); filter: brightness(1.25); }
@media (max-width: 600px) { #danceoff { left: 10px; right: 10px; width: auto; top: 44vh; } #do-cues i { width: 42px; height: 42px; font-size: 24px; } }
@media (max-height: 450px) { #danceoff { top: 10px; width: min(360px, 44vw); } .do-pads button b { display: none; } #do-score { font-size: 22px; } }
.do-result { text-align: center; }
.do-result .stars { font-size: 52px; letter-spacing: 6px; } .do-result .stars .dim { filter: grayscale(1); opacity: 0.3; }
.do-result .big { font-size: 26px; font-weight: 700; margin: 4px 0; } .do-result .prize { font-size: 19px; font-weight: 700; color: #1d8a4a; }
.do-result .badge { background: #ff5d8f; color: #fff; border-radius: 10px; padding: 2px 8px; font-size: 14px; vertical-align: middle; }

/* Dylan's event page (his drawing): big bubbly title, TASKS, PRIZES */
.ev-page { background: linear-gradient(160deg, #fff4e6, #f6eaff); border-radius: 18px; padding: 12px 14px 4px; margin-bottom: 14px; box-shadow: inset 0 0 0 3px #ff8a1a; }
.ev-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ev-title { margin: 0; font-size: clamp(30px, 7vw, 44px); font-weight: 700; letter-spacing: 1px; color: #ff8a1a; -webkit-text-stroke: 2px #4a2408; paint-order: stroke fill; line-height: 1; }
.ev-title span { -webkit-text-stroke: 0; }
.ev-sub { margin: 0 0 0 6px; font-size: 26px; font-style: italic; color: #4a2408; border-bottom: 2px solid #4a2408; display: inline-block; padding: 0 18px 2px 4px; }
.ev-points { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 4px 10px; margin: 10px 0 4px; }
.ev-points .muted { grid-column: 1 / -1; font-size: 13.5px; }
.ev-page .bar { display: inline-block; height: 8px; border-radius: 99px; background: #ead8c4; overflow: hidden; width: 90px; vertical-align: middle; margin-right: 6px; }
.ev-page .bar.big { width: auto; height: 14px; }
.ev-page .bar i { display: block; height: 100%; background: linear-gradient(90deg, #ff8a1a, #9b5de5); border-radius: 99px; }
.ev-h { margin: 14px 0 6px; font-size: 26px; letter-spacing: 3px; color: #2b2160; }
.ev-tasks { list-style: none; margin: 0; padding: 6px 8px; border: 2.5px solid #4a2408; border-radius: 22px 16px 26px 14px; background: #fffaf3; }
.ev-tasks li { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-bottom: 1px dashed #e6d2bd; }
.ev-tasks li:last-child { border-bottom: 0; }
.ev-tasks .te { font-size: 26px; width: 32px; text-align: center; }
.ev-tasks .tt { flex: 1; min-width: 0; } .ev-tasks .tt b { display: block; font-size: 15.5px; }
.ev-tasks .tp { font-weight: 700; color: #c4560a; text-align: right; white-space: nowrap; } .ev-tasks .tp small { display: block; font-weight: 500; color: #8a7a6a; font-size: 11.5px; }
.ev-tasks li.done { opacity: 0.6; } .ev-tasks li.done b { text-decoration: line-through; }
.ev-prizes { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 10px; padding: 10px; border: 2.5px solid #4a2408; border-radius: 16px 24px 14px 26px; background: #fffaf3; }
.prize { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.prize .pp { width: 96px; height: 96px; border: 2.5px solid #4a2408; border-radius: 10px; background: #fff; display: grid; place-items: center; overflow: hidden; }
.prize .pp img { width: 100%; height: 100%; object-fit: cover; } .prize .pe { font-size: 50px; white-space: nowrap; } .prize .pe.two { font-size: 38px; }
.prize b { font-size: 14.5px; } .prize .ps { font-size: 13px; color: #6a5a4a; }
.prize.locked .pp { filter: saturate(0.55); } .prize.soon { opacity: 0.55; }
.prize.ready .pp { box-shadow: 0 0 0 4px #ffd166, 0 0 18px #ffb04a; }
.prize.claimed .pp { box-shadow: 0 0 0 3px #2ecc71; }
.cat-pumpkin { flex: none; }

/* the weather forecast on the Calendar (weather.js) */
.forecast { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; background: #eef6ff; border-radius: 14px; padding: 8px 12px; margin: 4px 0 8px; }
.forecast b { margin-right: 6px; } .forecast span { display: flex; flex-direction: column; align-items: center; min-width: 46px; font-size: 12px; color: #4a5a7a; }
.forecast i { font-style: normal; font-size: 24px; }
/* the Weather Book (weather-book.js): a stamp for each weather and rare moment you've seen */
.wx-book { background: #f3f0ff; border-radius: 14px; padding: 8px 12px; margin: 0 0 8px; } .wx-book small { color: #6a5a9a; font-weight: 600; margin-left: 6px; }
.wx-stamps { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 6px; margin-top: 6px; }
.wx-stamps button { font-size: 22px; aspect-ratio: 1; border-radius: 10px; border: 2px dashed #c9bfe6; background: #fff; padding: 0; opacity: 0.55; }
.wx-stamps button.got { border: 2px solid #8a6fd6; opacity: 1; } .wx-how { font-size: 13px; color: #4a5a7a; margin: 6px 0 0; }
.try-wx { background: #fff4e0; } .try-wx button { font: inherit; font-size: 24px; min-width: 44px; min-height: 44px; border: 0; border-radius: 12px; background: #fff; cursor: pointer; } .try-wx .wx-back { font-size: 14px; padding: 0 10px; }

/* the Dive Center (diving.js): the dive list, and Open up! glowing at the right moment */
.dives { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.dive-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 6px 8px; border-radius: 12px; background: rgba(27, 95, 174, 0.07); }
.dive-row .dn { flex: 1 1 200px; } .dive-row .dp { display: flex; gap: 6px; flex-wrap: wrap; }
.dive-row .chip[disabled] { opacity: 0.35; }
.act.now { background: radial-gradient(circle at 35% 30%, #d9ffe6, #19b85a); box-shadow: 0 0 0 5px #fff, 0 0 26px #2ecc71; animation: cruise-pulse 0.5s ease-in-out infinite; }
/* a dive's timing ring (diving.js action fill 0–1): fills up round the button, full at the right moment; "Too late!" orange */
.act.fill::after { content: ''; position: absolute; inset: -9px; border-radius: 50%; pointer-events: none; background: conic-gradient(#ffd166 calc(var(--fill, 0) * 1turn), rgba(255, 255, 255, 0.28) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 8px), #000 calc(100% - 7px)); mask: radial-gradient(farthest-side, transparent calc(100% - 8px), #000 calc(100% - 7px)); }
.act.late { background: radial-gradient(circle at 35% 30%, #ffd9a8, #e6702a); }
.act.hold { animation: cruise-pulse 0.6s ease-in-out infinite; }

/* on a computer: the key for each button, in a little corner badge (Dylan: yes; the play-test's laptop players had to
   guess E, M, 1-4...). Touch screens don't show them. */
kbd.key { display: none; }
@media (hover: hover) and (pointer: fine) {
  kbd.key { display: block; position: absolute; top: -4px; right: -4px; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 7px;
    background: #2b2160; color: #fff; font: 700 13px/22px Fredoka, sans-serif; text-align: center; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.3); pointer-events: none; }
  .do-pads button { position: relative; }
  #bar button kbd.key { top: 0; right: 2px; min-width: 17px; height: 17px; line-height: 17px; font-size: 11px; border-radius: 5px; }
}

/* 📸 Pose (Dylan: yes): the camera turns round to your face, and everything else steps aside for a picture */
body.pose #bar, body.pose #controls, body.pose #where, body.pose #guide, body.pose #follow, body.pose #tags, body.pose #nowplaying, body.pose #rental, body.pose #held,
body.pose #radio, body.pose #keys-hint, body.pose #b-leave, body.pose #b-sound { visibility: hidden; }
body.pose #b-pose { background: #ff5d8f; color: #fff; }
body:has(#talk:not(.hidden)) #toast { bottom: auto; top: calc(max(8px, env(safe-area-inset-top)) + 110px); } /* (above the Mayor's talk box, not under it) */
body.pose #toast { bottom: auto; top: calc(max(8px, env(safe-area-inset-top)) + 70px); } /* (not over your face) */
body:has(#place:not(.hidden)) #toast { bottom: auto; top: calc(max(8px, env(safe-area-inset-top)) + 70px); } /* (placing furniture: not over the piece you're moving; on a phone held sideways it sat mid-screen) */
@media (max-width: 480px) { body:has(#place:not(.hidden)) #toast { top: calc(max(8px, env(safe-area-inset-top)) + 114px); } } /* (an upright phone: under the icon bar, not on it) */
body.diving #toast { bottom: auto; top: calc(max(8px, env(safe-area-inset-top)) + 110px); } /* (diving: not over the 🙌 button or the water you're aiming at) */
/* the judges' cards after a dive (diving.js flatCards): three big white cards across the middle, for a moment */
#dive-cards { position: fixed; left: 50%; top: 34%; translate: -50% 0; z-index: 7; display: flex; gap: 14px; pointer-events: none; opacity: 0; scale: 0.8; transition: opacity 0.2s, scale 0.2s; }
#dive-cards.on { opacity: 1; scale: 1; }
#dive-cards b { display: grid; place-items: center; width: 92px; height: 70px; background: #fff; color: #1b5fae; border: 5px solid #1b5fae; border-radius: 10px; font-size: 40px; font-weight: 800; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35); }
@media (max-width: 500px) { #dive-cards b { width: 74px; height: 58px; font-size: 32px; } }
/* (a short screen, like a phone held sideways: the cards go to the bottom middle, between the joystick and the buttons;
   a third of the way down they covered the score message up top, "RIP! ... = 60.90", 2026-10-24) */
@media (max-height: 500px) { #dive-cards { top: auto; bottom: max(16px, env(safe-area-inset-bottom)); } }
/* (a phone held upright: the tube's 👍 Faster / 👎 Slower / 🤪 Wild ride! go up above the round buttons; at 92 px from the
   bottom they were on top of Jump, the action button and the joystick, 2026-10-24. !important: boat.js sets its place) */
@media (max-width: 480px) and (min-height: 600px) { #tow-signals { bottom: calc(max(26px, env(safe-area-inset-bottom)) + 290px) !important; } }

/* ---- warming up on the first visit (game.js, warmup.js): hopping paws and a gentle bar ---- */
#warm { position: fixed; inset: 0; z-index: 2147482000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: radial-gradient(circle at 50% 40%, #bfe6ff, #7cc56a 85%); color: #2b2160; font-weight: 700; font-size: 22px; transition: opacity 0.4s; }
#warm[hidden] { display: none; }
#warm.off { opacity: 0; pointer-events: none; }
#warm p { margin: 0; text-shadow: 0 2px 0 rgba(255, 255, 255, 0.6); }
.warm-paws { font-size: 36px; } .warm-paws i { display: inline-block; font-style: normal; margin: 0 8px; animation: warm-hop 0.9s ease-in-out infinite; }
.warm-paws i:nth-child(2) { animation-delay: 0.15s; } .warm-paws i:nth-child(3) { animation-delay: 0.3s; }
@keyframes warm-hop { 0%, 100% { transform: translateY(0); } 40% { transform: translateY(-14px); } }
.warm-track { width: min(240px, 60vw); height: 10px; border-radius: 99px; background: rgba(255, 255, 255, 0.55); overflow: hidden; }
#warm-bar { display: block; height: 100%; width: 0; border-radius: 99px; background: #ffd166; transition: width 0.3s; }
@media (prefers-reduced-motion: reduce) { .warm-paws i { animation: none; } #warm-bar { transition: none; } }
/* (the 3rd time in 10 minutes the graphics are taken away: a break and a button, not another restart by itself; game.js needBreak) */
#town-rest { position: fixed; inset: 0; z-index: 2147482001; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  background: radial-gradient(circle at 50% 40%, #bfe6ff, #7cc56a 85%); color: #2b2160; font-weight: 700; font-size: 24px; text-align: center; padding: 16px; }
#town-rest[hidden] { display: none; }
#town-rest p { margin: 0; text-shadow: 0 2px 0 rgba(255, 255, 255, 0.6); }
#town-rest-go { font: inherit; font-size: 22px; color: #2b2160; background: #ffd166; border: 4px solid #2b2160; border-radius: 18px; padding: 12px 26px; cursor: pointer; box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25); }
#town-rest-go:active { transform: scale(0.96); }
/* Paw Square's game tables (gametable.js): the board in the panel, 8 × 8, light and dark squares; the piece you picked,
   the squares it can go to (a dot), the last move (a tint) */
.gt-board { display: grid; grid-template-columns: repeat(8, 1fr); width: min(100%, 400px); aspect-ratio: 1; margin: 6px auto; border: 4px solid #5a3a22; border-radius: 8px; overflow: hidden; touch-action: manipulation; }
.gt-sq { border: 0; padding: 0; margin: 0; position: relative; display: grid; place-items: center; aspect-ratio: 1; background: #d23a3a; }
.gt-sq.dark { background: #2f3542; } .gt-board.chess .gt-sq { background: #e8d4a8; } .gt-board.chess .gt-sq.dark { background: #a8794f; }
.gt-sq.last { box-shadow: inset 0 0 0 100px rgba(255, 209, 102, 0.35); }
.gt-sq.can { box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.55); }
.gt-sq.sel { box-shadow: inset 0 0 0 4px #ffd166; }
.gt-sq.to::after { content: ''; position: absolute; width: 30%; height: 30%; border-radius: 50%; background: rgba(255, 209, 102, 0.85); }
.gt-disc { width: 76%; height: 76%; border-radius: 50%; display: grid; place-items: center; font-size: 18px; color: #ffd166; box-shadow: inset 0 -4px 0 rgba(0, 0, 0, 0.3), 0 2px 3px rgba(0, 0, 0, 0.35); }
.gt-disc.r { background: #e63946; border: 2px solid #ff8a8a; } .gt-disc.b { background: #1e1e24; border: 2px solid #55555f; }
.gt-chess { font-size: clamp(22px, 8.5vw, 40px); line-height: 1; font-family: "Apple Symbols", "Segoe UI Symbol", "DejaVu Sans", serif; }
.gt-chess.w { color: #fffaf0; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 1px 0 #000; } .gt-chess.b { color: #1e1a18; text-shadow: 0 0 2px #fff8; }
.gt-status { text-align: center; font-weight: 700; min-height: 1.3em; margin: 4px 0; }
.gt-levels { justify-content: center; display: flex; gap: 6px; }
.gt-levels .chip { border: 2px solid #e3eaf0; background: #fff; border-radius: 999px; padding: 6px 14px; font: inherit; font-weight: 700; color: var(--ink); }
.gt-levels .chip.on { box-shadow: inset 0 0 0 3px var(--pink); background: #fff0f5; }
.book-card { background: #fffaf0; border: 2px solid #e8dcc8; border-radius: 14px; padding: 8px 14px; margin: 6px 0; } .book-card h3 { margin: 2px 0 4px; }
/* a friend asking you to play at Paw Square's game tables (gametable.js): a card at the bottom, Play! or No thanks */
.gt-ask { position: fixed; left: 50%; bottom: max(28px, calc(env(safe-area-inset-bottom) + 18px)); transform: translateX(-50%); z-index: 60; background: #fff; border-radius: 22px; padding: 16px 20px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3); text-align: center; width: min(92vw, 460px); font-family: Fredoka, system-ui, sans-serif; }
.gt-ask .q { font-size: 22px; font-weight: 700; margin-bottom: 12px; line-height: 1.25; color: var(--ink); }
.gt-ask .row { display: flex; gap: 12px; justify-content: center; }
.gt-ask button { font: 700 20px Fredoka, system-ui, sans-serif; border: 0; border-radius: 999px; padding: 12px 22px; min-width: 120px; color: #fff; touch-action: manipulation; }
.gt-ask .yes { background: #2e9e4f; } .gt-ask .no { background: #8a8fa0; }
.gt-levels .chip.friend { background: #eaf7ef; border-color: #b9e3c7; }
/* the corner shops (corner.js): "The usual!" at the top of the menu, and today's special in the grid */
#panel .btn.usual { display: block; width: 100%; margin: 4px 0 6px; font-size: 18px; background: #2e9e4f; color: #fff; }
.f-grid button.special { border-color: #ffd166; background: #fffaeb; box-shadow: inset 0 0 0 2px #ffd166; }

/* ---- "Where to?" (start.js): the cards you start from, shown while the town loads behind them ---- */
#start { position: fixed; inset: 0; z-index: 2147482500; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(10px, 2.2vh, 22px); padding: 16px 16px clamp(70px, 17vh, 130px); box-sizing: border-box; color: #2b2160; font-weight: 700;
  background: linear-gradient(#a9dcff, #def3ff 62%, #c9ecb8); transition: opacity 0.45s; }
#start.off { opacity: 0; pointer-events: none; }
#start h1 { margin: 0; font-size: clamp(28px, 5vw, 46px); text-shadow: 0 3px 0 rgba(255, 255, 255, 0.7); }
#start .st-home { position: absolute; top: max(10px, env(safe-area-inset-top)); left: max(10px, env(safe-area-inset-left)); display: grid; place-items: center; text-decoration: none; }
.st-cards { display: flex; justify-content: center; gap: clamp(10px, 2vw, 24px); width: min(980px, 100%); }
.st-card { position: relative; flex: 1 1 0; min-width: 0; max-width: 330px; display: flex; flex-direction: column; gap: 8px; padding: 8px 8px 12px; border: 0; border-radius: 22px;
  background: #fff; color: #2b2160; font: inherit; box-shadow: 0 6px 0 rgba(43, 33, 96, 0.16), 0 12px 26px rgba(20, 40, 80, 0.16); cursor: pointer;
  animation: st-pop 0.45s cubic-bezier(.3, 1.4, .5, 1) calc(var(--i) * 90ms) both; transition: transform 0.2s, opacity 0.3s; }
.st-card:active { transform: scale(0.96); }
.st-card b { font-size: clamp(20px, 3vw, 28px); } .st-card b i { font-style: normal; }
.st-pic { display: block; aspect-ratio: 4 / 3; border-radius: 16px; background: var(--pic) center / cover no-repeat, var(--sky); }
.st-town { --pic: url('icons/start-town.jpg'); --sky: linear-gradient(#bfe6ff, #9bd77f); }
.st-beach { --pic: url('icons/start-beach.jpg'); --sky: linear-gradient(#bfe6ff, #ffe3a3); }
.st-mountain { --pic: url('icons/start-mountain.jpg'); --sky: linear-gradient(#cfe3ff, #f4f8ff); }
/* (the one you picked last time glows; the glow is its own layer so only its opacity moves) */
.st-card.glow::after, .st-card.on::after { content: ''; position: absolute; inset: -6px; border-radius: 27px; pointer-events: none;
  box-shadow: 0 0 0 5px #ffd166, 0 0 26px 8px rgba(255, 209, 102, 0.85); animation: st-glow 1.5s ease-in-out infinite alternate; }
/* a place that isn't open yet (the 🏔️ Mountain): gray, "Coming soon", and a little shake if you tap it */
.st-card.soon { cursor: default; background: #eef0f4; color: #7a7f8f; box-shadow: 0 6px 0 rgba(43, 33, 96, 0.1); }
.st-card.soon .st-pic { filter: grayscale(1) brightness(1.06) contrast(0.85); opacity: 0.65; }
.st-card.soon:active { transform: none; }
.st-soon { position: absolute; top: 16px; right: -6px; padding: 4px 12px; border-radius: 10px 4px 4px 10px; background: #ffd166; color: #2b2160; font-size: clamp(14px, 1.8vw, 18px);
  box-shadow: 0 3px 0 rgba(43, 33, 96, 0.2); transform: rotate(4deg); }
.st-card.nope { animation: st-nope 0.45s ease-in-out; }
@keyframes st-nope { 20% { transform: translateX(-7px) rotate(-1.5deg); } 45% { transform: translateX(6px) rotate(1deg); } 70% { transform: translateX(-3px); } }
#start.picked .st-card { pointer-events: none; } #start.picked .st-card:not(.on) { opacity: 0.4; transform: scale(0.95); }
#start.picked .st-card.glow:not(.on)::after { display: none; } #start.picked .st-card.on::after { animation: none; }
.st-wait { display: flex; flex-direction: column; align-items: center; gap: 8px; min-height: 52px; opacity: 0; transition: opacity 0.3s; }
#start.picked .st-wait { opacity: 1; } .st-msg { font-size: 21px; text-shadow: 0 2px 0 rgba(255, 255, 255, 0.7); }
.st-bar { display: block; height: 100%; width: 0; border-radius: 99px; background: #ffd166; transition: width 0.3s; }
@keyframes st-pop { from { opacity: 0; transform: translateY(18px) scale(0.94); } }
@keyframes st-glow { from { opacity: 0.5; } to { opacity: 1; } }
/* phones held upright: the cards one above the other, the picture beside the name */
@media (max-width: 600px) and (orientation: portrait) {
  .st-cards { flex-direction: column; align-items: center; }
  .st-card { flex: none; width: 100%; max-width: 420px; flex-direction: row; align-items: center; gap: 14px; padding: 8px; }
  .st-pic { width: 46%; aspect-ratio: 16 / 10; }
}
/* short screens (a phone on its side) */
@media (max-height: 460px) { #start { padding-bottom: 64px; gap: 8px; } #start h1 { font-size: 26px; } .st-card { max-width: 230px; padding: 6px 6px 8px; } .st-pic { aspect-ratio: 16 / 10; } .st-card b { font-size: 19px; } }

/* the animal scenes along the hill (start-animals.js): one at a time, each its own length (--T), times in parts of it */
.st-hill { position: absolute; left: 0; right: 0; bottom: 0; height: clamp(64px, 16vh, 124px); pointer-events: none; }
.st-ground { position: absolute; inset: 0; width: 100%; height: 100%; } .st-ground path { fill: #86c96f; } .st-ground .far { fill: #a9dc8f; }
.st-hill svg { display: block; overflow: visible; }
.st-scenes { position: absolute; inset: 0; }
.ch-scene { display: none; position: absolute; inset: 0; }
.ch-scene.live { display: block; animation: ch-scene var(--T) linear infinite both; }
@keyframes ch-scene { 0% { opacity: 0; } 4%, 95% { opacity: 1; } 100% { opacity: 0; } }
/* the colors of the drawings: --c main, --d darker, --l light */
.st-hill .c { fill: var(--c); } .st-hill .d { fill: var(--d); } .st-hill .l { fill: var(--l); } .st-hill .k { fill: #2b2160; } .st-hill .w { fill: #fff; }
.st-hill .p { fill: #ff9fb2; } .st-hill .r { fill: #e63946; } .st-hill .o { fill: #ffa630; }
.st-hill .tl { fill: none; stroke: var(--c); stroke-width: 6; stroke-linecap: round; } .st-hill .tn { fill: none; stroke: var(--d); stroke-width: 1.8; stroke-linecap: round; }
.st-hill .sp { fill: none; stroke: var(--d); stroke-width: 3; stroke-linecap: round; } .st-hill .tf { fill: none; stroke: var(--l); stroke-width: 3; stroke-linecap: round; opacity: 0.6; }
.st-hill .wk { fill: none; stroke: #2b2160; stroke-width: 1; opacity: 0.45; } .st-hill .ey, .st-hill .an { fill: none; stroke: #2b2160; stroke-width: 1.4; stroke-linecap: round; }
.st-hill .hx { fill: none; stroke: var(--l); stroke-width: 2; stroke-linejoin: round; }
.st-hill .bn { fill: #fff8e7; } .st-hill .ac { fill: #c98a4a; } .st-hill .cp { fill: #7a4a24; }
.st-hill .yn { fill: #ff7aa2; } .st-hill .yl, .st-hill .ye { fill: none; stroke: #d94f7c; stroke-width: 1.8; stroke-linecap: round; } .st-hill .ye { stroke: #ff7aa2; stroke-width: 2.4; }
.st-hill .hb { fill: rgba(255, 255, 255, 0.3); stroke: rgba(255, 255, 255, 0.95); stroke-width: 3; } .st-hill .hv { stroke: rgba(160, 200, 230, 0.9); stroke-width: 2.4; stroke-linecap: round; }
.st-hill .hs { fill: none; stroke: #fff; stroke-width: 3.5; stroke-linecap: round; opacity: 0.85; }
.st-hill .stm { fill: none; stroke: #4f9a3c; stroke-width: 2.6; stroke-linecap: round; } .st-hill .lf { fill: #5fae47; }
.st-hill .pt { fill: var(--pt); } .st-hill .fc { fill: #ffd166; }
.st-hill .dt { fill: #a8774a; } .st-hill .ho { fill: #3d2a1c; } .st-hill .bu { fill: #5fae47; } .st-hill .bh { fill: #7fc865; }
.st-hill .pl { fill: #8a6d55; } .st-hill .fw { fill: #fff; } .st-hill .fk { fill: #2b2160; } .st-hill .rk { fill: #9aa0ab; } .st-hill .rh { fill: none; stroke: #c3c8d0; stroke-width: 2.4; stroke-linecap: round; }
.st-hill .sr { fill: #ffd166; stroke: #f4a62a; stroke-width: 1; stroke-linejoin: round; }
.p4-print svg { fill: rgba(96, 62, 36, 0.55); }
/* the pieces: an animal crossing (.ch-run), its ground shadow, its poses one over another, scenery (.ch-prop), a ? or ! */
.ch-run { position: absolute; left: 0; bottom: 34%; will-change: transform; animation: var(--T) linear infinite both; }
.ch-shadow { position: absolute; left: 14%; right: 14%; bottom: 0; height: 9px; border-radius: 50%; background: radial-gradient(closest-side, rgba(40, 80, 30, 0.34), transparent); }
.ch-flip { position: relative; }
.ch-pose + .ch-pose { position: absolute; left: 0; bottom: 0; }
.ch-pose { animation: var(--T) step-end infinite both; }
.ch-prop { position: absolute; bottom: 34%; }
.ch-say { position: absolute; left: 62%; bottom: 100%; width: 30px; height: 30px; border-radius: 50%; background: #fff; color: #2b2160; font-size: 22px; line-height: 30px; text-align: center;
  box-shadow: 0 2px 0 rgba(43, 33, 96, 0.18); transform-origin: 30% 100%; opacity: 0; animation: var(--T) linear infinite both; }
.ch-hop { animation: ch-hop 0.42s ease-in-out infinite; transform-origin: 50% 100%; } .ch-hop.quick { animation-duration: 0.2s; --up: -3px; } .ch-hop.none { animation: none; }
.ch-hop.bound { animation-duration: 0.36s; --up: -16px; } .ch-hop.digging { animation: ch-dig 0.16s ease-in-out infinite alternate; }
.ch-hop.waddle { animation: ch-waddle 0.46s ease-in-out infinite alternate; } .ch-hop.waddle.quick { animation-duration: 0.26s; }
@keyframes ch-hop { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(var(--up, -7px)); } }
@keyframes ch-dig { from { transform: rotate(14deg) translateY(2px); } to { transform: rotate(18deg) translateY(-2px); } }
@keyframes ch-waddle { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
.ch-leg { transform-box: fill-box; transform-origin: 50% 0; animation: ch-leg 0.21s ease-in-out infinite alternate; } .ch-leg.b { animation-delay: -0.21s; }
.frozen .ch-leg { animation: none; }
@keyframes ch-leg { from { transform: rotate(30deg); } to { transform: rotate(-30deg); } }
.ch-wag, .ch-tail { transform-box: fill-box; transform-origin: 0 100%; animation: ch-wag 0.28s ease-in-out infinite alternate; } .ch-tail { animation-duration: 0.6s; }
@keyframes ch-wag { from { transform: rotate(-14deg); } to { transform: rotate(14deg); } }
.ch-wing { transform-box: fill-box; transform-origin: 100% 50%; animation: ch-flap 0.16s ease-in-out infinite alternate; } .ch-wing.b { transform-origin: 0 50%; }
@keyframes ch-flap { to { transform: scaleX(0.25); } }
.ch-flutter { animation: ch-flutter 1.3s ease-in-out infinite alternate; }
@keyframes ch-flutter { from { transform: translateY(8px); } to { transform: translateY(-30px); } }
.ch-wave { transform-box: fill-box; transform-origin: 0 50%; animation: ch-wave 0.5s ease-in-out infinite alternate; }
@keyframes ch-wave { from { transform: skewY(-6deg) scaleX(0.92); } to { transform: skewY(5deg); } }

/* 1. a cat after a mouse: into its hole, the cat sits puzzled, turns back; the mouse peeks out behind it */
.m1-mouse { animation-name: m1-mouse; } .m1-mouse .ch-flip { animation: m1-mflip var(--T) step-end infinite; }
@keyframes m1-mouse { 0% { transform: translateX(-10vw); } 40% { transform: translateX(calc(74vw + 4px)); opacity: 1; } 43% { transform: translateX(calc(74vw + 8px)); opacity: 0; }
  84% { transform: translateX(calc(74vw + 6px)); opacity: 0; } 87% { opacity: 1; } 90%, 100% { transform: translateX(calc(74vw - 14px)); opacity: 1; } }
@keyframes m1-mflip { 0% { transform: none; } 84% { transform: scaleX(-1); } }
.m1-cat { animation-name: m1-cat; } .m1-cat .ch-flip { animation: m1-cflip var(--T) step-end infinite; }
@keyframes m1-cat { 0%, 5% { transform: translateX(-26vw); } 43% { transform: translateX(calc(74vw - 124px)); } 46%, 68% { transform: translateX(calc(74vw - 106px)); } 98%, 100% { transform: translateX(-26vw); } }
@keyframes m1-cflip { 0% { transform: none; } 68% { transform: scaleX(-1); } }
.m1-cat .run { animation-name: m1-run; } .m1-cat .sit { animation-name: m1-sit; }
@keyframes m1-run { 0% { opacity: 1; } 46% { opacity: 0; } 68% { opacity: 1; } }
@keyframes m1-sit { 0% { opacity: 0; } 46% { opacity: 1; } 68% { opacity: 0; } }
.m1-q { left: 48%; animation-name: m1-q; }
@keyframes m1-q { 0%, 49% { opacity: 0; transform: scale(0); } 52% { opacity: 1; transform: scale(1.2); } 54%, 65% { opacity: 1; transform: scale(1); } 68%, 100% { opacity: 0; transform: scale(0.5); } }

/* 2. a dog fetching a bone thrown in from the left: out, sniffs, picks it up, turns, trots back with it */
.f2-bone { animation-name: f2-bone; } .f2-bone .ch-shadow { display: none; } .f2-toss { animation: f2-toss var(--T) linear infinite both; }
@keyframes f2-bone { 0%, 5% { transform: translateX(-6vw); opacity: 0; } 6% { opacity: 1; } 22%, 50% { transform: translateX(58vw); opacity: 1; } 50.5%, 100% { transform: translateX(58vw); opacity: 0; } }
@keyframes f2-toss { 0%, 6% { transform: translateY(0) rotate(0); animation-timing-function: ease-out; } 14% { transform: translateY(-17vh) rotate(380deg); animation-timing-function: ease-in; }
  22% { transform: translateY(2px) rotate(720deg); animation-timing-function: ease-out; } 25% { transform: translateY(-12px) rotate(740deg); animation-timing-function: ease-in; } 28%, 100% { transform: translateY(2px) rotate(720deg); } }
.f2-dog { animation-name: f2-dog; } .f2-dog .ch-flip { animation: f2-flip var(--T) step-end infinite; }
@keyframes f2-dog { 0%, 10% { transform: translateX(-22vw); } 46%, 55% { transform: translateX(calc(58vw - 96px)); } 97%, 100% { transform: translateX(-24vw); } }
@keyframes f2-flip { 0% { transform: none; } 55% { transform: scaleX(-1); } }
.f2-dog .run { animation-name: f2-run; } .f2-dog .still { animation-name: f2-still; } .f2-dog .still .ch-hop { transform: rotate(9deg); transform-origin: 25% 100%; }
@keyframes f2-run { 0% { opacity: 1; } 46% { opacity: 0; } 55% { opacity: 1; } }
@keyframes f2-still { 0% { opacity: 0; } 46% { opacity: 1; } 55% { opacity: 0; } }
.f2-dog .carry { animation: f2-carry var(--T) step-end infinite; } @keyframes f2-carry { 0% { opacity: 0; } 50% { opacity: 1; } }

/* 3. a kitten sneaks up on a butterfly on a flower and pounces; it flutters off, the kitten sits and watches */
.b3-fly { animation-name: b3-fly; bottom: calc(34% + 34px); } .b3-fly .ch-shadow { display: none; }
@keyframes b3-fly { 0% { transform: translate(-6vw, 0); } 40%, 61% { transform: translate(calc(62vw - 6px), 0); } 100% { transform: translate(104vw, -32vh); } }
.b3-kit { animation-name: b3-kit; } .b3-kit .ch-flip { animation: b3-arc var(--T) linear infinite both; }
@keyframes b3-kit { 0%, 8% { transform: translateX(-16vw); } 52%, 59% { transform: translateX(calc(62vw - 132px)); } 67%, 100% { transform: translateX(calc(62vw - 52px)); } }
@keyframes b3-arc { 0%, 59% { transform: translateY(0) rotate(0); animation-timing-function: ease-out; } 63% { transform: translateY(-58px) rotate(-14deg); animation-timing-function: ease-in; } 67%, 100% { transform: translateY(0) rotate(0); } }
.b3-kit .sneak .ch-hop { transform: scaleY(0.86); } .b3-kit .sneak .ch-leg { animation-duration: 0.5s; } .b3-kit .sneak .ch-leg.b { animation-delay: -0.5s; }
.b3-kit .sneak { animation-name: b3-sneak; } .b3-kit .leap { animation-name: b3-leap; } .b3-kit .sit { animation-name: b3-sit; }
@keyframes b3-sneak { 0% { opacity: 1; } 59% { opacity: 0; } }
@keyframes b3-leap { 0% { opacity: 0; } 59% { opacity: 1; } 67% { opacity: 0; } }
@keyframes b3-sit { 0% { opacity: 0; } 67% { opacity: 1; } }

/* 4. paw prints stamp across the hill one by one, then a puppy follows them, nose down, and they fade as it passes */
.p4-print { position: absolute; bottom: 30%; opacity: 0; animation: p4-stamp var(--T) ease-out infinite both; animation-delay: calc(var(--k) * 0.3s); }
@keyframes p4-stamp { 0% { opacity: 0; transform: scale(1.7); } 3% { opacity: 1; transform: scale(1); } 46% { opacity: 1; transform: scale(1); } 60%, 100% { opacity: 0; transform: scale(1); } }
.p4-pup { animation-name: p4-pup; } .p4-pup .ch-hop { transform: rotate(8deg); transform-origin: 30% 100%; } .p4-pup .ch-leg { animation-duration: 0.3s; } .p4-pup .ch-leg.b { animation-delay: -0.3s; }
@keyframes p4-pup { 0%, 30% { transform: translateX(-16vw); } 96%, 100% { transform: translateX(106vw); } }

/* 5. a puppy chasing its own tail: round and round, then dizzy with stars, then off it trots */
.s5-pup { animation-name: s5-pup; } .s5-pup .ch-flip { animation: s5-spin var(--T) linear infinite both; }
@keyframes s5-pup { 0% { transform: translateX(-18vw); } 18%, 86% { transform: translateX(calc(46vw - 46px)); } 100% { transform: translateX(106vw); } }
@keyframes s5-spin { 0%, 20% { transform: scaleX(1); } 23% { transform: scaleX(-1); } 26% { transform: scaleX(1); } 29% { transform: scaleX(-1); } 32% { transform: scaleX(1); }
  35% { transform: scaleX(-1); } 38% { transform: scaleX(1); } 41% { transform: scaleX(-1); } 44% { transform: scaleX(1); } 47% { transform: scaleX(-1); } 50% { transform: scaleX(1); }
  53% { transform: scaleX(-1); } 56%, 100% { transform: scaleX(1); } }
.s5-pup .run { animation-name: s5-run; } .s5-pup .dizzy { animation-name: s5-dizzy; } .s5-pup .dizzy .ch-hop { animation: ch-waddle 0.55s ease-in-out infinite alternate; }
@keyframes s5-run { 0% { opacity: 1; } 57% { opacity: 0; } 86% { opacity: 1; } }
@keyframes s5-dizzy { 0% { opacity: 0; } 57% { opacity: 1; } 86% { opacity: 0; } }
.s5-stars { position: absolute; left: 62%; bottom: 82%; width: 40px; height: 16px; opacity: 0; animation: s5-stars var(--T) linear infinite both; }
@keyframes s5-stars { 0%, 58% { opacity: 0; } 61%, 84% { opacity: 1; } 87%, 100% { opacity: 0; } }
.s5-orbit { position: absolute; inset: 0; animation: s5-orbit 0.9s linear infinite; }
.s5-orbit svg { position: absolute; } .s5-orbit svg:nth-child(1) { left: 0; top: 4px; } .s5-orbit svg:nth-child(2) { left: 14px; top: -4px; } .s5-orbit svg:nth-child(3) { left: 28px; top: 4px; }
@keyframes s5-orbit { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* 6. the bunny and the turtle: the bunny zooms off and naps by a bush, the turtle plods past and wins at the flag */
.r6-bush { z-index: 1; } .r6-flag { margin-bottom: -2px; }
.r6-turtle { animation-name: r6-turtle; } .r6-turtle .ch-leg { animation-duration: 0.5s; } .r6-turtle .ch-leg.b { animation-delay: -0.5s; }
@keyframes r6-turtle { 0% { transform: translateX(-10vw); } 84%, 100% { transform: translateX(96vw); } }
.r6-bun { animation-name: r6-bun; }
@keyframes r6-bun { 0% { transform: translateX(-10vw); } 16%, 81% { transform: translateX(calc(58vw - 64px)); } 95%, 100% { transform: translateX(110vw); } }
.r6-bun .hop { animation-name: r6-hop; } .r6-bun .nap { animation-name: r6-nap; }
@keyframes r6-hop { 0% { opacity: 1; } 16% { opacity: 0; } 81% { opacity: 1; } }
@keyframes r6-nap { 0% { opacity: 0; } 16% { opacity: 1; } 81% { opacity: 0; } }
.r6-z { position: absolute; left: 70%; bottom: 52%; opacity: 0; animation: r6-zs var(--T) linear infinite both; }
@keyframes r6-zs { 0%, 20% { opacity: 0; } 24%, 74% { opacity: 1; } 78%, 100% { opacity: 0; } }
.r6-z i { position: absolute; left: 0; bottom: 0; font-style: normal; font-size: 16px; color: #5a4fa0; opacity: 0; animation: r6-z 2.1s ease-out infinite; }
.r6-z i:nth-child(2) { animation-delay: 0.7s; } .r6-z i:nth-child(3) { animation-delay: 1.4s; font-size: 20px; }
@keyframes r6-z { 0% { opacity: 0; transform: translate(0, 0) scale(0.6); } 20% { opacity: 1; } 100% { opacity: 0; transform: translate(18px, -40px) scale(1.1); } }
.r6-wake { animation-name: r6-wake; }
@keyframes r6-wake { 0%, 77% { opacity: 0; transform: scale(0); } 79% { opacity: 1; transform: scale(1.25); } 81%, 84% { opacity: 1; transform: scale(1); } 86%, 100% { opacity: 0; transform: scale(0.5); } }
.r6-win { position: absolute; left: calc(86vw + 6px); bottom: calc(34% + 50px); width: 40px; height: 30px; }
.r6-win svg { position: absolute; left: 10px; top: 10px; opacity: 0; animation: r6-win var(--T) ease-out infinite both; --to: translate(-22px, -18px); }
.r6-win svg:nth-child(2) { --to: translate(4px, -30px); } .r6-win svg:nth-child(3) { --to: translate(28px, -14px); }
@keyframes r6-win { 0%, 76% { opacity: 0; transform: translate(0, 0) scale(0.3); } 79% { opacity: 1; } 88% { opacity: 1; transform: var(--to) scale(1.1) rotate(90deg); } 92%, 100% { opacity: 0; transform: var(--to) scale(1.1) rotate(120deg); } }

/* 7. a kitten and a ball of yarn: the ball rolls in and stops, the kitten bats it on, twice, then chases it off */
.y7-ball { animation-name: y7-ball; } .y7-ball .ch-roll { animation: y7-roll var(--T) linear infinite both; }
@keyframes y7-ball { 0% { transform: translateX(-6vw); animation-timing-function: ease-out; } 20%, 30% { transform: translateX(36vw); animation-timing-function: ease-out; }
  42%, 57% { transform: translateX(66vw); animation-timing-function: ease-in; } 74%, 100% { transform: translateX(108vw); } }
@keyframes y7-roll { 0% { transform: rotate(0); animation-timing-function: ease-out; } 20%, 30% { transform: rotate(900deg); animation-timing-function: ease-out; }
  42%, 57% { transform: rotate(1500deg); animation-timing-function: ease-in; } 74%, 100% { transform: rotate(2400deg); } }
.y7-kit { animation-name: y7-kit; }
@keyframes y7-kit { 0%, 6% { transform: translateX(-20vw); } 27%, 31% { transform: translateX(calc(36vw - 80px)); } 53%, 58% { transform: translateX(calc(66vw - 80px)); } 92%, 100% { transform: translateX(106vw); } }
.y7-kit .run { animation-name: y7-run; } .y7-kit .bat { animation-name: y7-bat; } .y7-kit .bat .ch-hop { transform: rotate(-16deg); transform-origin: 20% 100%; }
@keyframes y7-run { 0% { opacity: 1; } 27% { opacity: 0; } 31% { opacity: 1; } 53% { opacity: 0; } 58% { opacity: 1; } }
@keyframes y7-bat { 0% { opacity: 0; } 27% { opacity: 1; } 31% { opacity: 0; } 53% { opacity: 1; } 58% { opacity: 0; } }

/* 8. a mother duck and her ducklings waddle across; the last one stops at a flower, then hurries after them */
.d8-duck, .d8-kid { animation-name: d8-walk; } .d8-kid { animation-delay: calc(var(--k) * 0.5s); }
@keyframes d8-walk { 0% { transform: translateX(-14vw); } 82%, 100% { transform: translateX(108vw); } }
.d8-late { animation-name: d8-late; }
@keyframes d8-late { 0%, 12% { transform: translateX(-14vw); } 38%, 56% { transform: translateX(calc(27vw - 40px)); } 92%, 100% { transform: translateX(108vw); } }

/* 9. a hamster in a rolling ball: bumps a rock, rolls back, tumbles, hops it and rolls on */
.h9-ball { animation-name: h9-ball; } .h9-ball .ch-flip { animation: h9-jump var(--T) linear infinite both; }
.h9-ball .ch-flip { width: 64px; height: 64px; } .h9-ball .ch-flip > div { position: absolute; inset: 0; }
.h9-ham svg { position: absolute; left: 12px; bottom: 6px; } .h9-ham { animation: h9-tumble var(--T) linear infinite both; } .h9-ham .ch-leg { animation-duration: 0.14s; }
@keyframes h9-ball { 0% { transform: translateX(-10vw); } 38% { transform: translateX(calc(52vw - 62px)); animation-timing-function: ease-out; } 43% { transform: translateX(calc(52vw - 96px)); }
  48% { transform: translateX(calc(52vw - 84px)); } 60% { transform: translateX(calc(52vw + 26px)); } 96%, 100% { transform: translateX(108vw); } }
@keyframes h9-roll { 0% { transform: rotate(0); } 38% { transform: rotate(940deg); } 43% { transform: rotate(860deg); } 48% { transform: rotate(890deg); } 60% { transform: rotate(1060deg); } 96%, 100% { transform: rotate(2100deg); } }
.h9-ball .ch-roll { animation: h9-roll var(--T) linear infinite both; }
@keyframes h9-tumble { 0%, 38% { transform: rotate(0); } 44%, 100% { transform: rotate(-360deg); } }
@keyframes h9-jump { 0%, 49% { transform: translateY(0); animation-timing-function: ease-out; } 54.5% { transform: translateY(-40px); animation-timing-function: ease-in; } 60% { transform: translateY(0); animation-timing-function: ease-out; }
  63% { transform: translateY(-8px); animation-timing-function: ease-in; } 66%, 100% { transform: translateY(0); } }

/* 10. a squirrel buries an acorn (dirt flying), scampers off, and a flower grows where it was */
.a10-sq { animation-name: a10-sq; }
@keyframes a10-sq { 0% { transform: translateX(-12vw); } 24%, 46% { transform: translateX(calc(48vw - 62px)); } 70%, 100% { transform: translateX(108vw); } }
.a10-sq .run { animation-name: a10-run; } .a10-sq .dig { animation-name: a10-dig; } .a10-sq .away { animation-name: a10-away; }
.a10-sq .dig .ch-hop { transform-origin: 70% 100%; }
@keyframes a10-run { 0% { opacity: 1; } 24% { opacity: 0; } }
@keyframes a10-dig { 0% { opacity: 0; } 24% { opacity: 1; } 46% { opacity: 0; } }
@keyframes a10-away { 0% { opacity: 0; } 46% { opacity: 1; } }
.a10-dirt { position: absolute; bottom: 34%; opacity: 0; animation: a10-dirt var(--T) linear infinite both; }
@keyframes a10-dirt { 0%, 26% { opacity: 0; } 27%, 43% { opacity: 1; } 44%, 100% { opacity: 0; } }
.a10-dirt i { position: absolute; left: 0; bottom: 0; width: 6px; height: 6px; border-radius: 50%; background: #8a5a32; animation: a10-clod 0.55s linear infinite; }
.a10-dirt i:nth-child(2) { animation-delay: -0.14s; } .a10-dirt i:nth-child(3) { animation-delay: -0.28s; width: 4px; height: 4px; } .a10-dirt i:nth-child(4) { animation-delay: -0.41s; }
@keyframes a10-clod { 0% { transform: translate(0, 0); opacity: 1; } 50% { transform: translate(calc(var(--dx) * 0.5), -26px); } 100% { transform: translate(var(--dx), 0); opacity: 0.3; } }
.a10-mound { transform-origin: 50% 100%; animation: a10-mound var(--T) ease-out infinite both; }
@keyframes a10-mound { 0%, 30% { transform: scale(0); } 44%, 100% { transform: scale(1); } }
.a10-grow { width: 30px; height: 84px; } .a10-grow > div { position: absolute; left: 0; }
.a10-stem { bottom: 2px; transform-origin: 50% 100%; animation: a10-stem var(--T) ease-out infinite both; }
@keyframes a10-stem { 0%, 70% { transform: scaleY(0); } 84%, 100% { transform: scaleY(1); } }
.a10-bloom { left: -1px !important; bottom: 42px; animation: a10-bloom var(--T) ease-out infinite both; }
@keyframes a10-bloom { 0%, 83% { transform: scale(0) rotate(-90deg); } 89% { transform: scale(1.25) rotate(10deg); } 92%, 100% { transform: scale(1) rotate(0); } }

/* short screens (a phone on its side): the animals smaller */
@media (max-height: 460px) { .ch-flip, .ch-prop, .p4-print, .r6-win, .a10-dirt { zoom: 0.72; } }
@media (prefers-reduced-motion: reduce) {
  .st-card, .st-card.glow::after { animation: none; }
  .ch-scene.live { animation: none; } .ch-scene .ch-run { display: none; } .p4-print { animation: none; opacity: 1; }
}
