/*
 * Stats slider block — frontend + editor styles.
 * Every selector is scoped to the root class .wsc-stats-slider (three-way sync rule).
 * Tokens only: theme.json presets (--wp--preset--*) plus theme customs. No !important.
 *
 * Applies .wsc-section + .wsc-container in render.php. White cards on a light
 * (surface) band. Each card is a content/image row with a 64px gap; the slide is
 * 66% wide on desktop so the next card peeks, and 100% on mobile where the card
 * stacks content over image. The dots, arrows and lock-hiding are cloned from the
 * features slider so the two carousels behave identically.
 */

.wsc-stats-slider {
	background-color: var(--wp--preset--color--surface);

	/*
	 * The slider overflows its container so the next card peeks into the gutter;
	 * this clips it back at the viewport edge. `hidden` first as the fallback,
	 * then `clip`, which wins where supported and — unlike `hidden` — does not
	 * make this a scroll container (so tabbing to an off-screen card cannot scroll
	 * the section sideways).
	 */
	overflow: hidden;
	overflow: clip;
}

.wsc-stats-slider__inner {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--60); /* 40px */
}

/*
 * Swiper's own box must NOT clip — that is what lets the next card show in the
 * gutter. The section clips instead. Doubled class so this beats Swiper's own
 * .swiper{overflow:hidden} on specificity rather than stylesheet order.
 */
.wsc-stats-slider .wsc-stats-slider__swiper {
	overflow: visible;
	width: 100%;
}

.wsc-stats-slider__swiper .swiper-wrapper {
	align-items: stretch;
}

/*
 * Full-width slides on mobile — one stat card per view; the desktop block below
 * narrows them to 66% so the next card peeks. 'auto' in script.js is what makes
 * this CSS width authoritative. height:auto lets uneven cards share a stretched
 * row.
 */
.wsc-stats-slider__swiper .swiper-slide {
	width: 100%;
	height: auto;
}

/* Card ----------------------------------------------------------------- */

/*
 * position: relative makes the card the containing block for the CTA's click
 * overlay, which is what turns the whole card into one link target. See the
 * ::before on the button below.
 */
.wsc-stats-slider__slide {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--50); /* 32px */
	height: 100%;
	padding: var(--wp--preset--spacing--40); /* 24px */
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm); /* 16px */
	background-color: var(--wp--preset--color--bg); /* white card on the surface band */
}

.wsc-stats-slider__body {
	display: flex;
	flex: 1;
	flex-direction: column;
}

/*
 * The statistic. Larger than the global h3 because it is the card's headline
 * number — a local raw rem alongside the heading token, the same sanctioned
 * departure the features slider makes for its card title.
 */
.wsc-stats-slider__heading {
	margin-block: 0;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 2rem; /* 32px — the stat headline */
	font-weight: 600;
	line-height: 1.125;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}

/* Body-Regular (14/20, -0.14px), muted; margins replace the removed body gap. */
.wsc-stats-slider__source {
	margin-block: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40); /* 16px above, 24px below */
	font-size: var(--wp--preset--font-size--body); /* 14px */
	line-height: 1.4286; /* 20/14 */
	letter-spacing: -0.01em; /* -0.14px */
	color: var(--wp--preset--color--muted); /* #7d7d7d */
}

/* The shared .wsc-button, pinned to the bottom of the content column. */
.wsc-stats-slider__body .wsc-button {
	/* Explicit, and load-bearing: see the ::before below. */
	position: static;
	align-self: flex-start;
	margin-block-start: auto;
}

/*
 * Stretches the CTA's hit area over the entire card — the same technique the
 * features slider uses.
 *
 * The overlay is absolutely positioned against the CARD, not the button, which
 * only works while the button itself stays unpositioned — hence the explicit
 * `position: static` above rather than relying on it being the default. If a
 * later change gives the button `position: relative`, the overlay silently
 * collapses to the button's own box and the card stops being clickable.
 *
 * Trade-off accepted: the overlay sits above the card's text, so the stat and
 * its source are no longer selectable. That is inherent to the pattern. Keyboard
 * and screen-reader users are unaffected — the <a> is still the only focusable
 * thing in the card.
 */
.wsc-stats-slider__body .wsc-button::before {
	content: '';
	position: absolute;
	inset: 0;
}

/*
 * Inert on the peeking card only.
 *
 * The next card peeks in by design (the 66% desktop width below), and the
 * instinctive gesture on that sliver is to tap it to bring it forward. Without
 * this the tap follows the peeking card's link and leaves the page — a behaviour
 * the card only acquired by becoming clickable. Swiper's own click suppression
 * does not cover it: that cancels a click after a DRAG, and a tap is not a drag.
 *
 * The marker is written by script.js (markClickableSlides) with a 1px tolerance
 * rather than read from Swiper's own swiper-slide-fully-visible, whose test is
 * exact — rounding strips it from a card that is in fact fully shown and kills a
 * live hit area. No marker exists before JS runs, so a no-JS render keeps every
 * card clickable.
 *
 * It hangs off Swiper's .swiper-slide, which is a node Swiper owns and not the
 * block's own __slide element, so it is written as a state class rather than a
 * BEM modifier — and scoped to the block root so it cannot leak.
 */
.wsc-stats-slider .swiper-slide.is-clipped .wsc-button::before {
	pointer-events: none;
}

/* Image ---------------------------------------------------------------- */

.wsc-stats-slider__media {
	flex: 1;
	max-width: 15rem; /* 240px */
}

.wsc-stats-slider__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 240 / 258;
	object-fit: contain;
	border-radius: var(--wp--custom--radius--sm); /* 16px */
}

/* Controls ------------------------------------------------------------- */

/* Dots bottom-left, arrows bottom-right. */
.wsc-stats-slider__controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--40); /* 24px */
	min-height: 2.5rem; /* 40px — the arrows' own height */
}

/* Swiper adds these when watchOverflow finds nothing to scroll; hide them, and
   drop the whole row (with its min-height) when both controls are locked. */
.wsc-stats-slider .swiper-pagination-lock,
.wsc-stats-slider .swiper-button-lock {
	display: none;
}

.wsc-stats-slider__controls:has(.swiper-pagination-lock):has(.swiper-button-lock) {
	display: none;
}

/* Dots ----------------------------------------------------------------- */

.wsc-stats-slider__dots.swiper-pagination {
	/* Zero Swiper's own bullet margin (a (0,3,0) rule no single class here can
	   outrank) so the 16px comes from this flex gap alone. */
	--swiper-pagination-bullet-horizontal-gap: 0;

	position: static;
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30); /* 16px */
	width: auto;
}

.wsc-stats-slider__dots .swiper-pagination-bullet {
	width: 0.75rem; /* 12px */
	height: 0.75rem;
	border: 2px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--pill);
	background-color: transparent;
	opacity: 1;
	transition: background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
		border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.wsc-stats-slider__dots .swiper-pagination-bullet-active {
	border-color: var(--wp--preset--color--ink-soft);
	background-color: var(--wp--preset--color--ink-soft);
}

/* Arrows --------------------------------------------------------------- */

.wsc-stats-slider__nav {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30); /* 16px */
}

.wsc-stats-slider__arrow {
	display: inline-flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 2.5rem; /* 40px */
	height: 2.5rem;
	padding: 0;
	border: 1.5px solid var(--wp--preset--color--muted);
	border-radius: var(--wp--custom--radius--pill);
	background-color: transparent;
	color: var(--wp--preset--color--ink-soft);
	cursor: pointer;
	transition: border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
		background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
		color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.wsc-stats-slider__arrow svg {
	display: block;
	width: 100%;
	height: 100%;
}

/* One chevron asset, flipped for "previous"; the flip reverses in RTL so the
   chevron always points the way travel actually goes. */
.wsc-stats-slider__arrow--prev {
	transform: rotate(180deg);
}

[dir='rtl'] .wsc-stats-slider__arrow--prev {
	transform: none;
}

[dir='rtl'] .wsc-stats-slider__arrow--next {
	transform: rotate(180deg);
}

.wsc-stats-slider__arrow:hover:not(.swiper-button-disabled),
.wsc-stats-slider__arrow:focus-visible:not(.swiper-button-disabled) {
	border-color: var(--wp--preset--color--ink-soft);
	background-color: var(--wp--preset--color--ink-soft);
	color: var(--wp--preset--color--bg);
}

.wsc-stats-slider__arrow.swiper-button-disabled {
	border-color: var(--wp--preset--color--border);
	color: var(--wp--preset--color--border);
	cursor: default;
}

/* Narrow viewports ----------------------------------------------------- */

@media (max-width: 767px) {
	/*
	 * Frame's mobile order is title → source → image → button. Flatten the body
	 * with display:contents so its heading/source/button become flex items of the
	 * slide column alongside the media, then push the button after the image with
	 * `order`. Spacing comes from the source's margins plus the media's, so the
	 * slide's own gap is dropped to avoid doubling it.
	 */
	.wsc-stats-slider__slide {
		gap: 0;
	}

	.wsc-stats-slider__body {
		display: contents;
	}

	.wsc-stats-slider__media {
		flex: none;
		max-width: 15.75rem; /* 252px */
		margin-block-end: var(--wp--preset--spacing--40); /* 24px, to the button */
		margin-inline: auto; /* centred */
	}

	.wsc-stats-slider__body .wsc-button {
		order: 1; /* after the image */
		width: 100%;
		margin-block-start: 0;
	}

	.wsc-stats-slider__heading {
		font-size: 1.25rem; /* 20px */
		line-height: 1.2;
		letter-spacing: 0.02em; /* 0.4px */
	}

	.wsc-stats-slider__source {
		font-size: var(--wp--preset--font-size--small); /* 12px */
		font-weight: 400;
		line-height: 1.5; /* 18/12 */
		letter-spacing: 0.01em; /* 0.12px */
	}
}

/* Desktop -------------------------------------------------------------- */

@media (min-width: 768px) {
	/* Narrower than the viewport so the following card peeks into the gutter —
	   the section's own overflow clip is what trims it at the screen edge. */
	.wsc-stats-slider__swiper .swiper-slide {
		width: 66%;
	}

	/* Content and image side by side with the 64px design gap. */
	.wsc-stats-slider__slide {
		flex-direction: row;
		align-items: stretch;
		gap: 4rem; /* 64px — the design's content-to-image gap; no preset at this size */
	}
}

/* Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.wsc-stats-slider__arrow,
	.wsc-stats-slider__dots .swiper-pagination-bullet {
		transition: none;
	}
}
