/* ============================================================
   OSLIDER — base mechanics (functional only, no visual skin).
   Skins live in per-location modifier classes (.oslider--hero …).
   Load this BEFORE the skin CSS; load oslider.js after the markup.
   ============================================================ */
.oslider { position: relative; }

.oslider__viewport { overflow: hidden; }

.oslider__track {
  display: flex;
  gap: var(--os-gap, 0px);
  will-change: transform;
  transition: transform var(--os-speed, 500ms) cubic-bezier(.4, 0, .2, 1);
}
.oslider__track.is-no-anim { transition: none !important; }

/* Each slide's width is derived from the engine-set custom properties, so the
   visible count + gap can change per breakpoint with NO media queries here. */
.oslider__slide {
  flex: 0 0 calc((100% - (var(--os-per-view, 1) - 1) * var(--os-gap, 0px)) / var(--os-per-view, 1));
  min-width: 0;
}

/* Category carousel defaults — visible before JS layout runs (Elementor preview). */
.cat-carousel.oslider {
  --os-per-view: 3;
  --os-gap: 18px;
}

/* Arrows / dots are hidden when the engine disables them via [hidden]. */
.oslider__arrow[hidden],
.oslider__dots[hidden] { display: none !important; }

/* Sensible resets so a skin only has to style, not un-style, the controls. */
.oslider__arrow { cursor: pointer; border: 0; background: none; display: grid; place-items: center; }
.oslider__arrow:disabled { cursor: default; }
.oslider__dot { cursor: pointer; border: 0; padding: 0; background: none; }

/* ============================================================
   REUSABLE LAYOUT (placement) — shared by every skin, so a skin
   only sets colours/sizes, never re-positions the controls.
   Centering is the DEFAULT; opt into other placements with a
   modifier class on the .oslider root.
   ============================================================ */

/* dots: centered by default (horizontal row) */
.oslider__dots { display: flex; justify-content: center; align-items: center; gap: 8px; }

/* ---- Placement 1 (default): nav in a centered bar BELOW the track ----
   Wrap prev · dots · next in <div class="oslider__bar"> for the classic
   "‹  • • •  ›" control row. */
.oslider__bar {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  margin-top: var(--os-bar-gap, 22px);
}

/* ---- Placement 2: arrows OVERLAY the track (vertical-centered L/R),
   dots centered along the bottom. Add .oslider--nav-overlay ---- */
.oslider--nav-overlay .oslider__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
}
.oslider--nav-overlay .oslider__arrow--prev { left: var(--os-arrow-inset, 16px); }
.oslider--nav-overlay .oslider__arrow--next { right: var(--os-arrow-inset, 16px); }
.oslider--nav-overlay .oslider__dots {
  position: absolute; left: 50%; bottom: var(--os-dots-inset, 16px);
  transform: translateX(-50%); z-index: 5;
}

/* ---- Placement 3: dots as a VERTICAL rail on the right (no arrows).
   Add .oslider--dots-right ---- */
.oslider--dots-right .oslider__dots {
  position: absolute; top: 50%; right: var(--os-dots-inset, 10px);
  transform: translateY(-50%); flex-direction: column; z-index: 3;
}

/* center the whole component in its container when narrower than the column */
.oslider--center { margin-left: auto; margin-right: auto; }

/* ============================================================
   MOBILE BASE — sane defaults so controls stay usable on phones
   without each skin re-declaring them. (Visual colour stays in skin.)
   ============================================================ */
@media (max-width: 768px) {
  .oslider--nav-overlay .oslider__arrow--prev { left: var(--os-arrow-inset-sm, 8px); }
  .oslider--nav-overlay .oslider__arrow--next { right: var(--os-arrow-inset-sm, 8px); }
  .oslider__bar { gap: 14px; margin-top: var(--os-bar-gap-sm, 16px); }
}
/* keep tap targets comfortable on touch devices */
@media (hover: none) and (pointer: coarse) {
  .oslider__arrow { min-width: 40px; min-height: 40px; }
}

/* ============================================================
   DEVICE GATE (data-os-enable) — when the slider is disabled for
   the current device, JS adds .is-off and the slides fall back to
   a STATIC wrapping grid: no transform, controls hidden, slides
   keep their per-view width and simply wrap onto new rows.
   ============================================================ */
.oslider.is-off .oslider__track { transform: none !important; flex-wrap: wrap; }
.oslider.is-off .oslider__arrow,
.oslider.is-off .oslider__dots { display: none !important; }
