html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #05060b;
  overflow: hidden;
  /* Stop iOS rubber-banding and pull-to-refresh dragging the game around. */
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

#stage {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}

#game {
  display: block;
  background: #05060b;
  /* Keep the pixels hard instead of letting the browser blur the upscale. */
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  box-shadow: 0 0 0 1px #1c2230, 0 18px 60px rgba(0, 0, 0, 0.75);
}

#boot {
  position: absolute;
  color: #4a5a70;
  font: 11px monospace;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

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

   Fixed overlay, so they work in portrait (sitting below the letterboxed
   canvas) and in landscape (overlapping the canvas corners, which is the
   normal convention for mobile games). Hidden entirely on desktop.
   --------------------------------------------------------------------------- */

#touch {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 16px 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  padding-left: calc(16px + env(safe-area-inset-left, 0px));
  padding-right: calc(16px + env(safe-area-inset-right, 0px));
  z-index: 10;
  pointer-events: none;   /* only the buttons themselves take input */
}

#touch[hidden] { display: none; }

/* Sizes are driven by these two so the whole cluster can be scaled in one
   place per breakpoint. Everything has to fit across the narrowest phone in
   portrait: 3 pad columns plus the action cluster plus the side gutters. */
#touch {
  --key: 54px;    /* d-pad cell, and the small action buttons */
  --fire: 86px;
}

#touch .pad {
  display: grid;
  grid-template-columns: repeat(3, var(--key));
  grid-template-rows: repeat(3, var(--key));
  gap: 4px;
}

#touch .acts {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

/* SPIN and JUMP stack beside BREATH. In one row the three of them overflowed
   a 375px screen in portrait. */
#touch .stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tb {
  pointer-events: auto;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  appearance: none;
  border: 1px solid rgba(170, 195, 225, 0.35);
  background: rgba(14, 20, 32, 0.55);
  color: #cfe0f0;
  font: bold 10px/1 monospace;
  letter-spacing: 0.08em;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 60ms linear, transform 60ms linear;
}

.tb.is-down {
  background: rgba(90, 170, 240, 0.55);
  border-color: rgba(210, 235, 255, 0.8);
  transform: scale(0.94);
}

/* D-pad placement inside the 3x3 grid, centre cell left empty. */
.tb-up    { grid-area: 1 / 2; }
.tb-left  { grid-area: 2 / 1; }
.tb-right { grid-area: 2 / 3; }
.tb-down  { grid-area: 3 / 2; }

/* Arrow glyphs drawn as CSS triangles, so no font or image dependency. */
.tb-up::after, .tb-down::after, .tb-left::after, .tb-right::after {
  content: '';
  border: 9px solid transparent;
}
.tb-up::after    { border-bottom-color: #cfe0f0; margin-bottom: 9px; }
.tb-down::after  { border-top-color: #cfe0f0;    margin-top: 9px; }
.tb-left::after  { border-right-color: #cfe0f0;  margin-right: 9px; }
.tb-right::after { border-left-color: #cfe0f0;   margin-left: 9px; }

.tb-jump, .tb-spin, .tb-roar {
  width: var(--key);
  height: var(--key);
  border-radius: 50%;
  font-size: 9px;
}

.tb-roar {
  border-color: rgba(160, 235, 170, 0.5);
  color: #9fe8b0;
}

.tb-roar.is-down {
  background: rgba(110, 220, 140, 0.55);
  color: #06210e;
}

.tb-spin {
  border-color: rgba(255, 190, 120, 0.5);
  color: #ffcf96;
}

.tb-spin.is-down {
  background: rgba(255, 180, 90, 0.55);
  color: #2a1606;
}

/* Sound toggle, parked out of the way in the top corner. */
.tb-mute {
  position: absolute;
  top: calc(8px + env(safe-area-inset-top, 0px));
  right: calc(12px + env(safe-area-inset-right, 0px));
  width: 52px;
  height: 26px;
  border-radius: 13px;
  font-size: 8px;
  opacity: 0.75;
}

.tb-mute.is-off {
  color: #7b8695;
  border-color: rgba(120, 135, 155, 0.35);
  text-decoration: line-through;
}

.tb-fire {
  width: var(--fire);
  height: var(--fire);
  border-radius: 50%;
  border-color: rgba(120, 210, 255, 0.55);
  background: rgba(20, 44, 70, 0.6);
  color: #9fe4ff;
  font-size: 11px;
}

.tb-fire.is-down {
  background: rgba(120, 220, 255, 0.62);
  color: #06121e;
}

/* Narrow phones in portrait. At 375px the full-size cluster is already close
   to the edge, and below that it has to come down. */
@media (max-width: 380px) {
  #touch { --key: 48px; --fire: 76px; padding-left: 10px; padding-right: 10px; }
}

@media (max-width: 330px) {
  #touch { --key: 42px; --fire: 66px; }
  .tb { font-size: 8px; }
}

/* Short landscape screens, where vertical room is what runs out. */
@media (max-height: 420px) {
  #touch {
    --key: 48px;
    --fire: 72px;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  }
  #touch .acts { gap: 8px; }
}
