/* Palette tokens mirror art/palette.json. */
:root {
  --void: #07060f;
  --night: #141233;
  --indigo: #222058;
  --deep-blue: #33408f;
  --blue: #4f6fd1;
  --sky: #8aa6e8;
  --gray: #8b8fa8;
  --white: #e9ecf7;
  --violet: #3f2463;
  --purple: #7340a0;
  --orchid: #b878d8;
  --amber: #ffb21e;
  --thruster: #ff6b2c;
  --alarm: #ff4d68;
  --phosphor: #39ff8a;
  --deep-phosphor: #168c52;
  --scale: 3;
  --font: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, Menlo, "DejaVu Sans Mono", monospace;
  --text: clamp(14px, calc(var(--scale) * 4.4px), 20px);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--void);
  color: var(--white);
  font-family: var(--font);
  font-size: var(--text);
  line-height: 1.4;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

#stage {
  position: relative;
  max-width: 100vw;
}

#screen {
  display: block;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

#ui {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  font-size: var(--text);
}

/* Narrow or short windows: canvas on top, UI flows underneath and the page scrolls. */
body.stacked { display: block; overflow-y: auto; }
body.stacked #stage { margin: 0 auto; }
body.stacked #ui { position: static; padding: 8px 12px 24px; }
body.stacked .screen.modal { position: static; background: none; padding: 0; }
body.stacked .crt-overlay { bottom: auto; height: calc(180px * var(--scale)); }

/* The hosted demo's landing (hosting brief, step 2): the game stays hidden until "Open the log" swaps the two. */
.landing { width: min(100%, 52em); padding: 0.6em 1em; }
.landing p { margin: 0.5em 0; }
.landing .landing-head { margin: 0; color: var(--phosphor); letter-spacing: 0.08em; text-transform: uppercase; }
body.stacked .landing { margin: 0 auto; }

/*
 * On /play/ the page also carries the site's header and footer and its
 * stylesheet (/assets/site.css, loaded before this one; tools/deploy-the-game.ts).
 * These rules keep the site's base and terminal-skin rules off the game, and
 * pin the header to the top and the footer to the bottom of the column.
 */
body.skin-terminal { background: var(--void); color: var(--white); font-family: var(--font); }
#stage { width: auto; flex: none; margin: 0; padding: 0; }
#stage a.btn, #stage .shirt-card { color: var(--white); }
#stage a.btn:hover, #stage a.btn:focus-visible { color: var(--amber); }
/* --text and --font here are the brand's (siteChrome scopes them to the header and footer): the footer's copy takes the site's green, as on every baked page. */
.site-header, .site-footer { align-self: stretch; flex: none; color: var(--text); font-family: var(--font); font-size: 16px; line-height: normal; }
.site-header { margin-bottom: auto; }
.site-footer { margin-top: auto; }

/* Leg 1's shirt under its debrief: a static card to the collection, never a store fetch. */
.shirt-card { display: flex; flex-direction: column; gap: 0.2em; margin-top: 0.8em; padding: 0.6em 0.8em; border: 2px solid var(--deep-phosphor); background: var(--void); color: var(--white); text-decoration: none; }
.shirt-card:hover, .shirt-card:focus-visible { border-color: var(--amber); outline: none; }
.shirt-head { color: var(--amber); font-weight: 700; }
.shirt-cta { color: var(--phosphor); }

.screen { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.screen.modal {
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--void) 72%, transparent);
  padding: 2%;
}
.panel {
  background: color-mix(in srgb, var(--night) 92%, transparent);
  border: 2px solid var(--deep-blue);
  padding: 0.8em 1em;
  max-height: 100%;
  overflow-y: auto;
  width: min(100%, 52em);
}
.panel.bottom { width: 100%; border-width: 2px 0 0; max-height: 58%; }
.spacer { flex: 1; }

h1, h2, h3 { margin: 0 0 0.4em; font-weight: 700; }
h1.logo { color: var(--amber); font-size: 2.2em; letter-spacing: 0.06em; text-transform: uppercase; }
h1.logo.death { color: var(--alarm); }
h1.logo.canon { color: var(--orchid); }
/* An ending's card until its art is delivered (D9, Leg 5): the panel's lines, as the terminal would print them. */
.ending-panel { flex: none; min-width: 12em; max-width: 45%; padding: 0.6em 0.8em; border: 2px solid var(--deep-phosphor); background: var(--void); color: var(--phosphor); text-transform: uppercase; letter-spacing: 0.04em; }
.ending-panel p { margin: 0.2em 0; }
@media (max-width: 520px) { .ending-panel { max-width: none; width: 100%; } }
h2 { color: var(--phosphor); font-size: 1.15em; }
h3 { color: var(--amber); font-size: 1em; }
p { margin: 0 0 0.5em; }
.sub { color: var(--sky); }
.dim { color: var(--gray); }
.small { font-size: 0.85em; }
.warn { color: var(--alarm); }
.good { color: var(--phosphor); }
.tier-minor { color: var(--sky); }
.tier-serious { color: var(--amber); }
.tier-critical { color: var(--alarm); }

.row { display: flex; gap: 1em; align-items: flex-start; }
.portrait { flex: none; width: calc(24px * var(--scale) * 1.4); height: auto; image-rendering: pixelated; border: 2px solid var(--deep-blue); }

.menu { display: flex; flex-wrap: wrap; gap: 0.4em; margin-top: 0.6em; }
.menu.col { flex-direction: column; align-items: stretch; }
.btn {
  font: inherit;
  color: var(--white);
  background: var(--indigo);
  border: 2px solid var(--deep-blue);
  padding: 0.35em 0.7em;
  cursor: pointer;
  text-align: left;
  min-height: 44px;
}
.btn:hover:not(:disabled), .btn:focus-visible { border-color: var(--amber); outline: none; color: var(--amber); }
.btn[data-primary] { border-color: var(--deep-phosphor); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.wide { width: 100%; }
a.btn { display: inline-flex; align-items: center; gap: 0.4em; text-decoration: none; }
.opt .odds { margin: 0.1em 0 0.4em 0.4em; }
.btn.tiny { min-height: 36px; min-width: 36px; padding: 0.1em 0.4em; text-align: center; }
/* Touch screens: the depot and trade steppers get a full 44px target (spec §10). */
@media (pointer: coarse) {
  .btn.tiny { min-height: 44px; min-width: 44px; }
}
/* Phone width: the steppers can't share a line with the item, price and coverage, so they take their own. */
@media (max-width: 480px) {
  table.shop tr { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; border-bottom: 1px solid var(--indigo); }
  table.shop td { border-bottom: none; }
  table.shop td.qty { grid-column: 1 / -1; padding-bottom: 0.4em; }
}
.key { color: var(--amber); margin-right: 0.5em; }
.key::before { content: "["; color: var(--gray); }
.key::after { content: "]"; color: var(--gray); }

.craft-card { display: flex; gap: 0.8em; align-items: center; }
.craft-card canvas { flex: none; image-rendering: pixelated; }
.opt p { margin: 0.2em 0 0.4em 0.4em; }
.blurbs { margin: 0.6em 0 0; padding-left: 1.2em; color: var(--gray); font-size: 0.85em; }

table.shop { border-collapse: collapse; width: 100%; }
table.shop td { padding: 0.15em 0.4em; border-bottom: 1px solid var(--indigo); }
table.shop .num { text-align: right; font-variant-numeric: tabular-nums; }
table.shop .qty { white-space: nowrap; text-align: right; }
table.shop .qty .num { display: inline-block; min-width: 2.2em; text-align: center; }
.icon { width: 16px; height: 16px; image-rendering: pixelated; vertical-align: -2px; }

.hud { background: color-mix(in srgb, var(--void) 80%, transparent); border-bottom: 2px solid var(--deep-blue); padding: 0.3em 0.8em; font-size: 0.85em; }
.hud-row { display: flex; flex-wrap: wrap; gap: 0.4em 1.2em; align-items: center; }
.hud-row .grow { flex: 1; min-width: 12em; }
.bar { display: inline-block; width: 5em; height: 0.6em; background: var(--indigo); vertical-align: middle; }
.bar.dist { width: 40%; min-width: 6em; }
.bar > span { display: block; height: 100%; background: var(--phosphor); }
.bar.low > span { background: var(--alarm); }
.bar.dist > span { background: var(--amber); }

.log p { margin: 0 0 0.2em; }
.log .day { color: var(--sky); }
.log .event { color: var(--amber); }
.log .arrive { color: var(--phosphor); }
.log .warn { color: var(--alarm); }
.log .good { color: var(--phosphor); }
.log.tall p { margin-bottom: 0.5em; }
.debrief { border: 2px solid var(--deep-phosphor); padding: 0.6em 0.8em; margin: 0.6em 0; }

label.seed { display: flex; gap: 0.6em; align-items: center; margin-top: 0.8em; }
input {
  font: inherit;
  color: var(--phosphor);
  background: var(--void);
  border: 2px solid var(--deep-blue);
  padding: 0.25em 0.5em;
  min-height: 40px;
}
input:focus-visible { border-color: var(--amber); outline: none; }

.screen.mining { justify-content: flex-start; pointer-events: none; }
.mining-hud { align-self: center; margin-top: 0.4em; padding: 0.2em 0.8em; background: color-mix(in srgb, var(--void) 80%, transparent); color: var(--amber); }

/* ---------- CRT effect (toggle in Settings; off is plain and fully readable) ---------- */
/* Softened 15% (operator, 2026-10-09), then again for legibility and colour (operator playtest, 2026-10-10: "too harsh",
   washed-out contrast, overbearing stripes). The scanline is now a thin dark line once per game pixel (about a third of
   it, was half) at 0.13 (was 0.238); the vignette 0.26 from 68% (was 0.4675 from 60%); the inner shadow 0.32 (was
   0.595); the canvas keeps its own colours (saturate 1.04, no brightness lift; glow 0.2, was 0.3825); text glow is a
   2px halo at 22% (was 5.1px at 46.75%), so glyph edges stay sharp; the flicker dips 2% and 1% (was 5.1% and 2.55%).
   Then a step back (operator playtest, 2026-10-10, "a little too far"): the scanline 0.17 over 40% of each line, the
   text glow 3px at 25%, and the flicker dips 5% and 2.5%. */
.crt-overlay { position: absolute; inset: 0; pointer-events: none; display: none; }
body.crt .crt-overlay {
  --line: max(2px, calc(var(--scale) * 1px));
  display: block;
  background:
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) calc(var(--line) * 0.6), rgba(0, 0, 0, 0.17) calc(var(--line) * 0.6), rgba(0, 0, 0, 0.17) var(--line)),
    radial-gradient(ellipse at center, rgba(0, 0, 0, 0) 68%, rgba(0, 0, 0, 0.26) 100%);
  border-radius: 2.5% / 4%;
  box-shadow: inset 0 0 calc(var(--scale) * 10px) rgba(0, 0, 0, 0.32);
  animation: flicker 6s infinite steps(1);
}
body.crt #screen { border-radius: 2.5% / 4%; filter: saturate(1.04) drop-shadow(0 0 calc(var(--scale) * 1px) rgba(79, 111, 209, 0.2)); }
body.crt #ui { text-shadow: 0 0 3px color-mix(in srgb, currentColor 25%, transparent); }
@keyframes flicker {
  0%, 100% { opacity: 1; }
  47% { opacity: 0.95; }
  48% { opacity: 1; }
  83% { opacity: 0.975; }
}
@media (prefers-reduced-motion: reduce) {
  body.crt .crt-overlay { animation: none; }
}

/* Key art (art/large/, quantized to the palette): beside the text on wide screens, above it on narrow ones. */
/* Sharp-bilinear: the canvas is the art at ×4, scaled down smoothly, so every art pixel comes out the same size. */
.keyart { flex: none; width: min(42%, calc(var(--scale) * 100px)); height: auto; image-rendering: auto; }
@media (max-width: 720px) {
  .row { flex-direction: column; }
  .keyart { width: 100%; }
}

.planner { border: 2px solid var(--deep-blue); padding: 0.4em 0.7em; margin: 0.6em 0 0.4em; }
.planner p { margin: 0 0 0.25em; }
.planner .plan-row { display: flex; flex-wrap: wrap; gap: 0.2em 0.8em; width: 100%; margin: 0 0 0.3em; min-height: 0; padding: 0.3em 0.6em; }
.planner .plan-row .plan-name { color: var(--amber); min-width: 11em; }
.planner .plan-row.selected { border-color: var(--phosphor); background: color-mix(in srgb, var(--deep-phosphor) 22%, var(--indigo)); }
/* HUD meters name themselves on hover (operator, 2026-10-09). */
.hud .tip { cursor: help; }
