/*
 * Layout, safe areas and the rules that stop a browser treating a fight as a web page.
 *
 * SAFE AREAS COME FROM TWO PLACES AND BOTH ARE NEEDED. `env(safe-area-inset-*)` is the
 * system's own notch and home-indicator geometry, and resolves to zero unless the
 * viewport meta carries `viewport-fit=cover`. `--tg-safe-area-inset-*` is what
 * Telegram publishes on the documentElement (Bot API 8.0), and it is the only source
 * inside the Telegram WebView on clients where env() stays zero. Taking the larger of
 * the two is correct under either. `--tg-content-safe-area-inset-top` is separate
 * again: it is the room Telegram's own close and menu buttons occupy in fullscreen,
 * which is exactly where a fighting game wants to put its health bars.
 *
 * The HUD, the round banners and the menus each have their own sheet under css/; they
 * are imported here so every page that links this one (the game, the previews) gets
 * the same look. The settings panel loads css/settings.css itself.
 */

@import url("css/hud.css");
@import url("css/banner.css");
@import url("css/screens.css");

:root {
  --ink: #e9edf2;
  --dim: #8d98a6;
  --hp: #63c08a;
  --grey: #7b8590;
  --mana: #5aa7d8;
  --ui: rgba(255, 255, 255, .1);
  --ui-line: rgba(255, 255, 255, .26);

  /* The shared interface tokens. Every module's stylesheet reads these with the same
     values as fallbacks, so a sheet loaded on its own still looks right. */
  --ui-gold: #ffc94a;
  --ui-gold-dim: #b88a2e;
  --ui-panel: rgba(12, 13, 18, .94);
  --ui-panel-line: rgba(255, 201, 74, .35);
  --ui-text: #f3ead2;
  --ui-muted: #a39a84;
  --ui-danger: #d0454f;
  --ui-radiant: #6fbf5a;
  --ui-dire: #d0454f;
  --ui-mana: #4a8fe0;
  /* Local fonts only: the game must look the same offline and inside a WebView that
     blocks third-party requests. Every face listed carries Cyrillic. */
  --ui-font-display: "Palatino Linotype", "Book Antiqua", Palatino, Cambria, Georgia, "Times New Roman", serif;
  --ui-font-body: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;
  --ui-font-impact: Impact, "Arial Narrow Bold", "Franklin Gothic Heavy", "Arial Black", sans-serif;

  /* One 1280x720 design pixel. Menus and the HUD are laid out in it, so 720p and 1080p
     show the same composition at different sharpness instead of different layouts.
     The bounds are the ones ui/kit.ts `uiUnit()` uses for the canvas-painted frames,
     which have to agree with the text inside them. */
  --u: clamp(.55px, min(100vw / 1280, 100vh / 720), 3px);

  --safe-t: max(var(--tg-safe-area-inset-top, 0px), env(safe-area-inset-top, 0px));
  --safe-b: max(var(--tg-safe-area-inset-bottom, 0px), env(safe-area-inset-bottom, 0px));
  --safe-l: max(var(--tg-safe-area-inset-left, 0px), env(safe-area-inset-left, 0px));
  --safe-r: max(var(--tg-safe-area-inset-right, 0px), env(safe-area-inset-right, 0px));
  /* Telegram's own buttons sit below the system inset, so the HUD clears both. */
  --hud-t: calc(var(--safe-t) + var(--tg-content-safe-area-inset-top, 0px));
  /* The same for the menus on every side (B-059): the system's insets and Telegram's own
     over them — its header buttons in fullscreen. */
  --ui-t: var(--hud-t);
  --ui-b: calc(var(--safe-b) + var(--tg-content-safe-area-inset-bottom, 0px));
  --ui-l: calc(var(--safe-l) + var(--tg-content-safe-area-inset-left, 0px));
  --ui-r: calc(var(--safe-r) + var(--tg-content-safe-area-inset-right, 0px));
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: #0b0d12;
  color: var(--ui-text);
  font: 500 14px/1.35 var(--ui-font-body);
  /* Removes document pan, pinch and double-tap zoom. This — not `user-scalable=no` —
     is what actually works inside an iOS WebView. */
  touch-action: none;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

#app { position: fixed; inset: 0; }

/* The canvas fills the screen edge to edge; only the overlays are inset. A fighting
   stage that stops short of the notch looks broken, a health bar under it is unusable. */
#stage-wrap { position: absolute; inset: 0; }
#stage { display: block; width: 100%; height: 100%; image-rendering: pixelated; }

/* ── HUD, banners, menus: see css/hud.css, css/banner.css, css/screens.css ───── */

/* ── touch controls ───────────────────────────────────────────────────────── */

/* Every rule below is scoped to #controls. The class names are short and common —
   `.block`, `.light`, `.q` — and unscoped they would position any menu or HUD element
   that happened to share one. */

#controls {
  position: absolute;
  inset: 0;
  z-index: 30;
  /* The layer passes touches through; only the two clusters take them. */
  pointer-events: none;
}

.cluster {
  position: absolute;
  /* --touch-*: the player's own size, opacity and room from the edges (touch-settings.ts,
     B-065), set on #controls. */
  bottom: calc(var(--safe-b) + 10px + var(--touch-edge, 0px));
  opacity: var(--touch-alpha, 1);
  pointer-events: auto;
  /* Everything that stops the browser treating a held button as text, a long press as
     a context menu, or a drag as a scroll. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/*
 * Cluster geometry.
 *
 * Every position is expressed against one size variable per control, so the whole
 * layout scales with the screen instead of being redrawn per device. The values are
 * arcs a thumb actually sweeps, not a grid: a thumb pivots from the corner where the
 * hand holds the phone, so the most-used control sits nearest that corner and the
 * rarest — the ult — sits furthest out.
 *
 * Minimum sizes are the platform touch targets (44 CSS px on iOS, 48 dp on Android);
 * the vh terms take over on anything taller than a small phone.
 */

/* At least 28px in from the edge: the system's back is a swipe from the edge on Android and
   in Telegram, and a thumb that starts a walk there closed the Mini App (B-133). */
#pad-left {
  left: calc(max(calc(var(--safe-l) + 10px), 28px) + var(--touch-edge, 0px));
  --dpad: calc(clamp(118px, 34vh, 172px) * var(--touch-scale, 1));
  width: var(--dpad);
  height: var(--dpad);
}

#pad-right {
  right: calc(max(calc(var(--safe-r) + 10px), 28px) + var(--touch-edge, 0px));
  /* Never so big, nor so far in, that the ult at the top of the arc (3.05 --atk up, --abl
     tall) reaches the HUD (--hud-t and some 142 --u of bars and portraits): the largest
     size with the largest edge on a 360 px phone put it over the health bar. */
  --atk-max: calc((100vh - var(--hud-t) - var(--u) * 142 - var(--safe-b) - 10px - var(--touch-edge, 0px)) / 3.85);
  --atk: min(calc(clamp(56px, 16.5vh, 82px) * var(--touch-scale, 1)), var(--atk-max));
  --abl: min(calc(clamp(44px, 11.5vh, 58px) * var(--touch-scale, 1)), calc(var(--atk) * .8));
  --g: calc(clamp(6px, 1.8vh, 11px) * var(--touch-scale, 1));
  width: calc(var(--atk) * 3 + var(--g) * 2);
  height: calc(var(--atk) * 2 + var(--abl) * 2 + var(--g) * 4);
}

/* The children are artwork. They must not receive pointer events: the cluster owns
   the capture and hit-tests their rectangles itself, which is the only way a thumb
   can roll from one direction to the next. */
.cluster > * { pointer-events: none; position: absolute; }

#controls .dpad {
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .07), rgba(255, 255, 255, .03));
  border: 1px solid var(--ui-line);
}

#controls .dpad-hub {
  position: absolute;
  left: 50%; top: 50%;
  width: 30%; height: 30%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px dashed rgba(255, 255, 255, .22);
}

#controls .arrow {
  position: absolute;
  color: rgba(255, 255, 255, .5);
  font-size: 15px;
  line-height: 1;
}
#controls .arrow.up { left: 50%; top: 7%; transform: translateX(-50%); }
#controls .arrow.down { left: 50%; bottom: 7%; transform: translateX(-50%); }
#controls .arrow.left { left: 7%; top: 50%; transform: translateY(-50%); }
#controls .arrow.right { right: 7%; top: 50%; transform: translateY(-50%); }

#controls .key {
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ui);
  border: 1px solid var(--ui-line);
  font-weight: 700;
  letter-spacing: .02em;
  color: rgba(255, 255, 255, .82);
}

#controls .atk { width: var(--atk); height: var(--atk); font-size: 19px; }
#controls .heavy { right: 0;                        bottom: calc(var(--atk) * .60); background: rgba(208, 90, 79, .16); border-color: rgba(208, 90, 79, .5); }
#controls .light { right: calc(var(--atk) * 1.05);  bottom: 0;                      background: rgba(233, 180, 76, .14); border-color: rgba(233, 180, 76, .45); }

#controls .block {
  right: calc(var(--atk) * 2.10);
  bottom: calc(var(--atk) * .30);
  width: var(--atk);
  height: var(--atk);
  font-size: 11px;
  background: rgba(90, 167, 216, .16);
  border-color: rgba(90, 167, 216, .5);
}

/* Throw sits in the pocket between the two attacks, where the right thumb already
   rests: it is a close-range answer to block, pressed in the middle of the same
   exchange as a jab, and the arc of abilities above stays untouched. */
#controls .throw {
  right: calc(var(--atk) * 1.12);
  bottom: calc(var(--atk) * 1.16);
  width: var(--abl);
  height: var(--abl);
  font-size: clamp(8px, 1.8vh, 10px);
  letter-spacing: 0;
  background: rgba(163, 154, 132, .14);
  border-color: rgba(163, 154, 132, .5);
}

#controls .ability {
  width: var(--abl);
  height: var(--abl);
  font-size: 14px;
  background: rgba(120, 174, 198, .12);
  border-color: rgba(120, 174, 198, .4);
}
/* The arc over the attacks, farthest from the thumb first. A hero's buttons take the places
   nearest the thumb (controls.ts setHero, B-058): Pudge all three, most heroes the last two,
   Wraith King the last. */
#controls [data-arc="2"] { right: calc(var(--atk) * .12);  bottom: calc(var(--atk) * 1.72); }
#controls [data-arc="1"] { right: calc(var(--atk) * 1.18); bottom: calc(var(--atk) * 2.10); }
#controls [data-arc="0"] { right: calc(var(--atk) * 2.28); bottom: calc(var(--atk) * 1.88); }
/* The ability's own icon, as in the HUD, clipped by the round key. */
#controls .key.has-icon { background-repeat: no-repeat; overflow: hidden; }
/* Not now — no mana, on cooldown, mid-move: greyed like the HUD's icon, still pressable
   (the simulation turns the press down, as it does from the keyboard). Greyed, not faded
   out: the thumb has to find the button before it lights up. */
#controls .key.is-off { opacity: .7; filter: grayscale(1) brightness(.75); border-color: rgba(255, 255, 255, .35); }
#controls .ult {
  right: calc(var(--atk) * 1.20);
  bottom: calc(var(--atk) * 3.05);
  background: rgba(233, 180, 76, .3);
  border-color: #e9b44c;
  box-shadow: 0 0 12px rgba(233, 180, 76, .45);
}

/* ── overlays ─────────────────────────────────────────────────────────────── */

#splash, #gate {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0b0d12;
  /* Menus keep tap and scroll behaviour but lose double-tap zoom. */
  touch-action: manipulation;
}

#splash {
  z-index: 90;
  transition: opacity .18s linear;
  background: radial-gradient(ellipse 60% 50% at 50% 50%, #17130c, #07080b 70%);
}
#splash.gone { opacity: 0; pointer-events: none; }
#splash span {
  color: var(--ui-gold-dim);
  letter-spacing: .32em;
  text-transform: uppercase;
  font: 700 13px/1 var(--ui-font-display);
  animation: splash-breathe 1.6s ease-in-out infinite;
}
@keyframes splash-breathe { 50% { color: var(--ui-gold); text-shadow: 0 0 14px rgba(255, 190, 60, .45); } }
/* Why the game did not load (index.html's loader, B-211): a message of two hundred
   characters, a line of at most 36em. The text replaces the splash's children, so the
   measure is set by the side padding, not by a box around it. */
#splash.failed { color: #d0454f; font: 14px/1.5 ui-monospace, monospace; padding: 24px max(24px, calc(50% - 18em)); text-align: center; }
/* Still coming on a slow line (index.html's loader, B-211): the title keeps breathing, and a
   line under it says why this takes so long — not a failure. */
#splash.slow { flex-direction: column; gap: 14px; }
#splash .splash-note { margin: 0; padding: 0 24px; max-width: 32em; color: var(--ui-muted); font: 12px/1.5 ui-monospace, monospace; text-align: center; }

/* The gate is invisible by default and revealed only by the media query below, so a
   desktop browser and a landscape phone never see it. */
/* Fully opaque: the game behind it is unplayable in portrait anyway, and a
   half-visible HUD bleeding through reads as a rendering fault. */
#gate { display: none; z-index: 100; background: #0b0d12; }
@media (orientation: portrait) {
  .mobile-device #gate { display: flex; }
}
.gate-box { text-align: center; padding: 0 32px; max-width: 22em; }
.gate-icon { font-size: 42px; color: var(--ui-gold); margin-bottom: 12px; }
.gate-hint { color: var(--ui-muted); font-size: 12px; }

/* “Click to play” (ui/focus-hint.ts): Telegram Desktop and the web clients open the
   game without the keyboard's focus. A quiet pill at the bottom; the click it asks for goes
   through it to the page. */
.focus-hint {
  position: fixed;
  z-index: 96;
  bottom: calc(var(--safe-b) + 14px);
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 14px;
  font: 600 13px/1.2 var(--ui-font-body);
  color: var(--ui-text);
  background: rgba(11, 13, 18, .88);
  border: 1px solid rgba(184, 138, 46, .55);
  border-radius: 999px;
  pointer-events: none;
}
.focus-hint[hidden] { display: none; }

/* “On phones, the game lives in Telegram” (B-132, D-94): a phone's own browser, over the menu.
   Under the portrait gate, over the screens; it takes taps, so it stays a thin strip. */
.tg-plate {
  position: fixed;
  z-index: 95;
  top: calc(var(--safe-t) + 8px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  padding: 8px 8px 8px 14px;
  font: 600 13px/1.3 var(--ui-font-body);
  color: var(--ui-text);
  background: rgba(11, 13, 18, .94);
  border: 1px solid rgba(184, 138, 46, .55);
  border-radius: 6px;
}
.tg-plate-open {
  padding: 6px 10px;
  color: #0b0d12;
  background: var(--ui-gold);
  border-radius: 4px;
  text-decoration: none;
  white-space: nowrap;
}
.tg-plate-close {
  width: 28px;
  height: 28px;
  font: 700 18px/1 var(--ui-font-body);
  color: var(--ui-muted);
  background: none;
  border: 0;
}

#controls[hidden] { display: none; }
#controls .ability[hidden] { display: none; }
