:root{
  --paper:#fbfbfa; --ink:#2b2b2b; --pencil:#5a6472;
  --blue:#196db4; --red:#ee4648;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;overflow:hidden;background:#e9e9e6;
  font-family:"Patrick Hand",system-ui,sans-serif;color:var(--ink);
  -webkit-font-smoothing:antialiased}
#app{display:flex;height:100%;width:100%;position:relative}
#worldwrap{flex:1;min-width:0;position:relative}
#world{position:absolute;inset:0;width:100%;height:100%;display:block;cursor:crosshair;background:var(--paper)}

/* ---- sidebar: a torn strip of paper taped to the edge ---- */
/* No rule and no drop shadow down the left: the ruled paper stops at the
   canvas edge, and that change of texture separates the two on its own. */
#side{
  width:262px;flex:0 0 262px;background:var(--paper);
  padding:14px 16px;display:flex;flex-direction:column;gap:12px;
  /* scrolls rather than clipping: on a short window something has to go, and
     quietly swallowing the save/load row is worse than a scrollbar */
  overflow-y:auto;overflow-x:hidden;
}
#side h1{font-family:"Rock Salt",cursive;font-size:23px;line-height:1.35;letter-spacing:1px;
  display:flex;align-items:baseline;justify-content:space-between;gap:8px}
#mute{font:inherit;font-family:"Patrick Hand",cursive;font-size:13px;letter-spacing:0;
  background:none;border:2px solid var(--ink);border-radius:10px 4px 12px 4px;
  padding:1px 8px;cursor:pointer;color:var(--pencil)}
#side h1::after{content:"";display:block;height:3px;margin-top:6px;
  background:var(--ink);border-radius:3px;
  clip-path:polygon(0 40%,12% 10%,28% 60%,45% 15%,63% 65%,80% 20%,100% 55%,100% 100%,0 100%)}

#minimap{width:230px;height:172px;border:2px solid var(--ink);border-radius:3px;
  background:#f4f4f2;display:block}

.readout .row{display:flex;justify-content:space-between;align-items:baseline;
  font-size:19px;line-height:1.5}
.readout .lab{font-size:14px;color:var(--pencil);text-transform:lowercase}
.powerbar{height:9px;border:2px solid var(--ink);border-radius:5px;overflow:hidden;margin-top:3px}
.powerbar i{display:block;height:100%;width:0;background:var(--blue);transition:width .3s}
.powerbar.low i{background:var(--red)}

.tabs{display:flex;gap:6px}
.tab{flex:1;font:inherit;font-size:16px;padding:5px 0;background:none;cursor:pointer;
  border:2px solid var(--ink);border-radius:14px 6px 16px 5px;color:var(--ink)}
.tab.on{background:var(--ink);color:var(--paper)}

/* The palette is the one part of the sidebar that gives: it takes whatever
   height is left over and scrolls inside it. Without `flex` and a floor it is
   just another auto-height block in a column that is over-subscribed, and the
   browser crushes it to a couple of clipped pixels — which is what happened
   when the pause row and the stance picker were added above it. The floor is
   two full rows of cards, so there is always something to click. */
#palette{display:grid;grid-template-columns:1fr 1fr;gap:8px;overflow-y:auto;padding-bottom:4px;
  flex:1 1 0;min-height:180px;align-content:start;
  /* Rows size to the card, never to the box. Implicit `auto` rows inside a
     grid whose own height is definite get stretched to fill it, so the moment
     the sidebar squeezed the palette every row shrank in step and the cards —
     which clip their overflow — showed as empty slivers with the icon cut off.
     Content-sized rows keep the card whole and let the palette scroll. */
  grid-auto-rows:max-content}
.card{
  position:relative;border:2px solid var(--ink);border-radius:12px 5px 14px 6px;
  background:#fff;padding:6px 6px 4px;cursor:pointer;text-align:center;overflow:hidden;
  transition:transform .08s;
}
.card:hover{transform:rotate(-1deg) scale(1.03)}
.card.locked{opacity:.32;cursor:not-allowed;filter:grayscale(1)}
.card.poor{opacity:.55}
.card .thumb{height:52px;display:flex;align-items:center;justify-content:center}
.card .thumb img{max-height:52px;max-width:100%}
.card .thumb svg{height:46px}
.card .nm{font-size:14px;line-height:1.15;margin-top:2px}
.card .cost{font-size:13px;color:var(--pencil)}
.card .fill{position:absolute;left:0;bottom:0;width:100%;background:rgba(25,109,180,.22);
  pointer-events:none;height:0}
.card.ready{outline:3px solid #3c9c4a;outline-offset:-3px}
.card.ready::after{content:"place it";position:absolute;inset:auto 0 0 0;
  background:#3c9c4a;color:#fff;font-size:13px;padding:1px}
.card .q{position:absolute;top:1px;right:5px;font-size:14px;color:var(--ink);
  font-weight:bold;text-shadow:0 0 3px #fff,0 0 3px #fff;pointer-events:none}

/* ---- the soundtrack player: a tape deck ruled in biro ---- */
#music{border-top:2px dashed rgba(90,100,114,.4);padding-top:8px;
  display:flex;flex-direction:column;gap:5px}
/* Collapsed by default -- the transport, the track list and the volume are all
   behind one header, because none of it is wanted until someone goes looking. */
#mtoggle{width:100%;display:flex;align-items:center;justify-content:space-between;
  gap:8px;text-align:left}
#mtoglabel{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
#mtoggle::after{content:"\25BE";font-size:10px;flex:0 0 auto;line-height:1}
#music.collapsed #mtoggle::after{content:"\25B8"}
#mbody{display:flex;flex-direction:column;gap:5px}
#music.collapsed #mbody{display:none}
.mrow{display:flex;gap:5px;align-items:center}
#music button{font:inherit;font-size:13px;background:none;color:var(--ink);cursor:pointer;
  border:2px solid var(--ink);border-radius:10px 4px 12px 4px;padding:1px 8px;line-height:1.4}
#music button:hover{background:var(--ink);color:var(--paper)}
#mplay{min-width:34px}
#mshuffle{margin-left:auto;font-size:12px}
#mshuffle.off{opacity:.45;text-decoration:line-through}
#mtitle{width:100%;text-align:left;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
  border-style:dashed !important;color:var(--pencil) !important}
#mtitle:hover{background:none !important;color:var(--ink) !important;border-style:solid !important}
#mtitle.on{color:var(--ink) !important;border-style:solid !important}
#mlist{display:flex;flex-direction:column;gap:3px;max-height:132px;overflow-y:auto;
  border:2px solid var(--ink);border-radius:12px 5px 14px 6px;padding:5px}
#mlist button{width:100%;text-align:left;border:none;border-radius:4px;padding:1px 5px;
  color:var(--pencil)}
#mlist button.on{color:var(--ink);font-weight:bold}
#mlist button.on::before{content:"\266a ";}
#mvol{width:100%;height:14px;-webkit-appearance:none;appearance:none;background:none;cursor:pointer}
#mvol::-webkit-slider-runnable-track{height:3px;background:var(--ink);border-radius:2px}
#mvol::-moz-range-track{height:3px;background:var(--ink);border-radius:2px}
#mvol::-webkit-slider-thumb{-webkit-appearance:none;width:13px;height:13px;margin-top:-5px;
  background:var(--paper);border:2px solid var(--ink);border-radius:50%}
#mvol::-moz-range-thumb{width:11px;height:11px;
  background:var(--paper);border:2px solid var(--ink);border-radius:50%}

#hint{margin-top:auto;font-size:13px;color:var(--pencil);line-height:1.55;
  border-top:2px dashed rgba(90,100,114,.4);padding-top:8px}
#savebtn,#loadbtn,#edge{font:inherit;font-size:13px;background:none;color:var(--ink);cursor:pointer;
  border:2px solid var(--ink);border-radius:10px 4px 12px 4px;padding:1px 9px;margin-bottom:6px}
#edge.off{opacity:.45;text-decoration:line-through}
#savebtn,#loadbtn{margin-left:6px}
#savebtn:hover,#loadbtn:hover{background:var(--ink);color:var(--paper)}

#banner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  pointer-events:none}
#banner span{font-family:"Rock Salt",cursive;font-size:min(9vw,96px);
  transform:rotate(-4deg);text-shadow:0 3px 0 rgba(0,0,0,.08)}
#banner.win span{color:var(--blue)} #banner.lose span{color:var(--red)}
/* "MISSION COMPLETE" is twice the width of "YOU WIN" — the campaign endings
   get their own size so the scrawl still fits between the margins. */
#banner.long span{font-size:min(5.4vw,60px)}
.hidden{display:none!important}

#toast{position:absolute;left:50%;bottom:38px;transform:translateX(-50%) rotate(-1deg);
  background:#fff;border:2px solid var(--ink);border-radius:14px 6px 16px 5px;
  padding:6px 16px;font-size:17px}

/* ---- title screen -------------------------------------------------------
   A full-bleed battle drawn behind the menu, with the menu itself sitting on a
   torn strip of paper taped down the left. Nothing is a panel: everything is
   either paper, tape or marker. */
#start{position:absolute;inset:0;z-index:20;overflow:hidden;background:var(--paper)}
#menuscene{position:absolute;inset:0;width:100%;height:100%;display:block}

#menu{position:relative;height:100%;width:min(430px,30vw);
  display:flex;flex-direction:column;justify-content:center;gap:22px;
  padding:36px clamp(20px,2.6vw,44px);
  background:linear-gradient(90deg,rgba(251,251,250,.97) 0%,rgba(251,251,250,.94) 74%,rgba(251,251,250,0) 100%)}
#menu::after{content:"";position:absolute;top:0;bottom:0;right:6px;width:3px;
  background:var(--ink);opacity:.16;
  clip-path:polygon(0 0,100% 2%,20% 9%,100% 17%,0 26%,100% 34%,10% 43%,100% 51%,0 60%,100% 68%,25% 77%,100% 85%,0 94%,100% 100%,0 100%,0 0)}

.brand .logo{font-family:"Rock Salt",cursive;font-size:clamp(38px,5vw,64px);line-height:1;
  letter-spacing:3px;transform:rotate(-1.6deg);text-shadow:4px 5px 0 rgba(43,43,43,.09)}
.brand .logo::after{content:"";display:block;height:6px;margin:12px 0 0;
  background:linear-gradient(90deg,var(--blue) 0 46%,var(--red) 46% 100%);border-radius:5px;
  clip-path:polygon(0 42%,9% 4%,22% 66%,35% 8%,49% 70%,62% 12%,76% 62%,88% 6%,100% 52%,100% 100%,0 100%)}
.brand .tag{margin-top:12px;font-size:clamp(16px,1.5vw,20px);color:var(--pencil);transform:rotate(-.5deg)}

#menubtns{display:flex;flex-direction:column;gap:11px}
#menubtns button{
  font:inherit;text-align:left;cursor:pointer;position:relative;
  background:#fff;color:var(--ink);border:2.5px solid var(--ink);
  border-radius:20px 7px 22px 8px;padding:9px 18px;
  box-shadow:3px 4px 0 rgba(43,43,43,.13);
  transition:transform .09s ease,box-shadow .09s ease,background .12s;
}
#menubtns button b{display:block;font-size:clamp(19px,1.7vw,24px);font-weight:normal;line-height:1.15}
#menubtns button small{display:block;font-size:14px;color:var(--pencil);margin-top:1px}
#menubtns button:nth-child(odd){transform:rotate(-.7deg)}
#menubtns button:nth-child(even){transform:rotate(.6deg)}
#menubtns button:hover{background:var(--ink);color:var(--paper);
  transform:rotate(0deg) translate(-2px,-2px);box-shadow:6px 7px 0 rgba(43,43,43,.18)}
#menubtns button:hover small{color:rgba(251,251,250,.72)}
#menubtns button:active{transform:rotate(0deg) translate(1px,2px);box-shadow:1px 1px 0 rgba(43,43,43,.2)}
#menubtns button[data-act="new"]{border-color:var(--blue)}
#menubtns button[data-act="new"]:hover{background:var(--blue);border-color:var(--blue)}
#menubtns button.dim{opacity:.42}

.sheet{background:#fff;border:2.5px solid var(--ink);border-radius:18px 7px 20px 8px;
  padding:14px 20px 16px;transform:rotate(-.4deg);box-shadow:3px 4px 0 rgba(43,43,43,.12);
  max-height:34vh;overflow-y:auto}
.sheet h3{font-family:"Rock Salt",cursive;font-size:15px;font-weight:normal;margin-bottom:8px}
.sheet ul{margin:0 0 0 17px;font-size:16px;line-height:1.6}
#menu .foot{color:var(--pencil);font-size:13px}

/* ---- save slots ---------------------------------------------------------- */
#slotmodal{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(240,240,238,.84);z-index:40}
#slotmodal .card{background:var(--paper);border:3px solid var(--ink);
  border-radius:20px 8px 22px 9px;padding:18px 22px;min-width:360px;
  transform:rotate(-.6deg);box-shadow:5px 7px 0 rgba(43,43,43,.12);cursor:default}
#slotmodal .card:hover{transform:rotate(-.6deg)}
#slotmodal h3{font-family:"Rock Salt",cursive;font-size:16px;font-weight:normal}
#slotmodal small{display:block;margin-top:12px;color:var(--pencil);font-size:13px}
.slot{display:flex;align-items:center;gap:12px;font-size:17px;padding:7px 11px;margin-bottom:7px;
  cursor:pointer;border:2px solid rgba(43,43,43,.35);border-radius:13px 5px 15px 5px}
.slot:hover{border-color:var(--ink);background:rgba(43,43,43,.05)}
.slot.empty{opacity:.55;font-style:italic}
.slot .n{font-family:"Rock Salt",cursive;font-size:13px;min-width:26px}
.slot .meta{margin-left:auto;text-align:right;font-size:13px;color:var(--pencil);line-height:1.25}
.slot .kill{font:inherit;font-size:13px;background:none;border:2px solid rgba(43,43,43,.4);
  border-radius:9px 4px 10px 4px;padding:0 7px;cursor:pointer;color:var(--pencil)}
.slot .kill:hover{background:var(--red);border-color:var(--red);color:#fff}
.slot.disabled{opacity:.35;cursor:not-allowed}

/* ---- sell / repair ---- */
#actions{display:flex;gap:8px;flex:0 0 auto}
#actions button{flex:1;font:inherit;font-size:16px;padding:4px 0;cursor:pointer;
  background:none;color:var(--ink);border:2px solid var(--ink);
  border-radius:13px 5px 15px 5px}
#actions button:hover{background:rgba(43,43,43,.08)}
#actions #repair.on{background:#3c9c4a;border-color:#3c9c4a;color:#fff}
#actions #sell.on{background:var(--red);border-color:var(--red);color:#fff}
#actions #deploy{background:var(--blue);border-color:var(--blue);color:#fff}

/* pause + main menu, sitting under the title with the rest of the chrome */
#gamectl{display:flex;gap:8px;margin:-4px 0 0;flex:0 0 auto}
#gamectl button{flex:1;font:inherit;font-size:14px;padding:3px 0;cursor:pointer;
  background:none;color:var(--pencil);border:2px solid var(--pencil);
  border-radius:12px 4px 14px 4px}
#gamectl button:hover{background:rgba(43,43,43,.08);color:var(--ink);border-color:var(--ink)}
#gamectl #pausebtn.on{background:var(--ink);border-color:var(--ink);color:var(--paper)}

/* stance picker — only on screen while something of yours is selected */
#stances{margin-top:0;flex:0 0 auto}
#stances .lab{font-size:14px;color:var(--pencil);text-transform:lowercase}
#stances .srow{display:flex;gap:6px;margin-top:4px}
#stances button{flex:1;font:inherit;font-size:13px;padding:3px 0;cursor:pointer;
  background:none;color:var(--ink);border:2px solid var(--ink);
  border-radius:11px 4px 13px 4px}
#stances button:hover{background:rgba(43,43,43,.08)}
#stances button.on{background:var(--blue);border-color:var(--blue);color:#fff}
#stances button.mixed{border-style:dashed}

/* the freeze. Deliberately not a dark scrim — the board should stay readable,
   because half of pausing is standing back and looking at it. */
#paused{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;pointer-events:none;
  background:rgba(255,255,255,.34)}
#paused span{font-family:"Rock Salt",cursive;font-size:min(7vw,72px);color:var(--ink);
  transform:rotate(-2deg)}
#paused small{font-size:15px;color:var(--pencil);margin-top:10px;transform:rotate(-1deg)}

/* ---- story mode ---------------------------------------------------------
   Everything here is the same three materials as the rest of the game: paper,
   marker and a bit of tape. The briefing is a sheet torn out and laid on the
   desk; the level list is a contents page; the objectives are a pencilled
   checklist down the side of the map. */

/* the checklist in the sidebar */
#objectives{border:2px solid var(--ink);border-radius:14px 5px 16px 6px;
  padding:7px 11px 8px;background:#fff;transform:rotate(-.35deg);flex:0 0 auto}
#objectives h4{font-family:"Rock Salt",cursive;font-size:11px;font-weight:normal;
  letter-spacing:.5px;margin-bottom:5px;color:var(--pencil)}
#objlist{list-style:none;font-size:15px;line-height:1.3}
#objlist li{display:flex;gap:7px;align-items:baseline;margin-bottom:3px}
#objlist li::before{content:"\2610";font-size:15px;color:var(--pencil)}
#objlist li.done{opacity:.55;text-decoration:line-through}
#objlist li.done::before{content:"\2611";color:var(--blue);text-decoration:none}
#objlist .n{margin-left:auto;font-size:13px;color:var(--pencil);white-space:nowrap;
  text-decoration:none}

/* the contents page */
#campaignmodal{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(240,240,238,.86);z-index:40}
#campaignmodal .card{background:var(--paper);border:3px solid var(--ink);
  border-radius:20px 8px 22px 9px;padding:18px 22px;width:min(560px,92vw);
  transform:rotate(-.5deg);box-shadow:5px 7px 0 rgba(43,43,43,.12)}
#campaignmodal h3{font-family:"Rock Salt",cursive;font-size:16px;font-weight:normal}
#campaignmodal small{display:flex;align-items:center;gap:10px;margin-top:12px;
  color:var(--pencil);font-size:13px}
#resetcampaign{font:inherit;font-size:12px;margin-left:auto;background:none;
  border:2px solid rgba(43,43,43,.4);border-radius:9px 4px 10px 4px;padding:0 7px;
  cursor:pointer;color:var(--pencil)}
#resetcampaign:hover{background:var(--red);border-color:var(--red);color:#fff}
#levellist{max-height:56vh;overflow-y:auto;padding-right:2px}
.level{display:flex;align-items:baseline;gap:12px;padding:7px 11px;margin-bottom:7px;
  cursor:pointer;border:2px solid rgba(43,43,43,.35);border-radius:13px 5px 15px 5px}
.level:hover{border-color:var(--ink);background:rgba(43,43,43,.05)}
.level .no{font-family:"Rock Salt",cursive;font-size:13px;min-width:30px;color:var(--pencil)}
.level .t{font-size:19px}
.level .w{font-size:13px;color:var(--pencil)}
.level .mark{margin-left:auto;font-size:13px;color:var(--blue)}
.level.locked{opacity:.4;cursor:not-allowed;filter:grayscale(1)}
.level.locked .mark{color:var(--pencil)}
.level.done{border-color:var(--blue)}

/* the briefing sheet */
#briefing{position:absolute;inset:0;z-index:50;display:flex;align-items:center;
  justify-content:center;background:rgba(240,240,238,.9);padding:24px}
.brief{background:#fff;border:3px solid var(--ink);border-radius:22px 9px 24px 10px;
  padding:22px 30px 20px;width:min(640px,94vw);max-height:92vh;overflow-y:auto;
  transform:rotate(-.4deg);box-shadow:6px 8px 0 rgba(43,43,43,.12)}
.bhead{border-bottom:3px solid var(--ink);padding-bottom:9px;margin-bottom:14px;
  position:relative}
.bhead .no{font-family:"Rock Salt",cursive;font-size:13px;color:var(--red);
  letter-spacing:1px}
.bhead h2{font-family:"Rock Salt",cursive;font-size:clamp(21px,3vw,30px);
  font-weight:normal;line-height:1.25;margin-top:3px}
.bhead .where{font-size:15px;color:var(--pencil);margin-top:4px}
.brief .story p{font-size:17px;line-height:1.55;margin-bottom:10px}
.brief h4{font-family:"Rock Salt",cursive;font-size:12px;font-weight:normal;
  color:var(--pencil);margin:16px 0 6px}
.brief ul{list-style:none;font-size:17px;line-height:1.5}
.brief ul li::before{content:"\2610";margin-right:8px;color:var(--pencil)}
.brief .tip{margin-top:14px;font-size:15px;color:var(--pencil);
  border-left:3px solid var(--blue);padding-left:10px}
.brow{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}
.brow button{font:inherit;font-size:17px;background:none;color:var(--ink);cursor:pointer;
  border:2.5px solid var(--ink);border-radius:13px 5px 15px 5px;padding:4px 16px}
.brow button:hover{background:var(--ink);color:var(--paper)}

/* Shown once, after the twelfth mission and only on a win. A line of text in
   the debrief rather than anything modal -- the game has spent twelve missions
   never asking for anything, and a dialog here would spend that. */
#debriefdonate{margin:10px 0 2px;font-size:16px;line-height:1.45;color:var(--pencil)}
#debriefdonate a{color:var(--blue)}
#debriefdonate.hidden{display:none}
.brow button.go{border-color:var(--blue);color:var(--blue)}
.brow button.go:hover{background:var(--blue);color:#fff}

/* the debrief */
#debrief{position:absolute;inset:0;z-index:50;display:flex;align-items:center;
  justify-content:center;background:rgba(240,240,238,.86)}
#debrief .card{background:var(--paper);border:3px solid var(--ink);
  border-radius:20px 8px 22px 9px;padding:20px 26px;width:min(480px,92vw);
  transform:rotate(.5deg);box-shadow:5px 7px 0 rgba(43,43,43,.12)}
#debrief h3{font-family:"Rock Salt",cursive;font-size:clamp(19px,2.6vw,26px);
  font-weight:normal;line-height:1.3}
#debrief.win h3{color:var(--blue)} #debrief.lose h3{color:var(--red)}
#debrief p{font-size:17px;line-height:1.5;margin-top:10px}
#debriefunlock{margin-top:14px;padding:8px 12px;font-size:16px;
  border:2px dashed var(--blue);border-radius:12px 5px 14px 5px;color:var(--blue)}
