/* wp-content/themes/gtmotor/assets/css/components/carousel.css — unified carousel (extracted from approved D1 mockup) */
/* ==========================================================================
   ==========================================================================
   SHIPPABLE: carousel.css   →  assets/css/components/carousel.css
   ==========================================================================
   Unified carousel. CSS owns the layout (how many columns, item width, peek,
   snap); JS reads the computed layout and drives motion. Nothing here is
   specific to bike cards — any .gtm-carousel__item content works.
   ========================================================================== */

/* ---- Root: column count per breakpoint + shared knobs -------------------- */
.gtm-carousel {
  /* --gtm-cards : columns visible at once. Overridden by the media queries
                   below. JS never sets this — it reads it back off the item. */
  --gtm-cards: 1;
  --gtm-gap: 24px;                 /* matches the theme's 24px track gap */
  --gtm-peek-basis: 86%;           /* phone peek width (see [data-peek]) */
  position: relative;
  width: 100%;
}

/* ONLY the 768 / 992 / 1200 breakpoints, per spec. Mobile-first: base is 1. */
@media (min-width: 768px)  { .gtm-carousel { --gtm-cards: 2; } }
@media (min-width: 992px)  { .gtm-carousel { --gtm-cards: 3; } }
@media (min-width: 1200px) { .gtm-carousel { --gtm-cards: 4; } }

/* ---- Viewport: the scroll container -------------------------------------- */
.gtm-carousel__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;   /* JS sets this to `none` mid-animation */
  overscroll-behavior-x: contain;  /* don't chain horizontal overscroll to the page */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;           /* Firefox: hide scrollbar */
  -ms-overflow-style: none;        /* old Edge */
  /* Horizontal swipes scroll the carousel; vertical swipes scroll the page. */
  touch-action: pan-x pan-y;
  cursor: grab;
  /* A little top/bottom room so hover shadow + focus ring aren't clipped. */
  padding: 4px 0 20px;
}
.gtm-carousel__viewport::-webkit-scrollbar { display: none; } /* Chrome/Safari */
.gtm-carousel__viewport:focus-visible {
  outline: 3px solid #342E37;
  outline-offset: 2px;
  border-radius: 8px;
}
.gtm-carousel.is-dragging .gtm-carousel__viewport {
  cursor: grabbing;
  scroll-snap-type: none;          /* let the pointer drag scrub freely */
  user-select: none;               /* no text selection while dragging */
}

/* ---- Track: the flex row of items ---------------------------------------- */
/* The track stays exactly the viewport width; items (flex-shrink:0) overflow it
   horizontally and the viewport scrolls them. Critically this makes the item's
   `calc(100% ...)` basis resolve against the VIEWPORT width, not the track's
   own content width (which would be circular). Do NOT add min-width:min-content
   here — that lets the track grow to its content and breaks the column maths. */
.gtm-carousel__track {
  display: flex;
  gap: var(--gtm-gap);
  align-items: stretch;            /* equal-height cards */
  width: 100%;
}

/* Guard: some converted filter pages keep the legacy .gtm-explore-track class
   (for its #id), whose flex-wrap:wrap would wrap the single row into a grid.
   3-class specificity here beats .gtm-explore-track.is-sparse. */
.gtm-carousel:not(.gtm-carousel--rows2) .gtm-carousel__track { display: flex; flex-wrap: nowrap; }

/* Guard: the legacy explore/parts scrollers left horizontal padding on the
   viewport (padding-left) and the track (padding-right) for the old edge-fade
   mask. Inside the unified engine those insets shrink the flex container so N
   columns no longer align to the viewport edges and the next card peeks on
   desktop. Force horizontal padding to 0 so the column maths resolves against
   the true viewport width (keeps the engine viewport vertical padding). */
.gtm-carousel .gtm-carousel__viewport { padding-left: 0 !important; padding-right: 0 !important; }
.gtm-carousel .gtm-carousel__track { padding-left: 0 !important; padding-right: 0 !important; }

/* ---- Item: width is one Nth of the viewport (minus the gaps) -------------- */
.gtm-carousel__item {
  /* (100% - (N-1) gaps) / N  → N whole columns fit exactly, no fractional card. */
  flex: 0 0 calc(
    (100% - (var(--gtm-cards) - 1) * var(--gtm-gap)) / var(--gtm-cards)
  );
  /* flex-basis is a floor, not a cap: with flex-shrink:0 a nowrap child (e.g. a
     very long card title) can still stretch the item past its basis. max-width
     turns the column into a hard cap so ellipsis inside the card takes over and
     the layout never balloons. min-width:0 lets that ellipsis actually engage. */
  max-width: calc(
    (100% - (var(--gtm-cards) - 1) * var(--gtm-gap)) / var(--gtm-cards)
  );
  min-width: 0;
  min-height: 0;
  overflow: hidden;                /* clip any stray child overflow to the cell */
  scroll-snap-align: start;        /* each card snaps to the left edge */
  display: flex;                   /* so the card can stretch to full height */
}
/* Phone peek must also cap at the peek width, not the N-column width. */
@media (max-width: 767.98px) {
  .gtm-carousel[data-peek] .gtm-carousel__item { max-width: var(--gtm-peek-basis); }
}

/* ---- Phone peek: reveal a sliver of the next card ------------------------- */
/* Only <768 and only when the root opts in via data-peek. */
@media (max-width: 767.98px) {
  .gtm-carousel[data-peek] .gtm-carousel__item { flex-basis: var(--gtm-peek-basis); }
}

/* ---- 2-row variant ("Explore"): 2 ROWS, STEP ONE COLUMN ----------------- */
/* The track is a 2-row grid that flows COLUMN-first (each on-screen column is a
   pair of stacked cards) and overflows horizontally. explore-bikes.js drops flat
   .gtm-carousel__item cards straight in (no page blocks); grid-auto-flow:column
   places them down-then-across, so column N holds cards 2N-1 and 2N. The engine
   measures ONE item (= one column) as its step, so an arrow advances exactly one
   column (dots still map to full pages). auto rows keep the top and bottom cards
   aligned across every column.
   >=768px only; the <768 single-row swipe layout is defined further below. */
@media (min-width: 768px) {
  .gtm-carousel--rows2 .gtm-carousel__track {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(2, auto);
    grid-auto-columns: calc((100% - (var(--gtm-cards) - 1) * var(--gtm-gap)) / var(--gtm-cards));
    column-gap: var(--gtm-gap);
    row-gap: 32px;
    align-content: start;
  }
  /* Each item fills its grid cell (one column); neutralise the base flex sizing. */
  .gtm-carousel--rows2 .gtm-carousel__item {
    flex: initial;
    width: auto;
    min-width: 0;
    max-width: none;
    scroll-snap-align: start;
  }
}

/* ---- Phone (<768): single-row swipe (unchanged behaviour) ---------------- */
/* On phones the 2-row grid is too tall, so explore-bikes.js skips the page
   chunking and drops flat .gtm-carousel__item cards straight into the track.
   The track then behaves like every other single-row .gtm-carousel: the base
   flex-item rule sizes each card and [data-peek] reveals a sliver of the next.
   (No .gtm-carousel__page blocks exist at this width.) */
@media (max-width: 767.98px) {
  .gtm-carousel--rows2 .gtm-carousel__track {
    display: flex;
    flex-wrap: nowrap;
    column-gap: var(--gtm-gap);
  }
}

/* ---- Navigation: the theme's Standard Pill bar (white rounded bar, circular
   outlined arrows at the ends, centred dots) — matches the original nav. ----- */
.gtm-carousel__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;  /* arrows to the ends, dots fill the centre */
  gap: 12px;
  background: #fff;
  border: 1px solid #eee;
  border-radius: 999px;
  padding: 8px 12px;
  width: 100%;
  margin-top: 24px;
}
/* When there's nothing to scroll (all cards fit), JS adds .is-static and the
   whole nav is hidden — no dead arrows, no lonely single dot. */
.gtm-carousel.is-static .gtm-carousel__nav { display: none; }

.gtm-carousel__arrow {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;                     /* 44px min touch target (a11y) */
  height: 44px;
  padding: 0;
  border: 1.5px solid #342E37;     /* outlined circle, brand dark */
  border-radius: 50%;
  background: #fff;
  color: #342E37;
  cursor: pointer;
  transition: background .2s ease, color .2s ease, opacity .2s ease;
}
.gtm-carousel__arrow svg { width: 18px; height: 18px; display: block; }
.gtm-carousel__arrow:hover { background: #342E37; color: #fff; }
.gtm-carousel__arrow:focus-visible { outline: 3px solid #342E37; outline-offset: 2px; }
.gtm-carousel__arrow:disabled {
  opacity: .28;
  cursor: default;
  pointer-events: none;
}

.gtm-carousel__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-grow: 1;                    /* dots take the centre space */
}
.gtm-carousel__dot {
  appearance: none;
  -webkit-appearance: none;
  width: 8px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: #ccc;
  cursor: pointer;
  transition: background .2s ease;
}
.gtm-carousel__dot:hover { background: #999; }
.gtm-carousel__dot:focus-visible { outline: 3px solid #342E37; outline-offset: 3px; }
.gtm-carousel__dot.is-active { background: #000; }

/* ---- Reduced motion: no scrub animations (JS also jump-scrolls) ---------- */
@media (prefers-reduced-motion: reduce) {
  .gtm-carousel__viewport { scroll-behavior: auto; }
  .gtm-carousel__dot,
  .gtm-carousel__arrow { transition: none; }
}
/* ===================== END SHIPPABLE carousel.css ========================= */
