/* ===========================================================================
   MEXAV 2026 — PARTICIPANTES (tarjeta, carrusel, grid y modal)
   ---------------------------------------------------------------------------
   Se carga en DOS vistas (ver header.tpl):
     · home           → sección "Participantes" (carrusel de destacados).
     · participantes  → página completa (grid + modal).
   Depende de css/mexav-public.css (tokens y scope `.mexav-public`).

   Aquí vive TODO lo que las dos vistas comparten: la tarjeta, el carrusel, el
   marco punteado con acentos azules, el grid y el modal. mexav-home.css sólo
   añade el fondo y los márgenes de la sección dentro de la landing. Ninguna
   regla de este archivo toca secciones ajenas: todas cuelgan de las clases
   `mexav-participante*`.

   MEDIDAS: tomadas 1:1 del export oficial de la sección (1920×926):
     tarjeta 327×479 (relación 0.6827), separación 64, cuatro por vista
     (203 / 594 / 988 / 1379), marco punteado de x109 a x1832, título de 46 a
     135 montado sobre el borde superior del marco, controles centrados abajo.
   =========================================================================== */

/* =======================================================================
   TARJETA — render compartido (partials/participante-card.tpl)
   -----------------------------------------------------------------------
   El visual completo (foto + cuadros amarillos + nombre + cargo + "+") viene
   horneado en el asset oficial, como la programación en /agenda. Por eso la
   tarjeta NO tiene fondo, borde ni tipografía propios: sólo la imagen y el
   área interactiva. El texto del DOM es accesible pero no visible.
   ======================================================================= */
.mexav-public .mexav-participante {
	margin: 0;
	/* Relación EXACTA del arte: evita saltos de layout mientras carga la
	   imagen y garantiza que todas las tarjetas midan igual. */
	aspect-ratio: 662 / 986;
}

.mexav-public .mexav-participante__link {
	display: block;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	text-align: inherit;
	cursor: pointer;
	border-radius: var(--mx-radius-sm);
	transition: transform var(--mx-dur) var(--mx-ease),
	            filter var(--mx-dur) var(--mx-ease);
}
.mexav-public .mexav-participante__link:hover,
.mexav-public .mexav-participante__link:focus-visible {
	transform: translateY(-4px);
	filter: brightness(1.06);
}
/* Foco visible sobre rojo: contorno blanco (el naranja del token se pierde). */
.mexav-public .mexav-participante__link:focus-visible {
	outline: 3px solid var(--mx-white);
	outline-offset: 3px;
}

.mexav-public .mexav-participante__img {
	display: block;
	width: 100%;
	height: 100%;
	/* `contain`: el arte de la tarjeta no se recorta NUNCA (los cuadros
	   amarillos y el "+" llegan hasta el borde del asset). */
	object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
	.mexav-public .mexav-participante__link { transition: none; }
	.mexav-public .mexav-participante__link:hover,
	.mexav-public .mexav-participante__link:focus-visible { transform: none; }
}

/* =======================================================================
   CARRUSEL (Home) — pista con scroll-snap
   -----------------------------------------------------------------------
   No usa una librería: el desplazamiento es scroll nativo con `scroll-snap`,
   así el swipe táctil, el trackpad, el teclado y los lectores de pantalla
   funcionan sin JavaScript. js/mexav-participantes.js sólo añade las flechas,
   los puntos y el cálculo de páginas.

   Cuántas tarjetas se ven a la vez lo decide SÓLO el ancho del item:
   4 en Desktop, 3 y 2 en Tablet, 1 en Mobile. El JS lo lee, no lo impone.
   ======================================================================= */
.mexav-participantes-carrusel {
	position: relative;
	z-index: 1;
	/* `clip` NO es cosmético. Sin él, el ancho de las 30 tarjetas se propaga al
	   `scrollWidth` de todos los ancestros (hasta <body>) pese al
	   `overflow-x: auto` de la pista. En escritorio no se nota porque el body
	   recorta, pero en móvil el navegador aplica "shrink to fit" sobre ese ancho
	   fantasma: monta un viewport de layout ~4× el real, dibuja la página a ~25%
	   en una columna estrecha, deja el resto con el fondo decorativo y habilita
	   scroll horizontal. `clip` corta la propagación en el contenedor.
	   Se usa `clip` y no `hidden` a propósito: `hidden` haría de este elemento
	   otro contenedor de scroll (y `overflow-y` pasaría a `auto`), mientras que
	   `clip` sólo recorta y deja intacto el scroll de la pista. */
	overflow-x: clip;
	/* Separación FLUIDA: 64px a 1920 (medida del export) y proporcional
	   hacia abajo, para que la tarjeta no encoja de más en laptop. */
	--mx-part-gap: clamp(20px, 3.34vw, 64px);
	--mx-part-visibles: 4;
}

.mexav-participantes-carrusel__track {
	display: flex;
	gap: var(--mx-part-gap);
	margin: 0;
	padding: 0;
	list-style: none;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	/* La barra de scroll se oculta: la navegación es por flechas/puntos/swipe. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}
.mexav-participantes-carrusel__track::-webkit-scrollbar { display: none; }

.mexav-participantes-carrusel__track:focus-visible {
	outline: 3px solid var(--mx-white);
	outline-offset: 6px;
}

.mexav-participantes-carrusel__item {
	flex: 0 0 calc(
		(100% - (var(--mx-part-visibles) - 1) * var(--mx-part-gap))
		/ var(--mx-part-visibles)
	);
	scroll-snap-align: start;
}

@media (prefers-reduced-motion: reduce) {
	.mexav-participantes-carrusel__track { scroll-behavior: auto; }
}

/* --- Controles: flecha ‹ · puntos · flecha › , centrados bajo la pista --- */
.mexav-participantes-carrusel__controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 22px;
	margin-top: 34px;
}

.mexav-public .mexav-participantes-carrusel__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--mx-white);
	font-family: var(--mx-font-display);
	font-size: 34px;
	line-height: 1;
	cursor: pointer;
	transition: opacity var(--mx-dur) var(--mx-ease);
}
.mexav-public .mexav-participantes-carrusel__arrow:hover { opacity: 0.7; }
.mexav-public .mexav-participantes-carrusel__arrow:focus-visible {
	outline: 3px solid var(--mx-white);
	outline-offset: 2px;
}
/* En los extremos la flecha se atenúa (el carrusel no da la vuelta: el orden
   editorial tiene principio y fin). Sigue siendo enfocable. */
.mexav-public .mexav-participantes-carrusel__arrow[disabled] {
	opacity: 0.35;
	cursor: default;
}

.mexav-participantes-carrusel__dots {
	display: flex;
	align-items: center;
	gap: 14px;
}
.mexav-public .mexav-participantes-carrusel__dot {
	width: 12px;
	height: 12px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.45);
	cursor: pointer;
	transition: background var(--mx-dur) var(--mx-ease);
}
.mexav-public .mexav-participantes-carrusel__dot.is-active { background: var(--mx-white); }
.mexav-public .mexav-participantes-carrusel__dot:focus-visible {
	outline: 2px solid var(--mx-white);
	outline-offset: 3px;
}

/* =======================================================================
   MARCO PUNTEADO + ACENTOS AZULES, SECCIÓN Y GRID
   -----------------------------------------------------------------------
   El marco usa el mismo lenguaje que el de la intro del Home
   (.mexav-home-intro__frame): bordes con repeating-linear-gradient, sin
   imágenes. Aquí el rectángulo va CERRADO por los cuatro lados y lleva dos
   escuadras azules (superior derecha e inferior izquierda), como en el arte.
   Las reglas se comparten con la sección del Home mediante los dos selectores
   (`.mexav-participantes__*` y `.mexav-home-participantes__*`).
   ======================================================================= */
.mexav-public .mexav-participantes {
	position: relative;
	/* Mismo rojo del arte (#ef4123 = --mx-accent), no el rojo de bloques. */
	background-color: var(--mx-accent);
	padding-block: clamp(2.5rem, 4.5vw, 4.5rem);
	/* El padding lateral vive en la SECCIÓN (no en __inner) para que el marco
	   punteado y sus escuadras azules —que sobresalen 4px— nunca lleguen al
	   borde del viewport y provoquen scroll horizontal. */
	padding-inline: clamp(1rem, 5.7vw, 109px);
}
.mexav-participantes__inner {
	position: relative;
	max-width: 1723px;                 /* ancho del marco en el export 1920 */
	margin-inline: auto;
}

/* Título display sobre el borde superior del marco. El fondo rojo es lo que
   "corta" la línea punteada, como en el arte. */
.mexav-public .mexav-participantes__title,
.mexav-public.mexav-home .mexav-home-participantes__title {
	position: relative;
	z-index: 2;
	display: inline-block;
	margin: 0 0 clamp(1.75rem, 3.7vw, 71px);
	padding-inline: clamp(0.75rem, 1.6vw, 30px);
	margin-left: clamp(0.5rem, 4.9vw, 94px);
	background-color: var(--mx-accent);
	color: var(--mx-white) !important;
	font-family: var(--mx-font-display);
	font-weight: 800;
	letter-spacing: 0.01em;
	line-height: 0.95;
	/* !important: gana al neutralizador global de headings de mexav-public
	   (`text-transform: none !important`), igual que Agenda y FAQ en Home. */
	text-transform: uppercase !important;
	font-size: clamp(38px, 4.6vw, 88px);
}

/* Marco: arranca a media altura del título (el título mide ~0.95em de
   line-height, así que la mitad es ~0.48em) y llega al fondo del bloque. */
.mexav-participantes__frame,
.mexav-home .mexav-home-participantes__frame {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	top: clamp(19px, 2.3vw, 44px);
	pointer-events: none;
	z-index: 0;
	background:
		repeating-linear-gradient(to right,  rgba(255,255,255,0.92) 0 14px, transparent 14px 30px) left top    / 100% 2px no-repeat,
		repeating-linear-gradient(to right,  rgba(255,255,255,0.92) 0 14px, transparent 14px 30px) left bottom / 100% 2px no-repeat,
		repeating-linear-gradient(to bottom, rgba(255,255,255,0.92) 0 14px, transparent 14px 30px) left top    / 2px 100% no-repeat,
		repeating-linear-gradient(to bottom, rgba(255,255,255,0.92) 0 14px, transparent 14px 30px) right top   / 2px 100% no-repeat;
}
.mexav-participantes__corner,
.mexav-home .mexav-home-participantes__corner {
	position: absolute;
	width: 34px;
	height: 34px;
	border: 0 solid var(--mx-blue-bright);
}
.mexav-participantes__corner--tr,
.mexav-home .mexav-home-participantes__corner--tr {
	top: -4px; right: -4px; border-top-width: 9px; border-right-width: 9px;
}
.mexav-participantes__corner--bl,
.mexav-home .mexav-home-participantes__corner--bl {
	bottom: -4px; left: -4px; border-bottom-width: 9px; border-left-width: 9px;
}

/* Grid: 4 columnas en Desktop, con la MISMA separación del carrusel para que
   la tarjeta se vea idéntica en las dos vistas. */
.mexav-participantes__grid {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: clamp(28px, 3.4vw, 64px);
	margin: 0;
	padding: 0 clamp(0.5rem, 3vw, 56px) clamp(1.5rem, 3vw, 56px);
	list-style: none;
}
.mexav-participantes__cell { margin: 0; }

/* =======================================================================
   MODAL — uno solo, reutilizable (partials/participante-modal.tpl)
   -----------------------------------------------------------------------
   Sobre el diálogo de Bootstrap 5 (ya incluido): se neutraliza su superficie
   blanca y se pinta el rojo MEXAV. Desktop: fotografía a la izquierda y
   contenido a la derecha. Mobile: una columna, foto arriba.
   ======================================================================= */
/* El diálogo NUNCA excede el viewport: se acota aquí y el desbordamiento se
   resuelve con scroll INTERNO (nunca recortando ni encogiendo el texto). El
   margen respecto al borde de la pantalla es el `--mx-modal-margen`. */
.mexav-participante-modal {
	--mx-modal-margen: 3rem;
}
.mexav-participante-modal .modal-dialog {
	max-width: min(1180px, calc(100vw - 3rem));
	max-height: calc(100vh - var(--mx-modal-margen));
	/* `dvh` para móviles: descuenta las barras del navegador que aparecen y
	   desaparecen, que con `vh` dejan el pie del modal fuera de pantalla. */
	max-height: calc(100dvh - var(--mx-modal-margen));
}
.mexav-participante-modal__content {
	position: relative;
	background-color: var(--mx-accent);
	border: 0;
	border-radius: 0;
	color: var(--mx-white);
	padding: clamp(1.75rem, 3.4vw, 3.5rem);
	/* Columna flexible acotada al diálogo: es lo que permite que un hijo
	   (la semblanza) reciba el alto sobrante y scrollee dentro. */
	display: flex;
	flex-direction: column;
	max-height: inherit;
}
/* Velo del diálogo: negro MEXAV, no el gris de Bootstrap. */
.modal-backdrop.show { background-color: var(--mx-black); opacity: 0.88; }

.mexav-participante-modal__body {
	display: flex;
	align-items: stretch;      /* la columna de texto hereda el alto disponible */
	gap: clamp(1.5rem, 3.4vw, 3.75rem);
	flex: 1 1 auto;
	min-height: 0;             /* sin esto un hijo flex no puede encoger ni scrollear */
}
.mexav-participante-modal__media {
	flex: 0 0 clamp(220px, 24vw, 327px);
	max-width: clamp(220px, 24vw, 327px);
	align-self: flex-start;    /* la fotografía conserva su alto natural */
}
.mexav-participante-modal__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 654 / 960;
	object-fit: contain;
}
/* Columna de contenido: nombre, cargo, línea divisoria y "Regresar" quedan
   FIJOS; el alto sobrante se lo lleva la semblanza, que es la única que
   scrollea. Así la identidad del participante y la acción de cierre siguen a
   la vista por larga que sea la biografía. */
.mexav-participante-modal__text {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	min-height: 0;
}
.mexav-participante-modal__nombre,
.mexav-participante-modal__cargo,
.mexav-participante-modal__rule,
.mexav-participante-modal__back { flex: 0 0 auto; }

.mexav-public .mexav-participante-modal__nombre {
	margin: 0;
	color: var(--mx-white) !important;
	font-family: var(--mx-font-mono);
	font-weight: 700;
	line-height: 1.15;
	font-size: clamp(24px, 2.3vw, 42px);
}
.mexav-public .mexav-participante-modal__cargo {
	margin: clamp(0.65rem, 1.1vw, 1.15rem) 0 0;
	color: var(--mx-white);
	font-family: var(--mx-font-mono);
	line-height: 1.45;
	font-size: clamp(14px, 1.15vw, 21px);
}
.mexav-participante-modal__rule {
	margin: clamp(1rem, 1.7vw, 1.85rem) 0;
	border: 0;
	border-top: 1px solid rgba(255, 255, 255, 0.55);
	opacity: 1;
}
/* La semblanza COMPLETA, con scroll propio: nunca se recorta, ni se acorta,
   ni se reduce la tipografía para que quepa. */
.mexav-participante-modal__bio {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding-right: 0.75rem;    /* la barra de scroll no pisa el texto */
	scrollbar-width: thin;
	scrollbar-color: rgba(255, 255, 255, 0.55) transparent;
}
.mexav-participante-modal__bio::-webkit-scrollbar { width: 6px; }
.mexav-participante-modal__bio::-webkit-scrollbar-thumb {
	background: rgba(255, 255, 255, 0.55);
	border-radius: 3px;
}
.mexav-public .mexav-participante-modal__bio p {
	margin: 0 0 1.25em;
	color: var(--mx-white);
	font-family: var(--mx-font-mono);
	line-height: 1.75;
	font-size: clamp(12.5px, 0.94vw, 17px);
}
.mexav-public .mexav-participante-modal__bio p:last-child { margin-bottom: 0; }

/* "Regresar": misma acción que la ✕, con el subrayado del arte. */
.mexav-public .mexav-participante-modal__back {
	margin-top: clamp(1.5rem, 2.3vw, 2.5rem);
	padding: 0;
	border: 0;
	background: none;
	color: var(--mx-white);
	font-family: var(--mx-font-mono);
	font-weight: 700;
	font-size: clamp(13px, 0.94vw, 17px);
	text-decoration: underline;
	text-underline-offset: 4px;
	cursor: pointer;
}
.mexav-public .mexav-participante-modal__back:hover { opacity: 0.75; }
.mexav-public .mexav-participante-modal__back:focus-visible,
.mexav-public .mexav-participante-modal__close:focus-visible {
	outline: 3px solid var(--mx-white);
	outline-offset: 3px;
}

.mexav-public .mexav-participante-modal__close {
	position: absolute;
	top: 0.5rem;
	right: 0.75rem;
	z-index: 3;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	border: 0;
	background: none;
	color: var(--mx-white);
	font-size: 2.25rem;
	line-height: 1;
	cursor: pointer;
}
.mexav-public .mexav-participante-modal__close:hover { opacity: 0.75; }

/* =======================================================================
   RESPONSIVE
   -----------------------------------------------------------------------
   El número de tarjetas por vista se cambia SÓLO aquí (variable
   --mx-part-visibles); el JS recalcula páginas y puntos a partir del ancho
   real, así que no hay que tocarlo.
   ======================================================================= */

/* --- Tablet grande (≤1199): 3 por vista / grid de 3 --- */
@media (max-width: 1199px) {
	.mexav-participantes-carrusel { --mx-part-visibles: 3; }
	.mexav-participantes__grid { grid-template-columns: repeat(3, 1fr); }
}

/* --- Tablet (≤899): 2 por vista / grid de 2 --- */
@media (max-width: 899px) {
	.mexav-participantes-carrusel {
		--mx-part-visibles: 2;
		--mx-part-gap: clamp(16px, 3vw, 28px);
	}
	.mexav-participantes__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: clamp(20px, 3.4vw, 32px);
	}

	/* Modal: una columna, foto arriba y contenido debajo. */
	.mexav-participante-modal__body { flex-direction: column; align-items: stretch; }
	.mexav-participante-modal__media {
		flex: 0 0 auto;
		max-width: min(240px, 60%);
	}
}

/* --- Mobile (≤639): UNA tarjeta por vista, como el diseño entregado --- */
@media (max-width: 639px) {
	.mexav-participantes-carrusel {
		--mx-part-visibles: 1;
		--mx-part-gap: clamp(16px, 5vw, 24px);
	}
	/* La tarjeta suelta se ve muy alta a ancho completo: se acota y se centra,
	   igual que en la maqueta Mobile. */
	.mexav-participantes-carrusel__item > .mexav-participante {
		max-width: 300px;
		margin-inline: auto;
	}

	/* Grid: 2 columnas hasta 479px (los cargos siguen legibles porque el
	   texto es parte del asset y escala con la tarjeta). */
	.mexav-participantes__grid {
		gap: clamp(16px, 4vw, 24px);
		padding-inline: clamp(0.25rem, 2vw, 1rem);
	}

	.mexav-participante-modal {
		/* Menos margen: en pantallas cortas cada píxel de alto cuenta. */
		--mx-modal-margen: 1.5rem;
	}
	.mexav-participante-modal .modal-dialog { max-width: calc(100vw - 1.5rem); }
	.mexav-participante-modal__media { max-width: 220px; margin-inline: auto; }
	.mexav-participante-modal__text { text-align: left; }

	/* En una columna es mejor recorrer TODO el contenido de un tirón (foto
	   incluida) que dejar una ventanita de texto scrollable dentro de la
	   pantalla: el scroll pasa al cuerpo y la semblanza vuelve a fluir. La ✕
	   va anclada al contenido, no al cuerpo, así que no se va con el scroll. */
	.mexav-participante-modal__body {
		overflow-y: auto;
		overscroll-behavior: contain;
		-webkit-overflow-scrolling: touch;
	}
	/* La columna de contenido vuelve a FLUJO normal: si siguiera siendo un
	   flex column acotado, la semblanza (ya sin scroll propio) desbordaría su
	   caja y "Regresar" se le montaría encima en vez de quedar debajo. */
	.mexav-participante-modal__text {
		display: block;
		min-height: auto;
	}
	.mexav-participante-modal__bio {
		overflow-y: visible;
		padding-right: 0;
	}
	.mexav-participante-modal__media { align-self: center; }
}

/* --- Mobile estrecho (≤479): una sola columna en el grid --- */
@media (max-width: 479px) {
	.mexav-participantes__grid { grid-template-columns: 1fr; justify-items: center; }
	.mexav-participantes__cell { width: 100%; max-width: 300px; }
}
