.cms-slider-wrapper {
	position: relative;
	width: 100%;
}

.cms-slider {
	width: 100%;
	height: 500px; /* fallback; overridden by Elementor Style tab */
}

.cms-slide {
	position: relative;
	overflow: hidden;
	background: #000;
	/* Own stacking context so media/overlay/caption z-index always behaves
	 * predictably, regardless of any ancestor stacking quirks (e.g. iframes
	 * or theme CSS creating their own contexts). */
	isolation: isolate;
}

.cms-slide__media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
}

.cms-slide__image-outer {
	overflow: hidden;
}

.cms-slide__image {
	display: block;
	will-change: transform;
	transform-origin: center center;
}

/* -----------------------------------------------------------------------
 * FIX: Image Size / Position X / Position Y.
 * Many WordPress themes ship global rules like `img { height: auto; }`
 * (sometimes with !important) meant for responsive content images. That
 * silently defeats object-fit:cover + object-position on a plain <img>,
 * because the element no longer actually fills its box. We scope this to
 * plain (non-Ken-Burns) image slides only, so Ken Burns pan/zoom sizing
 * below is completely untouched.
 * The actual fit/position VALUES come from the --cms-fit / --cms-pos-x /
 * --cms-pos-y custom properties set inline per-slide in the PHP render,
 * so each slide keeps its own independent setting even though the
 * properties themselves are forced with !important.
 * --------------------------------------------------------------------- */
.cms-slide:not(.cms-slide--kenburns) .cms-slide__image {
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	max-height: none !important;
	object-fit: var(--cms-fit, cover) !important;
	object-position: var(--cms-pos-x, 50%) var(--cms-pos-y, 50%) !important;
}

.cms-slide__video,
.cms-slide__video iframe,
.cms-yt-player {
	width: 100%;
	height: 100%;
}

.cms-slide__video.cms-video--fit {
	/* inherits position:absolute; inset:0 from .cms-slide__media — no override here */
}

.cms-slide__video.cms-video--full {
	overflow: hidden;
}

/* In "full" mode, JS measures the container and sizes the iframe to cover it
 * completely (like background-size:cover), cropping the video edges instead
 * of showing YouTube's native letterbox bars. The iframe is always centered
 * so the crop stays symmetric regardless of the computed oversize. */
.cms-slide__video.cms-video--full iframe {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 100%;
	height: 100%;
}

.cms-slide__video iframe {
	/* Interaction fix lives mostly in JS (Swiper touchStartPreventDefault)
	 * and here, defensively: make sure nothing accidentally disables
	 * pointer events on the iframe itself. */
	pointer-events: auto !important;
	border: 0;
}

/* Per-slide color overlay — sits above the media, below the caption text.
 * z-index explicitly higher than .cms-slide__media (1) and lower than
 * .cms-caption (3); pointer-events:none so clicks always pass through to
 * the video/image beneath it. */
.cms-slide__overlay {
	position: absolute;
	inset: 0;
	z-index: 2 !important;
	pointer-events: none !important;
}

/* Caption overlay */
.cms-caption {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	padding: 32px;
	box-sizing: border-box;
	pointer-events: none !important;
	z-index: 3 !important;
}

.cms-caption__title {
	color: #fff;
	font-size: 28px;
	font-weight: 700;
	margin: 0 0 8px;
}

.cms-caption__desc {
	color: #f2f2f2;
	font-size: 16px;
	margin: 0;
	max-width: 640px;
}

/* Ken Burns — two families of motion, kept mechanically separate so there is
 * never a moment where the image is smaller than its container:
 *
 * 1) ZOOM (zoom-in / zoom-out): pure center-scale, no translation. Since the
 *    image always covers the container at scale >= 1, the edges only ever
 *    move outward — there is no scale value in the animated range that can
 *    expose empty space.
 *
 * 2) PAN (top-bottom / bottom-top / left-right / right-left): the image is
 *    NOT object-fit:cover at container size. Instead it's rendered at its
 *    natural aspect ratio, sized to fully cover the cross-axis (e.g. width:
 *    100% for a vertical pan), which usually makes it taller/wider than the
 *    container on the pan axis. JS measures the real overflow in pixels and
 *    sets --kb-pan-start/--kb-pan-end accordingly, so translateX/Y always
 *    stays within the image's actual bounds — mathematically no gap is
 *    possible. If the image doesn't overflow enough to pan, JS falls back
 *    to a static object-fit:cover crop instead of forcing a broken pan.
 *
 * This block is intentionally left as-is (untouched by the fixes above) —
 * Ken Burns wasn't part of the reported bugs, and the :not(.cms-slide--kenburns)
 * scoping above guarantees these two areas of CSS can never fight each other.
 */

.cms-slide--kenburns .cms-slide__image {
	transform: none;
}

/* Zoom family */
.cms-kb-zoom-in .cms-slide__image,
.cms-kb-zoom-out .cms-slide__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transform-origin: center center;
}

.cms-kb-zoom-in.cms-kb-active .cms-slide__image,
.cms-kb-zoom-out.cms-kb-active .cms-slide__image {
	animation-name: cms-kb-zoom;
	animation-timing-function: linear;
	animation-fill-mode: forwards;
}

/* Pan family — JS sets width/height/top/left and the --kb-pan-* px values */
.cms-kb-top-bottom .cms-slide__image,
.cms-kb-bottom-top .cms-slide__image {
	width: 100%;
	height: auto;
	position: absolute;
	left: 0;
	top: 0;
}

.cms-kb-left-right .cms-slide__image,
.cms-kb-right-left .cms-slide__image {
	height: 100%;
	width: auto;
	position: absolute;
	top: 0;
	left: 0;
}

.cms-kb-top-bottom.cms-kb-active .cms-slide__image,
.cms-kb-bottom-top.cms-kb-active .cms-slide__image {
	animation-name: cms-kb-pan-y;
	animation-timing-function: linear;
	animation-fill-mode: forwards;
}

.cms-kb-left-right.cms-kb-active .cms-slide__image,
.cms-kb-right-left.cms-kb-active .cms-slide__image {
	animation-name: cms-kb-pan-x;
	animation-timing-function: linear;
	animation-fill-mode: forwards;
}

/* Fallback: pan direction but image doesn't overflow enough — JS adds this
 * class instead of activating the pan animation, so it just displays as a
 * normal static cover crop with no motion (better than a broken pan). */
.cms-slide__image--static-cover {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover !important;
	animation: none !important;
	transform: none !important;
}

@keyframes cms-kb-zoom {
	from { transform: scale(var(--kb-scale-start, 1)); }
	to   { transform: scale(var(--kb-scale-end, 1.3)); }
}

@keyframes cms-kb-pan-y {
	from { transform: translateY(var(--kb-pan-start, 0px)); }
	to   { transform: translateY(var(--kb-pan-end, 0px)); }
}

@keyframes cms-kb-pan-x {
	from { transform: translateX(var(--kb-pan-start, 0px)); }
	to   { transform: translateX(var(--kb-pan-end, 0px)); }
}

/* Elementor editor: keep arrows/pagination visible without hover requirement */
.swiper-button-next,
.swiper-button-prev {
	--swiper-navigation-size: 22px;
}

/* Arrows/pagination must stay clickable above the caption layer (z-index 3) */
.swiper-button-next,
.swiper-button-prev,
.swiper-pagination {
	z-index: 4;
}
