/* Mo & Pip — the second wave (assets/games-d.js).
   Prefixes: gd- shared, cz- Pip's cousins, shp- Mo's shopping, lb- the book.
   Every class here carries its scene's prefix. index.html is one stylesheet
   shared by sixty-odd games and a bare `.branch` or `.item` would land on all
   of them — that has broken two games in one afternoon before now. */

/* ------------------------------------------------------------ shared sky */
.gd-sky{position:absolute;inset:0;background:linear-gradient(180deg,#6FBFF0 0%,#A9DDF7 42%,#E7F5FC 72%)}
/* the top corners belong to the house and pause buttons — the sun goes
   inboard and below them, never behind them */
.gd-sun{position:absolute;right:15%;top:9%;width:11%;padding-bottom:11%;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,#FFE79A,#FFCE3D 62%);box-shadow:0 0 34px 10px rgba(255,206,61,.45);
  transition:box-shadow .8s,transform .8s var(--spring)}
.gd-cloud{position:absolute;width:22%;height:7%;background:#fff;border-radius:999px;opacity:.92;
  animation:gdDrift 46s linear infinite;filter:drop-shadow(0 3px 0 rgba(20,60,110,.08))}
.gd-cloud::before{content:"";position:absolute;left:16%;top:-60%;width:38%;padding-bottom:38%;background:#fff;border-radius:50%}
.gd-cloud::after{content:"";position:absolute;left:44%;top:-40%;width:34%;padding-bottom:34%;background:#fff;border-radius:50%}
.gd-cloud.c1{left:4%;top:10%}
.gd-cloud.c2{left:56%;top:19%;width:17%;animation-duration:62s}
@keyframes gdDrift{from{transform:translateX(0)}to{transform:translateX(34vw)}}
/* not a flat slab of green — a lit strip at the front and tufts along the
   skyline, so the ground reads as ground */
.gd-grass{position:absolute;left:0;right:0;bottom:0;height:calc(var(--cast-h) + 3vh);z-index:5;
  background:linear-gradient(180deg,#8AD37F,#6FBE66 46%,#5FAE58)}
.gd-grass::before{content:"";position:absolute;left:0;right:0;top:-9px;height:12px;
  background:repeating-radial-gradient(circle at 12px 12px,#8AD37F 0 9px,transparent 10px) 0 0/26px 12px}
.gd-grass::after{content:"";position:absolute;left:-4%;right:-4%;top:34%;height:16%;border-radius:50%;
  background:rgba(255,255,255,.13)}
.gd-fade{opacity:.32 !important;transition:opacity .4s}
.gd-no{animation:gdNo .5s}
@keyframes gdNo{0%,100%{transform:translateX(0)}25%{transform:translateX(-9px) rotate(-4deg)}75%{transform:translateX(9px) rotate(4deg)}}

/* ======================================================= FIND PIP =======
   One tree. A trunk that grows out of the grass, three branches off it, a
   leafy crown over the top — and the cousins sitting ON the branches, never
   more than four to a branch so the letter on the scarf stays readable. The
   bird table stands on the grass at the right, clear of Mo's corner. */
.cz-scene{position:absolute;inset:0;overflow:hidden}
.cz-hills{position:absolute;z-index:0;left:-10%;right:-10%;top:58%;height:24%;border-radius:50% 50% 0 0/100% 100% 0 0;
  background:linear-gradient(180deg,#9FD68C,#7CC276);opacity:.75}
/* the crown: overlapping leaf clusters, not one dome — a dome reads as a hill */
.cz-crown{position:absolute;left:-8%;right:-4%;top:0;height:20%;pointer-events:none;z-index:1}
.cz-crown i{position:absolute;bottom:0;border-radius:50%;
  background:radial-gradient(circle at 34% 30%,#8FD87F,#4FA85C 74%)}
.cz-crown i:nth-child(1){left:0;width:44%;height:78%}
.cz-crown i:nth-child(2){left:24%;width:40%;height:100%;background:radial-gradient(circle at 40% 28%,#9CE08C,#5CB566 74%)}
.cz-crown i:nth-child(3){left:52%;width:38%;height:86%}
.cz-crown i:nth-child(4){right:0;width:30%;height:66%;background:radial-gradient(circle at 40% 30%,#8FD87F,#57B063 74%)}
.cz-trunk{position:absolute;left:3%;top:13%;width:14%;bottom:0;z-index:3;
  background:linear-gradient(90deg,#7A4C22,#B98A50 44%,#8A5A2B);
  /* narrow at the top, flaring into roots at the foot — and the grass is
     drawn OVER it, so it goes into the ground rather than standing on it */
  clip-path:polygon(34% 0,64% 0,78% 78%,100% 100%,0 100%,20% 78%)}
.cz-trunk::after{content:"";position:absolute;left:42%;top:10%;width:7%;height:52%;border-radius:4px;
  background:rgba(60,36,12,.26)}
/* the branches grow OUT of the trunk, which sits in front of them — the
   first cut had them crossing it and the tree read as a ladder */
.cz-branch{position:absolute;left:7%;height:1.7vh;border-radius:0 999px 999px 0;z-index:2;
  background:linear-gradient(180deg,#B98A50,#7A4C22);box-shadow:0 3px 0 rgba(0,0,0,.12)}
.cz-branch.b1{top:34%;right:6%}
.cz-branch.b2{top:53%;right:9%}
.cz-branch.b3{top:72%;right:12%}
/* A SPRAY OF THREE LEAVES at the tip. Two earlier cuts got this wrong: one
   tall oval read as a green balloon on a stick, and three gradients inside a
   tall box came out as clipped rectangles, because a percentage radius
   resolves against the BOX, not against the circle you meant. So: a square
   box, and each blob given its own size and position. */
.cz-branch::after{content:"";position:absolute;right:-24px;top:50%;width:50px;height:50px;
  margin-top:-25px;
  background:
    radial-gradient(circle closest-side,#8FD87F 98%,transparent) -2px 0/28px 28px no-repeat,
    radial-gradient(circle closest-side,#7CCB6C 98%,transparent) 22px 10px/30px 30px no-repeat,
    radial-gradient(circle closest-side,#5CB566 98%,transparent) 4px 22px/26px 26px no-repeat}
/* THE BIRDS STAND ON THE BRANCH. Without translateY(-100%) the row hangs
   DOWN from the branch line, so the branch runs behind their heads and the
   lowest row disappears into the grass. */
.cz-row{position:absolute;left:14%;display:none;justify-content:space-around;align-items:flex-end;
  z-index:4;pointer-events:none;transform:translateY(-100%)}
.cz-row.on{display:flex}
.cz-row.r1{top:34%;right:6%}
.cz-row.r2{top:53%;right:9%}
.cz-row.r3{top:72%;right:12%}
.cz-bird{width:26%;max-width:112px;border:0;background:none;padding:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;pointer-events:auto;
  opacity:0;transform:translateY(-22px) scale(.72);
  transition:transform .45s var(--spring),opacity .3s;transition-delay:var(--d,0ms)}
.cz-row[data-n="2"] .cz-bird{width:28%}
.cz-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 0 rgba(20,60,30,.16));
  /* the feet sit on the branch, not above it */
  margin-bottom:-6%}
.cz-bird.in{opacity:1;transform:none}
/* the gap Pip's place is held open by while she is in the air. Not a
   hidden button — see the note in newRound(). */
.cz-slot{width:26%;max-width:112px;display:block;pointer-events:none}
.cz-row[data-n="2"] .cz-slot{width:28%}
.cz-bird.cz-yes{transform:translateY(-10px) scale(1.14) !important}
.cz-bird.cz-yes .cz-svg{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 16px #FFCE3D)}
.cz-bird.cz-wait{animation:czWait .5s}
@keyframes czWait{50%{transform:translateY(-5px) rotate(-4deg)}}
.cz-bird.cz-hint .cz-svg{animation:czTwinkle 1.1s ease-in-out infinite}
@keyframes czTwinkle{50%{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 15px #FFF3B0)}}
.cz-bird.cz-off{opacity:0 !important;transform:translateY(-130px) rotate(-14deg) !important;
  transition:transform .9s cubic-bezier(.3,-.3,.6,1),opacity .7s;transition-delay:var(--d,0ms)}
/* the one flying in, before she takes her place */
.cz-flyer{position:absolute;left:50%;top:40%;width:32%;max-width:180px;
  transform:translate(-50%,-50%) scale(.4);opacity:0;pointer-events:none;z-index:9;
  transition:transform .5s var(--spring),opacity .25s}
.cz-flyer .cz-svg{filter:drop-shadow(0 6px 0 rgba(20,60,30,.2))}
.cz-flyer.on{opacity:1}
.cz-flyer.big{transform:translate(-50%,-50%) scale(1);animation:czHover 1.2s ease-in-out infinite}
@keyframes czHover{50%{margin-top:-8px}}
.cz-flyer.fly{animation:none;
  transform:translate(calc(-50% + var(--fx,0px)),calc(-50% + var(--fy,0px))) scale(var(--fs,.4));
  transition:transform .95s cubic-bezier(.45,0,.5,1),opacity .2s .78s;opacity:0}
.cz-flyer.fly.quick{transition:transform .66s cubic-bezier(.45,0,.5,1),opacity .2s .5s}
/* the bird table on the grass, and the bowl the berries land in */
.cz-table{position:absolute;right:5%;bottom:2%;width:31%;max-width:190px;z-index:6}
.cz-tsvg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(0 5px 0 rgba(40,60,30,.18))}
.cz-bowl{position:absolute;left:12%;right:12%;top:29%;height:17%;
  border-radius:4px 4px 46% 46%/4px 4px 100% 100%;
  background:linear-gradient(180deg,#F0D9AE,#C9A06A);border:3px solid #8A5A2B;box-sizing:border-box;
  transition:transform .4s var(--spring)}
.cz-bowl.full{transform:scale(1.12)}
.cz-berries{position:absolute;inset:-30% 5% 8%}
.cz-b{position:absolute;left:var(--x,10%);bottom:var(--y,10%);width:17%;animation:czDrop .5s var(--spring)}
.cz-berry{width:100%;height:auto;display:block}
@keyframes czDrop{from{transform:translateY(-40px) scale(.4)}}
.cz-table.cz-crowd::after{content:"";position:absolute;left:-16%;right:-16%;top:-14%;height:34%;
  border-radius:999px;background:radial-gradient(ellipse at 50% 60%,rgba(255,243,176,.85),rgba(255,243,176,0) 70%)}
.cz-scene.cz-tea .gd-sun{transform:scale(1.16);box-shadow:0 0 60px 22px rgba(255,206,61,.6)}
.cz-scene.cz-tea .cz-crown i{filter:brightness(1.08)}

/* ======================================================= MO'S SHOPPING ==
   A market stall built the way one is: a scalloped striped awning on two
   posts, a plank back wall with crates of produce on a shelf, a counter to
   stand the shopping on, and the basket down on the grass at the right —
   away from Mo's corner and away from the counter, so nothing a child needs
   to touch is ever behind anything else. */
.shp-scene{position:absolute;inset:0;overflow:hidden}
.shp-back{position:absolute;left:2%;right:2%;top:24%;height:36%;
  background:repeating-linear-gradient(180deg,#EBD8B6 0 22px,#E2CBA2 22px 24px);
  box-shadow:inset 0 6px 0 rgba(0,0,0,.07),inset 0 -6px 0 rgba(0,0,0,.06)}
.shp-crates{position:absolute;left:5%;right:5%;top:27%;height:15%;display:flex;justify-content:space-between}
.shp-crates i{position:relative;width:22%;border-radius:5px;
  background:repeating-linear-gradient(180deg,#D9B37E 0 30%,#B98A50 30% 38%);
  box-shadow:inset 0 0 0 3px #9A7442,0 3px 0 rgba(0,0,0,.1)}
/* something IN the crates — an empty box on a shelf reads as a stall that has
   sold out, and a market with nothing on it is not a market. The produce sits
   INSIDE, with a slat of the crate drawn across the front of it. */
.shp-crates i::before{content:"";position:absolute;left:5%;right:5%;top:4%;height:52%;
  background:
    radial-gradient(circle at 22% 62%,#E0714E 0 26%,transparent 27%),
    radial-gradient(circle at 52% 40%,#FFCE3D 0 26%,transparent 27%),
    radial-gradient(circle at 80% 60%,#8AD37F 0 24%,transparent 25%),
    radial-gradient(circle at 36% 26%,#C9A0F0 0 20%,transparent 21%);
  background-repeat:no-repeat}
.shp-crates i::after{content:"";position:absolute;left:0;right:0;top:44%;height:16%;
  background:#B98A50;box-shadow:0 0 0 2px #9A7442}
.shp-awning{position:absolute;left:-1%;right:-1%;top:17%;height:8%;
  background:repeating-linear-gradient(90deg,#E0714E 0 5%,#FFF6E2 5% 10%);
  border-radius:8px 8px 0 0;filter:drop-shadow(0 4px 0 rgba(0,0,0,.12));z-index:3}
/* the scalloped edge along the bottom of the awning */
.shp-awning::after{content:"";position:absolute;left:0;right:0;top:100%;height:3.2%;
  background:repeating-linear-gradient(90deg,#E0714E 0 5%,#FFF6E2 5% 10%);
  -webkit-mask-image:repeating-radial-gradient(circle at 5% 0,#000 0 10px,transparent 10px);
  mask-image:repeating-radial-gradient(circle at 5% 0,#000 0 10px,transparent 10px);
  -webkit-mask-size:5% 100%;mask-size:5% 100%}
.shp-post{position:absolute;top:24%;width:2.4%;height:38%;z-index:2;
  background:linear-gradient(90deg,#7A4C22,#B98A50 50%,#8A5A2B);border-radius:3px}
.shp-post.l{left:1%}.shp-post.r{right:1%}
.shp-counter{position:absolute;left:-2%;right:-2%;top:58%;height:6%;z-index:5;
  background:linear-gradient(180deg,#E0B87E,#B98A50);border-radius:8px;
  box-shadow:0 5px 0 #8A5A2B,inset 0 4px 0 rgba(255,255,255,.32)}
.shp-front{position:absolute;left:-2%;right:-2%;top:64%;height:12%;z-index:4;
  background:
    repeating-linear-gradient(90deg,rgba(224,113,78,.9) 0 7%,rgba(255,246,226,.9) 7% 14%) 0 0/100% 42%,
    linear-gradient(180deg,#C99A5E,#A8783C);
  background-repeat:no-repeat,no-repeat;
  box-shadow:inset 0 -4px 0 rgba(0,0,0,.12)}
/* the things on the counter. height:auto, or an SVG in a fixed box is
   letterboxed and the picture ends up half the size it should be, floating
   in the middle of the shelf — which is exactly what the first cut did. */
.shp-items{position:absolute;left:3%;right:3%;top:60%;z-index:6;
  transform:translateY(-100%);display:flex;justify-content:space-around;align-items:flex-end}
.shp-item{width:28%;max-width:120px;border:0;background:none;padding:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  opacity:0;transform:translateY(26px) scale(.6);
  transition:transform .45s var(--spring),opacity .3s,filter .25s;transition-delay:var(--d,0ms)}
.shp-items[data-n="4"] .shp-item{width:23%}
.shp-items[data-n="2"] .shp-item{width:31%}
.shp-item .pic-svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 5px 0 rgba(90,60,20,.18))}
.shp-item.in{opacity:1;transform:none}
.shp-item.shp-lit{transform:translateY(-10px) scale(1.1)}
.shp-item.shp-lit .pic-svg{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 14px #FFCE3D)}
.shp-item.shp-name{animation:shpName .5s var(--spring)}
@keyframes shpName{50%{transform:translateY(-10px) scale(1.08)}}
.shp-item.shp-yes{transform:translateY(-16px) scale(1.16) !important}
.shp-item.shp-yes .pic-svg{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 18px #FFCE3D)}
.shp-item.shp-hint .pic-svg{animation:shpTwinkle 1.1s ease-in-out infinite}
@keyframes shpTwinkle{50%{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 15px #FFF3B0)}}
.shp-basket{position:absolute;right:5%;bottom:11%;width:30%;max-width:190px;z-index:7;
  transition:transform .5s var(--spring)}
.shp-bsvg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(0 5px 0 rgba(90,60,20,.2))}
.shp-basket.full{transform:scale(1.1) translateY(-6px)}
.shp-load{position:absolute;left:8%;right:8%;bottom:44%;height:56%;z-index:-1;pointer-events:none}
.shp-in{position:absolute;left:var(--x,10%);bottom:var(--y,10%);width:32%;
  transform:rotate(var(--r,0deg));animation:shpDrop .5s var(--spring)}
.shp-in .pic-svg{width:100%;height:auto;display:block}
@keyframes shpDrop{from{transform:translateY(-40px) rotate(0) scale(.5)}}
.shp-scene.shp-done .gd-sun{transform:scale(1.15);box-shadow:0 0 60px 22px rgba(255,206,61,.6)}
.shp-scene.shp-done .shp-awning{animation:shpFlap 1.1s ease-in-out 3}
@keyframes shpFlap{50%{transform:translateY(-6px)}}

/* ======================================================= THE LETTER BOOK
   A quiet room at reading time: warm wall, a window with the afternoon in it,
   a shelf of books, a lamp, a rug — and the book open on the rug. Everything
   is placed to keep off the four corners, which belong to the back button,
   the pause, the house and the version pill. */
.lb-scene{position:absolute;inset:0;overflow:hidden}
.lb-wall{position:absolute;inset:0;background:linear-gradient(180deg,#FFF0D2,#F6DDB6 58%,#E8C99A)}
.lb-window{position:absolute;left:5%;top:11%;width:25%;height:17%;border-radius:10px 10px 5px 5px;
  background:linear-gradient(180deg,#8ECBEE,#C9E8F6);border:5px solid #C9A06A;box-sizing:border-box;
  box-shadow:0 4px 0 rgba(0,0,0,.08)}
.lb-window i{position:absolute;background:#C9A06A}
.lb-window i:nth-child(1){left:0;right:0;top:48%;height:5px}
.lb-window i:nth-child(2){top:0;bottom:0;left:48%;width:5px}
.lb-window::after{content:"";position:absolute;right:10%;top:8%;width:26%;padding-bottom:26%;
  border-radius:50%;background:#FFF3B0;box-shadow:0 0 18px 6px rgba(255,243,176,.7)}
.lb-shelf{position:absolute;right:6%;top:22%;width:30%;height:2.2%;border-radius:4px;
  background:linear-gradient(180deg,#C9A06A,#9A7442);box-shadow:0 4px 0 rgba(0,0,0,.08)}
.lb-shelf b{position:absolute;bottom:100%;width:16%;border-radius:3px 3px 0 0}
.lb-shelf b:nth-child(1){left:10%;height:280%;background:#E0714E}
.lb-shelf b:nth-child(2){left:32%;height:360%;background:#4FA85C}
.lb-shelf b:nth-child(3){left:54%;height:230%;background:#6EC6F0}
/* A LAMP ON THE SHELF. It has been three things: a stalk with its foot in mid
   air (nothing to stand on), then a pendant on a cord — whose cord ran down
   through the title and the row of dots, because the header is painted over
   this wall. On the shelf it has a surface under it and stays clear of the
   header entirely. */
.lb-lamp{position:absolute;right:8%;top:12%;width:13%;height:10.4%}
.lb-lamp::before{content:"";position:absolute;left:36%;bottom:0;width:28%;height:44%;
  background:linear-gradient(90deg,#9A7442,#C9A06A 50%,#9A7442);border-radius:2px 2px 5px 5px}
.lb-lamp::after{content:"";position:absolute;left:0;right:0;top:0;height:60%;
  background:linear-gradient(180deg,#FFCE3D,#F0A93B);border-radius:30% 30% 8% 8%;
  box-shadow:0 8px 34px 10px rgba(255,206,61,.34)}
/* a small picture on the wall, so the wall is a wall */
.lb-frame{position:absolute;left:36%;top:16%;width:17%;height:12%;border-radius:4px;
  border:5px solid #C9A06A;box-sizing:border-box;background:linear-gradient(180deg,#BFE9FA 0 58%,#8AD37F 58%);
  box-shadow:0 4px 0 rgba(0,0,0,.08)}
.lb-frame::after{content:"";position:absolute;left:56%;top:14%;width:20%;padding-bottom:20%;
  border-radius:50%;background:#FFCE3D}
.lb-rug{position:absolute;left:-10%;right:-10%;bottom:0;height:calc(var(--cast-h) + 12vh);
  border-radius:50% 50% 0 0/26% 26% 0 0;
  background:repeating-radial-gradient(ellipse at 50% 130%,#EFA893 0 9%,#E79781 9% 18%);
  opacity:.7}
.lb-cushion{position:absolute;right:7%;bottom:calc(var(--cast-h) - 5vh);width:20%;height:6%;
  border-radius:26% 26% 30% 30%/40%;background:linear-gradient(180deg,#C9A0F0,#9268C4);
  box-shadow:0 4px 0 rgba(0,0,0,.1),inset 0 -6px 0 rgba(0,0,0,.08)}
.lb-cushion::after{content:"";position:absolute;left:50%;top:50%;width:16%;height:22%;
  transform:translate(-50%,-50%);border-radius:50%;background:rgba(90,50,140,.35)}
/* the book */
.lb-book{position:absolute;left:5%;right:5%;top:39%;height:35%;display:flex;z-index:6;
  filter:drop-shadow(0 10px 0 rgba(90,60,20,.18));transition:transform .5s var(--spring)}
.lb-page{position:relative;flex:1 1 50%;min-width:0;background:linear-gradient(180deg,#FFFDF4,#F6EBD4);
  border:4px solid #C9A06A;box-sizing:border-box;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:1%;padding:5% 4% 7%;overflow:hidden;cursor:pointer;
  font:inherit;color:inherit;-webkit-tap-highlight-color:transparent}
.lb-page.left{border-radius:16px 4px 4px 16px;border-right-width:2px}
.lb-page.right{border-radius:4px 16px 16px 4px;border-left-width:2px}
.lb-spine{position:absolute;left:50%;top:-2%;bottom:-2%;width:10px;transform:translateX(-50%);
  border-radius:5px;background:linear-gradient(90deg,#9A7442,#C9A06A 50%,#9A7442);z-index:3}
/* THE COVER. It was orange, and the picture on it is the letter drawn in the
   letter's own colour — which for A is orange. The whole cover was invisible.
   A deep cover with a cream panel under the picture, and cream type. */
.lb-book.lb-covered .lb-page{background:linear-gradient(180deg,#2C79A8,#1F5E8A);border-color:#164866}
.lb-book.lb-covered .lb-cover{background:#FFF8E8;border-radius:18px;padding:5%;
  box-shadow:inset 0 0 0 3px #C9A06A}
.lb-book.lb-covered .lb-cover em{color:#8A5A2B}
.lb-book.lb-covered .lb-big b{color:#FFF6E2}
.lb-book.lb-covered .lb-big i{color:#9BD2EE}
.lb-book.lb-covered .lb-tap svg circle{stroke:#FFF6E2;fill:#FFF6E2}
/* NOT a transform — see the note in arm(). The book stays still and the
   tap mark says it is ready. */
.lb-book.lb-ready .lb-tap svg{opacity:1}
.lb-tap svg{opacity:.35;transition:opacity .3s}
.lb-book.lb-hint .lb-tap svg{animation:lbPulse 1s ease-in-out infinite}
.lb-book.lb-shut{transform:scale(.86) rotate(-2deg);opacity:.55;transition:transform .6s var(--spring),opacity .5s}
@keyframes lbPulse{50%{transform:scale(1.22)}}
.lb-pic,.lb-cover{width:92%;flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center}
.lb-pic svg,.lb-cover svg{width:100%;height:100%;max-height:100%;overflow:visible}
.lb-pop{animation:lbPop .55s var(--spring)}
@keyframes lbPop{40%{transform:scale(1.18) rotate(-4deg)}}
.lb-cover{flex-direction:column;gap:2%}
.lb-cover em{font-size:clamp(12px,3.2vw,18px);font-style:normal;font-weight:800;color:#5A3A12;opacity:.9}
.lb-big{display:flex;align-items:baseline;gap:6%;line-height:1}
.lb-big b{font-size:clamp(46px,15vw,110px);font-weight:900;color:#1F5E8A}
.lb-big i{font-size:clamp(30px,10vw,74px);font-style:normal;font-weight:900;color:#5FB1DD}
.lb-page em{font-size:clamp(14px,4.4vw,26px);font-style:normal;font-weight:800;color:#8A5A2B}
.lb-tap{position:absolute;right:6%;bottom:5%;width:18%;max-width:48px}
.lb-tap svg{width:100%;height:auto;display:block}
.lb-all{display:flex;width:100%;height:82%;align-items:center;justify-content:space-around;gap:3%}
.lb-mini{flex:1 1 0;min-width:0;display:flex;align-items:center;justify-content:center}
.lb-mini svg{width:100%;height:auto;max-height:100%}
.lb-mini.beat{animation:lbBeat .4s var(--spring)}
@keyframes lbBeat{40%{transform:translateY(-14%) scale(1.16)}}
/* the page turning over */
.lb-turn{position:absolute;left:50%;top:0;bottom:0;width:50%;pointer-events:none;z-index:8;
  transform-origin:left center;background:linear-gradient(90deg,#FFFDF4,#EADFC4);
  border:4px solid #C9A06A;border-radius:4px 16px 16px 4px;box-sizing:border-box;opacity:0}
.lb-turn.go{animation:lbTurn .56s ease-in}
@keyframes lbTurn{
  0%{opacity:1;transform:rotateY(0)}
  99%{opacity:1;transform:rotateY(-172deg)}
  100%{opacity:0;transform:rotateY(-180deg)}}
.lb-end{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;z-index:9;
  opacity:0;pointer-events:none;transition:opacity .5s}
.lb-end.on{opacity:1}
.lb-end b{font-size:clamp(30px,10vw,64px);font-weight:900;color:#fff;
  background:linear-gradient(180deg,#F0A93B,#D98B2E);padding:2% 6%;border-radius:22px;
  border:5px solid #FFF6E2;box-shadow:0 8px 0 rgba(90,60,20,.25);animation:lbEnd .6s var(--spring)}
@keyframes lbEnd{from{transform:scale(.5) rotate(-6deg)}}

/* ======================================================= BUILD YOUR NAME
   Mo's room, the name on the bunting, the letters waiting underneath. The
   flags come off the END of the name as the rungs get harder, so the part
   the child has already read is always still there holding them up. */
.nl-scene{position:absolute;inset:0;overflow:hidden}
.nl-wall{position:absolute;inset:0;background:linear-gradient(180deg,#FFF0D2,#F6DDB6 60%,#E8C99A)}
/* a toy box on the rug rather than a window on the wall — there is no clear
   band of wall left between the bunting and the tray, and a window squeezed
   into the rug read as buried */
.nl-box{position:absolute;right:6%;bottom:2%;width:22%;height:11%;border-radius:6px 6px 4px 4px;
  background:linear-gradient(180deg,#D9B37E,#B98A50);border:3px solid #8A5A2B;box-sizing:border-box;
  box-shadow:0 4px 0 rgba(90,60,20,.2)}
.nl-box::before{content:"";position:absolute;left:0;right:0;top:-14%;height:24%;border-radius:5px;
  background:linear-gradient(180deg,#E8C48F,#C9A06A);border:3px solid #8A5A2B;box-sizing:border-box}
.nl-box::after{content:"";position:absolute;left:14%;bottom:16%;width:72%;height:26%;
  background:
    radial-gradient(circle closest-side,#E0714E 98%,transparent) 0 0/30% 100% no-repeat,
    radial-gradient(circle closest-side,#6EC6F0 98%,transparent) 36% 0/30% 100% no-repeat,
    radial-gradient(circle closest-side,#8AD37F 98%,transparent) 72% 0/30% 100% no-repeat;
  opacity:.9}
.nl-rug{position:absolute;left:-10%;right:-10%;bottom:0;height:calc(var(--cast-h) + 8vh);
  border-radius:50% 50% 0 0/26% 26% 0 0;
  background:repeating-radial-gradient(ellipse at 50% 130%,#EFA893 0 9%,#E79781 9% 18%);opacity:.7}
/* the string the flags hang from — a shallow sag, drawn with a border */
.nl-line{position:absolute;left:2%;right:2%;top:14%;height:6%;
  border-bottom:4px solid #C9A06A;border-radius:0 0 50% 50%/0 0 100% 100%}
/* the flags size themselves to the length of the name — three of them at the
   width eight of them need would be three stamps lost on a washing line */
.nl-flags{position:absolute;left:3%;right:3%;top:19%;height:16%;z-index:3;
  display:flex;justify-content:center;align-items:flex-start;gap:1.5%}
.nl-flags[data-n="2"] .nl-flag,.nl-flags[data-n="3"] .nl-flag{width:24%}
.nl-flags[data-n="4"] .nl-flag{width:21%}
.nl-flags[data-n="5"] .nl-flag{width:18%}
.nl-flags[data-n="6"] .nl-flag{width:15.5%}
.nl-flags[data-n="7"] .nl-flag{width:13.5%}
.nl-flag{width:12%;max-width:84px;opacity:0;transform:translateY(-18px) rotate(-8deg);
  transition:transform .45s var(--spring),opacity .3s,filter .3s;transition-delay:var(--d,0ms)}
.nl-flag.in{opacity:1;transform:none}
.nl-fsvg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 3px 0 rgba(90,60,20,.18))}
/* an empty flag is plainly empty — pale, dashed, waiting */
.nl-flag.nl-empty{--f:#F3E6CE;--fd:#C9A06A}
.nl-flag.nl-empty .nl-fsvg{opacity:.85}
.nl-flag.nl-asking{transform:translateY(4px) scale(1.12)}
.nl-flag.nl-asking .nl-fsvg{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 14px #FFCE3D)}
.nl-flag.nl-beg .nl-fsvg{animation:nlBeg 1s ease-in-out infinite}
@keyframes nlBeg{50%{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 18px #FFF3B0)}}
.nl-flag.nl-filled{animation:nlPop .55s var(--spring)}
@keyframes nlPop{40%{transform:translateY(6px) scale(1.2)}}
/* the letters waiting underneath. WRAPPING, not shrinking: the hardest rung
   of a six-letter name puts eight cards out, and eight across a phone is a
   46px tap target. Two rows of four keeps every card a thumb wide. */
.nl-tray{position:absolute;left:4%;right:4%;top:42%;height:26%;z-index:4;
  display:flex;flex-wrap:wrap;justify-content:center;align-content:center;gap:3% 3%}
.nl-card{width:21%;max-width:88px;border:0;background:none;padding:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  opacity:0;transform:translateY(22px) scale(.7);
  transition:transform .45s var(--spring),opacity .3s;transition-delay:var(--d,0ms)}
.nl-card.in{opacity:1;transform:none}
.nl-csvg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 0 rgba(90,60,20,.2))}
.nl-card.nl-gone{opacity:0;pointer-events:none;transition:opacity .2s}
/* the whole name, lit, at the end of every rung */
.nl-scene.nl-lit .nl-flag .nl-fsvg{filter:drop-shadow(0 0 0 #fff) drop-shadow(0 0 12px #FFCE3D)}
.nl-scene.nl-party .nl-flag{animation:nlWave 1.1s ease-in-out infinite;animation-delay:var(--d,0ms)}
@keyframes nlWave{50%{transform:translateY(-10px) rotate(4deg)}}
/* the letter lifting off the bunting on the very first go, so a child sees
   where the gap came from rather than having to work out what it is for */
.nl-flag.nl-lift{transform:translateY(-26px) scale(1.16) rotate(-8deg);
  transition:transform .5s var(--spring),opacity .4s .18s;opacity:0}
