/* /assets/css/web-player.css
 * iptv.events WebPlayer v2 (LiveSportsTV) - styles for webplayer.php + assets/js/web-player.js.
 *
 * Ported 2026-10-09 from iptv.soccer and rebranded to the iptv.events / LiveSportsTV palette:
 *   - iptv.soccer css/web-player.css           (theme vars, layout + column order, video/fullscreen,
 *                                               sticky header, #leftScroll, now-playing, reCAPTCHA
 *                                               badge, live dot, .ls-loading, topbar, .cn-tiles)
 *   - iptv.soccer web-player/index.php inline  (player chrome .wpv-*, sidebar search / crumb /
 *     <style> blocks                            section / footer / favorite star / group rows,
 *                                               expired bar .wp-expired-*)
 *   - iptv.soccer css/player-platforms.css     (.platforms-or, .platforms-grid, .platform-tile*;
 *                                               player-platforms.css itself is NOT loaded here)
 *   - iptv.events assets/css/m3u.css            (.now-playing, .pill-audio, .ls-loading,
 *                                               .wp-live-dot, .grecaptcha-badge, #tutorialsModal)
 *
 * Rebrand: soccer greens #1B8B3D / #25a94c / #22C55E / #15692E -> #16a34a / #22c55e / #15803d.
 * Gold (#F59E0B / #fbbf24) kept for favorites and the gold button. Player surface stays #070d18.
 * Header is white with a #eee bottom rule (no stadium gradient). Fonts inherit the system stack
 * from styles.css (Montserrat/Inter are not loaded). Bootstrap colour utilities (.btn-success,
 * .text-success, .bg-success-subtle, ...) are NOT overridden globally and there is no !important.
 *
 * Load order (CONTRACT section 1): bootstrap 5.3.3, bootstrap-icons, Font Awesome 6.5.1,
 * /assets/css/styles.css, then this file. The .modal / .modal-backdrop z-index pair lives
 * inline in webplayer.php and is intentionally not repeated here.
 */

/* =========================================================================
   1. Tokens
   ========================================================================= */
:root {
  --wpv-green:        #16a34a;   /* LiveSportsTV primary (= styles.css --green) */
  --wpv-green-light:  #22c55e;
  --wpv-green-dark:   #15803d;
  --wpv-green-ink:    #14532d;   /* text on green tints */
  --wpv-green-50:     #f0fdf4;
  --wpv-green-100:    #dcfce7;   /* = styles.css --green-soft */
  --wpv-gold:         #F59E0B;
  --wpv-gold-light:   #fbbf24;
  --wpv-ink:          #0f172a;   /* dark text on light surfaces */
  --wpv-player-bg:    #070d18;   /* video area + gates */
  --wpv-chrome-ink:   #e8eef6;   /* text/icons on the dark player chrome */
  --wpv-chrome-line:  rgba(255,255,255,.08);

  /* legacy alias: m3u.css-era rules and inline snippets used this name */
  --brand-green:      #16a34a;
}

/* =========================================================================
   2. Page base + header (header.web-player-topbar)
   ========================================================================= */
body { background: #fff; }

.web-player-topbar {
  background: #fff;
  color: #111;
  border-bottom: 1px solid #eee;
  padding-top: .75rem;              /* a py-* utility on the markup wins over this */
  padding-bottom: .75rem;
}
.web-player-topbar .navbar-brand {
  display: inline-flex;
  align-items: center;
  color: #111;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.web-player-topbar .navbar-brand:hover,
.web-player-topbar .navbar-brand:focus { color: #111; }

/* Gear menu: green hover/active tint via Bootstrap's own variables (no colour overrides) */
.web-player-topbar .dropdown-menu {
  min-width: 260px;
  --bs-dropdown-link-hover-bg: rgba(22,163,74,.08);
  --bs-dropdown-link-active-bg: var(--wpv-green);
}

/* Tiny LIVE dot after the brand */
.wp-live-dot {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  width: .7rem; height: .7rem;
  border-radius: 50%;
  background: #dc3545;
  flex: 0 0 auto;
  animation: wpPulse 2.4s ease-in-out infinite;
}
.wp-live-dot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(220,53,69,.24);
  animation: wpRipple 2.4s ease-in-out infinite;
}
@keyframes wpPulse {
  0%   { transform: scale(.92); }
  50%  { transform: scale(1.12); }
  100% { transform: scale(.92); }
}
@keyframes wpRipple {
  0%   { box-shadow: 0 0 0 0 rgba(220,53,69,.22); }
  50%  { box-shadow: 0 0 0 .45rem rgba(220,53,69,.10); }
  100% { box-shadow: 0 0 0 0 rgba(220,53,69,0); }
}

/* =========================================================================
   3. Layout: columns, order, #leftScroll
   <992px: video column first, list below (45vh scroll box).
   >=992px: list left / video right; JS syncHeights() caps #leftScroll at the
   video height (inline max-height).
   ========================================================================= */
#leftScroll { overflow-y: auto; -webkit-overflow-scrolling: touch; }

.col-left  { order: 2; }
.col-right { order: 1; }

@media (min-width: 992px) {
  /* align-self:flex-start stops the row stretching the list column to the video column's
     height (soccer removed the old min-height:100vh for the same reason). */
  .col-left  { order: 1; align-self: flex-start; }
  .col-right { order: 2; }
  .sidebar   { border-right: 1px solid #eee; }
}
@media (max-width: 991.98px) {
  #leftScroll { max-height: 45vh; }
  .video-wrap { margin-top: .25rem; }
}

/* =========================================================================
   4. Sidebar header: search + crumb row (.sticky-header)
   ========================================================================= */
.sticky-header {
  position: sticky; top: 0; z-index: 10;
  padding: 14px 14px 10px;
  background: #fff;
  border-bottom: 1px solid rgba(15,23,42,.08);
}

.wpv-search { position: relative; display: flex; align-items: center; }
.wpv-search input {
  width: 100%;
  font-size: .95rem;
  font-family: inherit;
  color: var(--wpv-ink);
  background: #F4F7F9;
  border: 1.5px solid rgba(15,23,42,.10);
  border-radius: 12px;
  padding: 11px 38px 11px 40px;
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
  -webkit-appearance: none;
  appearance: none;
}
.wpv-search input::-webkit-search-cancel-button { display: none; }
.wpv-search input:focus {
  border-color: var(--wpv-green);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(22,163,74,.13);
}
.wpv-search input::placeholder { color: #94A3B8; }
.wpv-search-ico {
  position: absolute; left: 14px;
  width: 17px; height: 17px;
  pointer-events: none;
  fill: none; stroke: #94A3B8; stroke-width: 2.2; stroke-linecap: round;
}
.wpv-search input:focus ~ .wpv-search-ico { stroke: var(--wpv-green); }
.wpv-search-x {
  position: absolute; right: 6px;
  display: none;
  border: 0; background: none;
  color: #94A3B8; cursor: pointer;
  font-size: 1rem; line-height: 1;
  padding: 7px 9px; border-radius: 9px;
}
.wpv-search-x.on { display: block; }
.wpv-search-x:hover { color: var(--wpv-ink); background: rgba(15,23,42,.06); }

/* "You are here" row: crumb pill + Back (#activeGroupBadge; .d-none hides it) */
.wpv-crumbrow { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.wpv-crumb {
  flex: 1; min-width: 0;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--wpv-green-50);
  color: var(--wpv-green-dark);
  border: 1px solid rgba(22,163,74,.20);
  font-weight: 800; font-size: .76rem; letter-spacing: .03em; text-transform: uppercase;
  padding: 7px 12px; border-radius: 999px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* the text sits in its own flex item, so the ellipsis has to live on that item */
.wpv-crumb > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wpv-back {
  flex: 0 0 auto;
  border: 1px solid rgba(15,23,42,.14);
  background: #fff;
  color: #41536B;
  font-weight: 700; font-size: .78rem;
  padding: 7px 13px; border-radius: 999px;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.wpv-back:hover { border-color: var(--wpv-green); color: var(--wpv-green-dark); background: var(--wpv-green-50); }

/* =========================================================================
   5. Lists: section labels, group rows, channel cards, loader, sentinel
   ========================================================================= */

/* Section label used when a search shows categories and channels together */
.wpv-sec {
  font-size: .68rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: #7286A0;
  margin: 2px 2px 8px;
}

/* ---- Group rows (#groupsContainer.group-list.list-group) ---- */
.group-list {
  /* brand the Bootstrap list states through its variables */
  --bs-list-group-action-active-bg: rgba(22,163,74,.12);
  --bs-list-group-action-active-color: var(--wpv-green-dark);
  --bs-list-group-active-bg: var(--wpv-green);
  --bs-list-group-active-border-color: var(--wpv-green);
}
.group-list .list-group-item { cursor: pointer; }

/* flag emoji or Font Awesome icon in front of the group name */
.wpv-grp { display: inline-flex; align-items: center; gap: 9px; min-width: 0; flex: 1; }
.wpv-grp-flag {
  font-size: 1.15rem; line-height: 1; flex: 0 0 auto;
  font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
}
.wpv-grp-icon { width: 1.15rem; text-align: center; flex: 0 0 auto; color: var(--wpv-green); font-size: .95rem; }
.wpv-grp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* channel-count badge (.badge.bg-success-subtle.text-success): brand tint scoped to the list,
   through Bootstrap's variables, so the global utilities stay untouched */
.group-list .badge {
  --bs-success-bg-subtle: var(--wpv-green-100);
  --bs-success-rgb: 21,128,61;
  flex: 0 0 auto;
  margin-left: .5rem;
  font-weight: 600;
}

/* Favorites row (pinned on top) */
.wpv-favrow .wpv-favstar { color: var(--wpv-gold); font-size: 1.05rem; }

/* Now-playing highlight on the group row that holds the active channel (D8 d) */
.list-group-item.playing {
  background-color: rgba(22,163,74,.08);
  box-shadow: inset 3px 0 0 var(--wpv-green);
}
.list-group-item.playing:hover,
.list-group-item.playing:focus { background-color: rgba(22,163,74,.13); }
.list-group-item.playing .wpv-grp-name { color: var(--wpv-green-dark); font-weight: 600; }

/* ---- Channel cards (#channelsContainer > .col-12 > .channel-card) ---- */
.channel-card {
  position: relative;
  background: #fff;
  cursor: pointer;
  transition: transform .05s ease, box-shadow .15s ease, background-color .15s ease;
}
.channel-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 .25rem .5rem rgba(0,0,0,.05);
  --bs-border-color: rgba(22,163,74,.35);   /* the .border utility reads this variable */
}
/* styles.css caps .channel-logo at 20px high for the event pages; undo that inside cards */
.channel-card .channel-logo {
  width: 38px; height: 38px;
  max-width: none; max-height: none;
  object-fit: contain;
  border-radius: .375rem;
  flex: 0 0 auto;
}
.wpv-ch-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
/* search-result cards wrap name + group in a .flex-column block */
.channel-card > .flex-column { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* Favorite star: right-hand end of the row, always visible (touch has no hover) */
.wpv-fav {
  margin-left: auto;
  flex: 0 0 auto;
  border: 0; background: none;
  cursor: pointer;
  padding: 6px; border-radius: 9px;
  line-height: 0;
  color: #C6D0DC;
  transition: color .15s ease, background .15s ease;
}
.wpv-fav svg { width: 18px; height: 18px; fill: currentColor; display: block; }
.wpv-fav:hover { color: var(--wpv-gold); background: rgba(245,158,11,.10); }
.wpv-fav.on { color: var(--wpv-gold); }

/* Now-playing highlight on the active channel card (D8 d). The card carries Bootstrap's
   .border/.rounded utilities (!important), so the colour goes through --bs-border-color and
   the left bar is an inset shadow. */
.channel-card.playing {
  --bs-border-color: rgba(22,163,74,.55);
  background: var(--wpv-green-50);
  box-shadow: inset 4px 0 0 var(--wpv-green);
}
.channel-card.playing:hover {
  --bs-border-color: rgba(22,163,74,.7);
  box-shadow: inset 4px 0 0 var(--wpv-green), 0 .25rem .5rem rgba(0,0,0,.05);
}
.channel-card.playing .wpv-ch-name,
.channel-card.playing .flex-column > .fw-semibold { color: var(--wpv-green-dark); }

/* Chunked-render sentinel (IntersectionObserver target): a 1px invisible row */
#searchSentinel,
#channelsSentinel,
.wpv-sentinel {
  display: block;
  width: 100%;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  pointer-events: none;
}

/* Animated playlist loader (rendered into #groupsContainer while the list loads) */
.ls-loading {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  padding: 1rem;
  background: #f8f9fa;
  border: 1px solid #e9ecef; border-left: 4px solid var(--wpv-green);
  border-radius: .5rem;
  font-weight: 600; color: #111;
  font-size: 1rem;                 /* break out of the parent .small */
  min-height: 48px;
}
.ls-loading .label { font-size: 1.05rem; font-weight: 600; }
.ls-loading .dots  { display: inline-flex; gap: .35rem; margin-left: .25rem; transform: translateY(1px); }
.ls-loading .dot {
  display: block;
  width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--wpv-green);
  animation: lstvDot 1.05s ease-in-out infinite both;
}
.ls-loading .dot:nth-child(2) { animation-delay: .15s; }
.ls-loading .dot:nth-child(3) { animation-delay: .30s; }
@keyframes lstvDot {
  0%, 80%, 100% { transform: translateY(0) scale(.85); opacity: .55; }
  40%           { transform: translateY(-6px) scale(1); opacity: 1; }
}

/* =========================================================================
   6. Right column: event note, expired bar, now-playing bars
   ========================================================================= */

/* #wpvEventNote: compact info line above the player on /WebPlayer/{id}/{slug} (plain text) */
.wpv-event-note {
  display: flex; align-items: flex-start; gap: .5rem;
  margin-bottom: .5rem;
  padding: .45rem .75rem;
  font-size: .875rem; line-height: 1.4; font-weight: 500;
  color: var(--wpv-green-ink);
  background: var(--wpv-green-50);
  border: 1px solid rgba(22,163,74,.22);
  border-left: 4px solid var(--wpv-green);
  border-radius: .5rem;
  overflow-wrap: anywhere;
}
.wpv-event-note::before {
  content: "i";
  content: "i" / "";               /* decorative: hidden from screen readers where supported */
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.1rem; height: 1.1rem;
  margin-top: .1rem;
  border-radius: 50%;
  background: var(--wpv-green);
  color: #fff;
  font-size: .7rem; font-weight: 800; font-style: normal; line-height: 1;
}

/* Expired bar (subState 'expired'): white card, green rule, amber warning icon */
.wp-expired-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: #fff;
  border: 1px solid #E5E7EB;
  border-left: 4px solid var(--wpv-green);
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.06);
}
.wp-expired-warn {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: #FEF3C7;
  color: #B45309;
  border-radius: 50%;
  font-size: 18px;
}
.wp-expired-info { flex: 1 1 240px; min-width: 0; }
.wp-expired-headline {
  display: block;
  font-family: inherit;
  font-weight: 800; font-size: .92rem;
  color: var(--wpv-ink);
  line-height: 1.25;
}
.wp-expired-meta {
  display: block;
  font-family: inherit;
  font-size: .8rem; color: #6B7280;
  margin-top: 2px;
  line-height: 1.4;
  word-break: break-all;
}
.wp-expired-meta code {
  background: #F3F4F6;
  color: var(--wpv-ink);
  padding: 1px 6px; border-radius: 4px;
  font-family: var(--bs-font-monospace, monospace);
  font-size: .78rem; font-weight: 600;
}
.wp-expired-meta .wp-expired-sep { color: #D1D5DB; margin: 0 4px; }
.wp-expired-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; flex-wrap: wrap; }
.wp-expired-renew {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 18px;
  background: linear-gradient(135deg, var(--wpv-green) 0%, var(--wpv-green-dark) 100%);
  color: #fff;
  border: 0; border-radius: 8px;
  font-family: inherit;
  font-weight: 700; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .5px;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(22,163,74,.25);
  transition: filter .18s ease, transform .18s ease;
}
.wp-expired-renew:hover { filter: brightness(1.05); transform: translateY(-1px); }
.wp-expired-renew i { font-size: .78rem; }
.wp-expired-switch {
  background: transparent; border: 0;
  padding: 6px 8px;
  font-family: inherit;
  font-size: .78rem; font-weight: 600;
  color: var(--wpv-green-dark);
  cursor: pointer;
  text-decoration: none;
  border-bottom: 1px dotted rgba(22,163,74,.4);
  line-height: 1;
}
.wp-expired-switch:hover { color: var(--wpv-green-ink); border-bottom-color: var(--wpv-green-dark); }

/* Now-playing bars (#nowPlayingTop mobile, #nowPlayingBottom desktop) */
.now-playing {
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .75rem;
  border: 1px solid #e9ecef; border-left: 4px solid var(--wpv-green);
  border-radius: .5rem;
  background: #f8f9fa; color: #111; font-weight: 600;
}
.now-playing .dot {
  display: inline-block;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--wpv-green);
  flex: 0 0 auto;
}
.pill-audio {
  font-weight: 600;
  border: 1px solid rgba(22,163,74,.2);
  color: var(--wpv-green-dark);
  background: rgba(22,163,74,.08);
}

/* =========================================================================
   7. Video + player chrome (scoped to .video-wrap; native controls are off)
   ========================================================================= */
.video-wrap {
  overflow: hidden;
  border-radius: 14px;
  background: var(--wpv-player-bg);
}
#video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  background: var(--wpv-player-bg);
}
.video-wrap.idle { cursor: none; }

/* ---- Fullscreen ----
   .video-wrap is what goes fullscreen. #video carries aspect-ratio:16/9, so without these rules
   a phone in landscape gets a taller-than-screen box and loses the bottom of the picture.
   Fill the screen and let object-fit letterbox. One rule per prefix: a selector list holding a
   pseudo-class the browser does not know is thrown away whole. */
.video-wrap:fullscreen          { border-radius: 0; background: #000; }
.video-wrap:-webkit-full-screen { border-radius: 0; background: #000; }
.video-wrap:-moz-full-screen    { border-radius: 0; background: #000; }
.video-wrap:fullscreen #video,
.video-wrap:fullscreen video          { width: 100%; height: 100%; aspect-ratio: auto; object-fit: contain; background: #000; }
.video-wrap:-webkit-full-screen #video,
.video-wrap:-webkit-full-screen video { width: 100%; height: 100%; aspect-ratio: auto; object-fit: contain; background: #000; }
.video-wrap:-moz-full-screen #video,
.video-wrap:-moz-full-screen video    { width: 100%; height: 100%; aspect-ratio: auto; object-fit: contain; background: #000; }
.video-wrap::backdrop { background: #000; }

/* ---- LIVE / go-to-live pill (#wpvLive) ---- */
.wpv-live {
  position: absolute; top: 12px; left: 12px; z-index: 3;
  display: none; align-items: center; gap: 7px;
  cursor: pointer;
  border: 0;
  background: rgba(220,38,38,.92);
  color: #fff;
  font-weight: 800; font-size: .72rem; letter-spacing: .05em; text-transform: uppercase;
  padding: 6px 11px; border-radius: 999px;
  box-shadow: 0 6px 18px rgba(220,38,38,.35);
}
.wpv-live.on { display: inline-flex; }
.wpv-live.behind { background: rgba(10,22,40,.82); border: 1px solid var(--wpv-chrome-line); }
.wpv-live .d {
  width: 8px; height: 8px; border-radius: 50%;
  background: #fff;
  animation: wpvp 1.4s infinite;
}
.wpv-live.behind .d { background: var(--wpv-gold-light); animation: none; }
@keyframes wpvp {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.7); }
}

/* ---- Loading spinner + rotating message (#wpvSpin > .wpv-ldr + #wpvMsg) ---- */
.wpv-spin {
  position: absolute; inset: 0; z-index: 2;
  display: none; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  pointer-events: none;
}
.wpv-spin.on { display: flex; }
.wpv-ldr {
  display: block;
  width: 44px; height: 44px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,.18);
  border-top-color: var(--wpv-green-light);
  animation: wpvrot .9s linear infinite;
}
@keyframes wpvrot { to { transform: rotate(360deg); } }
/* The poster behind changes per channel, so the text carries its own soft backdrop */
.wpv-msg {
  color: #EAF1F8;
  font-weight: 600; font-size: .95rem; line-height: 1.35;
  text-align: center;
  max-width: min(90%, 520px);
  padding: 9px 17px; border-radius: 999px;
  background: rgba(8,16,30,.66);
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  border: 1px solid rgba(255,255,255,.10);
  box-shadow: 0 6px 22px rgba(0,0,0,.35);
  text-shadow: 0 1px 6px rgba(0,0,0,.55);
  transition: opacity .28s ease;
}
.wpv-msg:empty { display: none; }   /* no empty pill before the first message */
.wpv-msg.fade  { opacity: 0; }

/* ---- "Tap for sound" bubble (#wpvSound) ---- */
.wpv-sound {
  position: absolute; left: 50%; bottom: 64px; z-index: 4;
  transform: translateX(-50%);
  display: none; align-items: center; gap: 8px;
  cursor: pointer;
  background: rgba(10,22,40,.82);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--wpv-chrome-line);
  color: var(--wpv-chrome-ink);
  font-weight: 600; font-size: .9rem;
  padding: 10px 16px; border-radius: 999px;
  box-shadow: 0 10px 30px rgba(0,0,0,.4);
}
.wpv-sound.on { display: inline-flex; }
.wpv-sound svg { width: 18px; height: 18px; fill: currentColor; }

/* ---- Control bar (#wpvBar: #wpvPP, #wpvMute, #wpvVol, .wpv-spacer, #wpvFs) ---- */
.wpv-bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: none; align-items: center; gap: 10px;
  padding: 22px 12px 10px;
  background: linear-gradient(0deg, rgba(6,12,24,.92), rgba(6,12,24,0));
  opacity: 1;
  transition: opacity .25s ease;
}
.wpv-bar.on   { display: flex; }
.wpv-bar.idle { opacity: 0; pointer-events: none; }
.wpv-bar button {
  display: inline-flex;
  background: none; border: 0;
  color: var(--wpv-chrome-ink);
  cursor: pointer;
  padding: 6px; border-radius: 8px;
}
.wpv-bar button:hover { color: var(--wpv-green-light); }
.wpv-bar svg { display: block; width: 22px; height: 22px; fill: currentColor; }
.wpv-bar .wpv-spacer { flex: 1; }
.wpv-vol { width: 92px; height: 4px; accent-color: var(--wpv-green-light); cursor: pointer; }

/* ---- In-player gate (#wpvGate: .k, h4, p, .wpv-cta, .wpv-plat) ----
   The ::before/::after spacers centre the content when it fits and collapse to 0 when it does
   not, so a tall gate in a short (phone) player scrolls from the top instead of having its top
   cut off (which is what justify-content:center + overflow:auto does). */
.wpv-gate {
  position: absolute; inset: 0; z-index: 5;
  display: none; flex-direction: column; align-items: center; justify-content: flex-start; gap: 13px;
  text-align: center;
  padding: 26px 18px;
  overflow: auto;
  background: var(--wpv-player-bg);
  color: #F8FAFB;
}
.wpv-gate::before,
.wpv-gate::after { content: ""; flex: 1 0 0px; }
.wpv-gate.on { display: flex; }
.wpv-gate .k {
  color: var(--wpv-gold-light);
  font-weight: 800; letter-spacing: .12em; font-size: .72rem; text-transform: uppercase;
}
.wpv-gate h4 {
  font-family: inherit;
  font-weight: 900;
  font-size: clamp(1.05rem, 3.2vw, 1.5rem);
  line-height: 1.15;
  margin: 0;
}
.wpv-gate p { color: #CBD5E1; max-width: 520px; margin: 0; font-size: .94rem; line-height: 1.5; }
.wpv-gate .wpv-cta { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 2px; }
.wpv-gate .wpv-cta:empty { display: none; }
.wpv-gate .wpv-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: .95rem;
  padding: 11px 19px; border-radius: 11px;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  transition: filter .15s ease, transform .15s ease;
}
.wpv-gate .wpv-btn:hover { filter: brightness(1.07); transform: translateY(-1px); }
.wpv-gate .wpv-btn-green { background: linear-gradient(180deg, var(--wpv-green), var(--wpv-green-dark)); color: #fff; }
.wpv-gate .wpv-btn-gold  { background: linear-gradient(180deg, var(--wpv-gold-light), var(--wpv-gold)); color: #231a02; }
.wpv-gate .wpv-btn-green:hover { color: #fff; }
.wpv-gate .wpv-btn-gold:hover  { color: #231a02; }

/* device tiles block inside the gate (nocodec / error / vod) */
.wpv-plat { display: none; width: 100%; max-width: 640px; }
.wpv-plat.on { display: block; }

/* =========================================================================
   8. Device tiles (from player-platforms.css; the six tiles are divs with data-platform)
   ========================================================================= */
.platforms-or {
  display: flex; align-items: center; gap: 12px;
  max-width: 480px;
  margin: 2px auto 10px;
  text-align: center;
  font-family: inherit;
  font-size: .78rem; font-weight: 700;
  color: #94A3B8;
  text-transform: uppercase; letter-spacing: .08em;
}
.platforms-or::before,
.platforms-or::after { content: ""; flex: 1; border-top: 1px solid rgba(255,255,255,.12); }

.platforms-grid {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  max-width: 800px;
  margin: 0 auto;
}
.platforms-grid .platform-tile { flex: 1 0 88px; max-width: 110px; }
.platform-tile {
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 12px;
  padding: 18px 8px 14px;
  cursor: pointer;
  text-align: center;
  -webkit-user-select: none;
  user-select: none;
  transition: transform .18s, background .18s, border-color .18s, box-shadow .18s;
}
.platform-tile:hover {
  transform: translateY(-3px);
  background: rgba(22,163,74,.18);
  border-color: var(--wpv-green);
  box-shadow: 0 6px 20px rgba(22,163,74,.25);
}
.platform-tile-icon { display: block; font-size: 32px; color: #fff; margin-bottom: 8px; }
.platform-tile:hover .platform-tile-icon { color: var(--wpv-green-light); }
.platform-tile-label {
  font-family: inherit;
  font-size: .85rem; font-weight: 800;
  color: #fff;
  text-transform: uppercase; letter-spacing: .5px;
  line-height: 1.15;
}

/* Defensive light variant: tiles placed inside a (white) Bootstrap modal stay readable */
.modal .platform-tile { background: #f8fafc; border-color: #e2e8f0; }
.modal .platform-tile-icon,
.modal .platform-tile-label { color: var(--wpv-ink); }
.modal .platform-tile:hover { background: var(--wpv-green-50); border-color: var(--wpv-green); box-shadow: 0 6px 20px rgba(22,163,74,.15); }
.modal .platform-tile:hover .platform-tile-icon { color: var(--wpv-green); }

/* =========================================================================
   9. Chrome/Brave HEVC notice tiles (#chromeNoticeSlot .cn-tiles > a.cn-tile)
   The strip is one inline-flex unit: it sits next to the text or moves to the next line
   wholesale, never split tile by tile.
   ========================================================================= */
.cn-tiles {
  display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 4px;
  vertical-align: middle;
}
.cn-tile {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: 26px; height: 26px;
  border-radius: 6px;
  background: rgba(255,255,255,.7);
  border: 1px solid rgba(0,0,0,.12);
  color: var(--wpv-green-dark);
  font-size: 14px; line-height: 1;
  text-decoration: none;
  transition: background .15s, color .15s, transform .15s;
}
.cn-tile:hover,
.cn-tile:focus {
  background: var(--wpv-green);
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
}

/* =========================================================================
   10. Footer (footer.wpv-foot.container-xxl)
   ========================================================================= */
.wpv-foot {
  margin-top: 22px;
  padding: 16px 12px 22px;
  text-align: center;
  font-size: .78rem;
  color: #7286A0;
  border-top: 1px solid rgba(15,23,42,.07);
}

/* =========================================================================
   11. Misc: reCAPTCHA badge toggle, Tutorials modal polish
   ========================================================================= */
/* badge hidden until JS adds body.show-badge (login / recover / contact forms) */
.grecaptcha-badge { visibility: hidden; opacity: 0; pointer-events: none; transition: opacity .2s ease; }
body.show-badge .grecaptcha-badge { visibility: visible; opacity: 1; pointer-events: auto; }

#tutorialsModal .modal-body { padding: 0; }
#tutorialsModal .accordion-button { font-weight: 600; }
#tutorialsModal img,
#tutorialsModal iframe { max-width: 100%; height: auto; }
#tutorialsModal iframe { width: 100%; aspect-ratio: 16 / 9; }

/* =========================================================================
   12. Keyboard focus rings
   ========================================================================= */
/* light surfaces */
.channel-card:focus-visible,
.wpv-fav:focus-visible,
.wpv-back:focus-visible,
.wpv-search-x:focus-visible,
.wp-expired-renew:focus-visible,
.wp-expired-switch:focus-visible,
.cn-tile:focus-visible {
  outline: 2px solid var(--wpv-green);
  outline-offset: 2px;
}
/* list rows are flush and touch each other: draw the ring inside the row */
.list-group-item-action:focus-visible {
  outline: 2px solid var(--wpv-green);
  outline-offset: -2px;
}
/* dark player chrome */
.wpv-live:focus-visible,
.wpv-sound:focus-visible,
.wpv-bar button:focus-visible,
.wpv-vol:focus-visible,
.wpv-gate .wpv-btn:focus-visible,
.platform-tile:focus-visible {
  outline: 2px solid var(--wpv-green-light);
  outline-offset: 2px;
}
.modal .platform-tile:focus-visible { outline-color: var(--wpv-green); }

/* =========================================================================
   13. Small screens (tiles 760/480 from player-platforms.css; 600/380 tweaks)
   ========================================================================= */
@media (max-width: 760px) {
  .platforms-grid { max-width: 520px; }
  .platforms-grid .platform-tile { flex-basis: 96px; max-width: 130px; }
}

@media (max-width: 600px) {
  /* 16px stops iOS Safari zooming the page when the search box gets focus */
  .wpv-search input { font-size: 16px; }

  .wp-expired-bar     { padding: 10px 14px; }
  .wp-expired-actions { width: 100%; justify-content: space-between; }
  .wp-expired-renew   { flex: 1; justify-content: center; }

  .wpv-msg   { font-size: .85rem; padding: 8px 14px; }
  .wpv-sound { bottom: 58px; }
  .wpv-vol   { width: 60px; }

  .wpv-gate   { padding: 16px 12px; gap: 9px; }
  .wpv-gate p { font-size: .88rem; }
  .wpv-gate .wpv-btn { font-size: .88rem; padding: 9px 15px; }

  /* the gate lives inside a ~16:9 box: keep the device tiles compact there */
  .wpv-plat .platforms-grid { gap: 8px; }
  .wpv-plat .platform-tile { padding: 10px 6px 9px; min-height: 0; }
  .wpv-plat .platform-tile-icon { font-size: 22px; margin-bottom: 5px; }
  .wpv-plat .platform-tile-label { font-size: .7rem; line-height: 1.2; }
}

@media (max-width: 480px) {
  .platforms-grid .platform-tile { flex-basis: 88px; max-width: 110px; }
  .platform-tile { padding: 16px 8px 14px; min-height: 92px; }
  .platform-tile-icon { font-size: 28px; }
  .platform-tile-label { font-size: .78rem; line-height: 1.2; }
}

@media (max-width: 380px) {
  .sticky-header { padding: 12px 10px 8px; }
  .wpv-crumb { font-size: .7rem; padding: 6px 10px; }
  .wpv-back  { padding: 6px 10px; }

  .wp-expired-bar { gap: 10px; }

  .wpv-bar   { gap: 4px; padding: 18px 6px 6px; }
  .wpv-vol   { width: 48px; }
  .wpv-msg   { font-size: .8rem; }
  .wpv-sound { font-size: .82rem; padding: 8px 13px; }

  .wpv-gate h4 { font-size: 1rem; }
  .wpv-gate p  { font-size: .82rem; }
  .wpv-plat .platforms-grid .platform-tile { flex-basis: 72px; }
  .wpv-plat .platforms-or { font-size: .7rem; }
}

/* =========================================================================
   14. Reduced motion
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .wp-live-dot,
  .wp-live-dot::after,
  .ls-loading .dot,
  .wpv-live .d { animation: none; }
  .wpv-ldr { animation-duration: 1.8s; }   /* keep a slow spinner: it is the only progress cue */
  .channel-card,
  .channel-card:hover,
  .platform-tile,
  .platform-tile:hover,
  .wp-expired-renew:hover,
  .wpv-gate .wpv-btn:hover,
  .cn-tile:hover { transition: none; transform: none; }
}
