/* The instrument panel around a viewport. Fixed tracks, contain:strict on every
   panel: nothing a canvas does to its own backing store can ever reach layout,
   which is the one bug that turns a resize into an infinite loop. */

:root {
  /* Kept in step with render/palette.js by hand. The HUD deliberately does not
     import it — a chrome that goes blank because the renderer moved a key is a
     bad trade for six hex strings. */
  --bg: #05070a;
  --panel: #0a0e13;
  --panel-hi: #10161d;
  --edge: #1d2630;
  --edge-hi: #2c3a48;
  --ink: #c2ced6;
  --ink-dim: #6c7a85;
  --ink-faint: #47535c;
  --green: #5da548;
  --green-dim: #2f5a26;
  --amber: #f0c020;
  --red: #e0402c;
  --blue: #3fa9f5;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas,
          "DejaVu Sans Mono", "Liberation Mono", "Courier New", monospace;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;             /* arrow keys and space cannot scroll what has no scroll */
  overscroll-behavior: none;
  background: var(--bg);
  color: var(--ink);
  font: 400 11px/1.35 var(--mono);
  -webkit-font-smoothing: antialiased;
}

body { user-select: none; -webkit-user-select: none; }

button { font: inherit; color: inherit; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* --- the five-zone frame ------------------------------------------------- */

#app {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) 268px;
  grid-template-rows: minmax(0, 1fr) 104px;
  grid-template-areas:
    "tools stage status"
    "log   log   log";
  gap: 4px;
  padding: 4px;
  background: var(--bg);
}

.panel {
  contain: strict;              /* load-bearing: no canvas can resize its own panel */
  position: relative;
  border: 1px solid var(--edge);
  background: var(--panel);
  border-radius: 2px;
}

#tools  { grid-area: tools;  padding: 3px 4px; }
#stage  { grid-area: stage;  background: #000; cursor: crosshair; }
#status { grid-area: status; padding: 5px; }
#logbar { grid-area: log;    padding: 3px 4px; }

.zone-title,
.box-title {
  margin: 0 0 3px;
  font-size: 8px;
  font-weight: 400;
  letter-spacing: 0.14em;
  color: var(--ink-faint);
  text-align: center;
}

/* --- zone 1: build palette ----------------------------------------------- */

#tool-list { display: grid; gap: 3px; }

.tool {
  display: grid;
  justify-items: center;
  gap: 0;
  position: relative;
  padding: 3px 0 2px;
  border: 1px solid var(--edge);
  border-radius: 2px;
  background: var(--panel-hi);
  cursor: pointer;
  line-height: 1.1;
}
.tool:hover { border-color: var(--edge-hi); background: #16202a; }
.tool:focus-visible { outline: 1px solid var(--blue); outline-offset: 1px; }

.tool-ico { display: block; width: 30px; height: 30px; image-rendering: pixelated; }
.tool-name { font-size: 8px; letter-spacing: 0.06em; color: var(--ink); }
.tool-cost { font-size: 8px; color: var(--ink-faint); }

.tool-key {
  position: absolute;
  top: 1px; left: 2px;
  font-size: 8px;
  color: var(--ink-faint);
}

.tool.is-active {
  border-color: var(--green);
  background: #12210f;
  box-shadow: inset 0 0 0 1px #1d3a17;
}
.tool.is-active .tool-name { color: var(--green); }
.tool.is-active .tool-key  { color: var(--green); }

/* Unaffordable is greyed, never hidden — you still need to know the tool exists
   and what it would cost you. */
.tool.is-poor { opacity: 0.38; }
.tool.is-poor .tool-cost { color: var(--red); }

/* The one hint that never goes away: a tool does nothing until you click a tile. */
#tool-hint {
  margin: 5px 0 0;
  font-size: 8px;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-align: center;
  color: var(--ink-faint);
}
#tools.is-armed #tool-hint { color: var(--green); }

/* --- zone 2: the stage ---------------------------------------------------- */

#view {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}

#overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(3, 5, 8, 0.86);
  z-index: 2;
}
#overlay[hidden] { display: none; }

#overlay-card {
  max-width: 560px;
  max-height: 100%;
  overflow: auto;               /* long help on a short laptop scrolls HERE, never the page */
  padding: 18px 22px;
  border: 1px solid var(--edge-hi);
  border-radius: 3px;
  background: var(--panel);
  box-shadow: 0 0 0 1px #000, 0 12px 40px rgba(0, 0, 0, 0.8);
}

#overlay-card h1 {
  margin: 0 0 2px;
  font-size: 22px;
  font-weight: 400;
  letter-spacing: 0.34em;
  color: var(--green);
}
#overlay-card h2 {
  margin: 14px 0 5px;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
}
#overlay-card p { margin: 0 0 8px; color: var(--ink); }
#overlay-card .lede { color: var(--ink-dim); }
#overlay-card ol { margin: 0; padding-left: 18px; }
#overlay-card ol li { margin-bottom: 6px; }
#overlay-card b { color: var(--amber); font-weight: 400; }
#overlay-card .dismiss {
  margin-top: 16px;
  padding: 7px 16px;
  border: 1px solid var(--green-dim);
  border-radius: 2px;
  background: #12210f;
  color: var(--green);
  letter-spacing: 0.12em;
  cursor: pointer;
}
#overlay-card .dismiss:hover { border-color: var(--green); background: #172b13; }

#overlay-card .keys {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 2px 10px;
  font-size: 11px;
}
#overlay-card .keys dt { color: var(--amber); }
#overlay-card .keys dd { margin: 0; color: var(--ink-dim); }

#overlay-card .stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2px 16px;
}

/* --- zones 3 and 4: status ------------------------------------------------ */

#status { display: flex; flex-direction: column; gap: 6px; overflow: hidden; }

.minimap-wrap,
.surface-wrap {
  position: relative;
  contain: strict;
  flex: 0 0 auto;
  border: 1px solid var(--edge);
  background: #04070b;
}

/* 128 backing pixels at 1:1 is the whole map, one pixel per tile — exactly the
   original's readout. It doubles only when there is genuinely room for it. */
.minimap-wrap { width: 128px; height: 128px; margin: 0 auto; }
.gauge-wrap   { height: 186px; border-color: transparent; background: none; }
.objects-wrap { height: 76px;  border-color: transparent; background: none; }

#minimap, #gauges, #objects {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
#minimap { image-rendering: pixelated; }

@media (min-height: 900px) {
  .minimap-wrap { width: 256px; height: 256px; }
}

#readouts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px 8px;
  margin: 0;
  font-size: 10px;
}
.ro { display: flex; justify-content: space-between; gap: 6px; }
.ro dt { color: var(--ink-faint); }
.ro dd { margin: 0; color: var(--ink); }
#ro-state.is-hot { color: var(--amber); }
#ro-state.is-bad { color: var(--red); }

#lgm {
  display: grid;
  gap: 1px;
  padding: 4px 6px 5px;
  border: 1px solid var(--edge);
  border-radius: 2px;
  background: var(--panel-hi);
  text-align: center;
}
#lgm .box-title { margin: 0; }
#lgm-state { font-size: 12px; letter-spacing: 0.1em; color: var(--green); }
#lgm-detail { font-size: 9px; color: var(--ink-faint); min-height: 12px; }
#lgm.is-bad { border-color: var(--red); background: #1c0d0a; }
#lgm.is-bad #lgm-state { color: var(--red); }
#lgm.is-flashing { animation: pulse-bad 0.7s steps(2, jump-none) infinite; }

@keyframes pulse-bad { from { opacity: 1; } to { opacity: 0.45; } }

/* --- zone 5: the newswire ------------------------------------------------- */

#logbar { display: flex; flex-direction: column; gap: 2px; overflow: hidden; }

#banners { flex: 0 0 auto; display: grid; gap: 2px; }

.banner {
  margin: 0;
  padding: 2px 6px;
  border: 1px solid #6b5310;
  border-radius: 2px;
  background: #1e1704;
  color: var(--amber);
  font-size: 10px;
  letter-spacing: 0.04em;
}
.banner[hidden] { display: none; }
.banner-warn { border-color: #5c3a1e; background: #180f06; color: #e09a3c; }

#logrow { flex: 1 1 auto; display: flex; gap: 6px; min-height: 0; }

#log-list {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 0 4px 0 0;
  list-style: none;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--edge-hi) transparent;
  font-size: 11px;
}
#log-list li { color: var(--ink-dim); white-space: pre-wrap; word-break: break-word; }
#log-list li::before { content: "› "; color: var(--ink-faint); }
#log-list .m-good { color: var(--green); }
#log-list .m-bad  { color: var(--red); }
#log-list .m-news { color: var(--amber); }
#log-list .m-news::before { content: "» "; color: var(--amber); }

#logside {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: space-between;
  gap: 4px;
}

#chips { display: flex; gap: 4px; }
.chip {
  padding: 1px 5px;
  border: 1px solid var(--edge-hi);
  border-radius: 2px;
  font-size: 9px;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
}
.chip[hidden] { display: none; }
.chip-good { border-color: var(--green-dim); color: var(--green); }

#logbtns { display: flex; gap: 4px; }
#logbtns button {
  padding: 3px 8px;
  border: 1px solid var(--edge);
  border-radius: 2px;
  background: var(--panel-hi);
  color: var(--ink-dim);
  font-size: 9px;
  letter-spacing: 0.08em;
  cursor: pointer;
}
#logbtns button:hover { border-color: var(--edge-hi); color: var(--ink); }
#logbtns b { color: var(--amber); font-weight: 400; }

/* --- the other fifteen ---------------------------------------------------- */

/* Name tags over the view. Never a hit target: every pointer event on the stage
   belongs to the little green man. */
#tags {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 1;
}

/* The roster takes whatever the column has left over and scrolls inside it.
   Sixteen rows at 12 px is 192 px, which fits on a tall window and scrolls on a
   short one — what it must never do is push the gauges off the bottom. */
#roster {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: 2px;
}
#roster[hidden] { display: none; }
#roster .box-title { margin: 0; }
#roster .box-title b { color: var(--ink-dim); font-weight: 400; }

.roster-head,
.pr {
  display: grid;
  grid-template-columns: 7px 13px minmax(0, 1fr) 26px 15px 15px 15px 15px;
  align-items: center;
  gap: 0 3px;
  font-size: 9px;
  line-height: 12px;
}
.roster-head {
  color: var(--ink-faint);
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--edge);
}
.roster-head span:nth-child(n + 4) { text-align: right; }

.roster-list {
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  min-height: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--edge-hi) transparent;
}

.pr { cursor: pointer; border-left: 2px solid transparent; padding-left: 2px; }
.pr:hover { background: var(--panel-hi); }
.pr-sw {
  width: 7px;
  height: 7px;
  border-radius: 1px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.6);
}
.pr-tag { color: var(--ink-faint); }
.pr-name {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pr-rel, .pr-num { text-align: right; color: var(--ink-dim); }
.pr-rel { letter-spacing: 0.04em; }

/* Allegiance is carried three ways at once — the bar down the left, the word in
   the REL column and the weight of the name — because at 9 px a hue on its own
   is not something you can bet a pillbox on. */
.pr.is-self { background: #0f1a12; border-left-color: var(--green); }
.pr.is-self .pr-name, .pr.is-self .pr-rel { color: var(--green); }
.pr.is-ally { border-left-color: var(--blue); }
.pr.is-ally .pr-rel { color: var(--blue); }
.pr.is-ally .pr-name { color: #9fd8ff; }
.pr.is-enemy .pr-rel { color: var(--ink-faint); }
.pr.is-gone { opacity: 0.42; }
.pr.is-gone .pr-name { text-decoration: line-through; }
.pr.is-cursor { background: #16202a; border-left-color: var(--amber); }
.pr.is-asks {
  border-left-color: var(--amber);
  animation: pulse-bad 0.9s steps(2, jump-none) infinite;
}
.pr.is-asks .pr-rel { color: var(--amber); }
.pr.is-sent .pr-rel { color: var(--ink-faint); }

/* The one line that says what the next key does. */
.ally-prompt {
  margin: 0;
  padding: 2px 4px;
  border: 1px solid var(--edge-hi);
  border-radius: 2px;
  background: var(--panel-hi);
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}
.ally-prompt[hidden] { display: none; }
.ally-prompt.is-ask { border-color: #6b5310; background: #1e1704; color: var(--amber); }
.ally-prompt.is-danger { border-color: #7a2116; background: #1c0d0a; color: var(--red); }

.banner-ally {
  border-color: #1c5c8c;
  background: #06202e;
  color: #9fd8ff;
  animation: pulse-bad 1.1s steps(2, jump-none) infinite;
}

/* --- the full-screen board ------------------------------------------------ */

#roster-full {
  position: fixed;
  inset: 0;
  z-index: 4;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(3, 5, 8, 0.9);
}
#roster-full[hidden] { display: none; }

#roster-card {
  width: min(560px, 100%);
  max-height: 100%;
  overflow: auto;
  padding: 16px 20px;
  border: 1px solid var(--edge-hi);
  border-radius: 3px;
  background: var(--panel);
  box-shadow: 0 0 0 1px #000, 0 12px 40px rgba(0, 0, 0, 0.8);
}
#roster-card h1 {
  margin: 0 0 2px;
  font-size: 18px;
  font-weight: 400;
  letter-spacing: 0.34em;
  color: var(--green);
}
#roster-card .lede { margin: 0 0 10px; color: var(--ink-dim); font-size: 10px; }

/* The same rows, at a size you can read from the back of the chair. */
#roster-card .roster-head,
.roster-list.is-big .pr {
  grid-template-columns: 10px 18px minmax(0, 1fr) 40px 34px 34px 34px 34px;
  gap: 0 6px;
  font-size: 12px;
  line-height: 20px;
}
.roster-list.is-big .pr-sw { width: 10px; height: 10px; }
#roster-card .roster-head { font-size: 9px; }

.roster-legend {
  margin: 10px 0 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--ink-faint);
}
.roster-legend b { color: var(--amber); font-weight: 400; }

/* --- chat ----------------------------------------------------------------- */

#chat { display: flex; align-items: center; gap: 6px; padding: 1px 0 2px; }
#chat[hidden] { display: none; }
#chat label { font-size: 9px; letter-spacing: 0.14em; color: var(--ink-faint); }
#chat-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 2px 5px;
  border: 1px solid var(--edge-hi);
  border-radius: 2px;
  background: #04070b;
  color: var(--ink);
  font: inherit;
}
#chat-input:focus { outline: 1px solid var(--blue); outline-offset: -1px; }

#log-list .m-ally { color: #9fd8ff; }
#log-list .m-ally::before { content: "⋈ "; color: #9fd8ff; }
#log-list .m-chat { color: var(--ink); }
#log-list .m-chat::before { content: "\201C"; color: var(--ink-faint); }

/* --- narrower laptops ----------------------------------------------------- */

@media (max-width: 1120px) {
  #app { grid-template-columns: 54px minmax(0, 1fr) 232px; }
  #status { padding: 3px; }
  .roster-head, .pr { grid-template-columns: 7px 12px minmax(0, 1fr) 22px 14px 14px 14px 14px; }
}
