:root {
  --bg: #0a0b0d;
  --bg-raised: #131519;
  --bg-hover: #1c1f25;
  --border: #24282f;
  --text: #eceef0;
  --text-dim: #9aa1ab;
  --text-faint: #5c626c;
  --amber: #f5a623;
  --amber-dim: #8a5f18;
  --error: #ef4444;
  --live: #e0392c;
  --live-green: #22c55e;
  --live-green-dim: rgba(34, 197, 94, 0.16);
  --font-display: "Bebas Neue", "Arial Narrow", sans-serif;
  --font-body: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
}

* {
  box-sizing: border-box;
}

/* No-page-scroll shell: html/body are pinned to exactly the viewport
   height (not min-height, which would let content stretch them and scroll
   the page) and never scroll themselves. Every flex ancestor of a
   scrollable region below also gets min-height: 0, since without it a flex
   item's default min-height: auto lets its content force the item (and
   therefore its parents, up to body) to grow past its share of the flex
   box instead of clipping/scrolling internally. Only .game-list (always)
   and .video-wrap (narrow/mobile only, see the media query below) are
   allowed overflow-y: auto. */
html, body {
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

button {
  font-family: var(--font-body);
  cursor: pointer;
}

[hidden] {
  display: none !important;
}

/* ---------- Gate ---------- */

.gate {
  height: 100%;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(circle at 50% 0%, rgba(245, 166, 35, 0.08), transparent 60%),
    var(--bg);
}

.gate-card {
  width: 100%;
  max-width: 360px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 40px 32px;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.gate-brand {
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  font-size: 1.4rem;
  color: var(--text);
  margin-bottom: 24px;
}

.gate-brand span {
  color: var(--amber);
}

.gate-card h1 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.03em;
  font-size: 1.9rem;
  margin: 0 0 24px;
  color: var(--text);
}

#loginForm {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

#codeInput {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  letter-spacing: 0.5em;
  text-align: center;
  padding: 14px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
}

#codeInput:focus {
  outline: none;
  border-color: var(--amber);
}

#loginForm button {
  padding: 14px;
  border-radius: 10px;
  border: none;
  background: var(--amber);
  color: #1a1200;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.02em;
  transition: filter 0.15s ease;
}

#loginForm button:hover {
  filter: brightness(1.08);
}

.error {
  color: var(--error);
  font-size: 0.85rem;
  margin: 16px 0 0;
}

/* ---------- Player shell ---------- */

.player {
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
}

.brand {
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  font-size: 1.2rem;
}

.brand span {
  color: var(--amber);
}

.pbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.info-wrap {
  position: relative;
}

#infoBtn {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg-hover);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-style: italic;
  font-weight: 700;
}

#infoBtn:hover {
  color: var(--amber);
  border-color: var(--amber-dim);
}

#signOutBtn {
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  font-size: 0.85rem;
}

#signOutBtn:hover {
  color: var(--text);
  border-color: var(--text-dim);
}

.stats-pop {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  min-width: 190px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}

.stats-pop div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 4px 0;
  font-size: 0.8rem;
}

.stats-pop span {
  color: var(--text-faint);
}

.stats-pop b {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--amber);
}

/* ---------- Broadcast scoreboard strip ---------- */

.scoreboard-strip {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 28px;
  border-bottom: 1px solid var(--border);
  /* background is set per-game from JS as a low-opacity team-color wash
     over var(--bg-raised) (see renderScoreboardStrip in app.js) */
  background: var(--bg-raised);
}

.ss-team {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex: 1;
}

.ss-home {
  justify-content: flex-end;
}

/* Compound selector (.team-logo.ss-logo) so this reliably beats the plain
   .team-logo rule below regardless of source order — the <img> always
   carries both classes (see teamLogoImg's extraClassName param in app.js). */
.team-logo.ss-logo {
  width: 46px;
  height: 46px;
  object-fit: contain;
  flex-shrink: 0;
}

.ss-name {
  font-family: var(--font-display);
  letter-spacing: 0.02em;
  font-size: 1.05rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ss-center {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 140px;
}

.ss-score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.8rem;
  line-height: 1;
  color: var(--text);
}

.ss-status {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.ss-status.is-live {
  color: var(--live-green);
  font-weight: 700;
}

.ss-status.is-pre {
  color: var(--amber);
}

/* ---------- Stage layout ---------- */

.stage {
  flex: 1;
  display: flex;
  min-height: 0;
  overflow: hidden;
}

.video-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

#video {
  width: 100%;
  height: 100%;
  max-height: calc(100vh - 56px);
  background: #000;
  display: block;
}

.player-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-faint);
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: 0.04em;
  pointer-events: none;
}

.next-feed {
  position: absolute;
  right: 12px;
  bottom: 56px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(19, 21, 25, 0.85);
  color: var(--text);
  font: 500 13px var(--font-body);
  cursor: pointer;
}
.next-feed:hover { border-color: var(--amber); }
.next-feed:disabled { opacity: 0.5; cursor: default; }

/* ---------- Rail ---------- */

.rail {
  width: 340px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--border);
  background: var(--bg-raised);
  min-height: 0;
}

#searchBox {
  margin: 14px 14px 10px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-size: 0.9rem;
}

#searchBox:focus {
  outline: none;
  border-color: var(--amber);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 14px 12px;
}

.chip {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.chip:hover {
  border-color: var(--text-dim);
  color: var(--text);
}

.chip.active {
  background: var(--amber);
  border-color: var(--amber);
  color: #1a1200;
}

.game-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 8px 14px;
}

.game-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 10px 6px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.team-logo {
  width: 18px;
  height: 18px;
  object-fit: contain;
  flex-shrink: 0;
}

.matchup .team-logo {
  width: 26px;
  height: 26px;
}

/* Pulse-ring live indicator: a solid dot with an expanding, fading ring
   behind it. Disabled entirely under prefers-reduced-motion below. */
.pulse-dot {
  position: relative;
  display: inline-flex;
  width: 8px;
  height: 8px;
  flex-shrink: 0;
}

.pulse-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--live-green);
}

.pulse-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--live-green);
  animation: pulse-ring 1.6s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(1);
    opacity: 0.6;
  }
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pulse-ring {
    animation: none;
    opacity: 0;
  }
}

.game-row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 10px 12px 16px;
  border-radius: 10px;
  cursor: pointer;
  border: 1px solid transparent;
  overflow: hidden;
}

/* Thin top-to-bottom accent bar, away-team color to home-team color (or the
   default accent for any team missing from team-colors.js — always true
   for NCAAF). Set per-row from JS via the --row-accent custom property;
   the var()'s own fallback covers a row rendered before JS ever sets it. */
.game-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--row-accent, var(--amber));
}

.game-row:hover {
  background: var(--bg-hover);
  border-color: var(--border);
}

.game-row.playing {
  border-color: var(--amber-dim);
  background: rgba(245, 166, 35, 0.08);
}

/* A live game gets a faint green glow/inset-border so it visually stands
   out from scheduled games at a glance, on top of whatever .playing state
   it's also in. */
.game-row.is-live {
  box-shadow: inset 0 0 0 1px rgba(34, 197, 94, 0.35), 0 0 16px var(--live-green-dim);
}

/* B2/B3: every stream for this game is currently the provider's offline
   slate. Dimmed but still clickable (a viewer may want to check anyway, or
   the feed may already be back by the time they tap it). */
.game-row.is-offline {
  opacity: 0.45;
}

.offline-tag {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  text-transform: uppercase;
}

/* B2: a final game is dimmed the same way an offline one is -- unwatchable
   either way, just for a different (permanent) reason. */
.game-row.is-final {
  opacity: 0.45;
}

.final-tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text);
  text-transform: uppercase;
}

.game-row-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.game-league {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  text-transform: uppercase;
}

.game-status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--text-dim);
}

.game-status.is-live {
  color: var(--live-green);
  font-weight: 700;
}

.live-score-line {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-dim);
}

.live-score-line .leading {
  color: var(--live-green);
}

/* B2: a final game's score line -- winner's score bold/bright, loser stays
   the section's default dim color (no green; the game isn't live). */
.live-score-line.is-final .leading {
  color: var(--text);
  font-weight: 800;
}

.live-score-dash {
  color: var(--text-faint);
  font-weight: 400;
}

.matchup {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.matchup-team {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 0.92rem;
  min-width: 0;
}

.matchup-team .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.matchup-team .score {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--text);
}

.fav-star {
  flex-shrink: 0;
  border: none;
  background: transparent;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  color: var(--text-faint);
}

.fav-star:hover {
  color: var(--text-dim);
}

.fav-star[aria-pressed="true"] {
  color: var(--amber);
}

.fav-star:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

.matchup-at {
  color: var(--text-faint);
  font-size: 0.75rem;
  padding: 0 2px;
}

.game-empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--text-faint);
  font-size: 0.85rem;
}

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  .stage {
    flex-direction: column;
  }

  .rail {
    width: 100%;
    border-left: none;
    border-top: 1px solid var(--border);
    max-height: 45vh;
  }

  #video {
    max-height: 40vh;
  }

  /* On a short/narrow viewport the video column can still end up taller
     than its share of the stage (video + feed picker + hint). It scrolls
     internally rather than pushing .rail off-screen or growing .stage (and
     therefore body) past 100%. */
  .video-wrap {
    overflow-y: auto;
  }

  .scoreboard-strip {
    padding: 8px 14px;
    gap: 8px;
  }

  .team-logo.ss-logo {
    width: 30px;
    height: 30px;
  }

  .ss-name {
    font-size: 0.85rem;
  }

  .ss-score {
    font-size: 1.3rem;
  }

  .ss-center {
    min-width: 90px;
  }
}
