/* Meta Ray-Ban Display: 600×600 viewport, additive waveguide.
   Dark background, high-contrast UI. Min font-size 16px for body text.
   See AUDIT.md for the full spec compliance checklist. */

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Hide the system cursor ONLY while inside an immersive XR session.
   Outside XR (windowed view, desktop dev, mobile) the native cursor
   stays available. main.js toggles `body.xr-active` on session
   start / end. */
body.xr-active,
body.xr-active *,
body.xr-active *::before,
body.xr-active *::after {
  cursor: none !important;
}

/* Hard kill image smoothing on every <img>, <canvas>, <svg>. Sometimes the
   body-level image-rendering doesn't cascade through inserted elements on
   iOS Safari, so we set it explicitly with three browser-vendor fallbacks. */
img, canvas, svg, video {
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
  -ms-interpolation-mode: nearest-neighbor;
}

/* PAGE UNDERLAY ONLY is pure #000 — on the glasses' additive waveguide that
   means the canvas/page background is fully transparent so the real world
   shows through where no game pixel covers it. Other UI surfaces still use
   the lifted #1a1a1a / #333 dark grays so they render visibly. */
html {
  background: #000000;
  min-height: 100vh;
  width: 100%;
  overflow: hidden;
}

html, body {
  width: 600px;
  height: 600px;
  overflow: hidden;
  background: #000000;
  color: #fff;
  font-family: 'Press Start 2P', 'Courier New', monospace;
  font-weight: bold;                 /* makes the fallback monospace heavier */
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  -ms-interpolation-mode: nearest-neighbor;
  user-select: none;
  -webkit-user-select: none;

  /* Prevent iOS rubber-band scroll / pinch-zoom / accidental tap-zoom. */
  touch-action: none;
  -webkit-touch-callout: none;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}

/* Phone: center the 600×600 stage in whatever space the device gives us. */
@media (max-width: 599px), (max-height: 599px) {
  html { display: flex; align-items: center; justify-content: center; }
  body { margin: 0 auto; }
}

#stage {
  position: relative;
  width: 600px;
  height: 600px;
}

#scene {
  position: absolute;
  inset: 0;
  width: 600px;
  height: 600px;
  display: block;
  z-index: 1;
}

/* ─── 2D ducks layer (between background and HUD) ───────── */
#ducks-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 5;
}
.duck-sprite {
  position: absolute;
  top: 0; left: 0;
  image-rendering: pixelated;
  /* No `will-change`: with 10 sprites it forced 10 dedicated GPU layers
     (~2–4 MB VRAM) even when most are off-screen. translate3d + opacity
     already get compositor promotion when actually animated. */
  /* Start hidden + far off-screen until the first _project() call places
     the sprite — prevents the one-frame flash at (0,0) on spawn. */
  opacity: 0;
  transform: translate3d(-9999px, -9999px, 0);
  transition: opacity 60ms linear;
}

/* ─── Off-screen duck indicators ────────────────────────── */
#duck-indicators {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 6;
}
/* Pixel-art chevron rendered with box-shadow grid (each shadow = 1 NES pixel).
   Base block is a 3px square; shadows stamp it across a 21×16 grid forming a
   chunky upward-pointing arrow. Rotates around its visual center to face duck.
   `--arrow-color` is driven from Game._updateArrows() so the arrow ramps from
   white → red as the duck's pair-timer drains. */
.duck-arrow {
  position: absolute;
  left: 0; top: 0;
  width: 3px;
  height: 3px;
  background: transparent;
  --arrow-color: #ffffff;
  color: var(--arrow-color);
  /* Pixel grid (3px units). Shape is a stepped triangle pointing UP:
     row0:                  ▓ ▓ ▓ ▓ ▓
     row1:               ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓
     row2:            ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓
     row3:                  ▓ ▓ ▓ ▓ ▓     (tail) */
  box-shadow:
    /* row 0 — tip */
       9px  0 0 currentColor, 12px  0 0 currentColor, 15px  0 0 currentColor,
    /* row 1 */
       6px  3px 0 currentColor,  9px  3px 0 currentColor, 12px  3px 0 currentColor, 15px  3px 0 currentColor, 18px  3px 0 currentColor,
    /* row 2 */
       3px  6px 0 currentColor,  6px  6px 0 currentColor,  9px  6px 0 currentColor, 12px  6px 0 currentColor, 15px  6px 0 currentColor, 18px  6px 0 currentColor, 21px  6px 0 currentColor,
    /* row 3 — wide base */
       0     9px 0 currentColor,  3px  9px 0 currentColor,  6px  9px 0 currentColor,  9px  9px 0 currentColor, 12px  9px 0 currentColor, 15px  9px 0 currentColor, 18px  9px 0 currentColor, 21px  9px 0 currentColor, 24px  9px 0 currentColor,
    /* row 4 — tail core */
       9px 12px 0 currentColor, 12px 12px 0 currentColor, 15px 12px 0 currentColor,
    /* row 5 — tail end */
       9px 15px 0 currentColor, 12px 15px 0 currentColor, 15px 15px 0 currentColor;
  opacity: 0;
  /* Rotate around the visual center of the chevron (12px right, 9px down) */
  transform-origin: 13.5px 10.5px;
  /* will-change removed: only 2 arrows live, so the GPU-layer win is
     marginal vs the always-on VRAM cost. The transition below still
     animates smoothly without a hint. */
  transition: opacity 100ms linear, color 80ms linear;
}
.duck-arrow.show { opacity: 1; }

/* NES duck colors via CSS filter on the same base sprite.
   "black" = natural sprite tone (the default duck) — no filter.
   "blue" / "red" rotate hue to mark them as the higher-value variants. */
/* Color variants handled by per-pixel canvas tinting in Duck.js
   (TINT_COLORS → topmost-blob head mask only). DO NOT add hue-rotate
   or filter rules here — they bypass the head mask and recolour the
   whole sprite, including beak/feet/coral body. */

/* HUD floats OVER the playfield as a free-standing framed bar. Chips sit
   at the bottom; the row hugs its content rather than stretching — the
   mockup shows a tightly-fit HIT bar (no padding stretching). */
#hud {
  position: absolute;
  bottom: 14px;
  left: 0;
  right: 0;
  z-index: 10;
  pointer-events: none;
  background: transparent;
  border: none;
  display: flex;
  justify-content: center;
}
.hud-strip {
  display: flex;
  align-items: stretch;
  gap: 14px;
}
/* Lime-framed chip with chamfered corners — matches the NES status-bar
   look where the corner pixels are diagonally cut off (border-radius:3px
   on a 2px border is the closest CSS analogue). Soft outer shadow gives
   the slight glow you see in the mockup. */
.hud-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 9px 15px;             /* old padding + 3 px to match border width */
  background: #666666;
  /* Crisp pixel border via inset box-shadow — thinner (3 px) for the bottom
     chips so they don't dominate visually. R= chip on top stays heavier. */
  box-shadow: inset 0 0 0 3px #7fdb3a;
  border: 0;
  border-radius: 0;
  min-width: 0;
}
.hud-section.hud-shot  .hud-label { color: #3a8eff; }   /* NES blue */
.hud-section.hud-hit   .hud-label { color: #7fdb3a; }   /* lime */
.hud-section.hud-score .hud-label { color: #ffffff; }   /* white */

/* HIT chip: HIT label on LEFT, duck row on RIGHT. Width hugs the content
   (label + 10 ducks) — no flex-grow. */
.hud-section.hud-hit {
  flex-direction: row;
  align-items: center;
  gap: 10px;
  justify-content: flex-start;
  padding: 6px 12px;
}

/* SHOT chip: stack shells over the label tightly. */
.hud-section.hud-shot {
  padding: 4px 8px;
}
.hud-section.hud-shot .hud-section-body {
  display: flex;
  gap: 4px;
  align-items: flex-end;
}

/* SCORE chip: 6-digit score above the label. */
.hud-section.hud-score {
  padding: 4px 8px;
  gap: 3px;
}

/* Round indicator: free-standing chip at the TOP-LEFT of the playfield,
   "R =" label + 2-digit round number. */
#hud-round-box {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;            /* old + 3 px to replace border thickness */
  background: #666666;
  /* Same crisp pixel border style as .hud-section — 3 px inset, no radius. */
  box-shadow: inset 0 0 0 3px #7fdb3a;
  border: 0;
  border-radius: 0;
  z-index: 11;
}
#hud-round-box .hud-label {
  color: #7fdb3a;
  font-size: 12px;
}
/* No text-shadow halos — Press Start 2P renders crisp pixel edges natively
   and the dark fringes were the "black outline on text" the user flagged. */
.hud-label {
  font-size: 10px;
  font-weight: bold;
  letter-spacing: 1px;
  color: #ffffff;
}
/* Per-section label colours mirroring the NES status-bar: SHOT blue,
   HIT lime, SCORE white. */
/* (per-label colours moved into the .hud-section block above) */

#hud-score {
  font-size: 18px;
  font-weight: bold;
  letter-spacing: 2px;
  color: #ffe14a;
}
#hud-round {
  font-size: 14px;
  font-weight: bold;
  letter-spacing: 2px;
  color: #ffe14a;
}
#hud-ammo { display: flex; gap: 4px; align-items: center; }
/* CSS-drawn shell — the original NES shot0-shot5 PNGs are solid-black
   silhouettes that disappear on the dim glasses background, so we
   replace them with a visible yellow bullet shape. */
/* NES shell — matches the mockup: simple yellow vertical bar with a
   single black "!" pixel-mark in the middle column. No cap, no border. */
.shell {
  position: relative;
  display: inline-block;
  width: 6px;
  height: 18px;
  background: #ffe14a;
  border-radius: 0;
}
.shell::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 2px;
  width: 2px;
  height: 8px;
  background: #1a1a1a;                /* "!" body */
}
.shell.spent {
  opacity: 0.22;
  background: #555;
}
.shell.spent::after { background: #2a2a2a; }

/* Slim timer strip just above the framed bottom-strip boxes. */
#hud-timer {
  position: absolute;
  bottom: 56px;
  left: 8px;
  right: 8px;
  height: 2px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}
#hud-timer-bar {
  width: 100%;
  height: 100%;
  background: #30d040;
  transition: width 0.1s linear, background 0.2s ease;
}

/* ─── Crosshair: classic 4-arm pixel "+" with hollow centre ─ */
#crosshair {
  position: absolute;
  top: 50%; left: 50%;
  pointer-events: none;
  z-index: 20;
  transition: opacity 30ms ease-out;
  width: 0; height: 0;            /* zero-size anchor for arms */
}
#crosshair.hidden { opacity: 0; }
/* White pixel arms, 2 px thick × 6 px long, offset 4 px from centre. */
#crosshair .arm { position: absolute; background: #ffffff; }
#crosshair .arm-t { width: 2px; height: 6px; top: -10px; left: -1px; }
#crosshair .arm-b { width: 2px; height: 6px; top:   4px; left: -1px; }
#crosshair .arm-l { width: 6px; height: 2px; top:  -1px; left: -10px; }
#crosshair .arm-r { width: 6px; height: 2px; top:  -1px; left:   4px; }

/* ─── Muzzle flash overlay ──────────────────────────────── */
#flash {
  position: absolute; inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  z-index: 15;
  transition: opacity 60ms ease-out;
}
#flash.fire { opacity: 0.35; transition: none; }

/* NES-style white shot square at the crosshair on fire — the original
   Duck Hunt drew a 16×16 white square wherever the light-gun was pointing
   when you pulled the trigger. Replicates that "hit marker" beat. */
#shot-square {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 16px;
  height: 16px;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
  z-index: 19;
  /* No box-shadow outline — pure white pixel block, matches the NES light
     gun hit indicator (just a plain white square, no dark border). */
}
#shot-square.fire {
  animation: shotSquare 90ms steps(1, end);
}
@keyframes shotSquare {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

/* ─── "FLY AWAY!" pair-spawn cue ────────────────────────── */
#fly-away {
  position: absolute;
  top: 30%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
  font-size: 40px;
  letter-spacing: 4px;
  color: #ff3030;
  /* No text-shadow — clean pixel font edges, no dark drop-shadow halo. */
  opacity: 0;
  pointer-events: none;
  z-index: 18;
}
#fly-away.show {
  animation: flyAwayPulse 1.3s ease-out;
}

/* ─── Floating score popup near crosshair on hit ────────── */
#score-pop {
  position: absolute;
  top: 44%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 22px;
  letter-spacing: 2px;
  color: #ffe14a;
  /* No text-shadow — clean pixel-font edges only. */
  opacity: 0;
  pointer-events: none;
  z-index: 17;
}
#score-pop.show {
  animation: scorePop 0.9s ease-out;
}
@keyframes scorePop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  25%  { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  100% { opacity: 0; transform: translate(-50%, -90%) scale(1); }
}
@keyframes flyAwayPulse {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  18%  { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  30%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  80%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.05); }
}

/* Dog is rendered as a 3D Three.js Sprite — see src/Dog.js. No DOM/CSS needed. */

/* Duck-progress bar sits inside the .hud-hit section. Pass-line is an
   absolutely-positioned vertical white tick INSIDE #duck-bar that shows
   the minimum-required-hits threshold for the current round. */
.hud-hit { position: relative; }
#duck-bar {
  display: flex;
  gap: 2px;
  position: relative;
}
#duck-bar .duck-slot {
  width: 14px;
  height: 18px;
  image-rendering: pixelated;
}
/* Pass-line (white tick marking the minimum-hits threshold) is hidden by
   default — not in the NES mockup. Toggle via .pass-line.visible if it
   ever needs to come back as a difficulty cue. */
#duck-bar .pass-line {
  display: none;
}
#duck-bar:empty { display: none; }

/* ─── Overlay screens (start, round-end, game-over) ─────── */
#overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(26, 26, 26, 0.78);
  z-index: 30;
  text-align: center;
}
#overlay[hidden] { display: none; }
.overlay-card {
  padding: 33px 41px;
  box-shadow: inset 0 0 0 5px #ffe14a;
  border: 0;
  border-radius: 0;
  background: #666666;
  min-width: 360px;
}
.overlay-card h1 {
  font-size: 28px;
  font-weight: bold;
  letter-spacing: 3px;
  margin-bottom: 16px;
  color: #ffe14a;
  /* 4-direction halo thickens each pixel glyph by 1 px in every direction. */
  text-shadow:
    1px 0 #ffe14a, -1px 0 #ffe14a, 0 1px #ffe14a, 0 -1px #ffe14a;
}
.overlay-card h1 span { color: #ff3030; }
.overlay-card .sub {
  font-size: 16px;
  letter-spacing: 1px;
  color: rgba(255,255,255,0.75);
  margin-top: 12px;
}
.overlay-card .sub-tiny {
  font-size: 12px;
  letter-spacing: 1px;
  color: rgba(255,255,255,0.5);
  margin-top: 12px;
}
.overlay-card .big {
  font-size: 18px;
  font-weight: bold;
  color: #00d4ff;
  margin: 8px 0;
  letter-spacing: 2px;
  text-shadow:
    1px 0 currentColor, -1px 0 currentColor, 0 1px currentColor, 0 -1px currentColor;
}

/* Controls table on start screen — preserves NES yellow + dark style.
   Two-column grid (key | action). `.ctrl-row` uses display:contents so the
   inner spans become direct grid items in the parent. */
.controls-table {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 18px;
  row-gap: 10px;
  margin: 18px auto;
  font-size: 16px;
  max-width: 320px;
  text-align: left;
}
.controls-table .ctrl-row {
  display: contents;
}
.controls-table .key {
  color: #ffe14a;
  text-shadow: 0 0 4px rgba(255, 225, 74, 0.4);
  letter-spacing: 2px;
  white-space: nowrap;
  text-align: right;
}
.controls-table .act {
  color: rgba(255, 255, 255, 0.85);
  letter-spacing: 1px;
}

/* Secondary action hint that sits BELOW the primary autofocus button —
   used on round-end and game-over to advertise the BACK gesture. */
.overlay-card .secondary-hint {
  font-size: 12px;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 10px;
}

/* Tagline directly under the title — sells the 360° concept in one line. */
.overlay-card .tagline {
  font-size: 14px;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: 18px;
}

/* Feature list — explains what's unique about our 360° version.
   Plain block layout so wrapped text aligns under the first character,
   not under the bullet (avoids the staircase effect). */
.overlay-card .feature-list {
  list-style: none;
  padding: 0;
  margin: 0 auto 20px;
  max-width: 480px;
  text-align: left;
}
.overlay-card .feature-list li {
  font-size: 15px;
  font-weight: bold;
  line-height: 1.8;
  letter-spacing: 1.5px;
  color: #ffffff;
  padding: 5px 0 5px 26px;
  text-indent: -26px;
}
.overlay-card .feature-list .bullet {
  color: #ffe14a;
  display: inline-block;
  width: 18px;
  margin-right: 8px;
}
.overlay-card .feature-list em {
  color: #ffe14a;
  font-style: normal;
}

/* ─── Focusable button — Meta-spec compliant ────────────── */
.focusable {
  display: inline-block;
  background: #666666;
  color: #fff;
  font: inherit;
  font-weight: bold;
  letter-spacing: 2px;
  padding: 23px 33px;          /* original 18/28 + 5 px to replace border width */
  margin: 12px 0;
  min-height: 88px;            /* Meta spec: minimum tap target */
  min-width: 240px;
  font-size: 16px;
  box-shadow: inset 0 0 0 5px currentColor;
  border: 0;
  border-radius: 0;
  transition: color 150ms ease, box-shadow 150ms ease;
  cursor: pointer;
}
.focusable:focus {
  outline: none;
  color: #00d4ff;                     /* border + text shift to cyan on focus */
}
.hint-btn {
  color: #ffe14a;
  border-color: rgba(255, 225, 74, 0.3);
  animation: blink 1.2s infinite;
}
.hint-btn:focus {
  color: #fff;
  animation: none;
}

@keyframes blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0.55; }
}
