/* Section: Before/After */
.websly-before-after {
	display: flex;
	flex-direction: column;
	gap: var(--websly-space-2xl);
}

.websly-before-after__item {
	position: relative;
}

.websly-before-after__pairs {
	display: flex;
	flex-direction: column;
	gap: var(--websly-space-2xl);
}

.websly-before-after__pair {
	position: relative;
	margin: 0;
}

.websly-before-after__images {
	position: relative;
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--websly-space-md);
	margin-top: var(--websly-space-sm);
}

@media (min-width: 45rem) {
	.websly-before-after__images {
		grid-template-columns: 1fr 1fr;
	}
}

.websly-before-after__before,
.websly-before-after__after {
	position: relative;
	aspect-ratio: var(--websly-ba-ratio, var(--ba-aspect, 4 / 3));
	overflow: hidden;
	border-radius: var(--websly-ba-radius, var(--websly-radius-lg));
}

.websly-before-after__before img,
.websly-before-after__after img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.websly-before-after__caption {
	margin-top: var(--websly-space-xs);
	color: var(--websly-color-text);
	font-size: var(--websly-text-sm);
	opacity: 0.8;
}

.websly-badge {
	position: absolute;
	top: var(--websly-ba-label-offset, var(--websly-space-sm));
	left: var(--websly-ba-label-offset, var(--websly-space-sm));
	background: var(--websly-color-surface);
	color: var(--websly-color-text);
	padding: var(--websly-space-2xs) var(--websly-space-sm);
	border-radius: var(--websly-radius-sm);
	font-size: var(--websly-text-xs);
	font-weight: var(--websly-font-weight-heading);
	z-index: 3;
	pointer-events: none;
	box-shadow: var(--websly-shadow-sm);
}

/*
 * The after-badge is right-anchored everywhere by default (not just in
 * slider mode) so a mode transition never has to move it — grid's own
 * 2-column layout already reads fine with "Before" top-left of the left
 * image and "After" top-right of the right one, and every other mode
 * simply inherits the same corner instead of relocating it (T32: this used
 * to only apply once `.js` + slider activated, which meant every page load
 * repositioned it mid-flight and measured as real CLS). `reveal` is the one
 * mode that overrides it back to match `before`'s corner, because there
 * both layers occupy the exact same box and the badge should swap text in
 * place, not jump.
 */
.websly-before-after__after .websly-badge {
	left: auto;
	right: var(--websly-ba-label-offset, var(--websly-space-sm));
}

/* The slider control only ever does something in `slider` mode with JS
   active; everywhere else it's a dead native control, so it stays hidden
   by default and is re-enabled only inside the scoped slider-mode block
   below. */
.websly-before-after__slider {
	display: none;
}

/* View-full-size affordance (D21-T11.2 lightbox reuse, T32 S6): a small
   corner control on every pair, in every mode, so dragging/hovering/
   swiping the pair itself never has to double as "open the viewer". The
   second, visually-hidden anchor exists only so the delegated lightbox's
   anchor list carries the after image too — prev/next then cycles the
   whole pair set, not just the before shot of each pair. */
.websly-before-after__expand {
	position: absolute;
	bottom: var(--websly-space-sm);
	right: var(--websly-space-sm);
	z-index: 11;
	width: 2.25rem;
	height: 2.25rem;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--websly-color-surface);
	border-radius: var(--websly-radius-pill);
	box-shadow: var(--websly-shadow-sm);
}

.websly-before-after__expand::before {
	content: '';
	width: 1rem;
	height: 1rem;
	background-color: var(--websly-color-text);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7'/%3E%3C/svg%3E");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.websly-before-after__expand--hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
}

/* Carousel prev/next: only rendered by PHP in carousel mode, but still
   hidden without JS (no handler exists to scroll the track, and without
   `.js` the track itself isn't a scroll-snap row — see below). */
.websly-before-after__nav {
	display: none;
}

.js .websly-before-after__pairs--carousel ~ .websly-before-after__nav {
	display: inline-flex;
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 9;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: var(--websly-radius-pill);
	background-color: var(--websly-color-surface);
	border: 1px solid var(--websly-color-border);
	box-shadow: var(--websly-shadow-md);
	font-size: var(--websly-text-lg);
	line-height: 1;
	cursor: pointer;
}

.websly-before-after__nav--prev { left: var(--websly-space-sm); }
.websly-before-after__nav--next { right: var(--websly-space-sm); }

/* ---------------------------------------------------------------------
 * `slider` mode (JS-active) — the original draggable split view,
 * extended to iterate every pair. Keep the real <input type="range">;
 * it is keyboard-operable, screen-reader-labelled and touch-native for
 * free (T32 stop condition: do not replace it with a pointer-drag
 * handler).
 * ------------------------------------------------------------------- */
.js .websly-before-after__pairs--slider .websly-before-after__images {
	position: relative;
	width: 100%;
	display: block;
	overflow: hidden;
	aspect-ratio: var(--websly-ba-ratio, var(--ba-aspect, 16 / 9));
	user-select: none;
	border-radius: var(--websly-ba-radius, var(--websly-radius-lg));
	border: 1px solid var(--websly-color-border);
	box-shadow: var(--websly-shadow-md);
}

.js .websly-before-after__pairs--slider .websly-before-after__before,
.js .websly-before-after__pairs--slider .websly-before-after__after {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	margin: 0;
}

/* The top image container is clipped.
   Using inset() is extremely clean because --reveal goes from 0% to 100%.
   If Before is on the left and After on the right, and After is on top:
   After is on top and visible on the right, so we clip its left part.
   Thus, clip-path: inset(0 0 0 var(--reveal, 50%)).
*/
.js .websly-before-after__pairs--slider .websly-before-after__after {
	clip-path: inset(0 0 0 var(--reveal, 50%));
	z-index: 2;
}

.js .websly-before-after__pairs--slider .websly-before-after__before {
	z-index: 1;
}

/* The slider input overlays the entire container */
.js .websly-before-after__pairs--slider .websly-before-after__slider {
	display: block;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	z-index: 10;
	cursor: ew-resize;
	-webkit-tap-highlight-color: transparent;
}

/* Visual divider line */
.js .websly-before-after__pairs--slider [data-websly-ba]::after {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--reveal, 50%);
	width: 4px;
	background-color: var(--websly-ba-handle-color, var(--websly-color-surface));
	z-index: 5;
	transform: translateX(-50%);
	pointer-events: none;
	box-shadow: var(--websly-shadow-md);
}

/* Visual slider handle button */
.js .websly-before-after__pairs--slider [data-websly-ba]::before {
	content: '';
	position: absolute;
	top: 50%;
	left: var(--reveal, 50%);
	width: var(--websly-ba-handle-size, 3rem);
	height: var(--websly-ba-handle-size, 3rem);
	background-color: var(--websly-ba-handle-color, var(--websly-color-surface));
	border: 3px solid var(--websly-color-border);
	border-radius: var(--websly-radius-pill);
	z-index: 6;
	transform: translate(-50%, -50%);
	pointer-events: none;
	box-shadow: var(--websly-shadow-lg);
	transition: transform 150ms ease, border-color 150ms ease;
}

/*
 * Arrow glyph on the handle, masked (not painted via background-image) so
 * its fill tracks --websly-color-text like every other themed element —
 * an SVG referenced via background-image can't consume CSS custom
 * properties for its own stroke, so a hardcoded stroke colour would be
 * stuck in the parent's neutral default on every child brand (A4).
 */
.js .websly-before-after__pairs--slider .websly-before-after__handle-icon {
	content: '';
	position: absolute;
	top: 50%;
	left: var(--reveal, 50%);
	width: 1.25rem;
	height: 1.25rem;
	z-index: 7;
	transform: translate(-50%, -50%);
	pointer-events: none;
	background-color: var(--websly-color-text);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 18-6-6 6-6M16 6l6 6-6 6'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 18-6-6 6-6M16 6l6 6-6 6'/%3E%3C/svg%3E");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

/* Hover effect on custom handle */
.js .websly-before-after__pairs--slider [data-websly-ba]:hover::before {
	transform: translate(-50%, -50%) scale(1.1);
	border-color: var(--websly-color-accent);
}

.js .websly-before-after__pairs--slider [data-websly-ba]:hover .websly-before-after__handle-icon {
	transform: translate(-50%, -50%) scale(1.1);
}

/* Focus and active styles mapped to the custom handle */
.js .websly-before-after__pairs--slider [data-websly-ba]:focus-within::before {
	transform: translate(-50%, -50%) scale(1.1);
	border-color: var(--websly-color-primary);
	box-shadow: 0 0 0 2px var(--websly-color-surface), 0 0 0 4px var(--websly-color-primary);
}

.js .websly-before-after__pairs--slider [data-websly-ba]:focus-within .websly-before-after__handle-icon {
	transform: translate(-50%, -50%) scale(1.1);
}

/* Badge corners already match the unscoped default (before=left, after=right) — nothing to override here. */

/* ---------------------------------------------------------------------
 * `reveal` mode (JS-active) — before image; after cross-fades in on
 * hover, or on tap on touch devices (main.js toggles .is-revealed).
 * ------------------------------------------------------------------- */
.js .websly-before-after__pairs--reveal .websly-before-after__images {
	position: relative;
	width: 100%;
	display: block;
	overflow: hidden;
	aspect-ratio: var(--websly-ba-ratio, var(--ba-aspect, 4 / 3));
	border-radius: var(--websly-ba-radius, var(--websly-radius-lg));
	border: 1px solid var(--websly-color-border);
	box-shadow: var(--websly-shadow-md);
}

.js .websly-before-after__pairs--reveal .websly-before-after__before,
.js .websly-before-after__pairs--reveal .websly-before-after__after {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	margin: 0;
}

/*
 * Both layers need an explicit z-index, not just `after`: a positioned
 * element with z-index:auto creates no stacking context of its own, so its
 * `.websly-badge` child (z-index:3) escapes to the nearest ancestor that
 * does and gets compared directly against `after`'s z-index there — 3 beats
 * 2 and "Before"'s badge wins the whole stack even though its image
 * correctly stays underneath. Giving `before` its own stacking context
 * (any explicit z-index) traps its badge locally, same as `after`.
 */
.js .websly-before-after__pairs--reveal .websly-before-after__before {
	z-index: 1;
}

.js .websly-before-after__pairs--reveal .websly-before-after__after {
	opacity: 0;
	z-index: 2;
	transition: opacity 300ms ease;
}

.js .websly-before-after__pairs--reveal .websly-before-after__pair:hover .websly-before-after__after,
.js .websly-before-after__pairs--reveal .websly-before-after__pair:focus-within .websly-before-after__after,
.js .websly-before-after__pairs--reveal .websly-before-after__pair.is-revealed .websly-before-after__after {
	opacity: 1;
}

/* Both layers occupy the exact same box here, so the badge should swap
   text in place on the same corner, not relocate to the default right side. */
.js .websly-before-after__pairs--reveal .websly-before-after__after .websly-badge {
	left: var(--websly-ba-label-offset, var(--websly-space-sm));
	right: auto;
}

/* ---------------------------------------------------------------------
 * `carousel` mode (JS-active) — one horizontal scroll-snap track, each
 * slide a complete before→after pair (rendered as the grid presentation
 * so it also works if the pair itself needs no drag/hover mechanics).
 * ------------------------------------------------------------------- */
.js .websly-before-after__pairs--carousel {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
}

.js .websly-before-after__pairs--carousel .websly-before-after__pair {
	flex: 0 0 100%;
	scroll-snap-align: start;
}

@media (prefers-reduced-motion: no-preference) {
	.js .websly-before-after__pairs--carousel {
		scroll-behavior: smooth;
	}
}

/* ---------------------------------------------------------------------
 * `scroll` mode (JS-active) — the reveal line driven by scroll progress
 * (main.js, IntersectionObserver + a scroll listener). Wrapping the
 * whole thing in `prefers-reduced-motion: no-preference` is what makes
 * it fall through to the unscoped grid rules above under `reduce` — a
 * scroll-driven wipe is exactly the effect a motion-sensitive visitor is
 * asking not to receive (T32 acceptance criterion, not a nicety).
 * ------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.js .websly-before-after__pairs--scroll .websly-before-after__images {
		position: relative;
		width: 100%;
		display: block;
		overflow: hidden;
		aspect-ratio: var(--websly-ba-ratio, var(--ba-aspect, 16 / 9));
		border-radius: var(--websly-ba-radius, var(--websly-radius-lg));
		border: 1px solid var(--websly-color-border);
		box-shadow: var(--websly-shadow-md);
	}

	.js .websly-before-after__pairs--scroll .websly-before-after__before,
	.js .websly-before-after__pairs--scroll .websly-before-after__after {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		margin: 0;
	}

	.js .websly-before-after__pairs--scroll .websly-before-after__after {
		clip-path: inset(0 0 0 var(--reveal, 0%));
		z-index: 2;
	}

	.js .websly-before-after__pairs--scroll .websly-before-after__before {
		z-index: 1;
	}
}

/* ---------------------------------------------------------------------
 * `stacked` mode (D99 §3.2, JS-active) — two horizontal filmstrip tracks,
 * before above after. Gated behind `prefers-reduced-motion: no-preference`
 * like `scroll` above, not just `.js` (D99 §3.3): case 2's lockstep sync
 * (main.js) moves the track the visitor never touched, which is the same
 * class of imposed motion `scroll`'s reveal-line already opts out of —
 * both land on the unscoped grid presentation with no second code path,
 * case 1 (independent galleries) included, so there is exactly one fallback
 * everywhere rather than a partially-synced third state.
 * ------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.js .websly-before-after__pairs--stacked {
		display: flex;
		flex-direction: column;
		gap: var(--websly-ba-gap, var(--websly-space-md));
	}

	.js .websly-before-after__pairs--stacked .websly-before-after__row {
		display: flex;
		flex-wrap: nowrap;
		align-items: flex-start;
		gap: var(--websly-ba-gap, var(--websly-space-sm));
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		scroll-behavior: smooth;
	}

	.js .websly-before-after__pairs--stacked .websly-before-after__pair {
		flex: 0 0 min(70vw, 14rem);
		margin: 0;
	}

	.js .websly-before-after__pairs--stacked .websly-before-after__before,
	.js .websly-before-after__pairs--stacked .websly-before-after__after {
		width: 100%;
		height: 100%;
	}
}

/* ---------------------------------------------------------------------
 * D99 §4 Layer 1/2 — the differentiation seam. frame/labels/aspect are
 * per-row fields (no code, editor-selectable); the six --websly-ba-*
 * custom properties above are what a child theme sets to restyle every
 * before/after section on the site at once, without forking anything. The
 * rules below are the parent's mechanism plus a neutral default (D2 tokens
 * only) for each frame/labels value — never a client's own colour/shadow.
 * ------------------------------------------------------------------- */

.websly-before-after--aspect-4-3  { --websly-ba-ratio: 4 / 3; }
.websly-before-after--aspect-3-4  { --websly-ba-ratio: 3 / 4; }
.websly-before-after--aspect-1-1  { --websly-ba-ratio: 1 / 1; }
.websly-before-after--aspect-16-9 { --websly-ba-ratio: 16 / 9; }

/* `flush`: edge-to-edge — no rounded corners, no plate border/shadow. */
.websly-before-after--frame-flush {
	--websly-ba-radius: 0;
}
.websly-before-after--frame-flush .websly-before-after__images,
.websly-before-after--frame-flush .websly-before-after__before,
.websly-before-after--frame-flush .websly-before-after__after {
	border: none;
	box-shadow: none;
}

/* `card`: a mounted-print look — the whole pair (or, in `stacked`, each
   single image) sits on a padded, bordered mat using the same tokens the
   `plate` treatment already reads elsewhere in this file. */
.websly-before-after--frame-card .websly-before-after__pair {
	padding: var(--websly-space-sm);
	background: var(--websly-color-surface);
	border: 1px solid var(--websly-color-border);
	border-radius: var(--websly-ba-radius, var(--websly-radius-lg));
	box-shadow: var(--websly-shadow-md);
}

/* `corner`: the label text stays, the badge chip (background/shadow/
   padding) doesn't — flush text in the corner instead of a raised pill. */
.websly-before-after--labels-corner .websly-badge {
	background: transparent;
	box-shadow: none;
	padding: 0;
}

/* `none`: no Before/After label anywhere in the section. */
.websly-before-after--labels-none .websly-badge {
	display: none;
}
