/* Structure, not style. Every rule here is about WHERE something sits and how big it is; every
   colour, font and border is a custom property a preset's theme.css defines.

   The split matters because the element ids are a contract (game.js and the tests address them
   by id, see PROTOCOL.md) while their appearance is the first thing a new game changes. Put
   both in one file and reskinning means editing around the layout and breaking it; split them
   and a theme is a list of colours.

   A preset that wants to move things, not just recolour them, overrides these rules in its own
   theme.css — it loads second and wins. */

html, body {
  margin: 0; padding: 0; overflow: hidden; height: 100%;
  background: var(--bg);
  touch-action: none; overscroll-behavior: none; -webkit-user-select: none;
}
canvas { display: block; }

#ui {
  position: fixed; inset: 0; pointer-events: none;
  font-family: var(--font); color: var(--fg); user-select: none;
}

/* ---- reticle ---- */
#crosshair {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 20px; height: 20px;
}
#crosshair::before, #crosshair::after { content: ''; position: absolute; background: var(--crosshair); }
#crosshair::before { left: 9px; top: 0; width: 2px; height: 20px; }
#crosshair::after { top: 9px; left: 0; width: 20px; height: 2px; }

/* X over the crosshair, shown only when a shot actually connects */
#hitmarker {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 28px; height: 28px; opacity: 0; transition: opacity .12s;
}
#hitmarker::before, #hitmarker::after {
  content: ''; position: absolute; left: 13px; top: 0; width: 2px; height: 28px;
  background: var(--hitmarker); box-shadow: 0 0 3px #000;
}
#hitmarker::before { transform: rotate(45deg); }
#hitmarker::after { transform: rotate(-45deg); }
#hitmarker.kill::before, #hitmarker.kill::after { background: var(--hitmarker-kill); }

/* ---- health ---- */
#healthWrap { position: absolute; left: 20px; bottom: 20px; width: 220px; }
#healthBar {
  width: 100%; height: 22px; overflow: hidden;
  background: var(--hp-bg); border: 2px solid var(--hp-border); border-radius: var(--hp-radius);
}
#healthFill { height: 100%; width: 100%; background: var(--hp-fill); transition: width .15s; }
#healthLabel { font-size: 12px; margin-bottom: 4px; letter-spacing: 1px; opacity: 0.8; }

/* ---- weapon / ammo ---- */
#ammo { position: absolute; right: 20px; bottom: 20px; font-size: 16px; text-shadow: 0 0 4px #000; opacity: 0.85; }
#weaponWrap { position: absolute; right: 20px; bottom: 44px; text-align: right; text-shadow: 0 1px 3px #000; }
#weaponName { font-size: 17px; font-weight: bold; letter-spacing: 2px; color: var(--weapon-fg); }

/* ---- transient centre message ---- */
#banner {
  position: absolute; top: 22%; left: 50%; transform: translateX(-50%);
  font-size: 34px; font-weight: bold; letter-spacing: 3px; white-space: nowrap;
  text-shadow: 0 2px 8px #000; opacity: 0; transition: opacity .35s;
  /* Above the death overlay. The overlay is a full-screen translucent wash that comes later in
     the DOM, so without this it paints over the banner and the most important message on
     screen — GAME OVER — renders dimmed to near-unreadable at the exact moment it matters. */
  z-index: 3;
}

#killfeed {
  position: absolute; top: 16px; right: 16px; text-align: right; font-size: 13px; line-height: 1.6;
  text-shadow: 0 1px 2px #000;
}
#killfeed div { opacity: 0.95; }

#status { position: absolute; top: 16px; left: 16px; font-size: 12px; opacity: 0.7; }

/* Preset-owned HUD corner. The engine creates the element and never writes to it; a preset's
   client.js fills it via hudHtml(). Empty and invisible for a preset that has no extra HUD. */
#presetHud {
  position: absolute; top: 50px; left: 16px; font-size: 13px; line-height: 1.5;
  text-shadow: 0 1px 3px #000;
}

/* Contextual "hold E to..." line, just under the crosshair where the eye already is. */
#prompt {
  position: absolute; top: 56%; left: 50%; transform: translateX(-50%);
  font-size: 14px; letter-spacing: 1px; text-align: center; white-space: nowrap;
  text-shadow: 0 1px 4px #000; opacity: 0; transition: opacity .12s;
}
#prompt.show { opacity: 0.95; }

/* ---- scoreboard ---- */
#scoreboard {
  position: absolute; top: 60px; left: 50%; transform: translateX(-50%);
  background: var(--panel-bg); border: 1px solid var(--panel-border); padding: 10px 16px;
  display: none; min-width: 260px;
}
#scoreboard h3 { margin: 0 0 8px; font-size: 14px; text-align: center; opacity: 0.85; }
#scoreboard table { width: 100%; border-collapse: collapse; font-size: 13px; }
#scoreboard td, #scoreboard th { padding: 2px 8px; text-align: left; }
#scoreboard th { border-bottom: 1px solid var(--panel-rule); }

/* ---- death overlay ---- */
#overlay {
  position: absolute; inset: 0; display: none; align-items: center; justify-content: center;
  flex-direction: column; background: var(--overlay-bg); text-align: center;
  z-index: 1;   /* under #banner — see the note there */
}
#overlay h1 { color: var(--danger); font-size: 48px; margin: 0 0 10px; }
#overlay p { font-size: 18px; }

/* ---- login ---- */
#login {
  position: fixed; inset: 0; background: var(--login-bg); display: flex;
  align-items: center; justify-content: center; flex-direction: column;
  color: var(--fg); font-family: var(--font); z-index: 10;
}
#login h1 { font-size: 38px; letter-spacing: 4px; color: var(--title-fg); margin-bottom: 4px; }
#login p { opacity: 0.6; margin-top: 0; }
#login input {
  font-size: 18px; padding: 8px 12px; text-align: center; width: 220px; margin-top: 20px;
  background: var(--input-bg); border: 2px solid var(--input-border); color: var(--input-fg);
  font-family: var(--font);
}
#login button {
  margin-top: 14px; font-size: 16px; padding: 8px 24px; border: none; cursor: pointer;
  font-weight: bold; letter-spacing: 2px; font-family: var(--font);
  background: var(--btn-bg); color: var(--btn-fg);
}
#login button:disabled { background: var(--btn-disabled-bg); color: var(--btn-disabled-fg); cursor: default; }
/* Wide enough that a control hint listing five or six keys stays on one or two lines. At 320px
   the zombies hint broke mid-phrase ("CLICK / fire"), which reads as a typo rather than a wrap. */
#login .hint { margin-top: 24px; font-size: 12px; opacity: 0.5; max-width: 560px; text-align: center; }

/* CC-BY 3.0 requires attribution to be SHOWN, not merely recorded in models/CREDITS.md.
   A preset may restyle this; it may not hide it. */
#credits { margin-top: 10px; font-size: 11px; opacity: 0.4; max-width: 560px; text-align: center; }

/* ---- mobile controls: hidden until game.js detects a coarse pointer ----
   Three rules here are load-bearing on a real phone, and all three were learned by running out
   of screen:

   1. SIZES SCALE WITH THE VIEWPORT. A landscape phone is ~375 CSS px tall; the stick and the
      fire button were 120px and 100px of fixed pixels, so the controls ate a third of the
      screen on the device they exist for and nothing on a tablet. `vmin` with a `clamp()` on
      both ends keeps a thumb-sized target on both.
   2. EVERY OFFSET GOES THROUGH --tbtn AND THE SAFE-AREA PADS. The HUD offsets below used to be
      the button sizes re-typed by hand (`bottom: 156px` was 120 + 24 + slack), so resizing a
      button silently parked the health bar underneath it.
   3. `viewport-fit=cover` IS SET IN index.html, SO env(safe-area-inset-*) IS NOT OPTIONAL. In
      landscape the notch column and the home indicator sit exactly where the left-hand controls
      and the bottom HUD are, and the phone will not warn you. */
#touchUi { display: none; }
#touchUi > * { position: absolute; pointer-events: auto; touch-action: none; }
body.touch {
  --tbtn: clamp(52px, 15vmin, 72px);
  --stick: clamp(84px, 26vmin, 120px);
  --pad-l: calc(16px + env(safe-area-inset-left));
  --pad-r: calc(16px + env(safe-area-inset-right));
  --pad-b: calc(16px + env(safe-area-inset-bottom));
  --pad-t: calc(8px + env(safe-area-inset-top));
}
/* The stick FLOATS: it is drawn wherever the left thumb lands and hidden the rest of the time.
   It always behaved this way — the origin has been the touch point since the first version —
   but it was drawn as a fixed circle in the corner, which was both a lie about where the
   control was and the single biggest thing eating the screen. `visibility`, not `display`,
   because game.js measures offsetWidth to get the radius. */
#stick {
  width: var(--stick); height: var(--stick); border-radius: 50%;
  margin: calc(var(--stick) / -2) 0 0 calc(var(--stick) / -2);
  visibility: hidden;
  background: var(--touch-bg); border: 2px solid var(--touch-border);
}
#stickNub {
  position: absolute; left: 50%; top: 50%;
  width: 40%; height: 40%; margin: -20% 0 0 -20%;
  border-radius: 50%; background: var(--touch-nub); border: 2px solid var(--touch-nub-border);
}
.tbtn {
  width: var(--tbtn); height: var(--tbtn);
  border-radius: 50%; background: var(--touch-bg); border: 2px solid var(--touch-border);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: bold; letter-spacing: 1px;
}
.tbtn.held { background: var(--touch-held); border-color: var(--touch-nub-border); }
#btnJump { right: var(--pad-r); bottom: var(--pad-b); }
#btnScore { left: var(--pad-l); top: calc(var(--pad-t) + 28px); width: 44px; height: 44px; font-size: 20px; }
/* Sits above JUMP. Only presets with an interact verb show it; game.js keeps it hidden
   unless the preset asks for it. */
#btnUse { right: var(--pad-r); bottom: calc(var(--pad-b) + var(--tbtn) + 12px); display: none; }

/* HUD would sit underneath the buttons and inside the notch otherwise */
body.touch #healthWrap { bottom: var(--pad-b); left: var(--pad-l); width: min(170px, 34vw); }
body.touch #ammo { right: calc(var(--pad-r) + var(--tbtn) + 12px); bottom: var(--pad-b); font-size: 13px; }
body.touch #weaponWrap { right: calc(var(--pad-r) + var(--tbtn) + 12px); bottom: calc(var(--pad-b) + 22px); }
body.touch #banner { font-size: 22px; top: 16%; }
body.touch #killfeed { top: calc(var(--pad-t) + 28px); right: var(--pad-r); font-size: 12px; }
body.touch #scoreboard { top: calc(var(--pad-t) + 80px); }
body.touch #presetHud { top: calc(var(--pad-t) + 80px); right: var(--pad-r); }
