/* style.css — the game viewport and optional handheld presentation.
 *
 * The game is 176x160 logical pixels on #screen and knows nothing about the
 * shell around it. Over HTTP, device-shell.js places it into the 3D handheld.
 * On file://, a clean screen-only fallback remains available.
 *
 * All shell geometry is expressed in --u, where 1u == 1 logical screen pixel.
 * js/shell.js picks --u as an integer so the canvas always lands on a whole
 * multiple and the art stays crisp. */

:root {
  --device-safe-top: env(safe-area-inset-top, 0px);
  --device-safe-right: env(safe-area-inset-right, 0px);
  --device-safe-bottom: env(safe-area-inset-bottom, 0px);
  --device-safe-left: env(safe-area-inset-left, 0px);
  --u: 2px;
  --screen-zoom: 1;

  --case-lit:   #a983cc;
  --case-mid:   #7f57ab;
  --case-dark:  #56356f;
  --case-edge:  #c9a9e4;
  --internals:  #241a33;

  --bezel-lit:  #4a4258;
  --bezel:      #2b2536;
  --bezel-dark: #1a1622;

  --btn-face:   #3b3348;
  --btn-edge:   #574c68;
  --btn-shadow: #17131f;

  --room:       #141c21;
}

* { box-sizing: border-box; }

/* Quiet desktop credit, opposite the sound control. */
#creator-credit { display: none; }
@media (min-width: 900px) and (hover: hover) and (pointer: fine) {
  #creator-credit {
    display: flex;
    align-items: center;
    position: fixed;
    top: calc(8px + env(safe-area-inset-top, 0px));
    left: calc(20px + env(safe-area-inset-left, 0px));
    min-height: 44px;
    z-index: 8;
    color: #929d9e;
    font: 400 12px/1.4 system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
    text-decoration: none;
    text-transform: none;
  }
  #creator-credit:hover { color: #bbc6c4; text-decoration: underline; text-underline-offset: 3px; }
  #creator-credit:focus-visible { outline: 2px solid #bbc6c4; outline-offset: 4px; }
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* Game chrome should never become a selection while dragging. Real fields
 * still support selecting/copying text in the local tools and share dialogs. */
input, textarea, [contenteditable="true"], [contenteditable=""] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

#stage, #screen, #device-shell-canvas, #mobile-screen {
  touch-action: none;
  -webkit-user-drag: none;
}

html { background: var(--room); }

body {
  background:
    radial-gradient(120% 90% at 50% 12%, #2b3737 0%, var(--room) 62%, #0b1117 100%);
  color: #a9bab3;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 100vh;
  overflow: hidden;
}

#stage { display: flex; align-items: center; justify-content: center; }

html.model-shell-pending #console {
  visibility: hidden;
}

#device-shell-canvas {
  display: none;
}

body.model-shell {
  background:
    radial-gradient(90% 85% at 50% 42%, #2b3635 0%, var(--room) 60%, #090f14 100%);
}

body.model-shell #stage {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: auto;
}

body.model-shell #device-shell-canvas {
  position: fixed;
  inset: 0;
  display: block;
  width: 100vw;
  height: 100vh;
  pointer-events: auto;
}

body.model-shell #console {
  display: none;
}

body.model-shell #screen {
  position: fixed;
  left: -9999px;
  top: 0;
  z-index: 2;
  width: 176px;
  height: 160px;
  opacity: 0;
  pointer-events: none;
}

body.model-shell #hud {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 22px;
  z-index: 3;
  justify-content: center;
}

#device-debug-canvas {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

/* ---- the case ------------------------------------------------------- */

#console {
  position: relative;
  width: calc(232 * var(--u));
  height: calc(348 * var(--u));
  padding: calc(18 * var(--u)) calc(22 * var(--u));
  border-radius: calc(16 * var(--u)) calc(16 * var(--u))
                 calc(44 * var(--u)) calc(16 * var(--u));
  background:
    /* specular sweep across the plastic */
    linear-gradient(148deg,
      rgba(255,255,255,0.30) 0%,
      rgba(255,255,255,0.06) 22%,
      rgba(255,255,255,0.00) 46%),
    /* the shapes you can half-see through translucent plastic */
    radial-gradient(60% 30% at 22% 74%, rgba(20,12,32,0.55) 0%, rgba(20,12,32,0) 70%),
    radial-gradient(45% 22% at 80% 88%, rgba(20,12,32,0.45) 0%, rgba(20,12,32,0) 70%),
    linear-gradient(165deg, var(--case-lit) 0%, var(--case-mid) 45%, var(--case-dark) 100%);
  box-shadow:
    inset 0 calc(1 * var(--u)) 0 rgba(255,255,255,0.55),
    inset 0 calc(-2 * var(--u)) 0 rgba(0,0,0,0.35),
    inset calc(1 * var(--u)) 0 0 rgba(255,255,255,0.22),
    inset calc(-1 * var(--u)) 0 0 rgba(0,0,0,0.22),
    0 calc(10 * var(--u)) calc(24 * var(--u)) rgba(0,0,0,0.55);
}

/* Faint seam line down the case, the way a real shell splits. */
#console::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: calc(232 * var(--u));
  height: 1px;
  background: rgba(255,255,255,0.10);
  pointer-events: none;
}

/* ---- screen --------------------------------------------------------- */

.bezel {
  width: calc(188 * var(--u));
  height: calc(196 * var(--u));
  border-radius: calc(6 * var(--u)) calc(6 * var(--u))
                 calc(22 * var(--u)) calc(6 * var(--u));
  background: linear-gradient(160deg, var(--bezel-lit) 0%, var(--bezel) 38%, var(--bezel-dark) 100%);
  box-shadow:
    inset 0 calc(1 * var(--u)) 0 rgba(255,255,255,0.14),
    0 calc(1 * var(--u)) 0 rgba(255,255,255,0.20);
  display: flex;
  align-items: center;
  justify-content: center;
}

.bezel-inner {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

#screen {
  display: block;
  width: calc(176 * var(--u));
  height: calc(160 * var(--u));
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #cfe2dc;
  outline: none;
  /* Focus is drawn inside the canvas as an inverted block; a browser ring at
     this scale would sit at a different pixel grid than everything else. */
  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
  transform: scale(var(--screen-zoom));
  transform-origin: center;
}

/* ---- screen-only fallback ------------------------------------------
 * ES modules and the 3D model cannot load reliably from file://. In that
 * environment show the game itself, not the retired purple CSS imitation of
 * the device. These rules are inactive as soon as the real model takes over. */
body:not(.model-shell) #console {
  width: auto;
  height: auto;
  padding: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body:not(.model-shell) #console::after,
body:not(.model-shell) .wordmark,
body:not(.model-shell) .controls,
body:not(.model-shell) .startsel,
body:not(.model-shell) .speaker,
body:not(.model-shell) .led,
body:not(.model-shell) .bezel-label,
body:not(.model-shell) #zoom-toggle {
  display: none;
}

body:not(.model-shell) .bezel {
  width: calc(176 * var(--u) + 8px);
  height: calc(160 * var(--u) + 8px);
  padding: 4px;
  border-radius: 7px;
  background: #090b10;
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.10),
    0 16px 48px rgba(0,0,0,0.48);
}

body:not(.model-shell) .bezel-inner {
  border-radius: 3px;
}

.led {
  position: absolute;
  left: calc(6 * var(--u));
  top: calc(88 * var(--u));
  width: calc(5 * var(--u));
  height: calc(5 * var(--u));
  border-radius: 50%;
  background: #d8433c;
  box-shadow: 0 0 calc(4 * var(--u)) rgba(216,67,60,0.9),
              inset 0 0 calc(1 * var(--u)) rgba(255,190,185,0.9);
}

.bezel-label {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(4 * var(--u));
  text-align: center;
  font-size: calc(4.2 * var(--u));
  letter-spacing: 0.14em;
  color: #8d84a0;
}

/* ---- wordmark ------------------------------------------------------- */

.wordmark {
  margin-top: calc(6 * var(--u));
  text-align: center;
  font-size: calc(9 * var(--u));
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.02em;
}
.wm-nintendo { color: #f0e6f8; }
.wm-color {
  background: linear-gradient(90deg, #f5c542, #57c06a, #4aa8e0, #d8536f);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

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

.controls {
  position: absolute;
  left: calc(22 * var(--u));
  right: calc(22 * var(--u));
  top: calc(246 * var(--u));
  height: calc(56 * var(--u));
}

.dpad {
  position: absolute;
  left: calc(4 * var(--u));
  top: 0;
  width: calc(54 * var(--u));
  height: calc(54 * var(--u));
}

.dpad-btn {
  position: absolute;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: linear-gradient(160deg, var(--btn-edge), var(--btn-face));
  box-shadow: 0 calc(1 * var(--u)) 0 var(--btn-shadow);
}
.dpad-btn:active { background: var(--btn-shadow); }

.dpad-up,
.dpad-down  { left: calc(18 * var(--u)); width: calc(18 * var(--u)); height: calc(19 * var(--u)); }
.dpad-up    { top: 0; border-radius: calc(3 * var(--u)) calc(3 * var(--u)) 0 0; }
.dpad-down  { top: calc(35 * var(--u)); border-radius: 0 0 calc(3 * var(--u)) calc(3 * var(--u)); }

.dpad-left,
.dpad-right { top: calc(18 * var(--u)); width: calc(19 * var(--u)); height: calc(18 * var(--u)); }
.dpad-left  { left: 0; border-radius: calc(3 * var(--u)) 0 0 calc(3 * var(--u)); }
.dpad-right { left: calc(35 * var(--u)); border-radius: 0 calc(3 * var(--u)) calc(3 * var(--u)) 0; }

.dpad-hub {
  position: absolute;
  left: calc(18 * var(--u));
  top: calc(18 * var(--u));
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
  background: var(--btn-face);
  pointer-events: none;
}
.dpad-hub::after {
  content: "";
  position: absolute;
  inset: calc(5 * var(--u));
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #4d4360, #2a2436);
}

/* A and B sit on the diagonal, B lower-left of A. */
.ab { position: absolute; right: 0; top: calc(2 * var(--u)); width: calc(74 * var(--u)); height: calc(54 * var(--u)); }

.face-btn {
  position: absolute;
  width: calc(28 * var(--u));
  height: calc(28 * var(--u));
  border-radius: 50%;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: radial-gradient(circle at 34% 28%, #6d4a86 0%, #472f5c 60%, #33204a 100%);
  box-shadow: 0 calc(2 * var(--u)) 0 rgba(0,0,0,0.45),
              inset 0 calc(1 * var(--u)) 0 rgba(255,255,255,0.28);
}
.face-btn:active { transform: translateY(calc(1 * var(--u))); box-shadow: 0 0 0 rgba(0,0,0,0.45); }
.face-btn span {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(-9 * var(--u));
  font-size: calc(6 * var(--u));
  color: #e3d3f2;
}
.btn-b { left: calc(2 * var(--u));  top: calc(20 * var(--u)); }
.btn-a { left: calc(40 * var(--u)); top: calc(6 * var(--u)); }

.startsel {
  position: absolute;
  left: 0; right: 0;
  top: calc(318 * var(--u));
  display: flex;
  justify-content: center;
  gap: calc(14 * var(--u));
  transform: rotate(-12deg);
}

.pill {
  position: relative;
  width: calc(36 * var(--u));
  height: calc(11 * var(--u));
  border-radius: calc(6 * var(--u));
  border: 0;
  cursor: pointer;
  background: linear-gradient(160deg, var(--btn-edge), var(--btn-face));
  box-shadow: 0 calc(1 * var(--u)) 0 var(--btn-shadow);
}
.pill:active { background: var(--btn-shadow); }
.pill span {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(-8 * var(--u));
  font-size: calc(4.4 * var(--u));
  color: #cbb8e0;
}

.speaker {
  position: absolute;
  right: calc(20 * var(--u));
  bottom: calc(14 * var(--u));
  width: calc(56 * var(--u));
  height: calc(34 * var(--u));
  transform: rotate(-27deg);
  background-image: radial-gradient(circle, rgba(15,10,24,0.75) 42%, transparent 44%);
  background-size: calc(7 * var(--u)) calc(7 * var(--u));
  opacity: 0.85;
}

/* ---- HUD ------------------------------------------------------------ */

#hud { display: flex; align-items: center; gap: 14px; }

#dev-toggle,
#editor-return {
  font: inherit;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: #e4eeeb;
  background: #27363d;
  border: 1px solid #627c80;
  border-radius: 3px;
  padding: 5px 12px;
  cursor: pointer;
  text-decoration: none;
}
#dev-toggle:hover,
#editor-return:hover { background: #354b52; }
#dev-toggle:focus-visible,
#editor-return:focus-visible { outline: 2px solid #a7e4d3; outline-offset: 3px; }

#hud-hint { color: #c1cbce; opacity: 0.85; }
#screen-zoom-readout { color: #a7e4d3; opacity: 1; }

/* ---- development console ------------------------------------------ */

#dev-panel {
  position: fixed;
  right: 18px;
  top: 18px;
  width: 290px;
  z-index: 20;
  padding: 12px;
  color: #e8ddf2;
  background: rgba(24, 18, 34, 0.97);
  border: 1px solid #745a91;
  border-radius: 5px;
  box-shadow: 0 12px 35px rgba(0,0,0,0.5);
  text-transform: none;
  letter-spacing: 0.02em;
}

.dev-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 9px;
  color: #f1c95b;
  text-transform: uppercase;
}

#dev-status {
  min-height: 35px;
  margin-bottom: 10px;
  color: #bdaecb;
  line-height: 1.45;
}

.dev-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px;
}

.dev-grid .dev-link,
.dev-grid button,
.dev-grid select,
#dev-close {
  min-width: 0;
  padding: 7px;
  color: #eee6f5;
  background: #392b4b;
  border: 1px solid #654d80;
  border-radius: 3px;
  font: inherit;
}

.dev-grid button,
.dev-grid .dev-link,
#dev-close { cursor: pointer; }

/* The editor link spans both columns and reads as the way out of the game,
   rather than as one more test action. */
.dev-grid .dev-link {
  grid-column: 1 / -1;
  text-align: center;
  text-decoration: none;
  background: #4a3566;
  border-color: #8a68b4;
}
.dev-grid .dev-link:hover { background: #5a4079; }
.dev-grid button:hover,
#dev-close:hover { background: #4a3761; }
#dev-npc { grid-column: 1 / -1; }

.dev-hint {
  margin-top: 10px;
  color: #7f708d;
  font-size: 9px;
  line-height: 1.4;
}

/* ---- screen zoom ----------------------------------------------------
 * The CSS fallback crops the magnified canvas inside its existing bezel. The
 * 3D shell keeps this source canvas hidden and performs the equivalent crop
 * while copying it into the model's screen texture. */

body.model-shell #screen { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .face-btn:active { transform: none; }
}
