/*
 * Section wrapper - holds the whole-widget background (colour, gradient or video)
 * behind the carousel. The background group control paints this element itself,
 * so padding set here insets the cards from that background.
 */
.nd-cat-slider {
	position: relative;
	isolation: isolate;
}

.nd-cat-slider-bg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	overflow: hidden;
	z-index: 0;
}

.nd-cat-slider-bg-fallback {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-size: cover;
	background-position: center center;
	background-repeat: no-repeat;
}

.nd-cat-slider-bg-video {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 100%;
	height: 100%;
	min-width: 100%;
	min-height: 100%;
	transform: translate(-50%, -50%);
	object-fit: cover;
	pointer-events: none;
}

/* Transparent until an Overlay Color is set in the Section Background section */
.nd-cat-slider-bg-overlay {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	pointer-events: none;
	z-index: 1;
}

.nd-cat-slider > .elementor-carousel-wrapper {
	position: relative;
	z-index: 2;
}

/*
 * Grid mode. The JS adds this class (and destroys any Swiper instance) whenever
 * the Layout control resolves to "grid" for the current viewport, so one DOM
 * serves both layouts and the two can differ per device. Column count comes from
 * the responsive Grid Columns control; the gap comes from Spacing Between Cards.
 *
 * The !important flags are what keep "Slides to Show" out of grid mode. CE's
 * carousel trait points that control at
 * `{{WRAPPER}} .swiper:not(.swiper-initialized) .swiper-wrapper`, and core's own
 * "before init fix" (frontend.css) targets the same pre-init state with
 * `grid-template-rows: 1fr; grid-auto-rows: 0`. Both are meant to last only until
 * Swiper initialises - but in grid mode it never does, so they apply forever, at a
 * specificity (and, for the control, a source order) this file cannot outrank:
 * the slide count would dictate the column count and every row after the first
 * would collapse to zero height.
 */
.nd-cat-slider-grid {
	overflow: visible;
}

.nd-cat-slider-grid .swiper-wrapper {
	display: grid;
	grid-template-columns: repeat(var(--nd-cat-grid-columns, 4), minmax(0, 1fr)) !important;
	grid-template-rows: none !important;
	grid-auto-rows: auto !important;
	align-items: stretch;
}

/* Undo the inline width / margin Swiper leaves on slides it has laid out */
.nd-cat-slider-grid .swiper-slide {
	width: auto !important;
	height: auto;
	margin: 0 !important;
}

/*
 * Per-card Column Span. The JS resolves each card's span for the current device,
 * caps it to the cards per row and sets it as --nd-cat-span on the slide; it also
 * puts the cards per row and the gap on the wrapper as --nd-cat-spv / --nd-cat-gap.
 *
 * In the slider, Swiper runs with `slidesPerView: 'auto'` whenever a span is
 * used and measures these widths: a span-N slide is N card widths plus the N-1
 * gaps it swallows, so the rest of the row still lines up with an even split.
 */
.nd-cat-slider-grid .swiper-slide {
	grid-column: span var(--nd-cat-span, 1);
}

/*
 * Grid Alignment Center / Right swap the grid for a wrapping flex row, which can
 * move an incomplete last row. This basis gives each slide the grid's column width
 * (span-N swallowing N-1 gaps, as above); a grid ignores flex-basis, so it is
 * always set and only takes effect once the wrapper is flex.
 */
.nd-cat-slider-grid .swiper-slide {
	flex: 0 0 calc((100% - (var(--nd-cat-grid-columns, 4) - 1) * var(--nd-cat-grid-gap, 0px)) / var(--nd-cat-grid-columns, 4) * var(--nd-cat-span, 1) + (var(--nd-cat-span, 1) - 1) * var(--nd-cat-grid-gap, 0px));
	min-width: 0;
}

.nd-cat-slider-spans:not(.nd-cat-slider-grid) .swiper-slide {
	flex-shrink: 0;
	width: calc((100% - (var(--nd-cat-spv, 1) - 1) * var(--nd-cat-gap, 0px)) / var(--nd-cat-spv, 1) * var(--nd-cat-span, 1) + (var(--nd-cat-span, 1) - 1) * var(--nd-cat-gap, 0px));
}

.nd-cat-slider-grid .elementor-swiper-button,
.nd-cat-slider-grid .swiper-pagination {
	display: none;
}

.nd-cat-slider-card {
	--nd-cat-slider-anim-duration: .3s;
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	height: 100%;
	text-align: center;
	text-decoration: none;
	color: inherit;
	background-color: #f7f7f7;
	overflow: hidden;
	isolation: isolate;
	transition: transform var(--nd-cat-slider-anim-duration) ease, box-shadow var(--nd-cat-slider-anim-duration) ease, border-color var(--nd-cat-slider-anim-duration) ease;
}

/*
 * Background - always rendered, as a clipping wrapper around the layer the
 * card's Background control (colour, gradient or image) paints. A background
 * video sits in that layer too, so the "Grow" hover animation can scale it
 * without touching the content.
 *
 * The wrapper itself never moves, so its rounded clip stays put while the layer
 * scales. The mask is the usual fix for browsers (Safari, and Chrome while the
 * transition runs on the compositor) dropping the border-radius clip around a
 * transformed child and showing square corners; it lives here rather than on
 * the card because a mask would also cut off the card's box shadow.
 */
.nd-cat-slider-card-bg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	overflow: hidden;
	isolation: isolate;
	-webkit-mask-image: -webkit-radial-gradient(white, black);
	mask-image: radial-gradient(white, black);
	z-index: 0;
}

.nd-cat-slider-card-bg-layer {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	transition: transform var(--nd-cat-slider-anim-duration) ease, filter var(--nd-cat-slider-anim-duration) ease;
}

.nd-cat-slider-card-video-fallback {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-size: cover;
	background-position: center center;
	background-repeat: no-repeat;
}

.nd-cat-slider-card-video {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 100%;
	height: 100%;
	min-width: 100%;
	min-height: 100%;
	transform: translate(-50%, -50%);
	object-fit: cover;
	pointer-events: none;
}

/* With no Mobile Video Link set the single video keeps no variant class, so it
 * stays visible at every width - that's the "show the default if empty" case.
 * Shared by the card and the section background. */
.nd-cat-video-mobile {
	display: none;
}

@media (max-width: 767px) {
	.nd-cat-video-desktop {
		display: none;
	}

	.nd-cat-video-mobile {
		display: block;
	}
}

/* Transparent until an Overlay Color is set in the Card style section */
.nd-cat-slider-card-overlay {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	pointer-events: none;
	transition: background-color var(--nd-cat-slider-anim-duration) ease, opacity var(--nd-cat-slider-anim-duration) ease;
	z-index: 1;
}

/*
 * Whole-card link used when the card also has a button: an empty anchor stretched
 * over the card, under the button but above everything else.
 */
.nd-cat-slider-card-link {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	z-index: 3;
}

.nd-cat-slider-card-media,
.nd-cat-slider-card-content {
	position: relative;
	z-index: 2;
}

.nd-cat-slider-card-media {
	display: flex;
	align-items: center;
	justify-content: center;
}

.nd-cat-slider-card-icon {
	display: inline-flex;
}

.nd-cat-slider-card-icon i {
	font-size: 48px;
	line-height: 1;
}

.nd-cat-slider-card-icon svg {
	width: 48px;
	height: auto;
	fill: currentColor;
}

.nd-cat-slider-card-image {
	max-width: 100%;
	height: auto;
	transition: filter var(--nd-cat-slider-anim-duration) ease;
}

.nd-cat-slider-card-content {
	width: 100%;
	/* Only take effect once a card's Layout makes this a flex row */
	align-items: center;
	gap: 16px;
}

/* The subheading / title / description / icon list, as one block beside the
 * button in Row layout */
.nd-cat-slider-card-text {
	flex: 1 1 auto;
	min-width: 0;
}

.nd-cat-slider-card-subheading {
	margin: 0 0 6px;
	font-size: 12px;
	line-height: 1.4;
	letter-spacing: .08em;
	text-transform: uppercase;
}

.nd-cat-slider-card-title {
	margin: 0 0 10px;
	font-size: 20px;
	line-height: 1.3;
}

.nd-cat-slider-card-description {
	margin: 0;
	font-size: 14px;
	line-height: 1.6;
	opacity: .8;
}

/* Subheading Position "Below Description": the description has no bottom
 * margin, so the subheading brings its own gap (Subheading > Spacing) */
.nd-cat-slider-card-description + .nd-cat-slider-card-subheading {
	margin-top: 6px;
}

/*
 * Per-card icon list, between the description and the button. Sized here the way
 * .nd-cat-slider-card-icon is, so the Icon List style section only has to
 * override the font-size / width.
 *
 * A grid rather than a flex column because `justify-items` takes left / right
 * (which `align-items` doesn't), so a card's Horizontal Alignment override can
 * drive it directly.
 */
.nd-cat-slider-card-icon-list {
	display: grid;
	justify-items: center;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nd-cat-slider-card-icon-list-item {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 14px;
	line-height: 1.6;
}

.nd-cat-slider-card-icon-list-icon {
	display: inline-flex;
	align-items: center;
}

.nd-cat-slider-card-icon-list-icon i {
	font-size: 16px;
	line-height: 1;
}

.nd-cat-slider-card-icon-list-icon svg {
	width: 16px;
	height: auto;
	fill: currentColor;
}

/*
 * margin-top comes from Button > Spacing via --nd-cat-btn-spacing, unless the
 * card is in Row layout, which sets --nd-cat-btn-row-mt to 0 on the content
 * wrapper (and back to `initial` - i.e. "use the fallback" - for Stacked).
 */
.nd-cat-slider-card-button {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-direction: row-reverse;
	flex-shrink: 0;
	gap: 8px;
	z-index: 4;
	margin-top: var(--nd-cat-btn-row-mt, var(--nd-cat-btn-spacing, 16px));
	padding: 10px 24px;
	border: 1px solid currentColor;
	border-radius: 2px;
	color: inherit;
	font-size: 14px;
	line-height: 1.4;
	text-decoration: none;
	transition: opacity var(--nd-cat-slider-anim-duration) ease, color var(--nd-cat-slider-anim-duration) ease, background-color var(--nd-cat-slider-anim-duration) ease, border-color var(--nd-cat-slider-anim-duration) ease;
}

.nd-cat-slider-card-button:hover,
.nd-cat-slider-card:hover .nd-cat-slider-card-button {
	opacity: .8;
}

/* No text: square the default padding so the icon sits in a balanced box */
.nd-cat-slider-card-button-icon-only {
	padding: 10px;
}

.nd-cat-slider-card-button-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
	transition: color var(--nd-cat-slider-anim-duration) ease, background-color var(--nd-cat-slider-anim-duration) ease, transform var(--nd-cat-slider-anim-duration) ease;
}

.nd-cat-slider-card-button-icon svg {
	width: 1em;
	height: auto;
	fill: currentColor;
}

/*
 * Card hover animations - the "Hover Animation" control puts one of these
 * classes on every card. `grow` and `zoom-media` leave the card itself still:
 * they scale the background layer and the icon / image respectively.
 */
.nd-cat-slider-anim-move-up:hover {
	transform: translateY(-4px);
}

.nd-cat-slider-anim-move-down:hover {
	transform: translateY(4px);
}

.nd-cat-slider-anim-shrink:hover {
	transform: scale(.96);
}

.nd-cat-slider-anim-float:hover {
	transform: translateY(-10px);
}

.nd-cat-slider-anim-tilt:hover {
	transform: rotate(-1.5deg) scale(1.02);
}

.nd-cat-slider-anim-zoom-media .nd-cat-slider-card-media {
	overflow: hidden;
}

.nd-cat-slider-anim-zoom-media .nd-cat-slider-card-image,
.nd-cat-slider-anim-zoom-media .nd-cat-slider-card-icon {
	transition: transform var(--nd-cat-slider-anim-duration) ease, filter var(--nd-cat-slider-anim-duration) ease;
}

.nd-cat-slider-anim-zoom-media:hover .nd-cat-slider-card-image,
.nd-cat-slider-anim-zoom-media:hover .nd-cat-slider-card-icon {
	transform: scale(1.08);
}

/* Scales only the background layer; .nd-cat-slider-card-bg clips it to the
 * card's shape. `zoom-bg` is the removed "Grow Background" option, kept for
 * cards saved with it. */
.nd-cat-slider-anim-grow:hover .nd-cat-slider-card-bg-layer,
.nd-cat-slider-anim-zoom-bg:hover .nd-cat-slider-card-bg-layer {
	transform: scale(1.08);
}

@media (prefers-reduced-motion: reduce) {
	.nd-cat-slider-card,
	.nd-cat-slider-card-bg-layer,
	.nd-cat-slider-card-overlay,
	.nd-cat-slider-card-button,
	.nd-cat-slider-card-button-icon,
	.nd-cat-slider-card-image,
	.nd-cat-slider-card-icon {
		transition: none;
	}

	.nd-cat-slider-card:hover,
	.nd-cat-slider-card:hover .nd-cat-slider-card-bg-layer,
	.nd-cat-slider-card:hover .nd-cat-slider-card-image,
	.nd-cat-slider-card:hover .nd-cat-slider-card-icon {
		transform: none;
	}
}
