/* The UI in the board's own pixel art: wooden bars above and below the map,
   parchment cards over it, and buttons that stand up off them, each with the
   board's dark outline and its corners nicked off. Every edge is a whole number
   of the art's pixels (--u), the colours are the board's (RAMP in pixel.js),
   and the words are in a pixel font, at sizes where its pixels land on whole
   screen pixels. The map has the screen: one slim bar above it, one below, and
   a few small cards over it that come and go. */

@font-face {
  font-family: 'Jersey 10';
  font-style: normal;
  font-weight: 400;
  font-display: block; /* a moment of nothing, not a flash of another font */
  src: url(assets/fonts/jersey10-latin.woff2) format('woff2');
}

:root {
  --u: 2px; /* one pixel of the art, as the board shows it at its usual size */
  /* The font's pixel is 3/28 of its size: one, two, three and six screen pixels to each. */
  --f1: 9.3333px;
  --f2: 18.6667px;
  --f3: 28px;
  --f6: 56px;

  --ink: #2a1f28; /* the outline round everything */
  --shadow: rgba(42, 31, 40, 0.38);
  --cream: #fff4d8;

  /* The bars: wood. */
  --wood-0: #462b17;
  --wood-1: #663f22;
  --wood-2: #86582f;
  --wood-3: #a4703d;
  --wood-4: #c08d55;
  --on-wood: #fff1d0;
  --on-wood-muted: #d8b07a;
  --on-wood-faint: #b58553;

  /* The cards: parchment. */
  --paper: #f6e4b6;
  --paper-hi: #fff6dc;
  --paper-lo: #ebcf95;
  --paper-edge: #ddb878;
  --paper-deep: #c99e63;
  --text: #3b2a24;
  --strong: var(--ink);
  --muted: #7a5233;
  --faint: #9d7a52;

  /* What things mean, dark enough to read on parchment... */
  --good: #2f6a2b;
  --bad: #b02c22;
  --warn: #9a6a10;
  --sent: #74439a;
  --ice: #285792;
  /* ...and bright enough on wood. */
  --good-lit: #8fd36b;
  --bad-lit: #ff8f78;
  --sent-lit: #d4adf0;

  /* The production split, in the core's card. */
  --bank: #3974b9;
  --ammo: #cb6a24;
  --upgrade: #4a943b;

  --slot: 46px; /* a build or send button */

  /* An outline a pixel wide with its corners left out, the way pixel art rounds a box. */
  --outline: 0 calc(-1 * var(--u)) 0 var(--ink), 0 var(--u) 0 var(--ink), calc(-1 * var(--u)) 0 0 var(--ink), var(--u) 0 0 var(--ink);
  /* A card's: the outline, and a hard shadow down and to the right. */
  --lift: var(--outline), calc(2 * var(--u)) calc(2 * var(--u)) 0 var(--shadow);
}

* { box-sizing: border-box; }

html { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--wood-0);
  color: var(--on-wood);
  font: 400 var(--f2) / 20px 'Jersey 10', system-ui, sans-serif;
  font-synthesis: none; /* a pixel font has no bold: emphasis is colour */
  -webkit-font-smoothing: none;
  overscroll-behavior: none; /* no pull-to-refresh or bounce under a drag */
  touch-action: manipulation; /* and no double-tap zoom on the buttons */
}

/* Nothing in the game is text to select, least of all under a long press. */
#app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

.hidden { display: none !important; }
.spacer { flex: 1; }
b, strong, h1, h2, h3, h4 { font-weight: 400; }
.dim { color: var(--muted); }
.good, .c-good { color: var(--good); }
.bad, .c-bad { color: var(--bad); }
.c-ice { color: var(--ice); }
.c-sent { color: var(--sent); }
img.ic { width: 20px; height: 20px; vertical-align: -5px; }
svg.gl { display: inline-block; vertical-align: 0; overflow: visible; }

kbd {
  display: inline-block; min-width: 14px; padding: 0 3px 1px; margin: 0 1px;
  font: var(--f2) / 16px 'Jersey 10', monospace; text-align: center;
  color: var(--ink); background: var(--paper-lo);
  box-shadow: inset 0 calc(-1 * var(--u)) 0 var(--paper-deep), var(--outline);
}

/* ---- Buttons: a block of colour that stands up off what it's on ---- */
/* Its face, lit along the top and shaded along the bottom, in the outline, which
   is thicker underneath: pressed, it sinks into it. Each kind sets the colours. */

button {
  --face: var(--wood-3); --hi: var(--wood-4); --lo: var(--wood-2); --fg: var(--on-wood); --fg-shadow: var(--wood-1);
  position: relative;
  font: inherit;
  line-height: 20px;
  color: var(--fg);
  text-shadow: 0 var(--u) 0 var(--fg-shadow);
  background: var(--face);
  border: 0;
  border-radius: 0;
  padding: 5px 11px 7px;
  cursor: pointer;
  box-shadow:
    inset 0 var(--u) 0 var(--hi), inset 0 calc(-1 * var(--u)) 0 var(--lo),
    0 calc(-1 * var(--u)) 0 var(--ink), calc(-1 * var(--u)) 0 0 var(--ink), var(--u) 0 0 var(--ink), 0 calc(2 * var(--u)) 0 var(--ink);
}
@media (hover: hover) { button:hover:not(:disabled) { background-image: linear-gradient(rgba(255, 246, 220, 0.16), rgba(255, 246, 220, 0.16)); } }
button:active:not(:disabled) {
  transform: translateY(var(--u));
  box-shadow:
    inset 0 var(--u) 0 var(--lo),
    0 calc(-1 * var(--u)) 0 var(--ink), calc(-1 * var(--u)) 0 0 var(--ink), var(--u) 0 0 var(--ink), 0 var(--u) 0 var(--ink);
}
button:disabled { cursor: default; opacity: 0.5; }
button:focus-visible { outline: var(--u) solid var(--cream); outline-offset: calc(3 * var(--u)); }

/* Go: the main thing to press. */
button.primary { --face: #5aa646; --hi: #76bd57; --lo: #3c7f32; --fg: #fff; --fg-shadow: #2f6a2b; padding: 7px 22px 9px; font-size: var(--f3); line-height: 28px; }
/* Look here: something wants you (paused, your opponent is ready, are you sure). */
button.attn { --face: #edc548; --hi: #f8e28c; --lo: #d6a21f; --fg: var(--ink); --fg-shadow: transparent; }
/* Picked: the tool in hand, the level chosen, the overlay that's open. */
button.on, button.active { --face: #f8e28c; --hi: #fff3c4; --lo: #edc548; --fg: var(--ink); --fg-shadow: transparent; }

/* A cost, or anything else counted in items: a picture and a number. */
.cost { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cost img { width: 18px; height: 18px; }
.cost.short { color: var(--bad); }

/* A sunken well in a bar, for what's read rather than pressed. */
.well {
  background: var(--wood-0);
  box-shadow: inset 0 var(--u) 0 var(--ink), inset 0 calc(-1 * var(--u)) 0 var(--wood-2);
  clip-path: polygon(var(--u) 0, calc(100% - var(--u)) 0, 100% var(--u), 100% calc(100% - var(--u)), calc(100% - var(--u)) 100%, var(--u) 100%, 0 calc(100% - var(--u)), 0 var(--u));
}

/* ---- The bars: planks, lit along the top and outlined against the map ---- */

#topbar, #bar {
  background-color: var(--wood-1);
  background-image:
    repeating-linear-gradient(90deg, transparent 0 calc(100% / 7 - var(--u)), rgba(42, 31, 40, 0.28) 0 calc(100% / 7)),
    linear-gradient(transparent 0 46%, rgba(255, 235, 200, 0.05) 46% 54%, transparent 54%);
}

/* ---- Top bar: how the match stands ---- */

#topbar {
  flex: none; position: relative; z-index: 2;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
  padding: max(8px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 10px max(12px, env(safe-area-inset-left));
  box-shadow: inset 0 calc(-2 * var(--u)) 0 var(--wood-0), 0 var(--u) 0 var(--ink), 0 calc(3 * var(--u)) 0 var(--shadow);
}
#topbar button { height: 32px; padding-top: 4px; padding-bottom: 6px; }

#wave { display: flex; align-items: center; gap: 10px; min-width: 0; max-width: 100%; }
#wave-what { /* where there isn't room for the whole wave, its last few enemies are cut off: its card has them all */
  display: flex; align-items: center; gap: 12px; min-width: 0; height: 32px; padding: 0 10px 0 4px; overflow: hidden; cursor: default;
}
#wave-info { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; overflow: hidden; }
#wave-time, #btn-wave { flex: none; }
.wv-n {
  flex: none; padding: 1px 7px 3px; color: var(--on-wood); background: var(--wood-2);
  box-shadow: inset 0 var(--u) 0 var(--wood-3), inset 0 calc(-1 * var(--u)) 0 var(--wood-1);
}
#wave.live .wv-n { background: #a62a21; color: #fff; box-shadow: inset 0 var(--u) 0 #c93f32, inset 0 calc(-1 * var(--u)) 0 #801e1a; }
.wv-name { color: var(--on-wood); margin-right: 2px; }
#wave.boss .wv-name { color: var(--bad-lit); }
.chip { display: inline-flex; align-items: center; gap: 1px; font-variant-numeric: tabular-nums; }
.chip img { width: 22px; height: 22px; }
.chip.new { padding: 0 5px 0 1px; box-shadow: inset 0 0 0 var(--u) #edc548; }
.mod { padding: 0 6px 2px; white-space: nowrap; background: #74439a; color: #fff; box-shadow: inset 0 calc(-1 * var(--u)) 0 #583177; }
#wave-time { color: var(--on-wood-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
#wave-time b { color: var(--on-wood); }
#btn-wave { --face: #5aa646; --hi: #76bd57; --lo: #3c7f32; --fg: #fff; --fg-shadow: #2f6a2b; padding: 0 12px; }
/* Online the button is a vote: yours is in, or theirs is and yours isn't yet. */
#btn-wave.done { --face: var(--wood-2); --hi: var(--wood-3); --lo: var(--wood-1); --fg: var(--on-wood-muted); --fg-shadow: transparent; }
#btn-wave.attn { --face: #edc548; --hi: #f8e28c; --lo: #d6a21f; --fg: var(--ink); --fg-shadow: transparent; }
#btn-wave .gl { vertical-align: 1px; margin-left: 2px; }
#app.online #btn-pause, #app.online #btn-speed { display: none; }
#app.sandbox #btn-view, #app.sandbox #lives .opp { display: none; } /* nobody else is here */
#btn-round-prev, #btn-round-next { flex: none; min-width: 30px; padding: 0 9px; }

#lives { display: flex; align-items: center; gap: 18px; white-space: nowrap; font-variant-numeric: tabular-nums; font-size: var(--f3); line-height: 28px; text-shadow: 0 var(--u) 0 var(--ink); }
#lives .gl { vertical-align: 1px; margin-right: 4px; filter: drop-shadow(0 var(--u) 0 var(--ink)); }
#lives .you .gl { color: #e6715d; }
#lives .opp .gl { color: #b78dd5; }
#lives b { color: var(--on-wood); }
#lives i { font-style: normal; font-size: var(--f2); color: var(--on-wood-muted); margin: 0 8px; }

#storage { display: flex; align-items: center; gap: 13px; height: 32px; padding: 0 12px; cursor: default; }
.res { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
.res img { width: 20px; height: 20px; }
.res b { color: var(--on-wood); }
.res .gl { vertical-align: 0; }

#btn-ammo { display: flex; align-items: center; gap: 1px; padding: 0 8px 2px 6px; }
#btn-ammo img { width: 24px; height: 24px; vertical-align: 0; }
#btn-ammo img + img { width: 18px; height: 18px; }
#btn-ammo.on { --face: #e6893e; --hi: #f5ad69; --lo: #cb6a24; }

#btn-research { overflow: hidden; max-width: 240px; }
#btn-research .fill { position: absolute; inset: 0 auto 0 0; background: rgba(118, 189, 87, 0.55); box-shadow: inset calc(-1 * var(--u)) 0 0 #3c7f32; transition: width 0.3s; }
#btn-research .lbl { position: relative; display: flex; align-items: center; gap: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#btn-research .gl { flex: none; filter: drop-shadow(0 var(--u) 0 var(--fg-shadow)); }
#btn-research .nm { overflow: hidden; text-overflow: ellipsis; }
#btn-research b { font-variant-numeric: tabular-nums; }
#btn-research.attn { --face: #34a898; --hi: #72cfbf; --lo: #1e877b; --fg: #fff; --fg-shadow: #16665e; }

.ctrl { display: flex; gap: 8px; }
.ctrl button { min-width: 36px; padding: 0 9px 2px; display: grid; place-items: center; }
.ctrl .gl { filter: drop-shadow(0 var(--u) 0 var(--fg-shadow)); }
#btn-speed { font-variant-numeric: tabular-nums; }
#btn-sound.off { --fg: var(--on-wood-muted); }

/* ---- The map, and the cards over it ---- */

#stage { position: relative; flex: 1; min-height: 200px; overflow: hidden; }
#game { position: absolute; inset: 0; display: block; width: 100%; height: 100%; cursor: crosshair; background: #4a943b; touch-action: none; }

/* A card over the map: parchment, outlined, with a hard shadow. */
.news, #incoming, #netnote, #scout, #inspect, #upgrade, #tip, #mini-label {
  color: var(--text);
  background: var(--paper);
  box-shadow: inset 0 calc(-1 * var(--u)) 0 var(--paper-edge), var(--lift);
}
.news b, #incoming b, #netnote b, #scout b, #inspect b, #upgrade b, #tip b { color: var(--strong); }

#feed {
  position: absolute; left: 50%; top: 14px; z-index: 1; width: max-content; max-width: min(560px, 70%);
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: none;
}
.news {
  --mark: var(--ice);
  padding: 4px 12px 6px 14px;
  background-image: linear-gradient(90deg, var(--mark) 0 calc(2 * var(--u)), transparent 0);
  animation: news linear both;
}
#feed.paused .news { animation-play-state: paused; }
.news.good { --mark: #4a943b; }
.news.bad { --mark: #c93f32; }
.news.warn { --mark: #d6a21f; }
.news.alert { --mark: #9261b9; }
.news i { margin-left: 6px; font-style: normal; color: var(--muted); }
@keyframes news {
  from { opacity: 0; transform: translateY(-8px); }
  3% { opacity: 1; transform: none; }
  92% { opacity: 1; }
  to { opacity: 0; }
}

/* What the opponent has queued up to send: one chip a pack, first out first. */
#incoming {
  position: absolute; left: 12px; top: 14px; z-index: 1; max-width: calc(100% - 24px);
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px 9px; padding: 4px 12px 6px 14px;
  background-image: linear-gradient(90deg, #9261b9 0 calc(2 * var(--u)), transparent 0);
  pointer-events: none;
}
#incoming b { color: var(--sent); }
#incoming .when { color: var(--muted); font-variant-numeric: tabular-nums; }
#incoming .cost img { width: 22px; height: 22px; }
#incoming:not(.hidden) ~ #netnote { top: 54px; }
@media (max-width: 1100px) { #incoming:not(.hidden) ~ #feed { top: 54px; } } /* no room beside the news: the news moves down */

/* Trouble with the connection, in an online match. */
#netnote {
  position: absolute; left: 12px; top: 14px; z-index: 1; max-width: min(320px, 40%); padding: 4px 12px 6px 14px;
  background-image: linear-gradient(90deg, #d6a21f 0 calc(2 * var(--u)), transparent 0);
  pointer-events: none;
}

#scout { position: absolute; right: 12px; top: 14px; z-index: 1; width: 290px; padding: 8px 12px 10px; }
#scout h3 { display: flex; justify-content: space-between; margin: 0 0 6px; font-size: var(--f2); color: var(--sent); }
#scout h3 .gl { color: #c93f32; margin-right: 3px; }
#scout h3 span { color: var(--strong); }
#scout .chips { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 4px; color: var(--strong); }
#scout .chips img { width: 22px; height: 22px; }
#scout p { margin: 4px 0 0; color: var(--muted); }
#scout ul { margin: 8px 0 0; padding: 6px 0 0; list-style: none; box-shadow: inset 0 var(--u) 0 var(--paper-edge); color: var(--sent); }
#scout li + li { margin-top: 2px; opacity: 0.7; }
#scout .keys { margin-top: 8px; }

#inspect { position: absolute; left: 12px; bottom: 14px; z-index: 1; max-width: min(520px, 62%); padding: 4px 12px 6px 8px; pointer-events: none; }
#inspect .row { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 8px; }
#inspect .row > img { width: 26px; height: 26px; }
#inspect .row > span { color: var(--muted); }
#inspect .row > span .cost { color: var(--strong); margin-right: 3px; }
#inspect small { display: block; margin-top: 1px; font-size: var(--f2); color: var(--muted); }

/* A turret's upgrades, while it's picked: two paths side by side, two steps each. */
#upgrade { position: absolute; left: 12px; bottom: 14px; z-index: 2; width: min(560px, calc(100% - 24px)); padding: 8px 10px 12px; }
.up-head { display: flex; align-items: center; gap: 8px; margin: 0 2px 10px; }
.up-head img { width: 26px; height: 26px; }
.up-head b { white-space: nowrap; }
.up-head .dim { flex: 1; }
.up-head button { padding: 1px 9px 3px; }
.up-head button[data-close] { --face: transparent; --hi: transparent; --lo: transparent; --fg: var(--muted); --fg-shadow: transparent; box-shadow: none; padding: 4px 6px; }
@media (hover: hover) { .up-head button[data-close]:hover { --fg: var(--ink); background-image: none; } }
.paths { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.path h4 { margin: 0 0 6px 2px; font-size: var(--f2); text-transform: uppercase; letter-spacing: 1px; color: color-mix(in srgb, var(--path) 55%, var(--ink)); }

/* A step, or a research project: a slip of parchment to press, banded on the left in its path's colour. */
.step, .tnode {
  --face: var(--paper-hi); --hi: #fffbef; --lo: var(--paper-edge); --fg: var(--text); --fg-shadow: transparent;
  display: flex; flex-direction: column; width: 100%; text-align: left;
}
.step { gap: 0; margin-bottom: 10px; padding: 4px 10px 6px 14px; background-image: linear-gradient(90deg, var(--path) 0 calc(2 * var(--u)), transparent 0); }
@media (hover: hover) { .step:hover:not(:disabled) { background-image: linear-gradient(90deg, var(--path) 0 calc(2 * var(--u)), transparent 0), linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4)); } }
.step:last-child { margin-bottom: 0; }
.step:disabled { opacity: 1; }
.st-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.st-top b { color: var(--strong); }
.st-top .costs { display: flex; gap: 7px; }
.st-top .costs img { width: 16px; height: 16px; }
.st-desc { color: var(--muted); }
.step.bought { --face: color-mix(in srgb, var(--path) 30%, var(--paper)); --lo: color-mix(in srgb, var(--path) 45%, var(--paper-edge)); --hi: color-mix(in srgb, var(--path) 15%, var(--paper-hi)); }
.step.bought .tick { color: var(--good); }
.step.bought .st-desc { color: var(--text); }
.step.later, .step.closed { --face: var(--paper-lo); --hi: var(--paper-lo); }
.step.later { opacity: 0.7; }
.path.closed { opacity: 0.45; }
.path.closed h4::after { content: ' · closed'; text-transform: none; letter-spacing: 0; }

#mini-wrap {
  position: absolute; right: 12px; bottom: 14px; z-index: 1;
  padding: calc(2 * var(--u)); background: var(--wood-2);
  box-shadow: inset 0 var(--u) 0 var(--wood-3), inset 0 calc(-1 * var(--u)) 0 var(--wood-1), var(--lift);
}
#mini { display: block; cursor: pointer; box-shadow: 0 0 0 var(--u) var(--wood-0); }
#mini-label { position: absolute; left: 8px; top: 8px; padding: 0 6px 2px; pointer-events: none; }

#toast {
  position: absolute; left: 50%; bottom: 18px; z-index: 3; transform: translate(-50%, 8px);
  padding: 5px 14px 7px; line-height: 20px;
  width: max-content; max-width: calc(100% - 24px); text-align: center;
  background: #a62a21; color: #fff; text-shadow: 0 var(--u) 0 #5a1916;
  box-shadow: inset 0 var(--u) 0 #c93f32, inset 0 calc(-1 * var(--u)) 0 #801e1a, var(--lift);
  opacity: 0; pointer-events: none; transition: opacity 0.15s, transform 0.15s;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }
#toast.info { background: #285792; text-shadow: 0 var(--u) 0 #1c3c6a; box-shadow: inset 0 var(--u) 0 #3974b9, inset 0 calc(-1 * var(--u)) 0 #1c3c6a, var(--lift); }

/* ---- Bottom bar: what you can do ---- */

#bar {
  flex: none; position: relative; z-index: 2;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  padding: 12px max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  box-shadow: inset 0 calc(2 * var(--u)) 0 var(--wood-2), 0 calc(-1 * var(--u)) 0 var(--ink), 0 calc(-3 * var(--u)) 0 var(--shadow);
}
/* Building on the left, sending on the right; on a narrow screen the sends drop to a row of their own. */
#bar .side { display: flex; align-items: center; gap: 12px; min-width: 0; }
#bar .side + .side { margin-left: auto; }
.bar-label { text-transform: uppercase; letter-spacing: 1px; color: var(--on-wood-muted); text-shadow: 0 var(--u) 0 var(--ink); }
#tools { display: flex; flex-wrap: wrap; gap: 10px 12px; }
.group { display: flex; gap: 8px; }
.group + .group { padding-left: 12px; box-shadow: inset var(--u) 0 0 var(--wood-0); }
#sends { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
#send-queue { display: flex; align-items: center; flex-wrap: wrap; gap: 1px 2px; color: var(--sent-lit); font-variant-numeric: tabular-nums; text-shadow: 0 var(--u) 0 var(--ink); }
#send-queue img.ic { width: 20px; height: 20px; vertical-align: 0; }
#send-queue b { margin-left: 4px; }
#send-queue.full b { color: var(--bad-lit); }

/* A slot in the bars, like one in a farm game's inventory: parchment, for the pictures to stand out on. */
.slot {
  --face: var(--paper-lo); --hi: var(--paper-hi); --lo: var(--paper-deep); --fg: var(--ink); --fg-shadow: transparent;
  width: var(--slot); height: var(--slot); padding: 0; display: grid; place-items: center;
}
.slot .icon { display: block; width: calc(var(--slot) - 12px); height: calc(var(--slot) - 12px); }
.slot kbd {
  position: absolute; left: 3px; top: 3px; min-width: 0; margin: 0; padding: 0;
  font-size: var(--f1); line-height: 8px; color: var(--muted); background: none; box-shadow: none;
}
.slot kbd .gl { vertical-align: 0; margin-right: 1px; }
.slot .count {
  position: absolute; right: 2px; bottom: 3px; min-width: 12px; padding: 1px 2px 1px 3px; text-align: center;
  font-size: var(--f1); line-height: 8px; color: var(--cream); background: var(--ink); text-shadow: none;
}
.slot.locked { display: none; }
.slot.poor { --face: var(--paper-edge); --hi: var(--paper-lo); --lo: var(--paper-deep); }
.slot.poor .icon { opacity: 0.45; filter: grayscale(0.8); }
.slot.active { --face: #edc548; --hi: #f8e28c; --lo: #d6a21f; }
.slot.active kbd { color: var(--ink); }
.slot.send { --face: #b78dd5; --hi: #d4b5ea; --lo: #9261b9; }
.slot.send kbd { color: #583177; }
.slot.send.poor { --face: #9a7bb4; --hi: #b29acb; --lo: #7a5a99; }
.slot.fresh { animation: fresh 1s steps(2, jump-none) 6; } /* just unlocked */
/* On a touch screen: the keyboard's rotate and the right button's remove, as buttons. */
body:not(.touch) .touch-only { display: none !important; }
.slot.act .icon { width: auto; height: auto; transition: transform 0.12s; }
.slot.act .count { color: var(--cream); }
.slot.act[data-act="erase"] { color: #a62a21; }
.slot.act[data-act="erase"].active { --face: #c93f32; --hi: #e6715d; --lo: #a62a21; color: #fff; }
body.touch .slot kbd, body.touch .tip-head kbd, body.touch #scout .keys { display: none; } /* no keys to press */
@keyframes fresh { 50% { box-shadow: inset 0 0 0 calc(2 * var(--u)) #edc548, var(--outline), 0 calc(2 * var(--u)) 0 var(--ink); } }

/* ---- Hover card ---- */

#tip { position: fixed; z-index: 20; width: max-content; min-width: 200px; max-width: 340px; padding: 6px 12px 10px; pointer-events: none; }
.tip-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 4px; padding-bottom: 4px; font-size: var(--f3); line-height: 28px; color: var(--strong); box-shadow: 0 var(--u) 0 var(--paper-edge); }
.tip-head kbd { font-size: var(--f2); }
#tip p { margin: 6px 0 0; color: var(--muted); }
#tip p b { color: var(--strong); }
#tip p img.ic { width: 22px; height: 22px; vertical-align: -6px; }
#tip .costs { display: flex; flex-wrap: wrap; gap: 3px 12px; color: var(--strong); }
#tip .eco { color: var(--sent); }
#tip .new { margin-left: 3px; padding: 0 5px 2px; text-transform: uppercase; background: #edc548; color: var(--ink); }
#tip .then { margin-top: 10px; padding-top: 2px; box-shadow: inset 0 var(--u) 0 var(--paper-edge); }
#tip table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
#tip th { padding: 0 0 2px 14px; font-weight: 400; text-align: right; color: var(--faint); }
#tip td { padding: 1px 0 1px 14px; text-align: right; color: var(--strong); }
#tip td:first-child { padding-left: 0; text-align: left; color: var(--text); }
#tip td.good { color: var(--good); }
#tip td.bad { color: var(--bad); }
.flowbar { display: flex; height: 8px; margin-top: 10px; background: var(--paper-lo); box-shadow: var(--outline); }
.f-bank { background: var(--bank); }
.f-ammo { background: var(--ammo); }
.f-upgrade { background: var(--upgrade); }
.flowbar > span + span { box-shadow: inset var(--u) 0 0 var(--ink); }
.legend { display: flex; gap: 12px; margin-top: 6px; color: var(--muted); white-space: nowrap; }
.dot { display: inline-block; width: 8px; height: 8px; margin-right: 4px; vertical-align: 1px; box-shadow: 0 0 0 var(--u) var(--ink); }

/* ---- Research overlay ---- */

/* Over the whole window (the game runs on behind it): four six-step ladders
   need the height. */
#tech {
  position: fixed; inset: 0; z-index: 8; display: flex; align-items: center; justify-content: center; padding: 16px;
  background: rgba(42, 31, 40, 0.55);
}

/* A big card: parchment in a wooden frame. */
.tech-card, #modal .card {
  color: var(--text);
  background: var(--paper);
  box-shadow:
    inset 0 0 0 calc(3 * var(--u)) var(--wood-2), inset 0 0 0 calc(4 * var(--u)) var(--wood-0),
    inset 0 calc(5 * var(--u)) 0 var(--paper-hi),
    var(--outline), calc(3 * var(--u)) calc(3 * var(--u)) 0 var(--shadow);
  scrollbar-width: thin; scrollbar-color: var(--paper-deep) transparent;
}
.tech-card b, #modal .card b { color: var(--strong); }
.tech-card {
  width: 100%; max-width: 1280px; max-height: 100%; overflow: auto; padding: 16px 20px 20px;
}
.tech-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.tech-head h1 { margin: 0; font-size: var(--f3); line-height: 28px; white-space: nowrap; color: var(--strong); }
.tech-head .dim { flex: 1; }
.tree { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.branch h3 {
  margin: 0 0 10px; padding-bottom: 4px; font-size: var(--f2); text-transform: uppercase; letter-spacing: 1px;
  color: color-mix(in srgb, var(--branch) 60%, var(--ink)); box-shadow: inset 0 calc(-1 * var(--u)) 0 var(--branch);
}
.tnode { gap: 0; padding: 5px 10px 7px; margin-bottom: 14px; }
.tnode:not(:last-child)::after { /* the link to the next one down */
  content: ''; position: absolute; left: 22px; bottom: -14px; width: 4px; height: 10px;
  background: var(--paper-deep);
}
.tnode.done::after, .tnode.active::after { background: var(--branch); box-shadow: 0 0 0 var(--u) var(--ink); }
.tnode.loose::after { display: none; } /* the one below doesn't need this one */
@media (hover: hover) { .tnode:hover:not(:disabled) { background-image: linear-gradient(rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.45)); } }
.tn-top { display: flex; align-items: center; gap: 4px; }
.tn-name { flex: 1; color: var(--strong); }
.tnode img.unlock { width: 26px; height: 26px; margin: -3px 0; }
.tn-desc { color: var(--muted); }
.needs { color: var(--warn); }
.tn-foot { display: flex; align-items: center; gap: 8px; margin-top: 3px; min-height: 18px; }
.tn-foot .costs { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; color: var(--strong); }
.tn-foot .costs img { width: 16px; height: 16px; }
.tn-foot .time { color: var(--faint); }
.tn-foot .st { font-variant-numeric: tabular-nums; color: var(--strong); }
.tn-foot .bar { flex: 1; height: 8px; background: var(--paper-lo); box-shadow: var(--outline); overflow: hidden; }
.tn-foot .fill { display: block; height: 100%; background: var(--branch); transition: width 0.3s; }
/* Ready to start: ringed in its branch's colour. Running: the same, and filling up. */
.tnode.ready, .tnode.active {
  box-shadow:
    inset 0 0 0 var(--u) var(--branch), inset 0 calc(-2 * var(--u)) 0 var(--lo),
    0 calc(-1 * var(--u)) 0 var(--ink), calc(-1 * var(--u)) 0 0 var(--ink), var(--u) 0 0 var(--ink), 0 calc(2 * var(--u)) 0 var(--ink);
}
.tnode.done { --face: color-mix(in srgb, var(--branch) 32%, var(--paper)); --hi: color-mix(in srgb, var(--branch) 18%, var(--paper-hi)); --lo: color-mix(in srgb, var(--branch) 50%, var(--paper-edge)); opacity: 1; }
.tnode.done .tn-desc { color: var(--text); }
.tnode.done .st { color: var(--good); }
.tnode.locked, .tnode.open { --face: var(--paper-lo); --hi: var(--paper-lo); }
.tnode.locked { opacity: 0.6; }
.tnode:disabled { cursor: default; }

/* ---- Modal: how to play, and the result ---- */

#modal {
  position: fixed; inset: 0; z-index: 10; display: flex; align-items: center; justify-content: center; padding: 16px;
  background: rgba(42, 31, 40, 0.58);
}
#modal .card { max-width: 660px; max-height: 100%; overflow: auto; padding: 22px 30px 26px; line-height: 22px; }
#modal h1 { margin: 0 0 10px; font-size: var(--f3); line-height: 28px; color: var(--strong); text-shadow: 0 var(--u) 0 var(--paper-edge); }
#modal h1.c-good { color: var(--good); }
#modal h1.c-bad { color: var(--bad); }
#modal p { margin: 8px 0; }
#modal .brief { display: flex; flex-direction: column; gap: 12px; margin: 14px 0; padding: 0; list-style: none; }
#modal .brief li { display: flex; align-items: center; gap: 12px; color: var(--muted); }
#modal .brief img { flex: none; width: 40px; height: 40px; padding: 2px; background: var(--paper-lo); box-shadow: inset 0 calc(-1 * var(--u)) 0 var(--paper-deep), var(--outline); }
#modal .how { margin: 0; padding: 0; list-style: none; }
#modal .how li { position: relative; margin: 8px 0; padding-left: 16px; color: var(--muted); }
#modal .how li::before { content: ''; position: absolute; left: 2px; top: 8px; width: 6px; height: 6px; background: var(--wood-3); box-shadow: 0 0 0 var(--u) var(--ink); }
/* Claiming a frontier: what it brings (+), and what it lets in (!). */
#modal .claim li { padding-left: 22px; }
#modal .claim li::before { left: 0; top: 0; width: 16px; height: auto; background: none; box-shadow: none; text-align: center; }
#modal .claim li.gain::before { content: '+'; color: var(--good); }
#modal .claim li.risk::before { content: '!'; color: var(--bad); }
#modal .claim-cost { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 14px 0 4px; color: var(--strong); }
#modal .keys {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 18px; margin: 16px 0 12px; padding: 12px 14px;
  color: var(--muted); background: var(--paper-lo);
  box-shadow: inset 0 var(--u) 0 var(--paper-deep), inset 0 calc(-1 * var(--u)) 0 var(--paper-hi);
}
#modal .keys .gl { vertical-align: 0; }
#modal .invited { padding: 6px 12px 8px 14px; color: var(--text); background: var(--paper-lo); background-image: linear-gradient(90deg, #9261b9 0 calc(2 * var(--u)), transparent 0); }
#modal .invite { display: flex; gap: 12px; margin: 12px 0 4px; }
#modal .invite input {
  flex: 1; min-width: 0; padding: 6px 10px 8px; border: 0; border-radius: 0; outline: 0;
  background: var(--paper-hi); color: var(--text); font: inherit;
  box-shadow: inset 0 var(--u) 0 var(--paper-deep), var(--outline);
}
#modal .invite button { padding: 5px 16px 7px; }
/* The settings: a slider each for the effects and the music. */
.sound { display: flex; flex-direction: column; gap: 14px; margin: 16px 0 6px; }
.vol { display: flex; align-items: center; gap: 14px; }
.vol span { flex: none; width: 62px; color: var(--strong); }
.vol b { flex: none; width: 30px; text-align: right; font-variant-numeric: tabular-nums; color: var(--muted) !important; }
.sound.muted .vol { opacity: 0.45; }
.sound button { align-self: flex-start; }
/* A slider: a groove in the parchment, and a wooden block to slide along it. */
.vol input {
  flex: 1; min-width: 0; height: 28px; margin: 0; cursor: pointer; background: none;
  -webkit-appearance: none; appearance: none;
}
.vol input::-webkit-slider-runnable-track { height: 8px; background: var(--paper-deep); box-shadow: inset 0 var(--u) 0 var(--wood-2), var(--outline); }
.vol input::-moz-range-track { height: 8px; background: var(--paper-deep); box-shadow: inset 0 var(--u) 0 var(--wood-2), var(--outline); }
.vol input::-moz-range-progress { height: 8px; background: #5aa646; box-shadow: inset 0 var(--u) 0 #76bd57; }
.vol input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 14px; height: 22px; margin-top: -7px; border: 0; border-radius: 0;
  background: var(--wood-3); box-shadow: inset 0 var(--u) 0 var(--wood-4), inset 0 calc(-1 * var(--u)) 0 var(--wood-1), var(--outline);
}
.vol input::-moz-range-thumb {
  width: 14px; height: 22px; border: 0; border-radius: 0;
  background: var(--wood-3); box-shadow: inset 0 var(--u) 0 var(--wood-4), inset 0 calc(-1 * var(--u)) 0 var(--wood-1), var(--outline);
}
#search-time { margin-left: 4px; font-variant-numeric: tabular-nums; color: var(--muted); }
/* The main menu, over two AIs playing each other: the bars and the cards over the map are put away for it, and the map is dimmed less than under the other modals. */
#app.at-menu #topbar, #app.at-menu #bar, #app.at-menu #stage > :not(#game) { display: none; }
#modal[data-kind="menu"] { background: rgba(42, 31, 40, 0.32); }
#modal[data-kind="menu"] .card { width: 380px; padding: 26px 28px 28px; text-align: center; }
/* The name in big gold letters, eight screen pixels to each of the font's,
   outlined half of one thick and standing on its shadow (--o, the outline). */
.logo {
  --o: 4px;
  display: flex; flex-direction: column; align-items: center;
  font-size: 74.6667px; line-height: 64px; text-transform: uppercase; letter-spacing: 4px;
  text-shadow:
    calc(-1 * var(--o)) 0 var(--ink), var(--o) 0 var(--ink), 0 calc(-1 * var(--o)) var(--ink), 0 var(--o) var(--ink),
    calc(-1 * var(--o)) calc(-1 * var(--o)) var(--ink), var(--o) calc(-1 * var(--o)) var(--ink), calc(-1 * var(--o)) var(--o) var(--ink), var(--o) var(--o) var(--ink),
    0 calc(2 * var(--o)) var(--ink), var(--o) calc(2 * var(--o)) var(--ink), calc(-1 * var(--o)) calc(2 * var(--o)) var(--ink),
    0 calc(3 * var(--o)) var(--shadow), var(--o) calc(3 * var(--o)) var(--shadow), calc(-1 * var(--o)) calc(3 * var(--o)) var(--shadow);
}
#modal .logo b { color: #edc548; }
#modal .tag { margin: 16px 0 0; color: var(--muted); text-wrap: balance; }
#modal .title .invited { margin: 14px 0 0; text-align: left; }
.menu { display: flex; flex-direction: column; gap: 14px; margin-top: 20px; }
.menu > .primary { padding: 9px 12px 11px; font-size: var(--f3); }
.menu > button:not(.primary), .menu .row button { padding: 7px 8px 9px; }
.menu .row { display: flex; gap: 12px; }
.menu .row button { flex: 1; }
.menu .levels { justify-content: center; margin: 2px 0 0; }
.menu .levels small { min-height: 44px; }
#modal .menu .map { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 0 0 4px; }
.menu .map button { padding: 1px 10px 3px; }
#modal .actions { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin-top: 18px; }
#modal .actions button { white-space: nowrap; }
#modal .actions button:not(.primary) { padding: 11px 16px 13px; } /* as tall as the big one beside it */
#modal .actions .dim { margin-left: auto; }
/* Which copy of the game this is, for play-testers' reports: under everything, quietly. */
#modal .ver { margin: 18px 0 -6px; color: var(--faint); font-variant-numeric: tabular-nums; }
table.stats { border-collapse: collapse; margin: 12px 0; font-variant-numeric: tabular-nums; }
table.stats th, table.stats td { padding: 2px 20px 2px 0; text-align: right; font-weight: 400; }
table.stats th { color: var(--strong); box-shadow: inset 0 calc(-1 * var(--u)) 0 var(--paper-edge); }
table.stats td { color: var(--strong); }
table.stats td:first-child, table.stats th:first-child { text-align: left; color: var(--muted); }

/* How hard the AI plays: four to pick from, and a line on the one that's picked. */
.levels { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin: 14px 0 2px; }
.levels > .dim { margin-right: 2px; text-transform: uppercase; letter-spacing: 1px; }
.levels button { padding: 1px 11px 3px; }
.levels small { flex-basis: 100%; font-size: var(--f2); color: var(--muted); }

/* ---- Smaller screens: smaller buttons, fewer words ---- */

@media (max-width: 1500px) {
  :root { --slot: 42px; }
  .wv-name { display: none; }
  #storage { gap: 10px; }
}
@media (max-width: 1250px), (max-height: 720px) {
  :root { --slot: 38px; }
  .bar-label, #lives i { display: none; }
  #lives { gap: 12px; }
}
@media (max-width: 900px) {
  .tree { grid-template-columns: 1fr 1fr; }
  #modal .keys { grid-template-columns: 1fr; }
}

/* ---- Touch screens and phones ---- */

/* Fingers want bigger buttons than the narrow-window sizes above. */
body.touch { --slot: 44px; }

/* A phone held upright: one column of everything, and cards as wide as the screen. */
@media (max-width: 600px) {
  #topbar { gap: 8px; }
  #storage { gap: 9px; padding: 0 9px; }
  #btn-research { max-width: 150px; }
  #lives { font-size: var(--f2); line-height: 20px; }
  #scout { width: min(290px, calc(100% - 24px)); }
  #feed { max-width: calc(100% - 24px); }
  #toast { width: max-content; max-width: calc(100% - 24px); white-space: normal; text-align: center; }
  .tree { grid-template-columns: 1fr; }
  #tech { padding: 8px; }
  .tech-head { flex-wrap: wrap; gap: 4px 12px; }
  .tech-head .dim { order: 3; flex-basis: 100%; }
  #modal { padding: 8px; }
  #modal .card { padding: 18px 18px 20px; }
  #modal .actions { flex-wrap: wrap; }
  .logo { --o: 3px; font-size: 56px; line-height: 50px; }
  /* The build bar as two plain rows of buttons, and the sends in a row of their own under it. */
  :root, body.touch { --slot: 40px; }
  #bar { gap: 8px; }
  #tools, #sends { gap: 6px; } /* eight to a row on the narrowest phones, outlines a pixel apart */
  .group { display: contents; }
  #bar .side { width: 100%; }
  #bar .side + .side { margin-left: 0; flex-wrap: wrap; gap: 4px 10px; }
  #sends { justify-content: flex-start; }
  #send-queue { flex-basis: 100%; line-height: 18px; }
  #send-queue:empty { display: none; }
}

/* A phone on its side has width to spare and no height: one slim row on top,
   and the build and send bars go down the two sides of the map. */
@media (max-height: 520px) and (orientation: landscape) {
  :root, body.touch { --slot: 38px; }
  #app { display: grid; grid-template: auto minmax(0, 1fr) / auto minmax(0, 1fr) auto; }
  #topbar { grid-column: 1 / -1; gap: 6px 8px; padding-top: max(6px, env(safe-area-inset-top)); padding-bottom: 8px; }
  #topbar button, #wave-what, #storage { height: 30px; }
  #topbar .spacer { flex: 0 1 6px; }
  #wave { flex: 1 1 140px; } /* takes what's left of the row; if that's too little for the wave's number, the bar goes to two rows */
  #wave-what { gap: 8px; padding-right: 8px; }
  .mod { display: none; } /* the wave's card says what it's modified with */
  #lives { gap: 10px; font-size: var(--f2); line-height: 20px; }
  #storage { gap: 8px; padding: 0 8px; }
  .res { gap: 2px; }
  #btn-research .nm { display: none; } /* just the flask, and the time left on what's running */
  .ctrl { gap: 6px; }
  .ctrl button { min-width: 32px; padding: 0 7px 2px; }
  /* The main menu, side by side: its name on the left, its buttons on the right. */
  #modal[data-kind="menu"] .card { display: flex; flex-wrap: wrap; align-items: center; gap: 0 24px; width: 660px; padding: 16px 22px 18px; }
  #modal[data-kind="menu"] .ver { flex-basis: 100%; margin: 8px 0 -6px; } /* a row of its own, under both halves */
  #modal[data-kind="menu"] .title, .menu { flex: 1; min-width: 0; }
  .menu { margin-top: 0; gap: 10px; }
  .menu > .primary { padding: 5px 9px 7px; }
  .menu .levels > .dim { display: none; } /* no room for the label: the four buttons stay on one row */
  .menu .levels button { padding: 1px 8px 3px; }
  .logo { --o: 3px; font-size: 56px; line-height: 50px; }

  #stage { grid-column: 2; grid-row: 2; min-height: 0; }
  #bar { display: contents; }
  #bar .side {
    grid-row: 2; flex-direction: column; justify-content: flex-start; gap: 8px; padding: 8px 8px 10px;
    background-color: var(--wood-1); overflow-y: auto; scrollbar-width: none;
  }
  #bar .side::-webkit-scrollbar { display: none; }
  #bar .side:first-child { grid-column: 1; padding-left: max(8px, env(safe-area-inset-left)); padding-bottom: max(8px, env(safe-area-inset-bottom)); box-shadow: inset calc(-2 * var(--u)) 0 0 var(--wood-0), var(--u) 0 0 var(--ink); z-index: 2; }
  #bar .side + .side { grid-column: 3; margin-left: 0; padding-right: max(8px, env(safe-area-inset-right)); padding-bottom: max(8px, env(safe-area-inset-bottom)); box-shadow: inset calc(2 * var(--u)) 0 0 var(--wood-0), calc(-1 * var(--u)) 0 0 var(--ink); z-index: 2; }
  #tools, #sends { display: grid; grid-template-columns: repeat(2, var(--slot)); gap: 8px; justify-content: start; }
  .group { display: contents; }
  #send-queue { max-width: calc(2 * var(--slot) + 8px); justify-content: center; line-height: 18px; }
  #send-queue img.ic { width: 16px; height: 16px; }
  #send-queue:empty { display: none; }

  #upgrade { bottom: 8px; left: 8px; width: min(520px, calc(100% - 16px)); padding: 6px 8px 10px; }
  .step { padding: 2px 8px 4px 12px; }
  #inspect { left: 8px; bottom: 8px; }
  #mini-wrap { right: 8px; bottom: 8px; }
  #feed { top: 8px; }
  #scout { top: 8px; right: 8px; }
  #tech { padding: 6px; }
  .tree { grid-template-columns: repeat(4, minmax(180px, 1fr)); } /* the whole tree, scrolled sideways */
  #modal { padding: 6px; }
  #modal .card { padding: 14px 20px 16px; }
  #modal h1 { margin-bottom: 4px; }
  #modal .how li { margin: 4px 0; }
  #modal .keys { grid-template-columns: 1fr 1fr; margin: 8px 0 6px; padding: 8px 12px; }
}
