/*
  ui.css — all page + UI styling.

  Phase 0: canvas fills the window.
  Phase 1: "click to look around" hint.
  Phase 3: crosshair + scope overlay.
  Phase 10: the real UI — HUD, floating damage text, main menu, options, end
            screen. (The Phase 8/9 placeholder banners are gone; HUD.js and
            Menus.js draw those numbers now.)

  TWO RULES THIS FILE LIVES BY — they are what keep the UI from eating the game:

  1. ⭐ `pointer-events: none` ON EVERYTHING THAT ISN'T A BUTTON. An overlay is a
     transparent sheet of glass over the canvas, and by default that glass
     catches every click — including the one meant to lock the pointer and the
     one meant to fire the rifle. The HUD, the crosshair, the scope, the damage
     text and the vignette all let clicks fall THROUGH to the canvas. Only the
     menus (and the debug panel) set `pointer-events: auto`, because only they
     have something to click. This is the #1 beginner bug in a DOM-overlay game:
     the gun stops firing and nothing in the JavaScript is wrong.

  2. Z-ORDER IS DELIBERATE, and it reads bottom-to-top like the game does:
        canvas → vignette → damage text (40) → toast (45) → HUD (46)
        → debug (50) → menus (60) → lock hint (70)
     A menu must sit above the HUD (it replaces it), and the lock hint above
     everything (it's what tells you why nothing is responding).
*/

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: #000;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  color: #eee;
}

#game-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* Arcade-style vignette: transparent center, darkened corners. */
#vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0) 55%,
    rgba(0, 0, 0, 0.38) 100%
  );
}

/* ---- "Click to look around" hint ------------------------------------- */
/* Shown ONLY while a hunt is running and the pointer is unlocked (Game decides).
   In a menu the cursor is supposed to be free, so the hint would be a lie. */
#lock-hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
  padding: 18px 26px;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  user-select: none;
  z-index: 70;
}
#lock-hint p { margin: 4px 0; font-size: 20px; letter-spacing: 0.5px; }
#lock-hint .small { font-size: 13px; opacity: 0.7; }
#lock-hint kbd {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  font-family: inherit;
}

/* ---- Crosshair (hip fire) -------------------------------------------- */
#crosshair {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;            /* never intercept clicks */
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.9));   /* readable over any color */
  z-index: 46;
}

/* ---- Scope overlay (aiming) ------------------------------------------ */
/* A big black ring with a clear circle in the middle = "looking through a
   scope". opacity is set from JavaScript (Player) as you zoom in. */
#scope {
  position: absolute;
  inset: 0;                        /* cover the whole screen */
  pointer-events: none;
  opacity: 0;                      /* Player fades this in while aiming */
  background: radial-gradient(
    circle at center,
    rgba(0, 0, 0, 0) 0,
    rgba(0, 0, 0, 0) 30%,
    rgba(0, 0, 0, 0.98) 40%,
    #000 100%
  );
  z-index: 47;
}

/* Thin cross-hair lines through the center of the scope. */
.scope-reticle::before,
.scope-reticle::after {
  content: "";
  position: absolute;
  background: rgba(0, 0, 0, 0.7);
}
.scope-reticle::before {           /* vertical line */
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  transform: translateX(-50%);
}
.scope-reticle::after {            /* horizontal line */
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  transform: translateY(-50%);
}

/* Scope magnification readout. Shown only through a variable optic (Player). */
#zoom {
  position: absolute;
  bottom: 68px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 16px;
  letter-spacing: 1.5px;
  padding: 4px 14px;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  pointer-events: none;
  user-select: none;
  font-variant-numeric: tabular-nums;   /* stops 5.5x -> 6.0x jittering the box */
  z-index: 46;
}

/* ================= THE HUD (Phase 10) ==================================
   Four corners, written by src/ui/HUD.js. The whole thing is inert: it reports,
   it never receives. Hidden entirely outside a hunt. */
#hud {
  position: absolute;
  inset: 0;
  pointer-events: none;            /* rule 1 — clicks fall through to the game */
  user-select: none;
  z-index: 46;
  font-variant-numeric: tabular-nums;   /* digits keep their width; nothing jitters */
}

.hud-corner {
  position: absolute;
  padding: 6px 14px;
  background: rgba(0, 0, 0, 0.38);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  line-height: 1.45;
}
.hud-tl { top: 18px; left: 18px; }
.hud-tr { top: 18px; right: 18px; text-align: right; }
.hud-bl { bottom: 22px; left: 18px; }
.hud-br { bottom: 22px; right: 18px; }

/* Keep the HUD sparse: the scope and the animal are the stars (02_Wireframes). */
#hud-round,
#hud-score {
  font-size: 16px;
  letter-spacing: 2px;
}

#hud-species {
  font-size: 13px;
  letter-spacing: 1.5px;
  opacity: 0.72;
  text-transform: uppercase;
  min-height: 1.45em;              /* reserve the line so the box never resizes */
}
/* The wounded cue: this animal is bleeding, and a follow-up shot is worth
   taking. Red because it's blood, and because it's a clock ticking. */
#hud-species.wounded {
  color: #e98d8d;
  opacity: 1;
}

#hud-streak {
  font-size: 13px;
  letter-spacing: 1.5px;
  color: #cfe9b0;                  /* green = earned, banked, yours */
}

/* ⭐ The escrow pot (Scoring.js). Amber = at stake, not yet earned. It sits on
   screen the entire time it is at risk, and if the animal escapes you watch it
   go. A rule the player cannot see is a rule they will report as a bug. */
#hud-risk {
  font-size: 13px;
  letter-spacing: 1px;
  color: #e8c07a;
}

/* The magazine: ● loaded, ○ spent. */
#hud-ammo {
  font-size: 20px;
  letter-spacing: 6px;
  color: #f0e6d2;
}

#hud-reload {
  font-size: 14px;
  letter-spacing: 2px;
  color: #e8c07a;
}
#hud-reload.urgent {
  color: #e9b0b0;                  /* empty, not merely reloading */
  animation: pulse 1s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* The outcome toast: "Deer down.  +150" / "It got away.  −80". Sits above the
   crosshair so it never covers the shot you're lining up. */
#round-toast {
  position: absolute;
  top: 34%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 26px;
  letter-spacing: 1px;
  padding: 8px 22px;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  user-select: none;
  animation: toast-in 180ms ease-out;
  z-index: 45;
}

#round-toast.good { color: #cfe9b0; }   /* a kill  */
#round-toast.bad  { color: #e9b0b0; }   /* it escaped — AI-3: this must STING */

@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ---- Floating damage text (Phase 10) ---------------------------------
   One .dmg-text per hit, created and positioned by src/ui/DamageText.js. The
   element is placed with `transform: translate(Xpx, Ypx)` from the hit point's
   projected screen position — so `left/top` stay at 0 and the transform does all
   the work (transforms don't trigger a page layout; left/top do). */
#damage-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 40;
}

.dmg-text {
  position: absolute;
  top: 0;
  left: 0;
  white-space: nowrap;
  font-weight: 700;
  letter-spacing: 1px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85);
  will-change: transform, opacity;
}

/* Colour-coded by what the shot was worth (02_Wireframes.md, Screen 3). */
.dmg-vital {
  font-size: 26px;
  color: #ffd479;                  /* gold — brain / heart / lungs */
}
.dmg-hit {
  font-size: 19px;
  color: #f2f2f2;                  /* white — a hit that isn't vital */
}
.dmg-miss {
  font-size: 16px;
  color: #9aa0a6;                  /* grey — including a bullet into a tree */
  font-weight: 600;
}

/* ================= MENUS (Phase 10) ====================================
   Main menu / options / end screen / goodbye. Exactly one is visible at a time
   (Menus.js enforces that). These are the ONLY overlay elements that accept
   clicks — everything else is pointer-events: none. */
.menu {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 340px;
  max-width: min(520px, 90vw);
  max-height: 90vh;
  overflow-y: auto;
  padding: 30px 36px;
  background: rgba(8, 12, 10, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(3px);
  text-align: center;
  user-select: none;
  pointer-events: auto;            /* the exception to rule 1 — see the header */
  z-index: 60;
}

.menu-title {
  margin: 0;
  font-size: 40px;
  font-weight: 600;
  letter-spacing: 10px;            /* the condensed, spaced-out title of the sketch */
  text-transform: uppercase;
  text-indent: 10px;               /* letter-spacing pads the right side only */
}
.menu-title.small {
  font-size: 24px;
  letter-spacing: 4px;
  text-indent: 4px;
}

.menu-sub {
  margin: 6px 0 24px;
  font-size: 14px;
  letter-spacing: 4px;
  text-transform: uppercase;
  opacity: 0.55;
}

.menu-buttons {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 20px 0 0;
}
.menu-buttons.row { flex-direction: row; justify-content: center; }

.menu-btn {
  padding: 12px 22px;
  font: inherit;
  font-size: 15px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #e8ecdf;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease, border-color 120ms ease;
}
.menu-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(255, 255, 255, 0.35);
}
.menu-btn:active { transform: translateY(1px); }   /* it presses IN — cheap, and it sells */

/* The one you're meant to press. Muted forest green, per the style direction. */
.menu-btn.primary {
  background: rgba(120, 160, 96, 0.28);
  border-color: rgba(160, 200, 130, 0.5);
  color: #ecf3e2;
}
.menu-btn.primary:hover { background: rgba(140, 185, 110, 0.42); }

.menu-blurb {
  margin: 22px 0 0;
  font-size: 13px;
  line-height: 1.6;
  opacity: 0.6;
}
.menu-foot {
  margin: 18px 0 0;
  font-size: 11px;
  letter-spacing: 1px;
  opacity: 0.35;
}

/* ---- Options rows ----------------------------------------------------- */
.opt-row {
  display: grid;
  grid-template-columns: 1fr 150px 56px;   /* label | control | value */
  align-items: center;
  gap: 14px;
  margin: 16px 0;
  text-align: left;
  font-size: 14px;
}
.opt-row label { opacity: 0.8; }
.opt-row input[type="range"] { width: 100%; cursor: pointer; accent-color: #8cb96e; }
.opt-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: #8cb96e;
  justify-self: start;
}
.opt-val {
  text-align: right;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

/* ---- End screen ------------------------------------------------------- */
/* The headline number, then the 5 rounds, then the shooting stats. */
#end-score {
  margin: 10px 0 18px;
  font-size: 46px;
  letter-spacing: 2px;
  font-variant-numeric: tabular-nums;
}

/* ---- High score (Phase 12) ------------------------------------------- */
/* Gold, and gold is already spoken for in this game: it's the colour of a vital
   hit (see .dt-vital above). Reusing it here is deliberate — gold means "the best
   thing that can happen" everywhere it appears, so the badge reads instantly. */
.end-record {
  margin: 12px 0 -4px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: #ffd479;
  animation: record-in 420ms ease-out;
}
.end-record .er-prev {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 1px;
  text-transform: none;
  opacity: 0.65;
}
@keyframes record-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

/* The target, on the main menu. Quiet on purpose: it's a number to beat, not an
   announcement — the loudest thing on that screen stays the Start button. */
.menu-best {
  margin: -14px 0 20px;
  font-size: 13px;
  letter-spacing: 1px;
  color: #ffd479;
  opacity: 0.75;
}
.menu-best strong {
  font-variant-numeric: tabular-nums;
}

.end-rounds {
  list-style: none;
  margin: 0;
  padding: 0;
  font-variant-numeric: tabular-nums;
}
.end-rounds li {
  display: grid;
  grid-template-columns: 24px 1fr auto 62px;   /* round | species | outcome | score */
  gap: 12px;
  align-items: center;
  padding: 6px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 15px;
}
.er-round { opacity: 0.5; }
.er-species { text-align: left; }
.er-outcome.good { color: #cfe9b0; }
.er-outcome.bad  { color: #e9b0b0; }

/* Per-round points. A forfeited round shows what it COST you (−80), not a bare
   0 — AI-3's whole point is that an escape has a price and you can see it. */
.er-score { text-align: right; }
.er-score.good { color: #cfe9b0; }
.er-score.bad  { color: #e9b0b0; opacity: 0.75; }

.end-stats {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  font-variant-numeric: tabular-nums;
}
.end-stats li {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: 4px 0;
  font-size: 14px;
}
.es-key { opacity: 0.55; }
.es-val { text-transform: capitalize; }

/* ---- Debug panel (toggle with the ` key) ---------------------------- */
/* A dev-only overlay: live toggles/sliders/buttons so we stop editing code
   constants and refreshing. pointer-events: auto so we can actually click it. */
#debug-panel {
  position: absolute;
  top: 12px;
  left: 12px;
  width: 260px;
  max-height: 92vh;
  overflow-y: auto;
  padding: 12px 14px;
  background: rgba(10, 12, 16, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  font-size: 13px;
  color: #eee;
  pointer-events: auto;
  user-select: none;
  z-index: 50;
}
#debug-panel h2 {
  margin: 0 0 6px;
  font-size: 15px;
  letter-spacing: 1px;
  display: flex;
  align-items: center;
  gap: 8px;
}
#debug-panel .dp-key {
  font-size: 12px;
  opacity: 0.6;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 4px;
  padding: 0 5px;
}
#debug-panel .dp-hint {
  margin: 0 0 10px;
  font-size: 11px;
  opacity: 0.6;
  line-height: 1.4;
}
#debug-panel .dp-hint kbd {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: inherit;
}
#debug-panel fieldset {
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  margin: 0 0 10px;
  padding: 8px 10px;
}
#debug-panel legend {
  padding: 0 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  opacity: 0.7;
}
#debug-panel .dp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 5px 0;
  cursor: default;
}
/* Nested category toggles (the skeleton's deform / IK / pole rows). Indented
   under their master checkbox, and dimmed + disabled while the master is off. */
#debug-panel .dp-nest {
  margin: 2px 0 6px 22px;
  padding-left: 8px;
  border-left: 1px solid rgba(255, 255, 255, 0.12);
}
#debug-panel .dp-nest.dp-disabled { opacity: 0.4; }
/* Colour legend for each bone category — matches BONE_CATEGORY_COLORS. */
#debug-panel .dp-swatch {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}
#debug-panel .dp-name { flex: 1; }
#debug-panel .dp-label { flex: 0 0 auto; }
#debug-panel .dp-slider input[type="range"] { flex: 1; min-width: 0; }
#debug-panel .dp-val {
  flex: 0 0 34px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  opacity: 0.8;
}
#debug-panel input[type="checkbox"] {
  width: 15px;
  height: 15px;
  cursor: pointer;
}
#debug-panel .dp-btns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
#debug-panel button {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #eee;
  border-radius: 6px;
  padding: 6px 4px;
  font: inherit;
  cursor: pointer;
}
#debug-panel button:hover { background: rgba(255, 255, 255, 0.16); }

/* ---- Debug shot readout (top-right; Debug panel #7) ------------------ */
/* Sits under the HUD's top-right corner so the two don't overlap. */
#debug-shot-info {
  position: absolute;
  top: 92px;
  right: 12px;
  max-width: 320px;
  padding: 6px 12px;
  background: rgba(10, 12, 16, 0.85);
  border: 1px solid rgba(54, 224, 255, 0.4);
  border-radius: 8px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  color: #cfeffd;
  pointer-events: none;
  user-select: none;
  z-index: 50;
}

/* ---- Frame-cost meter (bottom-left; Debug panel #11) ------------------ */
/* Bottom-left is deliberate: it must not sit under the crosshair, the HUD, or
   the shot readout — you read it WHILE aiming and firing, and an instrument you
   have to look away from is an instrument you won't use. `pointer-events: none`
   like every other overlay: an overlay that eats the click meant to fire the
   rifle is THE beginner bug of a DOM-overlay game. */
#debug-stats {
  position: absolute;
  bottom: 12px;
  left: 12px;
  padding: 6px 12px;
  background: rgba(10, 12, 16, 0.85);
  border: 1px solid rgba(54, 224, 255, 0.4);
  border-radius: 8px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre;          /* Stats.js writes two lines with a \n */
  color: #9de7a4;            /* Stats.js recolours this: green = good, amber = not */
  pointer-events: none;
  user-select: none;
  z-index: 50;
}

/* ---- Alertness meters (Debug panel #10, AI-2) ------------------------
   One of these floats over each living animal. AlertnessHelper.js sets `left`
   and `top` every frame from the animal's projected head position, so the
   element must be positioned ABSOLUTELY inside a full-screen layer.

   The translate(-50%, -100%) is what makes those two numbers mean "the point
   above the animal's head": without it, `left`/`top` would place the box's
   top-left corner there, hanging the label down and to the right of the animal
   instead of centred above it. */
#debug-alert-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;   /* never eat a click meant for the game */
  z-index: 40;
}
#debug-alert-layer .dbg-alert {
  position: absolute;
  transform: translate(-50%, -100%);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 6px;
  width: 132px;
  padding: 4px 7px 5px;
  background: rgba(10, 12, 16, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 10px;
  letter-spacing: 0.5px;
  user-select: none;
}
#debug-alert-layer .dbg-alert-state { font-weight: 700; }
#debug-alert-layer .dbg-alert-num {
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}
#debug-alert-layer .dbg-alert-bar {
  grid-column: 1 / -1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
#debug-alert-layer .dbg-alert-bar > i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 2px;
}

/* Generic "hide this element" helper toggled from JavaScript. */
.hidden { display: none !important; }
