/* ============================================================================
   S4U lite mode (site wide).
   Cuts the expensive paint work for low-powered devices: backdrop blur off
   everywhere, transitions and decorative animations reduced to near zero on
   s4u surfaces. Per device via localStorage 's4u.liteMode' ('1' explicit on,
   '0' explicit off, absent = auto: the lite-auto.js GPU probe turns lite on
   when the machine renders without hardware acceleration), applied as the
   `s4u-lite` class on <html> by an inline head snippet in the three layouts
   (_Layout, _S4ULayout, _S4ULoginLayout) BEFORE first paint. The class does
   NOT cascade into iframes, so every document (mosaic feed boxes, the
   channel-browser sheet) self-applies via its own snippet, and a `storage`
   listener in the snippet follows toggles made in other tabs or in the parent.
   Toggle UIs: the page-size dialog (page-zoom.js) and the player settings
   drawer.

   Standalone on purpose: it also loads on the legacy Materialize layout where
   design-system.css is absent. Old-TV notes (Chromium ~49): plain selectors
   only (attribute substring is fine), no oklch, no :is()/:where(), no `inset`.

   Kill style: near-zero DURATIONS, never `animation/transition: none`.
   transitionend/animationend still fire and `forwards` fills still land on
   their end state, so JS that waits on either keeps working, just instantly.

   The motion kill is scoped to s4u surfaces (.s4u content plus s4u-prefixed
   chrome/widgets). Careful: shell pages set body class "s4u-shell" and the
   login layout "s4u-body", both match [class*="s4u-"], so there the scope is
   the WHOLE document, vendor overlays on <body> included (video engines,
   SweetAlert). Their loading spinners are re-allowed in section 4. Only
   legacy _Layout pages stay out of scope (Materialize preloader, legacy
   #pageunloader keep animating on their own).
   ========================================================================== */

/* ---- 1) Backdrop blur off ------------------------------------------------
   The single biggest paint cost of the redesign (only s4u CSS uses it), and
   brutal with hardware acceleration off. Global under the flag on purpose. */
html.s4u-lite *,
html.s4u-lite *::before,
html.s4u-lite *::after {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* ---- 2) Blur-dependent surfaces ------------------------------------------
   These read fine blurred at low alpha but turn see-through without it.
   Nudge toward opaque; values track the source declarations (same rgb, higher
   alpha). Scrims and near-opaque sheets (alpha >= 0.9) need no help. */

/* login glass card: login.css .s4u-card rgba(14,14,18,0.62) */
html.s4u-lite .s4u-card { background: rgba(14, 14, 18, 0.94); }

/* shell top bar, content scrolls under it: app-shell.css .s4u-top rgba(10,10,12,0.72) */
html.s4u-lite .s4u-top { background: rgba(10, 10, 12, 0.96); }

/* immersive-exit chip over live video: app-shell.css rgba(18,18,22,0.62) */
html.s4u-lite .s4u-immersive-exit { background: rgba(18, 18, 22, 0.9); }

/* mosaic hover pills over video: mosaic.css rgba(12,11,10,0.82) */
html.s4u-lite .s4u .colm .tile-promote { background: rgba(12, 11, 10, 0.94); }
html.s4u-lite .s4u .colm .tile-framecatch::before,
html.s4u-lite .s4u .colm:not(.is-hero) .tile-swapcatch::before { background: rgba(12, 11, 10, 0.94); }

/* ---- 3) Motion off on s4u surfaces --------------------------------------- */
html.s4u-lite .s4u,
html.s4u-lite .s4u::before,
html.s4u-lite .s4u::after,
html.s4u-lite .s4u *,
html.s4u-lite .s4u *::before,
html.s4u-lite .s4u *::after,
html.s4u-lite [class*="s4u-"],
html.s4u-lite [class*="s4u-"]::before,
html.s4u-lite [class*="s4u-"]::after,
html.s4u-lite [class*="s4u-"] *,
html.s4u-lite [class*="s4u-"] *::before,
html.s4u-lite [class*="s4u-"] *::after {
  transition-duration: 0.01ms !important;
  transition-delay: 0s !important;
  animation-duration: 0.01ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
}

/* ---- 4) Functional animations survive the kill ---------------------------
   Loading feedback is not decoration: frozen bars read as a hang. Durations
   restated from the source files (keep in sync if those change).
   Higher specificity than the kill above, so order is belt and braces. */

/* indeterminate loading bars: app-shell.css (1.05s) + login.css (1.1s) share
   the class; one restated duration covers both, visually identical */
html.s4u-lite .s4u-progress .bar {
  animation-duration: 1.1s !important;
  animation-iteration-count: infinite !important;
}

/* player restart busy spinner: player.css s4u-restart-spin 0.8s linear infinite */
html.s4u-lite .s4u .s4u-stage-info__link--restart.is-busy svg {
  animation-duration: 0.8s !important;
  animation-iteration-count: infinite !important;
}

/* mosaic "Audio" cue: rests at opacity:0 and only its 3s forwards animation
   ever shows it (mosaic.css s4u-audio-cue); a near-zero duration would jump
   straight to the faded end state and the cue would never be seen */
html.s4u-lite .s4u .colm .tile-selected::after {
  animation-duration: 3s !important;
  animation-iteration-count: 1 !important;
}

/* Vendor player spinners: on shell pages body.s4u-shell puts the whole
   document in the kill scope (see header), so every video-engine buffering
   spinner froze. Selectors stay unscoped under the flag on purpose: they
   survive the theater reparenting video chrome to <body>, and each restated
   value matches the vendor rule, so pages outside the kill scope render the
   same as without the flag. Values come from the bundles the views actually
   load; keep in sync on player upgrades. Delays are restated too because
   the kill zeroes animation-delay. Flowplayer needs no entry: its waiting
   icon animates via SMIL inside the SVG, immune to the CSS kill. */

/* Clappr buffering spinner (/Player): clappr.min.js injects `bouncedelay
   1.4s infinite ease-in-out` with fill-mode:both, so the killed one-shot
   run parks on the last frame, scale(0): not just frozen, INVISIBLE.
   Negative delays restore the three-dot stagger. */
html.s4u-lite .spinner-three-bounce[data-spinner] > div {
  animation-duration: 1.4s !important;
  animation-iteration-count: infinite !important;
}
html.s4u-lite .spinner-three-bounce[data-spinner] > [data-bounce1] { animation-delay: -0.32s !important; }
html.s4u-lite .spinner-three-bounce[data-spinner] > [data-bounce2] { animation-delay: -0.16s !important; }

/* JW buffering icon (/Player JW engine, /Mosaic "J Player" boxes): jwplayer
   core injects `jw-spin 2s linear infinite`, display-gated by state class */
html.s4u-lite .jwplayer.jw-state-buffering .jw-svg-icon-buffer {
  animation-duration: 2s !important;
  animation-iteration-count: infinite !important;
}

/* Bitmovin buffering dots (shell DRM pages + mosaic DRM box iframes):
   bitmovinplayer-ui.css pulses three indicator dots (`fancy` 2s up to
   8.18x, `bmpui-fancy` 1.5s on 8.248+). One restated duration covers all
   versions; 2s so the legacy-layout DRM pages, which were never frozen,
   keep their exact original timing. nth-child restores the dot stagger. */
html.s4u-lite .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator {
  animation-duration: 2s !important;
  animation-iteration-count: infinite !important;
}
html.s4u-lite .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(2) { animation-delay: 0.2s !important; }
html.s4u-lite .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(3) { animation-delay: 0.4s !important; }

/* Clappr media-control busy pulses (/Player): quality / playback-rate /
   audio-track buttons pulse while a switch is in flight (plugin CSS:
   `pulse .5s infinite alternate` as a -webkit- shorthand; the kill's
   unprefixed longhands override aliased properties all the same) */
html.s4u-lite .level_selector button.changing,
html.s4u-lite .playback_rate button.changing,
html.s4u-lite .audio_selector button.changing {
  animation-duration: 0.5s !important;
  animation-iteration-count: infinite !important;
}

/* SweetAlert confirm-button loader (swal mounts on <body>, in scope via
   s4u-shell): dormant today, no swal call uses a loading button yet, but
   this keeps a future one from reading as a hang. Injected rule:
   `swal-loading-anim 1s infinite`. */
html.s4u-lite .swal-button__loader div {
  animation-duration: 1s !important;
  animation-iteration-count: infinite !important;
}

/* Materialize slate loading bars (?mat=1 fallback on the /Player slates):
   two staggered sweeps, `indeterminate` / `indeterminate-short` 2.1s with
   the second one 1.15s behind. Inert on the default de-Materialized player
   (the shim defines geometry but no animation). */
html.s4u-lite .s4u .progress .indeterminate::before {
  animation-duration: 2.1s !important;
  animation-iteration-count: infinite !important;
}
html.s4u-lite .s4u .progress .indeterminate::after {
  animation-duration: 2.1s !important;
  animation-delay: 1.15s !important;
  animation-iteration-count: infinite !important;
}

/* ---- 5) OS-level "reduce motion" gets the motion kill for free ------------
   Same rules as sections 3 and 4 without the flag: users who already asked
   their OS for less motion (accessibility, or slow machines with Windows
   animation effects off) get it even with Lite mode off. Blur stays: it is
   a paint cost, not motion, and this preference is strictly about motion.
   Keep in sync with sections 3 and 4. */
@media (prefers-reduced-motion: reduce) {
  .s4u,
  .s4u::before,
  .s4u::after,
  .s4u *,
  .s4u *::before,
  .s4u *::after,
  [class*="s4u-"],
  [class*="s4u-"]::before,
  [class*="s4u-"]::after,
  [class*="s4u-"] *,
  [class*="s4u-"] *::before,
  [class*="s4u-"] *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
  }

  .s4u-progress .bar {
    animation-duration: 1.1s !important;
    animation-iteration-count: infinite !important;
  }

  .s4u .s4u-stage-info__link--restart.is-busy svg {
    animation-duration: 0.8s !important;
    animation-iteration-count: infinite !important;
  }

  .s4u .colm .tile-selected::after {
    animation-duration: 3s !important;
    animation-iteration-count: 1 !important;
  }

  .spinner-three-bounce[data-spinner] > div {
    animation-duration: 1.4s !important;
    animation-iteration-count: infinite !important;
  }
  .spinner-three-bounce[data-spinner] > [data-bounce1] { animation-delay: -0.32s !important; }
  .spinner-three-bounce[data-spinner] > [data-bounce2] { animation-delay: -0.16s !important; }

  .jwplayer.jw-state-buffering .jw-svg-icon-buffer {
    animation-duration: 2s !important;
    animation-iteration-count: infinite !important;
  }

  .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator {
    animation-duration: 2s !important;
    animation-iteration-count: infinite !important;
  }
  .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(2) { animation-delay: 0.2s !important; }
  .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(3) { animation-delay: 0.4s !important; }

  .level_selector button.changing,
  .playback_rate button.changing,
  .audio_selector button.changing {
    animation-duration: 0.5s !important;
    animation-iteration-count: infinite !important;
  }

  .swal-button__loader div {
    animation-duration: 1s !important;
    animation-iteration-count: infinite !important;
  }

  .s4u .progress .indeterminate::before {
    animation-duration: 2.1s !important;
    animation-iteration-count: infinite !important;
  }
  .s4u .progress .indeterminate::after {
    animation-duration: 2.1s !important;
    animation-delay: 1.15s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ---- 6) Auto-detection toast ----------------------------------------------
   lite-auto.js turns lite mode on by default when the WebGL probe reports
   software rendering (hardware acceleration off) and announces it ONCE with
   this toast. Bottom left corner, one step under the net-watch pill
   (2147483500) so an outage always outranks it. Old-TV rules apply here too:
   plain selectors, no oklch, no `inset`, no flex gap. The card itself is
   s4u-prefixed chrome, so the section 3 motion kill collapses its entry
   animation to near-instant on the very devices it appears on: the base
   class must read as the final visible state with no animation needed. */
.s4u-liteauto-toast {
  position: fixed;
  left: 18px;
  bottom: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 2147483400;
  box-sizing: border-box;
  max-width: 340px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(17, 17, 21, 0.97);
  border: 1px solid rgba(214, 190, 140, 0.28);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  color: #e9e5db;
  font-family: Inter, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  font-size: 13px;
  line-height: 1.5;
  animation: s4u-liteauto-in 0.35s ease-out;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
@keyframes s4u-liteauto-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
.s4u-liteauto-toast--out {
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
}
.s4u-liteauto-toast__title {
  font-weight: 600;
  font-size: 14px;
  color: #f2ecdf;
  margin-bottom: 4px;
}
.s4u-liteauto-toast__body {
  color: rgba(233, 229, 219, 0.78);
  margin-bottom: 10px;
}
.s4u-liteauto-toast__ok {
  display: inline-block;
  padding: 6px 14px;
  border: 1px solid rgba(214, 190, 140, 0.4);
  border-radius: 8px;
  background: rgba(214, 190, 140, 0.12);
  color: #d6be8c;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.s4u-liteauto-toast__ok:hover { background: rgba(214, 190, 140, 0.2); }

/* Materialize on legacy _Layout pages ships a bare `button:focus` that paints
   the background cyan and kills the outline; this class+pseudo rule outranks
   it and gives keyboard / D-pad focus (tv-focus) a champagne ring instead. */
.s4u-liteauto-toast__ok:focus {
  background: rgba(214, 190, 140, 0.2);
  outline: 2px solid rgba(214, 190, 140, 0.55);
  outline-offset: 2px;
}

/* Small phones: span the width instead of hugging a 340px column so the card
   never pins itself under a form's controls or runs past the right edge. */
@media (max-width: 420px) {
  .s4u-liteauto-toast {
    left: 12px;
    right: 12px;
    max-width: none;
  }
}
