/* Frontend + editor styles for omg/carousel.
 *
 * Manual carousels show one focused slide with the neighbours bleeding at the
 * edges; the focus sits left, centre or right. Auto-scroll is a continuous
 * ribbon of natural-width slides. Gap / duration arrive as custom properties. */

.omg-carousel {
	--omg-carousel-gap: var( --wp--preset--spacing--space-20, 20px );

	/* Width of the focused slide as a fraction of the track; the rest is the
	 * bleed (split across both edges when centred, one edge otherwise). */
	--omg-carousel-slide-width: 86%;

	box-sizing: border-box;
}

@media (min-width: 834px) {

	/* Default desktop spotlight is 56%; a fixed cards-per-view overrides it via
	 * the desktop-scoped custom property so mobile keeps its single-card width. */
	.omg-carousel {
		--omg-carousel-slide-width: var(
			--omg-carousel-slide-width-desktop,
			56%
		);
	}
}

.omg-carousel__track {
	display: flex;
	align-items: center;
	gap: var( --omg-carousel-gap );
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Manual: the track is the scroll-snap viewport. */

.is-scroll-manual .omg-carousel__track {
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
}

.is-scroll-manual .omg-carousel__track::-webkit-scrollbar {
	display: none;
}

/* The slide fills the padded content box (the padding below sizes that box to
 * the focus width), so percentage flex-basis is not double-counted. */
.is-scroll-manual .omg-carousel-slide {
	flex: 0 0 100%;
}

/* Images carry their natural width (e.g. size-full), which leaves a gap inside
 * the fixed-width slide. Stretch them to fill while keeping their aspect. */
.is-scroll-manual .omg-carousel-slide .wp-block-image {
	width: 100%;
	margin: 0;
}

.is-scroll-manual .omg-carousel-slide .wp-block-image img {
	width: 100%;
	height: auto;
}

/* A linked image wraps the img in an inline-block <a> that sits on the baseline,
 * leaving descender whitespace below it inside the block figure. */
.omg-carousel-slide .wp-block-image a {
	display: block;
}

/* Auto-scroll: an animated flex strip clipped by the carousel; slides keep
 * their natural width; no controls. */

.is-scroll-auto {
	overflow: hidden;
}

.is-scroll-auto .omg-carousel__track {
	width: max-content;
}

.is-scroll-auto .omg-carousel-slide {
	flex: 0 0 auto;
}

/* Focus alignment: padding centres the first/last slide to the chosen edge,
 * and snap-align settles each slide there. */

.is-scroll-manual.is-focus-center .omg-carousel__track {
	padding-inline: calc( ( 100% - var( --omg-carousel-slide-width ) ) / 2 );
}

.is-scroll-manual.is-focus-right .omg-carousel__track {
	padding-left: calc( 100% - var( --omg-carousel-slide-width ) );
}

.is-scroll-manual.is-focus-center .omg-carousel-slide {
	scroll-snap-align: center;
}

/* Focus-left sizes each slide straight from the width variable (no track
 * padding), so the row scrolls from the first slide flush left to the last
 * flush right with no trailing gap. Centre/right keep the padded-content-box
 * model, where the slide fills 100% of a padding-shrunk track. The :where()
 * keeps this a low-specificity default so per-instance widths (trustindex's
 * multi-card row, the editor's fixed slide) still override it cleanly. */
.is-scroll-manual.is-focus-left :where( .omg-carousel-slide ) {
	flex: 0 0 var( --omg-carousel-slide-width );
}

.is-scroll-manual.is-focus-left .omg-carousel-slide {
	scroll-snap-align: start;
}

/* Focus-left rows are card grids: stretch slides to equal height so a card with
 * height:100% fills the tallest slide and its content top-aligns (the base
 * centre alignment suits the centred spotlight, not a row of cards). */
.is-scroll-manual.is-focus-left .omg-carousel__track {
	align-items: stretch;
}

.is-scroll-manual.is-focus-right .omg-carousel-slide {
	scroll-snap-align: end;
}

/* Centre (enlarged): view.js marks the centred slide ".is-current" and the rest
 * scale down toward it (origin on the edge nearest the centre), so the middle
 * slide reads as the spotlight and the on-screen gap stays the flex gap rather
 * than the flex gap plus the empty space a centre-origin scale would leave.
 * Gated on ".is-enlarge-ready" (also added by view.js) so the slides do not
 * flash shrunk before the script marks the first current slide. */

/* Two classes (0,2,0) beat the base gap default; an inline gap attribute still wins. */
.omg-carousel.is-enlarge-focus {
	--omg-carousel-gap: var( --wp--preset--spacing--space-16, 16px );
}

.is-enlarge-focus.is-enlarge-ready .omg-carousel-slide {
	transition: transform 0.35s ease;
}

@media (prefers-reduced-motion: reduce) {

	.is-enlarge-focus.is-enlarge-ready .omg-carousel-slide {
		transition: none;
	}
}

/* Focus-left stops with the last slide flush to the right edge rather than
 * stranding it on the left with a large trailing gap; the last slide snaps its
 * end to the viewport while the rest keep their left snap. */
.is-scroll-manual.is-focus-left .omg-carousel-slide:last-child {
	scroll-snap-align: end;
}

.is-enlarge-focus.is-enlarge-ready .omg-carousel-slide:not( .is-current ) {
	transform: scale( var( --omg-carousel-focus-scale, 0.8 ) );
}

/* Slides before the centred one shrink toward their right edge, slides after it
 * toward their left, so each scaled neighbour's inner edge stays put and the
 * gap to the centred slide reads as the 16px flex gap, not flex gap + scale slack. */
.is-enlarge-focus.is-enlarge-ready .omg-carousel-slide:has( ~ .is-current ) {
	transform-origin: right center;
}

.is-enlarge-focus.is-enlarge-ready .is-current ~ .omg-carousel-slide {
	transform-origin: left center;
}

/* Desktop grid: above the tablet breakpoint, a manual carousel can lay every
 * slide out as equal columns instead of bleeding, dropping the arrows. Mobile
 * keeps the center-focus carousel. */

@media (min-width: 834px) {

	.is-desktop-grid.is-scroll-manual .omg-carousel__track {
		overflow: visible;
		scroll-snap-type: none;

		/* Override the focus-alignment padding that frames the bleed. */
		padding-inline: 0;
	}

	.is-desktop-grid.is-scroll-manual .omg-carousel-slide {
		flex: 1 1 0;
	}

	.is-desktop-grid .omg-carousel__controls {
		display: none;
	}
}

.is-scroll-auto.is-animating .omg-carousel__track {
	animation: omg-carousel-marquee var( --omg-carousel-duration, 40s ) linear
		infinite;
}

.is-scroll-auto:hover .omg-carousel__track,
.is-scroll-auto:focus-within .omg-carousel__track {
	animation-play-state: paused;
}

@keyframes omg-carousel-marquee {

	from {
		transform: translateX( 0 );
	}

	to {

		/* Slides are duplicated once, so -50% returns to the start seamlessly. */
		transform: translateX( -50% );
	}
}

@media (prefers-reduced-motion: reduce) {

	.is-scroll-auto {
		overflow-x: auto;
	}

	.is-scroll-auto.is-animating .omg-carousel__track {
		animation: none;
	}
}

/* Controls. */

.omg-carousel__controls {
	display: flex;
	gap: 28px;
	margin-top: var( --wp--preset--spacing--space-20, 20px );
}

.is-controls-left .omg-carousel__controls {
	justify-content: flex-start;
}

.is-controls-center .omg-carousel__controls {
	justify-content: center;
}

.is-controls-right .omg-carousel__controls {
	justify-content: flex-end;
}

.no-controls .omg-carousel__controls {
	display: none;
}

.omg-carousel__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var( --wp--preset--color--dark-blue, #001c44 );
	border-radius: 9999px;
	background: transparent;
	color: var( --wp--preset--color--dark-blue, #001c44 );
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.omg-carousel__arrow:disabled {
	opacity: 0.35;
	cursor: default;
}

.omg-carousel__arrow:hover:not( :disabled ),
.omg-carousel__arrow:focus-visible:not( :disabled ) {
	background: var( --wp--preset--color--dark-blue, #001c44 );
	color: var( --wp--preset--color--white, #fff );
}

.omg-carousel__arrow svg {
	width: 8px;
	height: 14px;
}

