/* ==========================================================================
   WV Carousel — reusable horizontal scroll carousel
   --------------------------------------------------------------------------
   Version 2 (2026-06-01) — focus styles consolidated to apply at all
   viewports; scroll-padding added for focus="left" / focus="right" so
   last/first slide can reach the focus pivot regardless of list length;
   slide-width custom property documented for consumer override.
   Version 1 (2026-04-22) — initial.
   See parts/carousel.php for markup and COMPONENTS.md entry #15 for API.
   ========================================================================== */

.wv-carousel {
  /* Flex layout: arrows occupy their own narrow columns flanking the
     track. With arrows='none', the carousel renders as a single-child
     flex container — equivalent to a full-width block. */
  display: flex;
  align-items: center;
  width: 100%;

  /* Scoped custom properties — override via consumer wrapper style if needed.
     --wv-carousel-slide-width is consumed by the scroll-padding rules below
     so the last/first slide in focus-left/-right can reach the pivot even
     with short lists. Default 288 matches Product Card / Ingredient Card /
     Bundle Card; consumers with different slide widths (e.g. Product Tile
     at 221) set this inline. */
  --wv-carousel-gap:         20px;     /* between slides inside the track */
  --wv-carousel-arrow-gap:   16px;     /* between arrow column and track */
  --wv-carousel-slide-width: 288px;    /* slide width for scroll-padding math */

  gap: var(--wv-carousel-arrow-gap);

  /* container-type enables the "narrow-track auto-hide" rule at the
     bottom of this file — arrows disappear when the carousel itself is
     too narrow, independent of viewport width. */
  container-type: inline-size;
  container-name: wv-carousel;
}

.wv-carousel__track-wrap {
  flex: 1 1 auto;
  min-width: 0;                       /* allow shrinking so cards stay inside */
  overflow: hidden;
}

.wv-carousel__track {
  display: flex;
  flex-direction: row;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  gap: var(--wv-carousel-gap);
  padding-bottom: 8px;
  scrollbar-width: none;
}

.wv-carousel__track::-webkit-scrollbar { display: none; }

.wv-carousel__track > * {
  flex-shrink: 0;
  scroll-snap-align: start;
  transition: transform 240ms ease, opacity 240ms ease;
}

/* ==========================================================================
   Focus variants — non-focused slides dim + scale down.
   JS toggles [data-focused="true"] on whichever slide sits at the pivot.

   Mobile + desktop both apply muting (opacity 0.6) so the focused slide
   visually pops at all viewports. Desktop adds a scale-down for the
   non-focused slides; mobile keeps slides at scale 1 so they don't
   visually shrink at the smaller viewport.
   ========================================================================== */

.wv-carousel--focus-left .wv-carousel__track > *,
.wv-carousel--focus-right .wv-carousel__track > *,
.wv-carousel--focus-center .wv-carousel__track > * {
  opacity: 0.6;
}

/* Transform-origin is always `center center` regardless of focus mode so
   the scale-down shrinks symmetrically from each card's own center. This
   keeps visual gaps consistent across focus-left / -right / -center —
   non-focused cards always pull inward from both sides by the same
   percentage, so the gap pattern around the focused card mirrors. */
.wv-carousel--focus-left .wv-carousel__track > *,
.wv-carousel--focus-right .wv-carousel__track > *,
.wv-carousel--focus-center .wv-carousel__track > * { transform-origin: center center; }

.wv-carousel--focus-center .wv-carousel__track > * { scroll-snap-align: center; }
.wv-carousel--focus-right  .wv-carousel__track > * { scroll-snap-align: end; }

.wv-carousel__track > [data-focused="true"] {
  opacity: 1;
}

/* ==========================================================================
   Track padding — gives focus="left" / focus="right" carousels the
   trailing/leading space the last/first slide needs to actually scroll
   to the focus pivot. Physical padding (not scroll-padding) because we
   need the scrollWidth to grow, not just snap-alignment to move.
   focus="center" gets symmetric padding (below) for the same reason —
   center-snap alone can't bring the first/last slide to center.
   --wv-carousel-slide-width override (set on the consumer wrapper inline)
   lets a tile-sized variant get the right padding math.

   This trailing/leading padding only matters when content overflows. When
   all slides fit in the viewport, JS toggles the .wv-carousel__track--fits
   class (below) and we center the slides instead.
   ========================================================================== */

.wv-carousel--focus-left .wv-carousel__track {
  /* Trailing padding so last slide can reach the leftmost snap point.
     Math: padding_end >= clientWidth - slide_width (no -20 — the 20px
     focus pivot offset is handled by scroll-padding-inline-start, not
     by reducing the available scrollable area). */
  padding-inline-end: calc(100% - var(--wv-carousel-slide-width));
  /* Snap to viewport x=20 (matches the focus pivot at trackLeft + 20)
     so the focused card's left edge lands exactly AT the pivot.
     Consistent across all breakpoints. */
  scroll-padding-inline-start: 20px;
}

.wv-carousel--focus-right .wv-carousel__track {
  padding-inline-start: calc(100% - var(--wv-carousel-slide-width));
  scroll-padding-inline-end: 20px;
}

/* focus="center": symmetric leading + trailing padding so the FIRST and
   LAST slides can scroll all the way to the viewport center. center-snap
   alone can't do it — without this room the first/last can't reach center
   (only the inner slides become active). Half of (track − slide) per side. */
.wv-carousel--focus-center .wv-carousel__track {
  padding-inline: calc((100% - var(--wv-carousel-slide-width)) / 2);
}

/* When all slides fit in the viewport, JS adds .wv-carousel__track--fits
   to the track and we (a) center the slides horizontally and (b) drop the
   end/start padding that exists for the scroll-to-pivot use case. Click in
   this state becomes in-place focus — see wv-carousel.js. */
.wv-carousel__track--fits {
  justify-content: center;
}

.wv-carousel--focus-left .wv-carousel__track--fits,
.wv-carousel--focus-right .wv-carousel__track--fits,
.wv-carousel--focus-center .wv-carousel__track--fits {
  padding-inline: 0;
}

/* ==========================================================================
   Arrow placement — sides (flanking the track) vs none (consumer places)
   Arrow-btn partial owns visual styling; carousel owns positioning.

   In flex layout, arrows occupy their own narrow columns (flex: 0 0 auto).
   No absolute positioning, no z-index needed.
   ========================================================================== */

.wv-carousel__arrow {
  flex: 0 0 auto;
}

.wv-carousel--arrows-none .wv-carousel__arrow { display: none; }

/* Narrow-track auto-hide: when the carousel's own width drops below a
   threshold (cards getting cramped), drop the arrows entirely so the
   track has full width to render at least one card cleanly. Independent
   of viewport width — triggers from layout context, not page size. */
@container wv-carousel (max-width: 480px) {
  .wv-carousel__arrow { display: none; }
}

/* ==========================================================================
   Mobile base — cards bleed off the right edge, no scale transform.
   Track gets viewport padding so first slide aligns with section edge.
   Restored to default carousel layout at tablet+.
   ========================================================================== */

.wv-carousel__track {
  padding-inline: 20px;
  scroll-padding-inline: 20px;
}

.wv-carousel__track > * {
  flex: 0 0 82vw;
}

.wv-carousel--focus-left .wv-carousel__track > *,
.wv-carousel--focus-right .wv-carousel__track > *,
.wv-carousel--focus-center .wv-carousel__track > * {
  transform: none;
}

.wv-carousel--focus-left .wv-carousel__track > *,
.wv-carousel--focus-right .wv-carousel__track > * {
  /* Override the desktop transform-origin so the mobile no-scale rule
     above doesn't pick up an off-center origin if a future change adds
     scale at mobile. */
  transform-origin: center center;
}

.wv-carousel__arrow { display: none; }

@media (min-width: 768px) {
  .wv-carousel__track {
    padding-inline: 0;
    scroll-padding-inline: 0;
  }

  .wv-carousel__track > * {
    flex: 0 0 auto;
  }

  .wv-carousel--focus-left .wv-carousel__track > *,
  .wv-carousel--focus-right .wv-carousel__track > *,
  .wv-carousel--focus-center .wv-carousel__track > * {
    transform: scale(0.88);
  }

  /* Origin stays center for all focus modes — see comment above the
     base transform-origin rule. */
  .wv-carousel--focus-left .wv-carousel__track > *,
  .wv-carousel--focus-right .wv-carousel__track > *,
  .wv-carousel--focus-center .wv-carousel__track > * { transform-origin: center center; }

  .wv-carousel__track > [data-focused="true"] {
    transform: scale(1);
  }

  .wv-carousel__arrow { display: revert; }
}
