/* ───── NAViTRAiL QR Hunt — Theme ─────
   Inspired by Navitrail / The Navigator brand:
   cream/parchment background, navy headers, forest green,
   burnt-orange accents, compass-rose motif. */

:root {
  --bg:        #f3e9d2;        /* parchment cream */
  --bg-2:      #ebdfc1;        /* darker cream  */
  --paper:     #fbf6e8;        /* card paper */
  --line:      #d9c79b;        /* warm line */
  --line-soft: #ead9b1;

  --ink:       #1a2f4a;        /* deep navy */
  --ink-soft:  #314866;
  --muted:     #6b6244;        /* warm muted */
  --muted-2:   #8b8062;

  --navy:      #1a2f4a;
  --forest:    #2d5f3f;        /* trail green */
  --forest-2:  #1f4a30;
  --orange:    #e07a3a;        /* burnt orange */
  --orange-2:  #c45f1f;
  --amber:     #d4a73a;        /* signpost amber */
  --rust:      #a8431f;

  --gold:      #c9961d;
  --silver:    #8a8b8e;
  --bronze:    #a6612d;

  --shadow-1:  0 6px 18px rgba(26,47,74,0.10);
  --shadow-2:  0 18px 40px rgba(26,47,74,0.18);
  --r-md:      14px;
  --r-lg:      20px;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0;
  font-family: 'Prompt','IBM Plex Sans Thai',system-ui,-apple-system,sans-serif;
  color: var(--ink);
  background: var(--bg);
  min-height: 100%;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

/* topo / compass background hint */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(circle at 12% 18%, rgba(45,95,63,0.07) 0 22%, transparent 23%),
    radial-gradient(circle at 88% 82%, rgba(224,122,58,0.08) 0 25%, transparent 26%),
    radial-gradient(circle at 50% 50%, rgba(26,47,74,0.04) 0 35%, transparent 36%);
  pointer-events: none;
}
body.hero-bg::before {
  background:
    radial-gradient(circle at 50% 50%, rgba(26,47,74,0.05) 0 1px, transparent 1.5px) 0 0 / 36px 36px,
    radial-gradient(circle at 12% 18%, rgba(45,95,63,0.10) 0 22%, transparent 23%),
    radial-gradient(circle at 88% 88%, rgba(224,122,58,0.10) 0 25%, transparent 26%);
}
body.board-bg::before { opacity: 0.7; }

.page { max-width: 720px; margin: 0 auto; padding: 22px 18px 96px; }

/* ───── Brand header / wordmark ───── */
.brand-bar {
  /* Stack the logo full-width and center it; the brand should breathe. */
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 6px 0 22px;
  text-align: center;
}
/* Real Navitrail logo (used since June 2026; replaces the CSS compass + text). */
.brand-logo {
  /* Hero-sized so the brand is clearly the first thing a runner sees. */
  height: auto;
  width: 100%;
  max-width: 420px;
  /* `display: block` removes the inline whitespace baseline, but block
     elements DON'T centre via `text-align`. Use `margin: auto` so the logo
     sits in the middle of its container regardless of how wide the parent
     gets (matters on admin pages which use the full viewport width). */
  display: block;
  margin: 0 auto 4px;
  object-fit: contain;
}
.brand-tagline {
  font-weight: 500; font-size: 11px; letter-spacing: 2px;
  color: var(--forest); text-transform: uppercase;
}
/* Admin login: keep the brand visible but compact so the PIN card centers
   in the remaining viewport without scrolling. */
body.admin-login-bg .brand-logo {
  max-width: 220px;          /* ~half of the marketing-page size */
  margin-bottom: 0;
}
body.admin-login-bg .brand-bar { margin: 16px 0 8px; }
body.admin-login-bg .hero {
  min-height: calc(100dvh - 180px);  /* leave room for the brand above */
  padding: 8px 0 24px;
}
.compass {
  width: 44px; height: 44px; flex: 0 0 44px;
  display: grid; place-items: center;
  background: var(--navy);
  color: var(--bg);
  border-radius: 50%;
  box-shadow: var(--shadow-1);
  position: relative;
}
.compass::before, .compass::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
}
/* compass needle */
.compass::before {
  background:
    conic-gradient(from -45deg,
      transparent 0 35%, var(--orange) 35% 50%,
      transparent 50% 85%, #f4e6c3 85% 100%);
  -webkit-mask: radial-gradient(circle, transparent 30%, #000 31%, #000 46%, transparent 47%);
          mask: radial-gradient(circle, transparent 30%, #000 31%, #000 46%, transparent 47%);
  border-radius: 50%;
}
.compass::after {
  background: radial-gradient(circle, var(--bg) 0 18%, transparent 19%);
}

.wordmark {
  font-weight: 800; letter-spacing: 0.5px; font-size: 20px;
  color: var(--navy);
  line-height: 1;
}
.wordmark .lc { font-weight: 400; opacity: 0.65; text-transform: lowercase; }
.wordmark small {
  display: block; font-weight: 500; font-size: 11px; letter-spacing: 2px;
  color: var(--forest); margin-top: 4px; text-transform: uppercase;
}

/* ───── Hero ───── */
.hero { display: flex; align-items: center; min-height: 100dvh; padding: 24px 0; }
.hero-card {
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 28px 24px;
  box-shadow: var(--shadow-2);
  position: relative;
  overflow: hidden;
}
.hero-card::after {
  /* Decorative corner stripe — MUST be pointer-events:none, otherwise it
     silently intercepts clicks on the language pills that sit in the same
     top-right region. */
  content: ""; position: absolute; top: -40px; right: -40px;
  width: 140px; height: 140px;
  background: repeating-linear-gradient(45deg,
    var(--orange) 0 10px, var(--navy) 10px 20px);
  transform: rotate(15deg); opacity: 0.10;
  pointer-events: none;
}

h1 { font-size: 28px; line-height: 1.18; margin: 8px 0 6px; color: var(--navy); }
h2 { font-size: 18px; margin: 18px 0 10px; color: var(--navy); }
h3 { font-size: 14px; margin: 0 0 8px; color: var(--forest); text-transform: uppercase; letter-spacing: 0.6px; }
.lead { color: var(--muted); margin: 0 0 22px; line-height: 1.55; }
.hi { color: var(--orange); font-weight: 700; }

.back-link {
  display: inline-block;
  color: var(--muted); text-decoration: none;
  margin-bottom: 8px; font-size: 13px;
}
.back-link:hover { color: var(--navy); }

/* ───── Forms ───── */
.bib-form, .form { display: grid; gap: 14px; }
.bib-form label, .field label {
  display: block; font-size: 12px; color: var(--forest);
  margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600;
}
/* The bib-input is the runner's #1 action — give the label hero size so the
   intent is unmistakable on first glance. */
.bib-form label[for="bib"] {
  font-size: 28px;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: none;
  color: var(--navy);
  margin-bottom: 10px;
}
input, textarea, select {
  width: 100%;
  background: #fffaf0;
  border: 1.5px solid var(--line);
  color: var(--ink);
  padding: 13px 15px;
  border-radius: 12px;
  font-family: inherit;
  font-size: 16px;
  outline: none;
  transition: border-color .15s, background .15s;
}
input:focus, textarea:focus, select:focus {
  border-color: var(--forest);
  background: #fff;
}
.req { color: var(--orange); }

/* ───── Buttons ───── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  border: 1.5px solid var(--navy);
  border-radius: 12px;
  padding: 12px 18px;
  font-family: inherit; font-weight: 700; font-size: 15px;
  cursor: pointer; text-decoration: none;
  color: var(--navy);
  background: var(--paper);
  transition: transform .08s, background .15s, color .15s, border-color .15s;
  letter-spacing: 0.3px;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--navy); color: #fdf6e3;
  border-color: var(--navy);
  box-shadow: var(--shadow-1);
}
.btn-primary:hover  { background: var(--ink-soft); }
.btn-success {
  background: var(--forest); color: #fdf6e3; border-color: var(--forest);
}
.btn-accent {
  background: var(--orange); color: #fff; border-color: var(--orange-2);
}
.btn-danger {
  background: var(--rust); color: #fff; border-color: var(--rust);
}
.btn-ghost {
  background: transparent; color: var(--navy); border-color: var(--line);
}
.btn-link { background: none; border: none; color: var(--muted); font-weight: 500; }
.btn-lg { padding: 15px 22px; font-size: 16px; border-radius: 14px; }
.btn-xl { padding: 17px 24px; font-size: 17px; border-radius: 16px; }
.btn-block { width: 100%; margin-top: 10px; }
.btn-mini  { padding: 6px 10px; font-size: 12px; border-radius: 8px; }
.hero-actions { display: flex; gap: 10px; margin-top: 14px; }
.hero-actions .btn { flex: 1; }

/* segmented (team type) */
.seg { display: grid; grid-template-columns: repeat(2,1fr); gap: 8px; }
.seg-btn {
  background: #fffaf0; border: 1.5px solid var(--line); color: var(--navy);
  padding: 13px 8px; border-radius: 12px;
  font-weight: 600; font-family: inherit; font-size: 14px; cursor: pointer;
}
.seg-btn.active { background: var(--navy); color: #fdf6e3; border-color: var(--navy); }

/* ───── Messages ───── */
.msg { margin-top: 14px; font-size: 14px; min-height: 22px; font-weight: 500; }
.msg-err  { color: #a8221b; }
.msg-ok   { color: var(--forest-2); }
.msg-warn { color: var(--orange-2); }

/* ───── Team page ───── */
.team-page { display: grid; gap: 14px; }
.team-header {
  display: flex; align-items: center; gap: 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 14px;
  box-shadow: var(--shadow-1);
}
.team-bib {
  background: var(--navy);
  color: #fdf6e3;
  font-weight: 800; font-size: 24px;
  padding: 14px 18px; border-radius: 14px; min-width: 92px; text-align: center;
  box-shadow: var(--shadow-1);
  letter-spacing: 0.5px;
}
.team-meta h1 { font-size: 20px; margin: 0 0 6px; }
.chip {
  display: inline-block;
  font-size: 12px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: var(--bg-2); color: var(--navy);
  border: 1px solid var(--line);
}
.chip-Male     { background: #d8e3f0; color: #1a3a5c; border-color: #b9cce4; }
.chip-Female   { background: #f5d9e3; color: #832a4a; border-color: #e3b6c6; }
.chip-Mixed    { background: #e3dcf0; color: #4a3170; border-color: #c8bce0; }
.chip-Novice   { background: #d9ecd9; color: var(--forest-2); border-color: #b6d8b6; }
.chip-Novice3  { background: #cee3d0; color: var(--forest-2); border-color: #a8c9ab; }
.chip-Family   { background: #fbe2c5; color: #8a4a14; border-color: #f0c79a; }

.stats {
  display: grid; grid-template-columns: repeat(3,1fr); gap: 10px;
}
.stat {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 14px 8px; text-align: center;
  box-shadow: var(--shadow-1);
}
.stat-num   { font-size: 26px; font-weight: 800; color: var(--orange-2); letter-spacing: 0.5px; }
/* The elapsed-time chip turns red once we're past the event cut-off AND
   the team still hasn't scanned Finish — runners glance at it and know
   they're racking up penalty minutes. */
.stat-num.elapsed-over {
  color: var(--rust);
  animation: elapsed-blink 1.6s ease-in-out infinite;
}
@keyframes elapsed-blink { 50% { opacity: 0.55; } }
.stat-label { font-size: 11px; color: var(--muted); margin-top: 2px;
  text-transform: uppercase; letter-spacing: 0.5px; }

.action-card {
  display: flex; align-items: center; gap: 14px;
  background: var(--navy);
  color: #fdf6e3;
  padding: 18px; border-radius: var(--r-lg);
  text-decoration: none;
  box-shadow: var(--shadow-2);
  border: 1.5px solid var(--navy);
  position: relative; overflow: hidden;
}
.action-card::before {
  /* trail-marker stripe */
  content: ""; position: absolute; right: -12px; top: 0; bottom: 0; width: 36px;
  background: repeating-linear-gradient(135deg,
    var(--orange) 0 8px, transparent 8px 16px);
  opacity: 0.35;
}
.action-start { background: var(--forest); border-color: var(--forest-2); }
.action-scan  { background: var(--orange); border-color: var(--orange-2); color: #fffaf0; }
.action-icon  { font-size: 28px; line-height: 1; min-width: 38px; text-align: center; }
.action-title { font-weight: 800; font-size: 18px; letter-spacing: 0.3px; }
.action-sub   { font-size: 12px; opacity: 0.92; margin-top: 2px; }

.info-card {
  background: var(--paper); border: 1px solid var(--line);
  padding: 14px; border-radius: var(--r-md); box-shadow: var(--shadow-1);
}
.info-label { font-size: 11px; color: var(--forest); text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600; }
.info-val   { font-weight: 600; }
.info-thumb {
  margin-top: 10px; width: 100%; max-width: 200px;
  border-radius: 10px; border: 1px solid var(--line);
}

.scans-section { margin-top: 4px; }
.section-title {
  display: flex; justify-content: space-between; align-items: center;
  margin: 4px 0 10px;
  font-weight: 700; color: var(--navy);
}
.counter {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 999px; padding: 2px 10px; font-size: 12px; color: var(--muted);
}
.scan-list { display: grid; gap: 8px; }
.scan-row {
  /* 4 columns: bib-badge · info · selfie thumb · delete button. The delete
     col is `auto` so rows without the button (Start/Finish, pending-sync)
     collapse it to 0 with no visual gap. */
  display: grid; grid-template-columns: 60px 1fr 50px auto; gap: 10px;
  align-items: center;
  background: var(--paper); border: 1px solid var(--line);
  padding: 10px; border-radius: var(--r-md);
}
.scan-row:not(:has(.scan-thumb)) { grid-template-columns: 60px 1fr auto; }
.scan-pt {
  display: grid; place-items: center;
  text-align: center;
  background: var(--forest); color: #fdf6e3;
  border-radius: 12px;
  min-height: 48px;
  padding: 8px 6px;
  box-shadow: 0 2px 4px rgba(45,95,63,0.30);
}
.scan-pt-num { font-size: 22px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
/* Start / Finish use a word instead of a number — smaller font */
.scan-pt-word .scan-pt-num { font-size: 14px; letter-spacing: 0.5px; }
.scan-pt-finish { background: var(--rust); box-shadow: 0 2px 4px rgba(168,67,31,0.30); }
.scan-row-start  { border-color: var(--forest); background: #eaf6ec; }
.scan-row-finish { border-color: var(--rust);   background: #fbe9e2; }
.scan-row-pending { border-color: var(--amber); background: #fff8e6; }
/* Offline queue row — distinct from "GPS pending" so the runner sees this
   came from their own scan that hasn't uploaded yet (not awaiting admin). */
.scan-row-pending-sync {
  border: 1px dashed var(--amber);
  background: linear-gradient(135deg, #fff8e6, #ffeed3);
}
.scan-row-pending-sync .scan-pt-num {
  font-size: 22px; line-height: 1;
}

/* Cross-device live-sync indicator on the team header */
.sync-dot {
  display: inline-block; vertical-align: middle;
  font-size: 10px; line-height: 1;
  color: var(--forest);
  margin-left: 6px;
  animation: sync-pulse 2.4s ease-in-out infinite;
}
.sync-dot.stale { color: var(--rust); animation: none; }
.offline-ready  { display: inline-block; vertical-align: middle; font-size: 14px; margin-left: 4px; }
@keyframes sync-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
.scan-pt-pending { background: var(--amber); color: #1a1300; box-shadow: 0 2px 4px rgba(212,167,58,0.30); }
.scan-row-test   { border-color: #c8bce0; background: #f3eef9; }
.scan-pt-test    { background: #6d4cad; color: #fdf6e3; box-shadow: 0 2px 4px rgba(109,76,173,0.30); }

.shot-pending { outline: 2px solid var(--amber); }

/* Diagnostic page */
.diag-list { list-style: none; padding: 0; margin: 16px 0 0; }
.diag-list li {
  padding: 8px 12px; margin-bottom: 6px;
  border-radius: 10px; background: #fffaf0;
  border: 1px solid var(--line-soft); font-size: 13px;
}
.diag-list li[data-ok="1"]    { border-color: #b6d8b6; background: #eaf6ec; }
.diag-list li[data-ok="0"]    { border-color: #e3b6c6; background: #fbe9e2; }
.diag-list li[data-ok="warn"] { border-color: var(--amber); background: #fff8e6; }
.diag-list li b { font-weight: 700; color: var(--navy); margin-right: 6px; }
.diag-list li span { color: var(--ink-soft); word-break: break-word; }
.scan-label  { font-weight: 800; color: var(--forest-2); font-size: 18px; }
.scan-time   { font-size: 11px; color: var(--muted); margin-top: 2px; }
.scan-thumb  { width: 50px; height: 50px; object-fit: cover; border-radius: 8px; }
.empty       { color: var(--muted); padding: 14px; text-align: center; font-size: 14px; }

/* ───── Capture page ───── */
.capture-page { display: grid; gap: 10px; }
.capture-page h1 { font-size: 22px; }
.capture-page .page, .capture-page { padding-top: 8px; }
.camera-wrap {
  position: relative;
  width: 100%; aspect-ratio: 3/4;
  max-height: 55vh;
  max-width: 480px;          /* cap on wide screens (Z Fold inner, iPad) */
  margin: 6px auto;          /* centre when the column is wider */
  background: #111;
  border-radius: var(--r-lg); overflow: hidden;
  border: 2px solid var(--navy);
  box-shadow: var(--shadow-2);
}
.camera-wrap-big {
  /* Cap so the shutter button always fits in the same viewport — runners
     should never need to scroll to take the photo. The max-width keeps
     the camera selfie-shaped on Z Fold inner / Pixel Fold / iPad so it
     doesn't blow up to the full tablet width. */
  aspect-ratio: 3/4;
  max-height: 55vh;
  max-width: 480px;
}
@media (min-height: 740px) {
  .camera-wrap-big { aspect-ratio: 9/14; max-height: 58vh; }
}
/* Un-mirror the front-camera preview so what the runner sees matches what's
   saved. Toggled by JS when facingMode flips to 'user' (selfie phase). */
.camera-wrap video.cam-flipped { transform: scaleX(-1); }

.shoot-row {
  display: grid; gap: 8px;
  grid-template-columns: 1fr auto;
}
.shoot-main { font-size: 18px; }
.shoot-timer { font-size: 18px; min-width: 96px; }
.hint-hardware { font-size: 12px; text-align: center; margin: 4px 0 0; }
.gps-status {
  font-size: 12px; text-align: center; margin: 6px 0 0;
  font-weight: 600; color: var(--forest-2);
}
.gps-status.msg-err { color: var(--rust); }
.gps-status small { font-weight: 500; opacity: 0.8; }

/* Self-timer big countdown overlay */
.timer-overlay {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  color: #fff;
  font-size: clamp(120px, 28vw, 240px);
  font-weight: 900;
  text-shadow: 0 6px 24px rgba(0,0,0,0.6);
  background: rgba(0,0,0,0.35);
  pointer-events: none;
  font-variant-numeric: tabular-nums;
  animation: timer-pulse 1s ease-in-out infinite;
}
@keyframes timer-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.08); opacity: 0.85; }
}
.camera-wrap video, .camera-wrap img, .camera-wrap canvas {
  width: 100%; height: 100%; object-fit: cover;
}
.hidden { display: none !important; }
.cam-flip {
  position: absolute; top: 10px; right: 10px;
  background: rgba(0,0,0,0.55);
  color: #fff; border: 1px solid rgba(255,255,255,0.25);
  border-radius: 10px; padding: 7px 12px; font-size: 16px;
}
.scan-info-overlay {
  position: absolute; top: 10px; left: 10px; right: 60px;
  background: rgba(0,0,0,0.55);
  color: #fdf6e3;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.scan-info-overlay.scan-info-bad {
  background: rgba(168,67,31,0.85);
}
.reticle {
  position: absolute; inset: 16%;
  border: 3px solid rgba(253,246,227,0.85);
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.30);
  pointer-events: none;
  transition: border-color .15s, inset .2s;
}
.reticle.hit { border-color: #58d27a; inset: 14%; }
/* Pin the entire button stack (shoot / retake / confirm) to the bottom of
   the viewport so the runner never has to scroll to take or confirm the
   photo. Background fades into the page so the buttons don't look like a
   detached toolbar. Safe-area inset lifts the bar above the iOS home-bar. */
.capture-actions {
  display: grid; gap: 10px;
  position: fixed;
  left: 12px; right: 12px;
  bottom: max(10px, env(safe-area-inset-bottom));
  z-index: 20;
  background: linear-gradient(to top,
    rgba(253, 246, 227, 0.97) 70%,
    rgba(253, 246, 227, 0));
  padding: 14px 6px 6px;
}
/* Reserve space at the bottom of the page so the fixed button bar doesn't
   overlap the back button / hints / msg area when the page is scrolled. */
.capture-page { padding-bottom: 140px; }
.qr-detected {
  background: #e8f3dd;
  border: 1.5px solid #b3d99b;
  padding: 12px 14px; border-radius: var(--r-md);
}
.qr-detected-row { display: flex; justify-content: space-between; align-items: center; }
.qr-detected-code   { font-weight: 800; color: var(--forest-2); letter-spacing: 0.5px; font-size: 20px; }
.qr-detected-points { font-weight: 800; color: var(--orange-2); font-size: 22px; }
.qr-detected-label  { font-size: 13px; color: var(--muted); margin-top: 2px; }

/* ───── Leaderboard ───── */
.board-page { padding-top: 6px; }
.board-page h1 { text-align: center; font-size: 30px; margin-top: 6px; }
.board-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .board-grid { grid-template-columns: 1fr 1fr; } }

.board-card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 16px;
  box-shadow: var(--shadow-1);
  position: relative; overflow: hidden;
}
.board-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  background: var(--navy);
}
.board-card[data-tt="Male Team"]::before     { background: #1a3a5c; }
.board-card[data-tt="Female Team"]::before   { background: #b94776; }
.board-card[data-tt="Mixed Team"]::before    { background: #6d4cad; }
.board-card[data-tt="Novice Team"]::before   { background: var(--forest); }
.board-card[data-tt="Novice Team 3"]::before { background: var(--forest-2); }
.board-card[data-tt="Family Team 3"]::before { background: var(--orange); }

.board-head {
  font-weight: 800; font-size: 17px; margin-bottom: 10px;
  padding-bottom: 8px; border-bottom: 1px dashed var(--line);
  color: var(--navy);
}
.board-head small { display: block; font-size: 11px; color: var(--muted); font-weight: 500; letter-spacing: 0.5px; }

.board-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.board-row {
  display: grid; grid-template-columns: 32px 1fr auto; gap: 10px;
  align-items: center; padding: 9px 12px;
  background: #fffaf0; border: 1px solid var(--line-soft);
  border-radius: 10px;
}
.board-row .rank { text-align: center; font-weight: 800; color: var(--muted); }
.board-row .name b { display: block; color: var(--navy); }
.board-row .name small { color: var(--muted); font-size: 11px; }
.board-row .pts { font-weight: 800; color: var(--orange-2); font-size: 16px; }

.board-row.podium { font-weight: 700; }
.board-row.podium-1 {
  background: linear-gradient(135deg, #fbe5ad, #fff5d4);
  border: 1.5px solid var(--gold);
}
.board-row.podium-1 .rank { color: var(--gold); }
.board-row.podium-2 {
  background: linear-gradient(135deg, #ececec, #f8f8f8);
  border: 1.5px solid var(--silver);
}
.board-row.podium-2 .rank { color: var(--silver); }
.board-row.podium-3 {
  background: linear-gradient(135deg, #f0d4b3, #faecda);
  border: 1.5px solid var(--bronze);
}
.board-row.podium-3 .rank { color: var(--bronze); }

/* ───── Admin ───── */
/* Admin pages override base.html's 720px .page clamp so wide tables /
   admin-grid get their full 1100px on desktop. Inside, everything is
   center-aligned for a tidy column-style layout (asked for June 2026). */
body.admin-bg .page { max-width: none; padding: 18px 12px 96px; }
.admin-page { max-width: 1100px; margin: 0 auto; padding: 18px; }
.admin-header {
  display: flex; flex-direction: column; align-items: center;
  gap: 14px; text-align: center;
}
.admin-header h1 { margin: 0; }
.admin-actions {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
}
/* Center the meta strip + sync results banners with the rest of the page.
   .sync-info is a flex container by default — override justify-content too,
   not just text-align. */
.admin-page .sync-info {
  justify-content: center;
  text-align: center;
}
/* Section blocks stay left-aligned internally (tables look weird centered),
   but the block container itself is centered on the page via its grid. */
.admin-grid { display: grid; gap: 16px; margin-top: 18px; grid-template-columns: 1fr; }
@media (min-width: 900px) { .admin-grid { grid-template-columns: 1.4fr 1fr; } }
.admin-block {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 16px;
  box-shadow: var(--shadow-1);
}
.admin-block-wide { grid-column: 1 / -1; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th, .tbl td { padding: 9px 8px; border-bottom: 1px solid var(--line-soft); text-align: left; }
.tbl th { font-size: 11px; color: var(--forest); text-transform: uppercase; letter-spacing: 0.5px; }
.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; max-height: 480px; }
.row-dim { opacity: 0.5; }
.pill { font-size: 11px; padding: 2px 8px; border-radius: 999px; font-weight: 600; }
.pill.ok  { background: #d9ecd9; color: var(--forest-2); }
.pill.off { background: #f2cbc7; color: #8a1f15; }

.qr-add {
  display: grid; grid-template-columns: 1fr 1.4fr 70px 1fr auto;
  gap: 6px; margin-bottom: 12px;
}
.qr-add input { padding: 9px 10px; font-size: 14px; }
@media (max-width: 720px) {
  .qr-add { grid-template-columns: 1fr 1fr; }
  .qr-add button { grid-column: 1 / -1; }
}

.podium-grid {
  display: grid; gap: 12px; grid-template-columns: 1fr 1fr;
}
@media (min-width: 720px) { .podium-grid { grid-template-columns: repeat(3,1fr); } }
@media (min-width: 1000px){ .podium-grid { grid-template-columns: repeat(6,1fr); } }
.podium-card {
  background: #fffaf0; border: 1px solid var(--line); border-radius: 14px; padding: 12px;
}
.podium-card h3 { font-size: 12px; }
.podium-card ol { list-style: decimal; padding-left: 22px; margin: 0; }
.podium-card li { margin: 6px 0; display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 6px; font-size: 13px; }
.podium-card li span { color: var(--orange-2); font-weight: 800; }

.info-grid {
  display: grid; gap: 10px; margin-top: 12px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
.info-grid > div { background: #fffaf0; border: 1px solid var(--line); padding: 10px; border-radius: 12px; }
.info-grid label { font-size: 11px; color: var(--forest); text-transform: uppercase; }
.info-grid .big { font-size: 22px; font-weight: 800; color: var(--orange-2); }
.admin-shot { max-width: 320px; border-radius: 12px; border: 1px solid var(--line); }
.muted { color: var(--muted); font-size: 12px; }

.shot-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(180px,1fr));
}
.shot-card { background: #fffaf0; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.shot-card img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.shot-empty { aspect-ratio: 1; display: grid; place-items: center; color: var(--muted); font-size: 12px; }
.shot-meta { padding: 10px; font-size: 13px; }
.shot-meta small { display: block; color: var(--muted); font-size: 11px; }

.sync-info {
  background: #fffaf0; border: 1px solid var(--line); padding: 10px 14px;
  border-radius: 12px; font-size: 13px; color: var(--muted);
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.sync-info b { color: var(--forest); }

/* ───── Language switcher (runner-facing pages) ───── */
.lang-row {
  display: flex; gap: 8px; justify-content: flex-end;
  margin: -8px 0 14px;
}
.lang-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 700;
  text-decoration: none; color: var(--muted);
  border: 1.5px solid var(--line);
  background: var(--paper);
  transition: background .15s, border-color .15s, color .15s;
}
.lang-pill:hover { background: #fff; color: var(--navy); }
.lang-pill.active {
  background: var(--navy); color: #fdf6e3;
  border-color: var(--navy);
  box-shadow: var(--shadow-1);
}

/* ───── PWA install hint ───── */
.install-box {
  margin-top: 16px;
  padding: 10px 14px;
  background: #fffaf0;
  border: 1.5px dashed var(--orange);
  border-radius: var(--r-md);
}
.install-summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--navy);
  list-style: none;
  outline: none;
}
.install-summary::-webkit-details-marker { display: none; }
.install-summary::after { content: " ▾"; opacity: 0.5; font-size: 12px; }
details[open] .install-summary::after { content: " ▴"; }
.install-hint {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-soft);
}
/* Used on iOS Chrome/Firefox/etc — runners on these browsers literally
   cannot install the app, so the message needs to look like a warning,
   not just a tip. */
.install-hint-warn {
  margin: 10px 0 0;
  padding: 10px 12px;
  background: #fbe2c5;
  border-left: 4px solid #d6822a;
  border-radius: 8px;
  color: #6e3b0d;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.55;
}
.copy-ok {
  display: block;
  margin: 6px 0 0;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--forest-2);
  animation: fade-in 0.2s;
}
@keyframes fade-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; } }

/* Centered confirm modal — used by the runner's "Log out" button. The
   backdrop dims everything; the card holds just the question + two buttons,
   so the runner doesn't see a "navitrail.lyvia.run" origin header that
   native window.confirm() would force. */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(20, 24, 35, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  z-index: 1000;
  animation: fade-in 0.15s ease-out;
}
.modal-card {
  background: var(--paper);
  border-radius: 16px;
  padding: 22px 22px 16px;
  max-width: 360px; width: 100%;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35);
}
.modal-msg {
  margin: 0 0 18px;
  font-size: 17px;
  color: var(--navy);
  text-align: center;
  font-weight: 600;
  line-height: 1.5;
}
.modal-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.modal-actions .btn { margin: 0; }

/* Tiny inline pulse for the Confirm-while-uploading state. The button is
   already showing "✓ บันทึกแล้ว" — this dot just signals "still working". */
.spinner-dot {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: currentColor;
  margin-right: 8px;
  animation: pulse-dot 0.9s ease-in-out infinite;
  vertical-align: middle;
}
@keyframes pulse-dot {
  0%, 100% { transform: scale(0.6); opacity: 0.5; }
  50%      { transform: scale(1);   opacity: 1;   }
}

/* Manual-entry escape hatch. Looks deliberately understated (dashed border,
   amber accent) so it doesn't compete with the camera but a runner with a
   wet/muddy/faded QR can find it quickly. */
.manual-entry-btn {
  border: 1.5px dashed var(--amber);
  background: rgba(255, 248, 230, 0.5);
  color: #6e3b0d;
  font-weight: 700;
  font-size: 14px;
  padding: 12px 14px;
}
.manual-entry-btn:hover, .manual-entry-btn:focus {
  background: #fff8e6;
  border-style: solid;
}

/* Inline trash icon at the right edge of each scan row on the team page.
   Quiet styling (no border, no fill, low-opacity text) so it doesn't look
   like a primary action — the runner has to deliberately look for it. */
/* Round red destroy button — placed in the rightmost grid column so it
   sits right next to the selfie thumb. Bigger tap target (36×36) than a
   bare icon, but still clearly an "ancillary" action vs the main row. */
.scan-del-btn {
  width: 25px; height: 25px;
  display: inline-grid; place-items: center;
  background: var(--rust);
  color: #fff;
  border: none;
  border-radius: 50%;
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(168, 67, 31, 0.30);
  align-self: center;
  transition: transform .12s, background .12s, box-shadow .12s;
  -webkit-tap-highlight-color: transparent;
}
.scan-del-btn:hover,
.scan-del-btn:focus {
  background: #8a2a13;
  box-shadow: 0 3px 8px rgba(168, 67, 31, 0.45);
}
.scan-del-btn:active { transform: scale(0.92); }

/* Fallback /upload page — selected-photos preview grid. */
.upload-thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px;
  margin: 8px 0 12px;
  padding: 8px;
  background: #fffaf0;
  border: 1px dashed var(--line);
  border-radius: 10px;
}
.upload-thumb img {
  width: 100%; aspect-ratio: 3/4; object-fit: cover;
  border-radius: 8px; background: #222;
}
.upload-thumb-meta {
  font-size: 11px; color: var(--ink-soft); margin-top: 4px;
  text-align: center; line-height: 1.3;
}

/* ───── Back button below camera ───── */
.back-below-cam {
  margin-top: 14px;
  padding: 14px 18px;
  font-size: 16px;
}

/* ───── Landing / role picker ───── */
.landing-card h1 { font-size: 36px; text-align: center; margin: 18px 0 4px; }
.landing-card .lead { text-align: center; }

.role-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin: 18px 0 16px;
}
.role-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  padding: 22px 14px;
  text-decoration: none;
  border-radius: var(--r-lg);
  border: 2px solid var(--navy);
  background: var(--paper);
  color: var(--navy);
  transition: transform .08s, box-shadow .15s, background .15s;
  box-shadow: var(--shadow-1);
  text-align: center;
  position: relative; overflow: hidden;
}
.role-card:active { transform: translateY(1px); }
.role-card::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
}
.role-runner {
  background: linear-gradient(160deg, var(--forest) 0%, var(--forest-2) 100%);
  color: #fdf6e3; border-color: var(--forest-2);
}
.role-runner::after { background: repeating-linear-gradient(45deg, var(--orange) 0 8px, transparent 8px 16px); }
.role-staff {
  background: linear-gradient(160deg, var(--navy) 0%, #112338 100%);
  color: #fdf6e3; border-color: var(--navy);
}
.role-staff::after { background: var(--amber); }
.role-icon  { font-size: 38px; line-height: 1; }
.role-title { font-weight: 800; font-size: 18px; }
.role-sub   { font-size: 12px; opacity: 0.85; }

.staff-actions { display: grid; gap: 10px; margin: 16px 0; }
.action-staff { background: var(--navy); border-color: var(--navy); }
.action-board { background: var(--amber); color: var(--navy); border-color: #b08820; }
.action-board::before { background: repeating-linear-gradient(135deg, var(--navy) 0 8px, transparent 8px 16px); opacity: 0.25; }
.action-clock { background: var(--rust); color: #fff; border-color: var(--rust); }

/* ───── Event clock (staff control + runner team page) ───── */
.clock-row {
  display: grid; gap: 14px;
  grid-template-columns: 1fr;
  margin: 18px 0;
}
@media (min-width: 780px) { .clock-row { grid-template-columns: 1fr 1fr; } }

.clock-hero {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  padding: 22px 18px;
  text-align: center;
  box-shadow: var(--shadow-2);
  margin: 0;
}
.clock-hero + .clock-hero, .clock-row > .clock-hero { margin: 0; }
.clock-hero.clock-state-idle      { border-color: var(--line); }
.clock-hero.clock-state-scheduled { border-color: var(--amber); background: #fff8e6; }
.clock-hero.clock-state-running   { border-color: var(--forest); background: #eaf6ec; }
.clock-hero.clock-state-ended     { border-color: var(--rust);   background: #fbe9e2; }

.clock-state-label {
  font-size: 13px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 6px;
}
.clock-big {
  font-size: 56px; font-weight: 800; letter-spacing: 1.5px;
  font-variant-numeric: tabular-nums;
  color: var(--navy); line-height: 1.05;
}
.clock-state-running .clock-big { color: var(--forest-2); }
.clock-state-scheduled .clock-big { color: #8a6a14; }
.clock-state-ended .clock-big { color: var(--rust); }
.clock-sub { margin-top: 6px; font-size: 13px; color: var(--muted); }

.row-form {
  display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: center;
}
.row-form input[type="datetime-local"] { padding: 11px 12px; font-size: 14px; }
.row-form-3 {
  display: grid; gap: 8px; align-items: end;
  grid-template-columns: repeat(auto-fit, minmax(140px,1fr));
}

/* Pills for QR kind */
.pill-start  { background: #fbe2c5; color: #8a4a14; }
.pill-finish { background: #f2cbc7; color: #8a1f15; }
.pill-test   { background: #e3dcf0; color: #4a3170; }

/* Penalty card on team page */
.stat-sub-bad { font-size: 11px; font-weight: 700; color: #a8221b; margin-top: 2px; }
.penalty-card {
  background: #fbe9e2; border: 1.5px solid var(--rust);
  border-radius: var(--r-md); padding: 14px; box-shadow: var(--shadow-1);
}
.penalty-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.penalty-title { font-weight: 700; color: var(--rust); }
.penalty-sub   { font-size: 12px; color: var(--muted); margin-top: 2px; }
.penalty-amount {
  font-size: 26px; font-weight: 800; color: var(--rust);
  font-variant-numeric: tabular-nums;
}

/* Bonus card (special points awarded/deducted by staff — multiple entries) */
.bonus-card {
  background: #eaf6ec; border: 1.5px solid var(--forest);
  border-radius: var(--r-md); padding: 14px; box-shadow: var(--shadow-1);
}
.bonus-card-head {
  display: flex; justify-content: space-between; align-items: center;
  padding-bottom: 8px;
  border-bottom: 1px dashed rgba(45,95,63,0.25);
}
.bonus-title { font-weight: 700; color: var(--forest-2); }
.bonus-amount {
  font-size: 26px; font-weight: 800; color: var(--forest-2);
  font-variant-numeric: tabular-nums;
}
.bonus-list-runner {
  list-style: none; padding: 0; margin: 8px 0 0;
  display: grid; gap: 6px;
}
.bonus-list-runner li {
  display: grid; grid-template-columns: 52px 1fr; gap: 10px;
  align-items: center; font-size: 14px;
}
.bonus-pts {
  text-align: center;
  font-weight: 800; color: var(--forest-2);
  background: #fffaf0; border: 1px solid #b6d8b6;
  padding: 4px 6px; border-radius: 8px;
  font-variant-numeric: tabular-nums;
}
.bonus-pts.neg { color: var(--rust); border-color: #e8b9a5; }
.bonus-line-reason { color: var(--ink); word-break: break-word; }

/* Admin bonus list view */
.bonus-list { display: grid; gap: 8px; }
.bonus-item {
  display: grid; grid-template-columns: 70px 1fr auto; gap: 10px;
  align-items: center;
  background: #fffaf0;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  padding: 10px 12px;
}
.bonus-reason-text { font-weight: 600; }

.finish-card { border-color: var(--forest-2); background: #eaf6ec; }

/* ───── Admin teams: filter chips ───── */
.filter-chips {
  display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px;
}
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--paper);
  color: var(--navy);
  text-decoration: none;
  font-weight: 600; font-size: 14px;
  transition: background .15s, border-color .15s;
}
.filter-chip:hover { background: #fff; }
.filter-chip.active {
  background: var(--navy); color: #fdf6e3; border-color: var(--navy);
  box-shadow: var(--shadow-1);
}
.filter-chip .chip-count {
  background: rgba(0,0,0,0.10); color: inherit;
  padding: 1px 8px; border-radius: 999px;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.filter-chip.active .chip-count {
  background: rgba(255,255,255,0.20);
}

.last-point-num {
  display: inline-block;
  background: var(--forest); color: #fdf6e3;
  padding: 3px 10px; border-radius: 8px;
  font-weight: 800; font-variant-numeric: tabular-nums;
}
.row-finished { opacity: 0.7; background: rgba(232,243,221,0.25); }

/* Compact event clock on runner team page */
.event-clock {
  border-radius: var(--r-lg); padding: 12px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 2px solid var(--line);
  box-shadow: var(--shadow-1);
}
.event-clock-scheduled { background: #fff8e6; border-color: var(--amber); }
.event-clock-running   { background: #eaf6ec; border-color: var(--forest); }
.event-clock-ended     { background: #fbe9e2; border-color: var(--rust); }
.event-clock-label { font-weight: 700; font-size: 14px; color: var(--ink-soft); }
.event-clock-big   { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--navy); }
.event-clock-running .event-clock-big   { color: var(--forest-2); }
.event-clock-scheduled .event-clock-big { color: #8a6a14; }
.event-clock-ended .event-clock-big     { color: var(--rust); }

/* ───── Points grid (team page) ───── */
.points-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(36px, 1fr));
  gap: 6px;
  margin-top: 8px;
}
.pt-chip {
  display: flex; align-items: center; justify-content: center;
  height: 34px;
  border-radius: 9px;
  background: #ece2c5;
  border: 1px solid var(--line);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  font-size: 13px; font-weight: 600;
}
.pt-chip.pt-on {
  background: var(--forest); color: #fdf6e3; border-color: var(--forest-2);
  box-shadow: 0 2px 4px rgba(45,95,63,0.30);
}

/* ───── Points heatmap (admin overview) ───── */
.points-heatmap {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 6px;
}
.pt-cell {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  height: 54px;
  border-radius: 10px;
  text-decoration: none;
  border: 1px solid var(--line);
  background: #f4eada;
  color: var(--ink);
  transition: transform .08s;
}
.pt-cell:active { transform: scale(0.96); }
.pt-cell .pt-num { font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; }
.pt-cell .pt-cnt { font-size: 10px; font-weight: 600; opacity: 0.85; margin-top: 1px; }
.pt-heat-0 { background: #f4eada; color: #8a8062; }
.pt-heat-1 { background: #e7e8c4; color: #5a6b1f; }
.pt-heat-2 { background: #d3df9b; color: #44560f; }
.pt-heat-3 { background: #b0d290; color: #2e4314; border-color: #91b773; }
.pt-heat-4 { background: #6bb069; color: #0e2410; border-color: #4a9047; }
.pt-heat-5 { background: var(--forest-2); color: #fdf6e3; border-color: #143820; }

/* ───── Team chips (drill-down) ───── */
.team-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 8px;
}
.team-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  font-size: 12px;
  text-decoration: none; color: var(--navy);
}
.team-chip b { font-variant-numeric: tabular-nums; }
.team-chip:hover { background: #fff; }

/* Progress bar */
.bar {
  width: 120px; height: 8px;
  background: #ece2c5; border-radius: 999px;
  overflow: hidden; border: 1px solid var(--line-soft);
}
.bar-fill { height: 100%; background: var(--forest); }

/* ───── In-app browser warning (FB / LINE / Messenger / IG / TikTok) ───── */
.inapp-warn {
  position: sticky; top: 0; z-index: 11;
  background: linear-gradient(135deg, var(--rust), #c45f1f);
  color: #fff;
  padding: 12px 14px;
  border-bottom: 1px solid rgba(0,0,0,0.18);
  box-shadow: 0 3px 8px rgba(0,0,0,0.18);
}
.inapp-warn-inner { max-width: 760px; margin: 0 auto; }
.inapp-warn-title { font-weight: 800; font-size: 14px; }
.inapp-warn-body  { font-size: 13px; margin-top: 4px; opacity: 0.95; line-height: 1.5; }
.inapp-warn-hint  { font-size: 12px; margin-top: 6px; opacity: 0.95; }
.inapp-warn-actions {
  display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;
}
.inapp-warn-actions .btn-primary { background: #fff; color: var(--rust); border-color: #fff; }
.inapp-warn-actions .btn-ghost   { background: transparent; color: #fff; border-color: rgba(255,255,255,0.4); }
.inapp-copied {
  display: block; margin-top: 8px; font-size: 12px; font-weight: 700;
  background: rgba(255,255,255,0.18); padding: 4px 10px; border-radius: 999px;
  width: max-content;
}

/* ───── Net banner ───── */
.net-banner {
  position: sticky; top: 0; z-index: 10;
  background: var(--orange);
  color: #fffaf0;
  padding: 8px 14px;
  font-size: 13px; font-weight: 600;
  display: flex; align-items: center; gap: 8px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.10);
}
.net-banner.online { background: var(--forest); color: #fffaf0; }
.net-banner .dot { width: 8px; height: 8px; border-radius: 999px; background: currentColor; }
.queue-badge {
  background: rgba(255,255,255,0.25);
  padding: 2px 10px; border-radius: 999px; margin-left: auto;
  font-variant-numeric: tabular-nums;
}
