/* Task 8 — arcade-cabinet theme.
   Frames the EmulatorJS screen (#game) as an arcade cabinet: dark room, backlit marquee,
   recessed bezel + CRT vignette. Deliberately a LIGHTWEIGHT full-viewport frame, not a chunky
   cabinet: #game must keep (near-)full viewport so the touch controller — which EmulatorJS anchors
   position:absolute to the bottom of #game's .ejs_parent — stays full-size and reachable.

   DOM (index.html): .cabinet > .marquee + (.bezel > #game + #boot).
   .ejs_parent (EmulatorJS-generated, inside #game) is overflow:hidden + 100%x100%, so the marquee
   and frame live OUTSIDE #game (they'd be clipped inside it). No web fonts — offline / no-CDN rule. */

:root {
  --room-0: #050505;
  --room-1: #0b0a09;
  --room-2: #1a1512;
  --frame: #14100d;
  --frame-edge: #3a2f24;
  --marquee-a: #ffb43a;
  --marquee-b: #ff7a18;
  --marquee-ink: #2a1300;
}

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

html, body {
  margin: 0;
  height: 100%;
  background: var(--room-0);
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

/* Dark room: dim warm pool of light behind the cabinet, near-black at the edges. */
body {
  background:
    radial-gradient(120% 90% at 50% 22%, var(--room-2) 0%, var(--room-1) 46%, var(--room-0) 100%);
  color: #e8e2d6;
  font-family: "Avenir Next", "Segoe UI", Helvetica, Arial, sans-serif;
}

/* ---- Cabinet: full-viewport column, marquee on top, bezel filling the rest ---- */
.cabinet {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  max-width: 1100px;
  margin: 0 auto;
  padding:
    max(8px, env(safe-area-inset-top))
    max(8px, env(safe-area-inset-right))
    max(8px, env(safe-area-inset-bottom))
    max(8px, env(safe-area-inset-left));
}

/* ---- Backlit marquee: slim glowing title header ---- */
.marquee {
  flex: 0 0 auto;
  position: relative;
  margin-bottom: 8px;
  padding: 6px 18px;
  border-radius: 10px 10px 6px 6px;
  text-align: center;
  background:
    linear-gradient(180deg, #fff5e0 0%, var(--marquee-a) 18%, var(--marquee-b) 78%, #d85e0a 100%);
  border: 1px solid rgba(0, 0, 0, .5);
  box-shadow:
    0 0 26px 2px rgba(255, 138, 32, .55),   /* backlight spill into the room */
    inset 0 2px 3px rgba(255, 255, 255, .7),
    inset 0 -4px 8px rgba(120, 40, 0, .55),
    0 4px 10px rgba(0, 0, 0, .6);
}

.marquee__title {
  display: block;
  font-family: "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  font-weight: 800;
  font-size: clamp(15px, 4.4vw, 30px);
  line-height: 1.05;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--marquee-ink);
  text-shadow: 0 1px 0 rgba(255, 240, 210, .6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Bezel: recessed dark frame that holds the CRT screen ---- */
.bezel {
  flex: 1 1 auto;
  min-height: 0;             /* let it shrink inside the flex column */
  position: relative;
  padding: 12px;             /* thin frame; keep small so it doesn't eat the touch area */
  border-radius: 16px;
  background:
    linear-gradient(160deg, var(--frame-edge) 0%, var(--frame) 40%, #0c0906 100%);
  border: 1px solid rgba(0, 0, 0, .8);
  box-shadow:
    0 10px 30px rgba(0, 0, 0, .7),                 /* cabinet sits in the room */
    inset 0 1px 0 rgba(255, 255, 255, .06),        /* top frame highlight */
    inset 0 0 0 2px rgba(0, 0, 0, .6);             /* inner lip */
}

/* The screen mount. EmulatorJS injects .ejs_parent (relative, 100%x100%) in here. */
#game {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .9);   /* screen sits below the bezel lip */
}

/* Design critique fix (P1): EmulatorJS writes its own progress/error text into #game
   (.ejs_loading_text, data/emulator.css:189 — no inline style, so a plain rule is enough) and it
   was bleeding through faintly behind our own #loadstate/#errstate overlays, showing two competing
   messages at once. We have our own state machine (app.js) and a MutationObserver watching this
   same element's .ejs_error_text class, so we never need EJS's copy to be visible — hide it always. */
.ejs_loading_text { display: none !important; }

/* CRT vignette over the whole screen. pointer-events:none → touches pass to the controller.
   Kept gentle so the bright controller caps in the lower corners stay clearly visible. */
.bezel::after {
  content: "";
  position: absolute;
  inset: 12px;                                     /* match .bezel padding = screen area */
  border-radius: 8px;
  pointer-events: none;
  z-index: 3;
  background:
    radial-gradient(120% 120% at 50% 48%, transparent 62%, rgba(0, 0, 0, .38) 100%);
  box-shadow: inset 0 0 46px rgba(0, 0, 0, .5);
}

/* ---- Task 9: screen-state overlays over the CRT screen (gate / loading / error).
   Absolute inside .bezel, above the vignette (::after z-index 3). app.js toggles [hidden]. ---- */
[hidden] { display: none !important; }

.gate,
.overlay {
  position: absolute;
  inset: 12px;                                     /* cover the screen area (matches bezel padding) */
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 16px;
  text-align: center;
  border-radius: 8px;
  background: radial-gradient(120% 120% at 50% 45%, rgba(10, 8, 6, .72), rgba(0, 0, 0, .93));
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* Insert-coin button: big glowing arcade pill with a gentle attract pulse. */
.gate__btn {
  min-width: 220px;
  min-height: 88px;
  padding: 14px 34px;
  border: 2px solid rgba(0, 0, 0, .6);
  border-radius: 16px;
  cursor: pointer;
  color: var(--marquee-ink);
  font-family: "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  text-transform: uppercase;
  letter-spacing: .06em;
  background: linear-gradient(180deg, #ffe08a 0%, var(--marquee-a) 45%, var(--marquee-b) 100%);
  box-shadow:
    0 0 34px 4px rgba(255, 138, 32, .5),
    inset 0 2px 3px rgba(255, 255, 255, .7),
    0 6px 12px rgba(0, 0, 0, .5);
  animation: gate-pulse 1.6s ease-in-out infinite;
}
.gate__coin  { display: block; font-size: clamp(20px, 6.5vw, 36px); line-height: 1; }
.gate__label { display: block; font-weight: 800; font-size: clamp(18px, 5.5vw, 30px); }
.gate__sub   { display: block; font-weight: 600; font-size: clamp(11px, 3vw, 15px); opacity: .85; margin-top: 3px; }
.gate__btn:active { transform: translateY(2px); filter: brightness(.95); animation: none; }
/* Design critique fix (P2): #insertcoin/#repick are real <button>s (natively focusable) with no
   focus style before this — a keyboard/switch-access user got zero confirmation before triggering
   fullscreen+audio-unlock+boot. (The virtual gamepad's own buttons are plain EmulatorJS-generated
   <div>s with no tabindex — not natively focusable — so a focus-visible style there would be a
   no-op without injecting tabindex into vendored dynamic DOM; out of scope for this pass.) */
.gate__btn:focus-visible {
  outline: 3px solid #fff3b0;
  outline-offset: 3px;
}

.gate__btn--sm {
  min-width: 180px;
  min-height: 56px;
  padding: 12px 22px;
  font-weight: 700;
  font-size: clamp(13px, 3.6vw, 15px);
  animation: none;
}

@keyframes gate-pulse {
  0%, 100% { box-shadow: 0 0 20px 2px rgba(255, 138, 32, .4),  inset 0 2px 3px rgba(255, 255, 255, .7), 0 6px 12px rgba(0, 0, 0, .5); }
  50%      { box-shadow: 0 0 40px 8px rgba(255, 138, 32, .78), inset 0 2px 3px rgba(255, 255, 255, .7), 0 6px 12px rgba(0, 0, 0, .5); }
}

/* Loading spinner + messages. */
.overlay__spinner {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 4px solid rgba(255, 180, 58, .25);
  border-top-color: var(--marquee-a);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.overlay__msg   { margin: 0; color: #f2e6d2; font-size: clamp(13px, 3.6vw, 16px); font-weight: 600; letter-spacing: .04em; }
.overlay__title { margin: 0; color: #ff8a5a; font-weight: 800; font-size: clamp(15px, 4.4vw, 20px); text-transform: uppercase; letter-spacing: .05em; }
.overlay--error .overlay__msg { max-width: 34ch; opacity: .9; }

@media (prefers-reduced-motion: reduce) {
  .gate__btn { animation: none; }
  .overlay__spinner { animation-duration: 1.6s; }
}

/* ---- Escape hatch: "Change ROM" corner button (see index.html + app.js).
   A wrong-version romset makes FBNeo draw its error INSIDE the WASM canvas — not the DOM — so the
   app can't switch to #errstate and would strand the user on that screen. This button sits above the
   overlays (z 6) and vignette (z 3) so it's always tappable once booting/started. Kept small and
   semi-transparent so it recedes during play, and a ≥44px tap target (Fitts) for touch. ---- */
.rompick {
  position: absolute;
  top: 20px;                                       /* inside the bezel padding (12px) + a little inset */
  right: 20px;
  z-index: 8;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid rgba(0, 0, 0, .55);
  border-radius: 12px;
  cursor: pointer;
  color: var(--marquee-ink);
  font-family: "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  font-weight: 700;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .05em;
  background: linear-gradient(180deg, #ffe08a 0%, var(--marquee-a) 45%, var(--marquee-b) 100%);
  box-shadow: inset 0 1px 2px rgba(255, 255, 255, .6), 0 3px 8px rgba(0, 0, 0, .5);
  opacity: .5;                                     /* recede during play... */
  transition: opacity .15s ease;
}
.rompick:hover,
.rompick:focus-visible { opacity: 1; }             /* ...surface on intent (pointer devices) */
.rompick:focus-visible { outline: 3px solid #fff3b0; outline-offset: 3px; }
.rompick:active { transform: translateY(1px); filter: brightness(.95); opacity: 1; }
.rompick__icon { font-size: 16px; line-height: 1; }

@media (prefers-reduced-motion: reduce) {
  .rompick { transition: none; }
}

/* Design critique fix (P3): a lightweight, CSS-only "rotate your device" nudge. The product is
   landscape-only (screen.orientation.lock('landscape') fires on the gate tap — but iOS Safari has
   no orientation-lock API at all, and even where it's supported the lock can't fire before the
   first tap), so a visitor who opens the app in portrait would otherwise see the cabinet awkwardly
   letterboxed. This sits above every other state (z-index above the gate's) and needs no JS — the
   media query alone shows/hides it as the device (or an already-locked viewport) actually rotates. */
.rotate-nudge {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 20;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  background: rgba(5, 5, 5, .96);
  color: #f2e6d2;
  text-align: center;
}
@media (orientation: portrait) {
  .rotate-nudge { display: flex; }
}
.rotate-nudge__icon {
  font-size: 44px;
  line-height: 1;
  animation: rotate-hint 1.6s ease-in-out infinite;
}
.rotate-nudge__text {
  margin: 0;
  font-weight: 700;
  font-size: clamp(14px, 4.4vw, 18px);
  text-transform: uppercase;
  letter-spacing: .05em;
}
@keyframes rotate-hint {
  0%, 100% { transform: rotate(0deg); }
  50%      { transform: rotate(-90deg); }
}
@media (prefers-reduced-motion: reduce) {
  .rotate-nudge__icon { animation: none; }
}

/* ---- Short landscape (phones): reclaim vertical space for the playfield ---- */
@media (max-height: 460px) {
  .marquee { margin-bottom: 5px; padding: 3px 14px; border-radius: 7px; }
  .marquee__title { font-size: clamp(13px, 3.6vh, 20px); }
  .bezel { padding: 8px; border-radius: 12px; }
  .bezel::after,
  .gate,
  .overlay { inset: 8px; }
  .gate__btn { min-height: 76px; }
  .rompick { top: 14px; right: 14px; min-height: 40px; padding: 6px 12px; font-size: 12px; }
}
