/* Gameplay: HUD, question card, answers, every mechanic, the result screen and effects.
   Loops use the individual translate/rotate/scale properties so press feedback on `transform` always works.
   Materials (--card, --gloss, --lip, --drop, --item-drop) live at the top of screens.css. */
@keyframes shake{0%,100%{translate:0}20%{translate:-8px}40%{translate:8px}60%{translate:-6px}80%{translate:6px}}
@keyframes pop{50%{scale:1.1}}
@keyframes float{0%,100%{translate:0 0;rotate:-3deg}50%{translate:0 -12px;rotate:3deg}}
@keyframes popout{to{transform:scale(1.25);opacity:0}}
@keyframes fall{to{translate:0 calc(min(40vh,340px) + 120px)}}
@keyframes starin{from{scale:.5;rotate:-40deg}60%{scale:1.25;rotate:8deg}to{scale:1;rotate:0deg}}

/* ===== HUD: solid paper pills, the 3D star counts the score ===== */
.hud{display:flex;align-items:center;gap:var(--s3);width:100%;max-width:980px;margin:0 auto var(--s3)}
.progress{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:var(--s2)}
.g-title{display:inline-flex;align-items:center;gap:var(--s2);max-width:100%;padding:var(--s1) var(--s4) var(--s1) var(--s1);border-radius:var(--r-pill);background:var(--paper);box-shadow:var(--sh-1);font-weight:700}
.g-title .bi{min-width:0}
.bar{position:relative;width:100%;max-width:320px;height:16px;border-radius:var(--r-pill);background:var(--paper-2);box-shadow:inset 0 2px 3px rgb(var(--shade)/.2),0 0 0 4px var(--paper),0 4px 10px -4px rgb(var(--shade)/.4);overflow:hidden}
.bar .fill:dir(rtl){transform-origin:right}
.bar .fill{height:100%;width:100%;transform-origin:left;transform:scaleX(0);border-radius:inherit;background:linear-gradient(180deg,rgba(255,255,255,.4),rgba(255,255,255,0)),var(--leaf);transition:transform var(--t-fill) var(--ease-out)}
.bar-txt{display:inline-flex;align-items:center;min-height:26px;padding:2px var(--s3);border-radius:var(--r-pill);background:var(--paper);box-shadow:var(--sh-1);font-size:var(--fs-sm);font-weight:700;font-variant-numeric:tabular-nums}
.score{display:flex;align-items:center;gap:var(--s2);min-height:var(--tap);padding:0 var(--s4) 0 var(--s3);border-radius:var(--r-pill);background:var(--paper);box-shadow:var(--sh-1);font-family:var(--font-display);font-size:var(--fs-lg);font-variant-numeric:tabular-nums}
.score .ui3d{width:1.6em;height:1.6em}
.score.bump{animation:bump 220ms var(--ease-out)}
@keyframes bump{50%{scale:1.18}}

/* ===== the question: the host in a round portrait, a speech bubble, and the things to look at on a solid paper card ===== */
.stage{width:100%;max-width:980px;margin:0 auto;display:flex;flex-direction:column;justify-content:flex-start;gap:var(--s4);flex:1;padding-top:clamp(var(--s3),4vh,var(--s6));padding-bottom:var(--s4)}
.prompt-row{display:flex;align-items:center;gap:var(--s4)}
.prompt-row .face{width:96px;height:96px;flex:none;border-radius:50%;overflow:hidden;background:radial-gradient(circle at 50% 30%,var(--paper),color-mix(in srgb,var(--sky) 30%,var(--paper)));box-shadow:0 0 0 4px var(--paper),var(--drop)}
.bubble{position:relative;flex:1;min-width:0;display:flex;align-items:center;justify-content:center;min-height:88px;padding:var(--s3) var(--s6);border-radius:var(--r-md);background:var(--paper);box-shadow:var(--sh-1);text-align:center;font-size:clamp(1.25rem,2.4vw,1.6rem);text-wrap:balance}
.bubble.pulse{animation:pulse 600ms ease-in-out 2} /* game.js repeatQ: no voice, so the prompt itself asks to be read */
.bubble::before{content:"";position:absolute;inset-inline-start:-8px;top:50%;width:18px;height:18px;margin-top:-9px;background:var(--paper);rotate:45deg;border-radius:3px}
.bubble .it{height:1.3em}
/* a printed page, not a window: the scene must not show through behind things being counted */
.qbody{position:relative;flex:1 1 auto;display:flex;flex-direction:column;align-items:center;justify-content:safe center;gap:var(--s3);min-height:176px;padding:var(--s5) var(--s4);border-radius:var(--r-lg);background:var(--card);box-shadow:inset 0 2px 0 rgba(255,255,255,var(--hi)),var(--sh-2)}
.qbody:empty,.opts:empty{display:none} /* a game played on the page leaves the answer grid empty: it must not keep a gap and padding under the page */
.qbody:has(+.opts:not(:empty):not([hidden])){max-height:52vh} /* with answers below, the page stops growing at half the screen; a game played on the page itself (tune, cards) keeps all the height it needs */
/* no picture to look at: the answers take the free height and sit low, near the thumbs */
.qbody:empty+.opts{flex:1;align-content:end}
.qbody:empty+.opts .opt{min-height:clamp(140px,24vh,220px)}

/* ===== shared question pieces: 3D items stand on the paper with a soft contact shadow ===== */
.items{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:var(--s1) var(--s3);max-width:860px;font-size:clamp(var(--fs-piece-lg),9vh,var(--fs-hero));line-height:1.15}
.items:has(>.it:nth-child(4)){font-size:var(--fs-piece-lg)}.items:has(>.it:nth-child(8)){font-size:var(--fs-piece)}
.items>.it{position:relative;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards}
.items .it .it{display:block;height:100%} /* itemsHTML wraps each item in its own .it span */
.items img.it,.bigpic .it,.count-item .it,.pond-item .it,.rowitems .it,.hab .it,.drop .it,.tile .it,.slot .it,.piece .it,.hole .it,.card .b .it{filter:var(--item-drop)}
.items .it.gone{opacity:.4;filter:grayscale(.6)}
.items .it.gone::after{content:"";position:absolute;left:-4%;right:-4%;top:48%;height:6px;border-radius:3px;background:var(--coral-d);rotate:-28deg}
.eq{display:flex;align-items:center;justify-content:center;gap:var(--s3);flex-wrap:wrap}
.eq .grp{padding:var(--s2) var(--s3);border-radius:var(--r-md);background:var(--paper-2);box-shadow:inset 0 2px 4px rgb(var(--shade)/.1)}
.eq .op{font-family:var(--font-display);font-size:var(--fs-2xl);color:var(--ink-2)}
.bigpic{font-size:clamp(4.5rem,min(12vw,10vh),7rem);line-height:1.1;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards}
.bigpic .it{height:1.3em}
.bigpic.sm{font-size:var(--fs-piece-lg)}
.word{display:inline-flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:var(--s2);font-family:var(--font-display);font-size:clamp(2rem,6vw,3.2rem);letter-spacing:.05em}
.word.big{font-size:clamp(2.4rem,7vw,3.6rem)}
.word[dir="rtl"],.word [lang="ar"]{letter-spacing:0}
.word .blank{display:inline-block;width:1.1em;height:1.25em;border:4px dashed var(--ink-2);border-radius:var(--r-sm);vertical-align:middle}
.word .blank.filled{display:inline-flex;align-items:center;justify-content:center;border-style:solid;border-color:var(--good);color:var(--good);animation:popIn var(--t-ui) var(--ease-out) backwards}
.bridge{display:flex;align-items:center;gap:var(--s4);font-size:var(--fs-piece)}
.seq{display:flex;gap:var(--s2);flex-wrap:wrap;justify-content:center;align-items:center}
.shp{width:min(18vw,96px);aspect-ratio:1;display:flex;align-items:center;justify-content:center}
.shp svg{width:100%;height:100%;filter:drop-shadow(0 6px 4px rgb(var(--shade)/.28))}
.shp.q{font-family:var(--font-display);font-size:var(--fs-2xl);color:var(--ink-2);border:4px dashed var(--ink-2);border-radius:var(--r-md)}
.speaker{display:grid;place-items:center;width:112px;height:112px;border:0;border-radius:50%;background:var(--gloss),var(--card);box-shadow:0 var(--lip-h) 0 var(--lip),var(--drop),0 0 0 4px color-mix(in srgb,var(--sky) 45%,transparent);animation:pulse 1.8s ease-in-out 3;transition:transform var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
.speaker:active{transform:translateY(calc(var(--lip-h) - var(--press)));box-shadow:0 var(--press) 0 var(--lip),var(--sh-press),0 0 0 4px color-mix(in srgb,var(--sky) 45%,transparent)}
.speaker .ui3d{width:64px;height:64px}

/* ===== answers: chunky toy buttons, a glossy face on a darker lip that sinks when pressed ===== */
.opts{display:grid;gap:var(--s4) var(--s3);width:100%;padding-bottom:var(--s2)}
.opts.c2{grid-template-columns:repeat(2,1fr)}.opts.c3{grid-template-columns:repeat(3,1fr)}.opts.c4{grid-template-columns:repeat(4,1fr)}
@media (max-width:560px){.opts.c4,.opts.c3{grid-template-columns:repeat(2,1fr)}.opts.c3>:last-child:nth-child(odd){grid-column:1/-1}} /* no orphan third answer */
.opt{--edge:var(--lip);position:relative;display:flex;align-items:center;justify-content:center;min-width:0;min-height:120px;padding:var(--s2) var(--s3);border:3px solid transparent;border-radius:var(--r-md);background:var(--gloss),var(--card);color:var(--ink);box-shadow:0 var(--lip-h) 0 var(--edge),var(--drop);font-family:var(--font-display);font-size:clamp(2.6rem,5vw,3.4rem);text-align:center;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards;transition:transform var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
:where(.opts:not(.c2:has(>:nth-child(3)))) .opt{min-height:clamp(120px,18vh,170px)} /* one row of answers grows with the screen; two rows keep 120 so the round still fits */
.opt.txt{font-size:var(--fs-piece-sm)}
.opt .it{height:1.45em;filter:var(--item-drop)}
.opt .shp{width:min(22vw,110px)}
@media (hover:hover) and (pointer:fine){.opt:not(:disabled):hover{transform:translateY(-2px)}}
.opt:active{transform:translateY(calc(var(--lip-h) - var(--press)));box-shadow:0 var(--press) 0 var(--edge),var(--sh-press)}
.opt.correct{--edge:var(--good);border-color:var(--good);background:var(--gloss),var(--good-bg);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,pop var(--t-pop) var(--ease-out)}
.opt.wrong{--edge:var(--bad);border-color:var(--bad);background:var(--gloss),var(--bad-bg);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,shake var(--t-shake) var(--ease-out)}
.opt:disabled{cursor:default}
.opt:disabled:not(.correct,.wrong){color:color-mix(in srgb,var(--ink) 40%,transparent)} /* the page stays solid paper over the painted scene; only its content recedes. The child's own wrong pick stays readable */
.opt:disabled:not(.correct,.wrong) :is(img,svg){opacity:.45}
.opt.hint::after{content:"";position:absolute;inset:-7px;border-radius:calc(var(--r-md) + 6px);border:5px solid var(--good);pointer-events:none;animation:ring 1s var(--ease-out) infinite}
/* right and wrong carry the 3D check and cross, so the answer is told by mark and shape, not colour alone */
:is(.opt,.piece,.hole,.tile):is(.correct,.wrong)::before{content:"";position:absolute;top:-12px;inset-inline-end:-10px;width:40px;height:40px;background:center/contain no-repeat;filter:var(--art-drop);pointer-events:none;animation:popIn var(--t-ui) var(--ease-out) backwards}
:is(.opt,.piece,.hole,.tile).correct::before{background-image:url("art/ui/check.webp")}
:is(.opt,.piece,.hole,.tile).wrong::before{background-image:url("art/ui/close.webp")}
.spark{position:absolute;z-index:16;pointer-events:none;font-size:var(--fs-piece-sm);animation:sparkFly .6s var(--ease-out) forwards;translate:-50% -50%}
@keyframes sparkFly{to{translate:calc(-50% + var(--dx)) calc(-50% + var(--dy));scale:.2;opacity:0}}
.flyer{position:absolute;z-index:16;pointer-events:none;font-family:var(--font-display);font-size:var(--fs-piece);margin:-.6em 0 0 -.4em}

/* ===== order and spell ===== */
.line{display:flex;gap:var(--s3);justify-content:center;flex-wrap:wrap;min-height:84px}
.line.small{min-height:60px}.line.small .slot{width:54px;height:54px;font-size:var(--fs-piece-sm)}
.slot{display:flex;align-items:center;justify-content:center;width:78px;height:78px;border:4px dashed var(--ink-2);border-radius:var(--r-md);background:color-mix(in srgb,var(--paper-2) 60%,transparent);font-family:var(--font-display);font-size:var(--fs-piece)}
.slot.filled{border-style:solid;border-color:var(--good);background:var(--good-bg);animation:pop var(--t-pop) var(--ease-out)}
.line.train .slot{position:relative;border-radius:var(--r-md) var(--r-md) var(--r-sm) var(--r-sm)}
.line.train .slot::after{content:"";position:absolute;bottom:-14px;inset-inline:10px;height:8px;border-radius:4px;background:var(--ink-2);opacity:.4}
.slot .shp{width:76%}.hole .shp,.piece .shp{width:clamp(60px,10vh,104px)} /* pieces grow with the screen height, like the answers */
.tiles{display:flex;gap:var(--s3);justify-content:center;flex-wrap:wrap;padding-bottom:var(--s1)}
.tile{position:relative;display:flex;align-items:center;justify-content:center;width:84px;height:84px;border:0;border-radius:var(--r-md);background:var(--gloss),var(--card);color:var(--ink);box-shadow:0 var(--lip-h) 0 var(--lip),var(--drop);font-family:var(--font-display);font-size:var(--fs-piece);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards;transition:transform var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
.tile:active{transform:translateY(calc(var(--lip-h) - var(--press)));box-shadow:0 var(--press) 0 var(--lip),var(--sh-press)}
.tile .it{height:1.4em}
.tile.used{visibility:hidden}
.tile.wrong{background:var(--bad-bg);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,shake var(--t-shake) var(--ease-out)}
.tile.word,.slot.word{width:auto;min-width:84px;padding-inline:var(--s4);font-size:var(--fs-piece-sm)}
.slot.word{min-height:78px}
.tile.block.on{background:var(--gloss),var(--sun);color:var(--on-c);transform:translateY(-8px);box-shadow:0 var(--lip-h) 0 var(--sun-d),var(--drop)}

/* ===== balloons, falling items ===== */
.sky{position:relative;width:100%;height:min(46vh,380px);min-height:260px;overflow:hidden;border-radius:var(--r-lg);background:linear-gradient(180deg,var(--paper-2),color-mix(in srgb,var(--paper-2) 30%,transparent))}
.sky.rain{height:min(34vh,300px);min-height:200px}
.balloon{position:absolute;width:86px;height:104px;border:0;border-radius:50% 50% 50% 50%/45% 45% 55% 55%;color:var(--on-c);font-family:var(--font-display);font-size:var(--fs-piece);background:radial-gradient(circle at 34% 26%,rgba(255,255,255,.6),rgba(255,255,255,0) 40%),var(--bc,var(--coral));box-shadow:inset -8px -10px 0 rgb(var(--shade)/.14),0 10px 14px -8px rgb(var(--shade)/.45);animation:float 3s var(--ph,0s) ease-in-out infinite}
.balloon::after{content:"";position:absolute;left:50%;bottom:-26px;width:3px;height:26px;background:rgb(var(--shade)/.3);translate:-50% 0}
.balloon .it{height:1.2em}
.balloon.popped{animation:float 3s var(--ph,0s) ease-in-out infinite,popout .25s 0s var(--ease-out) forwards}
.balloon.wrong{animation:float 3s var(--ph,0s) ease-in-out infinite,shake var(--t-shake) 0s var(--ease-out)}
.counter{font-family:var(--font-display);font-size:var(--fs-lg);padding:var(--s1) var(--s4);border-radius:var(--r-pill);background:var(--paper);box-shadow:var(--sh-1)}
.catch-top{display:flex;flex-direction:column;align-items:center;gap:var(--s2)}
.drop{position:absolute;top:-90px;display:flex;align-items:center;justify-content:center;width:78px;height:78px;border:0;border-radius:50%;background:var(--gloss),var(--card);color:var(--ink);box-shadow:0 var(--lip-h-sm) 0 var(--lip),var(--drop);font-family:var(--font-display);font-size:var(--fs-piece);animation:fall var(--fall,4s) linear forwards}
.drop .it{height:1.25em}
.drop .shp{width:56px}
.drop.caught{animation:fall var(--fall,4s) linear forwards paused,popout .25s var(--ease-out) forwards}
.drop.wrong{background:var(--bad-bg)}

/* ===== feed and fishing ===== */
.muncher{display:flex;align-items:center;gap:var(--s3)}
.muncher>.mouth{display:block;flex:none;width:clamp(112px,18vh,168px);height:clamp(112px,18vh,168px);border-radius:50%;overflow:hidden;background:radial-gradient(circle at 50% 30%,var(--paper),color-mix(in srgb,var(--sky) 30%,var(--paper)));box-shadow:0 0 0 4px var(--paper),var(--drop);transition:transform .15s var(--ease-out)} /* the round portrait every host sits in, so the bust crop reads as a frame */
.muncher.chomp>.mouth{animation:chomp .4s var(--ease-out)}
@keyframes chomp{35%{scale:1.2;rotate:-6deg}65%{scale:.96;rotate:4deg}}
.muncher.wrong{animation:shake var(--t-shake) var(--ease-out)}
.bubble-count{min-width:72px;padding:var(--s1) var(--s5);border-radius:var(--r-pill);background:var(--paper);box-shadow:var(--sh-1);font-family:var(--font-display);font-size:var(--fs-xl);text-align:center;font-variant-numeric:tabular-nums}
.pond{display:flex;flex-wrap:wrap;gap:var(--s2);justify-content:center;max-width:760px}
.pond-item{min-width:var(--tap);min-height:var(--tap);border:0;background:transparent;padding:var(--s1);font-size:clamp(var(--fs-piece),7vh,var(--fs-piece-lg));line-height:1;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,float 3s var(--ph,0s) ease-in-out infinite;transition:transform var(--t-fast) var(--ease-out)}
.pond-item .it{height:1.4em}
.pond-item:active{transform:scale(.92)}
.pond-item.used{visibility:hidden}
.btn.done{--c:var(--paper);--cd:rgb(var(--shade)/.5);--sheen:rgba(255,255,255,0);color:var(--ink)} /* not yet: a quiet paper button at full contrast */
.btn.done.ready{--c:var(--sun);--cd:var(--sun-d);--sheen:rgba(255,255,255,.42);color:var(--on-c);animation:pulse 1.4s ease-in-out 3}

/* ===== sorter ===== */
.pieces,.holes{display:flex;gap:var(--s4);flex-wrap:wrap;justify-content:center}
.piece,.hole{position:relative;display:flex;align-items:center;justify-content:center;min-width:clamp(90px,16vh,150px);min-height:clamp(90px,16vh,150px);padding:var(--s2);border:3px solid transparent;border-radius:var(--r-md);font-family:var(--font-display);font-size:var(--fs-piece);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards;transition:transform var(--t-fast) var(--ease-out),scale var(--t-fast) var(--ease-out)}
.piece{background:var(--gloss),var(--card);color:var(--ink);box-shadow:0 var(--lip-h) 0 var(--lip),var(--drop)}
.piece .it,.hole .it{height:1.3em}
.pieces.text .piece,.holes.text .hole{min-width:120px;font-size:var(--fs-piece-sm)}
.hole{border:4px dashed var(--ink-2);background:color-mix(in srgb,var(--paper-2) 60%,transparent);color:var(--ink)}
.piece.sel{scale:1.06} /* border, paper and check come from the shared selected rule in screens.css */
.piece.done{visibility:hidden}
.hole.done{border-style:solid;border-color:var(--good);background:var(--good-bg)}
.hole.wrong,.piece.wrong{background:var(--bad-bg);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,shake var(--t-shake) var(--ease-out)}

/* ===== tune pads ===== */
.simon{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s3);width:min(70vw,320px)}
.pad{position:relative;overflow:hidden;aspect-ratio:1;border:5px solid rgba(255,255,255,.7);border-radius:var(--r-lg);font-size:var(--fs-piece-lg);box-shadow:var(--bevel),var(--sh-1);transition:transform var(--t-fast) var(--ease-out)}
.pad::before{content:"";position:absolute;inset:0;background:color-mix(in srgb,var(--paper) 45%,transparent);transition:opacity var(--t-fast)} /* resting pads sit under a paper veil; a lit pad drops it and shows its full colour */
.pad .it{position:relative;z-index:1;height:1.3em;filter:var(--item-drop)}
.pad.lit{transform:scale(1.07);box-shadow:var(--bevel),0 0 0 8px rgba(255,255,255,.6)}
.pad.lit::before{opacity:0}
.pad.wrong{animation:shake var(--t-shake) var(--ease-out)}

/* ===== memory cards ===== */
.board{display:grid;gap:var(--s3);width:100%;max-width:760px;margin:0 auto}
.board.c3{grid-template-columns:repeat(3,1fr)}.board.c4{grid-template-columns:repeat(4,1fr)}
.board .card{aspect-ratio:auto;height:clamp(84px,15vh,160px)} /* rows follow the screen height, so 12 cards still fit above the fold */
.card{position:relative;aspect-ratio:1;max-width:100%;padding:0;border:0;background:none;perspective:800px;transition:transform var(--t-fast) var(--ease-out)}
.card:active{transform:scale(.96)}
.card .in{position:absolute;inset:0;transition:transform 300ms var(--ease-in-out);transform-style:preserve-3d}
.card.open .in,.card.done .in{transform:rotateY(180deg)}
.card .f,.card .b{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:var(--s2);border-radius:var(--r-md);box-shadow:var(--sh-1);font-family:var(--font-display);text-align:center;overflow:hidden;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.card .f{color:#fff;font-size:var(--fs-piece);background:var(--enamel),var(--lilac-d);box-shadow:var(--bevel),var(--ring-in),var(--sh-1)}
.card .f .gi{width:58%;height:58%;filter:var(--art-drop)}
.card .b{transform:rotateY(180deg);background:var(--card);color:var(--ink);font-size:clamp(1.1rem,3.4vw,1.9rem);line-height:1.1}
.card .b.emoji{font-size:clamp(1.8rem,6vw,3rem)}
.card .b .it{height:1.5em}
.card.done .b{background:var(--good-bg);box-shadow:0 0 0 4px var(--good)}

/* ===== tracing ===== */
.trace-wrap{padding:var(--s2);border-radius:var(--r-lg);background:var(--paper);box-shadow:var(--sh-2);line-height:0}
.trace-wrap.wrong{animation:shake var(--t-shake) var(--ease-out)}
.trace-cv{border-radius:var(--r-md);cursor:crosshair;touch-action:none}

/* ===== counting, building a sum, hunting ===== */
.count-field{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s4);justify-content:center;max-width:760px}
.count-item{position:relative;padding:var(--s2);border:0;background:none;font-size:var(--fs-piece-lg);line-height:1;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards;transition:transform var(--t-fast) var(--ease-out)}
.count-item .it{height:1.35em}
.count-item:active{transform:scale(.9)}
.count-item.counted .it{opacity:.55} /* the item fades, its number badge stays full strength */
.count-item .num{position:absolute;inset-inline-end:-6px;top:-8px;min-width:30px;height:30px;border-radius:var(--r-pill);background:var(--leaf);color:var(--on-c);box-shadow:0 0 0 3px var(--paper);font:700 var(--fs-md)/30px var(--font-ui);font-style:normal;text-align:center;animation:pop var(--t-pop) var(--ease-out)}
.sum-meter{width:min(100%,420px);display:flex;flex-direction:column;align-items:center;gap:var(--s2)}
.sum-goal{display:flex;gap:var(--s3);align-items:center;font-size:var(--fs-lg)}
.sum-goal b{font-family:var(--font-display);font-size:var(--fs-2xl)}
.sum-bar{width:100%;height:18px;border-radius:var(--r-pill);background:var(--paper-2);box-shadow:inset 0 2px 3px rgb(var(--shade)/.2);overflow:hidden}
.sum-bar i{display:block;height:100%;width:100%;transform-origin:left;transform:scaleX(0);border-radius:inherit;background:var(--leaf);transition:transform var(--t-fill) var(--ease-out)}
.sum-now{font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.sum-meter.wrong{animation:shake var(--t-shake) var(--ease-out)}
.hunt-field{position:relative;width:100%;height:min(40vh,320px);min-height:230px}
.hunt-item{position:absolute;width:68px;height:68px;padding:var(--s1);border:0;background:none;animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards}
.hunt-item .shp{width:100%}
.hunt-item.found{animation:popout .3s var(--ease-out) forwards}
.hunt-item.wrong{animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards,shake var(--t-shake) var(--ease-out)}
.rowitems{display:flex;gap:var(--s4);flex-wrap:wrap;justify-content:center;font-size:var(--fs-piece-lg);line-height:1}
.rowitems .it{height:1.3em}
.rowitems .gap{animation:pop var(--t-pop) var(--ease-out)}
.mixrow{display:flex;align-items:center;gap:var(--s4);font-family:var(--font-display);font-size:var(--fs-piece)}
.sw{display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:50%;box-shadow:var(--bevel),0 8px 12px -8px rgb(var(--shade)/.5);font-size:var(--fs-piece)}
.sw.q{background:none;border:4px dashed var(--ink-2);color:var(--ink-2);box-shadow:none}
.opt .sw{width:56px;height:56px}
.hab{display:flex;flex-direction:column;align-items:center;gap:var(--s1)}
.hab b{font-size:var(--fs-piece);line-height:1}.hab small{font-size:var(--fs-md);font-weight:700}
.opt .hab .it{height:1.3em}
.cmp-items{font-size:var(--fs-piece-sm);line-height:1.1}
.cmp-items .it{height:1.1em;margin:1px}
.clock{width:min(34vw,170px);height:auto;filter:drop-shadow(0 6px 5px rgb(var(--shade)/.22))}

/* ===== result: the explorer in a sunny spotlight, three big 3D stars with the middle one raised ===== */
.result{position:relative;isolation:isolate;display:flex;flex-direction:column;align-items:center;gap:var(--s3);width:100%;max-width:640px;margin:var(--s6) auto 0;padding:var(--s7) var(--s5) var(--s5);text-align:center}
.ribbon{position:absolute;top:-26px;left:50%;translate:-50% 0;z-index:1;isolation:isolate;min-width:230px;padding:var(--s2) var(--s6);border-radius:var(--r-sm);background:var(--ribbon);color:#fff;font-family:var(--font-display);font-size:var(--fs-lg);box-shadow:var(--sh-1)}
.ribbon .bi .en{color:inherit;opacity:.92}
.ribbon::before,.ribbon::after{content:"";position:absolute;top:12px;width:30px;height:100%;background:var(--ribbon-d);z-index:-1;clip-path:polygon(0 0,100% 0,100% 100%,0 100%,32% 50%)}
.ribbon::before{left:-22px}.ribbon::after{right:-22px;scale:-1 1}
.result .face{width:min(56vw,280px);height:min(36vh,300px);background:radial-gradient(closest-side,color-mix(in srgb,var(--sun) 50%,transparent),transparent) center 40%/100% 90% no-repeat;filter:drop-shadow(0 10px 8px rgb(var(--shade)/.3))}
.bigstars{display:flex;align-items:flex-end;gap:var(--s2);margin-top:calc(-1 * var(--s3))}
.bigstars .ui3d{width:4.6rem;height:4.6rem}
.bigstars .ui3d:nth-child(2){width:5.6rem;height:5.6rem;margin-bottom:var(--s3)}
.bigstars .ui3d.on{animation:starin .5s var(--ease-out) both}
.result .msg{font-size:var(--fs-lg)}
.result .num{font-family:var(--font-display);font-size:var(--fs-piece);font-variant-numeric:tabular-nums}
.coins-earned{display:inline-flex;align-items:center;gap:var(--s2);padding:var(--s1) var(--s4) var(--s1) var(--s2);border-radius:var(--r-pill);background:var(--paper-2);font-family:var(--font-display);font-size:var(--fs-lg);color:var(--ink);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards}
.coins-earned .ui3d{width:1.5em;height:1.5em}
.coins-earned:empty{display:none}
.sticker-new{display:flex;flex-direction:column;align-items:center;gap:var(--s1);animation:popIn var(--t-ui) var(--d,0s) var(--ease-out) backwards} /* --d is set by the result timeline in game.js */
.rbtns{display:flex;gap:var(--s3);flex-wrap:wrap;justify-content:center}
.rbtns .btn{padding-inline:var(--s5)}
/* a new sticker or trophy adds a row: the explorer steps back so the next-level button stays on screen */
.result:has(.sticker-new:not([hidden])){gap:var(--s2)}
.result:has(.sticker-new:not([hidden])) .face{height:min(19vh,170px)}
@media (min-width:481px){.result:has(.sticker-new:not([hidden])) .bigstars .ui3d{width:4rem;height:4rem}.result:has(.sticker-new:not([hidden])) .bigstars .ui3d:nth-child(2){width:4.8rem;height:4.8rem}}
/* a wide screen has room beside the explorer: the new sticker stands next to it, so the celebrating friend keeps its full size */
@media (min-width:700px) and (min-height:481px){
  .result:has(.sticker-new:not([hidden])){display:grid;grid-template-columns:1fr 1fr;justify-items:center;align-items:center}
  .result:has(.sticker-new:not([hidden]))>*{grid-column:1/-1}
  .result:has(.sticker-new:not([hidden])) .face{grid-area:1/1;height:min(30vh,240px)}
  .result:has(.sticker-new:not([hidden])) .sticker-new{grid-area:1/2}
}

/* an upright tablet, or a big landscape one: bigger page, bigger buttons, and the on-page pieces grow to fill it */
@media (orientation:portrait) and (min-width:600px){.qbody{min-height:240px}.opt{min-height:152px}}
@media (orientation:portrait) and (min-width:600px),(min-width:900px) and (min-height:700px){
  /* a row of up to four takes the free height, capped by the width so the row never wraps; five or six step down */
  .line,.tiles{--pc:min(15vh,19vw,148px)}.line:has(>:nth-child(5)),.tiles:has(>:nth-child(5)){--pc:min(13vh,15vw,128px)}.line:has(>:nth-child(6)),.tiles:has(>:nth-child(6)){--pc:112px}
  .tile{width:max(112px,var(--pc));height:max(112px,var(--pc));font-size:var(--fs-piece-lg)}.slot{width:max(104px,calc(var(--pc) - 8px));height:max(104px,calc(var(--pc) - 8px));font-size:var(--fs-piece-lg)}
  .qbody:has(>.tiles,>.pieces){justify-content:space-evenly} /* the slots and the pieces spread over the tall page instead of huddling in its middle */
  .simon{width:min(70vw,320px,36vh)} /* the four pads fit under the prompt on a landscape tablet too */
  .items,.items:has(>.it:nth-child(4)){font-size:var(--fs-hero)}.items:has(>.it:nth-child(8)){font-size:var(--fs-piece-lg)}
}
@media (max-height:700px){.stage{padding-top:var(--s2)}.bubble{min-height:64px}.qbody{min-height:110px}.items{font-size:var(--fs-piece)}.items:has(>.it:nth-child(8)){font-size:var(--fs-piece-sm)}.qbody{padding:var(--s3)}.stage{gap:var(--s3)}.bigpic{font-size:var(--fs-piece-lg)}.opt,.qbody:empty+.opts .opt{min-height:84px}.prompt-row .face{width:72px;height:72px}.result .face{height:min(26vh,230px)}}
/* phones, and any short screen, keep the phone-sized pieces */
@media (max-width:480px),(max-height:700px){.piece,.hole{min-width:90px;min-height:90px}.hole .shp,.piece .shp{width:60px}.muncher>.mouth{width:112px;height:112px}.pond-item{font-size:var(--fs-piece)}}
/* a phone on its side: the picture on one side, the answers beside it, so the round fits without scrolling */
@media (orientation:landscape) and (max-height:480px){
  .hud{margin-bottom:var(--s2)}
  .stage{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:auto minmax(0,1fr);align-items:center;gap:var(--s2) var(--s4);padding-block:0}
  .prompt-row{grid-column:1/-1}.prompt-row .face{width:56px;height:56px}.bubble{min-height:56px;padding-block:var(--s2)}
  .qbody,.qbody:has(+.opts:not(:empty):not([hidden])){align-self:stretch;max-height:none;min-height:0;padding:var(--s2)}
  /* a game played on the page itself (feed, tune, train, trace...) leaves the answer grid empty: the page takes the whole width */
  .qbody:empty+.opts,.qbody:has(+.opts[hidden]),.qbody:has(+.opts:empty){grid-column:1/-1}
  .qbody:has(+.opts:empty){max-height:calc(100dvh - 150px)}
  .opts{align-self:stretch;grid-auto-rows:1fr;gap:var(--s3);padding-bottom:var(--s2)}.opts.c4{grid-template-columns:repeat(2,1fr)}.qbody:empty+.opts.c4{grid-template-columns:repeat(4,1fr)}
  .opt,.qbody:empty+.opts .opt{min-height:72px}
  .items{font-size:var(--fs-piece-lg)}.items:has(>.it:nth-child(5)){font-size:var(--fs-piece)}
  /* even so, games played on the page (feed, tune, trace, catch...) need more height than a phone on its side has:
     like the duel, the round asks to be turned upright; the back button in the HUD stays usable */
  #s-game{overflow:hidden}
  #s-game .stage{visibility:hidden}
  #s-game .hud{position:relative;z-index:6}
  #s-game .dz-rotate{position:absolute;inset:0;z-index:5;display:grid;place-items:center;padding:var(--s4);background:color-mix(in srgb,var(--paper) 88%,transparent)}
  /* the result: stars and score on the left, the three buttons stacked on the right, all on one screen */
  .result,.result:has(.sticker-new:not([hidden])){display:grid;grid-template-columns:auto 1fr;align-items:center;justify-items:center;column-gap:var(--s5);row-gap:var(--s2);max-width:760px;margin-top:var(--s5);padding:var(--s5) var(--s5) var(--s4)}
  .result:has(.sticker-new:not([hidden])){grid-template-columns:auto auto 1fr} /* a new sticker gets its own middle column */
  .result .face{display:none}
  .result .sticker-new{grid-column:2;grid-row:1/span 6}
  .result .rbtns{grid-column:-2;grid-row:1/span 6;flex-direction:column;flex-wrap:nowrap;width:100%}
}

@media (max-width:480px){
  .tile{width:64px;height:64px;font-size:var(--fs-piece-sm)}.slot{width:62px;height:62px;font-size:var(--fs-piece-sm)}.opt{min-height:84px}.stage{padding-top:var(--s2)}.hud{gap:var(--s2)}
  .eq .items,.eq .items:has(>.it:nth-child(4)){font-size:var(--fs-piece)}.eq .items:has(>.it:nth-child(6)){font-size:var(--fs-piece-sm)} /* a sum's two groups stay one row each */
  .pond{gap:var(--s1)}.pond-item{padding:0} /* five fish to a row */.score{padding:0 var(--s3) 0 var(--s2)}
  .prompt-row{gap:var(--s3)}.prompt-row .face{width:72px;height:72px}
  .bubble{padding:var(--s3) var(--s4)}
  .qbody{padding:var(--s4) var(--s3)}
  .g-title{overflow:hidden;padding-inline-start:var(--s4)}.g-title .badge{display:none}
  .g-title .bi{max-width:100%;white-space:nowrap}.g-title .bi .ar,.g-title .bi .en{max-width:100%;overflow:hidden;text-overflow:ellipsis}
  :root[data-lang="en"] .g-title .bi{white-space:normal}:root[data-lang="en"] .g-title .bi>.en{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:.9em;line-height:1.05} /* English names run longer than Arabic: two short lines, not an ellipsis */
  .bigstars .ui3d{width:3.6rem;height:3.6rem}.bigstars .ui3d:nth-child(2){width:4.4rem;height:4.4rem}
  /* the main button takes the first row, the two smaller ones share the second */
  .result:has(.sticker-new:not([hidden])){margin-top:var(--s5);padding-top:var(--s6)}.result:has(.sticker-new:not([hidden])) .face{height:150px}
  .rbtns .main{order:-1;flex-basis:100%}.rbtns .btn:not(.main){min-height:var(--tap);padding-inline:var(--s4);font-size:var(--fs-md)}
}
/* a short phone: smaller answers and host so the whole round fits; the trace tools stay on one row.
   It cannot stack the explorer, the coins and a new sticker either: the sticker takes the explorer's place, beside the coins */
@media (max-width:480px) and (max-height:700px){
  .progress{position:relative;gap:var(--s1)}.bar{max-width:none}
  .bar-txt{position:absolute;width:1px;height:1px;min-height:0;padding:0;overflow:hidden;clip-path:inset(50%)} /* the bar shows the progress; the 1/8 count stays for screen readers */
  .stage{gap:var(--s2)}.qbody{gap:var(--s2)}.slot.word{min-height:62px}
  .result{margin-top:var(--s5);padding-top:var(--s6);gap:var(--s2)} /* a zero-star round (no sticker) also fits without scrolling */
  #s-game{padding-top:max(var(--s2),env(safe-area-inset-top))}.hud{margin-bottom:var(--s2)}
  .opt{min-height:72px}
  .muncher>.mouth{width:88px;height:88px}.count-item{font-size:var(--fs-piece)}
  .qbody .btn.done{min-height:var(--tap);padding-block:var(--s1)}
  .pond{gap:var(--s1)}.pond-item{min-width:56px;min-height:56px;font-size:var(--fs-piece-sm)} /* up to 20 fish or cookies, five to a row */
  .qbody:has(+.opts:not(:empty):not([hidden])){max-height:40vh}
  .prompt-row .face{width:56px;height:56px}.bubble{min-height:56px;padding-block:var(--s2)}
  .trace-wrap+.row-btns{flex-wrap:nowrap;gap:var(--s2)}.trace-wrap+.row-btns .btn{padding-inline:var(--s3)}
  .result:has(.sticker-new:not([hidden])){display:grid;grid-template-columns:1fr 1fr;justify-items:center;align-items:center}
  .result:has(.sticker-new:not([hidden]))>*{grid-column:1/-1}
  .result:has(.sticker-new:not([hidden]))>:is(.coins-earned,.sticker-new){grid-column:auto}
  .result:has(.sticker-new:not([hidden])) .coins-earned:empty+.sticker-new{grid-column:1/-1} /* no coins: the sticker centres */
  .result:has(.sticker-new:not([hidden])) .face{display:none}
}

/* reduced motion: catch items wait still at a random height instead of falling, and stars fade in */
@media (prefers-reduced-motion:reduce){
  .sky .drop:not(.caught){animation:none !important;top:var(--y,30%)}
  .bigstars .ui3d.on{animation:starFade 200ms linear both !important}
}
@keyframes starFade{from{opacity:0}}
