/**
 * Onda Motion — Widgets de Preloader.
 *
 * Estilos autosuficientes de los widgets de preloader (Contador, Barra, Logo
 * Fill, Spinner, Words). Se encolan vía get_style_depends() de cada widget, así
 * funcionan también dentro del editor de Elementor (donde el runtime del
 * preloader no corre).
 *
 * El progreso lo maneja la variable --onda-pl-p (0→1) que el runtime publica en
 * .onda-preloader. Default 1 = lleno (para que en el editor se vea completo); el
 * cover real arranca en 0. Barra y Logo son CSS puro; Contador y Words usan el
 * runtime.
 *
 * @package Onda_Motion
 */

/* ── Contador (%) ─────────────────────────────────────────────────────── */
.onda-pre-counter {
	display: inline-flex;
	align-items: baseline;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.onda-pre-counter .onda-pre-affix {
	opacity: 0.65;
}

/* ── Contador odómetro (dígitos que ruedan) ───────────────────────────── */
.onda-pre-odo {
	display: inline-flex;
	line-height: 1;
}

.onda-pre-odo-digit {
	display: inline-block;
	height: 1em;
	overflow: hidden;
	vertical-align: top;
}

.onda-pre-odo-reel {
	display: flex;
	flex-direction: column;
	transform: translateY( calc( var( --d, 0 ) * -1em ) );
	transition: transform 0.4s cubic-bezier( 0.22, 1, 0.36, 1 );
	will-change: transform;
}

.onda-pre-odo-reel > span {
	display: block;
	height: 1em;
	line-height: 1;
	text-align: center;
}

/* ── Caja por número (cajita por dígito; vars publicadas por el widget) ──── */
/* Modo plano/scramble: el runtime reescribe el valor como celdas .onda-pre-cell. */
.onda-pl-num--cells {
	display: inline-flex;
	gap: var( --onda-cell-gap, 0.12em );
}
.onda-pre-cell {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 0.74em;
	padding: var( --onda-cell-pad, 0 );
	background: var( --onda-cell-bg, transparent );
	color: var( --onda-cell-color, inherit );
	border-radius: var( --onda-cell-radius, 0 );
	box-sizing: content-box;
}
/* Separadores (. , -): sin caja, pegados. */
.onda-pre-cell--sep {
	min-width: 0;
	padding-left: 0;
	padding-right: 0;
	background: transparent;
}
/* Modo odómetro con caja: la cajita va en cada dígito ya existente. */
.onda-pre-counter--boxed .onda-pre-odo {
	gap: var( --onda-cell-gap, 0.12em );
}
.onda-pre-counter--boxed .onda-pre-odo-digit {
	padding: var( --onda-cell-pad, 0 );
	background: var( --onda-cell-bg, transparent );
	color: var( --onda-cell-color, inherit );
	border-radius: var( --onda-cell-radius, 0 );
	box-sizing: content-box;
}

/* ── Barra de progreso (CSS puro vía scale) ───────────────────────────── */
.onda-pre-bar {
	position: relative;
	display: inline-block;
	vertical-align: middle;
	overflow: hidden;
	background: rgba( 255, 255, 255, 0.16 );
	width: min( 70vw, 360px );
	height: 3px;
	border-radius: 2px;
}

.onda-pre-bar__fill {
	position: absolute;
	inset: 0;
	background: #ff3d00;
	transform-origin: left center;
	transform: scaleX( var( --onda-pl-p, 1 ) );
	transition: transform 0.12s linear;
}

.onda-pre-bar--vertical {
	width: 3px;
	height: min( 60vh, 320px );
}

.onda-pre-bar--vertical .onda-pre-bar__fill {
	transform-origin: bottom center;
	transform: scaleY( var( --onda-pl-p, 1 ) );
}

/* ── Logo / Imagen que se rellena (CSS puro vía clip) ─────────────────── */
.onda-pre-logo {
	position: relative;
	display: inline-block;
	line-height: 0;
}

.onda-pre-logo img {
	display: block;
	max-width: 100%;
	height: auto;
}

.onda-pre-logo__base {
	opacity: var( --onda-pre-base-op, 0.18 );
}

.onda-pre-logo__fill {
	position: absolute;
	inset: 0;
	transition: -webkit-clip-path 0.12s linear, clip-path 0.12s linear;
}

.onda-pre-fill-up {
	-webkit-clip-path: inset( calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 0 );
	clip-path: inset( calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 0 );
}
.onda-pre-fill-down {
	-webkit-clip-path: inset( 0 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 );
	clip-path: inset( 0 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 );
}
.onda-pre-fill-left {
	-webkit-clip-path: inset( 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 );
	clip-path: inset( 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 );
}
.onda-pre-fill-right {
	-webkit-clip-path: inset( 0 0 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) );
	clip-path: inset( 0 0 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) );
}

/* Wrapper del spinner: ancho completo del widget para que el control "Alineación"
   (text-align) centre el spinner Y para que la unidad % del Tamaño resuelva contra
   un ancho definido (sin esto, dentro de un Container flex centrado el % colapsa;
   para "escala de pantalla" usar vw, que es siempre fiable). */
.onda-pre-spinner-wrap {
	display: block;
	width: 100%;
}

/* Mismo arreglo del % para los demás widgets con Tamaño/Largo: el wrap toma ancho
   completo del cover para que la unidad % resuelva contra un ancho definido (sin
   esto el wrap es shrink-to-fit y el % colapsa → solo estiraba con px/vw/vh). La
   alineación (text-align del control) sigue posicionando el elemento adentro. */
.onda-pre-logo-wrap,
.onda-pre-seq-wrap,
.onda-pre-media-wrap {
	display: block;
	width: 100%;
}

/* ── Spinner (CSS puro) ───────────────────────────────────────────────── */
.onda-pre-spinner {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	border: 2px solid rgba( 255, 255, 255, 0.22 );
	border-top-color: #ff3d00;
	animation: onda-pre-spin 0.7s linear infinite;
}

@keyframes onda-pre-spin {
	to { transform: rotate( 360deg ); }
}

/* ── Spinner Pack 2: tipos extra (CSS puro, consumen las vars del wrap) ──── */
/* Vars publicadas en .onda-pre-spinner-wrap: --onda-pre-size, --onda-pre-thick,
   --onda-pre-track, --onda-pre-active, --onda-pre-speed. */

/* Puntos que botan en secuencia. */
.onda-pre-dots {
	display: inline-flex;
	align-items: center;
	gap: calc( var( --onda-pre-size, 40px ) * 0.18 );
	height: var( --onda-pre-size, 40px );
}
.onda-pre-dot {
	width: calc( var( --onda-pre-size, 40px ) * 0.22 );
	height: calc( var( --onda-pre-size, 40px ) * 0.22 );
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	animation: onda-pre-dot var( --onda-pre-speed, 0.7s ) ease-in-out infinite;
}
/* Los delays por índice se emiten inline en el render (escala con cualquier N). */
@keyframes onda-pre-dot {
	0%, 80%, 100% { transform: translateY( 0 ); opacity: 0.5; }
	40% { transform: translateY( calc( var( --onda-pre-size, 40px ) * -0.28 ) ); opacity: 1; }
}

/* Barras tipo ecualizador. */
.onda-pre-eq {
	display: inline-flex;
	align-items: flex-end;
	justify-content: center;
	gap: calc( var( --onda-pre-size, 40px ) * 0.1 );
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
}
.onda-pre-eqbar {
	width: calc( var( --onda-pre-size, 40px ) * 0.13 );
	height: 100%;
	background: var( --onda-pre-active, #ff3d00 );
	border-radius: calc( var( --onda-pre-size, 40px ) * 0.06 );
	transform-origin: bottom;
	animation: onda-pre-eq var( --onda-pre-speed, 0.7s ) ease-in-out infinite;
}
/* Los delays por índice se emiten inline en el render (escala con cualquier N). */
@keyframes onda-pre-eq {
	0%, 100% { transform: scaleY( 0.28 ); }
	50% { transform: scaleY( 1 ); }
}

/* Doble anillo concéntrico en sentidos opuestos. */
.onda-pre-dualring {
	position: relative;
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
}
.onda-pre-dualring i {
	position: absolute;
	border-radius: 50%;
	border: var( --onda-pre-thick, 2px ) solid transparent;
	box-sizing: border-box;
}
.onda-pre-dualring i:nth-child( 1 ) {
	inset: 0;
	border-top-color: var( --onda-pre-active, #ff3d00 );
	border-bottom-color: var( --onda-pre-active, #ff3d00 );
	animation: onda-pre-spin var( --onda-pre-speed, 0.7s ) linear infinite;
}
.onda-pre-dualring i:nth-child( 2 ) {
	inset: calc( var( --onda-pre-thick, 2px ) + var( --onda-pre-size, 40px ) * 0.14 );
	border-left-color: var( --onda-pre-track, rgba( 255, 255, 255, 0.45 ) );
	border-right-color: var( --onda-pre-track, rgba( 255, 255, 255, 0.45 ) );
	animation: onda-pre-spin calc( var( --onda-pre-speed, 0.7s ) * 0.75 ) linear infinite reverse;
}

/* Cometa: aro con cola degradada (conic-gradient + máscara radial). */
.onda-pre-comet {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	background: conic-gradient( from 90deg, rgba( 0, 0, 0, 0 ) 0%, var( --onda-pre-active, #ff3d00 ) 100% );
	-webkit-mask: radial-gradient( farthest-side, rgba( 0, 0, 0, 0 ) calc( 100% - var( --onda-pre-thick, 2px ) ), #000 calc( 100% - var( --onda-pre-thick, 2px ) ) );
	mask: radial-gradient( farthest-side, rgba( 0, 0, 0, 0 ) calc( 100% - var( --onda-pre-thick, 2px ) ), #000 calc( 100% - var( --onda-pre-thick, 2px ) ) );
	animation: onda-pre-spin var( --onda-pre-speed, 0.7s ) linear infinite;
}

/* Pulso: círculo que crece y se desvanece. */
.onda-pre-pulse {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	animation: onda-pre-pulse var( --onda-pre-speed, 0.7s ) cubic-bezier( 0.2, 0.6, 0.35, 1 ) infinite;
}
@keyframes onda-pre-pulse {
	0% { transform: scale( 0.1 ); opacity: 1; }
	100% { transform: scale( 1 ); opacity: 0; }
}

/* ══ Spinner — TIER PREMIUM (CSS/SVG puro; glow vía --onda-pre-pglow) ═══════ */

/* ★ Anillo de progreso premium: se llena con --onda-pl-p + cabeza luminosa que
   viaja con el progreso (default p=1 → completo en el editor). */
.onda-pre-pring {
	position: relative;
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
}
.onda-pre-pring svg {
	display: block;
	width: 100%;
	height: 100%;
	transform: rotate( -90deg );
	overflow: visible;
}
.onda-pre-pring circle {
	fill: none;
	stroke-width: var( --onda-pre-thick, 3 );
	vector-effect: non-scaling-stroke;
}
.onda-pre-pring__track { stroke: var( --onda-pre-track, rgba( 255, 255, 255, 0.18 ) ); }
.onda-pre-pring__fill {
	stroke: var( --onda-pre-active, #ff3d00 );
	stroke-linecap: round;
	stroke-dasharray: 100;
	stroke-dashoffset: calc( 100 * ( 1 - var( --onda-pl-p, 1 ) ) );
	transition: stroke-dashoffset 0.12s linear;
}
.onda-pre-pring__head {
	position: absolute;
	inset: 0;
	transform: rotate( calc( var( --onda-pl-p, 1 ) * 360deg ) );
	transition: transform 0.12s linear;
}
.onda-pre-pring__head i {
	position: absolute;
	top: calc( var( --onda-pre-size, 40px ) * 0.06 );
	left: 50%;
	transform: translate( -50%, -50% );
	width: calc( var( --onda-pre-thick, 3 ) * 1.7px + 1px );
	height: calc( var( --onda-pre-thick, 3 ) * 1.7px + 1px );
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	box-shadow: 0 0 calc( var( --onda-pre-pglow, 0px ) + 5px ) var( --onda-pre-active, #ff3d00 );
}

/* ★ Órbita 3D: partículas en un plano inclinado (elipse) con profundidad. */
.onda-pre-orbit {
	position: relative;
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	transform: rotateX( 62deg );
	transform-style: preserve-3d;
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
}
.onda-pre-orbit i {
	position: absolute;
	top: 50%;
	left: 50%;
	width: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.26 ) );
	height: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.26 ) );
	margin: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.26 ) / -2 );
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	/* Radio, tamaño, ángulo y duración los varía el render por partícula. */
	animation: onda-pre-orbit calc( var( --onda-pre-speed, 2s ) * 1.6 ) linear infinite;
}
@keyframes onda-pre-orbit {
	from { transform: rotate( var( --onda-orb-a, 0deg ) ) translateX( calc( var( --onda-pre-size, 40px ) * var( --onda-orb-r, 0.36 ) ) ); opacity: 1; }
	50%  { opacity: 0.55; }
	to   { transform: rotate( calc( var( --onda-orb-a, 0deg ) + 360deg ) ) translateX( calc( var( --onda-pre-size, 40px ) * var( --onda-orb-r, 0.36 ) ) ); opacity: 1; }
}

/* ★ Partículas flotando: dispersas en un área 2D (fondo opcional), derivando. */
.onda-pre-float {
	position: relative;
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	overflow: hidden;
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
}
.onda-pre-float i {
	position: absolute;
	width: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.2 ) );
	height: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.2 ) );
	margin: calc( var( --onda-pre-size, 40px ) * var( --onda-orb-sz, 0.2 ) / -2 );
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	/* left/top, deriva (--onda-fdx/--onda-fdy) y duración los pone el render. */
	animation: onda-pre-float calc( var( --onda-pre-speed, 2s ) * 2 ) ease-in-out infinite alternate;
}
@keyframes onda-pre-float {
	from { transform: translate( calc( var( --onda-fdx, 0px ) * -1 ), calc( var( --onda-fdy, 0px ) * -1 ) ); opacity: 0.55; }
	to   { transform: translate( var( --onda-fdx, 0px ), var( --onda-fdy, 0px ) ); opacity: 1; }
}

/* ★ Gooey / Metaball: blobs que se fusionan vía filtro SVG (goo). El filtro va
   inline en __layer (id único); el glow va en el contenedor externo. */
.onda-pre-goo {
	position: relative;
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
}
.onda-pre-goo__defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.onda-pre-goo__layer { position: absolute; inset: 0; }
/* Lava lamp: cada blob trae su tamaño (--br), posición horizontal (--bx),
   recorrido vertical (--btravel), deriva (--bdrift), duración (--bdur) y fase
   (--bdelay) PROPIOS, emitidos inline por índice → nunca se mueven sincronizados.
   --onda-goo-amt escala el recorrido/deriva (intensidad). El filtro goo los
   fusiona y separa como metaballs. */
.onda-pre-goo__layer i {
	position: absolute;
	top: 50%;
	left: calc( 50% + var( --bx, 0px ) );
	width: var( --br, calc( var( --onda-pre-size, 40px ) * 0.3 ) );
	height: var( --br, calc( var( --onda-pre-size, 40px ) * 0.3 ) );
	border-radius: 50%;
	background: var( --onda-pre-active, #ff3d00 );
	animation: onda-pre-lava var( --bdur, 5s ) ease-in-out infinite var( --bdelay, 0s );
	will-change: transform;
}
@keyframes onda-pre-lava {
	0%   { transform: translate( -50%, var( --btravel, 8px ) ) scale( 0.82 ); }
	25%  { transform: translate( calc( -50% + var( --bdrift, 4px ) ), 0 ) scale( 1.08 ); }
	50%  { transform: translate( -50%, calc( var( --btravel, 8px ) * -1 ) ) scale( 0.9 ); }
	75%  { transform: translate( calc( -50% - var( --bdrift, 4px ) ), 0 ) scale( 1.12 ); }
	100% { transform: translate( -50%, var( --btravel, 8px ) ) scale( 0.82 ); }
}

/* ★ Morph blob: forma orgánica que MUTA (4 estados de border-radius). La rotación
   es opcional (clase --spin) para que la mutación se note. --onda-morph-amt (0..1)
   interpola cada radio entre 50% (círculo quieto) y la forma orgánica. */
.onda-pre-morph {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	background: var( --onda-pre-active, #ff3d00 );
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
	animation: onda-pre-morph calc( var( --onda-pre-speed, 2s ) * 3 ) ease-in-out infinite;
}
.onda-pre-morph--spin {
	animation: onda-pre-morph calc( var( --onda-pre-speed, 2s ) * 3 ) ease-in-out infinite,
		onda-pre-spin calc( var( --onda-pre-speed, 2s ) * 6 ) linear infinite;
}
.onda-pre-morph.onda-pre-pgrad {
	background: linear-gradient( var( --onda-pre-grad-angle, 135deg ), var( --onda-pre-active, #ff3d00 ), var( --onda-pre-g2, #ff9d00 ) );
}
@keyframes onda-pre-morph {
	0%, 100% { border-radius:
		calc( 50% + ( 42% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 58% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 70% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 30% - 50% ) * var( --onda-morph-amt, 1 ) )
		/ calc( 50% + ( 45% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 45% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 55% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 55% - 50% ) * var( --onda-morph-amt, 1 ) );
	}
	33% { border-radius:
		calc( 50% + ( 70% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 30% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 46% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 54% - 50% ) * var( --onda-morph-amt, 1 ) )
		/ calc( 50% + ( 30% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 60% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 40% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 70% - 50% ) * var( --onda-morph-amt, 1 ) );
	}
	66% { border-radius:
		calc( 50% + ( 34% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 66% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 54% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 46% - 50% ) * var( --onda-morph-amt, 1 ) )
		/ calc( 50% + ( 62% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 38% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 64% - 50% ) * var( --onda-morph-amt, 1 ) ) calc( 50% + ( 36% - 50% ) * var( --onda-morph-amt, 1 ) );
	}
}

/* ★ Trazo que se dibuja solo: SVG con pathLength=100 + dashoffset en bucle. */
.onda-pre-pdraw {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
	filter: drop-shadow( 0 0 var( --onda-pre-pglow, 0px ) var( --onda-pre-active, #ff3d00 ) );
}
.onda-pre-pdraw--wide { aspect-ratio: auto; height: auto; }
.onda-pre-pdraw svg { display: block; width: 100%; height: 100%; overflow: visible; }
.onda-pre-pdraw--wide svg { height: auto; }
.onda-pre-pdraw__p {
	fill: none;
	stroke: var( --onda-pre-active, #ff3d00 );
	stroke-width: var( --onda-pre-thick, 3 );
	stroke-linecap: round;
	stroke-linejoin: round;
	vector-effect: non-scaling-stroke;
	stroke-dasharray: 100;
	animation: onda-pre-pdraw calc( var( --onda-pre-speed, 2s ) * 3 ) ease-in-out infinite;
}
@keyframes onda-pre-pdraw {
	0%   { stroke-dashoffset: 100; }
	45%  { stroke-dashoffset: 0; }
	55%  { stroke-dashoffset: 0; }
	100% { stroke-dashoffset: -100; }
}

/* ── Words (saludos que ciclan; los maneja el runtime) ────────────────── */
.onda-pre-words {
	position: relative;
	display: grid;
	place-items: center;
	min-height: 1.3em;
	line-height: 1.1;
}

.onda-pre-words > span {
	grid-area: 1 / 1;
	opacity: 0;
	transform: translateY( 14px );
	filter: blur( 8px );
	transition: opacity 0.4s ease, transform 0.4s ease, filter 0.4s ease;
}

/* Fallback (editor / sin JS): la primera palabra visible. */
.onda-pre-words > span:first-child {
	opacity: 1;
	transform: none;
	filter: none;
}

/* El runtime manda: estas reglas van después y ganan por orden. */
.onda-pre-words > span.is-on {
	opacity: 1;
	transform: none;
	filter: none;
}
.onda-pre-words > span.is-out {
	opacity: 0;
	transform: translateY( -14px );
	filter: blur( 8px );
}

/* Modo Status/Log tipeado: sin blur ni desplazamiento, el runtime tipea. */
.onda-pre-words--type > span,
.onda-pre-words--type > span.is-out {
	transform: none;
	filter: none;
	transition: opacity 0.15s ease;
}

.onda-pre-words--caret > span.is-on::after {
	content: "";
	display: inline-block;
	width: 0.08em;
	height: 1em;
	margin-left: 0.06em;
	background: currentColor;
	vertical-align: -0.12em;
	animation: onda-pre-caret 1s steps( 1 ) infinite;
}

@keyframes onda-pre-caret {
	50% { opacity: 0; }
}

/* ── Spinner: anillo de progreso (CSS puro vía --onda-pl-p) ───────────── */
.onda-pre-ring {
	display: inline-block;
	width: var( --onda-pre-size, 40px );
	aspect-ratio: 1 / 1;
}

.onda-pre-ring svg {
	display: block;
	width: 100%;
	height: 100%;
	transform: rotate( -90deg );
	overflow: visible;
}

.onda-pre-ring circle {
	fill: none;
	stroke-width: var( --onda-pre-rw, 4 );
	vector-effect: non-scaling-stroke;
}

.onda-pre-ring__track {
	stroke: rgba( 255, 255, 255, 0.22 );
}

.onda-pre-ring__fill {
	stroke: #ff3d00;
	stroke-dasharray: 100;
	stroke-dashoffset: calc( 100 * ( 1 - var( --onda-pl-p, 1 ) ) );
	transition: stroke-dashoffset 0.12s linear;
}

/* ── Logo modo trazo (SVG dibujado; dashoffset lo mide el runtime) ────── */
.onda-pre-logo-draw {
	display: inline-block;
	line-height: 0;
}

.onda-pre-logo-draw svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

.onda-pre-logo-draw svg path,
.onda-pre-logo-draw svg line,
.onda-pre-logo-draw svg polyline,
.onda-pre-logo-draw svg polygon,
.onda-pre-logo-draw svg circle,
.onda-pre-logo-draw svg rect,
.onda-pre-logo-draw svg ellipse {
	fill: none;
	stroke: var( --onda-pre-stroke, #ffffff );
	stroke-width: var( --onda-pre-stroke-w, 2 );
	vector-effect: non-scaling-stroke;
}

/* ── Logo modo relleno con SVG inline (recoloreable: base tenue + relleno + ola) ─ */
/* Un <img> de SVG sin fill se ve negro/invisible y no es recoloreable; por eso el
   render lo INLINEA en 3 capas y acá las teñimos con fill (CSS gana sobre el
   atributo de presentación del SVG). Default --onda-pl-p=1 → lleno en el editor. */
.onda-pre-logo-svg__base,
.onda-pre-logo-svg__fill {
	display: block;
}
.onda-pre-logo-svg__base {
	opacity: var( --onda-pre-base-op, 0.18 );
}
.onda-pre-logo-svg__fill {
	position: absolute;
	inset: 0;
	transition: -webkit-clip-path 0.12s linear, clip-path 0.12s linear;
}
.onda-pre-logo-svg__base svg,
.onda-pre-logo-svg__fill svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}
/* Recolor: base (tenue) y relleno (la cresta de ola comparte el color de relleno). */
.onda-pre-logo-svg__base svg,
.onda-pre-logo-svg__base svg * {
	fill: var( --onda-pre-svg-base, #ffffff );
}
.onda-pre-logo-svg__fill svg,
.onda-pre-logo-svg__fill svg * {
	fill: var( --onda-pre-svg-fill, #ffffff );
}
/* Glow opcional sobre el relleno (mismo control que la versión raster). */
.onda-pre-logo-svg__fill svg {
	filter: drop-shadow( 0 0 var( --onda-pre-glow, 0px ) var( --onda-pre-c1, var( --onda-pre-svg-fill, #ffffff ) ) );
}

/* ── Texto / Wordmark que se rellena ──────────────────────────────────── */
.onda-pre-textfill {
	position: relative;
	display: inline-block;
	line-height: 1;
	white-space: nowrap;
}

.onda-pre-textfill__base {
	display: block;
	color: rgba( 255, 255, 255, 0.22 );
}

.onda-pre-textfill__fill {
	position: absolute;
	inset: 0;
	display: block;
	white-space: nowrap;
	color: #ffffff;
	transition: -webkit-clip-path 0.12s linear, clip-path 0.12s linear;
}

/* ── Image Sequence / Flipbook ────────────────────────────────────────── */
.onda-pre-seq {
	position: relative;
	display: inline-block;
	line-height: 0;
}

.onda-pre-seq img {
	display: block;
	max-width: 100%;
	height: auto;
}

.onda-pre-seq__frame {
	position: absolute;
	inset: 0;
	opacity: 0;
	/* Duración del fundido entre frames (la fija el widget; crossfade = más larga). */
	transition: opacity var( --onda-seq-fade, 0.08s ) linear;
}

/* El primer frame queda en flujo (da tamaño) y visible en editor/sin JS. */
.onda-pre-seq__frame:first-child {
	position: relative;
}

.onda-pre-seq__frame.is-on {
	opacity: 1;
}

/* ── Marquee (cinta de carga, CSS puro) ───────────────────────────────── */
/* El marquee apila filas (1 o más); cada fila recorta su propio track. La
   dirección de cada track la fija el render INLINE (base + alterna por fila). */
.onda-pre-marquee {
	display: flex;
	flex-direction: column;
	max-width: 100%;
	white-space: nowrap;
}

.onda-pre-marquee__row {
	display: flex;
	max-width: 100%;
	overflow: hidden;
}

.onda-pre-marquee__track {
	display: flex;
	width: max-content;
	animation: onda-pre-mq var( --onda-mq-speed, 12s ) linear infinite;
}

.onda-pre-marquee__group {
	display: flex;
	flex: 0 0 auto;
}

.onda-pre-mq-item {
	display: inline-flex;
	align-items: center;
}

/* Texto en contorno (outline): solo el trazo, relleno transparente. */
.onda-pre-marquee--outline {
	-webkit-text-fill-color: transparent;
	-webkit-text-stroke: 1px currentColor;
	text-stroke: 1px currentColor;
}

/* Imágenes / logos intercalados en la cinta. */
.onda-pre-mq-img img {
	display: block;
	width: auto;
	height: 1.2em;
	vertical-align: middle;
}

@keyframes onda-pre-mq {
	to { transform: translateX( -50% ); }
}

/* ── Respeto a reduce-motion para los loops infinitos ─────────────────── */
@media ( prefers-reduced-motion: reduce ) {
	.onda-pre-marquee__track,
	.onda-pre-spinner,
	.onda-pre-dot,
	.onda-pre-eqbar,
	.onda-pre-dualring i,
	.onda-pre-comet,
	.onda-pre-pulse,
	.onda-pre-orbit i,
	.onda-pre-float i,
	.onda-pre-goo__layer i,
	.onda-pre-morph,
	.onda-pre-morph--spin,
	.onda-pre-pdraw__p,
	.onda-pre-odo-reel {
		animation: none;
		transition: none;
	}
}


/* ── Relleno LÍQUIDO con OLAS: el borde superior del relleno ES la ola ──── */
/* La capa de relleno (__fill) lleva UNA máscara de 2 capas compuestas (unión):
   (1) la cresta ondulada, una tira que tilea en X y se desplaza horizontal en
   loop seamless, posicionada en la línea de agua --onda-wl (px desde abajo, la
   fija el runtime); (2) un cuerpo SÓLIDO de 0 hasta --onda-wl. La unión = una
   sola masa de agua continua (sin costura) con superficie ondulada que sube con
   la carga. Default --onda-wl=100% → el editor (sin runtime) se ve lleno. */
.onda-pre-textfill__fill--wave,
.onda-pre-logo-svg__fill--wave,
.onda-pre-logo__fill--wave {
	--onda-amp: var( --onda-wave-amp, 0.2em );
	/* Longitud de onda ANCHA por defecto: 1 cresta amplia a lo ancho (estilo NeoLeaf),
	   no un rizo chico. Subila más en el control para una sola joroba. */
	--onda-len: var( --onda-wave-len, 110% );
	/* Capa 1 = la FORMA del borde (tira que tilea en X y se desplaza); capa 2 =
	   cuerpo sólido de 0 hasta la línea de agua --onda-wl. La unión = una sola masa
	   continua con superficie con forma, que sube con la carga. */
	-webkit-mask-image: var( --onda-wave-svg ), linear-gradient( #000, #000 );
	mask-image: var( --onda-wave-svg ), linear-gradient( #000, #000 );
	-webkit-mask-repeat: repeat-x, no-repeat;
	mask-repeat: repeat-x, no-repeat;
	-webkit-mask-size: var( --onda-len ) calc( var( --onda-amp ) * 2 ), 100% var( --onda-wl, 100% );
	mask-size: var( --onda-len ) calc( var( --onda-amp ) * 2 ), 100% var( --onda-wl, 100% );
	-webkit-mask-position: left 0 bottom var( --onda-wl, 100% ), left bottom;
	mask-position: left 0 bottom var( --onda-wl, 100% ), left bottom;
	-webkit-mask-composite: source-over;
	mask-composite: add;
	/* MOVIMIENTO: lo escribe el RUNTIME (mask-position cada frame). Antes se animaba
	   por CSS (@keyframes/custom prop en mask-position), que en varios navegadores NO
	   repinta la máscara → se veía quieta. Ahora el JS muta mask-position por frame y
	   el navegador repinta sí o sí. En el editor (sin runtime) queda estática. */
}
/* En modo ola el relleno NO usa clip-path recto (la máscara hace el recorte). */
.onda-pre-textfill__fill--wave { -webkit-clip-path: none; clip-path: none; }

/* ── LIBRERÍA DE FORMAS del borde del relleno ─────────────────────────────
   Cada forma = un tile SVG distinto (viewBox 0 0 120 48, la forma arriba y
   sólido abajo) que tilea en X. Se elige por clase en el padre (hereda la var). */
.onda-pre-edge-wave {
	/* Sine seamless: tangente HORIZONTAL en x=0, pico y x=120 → los tiles juntan sin
	   cúspides (valles redondeados) a cualquier longitud de onda. */
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20C%2020%2024%2040%206%2060%206%20C%2080%206%20100%2024%20120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-wave-high {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20C%2015%202%2045%202%2060%2024%20C%2075%2046%20105%2046%20120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-zigzag {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20L30%206%20L60%2024%20L90%206%20L120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-scallop {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20C%200%208%2030%208%2030%2024%20C%2030%208%2060%208%2060%2024%20C%2060%208%2090%208%2090%2024%20C%2090%208%20120%208%20120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-drip {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2016%20C%2012%2016%2014%2040%2030%2040%20C%2046%2040%2048%2016%2060%2016%20C%2072%2016%2074%2040%2090%2040%20C%20106%2040%20108%2016%20120%2016%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-steps {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2014%20L40%2014%20L40%2030%20L80%2030%20L80%2014%20L120%2014%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-diagonal {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%208%20L120%2040%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
/* Aliases retrocompatibles con datos viejos (soft/strong → wave/wave-high). */
.onda-pre-edge-soft {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20C%2030%208%2090%208%20120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}
.onda-pre-edge-strong {
	--onda-wave-svg: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20120%2048'%20preserveAspectRatio='none'%3E%3Cpath%20d='M0%2024%20C%2015%202%2045%202%2060%2024%20C%2075%2046%20105%2046%20120%2024%20L120%2048%20L0%2048%20Z'%20fill='%23000'/%3E%3C/svg%3E");
}

/* El Logo (SVG inline o raster) reusa la MISMA máscara líquida del relleno
   (.onda-pre-logo-svg__fill--wave / .onda-pre-logo__fill--wave de arriba): la
   onda recorta la silueta real y el cuerpo sólido sube con --onda-wl. amp/ancho
   en px los fija el render inline (loop seamless). */
@media ( prefers-reduced-motion: reduce ) {
	.onda-pre-textfill__fill--wave,
	.onda-pre-logo-svg__fill--wave,
	.onda-pre-logo__fill--wave { animation: none; }
}

/* ── Words: modo Secciones de texto (bloques tipo emotion-agency) ─────── */
.onda-pre-words--block {
	white-space: pre-line;
	line-height: 1.5;
	max-width: 34ch;
	min-height: 0;
}
.onda-pre-words--block > span {
	white-space: pre-line;
}

/* ── Entrada / Salida por widget (atado al ciclo del preloader) ───────── */
/* El runtime agrega .onda-pl-armed al cover para el estado inicial (así en el
   editor, sin runtime, los elementos se ven completos), luego .is-in para que
   entren, y .is-out justo antes de remover el cover. */
.onda-pl-anim[data-onda-in] {
	transition:
		opacity var( --onda-in-dur, 600ms ) ease var( --onda-in-delay, 0ms ),
		transform var( --onda-in-dur, 600ms ) cubic-bezier( 0.22, 1, 0.36, 1 ) var( --onda-in-delay, 0ms ),
		filter var( --onda-in-dur, 600ms ) ease var( --onda-in-delay, 0ms ),
		clip-path var( --onda-in-dur, 600ms ) ease var( --onda-in-delay, 0ms );
}

.onda-pl-armed .onda-pl-anim[data-onda-in]:not( [data-onda-in="none"] ):not( .is-in ) { opacity: 0; }
.onda-pl-armed .onda-pl-anim[data-onda-in="up"]:not( .is-in )      { transform: translateY( 40px ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="down"]:not( .is-in )    { transform: translateY( -40px ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="left"]:not( .is-in )    { transform: translateX( 40px ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="right"]:not( .is-in )   { transform: translateX( -40px ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="scale"]:not( .is-in )   { transform: scale( 0.7 ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="blur"]:not( .is-in )    { filter: blur( 12px ); }
.onda-pl-armed .onda-pl-anim[data-onda-in="clip-up"]:not( .is-in ) { -webkit-clip-path: inset( 100% 0 0 0 ); clip-path: inset( 100% 0 0 0 ); }

.onda-pl-anim[data-onda-out].is-out {
	transition:
		opacity var( --onda-out-dur, 500ms ) ease var( --onda-out-delay, 0ms ),
		transform var( --onda-out-dur, 500ms ) cubic-bezier( 0.5, 0, 0.75, 0 ) var( --onda-out-delay, 0ms ),
		filter var( --onda-out-dur, 500ms ) ease var( --onda-out-delay, 0ms ),
		clip-path var( --onda-out-dur, 500ms ) ease var( --onda-out-delay, 0ms );
	opacity: 0;
}
.onda-pl-anim[data-onda-out="up"].is-out      { transform: translateY( -40px ); }
.onda-pl-anim[data-onda-out="down"].is-out    { transform: translateY( 40px ); }
.onda-pl-anim[data-onda-out="left"].is-out    { transform: translateX( -40px ); }
.onda-pl-anim[data-onda-out="right"].is-out   { transform: translateX( 40px ); }
.onda-pl-anim[data-onda-out="scale"].is-out   { transform: scale( 0.7 ); }
.onda-pl-anim[data-onda-out="blur"].is-out    { filter: blur( 12px ); }
.onda-pl-anim[data-onda-out="clip-up"].is-out { -webkit-clip-path: inset( 0 0 100% 0 ); clip-path: inset( 0 0 100% 0 ); }

@media ( prefers-reduced-motion: reduce ) {
	.onda-pl-anim[data-onda-in],
	.onda-pl-anim[data-onda-out].is-out { transition-duration: 1ms; }
}


/* ══ Pack 1 — Acabados de relleno premium (degradado · brillo · glow) ══════ */
/* Todo CSS puro: se ve en el editor (sin runtime) porque --onda-pl-p default 1. */

/* ── Degradado de relleno (clase `onda-pre-grad` en el elemento de relleno) ─ */
.onda-pre-bar__fill.onda-pre-grad {
	background-image: linear-gradient( var( --onda-pre-grad-angle, 90deg ), var( --onda-pre-g1, #ff3d00 ), var( --onda-pre-g2, #ff9d00 ) );
}

/* Texto: el degradado se recorta a las letras (background-clip: text). */
.onda-pre-textfill__fill.onda-pre-grad {
	background-image: linear-gradient( var( --onda-pre-grad-angle, 90deg ), var( --onda-pre-g1, #ffffff ), var( --onda-pre-g2, #7ab8ff ) );
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

/* ── Glow (resplandor) en el color activo. 0px = sombra oculta = sin glow. ── */
.onda-pre-bar__fill,
.onda-pre-ring__fill {
	filter: drop-shadow( 0 0 var( --onda-pre-glow, 0px ) var( --onda-pre-c1, #ff3d00 ) );
}
.onda-pre-textfill__fill {
	filter: drop-shadow( 0 0 var( --onda-pre-glow, 0px ) var( --onda-pre-c1, #ffffff ) );
}
.onda-pre-logo img {
	filter: drop-shadow( 0 0 var( --onda-pre-glow, 0px ) var( --onda-pre-c1, #ffffff ) );
}

/* ── Barrido de brillo (sheen): clase `onda-pre-sheen` en el elemento host ── */
/* Barra: la luz va recortada a la porción ya rellenada (--onda-pl-p). */
.onda-pre-bar.onda-pre-sheen::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient( 90deg, transparent, rgba( 255, 255, 255, 0.6 ), transparent );
	background-size: 45% 100%;
	background-repeat: no-repeat;
	-webkit-clip-path: inset( 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 );
	clip-path: inset( 0 calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 );
	mix-blend-mode: screen;
	animation: onda-pre-sheen-x var( --onda-pre-sheen-speed, 2s ) linear infinite;
}

.onda-pre-bar--vertical.onda-pre-sheen::after {
	background: linear-gradient( 0deg, transparent, rgba( 255, 255, 255, 0.6 ), transparent );
	background-size: 100% 45%;
	-webkit-clip-path: inset( calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 0 );
	clip-path: inset( calc( ( 1 - var( --onda-pl-p, 1 ) ) * 100% ) 0 0 0 );
	animation-name: onda-pre-sheen-y;
}

/* Logo: la luz barre la SILUETA real del logo (mask con la propia imagen), no
   una caja rectangular. */
.onda-pre-logo.onda-pre-sheen::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient( 110deg, transparent 40%, rgba( 255, 255, 255, 0.7 ) 50%, transparent 60% );
	background-size: 220% 100%;
	background-repeat: no-repeat;
	-webkit-mask: var( --onda-logo-src ) center / contain no-repeat;
	mask: var( --onda-logo-src ) center / contain no-repeat;
	mix-blend-mode: screen;
	animation: onda-pre-sheen-x var( --onda-pre-sheen-speed, 2s ) linear infinite;
}

/* Texto: la luz barre SOLO las letras (capa con el mismo texto recortado a los
   glifos vía background-clip:text), no un rectángulo sobre el bounding-box. */
.onda-pre-textfill__sheen {
	position: absolute;
	inset: 0;
	display: block;
	white-space: nowrap;
	pointer-events: none;
	background: linear-gradient( 110deg, transparent 42%, rgba( 255, 255, 255, 0.95 ) 50%, transparent 58% ) no-repeat;
	background-size: 220% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
	mix-blend-mode: screen;
	animation: onda-pre-sheen-x var( --onda-pre-sheen-speed, 2s ) linear infinite;
}

@keyframes onda-pre-sheen-x {
	from { background-position: -60% 0; }
	to   { background-position: 160% 0; }
}
@keyframes onda-pre-sheen-y {
	from { background-position: 0 160%; }
	to   { background-position: 0 -60%; }
}

@media ( prefers-reduced-motion: reduce ) {
	.onda-pre-bar.onda-pre-sheen::after,
	.onda-pre-textfill__sheen,
	.onda-pre-logo.onda-pre-sheen::after { animation: none; }
}

/* ── Preloader Media / Animación (video + lottie) ─────────────────────── */
.onda-pre-media-wrap { line-height: 0; }
.onda-pre-media {
	display: inline-block;
	width: 220px;
	max-width: 100%;
	vertical-align: top;
}
video.onda-pre-media,
lottie-player.onda-pre-media {
	display: block;
	width: 100%;
	height: auto;
}
/* Ajuste del video: natural (proporción real) vs rellenar recortando a 16:9. */
.onda-pre-media--contain { height: auto; }
video.onda-pre-media--cover {
	height: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}
/* Placeholder en el editor cuando falta la fuente. */
.onda-pre-media--ph {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 120px;
	padding: 1em 1.4em;
	line-height: 1.4;
	text-align: center;
	border: 1px dashed currentColor;
	border-radius: 8px;
	opacity: 0.5;
	font-size: 13px;
}

/* ══ Pack 3 — Words: reveals nuevos + modo log · Texto: cascada por letra ══ */

/* Perspectiva para el flip 3D (inocua para los demás reveals). */
.onda-pre-words { perspective: 800px; }

/* Estado "asentado" genérico (clave para el modo log: las líneas previas quedan
   reveladas). Los reveals específicos lo refinan abajo. */
.onda-pre-words > span.is-done {
	opacity: 1;
	transform: none;
	filter: none;
}

/* ── Reveal: cortina lateral (line-mask) ──────────────────────────────── */
.onda-pre-words--mask > span {
	opacity: 1;
	transform: none;
	filter: none;
	-webkit-clip-path: inset( 0 100% 0 0 );
	clip-path: inset( 0 100% 0 0 );
	transition: -webkit-clip-path 0.5s cubic-bezier( 0.22, 1, 0.36, 1 ), clip-path 0.5s cubic-bezier( 0.22, 1, 0.36, 1 );
}
.onda-pre-words--mask > span:first-child,
.onda-pre-words--mask > span.is-on,
.onda-pre-words--mask > span.is-done {
	-webkit-clip-path: inset( 0 0 0 0 );
	clip-path: inset( 0 0 0 0 );
}
.onda-pre-words--mask > span.is-out {
	-webkit-clip-path: inset( 0 0 0 100% );
	clip-path: inset( 0 0 0 100% );
}

/* ── Reveal: scramble / decode (los glifos los cicla el runtime) ──────── */
.onda-pre-words--scramble > span {
	transform: none;
	filter: none;
	transition: opacity 0.18s ease;
	font-variant-numeric: tabular-nums;
}

/* ── Reveal: flip 3D ───────────────────────────────────────────────────── */
.onda-pre-words--flip > span {
	opacity: 1;
	filter: none;
	transform: rotateX( -90deg );
	transform-origin: center bottom;
	backface-visibility: hidden;
	transition: transform 0.5s cubic-bezier( 0.22, 1, 0.36, 1 ), opacity 0.3s ease;
}
.onda-pre-words--flip > span:first-child,
.onda-pre-words--flip > span.is-on,
.onda-pre-words--flip > span.is-done {
	transform: rotateX( 0deg );
	opacity: 1;
}
.onda-pre-words--flip > span.is-out {
	transform: rotateX( 90deg );
	opacity: 0;
}

/* ── Modo Log: las líneas se apilan (terminal) ────────────────────────── */
.onda-pre-words--log {
	display: block;
	place-items: initial;
	min-height: 0;
	max-height: var( --onda-log-max, none );
	overflow: hidden;
	line-height: 1.5;
}
.onda-pre-words--log > span {
	grid-area: auto;
	display: block;
}
/* Editor (sin runtime → sin la clase --live): mostrar el log completo. */
.onda-pre-words--log:not( .onda-pre-words--live ) > span {
	opacity: 1 !important;
	transform: none !important;
	filter: none !important;
	-webkit-clip-path: none !important;
	clip-path: none !important;
}

/* ── Texto que se rellena: modo Cascada por letra ─────────────────────── */
/* Cada letra pasa de la base tenue al color de relleno cuando --onda-pl-p cruza
   su umbral (--onda-ls, inline por índice). --onda-casc-soft fija la pendiente.
   Default p=1 → todas llenas en el editor. */
.onda-pre-textfill--cascade { white-space: nowrap; }
.onda-pre-textfill__cascade {
	position: absolute;
	inset: 0;
	display: block;
	white-space: nowrap;
	color: #ffffff;
	pointer-events: none;
}
.onda-pre-textfill__cascade > span {
	display: inline-block;
	opacity: clamp( 0, calc( ( var( --onda-pl-p, 1 ) - var( --onda-ls, 0 ) ) * var( --onda-casc-soft, 8 ) ), 1 );
	transition: opacity 0.12s linear;
}

@media ( prefers-reduced-motion: reduce ) {
	.onda-pre-words--mask > span,
	.onda-pre-words--flip > span,
	.onda-pre-words--scramble > span,
	.onda-pre-textfill__cascade > span { transition: none; }
}

/* ══ Pack 4 — Barra: segmentada · indeterminada · etiqueta que viaja ═══════ */

/* ── Segmentada: N bloques que se encienden por umbral inline (--onda-seg-th) ── */
.onda-pre-bar--seg {
	display: inline-flex;
	overflow: visible;
}
.onda-pre-bar--horizontal.onda-pre-bar--seg { flex-direction: row; }
.onda-pre-bar--vertical.onda-pre-bar--seg { flex-direction: column-reverse; }
.onda-pre-seg {
	position: relative;
	flex: 1 1 0;
	background: var( --onda-pre-track, rgba( 255, 255, 255, 0.16 ) );
	border-radius: inherit;
	overflow: hidden;
}
.onda-pre-seg::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var( --onda-pre-active, #ff3d00 );
	/* "Encendido" cuando --onda-pl-p >= umbral: salto duro vía clamp (default p=1). */
	opacity: clamp( 0, calc( ( var( --onda-pl-p, 1 ) - var( --onda-seg-th, 0 ) ) * 1000 ), 1 );
	transition: opacity 0.12s linear;
}

/* ── Indeterminada: banda corta que recorre el track en bucle ─────────── */
.onda-pre-bar--indet { position: relative; overflow: hidden; }
.onda-pre-bar--indet .onda-pre-bar__fill {
	position: absolute;
	transform: none;
	transform-origin: center;
	transition: none;
}
.onda-pre-bar--horizontal.onda-pre-bar--indet .onda-pre-bar__fill {
	top: 0;
	bottom: 0;
	left: 0;
	width: 35%;
	animation: onda-pre-indet-x var( --onda-indet-speed, 1.3s ) cubic-bezier( 0.65, 0, 0.35, 1 ) infinite;
}
.onda-pre-bar--vertical.onda-pre-bar--indet .onda-pre-bar__fill {
	left: 0;
	right: 0;
	top: 0;
	height: 35%;
	animation: onda-pre-indet-y var( --onda-indet-speed, 1.3s ) cubic-bezier( 0.65, 0, 0.35, 1 ) infinite;
}
@keyframes onda-pre-indet-x {
	0%   { left: -40%; }
	100% { left: 100%; }
}
@keyframes onda-pre-indet-y {
	0%   { top: -40%; }
	100% { top: 100%; }
}

/* El wrap toma ancho completo para que el "Largo" en % resuelva contra el ancho
   del cover (sin esto, el wrap es shrink-to-fit y el % colapsa → solo estiraba con
   px). La alineación (text-align del control) sigue posicionando la barra adentro. */
.onda-pre-bar-wrap {
	width: 100%;
}

/* Barra VERTICAL: el "Largo" en % aplica height:% a la barra, que resuelve contra
   la altura del wrap. Sin contexto de altura el wrap es alto-auto → el % colapsa a
   un sliver (lo que se veía). height:100% crece dentro de un cover/contenedor con
   altura definida; min-height da un piso visible en el editor y cuando el contenedor
   del autor no fija altura. Para "% exacto de pantalla" usá la unidad vh en el control. */
.onda-pre-bar-wrap--vert {
	height: 100%;
	min-height: 50vh;
}

/* ── Etiqueta que viaja con la cabeza del relleno (horizontal) ─────────── */
.onda-pre-bar-wrap--labeled {
	position: relative;
	padding-top: 1.6em; /* sitio para la etiqueta encima */
	/* width:100% se hereda de .onda-pre-bar-wrap → el % del Largo sigue resolviendo
	   y la etiqueta viaja sobre el ancho del cover (caso barra full-width con %). */
}
.onda-pre-bar__label {
	position: absolute;
	top: 0;
	left: clamp( 0%, calc( var( --onda-pl-p, 1 ) * 100% ), 100% );
	transform: translateX( -50% );
	white-space: nowrap;
	line-height: 1;
	transition: left 0.12s linear;
	font-variant-numeric: tabular-nums;
}

@media ( prefers-reduced-motion: reduce ) {
	.onda-pre-bar--indet .onda-pre-bar__fill { animation: none; }
	.onda-pre-seg::after,
	.onda-pre-bar__label { transition: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   VISTA PREVIA EN EL EDITOR (2.94.0)
   ────────────────────────────────────────────────────────────────────────
   Estos widgets son nativos de Elementor: viven DENTRO de una plantilla de
   preloader, no son el overlay a pantalla completa (ese se suprime en el editor
   vía is_elementor_editor_context()). En el editor se ven CONTENIDOS dentro de
   su propia caja, a un estado representativo ESTÁTICO:
     · Atados a la carga (barra/anillo/logo/texto que se rellena): el render
       publica --onda-pl-p:0.6 en el wrap → se ven a ~60% (estado intermedio,
       muestra la FORMA del borde/relleno, no un bloque sólido al 100%).
     · Loops de animación (spinner, marquee, sheen, orbit, gooey, morph, draw,
       caret, indeterminada): se CONGELAN a un frame estático (animation-play-state
       paused; sin rAF, sin bucle) — un still honesto del visual.
     · Words: ya muestra la primera línea (:first-child) → still representativo.
     · Counter/Sequence/Media: ya muestran su valor/primer frame.
   Todo va scopeado por [data-onda-pre-editor] (atributo emitido SOLO en el editor)
   → el front queda byte por byte igual. Se conserva el marcador ⚡ "efecto Onda".
   ════════════════════════════════════════════════════════════════════════ */

/* Congela cualquier loop a un frame estático (sin tocar el front). */
[data-onda-pre-editor] *,
[data-onda-pre-editor].onda-pre-marquee .onda-pre-marquee__track {
	animation-play-state: paused !important;
}

/* Marcador ⚡ "efecto Onda" — esquina del wrap, discreto y descubrible. */
[data-onda-pre-editor] {
	position: relative;
}
[data-onda-pre-editor]::after {
	content: "\26A1";
	position: absolute;
	top: -2px;
	right: -2px;
	z-index: 5;
	font-size: 11px;
	line-height: 1;
	opacity: 0.45;
	pointer-events: none;
	color: currentColor;
}
/* El marquee usa ::after del wrap para el degradado de bordes en algunos casos;
   ahí colgamos el marcador del primer item para no pisarlo. */
[data-onda-pre-editor].onda-pre-marquee::after {
	top: 0;
	right: 2px;
}
