@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=Exo+2:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

:root {
  /* Surfaces */
  --void: #05080f;
  --hull: #0b1120;
  --panel: #111a2e;
  --panel-alt: #162036;
  --console: #0d1526;

  /* LCARS accents */
  --lcars-amber: #f4a927;
  --lcars-orange: #e87420;
  --lcars-peach: #f5c07a;
  --lcars-mauve: #cc99cc;

  /* Data accents */
  --data-cyan: #00e5ff;
  --data-teal: #06b6d4;
  --data-blue: #3b82f6;
  --data-indigo: #8b5cf6;

  /* Status */
  --status-green: #00e676;
  --status-yellow: #ffd740;
  --status-red: #ff1744;

  /* Text — tuned for WCAG AA against --void (#05080f).
     Mirrors the bfanetworks.com typography pass so the two sites read at the
     same contrast level.
       text-primary   (#e8edf5) ≈ 16.8:1  AAA at any size
       text-secondary (#b6c2d6) ≈  9.4:1  AAA at any size
       text-muted     (#8c9bb3) ≈  5.4:1  AA  body / AAA large
       text-faint     (#5e6e87) ≈  3.0:1  large / decorative microcopy only
                                          (e.g. STARDATE chips, "soon" pills) */
  --text-primary: #e8edf5;
  --text-secondary: #b6c2d6;
  --text-muted: #8c9bb3;
  --text-faint: #5e6e87;
  --text-on-chrome: #0b1120;

  /* Borders & glows */
  --border-dim: rgba(148, 163, 184, 0.1);
  --border-panel: rgba(244, 169, 39, 0.2);
  --border-active: rgba(0, 229, 255, 0.5);
  --glow-cyan: rgba(0, 229, 255, 0.4);
  --glow-amber: rgba(244, 169, 39, 0.35);
  --glow-green: rgba(0, 230, 118, 0.35);
  --glow-red: rgba(255, 23, 68, 0.35);

  /* Fonts */
  --font-display: 'Orbitron', sans-serif;
  --font-body: 'Exo 2', sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;

  /* Layout */
  --container: 1280px;
  --topbar-h: 64px;
  --radius-panel: 14px;
  --radius-card: 10px;
  --radius-pill: 999px;

  /* Sport accent colors — assigned per sport */
  --sport-basketball: #ff7a00;
  --sport-soccer: #00e676;
  --sport-football: #a0522d;
  --sport-baseball: #f4a927;
  --sport-hockey: #00e5ff;
  --sport-volleyball: #ffd740;
  --sport-lacrosse: #8b5cf6;
  --sport-rugby: #e87420;
  --sport-wrestling: #ff1744;
  --sport-track: #06b6d4;
}

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

/* Bump the rem base ~6.25% (browser default 16px → 17px) so all rem-based
   text and spacing reads a touch larger across the site. Matches the
   bfanetworks.com bump so the two BFA properties feel at the same scale.
   Using a percentage (not px) so user/OS font-size accessibility prefs
   still cascade proportionally on top.
     text-xs   → 12.75px
     text-sm   → 14.875px
     text-base → 17px
     text-lg   → 19.125px
     text-xl   → 21.25px
   Layout proportions are preserved because everything (max-widths, paddings,
   gaps) scales together via rem; only the chrome heights pinned in px stay
   put. */
html {
  font-size: 106.25%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  text-rendering: optimizeLegibility;
}

body {
  font-family: var(--font-body);
  background: var(--void);
  color: var(--text-primary);
  min-height: 100vh;
  line-height: 1.55;
}

/* Mobile (<768px): loosen paragraph leading on narrow columns so body copy
   still breathes. The base 17px rem bump already scales every other
   rem-based size up ~6%, which is enough for the micro-text used in
   stardate chips, panel labels, and badges (all defined in rem above) — no
   per-class overrides needed. Mirrors the bfanetworks.com mobile rule. */
@media (max-width: 767px) {
  p { line-height: 1.65; }
}

a { color: var(--data-cyan); text-decoration: none; }
a:hover { color: var(--text-primary); }

::selection { background-color: rgba(0, 229, 255, 0.25); color: var(--text-primary); }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--void); }
::-webkit-scrollbar-thumb { background: var(--panel); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--lcars-amber); }

img, video { max-width: 100%; display: block; }

/* ── Ambient background grid ─────────────────────────────────── */

.ambient-grid {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse at 50% 0%, rgba(244, 169, 39, 0.08) 0%, transparent 50%),
    linear-gradient(rgba(0, 229, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 229, 255, 0.04) 1px, transparent 1px);
  background-size: 100% 100%, 60px 60px, 60px 60px;
  animation: grid-pulse 6s ease-in-out infinite;
}

@keyframes grid-pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 0.6; } }

@media (max-width: 767px) { .ambient-grid { display: none; } }

/* ── Page container ──────────────────────────────────────────── */

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1rem;
}
@media (min-width: 768px) { .container { padding: 0 1.5rem; } }
@media (min-width: 1024px) { .container { padding: 0 2rem; } }

main { padding-top: var(--topbar-h); min-height: 100vh; }

/* ── Top bar / Navigation ────────────────────────────────────── */

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1rem;
  background: rgba(5, 8, 15, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-dim);
}
@media (min-width: 768px) { .topbar { padding: 0 1.5rem; } }

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--text-primary);
}

.topbar-logo {
  height: 1.5rem;
  width: auto;
  display: block;
}

.topbar-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--lcars-amber);
}

.topbar-nav {
  display: none;
  gap: 0.25rem;
  margin-left: 1.5rem;
}
@media (min-width: 1024px) { .topbar-nav { display: flex; } }

.topbar-nav a {
  font-family: var(--font-display);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-secondary);
  padding: 0.5rem 0.85rem;
  border-radius: 6px;
  transition: color 0.2s, background 0.2s;
}
.topbar-nav a:hover,
.topbar-nav a.active { color: var(--lcars-amber); background: rgba(244, 169, 39, 0.08); }

.topbar-spacer { flex: 1; }

.topbar-search {
  display: none;
  align-items: center;
  gap: 0.5rem;
  background: var(--console);
  border: 1px solid var(--border-dim);
  border-radius: 8px;
  padding: 0.4rem 0.75rem;
  min-width: 220px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
@media (min-width: 768px) { .topbar-search { display: flex; } }
.topbar-search:focus-within { border-color: var(--data-cyan); box-shadow: 0 0 0 3px rgba(0, 229, 255, 0.1); }
.topbar-search input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 0.85rem;
}
.topbar-search input::placeholder { color: var(--text-muted); }
.topbar-search-icon { color: var(--text-muted); flex-shrink: 0; }

.topbar-actions { display: flex; align-items: center; gap: 0.5rem; }

/* Always-visible auth control. Streaming-platform UX: signed-out users
   see a small filled CTA pill (like Twitch / Hulu); signed-in users see
   a 36px circular avatar with their initials (like YouTube / Netflix).
   Exactly one is visible at any time — see updateAuthUI in components.js. */
.topbar-signin {
  display: inline-flex; align-items: center; justify-content: center;
  height: 36px; padding: 0 0.95rem;
  background: var(--lcars-amber);
  color: var(--text-on-chrome, #0a0c12);
  border: 0; border-radius: 999px;
  font-family: var(--font-display, system-ui);
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
  cursor: pointer;
  transition: background 0.15s, box-shadow 0.15s, transform 0.05s;
  white-space: nowrap;
}
.topbar-signin:hover {
  background: var(--lcars-orange, #ff7a00);
  box-shadow: 0 0 18px var(--glow-amber, rgba(244, 169, 39, 0.4));
}
.topbar-signin:active { transform: translateY(1px); }
.topbar-signin[hidden] { display: none; }

.topbar-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--lcars-amber), var(--lcars-orange, #ff7a00));
  color: var(--text-on-chrome, #0a0c12);
  font-family: var(--font-display, system-ui);
  font-weight: 800; font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  border: 2px solid transparent;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
  flex-shrink: 0;
}
.topbar-avatar:hover {
  border-color: rgba(255,255,255,0.18);
  box-shadow: 0 0 18px var(--glow-amber, rgba(244, 169, 39, 0.4));
}
.topbar-avatar:active { transform: translateY(1px); }
.topbar-avatar[hidden] { display: none; }
.topbar-avatar-initials { line-height: 1; }

/* Compress on very small screens so the topbar still fits the brand,
   search icon (collapses to icon-only via .topbar-search rules above),
   sign-in pill, and hamburger without wrapping. */
@media (max-width: 480px) {
  .topbar-signin { height: 32px; padding: 0 0.7rem; font-size: 0.62rem; letter-spacing: 0.1em; }
  .topbar-avatar { width: 32px; height: 32px; font-size: 0.72rem; }
}

.topbar-mobile-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  background: transparent;
  border: none;
  color: var(--lcars-amber);
  cursor: pointer;
}
@media (min-width: 1024px) { .topbar-mobile-toggle { display: none; } }

.mobile-menu {
  position: fixed;
  top: var(--topbar-h);
  left: 0; right: 0;
  background: var(--hull);
  border-bottom: 1px solid var(--border-panel);
  padding: 1rem;
  display: none;
  flex-direction: column;
  gap: 0.25rem;
  z-index: 99;
}
.mobile-menu.open { display: flex; }
@media (min-width: 1024px) { .mobile-menu { display: none !important; } }
.mobile-menu a {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-secondary);
  padding: 0.85rem 0.75rem;
  border-radius: 6px;
  border-bottom: 1px solid var(--border-dim);
}
.mobile-menu a:last-child { border-bottom: none; }
.mobile-menu a:hover,
.mobile-menu a.active { color: var(--lcars-amber); background: rgba(244, 169, 39, 0.05); }

/* ── LCARS decorator bar ─────────────────────────────────────── */

.lcars-bar {
  height: 3px;
  background: linear-gradient(
    90deg,
    var(--lcars-amber) 0%,
    var(--lcars-orange) 40%,
    var(--data-cyan) 70%,
    transparent 100%
  );
}

/* ── Panels ──────────────────────────────────────────────────── */

.lcars-panel {
  background: var(--panel);
  border: 1px solid var(--border-panel);
  border-radius: var(--radius-panel);
  overflow: hidden;
  position: relative;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.lcars-panel:hover {
  border-color: rgba(244, 169, 39, 0.5);
  box-shadow: 0 0 24px var(--glow-amber), inset 0 0 0 1px rgba(244, 169, 39, 0.05);
}
.lcars-panel.no-hover:hover { border-color: var(--border-panel); box-shadow: none; }

.lcars-panel-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
}

.lcars-elbow {
  width: 2.5rem; height: 1.75rem;
  background: var(--lcars-amber);
  border-radius: 0 18px 0 0;
  flex-shrink: 0;
}
.lcars-elbow.cyan { background: var(--data-cyan); }
.lcars-elbow.green { background: var(--status-green); }
.lcars-elbow.peach { background: var(--lcars-peach); }

.lcars-panel-label {
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--lcars-amber);
}
.lcars-panel-label.cyan { color: var(--data-cyan); }
.lcars-panel-label.peach { color: var(--lcars-peach); }

.lcars-panel-line {
  flex: 1;
  height: 2px;
  background: linear-gradient(90deg, var(--lcars-amber), transparent);
}
.lcars-panel-line.cyan { background: linear-gradient(90deg, var(--data-cyan), transparent); }

.lcars-panel-body { padding: 1rem; }
@media (min-width: 768px) { .lcars-panel-body { padding: 1.5rem; } }

/* ── Page headers (kicker / title / sub) ─────────────────────── */

.page-header { padding: 2rem 0 1.5rem; }
@media (min-width: 768px) { .page-header { padding: 3rem 0 2rem; } }

.page-kicker {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--lcars-peach);
  margin-bottom: 0.75rem;
}

.page-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-primary);
  line-height: 1.1;
}
@media (min-width: 768px) { .page-title { font-size: 2.5rem; } }

.page-title .accent {
  background: linear-gradient(90deg, var(--data-cyan), var(--lcars-amber));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.page-sub {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--text-secondary);
  margin-top: 0.75rem;
  max-width: 640px;
}
@media (min-width: 768px) { .page-sub { font-size: 1.125rem; } }

/* ── Status indicators ───────────────────────────────────────── */

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.65rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: #ffffff;
  background: var(--status-red);
  padding: 0.25rem 0.55rem;
  border-radius: 3px;
  box-shadow: 0 0 12px rgba(255, 23, 68, 0.45);
}
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: pulse-dot 1.5s ease-in-out infinite; }
@keyframes pulse-dot {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.6); }
  50% { opacity: 0.7; box-shadow: 0 0 6px 3px rgba(255, 255, 255, 0.2); }
}

.upcoming-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--data-cyan);
  background: rgba(0, 229, 255, 0.1);
  padding: 0.2rem 0.55rem;
  border-radius: 3px;
  border: 1px solid rgba(0, 229, 255, 0.3);
}

.replay-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-muted);
  background: rgba(148, 163, 184, 0.08);
  padding: 0.2rem 0.55rem;
  border-radius: 3px;
}

/* ── Buttons ─────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding: 0.7rem 1.25rem;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  text-decoration: none;
  white-space: nowrap;
}

.btn-primary {
  background: var(--lcars-amber);
  color: var(--text-on-chrome);
}
.btn-primary:hover {
  background: var(--lcars-orange);
  box-shadow: 0 0 24px var(--glow-amber), 0 4px 16px rgba(0, 0, 0, 0.4);
  transform: translateY(-1px);
}

.btn-secondary {
  background: transparent;
  color: var(--data-cyan);
  border-color: rgba(0, 229, 255, 0.4);
}
.btn-secondary:hover {
  background: rgba(0, 229, 255, 0.08);
  border-color: var(--data-cyan);
  box-shadow: 0 0 16px var(--glow-cyan);
}

.btn-ghost {
  background: var(--panel-alt);
  color: var(--text-secondary);
  border-color: var(--border-dim);
}
.btn-ghost:hover {
  color: var(--text-primary);
  border-color: var(--lcars-amber);
  background: rgba(244, 169, 39, 0.08);
}

.btn-danger {
  background: transparent;
  color: var(--status-red);
  border-color: rgba(255, 23, 68, 0.3);
}
.btn-danger:hover { background: rgba(255, 23, 68, 0.1); border-color: var(--status-red); }

.btn-sm { padding: 0.45rem 0.85rem; font-size: 0.68rem; }
.btn-lg { padding: 0.9rem 1.75rem; font-size: 0.85rem; }
.btn-block { display: flex; width: 100%; }
.btn-icon { padding: 0.55rem; }

.btn-sweep::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.25), transparent);
  transform: translateX(-100%);
  transition: transform 0.5s;
}
.btn-sweep:hover::after { transform: translateX(100%); }

/* ── Chips / tags ────────────────────────────────────────────── */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-pill);
  background: var(--console);
  border: 1px solid var(--border-dim);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.2s;
  text-decoration: none;
}
.chip:hover { color: var(--text-primary); border-color: var(--lcars-amber); }
.chip.active { background: rgba(244, 169, 39, 0.12); border-color: var(--lcars-amber); color: var(--lcars-amber); }

/* ── Rails (horizontal scroller) ─────────────────────────────── */

.rail { margin: 2rem 0; }

.rail-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.rail-title {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.rail-title .accent { color: var(--lcars-amber); }
.rail-link {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--data-cyan);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.rail-link:hover { color: var(--text-primary); }

.rail-scroller {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  padding: 0.25rem 0 1rem;
  margin: 0 -1rem;
  padding-left: 1rem;
  padding-right: 1rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.rail-scroller > * { scroll-snap-align: start; flex: 0 0 auto; }

/* ── Edge-fade affordance for horizontal scrollers ────────────────
   Card rails (.rail-scroller) and chip rails (.chip-rail, .sport-chips,
   .filters-chips) always have more content than fits in the viewport,
   especially on mobile portrait where 1-2 cards are visible at a time.
   A hard right edge gives no signal that there's more content to swipe
   to — users miss the scrollability entirely.

   We use `mask-image` to fade the right edge to transparent. The mask
   doesn't clip interactivity (clicks still go through), it just fades
   the alpha channel as content crosses the edge — content slides in and
   out of view smoothly as the user scrolls. Works on any background
   without needing to match a specific bg color.

   Left edge: the first card sits behind a 1rem inner padding, so on a
   fresh (unscrolled) rail the first item already has visual breathing
   room. We deliberately don't fade the left edge here because pure CSS
   can't conditionally fade-only-when-scrolled — toggling a left fade
   when scrollLeft===0 would look broken. A future JS enhancement can
   toggle a `data-scrolled` attribute and add a symmetric left fade. */
.rail-scroller,
.chip-rail,
.sport-chips,
.filters-chips {
  -webkit-mask-image: linear-gradient(
    to right,
    black 0,
    black calc(100% - 2.5rem),
    transparent 100%
  );
          mask-image: linear-gradient(
    to right,
    black 0,
    black calc(100% - 2.5rem),
    transparent 100%
  );
}

/* ── Stream card ─────────────────────────────────────────────── */

/* Equal-height layout strategy
   ─────────────────────────────
   Cards live in two contexts: vertically-stacking CSS Grids (browse, live,
   replays, search, sport, event-related) and horizontally-scrolling rails
   (.rail-scroller — Continue Watching, related events, etc.).

   GRIDS need every card in a row to be the *same visual height* regardless
   of whether the title wraps to 1 or 2 lines, whether s.teams is present,
   or whether s.league/s.location are set. We do that by:

     1. Making <stream-card> (the custom element wrapper) a block-level
        flex container that fills its grid cell vertically. Without this,
        the custom element defaults to `display: inline` and the inner
        link sits at its natural content height regardless of cell size.
     2. Making the inner .stream-card link a flex column at width:100% /
        height:100% so it fills the wrapper.
     3. Making .stream-card-body a flex column with flex:1 so it eats the
        remaining vertical space below the fixed-aspect 16:9 thumb.
     4. Reserving 2 lines of vertical space for the title via `min-height`
        so a 1-line title and a 2-line title produce the same layout.
     5. Pushing .stream-card-meta to the bottom with `margin-top: auto` so
        it sits flush regardless of how much body content precedes it.

   RAILS need fixed-width cards (so they horizontally scroll predictably).
   The fixed widths now live on `.rail-scroller > stream-card` selectors
   instead of on `.stream-card` itself, which keeps rails working without
   forcing a fixed width on grid placements. Inside rails the body's
   internal flex layout still makes the card visually consistent. */

/* Custom element wrapper: flex column so the inner <a> can `flex:1` into
   it vertically. align-self:stretch makes the wrapper fill its parent's
   cross-axis (vertical in horizontal rails, vertical in vertical grids).
   We deliberately do NOT set height:100% here — when the parent
   (.rail-scroller) is auto-height, percentage heights on flex items can
   shadow the implicit `stretch` behavior in some browsers, leaving short
   cards at their natural content height instead of stretching to match
   the tallest sibling. Letting cross-size remain `auto` lets the flex
   stretch algorithm do its job. */
stream-card {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  /* In a vertical CSS Grid we still want the wrapper to fill its cell
     vertically. Grid items with auto cross-size + default
     `align-items: stretch` already do this, but being explicit avoids
     any ambiguity for grid implementations. */
  min-height: 100%;
}

.stream-card {
  /* flex:1 inside the column-flex wrapper grows the link vertically to
     consume the wrapper's full stretched height — no percentage-height
     dance required. */
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-card);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s, border-color 0.25s, box-shadow 0.25s;
  position: relative;
}
.stream-card:hover {
  transform: translateY(-2px);
  border-color: var(--lcars-amber);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 16px var(--glow-amber);
}

/* Rail-only fixed widths. Default rail card is 300px; the size= attribute
   on <stream-card> picks 220px (sm) or full-width (lg). flex:0 0 keeps the
   card from squishing or stretching as the rail scrolls. */
.rail-scroller > stream-card                 { flex: 0 0 300px; }
.rail-scroller > stream-card[size="sm"]      { flex: 0 0 220px; }
.rail-scroller > stream-card[size="lg"]      { flex: 0 0 100%;  }
.rail-scroller > stream-card[size="lg"] .stream-card { max-width: none; }

.stream-card-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, var(--panel-alt), var(--console));
  overflow: hidden;
}
.stream-card-thumb img,
.stream-card-thumb video {
  width: 100%; height: 100%;
  object-fit: cover;
}
.stream-card-thumb::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(5, 8, 15, 0.7) 100%);
  pointer-events: none;
}

.stream-card-overlay-tl,
.stream-card-overlay-tr,
.stream-card-overlay-bl,
.stream-card-overlay-br {
  position: absolute;
  z-index: 1;
}
.stream-card-overlay-tl { top: 0.5rem; left: 0.5rem; }
.stream-card-overlay-tr { top: 0.5rem; right: 0.5rem; }
.stream-card-overlay-bl { bottom: 0.5rem; left: 0.5rem; }
.stream-card-overlay-br { bottom: 0.5rem; right: 0.5rem; }

/* Resume progress bar — pinned to the bottom edge of the thumbnail.
   Sits above the radial gradient overlay so it stays visible on
   bright thumbs. Used by the Continue Watching rail. */
.stream-card-resume {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: rgba(5, 8, 15, 0.6);
  z-index: 2;
  overflow: hidden;
}
.stream-card-resume > span {
  display: block;
  height: 100%;
  background: var(--lcars-amber);
  box-shadow: 0 0 8px var(--glow-amber);
  transition: width 0.25s ease-out;
}

.stream-card-duration {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-primary);
  background: rgba(5, 8, 15, 0.85);
  padding: 0.2rem 0.45rem;
  border-radius: 3px;
}

.stream-card-viewers {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-primary);
  background: rgba(5, 8, 15, 0.85);
  padding: 0.2rem 0.45rem;
  border-radius: 3px;
}

/* Body is a flex column so we can grow it (flex:1) into whatever vertical
   space the grid cell gives us, then push the meta row to the bottom of
   the card with margin-top:auto. Combined with the title's reserved
   2-line min-height, this guarantees that two cards in the same row line
   up at the title baseline AND at the meta baseline regardless of which
   optional fields (teams, league, location) are present on each. */
.stream-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0.75rem 0.85rem 0.9rem;
}

.stream-card-title {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 0.35rem;
  /* Reserve 2 lines so a 1-line title sits at the same height as a 2-line
     title — prevents the meta row from jumping up half a line on shorter
     titles. line-height 1.3 × 2 = 2.6em. */
  min-height: 2.6em;
}

.stream-card-meta {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  /* Pin to the bottom of the card body so meta lines up across cards
     even when one has a teams row and another doesn't. */
  margin-top: auto;
  padding-top: 0.4rem;
}
.stream-card-meta .sport-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.stream-card-teams {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.35rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
}
.stream-card-teams .vs { color: var(--text-muted); font-family: var(--font-mono); font-size: 0.65rem; }

/* ── Score box ───────────────────────────────────────────────── */

.score-box {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1rem;
  align-items: center;
  background: var(--console);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-card);
  padding: 1rem;
}
.score-team { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; text-align: center; }
.score-team-badge {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--panel);
  border: 2px solid var(--border-panel);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 0.85rem;
  color: var(--lcars-amber);
}
.score-team-name {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-primary);
}
.score-team-score {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.75rem;
  color: var(--text-primary);
  line-height: 1;
}
.score-divider {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.15em;
}
.score-period {
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--status-red);
  text-transform: uppercase;
  letter-spacing: 0.15em;
}

/* ── Grid layouts ────────────────────────────────────────────── */

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.grid-2 { grid-template-columns: 1fr; }
@media (min-width: 768px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
.grid-3 { grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }
.grid-4 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 768px) { .grid-4 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }

/* ── Mobile overflow guards ────────────────────────────────────────
   CSS Grid items default to `min-width: auto`, which means a descendant
   wider than the cell's nominal `1fr` (e.g. a 16:9 stream-card thumbnail,
   a horizontal `.rail-scroller` with many cards) will EXPAND the cell
   beyond its allotted track. On mobile this blows the entire layout out
   past the viewport, producing horizontal scroll on the page itself.

   We hit this on /event.html (the `.rail-scroller` of related games inside
   the right `<aside>` pushed the whole `.event-layout` to ~970px wide on a
   390px viewport) and /replays.html (the `.grid grid-4` cells expanded to
   the stream-card's intrinsic width instead of honoring 2-cols × 1fr).

   Reset every known grid container's children to `min-width: 0` so 1fr
   actually means 1fr, and `overflow: auto` on nested rails actually clips.
   We enumerate the page-specific layout classes alongside the global ones
   so the fix is explicit; new layouts should be added here when introduced. */
.grid > *, .grid-2 > *, .grid-3 > *, .grid-4 > *,
.event-layout > *, .watch-wrap > *, .team-layout > *,
.browse-layout > *, .profile-grid > *, .home-cta-panel > *,
.about-grid > *, .value-grid > *, .how-grid > *,
.bx-grid > * { min-width: 0; }

/* Stream cards must never expand past their parent column. The
   `.rail-scroller > stream-card { flex: 0 0 300px }` rule above gives
   them a fixed width inside rails, but inside grids they should stretch
   to fill the cell — the `min-width: 0` on the grid item already does
   that. The `max-width: 100%` here is belt-and-braces against any
   future component that nests stream-cards in non-grid/non-rail
   containers (e.g. the Continue Watching section that doesn't use
   .rail-scroller). */
stream-card, .stream-card { max-width: 100%; }
stream-card { min-width: 0; }

/* ── Hero ────────────────────────────────────────────────────── */

.hero {
  position: relative;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
  border-radius: var(--radius-panel);
  overflow: hidden;
  border: 1px solid var(--border-panel);
  margin: 1.5rem 0 2rem;
  background: linear-gradient(135deg, var(--panel), var(--console));
}
@media (min-width: 768px) { .hero { min-height: 520px; } }

.hero-media {
  position: absolute; inset: 0;
  z-index: 0;
  overflow: hidden;
}
.hero-media img,
.hero-media video { width: 100%; height: 100%; object-fit: cover; }
.hero-media::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5, 8, 15, 0.2) 0%, rgba(5, 8, 15, 0.6) 50%, rgba(5, 8, 15, 0.95) 100%);
}

.hero-content {
  position: relative;
  z-index: 1;
  padding: 1.5rem;
  width: 100%;
}
@media (min-width: 768px) { .hero-content { padding: 2.5rem; } }

.hero-title {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--text-primary);
  line-height: 1.1;
  margin: 0.5rem 0;
  max-width: 720px;
}
@media (min-width: 768px) { .hero-title { font-size: 2.75rem; } }

.hero-sub {
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--text-secondary);
  max-width: 520px;
  margin-bottom: 1.25rem;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ── Footer ──────────────────────────────────────────────────── */

.site-footer {
  background: var(--hull);
  border-top: 1px solid var(--border-dim);
  padding: 3rem 0 1.5rem;
  margin-top: 4rem;
}

.site-footer-cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
}
@media (min-width: 768px) { .site-footer-cols { grid-template-columns: repeat(4, 1fr); } }

.site-footer-title {
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--lcars-amber);
  margin-bottom: 0.75rem;
}

.site-footer ul { list-style: none; display: flex; flex-direction: column; gap: 0.45rem; }
.site-footer a {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.site-footer a:hover { color: var(--data-cyan); }

.site-footer-bottom {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-dim);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

/* ── Metadata text ───────────────────────────────────────────── */

.meta { font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-muted); }
.meta-value { color: var(--text-secondary); }
.meta-cyan { color: var(--data-cyan); }
.meta-amber { color: var(--lcars-amber); }
.meta-green { color: var(--status-green); }

/* ── Quality selector ────────────────────────────────────────── */

.quality-select {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background: var(--console);
  color: var(--text-secondary);
  border: 1px solid var(--border-panel);
  padding: 0.4rem 0.7rem;
  border-radius: 6px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2394a3b8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  padding-right: 1.75rem;
}
.quality-select:hover { border-color: var(--lcars-amber); }
.quality-select option { background: var(--panel); color: var(--text-primary); }

/* ── Toast / snackbar ────────────────────────────────────────── */

.toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%) translateY(100px);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--data-cyan);
  background: var(--panel);
  border: 1px solid rgba(0, 229, 255, 0.3);
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: transform 0.3s, opacity 0.3s;
  z-index: 1000;
  pointer-events: none;
}
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }

/* ── Empty / zero state ──────────────────────────────────────── */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 4rem 2rem;
  text-align: center;
}
.empty-state-icon { font-size: 3rem; opacity: 0.3; }
.empty-state-title {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-secondary);
}
.empty-state-sub {
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--text-muted);
  max-width: 360px;
}

/* ── Utility ─────────────────────────────────────────────────── */

.section { padding: 2rem 0; }
@media (min-width: 768px) { .section { padding: 3rem 0; } }

.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.5rem; }
.gap-2 { gap: 1rem; }
.gap-3 { gap: 1.5rem; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mt-4 { margin-top: 2rem; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.mb-3 { margin-bottom: 1.5rem; }
.mb-4 { margin-bottom: 2rem; }
.text-center { text-align: center; }
.text-muted { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.text-faint { color: var(--text-faint); }
.text-cyan { color: var(--data-cyan); }
.text-amber { color: var(--lcars-amber); }
.text-green { color: var(--status-green); }
.text-red { color: var(--status-red); }
.hidden { display: none; }
@media (min-width: 768px) { .md\\:block { display: block; } .md\\:hidden { display: none; } }

/* ── Animations ──────────────────────────────────────────────── */

@keyframes fade-in-up {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
.animate-fade-in { animation: fade-in-up 0.5s ease-out both; }
.animate-fade-in.d1 { animation-delay: 0.08s; }
.animate-fade-in.d2 { animation-delay: 0.16s; }
.animate-fade-in.d3 { animation-delay: 0.24s; }
.animate-fade-in.d4 { animation-delay: 0.32s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
