/* ============================ THE MISSION'S WHOLE-SCREEN STATES ============================
   The success board (the win header replacing the mission header in place),
   the mission menu's rows, and the corner buttons and sound panel. Home's
   styles are css/home.css; the public site's, css/site.css.

   ORDER MATTERS. This is file 4 of 10 and the cascade is the order
   pages/app.html links them in:
     base.css · layout.css · board.css · screens.css · home.css · editor.css · helper.css · panels.css · drill.css · class.css
   Later files override earlier ones on purpose. Moving a rule between files
   without keeping that order is how a Chinese override or a `won` state
   quietly stops applying. */

/* ============================ THE SUCCESS BOARD ============================
   Winning does not open a card over the map — the map becomes the card. The
   ground lights up in rings from where BOLTZ stopped, the briefing header
   crossfades into a success header, and the action bar rises underneath. */
#winhead,#winbar{display:none}
/* the board steps back a little to make room for the bar — part of the
   settling, and it keeps the whole success screen on a 760px-tall laptop */
/* The board settles back and lifts, and the action bar floats over the foot
   of the map. The bar must NOT be a flex item: the grid is a fixed pixel size
   and will not shrink, so a third row in the column overflows a short laptop
   screen. Overlaying it keeps the whole success screen on one screen. */
#world.won #mapwrap{padding-bottom:172px}
#world.won #camera{transform:scale(.86)}
/* help is not on offer on the success board, and the sprite sat over the
   menu button at narrow widths */
body.winning #helper{opacity:0;pointer-events:none;transition:opacity .3s}
#world.won #task{display:none}
#world.won #winhead{display:block;flex:0 0 auto;z-index:6;width:min(700px,92%);text-align:center;
  animation:winup .5s cubic-bezier(.2,.9,.3,1) both}
#winhead .lbl{font:600 13px/1 var(--sans);color:var(--go-deep)}
#winhead h2{font:800 clamp(19px,2.1vw,26px)/1.2 var(--sans);margin:8px 0 0;letter-spacing:-.025em}
#winhead p{margin:9px auto 0;max-width:560px;font:400 12.5px/1.55 var(--sans);color:var(--ink2);
  text-wrap:pretty}
#winhead p b{color:var(--ink)}
@keyframes winup{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}

/* The centering translate is a BASE property, and the rise animates `bottom`.
   Putting the centering in the keyframes made the final position depend on
   the animation actually running — which it does not under
   prefers-reduced-motion, and did not in a backgrounded tab. */
#world.won #winbar{display:block;position:absolute;z-index:8;left:50%;bottom:18px;
  transform:translateX(-50%);
  width:min(700px,94%);padding:15px 17px 14px;
  background:var(--card);border:1.5px solid var(--line);border-radius:18px;
  box-shadow:0 26px 46px -22px rgba(90,60,45,.5);
  animation:winrise .5s .12s cubic-bezier(.2,.9,.3,1) both}
@keyframes winrise{from{opacity:0;bottom:-10px}to{opacity:1;bottom:18px}}
.wbcols{display:flex;gap:16px;align-items:flex-start}
.wbcell{flex:1;min-width:0;text-align:left}
.wbcell .k{font:600 12px/1 var(--sans);color:var(--ink3)}
#wbLesson{margin:8px 0 0;font:600 12.5px/1.5 var(--sans);color:var(--ink);text-wrap:pretty}
.wbacts{display:flex;align-items:center;gap:9px;margin-top:14px}
#winbar .go{flex:1;padding:14px 20px;border-radius:12px;background:var(--terracotta);color:#fff;
  font:800 14px/1 var(--sans);box-shadow:0 5px 0 var(--terra-deep);transition:.12s}
#winbar .go:hover{background:#e8734a}
#winbar .go:active{transform:translateY(3px);box-shadow:0 2px 0 var(--terra-deep)}
.ghost2{padding:13px 15px;border-radius:12px;border:1.5px solid var(--line);background:var(--card);
  font:700 11.5px/1 var(--sans);color:var(--ink2);transition:.14s}
.ghost2:hover{color:var(--ink);border-color:#c8cdd6;background:var(--well)}
.ghost2[hidden]{display:none}
#winbar .unlockrow{margin-top:12px}

/* the ground celebrates, ring by ring out from the rover. The LIT state is a
   plain rule; the animation only supplies the ripple on the way there. */
/* :not(.rock) for the same reason as .grid.sand below — a boulder must not
   light up with the ground it blocked. */
.grid.won .tile:not(.rock){background-color:var(--regolith-lit);
  animation:tilewin .9s var(--d,0s) ease-out backwards}
@keyframes tilewin{
  0%{background-color:hsl(calc(26deg + var(--j,0) * 2deg)
                          calc(54% + var(--j,0) * 4%)
                          calc(87% + var(--j,0) * 1.9%));transform:scale(1)}
  35%{background-color:var(--regolith-lit);transform:scale(1.07)}
  100%{background-color:var(--regolith-lit);transform:scale(1)}}
.grid.won{animation:gridwin 1.1s ease-out}
@keyframes gridwin{0%{filter:drop-shadow(0 24px 40px rgba(90,60,45,.18))}
  40%{filter:drop-shadow(0 24px 44px rgba(31,157,87,.35))}
  100%{filter:drop-shadow(0 24px 40px rgba(90,60,45,.18))}}
@media(prefers-reduced-motion:reduce){.grid.won .tile,#world.won #winbar,#world.won #winhead{animation:none}}
/* Stacked layout (the dock moves under the map): #world is only half the
   screen, so an overlaid bar would sit on top of the board. Put it back in
   flow and let the column scroll instead. */
@media(max-width:860px){
  .wbcols{flex-direction:column;gap:10px}
  #world.won{overflow-y:auto}
  #world.won #mapwrap{padding-bottom:0;flex:0 0 auto}
  #world.won #camera{transform:scale(.8)}
  #world.won #winbar{position:static;transform:none;bottom:auto;margin:12px auto 2px;
    width:min(700px,96%);animation:winup .5s .12s cubic-bezier(.2,.9,.3,1) both}
}


/* ---------- the unlock chip, shown on the success board ---------- */
.unlockrow[hidden]{display:none}   /* author display beats the UA [hidden] rule */
.unlockrow{margin-top:18px;display:inline-flex;align-items:center;gap:10px;padding:11px 16px;border-radius:12px;
  background:var(--terra-tint);border:1px solid rgba(224,102,58,.3)}
.unlockrow i{display:grid;color:var(--terra-deep)}
.unlockrow i svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.unlockrow span{font:600 12px/1 var(--sans);color:var(--terra-deep)}
.unlockrow code{font:600 12px/1 var(--mono);color:var(--ink)}
/* ---------- top-right utilities: language, then sound ---------- */
.topright{position:fixed;right:14px;top:12px;z-index:45;display:flex;align-items:center;gap:6px}
/* Missions (top-left), language and sound (top-right) are the mission screen's own
   chips — the same as Commands / Keys / Clear (.ibtn): one height, one corner, one
   border, so every button on this screen is of one family. */
#btnMenu,#langBtn,#audioBtn{height:30px;border-radius:9px;background:var(--card);
  border:1.5px solid var(--line);font:700 12px/1 var(--sans);color:var(--ink2);
  display:flex;align-items:center;justify-content:center;transition:color .15s,border-color .15s}
#btnMenu:hover,#langBtn:hover,#audioBtn:hover{color:var(--ink);border-color:#c8cdd6}
#audioBtn{width:34px;font-size:14px;line-height:1}
/* The toggle shows the language you would switch TO, which is how every
   bilingual site a Malaysian child already uses labels it. */
#langBtn{min-width:34px;padding:0 9px}

#sndPanel{position:fixed;right:16px;top:52px;z-index:45;width:230px;padding:14px 15px 15px;
  background:var(--card);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 20px 44px -18px rgba(90,60,45,.42);
  display:none;flex-direction:column;gap:11px}
#sndPanel.on{display:flex}
#sndPanel[data-off="1"] .sndrow:not(.sndtog){opacity:.35;pointer-events:none}
.sndhead{display:flex;align-items:center;justify-content:space-between}
.sndhead b{font:700 12px/1 var(--sans)}
#sndClose,#keysClose,#cmdsClose{font:600 10px/1 var(--sans);color:var(--ink3);padding:4px 7px;border-radius:7px}
#sndClose:hover,#keysClose:hover,#cmdsClose:hover{background:var(--well);color:var(--ink)}
.sndrow{display:flex;flex-direction:column;gap:6px;font:600 11px/1 var(--sans);color:var(--ink2)}
.sndrow.sndtog{flex-direction:row;align-items:center;justify-content:space-between;
  padding-bottom:11px;border-bottom:1px solid var(--line)}
.sndrow input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:5px;
  border-radius:4px;background:var(--well);outline:none}
.sndrow input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:15px;height:15px;
  border-radius:50%;background:var(--terracotta);cursor:pointer;border:2px solid var(--card);
  box-shadow:0 1px 4px rgba(90,60,45,.4)}
.sndrow input[type=checkbox]{width:16px;height:16px;accent-color:var(--terracotta);cursor:pointer}
@media(max-width:1080px){#dock{width:320px}:root{--tile:60px}}
#worldHome{display:none}
/* ---------- stacked: tablet in portrait, and phones ----------
   The board above, the code below. The board gets the larger share; the dock's
   logo would sit in the middle of the screen, so a small home button takes its
   place beside Missions; BOLTZ's helper waits at the board's bottom corner,
   clear of RUN and STOP. */
@media(max-width:860px){
  #stage{flex-direction:column-reverse}
  #dock{width:100%;height:42%;border-right:0;border-top:1px solid var(--line);gap:10px;padding:12px 14px}
  #dock .dhead{display:none}
  #given{max-height:40%}
  #world{padding-top:54px}
  #worldHome{position:absolute;left:14px;top:12px;z-index:45;display:grid;place-items:center;width:30px;height:30px;
    border-radius:9px;background:var(--card);border:1.5px solid var(--line)}
  #worldHome img{display:block}
  #world #btnMenu{left:52px}   /* editor.css places it; this beats it */
  /* Keys and Commands open over the code, which is short here: they scroll within the dock */
  .dockpop{max-height:calc(42vh - 64px);overflow:auto}
  #cmdsList{max-height:none;overflow:visible}
}
.tmore{display:none}
/* ---------- phones ----------
   The story folds to two lines behind "Read more": the title and the mission
   line are what a child needs first, and the board needs the height. */
@media(max-width:600px){
  /* The board is what a phone has least room for, so the header gives way: the
     mission number lives in the picker, the story waits behind a link, and what
     BOLTZ says moves under the board — where the eye already is during a run.
     #task stops being a box (display:contents) so its parts can be ordered. */
  #world{padding:50px 12px 10px;gap:6px}
  #task{display:contents}
  #task .lbl{display:none}
  #task h2{order:1;font-size:19px;margin:0}
  #brief{order:2;font-size:13px;padding:7px 12px;margin:2px auto 0}
  .tmore{order:3;display:inline-block;padding:3px 6px;font:600 12.5px/1 var(--sans);color:var(--terra-deep)}
  #task .sub{order:4;display:none;font-size:12.5px;margin:0 auto}
  #task .sub.open{display:block}
  #mapwrap{order:5}
  #bubble{order:6;margin:0 auto;padding:10px 14px 9px}
  #dock{padding:10px 12px;gap:8px}
}
/* ---------- upright tablet: the board takes the larger share ----------
   Between a phone and a laptop the code needs about eight lines, no more; the
   rest of the height is worth more to the board, which is the thing being read. */
@media(min-width:601px) and (max-width:860px){
  #dock{height:36%}
  .dockpop{max-height:calc(36vh - 64px)}
  #mapwrap{padding-right:74px}   /* BOLTZ waits in that corner, off the board */
}
#sheetGrip{display:none}
/* ---------- phone, upright: the code is a sheet (src/mission/sheet.js) ----------
   Down, it holds a few lines and RUN over the bottom of the screen; up, it has
   room to type and covers most of the board. It overlays — the board never
   re-lays itself as the sheet moves — and the world keeps the down height free
   so the board fits above it. */
@media(max-width:600px) and (orientation:portrait){
  #dock{position:fixed;left:0;right:0;bottom:0;z-index:30;height:44dvh;padding-top:4px;
    border-radius:18px 18px 0 0;border-top:0;box-shadow:0 -14px 36px -18px rgba(60,40,30,.5);transition:height .28s cubic-bezier(.2,.8,.2,1)}
  #dock.open{height:84dvh}
  #dock.drag{transition:none}
  #world{padding-bottom:calc(44dvh + 8px)}
  #sheetGrip{display:block;flex:0 0 auto;align-self:center;width:64px;height:20px;padding:0;background:none;touch-action:none;cursor:grab}
  #sheetGrip::before{content:"";display:block;width:40px;height:5px;margin:0 auto;border-radius:99px;background:#d3d8e0}
  .dockpop{max-height:calc(100% - 96px)}
}
/* ---------- phone, sideways: code beside the board, like the desktop ----------
   Too short to stack. The header keeps the title, the mission line and a
   folded story; the helper takes the board's corner. */
@media(max-height:500px) and (orientation:landscape){
  /* Too short to stack: code beside the board. The header is ordered the way the
     phone's is — title, the one line to act on, the story behind a link — and what
     BOLTZ says sits under the board, out of the way of its height. */
  #stage{flex-direction:row}
  #dock{width:300px;height:auto;border-top:0;border-right:1px solid var(--line);padding:10px 12px;gap:8px}
  #world{padding:46px 12px 8px;gap:4px}
  #task{display:contents}
  #task .lbl{display:none}
  #task h2{order:1;font-size:17px;margin:0}
  #brief{order:2;margin:2px auto 0;padding:6px 12px;font-size:12.5px}
  .tmore{order:3;display:inline-block;padding:3px 6px;font:600 12px/1 var(--sans);color:var(--terra-deep)}
  #task .sub{order:4;display:none;font-size:12px;margin:0 auto}
  #task .sub.open{display:block}
  #mapwrap{order:5;padding-right:56px}   /* the helper waits in this corner */
  #bubble{order:6;margin:0 auto;padding:8px 13px 7px}
  .dockpop{max-height:calc(100vh - 70px)}
}

.ibtn{height:26px;padding:0 9px;border-radius:8px;border:1.5px solid var(--line);
  background:var(--card);color:var(--ink2);font:700 12px/1 var(--sans);cursor:pointer;
  display:inline-flex;align-items:center;gap:5px;letter-spacing:.01em}
.ibtn i{font-style:normal;font-size:14px;line-height:1;color:var(--ink3)}
.panebtns{gap:6px}
.panebtns .ibtn{height:30px;padding:0 10px;border-radius:9px}
.ibtn:hover:not(:disabled){color:var(--ink);border-color:#c8cdd6}
.ibtn:disabled{opacity:.3;cursor:default}
/* Clear is the one button here that throws work away, so it stays as quiet as
   its neighbour until the pointer is on it. Tinted red all the time, it was the
   loudest thing above the code — and the last control a child should reach for. */
.clearbtn:not(:disabled):hover{color:var(--terra-deep);border-color:var(--terracotta);background:var(--terra-tint)}
.clearbtn:not(:disabled):hover i{color:inherit}
