/* Slider Carousel Slide - Frontend Styles
 * -----------------------------------------------------------
 * The slide block supports:
 *  - background image / colour / gradient + overlay
 *  - decorative orbit lines (slide 1 dark hero pattern)
 *  - eyebrow pill above heading (with optional icon)
 *  - heading with rich-text marks/highlights:
 *      <mark>            -> yellow gold pill highlight
 *      <mark class="hl-red">   -> red pill highlight (sale)
 *      <mark class="hl-green"> -> green pill highlight
 *  - subheading with optional <strong> emphasis
 *  - up to two CTAs with icon support and four style presets
 *      filled / dark / outline / ghost
 *  - inline promo-code chip next to the CTAs
 *  - corner badge top-right (pill or diagonal banner)
 *  - galaxy of circular category previews (split layout)
 *  - product card list (split layout)
 *  - lower-left footer info row (year badge + 2 text lines)
 * Defaults match the IMS-by-Soul-Country brand palette and
 * everything is colour/text/icon customisable per slide.
 * ---------------------------------------------------------- */

.ims-slide {
    --slide-heading-color: #fff;
    --slide-heading-highlight: var(--color-cta, #FAB000);
    --slide-subheading-color: rgba(255, 255, 255, 0.85);
    /* Distance from the slide's left/right edge to the centred 1400px
       content container. Backgrounds (bg image, overlay, orbit lines,
       decorative wedge) still extend full-bleed; absolutely-positioned
       chrome (corner badge, footer info) reads off this variable so it
       aligns with the inner content rather than hugging the viewport
       edges on wide screens. Falls to 0 on narrow viewports. */
    --slide-content-inset: max(0px, calc(50% - 700px));
    position: relative;
    overflow: hidden;
    display: flex;
    /* Inherit the carousel-level min-height (set via CSS variable on
       the .ims-slider-carousel wrapper) so each slide always fills
       the splide container vertically. This keeps the overlaid
       pagination dots sitting on the slide rather than in a white
       gap below it. The per-slide minHeight attribute, when set,
       overrides this via inline style. */
    min-height: var(--ims-slider-min-height, auto);
    width: 100%;
}

.ims-slide .slide-bg-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

.ims-slide .slide-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #000;
    z-index: 1;
}

/* ── Decorative orbit lines (slide 1 dark hero) ── */
.ims-slide .slide-orbit-lines {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    overflow: hidden;
}

.ims-slide .slide-orbit {
    position: absolute;
    border: 1.5px solid var(--orbit-line-color, rgba(255, 255, 255, 0.22));
    border-radius: 50%;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

/* Six scattered "orbit" circles — a mix of small (60-100px) and
   medium (160-300px) sizes sprinkled across the slide. A few are
   intentionally placed near the edges so they clip off-frame for
   variety. None overlap each other and they all sit below the
   foreground content (z-index 1 vs content's z-index 2+). */
.ims-slide .slide-orbit-1 { width: 70px;  height: 70px;  top: 28%; left: 28%; }  /* small dot, upper-left */
.ims-slide .slide-orbit-2 { width: 220px; height: 220px; top: 30%; left: 88%; }  /* medium, clips off right */
.ims-slide .slide-orbit-3 { width: 90px;  height: 90px;  top: 78%; left: 50%; }  /* small, lower-centre */
.ims-slide .slide-orbit-4 { width: 160px; height: 160px; top: 50%; left: 8%;  }  /* medium, clips off left */
.ims-slide .slide-orbit-5 { width: 60px;  height: 60px;  top: 88%; left: 78%; }  /* tiny, lower-right */
.ims-slide .slide-orbit-6 { width: 280px; height: 280px; top: 12%; left: 62%; }  /* larger, clips off top */

/* ── Decorative geometric shape (e.g. yellow wedge under footer)──
   Sits above the slide content (z-index 2 stacking sits below 3) so
   it can partly obscure the trailing edge of the subheading, but the
   footer / corner badge / CTAs (z-index 3+) read on top of it. */
.ims-slide .slide-decorative-shape {
    position: absolute;
    z-index: 2;
    pointer-events: none;
    background: var(--shape-color, #FAB000);
    display: block;
}

/* Wave-shaped wedge — the top edge is a smooth multi-segment cubic
   bezier curve, encoded as an SVG <path> inside an inline data: URI
   used as a CSS mask. No external assets and no polygon vertices —
   the curve is mathematically smooth at any zoom level.

   The path is monotonically descending (each successive y is greater
   than the last) so the curve always angles downwards from the left
   border to the bottom border, with the slope speeding up and slowing
   down along the way to give it a "wave" feel. The three-stop gold
   gradient (bright → main → dark) is applied as the element's
   background and shows through the mask. */
.ims-slide .slide-decorative-shape-wedge-bottom-left {
    bottom: 0;
    left: 0;
    width: 75%;
    height: 60%;
    background: linear-gradient(140deg,
        color-mix(in srgb, var(--shape-color, #FAB000) 55%, #FFFFFF) 0%,
        var(--shape-color, #FAB000) 45%,
        color-mix(in srgb, var(--shape-color, #FAB000) 60%, #000000) 100%);
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M0,17 C12,20 22,27 32,37 C42,49 52,63 62,75 C72,85 82,93 90,100 L0,100 Z' fill='black'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M0,17 C12,20 22,27 32,37 C42,49 52,63 62,75 C72,85 82,93 90,100 L0,100 Z' fill='black'/></svg>");
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
}

.ims-slide .slide-decorative-shape-wedge-bottom-right {
    bottom: 0;
    right: 0;
    width: 75%;
    height: 60%;
    background: linear-gradient(220deg,
        color-mix(in srgb, var(--shape-color, #FAB000) 55%, #FFFFFF) 0%,
        var(--shape-color, #FAB000) 45%,
        color-mix(in srgb, var(--shape-color, #FAB000) 60%, #000000) 100%);
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M100,17 C88,20 78,27 68,37 C58,49 48,63 38,75 C28,85 18,93 10,100 L100,100 Z' fill='black'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M100,17 C88,20 78,27 68,37 C58,49 48,63 38,75 C28,85 18,93 10,100 L100,100 Z' fill='black'/></svg>");
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
}

/* Fallback for browsers that don't support color-mix() — use the
   raw shape colour as a flat fill so the wedge still renders. */
@supports not (color: color-mix(in srgb, white, black)) {
    .ims-slide .slide-decorative-shape-wedge-bottom-left,
    .ims-slide .slide-decorative-shape-wedge-bottom-right {
        background: var(--shape-color, #FAB000);
    }
}

/* When the wedge is enabled, ensure the footer reads on top of it. */
.ims-slide:has(.slide-decorative-shape) .slide-footer-info { z-index: 4; }

/* ── Existing top-left badge (kept for backwards compat) ── */
.ims-slide .slide-badge {
    position: absolute;
    top: 1.5rem;
    left: 1.5rem;
    padding: 0.35rem 1rem;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #1a1a1a;
    border-radius: 999px;
    z-index: 3;
}

/* ── Corner badge top-right (pill / diagonal) ── */
.ims-slide .slide-corner-badge {
    position: absolute;
    top: 1.5rem;
    /* Constrained to the 1400px content container on wide screens via
       --slide-content-inset; falls to 1.5rem from the viewport edge on
       narrow screens. */
    right: calc(var(--slide-content-inset) + 1.5rem);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0.45rem 0.95rem;
}

.ims-slide .slide-corner-badge-pill {
    border-radius: 999px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.ims-slide .slide-corner-badge .slide-icon {
    width: 14px;
    height: 14px;
    display: inline-flex;
}

.ims-slide .slide-corner-badge .slide-icon svg {
    width: 100%;
    height: 100%;
}

.ims-slide .slide-corner-badge-diagonal {
    top: 24px;
    right: -56px;
    width: 220px;
    justify-content: center;
    transform: rotate(45deg);
    transform-origin: center;
    padding: 0.4rem 0;
    border-radius: 0;
    letter-spacing: 0.18em;
    font-size: 0.7rem;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

.ims-slide .slide-corner-badge-diagonal .slide-icon {
    display: none;
}

/* ── Slide inner shell ── */
.ims-slide .slide-inner {
    position: relative;
    z-index: 2;
    display: flex;
    width: 100%;
    max-width: 1400px;
    margin-left: auto;
    margin-right: auto;
    height: 100%;
    padding: 3.5rem 2rem 4rem;
    box-sizing: border-box;
}

.slide-layout-centered .slide-inner {
    justify-content: center;
    align-items: center;
}

.slide-layout-centered .slide-content {
    width: 100%;
}

.slide-inner.slide-split {
    gap: 2.5rem;
    align-items: center;
}

.slide-layout-split-left .slide-content,
.slide-layout-split-right .slide-content {
    flex: 1 1 50%;
    min-width: 0;
}

.slide-layout-split-left .slide-right,
.slide-layout-split-right .slide-right {
    flex: 1 1 50%;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.slide-foreground {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.slide-foreground img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 8px;
}

/* Vertical alignment */
.slide-valign-top .slide-inner    { align-items: flex-start; }
.slide-valign-center .slide-inner { align-items: center; }
.slide-valign-bottom .slide-inner { align-items: flex-end; }

/* Top image (logo / brand mark above heading) */
.slide-top-image { margin-bottom: 1.25rem; }
.slide-top-image img { height: auto; display: block; }
.slide-align-center .slide-top-image img { margin: 0 auto; }
.slide-align-right .slide-top-image img  { margin-left: auto; }

/* ── Eyebrow pill ── */
.slide-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    line-height: 1;
    margin: 0 0 1.25rem;
    background-color: #1C1C1C;
    color: #fff;
}

.slide-align-center .slide-eyebrow { margin-left: auto; margin-right: auto; }
.slide-align-right  .slide-eyebrow { margin-left: auto; }

.slide-eyebrow .slide-icon {
    width: 12px;
    height: 12px;
    color: var(--eyebrow-accent, var(--color-cta, #FAB000));
    display: inline-flex;
    flex-shrink: 0;
}

.slide-eyebrow .slide-icon svg { width: 100%; height: 100%; }

/* "● JUST ADDED · 24 NEW PRODUCTS" — green pill variant uses bg colour
   but we also want a subtle inner separator dot. */
.slide-eyebrow-label {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
}

/* ── Heading ── */
.slide-heading {
    font-size: clamp(1.75rem, 4.2vw, 3.25rem);
    font-weight: 800;
    color: var(--slide-heading-color, #fff);
    margin: 0 0 0.85rem 0;
    line-height: 1.1;
    letter-spacing: -0.01em;
}

/* RichText "Highlight" mark = yellow gold word colour (slide 1 style). */
.slide-heading mark {
    background: transparent;
    color: var(--slide-heading-highlight, #FAB000);
    padding: 0;
}

/* hl-pill-red = the red rounded-corner block on slide 2 ("25% OFF"). */
.slide-heading mark.hl-red,
.slide-heading .hl-red {
    background-color: #DC2626;
    color: #fff;
    padding: 0.05em 0.35em;
    border-radius: 8px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

.slide-heading mark.hl-green,
.slide-heading .hl-green {
    background-color: #16A34A;
    color: #fff;
    padding: 0.05em 0.35em;
    border-radius: 8px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

.slide-heading mark.hl-yellow,
.slide-heading .hl-yellow {
    background-color: #FDE280;
    color: #1a1a1a;
    padding: 0.05em 0.35em;
    border-radius: 8px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

/* hl-underline = thick highlighter-pen band behind the word
   (slide 3 cream style). Spans roughly the lower 60% of cap height
   so it reads as a true highlighter mark, not a thin underline. */
.slide-heading .hl-underline {
    background-image: linear-gradient(transparent 28%, #C7E6C9 28%, #C7E6C9 92%, transparent 92%);
    background-repeat: no-repeat;
    background-size: 100% 100%;
    padding: 0 0.15em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

/* ── Subheading ── */
.slide-subheading {
    font-size: clamp(0.95rem, 1.35vw, 1.1rem);
    color: var(--slide-subheading-color, rgba(255, 255, 255, 0.85));
    margin: 0 0 1.75rem 0;
    line-height: 1.55;
    max-width: 36rem;
}

.slide-align-center .slide-subheading { margin-left: auto; margin-right: auto; }
.slide-align-right  .slide-subheading { margin-left: auto; }

.slide-subheading strong { color: inherit; font-weight: 700; }

/* ── CTA buttons ── */
.slide-ctas {
    display: flex;
    gap: 0.85rem;
    flex-wrap: wrap;
    align-items: center;
}

.slide-align-center .slide-ctas { justify-content: center; }
.slide-align-right  .slide-ctas { justify-content: flex-end; }

.slide-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.85rem 1.5rem;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    border-radius: 8px;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, color 0.15s ease;
    cursor: pointer;
    border: 2px solid transparent;
    line-height: 1;
}

.slide-cta:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}

.slide-cta .slide-icon {
    width: 16px;
    height: 16px;
    display: inline-flex;
    flex-shrink: 0;
}

.slide-cta .slide-icon svg { width: 100%; height: 100%; }

/* CTA style presets */
.slide-cta-style-filled {
    background-color: var(--color-cta, #FAB000);
    color: #1a1a1a;
}

.slide-cta-style-filled:hover {
    background-color: var(--color-cta-hover, #E09E00);
    color: #1a1a1a;
}

.slide-cta-style-dark {
    background-color: #111;
    color: #fff;
}

.slide-cta-style-dark:hover {
    background-color: #000;
    color: #fff;
}

/* Outline derives from the heading colour so it adapts to any
   background unless the author overrides via secondCtaColor / secondCtaTextColor. */
.slide-cta-style-outline {
    background-color: transparent;
    color: var(--slide-heading-color, #fff);
    border-color: color-mix(in srgb, var(--slide-heading-color, #fff) 28%, transparent);
}

.slide-cta-style-outline:hover {
    border-color: var(--slide-heading-color, #fff);
}

.slide-cta-style-ghost {
    background-color: transparent;
    color: inherit;
    padding-left: 0.4rem;
    padding-right: 0.4rem;
    border-color: transparent;
}

.slide-cta-style-ghost:hover {
    transform: translateX(2px);
    box-shadow: none;
}

/* Older browsers without color-mix() — fall back to a plain rgba border. */
@supports not (color: color-mix(in srgb, white, black)) {
    .slide-cta-style-outline { border-color: rgba(0, 0, 0, 0.25); }
}

/* Backwards compat: original .slide-cta-primary / .slide-cta-secondary
   defaults still apply when no explicit style class is present. */
.slide-cta-primary:not([class*="slide-cta-style-"]) {
    background: var(--color-cta);
    color: #1a1a1a;
}

.slide-cta-secondary:not([class*="slide-cta-style-"]) {
    background: transparent;
    color: #fff;
    border: 2px solid rgba(255, 255, 255, 0.6);
}

/* ── Inline promo code chip (CODE: SPRING25) ── */
.slide-promo-code {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    padding-left: 0.25rem;
    color: rgba(0, 0, 0, 0.7);
}

.slide-promo-code-label { opacity: 0.65; font-weight: 600; }
.slide-promo-code-value { font-weight: 800; }

/* ── Footer info row (lower-left of slide) ── */
.slide-footer-info {
    position: absolute;
    z-index: 3;
    /* Aligns with the left edge of the 1400px content container so the
       year badge / phone / domain sit underneath the heading column on
       wide screens, rather than hard against the viewport edge. Both
       top corners are rounded so the bar reads as a floating chip when
       there's empty space to its left. */
    left: var(--slide-content-inset);
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 2rem;
    border-top-left-radius: 14px;
    border-top-right-radius: 14px;
    background-color: rgba(255, 255, 255, 0.94);
    color: #111;
}

.slide-footer-year {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    font-size: 0.82rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    flex-shrink: 0;
}

.slide-footer-text {
    display: inline-flex;
    flex-direction: column;
    line-height: 1.15;
}

.slide-footer-line-1 {
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: 0.02em;
}

.slide-footer-line-2 {
    font-size: 0.85rem;
    font-weight: 500;
    opacity: 0.65;
    margin-top: 2px;
}

/* ── Right side: galaxy of circular category previews ──
   Five circles arranged in a 2-1-2 diamond (galaxy) pattern:
       [1]       [2]
            [3]
       [4]       [5]
   Implemented with a 4-column / 3-row grid where pairs span two
   columns each so the circles align in the visual half-positions.
   Each circle has a subtle vertical offset to give the
   constellation an organic, hand-placed feel. */
.slide-circle-galaxy {
    position: relative;
    width: 100%;
    min-height: 420px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: auto auto auto;
    gap: 0.6rem 0.5rem;
    align-items: center;
    justify-items: center;
    padding: 1rem 0.5rem;
}

.slide-circle-galaxy .slide-galaxy-pos-1 { grid-column: 1 / span 2; grid-row: 1; transform: translateY(0.75rem); }
.slide-circle-galaxy .slide-galaxy-pos-2 { grid-column: 3 / span 2; grid-row: 1; transform: translateY(-0.5rem); }
.slide-circle-galaxy .slide-galaxy-pos-3 { grid-column: 2 / span 2; grid-row: 2; transform: translateY(-0.25rem); }
.slide-circle-galaxy .slide-galaxy-pos-4 { grid-column: 1 / span 2; grid-row: 3; transform: translateY(-0.25rem); }
.slide-circle-galaxy .slide-galaxy-pos-5 { grid-column: 3 / span 2; grid-row: 3; transform: translateY(0.5rem); }

.slide-circle-galaxy-row .slide-galaxy-item { transform: none !important; }
.slide-circle-galaxy-row {
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: 1fr;
}

.slide-galaxy-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-decoration: none;
    color: inherit;
    transition: transform 0.3s ease;
}

.slide-galaxy-item-linked:hover { transform: translateY(-2px) scale(1.02); }

.slide-galaxy-image {
    width: clamp(110px, 12vw, 165px);
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    background-color: #fff;
    border: 2px solid var(--color-cta, #FAB000);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    /* faint diagonal stripe pattern matches the design when no image set */
    background-image: repeating-linear-gradient(
        135deg,
        rgba(0, 0, 0, 0.06) 0,
        rgba(0, 0, 0, 0.06) 1px,
        transparent 1px,
        transparent 8px
    );
}

.slide-galaxy-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.slide-galaxy-image-empty { background-color: #f3f4f6; }

/* Bracket label rendered inside the circle as a fallback when no
   image is uploaded. */
.slide-galaxy-label {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--grid-item-font-size, 0.78rem);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #1a1a1a;
    text-align: center;
    white-space: normal;
    padding: 0 0.6rem;
    line-height: 1.2;
    pointer-events: none;
}

.slide-galaxy-item { position: relative; }

/* Soft pastel background tints rotated through the 5 circles to match
   the dark hero design — cream / pink / blue / cream / green. */
.slide-galaxy-pos-1 .slide-galaxy-image-empty { background-color: #F5E7C5; }
.slide-galaxy-pos-2 .slide-galaxy-image-empty { background-color: #F3DEDB; }
.slide-galaxy-pos-3 .slide-galaxy-image-empty { background-color: #DCE7EE; }
.slide-galaxy-pos-4 .slide-galaxy-image-empty { background-color: #F2E8C8; }
.slide-galaxy-pos-5 .slide-galaxy-image-empty { background-color: #DCE8D4; }

/* Varied circle sizes — the centre circle (pos-3) is the largest as the
   visual anchor of the diamond, the surrounding four vary in size so the
   constellation feels organic rather than rigidly grid-like. Values use
   clamp() so they scale with the viewport. */
.slide-circle-galaxy .slide-galaxy-pos-1 .slide-galaxy-image { width: clamp(115px, 13vw, 170px); }
.slide-circle-galaxy .slide-galaxy-pos-2 .slide-galaxy-image { width: clamp(95px,  10.5vw, 140px); }
.slide-circle-galaxy .slide-galaxy-pos-3 .slide-galaxy-image { width: clamp(135px, 15vw,   195px); }
.slide-circle-galaxy .slide-galaxy-pos-4 .slide-galaxy-image { width: clamp(85px,  9.5vw,  125px); }
.slide-circle-galaxy .slide-galaxy-pos-5 .slide-galaxy-image { width: clamp(110px, 12.5vw, 160px); }

/* When an actual image is present, hide the diagonal stripe pattern. */
.slide-galaxy-image:not(.slide-galaxy-image-empty) {
    background-image: none;
    background-color: #fff;
}

/* ── Right side: product cards (slides 2 + 3) ── */
.slide-product-cards {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    /* stretch cells so every card in a row resolves to the same height,
       even when product names wrap to different line counts. */
    align-items: stretch;
}

/* Slide 3 uses 4 cards in a 2x2 grid. Generous gaps stop adjacent
   cards from visually merging when the static (non-scrolling)
   layout is in use. */
.slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: minmax(0, auto);
    gap: 1.5rem 2.25rem;
}

.slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-2,
.slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-3 {
    transform: translateY(1.25rem);
}

/* ── Rotating-groups layout (productCardsRotate = true) ─────────
   The block server-renders N cards split into groups of
   `productCardsPerView` (3 by default), each wrapped in a
   `.slide-product-cards-group` layer. All groups stack on top of
   one another via a single CSS-grid cell so the parent container
   sizes itself to the largest group with no positioning hacks.
   The frontend script swaps which layer holds `.is-active`, and
   CSS handles the cross-fade. */
.slide-product-cards.slide-product-cards-rotating {
    /* Override the flat 3-column grid from the base
       `.slide-product-cards` rule — now there is just one stacked
       cell that every group inhabits, so each group's own grid
       takes over the row layout. */
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "stack";
    /* Stagger transforms inside each group push card-2 ~2.5rem
       down, so the visual row extends beyond the group's intrinsic
       bounding box. Match that on the rotating wrapper too so the
       cards aren't clipped against any flexbox-imposed height. */
    overflow: visible;
}

.slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group {
    grid-area: stack;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    align-items: stretch;
    opacity: 0;
    transition: opacity 0.6s ease;
    /* While inactive a group must not steal pointer events from the
       active layer underneath it (fully overlapped via grid stack). */
    pointer-events: none;
}

.slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group.is-active {
    opacity: 1;
    pointer-events: auto;
}

/* Stagger inside each rotating group — same rhythm as the static
   3-card layout, but scoped to each group so a fresh group's cards
   1/2/3 also stagger. The base flat-layout rules below this block
   already use `:not(:has(.slide-product-card-4))`, which evaluates
   true for the rotating parent (no card-4 anywhere), so they apply
   to every group's cards too — no extra rules needed here. */

/* Visitors who've opted out of motion at the OS level get a static
   first group with no fade. The other groups stay hidden so screen
   readers don't surface duplicate product cards. */
@media (prefers-reduced-motion: reduce) {
    .slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group {
        transition: none;
    }
    .slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group:not(.is-active) {
        display: none;
    }
}

/* ── Continuous-scroll layout (productCardsScroll = true) ────────
   Two side-by-side columns, each with a duplicated track that is
   animated from `translateY(0)` to `translateY(-50%)`. Because the
   duplicated half is identical to the original half, the loop
   appears infinite and seamless. The right column reuses the same
   keyframes but starts at -50%, so it scrolls in the opposite
   visual direction. Hover pauses the track so visitors can click. */
.slide-product-cards.slide-product-cards-scrolling {
    /* Override the flat-grid layout from `.slide-product-cards`. */
    display: flex;
    grid-template-columns: none;
    align-items: stretch;
    gap: 0 3rem;
    width: 100%;
    height: 100%;
    min-height: 420px;
    overflow: hidden;
    /* Soft fade at the top and bottom of each column so cards don't
       pop in/out at hard edges as the marquee wraps around. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 7%, #000 93%, transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.slide-product-cards.slide-product-cards-scrolling .slide-product-cards-column {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
}

.slide-product-cards.slide-product-cards-scrolling .slide-product-cards-track {
    display: flex;
    flex-direction: column;
    /* Using margin-block-end (vs `gap`) on every direct child means
       the duplicated half has the same trailing margin as the
       original — so a `translateY(-50%)` lands exactly back on the
       first card, with no half-gap drift after each loop. */
    will-change: transform;
}

/* Target every card in the track regardless of nesting depth — the
   `.slide-product-cards-clone` wrapper uses `display: contents`, so
   its children are layout-direct children of the track but they are
   *not* DOM-direct children of it. A `> *` selector therefore skips
   the cloned half and leaves every cloned card without the trailing
   margin, producing the asymmetric "first half spaced, second half
   crammed" gap pattern seen in the live marquee. Selecting the card
   class itself avoids that pitfall. */
.slide-product-cards.slide-product-cards-scrolling .slide-product-cards-track .slide-product-card {
    margin-block-end: 2rem;
}

/* `display: contents` on the cloned wrapper means the wrapper itself
   takes no layout space — its children sit directly in the track's
   flex column, exactly as if they had been written inline. */
.slide-product-cards.slide-product-cards-scrolling .slide-product-cards-clone {
    display: contents;
}

.slide-product-cards.slide-product-cards-scrolling
    .slide-product-cards-column-left .slide-product-cards-track {
    animation: ims-slide-cards-marquee 28s linear infinite;
}

.slide-product-cards.slide-product-cards-scrolling
    .slide-product-cards-column-right .slide-product-cards-track {
    animation: ims-slide-cards-marquee 28s linear infinite reverse;
}

@keyframes ims-slide-cards-marquee {
    from { transform: translateY(0); }
    to   { transform: translateY(-50%); }
}

/* Pause both column tracks together when the user hovers anywhere
   over the scrolling area — using `:hover` on a single column
   would cause one column to keep moving while the other is paused,
   which looks broken. */
.slide-product-cards.slide-product-cards-scrolling:hover
    .slide-product-cards-track {
    animation-play-state: paused;
}

/* Cancel the marquee for visitors who've opted out of motion at the
   OS level. The cloned half is hidden so screen-stack readers don't
   meet duplicate cards, and the track scrolls naturally if it
   overflows. */
@media (prefers-reduced-motion: reduce) {
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-track {
        animation: none;
    }
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-clone {
        display: none;
    }
}

/* Below tablet width the slide stacks vertically and neither the
   rotating cross-fade nor the continuous-scroll marquee earn their
   keep — the visitor can see the whole hero at once, and unsolicited
   motion just adds noise while making slide 2/3 push the rest of
   the page far below the fold. We collapse both modes to a single
   static 2-column grid that matches the rest of the slide's mobile
   rhythm, drop the animations, and (on phones, see the 768px block
   further down) cap how many cards stay visible. */
@media (max-width: 1024px) {
    /* Rotating ─ show only the first group, in a static 2-col grid.
       The other groups (and their cards) leave the layout entirely so
       slide height collapses to one row of cards. The `is-active`
       class still toggles in the DOM as the JS rotator ticks but on
       mobile we override visibility from CSS, so nothing moves. */
    .slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group:not(:first-child) {
        display: none !important;
    }
    .slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group:first-child {
        opacity: 1 !important;
        transition: none;
        grid-template-columns: repeat(2, 1fr);
    }

    /* Scrolling ─ flatten the two-column marquee into one 2-col grid.
       Both the column and the track wrappers fold flat via
       `display: contents`, so the cards become direct grid items.
       Using `grid-auto-flow: column` keeps source order: cards 1, 3,
       5 fall into column 1 (DOM-order children of the left track),
       and cards 2, 4, 6 into column 2 (right track) — visually they
       read row-by-row as 1,2 / 3,4 / 5,6. */
    .slide-product-cards.slide-product-cards-scrolling {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-auto-flow: column;
        grid-auto-rows: max-content;
        gap: 0.75rem !important;
        flex-direction: unset;
        height: auto;
        min-height: 0;
        overflow: visible;
        -webkit-mask-image: none;
                mask-image: none;
    }
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-column,
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-track {
        display: contents;
    }
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-clone {
        display: none;
    }
    .slide-product-cards.slide-product-cards-scrolling .slide-product-cards-track .slide-product-card {
        margin-block-end: 0;
        animation: none;
    }
}

/* 3-card row stagger — give the spring-savings cards a hand-laid
   rhythm rather than a flat row of identical tops. Heights stay equal
   (see `.slide-product-cards { align-items: stretch }` and `.slide-
   product-card { height: 100% }`); only each card's translateY offset
   differs per column position so the row reads as visually jumbled. */
.slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-1 {
    transform: translateY(0.4rem);
}
.slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-2 {
    transform: translateY(2.5rem);
}
.slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-3 {
    transform: translateY(1.2rem);
}

.slide-product-card {
    background-color: #fff;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
    color: #111;
    text-decoration: none;
    display: flex;
    flex-direction: column;
    /* fill the stretched grid cell so card heights match across the row. */
    height: 100%;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.slide-product-card-linked {
    /* Splide paints `cursor: grab` on its `.splide__track` when drag
       is enabled — that cursor would otherwise win for hovers over
       linked cards inside the slide. Forcing pointer here keeps the
       affordance correct regardless of slider drag state. */
    cursor: pointer;
}

.slide-product-card-linked:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 26px rgba(0, 0, 0, 0.12);
}

.slide-product-card-media {
    position: relative;
    aspect-ratio: 4 / 3;
    /* inset breathing room so product photos don't bleed all the way
       to the card edge — the absolutely-positioned SALE badge still
       hugs the outer corner because absolute positioning ignores the
       padding box. */
    padding: 0.6rem;
    background-color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

/* Bring back the diagonal-stripe texture only when there's no real
   product image — i.e. for placeholder/empty cards in the editor and
   on slides where authors haven't picked a thumbnail yet. */
.slide-product-card-media:has(.slide-product-card-placeholder) {
    background-color: #f3f4f6;
    background-image: repeating-linear-gradient(
        135deg,
        rgba(0, 0, 0, 0.05) 0,
        rgba(0, 0, 0, 0.05) 1px,
        transparent 1px,
        transparent 8px
    );
}

.slide-product-card-media img {
    width: 100%;
    height: 100%;
    /* contain so the full product is visible inside the padded media
       box (no edge-cropping on irregular product shapes). */
    object-fit: contain;
    display: block;
}

.slide-product-card-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.slide-product-card-placeholder-label {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #4b5563;
}

.slide-product-card-badge {
    position: absolute;
    top: 0;
    right: 0;
    padding: 0.25rem 0.55rem;
    font-size: 0.78rem;
    font-weight: 800;
    border-bottom-left-radius: 6px;
    line-height: 1;
}

.slide-product-card-body {
    padding: 0.75rem 0.85rem 0.95rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    /* claim the remaining vertical space below the media so prices can
       anchor to the card's bottom edge (margin-top:auto on .prices). */
    flex: 1 1 auto;
}

.slide-product-card-pn {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #6b7280;
}

.slide-product-card-name {
    font-size: 0.95rem;
    font-weight: 700;
    color: #111;
    line-height: 1.25;
    margin-top: 0.15rem;
}

.slide-product-card-prices {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    /* push to bottom of body so prices align across cards even when
       product names wrap to different line counts. */
    margin-top: auto;
    padding-top: 0.4rem;
}

.slide-product-card-price {
    font-size: 1.05rem;
    font-weight: 800;
    color: #DC2626;
}

.slide-product-card-orig {
    font-size: 0.85rem;
    color: #9ca3af;
    text-decoration: line-through;
}

/* When no discount badge exists the price should not be red. */
.slide-product-card:not(:has(.slide-product-card-badge)) .slide-product-card-price {
    color: #111;
}

/* ── Light-background helper class (auto-detected via gradient toggle) ──
   Authors can also add ".slide-on-light" via the editor by using a light
   background. We auto-apply it when the slide background is bright. */
.slide-on-light {
    --slide-heading-color: #111;
    --slide-subheading-color: #4b5563;
}

.slide-on-light .slide-heading mark { color: var(--slide-heading-highlight, #DC2626); }
.slide-on-light .slide-subheading strong { color: #111; }

/* ── Existing grid layout (unchanged) ── */
.slide-layout-grid .slide-grid-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 1400px;
    margin: 0 auto;
    padding: 2.5rem 2rem;
    box-sizing: border-box;
    position: relative;
    z-index: 2;
    height: 100%;
}

.slide-grid-heading {
    font-family: Helvetica, Arial, sans-serif;
    font-size: clamp(1.5625rem, 3.75vw, 2.5rem);
    font-weight: 800;
    color: #1a1a1a;
    text-align: center;
    margin: 0 0 2rem 0;
    line-height: 1.3;
}

.slide-grid-highlight {
    background-color: #FDE280;
    color: #1a1a1a;
    padding: 0.1em 0.4em;
    border-radius: 6px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

.slide-grid-columns {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem;
    width: 90%;
}

.slide-grid-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    text-decoration: none;
    color: inherit;
}

a.slide-grid-item-linked { text-decoration: none; color: inherit; cursor: pointer; }
a.slide-grid-item-linked:hover .slide-grid-item-image { border-color: #FAB000; }
a.slide-grid-item-linked:hover .slide-grid-item-image img { transform: scale(1.05); }
a.slide-grid-item-linked:hover .slide-grid-item-heading span {
    background-color: #FAB000;
    color: #1a1a1a;
}

.slide-grid-item-image {
    width: 100%;
    max-width: 270px;
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    margin-bottom: 1rem;
    background: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    border: 3px solid transparent;
    transition: border-color 0.25s ease;
}

.slide-grid-item-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.slide-grid-item-heading {
    font-family: Helvetica, Arial, sans-serif;
    font-size: var(--grid-item-font-size, 1.4375rem);
    font-weight: 500;
    color: #1a1a1a;
    text-align: center;
    margin: 0;
    line-height: 1.2;
}

.slide-grid-item-heading span {
    padding: 0.15em 0.4em;
    border-radius: 6px;
    background-color: transparent;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    transition: background-color 0.4s ease, color 0.4s ease;
}

/* ── Responsive ── */
@media (max-width: 1024px) {
    .slide-circle-galaxy {
        min-height: 320px;
    }

    .slide-product-cards {
        grid-template-columns: repeat(2, 1fr);
    }

    .slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-1,
    .slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-2,
    .slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-3,
    .slide-product-cards:not(.slide-product-cards-scrolling):has(.slide-product-card-4) .slide-product-card-4,
    .slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-1,
    .slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-2,
    .slide-product-cards:not(:has(.slide-product-card-4)) .slide-product-card-3 {
        transform: none;
        animation: none;
    }
}

@media (max-width: 768px) {
    /* .ims-slide is a flex row by default. On mobile the footer info
       bar switches from `position: absolute` to `position: relative`
       (rule below), which makes it a second in-flow flex item next to
       .slide-inner — and they end up sharing the row width. Flipping
       the parent to column-direction lets them stack vertically so
       each row spans the full slide width. */
    .ims-slide {
        flex-direction: column;
    }

    .ims-slide .slide-inner.slide-split {
        flex-direction: column;
        /* Stretch (default) ensures stacked columns take the full slide
           width rather than being horizontally centred mid-slide, which
           is what the desktop `align-items: center` would inherit. */
        align-items: stretch;
        gap: 1.75rem;
    }

    .slide-layout-split-right .slide-right { order: 2; }
    .slide-layout-split-left  .slide-right { order: 2; }

    .ims-slide .slide-inner {
        padding: 2.5rem 1.25rem 3rem;
        /* Don't try to fill 100% of the slide's height on mobile —
           that would starve the footer info bar of vertical space
           when it joins the column flow below. */
        height: auto;
    }

    /* Force the stacked content / galaxy columns to span the full
       available slide width on mobile. Two overrides happen here:
        1. Reset the `flex: 1 1 50%` basis (which constrains width on
           desktop via `align-items: center` + a 50% basis), and
        2. Override the inline `max-width` rendered from the per-slide
           contentMaxWidth attribute (e.g. 560px). The !important is
           required to beat that inline style. */
    .ims-slide .slide-inner.slide-split > .slide-content,
    .ims-slide .slide-inner.slide-split > .slide-right {
        flex: 0 0 auto !important;
        width: 100% !important;
        max-width: none !important;
    }

    /* Decorative wedge spans the full slide on mobile, with a slightly
       shorter height proportion. The mask path is redrawn for the new
       wider aspect ratio so the wave still angles smoothly downwards
       from the top-left edge to the bottom-right corner instead of
       ending at 90% width like on desktop. */
    .ims-slide .slide-decorative-shape-wedge-bottom-left,
    .ims-slide .slide-decorative-shape-wedge-bottom-right {
        width: 100%;
        height: 48%;
    }

    .ims-slide .slide-decorative-shape-wedge-bottom-left {
        -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M0,18 C14,21 26,29 38,40 C50,52 60,65 72,77 C82,87 92,94 100,100 L0,100 Z' fill='black'/></svg>");
                mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M0,18 C14,21 26,29 38,40 C50,52 60,65 72,77 C82,87 92,94 100,100 L0,100 Z' fill='black'/></svg>");
    }

    .ims-slide .slide-decorative-shape-wedge-bottom-right {
        -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M100,18 C86,21 74,29 62,40 C50,52 40,65 28,77 C18,87 8,94 0,100 L100,100 Z' fill='black'/></svg>");
                mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M100,18 C86,21 74,29 62,40 C50,52 40,65 28,77 C18,87 8,94 0,100 L100,100 Z' fill='black'/></svg>");
    }

    .slide-badge,
    .slide-corner-badge { top: 1rem; }
    .slide-badge { left: 1rem; }
    .slide-corner-badge:not(.slide-corner-badge-diagonal) { right: 1rem; }

    .slide-corner-badge-diagonal {
        padding: 0.4rem 3rem;
        font-size: 0.65rem;
    }

    .slide-grid-columns {
        grid-template-columns: repeat(2, 1fr);
        gap: 1.25rem;
    }

    .slide-grid-item-image { max-width: 200px; }

    .slide-layout-grid .slide-grid-inner { padding: 1.5rem 1rem; }

    .slide-circle-galaxy {
        grid-template-columns: repeat(3, 1fr);
        min-height: auto;
    }

    .slide-circle-galaxy .slide-galaxy-pos-4,
    .slide-circle-galaxy .slide-galaxy-pos-5 { transform: none; justify-self: center; }

    .slide-product-cards {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }

    /* Cap visible cards on phones so neither slide 2 (rotating) nor
       slide 3 (scrolling) can stretch into a wall of products that
       pushes the rest of the page far below the fold.

       Scrolling: cards 1/3/5 live in the left track, 2/4/6 in the
       right track; hiding nth-of-type(n+3) inside each track drops
       cards 5 and 6, leaving a tidy 2x2 grid of the first 4.

       Rotating: only the first group is visible on mobile (see the
       1024px block above). If an author has set "cards per view"
       higher than 4 we still cap at 4 here so the same 2x2 rhythm
       is preserved. */
    .slide-product-cards.slide-product-cards-scrolling
        .slide-product-cards-track > .slide-product-card:nth-of-type(n+3) {
        display: none;
    }
    .slide-product-cards.slide-product-cards-rotating
        > .slide-product-cards-group:first-child
        > .slide-product-card:nth-of-type(n+5) {
        display: none;
    }

    /* Sale slide on mobile loads 9 products but only 3 (or fewer)
       end up visible — make those cards comfortably tappable rather
       than crammed into the 2-up grid leftover from desktop staging. */
    .slide-product-cards.slide-product-cards-rotating > .slide-product-cards-group:first-child {
        gap: 0.75rem;
    }

    .slide-footer-info {
        position: relative;
        margin-top: 1.5rem;
        border-radius: 0;
    }
}

@media (max-width: 480px) {
    .slide-grid-columns { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
    .slide-grid-item-image { max-width: 130px; }
    .slide-grid-heading { font-size: 1.375rem; margin-bottom: 1.25rem; }

    .slide-product-cards { grid-template-columns: repeat(2, 1fr); }

    .slide-circle-galaxy {
        gap: 0.75rem;
    }

    .slide-galaxy-image { width: 100px; }
}
