html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #02030a;
  color: #cfe4ff;
  font-family: "Segoe UI", system-ui, sans-serif;
}

#app {
  display: grid;
  height: 100%;
}

#app > * {
  grid-area: 1 / 1;
  min-width: 0;
  min-height: 0;
}

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

#hud {
  pointer-events: none;
  user-select: none;
  display: grid;
  place-items: center;   /* centres the reticle ring on the true screen centre */
}

/* ---- Flight panel (top left): every gauge except radar + score ---- */
#panel {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 250px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 13px 15px 11px;
  background: linear-gradient(160deg, rgba(8, 20, 38, 0.74), rgba(6, 12, 24, 0.5));
  border: 1px solid rgba(124, 214, 255, 0.35);
  box-shadow: 0 0 20px rgba(20, 90, 150, 0.25), inset 0 0 26px rgba(30, 120, 180, 0.08);
  backdrop-filter: blur(3px);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%);
}

.p-row {
  display: flex;
  align-items: center;
  gap: 9px;
}

.p-label {
  flex: none;
  width: 52px;
  font-size: 10px;
  letter-spacing: 2px;
  color: #7fd4ff;
  opacity: 0.85;
}

.p-row .track {
  flex: 1;
  width: auto;
  height: 9px;
}

.p-sep {
  height: 1px;
  margin: 3px 0 1px;
  background: linear-gradient(90deg, rgba(124, 214, 255, 0.45), rgba(124, 214, 255, 0));
}

.p-stats {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 12px;
  letter-spacing: 2px;
  color: #cfe9ff;
}

/* ---- Score + level: inside the TOP of the ring, under the SHIELD arc ---- */
#score-box {
  position: absolute;
  left: 0;
  right: 0;
  top: 14vh;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

/* Same rendered size as the SVG gauge labels: those are 15 units in a 1000-unit
   viewBox drawn at min(1400px, 98vh) -> min(21px, 1.47vh). */
#score {
  font-size: min(21px, 1.47vh);
  letter-spacing: 3px;
  color: #eaf6ff;
  text-shadow: 0 0 12px rgba(80, 200, 255, 0.55);
}

#level {
  font-size: 11px;
  letter-spacing: 4px;
  color: #7fd4ff;
  opacity: 0.85;
}

/* ---- Lives: three small ship icons, top-left, no text ---- */
#lives {
  position: absolute;
  top: 16px;
  left: 18px;
  display: flex;
  gap: 7px;
  pointer-events: none;
}

.life-icon {
  width: 22px;
  height: 22px;
  display: block;
  transition: opacity 0.25s, transform 0.25s;
}

.life-icon svg {
  width: 100%;
  height: 100%;
  fill: #7fd4ff;
  filter: drop-shadow(0 0 4px rgba(90, 200, 255, 0.6));
}

.life-icon.lost {
  opacity: 0.15;
  transform: scale(0.8);
}

.life-icon.lost svg {
  fill: #4a5a6a;
  filter: none;
}

/* ---- Mission board: top-right, one goal per line ---- */
#mission-box {
  position: absolute;
  top: 14px;
  right: 16px;
  text-align: right;
  font-size: 11px;
  letter-spacing: 1.5px;
  color: #a9c6e8;
  pointer-events: none;
}

#mission-title {
  font-size: 12px;
  letter-spacing: 3px;
  color: #7fd4ff;
  margin-bottom: 5px;
  opacity: 0.9;
}

#mission-box .m-row {
  opacity: 0.82;
  margin-top: 2px;
}

#mission-box .m-row span {
  color: #eaf6ff;
  font-variant-numeric: tabular-nums;
}

#mission-box .m-row.done {
  color: #66e6a0;
}

#mission-box .m-row.done span {
  color: #66e6a0;
}

#mission-box.ready #mission-title {
  color: #6fe6ff;
  animation: portalPulse 0.9s infinite;
}

@keyframes portalPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* ---- Sector map (Tab): full-screen top-down overview ---- */
#map-screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: rgba(2, 6, 14, 0.82);
  backdrop-filter: blur(2px);
  z-index: 30;
}

#map-screen.hidden { display: none; }

#map-title {
  font-size: 16px;
  letter-spacing: 6px;
  color: #7fd4ff;
  text-shadow: 0 0 12px rgba(80, 200, 255, 0.5);
}

#map-canvas {
  width: min(78vh, 78vw);
  height: min(78vh, 78vw);
  border: 1px solid rgba(120, 190, 255, 0.25);
  border-radius: 6px;
  background: rgba(4, 10, 22, 0.6);
}

#map-hint {
  font-size: 11px;
  letter-spacing: 3px;
  color: #a9c6e8;
  opacity: 0.7;
}

/* ---- Warp flash: the jump in/out bloom over the whole screen ---- */
#warp-flash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 25;
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(120, 220, 255, 0.85) 35%,
    rgba(60, 120, 255, 0.5) 65%,
    rgba(10, 20, 60, 0) 100%);
}

/* Speed lines are NOT a CSS overlay any more (v11.21): a static ray gradient
   cannot convey motion. They are now a world-space streak field in the scene -
   see js/speedfx.js. */

#warp-flash.enter { animation: warpEnter 1.05s ease-in forwards; }
#warp-flash.exit  { animation: warpExit 1.0s ease-out forwards; }

@keyframes warpEnter {
  0%   { opacity: 0; transform: scale(2.2); }
  70%  { opacity: 0.5; transform: scale(1.1); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes warpExit {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(2.4); }
}

/* ---- Admin badge (HUD, only shown while a cheat is active) ---- */
#admin-badge {
  position: absolute;
  top: 44px;
  left: 18px;
  font-size: 11px;
  letter-spacing: 2px;
  color: #ffd23f;
  text-shadow: 0 0 8px rgba(255, 200, 60, 0.6);
  pointer-events: none;
}

/* ---- Admin unlock (overlay) ---- */
#admin-row {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  opacity: 0.5;
}

#admin-row input {
  width: 120px;
  padding: 5px 9px;
  font: inherit;
  font-size: 11px;
  letter-spacing: 1px;
  text-align: center;
  color: #cfe9ff;
  background: rgba(10, 18, 30, 0.7);
  border: 1px solid rgba(120, 190, 255, 0.25);
  border-radius: 4px;
}

#admin-status {
  font-size: 10px;
  letter-spacing: 1.5px;
  color: #ff9a8a;
  min-height: 12px;
}

#admin-status.ok {
  color: #ffd23f;
}

#msg {
  position: absolute;
  top: 26px;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-size: 16px;
  letter-spacing: 2px;
  color: #ffb3a8;
  text-shadow: 0 0 10px rgba(255, 120, 100, 0.5);
  opacity: 0;
  transition: opacity 0.3s;
}

#msg.show { opacity: 1; }

.bar {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  letter-spacing: 2px;
}

.track {
  width: 220px;
  height: 10px;
  border: 1px solid rgba(120, 225, 255, 0.5);
  border-radius: 5px;
  overflow: hidden;
  background: rgba(15, 35, 60, 0.5);
}

.fill {
  height: 100%;
  width: 50%;
  background: linear-gradient(90deg, #2fc7f0, #7ceaff);
  transition: width 0.12s linear;
}

.track.hit {
  border-color: #ff5f4d;
  box-shadow: 0 0 12px rgba(255, 80, 60, 0.9);
}

#overlay {
  display: grid;
  place-items: center;
  background: rgba(2, 4, 12, 0.78);
  cursor: pointer;
  text-align: center;
  overflow-y: auto;
  padding: 24px 0;
}

#overlay.hidden { display: none; }

#home-btn {
  position: fixed;
  top: 16px;
  left: 16px;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(120, 225, 255, 0.4);
  border-radius: 10px;
  background: rgba(8, 14, 30, 0.85);
  color: #9fdcff;
  transition: color 0.2s, border-color 0.2s, box-shadow 0.2s;
}

#home-btn svg { width: 24px; height: 24px; }

#home-btn:hover {
  color: #52e6ff;
  border-color: rgba(82, 230, 255, 0.8);
  box-shadow: 0 0 14px rgba(60, 210, 255, 0.35);
}

#overlay-card {
  padding: 30px 44px;
  border: 1px solid rgba(110, 220, 255, 0.35);
  border-radius: 14px;
  background: rgba(8, 14, 30, 0.88);
  box-shadow: 0 0 40px rgba(50, 190, 255, 0.22), inset 0 0 24px rgba(50, 190, 255, 0.05);
  max-width: 560px;
}

#overlay-card h1 {
  margin: 0 0 14px;
  font-size: 40px;
  letter-spacing: 8px;
  color: #eaf7ff;
  text-shadow: 0 0 16px rgba(80, 220, 255, 0.85), 0 0 34px rgba(255, 90, 220, 0.25);
}

#overlay-card p {
  margin: 6px 0;
  font-size: 14px;
  color: #a9c6e8;
}

#overlay-card .cta {
  margin-top: 14px;
  font-size: 17px;
  letter-spacing: 3px;
  color: #6fe6ff;
}

#mobile-note {
  color: #ffb3a8 !important;
  font-size: 15px !important;
  letter-spacing: 1px;
}

.hidden { display: none !important; }

#nick-row { margin-top: 16px; }

#nick-input {
  width: 240px;
  padding: 9px 12px;
  background: rgba(12, 24, 44, 0.9);
  border: 1px solid rgba(120, 225, 255, 0.45);
  border-radius: 8px;
  color: #dff4ff;
  font-family: inherit;
  font-size: 14px;
  letter-spacing: 1px;
  text-align: center;
  outline: none;
}

#nick-input:focus {
  border-color: rgba(90, 230, 255, 0.9);
  box-shadow: 0 0 10px rgba(60, 210, 255, 0.3);
}

#nick-error {
  min-height: 18px;
  margin-top: 5px;
  font-size: 12.5px;
  color: #ff8d7d;
  letter-spacing: 1px;
}

#overlay-buttons {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 16px;
}

#overlay-buttons button {
  padding: 10px 18px;
  background: rgba(30, 75, 130, 0.35);
  border: 1px solid rgba(110, 220, 255, 0.5);
  border-radius: 8px;
  color: #dff4ff;
  font-family: inherit;
  font-size: 14px;
  letter-spacing: 2px;
  cursor: pointer;
}

#overlay-buttons button:hover {
  background: rgba(55, 135, 210, 0.5);
  box-shadow: 0 0 12px rgba(60, 210, 255, 0.3);
}

/* Radar: bottom CENTRE, hard against the inside of the ring. Sized in vh, not
   px, on purpose: the ring is a vh circle, so a px-wide radar would drift out
   of it on a short/windowed viewport. 16vh wide -> half-width 8vh; with the
   bottom edge 38vh below centre the corners land at ~38.8vh, and the ring is
   at 39.2vh. */
#radar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10vh;
  margin: 0 auto;
  width: 16vh;
  height: 16vh;
}

#board {
  margin-top: 22px;
  border-top: 1px solid rgba(110, 220, 255, 0.25);
  padding-top: 14px;
}

#board h2 {
  margin: 0 0 8px;
  font-size: 15px;
  letter-spacing: 2px;
  color: #bfe8ff;
}

#board-week { color: #6fe6ff; font-weight: 400; }

#board-list {
  margin: 0;
  padding: 0 0 0 26px;
  text-align: left;
  font-size: 13.5px;
  color: #a9c6e8;
  max-height: 190px;
  overflow-y: auto;
}

#board-list li { padding: 2px 0; }

#board-list li .b-score { float: right; color: #6fe6ff; }

.board-loading { list-style: none; color: #7d97b8; }

.board-note {
  font-size: 11.5px !important;
  color: #7d97b8 !important;
  margin-top: 8px !important;
}

/* ================= Reticle ring (screen centre) =================
   A true circle wide enough to hold the ship through any manoeuvre: shield arc
   on top, laser heat left, rockets right, speed along the bottom. Colours are
   driven from hud.js (green->red ramps), so no per-gauge colour lives here.
   OPACITY BOOKKEEPING: a parent opacity MULTIPLIES its children, so the group
   is parked at 25% (the text level) and every graphic element is scaled back
   down from there: arcs 0.6 -> 15% on screen, ring/tracks 0.072 -> 1.8%. Only
   the labels and the lock line get the full 25%. Changing #reticle alone moves
   everything; these three numbers are what keep them apart.
   The radar and the score stay fully opaque. */
#reticle {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  color: #9fe4ff;
  opacity: 0.25;
}

/* The ring read as "solid" before because of the glow: a drop-shadow re-adds
   light on top of whatever opacity says. No glow here - the arcs are thin,
   flat strokes and the colour ramp alone carries the state. */
/* Ring size: the WHOLE svg (labels included) has to fit the viewport, because
   the game usually runs windowed, not fullscreen - 98vh, never taller. */
.ret-svg {
  width: min(1400px, 98vh);
  height: auto;
}

#ret-ring { opacity: 0.072; }

.arc-track {
  stroke: rgba(150, 215, 255, 0.9);
  stroke-width: 5;
  opacity: 0.072;
}

.arc-fill {
  stroke-width: 5;
  opacity: 0.6;
  transition: stroke-dasharray 0.1s linear, stroke 0.15s linear;
}

.arc-fill.hit {
  stroke: #ffffff;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.9));
}

.arc-fill.crit { animation: lockPulse 0.6s infinite; }

.g-label {
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: 15px;
  letter-spacing: 2px;
  fill: #cfe9ff;
  opacity: 0.88;
}

.ret-brk { opacity: 0.8; }
.ret-tick { opacity: 0.95; }
.ret-dot { opacity: 0.95; }

#reticle.acquiring .ret-core { color: #eaf7ff; }

#reticle.locked .ret-core {
  color: #ff4438;
  animation: lockPulse 0.7s infinite;
}

/* ---- Lock readout (above the ellipse) ---- */
#lock-status {
  font-size: 12px;
  letter-spacing: 3px;
  min-height: 0;
}

#lock-status.acquiring { color: #eaf7ff; }

#lock-status.locked {
  color: #ff3b30;
  text-shadow: 0 0 10px rgba(255, 60, 45, 0.9);
  animation: lockPulse 0.7s infinite;
}

@keyframes lockPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* ---- Music controls (overlay) ---- */
#music-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 14px;
  font-size: 12.5px;
  letter-spacing: 2px;
  color: #a9c6e8;
}

#music-vol {
  -webkit-appearance: none;
  appearance: none;
  width: 170px;
  height: 4px;
  border-radius: 3px;
  background: rgba(120, 225, 255, 0.28);
  outline: none;
  cursor: pointer;
}

#music-vol::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #6fe6ff;
  box-shadow: 0 0 10px rgba(60, 210, 255, 0.7);
  cursor: pointer;
}

#music-vol::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: none;
  border-radius: 50%;
  background: #6fe6ff;
  box-shadow: 0 0 10px rgba(60, 210, 255, 0.7);
  cursor: pointer;
}

#music-toggle {
  padding: 5px 12px;
  min-width: 52px;
  background: rgba(30, 75, 130, 0.35);
  border: 1px solid rgba(110, 220, 255, 0.5);
  border-radius: 6px;
  color: #dff4ff;
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: 2px;
  cursor: pointer;
}

#music-toggle.off {
  color: #ff8d7d;
  border-color: rgba(255, 141, 125, 0.5);
}




/* ---- LEVEL 2 fortress objective panel (replaces the mission board) ---- */
#boss-box {
  position: absolute;
  top: 14px;
  right: 16px;
  text-align: right;
  font-size: 11px;
  letter-spacing: 1.5px;
  color: #ffb3a0;
  pointer-events: none;
}
#boss-box .b-title {
  font-size: 12px;
  letter-spacing: 3px;
  color: #ff6a5a;
  margin-bottom: 5px;
  opacity: 0.95;
}
#boss-box .m-row { opacity: 0.85; margin-top: 2px; }
#boss-box .m-row span { color: #ffe6de; font-variant-numeric: tabular-nums; }
#boss-box .m-row.done { color: #66e6a0; }
#boss-box .m-row.done span { color: #66e6a0; }
#boss-box.ready .b-title { color: #6fe6ff; animation: portalPulse 0.9s infinite; }


/* ---- Screen-centred directional radar (off-screen target/enemy arrows) ---- */
#dir-hud {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 6;
}


/* ---- Touch controls (mobile) ------------------------------------------------
   The layer is only unhidden when main.js detects a coarse pointer. It sits
   above the HUD but is pointer-events:none itself, so only the pads and
   buttons take input - the canvas underneath keeps working exactly as it does
   on desktop. Everything is sized in vmin so one rule serves phone and tablet. */
#touch {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
#touch.hidden { display: none; }

/* While a touch device is FLYING, nothing on screen is selectable text and no
   long-press callout is allowed. The class is only on <body> for touch builds,
   and the overlay (nickname field, leaderboard) is exempted below so the start
   card still behaves like a normal page. */
body.touch #app,
body.touch #hud,
body.touch #touch {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
body.touch #overlay,
body.touch #overlay * {
  -webkit-user-select: auto;
  user-select: auto;
}


/* Right half is the look pad. It is deliberately the FULL height of the right
   side and sits under the buttons in stacking order, so a thumb that slides off
   a button still aims instead of dead-stopping. */
#t-look {
  position: absolute;
  right: 0; top: 0;
  width: 55%; height: 100%;
  pointer-events: auto;
}

#t-stick {
  position: absolute;
  left: 3.5vmin; bottom: 4vmin;
  width: 30vmin; height: 30vmin;
  max-width: 190px; max-height: 190px;
  border-radius: 50%;
  border: 1px solid rgba(90, 220, 255, 0.35);
  background: radial-gradient(circle, rgba(10, 30, 44, 0.55), rgba(6, 14, 22, 0.30));
  box-shadow: 0 0 18px rgba(0, 190, 255, 0.12) inset;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
#t-knob {
  width: 12vmin; height: 12vmin;
  max-width: 76px; max-height: 76px;
  border-radius: 50%;
  background: rgba(53, 240, 255, 0.22);
  border: 1px solid rgba(90, 230, 255, 0.7);
  box-shadow: 0 0 14px rgba(0, 200, 255, 0.35);
  will-change: transform;
}

.t-btn {
  position: absolute;
  pointer-events: auto;
  /* Long-press on a phone means "select this text / open the callout menu".
     On a game pad that reads as the screen breaking: the HUD gets a selection
     highlight, the callout steals the touch, and the canvas appears to vanish.
     These four lines are what stop it - JS preventDefault alone is not enough,
     the selection starts before any handler runs. touch-action:manipulation
     also kills the double-tap-zoom delay, which is what made the buttons feel
     like they only worked on a long press. */
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  width: 15vmin; height: 15vmin;
  max-width: 92px; max-height: 92px;
  border-radius: 50%;
  border: 1px solid rgba(90, 220, 255, 0.45);
  background: rgba(8, 26, 38, 0.45);
  color: #cdefff;
  font: 600 2.6vmin/1 'Segoe UI', system-ui, sans-serif;
  letter-spacing: 0.06em;
  text-shadow: 0 0 8px rgba(0, 200, 255, 0.5);
  -webkit-tap-highlight-color: transparent;
}
.t-btn.on {
  background: rgba(53, 200, 255, 0.35);
  border-color: #7ff0ff;
  box-shadow: 0 0 16px rgba(0, 220, 255, 0.45);
}
.t-btn.t-big { width: 19vmin; height: 19vmin; max-width: 116px; max-height: 116px; }
.t-btn.t-small { width: 11vmin; height: 11vmin; max-width: 66px; max-height: 66px; font-size: 2.2vmin; }

/* Right-hand pad: a 2x2 block, every key the same size as the roll pair on the
   left (11vmin). Top row SLW + BST (throttle), bottom row RKT + FIRE (guns),
   with FIRE outboard where the thumb rests. The explicit sizes override the
   .t-big class those two buttons still carry in the markup. */
.t-btn.t-big,
#t-fire, #t-rocket, #t-boost, #t-slow {
  width: 11vmin; height: 11vmin;
  max-width: 66px; max-height: 66px;
  font-size: 2.2vmin;
}
#t-fire   { right: 4vmin;  bottom: 5vmin; }
#t-rocket { right: 18vmin; bottom: 5vmin; }
#t-boost  { right: 4vmin;  bottom: 18vmin; }
#t-slow   { right: 18vmin; bottom: 18vmin; }
/* Roll pair, shrunk to t-small and re-seated so the lock arrows can stack on
   top of them (the pilot's request: one thumb column, arrows over rolls). */
#t-roll-l { left: 37vmin; bottom: 4vmin; width: 11vmin; height: 11vmin; max-width: 66px; max-height: 66px; font-size: 2.4vmin; }
#t-roll-r { left: 51vmin; bottom: 4vmin; width: 11vmin; height: 11vmin; max-width: 66px; max-height: 66px; font-size: 2.4vmin; }
/* Lock cycle arrows sit directly ABOVE the roll pair, same size, same columns
   - they were top-right before, where they collided with the MISSION box. */
#t-prev   { left: 37vmin; bottom: 17vmin; }
#t-next   { left: 51vmin; bottom: 17vmin; }
/* Menu strip: a vertical column down the LEFT EDGE (the pilot's request).
   The old top-centre row sat on the shield readout and the dirhud arrows.
   Starts below the top-left HUD stars, ends above the joystick. */
#t-pause  { left: 2.5vmin; top: 14vmin; }
#t-map    { left: 2.5vmin; top: 26vmin; }
#t-music  { left: 2.5vmin; top: 38vmin; }
#t-gyro   { left: 2.5vmin; top: 50vmin; }
#t-gyro.armed {
  color: #7ff0ff;
  border-color: #7ff0ff;
  box-shadow: 0 0 12px rgba(0, 220, 255, 0.5);
}

/* Portrait warning: the HUD assumes a wide viewport, so ask for landscape
   rather than trying to reflow a cockpit into a tall strip. */
#rotate-note {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  background: #04070c;
  color: #9fe6ff;
  font: 600 18px/1.6 'Segoe UI', system-ui, sans-serif;
  text-align: center;
  padding: 24px;
}
body.touch.portrait #rotate-note { display: flex; }

/* NOTE: there used to be a @media (max-height: 520px) block here that scaled
   the HUD boxes down with per-corner transform-origins. #hud is a full-screen
   layer, so scaling it from its top-left corner squeezed EVERYTHING - including
   centre-anchored readouts - toward the top-left: that was the "HUD drifts
   left on the phone" bug. The HUD now renders identically to desktop on every
   viewport; if phone sizing ever needs tuning, scale individual boxes about
   their own anchors, never the #hud layer itself. */

/* ---- Touch: the start overlay -----------------------------------------------
   The card was written for a desktop window and is taller than a phone in
   landscape, and #overlay does not scroll - so on mobile everything below the
   fold (music, leaderboard, admin) was simply unreachable. On touch the
   overlay becomes a scroll container, the card is compacted, and the
   keyboard-only instruction lines are dropped in favour of a touch line. */
body.touch #overlay {
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 10px 0 30px;
}
body.touch #overlay-card {
  padding: 16px 20px;
  margin: 8px 10px;
  max-width: 92vw;
}
body.touch #overlay-card h1 { font-size: 24px; letter-spacing: 5px; margin-bottom: 8px; }
body.touch #overlay-card p { font-size: 12px; margin: 4px 0; }
body.touch #overlay-card .cta { font-size: 15px; margin-top: 10px; }
body.touch .desktop-only { display: none; }
body.touch #touch-help { display: block; }
body.touch #board h2 { font-size: 14px; }
body.touch #music-row { margin-top: 10px; }
/* Fingers need a bigger target than a 4px slider thumb. */
body.touch #music-vol { height: 26px; }
body.touch #music-toggle,
body.touch #overlay-buttons button { min-height: 38px; padding: 8px 14px; }

#touch-help { display: none; }

/* The start card is centred by `place-items: center` on a grid. When the card
   is TALLER than the viewport, a centred grid item overflows both ways and the
   overflow is unreachable - which is how the music row, leaderboard and admin
   box went missing on a phone in landscape. Anchoring the card to the TOP once
   the viewport is short makes the whole card scrollable, and this is keyed on
   viewport height rather than on touch detection, so it holds even where the
   browser misreports pointer/hover (which is most of the reason it was still
   broken after the touch-only fix). */
@media (max-height: 760px) {
  #overlay { place-items: start center; padding: 12px 0 48px; }
  #overlay-card { padding: 16px 20px; max-width: 92vw; }
  #overlay-card h1 { font-size: 24px; letter-spacing: 5px; margin-bottom: 8px; }
  #overlay-card p { font-size: 12px; margin: 4px 0; }
  #overlay-card .cta { font-size: 15px; margin-top: 10px; }
  #board { max-height: none; }
}
