/*
Theme Name: ConjuntasORG
Description: Theme oficial de conjuntas.org. Adopta la estética de xhibiter (fuentes CalSans-SemiBold + DM Sans, paleta accent púrpura sobre jacarta) y se construye por bloques. Toda la marca pasa por las CSS variables `--brand-cta`, `--brand-cta-hover`, `--brand-cta-text` y `--brand-cta-text-hover`, configurables desde Apariencia → Personalizar → Color y tipografía. Si se desactiva, los plugins (Conjuntas, Modificación MemberPress) siguen siendo funcionales con el aspecto por defecto.
Version: 4.16.0
Author: pau
Text Domain: conjuntasorg
*/

/* ===================================================================
 * Fuentes locales — copias directas de xhibiter (src/fonts/).
 * =================================================================== */
@font-face {
	font-family: "CalSans-SemiBold";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/CalSans-SemiBold.woff2") format("woff2"),
	     url("assets/fonts/CalSans-SemiBold.woff") format("woff");
}
@font-face {
	font-family: "DM Sans";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/DMSans-Regular.ttf") format("truetype");
}
@font-face {
	font-family: "DM Sans";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("assets/fonts/DMSans-Medium.ttf") format("truetype");
}
@font-face {
	font-family: "DM Sans";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("assets/fonts/DMSans-Bold.ttf") format("truetype");
}

/* ===================================================================
 * Gradient animado arcoíris reutilizable — mismo efecto que el
 * `.animate-gradient` del H1 del hero, expuesto como clase global para
 * usar en cualquier sitio vía shortcode `[gradient]texto[/gradient]`.
 * El shortcode imprime `<span class="cjt-gradient-text">…</span>`.
 * =================================================================== */
@keyframes cjt-gradient-text {
	0%   { background-position: 0% 50%; }
	100% { background-position: 200% 50%; }
}
.cjt-gradient-text {
	display: inline-block;
	background: linear-gradient( 90deg, #8358FF, #ec4899, #8358FF );
	background-size: 200% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	animation: cjt-gradient-text 6s linear infinite;
}

/* ===================================================================
 * Tokens — heredados de xhibiter/HTML/tailwind.config.js. Los `--brand-*`
 * los inyecta el Customizer (Apariencia → Personalizar → Color y tipografía)
 * y sobreescriben estos defaults en wp_head.
 * =================================================================== */
:root {
	/* Brand (CTA) — xhibiter "accent" en violeta */
	--brand-cta:            #8358FF;
	--brand-cta-hover:      #7444FF;
	--brand-cta-text:       #ffffff;
	--brand-cta-text-hover: #ffffff;

	/* Paleta xhibiter — utilidades para el resto del theme */
	--xb-accent:        #8358FF;
	--xb-accent-dark:   #7444FF;
	--xb-accent-light:  #9E7CFF;
	--xb-accent-lighter:#B9A0FF;
	--xb-light-base:    #F5F8FA;
	--xb-jacarta-base:  #5A5D79;
	--xb-jacarta-50:    #F4F4F6;
	--xb-jacarta-100:   #E7E8EC;
	--xb-jacarta-200:   #C4C5CF;
	--xb-jacarta-300:   #A1A2B3;
	--xb-jacarta-400:   #7D7F96;
	--xb-jacarta-500:   #5A5D79;
	--xb-jacarta-600:   #363A5D;
	--xb-jacarta-700:   #131740;
	--xb-jacarta-800:   #101436;
	--xb-jacarta-900:   #0D102D;

	/* Tipografía — display (CalSans) para titulares, body (DM Sans) para todo */
	--xb-font-display: "CalSans-SemiBold", system-ui, -apple-system, "Segoe UI", sans-serif;
	--xb-font-body:    "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

	/* Gradient rainbow compartido — usado por el frame animado de las
	   coverflow cards above-the-fold (`.page-home__cf-slide`), por
	   el outer border de la pricing-table-container y por la celda
	   header benefit-column del pricing-table.

	   CICLO CERRADO: el último stop (100%) es del MISMO color que
	   el primer stop (0%) — `#8358FF`. Antes terminaba en pink y
	   al tiled (background-repeat: repeat) se veía una "vertical
	   line of change of color" en el seam. El user lo pidió:
	   "the curtain should have also a gradient color so i dont
	   want it to look like a loop". Así el bg loop no muestra
	   discontinuidad. */
	--cjt-rainbow-gradient: linear-gradient(
		90deg,
		#8358FF 0%,
		#ec4899 14%,
		#f97316 28%,
		#facc15 43%,
		#10b981 57%,
		#06b6d4 71%,
		#3b82f6 86%,
		#8358FF 100%
	);
}

/* Keyframes globales del rainbow — declarados aquí (no en el inline
   `<style>` de template-home.php) para que estén disponibles en
   cualquier página que use el frame, incluyendo la pricing-table
   cuando se renderiza fuera de la home. */
@keyframes cjt-card-rainbow {
	0%   { background-position: 0% 50%; }
	100% { background-position: 200% 50%; }
}

/* Reset global mínimo:
   - `box-sizing: border-box` en todo: elimina cálculos de width que se rompen
     cuando padding empuja el ancho real más allá del declarado. Indispensable
     para que `width: 100%` + padding no desborde, especialmente en mobile.
   - `overflow-x: hidden` en html/body: defensa contra cualquier elemento hijo
     que accidentalmente declare width fija mayor al viewport (badges con
     `left: -8px`, sombras `box-shadow: 0 8px 24px`, etc.). En mobile esto
     era la causa del "margin a la derecha" que también afectaba al footer:
     un hijo en /lista-de-cursos/ desbordaba unos pocos px y como `<body>`
     no tenía clip horizontal, todo el documento crecía y aparecía gris a
     la derecha del footer también.
   - `max-width: 100%` en `img/svg/video` previene que un media nativamente
     más grande que el viewport rompa el flow.
*/
*,
*::before,
*::after { box-sizing: border-box; }
html,
body {
	/* `overflow-x: clip` — equivalente a `hidden` para impedir scroll
	   horizontal accidental, pero a diferencia de `hidden` NO crea
	   un scroll-container y por tanto NO rompe `position: sticky` en
	   descendientes (la pricing-table-header sticky lo necesitaba).
	   Soporte: Chrome 90+, Firefox 81+, Safari 16+. */
	overflow-x: clip;
	max-width: 100%;
}
img,
svg,
video { max-width: 100%; height: auto; }

/* ----- Brand icon (logo SVG inline en header.php / footer.php / sidebar de MP) -----
   - Sin fondo (el SVG fuente está horneado a `transparent` para el negativo).
   - `currentColor` interno hereda del color del <a> padre → el logo cambia
     automáticamente en hover, dark mode y MP-chrome.
   - Tamaño y `gap` IGUALES en nav y footer (carbon copy) — el usuario lo
     pidió explícitamente, por eso usamos `gap: 6px` en el container y
     no `margin-right` en el icono (que daba spacing distinto si el icono
     se reposicionaba). */
.site-brand-icon {
	display: inline-block;
	width: auto;
	height: 26px;
	vertical-align: middle;
	flex: 0 0 auto;
	color: inherit;
	background: transparent !important; /* defensa extra contra el negativo blanco */
}
/* Container del brand: flex con `gap: 1px` IDÉNTICO en nav, footer y
   sidebar. El usuario pidió "5px más cerca" y "misma distancia en
   navbar y footer (como navbar)" — ajustamos a 1px para que el icono
   y el texto queden visualmente pegados (carbon-copy nav ↔ footer). */
.xb-nav__brand,
.site-footer__brand,
.mepr-mod-sidebar__brand {
	display: inline-flex;
	align-items: center;
	gap: 1px;
}
@media ( max-width: 768px ) {
	.site-brand-icon { height: 22px; }
}
/* TLD del nombre del sitio en `<small>` (`conjuntas` + `.org` con la
   `.org` más pequeña y opacada). El user lo pidió en ambos sitios — el
   markup en header.php / footer.php envuelve la TLD en `.xb-nav__brand-tld`
   y `.site-footer__brand-tld`. */
.xb-nav__brand-tld,
.site-footer__brand-tld {
	font-size: 0.65em;
	font-weight: 500;
	opacity: 0.7;
	letter-spacing: 0;
	margin-left: 1px;
}

/* ----- Chip selector (filtros multi-select de categoría e idioma) -----
   El user pidió convertir los <select> dropdown a un selector tipo "chip":
   click activa una categoría, otro click la desactiva, varias pueden estar
   activas a la vez. Cada chip muestra el icono del registry a la izquierda
   y la label a la derecha. Estado activo = `aria-pressed="true"`. */
.cjt-chip-selector {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
}
.cjt-chip {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 6px 12px 6px 6px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1.5px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.cjt-chip:hover {
	border-color: var( --brand-cta );
	color: var( --brand-cta );
}
.cjt-chip[aria-pressed="true"] {
	border-color: var( --brand-cta );
	background: color-mix( in srgb, var( --brand-cta ) 12%, #ffffff );
	color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 18%, transparent );
}
.cjt-chip__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	border-radius: 999px;
	flex: 0 0 auto;
}
.cjt-chip__label {
	font-family: var( --xb-font-display );
	letter-spacing: 0.2px;
	white-space: nowrap;
}
/* Idioma chips (sin icono): padding más uniforme. */
.cjt-chip-selector[data-filter-lang-multi] .cjt-chip { padding: 6px 14px; }
/* ----- Card action buttons inyectadas por mod-mepr en mis-conjuntas -----
   El user pidió:
   - Desapuntarme → texto rojo (no botón), tipo link
   - Panel de voluntario → botón VERDE (heredado positivo, antes era CTA púrpura)
*/
/* "Grupo de esta conjunta" — pill purple (brand-cta). Mismo lenguaje
   visual que el botón equivalente del single-conjunta, pero adaptado
   al tamaño compacto del row de acciones de la card de Mis Conjuntas
   (mismo size que .cjt-card__volunteer-panel y .cjt-card__pay). Va
   en col 3 antes del bloque de pago. */
.cjt-card__group,
.cjt-card__group:link,
.cjt-card__group:visited {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 8px 14px;
	margin: 6px 4px 0 0;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	background: var( --brand-cta );
	color: var( --brand-cta-text ) !important;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.cjt-card__group:hover,
.cjt-card__group:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover ) !important;
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
	outline: none;
}

/* Panel de voluntario: green pill IDÉNTICO a `.cjt-card__pay`. Necesita
   prefijo `body.mepr-mod-*` para vencer la regla MP-chrome
   `body.mepr-mod-shell button { font-size: var(--brand-body-size, 16px) }`
   que pisaba el `!important` por mayor especificidad (0,1,2 vs 0,1,0).
   Como `.cjt-card__pay` es un `<a>`, esa regla MP no le afecta — por eso
   el botón "Pagar conjunta" se veía bien y el "Panel de voluntario"
   salía grande. El user lo pidió: "Panel de voluntario same style as
   pagar conjunta". */
.cjt-card__volunteer-panel,
.cjt-card .cjt-card__volunteer-panel,
body.mepr-mod-chrome .cjt-card__volunteer-panel,
body.mepr-mod-shell .cjt-card__volunteer-panel,
body.mepr-mod-mis-conjuntas .cjt-card__volunteer-panel {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	padding: 8px 14px !important;
	margin: 6px 4px 0 0 !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	cursor: pointer !important;
	background: #3b82f6 !important;
	color: #ffffff !important;
	line-height: 1.2 !important;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
.cjt-card__volunteer-panel:hover,
.cjt-card__volunteer-panel:focus,
body.mepr-mod-chrome .cjt-card__volunteer-panel:hover,
body.mepr-mod-chrome .cjt-card__volunteer-panel:focus,
body.mepr-mod-mis-conjuntas .cjt-card__volunteer-panel:hover,
body.mepr-mod-mis-conjuntas .cjt-card__volunteer-panel:focus {
	background: #2563eb !important;
	color: #ffffff !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 59, 130, 246, 0.55 ) !important;
	outline: none !important;
}
/* Desapuntarme: NOT a button — plain red text link with underline.
   El user lo pidió: "top button, to not be a button and instead be a
   text (in red also)". Mismo tratamiento que `Dejar de ser voluntario`. */
.cjt-card__unenroll,
.cjt-card__unenroll:link,
.cjt-card__unenroll:visited {
	display: inline-block !important;
	margin: 6px 0 0 0 !important;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: 2px;
	color: #c0392b !important;
	cursor: pointer;
	box-shadow: none !important;
	transform: none !important;
	transition: color 0.15s ease;
}
/* Mobile (mis-conjuntas list view): igualar el ancho de
   "Panel de voluntario" y "Grupo de esta conjunta" + "Pagar conjunta" +
   "Material disponible" — todos al 100% de la columna de acciones, así
   ocupan la misma anchura visual (la del más largo, "GRUPO DE ESTA
   CONJUNTA"). Sin esto, el ancho lo decide la longitud del texto y queda
   irregular. "Desapuntarme" sigue siendo link-only — no se toca. User
   2026-05-25 (16ª iter): "All panel de voluntario and grupo de esta
   conjunta should be as wide as grupo de esta conjunta button same
   sizes (keeping original colors)". */
@media ( max-width: 768px ) {
	/* User 2026-05-25 (17ª iter, 2da pasada): el rule anterior con `width:
	   100%` no afectaba en list-view porque los botones son `inline-flex`
	   dentro de un `.cjt-card__actions` con `flex-wrap: wrap` — el flex
	   container gestiona `width` por `flex-basis`. Forzamos `flex: 0 0
	   100%` para que cada botón ocupe SU PROPIA fila ancho completo.
	   `display: flex` (en lugar de `inline-flex`) garantiza el block-box. */
	.cjt-card__actions .cjt-card__group,
	.cjt-card__actions .cjt-card__group:link,
	.cjt-card__actions .cjt-card__group:visited,
	.cjt-card__actions .cjt-card__volunteer-panel,
	body.mepr-mod-chrome .cjt-card__actions .cjt-card__volunteer-panel,
	body.mepr-mod-shell .cjt-card__actions .cjt-card__volunteer-panel,
	body.mepr-mod-mis-conjuntas .cjt-card__actions .cjt-card__volunteer-panel,
	.cjt-card__actions .cjt-card__pay,
	.cjt-card__actions .cjt-card__pay:link,
	.cjt-card__actions .cjt-card__pay:visited,
	.cjt-card__actions .cjt-card__material,
	.cjt-card__actions .cjt-card__material--available,
	.cjt-card__actions .cjt-card__material--locked,
	.cjt-card__actions .cjt-card__material--pending,
	.cjt-card__actions .cjt-card__pay-wrap {
		display: flex !important;
		flex: 0 0 100% !important;
		width: 100% !important;
		max-width: 100% !important;
		margin-right: 0 !important;
		box-sizing: border-box !important;
		align-items: center !important;
		justify-content: center !important;
	}
}
.cjt-card__unenroll:hover,
.cjt-card__unenroll:focus,
.cjt-card__unenroll:active {
	color: #8a2820 !important;
	background: transparent !important;
	transform: none !important;
	box-shadow: none !important;
	outline: none;
}

/* Lista de espera — botones de la card en /cuenta/?action=mi-lista-de-espera.
   "Editar condiciones" reusa el azul de `.cjt-card__volunteer-panel`;
   "Apuntarme manualmente" el verde de `.cjt-card__pay`. Necesitan los
   prefijos `body.mepr-mod-*` para vencer la regla MP-chrome que pisa el
   `font-size` de los <button> por mayor especificidad. */
.cjt-card__waitlist-edit,
.cjt-card__waitlist-join,
body.mepr-mod-chrome .cjt-card__waitlist-edit,
body.mepr-mod-chrome .cjt-card__waitlist-join,
body.mepr-mod-mi-lista-espera .cjt-card__waitlist-edit,
body.mepr-mod-mi-lista-espera .cjt-card__waitlist-join {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	padding: 8px 14px !important;
	margin: 6px 4px 0 0 !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	cursor: pointer !important;
	color: #ffffff !important;
	line-height: 1.2 !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
.cjt-card__waitlist-edit,
body.mepr-mod-chrome .cjt-card__waitlist-edit,
body.mepr-mod-mi-lista-espera .cjt-card__waitlist-edit { background: #3b82f6 !important; }
.cjt-card__waitlist-edit:hover,
.cjt-card__waitlist-edit:focus {
	background: #2563eb !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 59, 130, 246, 0.55 ) !important;
	outline: none !important;
}
.cjt-card__waitlist-join,
body.mepr-mod-chrome .cjt-card__waitlist-join,
body.mepr-mod-mi-lista-espera .cjt-card__waitlist-join { background: #10b981 !important; }
.cjt-card__waitlist-join:hover,
.cjt-card__waitlist-join:focus {
	background: #0e9c6f !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 16, 185, 129, 0.55 ) !important;
	outline: none !important;
}

/* Tag "Has propuesto esta conjunta" — pill discreta que aparece para el
   autor original durante toda la vida de la conjunta. Visual neutro
   (jacarta light bg + texto medio) — informativo, no acción. */
.cjt-card__author-tag,
body.mepr-mod-chrome .cjt-card__author-tag,
body.mepr-mod-mis-conjuntas .cjt-card__author-tag {
	display: inline-flex !important;
	align-items: center !important;
	padding: 4px 10px !important;
	margin: 0 0 4px 0 !important;
	background: color-mix( in srgb, var( --brand-cta, #8358FF ) 12%, transparent ) !important;
	color: var( --brand-cta, #8358FF ) !important;
	border-radius: 999px !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 12px !important;
	font-weight: 600 !important;
	letter-spacing: 0 !important;
	line-height: 1.2 !important;
	text-transform: none !important;
	white-space: nowrap !important;
}

/* "⏳ Material pendiente" / "🧲 Material disponible" — pill/botón que
   aparece en el TOP de las acciones de cada card en mis-conjuntas,
   sólo si la conjunta está cerrada. Tres variantes:
     --pending   → pill azul informativa (admin aún no subió material)
     --available → botón verde (paid/voluntario, abre popup con link+notas)
     --locked    → botón rojo (no paid, abre popup con CTA "Pagar")
   Comparten layout/typografía para que cambiar de estado no salte la
   altura del card. */
.cjt-card__material,
body.mepr-mod-chrome .cjt-card__material,
body.mepr-mod-mis-conjuntas .cjt-card__material {
	display: inline-flex !important;
	align-items: center !important;
	padding: 5px 11px !important;
	margin: 0 0 6px 0 !important;
	border: 0 !important;
	border-radius: 999px !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 12px !important;
	font-weight: 600 !important;
	line-height: 1.2 !important;
	text-transform: none !important;
	white-space: nowrap !important;
	cursor: default !important;
}
.cjt-card__material--pending,
body.mepr-mod-chrome .cjt-card__material--pending,
body.mepr-mod-mis-conjuntas .cjt-card__material--pending {
	background: color-mix( in srgb, #3b82f6 14%, transparent ) !important;
	color: #1d4ed8 !important;
}
/* Variante AMARILLA — misma pill que `--pending` pero para conjuntas en
   estado PROPUESTA donde el viewer está apuntado. Igual sizing, mismo
   copy ("Siguen uniéndose participantes") — sólo cambia el tono. */
.cjt-card__material--proposed,
body.mepr-mod-chrome .cjt-card__material--proposed,
body.mepr-mod-mis-conjuntas .cjt-card__material--proposed {
	background: color-mix( in srgb, #f59e0b 18%, transparent ) !important;
	color: #b45309 !important;
}/* `button.cjt-card__material--available` añade especificidad (tag+class)
   para vencer cualquier `body.mepr-mod-chrome button { ... }` que MP-Pro
   pueda inyectar. El user lo pidió: "make it uppercase and same size as
   others" — copiamos el sizing/typografía exacto de `.cjt-card__volunteer-panel`
   para que las 3 píldoras (Material disponible / Panel de voluntario /
   Grupo de esta conjunta) queden visualmente uniformes. */
.cjt-card__material--available,
button.cjt-card__material--available,
body.mepr-mod-chrome button.cjt-card__material--available,
body.mepr-mod-mis-conjuntas button.cjt-card__material--available {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	background: #10b981 !important;
	color: #ffffff !important;
	border: 0 !important;
	border-radius: 999px !important;
	padding: 8px 14px !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	line-height: 1.2 !important;
	cursor: pointer !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
button.cjt-card__material--available:hover,
button.cjt-card__material--available:focus {
	background: #0ea571 !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 6px 12px -4px rgba( 16, 185, 129, 0.45 ) !important;
	outline: 0 !important;
}
.cjt-card__material--locked,
button.cjt-card__material--locked,
body.mepr-mod-chrome button.cjt-card__material--locked,
body.mepr-mod-mis-conjuntas button.cjt-card__material--locked {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	background: #dc2626 !important;
	color: #ffffff !important;
	border: 0 !important;
	border-radius: 999px !important;
	padding: 8px 14px !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	line-height: 1.2 !important;
	cursor: pointer !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
button.cjt-card__material--locked:hover,
button.cjt-card__material--locked:focus {
	background: #b91c1c !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 6px 12px -4px rgba( 220, 38, 38, 0.45 ) !important;
	outline: 0 !important;
}

/* === User 2026-05-26: estados de material previos a la entrega ===
   Cuatro variantes nuevas que cubren la fase "todavía no entregable":
     --vol-pending  → vol no ha subido aún (sólo VE el voluntario):
                       fondo rojo claro · texto wine · NO clicable
     --vol-processing → vol subió, falta admin (sólo VE el voluntario):
                       fondo amarillo · texto wine · NO clicable
     --part-processing → vol subió, falta admin (sólo VE participantes):
                       mismo amarillo · texto wine · NO clicable
     --disabled-soft → admin ya subió pero el usuario aún no puede acceder
                       (conjunta abierta para todos, o cerrada+impago para
                       participantes): mismo tamaño/forma que `--available`
                       pero gris no clicable. */
.cjt-card__material--vol-pending,
.cjt-card__material--vol-processing,
.cjt-card__material--part-processing,
.cjt-card__material--disabled-soft,
body.mepr-mod-chrome .cjt-card__material--vol-pending,
body.mepr-mod-chrome .cjt-card__material--vol-processing,
body.mepr-mod-chrome .cjt-card__material--part-processing,
body.mepr-mod-chrome .cjt-card__material--disabled-soft,
body.mepr-mod-mis-conjuntas .cjt-card__material--vol-pending,
body.mepr-mod-mis-conjuntas .cjt-card__material--vol-processing,
body.mepr-mod-mis-conjuntas .cjt-card__material--part-processing,
body.mepr-mod-mis-conjuntas .cjt-card__material--disabled-soft {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	border: 0 !important;
	border-radius: 999px !important;
	padding: 8px 14px !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	line-height: 1.2 !important;
	cursor: not-allowed !important;
	pointer-events: none !important;
}
/* Rojo claro / wine — voluntario aún no ha subido. */
.cjt-card__material--vol-pending,
body.mepr-mod-chrome .cjt-card__material--vol-pending,
body.mepr-mod-mis-conjuntas .cjt-card__material--vol-pending {
	background: color-mix( in srgb, #b91c1c 18%, #ffffff ) !important;
	color: #7c1d3e !important;
}
/* Amarillo / wine — material subido por el voluntario, procesándose
   (vista del voluntario + vista del participante usan el mismo color
   familiar y se distinguen sólo por la copy + emoji). */
.cjt-card__material--vol-processing,
.cjt-card__material--part-processing,
body.mepr-mod-chrome .cjt-card__material--vol-processing,
body.mepr-mod-chrome .cjt-card__material--part-processing,
body.mepr-mod-mis-conjuntas .cjt-card__material--vol-processing,
body.mepr-mod-mis-conjuntas .cjt-card__material--part-processing {
	background: color-mix( in srgb, #facc15 32%, #ffffff ) !important;
	color: #7c1d3e !important;
}
/* Gris — disponible pero aún no accesible (a la espera de cerrar +
   pago). Mismo sizing que `--available` para no romper la maquetación. */
.cjt-card__material--disabled-soft,
body.mepr-mod-chrome .cjt-card__material--disabled-soft,
body.mepr-mod-mis-conjuntas .cjt-card__material--disabled-soft {
	background: var( --xb-jacarta-100, #e5e7ee ) !important;
	color: var( --xb-jacarta-400, #8a8db4 ) !important;
}

/* "Pendiente de pago" — label pegado al botón rojo Material disponible
   cuando el material está bloqueado por falta de pago. Refuerza la
   urgencia visual (botón rojo + label rojo apilados). El "Pagar conjunta"
   sigue saliendo más abajo dentro del pay-wrap. */
.cjt-card__pay-pending-top,
body.mepr-mod-chrome .cjt-card__pay-pending-top,
body.mepr-mod-mis-conjuntas .cjt-card__pay-pending-top {
	display: inline-block !important;
	margin: 0 0 4px 0 !important;
	color: #c0392b !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 12px !important;
	font-weight: 600 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
}

/* Reordenar el flex de `.cjt-card__actions` para que "Grupo de esta
   conjunta" quede SIEMPRE al final de la columna, debajo del pay-wrap.
   El user lo pidió: "grupo de esta conjunta button should be last one
   on the list". Usamos `order: 99`; los demás children quedan en el
   orden DOM natural (order: 0). */
body.mepr-mod-chrome .cjt-card__actions .cjt-card__group,
body.mepr-mod-mis-conjuntas .cjt-card__actions .cjt-card__group {
	order: 99 !important;
}

/* Variantes del cjt-confirm dialog:
     --success → botón YES verde (mismo verde de Pagado correctamente)
     --danger  → botón NO con texto rojo (estilo "no es un botón típico",
                 fondo neutro para que destaque el verde de "Sí"). El
                 user lo pidió textual: "Aún no quiero pagar… in red text
                 (not button)". */
.cjt-confirm__yes.cjt-confirm__yes--success {
	background: #10b981 !important;
	color: #ffffff !important;
	border-color: #10b981 !important;
}
.cjt-confirm__yes.cjt-confirm__yes--success:hover,
.cjt-confirm__yes.cjt-confirm__yes--success:focus {
	background: #0ea571 !important;
	border-color: #0ea571 !important;
}
.cjt-confirm__no.cjt-confirm__no--danger {
	background: transparent !important;
	color: #dc2626 !important;
	border: 0 !important;
	box-shadow: none !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
	padding: 6px 10px !important;
}
.cjt-confirm__no.cjt-confirm__no--danger:hover,
.cjt-confirm__no.cjt-confirm__no--danger:focus {
	background: transparent !important;
	color: #b91c1c !important;
	text-decoration: underline !important;
}

/* Botón "Eliminar conjunta" — sólo visible cuando el autor puede borrar
   (0 participantes). Estilo de link de aviso (rojo + subrayado) para
   reflejar la naturaleza destructiva, mismo patrón que Desapuntarme. */
.cjt-card__delete,
.cjt-card__delete:link,
.cjt-card__delete:visited,
body.mepr-mod-chrome .cjt-card__delete,
body.mepr-mod-mis-conjuntas .cjt-card__delete {
	/* Elevación local: el stretched-link (`.cjt-card__stretch`) usa
	   `position: absolute; inset: 0; z-index: 1` y captura cualquier
	   click si nuestro link queda detrás. Forzamos `position: relative`
	   + z-index claramente mayor + `pointer-events: auto` aquí, además
	   del allowlist de z-index, por si alguna regla más específica
	   (theme padre, MP chrome) intentara devolverlo a `static`. */
	position: relative !important;
	z-index: 3 !important;
	pointer-events: auto !important;
	display: inline-block !important;
	margin: 6px 0 0 0 !important;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: 2px !important;
	color: #c0392b !important;
	cursor: pointer !important;
	box-shadow: none !important;
}
.cjt-card__delete:hover,
.cjt-card__delete:focus,
.cjt-card__delete:active {
	color: #8a2820 !important;
	background: transparent !important;
	transform: none !important;
	box-shadow: none !important;
	outline: none !important;
}
/* Pago de conjunta cerrada (solo participantes NO voluntarios).
   Botón verde + caption rojo "Pendiente de pago" debajo. El wrapper
   nos permite apilar el caption bajo el botón sin romper el flex
   horizontal del resto de `.cjt-card__actions`. */
.cjt-card__pay-wrap {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
	margin: 6px 4px 0 0;
}
a.cjt-card__pay,
a.cjt-card__pay:link,
a.cjt-card__pay:visited,
.cjt-card a.cjt-card__pay,
body.mepr-mod-chrome .cjt-card a.cjt-card__pay {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 8px 14px !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	cursor: pointer;
	background: #10b981 !important;
	color: #ffffff !important;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
a.cjt-card__pay:hover,
a.cjt-card__pay:focus,
.cjt-card a.cjt-card__pay:hover,
.cjt-card a.cjt-card__pay:focus {
	background: #0e9c6f !important;
	color: #ffffff !important;
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 16, 185, 129, 0.55 );
	outline: none;
}
.cjt-card .cjt-card__pay-status,
body.mepr-mod-chrome .cjt-card .cjt-card__pay-status {
	display: inline-block;
	font-family: var( --xb-font-body );
	font-size: 12px !important;
	font-weight: 600 !important;
	color: #c0392b !important;
	letter-spacing: 0;
	text-transform: none;
}
/* Conjunta pagada — el botón "Pagar conjunta" desaparece y el caption
   se reusa con texto + color verde para mantener el layout idéntico
   al estado "pendiente". */
.cjt-card .cjt-card__pay-status--paid,
body.mepr-mod-chrome .cjt-card .cjt-card__pay-status--paid {
	color: #0e9c6f !important;
}
/* Wrapper de las acciones del card. En grid view (default) los botones se
   colocan al final del body apilados (`flex-column`). En list view dentro
   de /cuenta/?action=mis-conjuntas se reposiciona como grid-item ocupando
   la fila 2 del card-grid (donde antes vivía el excerpt). */
.cjt-card__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 12px;
	margin-top: 8px;
}

/* "Pendiente de pago" inline — pegado al botón rojo "Material disponible".
   El user lo pidió: "the 'pendiente de pago' should be right below of
   material disponible". `flex: 0 0 100%` fuerza break de fila para que
   aparezca DEBAJO del botón aunque el flex tenga otros items que cupiesen
   en la misma fila. */
.cjt-card__pay-status--inline,
body.mepr-mod-mis-conjuntas .cjt-card__pay-status--inline {
	flex: 0 0 100% !important;
	margin: 0 !important;
	padding: 0 !important;
	color: #c0392b !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 12px !important;
	font-weight: 600 !important;
	text-align: center !important;
	text-transform: none !important;
	letter-spacing: 0 !important;
}

/* "Grupo de esta conjunta" siempre al final del listado de acciones
   EN MIS-CONJUNTAS — el user lo pidió: "grupo de esta conjunta button
   should be last one on the list" (en /cuenta/?action=mis-conjuntas).
   Es una acción secundaria (abrir el chat) vs. las primarias (Pagar,
   Panel de voluntario, Desapuntarme).
   ATENCIÓN: scoped a `body.mepr-mod-*` PORQUE en el user-card del
   single-conjunta el orden es distinto (Grupo va EN MEDIO, no al final);
   el `order: 99 !important` antes leakeaba al single y hacía aparecer
   "Desapuntarme" en mitad de la pila en vez de al final. Fix 2026-05-24. */
body.mepr-mod-chrome .cjt-card__actions .cjt-card__group,
body.mepr-mod-mis-conjuntas .cjt-card__actions .cjt-card__group {
	order: 99 !important;
}

/* En /cuenta/?action=mis-conjuntas + list view: ocultar el excerpt y
   colocar los botones de acción donde el excerpt estaba (col 2, row 2)
   con scroll horizontal si caben justos. Las cabeceras del list-header
   y el resto de columnas (precios, descuento, categoría) NO se mueven. */
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__excerpt {
	display: none !important;
}
/* Mis conjuntas — botones de acción JUSTO BAJO el título, en col 2 row 2.
   Tamaño NORMAL (no compactado): el user pidió textual "you made the
   button smaller which I don't like / put it right below the text".
   Aumentamos el thumb a 110px para que título (row 1) + acciones
   (row 2) ambos queden alineados con el thumb sin necesidad de
   reducir las acciones. */
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view {
	--cjt-list-thumb: 110px;
}
/* Título de la conjunta MÁS GRANDE dentro de mis-conjuntas — el user
   reportó "you changed the size of title of conjunta inside mis conjuntas,
   now is smaller, I want it bigger like it was before". */
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__title {
	font-size: 18px !important;
	line-height: 1.3 !important;
}
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card {
	align-items: start !important;
	/* 3 rows en mis-conjuntas: title / cats / actions. El user lo pidió:
	   "put the categories of the conjunta right below the conjunta title
	   in the mis conjuntas list — between title and buttons". */
	grid-template-rows: auto auto auto !important;
}
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__media {
	align-self: start !important;
	grid-row: 1 / span 3 !important;
}
/* Cats permanecen en row 2 (entre título y acciones) — la regla
   genérica `.cjt-card__cats { grid-row: 2 }` ya las pone ahí. */
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats {
	grid-row: 2 !important;
	margin: 4px 0 0 !important;
}
body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions {
	grid-column: 2;
	grid-row: 3 !important;
	margin: 6px 0 0 !important;
	min-width: 0;
	align-self: start !important;
	gap: 6px 12px !important;
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
}
/* Acciones a TAMAÑO NORMAL (los defaults globales que vienen de
   .cjt-card__volunteer-panel y .cjt-card__unenroll son los correctos).
   No las re-comprimimos — el thumb 110px da espacio sobrado para
   título + botón sin necesidad de achicar la pill. */
/* En grid view (cuadrícula) los botones simplemente fluyen al final del
   body — el flex-column del wrapper los apila uno bajo otro. */
body.mepr-mod-mis-conjuntas .xb-collections__content:not( .is-list-view ) .cjt-card__actions {
	flex-direction: column;
	flex-wrap: nowrap;
	align-items: stretch;
	width: 100%;
	min-width: 0;
}
/* Constreñir cada botón de acción al ancho de la card en grid view —
   sin esto los pills (`.cjt-card__group`, "Pagar conjunta", "Material
   disponible"…) se desbordaban FUERA de la card y solapaban la card
   vecina. Dos causas combinadas:
     1) ancho intrínseco del contenido → se corrige con `max-width:100%`.
     2) `.cjt-card__pay-status--inline` / `.cjt-card__pay-pending-top`
        traen `flex: 0 0 100%` (pensado para FORZAR salto de fila en el
        flex-ROW del list view). En el flex-COLUMN del grid view ese
        `flex-basis: 100%` se aplica al eje principal (alto) y, con
        `flex-wrap`, empuja los items a una nueva columna a la derecha.
        Lo neutralizamos a `flex: 0 0 auto` + `flex-wrap: nowrap` arriba.
   El user lo reportó: en vista cuadrícula los botones se salían del
   recuadro. */
body.mepr-mod-mis-conjuntas .xb-collections__content:not( .is-list-view ) .cjt-card__actions > * {
	flex: 0 0 auto !important;
	max-width: 100% !important;
	min-width: 0 !important;
	box-sizing: border-box !important;
	margin-right: 0 !important;
	white-space: normal !important;
	overflow-wrap: anywhere;
}
/* `.cjt-card__pay-wrap` envuelve el botón "Pagar" + caption; en grid
   view ocupa el ancho completo de la columna de acciones. */
body.mepr-mod-mis-conjuntas .xb-collections__content:not( .is-list-view ) .cjt-card__pay-wrap {
	width: 100% !important;
	align-items: stretch !important;
}

/* =====================================================================
   Mis Conjuntas — list view DESKTOP reorg (≥1025px).
   El user lo pidió: "the same way you have organized mis conjuntas
   columns on mobile, I want the same organization in desktop. Buttons
   and personal info on the right, info about the conjunta on the left".

   Mirror del patrón mobile (línea 3307): 3 columnas planas:
     col 1 = thumb (110px, span todas las filas)
     col 2 = título + cats + precios (info "permanente" de la conjunta)
     col 3 = acciones dinámicas (tag "Has propuesto", Eliminar,
             Desapuntarme, Panel de voluntario, Pagar) apiladas en
             vertical, anchas auto hasta max-content (200px mín.).

   La cabecera (header con columnas "Precio en conjunta / Precio original
   / Descuento") deja de tener sentido porque los precios viven dentro
   del flujo de la columna izquierda — la ocultamos también en desktop.
   En /lista/ (no-mis-conjuntas) la cabecera sigue visible.
   ===================================================================== */
@media ( min-width: 1025px ) {
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .xb-collections__list-header {
		display: none !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .xb-collections__grid {
		border-top: 1px solid var( --xb-jacarta-100 ) !important;
		border-radius: 14px !important;
	}
	/* 3 columnas: thumb · info · acciones. Override del global
	   `--cjt-list-grid` (5 cols precios+descuento) para esta vista. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card {
		grid-template-columns: 110px minmax( 0, 1fr ) minmax( 200px, max-content ) !important;
		grid-template-rows: auto auto auto !important;
		column-gap: 16px !important;
		row-gap: 4px !important;
		align-items: start !important;
		padding: 18px 20px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__media {
		grid-column: 1 !important;
		grid-row: 1 / span 3 !important;
		width: 110px !important;
		height: 110px !important;
		align-self: start !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__title {
		grid-column: 2 !important;
		grid-row: 1 !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats {
		grid-column: 2 !important;
		grid-row: 2 !important;
		justify-self: start !important;
		align-self: start !important;
		gap: 4px 6px !important;
	}
	/* Chips de categoría en mis-conjuntas: SMALL + COMPACT. Necesita
	   `!important` y prefijo `body.mepr-mod-*` para vencer la regla MP
	   `body.mepr-mod-shell button { font-size: 16px !important }` que
	   estaba inflando los chips a 16px (mismo problema que tuvo
	   `.cjt-card__volunteer-panel`). Icono y padding también compactos
	   para que la fila de categorías sea visualmente discreta. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category {
		padding: 2px 8px 2px 2px !important;
		font-family: var( --xb-font-display ) !important;
		font-size: 10px !important;
		font-weight: 700 !important;
		letter-spacing: 0.4px !important;
		line-height: 1.3 !important;
		gap: 4px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category-icon {
		width: 16px !important;
		height: 16px !important;
		flex: 0 0 16px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category-icon svg {
		width: 10px !important;
		height: 10px !important;
	}
	/* Body deja de aplicar `display: contents` para esta vista (default
	   global), porque queremos que los precios floten DENTRO de col 2.
	   En su lugar, los precios son un flex con label inline (igual que
	   en mobile) y viven en col 2 row 3. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__body {
		display: contents !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__prices {
		grid-column: 2 !important;
		grid-row: 3 !important;
		display: flex !important;
		flex-direction: row !important;
		flex-wrap: wrap !important;
		align-items: baseline !important;
		justify-content: flex-start !important;
		justify-self: start !important;
		align-self: center !important;
		gap: 4px 10px !important;
		margin: 6px 0 0 !important;
		font-family: var( --xb-font-body );
		font-size: 14px;
		line-height: 1.3;
		text-align: left;
	}
	/* `order` explícito porque el DOM viene main / sep / discount /
	   original y queremos visualizar:
	     fila 1 → "Precio en conjunta: 30€"      (price-main, order 1)
	     fila 2 → "Precio original: 120€  -75%"  (original + discount, orders 2 y 3)
	   El user lo pidió: "the -X% should be right next to the crossed-off
	   original price". Sin `order` el descuento aparecía a la izquierda
	   del original porque iba antes en el markup. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-main {
		order: 1 !important;
		flex: 0 0 100% !important;
		display: block !important;
		font-size: 22px !important;
		font-weight: 700 !important;
		color: #10b981 !important;
		grid-column: auto !important;
		grid-row: auto !important;
		text-align: left !important;
		margin: 0 !important;
		line-height: 1.2 !important;
	}
	/* Label "Precio en conjunta:" mantiene el tamaño body normal — sólo
	   el número crece. El user lo pidió textual: "the precio en conjunta
	   price (not text, just price) to be as big". */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-main::before {
		content: 'Precio en conjunta: ';
		font-weight: 500;
		font-size: 13px;
		color: var( --xb-jacarta-500 );
		vertical-align: middle;
		margin-right: 2px;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-original {
		order: 2 !important;
		display: inline-flex !important;
		align-items: baseline;
		font-size: 13px !important;
		color: var( --xb-jacarta-500 );
		grid-column: auto !important;
		grid-row: auto !important;
		margin: 0 !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-original::before {
		content: 'Precio original: ';
		font-weight: 500;
		font-size: 13px;
		color: var( --xb-jacarta-500 );
		margin-right: 4px;
	}
	/* Strike pin al MISMO tamaño que el label "Precio original:" (13px).
	   El user lo pidió textual: "the crossed-off price to be as small as
	   the precio original text". */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-strike {
		text-decoration: line-through;
		color: var( --xb-jacarta-400 );
		font-size: 13px !important;
		font-weight: 500 !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-original-label,
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-sep {
		display: none !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__discount {
		order: 3 !important;
		display: inline-block !important;
		font-size: 11px !important;
		font-weight: 700 !important;
		color: var( --brand-cta-text ) !important;
		background: var( --brand-cta ) !important;
		padding: 2px 7px !important;
		border-radius: 999px !important;
		margin: 0 !important;
		grid-column: auto !important;
		grid-row: auto !important;
		justify-self: auto !important;
		align-self: center !important;
		line-height: 1.4 !important;
	}
	/* Acciones en col 3, span todas las filas, vertical stack CENTRADO.
	   El user lo pidió: "center the pendiente de pago and all the contents
	   in the column on the right of mis conjuntas". `align-items: center`
	   centra cada child auto-sized; `text-align: center` heredado centra
	   labels internas (ej. "Pendiente de pago" dentro de .cjt-card__pay-wrap). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions {
		grid-column: 3 !important;
		grid-row: 1 / span 3 !important;
		display: flex !important;
		flex-direction: column !important;
		flex-wrap: nowrap !important;
		align-items: center !important;
		align-self: start !important;
		justify-content: flex-start !important;
		gap: 8px !important;
		margin: 0 !important;
		min-width: 0;
		text-align: center !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions > * {
		min-width: 0 !important;
		max-width: 100% !important;
		text-align: center !important;
		margin: 0 !important;
	}
	/* Pay-wrap (botón "Pagar conjunta" + caption "Pendiente de pago" /
	   "Pagado") centra sus dos children — sin esto el wrap heredaba su
	   `align-items: flex-start` global y la caption salía pegada a la
	   izquierda mientras el botón ocupaba el ancho completo. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__pay-wrap {
		align-items: center !important;
		justify-content: center !important;
		text-align: center !important;
		width: 100%;
	}
	/* Author-tag full-width centrado (no inline-flex). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__author-tag {
		display: block !important;
		text-align: center !important;
	}
}

/* Mismo centrado de la columna derecha también en MOBILE (≤768px).
   La col 3 vive a la derecha del thumb + título; antes los children
   estaban con `align-items: stretch` y "Pendiente de pago" aparecía
   pegado a la izquierda dentro de .cjt-card__pay-wrap. */
@media ( max-width: 768px ) {
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions {
		align-items: center !important;
		text-align: center !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__pay-wrap {
		align-items: center !important;
		justify-content: center !important;
		text-align: center !important;
		width: 100%;
	}
}

/* ----- Modal "Panel de voluntario" (data-mod-mepr-volunteer-root) -----
   El user reportó: "Panel de voluntario no abre popup, los campos
   aparecen debajo del contenido". Causa: el modal tenía markup pero
   CERO CSS (sin position: fixed, sin overlay, sin centrado). Sin
   estilos, el `<div hidden>` se quita y queda como bloque inline.
   Aquí lo pintamos como modal centrado fixed con backdrop + panel
   blanco con tokens del theme. */
.mod-mepr-volunteer[hidden] { display: none !important; }
/* User 2026-06-06: bfcache defensive guard. Safari / Brave shields / some
   Firefox versions strip the `hidden` attribute on history restore,
   leaving the modal as an invisible 10001-z-index click-blocker covering
   the whole page. Body class `mod-mepr-volunteer-open` is added by JS in
   voluntario-panel.js on open; if it's missing, force hide regardless of
   the attribute. Same pattern as `body:not(.cjt-confirm-open) .cjt-confirm`
   below. */
body:not(.mod-mepr-volunteer-open) .mod-mepr-volunteer { display: none !important; }
.mod-mepr-volunteer {
	position: fixed;
	inset: 0;
	z-index: 10001;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	padding: 16px;
}
.mod-mepr-volunteer__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.55 );
	cursor: pointer;
}
.mod-mepr-volunteer__modal {
	position: relative;
	width: 100%;
	max-width: 560px;
	max-height: 90vh;
	overflow-y: auto;
	background: #ffffff;
	border-radius: 14px;
	padding: 28px 28px 24px;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	color: var( --xb-jacarta-700 );
	box-sizing: border-box;
}
.mod-mepr-volunteer__x {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 32px;
	height: 32px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 0;
	border-radius: 999px;
	color: var( --xb-jacarta-700 );
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease;
}
.mod-mepr-volunteer__x:hover { background: var( --xb-jacarta-100 ); }
.mod-mepr-volunteer__modal h2 {
	margin: 0 0 18px;
	font-family: var( --xb-font-display );
	font-size: 22px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	letter-spacing: -0.2px;
}
.mod-mepr-volunteer__section {
	margin: 0 0 20px;
	padding: 16px;
	background: var( --xb-jacarta-50 );
	border-radius: 12px;
}
.mod-mepr-volunteer__section-title {
	margin: 0 0 12px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	letter-spacing: 0.2px;
}
.mod-mepr-volunteer__field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0 0 10px;
}
.mod-mepr-volunteer__field span {
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 600;
	color: var( --xb-jacarta-500 );
	letter-spacing: 0.2px;
}
.mod-mepr-volunteer__field input,
.mod-mepr-volunteer__field select {
	width: 100%;
	padding: 10px 12px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	outline: none;
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
	box-sizing: border-box;
}
.mod-mepr-volunteer__field input:focus,
.mod-mepr-volunteer__field select:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
}
.mod-mepr-volunteer__sub { margin-top: 10px; }
.mod-mepr-volunteer__sub[hidden] { display: none; }
.mod-mepr-volunteer__remember,
.mod-mepr-volunteer__warn,
.mod-mepr-volunteer__price,
.mod-mepr-volunteer__saldo-line {
	margin: 0 0 8px;
	font-size: 13px;
	color: var( --xb-jacarta-500 );
}
.mod-mepr-volunteer__remember { color: #c0392b; font-weight: 600; }
.mod-mepr-volunteer__warn { color: #c0392b; font-weight: 500; }
.mod-mepr-volunteer__remember[hidden] { display: none; }
/* Pasos numerados (1. Ordena el material… etc.) bajo el input "URL del
   material". `<small>` con line-height generoso para que las tres
   líneas respiren sin tener que añadir párrafos. */
.mod-mepr-volunteer__hint {
	display: block;
	margin: 10px 0 0;
	font-family: var( --xb-font-body );
	font-size: var( --brand-body-size, 16px );
	font-weight: var( --brand-body-weight, 400 );
	line-height: 1.55;
	color: var( --xb-jacarta-500 );
}

/* Submit button + "dejar de ser voluntario" link inside modal */
.mod-mepr-volunteer__save,
.mod-mepr-volunteer button[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 20px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	color: var( --brand-cta-text );
	background: var( --brand-cta );
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.mod-mepr-volunteer__save:hover,
.mod-mepr-volunteer button[type="submit"]:hover {
	background: var( --brand-cta-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
}
/* "Dejar de ser voluntario" — link normal con texto en ROJO (no CTA),
   subrayado. El user lo pidió: "should be with same red color text as
   desapuntarme button. But should not be a button, rather a text like
   it was before but instead of CTA link color, this kind of red color". */
.mod-mepr-volunteer__quit,
.mod-mepr-volunteer a[data-mod-mepr-volunteer-quit],
.mod-mepr-volunteer a[data-mod-mepr-volunteer-quit]:link,
.mod-mepr-volunteer a[data-mod-mepr-volunteer-quit]:visited {
	display: inline-block !important;
	margin-top: 10px;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: 2px;
	color: #c0392b !important;
	cursor: pointer;
	box-shadow: none !important;
	transform: none !important;
	transition: color 0.15s ease;
}
.mod-mepr-volunteer__quit:hover,
.mod-mepr-volunteer__quit:focus,
.mod-mepr-volunteer a[data-mod-mepr-volunteer-quit]:hover,
.mod-mepr-volunteer a[data-mod-mepr-volunteer-quit]:focus {
	color: #8a2820 !important;
	background: transparent !important;
	transform: none !important;
	box-shadow: none !important;
	outline: none;
}
.mod-mepr-volunteer__error {
	margin: 8px 0;
	padding: 10px 14px;
	background: rgba( 192, 57, 43, 0.10 );
	border-radius: 8px;
	color: #c0392b;
	font-size: 13px;
}
.mod-mepr-volunteer__error[hidden] { display: none; }
body.mod-mepr-volunteer-open { overflow: hidden; }

/* ----- Proponer conjunta — botón + modal -----
   Botón vive en `.mod-mepr-proponer-bar` arriba del grid en mis-conjuntas.
   El modal tiene la misma forma que el volunteer panel: fixed overlay +
   dialog centrado. El user reportó: "no tiene estilo, no abre popup,
   el texto aparece en el contenido". Causa idéntica al volunteer panel:
   markup + JS existían, pero CERO CSS. */
.mod-mepr-proponer-bar {
	margin: 0 0 16px;
}
.mod-mepr-proponer-btn,
.mod-mepr-proponer-bar button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 10px 18px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var( --brand-cta-text );
	background: var( --brand-cta );
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.mod-mepr-proponer-btn:hover,
.mod-mepr-proponer-btn:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
	outline: none;
}

/* Header del panel Mis conjuntas — botón "Proponer conjunta" + link
   "Ver más conjuntas" en una sola fila (flex). En mobile envuelven a
   dos líneas via `flex-wrap`. Anula el `margin-bottom` que la
   `.mod-mepr-proponer-bar` traía por defecto — el margen vive en el
   contenedor exterior. */
.mod-mepr-mis-conjuntas__actions {
	display: flex;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
	margin: 0 0 16px;
}
.mod-mepr-mis-conjuntas__actions .mod-mepr-proponer-bar { margin: 0; }

/* Flash messages tras volver del flujo de pago (Stripe / saldo). */
.mod-mepr-mis-conjuntas__flash {
	margin: 12px 0;
	padding: 12px 16px;
	border-radius: 10px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.5;
}
.mod-mepr-mis-conjuntas__flash.--ok {
	background: color-mix( in srgb, #10b981 12%, #ffffff );
	border: 1px solid color-mix( in srgb, #10b981 40%, transparent );
	color: #047857;
}
.mod-mepr-mis-conjuntas__flash.--info {
	background: var( --xb-jacarta-50 );
	border: 1px solid var( --xb-jacarta-100 );
	color: var( --xb-jacarta-700 );
}
.mod-mepr-mis-conjuntas__flash.--err {
	background: color-mix( in srgb, #ef4444 10%, #ffffff );
	border: 1px solid color-mix( in srgb, #ef4444 35%, transparent );
	color: #b91c1c;
}

/* "Ver más conjuntas" — text link a la DERECHA del botón "Proponer
   conjunta". Mismo tratamiento que el "Ver mis conjuntas" del hero
   del home: texto plano en color brand-CTA, subrayado on hover. */
.mod-mepr-mis-conjuntas__ver-mas,
.mod-mepr-mis-conjuntas__ver-mas:link,
.mod-mepr-mis-conjuntas__ver-mas:visited {
	display: inline-block;
	margin: 0;
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-weight: 600;
	color: var( --brand-cta );
	text-decoration: none;
	letter-spacing: 0;
	transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.mod-mepr-mis-conjuntas__ver-mas:hover,
.mod-mepr-mis-conjuntas__ver-mas:focus {
	color: var( --brand-cta-hover, var( --brand-cta ) );
	text-decoration: underline;
	text-underline-offset: 3px;
	outline: none;
}

/* Modal — same shape pattern as `.mod-mepr-volunteer`. Sin estos estilos
   el `<div hidden>` se quita y el form aparece inline en el contenido,
   no como overlay. */
.mod-mepr-proponer[hidden] { display: none !important; }
/* User 2026-06-06: bfcache defensive guard — see `body:not(.cjt-confirm-open)
   .cjt-confirm` for the full rationale. Body class `mod-mepr-proponer-open`
   is added by JS in proponer-conjunta.js. */
body:not(.mod-mepr-proponer-open) .mod-mepr-proponer { display: none !important; }
.mod-mepr-proponer {
	position: fixed;
	inset: 0;
	z-index: 10001;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	padding: 16px;
}
.mod-mepr-proponer__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.55 );
	cursor: pointer;
}
.mod-mepr-proponer__modal {
	position: relative;
	width: 100%;
	max-width: 560px;
	max-height: 90vh;
	overflow-y: auto;
	background: #ffffff;
	border-radius: 14px;
	padding: 28px 28px 24px;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	color: var( --xb-jacarta-700 );
	box-sizing: border-box;
}
.mod-mepr-proponer__modal[data-mod-mepr-proponer-step][hidden] { display: none; }
.mod-mepr-proponer__x {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 32px;
	height: 32px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 0;
	border-radius: 999px;
	color: var( --xb-jacarta-700 );
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease;
}
.mod-mepr-proponer__x:hover { background: var( --xb-jacarta-100 ); }
.mod-mepr-proponer__modal h2 {
	margin: 0 0 18px;
	font-family: var( --xb-font-display );
	font-size: 22px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	letter-spacing: -0.2px;
}
.mod-mepr-proponer__field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0 0 14px;
}
/* `.mod-mepr-proponer__field { display: flex }` ganaba al UA-stylesheet
   default de `[hidden] { display: none }`, así que el row de la sub-cat
   se mostraba aunque tuviese el atributo `hidden`. Lo forzamos.
   Especificidad 0,3,1 — supera al rule `body.mepr-mod-mis-conjuntas
   .mod-mepr-proponer__field` (0,2,1) que vive en el theme `conjuntas`
   antiguo y todavía se carga en algunas vistas. */
.mod-mepr-proponer__field[hidden],
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__field[hidden] { display: none !important; }
.mod-mepr-proponer__required {
	color: var( --brand-cta, #8358FF );
	margin-left: 2px;
	font-weight: 700;
}
/* Status del botón "Detectar información" — banner verde (ok) o rojo
   (err) que cubre el texto, en vez de simplemente colorear las letras.
   Tamaño full-width DEBAJO del botón con padding generoso, fondo
   tintado y borde sutil. Especificidad bumpeada para ganar al rule
   del theme antiguo (`themes/conjuntas/inc/memberpress-styles.php`). */
.mod-mepr-proponer__detect-status,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__detect-status {
	display: block !important;
	margin: 12px 0 0 !important;
	padding: 10px 14px !important;
	border-radius: 10px !important;
	/* Peso base = regular. Las partes en negrita las marca el caller con
	   `<strong>` (regla más abajo) — así el banner no parece un grito. */
	font-weight: 400 !important;
	line-height: 1.4 !important;
	background: transparent !important;
	border: 1px solid transparent !important;
}
.mod-mepr-proponer__detect-status:empty,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__detect-status:empty {
	display: none !important;
}
.mod-mepr-proponer__detect-status strong,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__detect-status strong {
	font-weight: 700 !important;
}
.mod-mepr-proponer__detect-status.is-ok,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__detect-status.is-ok {
	color: #166534 !important;
	background: #DCFCE7 !important;
	border-color: #86EFAC !important;
}
.mod-mepr-proponer__detect-status.is-err,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__detect-status.is-err {
	color: #8a2820 !important;
	background: #FEE2E2 !important;
	border-color: #FCA5A5 !important;
}

/* Grid de imágenes detectadas — tras "Detectar información" el panel
   muestra candidatas (og:image, twitter:image, JSON-LD, primeros <img>).
   Grid de tiles cuadrados uniformes, máx 4 por fila en desktop, 2 en
   mobile. Sin labels visibles (el tipo va como tooltip via `title`).
   Bumpeamos especificidad con body class por el patrón usual. */
.mod-mepr-proponer__msg,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__msg {
	margin: 14px 0 8px !important;
	font-size: 14px !important;
	color: var( --xb-jacarta-500, #5A5D79 ) !important;
}
.mod-mepr-proponer__grid,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__grid {
	display: grid !important;
	grid-template-columns: repeat( 4, minmax( 0, 1fr ) ) !important;
	gap: 10px !important;
	margin: 0 !important;
	padding: 0 !important;
}
@media ( max-width: 640px ) {
	.mod-mepr-proponer__grid,
	body.mepr-mod-mis-conjuntas .mod-mepr-proponer__grid {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) ) !important;
	}
}
.mod-mepr-proponer__thumb,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb {
	position: relative !important;
	display: block !important;
	width: 100% !important;
	aspect-ratio: 1 / 1 !important;
	padding: 0 !important;
	margin: 0 !important;
	background: #F4F5F8 !important;
	border: 2px solid #E5E7EB !important;
	border-radius: 12px !important;
	overflow: hidden !important;
	cursor: pointer !important;
	transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease !important;
}
.mod-mepr-proponer__thumb:hover,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb:hover {
	border-color: var( --brand-cta, #8358FF ) !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 18px -8px rgba( 0, 0, 0, 0.18 ) !important;
}
.mod-mepr-proponer__thumb.is-selected,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb.is-selected {
	border-color: var( --brand-cta, #8358FF ) !important;
	box-shadow: 0 0 0 3px rgba( 131, 88, 255, 0.25 ) !important;
}
/* Octava tile "✕ sin imagen": fondo claro, ✕ centrado en jacarta-500.
   Aspecto cuadrado igual que las imágenes — el grid las alinea solo. */
.mod-mepr-proponer__thumb--none,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb--none {
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	aspect-ratio: 1 / 1 !important;
	background: #f4f5f8 !important;
	color: var( --xb-jacarta-500, #707092 ) !important;
}
.mod-mepr-proponer__thumb--none:hover,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb--none:hover {
	background: #ebebf2 !important;
	color: var( --xb-jacarta-700, #131740 ) !important;
}
.mod-mepr-proponer__thumb-x,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb-x {
	font-size: 28px !important;
	font-weight: 600 !important;
	line-height: 1 !important;
	font-family: var( --xb-font-display ) !important;
}
.mod-mepr-proponer__thumb img,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb img {
	display: block !important;
	width: 100% !important;
	height: 100% !important;
	object-fit: cover !important;
	background: #F4F5F8 !important;
}
/* Ocultar cualquier label residual del JS antiguo (compatibilidad
   con caches del usuario antes del deploy nuevo). */
.mod-mepr-proponer__thumb-label,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb-label {
	display: none !important;
}
/* Variante "composed" — cuando hay plantilla con overlay. La imagen
   detectada va al fondo, el overlay arriba. Mantenemos cuadrado. */
.mod-mepr-proponer__thumb--composed,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb--composed {
	aspect-ratio: 1 / 1 !important;
}
.mod-mepr-proponer__thumb--composed .mod-mepr-proponer__thumb-bg,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb--composed .mod-mepr-proponer__thumb-bg {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	object-fit: cover !important;
	z-index: 1 !important;
}
.mod-mepr-proponer__thumb--composed .mod-mepr-proponer__thumb-overlay,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__thumb--composed .mod-mepr-proponer__thumb-overlay {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	object-fit: contain !important;
	pointer-events: none !important;
	z-index: 2 !important;
}
.mod-mepr-proponer__field span {
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 600;
	color: var( --xb-jacarta-500 );
	letter-spacing: 0.2px;
}
.mod-mepr-proponer__field input,
.mod-mepr-proponer__field select,
.mod-mepr-proponer__field textarea {
	width: 100%;
	padding: 10px 12px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	outline: none;
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
	box-sizing: border-box;
}
.mod-mepr-proponer__field input:focus,
.mod-mepr-proponer__field select:focus,
.mod-mepr-proponer__field textarea:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
}
.mod-mepr-proponer__detect,
.mod-mepr-proponer__actions {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	margin: 12px 0 0;
}
/* Detectar información + Examinar + Añadir + Submit — TODOS con el
   mismo CTA-pill style. El user pidió: "Detectar información y
   Examinar should have same style as Añadir". Cancelar es la única
   excepción (outline secundario). */
.mod-mepr-proponer__btn-secondary,
.mod-mepr-proponer button[type="submit"],
.mod-mepr-proponer__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 20px;
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.mod-mepr-proponer__btn-secondary:hover,
.mod-mepr-proponer__btn-secondary:focus,
.mod-mepr-proponer button[type="submit"]:hover,
.mod-mepr-proponer__submit:hover {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
	outline: none;
}

/* Cancelar — link estilo outline / texto secundario para diferenciarlo
   visualmente del Añadir CTA. El user reportó "Cancelar has no style". */
.mod-mepr-proponer__cancel {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 20px;
	background: transparent;
	color: var( --xb-jacarta-500 );
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	transition: border-color 0.18s ease, color 0.18s ease, background 0.18s ease;
}
.mod-mepr-proponer__cancel:hover,
.mod-mepr-proponer__cancel:focus {
	border-color: var( --xb-jacarta-700 );
	color: var( --xb-jacarta-700 );
	background: var( --xb-jacarta-50 );
	outline: none;
}
.mod-mepr-proponer__error {
	margin: 8px 0;
	padding: 10px 14px;
	background: rgba( 192, 57, 43, 0.10 );
	border-radius: 8px;
	color: #c0392b;
	font-size: 13px;
}
.mod-mepr-proponer__error[hidden] { display: none; }
body.mod-mepr-proponer-open { overflow: hidden; }

/* Acciones SÍ / NO de los modales secundarios del flujo Proponer
   (recordatorio "Antes de añadirla…", voluntario "¿Quieres ser el
   voluntario?", bloqueo "Ya tienes una propuesta…"). Convención del
   proyecto: SÍ = botón verde prominente (acción afirmativa), NO = link
   discreto. Idéntico patrón al `.cjt-confirm` de Mis Conjuntas pero
   invertido — aquí la acción afirmativa es la mostrada en verde porque
   no es destructiva. */
/* `body` prefix + `!important` para sobrescribir las reglas de
   MemberPress y de WP que repintan `<button>` con sus propios resets
   (border, padding, background). Mismo patrón que usa el legacy theme
   `conjuntas` y que ya consagramos en `.cjt-confirm__*`. */
body .mod-mepr-proponer__actions--stacked,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__actions--stacked {
	display: flex !important;
	flex-direction: column !important;
	gap: 6px !important;
	margin-top: 4px !important;
}
body .mod-mepr-proponer__yes,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__yes,
body .mod-mepr-proponer button.mod-mepr-proponer__yes,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer button.mod-mepr-proponer__yes {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 100% !important;
	max-width: 100% !important;
	margin: 0 !important;
	padding: 12px 18px !important;
	background: #10b981 !important;
	color: #ffffff !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	appearance: none !important;
	box-sizing: border-box !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 14px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	text-align: center !important;
	cursor: pointer !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
body .mod-mepr-proponer__yes:hover,
body .mod-mepr-proponer__yes:focus,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__yes:hover,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__yes:focus {
	background: #0e9c6f !important;
	color: #ffffff !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 16, 185, 129, 0.55 ) !important;
	outline: none !important;
}
body .mod-mepr-proponer__no,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__no,
body .mod-mepr-proponer button.mod-mepr-proponer__no,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer button.mod-mepr-proponer__no {
	display: inline-block !important;
	width: auto !important;
	max-width: 100% !important;
	margin: 4px auto 0 !important;
	padding: 8px 0 !important;
	background: transparent !important;
	color: var( --xb-jacarta-500 ) !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	appearance: none !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
	text-align: center !important;
	cursor: pointer !important;
	transition: color 0.15s ease !important;
}
body .mod-mepr-proponer__no:hover,
body .mod-mepr-proponer__no:focus,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__no:hover,
body.mepr-mod-mis-conjuntas .mod-mepr-proponer__no:focus {
	color: var( --xb-jacarta-700 ) !important;
	background: transparent !important;
	outline: none !important;
}

/* ----- Mis-conjuntas top toolbar (sólo /cuenta/?action=mis-conjuntas) -----
   Layout actual (post-iteración "para claude" 2026-05-09):
     [ Filtros ]                                         [ list/grid toggle ]
   Sólo dos elementos, separados al máximo (`justify-content: space-between`).
   El search bar AHORA vive dentro del drawer del botón Filtros. */
.mod-mepr-toolbar {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0 0 16px;
	flex-wrap: wrap;
}
.mod-mepr-toolbar--split {
	justify-content: space-between;
}
/* Contador "X conjuntas (×)" entre el drawer de filtros y el grid de
   cards. El user lo pidió: "I want X conjuntas text not be below
   button, but below the filtros popup (before the conjuntas list table)". */
.mod-mepr-count {
	margin: 8px 0 6px !important;
	padding: 0 !important;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-500 );
}
.mod-mepr-toolbar .cjt-search {
	flex: 1 1 auto;
	min-width: 0;
}
/* Search bar dentro del drawer — full-width en su propia fila, encima
   de los pills y chip-selectors. */
.mod-mepr-filters-drawer__search {
	flex: 1 1 100%;
	margin: 0 0 6px;
}
.mod-mepr-filters-drawer__search .cjt-search__field {
	width: 100%;
}
.mod-mepr-toolbar__filters-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 12px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.mod-mepr-toolbar__filters-btn:hover,
.mod-mepr-toolbar__filters-btn:focus,
.mod-mepr-toolbar__filters-btn[aria-expanded="true"] {
	border-color: var( --brand-cta );
	color: var( --brand-cta );
	outline: none;
}
.mod-mepr-toolbar__filters-btn svg { flex: 0 0 16px; }

/* Drawer with the actual filters — collapsed by default, expands beneath
   the toolbar when the button is clicked. flex-direction: column +
   width: 100% en TODOS los hijos garantiza que cada bloque se apile
   verticalmente (search → estado pills → cat chips → idioma chips →
   sort), nunca al lado del anterior. El user lo pidió en mobile: "los
   filtros aparecen mal estilados y se empujan a la derecha en vez de
   hacia abajo". */
.mod-mepr-filters-drawer {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 16px;
	margin: 0 0 16px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 14px;
	width: 100%;
	box-sizing: border-box;
	overflow: hidden;
}
.mod-mepr-filters-drawer[hidden] { display: none; }
.mod-mepr-filters-drawer > * {
	width: 100%;
	min-width: 0;
}
.mod-mepr-filters-drawer .cjt-filters__left,
.mod-mepr-filters-drawer .cjt-filters__right,
.mod-mepr-filters-drawer .cjt-filters__flags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}
/* La columna "right" lleva chip-selectors (cats, idiomas) y la fila de
   sort. Stack vertical para que cada selector ocupe su propia fila —
   evita que cats e idiomas compitan por la misma row y se desborden. */
.mod-mepr-filters-drawer .cjt-filters__right {
	flex-direction: column;
	gap: 12px;
}
.mod-mepr-filters-drawer .cjt-chip-selector {
	width: 100%;
}
/* Fila de flags personales (Pendiente de pago / Material disponible /
   Soy voluntario). Renderizado bajo los pills de estado, separación
   visual sutil para indicar "estos NO son mutuamente exclusivos con
   los de arriba — operan en AND". */
.mod-mepr-filters-drawer .cjt-filters__flags {
	padding-top: 8px;
	border-top: 1px dashed var( --xb-jacarta-100 );
}/* Emoji al inicio de cada flag chip — separación visual mínima y mismo
   line-height que el label para que no desplace el baseline. */
.cjt-pill__emoji {
	display: inline-block;
	margin-right: 4px;
	font-size: 13px;
	line-height: 1;
}
/* ===================================================================
 * Base — el theme se mantiene mínimo a propósito; los blocks (footer,
 * topbar, hero, etc.) se irán añadiendo paso a paso.
 * =================================================================== */
html, body {
	margin: 0;
	padding: 0;
	background: #ffffff;
	color: var( --xb-jacarta-700 );
	font-family: var( --xb-font-body );
	font-size: 16px;
	line-height: 1.55;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
	font-family: var( --xb-font-display );
	color: var( --xb-jacarta-700 );
	margin: 0 0 0.5em;
	line-height: 1.15;
}
a { color: var( --brand-cta ); text-decoration: none; }
a:hover, a:focus { color: var( --brand-cta-hover ); }

/* `.screen-reader-text` — viene normalmente del CSS `classic-theme-styles`
   de WordPress, pero lo redeclaramos aquí como defensa por si WP cambia
   sus defaults o algún plugin lo dequeueea. Sin esto, el skip-link y la
   label oculta de la search del navbar quedan visibles. Regla estándar
   copiada de `wp-includes/css/dist/block-library/style.css`. */
.screen-reader-text {
	border: 0;
	clip-path: inset( 50% );
	-webkit-clip-path: inset( 50% );
	clip: rect( 1px, 1px, 1px, 1px );
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute !important;
	width: 1px;
	word-wrap: normal !important;
}
.screen-reader-text:focus {
	background-color: #ffffff;
	border-radius: 4px;
	box-shadow: 0 0 0 2px var( --brand-cta );
	clip-path: none;
	-webkit-clip-path: none;
	clip: auto !important;
	color: var( --xb-jacarta-700 );
	display: block;
	font-size: 14px;
	font-weight: 600;
	height: auto;
	left: 12px;
	line-height: normal;
	padding: 12px 18px;
	text-decoration: none;
	top: 12px;
	width: auto;
	z-index: 100000;
}

/* Container helper — equivalente a `.container` de tailwind/xhibiter. */
.xb-container {
	max-width: 1280px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 16px;
	padding-right: 16px;
}

/* ===================================================================
 * Entry / single — estructura base de cualquier post o página servida
 * desde index.php (fallback de WP cuando no hay single.php / page.php
 * específicos). Centrado, ancho de columna cómoda, tipografía heredada
 * de DM Sans/CalSans-SemiBold y rhythm vertical de bloques.
 * =================================================================== */
.site-content { display: block; }
.xb-entry {
	max-width: 760px;
	margin: 0 auto;
	padding: 64px 24px 96px;
}
@media ( max-width: 768px ) {
	.xb-entry { padding: 48px 16px 64px; }
}
.xb-entry__post + .xb-entry__post {
	margin-top: 56px;
	padding-top: 56px;
	border-top: 1px solid var( --xb-jacarta-100 );
}
.xb-entry__header { margin-bottom: 32px; }
.xb-entry__title {
	margin: 0 0 8px;
	font-family: var( --xb-font-display );
	font-size: clamp( 32px, 5vw, 52px );
	font-weight: 600;
	letter-spacing: -0.005em;
	line-height: 1.15;
	color: var( --xb-jacarta-700 );
}
.xb-entry__meta {
	margin: 0;
	font-size: 14px;
	color: var( --xb-jacarta-500 );
}
.xb-entry__body {
	font-family: var( --xb-font-body );
	font-size: 17px;
	line-height: 1.7;
	color: var( --xb-jacarta-700 );
}
.xb-entry__body > * + * { margin-top: 1.1em; }
.xb-entry__body p,
.xb-entry__body ul,
.xb-entry__body ol,
.xb-entry__body blockquote,
.xb-entry__body figure,
.xb-entry__body pre,
.xb-entry__body table { margin: 0; }
.xb-entry__body h2,
.xb-entry__body h3,
.xb-entry__body h4,
.xb-entry__body h5,
.xb-entry__body h6 {
	font-family: var( --xb-font-display );
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	line-height: 1.2;
	margin-top: 1.6em;
	margin-bottom: 0.4em;
}
.xb-entry__body h2 { font-size: clamp( 22px, 3vw, 30px ); }
.xb-entry__body h3 { font-size: clamp( 19px, 2.4vw, 24px ); }
.xb-entry__body h4 { font-size: 18px; }
.xb-entry__body img,
.xb-entry__body figure img,
.xb-entry__body iframe,
.xb-entry__body video {
	max-width: 100%;
	height: auto;
	border-radius: 12px;
}
.xb-entry__body a {
	color: var( --brand-cta );
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}
.xb-entry__body a:hover,
.xb-entry__body a:focus { color: var( --brand-cta-hover ); }
.xb-entry__body blockquote {
	margin-left: 0;
	padding: 4px 24px;
	border-left: 3px solid var( --brand-cta );
	color: var( --xb-jacarta-500 );
	font-style: italic;
}
.xb-entry__body code,
.xb-entry__body kbd,
.xb-entry__body pre {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.92em;
}
.xb-entry__body pre {
	padding: 16px 18px;
	background: var( --xb-jacarta-50 );
	border-radius: 10px;
	overflow-x: auto;
}
.xb-entry__body code {
	padding: 1px 6px;
	background: var( --xb-jacarta-50 );
	border-radius: 4px;
}
.xb-entry__body ul,
.xb-entry__body ol { padding-left: 1.5em; }
.xb-entry__body ul li + li,
.xb-entry__body ol li + li { margin-top: 6px; }
.xb-entry__body table {
	width: 100%;
	border-collapse: collapse;
}
.xb-entry__body th,
.xb-entry__body td {
	padding: 10px 12px;
	border-bottom: 1px solid var( --xb-jacarta-100 );
	text-align: left;
}
/* ===================================================================
 * Navbar — copiado del header de `xhibiter/HTML/dist/home-5.html`:
 * fixed top, fondo transparente con `backdrop-filter: blur`, mega-dropdown
 * "Explore" con íconos coloreados. Auto-hide al scrollear hacia abajo,
 * vuelve al hacer scroll-up (la lógica vive en el inline JS al final del
 * `<header>`; aquí sólo el `transform`).
 *
 * Los selectores `.xb-nav__*` están aislados; no entran en colisión con
 * los `cjt-*` del plugin Conjuntas ni con `.site-footer__*` del footer.
 * =================================================================== */
.xb-nav {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 50;
	/* COMPLETAMENTE TRANSPARENTE arriba del fold — sin blur, sin sombra,
	   sin background. !important porque alguna regla de specificity
	   superior estaba dejando el blur en estado base (el user lo reportó
	   como "0 changes" tras 2 iteraciones). Sólo el bloque
	   `.xb-nav.is-scrolled` (mayor specificity con misma regla) pinta el
	   chrome cuando el JS añade la clase a scrollY > 8. */
	background: transparent !important;
	backdrop-filter: none !important;
	-webkit-backdrop-filter: none !important;
	box-shadow: none !important;
	transition: transform 0.35s cubic-bezier( .4, 0, .2, 1 ),
	            background 0.25s ease,
	            backdrop-filter 0.25s ease,
	            box-shadow 0.25s ease,
	            top 0.2s ease;
}
/* Cuando el JS añade `.is-scrolled` (scrollY > 8), pintamos el chrome.
   Doblamos `!important` aquí también para vencer el `!important` del base. */
.xb-nav.is-scrolled {
	background: rgba( 255, 255, 255, 0.85 ) !important;
	backdrop-filter: blur( 20px ) !important;
	-webkit-backdrop-filter: blur( 20px ) !important;
	box-shadow: 0 6px 24px -8px rgba( 13, 16, 45, 0.12 ) !important;
}/* WordPress admin bar (sólo cuando está logueado) — se sienta arriba del
   viewport con `html { margin-top: 32px }`. Bajamos el navbar para que no
   quede por debajo. En <=782px el admin bar mide 46px. */
html.admin-bar .xb-nav,
body.admin-bar .xb-nav { top: 32px; }
@media ( max-width: 782px ) {
	html.admin-bar .xb-nav,
	body.admin-bar .xb-nav { top: 46px; }
	html.admin-bar .xb-nav__panel,
	body.admin-bar .xb-nav__panel { top: 46px; height: calc( 100vh - 46px ); }
}
.xb-nav.is-hidden,
body.xb-nav-hidden .xb-nav {
	transform: translateY( -110% ) !important;
	pointer-events: none !important;
}
/* WP admin bar — el navbar se posiciona en `top: 32px` (46 mobile)
   bajo el admin bar. translateY(-110%) sólo mueve un 110% de la
   altura del propio nav, así que el navbar quedaba parcialmente
   visible por arriba del admin bar offset. Restamos también la
   altura del admin bar al translate. */
body.admin-bar .xb-nav.is-hidden,
body.xb-nav-hidden.admin-bar .xb-nav {
	transform: translateY( calc( -110% - 32px ) ) !important;
}
@media ( max-width: 782px ) {
	body.admin-bar .xb-nav.is-hidden,
	body.xb-nav-hidden.admin-bar .xb-nav {
		transform: translateY( calc( -110% - 46px ) ) !important;
	}
}
/* Nota: la regla `.xb-nav.is-scrolled` que pintaba el chrome aquí se
   movió 30 líneas más arriba (con `!important`) para garantizar que el
   navbar es transparente en base hasta que se scrollee. Mantenerla aquí
   también no es problema — pero está consolidada arriba. */
.xb-nav__inner {
	max-width: 1280px;
	margin: 0 auto;
	padding: 18px 24px;
	display: flex;
	align-items: center;
	gap: 24px;
	position: relative;
}

/* CTA central de visitante en la home — pill posicionada
   absolutamente en el centro del navbar. Oculta por defecto (cuando
   el navbar está transparente arriba del fold). Se revela cuando el
   nav scrollea > 8px (clase `.is-scrolled` añadida por el script de
   `header.php`). El user lo pidió: "create a CTA button in the middle
   of nav bar only for visitors and only appears after scrolling up
   (not above fold) so when nav bar is 100% transparent CTA does not
   appear, but when not fully transparent then it does appear". */
.xb-nav__visitor-cta {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate( -50%, -50% ) translateY( 4px );
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 8px 18px;
	background: var( --brand-cta );
	color: var( --brand-cta-text ) !important;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	z-index: 5;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.25s ease, transform 0.25s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.xb-nav.is-scrolled .xb-nav__visitor-cta {
	opacity: 1;
	pointer-events: auto;
	transform: translate( -50%, -50% );
}
/* En páginas que NO son la home (`body:not(.home)`), el navbar no
   tiene la fase transparente above-the-fold — el CTA se muestra
   siempre desde arriba. El user lo pidió: "for visitors now in
   the home the cta button in the headernavbar does not appear
   above the fold, but do it so that in other pages that are not
   the home, yes, it appears for visitors on the navbar". */
body:not(.home) .xb-nav__visitor-cta {
	opacity: 1;
	pointer-events: auto;
	transform: translate( -50%, -50% );
}
.xb-nav__visitor-cta:hover,
.xb-nav__visitor-cta:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover ) !important;
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
	outline: none;
}
/* Mobile/tablet: alturas y paddings más compactos para que el navbar no
   ocupe demasiado del viewport pequeño (la altura efectiva controla el
   `padding-top` del body — ver más abajo).

   Visitor CTA en responsive: NO se oculta. Sale del centro absoluto y
   pasa a estar en flujo, posicionada a la DERECHA del header, justo a
   la IZQUIERDA del hamburger (orden flex: brand → actions → cta →
   hamburger). El user lo pidió: "for visitors, on responsive, the cta
   button in the nav will not be hidden, but on the right side of
   header in responsive, at the left of the burger/menu". */
@media ( max-width: 1024px ) {
	.xb-nav__inner { padding: 14px 16px; gap: 10px; flex-wrap: nowrap; }
	/* Brand (izquierda): nunca se comprime — `flex-shrink: 0` viene
	   de la regla global de `.xb-nav__brand`, pero re-afirmamos aquí
	   para que el flex layout de mobile sepa que es prioridad alta. */
	.xb-nav__brand {
		flex: 0 0 auto;
		min-width: 0;
	}
	/* Visitor CTA: ahora puede shrinkear y envolverse en varias líneas
	   cuando el label es largo. Antes tenía `white-space: nowrap` (no
	   escrito explícito, default heredado del `padding: …`) + `flex: 0
	   1 auto` permitía shrink pero `nowrap` forzaba el ancho al texto
	   completo, empujando el hamburger fuera de pantalla. El user lo
	   pidió: "menu on the left and right should never be compromised
	   — make the CTA bigger and in several lines instead". */
	.xb-nav__visitor-cta {
		position: static;
		transform: none !important;
		opacity: 1 !important;
		pointer-events: auto !important;
		order: 9;
		flex: 0 1 auto;
		min-width: 0;
		max-width: calc( 100% - 24px ); /* deja siempre 24px+ para el hamburger */
		margin-left: auto;
		padding: 7px 12px;
		font-size: 12px;
		letter-spacing: 0.25px;
		white-space: normal;     /* permite wrap a 2+ líneas */
		text-align: center;
		line-height: 1.2;
		word-break: break-word;
	}
	/* Hamburger (derecha): NUNCA shrink, NUNCA desplazado fuera. */
	.xb-nav__mobile-actions {
		order: 10;
		flex: 0 0 auto;
		margin-left: 8px;
	}
	.xb-nav__mobile-actions .xb-nav__icon-btn {
		flex: 0 0 auto;
	}
	/* Cuando hay visitor-cta, ÉL recoge el `margin-left: auto` y empuja
	   el hamburger a su derecha sin doble-push. */
	.xb-nav__visitor-cta ~ .xb-nav__mobile-actions { margin-left: 8px; }
}
@media ( max-width: 559px ) {
	/* En phones aún más estrechos, recortamos padding y font-size para
	   que el CTA quepa con el hamburger sin desbordar. El wrap a 2
	   líneas sigue activo de la regla anterior. */
	.xb-nav__visitor-cta {
		padding: 6px 10px;
		font-size: 11px;
		letter-spacing: 0.2px;
	}
}

.xb-nav__brand {
	display: inline-flex;
	align-items: center;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	flex-shrink: 0;
}
.xb-nav__brand-text {
	font-family: var( --xb-font-display );
	font-size: 22px;
	letter-spacing: 0.2px;
}
.xb-nav__brand:hover .xb-nav__brand-text,
.xb-nav__brand:focus .xb-nav__brand-text { color: var( --brand-cta ); }
.xb-nav__panel {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-left: auto;
}
.xb-nav__panel-head { display: none; } /* Sólo visible en el drawer mobile. */
.xb-nav__primary { /* posición la decide xb-nav__panel */ }
.xb-nav__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	align-items: center;
	gap: 4px;
}
.xb-nav__item { position: relative; }
.xb-nav__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 10px 18px;
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	transition: color 0.2s ease;
	border-radius: 999px;
}
.xb-nav__link:hover,
.xb-nav__link:focus,
.xb-nav__item:hover > .xb-nav__link,
.xb-nav__item:focus-within > .xb-nav__link { color: var( --brand-cta ); }
.xb-nav__caret { transition: transform 0.2s ease; }
.xb-nav__item--has-dropdown:hover .xb-nav__caret,
.xb-nav__item--has-dropdown:focus-within .xb-nav__caret { transform: rotate( 180deg ); }

/* Mega-dropdown del item Explore — 2 columnas x 5 filas igual que
   xhibiter. Aparece on hover (desktop) o on focus (keyboard). */
.xb-nav__dropdown {
	position: absolute;
	/* `top: 85%` solapa el dropdown con el ítem padre (~15% de overlap)
	   IGUAL que xhibiter (`top-[85%]`). Sin overlap, había un gap entre
	   parent y dropdown que el cursor cruzaba al moverse hacia un sub-
	   item — durante esos pixeles se perdía `:hover` y el dropdown se
	   cerraba. La traslación inicial (16px) + final (8px) sigue dando
	   sensación de "drop in" sin crear gap real. */
	top: 85%;
	/* Anclamos al borde DERECHO del item para evitar que un mega-menú
	   ancho (480px) se salga por la derecha cuando el item está cerca
	   del borde de la pantalla — exactamente el bug reportado. */
	right: -16px;
	left: auto;
	min-width: 480px;
	max-width: min( 520px, calc( 100vw - 32px ) );
	margin: 0;
	padding: 18px 14px;
	list-style: none;
	background: #ffffff;
	border-radius: 16px;
	box-shadow:
		0 25px 50px -12px rgba( 13, 16, 45, 0.18 ),
		0 12px 24px 0 rgba( 13, 16, 45, 0.08 );
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 8px;
	row-gap: 0;
	opacity: 0;
	visibility: hidden;
	transform: translateY( 16px );
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
	pointer-events: none;
}
.xb-nav__item--has-dropdown:hover > .xb-nav__dropdown,
.xb-nav__item--has-dropdown:focus-within > .xb-nav__dropdown,
.xb-nav__item--has-dropdown.is-open > .xb-nav__dropdown {
	opacity: 1;
	visibility: visible;
	transform: translateY( 8px );
	pointer-events: auto;
}
.xb-nav__dropdown-link {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 14px;
	border-radius: 12px;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	transition: background 0.18s ease, color 0.18s ease;
	white-space: nowrap;
}
.xb-nav__dropdown-link:hover,
.xb-nav__dropdown-link:focus {
	background: var( --xb-jacarta-50 );
	color: var( --brand-cta );
}
.xb-nav__dropdown-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 12px;
	flex-shrink: 0;
}
.xb-nav__dropdown-label {
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
}

/* CTA opcional del navbar (toggleable desde Customizer → Color y
   tipografía). Vive entre el menú y el bloque de iconos. Ligeramente
   más compacto que el `.btn-cta` por defecto para no robar altura al
   navbar. */
.xb-nav__cta {
	margin-left: 8px;
	padding: 9px 22px;
	font-size: 14px;
}
@media ( max-width: 1024px ) {
	.xb-nav__cta { width: 100%; margin: 0 0 12px; padding: 12px 24px; text-align: center; }
}

/* ----- Action group (wallet / profile / dark mode) — círculos icon-only ----- */
.xb-nav__actions {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-left: 16px;
}
.xb-nav__icon-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	background: #ffffff;
	color: var( --xb-jacarta-700 );
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.xb-nav__icon-btn:hover,
.xb-nav__icon-btn:focus {
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	border-color: transparent;
	outline: none;
}

/* Profile dropdown — toggleable on click. */
.xb-nav__profile { position: relative; }
.xb-nav__profile-menu {
	position: absolute;
	top: calc( 100% + 12px );
	right: -8px;
	min-width: 240px;
	padding: 14px 8px;
	background: #ffffff;
	border-radius: 14px;
	box-shadow: 0 25px 50px -12px rgba( 13, 16, 45, 0.18 );
	opacity: 0;
	visibility: hidden;
	transform: translateY( 6px );
	transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.xb-nav__profile.is-open .xb-nav__profile-menu {
	opacity: 1;
	visibility: visible;
	transform: translateY( 0 );
}
.xb-nav__profile-addr {
	display: flex;
	align-items: center;
	gap: 6px;
	width: calc( 100% - 8px );
	margin: 4px 4px 12px;
	padding: 0 12px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: transparent;
	border: 0;
	cursor: pointer;
	text-align: left;
}
.xb-nav__profile-addr-text {
	max-width: 11rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.xb-nav__profile-addr svg { color: var( --xb-jacarta-500 ); flex-shrink: 0; }
.xb-nav__profile-greeting {
	margin: 14px 12px 8px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 700;
	color: var( --xb-jacarta-700, #131740 );
	line-height: 1.3;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}.xb-nav__profile-balance,
.xb-nav__profile-balance:link,
.xb-nav__profile-balance:visited {
	display: block;
	margin: 0 12px 12px;
	padding: 12px;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	text-decoration: none;
	color: inherit;
	transition: border-color 0.15s ease, background 0.15s ease;
}
.xb-nav__profile-balance:hover,
.xb-nav__profile-balance:focus {
	border-color: var( --brand-cta, #8358FF );
	background: rgba( 131, 88, 255, 0.04 );
	outline: none;
}
.xb-nav__profile-balance-lbl {
	display: block;
	margin-bottom: 4px;
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.2px;
	color: var( --xb-jacarta-500 );
}
.xb-nav__profile-balance-row {
	display: flex;
	align-items: center;
	gap: 6px;
}
.xb-nav__profile-balance-val {
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 700;
	color: #10b981;
}
.xb-nav__profile-balance-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	font-size: 16px;
	line-height: 1;
}
.xb-nav__profile-link {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 8px 14px;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	border-radius: 10px;
	transition: background 0.18s ease, color 0.18s ease;
	font-family: var( --xb-font-display );
	font-size: 14px;
}
.xb-nav__profile-link:hover,
.xb-nav__profile-link:focus {
	background: var( --xb-jacarta-50 );
	color: var( --brand-cta );
}

/* Mobile burger / dark-mode pair — sólo visibles en pantallas pequeñas. */
.xb-nav__mobile-actions { display: none; align-items: center; gap: 8px; }

/* ----- Mobile drawer (panel) ----- */
@media ( max-width: 1024px ) {
	/* Drawer mobile — réplica del `js-mobile-menu` de xhibiter:
	   `inset: 0` (full viewport) cuando abierto, fuera de pantalla con
	   `transform: translateX(100%)` cuando cerrado. Usamos transform en
	   vez de `right: -N%` porque éste último es ambiguo cuando la fila
	   tiene paddings/scrollbars/containing-block edge cases — algunos
	   navegadores dejaban un sliver del drawer visible en el borde
	   derecho del viewport. Translate sobre el ancho del propio elemento
	   es siempre exacto. */
	.xb-nav__panel {
		position: fixed;
		top: 0;
		right: 0;
		width: 100%;
		height: 100vh;
		margin: 0;
		padding: 24px;
		/* CRÍTICO: sin border-box, los 24px de padding se suman al
		   `width: 100%` y el drawer mide viewport+48px → se sale por
		   ambos lados. Con border-box, padding va dentro del width. */
		box-sizing: border-box;
		background: #ffffff;
		flex-direction: column;
		align-items: stretch;
		gap: 8px;
		overflow-y: auto;
		overflow-x: hidden;
		box-shadow: none;
		transform: translateX( 100% );
		transition: transform 0.3s ease;
		z-index: 9999;
	}
	.xb-nav__panel.is-open { transform: translateX( 0 ); }
	/* Cuando WP renderiza la admin bar, bajamos el drawer para que la
	   admin bar siga visible y el botón "cerrar" sea accesible. */
	html.admin-bar .xb-nav__panel,
	body.admin-bar .xb-nav__panel { top: 32px; height: calc( 100vh - 32px ); }
	.xb-nav__panel-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 12px;
	}
	.xb-nav__primary { margin: 0; }
	.xb-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
	/* Items grandes y aireados — coincide con el `py-3.5 font-display
	   text-base` de xhibiter (~14px de padding vertical, 16px font). */
	.xb-nav__item { border-radius: 0; }
	.xb-nav__link {
		width: 100%;
		justify-content: space-between; /* chevron al borde derecho */
		padding: 14px 0;
		font-size: 16px;
		gap: 12px;
		border-radius: 0;
	}
	.xb-nav__dropdown {
		position: static;
		min-width: 0;
		max-width: none;
		grid-template-columns: 1fr;
		opacity: 1;
		visibility: visible;
		transform: none;
		pointer-events: auto;
		box-shadow: none;
		padding: 0 0 8px 12px;
		display: none;
	}
	/* En mobile el dropdown SÓLO se abre con click — el JS añade `.is-open`
	   al `<li>` cuando el usuario toca el item padre. Quitamos la apertura
	   por hover/focus que en touch se quedaba "pegada" tras un tap. */
	.xb-nav__item--has-dropdown.is-open > .xb-nav__dropdown {
		display: grid;
	}
	/* Anula la rotación del caret on hover/focus que viene del CSS desktop
	   (en touch, focus-within se queda "pegado" tras un tap y dejaba el
	   chevron rotado sin que el menú estuviese abierto). */
	.xb-nav__item--has-dropdown:hover > .xb-nav__link .xb-nav__caret,
	.xb-nav__item--has-dropdown:focus-within > .xb-nav__link .xb-nav__caret {
		transform: none;
	}
	.xb-nav__item--has-dropdown.is-open > .xb-nav__link .xb-nav__caret {
		transform: rotate( 180deg );
	}
	/* También: el color azul de focus en touch se quedaba pegado. Lo
	   reseteamos para que al cerrar el dropdown vuelva al estilo normal. */
	.xb-nav__item:focus-within > .xb-nav__link { color: var( --xb-jacarta-700 ); }
	.xb-nav__item.is-open > .xb-nav__link { color: var( --brand-cta ); }
	/* Dentro del drawer las labels pueden necesitar varias líneas. */
	.xb-nav__dropdown-link { white-space: normal; }

	/* En desktop el profile dropdown está anclado a `right: -8px` porque
	   el profile vive en el extremo derecho del navbar. En el drawer
	   mobile el profile está en el lado IZQUIERDO de `.xb-nav__actions`,
	   así que el dropdown se salía por la izquierda y `overflow-x: hidden`
	   lo recortaba. Aquí lo re-anclamos a la izquierda y lo ensanchamos
	   hasta el ancho disponible del drawer (sin pasarse del padding). */
	.xb-nav__profile-menu {
		right: auto;
		left: 0;
		width: calc( 100vw - 48px );
		max-width: 360px;
	}
	.xb-nav__actions {
		justify-content: flex-start;
		margin-left: 0;
		flex-wrap: wrap;
	}
	/* En el navbar exterior (fuera del drawer) sólo quedan brand +
	   mobile-actions; sin esto, el hamburger se pegaría al brand en
	   lugar de quedar en el lado derecho. */
	.xb-nav__mobile-actions { display: inline-flex; margin-left: auto; }
	body.xb-nav-open { overflow: hidden; }
}
/* Overlay real (vs pseudo-elemento `body::after`) — click-to-close
   cableado en el JS del header. Vive FUERA del `<header>` para que
   `inset:0` cubra siempre el viewport entero, independientemente de
   transformaciones/stacking contexts en la cabecera. */
.xb-nav__overlay {
	display: none;
	position: fixed;
	inset: 0;
	background: rgba( 13, 16, 45, 0.55 );
	z-index: 9998; /* Justo por debajo del drawer (9999), por encima del admin bar (~99999) y de cualquier plugin. */
	cursor: pointer;
}
body.xb-nav-open .xb-nav__overlay { display: block; }
/* Modo navbar del VISITANTE en la home. El `<body>` lleva
   `home-nav-visitor` cuando `is_front_page() && ! active_member()`.
   Un único toggle del Customizer ("Mostrar menú a visitantes")
   añade `home-nav-show-menu` cuando el admin lo activa.

   Siempre escondidos para visitantes en home:
     - `.xb-nav__cta`     brand CTA del navbar (siempre oculto)
   Configurables:
     - `.xb-nav__primary` menú principal — oculto por defecto
       SALVO que `home-nav-show-menu` esté presente. */
body.home-nav-visitor .xb-nav__cta {
	display: none !important;
}
body.home-nav-visitor:not(.home-nav-show-menu) .xb-nav__primary {
	display: none !important;
}
/* Hamburger/panel: si el menú está oculto no hay nada que abrir;
   colapsamos el panel completo. */
body.home-nav-visitor:not(.home-nav-show-menu) .xb-nav__mobile-actions,
body.home-nav-visitor:not(.home-nav-show-menu) .xb-nav__panel-head {
	display: none !important;
}
body.home-nav-visitor:not(.home-nav-show-menu) .xb-nav__panel { padding: 0; }
body.home-nav-visitor:not(.home-nav-show-menu) .xb-nav__overlay { display: none !important; }

/* Profile menu del visitante — comparte estilo con `.xb-nav__profile`
   del logged-in pero con menos items dentro (sólo Acceder). Forzamos
   `display: none` del profile-balance porque la regla original lo
   coloca arriba; aquí no hay saldo que mostrar. */
.xb-nav__profile--visitor .xb-nav__profile-balance { display: none !important; }
/* Quitamos el header del flow — el body NO se compensa por defecto. La
   home (template-home.php) y el resto de templates pueden añadir
   `padding-top` o un hero alto, según diseño. Aquí dejamos un margen
   lo bastante visible para que el contenido no quede tapado en pruebas.
   Cálculo: padding vertical inner (18*2 desktop / 14*2 mobile) + alto del
   icon button 40 = 76 desktop / 68 mobile. Le sumamos un par de px. */
body {
	padding-top: 78px;
	transition: padding-top 0.35s cubic-bezier( .4, 0, .2, 1 );
}
@media ( max-width: 1024px ) { body { padding-top: 72px; } }
/* Cuando el navbar se auto-oculta al scrollear hacia abajo, el
   padding-top reservado para el navbar (78/72px) se colapsa a 0.
   El admin bar (32/46px) lo reserva automáticamente WordPress vía
   `html { margin-top: 32px !important }` — NO añadir padding extra
   en body o se duplica el offset y queda un strip de 32/46px
   vacío. El user lo pidió: "as admin the nav bar still looks
   hanging with margin". */
body.xb-nav-hidden { padding-top: 0 !important; }

/* ===================================================================
 * Footer — estructura idéntica al theme antiguo (3 columnas sobre la
 * derecha + bloque inferior con copy/legal/badges) pintada con la paleta
 * y tipografía de xhibiter (white bg, jacarta-300 muted, accent on hover).
 * =================================================================== */
.site-footer {
	background: #ffffff;
	color: var( --xb-jacarta-500 );
	border-top: 1px solid var( --xb-jacarta-100 );
	padding: 96px 0 48px;
	font-family: var( --xb-font-body );
}
.site-footer__inner {
	max-width: 1280px;
	margin: 0 auto;
	padding: 0 16px;
	display: grid;
	grid-template-columns: 2fr 1fr 1fr;
	gap: 56px 48px;
}
/* Responsive footer — el brand-col + su description ocupan todo el ancho
   disponible debajo del breakpoint desktop (1024px). El user lo pidió
   explícitamente: "Footer on responsive should be taking the description
   extensively ... it should take the right side of the screen too". */
@media ( max-width: 1024px ) {
	.site-footer__inner {
		grid-template-columns: 1fr 1fr;
		gap: 32px 24px;
	}
	.site-footer__brand-col {
		grid-column: 1 / -1; /* span ambas columnas — toda la fila */
		max-width: none !important; /* sin cap de 360px */
		width: 100%;
	}
	.site-footer__desc {
		max-width: none;
		width: 100%; /* la description estira hasta el borde derecho */
	}
}
@media ( max-width: 768px ) {
	.site-footer { padding: 64px 0 32px; }
}

/* Columna brand (logo + descripción + socials). Desktop default 360px de
   ancho — ya quitado en el mediaquery responsive de arriba. */
.site-footer__brand-col { max-width: 360px; }
.site-footer__brand {
	/* `gap` y `display: inline-flex` heredados de la regla compartida
	   .xb-nav__brand, .site-footer__brand, .mepr-mod-sidebar__brand
	   (gap: 1px). NO redefinir `gap` aquí — antes había `gap: 10px`
	   que ganaba por orden y producía distancias desiguales nav vs
	   footer (el user lo señaló dos veces). */
	margin: 0 0 24px;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
}
.site-footer__brand-text {
	font-family: var( --xb-font-display );
	font-size: 22px;
	letter-spacing: 0.2px;
	color: inherit;
}
.site-footer__brand:hover .site-footer__brand-text,
.site-footer__brand:focus .site-footer__brand-text {
	color: var( --brand-cta );
}
.site-footer__desc {
	margin: 0 0 32px;
	font-size: 15px;
	line-height: 1.6;
	color: var( --xb-jacarta-400 );
}
.site-footer__social {
	display: flex;
	gap: 18px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.site-footer__social a {
	display: inline-flex;
	color: var( --xb-jacarta-300 );
	transition: color 0.2s ease;
}
.site-footer__social a:hover,
.site-footer__social a:focus { color: var( --brand-cta ); }

/* Columnas de listas (Conjuntas / Sobre Conjuntas.org / etc.). */
.site-footer__col-title {
	font-family: var( --xb-font-display );
	font-size: 16px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 24px;
	letter-spacing: 0.2px;
}
.site-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
}
.site-footer__list a {
	color: var( --xb-jacarta-500 );
	text-decoration: none;
	font-size: 15px;
	transition: color 0.2s ease;
}
.site-footer__list a:hover,
.site-footer__list a:focus { color: var( --brand-cta ); }

/* Bottom bar (copyright + legal + badges). */
.site-footer__bottom {
	max-width: 1280px;
	margin: 56px auto 0;
	padding: 24px 16px 0;
	border-top: 1px solid var( --xb-jacarta-100 );
	display: flex;
	flex-wrap: wrap;
	gap: 16px 32px;
	align-items: center;
	justify-content: space-between;
	font-size: 13px;
	color: var( --xb-jacarta-400 );
}
.site-footer__copy { margin: 0; }
.site-footer__legal,
.site-footer__badges {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px 18px;
	align-items: center;
}
.site-footer__legal a {
	color: var( --xb-jacarta-400 );
	text-decoration: none;
	transition: color 0.2s ease;
}
.site-footer__legal a:hover,
.site-footer__legal a:focus { color: var( --brand-cta ); }
.site-footer__badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 4px 10px;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	color: var( --xb-jacarta-400 );
	font-size: 12px;
}

/* ===================================================================
 * Listado /lista-de-cursos/ — réplica visual de
 * `xhibiter/HTML/dist/collections-wide-sidebar.html`. Layout: sidebar
 * sticky a 1/5 + grid principal con article-cards. Los filtros vienen
 * del plugin (selectores `[data-filter-*]` que el JS de cursos-filter
 * sigue leyendo igual).
 * =================================================================== */
.xb-collections {
	padding: 96px 0 72px; /* 96 = aire bajo el navbar fijo */
	font-family: var( --xb-font-body );
	color: var( --xb-jacarta-700 );
	background: var( --xb-light-base );
}
.xb-collections__container {
	max-width: 1280px;
	margin: 0 auto;
	padding: 0 24px;
}
/* En mobile el aire de top y los paddings horizontales son demasiado
   grandes — el listado se siente apretado y el título queda muy abajo. */
@media ( max-width: 768px ) {
	.xb-collections { padding: 56px 0 48px; }
	.xb-collections__container { padding: 0 16px; }
}
.xb-collections__main { padding-top: 16px; }

/* Descripción del término — visible sólo en `/lista-de-cursos/<slug>/`.
   Vive DENTRO del panel de contenido, pegada al grid de arriba. Sin
   border-top ni padding heavy: que se note como continuación del
   listado, no como sección aparte. */
.xb-collections__cat-description {
	margin-top: 28px;
	max-width: 720px;
}
.xb-collections__cat-description-title {
	margin: 0 0 8px;
	font-family: var( --xb-font-display );
	font-size: 17px;
	font-weight: 600;
	letter-spacing: 0;
	color: var( --xb-jacarta-700 );
}
.xb-collections__cat-description-body {
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.65;
	color: var( --xb-jacarta-500 );
}
.xb-collections__cat-description-body > * + * { margin-top: 0.8em; }
.xb-collections__cat-description-body a {
	color: var( --brand-cta );
	text-decoration: underline;
	text-underline-offset: 3px;
}
.xb-collections__cat-description-body a:hover,
.xb-collections__cat-description-body a:focus { color: var( --brand-cta-hover ); }
/* Heading dentro del panel principal del listado — réplica del bloque
   de xhibiter (`<h1>Explore Collections</h1><p>156,893 items</p>` +
   pill de toggle grid/lista a la derecha). Aquí mantenemos sólo el
   contador (sin H1) a la izquierda y los dos iconos a la derecha. */
.xb-collections__heading {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	margin: 4px 0 20px;
	flex-wrap: wrap;
}
.xb-collections__count {
	margin: 0;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 500;
	color: var( --xb-jacarta-500 );
	letter-spacing: 0.2px;
}
/* Highlight de partes dinámicas del contador — número + valores de
   filtros activos (estado, categoría, idioma) en color brand-CTA. Las
   palabras estáticas ("conjuntas", "sobre", "en", "con") quedan en el
   tono muted del párrafo padre. */
.xb-collections__count-hl {
	color: var( --brand-cta );
	font-weight: 600;
}

/* Botón "limpiar filtros" — el user pidió que sea un icono X (en vez de
   texto "(limpiar filtros)"), con el mismo aspecto que los iconos de
   categoría: círculo de fondo + svg al centro. Click cancela todos los
   filtros (el handler en cursos-filter.js no cambia). */
.xb-collections__count-clear {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	margin-left: 8px;
	border-radius: 999px;
	background: color-mix( in srgb, var( --brand-cta ) 10%, transparent );
	color: var( --brand-cta );
	text-decoration: none;
	transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
	vertical-align: middle;
}
.xb-collections__count-clear:hover,
.xb-collections__count-clear:focus {
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	transform: scale( 1.08 );
	outline: none;
}
.xb-collections__count-clear[hidden] { display: none; }
.xb-collections__count-clear svg { display: block; }

/* Sort inline (desktop) — bloque que aparece a la IZQUIERDA del
   toggle grid/lista en el heading row. En mobile (≤1023px) lo
   ocultamos y el orden vive en el drawer mobile. `margin-left: auto`
   empuja el bloque (y el view-toggle que va a su derecha) al extremo
   derecho del heading, manteniendo el contador a la izquierda. */
.xb-collections__sort-inline {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-left: auto;
}
.xb-collections__sort-inline-lbl {
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.2px;
	color: var( --xb-jacarta-500 );
	text-transform: uppercase;
}
.xb-collections__sort-inline .cjt-select--compact {
	min-width: 0;
}
.xb-collections__sort-inline .cjt-select--compact select {
	padding: 6px 28px 6px 12px;
	font-size: 13px;
	line-height: 1.2;
	height: 36px;
}@media ( max-width: 1024px ) {
	.xb-collections__sort-inline { display: none; }
}

/* Toggle grid/lista — pill horizontal con dos botones, copiado del
   `nav-tabs nav-link--style-5` de xhibiter. Activo = bg jacarta-50. */
.xb-collections__view-toggle {
	display: inline-flex;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	overflow: hidden;
	background: #ffffff;
}
.cjt-view-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 40px;
	background: transparent;
	color: var( --xb-jacarta-400 );
	border: 0;
	cursor: pointer;
	transition: color 0.18s ease, background 0.18s ease;
}
.cjt-view-toggle:hover { color: var( --xb-jacarta-700 ); }
.cjt-view-toggle.is-active {
	color: var( --xb-jacarta-700 );
	background: var( --xb-jacarta-50 );
}
.cjt-view-toggle:focus-visible {
	outline: 2px solid var( --brand-cta );
	outline-offset: -2px;
}
/* ===================================================================
 * List view — alterna el `.xb-collections__content` a una tabla con
 * columnas alineadas (réplica del `view-list` de xhibiter). El grid
 * principal pasa de tarjetas-cuadrícula a filas tipo tabla; cada
 * `.cjt-card` se reorganiza vía CSS Grid + `display:contents` en el
 * body para que los hijos floten directamente como columnas.
 *
 * Las columnas comparten `--cjt-list-grid` con la cabecera para que
 * todo quede alineado.
 * =================================================================== */
.xb-collections__list-header { display: none; }

/* List view — el card se convierte en una fila de tabla. La estructura:
 *   row    = flex( media | body )
 *   body   = grid de 6 columnas (title, participantes, precio,
 *            original, descuento, categoría)
 *   header = flex( ::before-spacer-igual-a-media | grid de 6 columnas
 *            con los mismos `--cjt-list-grid` que el body)
 *
 * `--cjt-list-grid` se define UNA vez en el contenedor list-view y la
 * usan tanto cabecera como cards → todo queda alineado pixel a pixel.
 */
.xb-collections__content.is-list-view {
	/* 5 columnas en list view (sin "Categoría" ya — el user lo pidió:
	   "remove the categoria column. The categories will be placed where
	   the extract text is now"):
	     thumb · título · precio_en_conjunta · precio_original · descuento
	   Categorías se reposicionan en row 2 col 2 (donde antes estaba el
	   excerpt) y el excerpt se elimina por completo. */
	--cjt-list-grid:
		var( --cjt-list-thumb )
		minmax( 0, 1fr )
		90px
		90px
		80px;
	--cjt-list-thumb: 56px;
	--cjt-list-gap: 12px;
	--cjt-list-pad-x: 16px;
}
/* Header span con max-width forzado → wrap en 2 líneas para títulos
   largos como "Precio en conjunta" / "Precio Original". Líneas cortas
   ("Descuento", "Categoría") quedan en una sola línea. line-height:
   1.2 mantiene la altura compacta. */
.xb-collections__content.is-list-view .xb-collections__list-col span {
	white-space: normal;
	line-height: 1.2;
	max-width: 80px;
	display: inline-block;
}
.xb-collections__content.is-list-view .xb-collections__grid {
	display: flex !important;
	flex-direction: column !important;
	gap: 0 !important;
	border: 1px solid var( --xb-jacarta-100 );
	border-top: 0;
	border-radius: 0 0 14px 14px;
	overflow: hidden;
	background: #ffffff;
}
/* List header — RESTAURADO. El user dejó claro: la table-grid de list view
   es non-negociable. La cabecera muestra los nombres de columna (Conjunta,
   Precio en conjunta, Precio original, Descuento, Categoría) y los sort
   buttons que permiten reordenar al hacer click. */
.xb-collections__content.is-list-view .xb-collections__list-header {
	display: grid;
	grid-template-columns: var( --cjt-list-grid );
	align-items: center;
	gap: 0 var( --cjt-list-gap );
	padding: 12px var( --cjt-list-pad-x );
	background: var( --xb-jacarta-50 );
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 14px 14px 0 0;
	border-bottom: 0;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 600 !important;
	color: var( --xb-jacarta-500 );
	letter-spacing: 0.3px;
	text-transform: uppercase;
}
.xb-collections__content.is-list-view .xb-collections__list-col--name {
	grid-column: 1 / 3;
}
.xb-collections__content.is-list-view .xb-collections__list-col {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: inherit;
}
/* Sort buttons (cabeceras numéricas). `font: inherit !important` para
   forzar a heredar la tipografía del header (CalSans display, 12px,
   600) — los `<button>` nativos vienen con `font: -webkit-small-control`
   por defecto y el `body button { font-family: inherit }` que WP a
   veces inyecta no lleva las otras props (size/weight). */
.xb-collections__content.is-list-view .xb-collections__list-col--sort {
	background: transparent;
	border: 0;
	padding: 0;
	font: inherit !important;
	color: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	cursor: pointer;
}
.xb-collections__content.is-list-view .xb-collections__list-col--sort:hover { color: var( --xb-jacarta-700 ); }
.xb-collections__content.is-list-view .xb-collections__sort-icon { flex: 0 0 12px; transition: opacity .15s, transform .15s; }
.xb-collections__content.is-list-view .xb-collections__list-col--sort[aria-sort] .xb-collections__sort-icon path { opacity: 1; }
.xb-collections__content.is-list-view .xb-collections__list-col--sort[aria-sort] { color: var( --brand-cta ); }
.xb-collections__content.is-list-view .xb-collections__list-col--sort[aria-sort="ascending"] .xb-collections__sort-icon { transform: rotate( 180deg ); }

/* Cards como filas — RESTAURADO al 6-col grid alineado con la cabecera
   pixel a pixel (vía `--cjt-list-grid`). El body usa `display: contents`
   para que sus hijos floten directamente como columnas del grid del card.
   AÑADIDO: 2 filas (row 1 = title/prices/etc, row 2 = excerpt span cols
   2..end). Así title arriba + excerpt debajo dentro de la columna del
   título, SIN sacrificar el resto de columnas (precios, descuento, cat). */
.xb-collections__content.is-list-view .cjt-card {
	display: grid;
	grid-template-columns: var( --cjt-list-grid );
	grid-template-rows: auto auto;
	align-items: center;
	gap: 4px var( --cjt-list-gap );
	padding: 14px var( --cjt-list-pad-x );
	margin: 0;
	border: 0;
	border-top: 1px solid var( --xb-jacarta-100 );
	border-radius: 0;
	background: #ffffff;
	transition: background 0.15s ease;
}

/* Clase usada por `cursos-filter.js` para ocultar cards filtradas.
   `!important` necesario porque las reglas de list-view (encima) y
   las de grid-view (abajo) escupen `display: grid` con suficiente
   especificidad para empatar/superar `style="display: none"` inline
   en algunos contextos mobile (regression observable: contador
   actualizaba bien pero cards no se ocultaban). Una clase con
   !important es la única fuente de verdad. */
.cjt-card.cjt-hidden { display: none !important; }
.xb-collections__content.is-list-view .cjt-card:first-child { border-top: 0; }
.xb-collections__content.is-list-view .cjt-card:hover {
	background: var( --xb-jacarta-50 );
	box-shadow: none;
	transform: none;
}
.xb-collections__content.is-list-view .cjt-card__media {
	grid-column: 1;
	grid-row: 1 / span 2; /* media spans both rows so title+excerpt sit beside */
	width: var( --cjt-list-thumb );
	height: var( --cjt-list-thumb );
	aspect-ratio: 1 / 1;
	border-radius: 8px;
	margin: 0;
	align-self: center;
	overflow: visible;
	position: relative;
}
.xb-collections__content.is-list-view .cjt-card__media .cjt-card__img,
.xb-collections__content.is-list-view .cjt-card__placeholder { border-radius: 8px; }

/* Badges sobre el thumbnail (count + check) — sólo en list view.
   En grid view están ocultos. */
.cjt-card__badge { display: none; }
.xb-collections__content.is-list-view .cjt-card__badge {
	display: inline-flex;
	position: absolute;
	left: -10px;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 999px;
	border: 2px solid #ffffff;
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
	box-sizing: border-box;
	pointer-events: none; /* el click pasa a la imagen / link */
}
/* Pattern xhibiter (Top Collectors): número CENTRADO vertical (top:50%),
   check JUSTO DEBAJO (top:60%). El check renderiza POR ENCIMA del número
   (z-index superior) — donde se solapan, el verde tapa el círculo del
   número, igual que en `dist/index.html`. */
.xb-collections__content.is-list-view .cjt-card__badge--count {
	top: 50%;
	transform: translateY( -50% );
	background: var( --xb-jacarta-700 );
	color: #ffffff;
	z-index: 1;
}
.xb-collections__content.is-list-view .cjt-card__badge--check {
	top: 60%;
	background: #10b981;
	color: #ffffff;
	z-index: 2;
	/* Re-habilitamos pointer-events para que el tooltip nativo del
	   `title=""` se dispare al pasar el cursor por encima. El cursor
	   se hereda del `<a>` padre (pointer) — igual que en xhibiter, no
	   cambiamos el cursor por estar sobre el badge. */
	pointer-events: auto;
}
/* Lock badge — para conjuntas en estado `cerrada`. Misma posición que
   el check (debajo del número, tapándolo donde se solapan), pero en gris
   pizarra para señalar "completada / cerrada / no se admiten apuntes". */
.xb-collections__content.is-list-view .cjt-card__badge--lock {
	top: 60%;
	background: #6b7280;
	color: #ffffff;
	z-index: 2;
	pointer-events: auto;
}
/* Proposed badge — para conjuntas en estado `propuesta`. Azul para
   distinguirlo del verde (abierta) y del gris (cerrada). El icono lo
   elige el admin desde Conjuntas → Ajustes → Contenido. */
.xb-collections__content.is-list-view .cjt-card__badge--proposed {
	top: 60%;
	background: #4F8CFF;
	color: #ffffff;
	z-index: 2;
	pointer-events: auto;
}/* `.cjt-card__excerpt` — extracto SÓLO en list view. El user pidió que
   sea un texto que "se extienda hasta donde quepa, sin empujar otros
   elementos". Single-line con `text-overflow: ellipsis` dentro de la
   col 2 (la del título) — el excerpt acompaña al título debajo, ocupando
   sólo el ancho de SU columna, NO spanning. Las demás columnas
   (precios, descuento, categoría) quedan alineadas con la cabecera
   pixel a pixel SIN ser empujadas por el excerpt. */
/* Excerpt OCULTO en list view (y en grid view por el rule global de
   `.cjt-card__excerpt { display: none }`). El user pidió en docx
   2026-05-09: "remove the categoria column. The categories will be
   placed where the extract text is now (so the extract text will be
   removed instead)". */
.cjt-card__excerpt { display: none; }
.xb-collections__content.is-list-view .cjt-card__excerpt {
	display: none !important;
}

/* Body con `display: contents` para que title/prices/category/excerpt
   floten como columnas del grid del card. RESTAURA el patrón antiguo. */
.xb-collections__content.is-list-view .cjt-card__body { display: contents; }
.xb-collections__content.is-list-view .cjt-card__prices { display: contents; }
.xb-collections__content.is-list-view .cjt-card__price-sep,
.xb-collections__content.is-list-view .cjt-card__price-original-label,
.xb-collections__content.is-list-view .cjt-card__participants-label { display: none; }
.xb-collections__content.is-list-view .cjt-card__expand { display: none; }
.xb-collections__content.is-list-view .cjt-card__participants { display: none; }

/* Asignación explícita de columnas en el grid del card (6 columnas):
   1 thumbnail · 2 título · 3 precio en conjunta · 4 original · 5 descuento · 6 categoría
   Todas las metas viven en row 1; sólo el excerpt en row 2. */
.xb-collections__content.is-list-view .cjt-card__title {
	grid-column: 2;
	grid-row: 1;
	margin: 0;
	min-width: 0;
	font-size: 15px;
	font-family: var( --xb-font-display );
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
.xb-collections__content.is-list-view .cjt-card__title-link,
.xb-collections__content.is-list-view .cjt-card__title-text {
	display: inline-block;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	vertical-align: bottom;
}
.xb-collections__content.is-list-view .cjt-card__price-main {
	grid-column: 3;
	grid-row: 1;
	font-size: 15px;
}
.xb-collections__content.is-list-view .cjt-card__price-original {
	grid-column: 4;
	grid-row: 1;
	font-size: 13px;
}
.xb-collections__content.is-list-view .cjt-card__discount {
	grid-column: 5;
	grid-row: 1;
	justify-self: start;
}
/* CATEGORÍAS se renderizan AHORA en row 2 col 2 (donde antes vivía el
   excerpt). El user lo pidió 2026-05-09: "remove the categoria column.
   The categories will be placed where the extract text is now". Multi-
   cats se apilan horizontalmente (flex row + wrap). */
.xb-collections__content.is-list-view .cjt-card__cats {
	grid-column: 2;
	grid-row: 2;
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 8px;
	margin: 2px 0 0;
	justify-self: start;
	align-self: start;
	min-width: 0;
	max-width: 100%;
}
/* En list view la categoría se renderiza como un chip con icono
   (`.cjt-card__category-icon`) + label en CTA color (clickable signal),
   mismo aspecto que los filtros del sidebar. El icon span sólo se
   muestra en list view; en grid view se oculta para mantener el
   chip compacto-uppercase original. */
.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category {
	display: inline-flex !important;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 3px 9px 3px 3px;
	background: transparent;
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.4px;
	color: var( --brand-cta );
	cursor: pointer;
	transition: color 0.15s ease, background 0.15s ease;
}
/* El label es un <span> y la regla global de MP-chrome
   (`body.mepr-mod-chrome span { font-size: var(--brand-body-size) !important }`)
   lo agranda a 16px también en desktop. Fijamos el tamaño aquí con
   `!important` para que el chip se vea pequeño en escritorio igual que
   en mobile. Aplica en `/lista/` y en las cards de "mis-conjuntas"
   (la regla no está scopeada a `mepr-mod-mis-conjuntas`). */
.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category-label {
	font-size: 12px !important;
	line-height: 1.3;
}
.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category:hover,
.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category:focus {
	color: var( --brand-cta-hover );
	background: color-mix( in srgb, var( --brand-cta ) 8%, transparent );
	outline: none;
}
.xb-collections__content.is-list-view .cjt-card__category-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border-radius: 999px;
	flex: 0 0 auto;
}

/* En grid view también mostramos el icon del chip (icono+label en una
   misma píldora pequeña). El user lo pidió: "On the card view/grid, I
   want the category to also show the icon same as with list view". */
.xb-collections__content:not( .is-list-view ) .cjt-card__category-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	flex: 0 0 auto;
}
/* Chip de categoría en grid view — añadimos flex + padding 4px alrededor
   del icono para que el icon+label queden alineados como una sola píldora
   compacta uppercase (en list view ya están con su propio set de reglas). */
.xb-collections__content:not( .is-list-view ) .cjt-card__cats .cjt-card__category {
	display: inline-flex !important;
	align-items: center;
	gap: 5px;
	padding: 3px 9px 3px 3px;
	background: transparent;
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.4px;
	color: var( --brand-cta );
	text-transform: uppercase;
	cursor: pointer;
	transition: color 0.15s ease, background 0.15s ease;
}
.xb-collections__content:not( .is-list-view ) .cjt-card__cats .cjt-card__category:hover,
.xb-collections__content:not( .is-list-view ) .cjt-card__cats .cjt-card__category:focus {
	color: var( --brand-cta-hover );
	background: color-mix( in srgb, var( --brand-cta ) 8%, transparent );
	outline: none;
}

/* En responsive (≤1024px) list view — VERSIÓN PRAISED (verbatim Pattern 2
   del skill `wp-responsive-fixes`) como baseline, MÁS layer mínimo de
   price + cats. El user lo pidió: "back to the original when it was
   working and work from there to include the elements im asking".
   Estructura: [thumb 80×80] [body flex-column con título + 3 líneas
   info: Precio en conjunta / Precio original / cats].
   BREAKPOINT 1024px (no 768px) porque a tablet portrait el sidebar ya
   está colapsado pero el desktop list view (grid 6-col) deja las cards
   cortadas en columna estrecha — el user reportó "is the opposite of
   responsive". A ≤1024px apply el patrón de fila simple. */
@media ( max-width: 1024px ) {
	.xb-collections__content.is-list-view .xb-collections__list-header { display: none; }

	.xb-collections__content.is-list-view .xb-collections__grid {
		display: flex !important;
		flex-direction: column !important;
		gap: 0 !important;
		border: 0 !important;
		border-radius: 0 !important;
		padding: 0 !important;
		background: transparent !important;
		box-shadow: none !important;
		overflow: visible !important;
	}

	/* Card layout responsive: GRID 3 columnas × 2 filas:
	     col 1 = thumb (56px, span 2 rows — MISMO tamaño que desktop)
	     col 2 = title (row 1) + prices (row 2) — toma el espacio sobrante
	     col 3 = cats (FIXED 130px, span 2 rows, pinned RIGHT extreme)
	   Body usa `display: contents`. Col 3 fija (no `auto`) garantiza que
	   el chip "DINERO" o etiquetas similares quepan sin que el texto se
	   recorte por overflow del viewport.
	   Thumb 56px (igual que desktop) — el user lo pidió: "On desktop list
	   view image is one size, but you make that image bigger in responsive
	   on list view, don't do it". */
	.xb-collections__content.is-list-view .cjt-card {
		display: grid !important;
		/* Col 3 ensanchada a 180px porque ahora aloja los precios
		   (label "Precio en conjunta:" + valor + descuento) — antes
		   sólo tenía cats (130px era suficiente). */
		grid-template-columns: 56px minmax( 0, 1fr ) 180px !important;
		grid-template-rows: auto auto !important;
		column-gap: 12px;
		row-gap: 2px;
		align-items: start;
		padding: 12px 16px 12px 12px !important;
		margin: 0 !important;
		border: 0 !important;
		border-radius: 0 !important;
		background: #ffffff !important;
		box-shadow: 0 1px 0 0 var( --xb-jacarta-100 ) !important;
		transform: none !important;
		position: relative !important;
		overflow: visible !important;
	}
	.xb-collections__content.is-list-view .cjt-card:last-child { box-shadow: none !important; }

	.xb-collections__content.is-list-view .cjt-card__media {
		grid-column: 1 !important;
		grid-row: 1 / span 2 !important;
		flex: none;
		width: 56px;
		height: 56px;
		border-radius: 8px;
		margin: 0;
		align-self: start;
	}

	/* Body aplanado: sus hijos toman su propia grid-area. */
	.xb-collections__content.is-list-view .cjt-card__body {
		display: contents !important;
	}

	.xb-collections__content.is-list-view .cjt-card__title {
		grid-column: 2 !important;
		grid-row: 1 !important;
		font-family: var( --xb-font-display );
		font-size: 14px !important;
		font-weight: 600 !important;
		line-height: 1.25 !important;
		margin: 0 !important;
		min-width: 0;
		align-self: end;
	}
	.xb-collections__content.is-list-view .cjt-card__title-link,
	.xb-collections__content.is-list-view .cjt-card__title-text {
		display: block;
		max-width: 100%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.xb-collections__content.is-list-view .cjt-card__excerpt {
		display: none !important;
	}

	/* === Iteración 2026-05-09 (final): SWAP cats ↔ prices.
	   - cats AHORA en col 2 row 2 (debajo del título)
	   - prices AHORA en col 3 (extremo derecho, span 2 rows)
	   El user lo pidió textual: "in responsive, where the categories
	   are now, instead, there you will put: precio en conjunta: X€ con
	   font slightly bigger en heredado green, precio original crossed
	   y descuento. So make it trade places". */
	/* Layout 2 filas via flex-wrap:
	     fila 1: "Precio en conjunta: 17,25€"      (price-main flex-basis 100%)
	     fila 2: "Precio original: 69€ -75%"        (original + discount inline)
	   El user lo pidió: "the discount number % should be on the right side
	   of the crossed off discounted price". */
	.xb-collections__content.is-list-view .cjt-card__prices {
		grid-column: 3 !important;
		grid-row: 1 / span 2 !important;
		display: flex !important;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: baseline;
		justify-content: flex-end;
		column-gap: 6px;
		row-gap: 2px;
		justify-self: stretch !important;
		align-self: center !important;
		margin: 0 !important;
		font-family: var( --xb-font-body );
		font-size: 13px;
		line-height: 1.3;
		text-align: right;
	}
	/* "Precio en conjunta: 40€" — verde heredado, ocupa toda la fila 1. */
	.xb-collections__content.is-list-view .cjt-card__price-main {
		order: 1;
		flex: 0 0 100% !important;
		display: block !important;
		font-size: 14px !important;
		font-weight: 700;
		color: #10b981 !important;
		grid-column: auto; grid-row: auto;
		text-align: right;
	}
	.xb-collections__content.is-list-view .cjt-card__price-main::before {
		content: 'Precio en conjunta: ';
		font-weight: 500;
		color: var( --xb-jacarta-500 );
	}
	/* "Precio original: 69€" + "-75%" inline en la fila 2. */
	.xb-collections__content.is-list-view .cjt-card__price-original {
		order: 2;
		display: inline-flex !important;
		align-items: baseline;
		font-size: 11px !important;
		color: var( --xb-jacarta-500 );
		grid-column: auto; grid-row: auto;
	}
	.xb-collections__content.is-list-view .cjt-card__price-original::before {
		content: 'Precio original: ';
		font-weight: 500;
		color: var( --xb-jacarta-500 );
		margin-right: 4px;
	}
	.xb-collections__content.is-list-view .cjt-card__price-strike {
		text-decoration: line-through;
		color: var( --xb-jacarta-400 );
	}
	.xb-collections__content.is-list-view .cjt-card__price-original-label,
	.xb-collections__content.is-list-view .cjt-card__price-sep { display: none !important; }
	.xb-collections__content.is-list-view .cjt-card__discount {
		order: 3;
		display: inline-block !important;
		font-size: 10px !important;
		font-weight: 700;
		color: var( --brand-cta-text );
		background: var( --brand-cta );
		padding: 1px 6px;
		border-radius: 999px;
		margin: 0 !important;
		grid-column: auto; grid-row: auto;
		justify-self: auto;
		align-self: center;
		line-height: 1.4;
	}

	/* CATS bajo el título — col 2 row 2 (donde ANTES estaban los precios
	   en responsive). El user pidió swap: precios ahora a la derecha (col
	   3), cats bajo el título (col 2 row 2). */
	.xb-collections__content.is-list-view .cjt-card__cats {
		grid-column: 2 !important;
		grid-row: 2 !important;
		justify-self: start !important;
		align-self: start !important;
		display: flex !important;
		flex-direction: row !important;
		flex-wrap: wrap;
		align-items: center !important;
		gap: 4px 8px;
		margin: 4px 0 0 !important;
		min-width: 0;
		max-width: 100%;
	}
	.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category-label {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		max-width: 90px;
	}
	.xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category {
		display: inline-flex !important;
		align-items: center;
		gap: 4px;
		padding: 1px 8px 1px 1px;
		font-size: 10px !important;
		font-weight: 700;
		letter-spacing: 0.4px;
		color: var( --brand-cta );
		background: transparent;
		border: 0;
		border-radius: 999px;
	}
	.xb-collections__content.is-list-view .cjt-card__category-icon {
		width: 16px !important;
		height: 16px !important;
	}

	.xb-collections__content.is-list-view .cjt-card__participants,
	.xb-collections__content.is-list-view .cjt-card__participants-label,
	.xb-collections__content.is-list-view .cjt-card__expand {
		display: none !important;
	}

	/* Chevron oculto en este layout responsive — las cats ya marcan el
	   extremo derecho de cada row, no hace falta un segundo indicador.
	   Si en el futuro queremos restaurarlo, hay que mover cats a col 3
	   y añadir col 4 = chevron en el grid-template-columns. */
	.xb-collections__content.is-list-view .cjt-card::after {
		content: none !important;
		display: none !important;
	}

	.xb-collections__content.is-list-view .cjt-card__badge {
		width: 22px; height: 22px;
		border-width: 2px;
		font-size: 11px;
		left: -10px;
	}
	.xb-collections__content.is-list-view .cjt-card__badge svg {
		width: 12px; height: 12px;
	}
}

/* =====================================================================
   Mis Conjuntas — list view mobile reorg.
   El user lo pidió (2026-05-20):
     - El TÍTULO va arriba del todo, a TODO el ancho de la card (fila 1).
     - Debajo: la imagen (izquierda) + categorías/precios (centro) +
       las acciones (derecha) — todo en la fila 2.
     - Sin márgenes laterales en mobile para el listado: cards edge-to-edge.

   Sólo aplica a /cuenta/?action=mis-conjuntas. El listado público
   (/lista/) conserva la disposición que ya tenía.
   ===================================================================== */
@media ( max-width: 768px ) {
	/* Grid 3 columnas × 3 filas:
	     fila 1 = título full-width (span de las 3 columnas)
	     fila 2 = thumb (col1) | categorías (col2) | acciones (col3)
	     fila 3 = thumb-span | precios   (col2) | acciones-span
	   El thumb y las acciones hacen `grid-row: 2 / span 2` para abarcar
	   las filas de cats + precios. Cats y precios van en FILAS DISTINTAS
	   (2 y 3) para que se apilen de verdad — antes compartían celda y se
	   superponían. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card {
		grid-template-columns: 56px minmax( 0, 1fr ) minmax( 110px, max-content ) !important;
		grid-template-rows: auto auto auto !important;
		column-gap: 10px !important;
		row-gap: 6px !important;
		align-items: start !important;
	}
	/* TÍTULO — fila 1, ocupa el ancho completo (las 3 columnas). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__title {
		grid-column: 1 / -1 !important;
		grid-row: 1 !important;
		align-self: start !important;
	}
	/* IMAGEN — columna 1, abarca las filas 2-3 (cats + precios). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__media {
		grid-column: 1 !important;
		grid-row: 2 / span 2 !important;
		align-self: start !important;
	}
	/* CATEGORÍAS — fila 2, columna 2 (encima de los precios). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats {
		grid-column: 2 !important;
		grid-row: 2 !important;
		align-self: start !important;
		margin: 0 !important;
	}
	/* PRECIOS — fila 3, columna 2 (debajo de las cats, fila propia). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__prices {
		grid-column: 2 !important;
		grid-row: 3 !important;
		justify-content: flex-start !important;
		justify-self: start !important;
		align-self: start !important;
		text-align: left !important;
		margin: 0 !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-main,
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__price-original {
		text-align: left !important;
	}
	/* ACTIONS — columna 3, abarca las filas 2-3, apiladas verticalmente. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions {
		grid-column: 3 !important;
		grid-row: 2 / span 2 !important;
		display: flex !important;
		flex-direction: column !important;
		flex-wrap: nowrap !important;
		align-items: stretch !important;
		align-self: start !important;
		justify-content: flex-start !important;
		gap: 6px !important;
		margin: 0 !important;
		min-width: 0;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__actions > * {
		min-width: 0 !important;
		max-width: 100% !important;
		text-align: center !important;
	}
	/* Pills de categoría más pequeñas en mobile — el user reportó que
	   "🏠 INMOBILIARIA" se cortaba. Reducimos font-size, padding e icono
	   y subimos el max-width del label para que el texto quepa entero.
	   IMPORTANTE: el `font-size` se fija TAMBIÉN en el `.cjt-card__category-label`
	   con `!important` porque la regla global de MP-chrome
	   (`body.mepr-mod-chrome span { font-size: var(--brand-body-size) !important }`)
	   matchea el <span> del label directamente y, sin esto, lo agranda a 16px
	   (el bug observado: la etiqueta de categoría salía gigante en mobile). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category {
		font-size: 10px !important;
		letter-spacing: 0.2px !important;
		gap: 3px !important;
		padding: 1px 6px 1px 1px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__cats .cjt-card__category-label {
		font-size: 10px !important;
		line-height: 1.3 !important;
		max-width: 140px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__category-icon {
		width: 14px !important;
		height: 14px !important;
	}
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__category-icon svg {
		width: 9px !important;
		height: 9px !important;
	}
	/* Título a 2 líneas como mucho — full-width ya da espacio, pero
	   evitamos que un título larguísimo empuje la fila. El truncado por
	   `white-space:nowrap` heredado se relaja: permitimos wrap y cortamos
	   con line-clamp para que el título se lea pero no desborde. */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__title-link,
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card__title-text {
		display: -webkit-box !important;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		white-space: normal !important;
		overflow: hidden;
	}
	/* Edge-to-edge: en mobile el contenido de la pestaña "Mis conjuntas"
	   ocupa todo el ancho. El shell envuelve el contenido en dos capas
	   con padding lateral (`.mepr-mod-shell__main` y `.mepr-mod-shell__inner`);
	   ahí se anulan los dos paddings y se reparte un único padding simétrico
	   de 16px sólo en la cabecera (título + acciones), dejando el listado
	   de cards a sangre (0 lateral). El padding interno de cada card sigue
	   dando aire al texto.

	   Histórico: antes se hacía con `margin: -16px` negativo en el wrapper,
	   pero ese hack sólo desplazaba el borde izquierdo — el ancho fijo del
	   grid no crecía hacia la derecha, dejando un hueco asimétrico de ~48px
	   en el lado derecho. */
	body.mepr-mod-mis-conjuntas .mepr-mod-shell__main,
	body.mepr-mod-mis-conjuntas .mepr-mod-shell__inner {
		padding-left: 0 !important;
		padding-right: 0 !important;
	}
	body.mepr-mod-mis-conjuntas .mod-mepr-mis-conjuntas__title,
	body.mepr-mod-mis-conjuntas .mod-mepr-mis-conjuntas__flash,
	body.mepr-mod-mis-conjuntas .mod-mepr-mis-conjuntas__actions,
	body.mepr-mod-mis-conjuntas .mod-mepr-toolbar,
	body.mepr-mod-mis-conjuntas .xb-collections__count,
	body.mepr-mod-mis-conjuntas .cjt-empty {
		padding-left: 16px;
		padding-right: 16px;
	}
	/* El drawer de filtros es una "card" propia (fondo blanco + borde +
	   esquinas redondeadas): necesita margen lateral, no padding extra,
	   para no pegarse a los bordes del viewport. */
	body.mepr-mod-mis-conjuntas .mod-mepr-filters-drawer {
		margin-left: 16px;
		margin-right: 16px;
		width: auto;
	}
	/* El grid de cards va a sangre completa (sin padding lateral). */
	body.mepr-mod-mis-conjuntas .xb-collections__content.is-list-view .cjt-card {
		border-radius: 0 !important;
	}
}.xb-collections__layout {
	display: flex;
	gap: 48px;
	align-items: flex-start;
}
.xb-collections__sidebar {
	flex: 0 0 260px;
	/* Sidebar completamente expandido (sin `max-height` ni `overflow`)
	   pero sticky cuando el usuario hace scroll: se queda pegado a 110px
	   del top del viewport (78 navbar + 32 colchón). Si el contenido es
	   más alto que el viewport, la parte inferior queda fuera de pantalla
	   mientras está sticky — se ve normal según el usuario scrollea la
	   página y el contenedor padre desplaza el sidebar también. */
	position: sticky;
	top: 110px;
	align-self: flex-start;
	padding-right: 12px;
	display: flex;
	flex-direction: column;
	gap: 14px;
}
.xb-collections__filter {
	border-bottom: 1px solid var( --xb-jacarta-100 );
	padding: 12px 0 18px;
}
.xb-collections__filter:last-child { border-bottom: 0; }
.xb-collections__filter-title {
	margin: 0 0 12px;
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
.xb-collections__pills {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.xb-collections__content { flex: 1 1 auto; min-width: 0; }
.xb-collections__toolbar {
	display: flex;
	justify-content: flex-end;
	margin-bottom: 16px;
}
.xb-collections__filters-toggle {
	display: none;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	cursor: pointer;
}

/* Mobile (≤1024px) — el heading y el toolbar quedaban en filas
   distintas con el botón "Filtros" suelto debajo. Lo consolidamos:
   el botón Filtros se mete VISUALMENTE en la misma franja que el
   contador, y el toggle grid/lista pasa a la derecha del Filtros.
   El toolbar mantiene el `data-toggle` original (no rompe el JS),
   pero usa `position: absolute` para alinearse al heading. */
@media ( max-width: 1024px ) {
	/* Permitimos wrap por si el contador crece (ej. con todos los filtros
	   activos: "X conjuntas abiertas sobre dinero en inglés (limpiar filtros)").
	   Si no cabe en una línea, el toggle baja a una segunda fila por debajo,
	   pero el texto del contador NO se trunca. */
	.xb-collections__heading {
		flex-wrap: wrap;
		gap: 8px 12px;
		align-items: center;
		margin-bottom: 14px;
	}
	.xb-collections__count {
		min-width: 0;
		flex: 1 1 auto;
		line-height: 1.4;
	}
	.xb-collections__view-toggle {
		flex: 0 0 auto;
		margin-left: auto;
	}
	.xb-collections__toolbar {
		justify-content: flex-start;
		margin-top: -4px;
		margin-bottom: 18px;
	}
}
/* En mobile (≤768px) reordenamos:
     fila 1: [Filtros]                      [grid/list toggle]
     fila 2: X conjuntas abiertas sobre Y …
     fila 3: (header de columnas, oculto fuera de list view)
     fila 4: grid de cards
     fila 5: descripción de categoría
   `display: contents` en `.xb-collections__heading` aplana sus hijos
   (count + view-toggle) como grid items directos del content, así
   pueden colocarse en filas distintas via grid-area sin tocar el HTML. */
@media ( max-width: 1024px ) {
	.xb-collections__content {
		display: grid;
		grid-template-columns: auto minmax( 0, 1fr ) auto;
		/* Fila explícita "drawer" entre toolbar y header. Recibe el
		   sidebar de filtros cuando el JS lo mueve dentro de content
		   en mobile (ver template-cursos.php). Cuando el drawer está
		   cerrado (`display: none` por CSS) la fila colapsa a 0px. */
		grid-template-areas:
			"toolbar count   toggle"
			"drawer  drawer  drawer"
			"header  header  header"
			"grid    grid    grid"
			"desc    desc    desc";
		gap: 12px 12px;
		align-items: center;
	}
	.xb-collections__heading {
		display: contents; /* sus hijos pasan a ser grid items del content */
		margin: 0;
	}
	/* Count vive ENTRE el botón Filtros (izquierda) y el view-toggle
	   (derecha) en una sola fila. El user lo pidió: "Between filtros
	   and the view list/grid you should include the same text and
	   effect as X conjuntas (x) for cleaning filters". */
	.xb-collections__count {
		grid-area: count;
		margin: 0;
		flex: initial;
		text-align: center;
		justify-self: start;
		align-self: center;
		padding: 0 12px;
		min-width: 0;
		font-size: 13px;
	}
	.xb-collections__view-toggle {
		grid-area: toggle;
		justify-self: end;
		margin-left: 0;
	}
	.xb-collections__toolbar {
		grid-area: toolbar;
		margin: 0;
		justify-content: flex-start;
	}
	.xb-collections__list-header { grid-area: header; }
	.xb-collections__grid       { grid-area: grid; }
	.xb-collections__cat-description { grid-area: desc; }
	/* Cuando el JS mueve el sidebar dentro de `.xb-collections__content`,
	   lo colocamos en la fila explícita "drawer" (entre toolbar y
	   header) — sin esto, auto-placement lo mete en una fila implícita
	   al final del content (debajo del grid) y los pills quedan fuera
	   del fold visible. */
	.xb-collections__content > .xb-collections__sidebar {
		grid-area: drawer;
		width: 100%;
	}
	/* Mismo problema con el drawer custom de mis-conjuntas
	   (`.mod-mepr-filters-drawer`): sin grid-area asignada, el auto-
	   placement lo metía en la columna 3 (la del view-toggle) y se
	   pintaba como una banda estrecha a la derecha empujando las cards
	   hacia abajo. Lo anclamos a la fila completa `drawer`, igual que el
	   sidebar legacy. */
	.xb-collections__content > .mod-mepr-filters-drawer {
		grid-area: drawer;
		width: 100%;
		justify-self: stretch;
	}
}
.xb-collections__grid {
	display: grid;
	/* Desktop fija a 4 columnas (pedido del usuario). Por debajo de
	   1024px bajamos a 3, a 768px a 2, y en phones a 1. Así la card
	   nunca queda excesivamente estrecha. */
	grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	gap: 24px;
}
@media ( max-width: 1024px ) {
	.xb-collections__grid { grid-template-columns: repeat( 3, minmax( 0, 1fr ) ); }
}
@media ( max-width: 768px ) {
	/* CRÍTICO: Estas reglas de grid SÓLO aplican cuando NO es list view.
	   Sin el `:not(.is-list-view)`, el `gap: 16px` se aplicaba al
	   contenedor en list view también — y como en list view ese
	   contenedor es un flex column, el gap inyectaba 16px de espacio
	   vertical entre filas, haciendo que cada fila pareciera una card
	   separada en lugar de una lista continua. */
	.xb-collections__content:not( .is-list-view ) .xb-collections__grid {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
		gap: 16px;
	}
	/* Mobile grid view — cards compactas:
	   - padding reducido (10px) para no comerse el espacio interno
	   - imagen más corta (aspect 4/3 en vez de 1/1) para que la card
	     no sea altísima — antes la square image hacía que cada card fuera
	     ~430px de alto en 2-column mobile grid
	   - "Participantes:" prefix y "del precio original" labels OCULTOS
	     (se mostraban en una línea aparte llenando la card de chrome
	     innecesario, igual que en list view)
	   - separador `|` entre precios oculto (eran 3 cosas: 199€ | 199€,
	     queda mucho más limpio sin la pleca) */
	.xb-collections__content:not( .is-list-view ) .cjt-card { padding: 10px; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__media { aspect-ratio: 4 / 3; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__body { margin-top: 8px; gap: 3px; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__title { font-size: 13px; line-height: 1.25; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__category { font-size: 10px; letter-spacing: 0.4px; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__participants { font-size: 11px; margin: 0; }
	/* Mostrar "Participantes:" antes del número en grid view mobile.
	   El user lo pidió: "on the card view in responsive you should show
	   Participantes before the number of members being part of that
	   conjunta". */
	.xb-collections__content:not( .is-list-view ) .cjt-card__participants-label {
		display: inline;
		margin-right: 3px;
		color: var( --xb-jacarta-500 );
		font-weight: 500;
	}
	.xb-collections__content:not( .is-list-view ) .cjt-card__price-main { font-size: 13px; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__price-original { font-size: 11px; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__price-original-label { display: none; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__price-sep { display: none; }
	.xb-collections__content:not( .is-list-view ) .cjt-card__discount { font-size: 9px; padding: 1px 5px; }
}
/* En phones MUY estrechos (≤360px) caemos a 1 columna; en el resto del
   rango mobile el grid se queda en 2 columnas para que las cards no
   ocupen toda la pantalla y se vean varias a la vez. */
@media ( max-width: 360px ) {
	.xb-collections__content:not( .is-list-view ) .xb-collections__grid { grid-template-columns: 1fr; }
}

/* ----- Filter primitives (cjt-*) basic styling so the controls in the
        sidebar are usable under any theme. The cursos-filter.js reads the
        SAME data-attrs, so behavior is unchanged. ----- */
.cjt-search { width: 100%; }
.cjt-search__field { position: relative; }
.cjt-search__input {
	width: 100%;
	padding: 11px 16px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	outline: none;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.cjt-search__input:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
}
.cjt-search__spinner { display: none; } /* placeholder; el filtro client-side no carga nada async */

/* `.cjt-pill` se renderiza en /lista/ Y en /cuenta/?action=mis-conjuntas
   (mismo markup). Marcamos la tipografía con `!important` para vencer
   cualquier rule `body button { font-family: inherit }` que MemberPress
   o WP core puedan inyectar bajo `body.mepr-mod-account` — sin esto el
   user reportó que los pills en mis-conjuntas se veían "con tipo body
   normal" en lugar de coincidir con /lista/. */
.cjt-pill {
	display: inline-flex;
	align-items: center;
	padding: 7px 14px;
	font-family: var( --xb-font-display ) !important;
	font-size: 13px !important;
	font-weight: 600 !important;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.cjt-pill:hover, .cjt-pill:focus { border-color: var( --brand-cta ); color: var( --brand-cta ); outline: none; }
.cjt-pill.is-active {
	background: var( --brand-cta );
	border-color: var( --brand-cta );
	color: var( --brand-cta-text );
}

/* Pills con icono — patrón tomado de los filtros de
   `xhibiter/HTML/dist/activity.html` (Listings · Bids · Transfer …):
   svg de 14px a la izquierda, gap pequeño, label a la derecha. El color
   del icono se fija por estado vía `--cjt-pill-icon-color` y el SVG usa
   `currentColor`. Cuando el pill está activo (fondo brand-cta), forzamos
   el icono a `currentColor` (= brand-cta-text) para que contraste igual
   que el texto. */
.cjt-pill--with-icon { gap: 6px; }
.cjt-pill__icon { flex: 0 0 14px; }
.cjt-pill__icon--check { color: #10b981; }
.cjt-pill__icon--bulb  { color: #FEB240; }
.cjt-pill__icon--lock  { color: #6b7280; }
.cjt-pill.is-active .cjt-pill__icon { color: currentColor; }

.cjt-select { display: block; margin-bottom: 10px; }
/* Fila con los dos selects de "Ordenar por" + dirección colocados lado
   a lado. Flex + `width: auto` en cada select para que cada uno ocupe
   SÓLO el ancho que necesita su contenido (la opción más larga + el
   padding del chevron), no la mitad fija de la columna. Si la suma de
   ambos no cabe, `flex-wrap` los baja al segundo renglón. */
.cjt-sort-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: stretch;
}
.cjt-sort-row .cjt-select {
	margin-bottom: 0;
	flex: 0 0 auto;
}
.cjt-sort-row .cjt-select select {
	width: auto;
}
.cjt-select select {
	width: 100%;
	padding: 11px 14px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	background-image: url( "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%237D7F96'><path d='M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z'/></svg>" );
	background-repeat: no-repeat;
	background-position: right 10px center;
	background-size: 18px;
	padding-right: 36px;
}

/* ===================================================================
 * Cards de conjunta (`.cjt-card`) — adoptan el mismo "rounded-2.5xl
 * border + p-[1.1875rem] + hover-shadow" del article xhibiter. La
 * markup interna del partial `partials/card-conjunta.php` queda igual,
 * sólo cambian los estilos.
 * =================================================================== */
.cjt-grid { } /* el wrapper define grid en .xb-collections__grid */
.cjt-card {
	position: relative; /* anchor for `.cjt-card__stretch` overlay */
	display: flex;
	flex-direction: column;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 1.25rem; /* 2.5xl */
	padding: 1.1875rem;
	transition: box-shadow 0.25s ease, transform 0.25s ease;
	cursor: pointer;
}
.cjt-card:hover {
	box-shadow: 0 8px 24px -10px rgba( 13, 16, 45, 0.18 );
	transform: translateY( -2px );
}
/* Stretched link — clic en cualquier zona de la card va al single del CPT.
   Las chips de categoría, los botones de acciones (Panel de voluntario,
   Desapuntarme), y el botón "expandir" se elevan vía z-index para
   permanecer interactivos por encima del overlay. */
.cjt-card__stretch {
	position: absolute;
	inset: 0;
	z-index: 1;
	border-radius: inherit;
	background: transparent;
	text-decoration: none;
	pointer-events: auto;
}
/* Cuando el cursor está sobre cualquier elemento interactivo de la
   tarjeta (botones de acción, link del título, badges activos, etc.),
   apagamos el stretched-link entero para que NO se trague el click.
   Esto resuelve los casos en los que un `z-index` mayor en el elemento
   interactivo no era suficiente — algunos navegadores y combinaciones
   de capas seguían entregando el click al stretched-link. Modern only
   (`:has()` requiere Chrome 105 / Firefox 121 / Safari 15.4). */
.cjt-card:has( .cjt-card__category:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__expand:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__volunteer-panel:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__unenroll:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__delete:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__pay:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__pay-wrap:hover ) .cjt-card__stretch,
.cjt-card:has( .cjt-card__group:hover ) .cjt-card__stretch {
	pointer-events: none !important;
}

/* En /cuenta/?action=mis-conjuntas el stretched-link es REDUNDANTE: el
   título y la miniatura ya son links propios al single de la conjunta,
   y la fila de acciones (Eliminar, Desapuntarme, Panel voluntario,
   Pagar…) es lo IMPORTANTE para el usuario. El stretched-link sólo
   se le come los clicks. Lo apagamos sin condiciones — la navegación
   a la conjunta sigue funcionando vía título / thumbnail. */
body.mepr-mod-mis-conjuntas .cjt-card__stretch {
	pointer-events: none !important;
	z-index: -1 !important;
}
.cjt-card__stretch:focus-visible {
	outline: 2px solid var( --brand-cta );
	outline-offset: -2px;
}
/* Elementos interactivos que deben ESCAPAR del stretched link y recibir
   sus propios eventos. Sus z-index los ponen por encima del overlay. */
.cjt-card .cjt-card__category,
.cjt-card .cjt-card__expand,
.cjt-card .cjt-card__volunteer-panel,
.cjt-card .cjt-card__unenroll,
.cjt-card .cjt-card__delete,
.cjt-card .cjt-card__pay,
.cjt-card .cjt-card__pay-wrap,
.cjt-card .cjt-card__group,
.cjt-card .cjt-card__title-link,
.cjt-card .cjt-card__media,
.cjt-card .cjt-card__badge--check,
.cjt-card .cjt-card__badge--lock,
.cjt-card .cjt-card__badge--proposed {
	position: relative;
	z-index: 2;
}
/* Hardening del stretched-link (reportado por el user — 10+ veces — que
   los clicks en botones de card "no reaccionan, como imagen estática"):
   las elevaciones individuales arriba (z-index: 2 por botón) NO bastan
   porque dependen de `:hover` para activar `:has(...)` y desactivar
   `pointer-events` del stretch — durante transiciones de hover (transform
   del card / transform de los botones en hover) hay frames de paint en los
   que el hit-test puede entregar el click al stretch en vez de al botón.
   Elevamos los CONTENEDORES enteros (`__cats`, `__title`, `__body`,
   `__actions`) por encima del stretch — así toda la región pintada por el
   contenido de la card vence siempre al overlay, no sólo en frames donde
   `:hover` está bien fijado en el target. El stretch sigue recibiendo
   clicks en el padding alrededor (el área entre media/body/actions
   donde no hay contenido). */
.cjt-card__cats,
.cjt-card__title,
.cjt-card__body,
.cjt-card__actions {
	position: relative;
	z-index: 2;
}
.cjt-card__media,
.cjt-card__media:link {
	display: block;
	border-radius: 0.625rem;
	overflow: hidden;
	background: var( --xb-jacarta-100 );
	aspect-ratio: 1 / 1;
}
.cjt-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.cjt-card__placeholder {
	width: 100%;
	height: 100%;
	background:
		linear-gradient( 135deg, var( --xb-jacarta-50 ), var( --xb-jacarta-100 ) );
}
.cjt-card__media--blur .cjt-card__img,
.cjt-card__media--blur .cjt-card__placeholder { filter: blur( 18px ) saturate( 1.1 ); }

.cjt-card__body {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 18px;
}
.cjt-card__category {
	align-self: flex-start;
	padding: 0;
	font-family: var( --xb-font-body );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.6px;
	color: var( --xb-accent );
	background: transparent;
	border: 0;
	cursor: pointer;
}
.cjt-card__category:hover { color: var( --xb-accent-dark ); }
.cjt-card__title {
	margin: 4px 0 6px;
	font-family: var( --xb-font-display );
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.3;
}
.cjt-card__title-link {
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	transition: color 0.18s ease;
}
.cjt-card__title-link:hover { color: var( --brand-cta ); }
.cjt-card__title-link--blur .cjt-card__title-text { filter: blur( 8px ); }
/* Excerpt blur — same pattern: cuando `conjunta_should_blur()` retorna
   true (visitante / no apuntado), también difuminamos el texto del
   excerpt para no spoil el contenido. */
.cjt-card__excerpt--blur { filter: blur( 6px ); user-select: none; }
.cjt-card__expand {
	margin-left: 6px;
	padding: 0;
	font-size: 11px;
	color: var( --xb-jacarta-500 );
	background: transparent;
	border: 0;
	text-decoration: underline;
	cursor: pointer;
}
.cjt-card__participants {
	margin: 0;
	font-size: 12px;
	color: var( --xb-jacarta-500 );
}
.cjt-card__participants strong { color: var( --xb-jacarta-700 ); font-weight: 700; }
.cjt-card__prices {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px;
	margin: 4px 0 0;
	font-size: 13px;
}
.cjt-card__price-main {
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
	color: #10b981;
}
.cjt-card__price-sep { color: var( --xb-jacarta-200 ); }
.cjt-card__discount {
	padding: 2px 7px;
	font-size: 11px;
	font-weight: 700;
	color: #ffffff;
	background: var( --xb-accent );
	border-radius: 6px;
}
.cjt-card__price-original {
	font-size: 12px;
	color: var( --xb-jacarta-500 );
}
.cjt-card__price-strike { text-decoration: line-through; }

/* Empty state. */
.cjt-empty {
	margin: 40px auto;
	padding: 24px;
	max-width: 520px;
	text-align: center;
	color: var( --xb-jacarta-500 );
	font-size: 15px;
}

/* Mobile: sidebar collapses to a drawer-ish panel toggled from the
   top-right Filtros button. CRÍTICO: `align-items: stretch` + `width:
   100%` para que el content (cards) ocupe TODO el ancho disponible.
   Sin esto el layout en flex-direction:column sigue con
   `align-items: flex-start` heredado del default y los hijos toman
   sólo su ancho de contenido, dejando un hueco blanco a la derecha
   (el user reportó "boxed in / cuts anything plus is the opposite of
   responsive"). */
/* Filtros de "Ordenar por" — sólo dentro del drawer mobile. En desktop
   ocultamos el bloque (la sección entera con sus dos selects), porque
   el listado tiene sus propios controles de orden visibles arriba. En
   mobile (≤1024px) el drawer es el único sitio donde el user puede
   tocarlos, así que aquí permanece visible. */
@media ( min-width: 1025px ) {
	.xb-collections__filter--sort { display: none !important; }
}

@media ( max-width: 1024px ) {
	.xb-collections__layout {
		flex-direction: column;
		gap: 24px;
		align-items: stretch;
	}
	.xb-collections__sidebar {
		flex: 1 1 auto;
		position: static;
		max-height: none;
		padding-right: 0;
		display: none;
	}
	.xb-collections__sidebar.is-open { display: flex; }
	.xb-collections__filters-toggle { display: inline-flex; }
	.xb-collections__content {
		width: 100%;
		min-width: 0;
	}
}
/* ===================================================================
 * Botones CTA — útiles para que las plantillas y plugins reutilicen el
 * mismo lenguaje. `--brand-cta*` los gobierna desde el Customizer.
 * =================================================================== */
.btn-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 12px 24px;
	border-radius: 999px;
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	font-family: var( --xb-font-body );
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.2px;
	border: 0;
	cursor: pointer;
	text-decoration: none;
	transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.btn-cta:hover,
.btn-cta:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
}

/* ===================================================================
 * MemberPress chrome — todas las páginas que el plugin
 * `modificacion-memberpress` marca con `body.mepr-mod-chrome`:
 *   - /login/, /register/, /cuenta/, /checkout/, single memberpressproduct
 *
 * El topbar custom (renderizado por `mod_mepr_render_topbar()` en
 * `wp_body_open`) reutiliza las clases `.site-topbar*` del theme y
 * aquí sólo le quitamos el chrome extra que NO queremos en MP:
 *   - en MP-chrome el topbar es MINIMALISTA: SOLO el brand (nombre del
 *     sitio). NO hay menú, NO hay icono de candado, NO hay dark-toggle.
 *
 * El "vertical memberpress bar" (`#mepr-account-nav`) y el resto de
 * widgets MP (formularios de login/register, errores, botones) se
 * estilan con los tokens del theme (`--brand-cta`, `--xb-jacarta-*`,
 * `--xb-font-display`/body) para que el aspecto sea coherente con el
 * resto del site sin tocar markup ni templates de MP.
 * =================================================================== */

/* ===================================================================
 * MP honeypot anti-spam — CRÍTICO, NO BORRAR.
 *
 * MemberPress mete en cada signup form un input + label `mepr_no_val`
 * (id + name) que es un HONEYPOT: invisible para humanos, los bots
 * lo rellenan y la validación rechaza la submission. Lo define en
 * `memberpress/css/signup.css` (`#mepr_no_val { display:none !important }`)
 * y `memberpress/css/ui/theme.css` (`.mepr-visuallyhidden { …; position:
 * absolute; clip:rect(0 0 0 0); … }`).
 *
 * PERO `topbar-en-checkout.php` (`modificacion-memberpress`) DEQUEUEA
 * TODAS las hojas de MP en MP-chrome pages para reemplazarlas con la
 * estética del theme. Sin estas reglas defensivas, en /registro/ aparece
 * un label "No val" + un input vacío visibles junto al botón "Comprar
 * suscripción" (catastrófico — el user lo reportó 2026-05-26).
 *
 * Replicamos textualmente las reglas mínimas que hacen falta. Globales
 * (no scoped a body.mepr-mod-shell) porque el honeypot puede salir en
 * cualquier MP form que el theme renderice — defensa-en-profundidad.
 * =================================================================== */
.mepr-visuallyhidden {
	border: 0 !important;
	clip: rect( 0 0 0 0 ) !important;
	height: 1px !important;
	width: 1px !important;
	margin: -1px !important;
	overflow: hidden !important;
	padding: 0 !important;
	position: absolute !important;
}
/* `.mepr-payment-method-desc-text` EXCLUIDO del hide global de
   `.mepr-hidden` — MP server-renderiza con `mepr-hidden` el desc-text
   del gateway NO-default ("Pagar con crypto" cuando Stripe va checked)
   y luego su signup.js usa un mecanismo DISTINTO para alternar
   visibilidad (`mepr-close` + jQuery slideUp/Down). Si dejáramos el
   hide global aplicado, el desc-text del gateway secundario nunca
   aparecería aunque su radio se seleccione — la regla `!important`
   gana sobre el `display: block` inline que pone slideDown.
   La visibilidad del desc-text la gestionamos nosotros vía
   `is-hidden-by-radio` (ver el script JS en topbar-en-checkout.php). */
.mepr-hidden:not( .mepr-payment-method-desc-text ),
.mp_wrapper .mepr_no_val,
#mepr_no_val {
	display: none !important;
}
.mepr-payment-method-desc-text.is-hidden-by-radio {
	display: none !important;
}

/* `.cc-error` / `.mepr-form-has-errors` / `.cc-success` / `.mepr-validation-error`
   — son los spans inline de error que MP renderiza dentro de cada
   `.mp-form-label` ("Nombre de usuario no válido", "Email no válido",
   "Contraseña no válida", "La confirmación de contraseña no coincide").
   Por defecto MP los oculta vía `signup.css`:
       .mp_wrapper .cc-error,
       .mp_wrapper .mepr-form-has-errors,
       .mp_wrapper .mepr-validation-error { display: none; color: #d4151e; }
       .mp_wrapper .mepr-validation-error  { display: inline; }
   y la validación JS (`signup.js` / jquery-validate) cambia la clase a
   `mepr-validation-error` para mostrarlos sólo en el campo concreto que
   falla. Como dequeueamos toda la CSS de MP, sin esta defensa los
   mensajes se ven SIEMPRE al lado del label, dando la sensación de que
   el formulario ya está roto antes de tocar nada (user lo reportó
   2026-05-26). Replicamos las dos reglas con `!important` para que
   ganen también frente a cualquier regla cascade global del theme. */
.cc-error,
.mp_wrapper .cc-error,
.cc-success,
.mp_wrapper .cc-success,
.mepr-form-has-errors,
.mp_wrapper .mepr-form-has-errors {
	display: none !important;
}
/* `.mepr-validation-error` se muestra inline porque ESE es el indicador
   activo cuando JS detecta un campo inválido tras submit. Mantiene el
   color rojo de MP por consistencia. */
.mp_wrapper .mepr-validation-error {
	display: inline !important;
	color: #d4151e;
}

/* `.mp-form-row.mp-address-group` — wrapper de los campos de "Dirección
   de facturación". En conjuntas.org NO se piden campos de address (no
   están activados en MP Options), pero el plugin igual emite el
   `<fieldset>` vacío con sólo `<legend class="screen-reader-text">`
   dentro. Por defecto el browser renderiza `<fieldset>` con borde 2px
   groove + padding interno, lo que se ve como un rectángulo vacío en
   la parte alta del formulario de registro. Si está vacío (sin inputs
   visibles), lo colapsamos. Usamos `:not(:has(input, select, textarea))`
   para que si alguna vez se activan los address fields, sí se vea. */
.mp-form-row.mp-address-group:not( :has( input:not([type="hidden"]), select, textarea ) ) {
	display: none !important;
}

/* `.mepr-payment-methods-icons` — banda visual ARRIBA del bloque de
   radios de método de pago. Contiene 2 `<span class="mepr-payment-method-icon">`
   anidados, cada uno con una `<img>`:
     · Stripe   → cards.png (Visa/MasterCard/Discover/AMEX)
     · Zeno     → checkout-logo-2.png (Z/Tether/USDC/BTC/LTC)
   MP los emite `display: inline-block` con `width: auto` y la imagen a
   `height: 32px`. Resultado por defecto: las 2 imágenes una al lado de
   la otra (o apiladas si no cabe).
   El user 2026-05-26 (2ª iteración): "i want that when crypto is
   selected, the image of the visa and cards will disappear and instead
   the crypto image will appear (appearing where the card image is now),
   and the other way around". O sea: sólo SE MUESTRA UN icono — el que
   corresponde al radio actualmente seleccionado, anclado a la izquierda.
   El otro icono se oculta. JS swap en
   `topbar-en-checkout.php` añade la clase `is-hidden-by-radio` al
   icon-span del gateway NO seleccionado y la quita del seleccionado.
   Default (Tarjeta checked → icon Stripe visible, icon Zeno oculto). */
body.mepr-mod-shell .mepr-payment-methods-icons,
body.mepr-mod-chrome .mepr-payment-methods-icons {
	display: flex !important;
	align-items: center;
	justify-content: flex-start;
	margin: 8px 0 12px;
}
body.mepr-mod-shell .mepr-payment-methods-icons .mepr-payment-method-icon,
body.mepr-mod-chrome .mepr-payment-methods-icons .mepr-payment-method-icon {
	padding: 0 !important;
	margin: 0;
	display: block;
}
body.mepr-mod-shell .mepr-payment-methods-icons .mepr-payment-method-icon.is-hidden-by-radio,
body.mepr-mod-chrome .mepr-payment-methods-icons .mepr-payment-method-icon.is-hidden-by-radio {
	display: none !important;
}
body.mepr-mod-shell .mepr-payment-methods-icons .mepr-payment-method-icon img,
body.mepr-mod-chrome .mepr-payment-methods-icons .mepr-payment-method-icon img {
	width: auto !important;
	height: auto !important;
	max-height: 35px !important; /* +25% sobre los 28px previos */
	max-width: 100%;
	display: block;
}

/* ===================================================================
 * MP shell — Strategy B (full template replacement, ver
 * `.claude/skills/wp-memberpress/SKILL.md`). El plugin
 * `modificacion-memberpress` redirige `/cuenta/`, `/login/`, etc. a
 * `templates/account-shell.php`, que pinta su propio <html> + <body
 * class="mepr-mod-shell"> y deja que `the_content()` ponga el form de
 * MP. Aquí van TODAS las reglas que dependen de ese body class.
 *
 * Doble selector `body.mepr-mod-shell` y `body.mepr-mod-chrome` por
 * compatibilidad: el `mepr-mod-chrome` se sigue añadiendo en
 * `body_class` (legacy) y `mepr-mod-shell` lo añade el template propio.
 * En la práctica ambos coinciden, pero mantener los dos previene que
 * un fallback al template viejo (si alguien desactiva el plugin) deje
 * la página sin layout.
 * =================================================================== */

body.mepr-mod-shell,
body.mepr-mod-chrome {
	background: var( --xb-jacarta-50 );
	color: var( --xb-jacarta-700 );
	font-family: var( --xb-font-body );
	padding-top: 0 !important;
}
body.mepr-mod-shell .site-topbar,
body.mepr-mod-chrome .site-topbar { display: none !important; }

/* Layout flex de 2 columnas. La sidebar la renderiza el plugin via
   `mod_mepr_render_sidebar()` en `wp_body_open` ANTES del <main>, así
   que aparecen como hermanos directos del body en el shell template. */
body.mepr-mod-shell {
	display: flex;
	min-height: 100vh;
	align-items: stretch;
	margin: 0;
}
body.mepr-mod-chrome #page,
body.mepr-mod-chrome .site.app-layout {
	display: flex;
	min-height: 100vh;
	align-items: stretch;
}
body.mepr-mod-shell .mepr-mod-shell__main {
	flex: 1 1 auto;
	min-width: 0;
	display: block;
}
body.mepr-mod-shell .mepr-mod-shell__inner {
	max-width: 1440px;
	margin: 32px auto;
	padding: 0 32px;
}
@media ( max-width: 768px ) {
	body.mepr-mod-shell .mepr-mod-shell__inner { margin: 16px auto; padding: 0 16px; }
}

/* Registro (single memberpressproduct) — sin navbar superior ni
   sidebar vertical de MP. El user lo pidió: "during registration
   form make the nav menu vertical bar to not be there, i dont want
   any nav bar for the registration". El layout queda full-width,
   sólo el form + el invoice card. */
body.single-memberpressproduct .xb-nav,
body.single-memberpressproduct .mepr-mod-sidebar,
body.single-memberpressproduct .mepr-mod-sidebar__toggle {
	display: none !important;
}
body.single-memberpressproduct { padding-top: 0 !important; }
body.single-memberpressproduct .mepr-mod-shell__main {
	flex: 1 1 100%;
	width: 100%;
}

/* Compactar la página /register/ para que entre en una sola pantalla
   en monitores medianos. El user lo pidió: "on the register place
   theres a very long scroll down, it should be limited to the fields
   on the screen". Trim: margin top/bottom del shell, gap del grid
   2-col, margin entre filas del form, y padding del invoice. */
body.single-memberpressproduct .mepr-mod-shell__inner {
	margin: 20px auto;
}
body.single-memberpressproduct .mepr-checkout-container {
	row-gap: 14px !important;
}
@media ( min-width: 901px ) {
	body.single-memberpressproduct .mepr-checkout-container {
		column-gap: 40px !important;
	}
}
body.single-memberpressproduct .mepr-mod-shell .mp-form-row,
body.single-memberpressproduct.mepr-mod-shell .mp-form-row {
	margin: 0 0 10px;
}
body.single-memberpressproduct .mepr-checkout-container .invoice-wrapper {
	padding: 20px 24px;
}

/* ===================================================================
 * Register / checkout — orden visual: SUMMARY arriba, FORM debajo
 * ===================================================================
 * MemberPress imprime el form ANTES de la `.invoice-wrapper` (resumen
 * con precio + cupón + total). El user lo pidió: "the information
 * part should be on top, not on the bottom, and is not styled
 * properly". Usamos flex column + `order` para reposicionar el
 * resumen al top SIN tocar el HTML del plugin, y le damos look de
 * card del theme (border + radius + sombra + tipografía del site). */
body.mepr-mod-shell .mepr-checkout-container {
	display: flex;
	flex-direction: column;
	gap: 24px;
}
body.mepr-mod-shell .mepr-checkout-container .invoice-wrapper {
	order: -1; /* primero en el orden visual (mobile) */
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 24px 28px;
	box-shadow: 0 8px 24px -14px rgba( 13, 16, 45, 0.08 );
}
/* Desktop ≥ 901px: layout 2-columnas 50/50 — invoice a la IZQUIERDA
   + form (con su sección "before-signup" arriba) a la DERECHA. La
   invoice es sticky para que se quede visible al scrollear el form
   largo. El user lo pidió: "the /register pages on desktop too narrow
   with lots of margins, make it proper 50/50".
   Usamos CSS Grid en vez de flex porque MemberPress mete TRES hijos
   en `.mepr-checkout-container` (`invoice-wrapper`, `mepr-before-
   signup-form`, `mepr-signup-form`). Con flex 50/50 los tres sumarían
   150% y se romperían en líneas. Con grid de 2 columnas, la invoice
   ocupa la columna 1 y los dos bloques del form se apilan en la
   columna 2. */
@media ( min-width: 901px ) {
	body.mepr-mod-shell .mepr-checkout-container {
		display: grid;
		grid-template-columns: 1fr 1fr;
		grid-auto-rows: min-content;
		column-gap: 48px;
		row-gap: 24px;
		align-items: start;
	}
	body.mepr-mod-shell .mepr-checkout-container .invoice-wrapper {
		grid-column: 1;
		grid-row: 1; /* fila 1 col 1; la altura de la fila la marca el form (col 2),
		                lo que da el "raíl" donde funciona el sticky. Antes era
		                `1 / span 100` y CSS Grid creaba 99 filas implícitas con
		                row-gap 24px → ~2376px de scroll vacío debajo del form
		                en /registro/. El user reportó: "very long scroll down
		                even though there's no more elements". */
		width: auto;
		max-width: none;
		position: sticky;
		top: 24px;
		align-self: start;
	}
	body.mepr-mod-shell .mepr-checkout-container .mepr-before-signup-form {
		grid-column: 2;
		min-width: 0;
		width: 100%;
	}
	body.mepr-mod-shell .mepr-checkout-container .mepr-signup-form {
		grid-column: 2;
		min-width: 0;
		width: 100%;
	}
}

/* Tipografía del invoice card:
     - `.invoice-heading` ("Pagar conjuntas.org") → body normal (es un
       label de página, no debe competir visualmente con el precio).
     - `.mepr_price_cell` solo actúa de wrapper block — la tipografía
       se aplica a sus dos hijos:
         · `.cjt-gradient-text` ("18€")   → H1 con el rainbow gradient.
         · `.cjt-price-unit`   ("/ mes")  → H2.
     - `.mp-cart-footer .bt` / `.total_cell` ("Total" / "18,00€") →
       H3 (regla más abajo).
   `!important` para vencer al CSS de MemberPress (signup.css /
   readylaunch) que también marca estos selectores con su propia
   jerarquía. */
body.mepr-mod-shell .invoice-wrapper .invoice-heading {
	font-family: var( --xb-font-body ) !important;
	font-size: var( --brand-body-size, 16px ) !important;
	font-weight: var( --brand-body-weight, 400 ) !important;
	line-height: 1.5 !important;
	color: var( --xb-jacarta-500 );
	margin: 0 0 4px;
	font-synthesis: weight style;
	letter-spacing: 0;
}/* `.mepr_price_cell` ya no carga tipografía propia — sólo posicionado
   block para que el `<span>` del número + `<span>` del sufijo formen
   una sola línea contenida en este wrapper. */
body.mepr-mod-shell .invoice-wrapper .mepr_price_cell {
	display: block !important;
	margin: 0 0 20px !important;
	color: var( --xb-jacarta-700 );
	line-height: 1.1;
}/* H1 sobre el número del precio. `.cjt-gradient-text` ya tiene el
   `background-clip: text` + animación rainbow definidos arriba en este
   stylesheet; aquí sólo añadimos las vars de tipografía H1 del theme.
   Scopeado a `.invoice-wrapper` para no afectar otros usos de
   `.cjt-gradient-text` (hero, pricing-table, etc.). */
body.mepr-mod-shell .invoice-wrapper .mepr_price_cell .cjt-gradient-text {
	font-family: var( --brand-h1-family, var( --xb-font-display ) ) !important;
	font-size: var( --brand-h1-size, 48px ) !important;
	font-weight: var( --brand-h1-weight, 700 ) !important;
	line-height: 1.1 !important;
	font-synthesis: weight style;
}
/* H2 sobre el sufijo "/ mes" — overridea la regla previa que lo dejaba
   a `0.5em`. Mantenemos color jacarta-600 (un poco apagado vs. el
   número, para guiar la jerarquía visual). */
body.mepr-mod-shell .invoice-wrapper .mepr_price_cell .cjt-price-unit {
	font-family: var( --brand-h2-family, var( --xb-font-display ) ) !important;
	font-size: var( --brand-h2-size, 32px ) !important;
	font-weight: var( --brand-h2-weight, 700 ) !important;
	line-height: 1.1 !important;
	color: var( --xb-jacarta-600 );
	margin-left: 8px;
	vertical-align: baseline;
	font-synthesis: weight style;
}/* `.mp-form-row.mepr_price` es el wrapper del precio en SPC. Si MP le
   mete display:flex o un margin, el `.mepr_price_cell` no respeta
   nuestro `display: block`. Reseteamos el wrapper para que el cell
   ocupe todo el ancho y el size del H1 sea visible. */
body.mepr-mod-shell .invoice-wrapper .mp-form-row.mepr_price {
	display: block !important;
	margin: 0 0 16px !important;
}

/* "Cancela cuando quieras." (o el texto que el admin escriba en el
   editor de la página del CPT memberpressproduct). El JS de
   `functions.php` lo mueve a vivir dentro de `.invoice-wrapper`
   justo debajo del precio. Estilo equivalente al de `.mp_price_str`
   ("Términos: 18€/mes") — descripción discreta, no compite con el
   precio. */
body.mepr-mod-shell .invoice-wrapper .mepr-mod-shell__product-summary {
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.55;
	color: var( --xb-jacarta-500 );
	margin: 0 0 16px;
}
/* Defensa GLOBAL contra emojis gigantes — antes era sólo
   `body.mepr-mod-shell` pero la página `/registro/<slug>/` lleva
   `body.single-memberpressproduct mepr-pro-template mepr-app-layout`
   (NO mepr-mod-shell, porque MP-Pro override el template antes de
   nuestro account-shell.php), así que la regla nunca matcheaba ahí.
   Resultado en producción: emojis ✅/🔒 renderizados por wp-emoji.js
   como `<img class="emoji">` salían a su size nativo (72px+ en
   Twemoji), sobre todo en mobile Safari donde la conversión sí
   dispara.

   Ahora:
   - Selector `body img.emoji` (specificity 0,1,2 > la regla inline
     `img.emoji` de WP que es 0,1,1) — ganamos en cualquier página.
   - Doble cap: `1em` para que escale con el texto cuando el parent es
     normal + `max: 22px` como hard ceiling absoluto para que ningún
     parent con font-size enorme infle el emoji a tamaño gigante.
   - Aplica en TODAS las páginas (no sólo MP) porque el patrón es el
     mismo en cualquier sitio que use emojis del CPT. */
body img.emoji,
body img.wp-smiley {
	display: inline-block !important;
	width: 1em !important;
	height: 1em !important;
	max-width: 22px !important;
	max-height: 22px !important;
	vertical-align: -0.1em !important;
	margin: 0 0.07em !important;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	line-height: 1 !important;
}
body.mepr-mod-shell .mepr-mod-shell__inner > p {
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.55;
	color: var( --xb-jacarta-500 );
	margin: 0 0 16px;
}
body.mepr-mod-shell .mp-form-row label,
body.mepr-mod-shell .mp-form-row .mp-form-label,
body.mepr-mod-shell .mp-form-row .placeholder-text {
	font-size: 14px;
	line-height: 1.5;
}

/* Brand block — logo + nombre del sitio arriba de la columna izquierda
   de la página /register/. Misma fuente y palette que header.php /
   footer.php (xb-nav__brand-* / site-footer__brand-*) para que se vea
   coherente. Sólo aparece en `body.single-memberpressproduct`. */
body.mepr-mod-shell .mepr-mod-shell__brand {
	display: inline-flex;
	align-items: center;
	/* Mismo gap=1px que `.xb-nav__brand` y `.site-footer__brand` para
	   carbon-copy entre navbar / footer / sidebar / shell. */
	gap: 1px;
	text-decoration: none;
	font-family: var( --xb-font-display );
	/* Peso 600 — matchea el face cargado de CalSans-SemiBold. Si
	   pedíamos 700 el browser intentaba faux-bold sobre el face 600
	   y el rendering salía MÁS DELGADO que el de la navbar (que
	   hereda 400 del body y termina usando el mismo face 600 sin
	   synthesis). Ahora ambos sitios renderizan idéntico. */
	font-weight: 600;
	font-size: 22px;
	line-height: 1.1;
	color: var( --xb-jacarta-700 );
	margin: 0 0 24px;
}body.mepr-mod-shell .mepr-mod-shell__brand:hover {
	color: var( --brand-cta );
}
body.mepr-mod-shell .mepr-mod-shell__brand .site-brand-icon,
body.mepr-mod-shell .mepr-mod-shell__brand .custom-logo {
	height: 28px;
	width: auto;
	display: block;
}
body.mepr-mod-shell .mepr-mod-shell__brand-text { display: inline-flex; align-items: baseline; }
body.mepr-mod-shell .mepr-mod-shell__brand-tld {
	font-size: 0.7em;
	font-weight: 500;
	margin-left: 2px;
	color: var( --xb-jacarta-500 );
}/* `.cjt-price-unit` (sufijo "/ mes") tiene su tipografía H2 definida
   arriba (línea ~3632) junto al `.cjt-gradient-text` con H1 — no
   duplicamos aquí para evitar conflictos de orden CSS. */
body.mepr-mod-shell .invoice-wrapper .have-coupon-link {
	display: inline-block;
	color: var( --brand-cta );
	font-weight: 500;
	text-decoration: none;
	margin: 8px 0 12px;
}
body.mepr-mod-shell .invoice-wrapper .have-coupon-link:hover {
	color: var( --brand-cta-hover );
	text-decoration: underline;
}
body.mepr-mod-shell .invoice-wrapper .mepr-coupon-code {
	width: 100%;
	max-width: 320px;
	padding: 10px 14px;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	font-family: var( --xb-font-body );
	font-size: 14px;
}
body.mepr-mod-shell .invoice-wrapper .mepr-coupon-code:focus {
	outline: none;
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 18%, transparent );
}
body.mepr-mod-shell .invoice-wrapper .mp_price_str {
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-600 );
	margin-top: 16px;
	padding-top: 16px;
	border-top: 1px solid var( --xb-jacarta-100 );
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-body {
	list-style: none;
	margin: 12px 0 0;
	padding: 0;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px 0;
	border-bottom: 1px solid var( --xb-jacarta-100 );
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item-image {
	width: 44px;
	height: 44px;
	border-radius: 10px;
	background: color-mix( in srgb, var( --brand-cta ) 8%, #ffffff );
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	overflow: hidden;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item-image img {
	max-width: 60%;
	max-height: 60%;
	opacity: 0.7;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item-details {
	flex: 1;
	min-width: 0;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item-details p {
	margin: 0;
	font-family: var( --xb-font-body );
	font-size: 15px;
	color: var( --xb-jacarta-700 );
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-item-details .desc {
	font-size: 13px;
	color: var( --xb-jacarta-500 );
	margin-top: 2px;
}
body.mepr-mod-shell .invoice-wrapper .mp-currency-cell {
	font-family: var( --xb-font-display );
	font-size: 16px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	white-space: nowrap;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: 14px;
	padding-top: 14px;
	border-top: 2px solid var( --xb-jacarta-100 );
	font-family: var( --xb-font-display );
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-footer > div {
	display: flex;
	justify-content: space-between;
	width: 100%;
	align-items: center;
}
/* "Total" + cifra total — H3 del theme (mismas vars que cualquier
   <h3> del site). El color del cell del total se mantiene en el CTA
   del brand para que la cifra "destaque" del label. */
body.mepr-mod-shell .invoice-wrapper .mp-cart-footer .bt {
	font-family: var( --brand-h3-family, var( --xb-font-display ) ) !important;
	font-size: var( --brand-h3-size, 20px ) !important;
	font-weight: var( --brand-h3-weight, 700 ) !important;
	line-height: 1.25;
}
body.mepr-mod-shell .invoice-wrapper .mp-cart-footer .total_cell {
	font-family: var( --brand-h3-family, var( --xb-font-display ) ) !important;
	font-size: var( --brand-h3-size, 20px ) !important;
	font-weight: var( --brand-h3-weight, 700 ) !important;
	color: var( --brand-cta );
}
/* ----- Sidebar vertical ----- */
.mepr-mod-sidebar {
	flex: 0 0 260px;
	width: 260px;
	background: #ffffff;
	border-right: 1px solid var( --xb-jacarta-100 );
	display: flex;
	flex-direction: column;
	padding: 0;
	position: sticky;
	top: 0;
	max-height: 100vh;
	overflow-y: auto;
	overflow-x: hidden;
	z-index: 30;
}
/* Brand del sidebar MP — el markup es `class="mepr-mod-sidebar__brand xb-nav__brand"`
   así que TODAS las reglas `.xb-nav__brand*` (gap: 1px de la regla compartida,
   font-family, color, hover) ya aplican aquí carbon-copy. Sólo añadimos lo
   específico del contexto sidebar: un padding lateral y border-bottom. */
.mepr-mod-sidebar__brand {
	padding: 18px 18px;
	border-bottom: 1px solid var( --xb-jacarta-100 );
	width: 100%;
}

.mepr-mod-sidebar__nav { padding: 12px 0; flex: 1 1 auto; }
.mepr-mod-sidebar__nav ul { list-style: none; margin: 0; padding: 0; }
.mepr-mod-sidebar__nav li { margin: 0; padding: 0; }
.mepr-mod-sidebar__nav a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 11px 18px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-weight: 500;
	color: var( --xb-jacarta-500 );
	text-decoration: none;
	border-left: 3px solid transparent;
	transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.mepr-mod-sidebar__nav a:hover,
.mepr-mod-sidebar__nav a:focus {
	color: var( --xb-jacarta-700 );
	background: color-mix( in srgb, var( --brand-cta ) 6%, transparent );
}
.mepr-mod-sidebar__nav .is-active > a,
.mepr-mod-sidebar__nav .mepr-active-nav-tab > a {
	color: var( --brand-cta );
	background: color-mix( in srgb, var( --brand-cta ) 10%, transparent );
	border-left-color: var( --brand-cta );
	font-weight: 600;
}

/* CTA "Comunidad" — botón pill al inicio del sidebar con el logo de
   Discord. Va dentro del mismo <ul> que el resto de items pero se
   estiliza distinto: pill con bg color-mix de la marca + icon. */
.mepr-mod-sidebar__nav li.is-cta { margin: 12px 14px; padding: 0; }
.mepr-mod-sidebar__nav li.is-cta > a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: 100%;
	padding: 10px 14px;
	border: 0;
	border-left: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.3px;
	text-transform: uppercase;
	color: var( --brand-cta-text );
	background: var( --brand-cta );
	transition: background 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
	text-align: center;
}
.mepr-mod-sidebar__nav li.is-cta > a:hover,
.mepr-mod-sidebar__nav li.is-cta > a:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
}
.mepr-mod-sidebar__nav-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	flex: 0 0 20px;
	color: inherit;
	opacity: 0.85;
}
.mepr-mod-sidebar__nav-icon svg { display: block; width: 20px; height: 20px; }
/* La CTA "Comunidad" usa un icono propio a 18px — no le aplica el 20px. */
.mepr-mod-sidebar__nav li.is-cta .mepr-mod-sidebar__nav-icon,
.mepr-mod-sidebar__nav li.is-cta .mepr-mod-sidebar__nav-icon svg {
	width: 18px;
	height: 18px;
	flex-basis: 18px;
}
.mepr-mod-sidebar__nav a:hover .mepr-mod-sidebar__nav-icon,
.mepr-mod-sidebar__nav a:focus .mepr-mod-sidebar__nav-icon,
.mepr-mod-sidebar__nav .is-active > a .mepr-mod-sidebar__nav-icon {
	opacity: 1;
}

/* Cuando estamos en MP-chrome, el #mepr-account-nav que MP renderiza
   dentro del contenido se OCULTA — su contenido vive ahora en la
   sidebar lateral (vía PHP que clona los items). Sin esto saldría
   duplicado. */
body.mepr-mod-chrome #mepr-account-nav {
	display: none;
}

/* ----- Content area ----- */
body.mepr-mod-chrome .site-main,
body.mepr-mod-chrome #primary {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 1100px;
	margin: 32px auto;
	padding: 0 24px;
}
@media ( max-width: 768px ) {
	body.mepr-mod-chrome .site-main,
	body.mepr-mod-chrome #primary { margin: 16px auto; padding: 0 16px; }
}

/* CTA "Comunidad" en MOBILE — pill morado pegado a la izquierda del
   hamburger (a la derecha del logo). En desktop se oculta porque el
   mismo botón ya vive como primer <li> del nav vertical. */
.mepr-mod-sidebar__mobile-cta { display: none; }

/* ----- Mobile: sidebar colapsable ----- */
.mepr-mod-sidebar__toggle {
	display: none;
	position: sticky;
	top: 0;
	z-index: 25;
	padding: 10px 14px;
	background: #ffffff;
	border-bottom: 1px solid var( --xb-jacarta-100 );
	width: 100%;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	border-left: 0;
	border-right: 0;
	border-top: 0;
	text-align: left;
	cursor: pointer;
}
@media ( max-width: 1024px ) {
	/* Mobile chrome: barra superior con LOGO a la izquierda + botón
	   HAMBURGER a la derecha. Los items del menú viven en un drawer
	   colapsable que se despliega bajo la barra al pulsar el toggle.
	   El user lo pidió textualmente: "in responsive i still not see the
	   hamburger menu and the logo on the left" — sustituye al patrón
	   anterior (tira horizontal scrollable que se llevaba el espacio
	   sin enseñar marca). */
	body.mepr-mod-shell,
	body.mepr-mod-chrome #page,
	body.mepr-mod-chrome .site.app-layout {
		flex-direction: column !important;
	}

	body.mepr-mod-chrome .mepr-mod-sidebar,
	body.mepr-mod-shell .mepr-mod-sidebar {
		position: sticky !important;
		top: 0 !important;
		left: 0;
		right: 0;
		flex: 0 0 auto !important;
		width: 100% !important;
		max-width: 100% !important;
		height: 60px !important;
		max-height: 60px !important;
		flex-direction: row !important;
		align-items: center !important;
		padding: 0 12px !important;
		transform: translateY( 0 );
		transition: transform 0.22s ease;
		border-right: 0 !important;
		border-bottom: 1px solid var( --xb-jacarta-100 );
		box-shadow: 0 4px 12px -8px rgba( 13, 16, 45, 0.15 );
		z-index: 50;
		overflow: visible;
		will-change: transform;
	}
	/* Hide-on-scroll-down: el JS añade `mepr-mod-sidebar-hidden` al body
	   cuando detecta scroll hacia abajo (≥6px) por debajo del topGuard
	   (80px). Lo quita al scroll-up o cuando el drawer está abierto. La
	   transformación es `translateY(-100%)` — la barra se desliza hacia
	   arriba dejando el contenido aprovechar la altura completa. */
	body.mepr-mod-sidebar-hidden.mepr-mod-chrome .mepr-mod-sidebar,
	body.mepr-mod-sidebar-hidden.mepr-mod-shell .mepr-mod-sidebar {
		transform: translateY( -100% );
	}	html.admin-bar body.mepr-mod-chrome .mepr-mod-sidebar,
	html.admin-bar body.mepr-mod-shell .mepr-mod-sidebar {
		top: 46px !important;
	}

	/* Brand (logo + nombre) visible a la izquierda, sin border-bottom
	   (la sidebar entera ya lo tiene). */
	body.mepr-mod-chrome .mepr-mod-sidebar__brand,
	body.mepr-mod-shell .mepr-mod-sidebar__brand {
		display: inline-flex !important;
		align-items: center;
		padding: 0 !important;
		border-bottom: 0 !important;
		width: auto !important;
		flex: 0 0 auto;
	}
	/* Toggle hamburger visible a la derecha. El `margin-left: 8px` deja un
	   gap entre el CTA Comunidad (que viene con `margin-left: auto`) y el
	   botón. Si NO hay CTA (URL Discord vacía), el toggle se pega al
	   borde derecho gracias a su propio `margin-left: auto` (definido en
	   la regla `:last-child` más abajo). */
	body.mepr-mod-chrome .mepr-mod-sidebar__toggle,
	body.mepr-mod-shell .mepr-mod-sidebar__toggle {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		position: static !important;
		top: auto !important;
		width: auto !important;
		padding: 8px 14px !important;
		font-size: 13px !important;
		border: 1px solid var( --xb-jacarta-100 ) !important;
		border-radius: 8px !important;
		background: #ffffff !important;
		color: var( --xb-jacarta-700 ) !important;
		margin-left: 8px;
	}
	/* Si el CTA Comunidad no se renderiza, el toggle queda como segundo
	   hijo del aside y se ancla por sí mismo al borde derecho. */
	body.mepr-mod-chrome .mepr-mod-sidebar__brand + .mepr-mod-sidebar__toggle,
	body.mepr-mod-shell .mepr-mod-sidebar__brand + .mepr-mod-sidebar__toggle {
		margin-left: auto;
	}
	body.mepr-mod-sidebar-open .mepr-mod-sidebar__toggle {
		background: color-mix( in srgb, var( --brand-cta ) 10%, #ffffff ) !important;
		border-color: var( --brand-cta ) !important;
		color: var( --brand-cta ) !important;
	}
	/* CTA "Comunidad" pegado a la IZQUIERDA del hamburger (en el extremo
	   derecho del topbar). `margin-left: auto` lo empuja al final del
	   espacio libre, y luego el toggle se coloca con `margin-left: 8px`
	   inmediatamente a su derecha. Layout final mobile:
	     [logo conjuntas.org]  ←gap→  [Comunidad CTA] [Menú]
	   Tipografía 1:1 con `.cjt-card__group` (la pill morada "GRUPO DE ESTA
	   CONJUNTA" del row de acciones de las cards): 12px / 700 / 0.4px
	   spacing / uppercase. `!important` en font-size y padding para vencer
	   cualquier regla MP-chrome global sobre `a` o `button` que escale al
	   16px del body. El pill abraza el contenido (flex: 0 0 auto + padding
	   compacto), no toma espacio extra. */
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta {
		display: inline-flex !important;
		align-items: center;
		gap: 5px;
		margin-left: auto;
		padding: 6px 12px !important;
		background: var( --brand-cta );
		color: var( --brand-cta-text ) !important;
		border-radius: 999px;
		font-family: var( --xb-font-display ) !important;
		font-size: 12px !important;
		font-weight: 700 !important;
		line-height: 1 !important;
		letter-spacing: 0.4px;
		text-transform: uppercase;
		text-decoration: none;
		transition: background 0.15s ease, transform 0.15s ease;
		flex: 0 0 auto;
		white-space: nowrap;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta-label,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta-label {
		font-size: 12px !important;
		line-height: 1 !important;
	}
	/* En mobile, ocultamos el clon de Comunidad que vive como <li> del
	   drawer (es el mismo CTA renderizado por el array `$items`). En
	   desktop ese <li> es el ÚNICO render del CTA y se mantiene. */
	body.mepr-mod-chrome .mepr-mod-sidebar__nav li.is-cta--discord,
	body.mepr-mod-shell .mepr-mod-sidebar__nav li.is-cta--discord {
		display: none !important;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta:hover,
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta:focus,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta:hover,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta:focus {
		background: var( --brand-cta-hover );
		color: var( --brand-cta-text-hover );
		transform: translateY( -1px );
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta-icon,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta-icon {
		display: inline-flex;
		align-items: center;
		flex: 0 0 14px;
		width: 14px;
		height: 14px;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta-icon svg,
	body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta-icon svg {
		display: block;
		width: 14px !important;
		height: 14px !important;
	}
	/* Viewports muy estrechos (≤420px): colapsa el label, deja sólo icono
	   redondo para no apelmazar la cabecera. */
	@media ( max-width: 420px ) {
		body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta-label,
		body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta-label { display: none; }
		body.mepr-mod-chrome .mepr-mod-sidebar__mobile-cta,
		body.mepr-mod-shell .mepr-mod-sidebar__mobile-cta {
			width: 36px;
			height: 36px;
			padding: 0;
			justify-content: center;
			gap: 0;
		}
	}
	/* Backdrop cuando el drawer está abierto. */
	body.mepr-mod-sidebar-open::after {
		content: '';
		position: fixed;
		inset: 60px 0 0 0;
		background: rgba( 13, 16, 45, 0.35 );
		z-index: 40;
	}
	html.admin-bar body.mepr-mod-sidebar-open::after { top: calc( 46px + 60px ); }

	/* Lista de items: drawer absolute bajo la barra, oculto por defecto. */
	body.mepr-mod-chrome .mepr-mod-sidebar__nav,
	body.mepr-mod-shell .mepr-mod-sidebar__nav {
		display: none;
		position: absolute;
		top: 60px;
		left: 0;
		right: 0;
		background: #ffffff;
		border-bottom: 1px solid var( --xb-jacarta-100 );
		box-shadow: 0 8px 16px -8px rgba( 13, 16, 45, 0.18 );
		padding: 8px 0 !important;
		flex: 0 0 auto;
		z-index: 45;
		max-height: calc( 100vh - 60px );
		overflow-y: auto;
	}	body.mepr-mod-sidebar-open .mepr-mod-sidebar__nav { display: block !important; }
	body.mepr-mod-chrome .mepr-mod-sidebar__nav ul,
	body.mepr-mod-shell .mepr-mod-sidebar__nav ul {
		display: flex;
		flex-direction: column;
		overflow: visible;
		gap: 0;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__nav a,
	body.mepr-mod-shell .mepr-mod-sidebar__nav a {
		padding: 12px 18px;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__nav li,
	body.mepr-mod-shell .mepr-mod-sidebar__nav li { flex: 0 0 auto; }
	body.mepr-mod-chrome .mepr-mod-sidebar__nav a,
	body.mepr-mod-shell .mepr-mod-sidebar__nav a {
		display: inline-flex;
		align-items: center;
		padding: 12px 16px;
		font-size: 13px;
		font-weight: 600;
		white-space: nowrap;
		border-left: 0;
		border-bottom: 2px solid transparent;
		border-radius: 0;
	}
	body.mepr-mod-chrome .mepr-mod-sidebar__nav .is-active > a,
	body.mepr-mod-chrome .mepr-mod-sidebar__nav .mepr-active-nav-tab > a,
	body.mepr-mod-shell .mepr-mod-sidebar__nav .is-active > a,
	body.mepr-mod-shell .mepr-mod-sidebar__nav .mepr-active-nav-tab > a {
		border-left: 0;
		border-bottom-color: var( --brand-cta );
		background: transparent;
		color: var( --brand-cta );
	}
}

/* Bloque "MP items" inyectado en el drawer del topbar (.xb-nav__panel)
   cuando el visitante está en una página MP-chrome y logueado. Sólo
   visible en responsive (≤1024px) — en desktop los mismos items viven
   en el sidebar vertical y aquí los ocultamos. Usa las MISMAS clases
   `xb-nav__list / xb-nav__item / xb-nav__link` que el menú primario,
   así heredan exacto el estilo del responsive nav del resto del site. */
.xb-nav__mp-items { display: none; }
@media ( max-width: 1024px ) {
	.xb-nav__mp-items {
		display: block;
		margin-top: 14px;
		padding-top: 14px;
		border-top: 1px solid var( --xb-jacarta-100 );
	}	.xb-nav__list--mp {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}
	.xb-nav__list--mp .xb-nav__item.is-active > .xb-nav__link {
		color: var( --brand-cta );
		font-weight: 700;
	}
}

/* (Vieja regla del topbar minimal — mantenida pero ahora vive el block
   anterior `display: none`. Se conserva sólo el detalle de tipografía
   por si alguna otra tema activa el topbar en MP en el futuro.) */
body.mepr-mod-chrome #mepr-account-nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
}
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item {
	margin: 0;
	padding: 0;
	border: 0;
}
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 11px 18px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-weight: 500;
	color: var( --xb-jacarta-500 );
	text-decoration: none;
	border-left: 3px solid transparent;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
/* Icono de cada item del menú de cuenta — viene del registro único
   `mod_mepr_account_icon()`. Hereda `currentColor`, así que cambia de
   color junto al label en hover / item activo. */
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	color: inherit;
	opacity: 0.85;
}
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-icon svg {
	width: 20px;
	height: 20px;
}
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item a:hover .mepr-nav-icon,
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item a:focus .mepr-nav-icon,
body.mepr-mod-chrome #mepr-account-nav .mepr-active-nav-tab a .mepr-nav-icon {
	opacity: 1;
}
/* Mismo icono en el dropdown responsive del avatar (profile-menu) —
   el item es un <a> inline; alineamos icono + label en flex. */
.profile-menu__dropdown-item .mepr-nav-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin-right: 8px;
	color: inherit;
	vertical-align: middle;
}
.profile-menu__dropdown-item .mepr-nav-icon svg {
	width: 18px;
	height: 18px;
}
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item a:hover,
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item a:focus {
	color: var( --xb-jacarta-700 );
	background: color-mix( in srgb, var( --brand-cta ) 6%, transparent );
}
body.mepr-mod-chrome #mepr-account-nav .mepr-active-nav-tab a,
body.mepr-mod-chrome #mepr-account-nav .mepr-nav-item.mepr-active-nav-tab a {
	color: var( --brand-cta );
	background: color-mix( in srgb, var( --brand-cta ) 10%, transparent );
	border-left-color: var( --brand-cta );
	font-weight: 600;
}

/* ----- Formularios MP (`mp-form-row`, inputs, labels) y MP-Pro
        (`mepro-*`) — en /login/, /register/, /cuenta/. ----- */
body.mepr-mod-chrome .mp-form-row,
body.mepr-mod-chrome .mepro-form-row {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0 0 14px 0;
}
body.mepr-mod-chrome .mp-form-label,
body.mepr-mod-chrome .mepro-form-label,
body.mepr-mod-chrome label {
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0;
	letter-spacing: 0.1px;
}
body.mepr-mod-chrome input[type="text"],
body.mepr-mod-chrome input[type="email"],
body.mepr-mod-chrome input[type="password"],
body.mepr-mod-chrome input[type="tel"],
body.mepr-mod-chrome input[type="url"],
body.mepr-mod-chrome input[type="number"],
body.mepr-mod-chrome textarea,
body.mepr-mod-chrome select {
	width: 100%;
	padding: 11px 14px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	outline: none;
	box-sizing: border-box;
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
body.mepr-mod-chrome input[type="text"]:focus,
body.mepr-mod-chrome input[type="email"]:focus,
body.mepr-mod-chrome input[type="password"]:focus,
body.mepr-mod-chrome input[type="tel"]:focus,
body.mepr-mod-chrome input[type="url"]:focus,
body.mepr-mod-chrome input[type="number"]:focus,
body.mepr-mod-chrome textarea:focus,
body.mepr-mod-chrome select:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
}
/* Checkbox + radio: dejamos los nativos pero igualamos color con el accent. */
body.mepr-mod-chrome input[type="checkbox"],
body.mepr-mod-chrome input[type="radio"] {
	accent-color: var( --brand-cta );
}

/* Botones (submit, primary). MP usa `button-primary`, `mepr-share-button`,
   `mepr-submit`, `wp-block-button__link` en distintos lugares — los
   colapsamos todos al estilo del theme `.btn-cta`. */
body.mepr-mod-chrome button[type="submit"],
body.mepr-mod-chrome input[type="submit"],
body.mepr-mod-chrome .button-primary,
body.mepr-mod-chrome .mepr-submit,
body.mepr-mod-chrome .mepr-share-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 12px 22px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 600;
	color: var( --brand-cta-text );
	background: var( --brand-cta );
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	text-decoration: none;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
body.mepr-mod-chrome button[type="submit"]:hover,
body.mepr-mod-chrome input[type="submit"]:hover,
body.mepr-mod-chrome .button-primary:hover,
body.mepr-mod-chrome .mepr-submit:hover,
body.mepr-mod-chrome .mepr-share-button:hover {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
}

/* Links genéricos en contenido MP. */
body.mepr-mod-chrome .mp_wrapper a,
body.mepr-mod-chrome .mepr-login-actions a,
body.mepr-mod-chrome .mepro-login-contents a {
	color: var( --brand-cta );
	text-decoration: none;
}
body.mepr-mod-chrome .mp_wrapper a:hover,
body.mepr-mod-chrome .mepr-login-actions a:hover,
body.mepr-mod-chrome .mepro-login-contents a:hover {
	color: var( --brand-cta-hover );
	text-decoration: underline;
}

/* Duplicado del error de login: MP renderiza el bloque `.mepr_pro_error`
   DOS veces cuando el login falla — una vez antes de la caja (desde
   `MeprLoginCtrl::display_login_form`) y otra DENTRO del form
   (`/readylaunch/login/form.php` lo vuelve a renderizar). No podemos
   tocar el plugin, así que ocultamos todas las instancias en la página
   y reactivamos sólo la que vive dentro de `#mepro-login-hero`. Scope
   a `body.mepr-mod-login` para no afectar a otras pantallas MP. */
body.mepr-mod-login .mepr_pro_error,
body.mepr-mod-login .mp_wrapper > .mepr_pro_error { display: none !important; }
body.mepr-mod-login #mepro-login-hero .mepr_pro_error { display: flex !important; }

/* ----- Cajas de login (mepro-login-hero, mepro-boxed) — la "tarjeta"
        que MP-Pro pinta alrededor del formulario. Frame rainbow
        animado de 2px (mismo gradient que las cards coverflow
        above-the-fold y la pricing-table). Trick: bg de dos capas con
        `background-clip` — capa interior `padding-box` (blanco sólido),
        capa exterior `border-box` (rainbow). Un `border` transparente
        de 2px deja ver la capa rainbow como ring animado. ----- */
body.mepr-mod-chrome .mepro-boxed,
body.mepr-mod-chrome .mepr-login-form-wrap,
body.mepr-mod-chrome .mp_wrapper.mp_login_form,
body.mepr-mod-chrome #mepr-template-login {
	max-width: 460px;
	margin: 32px auto;
	padding: 32px;
	background:
		linear-gradient( #ffffff, #ffffff ) padding-box,
		var( --cjt-rainbow-gradient ) border-box;
	background-size: 100% 100%, 200% 100%;
	background-repeat: no-repeat, no-repeat;
	border: 2px solid transparent;
	border-radius: 1.25rem;
	box-shadow: 0 12px 32px -14px rgba( 13, 16, 45, 0.10 );
	animation: cjt-card-rainbow 6s linear infinite;
}@media ( prefers-reduced-motion: reduce ) {
	body.mepr-mod-chrome .mepro-boxed,
	body.mepr-mod-chrome .mepr-login-form-wrap,
	body.mepr-mod-chrome .mp_wrapper.mp_login_form,
	body.mepr-mod-chrome #mepr-template-login { animation: none; }
}

/* MemberPress renderiza los wrappers de la página de acceso anidados
   (`#mepr-template-login > .mepr-login-form-wrap > .mp_wrapper.mp_login_form`
   > `.mepro-boxed`). La regla rainbow apunta a los cuatro para tener
   un fallback robusto entre versiones de MP — pero cuando MP los anida,
   los CUATRO acaban pintando su propio borde a la vez (triple/cuádruple
   anillo concéntrico). Aquí dejamos el rainbow SOLO en el outermost y
   neutralizamos cualquier wrapper anidado: fondo transparente, sin
   borde, sin shadow, sin animación, padding 0. */
body.mepr-mod-chrome :is( .mepro-boxed, .mepr-login-form-wrap, .mp_wrapper.mp_login_form, #mepr-template-login ) :is( .mepro-boxed, .mepr-login-form-wrap, .mp_wrapper.mp_login_form, #mepr-template-login ) {
	max-width: 100% !important;
	margin: 0 !important;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	animation: none !important;
}
body.mepr-mod-chrome #mepro-login-hero {
	background: transparent;
	padding: 0;
}
body.mepr-mod-chrome .mepro-login-contents {
	max-width: 100%;
}

/* ----- Mensajes de error/info de MP (`mepr_pro_error`, etc.) ----- */
body.mepr-mod-chrome .mepr_pro_error {
	display: flex;
	justify-content: center;
	margin: 16px 0;
}
body.mepr-mod-chrome .mepr_pro_error_content {
	padding: 12px 18px;
	background: color-mix( in srgb, var( --brand-cta ) 6%, #ffffff );
	border: 1px solid color-mix( in srgb, var( --brand-cta ) 22%, transparent );
	border-radius: 12px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
}

/* ----- Hide ReadyLaunch leftovers que ya no aplican porque tenemos
        nuestro propio chrome (sidebar con brand) ----- */
body.mepr-mod-chrome .mepr-rl-footer-widgets { display: none; }
/* `.account-header` lo añade `template_include` de MP cuando hay sesión —
   nuestra sidebar ya muestra el brand, así que la cabecera duplicada
   sobra y se oculta. */
body.mepr-mod-chrome .site-header.account-header { display: none; }

/* MP popups via Magnific Popup. Cuando se hace click en un trigger MP
   (p.ej. "Forgot password", "Edit subscription"), Magnific Popup mueve el
   contenido apuntado al `<body>` envuelto en `.mfp-wrap`. Nuestro layout
   `body.mepr-mod-shell { display: flex }` rompía la posición fixed del
   modal — el contenido salía como un hijo flex del body en vez de overlay
   centrado. Forzamos `position: fixed` + alto z-index. */
body.mepr-mod-shell .mfp-bg,
body.mepr-mod-chrome .mfp-bg {
	position: fixed !important;
	inset: 0 !important;
	background: rgba( 13, 16, 45, 0.5 ) !important;
	z-index: 9998 !important;
	flex: none !important;
}
body.mepr-mod-shell .mfp-wrap,
body.mepr-mod-chrome .mfp-wrap {
	position: fixed !important;
	inset: 0 !important;
	z-index: 9999 !important;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	overflow-y: auto !important;
	flex: none !important;
}
body.mepr-mod-shell .mfp-container,
body.mepr-mod-chrome .mfp-container {
	width: 100% !important;
	max-width: 600px !important;
	padding: 16px !important;
	box-sizing: border-box !important;
}
body.mepr-mod-shell .mfp-content,
body.mepr-mod-chrome .mfp-content {
	background: #ffffff !important;
	border-radius: 14px !important;
	padding: 24px !important;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 ) !important;
	max-height: 90vh !important;
	overflow-y: auto !important;
}
body.mepr-mod-shell .mfp-close,
body.mepr-mod-chrome .mfp-close {
	color: var( --xb-jacarta-700 ) !important;
	font-size: 28px !important;
	cursor: pointer !important;
}

/* ----- Refinos extra de MP-chrome (login form, password toggle, etc.) ----- */

/* H1/H2 dentro del login/register/account */
body.mepr-mod-chrome .mp_wrapper h1,
body.mepr-mod-chrome .mepro-login-contents h1,
body.mepr-mod-chrome #mepr-template-login h1,
body.mepr-mod-chrome #mepro-login-hero h1 {
	font-family: var( --xb-font-display );
	font-size: 28px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 18px;
	letter-spacing: -0.2px;
}
body.mepr-mod-chrome .mp_wrapper h2,
body.mepr-mod-chrome .mepro-login-contents h2 {
	font-family: var( --xb-font-display );
	font-size: 20px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 18px 0 10px;
}

/* `.placeholder-text` — pattern MP-Pro: el label flota encima del input
   con texto pequeño + color muted. Lo dejamos como label estándar del
   theme (encima del input, no superpuesto) — es más legible y consistente
   con el resto de forms. */
body.mepr-mod-shell .placeholder-text,
body.mepr-mod-chrome .placeholder-text {
	display: block;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 4px;
	letter-spacing: 0.1px;
	position: static !important;
	transform: none !important;
	background: transparent !important;
	padding: 0 !important;
}

/* `.mp-form-label` y `.mp-form-row` — wrappers de cada campo. Forzamos
   block + spacing legible. MP-Pro a veces los pinta inline, lo que
   apila el label A LA IZQUIERDA del input — feo en mobile. */
body.mepr-mod-shell .mp-form-label,
body.mepr-mod-chrome .mp-form-label {
	display: block;
	margin: 0 0 6px;
	width: 100%;
}
body.mepr-mod-shell .mp-form-row,
body.mepr-mod-chrome .mp-form-row {
	display: block;
	margin: 0 0 14px;
}
/* Wrapper general de los forms MP — anular el `alignwide` que extiende
   el contenido más allá del container. Aquí queremos que el form viva
   centrado en el card de login (max-width 460px). */
body.mepr-mod-shell .mp_wrapper,
body.mepr-mod-shell .mp_wrapper.alignwide,
body.mepr-mod-chrome .mp_wrapper,
body.mepr-mod-chrome .mp_wrapper.alignwide {
	max-width: none;
	margin: 0;
}
/* `.mepr-login-form-wrap` y `.mepro-boxed` ya tienen max-width 460px y
   margin auto desde la regla principal. No tocar. */

/* Botón "ojo" para mostrar/ocultar contraseña — pequeño, transparente,
   posicionado dentro del input. */
body.mepr-mod-chrome .mp-hide-pw {
	position: relative;
}
body.mepr-mod-chrome button.mp-hide-pw {
	background: transparent !important;
	color: var( --xb-jacarta-400 ) !important;
	border: 0 !important;
	padding: 6px 10px !important;
	font-size: 12px !important;
	font-weight: 500 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	border-radius: 6px !important;
	box-shadow: none !important;
	position: absolute;
	right: 6px;
	top: 50%;
	transform: translateY( -50% );
	cursor: pointer;
}
body.mepr-mod-chrome button.mp-hide-pw:hover {
	color: var( --xb-jacarta-700 ) !important;
	background: var( --xb-jacarta-50 ) !important;
}

/* Spacer & checkbox row alignment */
body.mepr-mod-chrome .mp-spacer { display: none; }
body.mepr-mod-chrome .mp-form-row.mepr_remember_me {
	flex-direction: row;
	align-items: center;
	gap: 8px;
	margin: 8px 0 14px;
}
body.mepr-mod-chrome .mp-form-row.mepr_remember_me input[type="checkbox"] {
	width: auto;
	margin: 0;
}
body.mepr-mod-chrome .mp-form-row.mepr_remember_me label {
	margin: 0;
	cursor: pointer;
	font-weight: 500;
	font-family: var( --xb-font-body );
}

/* Submit row: el botón a ancho completo dentro del card de login. */
body.mepr-mod-chrome .submit,
body.mepr-mod-chrome .mp-form-row.submit {
	margin: 18px 0 0;
}
body.mepr-mod-chrome .submit input[type="submit"],
body.mepr-mod-chrome .mp-form-row.submit input[type="submit"] {
	width: 100%;
}

/* Acciones de login/register (links secundarios bajo el form). */
body.mepr-mod-chrome .mepr-login-actions {
	margin-top: 18px;
	padding-top: 18px;
	border-top: 1px solid var( --xb-jacarta-100 );
	font-size: 13px;
	text-align: center;
	color: var( --xb-jacarta-500 );
	font-family: var( --xb-font-body );
}
body.mepr-mod-chrome .mepr-login-actions a {
	margin: 0 6px;
}

/* ----- Mi perfil (account?action=home) — bloque inyectado +
   formulario de edición de perfil. El user reportó que esta sección
   "no tiene estilo, ni botones ni nada" — añadimos ahora reglas
   completas: extras card + heading + form fields + submit button.

   Layout: en desktop (≥900px) el wrapper se vuelve grid 2-col donde
   `[welcome] + [.mepr-account-extras]` ocupan col 1 y la profile-
   wrapper (datos + CTAs Ver pagos/Ver suscripciones/Cambiar contraseña)
   ocupa col 2. El h1 "Perfil" y la sección Privacidad span full-width
   (rows propias). En móvil cae a una columna por defecto.
*/
body.mepr-mod-account .mepr-account-extras {
	max-width: 720px;
	margin: 18px auto 28px;
	padding: 22px 24px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	box-shadow: 0 1px 0 rgba( 13, 16, 45, 0.04 );
	font-family: var( --xb-font-body );
}
/* Wrapper de la profile (datos email + botones View Payments / View
   Subscriptions / Change Password). MP la pinta como
   `.mepr-profile-wrapper > #mepr-profile-details`. Le damos el mismo
   "card" visual que `.mepr-account-extras` para que las 2 cards al
   lado se lean como un par homogéneo. */
body.mepr-mod-account .mepr-profile-wrapper {
	max-width: 720px;
	margin: 18px auto 28px;
	padding: 22px 24px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	box-shadow: 0 1px 0 rgba( 13, 16, 45, 0.04 );
	font-family: var( --xb-font-body );
}
/* En desktop emparejamos las cards de /cuenta/?action=home en 2 columnas.
   El selector aplica al primer ancestor común — probamos `#mepr-account-content`
   primero, fallback a `.mp_wrapper`. h1 y Privacidad span full-width.

   Reparto de columnas (balanceado, el user reportó que la derecha era
   mucho más alta que la izquierda):
     · COL 1 → welcome-message + `.mepr-account-extras` (contador +
       CTAs + heading "Gestiona tu perfil") + `.mepr-account-perfil`
       (Nombre de usuario + Tu cuenta de Discord). El form de perfil va
       JUSTO debajo del heading "Gestiona tu perfil", que es donde se
       espera semánticamente.
     · COL 2 → `.mepr-profile-wrapper` (EMAIL + Ver pagos / Ver
       suscripciones / Cambiar contraseña).
     · FULL WIDTH → `.mepr_page_header` ("Perfil") y `.mepr-account-privacy`.
   Antes `.mepr-account-perfil` no tenía placement explícito y auto-fluía
   apilándose en la derecha, dejando la columna izquierda corta.

   Scoped a `mepr-mod-account-home` (la pestaña perfil): SÓLO ahí
   `#mepr-account-content` contiene estas cards. En las pestañas custom
   (`mis-conjuntas`, `mi-saldo`, `pagos`, `sugerencias`, …) el cuerpo de
   `#mepr-account-content` se sustituye por markup propio full-width — si
   heredaran este `display:grid` de 2 columnas, su único hijo caería en la
   columna izquierda (mitad del ancho) con un hueco a la derecha. */
@media ( min-width: 900px ) {
	body.mepr-mod-account-home #mepr-account-content,
	body.mepr-mod-account-home .mp_wrapper {
		display: grid;
		grid-template-columns: 1fr 1fr;
		column-gap: 24px;
		row-gap: 18px;
		align-items: start;
	}
	/* `.mepr_page_header` ("Perfil") y `.mepr-account-privacy` a todo el
	   ancho — fila propia arriba y abajo del par de columnas. */
	body.mepr-mod-account-home #mepr-account-content > .mepr_page_header,
	body.mepr-mod-account-home .mp_wrapper > .mepr_page_header {
		grid-column: 1 / -1;
		grid-row: 1;
	}
	body.mepr-mod-account-home #mepr-account-content > .mepr-account-privacy,
	body.mepr-mod-account-home .mp_wrapper > .mepr-account-privacy {
		grid-column: 1 / -1;
		grid-row: 5;
	}
	/* Reparto balanceado de las 4 cards en 2 columnas (el user reportó
	   columnas muy dispares):
	     COL 1 → welcome-message (fila 2) + `.mepr-account-extras` (fila 3).
	     COL 2 → `.mepr-profile-wrapper` (fila 2) + `.mepr-account-perfil`
	             (fila 3).
	   Cada columna fluye independiente: cada hijo fija su `grid-row`, así
	   ningún item alto de una columna infla la fila del item corto de la
	   otra (era el origen del hueco). `align-items: start` pega cada card
	   arriba de su celda. */
	body.mepr-mod-account-home #mepr-account-content > .mepr-account-welcome-message,
	body.mepr-mod-account-home .mp_wrapper > .mepr-account-welcome-message,
	body.mepr-mod-account-home #mepr-account-content > .mepr-account-message,
	body.mepr-mod-account-home .mp_wrapper > .mepr-account-message {
		grid-column: 1;
		grid-row: 2;
		max-width: 100%;
		margin: 0;
	}
	body.mepr-mod-account-home #mepr-account-content > .mepr-account-extras,
	body.mepr-mod-account-home .mp_wrapper > .mepr-account-extras {
		grid-column: 1;
		grid-row: 3;
		max-width: 100%;
		margin: 0;
	}
	body.mepr-mod-account-home #mepr-account-content > .mepr-profile-wrapper,
	body.mepr-mod-account-home .mp_wrapper > .mepr-profile-wrapper {
		grid-column: 2;
		grid-row: 2;
		max-width: 100%;
		margin: 0;
	}
	body.mepr-mod-account-home #mepr-account-content > .mepr-account-perfil,
	body.mepr-mod-account-home .mp_wrapper > .mepr-account-perfil {
		grid-column: 2;
		grid-row: 3;
		max-width: 100%;
		margin: 0;
	}
}
body.mepr-mod-account .mepr-account-extras__count {
	margin: 0 0 14px;
	font-size: 15px;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-extras__count strong { color: var( --brand-cta ); }

body.mepr-mod-account .mepr-account-extras__ctas {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0 0 4px;
}
body.mepr-mod-account .mepr-account-extras__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 10px 18px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
/* `!important` necesario para vencer la regla genérica
   `body.mepr-mod-chrome .mp_wrapper a { color: var( --brand-cta ) }`
   (línea 4684), que tiene la misma especificidad de clases + 1 elemento
   más que la nuestra y pintaba el texto del CTA del mismo color que el
   fondo, dejando el botón ilegible. */
body.mepr-mod-account .mepr-account-extras__btn--primary,
body.mepr-mod-chrome a.mepr-account-extras__btn--primary {
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	text-decoration: none !important;
}
body.mepr-mod-account .mepr-account-extras__btn--primary:hover,
body.mepr-mod-account .mepr-account-extras__btn--primary:focus,
body.mepr-mod-chrome a.mepr-account-extras__btn--primary:hover,
body.mepr-mod-chrome a.mepr-account-extras__btn--primary:focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
	outline: none;
}
/* Igual que el `--primary`: hace falta `!important` para vencer la
   regla `body.mepr-mod-chrome .mp_wrapper a` (line 4684), que añade un
   selector de elemento `a` y gana en específicidad. Sin esto el hover
   pintaba fondo morado pero el texto seguía morado (underline morado
   sobre fondo morado), igual de ilegible que el primary. */
body.mepr-mod-account .mepr-account-extras__btn--ghost,
body.mepr-mod-chrome a.mepr-account-extras__btn--ghost {
	background: transparent !important;
	color: var( --brand-cta ) !important;
	border: 1px solid var( --brand-cta ) !important;
	text-decoration: none !important;
}
body.mepr-mod-account .mepr-account-extras__btn--ghost:hover,
body.mepr-mod-account .mepr-account-extras__btn--ghost:focus,
body.mepr-mod-chrome a.mepr-account-extras__btn--ghost:hover,
body.mepr-mod-chrome a.mepr-account-extras__btn--ghost:focus {
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	text-decoration: none !important;
	transform: translateY( -1px );
	outline: none;
}
body.mepr-mod-account .mepr-account-extras__profile-heading {
	margin: 26px 0 10px;
	padding-top: 18px;
	border-top: 1px solid var( --xb-jacarta-100 );
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
/* Sección "Tu perfil" (Nombre de usuario + Tu cuenta de Discord). Vive
   en la columna izquierda de /cuenta/?action=home, bajo `.mepr-account-
   extras`. Le damos el mismo "card" visual que las otras dos cards para
   que las dos columnas se lean homogéneas. Estas reglas (con el prefijo
   `body.mepr-mod-account`) ganan en especificidad al `<style>` inline
   genérico que imprime `account-home-extras.php` como fallback. */
body.mepr-mod-account .mepr-account-perfil {
	margin: 0;
	padding: 22px 24px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	box-shadow: 0 1px 0 rgba( 13, 16, 45, 0.04 );
	font-family: var( --xb-font-body );
}body.mepr-mod-account .mepr-account-perfil__heading {
	margin: 0 0 14px;
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-perfil__field { margin: 0 0 16px; }
body.mepr-mod-account .mepr-account-perfil__field:last-child { margin-bottom: 0; }
body.mepr-mod-account .mepr-account-perfil__label {
	display: block;
	margin: 0 0 6px;
	font-weight: 600;
	font-size: 13px;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-perfil__row {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
}
body.mepr-mod-account .mepr-account-perfil__input {
	flex: 1 1 200px;
	min-width: 0;
	padding: 10px 12px;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 8px;
	font-size: 14px;
	font-family: var( --xb-font-body );
}/* Botón "Guardar" del nombre de usuario — pill púrpura como el resto. */
body.mepr-mod-account .mepr-account-perfil__save {
	padding: 10px 20px;
	border: 0;
	border-radius: 999px;
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.15s ease, transform 0.15s ease;
}
body.mepr-mod-account .mepr-account-perfil__save:hover:not(:disabled),
body.mepr-mod-account .mepr-account-perfil__save:focus:not(:disabled) {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	outline: none;
}
body.mepr-mod-account .mepr-account-perfil__save:disabled { opacity: .55; cursor: default; }
body.mepr-mod-account .mepr-account-perfil__status {
	margin: 7px 0 0;
	font-size: 13px;
	min-height: 1.1em;
}
body.mepr-mod-account .mepr-account-perfil__discord {
	margin: 0;
	display: flex;
	gap: 8px;
	align-items: baseline;
	flex-wrap: wrap;
}
body.mepr-mod-account .mepr-account-perfil__discord-name {
	font-size: 15px;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-perfil__discord-handle,
body.mepr-mod-account .mepr-account-perfil__discord--empty {
	color: var( --xb-jacarta-400 );
	font-size: 13px;
}

/* Sección "Privacidad" — al final de /cuenta/?action=home, después del
   form de perfil MP. Mismo lenguaje visual que `.mepr-account-extras`:
   heading separado por border-top y toggle estilizado como una row de
   form. */
body.mepr-mod-account .mepr-account-privacy {
	margin: 28px 0 8px;
	padding-top: 18px;
	border-top: 1px solid var( --xb-jacarta-100 );
}body.mepr-mod-account .mepr-account-privacy__heading {
	margin: 0 0 12px;
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-privacy__toggle {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	cursor: pointer;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
}body.mepr-mod-account .mepr-account-privacy__checkbox {
	width: 18px;
	height: 18px;
	accent-color: var( --brand-cta );
	cursor: pointer;
}
body.mepr-mod-account .mepr-account-privacy__status {
	margin: 8px 0 0;
	font-family: var( --xb-font-body );
	font-size: 13px;
	color: var( --xb-jacarta-500 );
	min-height: 1.2em; /* reserva alto para evitar layout shift al rellenar */
}

/* ----- Modal de edición de perfil (`#mepr-account-modal`) ----------------
   MemberPress renderiza el form de editar email / nombre / dirección de
   facturación dentro de un `.mepr_modal` que vive como hermano de
   `#mepr-account-content`. Su JS (`mepr-accountjs`, readylaunch/account.js)
   abre/cierra el modal con jQuery `.show()` / `.hide()` (display inline).
   El "estar oculto por defecto" + el "ser un overlay fixed centrado"
   venían ENTERAMENTE de la hoja `css/ui/account.css` de MP — que ahora
   dequeueamos para que /cuenta/ herede la estética del theme. Sin esas
   reglas el modal quedaba visible y suelto (una card flotando bajo el
   contenido). Reponemos aquí el frame del modal con tokens de marca. */
body.mepr-mod-shell .mepr_modal,
body.mepr-mod-chrome .mepr_modal {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 10001;
}
body.mepr-mod-shell .mepr_modal__overlay,
body.mepr-mod-chrome .mepr_modal__overlay {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.55 );
	cursor: pointer;
}
body.mepr-mod-shell .mepr_modal__content_wrapper,
body.mepr-mod-chrome .mepr_modal__content_wrapper {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: 16px;
	box-sizing: border-box;
}
body.mepr-mod-shell .mepr_modal__content,
body.mepr-mod-chrome .mepr_modal__content {
	position: relative;
	width: 100%;
	max-width: 520px;
}
body.mepr-mod-shell .mepr_modal__box,
body.mepr-mod-chrome .mepr_modal__box {
	position: relative;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 28px 26px;
	max-height: 86vh;
	overflow-y: auto;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
}/* Botón cerrar (X) — círculo discreto arriba a la derecha de la caja. */
body.mepr-mod-shell .mepr_modal__close,
body.mepr-mod-chrome .mepr_modal__close {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 34px;
	height: 34px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	background: #ffffff;
	color: var( --xb-jacarta-500 );
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
	transition: background .18s ease, color .18s ease;
}
body.mepr-mod-shell .mepr_modal__close:hover,
body.mepr-mod-chrome .mepr_modal__close:hover {
	background: var( --xb-jacarta-50 );
	color: var( --xb-jacarta-700 );
}/* La X del modal de MP no es `[type=submit]`, así que el override de
   botones de wp_head no le aplica color de fondo morado — bien, queremos
   que se quede como un botón "ghost" discreto. */

/* Form de edición de perfil dentro de /cuenta/?action=home — MP renderiza
   `<form ... class="mp_form_user_account">` con `.mp-form-row` para cada
   campo (nombre, apellido, email, contraseña). Aplicamos el mismo estilo
   de `.mp-form-row` que ya existe pero asegurando que el botón Update
   también se vea como un CTA. */
body.mepr-mod-account .mp-form-row,
body.mepr-mod-account .mepr_account_table .mp-form-row {
	margin: 0 0 14px;
}
body.mepr-mod-account .mp-form-label,
body.mepr-mod-account .mepr_account_table .mp-form-label {
	display: block;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 6px;
}
body.mepr-mod-account .mp-form-row input[type="text"],
body.mepr-mod-account .mp-form-row input[type="email"],
body.mepr-mod-account .mp-form-row input[type="password"],
body.mepr-mod-account .mp-form-row input[type="url"],
body.mepr-mod-account .mp-form-row input[type="tel"],
body.mepr-mod-account .mp-form-row select,
body.mepr-mod-account .mp-form-row textarea {
	width: 100%;
	padding: 10px 14px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	box-sizing: border-box;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
body.mepr-mod-account .mp-form-row input:focus,
body.mepr-mod-account .mp-form-row select:focus,
body.mepr-mod-account .mp-form-row textarea:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
	outline: none;
}
/* Submit del form de Mi perfil — MP usa `.mp-form-submit-row` o
   `.mp-form-row.submit` o un `<input type="submit">` directo. */
body.mepr-mod-account .mp-form-submit-row,
body.mepr-mod-account .mp-form-row.submit {
	margin-top: 20px;
}
body.mepr-mod-account input[type="submit"],
body.mepr-mod-account button[type="submit"],
body.mepr-mod-account .mepr-submit,
body.mepr-mod-account .mp-form-submit-row input[type="submit"],
body.mepr-mod-account .mp-form-row.submit input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 12px 24px;
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
body.mepr-mod-account input[type="submit"]:hover,
body.mepr-mod-account button[type="submit"]:hover,
body.mepr-mod-account .mepr-submit:hover {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
}

/* Section heading "Mi perfil" / "Cuenta" del propio MP. */
body.mepr-mod-account h1,
body.mepr-mod-account h2,
body.mepr-mod-account h3 {
	font-family: var( --xb-font-display );
	color: var( --xb-jacarta-700 );
	font-weight: 600;
}

/* ---------------- Pagos tab — /cuenta/?action=payments -----------------
   Sustituye al listado MP-default (transacciones de membresía) por un
   resumen Conjuntas-céntrico: "Has ahorrado" + Saldo actual en boxes
   y una tabla unificada de toda la actividad. */
body.mepr-mod-pagos .mod-mepr-pagos__title {
	font-family: var( --xb-font-display );
	font-size: 28px;
	font-weight: 800;
	color: var( --xb-jacarta-700 );
	margin: 0 0 18px;
}
body.mepr-mod-pagos .mod-mepr-pagos__hero {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 240px, 1fr ) );
	gap: 14px;
	margin: 0 0 24px;
}
body.mepr-mod-pagos .mod-mepr-pagos__box {
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 18px 20px;
}
body.mepr-mod-pagos .mod-mepr-pagos__box-label {
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-500 );
	margin: 0 0 4px;
}
body.mepr-mod-pagos .mod-mepr-pagos__box-value {
	font-family: var( --xb-font-display );
	font-size: 32px;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.5px;
	margin: 6px 0 4px;
	display: flex;
	align-items: center;
	gap: 8px;
}
body.mepr-mod-pagos .mod-mepr-pagos__box-sub {
	font-family: var( --xb-font-body );
	font-size: 12px;
	color: var( --xb-jacarta-500 );
}
body.mepr-mod-pagos .mod-mepr-pagos__box-sub a {
	color: var( --brand-cta );
	text-decoration: none;
}
body.mepr-mod-pagos .mod-mepr-pagos__box-sub a:hover { text-decoration: underline; }
body.mepr-mod-pagos .mod-mepr-pagos__box--saved .mod-mepr-pagos__box-value { color: #10b981; }
body.mepr-mod-pagos .mod-mepr-pagos__box--saldo .mod-mepr-pagos__box-value { color: var( --xb-jacarta-700 ); }

body.mepr-mod-pagos .mod-mepr-pagos__subtitle {
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
	margin: 12px 0 12px;
}
body.mepr-mod-pagos .mod-mepr-pagos__filters {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 14px;
}
body.mepr-mod-pagos .mod-mepr-pagos__chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1.5px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
body.mepr-mod-pagos .mod-mepr-pagos__chip:hover {
	border-color: var( --brand-cta );
	color: var( --brand-cta );
}
body.mepr-mod-pagos .mod-mepr-pagos__chip[aria-pressed="true"] {
	background: color-mix( in srgb, var( --brand-cta ) 12%, #ffffff );
	border-color: var( --brand-cta );
	color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 18%, transparent );
}
body.mepr-mod-pagos .mod-mepr-pagos__empty {
	padding: 24px 20px;
	background: var( --xb-jacarta-50 );
	border-radius: 12px;
	color: var( --xb-jacarta-500 );
	font-family: var( --xb-font-body );
	font-size: 14px;
}
body.mepr-mod-pagos .mod-mepr-pagos__table-wrap {
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 12px;
	overflow: hidden;
}
body.mepr-mod-pagos .mod-mepr-pagos__table {
	width: 100%;
	border-collapse: collapse;
}
body.mepr-mod-pagos .mod-mepr-pagos__table th,
body.mepr-mod-pagos .mod-mepr-pagos__table td {
	padding: 14px 16px;
	text-align: left;
	border-bottom: 1px solid var( --xb-jacarta-100 );
	font-family: var( --xb-font-body );
	font-size: 14px;
	vertical-align: top;
}
body.mepr-mod-pagos .mod-mepr-pagos__table tr:last-child td { border-bottom: 0; }
body.mepr-mod-pagos .mod-mepr-pagos__table th {
	background: var( --xb-jacarta-50 );
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var( --xb-jacarta-500 );
}
body.mepr-mod-pagos .mod-mepr-pagos__table a {
	color: var( --brand-cta );
	text-decoration: none;
}
body.mepr-mod-pagos .mod-mepr-pagos__table a:hover { text-decoration: underline; }
body.mepr-mod-pagos .mod-mepr-pagos__sub {
	margin-top: 4px;
	font-size: 12px;
	color: var( --xb-jacarta-500 );
}
body.mepr-mod-pagos .mod-mepr-pagos__date {
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
body.mepr-mod-pagos .mod-mepr-pagos__time {
	font-family: var( --xb-font-body );
	font-size: 11px;
	color: var( --xb-jacarta-500 );
	margin-top: 2px;
}
body.mepr-mod-pagos .mod-mepr-pagos__saved {
	margin-top: 4px;
	font-size: 12px;
	color: #10b981;
}
body.mepr-mod-pagos .mod-mepr-pagos__amount {
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
	text-align: right;
	white-space: nowrap;
}
body.mepr-mod-pagos .mod-mepr-pagos__amount--debit  { color: #c0392b; }
body.mepr-mod-pagos .mod-mepr-pagos__amount--credit { color: #10b981; }

/* Stacked importe cell: shows each "wallet" hit (saldo / tarjeta) on
   its own line. For full_saldo / full_stripe / recharge / refund there
   is one row; for partial conjunta payments there are two rows so the
   user sees the split clearly. */
body.mepr-mod-pagos .mod-mepr-pagos__amount-cell {
	text-align: right;
	white-space: nowrap;
}
body.mepr-mod-pagos .mod-mepr-pagos__amount-row {
	display: flex;
	align-items: baseline;
	justify-content: flex-end;
	gap: 8px;
	margin-bottom: 4px;
}
body.mepr-mod-pagos .mod-mepr-pagos__amount-row:last-child { margin-bottom: 0; }
body.mepr-mod-pagos .mod-mepr-pagos__amount-num {
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
}
body.mepr-mod-pagos .mod-mepr-pagos__amount-row--saldo  .mod-mepr-pagos__amount-num,
body.mepr-mod-pagos .mod-mepr-pagos__amount-row--stripe .mod-mepr-pagos__amount-num { color: #c0392b; }
body.mepr-mod-pagos .mod-mepr-pagos__amount-row--credit .mod-mepr-pagos__amount-num { color: #10b981; }
body.mepr-mod-pagos .mod-mepr-pagos__amount-tag {
	font-family: var( --xb-font-body );
	font-size: 11px;
	font-weight: 500;
	color: var( --xb-jacarta-500 );
	background: var( --xb-jacarta-50 );
	padding: 2px 8px;
	border-radius: 999px;
	white-space: nowrap;
}

/* "Mi saldo" hero — dos cajas lado a lado: Saldo disponible (€) +
   Saldo de kiwis (🥝, sólo si el user tiene Discord vinculado).
   Mismo lenguaje visual que las cajas de la pestaña Pagos. */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__hero {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 240px, 1fr ) );
	gap: 14px;
	margin: 0 0 24px;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box {
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 18px 20px;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box-label {
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-500 );
	margin: 0 0 4px;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box-value {
	font-family: var( --xb-font-display );
	font-size: 32px;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.5px;
	margin: 6px 0 4px;
	color: var( --xb-jacarta-700 );
	display: flex;
	align-items: center;
	gap: 8px;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box--euros .mod-mepr-mi-saldo__box-value { color: #10b981; }
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box-sub {
	font-family: var( --xb-font-body );
	font-size: 12px;
	color: var( --xb-jacarta-500 );
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box-link {
	display: inline-block;
	margin-top: 8px;
	font-family: var( --xb-font-body );
	font-size: 12px;
	color: var( --brand-cta );
	text-decoration: none;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__box-link:hover { text-decoration: underline; }

/* "Mi saldo" — explicador de qué es el saldo, editable desde
   Ajustes → Contenido. Card sutil debajo del importe; mismo texto que
   el embed del bot al pulsar "Mi saldo" en el panel de Discord.
   Va en italic (preferencia del admin). */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer {
	margin-top: 18px;
	padding: 16px 20px;
	background: var( --xb-jacarta-50 );
	border: 1px solid var( --xb-jacarta-100 );
	border-left: 3px solid var( --brand-cta );
	border-radius: 10px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-style: italic;
	color: var( --xb-jacarta-700 );
	line-height: 1.55;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer p { margin: 0 0 10px; }
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer p:last-child { margin-bottom: 0; }
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer strong { color: var( --xb-jacarta-700 ); font-weight: 700; font-style: normal; }
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer a {
	color: var( --brand-cta );
	text-decoration: underline;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__explainer a:hover { color: var( --brand-cta-hover ); }
/* Importe del saldo — bigger green emphasis dentro del párrafo
   "Tienes X€ de saldo en tu hucha personal de Conjuntas.org". */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__line {
	font-family: var( --xb-font-body );
	font-size: 16px;
	color: var( --xb-jacarta-700 );
	margin: 6px 0 0;
	line-height: 1.5;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount {
	display: inline-block;
	font-family: var( --xb-font-display );
	font-size: 32px;
	font-weight: 800;
	color: #10b981; /* green */
	vertical-align: middle;
	margin: 0 4px;
	letter-spacing: -0.5px;
}

/* Formulario de recarga — bajo el explainer, stacked en columna:
   label arriba, input pill ancho-fijo, botón CTA del mismo ancho. */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__recharge {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
	margin: 22px 0 12px;
	--cjt-recharge-w: 280px;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__recharge-heading {
	font-family: var( --xb-font-display );
	font-size: 16px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
	margin: 0;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-label {
	font-family: var( --xb-font-body );
	font-size: 14px;
	font-weight: 500;
	color: var( --xb-jacarta-500 );
	margin: 0;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-field {
	position: relative;
	display: flex;
	align-items: center;
	width: var( --cjt-recharge-w );
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-input {
	width: 100%;
	height: 48px;
	padding: 10px 36px 10px 18px; /* right padding reservado para el € */
	font-family: var( --xb-font-body );
	font-size: 15px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	box-sizing: border-box;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
	/* Quitar las flechas spinner del number input. */
	-moz-appearance: textfield;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-input::-webkit-outer-spin-button,
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-input:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
	outline: none;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__amount-suffix {
	position: absolute;
	right: 18px;
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
	color: var( --xb-jacarta-500 );
	pointer-events: none;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__recharge-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var( --cjt-recharge-w );
	padding: 0 16px;
	height: 48px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var( --brand-cta-text );
	background: var( --brand-cta );
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__recharge-btn:hover:not( [disabled] ) {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__recharge-btn[disabled] {
	background: var( --xb-jacarta-100 );
	color: var( --xb-jacarta-500 );
	cursor: not-allowed;
	box-shadow: none;
}

/* Inline validation errors (red boxed) — sustituyen al popup nativo
   del browser para que el mensaje viva dentro del formulario. */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__err {
	max-width: var( --cjt-recharge-w );
	margin: -4px 0 2px;
	padding: 8px 12px;
	background: color-mix( in srgb, #ef4444 10%, #ffffff );
	border: 1px solid color-mix( in srgb, #ef4444 35%, transparent );
	border-radius: 8px;
	font-family: var( --xb-font-body );
	font-size: 12px;
	font-weight: 600;
	color: #b91c1c;
	line-height: 1.4;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__err[hidden] { display: none; }

/* Checkbox de términos — obligatorio para habilitar el botón. */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__terms {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	max-width: var( --cjt-recharge-w );
	margin: 4px 0 2px;
	font-family: var( --xb-font-body );
	font-size: 13px;
	line-height: 1.45;
	color: var( --xb-jacarta-500 );
	cursor: pointer;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__terms input[type="checkbox"] {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin: 2px 0 0;
	accent-color: var( --brand-cta );
	cursor: pointer;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__terms-link {
	color: var( --brand-cta );
	text-decoration: underline;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__terms-link:hover {
	color: var( --brand-cta-hover );
}

/* Flash messages (redirect-back de la pasarela). */
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__flash {
	margin: 12px 0;
	padding: 12px 16px;
	border-radius: 10px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.5;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__flash.--ok {
	background: color-mix( in srgb, #10b981 12%, #ffffff );
	border: 1px solid color-mix( in srgb, #10b981 40%, transparent );
	color: #047857;
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__flash.--info {
	background: var( --xb-jacarta-50 );
	border: 1px solid var( --xb-jacarta-100 );
	color: var( --xb-jacarta-700 );
}
body.mepr-mod-mi-saldo .mod-mepr-mi-saldo__flash.--err {
	background: color-mix( in srgb, #ef4444 10%, #ffffff );
	border: 1px solid color-mix( in srgb, #ef4444 35%, transparent );
	color: #b91c1c;
}

/* Edit-modal del Mi perfil — el template readylaunch SIEMPRE pinta el
   label "Change your billing address" + el <fieldset.mp-address-group>,
   pero los inputs sólo se renderizan si MP `show_address_on_account` está
   ON. Si está OFF (default en este sitio) queda un cuadrado vacío
   confuso. Ocultamos label + fieldset cuando el fieldset no contiene
   ningún `.mp-form-row` (= ningún input de dirección renderizado). */
body.mepr-mod-account .mp-address-group:not( :has( .mp-form-row ) ):not( :has( input:not([type="hidden"]) ) ):not( :has( select ) ):not( :has( textarea ) ) {
	display: none;
}
body.mepr-mod-account #mp-address-group-label:has(
	+ .mp-address-group:not( :has( .mp-form-row ) ):not( :has( input:not([type="hidden"]) ) ):not( :has( select ) ):not( :has( textarea ) )
) {
	display: none;
}
body.mepr-mod-account h1 { font-size: 28px; line-height: 1.2; margin: 0 0 16px; }
body.mepr-mod-account h2 { font-size: 22px; line-height: 1.25; margin: 24px 0 12px; }
body.mepr-mod-account h3 { font-size: 17px; line-height: 1.3; margin: 18px 0 10px; }
/* CATCH-ALL para form fields dentro de /cuenta/ — cualquier input,
   select, textarea, sin importar el wrapper (mp-form-row, mepr-rl-*,
   .mepr-form-field, etc.). Sin esto, ReadyLaunch renderiza con sus
   propias clases que nuestro CSS específico de `.mp-form-row` no cubría
   → campos sin estilo. El user reportó: "Mi perfil has no proper style". */
body.mepr-mod-account #mepr-account-content input[type="text"],
body.mepr-mod-account #mepr-account-content input[type="email"],
body.mepr-mod-account #mepr-account-content input[type="password"],
body.mepr-mod-account #mepr-account-content input[type="url"],
body.mepr-mod-account #mepr-account-content input[type="tel"],
body.mepr-mod-account #mepr-account-content input[type="number"],
body.mepr-mod-account #mepr-account-content select,
body.mepr-mod-account #mepr-account-content textarea {
	width: 100%;
	max-width: 480px;
	padding: 10px 14px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	box-sizing: border-box;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
body.mepr-mod-account #mepr-account-content input:focus,
body.mepr-mod-account #mepr-account-content select:focus,
body.mepr-mod-account #mepr-account-content textarea:focus {
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px color-mix( in srgb, var( --brand-cta ) 22%, transparent );
	outline: none;
}/* Labels dentro de cualquier wrapper de MP. */
body.mepr-mod-account #mepr-account-content label {
	display: block;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 6px;
}/* Párrafos dentro de account: line-height legible. */
body.mepr-mod-account #mepr-account-content p {
	margin: 0 0 12px;
	font-family: var( --xb-font-body );
	font-size: 15px;
	line-height: 1.55;
	color: var( --xb-jacarta-700 );
}/* Hr separadores de secciones MP — más sutiles. */
body.mepr-mod-account #mepr-account-content hr {
	border: 0;
	border-top: 1px solid var( --xb-jacarta-100 );
	margin: 24px 0;
}/* Botones genéricos dentro del account: NO los promovemos a CTA pill —
   eso pisaba todos los toggles de mis-conjuntas, los tabs, los íconos,
   etc. Mantenemos sólo el estilo del SUBMIT del form de Mi perfil
   (cubierto en la regla `body.mepr-mod-account input[type="submit"]`
   más arriba). El user lo pidió: "you have put all CTA buttons in all
   options, go back to what it was". */

/* ==================================================================
 * Mi perfil — estilo TARGETED a las clases reales de MP ReadyLaunch
 * (`mepr-profile-wrapper`, `mepr-profile-details__*`, `mepr-button`).
 * Estructura del template `readylaunch/account/home.php`:
 *   <h1.mepr_page_header>Profile</h1>
 *   <div.mepr-account-welcome-message>
 *   <div.mepr-profile-wrapper>
 *     <div#mepr-profile-details>
 *       <dl.mepr-profile-details__list>
 *         <dt> Name <button.mepr-profile-details__button> ✎ </button></dt>
 *         <dd.mepr-profile-details__content> ... </dd>
 *       </dl>
 *       <ul.mepr-profile-wrapper__footer>
 *         <li><a.mepr-button.btn-outline> ... </a></li>
 *       </ul>
 *     </div>
 *   </div>
 * ================================================================ */
body.mepr-mod-account .mepr_page_header {
	font-family: var( --xb-font-display );
	font-size: 28px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	margin: 0 0 18px;
}
body.mepr-mod-account .mepr-account-welcome-message {
	margin: 0 0 24px;
	padding: 16px 20px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 14px;
	font-family: var( --xb-font-body );
	font-size: 15px;
	color: var( --xb-jacarta-500 );
}
/* Profile listing como tarjeta limpia. */
body.mepr-mod-account .mepr-profile-wrapper {
	display: flex;
	flex-wrap: wrap;
	gap: 32px;
	align-items: flex-start;
}
body.mepr-mod-account #mepr-profile-details {
	flex: 1 1 480px;
	min-width: 0;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 24px 28px;
	box-shadow: 0 1px 0 rgba( 13, 16, 45, 0.04 );
}
body.mepr-mod-account .mepr-profile-details__list {
	margin: 0;
}
body.mepr-mod-account .mepr-profile-details__list dt {
	display: flex;
	align-items: center;
	gap: 6px;
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 600;
	color: var( --xb-jacarta-500 );
	text-transform: uppercase;
	letter-spacing: 0.4px;
	margin: 18px 0 4px;
}
body.mepr-mod-account .mepr-profile-details__list dt:first-child { margin-top: 0; }
body.mepr-mod-account .mepr-profile-details__list dd.mepr-profile-details__content {
	margin: 0 0 8px;
	padding: 0;
	font-family: var( --xb-font-body );
	font-size: 16px;
	font-weight: 500;
	color: var( --xb-jacarta-700 );
	line-height: 1.45;
}
/* Botón "edit" (lápiz) — pequeño icono, NO CTA. */
body.mepr-mod-account .mepr-profile-details__button,
body.mepr-mod-account .mepr-profile-details__button.btn,
body.mepr-mod-account .mepr-profile-details__button.btn-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	background: transparent;
	border: 0;
	border-radius: 6px;
	cursor: pointer;
	color: var( --xb-jacarta-400 );
	transition: background 0.15s ease, color 0.15s ease;
}
body.mepr-mod-account .mepr-profile-details__button:hover,
body.mepr-mod-account .mepr-profile-details__button:focus {
	background: color-mix( in srgb, var( --brand-cta ) 8%, transparent );
	color: var( --brand-cta );
	outline: none;
}
body.mepr-mod-account .mepr-profile-details__icon {
	width: 14px;
	height: 14px;
	fill: currentColor;
}
body.mepr-mod-account .mepr-profile-details__icon path { fill: currentColor !important; }

/* Footer de Mi perfil — links "View Payments / Subscriptions / Change
   Password" como botones outline pero con tokens del theme. */
body.mepr-mod-account .mepr-profile-wrapper__footer {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	list-style: none;
	margin: 24px 0 0;
	padding: 0;
}
body.mepr-mod-account .mepr-profile-wrapper__footer li { margin: 0; }
body.mepr-mod-account .mepr-button.btn-outline,
body.mepr-mod-account a.mepr-button.btn-outline {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 9px 16px;
	background: transparent;
	color: var( --brand-cta );
	border: 1px solid var( --brand-cta );
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.3px;
	text-decoration: none;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
body.mepr-mod-account .mepr-button.btn-outline:hover,
body.mepr-mod-account a.mepr-button.btn-outline:hover {
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	transform: translateY( -1px );
}
/* Variante FILLED de `.mepr-button` — el "primary" CTA de la perfil
   (p.ej. el primer botón de /cuenta/?action=home). Sin esta regla MP
   pintaba un fondo morado pero el texto heredaba `color: var(--brand-cta)`
   de `.mp_wrapper a` → texto morado sobre fondo morado = ilegible.
   Aquí forzamos texto blanco vía `--brand-cta-text`. */
body.mepr-mod-chrome .mepr-button:not(.btn-outline),
body.mepr-mod-chrome a.mepr-button:not(.btn-outline),
body.mepr-mod-chrome button.mepr-button:not(.btn-outline),
body.mepr-mod-account .mepr-button:not(.btn-outline),
body.mepr-mod-account a.mepr-button:not(.btn-outline),
body.mepr-mod-account button.mepr-button:not(.btn-outline) {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	padding: 10px 18px !important;
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	border: 1px solid var( --brand-cta ) !important;
	border-radius: 999px !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 13px !important;
	font-weight: 600 !important;
	letter-spacing: 0.3px !important;
	text-transform: none !important;
	text-decoration: none !important;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
body.mepr-mod-chrome .mepr-button:not(.btn-outline):hover,
body.mepr-mod-chrome .mepr-button:not(.btn-outline):focus,
body.mepr-mod-chrome a.mepr-button:not(.btn-outline):hover,
body.mepr-mod-chrome a.mepr-button:not(.btn-outline):focus,
body.mepr-mod-account .mepr-button:not(.btn-outline):hover,
body.mepr-mod-account .mepr-button:not(.btn-outline):focus,
body.mepr-mod-account a.mepr-button:not(.btn-outline):hover,
body.mepr-mod-account a.mepr-button:not(.btn-outline):focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent ) !important;
	outline: none !important;
}
/* Imagen de bienvenida (si está activa en MP). */
body.mepr-mod-account #mepr-profile-image {
	flex: 0 0 240px;
	max-width: 240px;
}
body.mepr-mod-account #mepr-profile-image img {
	width: 100%;
	height: auto;
	border-radius: 14px;
}

/* Modal de edición del perfil — fields del modal + botón Save Changes.
   Chrome del modal: card blanca con padding generoso, ancho cómodo,
   borde sutil + sombra suave. El user lo pidió: "doesnt look too
   stylish, fix it to make it more stylish". */
body.mepr-mod-account .mepr_modal__content {
	position: relative;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 32px 36px;
	box-shadow: 0 12px 32px -16px rgba( 13, 16, 45, 0.18 );
	max-width: 560px;
	margin: 0 auto;
}/* `.mepr_modal__box` es el wrapper interno — quitar background/borde
   redundantes que MP-Pro le pone por defecto. */
body.mepr-mod-account .mepr_modal__box {
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
	padding: 0 !important;
}
/* Bloque de error MP — visible SÓLO cuando JS lo activa quitando la
   class `hidden`. Sin esto el SVG del triángulo aparece flotando solo
   (sin texto) en la parte superior del modal. Trip-state defensive:
   ocultar la version `.hidden`, la `[hidden]` y cualquier `.mepr_pro_error`
   sin contenido renderizable en sus children. */
body.mepr-mod-account .mepr_modal .mepr_pro_error.hidden,
body.mepr-mod-account .mepr_modal .mepr_pro_error[hidden] {
	display: none !important;
}
body.mepr-mod-account .mepr_modal .mepr_pro_error:not(.hidden) {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px 14px;
	margin: 0 0 18px;
	background: #fff5f5;
	border: 1px solid #fed7d7;
	border-radius: 10px;
	color: #c53030;
}
body.mepr-mod-account .mepr_modal .mepr_pro_error svg { flex: 0 0 auto; }
body.mepr-mod-account .mepr_modal .mepr_pro_error ul { margin: 0; padding-left: 18px; }
/* Si MP-Pro renderiza un `mepr_pro_error` SIN children visibles (sólo
   el SVG, sin <li> populated), también lo escondemos — el SVG solo es
   visualmente ruido. `:has()` (Safari/Chrome/FF 121+) detecta lista
   vacía o sin <li>. */
body.mepr-mod-account .mepr_modal .mepr_pro_error:has( ul:empty ),
body.mepr-mod-account .mepr_modal .mepr_pro_error:has( ul:not(:has(li)) ) {
	display: none !important;
}

/* Botón close (X) — top-right del modal con hit area cómoda y hover
   accesible. Por defecto MP lo deja como un <button> raw en la
   esquina sin estilizar, casi invisible. */
body.mepr-mod-account .mepr_modal__close {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 36px;
	height: 36px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	color: var( --xb-jacarta-500 );
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
body.mepr-mod-account .mepr_modal__close:hover,
body.mepr-mod-account .mepr_modal__close:focus {
	background: var( --xb-jacarta-50 );
	color: var( --xb-jacarta-700 );
	border-color: var( --xb-jacarta-200 );
	outline: 0;
}
/* Labels uniformes en el modal (Email, Cambia tu dirección, Nombre…). */
body.mepr-mod-account .mepr_modal .mp-form-label,
body.mepr-mod-account .mepr_modal #mp-address-group-label,
body.mepr-mod-account .mepr_modal label {
	display: block;
	margin-bottom: 6px;
	font-family: var( --xb-font-body );
	font-size: 13px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
/* Si MP-Pro renderiza el bloque "Change your billing address:*" + un
   <fieldset> VACÍO (caso `show_address_on_account = false`), ocultamos
   ambos para no dejar un label solitario + input fantasma debajo del
   email. `:has()` detecta el fieldset que NO tiene ningún input/select. */
body.mepr-mod-account .mepr_modal .mp-address-group:not(:has( input, select, textarea )),
body.mepr-mod-account .mepr_modal #mp-address-group-label:has( + .mp-address-group:not(:has(input, select, textarea)) ) {
	display: none !important;
}

/* Inputs del modal — heredan el styling del theme (los que ya
   definimos en `.mepr-form-input` general), pero forzamos espaciado
   y radius consistentes en este contexto. */
body.mepr-mod-account .mepr_modal .mp-form-row {
	margin-bottom: 18px;
}
body.mepr-mod-account .mepr_modal .mepr-form-input {
	width: 100%;
	padding: 10px 14px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-700 );
}
body.mepr-mod-account .mepr_modal .mepr-form-input:focus {
	outline: 0;
	border-color: var( --brand-cta );
	box-shadow: 0 0 0 3px rgba( 131, 88, 255, 0.12 );
}
/* Botón Save Changes — empujado un poco hacia abajo para respirar
   del último campo del form. */
body.mepr-mod-account .mepr_modal input[type="submit"].btn-primary {
	margin-top: 8px;
}
body.mepr-mod-account .mepr_modal .btn.btn-primary,
body.mepr-mod-account .mepr_modal input[type="submit"].btn-primary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 22px;
	background: var( --brand-cta );
	color: var( --brand-cta-text );
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
body.mepr-mod-account .mepr_modal .btn.btn-primary:hover {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 8px 16px -6px rgba( 131, 88, 255, 0.45 );
}
/* Mensaje "unauthorized" que MP pinta cuando un visitante intenta abrir
   una URL restringida: queda como texto centrado, sin caja blanca con
   borde — el form de login que aparece debajo ya da el marco visual.
   Strip TAMBIÉN del wrapper `.mp_wrapper` ancestro (MP lo pinta con
   `alignwide` + margin-top 2em + en algunas integraciones bg blanco) —
   sin esto el aviso aparecía dentro de una tarjeta blanca redundante
   por encima del card del login. `:has()` limita el strip al caso de
   un wrapper que contiene el aviso unauth (no afecta a otros
   `.mp_wrapper` como el login form o el profile). */
body.mepr-mod-chrome .mp_wrapper:has( > .mepr-unauthorized-excerpt ),
body.mepr-mod-chrome .mp_wrapper.alignwide:has( > .mepr-unauthorized-excerpt ) {
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	padding: 0 !important;
	margin-top: 0 !important;
}
body.mepr-mod-chrome .mepr-unauthorized-excerpt {
	max-width: 720px !important;
	margin: 0 auto 16px !important;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-500 );
	text-align: center;
}
/* Dentro de `.mepr-unauthorized-excerpt`, MP renderiza el aviso como
   `.mepr_pro_error > svg + .mepr_pro_error_content > p`. La regla genérica
   de `.mepr_pro_error_content` le da un card blanco con borde — aquí lo
   neutralizamos para que el aviso quede flotando como texto plano (el
   form de login que aparece debajo ya da el marco visual). */
body.mepr-mod-chrome .mepr-unauthorized-excerpt .mepr_pro_error {
	padding: 0 !important;
	margin: 0 !important;
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
	gap: 10px;
}
body.mepr-mod-chrome .mepr-unauthorized-excerpt .mepr_pro_error_content {
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	color: var( --xb-jacarta-500 ) !important;
}
body.mepr-mod-chrome .mepr-unauthorized-excerpt .mepr_pro_error_content p {
	margin: 0 !important;
}

/* Tablas dentro de /cuenta/ (subscriptions, payments). */
body.mepr-mod-chrome .mp_wrapper table {
	width: 100%;
	border-collapse: collapse;
	margin: 12px 0 18px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 12px;
	overflow: hidden;
}
body.mepr-mod-chrome .mp_wrapper table th,
body.mepr-mod-chrome .mp_wrapper table td {
	padding: 10px 14px;
	text-align: left;
	border-bottom: 1px solid var( --xb-jacarta-100 );
	font-family: var( --xb-font-body );
	font-size: 13px;
}
body.mepr-mod-chrome .mp_wrapper table th {
	background: var( --xb-jacarta-50 );
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var( --xb-jacarta-500 );
}
body.mepr-mod-chrome .mp_wrapper table tr:last-child th,
body.mepr-mod-chrome .mp_wrapper table tr:last-child td {
	border-bottom: 0;
}

/* Columna Actions en /cuenta/?action=subscriptions — botones inline en
   vez del kebab + tooltip default de MP-Pro (que renderizaba un cuadrado
   vacío con el texto fugado debajo). El theme override en
   memberpress/readylaunch/account/subscriptions.php sustituye el wrapper
   por <div class="cjt-mp-actions__buttons">…</div> conteniendo los
   anchors generados por print_user_account_subscription_row_actions. */
body.mepr-mod-chrome .cjt-mp-actions__buttons {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-row-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 8px 16px;
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: 0.3px;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 999px;
	border: 1.5px solid transparent;
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
/* Primary CTA púrpura: Update / Renew / Re-subscribe / Resume / Upgrade. */
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-update,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-renew,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-resume,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-upgrade {
	background: var( --brand-cta );
	border-color: var( --brand-cta );
	color: var( --brand-cta-text );
}
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-update:hover,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-renew:hover,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-resume:hover,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-upgrade:hover {
	background: var( --brand-cta-hover );
	border-color: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
}
/* Secondary outline para acciones destructivas: Cancel / Pause / Suspend. */
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-cancel,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-suspend {
	background: #ffffff;
	border-color: #ef4444;
	color: #ef4444;
}
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-cancel:hover,
body.mepr-mod-chrome .cjt-mp-actions__buttons a.mepr-account-suspend:hover {
	background: #ef4444;
	color: #ffffff;
	transform: translateY( -1px );
}

/* ===================================================================
 * /cuenta/?action=mis-notificaciones — botones del tab.
 *
 * El markup de la pestaña (tabla de eventos + sección "Notificaciones
 * de conjuntas nuevas") lo inyecta `modificacion-memberpress/inc/
 * mis-notificaciones-tab.php`. La tabla y los headings heredan estética
 * del chrome de cuenta, pero los <button> propios del tab —
 * "+ Añadir aviso personalizado", "Guardar preferencias", "Guardar
 * aviso", "Cancelar" — no tenían NINGUNA regla en este theme (la CSS
 * vieja vivía en el theme inactivo `conjuntas/`) y salían como botones
 * de navegador en bruto. Aquí los estilamos con el patrón pill del
 * sitio (mismo lenguaje que `.cjt-mp-actions__buttons a`).
 * =================================================================== */
body.mepr-mod-mis-notificaciones .mod-mepr-mis-notif__btn,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__add-toggle,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__save,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__cancel {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 24px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 999px;
	border: 1.5px solid transparent;
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
/* Primary púrpura: guardar preferencias + guardar aviso. */
body.mepr-mod-mis-notificaciones .mod-mepr-mis-notif__btn,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__save {
	background: var( --brand-cta );
	border-color: var( --brand-cta );
	color: var( --brand-cta-text );
}
body.mepr-mod-mis-notificaciones .mod-mepr-mis-notif__btn:hover,
body.mepr-mod-mis-notificaciones .mod-mepr-mis-notif__btn:focus,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__save:hover,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__save:focus {
	background: var( --brand-cta-hover );
	border-color: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	outline: none;
}
/* Secundario outline: "+ Añadir aviso personalizado" y "Cancelar". */
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__add-toggle,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__cancel {
	background: transparent;
	border-color: var( --brand-cta );
	color: var( --brand-cta );
}
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__add-toggle:hover,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__add-toggle:focus,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__cancel:hover,
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__cancel:focus {
	background: var( --brand-cta );
	border-color: var( --brand-cta );
	color: var( --brand-cta-text );
	transform: translateY( -1px );
	outline: none;
}
/* El toggle "+ Añadir aviso" lleva un poco de aire arriba para separarse
   de la lista de avisos que tiene encima. */
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__add-toggle {
	margin-top: 12px;
}
/* Botón "Eliminar" de cada aviso ya creado: discreto, texto-link rojo. */
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__delete {
	background: transparent;
	border: 0;
	padding: 4px 6px;
	font-family: var( --xb-font-body );
	font-size: 13px;
	font-weight: 600;
	color: #ef4444;
	cursor: pointer;
}
body.mepr-mod-mis-notificaciones .mod-mepr-custom-alerts__delete:hover {
	text-decoration: underline;
}

/* ===================================================================
 * /cuenta/?action=subscriptions — modal de confirmación de cancelación.
 *
 * MemberPress imprime, junto al enlace "Cancelar", un bloque
 * `.mepr-white-popup.mfp-hide` con la confirmación inline ("Are you sure
 * you want to cancel…" + Yes/No). Esa confirmación DEBE estar oculta: la
 * regla `display:none` venía de `.mfp-hide` en `magnific-popup.css`, hoja
 * que `topbar-en-checkout.php` desregistra junto al resto de CSS de MP.
 * Sin ella el bloque se quedaba visible inline, en inglés y feo.
 *
 * Aquí: 1) ocultamos el bloque inline de MP; 2) estilamos el modal
 * propio (`.cjt-cancel-modal`, markup en `modificacion-memberpress/inc/
 * cancelar-suscripcion-modal.php`) con el lenguaje visual de `.mepr_modal`
 * del theme. El JST de ese fichero lo abre al click en "CANCELAR".
 * =================================================================== */
/* Ocultar la confirmación inline nativa de MP en el tab de suscripciones. */
body.mepr-mod-account-subscriptions .mepr-white-popup,
body.mepr-mod-account-subscriptions .mepr-cancel-sub-text,
body.mepr-mod-account-subscriptions .mepr-cancel-sub-buttons {
	display: none !important;
}

/* Overlay + caja del modal propio. Mismo frame que `.mepr_modal__*`. */
.cjt-cancel-modal {
	position: fixed;
	inset: 0;
	z-index: 100010;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	box-sizing: border-box;
}
/* User 2026-06-06: `!important` so the hidden attribute always wins over any
   higher-specificity rule that might set display on this element. The
   modal's JS in `inc/cancelar-suscripcion-modal.php` toggles `modal.hidden`
   directly and does NOT add a body class — so we cannot use the
   `body:not(.X-open)` pattern as a bfcache defense. The companion JS
   pageshow handler in `partials/confirm-modal.php` re-applies `hidden` on
   history restore as the bfcache safety net. */
.cjt-cancel-modal[hidden] { display: none !important; }
.cjt-cancel-modal__overlay {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.55 );
	cursor: pointer;
}
.cjt-cancel-modal__box {
	position: relative;
	width: 100%;
	max-width: 440px;
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 30px 28px 26px;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	text-align: center;
}.cjt-cancel-modal__close {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 34px;
	height: 34px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 999px;
	background: #ffffff;
	color: var( --xb-jacarta-500 );
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	transition: background .15s ease, color .15s ease;
}
.cjt-cancel-modal__close:hover {
	background: var( --xb-jacarta-50 );
	color: var( --xb-jacarta-700 );
}.cjt-cancel-modal__title {
	margin: 4px 0 10px;
	font-family: var( --xb-font-display );
	font-size: 19px;
	font-weight: 700;
	line-height: 1.3;
	color: var( --xb-jacarta-700 );
}.cjt-cancel-modal__text {
	margin: 0 0 22px;
	font-size: 14px;
	line-height: 1.5;
	color: var( --xb-jacarta-500 );
}.cjt-cancel-modal__actions {
	display: flex;
	gap: 10px;
	justify-content: center;
	flex-wrap: wrap;
}
.cjt-cancel-modal__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 11px 22px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 999px;
	border: 1.5px solid transparent;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
/* "No" — outline neutro, mantiene la suscripción. */
.cjt-cancel-modal__btn--ghost {
	background: transparent;
	border-color: var( --xb-jacarta-200 );
	color: var( --xb-jacarta-700 );
}.cjt-cancel-modal__btn--ghost:hover,
.cjt-cancel-modal__btn--ghost:focus {
	background: var( --xb-jacarta-50 );
	outline: none;
}/* "Sí, cancelar" — acción destructiva, rojo. */
.cjt-cancel-modal__btn--danger {
	background: #ef4444;
	border-color: #ef4444;
	color: #ffffff;
}
.cjt-cancel-modal__btn--danger:hover,
.cjt-cancel-modal__btn--danger:focus {
	background: #dc2626;
	border-color: #dc2626;
	color: #ffffff;
	transform: translateY( -1px );
	outline: none;
}

/* ===================================================================
 * single-conjunta.php — single de un CPT `conjunta`.
 * Layout: grid 3-col edge-to-edge; banda gris en hero; card sticky a
 * la derecha que atraviesa hero + body, igual al patrón LearnPress
 * single-course.
 *
 * El template se portó del theme antiguo `conjuntas/`. Las clases y
 * markup se mantienen idénticos, pero los TOKENS se mapean al sistema
 * actual del theme (xb-jacarta-* + brand-cta + xb-font-*) para que
 * fonts, colores y bordes hereden del theme actual:
 *   --brand-bg          → --xb-jacarta-700
 *   --brand-fg          → #ffffff
 *   --brand-accent      → --brand-cta
 *   --brand-accent-hover→ --brand-cta-hover
 *   --brand-positive    → verde fijo (#10b981) para estado "abierta"
 *   --brand-font        → --xb-font-display
 *   --brand-body-font   → --xb-font-body
 *
 * Constantes locales `--content-pad` / `--content-bot` se definen aquí
 * porque sólo las usa este template — el resto del theme no tiene un
 * `content-bot` global.
 * =================================================================== */
.single-conjunta__main {
	--content-pad: 24px;
	--content-bot: 96px;
	display: grid;
	grid-template-columns:
		[full-start] minmax( var( --content-pad ), 1fr )
		[content-start] minmax( 0, 1180px ) [content-end]
		minmax( var( --content-pad ), 1fr ) [full-end];
	row-gap: 0;
}

/* Banda gris detrás del hero (fila 1, full-bleed). */
.single-conjunta__hero-bg {
	grid-column: full-start / full-end;
	grid-row: 1;
	background: var( --xb-jacarta-50 );
}

.single-conjunta__hero-text {
	grid-column: content-start / content-end;
	grid-row: 1;
	/* Padding-right reservado para la card (360px) + gap visual (48px). */
	padding: 48px 408px 48px 0;
	/* `flow-root` confina el float-right de `.single-conjunta__user-card`
	   dentro del hero-text — sin esto, la card podría sangrar por debajo
	   del header y solaparse con la descripción del body. */
	display: flow-root;
}
.single-conjunta__hero-text > * + * { margin-top: 14px; }

.single-conjunta__title {
	font-family: var( --xb-font-display );
	font-size: clamp( 32px, 5vw, 48px );
	line-height: 1.1;
	font-weight: 600;
	letter-spacing: -0.01em;
	margin: 8px 0 4px;
	color: var( --xb-jacarta-700 );
}

.single-conjunta__byline,
.single-conjunta__updated,
.single-conjunta__idioma {
	font-family: var( --xb-font-body );
	font-size: 14px;
	color: var( --xb-jacarta-500 );
	margin: 0;
}
.single-conjunta__byline strong { color: var( --xb-jacarta-700 ); font-weight: 700; }.single-conjunta__byline-icon {
	display: inline-block;
	vertical-align: -2px;
	margin: 0 4px 0 2px;
	color: #5865F2; /* Discord blurple — el logo gana reconocimiento de marca */
}

/* --- Card lateral --------------------------------------------------- */
.single-conjunta__sidebar {
	grid-column: content-start / content-end;
	grid-row: 1 / span 2;
	justify-self: end;
	align-self: start;
	width: 360px;
	max-width: 100%;
	margin-top: 48px;
	/* User 2026-05-29: la card lateral ya NO es sticky — el user pidió
	   quitar la stickiness del single de conjunta; scrollea con la página. */
}

/* Borde rainbow animado — mismo lenguaje que las coverflow cards
   above-the-fold (`.page-home__cf-slide`) y las cards del Centro de
   ayuda (`.page-help__cat-card`). Técnica de un solo elemento con
   doble background-clip:
     - Capa interior `padding-box`: relleno sólido blanco (jacarta-700
       en dark) — el contenido se ve nítido sin tinte rainbow.
     - Capa exterior `border-box`: `--cjt-rainbow-gradient` tilea con
       repeat-x — sólo asoma en los 2px del border transparente.
     - `cjt-card-rainbow` (6s linear infinite) hace correr el gradient.
   `overflow: hidden` sigue funcionando (la card-media queda recortada
   en las esquinas internas redondeadas). */
.single-conjunta__card {
	border: 2px solid transparent;
	border-radius: 1.25rem; /* mismo rounded-2.5xl que el resto de cards */
	background-image:
		linear-gradient( #ffffff, #ffffff ),
		var( --cjt-rainbow-gradient );
	background-origin: border-box;
	background-clip: padding-box, border-box;
	background-size: auto, 200% 100%;
	background-repeat: no-repeat, repeat-x;
	animation: cjt-card-rainbow 6s linear infinite;
	overflow: hidden;
	box-shadow: 0 8px 24px -10px rgba( 13, 16, 45, 0.08 );
	font-family: var( --xb-font-body );
	transition: box-shadow 0.25s ease, transform 0.25s ease;
}@media ( prefers-reduced-motion: reduce ) {
	.single-conjunta__card { animation: none; }
}
.single-conjunta__card:hover {
	box-shadow: 0 8px 24px -10px rgba( 13, 16, 45, 0.18 );
	transform: translateY( -2px );
}

.single-conjunta__card-media {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: var( --xb-jacarta-100 );
}
.single-conjunta__thumb,
.single-conjunta__placeholder {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	background: var( --xb-jacarta-100 );
}

.single-conjunta__card-body { padding: 24px; }

.single-conjunta__meta {
	list-style: none;
	margin: 0 0 20px;
	padding: 0;
}
.single-conjunta__meta-row {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 14px 0;
	border-bottom: 1px solid var( --xb-jacarta-100 );
}
.single-conjunta__meta-row:first-child { padding-top: 0; }
.single-conjunta__meta-row:last-child  { border-bottom: 0; padding-bottom: 0; }

.single-conjunta__meta-row--split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}
/* Cerrada: 2 cols clásicas para la row de precios — el "Precio cerrado"
   vive ahora en su propia franja (--cerrada-banner) entre rows. Mantenemos
   `--cerrada-prices` por compatibilidad (no se usa); si vuelve a hacer
   falta, ya está aquí. */
.single-conjunta__meta-row--cerrada-prices {
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}
/* Franja "Precio cerrado" full-width entre los dos separadores. Layout
   inline (label izq, valor dch) con fondo sutil para destacarla del resto
   de meta-rows. User 2026-05-24: "leave row de precios as 2 cols como
   antes · move precio cerrado entre los 2 separadores". */
.single-conjunta__meta-row--cerrada-banner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 12px 14px;
	margin: 6px 0;
	background: color-mix( in srgb, #10b981 7%, transparent );
	border-radius: 10px;
	border: 1px solid color-mix( in srgb, #10b981 25%, transparent );
}
.single-conjunta__meta-row--cerrada-banner .single-conjunta__meta-label {
	margin: 0;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.5px;
	color: var( --xb-jacarta-600, #4f5475 );
}
.single-conjunta__meta-row--cerrada-banner .single-conjunta__meta-value--participe {
	color: #10b981;
	font-weight: 700;
	font-size: 22px;
}
.single-conjunta__meta-col {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}
/* Cerrada · col-dch que aloja sólo el botón "QUIERO REVIVIRLA SI…". Sin
   label propia (el lado izq ya etiqueta la fila) y el botón se coloca
   alineado AL FINAL de la columna (`justify-content: flex-end`) para
   que su vertical-center quede a la altura del valor numérico de la
   col-izq (que vive debajo del label). Alineado a la derecha dentro de
   la columna para que respire del centro de la card. User 2026-05-25
   (12ª iter): "the button should be aligned with the number of
   resurrección pagada". */
.single-conjunta__meta-col--revive-cta {
	align-items: flex-end;
	justify-content: flex-end;
}

.single-conjunta__meta-label {
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var( --xb-jacarta-400 );
}

.single-conjunta__meta-value {
	font-family: var( --xb-font-display );
	font-size: 17px;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
}
.single-conjunta__meta-line {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}
.single-conjunta__meta-hint {
	display: block;
	margin-top: 2px;
	font-family: var( --xb-font-body );
	font-size: 11px;
	line-height: 1.35;
	font-weight: 400;
	color: var( --xb-jacarta-400 );
}
.single-conjunta__meta-value--strike {
	text-decoration: line-through;
	text-decoration-thickness: 2px;
	color: var( --xb-jacarta-300 );
}
.single-conjunta__meta-value--participe {
	color: #10b981; /* verde positivo del theme — buen precio = ahorro */
	font-weight: 700;
	font-size: 22px;
}
/* Variante para cerrada (user 2026-05-24): el "Precio en conjunta" sigue
   en verde para reforzar contexto (era el precio que iban a pagar) pero
   tachado porque ya no aplica — el precio efectivo es "Precio cerrado".
   Tamaño = 17px (MISMO que precio original, no 22 como cuando está
   activo) — user 2026-05-24: "Just for conjuntas cerradas · The precio
   en conjunta Price size should be the same as precio original Price
   size". El énfasis visual se traslada al banner "Precio cerrado". */
.single-conjunta__meta-value--participe-strike {
	color: #10b981;
	font-weight: 600;
	font-size: 17px;
	text-decoration: line-through;
	text-decoration-thickness: 2px;
	text-decoration-color: rgba( 16, 185, 129, .55 );
}
/* Cerrada con precio dual "25€ / 12🥝" — el `/` se renderiza dentro de
   este span. Lo bajamos a gris suave y un tamaño menor para que no
   compita visualmente con los números verdes. */
.single-conjunta__participe-sep {
	color: #9ca3af; /* gris neutro */
	font-weight: 500;
	font-size: 0.75em;
	margin: 0 .35em;
	vertical-align: middle;
}

.single-conjunta__meta-value-line {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}
.single-conjunta__voluntario-eres-tu {
	display: block;
	color: #10b981;
	font-weight: 700;
	font-size: 14px;
	margin-top: 2px;
}

/* Botón ? (info-tip) reusable. */
.cjt-info-tip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var( --xb-jacarta-100 );
	color: var( --xb-jacarta-700 );
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease;
	-webkit-appearance: none;
	appearance: none;
}
.cjt-info-tip:hover,
.cjt-info-tip:focus {
	background: var( --xb-jacarta-700 );
	color: #ffffff;
	outline: none;
}

/* Modal cjt-confirm — reutilizado por single + mis-conjuntas. */
.cjt-confirm[hidden] { display: none !important; }
.cjt-confirm {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
}
/* User 2026-06-04 (same defensive guard as cjt-buy-popup above): if the
   body class is missing, the modal must NOT cover the page. This catches
   the bfcache race where Brave/Safari restores the modal without `hidden`
   and clicks die silently on single-conjunta. */
body:not(.cjt-confirm-open) .cjt-confirm { display: none !important; }
.cjt-confirm__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.5 );
}
.cjt-confirm__dialog {
	position: relative;
	background: #ffffff !important;
	color: var( --xb-jacarta-700 );
	max-width: 460px !important;
	width: calc( 100% - 32px ) !important;
	margin: 0 auto !important;
	padding: 28px 26px !important;
	border-radius: 14px !important;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	box-sizing: border-box !important;
}
.cjt-confirm__msg {
	font-size: 16px;
	line-height: 1.45;
	margin: 0 0 22px;
	font-weight: 500;
}
.cjt-confirm__msg--secondary {
	margin-top: -10px;
	color: var( --xb-jacarta-500 );
	font-weight: 400;
	font-size: 14px;
}
.cjt-confirm__msg--secondary[hidden] { display: none; }
.cjt-confirm__actions {
	display: flex !important;
	flex-direction: column !important;
	gap: 10px !important;
	width: 100% !important;
	box-sizing: border-box !important;
}
/* User pidió (docx 2026-05-09 "para claude"): el TOP button (Yes, destructivo
   en rojo) debe ser un TEXTO subrayado en rojo — NO un botón. El BOTTOM button
   (No, no destructivo) debe ser un BOTÓN VERDE relleno (heredado del verde
   global del theme). Así la acción reversible (cancelar) es la prominente y
   la destructiva queda como link discreto.
   Aplica a ambos modales que usan cjt-confirm — Desapuntarme + Dejar de
   ser voluntario. */
.cjt-confirm__yes,
.cjt-confirm a.cjt-confirm__yes,
.cjt-confirm button.cjt-confirm__yes {
	display: inline-block !important;
	width: auto !important;
	max-width: 100% !important;
	margin: 4px auto !important;
	padding: 6px 0 !important;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	appearance: none !important;
	box-sizing: border-box !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
	text-align: center !important;
	cursor: pointer !important;
	transition: color 0.15s ease !important;
}
/* Yes default (no destructivo) — texto verde discreto. */
.cjt-confirm__yes,
.cjt-confirm a.cjt-confirm__yes {
	color: #0e9c6f !important;
}
.cjt-confirm__yes:hover,
.cjt-confirm__yes:focus,
.cjt-confirm a.cjt-confirm__yes:hover,
.cjt-confirm a.cjt-confirm__yes:focus {
	color: #0a7752 !important;
	background: transparent !important;
	transform: none !important;
	box-shadow: none !important;
	outline: none !important;
}
/* Yes PROMINENTE (CTA del sitio — púrpura `--brand-cta`). Para flujos
   donde el YES ES la acción primaria (ej. popup auto-abierto post-Reclamar:
   "Descargar material"). Sobreescribe la regla default (texto verde
   subrayado) con un pill púrpura completo, mismo look que
   `.single-conjunta__cta--open` del sidebar. */
body .cjt-confirm__yes.cjt-confirm__yes--primary,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 100% !important;
	max-width: 100% !important;
	margin: 4px auto !important;
	padding: 14px 24px !important;
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	appearance: none !important;
	box-sizing: border-box !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 15px !important;
	font-weight: 700 !important;
	letter-spacing: 0.5px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	text-align: center !important;
	cursor: pointer !important;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
body .cjt-confirm__yes.cjt-confirm__yes--primary:hover,
body .cjt-confirm__yes.cjt-confirm__yes--primary:focus,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary:hover,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary:focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 12px 24px -10px color-mix( in srgb, var( --brand-cta ) 60%, transparent ) !important;
}
/* Combo primary + success: pill grande (geometría heredada de --primary)
   pero verde (color heredado de --success). User 2026-05-25 (12ª iter):
   "make a full entiendo button" — el voluntario `?` quería ese verde
   pill pero "--primary" sólo es púrpura. Esta regla sobreescribe el
   background de --primary cuando --success también está presente. */
body .cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success {
	background: #10b981 !important;
	color: #ffffff !important;
	border-color: #10b981 !important;
}
body .cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success:hover,
body .cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success:focus,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success:hover,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--primary.cjt-confirm__yes--success:focus {
	background: #0ea571 !important;
	color: #ffffff !important;
	border-color: #0ea571 !important;
	box-shadow: 0 12px 24px -10px rgba( 16, 185, 129, .55 ) !important;
}
/* Extra link debajo del CTA principal — centrado, subrayado, color
   verde (mismo que el CTA Entendido). Reutilizable en cualquier modal
   cjt-confirm que pase `data-cjt-confirm-extra-url`. User 2026-05-25
   (12ª iter): "saber mas with the same color but centered and underlined". */
.cjt-confirm .cjt-confirm__extra-link {
	display: block;
	margin: 12px auto 0;
	padding: 4px 0;
	color: #0e9c6f;
	font-family: var( --xb-font-body );
	font-size: 13px;
	font-weight: 500;
	text-align: center;
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.15s ease;
}
.cjt-confirm .cjt-confirm__extra-link[hidden] { display: none; }
.cjt-confirm .cjt-confirm__extra-link:hover,
.cjt-confirm .cjt-confirm__extra-link:focus {
	color: #0a7752;
	outline: none;
}
/* Yes destructivo (rojo) — texto rojo subrayado, sin fondo. */
body .cjt-confirm__yes.cjt-confirm__yes--danger,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--danger {
	background: transparent !important;
	color: #c0392b !important;
}
body .cjt-confirm__yes.cjt-confirm__yes--danger:hover,
body .cjt-confirm__yes.cjt-confirm__yes--danger:focus,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--danger:hover,
body .cjt-confirm a.cjt-confirm__yes.cjt-confirm__yes--danger:focus {
	background: transparent !important;
	color: #8a2820 !important;
	transform: none !important;
	box-shadow: none !important;
}
/* No — botón VERDE relleno (heredado green del theme). Acción prominente. */
.cjt-confirm__no,
.cjt-confirm button.cjt-confirm__no {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 100% !important;
	max-width: 100% !important;
	margin: 0 !important;
	padding: 12px 18px !important;
	background: #10b981 !important;
	color: #ffffff !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	appearance: none !important;
	box-sizing: border-box !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 14px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	text-align: center !important;
	cursor: pointer !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
.cjt-confirm__no:hover,
.cjt-confirm__no:focus,
.cjt-confirm button.cjt-confirm__no:hover,
.cjt-confirm button.cjt-confirm__no:focus {
	background: #0e9c6f !important;
	color: #ffffff !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 16, 185, 129, 0.55 ) !important;
	outline: none !important;
}
/* Variante CTA del botón prominente de cjt-confirm — color de marca
   (morado) en lugar del verde. La usa el popup "Miembros en lista de
   espera" para el botón "Ir al chat de esta conjunta". */
body .cjt-confirm__no.cjt-confirm__no--cta,
body .cjt-confirm button.cjt-confirm__no.cjt-confirm__no--cta {
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
}
body .cjt-confirm__no.cjt-confirm__no--cta:hover,
body .cjt-confirm__no.cjt-confirm__no--cta:focus,
body .cjt-confirm button.cjt-confirm__no.cjt-confirm__no--cta:hover,
body .cjt-confirm button.cjt-confirm__no.cjt-confirm__no--cta:focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta ) 60%, transparent ) !important;
}
/* En el actions row: NO va arriba (botón prominente), YES va debajo
   (link discreto). Forzamos `order` para invertir el orden DOM (donde
   YES sale primero) sin cambiar el markup. */
.cjt-confirm__actions { gap: 6px !important; }
.cjt-confirm__actions .cjt-confirm__no,
.cjt-confirm__actions button.cjt-confirm__no { order: 1; }
.cjt-confirm__actions .cjt-confirm__yes,
.cjt-confirm__actions a.cjt-confirm__yes,
.cjt-confirm__actions button.cjt-confirm__yes { order: 2; }
.cjt-confirm__yes[hidden],
.cjt-confirm__no[hidden],
.cjt-confirm a.cjt-confirm__yes[hidden],
.cjt-confirm button.cjt-confirm__no[hidden] {
	display: none !important;
}
body.cjt-confirm-open { overflow: hidden; }

/* Modal "Me apunto si…" / "Editar mi condición" — lista de espera por
   precio objetivo. Mismo lenguaje visual que `.cjt-confirm` pero con un
   input numérico. Lo imprime `conjuntas_print_waitlist_modal()` en el
   footer; lo dispara cualquier elemento con `data-cjt-waitlist`. */
.cjt-waitlist-modal[hidden] { display: none !important; }
.cjt-waitlist-modal {
	position: fixed;
	inset: 0;
	z-index: 10001;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
}
.cjt-waitlist-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.5 );
}
.cjt-waitlist-modal__dialog {
	position: relative;
	background: #ffffff;
	color: var( --xb-jacarta-700 );
	max-width: 420px;
	width: calc( 100% - 32px );
	padding: 26px 24px;
	border-radius: 14px;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	box-sizing: border-box;
}
.cjt-waitlist-modal__title {
	font-family: var( --xb-font-display );
	font-size: 19px;
	font-weight: 700;
	margin: 0 0 8px;
	color: var( --xb-jacarta-700 );
}
.cjt-waitlist-modal__lead {
	font-size: 14px;
	line-height: 1.45;
	margin: 0 0 14px;
}
.cjt-waitlist-modal__field {
	display: flex;
	align-items: center;
	gap: 8px;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	padding: 2px 12px;
}
.cjt-waitlist-modal__input {
	flex: 1;
	min-width: 0;
	border: 0 !important;
	outline: none !important;
	background: transparent !important;
	font-family: var( --xb-font-display );
	font-size: 20px;
	font-weight: 700;
	padding: 8px 0 !important;
	color: var( --xb-jacarta-700 );
	box-shadow: none !important;
}
.cjt-waitlist-modal__currency {
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 700;
	color: var( --xb-jacarta-400 );
}
.cjt-waitlist-modal__hint {
	font-size: 12px;
	color: var( --xb-jacarta-400 );
	margin: 8px 0 0;
}
.cjt-waitlist-modal__error {
	font-size: 13px;
	color: #c0392b;
	margin: 8px 0 0;
	font-weight: 600;
}
.cjt-waitlist-modal__error[hidden] { display: none; }
.cjt-waitlist-modal__actions {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-top: 18px;
}
.cjt-waitlist-modal__confirm {
	width: 100%;
	padding: 12px 18px;
	background: #10b981;
	color: #ffffff;
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.18s ease, transform 0.18s ease;
}
.cjt-waitlist-modal__confirm:hover,
.cjt-waitlist-modal__confirm:focus {
	background: #0e9c6f;
	transform: translateY( -1px );
	outline: none;
}
.cjt-waitlist-modal__confirm:disabled {
	opacity: 0.6;
	cursor: default;
	transform: none;
}
.cjt-waitlist-modal__cancel {
	width: auto;
	margin: 0 auto;
	padding: 6px 0;
	background: transparent;
	border: 0;
	color: #0e9c6f;
	font-family: var( --xb-font-body );
	font-size: 13px;
	font-weight: 500;
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}
.cjt-waitlist-modal__cancel:hover,
.cjt-waitlist-modal__cancel:focus { color: #0a7752; outline: none; }

.single-conjunta__meta-value a {
	color: var( --brand-cta );
	text-decoration: none;
	word-break: break-all;
}
.single-conjunta__meta-value a:hover,
.single-conjunta__meta-value a:focus { text-decoration: underline; }

.single-conjunta__discount {
	display: inline-block;
	background: #c0392b;
	color: #ffffff;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.4px;
	padding: 2px 8px;
	border-radius: 4px;
	line-height: 1.3;
}

/* Colores por estado — fijos (no usan tokens del Customizer). El user lo
   pidió textual: Propuesta=blue, Abierta=green, Cerrada=granate. */
.single-conjunta__estado--open     { color: #10b981; }
.single-conjunta__estado--proposed { color: #2563eb; }
.single-conjunta__estado--closed   { color: #7c1d3e; }

/* Voluntario Sí / No — mismo lenguaje cromático que los estados:
   Sí (verde) replica la paleta de "Abierta" + "El voluntario eres tú"
   que ya viven en #10b981. No (granate) replica la paleta de "Cerrada"
   (#7c1d3e). El user lo pidió: "Sí" mismo verde heredado, "No" mismo
   granate más oscuro. */
.single-conjunta__voluntar--yes { color: #10b981; font-weight: 700; }
.single-conjunta__voluntar--no  { color: #7c1d3e; font-weight: 700; }

/* CTA principal del card. En el theme actual el CTA principal es brand-cta
   (púrpura). Solo cuando la conjunta está cerrada el botón es jacarta-700
   (oscuro), igual que el patrón anterior. */
.single-conjunta__cta {
	display: block;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	text-decoration: none;
	padding: 14px 24px;
	/* User 2026-05-25 (10ª iter): "Remove the black border from comprar
	   conjunta button. It should be same style as apuntarme a conjunta
	   keeping green color". El borde venía del default del `<button>`
	   nativo (`.single-conjunta__cta--buy` es <button>; los otros CTAs
	   son <a>). Lo quitamos para TODA la familia de CTAs del single. */
	border: 0;
	border-radius: 999px;
	transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.single-conjunta__cta--open {
	background: var( --brand-cta );
	color: var( --brand-cta-text );
}
.single-conjunta__cta--open:hover,
.single-conjunta__cta--open:focus {
	background: var( --brand-cta-hover );
	color: var( --brand-cta-text-hover );
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px color-mix( in srgb, var( --brand-cta ) 60%, transparent );
}
.single-conjunta__cta--closed {
	background: var( --xb-jacarta-700 );
	color: #ffffff;
}
.single-conjunta__cta--closed:hover,
.single-conjunta__cta--closed:focus {
	background: #ffffff;
	color: var( --xb-jacarta-700 );
	box-shadow: inset 0 0 0 1px var( --xb-jacarta-700 );
}
.single-conjunta__cta--enrolled {
	background: var( --xb-jacarta-100 ) !important;
	color: var( --xb-jacarta-500 ) !important;
	cursor: default;
	pointer-events: none;
}
/* Cerrada · gate "Comprar conjunta" (user 2026-05-25, 6ª iter): un único
   botón verde primary que, al pulsarse, ABRE un POPUP modal (no un reveal
   inline) con los 2 botones de pago reales (tarjeta / kiwis). Antes era
   un reveal expandido debajo del botón — el user lo quería como popup
   centrado tipo `cjt-confirm`. JS en single-conjunta.php; markup en la
   misma plantilla (`.cjt-buy-popup`). */
.single-conjunta__cta--buy {
	background: #10b981;
	color: #ffffff;
}
.single-conjunta__cta--buy:hover,
.single-conjunta__cta--buy:focus {
	background: #0e9c6f;
	color: #ffffff;
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px rgba( 16, 185, 129, .55 );
	outline: none;
}

/* === Popup "Comprar conjunta" === */
.cjt-buy-popup {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
}
/* User 2026-06-04: defensive — the popup MUST be hidden unless the body
   carries `cjt-buy-popup-open`. Browser bfcache / SPA restore in some
   browsers (Brave shields, Safari) can strip the `hidden` attribute
   after navigation, leaving a transparent 10000-z-index full-viewport
   div that silently blocks every click on the single. The double-guard
   below (attribute OR body class missing) defeats that race for good. */
.cjt-buy-popup[hidden] { display: none !important; }
body:not(.cjt-buy-popup-open) .cjt-buy-popup { display: none !important; }
.cjt-buy-popup__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 19, 23, 64, .65 );
	backdrop-filter: blur( 2px );
}
.cjt-buy-popup__dialog {
	position: relative;
	background: #ffffff;
	border-radius: 18px;
	box-shadow: 0 30px 60px -20px rgba( 19, 23, 64, .5 );
	padding: 32px 28px 24px;
	max-width: 420px;
	width: 100%;
	max-height: calc( 100vh - 40px );
	overflow: auto;
}
.cjt-buy-popup__close {
	position: absolute;
	top: 8px;
	right: 10px;
	background: transparent;
	border: 0;
	color: var( --xb-jacarta-500, #707a83 );
	font-size: 28px;
	line-height: 1;
	padding: 4px 10px;
	cursor: pointer;
	border-radius: 8px;
	transition: background .15s;
}
.cjt-buy-popup__close:hover,
.cjt-buy-popup__close:focus {
	background: var( --xb-jacarta-100, #f4f4f4 );
	outline: none;
}
.cjt-buy-popup__title {
	margin: 0 0 20px;
	font-family: var( --xb-font-display );
	font-weight: 700;
	font-size: 18px;
	text-align: center;
	color: var( --xb-jacarta-700, #131740 );
}
.cjt-buy-popup__actions {
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.cjt-buy-popup__form {
	display: block;
	margin: 0;
}
.cjt-buy-popup__actions .single-conjunta__cta {
	margin: 0;
	width: 100%;
	box-sizing: border-box;
}
/* Sub-botones del popup: estilo morado (mockup user 2026-05-25 image7).
   Diferenciados del verde del trigger "Comprar conjunta" para que en el
   popup se lean como acciones secundarias de elección. */
.single-conjunta__cta--buy-option {
	background: var( --xb-accent, #8358ff );
	color: #ffffff;
}
.single-conjunta__cta--buy-option:hover,
.single-conjunta__cta--buy-option:focus {
	background: #6e44e8;
	color: #ffffff;
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px rgba( 131, 88, 255, .55 );
	outline: none;
}
.single-conjunta__cta--buy-option:disabled,
.single-conjunta__cta--buy-option[disabled] {
	background: var( --xb-jacarta-200, #d8daea );
	color: var( --xb-jacarta-500, #707a83 );
	cursor: not-allowed;
	box-shadow: none;
	transform: none;
}
/* Cuando el popup está abierto, no permitimos scroll en el body —
   evita scrollear "detrás" del overlay con la rueda del mouse. */
body.cjt-buy-popup-open { overflow: hidden; }
.single-conjunta__cta--group {
	margin-top: 10px;
}
.single-conjunta__cta-unenroll {
	display: block;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	margin-top: 10px;
	font-family: var( --xb-font-display );
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	text-decoration: none;
	padding: 11px 22px;
	background: #c0392b;
	color: #ffffff;
	border-radius: 999px;
	transition: background 0.15s ease, color 0.15s ease;
}
.single-conjunta__cta-unenroll:hover,
.single-conjunta__cta-unenroll:focus {
	background: #8a2820;
	color: #ffffff;
}

.single-conjunta__cta-secondary {
	display: inline-block;
	margin-top: 6px;
	padding: 6px 14px;
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	text-decoration: none;
	color: #ffffff;
	background: #10b981;
	border: 1px solid #10b981;
	border-radius: 999px;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
	align-self: flex-start;
}
/* Variante compacta para cuando el botón vive embedido en una columna
   estrecha junto al número (ej. cerrada → Resurrección pagada col-dch).
   User 2026-05-25 (10ª iter): clona el LOOK del CTA principal
   "Comprar conjunta" — verde plano sin borde, uppercase, weight 700,
   border-radius pill — pero respeta el ancho de su columna (queda
   inline-flex, no `block 100%`). Padding generoso (10px 18px) para no
   parecer "secundario" debajo del label. */
.single-conjunta__cta-secondary--compact {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-top: 0;
	margin-left: 0;
	/* User 2026-05-25 (12ª iter): mismo tamaño tipográfico que el CTA
	   principal "Comprar conjunta" (15px / 0.5px tracking). El padding
	   sube a 14px/24px para que el botón tenga proporciones equivalentes. */
	padding: 14px 24px;
	background: #10b981;
	border: 0;
	border-radius: 999px;
	color: #ffffff;
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.5px;
	line-height: 1.2;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	cursor: pointer;
}
.single-conjunta__cta-secondary--compact:hover,
.single-conjunta__cta-secondary--compact:focus {
	background: #0e9c6f;
	color: #ffffff;
	transform: translateY( -1px );
	box-shadow: 0 12px 24px -10px rgba( 16, 185, 129, .55 );
	outline: none;
}
/* Variante deshabilitada — user 2026-05-26: cuando el user logueado YA
   pagó la conjunta cerrada, el botón "COMPRAR" sigue en su sitio (misma
   posición + tamaño que la versión activa) pero gris no-clicable, para
   comunicar visualmente "ya está hecho" sin romper la simetría del
   layout (alineado con RESUCITAR debajo). Sin hover-lift ni shadow. */
.single-conjunta__cta-secondary--disabled,
.single-conjunta__cta-secondary--compact.single-conjunta__cta-secondary--disabled {
	background: var( --xb-jacarta-100, #e5e7ee );
	color: var( --xb-jacarta-400, #8a8db4 );
	border-color: var( --xb-jacarta-100, #e5e7ee );
	cursor: not-allowed;
	pointer-events: none;
	box-shadow: none;
}
.single-conjunta__cta-secondary--disabled:hover,
.single-conjunta__cta-secondary--disabled:focus {
	background: var( --xb-jacarta-100, #e5e7ee );
	color: var( --xb-jacarta-400, #8a8db4 );
	border-color: var( --xb-jacarta-100, #e5e7ee );
	transform: none;
	box-shadow: none;
}
/* Cuando el col-dch es la versión compacta (revive embed-eado en Estado),
   reset del flex stretching del col padre para que el contenido respire
   horizontalmente. */
.single-conjunta__meta-col--revive-cta-compact {
	align-items: flex-start;
}
.single-conjunta__meta-col--revive-cta-compact .single-conjunta__meta-value-line {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	flex-wrap: wrap;
}
.single-conjunta__cta-secondary:hover,
.single-conjunta__cta-secondary:focus {
	background: #0e9c6f;
	color: #ffffff;
	border-color: #0e9c6f;
}

.single-conjunta__footlinks {
	margin: 14px 0 0;
	font-family: var( --xb-font-body );
	font-size: 12px;
	text-align: center;
	color: var( --xb-jacarta-400 );
}
.single-conjunta__footlinks + .single-conjunta__footlinks { margin-top: 6px; }
.single-conjunta__footlinks a,
.single-conjunta__footlinks .single-conjunta__footlink-btn {
	color: var( --xb-jacarta-500 );
	text-decoration: none;
	background: transparent;
	border: 0;
	padding: 0;
	font: inherit;
	cursor: pointer;
	line-height: inherit;
}
.single-conjunta__footlinks a:hover,
.single-conjunta__footlinks a:focus,
.single-conjunta__footlinks .single-conjunta__footlink-btn:hover,
.single-conjunta__footlinks .single-conjunta__footlink-btn:focus {
	color: var( --brand-cta );
	text-decoration: underline;
}

/* --- Body: descripción --------------------------------------------- */
.single-conjunta__body {
	grid-column: content-start / content-end;
	grid-row: 2;
	padding: 40px 408px var( --content-bot ) 0;
	max-width: 100%;
}
.single-conjunta__excerpt {
	font-family: var( --xb-font-body );
	font-size: 19px;
	line-height: 1.55;
	color: var( --xb-jacarta-700 );
	margin: 0 0 24px;
}
/* El excerpt ahora puede contener `<p>` (texto simple, con `<br>`
   por línea) o `<ol class="single-conjunta__excerpt-list">` cuando
   el helper detecta lista numerada (`1. … 2. …`). En ambos casos
   reseteamos el margin que el browser pondría por defecto y damos
   un padding-left consistente al `<ol>` para que los números no se
   coman el ancho útil. */
.single-conjunta__excerpt > p,
.single-conjunta__excerpt > ol {
	margin: 0;
}
.single-conjunta__excerpt-list {
	padding-left: 1.4em;
}
.single-conjunta__excerpt-list li {
	margin: 0 0 6px;
}
.single-conjunta__excerpt-list li:last-child {
	margin-bottom: 0;
}
.single-conjunta__flash {
	margin: 0 0 24px;
	padding: 14px 18px;
	border-radius: 8px;
	font-family: var( --xb-font-display );
	font-size: 15px;
	font-weight: 600;
}
.single-conjunta__flash--success {
	background: var( --brand-cta );
	color: var( --brand-cta-text );
}
.single-conjunta__flash--info {
	background: var( --xb-jacarta-500 );
	color: #ffffff;
}
.single-conjunta__flash--inline {
	margin: 0 0 12px;
	padding: 12px 14px;
	font-size: 14px;
	line-height: 1.4;
	text-align: center;
}

.single-conjunta__section {
	font-family: var( --xb-font-display );
	font-size: 28px;
	font-weight: 600;
	margin: 0 0 16px;
	color: var( --xb-jacarta-700 );
}
/* Sección INLINE "Miembros en lista de espera" — sustituye al popup
   anterior (que se eliminó 2026-05-23). Vive justo debajo de
   "Descripción"; necesita su propio top-margin porque viene tras un
   bloque de párrafos sin separación natural. */
.single-conjunta__section--waitlist {
	margin-top: 36px;
}
.single-conjunta__waitlist-inline .cjt-wl-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 8px;
}
.single-conjunta__waitlist-inline .cjt-wl-list li {
	padding: 12px 14px;
	background: var( --xb-light-base, #f5f6fc );
	border: 1px solid var( --xb-jacarta-100, #e5e7ee );
	border-radius: 10px;
	font-size: 15px;
	line-height: 1.45;
	color: var( --xb-jacarta-700 );
}
.single-conjunta__waitlist-inline .cjt-wl-list li strong {
	color: var( --xb-jacarta-900, #131740 );
	font-weight: 600;
}
/* "Hace X" badge — small + muted, en línea con la frase, separado por
   un margen para que no se pegue al precio. El user lo pidió 2026-05-23:
   "<small> font: when did that even happen? ... Less than 1 hour ago ...". */
.single-conjunta__waitlist-inline .cjt-wl-list__when {
	display: inline-block;
	margin-left: 8px;
	color: var( --xb-jacarta-400, #8b91b5 );
	font-size: 12px;
	font-weight: 500;
	font-style: italic;
}
.single-conjunta__waitlist-inline .cjt-wl-list__empty {
	color: var( --xb-jacarta-500, #71789b );
	font-size: 14px;
	margin: 0;
}
/* Items "promovidos" — usuarios que estuvieron en la lista de espera
   pero ya entraron a la conjunta. Se muestran después de los activos
   como prueba social. La línea principal va tachada suave (la condición
   ya está cumplida) y debajo aparece la "celebración" en verde. */
/* Items de actividad — TEXTO uniforme (jacarta-700) para todas las
   filas; el TIPO de evento se codifica con el COLOR DE FONDO de la
   pill, no con el color del texto. User 2026-05-24 (3ra iteración):
   "i don't want the text to be green, make the text as the others,
   but rather the box background should be green or gray or red
   depending on the event".
   User 2026-05-25 (6ª iter): paleta re-asignada.
     - default (wl-active, kiwi_reward, state-changed, created, etc.)
       → fondo BLANCO (estilo base — sin override; el border/bg viene
         del padding base de la lista en `.cjt-wl-list__item`).
     - enroll / promoted  → AZUL (nuevo participante apuntándose).
     - paid-kiwis         → VERDE (user pagó su parte — reservado para
       pagos; hoy sólo emergen los kiwis, mañana podría sumarse otro
       método si el user lo decide visible).
     - unenroll           → wine suave (igual que antes — sigue siendo
       el único evento "negativo" del feed). */
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--enroll,
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--promoted {
	background: color-mix( in srgb, #2563eb 10%, #ffffff ) !important;
	border-color: color-mix( in srgb, #2563eb 28%, var( --xb-jacarta-100, #e5e7ee ) ) !important;
}
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--paid,
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--paid-eur {
	background: color-mix( in srgb, #10b981 10%, #ffffff ) !important;
	border-color: color-mix( in srgb, #10b981 28%, var( --xb-jacarta-100, #e5e7ee ) ) !important;
}
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--unenroll {
	background: color-mix( in srgb, #7c1d3e 10%, #ffffff ) !important;
	border-color: color-mix( in srgb, #7c1d3e 28%, var( --xb-jacarta-100, #e5e7ee ) ) !important;
}
/* state-changed: caja BLANCA explícita (sin override). Se renderiza con
   el estilo base de `.cjt-wl-list__item` que ya es blanco — el override
   queda aquí documentado para que cualquier cambio futuro del default no
   se cuele en este evento (debe mantenerse neutral). */
.single-conjunta__waitlist-inline .cjt-wl-list .cjt-wl-list__item--state {
	background: #ffffff !important;
	border-color: var( --xb-jacarta-100, #e5e7ee ) !important;
}

/* Filtros de actividad (Todos / Precio / Lista de espera / Participantes).
   Estilo pill compacto similar a `.cjt-pill` de mis-conjuntas pero scoped
   a esta sección para no entrar en conflicto con MP-chrome. Single-select:
   sólo un chip activo a la vez. Toggle interactivo via JS — el filtrado
   real es client-side por `data-event-cat` de cada <li>. */
.single-conjunta__waitlist-inline .cjt-actividad-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 8px;
	margin: 0 0 14px;
}
.single-conjunta__waitlist-inline .cjt-actividad-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	background: var( --xb-light-base, #f5f6fc );
	border: 1px solid var( --xb-jacarta-100, #e5e7ee );
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.3px;
	color: var( --xb-jacarta-500, #71789b );
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.single-conjunta__waitlist-inline .cjt-actividad-pill:hover,
.single-conjunta__waitlist-inline .cjt-actividad-pill:focus {
	color: var( --brand-cta, #8358FF );
	border-color: color-mix( in srgb, var( --brand-cta, #8358FF ) 40%, var( --xb-jacarta-100, #e5e7ee ) );
	outline: 0;
}
.single-conjunta__waitlist-inline .cjt-actividad-pill--active,
.single-conjunta__waitlist-inline .cjt-actividad-pill[aria-pressed="true"] {
	background: color-mix( in srgb, var( --brand-cta, #8358FF ) 12%, #ffffff );
	border-color: var( --brand-cta, #8358FF );
	color: var( --brand-cta, #8358FF );
}

/* Filtrado client-side: cuando la <ul> tiene `data-actividad-active-filter`
   distinto de "todos", ocultamos los <li> cuyo `data-event-cat` no
   contenga ese tag. Implementación CSS pura (sin JS no se rompe el
   listado — sólo no se filtra). */
.single-conjunta__waitlist-inline .cjt-wl-list[data-actividad-active-filter="precio"] > li:not([data-event-cat*="precio"]),
.single-conjunta__waitlist-inline .cjt-wl-list[data-actividad-active-filter="lista-de-espera"] > li:not([data-event-cat*="lista-de-espera"]),
.single-conjunta__waitlist-inline .cjt-wl-list[data-actividad-active-filter="participantes"] > li:not([data-event-cat*="participantes"]) {
	display: none !important;
}
/* "Empty filter" — si el filtro activo no matchea ningún <li>, mostramos
   un placeholder que vive dentro de la ul como :before. No es perfecto
   pero ahorra render server-side. */
.single-conjunta__waitlist-inline .cjt-wl-list:not([data-actividad-active-filter="todos"]):not(:has(> li:not([style*="display: none"]))):empty::after {
	content: "Sin actividad en este filtro.";
	display: block;
	color: var( --xb-jacarta-400, #8b91b5 );
	font-size: 13px;
	font-style: italic;
}

/* === Chips de categoría en el hero ================================
   Aparecen entre "Última actualización" e "Idioma". Mismo lenguaje
   visual que la list-view de /lista-de-cursos
   (`.xb-collections__content.is-list-view .cjt-card__cats`): chip
   pill con icono circular coloreado + label uppercase en color CTA.
   Las reglas canonical están scoped a `.xb-collections__content`, así
   que aquí replicamos lo justo para nuestro contenedor sin tocar
   las del listado. Render como `<a>` para que sean enlaces directos
   al archivo de la taxonomía (en /lista son `<button>` filtro).
*/
.single-conjunta__cats {
	display: flex;
	flex-flow: row wrap;
	align-items: flex-start;
	gap: 10px 28px;
}
/* Cada grupo = root + sus subs asignadas. El root va arriba alineado
   al borde izquierdo; las subs aparecen indentadas debajo, una por
   fila, prefijadas con ↳ (flecha "subnivel" ASCII). */
.single-conjunta__cats-group {
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.single-conjunta__cats-subs {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding-left: 22px; /* alinea el ↳ con el centro del icono del root */
}
.single-conjunta__cats-sub-row {
	display: inline-flex;
	align-items: center;
	gap: 2px;
}
.single-conjunta__cats-arrow {
	display: inline-block;
	color: var( --xb-jacarta-400 );
	font-size: 14px;
	line-height: 1;
	width: 14px;
	text-align: center;
	flex: 0 0 auto;
}
/* La chip "sub" pesa visualmente menos: label en peso 600 y un poco
   más pequeño (la jerarquía la marca la indentación + el ↳, no el
   tamaño per se). */
.single-conjunta__cats .cjt-card__category--sub .cjt-card__category-label {
	font-weight: 600;
}
.single-conjunta__cats .cjt-card__category {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 10px 4px 4px;
	margin: 0;
	background: transparent;
	border: 0;
	border-radius: 999px;
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.4px;
	color: var( --brand-cta );
	text-decoration: none;
	cursor: pointer;
	transition: color 0.15s ease, background 0.15s ease;
}
.single-conjunta__cats .cjt-card__category:hover,
.single-conjunta__cats .cjt-card__category:focus {
	color: var( --brand-cta-hover );
	background: color-mix( in srgb, var( --brand-cta ) 8%, transparent );
	outline: none;
}
.single-conjunta__cats .cjt-card__category-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 999px;
	flex: 0 0 auto;
}
.single-conjunta__cats .cjt-card__category-icon svg {
	width: 14px;
	height: 14px;
}

/* === Tarjeta "Tu participación" user-specific (desktop) ============
   Vive dentro de `.single-conjunta__hero-text`, debajo del bloque
   "Idioma". Comparte el border rainbow animado de
   `.single-conjunta__card` (mismo `--cjt-rainbow-gradient`, misma
   keyframe `cjt-card-rainbow`) pero a escala reducida — sólo
   contiene las acciones user-specific de mis-conjuntas: estado de
   material, "Grupo de esta conjunta", "Pagar conjunta", "Pendiente
   de pago", "Desapuntarme", "Panel de voluntario". El render lo
   hace `mod_mepr_render_card_unenroll()` (plugin
   modificacion-memberpress) — SSoT con la pestaña /cuenta/?action=
   mis-conjuntas, así cualquier cambio se propaga aquí solo.
*/
.single-conjunta__user-card {
	float: right;
	width: 360px;
	max-width: 360px;
	margin: 4px -48px 18px 24px;
	/* `float: right` deja que byline/fecha/idioma/cats hagan wrap
	   a la izquierda de la card en vez de quedar empujados debajo
	   — la card "Tu participación" toma prioridad visual y el
	   resto del texto se acopla a su altura. El `margin-right: -48px`
	   mete la card en los 48px de hueco entre `padding-right: 408px`
	   del hero-text y el sidebar (360px) para que su borde derecho
	   coincida con el borde izquierdo del `single-conjunta__card`.
	   El `margin-left: 24px` da aire entre el texto que envuelve y
	   la card. */
	padding: 14px 16px 16px;
	border: 2px solid transparent;
	border-radius: 1rem;
	background-image:
		linear-gradient( #ffffff, #ffffff ),
		var( --cjt-rainbow-gradient );
	background-origin: border-box;
	background-clip: padding-box, border-box;
	background-size: auto, 200% 100%;
	background-repeat: no-repeat, repeat-x;
	animation: cjt-card-rainbow 6s linear infinite;
	box-shadow: 0 6px 18px -10px rgba( 13, 16, 45, 0.08 );
	font-family: var( --xb-font-body );
}@media ( prefers-reduced-motion: reduce ) {
	.single-conjunta__user-card { animation: none; }
}
.single-conjunta__user-card-label {
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var( --xb-jacarta-400 );
	margin: 0 0 10px;
	/* Permitir que las pills coloreadas del estado (apuntado / voluntario /
	   en lista de espera) se acoplen inline al label gris — wrap natural
	   cuando no caben en una línea (mobile / labels largos). */
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px;
}
/* Wrapper inline para las pills de estado. `inline-flex` para mantener
   las pills + separador alineados en una sola línea visual cuando hay
   sitio; el wrap lo hace el contenedor `.single-conjunta__user-card-label`
   más arriba (porque al label le pusimos `flex-wrap: wrap`). */
.single-conjunta__user-card-state {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px;
}
/* Pills coloreadas del estado del usuario en esta conjunta. Heredan el
   tamaño y el tracking del label (mismo `font-display` 11px uppercase),
   pero NO el color — cada modificador define el suyo:
     --apuntado  → verde   (#10b981)
     --voluntario → azul   (#0c63e7)
     --waitlist  → negro   (#0d102d)
   El separador `+` entre "apuntado" y "voluntario" se queda en gris
   jacarta-400 para que las dos palabras coloreadas se lean independientes. */
.single-conjunta__user-state {
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
}
.single-conjunta__user-state--apuntado {
	color: #10b981;
}
.single-conjunta__user-state--voluntario {
	color: #0c63e7;
}
.single-conjunta__user-state--waitlist {
	color: #0d102d;
}
.single-conjunta__user-state-sep {
	color: var( --xb-jacarta-400 );
	font-weight: 700;
	font-size: 11px;
	letter-spacing: 0.5px;
}
/* `mod_mepr_render_card_unenroll` emite `.cjt-card__actions` con
   `flex-wrap: wrap, align-items: center, gap: 6px 12px` (pensado
   para mis-conjuntas inline-row). Aquí stack vertical centrado —
   cada pill conserva su ancho intrínseco (`inline-flex` original)
   y queda centrada en el ancho del user-card.

   ORDEN VISUAL (user 2026-05-24): "Pagado correctamente" arriba del
   todo, seguido de "Material disponible", seguido inmediatamente de
   "Grupo de esta conjunta" (violeta-CTA, mismo tamaño que Material).
   Resto de acciones secundarias (Panel de voluntario, Desapuntarme,
   Eliminar conjunta) van debajo. Usamos `order` para no tocar el
   render PHP (compartido con mis-conjuntas, que tiene su propio
   layout en fila). */
.single-conjunta__user-card .cjt-card__actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	margin: 0;
	text-align: center;
}
/* `!important` obligatorio: las reglas hermanas de mis-conjuntas
   `.cjt-card__actions .cjt-card__group { order: 99 !important }`
   leakeaban antes y forzaban a Desapuntarme al medio en el user-card
   del single. Con `!important` aquí ganamos siempre. User 2026-05-24:
   "desapuntarme should be last" + "panel de voluntario will always be
   on top of grupo de esta conjunta". Orden visual deseado en user-card:
   pago → material → panel voluntario → grupo → desapuntarme → borrar. */
.single-conjunta__user-card .cjt-card__actions .cjt-card__pay-wrap        { order: 1 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__material        { order: 2 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__pay-pending-top { order: 2 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__volunteer-panel { order: 3 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__group           { order: 4 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__unenroll        { order: 5 !important; }
.single-conjunta__user-card .cjt-card__actions .cjt-card__delete          { order: 6 !important; }
/* Cada pill/botón sin margin extra hereda — el `gap: 12px` del
   contenedor ya espacia todo. `.cjt-card__material` traía
   `margin: 0 0 6px 0 !important` para compensar el layout de
   mis-conjuntas; aquí lo neutralizamos. */
.single-conjunta__user-card .cjt-card__material,
.single-conjunta__user-card .cjt-card__group,
.single-conjunta__user-card .cjt-card__unenroll,
.single-conjunta__user-card .cjt-card__volunteer-panel,
.single-conjunta__user-card .cjt-card__delete {
	margin: 0 !important;
	align-self: center;
	max-width: 100%;
}
/* Pay-wrap (botón verde "Pagar conjunta" + caption rojo "Pendiente
   de pago" stacked) — centra el caption bajo el botón. */
.single-conjunta__user-card .cjt-card__pay-wrap {
	align-items: center !important;
	margin: 0 !important;
	text-align: center;
}
/* "Pendiente de pago" — rojo + 12px. La regla canonical
   `.cjt-card .cjt-card__pay-status` no aplica aquí porque
   `.single-conjunta__user-card` no es `.cjt-card`. Replicamos
   el color #c0392b (mismo de mis-conjuntas) en este scope. */
.single-conjunta__user-card .cjt-card__pay-status,
.single-conjunta__user-card .cjt-card__pay-pending-top {
	display: inline-block;
	font-family: var( --xb-font-body );
	font-size: 12px !important;
	font-weight: 600 !important;
	color: #c0392b !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-align: center !important;
	margin: 0 !important;
	padding: 0 !important;
}
.single-conjunta__user-card .cjt-card__pay-status--paid {
	color: #0e9c6f !important;
}
/* "Estás en espera (X€)" badge ABOVE el botón "Editar mi condición"
   en la user-card del waitlist. Mismo verde que `Pagado correctamente`
   pero un pelín más grande (14px) para que destaque sobre el resto del
   layout. User 2026-05-25 (6ª iter): "I want you to clone this and put
   it on top of the button editar mi condición centered and change the
   style to the same style as 'pagado correctamente'". */
.single-conjunta__user-card .single-conjunta__user-card-wait-badge {
	font-size: 14px !important;
	font-weight: 700 !important;
	width: 100% !important;
	text-align: center !important;
}
/* "Grupo de esta conjunta" + "Material disponible/pendiente/locked"
   + "Panel de voluntario" en el user-card del single: el user pidió
   2026-05-24 (2da iteración) que los TRES compartan el MISMO tamaño
   (full-width, padding 12px 18px, 13px) y que "Grupo" use el color
   CTA de la marca (violeta `--brand-cta`). Comparten regla de
   geometría para no derivar; el color de fondo se diferencia por
   modificador en las reglas siguientes. User verbatim: "the button
   of panel de voluntario should be as big as grupo de esta conjunta
   and material disponible". */
.single-conjunta__user-card .cjt-card__group,
.single-conjunta__user-card .cjt-card__material,
.single-conjunta__user-card button.cjt-card__material--available,
.single-conjunta__user-card button.cjt-card__material--locked,
.single-conjunta__user-card .cjt-card__material--pending,
.single-conjunta__user-card .cjt-card__volunteer-panel,
.single-conjunta__user-card button.cjt-card__volunteer-panel {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	width: 100% !important;
	max-width: 100% !important;
	padding: 12px 18px !important;
	margin: 0 !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	box-sizing: border-box !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 13px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	line-height: 1.2 !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	text-align: center !important;
	white-space: normal !important;
	cursor: pointer !important;
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
	align-self: center !important;
}
/* Colores por modificador:
   - Material disponible (paid/voluntario) → verde
   - Material locked (no paid)             → rojo
   - Material pendiente (admin sin subir)  → azul info
   - Grupo de esta conjunta                → violeta CTA (--brand-cta) */
.single-conjunta__user-card button.cjt-card__material--available {
	background: #10b981 !important;
	color: #ffffff !important;
}
.single-conjunta__user-card button.cjt-card__material--available:hover,
.single-conjunta__user-card button.cjt-card__material--available:focus {
	background: #0e9c6f !important;
	color: #ffffff !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px rgba( 16, 185, 129, 0.55 ) !important;
	outline: 0 !important;
}
.single-conjunta__user-card button.cjt-card__material--locked {
	background: #dc2626 !important;
	color: #ffffff !important;
}
.single-conjunta__user-card button.cjt-card__material--locked:hover,
.single-conjunta__user-card button.cjt-card__material--locked:focus {
	background: #b91c1c !important;
	color: #ffffff !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 6px 12px -4px rgba( 220, 38, 38, 0.45 ) !important;
	outline: 0 !important;
}
.single-conjunta__user-card .cjt-card__material--pending {
	background: color-mix( in srgb, #3b82f6 14%, transparent ) !important;
	color: #1d4ed8 !important;
	cursor: default !important;
}
.single-conjunta__user-card .cjt-card__group {
	background: var( --brand-cta, #8358FF ) !important;
	color: var( --brand-cta-text, #ffffff ) !important;
}
.single-conjunta__user-card .cjt-card__group:hover,
.single-conjunta__user-card .cjt-card__group:focus {
	background: var( --brand-cta-hover, #7444FF ) !important;
	color: var( --brand-cta-text-hover, #ffffff ) !important;
	transform: translateY( -1px ) !important;
	box-shadow: 0 8px 16px -6px color-mix( in srgb, var( --brand-cta, #8358FF ) 60%, transparent ) !important;
}

/* Tablet/mobile: una columna. */
@media ( max-width: 900px ) {
	.single-conjunta__main {
		grid-template-columns:
			[full-start] var( --content-pad )
			[content-start] minmax( 0, 1fr ) [content-end]
			var( --content-pad ) [full-end];
		grid-template-rows: auto auto auto;
	}
	.single-conjunta__hero-bg   { grid-row: 1; }
	.single-conjunta__hero-text { grid-row: 1; padding: 36px 0; }
	.single-conjunta__sidebar {
		grid-row: 2;
		grid-column: content-start / content-end;
		justify-self: stretch;
		width: 100%;
		margin-top: 24px;
		margin-bottom: 8px;
		position: static;
	}
	.single-conjunta__body {
		grid-row: 3;
		padding: 24px 0 var( --content-bot ) 0;
	}
	/* En mobile la card "Tu participación" se queda visible, ancho
	   completo del hero, sin float (en desktop usamos `float: right`
	   para que el byline/fecha/cats hagan wrap a su izquierda; en
	   mobile no hay espacio para wrap). */
	.single-conjunta__user-card {
		float: none;
		width: auto;
		max-width: none;
		margin: 24px 0 0;
	}
	/* Cuando hay user-card, el meta-info (byline / fecha / idioma /
	   cats) se mueve AL FINAL de todo, después del body (description).
	   - inline (dentro del hero) → hidden
	   - mobile-after (sibling al final del main) → visible, grid-row 4
	     (sidebar row 2, body row 3, meta row 4). */
	.single-conjunta__main--with-user-card .single-conjunta__meta-info--inline {
		display: none;
	}
	.single-conjunta__main--with-user-card .single-conjunta__meta-info--mobile-after {
		display: block;
		/* Full-bleed gris detrás del meta-info al final del main
		   (mismo --xb-jacarta-50 que la banda gris del hero). El
		   bloque ocupa de borde a borde para que el fondo gris no
		   tenga "márgenes blancos" a los lados, y el padding interno
		   restringe el contenido al ancho de content-pad. */
		grid-column: full-start / full-end;
		grid-row: 4;
		background: var( --xb-jacarta-50 );
		padding: 28px var( --content-pad );
	}
	/* Equilibramos: el gap content→grey y el gap grey→footer deben
	   ser iguales. Tres reglas en juego:
	    1. Body padding-bottom 32px (gap arriba del gris).
	    2. Anulamos el margin-bottom del último elemento del body
	       para que no se sume al padding y rompa el cálculo.
	    3. Footer normalmente lleva padding-top: 96px (genérico); en
	       estas single-conjunta con user-card lo bajamos a 32px vía
	       `:has()` para que el hueco abajo del gris iguale el de
	       arriba — sin esto, 32px arriba + (0 margin + 96px footer)
	       abajo = totalmente asimétrico (lo que el user reportó). */
	.single-conjunta__main--with-user-card .single-conjunta__body {
		padding-bottom: 32px;
	}
	.single-conjunta__main--with-user-card .single-conjunta__body > *:last-child,
	.single-conjunta__main--with-user-card .single-conjunta__description > *:last-child {
		margin-bottom: 0;
	}
	.single-conjunta__main--with-user-card .single-conjunta__meta-info--mobile-after {
		margin-bottom: 0;
	}
	body:has( .single-conjunta__main--with-user-card ) .site-footer {
		padding-top: 32px;
	}
}
/* Default: la copia mobile-after está oculta en todos los viewports
   (sólo se activa via el media query + modifier de arriba). */
.single-conjunta__meta-info--mobile-after {
	display: none;
}
@media ( max-width: 480px ) {
	.single-conjunta__meta-row--split {
		grid-template-columns: 1fr;
		gap: 14px;
	}
}

/* ===================================================================
 * Dynamic Pricing Table — theme skin
 * ===================================================================
 * El plugin "Dynamic Pricing Table" emite tablas con la siguiente
 * estructura:
 *   .pricing-table-container#pricing-table-{post}-{rand}
 *     > .pricing-table-mobile-menu > .plans-scrollable > .plan-tab
 *     > .pricing-table.desktop-view
 *         > .pricing-table-header (+.has-empty-header)
 *             > .benefit-column (header text)
 *             > .plan-column > .plan-header > h3 + p + a.get-button + .plan-toggle?
 *         > .pricing-table-section
 *             > .pricing-table-row.section-title-row
 *                 > .benefit-column h4 + .plan-column .section-content
 *             > .pricing-table-row
 *                 > .benefit-column (.spoiler-toggle + .benefit-icon? + .benefit-name + .tooltip?)
 *                 > .plan-column .plan-value
 *             > .spoiler-content > .benefit-column
 *
 * El plugin escribe sus reglas dentro de un `<style>` inline scoped
 * por `#unique_id` (specificity 1,1,0). Aquí le ponemos encima la
 * piel del theme. Como el ID del plugin gana en cascada normal,
 * usamos `[id^="pricing-table-"]` (atributo: 0,1,0 + clases) y
 * `!important` en las propiedades que SÍ queremos forzar (fuentes,
 * botón CTA, dark-mode). El admin sigue pudiendo ajustar colores
 * individuales por tabla desde el metabox "Design Options" del CPT
 * `pricing_table` — sus elecciones se respetan vía las CSS vars
 * `--pt-bg`, `--pt-line`, `--pt-text`, `--pt-btn-*` que el plugin
 * inyecta en el `#unique_id` y que NO sobreescribimos.
 * =================================================================== */

/* Fuentes y color base — la tabla hereda la tipografía del theme.
   Los `!important` son necesarios porque algunas reglas del plugin
   están scoped por ID y ganarían sin ellos. */
[id^="pricing-table-"].pricing-table-container,
[id^="pricing-table-"] .pricing-table,
[id^="pricing-table-"] .plan-header,
[id^="pricing-table-"] .benefit-column,
[id^="pricing-table-"] .plan-column,
[id^="pricing-table-"] .plan-tab {
	font-family: var( --xb-font-body ) !important;
}

/* Headers (h3/h4) usan CalSans display + color jacarta del theme. */
[id^="pricing-table-"] .plan-header h3,
[id^="pricing-table-"] .pricing-table-section h4,
[id^="pricing-table-"] .section-title-row h4 {
	font-family: var( --xb-font-display ) !important;
	font-weight: 600;
	color: var( --xb-jacarta-700 );
	letter-spacing: -0.01em;
	margin: 0;
}
[id^="pricing-table-"] .plan-header h3 {
	font-size: clamp( 15px, 1.6vw, 18px );
	line-height: 1.15;
	margin-bottom: 1px;
}
[id^="pricing-table-"] .pricing-table-section h4,
[id^="pricing-table-"] .section-title-row h4 {
	font-size: 15px;
	line-height: 1.35;
	color: var( --xb-jacarta-600 );
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* Precio del plan — visualmente "h1 con <small>". Hereda fuente,
   peso e interlineado del H1 del hero (Customizer → "Texto
   bienvenida"); el tamaño es ~1/3 del H1 (`<small>` típicamente
   ~0.83 dentro de h1, pero como aquí no hay h1 envolvente bajamos
   más para que el precio quepa en una columna estrecha). El user
   pidió: "no quiero un font fijo, sino dinámico — si la tipo del
   <h1> small cambia, este área también cambia". */
[id^="pricing-table-"] .plan-header p {
	font-family: var( --brand-bienvenida-family, var( --xb-font-body ) ) !important;
	font-weight: var( --brand-bienvenida-weight, 600 );
	font-size: clamp( 18px, calc( var( --brand-bienvenida-size-max, 72px ) * 0.28 ), 24px ) !important;
	line-height: var( --brand-bienvenida-line-height, 1.1 );
	color: var( --xb-jacarta-700 );
	margin: 0 0 4px;
}

/* Nombre del beneficio + valor del plan. */
[id^="pricing-table-"] .benefit-name {
	font-size: 14px;
	line-height: 1.5;
	color: var( --xb-jacarta-700 );
	font-weight: 500;
}
[id^="pricing-table-"] .plan-value {
	font-size: 14px;
	line-height: 1.5;
	color: var( --xb-jacarta-600 );
}
[id^="pricing-table-"] .section-content {
	font-size: 13px;
	line-height: 1.55;
	color: var( --xb-jacarta-500 );
}

/* Botón CTA — usa las brand-cta vars del Customizer. Sobreescribe el
   `--pt-btn-*` por defecto del plugin (negro/gris) sólo cuando el
   admin NO ha tocado los colores del botón en el metabox de la
   tabla. Como el plugin define los `--pt-btn-*` con su default
   #000/#fff, la única forma fiable de saber si "no tocó" es
   sobreescribir directamente: aquí asumimos que el theme manda. Si
   el user quiere colores propios por tabla puede seguir usando los
   campos del metabox — esas reglas siguen activas porque el plugin
   las escribe en el inline style con specificity ID. */
[id^="pricing-table-"] .get-button {
	font-family: var( --xb-font-body ) !important;
	font-weight: 700 !important;
	font-size: var( --brand-body-size, 16px ) !important;
	letter-spacing: 0.01em;
	padding: 6px 18px !important;
	border-radius: 999px !important;
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	box-shadow: 0 4px 14px rgba( 0, 0, 0, 0.06 );
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
[id^="pricing-table-"] .get-button:hover,
[id^="pricing-table-"] .get-button:focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	transform: translateY( -1px );
	box-shadow: 0 8px 22px rgba( 0, 0, 0, 0.10 );
}

/* Plan-toggle (checkmark) — repinta para coincidir con la marca. */
[id^="pricing-table-"] .checkmark {
	border-color: var( --brand-cta ) !important;
}
[id^="pricing-table-"] .plan-checkbox:checked + .checkmark::after {
	color: var( --brand-cta ) !important;
}

/* Mobile tabs — pill-style del theme (similar a `.btn-cta` y a la
   visitor-cta del navbar). Inactivo: fondo `--pt-bg`, borde
   jacarta-100, texto jacarta-700; hover: borde + texto en
   `--brand-cta` con leve lift. Activo: fondo `--brand-cta`, texto
   blanco, sombra suave. El user lo pidió: "on mobile i want the
   plan-selector buttons to have the style of our theme". */
[id^="pricing-table-"] .plan-tab {
	font-family: var( --xb-font-display ) !important;
	font-weight: 600 !important;
	font-size: 14px !important;
	letter-spacing: 0.02em !important;
	padding: 10px 22px !important;
	border-radius: 999px !important;
	border: 1px solid var( --xb-jacarta-100 ) !important;
	background: var( --pt-bg ) !important;
	color: var( --xb-jacarta-700 ) !important;
	text-decoration: none;
	white-space: nowrap;
	transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease !important;
}
[id^="pricing-table-"] .plan-tab:hover,
[id^="pricing-table-"] .plan-tab:focus {
	border-color: var( --brand-cta ) !important;
	color: var( --brand-cta ) !important;
	transform: translateY( -1px );
}
[id^="pricing-table-"] .plan-tab.active {
	background: var( --brand-cta ) !important;
	color: var( --brand-cta-text ) !important;
	border-color: var( --brand-cta ) !important;
	box-shadow: 0 8px 18px -8px rgba( 131, 88, 255, 0.45 );
}
[id^="pricing-table-"] .plan-tab.active:hover,
[id^="pricing-table-"] .plan-tab.active:focus {
	background: var( --brand-cta-hover ) !important;
	color: var( --brand-cta-text-hover ) !important;
	border-color: var( --brand-cta-hover ) !important;
}

/* Tooltip — replica el estilo del theme (jacarta-700 / blanco / sombra). */
[id^="pricing-table-"] .benefit-name .tooltip {
	background: var( --xb-jacarta-700 ) !important;
	color: #ffffff !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 12px;
	font-weight: 500;
	border-radius: 8px !important;
	box-shadow: 0 6px 20px rgba( 0, 0, 0, 0.18 );
}
[id^="pricing-table-"] .benefit-name .tooltip::after {
	border-top-color: var( --xb-jacarta-700 ) !important;
}

/* Spoiler content — espaciado y tipografía consistentes. */
[id^="pricing-table-"] .spoiler-content .benefit-column {
	padding: 24px !important;
	font-size: 14px;
	line-height: 1.65;
	color: var( --xb-jacarta-600 );
}
[id^="pricing-table-"] .spoiler-content .benefit-column p { margin: 0 0 10px; }
[id^="pricing-table-"] .spoiler-content .benefit-column p:last-child { margin-bottom: 0; }

/* Spacing del wrapper — mantenemos el max-width del plugin (1200px)
   pero usamos el container del theme para que respire en mobile. */
[id^="pricing-table-"].pricing-table-container {
	padding: 0 16px;
}

/* Tabla SIN secciones — el `<div class="benefit-column">` del header
   queda vacío y el plugin sólo lo pinta transparente, dejándolo
   ocupando 1/N del flex y empujando los planes a la derecha. Cuando
   no hay secciones (clase `has-no-sections` añadida por el plugin
   server-side) colapsamos la columna por completo para que los
   planes ocupen el 100% del ancho. Plus añadimos los radios de
   esquinas izquierdas en el primer plan y derechas en el último. */
[id^="pricing-table-"].has-no-sections .pricing-table-header .benefit-column,
[id^="pricing-table-"].has-no-sections .pricing-table-header.has-empty-header .benefit-column {
	display: none !important;
}
[id^="pricing-table-"].has-no-sections .pricing-table-header .plan-column:first-of-type {
	border-top-left-radius: var( --pt-radius );
	border-bottom-left-radius: var( --pt-radius );
}
[id^="pricing-table-"].has-no-sections .pricing-table-header .plan-column:last-of-type {
	border-bottom-right-radius: var( --pt-radius );
}

/* =====================================================================
 * Cells / columns / rows — theme look
 * =====================================================================
 * El plugin pinta por defecto:
 *   - bg            #f7f7f7
 *   - line (border) #ffffff, 3px
 *   - sin sombra
 * Aquí lo reescribimos al lenguaje visual del theme:
 *   - bg            white (light) / jacarta-700 (dark)
 *   - line          jacarta-100 (light) / jacarta-600 (dark), 1px
 *   - container con sombra suave + radio del theme
 *   - section title rows con tinta sutil
 *   - hover sutil de plan-column
 * Usamos `!important` en las var declarations porque el plugin emite
 * `--pt-*` al nivel del ID (specificity 1,0,0). Si el admin elige
 * colores propios desde el metabox del CPT, el theme manda — nota
 * documentada para evitar sorpresas.
 * ===================================================================== */
html [id^="pricing-table-"].pricing-table-container {
	--pt-bg:   #ffffff !important;
	--pt-line: var( --xb-jacarta-100 ) !important;
	/* Frame rainbow animado compartido con las coverflow cards
	   above-the-fold (`.page-home__cf-slide`) vía
	   `--cjt-rainbow-gradient`. Padding 2px + bg rainbow → ring 2px
	   alrededor del panel interior. */
	border: none;
	padding: 2px;
	background: var( --cjt-rainbow-gradient );
	background-size: 200% 100%;
	animation: cjt-card-rainbow 6s linear infinite;
	border-radius: var( --pt-radius );
	box-shadow: 0 8px 32px -16px rgba( 13, 16, 45, 0.12 );
	/* IMPORTANTE: NO usar `overflow: hidden` en el container — rompe
	   `position: sticky` del `.pricing-table-header`. */
}
/* Panel interior — bg TRANSPARENT (no `--pt-bg` sólido) para que la
   esquina rectangular del panel no asome detrás del corner redondeado
   del container. Las celdas de las filas tienen su propio bg que
   cubre todo el área visible — el panel ya no necesita aportar bg.
   El user lo pidió: "i can still see white square border i want the
   square part to be transparent so it cannot be seen". */
[id^="pricing-table-"] .pricing-table.desktop-view {
	background: transparent;
	border-radius: calc( var( --pt-radius ) - 2px );
}
/* En mobile el container apila `mobile-menu` (tabs) ARRIBA y la
   `mobile-view` (filas) DEBAJO. Para que el rainbow frame cierre
   limpio: el menu redondea sólo top, la mobile-view sólo bottom. */
[id^="pricing-table-"] .pricing-table-mobile-menu {
	background: var( --pt-bg );
	border-top-left-radius: calc( var( --pt-radius ) - 2px );
	border-top-right-radius: calc( var( --pt-radius ) - 2px );
}

/* `.cjt-pt-mobile-header-strip` — inyectada por JS del theme (ver
   functions.php). Sólo visible en mobile; en desktop el header text
   ya vive en `.desktop-view .pricing-table-header .benefit-column`
   (la celda con gradient rainbow + texto blanco). El strip es la
   versión mobile de eso: una franja NO sticky, con `background:
   transparent` para dejar ver el gradient rainbow del container que
   ya lo lleva como background animado, y texto blanco encima. */
[id^="pricing-table-"] .cjt-pt-mobile-header-strip {
	display: none; /* mostrada sólo en mobile via media query */
}
@media ( max-width: 1024px ) {
	[id^="pricing-table-"] .cjt-pt-mobile-header-strip {
		display: block;
		padding: 12px 16px;
		text-align: center;
		font-family: var( --xb-font-display );
		font-weight: 600;
		font-size: 14px;
		line-height: 1.35;
		letter-spacing: 0.01em;
		background: transparent; /* deja ver el rainbow del container */
		border-top-left-radius: calc( var( --pt-radius ) - 2px );
		border-top-right-radius: calc( var( --pt-radius ) - 2px );
		position: relative;
		z-index: 2; /* por encima del background, debajo de sticky */
	}
	/* Forzar texto BLANCO sobre el rainbow — mismo trato que el
	   `.desktop-view .pricing-table-header .benefit-column *` del
	   desktop. El `[gradient]` shortcode envuelve el texto en
	   `.cjt-gradient-text` que usa `color: transparent` +
	   `background-clip: text` + `-webkit-text-fill-color`; hay que
	   pisar las tres propiedades para que el blanco gane sobre el
	   gradient violeta→rosa→violeta del shortcode. */
	[id^="pricing-table-"] .cjt-pt-mobile-header-strip,
	[id^="pricing-table-"] .cjt-pt-mobile-header-strip * {
		color: #ffffff !important;
		-webkit-text-fill-color: #ffffff !important;
		background: none !important;
		background-clip: border-box !important;
		-webkit-background-clip: border-box !important;
	}
	/* Cuando hay strip, el mobile-menu pierde sus corners superiores
	   (los hereda el strip ahora). */
	[id^="pricing-table-"]:has( .cjt-pt-mobile-header-strip ) .pricing-table-mobile-menu {
		border-top-left-radius: 0;
		border-top-right-radius: 0;
	}
	/* Mismo trato si el menu es sticky: top corners cuadrados cuando
	   el strip se queda arriba (no sticky) y el menu se ancla bajo. */
	[id^="pricing-table-"]:has( .cjt-pt-mobile-header-strip ).has-sticky-header .pricing-table-mobile-menu {
		border-top-left-radius: 0;
		border-top-right-radius: 0;
	}
}
[id^="pricing-table-"] .pricing-table.mobile-view {
	background: var( --pt-bg );
	border-bottom-left-radius: calc( var( --pt-radius ) - 2px );
	border-bottom-right-radius: calc( var( --pt-radius ) - 2px );
}

/* Sticky mobile tabs — al scrollear en mobile las tabs Mensual/
   Anual/Vitalicio quedan ancladas bajo el navbar. Sin rainbow
   frame propio (mismo criterio que el desktop sticky-header): bg
   sólido + 1px jacarta border en top + lados. El user lo pidió:
   "on responsive the upper part is also not disappearing, i want
   the header sticky part to be the only upper part visible". */
@media ( max-width: 1024px ) {
	[id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu {
		position: sticky;
		top: 72px;
		z-index: 5;
		padding: 5px !important;
		background: var( --pt-bg );
		border-top:    1px solid var( --xb-jacarta-100 );
		border-left:   1px solid var( --xb-jacarta-100 );
		border-right:  1px solid var( --xb-jacarta-100 );
		border-bottom: 0;
		box-shadow: 0 6px 16px -10px rgba( 13, 16, 45, 0.12 );
	}	[id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu .plans-scrollable {
		background: var( --pt-bg );
		padding: 0;
		/* Tabs centradas en responsive (override del default
		   `.scrollable` que las alineaba a la izquierda). El user
		   lo pidió: "in responsive i want these buttons to be
		   centered, now they are on the left". */
		display: flex !important;
		flex-wrap: wrap !important;
		justify-content: center !important;
		gap: 6px !important;
	}
	/* Mobile-only: tabs Mensual/Anual/Vitalicio con padding-Y más
	   ajustado para colaborar con la compresión global del sticky. */
	[id^="pricing-table-"] .plan-tab {
		padding: 7px 18px !important;
	}
	body.admin-bar [id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu {
		top: 118px;
	}

	/* `.mobile-plan-header` (renderizado por JS dentro del
	   `.pricing-table-mobile-menu` junto a las tabs) — contiene el
	   precio + CTA del plan seleccionado. Sticky propio NO necesario:
	   el plan-header vive dentro del mobile-menu sticky, así que ambos
	   se mueven juntos. Estilo del bloque inline. */
	[id^="pricing-table-"] .pricing-table-mobile-menu .mobile-plan-header {
		margin-top: 6px;
		padding: 8px 12px 4px;
		text-align: center;
	}
	[id^="pricing-table-"] .pricing-table-mobile-menu .mobile-plan-header .plan-column {
		display: block;
	}

	/* Cuando el navbar se auto-oculta al scrollear hacia abajo
	   (`body.xb-nav-hidden` añadido por el script de header.php),
	   las stickies de la pricing-table suben para no dejar el strip
	   vacío de 72px arriba. El user lo pidió: "still on mobile, now
	   sticky is working but the navbarheader is not completely
	   disappearing now". */
	body.xb-nav-hidden [id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu {
		top: 0;
	}
	body.xb-nav-hidden.admin-bar [id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu {
		top: 46px; /* sólo admin bar, navbar fuera */
	}

	/* Smooth transition on `top` para la mobile-menu también. */
	[id^="pricing-table-"].has-sticky-header .pricing-table-mobile-menu {
		transition: top 0.35s cubic-bezier( .4, 0, .2, 1 ),
		            background-position 0s linear;
	}
}

/* Sticky header en desktop — al scrollear la página el bloque de
   planes (Mensual / Anual / Vitalicio + precio + CTA) queda anclado
   bajo el navbar hasta que el final de la tabla salga del viewport.
   Sólo desktop: en mobile el layout es `.mobile-view` (tabs +
   single plan column) y la sticky no aplica. El user lo pidió: "on
   scroll on desktop, this upper part where prices are, get sticky,
   so its fixed until finishing table". */
@media ( min-width: 1025px ) {
	[id^="pricing-table-"].has-sticky-header .desktop-view .pricing-table-header {
		position: sticky;
		top: 78px; /* altura del navbar fijo (ver `body { padding-top: 78px }`) */
		z-index: 5;
		/* Sólo la fila de headers (Mensual/Anual/Vitalicio) sticky.
		   El user pidió: "pricing header will have border on top
		   left and right but no bottom" — usamos `border` 1px
		   jacarta-100 en top + lados (heredando el lenguaje visual
		   del theme) y dejamos el bottom abierto para que las filas
		   inferiores fluyan sin línea horizontal. */
		background: var( --pt-bg );
		border-top:    1px solid var( --xb-jacarta-100 );
		border-left:   1px solid var( --xb-jacarta-100 );
		border-right:  1px solid var( --xb-jacarta-100 );
		border-bottom: 0;
		box-shadow: 0 6px 16px -10px rgba( 13, 16, 45, 0.12 );
	}	/* Cuando el WP admin bar está presente, el navbar baja 32px y el
	   sticky-top sigue su offset (32 admin bar + 78 navbar). */
	body.admin-bar [id^="pricing-table-"].has-sticky-header .desktop-view .pricing-table-header {
		top: 110px;
	}

	/* Rainbow gradient en el border-bottom del header — visible
	   siempre (sticky o no), asoma como una línea fina que cierra
	   el bloque del header hacia abajo y casa con el frame rainbow
	   exterior del container. El user lo pidió: "do so that the
	   last border of the pricing-table-header (the sticky part)
	   also has a gradient border all the time". */
	[id^="pricing-table-"] .desktop-view .pricing-table-header {
		position: relative;
	}
	[id^="pricing-table-"] .desktop-view .pricing-table-header::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		/* Pseudo más alto que 2px: cubre el área de las esquinas
		   redondeadas para que el gradient pueda CURVAR siguiendo el
		   radio. Una `mask` lineal vertical recorta a los últimos
		   2px (incluida la curva) — el resto del pseudo queda
		   transparente, así sólo se ve la "ring" rainbow del bottom.
		   El user lo pidió: "i want this effect to be applied on the
		   rounded corner, i dont want it to look square". */
		height: var( --pt-radius );
		background-image: var( --cjt-rainbow-gradient );
		background-size: 200% 100%;
		background-repeat: repeat;
		animation: cjt-card-rainbow 6s linear infinite;
		pointer-events: none;
		z-index: 6;
		border-bottom-left-radius: calc( var( --pt-radius ) - 2px );
		border-bottom-right-radius: calc( var( --pt-radius ) - 2px );
		-webkit-mask: linear-gradient( transparent calc( 100% - 2px ), #000 0 );
		        mask: linear-gradient( transparent calc( 100% - 2px ), #000 0 );
	}
	/* Esquinas inferiores de las celdas del header redondeadas para
	   que casen con el strip rainbow curvado en las esquinas. */
	[id^="pricing-table-"] .desktop-view .pricing-table-header .benefit-column {
		border-bottom-left-radius: calc( var( --pt-radius ) - 2px ) !important;
	}
	[id^="pricing-table-"] .desktop-view .pricing-table-header .plan-column:last-child {
		border-bottom-right-radius: calc( var( --pt-radius ) - 2px ) !important;
	}
	/* Sticky desktop header sube a top:0 cuando el navbar se oculta. */
	body.xb-nav-hidden [id^="pricing-table-"].has-sticky-header .desktop-view .pricing-table-header {
		top: 0;
	}
	body.xb-nav-hidden.admin-bar [id^="pricing-table-"].has-sticky-header .desktop-view .pricing-table-header {
		top: 32px; /* sólo admin bar, navbar fuera */
	}
	[id^="pricing-table-"].has-sticky-header .desktop-view .pricing-table-header {
		transition: top 0.35s cubic-bezier( .4, 0, .2, 1 );
	}
}

/* 1px borders en lugar de los 3px del plugin. Mantienen el patrón
   border-right + border-bottom (last-child / last-row los anula). */
[id^="pricing-table-"] .plan-column,
[id^="pricing-table-"] .benefit-column {
	border-right-width: 1px !important;
	border-bottom-width: 1px !important;
	border-color: var( --xb-jacarta-100 ) !important;
	padding: 18px 18px !important;
}
[id^="pricing-table-"] .pricing-table-header .plan-column {
	padding: 10px 18px !important;
}

/* Gradient sutil vertical en las plan-columns — reemplaza el bg
   sólido `--pt-bg` con un fade `--pt-bg → brand-cta-tint(8%)`. Da
   profundidad visual a las celdas. */
[id^="pricing-table-"] .plan-column {
	background: linear-gradient(
		180deg,
		var( --pt-bg ) 0%,
		color-mix( in srgb, var( --brand-cta ) 8%, var( --pt-bg ) ) 100%
	) !important;
}

/* Header benefit-column (top-left empty cell) — usa el rainbow
   animado completo (mismo gradient que el frame del container y
   el mobile-menu sticky). Importante: `background-repeat: repeat`
   (no `no-repeat`) para que el ciclo de la animación 0→200% no
   deje un "white curtain" cuando la imagen sale de cuadro. El user
   lo pidió: "the rainbow effect has some kind of white curtain, i
   want this removed and instead that the rainbow effect is
   looping". Texto en blanco para contraste. */
[id^="pricing-table-"] .desktop-view .pricing-table-header .benefit-column {
	background-image: var( --cjt-rainbow-gradient ) !important;
	background-size: 200% 100% !important;
	background-repeat: repeat !important;
	animation: cjt-card-rainbow 6s linear infinite !important;
	color: #ffffff !important;
}
[id^="pricing-table-"] .desktop-view .pricing-table-header .benefit-column * {
	color: #ffffff !important;
}

/* Esquinas superiores del header — radio interior (`--pt-radius - 2`)
   para que la curva de la celda calce con la curva interna del
   rainbow border del container (que tiene padding 2px). El user
   pidió: "in desktop the rounded corners on top should be from the
   header, not from the behind table" — con este offset el rainbow
   strip envuelve las celdas a 2px constantes en lugar de mostrar
   dos curvas desalineadas. */
[id^="pricing-table-"] .desktop-view .pricing-table-header .benefit-column {
	border-top-left-radius: calc( var( --pt-radius ) - 2px ) !important;
}
[id^="pricing-table-"] .desktop-view .pricing-table-header .plan-column:last-child {
	border-top-right-radius: calc( var( --pt-radius ) - 2px ) !important;
}

/* Section title rows — fondo del theme (mismo `--pt-bg` que el resto
   de la tabla, blanco en light / jacarta-700 en dark). Lo que marca
   la sección no es un fondo gris sino: padding compacto + tipografía
   accent (h4 en `--brand-cta`, uppercase) y un fino borde top para
   separar visualmente de la sección anterior. */
[id^="pricing-table-"] .section-title-row .benefit-column,
[id^="pricing-table-"] .section-title-row .plan-column {
	background: var( --pt-bg ) !important;
	padding-top: 14px !important;
	padding-bottom: 14px !important;
}

/* Cells de la section-title-row alineadas al TOP — sin esto los
   cells single-line (`BENEFICIOS`, `ahorra de por vida`) centraban
   su contenido en una row stretched a la altura del cell más alto
   (multi-line tipo `3 meses gratis<br>equivale a 15€/mes`), dejando
   un strip vacío debajo del texto antes del primer benefit row.
   El user lo pidió: "theres some separation on the first benefit
   row ... in this one theres like space between that should not be
   there". */
[id^="pricing-table-"] .section-title-row .plan-column {
	justify-content: flex-start !important;
}
[id^="pricing-table-"] .section-title-row .benefit-column {
	align-items: flex-start !important;
}
[id^="pricing-table-"] .section-title-row .section-content {
	padding: 0 !important;
}

/* `.section-title-row` SIN border-top — el user lo pidió "no top
   border" para que no se vea una línea horizontal al cerrar la
   sticky-header. La separación entre secciones la marcan ya el bg
   del header (cuando no sticky) y el divisor del propio
   pricing-table-header. */

/* Colapsar `.section-title-row` VACÍAS — cuando una `section` del
   plugin tiene `title=""` Y `content` vacío en todos los planes, el
   plugin igualmente emite el `<div class="pricing-table-row section-title-row">`
   con su padding 14px+14px + border-bottom 1px. Eso aparece como una
   franja vacía con doble separador justo debajo de la sección
   anterior. Patrón típico: la primera sección actúa como "header"
   visible (ej. "Beneficios" + descripciones por plan) y la siguiente
   es un wrapper title-less para los benefits — sin esta regla, entre
   "BENEFICIOS" y el primer benefit aparece un strip vacío.
   `:not(:has(<contenido no vacío>))` detecta el caso y lo oculta. */
[id^="pricing-table-"] .section-title-row:not(:has( .benefit-column h4:not(:empty), .plan-column .section-content:not(:empty) )) {
	display: none !important;
}

/* Hover sobre la plan-column (sólo desktop, no en collapsed) —
   intensifica el gradient base para que el usuario perciba el
   estado hover. */
@media ( hover: hover ) {
	[id^="pricing-table-"] .plan-column:not( .collapsed ):hover {
		background: linear-gradient(
			180deg,
			color-mix( in srgb, var( --brand-cta ) 4%, var( --pt-bg ) ) 0%,
			color-mix( in srgb, var( --brand-cta ) 14%, var( --pt-bg ) ) 100%
		) !important;
		transition: background 0.18s ease;
	}
}

/* Spoiler-toggle "+" — adoptamos el accent del theme. */
[id^="pricing-table-"] .spoiler-toggle.enabled {
	color: var( --brand-cta );
}/* En dark el fondo del title-row es el mismo `--pt-bg` (jacarta-700)
   que el resto. El acento brand-cta del top-border ya da contraste
   suficiente — no hace falta override. */
@media ( hover: hover ) {}
/* Mobile small adjustments */
@media ( max-width: 768px ) {
	[id^="pricing-table-"] .plan-header h3 {
		font-size: 16px;
	}
	[id^="pricing-table-"] .get-button {
		padding: 10px 20px !important;
		/* font-size queda en `--brand-body-size` heredado de la regla
		   global; no lo overrideamos para mantener el theme body. */
	}
}

/* ===================================================================
 * Template "Centro de ayuda" (`template-centro-ayuda.php`).
 * Estructura clonada de xhibiter/HTML/dist/help-center.html:
 *   - Hero centrado con H1 + search.
 *   - Grid de sub-categorías ("O navega por categorías").
 *   - Accordion de FAQs (misma fuente theme_mod que la home).
 * =================================================================== */

.page-help { background: transparent; }

/* HERO con banner y overlay oscuro, similar a la sección de cabecera
   de help-center.html (`bg-cover bg-center after:bg-jacarta-900/60`). */
.page-help__hero {
	position: relative;
	padding: 96px 24px;
	background: linear-gradient( 180deg, #131740 0%, #0D102D 100% );
	color: #ffffff;
	overflow: hidden;
}
.page-help__hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background:
		radial-gradient( 600px 220px at 20% 30%, rgba( 131, 88, 255, 0.35 ), transparent 60% ),
		radial-gradient( 700px 260px at 80% 70%, rgba( 236, 72, 153, 0.25 ), transparent 60% );
	z-index: 0;
}
.page-help__hero-inner {
	position: relative;
	z-index: 1;
	max-width: 720px;
	margin: 0 auto;
	text-align: center;
}
.page-help__hero-title {
	font-family: var( --brand-h1-family, var( --xb-font-display ) );
	font-size: clamp( 32px, 5vw, 48px );
	font-weight: var( --brand-h1-weight, 700 );
	line-height: 1.15;
	color: #ffffff;
	margin: 0 0 24px;
}

/* Search box: input full-width con icono lupa absolutamente posicionado. */
.page-help__search {
	position: relative;
	max-width: 460px;
	margin: 0 auto;
}
.page-help__search-input {
	width: 100%;
	padding: 14px 16px 14px 48px;
	border: 1px solid rgba( 255, 255, 255, 0.18 );
	border-radius: 16px;
	background: rgba( 255, 255, 255, 0.95 );
	color: var( --xb-jacarta-700 );
	font-family: var( --xb-font-body );
	font-size: 16px;
	box-shadow: 0 8px 24px -10px rgba( 0, 0, 0, 0.25 );
}
.page-help__search-input:focus {
	outline: none;
	box-shadow: 0 0 0 3px rgba( 131, 88, 255, 0.35 );
}
.page-help__search-icon {
	position: absolute;
	top: 0;
	left: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 100%;
	pointer-events: none;
}
.page-help__search-icon svg {
	width: 18px;
	height: 18px;
	fill: var( --xb-jacarta-500 );
}

/* CATEGORÍAS — grid 3 cols ≥ md / 2 cols ≥ sm / 1 col mobile. Mantiene
   `rounded-2lg` (≈16px), `border-jacarta-100`, `bg-white`. Hover lift
   con sombra grande (xhibiter `hover:shadow-lg`). */
.page-help__cats {
	padding: 80px 24px 32px;
	background: transparent;
}
.page-help__cats-inner,
.page-help__faq-inner,
.page-help__extra-inner {
	max-width: 1200px;
	margin: 0 auto;
}
.page-help__section-title {
	font-family: var( --brand-h2-family, var( --xb-font-display ) );
	font-size: var( --brand-h2-size, 28px );
	font-weight: var( --brand-h2-weight, 700 );
	line-height: 1.25;
	color: var( --xb-jacarta-700 );
	margin: 0 0 32px;
	text-align: center;
}
.page-help__cats-grid {
	display: grid;
	/* Mobile (≤639px): 2 columnas (user lo pidió) — antes era 1.
	   Tablet (≥640px): 2 columnas (sin cambio).
	   Desktop (≥900px): 3 columnas. */
	grid-template-columns: repeat( 2, 1fr );
	gap: 18px;
}
@media ( min-width: 640px ) {
	.page-help__cats-grid { grid-template-columns: repeat( 2, 1fr ); gap: 28px; }
}
@media ( min-width: 900px ) {
	.page-help__cats-grid { grid-template-columns: repeat( 3, 1fr ); }
}
/* Border rainbow animado idéntico al de los coverflow cards de la home
   (`.page-home__cf-slide`). Técnica de un solo elemento:
     - `border: 2px solid transparent` reserva 2px de espacio en el
       perímetro.
     - `background-image` lleva DOS capas: la primera es el relleno del
       contenido (blanco / jacarta-700 en dark), la segunda es el
       rainbow del `--cjt-rainbow-gradient`.
     - `background-origin: border-box` hace que ambas capas se
       extiendan desde el borde exterior; `background-clip` corta la
       primera al `padding-box` (interior limpio) y la segunda al
       `border-box` (sólo asoma en los 2px del borde).
     - `background-size: auto, 200% 100%` + `cjt-card-rainbow` 6s
       reutiliza el mismo keyframe que la home — mismo ritmo, mismas
       paradas de color. */
.page-help__cat-card {
	display: block;
	border: 2px solid transparent;
	border-radius: 16px;
	background-image:
		linear-gradient( #ffffff, #ffffff ),
		var( --cjt-rainbow-gradient );
	background-origin: border-box;
	background-clip: padding-box, border-box;
	background-size: auto, 200% 100%;
	/* CRÍTICO: la capa interior NO se repite (el relleno blanco/jacarta
	   ocupa todo el padding-box), pero la capa del rainbow SÍ tiene que
	   tilear horizontalmente. Si no, cuando la animación arrastra el
	   gradient hacia la izquierda más allá del borde, sale un hueco
	   donde "asoma" el fill blanco → el "white panel crossing" que se
	   veía. Con repeat-x el siguiente tile entra justo al salir el
	   anterior, y como la rampa del gradient empieza/termina en el
	   mismo color (#8358FF, definido en `--cjt-rainbow-gradient`) la
	   unión es invisible — mismo principio que `.page-home__cf-slide`
	   y la pricing-table header. */
	background-repeat: no-repeat, repeat-x;
	animation: cjt-card-rainbow 6s linear infinite;
	padding: 28px 24px;
	text-align: center;
	text-decoration: none;
	color: inherit;
	transition: box-shadow 200ms ease, transform 200ms ease;
}.page-help__cat-card:hover {
	box-shadow: 0 18px 30px -12px rgba( 13, 16, 45, 0.18 );
	transform: translateY( -2px );
}
.page-help__cat-title {
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
	margin: 0 0 10px;
}.page-help__cat-desc {
	font-family: var( --xb-font-body );
	font-size: 15px;
	line-height: 1.55;
	color: var( --xb-jacarta-500 );
	margin: 0;
}.page-help__cats-empty {
	text-align: center;
	color: var( --xb-jacarta-500 );
	font-family: var( --xb-font-body );
	margin: 0;
}

/* FAQ — mismo lenguaje visual que `.page-home__faq-*` para que el
   admin no perciba diferencia entre la home y el centro de ayuda. */
.page-help__faq {
	padding: 48px 24px 96px;
	background: transparent;
}
.page-help__faq-inner { max-width: 1100px; }
.page-help__faq-lead {
	font-family: var( --xb-font-body );
	font-size: 18px;
	line-height: 1.6;
	color: var( --xb-jacarta-500 );
	max-width: 460px;
	margin: -16px auto 40px;
	text-align: center;
}/* Grid 2 columnas (≥ 720px). Idéntico patrón al de la home: ambas
   columnas `1fr 1fr`, gap controla spacing. Mobile = 1 columna. */
.page-help__faq-list {
	max-width: 1100px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px;
}
@media ( min-width: 720px ) {
	.page-help__faq-list {
		grid-template-columns: 1fr 1fr;
		gap: 16px 20px;
		align-items: start;
	}
}
.page-help__faq-item {
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 12px;
	overflow: hidden;
	background: #ffffff;
	transition: box-shadow 200ms ease;
}.page-help__faq-item:hover { box-shadow: 0 6px 18px -10px rgba( 13, 16, 45, 0.18 ); }
.page-help__faq-q {
	all: unset;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	padding: 16px 20px;
	font-family: var( --xb-font-display );
	font-weight: 600;
	font-size: var( --brand-body-size, 16px );
	line-height: 1.4;
	color: var( --xb-jacarta-700 );
	cursor: pointer;
	text-align: left;
	gap: 16px;
}.page-help__faq-q:focus-visible {
	outline: 2px solid var( --brand-cta );
	outline-offset: -2px;
}
.page-help__faq-q-text { flex: 1 1 auto; }
.page-help__faq-q-icon {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	fill: var( --xb-jacarta-700 );
	transition: transform 220ms ease;
}.page-help__faq-q[aria-expanded="true"] .page-help__faq-q-icon {
	transform: rotate( 180deg );
}
.page-help__faq-a {
	border-top: 1px solid var( --xb-jacarta-100 );
	padding: 16px 20px;
	font-family: var( --xb-font-body );
	font-size: var( --brand-body-size, 16px );
	line-height: 1.6;
	color: var( --xb-jacarta-500 );
	background: #ffffff;
}.page-help__faq-a > :first-child { margin-top: 0; }
.page-help__faq-a > :last-child { margin-bottom: 0; }
.page-help__faq-a p { margin: 0 0 12px; }
.page-help__faq-a p:last-child { margin-bottom: 0; }

.page-help__extra {
	padding: 0 24px 80px;
}

@media ( max-width: 540px ) {
	.page-help__hero { padding: 64px 16px; }
	.page-help__cats { padding: 56px 16px 24px; }
	.page-help__faq  { padding: 32px 16px 64px; }
}

/* ===================================================================
 * Subcategorías del Centro de ayuda (category-help-center.php).
 * Layout: aside sticky a la izquierda con TOC, contenido a la derecha
 * con todos los posts concatenados. En mobile el TOC pasa arriba en
 * un panel colapsable estático (no sticky para no ocupar viewport).
 * =================================================================== */

.page-help-cat {
	padding: 64px 24px 96px;
	background: transparent;
}
.page-help-cat__layout {
	max-width: 1200px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: 1fr;
	gap: 32px;
}
@media ( min-width: 900px ) {
	.page-help-cat__layout {
		grid-template-columns: 260px 1fr;
		gap: 56px;
		align-items: start;
	}
}

/* --- Sidebar TOC ---
   IMPORTANTE: NO sticky. El user lo pidió 2026-05-23: "i still want the
   navigation bar on the left, i just don't want it to be sticky". El
   sidebar scrollea con la página como un bloque normal. */
.page-help-cat__toc {
	background: #ffffff;
	border: 1px solid var( --xb-jacarta-100 );
	border-radius: 16px;
	padding: 20px 20px 16px;
}
.page-help-cat__back {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	text-decoration: none;
	color: var( --xb-jacarta-500 );
	font-family: var( --xb-font-body );
	font-size: 13px;
	margin: 0 0 12px;
}
.page-help-cat__back:hover { color: var( --brand-cta ); }
.page-help-cat__back svg { flex-shrink: 0; }
.page-help-cat__toc-title {
	font-family: var( --xb-font-display );
	font-size: 18px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
	margin: 0 0 12px;
	line-height: 1.3;
}
/* 3er nivel del TOC: subgrupos temáticos. Más pequeño + mayúsculas +
   color jacarta-400 para crear jerarquía clara entre el título de la
   categoría (grande, negro) y los enlaces a artículos (medio, negro). */
.page-help-cat__toc-group {
	font-family: var( --xb-font-display );
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.6px;
	color: var( --xb-jacarta-400 );
	margin: 18px 0 6px;
	padding: 0 0 4px;
}
.page-help-cat__toc-list {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid var( --xb-jacarta-100 );
}
.page-help-cat__toc-list li {
	border-bottom: 1px solid var( --xb-jacarta-100 );
}
.page-help-cat__toc-link {
	display: block;
	padding: 10px 4px;
	font-family: var( --xb-font-body );
	font-size: 14px;
	line-height: 1.4;
	color: var( --xb-jacarta-700 );
	text-decoration: none;
	transition: color 150ms ease, padding-left 150ms ease;
}
.page-help-cat__toc-link:hover,
.page-help-cat__toc-link:focus-visible {
	color: var( --brand-cta );
	padding-left: 8px;
}
.page-help-cat__toc-link.is-active {
	color: var( --brand-cta );
	font-weight: 600;
}

/* --- Contenido derecha --- */
.page-help-cat__content {
	min-width: 0;
}
.page-help-cat__intro {
	font-family: var( --xb-font-body );
	font-size: 17px;
	line-height: 1.6;
	color: var( --xb-jacarta-500 );
	margin: 0 0 32px;
	padding: 0 0 24px;
	border-bottom: 1px solid var( --xb-jacarta-100 );
}.page-help-cat__empty {
	font-family: var( --xb-font-body );
	color: var( --xb-jacarta-500 );
	font-style: italic;
}

.page-help-cat__article {
	margin: 0 0 48px;
	scroll-margin-top: 24px; /* offset cuando el TOC link saltea aquí */
}
.page-help-cat__article:last-child { margin-bottom: 0; }
.page-help-cat__article-title {
	font-family: var( --brand-h2-family, var( --xb-font-display ) );
	font-size: clamp( 24px, 3vw, 30px );
	font-weight: var( --brand-h2-weight, 700 );
	line-height: 1.25;
	color: var( --xb-jacarta-700 );
	margin: 0 0 16px;
}.page-help-cat__article-body {
	font-family: var( --xb-font-body );
	font-size: var( --brand-body-size, 16px );
	line-height: 1.7;
	color: var( --xb-jacarta-700 );
}.page-help-cat__article-body > :first-child { margin-top: 0; }
.page-help-cat__article-body > :last-child  { margin-bottom: 0; }
.page-help-cat__article-body p { margin: 0 0 16px; }
.page-help-cat__article-body p:last-child { margin-bottom: 0; }
.page-help-cat__article-body a { color: var( --brand-cta ); text-decoration: underline; }
.page-help-cat__article-body a:hover { color: var( --brand-cta-hover ); }
.page-help-cat__article-body img,
.page-help-cat__article-body video {
	max-width: 100%;
	height: auto;
	border-radius: 12px;
	margin: 16px 0;
}
.page-help-cat__article-body h2,
.page-help-cat__article-body h3,
.page-help-cat__article-body h4 {
	font-family: var( --xb-font-display );
	color: var( --xb-jacarta-700 );
	margin: 28px 0 12px;
	line-height: 1.3;
}
.page-help-cat__article-body h3 { font-size: 20px; }
.page-help-cat__article-body h4 { font-size: 17px; }
@media ( max-width: 540px ) {
	.page-help-cat { padding: 32px 16px 64px; }
	.page-help-cat__toc { padding: 16px; }
	.page-help-cat__article { margin-bottom: 32px; }
}

/* =====================================================================
 * Lista de espera ("En espera") — feature de precio objetivo.
 *
 *   - Modal `cjt-wl-modal`: input de precio objetivo (single + tab cuenta).
 *   - "Estás en espera (…)" bajo el contador del single.
 *   - Botones de la card en /cuenta/?action=mi-lista-de-espera.
 * ===================================================================== */

/* Estado "Estás en espera" bajo el contador del single — mismo color
   verde-positivo que "El voluntario eres tú". */
.single-conjunta__waitlist-mine {
	display: block;
	margin-top: 2px;
	color: #2563eb;
	font-family: var( --xb-font-body );
	font-size: 13px;
	font-weight: 600;
}

/* --- Modal "Me apunto si…" / "Editar condiciones" --- */
.cjt-wl-modal[hidden] { display: none !important; }
/* User 2026-06-06: bfcache defensive guard. Body class is shared with
   `.cjt-confirm` — `inc/waitlist.php` open() does
   `document.body.classList.add('cjt-confirm-open')` (not a dedicated wl
   class), so we gate on the same selector. Same pattern as the .cjt-confirm
   guard below. */
body:not(.cjt-confirm-open) .cjt-wl-modal { display: none !important; }
.cjt-wl-modal {
	position: fixed;
	inset: 0;
	z-index: 10001;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
}
.cjt-wl-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba( 13, 16, 45, 0.5 );
}
.cjt-wl-modal__dialog {
	position: relative;
	background: #ffffff !important;
	color: var( --xb-jacarta-700 );
	max-width: 420px !important;
	width: calc( 100% - 32px ) !important;
	margin: 0 auto !important;
	padding: 26px 24px !important;
	border-radius: 14px !important;
	box-shadow: 0 24px 60px rgba( 13, 16, 45, 0.25 );
	font-family: var( --xb-font-body );
	box-sizing: border-box !important;
}
.cjt-wl-modal__title {
	margin: 0 0 8px !important;
	font-family: var( --xb-font-display );
	font-size: 20px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
}
.cjt-wl-modal__lead {
	margin: 0 0 14px;
	font-size: 14px;
	line-height: 1.45;
	color: var( --xb-jacarta-500 );
}
.cjt-wl-modal__field {
	display: flex;
	align-items: center;
	gap: 8px;
	border: 2px solid var( --xb-jacarta-100 );
	border-radius: 10px;
	padding: 8px 12px;
	margin: 0 0 8px;
}
.cjt-wl-modal__field:focus-within { border-color: #10b981; }
.cjt-wl-modal__currency {
	font-size: 18px;
	font-weight: 700;
	color: var( --xb-jacarta-400 );
}
.cjt-wl-modal__input,
.cjt-wl-modal input.cjt-wl-modal__input {
	flex: 1 1 auto;
	min-width: 0;
	border: 0 !important;
	outline: none !important;
	background: transparent !important;
	box-shadow: none !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 20px !important;
	font-weight: 700 !important;
	color: var( --xb-jacarta-700 ) !important;
	padding: 4px 0 !important;
}
.cjt-wl-modal__hint {
	margin: 0 0 10px;
	font-size: 12px;
	color: var( --xb-jacarta-400 );
}
.cjt-wl-modal__error {
	margin: 0 0 10px;
	font-size: 13px;
	font-weight: 600;
	color: #c0392b;
}
.cjt-wl-modal__error[hidden] { display: none; }
.cjt-wl-modal__actions {
	display: flex;
	flex-direction: column;
	gap: 6px;
}
.cjt-wl-modal__confirm,
.cjt-wl-modal button.cjt-wl-modal__confirm,
body .cjt-wl-modal button.cjt-wl-modal__confirm {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 100% !important;
	padding: 12px 18px !important;
	border: 0 !important;
	border-radius: 999px !important;
	background: #10b981 !important;
	color: #ffffff !important;
	cursor: pointer !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 14px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	transition: background 0.18s ease !important;
}
.cjt-wl-modal__confirm:hover,
.cjt-wl-modal__confirm:focus { background: #0e9c6f !important; outline: none !important; }
.cjt-wl-modal__confirm:disabled { opacity: 0.6 !important; cursor: default !important; }
.cjt-wl-modal__cancel,
.cjt-wl-modal button.cjt-wl-modal__cancel,
body .cjt-wl-modal button.cjt-wl-modal__cancel {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: auto !important;
	margin: 2px auto 0 !important;
	padding: 6px 4px !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	color: #0e9c6f !important;
	cursor: pointer !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	text-transform: none !important;
	letter-spacing: 0 !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
}
.cjt-wl-modal__cancel:hover,
.cjt-wl-modal__cancel:focus { color: #0a7752 !important; background: transparent !important; outline: none !important; }

/* "Desapuntarme" dentro del modal de edición — mismo estilo que Cancelar
   pero en rojo (acción de salir de la lista de espera). */
.cjt-wl-modal__leave,
.cjt-wl-modal button.cjt-wl-modal__leave,
body .cjt-wl-modal button.cjt-wl-modal__leave {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: auto !important;
	margin: 2px auto 0 !important;
	padding: 6px 4px !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	color: #c0392b !important;
	cursor: pointer !important;
	font-family: var( --xb-font-body ) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	text-transform: none !important;
	letter-spacing: 0 !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
}
.cjt-wl-modal__leave:hover,
.cjt-wl-modal__leave:focus { color: #8a2820 !important; background: transparent !important; outline: none !important; }
.cjt-wl-modal__leave[hidden] { display: none !important; }

/* --- Card buttons en /cuenta/?action=mi-lista-de-espera --- */
/* "Editar condiciones" — pill azul (mismo lenguaje que Panel de voluntario). */
.cjt-card__waitlist-edit,
body.mepr-mod-chrome .cjt-card__waitlist-edit {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	padding: 8px 14px !important;
	margin: 6px 4px 0 0 !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	cursor: pointer !important;
	background: #3b82f6 !important;
	color: #ffffff !important;
	line-height: 1.2 !important;
	transition: background 0.18s ease !important;
}
.cjt-card__waitlist-edit:hover,
.cjt-card__waitlist-edit:focus,
body.mepr-mod-chrome .cjt-card__waitlist-edit:hover,
body.mepr-mod-chrome .cjt-card__waitlist-edit:focus {
	background: #2563eb !important;
	color: #ffffff !important;
	outline: none !important;
}
/* "Apuntarme manualmente" — pill verde (acción afirmativa, igual que Pagar). */
.cjt-card__waitlist-join,
body.mepr-mod-chrome .cjt-card__waitlist-join {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 6px !important;
	padding: 8px 14px !important;
	margin: 6px 4px 0 0 !important;
	font-family: var( --xb-font-display ) !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.4px !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	cursor: pointer !important;
	background: #10b981 !important;
	color: #ffffff !important;
	line-height: 1.2 !important;
	transition: background 0.18s ease !important;
}
.cjt-card__waitlist-join:hover,
.cjt-card__waitlist-join:focus,
body.mepr-mod-chrome .cjt-card__waitlist-join:hover,
body.mepr-mod-chrome .cjt-card__waitlist-join:focus {
	background: #0e9c6f !important;
	color: #ffffff !important;
	outline: none !important;
}

/* Wrapper de la pestaña "Mi lista de espera" — reusa el look de
   "Mis conjuntas" (mismo grid `.xb-collections__grid.cjt-grid`). */
.mod-mepr-mi-lista-espera__title {
	font-family: var( --xb-font-display );
	font-size: 28px;
	font-weight: 700;
	color: var( --xb-jacarta-700 );
	margin: 0 0 8px;
}
.mod-mepr-mi-lista-espera__lead {
	margin: 0 0 22px;
	font-size: 15px;
	line-height: 1.5;
	color: var( --xb-jacarta-500 );
}
.mod-mepr-mi-lista-espera__flash {
	margin: 0 0 18px;
	padding: 12px 16px;
	border-radius: 10px;
	font-size: 14px;
	font-weight: 600;
}
.mod-mepr-mi-lista-espera__flash.--ok  { background: #e7f8f0; color: #0a7752; }
.mod-mepr-mi-lista-espera__flash.--err { background: #fdeceb; color: #b32d2e; }
.mod-mepr-mi-lista-espera__empty {
	font-size: 15px;
	line-height: 1.5;
	color: var( --xb-jacarta-500 );
}

/* ==========================================================================
   Spinner de click (acciones de conjunta: apuntarse / desapuntarse / …)
   Se inyecta por JS (functions.php → wp_footer #conjuntasorg-click-spinner)
   en las coordenadas del cursor. Disco blanco con arco azul girando.
   ========================================================================== */
.cjt-click-spinner {
	position: fixed;
	z-index: 99999;
	width: 34px;
	height: 34px;
	margin: 0;
	transform: translate( -50%, -50% );
	pointer-events: none;
}
.cjt-click-spinner__ring {
	display: block;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	border: 3px solid rgba( 12, 99, 231, 0.22 );
	border-top-color: #0c63e7;
	background: rgba( 255, 255, 255, 0.92 );
	box-shadow: 0 2px 10px rgba( 13, 16, 45, 0.20 );
	animation: cjt-click-spin 0.6s linear infinite;
}
@keyframes cjt-click-spin {
	to { transform: rotate( 360deg ); }
}
@media ( prefers-reduced-motion: reduce ) {
	.cjt-click-spinner__ring { animation-duration: 1.4s; }
}
