/* ---------- Puzzle overlay ---------- */
body.pz-open #toasts, body.pz-open #pad, body.pz-open #slashBtn, body.pz-open .hint-keys, body.pz-open .combo, body.pz-open #banner { opacity: 0; pointer-events: none; }
#toasts, #pad, #slashBtn { transition: opacity .2s; }
/* The puzzle is a window over the game, not a separate screen: the world stays visible around it.
   The top-left HUD (level bar, gems, Hat Trick dots, your gold pet's gold, squad chest, power-ups) stays in
   view over it, a little smaller, so a child sees rewards land and grow while they play; the
   puzzle moves over to make room. The rest of the HUD fades out. */
body.pz-open #hud { z-index: 41; pointer-events: none; }
/* (everything in it, cards included: the faded portrait bar sat over the puzzle's "Got it!" button
   and took its taps) */
body.pz-open #hud * { pointer-events: none !important; }
body.pz-open #hud > :is(.hud-tc, .hud-tr, .hud-feed, .hud-edges, .bossbar, .ghost-back, .ghost-veil, .hint-keys, .av-bar, .greet-pop, .greet-line, .steps-lb) { opacity: 0; }
#hud > :is(.hud-tc, .hud-tr, .hud-feed, .hud-edges, .bossbar, .ghost-back, .hint-keys, .av-bar, .greet-line) { transition: opacity .25s; }
#hud .hud-tl { transform-origin: 0 0; transition: transform .25s; }
body.pz-open #hud .hud-tl { transform: scale(.74); }
body.pz-open #hud .sq-r b { display: none; } /* (during a puzzle each squad shows its animal and bar, not its name) */
body.pz-open #puzzle { padding-left: max(clamp(16px, 6vw, 110px), 186px); }
@media (max-width: 960px) { body.pz-open #puzzle { padding-left: max(clamp(16px, 6vw, 110px), 150px); } }
@media (max-height: 480px) {
  body.pz-open #hud .hud-tl { transform: scale(.62); }
  body.pz-open #puzzle { padding-left: max(clamp(18px, 7vw, 64px), 124px); }
}
/* upright screens: the HUD sits above the puzzle instead of beside it */
@media (max-aspect-ratio: 1/1) {
  body.pz-open #hud .hud-tl { transform: scale(.66); }
  body.pz-open #puzzle { padding-left: clamp(16px, 6vw, 110px); padding-top: max(clamp(14px, 6vh, 60px), 170px); }
}
#puzzle { position: absolute; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; padding: clamp(14px, 6vh, 60px) clamp(16px, 6vw, 110px); }
#puzzle[hidden] { display: none; }
.pz-dim { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 45%, color-mix(in srgb, var(--th-well) 20%, transparent), color-mix(in srgb, var(--th-well) 50%, transparent)); opacity: 0; transition: opacity .25s; }
#puzzle.show .pz-dim { opacity: 1; }
.pz-panel {
  position: relative; display: flex; flex-direction: column; width: min(940px, 100%); max-height: 100%;
  padding: 14px 18px 14px; color: var(--th-text);
  /* the frame is themed; the work area inside (.pz-body) stays light paper so the question reads clearly */
  background: var(--th-tex), linear-gradient(var(--th-panel-hi), var(--th-panel-lo));
  box-shadow: inset 0 0 0 4px var(--th-frame), inset 0 0 0 7px var(--th-frame-dk), 0 0 0 4px var(--ink), 0 0 0 8px var(--th-rim), 0 0 0 11px var(--ink), 0 30px 70px rgba(0, 0, 0, .8), 0 0 90px 10px var(--th-glow-soft);
  transform: scale(.6); opacity: 0; transition: transform .32s cubic-bezier(.2, 1.6, .4, 1), opacity .18s;
}
#puzzle.show .pz-panel { transform: scale(1); opacity: 1; }
#puzzle.closing .pz-panel { transform: scale(1.08); opacity: 0; transition: transform .25s, opacity .25s; }
/* corner ornaments and decorations: see .panel::before and .panel::after in style.css (puzzles get the
   top and bottom strips only, so nothing reaches into the question) */
.pz-panel::after { background: var(--th-d-drape-l) left top / 160px 64px no-repeat border-box, var(--th-d-drape-r) right top / 160px 64px no-repeat border-box, var(--th-d-top) left top / var(--th-d-top-w) 32px round no-repeat content-box, var(--th-d-bottom-l) left bottom / 160px 48px no-repeat border-box, var(--th-d-bottom-r) right bottom / 160px 48px no-repeat border-box; }

.pz-head { display: flex; align-items: center; gap: 12px; min-height: 40px; padding: 0 18px; }
.pz-chip { display: flex; align-items: center; gap: 6px; padding: 5px 12px 5px 8px; font-weight: 700; font-size: 15px; color: #1a120b;
  background: var(--sc); border-radius: 999px; box-shadow: 0 0 0 3px var(--ink), inset 0 -3px 0 rgba(0, 0, 0, .2); white-space: nowrap; }
.pz-chip.lesson { animation: glowPulse 1.6s ease-in-out infinite; }
.pz-chip .scroll { display: inline-grid; place-items: center; width: 1.6em; height: 1.6em; margin: -3px 0; border-radius: 50%; font-size: 1.05em; line-height: 1; background: radial-gradient(circle, #6a3c08, #2a1600); box-shadow: 0 0 0 2px var(--ink), 0 0 8px rgba(255, 215, 80, .8); }
.pz-chip .scroll .star-ico { width: 1.15em; height: 1.15em; vertical-align: 0; }
.pz-stamp .pz-won { display: inline-flex; gap: 2px; margin-left: 14px; color: #ffe680; font-size: .9em; filter: drop-shadow(0 0 8px rgba(255, 215, 80, .9)); }
.pz-vs { flex: 1; display: flex; justify-content: center; align-items: center; gap: 12px; font-weight: 700; font-size: clamp(13px, 1.6vw, 18px); text-shadow: 2px 2px 0 #000; min-width: 0; }
.pz-vs span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pz-vs i { font-style: normal; font-family: var(--pixel); font-size: 11px; color: #fff; background: #b5281f; padding: 6px 7px; box-shadow: 0 0 0 3px #000; transform: rotate(-6deg); }
.pz-vs .foe { color: #ff9384; }
.pz-vs .lab { color: #a6e6ff; }
.icon-btn { width: 44px; height: 44px; border: none; border-radius: 10px; font-size: 22px; cursor: pointer; background: linear-gradient(var(--th-btn-hi), var(--th-btn-lo)); box-shadow: inset 0 -4px 0 var(--th-btn-sh), inset 0 2px 0 var(--th-btn-lt), 0 0 0 3px var(--ink); }
.icon-btn:active { transform: translateY(2px); box-shadow: inset 0 -2px 0 var(--th-btn-sh), 0 0 0 3px var(--ink); }

.pz-title { margin: 8px 0 8px; text-align: center; font-weight: 700; font-size: clamp(20px, 3.2vw, 34px); line-height: 1.15; color: var(--th-text); text-shadow: 3px 3px 0 var(--ink); }
.pz-body {
  position: relative; flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(8px, 1.6vh, 16px);
  padding: clamp(10px, 2vh, 20px) clamp(10px, 2vw, 22px); color: var(--ink2);
  background: var(--th-paper-tex), var(--th-paper);
  border-radius: 6px; box-shadow: inset 0 0 0 3px var(--th-pz-line), inset 0 6px 0 rgba(255, 255, 255, .35), inset 0 -8px 18px var(--th-pz-shade), 0 0 0 3px var(--th-frame-dk);
}
.pz-prompt { font-weight: 700; font-size: clamp(30px, 5.4vw, 60px); line-height: 1.05; color: var(--ink2); text-align: center; text-shadow: 0 3px 0 rgba(255, 255, 255, .6); }
.pz-prompt b { color: #b5281f; }
.pz-prompt .qm, .qm { color: #e0702a; display: inline-block; animation: bob 1s ease-in-out infinite; }
.big-letter { font-size: 1.3em; letter-spacing: .05em; color: #2a6fc4; }
.big-pic { font-size: clamp(56px, 9vw, 96px); line-height: 1; filter: drop-shadow(0 4px 0 rgba(0, 0, 0, .15)); }
.pattern { font-size: clamp(30px, 5vw, 50px); letter-spacing: .08em; }

/* visuals */
.pz-visual { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 18px; }
.pz-visual .ig { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; padding: 8px; background: rgba(255, 255, 255, .55); border-radius: 12px; box-shadow: 0 0 0 3px var(--th-pz-soft); }
.pz-visual .ig.ghost { display: flex; }
.pz-visual .ic { position: relative; font-size: clamp(24px, 3.6vw, 38px); line-height: 1.1; text-align: center; transition: transform .2s; }
.pz-visual .ic.crossed { opacity: .35; filter: grayscale(.7); }
.pz-visual .ic.crossed::after { content: '✖'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #c0392b; font-size: .9em; opacity: 1; }
.pz-visual .ic.counted { transform: scale(1.15); }
.pz-visual .ic.counted::before { content: attr(data-n); position: absolute; top: -8px; right: -6px; z-index: 2; min-width: 20px; height: 20px; padding: 0 3px; border-radius: 10px; font-size: 13px; font-weight: 700; line-height: 20px; color: #fff; background: #2a6fc4; box-shadow: 0 0 0 2px #fff; }
.pz-visual .op { font-size: clamp(30px, 5vw, 52px); font-weight: 700; color: #b5281f; }
.pz-visual.pulse .ig { animation: pulseBox .9s ease-in-out 2; }
.qbox { display: flex; align-items: center; justify-content: center; width: 70px; height: 70px; border: 4px dashed var(--th-pz-line); border-radius: 12px; font-size: 40px; font-weight: 700; color: #e0702a; }
.pz-visual.rods { gap: 8px; align-items: flex-end; }

/* option buttons */
.pz-options { display: grid; gap: clamp(8px, 1.4vw, 16px); width: 100%; max-width: 760px; }
.pz-options.n2 { grid-template-columns: repeat(2, 1fr); max-width: 520px; }
.pz-options.n3 { grid-template-columns: repeat(3, 1fr); }
.pz-options.n4 { grid-template-columns: repeat(4, 1fr); }
.pz-options.l-num.n4 { max-width: 640px; }
.opt {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: clamp(76px, 13vh, 116px); padding: 8px 6px; border: none; border-radius: 14px; cursor: pointer;
  font-family: var(--font); font-weight: 700; font-size: clamp(32px, 5vw, 54px); color: #fff;
  background: linear-gradient(var(--th-opt-hi), var(--th-opt-lo)); text-shadow: 0 3px 0 rgba(0, 0, 0, .3);
  box-shadow: inset 0 -7px 0 var(--th-opt-sh), inset 0 4px 0 var(--th-opt-lt), 0 0 0 4px var(--ink), 0 6px 0 4px rgba(0, 0, 0, .25);
  transition: transform .12s, filter .2s, opacity .3s;
}
.opt .k { position: absolute; top: 6px; left: 8px; font-size: 12px; opacity: .55; font-weight: 600; }
.opt:hover:not(.wrong):not(.fade) { transform: translateY(-3px); filter: brightness(1.08); }
.opt:active:not(.wrong) { transform: translateY(3px); box-shadow: inset 0 -3px 0 var(--th-opt-sh), 0 0 0 4px var(--ink); }
.opt:focus-visible { outline: 4px solid #ffd25a; outline-offset: 3px; }
.opt.pic { background: linear-gradient(#fffcf6, var(--th-card-lo)); color: var(--ink2); text-shadow: none; box-shadow: inset 0 -7px 0 var(--th-card-sh), inset 0 4px 0 #fff, 0 0 0 4px var(--ink), 0 6px 0 4px rgba(0, 0, 0, .2); }
.opt.pic .face { font-size: clamp(44px, 7.5vw, 76px); line-height: 1.05; }
.opt .lbl { font-size: clamp(14px, 1.7vw, 19px); font-weight: 600; color: #6b4f24; }
.l-word .opt { font-size: clamp(30px, 4.6vw, 48px); letter-spacing: .03em; }
.l-art .opt { min-height: clamp(120px, 22vh, 190px); }
.opt.right { background: linear-gradient(#5ec466, #3f9e48) !important; color: #fff; transform: translateY(-4px) scale(1.04); box-shadow: inset 0 -7px 0 #24642b, inset 0 4px 0 #8fe596, 0 0 0 4px #0b2a0c, 0 0 32px rgba(110, 255, 120, .8) !important; }
.opt.right .lbl { color: #fff; }
.opt.right::after { content: '✔'; position: absolute; top: -14px; right: -10px; width: 36px; height: 36px; border-radius: 50%; font-size: 22px; line-height: 36px; text-align: center; color: #fff; background: #2e8a37; box-shadow: 0 0 0 3px #fff, 0 0 0 6px #0b2a0c; animation: popIn .3s cubic-bezier(.2, 1.8, .4, 1); }
/* a wrong answer: greyed, with a red ring and a big red ✗ (see "Wrong answers" below) */
.opt.wrong { animation: wiggle .4s; cursor: default; color: #8a7068; text-shadow: none; background: linear-gradient(#f4e6e2, #ddc6c0) !important; box-shadow: inset 0 -7px 0 #b99c95, 0 0 0 4px #c8372b, 0 6px 0 4px rgba(0, 0, 0, .2) !important; }
.opt.wrong > .face, .opt.wrong > .lbl, .opt.wrong > .k { opacity: .4; filter: grayscale(.85); }
.opt.wrong::after { width: 1.3em; height: 1.3em; }
.opt.fade { opacity: .3; transform: scale(.95); }
.opt.reveal { animation: reveal 0.6s ease-in-out 2; }
.replay { margin-top: -4px; }

.shape { display: inline-block; width: 1.1em; height: 1.1em; background: var(--c); filter: drop-shadow(.06em .08em 0 rgba(0, 0, 0, .3)); }
.shape.tri { clip-path: polygon(50% 4%, 96% 94%, 4% 94%); }
.shape.cir { border-radius: 50%; }
.shape.sqr { transform: scale(.88); }
.shape.star { clip-path: polygon(50% 0, 62% 36%, 100% 36%, 69% 58%, 80% 96%, 50% 72%, 20% 96%, 31% 58%, 0 36%, 38% 36%); }
.shape.heart { clip-path: polygon(50% 92%, 6% 46%, 4% 22%, 18% 6%, 36% 6%, 50% 20%, 64% 6%, 82% 6%, 96% 22%, 94% 46%); }
.swatch { display: inline-block; width: 1em; height: 1em; vertical-align: middle; border-radius: 30% 40% 35% 45%; background: var(--c); box-shadow: inset -4px -5px 0 rgba(0, 0, 0, .18), inset 3px 3px 0 rgba(255, 255, 255, .35), 0 0 0 3px var(--ink); }
.swatch.big { width: 64px; height: 64px; }
.opt .swatch { width: 1.2em; height: 1.2em; }
.painting { display: grid; grid-template-columns: repeat(5, 1fr); width: clamp(84px, 13vw, 130px); aspect-ratio: 1; padding: 6px; background: #6b4527; box-shadow: inset 0 0 0 3px #4a2f1c, 0 0 0 3px var(--ink); }
.painting i { display: block; }

/* footer */
.pz-foot { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 0 6px; }
.pz-timer { position: relative; flex: 1; height: 16px; border-radius: 8px; background: var(--th-well); box-shadow: 0 0 0 3px var(--ink), inset 0 2px 0 rgba(0, 0, 0, .5); overflow: hidden; }
.pz-timer i { position: absolute; inset: 0; transform-origin: left; background: linear-gradient(#ffe07a, #e0962a); transition: background .4s; }
.pz-timer span { position: absolute; inset: 0; font-size: 11px; font-weight: 700; line-height: 16px; text-align: center; color: #fff; opacity: 0; transition: opacity .4s; text-shadow: 1px 1px 0 #000; }
.pz-timer.over i { background: linear-gradient(#8fd8ff, #4a9ad0); transform: scaleX(1) !important; }
.pz-timer.over span { opacity: 1; }
.pz-timer.off { visibility: hidden; }

.pz-feedback { position: absolute; left: 50%; top: 92px; z-index: 5; transform: translate(-50%, -10px) scale(.8); padding: 10px 20px; border-radius: 999px; font-weight: 700; font-size: clamp(16px, 2.2vw, 22px); color: #fff; white-space: nowrap; max-width: 92%; overflow: hidden; text-overflow: ellipsis;
  background: #b06a1f; box-shadow: 0 0 0 3px var(--ink), 0 8px 20px rgba(0, 0, 0, .4); opacity: 0; pointer-events: none; transition: opacity .2s, transform .25s cubic-bezier(.2, 1.6, .4, 1); }
.pz-feedback.show { opacity: 1; transform: translate(-50%, 0) scale(1); }
.pz-feedback.solve { background: #2a6fc4; }
.pz-hintbox.below { bottom: auto; top: calc(100% + 4px); }
.pz-hintbox.top { bottom: auto; top: 46px; }
.pz-visual .ic.tappable { cursor: pointer; }
.pz-visual .ic.tappable:active { transform: scale(0.9); }
.pz-hintbox { position: absolute; left: 50%; bottom: 52px; z-index: 4; transform: translateX(-50%); width: min(640px, 90%); padding: 12px 16px; border-radius: 12px; font-size: clamp(15px, 1.9vw, 19px); font-weight: 600; color: #3a2a1a;
  background: #fff6c8; box-shadow: 0 0 0 3px #e0b450, 0 0 0 6px var(--ink), 0 10px 24px rgba(0, 0, 0, .35); text-align: center; pointer-events: none; }
.pz-hintbox.pop { animation: popIn .35s cubic-bezier(.2, 1.6, .4, 1); }
.pz-hintbox b { color: #b06a1f; }
.pz-panel.locked .pz-body { filter: saturate(.6) brightness(.92); }
.pz-lockout { position: absolute; right: 26px; top: 64px; z-index: 6; width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 24px; background: #fff6c8; box-shadow: 0 0 0 3px var(--ink); animation: spinSlow 2s linear; }

.pz-stamp { position: absolute; inset: 0; z-index: 10; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; pointer-events: none; background: radial-gradient(ellipse 60% 55% at center, rgba(20, 14, 6, .82), rgba(20, 14, 6, .35) 80%); animation: fadeIn .2s; }
.pz-stamp .stars { display: flex; gap: 6px; font-size: clamp(44px, 7vw, 74px); }
.pz-stamp .stars i { font-style: normal; color: #4a3a28; text-shadow: 0 4px 0 #000; transform: scale(0); animation: starIn .4s cubic-bezier(.2, 1.8, .4, 1) forwards; animation-delay: var(--d); }
.pz-stamp .stars i.on { color: #ffd23a; text-shadow: 0 0 20px rgba(255, 200, 40, .9), 0 4px 0 #8a4a12; }
.pz-stamp .word { font-family: var(--pixel); font-size: clamp(24px, 4.4vw, 52px); color: #86ff74; text-shadow: 0 0 22px rgba(100, 255, 90, .9), 4px 4px 0 #0b3a07, 7px 7px 0 #000; transform: rotate(-6deg); animation: stampIn .4s cubic-bezier(.2, 1.6, .4, 1); }
.pz-stamp.tier-perfect .word { color: #ffe066; text-shadow: 0 0 26px rgba(255, 210, 60, 1), 4px 4px 0 #6a3a00, 7px 7px 0 #000; }
.pz-stamp.tier-learning .word { color: #c9c3b8; text-shadow: 4px 4px 0 #2a241c, 7px 7px 0 #000; font-size: clamp(16px, 2.8vw, 32px); transform: rotate(-3deg); animation: stampSad .5s cubic-bezier(.3, 1.3, .5, 1); }
/* two misses: a muted stamp that sinks a little, and a struck-through +0 (no gems this time) */
.pz-stamp.tier-learning { background: radial-gradient(ellipse 60% 55% at center, rgba(16, 14, 12, .86), rgba(16, 14, 12, .45) 80%); }
.pz-stamp.tier-learning .stars i { color: #3a332a; }
.pz-stamp .gems.none { color: #9a948a; text-decoration: line-through 4px #e0685a; animation: rise .6s ease-out .2s both, sadShake .5s ease-in-out .8s; }
.pz-stamp .gems.none .gem-ico { filter: grayscale(1) brightness(.7); }
@keyframes stampSad { 0% { transform: translateY(-20px) rotate(-3deg); opacity: 0; } 60% { transform: translateY(6px) rotate(-3deg); opacity: 1; } 100% { transform: translateY(0) rotate(-3deg); } }
@keyframes sadShake { 25% { transform: translateX(-6px); } 50% { transform: translateX(5px); } 75% { transform: translateX(-3px); } }
.pz-stamp .gems { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: clamp(24px, 3.6vw, 40px); color: #a6f3ff; text-shadow: 3px 3px 0 #000; animation: rise .6s ease-out .2s both; }
/* first-try answers in a row (puzzles/engine.js finish) */
.pz-stamp .row-of { padding: 4px 16px; border-radius: 999px; font-weight: 700; font-size: clamp(18px, 2.6vw, 28px); color: #fff3c8; background: rgba(120, 40, 0, .7); box-shadow: 0 0 0 3px #ff9a3a, 0 0 20px 4px rgba(255, 140, 40, .7); animation: rise .6s ease-out .35s both; }
/* ---------- A solved puzzle blows apart into its reward (puzzles/blast.js, engine.js close) ----------
   The real panel hides at once; copies of it, each clipped to a shard, fly out of where it cracked,
   with a flash, a ring of light, white cracks for a blink and chips of its frame, and the stamp's
   gems line pops out whole (the gems fly out of it: game/run.js finishEncounter). The HUD stays over
   the pieces while they fly, so the rewards are seen landing. Two misses (.soft): grey pieces crumble
   and drop in a puff of dust. (No color-mix here: older Safari and Chrome must see it too.) */
#puzzle.blasted { pointer-events: none; }
#puzzle.blasted > .pz-panel { visibility: hidden; opacity: 0; transition: none; }
#puzzle.blasted > .pz-dim { opacity: 0; transition: opacity .12s; }
body.pz-blasting #hud { z-index: 41; }
.pz-blast { position: absolute; inset: 0; z-index: 20; pointer-events: none; overflow: hidden; }
.pz-blast.gone { opacity: 0; transition: opacity .15s; } /* (a new puzzle opened before the pieces were gone) */
.pz-shard { position: absolute; overflow: hidden; will-change: transform, opacity; }
/* (a copy would start its own animations again: they stay frozen where they ended) */
.pz-shard *, .pz-shard *::before, .pz-shard *::after { animation-delay: -30s !important; animation-play-state: paused !important; transition: none !important; }
.pz-blast.soft .pz-shard { filter: grayscale(.85) brightness(.8); }
.pz-cracks { position: absolute; overflow: visible; fill: none; stroke: #fff; stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; }
.pz-cracks .glow { stroke: rgba(255, 236, 170, .45); stroke-width: 12; }
.pz-blast.soft .pz-cracks { stroke: #d8d2c6; stroke-width: 2.5; }
.pz-blast.soft .pz-cracks .glow { stroke: rgba(40, 34, 28, .35); stroke-width: 7; }
.pz-flash { position: absolute; border-radius: 50%; background: radial-gradient(circle, #fff 0 18%, #fff6c8 32%, rgba(255, 214, 100, .55) 50%, rgba(255, 214, 100, 0) 70%); }
.pz-ring { position: absolute; border-radius: 50%; box-shadow: inset 0 0 0 5px #fff, inset 0 0 18px 6px var(--sc, #ffd25a), 0 0 22px 6px var(--sc, #ffd25a); }
.pz-puff { position: absolute; border-radius: 50%; background: radial-gradient(circle, rgba(190, 182, 168, .8), rgba(120, 112, 100, .45) 45%, rgba(120, 112, 100, 0) 70%); }
.pz-bit { position: absolute; border-radius: 2px; box-shadow: 0 0 0 2px var(--ink); }
.pz-bit.c0 { background: #fff; }
.pz-bit.c1 { background: #ffe58a; }
.pz-bit.c2 { background: var(--sc, #ffd25a); }
.pz-bit.c3 { background: var(--th-frame, #c8a060); }
.pz-bit.star { background: none; box-shadow: none; line-height: 1; color: #fff8d0; text-shadow: 0 0 8px #ffd25a, 0 0 2px #fff; }
.pz-blast.soft .pz-bit { background: #8c877e; }
.pz-blast.soft .pz-bit.c1 { background: #b4aea4; }
.pz-blast .pz-pop { inset: auto; display: flex; align-items: center; justify-content: center; background: none; animation: none; }
.pz-pop .gems { animation: none; white-space: nowrap; filter: drop-shadow(0 0 14px rgba(140, 230, 255, .9)); }
.pz-gotit { position: absolute; left: 50%; bottom: 18px; z-index: 8; transform: translateX(-50%); width: min(660px, 92%); display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 16px; border-radius: 14px; background: #fff6c8; color: #3a2a1a; box-shadow: 0 0 0 3px #4a9ad0, 0 0 0 6px var(--ink), 0 14px 30px rgba(0, 0, 0, .45); animation: popIn .35s cubic-bezier(.2, 1.6, .4, 1); }
.pz-explain { font-size: clamp(17px, 2.2vw, 22px); font-weight: 600; text-align: center; }

/* ---------- Block Builder ---------- */
.bb { display: flex; gap: clamp(10px, 3vw, 32px); align-items: stretch; justify-content: center; width: 100%; }
.bb-supply { display: flex; flex-direction: column; gap: 14px; justify-content: center; }
.bb-pile { position: relative; display: flex; align-items: center; justify-content: center; gap: 10px; min-width: 120px; min-height: 96px; padding: 10px 14px; border: none; border-radius: 14px; cursor: pointer;
  background: linear-gradient(#fffcf6, var(--th-card-lo)); box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px var(--ink), 0 6px 0 4px rgba(0, 0, 0, .2); font-family: var(--font); }
.bb-pile b { font-size: 26px; color: #6b4f24; }
.bb-pile:hover { transform: translateY(-2px); }
.bb-pile:active { transform: translateY(3px); }
.bb-pile:disabled { opacity: .4; }
.bb-mat { display: flex; gap: 14px; min-width: min(420px, 60%); min-height: clamp(170px, 30vh, 250px); padding: 12px 16px; border-radius: 14px; background: color-mix(in srgb, var(--th-pz-line) 62%, var(--th-paper)); box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--th-pz-line) 70%, #000 30%), inset 0 6px 14px rgba(0, 0, 0, .15); }
.bb-mat.done { box-shadow: inset 0 0 0 3px #3f9e48, 0 0 26px rgba(90, 220, 100, .7); }
.bb-mat.shake { animation: wiggle .4s; }
.bb-col { display: flex; flex-direction: column; flex: 1; min-width: 80px; }
.bb-label { font-weight: 700; font-size: 15px; color: #7a5a2a; text-align: center; margin-bottom: 6px; }
.bb-tens { flex: 1; display: flex; flex-wrap: wrap; align-content: flex-end; align-items: flex-end; gap: 6px; }
.bb-ones { flex: 1; display: flex; flex-wrap: wrap-reverse; align-content: flex-start; gap: 4px; width: 60px; max-width: 60px; margin: 0 auto; }
.bb-ones .cube { flex: none; }
.rod, .cube { display: block; border: none; padding: 0; cursor: pointer; }
.rod { width: 24px; height: 176px; background: repeating-linear-gradient(#5aa0ff 0 15px, #2f6fd0 15px 17.6px); box-shadow: inset -4px 0 0 rgba(0, 0, 0, .2), inset 3px 0 0 rgba(255, 255, 255, .35), 0 0 0 3px var(--ink); border-radius: 3px; }
.cube { width: 24px; height: 24px; background: #ffb43a; box-shadow: inset -4px -4px 0 rgba(0, 0, 0, .2), inset 3px 3px 0 rgba(255, 255, 255, .45), 0 0 0 3px var(--ink); border-radius: 3px; }
.bb-pile .rod.big { height: 120px; background: repeating-linear-gradient(#5aa0ff 0 10px, #2f6fd0 10px 12px); }
.bb-pile .cube.big { width: 34px; height: 34px; }
.bb-pile .rod, .bb-pile .cube { pointer-events: none; }
.rod.pop, .cube.pop { animation: popIn .25s cubic-bezier(.2, 1.8, .4, 1); }
.cube.merge { animation: mergeOut .35s forwards; }
.bb-count { font-size: clamp(18px, 2.4vw, 24px); font-weight: 600; color: #3a2a1a; padding: 6px 14px; border-radius: 10px; background: #fff6c8; box-shadow: 0 0 0 3px #e0b450; }
.bb-count .tot { color: #b5281f; font-size: 1.2em; }
.bb-count.pop { animation: popIn .3s cubic-bezier(.2, 1.6, .4, 1); }
.bb-actions, .wb-actions, .mx-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.flyer { position: fixed; z-index: 100; pointer-events: none; transform: translate(-50%, -50%); }
.flyer.wb-fly { width: 64px; height: 64px; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 38px; color: #3a2a1a; background: #fffaf0; border-radius: 10px; box-shadow: 0 0 0 3px var(--ink); }
.flyer.so-fly { display: flex; flex-direction: column; align-items: center; font-size: 40px; }
.flyer.so-fly .lbl { display: none; }

/* ---------- Sort It ---------- */
.so-tray { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; min-height: 92px; width: 100%; }
.so-card { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; width: clamp(78px, 11vw, 100px); height: clamp(84px, 12vw, 108px); border-radius: 14px; cursor: grab; touch-action: none; user-select: none;
  background: linear-gradient(#fffcf6, var(--th-card-lo)); box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px var(--ink), 0 6px 0 4px rgba(0, 0, 0, .2); transition: transform .15s; z-index: 1; }
.so-card .pic { font-size: clamp(36px, 5.4vw, 52px); line-height: 1.05; }
.so-card .lbl { font-size: 13px; font-weight: 600; color: #6b4f24; text-align: center; line-height: 1.1; padding: 0 4px; }
.so-card.sel { transform: translateY(-6px) scale(1.06); box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px #ffd25a, 0 0 0 8px var(--ink), 0 0 22px rgba(255, 210, 90, .8); }
.so-card.drag { z-index: 50; cursor: grabbing; transition: none; box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px #ffd25a, 0 0 0 8px var(--ink), 0 16px 30px rgba(0, 0, 0, .4); }
.so-card.nope { animation: wiggle .45s; }
.so-card.placed { width: 58px; height: 58px; cursor: default; box-shadow: inset 0 -3px 0 var(--th-card-sh), 0 0 0 3px var(--ink); }
.so-card.placed .pic { font-size: 32px; }
.so-card.placed .swatch.big { width: 36px; height: 36px; }
.so-card.placed .lbl { display: none; }
.so-card.hinted, .so-bin.hinted { animation: pulseGlow .8s ease-in-out infinite; }
.so-bins { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; width: 100%; }
.so-bins.g3 { grid-template-columns: repeat(3, 1fr); }
.so-bin { display: flex; flex-direction: column; min-height: clamp(120px, 22vh, 190px); padding: 8px; border: none; border-radius: 16px; font-family: var(--font); cursor: pointer;
  background: rgba(255, 255, 255, .45); box-shadow: inset 0 0 0 4px var(--th-pz-line), inset 0 0 0 7px rgba(255, 255, 255, .5); transition: transform .15s, box-shadow .15s; }
.so-head { display: flex; align-items: center; justify-content: center; gap: 8px; font-weight: 700; font-size: clamp(18px, 2.5vw, 26px); color: #3a2a1a; }
.so-head .ico { font-size: 1.4em; }
.so-items { flex: 1; display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start; justify-content: center; padding-top: 8px; }
.so-slot { display: inline-block; width: 58px; height: 58px; }
.so-bins.armed .so-bin { box-shadow: inset 0 0 0 4px #e0b450, inset 0 0 0 7px rgba(255, 255, 255, .5); }
.so-bin.over { transform: scale(1.03); box-shadow: inset 0 0 0 5px #ffd25a, 0 0 22px rgba(255, 210, 90, .7); }
.so-bin.yes { animation: binYes .5s; }
.so-bin.no { animation: wiggle .4s; }
.so-bins.done .so-bin { box-shadow: inset 0 0 0 4px #3f9e48, 0 0 20px rgba(90, 220, 100, .5); }
.so-tip { font-size: 14px; font-weight: 600; color: #8a6a3a; }

/* ---------- Word Builder ---------- */
.wb-top { display: flex; justify-content: center; }
.wb-pic { font-size: clamp(70px, 12vw, 120px); line-height: 1; filter: drop-shadow(0 6px 0 rgba(0, 0, 0, .15)); animation: bob 2.2s ease-in-out infinite; }
.wb-pic.sound { border: none; background: #fffcf6; border-radius: 20px; padding: 10px 24px; cursor: pointer; box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px var(--ink); font-size: 70px; }
.wb-slots { display: flex; gap: clamp(6px, 1vw, 12px); justify-content: center; }
.wb-slot { width: clamp(52px, 8vw, 76px); height: clamp(60px, 9vw, 86px); border: none; border-radius: 12px; font-family: var(--font); font-weight: 700; font-size: clamp(34px, 5.6vw, 54px); color: #3a2a1a; cursor: pointer;
  background: rgba(255, 255, 255, .5); box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .08), inset 0 0 0 4px var(--th-pz-line); border-bottom: 6px solid color-mix(in srgb, var(--th-pz-line) 55%, #000 45%); text-transform: lowercase; position: relative; }
.wb-slot.filled { background: #fffcf6; box-shadow: inset 0 -5px 0 var(--th-card-sh), 0 0 0 4px var(--ink); animation: popIn .2s; }
.wb-slot.given { color: #8a6a3a; background: rgba(255, 255, 255, .3); cursor: default; }
.wb-slot.good { background: #c9f5c4; box-shadow: inset 0 -5px 0 #8fd88a, 0 0 0 4px #1f6a28; color: #1f5a24; }
.wb-slot.bad { background: #ffe0c8; animation: wiggle .4s; box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .08), 0 0 0 4px #c8372b; }
.wb-slot.bad::before { width: .9em; height: .9em; }
.wb-slot.ghosted::after { content: attr(data-ghost); position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: rgba(42, 111, 196, .35); }
.wb-slot.ghosted.filled::after { content: none; }
.wb-tiles { display: flex; flex-wrap: wrap; gap: clamp(8px, 1.2vw, 14px); justify-content: center; max-width: 640px; }
.wb-tile { width: clamp(56px, 8.4vw, 78px); height: clamp(56px, 8.4vw, 78px); border: none; border-radius: 12px; font-family: var(--font); font-weight: 700; font-size: clamp(32px, 5.2vw, 50px); color: #fff; cursor: pointer; text-transform: lowercase;
  background: linear-gradient(#ff9a4a, #e0702a); text-shadow: 0 3px 0 rgba(0, 0, 0, .25); box-shadow: inset 0 -6px 0 #a84a14, inset 0 4px 0 #ffc08a, 0 0 0 4px var(--ink), 0 5px 0 4px rgba(0, 0, 0, .2); transition: transform .12s, opacity .2s; }
.wb-tile:hover { transform: translateY(-3px); }
.wb-tile:active { transform: translateY(3px); }
.wb-tile.used { opacity: .18; pointer-events: none; transform: scale(.9); }
.wb-tile.hinted { animation: pulseGlow .8s ease-in-out infinite; }

/* ---------- Paint Mixer ---------- */
.mx-top { display: flex; align-items: center; justify-content: center; gap: clamp(14px, 3vw, 40px); flex-wrap: wrap; }
.mx-target { display: flex; align-items: center; gap: 12px; padding: 8px 18px 8px 10px; border-radius: 999px; background: #fffcf6; box-shadow: 0 0 0 4px var(--ink), inset 0 -5px 0 var(--th-card-sh); }
.mx-target .blob { width: 54px; height: 54px; border-radius: 42% 58% 47% 53%; background: var(--c); box-shadow: inset -6px -6px 0 rgba(0, 0, 0, .18), inset 4px 4px 0 rgba(255, 255, 255, .35), 0 0 0 3px var(--ink); animation: wobble 3s ease-in-out infinite; }
.mx-target .nm { font-weight: 700; font-size: clamp(22px, 3.2vw, 32px); text-transform: capitalize; color: #3a2a1a; }
.mx-recipe { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 26px; color: #6b4f24; }
.mx-recipe .drop { width: 36px; height: 36px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); background: var(--c, transparent); box-shadow: inset 0 0 0 3px var(--th-pz-line); transition: background .3s; }
.mx-recipe .drop.on, .mx-recipe .drop.goal { box-shadow: inset -3px -3px 0 rgba(0, 0, 0, .2), 0 0 0 3px var(--ink); }
.mx-stage { display: flex; align-items: flex-end; justify-content: center; gap: clamp(14px, 4vw, 50px); width: 100%; }
.mx-shelf { display: grid; grid-template-columns: repeat(3, auto); gap: 10px 14px; padding: 12px 14px 8px; border-radius: 10px; background: #8a5a32; box-shadow: inset 0 -8px 0 #6b4527, 0 0 0 4px var(--ink); }
.mx-pot { display: flex; flex-direction: column; align-items: center; gap: 2px; border: none; background: none; cursor: grab; touch-action: none; padding: 2px; font-family: var(--font); position: relative; z-index: 1; }
.mx-pot.drag { z-index: 50; cursor: grabbing; }
.mx-pot.pouring { z-index: 60; }
.mx-pot .jar { position: relative; display: block; width: 58px; height: 64px; border-radius: 8px 8px 14px 14px; background: rgba(255, 255, 255, .55); box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .7), 0 0 0 3px var(--ink); overflow: hidden; }
.mx-pot .fill { position: absolute; left: 0; right: 0; bottom: 0; height: 70%; background: var(--c); box-shadow: inset -6px 0 0 rgba(0, 0, 0, .15), inset 0 4px 0 rgba(255, 255, 255, .35); }
.mx-pot .lid { position: absolute; left: 6px; right: 6px; top: 0; height: 8px; background: #6b4527; z-index: 2; }
.mx-pot .lbl { font-weight: 700; font-size: 14px; color: #fff; text-shadow: 1px 2px 0 #000; text-transform: capitalize; }
.mx-pot.hinted .jar { animation: pulseGlow .8s ease-in-out infinite; }
.mx-bucket { position: relative; width: clamp(150px, 22vw, 200px); height: clamp(170px, 26vh, 220px); display: flex; align-items: flex-end; justify-content: center; }
.mx-pail { position: relative; width: 100%; height: 72%; clip-path: polygon(0 0, 100% 0, 90% 100%, 10% 100%); background: linear-gradient(90deg, #8a8f99, #c8ccd2 40%, #8a8f99); overflow: hidden; }
.mx-pail::before { content: ''; position: absolute; inset: 8px 12px 10px; background: #3a3a44; clip-path: polygon(0 0, 100% 0, 92% 100%, 8% 100%); }
.mx-paint { position: absolute; left: 0; right: 0; bottom: 0; height: 0; background: var(--c, transparent); transition: height .5s ease-out, background .6s; clip-path: polygon(6% 0, 94% 0, 88% 100%, 12% 100%); margin: 0 6px 10px; overflow: hidden; }
.mx-paint.draining { transition: height .35s ease-in; }
.mx-swirl { position: absolute; inset: -40%; background: conic-gradient(from 0deg, rgba(255, 255, 255, .25), transparent 25%, rgba(255, 255, 255, .2) 50%, transparent 75%); animation: spin 3s linear infinite; }
.mx-rim { position: absolute; left: -6px; right: -6px; top: 28%; height: 12px; border-radius: 6px; background: #6a6f78; box-shadow: 0 0 0 3px var(--ink); }
.mx-bucket.over .mx-rim { background: #ffd25a; box-shadow: 0 0 0 3px var(--ink), 0 0 20px #ffd25a; }
.mx-bucket.done .mx-pail { box-shadow: 0 0 30px rgba(255, 230, 120, .9); }
.mx-bucket.done .mx-swirl { animation-duration: .6s; }
.mx-stream { position: absolute; left: 50%; top: -10%; width: 16px; height: 0; margin-left: -8px; border-radius: 8px; background: var(--c); z-index: 3; transition: height .22s ease-in; }
.mx-stream.on { height: 48%; }

/* ---------- Big, focused puzzle layout ----------
   The puzzle fills most of the screen; the header is just a subject tag, the
   instruction and a speaker button. Sizes follow the screen height. */
.pz-panel { width: min(1080px, 100%); height: min(100%, 820px); max-height: 100%; padding: 12px 16px 12px; }
.pz-head { min-height: 52px; padding: 0 12px; }
.pz-head .pz-title { flex: 1; margin: 0; font-size: clamp(20px, 4vh, 40px); }
.pz-action { align-self: center; margin: 4px 0 10px; padding: 5px 16px; border-radius: 999px; font-weight: 600; font-size: clamp(14px, 2.2vh, 20px); color: var(--th-soft); background: rgba(0, 0, 0, .3); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--th-frame) 45%, transparent); text-align: center; }
.pz-action:empty { display: none; }
.pz-prompt { font-size: clamp(34px, 8vh, 86px); }
.big-pic { font-size: clamp(60px, 13vh, 130px); }
.pz-visual .ic { font-size: clamp(26px, 5.5vh, 54px); }
.pz-options { max-width: 920px; }
.pz-options.l-num.n4 { max-width: 820px; }
.opt { min-height: clamp(84px, 17vh, 170px); font-size: clamp(34px, 7vh, 72px); }
.opt.pic .face { font-size: clamp(50px, 10vh, 112px); }
.opt .lbl { font-size: clamp(14px, 2.3vh, 22px); }
.l-word .opt { font-size: clamp(30px, 6.5vh, 64px); }
.l-art .opt { min-height: clamp(130px, 27vh, 250px); }
.painting { width: clamp(90px, 20vh, 190px); }
/* Block Builder */
.bb-mat { min-height: clamp(180px, 36vh, 360px); min-width: min(520px, 62%); }
.bb-pile { min-width: clamp(130px, 15vw, 190px); min-height: clamp(96px, 15vh, 150px); flex-direction: column; gap: 4px; }
.bb-pile .pile-row { display: flex; align-items: center; gap: 10px; }
.bb-pile .tap { font-size: clamp(12px, 1.8vh, 15px); font-weight: 600; color: #8a6a3a; }
.rod { width: clamp(20px, 3.4vh, 30px); height: clamp(150px, 31vh, 300px); background: linear-gradient(#5aa0ff 0 84%, #2f6fd0 84% 100%); background-size: 100% 10%; }
.bb-pile .rod.big { height: clamp(70px, 12vh, 120px); background: linear-gradient(#5aa0ff 0 80%, #2f6fd0 80% 100%); background-size: 100% 10%; }
.cube { width: clamp(22px, 4.2vh, 36px); height: clamp(22px, 4.2vh, 36px); }
.bb-ones { width: calc(2 * clamp(22px, 4.2vh, 36px) + 10px); max-width: none; }
.bb-label { font-size: clamp(13px, 2vh, 17px); }
/* Sort It */
.so-card { width: clamp(84px, 14vh, 130px); height: clamp(92px, 16vh, 142px); }
.so-card .pic { font-size: clamp(38px, 7.6vh, 72px); }
.so-card .lbl { font-size: clamp(12px, 1.9vh, 16px); }
.so-bin { min-height: clamp(130px, 27vh, 270px); }
.so-head { font-size: clamp(18px, 3.2vh, 30px); }
/* Word Builder */
.wb-pic { font-size: clamp(72px, 16vh, 150px); }
.wb-slot { width: clamp(54px, 10vh, 96px); height: clamp(62px, 11.5vh, 110px); font-size: clamp(34px, 7vh, 64px); }
.wb-tile { width: clamp(56px, 10vh, 96px); height: clamp(56px, 10vh, 96px); font-size: clamp(32px, 6.5vh, 60px); }
/* Paint Mixer */
.mx-pot .jar { width: clamp(56px, 10vh, 92px); height: clamp(62px, 11vh, 100px); }
.mx-pot .lbl { font-size: clamp(13px, 2vh, 17px); }
.mx-bucket { width: clamp(150px, 26vh, 250px); height: clamp(170px, 32vh, 300px); }
.mx-target .blob { width: clamp(50px, 8vh, 76px); height: clamp(50px, 8vh, 76px); }

/* Readability: the words kids sort and the block mat labels are part of the puzzle. */
.so-card .lbl { font-size: clamp(14px, 2.3vh, 19px); font-weight: 700; }
.bb-label { font-size: clamp(14px, 2.3vh, 19px); font-weight: 700; }
.pz-prompt .story { font-weight: 700; }

/* ---------- "Hands off!" ready state ----------
   While a fight is on, the puzzle shows dimmed until the child stops tapping. */
#puzzle.arming .pz-body, #puzzle.arming .pz-head .pz-title, #puzzle.arming .pz-action { filter: blur(3px) saturate(.5) brightness(.75); pointer-events: none; }
.pz-ready { --p: 0; position: absolute; inset: 0; z-index: 9; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; background: rgba(12, 8, 4, .35); cursor: default; }
.pz-ready .ring { width: clamp(110px, 20vh, 170px); aspect-ratio: 1; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: conic-gradient(#7af08a calc(var(--p) * 360deg), rgba(255, 255, 255, .15) 0); box-shadow: 0 0 0 5px var(--ink), 0 0 30px rgba(120, 240, 140, calc(var(--p) * .7)); }
.pz-ready .ring span { width: 82%; aspect-ratio: 1; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: clamp(48px, 9vh, 80px); background: var(--th-tile); box-shadow: inset 0 0 0 3px var(--ink); }
.pz-ready .msg { font-weight: 700; font-size: clamp(28px, 5.5vh, 52px); color: var(--th-text); text-shadow: 3px 3px 0 var(--ink); }
.pz-ready .sub { font-weight: 600; font-size: clamp(14px, 2.2vh, 20px); color: var(--th-soft); text-shadow: 2px 2px 0 var(--ink); }
.pz-ready.poke .ring { animation: wiggle .35s; }

/* ---------- Grade 1 question pieces ---------- */
.pz-prompt .story { display: block; max-width: 30em; margin: 0 auto; font-size: clamp(20px, 3.8vh, 36px); line-height: 1.25; color: #3a2a1a; text-shadow: none; }
.pz-prompt .blank { display: inline-block; min-width: 3.2em; color: #e0702a; letter-spacing: -.05em; }
.pz-prompt .word-tag { margin-left: .3em; vertical-align: middle; font-size: clamp(26px, 5vh, 46px); color: #2a6fc4; letter-spacing: .04em; }
.big-pic.sm { font-size: clamp(44px, 9vh, 90px); }
svg.clock { width: clamp(150px, 30vh, 280px); height: auto; filter: drop-shadow(0 5px 0 rgba(0, 0, 0, .18)); }
svg.clock .face { fill: #fffaf0; stroke: var(--ink); stroke-width: 4; }
svg.clock text { font: 700 11px var(--font, system-ui), sans-serif; fill: #3a2a1a; text-anchor: middle; }
svg.clock .hh { stroke: #c0392b; stroke-width: 6.5; stroke-linecap: round; }
svg.clock .mh { stroke: #2f6fe0; stroke-width: 4; stroke-linecap: round; }
svg.clock .pin { fill: var(--ink); }
svg.wheel { width: clamp(130px, 26vh, 240px); height: auto; filter: drop-shadow(0 5px 0 rgba(0, 0, 0, .18)); }
.line-art { display: block; width: 2.3em; height: 1.4em; }
.l-expr .opt { font-size: clamp(30px, 6vh, 58px); white-space: nowrap; }

/* A hand that shows the drag move once, without revealing an answer. */
.demo-hand { position: fixed; z-index: 120; pointer-events: none; font-size: 54px; line-height: 1; transform: translate(-30%, -10%); filter: drop-shadow(0 4px 0 rgba(0, 0, 0, .35)); }
.demo-hand::after { content: ''; position: absolute; left: 22%; top: -6px; width: 26px; height: 26px; border-radius: 50%; border: 4px solid rgba(255, 255, 255, .85); opacity: 0; animation: demoTap 1.9s ease-out; }
@keyframes demoTap { 0%, 12% { opacity: 0; transform: scale(.4); } 22% { opacity: 1; transform: scale(1); } 40%, 100% { opacity: 0; transform: scale(1.4); } }
.so-card.nudge, .mx-pot.nudge { animation: wiggle .5s 2; }

/* ---------- animations ---------- */
@keyframes popIn { from { transform: scale(.4); } to { transform: scale(1); } }
@keyframes starIn { from { transform: scale(0) rotate(-40deg); } to { transform: scale(1) rotate(0); } }
@keyframes stampIn { from { transform: scale(2.4) rotate(-6deg); opacity: 0; } to { transform: scale(1) rotate(-6deg); opacity: 1; } }
@keyframes wiggle { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-8px) rotate(-2deg); } 40% { transform: translateX(8px) rotate(2deg); } 60% { transform: translateX(-5px); } 80% { transform: translateX(5px); } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes pulseBox { 50% { transform: scale(1.06); box-shadow: 0 0 0 4px #ffd25a, 0 0 18px rgba(255, 210, 90, .8); } }
@keyframes pulseGlow { 50% { box-shadow: 0 0 0 4px #ffd25a, 0 0 24px 6px rgba(255, 210, 90, .9); transform: scale(1.06); } }
@keyframes reveal { 50% { transform: translateY(-8px) scale(1.08); } }
@keyframes rise { from { transform: translateY(14px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes fadeIn { from { opacity: 0; } }
@keyframes binYes { 40% { transform: scale(1.05); box-shadow: inset 0 0 0 5px #3f9e48, 0 0 24px rgba(90, 220, 100, .8); } }
@keyframes mergeOut { to { transform: translateY(-30px) scale(.3); opacity: 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes spinSlow { to { transform: rotate(180deg); } }
@keyframes wobble { 50% { border-radius: 55% 45% 52% 48%; } }
@keyframes glowPulse { 50% { box-shadow: 0 0 0 3px var(--ink), 0 0 18px #ffd25a; } }

/* (narrow screens, but not short phones held sideways: those get the side-by-side layouts under
   "short screens" below, since stacking things there makes the puzzle too tall) */
@media (max-width: 640px) and (orientation: portrait), (max-width: 640px) and (min-height: 481px) {
  .pz-panel { padding: 10px 10px; }
  .pz-head { padding: 0 6px; }
  .pz-vs { display: none; }
  .pz-options.n4 { grid-template-columns: repeat(2, 1fr); }
  .bb { flex-direction: column; align-items: center; }
  .bb-supply { flex-direction: row; }
  .bb-pile { min-width: 100px; min-height: 70px; }
  .bb-pile .rod.big { height: 60px; }
  .rod { height: 120px; background: repeating-linear-gradient(#5aa0ff 0 10px, #2f6fd0 10px 12px); }
  .mx-stage { flex-direction: column; align-items: center; }
}
@media (max-height: 560px) {
  .pz-title { margin: 4px 0; font-size: 20px; }
  .opt { min-height: 64px; }
  .rod { height: 110px; background: repeating-linear-gradient(#5aa0ff 0 9px, #2f6fd0 9px 11px); }
  .so-bin { min-height: 96px; }
}
.reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; }

/* ---------- short screens (phones held sideways) ---------- */
@media (max-height: 480px) {
  #puzzle { padding: clamp(12px, 4.5vh, 22px) clamp(18px, 7vw, 64px); }
  .pz-panel { padding: 6px 10px 8px; }
  .pz-panel::before, .pz-panel::after { display: none; }
  .pz-head { min-height: 30px; padding: 0 4px; }
  .pz-chip { font-size: 13px; padding: 3px 10px 3px 6px; }
  .icon-btn { width: 34px; height: 34px; font-size: 18px; }
  .pz-title { font-size: 17px; margin: 2px 0 4px; }
  .pz-body { padding: 6px 8px; gap: 6px; }
  .pz-prompt { font-size: 26px; }
  .big-pic { font-size: 46px; }
  .pz-visual .ic { font-size: 20px; }
  .opt { min-height: 54px; font-size: 26px; border-radius: 10px; }
  .opt.pic .face { font-size: 36px; }
  .opt .lbl { font-size: 12px; }
  .l-art .opt { min-height: 96px; }
  .painting { width: 72px; }
  .pz-foot { margin-top: 6px; }
  .pz-timer { height: 10px; }
  .pz-feedback { top: 40px; font-size: 15px; padding: 6px 14px; }
  .pz-hintbox { font-size: 14px; padding: 8px 12px; bottom: 30px; }
  .bb { gap: 10px; align-items: center; }
  .bb-supply { flex-direction: column; gap: 8px; }
  .bb-pile { min-width: 86px; min-height: 58px; padding: 4px 8px; }
  .bb-pile .rod.big { height: 50px; background: repeating-linear-gradient(#5aa0ff 0 4px, #2f6fd0 4px 5px); }
  .bb-pile .cube.big { width: 24px; height: 24px; }
  .bb-pile b { font-size: 20px; }
  .bb-mat { min-height: 120px; padding: 6px 10px; }
  .bb-label { font-size: 12px; margin-bottom: 2px; }
  .rod { width: 18px; height: 100px; background: repeating-linear-gradient(#5aa0ff 0 8px, #2f6fd0 8px 10px); }
  .cube { width: 18px; height: 18px; }
  .bb-ones { width: 46px; max-width: 46px; }
  .bb-count { font-size: 15px; padding: 3px 10px; }
  .bb-actions .btn, .wb-actions .btn, .mx-actions .btn { min-height: 36px; padding: 4px 12px; font-size: 15px; }
  .so-tray { min-height: 64px; gap: 6px; }
  .so-card { width: 62px; height: 68px; }
  .so-card .pic { font-size: 30px; }
  .so-card .lbl { font-size: 11px; }
  .so-bin { min-height: 76px; padding: 4px; }
  .so-head { font-size: 15px; }
  .so-card.placed { width: 42px; height: 42px; }
  .so-card.placed .pic { font-size: 22px; }
  .so-tip { display: none; }
  .wb-pic { font-size: 50px; }
  .wb-slot { width: 44px; height: 50px; font-size: 30px; border-bottom-width: 4px; }
  .wb-tile { width: 46px; height: 46px; font-size: 28px; }
  .mx-target .blob { width: 34px; height: 34px; }
  .mx-target .nm { font-size: 18px; }
  .mx-recipe .drop { width: 24px; height: 24px; }
  .mx-pot .jar { width: 42px; height: 46px; }
  .mx-pot .lbl { font-size: 11px; }
  .mx-bucket { width: 110px; height: 120px; }
  .pz-stamp .stars { font-size: 40px; }
  .pz-gotit { padding: 10px; bottom: 6px; }
  .pz-explain { font-size: 15px; }
}
@media (max-height: 480px) and (orientation: landscape) {
  /* Block Builder: prompt + actions in a side column to save height */
  .t-build { display: grid; grid-template-columns: auto 1fr; grid-template-areas: "prompt bb" "count bb" "actions bb"; align-items: center; justify-items: center; column-gap: 14px; }
  .t-build .pz-prompt { grid-area: prompt; }
  .t-build .bb { grid-area: bb; }
  .t-build .bb-count { grid-area: count; }
  .t-build .bb-actions { grid-area: actions; flex-direction: column; gap: 6px; }
  .t-mix .mx-top { gap: 10px; }
  /* (the picture sits beside its word to save height; the letters stay below, in their tray) */
  .t-word .wb-word { flex-direction: row; gap: 14px; }
}

/* ---------- review fixes ---------- */
/* Hints sit over the lower part of the puzzle, never over the question or the instructions. */
.pz-hintbox, .pz-hintbox.top, .pz-hintbox.below { top: auto; bottom: clamp(48px, 9vh, 72px); }
.pz-close { margin-left: 8px; }
/* Block Builder: up to 9 ten-rods in one row and 19 cubes in a 4-wide stack, without scrolling. */
.t-build .bb-mat { min-width: min(600px, 66%); }
.t-build .bb-col:first-child { flex: 2.2; }
.t-build .bb-tens { flex-wrap: nowrap; gap: 4px; justify-content: center; }
.t-build .bb-tens .rod { width: clamp(16px, 2.6vh, 24px); height: clamp(120px, 26vh, 240px); flex: none; }
.t-build .bb-ones { width: calc(4 * clamp(18px, 3.4vh, 30px) + 14px); }
.t-build .bb-ones .cube { width: clamp(18px, 3.4vh, 30px); height: clamp(18px, 3.4vh, 30px); }
/* Cloze and grammar sentences read clearly next to the big answer buttons. */
.pz-prompt .story { font-size: clamp(22px, 4.4vh, 40px); }
@media (max-height: 420px) { .mx-bucket { width: 120px; height: 140px; } }
.t-build .bb-mat { min-height: clamp(140px, 28vh, 320px); }
.t-build .bb-tens .rod { height: clamp(110px, 24vh, 230px); }

/* ---------- JK and SK puzzles (puzzles/early.js) ----------
   Bigger buttons, no key numbers, and the right answer glows after a miss. */
.pz-body.early .pz-options { gap: clamp(14px, 2.4vw, 28px); }
.pz-body.early .opt { min-height: clamp(110px, 24vh, 230px); }
.pz-body.early .opt .k { display: none; }
.pz-body.early .opt .swatch { width: 1.7em; height: 1.7em; }
.pz-body.early .opt.pic .face { font-size: clamp(58px, 13vh, 130px); }
.pz-body.early .replay { margin-top: 12px; }
.opt.glow { z-index: 2; animation: glowWiggle 1.1s ease-in-out infinite; box-shadow: inset 0 -7px 0 var(--th-card-sh), inset 0 4px 0 #fff, 0 0 0 5px #ffd25a, 0 0 0 9px var(--ink), 0 0 34px 10px rgba(255, 210, 90, .9); }
@keyframes glowWiggle { 0%, 100% { transform: rotate(0) scale(1.03); } 25% { transform: rotate(-1.5deg) scale(1.06); } 75% { transform: rotate(1.5deg) scale(1.06); } }
.mini-grp { display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: center; max-width: 3.4em; gap: .06em; font-size: .8em; line-height: 1.1; }
.pz-body.early .pz-visual .ic { font-size: clamp(30px, 7vh, 64px); }
.mini-grp i { font-style: normal; }
.numeral { font-weight: 800; line-height: 1; color: #2a3a6a; }
.letter { font-weight: 800; line-height: 1; color: #2a6fc4; }
.dots { font-size: .7em; letter-spacing: .1em; color: #2a6fc4; }
.pz-prompt .letter, .pz-prompt > .numeral { font-size: clamp(64px, 12vh, 120px); }
.die { display: inline-grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); width: 1.2em; height: 1.2em; padding: .1em; gap: .05em; vertical-align: middle; background: #fff; border-radius: .18em; box-shadow: 0 0 0 3px var(--ink), inset 0 -4px 0 #ddd; }
.die b { border-radius: 50%; background: #2b2b2e; }
.pz-prompt .die { font-size: clamp(80px, 14vh, 130px); }
.tenframe { display: inline-grid; grid-template-columns: repeat(5, 1fr); gap: 5px; padding: 7px; background: #fff; border-radius: 10px; box-shadow: 0 0 0 3px var(--ink); vertical-align: middle; }
.tenframe i { display: flex; width: clamp(34px, 7vh, 58px); height: clamp(34px, 7vh, 58px); border-radius: 6px; background: var(--th-card-lo); }
.tenframe i.on::after { content: ''; margin: auto; width: 72%; height: 72%; border-radius: 50%; background: #e8352b; box-shadow: inset -3px -3px 0 rgba(0, 0, 0, .2); }
svg.shape { width: 1.3em; height: 1.3em; vertical-align: middle; overflow: visible; }
.pz-prompt svg.shape { width: clamp(96px, 17vh, 150px); height: clamp(96px, 17vh, 150px); }
.pz-prompt .swatch.big { width: clamp(84px, 15vh, 130px); height: clamp(84px, 15vh, 130px); }
.pz-prompt .mini-grp { font-size: 1.1em; max-width: 4em; vertical-align: middle; }

/* ---------- Hints ----------
   The hint sits under the title, in place of the "what to do" line (the engine hides that line
   while a hint shows), so it never covers the answers or the Done and take-away buttons. */
.pz-hintbox, .pz-hintbox.top, .pz-hintbox.below { position: relative; left: auto; top: auto; bottom: auto; transform: none; z-index: auto; align-self: center; width: min(780px, 100%); margin: 2px auto 8px; padding: 8px 16px; }
@media (max-height: 480px) { .pz-hintbox, .pz-hintbox.top, .pz-hintbox.below { margin: 0 auto 4px; padding: 5px 10px; } }

/* ---------- Block Builder: add and take-away buttons ---------- */
.bb-ctl { display: flex; gap: 8px; align-items: stretch; }
.bb-take { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: clamp(64px, 7vw, 88px); padding: 6px 8px; border: none; border-radius: 14px; cursor: pointer; font-family: var(--font);
  background: linear-gradient(#ffe6de, #f3c8bc); box-shadow: inset 0 -6px 0 #d49a8a, 0 0 0 4px var(--ink), 0 6px 0 4px rgba(0, 0, 0, .2); transition: transform .12s, opacity .2s; }
.bb-take b { font-size: clamp(22px, 3.4vh, 30px); color: #b5281f; }
.bb-take .tap { font-size: clamp(11px, 1.7vh, 14px); font-weight: 600; color: #8a4a3a; }
.bb-take:hover:not(:disabled) { transform: translateY(-2px); }
.bb-take:active:not(:disabled) { transform: translateY(3px); }
.bb-take:disabled { opacity: .35; cursor: default; }
.bb-tens .rod, .bb-ones .cube { cursor: pointer; }
@media (max-width: 640px) and (orientation: portrait), (max-width: 640px) and (min-height: 481px) { .bb-take { min-width: 54px; padding: 4px 6px; } }
@media (max-height: 480px) { .bb-take { min-width: 54px; padding: 4px 6px; } .bb-take b { font-size: 20px; } .bb-take .tap { display: none; } }
/* Phones held upright: the four add/take buttons fit across, and Done stays in view. */
@media (max-width: 640px) and (orientation: portrait), (max-width: 640px) and (min-height: 481px) {
  .bb-supply { gap: 8px; }
  .bb-ctl { gap: 5px; }
  .bb-pile { min-width: 0; padding: 6px 8px; }
  .bb-pile .pile-row { gap: 5px; }
  .bb-pile .tap, .bb-take .tap { display: none; }
  .bb-pile b, .bb-take b { font-size: 22px; }
  .bb-take { min-width: 46px; }
  .t-build .pz-prompt { font-size: clamp(28px, 6vh, 48px); }
  .t-build .bb-tens .rod { height: clamp(96px, 17vh, 170px); }
  .t-build .bb-mat { min-height: 0; min-width: 0; width: 100%; }
}

/* ---------- developer quick-solve ---------- */
.pz-dev { background: #3a1f5a !important; box-shadow: 0 0 0 3px #b98bff, 0 0 0 5px var(--ink) !important; }
/* (also God mode's, on a phone: a finger-sized place to tap around the small button) */
.pz-dev { position: relative; flex: none; }
.pz-dev::after { content: ''; position: absolute; inset: -8px -6px; }
/* (short screens have no room to spare in the header: beside a weekly lesson's long question it
   squeezed the title so tall that the puzzle scrolled. There it hangs on the panel's bottom-left
   corner instead, taking no room.) */
@media (max-height: 480px) { .pz-head .pz-dev { position: absolute; left: -14px; bottom: -14px; z-index: 7; } }
/* Paint Mixer on phones held sideways: the paints sit in one row and Empty bucket moves beside the
   bucket, so everything fits without scrolling */
@media (max-height: 480px) and (orientation: landscape) {
  .mx-shelf { grid-template-columns: none; grid-auto-flow: column; }
  .t-mix { display: grid; grid-template-columns: auto auto; grid-template-areas: "top top" "stage actions"; align-items: end; justify-content: center; column-gap: 14px; }
  .t-mix .mx-top { grid-area: top; }
  .t-mix .mx-stage { grid-area: stage; }
  .t-mix .mx-actions { grid-area: actions; flex-direction: column; margin-bottom: 8px; }
}
/* A solved puzzle's answer bursts on the baddie as the hero strikes (game/run.js strike) */
.float.answer-hit { font-size: clamp(24px, 4.6vh, 40px); text-shadow: -3px 0 #000, 3px 0 #000, 0 -3px #000, 0 3px #000, 0 0 18px rgba(255, 255, 255, .7); }
/* A puzzle that starts from a fight grows out of the clash point on screen and shrinks back into it
   (opts.from in puzzles/engine.js); the clash callout names the baddie (game/run.js clash) */
#puzzle.burst .pz-panel { transform: scale(.06); transition: transform .4s cubic-bezier(.2, 1.25, .4, 1), opacity .18s; }
#puzzle.burst.show .pz-panel { transform: scale(1); }
#puzzle.burst.closing .pz-panel { transform: scale(.06); opacity: 0; transition: transform .28s ease-in, opacity .28s; }
.float.clash { padding: 5px 14px; border-radius: 12px; font-size: clamp(16px, 2.6vh, 22px); color: #fff; background: rgba(140, 22, 12, .9); box-shadow: 0 0 0 3px #000, 0 0 20px rgba(255, 80, 40, .75); text-shadow: 0 2px 0 #000; }
/* Why the stamp says what it says, and what your streak did (game/run.js stampNote) */
.pz-stamp .why { font-weight: 700; font-size: clamp(15px, 2.2vw, 22px); color: #fff3c8; text-shadow: 2px 2px 0 #000; animation: rise .5s ease-out .15s both; }
.pz-stamp .note { display: flex; align-items: center; gap: 8px; padding: 4px 14px; border-radius: 999px; font-weight: 700; font-size: clamp(14px, 2vw, 20px); color: #fff; background: rgba(0, 0, 0, .55); box-shadow: 0 0 0 2px #000; animation: rise .6s ease-out .3s both; }
.pz-stamp .row-of.trick { font-family: var(--pixel); font-size: clamp(14px, 2.2vw, 24px); box-shadow: 0 0 0 3px #ffd25a, 0 0 28px 8px rgba(255, 140, 40, .9); animation: rise .6s ease-out .35s both, fireTag 1s ease-in-out 1s infinite; }
/* a gold (weekly-lesson) puzzle: a golden frame and glow, and your gold pet filling on its chip */
#puzzle.lesson .pz-panel { box-shadow: inset 0 0 0 4px #ffd25a, inset 0 0 0 7px #a8741c, 0 0 0 4px var(--ink), 0 0 0 8px #ffe58a, 0 0 0 11px var(--ink), 0 30px 70px rgba(0, 0, 0, .8), 0 0 70px 16px rgba(255, 200, 80, .45); }
#puzzle.lesson .pz-dim { background: radial-gradient(ellipse at 50% 45%, rgba(255, 200, 80, .12), rgba(20, 12, 4, .6)); }
.pz-chip.lesson { font-size: 16px; padding-right: 6px; background: linear-gradient(#fff0a0, #ffc23a); }
.pz-jar { display: inline-flex; align-items: center; margin-left: 6px; padding: 1px 8px 1px 4px; border-radius: 999px; font-size: 13px; color: #fff3c8; background: #5a3a10; box-shadow: 0 0 0 2px var(--ink); }
.pz-jar .pzj-pet { display: block; width: 24px; height: 24px; margin: -5px 0; object-fit: contain; filter: drop-shadow(0 0 3px rgba(255, 210, 90, .9)); }
.pz-jar .pzj-prize { margin-left: 4px; font-style: normal; font-size: 14px; line-height: 1; }

/* ---------- phones held upright ("Play this way" on the turn-your-phone card) ----------
   The header wraps so the instruction gets a line of its own, two answers sit on a row, and
   pictures and sorting cards follow the screen's width instead of its (tall) height. */
@media (max-width: 520px) and (orientation: portrait) {
  .pz-head { flex-wrap: wrap; justify-content: center; row-gap: 6px; }
  .pz-head .pz-title { flex: 1 1 100%; order: 3; font-size: clamp(18px, 6vw, 26px); }
  .pz-options.n3, .pz-options.n4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pz-options.n3 > :last-child { grid-column: 1 / -1; justify-self: center; width: calc(50% - 6px); }
  .opt { min-width: 0; min-height: clamp(76px, 22vw, 110px); }
  .pz-prompt { font-size: clamp(30px, 10vw, 48px); }
  .big-pic { font-size: clamp(54px, 18vw, 84px); }
  .pz-visual .ic { font-size: clamp(22px, 7vw, 34px); }
  .so-card { width: clamp(68px, 20vw, 90px); height: clamp(74px, 22vw, 98px); }
  .so-card .pic { font-size: clamp(30px, 9vw, 44px); }
  .so-card .lbl { font-size: 12px; }
  .so-bin { min-height: clamp(96px, 16vh, 150px); }
  .so-bins { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .so-bins.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .so-bin { min-width: 0; padding: 6px; }
  .so-head { font-size: clamp(13px, 4.2vw, 18px); gap: 4px; }
  .so-head .ico { font-size: 1.2em; }
  /* (taller than the screen: the puzzle scrolls, never squeezes the cards over the boxes) */
  .pz-body { justify-content: flex-start; }
  .pz-body > * { flex-shrink: 0; }
}

/* ---------- Wrong answers (puzzles/engine.js wrong) ----------
   A wrong answer is never scary, but you can't miss it: a red flash round the puzzle and a short
   shake (no shake with reduce motion), a big red ✗ on what was wrong (an answer button, a letter,
   a group, the block mat, the paint bucket), and the gem chip shows what the puzzle can still give. */
#puzzle { --pz-x: linear-gradient(45deg, transparent 38%, #e23b2e 38% 62%, transparent 62%), linear-gradient(-45deg, transparent 38%, #e23b2e 38% 62%, transparent 62%); }
.opt.wrong::after, .wb-slot.bad::before, .wb-tile.nope::after, .so-bin.no::after, .bb-mat.no::after, .mx-bucket.no::after {
  content: ''; position: absolute; left: 50%; top: 50%; z-index: 3; pointer-events: none; transform: translate(-50%, -50%);
  background: var(--pz-x); filter: drop-shadow(2px 0 0 #fff) drop-shadow(-2px 0 0 #fff) drop-shadow(0 2px 0 #fff) drop-shadow(0 -2px 0 #fff) drop-shadow(0 3px 0 rgba(0, 0, 0, .35));
  animation: xIn .28s cubic-bezier(.2, 1.8, .4, 1) both;
}
@keyframes xIn { from { transform: translate(-50%, -50%) scale(.2) rotate(-35deg); opacity: 0; } to { transform: translate(-50%, -50%) scale(1) rotate(0); opacity: 1; } }
.wb-tile.nope { position: relative; cursor: default; pointer-events: none; color: #f2ece4; text-shadow: none; transform: scale(.92); background: linear-gradient(#cfc7bd, #aaa196); box-shadow: inset 0 -6px 0 #81786e, 0 0 0 4px #6a2018, 0 5px 0 4px rgba(0, 0, 0, .15); }
.wb-tile.nope::after { width: 82%; height: 82%; }
.wb-tile.nope.used::after { display: none; }
.so-bin { position: relative; }
.so-bin.no { box-shadow: inset 0 0 0 5px #c8372b, inset 0 0 0 8px rgba(255, 255, 255, .5), 0 0 20px rgba(226, 59, 46, .55); }
.so-bin.no::after { width: clamp(46px, 11vh, 96px); height: clamp(46px, 11vh, 96px); }
.so-card.nope { box-shadow: inset 0 -6px 0 var(--th-card-sh), 0 0 0 4px #c8372b, 0 0 0 7px var(--ink); }
.bb-mat { position: relative; }
.bb-mat.no { box-shadow: inset 0 0 0 4px #c8372b, 0 0 22px rgba(226, 59, 46, .6); }
.bb-mat.no::after { width: clamp(56px, 15vh, 130px); height: clamp(56px, 15vh, 130px); }
.mx-bucket.no .mx-pail { box-shadow: 0 0 26px rgba(226, 59, 46, .9); }
.mx-bucket.no::after { width: 56%; height: 48%; top: 58%; }
/* the red flash round the puzzle, and the shake */
.pz-redge { position: absolute; inset: 0; z-index: 8; border-radius: 6px; pointer-events: none; opacity: 0; transition: opacity .45s ease-out;
  box-shadow: inset 0 0 0 5px #ff4a3a, inset 0 0 44px 10px rgba(255, 50, 30, .42), 0 0 0 4px #ff4a3a, 0 0 46px 12px rgba(255, 50, 30, .55); }
.pz-panel.miss .pz-redge { opacity: 1; transition: opacity .05s; }
.pz-panel.shake { animation: pzShake .38s ease-in-out; }
@keyframes pzShake { 0%, 100% { transform: translateX(0); } 18% { transform: translateX(-9px) rotate(-.5deg); } 38% { transform: translateX(8px) rotate(.4deg); } 58% { transform: translateX(-5px); } 78% { transform: translateX(3px); } }

/* ---------- The gem chip (puzzles/engine.js showGems, updateGems) ----------
   At the end of the timer bar: what a right answer brings now: +20 on the first try (+15 once the
   bar runs out), +10 on the second,
   nothing after that. A miss shakes it down, and the loss shows in the middle of the puzzle: a red
   "−10" first; the second miss cracks a big gem in two and the chip stays grey at a struck-out +0. */
.pz-gems { position: relative; z-index: 7; display: flex; align-items: center; gap: 5px; padding: 4px 12px 4px 11px; border-radius: 999px; white-space: nowrap;
  font-weight: 800; font-size: 19px; line-height: 1.1; color: #eafcff; text-shadow: 0 2px 0 rgba(0, 0, 0, .45);
  background: linear-gradient(#2d6a98, #183f60); box-shadow: 0 0 0 3px var(--ink), inset 0 -3px 0 rgba(0, 0, 0, .3), inset 0 2px 0 rgba(255, 255, 255, .2); }
.pz-gems[hidden] { display: none; }
.pz-foot .pz-gems { margin: -6px 0; } /* (it reaches past the timer bar's height instead of making the footer taller) */
.pz-gems .gem-ico { width: 20px; height: 20px; }
.pz-gems.drop { animation: gemHit .55s ease-out; }
.pz-gems.tick b { display: inline-block; animation: gemTick .45s ease-out; }
.pz-gems.broke { color: #d6d0c6; background: linear-gradient(#77706a, #4f4a44); }
.pz-gems.broke b { text-decoration: line-through 3px #ff7a6a; }
.pz-gems.broke .gem-ico { position: relative; filter: none; background: linear-gradient(135deg, #ececec 0 30%, #b0b0b0 30% 60%, #808080 60%); }
.pz-gems.broke .gem-ico::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 42%, #2a2622 42% 54%, transparent 54%); }
@keyframes gemHit { 0%, 100% { transform: none; } 15% { transform: scale(1.3) rotate(-7deg); box-shadow: 0 0 0 3px var(--ink), 0 0 0 6px #ff4a3a, 0 0 20px 4px rgba(255, 60, 40, .8); } 35% { transform: translateX(6px) rotate(5deg); } 55% { transform: translateX(-5px); } 75% { transform: translateX(3px); } }
@keyframes gemTick { from { transform: translateY(-8px); opacity: 0; } }
@media (max-height: 480px) { .pz-gems { font-size: 15px; padding: 1px 9px 1px 8px; gap: 4px; } .pz-foot .pz-gems { margin: -5px 0; } .pz-gems .gem-ico { width: 15px; height: 15px; } }
/* the loss, in the middle of the puzzle (it never takes a tap) */
.pz-loss { --gs: clamp(76px, 19vh, 124px); position: absolute; left: 50%; z-index: 9; width: 0; height: 0; pointer-events: none; }
.pz-loss b { position: absolute; left: 0; top: 0; display: flex; align-items: center; gap: 6px; white-space: nowrap; font-weight: 800; font-size: clamp(36px, 9vh, 62px); color: #ff5a48; text-shadow: 3px 3px 0 #000, -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000; animation: lossPop 1.1s ease-out both; }
.pz-loss b .gem-ico { width: .8em; height: .8em; }
.pz-loss.crack b { top: calc(var(--gs) * .8); animation-delay: .3s; }
.pz-loss .g { position: absolute; left: calc(var(--gs) / -2); top: calc(var(--gs) / -2); width: var(--gs); height: var(--gs); background: linear-gradient(135deg, #c9f8ff 0 30%, #4fd2ff 30% 60%, #1e8fd6 60%); filter: drop-shadow(0 0 3px #000) drop-shadow(0 0 14px rgba(120, 220, 255, .9)); }
.pz-loss .whole { clip-path: polygon(50% 0, 100% 38%, 50% 100%, 0 38%); animation: breakWhole .5s ease-out both; }
.pz-loss .l { clip-path: polygon(50% 0, 42% 26%, 56% 48%, 44% 72%, 50% 100%, 0 38%); animation: breakL 1.05s ease-in both; }
.pz-loss .r { clip-path: polygon(50% 0, 100% 38%, 50% 100%, 44% 72%, 56% 48%, 42% 26%); animation: breakR 1.05s ease-in both; }
@keyframes lossPop { 0% { transform: translate(-50%, -50%) scale(.4); opacity: 0; } 14% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; } 28% { transform: translate(-50%, -50%) scale(1); } 70% { opacity: 1; } 100% { transform: translate(-50%, 10%) scale(.95); opacity: 0; } }
@keyframes breakWhole { 0% { transform: scale(.3); opacity: 0; } 30% { transform: scale(1.15); opacity: 1; } 55% { transform: scale(1) rotate(-7deg); } 80% { transform: rotate(7deg); opacity: 1; } 100% { opacity: 0; } }
@keyframes breakL { 0%, 44% { transform: none; opacity: 0; } 46% { opacity: 1; } 100% { transform: translate(-60%, 110%) rotate(-40deg); opacity: 0; filter: drop-shadow(0 0 3px #000) drop-shadow(0 0 14px rgba(120, 220, 255, 0)) grayscale(1); } }
@keyframes breakR { 0%, 44% { transform: none; opacity: 0; } 46% { opacity: 1; } 100% { transform: translate(60%, 120%) rotate(45deg); opacity: 0; filter: drop-shadow(0 0 3px #000) drop-shadow(0 0 14px rgba(120, 220, 255, 0)) grayscale(1); } }
/* reduce motion: the "−10" just shows for a moment, still */
.reduce-motion .pz-loss b { animation: none !important; transform: translate(-50%, -50%); }
.reduce-motion .pz-loss .g { display: none; }

/* ---------- A gold puzzle comes in (puzzles/engine.js goldIn, puzzles/shine.js) ----------
   A weekly-lesson puzzle: the whole panel comes in shimmering gold, and the shimmer quickly
   dissolves away in pixels (a canvas over the panel that never takes a tap), and the gold frame
   keeps a soft, slow glow for as long as the puzzle is open. */
.pz-shine { position: absolute; left: -8px; top: -8px; z-index: 11; width: calc(100% + 16px); height: calc(100% + 16px); pointer-events: none; image-rendering: crisp-edges; image-rendering: pixelated; }
.pz-shine[hidden] { display: none; }
.pz-aura { position: absolute; inset: -11px; z-index: 0; border-radius: 4px; pointer-events: none; opacity: 0; transition: opacity .6s;
  box-shadow: 0 0 0 3px rgba(255, 238, 160, .95), 0 0 28px 8px rgba(255, 205, 70, .85); }
#puzzle.lesson .pz-aura { opacity: .5; animation: auraPulse 2.6s ease-in-out infinite; }
#puzzle.lesson.gold-in .pz-aura { animation: auraIn .7s ease-out, auraPulse 2.6s ease-in-out .7s infinite; }
.reduce-motion #puzzle.lesson.gold-in .pz-aura { opacity: 1; }
@keyframes auraPulse { 0%, 100% { opacity: .45; } 50% { opacity: .9; } }
@keyframes auraIn { 0% { opacity: 0; transform: scale(1.06); } 15% { opacity: 1; } 100% { opacity: .45; transform: scale(1); } }

/* ---------- Word Builder: the word on top, the letters below in their tray ----------
   Never side by side, so the letters to pick never read as part of the word. In a missing-vowel
   puzzle the letters you are given look like a printed word and the blank is a dashed box. */
.wb-word { display: flex; flex-direction: column; align-items: center; gap: clamp(6px, 1.4vh, 14px); }
.wb-tray { display: flex; justify-content: center; max-width: 100%; margin-top: clamp(4px, 1.4vh, 14px); padding: clamp(8px, 1.5vh, 14px) clamp(10px, 1.8vw, 18px); border-radius: 18px;
  background: rgba(150, 110, 50, .16); box-shadow: inset 0 0 0 3px rgba(150, 110, 50, .4), inset 0 6px 12px rgba(0, 0, 0, .12); }
@supports (background: color-mix(in srgb, red 50%, blue)) {
  .wb-tray { background: color-mix(in srgb, var(--th-pz-line) 34%, transparent); box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--th-pz-line) 80%, #000 20%), inset 0 6px 12px rgba(0, 0, 0, .12); }
}
.wb-tray .wb-tiles { max-width: 820px; }
.wb-missing .wb-slot.given { width: auto; min-width: .6em; padding: 0 .04em; color: var(--ink2); background: none; box-shadow: none; border-bottom-color: transparent; }
.wb-missing .wb-slot:not(.given):not(.filled):not(.good) { background: #fff6e2; box-shadow: none; border: 4px dashed #d9822b; }
@media (max-height: 480px) { .wb-tray { margin-top: 8px; padding: 8px 12px; border-radius: 14px; } }
@media (max-width: 520px) and (orientation: portrait) {
  .wb-pic { font-size: clamp(56px, 17vw, 96px); }
  .wb-slots { gap: 6px; }
  .wb-slot { width: clamp(38px, 11.5vw, 64px); height: clamp(48px, 14vw, 76px); font-size: clamp(28px, 9vw, 48px); }
  .wb-tiles { gap: 8px; }
  .wb-tile { width: clamp(44px, 13vw, 64px); height: clamp(44px, 13vw, 64px); font-size: clamp(28px, 8.5vw, 44px); }
}

/* ---------- Every puzzle fits on one screen (owner rule: no scrolling) ----------
   Phones held sideways: the "what to do" line, the pictures and the answer buttons shrink with
   the screen's height, so the question and every button are in view without scrolling. Answer
   buttons stay at least 54px tall. */
@media (max-height: 480px) {
  .pz-action { margin: 0 0 4px; padding: 2px 12px; font-size: 13px; }
  .pz-visual { gap: 4px 8px; }
  .pz-visual .ig { gap: 1px 3px; padding: 4px 6px; }
  .pz-visual .ic { font-size: clamp(18px, 5.5vh, 22px); }
  .pz-visual .op { font-size: 24px; }
  .pz-visual .qbox { width: 44px; height: 44px; font-size: 28px; }
  /* (answer buttons may share a row: a long word gets smaller instead of pushing the row wider) */
  .pz-options > .opt { min-width: 0; }
  .l-word .opt, .l-expr .opt { font-size: clamp(20px, 3.8vw, 30px); }
  .l-art .opt { min-height: clamp(70px, 24vh, 96px); }
  .painting { width: clamp(52px, 18vh, 72px); padding: 4px; }
  .pz-body .replay { min-height: 36px; padding: 3px 12px; font-size: 14px; }
  .t-build .bb-ones { max-width: none; } /* (the 4-wide stack, so 19 ones still fit beside the rods) */
  /* (centred while it fits; when it can't, it scrolls from the top instead of hiding the question) */
  .pz-body.t-choose, .pz-body.t-sort { justify-content: flex-start; }
  .pz-body.t-choose > :first-child, .pz-body.t-sort > :first-child { margin-top: auto; }
  .pz-body.t-choose > :last-child, .pz-body.t-sort > :last-child { margin-bottom: auto; }
  /* "What number is this?": shorter rods, and the ones in two columns beside them */
  .pz-visual.rods .rod { height: clamp(64px, 26vh, 100px); }
  .pz-visual.rods .ones { display: grid; grid-template-columns: repeat(2, auto); gap: 0 4px; }
  .pz-prompt .story { font-size: clamp(18px, 5.6vh, 24px); }
  .pz-prompt .word-tag { font-size: clamp(22px, 6.5vh, 30px); }
  .big-pic.sm { font-size: clamp(34px, 10vh, 44px); }
  svg.clock { width: clamp(84px, 28vh, 150px); }
  svg.wheel { width: clamp(76px, 25vh, 130px); }
  /* JK and SK: big buttons still, but sized by the screen's height */
  .pz-body.early .pz-options { gap: 10px; }
  .pz-body.early .opt { min-height: clamp(56px, 18vh, 110px); }
  .pz-body.early .opt.pic .face { font-size: clamp(32px, 10.5vh, 58px); }
  .pz-body.early .pz-visual .ic { font-size: clamp(20px, 6.6vh, 30px); }
  .pz-body.early .replay { margin-top: 0; }
  .pz-prompt .letter, .pz-prompt > .numeral { font-size: clamp(40px, 13vh, 64px); }
  .pz-prompt .die { font-size: clamp(46px, 15vh, 80px); }
  .tenframe { gap: 3px; padding: 4px; }
  .tenframe i { width: clamp(20px, 6.5vh, 34px); height: clamp(20px, 6.5vh, 34px); }
  .pz-prompt svg.shape { width: clamp(52px, 17vh, 96px); height: clamp(52px, 17vh, 96px); }
  .pz-prompt .swatch.big { width: clamp(46px, 15vh, 84px); height: clamp(46px, 15vh, 84px); }
}
/* Paint Mixer on narrower phones held sideways: the paints sit in three columns beside the bucket,
   and Empty bucket wraps onto two lines, so the bucket keeps its room */
@media (max-height: 480px) and (orientation: landscape) and (max-width: 760px) {
  .mx-shelf { grid-template-columns: repeat(3, auto); grid-auto-flow: row; gap: 6px 10px; padding: 8px 10px 6px; }
  .mx-stage { gap: 12px; }
  .t-mix { column-gap: 10px; }
  .t-mix .mx-actions .btn { white-space: normal; width: 84px; line-height: 1.1; }
}
/* Block Builder on narrower phones held sideways: the add/take buttons on the left with Done under
   them, and the question over the mat, so the mat gets the rest of the width */
@media (max-height: 480px) and (orientation: landscape) and (max-width: 760px) {
  .t-build { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto 1fr auto; grid-template-areas: "supply prompt" "supply count" "supply mat" "actions mat"; row-gap: 6px; }
  .t-build .bb { display: contents; }
  .t-build .bb-supply { grid-area: supply; gap: 6px; }
  .t-build .bb-mat { grid-area: mat; align-self: stretch; width: 100%; min-width: 0; min-height: 0; }
  .t-build .bb-actions .btn { white-space: normal; max-width: 140px; line-height: 1.1; }
  .t-build .bb-col:last-child { flex: none; }
  .t-build .bb-tens { gap: 3px; }
}
/* The smallest phones held sideways. Block Builder: the four add/take buttons in a row over the
   mat, and the question, the count and Done (and Trade) on the left, so Trade never pushes Done
   off the screen; thinner rods so nine still fit across. Word Builder: Say it and Clear sit beside
   the letters instead of under them. */
@media (max-height: 480px) and (orientation: landscape) and (max-width: 620px) {
  .t-build { grid-template-rows: auto auto 1fr; grid-template-areas: "prompt supply" "count mat" "actions mat"; }
  .t-build .bb-supply { flex-direction: row; gap: 6px; }
  .t-build .pz-prompt { max-width: 130px; font-size: 22px; }
  .t-build .bb-count { max-width: 130px; padding: 2px 6px; font-size: 12px; line-height: 1.15; text-align: center; }
  .t-build .bb-actions { gap: 5px; }
  .t-build .bb-actions .btn { max-width: 120px; font-size: 14px; }
  .t-build .bb-mat { gap: 8px; padding: 6px 8px; }
  .bb-ctl { gap: 4px; }
  .bb-pile { min-width: 0; min-height: 46px; padding: 4px 6px; }
  .bb-pile .tap { display: none; }
  .bb-pile .pile-row { gap: 5px; }
  .bb-pile b, .bb-take b { font-size: 18px; }
  .bb-pile .rod.big { height: 30px; background: linear-gradient(#5aa0ff 0 75%, #2f6fd0 75% 100%); background-size: 100% 10%; }
  .bb-pile .cube.big { width: 20px; height: 20px; }
  .bb-take { min-width: 44px; }
  .t-build .bb-col:first-child { min-width: 0; }
  .t-build .bb-col:last-child { min-width: 0; }
  .t-build .bb-tens .rod { width: 12px; height: clamp(70px, 27vh, 110px); }
  .t-build .bb-ones { width: calc(4 * 14px + 12px); }
  .t-build .bb-ones .cube { width: 14px; height: 14px; }
  .t-word { display: grid; grid-template-columns: auto auto; grid-template-areas: "word word" "tray actions"; align-items: center; justify-content: center; gap: 6px 10px; }
  .t-word .wb-word { grid-area: word; }
  .t-word .wb-tray { grid-area: tray; margin-top: 0; }
  .t-word .wb-actions { grid-area: actions; flex-direction: column; gap: 8px; }
  .t-word .wb-word { gap: 10px; }
  .wb-slots { gap: 5px; }
  .wb-pic { font-size: 44px; }
  .wb-tiles { gap: 6px; }
  .wb-tile { width: 44px; height: 44px; }
}
@media (max-height: 340px) {
  .pz-head .pz-title { font-size: 18px; line-height: 1.1; }
  .pz-hintbox, .pz-hintbox.top, .pz-hintbox.below { box-sizing: border-box; padding: 4px 10px; font-size: 14px; line-height: 1.15; }
  .mx-shelf { gap: 4px 8px; }
  .mx-pot { gap: 1px; }
  .mx-pot .lbl { line-height: 1; }
  .pz-body { padding: 5px 8px; gap: 5px; }
  .pz-foot { margin-top: 4px; }
  .mx-pot .jar { width: 38px; height: 40px; }
  .mx-bucket { width: 96px; height: 108px; }
  .mx-target { padding: 4px 14px 4px 6px; }
  .mx-target .blob { width: 28px; height: 28px; }
  .mx-recipe { font-size: 20px; }
}

/* Phones held upright: sizes follow the screen's width, not its (tall) height, so a puzzle and its
   buttons fit below the top bar without scrolling. */
@media (max-width: 700px) and (orientation: portrait) {
  .pz-action { margin: 2px 0 6px; font-size: clamp(13px, 4vw, 17px); }
  .pz-body { padding: 10px; gap: 10px; }
  .pz-hintbox, .pz-hintbox.top, .pz-hintbox.below { box-sizing: border-box; }
  .pz-body:not(.t-mix) > :first-child { margin-top: auto; } /* (centred while it fits; never pushed up out of view) */
  .pz-body:not(.t-mix) > :last-child { margin-bottom: auto; }
  .pz-visual .ic { font-size: clamp(20px, 6vw, 34px); }
  .opt { font-size: clamp(30px, 9.5vw, 58px); }
  .opt.pic .face { font-size: clamp(40px, 12vw, 70px); }
  .l-word .opt, .l-expr .opt { font-size: clamp(22px, 7vw, 44px); }
  .l-art .opt { min-height: clamp(96px, 28vw, 160px); }
  .painting { width: clamp(80px, 26vw, 140px); }
  .pz-prompt .story { font-size: clamp(20px, 6vw, 30px); }
  .pz-prompt .word-tag { font-size: clamp(26px, 9vw, 40px); }
  .big-pic.sm { font-size: clamp(44px, 14vw, 80px); }
  svg.clock { width: clamp(130px, 42vw, 220px); }
  svg.wheel { width: clamp(120px, 38vw, 200px); }
  .pz-body.early .pz-options { gap: 12px; }
  /* (three pictures or numbers fit on one row) */
  .pz-body.early .pz-options.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pz-body.early .pz-options.n3 > :last-child { grid-column: auto; justify-self: stretch; width: auto; }
  .pz-body.early .replay { margin-top: 0; }
  .opt .face, .opt .line-art { max-width: 100%; } /* (a wide line drawing shrinks to its button) */
  .pz-body.early .opt .dots { font-size: .5em; }
  .pz-body.early .opt { min-height: clamp(80px, 23vw, 150px); }
  .pz-body.early .opt.pic .face { font-size: clamp(44px, 14vw, 80px); }
  .pz-body.early .pz-visual .ic { font-size: clamp(22px, 7vw, 40px); }
  .pz-prompt .letter, .pz-prompt > .numeral { font-size: clamp(56px, 20vw, 110px); }
  .pz-prompt .die { font-size: clamp(64px, 22vw, 120px); }
  .tenframe i { width: clamp(30px, 9vw, 52px); height: clamp(30px, 9vw, 52px); }
  .pz-prompt svg.shape { width: clamp(80px, 26vw, 140px); height: clamp(80px, 26vw, 140px); }
  .pz-prompt .swatch.big { width: clamp(72px, 22vw, 120px); height: clamp(72px, 22vw, 120px); }
  /* Sort It: four cards on a row */
  .so-tray { gap: 8px; }
  .so-card { width: clamp(62px, 17.5vw, 90px); height: clamp(68px, 19vw, 98px); }
  /* Paint Mixer: the paints on one shelf across the top, the bucket below them to pour into, and
     Empty bucket beside it */
  .t-mix { display: grid; grid-template-columns: auto auto; grid-template-areas: "top top" "shelf shelf" "bucket actions"; align-items: center; justify-content: center; column-gap: 14px; }
  .t-mix .mx-stage { display: contents; }
  .t-mix .mx-top { grid-area: top; gap: 6px 10px; }
  .t-mix .mx-shelf { grid-area: shelf; justify-self: center; grid-template-columns: none; grid-auto-flow: column; gap: 6px; padding: 8px 8px 6px; }
  .t-mix .mx-bucket { grid-area: bucket; justify-self: end; }
  .t-mix .mx-actions { grid-area: actions; justify-self: start; }
  .mx-target { gap: 8px; padding: 6px 14px 6px 8px; }
  .mx-pot .jar { width: clamp(44px, 12vw, 70px); height: clamp(48px, 13vw, 76px); }
  .mx-pot .lbl { font-size: clamp(11px, 3.4vw, 15px); }
  .mx-bucket { width: clamp(110px, 34vw, 200px); height: clamp(120px, 38vw, 220px); }
  .mx-target .blob { width: clamp(38px, 11vw, 60px); height: clamp(38px, 11vw, 60px); }
  .mx-recipe .drop { width: 30px; height: 30px; }
}

/* A ten-rod always shows ten blocks, however tall the screen makes it (the small-screen rules
   above give rods fixed-size stripes, which only count to ten at one height). */
.t-build .bb-tens .rod, .pz-visual.rods .rod { background: linear-gradient(#5aa0ff 0 84%, #2f6fd0 84% 100%); background-size: 100% 10%; }
