/* BAI Base — CSS extra. Especificidad BAJA. Cero valores hardcodeados de diseño:
   todo sale de las custom properties que theme.json genera (--wp--preset--*, --wp--custom--*).
   Aquí solo van comportamientos que theme.json no cubre: header sticky, foco visible,
   una única clase de entrada, y el hueco del elemento firma (al final, comentado). */

/* --- Foco visible global (accesibilidad) --- */
:where(a, button, input, textarea, select, summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
	border-radius: var(--wp--custom--radius--sm);
}

/* --- Header sticky que encoge (H1 del catálogo) --- */
.bai-header {
	position: sticky;
	top: 0;
	z-index: 50;
	min-height: var(--wp--custom--header--height);
	background: var(--wp--preset--color--base);
	transition: min-height var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base),
		background var(--wp--custom--transition--base);
}
.bai-header.is-scrolled {
	min-height: var(--wp--custom--header--height-scrolled);
	box-shadow: 0 1px 0 color-mix(in srgb, var(--wp--preset--color--contrast) 10%, transparent);
}

/* --- Medida de lectura cómoda para bloques de texto largo --- */
.bai-measure { max-width: var(--wp--custom--measure); }

/* --- Una sola clase de entrada (movimiento como puntuación, no decoración) --- */
.bai-enter {
	opacity: 0;
	transform: translateY(var(--bai-motion-recorrido));
	animation: bai-enter-in var(--wp--custom--transition--base) forwards;
}
@keyframes bai-enter-in { to { opacity: 1; transform: none; } }

/* ==========================================================================
   MOVIMIENTO — lo dicta la dirección de arte, no este fichero.
   Todo sale de settings.custom.motion del theme.json compilado:
     --wp--custom--motion--activo          1 / 0   (0 = intensidad "ninguna")
     --wp--custom--motion--duracion        120ms (Neo-Brutal) … 400ms (Lujo)
     --wp--custom--motion--curva           steps(2) … ease-in-out
     --wp--custom--motion--desplazamiento  cuánto viaja un reveal
   Los fallbacks de var() son para temas antiguos sin el bloque motion; el
   valor bueno siempre es el del tema.

   Cómo se apaga TODO sin una sola regla condicional: `activo` es un número, y
   entra multiplicando. Con activo = 0 el recorrido es 0px y la opacidad de
   partida es 1 — el elemento nace donde acaba, y no hay nada que animar.
   ========================================================================== */
:root {
	--bai-motion-activo: var(--wp--custom--motion--activo, 1);
	--bai-motion-recorrido: calc(var(--wp--custom--motion--desplazamiento, 8px) * var(--bai-motion-activo));
	--bai-motion-transicion: var(--wp--custom--motion--duracion, 220ms) var(--wp--custom--motion--curva, ease-out);
}

/* Reveal de sección al entrar en viewport. UNA sola clase (.bai-reveal) y un
   estado (.is-visible) que pone el observador de assets/js/reveal.js.
   El estado de partida sólo existe bajo .bai-js: si el JS no corre (o decide no
   correr), el contenido se ve desde el primer frame. Nada se esconde sin dueño. */
.bai-reveal {
	transition: opacity var(--bai-motion-transicion), transform var(--bai-motion-transicion);
}
.bai-js .bai-reveal {
	opacity: calc(1 - var(--bai-motion-activo));
	transform: translateY(var(--bai-motion-recorrido));
}
.bai-js .bai-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* Hover de enlaces y botones: la misma duración y la misma curva que el resto.
   Con Neo-Brutal (steps(2)) el color salta en dos escalones; con Lujo se derrite
   en 400ms. El markup no sabe nada de esto. */
:where(a, .wp-element-button, .wp-block-button__link, summary, .bai-faq__pregunta) {
	transition: color var(--bai-motion-transicion),
		background-color var(--bai-motion-transicion),
		border-color var(--bai-motion-transicion),
		box-shadow var(--bai-motion-transicion),
		transform var(--bai-motion-transicion);
}
/* El botón se levanta un cuarto del recorrido de la dirección: gesto, no salto. */
:where(.wp-element-button, .wp-block-button__link):hover {
	transform: translateY(calc(var(--bai-motion-recorrido) * -0.25));
}

/* --- El MOTOR toma el mando (assets/js/motion.js) --------------------------
   .bai-motor sólo aparece si motion.js ha decidido correr: hay bundle de GSAP,
   la dirección no está en intensidad "ninguna" y nadie ha pedido menos
   movimiento. A partir de ahí el estado de las secciones lo escribe GSAP inline
   y este fichero se aparta: dos motores peleando por la misma propiedad es
   exactamente cómo se consigue un tirón. Si el bundle no llega, .bai-motor no
   existe, y manda el reveal por CSS de aquí arriba con reveal.js detrás. */
.bai-motor .bai-reveal { transition: none; }
.bai-motor.bai-js .bai-reveal,
.bai-motor.bai-js .bai-reveal.is-visible { opacity: 1; transform: none; }

/* Titular partido en líneas por el motor: cada línea es una caja de bloque para
   poder escalonarlas. Sin overflow:hidden a propósito — con el line-height 1.04
   de los titulares, una máscara recortaría los descendentes. */
.bai-linea { display: block; }

/* Cifras que cuentan: cifras tabulares mientras corre el contador, para que los
   dígitos no bailen de ancho en cada frame. */
.bai-motor .bai-cifra { font-variant-numeric: tabular-nums; }

/* Hover de botón: con el motor puesto lo conduce GSAP (imán o salto seco, según
   la dirección), así que se retira la transición CSS de transform. El color, el
   fondo y el borde los sigue haciendo el CSS con la curva de la dirección. */
.bai-motor :where(.wp-element-button, .wp-block-button__link) {
	transition-property: color, background-color, border-color, box-shadow;
}
.bai-motor :where(.wp-element-button, .wp-block-button__link):hover { transform: none; }

/* Lenis — copiado literal de node_modules/lenis/dist/lenis.css (MIT, ver
   assets/js/vendor/LICENSE.lenis.txt). Sin estas reglas el scroll suave pelea
   con el nativo dentro de los contenedores con scroll propio y con los iframes. */
html.lenis,
html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }
.lenis.lenis-autoToggle {
	transition-property: overflow;
	transition-duration: 1ms;
	transition-behavior: allow-discrete;
}

/* Respeta a quien pide menos movimiento (obligatorio). */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
	.bai-enter { opacity: 1; transform: none; }
	/* Cinturón y tirantes: reveal.js ni siquiera pone .bai-js con reduced-motion,
	   pero si algo lo pusiera, el contenido sigue visible y quieto. */
	.bai-js .bai-reveal,
	.bai-js .bai-reveal.is-visible { opacity: 1 !important; transform: none !important; }
	:where(.wp-element-button, .wp-block-button__link):hover { transform: none; }
	/* Lo mismo con el motor: motion.js sale antes de tocar el DOM si hay
	   reduced-motion (no arranca Lenis ni una sola animación), pero si alguien
	   pusiera .bai-motor a mano, la página sigue entera, visible y quieta. */
	.bai-motor .bai-reveal,
	.bai-motor .bai-linea { opacity: 1 !important; transform: none !important; }
}

/* --- Utilidades de ritmo (fondos de sección, consumiendo presets) --- */
.bai-section--dark {
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
}
.bai-section--dark :where(h1,h2,h3,h4) { color: var(--wp--preset--color--on-dark); }
.bai-section--alt { background: var(--wp--preset--color--base-alt); }

/* ==========================================================================
   ELEMENTO FIRMA (D6 del brief) — se activa por instancia de cliente.
   El CSS del gesto único va AQUÍ, comentado, con la decisión del brief al lado.
   Ejemplo (bai-base no define firma; cada cliente la escribe):
   .bai-firma { ... }   // Decisión D6: <qué es y por qué es memorable para este cliente>
   ========================================================================== */

/* --- Carril de contenido (equivalente al .p-wrap del prototipo estatico).
   Las secciones full-bleed usan layout default + este carril interior para que los hijos
   queden alineados a la IZQUIERDA del carril (constrained centraria cada hijo con max-width). --- */
.bai-wrap {
	max-width: calc(1200px + 2 * var(--wp--preset--spacing--30));
	margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--30);
}
.bai-wrap--narrow { max-width: calc(860px + 2 * var(--wp--preset--spacing--30)); }

/* ==========================================================================
   CATÁLOGO DE SECCIONES — comportamientos que theme.json no puede declarar.
   Ni un color, ni una familia, ni un tamaño de letra literal: todo por token.
   ========================================================================== */

/* --- Etiqueta de sección (utility-mono en acento) --------------------------
   Primitiva de estructura: dice de qué va la sección antes del titular y da ritmo
   al recorrido. NO es el elemento firma del cliente (D6) — eso lo escribe cada
   instancia; esto es la etiqueta que el catálogo usa en todas sus secciones. */
.bai-etiqueta {
	display: inline-block;
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
	margin: 0 0 var(--wp--preset--spacing--20);
}
.bai-section--dark .bai-etiqueta { color: var(--wp--preset--color--on-dark); }

/* --- Hueco de imagen (placeholder neutro y VISIBLE) ------------------------
   La capa de imagen (orden 2/2) sustituye el contenido de estos huecos por la
   imagen tratada. Mientras tanto se ve un rectángulo con su ratio y su etiqueta:
   un hueco marcado es honesto; una sección que se descuadra al llegar la foto, no. */
.bai-hueco {
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	overflow: hidden;
	background: var(--wp--preset--color--base-alt);
	box-shadow: inset 0 0 0 1px var(--wp--preset--color--contrast-soft);
	border-radius: var(--wp--custom--radius--sm);
}
.bai-hueco > * {
	margin: 0;
	padding: var(--wp--preset--spacing--20);
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast-soft);
}
.bai-hueco--retrato  { aspect-ratio: 4 / 5; }
.bai-hueco--paisaje  { aspect-ratio: 16 / 9; }
.bai-hueco--cuadro   { aspect-ratio: 1 / 1; }
/* Franja a sangre: alto contenido (nunca se come la pantalla entera). */
.bai-hueco--franja {
	aspect-ratio: 21 / 9;
	min-height: 46vh;
	max-height: 72vh;
	border-radius: 0;
}

/* --- Franja full-bleed con titular superpuesto opcional -------------------- */
.bai-franja { position: relative; }
.bai-franja__texto {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--30);
	/* Velo desde la tinta del tema: legibilidad sin inventar un color. */
	background: linear-gradient(
		to top,
		color-mix(in srgb, var(--wp--preset--color--dark) 78%, transparent),
		transparent
	);
}
.bai-franja__texto :where(h1, h2, h3, p) { color: var(--wp--preset--color--on-dark); }

/* --- Numeral grande de "cómo trabajamos" ---------------------------------- */
.bai-numeral {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--huge);
	line-height: 0.9;
	color: var(--wp--preset--color--accent);
	margin: 0 0 var(--wp--preset--spacing--20);
}

/* --- Cifra grande del caso destacado -------------------------------------- */
.bai-cifra {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--giant);
	line-height: 0.85;
	margin: 0;
}

/* --- Caso destacado: la repetición alterna lados --------------------------
   Sólo a partir del punto en que wp:columns deja de apilar (782px, el de WP);
   apilado, invertir el orden dejaría la imagen debajo del texto en unos casos
   y encima en otros. */
@media (min-width: 782px) {
	.wp-block-columns.bai-caso--invertido { flex-direction: row-reverse; }
}

/* --- FAQ editorial: details/summary nativo, cero JS ------------------------
   Los filetes son los de la lista de servicios (borde superior + aire). */
.bai-faq__item {
	border-top: 1px solid var(--wp--preset--color--contrast-soft);
}
.bai-faq__item > summary {
	cursor: pointer;
	list-style: none;
	display: flex;
	gap: var(--wp--preset--spacing--30);
	align-items: baseline;
	justify-content: space-between;
	padding: var(--wp--preset--spacing--30) 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1.15;
}
.bai-faq__item > summary::-webkit-details-marker { display: none; }
/* El signo lo pone el CSS (no el texto): + cerrado, − abierto. */
.bai-faq__item > summary::after {
	content: "+";
	flex: 0 0 auto;
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--large);
	color: var(--wp--preset--color--accent);
	transition: transform var(--bai-motion-transicion);
}
.bai-faq__item[open] > summary::after { content: "−"; }
.bai-faq__item > summary:hover { color: var(--wp--preset--color--accent); }
.bai-faq__respuesta {
	padding-bottom: var(--wp--preset--spacing--30);
	color: var(--wp--preset--color--contrast-soft);
	max-width: var(--wp--custom--measure);
}
