/* ============================================================
   Null Sector — standalone game page.
   Full viewport, never scrolls. Canvas draws the board; DOM draws
   the chrome.

   Look: a Blendo Games pass. Flat blocks of colour, hard edges,
   solid offset shadows instead of glows, stencilled uppercase
   labels on tabs, dotted leader lines between label and value,
   and big numbers with small captions — a piece of field equipment
   rather than a sci-fi hologram. The neon palette stays for the
   board itself; the chrome around it is deliberately utilitarian.
   ============================================================ */

:root{
  --sans:"Inter",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
  --heavy:"Archivo Black","Arial Black",system-ui,sans-serif;
  --bg:#0a0812;
  --panel:#141024;
  --panel2:#1b1530;
  --edge:#3d3163;
  --pink:#ff2d95;
  --cyan:#00e5ff;
  --mint:#8affc0;
  --amber:#ffc247;
  --dim:#9c93bd;
  --ink:#0a0812;
  --hud-h:62px;
}

*{box-sizing:border-box;}
html,body{margin:0;height:100%;overflow:hidden;background:var(--bg);
  color:#eef1ff;font-family:var(--mono);font-size:16px;
  -webkit-text-size-adjust:100%;overscroll-behavior:none;}
/* No grey tap flash, and no text selection flicker when tapping fast */
*{-webkit-tap-highlight-color:transparent;}
button,canvas,a{-webkit-user-select:none;user-select:none;}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}

.tac-app{position:fixed;inset:0;display:flex;flex-direction:column;background:var(--bg);
  /* dvh tracks the shrinking address bar on mobile; the fallback is for old browsers */
  height:100%;height:100dvh;
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);}

/* ---------- shared bits of the visual language ---------- */
/* stencilled tab label, sits on the edge of a block */
.tab{display:inline-block;padding:.2rem .5rem .16rem;font-family:var(--heavy);
  font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;
  background:var(--edge);color:#eef1ff;}
.tab--foe{background:var(--pink);color:var(--ink);}
.tab--ally{background:var(--cyan);color:var(--ink);}
.tab--mint{background:var(--mint);color:var(--ink);}
.tab--amber{background:var(--amber);color:var(--ink);}

/* label ......... value */
.led{display:flex;align-items:baseline;gap:.4rem;font-size:.8rem;line-height:1.75;}
.led__k{flex:0 0 auto;color:var(--dim);text-transform:uppercase;letter-spacing:.09em;font-size:.72rem;}
.led__fill{flex:1 1 auto;border-bottom:1px dotted rgba(156,147,189,.45);transform:translateY(-.22em);}
.led__v{flex:0 0 auto;color:#fff;font-weight:600;}
.led__v em{font-style:normal;color:var(--mint);}
.led__v s{text-decoration:none;color:var(--dim);font-weight:400;}

/* big number with a caption under it */
.big{display:flex;flex-direction:column;align-items:center;gap:.05rem;min-width:3.6rem;}
.big b{font-family:var(--heavy);font-size:1.6rem;line-height:1;letter-spacing:-.01em;}
.big i{font-style:normal;font-size:.58rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);}
.big--hit b{color:var(--mint);}
.big--dmg b{color:var(--amber);}
.big--sure b{color:var(--mint);}

/* ---------- HUD bars ---------- */
.hud{flex:0 0 auto;min-height:var(--hud-h);display:flex;align-items:center;
  gap:.7rem;padding:.35rem clamp(.5rem,2vw,1.2rem);z-index:5;background:var(--panel);}
.hud--top{border-bottom:3px solid var(--edge);}
.hud--bottom{border-top:3px solid var(--edge);}
.hud__right{display:flex;align-items:center;gap:.4rem;margin-left:auto;}
.hud__title{font-family:var(--heavy);font-size:1.05rem;letter-spacing:.06em;color:#fff;
  white-space:nowrap;}
.hud__back{flex:0 0 auto;display:grid;place-items:center;width:34px;height:34px;
  font-size:1rem;color:var(--dim);text-decoration:none;border:2px solid var(--edge);}

/* top-right readouts */
.stat{display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:3.1rem;padding:.1rem .35rem;background:var(--panel2);border:2px solid var(--edge);}
.stat b{font-family:var(--heavy);font-size:1.05rem;line-height:1.05;color:#fff;}
.stat i{font-style:normal;font-size:.54rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);}
.stat--foe b{color:var(--pink);}
.stat--threat{border-color:var(--pink);background:rgba(255,45,149,.14);}
.stat--threat b{color:var(--pink);}
.stat[hidden]{display:none;}

.hud__help{flex:0 0 auto;width:34px;height:34px;font-family:var(--heavy);font-size:.8rem;
  cursor:pointer;background:transparent;color:var(--dim);border:2px solid var(--edge);}

/* ---------- operative cards ---------- */
.squad{flex:1 1 auto;display:flex;flex-wrap:nowrap;gap:.5rem;align-items:center;
  min-width:0;overflow-x:auto;overflow-y:hidden;padding:.4rem 0;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.squad::-webkit-scrollbar{display:none;}
.chip{flex:0 0 auto;display:flex;align-items:center;gap:.55rem;cursor:pointer;
  padding:.3rem .5rem;background:var(--panel2);border:2px solid var(--edge);
  font-family:var(--mono);text-align:left;transition:none;}
.chip--sel{border-color:var(--cyan);background:#10233a;box-shadow:3px 3px 0 var(--cyan);}
.chip--done{opacity:.45;}
.chip--down{opacity:.28;}
.chip--down .chip__name{text-decoration:line-through;}
.chip__id{display:flex;flex-direction:column;gap:.05rem;}
.chip__name{font-family:var(--heavy);font-size:.82rem;letter-spacing:.05em;color:#fff;line-height:1;}
.chip__wpn{font-size:.62rem;letter-spacing:.05em;color:var(--dim);white-space:nowrap;}
/* HP as chunky blocks */
.chip__hp{display:inline-flex;gap:2px;align-items:center;}
.chip__pip{width:8px;height:15px;background:var(--mint);}
.chip__pip--empty{background:transparent;box-shadow:inset 0 0 0 2px rgba(138,255,192,.3);}
/* hull the hostiles are about to take off this operative */
.chip__pip--risk{background:var(--amber);}
.chip__pip--dead{background:var(--pink);}
.chip__perk{font-family:var(--heavy);font-size:.6rem;letter-spacing:.06em;
  background:var(--amber);color:var(--ink);padding:.12rem .28rem;}

/* move / action availability */
.av{display:inline-flex;gap:3px;align-items:center;}
.av i{width:11px;height:11px;display:block;box-shadow:inset 0 0 0 2px rgba(156,147,189,.6);}
.av i.on{background:var(--mint);box-shadow:none;}
.av i.act{border-radius:50%;}

.hud__msg{flex:1 1 0;display:flex;align-items:center;justify-content:center;
  font-size:.8rem;letter-spacing:.02em;color:var(--mint);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hud__acts{flex:0 0 auto;display:flex;gap:.4rem;align-items:center;}

.btn-act{font-family:var(--heavy);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--amber);background:transparent;border:2px solid var(--amber);
  padding:.5rem .7rem;cursor:pointer;}
.btn-act--on{background:var(--amber);color:var(--ink);}

.btn-end{flex:0 0 auto;font-family:var(--heavy);font-size:.82rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink);background:var(--dim);border:0;
  padding:.6rem 1.15rem;cursor:pointer;box-shadow:3px 3px 0 rgba(0,0,0,.55);}
.btn-end:active:not(:disabled){transform:translate(1px,1px);box-shadow:1px 1px 0 rgba(0,0,0,.55);}
.btn-end:disabled{background:#2e2748;color:#6d6592;box-shadow:none;cursor:default;}
.btn-end--ready:not(:disabled){background:var(--mint);}

/* Hover effects are gated: on a touch screen :hover sticks after a tap and the
   element visibly jumps, which reads as a flash. */
@media (hover:hover) and (pointer:fine){
  .hud__back:hover{color:var(--ink);background:var(--dim);}
  .hud__help:hover{background:var(--amber);border-color:var(--amber);color:var(--ink);}
  .btn-act:hover:not(:disabled){background:var(--amber);color:var(--ink);}
  .btn-end:hover:not(:disabled){transform:translate(-1px,-1px);box-shadow:4px 4px 0 rgba(0,0,0,.55);}
  .btn-neon:hover{transform:translate(-1px,-1px);box-shadow:6px 6px 0 rgba(0,0,0,.6);}
  .reward:hover{border-color:var(--mint);box-shadow:4px 4px 0 var(--mint);transform:translate(-1px,-1px);}
}

/* ---------- board ---------- */
.stagewrap{flex:1 1 auto;min-height:0;display:grid;place-items:center;position:relative;overflow:hidden;}
#stage{display:block;cursor:pointer;touch-action:none;}

/* ---------- inspector ("dossier") ---------- */
.tip{position:absolute;z-index:12;pointer-events:none;width:258px;
  background:var(--panel);border:3px solid var(--edge);
  box-shadow:6px 6px 0 rgba(0,0,0,.6);}
.tip__sheet-hint{margin:0;padding:.55rem;text-align:center;font-size:.74rem;color:var(--dim);}
.tip[hidden]{display:none;}
.tip__head{padding:.5rem .6rem .55rem;}
.tip__name{display:block;font-family:var(--heavy);font-size:1.3rem;line-height:1;
  letter-spacing:.02em;color:#fff;margin-top:.34rem;}
.tip__name--foe{color:var(--pink);}
.tip__name--ally{color:var(--cyan);}
.tip__sub{display:block;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim);margin-top:.16rem;}
.tip__block{padding:.15rem .6rem .5rem;border-top:2px solid var(--edge);}
.tip__block .tab{margin:-2px 0 .35rem;}
.tip__bigs{display:flex;gap:.5rem;justify-content:space-around;
  padding:.35rem 0 .45rem;background:var(--panel2);margin-bottom:.35rem;}
.tip__note{margin:.3rem 0 0;font-size:.72rem;line-height:1.55;color:#b8afd8;}
/* flavour caption: sits under the name, quieter than the stats it precedes */
.tip__flavour{margin:0 0 .45rem;font-size:.72rem;line-height:1.4;font-style:italic;
  color:var(--dim);border-left:2px solid var(--edge);padding-left:.5rem;}
.tip__warn{margin:.35rem 0 0;padding:.3rem .4rem;font-size:.72rem;line-height:1.4;
  color:var(--ink);background:var(--amber);font-weight:600;}
.tip__kill{margin:.35rem 0 0;padding:.32rem .4rem;font-family:var(--heavy);font-size:.7rem;
  letter-spacing:.07em;text-transform:uppercase;color:var(--ink);background:var(--mint);}
.tip__perks{margin:.35rem 0 0;font-size:.68rem;line-height:1.5;color:var(--amber);}
.tip__perks--foe{color:var(--pink);}
.tip__confirm{padding:.45rem .5rem;text-align:center;font-family:var(--heavy);
  font-size:.68rem;letter-spacing:.11em;text-transform:uppercase;
  background:var(--mint);color:var(--ink);}
.tip__confirm--wait{background:var(--edge);color:#eef1ff;}
.tip__confirm--danger{background:var(--pink);color:var(--ink);}

/* ---------- modal screens ---------- */
.overlay{position:absolute;inset:0;z-index:20;display:grid;place-items:center;
  padding:1.2rem;background:rgba(6,4,12,.92);}
.overlay[hidden]{display:none;}
.panel{position:relative;max-width:600px;width:100%;max-height:92vh;overflow:auto;
  background:var(--panel);border:3px solid var(--edge);box-shadow:10px 10px 0 rgba(0,0,0,.6);
  padding:clamp(.9rem,2.2vw,1.4rem);}
.panel h1{font-family:var(--heavy);font-size:clamp(1.9rem,6vw,2.7rem);line-height:.95;
  margin:.3rem 0 .35rem;letter-spacing:.01em;color:#fff;}
.panel h1 span{color:var(--pink);}
.panel h2{font-family:var(--heavy);font-size:clamp(1.3rem,4vw,1.9rem);line-height:1;
  margin:.3rem 0 .55rem;color:#fff;letter-spacing:.02em;}
.panel p{font-size:.82rem;line-height:1.55;color:#c6bee4;margin:0 0 .6rem;}
.panel .lede{color:var(--mint);font-size:.8rem;letter-spacing:.06em;text-transform:uppercase;}

/* field manual: numbered rules */
.how{margin:.7rem 0 .9rem;border-top:2px solid var(--edge);}
.how__row{display:flex;gap:.6rem;padding:.4rem 0;border-bottom:2px solid var(--edge);}
.how__n{flex:0 0 1.7rem;height:1.7rem;display:grid;place-items:center;
  font-family:var(--heavy);font-size:.8rem;background:var(--edge);color:#fff;}
.how__t{flex:1 1 auto;font-size:.78rem;line-height:1.45;color:#c6bee4;margin:0;}
.how__t b{color:#fff;}
.how__t em{font-style:normal;color:var(--mint);font-weight:600;}
.how__t s{text-decoration:none;color:var(--pink);font-weight:600;}

.btn-neon{display:inline-block;font-family:var(--heavy);font-size:1rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink);background:var(--mint);border:0;
  padding:.65rem 1.6rem;margin:.3rem .3rem 0 0;cursor:pointer;
  box-shadow:5px 5px 0 rgba(0,0,0,.6);}
.btn-neon:active{transform:translate(2px,2px);box-shadow:2px 2px 0 rgba(0,0,0,.6);}

/* hostiles got there first */
.steal{margin:.7rem 0 .9rem;padding:.5rem .6rem;border:3px solid var(--pink);
  background:rgba(255,45,149,.12);}
.steal .tab{margin:-.5rem 0 .4rem -.6rem;}
.steal__what{margin:0;font-size:.84rem;line-height:1.45;color:#ffd9ec;}
.steal__what b{font-family:var(--heavy);color:#fff;}
.steal__next{margin:.5rem 0 0;font-size:.72rem;color:var(--pink);}

/* debrief lines */
.brief__cost{margin:.4rem 0 .6rem;padding:.3rem .45rem;font-size:.78rem;
  background:var(--pink);color:var(--ink);font-weight:600;}
.brief__note{margin:.35rem 0 .6rem;font-size:.74rem;color:var(--mint);}

/* squad roster (kept for reuse; the debrief no longer prints one) */
.roster{margin:.9rem 0 1.1rem;border:2px solid var(--edge);}
.roster__row{display:flex;gap:.7rem;padding:.45rem .6rem;border-bottom:2px solid var(--edge);
  align-items:baseline;font-size:.78rem;}
.roster__row:last-child{border-bottom:0;}
.roster__row dt{flex:0 0 4.2rem;font-family:var(--heavy);font-size:.78rem;
  letter-spacing:.05em;color:var(--cyan);}
.roster__row dd{margin:0;color:#c6bee4;}
.roster__perks{display:block;color:var(--amber);font-size:.72rem;margin-top:.1rem;}
.roster__row--foe dt{color:var(--pink);}
.roster__row--foe dd{color:#ffd9ec;}

/* requisition choices */
.rewards{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:.6rem;margin-top:.7rem;}
.reward{display:flex;flex-direction:column;gap:.3rem;padding:.8rem .6rem;cursor:pointer;
  background:var(--panel2);border:3px solid var(--edge);text-align:left;}
.reward__icon{font-family:var(--heavy);font-size:1.5rem;line-height:1;color:var(--mint);}
.reward__name{font-family:var(--heavy);font-size:.8rem;letter-spacing:.03em;color:#fff;}
.reward__desc{font-size:.72rem;color:var(--dim);line-height:1.45;}
@media(max-width:560px){ .rewards{grid-template-columns:1fr;} }

/* ---------- phones ----------
   Two independent decisions:
   - COMPACT content (<=820px, any orientation): the readout shows only what a
     decision needs — who, two figures, one warning, the confirm bar. game.js
     renders this via renderSheet(); the full dossier never fits a phone.
   - DOCKED position (<=820px AND portrait only): it sits in the flex flow at a
     fixed height, so it reserves its own space and the board never jumps.
     In landscape height is the scarce axis, so it floats beside the board
     instead of stealing a row. */
@media(max-width:820px){
  :root{ --hud-h:54px; --sheet-h:104px; }
  .chip__wpn{display:none;}

  .tip{width:238px;
    display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr auto;
    align-content:start;column-gap:.5rem;}
  .sheet__id{grid-column:1;grid-row:1;padding:.35rem .55rem 0;min-width:0;}
  .sheet__name{display:block;font-family:var(--heavy);font-size:1.02rem;line-height:1.1;
    margin-top:.2rem;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .sheet__figs{grid-column:2;grid-row:1/3;display:flex;gap:.5rem;align-items:center;
    padding:.35rem .55rem 0;}
  .sheet__figs .big{min-width:2.9rem;}
  .sheet__figs .big b{font-size:1.45rem;}
  .sheet__line{grid-column:1;grid-row:2;margin:.15rem 0 .2rem;padding:0 .55rem;
    font-size:.7rem;line-height:1.3;color:var(--amber);
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
  .sheet__line--kill{color:var(--mint);font-weight:600;}
  .sheet__line--flavour{color:var(--dim);font-style:italic;}
  .tip__confirm{grid-column:1/-1;grid-row:3;align-self:end;}
  .tip__sheet-hint{grid-column:1/-1;grid-row:1/-1;align-self:center;}
}
@media(max-width:820px) and (orientation:portrait){
  /* dock it: static in the flow, fixed height, always reserving its space */
  .tip{position:static;left:auto;right:auto;bottom:auto;width:auto;
    flex:0 0 var(--sheet-h);height:var(--sheet-h);overflow:hidden;
    border-width:3px 0 0;box-shadow:none;}
  .tip[hidden]{display:grid;}
}
@media(max-width:620px){
  .hud__title{display:none;}
  .stat{min-width:2.5rem;padding:.1rem .25rem;}
  .stat b{font-size:.92rem;}
  .chip{gap:.4rem;padding:.25rem .4rem;}
  .chip__pip{width:6px;height:13px;}
  .chip__name{font-size:.74rem;}
  /* claw back room for the operative cards */
  .btn-end{padding:.5rem .6rem;font-size:.7rem;}
  .btn-act{padding:.4rem .5rem;font-size:.58rem;}
}
/* landscape phone: height is scarce, so thin the bars right down */
@media(max-height:520px){
  :root{ --hud-h:40px; }
  .hud{padding:.2rem .5rem;}
  /* keep the panel narrow enough to park beside a height-limited board
     instead of covering it */
  .tip{width:196px;}
  .sheet__figs .big{min-width:2.4rem;}
  .sheet__figs .big b{font-size:1.2rem;}
  .hud__back,.hud__help{width:30px;height:30px;}
  .stat i,.big i{font-size:.5rem;}
  .stat b{font-size:.9rem;}
  .tip__note,.tip__perks{display:none;}
  .panel{padding:.6rem .8rem;max-height:94vh;}
  .how__row{padding:.2rem 0;}
  .how__t{font-size:.66rem;line-height:1.3;}
  .panel h1{font-size:1.4rem;margin:.2rem 0 .3rem;}
  .panel h2{font-size:1.1rem;}
  .btn-neon{font-size:.78rem;padding:.42rem 1rem;}
  .rewards{gap:.4rem;}
  .reward{padding:.5rem .45rem;}
  .roster__row{padding:.3rem .5rem;font-size:.72rem;}
  /* two columns of rules, so the primary button stays above the fold on a
     landscape phone instead of scrolling out of reach */
  .how{display:grid;grid-template-columns:1fr 1fr;column-gap:.9rem;border-top:0;}
  .how__row{border-bottom:0;border-top:2px solid var(--edge);}
  .how__n{width:1.4rem;height:1.4rem;flex-basis:1.4rem;font-size:.7rem;}
}

.toosmall{position:absolute;inset:0;z-index:30;display:none;place-items:center;text-align:center;
  padding:2rem;background:var(--bg);font-size:.86rem;color:var(--dim);}
.tac-app.is-tiny .toosmall{display:grid;}

@media(prefers-reduced-motion:reduce){
  *{transition:none!important;}
  .btn-end:hover,.btn-neon:hover,.reward:hover{transform:none;}
}

/* short windows: keep the primary button above the fold */
@media(max-height:760px){
  .how__row{padding:.3rem 0;}
  .how__t{font-size:.74rem;line-height:1.38;}
  .panel h1{font-size:clamp(1.6rem,5vw,2.1rem);}
  .btn-neon{font-size:.9rem;padding:.55rem 1.3rem;}
}

/* very short (landscape phone): squeeze the manual so Deploy stays reachable */
@media(max-height:430px){
  .panel{padding:.45rem .6rem;max-height:97vh;}
  .panel h1{font-size:1.15rem;margin:.1rem 0 .25rem;}
  .panel h2{font-size:1rem;margin:.1rem 0 .3rem;}
  .how{margin:.35rem 0 .45rem;}
  .how__row{padding:.16rem 0;}
  .how__t{font-size:.62rem;line-height:1.28;}
  .btn-neon{font-size:.72rem;padding:.36rem .9rem;box-shadow:3px 3px 0 rgba(0,0,0,.6);}
  .tip__bigs{padding:.15rem 0 .2rem;}
}
