/**
 * StreamVerse — Live Now Bar
 *
 * A NEW, compact signal bar between Hero and Trust Banner. Purpose: a
 * quick "something is live right now" cue that bridges the Hero's
 * cinematic full-bleed artwork into the rest of the page's calmer,
 * contained sections — not a second sports section (Live Sports below
 * already owns that job), not a dashboard, not a scores ticker.
 *
 * UI-ONLY BUILD. There is no live data source wired up yet, so every
 * event card here renders as a neutral skeleton — no invented teams,
 * scores, times, or competitions. The markup below is the future data
 * contract: each field a real integration will eventually populate is
 * marked with a data-field attribute (see the HTML for the full list).
 * Swapping skeleton state for real content is a JS/markup change for
 * a later phase, not a CSS change — nothing here should need to move.
 *
 * Deliberately its own visual family, distinct from both the
 * elevated-panel banners (trust-banner.css / guarantee-banner.css) and
 * the four transform-driven carousels (movie-carousel.css and
 * siblings): this is a thin, full-bleed BAR, not an inset panel, and
 * it's a quiet signal strip, not a browsable showcase (no drag,
 * click-to-center, or keyboard-arrow nudging like the carousels).
 *
 * Its continuous horizontal movement now uses the exact same engine
 * as the Movies carousel (movie-showcase.js): a requestAnimationFrame
 * loop advances one `scrollOffset` number every frame and writes it to
 * .live-now__rail's own `transform: translateX()` — no CSS
 * @keyframes, no native overflow-scroll. That runs identically on
 * desktop, tablet, and touch (see live-now.js's runAutoScroll()), so
 * it never depends on hover/pointer capability the way an earlier
 * version of this file did. The one exception is
 * prefers-reduced-motion, where this component instead falls back to
 * plain native overflow-x: auto scrolling and the continuous drift
 * never starts at all — see the media query near the end of this
 * file, and live-now.js's `reducedMotion` check.
 *
 * Colors/spacing/radius/shadow/easing are all existing tokens from
 * tokens.css — no new design values were introduced. The one literal,
 * #A3AED0, matches the same untokenized secondary-text color already
 * used sitewide for muted copy (subtitles, descriptions, etc.), for
 * visual consistency with the rest of the page rather than the
 * lesser-used --color-text-secondary token.
 */

.live-now {
  position: relative;
  background-color: var(--color-bg-elevated);
  border-bottom: 1px solid var(--color-border-subtle);
}

/* A restrained violet-to-cyan hairline at the very top edge — the one
   deliberate accent moment in this component, and the visual thread
   tying the Hero (which sits directly above) into the rest of the
   page. 2px, soft-opacity, never a hard line. An earlier version of
   Trust Banner explored a similar "decorative top hairline" idea
   before being simplified away (see trust-banner.css's own history
   note) — reintroduced here instead, where it now does a real job:
   marking the seam where the Hero ends. */
.live-now::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--color-accent) 35%,
    var(--color-highlight) 65%,
    transparent 100%
  );
  opacity: 0.55;
  pointer-events: none;
}

.live-now__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 118px;
  max-width: var(--grid-max-width);
  margin-inline: auto;
  padding-block: var(--space-1);
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .live-now__inner {
    padding-inline: var(--space-6);
  }
}

@media (min-width: 1024px) {
  .live-now__inner {
    padding-inline: var(--space-7);
  }
}

/* ------------------------------------------------------------------
 * Live signal — fixed-width, never scrolls, always visible. The one
 * badge-style element in the component; everything else is neutral.
 * ------------------------------------------------------------------ */

.live-now__signal {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 0 0 auto;
  padding-right: var(--space-4);
  border-right: 1px solid var(--color-border-subtle);
}

.live-now__dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background-color: var(--color-error);
  box-shadow: 0 0 6px rgba(239, 68, 68, 0.55);
}

/* Same slow, steady breathing pulse as the Live Sports carousel's own
   LIVE badge (sports-carousel.css) — reused intentionally so "live"
   reads identically everywhere on the page, not as two different
   conventions. Kept to opacity only (no scale/size change), and only
   runs at all under prefers-reduced-motion: no-preference. */
@media (prefers-reduced-motion: no-preference) {
  .live-now__dot {
    animation: live-now-pulse 2.4s ease-in-out infinite;
  }
}

@keyframes live-now-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.45;
  }
}

.live-now__label {
  font-family: var(--font-body);
  font-size: var(--text-micro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-primary);
  white-space: nowrap;
}

/* ------------------------------------------------------------------
 * Viewport — fixed, clips whatever the rail's transform brings into
 * view. Same architecture as .movie-carousel__viewport: overflow:
 * hidden and touch-action: pan-y by default, so continuous movement
 * and touch/drag never fight a native scrollbar — see live-now.js for
 * the transform side of this. min-width: 0 is load-bearing: without
 * it, a flex child's default min-width (auto) forces the row wider
 * than its container the moment content doesn't fit, which pushes the
 * *page* into horizontal overflow — exactly the failure mode this
 * component must never cause.
 * ------------------------------------------------------------------ */

.live-now__viewport {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  touch-action: pan-y; /* vertical page scroll passes through untouched;
                           horizontal movement is fully owned by the JS
                           transform, exactly like the Movies carousel */
  /* Soft edge fade hints "there's more content", matching the same
     mask-image convention already used on the Movies/Sports/Channels
     carousel viewports (both prefixes, same as movie-carousel.css, for
     Safari/mobile Safari support). */
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 20px,
    #000 calc(100% - 20px),
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 20px,
    #000 calc(100% - 20px),
    transparent 100%
  );
}

/* Reduced motion: the continuous drift never starts (see live-now.js),
   so fall back to plain native horizontal scrolling — the same
   behavior this component always had — rather than leaving the
   content stuck with no way to reach cards past the first screenful.
   (The matching .live-now__track--clone { display: none } for this
   same media query lives just after .live-now__track's base rule
   below, so it isn't overridden by that later, equal-specificity
   rule.) */
@media (prefers-reduced-motion: reduce) {
  .live-now__viewport {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none; /* Firefox */
    -webkit-overflow-scrolling: touch;
  }
}

.live-now__viewport::-webkit-scrollbar {
  display: none; /* Chrome/Safari/Edge — only relevant in the reduced-motion fallback above */
}

.live-now__track {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding-block: 2px; /* clears the card's own focus/hover outline from being clipped */
  scroll-snap-type: x proximity;
  flex: 0 0 auto; /* never shrunk now that it's a flex item inside .live-now__rail */
}

@media (prefers-reduced-motion: reduce) {
  .live-now__track--clone {
    display: none; /* no loop animation running — nothing to duplicate */
  }
}

/* ------------------------------------------------------------------
 * Event card — skeleton-only for now. Three stacked rows: a status/
 * competition tag, the team-vs-team row, and a time/score row —
 * mirroring exactly the structure a populated card will eventually
 * need, just with neutral placeholder blocks instead of real content.
 * ------------------------------------------------------------------ */

.live-now__card {
  flex: 0 0 auto;
  width: 168px;
  scroll-snap-align: start;
}

@media (min-width: 480px) {
  .live-now__card {
    width: 188px;
  }
}

@media (min-width: 1024px) {
  .live-now__card {
    width: 208px;
  }
}

.live-now__card-inner {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%; /* buttons default to shrink-to-fit; the old <div> filled
                   its flex slot for free, so this keeps that unchanged
                   now that .live-now__card-inner is a real <button> */
  height: 100%;
  padding: 8px var(--space-3);
  background-color: var(--color-bg-elevated-hover);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  transition: border-color var(--duration-micro) var(--ease-standard),
    box-shadow var(--duration-micro) var(--ease-standard),
    transform var(--duration-micro) var(--ease-standard);
}

/* Deliberately quiet hover — noticeably softer than the Movies/Sports
   carousel cards' own glow (their --color-accent-glow is 0.35 alpha).
   These are empty placeholders standing in for a live-activity rail,
   not promotional artwork, so the same restraint principle applied to
   the Testimonials carousel's hover treatment applies here too. */
@media (hover: hover) {
  .live-now__card-inner:hover {
    border-color: var(--color-accent);
    box-shadow: 0 0 14px rgba(124, 58, 237, 0.18);
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .live-now__card-inner:hover {
    transform: translateY(-2px);
  }
}

.live-now__card-inner:focus-within {
  border-color: var(--color-accent);
}

.live-now__matchup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.live-now__team {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1 1 0;
  min-width: 0;
}

.live-now__vs {
  flex: 0 0 auto;
  font-family: var(--font-body);
  font-size: 0.6875rem; /* 11px — one step below --text-micro, reserved for this one small in-card label */
  font-weight: 600;
  color: #a3aed0; /* matches the sitewide untokenized secondary-text color, see file header */
}

/* ------------------------------------------------------------------
 * Skeleton primitives — neutral, non-representational blocks. No
 * text, no numbers, no team names: this is what makes the card read
 * as "loading/empty" rather than "a real match with the details
 * hidden". A gentle shimmer sweep under normal motion preferences;
 * a flat, static fill under prefers-reduced-motion.
 * ------------------------------------------------------------------ */

.live-now__skeleton {
  display: block;
  flex: 0 0 auto;
  border-radius: var(--radius-xs);
  background-color: rgba(148, 163, 184, 0.14);
}

@media (prefers-reduced-motion: no-preference) {
  .live-now__skeleton {
    background: linear-gradient(
      90deg,
      rgba(148, 163, 184, 0.1) 25%,
      rgba(148, 163, 184, 0.24) 50%,
      rgba(148, 163, 184, 0.1) 75%
    );
    background-size: 200% 100%;
    animation: live-now-shimmer 2.6s ease-in-out infinite;
  }
}

@keyframes live-now-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.live-now__skeleton--tag {
  width: 56px;
  /* Matches the real .live-now__tag's rendered height (18px: 10px
     font-size * 1.4 line-height + 1px top/bottom padding) — was 10px,
     a plain guess that didn't account for the real element's padding
     and line-height. That ~8px-per-row shortfall (repeated across the
     tag/name/status rows below) was the actual root cause of the
     layout shift Lighthouse attributed to section.trust-banner: this
     bar grows taller once live-now.js swaps skeleton for real data,
     pushing every section below it down by the same amount. Matching
     the skeleton's reserved height to the real content's height up
     front means the bar is already the right height on first paint,
     so nothing needs to move when the real content arrives. Purely a
     reserved-space fix — the populated-state CSS (.live-now__tag etc.)
     is untouched, so the final, settled appearance is pixel-identical
     to before. */
  height: 18px;
  border-radius: var(--radius-full);
  align-self: flex-start;
}

.live-now__skeleton--crest {
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

.live-now__skeleton--name {
  /* Matches .live-now__team-name's real rendered height (13px, from
     its own font-size/line-height) — was 8px. Same reasoning as
     .live-now__skeleton--tag above. */
  width: 32px;
  height: 13px;
}

.live-now__skeleton--status {
  width: 72px;
  /* Matches .live-now__status-text's real rendered height (~17.6px,
     from its own font-size with the inherited body line-height) —
     was 10px. Same reasoning as .live-now__skeleton--tag above. */
  height: 18px;
  border-radius: var(--radius-full);
  align-self: center;
}

/* ------------------------------------------------------------------
 * Populated-state content — rendered by live-now.js once real
 * API-Football data is available. Same card shape/sizing as the
 * skeleton state above (same .live-now__card / .live-now__card-inner
 * / .live-now__matchup / .live-now__team / .live-now__vs), so a card
 * never visibly resizes when it swaps from loading to populated.
 * ------------------------------------------------------------------ */

.live-now__tag {
  align-self: flex-start;
  padding: 2px var(--space-2);
  background-color: var(--color-accent-muted);
  border-radius: var(--radius-full);
  color: var(--color-accent-hover);
  font-family: var(--font-body);
  font-size: 0.625rem; /* 10px — small badge text, one step below --text-micro */
  font-weight: 600;
  line-height: 1.4;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-now__team-logo {
  width: 20px;
  height: 20px;
  object-fit: contain;
}

.live-now__team-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-body);
  font-size: 0.6875rem; /* 11px, matches .live-now__vs */
  font-weight: 600;
  color: var(--color-text-primary);
}

.live-now__score {
  flex: 0 0 auto;
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  font-weight: 700;
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}

/* A compact pill for every state (live/upcoming/finished/postponed) —
   same recipe as .live-now__tag just above (font-size, line-height,
   padding, pill radius) so it's guaranteed to fit the exact height
   already reserved by .live-now__skeleton--status (18px), with only
   the background/text color varying per state below. Was plain,
   unpadded text before this — the "small pill/badge, never a large
   text block" requirement applies to every status, not just LIVE. */
.live-now__status-text {
  display: inline-block;
  align-self: center;
  max-width: 100%;
  padding: 1px 6px;
  border-radius: var(--radius-full);
  background-color: rgba(148, 163, 184, 0.12);
  color: #a3aed0; /* matches the sitewide untokenized secondary-text color, see file header */
  font-family: var(--font-body);
  font-size: 0.625rem; /* 10px, matches .live-now__tag's own compact badge size */
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Same red pill language as .live-now__tag--live used to be (moved
   here instead — see buildCard() in live-now.js: the tag no longer
   carries a "LIVE · " prefix, so this is now the one and only place a
   live match's red treatment lives). */
.live-now__status-text--live {
  background-color: rgba(239, 68, 68, 0.14);
  border: 1px solid rgba(239, 68, 68, 0.5);
  color: var(--color-error);
  font-weight: 700;
}

/* Postponed reuses --color-accent-muted/--color-accent-hover — already
   the design system's own "tinted glass fill for badges" pair (see
   tokens.css), giving Postponed a distinct look from both Live (red)
   and Upcoming/Finished (neutral) without introducing any new color. */
.live-now__status-text--postponed {
  background-color: var(--color-accent-muted);
  color: var(--color-accent-hover);
}

/* Empty / error state — a single message in place of the card row,
   height-matched to a real card so the bar never visibly jumps when
   swapping between states. */
.live-now__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 auto;
  min-height: 68px;
  padding-inline: var(--space-4);
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  color: #a3aed0;
  white-space: nowrap;
}

/* ------------------------------------------------------------------
 * Populated content — the real-data counterparts to the skeleton
 * primitives above, added when live-now.js wires this component up
 * to real match data. Same footprint/sizing language as the skeleton
 * state on purpose (this is "fill in the existing shape with real
 * content", not a new layout) — only real text/images instead of
 * shimmering placeholder blocks.
 * ------------------------------------------------------------------ */

.live-now__tag {
  display: inline-block;
  align-self: flex-start;
  max-width: 100%;
  padding: 1px 6px;
  border-radius: var(--radius-full);
  background-color: rgba(148, 163, 184, 0.12);
  color: #a3aed0; /* matches the sitewide untokenized secondary-text color, see file header */
  font-family: var(--font-body);
  font-size: 0.625rem; /* 10px — deliberately below --text-micro to fit this compact pill; matches the skeleton pill it replaces */
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Reuses the exact same red / translucent-dark / pulsing-dot visual
   language already established by the Live Sports carousel's own
   LIVE badge (sports-carousel.css .sports-carousel__badge-live), so
   "this is live" reads identically everywhere on the page. */
.live-now__tag--live {
  background-color: rgba(239, 68, 68, 0.14);
  border: 1px solid rgba(239, 68, 68, 0.5);
  color: var(--color-error);
  font-weight: 700;
}

.live-now__crest {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: contain;
  background-color: rgba(255, 255, 255, 0.05);
}

.live-now__team-name {
  display: block;
  max-width: 100%;
  color: var(--color-text-primary);
  font-family: var(--font-body);
  font-size: 0.625rem; /* 10px, see .live-now__tag note above */
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.live-now__status {
  align-self: center;
  max-width: 100%;
  color: #a3aed0;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.live-now__status--live {
  color: var(--color-text-primary);
  font-weight: 700;
}

/* A quiet fade-in for cards as they're populated with real data, so
   the loading -> real-matches swap doesn't hard-cut. Applied by
   live-now.js via a class toggled off shortly after insertion;
   skipped entirely under reduced motion (cards simply appear). */
.live-now__card--enter {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .live-now__card-inner {
    transition: border-color var(--duration-micro) var(--ease-standard),
      box-shadow var(--duration-micro) var(--ease-standard),
      transform var(--duration-micro) var(--ease-standard),
      opacity var(--duration-transition) var(--ease-standard);
  }
}

/* ------------------------------------------------------------------
 * Empty / error message — shown instead of the track when there is
 * nothing worth displaying (no important matches) or the API could
 * not be reached. Never renders alongside fake/invented match data.
 * ------------------------------------------------------------------ */

.live-now__message {
  margin: 0;
  color: #a3aed0;
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  white-space: nowrap;
}


/* ------------------------------------------------------------------
 * Auto-scrolling rail — runs on every device by default now (see the
 * file header). .live-now__rail wraps the real track
 * (.js-live-now-track) and an aria-hidden clone
 * (.js-live-now-clone) side by side; live-now.js repeats the clone's
 * content as many times as needed to comfortably exceed the
 * viewport's own width, then drives this element's own `transform`
 * every animation frame (see runAutoScroll() there) — no CSS
 * @keyframes here at all, matching the Movies carousel's own engine
 * exactly. Because the clone is an exact copy of the real track's
 * current content, the instant the loop wraps is visually identical
 * to the frame just before — no visible jump, even with as few as one
 * match card currently showing.
 * ------------------------------------------------------------------ */

.live-now__rail {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: max-content;
  will-change: transform;
}
