/*
 * Design tokens are non-negotiable (scope §1): ink, teal, one bright primary
 * per screen, gold, Poppins plus Press Start 2P, square corners, faint grid.
 * Ported from the prototype rather than reinterpreted.
 *
 * Fonts are self-hosted from /fonts (scope §14.2): the public portal makes no
 * third-party font request, so no visitor IP leaks to a CDN, and a cold kiosk
 * boot on a dead venue connection still renders the real typefaces rather than
 * dropping to system fonts. The woff2 files are the Google latin subsets under
 * the SIL Open Font License 1.1, with the licences alongside them in /fonts.
 */

/* The three Poppins weights the portal uses (300 body, 400 default, 700 bold)
 * and the single-weight arcade face. font-display: swap keeps text visible
 * while the file loads, matching the CDN behaviour this replaces. */
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/fonts/Poppins-300.woff2') format('woff2');
}
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Poppins-400.woff2') format('woff2');
}
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/Poppins-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Press Start 2P';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/PressStart2P-400.woff2') format('woff2');
}

:root {
  --ink: #0f1419;
  --panel: #0b0f13;
  --dark: #2c313d;
  --teal: #85bcd0;
  --bright: #00b0f0;
  --gold: #e2b73a;
  --ochre: #d0995e;
  --green: #89bd70;
  --lite: #bcd9e4;
  --red: #ed4d5e;
}

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

/* Sound controls: fixed, out of the way, present on every screen. The mute
   toggle sits beside a volume slider (v1 feedback). Hidden on the 43 inch
   attract display, which takes no input and plays no sound. */
#audioControls {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 8px;
}
#audioToggle {
  width: 42px;
  height: 42px;
  padding: 0;
  font-size: 18px;
  line-height: 42px;
  text-align: center;
  cursor: pointer;
  color: var(--teal);
  background: var(--panel);
  border: 1px solid var(--dark);
  border-radius: 8px;
}
#audioToggle:hover {
  border-color: var(--teal);
}
#audioVolume {
  width: 90px;
  height: 4px;
  cursor: pointer;
  accent-color: var(--teal);
}
body.attract #audioControls {
  display: none;
}

/* Avatar style picker on the signup screen (v2 §9). Two by two grid of the four
   styles, generated from the handle; the chosen one is ringed in gold. */
.style-picker {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-top: 14px;
  max-width: 240px;
}
.style-opt {
  padding: 8px 6px 6px;
  background: var(--panel);
  border: 2px solid var(--dark);
  /* Square corners: the retro avatar tiles are square per the brand, and a
     rounded frame around a square tile reads as a mistake. */
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--lite);
}
.style-opt:hover {
  border-color: var(--teal);
}
.style-opt.sel {
  border-color: var(--gold);
}
.style-opt svg {
  width: 68px;
  height: 68px;
  display: block;
}
.style-nm {
  font-family: 'Press Start 2P', monospace;
  font-size: 7px;
  letter-spacing: 0.5px;
}
.style-opt.sel .style-nm {
  color: var(--gold);
}

body {
  background: var(--ink);
  color: #fff;
  font-family: 'Poppins', 'Segoe UI', sans-serif;
  font-weight: 300;
  min-height: 100vh;
  /* The faint grid. Part of the identity, not decoration. */
  background-image:
    linear-gradient(rgba(133, 188, 208, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(133, 188, 208, 0.06) 1px, transparent 1px);
  background-size: 26px 26px;
}

.px {
  font-family: 'Press Start 2P', monospace;
}

.screen {
  display: none;
  min-height: 100vh;
  padding: 48px 64px;
  max-width: 1280px;
  margin: 0 auto;
  position: relative;
}

.screen.active {
  display: block;
}

.btn {
  font-family: 'Press Start 2P', monospace;
  font-size: 13px;
  background: var(--bright);
  color: var(--ink);
  border: none;
  padding: 14px 20px;
  cursor: pointer;
}

.btn:hover {
  filter: brightness(1.12);
}

.btn:disabled {
  opacity: 0.4;
  cursor: default;
  filter: none;
}

.ghost {
  font-family: 'Press Start 2P', monospace;
  font-size: 12px;
  background: transparent;
  color: var(--teal);
  border: 1.5px solid var(--teal);
  padding: 13px 19px;
  cursor: pointer;
}

.ghost:disabled {
  opacity: 0.35;
  cursor: default;
}

.eyebrow {
  font-family: 'Press Start 2P', monospace;
  font-size: 10px;
  color: var(--teal);
  letter-spacing: 1px;
}

.field {
  width: 100%;
  background: #11161c;
  border: 1px solid var(--dark);
  color: var(--lite);
  font-family: 'Poppins', sans-serif;
  font-size: 15px;
  padding: 12px 14px;
  margin-top: 6px;
}

.field:focus-visible,
.btn:focus-visible,
.ghost:focus-visible,
.opt:focus-visible {
  outline: 2px solid var(--bright);
  outline-offset: 2px;
}

.flabel {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  color: var(--teal);
  margin-top: 18px;
  display: block;
}

.logo {
  width: 130px;
  height: 48px;
}

.brandband {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 44px;
  background: var(--panel);
  border-top: 1px solid var(--dark);
  display: flex;
  align-items: center;
  padding: 0 28px;
  gap: 22px;
  z-index: 5;
}

.brandband .logo {
  width: 86px;
  height: 32px;
}

.brandband span {
  font-size: 12px;
  color: var(--lite);
}

.brandband .url {
  margin-left: auto;
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  color: var(--teal);
}

.lb-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--dark);
  padding: 12px 18px;
  margin-top: 12px;
}

.lb-row.you {
  border: 2px solid var(--gold);
  background: #12181f;
}

/* Rank sits in a fixed column so avatars line up down the board, but the number
   is right-aligned so it hugs the avatar rather than leaving a wide gutter for
   single-digit ranks. Width holds the widest rank shown (#10 on the 43 inch). */
.lb-rank {
  font-family: 'Press Start 2P', monospace;
  font-size: 15px;
  width: 44px;
  text-align: right;
  flex: none;
}

.lb-handle {
  font-family: 'Press Start 2P', monospace;
  font-size: 12px;
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
  overflow: hidden;
}
.lb-name {
  white-space: nowrap;
  /* Long handles (up to 15 chars in the pixel font) must truncate, not run over
     the gold score on a narrow screen. Ellipsis inside the flex column, which
     already carries min-width: 0 so it can shrink below its content. */
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Attempts per player on the board (v1 feedback). Small and muted so it sits
   under the handle without competing with it. */
.lb-plays {
  font-size: 8px;
  color: var(--teal);
  opacity: 0.75;
}
/* The "(YOU)" marker rides on the plays line (v1 feedback: it used to wrap the
   handle onto an extra line and left that row taller than the rest). Gold, and
   its own opacity so the muted plays line does not dim it. */
.lb-you {
  color: var(--gold);
  opacity: 1;
}

.lb-score {
  font-family: 'Press Start 2P', monospace;
  font-size: 14px;
  color: var(--gold);
  margin-left: auto;
}

.ava-tile {
  background: var(--panel);
  border: 2px solid var(--dark);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Lightweight trophy cabinet (badges launch phasing): earned badges as
   rarity-coloured tiles, square corners per the retro brand. The tile border
   and text take the rarity colour inline; narration shows in .badge-note. */
.badge-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.badge-strip:empty {
  display: none;
}
.badge-tile {
  font-family: 'Press Start 2P', monospace;
  font-size: 7px;
  line-height: 1.6;
  letter-spacing: 0.5px;
  padding: 8px 10px;
  background: var(--panel);
  border: 2px solid var(--dark);
  cursor: pointer;
  max-width: 130px;
}
.badge-note {
  font-size: 12px;
  color: var(--lite);
  margin-top: 10px;
  min-height: 18px;
  line-height: 1.5;
}

.term {
  font-family: 'Press Start 2P', monospace;
  font-size: 11px;
  color: var(--teal);
  line-height: 2.4;
}

.modalback {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(4, 7, 10, 0.85);
  z-index: 20;
  align-items: center;
  justify-content: center;
}

.modalback.active {
  display: flex;
}

.opt {
  flex: 1;
  border: 1.5px solid var(--teal);
  background: #11161c;
  padding: 26px 14px;
  text-align: center;
  cursor: pointer;
  font-family: 'Press Start 2P', monospace;
  font-size: 10px;
  line-height: 1.9;
  color: #fff;
}

.opt:hover {
  background: #152030;
  border-color: var(--bright);
}

/*
 * The offline bar. Count only, never contents: the queue holds names and
 * email addresses and this bar sits on a screen the public can read over
 * someone's shoulder.
 */
#offlinebar {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: #11161c;
  color: var(--teal);
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  padding: 8px 16px;
  z-index: 30;
  border-bottom: 1px solid var(--teal);
}

a {
  color: var(--teal);
}

/*
 * Attract mode drives a 43 inch screen from across an aisle. Everything grows
 * and the body scale goes up, because the readable distance is metres rather
 * than an arm's length.
 */
body.attract .lb-rank {
  font-size: 26px;
  width: 82px; /* holds "#10" right-aligned at this size */
}

body.attract .lb-handle {
  font-size: 21px;
  gap: 9px;
}
body.attract .lb-plays {
  font-size: 11px;
}

body.attract .lb-score {
  font-size: 24px;
}

/* The 43 inch board is read from metres away, so the rows want more air between
   them and inside them than the arm's-length home board. */
body.attract .lb-row {
  gap: 22px;
  padding: 18px 28px;
  margin-top: 16px;
}

body.attract .ava-tile {
  width: 68px !important;
  height: 68px !important;
}

/*
 * The ARSENAL codex (brief section 15): a modal overlay of discovery tiles.
 * Locked entries are a dashed "?" per the codex mock; discovered ones carry
 * the name and its one-liner.
 */
#codexOverlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(11, 13, 17, 0.86);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 40px 24px;
}

#codexOverlay[hidden] {
  display: none;
}

#codexPanel {
  width: min(1080px, 100%);
  background: var(--bg, #101216);
  border: 1px solid var(--dark);
  border-radius: 10px;
  padding: 30px 34px 40px;
}

#codexHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.codex-section {
  font-size: 12px;
  color: var(--teal);
  margin: 30px 0 12px;
}

.codex-section .codex-count {
  color: var(--lite);
  font-size: 9px;
  margin-left: 12px;
}

.codex-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.codex-tile {
  border: 1px solid var(--dark);
  border-radius: 6px;
  padding: 16px 14px;
  min-height: 84px;
  text-align: center;
}

.codex-tile .codex-name {
  font-size: 10px;
  color: #fff;
}

.codex-tile .codex-line {
  font-size: 12px;
  color: var(--lite);
  margin-top: 8px;
}

.codex-tile.locked {
  border-style: dashed;
  opacity: 0.55;
}

.codex-tile.locked .codex-name {
  color: var(--lite);
}

/* --------------------------------------------------------------- mobile
   The portal and the game are desktop-only (the game needs a fine pointer), so
   the CSS above is desktop-first. But a phone visitor still lands on the mobile
   holding page (#scr-mobile), which shows the live TOP 3 board and the fixed
   brand footer, and those two were never sized for a narrow screen: long handles
   overran the score and the footer's logo + Supply Nation line + URL did not fit.
   This block fits exactly those, and keeps the full brand line (never truncated,
   it is a brand requirement) by letting the footer wrap and shrink. */
@media (max-width: 640px) {
  .brandband {
    height: auto;
    padding: 7px 12px;
    gap: 4px 10px;
    flex-wrap: wrap;
    justify-content: center;
    text-align: center;
  }
  .brandband .logo {
    width: 54px;
    height: 20px;
  }
  .brandband span {
    font-size: 9px;
    line-height: 1.4;
  }
  .brandband .url {
    margin-left: 0; /* no auto-push once the row can wrap */
    font-size: 8px;
  }
  /* The footer is position: fixed, so clear the mobile screen's own content
     past it (it can wrap to two lines on the narrowest phones). */
  #scr-mobile {
    padding-bottom: 96px;
  }
  /* Tighter board rows so a handle and its score both fit; the ellipsis on
     .lb-name handles anything still too long. */
  .lb-row {
    padding: 10px 12px;
    gap: 10px;
  }
  .lb-rank {
    width: 30px;
    font-size: 12px;
  }
  .lb-handle {
    font-size: 11px;
  }
  .lb-score {
    font-size: 12px;
  }
}
