/* Crosskeep — UI chrome. The game world itself is a low-res canvas scaled up
   with nearest-neighbor; the DOM HUD around it keeps the same chunky feel. */

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --sky1: #8fd3ff;
  --sky2: #c9ecff;
  --ink: #14101b;
  --panel: #241d31;
  --panel2: #362b49;
  --paper: #f4f1e4;
  --gold: #f2c14a;
  --accent: #2cb583;
}

html, body { height: 100%; }

body {
  background: linear-gradient(180deg, var(--sky1) 0%, var(--sky2) 70%, #eafaf1 100%);
  font-family: "Consolas", "Menlo", monospace;
  color: var(--ink);
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  /* no double-tap zoom on the chrome; the field has its own zoom control */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

/* dvh tracks the phone's shrinking/growing browser chrome; vh does not, and
   the difference is a build bar sitting under the address bar. */
#app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }

/* Every screen scrolls. With eighteen levels the picker overflows even a
   desktop window, and on a phone almost everything does. Content is pinned
   to the top and centred only when it actually fits (see .screen > * below). */
.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  gap: 14px;
  padding: 12px max(12px, env(safe-area-inset-left)) max(12px, env(safe-area-inset-bottom));
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}
.screen > * { flex-shrink: 0; }
.screen.hidden, .hidden { display: none !important; }

/* ---------- shared buttons ---------- */
.big-btn, .small-btn, .tiny-btn {
  font-family: inherit;
  font-weight: bold;
  color: var(--paper);
  background: var(--panel);
  border: 3px solid var(--ink);
  border-radius: 2px;
  box-shadow: 0 4px 0 var(--ink);
  cursor: pointer;
  letter-spacing: 1px;
}
.big-btn { font-size: 20px; padding: 12px 28px; }
.big-btn.alt { background: var(--panel2); }
.small-btn { font-size: 14px; padding: 6px 16px; }
.tiny-btn { font-size: 12px; padding: 3px 8px; box-shadow: 0 2px 0 var(--ink); }
.big-btn:hover, .small-btn:hover, .tiny-btn:hover { filter: brightness(1.25); }
.big-btn:active, .small-btn:active, .tiny-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--ink); }

/* ---------- title ---------- */
.title-box { text-align: center; }
.logo {
  font-size: clamp(42px, 9vw, 84px);
  letter-spacing: 6px;
  color: var(--paper);
  text-shadow:
    4px 4px 0 var(--ink),
    -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink),
    0 8px 0 rgba(20,16,27,.25);
}
.tagline { margin-top: 6px; font-size: 15px; color: var(--panel); font-weight: bold; letter-spacing: 2px; }
.menu-buttons { margin-top: 34px; display: flex; flex-direction: column; gap: 14px; align-items: center; }
.footnote { margin-top: 40px; font-size: 11px; opacity: .55; }

.screen-head {
  font-size: 26px; letter-spacing: 3px; color: var(--paper);
  text-shadow: 3px 3px 0 var(--ink), -1px -1px 0 var(--ink), 1px -1px 0 var(--ink), -1px 1px 0 var(--ink);
}
.hint { font-size: 12px; max-width: 560px; text-align: center; color: var(--panel); }

/* ---------- faction select ---------- */
.faction-cards { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
.faction-card {
  width: 218px;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 3px;
  box-shadow: 0 5px 0 var(--ink);
  padding: 12px;
  text-align: center;
  cursor: pointer;
  transition: transform .08s;
}
.faction-card:hover { transform: translateY(-4px); }
.faction-card h3 { font-size: 16px; letter-spacing: 1px; margin: 6px 0 2px; }
.faction-card .blurb { font-size: 11px; min-height: 44px; opacity: .8; }
.faction-card canvas { image-rendering: pixelated; }
.faction-card .crest { width: 72px; height: 72px; }
.faction-card .roster { display: flex; justify-content: center; gap: 6px; margin: 8px 0; align-items: flex-end; min-height: 40px; }
.faction-card .trait { font-size: 10px; font-weight: bold; letter-spacing: 1px; padding: 2px 6px; border: 2px solid var(--ink); border-radius: 2px; display: inline-block; margin-bottom: 8px; }

/* ---------- game ---------- */
/* The play screen never scrolls — it partitions the viewport. The canvas
   takes whatever is left after the two HUDs, and ui.js sizes it to fit
   exactly that, so nothing is ever cut off at any aspect ratio. */
#screen-game {
  gap: 6px; justify-content: flex-start; padding: 8px 6px 6px;
  overflow: hidden;
}

#hud-top {
  display: flex; align-items: center; gap: 14px;
  background: var(--panel);
  color: var(--paper);
  border: 3px solid var(--ink);
  box-shadow: 0 3px 0 var(--ink);
  border-radius: 2px;
  padding: 5px 12px;
  font-size: 14px;
  width: min(98vw, 900px);
  flex-wrap: wrap;
  row-gap: 4px;
}
.hud-stat { display: inline-flex; align-items: center; gap: 5px; }
.hud-stat canvas { width: 16px; height: 16px; image-rendering: pixelated; }
.hud-spacer { flex: 1; }
/* the tool cluster wraps as one piece, never split across rows */
.hud-tools { display: inline-flex; align-items: center; gap: 6px; }
#hud-gold { color: var(--gold); }
#hud-lives { color: #ff8a80; }

#game-area {
  /* basis 0, not auto: with `auto` the area's size depends on the canvas
     inside it while the canvas is sized from the area — a loop that settles
     a few pixels too large and clips the bottom row of the field. */
  flex: 1 1 0; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;              /* the field never spills over the HUD */
}
#game-wrap { position: relative; line-height: 0; }
#game {
  /* content-box, deliberately: the page-wide border-box rule would fold the
     3px border into the declared width, leaving the bitmap scaled by a
     fraction and every pixel of the art faintly smeared. */
  box-sizing: content-box;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  border: 3px solid var(--ink);
  border-radius: 2px;
  box-shadow: 0 6px 0 rgba(20,16,27,.35);
  background: transparent;
  cursor: crosshair;
  /* the canvas owns every gesture on it: drag pans, pinch zooms, and the
     page must not try to scroll or zoom underneath */
  touch-action: none;
}

#msg-overlay, #tut-overlay {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20,16,27,.55);
  z-index: 20;
}
.msg-box {
  line-height: 1.45;        /* #game-wrap zeroes line-height for the canvas */
  background: var(--paper);
  border: 3px solid var(--ink);
  box-shadow: 0 6px 0 var(--ink);
  padding: 22px 34px;
  text-align: center;
  max-width: 460px;
}
.msg-box h2 { font-size: 24px; letter-spacing: 2px; margin-bottom: 8px; }
.msg-box p { font-size: 13px; margin-bottom: 16px; white-space: pre-line; }
.msg-box ul {
  text-align: left; font-size: 12px; line-height: 1.5;
  margin: 0 0 16px 0; padding-left: 18px;
}
.msg-box ul li { margin-bottom: 7px; }
.msg-btns { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

#tower-panel {
  position: absolute;
  z-index: 10;
  line-height: 1.5;         /* #game-wrap zeroes line-height for the canvas */
  background: var(--paper);
  border: 3px solid var(--ink);
  box-shadow: 0 4px 0 var(--ink);
  border-radius: 2px;
  padding: 6px 10px;
  font-size: 11px;
  display: flex; flex-direction: column; gap: 4px;
  min-width: 170px;
  pointer-events: auto;
}
#tp-name { font-weight: bold; font-size: 12px; letter-spacing: .5px; color: var(--ink); }
#tp-stats { color: var(--panel); }
#tp-upgrade { align-self: flex-start; }
#tp-upgrade:disabled { opacity: .55; cursor: not-allowed; }
#tp-close { position: absolute; top: 2px; right: 2px; padding: 0 5px; box-shadow: none; }

#hud-bottom {
  display: flex; flex-direction: column; gap: 5px;
  background: var(--panel);
  border: 3px solid var(--ink);
  box-shadow: 0 3px 0 var(--ink);
  border-radius: 2px;
  padding: 6px 10px;
  max-width: 100%;
  /* Thirteen build buttons do not fit a phone. Rather than shrink them into
     un-tappable stamps, each row scrolls sideways at full size. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
}
.bar-row { display: flex; gap: 7px; align-items: stretch; justify-content: center; min-width: min-content; }
.build-btn {
  position: relative;
  width: 76px;
  background: var(--panel2);
  border: 2px solid var(--ink);
  border-radius: 2px;
  color: var(--paper);
  font-family: inherit;
  cursor: pointer;
  padding: 4px 2px 3px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  overflow: hidden;
}
.build-btn:hover { filter: brightness(1.2); }
.build-btn.selected { outline: 3px solid var(--gold); filter: brightness(1.25); }
.build-btn.disabled { opacity: .45; cursor: not-allowed; }
.build-btn.locked { cursor: help; }
.build-btn canvas { image-rendering: pixelated; max-height: 40px; }
.build-btn .b-name {
  font-size: 8px; letter-spacing: 0; white-space: nowrap;
  max-width: 70px; overflow: hidden; text-overflow: ellipsis;
}
.build-btn .b-cost { font-size: 10px; color: var(--gold); font-weight: bold; }
.build-btn .b-key {
  position: absolute; top: 1px; left: 3px;
  font-size: 9px; opacity: .6;
}
.build-btn .b-stars {
  position: absolute; top: 1px; right: 3px;
  font-size: 8px; color: var(--gold); letter-spacing: -1px;
}
.build-btn .b-up {
  position: absolute; right: 1px; bottom: 1px;
  font-size: 9px; font-weight: bold;
  background: var(--gold); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 2px;
  padding: 0 3px;
  cursor: pointer;
}
.build-btn .b-up.cant { opacity: .5; }
.build-btn .b-lock {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20,16,27,.66);
  font-size: 9px; letter-spacing: 1px; font-weight: bold; color: var(--paper);
  pointer-events: none;
}
#hud-tip { font-size: 12px; color: var(--panel); font-weight: bold; min-height: 16px; }

/* When the build bar has to scroll, say so: a soft edge is the difference
   between "there are seven towers" and "there are five towers". */
#hud-bottom-wrap { position: relative; max-width: 100%; }

#hud-hero { gap: 4px; }
#hud-hero-name { color: var(--gold); font-size: 12px; }
#hud-hero-hp {
  display: inline-block; width: 46px; height: 8px;
  border: 2px solid var(--ink); background: #5c1a16; border-radius: 1px;
}
#hud-hero-hp i { display: block; height: 100%; background: #55cb62; }

/* ---------- level select ---------- */
/* Eighteen cards. A grid that reflows to whatever width there is, rather
   than a fixed row count that runs off the bottom of a phone. */
.level-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
  width: min(100%, 1040px);
  align-content: start;
}
.level-card {
  position: relative;
  width: auto;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 3px;
  box-shadow: 0 5px 0 var(--ink);
  padding: 10px 12px 12px;
  cursor: pointer;
  transition: transform .08s;
}
.level-card:hover { transform: translateY(-3px); }
.level-card.locked { opacity: .55; cursor: not-allowed; filter: saturate(.4); }
.level-card.locked:hover { transform: none; }
.level-card h3 { font-size: 14px; letter-spacing: .5px; margin: 8px 0 2px; }
.lv-swatch {
  width: 100%; height: 34px;
  border: 2px solid var(--ink); border-radius: 2px;
  display: flex; align-items: center; justify-content: flex-start;
  padding-left: 10px;          /* leaves the top-right corner to the tick */
  font-size: 18px; font-weight: bold; color: var(--paper);
  text-shadow: 2px 2px 0 var(--ink);
}
.lv-meta { font-size: 10px; opacity: .75; }
.lv-badges { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; min-height: 18px; }
.lv-badges span {
  font-size: 9px; font-weight: bold; letter-spacing: .5px;
  border: 2px solid var(--ink); border-radius: 2px;
  padding: 1px 5px; background: var(--gold);
}
.lv-done {
  position: absolute; top: 4px; right: 8px;
  font-size: 18px; font-weight: bold; color: var(--accent);
  text-shadow: 1px 1px 0 var(--ink);
}
.level-foot { display: flex; gap: 14px; align-items: center; }

/* ---------- gallery ---------- */
.gallery-tabs { display: flex; gap: 8px; }
.gallery-tabs .tiny-btn.on { background: var(--accent); color: var(--ink); }
#gallery-grid {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
  overflow-y: auto;
  max-height: 70vh;
  width: min(96vw, 1000px);
  padding: 10px;
  background: rgba(244,241,228,.65);
  border: 3px solid var(--ink);
  border-radius: 3px;
}
.g-item {
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 2px;
  padding: 6px 8px;
  text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px;
}
.g-item canvas { image-rendering: pixelated; }
.g-item .g-name { font-size: 10px; font-weight: bold; letter-spacing: .5px; }

/* ---------- multiplayer lobby ---------- */
.mp-box {
  background: rgba(244,241,228,.85);
  border: 3px solid var(--ink);
  border-radius: 3px;
  padding: 18px 22px;
  width: min(94vw, 560px);
  display: flex; flex-direction: column; gap: 12px;
}
.mp-row { display: flex; align-items: center; gap: 10px; font-size: 13px; flex-wrap: wrap; }
.mp-row label, .mp-label { font-weight: bold; }
.mp-row input[type="text"], .mp-row input:not([type]), #mp-name, #mp-code {
  font-family: inherit; font-size: 14px; padding: 5px 8px;
  border: 2px solid var(--ink); border-radius: 2px; background: var(--paper);
  width: 150px;
}
#mp-code { width: 90px; text-transform: lowercase; letter-spacing: 2px; }
#mp-map {
  font-family: inherit; font-size: 13px; padding: 4px 6px;
  border: 2px solid var(--ink); border-radius: 2px; background: var(--paper);
}
.mp-factions { display: flex; gap: 8px; }
.mp-fac {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-family: inherit; font-size: 11px; font-weight: bold;
  background: var(--paper); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 2px;
  padding: 5px 9px; cursor: pointer;
}
.mp-fac canvas { image-rendering: pixelated; }
.mp-fac.on { background: var(--gold); box-shadow: 0 2px 0 var(--ink); }
.mp-fac:hover { filter: brightness(1.08); }
.mp-actions { display: flex; justify-content: center; }
.mp-split { display: flex; gap: 18px; flex-wrap: wrap; }
.mp-col {
  flex: 1; min-width: 200px;
  border: 2px dashed var(--panel2); border-radius: 3px;
  padding: 10px; display: flex; flex-direction: column; gap: 8px;
}
.mp-col h3 { font-size: 13px; letter-spacing: 1px; }
.mp-status { font-size: 13px; min-height: 18px; color: #8a2e28; font-weight: bold; }
#mp-challenge { margin: 4px auto; min-height: 0; }
.mp-wait-line { font-size: 14px; }
.mp-code-big {
  font-size: 44px; font-weight: bold; letter-spacing: 10px; text-align: center;
  color: var(--paper); background: var(--panel);
  border: 3px solid var(--ink); border-radius: 3px;
  padding: 10px 18px 10px 28px;
  text-shadow: 0 3px 0 var(--ink);
}

/* ---------- touch panning ---------- */
/* A five-key cross tucked into the corner of the field. Hidden for anyone
   with a mouse (arrow keys and WASD are right there) and for very short
   viewports, where it would eat the map it exists to move. */
#pan-pad {
  position: absolute; right: 6px; bottom: 6px;
  display: none;
  grid-template-columns: repeat(3, 34px);
  grid-template-rows: repeat(3, 34px);
  gap: 2px;
  z-index: 12;
  line-height: 1;
}
#pan-pad .pan-btn {
  font-family: inherit; font-size: 13px; font-weight: bold;
  color: var(--paper);
  background: rgba(36,29,49,.72);
  border: 2px solid var(--ink);
  border-radius: 3px;
  padding: 0;
  cursor: pointer;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
#pan-pad .pan-btn:active { background: var(--gold); color: var(--ink); }
#pan-pad [data-pan="up"]    { grid-area: 1 / 2; }
#pan-pad [data-pan="left"]  { grid-area: 2 / 1; }
#pan-pad [data-pan="home"]  { grid-area: 2 / 2; font-size: 15px; }
#pan-pad [data-pan="right"] { grid-area: 2 / 3; }
#pan-pad [data-pan="down"]  { grid-area: 3 / 2; }
@media (pointer: coarse) {
  #pan-pad { display: grid; }
}
@media (pointer: coarse) and (max-height: 430px) {
  #pan-pad { display: none; }        /* landscape phone: the drag is enough */
}

/* ---------- narrow screens ---------- */
/* A phone is not a small desktop. Everything here is about giving the thumb
   room and the field the pixels: chrome shrinks, columns collapse to one,
   and nothing is allowed to be wider than the viewport. */
@media (max-width: 700px) {
  .screen { gap: 10px; padding: 10px 8px max(10px, env(safe-area-inset-bottom)); }
  .logo { letter-spacing: 3px; }
  .tagline { font-size: 12px; letter-spacing: 1px; }
  .menu-buttons { margin-top: 22px; gap: 11px; width: 100%; }
  .menu-buttons .big-btn { width: min(320px, 88vw); font-size: 17px; padding: 14px 10px; }
  .footnote { margin-top: 22px; }
  .screen-head { font-size: 19px; letter-spacing: 1.5px; text-align: center; }
  .hint { font-size: 11px; }

  .faction-cards { gap: 10px; width: 100%; }
  .faction-card { width: min(340px, 92vw); padding: 10px; }
  .faction-card .blurb { min-height: 0; }
  .faction-card .crest { width: 56px; height: 56px; }

  .level-cards { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 9px; }
  .level-card { padding: 7px 8px 9px; }
  .level-card h3 { font-size: 12px; margin: 6px 0 2px; }
  .lv-swatch { height: 26px; font-size: 15px; }
  .lv-meta { font-size: 9px; }
  .lv-badges span { font-size: 8px; padding: 1px 4px; }

  .mp-box { padding: 12px 13px; gap: 10px; width: 100%; }
  .mp-split { flex-direction: column; gap: 10px; }
  .mp-col { min-width: 0; }
  .mp-code-big { font-size: 30px; letter-spacing: 6px; padding: 8px 10px 8px 16px; }
  #mp-name { width: 100%; max-width: 190px; }

  #gallery-grid { max-height: 62vh; padding: 8px; gap: 8px; }

  #screen-game { padding: 4px 2px 4px; gap: 4px; }
  #hud-top { gap: 8px; padding: 4px 7px; font-size: 12px; width: 100%; }
  .hud-stat canvas { width: 13px; height: 13px; }
  #hud-bottom { padding: 4px 5px; gap: 4px; }
  .build-btn { width: 62px; }
  #hud-bottom {
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 22px), transparent 100%);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 22px), transparent 100%);
  }
  .build-btn canvas { max-height: 32px; }
  .build-btn .b-name { font-size: 7px; max-width: 56px; }
  #hud-tip { font-size: 11px; min-height: 14px; text-align: center; padding: 0 6px; }
  .msg-box { padding: 14px 16px; max-width: 92vw; }
  .msg-box h2 { font-size: 19px; }
  .msg-box p, .msg-box ul { font-size: 12px; }
  #tower-panel { font-size: 10px; min-width: 150px; }
  #mp-banner { font-size: 11px; padding: 6px 10px; max-width: 94%; white-space: normal; text-align: center; }
}

/* Landscape phone: height is the scarce axis, so the chrome gets out of
   the way and the field keeps almost all of it. */
@media (max-height: 460px) and (orientation: landscape) {
  #screen-game { padding: 3px 2px; gap: 3px; }
  #hud-top { padding: 2px 6px; font-size: 11px; }
  #hud-tip { display: none; }
  /* Names go, but the upgrade chip is absolutely placed bottom-right and
     would land on top of the price — give it its own strip. */
  .build-btn { width: 54px; padding: 2px 2px 11px; }
  .build-btn canvas { max-height: 24px; }
  .build-btn .b-name { display: none; }
  .build-btn .b-up { font-size: 8px; padding: 0 2px; }
  .menu-buttons { margin-top: 12px; }
  .logo { font-size: clamp(30px, 7vw, 48px); }
}

/* ---------- multiplayer in-match chrome ---------- */
#hud-foe-wrap .foe-lives b { color: #d93a30; }
#hud-link { font-style: normal; font-size: 10px; }
#mp-banner {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  background: var(--panel); color: var(--paper);
  border: 3px solid var(--ink); border-radius: 3px;
  box-shadow: 0 4px 0 var(--ink);
  font-size: 14px; font-weight: bold; letter-spacing: 1px;
  padding: 8px 18px; z-index: 15; white-space: nowrap;
}
