/* Styles for the games in assets/games-b.js. Kept out of index.html so two
   sessions are never editing the same stylesheet. Loaded after it, so it
   can override, but it should not need to. */


/* =======================================================================
   1. BUILD THE IGLOO
   Night on the ice. Blocks of clear ice drift past on the black water and
   the dome closes over from the bottom up; the last one leaves a doorway
   and the seal goes in. Everything here is prefixed ig- / .sc-iglu, because
   index.html is one stylesheet shared by fifty-odd games.
   ======================================================================= */
.sc-iglu{position:absolute;inset:0;overflow:hidden}
.ig-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#12224A 0%,#1E3A66 42%,#2F5D86 70%,#4E86A8 100%)}
.ig-aurora{position:absolute;left:-16%;right:-16%;top:9%;height:26%;opacity:.5;filter:blur(14px);
  background:linear-gradient(90deg,transparent,#6BE6B4 22%,#9AD8F5 52%,#B79BF0 78%,transparent);
  animation:igAur 15s ease-in-out infinite alternate}
.ig-aurora.b{top:20%;height:17%;opacity:.32;animation-duration:21s;animation-delay:-7s;
  background:linear-gradient(90deg,transparent,#B79BF0 30%,#6BE6B4 70%,transparent)}
@keyframes igAur{from{transform:translateX(-6%) skewY(-2deg) scaleY(.85)}
  to{transform:translateX(6%) skewY(2deg) scaleY(1.15)}}
.ig-moon{position:absolute;right:11%;top:5%;width:13%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 38% 34%,#FFFDF2,#E4EDF6 60%,rgba(228,237,246,0) 76%)}
.ig-star{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;
  animation:igTwinkle 3.4s ease-in-out infinite alternate}
@keyframes igTwinkle{from{opacity:.2}to{opacity:1}}
.ig-sea{position:absolute;left:0;right:0;bottom:0;height:20%;
  background:linear-gradient(180deg,#173C60,#0B2038)}
.ig-sea::after{content:'';position:absolute;left:0;right:0;top:14%;height:3px;opacity:.35;
  background:linear-gradient(90deg,transparent,#9AD8F5,transparent)}
.ig-berg{position:absolute;background:#DCEFFA;
  clip-path:polygon(0 100%,26% 22%,44% 46%,66% 4%,100% 100%);
  filter:drop-shadow(0 4px 6px rgba(10,30,60,.5))}
.ig-berg.one{left:2%;bottom:16%;width:17%;height:9%}
.ig-berg.two{right:4%;bottom:13%;width:13%;height:7%}
.ig-shelf{position:absolute;left:-5%;right:-5%;bottom:12%;height:34%;
  border-radius:22% 22% 0 0/12% 12% 0 0;
  background:linear-gradient(180deg,#9BBDD8 0%,#89ACCA 45%,#77A0BC 100%);
  box-shadow:inset 0 4px 0 rgba(255,255,255,.65)}
.ig-flake{position:absolute;top:-6%;border-radius:50%;background:#fff;opacity:.85;
  animation:igFall var(--fd,10s) linear infinite}
@keyframes igFall{from{transform:translateY(0)}to{transform:translateY(122vh)}}

/* THE OTHER BUILDERS. Two part-built igloos on the shelf behind, each with its
   own lot of blocks and its own marker board. They are the whole reason a
   perfectly good block can be the wrong one — without somebody else's igloo on
   screen, the ticket on a block answers a question nobody asked. */
/* scenery only — it sits above the field in the stacking order, so without
   this a block drifting over a neighbour's board would eat the tap */
.ig-other{position:absolute;z-index:3;pointer-events:none}
.ig-other.one{left:1%;bottom:34%;width:19%}
.ig-other.two{right:2%;bottom:36%;width:17%}
.ig-oth-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 4px 7px rgba(10,30,60,.4))}
/* the marker board is HTML, not SVG, so its letter keeps its own size however
   small the igloo behind it gets */
/* 43%, not 50% — the dome sits left of centre in the box, the lot of spare
   blocks fills the right of it, and the board belongs over the dome */
.ig-mark{position:absolute;left:43%;bottom:calc(72% - 3px);transform:translateX(-50%);
  z-index:2;display:grid;place-items:center;min-width:1.9em;padding:2px 8px 4px;
  border-radius:7px;background:#FFF6E2;border:3px solid #A2764A;color:#6B4A2A;
  font:900 clamp(17px,4.6vw,22px)/1.15 var(--font);white-space:nowrap;
  box-shadow:0 3px 7px rgba(10,30,60,.45)}
.ig-mark::after{content:'';position:absolute;left:50%;top:100%;margin-left:-3px;
  width:6px;height:20px;border-radius:0 0 3px 3px;background:#A2764A}
/* and ours, on its own post at the side of our igloo */
.ig-mine{position:absolute;right:12%;bottom:29%;z-index:7;pointer-events:none}
.ig-mine .ig-mark{position:relative;left:auto;bottom:auto;transform:none}

/* the igloo itself: twelve blocks clipped to a dome */
.ig-build{position:absolute;left:50%;transform:translateX(-50%);bottom:25%;
  filter:drop-shadow(0 6px 8px rgba(40,80,115,.35));
  width:54%;aspect-ratio:1/.68;z-index:5}
.ig-dome{position:absolute;inset:0;overflow:hidden;
  border-radius:50% 50% 7% 7%/74% 74% 7% 7%;
  background:rgba(255,255,255,.2);
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.6)}
.ig-blk{position:absolute;box-sizing:border-box;border-radius:5px;
  border:2px solid rgba(255,255,255,.92);
  background:linear-gradient(180deg,#FFFFFF,#DDF2FD);
  box-shadow:0 0 0 1.6px rgba(64,124,164,.4);
  opacity:0;transform:translateY(-26px) scale(.72);
  transition:opacity .3s ease,transform .44s var(--spring)}
.ig-blk.on{opacity:1;transform:none}
.ig-arch{position:absolute;left:50%;margin-left:-9%;bottom:-3%;width:18%;aspect-ratio:1/1.2;
  border-radius:50% 50% 4% 4%/66% 66% 4% 4%;background:#123354;
  box-shadow:0 0 0 5px #EAF7FE;opacity:0;transform:translateY(12px) scale(.55);
  transition:opacity .4s ease,transform .55s var(--spring)}
.sc-iglu.ig-built .ig-arch{opacity:1;transform:none}
.ig-glow{position:absolute;inset:0;border-radius:inherit;opacity:0;transition:opacity .9s ease;
  background:radial-gradient(circle at 50% 76%,rgba(255,214,110,.95),rgba(255,150,60,.3) 58%,transparent 76%)}
.sc-iglu.ig-cosy .ig-glow{opacity:1}
.sc-iglu.ig-cosy .ig-dome{filter:drop-shadow(0 0 18px rgba(255,206,61,.55))}

.ig-seal{position:absolute;left:3%;bottom:21%;width:34%;z-index:6;
  animation:igShiver 1.4s ease-in-out infinite;
  transition:transform 1.5s cubic-bezier(.4,0,.3,1),opacity .5s ease 1.05s}
.ig-seal-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 6px 8px rgba(10,30,60,.45))}
@keyframes igShiver{0%,100%{transform:translateX(0)}25%{transform:translateX(-2.5px)}
  75%{transform:translateX(2.5px)}}
.sc-iglu.ig-cosy .ig-seal{animation:none;transform:translate(95%,7%) scale(.5);opacity:0}

.ig-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(10,30,60,.4);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.ig-say.on{opacity:1;transform:none}
.ig-say.her{background:#FFE6EF;color:#8E3B5E}
.ig-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.ig-say.her::after{border-top-color:#FFE6EF}

/* what drifts past */
.ig-field{position:absolute;inset:0}
.ig-drift{position:absolute;right:-28%;width:26%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:igDrift var(--dur,6s) linear forwards}
@keyframes igDrift{from{transform:translateX(0)}to{transform:translateX(-152vw)}}
.ig-bob{display:block;animation:igBob 1.6s ease-in-out infinite alternate}
@keyframes igBob{from{transform:translateY(-5px) rotate(-3deg)}to{transform:translateY(5px) rotate(3deg)}}
.ig-svg{width:100%;height:auto;display:block;filter:drop-shadow(2px 5px 7px rgba(8,26,54,.55))}
/* written on the ticket in crayon, not cut into the ice */
.ig-letter{font:900 27px/1 var(--font);fill:#6B4A2A;text-anchor:middle}
.ig-drip{animation:igDrip 1.5s ease-in infinite}
.ig-drip.b{animation-delay:-.75s}
.ig-drip.c{animation-delay:-1.15s}
@keyframes igDrip{0%{transform:translateY(0);opacity:.95}100%{transform:translateY(13px);opacity:0}}
.ig-drift.ig-laid{animation:none;transform:translate(-18vw,24vh) scale(.28);opacity:0;
  transition:all .43s ease-in}
.ig-drift.ig-nope{animation-play-state:paused}
.ig-drift.ig-nope .ig-bob{animation:sceneJig .5s ease-in-out 2}
.ig-drift.ig-shrug .ig-bob{animation:shrugIt .7s var(--spring)}


/* =======================================================================
   2. UP TO THE TREEHOUSE
   The bridge stood on its end. Rungs blow down through the air, the ladder
   climbs the trunk, and the squirrel goes up it. Prefix th- / .sc-thouse.
   ======================================================================= */
.sc-thouse{position:absolute;inset:0;overflow:hidden}
.th-sky{position:absolute;inset:0;background:linear-gradient(178deg,#BFE8FA,#DFF1FB 44%,#F7F0DA)}
.th-sun{position:absolute;left:9%;top:5%;width:14%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,#FFF6CC,#FFCE3D 58%,transparent 72%)}
.th-cloud{position:absolute;height:15px;border-radius:999px;background:#fff;opacity:.9;
  animation:thDrift var(--wd,40s) linear infinite}
.th-cloud::before,.th-cloud::after{content:'';position:absolute;bottom:0;border-radius:50%;background:#fff}
.th-cloud::before{left:18%;width:38%;height:0;padding-bottom:38%}
.th-cloud::after{right:22%;width:28%;height:0;padding-bottom:28%}
@keyframes thDrift{from{transform:translateX(-32vw)}to{transform:translateX(122vw)}}
.th-far{position:absolute;left:-6%;right:-6%;bottom:14%;height:15%;
  border-radius:50% 50% 0 0/100% 100% 0 0;background:#8CBE79}
.th-grass{position:absolute;left:0;right:0;bottom:0;height:16%;
  background:linear-gradient(180deg,#82B76D,#5E9450)}
.th-trunk{position:absolute;left:70%;width:12%;bottom:9%;height:50%;z-index:2;
  border-radius:6px 6px 3px 3px;
  background:linear-gradient(90deg,#8A6234,#BE8B48 42%,#8A6234)}
.th-trunk::after{content:'';position:absolute;left:-60%;right:-60%;bottom:-4%;height:12%;
  border-radius:50%;background:#8A6234}
.th-bark{position:absolute;width:14%;border-radius:3px;background:rgba(90,60,26,.4)}
.th-bark.a{left:24%;top:14%;height:24%}
.th-bark.b{left:62%;top:44%;height:20%}
.th-crown{position:absolute;border-radius:50%;z-index:3;
  filter:drop-shadow(0 6px 10px rgba(40,80,40,.22))}
.th-crown.c1{left:47%;top:21%;width:33%;aspect-ratio:1/.82;background:#5FA854}
.th-crown.c2{left:65%;top:13%;width:29%;aspect-ratio:1/.86;background:#71C062}
.th-crown.c3{left:55%;top:31%;width:24%;aspect-ratio:1/.8;background:#4E9448}
.th-leaf{position:absolute;top:-4%;width:11px;height:8px;border-radius:60% 20% 60% 20%;
  background:#D8963A;opacity:.85;animation:thLeaf var(--ld,12s) linear infinite}
@keyframes thLeaf{0%{transform:translate(0,0) rotate(0)}
  50%{transform:translate(34px,52vh) rotate(180deg)}
  100%{transform:translate(-14px,112vh) rotate(360deg)}}

/* THE OTHER TREEHOUSES. Back in the wood, each with its letter on a board
   nailed to the wall — so a rung labelled for one of them is visibly for one
   of them and not just "the wrong letter". */
/* scenery only — rungs fall right through this band */
.th-nbr{position:absolute;z-index:2;pointer-events:none}
.th-nbr.one{left:1%;bottom:19%;width:26%}
.th-nbr.two{left:30%;bottom:21%;width:24%}
.th-nbr-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 5px 8px rgba(40,80,40,.22))}
/* the board is HTML so its letter keeps its size however far back the tree is */
.th-mark{position:absolute;z-index:3;pointer-events:none;display:grid;place-items:center;
  min-width:1.9em;padding:2px 8px 4px;border-radius:6px;
  background:#FFF6E2;border:3px solid #8E5F2B;color:#6B4A2A;
  font:900 clamp(16px,4.4vw,21px)/1.15 var(--font);white-space:nowrap;
  box-shadow:0 3px 6px rgba(60,40,15,.32)}
.th-nbr .th-mark{left:50%;top:48%;transform:translate(-50%,-50%)}

.th-house{position:absolute;left:55%;width:40%;bottom:54%;height:20%;z-index:5}
/* ours, on the wall beside the door */
.th-sign{left:50%;top:64%;transform:translate(-50%,-50%);z-index:3}
.th-roof{position:absolute;left:-7%;right:-7%;top:0;height:46%;
  background:linear-gradient(180deg,#D4664A,#A8442C);
  clip-path:polygon(50% 0,100% 100%,0 100%)}
.th-wall{position:absolute;left:4%;right:4%;top:42%;bottom:0;border-radius:3px;
  background:repeating-linear-gradient(180deg,#DCAA6C 0 7px,#C8944F 7px 14px);
  box-shadow:inset 0 0 0 2px rgba(120,80,30,.35)}
.th-win{position:absolute;left:6%;top:54%;width:20%;height:28%;border-radius:3px;
  background:linear-gradient(180deg,#8FD0EA,#BEE4F4);box-shadow:inset 0 0 0 2px #8E5F2B}
.th-doorway{position:absolute;left:74%;top:50%;width:22%;bottom:7%;overflow:hidden;
  border-radius:5px 5px 2px 2px;background:#42301E}
.th-owl{position:absolute;left:5%;right:5%;bottom:-46%;opacity:0;
  transition:bottom .8s var(--spring) .6s,opacity .5s ease .6s}
.th-owl-svg{width:100%;height:auto;display:block}
.sc-thouse.th-top .th-owl{bottom:0;opacity:1}
.th-doorleaf{position:absolute;left:74%;top:50%;width:22%;bottom:7%;
  border-radius:5px 5px 2px 2px;background:linear-gradient(90deg,#C08F52,#8E5F2B);
  box-shadow:inset 0 0 0 2px rgba(80,50,20,.4);
  transform-origin:left center;transition:transform .8s var(--spring) .45s}
.sc-thouse.th-top .th-doorleaf{transform:perspective(220px) rotateY(-82deg)}
.th-deck{position:absolute;left:-5%;right:-5%;bottom:-7%;height:8%;border-radius:3px;
  background:linear-gradient(180deg,#C08F52,#8E5F2B)}

.th-ladder{position:absolute;left:70%;width:12%;bottom:12%;height:42%;z-index:4;--n:0}
/* a ghost of the ladder that is not there yet, so a child can see where the
   rungs are going before the first one lands */
.th-ladder::before,.th-ladder::after{content:'';position:absolute;top:0;bottom:0;width:17%;
  border-radius:4px;border:2px dashed rgba(90,60,26,.32);box-sizing:border-box;
  transition:opacity .5s ease}
.th-ladder::before{left:0}
.th-ladder::after{right:0}
/* once the ladder is really there the guide has done its job */
.sc-thouse.th-built .th-ladder::before,.sc-thouse.th-built .th-ladder::after{opacity:0}
.th-rail{position:absolute;bottom:0;width:17%;border-radius:4px;
  background:linear-gradient(180deg,#C08F52,#8E5F2B);
  height:calc(var(--n) * 8.34%);transition:height .42s var(--spring)}
.th-rail.l{left:0}
.th-rail.r{right:0}
.th-rung{position:absolute;left:-17%;width:134%;height:3.2%;border-radius:4px;
  bottom:calc(var(--i) * 8.34% + 1%);
  background:linear-gradient(180deg,#F0C795,#C08F52 55%,#9A6A2E);
  box-shadow:0 2px 0 rgba(90,60,20,.35);animation:thNail .5s var(--spring)}
@keyframes thNail{from{transform:scaleX(.2) rotate(-14deg);opacity:0}to{transform:none;opacity:1}}

.th-squirrel{position:absolute;left:65%;width:19%;z-index:6;
  bottom:calc(9% + var(--up,0) * 3.5%);
  transition:bottom .55s var(--spring),left .8s ease-in-out}
.th-sq-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 5px 7px rgba(60,40,15,.35))}
.sc-thouse.th-top .th-squirrel{bottom:53.5%;left:65%;
  transition:bottom 1.7s cubic-bezier(.35,0,.3,1),left 1.7s cubic-bezier(.35,0,.3,1)}
.sc-thouse.th-top .th-sq-svg{animation:thCheer .5s ease-in-out 2.1s 4}
@keyframes thCheer{0%,100%{transform:rotate(0)}35%{transform:rotate(-7deg)}70%{transform:rotate(7deg)}}
.sc-thouse.th-built .th-ladder{animation:thGlow .6s ease-in-out 2}
@keyframes thGlow{0%,100%{filter:none}50%{filter:drop-shadow(0 0 10px rgba(255,206,61,.95))}}

/* The squirrel stands at left 65%, bottom 9% — exactly under this bubble,
   so he was invisible for the whole opening, and he is the character the
   story is about. Lifted clear of him; still clear of Mo at left 31%. */
.th-say{position:absolute;left:31%;right:3%;bottom:24%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(40,86,44,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.th-say.on{opacity:1;transform:none}
.th-say.her{background:#FFE6EF;color:#8E3B5E}
.th-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.th-say.her::after{border-top-color:#FFE6EF}

/* what blows down */
.th-field{position:absolute;inset:0}
.th-fly{position:absolute;top:-16%;width:28%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:thBlow var(--dur,6s) linear forwards}
@keyframes thBlow{from{transform:translateY(0)}to{transform:translateY(126vh)}}
.th-bob{display:block;animation:thBob 1.9s ease-in-out infinite alternate}
@keyframes thBob{from{transform:rotate(-8deg)}to{transform:rotate(8deg)}}
.th-svg{width:100%;height:auto;display:block;filter:drop-shadow(2px 5px 6px rgba(60,45,20,.4))}
/* written on the tied-on label, not branded into the wood */
.th-letter{font:900 32px/1 var(--font);fill:#6B4A2A;text-anchor:middle}
.th-crumb{animation:thCrumb 1.7s ease-in infinite}
@keyframes thCrumb{0%{transform:translateY(0);opacity:.9}100%{transform:translateY(11px);opacity:0}}
.th-fly.th-nailed{animation:none;transform:translate(26vw,-12vh) scale(.28);opacity:0;
  transition:all .43s ease-in}
.th-fly.th-nope{animation-play-state:paused}
.th-fly.th-nope .th-bob{animation:sceneJig .5s ease-in-out 2}
.th-fly.th-shrug .th-bob{animation:shrugIt .7s var(--spring)}


/* =======================================================================
   3. MEND THE ROOF
   Slates blow past on the wind and go back on one gap at a time. When the
   last gap shuts the rain runs off the eaves instead of through them — the
   rain does NOT stop, because Pip's line is about listening to it.
   Prefix rf- / .sc-rhouse (the old game's rf- names are all avoided).
   ======================================================================= */
.sc-rhouse{position:absolute;inset:0;overflow:hidden}
.rf-sky{position:absolute;inset:0;transition:background 1.6s ease;
  background:linear-gradient(180deg,#5E7488 0%,#7A93A6 36%,#A8BECB 66%,#C9DCE4 100%)}
.sc-rhouse.rf-dry .rf-sky{
  background:linear-gradient(180deg,#728EA6 0%,#95B2C4 36%,#BFD6E0 66%,#DCEBF2 100%)}
.rf-cloudbank{position:absolute;height:19px;border-radius:999px;background:#6E8496;opacity:.92;
  animation:rfDrift var(--wd,34s) linear infinite;transition:background 1.6s ease}
.rf-cloudbank::before,.rf-cloudbank::after{content:'';position:absolute;bottom:0;
  border-radius:50%;background:inherit}
.rf-cloudbank::before{left:16%;width:40%;height:0;padding-bottom:40%}
.rf-cloudbank::after{right:20%;width:30%;height:0;padding-bottom:30%}
@keyframes rfDrift{from{transform:translateX(-42vw)}to{transform:translateX(132vw)}}
.sc-rhouse.rf-dry .rf-cloudbank{background:#93A9B8}
.rf-hills{position:absolute;left:-6%;right:-6%;bottom:13%;height:16%;
  border-radius:50% 50% 0 0/100% 100% 0 0;background:#6F8C6A}
.rf-lawn{position:absolute;left:0;right:0;bottom:0;height:15%;
  background:linear-gradient(180deg,#7FB06C,#5C8D50)}
.rf-pool{position:absolute;bottom:4%;border-radius:50%;background:#6E93A8;opacity:.7}
.rf-pool.one{left:7%;width:21%;height:3.4%}
.rf-pool.two{right:9%;width:15%;height:2.8%}
.rf-drop{position:absolute;top:-9%;width:2px;border-radius:1px;
  background:linear-gradient(180deg,rgba(214,236,248,0),rgba(214,236,248,.92));
  animation:rfRain var(--rd,1s) linear infinite}
@keyframes rfRain{from{transform:translateY(0)}to{transform:translateY(118vh)}}

/* THE REST OF THE STREET. The delivery came for all three houses, so each one
   has its own letter chalked on its own roof and a slate chalked for next door
   is plainly next door's. They sit behind ours (z-index 3 against its 4) so the
   row reads as a street rather than three houses in a line. */
.rf-nbr{position:absolute;bottom:14%;z-index:3;pointer-events:none;aspect-ratio:1/1.1}
.rf-nbr.one{left:-2%;width:27%}
.rf-nbr.two{right:-2%;width:24%}
.rf-nroof{position:absolute;left:-8%;right:-8%;top:0;height:52%;
  clip-path:polygon(50% 0,100% 100%,0 100%);
  background:repeating-linear-gradient(180deg,#54697C 0 8px,#48596A 8px 16px)}
.rf-nwall{position:absolute;left:6%;right:6%;top:50%;bottom:0;border-radius:3px;
  background:linear-gradient(180deg,#EADCC0,#D2BE9A);
  box-shadow:inset 0 0 0 2px rgba(140,110,70,.3)}
.rf-ndoor{position:absolute;left:50%;margin-left:-13%;bottom:0;width:26%;height:60%;
  border-radius:4px 4px 0 0;background:linear-gradient(180deg,#A0573A,#7C3F27)}
/* the chalk mark itself — a wobbly ring round a letter, set off square, the
   same hand that chalked the slates */
.rf-chalkmark{position:absolute;left:50%;top:56%;
  transform:translate(-50%,-50%) rotate(-7deg);
  display:grid;place-items:center;width:2em;height:2em;border-radius:50%;
  border:2.5px solid rgba(244,248,234,.78);color:#F4F8EA;
  font:900 clamp(16px,4.3vw,20px)/1 var(--font);
  text-shadow:0 1px 3px rgba(20,34,46,.55)}
.rf-chalkmark.rf-ours{top:44%;font-size:clamp(17px,4.6vw,22px)}

.rf-cot{position:absolute;left:24%;width:52%;bottom:14%;height:38%;z-index:4}
.rf-gable{position:absolute;left:-8%;right:-8%;top:0;
  clip-path:polygon(0 100%,16% 0,84% 0,100% 100%);height:48%;
  background:repeating-linear-gradient(180deg,#54697C 0 9px,#48596A 9px 18px)}
/* the gap holds our letter all along; it only shows once a slate of ours is
   actually in it, so the mended roof visibly becomes OURS */
.rf-slot{position:absolute;border-radius:3px;background:#231F1C;
  display:grid;place-items:center;color:transparent;
  font:900 clamp(11px,2.9vw,15px)/1 var(--font);
  box-shadow:inset 0 3px 7px rgba(0,0,0,.65);transition:all .42s var(--spring)}
.rf-slot::after{content:'';position:absolute;left:50%;top:16%;width:2px;height:64%;margin-left:-1px;
  background:linear-gradient(180deg,rgba(186,224,244,.95),rgba(186,224,244,0));
  animation:rfThrough .8s linear infinite}
@keyframes rfThrough{0%{transform:translateY(-40%);opacity:0}
  30%{opacity:.95}100%{transform:translateY(60%);opacity:0}}
.rf-slot.on{background:linear-gradient(180deg,#70899B,#4E6478 42%,#3E4F63);
  color:rgba(244,248,234,.72);box-shadow:0 2px 0 rgba(28,42,56,.55)}
.rf-slot.on::after{display:none}
.rf-eave{position:absolute;left:-12%;right:-12%;top:calc(48% - 5px);height:9px;border-radius:5px;
  background:#3E4F63}
.rf-chimney{position:absolute;right:15%;top:-7%;width:11%;height:22%;border-radius:2px;z-index:-1;
  background:linear-gradient(90deg,#965944,#C4785C 42%,#864F3C)}
.rf-smoke{position:absolute;left:26%;top:-32%;width:48%;height:30%;border-radius:50%;
  filter:blur(4px);background:#DCE6EC;opacity:.4;animation:rfSmoke 3.6s ease-in-out infinite}
@keyframes rfSmoke{0%,100%{opacity:.2;transform:translateY(4px) scale(.8)}
  50%{opacity:.6;transform:translateY(-8px) scale(1.15)}}
.rf-front{position:absolute;left:6%;right:6%;top:48%;bottom:0;border-radius:3px;
  background:linear-gradient(180deg,#F2E5CB,#DDCAA6);
  box-shadow:inset 0 0 0 2px rgba(140,110,70,.32)}
.rf-pane{position:absolute;left:8%;top:11%;width:39%;height:52%;border-radius:4px;overflow:hidden;
  background:linear-gradient(180deg,#8FC8E2,#BCDFEF);box-shadow:inset 0 0 0 3px #A8794E;
  transition:background 1.2s ease}
.sc-rhouse.rf-dry .rf-pane{background:linear-gradient(180deg,#FFE6A2,#FFD277)}
.rf-mousey{position:absolute;left:11%;bottom:-5%;width:78%}
.rf-mouse-svg{width:100%;height:auto;display:block}
.sc-rhouse.rf-dry .rf-mousey{animation:rfBounce .5s var(--spring) 6}
@keyframes rfBounce{0%,100%{transform:translateY(0)}45%{transform:translateY(-7px)}}
.rf-frontdoor{position:absolute;right:11%;bottom:0;width:26%;height:56%;border-radius:5px 5px 0 0;
  background:linear-gradient(180deg,#B0603F,#8A462C);box-shadow:inset 0 0 0 2px rgba(90,45,25,.4)}
.rf-leak{position:absolute;width:4px;height:11px;border-radius:2px;background:rgba(152,207,236,.95);
  animation:rfLeak 1.1s linear infinite;transition:opacity .7s ease}
.rf-leak.one{left:25%;top:2%}
.rf-leak.two{left:55%;top:0;animation-delay:-.4s}
.rf-leak.three{left:78%;top:4%;animation-delay:-.8s}
@keyframes rfLeak{0%{transform:translateY(0);opacity:.95}100%{transform:translateY(48px);opacity:0}}
.sc-rhouse.rf-dry .rf-leak{opacity:0;animation:none}
.rf-spill{position:absolute;top:47%;width:5px;height:0;border-radius:3px;opacity:0;
  background:linear-gradient(180deg,rgba(166,218,242,.95),rgba(166,218,242,.05));
  transition:height .9s ease-out,opacity .5s ease}
.rf-spill.l{left:-10%}
.rf-spill.r{right:-10%}
.sc-rhouse.rf-dry .rf-spill{opacity:1;height:54%}

.rf-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(20,45,60,.4);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.rf-say.on{opacity:1;transform:none}
.rf-say.her{background:#FFE6EF;color:#8E3B5E}
.rf-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.rf-say.her::after{border-top-color:#FFE6EF}

/* what blows past on the wind */
.rf-field{position:absolute;inset:0}
.rf-fly{position:absolute;left:-26%;width:22%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:rfBlow var(--dur,6s) linear forwards}
@keyframes rfBlow{from{transform:translateX(0)}to{transform:translateX(152vw)}}
.rf-sway{display:block;animation:rfSway 1.5s ease-in-out infinite alternate}
@keyframes rfSway{from{transform:rotate(-10deg) translateY(-4px)}
  to{transform:rotate(10deg) translateY(4px)}}
.rf-svg{width:100%;height:auto;display:block;filter:drop-shadow(2px 5px 7px rgba(18,38,54,.5))}
/* chalk on slate: flat, no outline. An outlined letter reads as part of the
   object; a flat white one reads as something somebody wrote on it. */
.rf-letter{font:900 30px/1 var(--font);fill:#F4F8EA;text-anchor:middle}
.rf-drip{animation:rfDripFall 1.4s ease-in infinite}
@keyframes rfDripFall{0%{transform:translateY(0);opacity:.95}100%{transform:translateY(12px);opacity:0}}
.rf-fly.rf-fitted{animation:none;transform:translate(24vw,20vh) scale(.28);opacity:0;
  transition:all .43s ease-in}
.rf-fly.rf-nope{animation-play-state:paused}
.rf-fly.rf-nope .rf-sway{animation:sceneJig .5s ease-in-out 2}
.rf-fly.rf-shrug .rf-sway{animation:shrugIt .7s var(--spring)}


/* =======================================================================
   BUILD THE BRIDGE — the ownership layer                     id: bridge
   -----------------------------------------------------------------------
   The game itself is styled in index.html. Everything here is the second
   half of the choice: whose plank is it. Two other broken bridges away on
   the hills, each with its letter on a marker board, and ours on a board
   at the head of the gorge. Class names are all gg-* so nothing here can
   reach into another game's scene.
   ======================================================================= */

/* somebody else's bridge, still waiting for its own timber */
.gg-other{position:absolute;z-index:2;pointer-events:none}
.gg-other.one{left:2%;bottom:62%;width:27%}
.gg-other.two{left:34%;bottom:66%;width:23%}
.gg-oth-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 4px 7px rgba(40,60,90,.28))}
/* The marker board is HTML rather than part of the drawing, so its letter
   keeps its own readable size however small the bridge behind it is. */
.gg-mark{position:absolute;left:22%;bottom:72%;transform:translateX(-50%);
  z-index:3;display:grid;place-items:center;min-width:1.9em;padding:2px 8px 4px;
  border-radius:7px;background:#FFF6E2;border:3px solid #A2764A;color:#6B4A2A;
  font:900 clamp(17px,4.6vw,22px)/1.15 var(--font);white-space:nowrap;
  box-shadow:0 3px 7px rgba(40,60,90,.3)}
/* the post it is nailed to */
.gg-mark::after{content:'';position:absolute;left:50%;top:100%;margin-left:-3px;
  width:6px;height:20px;border-radius:0 0 3px 3px;background:#A2764A}

/* and ours, on the board at the head of the gorge — the post runs UP from it
   to the deck, so it belongs to the bridge the child is building */
.gg-mine{position:absolute;left:24%;bottom:32.5%;z-index:6;pointer-events:none}
.gg-mine .gg-mark{position:relative;left:auto;bottom:auto;transform:none;
  border-color:#8E5F2B;box-shadow:0 3px 9px rgba(10,25,40,.5)}
.gg-mine .gg-mark::after{top:auto;bottom:100%;height:40px;border-radius:3px 3px 0 0}

/* the docket nailed to a plank. Flat ink, no outline — an outlined letter
   reads as part of the object, a flat written one reads as somebody's mark. */
.gg-plank-letter{font:900 30px/1 var(--font);fill:#5A3E22;text-anchor:middle}
.gg-docket{transform-origin:55px 22px}


/* =======================================================================
   FIREWORKS NIGHT — the ownership layer                    id: fireworks
   -----------------------------------------------------------------------
   The game is styled in index.html; this is only the second half of the
   choice. Two other families' crates on the grass with their letters
   chalked on, ours beside them, and the taped-on paper label that carries
   the letter on a rocket. All fw-* so nothing here escapes the scene.
   ======================================================================= */

/* the boxes people carried up the hill, standing on the grass */
.fw-crate{position:absolute;z-index:6;pointer-events:none}
.fw-crate.one{left:35%;bottom:4%;width:16%}
.fw-crate.two{left:56%;bottom:4.5%;width:17%}
.fw-crate.fw-ours{left:77%;bottom:5%;width:18%}
.fw-crate-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 3px 8px rgba(4,8,24,.7))}
/* ours catches the light from the sky, so it is plainly the one we came with */
.fw-crate.fw-ours .fw-crate-svg{filter:drop-shadow(0 0 12px rgba(255,206,61,.55))
  drop-shadow(0 3px 8px rgba(4,8,24,.7))}
/* the letter is chalked on the side, in a chalked box somebody drew round it.
   HTML rather than part of the drawing, so it keeps a readable size. */
.fw-cmark{position:absolute;left:50%;top:60%;z-index:7;
  transform:translate(-50%,-50%) rotate(-4deg);
  display:grid;place-items:center;min-width:1.5em;padding:0 7px 2px;
  border:2.5px solid rgba(255,246,226,.9);border-radius:8px;
  color:#FFF6E2;font:900 clamp(17px,4.6vw,22px)/1.25 var(--font);
  text-shadow:0 1px 2px rgba(0,0,0,.6)}
.fw-crate.fw-ours .fw-cmark{border-color:#FFE49A;color:#FFF3C8;
  text-shadow:0 0 8px rgba(255,206,61,.8),0 1px 2px rgba(0,0,0,.6)}

/* the label taped to a rocket. Flat marker ink on paper — an outlined letter
   reads as part of the object, a flat written one reads as somebody's mark. */
.fw-ink{font:900 26px/1 var(--font);fill:#2E4E86;text-anchor:middle}
.fw-label{transform-origin:22px 46px}


/* =======================================================================
   THE ROCK POOL                                            id: rock-pool
   The tide is out. Creatures stranded on the wet sand drift past on the
   ebb; the ones with our letter on their shell go back in the pool and
   stay there, the rubbish gets shrugged off. Everything is rpx- prefixed,
   because index.html is one stylesheet shared by sixty games.
   ======================================================================= */
.rpx-scene{position:absolute;inset:0;overflow:hidden}
.rpx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#8ED2F2 0%,#B8E4F7 26%,#DFF2FA 46%)}
.rpx-sun{position:absolute;right:9%;top:7%;width:15%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFF3C0,#FFCE3D 58%,rgba(255,206,61,0) 74%)}
.rpx-cloud{position:absolute;left:-30%;height:26px;border-radius:20px;background:#FFF8EC;opacity:.85;
  animation:rpxCloud var(--wd,40s) linear infinite}
.rpx-cloud::after{content:'';position:absolute;left:22%;top:-52%;width:56%;height:150%;
  border-radius:50%;background:#FFF8EC}
@keyframes rpxCloud{from{transform:translateX(0)}to{transform:translateX(160vw)}}
/* the sea, well back — it has gone out and left the sand bare */
.rpx-sea{position:absolute;left:-6%;right:-6%;top:22%;height:14%;
  background:linear-gradient(180deg,#3E8FBF,#5FB1DD 62%,#7FC6E4)}
.rpx-wv{position:absolute;left:-10%;right:-10%;height:7px;border-radius:50%;
  background:rgba(255,255,255,.6);animation:rpxWave 5s ease-in-out infinite alternate}
.rpx-wv.a{bottom:22%}
.rpx-wv.b{bottom:52%;animation-duration:7s;animation-delay:-2s;opacity:.55}
@keyframes rpxWave{from{transform:translateX(-5%)}to{transform:translateX(5%)}}
.rpx-sand{position:absolute;left:-6%;right:-6%;top:35%;bottom:0;
  background:linear-gradient(180deg,#DCC69A 0%,#EFDDB6 22%,#F6E8CA 100%)}
/* wet ripples left by the tide, so the sand is not a flat beige block */
.rpx-sand::after{content:'';position:absolute;left:0;right:0;top:0;height:22%;opacity:.34;
  background:repeating-linear-gradient(180deg,rgba(95,177,221,.4) 0 2px,transparent 2px 17px)}
/* real rocks: flat-topped and faceted, not grey eggs */
.rpx-boulder{position:absolute;background:linear-gradient(180deg,#C3B8A2,#8E8574);
  clip-path:polygon(0 100%,10% 46%,34% 14%,62% 22%,90% 52%,100% 100%);
  box-shadow:0 6px 10px rgba(120,95,50,.18)}
.rpx-boulder::after{content:'';position:absolute;left:14%;top:14%;width:46%;height:46%;
  background:rgba(255,255,255,.28);
  clip-path:polygon(6% 100%,30% 0,100% 26%,62% 92%)}
.rpx-boulder.one{left:1%;top:45%;width:22%;height:8%}
.rpx-boulder.two{right:2%;top:47%;width:18%;height:6.5%}
/* the pool itself — the thing being filled, so the wanted-letter tag pins here */
.rpx-pool{position:absolute;left:50%;transform:translateX(-50%);bottom:9%;
  width:64%;height:28%;z-index:4}
.rpx-lip{position:absolute;inset:-7% -5%;border-radius:50%;
  background:linear-gradient(180deg,#C9BCA2,#9E937E);
  box-shadow:inset 0 4px 0 rgba(255,255,255,.4)}
.rpx-water{position:absolute;inset:6% 4%;border-radius:50%;
  background:radial-gradient(ellipse at 44% 34%,#8FE0F0,#3E9FC8 62%,#2A7EA6)}
.rpx-shine{position:absolute;left:16%;top:16%;width:34%;height:22%;border-radius:50%;
  background:rgba(255,255,255,.45);filter:blur(3px)}
.rpx-in{position:absolute;inset:8% 7%;z-index:5}
.rpx-in-bit{position:absolute;width:22%;transform:scale(var(--sw,1));
  animation:rpxSettle .6s var(--spring)}
.rpx-in-bit svg{width:100%;height:auto;display:block;
  animation:rpxBob var(--bob,2s) ease-in-out infinite alternate}
@keyframes rpxSettle{from{transform:scale(0) rotate(-30deg)}to{transform:scale(var(--sw,1))}}
@keyframes rpxBob{from{transform:translateY(-3px) rotate(-4deg)}to{transform:translateY(3px) rotate(4deg)}}
.rpx-weed{position:absolute;width:9%;height:13%;z-index:5;
  background:linear-gradient(180deg,#3E8F55,#6FBF6E);
  clip-path:polygon(38% 100%,10% 42%,30% 52%,18% 8%,46% 46%,52% 4%,64% 48%,84% 14%,74% 56%,96% 46%,62% 100%)}
/* clear of the rocks, tucked against the near edge of the pool */
.rpx-weed.a{left:9%;bottom:14%}
.rpx-weed.b{right:8%;bottom:12%;transform:scaleX(-1)}
/* the tide coming back in over the sand — the ending */
.rpx-swash{position:absolute;left:-6%;right:-6%;top:35%;height:0;z-index:3;
  background:linear-gradient(180deg,rgba(62,143,191,.9),rgba(143,205,232,.55));
  transition:height 1.8s ease-in-out}
/* the line of foam only exists once the water is actually moving up the beach —
   at height 0 it was a hard white bar sitting across the dry sand */
.rpx-swash::after{content:'';position:absolute;left:0;right:0;bottom:-4px;height:9px;
  border-radius:50%;background:rgba(255,255,255,.75);opacity:0;transition:opacity .9s ease}
.rpx-scene.rpx-tide .rpx-swash::after{opacity:1}
.rpx-scene.rpx-tide .rpx-swash{height:22%}
.rpx-scene.rpx-tide .rpx-sand{transition:filter 1.6s ease;filter:brightness(.96) saturate(1.1)}
.rpx-pool.rpx-alive .rpx-water{animation:rpxSparkle 1.5s ease-in-out infinite alternate}
.rpx-pool.rpx-alive{filter:drop-shadow(0 0 24px rgba(120,225,250,.9))}
.rpx-pool.rpx-alive .rpx-in-bit{animation:rpxCheer .5s var(--spring) 8}
@keyframes rpxSparkle{from{filter:brightness(1)}to{filter:brightness(1.22)}}
@keyframes rpxCheer{0%,100%{transform:scale(var(--sw,1))}50%{transform:scale(calc(var(--sw,1) * 1.22)) rotate(8deg)}}

.rpx-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(20,60,80,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.rpx-say.on{opacity:1;transform:none}
.rpx-say.her{background:#FFE6EF;color:#8E3B5E}
.rpx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.rpx-say.her::after{border-top-color:#FFE6EF}

/* what the ebb carries past */
.rpx-field{position:absolute;inset:0;z-index:7}
.rpx-bit{position:absolute;right:-30%;width:26%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:rpxDrift var(--dur,6s) linear forwards}
@keyframes rpxDrift{from{transform:translateX(0)}to{transform:translateX(-156vw)}}
.rpx-bob{display:block;animation:rpxSway 1.7s ease-in-out infinite alternate}
@keyframes rpxSway{from{transform:translateY(-5px) rotate(-4deg)}to{transform:translateY(5px) rotate(4deg)}}
.rpx-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(20,60,80,.35))}
/* a marking on the shell — flat, no outline, so it reads as part of the animal.
   26 units in a 64-wide box shown at 26% of the stage = a 43px letter. */
.rpx-ink{font:900 26px/1 var(--font);fill:#3B2A1E;text-anchor:middle}
.rpx-junk .rpx-svg{filter:drop-shadow(2px 5px 6px rgba(20,60,80,.25)) saturate(.8)}
.rpx-bit.rpx-saved{animation:none;transform:translate(-14vw,26vh) scale(.3);opacity:0;
  transition:all .4s ease-in}
.rpx-bit.rpx-tossed{animation:none;transform:translateY(-16vh) rotate(40deg) scale(.5);opacity:0;
  transition:all .68s ease-out}
.rpx-bit.rpx-nope{animation-play-state:paused}
.rpx-bit.rpx-nope .rpx-bob{animation:sceneJig .5s ease-in-out 2}


/* =======================================================================
   DIG FOR THE BONES                                        id: dig-bones
   THE STILL GAME. Nothing on this screen travels, on purpose — some
   children cannot chase a moving target yet, and this is the turn that
   is theirs. Six big patches of dug earth, a thing poking out of each,
   and all the time in the world. Everything dgx- prefixed.
   ======================================================================= */
.dgx-scene{position:absolute;inset:0;overflow:hidden}
.dgx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#9BD9F5 0%,#C4E9F9 24%,#E4F4FB 40%)}
.dgx-sun{position:absolute;right:8%;top:6%;width:15%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFF3C0,#FFCE3D 58%,rgba(255,206,61,0) 74%)}
.dgx-cloud{position:absolute;left:-30%;height:26px;border-radius:20px;background:#FFF8EC;opacity:.85;
  animation:dgxCloud var(--wd,40s) linear infinite}
.dgx-cloud::after{content:'';position:absolute;left:22%;top:-52%;width:56%;height:150%;
  border-radius:50%;background:#FFF8EC}
@keyframes dgxCloud{from{transform:translateX(0)}to{transform:translateX(160vw)}}
.dgx-hedge{position:absolute;left:-4%;right:-4%;top:22%;height:11%;border-radius:28% 28% 0 0/60% 60% 0 0;
  background:linear-gradient(180deg,#5E9F4E,#3E7A38)}
.dgx-fence{position:absolute;left:-4%;right:-4%;top:28%;height:7%;
  background:repeating-linear-gradient(90deg,#C99A5E 0 12px,transparent 12px 26px)}
.dgx-fence::after{content:'';position:absolute;left:0;right:0;top:38%;height:5px;background:#B0864C}
.dgx-tree{position:absolute;left:1%;top:5%;width:26%;height:29%}
.dgx-trunk{position:absolute;left:44%;bottom:0;width:12%;height:46%;border-radius:3px;
  background:linear-gradient(90deg,#8A5230,#A8703E)}
.dgx-leaves{position:absolute;left:0;right:0;top:0;height:64%;border-radius:50% 50% 44% 44%;
  background:radial-gradient(circle at 36% 30%,#7FC55E,#4E8F42)}
.dgx-lawn{position:absolute;left:-4%;right:-4%;top:33%;bottom:0;
  background:linear-gradient(180deg,#7FC55E 0%,#8AD37F 26%,#A2DE8E 100%)}
/* the strip of turned earth the patches sit in */
.dgx-earth{position:absolute;left:-4%;right:-4%;top:46%;height:43%;
  background:linear-gradient(180deg,#9C6E3E,#8A6234 40%,#7A5630);
  border-radius:26% 26% 18% 18%/16% 16% 10% 10%;
  box-shadow:inset 0 5px 0 rgba(255,255,255,.14)}

.dgx-plot{position:absolute;left:2%;right:2%;top:47%;height:40%;z-index:5}
.dgx-mound{position:absolute;width:29%;height:46%;border:0;background:transparent;padding:0;
  cursor:pointer;transition:transform .16s var(--spring)}
.dgx-mound:active{transform:scale(.94)}
.dgx-svg{width:100%;height:100%;display:block;overflow:visible;
  filter:drop-shadow(1px 4px 5px rgba(60,45,20,.34))}
/* written on the bone end that is still above ground — 23 units in an 80-wide
   box, which is a 34px letter on a 402px phone */
/* 26 units in an 80-wide box shown at 29% of the stage = a 36px letter on a
   402px phone. Kept at 26 as the raw number too, so choices.test.mjs — which
   reads the CSS font-size, not the scaled one — measures it honestly. */
.dgx-ink{font:900 26px/1 var(--font);fill:#6B4A2A;text-anchor:middle}
.dgx-mound.dgx-fresh .dgx-svg{animation:dgxPop .46s var(--spring)}
@keyframes dgxPop{from{transform:translateY(16px) scale(.7);opacity:0}to{transform:none;opacity:1}}
.dgx-mound.dgx-dug-out .dgx-svg{animation:dgxOut .3s ease-in forwards}
@keyframes dgxOut{to{transform:translateY(-26px) scale(.6);opacity:0}}
.dgx-mound.dgx-shrug .dgx-svg{animation:shrugIt .62s var(--spring)}
.dgx-plot.dgx-over .dgx-mound{opacity:.55;pointer-events:none;transition:opacity .5s}
.dgx-clod{position:absolute;width:9px;height:9px;border-radius:50%;background:#6E4C26;
  pointer-events:none;z-index:8;animation:dgxClod 1s ease-out forwards}
@keyframes dgxClod{from{transform:translate(0,0) scale(1);opacity:1}
  to{transform:translate(var(--sx,0),var(--sy,-40px)) scale(.3);opacity:0}}

.dgx-pup{position:absolute;right:3%;top:33%;width:27%;z-index:7;
  transition:transform .9s var(--spring)}
.dgx-pup-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 5px 7px rgba(60,80,40,.28))}
.dgx-tail{transform-origin:78px 60px;animation:dgxWag 1.1s ease-in-out infinite alternate}
@keyframes dgxWag{from{transform:rotate(-12deg)}to{transform:rotate(16deg)}}
.dgx-pup.dgx-joy{transform:translate(-14%,33vh) scale(1.08);
  filter:drop-shadow(0 0 18px rgba(255,206,61,.75))}
.dgx-pup.dgx-joy .dgx-pup-svg{animation:dgxBound .58s var(--spring) 8}
.dgx-pup.dgx-joy .dgx-tail{animation-duration:.2s}
@keyframes dgxBound{0%,100%{transform:translateY(0) rotate(0)}
  40%{transform:translateY(-16px) rotate(-7deg)}70%{transform:translateY(-4px) rotate(5deg)}}

.dgx-bowl{position:absolute;right:2%;bottom:2%;width:32%;z-index:6}
.dgx-bowl-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 4px 6px rgba(60,45,20,.3))}
.dgx-heap{position:absolute;left:8%;right:8%;bottom:16%;height:64%}
.dgx-bone-in{position:absolute;width:38%;transform:rotate(var(--rt,0));
  animation:dgxDrop .5s var(--spring)}
.dgx-bone-in svg{width:100%;height:auto;display:block}
@keyframes dgxDrop{from{transform:translateY(-46px) rotate(0) scale(.5);opacity:0}
  to{transform:rotate(var(--rt,0));opacity:1}}
.dgx-bowl.dgx-clink .dgx-bowl-svg{animation:dgxClink .3s var(--spring)}
@keyframes dgxClink{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
.dgx-bowl.dgx-full{filter:drop-shadow(0 0 16px rgba(255,206,61,.85))}

.dgx-say{position:absolute;left:31%;right:3%;bottom:15%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(40,70,30,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.dgx-say.on{opacity:1;transform:none}
.dgx-say.her{background:#FFE6EF;color:#8E3B5E}
.dgx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.dgx-say.her::after{border-top-color:#FFE6EF}


/* =======================================================================
   THE SCARECROW                                            id: scarecrow
   Harvest week. The village clothes box got shared out, so what blows
   across the field belongs to three different scarecrows — ours and the
   two standing out in the corn with their letters on marker boards. All
   crx- prefixed.
   ======================================================================= */
.crx-scene{position:absolute;inset:0;overflow:hidden}
.crx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#8FD2F0 0%,#BEE6F6 22%,#EAF3E0 42%)}
.crx-sun{position:absolute;right:8%;top:6%;width:15%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFF3C0,#FFCE3D 58%,rgba(255,206,61,0) 74%)}
.crx-cloud{position:absolute;left:-30%;height:26px;border-radius:20px;background:#FFF8EC;opacity:.85;
  animation:crxCloud var(--wd,40s) linear infinite}
.crx-cloud::after{content:'';position:absolute;left:22%;top:-52%;width:56%;height:150%;
  border-radius:50%;background:#FFF8EC}
@keyframes crxCloud{from{transform:translateX(0)}to{transform:translateX(160vw)}}
.crx-hills{position:absolute;left:-8%;right:-8%;top:24%;height:12%;
  border-radius:46% 46% 0 0/100% 100% 0 0;
  background:linear-gradient(180deg,#7FAE5E,#5E8F48)}
/* the barn — its roof is on ::after so nothing clips a letter above it */
.crx-barn{position:absolute;left:4%;top:21%;width:21%;height:12%}
.crx-barn-wall{position:absolute;left:6%;right:6%;bottom:0;height:62%;border-radius:2px;
  background:linear-gradient(180deg,#C9463A,#A8352B)}
.crx-barn-roof{position:absolute;left:0;right:0;top:0;height:42%;
  background:#8E2E26;clip-path:polygon(50% 0,100% 100%,0 100%)}
.crx-barn-door{position:absolute;left:38%;bottom:0;width:24%;height:38%;border-radius:3px 3px 0 0;
  background:#6B2A22}
/* the standing corn everything is planted in */
.crx-corn{position:absolute;left:-4%;right:-4%;top:33%;bottom:0;
  background:linear-gradient(180deg,#E2C864 0%,#EBD57C 26%,#F3E29C 100%)}
.crx-corn::after{content:'';position:absolute;inset:0;opacity:.4;
  background:repeating-linear-gradient(96deg,rgba(180,150,50,.55) 0 2px,transparent 2px 13px)}

/* THE OTHER TWO SCARECROWS, back in the corn, each with its own letter on a
   marker board — so a labelled coat is visibly for one of THEM and not just
   "the wrong letter". Scenery only: pieces blow right past them. */
.crx-nbr{position:absolute;z-index:3;pointer-events:none}
.crx-nbr.one{left:1%;top:50%;width:19%}
.crx-nbr.two{right:1%;top:53%;width:17%}
.crx-oth-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 5px 8px rgba(120,100,40,.25))}
/* the board is HTML, not part of the drawing, so its letter keeps a readable
   size however far back in the field the scarecrow stands */
.crx-mark{position:absolute;z-index:4;pointer-events:none;display:grid;place-items:center;
  min-width:1.9em;padding:2px 8px 4px;border-radius:6px;
  background:#FFF6E2;border:3px solid #8E5F2B;color:#6B4A2A;
  font:900 clamp(16px,4.4vw,21px)/1.15 var(--font);white-space:nowrap;
  box-shadow:0 3px 6px rgba(90,60,20,.3)}
.crx-nbr .crx-mark{left:50%;top:76%;transform:translate(-50%,-50%)}
.crx-mark.crx-ours{left:81%;top:69%;transform:translate(-50%,-50%) rotate(-3deg);z-index:6;
  border-color:#C9463A;box-shadow:0 0 12px rgba(255,206,61,.7),0 3px 6px rgba(90,60,20,.3)}
/* ours is nailed to a stake in the ground, not floating in the corn */
.crx-mark.crx-ours::before{content:'';position:absolute;left:50%;top:82%;margin-left:-5px;
  width:10px;height:54px;border-radius:2px;z-index:-1;
  background:linear-gradient(90deg,#8A5230,#B07C46 55%,#8A5230)}

/* ours */
.crx-crow{position:absolute;left:50%;transform:translateX(-50%);top:42%;width:50%;z-index:5}
.crx-man-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 6px 9px rgba(120,100,40,.32))}
/* every part waits its turn and springs in when it is fitted */
/* the parts still to come show as a pale ghost, so a child can see what they
   are making from the very first tap rather than an empty field */
.crx-p{opacity:.14;transform:translateY(-14px) scale(.9);transform-origin:50% 50%;
  transition:opacity .34s ease,transform .44s var(--spring)}
.crx-p.on{opacity:1;transform:none}
.crx-crow.crx-alive{animation:crxAlive .8s var(--spring) 5;
  filter:drop-shadow(0 0 22px rgba(255,206,61,.8))}
@keyframes crxAlive{0%,100%{transform:translateX(-50%) rotate(0)}
  30%{transform:translateX(-50%) rotate(-4deg)}70%{transform:translateX(-50%) rotate(4deg)}}

.crx-bird{position:absolute;width:9%;z-index:6;pointer-events:none;
  animation:crxPeck 1.5s ease-in-out infinite alternate}
.crx-crow-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 3px 4px rgba(90,70,20,.3))}
@keyframes crxPeck{0%,60%{transform:rotate(0)}80%{transform:rotate(11deg)}100%{transform:rotate(0)}}
.crx-wing{transform-origin:40px 22px}
.crx-bird.crx-flown{animation:crxFly 1.5s ease-in forwards}
@keyframes crxFly{to{transform:translate(var(--fx,60vw),-80vh) rotate(-14deg);opacity:0}}
.crx-bird.crx-flown .crx-wing{animation:crxFlap .18s ease-in-out infinite alternate}
@keyframes crxFlap{from{transform:rotate(-24deg)}to{transform:rotate(26deg)}}

.crx-need{position:absolute;left:50%;transform:translateX(-50%);top:17%;z-index:9;
  background:#FFF8EC;border-radius:999px;padding:5px 15px 7px;color:#6B4A2A;
  font:800 clamp(14px,4vw,19px)/1.2 var(--font);white-space:nowrap;
  box-shadow:0 4px 10px rgba(90,60,20,.26)}
.crx-need b{color:#C9463A}
.crx-need.crx-gone{opacity:0;transition:opacity .4s}

.crx-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:10;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(90,70,20,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.crx-say.on{opacity:1;transform:none}
.crx-say.her{background:#FFE6EF;color:#8E3B5E}
.crx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.crx-say.her::after{border-top-color:#FFE6EF}

/* what blows across the field */
.crx-field{position:absolute;inset:0;z-index:8}
.crx-bit{position:absolute;right:-32%;width:28%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:crxBlow var(--dur,6s) linear forwards}
@keyframes crxBlow{from{transform:translateX(0)}to{transform:translateX(-160vw)}}
.crx-blow{display:block;position:relative;animation:crxTumble 1.9s ease-in-out infinite alternate}
@keyframes crxTumble{from{transform:translateY(-6px) rotate(-5deg)}to{transform:translateY(6px) rotate(5deg)}}
.crx-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(90,70,20,.34))}
/* the letter is HTML sitting on the drawn paper label, so it keeps a readable
   size whatever the piece does — 29px on a 402px phone */
.crx-tag{position:absolute;left:75%;top:63%;z-index:2;pointer-events:none;
  transform:translate(-50%,-50%) rotate(9deg);
  font:900 clamp(22px,7.2vw,30px)/1 var(--font);color:#5A3E22}
.crx-drip{animation:crxDrip 1.4s ease-in infinite}
.crx-drip.b{animation-delay:-.5s}
.crx-drip.c{animation-delay:-.95s}
@keyframes crxDrip{0%{transform:translateY(0);opacity:.95}100%{transform:translateY(11px);opacity:0}}
.crx-bit.crx-fitted{animation:none;transform:translate(-22vw,-8vh) scale(.3);opacity:0;
  transition:all .42s ease-in}
.crx-bit.crx-drop{animation:none;transform:translateY(22vh) rotate(28deg) scale(.6);opacity:0;
  transition:all .68s ease-in}
.crx-bit.crx-nope{animation-play-state:paused}
.crx-bit.crx-nope .crx-blow{animation:sceneJig .5s ease-in-out 2}


/* =======================================================================
   THE MARKET                                                  id: market
   Saturday morning. Mo's written list runs down the left and gets a red
   pencil through it a line at a time; the trader's crates come along the
   stall front with hand-written tickets on them. Ours carry our letter,
   and the two women at the stall have theirs on their own baskets. All
   mkx- prefixed — index.html is one stylesheet shared by sixty games.
   ======================================================================= */
.mkx-scene{position:absolute;inset:0;overflow:hidden}
.mkx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#8FD2F0 0%,#C4E6F4 26%,#F0E4C8 52%,#E4D2AE 100%)}
/* bunting strung across the stalls */
.mkx-bunt{position:absolute;left:23%;right:0;top:1%;height:7%}
.mkx-bunt::before{content:'';position:absolute;left:0;right:0;top:16%;height:2px;
  border-radius:2px;background:#B08A52}
.mkx-bunt i{position:absolute;top:16%;width:6.4%;height:66%;
  left:calc(var(--i) * 8.6%);
  background:#F0604A;clip-path:polygon(0 0,100% 0,50% 100%);
  transform-origin:50% 0;animation:mkxFlag 2.6s ease-in-out infinite alternate;
  animation-delay:calc(var(--i) * -.22s)}
.mkx-bunt i:nth-child(3n+2){background:#FFD75E}
.mkx-bunt i:nth-child(3n+3){background:#8AD37F}
@keyframes mkxFlag{from{transform:rotate(-4deg)}to{transform:rotate(4deg)}}
.mkx-scene.mkx-done .mkx-bunt i{animation-duration:.5s}

/* the stalls behind — awning on posts with the trader's board under it */
.mkx-stall{position:absolute;height:33%}
.mkx-stall.one{left:25%;top:6%;width:36%}
.mkx-stall.two{right:1%;top:8%;width:33%}
.mkx-awn{position:absolute;left:0;right:0;top:0;height:26%;border-radius:5px 5px 0 0;
  background:repeating-linear-gradient(90deg,#E8543C 0 11%,#FFF8EC 11% 22%);
  box-shadow:0 3px 5px rgba(90,60,20,.22)}
.mkx-awn::after{content:'';position:absolute;left:0;right:0;top:100%;height:13%;
  background:repeating-linear-gradient(90deg,#E8543C 0 11%,#FFF8EC 11% 22%);
  clip-path:polygon(0 0,100% 0,100% 20%,94% 100%,89% 20%,83% 100%,78% 20%,
    72% 100%,67% 20%,61% 100%,56% 20%,50% 100%,45% 20%,39% 100%,34% 20%,
    28% 100%,23% 20%,17% 100%,12% 20%,6% 100%,1% 20%,0 40%)}
.mkx-post{position:absolute;top:25%;bottom:0;width:3.4%;border-radius:2px;
  background:linear-gradient(90deg,#8A5230,#B07C46 55%,#8A5230)}
.mkx-post.l{left:4%}
.mkx-post.r{right:4%}
.mkx-board{position:absolute;left:2%;right:2%;bottom:0;height:20%;border-radius:3px;
  background:linear-gradient(180deg,#D9A05B,#B07C46);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.35);
  display:flex;align-items:flex-start;justify-content:space-around}
.mkx-board i{display:block;width:21%;position:relative;top:-13px}
.mkx-cobbles{position:absolute;left:0;right:0;top:42%;bottom:0;background:#DCC9A4;
  box-shadow:0 -8px 14px rgba(200,175,130,.55)}
.mkx-cobbles::after{content:'';position:absolute;inset:0;opacity:.35;
  background:radial-gradient(ellipse 16px 8px at 12px 10px,#C4AE84 60%,transparent 62%),
             radial-gradient(ellipse 16px 8px at 40px 26px,#C4AE84 60%,transparent 62%);
  background-size:56px 36px}

/* the two other shoppers, each with her letter on her own basket */
.mkx-shop{position:absolute;z-index:3;pointer-events:none}
.mkx-shop.one{left:25.5%;top:29%;width:14%}
.mkx-shop.two{right:2%;top:31%;width:13%}
.mkx-shop-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 4px 6px rgba(90,60,20,.24))}
/* the tag is HTML, not part of the drawing, so its letter keeps a readable
   size however small the shopper is drawn */
.mkx-mark{position:absolute;z-index:4;pointer-events:none;display:grid;place-items:center;
  min-width:1.7em;padding:1px 6px 3px;border-radius:5px;
  background:#FFF8EC;border:2.6px solid #B08A52;color:#6B4A2A;
  font:900 clamp(15px,4.2vw,20px)/1.15 var(--font);white-space:nowrap;
  box-shadow:0 2px 5px rgba(90,60,20,.3)}
.mkx-shop .mkx-mark{left:50%;top:72%;transform:translate(-50%,-50%)}
.mkx-mark.mkx-ours{left:50%;top:56%;transform:translate(-50%,-50%) rotate(-4deg);z-index:8;
  border-color:#C93B2A;
  box-shadow:0 0 12px rgba(255,206,61,.75),0 2px 5px rgba(90,60,20,.3)}

/* MO'S LIST — the whole point of the game. Twelve pictures of shopping, each
   one getting a red pencil through it, so what is left to do can be read at a
   glance instead of being a row of dots. */
.mkx-list{position:absolute;left:1.5%;top:11%;width:22%;bottom:25%;z-index:6;
  display:flex;flex-direction:column;padding:5px 4px 6px;border-radius:4px;
  background:#FFFBF0;border:1px solid #E4CFA8;transform:rotate(-1.2deg);
  box-shadow:0 5px 12px rgba(90,60,20,.28)}
.mkx-list>b{display:block;text-align:center;color:#B0532A;
  font:900 clamp(10px,3vw,13px)/1.3 var(--font);
  border-bottom:2px solid #E4CFA8;padding-bottom:2px;margin-bottom:2px}
.mkx-item{position:relative;flex:1;display:flex;align-items:center;gap:2px;
  color:#5A4636;font:800 clamp(9px,2.7vw,12px)/1 var(--font);
  padding:0 1px;border-radius:3px}
.mkx-ico{flex:0 0 auto;width:26%;max-width:22px;display:block}
.mkx-ico-svg{width:100%;height:auto;display:block}
.mkx-item.mkx-now{background:#FFF0B8;box-shadow:0 0 0 2px #FFD75E}
.mkx-item.mkx-got{opacity:.5}
/* the red pencil line, drawn on rather than switched on, so it reads as
   somebody scoring the line out */
.mkx-item.mkx-got::after{content:'';position:absolute;left:2%;top:52%;height:2.4px;
  border-radius:2px;background:#C93B2A;width:96%;transform-origin:0 50%;
  animation:mkxCross .34s ease-out}
@keyframes mkxCross{from{transform:scaleX(0) rotate(-2deg)}to{transform:scaleX(1) rotate(-2deg)}}
/* the box has to be SQUARE or the two strokes come out as two red bricks —
   the list is tall and narrow, so a percentage height is nothing like a
   percentage width */
.mkx-tick{position:absolute;left:50%;top:50%;width:88%;aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.2) rotate(-12deg);opacity:0;
  transition:all .5s var(--spring)}
.mkx-tick i{position:absolute;border-radius:4px;background:#C93B2A;opacity:.9}
.mkx-tick i:first-child{left:12%;top:46.5%;width:34%;height:11%;transform:rotate(48deg);
  transform-origin:0 50%}
.mkx-tick i:last-child{left:34.7%;top:71.8%;width:76%;height:11%;transform:rotate(-52deg);
  transform-origin:0 50%}
.mkx-scene.mkx-done .mkx-tick{opacity:1;transform:translate(-50%,-50%) scale(1) rotate(-8deg)}

.mkx-need{position:absolute;left:62%;transform:translateX(-50%);top:19%;z-index:9;
  background:#FFF8EC;border-radius:999px;padding:4px 14px 6px;color:#6B4A2A;
  font:800 clamp(13px,3.8vw,18px)/1.2 var(--font);white-space:nowrap;
  box-shadow:0 4px 10px rgba(90,60,20,.26)}
.mkx-need b{color:#C93B2A}
.mkx-need.mkx-gone{opacity:0;transition:opacity .4s}

/* ours, filling up */
.mkx-basket{position:absolute;right:3%;bottom:3%;width:26%;z-index:7;
  transition:transform .5s var(--spring)}
.mkx-bkt-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 5px 8px rgba(90,60,20,.3))}
.mkx-in{position:absolute;left:9%;right:9%;top:34%;bottom:12%;display:block}
.mkx-inbit{position:absolute;width:30%;display:block;
  transform:rotate(var(--rt,0deg));animation:mkxDrop .42s var(--spring)}
@keyframes mkxDrop{from{transform:translateY(-40px) rotate(var(--rt,0deg)) scale(.5);opacity:0}
  to{transform:translateY(0) rotate(var(--rt,0deg));opacity:1}}
.mkx-basket.mkx-drop{transform:translateY(3px) scale(1.03)}
.mkx-basket.mkx-full{animation:mkxCarry 1.1s var(--spring) 4}
.mkx-basket.mkx-full{z-index:9}
@keyframes mkxCarry{0%,100%{transform:translateY(-4%) scale(1.12) rotate(0)}
  35%{transform:translateY(-13%) scale(1.12) rotate(-4deg)}
  70%{transform:translateY(-8%) scale(1.12) rotate(4deg)}}

.mkx-say{position:absolute;left:31%;right:3%;bottom:21%;z-index:10;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(90,70,20,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.mkx-say.on{opacity:1;transform:none}
.mkx-say.her{background:#FFE6EF;color:#8E3B5E}
.mkx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.mkx-say.her::after{border-top-color:#FFE6EF}

/* the crates coming along the stall front. The field stops at the list, so a
   crate slides out of sight behind the paper rather than over the shopping. */
.mkx-field{position:absolute;left:24%;right:0;top:0;bottom:0;z-index:8;
  overflow:hidden;pointer-events:none}
.mkx-tray{position:absolute;right:-36%;width:33%;border:0;background:transparent;padding:0;
  cursor:pointer;pointer-events:auto;animation:mkxSlide var(--dur,6s) linear forwards}
/* A crate stops SHORT of the list paper and fades as it gets there, rather
   than sliding on behind it. Travelling further left leaves a crate whose
   middle is under the shopping list while its right-hand end is still on
   show — invisible where a finger aims, which is exactly the bug the reach
   probe exists to catch. */
@keyframes mkxSlide{0%{transform:translateX(0);opacity:1}
  84%{opacity:1}100%{transform:translateX(-352%);opacity:0}}
.mkx-slide{display:block;position:relative;animation:mkxBob 2.1s ease-in-out infinite alternate}
@keyframes mkxBob{from{transform:translateY(-4px) rotate(-2deg)}to{transform:translateY(4px) rotate(2deg)}}
.mkx-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(90,70,20,.32))}
/* the letter is HTML sitting on the drawn ticket, so it stays readable
   whatever the crate does — 29px on a 402px phone */
.mkx-tag{position:absolute;left:37%;top:66%;z-index:2;pointer-events:none;
  transform:translate(-50%,-50%) rotate(-6deg);
  font:900 clamp(22px,7.2vw,30px)/1 var(--font);color:#5A3E22}
.mkx-tray.mkx-bought{animation:none;
  transform:translate(38vw,34vh) scale(.28);opacity:0;transition:all .5s ease-in}
.mkx-tray.mkx-nope{animation-play-state:paused}
.mkx-tray.mkx-nope .mkx-slide{animation:sceneJig .5s ease-in-out 2}

/* sacks and boxes down on the cobbles, so the front of the market is not an
   empty floor while the crates come along above it */
.mkx-sacks{position:absolute;left:30%;right:3%;bottom:1.5%;height:13%;z-index:2;
  pointer-events:none}
.mkx-sacks i{position:absolute;bottom:0;width:13%;height:66%;
  left:calc(4% + var(--i) * 18%);
  border-radius:44% 44% 18% 18%/34% 34% 12% 12%;
  background:linear-gradient(180deg,#C9A87E,#A9834E)}
.mkx-sacks i::after{content:'';position:absolute;left:30%;right:30%;top:-11%;height:20%;
  border-radius:50% 50% 0 0;background:#8E6A3E}
.mkx-sacks i:nth-child(2),.mkx-sacks i:nth-child(4){height:56%;border-radius:4px;
  background:linear-gradient(180deg,#D9A05B,#B07C46)}
.mkx-sacks i:nth-child(2)::after,.mkx-sacks i:nth-child(4)::after{left:0;right:0;top:22%;
  height:11%;border-radius:0;background:rgba(154,107,50,.7)}


/* =======================================================================
   THE ICE CREAM VAN                                        id: ice-cream
   A queue that gets shorter. The person at the front holds up the order
   they asked for, written on a paper ticket; every cone on the counter
   has a matching paper flag. The next two in the queue are holding their
   own tickets, so a cone that is not ours belongs to somebody the child
   can point at. All ivx- prefixed.
   ======================================================================= */
.ivx-scene{position:absolute;inset:0;overflow:hidden}
.ivx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#8FD2F2 0%,#BFE7F6 30%,#E4F2E0 44%)}
.ivx-sun{position:absolute;right:6%;top:3%;width:14%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFF6D0,#FFCE3D 58%,rgba(255,206,61,0) 76%)}
.ivx-cloud{position:absolute;left:-30%;height:24px;border-radius:20px;background:#FFF8EC;opacity:.9;
  animation:ivxCloud var(--wd,40s) linear infinite}
.ivx-cloud::after{content:'';position:absolute;left:22%;top:-52%;width:56%;height:150%;
  border-radius:50%;background:#FFF8EC}
@keyframes ivxCloud{from{transform:translateX(0)}to{transform:translateX(160vw)}}
.ivx-hedge{position:absolute;left:-6%;right:-6%;top:32%;height:11%;
  border-radius:46% 46% 0 0/100% 100% 0 0;
  background:linear-gradient(180deg,#6FA84E,#4E8038)}
.ivx-grass{position:absolute;left:0;right:0;top:41%;bottom:0;
  background:linear-gradient(180deg,#8FC46A 0%,#7EB65C 30%,#96CC72 100%)}
.ivx-grass::after{content:'';position:absolute;inset:0;opacity:.3;
  background:repeating-linear-gradient(84deg,rgba(80,130,60,.5) 0 2px,transparent 2px 15px)}

.ivx-van{position:absolute;left:0;top:13%;width:60%;z-index:4}
.ivx-van-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 6px 10px rgba(50,80,40,.28))}
.ivx-roofcone{transform-origin:50% 100%;animation:ivxWobble 3.4s ease-in-out infinite alternate}
@keyframes ivxWobble{from{transform:rotate(-3deg)}to{transform:rotate(3deg)}}
/* the shutter that comes down at the end, over the drawn hatch */
.ivx-sold{position:absolute;left:40%;right:14%;top:35%;height:0;overflow:hidden;
  border-radius:0 0 3px 3px;transition:height .8s ease;
  background:repeating-linear-gradient(180deg,#C9CFD4 0 5px,#AEB6BC 5px 7px)}
.ivx-sold i{position:absolute;left:38%;right:38%;bottom:8%;height:14%;border-radius:3px;
  background:#8E979E}
.ivx-sold i:first-child{left:12%;right:12%;bottom:34%;height:8%;background:#9AA3AA}
.ivx-scene.ivx-soldout .ivx-sold{height:26%}

/* THE QUEUE, receding into the distance so all twelve fit and a child can see
   it getting shorter every single time */
.ivx-queue{position:absolute;left:38%;right:-4%;top:8%;height:36%;z-index:5}
.ivx-cust{position:absolute;display:block;transition:all .45s var(--spring)}
.ivx-cust-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 4px 6px rgba(50,80,40,.24))}
.ivx-cust.ivx-first .ivx-cust-svg{filter:drop-shadow(0 5px 8px rgba(50,80,40,.32))}
.ivx-cust.ivx-first .ivx-ticket{animation:ivxWave 1.9s ease-in-out infinite alternate}
@keyframes ivxWave{from{transform:rotate(3deg)}to{transform:rotate(12deg)}}
/* the letter is HTML on the drawn ticket, so it stays readable however far
   back in the queue the person is standing */
.ivx-ask{position:absolute;left:77%;top:14%;transform:translate(-50%,-50%) rotate(7deg);
  font:900 var(--fs,20px)/1 var(--font);color:#5A3E22;pointer-events:none}

/* everybody who has been served, over on the grass */
.ivx-seated{position:absolute;left:31%;right:0;bottom:1%;height:19%;z-index:6}
.ivx-sat{position:absolute;width:20%;display:block;animation:ivxSit .5s var(--spring)}
.ivx-sat.r0{bottom:0}
.ivx-sat.r1{bottom:47%;width:18%}
.ivx-sit-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 3px 4px rgba(50,80,40,.24))}
@keyframes ivxSit{from{transform:translate(30px,-30px) scale(.5);opacity:0}
  to{transform:none;opacity:1}}
.ivx-sat.ivx-cheer .ivx-eat{animation:ivxCheer .7s var(--spring) 3}
@keyframes ivxCheer{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px) rotate(-10deg)}}

/* THE COUNTER — the cones the van has made up, each with its paper flag */
.ivx-counter{position:absolute;left:1%;right:1%;top:44%;height:22%;z-index:7;
  display:flex;justify-content:space-around;align-items:flex-end}
.ivx-counter::after{content:'';position:absolute;left:2%;right:2%;bottom:6%;height:9%;
  border-radius:4px;background:linear-gradient(180deg,#EFDCB4 0 46%,#C0985E 46% 100%);
  box-shadow:0 4px 8px rgba(60,80,40,.28)}
/* two trestle legs, so the counter is a table standing on the grass rather
   than a plank floating in a field */
.ivx-counter::before{content:'';position:absolute;left:10%;right:10%;bottom:0;height:7%;
  background:linear-gradient(90deg,#A9834E 0 4%,transparent 4% 96%,#A9834E 96% 100%)}
.ivx-cone{position:relative;z-index:2;width:21%;border:0;background:transparent;padding:0;
  margin-bottom:1%;cursor:pointer;animation:ivxUp .42s var(--spring) backwards}
@keyframes ivxUp{from{transform:translateY(26px) scale(.6);opacity:0}to{transform:none;opacity:1}}
.ivx-cone-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(60,80,40,.3))}
/* the letter is HTML on the drawn flag — 30px on a 402px phone */
.ivx-flag{position:absolute;left:75%;top:13%;z-index:2;pointer-events:none;
  transform:translate(-50%,-50%);
  font:900 clamp(24px,7.4vw,31px)/1 var(--font);color:#5A3E22}
.ivx-cone.ivx-handed{animation:none;transform:translate(0,-40%) scale(1.15);opacity:0;
  transition:all .5s ease-in}
.ivx-cone.ivx-away{animation:none;opacity:0;transform:translateY(18px) scale(.8);
  transition:all .3s ease-in}
.ivx-cone.ivx-nope{animation:sceneJig .5s ease-in-out 2}

.ivx-say{position:absolute;left:31%;right:3%;bottom:24%;z-index:10;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(50,80,40,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.ivx-say.on{opacity:1;transform:none}
.ivx-say.her{background:#FFE6EF;color:#8E3B5E}
.ivx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.ivx-say.her::after{border-top-color:#FFE6EF}


/* =======================================================================
   WASH THE PUPPY                                          id: puppy-wash
   Back garden, tin tub, one filthy puppy. It is a windy day and the wash
   basket has gone over, so the sponge, the soap, the brush, the jug, the
   towel and the comb are all blowing across the yard — and some of them
   went through the mud puddle on the way. All pwx- prefixed.
   ======================================================================= */
.pwx-scene{position:absolute;inset:0;overflow:hidden}
.pwx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#8FD2F2 0%,#C4E8F6 24%,#E6F2DE 36%)}
.pwx-sun{position:absolute;right:6%;top:2%;width:14%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFF6D0,#FFCE3D 58%,rgba(255,206,61,0) 76%)}
.pwx-cloud{position:absolute;left:-30%;height:22px;border-radius:20px;background:#FFF8EC;opacity:.9;
  animation:pwxCloud var(--wd,42s) linear infinite}
.pwx-cloud::after{content:'';position:absolute;left:22%;top:-52%;width:56%;height:150%;
  border-radius:50%;background:#FFF8EC}
@keyframes pwxCloud{from{transform:translateX(0)}to{transform:translateX(160vw)}}
/* the washing line, so the yard is somebody's yard on a washing day */
.pwx-line{position:absolute;left:-2%;right:-2%;top:17%;height:8%;z-index:1}
.pwx-line::before{content:'';position:absolute;left:0;right:0;top:0;height:2px;
  border-radius:2px;background:#B08A52}
.pwx-hang{position:absolute;top:0;width:9%;height:100%;border-radius:0 0 4px 4px;
  transform-origin:50% 0;animation:pwxFlap 3.2s ease-in-out infinite alternate}
.pwx-hang.a{left:11%;background:repeating-linear-gradient(90deg,#F2A0B4 0 34%,#FFF8EC 34% 68%)}
.pwx-hang.b{left:44%;background:repeating-linear-gradient(90deg,#8FD2F2 0 34%,#FFF8EC 34% 68%);
  animation-delay:-1.1s}
.pwx-hang.c{left:76%;background:repeating-linear-gradient(90deg,#FFD75E 0 34%,#FFF8EC 34% 68%);
  animation-delay:-2.2s}
@keyframes pwxFlap{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
.pwx-hedge{position:absolute;left:-6%;right:-6%;top:25%;height:13%;
  border-radius:42% 42% 0 0/100% 100% 0 0;
  background:linear-gradient(180deg,#6FA84E,#4E8038)}
.pwx-hedge::after{content:'';position:absolute;inset:0;opacity:.3;border-radius:inherit;
  background:radial-gradient(circle 9px at 12px 14px,rgba(255,255,255,.5) 60%,transparent 62%);
  background-size:34px 26px}
.pwx-lawn{position:absolute;left:0;right:0;top:34%;bottom:0;
  background:linear-gradient(180deg,#8FC46A 0%,#7EB65C 26%,#98CE74 100%)}
.pwx-lawn::after{content:'';position:absolute;inset:0;opacity:.28;
  background:repeating-linear-gradient(84deg,rgba(80,130,60,.5) 0 2px,transparent 2px 15px)}

/* the mud puddle he was rolling in, with his own prints coming out of it —
   this is where the filthy things have been */
.pwx-puddle{position:absolute;left:2%;top:56%;width:28%;height:8.5%;
  border-radius:52% 48% 44% 56%/58% 42% 58% 42%;
  background:#6B4A2A;box-shadow:inset 0 2px 0 rgba(255,255,255,.14),
    0 0 0 4px rgba(107,74,42,.35)}
.pwx-puddle i{position:absolute;border-radius:50%;background:#4E351C;opacity:.6}
.pwx-puddle i:first-child{left:16%;top:30%;width:26%;height:30%}
.pwx-puddle i:last-child{right:14%;bottom:22%;width:20%;height:26%}
.pwx-prints{position:absolute;left:24%;top:66%;width:18%;height:8%}
.pwx-prints i{position:absolute;width:19%;height:40%;border-radius:52% 48% 42% 42%;
  background:#6B4A2A;opacity:.72;box-shadow:0 -3px 0 -1px #6B4A2A,3px -2px 0 -1.4px #6B4A2A}
.pwx-prints i:nth-child(1){left:0;top:44%}
.pwx-prints i:nth-child(2){left:26%;top:6%}
.pwx-prints i:nth-child(3){left:52%;top:48%}
.pwx-prints i:nth-child(4){left:78%;top:10%}

/* him, in the tub */
.pwx-bath{position:absolute;left:34%;width:50%;top:41%;height:40%;z-index:5}
.pwx-pup{position:absolute;left:12%;width:76%;bottom:26%;z-index:1}
.pwx-pup-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 5px 8px rgba(60,80,40,.26))}
.pwx-mud{position:absolute;display:block;pointer-events:none;
  background:radial-gradient(ellipse at 38% 34%,#7A5630,#4E351C 76%);
  box-shadow:0 1px 0 rgba(255,255,255,.12);
  transition:opacity .42s ease,transform .42s var(--spring)}
.pwx-mud.pwx-off{opacity:0;transform:scale(1.7)}
.pwx-shine{position:absolute;inset:-10%;border-radius:50%;pointer-events:none;opacity:0;
  background:radial-gradient(circle,rgba(255,255,255,.42),rgba(255,255,255,0) 66%);
  transition:opacity .5s ease}
.pwx-pup.pwx-clean .pwx-shine{opacity:1;animation:pwxTwinkle 1.1s ease-in-out infinite alternate}
@keyframes pwxTwinkle{from{transform:scale(.94)}to{transform:scale(1.06)}}
.pwx-tub{position:absolute;left:0;right:0;bottom:0;z-index:2}
.pwx-tub-svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 6px 9px rgba(60,80,40,.3))}
.pwx-bath.pwx-slosh{animation:pwxSlosh .42s ease-in-out}
@keyframes pwxSlosh{0%,100%{transform:rotate(0)}30%{transform:rotate(-1.6deg)}
  70%{transform:rotate(1.6deg)}}
.pwx-bath.pwx-shake{animation:pwxShake .12s linear 14}
@keyframes pwxShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-7px) rotate(-1deg)}
  75%{transform:translateX(7px) rotate(1deg)}}
.pwx-fly{position:absolute;inset:0;z-index:3;pointer-events:none}
.pwx-drop{position:absolute;width:9px;height:12px;border-radius:50% 50% 46% 46%;
  background:#BFE4F5;box-shadow:0 0 5px rgba(255,255,255,.8);
  animation:pwxFling .9s ease-out forwards}
@keyframes pwxFling{from{transform:translate(0,0) scale(.4);opacity:1}
  to{transform:translate(var(--dx,60px),var(--dy,-60px)) scale(1.1);opacity:0}}

.pwx-say{position:absolute;left:31%;right:3%;bottom:6%;z-index:10;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(50,80,40,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.pwx-say.on{opacity:1;transform:none}
.pwx-say.her{background:#FFE6EF;color:#8E3B5E}
.pwx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.pwx-say.her::after{border-top-color:#FFE6EF}

/* what is blowing across the yard */
.pwx-yard{position:absolute;inset:0;z-index:8}
.pwx-thing{position:absolute;right:-30%;width:27%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:pwxBlow var(--dur,6s) linear forwards}
@keyframes pwxBlow{from{transform:translateX(0)}to{transform:translateX(-160vw)}}
.pwx-blow{display:block;position:relative;animation:pwxTumble 2s ease-in-out infinite alternate}
@keyframes pwxTumble{from{transform:translateY(-5px) rotate(-5deg)}to{transform:translateY(5px) rotate(5deg)}}
.pwx-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(60,80,40,.3))}
/* the ones out of the puddle: brown right through, and no name tape on them */
.pwx-mucky .pwx-svg{filter:sepia(.8) saturate(1.3) hue-rotate(-16deg) brightness(.74)
  drop-shadow(2px 5px 6px rgba(60,60,30,.34))}
.pwx-drip{animation:pwxDrip 1.5s ease-in infinite}
.pwx-drip.b{animation-delay:-.7s}
@keyframes pwxDrip{0%{transform:translateY(0);opacity:.95}100%{transform:translateY(12px);opacity:0}}
/* the letter is HTML sitting on the drawn name tape, so it stays readable
   whatever the thing does — 29px on a 402px phone */
.pwx-tag{position:absolute;left:71%;top:74%;z-index:2;pointer-events:none;
  transform:translate(-50%,-50%) rotate(-7deg);
  font:900 clamp(22px,7.2vw,30px)/1 var(--font);color:#5A3E22}
.pwx-thing.pwx-used{animation:none;transform:translate(-8vw,26vh) scale(.34);opacity:0;
  transition:all .48s ease-in}
.pwx-thing.pwx-drop-it{animation:none;transform:translateY(20vh) rotate(26deg) scale(.6);opacity:0;
  transition:all .7s ease-in}


/* =======================================================================
   THE LOST TREASURE  (assets/games.js — pgx- / .sc-pgx)
   A bright beach. The tide keeps washing coins along the sand; ours are the
   ones with our letter STAMPED on, and the two pirates further up the beach
   are sitting beside their own chests, each branded with theirs — so a coin
   a child may not take always belongs to somebody they can point at.
   ======================================================================= */
.sc-pgx{position:absolute;inset:0;overflow:hidden}
.pgx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#7FCDEB 0%,#A8DFF2 16%,#CFEDF6 24%,#FFE9C2 28%,#FFE9C2 100%)}
.pgx-sun{position:absolute;left:9%;top:5%;width:15%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 42% 38%,#FFF7CE,#FFD75E 58%,rgba(255,215,94,0) 74%)}
.pgx-cloud{position:absolute;height:16px;border-radius:20px;background:rgba(255,255,255,.9);
  animation:pgxDrift var(--wd,42s) linear infinite}
.pgx-cloud::before,.pgx-cloud::after{content:'';position:absolute;bottom:0;border-radius:50%;
  background:rgba(255,255,255,.94)}
.pgx-cloud::before{left:16%;width:44%;aspect-ratio:1}
.pgx-cloud::after{right:12%;width:32%;aspect-ratio:1}
@keyframes pgxDrift{from{transform:translateX(112vw)}to{transform:translateX(-64vw)}}
.pgx-sea{position:absolute;left:0;right:0;top:26%;height:15%;
  background:linear-gradient(180deg,#2E86AE 0%,#3FA3C4 46%,#63C0D6 100%)}
.pgx-swell{position:absolute;left:-12%;right:-12%;height:6px;border-radius:50%;
  background:rgba(255,255,255,.32)}
.pgx-swell.a{top:30%;animation:pgxSwell 6.5s ease-in-out infinite alternate}
.pgx-swell.b{top:64%;opacity:.6;animation:pgxSwell 8.5s ease-in-out -3s infinite alternate}
@keyframes pgxSwell{from{transform:translateX(-4%) scaleX(.9)}to{transform:translateX(4%) scaleX(1)}}
.pgx-ship{position:absolute;right:4%;top:19%;width:29%;z-index:3;
  animation:pgxBobShip 5.4s ease-in-out infinite alternate}
.pgx-ship-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 6px rgba(20,60,80,.32))}
@keyframes pgxBobShip{from{transform:translateY(-4px) rotate(-2deg)}
  to{transform:translateY(4px) rotate(2deg)}}
/* the wet line where the sea meets the sand — where the coins wash along */
.pgx-foam{position:absolute;left:-6%;right:-6%;top:39.2%;height:2.2%;z-index:4;
  border-radius:50%/100% 100% 40% 40%;background:rgba(255,255,255,.8);
  animation:pgxFoam 4.6s ease-in-out infinite alternate}
@keyframes pgxFoam{from{transform:translateX(-2%) scaleY(.8)}to{transform:translateX(2%) scaleY(1.1)}}
.pgx-sand{position:absolute;left:0;right:0;top:41%;bottom:0;
  background:linear-gradient(180deg,#E9CE97 0%,#F3E1B4 22%,#EFD8A4 100%)}
/* pebbles the tide has left behind — small, quiet, part of the sand */
.pgx-shell{position:absolute;width:4%;aspect-ratio:1.5;border-radius:50%;
  background:radial-gradient(circle at 38% 30%,#E6D6B4,#C9B18A 78%);opacity:.85}
.pgx-shell.one{left:33%;top:46%;transform:rotate(-16deg)}
.pgx-shell.two{left:79%;top:53%;transform:rotate(22deg);width:3%}
.pgx-starfish{position:absolute;left:7%;top:49%;width:7.5%;opacity:.9;transform:rotate(-14deg)}
.pgx-starfish svg{width:100%;height:auto;display:block}
/* the sand is not a flat colour — the tide leaves lines on it */
.pgx-ripple{position:absolute;left:-8%;right:-8%;height:2.5%;border-radius:50%;
  border-top:3px solid rgba(200,160,96,.42)}
.pgx-ripple.r1{top:43%;transform:rotate(-1deg)}
.pgx-ripple.r2{top:49%;transform:rotate(.8deg);opacity:.8}
.pgx-ripple.r3{top:57%;transform:rotate(-.6deg);opacity:.55}

/* the two pirates, each beside their own branded chest */
.pgx-crew{position:absolute;z-index:5}
.pgx-crew.one{right:2%;top:60%;width:29%}
.pgx-crew.two{right:29%;top:69%;width:29%}
.pgx-crew-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(120,90,40,.34))}
.pgx-crew-letter{font:900 42px var(--font);fill:#5E3717;text-anchor:middle}
.pgx-crew-lip{fill:#D2A76B;opacity:.9}
.pgx-crew-art{transform-origin:56px 120px}
.sc-pgx.pgx-hooray .pgx-crew-art{animation:pgxCheer .58s ease-in-out 5}
@keyframes pgxCheer{0%,100%{transform:translateY(0) rotate(0)}
  40%{transform:translateY(-7px) rotate(-5deg)}70%{transform:translateY(-2px) rotate(5deg)}}

/* OUR chest — the gauge for the whole game. The pile heaps up over the rim
   and at the end it brims over the front. */
.pgx-chest{position:absolute;left:3%;bottom:19%;width:41%;aspect-ratio:170/160;z-index:6}
.pgx-lid{position:absolute;left:0;top:0;width:100%;z-index:1}
.pgx-lid-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 5px rgba(120,90,40,.3))}
.pgx-hollow{position:absolute;left:11%;right:11%;bottom:59%;height:30%;z-index:2;overflow:hidden}
.pgx-hollow::after{content:'';position:absolute;left:0;right:0;bottom:0;height:16%;
  background:#3E2711}
.pgx-gold{position:absolute;left:-3%;right:-3%;bottom:0;height:8%;
  border-radius:46% 46% 6% 6%/74% 74% 6% 6%;
  background:
    radial-gradient(circle at 20% 26%,#FFF3C2 0 7%,transparent 8%),
    radial-gradient(circle at 58% 16%,#FFF3C2 0 6%,transparent 7%),
    radial-gradient(circle at 80% 34%,#FFF3C2 0 6%,transparent 7%),
    radial-gradient(circle at 38% 52%,#D79A1B 0 8%,transparent 9%),
    radial-gradient(circle at 70% 66%,#D79A1B 0 8%,transparent 9%),
    linear-gradient(180deg,#FBD75F 0%,#EFBF33 50%,#C98A16 100%);
  box-shadow:inset 0 3px 0 rgba(255,255,255,.55);
  transition:height .5s var(--spring)}
.pgx-front{position:absolute;left:0;bottom:0;width:100%;z-index:3}
.pgx-front-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 5px 7px rgba(120,90,40,.36))}
.pgx-brand{font:900 46px var(--font);fill:#5E3717;text-anchor:middle}
.pgx-brand-lip{fill:#D2A76B;opacity:.9}
.pgx-chest.pgx-clink{animation:pgxClink .34s var(--spring)}
@keyframes pgxClink{0%,100%{transform:scale(1)}45%{transform:scale(1.06) rotate(-1.5deg)}}
/* a few coins tipped out on to the sand at the foot of the chest */
.pgx-spill{position:absolute;left:-6%;right:-6%;bottom:-12%;z-index:4;opacity:0;
  transform:translateY(-10px) scale(.6);transform-origin:50% 100%;
  transition:all .6s var(--spring)}
.pgx-spill-svg{width:100%;height:auto;display:block;overflow:visible}
.pgx-chest.pgx-brim .pgx-spill{opacity:1;transform:none}
.pgx-twinkle{position:absolute;z-index:5;width:11%;aspect-ratio:1;opacity:0;
  background:conic-gradient(from 0deg,transparent 0 8%,#FFF6C8 12%,transparent 16% 33%,
    #FFF6C8 37%,transparent 41% 58%,#FFF6C8 62%,transparent 66% 83%,#FFF6C8 87%,transparent 91%);
  filter:blur(.4px)}
.pgx-twinkle.t1{left:4%;top:6%}
.pgx-twinkle.t2{right:2%;top:16%}
.pgx-twinkle.t3{left:46%;top:-6%;width:14%}
.pgx-chest.pgx-brim .pgx-twinkle{animation:pgxTwink 1.5s ease-in-out infinite}
.pgx-chest.pgx-brim .pgx-twinkle.t2{animation-delay:-.5s}
.pgx-chest.pgx-brim .pgx-twinkle.t3{animation-delay:-1s}
@keyframes pgxTwink{0%,100%{opacity:0;transform:scale(.4) rotate(0)}
  50%{opacity:1;transform:scale(1) rotate(45deg)}}

.pgx-say{position:absolute;left:31%;right:3%;bottom:7%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(90,70,30,.34);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.pgx-say.on{opacity:1;transform:none}
.pgx-say.her{background:#FFE6EF;color:#8E3B5E}
.pgx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.pgx-say.her::after{border-top-color:#FFE6EF}

/* the coins washing along the tide line */
.pgx-surf{position:absolute;inset:0;z-index:12}
.pgx-coin{position:absolute;right:-24%;width:21%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:pgxWash var(--dur,7s) linear forwards}
@keyframes pgxWash{from{transform:translateX(0)}to{transform:translateX(-150vw)}}
.pgx-rock{display:block;animation:pgxRock var(--rock,2s) ease-in-out infinite alternate}
@keyframes pgxRock{from{transform:rotate(-11deg) translateY(-3px)}
  to{transform:rotate(11deg) translateY(3px)}}
.pgx-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 4px 5px rgba(140,100,30,.42))}
.pgx-letter{font:900 38px var(--font);fill:#8A5407;text-anchor:middle}
.pgx-lip{fill:#FFEFB4}
.pgx-coin.pgx-tochest{animation:none;transform:translate(-52vw,20vh) scale(.22);opacity:0;
  transition:all .42s ease-in}
.pgx-coin.pgx-nope{animation-play-state:paused}
.pgx-coin.pgx-nope .pgx-rock{animation:sceneJig .5s ease-in-out 2}


/* =======================================================================
   GET THE PARTY READY  (assets/games.js — pyx- / .sc-pyx)
   The room starts bare and every catch puts something up in it. Through the
   archway on the left is the party NEXT DOOR, with two big letter balloons —
   which is what every wrong delivery label belongs to.
   ======================================================================= */
.sc-pyx{position:absolute;inset:0;overflow:hidden}
.pyx-wall{position:absolute;left:0;right:0;top:0;height:78%;
  background:linear-gradient(180deg,#FFF6E8 0%,#FDEBD8 62%,#F6DFC8 100%)}
.pyx-wall::after{content:'';position:absolute;inset:0;opacity:.26;
  background:repeating-linear-gradient(90deg,transparent 0 26px,rgba(226,196,160,.5) 26px 29px)}
.pyx-skirt{position:absolute;left:0;right:0;top:75.6%;height:2.8%;
  background:linear-gradient(180deg,#F2E3CE,#E2CDB0);border-top:2px solid #EDDCC2}
.pyx-floor{position:absolute;left:0;right:0;top:78%;bottom:0;
  background:linear-gradient(180deg,#D9B98C 0%,#C7A170 100%)}
.pyx-floor::after{content:'';position:absolute;inset:0;opacity:.45;
  background:repeating-linear-gradient(90deg,transparent 0 44px,rgba(150,110,66,.5) 44px 47px)}

/* ---- the party next door ---- */
.pyx-next{position:absolute;left:0;top:30%;width:27%;height:48%;z-index:2}
.pyx-nroom{position:absolute;inset:0;border-radius:0 46% 0 0;
  background:linear-gradient(180deg,#F0DAB8 0%,#E4C79E 66%,#B98F63 66.5%,#A67C52 100%)}
.pyx-nbunt{position:absolute;left:4%;right:14%;top:8%;height:8%;
  background:
    linear-gradient(-40deg,transparent 48%,#FF8FA6 49% 100%) 0 0/26% 100% no-repeat,
    linear-gradient(-40deg,transparent 48%,#FFCE3D 49% 100%) 26% 0/26% 100% no-repeat,
    linear-gradient(-40deg,transparent 48%,#8AD37F 49% 100%) 52% 0/26% 100% no-repeat,
    linear-gradient(-40deg,transparent 48%,#7FC8EE 49% 100%) 78% 0/26% 100% no-repeat;
  opacity:.85}
.pyx-ntable{position:absolute;left:10%;right:14%;bottom:14%;height:9%;border-radius:4px;
  background:#C89B62;box-shadow:0 5px 0 #A87C46}
.pyx-ntable::after{content:'';position:absolute;left:36%;bottom:100%;width:28%;height:86%;
  border-radius:8px 8px 3px 3px;background:linear-gradient(180deg,#FFC3D4 0 40%,#EFC79E 40%)}
/* their two letter balloons — exactly the two letters every wrong label has */
.pyx-nball{position:absolute;width:44%;aspect-ratio:.86;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font:900 clamp(20px,5.6vw,26px)/1 var(--font);color:#7A3550;
  box-shadow:inset -5px -6px 0 rgba(0,0,0,.09);
  animation:pyxBob 3.6s ease-in-out infinite alternate}
.pyx-nball::after{content:'';position:absolute;top:100%;left:50%;margin-left:-5px;
  border:5px solid transparent}
.pyx-nball.a{left:8%;top:24%;background:#FFD6E2}
.pyx-nball.a::after{border-top-color:#FFD6E2}
.pyx-nball.b{right:6%;top:42%;background:#FFE9A8;color:#8A5C1E;animation-delay:-1.7s}
.pyx-nball.b::after{border-top-color:#FFE9A8}
@keyframes pyxBob{from{transform:translateY(-5px)}to{transform:translateY(5px)}}
.pyx-narch{position:absolute;inset:-2% -2% -2% -2%;border-radius:0 48% 0 0;
  border:10px solid #EADCC6;border-left:0;border-bottom:0;
  box-shadow:inset 0 0 22px rgba(90,60,34,.35)}

/* ---- our door: she comes in through this one ---- */
.pyx-door{position:absolute;right:0;top:32%;width:24%;height:44%;z-index:2;
  border-radius:7px 7px 0 0;background:#C4784A;
  box-shadow:inset 0 0 0 4px #A8623A,0 4px 10px rgba(90,60,34,.28);
  transform-origin:100% 50%;transition:transform .8s var(--spring)}
.pyx-panel{position:absolute;left:14%;right:14%;top:9%;height:38%;border-radius:5px;
  background:#B36C42;box-shadow:inset 0 0 0 3px #9C5A34}
.pyx-knob{position:absolute;left:9%;top:53%;width:11%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 36% 32%,#FFE9A8,#E8B62C 70%)}
.pyx-sign{position:absolute;left:18%;right:18%;top:58%;height:17%;border-radius:6px;
  background:#FFF6E2;box-shadow:0 3px 7px rgba(90,60,34,.3);transform:rotate(-5deg);
  display:flex;align-items:center;justify-content:center;font-style:normal;
  font:900 clamp(24px,7vw,32px)/1 var(--font);color:#8E3B5E}
.pyx-light{position:absolute;right:0;top:32%;width:24%;height:44%;z-index:1;opacity:0;
  border-radius:9px 9px 0 0;
  background:radial-gradient(120% 90% at 78% 46%,#FFFAE0 0%,#FFE9A8 46%,#F6C96A 100%);
  transition:opacity .6s ease}
.sc-pyx.pyx-open .pyx-door{transform:perspective(600px) rotateY(-72deg)}
.sc-pyx.pyx-open .pyx-light{opacity:1;box-shadow:0 0 40px 14px rgba(255,220,140,.6)}

/* ---- the twelve things that go up in the room ---- */
.pyx-bit{position:absolute;z-index:3;opacity:0;transform:translateY(-14px) scale(.5);
  transition:opacity .34s ease,transform .46s var(--spring)}
.pyx-bit.pyx-up{opacity:1;transform:none}
.pyx-thing-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(1px 3px 4px rgba(120,90,50,.24))}
.pyx-p0{left:0;top:10%;width:47%}           /* bunting, left half */
.pyx-p1{left:52%;top:12%;width:47%}         /* bunting, right half */
.pyx-p2{left:25%;top:28%;width:16%;transform-origin:50% 100%}   /* balloons */
.pyx-p3{left:58%;top:26%;width:16%;transform-origin:50% 100%}
.pyx-p2.pyx-up,.pyx-p3.pyx-up{animation:pyxBob 3.8s ease-in-out 1s infinite alternate}
.pyx-p3.pyx-up{animation-delay:-1.4s}
.pyx-p4{left:22%;top:58%;width:52%}         /* the table */
.pyx-p5{left:19%;top:56.5%;width:58%}       /* the cloth over it */
.pyx-p6{left:40%;top:58%;width:18%}         /* the cake, on the cloth */
.pyx-p7{left:42.5%;top:56%;width:13%}       /* the candles, on the cake */
.pyx-p8{left:24%;top:60%;width:14%}         /* plates and a cup */
.pyx-p9{left:26%;top:72%;width:14%}         /* a present, on the floor */
.pyx-p10{left:46%;top:73%;width:14%}        /* another present */
.pyx-p11{left:57%;top:62%;width:18%;display:flex;align-items:flex-end;gap:2px}
.pyx-p11 .pyx-thing-svg{width:34%}
.pyx-p11 .pyx-thing-svg:nth-child(2){width:38%;margin-bottom:-2%}
.sc-pyx.pyx-ready .pyx-p6 .pyx-thing-svg,.sc-pyx.pyx-ready .pyx-p7 .pyx-thing-svg{
  filter:drop-shadow(0 0 12px rgba(255,206,61,.75))}

/* ---- confetti, only once the room is ready ---- */
.pyx-conf{position:absolute;inset:0;z-index:8;pointer-events:none;opacity:0;
  transition:opacity .3s ease}
.sc-pyx.pyx-ready .pyx-conf{opacity:1}
.pyx-conf i{position:absolute;top:-8%;height:12px;border-radius:2px;
  animation:pyxFall var(--cd,2.2s) linear infinite}
@keyframes pyxFall{from{transform:translateY(0) rotate(0)}
  to{transform:translateY(112vh) rotate(540deg)}}

.pyx-say{position:absolute;left:31%;right:3%;bottom:6%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(90,60,34,.32);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.pyx-say.on{opacity:1;transform:none}
.pyx-say.her{background:#FFE6EF;color:#8E3B5E}
.pyx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.pyx-say.her::after{border-top-color:#FFE6EF}

/* ---- what is being carried through ---- */
.pyx-run{position:absolute;inset:0;z-index:12}
.pyx-carry{position:absolute;right:-30%;width:27%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:pyxCarry var(--dur,6s) linear forwards}
@keyframes pyxCarry{from{transform:translateX(0)}to{transform:translateX(-160vw)}}
.pyx-sway{display:block;animation:pyxSway 1.7s ease-in-out infinite alternate}
@keyframes pyxSway{from{transform:rotate(-5deg) translateY(-4px)}
  to{transform:rotate(5deg) translateY(4px)}}
.pyx-carry-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(2px 5px 6px rgba(120,90,50,.3))}
.pyx-label{font:900 40px var(--font);fill:#5A4636;text-anchor:middle}
.pyx-carry.pyx-putup{animation:none;transform:translate(-30vw,-16vh) scale(.3);opacity:0;
  transition:all .44s ease-in}
.pyx-carry.pyx-nope{animation-play-state:paused}
.pyx-carry.pyx-nope .pyx-sway{animation:sceneJig .5s ease-in-out 2}


/* =======================================================================
   LIGHT THE WAY HOME  (assets/games.js — lgx- / .sc-lgx)
   Night, fog, and a boat that cannot find the harbour. --lit runs 0 to 1 and
   drives all three things at once: the lamp, the fog and how far in the boat
   has got. The bugs sit ABOVE the fog layer so the letters never go soft.
   ======================================================================= */
.sc-lgx{position:absolute;inset:0;overflow:hidden;--lit:0}
.lgx-sky{position:absolute;inset:0;
  background:linear-gradient(180deg,#0D1930 0%,#152845 30%,#1F3C59 54%,#2F5169 64%)}
.lgx-star{position:absolute;width:3px;height:3px;border-radius:50%;background:#FFF8E0;
  opacity:calc(.25 + var(--lit) * .7);
  animation:lgxTwinkle 3.6s ease-in-out infinite alternate;transition:opacity .6s ease}
@keyframes lgxTwinkle{from{transform:scale(.6)}to{transform:scale(1.3)}}
.lgx-moon{position:absolute;left:7%;top:6%;width:14%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 38% 34%,#FFFBE8,#E8E2C8 58%,rgba(232,226,200,0) 74%)}
.lgx-sea{position:absolute;left:0;right:0;top:64%;bottom:0;
  background:linear-gradient(180deg,#20455E 0%,#16324A 44%,#0C1E30 100%)}
.lgx-swell{position:absolute;left:-12%;right:-12%;height:5px;border-radius:50%;
  background:rgba(190,220,236,calc(.12 + var(--lit) * .3))}
.lgx-swell.a{top:9%;animation:lgxSwell 7s ease-in-out infinite alternate}
.lgx-swell.b{top:30%;animation:lgxSwell 9s ease-in-out -3s infinite alternate}
.lgx-swell.c{top:58%;animation:lgxSwell 11s ease-in-out -6s infinite alternate}
@keyframes lgxSwell{from{transform:translateX(-4%) scaleX(.92)}to{transform:translateX(4%) scaleX(1)}}

/* the harbour wall, the post and the lamp on it */
.lgx-rock{position:absolute;left:-8%;bottom:0;width:36%;height:33%;z-index:5;
  border-radius:0 64% 0 0;
  background:linear-gradient(180deg,#3B4A50 0%,#2C383E 56%,#1D272C 100%);
  box-shadow:inset 6px 6px 0 rgba(255,255,255,.05)}
.lgx-post{position:absolute;left:20%;bottom:21%;width:3.4%;height:37%;z-index:6;
  border-radius:2px;background:linear-gradient(90deg,#4E3A28,#7A6046 45%,#402F20)}
.lgx-post::after{content:'';position:absolute;right:96%;top:0;width:400%;height:9%;
  border-radius:4px;background:linear-gradient(180deg,#8A6E52,#503B28)}
/* the little brace under the arm, so the lamp is hanging off something */
.lgx-post::before{content:'';position:absolute;right:88%;top:7%;width:150%;height:14%;
  background:linear-gradient(180deg,#7A6046,#4E3A28);
  clip-path:polygon(100% 0,100% 24%,0 100%,0 70%)}
.lgx-halo{position:absolute;left:15%;top:50%;z-index:6;pointer-events:none;
  width:calc(26% + var(--lit) * 84%);aspect-ratio:1;border-radius:50%;
  transform:translate(-50%,-50%);transition:width .6s ease;
  background:radial-gradient(circle,rgba(255,222,148,calc(.16 + var(--lit) * .42)) 0%,
    rgba(255,222,148,calc(var(--lit) * .12)) 44%,transparent 70%)}
.lgx-beam{position:absolute;left:15%;top:50%;z-index:6;pointer-events:none;
  width:calc(22% + var(--lit) * 82%);height:calc(12% + var(--lit) * 24%);
  transform:translateY(-50%);opacity:calc(.1 + var(--lit) * .78);
  transition:all .6s ease;clip-path:polygon(0 40%,100% 0,100% 100%,0 60%);
  background:linear-gradient(90deg,rgba(255,230,160,.62),rgba(255,230,160,.06))}
.lgx-lamp{position:absolute;left:6.5%;bottom:44%;width:17%;z-index:7}
.lgx-lamp-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 0 calc(4px + var(--lit) * 26px) rgba(255,214,110,calc(.3 + var(--lit) * .7)))}
.lgx-glass{fill:rgba(255,246,208,calc(.22 + var(--lit) * .78))}
.lgx-flame{opacity:calc(.3 + var(--lit) * .7);animation:lgxFlicker 1.15s ease-in-out infinite alternate}
.lgx-flame-in{opacity:calc(.2 + var(--lit) * .8)}
@keyframes lgxFlicker{from{opacity:.55}to{opacity:1}}
.lgx-lamp.lgx-pulse{animation:lgxPulse .4s var(--spring)}
@keyframes lgxPulse{0%,100%{transform:scale(1)}45%{transform:scale(1.09)}}
.lgx-lamp.lgx-gutter{animation:lgxGutter .62s ease-in-out}
@keyframes lgxGutter{0%,100%{transform:rotate(0);filter:none}
  25%{transform:rotate(-6deg);filter:brightness(.55)}
  60%{transform:rotate(5deg);filter:brightness(.7)}}

/* the boat: further in, bigger and lower in the frame with every firefly */
.lgx-boat{position:absolute;right:3%;bottom:30%;width:32%;z-index:5;
  transform:scale(var(--bsc,.48));transform-origin:50% 100%;
  transition:right .7s ease,bottom .7s ease,transform .7s ease}
.lgx-bob{display:block;animation:lgxBob 4.4s ease-in-out infinite alternate}
@keyframes lgxBob{from{transform:translateY(-5px) rotate(-2.4deg)}
  to{transform:translateY(5px) rotate(2.4deg)}}
.lgx-boat-svg{width:100%;height:auto;display:block;overflow:visible}
.lgx-boatlamp{animation:lgxFlicker 1.6s ease-in-out infinite alternate}
.lgx-boat.lgx-home .lgx-arm{transform-box:fill-box;transform-origin:0% 100%;
  animation:lgxHail .46s ease-in-out infinite alternate}
@keyframes lgxHail{from{transform:rotate(-16deg)}to{transform:rotate(18deg)}}

/* the fog. It sits UNDER the bugs, so the letters are always crisp. */
.lgx-fog{position:absolute;inset:0;z-index:9;pointer-events:none;
  opacity:calc(1 - var(--lit) * .94);transition:opacity .6s ease;
  background:linear-gradient(180deg,rgba(206,220,232,.2) 0%,rgba(212,226,236,.5) 42%,
    rgba(222,232,240,.76) 76%,rgba(228,238,246,.86) 100%)}
.lgx-fog i{position:absolute;left:-30%;right:-30%;height:16%;border-radius:50%;
  background:rgba(238,244,250,.5);filter:blur(9px)}
.lgx-fog i.f1{top:34%;animation:lgxRoll 26s linear infinite}
.lgx-fog i.f2{top:52%;animation:lgxRoll 34s linear -12s infinite reverse}
.lgx-fog i.f3{top:70%;animation:lgxRoll 30s linear -20s infinite}
@keyframes lgxRoll{from{transform:translateX(-14%)}to{transform:translateX(14%)}}
.sc-lgx.lgx-clear .lgx-fog{opacity:0}

.lgx-say{position:absolute;left:31%;right:3%;bottom:6%;z-index:14;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(4,14,30,.5);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.lgx-say.on{opacity:1;transform:none}
.lgx-say.her{background:#FFE6EF;color:#8E3B5E}
.lgx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.lgx-say.her::after{border-top-color:#FFE6EF}

/* what is flying past */
.lgx-air{position:absolute;inset:0;z-index:12}
.lgx-bug{position:absolute;right:-28%;width:22%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:lgxDrift var(--dur,7s) linear forwards}
.lgx-bug.lgx-moth{width:28%}
@keyframes lgxDrift{from{transform:translateX(0)}to{transform:translateX(-152vw)}}
.lgx-flit{display:block;animation:lgxFlit var(--bob,1.8s) ease-in-out infinite alternate}
@keyframes lgxFlit{from{transform:translateY(-9px) rotate(-6deg)}
  to{transform:translateY(9px) rotate(6deg)}}
.lgx-moth .lgx-flit{animation-name:lgxFlap}
@keyframes lgxFlap{from{transform:translateY(-6px) rotate(-11deg) scaleX(.88)}
  to{transform:translateY(6px) rotate(11deg) scaleX(1)}}
.lgx-fly-svg,.lgx-moth-svg{width:100%;height:auto;display:block;overflow:visible}
.lgx-fly-svg{filter:drop-shadow(0 0 12px rgba(255,226,140,.85))}
.lgx-moth-svg{filter:drop-shadow(2px 4px 5px rgba(4,14,30,.5))}
.lgx-letter{font:900 36px var(--font);fill:#6B4A12;text-anchor:middle}
.lgx-bug.lgx-caught{animation:none;transform:translate(-42vw,12vh) scale(.18);opacity:0;
  transition:all .42s ease-in}
.lgx-bug.lgx-shoo{animation-play-state:paused}
.lgx-bug.lgx-shoo .lgx-flit{animation:sceneJig .5s ease-in-out 2}


/* =======================================================================
   4. FLY THE KITE
   A bright windy hill. Bows blow across on the wind and are tied on the
   tail one at a time; the longer the tail the higher the kite climbs, and
   the string is measured every frame so it really does join Mo's hand to
   the kite. Two other children are already up. Prefix ktx- / .sc-ktx —
   the old kite game's kt- / .kite names are all avoided.
   ======================================================================= */
.sc-ktx{position:absolute;inset:0;overflow:hidden}
.ktx-sky{position:absolute;inset:0;
  background:linear-gradient(178deg,#8FD3F4 0%,#BCE7FA 44%,#E1F4FB 74%,#EFF8E6 100%)}
.ktx-sun{position:absolute;right:7%;top:5%;width:15%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,#FFF6CC,#FFCE3D 56%,transparent 72%)}
.ktx-cloud{position:absolute;height:15px;border-radius:999px;background:#fff;opacity:.88;
  animation:ktxDrift var(--wd,38s) linear infinite}
.ktx-cloud::before,.ktx-cloud::after{content:'';position:absolute;bottom:0;
  border-radius:50%;background:#fff}
.ktx-cloud::before{left:18%;width:38%;height:0;padding-bottom:38%}
.ktx-cloud::after{right:22%;width:28%;height:0;padding-bottom:28%}
@keyframes ktxDrift{from{transform:translateX(122vw)}to{transform:translateX(-42vw)}}
.ktx-far{position:absolute;left:-8%;right:-8%;bottom:14%;height:25%;
  border-radius:50% 50% 0 0/100% 100% 0 0;background:#8FC078;
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.ktx-hill{position:absolute;left:-10%;right:-10%;bottom:-4%;height:30%;
  border-radius:50% 50% 0 0/62% 62% 0 0;
  background:linear-gradient(180deg,#84BA6E,#5D9450);
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}

/* everything standing ON the hill travels together when the ground drops
   away at the end — one transform, so nothing comes adrift from anything */
.ktx-ground{position:absolute;inset:0;z-index:2;pointer-events:none;
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.ktx-kid{position:absolute}
/* he flies his kite off to the left, so he is turned to face it. There is no
   mark anywhere on a child, so mirroring the whole sprite is safe here. */
.ktx-kid.one .ktx-kidsvg{transform:scaleX(-1)}
/* up on the crest, not down at the front — Mo's speech bubble sits across
   the bottom sixth of the stage and it was standing on both their heads */
.ktx-kid.one{left:33%;bottom:22%;width:13.5%}
.ktx-kid.two{left:84%;bottom:24%;width:11%}
.ktx-kidsvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 5px 5px rgba(40,70,40,.3))}
/* off to the side of centre: the kite hangs its tail straight down the
   middle of the hill and the box was sitting on the end of it */
.ktx-box{position:absolute;left:63%;bottom:17%;width:18%}
.ktx-boxsvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 5px 6px rgba(60,45,20,.35))}

/* THE OTHER TWO KITES, already up. Each carries the other family's name
   tape on its tail, big enough to read from the ground — without them a
   tape on a bow answers a question nobody has asked. */
.ktx-other{position:absolute;z-index:2;pointer-events:none;
  animation:ktxBob 4.4s ease-in-out infinite alternate;
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.ktx-other.one{left:2%;top:30%;width:16%}
.ktx-other.two{right:2%;top:20%;width:14%;animation-duration:5.3s;animation-delay:-2s}
@keyframes ktxBob{from{transform:translateY(-6px) rotate(-4deg)}
  to{transform:translateY(6px) rotate(4deg)}}
.ktx-osvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 4px 5px rgba(40,70,60,.25))}
/* their tail is short, dark and hangs a little off square, so it reads as a
   TAIL and not as a bead threaded on the long string back down to the child */
.ktx-otail{position:absolute;left:50%;top:95%;width:3px;height:5vh;
  transform:translateX(-46%) rotate(9deg);transform-origin:50% 0;
  background:linear-gradient(180deg,rgba(74,58,40,.85),rgba(74,58,40,.45))}
.ktx-mark{position:absolute;left:50%;top:calc(95% + 4.4vh);transform:translate(-50%,-50%);
  min-width:2.3em;padding:2px 7px;border-radius:999px;background:#FDFBF3;color:#3C3226;
  border:2px solid #B4A98F;text-align:center;
  font:900 clamp(15px,4.4vw,20px)/1.15 var(--font);
  box-shadow:0 3px 7px rgba(40,70,40,.32)}

/* the strings. Width and angle are written every frame from the real boxes,
   so nothing is ever guessed and nothing ever comes unattached. */
.ktx-line{position:absolute;height:1.6px;z-index:3;pointer-events:none;
  transform-origin:0 50%;background:rgba(70,54,36,.4);border-radius:2px}
.ktx-line.ours{height:2.4px;background:rgba(60,44,28,.78)}
/* Mo stands over the bottom-left of every stage and this is his paw — the
   string really does come out of his hand rather than out of the air */
.ktx-hand{position:absolute;left:25%;bottom:11%;width:2px;height:2px;
  opacity:0;pointer-events:none}

.ktx-kite{position:absolute;left:var(--kl,50%);bottom:var(--kb,28%);width:24%;z-index:4;
  transform:translateX(-50%);pointer-events:none;
  transition:left .9s var(--spring),bottom .9s var(--spring),transform 1.4s ease-out}
.ktx-diamond{width:100%;animation:ktxSway 3.6s ease-in-out infinite alternate}
@keyframes ktxSway{from{transform:rotate(-7deg)}to{transform:rotate(7deg)}}
.ktx-ksvg{width:100%;height:auto;display:block;
  filter:drop-shadow(3px 6px 7px rgba(40,70,40,.3))}
.ktx-tail{position:absolute;left:50%;top:98%;width:3px;height:11vh;
  transform-origin:50% 0;border-radius:2px;
  animation:ktxTailSway 3.6s ease-in-out infinite alternate;
  background:linear-gradient(180deg,rgba(74,58,40,.85),rgba(74,58,40,.4));
  transition:height .5s ease-out}
.ktx-tbow{position:absolute;left:50%;width:34px;height:19px;
  transform:translate(-50%,-50%);
  background:linear-gradient(90deg,var(--a,#FF8FA6),var(--b,#E8577A) 50%,var(--a,#FF8FA6));
  clip-path:polygon(0 0,42% 42%,58% 42%,100% 0,100% 100%,58% 58%,42% 58%,0 100%);
  animation:ktxPop .42s var(--spring) both;transition:top .5s ease-out}
@keyframes ktxPop{from{transform:translate(-50%,-50%) scale(.2)}
  to{transform:translate(-50%,-50%) scale(1)}}
@keyframes ktxTailSway{from{transform:translateX(-50%) rotate(-3.5deg)}
  to{transform:translateX(-50%) rotate(3.5deg)}}

.ktx-say{position:absolute;left:31%;right:3%;bottom:5%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(40,86,44,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.ktx-say.on{opacity:1;transform:none}
.ktx-say.her{background:#FFE6EF;color:#8E3B5E}
.ktx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.ktx-say.her::after{border-top-color:#FFE6EF}

/* what the wind brings */
.ktx-field{position:absolute;inset:0;z-index:5}
.ktx-blow{position:absolute;right:-28%;width:27%;border:0;background:transparent;padding:0;
  cursor:pointer;animation:ktxBlow var(--dur,6s) linear forwards}
@keyframes ktxBlow{from{transform:translateX(0)}to{transform:translateX(-132vw)}}
.ktx-bob{display:block;animation:ktxFlut 1.7s ease-in-out infinite alternate}
@keyframes ktxFlut{from{transform:rotate(calc(var(--tilt,0deg) - 7deg))}
  to{transform:rotate(calc(var(--tilt,0deg) + 7deg))}}
.ktx-bsvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 4px 5px rgba(50,70,50,.34))}
.ktx-blow.ktx-tied{animation:none;transform:translate(-26vw,-22vh) scale(.28);opacity:0;
  transition:all .44s ease-in}
.ktx-blow.ktx-nope{animation-play-state:paused}
.ktx-blow.ktx-nope .ktx-bob{animation:sceneJig .5s ease-in-out 2}

/* THE PAYOFF. The ground drops away, the other two kites fall behind and
   ours goes right up over the hill. The first beat of it is on screen the
   instant the last bow is tied on. */
/* it stops short of the header — a payoff that flies in behind the dots row
   is a payoff nobody sees */
.sc-ktx.ktx-soar .ktx-kite{bottom:56%;left:52%;transform:translateX(-50%) scale(.94)}
/* vh, not per cent — see the note in the balloon yard below. The ground is
   full height and the hill is a third of it, so a percentage slid the two
   apart and walked the children down off the hillside. */
.sc-ktx.ktx-soar .ktx-ground,.sc-ktx.ktx-soar .ktx-hill,
.sc-ktx.ktx-soar .ktx-far{transform:translateY(4vh)}
/* the bob is an animation, and an animation beats a plain declaration — so
   the other two only fall behind if their bobbing is called off first */
.sc-ktx.ktx-soar .ktx-other{animation:none;transform:translateY(4vh) scale(.9)}
.sc-ktx.ktx-high .ktx-kite{bottom:66%;transform:translateX(-50%) scale(.78)}
.sc-ktx.ktx-high .ktx-ground,.sc-ktx.ktx-high .ktx-hill,
.sc-ktx.ktx-high .ktx-far{transform:translateY(9vh)}
.sc-ktx.ktx-high .ktx-other{animation:none;transform:translateY(12vh) scale(.8)}
.sc-ktx.ktx-high .ktx-sky{filter:saturate(1.15) brightness(1.05)}
.sc-ktx.ktx-cheer .ktx-diamond{animation:ktxCheer 1s ease-in-out 3}
@keyframes ktxCheer{0%,100%{transform:rotate(0)}
  30%{transform:rotate(-13deg)}70%{transform:rotate(13deg)}}


/* =======================================================================
   5. THE BALLOON RIDE
   The balloon yard on a bright morning. Our envelope is lying flat on the
   grass and stands up a twelfth at a time as the canisters go on the
   burner; two more balloons are out on the field with their own stamp on
   their baskets. Prefix blx- / .sc-blx — the old balloon game's bl- / bal-
   names are all avoided.
   ======================================================================= */
.sc-blx{position:absolute;inset:0;overflow:hidden}
.blx-sky{position:absolute;inset:0;
  background:linear-gradient(178deg,#7FC9EE 0%,#B4E4F8 40%,#E6F3F4 72%,#F6EFD8 100%)}
.blx-sun{position:absolute;left:8%;top:7%;width:16%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,#FFF7D4,#FFD75E 54%,transparent 72%)}
.blx-cloud{position:absolute;height:14px;border-radius:999px;background:#fff;opacity:.85;
  animation:blxDrift var(--wd,40s) linear infinite}
.blx-cloud::before,.blx-cloud::after{content:'';position:absolute;bottom:0;
  border-radius:50%;background:#fff}
.blx-cloud::before{left:18%;width:38%;height:0;padding-bottom:38%}
.blx-cloud::after{right:22%;width:28%;height:0;padding-bottom:28%}
@keyframes blxDrift{from{transform:translateX(-38vw)}to{transform:translateX(124vw)}}
.blx-trees{position:absolute;left:-6%;right:-6%;bottom:33%;height:9%;
  border-radius:44% 44% 0 0/100% 100% 0 0;background:#6F9E63;
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.blx-grass{position:absolute;left:0;right:0;bottom:0;height:36%;
  background:linear-gradient(180deg,#8FC276 0%,#7CB268 34%,#61945A 100%);
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.blx-grass::after{content:'';position:absolute;left:0;right:0;top:0;height:5px;
  background:rgba(255,255,255,.28)}

/* THE OTHER TWO BALLOONS, out on the same field with the yard's stamp on
   their baskets — the whole reason a perfectly good canister can be the
   wrong canister. Scenery: canisters roll straight past in front. */
.blx-other{position:absolute;z-index:2;pointer-events:none;
  transition:transform 1.5s cubic-bezier(.3,.7,.3,1)}
.blx-other.one{left:2%;bottom:31%;width:20%}
.blx-other.two{right:2%;bottom:33%;width:17.5%}
.blx-obask{position:absolute;left:50%;top:97%;width:34%;height:5.2%;
  transform:translateX(-50%);border-radius:5px;
  background:linear-gradient(180deg,#E3BA83,#C89A61 40%,#A87C48)}
.blx-mark{position:absolute;left:50%;top:calc(97% + 2.6%);transform:translate(-50%,-50%);
  min-width:2.3em;padding:2px 7px;border-radius:8px;background:#EFE7D6;color:#33301F;
  border:2px solid #6E6350;text-align:center;
  font:900 clamp(15px,4.3vw,20px)/1.15 var(--font);
  box-shadow:0 3px 7px rgba(40,70,40,.32)}

/* OURS. One number, --f, runs from 0 to 1 and stands the envelope up out of
   the grass — so every canister has a visible effect on the thing you are
   working towards, not on a counter. */
/* an explicit HEIGHT, because both the envelope and the basket inside it are
   absolutely positioned — without one the rig is a zero-tall box and
   pinWanted refuses to put the wanted-letter tag on anything under 26px */
.blx-rig{position:absolute;left:24%;bottom:26%;width:52%;height:42%;z-index:3;
  transition:transform 1.4s cubic-bezier(.3,.75,.35,1)}
.blx-env{position:absolute;left:0;right:0;bottom:23%;transform-origin:50% 100%;
  transform:translateX(calc((1 - var(--f,0)) * -26%))
            rotate(calc((1 - var(--f,0)) * -15deg))
            scaleX(calc(.74 + .26 * var(--f,0)))
            scaleY(calc(.15 + .85 * var(--f,0)));
  transition:transform .55s cubic-bezier(.3,.8,.4,1)}
.blx-esvg{width:100%;height:auto;display:block;
  filter:drop-shadow(3px 6px 8px rgba(40,70,50,.28))}
.blx-basket{position:absolute;left:29%;width:42%;bottom:0}
.blx-bsvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 5px 6px rgba(60,45,20,.4))}
/* drawn BEFORE the basket, so the basket covers his middle and he is
   peeking over the rim rather than standing on it */
.blx-hog{position:absolute;left:18%;width:64%;bottom:38%}
.blx-hogsvg{width:100%;height:auto;display:block}
/* it has to come out of the BURNER, which is the little grey block at the top
   of the basket svg — 23% up the rig, the same height the envelope's throat
   starts at */
.blx-flame{position:absolute;left:50%;bottom:23%;width:13%;height:0;padding-bottom:16%;
  transform:translateX(-50%) scaleY(.15);transform-origin:50% 100%;opacity:0;
  border-radius:50% 50% 40% 40%/70% 70% 30% 30%;
  background:radial-gradient(ellipse at 50% 80%,#FFF3B0,#FFB03A 46%,#FF6B35 82%);
  transition:opacity .18s ease,transform .18s ease}
.sc-blx.blx-fire .blx-flame{opacity:1;transform:translateX(-50%) scaleY(1);
  animation:blxFlick .16s ease-in-out infinite alternate}
@keyframes blxFlick{from{transform:translateX(-50%) scaleY(.86) scaleX(.9)}
  to{transform:translateX(-50%) scaleY(1.12) scaleX(1.06)}}

.blx-say{position:absolute;left:31%;right:3%;bottom:5%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(40,86,44,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.blx-say.on{opacity:1;transform:none}
.blx-say.her{background:#FFE6EF;color:#8E3B5E}
.blx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.blx-say.her::after{border-top-color:#FFE6EF}

/* what the yard hands roll across the field */
.blx-field{position:absolute;inset:0;z-index:5}
.blx-can{position:absolute;right:-19%;width:18%;border:0;background:transparent;padding:0;z-index:5;
  cursor:pointer;animation:blxRoll var(--dur,6s) linear forwards}
@keyframes blxRoll{from{transform:translateX(0)}to{transform:translateX(-124vw)}}
.blx-roll{display:block;animation:blxTip 1.9s ease-in-out infinite alternate}
@keyframes blxTip{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
.blx-csvg{width:100%;height:auto;display:block;
  filter:drop-shadow(2px 4px 5px rgba(40,60,40,.36))}
/* the canister flies to the basket now — see ctx.fly in session.js */
.blx-can.flying{animation:none}
.blx-can.blx-nope{animation-play-state:paused}
.blx-can.blx-nope .blx-roll{animation:sceneJig .5s ease-in-out 2}

/* THE PAYOFF. It comes off the grass the instant the last canister is in,
   and then the whole field drops away underneath it. */
.sc-blx.blx-lift .blx-rig{transform:translateY(-7%)}
.sc-blx.blx-up .blx-rig{transform:translateY(-36%)}
/* vh, NOT per cent. A percentage translateY is a percentage of the ELEMENT'S
   OWN height, so translateY(26%) moved the 36%-tall grass 82px and the
   9%-tall treeline 20px, and a strip of bare sky opened up between them. */
.sc-blx.blx-up .blx-grass,.sc-blx.blx-up .blx-trees,
.sc-blx.blx-up .blx-other{transform:translateY(11vh)}
.sc-blx.blx-up .blx-sky{filter:saturate(1.12) brightness(1.05)}

/* =======================================================================
   THE SLEEPY BARN                                              slb-
   ======================================================================= */
.sc-slb{position:absolute;inset:0;overflow:hidden;
  background:linear-gradient(180deg,#1E1A2E 0%,#2C2338 55%,#3A2C22 100%);
  transition:background 2.4s ease}
.sc-slb.slb-morning{background:linear-gradient(180deg,#F8E6B2 0%,#EACD8A 55%,#C9985E 100%)}
.slb-wall{position:absolute;inset:0;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.03) 0 12px,rgba(0,0,0,.06) 12px 14px)}
.slb-window{position:absolute;left:5%;top:2.5%;width:20%;aspect-ratio:1;border-radius:50% 50% 8px 8px;
  background:#11162A;box-shadow:inset 0 0 0 5px #5A4030,0 0 0 3px #3A2A20;overflow:hidden;
  transition:background 2.4s ease}
.slb-morning .slb-window{background:linear-gradient(180deg,#8FD5F5,#D6F0FF)}
.slb-window i{position:absolute;border-radius:50%;transition:transform 2.4s var(--spring),opacity 1.6s}
.slb-moon{right:16%;top:12%;width:34%;aspect-ratio:1;background:#FFF1B8;
  box-shadow:inset -8px -4px 0 #E8D48A,0 0 18px rgba(255,241,184,.6)}
.slb-sun{left:22%;top:100%;width:56%;aspect-ratio:1;background:#FFCE3D;
  box-shadow:0 0 0 8px rgba(255,206,61,.35),0 0 30px rgba(255,206,61,.8)}
.slb-morning .slb-moon{transform:translateY(-140%);opacity:0}
.slb-morning .slb-sun{transform:translateY(-118%)}
.slb-beam{position:absolute;left:0;right:0;top:9%;height:5%;
  background:linear-gradient(180deg,#5A4230,#3E2C1E);box-shadow:0 4px 0 #2A1C12}
.slb-lanterns{position:absolute;left:8%;right:8%;top:13%;height:30%;display:flex;
  justify-content:center;gap:6%;z-index:5}
.slb-lantern{border:0;background:transparent;padding:0;cursor:pointer;width:24%;max-width:120px;
  transform-origin:50% 0;transition:transform .5s var(--spring),margin .6s var(--spring);
  -webkit-tap-highlight-color:transparent}
.slb-lantern .slb-lsvg{width:100%;height:auto;display:block;overflow:visible}
.slb-lantern.slb-blank .slb-glass{fill:#26222C;stroke:#4A3C30}
.slb-lantern.next{animation:slbNext 1.1s ease-in-out infinite}
@keyframes slbNext{0%,100%{transform:scale(1)}50%{transform:scale(1.1) rotate(-3deg)}}
.slb-lantern.swing{animation:slbSwing .7s ease-in-out}
@keyframes slbSwing{0%,100%{transform:rotate(0)}25%{transform:rotate(-12deg)}65%{transform:rotate(9deg)}}
.slb-lantern.lit .slb-glass{fill:#FFF0B8;stroke:#B98A3C;transition:fill .3s}
.slb-lantern.lit .slb-letter{fill:#6A4A12}
.slb-lantern.lit .slb-glow{opacity:.55;transition:opacity .4s}
.slb-lanterns.together .slb-lantern{margin:0 -3.5%}
.slb-lanterns.together .slb-lantern.lit{animation:slbBump .7s var(--spring)}
@keyframes slbBump{0%,100%{transform:translateY(0)}40%{transform:translateY(-10px) scale(1.06)}}
.slb-word{position:absolute;left:50%;top:44%;transform:translate(-50%,0) scale(.4);opacity:0;
  font:900 clamp(40px,12vw,64px)/1 var(--font);color:#FFE49A;letter-spacing:.06em;
  text-shadow:0 0 22px rgba(255,210,92,.75),0 4px 0 rgba(0,0,0,.35);z-index:6;
  transition:opacity .4s,transform .6s var(--spring);pointer-events:none}
.slb-word.on{opacity:1;transform:translate(-50%,0) scale(1)}
.slb-morning .slb-word{color:#8E5F2B;text-shadow:none}
.slb-floor{position:absolute;left:0;right:0;bottom:0;height:46%;
  background:linear-gradient(180deg,#5C4426 0%,#8A6A38 40%,#A3823F 100%);
  box-shadow:inset 0 10px 18px rgba(0,0,0,.35);transition:filter 2.4s ease;filter:brightness(.55)}
.slb-morning .slb-floor{filter:brightness(1)}
.slb-sleepers{position:absolute;left:0;right:0;bottom:0;height:52%;z-index:4}
.slb-sleeper{position:absolute;border:0;background:transparent;padding:0;cursor:pointer;
  width:27%;-webkit-tap-highlight-color:transparent;transition:filter 1s ease,transform .3s var(--spring)}
.slb-sleeper .bt-art{display:block;width:100%}
.slb-sleeper .prop-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(3px 5px 5px rgba(20,10,0,.4))}
.slb-sleeper.asleep{filter:brightness(.33) saturate(.35)}
.slb-p0{left:1%;bottom:66%}.slb-p1{left:36%;bottom:70%}.slb-p2{right:1%;bottom:66%}
.slb-p3{left:12%;bottom:38%}.slb-p4{right:12%;bottom:38%}
.slb-zz{position:absolute;right:-6%;top:-18%;color:#CFC6E8;font:900 clamp(13px,3.6vw,18px)/1 var(--font);
  opacity:0;transition:opacity .4s}
.slb-sleeper.asleep .slb-zz{opacity:.9}
.slb-zz i{display:inline-block;font-style:normal;animation:slbZ 2.2s ease-in-out infinite}
.slb-zz i:nth-child(2){animation-delay:.5s;font-size:.8em}
.slb-zz i:nth-child(3){animation-delay:1s;font-size:.65em}
@keyframes slbZ{0%{transform:translateY(0);opacity:0}30%{opacity:1}100%{transform:translateY(-16px) translateX(6px);opacity:0}}
.slb-sleeper.stir{animation:slbStir 1.3s ease-in-out infinite;filter:brightness(.55) saturate(.6)}
@keyframes slbStir{0%,100%{transform:rotate(0)}50%{transform:rotate(-3deg) translateY(-3px)}}
.slb-sleeper.grumble{animation:slbGrumble .8s ease-in-out}
@keyframes slbGrumble{0%,100%{transform:translateX(0)}20%{transform:translateX(-7px) rotate(-3deg)}
  50%{transform:translateX(6px) rotate(3deg)}80%{transform:translateX(-3px)}}
.slb-sleeper.awake{filter:none;transform:translateY(-6px);z-index:5}
.slb-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(10,30,60,.4);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.slb-say.on{opacity:1;transform:none}
.slb-say.her{background:#FFE6EF;color:#8E3B5E}
.slb-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.slb-say.her::after{border-top-color:#FFE6EF}

/* =======================================================================
   THE PET SHOW                                                 psh-
   ======================================================================= */
.sc-psh{position:absolute;inset:0;overflow:hidden;
  background:linear-gradient(180deg,#BFE9FB 0%,#E4F5FF 42%,#8CC96A 42.5%,#6FB350 100%)}
.psh-sky{position:absolute;inset:0;background:
  radial-gradient(circle at 80% 12%,rgba(255,240,180,.9) 0 8%,transparent 9%),
  radial-gradient(circle at 18% 22%,rgba(255,255,255,.85) 0 6%,transparent 7%),
  radial-gradient(circle at 30% 18%,rgba(255,255,255,.85) 0 8%,transparent 9%)}
.psh-bunting{position:absolute;left:-2%;right:-2%;top:1.5%;height:9%}
.psh-bsvg{width:100%;height:100%;display:block;overflow:visible}
.psh-flag{transform-origin:50% 0}
.psh-done .psh-flag{animation:pshFlag 1.2s ease-in-out infinite;animation-delay:var(--d)}
@keyframes pshFlag{0%,100%{transform:skewX(0)}50%{transform:skewX(12deg)}}
.psh-ring{position:absolute;left:4%;right:4%;top:36%;height:30%;border-radius:50%;
  background:radial-gradient(ellipse at 50% 40%,#E9C98A,#CFA765);box-shadow:inset 0 0 0 6px #FFF3D6,0 8px 0 #A98652}
.psh-row{position:absolute;left:3%;right:3%;top:16%;height:46%;display:flex;
  justify-content:space-between;align-items:flex-end;z-index:3}
.psh-stand{position:relative;width:31%;display:flex;flex-direction:column;align-items:center;
  transition:transform .5s var(--spring)}
.psh-stand.now{transform:translateY(-8px) scale(1.04);transform-origin:50% 100%;z-index:4}
.psh-pet{position:relative;width:88%;z-index:2;filter:saturate(.7) brightness(.92);
  transition:filter .4s}
.psh-stand.now .psh-pet,.psh-pet.won{filter:none}
.psh-pet .bt-art{display:block;width:100%}
.psh-pet .prop-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(3px 5px 5px rgba(40,20,4,.3))}
.psh-rosette{position:absolute;right:-8%;top:-14%;width:38%;opacity:0;transform:scale(0) rotate(-30deg);
  transition:transform .6s var(--spring),opacity .3s;pointer-events:none}
.psh-rsvg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 6px rgba(80,40,0,.3))}
.psh-pet.won .psh-rosette{opacity:1;transform:scale(1) rotate(8deg)}
.psh-podium{width:100%;height:18%;min-height:22px;border-radius:8px 8px 4px 4px;
  background:linear-gradient(180deg,#F5D9A0,#D8B276);box-shadow:0 6px 0 #B08B50,inset 0 3px 0 rgba(255,255,255,.6)}
.psh-stand.now .psh-podium{background:linear-gradient(180deg,#FFE9B0,#EFC47A);
  box-shadow:0 6px 0 #B08B50,0 0 0 4px rgba(255,206,61,.55),inset 0 3px 0 rgba(255,255,255,.7)}
.psh-card{margin-top:8px;display:flex;gap:4px;padding:5px;border-radius:10px;
  background:#FFF8EC;box-shadow:0 4px 0 #D8B989,0 6px 12px rgba(40,30,10,.18)}
.psh-slot{width:clamp(22px,7vw,34px);aspect-ratio:.86;border-radius:6px;
  background:rgba(255,235,190,.25);box-shadow:inset 0 0 0 2px rgba(200,160,100,.45);
  display:flex;align-items:center;justify-content:center;
  font:900 clamp(17px,5.4vw,26px)/1 var(--font);color:#5A3E1C;transition:background .3s}
.psh-slot.in{background:linear-gradient(180deg,#FFF6D8,#FFE49A);box-shadow:inset 0 0 0 2px #E2A81F;
  animation:pshIn .5s var(--spring)}
@keyframes pshIn{0%{transform:scale(.4)}60%{transform:scale(1.2)}100%{transform:scale(1)}}
.psh-card.read .psh-slot{animation:pshRead .55s var(--spring)}
.psh-card.read .psh-slot:nth-child(2){animation-delay:.18s}
.psh-card.read .psh-slot:nth-child(3){animation-delay:.36s}
@keyframes pshRead{0%,100%{transform:translateY(0)}45%{transform:translateY(-8px) scale(1.12)}}
.psh-tray{position:absolute;left:3%;right:3%;top:67%;height:17%;display:flex;flex-wrap:nowrap;
  justify-content:center;align-items:center;gap:6px;z-index:5;padding:6px;border-radius:16px;
  background:linear-gradient(180deg,#A47A48,#7E5A32);box-shadow:inset 0 3px 0 rgba(255,255,255,.25),0 6px 0 #5C4022}
.psh-tile{position:relative;border:0;padding:0;cursor:pointer;width:clamp(42px,12.5vw,60px);flex:none;aspect-ratio:1;
  border-radius:12px;background:linear-gradient(180deg,#FFFDF6,#F2E6CE);
  box-shadow:0 4px 0 #C9AE86,0 6px 10px rgba(40,20,4,.25);
  font:900 clamp(26px,8vw,38px)/1 var(--font);color:#3B2A1E;
  transition:transform .55s var(--spring),opacity .3s;-webkit-tap-highlight-color:transparent}
.psh-tile:active{transform:translateY(3px)}
.psh-tray.psh-shut .psh-tile{color:transparent;background:linear-gradient(180deg,#E9D9BC,#D6C39F)}
.psh-tile.nope{animation:pshNope .5s ease-out}
@keyframes pshNope{0%,100%{transform:translateX(0)}25%{transform:translateX(-7px)}65%{transform:translateX(6px)}}
.psh-tile.psh-fly{transform:translate(var(--dx),var(--dy)) scale(.62);z-index:8;pointer-events:none}
.psh-tile.landed{opacity:0}
.psh-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(10,30,60,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.psh-say.on{opacity:1;transform:none}
.psh-say.her{background:#FFE6EF;color:#8E3B5E}
.psh-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.psh-say.her::after{border-top-color:#FFE6EF}

/* =======================================================================
   THE CHALKBOARD                                                 cb-
   ======================================================================= */
.sc-cb{position:absolute;inset:0;overflow:hidden;
  background:linear-gradient(180deg,#FFF3DA 0%,#F6E3C4 100%)}
.cb-wall{position:absolute;inset:0;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.18) 0 18px,rgba(0,0,0,.025) 18px 20px)}
.cb-frame{position:relative;border-radius:10px;padding:5px;
  background:linear-gradient(180deg,#C9A25C,#A57C3C);box-shadow:0 8px 0 #7E5A2A,0 14px 24px rgba(80,50,10,.28)}
.cb-svg{display:block;width:100%;height:auto;border-radius:6px;overflow:visible;
  background:radial-gradient(ellipse at 40% 30%,#3E6B57 0%,#2F5646 70%,#27483B 100%);
  box-shadow:inset 0 0 26px rgba(0,0,0,.35)}
.cb-mo{position:absolute;left:4%;top:2%;width:36%;z-index:3}
.cb-you{position:absolute;left:14%;right:14%;top:27%;z-index:2;touch-action:none}
.cb-label{margin-top:5px;text-align:center;font:800 clamp(12px,3.4vw,16px)/1 var(--font);color:#8E5F2B}
.cb-ink{fill:none;stroke:#FFFCF2;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 2px rgba(255,255,255,.5))}
.cb-chalk{fill:#FFF6DE;opacity:0;filter:drop-shadow(0 2px 2px rgba(0,0,0,.4))}
.cb-svg.cb-wiped .cb-ink{transition:opacity .5s;opacity:0}
.cb-svg.cb-wiped{animation:cbWipe .7s ease-in-out}
@keyframes cbWipe{0%,100%{box-shadow:inset 0 0 26px rgba(0,0,0,.35)}50%{box-shadow:inset 0 0 40px rgba(255,255,255,.25)}}
.cb-guide{fill:none;stroke:transparent;stroke-width:1;pointer-events:none}
.cb-mark{fill:none;stroke:#FFFCF2;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 2px rgba(255,255,255,.45))}
.cb-pad{cursor:crosshair}
.cb-pad.cb-yes .cb-mark{stroke:#FFCE3D;filter:drop-shadow(0 0 8px rgba(255,206,61,.9));transition:stroke .4s}
.cb-pad.cb-no{animation:cbNo .6s ease-out}
@keyframes cbNo{0%,100%{transform:translateX(0)}25%{transform:translateX(-6px)}65%{transform:translateX(5px)}}
.cb-done .cb-you .cb-frame{box-shadow:0 8px 0 #7E5A2A,0 0 0 6px rgba(255,206,61,.55),0 14px 30px rgba(255,206,61,.45);
  animation:cbGlow 1.2s var(--spring)}
@keyframes cbGlow{0%{transform:scale(1)}40%{transform:scale(1.05)}100%{transform:scale(1)}}
.cb-done .cb-pad .cb-mark{stroke:#FFCE3D;filter:drop-shadow(0 0 10px rgba(255,206,61,1))}
.cb-duster{position:absolute;right:-16%;bottom:4%;width:clamp(48px,14vw,64px);aspect-ratio:1.3;border:0;cursor:pointer;
  border-radius:8px;background:linear-gradient(180deg,#F5D9A0,#D8B276);box-shadow:0 5px 0 #A98652,0 8px 14px rgba(80,50,10,.28);
  -webkit-tap-highlight-color:transparent;z-index:4}
.cb-duster i{position:absolute;left:12%;right:12%;bottom:14%;height:36%;border-radius:4px;background:#5A4636;
  box-shadow:inset 0 -4px 0 #3B2A1E}
.cb-duster:active{transform:translateY(3px)}
.cb-duster.wipe{animation:cbDust .5s ease-in-out}
@keyframes cbDust{0%,100%{transform:rotate(0)}30%{transform:rotate(-14deg) translateX(-6px)}70%{transform:rotate(12deg) translateX(6px)}}
.cb-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(10,30,60,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.cb-say.on{opacity:1;transform:none}
.cb-say.her{background:#FFE6EF;color:#8E3B5E}
.cb-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.cb-say.her::after{border-top-color:#FFE6EF}

/* =======================================================================
   THE APPLE CART                                                apc-
   ======================================================================= */
.sc-apc{position:absolute;inset:0;overflow:hidden;
  background:linear-gradient(180deg,#BFE9FB 0%,#E4F5FF 48%,#8CC96A 48.5%,#6FB350 100%)}
.apc-sky{position:absolute;inset:0;background:
  radial-gradient(circle at 82% 10%,#FFCE3D 0 7%,rgba(255,206,61,.35) 7.5%,transparent 10%),
  radial-gradient(circle at 16% 18%,rgba(255,255,255,.9) 0 6%,transparent 7%),
  radial-gradient(circle at 26% 15%,rgba(255,255,255,.9) 0 8%,transparent 9%)}
.apc-hill{position:absolute;left:-10%;right:-10%;top:40%;height:20%;border-radius:50%;background:#9AD27A}
.apc-tree{position:absolute;left:14%;right:14%;top:5%;height:56%}
.apc-trunk{position:absolute;left:44%;width:12%;bottom:0;height:34%;border-radius:8px 8px 0 0;
  background:linear-gradient(90deg,#8E5F2B,#B98346 50%,#7A4E22)}
.apc-crown{position:absolute;left:0;right:0;top:0;height:74%;border-radius:48% 52% 45% 55%/55% 50% 50% 45%;
  background:radial-gradient(circle at 35% 30%,#8ED57A,#4FA85C 70%,#3E8A4A);box-shadow:inset -10px -14px 0 rgba(0,0,0,.08)}
.apc-fruit{position:absolute;left:0;right:0;top:0;height:74%}
.apc-apple{position:absolute;border:0;background:transparent;padding:0;cursor:pointer;width:17%;
  transform:translate(-50%,-50%);animation:apcGrow .5s var(--spring) both;animation-delay:var(--d);
  -webkit-tap-highlight-color:transparent;transition:transform .5s var(--spring)}
@keyframes apcGrow{0%{transform:translate(-50%,-50%) scale(0)}100%{transform:translate(-50%,-50%) scale(1)}}
.apc-svg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(0 3px 4px rgba(60,20,0,.3))}
.apc-apple:active{transform:translate(-50%,-50%) scale(1.15)}
.apc-apple.drop{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(.7);z-index:6;animation:none}
.apc-apple.bounce{animation:apcBounce .6s var(--spring)}
@keyframes apcBounce{0%,100%{transform:translate(-50%,-50%)}40%{transform:translate(-50%,-90%) rotate(-12deg)}}
.apc-apple.bad.squash{animation:apcSquash .5s ease-out}
@keyframes apcSquash{0%,100%{transform:translate(-50%,-50%) scaleY(1)}50%{transform:translate(-50%,-30%) scaleY(.5) scaleX(1.3)}}
.apc-ground{position:absolute;left:0;right:0;bottom:0;height:40%}
.apc-customer{position:absolute;left:4%;bottom:16%;width:22%;opacity:0;transition:opacity .5s,transform .6s var(--spring);transform:translateX(-40px)}
.apc-customer.arrive{opacity:1;transform:translateX(0)}
.apc-customer .bt-art{display:block;width:100%}
.apc-customer .prop-svg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(3px 5px 5px rgba(40,20,4,.3))}
.apc-cart{position:absolute;right:6%;bottom:14%;width:52%;height:22%;transition:transform .8s ease-in}
.apc-cart.roll{transform:translateX(120%)}
.apc-cart.full-bump{animation:apcBump .5s ease-out}
@keyframes apcBump{0%,100%{transform:translateY(0)}40%{transform:translateY(-6px)}}
.apc-bed{position:absolute;left:0;right:0;top:0;bottom:22%;border-radius:6px 6px 14px 14px;
  background:linear-gradient(180deg,#C9A25C,#A57C3C);box-shadow:inset 0 -6px 0 rgba(0,0,0,.12),0 6px 0 #7E5A2A}
.apc-slots{position:absolute;inset:8% 6%;display:flex;flex-wrap:wrap;gap:4px 6px;align-content:center;justify-content:center}
.apc-slot{width:17%;aspect-ratio:1;border-radius:50%;border:2px dashed rgba(255,248,236,.7);box-sizing:border-box;
  display:flex;align-items:center;justify-content:center}
.apc-slots.many .apc-slot{width:15%}
.apc-slot.in{border-color:transparent;animation:apcIn .5s var(--spring)}
.apc-slot .apc-svg{width:100%}
@keyframes apcIn{0%{transform:scale(.4)}60%{transform:scale(1.2)}100%{transform:scale(1)}}
.apc-cart.full .apc-bed{box-shadow:inset 0 -6px 0 rgba(0,0,0,.12),0 6px 0 #7E5A2A,0 0 0 5px rgba(255,206,61,.5)}
.apc-wheel{position:absolute;bottom:0;width:22%;aspect-ratio:1;border-radius:50%;background:#5A4636;
  box-shadow:inset 0 0 0 6px #8E5F2B,inset 0 0 0 9px #5A4636}
.apc-wheel.a{left:10%}.apc-wheel.b{right:10%}
.apc-cart.roll .apc-wheel{animation:apcSpin .8s linear infinite}
@keyframes apcSpin{to{transform:rotate(360deg)}}
.apc-handle{position:absolute;left:-16%;top:30%;width:18%;height:8%;border-radius:4px;background:#8E5F2B;transform:rotate(-20deg)}
.apc-count{position:absolute;left:50%;top:60%;transform:translate(-50%,-50%);font:900 clamp(40px,12vw,70px)/1 var(--font);
  color:var(--deep);text-shadow:0 4px 0 #fff;pointer-events:none;opacity:0}
.apc-count.pop{animation:apcPop 1s var(--spring)}
@keyframes apcPop{0%{opacity:0;transform:translate(-50%,-50%) scale(.4)}25%{opacity:1;transform:translate(-50%,-50%) scale(1.2)}70%{opacity:1}100%{opacity:0;transform:translate(-50%,-70%) scale(1)}}
.apc-count.big{opacity:1;animation:none;transform:translate(-50%,-50%) scale(1.3);text-shadow:0 0 24px rgba(255,206,61,.9),0 4px 0 #fff}
.apc-done .apc-crown{box-shadow:inset -10px -14px 0 rgba(0,0,0,.08),0 0 0 8px rgba(255,206,61,.4)}
.apc-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);
  box-shadow:0 6px 16px rgba(10,30,60,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;
  transition:all .34s var(--spring);pointer-events:none}
.apc-say.on{opacity:1;transform:none}
.apc-say.her{background:#FFE6EF;color:#8E3B5E}
.apc-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;
  border:10px solid transparent;border-top-color:#FFF8EC}
.apc-say.her::after{border-top-color:#FFE6EF}

/* =======================================================================
   PACK THE EGGS                                                 egx-
   ======================================================================= */
.sc-egx{position:absolute;inset:0;overflow:hidden;background:linear-gradient(180deg,#FFF3DA 0%,#F6E3C4 100%)}
.egx-wall{position:absolute;inset:0;background:repeating-linear-gradient(90deg,rgba(255,255,255,.18) 0 18px,rgba(0,0,0,.025) 18px 20px)}
.egx-counter{position:absolute;left:0;right:0;top:56%;height:44%;background:linear-gradient(180deg,#C9A25C,#A57C3C 30%,#8E5F2B);box-shadow:inset 0 8px 0 #E7C79B}
.egx-order{position:absolute;left:5%;top:15%;width:52%;display:flex;flex-direction:column;gap:8px;z-index:3}
.egx-ticket{background:#FFFDF6;border-radius:10px;padding:8px 10px;box-shadow:0 5px 0 #D8B989,0 8px 14px rgba(80,50,10,.18);
  display:flex;align-items:baseline;gap:8px;transform:rotate(-2deg)}
.egx-want{font:900 clamp(34px,10vw,52px)/1 var(--font);color:#E45B4A}
.egx-ticket i{font:700 clamp(12px,3.4vw,15px)/1.1 var(--font);color:#8E5F2B;font-style:normal}
.egx-have{display:flex;gap:6px;justify-content:center}
.egx-have b{width:clamp(48px,14vw,66px);aspect-ratio:.9;border-radius:12px;display:flex;align-items:center;justify-content:center;
  font:900 clamp(30px,9vw,46px)/1 var(--font);color:#B5A48E;background:#FFF8EC;box-shadow:inset 0 0 0 3px #E9DED0,0 4px 0 #D8B989}
.egx-tens.lit{color:#1F5E8A;box-shadow:inset 0 0 0 3px #6EC6F0,0 4px 0 #D8B989}
.egx-ones.lit{color:#B8600F;box-shadow:inset 0 0 0 3px #FFCE3D,0 4px 0 #D8B989}
.egx-have b.flash{animation:egxFlash .5s var(--spring)}
@keyframes egxFlash{0%{transform:scale(1)}40%{transform:scale(1.25)}100%{transform:scale(1)}}
.egx-crate{position:absolute;right:4%;top:14%;width:36%;height:40%;border-radius:10px;
  background:linear-gradient(180deg,#D8B276,#B98346);box-shadow:inset 0 0 0 5px #E7C79B,0 6px 0 #7E5A2A;
  transition:transform .8s ease-in,opacity .8s;overflow:hidden}
.egx-crate.full{box-shadow:inset 0 0 0 5px #E7C79B,0 6px 0 #7E5A2A,0 0 0 5px rgba(255,206,61,.55)}
.egx-crate.off{transform:translateX(140%);opacity:0}
.egx-packed{position:absolute;inset:8px;display:flex;flex-wrap:wrap;gap:3px;align-content:flex-start}
.egx-box{width:48%;animation:egxIn .45s var(--spring)}
.egx-egg{width:13%;animation:egxIn .45s var(--spring)}
.egx-box .egx-svg,.egx-egg .egx-svg{width:100%;height:auto;display:block}
@keyframes egxIn{0%{transform:scale(.3)}60%{transform:scale(1.15)}100%{transform:scale(1)}}
.egx-pile,.egx-basket{position:absolute;top:60%;border:0;cursor:pointer;padding:8px 8px 10px;border-radius:16px;
  background:linear-gradient(180deg,#FFFDF6,#F2E6CE);box-shadow:0 6px 0 #C9AE86,0 10px 16px rgba(40,20,4,.25);
  display:flex;flex-direction:column;align-items:center;gap:4px;-webkit-tap-highlight-color:transparent;transition:transform .16s var(--spring)}
.egx-pile{left:8%;width:40%}
.egx-basket{right:10%;width:26%}
.egx-pile .egx-svg{width:100%;height:auto;display:block}
.egx-basket .egx-svg{width:52%;height:auto;display:block}
.egx-pile span,.egx-basket span{font:900 clamp(20px,6vw,30px)/1 var(--font);color:#5A3E1C}
.egx-pile:active,.egx-basket:active{transform:translateY(4px)}
.egx-pile.next,.egx-basket.next{animation:egxNext 1.1s ease-in-out infinite}
@keyframes egxNext{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.egx-pile.nope{animation:egxNope .5s ease-out}
@keyframes egxNope{0%,100%{transform:translateX(0)}25%{transform:translateX(-8px) rotate(-3deg)}65%{transform:translateX(7px) rotate(3deg)}}
.egx-done .egx-order .egx-ticket{background:#E6FAE2}
.egx-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;
  background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);box-shadow:0 6px 16px rgba(10,30,60,.3);
  opacity:0;transform:translateY(8px) scale(.9);transform-origin:8% 100%;transition:all .34s var(--spring);pointer-events:none}
.egx-say.on{opacity:1;transform:none}
.egx-say.her{background:#FFE6EF;color:#8E3B5E}
.egx-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;border:10px solid transparent;border-top-color:#FFF8EC}
.egx-say.her::after{border-top-color:#FFE6EF}

/* =======================================================================
   YOUR NAME                                                     nmg-
   ======================================================================= */
.sc-nmg{position:absolute;inset:0;overflow:hidden;background:linear-gradient(180deg,#DDF3EE 0%,#CDEDE6 58%,#E9CFA3 58.5%,#D9B888 100%)}
.nmg-wall{position:absolute;inset:0;background:repeating-linear-gradient(90deg,rgba(255,255,255,.14) 0 16px,rgba(0,0,0,.02) 16px 18px)}
.nmg-rail{position:absolute;left:8%;right:8%;top:9%;height:3.5%;border-radius:6px;background:linear-gradient(180deg,#C9A25C,#A57C3C);box-shadow:0 5px 0 #7E5A2A}
.nmg-peg{position:absolute;left:50%;top:12%;width:6%;height:6%;transform:translateX(-50%)}
.nmg-peg i{display:block;width:100%;height:100%;border-radius:0 0 50% 50%;background:#8E5F2B}
.nmg-coat{position:absolute;left:50%;top:14%;width:26%;transform:translate(-50%,-30%) scale(.6);opacity:0;transition:transform .7s var(--spring),opacity .4s}
.nmg-coat.up{opacity:1;transform:translate(-50%,0) scale(1)}
.nmg-svg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(3px 5px 5px rgba(40,20,4,.28))}
.nmg-card{position:absolute;left:6%;right:6%;top:36%;padding:12px 8px;border-radius:14px;background:#FFF8EC;
  box-shadow:0 5px 0 #D8B989,0 8px 16px rgba(40,30,10,.18);display:grid}
.nmg-ghost,.nmg-slots{grid-area:1/1;display:flex;justify-content:center;gap:5px}
.nmg-g,.nmg-slot{width:clamp(34px,10vw,50px);aspect-ratio:.86;border-radius:8px;display:flex;align-items:center;justify-content:center;
  font:900 clamp(24px,7.4vw,36px)/1 var(--font)}
.nmg-g{color:rgba(90,62,28,.22);opacity:0}
.nmg-card.nmg-copy .nmg-g{opacity:1}
.nmg-slot{background:rgba(255,235,190,.3);box-shadow:inset 0 0 0 2px rgba(200,160,100,.45);color:#5A3E1C}
.nmg-slot.in{background:linear-gradient(180deg,#FFF6D8,#FFE49A);box-shadow:inset 0 0 0 2px #E2A81F;animation:pshIn .5s var(--spring)}
.nmg-card.nmg-read .nmg-slot{animation:pshRead .55s var(--spring)}
.nmg-done .nmg-card{box-shadow:0 5px 0 #D8B989,0 0 0 5px rgba(255,206,61,.55),0 10px 24px rgba(255,206,61,.4)}
.nmg-tray{position:absolute;left:3%;right:3%;top:58%;min-height:17%;display:flex;flex-wrap:wrap;justify-content:center;align-content:center;gap:7px;
  padding:8px;border-radius:16px;background:linear-gradient(180deg,#A47A48,#7E5A32);box-shadow:inset 0 3px 0 rgba(255,255,255,.25),0 6px 0 #5C4022;z-index:5}
.nmg-tile{position:relative;border:0;padding:0;cursor:pointer;width:clamp(42px,12vw,58px);flex:none;aspect-ratio:1;border-radius:12px;
  background:linear-gradient(180deg,#FFFDF6,#F2E6CE);box-shadow:0 4px 0 #C9AE86,0 6px 10px rgba(40,20,4,.25);
  font:900 clamp(24px,7.6vw,36px)/1 var(--font);color:#3B2A1E;transition:transform .55s var(--spring),opacity .3s;-webkit-tap-highlight-color:transparent}
.nmg-tile.nope{animation:pshNope .5s ease-out}
.nmg-tile.nmg-fly{transform:translate(var(--dx),var(--dy)) scale(.72);z-index:8;pointer-events:none}
.nmg-tile.landed{opacity:0}
.nmg-say{position:absolute;left:31%;right:3%;bottom:9%;z-index:9;background:#FFF8EC;border-radius:14px;padding:9px 14px;color:#5A4636;
  font:800 clamp(14px,3.9vw,18px)/1.35 var(--font);box-shadow:0 6px 16px rgba(10,30,60,.3);opacity:0;transform:translateY(8px) scale(.9);
  transform-origin:8% 100%;transition:all .34s var(--spring);pointer-events:none}
.nmg-say.on{opacity:1;transform:none}
.nmg-say.her{background:#FFE6EF;color:#8E3B5E}
.nmg-say::after{content:'';position:absolute;left:7%;top:100%;width:0;height:0;border:10px solid transparent;border-top-color:#FFF8EC}
.nmg-say.her::after{border-top-color:#FFE6EF}

/* OWL GOES HOME — the trail of lights, and the owl actually moving along it */
.sc-owx{--owx-x:0}
.sc-owx .owx-owl{left:calc(12% + var(--owx-x) * 34%);transition:left .7s var(--spring)}
.owx-trail{position:absolute;left:5%;right:5%;bottom:20%;height:34px;z-index:8;
  display:flex;align-items:center;gap:0;pointer-events:none}
.owx-trail i{flex:1;height:9px;margin:0 2px;border-radius:5px;background:rgba(255,255,255,.18);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.22);transition:background .3s,box-shadow .3s}
.owx-trail i.lit{background:#FFCE3D;box-shadow:0 0 10px 2px rgba(255,206,61,.75);
  animation:owxLit .5s var(--spring)}
@keyframes owxLit{0%{transform:scaleY(1)}50%{transform:scaleY(1.9)}100%{transform:scaleY(1)}}
.owx-tmark,.owx-ttree{flex:none;width:30px;height:34px}
.owx-tmark svg,.owx-ttree svg{width:100%;height:100%;display:block;overflow:visible;
  filter:drop-shadow(0 2px 3px rgba(0,10,30,.5))}
.owx-tmark{animation:owxGlide 3.2s ease-in-out infinite}
.sc-owx.owx-there .owx-twin{fill:#FFE49A;filter:drop-shadow(0 0 6px #FFCE3D)}

/* ---- another angle: odd one out, big and small ---- */
.an-scene{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:clamp(14px,4vh,30px);
  background:radial-gradient(70% 46% at 50% 40%,rgba(255,255,255,.9),transparent 70%),linear-gradient(180deg,#FFF6E9 0%,#FFE9D2 100%)}
.an-say{font-size:clamp(15px,4.2vw,19px);font-weight:800;color:var(--ink-soft);background:rgba(255,255,255,.85);padding:8px 16px;border-radius:18px}
.an-row{display:flex;gap:clamp(10px,3vw,18px);flex-wrap:wrap;justify-content:center;padding:0 12px}
.an-tile{width:clamp(70px,20vw,110px);height:clamp(84px,24vw,130px);border:0;cursor:pointer;border-radius:22px;
  font:800 clamp(44px,13vw,72px)/1 var(--font);color:var(--deep);background:linear-gradient(180deg,#fff,#FFF6E9);
  box-shadow:var(--lift-2),var(--gloss);position:relative;opacity:0;transform:translateY(24px) scale(.7) rotate(var(--r,0deg));
  transition:transform .5s var(--spring),opacity .3s}
.an-tile::before{content:'';position:absolute;inset:0;border-radius:inherit;padding:3px;background:linear-gradient(135deg,var(--sun),var(--sky));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.an-tile.in{opacity:1;transform:translateY(0) scale(1) rotate(var(--r,0deg))}
.an-tile.lower{color:var(--honey)}
.an-tile.yes{transform:scale(1.15) !important;box-shadow:0 0 0 5px var(--leaf),var(--lift-2)}
.an-tile.fade{opacity:.25}
.an-tile.no{animation:anNo .5s}
@keyframes anNo{0%,100%{transform:translateX(0) scale(1)}25%{transform:translateX(-8px)}75%{transform:translateX(8px)}}
.an-big{font:800 clamp(90px,26vw,150px)/1 var(--font);color:var(--deep);text-shadow:0 6px 0 rgba(255,255,255,.9);transition:transform .4s var(--spring)}
.an-big.pop{animation:bump .5s var(--spring)}
.an-big.match{transform:scale(1.12);color:var(--leaf)}

/* ---- pairs ---- */
.pr-scene{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(70% 46% at 50% 40%,rgba(255,255,255,.9),transparent 70%),linear-gradient(180deg,#FFF0F6 0%,#FFE3ED 100%)}
.pr-grid{display:grid;grid-template-columns:repeat(2,clamp(92px,26vw,150px));gap:clamp(10px,3vw,18px);padding:0 12px}
.pr-card{position:relative;height:clamp(110px,31vw,180px);border:0;background:none;padding:0;cursor:pointer;perspective:700px;
  opacity:0;transform:translateY(30px);transition:opacity .3s,transform .5s var(--spring);transition-delay:var(--d,0ms)}
.pr-grid.dealt .pr-card{opacity:1;transform:none}
.pr-face{position:absolute;inset:0;border-radius:18px;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform .5s var(--spring);
  display:grid;place-items:center;box-shadow:var(--lift-2),var(--gloss)}
.pr-back{background:linear-gradient(135deg,#8A6BD8,#5FB1DD);transform:rotateY(0)}
.pr-back i{position:absolute;width:26%;height:26%;border-radius:50%;background:rgba(255,255,255,.28)}
.pr-back i:nth-child(1){left:14%;top:14%}.pr-back i:nth-child(2){right:14%;top:40%}.pr-back i:nth-child(3){left:30%;bottom:12%}
.pr-front{background:linear-gradient(180deg,#fff,#FFF6E9);color:var(--deep);font:800 clamp(48px,14vw,80px)/1 var(--font);transform:rotateY(180deg)}
.pr-card.up .pr-back,.pr-card.done .pr-back{transform:rotateY(180deg)}
.pr-card.up .pr-front,.pr-card.done .pr-front{transform:rotateY(0)}
.pr-card.done .pr-front{box-shadow:0 0 0 5px var(--leaf),var(--lift-2)}
.pr-grid.all .pr-card{animation:bump .6s var(--spring)}

/* ---- sort the post: a postbox, and Mo with his bag ---- */
.sp-scene{position:absolute;inset:0;overflow:hidden;
  background:linear-gradient(180deg,#FFF6E9 0%,#F3E2C8 58%,#D9B888 58.5%,#C9A05E 100%)}
.sp-box{position:absolute;left:6%;bottom:22%;width:22%;height:30%;border-radius:40% 40% 8px 8px;
  background:linear-gradient(90deg,#C25141,#E0714E 40%,#B4533A);box-shadow:var(--lift-2),inset 0 3px 0 rgba(255,255,255,.3);transition:transform .25s var(--spring),box-shadow .25s}
.sp-box::before{content:'';position:absolute;left:10%;right:10%;top:-8%;height:18%;border-radius:50%;background:#A84034}
.sp-box .sp-slot{position:absolute;left:22%;right:22%;top:30%;height:9%;border-radius:4px;background:#3B2A1E}
.sp-box.lit{transform:scale(1.08);box-shadow:0 0 0 6px var(--sun),var(--lift-2)}
.sp-box.gulp{animation:spGulp .5s var(--spring)}
@keyframes spGulp{0%{transform:scaleY(1)}40%{transform:scaleY(.92) scaleX(1.06)}100%{transform:scaleY(1)}}
.sp-mo{position:absolute;right:4%;bottom:20%;width:34%;height:34%;display:flex;align-items:flex-end;justify-content:center;transition:transform .25s var(--spring)}
.sp-mo .char{width:100%}
.sp-mo .char svg{width:100%;height:auto;display:block;overflow:visible}
.sp-mo .sp-bag{position:absolute;left:-18%;bottom:6%;width:44%;height:40%;border-radius:12px 12px 18px 18px;background:linear-gradient(180deg,#FFCE3D,#F0A93B);
  box-shadow:var(--lift-2);display:grid;place-items:center;font:800 clamp(26px,8vw,44px)/1 var(--font);color:#fff;text-shadow:0 2px 0 rgba(0,0,0,.2)}
.sp-mo .sp-bag::before{content:'';position:absolute;left:24%;right:24%;top:-12px;height:16px;border:4px solid #C9862A;border-bottom:0;border-radius:12px 12px 0 0}
.sp-mo.lit{transform:scale(1.06)}
.sp-mo.lit .sp-bag{box-shadow:0 0 0 6px var(--sun),var(--lift-2)}
.sp-sack{position:absolute;left:50%;bottom:4%;width:26%;height:16%;transform:translateX(-50%);border-radius:30% 30% 40% 40%;background:linear-gradient(180deg,#B9A58F,#8A7A66);box-shadow:var(--lift-2)}
.sp-sack::before{content:'';position:absolute;left:30%;right:30%;top:-10px;height:14px;border-radius:50%;background:#6E5F4E}
.sp-tray{position:absolute;left:0;right:0;top:16%;height:36%;display:flex;align-items:center;justify-content:center}
.sp-env{position:absolute;width:min(48vw,200px);aspect-ratio:1.5;border-radius:12px;background:linear-gradient(180deg,#FFFDF7,#FFF1D8);
  box-shadow:0 0 0 3px #E2C89A,0 14px 24px rgba(59,42,30,.22);display:grid;place-items:center;touch-action:none;cursor:grab;z-index:5;
  opacity:0;transform:translateY(60px) scale(.8);transition:opacity .3s,transform .5s var(--spring)}
.sp-env.in{opacity:1;transform:none}
.sp-env.held{transition:none;cursor:grabbing;z-index:9}
.sp-flap{position:absolute;left:0;right:0;top:0;height:50%;background:linear-gradient(180deg,#F3E2C8,#E2C89A);clip-path:polygon(0 0,100% 0,50% 100%);opacity:.9}
.sp-stamp{position:relative;z-index:1;width:36%;aspect-ratio:1;border-radius:6px;background:#fff;box-shadow:0 0 0 3px #FF9EC0,0 0 0 6px #fff;
  display:grid;place-items:center;font:800 clamp(34px,10vw,54px)/1 var(--font);color:var(--deep);margin-top:22%}
.sp-env.demo{cursor:default}
.sp-env.fly-mo{transition:transform 1.1s ease-in-out;transform:translate(30vw,26vh) rotate(8deg) scale(.7) !important}
.sp-env.fly-box{transition:transform 1.1s ease-in-out;transform:translate(-32vw,24vh) rotate(-8deg) scale(.7) !important}
.sp-env.to-mo{transition:transform .45s ease-in,opacity .3s .2s;transform:translate(30vw,30vh) scale(.2) !important;opacity:0}
.sp-env.to-box{transition:transform .45s ease-in,opacity .3s .2s;transform:translate(-32vw,26vh) scale(.2) !important;opacity:0}
.sp-env.nope{animation:anNo .5s}

/* ---- build the letter ---- */
.bl-scene{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:6px;padding-top:15%;
  background:radial-gradient(70% 46% at 50% 36%,rgba(255,255,255,.9),transparent 70%),linear-gradient(180deg,#FFF6E9 0%,#F3E2C8 100%)}
.bl-board{width:min(54vw,260px);height:auto;overflow:visible}
.bl-ghost{fill:none;stroke:rgba(59,42,30,.14);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:6 8}
.bl-home{fill:none;stroke-width:18;stroke-linecap:round;stroke-linejoin:round;opacity:0;transition:opacity .3s}
.bl-home.in{opacity:1}
.bl-board.done{animation:bump .6s var(--spring);opacity:.12;transition:opacity .5s .6s}
.bl-tray{position:absolute;left:4%;right:4%;bottom:6%;height:24%;display:flex;align-items:center;justify-content:space-evenly;gap:2%;
  background:linear-gradient(180deg,#D9B27C,#B98A50);border-radius:18px;box-shadow:var(--lift-2),inset 0 3px 0 rgba(255,255,255,.35)}
.bl-piece{width:20%;max-width:100px;max-height:80%;height:auto;overflow:visible;touch-action:none;cursor:grab;filter:drop-shadow(2px 5px 5px rgba(59,42,30,.28));transition:transform .35s var(--spring)}
.bl-piece path{fill:none;stroke-width:18;stroke-linecap:round;stroke-linejoin:round}
.bl-piece.drag{transition:none;z-index:9;filter:drop-shadow(0 12px 14px rgba(59,42,30,.35))}
.bl-piece.placed{opacity:0;pointer-events:none;transition:opacity .25s}
.bl-piece.demo{animation:blDemo 1.5s ease-in-out forwards}
@keyframes blDemo{0%{transform:none}70%{transform:translateY(-38vh) scale(1.3)}100%{transform:translateY(-40vh) scale(1.3);opacity:0}}
.bl-pic{position:absolute;left:50%;top:34%;transform:translate(-50%,-50%) scale(.3);opacity:0;width:min(52vw,240px);text-align:center;pointer-events:none;transition:opacity .35s,transform .7s var(--spring)}
.bl-pic.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.bl-pic .shape-svg{width:100%;height:auto;display:block;filter:drop-shadow(0 10px 14px rgba(59,42,30,.18))}
.bl-pic b{display:block;margin-top:4px;font-size:clamp(16px,4.6vw,22px);color:var(--ink);background:rgba(255,255,255,.85);border-radius:14px;padding:5px 12px}

/* ---- letter hunt ---- */
.lh-scene{position:absolute;inset:0;overflow:hidden}
.lh-sky{position:absolute;inset:0;background:linear-gradient(180deg,#BFE9FB,#EAF7FF 60%)}
.lh-sun{position:absolute;right:8%;top:5%;width:14%;padding-bottom:14%;border-radius:50%;background:radial-gradient(circle at 40% 36%,#FFE79A,#FFCE3D 62%);box-shadow:0 0 30px 8px rgba(255,206,61,.4)}
.lh-hill{position:absolute;bottom:26%;border-radius:50% 50% 0 0}
.lh-hill.h1{left:-10%;width:70%;height:30%;background:#A9DD8E}
.lh-hill.h2{right:-14%;width:72%;height:36%;background:#98D686}
.lh-grass{position:absolute;left:0;right:0;bottom:0;height:30%;background:linear-gradient(180deg,#8AD37F,#5FAE58)}
.lh-tree{position:absolute;bottom:26%;width:16%;padding-bottom:30%;background:radial-gradient(circle at 50% 30%,#6BC46A,#4FA85C 70%);border-radius:50% 50% 45% 45%}
.lh-tree::after{content:'';position:absolute;left:44%;bottom:-24%;width:12%;height:40%;background:#8E5F2B;border-radius:4px}
.lh-tree.t1{left:6%}.lh-tree.t2{right:10%;width:20%;padding-bottom:36%}
.lh-bush{position:absolute;bottom:22%;width:18%;height:12%;border-radius:50%;background:#4FA85C}
.lh-bush.b1{left:30%}.lh-bush.b2{right:34%;background:#6BC46A}
.lh-count{position:absolute;left:50%;top:17%;transform:translateX(-50%);display:flex;gap:8px;background:rgba(255,255,255,.85);padding:6px 12px;border-radius:16px;z-index:5}
.lh-count i{width:16px;height:16px;border-radius:50%;background:#E6D8C4;display:block}
.lh-count i.on{background:var(--sun);box-shadow:0 0 0 3px #fff,0 0 8px var(--sun)}
.lh-l{position:absolute;transform:translate(-50%,-50%) rotate(var(--r)) scale(var(--s));border:0;background:none;cursor:pointer;padding:6px;
  font:800 clamp(44px,12vw,70px)/1 var(--font);color:var(--c);text-shadow:0 3px 0 rgba(0,0,0,.12);z-index:3;transition:transform .4s var(--spring),opacity .4s}
.lh-l.got{transform:translate(-50%,-50%) rotate(0) scale(1.3);color:var(--sun);text-shadow:0 0 0 #fff,0 0 18px #fff;opacity:.35}
.lh-l.no{animation:anNo .5s}
.lh-l.peek{animation:lhPeek .9s var(--spring)}
@keyframes lhPeek{0%,100%{transform:translate(-50%,-50%) rotate(var(--r)) scale(var(--s))}50%{transform:translate(-50%,-56%) rotate(var(--r)) scale(calc(var(--s) * 1.25))}}

/* ---- your letter in your name ---- */
.nm-scene{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;
  background:radial-gradient(70% 46% at 50% 40%,rgba(255,255,255,.9),transparent 70%),linear-gradient(180deg,#FFF6E9 0%,#FFE9D2 100%)}
.nm-say{font-size:clamp(15px,4.2vw,19px);font-weight:800;color:var(--ink-soft);background:rgba(255,255,255,.85);padding:8px 16px;border-radius:18px}
.nm-row{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(6px,2vw,12px);padding:0 10px}
.nm-t{width:clamp(50px,13vw,84px);height:clamp(62px,16vw,104px);border:0;cursor:pointer;border-radius:16px;font:800 clamp(34px,9vw,58px)/1 var(--font);color:var(--deep);
  background:linear-gradient(180deg,#fff,#FFF6E9);box-shadow:var(--lift-2),var(--gloss);opacity:0;transform:translateY(-40px) scale(.6);transition:transform .6s var(--spring),opacity .3s;transition-delay:var(--d,0ms)}
.nm-row.in .nm-t{opacity:1;transform:none}
.nm-t.got{box-shadow:0 0 0 5px var(--sun),var(--lift-2);color:var(--honey);transform:scale(1.1) !important}
.nm-t.no{animation:anNo .5s}
.nm-row.all .nm-t{animation:bump .6s var(--spring)}

/* build the letter: one piece at a time */
.bl-piece{opacity:.35;filter:grayscale(.4) drop-shadow(2px 5px 5px rgba(59,42,30,.28));pointer-events:none}
.bl-piece.next{opacity:1;filter:drop-shadow(0 0 12px rgba(255,206,61,.95)) drop-shadow(2px 5px 5px rgba(59,42,30,.28));pointer-events:auto;animation:blBreath 1.4s ease-in-out infinite}
@keyframes blBreath{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
.bl-piece.next.drag{animation:none}
.bl-ghost.want{stroke:rgba(255,206,61,.75);stroke-dasharray:none;animation:blWant 1.2s ease-in-out infinite}
@keyframes blWant{0%,100%{stroke:rgba(255,206,61,.55)}50%{stroke:rgba(255,206,61,1)}}
/* your name: the tiles jumble */
.nm-row .nm-t{order:var(--o,0)}
.nm-row.jumbled{animation:nmShake .6s ease-in-out}
@keyframes nmShake{0%,100%{transform:none}25%{transform:translateX(-8px) rotate(-2deg)}75%{transform:translateX(8px) rotate(2deg)}}

/* ============================================ THE BANDSTAND (song, rebuilt)
   Prefix bnd- because sg- is already Show the Way's, and index.html is one
   stylesheet shared by every game — a bare or borrowed prefix is the commonest
   way to break a game without touching its code.

   The old version drew a five-line musical stave, which is a thing a
   three-year-old has never seen. This draws a bandstand with a music stand in
   it: the notes go back on the stand, higher note higher up, and three birds
   sing them. The stave is gone; the shape of the tune is still visible,
   because the notes really do climb and fall with the pitch. */
.bnd-scene{position:absolute;inset:0;overflow:hidden}
.bnd-sky{position:absolute;inset:0;background:linear-gradient(#BFE8FA,#E8F6FF 62%,#DFF3E0)}
.bnd-hill{position:absolute;left:-10%;right:-10%;bottom:14%;height:34%;border-radius:50% 50% 0 0;background:#9BD98C}
.bnd-ground{position:absolute;left:0;right:0;bottom:0;height:20%;background:linear-gradient(#7FC96F,#63B355)}

/* the bandstand: a roof, the stand the music sits on, two legs */
.bnd-stand{position:absolute;left:6%;right:6%;bottom:26%;height:46%}
.bnd-roof{position:absolute;left:-2%;right:-2%;top:0;height:16%;
  background:linear-gradient(#FF9EC0,#E8577A);border-radius:14px 14px 4px 4px;
  box-shadow:0 3px 0 rgba(0,0,0,.10)}
.bnd-board{position:absolute;left:0;right:0;top:18%;bottom:14%;
  background:linear-gradient(#FFF9EC,#FFF0D2);border-radius:12px;
  border:3px solid #E0C79A;box-shadow:inset 0 2px 8px rgba(138,90,43,.12)}
.bnd-legs{position:absolute;left:0;right:0;bottom:0;height:14%}
.bnd-legs i{position:absolute;bottom:0;width:5%;height:100%;background:#C9862A;border-radius:3px}
.bnd-legs i:first-child{left:22%}
.bnd-legs i:last-child{right:22%}

/* WHERE A NOTE GOES. Empty it is a faint dish; filled it is a real note head
   with a stem, in the colour of its pitch. Higher pitch sits higher up, so the
   shape of the tune is drawn across the stand as the child builds it. */
.bnd-slot{position:absolute;width:11%;aspect-ratio:1;transform:translate(-50%,50%);
  border-radius:50%;background:rgba(138,90,43,.10);
  box-shadow:inset 0 0 0 2px rgba(138,90,43,.16)}
.bnd-slot.bnd-on{background:var(--nc,#FFCE3D);box-shadow:0 2px 0 rgba(0,0,0,.12)}
/* the stem hugs the right edge of the head and rises from its middle, the way
   a note is actually written — floating it clear of the head read as a stem
   belonging to some other note */
.bnd-slot.bnd-on::after{content:'';position:absolute;right:1px;bottom:50%;width:3px;height:128%;
  border-radius:2px;background:#3B2A1E}
.bnd-slot.bnd-beat{animation:bndBeat .42s cubic-bezier(0.34,1.56,0.64,1)}
@keyframes bndBeat{0%{transform:translate(-50%,50%) scale(1)}45%{transform:translate(-50%,50%) scale(1.45)}100%{transform:translate(-50%,50%) scale(1)}}

/* THE BAND PERCHES ON THE ROOF, not on the grass — on the grass they stood
   behind Mo, and the one thing a child is meant to be watching sing cannot be
   behind a bear. Drawn, not emoji: body, tail, wing, beak, eye. */
.bnd-band{position:absolute;left:14%;right:14%;bottom:70%;height:13%;
  display:flex;justify-content:space-between;align-items:flex-end;z-index:3}
.bnd-singer{position:relative;width:26%;aspect-ratio:1.15;transform-origin:50% 100%}
.bnd-singer .bnd-body{position:absolute;left:12%;right:6%;bottom:0;top:12%;
  border-radius:52% 58% 46% 46%;background:#FFCE3D;box-shadow:0 2px 0 rgba(0,0,0,.13)}
.bnd-singer[data-s="1"] .bnd-body{background:#6EC6F0}
.bnd-singer[data-s="2"] .bnd-body{background:#FF9EC0}
.bnd-tail{position:absolute;left:-2%;bottom:24%;width:26%;height:20%;border-radius:40% 6% 6% 40%;
  background:#F0A93B}
.bnd-singer[data-s="1"] .bnd-tail{background:#4FA9D6}
.bnd-singer[data-s="2"] .bnd-tail{background:#E8577A}
.bnd-wing{position:absolute;left:26%;top:44%;width:34%;height:30%;border-radius:60% 40% 60% 40%;
  background:rgba(0,0,0,.10)}
.bnd-beak{position:absolute;right:0;top:36%;width:20%;height:15%;background:#F0A93B;
  clip-path:polygon(0 0,100% 46%,0 100%);transition:height .12s ease,top .12s ease}
.bnd-eye{position:absolute;right:24%;top:28%;width:13%;aspect-ratio:1;border-radius:50%;background:#3B2A1E}
.bnd-singer.bnd-sing .bnd-beak{height:26%;top:31%}
.bnd-singer.bnd-sing .bnd-wing{animation:bndFlap .3s ease-in-out 2}
@keyframes bndFlap{0%,100%{transform:rotate(0)}50%{transform:rotate(-22deg)}}
.bnd-singer.bnd-sing{animation:bndHop .38s cubic-bezier(0.34,1.56,0.64,1)}
@keyframes bndHop{0%,100%{transform:translateY(0)}45%{transform:translateY(-16%)}}
.bnd-band.bnd-bow .bnd-singer{animation:bndHop .5s cubic-bezier(0.34,1.56,0.64,1) 3}
.bnd-stand.bnd-singing .bnd-roof{animation:bndGlow 1.1s ease-in-out infinite alternate}
@keyframes bndGlow{from{filter:brightness(1)}to{filter:brightness(1.22)}}

/* the notes blowing past */
.bnd-field{position:absolute;inset:0;pointer-events:none}
/* above the band, not behind it — .bnd-band is z-index 3, and a note drifting
   past a singer was landing underneath them */
.bnd-note{position:absolute;left:100%;width:19%;max-width:96px;aspect-ratio:1;z-index:5;
  border:0;padding:0;background:none;pointer-events:auto;cursor:pointer;
  animation:bndBlow var(--dur,6s) linear forwards;touch-action:manipulation}
@keyframes bndBlow{from{left:100%}to{left:-24%}}
.bnd-paper{position:absolute;inset:0;border-radius:10px;background:#FFFDF6;
  box-shadow:0 3px 0 rgba(0,0,0,.10),inset 0 0 0 2px #F0DCB4}
/* a good note: clean paper, a coloured head, a stem. Two cues with the letter. */
.bnd-head{position:absolute;left:16%;bottom:20%;width:34%;aspect-ratio:1;border-radius:50%;
  background:var(--nc,#FFCE3D)}
.bnd-stem{position:absolute;left:47%;bottom:26%;width:4px;height:44%;border-radius:2px;background:#3B2A1E}
/* a wrong one: an old torn grey scrap off the ground. It LOOKS wrong before
   the letter is read, so a child can refuse it for a reason. */
.bnd-paper.bnd-torn{background:#D8D2C4;box-shadow:inset 0 0 0 2px #B8B0A0;
  clip-path:polygon(0 8%,18% 0,42% 9%,68% 1%,100% 10%,94% 38%,100% 66%,88% 100%,58% 92%,30% 100%,4% 88%,10% 48%)}
.bnd-ltr{position:absolute;right:8%;bottom:8%;font-size:clamp(26px,7.4vw,42px);font-weight:900;
  color:#3B2A1E;line-height:1;text-shadow:0 1px 0 rgba(255,255,255,.7)}
.bnd-scrap .bnd-ltr{color:#6B6355}
.bnd-note.bnd-no{animation:bndBlow var(--dur,6s) linear forwards,bndShake .42s ease}
@keyframes bndShake{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-7px) rotate(-7deg)}75%{transform:translateX(7px) rotate(7deg)}}
.bnd-note.bnd-away{opacity:0;transition:opacity .5s ease}
