/* ==========================================================================
   vxc — Netflix-style card hover for styles/default
   Scoped to .videoBlock.vxc (the video.html / series.html card components
   only — relatedVideo cards, live channels, grids are untouched). vodlix.css
   is read-only and loads before this file: its raw-:hover expansion rules
   are neutralized via :not(.vxc-open) guards, and the expansion is re-keyed
   to the Vue-driven .vxc-open class (added after a 400ms hover dwell).
   Consumes only existing customizer variables (--vod-*); hover shades are
   derived from them (color-mix, with rgba fallbacks declared first).
   RTL needs no mirroring here: the transform-origin is computed from
   physical viewport rects in the component.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Neutralize the legacy raw-:hover expansion during the dwell window
   -------------------------------------------------------------------------- */
.videoBlock.vxc:not(.vxc-open):hover,
.videoBlock.vxc:not(.vxc-open):active,
.videoBlock.vxc.hoverOnVideo:not(.vxc-open):hover,
.videoBlock.vxc.hoverOnVideo:not(.vxc-open):active {
  -webkit-transform: none;
  -moz-transform: none;
  -ms-transform: none;
  -o-transform: none;
  transform: none;
  z-index: 99;
}
.videoBlock.vxc:not(.vxc-open):hover .videoInfo,
.videoBlock.vxc:not(.vxc-open):active .videoInfo,
.videoBlock.vxc.hoverOnVideo:not(.vxc-open):hover .videoInfo,
.videoBlock.vxc.hoverOnVideo:not(.vxc-open):active .videoInfo {
  position: absolute;
  visibility: hidden;
  opacity: 0;
  z-index: -1;
}
/* top-10 rows: vodlix widens the card 72% -> 100% on raw :hover */
.swiper-slide.slideBlock.relative.top-10-list .videoBlock.vxc:not(.vxc-open):hover,
.swiper-slide.slideBlock.relative.top-10-list .videoBlock.vxc:not(.vxc-open):active {
  width: auto !important;
}
.swiper-slide.slideBlock.relative.top-10-list .videoBlock.vxc.vxc-open {
  width: 100% !important;
}

/* --------------------------------------------------------------------------
   portrait ratio — the platform's portrait art standard is 9:16 (the admin
   uploader asks for "9:16 e.g. 1080 x 1920" and the thumb pipeline preserves
   it: a generated "320x480" file is really 270x480). vodlix.css renders the
   box at 2:3 (padding 150%), silently cropping ~15% off every poster. Rails
   and cards now use the true 9:16 box.
   -------------------------------------------------------------------------- */
.swiper-slide.slideBlock .ratio.portrait,
.videoBlock .ratio.portrait {
  padding-top: 177.78% !important;
}

/* --------------------------------------------------------------------------
   top-10 geometry — slide height locked to the card's true aspect ratio.
   vodlix.css carries hand-tuned values (112%/130% portrait, none for
   landscape, a 95% thumb box) that never matched the poster, so the number
   art, the card and the hover panel all drifted. The card is 55% of the
   slide in portrait rails and 72% in landscape rails (vodlix.css
   .videoBlockDiv), so:
     portrait:  55% * 3/2  = 82.5% slide padding
     landscape: 72% * 9/16 = 40.5% slide padding
   -------------------------------------------------------------------------- */
/* vodlix pads the slide 75px left, which makes the static spacer resolve
   %-padding against a narrower box than the absolutely-positioned card —
   the root of the height mismatch. The number art is absolute (left %),
   so the padding does nothing but skew the math. */
.swiper-slide.slideBlock.relative.top-10-list {
  padding-left: 0 !important;
}
.swiper-slide.slideBlock.relative.top-10-list .top10-index-portrait + .ratio.portrait {
  /* 55% card width x 16/9 vertical */
  padding-top: 97.78% !important;
}
.swiper-slide.slideBlock.relative.top-10-list .top10-index-landscape + .ratio.ratio-16x9 {
  padding-top: 40.5% !important;
}
/* number art, Netflix alignment: bottom-anchored and pressed against the
   poster's left edge (tucked 6px underneath it — the card layer sits above),
   so any spare room falls BEFORE the numeral, not between numeral and card.
   Anchored via `right` to the card's known width (55% portrait / 72%
   landscape). :nth-child(n) outguns vodlix's per-digit left nudges. */
.swiper-slide.slideBlock.relative.top-10-list:nth-child(n) .top10-index-portrait,
.swiper-slide.slideBlock.relative.top-10-list:nth-child(n) .top10-index-landscape {
  top: auto !important;
  bottom: 0 !important;
  transform: none !important;
  height: 85% !important;
}
.swiper-slide.slideBlock.relative.top-10-list:nth-child(n) .top10-index-portrait {
  left: auto !important;
  right: calc(55% - 6px);
}
.swiper-slide.slideBlock.relative.top-10-list:nth-child(n) .top10-index-landscape {
  left: auto !important;
  right: calc(72% - 6px);
}
/* the numeral <img> is absolutely positioned inside a zero-width span —
   anchor it to the span's right so it extends AWAY from the card */
.swiper-slide.slideBlock.relative.top-10-list .top10-image-portrait,
.swiper-slide.slideBlock.relative.top-10-list .top10-image-landscape {
  left: auto !important;
  right: 0 !important;
}
/* poster: vx corner radius + a solid dark fallback when a title has no
   matching art (live items without portrait stills read as a calm card,
   not a transparent hole) */
.swiper-slide.slideBlock.relative.top-10-list .videoBlock {
  border-radius: var(--vxl-card-radius, 6px);
}
.swiper-slide.slideBlock.relative.top-10-list .videoBlock .res-img {
  border-radius: var(--vxl-card-radius, 6px);
  background-color: #1e1e1e;
  background-color: var(--vod-menu-bg, #1e1e1e);
}
/* Every rail / grid card reads the tile word at REST, not only on hover.
   The clipping box is Bootstrap's .card (overflow: hidden, 0.25rem), and on
   desktop nothing re-pointed its radius at --vxl-card-radius — so a tenant on
   `sharp` saw 4px corners until the dwell panel opened and the .vxc-open
   rules below swapped them for the word (QA report). The phone sheet had the
   same rule scoped to ≤991.98px; this is the desktop half. */
.videoBlock .card,
.videoBlock.vxc {
  border-radius: var(--vxl-card-radius, 6px);
}
/* top-10 hover: the preview flips to landscape at normal card size — the
   Netflix pattern (portrait boxart at rest, 16:9 panel on hover). The
   component swaps the thumb + ratio classes; here the card container takes
   the full slide so the panel isn't clamped to the 55%/72% rest width. */
.swiper-slide.slideBlock.relative.top-10-list:has(.videoBlock.vxc-open) .videoBlockDiv,
.swiper-slide.slideBlock.relative.top-10-list:has(.videoBlock.hoverOnVideo) .videoBlockDiv {
  width: 100% !important;
}
.swiper-slide.slideBlock.relative.top-10-list .videoBlock .ratio.vxc-flip,
.swiper-slide.slideBlock.relative.top-10-list .videoBlock .ratio.top10.portrait.vxc-flip {
  padding-top: 56.25% !important;
}
/* hover hit-area keeper: the portrait->landscape flip shrinks the card's
   layout box, so a cursor resting on the lower half of the poster suddenly
   falls OUTSIDE the card -> mouseleave -> flip back -> mouseenter -> loop
   (visible as stutter). An invisible child keeps the original 2:3 footprint
   hoverable while the flip is open; z-index -1 keeps it behind the panel so
   the buttons stay clickable. */
.videoBlock:has(.ratio.vxc-flip) {
  overflow: visible;
}
.videoBlock:has(.ratio.vxc-flip)::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  aspect-ratio: 9 / 16;
  z-index: -1;
}
/* the card's own thumb box is a true 9:16 — vodlix squashes it to 95% */
.swiper-slide.slideBlock.relative.top-10-list .videoBlock .ratio.top10.portrait {
  padding-top: 177.78% !important;
}
/* ...and a true 16:9 when the rail is landscape */
.swiper-slide.slideBlock.relative.top-10-list .videoBlock .ratio.top10.ratio-16x9 {
  padding-top: 56.25% !important;
}
/* hover-panel controls: same 32px buttons as every other rail (vodlix
   shrinks them to 1.3–1.7rem inside top-10, which crushes the icons) */
.swiper-slide.slideBlock.top-10-list .boxBtn {
  width: 32px !important;
  height: 32px !important;
}
.swiper-slide.slideBlock.top-10-list .boxBtn.playBtn2 i {
  font-size: 26px !important;
}
.swiper-slide.slideBlock.top-10-list .boxBtn i {
  font-size: 20px !important;
}
.swiper-slide.slideBlock.top-10-list .boxBtn i.more {
  font-size: 24px !important;
}
.swiper-slide.slideBlock.top-10-list .videoInfo .caption2 {
  font-size: 14px !important;
}

/* --------------------------------------------------------------------------
   vxs — skeleton loading states (shimmer placeholders shaped like content;
   replaces the Bootstrap spinner on content surfaces)
   -------------------------------------------------------------------------- */
.vxs-tile,
.vxs-line,
.vxs-avatar,
.vxs-player {
  position: relative;
  overflow: hidden;
  background-color: var(--vod-menu-bg);
  border-radius: 6px;
}
.vxs-tile::after,
.vxs-line::after,
.vxs-avatar::after,
.vxs-player::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--vod-white-color, #fff) 7%, transparent), transparent);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--vod-white-color) 7%, transparent), transparent);
  animation: vxs-shimmer 1.4s ease-in-out infinite;
}
@keyframes vxs-shimmer {
  to {
    transform: translateX(100%);
  }
}
.vxs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px;
  margin-bottom: 24px;
}
.vxs-tile {
  aspect-ratio: 16 / 9;
}
.vxs-line {
  display: block;
  height: 14px;
  border-radius: 7px;
}
.vxs-player {
  aspect-ratio: 16 / 9;
  border-radius: 8px;
}
.vxs-chrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
/* skeleton column on pages whose row has no right padding (live) */
.vxs-side {
  padding-inline-end: 40px;
}
.vxs-avatar {
  flex: 0 0 auto;
  width: 50px;
  height: 50px;
}
.vxs-chrow .vxs-line {
  flex: 1;
}
.vxs-bars .vxs-line {
  margin-bottom: 12px;
}
.vxs-bars {
  padding-inline-end: 26px;
}
@media (prefers-reduced-motion: reduce) {
  .vxs-tile::after,
  .vxs-line::after,
  .vxs-avatar::after,
  .vxs-player::after {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   Row headings — Netflix-size category titles above the card rows
   -------------------------------------------------------------------------- */
.swiperHolder .swiperTitle,
.hoverBlock h2.h5 {
  font-size: var(--vxl-rail-title-size, clamp(1.15rem, 1.5vw, 1.45rem));
  font-weight: var(--vxl-rail-title-weight, 600);
  color: var(--vod-white-color);
}
/* Owner call (critique round): classic's rail headings rendered weight-400
   forever — Bootstrap's .font-weight-normal !important winning over the
   token, an accident, not a choice. The token weight is the standard now;
   the Bold arrangement pill still outranks this (higher specificity). */
body[data-layout] .swiperHolder .swiperTitle {
  font-weight: var(--vxl-rail-title-weight, 600) !important;
}

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */
.videoBlock.vxc {
  -webkit-transition: -webkit-transform var(--vxl-dur-2) var(--vxl-ease), box-shadow var(--vxl-dur-2) var(--vxl-ease);
  transition: transform var(--vxl-dur-2) var(--vxl-ease), box-shadow var(--vxl-dur-2) var(--vxl-ease);
}

/* Skeleton → content reveal (transitions.dev skeleton-reveal recipe, adapted
   to Vue's branch swap): the vxg skeletons and the real rails/bands are
   sibling v-if branches, so there is no stacked cross-fade — instead the
   content root animates IN on mount, resolving from a soft blur. Runs once
   per insert (lazy sections get it as they land) and fills backwards, so
   after 400ms the element carries no filter at all. The container animates,
   never the N cards inside it. */
.swiperHolder {
  animation: vx-reveal var(--vxl-dur-3) var(--vxl-ease) backwards;
}
@keyframes vx-reveal {
  from {
    opacity: 0;
    filter: blur(2px);
  }
}

/* --------------------------------------------------------------------------
   Expanded card
   -------------------------------------------------------------------------- */
.videoBlock.vxc.vxc-open {
  z-index: 100;
  -webkit-transform: scale(1.35);
  transform: scale(1.35);
  width: inherit;
  border-radius: var(--vxl-card-radius, 6px);
  background-color: var(--vod-card-bg);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45), 0 14px 40px rgba(0, 0, 0, 0.55);
}
.videoBlock.vxc.vxc-open .card {
  border-radius: var(--vxl-card-radius, 6px) var(--vxl-card-radius, 6px) 0 0;
}
/* seam-free fade from the preview into the panel (mirrors the vxm hero).
   Starts from the tenant's Card Gradient token — this rule replaced the
   only consumer of --vod-card-gradient exactly when the hover shows it,
   which is why the control read as dead (#5350 item 5); card-bg stays the
   fallback so the seam-free fade survives any legacy palette. */
.videoBlock.vxc.vxc-open .card-img-overlay.boxShadow {
  background: linear-gradient(0deg, var(--vod-card-gradient, var(--vod-card-bg)) 0%, rgba(0, 0, 0, 0) 22%);
}

/* --------------------------------------------------------------------------
   Info panel
   -------------------------------------------------------------------------- */
.videoBlock.vxc.vxc-open .videoInfo {
  position: relative;
  bottom: 0;
  visibility: visible;
  opacity: 1;
  z-index: 1;
  padding: 10px 12px 12px !important;
  background-color: var(--vod-card-bg);
  border-radius: 0 0 var(--vxl-card-radius, 6px) var(--vxl-card-radius, 6px);
  animation: vxc-panel-in 0.25s ease;
}
@keyframes vxc-panel-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.videoBlock.vxc .cardActions {
  align-items: center;
}

/* Buttons — var-driven incl. hover (vodlix hardcodes greys) */
.videoBlock.vxc .boxBtn {
  border: 1px solid color-mix(in srgb, var(--vod-white-color, #fff) 45%, transparent);
  border-color: color-mix(in srgb, var(--vod-white-color) 45%, transparent);
  background-color: rgba(30, 30, 30, 0.6);
  background-color: color-mix(in srgb, var(--vod-menu-bg) 60%, transparent);
  transition: border-color var(--vxl-dur-1) var(--vxl-ease), background-color var(--vxl-dur-1) var(--vxl-ease);
}
.videoBlock.vxc .boxBtn:hover,
.videoBlock.vxc .boxBtn:active {
  border-color: var(--vod-white-color);
  background-color: rgba(30, 30, 30, 0.9);
  background-color: color-mix(in srgb, var(--vod-menu-bg) 90%, transparent);
}
/* Play button matches its sibling action circles (+ / like): subtle fill,
   white outline, white filled glyph — was a solid white disc with a dark
   triangle (base .boxBtn.playBtn2 forces white bg + black icon). */
.videoBlock.vxc .boxBtn.playBtn2 {
  background-color: rgba(30, 30, 30, 0.6);
  background-color: color-mix(in srgb, var(--vod-menu-bg) 60%, transparent);
  border-color: color-mix(in srgb, var(--vod-white-color, #fff) 45%, transparent);
  border-color: color-mix(in srgb, var(--vod-white-color) 45%, transparent);
}
.videoBlock.vxc .boxBtn.playBtn2:hover,
.videoBlock.vxc .boxBtn.playBtn2:active {
  background-color: rgba(30, 30, 30, 0.9);
  background-color: color-mix(in srgb, var(--vod-menu-bg) 90%, transparent);
  border-color: var(--vod-white-color);
}
.videoBlock.vxc .boxBtn.playBtn2 i,
.videoBlock.vxc .boxBtn.playBtn2 .vxm-ico {
  color: var(--vod-white-color);
  /* base .playBtn2 pins 26px (sized to fill the old white disc). Now a ghost
     circle: match the 20px sibling glyphs, minus a hair — a filled triangle
     reads heavier than an outline icon, so 18px is optically equal. */
  font-size: 18px;
}

/* Meta row — replace hardcoded #8A8A8A / #D2D2D2 */
.videoBlock.vxc .maturityTextBadge {
  border-color: color-mix(in srgb, var(--vod-white-color, #fff) 45%, transparent);
  border-color: color-mix(in srgb, var(--vod-white-color) 45%, transparent);
  color: color-mix(in srgb, var(--vod-white-color, #fff) 80%, transparent);
  color: color-mix(in srgb, var(--vod-white-color) 80%, transparent);
}
.videoBlock.vxc .videoInfo .textColor {
  color: var(--vod-grey-text) !important;
}
.videoBlock.vxc .vxc-live {
  display: inline-flex;
  align-items: center;
  padding: 0 6px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--vod-white-color);
  background-color: var(--vod-primary);
}

/* Continue-watch progress — keep it in the expanded card, themed
   (vodlix hides it on .hoverOnVideo:hover) */
.videoBlock.vxc.hoverOnVideo:hover .progress,
.videoBlock.vxc.hoverOnVideo:active .progress {
  display: flex;
  margin: 0 12px 10px !important;
  background-color: color-mix(in srgb, var(--vod-white-color, #fff) 25%, transparent);
  background-color: color-mix(in srgb, var(--vod-white-color) 25%, transparent);
}
.videoBlock.vxc .progress .progress-bar.bg-danger {
  background-color: var(--vod-primary) !important;
}

/* --------------------------------------------------------------------------
   Portrait rows — vodlix keeps them unscaled (!important); style the
   floating panel consistently
   -------------------------------------------------------------------------- */
.videoBlock.vxc.portraitBlock.vxc-open {
  border-radius: var(--vxl-card-radius, 6px);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45), 0 14px 40px rgba(0, 0, 0, 0.55);
}

/* --------------------------------------------------------------------------
   Mobile — defense in depth (enter() already early-returns on mobile)
   -------------------------------------------------------------------------- */
@media only screen and (max-width: 767px) {
  .videoBlock.vxc.vxc-open {
    -webkit-transform: none !important;
    transform: none !important;
    box-shadow: none;
  }
  .videoBlock.vxc.vxc-open .videoInfo {
    display: none !important;
  }
}

/* --------------------------------------------------------------------------
   Reduced motion — no transitions/animations; the dwell delay stays
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .videoBlock.vxc,
  .videoBlock.vxc .boxBtn {
    transition: none;
  }
  .videoBlock.vxc.vxc-open .videoInfo {
    animation: none;
  }
}

/* ==========================================================================
   vxr — Netflix-style reaction control
   A single collapsed thumb showing the current rating; on hover it reveals a
   floating pill with "Not for me" (dislike) + "I like this" (like), each with
   a label bubble. Used by the likeVideo component in the info modal, the
   detail pages and the hover cards. Consumes only --vod-* customizer vars.
   ========================================================================== */
.vxr {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
}
.vxr__trigger {
  transition: opacity var(--vxl-dur-0) var(--vxl-ease);
}
/* hide the collapsed trigger once the pill takes over (it still holds layout) */
.vxr:hover .vxr__trigger {
  opacity: 0;
}
/* floating reaction pill — anchored to the trigger's right so the like stays
   in place and dislike expands to the left; absolute so it never shifts the row */
.vxr__pop {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%) scale(0.9);
  transform-origin: right center;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  /* opaque-by-construction dark pill regardless of tenant alpha */
  background:
    linear-gradient(color-mix(in srgb, var(--vod-menu-bg) 92%, #000), color-mix(in srgb, var(--vod-menu-bg) 92%, #000)),
    #000;
  border: 1px solid color-mix(in srgb, var(--vod-white-color, #fff) 12%, transparent);
  border-color: color-mix(in srgb, var(--vod-white-color) 12%, transparent);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--vxl-dur-1) var(--vxl-ease), transform var(--vxl-dur-1) var(--vxl-ease);
  z-index: 40;
}
.vxr:hover .vxr__pop {
  opacity: 1;
  transform: translateY(-50%) scale(1);
  pointer-events: auto;
}
.vxr__optBtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--vod-white-color);
  cursor: pointer;
  transition: background-color var(--vxl-dur-0) var(--vxl-ease), transform var(--vxl-dur-0) var(--vxl-ease);
}
.vxr__optBtn .mdi,
.vxr__optBtn .vxm-ico {
  font-size: 20px;
  line-height: 1;
}
/* Lucide has no filled thumb variant — so an active/selected rating fills the
   outline glyph (fill: currentColor) instead, mirroring MDI's filled-vs-outline. */
.vxr--on .vxm-ico {
  fill: currentColor;
}
.vxr__optBtn:hover {
  background-color: color-mix(in srgb, var(--vod-white-color, #fff) 16%, transparent);
  background-color: color-mix(in srgb, var(--vod-white-color) 16%, transparent);
  transform: scale(1.08);
}
.vxr__optBtn:disabled {
  opacity: 0.5;
  cursor: default;
}
/* label bubble + caret above each reaction, on its own hover (Netflix white tag) */
.vxr__optBtn::after {
  content: attr(data-vxr-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 9px;
  border-radius: 4px;
  background: #fff;
  color: #000;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--vxl-dur-0) var(--vxl-ease);
}
.vxr__optBtn::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--vxl-dur-0) var(--vxl-ease);
}
.vxr__optBtn:hover::after,
.vxr__optBtn:hover::before {
  opacity: 1;
}
/* RTL — mirror the anchor so dislike expands right, like stays put */
body.rtl .vxr__pop {
  right: auto;
  left: 0;
  transform-origin: left center;
}
@media (prefers-reduced-motion: reduce) {
  .vxr__trigger,
  .vxr__pop,
  .vxr__optBtn,
  .vxr__optBtn::after,
  .vxr__optBtn::before {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Arrangement: card_hover="lift" — no dwell panel. Hovering a card shows the
   artwork and nothing else; a calm scale + shadow says "this is the one you
   are pointing at" without decorating the artwork. The panel is where More
   Info lived, and the poster's own link points at `/watch/` on desktop, so
   with the panel gone the poster IS the way in: thumbUrl / posterClick in
   video.html and series.html send it to the title's info when this word is
   set. `panel` is the default (the dwell rules at the top of this file).
   -------------------------------------------------------------------------- */
body[data-lo-card-hover="lift"] .videoBlock.vxc.vxc-open {
  transform: none !important;
  z-index: 5 !important;
}
body[data-lo-card-hover="lift"] .videoBlock.vxc.vxc-open .videoInfo {
  display: none !important;
}
body[data-lo-card-hover="lift"] .videoBlock.vxc {
  transition: transform var(--vxl-dur-2) var(--vxl-ease),
              box-shadow var(--vxl-dur-2) var(--vxl-ease);
}
body[data-lo-card-hover="lift"] .videoBlock.vxc.vxc-open {
  transform: scale(1.04) !important;
  box-shadow: var(--vxl-shadow-3);
}
/* The :hover half only where a pointer can hover. On touch, a tap left the
   card stuck at scale(1.04) after navigating back (sticky hover). */
@media (hover: hover) {
  body[data-lo-card-hover="lift"] .videoBlock.vxc:hover .videoInfo {
    display: none !important;
  }
  body[data-lo-card-hover="lift"] .videoBlock.vxc:hover {
    transform: scale(1.04) !important;
    box-shadow: var(--vxl-shadow-3);
  }
}
@media (prefers-reduced-motion: reduce) {
  body[data-lo-card-hover="lift"] .videoBlock.vxc {
    transition: none;
  }
  /* No transform, so elevation alone has to carry the hover state. */
  body[data-lo-card-hover="lift"] .videoBlock.vxc.vxc-open {
    transform: none !important;
    box-shadow: var(--vxl-shadow-3);
  }
  @media (hover: hover) {
    body[data-lo-card-hover="lift"] .videoBlock.vxc:hover {
      transform: none !important;
      box-shadow: var(--vxl-shadow-3);
    }
  }
}
}

/* ==========================================================================
   CONTINUE WATCHING — the resume row.

   Landscape stills (forced for this rail alone, see new-swiper.html's
   forceThumbType), a progress rule welded to the artwork's bottom edge, the
   episode caption underneath, and an overflow menu in the corner. The menu
   is not decoration: with card_hover="lift" there is no dwell panel, which
   is where "Remove from Continue Watching" used to live, so without it a
   finished title could not be taken off the row.

   Universal since 26.480.0 (was cinematic-only): the bare body[data-layout]
   prefix keeps the specificity the rules were written at, nothing more.
   ========================================================================== */
body[data-layout] .swiper--continue-watching .card.no-border {
  background: transparent !important;
}
/* The slide is sized by an aspect-ratio spacer and the card is laid over it,
   so the caption hangs BELOW the track without adding to its height — its
   last line landed on the next rail's heading. The caption is bounded (title
   clamped to two lines, then one meta line), so the row reserves exactly
   that much underneath. */
body[data-layout] .swiper--continue-watching .vxcw-caption {
  min-height: 66px;
}
body[data-layout] .swiper--continue-watching {
  /* !important: the rail carries Bootstrap's .pb-4 utility, which is itself
     !important and would otherwise keep the row at 24px. */
  padding-bottom: 84px !important;
}
/* The rule sits ON the still, flush to its bottom edge — as a sibling below
   it (the stock position) it floated in the gap between card and caption. */
body[data-layout] .swiper--continue-watching .videoBlock {
  position: relative;
}
/* Flush with the card's bottom edge, inside it. The bar lives in the card
   now (see video.html / series.html), so `bottom: 0` seats it on the tile's
   own edge rather than leaving it at its static position — which is what
   made it read as a separate strip sitting under the artwork.
   `border-radius: 0` on purpose: the card already clips to its 4px corners,
   so the bar takes the tile's shape and its ends meet the rounded edge
   instead of curving away from it. */
body[data-layout] .swiper--continue-watching .vxcw-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  width: auto !important;
  margin: 0 !important;
  border-radius: 0;
  background: color-mix(in srgb, var(--vxl-ink) 28%, transparent) !important;
  overflow: hidden;
}
body[data-layout] .swiper--continue-watching .vxcw-progress .progress-bar {
  background: var(--vod-primary, #e50914) !important;
}
/* ---- Preview media stays inside the card -------------------------------
   The preview is absolutely positioned, and an absolutely-positioned
   element is clipped ONLY by an ancestor that is its containing block —
   `overflow: hidden` on the card does nothing if the card is not that
   block. When the anchor and the card are both static, the preview
   resolves against whatever is positioned further up (the rail wrapper is
   1920x299 and starts ABOVE the card), so it escapes the tile entirely and
   paints over the row heading and the neighbouring cards.

   So the containing block is pinned to the card rather than the preview
   being resized: the card and its anchor are made positioned, which puts
   the card's own `overflow: hidden` back in charge of the preview. The
   size caps only ever shrink — nothing here can make a preview larger,
   which an earlier `inset: 0` version could when the ancestor it resolved
   against was bigger than the card.

   An embedded trailer needs this most: it arrives as raw provider markup
   through `v-html` (`emebedTrailer` is the API's `embed_code`) carrying its
   own `width="560" height="315"`. */
/* `a.relative` is the ARTWORK link specifically — not `.card > a`, which
   also matches the play affordance and, at higher specificity than its own
   rule, would strip its absolute positioning and drop it into the flow. */
body[data-layout] .videoBlock.vxc .card,
body[data-layout] .videoBlock.vxc .card > a.relative {
  position: relative;
}
/* With the containing block pinned above, filling it is safe: `inset: 0`
   can now only ever mean the card. Without that guarantee it was the bug —
   it stretched the preview to whichever larger ancestor happened to be
   positioned. Capped as well as stretched, so a provider's own width can
   never win. */
body[data-layout] .videoBlock.vxc .card iframe,
body[data-layout] .videoBlock.vxc .card video,
body[data-layout] .videoBlock.vxc .card .video-js,
body[data-layout] .videoBlock.vxc .card .vjs-tech {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  border: 0;
  object-fit: cover;
}

/* ---- Resume affordance, bottom-left of the still -----------------------
   The reference puts a bare white triangle there on every resume card, and
   it earns its place: the still itself opens the title's page, so without
   it the row has no one-click way back into playback. Always visible, like
   the ⋮ — there is no dwell at all on touch.
   Bare glyph again, no disc: legibility over a bright frame comes from a
   drop-shadow, which darkens only what is behind the triangle. It clears
   the progress rule at the card's base. */
/* The padding is the tap target, not the glyph: at 22px the triangle alone
   would be a 22px target, under the 30px a thumb needs. The inset is
   reduced by the same 4px so the glyph still sits 12px off the card's
   edges — the padding grows the hit area inward, invisibly. */
body[data-layout] .swiper--continue-watching .vxcw-play {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  color: var(--vxl-ink, #fff);
  line-height: 0;
  text-decoration: none;
  opacity: 1;
}
body[data-layout] .swiper--continue-watching .vxcw-play .vxm-ico {
  width: 22px;
  height: 22px;
  /* ink and scrim both derive from the tenant's branding, so the glyph stays
     legible on a light-branded site instead of being white-on-white */
  color: var(--vxl-ink, #fff);
  filter: drop-shadow(0 1px 5px color-mix(in srgb, var(--vxl-scrim-solid) 88%, transparent));
}
body[data-layout] .swiper--continue-watching .vxcw-play:hover {
  opacity: 0.85;
}
body[data-layout] .swiper--continue-watching .vxcw-play:focus-visible {
  outline: 2px solid var(--vxl-ink, #fff);
  outline-offset: 3px;
}

/* The bar must not move when the card is focused. cards.css re-margins it on
   hover (`margin: 0 12px 10px !important`, for the legacy expanding card),
   which lifted it 10.4px off the bottom edge and detached it from the tile —
   measured. Restated here for every focus state, at a specificity that
   outranks that rule, so the bar is simply always where it is at rest. */
body[data-layout] .swiper--continue-watching .videoBlock.vxc.hoverOnVideo:hover .progress.vxcw-progress,
body[data-layout] .swiper--continue-watching .videoBlock.vxc.hoverOnVideo:active .progress.vxcw-progress,
body[data-layout] .swiper--continue-watching .videoBlock.vxc.vxc-open .progress.vxcw-progress,
body[data-layout] .swiper--continue-watching .videoBlock.vxc:hover .progress.vxcw-progress {
  display: flex;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: auto !important;
  margin: 0 !important;
  border-radius: 0;
}

/* The row keeps the lift and transitions every other rail uses — it was
   briefly opted out of both, along with a white focus ring on the card.
   The ring is gone: `outline` on the card is drawn outside its border box,
   and the slide clips it on three sides, so only the bottom edge survived
   and it read as a stray underline rather than a frame. */

/* No panel behind a resume card. The block paints rgb(13,13,13) at a 6px
   radius, which on the near-black page shows as a slab wrapping BOTH the
   artwork and the caption — the card stops reading as a still with text
   under it and starts reading as a tile with a backing. The artwork and the
   ring supply all the edge this row needs. */
body[data-layout] .swiper--continue-watching .videoBlock.vxc,
body[data-layout] .swiper--continue-watching .videoBlock.vxc:hover,
body[data-layout] .swiper--continue-watching .videoBlock.vxc:active,
body[data-layout] .swiper--continue-watching .videoBlock.vxc.hoverOnVideo:hover,
body[data-layout] .swiper--continue-watching .videoBlock.vxc.vxc-open {
  background: transparent !important;
  border-radius: 0 !important;
}

/* ---- Caption: "S1 E2  Family Statements", then a quiet meta line -------- */
body[data-layout] .swiper--continue-watching .vxcw-caption {
  padding: 10px 2px 0;
}
body[data-layout] .swiper--continue-watching .vxcw-title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--vxl-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* the episode number reads as a label, so it stays quiet next to the title */
body[data-layout] .swiper--continue-watching .vxcw-ep {
  margin-inline-end: 6px;
  font-weight: 400;
  color: var(--vxl-ink-muted);
}
body[data-layout] .swiper--continue-watching .vxcw-meta {
  margin-top: 3px;
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--vxl-ink-muted);
}
/* the stock mobile-only title would duplicate the caption */
body[data-layout] .swiper--continue-watching .videoBlock > .title {
  display: none !important;
}

body[data-layout]:not([data-lo-card-hover="lift"]) .swiper--continue-watching .videoBlock.vxc.vxc-open .vxcw-caption,
body[data-layout]:not([data-lo-card-hover="lift"]) .swiper--continue-watching .videoBlock.vxc.vxc-open .vxcw-play {
  display: none !important;
}
body[data-layout][data-lo-card-hover="lift"] .swiper--continue-watching .videoBlock.vxc.vxc-open .titleBox {
  display: none !important;
}

/* ---- Overflow menu ------------------------------------------------------ */
body[data-layout] .swiper--continue-watching .vxcw-menu,
body[data-layout] .swiper--my-list .vxcw-menu {
  position: absolute;
  top: 4px;
  inset-inline-end: 4px;
  z-index: 6;
}
/* Bare glyph — no chip, no ring, no fill. The reference draws three white
   dots straight onto the still, and a scrim disc around them read as a
   button floating over the artwork. Legibility on a bright frame comes from
   a drop-shadow instead: it darkens only what is behind the dots
   themselves, so nothing box-shaped appears.
   Always visible, as the reference has it: hiding it until dwell makes the
   row's only affordance for Remove/Restart undiscoverable, and there is no
   dwell at all on touch. */
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger,
body[data-layout] .swiper--my-list .vxcw-menu__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  outline: 0;
  border-radius: 50%;
  background: transparent;
  box-shadow: none;
  color: var(--vxl-ink, #fff);
  opacity: 1;
  transition: opacity var(--vxl-dur-2) var(--vxl-ease);
}
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger:hover,
body[data-layout] .swiper--my-list .vxcw-menu__trigger:hover,
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger:focus,
body[data-layout] .swiper--my-list .vxcw-menu__trigger:focus,
body[data-layout] .swiper--continue-watching .vxcw-menu.is-open .vxcw-menu__trigger,
body[data-layout] .swiper--my-list .vxcw-menu.is-open .vxcw-menu__trigger {
  background: transparent;
  box-shadow: none;
  outline: 0;
}
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger:hover,
body[data-layout] .swiper--my-list .vxcw-menu__trigger:hover,
body[data-layout] .swiper--continue-watching .vxcw-menu.is-open .vxcw-menu__trigger,
body[data-layout] .swiper--my-list .vxcw-menu.is-open .vxcw-menu__trigger {
  opacity: 0.75;
}
/* keyboard users still get a ring — removing the outline is about the
   resting state, not about making the control untabbable */
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger:focus-visible,
body[data-layout] .swiper--my-list .vxcw-menu__trigger:focus-visible {
  outline: 2px solid var(--vxl-ink, #fff);
  outline-offset: 2px;
}
body[data-layout] .swiper--continue-watching .vxcw-menu__trigger .vxm-ico,
body[data-layout] .swiper--my-list .vxcw-menu__trigger .vxm-ico {
  width: 22px;
  height: 22px;
  color: var(--vxl-ink, #fff);
  filter: drop-shadow(0 1px 4px color-mix(in srgb, var(--vxl-scrim-solid) 85%, transparent));
}
/* Placed from JS as `position: fixed` (see toggleCwMenu) — the swiper track
   and the card both clip their overflow, which sliced an absolutely
   positioned panel off at the card's edge, and Swiper's transform on the
   track made `fixed` resolve against IT rather than the viewport. The panel
   is therefore re-parented to <body> while open, which is exactly why these
   rules must NOT be scoped under .swiper--continue-watching: detached, it
   would match nothing and render unstyled. */
body[data-layout] .vxcw-menu__pop {
  position: fixed;
  z-index: 1200;
  min-width: 264px;
  padding: 8px 0;
  border-radius: 8px;
  /* opaque by construction: the surface token is a translucent white, which
     over artwork left the labels unreadable. Same trick as the login card —
     stack it on the page colour so a tenant's own palette still shows. */
  background:
    linear-gradient(var(--vxl-surface-2), var(--vxl-surface-2)),
    var(--vod-body-bg, #0b0b10);
  border: 1px solid var(--vxl-line);
  box-shadow: var(--vxl-shadow-3);
}
body[data-layout] .vxcw-menu__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 18px;
  border: 0;
  background: transparent;
  color: var(--vxl-ink);
  font-size: 14px;
  font-weight: 600;
  text-align: start;
  text-decoration: none;
  white-space: nowrap;
}
body[data-layout] .vxcw-menu__item:hover {
  background: color-mix(in srgb, var(--vxl-ink) 10%, transparent);
  color: var(--vxl-ink);
  text-decoration: none;
}
body[data-layout] .vxcw-menu__item .vxm-ico {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}
/* "Resume S1 E1" carries its progress rule here too, as on the CTA buttons.
   The row has room below the text, so the rule hangs closer than the 7px the
   buttons use. */
body[data-layout] .vxcw-menu__item .vxc-resumeBar {
  bottom: -5px;
}
/* Edge cases (a card at the row's right edge, or one low in the viewport)
   are handled by toggleCwMenu, which flips the panel left/up; nothing else
   is needed per breakpoint. */

