/**
 * Shared carousel styling.
 *
 * Every Click Wise Design carousel — the generic Carousel block and the
 * Reviews block — emits the same scaffolding and is styled by this one file,
 * so a layout setting behaves identically wherever it is used:
 *
 *   .cwd-carousel                       root, positioning context
 *     .cwd-carousel__viewport           native scroll container + snapping
 *       .cwd-carousel__track            flex row; every direct child is a slide
 *     .cwd-carousel__arrow.is-prev/next
 *     .cwd-carousel__dots > .cwd-carousel__dot
 *
 * Slide sizing has two modes, set on the root:
 *   .is-sizing-peek  slides use an explicit width, so neighbours peek in.
 *   .is-sizing-fit   N slides plus their gaps add up to exactly the container,
 *                    so a row always ends flush with the container edge.
 *
 * Breakpoint tiers, shared by both modes:
 *   mobile  <= 600px, tablet 601-899px, desktop >= 900px.
 * `peek` has no tablet setting of its own: tablet follows desktop.
 */

.cwd-carousel {
  --cwd-carousel-gap: 16px;
  --cwd-carousel-slide-w: 320px;
  --cwd-carousel-peek: 16px;
  --cwd-carousel-per-view: 3;
  --cwd-carousel-per-view-tablet: 2;
  --cwd-carousel-per-view-mobile: 1;

  /* Slides visible at once in `fit` mode, re-pointed per tier further down.
     Mobile-first, so it starts on the mobile value. */
  --cwd-carousel-pv: var(--cwd-carousel-per-view-mobile);

  position: relative;
}

/* Auto width: as wide as the widest slide, measured by the view script into
   --cwd-carousel-auto-w, and never wider than the container. Until that
   measurement lands (and in the editor, which does not run it) the carousel
   fills its container, exactly like the full-width mode.

   `!important` beats container-block plugins that force `width: 100%` on every
   direct child with a far more specific selector (e.g. Spectra/UAGB), which
   would otherwise pin the carousel to the container and leave the arrows out
   at the container edges. */
.cwd-carousel.is-width-auto {
  inline-size: min(100%, var(--cwd-carousel-auto-w, 100%)) !important;
  margin-inline: auto;
}

.cwd-carousel__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scroll-padding-inline: 0;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;

  /* Room for card borders and shadows, which `overflow-y: hidden` would
     otherwise shave off. */
  padding-block: 4px;

  /* Hide the native scrollbar without disabling scrolling. */
  scrollbar-width: none;
}

.cwd-carousel__viewport::-webkit-scrollbar {
  display: none;
}

/* Loop recentring: an instant, invisible jump of exactly one slide set. */
.cwd-carousel__viewport.is-jumping {
  scroll-behavior: auto;
}

.cwd-carousel__track {
  display: flex;
  align-items: stretch;
  gap: var(--cwd-carousel-gap);
  padding-inline: 0;
  margin: 0;
  list-style: none;
}

/* Every direct child is a slide, whatever block or element it is. */
.cwd-carousel__track > * {
  flex: 0 0 auto;
  margin: 0;
  max-inline-size: 100%;

  /* Align each slide to the start of the viewport, so every slide is its own
     scroll stop. (Centring would give the first two slides — and the last two —
     the same resting position once several slides share the view, making the
     first arrow click do nothing.) */
  scroll-snap-align: start;
  scroll-snap-stop: always;

  /* Default: exactly one slide fills the viewport.
     `!important` beats plugins that force `width: unset !important` on their
     container blocks (e.g. Spectra/UAGB). */
  inline-size: 100% !important;
}

/*
 * `fit`: N slides plus the N-1 gaps between them add up to exactly 100% of the
 * track, so a row always fits the container with nothing cut off at the right
 * edge. That also makes the scroll extent an exact multiple of one slide + gap,
 * which is what keeps every navigation step a full slide rather than a few
 * pixels.
 */
.cwd-carousel.is-sizing-fit .cwd-carousel__track > * {
  inline-size: calc(
    (100% - (var(--cwd-carousel-pv) - 1) * var(--cwd-carousel-gap)) / var(--cwd-carousel-pv)
  ) !important;
  scroll-snap-stop: normal;
}

/* "Show one at a time": one slide fills the viewport at every width. Mobile
   peek is more specific and still wins on small screens. */
.cwd-carousel.is-mode-single .cwd-carousel__track > * {
  inline-size: 100% !important;
  scroll-snap-stop: always;
}

/* Natural width probe: the view script measures the widest slide with one
   forced layout, then removes this class again. */
.cwd-carousel.is-measuring .cwd-carousel__track > * {
  inline-size: max-content !important;
}

/* --- Mobile (<= 600px) --------------------------------------------------- */
@media (max-width: 600px) {
  /* Peek: leave room for a peek + gap on BOTH sides so the previous and next
     slides each show a sliver. */
  .cwd-carousel.is-sizing-peek.is-mobile-peek .cwd-carousel__track {
    padding-inline: var(--cwd-carousel-peek);
  }

  .cwd-carousel.is-sizing-peek.is-mobile-peek .cwd-carousel__track > * {
    inline-size: calc(100% - (2 * var(--cwd-carousel-peek)) - (2 * var(--cwd-carousel-gap))) !important;

    /* Centred, so the previous and next slides peek by an equal amount. Safe
       here: a slide is nearly the full viewport, so no two slides share a
       resting position. */
    scroll-snap-align: center;
  }

  .cwd-carousel.has-arrows-mobile .cwd-carousel__arrow {
    display: flex;
  }
}

/* --- Tablet (601-899px) -------------------------------------------------- */
@media (min-width: 601px) and (max-width: 899px) {
  .cwd-carousel {
    --cwd-carousel-pv: var(--cwd-carousel-per-view-tablet);
  }
}

/* --- Tablet and desktop (>= 601px) --------------------------------------- */
@media (min-width: 601px) {
  /* Peek: slides sized by the configured width; several share the view, so a
     drag can pass over intermediate slides. */
  .cwd-carousel.is-sizing-peek.is-mode-multiple .cwd-carousel__track > * {
    inline-size: var(--cwd-carousel-slide-w) !important;
    scroll-snap-stop: normal;
  }

  .cwd-carousel.has-arrows .cwd-carousel__arrow {
    display: flex;
  }
}

/* --- Desktop (>= 900px) -------------------------------------------------- */
@media (min-width: 900px) {
  .cwd-carousel {
    --cwd-carousel-pv: var(--cwd-carousel-per-view);
  }
}

/* --- Arrows -------------------------------------------------------------- */
/*
 * Hidden by default and switched on per breakpoint above, so "show arrows" is
 * a separate choice for desktop and mobile. Each state falls back to the one
 * below it, and finally to the Astra global palette, so an unstyled carousel
 * follows the site's colors: an unset hover color keeps the base color
 * rather than jumping back to a stock grey.
 */
.cwd-carousel__arrow {
  /* Resting colors, reused by the :focus reset below. */
  --cwd-arrow-icon-rest: var(--cwd-carousel-arrow-icon, var(--ast-global-color-2, #1e1e1e));
  --cwd-arrow-bg-rest: var(--cwd-carousel-arrow-bg, var(--ast-global-color-5, #fff));

  display: none;
  position: absolute;
  top: 50%;
  z-index: 2;
  align-items: center;
  justify-content: center;
  inline-size: 44px;
  block-size: 44px;
  padding: 0;
  color: var(--cwd-arrow-icon-rest);
  background: var(--cwd-arrow-bg-rest);
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  cursor: pointer;
  transform: translateY(-50%);
  transition:
    opacity 0.15s ease,
    color 0.15s ease,
    background 0.15s ease;
}

.cwd-carousel__arrow.is-prev {
  inset-inline-start: 8px;
}

.cwd-carousel__arrow.is-next {
  inset-inline-end: 8px;
}

/* Auto width: the root is the width of the widest slide, so the arrows straddle
   the slide edges — half on the slide, half beside it — instead of sitting
   inside it. */
.cwd-carousel.is-width-auto .cwd-carousel__arrow.is-prev {
  inset-inline-start: 0;
  transform: translate(-50%, -50%);
}

.cwd-carousel.is-width-auto .cwd-carousel__arrow.is-next {
  inset-inline-end: 0;
  transform: translate(50%, -50%);
}

/* A click leaves the button focused, and Astra styles `button:focus` with its
   hover colors — more specific than the plain class rule above, so the arrow
   would look stuck on hover until something else was clicked. Restate the
   resting colors here; the :hover and :active rules below are equally
   specific and come later, so they still win while the pointer is down or
   over the button. */
.cwd-carousel__arrow:focus {
  color: var(--cwd-arrow-icon-rest);
  background: var(--cwd-arrow-bg-rest);
}

@media (hover: hover) {
  .cwd-carousel__arrow:hover {
    color: var(--cwd-carousel-arrow-icon-hover, var(--cwd-carousel-arrow-icon, var(--ast-global-color-5, #1e1e1e)));
    background: var(--cwd-carousel-arrow-bg-hover, var(--cwd-carousel-arrow-bg, var(--ast-global-color-1, #f3f3f3)));
  }
}

.cwd-carousel__arrow:active {
  color: var(
    --cwd-carousel-arrow-icon-active,
    var(--cwd-carousel-arrow-icon-hover, var(--cwd-carousel-arrow-icon, var(--ast-global-color-1, #1e1e1e)))
  );
  background: var(
    --cwd-carousel-arrow-bg-active,
    var(--cwd-carousel-arrow-bg-hover, var(--cwd-carousel-arrow-bg, var(--ast-global-color-5, #e8e8e8)))
  );
}

.cwd-carousel__arrow:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.cwd-carousel__arrow:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

.cwd-carousel__arrow svg {
  display: block;
}

/* --- Dots: below the slides, in normal flow, every breakpoint ------------ */
.cwd-carousel__dots {
  display: none;
  justify-content: center;
  gap: 8px;
  margin-block-start: 12px;
}

.cwd-carousel.has-dots .cwd-carousel__dots {
  display: flex;
}

.cwd-carousel__dot {
  inline-size: 8px;
  block-size: 8px;
  padding: 0;
  color: inherit;
  background: rgba(0, 0, 0, 0.25);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition:
    background 0.15s ease,
    transform 0.15s ease;
}

/* Slides past the last scroll stop are already on screen, so their dots are
   hidden by the view script rather than left permanently dead. */
.cwd-carousel__dot[hidden] {
  display: none;
}

@media (hover: hover) {
  .cwd-carousel__dot:hover {
    background: rgba(0, 0, 0, 0.45);
  }
}

.cwd-carousel__dot.is-active {
  background: currentColor;
  transform: scale(1.25);
}

.cwd-carousel__dot:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Respect users who prefer reduced motion: no smooth scroll. */
@media (prefers-reduced-motion: reduce) {
  .cwd-carousel__viewport {
    scroll-behavior: auto;
  }
}
