/* Club Penguin public home. Shared tokens, buttons, header and footer: /site/shared/site.css. */
/* ------------------------------------------------------------------ hero: planes re-composed per layout mode */
.dive { position: relative; background: var(--sea-500); }
.stage { position: relative; }
.hero {
  position: relative; height: 100svh; min-height: 500px; overflow: hidden; container-type: size;
  --horizon: 58cqh; --shift: 0px;
  --hz: calc(var(--horizon) + var(--shift));   /* --shift (px): home.js moves the island down when the copy would cover its cast */
  --sky-top: #003C7E; --sky-a: #00529B; --sky-b: #015DA7; --sky-c: #0280CD;
  background: var(--sea-500);
}
.plane { position: absolute; inset: 0; pointer-events: none; }
.plane img { position: absolute; max-width: none; }

/* sky: the panorama's own gradient stops, extended upward for a tall viewport */
.sky { bottom: calc(100cqh - var(--hz) - 2px); background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-a) 30%, var(--sky-b) 70%, var(--sky-c) 100%); }
.stars { inset: 0 0 12% 0; width: 100%; height: 88%; object-fit: cover; opacity: 0; display: none; }
.starfield { position: absolute; inset: 0 0 18% 0; opacity: 0; background: url(/site/home/art/sky/night-stars.svg) 0 0 / 1200px auto repeat; -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent); }
.sun { position: absolute; inset: 0; opacity: 0; }

.clouds { transform: translate3d(calc(var(--mx, 0) * -6px), 0, 0); }
.cloud { bottom: calc(100cqh - var(--hz) - 2px); animation: drift 90s linear infinite alternate; }
.cloud--l { left: 4cqw; width: 30cqw; }
.cloud--r { right: -2cqw; width: 36cqw; animation-duration: 140s; animation-direction: alternate-reverse; }
@keyframes drift { from { translate: -2cqw 0; } to { translate: 2cqw 0; } }
.night-only { display: none; }

.sea { top: calc(var(--hz) - 3px); background: var(--sea-500); }
.sea__art { left: 50%; top: 0; width: 170cqw; translate: -50% 0; }

.ship { transform: translate3d(calc(var(--mx, 0) * -10px), 0, 0); }
/* the ship keeps to the island's scale (18.5% of its width) wherever the island is height-bound (short windows) */
.migrator { right: 2.5cqw; width: min(14cqw, calc(var(--d-w, 76cqw) * .185)); bottom: calc(100cqh - var(--hz) - 20cqh); animation: bob 6s var(--ease-bob) infinite; transform-origin: 50% 90%; }
@keyframes bob { 0%, 100% { transform: translateY(0) rotate(-1.2deg); } 50% { transform: translateY(-5px) rotate(1.2deg); } }
/* the Hydro Hopper art faces left (bow left, the tube towed behind it on the right), so it runs right to left, far out
   on the horizon lane: there it shows over the island's low middle instead of vanishing behind the whole island */
.hopper img { width: 10cqw; left: 12cqw; bottom: calc(100cqh - var(--hz) - 2.2cqh); animation: hop 26s linear -2s infinite; }
@keyframes hop { 0% { transform: translateX(100cqw); } 45%, 100% { transform: translateX(-40cqw); } }
/* where the copy comes down to the horizon (see data-lane below) its last line would hide the boat there: it runs a little
   nearer instead */
[data-lane^="climb"] .hopper img { bottom: calc(100cqh - var(--hz) - 4.5cqh); }

/* the diorama: island + cast share one box so they re-compose together */
.diorama {
  inset: auto; left: var(--d-left, 13cqw); top: calc(var(--d-top, 53cqh) + var(--shift)); width: var(--d-w, 76cqw); aspect-ratio: 997 / 495.9;
  transform: translate3d(calc(var(--mx, 0) * -14px), calc(var(--my, 0) * -4px), 0);
}
.island { inset: 0; width: 100%; height: 100%; }
/* Every cast member is anchored in the island art's own coordinate space: --fx/--fy is the point (in % of island.svg,
   997 x 495.9) where its feet touch flat snow; --w its width in % of the island; --ox/--oy where its feet are inside its own
   box (shares of its width/height); --ar its height/width. The diorama keeps the island's aspect ratio, so a width % turns
   into a height % by 997 / 495.9 = 2.0105. Left/top are plain offsets (no translate), so home.js can still measure them. */
.cast {
  position: absolute; --ox: .5; --oy: 1; --ar: 1;
  left: calc((var(--fx) - var(--w) * var(--ox)) * 1%);
  top: calc((var(--fy) - var(--w) * var(--ar) * var(--oy) * 2.0105) * 1%);
  width: calc(var(--w) * 1%);
}
.cast img, img.cast { height: auto; }   /* the intrinsic width/height attributes only reserve the aspect ratio */
.cast img { position: static; width: 100%; }
/* The anchors sit high on the flat snow (just below the mountain's foot, 53-58% down the art), so the feet stay on screen
   on short windows too, where the island's lower half is below the fold; the two away from the pair also keep out of the
   bottom-centre "Dive in" cue and the bottom-left badge (home.js moves the scene up when a foot would still meet one). */
/* the foot of the ski hill (they are going sledding) */
.cast--pair { --fx: 22; --fy: 55; --w: 24.2; --ox: .35; --oy: .965; --ar: .9373; animation: bob2 3.2s var(--ease-bob) infinite; }
/* The pair's raster carries a baked, broken bubble (its gold rim and its white fill are offset from each other), so it is
   clipped away: only the two penguins are drawn. They speak through the scene's own bubble art, like every other bubble. */
.pair__art { clip-path: polygon(0 43.4%, 60.3% 43.4%, 60.3% 48.4%, 73.7% 48.4%, 73.7% 43.4%, 100% 43.4%, 100% 100%, 0 100%); }
.pair__bodies { position: absolute; left: 0; right: 36%; top: 44%; bottom: 0; }
/* the tail tip sits just above the yellow penguin's head (60% across, 43% down the pair's box) */
.say--pair { left: 44.4%; top: -10%; width: 70%; }
.say--pair > span { font: 600 clamp(8px, 14cqi, 44px)/1.05 var(--f-ui); }
/* the snow shelf by the Dock, right of the tree hill */
.cast--reporter { --fx: 80; --fy: 55; --w: 12.6; --ox: .547; --oy: .984; --ar: 1.2059; animation: bob2 3.6s var(--ease-bob) -1.2s infinite; transform-origin: 50% 100%; }
/* the snow in front of the tree hill, where the reporter points: far enough out that its shadow clears the hill's outline */
.cast--orange { --fx: 72.5; --fy: 59.5; --w: 8.5; --ox: .52; --oy: .928; --ar: 1.0705; animation: bob2 4s var(--ease-bob) -2s infinite; }
/* the snow under the ski lift, beside the pair (the easel's own snow patch sits on it) */
.cast--artist { --fx: 35; --fy: 53.5; --w: 11; --oy: .8; --ar: 1.0087; aspect-ratio: 115 / 116; }
/* The painter plays its 12 real frames from ONE file that animates itself (build-art.py artist_strip: a one-frame
   viewport stepped by SMIL). The whole cycle arrives before the first step, so no frame can flash blank while its own
   file downloads (12 separate files did, all through the first cycle), and the box never moves, so no engine can land a
   step between device pixels (sliding a wide sheet made the easel jitter at fractional scales in Firefox and WebKit).
   An SVG image runs its own animation whatever the page's reduced-motion rule says, so reduced motion shows frame 1. */
.artist { position: absolute; inset: 0; background: url(/site/home/art/hero/puffle-artist-strip.svg) center / contain no-repeat; }
@media (prefers-reduced-motion: reduce) { .artist { background-image: url(/site/home/art/hero/puffle-artist-00.svg); } }
@keyframes bob2 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
.cast--me { display: none; --fx: 81; --fy: 55; --w: 20; --oy: .89; }
/* the returning penguin is wider than the reporter it replaces (and keeps its feet and name tag off the Dock's rocks, which
   start at 84% across), so the orange penguin steps left along the tree hill's foot to keep clear of it (flat snow there
   too: the hill's edge is at 58% of the art's height) */
[data-me="1"] .cast--orange { --fx: 69; --fy: 62.5; }
.doll { position: relative; aspect-ratio: 1; animation: hello 2.4s var(--ease-bob) infinite; transform-origin: 50% 88%; }
.doll img { position: absolute; inset: 0; width: 100%; height: 100%; }
@keyframes hello { 0%, 100% { transform: rotate(0) translateY(0); } 20% { transform: rotate(-4deg) translateY(-6px); } 40% { transform: rotate(4deg) translateY(0); } 60% { transform: rotate(-3deg) translateY(-3px); } 80% { transform: rotate(2deg); } }
/* speech bubbles made of the scene's own bubble art (#82 left tail, #154 right tail): the image sets the box, the words sit
   in its white body (inset in % of the same box) and are sized in cqi of that box, so they scale with the bubble */
.say { position: absolute; z-index: 2; container-type: inline-size; pointer-events: none; }
.say__art { position: static !important; display: block; width: 100%; height: auto; }
.say__art--r, .say.is-right .say__art--l { display: none; }
.say.is-right .say__art--r { display: block; }
.say > span, .say > p { position: absolute; inset: 7% 8% 27% 8%; margin: 0; display: grid; place-items: center; text-align: center; color: var(--ocean-900); text-wrap: balance; }
/* the returning penguin speaks up and to the left (the bubble mirrored, its tail at the head), over the open sky above the
   tree hill: to its right the Migrator rides at anchor, and a bubble there would cover the ship */
.say--me { left: -36%; top: -20%; width: 72%; animation: pop-in .5s var(--ease-out) .6s both; }
.say--me .say__art--l { transform: scaleX(-1); }
.say--me > span { font: 600 clamp(8px, 14cqi, 44px)/1.05 var(--f-ui); }
.hero__notyou { margin-top: 16px; padding: 7px 14px; border-radius: var(--r-pill); font: 600 14.5px/1.2 var(--f-ui); color: rgba(255,255,255,.88); background: rgba(6,33,63,.42); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22); backdrop-filter: blur(10px); }
.linkish { padding: 0; border: 0; background: none; color: #fff; font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.nametag { position: absolute; left: 50%; bottom: 4%; translate: -50% 0; max-width: 140%; padding: 4px 12px; border-radius: var(--r-pill); background: rgba(255,255,255,.94); font: 600 clamp(12px, 1.05cqw, 16px)/1.2 var(--f-ui); color: var(--ocean-900); box-shadow: var(--lift-1); white-space: nowrap; }
@keyframes pop-in { from { opacity: 0; transform: scale(.6) translateY(10px); } }

/* the near plane: the lighthouse as a foreground edge piece, its top out of frame */
.near { transform: translate3d(calc(var(--mx, 0) * -26px), calc(var(--my, 0) * -6px), 0); }
.lighthouse { left: -47cqh; bottom: -8cqh; height: 110cqh; width: auto; filter: blur(1.2px) saturate(.9) brightness(.94); }

/* flybys on motion paths */
.flyby { overflow: hidden; }
.jet { position: absolute; left: 0; top: 0; width: 6.2cqw; animation: jetfly 24s linear -8.64s infinite; }
.jet__pg { position: relative !important; width: 100%; }
.jet__smoke { width: 15%; opacity: .9; }
.jet__smoke.s1 { left: 96%; top: 40%; }
.jet__smoke.s2 { left: 118%; top: 34%; width: 12%; opacity: .6; }
.jet__smoke.s3 { left: 138%; top: 26%; width: 9%; opacity: .35; }
@keyframes jetfly { 0% { transform: translate(108cqw, 26cqh) rotate(4deg); } 20% { transform: translate(62cqw, 16cqh) rotate(0); } 40% { transform: translate(10cqw, 22cqh) rotate(-5deg); } 45%, 100% { transform: translate(-20cqw, 30cqh) rotate(-6deg); } }
.gpuffle { width: 3.4cqw; left: 0; top: 0; animation: pufffly 26s linear -10.7s infinite; }
/* phones: the copy stack fills the sky, so the puffle skims the open water between the horizon and the island instead
   (the fly-by plane is drawn over the sea and under the island; it follows the island when home.js shifts the scene) */
@keyframes pufffly-p {
  0% { transform: translate(-12cqw, calc(60cqh + var(--shift))); }
  12% { transform: translate(20cqw, calc(58.6cqh + var(--shift))) rotate(-4deg); }   /* over the ski hill's top */
  26% { transform: translate(50cqw, calc(62.4cqh + var(--shift))) rotate(3deg); }    /* down over the open water mid-island */
  38% { transform: translate(80cqw, calc(61.4cqh + var(--shift))); }
  50% { transform: translate(112cqw, calc(60cqh + var(--shift))) rotate(4deg); }
  50.1%, 100% { transform: translate(120cqw, calc(60cqh + var(--shift))); }
}
/* phones on their side: the copy panel fills the right of the sky, so the puffle climbs away out of the top instead */
@keyframes pufffly-l { 0% { transform: translate(-8cqw, 36cqh); } 25% { transform: translate(24cqw, 22cqh) rotate(-4deg); } 42% { transform: translate(44cqw, 8cqh) rotate(-8deg); } 50% { transform: translate(52cqw, -16cqh) rotate(-10deg); } 50.1%, 100% { transform: translate(-20cqw, -16cqh); } }
/* the puffle's arc keeps to the open sky under the copy (over the clouds, above the horizon), so it is never lost behind the
   logo and the lines of text; it follows the horizon when home.js shifts the scene */
@keyframes pufffly { 0% { transform: translate(-10cqw, calc(var(--hz) - 7cqh)); } 25% { transform: translate(40cqw, calc(var(--hz) - 10.5cqh)) rotate(-4deg); } 50% { transform: translate(110cqw, calc(var(--hz) - 8cqh)) rotate(4deg); } 50.1%, 100% { transform: translate(120cqw, calc(var(--hz) - 8cqh)); } }
/* where the copy comes down to the horizon (short and tablet-width windows) there is no open sky under it: home.js marks
   the hero data-lane and the puffle rises up the open sky beside the copy and away out of the top instead: on the left
   (climb-l), or where the lighthouse stands there, on the right (climb-r), turned round so it still flies the way it faces */
[data-lane="climb-l"] .gpuffle { animation-name: pufffly-cl; }
[data-lane="climb-r"] .gpuffle { animation-name: pufffly-cr; }
@keyframes pufffly-cl { 0% { transform: translate(-8cqw, calc(var(--hz) - 4cqh)); } 20% { transform: translate(6cqw, calc(var(--hz) - 16cqh)) rotate(-6deg); } 40% { transform: translate(13cqw, 18cqh) rotate(-9deg); } 50%, 100% { transform: translate(17cqw, -14cqh) rotate(-10deg); } }
@keyframes pufffly-cr { 0% { transform: translate(104cqw, calc(var(--hz) - 12cqh)) scaleX(-1); } 20% { transform: translate(92cqw, calc(var(--hz) - 22cqh)) scaleX(-1) rotate(-6deg); } 40% { transform: translate(85cqw, 16cqh) scaleX(-1) rotate(-9deg); } 50%, 100% { transform: translate(81cqw, -14cqh) scaleX(-1) rotate(-10deg); } }

.beam { position: absolute; inset: 0; pointer-events: none; opacity: 0; }
.grade { position: absolute; inset: 0; pointer-events: none; opacity: 0; }
.snow { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* hero copy */
.hero__copy { position: absolute; z-index: 5; left: 50%; top: calc(var(--header-h) + 2cqh); translate: -50% 0; width: min(880px, 92cqw); display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero__logo { width: clamp(250px, 25cqw, 380px); height: auto; filter: drop-shadow(0 10px 24px rgba(0,25,70,.35)); }
.hero__tag { margin-top: 14px; font: 400 clamp(30px, 3.1cqw, 46px)/1.05 var(--f-display); color: #fff; letter-spacing: .005em; text-shadow: 0 3px 0 rgba(0,40,100,.55), 0 10px 30px rgba(0,30,80,.35); }
.hero__tag > span { color: var(--gold-500); }
.hero__sub { margin-top: 10px; max-width: 44em; font: 600 clamp(16px, 1.35cqw, 20px)/1.45 var(--f-body); color: rgba(255,255,255,.95); text-shadow: 0 1px 12px rgba(0,30,80,.45); }
.hero__sub b { color: #fff; font-weight: 800; }
/* the newcomer's line breaks only between its phrases (never "...back and free. Play / right here..."), in balanced lines */
.hero__sub.new-only { text-wrap: balance; }
.hero__sub > span { white-space: nowrap; }
.hero__ctas { margin-top: 24px; display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; align-items: flex-start; }
/* the gold button and, under it for a newcomer, how long a penguin takes to make (on a glass pill: it may sit on the
   clouds) */
.hero__go { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.hero__hint { padding: 5px 14px; border-radius: var(--r-pill); font: 600 14.5px/1.2 var(--f-ui); color: #fff; background: rgba(6,33,63,.42); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22); backdrop-filter: blur(10px); }
/* the quiet way in for a player whose penguin this device doesn't remember: a glass pill beside the gold button, as tall
   as it (the copy's own --h per layout) */
.hero__have { --h: 66px; display: inline-flex; align-items: center; justify-content: center; height: var(--h); padding: 0 calc(var(--h) * .42); border-radius: var(--r-pill); font: 600 18px/1.1 var(--f-ui); color: #fff; text-decoration: none; white-space: nowrap;
  background: rgba(6,33,63,.42); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.3); backdrop-filter: blur(10px); transition: background var(--t-fast); }
.hero__have:hover { background: rgba(6,33,63,.6); }
[data-me="1"] .hero__ctas .me-only { display: inline-flex !important; }
[data-me="1"] .cast--reporter { display: none; }
[data-me="1"] .cast--me { display: block; }

.hero__foot { position: absolute; z-index: 6; left: 0; right: 0; bottom: max(20px, env(safe-area-inset-bottom)); display: flex; align-items: center; justify-content: space-between; padding: 0 max(28px, var(--gutter)); pointer-events: none; }
.hero__foot > * { pointer-events: auto; }
.badge-pill { display: inline-flex; align-items: center; gap: 10px; padding: 9px 16px; border-radius: var(--r-pill); background: rgba(234,246,255,.92); color: var(--ocean-900); font: 700 13.5px/1.2 var(--f-body); text-decoration: none; box-shadow: var(--lift-2); backdrop-filter: blur(10px); }
.badge-pill i { width: 4px; height: 4px; border-radius: 50%; background: var(--ocean-700); opacity: .5; }
.cue { position: absolute; left: 50%; translate: -50% 0; bottom: 0; display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 12px 0 18px; border-radius: var(--r-pill); color: #fff; text-decoration: none; font: 600 14px/1 var(--f-ui); letter-spacing: .1em; text-transform: uppercase; background: rgba(6,33,63,.5); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.3); backdrop-filter: blur(10px); }
.cue svg { width: 22px; height: 22px; animation: nudge 1.8s var(--ease-bob) infinite; }
@keyframes nudge { 50% { transform: translateY(5px); } }
.snow-toggle { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 16px 0 12px; border-radius: var(--r-pill); border: 0; cursor: pointer; background: rgba(6,33,63,.36); color: #fff; font: 600 14px/1 var(--f-ui); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.3); backdrop-filter: blur(10px); }
.snow-toggle svg { width: 16px; height: 16px; fill: currentColor; }
.snow-toggle .i-play, .snow-toggle[aria-pressed="true"] .i-pause { display: none; }
.snow-toggle[aria-pressed="true"] .i-play { display: block; }

/* ------------------------------------------------------------------ time of day (M2) */
[data-sky="golden"] .hero { --sky-top: #1d3f8f; --sky-a: #3a5fb4; --sky-b: #d97a6c; --sky-c: #ffc47a; }
[data-sky="golden"] .sun { opacity: 1; background: radial-gradient(60cqw 26cqh at 50% calc(var(--hz) + 1cqh), rgba(255,236,170,.9), rgba(255,190,110,.35) 45%, rgba(255,160,90,0) 70%); }
[data-sky="golden"] .cloud { filter: sepia(.35) saturate(1.5) hue-rotate(-18deg) brightness(1.02); }
[data-sky="golden"] .grade { opacity: 1; background: radial-gradient(38cqw 30cqh at 50% var(--hz), rgba(255,210,140,.55), rgba(255,170,100,0) 70%), linear-gradient(180deg, rgba(255,150,70,0) 0%, rgba(255,150,70,0) calc(var(--hz) - 1cqh), rgba(255,140,80,.32) calc(var(--hz) + 4cqh), rgba(240,120,110,.22) 100%); mix-blend-mode: overlay; }
[data-sky="golden"] .sea { background: #1b8fb4; }

[data-sky="night"] .hero { --sky-top: #0c0426; --sky-a: #2f0143; --sky-b: #1b3f93; --sky-c: #22a9d9; }
[data-sky="night"] .starfield { opacity: 1; animation: twinkle 5s var(--ease-bob) infinite alternate; }
[data-sky="night"] .day-only { display: none; }
[data-sky="night"] .night-only { display: block; }
[data-sky="night"] .sea { background: #0b6f98; }
[data-sky="night"] .sun { opacity: 1; background: radial-gradient(70cqw 16cqh at 50% var(--hz), rgba(210,255,200,.55), rgba(120,220,255,.12) 55%, rgba(0,0,0,0) 75%); }
[data-sky="night"] .grade { opacity: 1; background: linear-gradient(180deg, rgba(20,20,90,0) 0%, rgba(20,20,90,0) calc(var(--hz) - 2cqh), rgba(26,30,110,.38) calc(var(--hz) + 6cqh), rgba(14,18,70,.5) 100%); mix-blend-mode: multiply; }
[data-sky="night"] .beam {
  opacity: 1; mix-blend-mode: screen;
  background: conic-gradient(from 100deg at 3cqw -4cqh, rgba(255,250,200,0) 0deg, rgba(255,246,190,.16) 3deg, rgba(255,248,205,.42) 8deg, rgba(255,246,190,.16) 13deg, rgba(255,250,200,0) 16deg);
  -webkit-mask-image: radial-gradient(130cqw 120cqh at 3cqw -4cqh, #000 30%, transparent 80%); mask-image: radial-gradient(130cqw 120cqh at 3cqw -4cqh, #000 30%, transparent 80%);
  transform-origin: 3cqw -4cqh; animation: sweep 9s var(--ease-bob) infinite alternate;
}
@keyframes sweep { from { transform: rotate(-9deg); } to { transform: rotate(16deg); } }
@keyframes twinkle { from { opacity: .7; } to { opacity: 1; } }

/* ------------------------------------------------------------------ explore the island (M3) */
.explore { position: relative; background: radial-gradient(120% 90% at 30% 20%, #19a9dc 0%, var(--sea-500) 45%, #06669a 100%); color: #fff; }
.explore__inner { width: min(1320px, 100% - 2 * var(--gutter)); margin-inline: auto; display: grid; grid-template-columns: minmax(0, 1fr) 380px; grid-template-rows: auto auto; gap: 26px 36px; padding: calc(var(--header-h) + 36px) 0 64px; align-items: stretch; }
.explore__head { grid-column: 1 / -1; grid-row: 1; display: grid; grid-template-columns: 1fr auto; align-items: end; column-gap: 40px; }
.explore__head .cats { grid-column: 2; grid-row: 1 / span 3; align-self: end; margin: 0; }
.map { grid-column: 1; grid-row: 2; align-self: start; width: 100%; }
/* the sheet grows to the map's height (its photo fills the spare room), and the row grows when its words need more */
.sheet { grid-column: 2; grid-row: 2; display: flex; flex-direction: column; min-width: 0; }
.sheet__body { flex: 1; display: flex; flex-direction: column; }
.sheet__actions { margin-top: auto !important; padding-top: 16px; }
.eyebrow { display: inline-flex; align-items: center; gap: 10px; font: 600 15px/1 var(--f-ui); letter-spacing: .12em; text-transform: uppercase; color: #cdeeff; }
.eyebrow img { width: 30px; height: 30px; }
.eyebrow--dark { color: var(--ocean-700); }
h2 { font: 400 clamp(32px, 3.2vw, 48px)/1.02 var(--f-display); letter-spacing: .005em; margin-top: 10px; }
.explore h2 { text-shadow: 0 3px 0 rgba(0,40,100,.35); margin-top: 8px; }
.lede { margin-top: 12px; font-size: 17.5px; line-height: 1.55; max-width: 38em; }
.explore .lede { color: rgba(255,255,255,.9); }
.cats { display: flex; gap: 10px; margin-top: 22px; flex-wrap: wrap; }
.cats button { display: inline-flex; align-items: center; gap: 8px; height: 50px; padding: 0 16px 0 6px; border: 0; border-radius: 16px; cursor: pointer; background: rgba(255,255,255,.14); color: #fff; font: 600 16px/1 var(--f-ui); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22); transition: background var(--t-fast), transform var(--t-fast); }
.cats button img { width: 38px; height: 38px; }
.cats button[aria-selected="true"] { background: #fff; color: var(--ocean-900); box-shadow: 0 4px 0 rgba(6,33,63,.25), 0 10px 20px rgba(6,33,63,.18); }

.map { position: relative; aspect-ratio: 781 / 500.5; border-radius: 28px; overflow: hidden; box-shadow: 0 0 0 6px rgba(255,255,255,.9), 0 24px 60px rgba(0,30,80,.45); background: var(--sea-500); }
.map > img { position: absolute; inset: 0; width: 100%; height: 100%; }
.map__full { opacity: 0; transition: opacity var(--t-base); }
.map[data-cat="games"] .map__full, .map[data-cat="shop"] .map__full, .map[data-cat="pets"] .map__full { opacity: 1; }
.map__badges { position: absolute; inset: 0; }
.mb { position: absolute; padding: 0; border: 0; background: none; cursor: pointer; transform-origin: 50% 70%; }
.mb img { width: 100%; height: 100%; filter: drop-shadow(0 3px 0 rgba(6,33,63,.25)); transition: transform var(--t-fast) var(--ease-out); }
.mb:hover img, .mb.is-active img { transform: translateY(-4px) scale(1.06); filter: drop-shadow(0 6px 6px rgba(6,33,63,.35)) drop-shadow(0 0 10px rgba(255,255,200,.9)); }
.mb[data-cat]:not(.show) { display: none; }
.map__pins { position: absolute; inset: 0; pointer-events: none; }
.pin { position: absolute; translate: -50% calc(-100% - 6px); padding: 4px 9px 5px; border-radius: 9px; background: #fff; color: var(--ocean-900); font: 600 12.5px/1 var(--f-ui); white-space: nowrap;
  box-shadow: 0 2px 0 rgba(6,33,63,.18), 0 6px 14px rgba(6,33,63,.22); opacity: 0; transition: opacity var(--t-fast); }
.pin::after { content: ""; position: absolute; left: 50%; top: 100%; translate: -50% 0; border: 6px solid transparent; border-top-color: #fff; }
.pin:not(.show) { display: none; }
.pin.hover { opacity: 1; }
/* places: every building is a hotspot, so each wears its name pin (the in-game hover label, always on) */
.map[data-cat="places"] .pin { opacity: 1; }
.pin.is-active { background: var(--gold-500); color: #4a2600; font-size: 14px; padding: 6px 11px 7px; z-index: 2; box-shadow: 0 3px 0 #c47f0e, 0 8px 18px rgba(6,33,63,.3); }
.pin.is-active::after { border-top-color: var(--gold-500); }
.pin[data-label="ski_hill"] { translate: -50% calc(-100% + 22px); }
.pin[data-label="plaza"] { translate: -50% calc(-100% + 34px); }
.pin[data-label="igloos"] { translate: -50% calc(-100% + 18px); }
.pin[data-label="dock"] { translate: -30% calc(-100% + 12px); }
.pin[data-label="town"] { translate: -50% calc(-100% + 4px); }
.pin[data-label="forts"] { translate: -50% calc(-100% + 2px); }
.pin[data-label="your_igloo"] { translate: -40% calc(-100% - 2px); }

.sheet { background: #fff; color: var(--ocean-900); border-radius: var(--r-card); overflow: hidden; box-shadow: 0 24px 60px rgba(0,30,80,.4); }
.sheet__shot { position: relative; flex: 1 1 auto; min-height: 150px; }
.sheet__shot img { width: 100%; height: 100%; object-fit: cover; }
.sheet__live { position: absolute; left: 12px; top: 12px; display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: var(--r-pill); background: rgba(6,33,63,.72); color: #fff; font: 600 12.5px/1 var(--f-ui); backdrop-filter: blur(6px); }
.sheet__live i { width: 8px; height: 8px; border-radius: 50%; background: #5BE36B; }
.sheet__body { flex: none; padding: 18px 22px 22px; }
.sheet__title { display: flex; align-items: center; gap: 14px; }
.sheet__title img { width: 76px; height: 60px; object-fit: contain; }
.sheet__title h3 { font: 400 30px/1 var(--f-display); margin-top: 4px; }
.sheet__title .eyebrow { font-size: 12px; }
.sheet__body > p { margin-top: 12px; font-size: 15.5px; line-height: 1.5; color: #274463; }
.sheet__chips { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }
.sheet__chips li { padding: 6px 12px; border-radius: var(--r-pill); background: var(--ice-50); box-shadow: inset 0 0 0 1.5px #d4e6f6; font: 600 13.5px/1.2 var(--f-ui); color: var(--ocean-700); }
.sheet__body > p.sheet__tip { margin-top: 14px; padding: 10px 12px; border-radius: 14px; background: #fff8d6; box-shadow: inset 0 0 0 1.5px #f3df86; font-size: 14px; color: #5a4200; }
.sheet__tip b { font-weight: 800; }
.sheet__actions { display: flex; gap: 12px; margin-top: 16px; }
.sheet__badge { display: none; position: absolute; inset: 12% 20%; width: 60%; height: 76%; object-fit: contain; filter: drop-shadow(0 8px 10px rgba(6,33,63,.3)); }
.sheet__shot.no-shot { background: radial-gradient(80% 90% at 50% 40%, #3cc3f0, #0b5db8); }
.sheet__shot.no-shot #sheet-img, .sheet__shot.no-shot .sheet__live { display: none; }
.sheet__shot.no-shot .sheet__badge { display: block; }
.sheet__chips:empty { display: none; }
.mb:focus-visible { outline-offset: 0; }

/* ------------------------------------------------------------------ bands */
.band { position: relative; padding: clamp(64px, 8vw, 112px) 0; }
.band--ice { background: linear-gradient(180deg, #f3faff, var(--ice-50)); }
.band--deep { background: radial-gradient(120% 80% at 80% 0%, #10448a 0%, #0a2f63 45%, var(--ocean-900) 100%); color: #fff; }
.band--sky { background: linear-gradient(180deg, #c4e5ff 0%, #dff1ff 70%, #eef8ff 100%); }
.band--white { background: #fff; }
.sec-head { margin-bottom: 36px; }
.sec-head--row { display: flex; align-items: end; justify-content: space-between; gap: 20px; }
.sec-head--center { text-align: center; display: flex; flex-direction: column; align-items: center; }
.sec-head .lede { color: #35516f; }
.band--deep .eyebrow { color: #9fdcff; }
.band--deep .lede { color: rgba(234,246,255,.86); }
.link-arrow { display: inline-flex; align-items: center; gap: 6px; font: 600 17px/1 var(--f-ui); text-decoration: none; color: #9fdcff; padding: 10px 0; }
.link-arrow svg { width: 20px; height: 20px; }

/* what's inside */
.rooms { display: grid; grid-template-columns: repeat(12, 1fr); grid-auto-rows: clamp(220px, 29vw, 400px); gap: 22px; }
.room { position: relative; margin: 0; border-radius: var(--r-card); overflow: hidden; grid-column: span 5; box-shadow: 0 0 0 5px #fff, 0 18px 40px rgba(6,33,63,.18); background: #cfe6f7; transition: transform var(--t-base) var(--ease-out); }
.room:hover { transform: translateY(-4px) rotate(-.4deg); }
.room--xl, .room--wide { grid-column: span 7; }
.room img { width: 100%; height: 100%; object-fit: cover; }
.room figcaption { position: absolute; left: 14px; bottom: 14px; display: flex; align-items: center; gap: 10px; padding: 8px 16px 8px 8px; border-radius: 18px; background: rgba(255,255,255,.94); box-shadow: var(--lift-2); backdrop-filter: blur(8px); }
.room figcaption img { width: 52px; height: 42px; object-fit: contain; }
.room figcaption span { display: flex; flex-direction: column; font: 400 13.5px/1.25 var(--f-body); color: #35516f; }
.room figcaption b { font: 400 20px/1.05 var(--f-display); color: var(--ocean-900); letter-spacing: .01em; }

/* play the classics */
.games { display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(2, 224px); gap: 18px; }
.game { --g1: #3aa8f5; --g2: #0a3f8f; position: relative; display: grid; place-items: center; border-radius: var(--r-card); overflow: hidden; text-decoration: none; color: #fff;
  background: radial-gradient(90% 80% at 50% 38%, var(--g1), var(--g2)); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.18), 0 16px 34px rgba(0,0,0,.28); transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base); }
.game::before { content: ""; position: absolute; inset: 0; background: url(/site/home/art/ui/pattern-band.png) 0 0 / 200px auto; opacity: .09; mix-blend-mode: screen; }
.game:hover { transform: translateY(-5px); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.3), 0 22px 44px rgba(0,0,0,.36); }
.game--mine { --g1: #ffb347; --g2: #a3470b; }
.game--jetpack { --g1: #6fd3ff; --g2: #1461be; }
.game--fish { --g1: #9be9ff; --g2: #1978bd; }
.game--sub { --g1: #3fd0c0; --g2: #075a6d; }
.game--hydro { --g1: #45b4ff; --g2: #0a3a86; }
.game--thinice { --g1: #3b6fd0; --g2: #0a1a48; }
.game__title { position: relative; width: 78%; max-height: 56%; margin-top: -6px; object-fit: contain; filter: drop-shadow(0 6px 10px rgba(0,0,0,.3)); transition: transform var(--t-base) var(--ease-out); }
.game:hover .game__title { transform: scale(1.05) rotate(-1deg); }
.game__badge { position: absolute; left: 12px; top: 12px; width: 50px; height: 50px; filter: drop-shadow(0 3px 0 rgba(0,0,0,.2)); }
.game__name { position: absolute; left: 0; right: 0; bottom: 12px; text-align: center; font: 600 15px/1 var(--f-ui); letter-spacing: .03em; opacity: .92; }
.game--feature { grid-column: span 2; grid-row: span 2; place-items: stretch; background: #7a2c0e; }
.game__shot { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 30% 40%; }
.game__meta { position: absolute; left: 16px; right: 16px; bottom: 16px; display: flex; align-items: center; gap: 14px; padding: 12px 12px 12px 12px; border-radius: 20px; background: rgba(6,33,63,.72); backdrop-filter: blur(10px); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.18); }
.game__meta > img { width: 54px; height: 54px; }
.game__meta > span:not(.btn) { display: flex; flex-direction: column; font: 400 14.5px/1.3 var(--f-body); color: rgba(255,255,255,.85); flex: 1; }
.game__meta b { font: 400 24px/1.05 var(--f-display); color: #fff; }
.game__blurb { font-style: normal; }
.strip { margin-top: 28px; display: flex; align-items: center; gap: 20px; padding: 14px 14px 14px 20px; border-radius: 22px; background: rgba(255,255,255,.06); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.1); }
.strip__label { display: inline-flex; align-items: center; gap: 10px; font: 600 15px/1.1 var(--f-ui); color: #e3c8ff; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
.strip__label img { width: 36px; height: 36px; }
.strip__row { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; flex: 1; }
.chip-game { flex: 1 1 0; min-width: 132px; display: grid; place-items: center; height: 72px; padding: 0 14px; border-radius: 16px; background: linear-gradient(180deg, #7b3fc4, #4a1f8c); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.18); transition: transform var(--t-fast); }
.chip-game:hover { transform: translateY(-3px); }
.chip-game img { height: 40px; width: 100%; max-width: 160px; object-fit: contain; filter: drop-shadow(0 3px 4px rgba(0,0,0,.3)); }

/* puffles: each is a button; the one you picked says hi in the scene's own bubble (one bubble, placed by home.js above
   the picked puffle and kept inside the section; its words are sized in cqi of the bubble, so they always fit) */
.puffles .wrap { position: relative; }
.puffle-row { list-style: none; margin: 0; padding: 26px 20px 30px; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 8px; border-radius: 32px; background: #fff; box-shadow: 0 18px 40px rgba(6,33,63,.1); }
.puffle-row li { position: relative; display: flex; justify-content: center; }
.puffle-row button { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; padding: 6px 0 0; border: 0; background: none; cursor: pointer; border-radius: 16px; }
.puffle-row img { width: 100%; max-width: 92px; aspect-ratio: 1; object-fit: contain; object-position: 50% 100%; animation: bob2 3s var(--ease-bob) infinite; transition: transform var(--t-fast) var(--ease-out); }
.puffle-row li:nth-child(3n) img { animation-delay: -1s; } .puffle-row li:nth-child(3n+1) img { animation-delay: -2s; }
.puffle-row button:hover img { transform: translateY(-8px) scale(1.08); }
.puffle-row span { font: 600 14px/1 var(--f-ui); color: #35516f; padding: 5px 10px; border-radius: var(--r-pill); margin-top: -4px; }
.puffle-row button::before { content: ""; position: absolute; left: 50%; top: calc(6px + min(92px, 100%) * .92); width: 66%; height: 12px; translate: -50% 0; border-radius: 50%; background: radial-gradient(closest-side, rgba(6,33,63,.16), rgba(6,33,63,0)); }
.puffle-row li.is-picked img { transform: translateY(-10px) scale(1.12); animation: none; }
.puffle-row li.is-picked button::before { background: radial-gradient(closest-side, rgba(255,204,0,.55), rgba(255,204,0,0)); height: 16px; }
.puffle-row li.is-picked span { color: var(--ocean-900); background: var(--gold-500); box-shadow: 0 2px 0 #c47f0e; }
.say--puffle { --bw: min(250px, 62vw); left: var(--sx, 0px); top: var(--sy, 0px); width: var(--bw); z-index: 3; }
.say--puffle > p { font: 600 clamp(11px, 6.4cqi, 16px)/1.2 var(--f-ui); }
.say--puffle.is-placing { visibility: hidden; }
/* room above the row for the bubble: it hangs from the picked puffle's head (row padding + 6 px) up by its own height */
.puffles .puffle-row { margin-top: calc(min(250px, 62vw) * .7266 - 16px); }
/* waddle safe + create */
.safe__grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 40px; align-items: stretch; }
.rules { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.rules li { display: grid; grid-template-columns: 56px 1fr; grid-template-rows: auto auto; column-gap: 14px; align-items: center; padding: 18px; border-radius: 20px; background: #fff; box-shadow: 0 10px 24px rgba(6,33,63,.08), inset 0 0 0 1.5px #dcecf8; }
.rules img { grid-row: span 2; width: 52px; height: 52px; object-fit: contain; image-rendering: auto; }
.rules b { font: 400 21px/1.1 var(--f-display); letter-spacing: .01em; }
.rules span { font-size: 14.5px; line-height: 1.4; color: #35516f; }
.safe__links { display: flex; gap: 20px; margin-top: 22px; flex-wrap: wrap; }
.safe__links a { font: 600 16px/1 var(--f-ui); color: var(--ocean-700); text-underline-offset: 4px; }
.create-card { position: relative; display: grid; grid-template-columns: 42% 1fr; align-items: center; gap: 10px; padding: 34px 36px 34px 20px; border-radius: 32px; overflow: hidden; color: #fff;
  background: radial-gradient(90% 90% at 20% 30%, #3cc3f0 0%, var(--ocean-700) 55%, #073f86 100%); box-shadow: 0 24px 50px rgba(11,93,184,.35); }
.create-card::before { content: ""; position: absolute; inset: 0; background: url(/site/home/art/ui/pattern-band.png) 0 0 / 220px auto; opacity: .16; mix-blend-mode: screen; }
.create-card__doll { position: relative; align-self: end; margin-bottom: -6px; }
.create-card__doll { aspect-ratio: 194 / 261.75; animation: bob2 3s var(--ease-bob) infinite; }
.pd { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 16px 20px rgba(0,20,60,.35)); transition: opacity var(--t-base) var(--ease-out); }
.pd--b { opacity: 0; }
.create-card__copy { position: relative; }
.create-card h2 { margin-top: 0; text-shadow: 0 3px 0 rgba(0,40,100,.35); }
.create-card p { margin-top: 10px; color: rgba(255,255,255,.92); font-size: 17px; }
.balls { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; margin: 18px 0 22px; max-width: 320px; }
.balls img { width: 100%; filter: drop-shadow(0 2px 0 rgba(0,20,60,.3)); }

/* ------------------------------------------------------------------ the scroll dive (motion mode only) */
/* one progress value --p (0..1) drives four overlapping acts:
   push-in (0 .. .55)  ->  white-out through the real horizon clouds (.30 .. .48)
   ->  the island map surfaces through the parting clouds (.46 .. .64)  ->  buildings + pins pop in (.56 .. .88) */
.dive-on .dive { height: calc(100svh + 160vh); }
.dive-on .stage { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.dive-on .hero { position: absolute; inset: 0; min-height: 0;
  --a: clamp(0, calc(var(--p) * 1.8), 1);
  opacity: calc(1 - clamp(0, calc((var(--p) - .40) * 16), 1));
}
.dive-on .explore { position: absolute; inset: 0; overflow: hidden;
  --b: clamp(0, calc((var(--p) - .46) * 5.6), 1);
  --c: clamp(0, calc((var(--p) - .52) * 3.4), 1);
  opacity: clamp(0, calc((var(--p) - .44) * 12), 1);
}
.dive-on .explore__inner { height: 100%; align-content: center; padding-top: calc(var(--header-h) + 6px); padding-bottom: 24px; }
/* laptop-height windows (1133x753, 1280x720, 1366x768): the map is sized to the screen's height and the sheet leaves its tip
   out, so the map, the tabs and the sheet fit one screen and the dive through the clouds plays there too */
@media (min-width: 1024px) and (max-height: 899px) {
  .dive-on .explore__inner { width: min(1320px, 100% - 2 * var(--gutter), (100svh - var(--header-h) - 210px) * 1.5605 + 416px); }
  .dive-on .sheet__tip { display: none; }
  .dive-on .sheet__shot { min-height: 90px; }
}
/* short laptop windows (1280x633, 1366x657 inside the browser): the lede steps out too and the map takes its room */
@media (min-width: 1024px) and (max-height: 700px) {
  .dive-on .lede { display: none; }
  .dive-on .explore__inner { width: min(1320px, 100% - 2 * var(--gutter), (100svh - var(--header-h) - 150px) * 1.5605 + 416px); }
  .dive-on .sheet__shot { min-height: 70px; }
}
/* tablets on their end (768x1024 to 834x1194): in the dive the sheet takes the phones' compact form (the shot beside the
   place's name, no chips or tip) and the lede steps out, so the map, the tabs and the sheet fit one screen */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) {
  .dive-on .lede { display: none; }
  .dive-on .explore__inner { row-gap: 16px; }
  .dive-on .sheet { display: grid; grid-template-columns: 42% 1fr; grid-template-rows: auto auto; }
  .dive-on .sheet__shot { grid-row: 1; grid-column: 1; min-height: 0; margin: 12px 0 0 12px; border-radius: 14px; overflow: hidden; }
  .dive-on .sheet__body { display: contents; }
  .dive-on .sheet__title { grid-row: 1; grid-column: 2; align-self: center; padding: 12px 16px 0 14px; }
  .dive-on .sheet__body > p { grid-column: 1 / -1; margin: 12px 16px 0; }
  .dive-on .sheet__chips, .dive-on .sheet__tip { display: none; }
  .dive-on .sheet__actions { grid-column: 1 / -1; padding: 14px; margin-top: 0; }
}
.dive-on .map { transform: scale(calc(1.5 - .5 * var(--b))); transform-origin: 38% 58%; }
.dive-on .explore__head { transform: translateY(calc((1 - var(--b)) * 36px)); opacity: var(--b); }
.dive-on .sheet { transform: translateX(calc((1 - var(--c)) * 48px)); opacity: var(--c); }
.dive-on .mb { --k: clamp(0, calc(var(--c) * 3.4 - var(--i) * .07), 1); opacity: var(--k); transform: translateY(calc((1 - var(--k)) * -16px)) scale(calc(.7 + var(--k) * .3)); }
.dive-on .map[data-cat="places"] .pin { opacity: clamp(0, calc(var(--c) * 3.4 - var(--i) * .07 - .45), 1); }
.dive-on .hero .diorama { transform: translate3d(0, calc(var(--a) * 6cqh), 0) scale(calc(1 + var(--a) * 1.7)); transform-origin: 46% 62%; }
.dive-on .hero .sea__art { transform: scale(calc(1 + var(--a) * 1.2)); transform-origin: 50% 20%; }
.dive-on .hero .ship { transform: translate3d(calc(var(--a) * 40cqw), calc(var(--a) * 20cqh), 0) scale(calc(1 + var(--a))); transform-origin: 90% 60%; }
.dive-on .hero .near { transform: translate3d(calc(var(--a) * -40cqw), 0, 0) scale(calc(1 + var(--a) * .6)); transform-origin: 0 100%; }
.dive-on .hero .cloud--l { transform: translate3d(calc(var(--a) * -60cqw), calc(var(--a) * -8cqh), 0) scale(calc(1 + var(--a) * 1.4)); }
.dive-on .hero .cloud--r { transform: translate3d(calc(var(--a) * 60cqw), calc(var(--a) * -8cqh), 0) scale(calc(1 + var(--a) * 1.4)); }
.dive-on .hero .sky { transform: translateY(calc(var(--a) * -30cqh)); }
.dive-on .hero__copy { opacity: calc(1 - var(--a) * 2.4); transform: translateY(calc(var(--a) * -18cqh)) scale(calc(1 - var(--a) * .1)); }
.dive-on .hero__foot { opacity: calc(1 - var(--a) * 4); }
.veil { display: none; }
.dive-on .veil {
  display: block; position: absolute; inset: 0; z-index: 3; pointer-events: none; overflow: hidden;
  --vin: clamp(0, calc((var(--p) - .30) * 8), 1);
  --vbg: min(var(--vin), clamp(0, calc(1 - (var(--p) - .47) * 10), 1));
  --vcl: min(var(--vin), clamp(0, calc(1 - (var(--p) - .63) * 12), 1));
}
.dive-on .veil::before { content: ""; position: absolute; inset: 0; opacity: var(--vbg); background: radial-gradient(70% 60% at 50% 50%, #ffffff 0%, #f2f9ff 50%, #d6ecfc 100%); }
.veil__zoom { position: absolute; inset: 0; opacity: var(--vcl); transform: scale(calc(.5 + (var(--p) - .3) * 4)); transform-origin: 50% 54%; }
.vc { position: absolute; max-width: none; filter: drop-shadow(0 20px 40px rgba(0,40,100,.18)); }
.vc1 { left: -26%; top: 2%; width: 76%; }
.vc2 { right: -30%; top: 8%; width: 84%; }
.vc3 { left: -36%; top: 58%; width: 82%; transform: scaleX(-1); }
.vc4 { right: -24%; top: 64%; width: 72%; transform: scaleX(-1); }
.vc5 { left: 20%; top: -18%; width: 58%; }
.vc6 { left: 12%; top: 82%; width: 72%; }

/* ------------------------------------------------------------------ layout modes (docs/PUBLIC-SITE.md §3.5) */
/* portrait screens: the lighthouse edge piece would cover the cast, so it steps out (phones already drop it) */
@media (orientation: portrait) { .near { display: none; } }
/* the Dive in cue sits between the badge and the snow toggle only where there is room for all three */
@media (max-width: 1099px) { .cue { display: none; } }
/* short windows (1600x600): the island's cast comes down to the footer, where the cue would sit on the painter; the dive is
   off under 700 px anyway, and the badge and the snow switch stay */
@media (max-height: 640px) { .cue { display: none; } }
/* wide */
@media (min-width: 1440px) {
  .hero__copy { top: calc(var(--header-h) + 4cqh); }
}
/* desktop: on short, wide windows the island follows the height too (centred as before), so the cast stays on screen
   even when the copy pushes the scene down. The cast's lowest point (the pair's feet, the returning penguin's name tag)
   sits at about 64% of the island's height, i.e. 0.318 x its width below --d-top (53cqh): capping the width at
   146cqh - 56px keeps it at least 16px above the hero's bottom edge (1600x800, 1920x800: 2-5px past it before). */
@media (min-width: 1024px) and (min-height: 500px) {
  .hero { --d-w: min(76cqw, calc(146cqh - 56px)); --d-left: calc(51cqw - var(--d-w) / 2); }
}
/* short laptop windows (1280x720, 1366x768): a tighter copy stack, so the island and its cast stay on screen */
@media (min-width: 1024px) and (min-height: 500px) and (max-height: 820px) {
  .hero__logo { width: clamp(220px, 34cqh, 330px); }
  .hero__tag { margin-top: 8px; font-size: clamp(28px, 5cqh, 42px); }
  .hero__sub { margin-top: 6px; }
  .hero__ctas { margin-top: 16px; }
  .hero__notyou { margin-top: 10px; }
}
@media (min-width: 1024px) and (min-height: 500px) and (max-height: 660px) { .hero { --d-w: min(76cqw, 110cqh); } }
/* a newcomer's copy is taller (its line under the tag runs to two lines, and the gold button has the time a penguin takes
   under it), so for a newcomer the tighter stack starts at 900 px tall, and on short laptop windows it tightens further (a
   smaller logo, 58 px buttons, the hint closer): the copy keeps off the island's cast, the cast's feet keep clear of the
   footer pills, and the dive stays on (1536x864 at 125%, 1360x700, 1120x600) */
@media (min-width: 1024px) and (min-height: 821px) and (max-height: 900px) {
  html:not([data-me="1"]) .hero__logo { width: clamp(220px, 34cqh, 330px); }
  html:not([data-me="1"]) .hero__tag { margin-top: 8px; font-size: clamp(28px, 5cqh, 42px); }
  html:not([data-me="1"]) .hero__sub { margin-top: 6px; }
  html:not([data-me="1"]) .hero__ctas { margin-top: 16px; }
}
@media (min-width: 1024px) and (min-height: 500px) and (max-height: 820px) {
  html:not([data-me="1"]) .hero__logo { width: clamp(190px, 30cqh, 300px); }
  html:not([data-me="1"]) .hero__sub { line-height: 1.35; }
  html:not([data-me="1"]) .hero__ctas { margin-top: 12px; }
  html:not([data-me="1"]) .hero__ctas .btn, html:not([data-me="1"]) .hero__have { --h: 58px; }
  html:not([data-me="1"]) .hero__go { gap: 6px; }
  html:not([data-me="1"]) .hero__hint { padding: 3px 12px; font-size: 13.5px; }
}
/* tablet */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) {
  /* the same bound as desktop from --d-top 56cqh: the cast's lowest point stays 16px inside the hero (960x800, 1000x800) */
  .hero { --horizon: 56cqh; --d-w: min(118cqw, calc(138cqh - 56px)); --d-left: calc(51cqw - var(--d-w) / 2); --d-top: 56cqh; }
  /* the island is as wide as the window or wider here, so the ship would stand behind the reporter's head: it rides
     further out instead, on the horizon (the reporter's head is always a good way below it) */
  .migrator { bottom: calc(100cqh - var(--hz) - 3cqh); }
  .explore__inner { grid-template-columns: minmax(0, 1fr); }
  .explore__head { display: block; }
  .explore__head, .map, .sheet { grid-column: 1; grid-row: auto; }
  .sheet { contain: none; min-height: 0; }
  .sheet__shot { flex: none; aspect-ratio: 1504 / 733; }
  .rooms { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 220px; }
  .room, .room--xl, .room--wide { grid-column: span 1; grid-row: span 1; }
  .room--xl { grid-column: span 2; grid-row: span 2; }
  .games { grid-template-columns: repeat(2, 1fr); grid-template-rows: none; grid-auto-rows: 200px; }
  .puffle-row { grid-template-columns: repeat(6, minmax(0, 1fr)); row-gap: 20px; }
  .safe__grid { grid-template-columns: 1fr; }
}

/* tablets nearer square than 3:2: the island is wider than the window, so the lighthouse edge piece would stand on the pair */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) and (max-aspect-ratio: 3/2) { .near { display: none; } }
/* a little taller (1000x700): the full copy stack is back (and a returning penguin's "Not you?" line under it), so the island
   is a touch smaller and its cast sits higher, clear of the footer pills (the painter's palette met the badge at 1000x700) */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 681px) and (max-height: 760px) { .hero { --d-w: min(118cqw, 122cqh); } }
/* short tablet-width windows (700x500, 1000x600): a compact copy stack, so the island keeps its cast on screen */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) and (max-height: 680px) {
  .hero { --d-w: min(118cqw, 115cqh); }
  .hero__logo { width: clamp(180px, 34cqh, 260px); }
  .hero__tag { margin-top: 6px; font-size: clamp(26px, 5.6cqh, 36px); }
  .hero__sub, [data-me="1"] .hero__sub.me-only { display: none !important; }
  .hero__ctas { margin-top: 12px; gap: 12px; }
  .hero__ctas .btn, .hero__have { --h: 54px; }
  .hero__go { gap: 8px; }
  .hero__notyou { margin-top: 8px; }
}
/* tablets, for a newcomer: the gold button and "I already have a penguin" stay side by side down to 600 px wide (a little
   closer together, the quiet one a little narrower, both 56 px tall under 700 px wide), and on short windows the hint sits
   closer and the stack tightens, so the copy keeps off the cast and the cast's feet keep clear of the footer pills
   (1000x700, 640x800, 900x500) */
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) {
  html:not([data-me="1"]) .hero__ctas { gap: 10px; }
  html:not([data-me="1"]) .hero__have { padding: 0 calc(var(--h) * .32); }
}
@media (min-width: 600px) and (max-width: 699px) and (min-height: 681px) {
  html:not([data-me="1"]) .hero__ctas .btn, html:not([data-me="1"]) .hero__have { --h: 56px; }
}
@media (min-width: 700px) and (max-width: 1023px) and (min-height: 681px) and (max-height: 760px) {
  html:not([data-me="1"]) .hero__ctas .btn, html:not([data-me="1"]) .hero__have { --h: 58px; }
}
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) and (max-height: 760px) {
  html:not([data-me="1"]) .hero__go { gap: 6px; }
  html:not([data-me="1"]) .hero__hint { padding: 3px 12px; font-size: 13.5px; }
}
@media (min-width: 600px) and (max-width: 1023px) and (min-height: 500px) and (max-height: 680px) {
  html:not([data-me="1"]) .hero__logo { width: clamp(150px, 30cqh, 260px); }
  html:not([data-me="1"]) .hero__tag { margin-top: 4px; }
  html:not([data-me="1"]) .hero__ctas { margin-top: 8px; }
  html:not([data-me="1"]) .hero__go { gap: 5px; }
  html:not([data-me="1"]) .hero__hint { font-size: 13px; }
}
/* phone (portrait, and narrow windows that are not phone landscape) */
@media (max-width: 599px) and (min-height: 500px), (max-width: 599px) and (orientation: portrait) {

  /* re-composed, not cropped: copy stack on top, horizon just under the CTAs, island low at 150% width
     (ski hill + town + one real penguin in the right third), per the §5.1 phone-p column */
  .hero { min-height: 700px; --horizon: 56.5cqh; --d-w: 150cqw; --d-left: -19cqw; --d-top: 60.5cqh; }
  .hero__copy { top: calc(var(--header-h) + 1.6cqh); width: calc(100% - 36px); }
  .hero__logo { width: 64cqw; }
  .hero__tag { margin-top: 12px; font-size: 8.2cqw; line-height: 1.02; }
  .hero__tag > span { display: block; }
  .hero__sub { margin-top: 10px; font-size: 15.5px; line-height: 1.42; padding: 0 4px; }
  .hero__ctas { margin-top: 18px; flex-direction: column; align-items: stretch; width: 100%; gap: 12px; }
  .hero__ctas .btn { width: 100%; --h: 56px; }
  .hero__go { gap: 8px; }
  .hero__hint { font-size: 13.5px; padding: 4px 12px; }
  .hero__have { --h: 46px; align-self: center; font-size: 16px; }
  .hero__notyou { margin-top: 12px; }
  .cloud--l { left: -22cqw; width: 62cqw; }
  .cloud--r { right: -34cqw; width: 70cqw; }
  .sea__art { width: 300cqw; }
  .near, .ship, .hopper { display: none; }
  .cast--orange, .cast--artist { display: none; }
  .cast--pair { --w: 22; }
  /* the phone shows the island's middle 13-79%: the reporter steps in front of the tree hill (phones have room below) */
  .cast--reporter { --fx: 70; --fy: 61; --w: 13.4; }
  .cast--me { --fx: 69.5; --fy: 61; --w: 21; }
  .nametag { font-size: 12px; padding: 3px 10px; }
  .jet { display: none; }
  #hero .gpuffle { width: 8cqw; animation-name: pufffly-p; animation-delay: -6.5s; }   /* its own path, whatever data-lane says */
  .hero__foot { bottom: max(12px, env(safe-area-inset-bottom)); padding: 0 12px; gap: 8px; }
  /* the badge takes the room the snow toggle leaves; on the narrowest phones its three items wrap onto two lines rather
     than push the toggle off screen (never cut: it carries the not-affiliated notice) */
  .badge-pill { font-size: 11.5px; padding: 8px 12px; gap: 6px; white-space: nowrap; letter-spacing: -.005em; flex: 0 1 auto; min-width: 0; flex-wrap: wrap; row-gap: 2px; }
  .cue { display: none; }
  .snow-toggle { width: 36px; height: 36px; padding: 0; justify-content: center; flex: none; }
  .snow-toggle span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }   /* visually hidden, still its name */

  .explore__inner { grid-template-columns: minmax(0, 1fr); gap: 18px; padding: 56px 0 40px; }
  .explore__head, .map, .sheet { grid-column: 1; grid-row: auto; }
  .sheet { contain: none; min-height: 0; display: grid; grid-template-columns: 42% 1fr; grid-template-rows: auto auto; border-radius: 22px; }
  .sheet__shot { grid-row: 1; grid-column: 1; min-height: 0; aspect-ratio: auto; margin: 10px 0 0 10px; border-radius: 14px; overflow: hidden; }
  .sheet__live { left: 6px; top: 6px; padding: 4px 8px; font-size: 10.5px; }
  .sheet__body { display: contents; }
  .sheet__title { grid-row: 1; grid-column: 2; align-self: center; padding: 12px 14px 0 12px; display: block; }
  .sheet__title img { display: none; }
  .sheet__title h3 { font-size: 26px; }
  .sheet__body > p { grid-column: 1 / -1; margin: 10px 14px 0 !important; font-size: 14px !important; line-height: 1.45 !important; }
  .sheet__chips, .sheet__tip { display: none !important; }
  .sheet__actions { grid-column: 1 / -1; padding: 12px 12px 12px !important; margin-top: 0 !important; }
  .sheet__actions .btn { --h: 46px; font-size: 16px; }
  .explore__head { display: block; }
  .dive-on .explore__inner { gap: 14px; padding-top: calc(var(--header-h) + 4px); padding-bottom: 14px; }
  .dive-on .lede { display: none; }
  .dive-on h2 { font-size: 34px; }
  .dive-on .cats { margin-top: 12px; }
  .dive-on .cats button { height: 44px; }
  .dive-on .cats button img { width: 32px; height: 32px; }
  .cats { flex-wrap: nowrap; overflow-x: auto; margin-inline: calc(-1 * var(--gutter)); padding: 4px var(--gutter) 8px; scrollbar-width: none; }
  .explore__head .cats { margin-inline: calc(-1 * var(--gutter)); }   /* the strip runs edge to edge (outranks the desktop reset) */
  .cats button { flex: 0 0 auto; }
  .map { border-radius: 22px; }
  /* 18 labels would bury a 350 px map: hotspot dots, with only the chosen place named */
  .map[data-cat="places"] .pin:not(.is-active) { width: 11px; height: 11px; padding: 0; font-size: 0; border-radius: 50%; translate: -50% -50%; box-shadow: 0 0 0 3px rgba(11,93,184,.6), 0 2px 6px rgba(6,33,63,.4); animation: ping 2.4s var(--ease-bob) infinite; }
  .map[data-cat="places"] .pin:not(.is-active)::after { display: none; }
  .pin.is-active { font-size: 12.5px; padding: 4px 9px 5px; }
  .sheet__actions .btn { flex: 1; }
  .band { padding: 64px 0; }
  .sec-head--row { align-items: start; flex-direction: column; gap: 0; }
  .rooms { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: 14px; margin-inline: calc(-1 * var(--gutter)); padding: 6px var(--gutter) 16px; scrollbar-width: none; }
  .room, .room--xl, .room--wide { flex: 0 0 86%; aspect-ratio: 1504 / 733; scroll-snap-align: center; }
  .room figcaption { left: 10px; bottom: 10px; padding: 6px 12px 6px 6px; }
  .room figcaption img { width: 40px; height: 32px; }
  .room figcaption b { font-size: 17px; }
  .game__meta { left: 10px; right: 10px; bottom: 10px; padding: 10px; gap: 10px; }
  .game__meta > img { width: 44px; height: 44px; }
  .game__meta b { font-size: 20px; }
  .game__meta > span:not(.btn) { font-size: 13px; }
  .game__meta .game__blurb { display: none; }
  .safe { padding-bottom: 120px; }
  .games { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: 14px; margin-inline: calc(-1 * var(--gutter)); padding: 6px var(--gutter) 16px; scrollbar-width: none; }
  .game { flex: 0 0 72%; height: 220px; scroll-snap-align: center; }
  .game--feature { flex-basis: 86%; height: 260px; }
  .strip { flex-direction: column; align-items: start; padding: 16px; }
  .strip__row { width: 100%; justify-content: start; }
  .puffle-row { grid-template-columns: repeat(4, minmax(0, 1fr)); row-gap: 18px; padding: 20px 12px; }
  .safe__grid { grid-template-columns: 1fr; gap: 28px; }
  .rules { grid-template-columns: 1fr 1fr; gap: 10px; }
  .rules li { grid-template-columns: 1fr; grid-template-rows: auto; justify-items: start; gap: 8px; padding: 14px; }
  .rules img { grid-row: auto; width: 44px; height: 44px; }
  .rules b { font-size: 18px; }
  .rules span { font-size: 13.5px; }
  .create-card { grid-template-columns: 1fr; padding: 28px 22px 26px; text-align: center; }
  .create-card__doll { width: 52%; margin: -10px auto 0; order: 0; }
  .balls { margin: 16px auto 20px; }
}
/* short phones (iPhone 13 mini to iPhone 15, 600-700 px tall), after the phone block so these win: the hero is one screen
   tall in the dive (700 px elsewhere), so its copy stack (a returning penguin's "Not you?" line included) tightens as on
   short laptops and the cast keeps clear of the footer pills; in the map section the
   kicker steps out, the gaps tighten and the place's text keeps two lines. Where even that cannot hold (a 320 px wide
   iPhone SE), home.js leaves the dive off. */
@media (max-width: 599px) and (max-height: 700px) {
  .dive-on .hero__tag { margin-top: 8px; }
  .dive-on .hero__sub { margin-top: 6px; }
  .dive-on .hero__ctas { margin-top: 14px; gap: 10px; }
  .dive-on .hero__ctas .btn { --h: 52px; }
  .dive-on .hero__go { gap: 6px; }
  .dive-on .hero__have { --h: 44px; }
  .dive-on .hero__logo { width: 56cqw; }
  .dive-on .hero__notyou { margin-top: 6px; }
  .dive-on .explore__inner { gap: 10px; }
  .dive-on .explore__head .eyebrow { display: none; }
  .dive-on .sheet__body > p { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .dive-on .sheet__actions { padding: 10px 12px !important; }
}

/* phone landscape */
@media (orientation: landscape) and (max-height: 499px) {
  /* art left 60%, CTA column right 40% (§5.1 phone-l); every plane re-anchored, nothing just cropped */
  .hero { min-height: 340px; --horizon: 47cqh; --d-w: 58cqw; --d-left: 2.5cqw; --d-top: 37cqh; }
  .hero__copy { left: auto; right: max(2.5cqw, env(safe-area-inset-right)); translate: 0 0; top: calc(var(--header-h) + 3cqh); width: 37cqw; padding: 14px 16px 16px; border-radius: 24px; align-items: center;
    background: linear-gradient(180deg, rgba(6,40,90,.46), rgba(6,33,63,.56)); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22), 0 18px 40px rgba(0,20,60,.3); backdrop-filter: blur(14px) saturate(1.3); }
  [data-me="1"] .hero__sub.me-only { display: none !important; }
  .hero__logo { width: 23cqw; }
  .hero__tag { font-size: 2.55cqw; margin-top: 8px; line-height: 1.04; }
  .hero__tag > span { display: block; }
  .hero__sub { display: none; }
  .hero__notyou { margin-top: 8px; font-size: 12.5px; padding: 5px 12px; }
  .hero__ctas { margin-top: 12px; flex-direction: column; align-items: stretch; gap: 9px; width: 100%; max-width: 300px; }
  /* the panel's content is 37cqw - 32px wide and its longest label (CREATE A FREE PENGUIN) 11 font sizes, so on small phones
     the labels shrink to fit it */
  .hero__ctas .btn { --h: 44px; width: 100%; padding: 0 12px; font-size: min(calc(var(--h) * .4), calc((37cqw - 56px) / 11)); }
  .hero__go { gap: 6px; }
  .hero__hint { font-size: 12.5px; padding: 3px 10px; }
  .hero__have { --h: 38px; align-self: center; padding: 0 12px; font-size: min(14px, calc((37cqw - 56px) / 11)); }
  .btn__ball { width: 24px; height: 24px; }
  .near { display: block; }
  .lighthouse { left: -27cqw; bottom: -16cqh; height: 122cqh; filter: blur(1.4px) saturate(.9) brightness(.94); }
  .ship { display: none; }
  .cloud--l { left: -6cqw; width: 24cqw; }
  .cloud--r { right: 30cqw; width: 22cqw; }
  .hopper { display: none; }
  .say--me { left: -35%; top: -14%; width: 70%; }
  .nametag { font-size: 11px; padding: 2px 9px; }
  .jet { width: 4.6cqw; }
  #hero .gpuffle { width: 2.8cqw; animation-name: pufffly-l; }   /* its own path, whatever data-lane says */
  .cue { display: none; }
  .hero__foot { bottom: max(10px, env(safe-area-inset-bottom)); padding: 0 max(14px, env(safe-area-inset-left)) 0 max(14px, env(safe-area-inset-left)); }
  .badge-pill { font-size: 11px; padding: 6px 12px; gap: 6px; }
  .hero__foot { justify-content: flex-start; gap: 10px; }
  .pin { font-size: 10px; padding: 3px 6px 4px; }
  .pin.is-active { font-size: 11.5px; padding: 4px 8px 5px; }
  /* small phones on their side: the map is too small for every name at once, so the others become dots (as on phones) */
  @media (max-width: 719px) {
    .map[data-cat="places"] .pin:not(.is-active) { width: 9px; height: 9px; padding: 0; font-size: 0; border-radius: 50%; translate: -50% -50%; box-shadow: 0 0 0 3px rgba(11,93,184,.6), 0 2px 6px rgba(6,33,63,.4); animation: ping 2.4s var(--ease-bob) infinite; }
    .map[data-cat="places"] .pin:not(.is-active)::after { display: none; }
  }
  /* narrower than 2:1 the lighthouse edge piece would stand in front of the sledding pair */
  @media (max-aspect-ratio: 2/1) { .near { display: none; } }
  .snow-toggle span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .snow-toggle { width: 34px; height: 34px; padding: 0; justify-content: center; }
  .explore__inner { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 18px 20px; padding-top: 64px; padding-bottom: 40px; }
  .explore__head { grid-column: 1 / -1; grid-row: 1; display: block; }
  .explore__head .cats { margin-top: 14px; }
  .map { grid-column: 1; grid-row: 2; border-radius: 20px; }
  .sheet { grid-column: 2; grid-row: 2; min-height: 0; }
  .sheet__shot { min-height: 70px; }
  .sheet__chips, .sheet__tip { display: none; }
  .sheet__body { padding: 12px 14px 14px; }
  .sheet__title img { width: 52px; height: 42px; }
  .sheet__title h3 { font-size: 24px; }
  .sheet__body > p { font-size: 13.5px; margin-top: 6px; line-height: 1.4; }
  .sheet__actions { gap: 8px; padding-top: 10px; }
  .sheet__actions .btn { --h: 40px; font-size: 15px; padding: 0 14px; }
  .rooms { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 160px; }
  .room, .room--xl, .room--wide { grid-column: span 1; grid-row: span 1; }
  .games { grid-template-columns: repeat(3, 1fr); grid-template-rows: none; grid-auto-rows: 170px; }
  .game--feature { grid-column: span 3; grid-row: span 1; }
  .puffle-row { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .safe__grid { grid-template-columns: minmax(0, 1fr); }
  .create-card { grid-template-columns: 34% minmax(0, 1fr); }
}

/* ------------------------------------------------------------------ reduced motion: still frames, no dive */
/* the narrowest phones: a touch smaller badge still fits beside the snow toggle on one line at 360 px (it wraps below) */
@media (max-width: 374px) { .badge-pill { font-size: 10.8px; padding: 7px 10px; gap: 5px; } }
/* very wide, short windows: the copy's buttons sit on the horizon, the only lane the Hydro Hopper has, so it would spend a
   third of its crossing behind them; it stays out there (the puffle and the jetpack still fly) */
@media (min-aspect-ratio: 14/5) and (max-height: 660px) { .hopper { display: none; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .snow { display: none; }
  .flyby { display: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .live, .badge-pill, .snow-toggle, .sheet__live, .game__meta, .room figcaption { backdrop-filter: none; }
}
