/**
 * JMeks Split Panels styles (widget type jmeks_alternating_features; it was
 * called Alternating Features until 1.14.0).
 *
 * Rows are image beside text, alternating sides down the page. Below the
 * breakpoint the shared slider runtime turns each row into a slide and adds
 * .jmeks-slider-active to the wrapper — that class, not a media query, is what
 * switches the layout to stacked cards, so the CSS and the slider cannot
 * disagree about where the switch happens. The breakpoint itself lives in the
 * panel and is read from Elementor's own config by jmeks-slider.js.
 *
 * Specificity is doing real work here. Stacked is the base state; the
 * alternating rules add it back from 768px up and are held to two classes with
 * :where( :nth-child() ); the .jmeks-slider-active rules are three classes and
 * therefore win wherever they apply, in or out of a media query, without
 * depending on source order. The 768px floor only decides where side-by-side
 * starts when no slider is running — it is not the slider's breakpoint.
 *
 * Custom properties:
 *   --jmeks-features-ratio        image aspect ratio, as a number (from PHP)
 *   --jmeks-features-peek         how much of the next card shows (from PHP)
 *   --jmeks-features-gap          space between cards (from PHP)
 *   --jmeks-features-dots-top     gap between the image and the dots (20px)
 *   --jmeks-features-dots-inset   extra gap from the image's right edge (0)
 *   --jmeks-panel-gutter          floor for the outer padding when aligned;
 *                                 defaults to the shared --jmeks-gutter
 *   --jmeks-panel-inner-gutter    gap between the copy and the image; defaults
 *                                 to the same gutter as the outer edge
 *   --jmeks-features-copy-max     widest the panel copy runs (580px; the
 *                                 Text max width control sets it per device)
 * Dot size and colour use the shared --jmeks-dot-* properties from
 * jmeks-slider.css, so these dots match every other JMeks slider.
 */

/*
 * Elementor's own widget wrapper. A flex container sizes its children
 * shrink-to-fit unless they stretch, which would render this section at the
 * width of its longest line rather than the width of the container. Stating it
 * on the wrapper is the only place that reaches: .jmeks-features sizing itself
 * to 100% of a wrapper that has already shrunk changes nothing.
 */
.elementor-widget-jmeks_alternating_features {
	width: 100%;
}

.jmeks-features {
	/*
	 * The containing block for the dots, and full width in its own right.
	 *
	 * Deliberately NOT a container query context. An Elementor V4 Flexbox
	 * sizes its children shrink-to-fit, and inline-size containment means
	 * "size me without looking at my contents" — so the widget contributes
	 * nothing to its ancestors' intrinsic width and the whole wrapper chain
	 * collapses to zero, rendering a narrow strip of overflowing text. Setting
	 * a width here does not save it: the collapse happens above this element.
	 * Covered by the shrink-to-fit case in alternating-features.test.mjs.
	 */
	width: 100%;
	position: relative;
	/*
	 * The section's own background. The gap between cards and the strip beside
	 * a peeking one belong to the widget, not to any card, so without this the
	 * page shows through them. It follows the kit's primary colour, the same
	 * global the panel control defaults to, so the two agree before Elementor
	 * has generated any CSS; the hex is only a last resort.
	 */
	background-color: var( --e-global-color-primary, #0f0f1d );
}

/* Base state: stacked. */
.jmeks-features__row {
	display: flex;
	flex-direction: column;
	align-items: stretch;
}

.jmeks-features__media,
.jmeks-features__panel {
	flex: 0 0 auto;
	width: 100%;
	min-width: 0;
}

.jmeks-features__media {
	position: relative;
	aspect-ratio: var( --jmeks-features-ratio, 1 );
}

/*
 * The photo fills its box and never sizes it. In flow, a side-by-side row
 * grew to the photo's own shape: a near-square picture in a 960px half made
 * the row 987px tall whatever the minimum said. Taken out of flow, the row is
 * as tall as its minimum or its copy, whichever is more, and the photo crops.
 * Stacked, the media box gets its height from the aspect ratio above.
 *
 * Two classes on purpose. Elementor ships `.elementor img{height:auto}`, which
 * is a class and a type — (0,1,1) — and beats a single class. Scoping to the
 * wrapper makes this (0,2,0) and it wins.
 */
.jmeks-features .jmeks-features__image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: cover;
}

.jmeks-features__panel {
	display: flex;
	flex-direction: column;
	justify-content: center;
	/* Horizontal padding is the site gutter, so a full-bleed panel's copy sits
	   on the same line as a boxed section's. */
	padding: 60px var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) );
	background-color: var( --e-global-color-primary, #0f0f1d );
	color: #fff;
}

/* 40px, 20px on phones; the Space under title control sets both. */
.jmeks-features__title {
	margin: 0 0 40px;
	/* Even lines rather than a full line and a stray word. */
	text-wrap: balance;
}

/*
 * Two classes on the colour: the kit writes heading colours as
 * `.elementor-kit-N h2` (0,1,1), which beats one class and would paint this
 * heading in the site's heading colour instead of the widget's.
 */
.jmeks-features .jmeks-features__title {
	color: inherit;
}

/*
 * The copy stops at a comfortable line length while the panel's background
 * still fills its half. Each child is capped rather than the panel, which is a
 * flex column: its children sit at the start edge, so the text stays on the
 * content line and the button keeps sizing to its label.
 */
.jmeks-features__panel > * {
	max-width: var( --jmeks-features-copy-max, 580px );
}

.jmeks-features__body > :first-child {
	margin-top: 0;
}

.jmeks-features__body > :last-child {
	margin-bottom: 0;
}

/*
 * The section heading for phones. Its sides are the same gutter as the card
 * copy, so the two start on one line; top and bottom come from the panel.
 * When the slider runs it moves this out of the rows and above the cards
 * (data-jmeks-place="before"), so it never becomes a slide.
 */
.jmeks-features__mobile-heading {
	margin: 0;
	text-wrap: balance;
	padding: 40px var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) 24px;
}

/* Two classes, for the kit's heading colour; see the title above. */
.jmeks-features .jmeks-features__mobile-heading {
	color: #fff;
}

@media ( min-width: 768px ) {
	.jmeks-features__mobile-heading {
		display: none;
	}
}

@media ( max-width: 767px ) {
	.jmeks-features__title--hide-mobile {
		display: none;
	}

	.jmeks-features__title {
		margin-bottom: 20px;
	}
}

/*
 * The panel is a flex column, so an anchor would stretch to its full width and
 * stop looking like a button. Sizing to its own text is the whole rule.
 */
.jmeks-features__button {
	align-self: flex-start;
	margin-top: 30px;
}

/*
 * Side by side, alternating. The image stops carrying an aspect ratio here and
 * stretches to the row, whose height is the minimum or the copy's.
 */
@media ( min-width: 768px ) {
	.jmeks-features__media,
	.jmeks-features__panel {
		flex: 0 0 50%;
		width: 50%;
	}

	.jmeks-features__media {
		aspect-ratio: auto;
	}

	/*
	 * Rows are counted among rows only ("of .jmeks-features__row"). The mobile
	 * heading is the widget's first child, and a plain :nth-child() counted it:
	 * with a heading set, the first row became even and every row swapped
	 * sides, so "Text on the left" put the image there (fixed in 1.14.1).
	 */
	.jmeks-features--text-first .jmeks-features__row:where( :nth-child( odd of .jmeks-features__row ) ) {
		flex-direction: row-reverse;
	}

	.jmeks-features--text-first .jmeks-features__row:where( :nth-child( even of .jmeks-features__row ) ) {
		flex-direction: row;
	}

	.jmeks-features--image-first .jmeks-features__row:where( :nth-child( odd of .jmeks-features__row ) ) {
		flex-direction: row;
	}

	.jmeks-features--image-first .jmeks-features__row:where( :nth-child( even of .jmeks-features__row ) ) {
		flex-direction: row-reverse;
	}

	/*
	 * Content-grid alignment. The panel keeps its full-bleed background while
	 * its copy starts on the same line as every other section, which means the
	 * padding on the panel's OUTER edge is the page gutter: half of whatever is
	 * left over once the content column is taken out of the widget's width.
	 *
	 * It is the same number on both sides of the alternation. A panel on the
	 * left needs it on the left so the text starts at the column; a panel on
	 * the right needs it on the right so the text ends there.
	 *
	 * The percentage resolves against the row, which is the widget's width, so
	 * there is no 100vw here: 100vw includes the scrollbar and would throw every
	 * panel about 15px off the grid, and it would be wrong outright if the
	 * widget were ever not full-bleed. --container-max-width is the variable
	 * Elementor's kit already writes onto .e-con from Site Settings > Layout >
	 * Content Width, and custom properties inherit, so this follows the site.
	 *
	 * max() is the floor: once the viewport is narrower than the content column
	 * the gutter would go negative.
	 *
	 * :not( .jmeks-slider-active ) both scopes this to the side-by-side layout
	 * and lifts the specificity above the panel padding Elementor generates.
	 * When the cards stack there is no half to align to and the base padding
	 * applies again, with no reset rule needed.
	 *
	 * Physical left/right, not logical: which side is "outer" depends on the
	 * flex direction, which itself flips under RTL. These rules assume LTR.
	 */
	.jmeks-features--align:not( .jmeks-slider-active ).jmeks-features--text-first .jmeks-features__row:where( :nth-child( odd of .jmeks-features__row ) ) .jmeks-features__panel,
	.jmeks-features--align:not( .jmeks-slider-active ).jmeks-features--image-first .jmeks-features__row:where( :nth-child( even of .jmeks-features__row ) ) .jmeks-features__panel {
		padding-left: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
		padding-right: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
	}

	.jmeks-features--align:not( .jmeks-slider-active ).jmeks-features--text-first .jmeks-features__row:where( :nth-child( even of .jmeks-features__row ) ) .jmeks-features__panel,
	.jmeks-features--align:not( .jmeks-slider-active ).jmeks-features--image-first .jmeks-features__row:where( :nth-child( odd of .jmeks-features__row ) ) .jmeks-features__panel {
		padding-right: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
		padding-left: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
	}
}

/*
 * Sliding. Each row is the only child of its slide, so without these it would
 * count as nth-child( odd ) and lay out sideways inside the card.
 */
.jmeks-features.jmeks-slider-active .jmeks-features__row {
	flex-direction: column;
}

.jmeks-features.jmeks-slider-active .jmeks-features__media,
.jmeks-features.jmeks-slider-active .jmeks-features__panel {
	flex: 0 0 auto;
	width: 100%;
}

.jmeks-features.jmeks-slider-active .jmeks-features__media {
	aspect-ratio: var( --jmeks-features-ratio, 1 );
}

/*
 * Slide width. The shared slider takes only the peek off, which is right when
 * slides sit flush against each other. These are spaced, and Swiper advances by
 * slide width plus gap, so a gap the same size as the peek would leave exactly
 * nothing showing. Taking both off makes the control honest: 20px of peek shows
 * 20px of the next card, whatever the gap is. Four classes, so it beats the
 * shared rule's three.
 */
.jmeks-features.jmeks-slider-active > .jmeks-slider .swiper-slide {
	width: calc( 100% - var( --jmeks-features-peek, 0px ) - var( --jmeks-features-gap, 0px ) );
}

/*
 * The runtime appends the dots to the slider root, a sibling of the slides, so
 * they stay put while the slides move. Placed at the top of the panel, level
 * with where the image ends.
 */
.jmeks-features.jmeks-slider-active > .jmeks-slider > .jmeks-slider__dots {
	position: absolute;
	top: 0;
	/*
	 * A percentage margin on an absolutely positioned box resolves against the
	 * containing block's WIDTH, which is what gives the image's height once the
	 * aspect ratio is applied. `top` cannot do this: its percentages resolve
	 * against the containing block's height. The offset lives in the shorthand
	 * so a later `margin` cannot silently reset it.
	 *
	 * The peek is subtracted because it is taken off the slide, and the image
	 * is only as wide as the slide — so the image is both shorter and further
	 * from the widget's right edge than the widget itself. Both offsets have to
	 * account for it or the dots drift off the picture.
	 */
	margin: calc( ( 100% - var( --jmeks-features-peek, 0px ) - var( --jmeks-features-gap, 0px ) ) / var( --jmeks-features-ratio, 1 ) + var( --jmeks-features-dots-top, 20px ) ) 0 0;
	right: calc( var( --jmeks-features-peek, 0px ) + var( --jmeks-features-gap, 0px ) + var( --jmeks-features-dots-inset, 0px ) );
	left: auto;
	justify-content: flex-end;
	z-index: 2;
}

/* ---------------------------------------------------------------------------
 * Image side and the desktop cross-fade (1.30).
 *
 * PHP writes jmeks-features__row--image-right / --image-left on every row,
 * worked out from Image side and First row starts with. The :nth-child() rules
 * above still draw the default Alternate layout; these take over when every
 * row keeps the same side (--same) and when the slides cross-fade on desktop
 * (--fade, where each row is alone in its slide and can't be counted).
 * ------------------------------------------------------------------------ */

@media ( min-width: 768px ) {
	/* Same side every row: later and as heavy as the counted rules, so these win. */
	.jmeks-features--same .jmeks-features__row--image-right {
		flex-direction: row-reverse;
	}

	.jmeks-features--same .jmeks-features__row--image-left {
		flex-direction: row;
	}

	.jmeks-features--same.jmeks-features--align:not( .jmeks-slider-active ) .jmeks-features__row--image-right .jmeks-features__panel {
		padding-left: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
		padding-right: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
	}

	.jmeks-features--same.jmeks-features--align:not( .jmeks-slider-active ) .jmeks-features__row--image-left .jmeks-features__panel {
		padding-right: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
		padding-left: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
	}
}

/*
 * Desktop cross-fade. The slider runtime adds jmeks-slider-fading while it is
 * fading (above phone width), so every rule here is keyed on that rather than
 * on a media query: on a phone the stacked-card rules above apply untouched.
 */
.jmeks-features.jmeks-slider-active.jmeks-slider-fading .jmeks-features__row--image-right {
	flex-direction: row-reverse;
}

.jmeks-features.jmeks-slider-active.jmeks-slider-fading .jmeks-features__row--image-left {
	flex-direction: row;
}

.jmeks-features.jmeks-slider-active.jmeks-slider-fading .jmeks-features__media,
.jmeks-features.jmeks-slider-active.jmeks-slider-fading .jmeks-features__panel {
	flex: 0 0 50%;
	width: 50%;
}

.jmeks-features.jmeks-slider-active.jmeks-slider-fading .jmeks-features__media {
	aspect-ratio: auto;
}

/* One slide at a time: no peek, no gap, no dots. */
.jmeks-features.jmeks-slider-active.jmeks-slider-fading > .jmeks-slider .swiper-slide {
	width: 100%;
}

.jmeks-features.jmeks-slider-active.jmeks-slider-fading > .jmeks-slider > .jmeks-slider__dots {
	display: none;
}

/* The copy on the content line, as the side-by-side layout does. */
.jmeks-features.jmeks-features--align.jmeks-slider-fading .jmeks-features__row--image-right .jmeks-features__panel {
	padding-left: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
	padding-right: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
}

.jmeks-features.jmeks-features--align.jmeks-slider-fading .jmeks-features__row--image-left .jmeks-features__panel {
	padding-right: max( var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ), calc( ( 100% - var( --container-max-width, 1140px ) ) / 2 ) );
	padding-left: var( --jmeks-panel-inner-gutter, var( --jmeks-panel-gutter, var( --jmeks-gutter, 32px ) ) );
}

/*
 * Next / Back: text on the photo, bottom corner. Only while fading; phones
 * keep the dots. The one that can't go anywhere (Back on the first slide,
 * Next on the last) is hidden rather than dimmed.
 */
.jmeks-features.jmeks-slider-active > .jmeks-slider > .jmeks-slider__nav {
	display: none;
}

.jmeks-features.jmeks-slider-active.jmeks-slider-fading > .jmeks-slider > .jmeks-slider__nav {
	position: absolute;
	bottom: var( --jmeks-features-nav-bottom, 48px );
	right: var( --jmeks-features-nav-inset, 64px );
	left: auto;
	z-index: 3;
	display: flex;
	gap: 24px;
	padding: 0;
	color: var( --jmeks-features-nav-color, #fff );
}

.jmeks-features--nav-left.jmeks-slider-active.jmeks-slider-fading > .jmeks-slider > .jmeks-slider__nav {
	right: auto;
	left: var( --jmeks-features-nav-inset, 64px );
}

/* Hello Elementor paints every button pink with padding and a border. */
.jmeks-features .jmeks-slider__nav .jmeks-slider__prev,
.jmeks-features .jmeks-slider__nav .jmeks-slider__next,
.jmeks-features .jmeks-slider__nav .jmeks-slider__prev:hover,
.jmeks-features .jmeks-slider__nav .jmeks-slider__next:hover,
.jmeks-features .jmeks-slider__nav .jmeks-slider__prev:focus,
.jmeks-features .jmeks-slider__nav .jmeks-slider__next:focus {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: inherit;
	cursor: pointer;
}

.jmeks-features .jmeks-slider__nav .jmeks-slider__prev:hover,
.jmeks-features .jmeks-slider__nav .jmeks-slider__next:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.jmeks-features .jmeks-slider__nav .jmeks-slider__prev:focus-visible,
.jmeks-features .jmeks-slider__nav .jmeks-slider__next:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
}

.jmeks-features .jmeks-slider__nav .is-disabled {
	display: none;
}
