/**
 * Frontend styles: media-text slideshow.
 *
 * Plain CSS (copied verbatim to build/extensions/media-text-slideshow/view.css
 * via CopyWebpackPlugin) so the enqueued filename is deterministic.
 *
 * Fade engine: all slides share one grid cell; the active one is opaque. The
 * viewport carries an inline `aspect-ratio` (from the primary image) so every
 * slide cover-fills a consistent frame and the height never jumps on change.
 */

.ch-mts {
	position: relative;
	margin: 0;
}

.ch-mts__viewport {
	overflow: hidden;
	width: 100%;
	/* Vertical page scroll passes through; horizontal swipe is the lib's. */
	touch-action: pan-y;
}

.ch-mts__track {
	display: grid;
	grid-template-areas: "stack";
	grid-template-columns: 1fr;
	/* Lock the single row to the track height. Without it the row is
	   content-sized — the tallest slide's natural media height inflates
	   the row past the frame and overflow:hidden crops every slide. With
	   an indefinite track height (no-aspect fallback) 100% resolves to
	   auto, so the fallback is unaffected. */
	grid-template-rows: 100%;
	width: 100%;
	height: 100%;
}

.ch-mts__slide {
	min-height: 0;
}

/* The aspect-ratio frame is authoritative. Without this, the grid rows
   size to the TALLEST slide — an extra image/video with a taller ratio
   than the primary inflates the track past the frame, and overflow:hidden
   then crops every slide (including the primary). Absolute-position the
   track so the frame fully controls the box; slides cover-fit within it. */
.ch-mts__viewport[style*="aspect-ratio"] {
	position: relative;
}

.ch-mts__viewport[style*="aspect-ratio"] .ch-mts__track {
	position: absolute;
	inset: 0;
}

.ch-mts__slide {
	grid-area: stack;
	min-width: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity 400ms ease, visibility 0s linear 400ms;
}

.ch-mts__slide.is-active {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: opacity 400ms ease, visibility 0s linear 0s;
	z-index: 1;
}

/* Media fills the slide frame regardless of intrinsic size. */
.ch-mts__slide img,
.ch-mts__slide video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* When no aspect-ratio could be resolved server-side, fall back to the
   primary media's natural height (first slide defines the box). */
.ch-mts__viewport:not([style*="aspect-ratio"]) .ch-mts__slide img,
.ch-mts__viewport:not([style*="aspect-ratio"]) .ch-mts__slide video {
	height: auto;
}

/* ── Image fill (crop media to fill the column) ─────────────────────────
   Both generations of core's fill mode expect ONE media element filling
   the figure: legacy `is-image-fill` sr-hides the img (background-image
   shows it — an inline style our rewritten figure doesn't carry), and
   modern `is-image-fill-element` absolute-positions every img against the
   FIGURE (which the text column stretches) while our viewport clips to
   the primary's aspect — massive crop. In fill mode the figure box IS the
   frame: no aspect-ratio is emitted server-side (ch-mts--fill), the
   viewport/track fill the figure, and core's img treatment is neutralized
   so the slide stack owns sizing. Extra classes outweigh core's rules. */
.ch-mts.ch-mts--fill .ch-mts__viewport {
	position: relative;
	height: 100%;
}

.ch-mts.ch-mts--fill .ch-mts__track {
	position: absolute;
	inset: 0;
}

.wp-block-media-text.is-image-fill > .wp-block-media-text__media.ch-mts--fill img,
.wp-block-media-text.is-image-fill-element > .wp-block-media-text__media.ch-mts--fill img,
.wp-block-media-text.is-image-fill > .wp-block-media-text__media.ch-mts--fill video,
.wp-block-media-text.is-image-fill-element > .wp-block-media-text__media.ch-mts--fill video {
	position: static;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	clip: auto;
	clip-path: none;
	overflow: clip;
	object-fit: cover;
}

/* ── Arrows ─────────────────────────────────────────────────────────── */
.ch-mts__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: 9999px;
	background: rgba(0, 0, 0, 0.45);
	color: #fff;
	cursor: pointer;
	transition: background 150ms ease, opacity 150ms ease;
}

.ch-mts__arrow:hover {
	background: rgba(0, 0, 0, 0.65);
}

.ch-mts__arrow:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

.ch-mts__arrow svg {
	width: 1.25rem;
	height: 1.25rem;
	display: block;
}

.ch-mts__arrow--prev {
	left: 0.5rem;
}

.ch-mts__arrow--next {
	right: 0.5rem;
}

/* ── Dots ───────────────────────────────────────────────────────────── */
.ch-mts__dots {
	position: absolute;
	bottom: 0.75rem;
	left: 0;
	right: 0;
	z-index: 2;
	display: flex;
	justify-content: center;
	gap: 0.4rem;
	pointer-events: none;
}

.ch-mts__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.55);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
	cursor: pointer;
	pointer-events: auto;
	transition: background 200ms ease, transform 200ms ease;
}

.ch-mts__dot.is-active {
	background: #fff;
	transform: scale(1.15);
}

.ch-mts__dot:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* ── Author media aspect ratio (ch-mts-aspect on the block wrapper) ─────
   Mirrors core/image's aspect-ratio control for the media column — image
   AND video. Only for NON-slideshow media: a slideshow's frame carries
   the ratio inline on the viewport instead, and imageFill's figure box
   always wins (both fill generations excluded). height:auto lets the
   ratio beat the intrinsic height attribute. */
.wp-block-media-text.ch-mts-aspect:not(.is-image-fill):not(.is-image-fill-element)
	> .wp-block-media-text__media:not(.ch-mts)
	img,
.wp-block-media-text.ch-mts-aspect:not(.is-image-fill):not(.is-image-fill-element)
	> .wp-block-media-text__media:not(.ch-mts)
	video {
	aspect-ratio: var( --ch-mts-aspect );
	width: 100%;
	height: auto;
	object-fit: cover;
}

/* ── Reversed stacking order on mobile (ch-mts-reverse-mobile) ──────────
   Core stacks media first (grid-row 1) under 600px; the extra class
   outweighs core's two-class selectors and swaps the rows so the text
   comes first. */
@media (max-width: 600px) {
	.wp-block-media-text.is-stacked-on-mobile.ch-mts-reverse-mobile
		> .wp-block-media-text__media {
		grid-row: 2;
	}

	.wp-block-media-text.is-stacked-on-mobile.ch-mts-reverse-mobile
		> .wp-block-media-text__content {
		grid-row: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ch-mts__slide {
		transition: none;
	}
	.ch-mts__dot {
		transition: none;
	}
}
