/* VOID player. Everything is scoped under .vpx so it can drop into VOIDtv (or any page) without leaking.
   Colours follow the brand kit; override the custom properties to re-skin. */
.vpx{--vpx-ink:#e8e8ee;--vpx-dim:#9aa0b4;--vpx-accent:#5fd4ff;--vpx-gold:#f2a93b;--vpx-bg:#000;--vpx-bar:rgba(7,8,12,.86);--vpx-focus:#5fd4ff;
  position:relative;display:block;width:100%;aspect-ratio:16/9;background:var(--vpx-bg);color:var(--vpx-ink);overflow:hidden;border-radius:12px;
  font:14px/1.3 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;-webkit-tap-highlight-color:transparent;user-select:none;contain:layout paint;container-type:inline-size}
.vpx:focus{outline:none}.vpx:focus-visible{box-shadow:0 0 0 3px var(--vpx-focus) inset}
/* the picture: always the whole player box, centred, as big as fits without stretching. Every box property is
   set here, at higher specificity than a host's element rules (VOIDtv has video{max-height:70vh;border-radius:8px}
   and .tv video{aspect-ratio:16/9}, which once capped fullscreen at 70% height, top-aligned). */
.vpx .vpx-video{position:absolute;inset:0;display:block;width:100%;height:100%;min-width:0;min-height:0;max-width:none;max-height:none;
  margin:0;padding:0;border:0;border-radius:0;aspect-ratio:auto;object-fit:contain;object-position:center;background:#000;outline:none}
.vpx-shade{position:absolute;inset:0}
.vpx svg{width:22px;height:22px;display:block;flex:none}

/* control bar */
.vpx-bar{position:absolute;left:0;right:0;bottom:0;padding:28px 12px 8px;background:linear-gradient(transparent,var(--vpx-bar) 55%);opacity:0;transform:translateY(6px);transition:opacity .2s,transform .2s;pointer-events:none}
.vpx.vpx-show .vpx-bar,.vpx.paused .vpx-bar{opacity:1;transform:none;pointer-events:auto}
/* keyboard focus on a control keeps the bar up; a mouse click does not (.vpx:focus-within did, and since the player
   itself takes focus on click, it kept the controls over the picture for good, fullscreen included). Its own rule,
   so a browser without :has drops only this line. */
.vpx-bar:has(:focus-visible){opacity:1;transform:none;pointer-events:auto}
.vpx.vpx-show,.vpx.paused{cursor:default}.vpx:not(.vpx-show):not(.paused){cursor:none}
.vpx-title{font-weight:600;margin:0 4px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 4px #000}
.vpx-row{display:flex;align-items:center;gap:2px}
.vpx-row button,.vpx-btn{appearance:none;border:0;background:transparent;color:inherit;min-width:40px;height:40px;padding:0 8px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;gap:6px;cursor:pointer;font:inherit;text-decoration:none}
.vpx-row button:hover,.vpx-btn:hover{background:rgba(255,255,255,.1)}
.vpx button:focus-visible,.vpx a:focus-visible,.vpx input:focus-visible{outline:3px solid var(--vpx-focus);outline-offset:2px}
.vpx-row button.vpx-on,.vpx-speed.vpx-on{color:var(--vpx-accent)}
.vpx-speed{font-weight:700;min-width:48px}
.vpx-time{margin-left:8px;font-variant-numeric:tabular-nums;color:var(--vpx-dim);white-space:nowrap}
.vpx-sp{flex:1}
.vpx-vol{width:84px;accent-color:var(--vpx-accent)}

/* seek bar: a big invisible range over thin painted tracks */
.vpx-seek{position:relative;height:18px;margin:0 4px 4px;cursor:pointer}
.vpx-seek::before,.vpx-buf,.vpx-played{content:"";position:absolute;left:0;top:7px;height:4px;border-radius:2px}
.vpx-seek::before{right:0;background:rgba(255,255,255,.18)}
.vpx-buf{background:rgba(255,255,255,.35);width:0}
.vpx-played{background:var(--vpx-accent);width:0}
.vpx-seek:hover .vpx-buf,.vpx-seek:hover .vpx-played,.vpx-seek:hover::before{top:6px;height:6px}
.vpx-seek input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.vpx-seek input:focus-visible+*{outline:none}
.vpx-seek:focus-within::before{box-shadow:0 0 0 2px var(--vpx-focus)}

/* big play button, spinner, status line, skip flash */
.vpx-big{position:absolute;left:50%;top:50%;width:76px;height:76px;margin:-38px 0 0 -38px;border-radius:50%;border:0;background:rgba(7,8,12,.62);color:#fff;display:none;align-items:center;justify-content:center;cursor:pointer}
.vpx-big svg{width:36px;height:36px;margin-left:4px}
.vpx.paused:not(.vpx-wait) .vpx-big{display:flex}
.vpx-status{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:none;flex-direction:column;align-items:center;gap:10px;text-align:center;pointer-events:none;text-shadow:0 1px 6px #000}
.vpx.vpx-wait .vpx-status,.vpx.vpx-has-status .vpx-status{display:flex}
/* "tuning in": a broadcast signal pulsing outward (replaces the spinner). Smooth fades, no flashing. */
.vpx-sig{width:56px;height:56px;display:block;filter:drop-shadow(0 0 6px rgba(95,212,255,.55))}
.vpx-sig svg{width:100%;height:100%;overflow:visible}
.vpx-sig path{fill:none;stroke:var(--vpx-accent);stroke-width:3.6;stroke-linecap:round;opacity:.18;animation:vpx-arc 1.6s ease-in-out infinite}
.vpx-sig .vpx-d{fill:var(--vpx-accent)}
.vpx-sig .a2{animation-delay:.2s}.vpx-sig .a3{animation-delay:.4s}
@keyframes vpx-arc{0%,100%{opacity:.18}35%{opacity:1}70%{opacity:.18}}
/* recovering (reconnecting / switching servers): gold, sweeping back in, a calm "searching" */
.vpx.vpx-recovering .vpx-sig{filter:drop-shadow(0 0 6px rgba(242,169,59,.55))}
.vpx.vpx-recovering .vpx-sig path{stroke:var(--vpx-gold);animation-direction:reverse;animation-duration:1.2s}
.vpx.vpx-recovering .vpx-sig .vpx-d{fill:var(--vpx-gold)}
.vpx:not(.vpx-wait) .vpx-sig{display:none}
.vpx-status-t{font-size:15px;color:var(--vpx-ink)}
.vpx-status-t:not(:empty){background:rgba(7,8,12,.62);padding:6px 12px;border-radius:999px}
.vpx-flash{position:absolute;top:50%;transform:translateY(-50%);padding:10px 16px;border-radius:999px;background:rgba(7,8,12,.7);font-weight:700;font-size:18px;opacity:0;transition:opacity .15s;pointer-events:none}
.vpx-flash.vpx-on{opacity:1}.vpx-flash.vpx-l{left:12%}.vpx-flash.vpx-r{right:12%}

/* stats for nerds (Shift+D) */
.vpx-stats{position:absolute;left:10px;top:10px;max-width:calc(100% - 20px);background:rgba(7,8,12,.86);border:1px solid rgba(255,255,255,.14);border-radius:8px;padding:8px 10px;z-index:3;user-select:text}
.vpx-stats[hidden]{display:none}
.vpx-stats pre{margin:0 0 6px;font:11px/1.45 ui-monospace,Consolas,monospace;white-space:pre-wrap;color:var(--vpx-ink)}
.vpx-stats div{display:flex;gap:6px}.vpx-stats button{appearance:none;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);color:inherit;border-radius:6px;padding:4px 8px;font:12px system-ui,sans-serif;cursor:pointer;display:inline-flex;align-items:center}
.vpx-stats button svg{width:14px;height:14px}

/* cards: up next, failure */
.vpx-card{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:24px;text-align:center;background:rgba(7,8,12,.88)}
.vpx-card[hidden]{display:none}
/* no signal: faint static that changes only twice a second (well under 3 flashes/s, WCAG 2.3.1) */
.vpx-card.static::before{content:"";position:absolute;inset:0;opacity:.09;pointer-events:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");animation:vpx-static 1s steps(2) infinite}
@keyframes vpx-static{0%{background-position:0 0}50%{background-position:-53px 29px}100%{background-position:31px -47px}}
.vpx-card>*{position:relative}
.vpx-nosig svg{width:44px;height:44px;opacity:.85}
/* up next: a ring that drains over the countdown, with the seconds inside; the title slides in */
.vpx-ring{position:relative;width:44px;height:44px;display:inline-grid;place-items:center;margin-right:4px}
.vpx-ring svg{position:absolute;inset:0;transform:rotate(-90deg)}
.vpx-ring circle{fill:none;stroke-width:3}.vpx-ring .bg{stroke:rgba(255,255,255,.15)}
.vpx-ring .fg{stroke:var(--vpx-gold);stroke-linecap:round;stroke-dasharray:100.53;stroke-dashoffset:0;animation:vpx-drain linear forwards}
.vpx-ring b{font-variant-numeric:tabular-nums;font-size:15px}
@keyframes vpx-drain{to{stroke-dashoffset:100.53}}
.vpx-card.upnext .vpx-k,.vpx-card.upnext .vpx-t{animation:vpx-in .45s ease-out both}.vpx-card.upnext .vpx-t{animation-delay:.08s}
@keyframes vpx-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.vpx-k{margin:0;font-size:18px;font-weight:700}
.vpx-t{margin:0;font-size:16px}
.vpx-dim{color:var(--vpx-dim);margin:0;max-width:44ch}
.vpx-acts{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;align-items:center;margin-top:8px}
.vpx-acts button,.vpx-acts .vpx-btn{appearance:none;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);color:inherit;min-height:44px;padding:0 16px;border-radius:10px;display:inline-flex;align-items:center;gap:8px;cursor:pointer;font:inherit;text-decoration:none}
.vpx-acts .vpx-primary{background:var(--vpx-gold);color:#07080c;border-color:var(--vpx-gold);font-weight:700}
.vpx-acts svg{width:18px;height:18px}

/* fullscreen: fill the screen, keep the picture's own shape */
.vpx.vpx-fs,.vpx:fullscreen{border-radius:0;aspect-ratio:auto;width:100vw;height:100vh}
.vpx:fullscreen .vpx-bar{padding-bottom:max(8px,env(safe-area-inset-bottom))}

/* narrow players (phones, side columns): bigger targets, fewer controls. Keyed to the PLAYER's width, so it
   also works when the player sits in a narrow column on a wide screen. Double-tap the sides still skips. */
@container (max-width:560px){
  .vpx-row button{min-width:44px;height:44px;padding:0 6px}
  .vpx-vol,.vpx-row [data-a=pip],.vpx-row [data-a=speed]{display:none}
  .vpx-time{font-size:12px;margin-left:2px}
}
@container (max-width:420px){.vpx-row [data-a=back],.vpx-row [data-a=fwd]{display:none}}
/* cards on small players: tighter, so the actions always fit inside the picture */
@container (max-width:560px){
  .vpx-card{padding:10px 14px;gap:4px;overflow:auto}
  .vpx-k{font-size:15px}.vpx-t{font-size:14px}.vpx-dim{font-size:12px}
  .vpx-nosig svg{width:28px;height:28px}
  .vpx-acts{gap:6px;margin-top:4px}.vpx-acts button,.vpx-acts .vpx-btn{min-height:36px;padding:0 10px;font-size:13px}
  .vpx-ring{width:36px;height:36px}.vpx-ring b{font-size:13px}
}
/* phone-sized players: the heading and the buttons; the explanation and icon give way */
@container (max-width:420px){.vpx-card .vpx-dim,.vpx-nosig{display:none}.vpx-k{font-size:14px}}
/* browsers without container queries fall back to the screen width */
@supports not (container-type:inline-size){@media (max-width:600px){
  .vpx-row button{min-width:44px;height:44px;padding:0 6px}
  .vpx-vol,.vpx-row [data-a=pip],.vpx-row [data-a=speed],.vpx-row [data-a=back],.vpx-row [data-a=fwd]{display:none}
  .vpx-time{font-size:12px;margin-left:2px}
}}
/* TV / 10-foot screens: larger everything, focus you can see from the couch */
@media (min-width:1600px) and (hover:none),(min-width:1900px){
  .vpx{font-size:18px}.vpx svg{width:28px;height:28px}
  .vpx-row button{min-width:56px;height:56px}
  .vpx button:focus-visible{outline-width:4px}
}
@media (prefers-reduced-motion:reduce){.vpx-bar,.vpx-flash{transition:none}.vpx-sig path{animation:none;opacity:.85}.vpx-card.static::before{animation:none}.vpx-card.upnext .vpx-k,.vpx-card.upnext .vpx-t{animation:none}}

/* Live TV: two big channel buttons in the control row (player.js, only when the host passes channelButtons) and the channel-name flash.
   Brand pink #ff4fc8 at 60% opacity; the row's own rules stay as they are. The selectors carry button.vpx-ch so they beat .vpx-row button:hover. */
.vpx-row button.vpx-ch{min-width:68px;height:52px;padding:0 14px;gap:2px;margin-left:6px;border-radius:12px;background:rgba(255,79,200,.6);color:#fff;font-weight:800;font-size:16px;letter-spacing:.05em}
.vpx-row button.vpx-ch:hover{background:rgba(255,79,200,.8)}
.vpx-row button.vpx-ch svg{width:24px;height:24px}
.vpx-chname{position:absolute;top:14px;right:14px;max-width:calc(100% - 28px);padding:8px 16px;border-radius:999px;background:rgba(7,8,12,.72);border:2px solid rgba(255,79,200,.6);font-weight:800;font-size:20px;letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;opacity:0;visibility:hidden;transition:opacity .25s,visibility 0s .25s}
.vpx-chname.vpx-on{opacity:1;visibility:visible;transition:opacity .15s}
@container (max-width:560px){
  .vpx-row button.vpx-ch{min-width:52px;height:48px;padding:0 8px;margin-left:2px;font-size:14px}
  .vpx-chname{top:8px;right:8px;max-width:calc(100% - 16px);padding:6px 12px;font-size:16px}
}
@supports not (container-type:inline-size){@media (max-width:760px){
  .vpx-row button.vpx-ch{min-width:52px;height:48px;padding:0 8px;margin-left:2px;font-size:14px}
  .vpx-tv .vpx-time{display:none}
}}
@media (min-width:1600px) and (hover:none),(min-width:1900px){.vpx-row button.vpx-ch{min-width:84px;height:64px;font-size:20px}.vpx-chname{font-size:28px;padding:10px 22px}}
@media (prefers-reduced-motion:reduce){.vpx-chname,.vpx-chname.vpx-on{transition:none}}
/* Live TV players up to 720 px wide: the compact channel buttons, and the elapsed time gives way, so the fullscreen button always fits the row
   (the two big buttons and the time did not fit between 430 and 470 px and between 561 and 700 px, and the row ran past the player's edge). Last in the file so it also beats the 10-foot sizes above in a narrow player. */
@container (max-width:720px){
  .vpx-row button.vpx-ch{min-width:52px;height:48px;padding:0 8px;margin-left:2px;font-size:14px}
  .vpx-tv .vpx-time{display:none}
}
