/* AEKE .sg — slideshow section (the home hero, and the banner slideshows below it).
 *
 * A port of the theme's own `slideshow.css`, reduced to the parts our markup uses.
 * Declarations are kept as the theme writes them; only the values are re-pointed at
 * tokens in `tokens.css`.
 *
 * MEASURED AGAINST THE LIVE SITE (1440px viewport, 1425px of page):
 *   hero height 482px  ·  row starts 70px below the header row  ·  arrows 42x42,
 *   flush to the right edge, 20px above the bottom, 8px apart  ·  content panel
 *   max-width 640px (medium) / 780px (large), padding 50px  ·  heading 34/42 weight
 *   600, margin-bottom 20px  ·  description 17/27.2  ·  CTA 15px, weight 500.
 *
 * TWO THINGS THE THEME DOES THAT THIS DOES NOT.
 *
 * 1. The theme's `--color-slidebg-blur` is read by a rule that asks for
 *    `var(--bg-blur)`. The name does not exist, the declaration is therefore
 *    invalid, and the content panel's backdrop blur has never rendered. The rule
 *    here reads the correct variable, so the feature works if a slide ever asks for
 *    it; today no slide does (every slide sets opacity 0), so nothing looks
 *    different either way.
 *
 * 2. Non-current slides are marked `inert` (see the section template). Upstream
 *    hides them with `opacity: 0` and `pointer-events: none` only, which stops the
 *    mouse but leaves three invisible slides' links in the tab order — a keyboard
 *    user tabs through "Shop Now" four times and sees nothing move.
 */

.slideshow {
  display: flex;
  position: relative;
  overflow: hidden;
  background: rgba(var(--color-body-rgb), 0.03);
}

/* The slide is absolutely positioned and stacked, so the fades overlap instead of
   pushing each other sideways. The FIRST slide stays in normal flow: it is what
   gives the container its height, and it is upstream's own arrangement (the theme
   ships exactly this pair of rules for the moment before its carousel script runs).
 *
 * Sizing from one slide rather than from the tallest matters. In a flex row every
 * slide stretches to the tallest, so adding a slide with a marginally wider image
 * would silently make the whole hero taller. Here the height is one slide's ratio,
 * and every other slide is given that height whether or not its own artwork agrees.
 * ("Tallest" is not the same as "all the same", and the two are easy to conflate:
 * a flex row makes its children equal to the tallest child, which is only equal to
 * each other child if every child already was.) */
.slideshow__slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  background: rgba(var(--color-body-rgb), 0.03);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade-duration) var(--ease-theme),
              visibility var(--fade-duration) var(--ease-theme);
}

.slideshow__slide:first-child {
  position: relative;
  height: auto;
}

/* The live site switches slides with a ~650ms ease-out crossfade: measured at 52ms
   the incoming slide is at 0.12, at 470ms at 0.95, and it settles near 650ms. 0.7s
   on the theme's own easing curve reproduces that. */
.slideshow__slide.is-current {
  opacity: 1;
  visibility: visible;
  z-index: 1;
}

/* ------------------------------------------------------------------- the image */
/* A hidden copy of the image, in normal flow, whose intrinsic ratio gives the slide
   its height. That is why the hero is 482px and not a fixed 100vh: the height is a
   property of the artwork rather than a number somebody has to re-tune per
   breakpoint. It only decides anything on the FIRST slide; on the other three it is
   just a copy that happens to be 1.4% too tall, which is what the clip below is for. */
.slideshow__slide-adapt-to-image {
  width: 100%;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Only the geometry. Deliberately NO `display` here: this selector is more specific
   than `.slideshow-image--mobile`, so setting `display: block` would override the
   breakpoint switch and leave BOTH images in flow — the portrait one then drives the
   height and the hero measured 2547px tall at 1440 wide instead of 488.
   `img { display: block }` already comes from the base layer. */
.slideshow__slide-adapt-to-image img {
  width: 100%;
  height: auto;
}

.slideshow__slide-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.slideshow__slide-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* `height: image` — the hero is as tall as its artwork, not as tall as the viewport.

   The first slide decides how tall, because it is the only one in flow. Every other
   slide is stacked on top of it and takes `height: 100%`, so all four are the same
   height whichever one is showing. The clip is the second half of that promise: the
   hidden ratio-setting copy in the slides that are not first is 7px taller than the
   box it sits in, and without this it would paint past the slide.

   THE ONE THING THIS COSTS. Slides 1-3 are all 192:65 — 3840x1300, 3840x1300,
   5760x1950. Slide 4 is 4953x1700, which is 2.9135 against their 2.9538: 1.4%
   narrower. Given its own ratio it rendered 489px tall inside a 482px hero, so it
   was seven pixels too tall, clipped at the bottom, and the hero visibly changed
   height every time the carousel reached it. Fitting the artwork to the height it
   has been given costs slide 4 a 0.7% crop off each side instead — invisible on a
   photograph, and the far better half of the trade.

   The mobile artwork has no such problem: all four mobile images are 5:7 (2000x2800
   for the first, 1000x1400 for the others), so below 48em this changes nothing. */
.slideshow--height-image .slideshow__slide {
  overflow: hidden;
}

.slideshow__slide-overlay {
  position: absolute;
  inset: 0;
  z-index: 11;
  pointer-events: none;
  background: rgba(var(--overlay-color-rgb), var(--overlay-opacity));
}

/* ------------------------------------------------------------- the slide content */
.slideshow__slide-inner {
  display: flex;
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 15;
  width: 100%;
  height: 100%;
  max-width: var(--grid-width);
  transform: translateX(-50%);
}

.slideshow__slide-heading,
.slideshow__slide-inner p {
  color: var(--color-text);
}

/* Nine positions, exactly as upstream names them. Two axes, so the rule is
   `justify-content` for the horizontal and `align-items` for the vertical. */
.slideshow__slide-inner.content-top-left      { justify-content: flex-start; align-items: flex-start; }
.slideshow__slide-inner.content-top-center    { justify-content: center;     align-items: flex-start; }
.slideshow__slide-inner.content-top-right     { justify-content: flex-end;   align-items: flex-start; }
.slideshow__slide-inner.content-middle-left   { justify-content: flex-start; align-items: center; }
.slideshow__slide-inner.content-middle-center { justify-content: center;     align-items: center; }
.slideshow__slide-inner.content-middle-right  { justify-content: flex-end;   align-items: center; }
.slideshow__slide-inner.content-bottom-left   { justify-content: flex-start; align-items: flex-end; }
.slideshow__slide-inner.content-bottom-center { justify-content: center;     align-items: flex-end; }
.slideshow__slide-inner.content-bottom-right  { justify-content: flex-end;   align-items: flex-end; }

/* The panel that carries its own background gets inset from the slide edge. This is
   the part of `content-has-bg` that is actually observable — the background itself
   is transparent on every live slide. */
.slideshow__slide-inner.content-has-bg--true .slideshow__slide-content {
  margin: 0 15px;
}

@media (min-width: 48em) {
  .slideshow__slide-inner.content-has-bg--true .slideshow__slide-content {
    margin: 0 50px;
  }

  /* A full-bleed slideshow lines its content up with the page gutter instead. */
  .slideshow--full-width-true .slideshow__slide-inner.content-has-bg--true .slideshow__slide-content {
    margin: 0 50px;
  }
}

@media (min-width: 1068px) {
  .slideshow--full-width-true .slideshow__slide-inner.content-has-bg--true .slideshow__slide-content {
    margin: 0;
  }
}

/* ----------------------------------------------------------- the inset variant */
/* `full_width: false` — the two product banners under the hero. Upstream wraps these
   in an extra `.row` (padding 0 35px) and `.columns` (padding 0 15px), so the block is
   inset 50px from each side of the viewport and sits in the page grid rather than
   bleeding past it. Measured at both 1051px and 1425px of page: the carousel is
   exactly `page width - 100`, so a single `--gutter` reproduces the two nested
   paddings and keeps the block aligned with every other section.

   `isolation` and the radius are the theme's own declaration for this class —
   `.slideshow__slide-content:after, .slideshow--full-width-false { isolation: isolate;
   border-radius: var(--block-border-radius, 16px) }`. Isolation matters because the
   content panel's tinted `::after` sits at `z-index: -1`: without a stacking context
   on the block, a negative-z child paints behind the SECTION and the panel disappears
   into the page background. Live ships `--block-border-radius: 4px`, not the 16px
   fallback, so the corners are nearly square. */
.slideshow--full-width-false {
  isolation: isolate;
  border-radius: var(--block-border-radius);
  width: calc(100% - var(--gutter) * 2);
  margin-right: auto;
  margin-left: auto;
  /* Measured, not guessed: the live carousel computes to 330.175px at 375, 560, 768
     and 1024 — the same height at four widths, which no image ratio can produce. At
     1440 its artwork is taller and wins. Reproducing the measurement rather than
     guessing where the number came from is the rule this file already follows.

     It is load-bearing between 768 and 1068: there the desktop artwork is only 223px
     tall while its text panel is 248, so without a floor the copy is taller than the
     block and the rounded corners slice the CTA off.

     So the floor is scoped to a carousel that HAS a text panel — which is what it is
     for. On a product page the same inset variant carries image-only banners (the K1's
     first one is 124px of artwork), and an unconditional floor turned that 194px
     section into 400. */
}

/* The floor itself, now that it only applies where it was measured. */
.slideshow--full-width-false.slideshow--has-content {
  min-height: 330px;
}

/* The inset banners letterbox their artwork instead of cropping it — that is what
   upstream does in this variant, measured. The full-bleed hero above them stays
   `cover`, which is the whole point of the height work it needed. */
.slideshow--full-width-false .slideshow__slide-bg img {
  object-fit: contain;
}

.slideshow__slide-content {
  position: relative;
  z-index: 20;
  width: 100%;
  max-width: 500px;
  padding: 15px;
}

@media (min-width: 48em) {
  .slideshow__slide-content { padding: 35px; }
}

@media (min-width: 1068px) {
  .slideshow__slide-content { padding: 50px; }
}

/* The optional tinted panel behind the text. `backdrop-filter` is read from the
   slide's blur setting — see the note at the top of this file. */
.slideshow__slide-content::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(var(--color-slidebg-rgb), var(--color-slidebg-opacity, 0));
  backdrop-filter: blur(var(--color-slidebg-blur, 0px));
  -webkit-backdrop-filter: blur(var(--color-slidebg-blur, 0px));
  transform: translateZ(0);
}

/* Whole-slide click target. Sits above the artwork and below the text and the CTA, so the picture
   is clickable without the overlay swallowing the button.

   `inset: 0` here resolves against `.slideshow__slide` — this element is a child of it — which is
   the whole point. While the anchor lived inside `.slideshow__slide-content` the same declaration
   meant the *content box*: measured on the home hero, a 640x100 strip against a 1301x440 slide.
   The first banner's copy and its "Shop Now" button are baked into the artwork at the upper left,
   so the visible button sat outside the clickable area and the link appeared not to work. */
.slideshow__slide-link {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* **The panel and its wrapper are layout, not targets.**

   This is the second half of the fix above, and without it the first half achieves nothing. Moving
   the anchor out of the content box puts it *below* `.slideshow__slide-inner` in the paint order —
   and that inner is a full-slide box (`top: 0; width: 100%; height: 100%`) whose only job is to
   place the text. It caught every click on the slide, including the whole of the new link, so
   `elementFromPoint` over the baked-in "Shop Now" button returned the wrapper rather than an anchor.

   An element with a transparent background still wins a hit test. That is worth stating plainly
   because it is what makes this class of bug so quiet: nothing is visible, and the only symptom is
   a link that does not respond.

   So both boxes stop taking pointers, and the things a visitor can actually interact with — the
   text, and the button — take them back. Everything else on the slide falls through to the link, so
   the padding around the copy is part of the target rather than a 640x100 dead rectangle in the
   middle of it. */
.slideshow__slide-inner,
.slideshow__slide-content {
  pointer-events: none;
}

/* `pointer-events` is inherited, so re-enabling the direct children of the panel restores the copy
   and the CTA (which lives in `.button-overflow-container`) in one declaration, without having to
   enumerate them or to name the button class. */
.slideshow__slide-content > * {
  pointer-events: auto;
}

.slideshow__slide-content .text-button {
  position: relative;
  z-index: 22;
}

.slideshow__slide.content-size-medium .slideshow__slide-content { max-width: 640px; }
.slideshow__slide.content-size-large  .slideshow__slide-content { max-width: 780px; }

.slideshow__slide-heading {
  margin: 0 0 20px;
  font-weight: var(--font-body-bold-weight);
  color: var(--color-text);
}

/* The eyebrow above a heading. `.subheading` is the theme's class name and its own
   selector is `.slideshow__slide .subheading { color: var(--color-text) }` — the
   tracking and the casing are ours because the theme sets them in a generic
   `.subheading` rule we do not otherwise port.
   12px / 500 / 0.1em / uppercase, measured off the live banner. */
.slideshow__slide .subheading {
  margin: 0 0 20px;
  font-size: 0.75rem;
  font-weight: var(--font-body-medium-weight);
  line-height: 1.6;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
}

.slideshow__slide-content p {
  margin: 0 0 20px;
  color: var(--color-text);
}

/* ------------------------------------------------------------------- the arrows */
/* Positioned inside a centred `--grid-width` box, right-aligned, 20px off the
   bottom — so they hold their place relative to the content column rather than to
   the viewport edge. */
.slideshow__navigation {
  position: absolute;
  bottom: 0;
  left: 50%;
  z-index: 40;
  width: 100%;
  max-width: var(--grid-width);
  padding: 0 20px 20px 0;
  text-align: right;
  transform: translateX(-50%);
  pointer-events: none;
}

.slideshow__navigation-inner {
  display: inline-flex;
  gap: 8px;
  pointer-events: auto;
}

.slideshow__nav-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--color-drawer-bg);
  color: var(--color-body);
  cursor: pointer;
  transition: background-color var(--duration-theme) var(--ease-theme);
}

.slideshow__nav-button:hover {
  background: var(--color-accent);
  color: var(--color-ground, var(--bg-body));
}

/* The theme scales the chevron on hover rather than the button, which keeps the
   circular edge from moving. */
.slideshow__nav-button svg {
  pointer-events: none;
  transition: transform var(--duration-theme) var(--ease-theme);
}

.slideshow__nav-button:hover svg {
  transform: scale(1.2);
}

.slideshow__nav-button[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---------------------------------------------------- mobile / desktop switching */
.slideshow-image--mobile { display: block; }
.slideshow-image--desktop { display: none; }

.slideshow__slide-desktop-content { display: none; }
.slideshow__slide-mobile-content { display: flex; }

@media (min-width: 48em) {
  .slideshow-image--mobile { display: none; }
  .slideshow-image--desktop { display: block; }
  .slideshow__slide-desktop-content { display: flex; }
  .slideshow__slide-mobile-content { display: none; }
}

/* The slide's text alignment is set twice on the live site — once for desktop and
   once for mobile — because a centre-aligned phone layout and a left-aligned
   desktop layout are different compositions, not one that scales. */
.slideshow__slide.mobile-text-left .slideshow__slide-content { text-align: left; }
.slideshow__slide.mobile-text-center .slideshow__slide-content { text-align: center; }

@media (min-width: 48em) {
  .slideshow__slide.text-left .slideshow__slide-content { text-align: left; }
  .slideshow__slide.text-center .slideshow__slide-content { text-align: center; }
}

@media (max-width: 47.99em) {
  .slideshow__slide-mobile-content.mobile-padding-small .slideshow__slide-content { padding: 15px; }
  .slideshow__slide-mobile-content.mobile-padding-medium .slideshow__slide-content { padding: 25px; }
  .slideshow__slide-mobile-content.mobile-padding-large .slideshow__slide-content { padding: 35px; }
}

/* ------------------------------------------------------------------ section rhythm *//* `flow-root` so a carousel's own margins stay inside its section instead of
   collapsing through it. Upstream gets this for free: the `.shopify-section` wrapper
   around each section is what keeps them apart, and its height includes the child's
   margins (measured: 70 + 330 + 70 = 470). Without it, the 70px bottom margin of one
   banner and the 70px top margin of the next collapse into a single 70px — half the
   gap the live site shows between two stacked banners.

   It does not move anything: a collapsed-out top margin and a contained one put the
   artwork in the same place. What changes is whose box the 70px belongs to. */
.slideshow-section {
  display: flow-root;
}
/* The hero carries top spacing only: the bottom of the image is meant to meet the
   next section, not to float above it. The banners under it carry both, so stacked
   banners are 140px apart rather than 70px.

   MARGIN, NOT PADDING — and the difference is not cosmetic. `.slideshow` is also the
   positioning context for three absolutely positioned slides, and for those the
   containing block is the element's PADDING BOX. Padding here did two things at
   once: it pushed the first slide (in flow, inside the content box) 70px down, and
   it made every other slide 70px taller than the one it was supposed to cover —
   557.5px against 487.5px at 1440 wide, with their `top: 0` resolving to the top of
   the padding rather than the top of the slide. Slides 2-4 were both offset from
   slide 1 and scaled against it, so the artwork moved and zoomed on every change.

   It survived because it needed TWO conditions to be visible at the same time: the
   >= 1068px branch (below that the spacing is 50px, not 70px) and a slideshow taller
   than one screen's worth of inspection. The browser panel this page was built in is
   1066px wide, so the 70px branch was the one width that could never be looked at. */
.slideshow--spacing-top-only {
  margin-top: var(--section-spacing-mobile);
}

.slideshow--spacing-bottom-only {
  margin-bottom: var(--section-spacing-mobile);
}

.slideshow--spacing-both {
  margin-top: var(--section-spacing-mobile);
  margin-bottom: var(--section-spacing-mobile);
}

/* `none` still needs a rule of its own on a product page: the K1 uses four of them between
   sections whose own spacing already covers the gap, and without this they would inherit
   nothing rather than nothing-if-the-theme-says-so. */
.slideshow--spacing-none {
  margin-top: 0;
  margin-bottom: 0;
}

/* 768px, not 1068px. The theme's `.section-spacing` — which is what these two
   modifiers express — moves its token at 768; only the header switches at 1068.
   Ours had the desktop values starting at 1068, so every section on the page was 50px
   short of the live spacing for the whole 768-1067 band. Confirmed two ways: the
   theme's own rule, and the live gallery at 768, whose 181px card plus 70px margin
   measures 251px. See `section-spacing.css`. */
@media (min-width: 48em) {
  .slideshow--spacing-top-only {
    margin-top: var(--section-spacing-desktop);
  }

  .slideshow--spacing-bottom-only {
    margin-bottom: var(--section-spacing-desktop);
  }

  .slideshow--spacing-both {
    margin-top: var(--section-spacing-desktop);
    margin-bottom: var(--section-spacing-desktop);
  }
}

@media (prefers-reduced-motion: reduce) {
  .slideshow__slide {
    transition-duration: 0.01ms;
  }

  .slideshow__nav-button svg {
    transition-duration: 0.01ms;
  }
}
