* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #0a0908;
  color: #f2e9de;
  font-family: "Courier New", ui-monospace, monospace;
  overflow: hidden;
  /* No rubber banding, no pinch zoom, no text selection while you are playing. */
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

#screen { touch-action: none; }

#app {
  position: relative;
  width: 100vw;
  /* 100vh on iOS counts the browser chrome, so the bottom of the layout - the
     on-screen controls, the launch button - ends up under it. dvh is the part
     you can actually see; the vh line stays as a fallback. */
  height: 100vh;
  height: 100dvh;
  display: grid;
  place-items: center;
}

/* Two canvases, the same size, one on top of the other: the world in WebGL and
   the head-up display in 2D over it.

   Both are now sized to the window rather than to a fixed 640 x 448, so there is
   no letterboxing left to do and nothing is being stretched - the picture is
   drawn at the shape of the window and the lens opens sideways to suit. The
   pixel-doubling that used to be the whole look is gone with it; what is left
   of that look is the flat shading, which was always the part doing the work. */
#screen, #hud {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  outline: none;
}

#screen {
  background: #080706;
}

/* Nothing on the display is clickable: the panels are painted over the world and
   every control is either a key or one of the touch buttons above it. */
#hud {
  pointer-events: none;
  z-index: 1;
}

.overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(4, 7, 16, 0.72);
  backdrop-filter: blur(2px);
  z-index: 10;
}

.overlay.hidden { display: none; }

.row.hidden { display: none; }

.panel {
  width: min(580px, 92vw);
  max-height: 92vh;
  max-height: 92dvh;
  overflow: auto;
  padding: 26px 30px;
  background: #181410;
  border: 2px solid #5a3f2e;
  box-shadow: inset 0 0 0 2px #080706, 0 10px 40px rgba(0, 0, 0, 0.6);
}

.panel.small { width: min(340px, 90vw); text-align: center; }

h1 {
  margin: 0;
  font-size: 36px;
  letter-spacing: 4px;
  color: #ff8a3d;
  text-shadow: 3px 3px 0 #4a1c05;
}

h1 span { display: block; color: #ffca4d; text-shadow: 3px 3px 0 #4a2c05; }

h2 { margin: 0 0 18px; letter-spacing: 3px; color: #ff8a3d; }

.tag { margin: 6px 0 22px; color: #b09a86; font-size: 13px; letter-spacing: 1px; }

.row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}

.row label {
  width: 92px;
  font-size: 13px;
  color: #b09a86;
  letter-spacing: 1px;
}

.btns { display: flex; gap: 8px; flex-wrap: wrap; }

button, select {
  font-family: inherit;
  font-size: 13px;
  padding: 9px 14px;
  color: #f2e9de;
  background: #2a2118;
  border: 2px solid #5a3f2e;
  cursor: pointer;
  letter-spacing: 1px;
}

button:hover, select:hover { background: #42311f; }

button.active { background: #ff8a3d; color: #0d0b09; border-color: #ff8a3d; font-weight: bold; }

button.primary {
  width: 100%;
  margin-top: 18px;
  padding: 13px;
  font-size: 17px;
  font-weight: bold;
  background: #ffca4d;
  color: #17110a;
  border-color: #c79a1e;
}

button.primary:hover { background: #ffdd85; }

.panel.small button { width: 100%; margin-top: 8px; }

.keys {
  width: 100%;
  margin: 18px 0 4px;
  border-collapse: collapse;
  font-size: 12px;
}

.keys th, .keys td {
  padding: 6px 8px;
  text-align: left;
  border-bottom: 1px solid #3b2c22;
}

.keys th { color: #b09a86; font-weight: normal; letter-spacing: 1px; }

.keys td .bind {
  min-width: 74px;
  padding: 5px 8px;
  font-size: 12px;
  letter-spacing: 0;
}

.keys td .bind.listening {
  background: #ff8a3d;
  color: #0d0b09;
  border-color: #ff8a3d;
}

.keys td .bind.clash {
  border-color: #ff7a5a;
  color: #ff9d85;
}

.preset { width: 100%; padding: 5px 6px; font-size: 11px; letter-spacing: 0; }

#bindHint.warn { color: #ff9d85; }

.hints {
  margin: 12px 0 0;
  padding-left: 18px;
  font-size: 12px;
  line-height: 1.7;
  color: #ded2c4;
}

.hints b { color: #ffca4d; }

/* --- The small print ------------------------------------------------------ */

.fineprint {
  font-size: 12px;
  line-height: 1.7;
  color: #ded2c4;
}

.fineprint { margin: 16px 0 0; color: #8e7d6c; }

.fineprint code { color: #ded2c4; }

.status {
  min-height: 18px;
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: #b09a86;
}

button:disabled { opacity: 0.45; cursor: default; }
button:disabled:hover { background: #2a2118; }
button.primary:disabled:hover { background: #ffca4d; }

/* A phone held sideways is about 400px tall. The panel scrolls, but a button
   you have to scroll to find is a button nobody presses, so the primary action
   sticks to the bottom of it and everything else gives up its spare room. */
.panelFooter {
  position: sticky;
  bottom: 0;
  z-index: 2;
  padding-top: 4px;
  background: #181410;
  box-shadow: 0 -12px 16px -8px rgba(16, 24, 40, 0.95);
}

@media (max-height: 560px) {
  .panel { padding: 14px 18px; max-height: 96dvh; }
  h1 { font-size: 22px; }
  h1 span { display: inline; margin-left: 8px; }
  .tag { margin: 4px 0 12px; font-size: 11px; }
  .row { margin-bottom: 8px; gap: 10px; }
  .row label { width: 76px; font-size: 11px; }
  button, select { padding: 6px 10px; font-size: 11px; }
  button.primary { margin-top: 10px; padding: 11px; font-size: 15px; }
  .fineprint, .hints { font-size: 11px; line-height: 1.5; }
  .keys th, .keys td { padding: 3px 6px; }
}

/* On a touch device the tips about the keyboard are a wall of text about keys
   you do not have - but the ones about the pod are the game, so they stay. */
@media (pointer: coarse) {
  #controlsBox .keys, #controlsBox #bindHint { display: none; }
}

details {
  margin: 14px 0 4px;
  border-top: 1px solid #3b2c22;
  border-bottom: 1px solid #3b2c22;
}

summary {
  padding: 9px 2px;
  font-size: 12px;
  letter-spacing: 1px;
  color: #b09a86;
  cursor: pointer;
}

summary:hover { color: #ffca4d; }

details[open] summary { color: #ffca4d; }

details .keys { margin-top: 0; }

/* A narrow screen has no room for a label beside its buttons: at 390 pixels the
   options wrapped into a ragged stack with one button stranded on the line
   above. The label goes over the top instead. */
@media (max-width: 520px) {
  .row {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
  }

  .row label { width: auto; }

  .btns { flex-wrap: wrap; }
}

/* --- touch controls ---
   Small and hard into the corners, which is not a style choice.
   The picture is letterboxed to ten by seven, so on a phone held sideways there
   are bars down both sides - a hundred and forty-five pixels of them on a
   fifteen, a hundred and sixty on a Pixel - and those bars are exactly where a
   thumb wants to be. Sized to fit inside them, the controls cover nought to nine
   per cent of the picture instead of the eleven to twenty-three they used to,
   and what they used to cover was the corners the head-up display lives in.
   Standing up they fall below the picture entirely.
   The comments here once described a different game in this series: there is no
   fire button, no pod and no wave, and the element ids are all that is left of
   them. */

#touch {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none; /* only the controls themselves take touches */
  padding: 0 max(14px, env(safe-area-inset-left)) max(14px, env(safe-area-inset-bottom));
}

/* touch-action does not inherit, so saying it on the box the buttons sit in
   does nothing for the buttons. Without it on the button itself, holding fire
   is a long press, and a long press on a phone is a text selection - the
   callout comes up and the gun stops charging. */
#stick, #touchButtons, #touchButtons button, #knob, #btnPause {
  pointer-events: auto;
  touch-action: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

#knob { pointer-events: none; }

/* The bottom-left corner is the stick. Eight ways, like the joystick this is
   imitating: the shared touch module measures from the middle of this box, so
   the box is deliberately large and the knob sits in the centre of it, where a
   thumb resting on the corner of the screen already is. */
#stick {
  position: absolute;
  left: 0;
  bottom: 0;
  /* Was forty-two per cent of the window, which on a phone held sideways is
     three hundred and fifty pixels and reached a third of the way across the
     road. A fixed width fits in the letterbox bar. */
  width: 150px;
  height: 140px;
  /* No tint of its own: a faintly lit corner of the screen reads as a bug
     rather than as a control, and the knob is the only part worth drawing. */
  background: transparent;
}

#knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 62px;
  height: 62px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(255, 138, 61, 0.6);
  border: 3px solid rgba(255, 255, 255, 0.4);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}

#touchButtons {
  position: absolute;
  right: max(10px, env(safe-area-inset-right));
  bottom: max(18px, calc(env(safe-area-inset-bottom) + 10px));
  display: flex;
  align-items: flex-end;
  gap: 12px;
}

#touchButtons button {
  border-radius: 50%;
  font-size: 12px;
  font-weight: bold;
  letter-spacing: 0;
  border-width: 3px;
}

/* The throttle is held for whole laps at a time, so it is the big one and it
   sits nearest the thumb; the brake is above and inside it, where a thumb can
   reach it without letting go of the gas. */
#btnFire {
  width: 84px;
  height: 84px;
  font-size: 13px;
  background: rgba(255, 202, 77, 0.72);
  color: #17110a;
  border-color: rgba(255, 255, 255, 0.55);
}

#btnPod {
  width: 60px;
  height: 60px;
  margin-bottom: 22px;
  background: rgba(178, 40, 48, 0.72);
  color: #f2e9de;
  border-color: rgba(255, 255, 255, 0.4);
}

#touchButtons button.pressed { filter: brightness(1.35); transform: scale(0.94); }

/* Pause, for a device with no Escape key. Small and quiet, and kept off the
   picture in both orientations, which took moving it.
   Top middle is where it was, and top middle of a letterboxed picture is the
   lap clock - the biggest number on the screen and the one you are reading on
   the way into a corner. Sideways it goes to the top left instead, which is the
   letterbox bar. Standing up there is no bar, so it goes into the empty space
   under the picture, between the stick and the pedals. */
#btnPause {
  position: absolute;
  left: max(6px, env(safe-area-inset-left));
  top: max(6px, env(safe-area-inset-top));
  width: 48px;
  /* Forty-four is the smallest target Apple and Google will both defend, and a
     pause button you miss while braking is a pause button that did not pause. */
  height: 44px;
  padding: 0;
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 2px;
  color: #f2e9de;
  background: rgba(10, 20, 36, 0.5);
  border: 2px solid rgba(255, 138, 61, 0.45);
  border-radius: 8px;
}

#btnPause:active { background: rgba(255, 138, 61, 0.6); color: #0d0b09; }

@media (orientation: portrait) {
  /* Straight under the picture rather than down among the pedals.
     Standing up the picture is the full width of the window and ten by seven, so
     it is exactly 70vw tall and ends there - which is a number the stylesheet can
     have without measuring anything. Down at the bottom instead, it collided with
     the brake on a phone as narrow as an SE. */
  #btnPause {
    left: 50%;
    top: calc(70vw + 16px);
    transform: translateX(-50%);
  }
}

/* --- The score board ----------------------------------------------------- */

.scores {
  width: 100%;
  border-collapse: collapse;
  margin: 6px 0 0;
}

.scores td { padding: 3px 4px; color: #ded2c4; }

.scores td.place { color: #8e7d6c; width: 2.2em; }
.scores td.name { color: #ffca4d; letter-spacing: 2px; }
.scores td.result { text-align: right; color: #ff8a3d; font-weight: bold; }
.scores td.stage { color: #b09a86; text-align: right; }  /* how many went down */
.scores td.when { color: #8e7d6c; text-align: right; }
.scores tr.fresh td { color: #ffffff; }

/* The three letters, and a pair of arrows over and under each of them.
   The arrows are not a phone affordance bolted on the side: the picker used to
   be driven only by the game's own stick and fire button, and on a phone those
   live underneath this panel, where a tap cannot reach them. A run that earned
   a score had nowhere to go. They are shown on every device because clicking an
   arrow is nicer than hunting for the arrow keys anyway. */
.picker { margin: 18px 0 6px; }

.letters, .letterRow {
  display: flex;
  justify-content: center;
  gap: 12px;
}

.letter, .panel.small .letterRow button {
  width: 64px;
}

.letter {
  display: block;
  padding: 6px 0;
  border: 2px solid #5a3f2e;
  border-radius: 4px;
  font-size: 34px;
  text-align: center;
  color: #ded2c4;
  cursor: pointer;
}

/* Big enough to hit with a thumb without looking, which is the whole point. */
.panel.small .letterRow button {
  margin: 6px 0;
  padding: 10px 0;
  font-size: 16px;
  line-height: 1;
}

.letter.on {
  border-color: #ffca4d;
  color: #ffca4d;
  /* The slot you are on blinks, the way the cabinet did it. */
  animation: blink 0.9s steps(2, start) infinite;
}

@keyframes blink { 50% { opacity: 0.35; } }

/* Generic and deliberately last: .overlay and .row set their own display with
   the same specificity, so this only wins by coming after them. Without it
   nothing with class="hidden" is actually hidden, and the result card sits
   underneath the menu the whole time rather than instead of it. */
.hidden { display: none; }
