/* css/style.css: MOO.F.O. '85 page shell. Letterbox, CRT overlay, touch deck and gutter buttons.
   Palette "NEON PASTURE 23" (UFO.PAL): k #0b0418, n #170a33, i #2b1260, v #4a1a8c, p #9b30ff, m #ff2bd6, h #ff6ec7,
   y #ffe14d, c #22f2ff, g #8cff3c, w #f6f0ff, l #c7b6ff, s #7d74b0.
   No @import, no @font-face, no url() to the network: the page makes zero requests (G.8).
   Variables written by UFO.Main.resize: --px (CSS scale), --scan (scanline period, CSS px), --deckH, --hudPH, --bandH. */

:root {
  --px: 1;
  --scan: 2px;
  --deckH: clamp(260px, 38vh, 340px);
  --hudPH: 76px;
  --bandH: 100px;
  --k: #0b0418; --n: #170a33; --i: #2b1260; --v: #4a1a8c; --p: #9b30ff; --m: #ff2bd6; --h: #ff6ec7;
  --y: #ffe14d; --c: #22f2ff; --g: #8cff3c; --w: #f6f0ff; --l: #c7b6ff; --s: #7d74b0;
  --mono: ui-monospace, Menlo, Consolas, "Courier New", monospace;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #0b0418;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  color: var(--l);
  font-family: var(--mono);
}

/* ------------------------------------------------------------------------------------------------------------------
   Letterbox: the canvas is centered on #0b0418. Portrait touch: the canvas sits directly on top of the deck.
   ------------------------------------------------------------------------------------------------------------------ */
#wrap {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  overflow: hidden;
}
body.portrait.touch #wrap {
  justify-content: flex-end;
  padding-bottom: env(safe-area-inset-bottom);
}

#stage {
  position: relative;
  flex: none;
  line-height: 0;
  /* a faint neon halo where the picture meets the letterbox */
  box-shadow: 0 0 0 1px rgba(155, 48, 255, .30), 0 0 22px rgba(255, 43, 214, .16), 0 0 70px rgba(34, 242, 255, .07);
}
body.portrait.touch #stage {
  box-shadow: 0 0 0 1px rgba(155, 48, 255, .30), 0 -6px 26px rgba(255, 43, 214, .12);
}
/* Portrait touch: the cabinet topper sign (the logo, painted by UI.layout) fills the free band above the field. It
   shrinks with the band (the playfield zoom grows the canvas into it). */
#topper { display: none; }
body.portrait.touch #topper {
  display: flex;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  align-items: center;
  justify-content: center;
  padding: 10px 24px 14px;
  overflow: hidden;
  pointer-events: none;
}
#topperLogo {
  display: block;
  width: 100%;
  height: 100%;
  max-width: 340px;
  max-height: 96px;
  object-fit: contain;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  opacity: .92;
  filter: drop-shadow(0 0 10px rgba(255, 43, 214, .35));
}
body[data-state="BOOT"] #topperLogo, body:not(.topper) #topperLogo { visibility: hidden; }   /* .topper: band >= 56 px */

/* Band touch layout (B.4): the canvas is centred above a strip that holds the three buttons */
body.band.touch #wrap {
  padding-bottom: calc(var(--bandH, 100px) + env(safe-area-inset-bottom));
}

#game {
  display: block;
  width: 480px;
  height: 270px;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  touch-action: none;
  outline: none;
  cursor: crosshair;
  background: #0b0418;
}
/* Portrait touch: the playfield zoom (Main.resize, body.zoom while the world runs) eases in and out. When zoomed the
   canvas is wider than the screen; #wrap centres it and clips the side columns. body.zoomease is on only when the
   resize kept the layout and viewport (so the zoom toggled): a load or a rotation snaps to the new size. */
body.zoomease.portrait.touch #game { transition: width .2s ease-out, height .2s ease-out; }
body.reduced.zoomease.portrait.touch #game { transition: none; }
@media (prefers-reduced-motion: reduce) {
  body.zoomease.portrait.touch #game { transition: none; }
}

/* ------------------------------------------------------------------------------------------------------------------
   CRT overlay (F.1). OFF / LITE / FULL via the class UI.setSetting writes. Scanlines: 1 logical row per period
   (2 rows below scale 2, none below 1.2: body.noscan), at rgba(11,4,24,.32) (LITE .22); vignette on top of the picture.
   ------------------------------------------------------------------------------------------------------------------ */
#crt {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
#crt.crt-off { display: none; }
/* LITE (the default) reads as texture, not dimming: lighter scanlines and a soft corner vignette, so the HUD corners
   (score, clock, combo) keep their brightness. FULL keeps the heavy vignette. */
#crt.crt-lite {
  background-image:
    repeating-linear-gradient(to bottom,
      rgba(11, 4, 24, 0) 0,
      rgba(11, 4, 24, 0) calc(var(--scan, calc(var(--px) * 1px)) * .5),
      rgba(11, 4, 24, .22) calc(var(--scan, calc(var(--px) * 1px)) * .5),
      rgba(11, 4, 24, .22) var(--scan, calc(var(--px) * 1px))),
    radial-gradient(ellipse farthest-corner, rgba(11, 4, 24, 0) 72%, rgba(11, 4, 24, .16) 100%);
}
#crt.crt-full {
  background-image:
    repeating-linear-gradient(to bottom,
      rgba(11, 4, 24, 0) 0,
      rgba(11, 4, 24, 0) calc(var(--scan, calc(var(--px) * 1px)) * .5),
      rgba(11, 4, 24, .32) calc(var(--scan, calc(var(--px) * 1px)) * .5),
      rgba(11, 4, 24, .32) var(--scan, calc(var(--px) * 1px))),
    radial-gradient(ellipse, rgba(11, 4, 24, 0) 60%, rgba(11, 4, 24, .55));
}
body.noscan #crt.crt-lite {
  background-image: radial-gradient(ellipse farthest-corner, rgba(11, 4, 24, 0) 72%, rgba(11, 4, 24, .16) 100%);
}
body.noscan #crt.crt-full {
  background-image: radial-gradient(ellipse, rgba(11, 4, 24, 0) 60%, rgba(11, 4, 24, .55));
}
#crt.crt-full {
  animation: crt-flicker .12s steps(1, end) infinite;   /* two discrete phosphor states per .12 s */
}
@keyframes crt-flicker {
  0% { opacity: .97; }
  50% { opacity: 1; }
  100% { opacity: .97; }
}
@media (prefers-reduced-motion: reduce) {
  #crt.crt-full { animation: none; }
}
body.reduced #crt.crt-full { animation: none; }

/* ------------------------------------------------------------------------------------------------------------------
   Touch buttons (DOM; never over the canvas). Hidden unless body.touch.
   ------------------------------------------------------------------------------------------------------------------ */
.beam, .lock, .pause {
  display: none;
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  padding: 0;
  flex: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  letter-spacing: 2px;
  text-indent: 2px;               /* optically center the letter-spaced label */
  color: var(--w);
  border: 3px solid var(--c);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, rgba(34, 242, 255, .30), rgba(23, 10, 51, .88) 62%, rgba(11, 4, 24, .94));
  box-shadow: 0 0 10px rgba(34, 242, 255, .55), 0 0 26px rgba(34, 242, 255, .22), inset 0 0 14px rgba(34, 242, 255, .35);
  text-shadow: 0 0 6px var(--c), 0 0 2px var(--c);
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  cursor: pointer;
  outline: none;
  transition: transform .06s ease-out, opacity .08s linear, box-shadow .08s linear;
}
.lock {
  border-color: var(--m);
  background: radial-gradient(circle at 50% 38%, rgba(255, 43, 214, .30), rgba(23, 10, 51, .88) 62%, rgba(11, 4, 24, .94));
  box-shadow: 0 0 10px rgba(255, 43, 214, .55), 0 0 26px rgba(255, 43, 214, .22), inset 0 0 14px rgba(255, 43, 214, .35);
  text-shadow: 0 0 6px var(--m), 0 0 2px var(--m);
}
.pause {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border-width: 2px;
  font-size: 14px;
  letter-spacing: 1px;
  text-indent: 1px;
  background: linear-gradient(180deg, rgba(34, 242, 255, .18), rgba(11, 4, 24, .92));
  box-shadow: 0 0 8px rgba(34, 242, 255, .45), inset 0 0 8px rgba(34, 242, 255, .25);
}
.beam:focus-visible, .lock:focus-visible, .pause:focus-visible { outline: 2px dashed var(--y); outline-offset: 3px; }

/* pressed: :active plus any state class the input layer may set */
.beam:active, .beam.on, .beam.active, .beam.held, .beam.pressed, .beam[aria-pressed="true"],
.lock:active, .lock.on, .lock.active, .lock.held, .lock.pressed, .lock[aria-pressed="true"],
.pause:active, .pause.on, .pause.active, .pause.held, .pause.pressed {
  transform: scale(.93);
  color: #ffffff;
}
.beam:active, .beam.on, .beam.active, .beam.held, .beam.pressed, .beam[aria-pressed="true"] {
  background: radial-gradient(circle at 50% 42%, rgba(246, 240, 255, .55), rgba(34, 242, 255, .45) 45%, rgba(23, 10, 51, .9) 80%);
  box-shadow: 0 0 16px rgba(34, 242, 255, .95), 0 0 40px rgba(34, 242, 255, .45), inset 0 0 18px rgba(246, 240, 255, .5);
}
.lock:active, .lock.on, .lock.active, .lock.held, .lock.pressed, .lock[aria-pressed="true"] {
  background: radial-gradient(circle at 50% 42%, rgba(246, 240, 255, .55), rgba(255, 43, 214, .45) 45%, rgba(23, 10, 51, .9) 80%);
  box-shadow: 0 0 16px rgba(255, 43, 214, .95), 0 0 40px rgba(255, 43, 214, .45), inset 0 0 18px rgba(246, 240, 255, .5);
}

/* AUTO-BEAM latch on: lime glow and an "AUTO" label */
body.autobeam .beam {
  border-color: var(--g);
  box-shadow: 0 0 12px rgba(140, 255, 60, .7), 0 0 30px rgba(140, 255, 60, .3), inset 0 0 14px rgba(140, 255, 60, .35);
  text-shadow: 0 0 6px var(--g), 0 0 2px var(--c);
}
body.autobeam .beam::after {
  content: 'AUTO';
  display: block;
  font-size: 9px;
  letter-spacing: 1px;
  text-indent: 1px;
  color: var(--g);
  text-shadow: 0 0 4px var(--g);
}

/* Landscape touch: the three gutter buttons, inset 20px + safe area from the screen edges, 45 % opacity */
body.touch.landscape #pauseBtnL,
body.touch.landscape #lockBtnL,
body.touch.landscape #beamBtnL {
  display: flex;
  position: fixed;
  z-index: 5;
  opacity: .45;
}
body.touch.landscape #pauseBtnL {
  top: calc(20px + env(safe-area-inset-top));
  left: calc(20px + env(safe-area-inset-left));
}
body.touch.landscape #lockBtnL {
  width: 72px;
  height: 72px;
  bottom: calc(20px + env(safe-area-inset-bottom));
  left: calc(20px + env(safe-area-inset-left));
}
body.touch.landscape #beamBtnL {
  width: 76px;
  height: 76px;
  font-size: 16px;
  bottom: calc(20px + env(safe-area-inset-bottom));
  right: calc(20px + env(safe-area-inset-right));
}
/* Band layout: the pause square sits in the strip next to LOCK instead of over the full-width canvas */
body.touch.band #pauseBtnL {
  top: auto;
  left: calc(20px + 72px + 14px + env(safe-area-inset-left));
  bottom: calc(20px + 14px + env(safe-area-inset-bottom));
}

/* Landscape gutter trackpads (B.4): #padL between pause and LOCK, #padR above BEAM. They steer exactly like the
   portrait #pad (world-anchored drag from touchstart, edge scroll, menu swipes), so the thumb never covers the field.
   Inside the safe area and the 96 px gutter, 12 px clear of the buttons. */
.gpad { display: none; }
body.touch.landscape:not(.band) .gpad {
  display: block;
  position: fixed;
  z-index: 4;
  opacity: .45;
}
body.touch.landscape:not(.band) #padL {
  left: calc(20px + env(safe-area-inset-left));
  width: 72px;
  top: calc(20px + 44px + 12px + env(safe-area-inset-top));
  bottom: calc(20px + 72px + 12px + env(safe-area-inset-bottom));
}
body.touch.landscape:not(.band) #padR {
  right: calc(20px + env(safe-area-inset-right));
  width: 76px;
  top: calc(20px + env(safe-area-inset-top));
  bottom: calc(20px + 76px + 12px + env(safe-area-inset-bottom));
}
/* Band layout: #padR becomes a horizontal strip in the band, between the pause square and BEAM */
body.touch.band #padR {
  display: block;
  position: fixed;
  z-index: 4;
  opacity: .45;
  left: calc(20px + 72px + 14px + 44px + 14px + env(safe-area-inset-left));
  right: calc(20px + 76px + 14px + env(safe-area-inset-right));
  bottom: calc(20px + env(safe-area-inset-bottom));
  height: 76px;
}
@media (max-width: 359px) {
  body.touch.band #padR { display: none; }
}
body.touch.landscape .gpad.dragging { opacity: .8; }

body.touch.landscape #pauseBtnL:active, body.touch.landscape #lockBtnL:active, body.touch.landscape #beamBtnL:active,
body.touch.landscape .beam.on, body.touch.landscape .beam.active, body.touch.landscape .beam.held, body.touch.landscape .beam.pressed,
body.touch.landscape .lock.on, body.touch.landscape .lock.active, body.touch.landscape .lock.held, body.touch.landscape .lock.pressed {
  opacity: .9;
}

/* ------------------------------------------------------------------------------------------------------------------
   Portrait touch: the control deck under the canvas (deck HUD, trackpad, LOCK, BEAM, pause, rotate chip)
   ------------------------------------------------------------------------------------------------------------------ */
#deck {
  display: none;
  flex-direction: column;
  align-items: center;
  flex: none;
  width: 100%;
  height: var(--deckH, clamp(260px, 38vh, 340px));
  padding: 0 env(safe-area-inset-right) 0 env(safe-area-inset-left);
  overflow: hidden;
  position: relative;
  background-color: #0b0418;
  background-image:
    linear-gradient(180deg, rgba(255, 43, 214, .16) 0, rgba(255, 43, 214, 0) 18px),
    linear-gradient(rgba(255, 43, 214, .075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 43, 214, .075) 1px, transparent 1px),
    linear-gradient(180deg, rgba(23, 10, 51, 0) 40%, rgba(74, 26, 140, .35));
  background-size: 100% 100%, 22px 22px, 22px 22px, 100% 100%;
  background-position: 0 0, 0 -1px, -1px 0, 0 0;
  border-top: 2px solid var(--m);
  box-shadow: 0 -2px 14px rgba(255, 43, 214, .45);
}
body.touch.portrait #deck { display: flex; }
body.touch.portrait #deck .beam,
body.touch.portrait #deck .lock,
body.touch.portrait #deck .pause { display: flex; }

#hudP {
  display: block;
  flex: none;
  width: 400px;
  height: var(--hudPH, 76px);
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  touch-action: none;
  background: #0b0418;
  box-shadow: 0 1px 0 rgba(155, 48, 255, .55);   /* no border: keeps the 200x38 bitmap at an exact CSS scale */
}

#deckRow {
  display: flex;
  flex: 1;
  position: relative;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 0;
  padding: 10px 12px 8px;
}

#pad {
  flex: 1;
  align-self: stretch;
  min-width: 0;
  position: relative;
}
#pad, .gpad {
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  border: 2px solid rgba(34, 242, 255, .55);
  border-radius: 16px;
  background-color: rgba(23, 10, 51, .85);
  background-image:
    radial-gradient(ellipse at 50% 55%, rgba(34, 242, 255, .16), rgba(34, 242, 255, 0) 62%),
    linear-gradient(rgba(34, 242, 255, .10) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34, 242, 255, .10) 1px, transparent 1px);
  background-size: 100% 100%, 16px 16px, 16px 16px;
  background-position: 0 0, 0 7px, 7px 0;
  box-shadow: inset 0 0 18px rgba(34, 242, 255, .25), inset 0 0 2px rgba(34, 242, 255, .6), 0 0 10px rgba(34, 242, 255, .2);
  overflow: hidden;
}
#pad::before, .gpad::before {     /* center reticle */
  content: '';
  position: absolute;
  left: 50%; top: 46%;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 2px solid rgba(34, 242, 255, .45);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(34, 242, 255, .35), inset 0 0 6px rgba(34, 242, 255, .3);
  background:
    linear-gradient(rgba(34, 242, 255, .55), rgba(34, 242, 255, .55)) center / 2px 12px no-repeat,
    linear-gradient(rgba(34, 242, 255, .55), rgba(34, 242, 255, .55)) center / 12px 2px no-repeat;
  pointer-events: none;
}
#pad::after {                     /* label */
  content: 'DRAG TO FLY';
  position: absolute;
  left: 0; right: 0; bottom: 8px;
  text-align: center;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2px;
  color: rgba(34, 242, 255, .7);
  text-shadow: 0 0 6px rgba(34, 242, 255, .6);
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
}
.gpad::after {                    /* gutter strip label */
  content: 'DRAG';
  position: absolute;
  left: 0; right: 0; bottom: 6px;
  text-align: center;
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1px;
  text-indent: 1px;
  color: rgba(34, 242, 255, .8);
  text-shadow: 0 0 6px rgba(34, 242, 255, .6);
  pointer-events: none;
}
#pad:active, #pad.on, #pad.active, #pad.dragging, .gpad.dragging {
  border-color: var(--c);
  box-shadow: inset 0 0 26px rgba(34, 242, 255, .4), inset 0 0 2px var(--c), 0 0 16px rgba(34, 242, 255, .45);
}

/* LOCK and BEAM sit below the row's middle so the top-right pause square keeps >= 8 px clear of the BEAM circle even
   in the shortest deck (a 126 px content row: BEAM top at row+55, pause bottom at row+46; BEAM still ends inside the
   row's bottom padding) */
#lockBtnP {
  width: 72px;
  height: 72px;
  margin-top: 52px;
}
#beamBtnP {
  width: 88px;
  height: 88px;
  margin-top: 52px;
  font-size: 17px;
}
#pauseBtnP {
  position: absolute;
  top: 2px;
  right: 12px;
}

#rotateHint {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 24px);
  margin: 0 0 8px;
  padding: 4px 4px 4px 12px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  line-height: 1.2;
  color: var(--h);
  text-shadow: 0 0 5px rgba(255, 43, 214, .7);
  border: 1px solid rgba(255, 43, 214, .7);
  border-radius: 999px;
  background: rgba(23, 10, 51, .9);
  box-shadow: 0 0 8px rgba(255, 43, 214, .35);
  white-space: nowrap;
  overflow: hidden;
}
#rotateClose {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--m);
  color: var(--w);
  font-size: 10px;
  cursor: pointer;
  touch-action: none;
}
#rotateClose:active { background: rgba(255, 43, 214, .5); }
body.rotate-dismissed #rotateHint { display: none; }

/* ------------------------------------------------------------------------------------------------------------------
   Safe-area probe (read by UFO.Main.resize) and the no-JS message
   ------------------------------------------------------------------------------------------------------------------ */
#insetProbe {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  visibility: hidden;
  pointer-events: none;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

noscript {
  position: fixed;
  left: 0; right: 0; top: 45%;
  display: block;
  text-align: center;
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 2px;
  color: var(--m);
  text-shadow: 0 0 8px var(--m);
}
