.tvp{position:relative;background:#000;line-height:0}
.tvp-video{display:block;width:100%;aspect-ratio:16/9;background:#000}

.tvp-bar{position:absolute;left:0;right:0;bottom:0;padding:30px 14px 11px;line-height:1;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.88));
  opacity:0;transition:opacity .18s ease;pointer-events:none}
.tvp:hover .tvp-bar,.tvp:focus-within .tvp-bar,.tvp.busy .tvp-bar,
.tvp.show .tvp-bar{opacity:1;pointer-events:auto}
/* A touch screen has no hover, so the bar would appear once while buffering and
   then never again; there it is revealed by a tap instead. */
@media (hover:none){.tvp .tvp-bar{opacity:0}.tvp.show .tvp-bar{opacity:1}}

/* the live line. These streams have no end, so it is drawn against the window
   the server keeps rather than a duration, and goes flat when there is none. */
.tvp-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;
  margin:0 2px 6px;touch-action:none}
.tvp-seek:before{content:"";position:absolute;left:0;right:0;height:4px;border-radius:99px;
  background:rgba(255,255,255,.26)}
.tvp-seek-buf{position:absolute;left:0;height:4px;border-radius:99px;background:rgba(255,255,255,.34)}
.tvp-seek-fill{position:absolute;left:0;height:4px;border-radius:99px;background:var(--accent)}
.tvp-seek-dot{position:absolute;right:-6px;top:50%;width:12px;height:12px;margin-top:-6px;
  border-radius:50%;background:#fff;opacity:0;transition:opacity .15s}
.tvp-seek:hover .tvp-seek-dot,.tvp-seek:focus-visible .tvp-seek-dot{opacity:1}
.tvp-seek:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:99px}
.tvp.nodvr .tvp-seek{cursor:default}
.tvp.nodvr .tvp-seek-dot{display:none}

.tvp-row{display:flex;align-items:center;gap:11px}
.tvp-btn{background:none;border:0;color:#fff;font-size:16px;cursor:pointer;padding:7px;border-radius:9px;
  display:grid;place-items:center}
.tvp-btn:hover{background:rgba(255,255,255,.18)}
/* [hidden] is a UA rule on the element, so any class that sets display beats
   it. Without this the quality gear stayed on screen for a stream with one
   rendition and opened an empty menu, and the same for PiP where the browser
   does not support it. */
.tvp-btn[hidden]{display:none}
.tvp-vol{width:78px;accent-color:var(--accent)}
.tvp-name{font-weight:800;font-size:.86rem;opacity:.9;color:#fff;white-space:nowrap}
.tvp-spacer{flex:1}

/* the live tag, in the channel's colour. The dot pulses so a glance tells you
   this is a broadcast; scrub back and it dims to a plain button that takes you
   to the edge again. */
.tvp-live{display:inline-flex;align-items:center;gap:7px;font-weight:900;font-size:.7rem;
  letter-spacing:.13em;background:var(--accent);color:#fff;padding:5px 10px;border-radius:999px;
  border:0;cursor:pointer;font-family:inherit}
.tvp-live i{width:7px;height:7px;border-radius:50%;background:currentColor;
  animation:tvp-pulse 1.6s ease-in-out infinite}
.sport-page .tvp-live{color:#0a0a0d}       /* white would not read on the gold */
.tvp.behind .tvp-live{background:rgba(255,255,255,.2);color:#fff}
.tvp.behind .tvp-live i{animation:none;opacity:.5}
@keyframes tvp-pulse{0%,100%{opacity:1}50%{opacity:.2}}
@media (prefers-reduced-motion:reduce){.tvp-live i{animation:none}}

/* quality. Hidden unless the stream actually publishes more than one rendition,

/* Icons are SVG here, not Font Awesome — this theme does not load an icon font. */
.tvp-btn svg{width:18px;height:18px;fill:currentColor}
.tvp-live svg,.tvp-unmute svg{width:16px;height:16px;fill:currentColor}
.tvp-unmute{position:absolute;left:14px;bottom:70px;display:flex;align-items:center;gap:8px;
  padding:9px 14px;border-radius:999px;border:0;cursor:pointer;color:#fff;font-weight:800;
  font-size:12.5px;background:rgba(0,0,0,.72);backdrop-filter:blur(8px)}
.tvp-unmute[hidden]{display:none}
.tvp-menu{position:absolute;right:0;bottom:44px;min-width:132px;padding:6px;border-radius:12px;
  background:rgba(16,16,22,.97);border:1px solid rgba(255,255,255,.12);display:grid;gap:2px}
.tvp-menu[hidden]{display:none}
.tvp-menu button{background:none;border:0;color:#dcdce6;text-align:left;padding:8px 11px;
  border-radius:8px;font:inherit;font-size:13px;cursor:pointer}
.tvp-menu button:hover{background:rgba(255,255,255,.08)}
.tvp-menu button.on{color:var(--accent,#e8833a);font-weight:800}
.tvp-menu-wrap{position:relative;display:inline-grid}

/* ---------------------------------------------------------------------------
   Player must fill the frame it sits in.

   .screen-wrap is a centring flex row (align-items:center; justify-content:
   center). .tvp is its only child and is block-level with no width, so as a
   flex item it shrank to its own content — and a <video> with no width/height
   attributes reports the browser default intrinsic size, 300x150. With
   aspect-ratio:16/9 that settled at 300x169.

   The visible symptom was not an obviously broken layout: .tvp-bar is
   position:absolute;bottom:0, so it stayed correctly pinned to the bottom of
   the *player* — which was a 300px box floating dead centre of a 708x398
   black frame. It read as a control bar hovering in the middle of nothing.
   --------------------------------------------------------------------------- */
.screen-wrap > .tvp { flex: 1 1 auto; width: 100%; min-width: 0; }

/* Letterbox rather than stretch if a source is not 16:9. */
.tvp-video { object-fit: contain; }

/* ---------------------------------------------------------------------------
   tvp-unmute BANNER — "sound is off"

   Live TV starts muted because browsers permit unattended playback no other
   way. That leaves a viewer watching silent television, so the offer of sound
   has to be legible at a glance rather than a small icon tucked above the
   control bar. It sits top-centre, over the picture but clear of the controls,
   and disappears the moment sound is on.
   --------------------------------------------------------------------------- */
.tvp-unmute {
  left: 50%;
  right: auto;
  top: 14px;
  bottom: auto;
  transform: translateX(-50%);
  gap: 10px;
  padding: 11px 18px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  background: rgba(12, 12, 14, .82);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  color: #fff;
  font-weight: 700;
  font-size: .82rem;
  line-height: 1;
  letter-spacing: .01em;
  cursor: pointer;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
  z-index: 5;
  animation: tvp-unmute-in .32s ease-out both;
}
.tvp-unmute:hover,
.tvp-unmute:focus-visible { background: var(--accent, #e8833a); border-color: transparent; }
.tvp-unmute:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.tvp-unmute svg { width: 17px; height: 17px; fill: currentColor; flex: none; }

@keyframes tvp-unmute-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .tvp-unmute { animation: none; }
}

/* ---------------------------------------------------------------------------
   The message plate.

   Until now every failure ended in an empty catch and the viewer got a black
   rectangle: a channel needing sign-in, a channel that no longer exists and a
   dropped connection were indistinguishable. This says which. It sits over the
   picture, clear of the control bar, and disappears the moment playback starts.
   --------------------------------------------------------------------------- */
.tvp-msg {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  max-width: min(30ch, 86%);
  padding: 13px 18px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, .14);
  background: rgba(12, 12, 14, .88);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  color: #fff;
  font-size: .88rem;
  font-weight: 600;
  line-height: 1.45;
  text-align: center;
  text-wrap: balance;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
  z-index: 6;
}
.tvp-msg[hidden] { display: none !important; }

/* Audio only: there is no picture to show, so give the frame the house tile
   rather than a black hole that reads as a broken stream. */
.tvp.is-audio-only .tvp-video {
  background: #0b0b0e url('/wp-content/uploads/brand/tl-tv-fallback.png') center / 92px no-repeat;
}

/* ---- narrow screens ------------------------------------------------------
   This file had no width-based media query at all. The control row is one
   non-wrapping flex line; measured on the live page its ten children plus the
   11px gaps need 613px, while the page gutter takes 78px of the viewport. So
   it only ever fit above ~691px, and below that it ran off the right edge -
   taking Picture-in-Picture and, being last in the row, FULLSCREEN with it.
   On a 390-430px phone the button was simply not on screen.

   Shed what a phone does not need rather than shrinking everything:
   the channel name repeats the <h1> directly above the player, and the volume
   slider is redundant next to the hardware volume keys (mute stays). */
@media (max-width: 700px) {
  .tvp-name { display: none; }
}
@media (max-width: 600px) {
  /* 6px, not 8: with the name and slider gone the row needs 298px at this
     gap and a 390px phone leaves 312px, so it lands on one line. At 8px it
     needed exactly the 312px available and tipped onto a second line. */
  .tvp-row { gap: 6px; flex-wrap: wrap; row-gap: 8px; }
  .tvp-vol { display: none; }
  /* Let the spacer collapse to nothing before anything is pushed out of view,
     and if a very narrow screen still cannot fit the row, wrap to a second
     line instead of hiding the controls past the edge. */
  .tvp-spacer { flex: 1 1 0; min-width: 0; }
}
