/* mouldshop-product-gallery.css — the PDP gallery: big image + full-width thumbnail row.
   TASK-0049, DEC-0026 rulings 34.1, 34.2, 35. Loaded via MouldshopHead.
   Tokens from mouldshop.css (--ms-*). Zero colour literals (M4 invariant 12). */

:root {
    /* 1:1. Operator ruling, 2026-09-10: product images are 1:1 everywhere — card, PDP
       and thumbs. The per-instance ImageAspectRatio field still wins over this; the
       default is aligned with the ruling so a NEW gallery is right without being set. */
    --ms-gallery-ratio: 100%;
    --ms-gallery-thumb-size: 88px;
    --ms-gallery-thumb-gap: 0.75rem;
    --ms-gallery-radius: 2px;
}

/* ---------------------------------------------------------------------------
   THE BIG IMAGE
   A <button>, so the reset matters: browsers give buttons a background, a
   border, a font and a text-align of their own, none of which belong here.
   --------------------------------------------------------------------------- */

.ms-gallery-main {
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--ms-rule);
    border-radius: var(--ms-gallery-radius);
    background: var(--ms-white);
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: zoom-in;
    overflow: hidden;
}

/* THE RATIO BOX, and it is padding-top rather than aspect-ratio on purpose.
   The vendor item type stores ratios as percentage strings — "75%" is 4:3 — and a
   percentage padding-top resolves against the element's own WIDTH, so the stored
   value is usable exactly as authored. `aspect-ratio` does not accept a percentage
   and would mean converting to a ratio pair in Razor, which is arithmetic in a
   template to avoid one line of CSS.

   It earns its place: the images on this box are 17 different intrinsic sizes, and
   without a reserved box the buy box beside it jumps on every thumbnail switch.
   Performance-first includes not shipping layout shift. */
.ms-gallery-main {
    position: relative;
}

.ms-gallery-main::before {
    content: "";
    display: block;
    padding-top: var(--ms-gallery-ratio);
}

.ms-gallery-main > img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: contain;
}

.ms-gallery-main:focus-visible {
    outline: 2px solid var(--ms-blue);
    outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   THE THUMBNAIL ROW — row 2, spanning the container (ruling 34.2)
   It sits in its own 1-column grid row, so it inherits the container ladder from
   [data-swift-container] and needs no width of its own. Setting a width here would
   put a second mechanism next to the ladder DEC-0014 ruling 13 already governs.
   --------------------------------------------------------------------------- */

.ms-gallery-thumbs {
    margin-block-start: var(--ms-gallery-thumb-gap);
}

.ms-gallery-thumbs-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ms-gallery-thumb-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ms-gallery-thumbs-item {
    margin: 0;
}

.ms-gallery-thumb {
    display: block;
    width: var(--ms-gallery-thumb-size);
    height: var(--ms-gallery-thumb-size);
    padding: 0;
    border: 1px solid var(--ms-rule);
    border-radius: var(--ms-gallery-radius);
    background: var(--ms-white);
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.15s linear;
}

.ms-gallery-thumb > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.ms-gallery-thumb:hover {
    border-color: var(--ms-navy-40);
}

.ms-gallery-thumb.is-active {
    border-color: var(--ms-ink);
}

.ms-gallery-thumb:focus-visible {
    outline: 2px solid var(--ms-blue);
    outline-offset: 2px;
}

/* Small screens: the row scrolls rather than wrapping to four tall rows of thumbs.
   This is the ONE horizontal scroller this component introduces, it is inside its own
   overflow container, and it is the sanctioned exception in CLAUDE.md's design
   principles (product sliders scroll; the PAGE never does). */
@media (max-width: 749px) {
    :root {
        --ms-gallery-thumb-size: 72px;
    }

    .ms-gallery-thumbs-list {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: thin;
        -webkit-overflow-scrolling: touch;
    }

    .ms-gallery-thumbs-item {
        flex: 0 0 auto;
    }
}

/* ---------------------------------------------------------------------------
   THE GAP BETWEEN THE FRAME AND THE THUMBNAIL ROW — 204px, and none of it was ours.

   MEASURED at 1440, frame bottom 901 to thumbnail row top 1105:
       96px  the two-column row's <section> padding-bottom   (GridRowBottomSpacing = 6)
     + 96px  the thumbnail row's <section> padding-top       (GridRowTopSpacing = null)
     + 12px  .ms-gallery-thumbs margin-top                   (ours)
     = 204px

   Both 96s are DW row spacing, not CSS we wrote: Swift-v2_Row.cshtml:8 emits
   `data-dw-row-space-top="@(Model.TopSpacing ?? 6)"` — so a row with spacing UNSET
   defaults to 6, which swift.css renders as 96px. The new thumbnail row had both
   unset, and the row above it carries an explicit bottom spacing of 6.

   A PREVIOUS WORKLOG ENTRY BLAMED 130px OF THIS ON THE 1:1 ASPECT RATIO. THAT WAS
   WRONG and the operator caught it: the ratio's letterboxing is INSIDE the bordered
   frame, and this 204px is measured from the frame's bottom border downward. The two
   are additive, not the same pixels. Ruling: product images are 1:1 everywhere —
   card, PDP, thumbs — and the ratio is not to be changed.

   WHY THIS IS FIXED IN CSS RATHER THAN BY TWO DROPDOWNS IN ADMIN. The thumbnail row
   is not an independent row that happens to sit below the image; it is half of one
   component that DW's grid forces into two rows (see Thumbnails.cshtml). The distance
   between them belongs to the component, the same way the gap between the thumbs
   does. Leaving it to a per-row admin setting means the gallery is only correct when
   somebody remembers to set two dropdowns — and ruling 37 is explicit that a
   Mouldshop component carries its own default styling.

   SCOPE IS THE SAFETY. `:has()` targets ONLY a section containing this component, so
   no other row on any page is touched. Specificity is (0,1,1) against swift.css's
   (0,1,0) attribute rule, which is why no !important is needed — verified by reading
   the computed padding back, not by assuming.

   THE COST, STATED: this overrides the row's admin spacing for these two rows. If a
   deliberate spacing is ever wanted there, it has to come out of here, not out of the
   Visual Editor. That is the trade for a component that is right by default.
   --------------------------------------------------------------------------- */

section:has(.ms-gallery) {
    padding-bottom: 0;
}

section:has(.ms-gallery-thumbs) {
    padding-top: 0;
}

/* The remaining distance is ours alone, declared once at the top of this file
   as .ms-gallery-thumbs { margin-block-start: var(--ms-gallery-thumb-gap) } = 12px. */

/* ---------------------------------------------------------------------------
   fsLightbox — the only rules we add to it, and they are restraint not styling.
   The Pro bundle ships its own complete UI (counter, arrows, zoom, slideshow,
   fullscreen, thumbnail strip). Restyling it would be a second design system on
   top of a finished one, so this sets nothing but the stacking context, which is
   the one thing it cannot know: the Mouldshop header is sticky and would
   otherwise paint over the viewer.
   --------------------------------------------------------------------------- */

.fslightbox-container {
    z-index: 2000;
}

@media (prefers-reduced-motion: reduce) {
    .ms-gallery-thumb {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   CARD MARKERS ON THE BIG IMAGE (operator, 2026-09-24: "add badges same position
   as in product card, and also PERCENTAGE"). The card partial renders them and
   mouldshop-card-markers.css places them: NEW / BESTSELLER top-left, -X% bottom-
   right, --ms-marker-inset from the edges - positioned against .ms-gallery, the
   same frame as the heart. The card's divider and 8px band are scoped to the card
   and do not reach here; the percentage sits on the plain 20px inset, which is
   where the card's lands too (8px + 12px band padding).
   The stock dot is not asked for on the PDP (the buy box and variant table carry
   stock): hidden here. Remove this rule to show it.
   --------------------------------------------------------------------------- */

.ms-gallery .ms-markers-slot--status {
    display: none;
}

/* The percentage on the PDP image is twice the card's (operator, 2026-09-24: "% twice as big"):
   2.2rem -> 4.4rem. PDP only; the card keeps 2.2rem. */
.ms-gallery .ms-badge--sale {
    font-size: 4.4rem;
}

/* STOCK ON THE IMAGE FOR A PRODUCT WITHOUT VARIANTS (operator, 2026-09-25: "if we dont have
   variants - we dont have information about stock - we need to add in the same place as in
   product card = bottom left of the image"). The rule above still hides it on a variant product,
   whose variant table carries stock per row. The gallery template sets the class from the buy
   box's own has-variants predicate. Same slot, same look, same bottom-left as the card. */
.ms-gallery--no-variants .ms-markers-slot--status {
    display: flex;
}
