/* Warbirds.io — chunky slab UI to match the blocky world. */

:root {
  --crimson: #e84a4a;
  --cobalt: #4a7de8;
  --gold: #f4c542;
  --slab: rgba(24, 28, 38, 0.88);
  --slab-border: #0d0f15;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #87b7e0;
  font-family: "Courier New", ui-monospace, monospace;
  color: #eef2f6;
  /* No browser gestures over the playfield (double-tap zoom, overscroll). */
  touch-action: manipulation;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
input { -webkit-user-select: text; user-select: text; }

#game { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }

/* Help text swaps with the input mode (body.touch is set on coarse-pointer
   devices by main.js). */
body:not(.touch) .touch-only { display: none; }
body.touch .desktop-only { display: none; }

#ui { position: fixed; inset: 0; pointer-events: none; }
#ui button, #ui input { pointer-events: auto; }

.hidden { display: none !important; }

/* ---------- join screen ---------- */
#join-screen, #disconnect-screen {
  position: absolute; inset: 0;
  display: flex; justify-content: center;
  background: linear-gradient(rgba(10, 20, 40, 0.35), rgba(10, 20, 40, 0.65));
  pointer-events: auto;
  /* Scroll the overlay (sized to the visible viewport) whenever the card is
     taller than the window, so every option — plane stats, TAKE OFF, the
     controls help — stays reachable. margin:auto on the card centers it when
     it fits and lets the whole thing scroll when it doesn't (using auto
     margins rather than align-items:center, which would clip the top in an
     overflowing flex container). */
  height: 100dvh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.join-card {
  background: var(--slab);
  border: 4px solid var(--slab-border);
  box-shadow: 0 8px 0 var(--slab-border), inset 0 0 0 2px rgba(255,255,255,0.07);
  padding: 28px 36px;
  max-width: 720px;
  margin: auto;
  text-align: center;
}

.title {
  margin: 0 0 4px;
  font-size: 56px;
  letter-spacing: 6px;
  color: var(--gold);
  text-shadow: 4px 4px 0 #7a5a12, 8px 8px 0 rgba(0,0,0,0.35);
}
.title.small { font-size: 36px; }
.title-tld { color: #eef2f6; text-shadow: 4px 4px 0 #1b2330, 8px 8px 0 rgba(0,0,0,0.35); }

.tagline { margin: 0 0 22px; color: #9fb6cc; letter-spacing: 2px; }

/* ---------- join footer / about link ---------- */
.join-footer { margin: 16px 0 0; }
.footer-link {
  color: #8d9aa8; font-size: 13px; letter-spacing: 2px;
  text-decoration: none; border-bottom: 2px solid transparent;
}
.footer-link:hover { color: var(--gold); border-bottom-color: var(--gold); }
/* The leaderboard link is a button (opens an in-page overlay) but reads as the
   sibling anchors. */
button.footer-link {
  font: inherit; font-size: 13px; letter-spacing: 2px;
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 0; cursor: pointer;
}

/* ---------- leaderboard / hall of fame ---------- */
#leaderboard-screen {
  position: absolute; inset: 0; z-index: 30;
  display: flex; justify-content: center;
  background: linear-gradient(rgba(10, 20, 40, 0.55), rgba(10, 20, 40, 0.82));
  pointer-events: auto;
  height: 100dvh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.lb-card { position: relative; max-width: 560px; width: min(560px, 94vw); }
#leaderboard-close, #daily-close {
  position: absolute; top: 10px; right: 14px;
  background: none; border: 0; color: #8d9aa8;
  font-size: 30px; line-height: 1; cursor: pointer;
}
#leaderboard-close:hover, #daily-close:hover { color: var(--gold); }
.lb-cat { margin: 18px 0 0; text-align: left; }
.lb-cat h3 {
  margin: 0 0 6px; color: var(--gold);
  font-size: 15px; letter-spacing: 2px;
}
.lb-table { width: 100%; border-collapse: collapse; font-size: 15px; }
.lb-table th {
  color: #8d9aa8; text-align: left; font-weight: normal;
  padding: 3px 8px; border-bottom: 2px solid #2a3140; font-size: 12px;
}
.lb-table td { padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.05); }
.lb-table td.rank { color: #76838f; width: 2em; text-align: right; }
.lb-table td.val { text-align: right; color: #eef2f6; font-weight: bold; }
.lb-table td.num { text-align: right; color: #9fb6cc; }
.lb-table tr:nth-child(1) td.rank { color: var(--gold); }
.lb-name { color: #eef2f6; }
.lb-title { color: #f4c542; font-size: 10px; letter-spacing: 0.5px; margin-left: 6px; }
.lb-empty { color: #76838f; font-style: italic; padding: 4px 8px; }
#leaderboard-status { margin: 18px 0 0; color: #8d9aa8; }

.join-row { display: flex; gap: 10px; justify-content: center; }

#name-input {
  font: inherit; font-size: 18px;
  padding: 10px 12px;
  background: #11141c; color: #eef2f6;
  border: 3px solid var(--slab-border);
  outline: none; width: 220px;
}
#name-input:focus { border-color: var(--gold); }

button {
  font: inherit; font-size: 18px; font-weight: bold;
  padding: 10px 22px;
  color: #1b1405;
  background: var(--gold);
  border: 3px solid var(--slab-border);
  box-shadow: 0 4px 0 var(--slab-border);
  cursor: pointer;
}
button:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--slab-border); }
button:disabled { background: #6b6b6b; cursor: default; }

#join-status { min-height: 1.2em; color: #9fb6cc; margin: 14px 0 6px; }

button.ghost { background: #2a3140; color: #c9d6e4; }

/* ============ training / flight school ============ */
#training-screen {
  position: absolute; inset: 0; z-index: 30;
  display: flex; justify-content: center;
  background: linear-gradient(rgba(10, 20, 40, 0.55), rgba(10, 20, 40, 0.82));
  pointer-events: auto;
  height: 100dvh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
#training-close {
  position: absolute; top: 10px; right: 14px;
  background: none; border: 0; color: #8d9aa8;
  font-size: 30px; line-height: 1; cursor: pointer;
}
#training-close:hover { color: var(--gold); }
#training-list { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.train-item {
  display: block; width: 100%; text-align: left;
  font: inherit; cursor: pointer;
  padding: 12px 14px;
  color: #eef2f6; background: #1a2230;
  border: 3px solid var(--slab-border);
  box-shadow: 0 3px 0 var(--slab-border);
}
.train-item:hover { border-color: var(--gold); background: #202a3b; }
.train-item:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--slab-border); }
.train-item .ti-name {
  display: block; color: var(--gold);
  font-size: 16px; font-weight: bold; letter-spacing: 1px;
}
.train-item .ti-blurb { display: block; color: #9fb6cc; font-size: 13px; margin-top: 3px; }

/* In-game: one-time briefing card. */
#training-brief {
  position: absolute; inset: 0; z-index: 25;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10, 20, 40, 0.55);
  pointer-events: auto;
}
.brief-card {
  max-width: 460px; width: min(460px, 92vw);
  background: var(--slab); border: 3px solid var(--slab-border);
  box-shadow: 0 6px 0 var(--slab-border);
  padding: 20px 22px; text-align: left;
}
.brief-card h2 { margin: 0 0 8px; color: var(--gold); letter-spacing: 1px; font-size: 20px; }
.brief-card p { margin: 0 0 10px; color: #d7e2ee; font-size: 14px; line-height: 1.5; }
#brief-tips { margin: 0 0 16px; padding-left: 18px; color: #9fb6cc; font-size: 13px; }
#brief-tips li { margin: 3px 0; }
.brief-actions { display: flex; gap: 10px; }
.brief-actions button { font-size: 15px; padding: 8px 16px; }

/* In-game: persistent corner control to leave the drill. */
#training-exit {
  position: absolute; top: 8px; left: 8px; z-index: 12;
  font-size: 12px; font-weight: bold; padding: 6px 10px;
  background: #2a3140; color: #c9d6e4;
  border: 2px solid var(--slab-border); box-shadow: 0 2px 0 var(--slab-border);
  pointer-events: auto;
}
#training-exit:hover { color: var(--gold); }

/* Unit picker: a row of category tabs over the stat cards for the active tab. */
#unit-tabs {
  display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px;
  border-bottom: 3px solid var(--slab-border);
}
.unit-tab {
  font-size: 12px; font-weight: bold; letter-spacing: 1px;
  padding: 7px 12px; margin-bottom: -3px;
  color: #8d9aa8; background: #161a24;
  border: 3px solid var(--slab-border); box-shadow: none;
}
.unit-tab:active { transform: none; }
.unit-tab.active { color: var(--gold); background: #1b1f2b; border-bottom-color: #1b1f2b; }

#unit-select { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }
.plane-card {
  /* flex-basis sized to the card name so five cards fit a desktop row without
     overflowing; wraps to a second row on narrower windows instead of
     bleeding off the side. */
  flex: 1 1 116px; min-width: 0; padding: 10px 8px;
  background: #11141c; border: 3px solid var(--slab-border);
  cursor: pointer; text-align: left; font-size: 12px;
  color: #b7c6d4;
}
.plane-card h3 { overflow-wrap: anywhere; }
.plane-card.selected { border-color: var(--gold); background: #1b1f2b; }
/* Career-locked hull: dimmed, not selectable, with a requirement badge. */
.plane-card.locked { cursor: not-allowed; opacity: 0.5; position: relative; }
.plane-card.locked:hover { border-color: var(--slab-border); }
.plane-card .lock-badge {
  display: block; margin-top: 6px; padding: 2px 5px;
  background: #2a1d12; border: 1px solid #6b4a23; color: #f0b35a;
  font-size: 10px; letter-spacing: 0.5px; text-align: center; border-radius: 2px;
}
.plane-card h3 { margin: 0 0 4px; font-size: 15px; color: #eef2f6; letter-spacing: 1px; }
.plane-card .stat { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.plane-card .stat label { width: 34px; color: #76838f; font-size: 10px; }
.plane-card .stat .bar { height: 7px; }
.plane-card .role { color: #8d9aa8; font-style: italic; min-height: 2.4em; display: block; margin-bottom: 4px; }

#device-hint { color: #6f8fae; font-size: 12px; margin-top: 4px; }

.controls-help {
  margin: 14px 0; padding: 10px;
  background: rgba(0,0,0,0.3);
  border: 2px solid var(--slab-border);
  font-size: 14px; line-height: 1.8;
}

.blurb { font-size: 13px; color: #b7c6d4; line-height: 1.5; margin-bottom: 0; }
.gold { color: var(--gold); font-weight: bold; }

/* ---------- hud ---------- */
#top-bar {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 14px; align-items: center;
  background: var(--slab);
  border: 3px solid var(--slab-border);
  padding: 6px 14px;
  font-size: 18px; font-weight: bold;
}

.team-chip.crimson { color: var(--crimson); }
.team-chip.cobalt { color: var(--cobalt); }
#timer { color: #eef2f6; }
#zone-state { color: #8d9aa8; letter-spacing: 1px; font-size: 14px; }
#zone-state.crimson { color: var(--crimson); }
#zone-state.cobalt { color: var(--cobalt); }
#zone-state.contested { color: var(--gold); }

#crosshair {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-size: 26px; color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 0 4px #000;
}
#crosshair.hitmarker { color: var(--gold); }

/* Tank main-gun reload readout, just under the crosshair. */
#reload-indicator {
  position: absolute; left: 50%; top: calc(50% + 26px);
  transform: translateX(-50%);
  font-size: 13px; font-weight: 600; letter-spacing: 0.06em;
  white-space: nowrap; text-shadow: 0 0 4px #000; pointer-events: none;
}
#reload-indicator.loading { color: #ffcf6b; }
#reload-indicator.ready { color: #8ef0a0; }

/* Naval turret readout ("GUNS 4/6"), under the reload line. Amber while part
   of the battery is masked, so the broadside nudge reads at a glance. */
#turret-status {
  position: absolute; left: 50%; top: calc(50% + 44px);
  transform: translateX(-50%);
  font-size: 12px; font-weight: 600; letter-spacing: 0.06em;
  color: #9fe7b0; white-space: nowrap; text-shadow: 0 0 4px #000;
  pointer-events: none;
}
#turret-status.partial { color: #ffcf6b; }

#aim-cursor {
  position: absolute; left: 50%; top: 50%;
  font-size: 30px; color: rgba(255, 255, 255, 0.9);
  text-shadow: 0 0 5px #000;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

#lead-pip {
  position: absolute; left: -100px; top: -100px;
  font-size: 20px; color: var(--gold);
  text-shadow: 0 0 4px #000;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* Level-bombing pipper (Leviathan only): a ring marking the predicted bomb
   impact point, with a center cross. Cyan to read distinctly from the gold
   gunnery lead pip. */
#bombsight {
  position: absolute; left: -100px; top: -100px;
  width: 26px; height: 26px;
  transform: translate(-50%, -50%);
  border: 2px solid #5fe3ff;
  border-radius: 50%;
  box-shadow: 0 0 4px #000, inset 0 0 3px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
#bombsight i {
  position: absolute; left: 50%; top: 50%;
  width: 2px; height: 2px;
  background: #5fe3ff;
  box-shadow:
    0 0 3px #000,
    -9px 0 0 -0px #5fe3ff, 9px 0 0 0 #5fe3ff,
    0 -9px 0 0 #5fe3ff, 0 9px 0 0 #5fe3ff;
  transform: translate(-50%, -50%);
}

#protect-banner, #warning-banner {
  position: absolute; left: 50%; transform: translateX(-50%);
  font-weight: bold; letter-spacing: 2px;
  padding: 4px 14px;
  border: 2px solid var(--slab-border);
}
#protect-banner { top: 64px; background: rgba(74, 125, 232, 0.25); color: #bcd2ff; }
#warning-banner { top: 64px; background: rgba(232, 74, 74, 0.3); color: #ffd2d2; }

#flight-data {
  position: absolute; left: 16px; bottom: 16px;
  background: var(--slab); border: 3px solid var(--slab-border);
  padding: 10px 14px; display: flex; flex-direction: column; gap: 6px;
  min-width: 170px;
}
.gauge { display: flex; align-items: baseline; gap: 8px; font-size: 16px; }
.gauge label { color: #8d9aa8; font-size: 12px; width: 32px; }
.gauge span { font-size: 22px; font-weight: bold; min-width: 64px; text-align: right; }
.gauge small { color: #8d9aa8; }

.bar {
  flex: 1; height: 12px; background: #11141c;
  border: 2px solid var(--slab-border); position: relative;
}
.bar .fill { height: 100%; width: 50%; background: var(--gold); }
.bar.big { height: 18px; }

#hp-wrap {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 22px; width: 280px;
}
#hp-fill { background: #62d655; transition: width 0.15s; }
#hp-fill.hurt { background: #e8a23a; }
#hp-fill.critical { background: var(--crimson); }

/* Localized-damage subsystem panel: compact bars above the health bar. */
#subsys {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 46px;
  display: flex; gap: 10px; padding: 4px 8px;
  background: var(--slab); border: 2px solid var(--slab-border);
}
.subsys-cell { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.subsys-cell label { color: #8d9aa8; font-size: 9px; letter-spacing: 0.5px; }
.subsys-bar { width: 48px; height: 5px; background: #11141c; border: 1px solid var(--slab-border); overflow: hidden; }
.subsys-fill { height: 100%; width: 100%; background: #62d655; transition: width 0.2s; }
.subsys-fill.hurt { background: #e8a23a; }
.subsys-fill.crit { background: var(--crimson); }
#pilot-veil {
  position: fixed; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.3s; z-index: 7;
  background: radial-gradient(circle at 50% 50%, rgba(40,0,0,0) 40%, rgba(70,0,0,0.85) 98%);
}

#minimap {
  position: absolute; right: 16px; bottom: 16px;
  border: 3px solid var(--slab-border);
  background: #123;
  image-rendering: pixelated;
}
/* ---------- battleship plot table (big guns targeting) ---------- */
/* The whole-screen plotting surface that replaces the cramped corner chart
   while manning a main battery. A backdrop darkens the 3D world for clarity;
   only the canvas and buttons take pointer events, so the bail control and
   touch zones underneath stay reachable. */
#plot-table {
  position: absolute; inset: 0; z-index: 6;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px;
  pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(6, 10, 16, 0.5), rgba(4, 7, 12, 0.85));
}
#plot-table.hidden { display: none; }
/* While manning the big guns the corner HUD and touch flight cluster give way
   to the plot table. */
body.manning-main #minimap,
body.manning-main #touch-controls { display: none; }

/* The status banner floats over the top of the chart; the action bar floats
   over the bottom. Both ride inside the frame so the chart itself fills the
   full height of the screen. */
#plot-banner {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 2; pointer-events: none;
  font-size: 15px; letter-spacing: 0.08em; text-align: center; white-space: nowrap;
  color: var(--gold);
  background: rgba(8, 12, 18, 0.86);
  border: 2px solid var(--slab-border); border-radius: 6px;
  padding: 7px 16px; max-width: 94%;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}
#plot-banner.ready { color: #7bff8a; }

/* Fire-control solution readout: a brass-cornered plotting slip pinned to the
   top-right of the chart. It lists the data points the ballistic computer
   collected for the firing solution once the solve timer expires. */
#plot-readout {
  position: absolute; top: 14px; right: 14px; z-index: 2; pointer-events: none;
  min-width: 188px; max-width: 38%;
  font-size: 12px; letter-spacing: 0.06em; line-height: normal; text-align: left;
  color: #f0e4c8;
  background: linear-gradient(170deg, rgba(20, 16, 10, 0.93), rgba(10, 8, 5, 0.93));
  border: 2px solid #7a5a32; border-radius: 6px;
  box-shadow: 0 0 0 2px #2c2014, 0 6px 20px rgba(0, 0, 0, 0.55);
  padding: 8px 10px 9px;
}
#plot-readout.hidden { display: none; }
#plot-readout-head {
  font-weight: bold; letter-spacing: 0.16em; font-size: 11px;
  color: #7bff8a; text-align: center;
  padding-bottom: 6px; margin-bottom: 6px;
  border-bottom: 1px solid rgba(122, 90, 50, 0.7);
}
#plot-readout-rows { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; }
#plot-readout-rows dt { color: #b9a778; white-space: nowrap; }
#plot-readout-rows dd {
  margin: 0; text-align: right; font-weight: bold; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#plot-readout-rows dd.hot { color: #ffd76b; }       /* dropped-charge / plunging fire */
#plot-readout-rows dd.good { color: #7bff8a; }      /* spotter-tightened pattern */

#plot-frame { position: relative; pointer-events: none; line-height: 0; }
/* The chart reads as a sheet of nautical paper in a brass-and-leather mount:
   an aged-brass inner edge, a dark leather surround, and a warm inner glow that
   ages the corners of the parchment. */
#plot-canvas {
  pointer-events: auto; touch-action: none; cursor: crosshair;
  border: 3px solid #7a5a32;
  background: #e7d9bd;
  box-shadow:
    0 0 0 3px #2c2014,
    0 14px 36px rgba(0, 0, 0, 0.6),
    inset 0 0 64px rgba(120, 90, 50, 0.22);
}

/* Magnifier loupe: rides above the dragging finger so the aim point is never
   hidden under the thumb. A brass-rimmed lens over the paper chart. */
#plot-loupe {
  position: fixed; z-index: 7; pointer-events: none;
  width: 132px; height: 132px;
  border: 3px solid #7a5a32; border-radius: 50%;
  background: #e7d9bd;
  box-shadow:
    0 0 0 2px #2c2014,
    0 6px 16px rgba(0, 0, 0, 0.6),
    inset 0 0 18px rgba(90, 64, 32, 0.4);
}
#plot-loupe.hidden { display: none; }

#plot-bar {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
  z-index: 2; pointer-events: none;
  display: flex; align-items: center; gap: 12px; max-width: 94%; flex-wrap: wrap;
  justify-content: center; line-height: normal;
}
#plot-bar button {
  pointer-events: auto;
  font: inherit; font-weight: bold; letter-spacing: 1px;
  border: 3px solid var(--slab-border);
  box-shadow: 0 4px 0 var(--slab-border);
  padding: 12px 22px; border-radius: 8px;
  background: rgba(42, 49, 64, 0.92); color: #c9d6e4;
}
#plot-bar button:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--slab-border); }
#plot-reaim { color: var(--gold); }
#plot-primary { min-width: 200px; background: var(--gold); color: #1b1405; }
#plot-primary:disabled {
  background: rgba(42, 49, 64, 0.7); color: #6b7686;
  box-shadow: 0 4px 0 var(--slab-border); transform: none;
}
#plot-primary.set { background: #7bff8a; color: #06210b; }
#plot-primary.fire {
  background: var(--crimson); color: #ffe9e9;
  animation: plot-fire-pulse 0.9s ease-in-out infinite;
}
@keyframes plot-fire-pulse {
  0%, 100% { box-shadow: 0 4px 0 var(--slab-border), 0 0 0 0 rgba(232, 74, 74, 0); }
  50%      { box-shadow: 0 4px 0 var(--slab-border), 0 0 22px 5px rgba(232, 74, 74, 0.6); }
}

#killfeed {
  position: absolute; top: 64px; right: 16px;
  display: flex; flex-direction: column; gap: 4px; align-items: flex-end;
  font-size: 14px;
}
.feed-line {
  background: var(--slab); border: 2px solid var(--slab-border);
  padding: 3px 10px; opacity: 1; transition: opacity 0.6s;
}
.feed-line .crimson { color: var(--crimson); font-weight: bold; }
.feed-line .cobalt { color: var(--cobalt); font-weight: bold; }
.feed-line.fade { opacity: 0; }

#chat {
  position: absolute; left: 16px; bottom: 148px;
  display: flex; flex-direction: column; gap: 4px;
  max-width: min(440px, 44vw);
  font-size: 14px;
}
#chat-log { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.chat-line {
  background: var(--slab); border: 2px solid var(--slab-border);
  padding: 3px 10px; opacity: 1; transition: opacity 0.6s;
  overflow-wrap: anywhere;
}
.chat-line .crimson { color: var(--crimson); font-weight: bold; }
.chat-line .cobalt { color: var(--cobalt); font-weight: bold; }
.chat-line.fade { opacity: 0; }
/* While composing, resurface the recent history. */
#chat.open .chat-line { opacity: 1; }
#chat-entry {
  display: flex; align-items: center; gap: 6px;
  background: var(--slab); border: 2px solid var(--gold);
  padding: 4px 10px;
}
.chat-prompt { color: var(--gold); font-weight: bold; }
#chat-input {
  font: inherit; font-size: 14px;
  flex: 1; min-width: 280px;
  background: transparent; border: none; outline: none;
  color: #eef2f6;
}
#chat-input::placeholder { color: #76838f; }

#message {
  position: absolute; left: 50%; top: 30%;
  transform: translate(-50%, -50%);
  font-size: 30px; font-weight: bold; letter-spacing: 3px;
  text-shadow: 3px 3px 0 #000;
  text-align: center;
}

/* Stream "now playing" chip: shown only in director mode, names the current
   procedural soundtrack theme with a little animated equalizer. */
#now-playing {
  position: absolute; left: 16px; bottom: 16px;
  display: flex; align-items: center; gap: 10px;
  background: var(--slab); border: 2px solid var(--slab-border);
  padding: 6px 12px; font-size: 13px; letter-spacing: 1px;
  box-shadow: 0 3px 0 var(--slab-border);
}
#now-playing.hidden { display: none; }
.np-eq { display: flex; align-items: flex-end; gap: 2px; height: 14px; width: 16px; }
.np-eq span {
  flex: 1; background: var(--gold); height: 100%;
  transform-origin: bottom; animation: np-bounce 0.9s ease-in-out infinite;
}
.np-eq span:nth-child(2) { animation-delay: 0.3s; }
.np-eq span:nth-child(3) { animation-delay: 0.6s; }
@keyframes np-bounce {
  0%, 100% { transform: scaleY(0.25); }
  50% { transform: scaleY(1); }
}
.np-text { display: flex; flex-direction: column; line-height: 1.25; }
.np-label { color: #8d9aa8; font-size: 9px; letter-spacing: 2px; }
.np-name { color: var(--gold); font-weight: bold; }
#now-playing.np-bump { animation: np-flash 0.5s ease-out; }
@keyframes np-flash {
  0% { border-color: var(--gold); box-shadow: 0 0 12px rgba(244, 197, 66, 0.7), 0 3px 0 var(--slab-border); }
  100% { border-color: var(--slab-border); box-shadow: 0 3px 0 var(--slab-border); }
}

/* Killcam badge: persistent for the whole death replay so it plainly reads as
   a killcam and keeps the killer's name on screen (see hud.setKillcamTag). */
#killcam-tag {
  position: absolute; left: 50%; top: 12%;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 14px;
  pointer-events: none; white-space: nowrap;
  animation: kc-in 0.35s ease-out;
}
#killcam-tag.hidden { display: none; }
.kc-rule {
  width: 90px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold));
}
.kc-rule:last-child { transform: scaleX(-1); }
.kc-body { display: flex; flex-direction: column; align-items: center; line-height: 1.2; }
.kc-label {
  color: var(--gold); font-weight: bold;
  font-size: 22px; letter-spacing: 6px;
  text-shadow: 2px 2px 0 #000;
}
.kc-by {
  color: #8d9aa8; font-size: 10px; letter-spacing: 3px;
  text-transform: uppercase; margin-top: 2px;
}
.kc-name {
  color: #fff; font-weight: bold;
  font-size: 17px; letter-spacing: 2px;
  text-shadow: 2px 2px 0 #000;
}
@keyframes kc-in {
  0% { opacity: 0; transform: translateX(-50%) translateY(-8px); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0); }
}
body.touch .kc-label { font-size: 17px; letter-spacing: 4px; }
body.touch .kc-rule { width: 50px; }


/* ---------- respawn screen ----------
   The respawn screen IS the join screen (#join-screen), shown verbatim — same
   masthead, unit picker, deck choice, daily missions and controls. There's no
   death banner; the killcam replay is what names who got you. The `respawning`
   class is only an internal marker (so a per-frame setRespawn(false) won't hide
   the first-join screen before you've spawned), with no visual effect. */

/* LAUNCH FROM base / carrier deck — sits under the unit cards. */
#respawn-deck { margin-top: 4px; margin-bottom: 16px; }
.gs-label {
  width: 100%; font-size: 11px; letter-spacing: 2px; color: #8d9aa8;
  margin-bottom: 6px;
}
.gun-chip {
  padding: 5px 10px; font-size: 12px; letter-spacing: 1px;
  background: #2a3140; color: #c9d6e4;
  border: 2px solid var(--slab-border);
  box-shadow: 0 2px 0 var(--slab-border);
}
.gun-chip.picked { background: var(--gold); color: #1a1408; border-color: var(--gold); }
.gun-chip:disabled { background: #20242e; color: #5a6473; }
.gun-chip.destroyed { text-decoration: line-through; }

/* Daily missions: shown on both the join and respawn screens. */
#respawn-daily { margin: 16px auto 0; max-width: 360px; }
#respawn-daily:empty { display: none; }
.daily-head {
  font-size: 11px; letter-spacing: 2px; color: #8d9aa8; text-align: left;
}
.daily-row { margin-top: 8px; text-align: left; }
.daily-row .daily-desc {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; color: #c9d6e4;
}
.daily-row .daily-have { color: var(--gold); font-variant-numeric: tabular-nums; }
.daily-bar {
  margin-top: 4px; height: 6px;
  background: #20242e; border: 1px solid var(--slab-border);
}
.daily-fill { height: 100%; background: var(--gold); transition: width 0.3s; }
.daily-row.done .daily-desc { color: #7bff8a; }
.daily-row.done .daily-have::before { content: "✓ "; }
.daily-row.done .daily-fill { background: #4cae5a; }

#daily-screen {
  position: absolute; inset: 0; z-index: 30;
  display: flex; align-items: center; justify-content: center;
  background: rgba(6, 10, 16, 0.72);
}
#daily-body { margin: 8px 0; }
#daily-body .daily-row { margin-top: 12px; }

#scoreboard {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  background: var(--slab); border: 4px solid var(--slab-border);
  padding: 16px 24px;
  min-width: 420px;
}
#scoreboard table { width: 100%; border-collapse: collapse; font-size: 16px; }
#scoreboard th { color: #8d9aa8; text-align: left; padding: 4px 10px; border-bottom: 2px solid #2a3140; }
#scoreboard td { padding: 4px 10px; }
#scoreboard tr.me { background: rgba(244, 197, 66, 0.12); }
#scoreboard td.crimson { color: var(--crimson); }
#scoreboard td.cobalt { color: var(--cobalt); }
#scoreboard .bot-tag { color: #76838f; font-size: 12px; }
#scoreboard .title-tag { color: #f4c542; font-size: 11px; letter-spacing: 0.5px; }

/* ============ round intel summary ============ */
#intel-card {
  position: absolute; inset: 0; z-index: 8;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 10, 16, 0.55);
  cursor: pointer;
}
.intel-inner {
  background: var(--slab); border: 4px solid var(--slab-border);
  padding: 20px 28px; text-align: center;
  width: min(580px, 94vw); max-height: 92vh; overflow: auto;
}
#intel-head {
  margin: 0; font-size: 26px; font-weight: bold; letter-spacing: 2px;
  text-shadow: 2px 2px 0 #000;
}
#intel-sub { margin-top: 4px; font-size: 13px; letter-spacing: 1px; color: #b7c6d4; }
#intel-sub .crimson, #intel-cols .crimson, #intel-top .crimson { color: var(--crimson); }
#intel-sub .cobalt, #intel-cols .cobalt, #intel-top .cobalt { color: var(--cobalt); }
#intel-timeline {
  margin-top: 14px; width: 100%; height: auto;
  border: 2px solid var(--slab-border); background: rgba(8, 12, 20, 0.55);
}
#intel-cols { margin-top: 14px; display: flex; gap: 14px; }
.intel-col {
  flex: 1; padding: 8px 10px;
  background: rgba(13, 16, 24, 0.6); border: 2px solid var(--slab-border);
}
.intel-col h3 {
  margin: 0 0 6px; font-size: 14px; letter-spacing: 2px;
  border-bottom: 2px solid #2a3140; padding-bottom: 4px;
}
.intel-col.crimson h3 { color: var(--crimson); }
.intel-col.cobalt h3 { color: var(--cobalt); }
.intel-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; padding: 2px 0; color: #c9d6e4;
}
.intel-ico { width: 18px; text-align: center; }
.intel-val { width: 28px; text-align: right; font-weight: bold; color: #eef2f6; }
.intel-lbl { color: #8d9aa8; letter-spacing: 0.5px; }
#intel-top { margin-top: 14px; }
#intel-top h4 {
  margin: 0 0 6px; font-size: 12px; letter-spacing: 2px; color: #8d9aa8;
}
.intel-ace {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; padding: 2px 0; justify-content: center;
}
.intel-rank {
  width: 18px; height: 18px; line-height: 18px; text-align: center;
  background: var(--gold); color: #1a1408; font-weight: bold; font-size: 12px;
}
.intel-title { color: var(--gold); font-size: 11px; letter-spacing: 0.5px; }
.intel-kills { color: #eef2f6; font-weight: bold; }
.intel-foot { margin-top: 14px; font-size: 11px; letter-spacing: 1px; color: #6c7a89; }
body.touch .intel-inner { padding: 14px 16px; }
body.touch #intel-head { font-size: 20px; }
body.touch .intel-row, body.touch .intel-ace { font-size: 12px; }

#hint-bar {
  position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%);
  font-size: 11px; color: rgba(255,255,255,0.55); text-shadow: 1px 1px 0 #000;
}

#damage-flash {
  position: fixed; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 55%, rgba(220, 40, 40, 0.55) 100%);
  opacity: 0; transition: opacity 0.4s;
}

/* G-meter colour states (the gauge digit). */
#g-load.g-warn { color: #f4c542; }
#g-load.g-crit { color: var(--crimson); }

/* G-physiology veils: black grey-out tunnel and red-out wash. Opacity and
   the vignette radius are driven from hud.gForce(); kept under the HUD. */
#g-veil, #g-redout {
  position: fixed; inset: 0; pointer-events: none; z-index: 3;
  opacity: 0;
}
#g-redout { background: rgba(150, 0, 0, 1); }

/* Elevator-trim gauge: a strip with a centre detent and a tick that rides
   right for nose-up trim, left for nose-down. Dims when auto-trim is off. */
.trim-detent {
  position: absolute; top: -2px; bottom: -2px; left: 50%; width: 1px;
  transform: translateX(-0.5px); background: rgba(255, 255, 255, 0.4);
}
#trim-tick {
  position: absolute; top: -2px; bottom: -2px; width: 3px; left: 50%;
  transform: translateX(-1.5px); background: var(--gold);
  transition: left 0.08s linear;
}
#trim-gauge.off { opacity: 0.4; }
#trim-gauge.off #trim-tick { background: #9aa3ad; }

/* Pre-stall warning flag, just under the crosshair. */
#stall-warn {
  position: absolute; left: 50%; top: 58%; transform: translateX(-50%);
  font-weight: bold; letter-spacing: 3px; font-size: 18px;
  color: #1b1405; background: var(--gold);
  padding: 3px 12px; border: 2px solid var(--slab-border);
  animation: stall-blink 0.45s steps(2, start) infinite;
}
@keyframes stall-blink { 50% { opacity: 0.35; } }

#autopilot-ind {
  position: absolute; left: 50%; top: 96px; transform: translateX(-50%);
  font-weight: bold; letter-spacing: 2px; font-size: 14px;
  color: #bfe6ff; background: rgba(74, 125, 232, 0.22);
  padding: 3px 12px; border: 2px solid var(--slab-border);
}
/* Touch shows engagement on the AP button itself, so skip the centre flag. */
body.touch #autopilot-ind { display: none; }

/* ---------- naval conning panel ---------- */
#naval-panel {
  position: absolute; left: 16px; bottom: 132px;
  display: flex; align-items: center; gap: 10px;
  background: var(--slab); border: 3px solid var(--slab-border);
  padding: 6px 12px; font-size: 14px; font-weight: bold; letter-spacing: 1px;
  /* The chips double as buttons — the touch path to X/R/T/G (and a mouse
     convenience): tap the shell chip to cycle ammo, REPAIR/BOOST/DC to fire
     the matching consumable. Lifted above the touch steer/look zones so a
     tap reaches the chip instead of grabbing the virtual stick. */
  pointer-events: auto;
  z-index: 31;
}
#naval-panel span { cursor: pointer; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
/* On touch the panel tucks under the flight gauges and sits to the RIGHT of the
   throttle slider (left edge, x<~56) so it never covers the engine telegraph.
   It wraps to a compact two-row block and is width-capped to the left third so
   it can't reach the centre gunnery readout or the right-hand button cluster —
   the two collisions that made the naval HUD read as clutter on a phone. */
body.touch #naval-panel {
  font-size: 14px; padding: 7px 9px; gap: 7px 8px;
  left: calc(66px + env(safe-area-inset-left));
  right: auto; bottom: auto; top: 152px;
  flex-wrap: wrap; max-width: 42vw;
}
body.touch #naval-panel span { padding: 3px 8px; }
#naval-shell { padding: 2px 9px; border: 2px solid var(--slab-border); }
#naval-shell.naval-he { color: #ffd05a; background: rgba(244, 197, 66, 0.18); }
#naval-shell.naval-ap { color: #ff8a5a; background: rgba(255, 122, 46, 0.20); }
#naval-shell.naval-ss { color: #ffe39a; background: rgba(255, 227, 154, 0.22); }
#naval-dc.dc-ready { color: #7CFC7C; }
#naval-dc.dc-active { color: #bfe6ff; }
#naval-dc.dc-cooldown { color: #8d9aa8; }
#naval-dot { color: #ff7b2e; font-size: 13px; }
#naval-torp { padding: 2px 8px; border: 2px solid var(--slab-border); }
#naval-torp.torp-ready { color: #7CFC7C; }
#naval-torp.torp-cooldown { color: #8d9aa8; }

/* ---------- naval binocular gunsight ---------- */
#naval-scope { position: absolute; inset: 0; pointer-events: none; z-index: 30; }
/* A soft optical vignette so it reads as "through the glass". */
#naval-scope .scope-mask {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 50%,
    rgba(0,0,0,0) 30%, rgba(0,0,0,0.18) 52%, rgba(0,0,0,0.72) 70%, rgba(0,0,0,0.92) 100%);
}
/* WoWS-style reticle: a wide horizontal lead scale with notches rising off
   it, and a short vertical centre stroke — not a full crosshair. */
#naval-scope .scope-reticle {
  position: absolute; left: 50%; top: 50%; width: min(80vw, 980px); height: 46vh;
  transform: translate(-50%, -50%);
}
#naval-scope .sr-h {
  position: absolute; top: 50%; left: 0; height: 1px; width: 100%;
  transform: translateY(-0.5px); background: rgba(120,230,150,0.55);
}
#naval-scope .sr-vc {
  position: absolute; left: 50%; top: 50%; width: 1px; height: 36px;
  transform: translate(-0.5px, -50%); background: rgba(120,230,150,0.9);
}
/* Lead notches: minor every half unit, taller numbered majors every unit
   (one unit = a nominal hull's travel over one shell flight — main.js lays
   them out). They rise off the scale line like a ruler. */
#naval-scope .sr-notch {
  position: absolute; top: 50%; width: 1px; height: 9px;
  transform: translate(-0.5px, -100%); background: rgba(120,230,150,0.7);
}
#naval-scope .sr-notch.major {
  height: 16px; background: rgba(120,230,150,0.95);
}
#naval-scope .sr-notch.major::after {
  content: attr(data-n);
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  color: rgba(120,230,150,0.85); font-size: 10px; letter-spacing: 0;
}
#naval-scope .scope-label {
  position: absolute; left: 50%; bottom: 7%; transform: translateX(-50%);
  color: rgba(120,230,150,0.8); font-size: 12px; letter-spacing: 2px;
}
/* Range-dial hold buttons: the touch path to "aim for distance" (desktop has
   the mouse and the scroll wheel too). Parked on the right edge, inside the
   scope glass, big enough for thumbs. */
#naval-scope .scope-rng-btns {
  position: absolute; right: calc(3% + env(safe-area-inset-right)); top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 14px;
  pointer-events: auto;
}
#naval-scope .scope-rng-btns button {
  width: 58px; height: 58px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font: 600 15px/1.1 inherit; letter-spacing: 1px;
  color: rgba(140,240,165,0.95);
  background: rgba(10, 30, 18, 0.45);
  border: 1px solid rgba(120,230,150,0.55);
  touch-action: none; user-select: none; -webkit-user-select: none;
}
#naval-scope .scope-rng-btns button small { font-size: 9px; letter-spacing: 2px; opacity: 0.8; }
#naval-scope .scope-rng-btns button.held { background: rgba(120,230,150,0.3); }
/* Bigger thumb targets on coarse pointers. */
body.touch #naval-scope .scope-rng-btns button { width: 72px; height: 72px; }
/* Rangefinder readout: live range to the sighted target and the locked solution. */
#naval-scope .scope-range {
  position: absolute; left: 50%; top: 16%; transform: translateX(-50%);
  color: rgba(120,230,150,0.92); font-size: 15px; letter-spacing: 2px;
  text-align: center; line-height: 1.5; text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}
#naval-scope .scope-range .set { color: #7CFC7C; font-weight: 600; }
#naval-scope .scope-range .max { color: #ff8f7a; font-weight: 600; }
#naval-scope .scope-range .nolock { color: rgba(120,230,150,0.55); }

/* ---------- touch controls ---------- */
#touch-controls { position: absolute; inset: 0; pointer-events: none; }

.tc-zone { position: absolute; pointer-events: auto; touch-action: none; }
#tc-steer-zone { left: 0; top: 56px; bottom: 0; width: 50%; }
#tc-look-zone { right: 0; top: 56px; bottom: 0; width: 50%; }

#tc-stick-base {
  position: absolute; width: 124px; height: 124px;
  margin: -62px 0 0 -62px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.4);
  background: rgba(24, 28, 38, 0.3);
  display: none; pointer-events: none;
}
#tc-stick-base.on { display: block; }
#tc-stick-knob {
  position: absolute; left: 50%; top: 50%; width: 52px; height: 52px;
  margin: -26px 0 0 -26px;
  border-radius: 50%;
  background: rgba(244, 197, 66, 0.9);
  border: 3px solid var(--slab-border);
  box-shadow: 0 2px 0 var(--slab-border);
}

.tc-btn {
  position: absolute; pointer-events: auto; touch-action: none;
  border-radius: 50%;
  border: 3px solid var(--slab-border);
  box-shadow: 0 4px 0 var(--slab-border);
  font: inherit; font-weight: bold; letter-spacing: 1px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.tc-btn:active { transform: none; } /* the generic button press-drop reads as jitter here */
.tc-btn.held { transform: scale(0.92); box-shadow: 0 1px 0 var(--slab-border); }

#tc-fire {
  width: 96px; height: 96px; font-size: 17px;
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(24px + env(safe-area-inset-bottom));
  background: rgba(244, 197, 66, 0.88); color: #1b1405;
}
#tc-bomb {
  width: 64px; height: 64px; font-size: 12px;
  right: calc(124px + env(safe-area-inset-right));
  bottom: calc(44px + env(safe-area-inset-bottom));
  background: rgba(232, 74, 74, 0.85); color: #ffe9e9;
}
#tc-bail {
  display: none;
  width: 64px; height: 64px; font-size: 12px;
  right: calc(124px + env(safe-area-inset-right));
  bottom: calc(44px + env(safe-area-inset-bottom));
  background: rgba(42, 49, 64, 0.9); color: #c9d6e4;
}
#touch-controls.gun-mode #tc-bail { display: flex; }
#touch-controls.gun-mode #tc-bomb,
#touch-controls.gun-mode #tc-throttle { display: none; }
/* Drive mode (vehicle / warship): keep the throttle — the engine telegraph —
   and the BOMB button (torpedoes at sea); swap AP for BAIL (leave the ship).
   BAIL shares the BOMB slot in gun mode, so shift it clear here. */
#touch-controls.drive-mode #tc-bail {
  display: flex;
  right: calc(284px + env(safe-area-inset-right));
}
#touch-controls.drive-mode #tc-autopilot { display: none; }
#tc-zoom {
  width: 64px; height: 64px; font-size: 12px;
  right: calc(204px + env(safe-area-inset-right));
  bottom: calc(44px + env(safe-area-inset-bottom));
  background: rgba(64, 168, 108, 0.82); color: #eafff0;
}

/* Autopilot toggle: a small pill tucked under the top bar on the freelook side,
   out of the way of the stick, throttle, and fire cluster. Dim when idle, lit
   blue when engaged (it doubles as the on-screen state, so no extra HUD chrome
   is needed on touch). Hidden while manning a gun or driving. */
#tc-autopilot {
  width: 50px; height: 50px; font-size: 14px;
  top: calc(64px + env(safe-area-inset-top));
  right: calc(14px + env(safe-area-inset-right));
  background: rgba(24, 28, 38, 0.5); color: #9fb4cc;
}
#tc-autopilot.on { background: rgba(74, 125, 232, 0.85); color: #eaf2ff; }
#touch-controls.gun-mode #tc-autopilot { display: none; }

/* Spectate vantage controls — bottom-centre PREV/NEXT pills. The bar itself
   is click-through so taps between the buttons fall to the playfield. */
#tc-spectate {
  position: absolute; pointer-events: none;
  left: 50%; transform: translateX(-50%);
  bottom: calc(22px + env(safe-area-inset-bottom));
  display: flex; gap: 18px; z-index: 5;
}
#tc-spectate .tc-btn {
  position: static; pointer-events: auto;
  width: 128px; height: 54px; border-radius: 27px;
  font-size: 15px;
  background: rgba(42, 49, 64, 0.9); color: #c9d6e4;
}

#tc-throttle {
  position: absolute; pointer-events: auto; touch-action: none;
  left: calc(12px + env(safe-area-inset-left));
  bottom: calc(64px + env(safe-area-inset-bottom));
  width: 44px; height: 36%;
  background: rgba(24, 28, 38, 0.45);
  border: 3px solid var(--slab-border);
  display: flex; align-items: flex-end;
}
#tc-throttle-fill { width: 100%; background: rgba(244, 197, 66, 0.8); }
#tc-throttle span {
  position: absolute; left: 50%; top: -20px; transform: translateX(-50%);
  font-size: 11px; color: rgba(255, 255, 255, 0.7);
}

/* ---------- iOS "add to home screen" hint (join screen) ---------- */
#ios-install-hint {
  position: relative;
  margin: 12px auto 0;
  max-width: 360px;
  padding: 10px 30px 10px 12px;
  border: 2px solid var(--gold);
  border-radius: 4px;
  background: rgba(244, 197, 66, 0.1);
  color: #e9eefa;
  font-size: 13px;
  line-height: 1.45;
  text-align: left;
}
#ios-install-hint b { color: var(--gold); }
#ios-install-hint.hidden { display: none; }
.ios-share-glyph {
  display: inline-block;
  padding: 0 5px;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-weight: bold;
}
#ios-install-dismiss {
  position: absolute;
  top: 2px; right: 4px;
  border: none; background: none;
  color: #9aa6bf; font-size: 20px; line-height: 1;
  cursor: pointer; padding: 2px 6px;
}
#ios-install-dismiss:hover { color: #e9eefa; }

/* ---------- rotate-to-landscape gate ---------- */
#rotate-overlay {
  display: none; position: fixed; inset: 0; z-index: 50;
  align-items: center; justify-content: center; text-align: center;
  background: rgba(10, 14, 22, 0.94);
  pointer-events: auto;
}
.rotate-card { font-size: 20px; font-weight: bold; letter-spacing: 3px; color: var(--gold); }
.rotate-icon { font-size: 64px; line-height: 1.2; }
@media (orientation: portrait) {
  body.touch #rotate-overlay { display: flex; }
}

/* ---------- mobile hud layout (body.touch) ---------- */
body.touch #hint-bar { display: none; }
body.touch #top-bar {
  pointer-events: auto; /* tap toggles the scoreboard */
  top: max(6px, env(safe-area-inset-top));
  gap: 10px; padding: 4px 10px; font-size: 14px;
}
body.touch #zone-state { font-size: 11px; }
/* Gauges move out from under the left thumb, up to the top-left corner. */
body.touch #flight-data {
  left: calc(10px + env(safe-area-inset-left));
  top: 48px; bottom: auto;
  padding: 6px 10px; gap: 3px; min-width: 132px;
}
body.touch .gauge { font-size: 13px; gap: 6px; }
body.touch .gauge span { font-size: 16px; min-width: 46px; }
body.touch #minimap {
  width: 112px; height: 112px;
  top: 48px; bottom: auto;
  right: calc(10px + env(safe-area-inset-right));
}
/* Plot table: tighten the action bar and banner for short landscape phones so
   the chart canvas can claim more of the limited height. */
body.touch #plot-table { gap: 8px; }
body.touch #plot-banner { font-size: 12px; padding: 5px 12px; }
body.touch #plot-bar { gap: 8px; }
body.touch #plot-bar button { padding: 9px 16px; }
body.touch #plot-primary { min-width: 150px; }
body.touch #plot-readout { top: 10px; right: 10px; min-width: 150px; font-size: 11px; padding: 6px 8px 7px; }
body.touch #plot-readout-rows { gap: 2px 8px; }
body.touch #killfeed { top: 172px; font-size: 12px; }
body.touch #chat {
  left: calc(10px + env(safe-area-inset-left));
  bottom: auto; top: 180px;
  max-width: 38vw; font-size: 12px;
}
body.touch #hp-wrap { width: 200px; bottom: 12px; }
body.touch #message { font-size: 22px; letter-spacing: 2px; }

/* ---------- naval theater, touch: de-stack the small-screen HUD ----------
   The ship overlays (RNG readout, DETECTED banner, fleet orders, the gunnery
   readouts, and the range dial) all wanted the same slivers of a phone screen
   and piled on top of each other. Give each its own lane. */
/* Fleet orders / callouts wrap tight and sit in their own lane just under the
   DETECTED banner — above the conning panel (top 152) — instead of a full-width
   wall of text that slid behind the panel. */
body.naval.touch #message {
  font-size: 16px; letter-spacing: 1px; top: 124px;
  /* Symmetric left/right (not left:50%) so a centred message can use the full
     width instead of shrink-to-fitting into the right half and stacking tall. */
  left: 9vw; right: 9vw; max-width: none;
  transform: translateY(-50%); line-height: 1.25;
}
/* RNG rangefinder drops below the DETECTED banner (top ~64) rather than landing
   on it. */
body.naval.touch #naval-scope .scope-range {
  top: 96px; font-size: 14px; letter-spacing: 1.5px;
}
/* While scoped the binocular view is the point; hand the minimap's top-right
   corner to the range dial so the two stop overlapping, and pull the killfeed
   in clear of the dial that now lives on that edge. */
body.naval-scoped.touch #minimap { display: none; }
body.naval-scoped.touch #killfeed { right: calc(96px + env(safe-area-inset-right)); }
/* The range dial rides the right edge, vertically centred in the corner the
   minimap just vacated — clear of the FIRE cluster below it. */
body.naval.touch #naval-scope .scope-rng-btns { gap: 14px; }
body.naval.touch #naval-scope .scope-rng-btns button { width: 64px; height: 64px; }
/* Keep the two-line control brief / gunsight label from riding on the ranging
   bar at the very bottom. */
body.naval.touch #naval-scope .scope-label {
  bottom: calc(34px + env(safe-area-inset-bottom)); font-size: 11px;
}
/* The gunnery readouts (● READY, GUNS n/n — swing broadside) live under the
   crosshair on desktop; on a phone that dead-centre band collides with the
   conning panel, the reticle, and (centred) the BAIL button. Anchor them in the
   free bottom-left corner — right of the throttle, below the panel, left of the
   health bar — where nothing else competes. */
body.naval.touch #reload-indicator,
body.naval.touch #turret-status {
  left: calc(66px + env(safe-area-inset-left)); transform: none;
  top: auto; text-align: left;
}
body.naval.touch #reload-indicator { bottom: calc(74px + env(safe-area-inset-bottom)); }
body.naval.touch #turret-status {
  bottom: calc(54px + env(safe-area-inset-bottom)); font-size: 11px;
}
/* The respawn screen is the join screen, so it inherits the join screen's
   touch overlay-scroll and sizing — nothing respawn-specific to style. */
body.touch #scoreboard { min-width: 0; width: min(480px, 94vw); padding: 10px 12px; }
body.touch #scoreboard table { font-size: 13px; }
body.touch .gun-chip { padding: 7px 12px; } /* finger-sized */

/* ---------- small screens (phones, narrow windows) ---------- */
@media (max-width: 760px), (max-height: 560px) {
  /* The overlay-scroll setup now lives in the base rule; here we just allow
     vertical panning on touch and shrink the card to fit narrow viewports. */
  #join-screen, #disconnect-screen { touch-action: pan-y; }
  .join-card {
    padding: 14px 16px; max-width: 94vw;
  }
  .title { font-size: 32px; letter-spacing: 3px; text-shadow: 2px 2px 0 #7a5a12, 4px 4px 0 rgba(0,0,0,0.35); }
  .title.small { font-size: 26px; }
  .tagline { margin-bottom: 10px; font-size: 12px; }
  /* Phones swipe the tab row and the card row sideways rather than wrapping. */
  #unit-tabs { flex-wrap: nowrap; overflow-x: auto; touch-action: pan-x; }
  #unit-select { flex-wrap: nowrap; overflow-x: auto; touch-action: pan-x; }
  .unit-tab { flex: 0 0 auto; }
  .plane-card { flex: 0 0 auto; min-width: 116px; }
  .controls-help { margin: 10px 0; padding: 8px; font-size: 11px; line-height: 1.6; }
  .blurb { font-size: 11px; }
  #name-input { width: 150px; font-size: 16px; }
  .join-row { flex-wrap: wrap; }
  .join-row button { font-size: 16px; padding: 8px 14px; }
}

/* ---------- about page ----------
   An editorial redesign set in Jost — a geometric sans that's deliberately
   unlike the chunky monospace game UI, on a deep cinematic backdrop that lets
   the in-engine stills carry the page. Still flying the brand palette
   (gold / cobalt / crimson) for accents. Everything below is scoped to
   .about-body so the game and blog surfaces are untouched. */
.about-body {
  /* Unlike the playfield, the about page scrolls. Keep the base `height: 100%`
     (html is `overflow: hidden`, so the body itself must be the scroll
     container) and just let it scroll its overflow — overriding the height to
     `auto` here lets the body grow past the clipped html and kills scrolling. */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background:
    radial-gradient(140% 90% at 50% -10%, rgba(58, 96, 148, 0.45), transparent 62%),
    linear-gradient(180deg, #101926 0%, #0a1019 100%);
  background-attachment: fixed;
  color: #d7e2ee;
  /* Jost first; the system sans stack covers the brief flash before it loads. */
  font-family: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
#about-page {
  min-height: 100%;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 64px 22px 80px;
}
.about-card {
  max-width: 760px; width: 100%;
  text-align: left;
  /* Drop the join modal's chunky slab entirely — the about page reads as a
     clean editorial column, not a game panel. (This also undoes the join
     modal's narrow-viewport fixed-height inner scroll box, which would
     otherwise clip the long content on mobile.) */
  background: none; border: 0; box-shadow: none; padding: 0;
  max-height: none; overflow: visible;
}

/* Masthead: the wordmark and tagline, centered above the lede. */
.about-card .title {
  text-align: center;
  margin: 0 0 10px;
  font-family: "Jost", sans-serif;
  font-weight: 700; font-size: 68px; letter-spacing: 6px;
  line-height: 1;
  color: var(--gold);
  text-shadow: 0 4px 28px rgba(244, 197, 66, 0.22);
}
.about-card .title-tld { color: #f1f6fb; text-shadow: none; }
.about-card .tagline {
  text-align: center;
  margin: 0 0 30px;
  font-weight: 300; font-size: 14px;
  letter-spacing: 5px; text-transform: uppercase;
  color: #89a1ba;
}
.about-body .about-lede {
  max-width: 620px; margin: 0 auto 8px; text-align: center;
  font-weight: 300; font-size: 19px; line-height: 1.6; color: #aebdcd;
}
.about-body .shot-hint { color: var(--gold); font-weight: 400; }

/* Livestream embed: a 16:9 responsive frame on the same cinematic backdrop as
   the gallery stills. The padding-top trick holds the aspect ratio while the
   iframe is absolutely positioned to fill it at any width. */
.about-body .live-embed {
  position: relative;
  width: 100%;
  margin: 36px 0 0;
  padding-top: 56.25%;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45);
}
.about-body .live-embed iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}

/* Sections: a tracked gold kicker heading over a comfortable reading column. */
.about-body .about-section { margin: 52px 0; }
.about-body .about-section + .about-section {
  /* Clearer breaks between sections: a hairline rule above each. */
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: 52px;
}
.about-body .about-section h2 {
  margin: 0 0 16px;
  font-family: "Jost", sans-serif;
  font-weight: 600; font-size: 15px; letter-spacing: 5px;
  text-transform: uppercase; color: var(--gold);
  text-shadow: none;
}
.about-body .about-section p {
  margin: 0 0 14px; font-weight: 400; font-size: 17px;
  line-height: 1.75; color: #c2d2e2;
}
.about-body .about-section p:last-of-type { margin-bottom: 0; }
.about-body .about-section b { font-weight: 600; color: #e6eef7; }
.about-body .about-section .controls-help { text-align: left; }
.about-body .crimson-text { color: var(--crimson); font-weight: 600; }
.about-body .cobalt-text { color: var(--cobalt); font-weight: 600; }
.about-body .gold { color: var(--gold); font-weight: 600; }

/* Gallery: staged in-engine stills (tools/screenshots), two-up on desktop. */
.about-body .shot-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin: 26px 0 0;
}
.about-body .shot-grid figure { margin: 0; position: relative; }
.about-body .shot-grid img {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 5px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  image-rendering: auto;
  cursor: zoom-in;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.about-body .shot-grid img:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.55);
}
/* Affordance hinting that a still opens full size on tap/click. */
.about-body .shot-grid figure::after {
  content: "\2922"; /* diagonal expand arrows */
  position: absolute; top: 10px; right: 10px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; color: #fff;
  background: rgba(13, 15, 21, 0.66);
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 4px;
  pointer-events: none;
  opacity: 0.85;
}
.about-body .shot-grid figcaption {
  margin-top: 11px;
  font-weight: 300; font-size: 13px; line-height: 1.55; color: #93a8be;
}
.about-body .shot-wide { grid-column: 1 / -1; }

/* ---------- full-size image viewer (about gallery) ---------- */
body.lightbox-open { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(6, 10, 18, 0.93);
  cursor: zoom-out;
}
.lightbox.hidden { display: none; }
.lightbox-figure {
  margin: 0; max-width: 100%; max-height: 100%;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.lightbox-img {
  max-width: 100%; max-height: 80vh; max-height: 80dvh;
  width: auto; height: auto;
  border: 3px solid var(--slab-border);
  box-shadow: 0 6px 0 rgba(0, 0, 0, 0.45);
  image-rendering: auto;
}
.lightbox-caption {
  max-width: 680px; text-align: center;
  font-size: 13px; line-height: 1.5; color: #c4d2df;
}
.lightbox-close {
  position: fixed; top: 12px; right: 16px;
  width: 44px; height: 44px;
  font-size: 30px; line-height: 1; font-weight: bold;
  color: #fff; background: var(--slab);
  border: 3px solid var(--slab-border);
  cursor: pointer;
}
.lightbox-close:active { transform: translateY(2px); }

/* ===================================================================
   Dev log (blog)
   Matches the About page: the same Jost editorial treatment set on the
   deep cinematic backdrop, a centered gold wordmark masthead, tracked
   gold kickers, and the gold pill CTAs. The brand palette leads with
   gold for accents. Everything is scoped to .blog-body so the game UI
   and the About page are untouched.
   =================================================================== */
.blog-body {
  /* Like the About page, the blog scrolls. Keep the base `height: 100%` (html
     is `overflow: hidden`, so the body itself must be the scroll container) and
     just let it scroll its overflow — overriding the height to `auto` here lets
     the body grow past the clipped html and kills scrolling on the detail
     pages. */
  min-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Same cinematic gradient as the About page, fixed behind the scroll. */
  background:
    radial-gradient(140% 90% at 50% -10%, rgba(58, 96, 148, 0.45), transparent 62%),
    linear-gradient(180deg, #101926 0%, #0a1019 100%);
  background-attachment: fixed;
  color: #d7e2ee;
  /* Jost first, the system sans stack covers the flash before it loads. */
  font-family: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: text; user-select: text;
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}
.blog-wrap {
  max-width: 760px;
  margin: 0 auto;
  padding: 64px 22px 80px;
}

/* Masthead: centered gold wordmark over a tracked Dev Log kicker,
   mirroring the About page's title/tagline treatment. */
.blog-masthead {
  text-align: center;
  margin: 0 0 44px;
}
.blog-brand {
  display: inline-block;
  font-family: "Jost", sans-serif;
  font-weight: 700; font-size: 68px; letter-spacing: 6px; line-height: 1;
  color: var(--gold); text-decoration: none;
  text-shadow: 0 4px 28px rgba(244, 197, 66, 0.22);
}
.blog-brand span { color: #f1f6fb; text-shadow: none; }
.blog-kicker {
  display: block; margin: 12px 0 0;
  font-weight: 300; font-size: 14px;
  letter-spacing: 5px; text-transform: uppercase; color: #89a1ba;
}

/* ---- index listing ---- */
.blog-lede {
  max-width: 620px; margin: 0 auto; text-align: center;
  font-weight: 300; font-size: 19px; line-height: 1.6; color: #aebdcd;
}
.post-list { list-style: none; margin: 44px 0 0; padding: 0; }
.post-item { padding: 36px 0; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.post-item:first-child { border-top: 0; }
.post-link { display: block; text-decoration: none; color: inherit; }
.post-date {
  font-size: 13px; letter-spacing: 3px; text-transform: uppercase;
  font-weight: 500; color: var(--gold);
}
.post-title {
  margin: 12px 0; font-family: "Jost", sans-serif;
  font-size: 27px; line-height: 1.3; font-weight: 600; color: #f3f6f9;
}
.post-link:hover .post-title { color: var(--gold); }
.post-excerpt { margin: 0; font-weight: 400; font-size: 17px; line-height: 1.7; color: #c2d2e2; }
.post-more {
  display: inline-block; margin-top: 16px;
  font-family: "Jost", sans-serif;
  font-size: 14px; letter-spacing: 2px; text-transform: uppercase;
  font-weight: 600; color: var(--gold);
}
.post-link:hover .post-more { text-decoration: underline; }

/* ---- long-form article ---- */
.post-breadcrumb { margin: 0 0 32px; font-size: 14px; letter-spacing: 1px; }
.blog-article a, .post-breadcrumb a {
  color: var(--gold); text-decoration: none;
}
.blog-article a:hover, .post-breadcrumb a:hover {
  color: #ffd45e; text-decoration: underline;
}
.article-title {
  margin: 0 0 16px; font-family: "Jost", sans-serif;
  font-size: 40px; line-height: 1.16; font-weight: 700;
  letter-spacing: 0; color: #f3f6f9;
}
.article-meta {
  margin: 0 0 36px; font-size: 14px; letter-spacing: 3px;
  text-transform: uppercase; font-weight: 500; color: var(--gold);
}
.article-standfirst {
  margin: 0 0 40px; padding-left: 20px;
  border-left: 3px solid var(--gold);
  font-weight: 300; font-size: 21px; line-height: 1.6; color: #aebdcd;
}
.blog-article h2 {
  margin: 52px 0 16px; font-family: "Jost", sans-serif;
  font-size: 24px; line-height: 1.3; font-weight: 600;
  letter-spacing: 0; color: #f3f6f9;
}
.blog-article p { margin: 0 0 20px; font-size: 17px; line-height: 1.78; color: #c2d2e2; }
.blog-article ul { margin: 0 0 20px; padding-left: 26px; }
.blog-article li { margin: 0 0 14px; font-size: 17px; line-height: 1.78; color: #c2d2e2; }
.blog-article b, .blog-article strong { color: #e6eef7; font-weight: 600; }
.blog-article em { font-style: italic; color: #e6ebf1; }
.blog-article blockquote {
  margin: 30px 0; padding: 4px 0 4px 22px;
  border-left: 3px solid var(--gold);
  font-weight: 300; font-size: 21px; line-height: 1.55; font-style: italic; color: #e6ebf1;
}
.blog-article code {
  font-family: ui-monospace, "SF Mono", Menlo, "Courier New", monospace;
  font-size: 0.86em; padding: 2px 6px; border-radius: 4px;
  background: rgba(255, 255, 255, 0.08); color: #e6ebf1;
}
.blog-article pre {
  margin: 0 0 24px; padding: 16px 18px; overflow-x: auto;
  background: rgba(10, 16, 25, 0.6); border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 8px; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}
.blog-article pre code {
  background: none; padding: 0; border-radius: 0;
  font-size: 13.5px; line-height: 1.7; color: #c2d2e2; white-space: pre;
}
.article-figure { margin: 32px 0 36px; }
.article-figure img {
  display: block; width: 100%; height: auto; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.4);
}
.article-figure figcaption {
  margin-top: 12px; font-size: 14px; line-height: 1.6;
  color: #9fb0c2; font-style: italic;
}

/* ---- footer actions: the About page's gold pill + tracked text link ---- */
.blog-foot {
  margin-top: 56px; padding-top: 36px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex; align-items: center; gap: 28px;
}
.blog-cta {
  display: inline-block; text-decoration: none;
  font-family: "Jost", sans-serif;
  font-weight: 600; font-size: 15px; letter-spacing: 3px; text-transform: uppercase;
  padding: 13px 30px; border-radius: 6px;
  color: #15171c; background: var(--gold);
  box-shadow: 0 6px 20px rgba(244, 197, 66, 0.28);
  transition: background 0.16s ease, transform 0.12s ease, box-shadow 0.16s ease;
}
.blog-cta:hover {
  background: #ffd45e;
  box-shadow: 0 8px 26px rgba(244, 197, 66, 0.4);
}
.blog-cta:active {
  transform: translateY(2px);
  box-shadow: 0 3px 12px rgba(244, 197, 66, 0.28);
}
.blog-foot a:not(.blog-cta) {
  font-family: "Jost", sans-serif;
  font-weight: 500; font-size: 14px; letter-spacing: 3px;
  text-transform: uppercase; color: #8ba0b6; text-decoration: none;
}
.blog-foot a:not(.blog-cta):hover { color: var(--gold); }

@media (max-width: 640px) {
  .blog-wrap { padding: 40px 18px 64px; }
  .blog-masthead { margin-bottom: 36px; }
  .blog-brand { font-size: 44px; letter-spacing: 4px; }
  .blog-kicker { letter-spacing: 4px; }
  .blog-lede { font-size: 16px; }
  .post-title { font-size: 23px; }
  .article-title { font-size: 30px; }
  .article-standfirst { font-size: 18px; }
  .blog-article h2 { font-size: 21px; margin-top: 44px; }
  .blog-article p, .blog-article li { font-size: 16px; }
  .blog-article blockquote { font-size: 19px; }
  .blog-foot { gap: 20px; margin-top: 44px; padding-top: 28px; }
}

.about-actions { margin-top: 28px; }
.btn-link {
  display: inline-block;
  font-weight: bold; font-size: 18px;
  padding: 10px 22px;
  color: #1b1405; background: var(--gold);
  border: 3px solid var(--slab-border);
  box-shadow: 0 4px 0 var(--slab-border);
  text-decoration: none; letter-spacing: 1px;
}
.btn-link:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--slab-border); }

/* About page: the controls cheat-sheet and footer actions, on-brand with the
   Jost editorial treatment rather than the chunky game-UI slab. */
.about-body .controls-help {
  margin: 22px 0 0; padding: 18px 20px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 6px;
  font-weight: 300; font-size: 15px; line-height: 1.9; color: #b9c8d8;
}
.about-body .controls-help b { font-weight: 600; color: #eef4fa; }
.about-body .about-actions {
  display: flex; align-items: center; gap: 28px;
  margin-top: 56px; padding-top: 36px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.about-body .btn-link {
  font-family: "Jost", sans-serif;
  font-weight: 600; font-size: 15px; letter-spacing: 3px;
  text-transform: uppercase;
  padding: 13px 30px;
  border: 0; border-radius: 6px;
  box-shadow: 0 6px 20px rgba(244, 197, 66, 0.28);
  transition: background 0.16s ease, transform 0.12s ease, box-shadow 0.16s ease;
}
.about-body .btn-link:hover {
  background: #ffd45e;
  box-shadow: 0 8px 26px rgba(244, 197, 66, 0.4);
}
.about-body .btn-link:active {
  transform: translateY(2px);
  box-shadow: 0 3px 12px rgba(244, 197, 66, 0.28);
}
.about-body .about-actions .footer-link {
  font-family: "Jost", sans-serif;
  font-weight: 500; font-size: 14px; letter-spacing: 3px;
  text-transform: uppercase; color: #8ba0b6;
  border-bottom: 0;
}
.about-body .about-actions .footer-link:hover { color: var(--gold); }

@media (max-width: 760px) {
  /* Trim the page gutters so the 16:9 stills get the full screen width
     instead of being squeezed into a narrow column. */
  #about-page { padding: 32px 14px 56px; }
  .about-card .title { font-size: 44px; letter-spacing: 4px; }
  .about-card .tagline { font-size: 12px; letter-spacing: 4px; margin-bottom: 24px; }
  .about-body .about-lede { font-size: 16px; }
  .about-body .about-section { margin: 38px 0; }
  .about-body .about-section + .about-section { padding-top: 38px; }
  .about-body .about-section h2 { font-size: 14px; letter-spacing: 4px; }
  .about-body .about-section p { font-size: 16px; }
  /* Stack the gallery one-up; full document width per shot, nothing cropped. */
  .about-body .shot-grid { grid-template-columns: 1fr; gap: 18px; }
  .about-body .shot-grid figcaption { font-size: 13px; }
  .about-body .controls-help { font-size: 14px; }
  .about-body .about-actions { gap: 20px; margin-top: 40px; padding-top: 28px; }
}
