/* player.css - Final Code with Menu Position Fix */
@import url('./safe-poster.css');

:root {
    --pc-control-color: #fff;
    --pc-control-hover: rgba(255, 255, 255, 0.18);
    /* Rounded-inset highlight for menu ITEMS so a hovered/selected row nests
       cleanly inside the 21px glass menu instead of reading square. Single source
       reused by #settingsMenu / #procast-context-menu / #procast-stats-overlay. */
    --pc-menu-item-radius: 12px;
    --pc-menu-item-inset: 6px;
    --pc-menu-item-hover-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
    /* Default: same as UI; owner theme overwrites via applyPlayerColors */
    --pc-highlight-color: #ffffff;
    --pc-background-color: transparent; /* Default: transparent; set via applyPlayerColors when user chooses a bar fill */
    --pc-ui-elements-color: #FFFFFF; /* Color for UI elements (buttons, text, icons) except play button */
    --progress-offset: 38px;
    --progress-height: 8px;
    --controls-offset: 0px;
    --controls-height: 40px;
}

/* ✅ Ограничиваем глобальные стили только страницами с watch-page-active */
html.watch-page-active, body.watch-page-active {
    height: 100%;
    margin: 0;
    background: #181818;
    font-family: 'Calibri', Arial, sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
}

#vjs-container:fullscreen,
#vjs-container:-webkit-full-screen {
    width: 100% !important;
    height: 100% !important;
    background: #000 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    box-sizing: border-box !important;
}

#vjs-container:fullscreen .video-js,
#vjs-container:-webkit-full-screen .video-js {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    display: block !important;
}

#vjs-container:fullscreen .video-js video,
#vjs-container:-webkit-full-screen .video-js video {
    object-fit: contain !important;
    object-position: center !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    max-height: none !important;
}

#watch-player-shell:fullscreen,
#watch-player-shell:-webkit-full-screen {
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    max-height: 100% !important;
    background: #000 !important;
    display: flex !important;
    flex-direction: column !important;
    box-sizing: border-box !important;
    border-radius: 0 !important;
}

#watch-player-shell:fullscreen #vjs-container,
#watch-player-shell:-webkit-full-screen #vjs-container {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    width: 100% !important;
    height: 100% !important;
    max-height: none !important;
    position: relative !important;
    display: block !important;
}

#watch-player-shell:fullscreen .video-js,
#watch-player-shell:-webkit-full-screen .video-js {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    display: block !important;
    border-radius: 0 !important;
}

#watch-player-shell:fullscreen .video-js video,
#watch-player-shell:-webkit-full-screen .video-js video {
    object-fit: contain !important;
    object-position: center !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    max-height: none !important;
}

/* Standalone embed (external-hls-embed.html): .video-js is position:absolute, so height:auto collapses the shell */
html.dcast-external-player #vjs-container {
    height: 100% !important;
    min-height: 200px;
    max-height: 100%;
}

/* Tools embed: keep chrome clickable even if controls-hidden gets toggled */
html.dcast-external-player #vjs-container.controls-hidden .custom-control-bar,
html.dcast-external-player #vjs-container.controls-hidden .custom-progress-bar,
html.dcast-external-player #vjs-container.controls-hidden #settingsMenu {
    opacity: 1 !important;
    pointer-events: auto !important;
}

#vjs-container {
    position: relative;
    max-width: 100vw !important; /* КРИТИЧНО: Строго ограничено viewport шириной */
    /* ✅ КРИТИЧНО: НЕ устанавливаем max-height - это нарушает aspect-ratio! */
    /* ✅ Вместо max-height используем overflow: hidden на родителе (.watch-card-player) */
    width: 100% !important;
    height: auto !important;
    /* ✅ ASPECT RATIO FIX: Разрешаем динамический aspect-ratio, но ограничиваем размеры viewport */
    /* aspect-ratio устанавливается динамически через inline style в ui.js после загрузки метаданных */
    border-radius: clamp(6px, 1.5vw, 16px);
    background: #111;
    overflow: hidden;
    box-shadow: 0 8px 32px #000c;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: stretch;
    transition: cursor 0.3s;
    z-index: 1;
    /* ✅ НЕ используем contain:size — ломает размеры при position:absolute .video-js и даёт чёрный экран при живом HLS (сегменты 200, кадров нет) */
    contain: none !important;
}

/* ✅ КРИТИЧНО: НЕ переопределяем inline aspect-ratio - он должен работать напрямую */
/* ✅ Убрано правило aspect-ratio: inherit - оно переопределяло inline aspect-ratio */
/* ✅ Inline style aspect-ratio имеет приоритет над CSS, поэтому не нужно переопределять */

/* Storefront inline mode: the channel-player wrapper already supplies the
   rounded frame + surface background. Drop the duplicate rounding/shadow on
   #vjs-container AND on .video-js so the corners don't show a colored ring
   around them and the player doesn't cast a separate inner shadow.
   `.video-js` had border-radius:16px AND background:#111 — the 16px rounded
   shape was bigger than the channel-player wrapper's 12px clip, leaving 4
   visible dark crescents at the corners on light-themed creator sites
   (rgb 0,0,0 / rgb 17,17,17 leaking through). */
[data-inline-player='true'] #vjs-container,
[data-inline-player='true'] .video-js {
    border-radius: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
}
[data-inline-player='true'] .video-js video {
    background: transparent !important;
}

/* One radius for the whole player stack (/watch, /embed and the creator
   PlayerCard all mount #watch-player-shell). Every layer takes the SHELL's own
   radius via `inherit` — the same idiom #watch-ambient-fill already uses — so
   the arcs are identical instead of the former pie of three (shell 16px,
   #vjs-container clamp(6px,1.5vw,16px), .video-js 16px) plus the container's
   duplicate drop shadow.

   `inherit` and not a literal: the shell's radius differs per surface and per
   state, and each of those must follow automatically.
     /watch, /embed          shell = rounded-2xl (16px) -> layers 16px
     creator storefront      shell has no radius (the [data-inline-player]
                             wrapper owns the 12px frame) -> layers 0, untouched
     fullscreen              shell is forced to 0 above -> layers 0

   Clipping alone is NOT enough and that is what broke the corners: the shell
   only clips what crosses ITS edge. A portrait clip pillarboxes, so
   #vjs-container sits strictly inside the shell (measured 349px wide inside a
   386px shell at 390px viewport) and its own corners are the ones the viewer
   reads as "the player" — square once their radius was zeroed. */
#watch-player-shell #vjs-container,
#watch-player-shell .video-js,
#watch-player-shell .vjs-poster {
    border-radius: inherit;
    box-shadow: none !important;
}

/* Storefront inline mode — pre-loading fallback shape. Until ui.js inspects
   the loaded metadata and sets the real aspect-ratio (inline + !important),
   #vjs-container's global `height: auto !important` rule lets it collapse
   to ~150px (HTML5 <video> intrinsic default). With shell still 693px tall,
   the small player sits at the top of a big black box → "player offset"
   during loading. No !important here so ui.js' inline rule wins after
   metadata arrives, preserving the existing adaptation behavior. */
[data-inline-player='true'] #vjs-container {
    aspect-ratio: 16 / 9;
}

/* Suppress videojs' default loading spinner — the player ships its own
   branded loader (.dcast-player-loader, injected by stream.js). During
   buffering both were rendering concentrically, which read as a "double
   spinner" to viewers. The branded one is the intended UX. */
.vjs-loading-spinner {
    display: none !important;
}


body.watch-page-active:not(.is-touch) #vjs-container.controls-hidden {
    cursor: none;
}

body:not(.is-touch) #vjs-container.controls-hidden .custom-control-bar,
body:not(.is-touch) #vjs-container.controls-hidden .custom-progress-bar,
body:not(.is-touch) #vjs-container.controls-hidden #settingsMenu {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.33s;
}

#vjs-container.controls-hidden .custom-control-bar,
#vjs-container.controls-hidden .custom-progress-bar {
    opacity: 0 !important;
    pointer-events: none !important;
    transition: opacity 0.33s;
}

/* ✅ FIX: В полноэкранном режиме контролы должны иметь правильный z-index */
:fullscreen .custom-control-bar,
:fullscreen .custom-progress-bar,
:-webkit-full-screen .custom-control-bar,
:-webkit-full-screen .custom-progress-bar {
    z-index: 100 !important;
}

:fullscreen #vjs-container.controls-hidden .custom-control-bar,
:fullscreen #vjs-container.controls-hidden .custom-progress-bar,
:-webkit-full-screen #vjs-container.controls-hidden .custom-control-bar,
:-webkit-full-screen #vjs-container.controls-hidden .custom-progress-bar {
    opacity: 0 !important;
    pointer-events: none !important;
    transition: opacity 0.33s !important;
}

:fullscreen #vjs-container:not(.controls-hidden) .custom-control-bar,
:fullscreen #vjs-container:not(.controls-hidden) .custom-progress-bar,
:-webkit-full-screen #vjs-container:not(.controls-hidden) .custom-control-bar,
:-webkit-full-screen #vjs-container:not(.controls-hidden) .custom-progress-bar {
    opacity: 1 !important;
    pointer-events: auto !important;
    transition: opacity 0.33s !important;
}

.video-js {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    /* ✅ FULLSCREEN FIX: z-index видео должен быть ниже контролов */
    z-index: 1 !important;
    height: 100% !important;
    border-radius: 16px;
    background: #111;
}

/* ✅ ASPECT RATIO FIX: Видео должно корректно помещаться в правильно размеренный контейнер */
.video-js video,
#vjs-container .video-js video,
#vjs-container video {
    width: 100% !important;
    height: 100% !important;
    object-fit: contain !important; /* Видео помещается в правильно размеренный контейнер */
    object-position: center !important;
    /* ✅ FULLSCREEN FIX: z-index видео должен быть ниже контролов */
    z-index: 1 !important;
    position: relative !important;
}

/* Poster by cover on a surface that opts in (data-poster-fit="cover", /watch).
   Until a real frame replaces the poster the element paints only the author's
   poster, whose shape is arbitrary; contain drew it with black bars first and the
   off-air screen (cover) then zoomed it. ui.js sets data-dcast-picture on the
   element at the first real frame, and from then on the rule above (contain)
   applies again, so video is not cropped. Matches both the server-rendered tag
   (#player) and the element video.js drives (.vjs-tech); the teaser <video> is
   neither. Specificity is above the :fullscreen contain rules. */
#vjs-container[data-poster-fit="cover"] video#player:not([data-dcast-picture="1"]),
#vjs-container[data-poster-fit="cover"] video.vjs-tech:not([data-dcast-picture="1"]),
#vjs-container[data-poster-fit="cover"] .vjs-poster img {
    object-fit: cover !important;
}
#vjs-container[data-poster-fit="cover"] .vjs-poster {
    background-size: cover !important;
}

/* The splash has to out-rank the <video> above, or the end of playback stays
   black however correctly the reset runs.

   The rule right above gives the <video> `position: relative; z-index: 1`, and
   the element carries an inline `background-color: #000`. `.vjs-poster` is
   `position: absolute` with no z-index at all, so it loses the stacking
   comparison and the opaque black element paints over it. MEASURED 2026-08-31,
   headed Chrome on prod /watch/473c9771…: at end of playback the reset had
   already done its whole job - currentTime 0, `vjs-paused`, no
   `vjs-has-started`, `.vjs-poster` display:block, its <img> loaded at
   1280x720 - and `elementsFromPoint` at the centre of the player still returned
   VIDEO.vjs-tech on top. Hiding the <video> in the same session revealed the
   splash underneath, intact. That is why four fixes inside the `ended` handler
   did not hold: the reset was never the broken half.

   Scoped to `:not(.vjs-has-started)` rather than applied flat, because that is
   the exact condition under which video.js itself displays the poster
   (`.vjs-has-started .vjs-poster{display:none}`). Once the player believes
   playback has started the splash is display:none anyway, so a raised z-index
   would buy nothing - and it keeps the 2026-07-06 regression (splash masking a
   playing picture) structurally out of reach instead of merely unlikely. */
.video-js:not(.vjs-has-started) .vjs-poster {
    z-index: 2;
}

/* iOS-hostile-layer fix (BOSS 2026-07-14 "audio plays, picture hangs"):
   NEVER put `filter`/`backdrop-filter`/`will-change`/`transform` on the <video>
   element itself. A `filter` on <video> forces it into its own filtered
   compositing layer, and iOS Safari can DROP that layer during first play (audio
   decodes, no picture = videoWidth 0). The buffering dim is already provided by
   the `.dcast-player-loader` scrim (a SIBLING radial-gradient overlay above), so
   the previous `filter: brightness(0.72) saturate(0.9)` on the video was both
   redundant and the compositing hazard. Keep the video layer clean. */
#vjs-container.is-buffering .dcast-player-loader {
    /* Slightly deepen the sibling scrim while buffering (dim effect without ever
       touching the <video>'s own compositing layer). */
    background: radial-gradient(circle at center, rgba(16, 20, 34, 0.22) 0%, rgba(7, 10, 18, 0.82) 68%, rgba(4, 7, 12, 0.94) 100%);
}

.dcast-player-loader {
    position: absolute;
    inset: 0;
    z-index: 26;
    display: grid;
    place-items: center;
    background: radial-gradient(circle at center, rgba(16, 20, 34, 0.12) 0%, rgba(7, 10, 18, 0.78) 68%, rgba(4, 7, 12, 0.92) 100%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 180ms ease;
}

.dcast-player-loader.is-visible {
    opacity: 1;
}

/* Startup overhaul (BOSS 2026-07-14): during the open → first-frame window the
   React WatchPlayerSkeleton shows the ONE unified loader (byte-identical ring).
   Suppress the branded buffering loader while that skeleton is up so the two
   never stack into a perceived "double spinner". html.dcast-splash-active is
   toggled by the watch + embed pages while showThumbnailPreview is true; it
   clears on the first painted frame, at which point the branded loader resumes
   its normal mid-playback buffering duty. */
.watch-card-player:has([data-watch-live-waiting="starting"]) .dcast-player-loader,
html.dcast-splash-active .dcast-player-loader {
    opacity: 0 !important;
}

.dcast-player-loader__frame {
    width: clamp(92px, 12vw, 132px);
    height: clamp(92px, 12vw, 132px);
    display: grid;
    place-items: center;
}

.dcast-player-loader__symbol {
    width: 100%;
    height: 100%;
    overflow: visible;
}

.dcast-player-loader__ring-track,
.dcast-player-loader__ring-head {
    fill: none;
    stroke-width: 3.6;
    transform-origin: 60px 60px;
    transform-box: view-box;
}

.dcast-player-loader__ring-track {
    stroke: rgba(255, 255, 255, 0.10);
}

.dcast-player-loader__ring-head {
    /* Gradient stroke + long arc + round caps = comet-tail spinner. The gradient fades the
       trailing end, which makes a single rotating circle look like motion blur. Faster cadence
       (1s/turn) reads as "active loading" without strobing. */
    stroke: url(#dcastLoaderArc);
    stroke-linecap: round;
    stroke-dasharray: 130 200; /* ~44% visible arc, ~66% gap */
    animation: dcastLoaderSpin 1s linear infinite;
}

/* play-bg / play-icon rules removed: the small play overlay was deleted from the SVG —
   the player has its own play button, no duplicate inside the loader. */

@keyframes dcastLoaderSpin {
    to {
        transform: rotate(360deg);
    }
}


.custom-progress-bar {
    width: 100%;
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--progress-offset);
    /* 31 (was 30) so it stacks just above .custom-control-bar (z-index:30): the
       control bar sits directly below and, being later in DOM at equal z-index,
       used to win hit-testing over the seek bar's downward hit-expander — so the
       "+ below" half of the widened grab zone was dead. The container itself is
       pointer-events:none, so raising it only lets the .progress-outer/::before
       hit target win in the ~3px sliver above the control-bar buttons' icons; it
       does NOT block the buttons. */
    z-index: 31;
    padding: 0 16px;
    height: var(--progress-height);
    display: flex;
    align-items: center;
    background: transparent;
    box-sizing: border-box;
    pointer-events: none;
    /* ✅ FULLSCREEN FIX: В fullscreen контролы должны быть поверх видео */
    position: absolute !important;
}

/* ✅ FIX: В полноэкранном режиме z-index контролов должен быть выше */
/* 10000 so it stays above the fullscreen control-bar (z-index:9999) for the same
   downward-hit-zone reason as the base rule above. */
:fullscreen .custom-progress-bar,
:-webkit-full-screen .custom-progress-bar {
    z-index: 10000 !important;
}

.progress-outer {
    width: 100%;
    height: 3.5px;
    background: #fff2;
    border-radius: 2px;
    /* overflow was `hidden`; it is now `visible` so the invisible ::before
       hit-expander below can extend the clickable/hover zone beyond the 3.5px
       visible track. The fill (.progress-inner) keeps its own border-radius so
       the visual is unchanged. */
    overflow: visible;
    position: relative;
    cursor: pointer;
    transition: box-shadow 0.33s;
    box-shadow: 0 1px 8px #0006;
    pointer-events: auto;
}

/* Taller invisible hit target: +3px above and +3px below the visible 3.5px bar
   (a ~9.5px grab band) so the scrubber is easy to click/hover/drag without
   changing its rendered thickness. The pseudo belongs to .progress-outer, so
   clicks/hover in the expanded band still target the same element the seek +
   scrub-preview handlers (progress.js) are bound to, and getBoundingClientRect()
   there still returns the 3.5px visible rect (seek math is horizontal-only, so
   the vertical growth does not affect it). The downward half is only effective
   because .custom-progress-bar now stacks above .custom-control-bar (see above);
   otherwise the control bar swallowed it. */
.progress-outer::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -3px;
    bottom: -3px;
    background: transparent;
}

.progress-inner {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: var(--pc-highlight-color, var(--pc-control-color));
    height: 100%;
    width: 0%;
    transition: width 0.33s;
    border-radius: 2px;
}

/* Item 3: scrubber hover thumbnail preview. Appended to document.body (NOT any
   React-managed node — that caused an insertBefore reconciliation crash) by
   progress.js, only when a storyboard.vtt exists AND its sprite sheet has decoded
   (graceful-absent otherwise). position: fixed + inline left/bottom in JS position
   it over the cursor in viewport coords. Pointer-events off so it never eats
   scrubber clicks. */
.dcast-scrub-preview {
    position: fixed;
    transform: translateX(-50%);
    z-index: 2147483000;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.12s ease;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}
.dcast-scrub-preview.is-visible {
    opacity: 1;
}
.dcast-scrub-preview-img {
    /* Reuse the canonical glass rounding (same var as menu-item highlight, 1a7b374a)
       so the hover thumbnail matches the settings menu / share-popover language.
       overflow:hidden clips the sprite background crop cleanly to the rounded shape
       so no square corner of the cropped frame bleeds past the border — and it also
       clips the magnified inner frame to the box. Box size is set inline by
       progress.js from the player width (2x the sprite tile at most). */
    border-radius: var(--pc-menu-item-radius);
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.35);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
}
/* The sprite crop stays at the tile's natural size and is magnified from the
   top-left corner, so the #xywh crop offsets remain plain sprite-sheet pixels
   whatever the preview is scaled to. */
.dcast-scrub-preview-frame {
    background-repeat: no-repeat;
    transform-origin: 0 0;
}
.dcast-scrub-preview-time {
    font: 600 11px/1 system-ui, -apple-system, sans-serif;
    color: #fff;
    background: rgba(0, 0, 0, 0.75);
    padding: 2px 6px;
    /* Small chip radius on the same canon scale as the rounded thumbnail above,
       so the time chip + thumbnail read as one cohesive canonical popover. */
    border-radius: 8px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    white-space: nowrap;
}

/* ====== BOTTOM CONTROL SCRIM (legibility on bright content) ======
   A soft dark gradient painted behind the progress + control bar so the white
   control icons and progress track stay legible over white / very bright video,
   WITHOUT darkening the center of the frame. BOSS 2026-07-24: a light dimming at
   the bottom, behind the controls and the progress bar.

   Implemented as a container pseudo-element (NOT a DOM node) so it can never
   trigger the videojs React-reconciliation insertBefore crash that appending an
   overlay into #vjs-container causes (see player-feature-parity canon). Shared
   player.css => the scrim reaches all videojs variants (watch / embed / creator
   big player / partner-API embed) at once. z-index 29 keeps it below
   .custom-control-bar (30) and .custom-progress-bar (31) but above .video-js;
   pointer-events:none so taps/clicks pass through to the surface + controls. The
   container's overflow:hidden clips it to the rounded shape, so no square dark
   corners. It fades together with the controls via the .controls-hidden opacity
   toggle => no permanent dark band when controls auto-hide. */
#vjs-container::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 30%;
    min-height: 88px;
    max-height: 160px;
    z-index: 29;
    pointer-events: none;
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.45) 0%,
        rgba(0, 0, 0, 0.24) 42%,
        rgba(0, 0, 0, 0.08) 72%,
        rgba(0, 0, 0, 0.00) 100%
    );
    opacity: 1;
    transition: opacity 0.33s;
}

/* Fade the scrim out with the controls (auto-hide) — no dark band when the bar
   is hidden. Mirrors the .custom-control-bar / .custom-progress-bar opacity
   rules above. */
#vjs-container.controls-hidden::after {
    opacity: 0;
}

.custom-control-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--controls-offset);
    width: 100%;
    background: var(--pc-background-color, transparent) !important;
    padding: 0 16px;
    display: flex;
    align-items: center;
    height: var(--controls-height);
    z-index: 30;
    border-bottom-left-radius: 16px;
    border-bottom-right-radius: 16px;
    box-sizing: border-box;
    pointer-events: none; /* По умолчанию отключено, но включится через CSS при показе */
    gap: 0;
    /* ✅ FULLSCREEN FIX: В fullscreen контролы должны быть поверх видео */
    position: absolute !important;
}

/* ✅ FIX: Включаем pointer-events когда контролы видны */
#vjs-container:not(.controls-hidden) .custom-control-bar,
[class*="aspect-video"]:has(#vjs-container:not(.controls-hidden)) .custom-control-bar {
    pointer-events: auto;
}

/* ✅ FIX: В fullscreen также включаем pointer-events */
:fullscreen #vjs-container:not(.controls-hidden) .custom-control-bar,
:fullscreen [class*="aspect-video"]:has(#vjs-container:not(.controls-hidden)) .custom-control-bar,
:-webkit-full-screen #vjs-container:not(.controls-hidden) .custom-control-bar,
:-webkit-full-screen [class*="aspect-video"]:has(#vjs-container:not(.controls-hidden)) .custom-control-bar {
    pointer-events: auto !important;
}

:fullscreen .custom-control-bar,
:-webkit-full-screen .custom-control-bar {
    z-index: 9999 !important;
    position: absolute !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    border-radius: 0 !important;
}

:fullscreen .video-js,
:-webkit-full-screen .video-js {
    z-index: 1 !important;
    position: absolute !important;
    border-radius: 0 !important;
}

:fullscreen .video-js video,
:-webkit-full-screen .video-js video {
    z-index: 1 !important;
    position: relative !important;
}

.custom-control-bar > * { 
    pointer-events: auto; 
}

.bar-left, .bar-center, .bar-right { 
    display: flex; 
    align-items: center; 
}

.bar-left { 
    gap: 1px; 
    min-width: 0; 
    overflow: hidden; 
}

.bar-center { 
    flex: 1 1 0%;
    gap: 8px; 
    justify-content: center; 
    min-width: 0;
}

/* WebKit: explicit flex on the right group; empty .bar-center uses flex: 1 1 0% + min-width 0 */
.bar-right { 
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex: 0 0 auto;
    flex-shrink: 0;
    gap: 2px; 
}

.control-btn {
    background: none;
    border: none;
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    font-size: 22px;
    cursor: pointer;
    border-radius: 50%;
    padding: 8px;
    transition: background 0.15s, color 0.15s, box-shadow 0.18s;
    outline: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
}

/* A control the platform refuses has to LOOK refused. The unavailable state was
   being set as a class with nothing painting it, so on a device that cannot go
   fullscreen the button stayed indistinguishable from a working one and the viewer
   kept pressing it. Dimmed + not-allowed, and the click handler stays attached so a
   platform that changes its mind on a later attempt is still reachable. */
.control-btn.is-unavailable {
    opacity: 0.35;
    cursor: not-allowed;
}

.control-btn.is-unavailable:hover {
    background: none;
}

/* ✅ Play button uses highlight color, all others use UI elements color */
.control-btn:not(#playPauseBtn) {
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

/* ✅ All control button SVGs use UI elements color by default */
.control-btn svg {
    width: 24px;
    height: 24px;
    fill: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    transition: fill 0.33s;
    vertical-align: middle;
}

/* ✅ All SVG elements inside control buttons (except play button) */
.control-btn:not(#playPauseBtn) svg,
.control-btn:not(#playPauseBtn) svg *,
.control-btn:not(#playPauseBtn) svg path,
.control-btn:not(#playPauseBtn) svg polygon,
.control-btn:not(#playPauseBtn) svg polyline,
.control-btn:not(#playPauseBtn) svg rect,
.control-btn:not(#playPauseBtn) svg circle,
.control-btn:not(#playPauseBtn) svg line {
    fill: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    stroke: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

/* PiP icon: outer frame is outline-only, inner inset is FILLED. Selector specificity is bumped
   with `.control-btn#pipBtn` so it actually beats the catchall rule above, which itself has
   spec (0,1,1,2) thanks to `:not(#playPauseBtn)` counting as one ID. Without this bump the
   catchall painted both rects solid and the icon looked like a blank white block. */
.control-btn#pipBtn svg rect {
    fill: none !important;
    stroke: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}
.control-btn#pipBtn svg rect.dcast-pip-inset {
    fill: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    stroke: none !important;
}

/* Right-bar controls (settings + fullscreen + PiP): guarantee a pixel-identical box + icon size
   (matched to the settings button) and vertical alignment. The PiP glyph sits ~1px high in its
   24-unit viewBox (outer rect y=4..18 → center 11 vs the box center 12), which made PiP "dance"
   above settings/fullscreen — nudge it down 1px so all glyph tops/bottoms line up. */
.bar-right .control-btn {
    width: 40px !important;
    height: 40px !important;
    padding: 8px !important;
}
.bar-right .control-btn svg {
    width: 24px !important;
    height: 24px !important;
}
.control-btn#pipBtn svg {
    transform: translateY(1px);
}

/* Audio language (settings.js inserts it before the gear only when the source has
   more than one audio track): the same 40px round control, widened into a pill so
   the current track's name fits beside the icon. */
.bar-right .control-btn.audio-language-btn {
    width: auto !important;
    min-width: 40px;
    gap: 4px;
    padding: 8px 12px 8px 8px !important;
    border-radius: 20px;
}
.audio-language-label {
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    max-width: 7.5em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--pc-ui-elements-color, var(--pc-control-color));
}

/* ✅ Play button SVG uses highlight color */
#playPauseBtn svg,
#playPauseBtn svg *,
#playPauseBtn svg path,
#playPauseBtn svg polygon,
#playPauseBtn svg polyline {
    fill: var(--pc-highlight-color, var(--pc-control-color)) !important;
    stroke: var(--pc-highlight-color, var(--pc-control-color)) !important;
    color: var(--pc-highlight-color, var(--pc-control-color)) !important;
}

.control-btn:hover, .control-btn.active, .control-btn:focus {
    background: var(--pc-control-hover);
    box-shadow: 0 0 18px 2px var(--pc-control-hover);
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

.control-btn:hover svg, .control-btn:focus svg {
    fill: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

/* ✅ Play button hover uses highlight color */
#playPauseBtn:hover svg,
#playPauseBtn:focus svg {
    fill: var(--pc-highlight-color, var(--pc-control-color)) !important;
}

/* ✅ Play button uses highlight color (like Ignite Video) */
#playPauseBtn #playIcon,
#playPauseBtn #pauseIcon {
    fill: var(--pc-highlight-color, var(--pc-control-color)) !important;
    transition: fill 0.33s;
}

.volume-slider {
    width: 64px;
    height: 20px;
    /* Left margin breathes the slider away from the mute icon (.bar-left has gap:1px which
       previously left the slider visually glued to the speaker glyph). */
    margin: 0 6px 0 6px;
    display: flex;
    align-items: center;
}

.volume-slider input[type=range] {
    width: 100%;
    height: 2px;
    margin: 0;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 1px;
    outline: none;
    cursor: pointer;
    -webkit-appearance: none;
    position: relative;
    z-index: 2;
}

/* ✅ Volume slider track uses UI elements color with opacity */
.volume-slider input[type=range] {
    background: color-mix(in srgb, var(--pc-ui-elements-color, white) 30%, transparent);
}

.volume-slider input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    background: var(--pc-ui-elements-color, white);
    border-radius: 50%;
    cursor: pointer;
    transition: all 0.2s ease;
}

.volume-slider input[type=range]::-moz-range-thumb {
    width: 12px;
    height: 12px;
    background: var(--pc-ui-elements-color, white);
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: all 0.2s ease;
}

.volume-slider input[type=range]::-webkit-slider-thumb:hover {
    transform: scale(1.2);
}

.volume-slider input[type=range]::-moz-range-thumb:hover {
    transform: scale(1.2);
}

.time-display, .stream-title {
    color: var(--pc-ui-elements-color, var(--pc-control-color));
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.1px;
    user-select: none;
    white-space: nowrap;
}

/* ✅ All control buttons and icons use UI elements color */
#muteBtn,
#settingsBtn,
#fullscreenBtn,
#pipBtn,
#theaterBtn,
#wideModeBtn,
.control-btn:not(#playPauseBtn) {
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

/* Wide/theater mode is not working yet — hide the control until it ships (BOSS 2026-07-07).
   Reversible: delete this rule to restore the button. */
#theaterBtn,
#wideModeBtn,
[data-control="theater"],
[data-control="wideMode"] {
    display: none !important;
}

#muteBtn svg,
#settingsBtn svg,
#fullscreenBtn svg,
#pipBtn svg,
#theaterBtn svg,
#wideModeBtn svg,
.control-btn:not(#playPauseBtn) svg,
.control-btn:not(#playPauseBtn) path {
    fill: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    color: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
    stroke: var(--pc-ui-elements-color, var(--pc-control-color)) !important;
}

/* ✅ Settings menu uses UI elements color */
#settingsMenu {
    color: var(--pc-ui-elements-color, var(--pc-control-color));
}

#settingsMenu * {
    color: var(--pc-ui-elements-color, var(--pc-control-color));
}

#settingsMenu svg,
#settingsMenu path {
    fill: var(--pc-ui-elements-color, var(--pc-control-color));
    stroke: var(--pc-ui-elements-color, var(--pc-control-color));
}

.bar-left-text {
    display: flex;
    align-items: center;
    padding: 0 8px;
}

.live-dot {
    display: none;
    width: 9px;
    height: 9px;
    background-color: #ff4444;
    border-radius: 50%;
    margin: 0 7px 0 8px;
    vertical-align: middle;
    transition: opacity 0.3s;
}

.live-dot.is-hidden {
    opacity: 0;
    pointer-events: none;
}

.live-text {
    display: none;
    font-size: 14px;
    line-height: 1;
    color: var(--pc-ui-elements-color, #ffffff) !important;
    font-weight: 500;
    margin-right: 4px;
    transition: color 0.2s, text-shadow 0.2s;
}

/* Behind the live edge: "LIVE" becomes a brand-blue, clearly-clickable link that
   returns the player to the correct live edge for the stream's latency mode. */
.live-text.live-button-active {
    cursor: pointer;
    color: #3b82f6 !important;
    text-decoration: underline;
    text-underline-offset: 2px;
    text-shadow: none;
    outline: none;
}

.live-text.live-button-active:hover {
    color: #60a5fa !important;
    text-shadow: 0 0 8px rgba(59, 130, 246, 0.5);
}

.live-text.live-button-active:focus-visible {
    color: #60a5fa !important;
    outline: 2px solid rgba(59, 130, 246, 0.7);
    outline-offset: 2px;
    border-radius: 3px;
}

.stream-title {
    color: var(--pc-ui-elements-color, #fff) !important;
    font-size: 13px;
    font-family: 'Segoe UI', 'Roboto', 'Arial', 'Calibri', sans-serif;
    font-weight: 100;
    letter-spacing: 0.02em;
    margin-left: 4px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    max-width: 320px;
    text-shadow: none;
    /* line-height was 1: the line box equalled the 13px font size, so with
       overflow:hidden (needed for the horizontal ellipsis) glyph descenders
       (g,y,p,q,j) were clipped and the text sat low vs the timer. 1.4 gives the
       box enough vertical room for full descenders while flex align-items:center
       keeps it aligned with the time display. */
    line-height: 1.4;
    user-select: none;
    opacity: 0.98;
}

#settingsMenu, #settingsMenu *,
#procast-context-menu, #procast-context-menu *,
#procast-stats-overlay, #procast-stats-overlay * {
    font-family: 'Segoe UI', 'Roboto', 'Arial', 'Calibri', sans-serif !important;
}

/* ====== СТИЛИ МЕНЮ НАСТРОЕК ====== */
#settingsMenu {
    position: fixed;
    /* Content-driven width so the longest label ("Chat Overlay") never wraps.
       min-width keeps the original snug 148px look for short menus; max-width
       caps growth so the glass panel stays compact. JS no longer forces a fixed
       px width (it only drives the mobile font shrink + reads back the rendered
       width for right-edge positioning). */
    width: max-content;
    min-width: 148px;
    max-width: 240px;
    background: rgba(80, 80, 80, 0.33);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 21px;
    box-shadow: 0 4px 24px #000c;
    border: 1px solid #262a38;
    font-size: 13px; color: var(--pc-ui-elements-color, #fff);
    z-index: 10001; display: none;
    flex-direction: column; padding: 3px 0;
    max-height: 68vh; overflow-y: auto;
    user-select: none;
    transition: opacity 0.14s, transform 0.13s;
    opacity: 0; pointer-events: none;
}

#settingsMenu.open {
    display: flex; opacity: 1; pointer-events: auto;
    transform: translateY(0);
}

.settings-menu-list {
    display: flex; flex-direction: column; width: 100%;
}

.settings-menu-item {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 14px 8px 10px !important; /* ✅ Уменьшено на 20%: было 10px, стало 8px */
    padding-top: 8px !important;
    padding-bottom: 8px !important;
    font-size: 13px; font-weight: 400; cursor: pointer;
    white-space: nowrap;
    border: none; background: none; color: var(--pc-ui-elements-color, #fff);
    transition: background .11s, color .11s, box-shadow .11s;
    border-radius: var(--pc-menu-item-radius); gap: 5px;
    margin: 0 var(--pc-menu-item-inset);
}

.settings-menu-item:active, .settings-menu-item:hover {
    background: var(--pc-control-hover); color: #fff;
    box-shadow: var(--pc-menu-item-hover-shadow);
}

.settings-menu-arrow {
    margin-left: auto; font-size: 14px; opacity: 0.57;
}

.settings-menu-back {
    font-size: 13px; font-weight: 400;
    white-space: nowrap;
    padding: 8px 0 8px 8px; cursor: pointer; /* ✅ Уменьшено на 20%: было 10px, стало 8px */
    background: none; color: var(--pc-ui-elements-color, #fff); border: none; outline: none;
    display: flex; align-items: center;
    border-radius: var(--pc-menu-item-radius);
    margin: 0 var(--pc-menu-item-inset);
    transition: background .11s, box-shadow .11s;
}

.settings-menu-back:hover {
    background: rgba(103,188,245,0.08);
    box-shadow: var(--pc-menu-item-hover-shadow);
}

.settings-menu-check {
    margin-right: 7px; color: #6af5da; font-size: 13px;
    width: 13px; text-align: right; font-family: Arial, sans-serif;
}

#settingsMenu::-webkit-scrollbar { 
    width: 6px; 
    background: #2d2e34; 
}

#settingsMenu::-webkit-scrollbar-thumb { 
    background: #222225; 
    border-radius: 8px; 
}

/* ====== СТИЛИ ДЛЯ КОНТЕКСТНОГО МЕНЮ ====== */
#procast-context-menu {
    display: none;
    position: absolute; /* <-- This was changed from fixed to absolute */
    z-index: 3000;
    width: 250px;
    background: rgba(80, 80, 80, 0.33);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 21px;
    box-shadow: 0 4px 24px #000c;
    border: 1px solid #262a38;
    padding: 5px;
    user-select: none;
    /* Properties for perfect centering */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

#procast-context-menu .pcm-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 400;
    cursor: pointer;
    border: none;
    background: none;
    color: #fff;
    transition: background .11s, box-shadow .11s;
    border-radius: var(--pc-menu-item-radius);
}

#procast-context-menu .pcm-item:hover {
    background: var(--pc-control-hover);
    box-shadow: var(--pc-menu-item-hover-shadow);
}

#procast-context-menu .pcm-item svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    opacity: 0.9;
    flex-shrink: 0;
}

/* ====== СТИЛИ ДЛЯ МЕНЮ СТАТИСТИКИ ====== */
#procast-stats-overlay {
    display: none;
    position: absolute;
    z-index: 3000;
    top: 8px;
    left: 8px;
    width: 360px;
    min-width: 360px;
    max-width: 400px;
    line-height: 1.4;
    font-size: 13px;
    color: #e7faff;
    background: rgba(80, 80, 80, 0.33);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 21px;
    box-shadow: 0 4px 24px #000c;
    border: 1px solid #262a38;
    padding: 12px 18px;
}

#procast-stats-overlay .stat-close {
    position: absolute;
    z-index: 1;
    top: 8px;
    right: 8px;
    cursor: pointer;
    color: #fff;
    font-size: 18px;
    line-height: 1;
    opacity: 0.6;
    padding: 3px 6px;
    border-radius: var(--pc-menu-item-radius);
    transition: opacity .12s, color .12s, background .12s, box-shadow .12s;
    user-select: none;
}

#procast-stats-overlay .stat-close:hover {
    opacity: 1;
    color: #ff5656;
    background: var(--pc-control-hover);
    box-shadow: var(--pc-menu-item-hover-shadow);
}

/* Bare copy icon-button (no plate) — matches the canonical mini-card copy button
   (CopyFeedbackButton, ghost). Idle transparent; ghost hover = subtle accent. */
#procast-stats-overlay #stats-copy-btn:hover {
    opacity: 1;
    background: var(--pc-control-hover);
}

#yt-stats-content {
    user-select: text;
}

#yt-stats-content .stat-label {
    color: #A2B9E1;
    font-weight: 500 !important;
}

#yt-stats-content .stat-latency {
    color: #56ff86;
}

#yt-stats-content .stat-error {
    color: #ff5656;
}

/* ====== СТИЛИ ДЛЯ ГРАФИКОВ В СТАТИСТИКЕ ====== */
#stats-graphs {
    margin-top: 15px;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding-top: 15px;
}

.graph-container {
    margin-bottom: 12px;
}

.graph-title {
    color: #A2B9E1;
    font-size: 11px;
    font-weight: 500;
    margin-bottom: 6px;
    text-align: center;
}

#network-graph, #speed-graph {
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(20, 20, 20, 0.8);
    display: block;
    margin: 0 auto;
    height: 80px; /* Явно задаем компактную высоту */
}


/* ====== AMBIENT MODE ======
   Per-side YouTube-style halo around the /watch player card. The picture (four edge-anchored
   radial gradients blurred by the tier's radius) is painted by ambient-halo.js into a small
   canvas that the browser stretches over the card plus 3 blur radii on every side. Until
   2026-10-02 it was this card's ::before with filter: blur(80px), which the compositor
   re-filtered on every video frame: 47-48 % of the frames dropped on a 1080p VOD (numbers in
   ambient-halo.js). A stretched bitmap is drawn as a plain texture, nothing runs per frame.

   The card keeps overflow visible so the halo can spill past it. The layer's `contain: layout`
   turns the canvas's overflow into ink overflow, so it never adds page scroll — the property
   the blur's spill had (CSS Overflow 3, ink overflow from filters). */
.watch-card-player:has(#vjs-container.ambient-mode) {
    /* Opacity is a variable so the JS governor in ambient-budget.js can fade the halo out
       before it gives up on a device that is measurably failing to keep up. */
    --ambient-opacity: 1;
    overflow: visible !important;
    position: relative;
    isolation: isolate;
}

.watch-card-player > .ambient-halo-layer {
    display: none;
}

.watch-card-player:has(#vjs-container.ambient-mode) > .ambient-halo-layer {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    contain: layout;
}

.watch-card-player > .ambient-halo-layer > canvas.ambient-halo {
    position: absolute;
    display: block;
    max-width: none;
    opacity: var(--ambient-opacity, 1);
    transition: opacity 0.45s ease;
}

/* MOBILE OFF — BOSS 2026-05-12. The former filter:blur(80px) halo caused page-wide flicker
   on iPhone Safari. settings.js also force-disables ambientMode on touch/narrow screens
   (belt + suspenders); this rule is the visual stop in case some other code path still
   adds the .ambient-mode class. */
@media (hover: none) and (pointer: coarse), (max-width: 767px) {
    .watch-card-player > .ambient-halo-layer {
        display: none !important;
    }
}


/* ====== ПРОЧИЕ И АДАПТИВНЫЕ СТИЛИ ====== */
@media (max-width: 700px) {
    #vjs-container { border-radius: clamp(4px, 1vw, 6px); }
    /* Vertical volume fader temporarily reverted 2026-07-07 — the popup mis-anchored (appeared
       far right of the speaker), showed a blue native track, and the old .volume-fill overlay
       stayed and slid right. Restore the known-good hide until the fader is rebuilt properly. */
    .volume-slider, [data-control="timeSlash"], #durationDisplay, .stream-title { display: none; }
    .audio-language-label { display: none; }
    .bar-right .control-btn.audio-language-btn { padding: 8px !important; border-radius: 50%; }
}

body.watch-page-active.player-theater #vjs-container { 
    width: 90vw !important; 
    max-width: 100vw !important; 
    border-radius: clamp(4px, 1vw, 8px); 
    box-shadow: none; 
    transition: all 0.26s cubic-bezier(.2,1.6,.42,1.01); 
}

body.watch-page-active.player-theater {
    background: #181818 !important;
}

@media (max-aspect-ratio: 1/1) {
    .bar-left, .bar-right { gap: 0; }
    .control-btn { width: 36px; height: 36px; padding: 6px; }
    .custom-control-bar { height: 36px; }
}

@keyframes live-pulse { 
    0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 68, 68, 0.7); } 
    70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(255, 68, 68, 0); } 
    100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 68, 68, 0); } 
}

.live-dot.live-dot-pulsing { 
    animation: live-pulse 2s infinite; 
}

/* PiP: avoid transform (Safari + flex can misplace the control); vertical alignment is via flex on .bar-right */
#pipBtn {
    position: relative;
    top: 0;
}

#vjs-container.is-fullscreen { 
    border-radius: 0; 
}

/* ✅ FIX: Устанавливаем z-index для .video-js чтобы контролы были поверх */
#vjs-container.is-fullscreen .video-js {
    z-index: 1;
}

/* ✅ FIX: settingsMenu is a sibling of #vjs-container (inside #watch-player-shell), not a child */

/* ✅ FIX: Оптимизируем z-index контролов - достаточно высокий для отображения поверх видео */
/* Контролы могут находиться как внутри #vjs-container, так и в родительском контейнере */
/* Используем множественные селекторы для надежности */
#vjs-container.is-fullscreen .custom-control-bar,
#vjs-container.is-fullscreen .custom-progress-bar {
    z-index: 9999 !important; /* ✅ FULLSCREEN FIX: Увеличен z-index для надежности */
    position: absolute !important;
}

:fullscreen .custom-progress-bar,
:-webkit-full-screen .custom-progress-bar {
    z-index: 9999 !important;
    position: absolute !important;
    bottom: var(--progress-offset) !important;
    left: 0 !important;
    right: 0 !important;
}

:fullscreen #vjs-container,
:-webkit-full-screen #vjs-container {
    border-radius: 0 !important;
    box-shadow: none !important;
}

/* ✅ Контекстное меню и статистика остаются с максимальным z-index */
#vjs-container.is-fullscreen #procast-context-menu,
#vjs-container.is-fullscreen #procast-stats-overlay {
    z-index: 2147483647;
}

/* YouTube-style center play/pause hint (surface-click only). Controlled from
   controls.js: it toggles .is-active to pop the glyph in and fade it out. Sits
   below the control bar (z-index 30) and never captures pointer events, so it
   is purely presentational and cannot interfere with surface clicks. */
.dcast-play-hint {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 25;
    opacity: 0;
}

.dcast-play-hint.is-active {
    animation: dcastPlayHintPop 1300ms ease-out forwards;
}

.dcast-play-hint-circle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 76px;
    height: 76px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
}

.dcast-play-hint-circle svg {
    width: 40px;
    height: 40px;
    fill: #fff;
}

@keyframes dcastPlayHintPop {
    0%   { opacity: 0;   transform: scale(0.7); }
    15%  { opacity: 1;   transform: scale(1); }
    55%  { opacity: 0.9; transform: scale(1.03); }
    100% { opacity: 0;   transform: scale(1.28); }
}

/* The platform is drawing its own transport bar on this picture (controls.js
   sets the class from native-controls.js). Two bars on one frame is what the
   owner photographed on his TV: two clocks, two progress bars, two play
   buttons. The platform bar is the one we cannot take away, so ours goes -
   whole, not trimmed. The flag sits on <body> because #settingsMenu is a
   sibling of #vjs-container, not a child of it. */
body.dcast-platform-controls .custom-control-bar,
body.dcast-platform-controls .custom-progress-bar,
body.dcast-platform-controls #settingsMenu,
body.dcast-platform-controls .dcast-play-hint {
    display: none !important;
}
