video.pv_list_popup {
    width: 100%;
    height: auto;
    object-fit: cover;
}

.pv_list_media_holder {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
}

.pv_list_media_holder iframe, .pv_list_media_holder video {
    width: 100%;
    height: 100%;
}

/* Loader shown inside every .videoholder while the iframe/video warms up.
   Mirrors the rules in productvideoextraright-1.7.css so the same markup
   works on category listings (which don't load that file). */
.videoholder { position: relative; }
.pv-video-loader {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    z-index: 2;
    pointer-events: none;
    min-height: 60px;
    transition: opacity 0.3s ease, visibility 0.3s;
}
.pv-video-loader.is-hidden { opacity: 0; visibility: hidden; }
.pv-video-loader__spinner {
    display: block;
    width: 40px;
    height: 40px;
    border: 4px solid rgba(0, 0, 0, 0.18);
    border-top-color: var(--pv-loader-color, #111111);
    border-radius: 50%;
    animation: pvSlideLoaderSpin 0.9s linear infinite;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
}
@keyframes pvSlideLoaderSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .pv-video-loader__spinner { animation: none; opacity: 0.6; }
}

/* ------------------------------------------------------------------ *
 * Inline SVG icons (replaced the FontAwesome glyphs). Inherit color
 * and font-size so the existing PV_LISTINGS_ICON_SIZE/opacity styles
 * still drive sizing. `.pv_icon_glyph` is the wrapper span.
 * ------------------------------------------------------------------ */
.pv_icon_glyph { display: inline-flex; align-items: center; justify-content: center; line-height: 0; }
.pv_svg_icon   { width: 1em; height: 1em; fill: currentColor; }
/* Card play-icon overlay. The glyph span is absolutely centred (the old
   FontAwesome rules targeted <i> and no longer match the new <span>). The SVG
   inherits the configured PV_LISTINGS_ICON_SIZE via font-size, defaulting to
   40px, with a soft white glow mirroring the old icon's text-shadow. */
.pv_icon_wrapper .pv_icon_glyph {
    position: absolute;
    left: 0;
    top: 50%;
    width: 100%;
    text-align: center;
    transform: translateY(-50%);
    z-index: 10;
    color: #000;
    font-size: 40px;
    line-height: 0;
}
.pv_icon_wrapper .pv_svg_icon { width: 1em; height: 1em; }
.pv_icon_wrapper .pv_icon_glyph .pv_svg_icon {
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, .9));
}

/* ------------------------------------------------------------------ *
 * Modern "View video" pill button (PV_LISTINGS_DESK = button mode).
 * The button previously rendered as an unstyled theme text link. These
 * rules give it a self-contained modern look that works regardless of
 * whether the theme styles `.btn`. Scoped to `.pv_popupvideo` only.
 * ------------------------------------------------------------------ */
button.pv_popupvideo,
a.pv_popupvideo,
.pv_popupvideo {
    display: inline-flex;
    /* Keep icon + label on a single line. The theme's .btn (width:100% /
       white-space:normal on mobile) and the icon span's inherited width were
       pushing the label onto a 2nd line on narrow cards. */
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: auto;
    max-width: 100%;
    white-space: nowrap;
    padding: 8px 16px;
    margin: 6px 0;
    border: 0;
    border-radius: 999px;
    background: #1b8ef2;
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: .01em;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(16, 42, 67, .18);
    transition: background .2s ease, transform .15s ease, box-shadow .2s ease;
    -webkit-appearance: none;
    appearance: none;
}
/* The icon span must size to its glyph, never stretch full-width (it carries a
   position class like pv_default in icon-mode). */
.pv_popupvideo .pv_icon_glyph {
    flex: 0 0 auto;
    width: auto;
    position: static;
    margin: 0;
    line-height: 0;
}
.pv_popupvideo .pv_button_text { white-space: nowrap; flex: 0 1 auto; }
button.pv_popupvideo:hover,
a.pv_popupvideo:hover,
.pv_popupvideo:hover,
.pv_popupvideo:focus-visible {
    background: #1366b8;
    color: #fff;
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(16, 42, 67, .26);
    text-decoration: none;
}
.pv_popupvideo:active { transform: translateY(0); }
.pv_popupvideo .pv_svg_icon { width: 1.15em; height: 1.15em; }
.pv_popupvideo .pv_button_text { line-height: 1; }
@media (prefers-reduced-motion: reduce) {
    .pv_popupvideo { transition: none; }
    .pv_popupvideo:hover { transform: none; }
}
/* Narrow cards (dense mobile grids): tighten the pill so "View video" stays on
   one line within the thumbnail width instead of being clipped. */
@media (max-width: 575px) {
    .pv_popupvideo { padding: 6px 11px; font-size: 12px; gap: 4px; }
    .pv_popupvideo .pv_svg_icon { width: 1em; height: 1em; }
}

/* ================================================================== *
 * Listing hover EFFECTS (PV_LISTINGS_HOVER_EFFECT, mode "video on
 * hover"). The product image stays visible; the video overlay
 * (.pv_list_media_holder) is revealed on hover. Effect 0 (legacy
 * "replace image") does NOT use these classes and is unaffected.
 * ================================================================== */
.pv-hover-fx .pv_list_media_holder {
    opacity: 0;
    pointer-events: none;
    /* The holder is position:absolute but its z-index was auto, so the theme's
       product image (rendered in a sibling container) painted ON TOP of the
       revealed video — the effect looked inert ("image shows on hover, no
       video"). z-index:1 lifts the playing video above the image while still
       sitting BELOW theme hover affordances that use z-index >= 2 (e.g. a
       "Quick view" bar), so those stay clickable on top of the video. */
    z-index: 1;
    transition: opacity .35s ease, transform .4s ease;
    will-change: opacity, transform;
}
.pv-hover-fx:hover .pv_list_media_holder,
.pv-hover-fx:focus-within .pv_list_media_holder {
    opacity: 1;
    pointer-events: auto;
}
/* Fill the whole card image area with the video (no letterbox gaps that let
   the product image show through around a contained 16:9 clip). */
.pv-hover-fx .pv_list_media_holder,
.pv-hover-fx .pv_list_media_holder .videoholder {
    width: 100%;
    height: 100%;
}
.pv-hover-fx .pv_list_media_holder video,
.pv-hover-fx .pv_list_media_holder iframe {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
}
/* Keep the underlying product image crisp; the video sits on top of it. */
.pv-hover-fx img { transition: opacity .35s ease; }

/* 1) Crossfade — background video fades in over the image (no movement). */
/*    (base rules above already deliver the crossfade) */

/* 2) Zoom-in — video scales up from the centre while fading in. */
.pv-hover-fx-zoom .pv_list_media_holder { transform: scale(.9); }
.pv-hover-fx-zoom:hover .pv_list_media_holder,
.pv-hover-fx-zoom:focus-within .pv_list_media_holder { transform: scale(1); }

/* 3) Lift — the whole card lifts with a shadow (Netflix style) and the
 *    video reveals on top. Applied to the product list item itself. */
.pv-hover-fx-lift {
    transition: transform .3s ease, box-shadow .3s ease, z-index 0s;
    transform-origin: center center;
    position: relative;
}
.pv-hover-fx-lift:hover,
.pv-hover-fx-lift:focus-within {
    transform: scale(var(--pv-lift-scale, 1.1));
    box-shadow: 0 14px 34px rgba(16, 42, 67, .28);
    /* High enough to sit above theme "New/Sale" badges and sticky elements. */
    z-index: 20;
}

@media (prefers-reduced-motion: reduce) {
    .pv-hover-fx .pv_list_media_holder,
    .pv-hover-fx-zoom .pv_list_media_holder,
    .pv-hover-fx-lift { transition: opacity .2s ease; transform: none; }
    .pv-hover-fx-lift:hover { transform: none; }
}

/* ── Floating listing popup (icon + lightbox mode) ──────────────────────────
 * productvideoextraright-1.7.css (the product-page popup styles) is NOT loaded
 * on category/listing pages, so the popup had no size bound and could grow
 * taller than the window (content cut off below the fold). Clamp it to the
 * viewport and give the media a stable 16:9 box so every format fits. The JS
 * still positions the wrapper; it reads the (now clamped) size when centring. */
.pv_video_wrapper {
    max-width: 92vw;
    max-height: 90vh;
    box-sizing: border-box;
    overflow: hidden;
    border-radius: 16px;
}
.pv_video_wrapper .pv_video_hover {
    position: relative;
    width: 100%;
    padding-bottom: 56.25%; /* 16:9 — video providers (youtube/vimeo/html5) */
    height: 0;
    max-height: 84vh;
    overflow: hidden;
    border-radius: 12px;
    background: #000;
}
/* The floating popup reuses the gallery markup, where setVideoAspect() injects a
   padding-bottom aspect onto `.videoholder` GLOBALLY (sized to the product image).
   Inside the popup that fights the box aspect set on `.pv_video_hover` and lets
   the media overflow its slot: a Sketchfab 3D model / Google Map was sized 788x788
   and then cropped to a 788x443 (16:9) window — "the 3D object doesn't display well
   in the lightbox". object-fit can letterbox a <video> but does NOT clip an
   <iframe>'s internal content, so iframes were the visible casualty. Pin both
   wrapper layers to FILL the box so the aspect is driven solely by .pv_video_hover. */
.pv_video_wrapper .pv_list_media_holder,
.pv_video_wrapper .videoholder {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0 !important;
}
.pv_video_wrapper video,
.pv_video_wrapper iframe {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    object-fit: contain; /* letterboxes <video>; harmless on <iframe> */
}
/* Non-video iframe embeds (Sketchfab 3D, Google Maps, and any future iframe
   provider) are NOT 16:9 — a 16:9 letterbox crops them top & bottom. Give them a
   taller 4:3 box so the whole model/map is visible; the iframe fills it edge-to-
   edge. Matches by EXCLUDING the known video providers, so it generalises to any
   custom iframe provider a merchant adds (no hard-coded provider whitelist). */
.pv_video_wrapper .pv_video_hover:not([data-provider="youtube"]):not([data-provider="vimeo"]):not([data-provider="html5"]) {
    padding-bottom: 75%; /* 4:3 */
    background: #0b0b0b;
}

/* ── Product info bar under the click-to-open listing popup (button mode) ──────
 * Appended by pv-listing-button.js after the video: Title | Price | View | cart.
 * Reads the .product-miniature card; the add-to-cart <form> is cloned verbatim so
 * the theme's own button styling + delegated ajax-cart handler keep working. */
.pv_video_wrapper #pv_popup_content.pv-popup-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 10px;
    padding: 12px 4px 2px;
}
.pv-popup-bar__info { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.pv-popup-bar__title {
    font-weight: 700; font-size: 16px; line-height: 1.25; color: #111;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pv-popup-bar__price { font-size: 15px; font-weight: 700; color: #1b8ef2; }
.pv-popup-bar__price .price,
.pv-popup-bar__price .product-miniature__price { color: inherit; font: inherit; }
.pv-popup-bar__actions { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.pv-popup-bar__view {
    display: inline-flex; align-items: center; padding: 9px 16px; border-radius: 999px;
    background: #eef2f6; color: #102a43; font-size: 13px; font-weight: 600;
    text-decoration: none; white-space: nowrap; transition: background .15s ease;
}
.pv-popup-bar__view:hover { background: #e2e8f0; color: #102a43; text-decoration: none; }
.pv-popup-bar__cart { display: inline-flex; }
.pv-popup-bar__cart form { margin: 0; }
@media (max-width: 575px) {
    .pv_video_wrapper #pv_popup_content.pv-popup-bar { gap: 10px; }
    .pv-popup-bar__title { font-size: 14px; white-space: normal; }
}
