/*
Theme Name: BiiLinx
Theme URI: https://global-linx.com
Author: BiiSmart Group
Author URI: https://biismart.com
Description: Theme de bloques de BiiLinx, la unidad de consultoria de compras en Asia de BiiSmart Group. Todo el contenido se edita desde el editor de bloques. Ningun texto de cara al publico vive dentro de un archivo PHP.
Version: 0.3.0-exploracion
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: Propietario
Text Domain: biilinx
Tags: block-theme, full-site-editing, translation-ready
*/

/*
   Este archivo existe por el encabezado de arriba, que es lo que WordPress lee para
   reconocer el theme. Los estilos de verdad viven en theme.json.

   Lo que va aca es solo lo que theme.json no sabe expresar:
   utilidades, estados y detalles de composicion.
*/

/* --------------------------------------------------------------------------
   Etiqueta: el estilo "Etiqueta" del brandkit es versalita espaciada.
   theme.json define el tamano y el peso, el resto va aca.

   El color era Teal Linx y se cambio a Verde Linx por contraste medido: el teal
   #239193 sobre blanco da 3.79:1 y sobre Fondo Claro 3.54:1, y la etiqueta es
   texto de 18 px, o sea que le corresponde el piso de 4.5:1 de WCAG AA y no el
   de 3:1 de texto grande. Verde Linx #197C7E da 4.97:1 sobre blanco y 4.64:1
   sobre Fondo Claro. El brandkit ademas le asigna a Verde Linx justamente los
   titulares y nombres, que es lo que una etiqueta es.

   Donde la etiqueta va sobre fondo oscuro, el bloque le pone encima
   has-menta-linx-color, que WordPress emite con !important y gana: el hero y
   el pie no cambian.
   -------------------------------------------------------------------------- */
.is-style-etiqueta {
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--verde-linx);
}

/* --------------------------------------------------------------------------
   Dato: el numero grande de las tarjetas de dato. Va en menta, nunca en texto
   corrido, porque el brandkit reserva el menta para acentos y CTA.
   -------------------------------------------------------------------------- */
.is-style-dato {
	color: var(--wp--preset--color--menta-linx);
	font-weight: 700;
	line-height: 1;
}

/* --------------------------------------------------------------------------
   Convivencia latin / CJK.

   Regla del brandkit: nunca estirar ni condensar los glifos chinos para igualar
   el ancho del latin. Por eso el chino no se resuelve escalando Montserrat sino
   cambiando de familia. Se aplica por atributo lang para que funcione tambien
   cuando conviven los dos idiomas en el mismo bloque.
   -------------------------------------------------------------------------- */
:lang(zh),
:lang(zh-CN),
:lang(zh-Hans) {
	font-family: var(--wp--preset--font-family--noto-sans-sc);
	line-height: 1.75; /* el CJK necesita mas aire vertical que el latin */
	letter-spacing: 0;
}

/* --------------------------------------------------------------------------
   Overlay de marca sobre foto.
   El brandkit lo fija entre 40% y 60% de Negro Verde. Se toma el punto medio.
   -------------------------------------------------------------------------- */
.has-overlay-marca {
	position: relative;
	isolation: isolate;
}

.has-overlay-marca::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--wp--preset--color--negro-verde);
	opacity: 0.5;
	z-index: -1;
	pointer-events: none;
}

/* --------------------------------------------------------------------------
   Accesibilidad: el foco visible no se elimina nunca.

   El anillo era de un solo color, Menta Linx, y ese es el problema: medido,
   el menta #2FC7B5 da 2.11:1 sobre blanco y 1.97:1 sobre Fondo Claro. WCAG
   2.4.11 pide 3:1 del indicador de foco contra lo que tiene al lado, asi que
   sobre las superficies claras del sitio, que son la mayoria, el anillo
   practicamente no se veia. Sobre Negro Verde, en cambio, el menta da 8.64:1
   y funciona muy bien.

   Por eso el anillo pasa a ser de dos tonos y no de uno solo, que es la unica
   forma de que sirva sobre claro y sobre oscuro sin escribir una regla por
   superficie:

     - un aro interior de 2 px en Menta Linx, que es el que se ve sobre el
       hero y sobre el pie;
     - un aro exterior de 3 px en Verde Profundo, 7.29:1 sobre blanco y
       6.81:1 sobre Fondo Claro, que es el que se ve sobre las claras.

   El box-shadow con spread de 2 px llena exactamente el hueco que deja
   outline-offset: 2px, asi que los dos aros quedan pegados y se leen como un
   solo indicador.
   -------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 3px solid var(--wp--preset--color--verde-profundo);
	outline-offset: 2px;
	box-shadow: 0 0 0 2px var(--wp--preset--color--menta-linx);
}

/* --------------------------------------------------------------------------
   Respeto por la preferencia de movimiento reducido.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* --------------------------------------------------------------------------
   El video del hero, y la preferencia de movimiento reducido.

   La regla de arriba apaga animaciones y transiciones, pero NO apaga un
   <video autoplay loop>, que es contenido en movimiento y sigue corriendo. El
   hero de la portada tiene uno, del skyline de Shenzhen, en bucle infinito.

   Para quien pidio movimiento reducido se cambia el video por su poster, que
   es un fotograma del mismo material: la imagen no se pierde, solo deja de
   moverse. El poster va siempre en el HTML y se oculta por defecto, porque
   decidirlo por CSS es lo unico que respeta la preferencia sin JavaScript.

   Lo que esto NO resuelve, y queda anotado: WCAG 2.2.2 pide un control para
   pausar el movimiento, no solo respetar la preferencia del sistema. Un boton
   de pausa sobre el hero es el arreglo completo y necesita verse renderizado
   antes de escribirlo.
   -------------------------------------------------------------------------- */
.biilinx-hero-poster {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-cover__video-background {
		display: none;
	}

	.biilinx-hero-poster {
		display: block;
	}
}

/* --------------------------------------------------------------------------
   Logo del pie.

   El pie va sobre Negro Verde y el logo del sitio es la version en teal, que
   ahi no se lee. La biblioteca de marca tiene el archivo blanco oficial
   (biilinx-white-transparent-bg), pero apuntarlo desde el template part
   obligaria a escribir a mano la URL del sitio y el ID del adjunto, y las dos
   cosas cambian al pasar a produccion. Un template part con una URL de
   staging adentro es una bomba de tiempo.

   Se invierte el mismo adjunto con un filtro. El logo es una marca de un solo
   color plano, asi que brightness(0) invert(1) da exactamente el blanco del
   archivo oficial. No se rearma el lockup ni se toca el espaciado, que es lo
   que la guia de marca prohibe: se cambia el color de una pieza de un color.
   -------------------------------------------------------------------------- */
.biilinx-logo-pie img {
	filter: brightness(0) invert(1);
}

/* ==========================================================================
   EXPLORACION VISUAL · portacion del tratamiento "perpetuity" de 21st.dev
   ==========================================================================

   QUE ES ESTO Y POR QUE NO HAY REACT.

   El pedido llego como una lista de componentes de 21st.dev, que son React con
   shadcn y Tailwind, para pegar en /components/ui. Este theme es un block theme
   de WordPress en PHP: 7 templates .html, 2 parts y patrones. No hay Node, no
   hay build, no hay JSX.

   Se descarto montar el stack. Los motivos, para que no haya que reconstruirlos:

     1. Meter Tailwind y un bundler obliga a un paso de build entre el repo y el
        servidor. Hoy bin/deploy-theme.sh publica el theme tal como esta en git,
        y eso es lo que hace que el rollback sea un rename. Con build, lo que
        corre en el servidor deja de ser lo que se lee en el repo.
     2. Tailwind y theme.json resuelven el MISMO problema, los tokens de diseño,
        y quedarian los dos. El editor de bloques seguiria ofreciendo la paleta
        de theme.json mientras el CSS real vendria de otra parte.
     3. React se come el editor de bloques. La regla del proyecto es que ningun
        texto de cara al publico viva en un archivo, y que marketing edite todo
        desde el panel. Un hero en JSX rompe eso.

   Asi que se porto el DISEÑO, no el codigo: cada componente de referencia se
   leyo, se extrajo su gramatica visual, y se rehizo con patrones, theme.json y
   este archivo. Lo que se gano: cero dependencias nuevas, el editor sigue
   editando, y el deploy sigue siendo un rsync. Lo que se perdio esta anotado en
   docs/exploracion-visual.md, componente por componente.

   ORDEN DE ESTE ARCHIVO: primero el modo oscuro, que es la base de todo lo de
   abajo, y despues una seccion por componente.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   MODO OSCURO DE MARCA

   perpetuity es un tema oscuro. La marca de BiiLinx no lo es: su paleta es
   verde y teal sobre blanco. Lo que se porto es el TRATAMIENTO, no la paleta:
   fondo Negro Verde, superficies apenas elevadas, un borde tenue que hace el
   trabajo que la sombra no puede hacer sobre oscuro, y el menta como unico
   acento. Ningun color nuevo fuera de los tres tokens de superficie.

   CONTRASTES MEDIDOS con WCAG 2.1 contra Negro Verde #0B1811:

     blanco       #FFFFFF   18.21:1
     texto-tenue  #A8C0BA    9.47:1
     menta-linx   #2FC7B5    8.64:1
     verde-senal  #009488    4.85:1
     teal-linx    #239193    4.81:1

   Y contra Superficie #10231C, que es el fondo real de las tarjetas:

     blanco       16.42:1
     texto-tenue  10.03:1
     menta-linx    7.78:1
     teal-linx     4.33:1   <-- POR DEBAJO de 4.5:1

   DE AHI SALE UNA REGLA QUE NO SE NEGOCIA: sobre una tarjeta, el acento y los
   enlaces van en MENTA, nunca en teal. El teal pasa AA sobre el fondo de la
   pagina y no lo pasa sobre las tarjetas, que es justo donde uno lo pondria sin
   medir. El teal queda para fondos planos y para el gradiente de marca.

   Las superficies dan 1.11:1 y 1.30:1 contra el fondo, o sea que por si solas
   son invisibles. Por eso cada tarjeta lleva borde: sobre oscuro la elevacion
   se comunica con el borde, no con la sombra.
   -------------------------------------------------------------------------- */
.blx-oscuro {
	--blx-borde: rgba(168, 192, 186, 0.16);
	--blx-borde-fuerte: rgba(168, 192, 186, 0.28);
	--blx-vidrio: rgba(16, 35, 28, 0.72);

	background-color: var(--wp--preset--color--negro-verde);
	color: var(--wp--preset--color--texto-tenue);
}

/* Los titulares heredan Verde Linx de theme.json, que sobre oscuro da 2.3:1 y
   no se lee. Sobre superficie oscura pasan a blanco. */
.blx-oscuro :where(h1, h2, h3, h4) {
	color: var(--wp--preset--color--blanco);
}

.blx-oscuro :where(a):not(.wp-element-button) {
	color: var(--wp--preset--color--menta-linx);
}

/* La etiqueta versalita: sobre claro va en Verde Linx por contraste, sobre
   oscuro ese verde da 2.4:1. Aca va en menta, que da 8.64:1. */
.blx-oscuro .is-style-etiqueta {
	color: var(--wp--preset--color--menta-linx);
}


/* --------------------------------------------------------------------------
   1 · HERO  ·  de galaxy-interactive-hero-section

   Lo que se tomo del componente: la navbar fija con vidrio esmerilado, el
   titular a la izquierda y no centrado, los dos botones de forma pildora con el
   primero translucido y borde en vez de relleno solido, el velo en dos
   gradientes (uno lateral y uno inferior), y el contenido que se desvanece al
   bajar mientras el fondo queda.

   LO QUE NO SE TOMO, Y ES EL PUNTO IMPORTANTE: la escena de Spline.

   El componente trae una galaxia 3D servida desde prod.spline.design. Este hero
   ya tiene un video del skyline de Shenzhen, que es material propio y es lo que
   el pedido dijo respetar. Cambiarlo por una galaxia generica habria sido tirar
   lo unico del hero que es de la empresa para poner lo que cualquiera puede
   poner. Ademas: un iframe a un tercero en el hero es el peor lugar posible
   para un LCP, y el video ya esta en la biblioteca de medios.

   Asi que el video se queda y lo que se porto es el tratamiento alrededor: los
   dos velos, la tipografia, la alineacion y el desvanecimiento.
   -------------------------------------------------------------------------- */
.blx-hero {
	position: relative;
	isolation: isolate;
}

/* Los dos velos del componente, uno arriba del otro. El lateral abre el centro
   para que el skyline se vea y cierra los bordes para que el texto blanco tenga
   contraste sin importar que fotograma este pasando. El inferior funde el hero
   con la seccion que sigue. */
.blx-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background:
		var(--wp--preset--gradient--velo-hero),
		var(--wp--preset--gradient--velo-inferior);
}

.blx-hero .wp-block-cover__inner-container {
	position: relative;
	z-index: 2;
	max-width: 62ch;
	margin-inline: 0;
	text-align: left;
}

/* El desvanecimiento al bajar. El componente lo hace con un listener de scroll
   y requestAnimationFrame; aca se hace con una animacion guiada por el scroll,
   que corre en el compositor y no en el hilo principal.

   La @supports no es decorativa: donde no hay animation-timeline el hero queda
   opaco y quieto, que es un estado perfectamente bueno. Nada depende de que la
   animacion exista. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.blx-hero .wp-block-cover__inner-container {
			animation: blx-desvanecer linear both;
			animation-timeline: view();
			animation-range: exit 0% exit 65%;
		}
	}
}

@keyframes blx-desvanecer {
	from { opacity: 1; transform: none; }
	to   { opacity: 0; transform: translateY(-2.5rem); }
}

/* El titular del componente lleva tracking abierto en los tamaños grandes.
   theme.json le pone -0.02em, que es lo correcto para un titular de 4.875rem
   sobre claro. Sobre el video, con el peso 700 y el blanco, el texto se cierra
   demasiado. */
.blx-hero h1 {
	letter-spacing: -0.01em;
	text-wrap: balance;
}

/* Boton translucido con borde, la firma visual del componente. Se aplica como
   estilo de bloque para que el editor lo elija desde la barra lateral y no
   pueda inventar una variante. */
.wp-block-button.is-style-vidrio .wp-block-button__link {
	background-color: rgba(47, 199, 181, 0.16);
	border: 1px solid var(--wp--preset--color--menta-linx);
	color: var(--wp--preset--color--blanco);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
}

.wp-block-button.is-style-vidrio .wp-block-button__link:hover,
.wp-block-button.is-style-vidrio .wp-block-button__link:focus-visible {
	background-color: rgba(47, 199, 181, 0.28);
}


/* --------------------------------------------------------------------------
   2 · NAVBAR  ·  de @AliFarooqDev/components/navbar

   Barra fija, fondo de vidrio, esquinas inferiores redondeadas, y el detalle
   que la define: cuando el puntero entra en un item, los OTROS se apagan. El
   componente lo hace con estado de React (hoveredNavItem) y tres clases de
   color; aca sale de :hover en el contenedor mas :not(:hover) en el hermano,
   sin una linea de JavaScript.

   La barra es position: sticky y no fixed. fixed la saca del flujo y hay que
   compensar con padding en el body, que en un block theme significa tocar el
   template. sticky se queda en el flujo y no compensa nada.
   -------------------------------------------------------------------------- */
.blx-nav {
	position: sticky;
	top: 0;
	z-index: 30;
	background: var(--blx-vidrio, rgba(16, 35, 28, 0.72));
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 0 0 15px 15px;
}

/* El apagado de los hermanos. Se limita a punteros finos: en tactil no hay
   hover real y el navegador lo emula al tocar, con lo cual el menu parpadearia
   al navegarlo con el dedo. */
@media (hover: hover) and (pointer: fine) {
	.blx-nav .wp-block-navigation__container:hover
	.wp-block-navigation-item:not(:hover) > a {
		color: rgba(168, 192, 186, 0.55);
	}
}

.blx-nav .wp-block-navigation-item > a {
	transition: color 150ms ease;
}

.blx-nav .wp-block-navigation-item > a:hover {
	color: var(--wp--preset--color--blanco);
}


/* --------------------------------------------------------------------------
   3 · TARJETAS DE DATO  ·  de @sean0205/components/statistics-card-1

   Numero grande arriba, etiqueta abajo, borde tenue, y un acento de color que
   sube desde el pie de la tarjeta al pasar el puntero.

   El numero usa el tamaño "dato" que theme.json ya tenia definido y el estilo
   de bloque "dato" que ya estaba registrado en functions.php. No se invento
   nada: el brandkit ya reservaba el menta para el numero.

   font-variant-numeric: tabular-nums es lo que evita que una fila de numeros
   con anchos distintos baile. En Montserrat variable el 1 es mucho mas angosto
   que el 7.
   -------------------------------------------------------------------------- */
.blx-dato-tarjeta {
	position: relative;
	overflow: hidden;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 14px;
	background-color: var(--wp--preset--color--superficie);
	transition: border-color 200ms ease, transform 200ms ease;
}

.blx-dato-tarjeta::before {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 2px;
	background: var(--wp--preset--gradient--gradiente-linx);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 260ms ease;
}

.blx-dato-tarjeta:hover,
.blx-dato-tarjeta:focus-within {
	border-color: var(--blx-borde-fuerte, rgba(168, 192, 186, 0.28));
	transform: translateY(-2px);
}

.blx-dato-tarjeta:hover::before,
.blx-dato-tarjeta:focus-within::before {
	transform: scaleX(1);
}

.blx-dato-tarjeta .is-style-dato {
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.03em;
}


/* --------------------------------------------------------------------------
   4 · BENTO DEL BLOG  ·  de @kinfe123/components/bento

   Grilla asimetrica donde la primera celda ocupa el doble. El componente la
   arma con clases de Tailwind por breakpoint; aca sale de grid-template-columns
   con auto-fit, o sea que el numero de columnas lo decide el ancho disponible y
   no una lista de breakpoints.

   POR QUE auto-fit Y NO breakpoints: el sitio tiene tres idiomas y los titulos
   en chino ocupan la mitad del ancho que en español. Una grilla atada a
   breakpoints se rompe en uno de los tres. auto-fit no.

   La celda destacada solo se agranda cuando hay al menos dos columnas de 22rem,
   porque en una sola columna "ocupar el doble" no significa nada.
   -------------------------------------------------------------------------- */
.blx-bento .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--30);
}

.blx-bento .wp-block-post-template > li {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 16px;
	background-color: var(--wp--preset--color--superficie);
	padding: var(--wp--preset--spacing--30);
	transition: border-color 200ms ease, background-color 200ms ease;
}

.blx-bento .wp-block-post-template > li:hover {
	border-color: var(--blx-borde-fuerte, rgba(168, 192, 186, 0.28));
	background-color: var(--wp--preset--color--superficie-alta);
}

@media (min-width: 48rem) {
	.blx-bento .wp-block-post-template > li:first-child {
		grid-column: span 2;
	}
}

/* El titulo de la tarjeta hereda blanco del modo oscuro. El enlace de adentro
   heredaria menta y se veria como un enlace suelto en vez de un titular. */
.blx-bento .wp-block-post-title a {
	color: var(--wp--preset--color--blanco);
	text-decoration: none;
}

.blx-bento .wp-block-post-title a:hover {
	color: var(--wp--preset--color--menta-linx);
}

/* La imagen destacada se recorta a una franja para que las tarjetas queden
   parejas sin importar el alto del original. */
.blx-bento .wp-block-post-featured-image img {
	width: 100%;
	height: 12rem;
	object-fit: cover;
	border-radius: 10px;
}

@media (min-width: 48rem) {
	.blx-bento .wp-block-post-template > li:first-child
	.wp-block-post-featured-image img {
		height: 18rem;
	}
}


/* --------------------------------------------------------------------------
   5 · CTA CON GALERIA  ·  de @youcefbnm/components/cta-section-with-gallery

   Texto a un lado, un abanico de imagenes al otro, cada una rotada un poco y
   solapada con la anterior. Al pasar el puntero por el grupo, el abanico se
   abre.

   Las imagenes son los cinco "hero" de servicio que ya estan en la biblioteca
   (maritimo, aereo, terrestre, metodo, otros). No entro ni una imagen nueva al
   repositorio: la regla del proyecto pide .webp hermano y peso optimizado para
   todo lo que entra, y estas ya estan en WebP en la biblioteca.

   La rotacion va en el CSS y no en cada bloque para que el editor no tenga que
   acertar cinco angulos a mano.
   -------------------------------------------------------------------------- */
.blx-abanico {
	display: flex;
	justify-content: center;
	padding-block: var(--wp--preset--spacing--30);
}

.blx-abanico .wp-block-image {
	flex: 0 0 auto;
	width: clamp(7rem, 18vw, 11rem);
	margin: 0;
	border-radius: 12px;
	overflow: hidden;
	border: 1px solid var(--blx-borde-fuerte, rgba(168, 192, 186, 0.28));
	box-shadow: var(--wp--preset--shadow--media);
	transition: transform 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.blx-abanico .wp-block-image img {
	display: block;
	width: 100%;
	height: 14rem;
	object-fit: cover;
}

.blx-abanico .wp-block-image + .wp-block-image {
	margin-left: -2.5rem;
}

.blx-abanico .wp-block-image:nth-child(1) { transform: rotate(-9deg) translateY(0.5rem); }
.blx-abanico .wp-block-image:nth-child(2) { transform: rotate(-4deg); }
.blx-abanico .wp-block-image:nth-child(3) { transform: rotate(0deg) translateY(-0.5rem); z-index: 2; }
.blx-abanico .wp-block-image:nth-child(4) { transform: rotate(4deg); }
.blx-abanico .wp-block-image:nth-child(5) { transform: rotate(9deg) translateY(0.5rem); }

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
	.blx-abanico:hover .wp-block-image { margin-left: -1rem; }
	.blx-abanico:hover .wp-block-image:nth-child(1) { transform: rotate(-13deg) translateY(0.25rem); }
	.blx-abanico:hover .wp-block-image:nth-child(5) { transform: rotate(13deg) translateY(0.25rem); }
}

/* En pantallas angostas el abanico se convierte en una tira que se desliza.
   Solapadas y rotadas, cinco imagenes en 360 px no se leen. */
@media (max-width: 47.99rem) {
	.blx-abanico {
		overflow-x: auto;
		justify-content: flex-start;
		scroll-snap-type: x mandatory;
		gap: var(--wp--preset--spacing--20);
	}

	.blx-abanico .wp-block-image {
		scroll-snap-align: center;
		transform: none !important;
		margin-left: 0 !important;
	}
}


/* --------------------------------------------------------------------------
   6 · TESTIMONIOS  ·  de @jatin-yadav05/components/clean-testimonial

   Tarjeta sobria: la cita en tamaño de titular, el autor abajo con avatar
   redondo, y una comilla decorativa grande y muy tenue detras.

   La comilla va como ::before con aria-hidden implicito, o sea que no la lee
   ningun lector de pantalla. Si fuera texto en el HTML, un lector la anunciaria
   antes de cada cita.
   -------------------------------------------------------------------------- */
.blx-testimonio {
	position: relative;
	overflow: hidden;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 16px;
	background-color: var(--wp--preset--color--superficie);
	padding: var(--wp--preset--spacing--40);
}

.blx-testimonio::before {
	content: "\201C";
	position: absolute;
	top: -2.5rem;
	right: 0.5rem;
	font-size: 12rem;
	line-height: 1;
	color: var(--wp--preset--color--menta-linx);
	opacity: 0.09;
	pointer-events: none;
	user-select: none;
}

.blx-testimonio blockquote,
.blx-testimonio .wp-block-quote {
	margin: 0;
	border: 0;
	padding: 0;
	font-size: var(--wp--preset--font-size--subtitulo);
	line-height: 1.35;
	color: var(--wp--preset--color--blanco);
	font-weight: 500;
	text-wrap: pretty;
}

.blx-testimonio cite {
	display: block;
	margin-top: var(--wp--preset--spacing--30);
	font-style: normal;
	font-size: var(--wp--preset--font-size--etiqueta);
	color: var(--wp--preset--color--texto-tenue);
}


/* --------------------------------------------------------------------------
   7 · OFICINAS  ·  de @shuding/components/cobe-globe-pulse

   ACA HAY UNA SUSTITUCION DECLARADA, no una copia.

   El componente original dibuja un globo terraqueo en WebGL con la libreria
   cobe y le pone pulsos en las ciudades. cobe es una dependencia npm y sin
   build no entra. Descargar el bundle y versionarlo dentro del theme habria
   metido una libreria de un tercero, minificada e imposible de revisar, en un
   repositorio donde todo lo demas se lee.

   Lo que se porto es el MECANISMO, que es lo que hace bueno al componente: seis
   puntos que laten sobre un mapa, uno por oficina, con el nombre al lado. En
   vez de WebGL, seis puntos posicionados en porcentajes sobre el mapa de fondo
   y un keyframe de dos anillos. Cero dependencias, funciona sin JavaScript, y
   es legible.

   Lo que se pierde y hay que decirlo: no rota, no se puede arrastrar, y la
   proyeccion es la del mapa que se use de fondo y no una esfera de verdad. Si
   algun dia se quiere el globo real, la conversacion es sobre montar el build,
   no sobre este archivo.

   LAS COORDENADAS SON APROXIMADAS Y ESTAN A OJO SOBRE EL MAPA. No son
   lat/long: son porcentajes del contenedor. Si se cambia el mapa de fondo hay
   que rehacerlas, y por eso cada punto lleva su ciudad en el nombre de la
   clase en vez de un indice.
   -------------------------------------------------------------------------- */
.blx-mapa {
	position: relative;
	aspect-ratio: 2 / 1;
	width: 100%;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 18px;
	overflow: hidden;
	background-color: var(--wp--preset--color--superficie);
}

.blx-mapa__fondo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.32;
	filter: grayscale(1);
}

.blx-mapa__punto {
	position: absolute;
	width: 0.75rem;
	height: 0.75rem;
	margin: -0.375rem 0 0 -0.375rem;
	border-radius: 50%;
	background: var(--wp--preset--color--menta-linx);
	box-shadow: 0 0 0 2px rgba(11, 24, 17, 0.8);
}

/* El anillo que late. Va en ::after para que el punto quede quieto y solo el
   anillo crezca: un punto que cambia de tamaño se lee como un error de render,
   un anillo que se expande se lee como una señal. */
.blx-mapa__punto::after {
	content: "";
	position: absolute;
	inset: -0.25rem;
	border-radius: 50%;
	border: 1px solid var(--wp--preset--color--menta-linx);
	animation: blx-latido 2.8s ease-out infinite;
}

/* Los seis puntos se escalonan para que no laten al unisono, que es lo que
   convierte seis oficinas en una guirnalda de navidad. */
.blx-mapa__punto--mexico    { top: 41%; left: 20%; }
.blx-mapa__punto--panama    { top: 49%; left: 25%; }
.blx-mapa__punto--colombia  { top: 54%; left: 27%; animation-delay: 0.4s; }
.blx-mapa__punto--espana    { top: 33%; left: 47%; }
.blx-mapa__punto--china     { top: 40%; left: 76%; }
.blx-mapa__punto--hongkong  { top: 44%; left: 78%; }

.blx-mapa__punto--panama::after   { animation-delay: 0.45s; }
.blx-mapa__punto--colombia::after { animation-delay: 0.9s; }
.blx-mapa__punto--espana::after   { animation-delay: 1.35s; }
.blx-mapa__punto--china::after    { animation-delay: 1.8s; }
.blx-mapa__punto--hongkong::after { animation-delay: 2.25s; }

@keyframes blx-latido {
	0%   { transform: scale(1);   opacity: 0.9; }
	70%  { transform: scale(3.2); opacity: 0; }
	100% { transform: scale(3.2); opacity: 0; }
}

/* La regla global de movimiento reducido de mas arriba lleva la duracion a
   0.01ms con !important, asi que el latido se detiene. Queda el punto, que es
   la informacion. No hace falta nada mas aca. */

.blx-mapa__nombre {
	position: absolute;
	transform: translate(0.9rem, -0.7rem);
	font-size: 0.875rem;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--blanco);
	white-space: nowrap;
	text-shadow: 0 1px 3px rgba(11, 24, 17, 0.95);
}

/* Debajo de 40rem el mapa se reduce tanto que seis nombres se encaballan. Se
   ocultan los nombres y queda la lista de texto que el patron pone al lado,
   que es la que de verdad se lee. */
@media (max-width: 39.99rem) {
	.blx-mapa__nombre { display: none; }
}


/* --------------------------------------------------------------------------
   8 · MEDIA QUE SE EXPANDE AL SCROLL  ·  de @arunachalam/scroll-expansion-hero

   SE EVALUO Y SE USA, pero no donde el componente lo pone.

   El original lo usa de hero: la pagina abre con un media chico que se expande
   a pantalla completa mientras uno baja. Aca el hero ya tiene el video del
   skyline y el pedido dijo respetarlo, asi que poner dos heros que compiten no
   tenia sentido.

   Donde si funciona es en "Servicio integral", que es la seccion que explica la
   cadena de suministro de punta a punta. Que la imagen se abra mientras se lee
   el texto acompaña la idea en vez de decorarla.

   Se hace con animation-timeline: view(), igual que el desvanecimiento del
   hero, y por el mismo motivo: corre en el compositor. Sin soporte, la imagen
   se ve en su tamaño final y quieta, que es un estado bueno. Nada del contenido
   depende de la animacion.
   -------------------------------------------------------------------------- */
.blx-expandir {
	border-radius: 18px;
	overflow: hidden;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
}

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.blx-expandir {
			animation: blx-abrir linear both;
			animation-timeline: view();
			animation-range: entry 10% cover 45%;
		}
	}
}

@keyframes blx-abrir {
	from {
		clip-path: inset(12% 22% round 18px);
		transform: scale(0.92);
	}
	to {
		clip-path: inset(0% 0% round 18px);
		transform: none;
	}
}


/* --------------------------------------------------------------------------
   9 · PIE  ·  de @shadcnblockscom/components/footer-7

   Cuatro columnas de enlaces, el logo y el reclamo a la izquierda, y una linea
   inferior separada con el legal. El pie que ya existia tenia el logo y poco
   mas; esto le agrega la estructura de columnas.

   La grilla usa auto-fit por el mismo motivo que el bento: tres idiomas con
   anchos de palabra muy distintos.
   -------------------------------------------------------------------------- */
.blx-pie-columnas {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--40);
}

.blx-pie-columnas .wp-block-heading {
	font-size: var(--wp--preset--font-size--etiqueta);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--texto-tenue);
	margin-bottom: var(--wp--preset--spacing--20);
}

.blx-pie-columnas ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.5rem;
}

.blx-pie-legal {
	border-top: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	margin-top: var(--wp--preset--spacing--50);
	padding-top: var(--wp--preset--spacing--30);
	font-size: 0.875rem;
	color: var(--wp--preset--color--texto-tenue);
}


/* --------------------------------------------------------------------------
   10 · MARCADOR DE CONTENIDO SIN VALIDAR

   El theme clasico tiene este mecanismo en inc/pendiente.php y el smoke test
   cuenta la clase en el chequeo "marcadores SIN VALIDAR". El block theme no lo
   tenia, asi que un patron con contenido sin confirmar se veia igual que uno
   terminado.

   Se ve FEO A PROPOSITO. Un marcador discreto no es un marcador: es un texto
   provisorio que se publica y se queda dos años. Este pide que lo saquen.
   -------------------------------------------------------------------------- */
.blx-pendiente {
	position: relative;
	border-left: 3px solid #E0603A;
	background-color: rgba(224, 96, 58, 0.1);
	padding-left: var(--wp--preset--spacing--20);
}

.blx-pendiente::after {
	content: "SIN VALIDAR";
	position: absolute;
	top: 0;
	right: 0;
	background: #E0603A;
	color: #FFFFFF;
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	padding: 0.15rem 0.45rem;
	border-radius: 0 0 0 6px;
}


/* --------------------------------------------------------------------------
   11 · OFICINAS SIN MAPA  ·  la variante que se usa hoy

   La seccion 7 de arriba define .blx-mapa, que necesita una imagen de mapa de
   fondo. ESA IMAGEN NO EXISTE en la biblioteca de medios: se buscaron los
   slugs con "mapa", "globo" y "world" y no hay ninguno. El CSS queda escrito
   porque el patron lo usa en cuanto el adjunto aparezca, y el patron elige la
   rama sola.

   Mientras no exista, la seccion usa esta variante: el mismo mecanismo del
   componente de referencia, seis puntos que laten escalonados, uno por oficina,
   pero en una grilla de tarjetas en vez de sobre un mapa.

   POR QUE NO SE INVENTO UN MAPA. La opcion facil era una grilla de puntos
   decorativa con las seis oficinas puestas donde quedaran bien. Eso afirma una
   geografia: alguien mira el punto y entiende "la oficina esta ahi". Poner
   Bogota donde va Caracas porque el diseño cerraba mejor es inventar un dato, y
   este proyecto no inventa datos. Sin mapa de verdad, no hay mapa.
   -------------------------------------------------------------------------- */
.blx-oficinas {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--30);
}

.blx-oficina {
	position: relative;
	border: 1px solid var(--blx-borde, rgba(168, 192, 186, 0.16));
	border-radius: 14px;
	background-color: var(--wp--preset--color--superficie);
	padding: var(--wp--preset--spacing--30);
	padding-left: calc(var(--wp--preset--spacing--30) + 1.4rem);
	transition: border-color 200ms ease, background-color 200ms ease;
}

.blx-oficina:hover {
	border-color: var(--blx-borde-fuerte, rgba(168, 192, 186, 0.28));
	background-color: var(--wp--preset--color--superficie-alta);
}

/* El punto. Va en ::before del contenedor y no como elemento en el HTML porque
   es decorativo: el nombre de la oficina ya esta escrito al lado y un lector de
   pantalla no gana nada anunciando un punto. */
.blx-oficina::before {
	content: "";
	position: absolute;
	top: calc(var(--wp--preset--spacing--30) + 0.55rem);
	left: var(--wp--preset--spacing--30);
	width: 0.55rem;
	height: 0.55rem;
	border-radius: 50%;
	background: var(--wp--preset--color--menta-linx);
}

/* El anillo que late, escalonado por posicion para que las seis oficinas no
   pulsen al unisono. nth-child y no una clase por ciudad: el orden lo decide
   el patron y asi agregar una septima oficina no pide tocar el CSS. */
.blx-oficina::after {
	content: "";
	position: absolute;
	top: calc(var(--wp--preset--spacing--30) + 0.3rem);
	left: calc(var(--wp--preset--spacing--30) - 0.25rem);
	width: 1.05rem;
	height: 1.05rem;
	border-radius: 50%;
	border: 1px solid var(--wp--preset--color--menta-linx);
	animation: blx-latido 3s ease-out infinite;
	pointer-events: none;
}

.blx-oficina:nth-child(2)::after { animation-delay: 0.5s; }
.blx-oficina:nth-child(3)::after { animation-delay: 1s; }
.blx-oficina:nth-child(4)::after { animation-delay: 1.5s; }
.blx-oficina:nth-child(5)::after { animation-delay: 2s; }
.blx-oficina:nth-child(6)::after { animation-delay: 2.5s; }

.blx-oficina .wp-block-heading {
	margin: 0;
	font-size: var(--wp--preset--font-size--etiqueta);
	color: var(--wp--preset--color--blanco);
}

.blx-oficina p {
	margin: 0.35rem 0 0;
	font-size: 0.9375rem;
	color: var(--wp--preset--color--texto-tenue);
}
