/* Admin Adventures: NES color.
   One palette (the NES 2C02's own values, mirrored in palette.ts), one font ("Smplify 8", ours, drawn on an 8x8 grid),
   and one kind of window: deep blue fill, a 2px white border with notched corners, the way a 1985 RPG drew its menus.
   The world, the people and the monsters are in color. Some colors also say something: red is danger only (drift, alerts,
   DENY, errors, low coffee), green is healthy and done, gold is tokens and XP. Nothing is ever color alone: each has an icon or a word. */

@font-face { font-family: "Smplify 8"; src: url("/fonts/smplify-8.woff") format("woff"); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: "Smplify 8 Mono"; src: url("/fonts/smplify-8-mono.woff") format("woff"); font-weight: 400; font-style: normal; font-display: block; }

:root {
  /* The palette. */
  --nes-black: #000000; --nes-dark: #585858; --nes-gray: #7C7C7C; --nes-light: #BCBCBC; --nes-white: #F8F8F8;
  --nes-navy: #0000BC; --nes-blue: #0058F8; --nes-sky: #3CBCFC; --nes-ice: #A4E4FC;
  --nes-indigo: #4428BC; --nes-violet: #6844FC; --nes-lavender: #B8B8F8;
  --nes-plum: #940084; --nes-pink: #F878F8; --nes-blush: #F8A4C0;
  --nes-crimson: #A80020; --nes-red: #D82800; --nes-red-light: #F87858;
  --nes-umber: #503000; --nes-rust: #881400; --nes-brown: #AC7C00; --nes-orange: #E45C10; --nes-peach: #FCA044;
  --nes-gold: #F8B800; --nes-straw: #F8D878; --nes-cream: #FCE0A8;
  --nes-forest: #005800; --nes-pine: #007800; --nes-green: #00A844; --nes-green-light: #58D854; --nes-mint: #B8F8B8;
  --nes-deep-teal: #004058; --nes-teal: #008888; --nes-aqua: #00E8D8;
  /* What the palette is for. --bg is a window's fill (deep blue); --page is what the windows sit on (black). Every text color
     below passes WCAG AA (4.5:1) on both, and every edge that marks a control passes 3:1 (scripts/contrast-audit.mjs checks). */
  --page: var(--nes-black); --bg: var(--nes-navy); --fg: var(--nes-white); --dim: var(--nes-ice); --faint: var(--nes-light); --rule: var(--nes-sky);
  --drift: var(--nes-red-light); --drift-fill: var(--nes-red);
  --ok: var(--nes-green-light); --ok-fill: var(--nes-green);
  --gold: var(--nes-gold);
  --font: "Smplify 8", ui-monospace, Menlo, Consolas, monospace;
  --font-mono: "Smplify 8 Mono", ui-monospace, Menlo, Consolas, monospace;
  /* A window edge: a 2px white line on each side, and nothing at the corners, so every corner is notched. */
  --edge: 0 -2px 0 0 var(--nes-white), 0 2px 0 0 var(--nes-white), -2px 0 0 0 var(--nes-white), 2px 0 0 0 var(--nes-white);
  --edge-dim: 0 -2px 0 0 var(--nes-sky), 0 2px 0 0 var(--nes-sky), -2px 0 0 0 var(--nes-sky), 2px 0 0 0 var(--nes-sky);
  --edge-gold: 0 -2px 0 0 var(--nes-gold), 0 2px 0 0 var(--nes-gold), -2px 0 0 0 var(--nes-gold), 2px 0 0 0 var(--nes-gold);
  --edge-ok: 0 -2px 0 0 var(--nes-green-light), 0 2px 0 0 var(--nes-green-light), -2px 0 0 0 var(--nes-green-light), 2px 0 0 0 var(--nes-green-light);
  --edge-drift: 0 -2px 0 0 var(--nes-red-light), 0 2px 0 0 var(--nes-red-light), -2px 0 0 0 var(--nes-red-light), 2px 0 0 0 var(--nes-red-light);
  --win: var(--edge), 0 -4px 0 0 var(--nes-black), 0 4px 0 0 var(--nes-black), -4px 0 0 0 var(--nes-black), 4px 0 0 0 var(--nes-black);
  /* Set by theme.ts from the pixel art, so the icons in the interface are the icons in the game. */
  --ic-cup: none; --ic-cup-empty: none; --ic-cup-low: none; --ic-robot: none; --sky: none;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%;background:var(--page);color:var(--fg);
  font-family:var(--font);font-size:16px;line-height:24px;font-weight:400;font-synthesis:none;
  -webkit-font-smoothing:none}
b,strong,h1,h2,h3,th{font-weight:400}
body{padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px);
  overflow:hidden;touch-action:manipulation;-webkit-user-select:none;user-select:none}
button,input,textarea,select{font:inherit;color:inherit;letter-spacing:0}
button{cursor:pointer;border-radius:0}
:focus-visible{outline:2px solid var(--nes-white);outline-offset:2px}
.hidden{display:none!important}
a{color:var(--nes-white)}

/* ---------- the menu cursor: a small triangle that marks the focused choice ---------- */
.choice,.hudbtn,.big,.town,#moves button,.tabs button,.gbtns button{position:relative}
.choice::before,.hudbtn::before,.big::before,.town::before,#moves button::before,.tabs button::before,.gbtns button::before{
  /* Decorative: the second declaration gives the glyph empty alt text so it stays out of the button's accessible name (browsers without alt text keep the first). */
  content:"\25B6";content:"\25B6" / "";position:absolute;left:var(--cx,4px);top:var(--cy,2px);visibility:hidden;color:inherit}
#moves button::before,.tabs button::before{color:var(--nes-white)}
.choice:hover::before,.choice:focus-visible::before,.hudbtn:hover::before,.hudbtn:focus-visible::before,
.big:hover::before,.big:focus-visible::before,.town:hover::before,.town:focus-visible::before,
#moves button:hover:not(:disabled)::before,#moves button:focus-visible::before,
.tabs button:hover::before,.tabs button:focus-visible::before,.gbtns button:hover::before,.gbtns button:focus-visible::before{visibility:visible}
.choice{--cx:2px}.hudbtn{--cx:6px}.big{--cx:10px;--cy:8px}.town{--cx:8px;--cy:12px}#moves button{--cx:-20px}.tabs button{--cx:-18px}.gbtns button{--cx:4px;--cy:8px}

#app{height:100%;display:flex;flex-direction:column;max-width:1040px;margin:0 auto}

/* ---------- the status bar ---------- */
#hud{display:flex;flex-wrap:wrap;align-items:center;gap:0 16px;padding:8px 12px 8px 20px;background:var(--bg);box-shadow:0 2px 0 0 var(--nes-white)}
/* Row one: where you are, and the menu. Row two: how you are doing. */
#hud::after{content:"";order:2;flex-basis:100%;height:0}
#loc{order:0;margin-right:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:60vw;color:var(--fg);font-size:24px;line-height:32px}
#hud .hudbtn{order:1}
#hud .stat{order:3}
.stat{display:flex;align-items:center;gap:8px;white-space:nowrap;color:var(--dim)}
#lvlTxt{color:var(--fg)}
/* Segmented meters. --segs squares; the fill snaps to whole squares (round() ignores older browsers, which then show the plain width). */
/* A meter sits in a black well (a 2px black frame around it), empty squares gray, so it reads on the blue window. */
.bar{--segs:10;--seg:8px;--gap:2px;position:relative;width:calc(var(--segs) * (var(--seg) + var(--gap)));height:var(--seg);flex:none;
  background:repeating-linear-gradient(90deg,var(--nes-gray) 0 var(--seg),var(--nes-black) var(--seg) calc(var(--seg) + var(--gap)));box-shadow:0 0 0 2px var(--nes-black)}
.bar i{display:block;height:100%;width:0;
  background:repeating-linear-gradient(90deg,var(--fill,var(--nes-green-light)) 0 var(--seg),transparent var(--seg) calc(var(--seg) + var(--gap)));
  transition:width .4s steps(8)}
.bar i[style*="--n"]{width:max(round(down,calc(var(--n) * 1%),calc(100% / var(--segs))),calc(sign(var(--n)) * 100% / var(--segs)))!important}
.bar.xp{--fill:var(--nes-gold)}
.bar.drift{--fill:var(--nes-red-light);--seg:12px;--gap:4px}
.bar.drift i{transition:none}
/* Coffee, as cups. */
.cups{--max:10;--n:10;--cw:18px;--ch:14px;display:inline-block;flex:none;width:calc(var(--max) * var(--cw));height:var(--ch);
  background:var(--ic-cup-empty) 0 0/var(--cw) var(--ch) repeat-x var(--nes-black);box-shadow:0 0 0 2px var(--nes-black);image-rendering:pixelated}
.cups i{display:block;height:100%;width:calc(var(--n) * var(--cw));background:var(--ic-cup) 0 0/var(--cw) var(--ch) repeat-x;image-rendering:pixelated}
/* Low coffee turns the cups red (meter.ts sets .low); the number beside them says the same in words. */
.cups.low i{background-image:var(--ic-cup-low)}
#coffeeStat{gap:8px}
#coffeeTxt{color:var(--dim)}
/* Menu labels. */
.hudbtn{background:none;border:0;padding:2px 6px 2px 22px;color:var(--fg);position:relative}
.hudbtn:hover,.hudbtn:focus-visible{background:var(--nes-white);color:var(--nes-navy)}
.hudbtn:active{transform:translateY(2px)}
#tokenbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:0 12px 0 20px;background:var(--bg)}
#tokenTxt{color:var(--gold);padding:2px 0}
#questbar{background:var(--bg);padding:2px 12px 8px 20px;color:var(--dim);box-shadow:0 2px 0 0 var(--nes-sky);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}
#questbar span{color:var(--fg)}

/* ---------- the map ---------- */
#stage{flex:1;display:flex;align-items:center;justify-content:center;min-height:0;padding:16px 12px;position:relative}
#cv{image-rendering:pixelated;image-rendering:crisp-edges;display:block;background:var(--page);box-shadow:var(--win)}
#bubble{position:absolute;z-index:5;background:var(--bg);color:var(--fg);padding:6px 12px;line-height:24px;
  max-width:340px;width:max-content;pointer-events:none;box-shadow:var(--edge);transform:translate(-50%,calc(-100% - 22px))}
#bubble::after{content:"\25BC";content:"\25BC" / "";position:absolute;left:50%;bottom:-24px;margin-left:-4px;color:var(--nes-white);line-height:24px}
#bubble b{display:block;color:var(--dim)}
#toast{position:absolute;top:24px;left:50%;transform:translateX(-50%);background:var(--bg);padding:6px 16px;
  box-shadow:var(--edge);pointer-events:none;max-width:90%;text-align:center}

/* ---------- windows ---------- */
#dialog{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(20px + env(safe-area-inset-bottom,0px));
  width:min(92vw,760px);background:var(--bg);padding:20px 24px 16px;z-index:20;box-shadow:var(--win)}
#dname{position:absolute;top:-16px;left:20px;padding:0 10px;background:var(--bg);color:var(--fg);box-shadow:var(--edge);line-height:24px}
#dname:empty{display:none}
#dname.fm::before{content:"";display:inline-block;width:14px;height:10px;margin-right:8px;background:var(--ic-robot) center/14px 10px no-repeat;image-rendering:pixelated}
#dtext{min-height:72px;white-space:pre-line;max-height:52vh;overflow:auto;color:var(--fg)}
#dchoices{display:flex;flex-wrap:wrap;gap:0 28px;margin-top:12px;padding-left:16px}
/* A link under a line (the field note after a knowledge check): small, and it opens smplify.com in a new tab. */
#dlink{margin-top:8px;padding-left:16px;font-size:16px;line-height:24px}
#dlink a{color:var(--fg);padding:0 4px}
#dlink a:hover,#dlink a:focus-visible{background:var(--nes-white);color:var(--nes-navy);text-decoration:none}
#dmore{position:absolute;right:20px;bottom:10px;color:var(--fg);animation:blink 1s steps(2) infinite}
@keyframes blink{50%{opacity:0}}
@media (min-width:640px){#dialog{font-size:24px;line-height:36px}#dname{font-size:16px}#dtext{min-height:108px}}
.choice{position:relative;background:none;border:0;padding:2px 8px 2px 16px;color:var(--fg);text-align:left}
.choice:hover,.choice:focus-visible{background:var(--nes-white);color:var(--nes-navy)}
/* Outside the dialog, a choice is a small window of its own, so it reads as a button. */
.panel .choice,.speech .choice{padding:2px 12px 2px 24px;box-shadow:var(--edge);--cx:6px;margin:2px}

.overlay{position:fixed;inset:0;z-index:30;display:flex;align-items:center;justify-content:center;
  /* Every other pixel black, a 1px checkerboard: the world shows through, dimmed, without a single blended color. */
  background:conic-gradient(var(--nes-black) 25%,transparent 0 50%,var(--nes-black) 0 75%,transparent 0) 0 0/2px 2px;
  padding:calc(24px + env(safe-area-inset-top,0px)) 24px calc(24px + env(safe-area-inset-bottom,0px));overflow:auto}
.panel{background:var(--bg);width:min(100%,640px);padding:24px 28px;max-height:100%;overflow:auto;box-shadow:var(--win);margin:4px}
.panel h2{margin:0 0 8px;font-size:24px;line-height:32px;color:var(--fg)}
.panel h3{margin:16px 0 10px;padding-bottom:4px;font-size:16px;color:var(--fg);box-shadow:0 2px 0 0 var(--nes-sky)}
.panel p{margin:8px 0 16px;color:var(--dim)}
.panel{font-size:calc(16px * var(--text-scale,1))}
label{display:block;margin:12px 0 4px;color:var(--dim)}
input[type=text],input[type=password],input[type=url],textarea{width:100%;background:var(--bg);border:0;padding:8px 12px;box-shadow:var(--edge-dim);-webkit-user-select:text;user-select:text}
input:focus,textarea:focus{box-shadow:var(--edge);outline:0}
::placeholder{color:var(--faint);opacity:1}
input[type=range]{accent-color:var(--nes-white);vertical-align:middle;width:min(100%,220px)}
input[type=checkbox],input[type=radio]{accent-color:var(--nes-white)}
.hint{color:var(--dim);margin-top:4px}
.row{display:flex;gap:16px;flex-wrap:wrap;margin-top:20px;padding-left:2px}
/* Buttons. Primary is a white slab with navy type; "alt" is a blue window with white type. */
.big{position:relative;background:var(--nes-white);color:var(--nes-navy);border:0;padding:8px 20px 8px 32px;box-shadow:var(--edge)}
.big.alt{background:var(--bg);color:var(--fg);box-shadow:var(--edge)}
.big:hover,.big:focus-visible{background:var(--nes-ice)}
.big.alt:hover,.big.alt:focus-visible{background:var(--nes-indigo)}
.big:active{transform:translateY(2px)}
.big:disabled,.choice:disabled{background:var(--nes-gray);color:var(--nes-black);box-shadow:var(--edge-dim);cursor:not-allowed}
.big:disabled::before,.choice:disabled::before{visibility:hidden!important}
.big:disabled{cursor:wait}
details{margin-top:12px}
summary{cursor:pointer;color:var(--fg)}
#setupMsg{margin-top:12px;white-space:pre-line;color:var(--dim)}
#setupMsg.err{color:var(--drift)}

/* ---------- the title screen ---------- */
#setup{background:var(--nes-black) var(--sky) 0 0/128px 128px;align-items:center}
#setup .panel{width:min(100%,600px)}
.title{font-size:40px;line-height:48px;margin:0 0 8px;color:var(--nes-white);text-shadow:4px 4px 0 var(--nes-black)}
.title-art{display:flex;align-items:flex-end;justify-content:center;gap:16px;margin:8px 0 20px;height:128px}
.title-art svg{image-rendering:pixelated;flex:none}
.title-art .hero,.title-art .fm{width:96px;height:96px}
.title-art .foe{width:128px;height:128px}
#setup .row{margin-top:24px}
#setup .setting{display:flex;gap:16px;flex-wrap:wrap;align-items:center;margin-top:16px;padding-left:2px}

/* ---------- travel ---------- */
#towns{display:grid;grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:20px;margin:16px 0;padding:0 4px}
.town{position:relative;background:var(--bg);border:0;padding:12px 12px 12px 28px;text-align:left;box-shadow:var(--edge-dim);display:flex;flex-direction:column;gap:4px}
.town:hover,.town:focus-visible{box-shadow:var(--edge);background:var(--bg)}
.town.here{box-shadow:var(--edge)}
.town svg{width:40px;height:40px;image-rendering:pixelated}
.town .sub{color:var(--dim)}
.stars{color:var(--gold);letter-spacing:4px}
.stars .off{color:var(--faint)}
#worldMsg{white-space:pre-line;color:var(--dim)}


/* ---------- battle: a classic console RPG ---------- */
#battle{background:var(--page) var(--sky) 0 0/128px 128px;align-items:center}
#battle .panel{width:min(100%,920px);background:none;box-shadow:none;padding:0;margin:0;overflow:visible;
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);grid-template-areas:"arena arena" "msg cmd" "prompt cmd";gap:24px 28px;align-items:start}
.arena{grid-area:arena;position:relative;height:clamp(280px,44vh,380px);border-bottom:2px solid var(--nes-blue)}
#foeCv{position:absolute;left:calc(50% - 112px);bottom:8px;width:224px;height:224px;image-rendering:pixelated;animation:bob 1.2s steps(2) infinite}
#foeCv.hit{animation:shake .3s steps(3)}
@keyframes bob{50%{transform:translateY(-8px)}}
@keyframes shake{33%{transform:translateX(-12px)}66%{transform:translateX(12px)}}
.plate{position:absolute;background:var(--bg);padding:8px 16px 10px;box-shadow:var(--edge);min-width:210px;margin:2px}
.plate .bar,.plate .cups{margin-top:6px;display:block}
.plate small{display:block;color:var(--dim);font-size:16px}
#foePlate{right:6px;top:6px}
#heroPlate{left:6px;top:6px}
#heroPlate .lv{color:var(--gold)}
#foePlate #foeSub{color:var(--drift)}
#foeName{color:var(--fg)}
#intentTag{position:absolute;left:6px;bottom:12px;background:var(--nes-green);color:var(--nes-black);padding:0 12px;box-shadow:var(--edge-ok)}
#pendingTag{position:absolute;right:6px;bottom:12px;background:var(--nes-ice);color:var(--nes-black);padding:0 12px;max-width:60%}
#btext{grid-area:msg;min-height:132px;white-space:pre-line;background:var(--bg);padding:14px 20px;box-shadow:var(--edge);margin:2px;color:var(--fg)}
#moves{grid-area:cmd;display:flex;flex-direction:column;gap:0;background:var(--bg);padding:10px 12px 10px 28px;box-shadow:var(--edge);margin:2px}
#moves button{position:relative;background:none;border:0;padding:2px 8px 2px 4px;color:var(--fg);text-align:left;display:flex;justify-content:space-between;gap:12px;align-items:center}
#moves button:hover:not(:disabled),#moves button:focus-visible{background:var(--nes-white);color:var(--nes-navy)}
#moves button:disabled{color:var(--faint);cursor:not-allowed}
#moves button.fm span:first-child::before{content:"";display:inline-block;width:14px;height:10px;margin-right:8px;background:var(--ic-robot) center/14px 10px no-repeat;image-rendering:pixelated}
.tier{padding:0 6px;color:var(--nes-black);white-space:nowrap;flex:none;background:var(--nes-light)}
/* Tiers say their name in words; the fill only helps. Red is DENY's alone. */
.t-AUTO{background:var(--nes-green-light)} .t-NOTIFY{background:var(--nes-sky)} .t-APPROVE{background:var(--nes-white)} .t-TWO_PERSON{background:var(--nes-lavender);box-shadow:0 0 0 2px var(--nes-white);margin:0 2px}
.t-DENY{background:var(--nes-red);color:var(--nes-white)} .t-ASK{background:var(--nes-light);color:var(--nes-black)}
@media (max-width:760px){
  #battle{align-items:flex-start}
  #battle .panel{grid-template-columns:minmax(0,1fr);grid-template-areas:"arena" "msg" "prompt" "cmd";gap:20px}
  /* The battle stacks: foe, monster, you. Nothing overlaps at any width. */
  .arena{height:auto;display:flex;flex-direction:column;align-items:stretch;gap:12px;padding-bottom:12px}
  .arena .plate,.arena #foeCv,.arena #intentTag,.arena #pendingTag{position:static;margin:0}
  .arena #foePlate{order:1} .arena #foeCv{order:2;align-self:center} .arena #heroPlate{order:3}
  .arena #intentTag{order:4;align-self:flex-start} .arena #pendingTag{order:5;max-width:none}
  #foeCv{width:192px;height:192px}
  .plate{min-width:0;padding:6px 12px 8px}
  #btext{min-height:96px}
}
@media (prefers-reduced-motion:reduce){#foeCv{animation:none}#dmore{animation:none}}

/* ---------- touch controls: a plus-shaped pad and an A button ---------- */
#pad{display:none;justify-content:space-between;align-items:center;padding:8px 24px 14px}
@media (pointer:coarse){#pad{display:flex}}
.dpad{display:grid;grid-template-columns:repeat(3,52px);grid-template-rows:repeat(3,52px)}
.dpad button,.abtn{background:var(--bg);border:0;box-shadow:var(--edge);font-size:24px;line-height:24px;padding:0}
.dpad button:active,.abtn:active{background:var(--nes-white);color:var(--nes-navy)}
.abtn{width:68px;height:68px;margin:4px}
#menuFields{white-space:pre-wrap;background:var(--bg);padding:10px 12px;max-height:220px;overflow:auto;color:var(--dim);box-shadow:var(--edge-dim);margin:2px}

/* ---------- badges, the journal, the gate desk ---------- */
#badgePop{position:fixed;top:calc(20px + env(safe-area-inset-top,0px));left:50%;z-index:40;display:flex;align-items:center;gap:16px;
  background:var(--bg);padding:10px 20px 10px 16px;box-shadow:var(--edge-gold);
  transform:translate(-50%,-260%);visibility:hidden;transition:transform .35s steps(5);pointer-events:none;max-width:92vw}
#badgePop.show{transform:translate(-50%,0);visibility:visible}
#badgePop svg{width:40px;height:50px;flex:none;image-rendering:pixelated}
#badgePop small{display:block;color:var(--gold)}
@media (prefers-reduced-motion:reduce){#badgePop{transition:none}}
.tabs{display:flex;gap:4px 20px;margin:8px 0 16px;flex-wrap:wrap;padding-left:16px}
/* Six tabs now: a wider journal window keeps them on one row (they still wrap on a phone). */
#journal .panel{width:min(100%,760px)}
.tabs button{position:relative;background:none;border:0;padding:2px 8px 2px 4px;color:var(--dim)}
.tabs button:hover,.tabs button:focus-visible{background:var(--nes-white);color:var(--nes-navy)}
.tabs button[aria-selected=true]{color:var(--fg);box-shadow:0 2px 0 0 var(--nes-white)}
.tabs button[aria-selected=true]:hover,.tabs button[aria-selected=true]:focus-visible{color:var(--nes-navy)}
.rankcard{display:flex;gap:20px;align-items:center;background:var(--bg);padding:12px 16px;margin:8px 2px 16px;box-shadow:var(--edge-dim)}
.rankcard .lv{font-size:40px;line-height:40px;color:var(--gold);text-shadow:4px 4px 0 var(--nes-black)}
.rankcard .bar{--segs:20;--seg:6px;--gap:2px;margin:6px 0 4px}
.rankcard .grow{flex:1;min-width:0}
.rankcard small{color:var(--dim)}
.stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr));gap:12px;margin:0 2px 8px}
.stats div{background:var(--bg);padding:8px 12px;box-shadow:var(--edge-dim)}
.stats b{display:block;font-size:24px;line-height:32px;color:var(--fg)}
.stats span{color:var(--dim)}
#badgeGrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(184px,1fr));gap:14px;margin:0 2px}
.badge{background:var(--bg);padding:10px 12px;display:flex;gap:12px;align-items:flex-start;box-shadow:var(--edge-dim)}
.badge svg{width:32px;height:40px;flex:none;image-rendering:pixelated}
.badge b{display:block;color:var(--fg)}
.badge span{display:block;color:var(--dim);line-height:20px}
.badge.locked b{color:var(--faint)}
.badge .bar{--segs:10;--seg:6px;--gap:2px;--fill:var(--nes-light);margin-top:8px}
.qlist{list-style:none;margin:0 2px;padding:0;display:flex;flex-direction:column;gap:12px}
.qlist li{background:var(--bg);padding:10px 14px;display:flex;gap:12px;box-shadow:var(--edge-dim)}
.qlist li .m{flex:none;width:16px;color:var(--faint)}
.qlist li.done .m{color:var(--ok)}
.qlist li.now{box-shadow:var(--edge)}
.qlist li.now .m{color:var(--fg)}
.qlist li.lock{color:var(--faint)}
.qlist li.lock small{color:var(--faint)}
.qlist small{display:block;color:var(--dim)}
.gatepanel{width:min(100%,680px)!important}
.gatehead{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
#gStatus{color:var(--dim);white-space:pre}
.ticket{position:relative;background:var(--bg);color:var(--fg);padding:14px 18px;margin:16px 2px;box-shadow:var(--edge)}
.ticket h3{margin:0 0 10px;font-size:16px;color:var(--fg);padding-right:150px}
.ticket dl{display:grid;grid-template-columns:auto 1fr;gap:4px 16px;margin:0}
.ticket dt{color:var(--dim)}
.ticket dd{margin:0}
.ticket .why{margin:10px 0 0;color:var(--dim)}
.who-tag{padding:0 6px;margin-left:8px;background:var(--nes-indigo);color:var(--nes-white)}
.who-tag.agent{background:var(--nes-aqua);color:var(--nes-black)}
/* The decision stamp: a plain block, no tilt. */
.stamp{position:absolute;right:14px;top:12px;padding:0 12px;background:var(--bg);box-shadow:var(--edge)}
.stamp.approve{color:var(--ok);box-shadow:var(--edge-ok)} .stamp.deny{color:var(--drift);box-shadow:var(--edge-drift)} .stamp.flag{color:var(--fg)} .stamp.expired{color:var(--dim);box-shadow:var(--edge-dim)}
.gtimer{height:8px;background:var(--nes-black);box-shadow:0 0 0 2px var(--nes-black);margin:16px 2px}
.gtimer i{display:block;height:100%;background:var(--nes-sky);width:100%}
.gbtns{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:0 2px}
.gbtns button{position:relative;border:0;padding:8px 6px 8px 22px;color:var(--fg);background:var(--bg);box-shadow:var(--edge)}
.gbtns button:active{transform:translateY(2px)}
.g-approve{box-shadow:var(--edge-ok)!important} .g-approve:hover,.g-approve:focus-visible{background:var(--nes-green-light)!important;color:var(--nes-black)!important}
.g-deny{box-shadow:var(--edge-drift)!important} .g-deny:hover,.g-deny:focus-visible{background:var(--nes-red)!important;color:var(--nes-white)!important}
.g-flag:hover,.g-flag:focus-visible{background:var(--nes-white)!important;color:var(--nes-navy)!important}
.gbtns small{display:block;color:var(--dim);line-height:16px}
.gbtns button:hover small,.gbtns button:focus-visible small{color:inherit}
.verdict{font-size:24px;line-height:32px;margin:8px 2px 4px} .verdict.ok{color:var(--ok)} .verdict.bad{color:var(--drift)} .verdict.meh{color:var(--dim)}
.rulebox{background:var(--bg);padding:10px 14px;margin:12px 2px 4px;box-shadow:var(--edge-dim)}
.grade{font-size:64px;line-height:64px;color:var(--gold);text-shadow:4px 4px 0 var(--nes-black);margin:8px 0}
.brief{margin:8px 0;padding-left:24px}
.brief li{margin:8px 0}
.audit{background:var(--bg);padding:10px 12px;white-space:pre-wrap;max-height:50vh;overflow:auto;color:var(--dim);box-shadow:var(--edge-dim);margin:2px;font-family:var(--font-mono);-webkit-user-select:text;user-select:text}
.audit b{color:var(--fg)}
.booking-link{color:var(--nes-white);text-decoration:underline;display:inline-block;padding:12px}
.ok-text{color:var(--ok)} .gold-text{color:var(--gold)}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
.panel h3.first{margin-top:0}
.audit-row{margin-bottom:8px}
.fg-text{color:var(--fg)!important}
.hint.keys{margin-top:12px}

/* ---------- small screens and touch ---------- */
@media (max-width:560px){
  /* A tidy grid: the location on top, then Travel, Journal and Menu in one row, the vending label on its own row, then the meters. */
  #hud{display:grid;grid-template-columns:repeat(3,auto);justify-content:start;column-gap:12px;row-gap:0;padding:6px 10px 6px 14px}
  #hud::after{display:none}
  #loc{grid-column:1/-1;font-size:16px;line-height:24px;max-width:none}
  #hud .hudbtn{flex:none;text-align:left;padding:2px 4px 2px 20px;--cx:2px;white-space:nowrap}
  #vendingBtn{grid-column:1/-1;justify-self:start}
  #hud .stat:not(#lvlStat):not(#coffeeStat){grid-column:1/3}
  #coffeeStat{grid-column:1/-1}
  .stat{gap:6px}
  #hud .bar{--seg:5px;--gap:1px}
  #hud .cups{--cw:9px;--ch:7px}
  #tokenbar,#questbar{padding-left:14px}
  #stage{padding:10px 8px}
  #toast{top:8px;padding:2px 10px}
  .panel{padding:18px 16px}
  .overlay{padding:16px 12px}
}
@media (pointer:coarse){
  .choice,#moves button,.tabs button,.hudbtn,.gbtns button,.big,.town{min-height:44px}
  .choice,#moves button,.tabs button,.hudbtn{display:inline-flex;align-items:center}
  #moves button{display:flex}
  #dchoices{gap:0 20px}
}
/* Foreman's phone. A light-gray phone with a black screen, drawn as pixel art: the body, the screen and the bubbles are small
   pictures set by theme.ts (--ph-*) and cut into nine pieces with border-image, so the phone stretches to any width without a
   blurry pixel. --px is how many screen pixels one art pixel is (whole numbers only). Slack and Teams are words in a tag: no logos,
   no brand colors. Red is the Deny button's alone, the same as the gate desk's. */
#phone{position:fixed;inset:0;z-index:35;display:flex;align-items:flex-end;justify-content:center;pointer-events:none;
  padding:calc(12px + env(safe-area-inset-top,0px)) 12px calc(12px + env(safe-area-inset-bottom,0px))}
#phone .phone{pointer-events:auto}

.phone{--px:2px;--bpx:2px;position:relative;display:flex;flex-direction:column;min-height:0;width:100%;max-width:420px;max-height:100%;
  border:solid transparent;border-width:calc(8 * var(--px));border-image:var(--ph-body) 8 fill / calc(8 * var(--px)) stretch;
  image-rendering:pixelated;font-family:var(--font);font-size:calc(16px * var(--text-scale,1));line-height:24px;color:var(--nes-white);
  box-shadow:0 0 0 4px var(--nes-black)}
.phone-speaker,.phone-home{position:absolute;left:50%;image-rendering:pixelated;background-repeat:no-repeat;background-size:100% 100%}
.phone-speaker{top:calc(-5 * var(--px));width:24px;height:8px;margin-left:-12px;background-image:var(--ph-speaker)}
.phone-home{bottom:calc(-6 * var(--px));width:16px;height:16px;margin-left:-8px;background-image:var(--ph-home)}
.phone-screen{display:flex;flex-direction:column;flex:1;min-height:0;padding:2px 2px 6px;
  border:solid transparent;border-width:calc(3 * var(--px));border-image:var(--ph-screen) 3 fill / calc(3 * var(--px)) stretch}
/* One header row: the avatar, who is writing, and the channel as a word in a tag (the same plain tag for Slack and Teams). */
.phone-head{display:flex;align-items:center;gap:8px;padding:2px 6px 6px;box-shadow:0 2px 0 0 var(--nes-dark)}
.phone-chan{flex:none;margin-left:auto;padding:0 8px;background:var(--nes-light);color:var(--nes-black)}
.phone-avatar{flex:none;width:32px;height:32px;background:var(--nes-black);box-shadow:0 0 0 2px var(--nes-sky)}
.phone-avatar svg{display:block;width:100%;height:100%;image-rendering:pixelated}
.phone-who{display:flex;flex-direction:column;line-height:18px}
.phone-who b{color:var(--nes-white)}
.phone-who small{color:var(--dim);font-size:16px}

.phone-thread{flex:1;min-height:0;overflow:auto;padding:6px 4px 4px;display:flex;flex-direction:column;gap:6px}
.bub{--bpx:2px;--fill:var(--ph-bubble-fm);position:relative;max-width:100%;color:var(--nes-black);
  border:solid transparent;border-width:calc(4 * var(--bpx));border-image:var(--fill) 4 fill / calc(4 * var(--bpx)) stretch;image-rendering:pixelated}
.bub-you{--fill:var(--ph-bubble-you);align-self:flex-end;max-width:88%}
.bub-co{--fill:var(--ph-bubble-co)}
.bub p,.panel .bub p{margin:0 0 6px;color:var(--nes-black);line-height:20px}
.bub p:last-child,.panel .bub p:last-child{margin-bottom:0}
.bub-from{display:block;color:var(--nes-black);margin-bottom:2px}
/* The impact is the line you are agreeing to, so it gets a bar down its side. */
.bub .part-impact{padding-left:8px;box-shadow:inset 4px 0 0 0 var(--nes-navy)}

.phone-actions{display:flex;gap:12px;padding:6px 4px 0}
.phone-btn{position:relative;flex:1;min-height:48px;padding:8px 10px;border:0;background:var(--bg);color:var(--fg);box-shadow:var(--edge);font-family:var(--font);font-size:inherit;text-align:center}
.phone-btn:hover,.phone-btn:focus-visible{background:var(--nes-white);color:var(--nes-navy)}
.phone-btn:active{transform:translateY(2px)}
.phone-approve{box-shadow:var(--edge-ok)}
.phone-approve:hover,.phone-approve:focus-visible{background:var(--nes-green-light);color:var(--nes-black)}
/* Deny is the one red on the phone: danger and DENY are what red says. */
.phone-deny{box-shadow:var(--edge-drift)}
.phone-deny:hover,.phone-deny:focus-visible{background:var(--nes-red);color:var(--nes-white)}
.phone-ok{box-shadow:var(--edge-ok)}
.phone-ok:hover,.phone-ok:focus-visible{background:var(--nes-green-light);color:var(--nes-black)}
.phone-hint{margin:2px 6px 0;color:var(--dim);font-size:16px;line-height:20px;text-align:center}

/* The notice when a coworker answers: a small strip near the top with a phone beside it. */
/* It sits under the badge pop (which is at the very top), so a badge that fires with the reply never covers it. */
#phoneNote{position:fixed;z-index:36;top:calc(92px + env(safe-area-inset-top,0px));left:50%;transform:translateX(-50%);width:min(92vw,400px);
  pointer-events:none;background:var(--bg);color:var(--fg);padding:8px 14px 8px 52px;box-shadow:var(--edge)}
#phoneNote::before{content:"";position:absolute;left:14px;top:10px;width:27px;height:36px;background:var(--ic-phone) center/100% 100% no-repeat;image-rendering:pixelated}
#phoneNote b{display:block;color:var(--dim)}
#phoneNote span{display:block}
#phoneNote small{display:block;color:var(--dim);font-size:16px}

/* Sliding up, a short buzz, and sliding away. Reduced motion stops every animation (styles.css), so the phone just appears. */
.phone.enter{animation:phone-up .32s steps(8) both,phone-buzz .3s steps(4) .32s}
.phone.leave{animation:phone-down .25s steps(5) both}
@keyframes phone-up{from{transform:translateY(calc(100% + 40px))}to{transform:none}}
@keyframes phone-down{from{transform:none}to{transform:translateY(calc(100% + 40px))}}
@keyframes phone-buzz{25%{transform:translateX(-4px)}50%{transform:translateX(4px)}75%{transform:translateX(-2px)}}

/* A desktop phone is a phone-sized card low at the right of the screen, over the battle; a small screen gets it nearly full width as a sheet.
   Either way it never takes more than about two thirds of the height: a long message scrolls inside, and the buttons stay in view. */
@media (min-width:761px){
  #phone{justify-content:flex-end;padding-right:max(24px,calc(50vw - 480px))}
  .phone{--px:2px;width:340px;max-height:68%}
}
@media (max-width:760px){
  #phoneNote{top:calc(124px + env(safe-area-inset-top,0px))} /* the badge pop wraps to more lines on a narrow screen */
  #phone{padding-left:8px;padding-right:8px}
  .phone{max-width:none;max-height:68%}
}

/* The Journal's Messages tab: each exchange with Foreman is a card of the same bubbles. */
.msg-ic{display:inline-block;width:18px;height:24px;margin-right:10px;vertical-align:-6px;background:var(--ic-phone) center/100% 100% no-repeat;image-rendering:pixelated}
.msg-list{display:flex;flex-direction:column;gap:16px;margin:0 2px}
.msg-group{background:var(--bg);padding:12px 14px;box-shadow:var(--edge-dim);display:flex;flex-direction:column;gap:8px;font-size:calc(16px * var(--text-scale,1))}
.msg-group header{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px}
.msg-group header b{color:var(--fg)}
.msg-tag{padding:0 8px;background:var(--nes-light);color:var(--nes-black)}
.msg-tier{color:var(--dim)}
.panel .msg-meta{margin:0 0 4px;color:var(--dim)}
.msg-group .bub{align-self:flex-start;max-width:100%}
.msg-group .bub-you{align-self:flex-end}
/* The text view of a saved campaign: the same blue windows and the same font as the game, laid out as a page on black.
   Long-form text stays at 16px or larger (the font is drawn on an 8px grid, so it is crispest at 16, 24 and 32). */
.account{position:fixed;inset:0;z-index:100;background:var(--nes-black);color:var(--nes-white);overflow:auto;padding:32px max(24px,calc((100vw - 1100px)/2));
  font-family:"Smplify 8",ui-monospace,Menlo,Consolas,monospace;font-weight:400;font-synthesis:none;line-height:26px;font-size:calc(16px * var(--text-scale,1))}
.account.hidden{display:none}
.account h1{font-size:32px;line-height:40px;font-weight:400;color:var(--nes-white);margin:0;text-shadow:4px 4px 0 var(--nes-navy)}
.account h2{font-size:24px;line-height:32px;font-weight:400;margin:0 0 12px}
.account h3{font-size:16px;font-weight:400;color:var(--nes-ice)}
.account-row{display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;margin:16px 0}
.account-row span{background:var(--nes-navy);padding:8px 16px;box-shadow:0 -2px 0 0 var(--nes-sky),0 2px 0 0 var(--nes-sky),-2px 0 0 0 var(--nes-sky),2px 0 0 0 var(--nes-sky)}
.account-card{background:var(--nes-navy);padding:22px 24px;margin:24px 2px;box-shadow:0 -2px 0 0 var(--nes-white),0 2px 0 0 var(--nes-white),-2px 0 0 0 var(--nes-white),2px 0 0 0 var(--nes-white)}
.account-muted{color:var(--nes-ice)}
.account-status{background:var(--nes-navy);padding:14px 18px;min-height:56px;color:var(--nes-white);
  box-shadow:0 -2px 0 0 var(--nes-gold),0 2px 0 0 var(--nes-gold),-2px 0 0 0 var(--nes-gold),2px 0 0 0 var(--nes-gold);margin:4px 2px}
.account button{font:inherit;border:0;border-radius:0;background:var(--nes-navy);color:var(--nes-white);padding:8px 18px;cursor:pointer;margin:6px;
  box-shadow:0 -2px 0 0 var(--nes-white),0 2px 0 0 var(--nes-white),-2px 0 0 0 var(--nes-white),2px 0 0 0 var(--nes-white)}
.account button:hover{background:var(--nes-white);color:var(--nes-navy)}
.account button:focus-visible{outline:2px solid var(--nes-white);outline-offset:4px;background:var(--nes-white);color:var(--nes-navy)}
.account button:disabled{background:var(--nes-gray);color:var(--nes-black);cursor:wait;box-shadow:none}
.account button.secondary{background:var(--nes-navy)}
.account button.selected{color:var(--nes-gold);box-shadow:0 -2px 0 0 var(--nes-gold),0 2px 0 0 var(--nes-gold),-2px 0 0 0 var(--nes-gold),2px 0 0 0 var(--nes-gold)}
.account button.selected:hover,.account button.selected:focus-visible{color:var(--nes-black);background:var(--nes-gold)}
.account-issue{display:flex;justify-content:space-between;gap:16px;align-items:center;box-shadow:0 -2px 0 0 var(--nes-sky);padding:14px 0;margin-top:2px}
.account input,.account select,.account textarea{font:inherit;background:var(--nes-navy);border:0;color:var(--nes-white);padding:8px 12px;max-width:100%;border-radius:0;
  box-shadow:0 -2px 0 0 var(--nes-sky),0 2px 0 0 var(--nes-sky),-2px 0 0 0 var(--nes-sky),2px 0 0 0 var(--nes-sky)}
.account input:focus,.account select:focus,.account textarea:focus{outline:2px solid var(--nes-white);outline-offset:2px}
.account label{display:block;margin:12px 0}
.account small{display:block;color:var(--nes-ice)}
.account a{color:var(--nes-white)}
.account a:focus-visible{outline:2px solid var(--nes-white);outline-offset:4px}
.booking-link{color:var(--nes-white)}
@media(max-width:600px){.account{padding:20px 14px}.account-card{padding:16px}.account-issue{align-items:flex-start;flex-direction:column}.account h1{font-size:24px;line-height:32px}}
/* Foreman's message in the text view (the same three parts the phone shows). */
.account-foreman{margin:12px 0;padding:6px 16px;box-shadow:0 -2px 0 0 var(--nes-sky),0 2px 0 0 var(--nes-sky),-2px 0 0 0 var(--nes-sky),2px 0 0 0 var(--nes-sky)}
.account-foreman h3{margin:8px 0}
.account-foreman p{margin:8px 0}
/* Server mode: the small "Saving…" note while the server is slow to answer. */
#saving{position:absolute;right:12px;bottom:12px;z-index:6;background:var(--bg);color:var(--fg);padding:2px 12px;font-family:var(--font);box-shadow:var(--edge-dim);pointer-events:none}
/* Keyboard play (MAR-15): the skip link, the map's focus frame, key hints beside buttons, and the Controls screen.
   Same palette and same windows as the rest of the game. Focus is never color alone: it is an outline or the ▶ cursor. */

/* ---------- Tab order: skip link, the game, the HUD buttons ----------
   focus.ts moves the map first in the page so Tab reaches it before the HUD; these orders keep it looking as it did. */
#app>#hud{order:1}
#app>#tokenbar{order:2}
#app>#questbar{order:3}
#app>#stage{order:4}
#app>#pad{order:5}

.skip{position:fixed;left:12px;top:-80px;z-index:60;padding:6px 16px;background:var(--nes-white);color:var(--nes-navy);text-decoration:none;box-shadow:var(--win)}
.skip:focus,.skip:focus-visible{top:12px;outline:2px solid var(--nes-white);outline-offset:6px}

/* The map takes focus. Its window edge is already 2px white and 2px black, so the frame stands 6px out, where it can be seen. */
#cv:focus{outline:0}
#cv:focus-visible{outline:4px solid var(--nes-white);outline-offset:6px}
#questbar:focus-visible{background:var(--nes-white);color:var(--nes-navy);outline-offset:-2px}
#questbar:focus-visible span{color:var(--nes-navy)}
.ticket:focus-visible,#dialog:focus-visible{outline-offset:4px}

/* ---------- key hints ----------
   A small key name beside a button that has a key of its own. Desktops always show them; a touch screen shows them
   once a key has been pressed (focus.ts adds .using-keys). Screen readers get aria-keyshortcuts instead. */
[data-key]::after{content:"[" attr(data-key) "]";content:"[" attr(data-key) "]" / "";margin-left:10px;color:var(--dim);white-space:nowrap}
.choice:hover[data-key]::after,.choice:focus-visible[data-key]::after,.big:hover[data-key]::after,.big:focus-visible[data-key]::after{color:inherit}
#moves button[data-key]::after{order:-1;margin:0 10px 0 0;min-width:3ch}
#moves button[data-key]>span:first-child{flex:1}
#moves button[data-key]:hover:not(:disabled)::after,#moves button[data-key]:focus-visible::after{color:inherit}
#moves button:disabled[data-key]::after{color:inherit}
.town[data-key]::after{position:absolute;right:10px;top:8px;margin:0}
@media (pointer:coarse) and (hover:none){
  body:not(.using-keys) [data-key]::after{content:none}
}
.keyhint{color:var(--dim);margin:0}
#bkeys{grid-area:keys;padding:0 4px}
#battle .panel.has-keys{grid-template-areas:"arena arena" "msg cmd" "prompt cmd" "keys keys"}
@media (max-width:760px){#battle .panel.has-keys{grid-template-areas:"arena" "msg" "prompt" "cmd" "keys"}}
@media (pointer:coarse) and (hover:none){body:not(.using-keys) #bkeys{display:none}}

/* ---------- the Controls screen ---------- */
.controls{width:min(100%,860px)}
.controls .intro{margin-top:0}
.controls dl{margin:0 2px 8px;display:flex;flex-direction:column;gap:10px}
.controls dl>div{display:grid;grid-template-columns:minmax(220px,300px) minmax(0,1fr);gap:4px 20px;align-items:baseline;padding:8px 12px;background:var(--bg);box-shadow:var(--edge-dim)}
.controls dt{margin:0;color:var(--fg);display:flex;flex-wrap:wrap;gap:6px 8px;align-items:baseline}
.controls dd{margin:0;color:var(--dim)}
.controls kbd{font-family:var(--font);display:inline-block;min-width:24px;padding:0 8px;background:var(--nes-white);color:var(--nes-navy);text-align:center;box-shadow:0 2px 0 0 var(--nes-light)}
.controls .or{color:var(--dim)}
.controls h2:focus-visible{outline-offset:4px}
@media (max-width:560px){.controls dl>div{grid-template-columns:minmax(0,1fr)}}
/* The in-world rewards UX: the HUD pointer, the Supply Closet, the final mission and the journal's newer tabs.
   Same windows as the rest of the game: deep blue fill, a 2px white edge with notched corners. Gold is for tokens. */
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

#tokenNext{background:none;border:0;padding:4px 0;color:var(--dim);text-decoration:underline dotted;text-underline-offset:4px}
#tokenNext:hover,#tokenNext:focus-visible{color:var(--nes-navy);background:var(--nes-white);text-decoration:none}

.closet,.finale{width:min(100%,700px);font-family:var(--font)}
.closet{width:min(100%,1040px)}
input,textarea{font-family:var(--font)}
.panel p.closet-banner{background:var(--bg);color:var(--fg);padding:8px 14px;box-shadow:var(--edge-dim);margin-left:2px;margin-right:2px}
.panel p.closet-next,.panel p.vm-prize{color:var(--gold)}
.panel .closet-notice,.panel .finale-status{color:var(--ok);min-height:1em}
.panel .closet-notice.bad,.panel .finale-status.bad{color:var(--drift)}
.closet-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px}

/* ---------- the vending machine ----------
   A cabinet, a glass window with a coil and a goodie in every slot, a side panel with the display, the coin slot and the keypad's
   button, and a tray. The frames are small pixel pictures set by theme.ts (--vm-*) and cut into nine pieces with border-image, so
   the machine stretches to any width without a blurry pixel. --px is how many screen pixels one art pixel is: whole numbers only. */
.closet-top{display:flex;margin:0 0 16px 2px}
.closet .big{min-height:44px}
.closet-wrap{display:grid;grid-template-columns:minmax(0,1fr);gap:24px;align-items:start}
.closet-info{min-width:0}
.closet-info>*:first-child{margin-top:0}
.vm{--px:3px;min-width:0}
.pic{display:inline-block;line-height:0;flex:none}
.pic svg{display:block;width:100%;height:100%;image-rendering:pixelated}
.vm-cabinet{display:grid;grid-template-columns:minmax(0,1fr);gap:calc(3 * var(--px));padding:calc(1 * var(--px));
  border:solid transparent;border-width:calc(6 * var(--px));border-image:var(--vm-cabinet) 6 fill / calc(6 * var(--px)) stretch}
.panel .vm-sign{display:flex;align-items:center;justify-content:center;gap:12px;margin:0;padding:0 8px;font-size:24px;line-height:32px;color:var(--nes-white);
  border:solid transparent;border-width:calc(4 * var(--px));border-image:var(--vm-sign) 4 fill / calc(4 * var(--px)) stretch;text-shadow:2px 2px 0 var(--nes-navy)}
.vm-sign .vm-token{width:28px;height:28px}
.vm-glass{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));align-content:start;position:relative;min-width:0;
  border:solid transparent;border-width:calc(4 * var(--px));border-image:var(--vm-glass) 4 fill / calc(4 * var(--px)) stretch}
.vm-glass::after{content:"";position:absolute;left:calc(2 * var(--px));top:calc(2 * var(--px));width:calc(8 * var(--px));height:calc(8 * var(--px));background:var(--vm-glint) 0 0 / 100% 100% no-repeat;pointer-events:none;image-rendering:pixelated}
.vm-empty{grid-column:1/-1;margin:16px;color:var(--fg)}

/* a slot: the goodie hangs in its coil, and the plate under it has the slot code and the price */
.vm-slot{position:relative;display:flex;flex-direction:column;align-items:stretch;min-width:0;min-height:44px;padding:calc(5 * var(--px)) calc(1 * var(--px)) 0;
  background:none;border:0;color:var(--fg);font:inherit;text-align:center;cursor:pointer}
.vm-slot:hover{box-shadow:inset 0 0 0 2px var(--nes-sky)}
.vm-slot:focus-visible{outline:2px solid var(--nes-white);outline-offset:-4px}
.vm-slot[aria-pressed=true]{box-shadow:inset 0 0 0 2px var(--nes-white);background:var(--nes-navy)}
.vm-goodie{position:relative;display:block;height:calc(24 * var(--px));margin:0 calc(-1 * var(--px));
  background:var(--vm-coil) repeat-x 0 calc(100% - 3 * var(--px)) / calc(6 * var(--px)) calc(4 * var(--px));image-rendering:pixelated}
.vm-art{position:absolute;left:50%;top:0;width:calc(24 * var(--px));height:calc(24 * var(--px));margin-left:calc(-12 * var(--px))}
.vm-lock{position:absolute;left:50%;top:calc(-2 * var(--px));width:calc(9 * var(--px));height:calc(10 * var(--px));margin-left:calc(3 * var(--px))}
.vm-cursor{position:absolute;left:50%;top:calc(1 * var(--px));width:calc(7 * var(--px));height:calc(4 * var(--px));margin-left:calc(-3.5 * var(--px));visibility:hidden}
.vm-slot:hover .vm-cursor,.vm-slot:focus-visible .vm-cursor,.vm-slot[aria-pressed=true] .vm-cursor{visibility:visible}
.vm-plate{display:flex;flex-direction:column;gap:2px;margin-top:calc(2 * var(--px));padding:2px 4px 4px;background:var(--nes-black);color:var(--nes-white);box-shadow:0 0 0 2px var(--nes-light)}
.vm-row{display:flex;justify-content:space-between;align-items:center;gap:6px}
.vm-price{display:inline-flex;align-items:center;gap:4px;color:var(--gold)}
.vm-price .vm-token{width:14px;height:14px}
.vm-tag{display:flex;align-items:center;justify-content:center;gap:6px;padding:0 2px;text-align:center;overflow-wrap:break-word;background:var(--nes-light);color:var(--nes-black)}
.vm-tag-lock{width:9px;height:10px}
.vm-shelf{display:block;height:calc(4 * var(--px));margin:auto calc(-1 * var(--px)) 0;background:var(--vm-shelf) repeat-x 0 0 / calc(4 * var(--px)) calc(4 * var(--px));image-rendering:pixelated}
/* a locked slot has a dark plate and a padlock; a restocking one has a gray plate and the goodie stays in full color, because showing what you can win is the point of the machine */
.vm-slot.locked .vm-plate{background:var(--nes-dark)}
.vm-slot.locked .vm-price{color:var(--nes-white)}
.vm-slot.soldout .vm-plate{background:var(--nes-gray);color:var(--nes-black)}
/* RESTOCKING SOON is the longest tag. Under about 130px a slot cannot hold RESTOCKING at 16px, so the tag drops to the font's own 8px (still crisp, still one line) instead of breaking a word */
.vm-slot{container-type:inline-size}
@container (max-width:129px){.vm-slot.soldout .vm-tag{font-size:8px;line-height:16px}}
.vm-slot.soldout .vm-price{color:var(--nes-black)}

/* the side panel: the display, the coin slot, and the keypad's button */
.vm-side{display:grid;grid-template-columns:minmax(0,1fr) calc(34 * var(--px));gap:calc(3 * var(--px));align-content:start;min-width:0;
  border:solid transparent;border-width:calc(4 * var(--px));border-image:var(--vm-panel) 4 fill / calc(4 * var(--px)) stretch}
.vm-lcd{display:flex;flex-direction:column;min-width:0;padding:2px 6px;
  border:solid transparent;border-width:calc(3 * var(--px));border-image:var(--vm-lcd) 3 fill / calc(3 * var(--px)) stretch}
.vm-lcd-label{color:var(--dim)}
.panel .vm-lcd-value,.vm-lcd-value{color:var(--gold);font-size:24px;line-height:32px;white-space:nowrap}
.vm-lcd-pick{color:var(--fg);min-height:24px;overflow-wrap:break-word}
.vm-coin{display:flex;flex-direction:column;align-items:center;gap:6px}
.vm-coin-art{width:calc(15 * var(--px));height:calc(22 * var(--px))}
.vm-coin-plate{padding:0 8px;background:var(--nes-black);color:var(--ok);box-shadow:var(--edge-dim);text-align:center}
.vm[data-coin=paused] .vm-coin-plate,.vm[data-coin=display-only] .vm-coin-plate,.vm[data-coin=sign-in] .vm-coin-plate{background:var(--nes-dark);color:var(--nes-white);box-shadow:var(--edge-dim)}
.vm-insert{grid-column:1/-1;min-height:48px;padding:8px 10px 8px 26px;text-align:center}

/* the tray */
.vm-tray{display:flex;align-items:center;gap:12px;min-height:calc(20 * var(--px));padding:4px 12px;overflow:hidden;color:var(--fg);
  border:solid transparent;border-width:calc(5 * var(--px)) calc(3 * var(--px)) calc(3 * var(--px));border-image:var(--vm-tray) 5 3 3 3 fill / calc(5 * var(--px)) calc(3 * var(--px)) calc(3 * var(--px)) stretch}
.panel .vm-tray p{margin:0;color:var(--fg)}
.panel .vm-tray p.closet-notice:not(.bad){color:var(--ok)}
.vm-tray-idle{color:var(--dim)}
.vm-tray-text b{display:block;color:var(--gold)}
.vm-slip{width:calc(12 * var(--px));height:calc(14 * var(--px))}
@keyframes vm-drop{from{transform:translateY(calc(-16 * var(--px)))}to{transform:none}}
@keyframes vm-press{50%{transform:translateY(calc(2 * var(--px)))}}
.vm-animating .vm-slip{animation:vm-drop .5s steps(5) both}
.vm-animating .vm-coin-art{animation:vm-press .5s steps(3) both}

/* the details beside the machine (under it on a phone) */
.vm-detail{padding:12px 16px 4px;margin:2px 2px 16px;box-shadow:var(--edge-dim)}
.panel .vm-facts{color:var(--gold);margin-top:0}
.vm-detail .qlist{margin:0 0 12px;gap:8px}
.vm-detail .qlist li{box-shadow:none;padding:4px 0}

@media (max-width:560px){
  .vm-glass{grid-template-columns:repeat(2,minmax(0,1fr))}
  .panel .vm-sign{font-size:16px;line-height:24px;gap:8px}
  .vm-sign .vm-token{width:14px;height:14px}
  .vm-tray{padding:4px 8px;gap:8px}
}
@media (min-width:900px){
  .vm{--px:4px}
  .closet-wrap{grid-template-columns:minmax(0,700px) minmax(240px,1fr)}
  .vm-cabinet{grid-template-columns:minmax(0,1fr) 216px;grid-template-areas:"sign sign" "glass side" "tray tray"}
  .vm-sign{grid-area:sign}.vm-glass{grid-area:glass}.vm-side{grid-area:side;grid-template-columns:minmax(0,1fr);align-content:start}
  .vm-tray{grid-area:tray}
  .vm-coin{flex-direction:column}
}
.closet-mine{margin-top:8px}
textarea{resize:vertical}
.closet-form .hint,.finale-form .hint{display:block;margin-top:8px}

.speech{background:var(--bg);padding:10px 14px;margin:10px 2px;box-shadow:var(--edge)}
.panel .speech p{margin:4px 0;color:var(--fg)}
.speech b{color:var(--gold)}
.speech b.fm{color:var(--fg)}
.speech b.fm::before{content:"";display:inline-block;width:14px;height:10px;margin-right:8px;background:var(--ic-robot) center/14px 10px no-repeat;image-rendering:pixelated}

a.finale-link{display:inline-block;text-decoration:none}
.panel p.finale-state{color:var(--fg);background:var(--bg);padding:8px 14px;box-shadow:var(--edge-dim);margin-left:2px;margin-right:2px}
.panel p.finale-state.ok{color:var(--ok);box-shadow:var(--edge-ok)}

.badge.secret{box-shadow:var(--edge)}
.badge.secret small{display:block;color:var(--dim);margin-top:4px}

.leaderboard{margin:8px 0 0;padding-left:32px}
.leaderboard li{background:var(--bg);padding:6px 12px;margin:8px 2px;box-shadow:var(--edge-dim)}
.leaderboard span{color:var(--dim)}
#tab-crew input[readonly]{color:var(--fg)}
#tab-crew .stats,#tab-missions .qlist{margin-top:12px}

/* Field notes: the journal's catalogue of Smplify's write-ups (field-notes-ui.ts). A card is a small window with the plate
   number beside the study's name. White and ice type on the blue window; no gold (that is tokens) and no red (danger). */
a.big{display:inline-block;text-decoration:none}
.notes{list-style:none;margin:12px 2px 0;padding:0;display:flex;flex-direction:column;gap:16px}
.note{background:var(--bg);padding:12px 14px;display:flex;gap:16px;box-shadow:var(--edge-dim)}
.note-plate{flex:none;width:72px;text-align:center;color:var(--dim)}
.note-plate small{display:block}
.note-plate b{display:block;font-size:32px;line-height:40px;color:var(--fg);text-shadow:4px 4px 0 var(--nes-black)}
.note-body{flex:1;min-width:0}
.panel h4.note-title{margin:0;font-size:16px;line-height:24px;color:var(--fg);font-weight:400}
.panel p.note-meta{margin:0 0 8px;color:var(--dim)}
.note-new{display:inline-block;padding:0 6px;margin-right:8px;background:var(--nes-indigo);color:var(--nes-white)}
.panel p.note-take{margin:0 0 8px;color:var(--fg)}
.panel p.note-where{margin:0;color:var(--dim)}
.note .row{margin-top:12px}
@media (max-width:560px){
  .note{flex-direction:column;gap:4px}
  .note-plate{width:auto;display:flex;gap:8px;align-items:baseline;text-align:left}
  .note-plate b{font-size:24px;line-height:32px;text-shadow:2px 2px 0 var(--nes-black)}
}
