/* ==========================================================================
   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);
}
/* 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,
.vxlg-band {
  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;
  }
}
