@font-face {
  font-family: "VT323";
  src: url("fonts/vt323.ttf") format("truetype");
  font-display: swap;
}

:root {
  --bg: #0a0e17;
  --panel: #131a26;
  --border: #060a10;
  --text: #e5e7eb;
  --dim: #8b93a3;
  --gold: #c8aa6e;
  /* Original pixel-block palette, hand-picked, not sampled from any game's
     actual texture files -- just an earthy/blocky vibe in the same spirit. */
  --dirt-1: #4a3423;
  --dirt-2: #5c4230;
  --dirt-3: #3c2a1c;
  --grass-1: #3f6b2e;
  --grass-2: #4d7f38;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text);
  /* VT323 renders visibly smaller than its font-size number, so the base
     size is bumped up a couple px over a normal-font app to compensate. */
  font: 19px/1.35 "VT323", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
  letter-spacing: 0.02em; }
/* Fixed to exactly one screen, no page-level scroll -- the Map tab should
   never scroll at all, and Stats scrolls in its own box below the nav
   instead of the whole page scrolling. */
body { display: flex; flex-direction: column; position: fixed; inset: 0; height: auto; overflow: hidden; }
/* iOS home-screen apps with the black-translucent status bar shift the page
   up under the status bar but don't grow it to match, so a strip exactly
   the status bar's height is left at the bottom, outside the document
   entirely. iOS paints that strip with the page's flat background colour --
   no texture -- which is the hard band that showed at the bottom. Making
   the document itself that much taller puts the dirt there instead;
   overflow: hidden keeps the extra height from making the page scroll. The
   dirt-brown background colour is the fallback if any sliver still shows. */
html { height: calc(100% + env(safe-area-inset-top)); overflow: hidden; }
html, body { background-color: #7a5433; }

/* The background is the grass-block picture (art/grass-block.jpg), rebuilt
   block by block by art/clean.py into tiles at one pixel per block.
   Scaled up here to 18px per block with image-rendering: pixelated, so every
   block is a hard-edged square instead of the JPEG's soft blur.
   dirt-tile.png is exactly one repeat of the dirt (15 x 10 blocks), so it
   tiles with no seam. It's positioned from the header's bottom edge (--seam,
   set by app.js) plus 2 block rows, which is where the picture's own dirt
   continues after the header's grass strip -- so the grass-to-dirt edge
   matches the picture instead of cutting a block row in half. */
html, body {
  background-image: url("textures/dirt-tile.png");
  background-size: 270px 180px;
  background-position: left 0 top calc(var(--seam, 0px) + 36px);
  background-repeat: repeat;
  image-rendering: pixelated;
}
/* iOS PWA (status-bar-style black-translucent) draws content under the
   status bar/notch -- without this the tabs render right under the clock
   and signal icons. The header is the top of the same picture: the grass
   with its blades hanging down into the dirt (grass-strip.png, 6 block rows,
   anchored to the bottom), and whole rows of plain grass (grass-fill.png)
   above it for however much height the safe area adds -- aligned to the
   strip's top edge so the block rows line up rather than being cut mid-row.
   Bottom padding keeps the blades below the tabs rather than hidden. */
header { width: 100%; flex-shrink: 0;
  padding: calc(18px + env(safe-area-inset-top)) 16px 44px;
  background-image: url("textures/grass-strip.png"), url("textures/grass-fill.png");
  background-size: 270px 108px, 270px 36px;
  background-position: left bottom, left 0 bottom 108px;
  background-repeat: repeat-x, repeat;
  image-rendering: pixelated;
}
header .tabs { max-width: 900px; margin: 0 auto; }

/* Minecraft's own UI has no rounded corners and a chunky beveled-pixel look
   on every button/panel (light edge top-left, dark edge bottom-right) --
   that pseudo-3D bevel, more than anything else, is what reads as "the
   Minecraft UI" rather than just "a dark app". */
.tabs { display: flex; gap: 8px; }
.tab {
  flex: 1; text-align: center; padding: 12px 10px; border-radius: 2px;
  border: 2px solid var(--border); background: var(--panel); color: var(--text);
  font: inherit; font-size: 1.15rem; text-transform: uppercase; letter-spacing: 0.08em;
  cursor: pointer;
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.08), inset -2px -2px 0 rgba(0,0,0,0.4);
}
.tab:active { box-shadow: inset -2px -2px 0 rgba(255,255,255,0.08), inset 2px 2px 0 rgba(0,0,0,0.4); }
.tab.active {
  background: var(--gold); color: #1a1400; border-color: #7a6338; font-weight: 700;
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.35), inset -2px -2px 0 rgba(0,0,0,0.3);
}

/* min-height: 0 is load-bearing here -- without it a flex child defaults to
   min-height: auto, which grows past the flex container instead of scrolling
   inside it, and the whole page ends up scrolling instead. */
main, .view { flex: 1; min-height: 0; display: none; }
.view.active { display: flex; flex-direction: column; }

/* Map: exactly one screen, never scrolls -- the frame just fills whatever
   space is left below the nav. */
#view-map { overflow: hidden; padding: 0 16px 16px; max-width: 900px; width: 100%; margin: 0 auto; }
#map-frame {
  flex: 1; width: 100%; min-height: 0; border: 2px solid var(--border);
  border-radius: 2px; background: #000;
}

/* Stats: the nav bar above stays put, this scrolls on its own. */
#view-stats { overflow-y: auto; -webkit-overflow-scrolling: touch;
  max-width: 700px; width: 100%; margin: 0 auto;
  padding: 14px 16px calc(40px + env(safe-area-inset-bottom)); }

.player-card {
  background: var(--panel); border: 2px solid var(--border); border-radius: 2px;
  padding: 16px; margin-bottom: 14px;
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.06), inset -2px -2px 0 rgba(0,0,0,0.35);
}
.player-name { font-size: 1.5rem; font-weight: 700; color: var(--gold); margin-bottom: 10px;
  text-transform: uppercase; letter-spacing: 0.04em; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.stat { background: var(--bg); border: 1px solid var(--border); border-radius: 2px; padding: 10px 12px; }
.stat .value { font-size: 1.6rem; font-weight: 700; }
.stat .label { font-size: 0.85rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.06em; }

.kills-section { margin-top: 12px; }
.kills-section h3 { font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--dim); margin: 0 0 8px; }
.kill-chip {
  display: inline-flex; gap: 6px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 2px; padding: 4px 10px; margin: 0 6px 6px 0; font-size: 0.95rem;
}
.kill-chip b { color: var(--gold); }

.empty { color: var(--dim); font-size: 1.05rem; text-align: center; padding: 24px 16px;
  background: var(--panel); border: 2px solid var(--border); border-radius: 2px; }

/* Login gate. This subdomain is public, unlike the rest of the homelab, so
   the code is the only thing in front of it. */
.login-page { display: flex; align-items: center; justify-content: center; min-height: 100dvh; padding: 24px; }
.login-card {
  width: 100%; max-width: 320px; display: flex; flex-direction: column; gap: 12px;
  background: var(--panel); border: 2px solid var(--border); border-radius: 2px;
  padding: 26px 22px; text-align: center;
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.06), inset -2px -2px 0 rgba(0,0,0,0.35);
}
.login-card h1 { font-size: 2rem; margin: 0; color: var(--gold); text-transform: uppercase; letter-spacing: 0.06em; }
.login-card .hint { color: var(--dim); font-size: 1rem; margin: 0 0 4px; }
.login-card input {
  padding: 13px 14px; border-radius: 2px;
  border: 2px solid var(--border); background: var(--bg); color: var(--text);
  /* >=16px or iOS zooms the page on focus. */
  font-size: 17px; font-family: inherit;
}
.login-card button {
  padding: 13px; border: 2px solid #7a6338; border-radius: 2px;
  background: var(--gold); color: #1a1400; font: inherit; font-weight: 700;
  font-size: 1.15rem; text-transform: uppercase; letter-spacing: 0.06em; cursor: pointer;
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.35), inset -2px -2px 0 rgba(0,0,0,0.3);
}
.login-card button:active { box-shadow: inset -2px -2px 0 rgba(255,255,255,0.25), inset 2px 2px 0 rgba(0,0,0,0.3); }
.login-card button:disabled { opacity: 0.6; }
.error { color: #e5734a; font-size: 0.95rem; margin: 0; }
