/**
 * Carousel pagination — 6 types × 3 sizes × any color (since 2.2).
 *
 * Applies to both `[dsg_gallery type="carousel"]` and the WC gallery
 * carousel layout. All variants share the same outer classnames
 * (`.dsg-pagination-type-*`, `.dsg-pagination-size-*`) and a single
 * CSS custom property `--dsg-pag-color` for the accent colour, so a
 * host can theme every type by overriding one variable.
 *
 * Sizes: sm ~=  6-8px feel, md ~= 10-12px, lg ~= 14-18px. Applied via
 * body-level CSS vars so JS-generated content (dots-pill overlay,
 * counter numerals, thumbnail strip) all pick up the same scale.
 */

.dsg-gallery-carousel,
.dsg-wc-gallery--carousel {
	--dsg-pag-inactive: rgba(0, 0, 0, 0.3);
	--dsg-pag-h: 10px;     /* dot / bar height at md */
	--dsg-pag-gap: 6px;    /* between dots / segments */
	--dsg-pag-radius: 999px;
}

/* ── Size scale ─────────────────────────────────────── */

.dsg-pagination-size-sm {
	--dsg-pag-h: 6px;
	--dsg-pag-gap: 4px;
}
.dsg-pagination-size-md {
	--dsg-pag-h: 10px;
	--dsg-pag-gap: 6px;
}
.dsg-pagination-size-lg {
	--dsg-pag-h: 14px;
	--dsg-pag-gap: 8px;
}

/* ── Shared: paginator slot positioning ─────────────── */

.dsg-pagination {
	position: absolute;
	left: 50%;
	bottom: 8px;
	transform: translateX(-50%);
	z-index: 5;
	pointer-events: auto;
	max-width: calc(100% - 32px);
}

/* ── Type: dots ─────────────────────────────────────── */
/* Swiper renders .swiper-pagination-bullet inside our .dsg-pagination.
   Override Swiper's default 8px round bullets so `size` variables
   actually reach the visible element. */

.dsg-pagination--dots {
	display: flex;
	gap: var(--dsg-pag-gap);
	align-items: center;
	background: transparent;
}
.dsg-pagination--dots .swiper-pagination-bullet {
	width: var(--dsg-pag-h);
	height: var(--dsg-pag-h);
	background: var(--dsg-pag-inactive);
	opacity: 1;
	border-radius: 50%;
	margin: 0 !important; /* Swiper default margin fights our gap */
	transition: background 0.2s, transform 0.2s;
}
.dsg-pagination--dots .swiper-pagination-bullet-active {
	background: var(--dsg-pag-color);
	transform: scale(1.2);
}

/* ── Type: dots-pill ────────────────────────────────── */
/* Same dots as above, PLUS an animated pill that JS positions on
   `slide_change` and stretches during autoplay progress. The pill is
   absolutely positioned over the same row as the dots. */

.dsg-pagination--dots-pill {
	position: relative; /* pill anchors to this box */
	display: flex;
	gap: var(--dsg-pag-gap);
	align-items: center;
	background: transparent;
	padding: 0 4px;
}
.dsg-pagination--dots-pill .swiper-pagination-bullet {
	width: var(--dsg-pag-h);
	height: var(--dsg-pag-h);
	background: var(--dsg-pag-inactive);
	opacity: 1;
	border-radius: 50%;
	margin: 0 !important;
	transition: background 0.2s;
	position: relative;
	z-index: 1;
}
.dsg-pagination--dots-pill .swiper-pagination-bullet-active {
	background: transparent; /* pill covers the active dot */
}
.dsg-pagination__pill {
	position: absolute;
	top: 50%;
	left: 0;
	width: var(--dsg-pag-h);
	height: var(--dsg-pag-h);
	background: var(--dsg-pag-color);
	border-radius: var(--dsg-pag-radius);
	transform: translateY(-50%);
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
				width 0.15s linear;
	z-index: 2;
	pointer-events: none;
	will-change: transform, width;
}

/* ── Type: bar ──────────────────────────────────────── */
/* Linear progress bar spanning most of the carousel width.
   Since 2.3.2: animation driven by CSS keyframes instead of the
   Swiper `autoplayTimeLeft` event (which doesn't exist in Swiper
   6.4.5 — added in 8+). Duration comes from `--dsg-pag-duration`
   set by JS to the autoplay interval. Restarts on slideChange by
   toggling `.is-animating` off / reflow / on. */

@keyframes dsg-pag-bar-fill {
	from { width: 0%;   }
	to   { width: 100%; }
}

.dsg-pagination--bar {
	width: 60%;
	height: calc(var(--dsg-pag-h) / 2);
	min-height: 3px;
	background: var(--dsg-pag-inactive);
	border-radius: var(--dsg-pag-radius);
	overflow: hidden;
}
.dsg-pagination--bar .dsg-pagination__fill {
	display: block;
	height: 100%;
	width: 0%;
	background: var(--dsg-pag-color);
	border-radius: inherit;
	transform-origin: left center;
}
/* Autoplay dwell: fill 0 → 100% over the configured interval. */
.dsg-pagination--bar.is-animating .dsg-pagination__fill {
	animation: dsg-pag-bar-fill var(--dsg-pag-duration, 5000ms) linear forwards;
}
/* Pause native on hover (mouse users) + when Swiper autoplay is
   paused via the toggle button (JS toggles `.is-paused`). */
.dsg-gallery-carousel:hover .dsg-pagination--bar.is-animating .dsg-pagination__fill,
.dsg-wc-gallery--carousel:hover .dsg-pagination--bar.is-animating .dsg-pagination__fill,
.dsg-pagination--bar.is-animating.is-paused .dsg-pagination__fill {
	animation-play-state: paused;
}
/* Slide-position fallback (autoplay off): JS sets width directly,
   no keyframe animation. Kept for backward compat with 2.3 renderer. */
.dsg-pagination--bar:not(.is-animating) .dsg-pagination__fill {
	transition: width 0.25s ease;
}

/* ── Type: stories ──────────────────────────────────── */
/* Instagram Stories layout — one segment per slide, each fills L→R
   during its dwell. JS toggles `.is-past` / `.is-active` on bullets;
   segments look like tiny bars, not dots. */

.dsg-pagination--stories {
	display: flex;
	gap: var(--dsg-pag-gap);
	align-items: center;
	width: min(80%, 480px);
	background: transparent;
}
.dsg-pagination--stories .swiper-pagination-bullet {
	flex: 1 1 0;
	height: calc(var(--dsg-pag-h) / 2);
	min-height: 3px;
	width: auto;
	background: var(--dsg-pag-inactive);
	border-radius: var(--dsg-pag-radius);
	opacity: 1;
	margin: 0 !important;
	position: relative;
	overflow: hidden;
}
/* Past slides fill fully; JS wires `.dsg-past` via `slideChange`. */
.dsg-pagination--stories .swiper-pagination-bullet.dsg-past::after {
	content: '';
	position: absolute;
	inset: 0;
	background: var(--dsg-pag-color);
	border-radius: inherit;
}
/* Active slide's segment grows from 0 → 100% over autoplay interval.
   Since 2.3.2: driven by CSS animation (same reason as bar). Fallback
   via `--dsg-pag-fill` inline still works for the no-autoplay code path
   and for the Settings live-preview which runs its own rAF loop. */
@keyframes dsg-pag-story-fill {
	from { width: 0%;   }
	to   { width: 100%; }
}
.dsg-pagination--stories .swiper-pagination-bullet-active::after {
	content: '';
	position: absolute;
	inset: 0;
	width: var(--dsg-pag-fill, 0%);
	background: var(--dsg-pag-color);
	border-radius: inherit;
	transition: width 0.1s linear;
}
.dsg-pagination--stories.is-animating .swiper-pagination-bullet-active::after {
	width: 0%;
	animation: dsg-pag-story-fill var(--dsg-pag-duration, 5000ms) linear forwards;
}
.dsg-gallery-carousel:hover .dsg-pagination--stories.is-animating .swiper-pagination-bullet-active::after,
.dsg-wc-gallery--carousel:hover .dsg-pagination--stories.is-animating .swiper-pagination-bullet-active::after,
.dsg-pagination--stories.is-animating.is-paused .swiper-pagination-bullet-active::after {
	animation-play-state: paused;
}

/* ── Type: counter ──────────────────────────────────── */
/* Minimal "3 / 7" text badge — anchored bottom-right instead of
   centered so it doesn't compete with focal content in the middle. */

.dsg-pagination--counter {
	left: auto;
	right: 12px;
	transform: none;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	padding: 4px 10px;
	border-radius: 999px;
	font: 500 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	pointer-events: none;
	display: inline-flex;
	align-items: baseline;
	gap: 2px;
}
.dsg-pagination-size-sm .dsg-pagination--counter { font-size: 11px; padding: 3px 8px; }
.dsg-pagination-size-lg .dsg-pagination--counter { font-size: 14px; padding: 6px 12px; }
.dsg-pagination--counter .dsg-pagination__current {
	color: var(--dsg-pag-color);
	font-weight: 700;
}

/* ── Type: thumbnails ───────────────────────────────── */
/* Airbnb-style click-to-jump strip. Positions BELOW the carousel
   rather than overlaid on it, because thumbnails covering the image
   is a bad look. */

.dsg-pagination--thumbnails {
	position: static;
	transform: none;
	display: flex;
	gap: var(--dsg-pag-gap);
	margin: 12px 0 0;
	padding: 4px 0;
	overflow-x: auto;
	scrollbar-width: thin;
	max-width: 100%;
	justify-content: flex-start;
}
.dsg-pagination__thumb {
	flex: 0 0 auto;
	width: calc(var(--dsg-pag-h) * 5);
	height: calc(var(--dsg-pag-h) * 5);
	padding: 0;
	background: none;
	border: 2px solid transparent;
	border-radius: 4px;
	overflow: hidden;
	cursor: pointer;
	opacity: 0.55;
	transition: opacity 0.15s, border-color 0.15s;
}
.dsg-pagination__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.dsg-pagination__thumb:hover,
.dsg-pagination__thumb:focus-visible {
	opacity: 1;
	outline: none;
}
.dsg-pagination__thumb--active {
	opacity: 1;
	border-color: var(--dsg-pag-color);
}

/* ── Type: none ─────────────────────────────────────── */
/* Nothing renders — the paginator slot is empty. Arrows still work. */

/* ── Reduced motion — kill decorative transitions ───── */

@media (prefers-reduced-motion: reduce) {
	.dsg-pagination__pill,
	.dsg-pagination--bar .dsg-pagination__fill,
	.dsg-pagination--stories .swiper-pagination-bullet-active::after,
	.dsg-pagination--dots .swiper-pagination-bullet {
		transition: none !important;
	}
}

/* ── Position variants (since 2.3) ───────────────────
   `carousel_pagination_position` in settings. Applied to the outer
   .dsg-gallery-carousel / .dsg-wc-gallery--carousel wrapper so it
   composes with every type's own styling without duplicating rules.
   Note: `thumbnails` type positions itself statically below the
   carousel (see .dsg-pagination--thumbnails { position:static }
   above) so these position classes are no-ops for it. */

/* bottom-center is baseline default in the shared .dsg-pagination
   rule above — no override needed. */

.dsg-pagination-pos-bottom-left    .dsg-pagination:not(.dsg-pagination--thumbnails):not(.dsg-pagination--counter) { left: 12px; transform: none; }
.dsg-pagination-pos-bottom-right   .dsg-pagination:not(.dsg-pagination--thumbnails):not(.dsg-pagination--counter) { left: auto; right: 12px; transform: none; }
.dsg-pagination-pos-top-center     .dsg-pagination:not(.dsg-pagination--thumbnails)                             { top: 8px;  bottom: auto; }
.dsg-pagination-pos-top-left       .dsg-pagination:not(.dsg-pagination--thumbnails):not(.dsg-pagination--counter) { top: 8px; bottom: auto; left: 12px; transform: none; }
.dsg-pagination-pos-top-right      .dsg-pagination:not(.dsg-pagination--thumbnails):not(.dsg-pagination--counter) { top: 8px; bottom: auto; left: auto; right: 12px; transform: none; }

/* counter — respects position too, its baseline is bottom-right so
   overrides need to set both axes explicitly. */
.dsg-pagination-pos-bottom-left  .dsg-pagination--counter { left: 12px;  right: auto; bottom: 12px; top: auto; }
.dsg-pagination-pos-bottom-center .dsg-pagination--counter { left: 50%;  right: auto; transform: translateX(-50%); bottom: 12px; top: auto; }
.dsg-pagination-pos-top-left     .dsg-pagination--counter { left: 12px;  right: auto; top: 12px;    bottom: auto; }
.dsg-pagination-pos-top-center   .dsg-pagination--counter { left: 50%;   right: auto; transform: translateX(-50%); top: 12px; bottom: auto; }
.dsg-pagination-pos-top-right    .dsg-pagination--counter { right: 12px; left: auto;  top: 12px;    bottom: auto; }

/* ── Live-preview positioning reset (since 2.3) ───────
   The Settings preview mount uses its own layout container
   (`.dsg-pag-preview-target`) so the front-end absolute-positioning
   collapses inside it. Force paginators to static + strip
   position offsets so they line up in the flex row we set up in PHP. */

#dsg-pagination-preview .dsg-pagination {
	position: static !important;
	transform: none !important;
	left: auto !important;
	right: auto !important;
	top: auto !important;
	bottom: auto !important;
	margin: 0 !important;
}
#dsg-pagination-preview .dsg-pagination--dots-pill {
	position: relative !important; /* pill needs an anchor */
}
#dsg-pagination-preview .dsg-pagination--thumbnails {
	max-width: 100%;
	overflow-x: auto;
}
