/* =============================================================================
   style.css — cabinet chrome, CRT treatment, terminal.
   Palette constants are duplicated from config.js on purpose: CSS can't import
   JS, and these two are the only places colors are defined. Change both.
   ============================================================================= */

:root {
  --green: #33ff33;
  --green-dim: #1f9e2a;
  --red: #ff2200;
  --black: #000;
  --bezel: #0a0d0a;

  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo,
          Consolas, "Liberation Mono", monospace;

  --panel-h: clamp(190px, 32vh, 320px);
}

* { box-sizing: border-box; }
a { text-decoration: none; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--black);
  color: var(--green);
  font-family: var(--mono);
  overflow: hidden;
}

/* Keyboard users get a real way past the decorative canvas. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--black);
  color: var(--green);
  border: 1px solid var(--green);
  text-decoration: none;
}
.skip-link:focus { left: 0; }
.skip-link:hover,
.skip-link:focus-visible {
  color: var(--red);
  border-color: var(--red);
}
body:not(.is-mobile) .skip-dock { display: none; }
body.is-mobile .skip-term { display: none; }

/* ---------------------------------------------------------------------------
   Cabinet
   --------------------------------------------------------------------------- */

.cabinet {
  display: grid;
  grid-template-rows: auto 1fr var(--panel-h) auto;
  height: 100%;
  max-height: 100dvh;
}

.site-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.55rem 1.25rem;
  padding: 0.9rem clamp(1rem, 4vw, 2.4rem);
  border-bottom: 1px solid rgba(51, 255, 51, 0.35);
  background: var(--black);
  z-index: 8;
}

.site-mark {
  color: var(--green);
  letter-spacing: 0.18em;
  text-decoration: none;
  font-size: 0.85rem;
}
.site-mark:hover, .site-mark:focus-visible {
  color: var(--red);
  text-decoration: none;
}

.site-nav {
  flex: 1 1 14rem;
  min-width: 0;
}
.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.15rem 1.15rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav a {
  display: inline-block;
  padding: 0.2rem 0;
  color: var(--green);
  font-size: clamp(0.64rem, 1.3vw, 0.76rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}
.site-nav a:hover,
.site-nav a:focus-visible {
  color: var(--red);
  text-shadow: 0 0 8px rgba(255, 34, 0, 0.6);
}

.view-toggle {
  display: inline-block;
  margin-left: auto;
  padding: 0.38rem 0.75rem;
  border: 1px solid rgba(51, 255, 51, 0.55);
  color: var(--green);
  text-decoration: none;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 0.72rem;
  background: transparent;
}
.view-toggle:hover,
.view-toggle:focus-visible {
  color: var(--red);
  border-color: var(--red);
  background: rgba(255, 34, 0, 0.12);
  outline: 1px solid var(--red);
}

/* ---------------------------------------------------------------------------
   Viewport — the game screen
   --------------------------------------------------------------------------- */

.viewport {
  position: relative;
  overflow: hidden;
  background: var(--black);
  min-height: 0;   /* lets the grid row actually shrink */
}

#scene {
  display: block;
  width: 100%;
  height: 100%;
}

/* Desktop mouse aiming: drag on the view, don't pan the page. Crosshair only
   while the tank is live — attract mode keeps the default cursor so the
   terminal still looks like the thing you click. */
.cabinet.is-driving #scene {
  cursor: crosshair;
  touch-action: none;
}
#scene.is-aiming { cursor: grabbing; }

/* The periscope. Not decoration — the 1980 cabinet had a viewfinder hood that
   deliberately restricted the player's view to resemble looking through a
   scope. Vignetting the edges is the authentic look. */
.periscope {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 74% 82% at 50% 50%,
      transparent 52%,
      rgba(0,0,0,0.55) 78%,
      rgba(0,0,0,0.94) 100%);
}

/* CRT: scanlines + a faint phosphor wash. */
.crt {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0)   0px,
    rgba(0,0,0,0)   2px,
    rgba(0,0,0,0.28) 3px,
    rgba(0,0,0,0.28) 4px
  );
  mix-blend-mode: multiply;
}

/* ---------------------------------------------------------------------------
   Control panel — the terminal
   --------------------------------------------------------------------------- */

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0.85rem clamp(0.85rem, 3vw, 2.2rem) 0.5rem;
  background: var(--bezel);
  border-top: 2px solid var(--green-dim);
  box-shadow: 0 -14px 40px rgba(51,255,51,0.07) inset;
  cursor: text;
}

.output {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  font-size: clamp(0.76rem, 1.7vw, 0.95rem);
  line-height: 1.55;
  scrollbar-width: thin;
  scrollbar-color: var(--green-dim) transparent;
}
.output::-webkit-scrollbar { width: 8px; }
.output::-webkit-scrollbar-thumb { background: var(--green-dim); }

.line {
  white-space: pre-wrap;
  word-break: break-word;
  text-shadow: 0 0 6px rgba(51,255,51,0.55);
}
.line.dim,
.line.boot   { color: var(--green-dim); text-shadow: none; }
.line.echo   { color: var(--green-dim); }
.line.error  { color: var(--red); text-shadow: 0 0 6px rgba(255,34,0,0.6); }
.line.heading{ color: var(--green); font-weight: 700; letter-spacing: 0.06em; }
.line a      { color: var(--green); text-decoration: none; }
.line a:hover,
.line a:focus-visible { color: var(--red); }
.line.typing::after {
  content: "█";
  margin-left: 0.05ch;
}

/* Prompt row */

.prompt-row {
  display: flex;
  align-items: center;
  gap: 0.6ch;
  margin-top: 0.5rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid transparent;
  font-size: clamp(0.76rem, 1.7vw, 0.95rem);
}

/* Focus indication for the prompt lives on the row, not as a box around the
   input. The input is focused almost permanently by design (clicking anywhere
   in the panel focuses it), so a full outline would read as a rendering bug.
   An underline plus the native blinking caret is the terminal convention and
   still gives a clear, non-color-dependent focus cue. */
.prompt-row:focus-within {
  border-bottom-color: var(--green-dim);
}

.prompt {
  color: var(--green-dim);
  white-space: nowrap;
  user-select: none;
}

.prompt-input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: 0;
  padding: 0;
  color: var(--green);
  font: inherit;
  text-shadow: 0 0 6px rgba(51,255,51,0.55);
  text-transform: uppercase;
  caret-color: var(--green);
}
.prompt-input::placeholder { color: var(--green-dim); }

.hint {
  margin: 0.45rem 0 0;
  font-size: clamp(0.64rem, 1.3vw, 0.76rem);
  letter-spacing: 0.1em;
  color: var(--green-dim);
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.hint::-webkit-scrollbar { display: none; }

/* ---------------------------------------------------------------------------
   Footer — copyright only. Links live in the header.
   --------------------------------------------------------------------------- */

.site-foot {
  display: flex;
  justify-content: center;
  background: var(--black);
  border-top: 1px solid rgba(51,255,51,0.18);
  padding: 0.4rem clamp(0.85rem, 3vw, 2.2rem) max(0.45rem, env(safe-area-inset-bottom));
}
.site-foot p {
  margin: 0;
  color: var(--green-dim);
  font-size: clamp(0.58rem, 1.2vw, 0.7rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Phone dock — replaces the terminal on a NARROW viewport only.
   Coarse pointers on a wide screen (a touch laptop) keep the terminal. */
.mobile-dock {
  display: none !important;
  gap: 0.55rem;
  padding: 0.7rem clamp(0.85rem, 4vw, 1.6rem);
  padding-bottom: max(0.7rem, env(safe-area-inset-bottom));
  background: var(--black);
  border-top: 1px solid rgba(51,255,51,0.28);
}
.mobile-dock-btn {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 2.8rem;
  padding: 0.55rem 0.4rem;
  background: transparent;
  border: 1px solid var(--green);
  color: var(--green);
  font: inherit;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.mobile-dock-btn:hover,
.mobile-dock-btn:focus-visible {
  color: var(--red);
  border-color: var(--red);
  background: rgba(255, 34, 0, 0.12);
}

@media (max-width: 720px) {
  .cabinet { grid-template-rows: auto 1fr auto auto; }
  .panel { display: none; }
  .site-foot { padding-bottom: 0.35rem; }
  .mobile-dock { display: flex !important; }
  .cabinet.is-driving { grid-template-rows: auto 1fr; }
  .cabinet.is-driving .mobile-dock,
  .cabinet.is-driving .site-foot,
  .cabinet.is-driving .site-nav { display: none !important; }
}

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}
/* See .prompt-row:focus-within above for why this one opts out. */
.prompt-input:focus-visible { outline: none; }

/* ---------------------------------------------------------------------------
   noscript
   --------------------------------------------------------------------------- */

.noscript {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-content: center;
  gap: 1rem;
  padding: 2rem;
  background: var(--black);
  color: var(--green);
}
.noscript ul { list-style: none; padding: 0; display: grid; gap: 0.6rem; }
.noscript a  { color: var(--green); text-decoration: none; }
.noscript a:hover,
.noscript a:focus-visible { color: var(--red); }

/* ---------------------------------------------------------------------------
   Motion and small screens
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* Short viewports: give the terminal a fixed slice rather than letting the
   game squeeze it out. The links matter more than the scenery. */
@media (max-height: 620px) {
  :root { --panel-h: 46vh; }
  .crt { display: none; }
}

@media (max-width: 480px) {
  .periscope { background: radial-gradient(
      ellipse 92% 92% at 50% 50%,
      transparent 60%, rgba(0,0,0,0.85) 100%); }
}

/* ---------------------------------------------------------------------------
   Touch controls

   Overlaid on the viewport, not the panel: the terminal keeps every pixel it
   had, because the links still matter more than the tank. Hidden until
   js/touch.js adds .is-on, which it does on coarse-pointer devices in PLAY
   mode only — so a desktop visitor never sees them and an idle phone visitor
   gets an unobstructed attract screen.

   touch-action: none on the controls is what stops a drag on a stick from
   scrolling or pinch-zooming the page instead of driving the tank.
   --------------------------------------------------------------------------- */

.touch {
  position: absolute;
  inset: 0;
  display: none;
  z-index: 5;
  /* The container is inert; only the controls inside it take input, so the
     middle of the screen stays clear for looking at the game. */
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}
.touch.is-on { display: block; }

.touch-bar,
.touch-pads { position: absolute; display: flex; align-items: center; }

.touch-bar {
  top: 0;
  right: 0;
  gap: 0.4rem;
  padding: 0.5rem clamp(0.5rem, 2vw, 1rem);
}

.touch-pads {
  left: 0;
  right: 0;
  bottom: 0;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0 clamp(0.4rem, 2vw, 1.2rem)
           calc(clamp(0.4rem, 2vw, 1.2rem) + env(safe-area-inset-bottom, 0px));
}

.touch-btn,
.touch-fire,
.touch-stick {
  pointer-events: auto;
  touch-action: none;
  color: var(--green);
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(51,255,51,0.42);
  display: flex;
  align-items: center;
  justify-content: center;
}

.touch-btn {
  min-width: 3.7rem;
  padding: 0.42rem 0.5rem;
  font-size: 0.6rem;
  border-radius: 3px;
}
.touch-btn:hover,
.touch-btn:focus-visible {
  color: var(--red);
  border-color: var(--red);
}
.touch-btn-exit { border-color: rgba(51,255,51,0.42); color: var(--green); }

.touch-fire {
  width: clamp(66px, 17vw, 92px);
  aspect-ratio: 1;
  margin-bottom: 0.6rem;
  border-radius: 50%;
  border-width: 2px;
  font-size: 0.72rem;
  font-weight: 700;
}

/* Pressed state. Deliberately a fill rather than a transform — a control that
   moves under the thumb reads as slipping, and the thumb is already covering
   most of it. */
.touch-btn.is-down,
.touch-fire.is-down {
  background: rgba(51,255,51,0.28);
  box-shadow: 0 0 14px rgba(51,255,51,0.5);
}
.touch-btn-exit.is-down { background: rgba(255,34,0,0.3); }

.touch-stick {
  position: relative;
  width: clamp(104px, 30vw, 148px);
  aspect-ratio: 1;
  border-radius: 50%;
  border-style: dashed;
  border-color: rgba(51,255,51,0.28);
  background: rgba(0,0,0,0.4);
}
.touch-stick.is-down { border-style: solid; border-color: rgba(51,255,51,0.55); }

.touch-knob {
  width: 38%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(51,255,51,0.16);
  border: 1px solid rgba(51,255,51,0.7);
  box-shadow: 0 0 12px rgba(51,255,51,0.35);
}

.touch-cap {
  position: absolute;
  bottom: 0.34rem;
  font-size: 0.5rem;
  letter-spacing: 0.2em;
  color: var(--green-dim);
}

/* Landscape on a phone leaves almost no vertical room — shrink the furniture
   rather than let the sticks eat the horizon. */
@media (max-height: 480px) {
  .touch-stick { width: clamp(84px, 22vh, 116px); }
  .touch-fire { width: clamp(54px, 14vh, 74px); margin-bottom: 0.3rem; }
  .touch-cap { display: none; }
}

/* While the controls are up, the canvas itself stops accepting pan and zoom
   gestures — a stray double-tap mid-fight would otherwise zoom the page and
   leave the sticks somewhere off-screen. Scoped to the canvas and to PLAY
   mode ONLY: the terminal, the header links and the whole page in attract mode
   stay pinch-zoomable, which is the part that actually matters for access. */
.viewport:has(.touch.is-on) #scene { touch-action: none; }

/* The tutorial's between-section prompt. Centred over the canvas, sitting in
   the same dead band the banner is drawn in, and hidden until a section ends. */
.touch-prompt {
  position: absolute;
  left: 0;
  right: 0;
  top: 58%;
  display: none;
  justify-content: center;
  gap: 0.7rem;
}
.touch-prompt.is-on { display: flex; }

.touch-btn-wide {
  min-width: 5.4rem;
  padding: 0.62rem 0.9rem;
  font-size: 0.68rem;
}

/* ---------------------------------------------------------------------------
   Terminal minimize

   Collapsed keeps the PROMPT ROW — it hides the scrollback, not the terminal.
   Fully hiding it would take away the site's actual job (type a name, get a
   link) in exchange for some screen; this way the game gets the space and the
   commands still work. The header links are untouched in both states.
   --------------------------------------------------------------------------- */

.term-toggle {
  position: absolute;
  top: 0.35rem;
  right: clamp(0.6rem, 3vw, 2.2rem);
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 0.4ch;
  padding: 0.3rem 0.55rem;
  background: rgba(0,0,0,0.5);
  border: 1px solid rgba(51,255,51,0.35);
  border-radius: 3px;
  color: var(--green);
  font-family: var(--mono);
  font-size: clamp(0.56rem, 1.2vw, 0.66rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.term-toggle:hover,
.term-toggle:focus-visible { color: var(--red); border-color: var(--red); }

.term-toggle-glyph { font-size: 1.1em; line-height: 1; }

.panel { position: relative; }

/* Room for the button, so a long first output line never runs under it. */
.output { padding-right: 7.5rem; }

/* ---- collapsed ---- */

/* The panel row becomes content-height, which is the prompt row plus padding.
   Declared on .cabinet so it overrides the --panel-h rules, including the
   max-height:620px one that would otherwise still claim 46vh. */
.cabinet.term-min { grid-template-rows: auto 1fr auto auto; }

.term-min .output,
.term-min .hint { display: none; }

.term-min .panel { padding-top: 0.4rem; padding-bottom: 0.35rem; }
.term-min .prompt-row { margin-top: 0; }
.term-min .term-toggle { top: 50%; transform: translateY(-50%); }
.term-min .term-toggle-glyph { transform: rotate(180deg); }

/* On a narrow screen the word is what gets cut, not the control. */
@media (max-width: 480px) {
  .term-toggle-label { display: none; }
  .term-toggle { padding: 0.34rem 0.5rem; }
  .output { padding-right: 3rem; }
}
