/* Typography lives in assets/fonts/fonts.css, which is generated and linked
   from index.html before this file. 'PB Rounded' is Nunito (UI) and
   'PB Display' is Fredoka (logo); both fall through to ui-rounded and then the
   system face if the files are missing. */

:root{
  --bg:#e6dcc4;
  --slot:#dbd0b6;
  --ink:#5b4a33;
  --chip:#fdf6e6;
  --stroke:#4a3b2a;
  --shade:#c9bd9f;
  /* Secondary buttons sitting ON a card need their own tone: --chip is the
     card's own colour, so a --chip button on a card shows nothing but its
     shadow, which reads as a stray line under floating text. */
  --btn2:#ece0c4;
  --btn2-shade:#c9ba95;
  /* Secondary action colours: orange = try again, blue = go elsewhere.
     Red is deliberately unused here — it reads as destructive. */
  --orange:#e8843e;
  --orange-d:#bd6529;
  --blue:#4a9bd4;
  --blue-d:#3579aa;
  --green:#7cb342;
  --green-d:#5d8a2f;
  --gold:#f2b134;
  --red:#d9503a;
  --red-d:#a63626;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  /* NB: "Segoe UI Variable" is deliberately NOT listed. Windows 11 resolves it
     to a lighter, more condensed face than plain Segoe UI, which reads badly at
     the heavy weights this UI uses. */
  font-family:'PB Rounded',ui-rounded,system-ui,-apple-system,"Segoe UI",Roboto,
              "Helvetica Neue",Arial,sans-serif;
  font-weight:800;
  overflow:hidden;touch-action:none;user-select:none;
}
button{font:inherit;color:inherit;cursor:pointer}
/* Author `display` rules beat the UA stylesheet's [hidden]{display:none}, so
   any element given a display below would ignore its hidden attribute. */
[hidden]{display:none!important}

/* ---------------------------------------------------------- icons */
#sprite{position:absolute;width:0;height:0;overflow:hidden}
.ic{width:22px;height:22px;display:block;flex:none;color:inherit}
.ic-sm{width:17px;height:17px}
.ic-lg{width:26px;height:26px}
.ic-coin{color:var(--gold)}

/* Menu footer: icon plus label, so neither has to carry the meaning alone. */
.pillbtn{
  border:0;border-radius:14px;background:var(--chip);box-shadow:0 4px 0 var(--shade);
  padding:10px 12px;display:flex;align-items:center;justify-content:center;gap:8px;
  font-size:14px;transition:transform .08s,box-shadow .08s;min-height:46px;
}
.pillbtn:active{transform:translateY(3px);box-shadow:0 1px 0 var(--shade)}
.pillbtn .ic{width:21px;height:21px}
.pillbtn.off{opacity:.55}

/* Corner close on every dialog — replaces the old text buttons. */
.cardclose{
  position:absolute;top:-12px;right:-12px;width:38px;height:38px;
  border:0;border-radius:50%;background:var(--red);color:#fff;
  box-shadow:0 3px 0 var(--red-d);display:grid;place-items:center;z-index:2;
  transition:transform .08s,box-shadow .08s;
}
.cardclose:active{transform:translateY(2px);box-shadow:0 1px 0 var(--red-d)}
.cardclose .ic{width:18px;height:18px}

/* ---------------------------------------------------------- screens

   Screens are driven by the Web Animations API in main.js, not by keyframes
   here: the slide direction has to flip in RTL, and computing the sign in JS
   beats maintaining four mirrored keyframe sets. All this rule does is keep the
   outgoing screen painted while it slides away. */
.screen{position:fixed;inset:0;display:none;flex-direction:column;align-items:center}
.screen.show{display:flex}
/* Still visible, but must not swallow taps meant for the screen arriving. */
.screen.leaving{display:flex;pointer-events:none}

.topbar{
  width:100%;max-width:520px;padding:16px 14px 0;
  display:grid;grid-template-columns:56px 1fr 56px;align-items:start;gap:8px;flex:none;
}
.iconbtn{
  width:56px;height:52px;border:0;border-radius:14px;background:var(--chip);
  box-shadow:0 4px 0 var(--shade);font-size:24px;display:grid;place-items:center;
  transition:transform .08s,box-shadow .08s;
}
.iconbtn:active{transform:translateY(3px);box-shadow:0 1px 0 var(--shade)}
.title{text-align:center}
.title .lvl{font-size:16px;letter-spacing:.14em;opacity:.75;padding-top:6px}
.timer{
  margin-top:8px;display:inline-block;min-width:126px;padding:8px 20px;
  background:var(--chip);border-radius:14px;box-shadow:0 4px 0 var(--shade);font-size:21px;
}
.timer.low{color:var(--red);animation:pulse .6s ease-in-out infinite}
@keyframes pulse{50%{transform:scale(1.06)}}


/* ---------------------------------------------------------- buttons */
.btn{
  border:0;border-radius:14px;padding:12px 22px;font-size:16px;
  background:var(--chip);box-shadow:0 4px 0 var(--shade);
  transition:transform .08s,box-shadow .08s;
}
.btn:active{transform:translateY(3px);box-shadow:0 1px 0 var(--shade)}
.btn.primary{background:var(--green);color:#fff;box-shadow:0 4px 0 var(--green-d)}
.btn.primary:active{box-shadow:0 1px 0 var(--green-d)}
.btn.big{width:100%;padding:15px;font-size:18px}
.btn.small{padding:8px 14px;font-size:13px}
/* NB: not ".ghost" — that class is the piece landing preview, which is
   display:none by default and would hide these buttons entirely. */
.btn.quiet{background:transparent;box-shadow:none;opacity:.6}
.btn.quiet:active{transform:none}
.btn:disabled{opacity:.4;pointer-events:none}
.btn.reward-btn{background:var(--gold);color:#4a3b2a;box-shadow:0 4px 0 #c98f22}
.btn.reward-btn:active{box-shadow:0 1px 0 #c98f22}
.btn.retry{background:var(--orange);color:#fff;box-shadow:0 4px 0 var(--orange-d)}
.btn.retry:active{box-shadow:0 1px 0 var(--orange-d)}
.btn.nav{background:var(--blue);color:#fff;box-shadow:0 4px 0 var(--blue-d)}
.btn.nav:active{box-shadow:0 1px 0 var(--blue-d)}
.row{display:flex;gap:10px;margin-top:10px}
.row .btn{flex:1}
.btn .ic{display:inline-block;vertical-align:-3px;margin-right:6px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:2px}
.ad{display:inline-grid;place-items:center}

/* ------------------------------------------------------------- menu */
.menu-wrap{margin:auto;width:min(340px,86vw);text-align:center;padding-bottom:8vh}
.logo,.loader-logo{
  font-family:'PB Display','PB Rounded',ui-rounded,system-ui,sans-serif;
  font-size:42px;font-weight:700;margin:0 0 4px;line-height:1.05;letter-spacing:0;
}
.logo span,.loader-logo span{color:var(--green)}

/* Startup loading screen: covers everything until the first chapters are in,
   then fades. Painted from plain HTML + this stylesheet, before any script. */
#loader{
  position:fixed;inset:0;z-index:400;display:grid;place-items:center;
  background:var(--bg);padding-inline:16px;
  transition:opacity .35s ease, visibility 0s linear .35s;
}
#loader.done{opacity:0;visibility:hidden}
.loader-inner{width:min(300px,78vw);text-align:center}
.loadbar{
  height:14px;margin:22px 0 10px;border-radius:99px;overflow:hidden;
  background:var(--slot);box-shadow:inset 0 2px 0 rgba(0,0,0,.06);
}
.loadbar i{
  display:block;width:100%;height:100%;border-radius:99px;background:var(--green);
  transform:scaleX(0);transform-origin:left center;transition:transform .2s ease-out;
}
#loadPct{font-size:14px;opacity:.6}
@media (prefers-reduced-motion: reduce){
  #loader,.loadbar i{transition:none}
}
.tagline{margin:0 0 26px;font-weight:700;opacity:.6;font-size:14px}
.menu-stats{display:flex;gap:10px;margin-bottom:24px}
.menu-stats>div{
  flex:1;background:var(--chip);border-radius:16px;box-shadow:0 4px 0 var(--shade);padding:12px 4px;
}
/* Icon and value share a row; the label sits under them. .ic is display:block,
   so the row needs an explicit flex or the icon drops onto its own line. */
.statline{display:flex;align-items:center;justify-content:center;gap:5px}
.menu-stats b{font-size:22px;line-height:1.1}
.menu-stats span{font-size:11px;opacity:.6;letter-spacing:.06em}
.menu-stats .statline{opacity:1}
.ic-star{color:var(--gold)}
.ic-level{color:var(--green)}
.menu-wrap .btn{width:100%;margin-bottom:10px}
.menu-foot{display:flex;gap:10px;margin-top:14px;justify-content:center}
.menu-foot .pillbtn{margin:0}

/* -------------------------------------------------------- level map */
.map-list{
  width:100%;max-width:520px;flex:1;overflow-y:auto;padding:14px 14px 40px;
  -webkit-overflow-scrolling:touch;touch-action:pan-y;
  /* The platform scrollbar is a wide grey slab that does not belong in a game.
     `stable` reserves its gutter either way so the grid does not jump when the
     list becomes scrollable. */
  scrollbar-width:thin;
  scrollbar-color:var(--shade) transparent;
  scrollbar-gutter:stable;
}
.map-list::-webkit-scrollbar{width:7px}
.map-list::-webkit-scrollbar-track{background:transparent}
.map-list::-webkit-scrollbar-thumb{background:var(--shade);border-radius:99px}
.map-list::-webkit-scrollbar-thumb:hover{background:#b3a382}
/* Same treatment for the language grid. */
.lang-grid{scrollbar-width:thin;scrollbar-color:var(--btn2-shade) transparent}
.lang-grid::-webkit-scrollbar{width:7px}
.lang-grid::-webkit-scrollbar-track{background:transparent}
.lang-grid::-webkit-scrollbar-thumb{background:var(--btn2-shade);border-radius:99px}
.chapter{margin-bottom:20px;animation:chapterIn .4s cubic-bezier(.2,.9,.25,1) both}
@keyframes chapterIn{from{opacity:0;transform:translateY(26px)}}
/* Chapter name centred and bold, with its star count underneath. */
.chapter h3{
  margin:4px 0 12px;font-size:16px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:2px;
}
/* .ic is display:block, so the count and its star need an explicit row or the
   icon drops to a second line. */
/* Star count as a small light pill with dark text — gold text straight on the
   beige page was too faint to read. The star itself stays gold. */
.chapter h3 em{
  font-style:normal;font-size:13px;font-weight:800;letter-spacing:.02em;
  display:inline-flex;align-items:center;gap:4px;flex:none;
  color:#6e5010;background:#fff7e0;border-radius:99px;padding:3px 10px;
  box-shadow:0 2px 0 rgba(150,110,40,.22);
}
.chapter h3 em .ic{color:var(--gold);width:14px;height:14px}
.nodes{display:grid;grid-template-columns:repeat(5,1fr);gap:9px}
.node{
  aspect-ratio:1;border:0;border-radius:14px;background:var(--chip);
  box-shadow:0 4px 0 var(--shade);display:grid;place-items:center;gap:1px;
  font-size:17px;position:relative;transition:transform .08s,box-shadow .08s;
  overflow:hidden;padding:0;
}
/* Each unlocked level previews its own picture, so the map reads as a gallery
   of what you have made rather than a grid of numbers. */
.node .thumb{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
}
/* Scrim under the label only — the picture stays readable at the top. */
.node.pic::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(to top,rgba(28,20,10,.62) 0%,rgba(28,20,10,.12) 52%,
                             rgba(28,20,10,0) 78%);
}
.node.pic .num,.node.pic .st{position:relative;z-index:1}
.node.pic .num{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.7)}
.node .num{align-self:end}
.node .st{align-self:start}
.node:active{transform:translateY(3px);box-shadow:0 1px 0 var(--shade)}
/* Locked levels are one shared grey tile with a question mark — the picture
   stays a surprise until the level is reached. */
.node.locked{
  background:linear-gradient(145deg,#d9d4cb 0%,#c5beb2 100%);
  box-shadow:0 4px 0 #a9a192;cursor:default;
}
.node.locked:active{transform:none;box-shadow:0 4px 0 #a9a192}
.node .mystery{
  font-family:'PB Display','PB Rounded',ui-rounded,system-ui,sans-serif;
  font-size:30px;font-weight:700;line-height:1;color:#fff;
  text-shadow:0 2px 0 rgba(90,80,66,.35);
}
.node.locked .thumb{filter:grayscale(1) contrast(.9);opacity:.42}
.node.locked::after{background:linear-gradient(to top,rgba(60,48,32,.22),rgba(60,48,32,.10))}
.node.locked .lockicon{
  position:relative;z-index:1;width:20px;height:20px;
  color:#584734;opacity:.85;filter:drop-shadow(0 1px 1px rgba(255,255,255,.5));
}
/* The next level to play keeps its picture but gains a green frame, so it
   still stands out now that every unlocked tile is an image. */
.node.current{
  background:var(--green);color:#fff;
  box-shadow:0 4px 0 var(--green-d), inset 0 0 0 3px var(--green);
}
.node .st{display:flex;gap:1px;height:11px;color:var(--gold)}
.node .st .ic{width:11px;height:11px}
.node.current .st{color:#fff}

/* ------------------------------------------------------------ board */
#stage{flex:1;width:100%;min-height:0;display:grid;place-items:center;padding:10px;overflow:hidden}
#board{position:relative}
#slots{position:absolute;inset:0;display:grid}
.slot{background:var(--slot);border-radius:8px}
#pieces{position:absolute;inset:0}

.piece{position:absolute;left:0;top:0;cursor:grab;will-change:transform}
.piece.drag{cursor:grabbing}
.piece.settling{transition:transform .17s cubic-bezier(.34,1.56,.64,1)}
.piece.locked{cursor:default}
.layer{position:absolute;left:0;top:0}
.layer.lip{filter:drop-shadow(0 5px 7px rgba(58,44,28,.38))}
.piece.drag .layer.lip{filter:drop-shadow(0 14px 16px rgba(58,44,28,.45))}
.cell{position:absolute}
.lip .cell,.stroke .cell{background:var(--stroke)}

/* Auto-Fixed pieces are pinned in place. Draining the colour says "this one is
   done, you can't move it" at a glance. The picture gets its colour back once
   it is complete — see .merged below. */
.piece.locked .layer.face{filter:grayscale(1) brightness(.97);transition:filter .3s ease}

/* landing preview */
.ghost{position:absolute;left:0;top:0;z-index:0;display:none}
.ghost.show{display:block}
.ghost .cell{background:rgba(255,252,242,.5);box-shadow:inset 0 0 0 2px rgba(74,59,42,.45)}
.ghost.bad .cell{background:rgba(192,73,47,.24);box-shadow:inset 0 0 0 2px rgba(192,73,47,.6)}


/* completion */
.piece.merged .layer.lip,.piece.merged .layer.stroke{opacity:0;transition:opacity .4s ease}
.piece.merged .cell{transition:border-radius .4s ease}
.piece.merged .layer.face{filter:none}
#frame{position:absolute;left:0;top:0;z-index:0;display:none}
#frame.show{display:block}
#frame .band{position:absolute;left:0;top:0;background:var(--stroke)}
#frame .band.lip{filter:drop-shadow(0 6px 9px rgba(58,44,28,.4))}

#shine{position:absolute;left:0;top:0;z-index:50;display:none;overflow:hidden;pointer-events:none}
#shine.play{display:block}
#shine .beam{
  position:absolute;top:-30%;height:160%;width:38%;transform:skewX(-18deg);
  background:linear-gradient(100deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.18) 28%,
    rgba(255,255,255,.85) 50%,rgba(255,255,255,.18) 72%,rgba(255,255,255,0) 100%);
  animation:sweep 1.05s cubic-bezier(.4,0,.3,1) .12s both;
}
@keyframes sweep{from{left:-50%}to{left:112%}}

#confetti{position:fixed;inset:0;z-index:100;pointer-events:none;display:none}
#confetti.play{display:block}

/* ------------------------------------------------------ booster bar */
#boosterBar{
  width:100%;max-width:520px;display:flex;gap:8px;padding:0 14px 16px;flex:none;
}
.booster{
  flex:1;border:0;border-radius:16px;background:var(--chip);box-shadow:0 4px 0 var(--shade);
  padding:9px 4px 8px;display:grid;justify-items:center;gap:1px;position:relative;
  transition:transform .08s,box-shadow .08s;
}
.booster:active{transform:translateY(3px);box-shadow:0 1px 0 var(--shade)}
.booster .ic-lg{margin-bottom:1px}
.booster b{font-size:12px}
.booster small{font-size:10px;opacity:.55;font-weight:700}
.booster .ad{
  position:absolute;top:-7px;right:-5px;width:24px;height:24px;border-radius:8px;
  background:var(--gold);color:#8a5f14;box-shadow:0 2px 0 #c98f22;margin:0;
}
.booster .ad .ic{width:14px;height:14px;margin:0}
.booster:disabled{opacity:.42;pointer-events:none}
.booster.cooling small{color:var(--red);opacity:.9}

/* Hint, after the popup closes: the button becomes the picture for the viewing
   window, and a 40% black shade sweeps over it from right to left as the time
   runs out — the picture visibly "fills up" dark. Tap to enlarge again. */
.booster .peekbar{display:none}
.booster.peeking{
  background:var(--peek-img) center/cover no-repeat;overflow:hidden;
  box-shadow:0 4px 0 var(--shade),inset 0 0 0 3px var(--gold);
}
.booster.peeking > :not(.peekbar){visibility:hidden}
.booster.peeking .peekbar{
  display:block;position:absolute;inset:0;
  background:rgba(0,0,0,.4);transform-origin:right center;
  transition:transform .5s linear;pointer-events:none;
}

/* `.booster` sets display:grid, which would beat the [hidden] attribute. */
.booster[hidden]{display:none}

/* Magnet waiting for a tap: the button stays lit rather than greyed out. */
.booster.armed{box-shadow:0 4px 0 var(--shade),inset 0 0 0 3px var(--gold)}
.booster.armed:disabled{opacity:1}
.booster.armed small{color:#a8741a;opacity:1}

/* ------------------------------------------------ landscape game screen */
/* Wider than tall: the power-ups leave the bottom of the screen, where they
   cost the board height it cannot spare, and stack in a column under the
   restart button, centred in the space below the top bar.

     [ back ]      LEVEL 7 · Moves 12      [ restart ]
                                            [ hint    ]
                    board                   [ +5      ]
                                            [ autofix ]

   The left column is kept as wide as the right one so the board stays centred.
   game.js sizes the board from #stage in this layout — keep its
   SIDE_LAYOUT media query identical to this one. */
@media (orientation: landscape){
  #gameScreen{
    --side:112px;
    grid-template-columns:var(--side) minmax(0,760px) var(--side);
    grid-template-rows:auto minmax(0,1fr);
    justify-content:center;align-items:stretch;
    padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);
  }
  #gameScreen.show,#gameScreen.leaving{display:grid}
  #gameScreen .topbar{grid-column:1 / -1;grid-row:1;max-width:none;align-items:center}
  /* Level and moves side by side: stacked, they cost the board ~30px of the
     height a landscape phone has least of. */
  #gameScreen .title{display:flex;align-items:center;justify-content:center;gap:12px}
  #gameScreen .title .lvl{padding-top:0}
  #gameScreen .timer{margin-top:0}
  #gameScreen #stage{grid-column:2;grid-row:2;height:100%}
  #boosterBar{
    grid-column:3;grid-row:2;align-self:center;justify-self:end;
    flex-direction:column;width:auto;max-width:none;gap:10px;padding:0 14px 8px 0;
  }
  .booster{flex:none;width:84px}
}
/* Landscape phones: every pixel of height goes to the board. */
@media (orientation: landscape) and (max-height: 500px){
  #gameScreen .topbar{padding-top:10px}
  #boosterBar{gap:8px}
  .booster{padding:7px 4px 6px}
}

/* Magnet armed: every piece it can take glows gold and pulses. */
#board.magnet-armed .piece:not(.locked){cursor:pointer}
#board.magnet-armed .piece:not(.locked) .layer.stroke .cell{background:var(--gold)}
#board.magnet-armed .piece:not(.locked) .layer.face{animation:magnetPulse .8s ease-in-out infinite}
@keyframes magnetPulse{50%{filter:brightness(1.18)}}
/* A piece pushed out of the way flashes, so the player sees it moved. */
.piece.bumped .layer.face{animation:bumped .35s ease-in-out 3}
@keyframes bumped{50%{filter:brightness(1.4)}}
/* Two pieces just joined into one: a quick glow says "that fits". */
.piece.joined .layer.face{animation:joined .45s ease-out}
@keyframes joined{35%{filter:brightness(1.35)}}

/* --------------------------------------------------------- dialogs */
/* Visibility rather than display, so the backdrop can fade both ways. The
   delayed `visibility` step keeps the panel interactive until the fade ends. */
.modal{
  position:fixed;inset:0;display:grid;place-items:center;padding:20px;
  background:rgba(60,48,32,.55);backdrop-filter:blur(3px);z-index:120;
  opacity:0;visibility:hidden;
  transition:opacity .2s ease, visibility 0s linear .2s;
}
.modal.show{opacity:1;visibility:visible;transition:opacity .2s ease}

/* Scoped to `.show`, not just `.modal`: the language sheet's card is always
   displayed (only its parent is hidden), so an unscoped rule would run this
   once at page load and never again. Gating on the parent class means the
   animation starts the moment a panel opens, every time. */
.modal.show .card{animation:cardIn .42s cubic-bezier(.2,.9,.25,1) both}
@keyframes cardIn{from{opacity:0;transform:translateY(70px) scale(.94)}}

/* Score rows arrive in sequence so the total reads as being tallied up. */
.modal.show .scoreboard div{animation:rowIn .3s ease both}
.modal.show .scoreboard div:nth-child(1){animation-delay:.10s}
.modal.show .scoreboard div:nth-child(2){animation-delay:.18s}
.modal.show .scoreboard div:nth-child(3){animation-delay:.26s}
.modal.show .scoreboard div:nth-child(4){animation-delay:.34s}
.modal.show .scoreboard div:nth-child(5){animation-delay:.42s}
@keyframes rowIn{from{opacity:0;transform:translateX(-10px)}}
.modal.show .reward{animation:rowIn .3s ease .5s both}
.card{
  position:relative;   /* anchors .cardclose */
  background:var(--chip);border-radius:24px;padding:26px 24px;text-align:center;
  box-shadow:0 10px 0 var(--shade);width:min(320px,88vw);
}
/* Stacked buttons need breathing room; without this their 4px bottom edges
   touch and the two options read as one control. */
.card > .btn + .btn{margin-top:12px}
.card h2{margin:0 0 6px;font-size:24px}
.card .sub{margin:0 0 18px;font-weight:700;opacity:.65;font-size:14px}
.card .btn{width:100%}
.card .row{margin-top:12px}
.card .row .btn{width:auto}

/* Plain buttons on a card get the darker surface, since --chip is the card's
   own colour and would make them invisible. Coloured variants keep theirs. */
.card .btn:not(.primary):not(.reward-btn):not(.quiet):not(.retry):not(.nav):not(.coin){
  background:var(--btn2);box-shadow:0 4px 0 var(--btn2-shade);
}
.card .btn:not(.primary):not(.reward-btn):not(.quiet):not(.retry):not(.nav):not(.coin):active{
  box-shadow:0 1px 0 var(--btn2-shade);
}
.card .row .btn{padding:13px 20px}

/* Hint popup: the finished picture, big and clear of the board. */
.card.peek-card{width:min(400px,92vw);padding:18px}
.peek-card h2{margin-bottom:12px}
.peek-card img{
  display:block;width:100%;aspect-ratio:1;object-fit:cover;
  border-radius:16px;box-shadow:0 4px 0 var(--shade);
}

/* Pay-with-coins alternative: solid enough to read as a real second option
   next to the gold ad button, without competing with it. */
/* The score table sits straight above Next Level now that the coin row is gone. */
.card .scoreboard + .btn{margin-top:16px}

.card .uses{margin:-12px 0 16px;font-size:12px;font-weight:800;opacity:.5}
.balance{
  display:flex;align-items:center;justify-content:center;gap:5px;
  margin:12px 0 2px;font-size:13px;font-weight:700;opacity:.6;
}
/* Cancel needs a real touch target, not just its text box. */
.btn.quiet{min-height:44px}
.bicon{display:flex;justify-content:center;margin-bottom:10px;color:var(--green)}
.bicon .ic{width:44px;height:44px}
.bicon.warn{color:var(--red)}

/* A back arrow names a real direction, so it mirrors in RTL. (The restart
   icon deliberately does not — counter-clockwise is counter-clockwise in
   every language, and flipping it would make the button lie.) */
[dir="rtl"] #btnPause .ic,
[dir="rtl"] #cardExit .bicon .ic{transform:scaleX(-1)}

.stars{display:flex;justify-content:center;gap:8px;margin-bottom:10px}
.stars i{
  display:block;color:var(--shade);
  transform:scale(.6);opacity:.35;transition:transform .3s cubic-bezier(.34,1.7,.6,1),opacity .3s;
}
.stars i .ic{width:38px;height:38px}
.stars i.on{color:var(--gold);transform:scale(1);opacity:1}

.scoreboard{margin:0 0 12px;font-size:13px;font-weight:700}
.scoreboard div{display:flex;justify-content:space-between;padding:3px 2px;opacity:.7}
.scoreboard div.total{
  opacity:1;font-size:17px;border-top:2px dashed var(--shade);margin-top:5px;padding-top:7px;
}
.scoreboard div.neg{color:var(--red)}
.reward{
  display:flex;align-items:center;justify-content:center;gap:6px;font-size:19px;margin-bottom:16px;
}

/* The Access Restricted panel's CSS lives in css/ads-panel.css — only the
   gate builds ship it. */

/* --------------------------------------------------- language picker */
.flagslot{display:grid;place-items:center;width:28px;height:19px}
.flag{width:28px;height:19px;border-radius:3px;display:block;
      box-shadow:0 0 0 1px rgba(74,59,42,.25)}

/* Narrower side padding than other cards: at the default 24px the grid's
   content box lands 3px short of fitting a third 96px track, dropping the
   whole picker to two columns. */
.lang-card{
  width:min(430px,94vw);max-height:88vh;display:flex;flex-direction:column;
  padding-left:14px;padding-right:14px;
}
.lang-card h2{font-size:20px;margin-bottom:14px}

.lang-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(86px,1fr));
  gap:8px;overflow-y:auto;margin-bottom:14px;
  /* Room for the selection tick, which overhangs each tile by 8px. Without
     the top and right padding the first row's tick is clipped by the
     scroll container. */
  padding:12px 12px 4px;
  touch-action:pan-y;min-height:0;
}
.lang-tile{
  border:2px solid transparent;   /* reserved so nothing shifts when selected */
  border-radius:14px;background:var(--btn2);box-shadow:0 3px 0 var(--btn2-shade);
  padding:8px 4px 7px;display:grid;justify-items:center;gap:5px;position:relative;
  min-height:64px;transition:transform .08s,box-shadow .08s;
}
.lang-tile:active{transform:translateY(2px);box-shadow:0 1px 0 var(--btn2-shade)}
/* Selection is marked three ways — colour alone is invisible to a colour-blind
   player, and here it must also read to someone who cannot read the label. */
.lang-tile.sel{
  border-color:var(--green);background:#e7f2d8;
  box-shadow:0 3px 0 var(--green-d);transform:translateY(-2px);
}
.lang-tile .tick{
  position:absolute;top:-8px;right:-8px;width:20px;height:20px;
  border-radius:50%;background:var(--green);color:#fff;
  box-shadow:0 0 0 2px var(--chip);display:none;place-items:center;z-index:1;
}
.lang-tile.sel .tick{display:grid}
.lang-tile .tick svg{width:11px;height:11px}
.lang-name{
  /* 600, not the UI's 800: at ~11px the counters in 中文, हिन्दी and ไทย fill in
     at heavy weights, and non-Latin fallbacks may be synthetically bolded. */
  font-weight:600;font-size:11px;line-height:1.3;text-align:center;
  word-break:normal;overflow-wrap:anywhere;
}

/* ----------------------------------------------------------- toast */
#toast{
  position:fixed;left:50%;bottom:14%;transform:translate(-50%,14px);
  background:var(--stroke);color:#f5f0e4;padding:11px 18px;border-radius:14px;
  font-size:14px;opacity:0;pointer-events:none;transition:opacity .22s,transform .22s;z-index:300;
}
#toast.show{opacity:1;transform:translate(-50%,0)}

@media (prefers-reduced-motion:reduce){
  #shine .beam{animation-duration:.01ms}
  .piece.settling{transition:none}
  .timer.low{animation:none}
  #board.magnet-armed .piece .layer.face,.piece.bumped .layer.face,.piece.joined .layer.face{animation:none}
  /* Screens and panels still change, they just stop moving. */
  .modal.show .card,.modal.show .scoreboard div,.chapter,
  .modal.show .reward{animation:none!important}
  .modal{transition:none}
}
