/* 5Space - the canvas fills the window; everything else floats over it. */

:root {
  --ink: #cfe4ff;
  --dim: #7f96b0;
  --accent: #40c0f0;
  --gold: #ffd24a;
  --panel: rgba(8, 12, 20, 0.88);
  --edge: rgba(90, 140, 190, 0.35);
  --mono: "DejaVu Sans Mono", "Liberation Mono", Menlo, Consolas, "Courier New", monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: #05060a;
  color: var(--ink);
  font-family: var(--mono);
  -webkit-font-smoothing: antialiased;

  /* A game surface, not a document: no pinch-zoom, no pull-to-refresh, no
     text selection or callout menus when a thumb rests on a control. */
  touch-action: none;
  overscroll-behavior: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

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

.hidden { display: none !important; }

/* ---- message log ---------------------------------------------------- */

#messages {
  position: fixed;
  top: 10px;
  left: 12px;
  max-width: min(52ch, 60vw);
  pointer-events: none;
  font-size: 13px;
  line-height: 1.45;
  text-shadow: 0 1px 3px #000, 0 0 8px #000;
}

#messages .msg {
  color: var(--ink);
  transition: opacity 0.2s linear;
}

/* ---- the big banner ------------------------------------------------- */

#banner {
  position: fixed;
  top: 32%;
  left: 0;
  right: 0;
  text-align: center;
  font-size: clamp(22px, 5vw, 46px);
  font-weight: bold;
  letter-spacing: 0.08em;
  pointer-events: none;
  text-shadow: 0 2px 16px #000, 0 0 40px rgba(0, 0, 0, 0.9);
  opacity: 0;
}

#banner.fade { animation: bannerFade 2.4s ease-out forwards; }

@keyframes bannerFade {
  0% { opacity: 0; transform: scale(1.12); }
  12% { opacity: 1; transform: scale(1); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.04); }
}

/* ---- overlays: menus, prompts, full-screen text ---------------------- */

#overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(3, 5, 10, 0.82);
  backdrop-filter: blur(2px);
  z-index: 20;
  padding: 20px;
}

.menu {
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 4px;
  padding: 18px 22px;
  max-width: min(96ch, 96vw);
  max-height: 92vh;
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.5;
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.8);
}

.menu.full { min-width: min(88ch, 92vw); }

.mtitle {
  display: block;
  color: var(--gold);
  font-weight: bold;
  margin-bottom: 10px;
  letter-spacing: 0.04em;
}

.mhead {
  color: var(--accent);
  margin: 12px 0 4px;
  font-weight: bold;
}

.mrow {
  white-space: pre-wrap;
  color: var(--ink);
  padding: 1px 0;
}

.mrow.pick {
  cursor: pointer;
  padding: 3px 6px;
  margin: 1px -6px;
  border-radius: 3px;
}

.mrow.pick:hover { background: rgba(64, 192, 240, 0.14); }

.msel {
  display: inline-block;
  min-width: 2.4ch;
  color: var(--gold);
  font-weight: bold;
}

.mfoot {
  display: block;
  margin-top: 12px;
  color: var(--dim);
  font-size: 12px;
}

.logo { color: #56d0ff; white-space: pre; }
.hi { color: var(--gold); }

/* ---- text entry ------------------------------------------------------ */

.entryform { margin: 6px 0 2px; }

/* Big enough to be an obvious tap target: if a browser declines to focus it
   automatically, tapping it is the fallback that always works. */
.entryinput {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  background: rgba(4, 8, 14, 0.9);
  border: 1px solid var(--accent);
  border-radius: 5px;
  color: #fff;
  font-family: var(--mono);
  font-size: 17px;              /* under 16px and iOS zooms the page in */
  letter-spacing: 0.04em;
  outline: none;
  /* the page suppresses selection; a text field needs it back */
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}

.entryinput:focus { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(255, 210, 74, 0.2); }

.entrybtns { display: flex; gap: 10px; margin-top: 12px; }

.ebtn {
  flex: 1;
  padding: 12px 18px;
  background: rgba(20, 32, 48, 0.9);
  border: 1px solid var(--edge);
  border-radius: 5px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  touch-action: manipulation;
}

.ebtn.ok { background: var(--accent); border-color: var(--accent); color: #04121c; }
.ebtn:active { transform: scale(0.98); }
.ebtn.ok:active { background: var(--gold); }

.entry { color: #fff; }
.caret { animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* ---- the hull picker ------------------------------------------------- */

.shipname { font-weight: bold; }
.shipstats { color: var(--dim); font-size: 12px; }
.shipblurb { color: var(--ink); font-size: 12.5px; padding: 2px 0 0 2.4ch; opacity: 0.9; }
.shiphint { color: var(--dim); font-size: 12px; padding: 0 0 4px 2.4ch; font-style: italic; }

/* ---- on-screen controls ---------------------------------------------- */

/* The layer covers the screen but only its buttons take input, so a thumb
   that misses one lands on the game rather than on an invisible panel. */
#touch {
  position: fixed;
  inset: 0;
  z-index: 15;
  pointer-events: none;
}

/* A menu owns the whole screen; the flight controls step aside for it. */
#overlay:not(.hidden) ~ #touch { display: none; }

#touch .tbtn {
  pointer-events: auto;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(16, 26, 40, 0.5);
  border: 1px solid rgba(120, 175, 225, 0.34);
  border-radius: 12px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 0.04em;
  touch-action: none;
  backdrop-filter: blur(2px);
  transition: background 0.06s linear, transform 0.06s linear;
}

#touch .tbtn.lit,
#touch .tbtn:active {
  background: rgba(64, 192, 240, 0.42);
  border-color: rgba(150, 220, 255, 0.8);
  transform: scale(0.96);
}

/* thumb zones: bottom corners, inside the safe area */
#touch .tpad {
  position: absolute;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
  width: 186px;
  height: 186px;
  pointer-events: none;
}
#touch .tpad-left { left: calc(env(safe-area-inset-left, 0px) + 10px); }
#touch .tpad-right { right: calc(env(safe-area-inset-right, 0px) + 10px); }

/* a d-pad: thrust above, reverse below, turn either side */
#touch .tpad-left .tbtn { width: 62px; height: 62px; font-size: 20px; }
#touch .tpad-left .up { left: 62px; top: 0; }
#touch .tpad-left .left { left: 0; top: 62px; }
#touch .tpad-left .right { left: 124px; top: 62px; }
#touch .tpad-left .down { left: 62px; top: 124px; }

/* fire under the thumb, bomb and boost within reach of it */
#touch .tpad-right .fire {
  right: 0; bottom: 8px;
  width: 104px; height: 104px;
  border-radius: 52px;
  font-size: 17px;
  background: rgba(64, 150, 200, 0.34);
}
#touch .tpad-right .bomb { right: 8px; bottom: 118px; width: 86px; height: 52px; }
#touch .tpad-right .boost { right: 112px; bottom: 20px; width: 68px; height: 68px; border-radius: 34px; }
/* dropping a portal is a two-hand-free moment, so it sits outboard of boost
   where the thumb reaches it without crossing fire */
#touch .tpad-right .portal {
  right: 188px; bottom: 24px;
  width: 60px; height: 60px;
  border-radius: 30px;
  font-size: 11px;
}

#touch .tpad-right .mine { right: 8px; bottom: 176px; width: 86px; height: 44px; font-size: 11px; }

/* The rest of the stock, climbing away from MINE.
   column-reverse so the first button in the array is the lowest one, and
   wrap so a short landscape phone gets a second column instead of a stack
   that runs off the top of the screen and under the radar.  The height it is
   allowed to occupy is measured and set by layoutTouch, because only the
   running page knows where the radar ends. */
#touch .tstack {
  position: absolute;
  right: 8px;
  bottom: 226px;
  display: flex;
  flex-direction: column-reverse;
  flex-wrap: wrap-reverse;
  align-content: flex-start;
  gap: 6px;
  pointer-events: none;
}
#touch .tstack .tbtn {
  position: static;
  width: 86px;
  height: 42px;
  font-size: 11px;
}

/* Map, gear and menu stack down the right-hand edge, below the radar.
   Anywhere along the top centre they eventually collide with the status
   readout on the left - which is exactly what happened on a tablet, where
   the readout is wide enough to reach the middle.  The radar is 22vmin tall
   (capped at 190px) and starts 12px down, hence the offset. */
#touch .ttop {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + min(22vmin, 190px) + 22px);
  right: calc(env(safe-area-inset-right, 0px) + 10px);
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}
#touch .ttop .tbtn {
  position: static;
  min-width: 56px;
  height: 34px;
  font-size: 12px;
  border-radius: 8px;
}

/* Too small to place the stock anywhere without collisions: it stays in GEAR,
   which is where it was before the pad had it. */
#touch.no-stack .tstack { display: none; }

/* Narrow portrait: PORT stacks on top of BOOST rather than reaching across
   the screen into the d-pad.  Set by layoutTouch when the two actually meet. */
#touch.port-up .tpad-right .portal { right: 116px; bottom: 94px; }
#touch.compact.port-up .tpad-right .portal { right: 96px; bottom: 80px; }

/* When the utility stack needs the right-hand edge, this column moves to the
   left one, under the status readout and above the d-pad.  layoutTouch adds
   the class only when the two actually intersect, so a tablet keeps the
   original arrangement. */
#touch.ttop-left .ttop {
  right: auto;
  left: calc(env(safe-area-inset-left, 0px) + 10px);
  top: calc(env(safe-area-inset-top, 0px) + 72px);
  /* A row, not a column: stacked vertically these three reach 174px down the
     left edge, which is into the d-pad on a 320px-tall phone.  Lying on their
     side they are 30px tall and clear it at every size, and the left edge has
     the width to spare because the d-pad is only 150 wide. */
  flex-direction: row;
}
#touch.ttop-left .tgear-panel {
  right: auto;
  left: calc(env(safe-area-inset-left, 0px) + 10px);
  top: calc(env(safe-area-inset-top, 0px) + 112px);
}

/* everything else, behind one toggle, opening inward from that column */
#touch .tgear-panel {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + min(22vmin, 190px) + 22px);
  right: calc(env(safe-area-inset-right, 0px) + 72px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  padding: 10px;
  width: min(420px, calc(100vw - 96px));
  background: rgba(8, 12, 20, 0.9);
  border: 1px solid var(--edge);
  border-radius: 10px;
  pointer-events: auto;
}
#touch .tgear-panel .tbtn {
  position: static;
  height: 40px;
  font-size: 11px;
  font-weight: normal;
  border-radius: 7px;
}

/* compact: small phones, where the pads would otherwise meet in the middle */
#touch.compact .tpad { width: 150px; height: 150px; }
#touch.compact .tpad-left .tbtn { width: 50px; height: 50px; font-size: 17px; }
#touch.compact .tpad-left .up { left: 50px; top: 0; }
#touch.compact .tpad-left .left { left: 0; top: 50px; }
#touch.compact .tpad-left .right { left: 100px; top: 50px; }
#touch.compact .tpad-left .down { left: 50px; top: 100px; }
#touch.compact .tpad-right .fire { width: 86px; height: 86px; border-radius: 43px; font-size: 14px; }
#touch.compact .tpad-right .bomb { bottom: 100px; width: 74px; height: 44px; font-size: 11px; }
#touch.compact .tpad-right .boost { right: 92px; bottom: 16px; width: 58px; height: 58px; border-radius: 29px; font-size: 11px; }
#touch.compact .tpad-right .portal { right: 156px; bottom: 20px; width: 50px; height: 50px; border-radius: 25px; font-size: 10px; }
#touch.compact .tpad-right .mine { right: 8px; bottom: 150px; width: 74px; height: 36px; font-size: 10px; }
#touch.compact .tstack { bottom: 191px; gap: 5px; }
#touch.compact .tstack .tbtn { width: 74px; height: 36px; font-size: 10px; }

/* Landscape on a phone: there is no vertical room for a ladder, but there is
   a whole empty strip along the bottom between the two thumbs.  The stock
   becomes a row of circles running left from PORT, in the same order the
   column had - nearest first, so REPEL stays closest to the thumb either way.

   Applied by layoutTouch, and only after it has checked the row actually
   clears the d-pad; on a very short phone it falls back to the ladder. */
#touch.row-bottom .tstack {
  right: 214px;
  bottom: 24px;
  flex-direction: row-reverse;
  flex-wrap: nowrap;
  gap: 8px;
}
#touch.row-bottom .tstack .tbtn {
  width: 46px;
  height: 46px;
  border-radius: 23px;
  font-size: 9px;
  letter-spacing: 0;
}

#touch.compact .ttop .tbtn { min-width: 52px; height: 30px; font-size: 11px; }
#touch.compact .tgear-panel {
  grid-template-columns: repeat(3, 1fr);
  width: min(300px, calc(100vw - 96px));
}

/* the message log clears the compact status readout when controls are up */
body.touch #messages {
  top: calc(env(safe-area-inset-top, 0px) + 52px);
  left: calc(env(safe-area-inset-left, 0px) + 12px);
  max-width: 54vw;
  font-size: 11px;
}

body.touch #banner { top: 26%; }

/* menus must clear the thumb zones and the notch */
body.touch #overlay {
  padding: calc(env(safe-area-inset-top, 0px) + 12px)
           calc(env(safe-area-inset-right, 0px) + 12px)
           calc(env(safe-area-inset-bottom, 0px) + 12px)
           calc(env(safe-area-inset-left, 0px) + 12px);
}
body.touch .menu { max-height: 86vh; }
body.touch .mrow.pick { padding: 9px 8px; }   /* tappable rows */

@media (max-width: 700px) {
  #messages { font-size: 11px; max-width: 70vw; }
  .menu { font-size: 12px; padding: 12px 14px; }
  .mrow.pick { padding: 8px 6px; }
}
