/**
 * KISS LocoMotion — scaffold.
 *
 * Structure only. There is deliberately no theme layer: the visual IS the content, and the
 * only cosmetics here are the stage background and the scroll hint.
 *
 * Two families of custom property:
 *   --kiss-loco-*   configuration, written per instance by the renderer (sizes, fit, focal).
 *   --loco-*        the published signal, written every frame by the engine (progress, frame).
 *                   The prefix is configurable per widget; `loco` is the default and what the
 *                   stock .loco-* classes below read.
 *
 * Cascade: this file at (0,1,0) / (0,2,0); site CSS should use
 * `.elementor-widget-kiss_locomotion .kiss-loco` (0,2,0) to win regardless of load order.
 */

.kiss-loco {
	position: relative;
	width: 100%;
	--kiss-loco-stage-h: 70vh;
	--kiss-loco-distance: 300vh;
	--kiss-loco-hold: 0px;
	--kiss-loco-top: 0px;
	--kiss-loco-fit: cover;
	--kiss-loco-focal: 50% 50%;
	/* The screen height for Fill. 100svh below where supported: the height a phone never covers with its toolbars. */
	--kiss-loco-vh: 100vh;
	--kiss-loco-x: 0;
	--loco-progress: 0;
	--loco-frame: 0;
}

/*
 * The widget must have a definite width inside an Elementor flex container. Under 768px Elementor
 * sets `flex-wrap: wrap` on every container, and a wrapped flex line does not hand a stretched
 * item a definite width, so a height that comes from `aspect-ratio` alone ("Match the frames",
 * the editor, reduced motion) is computed at width 0: the widget measures 0px and the next section
 * sits on top of the stage. Elementor's own video and maps widgets carry the same `width: 100%`
 * for the same reason. Its Width control writes `width` at (0,3,0) and still wins.
 */
.e-con .elementor-widget-kiss_locomotion {
	width: var(--container-widget-width, 100%);
}

/* A shortcode inside another widget (Text Editor, Shortcode, HTML): the same rule, where :has() exists. */
.e-con .elementor-widget:has(.kiss-loco) {
	width: var(--container-widget-width, 100%);
}

.kiss-loco *,
.kiss-loco *::before,
.kiss-loco *::after {
	box-sizing: border-box;
}

/* The track: tall, invisible. Its height IS the scrub duration. */
.kiss-loco .kiss-loco-track {
	position: relative;
	width: 100%;
	height: calc(var(--kiss-loco-distance) + var(--kiss-loco-hold));
}

@supports (height: 100svh) {
	.kiss-loco {
		--kiss-loco-vh: 100svh;
	}
}

/* Under a Fill stage the track wears the stage background, so the sliver a phone uncovers when its toolbars slide away matches the stage. */
.kiss-loco .kiss-loco-track {
	background: var(--kiss-loco-track-bg, transparent);
}

/* The stage: pinned, and what you see. */
.kiss-loco .kiss-loco-stage {
	position: -webkit-sticky;
	position: sticky;
	top: var(--kiss-loco-top);
	width: 100%;
	height: var(--kiss-loco-stage-h);
	/* "Match the frames": height auto and the frames' ratio, so the stage is as tall as they are at full width. */
	aspect-ratio: var(--kiss-loco-stage-ar, auto);
	/* …never taller than the screen under the header while pinned (the renderer sets it for that mode). */
	max-height: var(--kiss-loco-stage-max, none);
	overflow: hidden;
	margin: 0;
	background: var(--kiss-loco-stage-bg, transparent);
}

.kiss-loco .kiss-loco-poster,
.kiss-loco .kiss-loco-canvas,
.kiss-loco .kiss-loco-video {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: block;
	margin: 0;
	padding: 0;
	border: 0;
	max-width: none;
}

.kiss-loco .kiss-loco-poster,
.kiss-loco .kiss-loco-video {
	object-fit: var(--kiss-loco-fit);
	object-position: var(--kiss-loco-focal);
}

/*
 * The poster paints first and stays until the engine has drawn something. Then it steps
 * behind: hidden rather than removed, so it is still there for print, for a canvas that
 * loses its context, and for the reduced-motion rule below.
 */
.kiss-loco .kiss-loco-canvas,
.kiss-loco .kiss-loco-video {
	opacity: 0;
}

.kiss-loco.kiss-loco--ready .kiss-loco-canvas,
.kiss-loco.kiss-loco--ready .kiss-loco-video {
	opacity: 1;
}

.kiss-loco.kiss-loco--ready .kiss-loco-poster {
	visibility: hidden;
}

/* Script-driven pinning: the stage is a normal block and ScrollTrigger moves it. */
.kiss-loco.kiss-loco--pin-js .kiss-loco-stage {
	position: relative;
	top: auto;
}

/*
 * Modes where nothing scrubs: no track, no pin. The section is exactly as tall as the stage.
 * `--still` is the reduced-motion / "first frame only" case; `--once` plays in place;
 * `--editor` is the Elementor preview, which never attempts live scroll.
 */
.kiss-loco.kiss-loco--still .kiss-loco-track,
.kiss-loco.kiss-loco--once .kiss-loco-track,
.kiss-loco.kiss-loco--editor .kiss-loco-track {
	height: auto;
}

.kiss-loco.kiss-loco--still .kiss-loco-stage,
.kiss-loco.kiss-loco--once .kiss-loco-stage,
.kiss-loco.kiss-loco--editor .kiss-loco-stage {
	position: relative;
	top: auto;
}

/* Not pinned, so the whole picture can simply be as tall as it is (the editor keeps the page's cap). */
.kiss-loco.kiss-loco--still .kiss-loco-stage,
.kiss-loco.kiss-loco--once .kiss-loco-stage {
	max-height: none;
}

.kiss-loco.kiss-loco--still .kiss-loco-canvas,
.kiss-loco.kiss-loco--still .kiss-loco-video {
	display: none;
}

/*
 * "Tap through the steps" (a phone policy): no track, no pin, the stage is a tap target and a
 * swipe surface; vertical panning stays the browser's. The scroll hint would say "scroll", so
 * it leaves.
 */
.kiss-loco.kiss-loco--steps .kiss-loco-track {
	height: auto;
}

.kiss-loco.kiss-loco--steps .kiss-loco-stage {
	position: relative;
	top: auto;
	cursor: pointer;
	touch-action: pan-y;
	-webkit-tap-highlight-color: transparent;
}

.kiss-loco.kiss-loco--steps .kiss-loco-stage:focus-visible {
	outline: 2px solid var(--kiss-loco-accent, #f5a623);
	outline-offset: -2px;
}

.kiss-loco.kiss-loco--steps button.kiss-loco-hint {
	display: none;
}

/*
 * "Pin the next section too": the widget's own track collapses (so the stage and the section
 * after it are adjacent before any script runs) and the engine wraps the widget's container and
 * the next N sections in a sticky group inside a runway that is distance + hold taller than the
 * group. Same numbers, same anchors; only what is pinned changes. Reduced motion: no runway.
 */
.kiss-loco.kiss-loco--group .kiss-loco-track {
	height: auto;
}

.kiss-loco.kiss-loco--group .kiss-loco-stage {
	position: relative;
	top: auto;
}

.kiss-loco-runway {
	position: relative;
	width: 100%;
	--kiss-loco-run: 0px;
	--kiss-loco-top: 0px;
}

.kiss-loco-runway::after {
	content: "";
	display: block;
	height: var(--kiss-loco-run);
}

.kiss-loco-group {
	position: -webkit-sticky;
	position: sticky;
	top: var(--kiss-loco-top);
	width: 100%;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco-runway::after {
		display: none;
	}

	.kiss-loco-group {
		position: static;
	}
}

.kiss-loco.kiss-loco--still .kiss-loco-poster {
	visibility: visible;
}

/*
 * Reduced motion: a static image with its copy, and the page still reads. This is CSS, not
 * a class the script sets, so it is right before any script runs and right without one.
 */
@media (prefers-reduced-motion: reduce) {
	.kiss-loco .kiss-loco-track {
		height: auto;
	}

	.kiss-loco .kiss-loco-stage {
		position: relative;
		top: auto;
		max-height: none;
	}

	.kiss-loco .kiss-loco-canvas,
	.kiss-loco .kiss-loco-video {
		display: none;
	}

	.kiss-loco .kiss-loco-poster {
		visibility: visible;
	}
}

/* The visual wrapper: fills the stage; the poster/canvas/video fill it. */
.kiss-loco .kiss-loco-visual {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

/* ------------------------------------------------------------------ *
 * Image layers — the DOM alternative to the canvas.
 *
 * One <img> per frame, all stacked; the engine publishes --kiss-loco-x (progress × (n − 1))
 * and each layer's opacity is 1 − |x − i|, clamped: frame i is solid at x = i and gone a
 * whole frame away, so adjacent layers cross-fade with nothing drawn by script. max(a, −a)
 * is abs() for browsers that lack it. At x = 0 (no script, reduced motion) only layer 0
 * shows, which is the poster.
 * ------------------------------------------------------------------ */

.kiss-loco .kiss-loco-layer {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: block;
	margin: 0;
	padding: 0;
	border: 0;
	max-width: none;
	object-fit: var(--kiss-loco-fit);
	object-position: var(--kiss-loco-focal);
	/*
	 * Cross-fade with no dip: layer i fades IN over x ∈ [i − 1, i] on top of the layers below it,
	 * which stay solid until they are covered; layer 0 is always solid. Two half-transparent
	 * frames over the page background (the old 1 − |x − i|) let the background bleed through at
	 * the midpoint — that was the "white in the cross-fade".
	 * --kiss-loco-fade (0.1–1, default 1) is how much of the slot the fade takes: at 0.3, layer i
	 * fades in over x ∈ [i − 0.3, i] and the frame before it holds pure for the first 70%.
	 */
	opacity: clamp(0, calc((var(--kiss-loco-x, 0) - var(--i, 0) + var(--kiss-loco-fade, 1)) / var(--kiss-loco-fade, 1)), 1);
}

/* A placed layer sits at its own box inside the visual, drawn whole (meet), never cropped. */
.kiss-loco .kiss-loco-layer.kiss-loco-layer--placed {
	object-fit: contain;
	object-position: center center;
}

/* A layer with no src yet (deferred) must not paint a broken-image glyph. */
/*
 * A portrait set (a second sequence for phones and upright tablets) and a tablet set (a third, for
 * tablets held upright): their layers 2–N are in the DOM from the start and hidden here; the per-instance CSS shows them and hides the landscape
 * layers under the same media query the <picture> source and the engine use. Layer 1 of both
 * sets is the one <picture>, so the browser fetches one poster, never two.
 */
.kiss-loco .kiss-loco-layer--alt,
.kiss-loco .kiss-loco-layer--tab {
	display: none;
}

.kiss-loco picture {
	display: contents;
}

.kiss-loco .kiss-loco-layer:not([src]) {
	visibility: hidden;
}

/*
 * In sequence: a frame is solid until 0.35 away from its position and gone by 0.5, so the
 * outgoing drawing has left before the incoming one arrives — never two boats at two heights.
 * Swap: a hard cut at the midpoint.
 */
.kiss-loco.kiss-loco--blend-seq .kiss-loco-layer {
	opacity: clamp(0, calc((0.5 - max(var(--kiss-loco-x, 0) - var(--i, 0), var(--i, 0) - var(--kiss-loco-x, 0))) / 0.15), 1);
}

.kiss-loco.kiss-loco--blend-none .kiss-loco-layer {
	opacity: clamp(0, calc((0.5 - max(var(--kiss-loco-x, 0) - var(--i, 0), var(--i, 0) - var(--kiss-loco-x, 0))) * 1000), 1);
}

/* ------------------------------------------------------------------ *
 * Layouts: copy beside or below the visual.
 *
 * The stage becomes a grid of named areas — heading, copy, visual, rail — and the visual
 * stops being absolute. The renderer emits the phone stacking order per instance with the
 * site's real mobile breakpoint.
 * ------------------------------------------------------------------ */

.kiss-loco.kiss-loco--layout-beside .kiss-loco-stage,
.kiss-loco.kiss-loco--layout-below .kiss-loco-stage {
	display: grid;
	padding: var(--kiss-loco-stage-pad, 0);
}

.kiss-loco.kiss-loco--layout-beside .kiss-loco-stage {
	grid-template-columns: var(--kiss-loco-copy-w, 36%) minmax(0, 1fr);
	grid-template-rows: auto minmax(0, 1fr) auto;
	grid-template-areas:
		"heading heading"
		"copy    visual"
		"rail    rail";
	column-gap: var(--kiss-loco-copy-gap, 32px);
}

.kiss-loco.kiss-loco--layout-beside.kiss-loco--copy-right .kiss-loco-stage {
	grid-template-columns: minmax(0, 1fr) var(--kiss-loco-copy-w, 36%);
	grid-template-areas:
		"heading heading"
		"visual  copy"
		"rail    rail";
}

.kiss-loco.kiss-loco--layout-below .kiss-loco-stage {
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: auto minmax(0, 1fr) auto auto;
	grid-template-areas:
		"heading"
		"visual"
		"copy"
		"rail";
}

.kiss-loco.kiss-loco--layout-beside .kiss-loco-visual,
.kiss-loco.kiss-loco--layout-below .kiss-loco-visual {
	aspect-ratio: var(--kiss-loco-visual-ar, auto);
}

.kiss-loco.kiss-loco--layout-beside .kiss-loco-stage,
.kiss-loco.kiss-loco--layout-below .kiss-loco-stage {
	/* In the copy layouts the ratio belongs to the visual, not the whole grid. */
	--kiss-loco-visual-ar: var(--kiss-loco-stage-ar, auto);
	aspect-ratio: auto;
}

.kiss-loco.kiss-loco--layout-beside .kiss-loco-visual,
.kiss-loco.kiss-loco--layout-below .kiss-loco-visual {
	grid-area: visual;
	position: relative;
	width: auto;
	height: auto;
	min-height: 0;
	min-width: 0;
}

.kiss-loco.kiss-loco--layout-beside .kiss-loco-captions,
.kiss-loco.kiss-loco--layout-below .kiss-loco-captions {
	grid-area: copy;
	position: relative;
	width: auto;
	height: auto;
	min-width: 0;
	display: grid;
	align-content: center;
	justify-content: start;
	/* The copy column honors "Inset from the edge" too, not only captions over the stage. */
	padding: var(--kiss-loco-copy-pad, 0 var(--kiss-loco-overlay-pad, 24px));
	--kiss-loco-cap-bg: transparent;
	--kiss-loco-cap-pad: 0;
	--kiss-loco-cap-radius: 0;
	--kiss-loco-cap-align: left;
	--kiss-loco-cap-max-w: 28em;
}

.kiss-loco.kiss-loco--layout-below .kiss-loco-captions {
	justify-content: center;
	--kiss-loco-cap-align: center;
}

.kiss-loco .kiss-loco-heading {
	grid-area: heading;
	text-align: center;
	padding: var(--kiss-loco-heading-pad, 24px 24px 0);
	position: relative;
	z-index: 2;
}

/*
 * In the visual-only layout the heading floats over the stage: nine positions
 * (.kiss-loco-heading--x-* / --y-*), inset from the named edges by --kiss-loco-heading-inset.
 */
.kiss-loco.kiss-loco--layout-stage .kiss-loco-heading {
	position: absolute;
	top: var(--kiss-loco-heading-inset, 0px);
	left: 0;
	right: 0;
	pointer-events: none;
}

.kiss-loco.kiss-loco--layout-stage .kiss-loco-heading--y-center {
	top: 50%;
	transform: translateY(-50%);
}

.kiss-loco.kiss-loco--layout-stage .kiss-loco-heading--y-bottom {
	top: auto;
	bottom: var(--kiss-loco-heading-inset, 0px);
}

.kiss-loco.kiss-loco--layout-stage .kiss-loco-heading--x-left {
	text-align: left;
	right: auto;
	left: var(--kiss-loco-heading-inset, 0px);
}

.kiss-loco.kiss-loco--layout-stage .kiss-loco-heading--x-right {
	text-align: right;
	left: auto;
	right: var(--kiss-loco-heading-inset, 0px);
}

.kiss-loco .kiss-loco-eyebrow {
	margin: 0 0 4px;
	color: var(--kiss-loco-eyebrow-color, var(--kiss-loco-accent, #f5a623));
	font-size: var(--kiss-loco-eyebrow-size, 0.875rem);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.kiss-loco .kiss-loco-title {
	margin: 0;
	color: var(--kiss-loco-title-color, inherit);
	font-size: var(--kiss-loco-title-size, clamp(2rem, 6vw, 4.5rem));
	font-weight: 800;
	line-height: 1;
	letter-spacing: 0.01em;
	text-transform: uppercase;
}

.kiss-loco .kiss-loco-title span {
	color: var(--kiss-loco-accent, #f5a623);
}

/* Step copy: kicker, title, text. Each names its own color. */
.kiss-loco .kiss-loco-cap-kicker {
	margin: 0 0 6px;
	color: var(--kiss-loco-kicker-color, var(--kiss-loco-accent, #f5a623));
	font-size: var(--kiss-loco-kicker-size, 0.8125rem);
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.kiss-loco .kiss-loco-cap-title {
	margin: 0 0 8px;
	color: var(--kiss-loco-cap-color, #fff);
	font-size: var(--kiss-loco-cap-title-size, 2.25rem);
	font-weight: 800;
	line-height: 1.05;
}

.kiss-loco .kiss-loco-cap-text {
	color: var(--kiss-loco-cap-color, #fff);
}

/* ------------------------------------------------------------------ *
 * The step rail: one <button> per step, a line between, labels beneath.
 * Element-plus-class scope, like every button here.
 * ------------------------------------------------------------------ */

.kiss-loco .kiss-loco-rail {
	grid-area: rail;
	position: relative;
	z-index: 2;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	padding: var(--kiss-loco-rail-pad, 16px 24px 24px);
	pointer-events: none;
}

.kiss-loco.kiss-loco--layout-stage .kiss-loco-rail {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
}

.kiss-loco button.kiss-loco-dot {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	width: var(--kiss-loco-rail-gap, 140px);
	margin: 0;
	padding: 6px 0 0;
	min-height: 44px;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var(--kiss-loco-rail-idle, rgba(255, 255, 255, 0.55));
	font: 700 11px/1.2 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-align: center;
	cursor: pointer;
	pointer-events: auto;
}

.kiss-loco button.kiss-loco-dot::before,
.kiss-loco button.kiss-loco-dot::after {
	content: none;
}

/*
 * The connecting line: drawn on each step's button, back to the previous dot, and sized from the
 * button's real width (the dots sit at the centers of equal buttons, so the previous center is
 * half a button to the left). A fixed length, hung off the dot, overran the previous dot as soon as
 * a phone squeezed the buttons, and grew with the active dot's scale. It stops short of both dots
 * by --kiss-loco-rail-line-gap, so each step reads as its own stop. The button's own ::before is
 * blanked above against kit styles; this rule is more specific and sets every property it uses.
 */
.kiss-loco button.kiss-loco-dot + button.kiss-loco-dot::before {
	content: "";
	position: absolute;
	top: 10px;
	left: calc(-50% + 4.5px + var(--kiss-loco-rail-line-gap, 8px));
	width: calc(100% - 9px - 2 * var(--kiss-loco-rail-line-gap, 8px));
	height: 1px;
	margin: 0;
	padding: 0;
	border: 0;
	background: var(--kiss-loco-rail-idle, rgba(255, 255, 255, 0.55));
	opacity: 0.6;
	transform: none;
	pointer-events: none;
}

.kiss-loco .kiss-loco-dot-mark {
	position: relative;
	display: block;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: currentColor;
	transition: transform 0.2s ease;
}

.kiss-loco .kiss-loco-dot-label {
	color: inherit;
	white-space: nowrap;
}

.kiss-loco button.kiss-loco-dot[aria-current] {
	color: var(--kiss-loco-rail-active, var(--kiss-loco-accent, #f5a623));
}

.kiss-loco button.kiss-loco-dot[aria-current] .kiss-loco-dot-mark {
	transform: scale(1.25);
}

.kiss-loco button.kiss-loco-dot:focus-visible {
	outline: 2px solid var(--kiss-loco-rail-active, var(--kiss-loco-accent, #f5a623));
	outline-offset: 2px;
}

/* Where nothing scrubs the rail is meaningless; the captions stack instead. */
.kiss-loco.kiss-loco--still .kiss-loco-rail {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco .kiss-loco-rail {
		display: none;
	}

	.kiss-loco .kiss-loco-dot-mark {
		transition: none;
	}
}

/* ------------------------------------------------------------------ *
 * Captions and watermark
 *
 * Both are overlays on the stage, placed with the nine-position classes. Captions read the
 * engine's internal --kiss-loco-p (always published on the root, whatever the public prefix
 * is) and each shows only while progress is inside its own --loco-from / --loco-to window.
 * ------------------------------------------------------------------ */

.kiss-loco .kiss-loco-captions,
.kiss-loco .kiss-loco-ripplemark {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: grid;
	pointer-events: none;
	padding: var(--kiss-loco-overlay-pad, 24px);
}

.kiss-loco .kiss-loco-caption {
	grid-area: 1 / 1;
	max-width: var(--kiss-loco-cap-max-w, 32em);
	margin: 0;
	padding: var(--kiss-loco-cap-pad, 12px 18px);
	color: var(--kiss-loco-cap-color, #fff);
	background: var(--kiss-loco-cap-bg, rgba(0, 0, 0, 0.55));
	border-radius: var(--kiss-loco-cap-radius, 6px);
	font-size: var(--kiss-loco-cap-size, 1.125rem);
	line-height: 1.4;
	text-align: var(--kiss-loco-cap-align, center);
	pointer-events: auto;
	/*
	 * A hard window, inclusive at both edges: the first step's copy is on screen at progress 0
	 * (the section at rest) and the last step's stays through the hold at progress 1. Without
	 * the 0.002 both ends compute to exactly 0 and the section rests with no copy at all.
	 */
	opacity: clamp(0, calc((min(var(--kiss-loco-p, 0) - var(--loco-from, 0), var(--loco-to, 1) - var(--kiss-loco-p, 0)) + 0.002) * 1000), 1);
}

.kiss-loco .kiss-loco-caption > :first-child { margin-top: 0; }
.kiss-loco .kiss-loco-caption > :last-child { margin-bottom: 0; }

/* Caption text names its own color: inherited color loses to any theme rule on <p>. */
.kiss-loco .kiss-loco-caption p,
.kiss-loco .kiss-loco-caption span {
	color: inherit;
}

/*
 * The kicker and the step title are <p> elements too, so the rule above (0,2,1) outranked their
 * own color and spacing (0,2,0): a picked kicker color never showed, and any theme margin on <p>
 * could open the gaps. One class deeper (0,3,0) they win, and the gaps are two variables the
 * Style tab sets per device. The typography controls write at (0,3,0) and do not touch these.
 */
.kiss-loco .kiss-loco-caption .kiss-loco-cap-kicker {
	margin: 0 0 var(--kiss-loco-kicker-gap, 6px);
	color: var(--kiss-loco-kicker-color, var(--kiss-loco-accent, #f5a623));
}

.kiss-loco .kiss-loco-caption .kiss-loco-cap-title {
	margin: 0 0 var(--kiss-loco-title-gap, 8px);
}

.kiss-loco .kiss-loco-ripplemark {
	opacity: var(--kiss-loco-wm-o, 0.6);
}

.kiss-loco .kiss-loco-wm-img {
	width: var(--kiss-loco-wm-w, 12%);
	height: auto;
	display: block;
	max-width: 100%;
}

.kiss-loco .kiss-loco-wm-text {
	color: var(--kiss-loco-wm-color, #fff);
	font-size: var(--kiss-loco-wm-size, 0.875rem);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
	white-space: nowrap;
}

/*
 * The scroll hint. A real <button>, so it needs the element-plus-class scope: an Elementor kit
 * styles every button through `.elementor-kit-N button` (0,1,1), and a bare class loses.
 * Fades out over the first tenth of the scrub, in CSS.
 */
.kiss-loco button.kiss-loco-hint {
	position: absolute;
	left: 50%;
	bottom: var(--kiss-loco-hint-bottom, var(--kiss-loco-overlay-pad, 24px));
	transform: translateX(-50%) scale(var(--kiss-loco-hint-scale, 1));
	transform-origin: 50% 100%;
	z-index: 3;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	min-height: 0;
	width: auto;
	line-height: 1;
	cursor: pointer;
	opacity: clamp(0, calc(1 - var(--kiss-loco-p, 0) * 10), 1);
	pointer-events: auto;
}

/* Dark pill (default) and text-only carry their own look; "the site's button" is left to the kit. */
.kiss-loco button.kiss-loco-hint--pill,
.kiss-loco button.kiss-loco-hint--text {
	padding: 8px 14px;
	border: 0;
	border-radius: 999px;
	background: var(--kiss-loco-hint-bg, rgba(0, 0, 0, 0.45));
	color: var(--kiss-loco-hint-color, #fff);
	font: 600 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	box-shadow: none;
}

.kiss-loco button.kiss-loco-hint--text {
	padding: 4px 0;
	background: transparent;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.kiss-loco button.kiss-loco-hint--button {
	color: var(--kiss-loco-hint-color, inherit);
}

.kiss-loco button.kiss-loco-hint::before,
.kiss-loco button.kiss-loco-hint::after {
	content: none;
}

.kiss-loco button.kiss-loco-hint .kiss-loco-hint-arrow {
	width: 8px;
	height: 8px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translate(-2px, -2px);
	animation: kiss-loco-nudge 1.6s ease-in-out infinite;
}

@keyframes kiss-loco-nudge {
	0%, 100% { transform: rotate(45deg) translate(-2px, -2px); }
	50%      { transform: rotate(45deg) translate(1px, 1px); }
}

.kiss-loco.kiss-loco--still button.kiss-loco-hint,
.kiss-loco.kiss-loco--editor button.kiss-loco-hint {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco button.kiss-loco-hint .kiss-loco-hint-arrow {
		animation: none;
	}
}

/* Nine positions, shared by captions and watermark. */
.kiss-loco .kiss-loco-pos-left-top      { justify-content: start;  align-content: start; }
.kiss-loco .kiss-loco-pos-center-top    { justify-content: center; align-content: start; }
.kiss-loco .kiss-loco-pos-right-top     { justify-content: end;    align-content: start; }
.kiss-loco .kiss-loco-pos-left-center   { justify-content: start;  align-content: center; }
.kiss-loco .kiss-loco-pos-center-center { justify-content: center; align-content: center; }
.kiss-loco .kiss-loco-pos-right-center  { justify-content: end;    align-content: center; }
.kiss-loco .kiss-loco-pos-left-bottom   { justify-content: start;  align-content: end; }
.kiss-loco .kiss-loco-pos-center-bottom { justify-content: center; align-content: end; }
.kiss-loco .kiss-loco-pos-right-bottom  { justify-content: end;    align-content: end; }

/*
 * Where nothing scrubs (still, reduced motion), the captions cannot swap — so they leave the
 * stage and stack below it in reading order, every one visible. The copy still reads.
 */
.kiss-loco.kiss-loco--still .kiss-loco-captions {
	position: static;
	display: block;
	height: auto;
	padding: 0;
}

.kiss-loco.kiss-loco--still.kiss-loco--layout-beside .kiss-loco-stage,
.kiss-loco.kiss-loco--still.kiss-loco--layout-below .kiss-loco-stage {
	display: block;
	height: auto;
}

.kiss-loco.kiss-loco--still.kiss-loco--layout-beside .kiss-loco-visual,
.kiss-loco.kiss-loco--still.kiss-loco--layout-below .kiss-loco-visual {
	aspect-ratio: 16 / 9;
}

.kiss-loco.kiss-loco--still .kiss-loco-caption {
	opacity: 1;
	max-width: none;
	margin: 8px 0 0;
	border-radius: 0;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco .kiss-loco-captions {
		position: static;
		display: block;
		height: auto;
		padding: 0;
	}

	.kiss-loco.kiss-loco--layout-beside .kiss-loco-stage,
	.kiss-loco.kiss-loco--layout-below .kiss-loco-stage {
		display: block;
		height: auto;
	}

	.kiss-loco.kiss-loco--layout-beside .kiss-loco-visual,
	.kiss-loco.kiss-loco--layout-below .kiss-loco-visual {
		aspect-ratio: 16 / 9;
	}

	.kiss-loco .kiss-loco-caption {
		opacity: 1;
		max-width: none;
		margin: 8px 0 0;
		border-radius: 0;
	}
}

/* Editor-only notices. Never rendered on the front end. */
.kiss-loco-notice {
	margin: 0;
	padding: 12px 16px;
	border-left: 4px solid #72aee6;
	background: #f0f6fc;
	color: #1d2327;
	font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.kiss-loco-notice--warning {
	border-left-color: #dba617;
	background: #fcf9e8;
}

/* ------------------------------------------------------------------ *
 * Stock behaviors — the non-CSS path.
 *
 * Add one of these class names to any Elementor element (Advanced → CSS Classes) that sits
 * where the published variable reaches it (the widget publishes on its container or the
 * page — see Advanced → LocoMotion → Publish on). Tune with the --loco-from / --loco-to
 * window (0 → 1 of progress) on the same element.
 *
 * Each is a pure function of --loco-progress: no transitions, no JS, nothing to fight the
 * visitor's thumb.
 * ------------------------------------------------------------------ */

.loco-fade-in {
	opacity: clamp(0, calc((var(--loco-progress, 0) - var(--loco-from, 0)) / (var(--loco-to, 0.3) - var(--loco-from, 0))), 1);
}

.loco-fade-out {
	opacity: clamp(0, calc(1 - (var(--loco-progress, 0) - var(--loco-from, 0.7)) / (var(--loco-to, 1) - var(--loco-from, 0.7))), 1);
}

.loco-rise {
	opacity: clamp(0, calc((var(--loco-progress, 0) - var(--loco-from, 0)) / (var(--loco-to, 0.3) - var(--loco-from, 0))), 1);
	transform: translateY(calc((1 - clamp(0, calc((var(--loco-progress, 0) - var(--loco-from, 0)) / (var(--loco-to, 0.3) - var(--loco-from, 0))), 1)) * var(--loco-rise, 40px)));
}

.loco-parallax {
	transform: translateY(calc((0.5 - var(--loco-progress, 0)) * var(--loco-parallax, 80px)));
}

.loco-progress-bar {
	transform: scaleX(var(--loco-progress, 0));
	transform-origin: left center;
}

/* Visible only while progress is inside [--loco-from, --loco-to]. Caption sequences. */
.loco-step {
	opacity: clamp(0, calc(min(var(--loco-progress, 0) - var(--loco-from, 0), var(--loco-to, 1) - var(--loco-progress, 0)) * 1000), 1);
}

@media (prefers-reduced-motion: reduce) {
	.loco-fade-in,
	.loco-fade-out,
	.loco-rise,
	.loco-parallax,
	.loco-step {
		opacity: 1;
		transform: none;
	}

	.loco-progress-bar {
		transform: none;
	}
}

/*
 * Callouts: pins on the drawing. The engine sizes .kiss-loco-callouts to the drawing as it is
 * fitted (contain or cover, focal point) and marks it placed; a pin is a zero-size point at its
 * percentages with a dot, a line at an angle (--a) and a label at the line's end. The set for the
 * frame on show gets .is-on: the dot pops, the line draws out, the label fades in, the dot pulses.
 */
.kiss-loco .kiss-loco-callouts {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	z-index: 2;
	pointer-events: none;
	visibility: hidden;
}

.kiss-loco .kiss-loco-callouts.is-placed {
	visibility: visible;
}

.kiss-loco .kiss-loco-callout-set {
	position: absolute;
	inset: 0;
}

.kiss-loco .kiss-loco-pin {
	--kiss-loco-pin-len: clamp(36px, 5vw, 72px);
	--a: -35deg;
	--lx: calc(var(--kiss-loco-pin-len) * 0.819);
	--ly: calc(var(--kiss-loco-pin-len) * -0.574);
	--tx: 0%;
	position: absolute;
	width: 0;
	height: 0;
	color: var(--kiss-loco-pin-color, #fff);
}

.kiss-loco .kiss-loco-pin--up-left {
	--a: -145deg;
	--lx: calc(var(--kiss-loco-pin-len) * -0.819);
	--tx: -100%;
}

.kiss-loco .kiss-loco-pin--down-right {
	--a: 35deg;
	--ly: calc(var(--kiss-loco-pin-len) * 0.574);
}

.kiss-loco .kiss-loco-pin--down-left {
	--a: 145deg;
	--lx: calc(var(--kiss-loco-pin-len) * -0.819);
	--ly: calc(var(--kiss-loco-pin-len) * 0.574);
	--tx: -100%;
}

.kiss-loco .kiss-loco-pin-dot {
	position: absolute;
	left: -6px;
	top: -6px;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--kiss-loco-pin-dot, var(--kiss-loco-accent, #f5a623));
	box-shadow: 0 0 0 2px var(--kiss-loco-pin-color, #fff), 0 1px 6px rgba(0, 0, 0, 0.35);
	transform: scale(0);
	transition: transform 0.2s ease;
}

.kiss-loco .kiss-loco-pin-dot::after {
	content: "";
	position: absolute;
	inset: -6px;
	border-radius: 50%;
	border: 2px solid var(--kiss-loco-pin-dot, var(--kiss-loco-accent, #f5a623));
	opacity: 0;
}

.kiss-loco .kiss-loco-pin-line {
	position: absolute;
	left: 0;
	top: -0.75px;
	width: var(--kiss-loco-pin-len);
	height: 1.5px;
	background: currentColor;
	transform-origin: 0 50%;
	transform: rotate(var(--a)) scaleX(0);
	transition: transform 0.2s ease;
}

.kiss-loco .kiss-loco-pin-label {
	position: absolute;
	left: var(--lx);
	top: var(--ly);
	transform: translate(var(--tx), -50%);
	padding: 5px 9px 4px;
	white-space: nowrap;
	font: 700 11px/1.2 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	/* A pill in the stage's own color, so the label reads over any line art behind it. */
	background: var(--kiss-loco-pin-bg, var(--kiss-loco-stage-bg, rgba(0, 32, 64, 0.85)));
	border: 1px solid var(--kiss-loco-pin-color, #fff);
	border-radius: 3px;
	opacity: 0;
	transition: opacity 0.15s ease;
}

.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-dot {
	transform: scale(1);
	transition: transform 0.35s cubic-bezier(0.3, 1.6, 0.5, 1);
}

.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-dot::after {
	animation: kiss-loco-pin-pulse 1.8s ease-out 0.9s infinite;
}

.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-line {
	transform: rotate(var(--a)) scaleX(1);
	transition: transform 0.45s ease 0.2s;
}

.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-label {
	opacity: 1;
	transition: opacity 0.35s ease 0.55s;
}

@keyframes kiss-loco-pin-pulse {
	0% { transform: scale(0.6); opacity: 0.9; }
	100% { transform: scale(2.2); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco .kiss-loco-pin-dot,
	.kiss-loco .kiss-loco-pin-line,
	.kiss-loco .kiss-loco-pin-label,
	.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-dot,
	.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-line,
	.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-label {
		transition: none;
	}
	.kiss-loco .kiss-loco-callout-set.is-on .kiss-loco-pin-dot::after {
		animation: none;
	}
}

/*
 * Ripple: one side of a line shimmers (computers only; the engine decides and adds the classes).
 * .kiss-loco-ripple holds copies of the frame layers with an SVG displacement filter; the originals
 * are masked off on the rippling side of --kiss-loco-ripple-line and the copies on the other, over
 * one complementary 24px ramp, so there is one set of lines everywhere. Water ripples below the
 * line; heat haze (.kiss-loco--ripple-above) above it. A placed layer measures the line from its
 * own top (--kiss-loco-layer-top). Nothing here applies until the engine marks it live on screen.
 */
.kiss-loco .kiss-loco-ripple {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
	pointer-events: none;
	display: none;
}

.kiss-loco .kiss-loco-ripple-defs {
	position: absolute;
	width: 0;
	height: 0;
	overflow: hidden;
}

.kiss-loco.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-ripple {
	display: block;
	filter: var(--kiss-loco-ripple-filter);
	-webkit-mask-image: linear-gradient(to bottom, transparent var(--kiss-loco-ripple-line), #000 calc(var(--kiss-loco-ripple-line) + 24px));
	mask-image: linear-gradient(to bottom, transparent var(--kiss-loco-ripple-line), #000 calc(var(--kiss-loco-ripple-line) + 24px));
}

.kiss-loco.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-visual > .kiss-loco-layer,
.kiss-loco.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-visual > picture > .kiss-loco-layer {
	-webkit-mask-image: linear-gradient(to bottom, #000 calc(var(--kiss-loco-ripple-line) - var(--kiss-loco-layer-top, 0px)), transparent calc(var(--kiss-loco-ripple-line) + 24px - var(--kiss-loco-layer-top, 0px)));
	mask-image: linear-gradient(to bottom, #000 calc(var(--kiss-loco-ripple-line) - var(--kiss-loco-layer-top, 0px)), transparent calc(var(--kiss-loco-ripple-line) + 24px - var(--kiss-loco-layer-top, 0px)));
}

/* Above the line: the same pair, mirrored. */
.kiss-loco.kiss-loco--ripple-above.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-ripple {
	-webkit-mask-image: linear-gradient(to bottom, #000 calc(var(--kiss-loco-ripple-line) - 24px), transparent var(--kiss-loco-ripple-line));
	mask-image: linear-gradient(to bottom, #000 calc(var(--kiss-loco-ripple-line) - 24px), transparent var(--kiss-loco-ripple-line));
}

.kiss-loco.kiss-loco--ripple-above.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-visual > .kiss-loco-layer,
.kiss-loco.kiss-loco--ripple-above.kiss-loco--ripple-on.kiss-loco--ripple-live .kiss-loco-visual > picture > .kiss-loco-layer {
	-webkit-mask-image: linear-gradient(to bottom, transparent calc(var(--kiss-loco-ripple-line) - 24px - var(--kiss-loco-layer-top, 0px)), #000 calc(var(--kiss-loco-ripple-line) - var(--kiss-loco-layer-top, 0px)));
	mask-image: linear-gradient(to bottom, transparent calc(var(--kiss-loco-ripple-line) - 24px - var(--kiss-loco-layer-top, 0px)), #000 calc(var(--kiss-loco-ripple-line) - var(--kiss-loco-layer-top, 0px)));
}

/* The editor draws the line, so it can be placed by eye. */
.kiss-loco .kiss-loco-ripple-guide {
	display: none;
}

.kiss-loco.kiss-loco--editor.kiss-loco--ripple-on .kiss-loco-ripple-guide {
	display: block;
	position: absolute;
	left: 0;
	right: 0;
	top: var(--kiss-loco-ripple-line);
	z-index: 2;
	border-top: 1px dashed rgba(255, 255, 255, 0.75);
	box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-loco.kiss-loco--ripple-live .kiss-loco-ripple {
		display: none;
	}
	.kiss-loco.kiss-loco--ripple-live .kiss-loco-visual > .kiss-loco-layer,
	.kiss-loco.kiss-loco--ripple-live .kiss-loco-visual > picture > .kiss-loco-layer {
		-webkit-mask-image: none;
		mask-image: none;
	}
}

/* Keep the picture big on phones: the engine zooms the slide copy (0.85–1) when a long slide would
   squeeze the picture; one value for every slide. Unset, zoom is 1. */
.kiss-loco .kiss-loco-captions {
	zoom: var(--kiss-loco-copy-zoom, 1);
}

/* A "Match the frames" stage at its screen-height cap fills the screen like Fill, so when a mobile
   browser's toolbar slides away the strip that opens below it wears the stage color too (the engine
   adds the class only while the cap holds the stage). */
.kiss-loco.kiss-loco--capped .kiss-loco-track {
	background: var(--kiss-loco-stage-bg, transparent);
}
