/**
 * @package     J2Commerce
 * @subpackage  plg_j2commerce_app_imagedisplay
 *
 * @copyright   (C)2024-2026 J2Commerce, LLC <https://www.j2commerce.com>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

/* Constants declared here (not emitted server-side) so a site template can
   override them without touching the PHP-generated style attribute. */
.j2c-imagedisplay {
    --j2c-imgdisp-gap: .75rem;
    --j2c-imgdisp-radius: var(--product-radius-sm, 4px);
}

/* Own clip-rect implementation — J2Commerce ships no guaranteed
   visually-hidden utility in either template family. */
.j2c-imagedisplay-status {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   Shared (all three modes)
   Specificity (0,3,0) beats core's (0,2,0) at j2commerce.css:216 and its
   (0,2,0) inside the max-width:767.98px block at j2commerce.css:750 — a
   media query adds no specificity, so source order is irrelevant and no
   !important is needed.
   ========================================================================== */
.j2c-imagedisplay .product-gallery-thumbs .swiper-slide {
    opacity: var(--j2c-imgdisp-idle, .5);
}
.j2c-imagedisplay .product-gallery-thumbs .swiper-slide:hover {
    opacity: var(--j2c-imgdisp-hover, .8);
}
/* Both the Swiper-owned class (swiper/vertical modes) and the plugin-owned
   substitute (grid mode), always together.
   `.j2c-imagedisplay` is deliberately repeated: the idle rule above is
   also (0,3,0), and relying on this rule being declared later to win an
   exact specificity tie proved unreliable in testing. Repeating a class
   selector is valid CSS and raises this rule to (0,4,0) — an
   unambiguous, source-order-independent win over idle, no !important. */
.j2c-imagedisplay.j2c-imagedisplay .product-gallery-thumbs .swiper-slide-thumb-active,
.j2c-imagedisplay.j2c-imagedisplay .product-gallery-thumbs .j2c-imagedisplay-thumb-active {
    opacity: 1;
    border-color: var(--product-color-accent);
}

/* ==========================================================================
   Grid mode
   ========================================================================== */
.j2c-imagedisplay-grid .product-gallery-thumbs {
    overflow: visible;
    height: auto;
}
.j2c-imagedisplay-grid .product-gallery-thumbs .swiper-wrapper {
    display: grid;
    grid-template-columns: repeat(var(--j2c-imgdisp-cols-sm, 3), minmax(0, 1fr));
    gap: var(--j2c-imgdisp-gap, .75rem);
    height: auto;
    transform: none; /* neutralises Swiper's residual translate3d */
}
@media (min-width: 768px) {
    .j2c-imagedisplay-grid .product-gallery-thumbs .swiper-wrapper {
        grid-template-columns: repeat(var(--j2c-imgdisp-cols, 4), minmax(0, 1fr));
    }
}
.j2c-imagedisplay-grid .product-gallery-thumbs .swiper-slide {
    width: auto; /* beats core's width:100px AND core's 70px mobile rule */
    height: auto;
    aspect-ratio: 1 / 1;
    margin: 0; /* Swiper writes margin-right for spaceBetween */
    position: relative; /* keeps .thumb-video-indicator::after { inset:0 } working */
}

/* Grid thumb button — the click target that replaces the bare slide. */
.j2c-imagedisplay-grid .j2c-imagedisplay-thumb-btn {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    scroll-margin-block: 5rem;
}
.j2c-imagedisplay-grid .j2c-imagedisplay-thumb-btn:focus-visible {
    outline: 2px solid var(--product-color-accent);
    outline-offset: -3px;
}

/* ==========================================================================
   Vertical mode — shipped twice, once per supported breakpoint marker.
   A CSS custom property cannot appear in a media-query condition, so the
   breakpoint choice (768 | 992) is expressed as a marker class emitted
   server-side alongside the mode class.
   ========================================================================== */
@media (min-width: 768px) {
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical {
        display: grid;
        grid-template-columns: var(--j2c-imgdisp-side, 96px) minmax(0, 1fr);
        grid-template-rows: auto auto;
        column-gap: var(--j2c-imgdisp-gap, .75rem);
        align-items: start;
    }
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical > :is(.product-gallery-thumbs, .j2c-imagedisplay-thumbs-shell) {
        grid-column: 1;
        grid-row: 1;
    }
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical > .product-gallery-main {
        grid-column: 2;
        grid-row: 1;
        /* A grid item defaults to min-width: auto, so its automatic minimum
           is content-based. Swiper writes each slide's width from the
           measured container width; that width feeds back into the item's
           own intrinsic size, the item grows, Swiper re-measures — a
           runaway feedback loop that only stops at Swiper's internal 2^25px
           safety clamp (a blank main image behind a page-wide horizontal
           scrollbar). min-width: 0 breaks the loop; max-width: 100% caps
           the item to its track so it can't grow past it either. Proven by
           live isolation testing — do not remove either line. */
        min-width: 0;
        max-width: 100%;
    }
    /* Anything a sibling app injects between main and thumbs (e.g.
       app_imagepopup's full-view link) drops to a full-width row below
       instead of becoming a third column. Tagged by our JS, never by a
       wildcard — a wildcard would also match the absolutely-positioned
       discount badge and relocate it. */
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical > .j2c-imagedisplay-extra {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    /* Swiper vertical needs a definite height. Computed from the params
       rather than measured from the DOM: N square thumbs of width `side`
       plus N-1 gaps. This also keeps the thumbs square by construction,
       because Swiper then computes slide height = (H - gaps) / N = side. */
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical .product-gallery-thumbs {
        height: calc(
            var(--j2c-imgdisp-vslides, 4) * var(--j2c-imgdisp-side, 96px)
            + (var(--j2c-imgdisp-vslides, 4) - 1) * var(--j2c-imgdisp-gap, .75rem)
        );
        padding: 0; /* core adds padding: .75rem 0 0 */
        overflow: hidden;
    }
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical .product-gallery-thumbs .swiper-wrapper {
        height: 100%; /* core sets auto */
        align-items: stretch; /* core sets flex-start */
    }
    .j2c-imagedisplay-bp-768.j2c-imagedisplay-vertical .product-gallery-thumbs .swiper-slide {
        width: 100%; /* core sets 100px / 70px */
        margin: 0;
        position: relative;
    }
}
@media (min-width: 992px) {
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical {
        display: grid;
        grid-template-columns: var(--j2c-imgdisp-side, 96px) minmax(0, 1fr);
        grid-template-rows: auto auto;
        column-gap: var(--j2c-imgdisp-gap, .75rem);
        align-items: start;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical > :is(.product-gallery-thumbs, .j2c-imagedisplay-thumbs-shell) {
        grid-column: 1;
        grid-row: 1;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical > .product-gallery-main {
        grid-column: 2;
        grid-row: 1;
        /* See the matching comment in the 768px block above — same
           feedback loop, same fix, required at both breakpoints. */
        min-width: 0;
        max-width: 100%;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical > .j2c-imagedisplay-extra {
        grid-column: 1 / -1;
        grid-row: 2;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical .product-gallery-thumbs {
        height: calc(
            var(--j2c-imgdisp-vslides, 4) * var(--j2c-imgdisp-side, 96px)
            + (var(--j2c-imgdisp-vslides, 4) - 1) * var(--j2c-imgdisp-gap, .75rem)
        );
        padding: 0;
        overflow: hidden;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical .product-gallery-thumbs .swiper-wrapper {
        height: 100%;
        align-items: stretch;
    }
    .j2c-imagedisplay-bp-992.j2c-imagedisplay-vertical .product-gallery-thumbs .swiper-slide {
        width: 100%;
        margin: 0;
        position: relative;
    }
}

/* ==========================================================================
   Thumbnail arrows (swiper mode with arrows on, and vertical mode).
   The buttons only exist in the DOM when the plugin setting enables them
   (JS decides that once, at creation), but JS also toggles the
   .j2c-imagedisplay-arrows modifier on .product-gallery on every apply() —
   so a mode switch (e.g. vertical falling back to grid) hides them and
   frees the reserved padding without touching the DOM nodes.
   ========================================================================== */
.j2c-imagedisplay-thumbs-shell {
    position: relative;
}
.j2c-imagedisplay-thumb-prev,
.j2c-imagedisplay-thumb-next {
    position: absolute;
    z-index: 2;
    display: none;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 2px solid var(--product-color-accent);
    border-radius: 50%;
    background: rgba(255, 255, 255, .95);
    color: var(--product-color-accent);
    cursor: pointer;
    scroll-margin-block: 5rem;
    transition: box-shadow .2s, background .2s;
}
.j2c-imagedisplay-thumb-prev:hover,
.j2c-imagedisplay-thumb-next:hover {
    background: var(--product-color-accent);
    color: #fff;
}
.j2c-imagedisplay-thumb-prev:focus-visible,
.j2c-imagedisplay-thumb-next:focus-visible {
    outline: 2px solid var(--product-color-accent);
    outline-offset: 2px;
}

/* Border-drawn chevrons — no markup injection, no SVG string. */
.j2c-imagedisplay-thumb-prev::after,
.j2c-imagedisplay-thumb-next::after {
    content: '';
    display: block;
    width: 8px;
    height: 8px;
    border-style: solid;
    border-width: 0 2px 2px 0;
    border-color: currentColor;
}

/* Horizontal strip (swiper mode + arrows): left/right chevrons, buttons at
   the strip's vertical center, outside the thumbs on either edge. This is
   the default; the vertical mode below overrides it via the mode class
   already present on .product-gallery, so no extra shell modifier class
   is needed. */
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumbs-shell {
    padding-inline: calc(32px + .5rem);
}
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-prev,
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-next {
    display: flex;
}
/* Every rule below sets all FOUR inset-* logical properties explicitly.
   The base and vertical rulesets each only touch two of the four — the
   other two therefore keep whatever the OTHER ruleset set (properties,
   unlike shorthand values, don't get "reset" just because a
   higher-specificity rule left them alone), so without this a thumb
   button ends up with both a start AND an end value on the same axis
   at once. For an absolutely positioned box with an auto width/height
   that is over-constrained: the box stretches to span the distance
   between them instead of using its own width/height — this is what
   produced a 48x250 button. Explicit width/height above prevents the
   size from stretching either way, but the position rules are kept
   fully explicit too so there is no ambiguity to depend on. */
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-prev {
    inset-inline-start: 0;
    inset-inline-end: auto;
    inset-block-start: 50%;
    inset-block-end: auto;
    transform: translateY(-50%);
}
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-next {
    inset-inline-start: auto;
    inset-inline-end: 0;
    inset-block-start: 50%;
    inset-block-end: auto;
    transform: translateY(-50%);
}
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-prev::after {
    transform: rotate(135deg);
}
.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-next::after {
    transform: rotate(-45deg);
}

/* Vertical strip: up/down chevrons, buttons above and below the strip. */
.j2c-imagedisplay-vertical.j2c-imagedisplay-arrows .j2c-imagedisplay-thumbs-shell {
    padding-inline: 0;
    padding-block: calc(32px + .5rem);
}
.j2c-imagedisplay-vertical.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-prev {
    inset-inline-start: 50%;
    inset-inline-end: auto;
    inset-block-start: 0;
    inset-block-end: auto;
    transform: translateX(-50%);
}
.j2c-imagedisplay-vertical.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-next {
    inset-inline-start: 50%;
    inset-inline-end: auto;
    inset-block-start: auto;
    inset-block-end: 0;
    transform: translateX(-50%);
}
.j2c-imagedisplay-vertical.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-prev::after {
    transform: rotate(-135deg);
}
.j2c-imagedisplay-vertical.j2c-imagedisplay-arrows .j2c-imagedisplay-thumb-next::after {
    transform: rotate(45deg);
}

/* Reduced motion — best-effort (WCAG 2.3.3 is AAA, outside this plugin's AA
   target, but cheap to honour). Swiper writes transition-duration inline,
   so this is the one documented exception to the no-!important rule. */
@media (prefers-reduced-motion: reduce) {
    .j2c-imagedisplay .product-gallery-thumbs .swiper-slide {
        transition: none;
    }
    .j2c-imagedisplay .product-gallery-thumbs .swiper-wrapper {
        transition-duration: 0ms !important;
    }
}
