/* main.css
 * ---------------------------------------------------------------------------
 * Page chrome + responsive letterbox for the fixed 480x270 canvas, plus the
 * on-screen touch controls. Landscape-oriented, centered, black letterbox bars.
 * ------------------------------------------------------------------------- */

/* Pixel UI font (bundled in client/assets/fonts). `PixelUI` is a stable alias so
 * swapping the underlying font only touches these src paths. Canvas text falls
 * back to monospace (per-glyph) until it loads, so the game is always usable. */
@font-face {
  font-family: 'PixelUI';
  src: url('../assets/fonts/DotGothic16-subset.woff2') format('woff2'),
       url('../assets/fonts/DotGothic16-subset.ttf') format('truetype');
  font-weight: normal;
  font-display: swap;
}

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

html, body {
  width: 100%;
  height: 100%;
  background: #000;
  overflow: hidden;
  font-family: PixelUI, monospace;
  color: #fff;
  /* Prevent iOS gesture zoom / rubber-band while playing. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  overscroll-behavior: none;
}

#stage {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}

#game {
  display: block;
  /* Crisp, chunky PS1 upscale — no smoothing. */
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #000;
  touch-action: none;
}

/* --- Touch controls (hidden unless body.touch) ----------------------------
 * The whole overlay is pointer-events:none so taps in the GAPS between buttons
 * still reach the canvas (menus hit-test canvas taps). Only .tbtn buttons opt
 * back in. touch-action:none + preventDefault (input.js) kills page scroll,
 * pinch-zoom and the 300ms synthetic click, and lets a direction + an attack be
 * held at the same time (multitouch — each button captures its own pointer). */
#touch { display: none; }
body.touch #touch { display: block; }

#touch {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Cluster frames are inert; only their .tbtn children capture input. */
.pad, .tc-topbar { position: absolute; pointer-events: none; }
.pad .tbtn { position: absolute; }

.tbtn {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(255, 255, 255, 0.5);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-family: PixelUI, monospace;
  font-size: 18px;
  font-weight: bold;
  line-height: 1;
  backdrop-filter: blur(2px);
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  touch-action: none;
}
.tbtn.pressed { background: rgba(255, 223, 107, 0.55); transform: scale(0.94); }

/* Left d-pad (bigger 52px targets in a cross). Safe-area aware. */
.pad.left  { bottom: max(4vh, var(--safe-bottom)); left: max(3vw, var(--safe-left)); width: 156px; height: 156px; }
.dir { width: 52px; height: 52px; }
.dir.up    { left: 52px;  top: 0; }
.dir.left  { left: 0;     top: 52px; }
.dir.down  { left: 52px;  top: 104px; }
.dir.right { left: 104px; top: 52px; }

/* Right clusters share one footprint; only one shows per data-mode. */
.pad.right { bottom: max(4vh, var(--safe-bottom)); right: max(3vw, var(--safe-right)); width: 156px; height: 156px; }

/* Action cluster (fight): P / K / S / block as a diamond, 56px thumb targets. */
.act { width: 56px; height: 56px; border-radius: 50%; }
.act.special { left: 50px; top: 2px;   background: rgba(180, 120, 255, 0.22); }  /* S  — top    */
.act.heavy   { left: 98px; top: 50px;  background: rgba(255, 150, 90, 0.22); }   /* K  — right  */
.act.block   { left: 2px;  top: 50px;  background: rgba(160, 255, 160, 0.22); }  /* ⛊ — left    */
.act.light   { left: 50px; top: 98px;  background: rgba(120, 200, 255, 0.22); }  /* P  — bottom */

/* Menu cluster (menus): big confirm + smaller back. */
.ui.ok   { left: 90px; top: 90px; width: 64px; height: 64px; border-radius: 50%;
           background: rgba(120, 200, 255, 0.24); font-size: 26px; }
.ui.back { left: 2px;  top: 96px; width: 54px; height: 54px; border-radius: 14px;
           background: rgba(255, 255, 255, 0.14); font-size: 22px; }

/* Top system bar: mute + pause, always reachable in the safe top-right. */
.tc-topbar { top: max(3vh, var(--safe-top)); right: max(3vw, var(--safe-right)); display: flex; gap: 8px; }
.tbtn.sys { width: 46px; height: 38px; border-radius: 10px; font-size: 15px; }
.tbtn.sys.mute { font-size: 19px; }

/* --- Per-mode visibility (data-mode set by game.setTouchLayout) ------------
 * Cluster frames toggle display:block/none; the standalone .sys.pause button
 * toggles display:flex/none so its glyph stays centred when shown. */
#touch .pad.left,
#touch .acts,
#touch .menu { display: none; }
#touch .sys.pause { display: none; }

#touch[data-mode="menu"]  .pad.left,
#touch[data-mode="menu"]  .menu    { display: block; }
#touch[data-mode="fight"] .pad.left,
#touch[data-mode="fight"] .acts    { display: block; }
#touch[data-mode="fight"]  .sys.pause,
#touch[data-mode="paused"] .sys.pause { display: flex; }

/* --- Rotate-to-landscape hint (touch + portrait only) --------------------- */
#rotate-hint { display: none; }
@media (orientation: portrait) {
  body.touch #rotate-hint {
    display: block;
    position: fixed;
    left: 50%;
    bottom: max(10px, var(--safe-bottom));
    transform: translateX(-50%);
    padding: 8px 14px;
    background: rgba(0, 0, 0, 0.62);
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 12px;
    color: #fff;
    text-align: center;
    pointer-events: none;   /* the game still plays underneath in portrait */
    z-index: 20;
    animation: rh-pulse 1.6s ease-in-out infinite;
  }
}
.rh-icon { font-size: 22px; line-height: 1; }
.rh-text { font: bold 12px PixelUI, monospace; margin-top: 3px; letter-spacing: 0.05em; }
@keyframes rh-pulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }

/* --- Telegram Mini App safe areas (additive) -----------------------------
 * Keep chrome out of notches / rounded corners / the home indicator / the
 * Telegram header. Combines the iOS env() insets with the CSS vars telegram.js
 * publishes (which also cover Telegram's own header). Outside Telegram every
 * var is unset and env() resolves to 0, so max(...) collapses to the original
 * values and the plain-browser layout is IDENTICAL. Exact canvas fitting stays
 * owned by game.layout(); this only keeps UI out of unsafe regions. */
:root {
  --safe-top: max(env(safe-area-inset-top), var(--tg-safe-area-inset-top, 0px), var(--tg-content-safe-area-inset-top, 0px));
  --safe-right: max(env(safe-area-inset-right), var(--tg-safe-area-inset-right, 0px), var(--tg-content-safe-area-inset-right, 0px));
  --safe-bottom: max(env(safe-area-inset-bottom), var(--tg-safe-area-inset-bottom, 0px), var(--tg-content-safe-area-inset-bottom, 0px));
  --safe-left: max(env(safe-area-inset-left), var(--tg-safe-area-inset-left, 0px), var(--tg-content-safe-area-inset-left, 0px));
}

/* Pad the letterbox by the safe insets so the centered content is pulled in
 * from notches. flex:0 0 auto keeps the crisp backbuffer at exactly the size
 * game.layout() assigns (never shrink/distort the pixel-perfect canvas). */
#stage {
  padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
}
#game { flex: 0 0 auto; }

/* NOTE: the touch clusters already fold the safe-area insets into their own
 * bottom/left/right/top via max(vw/vh, var(--safe-*)) above, so no separate
 * override block is needed here. Outside Telegram every --safe-* collapses to
 * env()=0 and the plain-browser layout is IDENTICAL to before. */
