/*
 Theme Name:   Bricks Child Theme
 Theme URI:    https://bricksbuilder.io/
 Description:  Use this child theme to extend Bricks.
 Author:       Bricks
 Author URI:   https://bricksbuilder.io/
 Template:     bricks
 Version:      1.1-nx-2026-09-18m
 Text Domain:  bricks
*/
/* NEXEVO · style.css · 2026-09-01 13:50 */

/* ═══════════════════════════════════════════════════════════════════════════
   NEXEVO — hoja global del sitio
   ORIGEN: 3-montaje/00-css-global.css. NO se edita aquí.
   Se edita allí, se vuelve a copiar entera y se sube. Si alguien la retoca
   directamente en el servidor, el siguiente despliegue se lo lleva por delante.
   functions.php encola nx-{BUILD}.css (no style.css) para que el CDN y el
   teléfono no puedan devolver una hoja de hace un año. Al cambiar CSS se
   sube NX_CSS_BUILD y se regenera con python3 4-wordpress/sella-css.py.

   LiteSpeed ya no recorta esta hoja: functions.php apaga Unique CSS, CSS
   Combine y CSS Async en cada petición. Antes había que purgar a mano y el
   fallo volvía solo, porque UCSS se regenera con la primera visita.
   ═══════════════════════════════════════════════════════════════════════════ */

/* =============================================================================
   NEXEVO — 00-css-global.css
   Ámbito: todo el sitio. Se pega una sola vez.

   Orden del archivo (según normas de desarrollo):
     1  :root            tokens: color, tipografía, espaciado, tiempos, medidas
     2  reset
     3  tipografía base
     4  utilidades
     5  botones
     6  componentes
     7  cabecera y pie
     8  bloques de página
     9  estados           :hover :focus-visible
     10 media queries
     11 prefers-reduced-motion

   Reglas: cero style="…" en el HTML. Cero CSS por página.
   Nomenclatura: nx-bloque  nx-bloque__elemento  nx-bloque--modificador
   ============================================================================= */

/* =============================================================================
   1 · :root — TOKENS
   ============================================================================= */

/* ── Tamaño raíz ─────────────────────────────────────────────────────────────
   Bricks trae en su CSS de frontend un `html { font-size: 62.5% }`, un truco
   viejo para que 1rem valgan 10px y sea cómodo escribir «1.6rem» en el panel.
   Nuestra escala está en rem contando con el 100% del navegador, así que bajo
   ese 62.5% TODO el sitio salía un 37,5% más pequeño: el cuerpo a 10px en vez
   de 16, los titulares a 36 en vez de 57.

   Se devuelve el raíz al 100%, que además es lo correcto de accesibilidad: si
   alguien ha subido el tamaño de letra en su navegador, el sitio lo respeta.

   `html:root` en vez de `html` a propósito: misma etiqueta pero una clase más
   de especificidad, así gana siempre, sin depender de qué hoja carga antes.
   Si algún día se maqueta algo NATIVO en Bricks con rem, esos valores habrá
   que multiplicarlos por 1,6.                                                */
html:root {
  font-size: 100%;
  overflow-x: clip;
  overscroll-behavior-x: none;
}

:root {

  /* ---- Color: identidad ------------------------------------------------- */
  --nx-coral:              #E2674A;   /* SOLO como fondo. Ver nota de contraste */
  --nx-coral-oscuro:       #B5402A;   /* coral legible como TEXTO */
  --nx-navy:               #1A1C22;   /* SOLO texto y bordes, ya no es superficie */
  --nx-negro:              #070707;   /* toda superficie oscura del sitio */
  --nx-crema:              #F4F2EC;
  /* verdes de WhatsApp: el vivo identifica, el oscuro da el contraste */
  --nx-wa-verde:           #25D366;
  --nx-wa-borde:           #075E54;
  --nx-blanco:             #FFFFFF;
  --nx-lino:               #EAE7DE;   /* superficie hundida */
  --nx-linea:              #E5E1D7;
  --nx-grafito:            #3A4450;
  --nx-gris:               #636B77;   /* corregido: #6B7480 daba 4.23 sobre crema */
  --nx-verde:              #2A6644;
  --nx-rojo:               #963C2A;
  --nx-azul:               #2A4A80;

  /* NOTA DE CONTRASTE (WCAG AA, medido):
     El coral #E2674A da 2.99:1 sobre crema — FALLA como color de texto y como
     fondo de botón con texto claro. Por eso:
       · como FONDO de botón  -> el texto va en navy  (5.09:1)  ✔
       · como TEXTO           -> se usa --nx-coral-oscuro (5.03:1) ✔
     El coral vivo se reserva para superficies, nunca para letra.

     Sobre el negro #070707 (todas las superficies oscuras):
       · crema #F4F2EC              17.8:1  ✔
       · coral #E2674A               5.7:1  ✔  (era 4.8:1 sobre el navy)
       · --nx-texto-claro-suave      9.3:1  ✔
     El cambio de navy a negro SUBE el contraste en todos los casos.           */

  /* ---- Color: roles semánticos ------------------------------------------ */
  --nx-fondo:              var(--nx-crema);
  --nx-superficie:         var(--nx-blanco);
  --nx-superficie-baja:    var(--nx-lino);
  --nx-superficie-oscura:  var(--nx-negro);
  --nx-borde:              var(--nx-linea);
  --nx-texto:              var(--nx-grafito);
  --nx-texto-suave:        var(--nx-gris);
  --nx-texto-claro:        var(--nx-crema);
  --nx-texto-claro-suave:  rgba(244, 242, 236, 0.72);
  --nx-acento:             var(--nx-coral);         /* fondos y filetes */
  --nx-acento-texto:       var(--nx-coral-oscuro);  /* letra y iconos */

  /* ---- Color: estados ---------------------------------------------------- */
  --nx-estado-venta-fondo:    #F4E8E5;
  --nx-estado-venta-texto:    var(--nx-rojo);
  --nx-estado-curso-fondo:  #E8EEFA;
  --nx-estado-curso-texto:  var(--nx-azul);
  --nx-estado-entregado-fondo:   var(--nx-crema);
  --nx-estado-entregado-texto:   var(--nx-navy);

  /* ---- Tipografía --------------------------------------------------------- */
  /* Las mismas tres familias en ES, EN y RU. Archivo, Instrument Sans y
     Pinyon no traen cirílico: en /ru/ el navegador caía a system-ui y las
     tres webs no se leían iguales. Commissioner, Manrope y Marck Script
     cubren latino y cirílico, con el mismo trabajo en cada idioma:
     display  → titulares. Commissioner 800 aguanta a tamaño de h1.
     cuerpo   → todo lo demás. Manrope, neutra y legible.
     script   → citas y glosario. Marck Script (Pinyon no tiene cirílico). */
  --nx-fuente-display: "Commissioner", "Helvetica Neue", Arial, sans-serif;
  --nx-fuente: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
  --nx-fuente-script: "Marck Script", cursive;
  --nx-fuente-serif: "Marck Script", Georgia, "Times New Roman", serif;

  /* Manrope sí tiene 300, pero el suelo del sistema es 400: si se pide
     más fino, el contraste con el crema se queda corto en móvil.           */
  --nx-peso-ligero:  400;
  --nx-peso-normal:  400;
  --nx-peso-medio:   500;
  --nx-peso-fuerte:  600;
  --nx-peso-display: 800;

  /* la escala grande es FLUIDA: el h1 llega a 104px en pantalla ancha.
     Antes eran 48px fijos y ese era el techo de toda la página.            */
  --nx-texto-xxl:  clamp(2rem, 5vw, 4.75rem);       /* 32 →  76px  h1 */
  --nx-texto-xl:   clamp(1.75rem, 3.4vw, 3.5rem);   /* 28 →  56px  h2 */
  --nx-texto-l:    1.5rem;    /* 24px  h3 destacado */
  --nx-texto-m:    1.25rem;   /* 20px  h3 / entradilla */
  --nx-texto-base: 1rem;      /* 16px  cuerpo */
  --nx-texto-s:    0.875rem;  /* 14px  MÍNIMO de cuerpo y de texto legal */
  --nx-texto-xs:   0.75rem;   /* 12px  SOLO etiquetas en mayúsculas */

  /* 0.92 y no 0.88: en español los acentos sobre mayúscula (Ó, Ñ, É) suben
     por encima de la altura de caja. A 0.88 las líneas se tocan.           */
  --nx-interlinea-titulo: 1.1;
  --nx-interlinea-texto:  1.6;

  /* set CERRADO de tracking: no existe un cuarto valor */
  --nx-tracking-titulo:  -0.02em;   /* solo a partir de 32px */
  --nx-tracking-normal:  0;
  --nx-tracking-etiqueta: 0.12em;   /* único valor positivo, solo mayúsculas */

  /* ---- Espaciado ---------------------------------------------------------- */
  --nx-e1:   8px;
  --nx-e2:  16px;
  --nx-e3:  24px;
  --nx-e4:  32px;
  --nx-e5:  40px;
  --nx-e6:  56px;
  --nx-e7:  72px;

  /* alturas de sección por token, nunca a mano */
  --nx-header-alto:    112px;   /* cabecera en reposo */
  --nx-header-min:      56px;   /* cabecera encogida, ya solo con la marca */
  --nx-alto-cabecera:   72px;
  --nx-alto-seccion:    88px;
  --nx-alto-destacada: 112px;

  /* ---- Medidas ------------------------------------------------------------ */
  --nx-franja:          184px;   /* en reposo: accesos y miniaturas */
  --nx-franja-abierta:  276px;   /* al apuntar encima: +50% */
  --nx-franja-movil:     36px;   /* tira lateral en móvil: fina, no come el contenido */
  --nx-ancho-lectura:   34em;
  --nx-lado:            56px;   /* padding lateral */
  /* dónde empieza la marca contando desde el borde de la ventana: la cabecera
     vive dentro del shell, así que hay que sumar el ancho de la franja. Lo usa
     la intro para aterrizar justo encima del logotipo real.               */
  --nx-marca-x:         calc(var(--nx-franja) + var(--nx-lado));

  --nx-radio-0:   0px;
  --nx-radio-1:   8px;
  --nx-radio-2:  99px;
  --nx-filete:    1px;

  --nx-toque:    44px;   /* objetivo táctil mínimo */

  /* ---- Tiempos ------------------------------------------------------------ */
  /* Movimiento más cálido (2026-08-10): las entradas se alargan y la curva
     deja de ser expo.out, que arrancaba de golpe. El hover NO se toca —
     el feedback directo sigue por debajo de 200ms, como manda el contrato. */
  --nx-t-instante: 80ms;
  --nx-t-rapido:  150ms;    /* hover: el estándar, intocable */
  --nx-t-base:    420ms;    /* entrada y expansión */
  --nx-t-lento:   760ms;    /* reveal grande */

  --nx-curva:          cubic-bezier(0.2, 0.7, 0.2, 1);
  /* ease-out suave y con cola larga: entra sin tirón y se asienta despacio */
  --nx-curva-entrada:  cubic-bezier(0.25, 0.8, 0.35, 1);
  --nx-curva-salida:   cubic-bezier(0.4, 0, 1, 1);
  /* franja en escritorio: spring suave (empieza rápido, aterriza sin golpe) */
  --nx-curva-franja:   cubic-bezier(0.22, 1, 0.36, 1);
  --nx-t-franja:       520ms;
  --nx-t-franja-texto: 380ms;

  --nx-escalonado:      90ms;
  --nx-escalonado-corto: 50ms;

  /* REGLA DE MOVIMIENTO: dentro de una misma interacción, todas las propiedades
     comparten duración y curva. Nunca se animan width, height, margin, padding
     ni top/left/right/bottom. Única excepción: grid-template-columns en el
     acordeón horizontal.                                                      */
}

/* =============================================================================
   2 · RESET
   ============================================================================= */

*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--nx-fuente);
  font-weight: var(--nx-peso-normal);
  font-size: var(--nx-texto-base);
  line-height: var(--nx-interlinea-texto);
  color: var(--nx-texto);
  background: var(--nx-fondo);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* html ya recorta el eje X; el body seguía en visible y en iOS eso deja
     panear la página cuando una tabla o un globo se sale (medido: la
     comparativa de /inversion-inmobiliaria-espana/ pinta 720px en un
     viewport de 390). overflow-wrap evita que una URL o un término ruso
     empujen el layout. */
  overflow-x: clip;
  overscroll-behavior-x: none;
  overflow-wrap: break-word;
}

img, video, svg { display: block; max-width: 100%; }
img, video { height: auto; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }

ul, ol { list-style: none; }

table { border-collapse: collapse; width: 100%; }

:target { scroll-margin-top: var(--nx-e7); }

/* =============================================================================
   3 · TIPOGRAFÍA BASE
   ============================================================================= */

h1, h2, h3, h4 {
  line-height: var(--nx-interlinea-titulo);
  text-wrap: balance;
}

/* h1 y h2 van en la display, con su peso Black. h3 y h4 se quedan en la
   familia de cuerpo: son subtítulos, no titulares.                        */
h1, h2 {
  font-family: var(--nx-fuente-display);
  font-weight: var(--nx-peso-display);
  letter-spacing: var(--nx-tracking-titulo);
}
h3, h4 { font-family: var(--nx-fuente); }

h1 { font-size: var(--nx-texto-xxl); }

h2 {
  font-size: var(--nx-texto-xl);
  margin-bottom: var(--nx-e2);
}

h3 {
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-medio);
  letter-spacing: var(--nx-tracking-normal);
  margin-bottom: var(--nx-e1);
}

h4 {
  font-size: var(--nx-texto-base);
  font-weight: var(--nx-peso-medio);
  letter-spacing: var(--nx-tracking-normal);
}

/* evita la palabra suelta huérfana al final de un párrafo o ítem de lista.
   Sin soporte en Firefox: degrada solo a wrap normal, no rompe nada.        */
p, li, blockquote { text-wrap: pretty; }

p { font-weight: var(--nx-peso-ligero); }
p + p { margin-top: var(--nx-e2); }

strong { font-weight: var(--nx-peso-medio); }
em { font-style: italic; }

/* listas de contenido (el reset las deja limpias por defecto) */
.nx-lista { display: grid; gap: var(--nx-e1); }
.nx-lista li { padding-left: var(--nx-e3); position: relative; font-weight: var(--nx-peso-ligero); }
.nx-lista strong { font-weight: var(--nx-peso-fuerte); color: var(--nx-texto); }
.nx-lista li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.65em;
  width: 10px; height: var(--nx-filete);
  background: var(--nx-acento);
}

/* Variante ordenada: cuando la lista es <ol>, el orden ES el contenido y una
   raya no lo dice. Se sustituye por el número, con el mismo aspecto que
   .nx-tarjeta__indice para que un proceso se lea igual esté en tarjetas o en
   lista. Nació del bloque 03 de /reactiva-tu-proyecto-parado/, donde el
   argumento es que la visita a la obra va la CUARTA y no la primera.
   Los contadores van en el <ol>, no en el li: reinician solos en cada lista. */
ol.nx-lista {
  counter-reset: nx-paso;
}
ol.nx-lista > li {
  counter-increment: nx-paso;
  padding-left: var(--nx-e4);
}
ol.nx-lista > li::before {
  content: counter(nx-paso, decimal-leading-zero);
  top: 0;
  width: auto; height: auto;
  background: none;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  color: var(--nx-acento-texto);
}

/* =============================================================================
   4 · UTILIDADES
   ============================================================================= */


/* sección: la banda. El ritmo de fondos se controla con los modificadores.
   Máximo DOS --destacada por página.                                         */
.nx-seccion {
  padding-block: var(--nx-alto-seccion);
  padding-inline: var(--nx-lado);
}
.nx-seccion--alt {
  background: var(--nx-superficie);
  border-block: var(--nx-filete) solid var(--nx-borde);
}
.nx-seccion--destacada {
  padding-block: var(--nx-alto-destacada);
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro);
}
.nx-seccion--destacada h1,
.nx-seccion--destacada h2,
.nx-seccion--destacada h3,
.nx-seccion--destacada h4 { color: var(--nx-texto-claro); }
.nx-seccion--destacada p  { color: var(--nx-texto-claro-suave); }
.nx-seccion--destacada .nx-lista li { color: var(--nx-texto-claro-suave); }

/* CTA: superficie coral OSCURO (#B5402A), no el vivo — el blanco sobre el
   vivo se queda en 3.35:1 y no pasa AA. Sobre el oscuro da 5.63:1.
   Texto centrado: es una llamada, no un artículo. El pie lleva el cierre
   global; una página puede tener además un CTA de sección.                 */
.nx-seccion--cta {
  padding-block: var(--nx-alto-destacada);
  background: var(--nx-coral-oscuro);
  color: var(--nx-blanco);
  text-align: center;
}
.nx-seccion--cta h2 { color: var(--nx-blanco); }
.nx-seccion--cta .nx-kicker { color: rgba(255, 255, 255, 0.72); }
.nx-seccion--cta .nx-lead {
  color: rgba(255, 255, 255, 0.85);
  margin-inline: auto;
}
.nx-seccion--cta .nx-botonera { justify-content: center; }
/* los botones se invierten: sobre coral, el blanco es el que destaca */
.nx-seccion--cta .nx-boton--primario {
  background: var(--nx-blanco);
  color: var(--nx-coral-oscuro);
}
.nx-seccion--cta .nx-boton--secundario {
  border-color: rgba(255, 255, 255, 0.5);
  color: var(--nx-blanco);
}
.nx-seccion--cta .nx-enlace { color: var(--nx-blanco); }
.nx-seccion--cta .nx-enlace__flecha { color: var(--nx-blanco); }

/* Cinta coral a todo el ancho de la columna: 10px arriba y abajo del texto.
   Sale del padding de la sección con márgenes negativos. No es --cta:
   esa sigue reservada para bloques de llamada con botón.

   REGLA DE SITIO: CTA corto y llamativo para brokers/oportunidad. El copy
   canónico ES: «¿Eres broker o conoces una oportunidad? Preséntala y cobra
   comisión →». Misma clase .nx-cinta en landings que lo pidan; no inventar
   otro banner.                                                              */
.nx-cinta {
  box-sizing: border-box;
  width: auto;
  max-width: none;
  margin-block: var(--nx-e4) 0;
  margin-inline: calc(-1 * var(--nx-lado));
  padding-block: 10px;
  padding-inline: var(--nx-lado);
  background: var(--nx-coral-oscuro);
  color: var(--nx-blanco);
  text-align: center;
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-medio);
  line-height: 1.35;
  text-wrap: pretty;
}
.nx-cinta a { color: var(--nx-blanco); }
.nx-cinta a:hover,
.nx-cinta a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.nx-grid { display: grid; gap: var(--nx-e3); }
.nx-grid--2 { grid-template-columns: repeat(2, 1fr); }
.nx-grid--3 { grid-template-columns: repeat(3, 1fr); }
.nx-grid--4 { grid-template-columns: repeat(4, 1fr); }
.nx-grid--ancho   { gap: var(--nx-e6); }
.nx-grid--centrado { align-items: center; }   /* texto e imagen al mismo eje */

/* Aquí vivía .nx-grid--igualado, que estiraba la foto hasta igualar la altura
   del texto. Se retiró: hacía que la MISMA imagen se recortara distinto en
   cada hueco y en cada tamaño de pantalla —la captura del portal iba de 1,22
   a 1,90 de proporción según el ancho—, así que no había forma de encuadrar
   un archivo que valiera para todo. Ahora todo hueco de foto es 16:9 vía
   .nx-tarjeta__media, y las dos columnas se alinean con .nx-grid--centrado. */

.nx-kicker {
  display: inline-block;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-acento-texto);
  margin-bottom: var(--nx-e2);
}
.nx-seccion--destacada .nx-kicker { color: var(--nx-coral); }

.nx-lead {
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
  max-width: var(--nx-ancho-lectura);
  /* balance y no pretty (regla general de más arriba): un lead son 1-3
     líneas de marca, no un párrafo largo — balance las reparte de forma
     pareja en vez de solo evitar la huérfana final. Regla general de
     textos responsive, 2026-09-01. */
  text-wrap: balance;
}
.nx-seccion--destacada .nx-lead { color: var(--nx-texto-claro-suave); }

/* ── párrafo corriente ────────────────────────────────────────────────────
   El párrafo que no es lead, ni de tarjeta, ni de FAQ. Hasta ahora no tenía
   clase propia y se escribía como <p class="nx-mt-3">: sin max-width, así que
   se estiraba a todo el contenedor.

   Medido en producción a 1710px de ventana: .nx-lead salía a 680px (68
   caracteres por línea, correcto) y el párrafo suelto a 1382px — 173
   caracteres. El rango legible son 45-75. A 173 el ojo pierde el comienzo de
   la línea siguiente al volver, y el texto se lee como si estuviera mal
   escrito aunque la frase esté bien. Convivían las dos medidas en la misma
   sección, que es lo que más canta.

   Misma medida que .nx-lead a propósito: dos anchos distintos en la misma
   columna vuelven a producir el escalón que esto viene a quitar.          */
.nx-parrafo {
  max-width: var(--nx-ancho-lectura);
}

/* texto legal: NUNCA por debajo de 14px */
.nx-legal {
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  line-height: 1.45;
  color: var(--nx-texto-suave);
  max-width: 52em;
}
.nx-seccion--destacada .nx-legal { color: var(--nx-texto-claro-suave); }

.nx-sub {
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-acento-texto);
  text-wrap: balance;
}

.nx-mt-2 { margin-top: var(--nx-e2); }
.nx-mt-3 { margin-top: var(--nx-e3); }
.nx-mt-4 { margin-top: var(--nx-e4); }
.nx-mt-5 { margin-top: var(--nx-e5); }
.nx-mb-3 { margin-bottom: var(--nx-e3); }
.nx-mb-4 { margin-bottom: var(--nx-e4); }


/* accesible pero oculto: saltos de navegación, etiquetas de lector */
.nx-oculto {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}

/* El único .nx-oculto focable del sitio es el «Saltar al contenido» del
   header (02-header.html): al recibir foco de teclado tiene que hacerse
   visible, si no un usuario de teclado vidente no sabe que existe. Las
   etiquetas de lector con esta misma clase nunca reciben foco, así que
   esta regla no las afecta. Auditoría de accesibilidad, 2026-08-31. */
.nx-oculto:focus {
  position: fixed;
  inset-block-start: var(--nx-e2);
  inset-inline-start: var(--nx-e2);
  z-index: 100;
  width: auto;
  height: auto;
  padding: var(--nx-e2) var(--nx-e3);
  margin: 0;
  overflow: visible;
  clip-path: none;
  white-space: normal;
  background: var(--nx-superficie-oscura, #070707);
  color: var(--nx-texto-claro, #F4F2EC);
  border-radius: var(--nx-radio-1, 8px);
  font-weight: var(--nx-peso-medio);
  box-shadow: 0 12px 30px rgba(7, 7, 7, .28);
}

/* entrada escalonada. Solo si el script del head puso .nx-js (antes del
   primer pintado, data-no-optimize). Sin esa clase el texto se ve igual.
   --visible la pone el observador: fade + 14px hacia arriba, como antes. */
.nx-js .nx-anim > * { opacity: 0; transform: translateY(14px); }

/* …salvo el PRIMER bloque de la página, que no se esconde nunca.
   2026-08-26: medido en /reactiva-tu-proyecto-parado/ — el hero salía en
   blanco hasta que corría el script del final del body, y Chrome no
   registraba NINGUNA entrada de LCP (un elemento en opacity:0 no es
   candidato a LCP, así que el <h1> no puntuaba). FCP 1280 ms.
   Solo se levanta el opacity inicial: la animación de --visible sigue
   declarada y no se nota, porque va de opacity:1 a opacity:1.
   Especificidad (0,4,0) para ganarle a la regla de arriba (0,2,0). */
.nx-js .nx-seccion:first-of-type .nx-anim > * {
  opacity: 1;
  transform: none;
}

.nx-anim--visible > * {
  animation: nx-subir var(--nx-t-base) var(--nx-curva-entrada) forwards;
}
.nx-anim--visible > *:nth-child(1) { animation-delay: calc(var(--nx-escalonado) * 0); }
.nx-anim--visible > *:nth-child(2) { animation-delay: calc(var(--nx-escalonado) * 1); }
.nx-anim--visible > *:nth-child(3) { animation-delay: calc(var(--nx-escalonado) * 2); }
.nx-anim--visible > *:nth-child(4) { animation-delay: calc(var(--nx-escalonado) * 3); }
.nx-anim--visible > *:nth-child(5) { animation-delay: calc(var(--nx-escalonado) * 4); }
.nx-anim--visible > *:nth-child(6) { animation-delay: calc(var(--nx-escalonado) * 5); }
.nx-anim--visible > *:nth-child(7) { animation-delay: calc(var(--nx-escalonado) * 5); }
.nx-anim--visible > *:nth-child(8) { animation-delay: calc(var(--nx-escalonado) * 5); }
/* a partir del 6º elemento el escalonado se congela: el último no llega tarde */

@keyframes nx-subir { to { opacity: 1; transform: translateY(0); } }

/* =============================================================================
   5 · BOTONES
   Un solo botón primario visible por vista.
   ============================================================================= */

.nx-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--nx-toque);
  padding-inline: var(--nx-e3);
  border-radius: var(--nx-radio-1);
  border: var(--nx-filete) solid transparent;
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  letter-spacing: var(--nx-tracking-normal);
  text-align: center;
  transition: background-color var(--nx-t-rapido) var(--nx-curva),
              border-color     var(--nx-t-rapido) var(--nx-curva),
              color            var(--nx-t-rapido) var(--nx-curva);
}

/* primario: texto BLANCO sobre coral oscuro (5.63:1).
   El blanco sobre el coral vivo #E2674A se queda en 3.35:1 y no pasa AA,
   por eso el fondo del botón es el coral oscuro y no el vivo.               */
.nx-boton--primario {
  background: var(--nx-coral-oscuro);
  color: var(--nx-blanco);
}

.nx-boton--secundario {
  background: transparent;
  border-color: var(--nx-navy);
  color: var(--nx-navy);
}
/* sobre superficie oscura el borde navy desaparece y el texto navy queda a
   1,3:1 sobre #070707. Aquí se invierten los dos.                          */
.nx-seccion--destacada .nx-boton--secundario,
.nx-footer .nx-boton--secundario {
  border-color: rgba(244, 242, 236, 0.45);
  color: var(--nx-texto-claro);
}

.nx-boton--terciario {
  background: transparent;
  color: var(--nx-texto);
  padding-inline: 0;
}

.nx-boton--bloque { width: 100%; }

/* flecha: el hueco está reservado desde el inicio, el ancho no cambia nunca */
.nx-boton__texto {
  display: inline-block;
  transform: translateX(0.65em);
  transition: transform var(--nx-t-rapido) var(--nx-curva);
}
.nx-boton__flecha {
  display: inline-block;
  width: 1.3em;
  text-align: right;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity   var(--nx-t-rapido) var(--nx-curva),
              transform var(--nx-t-rapido) var(--nx-curva);
}

.nx-botonera { display: flex; flex-wrap: wrap; gap: var(--nx-e2); }
.nx-cta-nota {
  font-size: var(--nx-texto-base);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-suave);
  max-width: var(--nx-ancho-lectura);
}
.nx-cta-nota strong {
  font-weight: var(--nx-peso-display);
  color: var(--nx-texto);
}
.nx-seccion--destacada .nx-cta-nota,
.nx-seccion--cta .nx-cta-nota {
  color: var(--nx-texto-claro-suave);
}
.nx-seccion--destacada .nx-cta-nota strong,
.nx-seccion--cta .nx-cta-nota strong {
  color: var(--nx-blanco);
}

/* =============================================================================
   6 · COMPONENTES
   ============================================================================= */

/* ---- enlace con flecha ---------------------------------------------------
   Regla global (crítica de diseño, 2026-09-01): antes el color naranja y la
   flecha solo aparecían en :hover — en táctil, sin hover, un enlace de texto
   no se distinguía del resto de la frase. Ahora el naranja y la flecha van
   SIEMPRE puestos; el hover pasa a subrayado + la flecha se adelanta un
   poco, en vez de aparecer de la nada. Los contextos oscuros (CTA, franja,
   glosario, footer, destacada…) siguen pisando el color con sus propias
   reglas más específicas — esto no les afecta. */
.nx-enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--nx-toque);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-acento-texto);
  transition: color var(--nx-t-rapido) var(--nx-curva);
}
.nx-enlace:hover,
.nx-enlace:focus-visible {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.nx-enlace__flecha {
  display: inline-block;
  width: 1.2em;
  text-align: right;
  color: var(--nx-acento-texto);
  opacity: 1;
  transform: translateX(0);
  transition: opacity   var(--nx-t-rapido) var(--nx-curva),
              transform var(--nx-t-rapido) var(--nx-curva);
}
.nx-enlace:hover .nx-enlace__flecha,
.nx-enlace:focus-visible .nx-enlace__flecha { transform: translateX(3px); }
.nx-seccion--destacada .nx-enlace__flecha { color: var(--nx-coral); }

/* ---- tarjeta: UN SOLO componente para todo el sitio -----------------------
   Anatomía fija, siempre en este orden. Cada parte es opcional, pero el orden
   y el espaciado no cambian nunca:
       media  →  índice  →  título  →  meta  →  texto  →  pie
   Se usa igual en fases, caminos, pilares, socios e imágenes sueltas. Si un
   bloque necesita algo que no está aquí, se amplía este componente — no se
   crea otro. Cuatro anatomías distintas es lo que hacía que la página
   pareciera montada a trozos.                                               */
.nx-tarjeta {
  display: flex;
  flex-direction: column;
  padding: var(--nx-e3);
  background: var(--nx-superficie);
  border: var(--nx-filete) solid var(--nx-borde);
  border-radius: var(--nx-radio-1);
  overflow: hidden;
  transition: transform var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva),
              box-shadow var(--nx-t-rapido) var(--nx-curva);
}

/* la imagen sangra hasta el borde anulando el padding de la tarjeta */
.nx-tarjeta__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  margin: calc(var(--nx-e3) * -1) calc(var(--nx-e3) * -1) var(--nx-e3);
  background: var(--nx-superficie-baja);
  border-radius: var(--nx-radio-1) var(--nx-radio-1) 0 0;
}
.nx-tarjeta__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--nx-t-rapido) var(--nx-curva);
}
/* corner bracket: motivo de marca, en el mismo sitio en todas las tarjetas */
.nx-tarjeta__media::after {
  content: "";
  position: absolute;
  top: var(--nx-e2); left: var(--nx-e2);
  width: 24px; height: 24px;
  border-top: 2px solid var(--nx-coral);
  border-left: 2px solid var(--nx-coral);
}

.nx-tarjeta__indice {
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-acento-texto);
  margin-bottom: var(--nx-e1);
}
.nx-tarjeta__titulo {
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-medio);
  margin-bottom: var(--nx-e1);
}
.nx-tarjeta__meta {
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
  margin-bottom: var(--nx-e1);
}

/* ---- retrato de socio o advisor -------------------------------------------
   4:5 vertical, el mismo encuadre del retrato de Instagram. Es el formato en
   el que la gente ya se hace las fotos, así que no hay que pedir sesión nueva:
   sirve una foto de perfil decente.
   Va dentro de la tarjeta y por encima del nombre, con sangrado hasta el borde
   —de ahí los márgenes negativos— para que la foto mande y el texto acompañe. */
.nx-tarjeta__retrato {
  margin: calc(var(--nx-e3) * -1) calc(var(--nx-e3) * -1) var(--nx-e3);
  border-radius: var(--nx-radio-1) var(--nx-radio-1) 0 0;
  overflow: hidden;
  background: var(--nx-superficie-baja);
}
.nx-tarjeta__retrato img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  /* el encuadre se ancla arriba: en un retrato, si algo se recorta que sean
     los pies, nunca la cara */
  object-position: center top;
}
.nx-tarjeta__texto {
  flex: 1;                       /* empuja el pie al fondo: pies alineados */
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
}
.nx-tarjeta__pie { margin-top: var(--nx-e3); }

/* modificadores: cambian el acento, nunca la anatomía */
.nx-tarjeta--activa { border-color: var(--nx-acento); }
.nx-tarjeta--plana  { padding: 0; border-color: transparent; background: transparent; }
.nx-tarjeta--plana .nx-tarjeta__media { margin: 0; border-radius: var(--nx-radio-1); }

/* dentro de una sección oscura la tarjeta mantiene su fondo claro: es el
   contraste de superficie lo que la separa del fondo, no un color propio.  */
.nx-seccion--destacada .nx-tarjeta__texto { color: var(--nx-texto-suave); }
.nx-seccion--destacada .nx-tarjeta__titulo { color: var(--nx-texto); }

/* rejillas de tarjetas: mismo gap en todas */
.nx-tarjetas { display: grid; gap: var(--nx-e3); }
.nx-tarjetas--2 { grid-template-columns: repeat(2, 1fr); }
.nx-tarjetas--3 { grid-template-columns: repeat(3, 1fr); }
.nx-tarjetas--4 { grid-template-columns: repeat(4, 1fr); }
/* la causa de raíz del desbordamiento: un hijo de grid tiene tamaño mínimo
   automático = min-content, así que un apellido largo ensancha su columna por
   encima del 1fr y la fila entera se sale. Con min-width:0 la palabra parte o
   se ajusta, pero la rejilla nunca crece más que su contenedor.              */
.nx-tarjetas > *,
.nx-pilares > *,
.nx-caminos > * { min-width: 0; }

/* ---- etiqueta de estado -------------------------------------------------- */
.nx-estado {
  display: inline-block;
  padding: 2px var(--nx-e2);
  border-radius: var(--nx-radio-1);
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
}
.nx-estado--venta   { background: var(--nx-estado-venta-fondo);   color: var(--nx-estado-venta-texto); }
.nx-estado--curso { background: var(--nx-estado-curso-fondo); color: var(--nx-estado-curso-texto); }
.nx-estado--entregado  { background: var(--nx-estado-entregado-fondo);  color: var(--nx-estado-entregado-texto); }

/* ---- acordeón / FAQ ------------------------------------------------------
   Con <details> el navegador no renderiza el contenido cerrado, así que no hay
   nada que animar y la respuesta aparece de golpe. Por eso se construye con
   botón + panel: el panel existe siempre y se abre animando grid-template-rows
   de 0fr a 1fr, que es la única forma de animar "alto automático" sin fijar
   una altura a mano.

   Excepción de movimiento declarada: grid-template-rows es propiedad de layout.
   Es la misma excepción ya admitida para el acordeón horizontal, y se limita a
   este componente.                                                          */
.nx-faq { max-width: 60em; }
.nx-faq__item { border-bottom: var(--nx-filete) solid var(--nx-borde); }

/* el botón de cada pregunta va envuelto en h3 (navegación por encabezados
   con lector de pantalla, auditoría de accesibilidad 2026-08-31): reset
   completo para que el h3 no aporte ningún estilo propio, el botón sigue
   pintando el título tal cual. */
.nx-faq__h3 { margin: 0; font: inherit; font-weight: inherit; }

/* ── la salida del bloque de preguntas ────────────────────────────────────
   «Hablar con el equipo» vivía en la botonera del hero, al lado del CTA
   principal y con el mismo peso visual: dos botones iguales = ninguna acción
   principal. Su sitio es este. Quien ha leído cinco preguntas y no ha
   encontrado la suya es exactamente quien quiere hablar con alguien.

   Enlace y no botón, a propósito: es una salida, no la acción de la página. */
.nx-faq__salida {
  max-width: 60em;
  margin-block-start: var(--nx-e4);
  padding-block-start: var(--nx-e3);
  font-size: var(--nx-texto-s);
  color: var(--nx-texto-suave);
}
.nx-faq__salida .nx-enlace { margin-inline-start: var(--nx-e1); }
.nx-seccion--destacada .nx-faq__salida { color: var(--nx-texto-claro-suave); }

.nx-faq__pregunta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nx-e3);
  width: 100%;
  padding-block: var(--nx-e3);
  min-height: var(--nx-toque);
  text-align: left;
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto);
  transition: color var(--nx-t-rapido) var(--nx-curva);
}

/* signo: un + que gira 135° y se convierte en × */
.nx-faq__signo {
  position: relative;
  flex-shrink: 0;
  width: 16px; height: 16px;
  transition: transform var(--nx-t-base) var(--nx-curva-entrada);
}
.nx-faq__signo::before,
.nx-faq__signo::after {
  content: "";
  position: absolute;
  background: var(--nx-acento-texto);
  border-radius: 1px;
}
.nx-faq__signo::before { inset-block-start: 7px; inset-inline: 0; height: 2px; }
.nx-faq__signo::after  { inset-inline-start: 7px; inset-block: 0; width: 2px; }
.nx-faq__pregunta[aria-expanded="true"] .nx-faq__signo { transform: rotate(135deg); }

/* panel: 0fr → 1fr. El hijo lleva el overflow. */
.nx-faq__panel {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--nx-t-base) var(--nx-curva-entrada);
}
/* el botón ya no es hermano directo de .nx-faq__panel: va envuelto en
   .nx-faq__h3 (accesibilidad, 2026-08-31). :has() ya es el patrón admitido
   en este archivo (ver franja, galería, checkbox) — sin fallback JS. */
.nx-faq__h3:has(.nx-faq__pregunta[aria-expanded="false"]) + .nx-faq__panel { grid-template-rows: 0fr; }

.nx-faq__respuesta {
  overflow: hidden;
  opacity: 1;
  transform: translateY(0);
  transition: opacity   var(--nx-t-base) var(--nx-curva-entrada),
              transform var(--nx-t-base) var(--nx-curva-entrada);
}
.nx-faq__h3:has(.nx-faq__pregunta[aria-expanded="false"]) + .nx-faq__panel .nx-faq__respuesta {
  opacity: 0;
  transform: translateY(-6px);
}
.nx-faq__texto {
  padding-block: 0 var(--nx-e3);
  padding-inline-end: var(--nx-e5);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
  max-width: 52em;
}

/* ---- formulario ---------------------------------------------------------- */
.nx-campo { display: grid; gap: var(--nx-e1); margin-bottom: var(--nx-e3); }
.nx-campo__label { font-size: var(--nx-texto-s); font-weight: var(--nx-peso-medio); }
.nx-campo__input {
  min-height: var(--nx-toque);
  padding-inline: var(--nx-e2);
  background: var(--nx-superficie);
  border: var(--nx-filete) solid var(--nx-borde);
  border-radius: var(--nx-radio-0);
  transition: border-color var(--nx-t-rapido) var(--nx-curva);
}
.nx-campo__error { font-size: var(--nx-texto-s); color: var(--nx-rojo); }

/* ---- el formulario como pieza elevada ------------------------------------
   Cuando el formulario comparte fila con una columna de texto, deja de ser
   «el final de la página» y pasa a ser un objeto: se levanta del fondo para
   que se lea como la cosa que hay que rellenar.
   La receta de elevación no es nueva — es la misma que ya usa el globo del
   glosario: fondo de superficie, filete, radio 1 y la misma sombra.
   Va sobre un contenedor propio y no sobre el <form>, porque el <form> lo
   imprime inc/formulario.php y no queremos que el PHP sepa de maquetación. */
.nx-form-caja {
  background: var(--nx-superficie);
  border: var(--nx-filete) solid var(--nx-borde);
  border-radius: var(--nx-radio-1);
  box-shadow: 0 16px 40px rgba(7, 7, 7, 0.1);
  padding: var(--nx-e4);
}
/* el <form> ya trae .nx-mt-4 del PHP: dentro de la caja ese aire sobra,
   porque el padding de la caja ya lo pone */
.nx-form-caja > form { margin-block-start: 0; }
/* el último campo no necesita separarse del borde de abajo */
.nx-form-caja .nx-botonera { margin-block-end: 0; }

@media (max-width: 860px) {
  /* en móvil la caja se estrecha: con 32px por lado los campos se quedan sin
     sitio. La sombra se mantiene, que es lo que la distingue del fondo. */
  .nx-form-caja { padding: var(--nx-e3); }
}

/* Casilla de consentimiento. Medía 13×13 px: el control más pequeño de la
   página y, a la vez, el último clic obligatorio antes de enviar el
   formulario. WCAG 2.2 criterio 2.5.8 (AA) pide 24 px de lado.
   display:block (no flex) en la etiqueta: flex partía el texto en columnas
   de ~70px porque el <input>, el anónimo «He leído…» y el <a> de la
   política eran tres ítems en fila. Medido en /reactiva-tu-proyecto-parado/
   a 390px. Si el PHP envuelve el texto en .nx-campo__aviso, la fila es
   casilla + un solo bloque y sí se puede usar flex. */
.nx-campo__label input[type="checkbox"] {
  float: left;
  inline-size: 24px;
  block-size: 24px;
  flex: none;
  margin: 0.2em var(--nx-e1) 0 0;
}
.nx-campo__label:has(input[type="checkbox"]) {
  display: block;
  line-height: 1.5;
}
.nx-campo__label:has(input[type="checkbox"])::after {
  content: "";
  display: block;
  clear: both;
}
.nx-campo__label:has(> .nx-campo__aviso) {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-e1);
}
.nx-campo__aviso { flex: 1; min-width: 0; }
.nx-campo__label:has(> .nx-campo__aviso) input[type="checkbox"] {
  float: none;
  margin: 0.15em 0 0;
}
.nx-campo__label:has(> .nx-campo__aviso)::after { content: none; }

/* ---- tabla --------------------------------------------------------------- */
.nx-tabla th,
.nx-tabla td {
  text-align: left;
  padding: var(--nx-e2);
  border-bottom: var(--nx-filete) solid var(--nx-borde);
  font-size: var(--nx-texto-s);
}
.nx-tabla th { font-weight: var(--nx-peso-medio); }
.nx-tabla td { font-weight: var(--nx-peso-ligero); color: var(--nx-texto-suave); }
.nx-tabla tbody tr:nth-child(even) { background: var(--nx-superficie-baja); }

/* ---- cita con mascota ---------------------------------------------------- */
/* Bloque de respiro: 80vh, sin marco ni fondo, texto grande en itálica coral. */
.nx-cita {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nx-e6);
  min-height: 60vh;
  max-width: 68em;
  margin-inline: auto;
  padding-block: var(--nx-e6);
}
/* la mascota conserva su proporción: cuadrada, sin deformar.
   Flotación lenta: solo transform, nunca layout. Se detiene con
   prefers-reduced-motion (bloque 11).                                        */
.nx-cita__mascota {
  width: calc(clamp(140px, 16vw, 220px) * 0.8);
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  flex-shrink: 0;
  animation: nx-flotar 6s ease-in-out infinite;
  will-change: transform;
}
@keyframes nx-flotar {
  0%   { transform: translateY(0)     rotate(0deg); }
  30%  { transform: translateY(-10px) rotate(-1.5deg); }
  60%  { transform: translateY(-4px)  rotate(1deg); }
  100% { transform: translateY(0)     rotate(0deg); }
}
/* El mismo filete coral que marca las citas y los sumarios de los artículos.
   Aquí hacía falta: sin él la pregunta era un párrafo grande en cursiva
   flotando en medio de la nada, y con él se lee como lo que es — una voz
   aparte del resto de la página. */
.nx-cita__texto {
  padding-inline-start: var(--nx-e4);
  border-inline-start: 2px solid var(--nx-acento);
  font-family: var(--nx-fuente-script);
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  font-style: normal;
  font-weight: var(--nx-peso-ligero);
  line-height: 1.4;
  letter-spacing: var(--nx-tracking-titulo);
  /* coral legible: #B5402A da 5.03:1 sobre crema. El coral vivo se queda
     en 2.99:1 y no pasa ni el mínimo de texto grande (3:1).                  */
  color: var(--nx-acento-texto);
  text-wrap: pretty;
}

/* =============================================================================
   7 · CABECERA Y PIE
   ============================================================================= */

/* estructura general: franja fija a la IZQUIERDA + contenido.
   La franja se escribe al final del HTML (04-footer) para que el contenido
   principal vaya primero en el código —mejor para SEO y lectores de pantalla—
   pero se coloca a la izquierda con grid-column. El orden visual y el orden
   del código no tienen por qué coincidir.                                    */
/* La franja crece al pulsar el menú. Misma excepción declarada que el
   acordeón: es un cambio de estado deliberado al click, no una animación
   continua. Se anima grid-template-columns porque no hay otra forma de que
   las dos columnas se repartan el ancho.                                  */
.nx-shell {
  display: grid;
  grid-template-columns: var(--nx-franja) 1fr;
  transition: grid-template-columns var(--nx-t-franja) var(--nx-curva-franja);
}.nx-shell:has(.nx-franja--abierta){ grid-template-columns: var(--nx-franja-abierta) 1fr; }
.nx-main   { min-width: 0; grid-column: 2; grid-row: 1; }

/* ---- cabecera ------------------------------------------------------------ */
/* Cabecera de todo el sitio: marca, nav, idiomas y WhatsApp.
   En la home se pinta cristal sobre el hero; en el resto, barra sólida. */
.nx-header {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  height: var(--nx-header-alto);
  padding-inline: var(--nx-lado);
  background: var(--nx-fondo);
  border-bottom: var(--nx-filete) solid var(--nx-borde);
  overflow: visible;
  transition: background-color var(--nx-t-base) var(--nx-curva),
              backdrop-filter  var(--nx-t-base) var(--nx-curva),
              border-color     var(--nx-t-base) var(--nx-curva),
              box-shadow       var(--nx-t-base) var(--nx-curva);
}

/* la marca: logotipo y marca-disco ocupan el mismo sitio, uno sobre el otro.
   La entrada al cargar vive AQUÍ, no en las imágenes: así el transform de
   cada marca queda libre para la animación de scroll y no se pelean.      */
.nx-header__marca {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%;
  animation: nx-logo var(--nx-t-lento) var(--nx-curva-entrada) both;
}
@keyframes nx-logo {
  from { opacity: 0; transform: translateY(-8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}
.nx-header__logo {
  height: 64px;
  max-height: 70%;      /* al encoger la cabecera, encoge con ella */
  width: auto;
  max-width: 100%;
  /* contain y no el `fill` por defecto de <img>: con max-width recortando el
     ancho, `fill` estrujaba el logotipo. En móvil salía a 114×64 cuando su
     proporción es 4,07:1 — la marca deformada.                            */
  object-fit: contain;
  object-position: left center;
  transform-origin: left center;
}
/* el blanco solo se ve sobre el hero; el navy es el de reposo */
.nx-header__logo--claro {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  translate: 0 -50%;
  opacity: 0;
  pointer-events: none;
}
/* la marca-disco: oculta hasta que el scroll la trae */
.nx-header__iso {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  height: 34px;
  width: auto;
  translate: 0 -50%;    /* propiedad individual: deja libre transform */
  transform-origin: center center;
  opacity: 0;
}
.nx-header__fin { margin-left: auto; display: flex; align-items: center; gap: var(--nx-e3); }

/* selector de idioma: sin banderas, sin país */
.nx-idioma { display: flex; gap: var(--nx-e1); font-size: var(--nx-texto-s); }
.nx-idioma__op {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--nx-toque);
  min-width: var(--nx-toque);
  padding: 2px var(--nx-e1);
  border-radius: var(--nx-radio-1);
  transition: color var(--nx-t-rapido) var(--nx-curva),
              background var(--nx-t-rapido) var(--nx-curva);
}
.nx-idioma__op--activo { background: var(--nx-superficie-baja); font-weight: var(--nx-peso-medio); }

/* El filete coral crece desde el centro. Va en un ::after y no en un
   border-bottom porque un borde cambiaría el alto de la caja y movería los
   otros dos idiomas al pasar por encima de uno.
   scaleX es de las propiedades baratas: no repinta, solo compone.          */
.nx-idioma__op::after {
  content: "";
  position: absolute;
  inset-inline: var(--nx-e1);
  inset-block-end: 0;
  height: var(--nx-filete);
  background: var(--nx-acento);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--nx-t-base) var(--nx-curva-entrada);
}

/* barra de progreso de lectura (indicador global fijo) */
.nx-progreso {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  height: 2px;
  background: var(--nx-acento);
  z-index: 60;
  transform-origin: 0 50%;
  transform: scaleX(0);
}

/* ---- menú móvil ---------------------------------------------------------- */
/* El ☰ y su desplegable viven con el resto de la cabecera, en el bloque
   @media (max-width: 1200px) que hay junto a .nx-menu-boton. Aquí no queda
   ningún nav aparte: el que hubo estaba solo desplazado, no oculto, y sumaba
   426px al ancho del documento en móvil.                                  */

/* ---- pie ----------------------------------------------------------------- */
.nx-footer {
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro-suave);
  padding: var(--nx-e6) var(--nx-lado);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
}
/* marca + cuatro columnas de enlaces. La primera ya no se lleva el doble:
   con 2fr quedaba medio vacía y apretaba los enlaces contra la derecha.   */
.nx-footer__cols {
  display: grid;
  grid-template-columns: 1.4fr repeat(4, 1fr);
  gap: var(--nx-e4);
  margin-bottom: var(--nx-e5);
}
.nx-footer__titulo {
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-claro);
  margin-bottom: var(--nx-e2);
}
.nx-footer__enlace { display: block; padding-block: 4px; }

/* ── newsletter del pie ────────────────────────────────────────────────
   [nx_newsletter], inc/newsletter.php. Un solo campo + botón en la misma
   fila en escritorio; se apila en móvil porque min-width del input más el
   botón no caben en una columna de footer de 240px. */
.nx-newsletter__form { max-width: 320px; }
.nx-newsletter__fila {
  display: flex;
  gap: var(--nx-e1);
  align-items: stretch;
}
.nx-newsletter__input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border-color: rgba(244, 242, 236, .28);
  color: inherit;
}
.nx-newsletter__input::placeholder { color: rgba(244, 242, 236, .55); }
.nx-newsletter__consent {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-e1);
  margin-block-start: var(--nx-e2);
  font-size: var(--nx-texto-xs);
  color: var(--nx-texto-claro-suave);
}
.nx-newsletter__consent input { margin-block-start: 3px; }
.nx-newsletter__consent .nx-enlace { color: inherit; text-decoration: underline; font-size: inherit; }
@media (max-width: 420px) {
  .nx-newsletter__fila { flex-direction: column; }
}

/* contacto del pie: la única vía directa visible en toda la web */
.nx-contacto { display: flex; flex-direction: column; gap: 2px; }
.nx-contacto__via {
  display: inline-block;
  width: fit-content;
  padding-block: 4px;
  color: var(--nx-texto-claro);
  border-bottom: var(--nx-filete) solid transparent;
  transition: color var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva);
}
.nx-contacto__via--wa { color: var(--nx-coral); }
.nx-footer__contactos { display: flex; flex-direction: column; gap: var(--nx-e3); }
.nx-contacto--social { flex-direction: row; flex-wrap: wrap; gap: var(--nx-e1) var(--nx-e3); }
.nx-contacto__via--social { display: inline-flex; align-items: center; gap: 6px; width: auto; }
.nx-contacto__icono { flex: none; width: 16px; height: 16px; }
.nx-footer__legal {
  border-top: var(--nx-filete) solid rgba(244, 242, 236, 0.2);
  padding-top: var(--nx-e3);
  line-height: 1.5;
}
.nx-footer__copy { margin-top: var(--nx-e1); color: rgba(244, 242, 236, 0.55); }

/* =============================================================================
   8 · BLOQUES DE PÁGINA
   ============================================================================= */

/* ---- intro: telón negro y el logotipo aterrizando en la cabecera -----------
   Solo en la home, porque su marcado vive en el bloque de la home: quien
   entra por el dominio la ve una vez, y navegar de página en página no la
   repite.

   TODO EN CSS, sin una línea de JS, y a propósito: el telón se retira con su
   propia animación (`both` deja puesto el último fotograma). Si dependiera de
   un script y el script fallara, el visitante se quedaría mirando una pantalla
   negra para siempre. Así lo peor que puede pasar es que se vea.

   El logotipo NO viaja a ojo. Su posición en reposo ES la de la cabecera
   —mismo inset, mismo alto, mismo origen— y lo que se anima es el estado
   inicial: grande y centrado. Al llegar a `transform: none` cae exactamente
   sobre el logotipo real que hay debajo, así que el relevo no se ve.        */
.nx-intro {
  position: fixed;
  inset: 0;
  z-index: 200;              /* por encima de la franja (70) y de la cabecera */
  background: var(--nx-negro);
  overflow: hidden;
  pointer-events: none;
  animation: nx-intro-telon 2200ms var(--nx-curva-entrada) both;
}
@keyframes nx-intro-telon {
  0%, 62%   { opacity: 1; visibility: visible; }
  90%, 100% { opacity: 0; visibility: hidden; }
}

.nx-intro__logo {
  --escala: 3;
  position: absolute;
  /* reposo = exactamente donde está el logotipo de la cabecera */
  inset-inline-start: var(--nx-marca-x);
  inset-block-start: calc(var(--nx-header-alto) / 2);
  height: 64px;
  width: auto;
  max-width: calc(100vw - var(--nx-marca-x) - var(--nx-lado));
  object-fit: contain;
  object-position: left center;
  translate: 0 -50%;
  transform-origin: left center;
  animation: nx-intro-marca 2200ms var(--nx-curva-entrada) both;
}
/* el orden importa: `translate() scale()` aplica primero la escala y luego
   desplaza en coordenadas del padre, así que el desplazamiento no se
   multiplica por la escala y la cuenta sale exacta */
@keyframes nx-intro-marca {
  0%, 6% {
    opacity: 0;
    filter: blur(6px);
    transform: translate(calc(50vw - var(--nx-marca-x)),
                         calc(50vh - var(--nx-header-alto) / 2))
               scale(var(--escala)) translateX(-50%);
  }
  34%, 52% {
    opacity: 1;
    filter: blur(0);
    transform: translate(calc(50vw - var(--nx-marca-x)),
                         calc(50vh - var(--nx-header-alto) / 2))
               scale(var(--escala)) translateX(-50%);
  }
  /* llega a su sitio y se disuelve sobre el logotipo real que hay debajo.
     El relevo es un fundido cruzado, no un corte: en pantalla estrecha la
     cabecera solo deja ~115px al logotipo (el selector de idioma ocupa el
     resto) y el de la intro no puede medir exactamente lo mismo. Fundido,
     esa diferencia no se ve; con un corte seco, saltaría.                */
  88%  { opacity: 1; filter: blur(0); transform: none; }
  100% { opacity: 0; filter: blur(0); transform: none; }
}

/* phSweep del panel: la banda de luz cruza el telón mientras el logo espera */
.nx-intro::after {
  content: "";
  position: absolute;
  inset-block: -40%;
  inset-inline-start: 0;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 0%,
    rgba(244, 242, 236, 0.10) 45%, rgba(226, 103, 74, 0.16) 55%, transparent 100%);
  animation: nx-intro-brillo 2200ms ease both;
}
@keyframes nx-intro-brillo {
  0%, 14% { transform: translateX(-130%) skewX(-18deg); opacity: 0; }
  20%     { opacity: 1; }
  56%     { transform: translateX(330%) skewX(-18deg); opacity: 0; }
  100%    { transform: translateX(330%) skewX(-18deg); opacity: 0; }
}

@media (max-width: 700px) {
  .nx-intro__logo { --escala: 1.35; }
}

/* Quien pide menos movimiento no ve la intro en absoluto: no es contenido,
   es un gesto de marca. */
@media (prefers-reduced-motion: reduce) {
  .nx-intro { display: none; }
}/* ---- franja de actividad -------------------------------------------------- *//* Fija en todo el sitio. Tiene navegación propia. Lo único fijo dentro de
   ella es el acceso al portal, anclado abajo.
   Orden de bloques: útil ahora → últimas noticias → nuevos → terminados.     */



.nx-franja{
  grid-column: 1;
  grid-row: 1;
  position: sticky;
  top: 0;
  height: 100vh;
  display: grid;
  /* CERRADA: el feed estira (1fr) y ocupa todo lo que queda hasta el botón
     del portal, que es donde desfila el carrusel. Cabe todo, no hace falta
     scroll.
     ABIERTA: todas a su alto natural y scrollea la franja entera — más abajo
     se cambia. Ahí ya no hay carrusel y sí hay texto que leer.           */
  /* CADA BLOQUE EN SU FILA, Y NADIE SALE DE LA SUYA.
     Seis filas: menú · accesos · datos · cabecera · feed · portal. Las cinco
     de fuera miden lo suyo; el feed se queda con lo que sobre —minmax(0,1fr),
     no 1fr— y es el ÚNICO que scrollea.
     El 0 del minmax es la pieza clave: un hijo de grid tiene tamaño mínimo
     automático igual a su contenido, así que con 1fr a secas la fila del feed
     crecía hasta caber entera y empujaba al portal fuera de la franja. Eso
     era lo de los artículos subiéndose encima de «Actividad».             */
  grid-template-rows:
    [menu]     auto
    [accesos]  auto
    [cabecera] auto
    [datos]    auto
    [feed]     minmax(0, 1fr)
    [portal]   auto;
  align-content: stretch;
  overflow: hidden;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(244, 242, 236, 0.22) transparent;
  /* sin mask aquí: una máscara en el contenedor también difumina al hijo
     sticky, y el botón del portal se quedaría medio borrado. El
     desvanecido lo pone ahora .nx-franja__portal::before, justo encima. */
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro);
  border-right: 0;
  box-shadow: 2px 0 24px rgba(7, 7, 7, 0.18);
}/* la barra solo con el puntero encima: en reposo la franja es una tira de
   fotos y una barra permanente la ensucia */

.nx-franja::-webkit-scrollbar{ width: 6px; }
.nx-franja::-webkit-scrollbar-thumb{
  border-radius: 99px;
  background-color: transparent;
  /* background-color y no el atajo `background`: el atajo incluye imagen,
     posición y tamaño, y ninguno de esos interpola bien */
  transition: background-color var(--nx-t-base) var(--nx-curva);
}.nx-franja--abierta::-webkit-scrollbar-thumb{ background: rgba(244, 242, 236, 0.22); }/* la franja es negra: todo lo que va dentro se aclara */

.nx-franja .nx-franja__menu, .nx-franja .nx-franja__cabecera, .nx-franja .nx-franja__grupo{ border-color: rgba(244, 242, 236, 0.12); }
.nx-franja h4{ color: var(--nx-texto-claro); }
.nx-franja .nx-franja__fecha{ color: var(--nx-texto-claro-suave); }
.nx-franja .nx-franja__boton, .nx-franja .nx-franja__titulo{ color: var(--nx-texto-claro); }/* el fondo del portal ya NO es transparente: al quedarse clavado abajo,
   las miniaturas le pasarían por detrás. Se define donde se hace sticky. */

.nx-franja .nx-franja__portal{ border-top-color: rgba(244, 242, 236, 0.12); }/* navegación principal del sitio: vive aquí, plegada tras un botón para no
   comerse la altura de la franja.                                           */


.nx-franja__menu{ border-bottom: var(--nx-filete) solid rgba(244, 242, 236, 0.12); }

.nx-franja__boton{
  display: flex;
  align-items: center;
  gap: var(--nx-e2);
  width: 100%;
  padding: var(--nx-e2);
  min-height: var(--nx-toque);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  transition: color var(--nx-t-rapido) var(--nx-curva);
}/* icono de tres líneas que se convierte en × al abrir */

.nx-franja__icono{ position: relative; width: 16px; height: 12px; flex-shrink: 0; }
.nx-franja__icono span{
  position: absolute;
  inset-inline: 0;
  height: 2px;
  background: var(--nx-acento);
  border-radius: 1px;
  transition: transform var(--nx-t-base) var(--nx-curva-entrada),
              opacity   var(--nx-t-base) var(--nx-curva-entrada);
}
.nx-franja__icono span:nth-child(1){ top: 0; }
.nx-franja__icono span:nth-child(2){ top: 5px; }
.nx-franja__icono span:nth-child(3){ top: 10px; }
.nx-franja__boton[aria-expanded="true"] .nx-franja__icono span:nth-child(1){ transform: translateY(5px) rotate(45deg); }
.nx-franja__boton[aria-expanded="true"] .nx-franja__icono span:nth-child(2){ opacity: 0; }
.nx-franja__boton[aria-expanded="true"] .nx-franja__icono span:nth-child(3){ transform: translateY(-5px) rotate(-45deg); }

.nx-franja__cabecera{
  display: flex;
  align-items: center;
  gap: var(--nx-e1);
  padding: var(--nx-e2);
  border-bottom: var(--nx-filete) solid rgba(244, 242, 236, 0.12);
}/* el punto late: es la única señal de que el feed está vivo.
   El bloque 11 lo detiene con prefers-reduced-motion.                        */

.nx-franja__pulso{
  width: 7px; height: 7px;
  border-radius: var(--nx-radio-2);
  background: var(--nx-acento);
  flex-shrink: 0;
  animation: nx-pulso 2s var(--nx-curva) infinite;
}
@keyframes nx-pulso {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.65); }
}
.nx-franja__titulo{
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
}/* ---- tira lateral de la franja — SOLO móvil ------------------------------- */


.nx-franja__resumen, .nx-franja__cerrar{ display: none; }

.nx-franja__tiras{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.nx-franja__tira{
  width: 25px; height: 25px;
  flex-shrink: 0;
  border-radius: 2px;
  object-fit: cover;
  background: var(--nx-superficie-baja);
}
.nx-franja__cuenta{
  flex-shrink: 0;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-claro-suave);
}

.nx-franja__entrada h4{ font-size: var(--nx-texto-s); line-height: 1.3; }
.nx-franja__fecha{ font-size: var(--nx-texto-s); font-weight: var(--nx-peso-ligero); }/* acceso al portal: lo ÚNICO fijo dentro de la franja */


.nx-franja__portal .nx-boton{ font-size: var(--nx-texto-xs); padding-inline: var(--nx-e2); }/* clavado abajo mientras rueda todo lo demás: es el CTA principal de la
   franja y no puede depender de que el usuario baje hasta el final. Es la
   única fila que no se mueve.
   Necesita fondo opaco: si no, las miniaturas pasan por detrás.          */

.nx-franja__portal{
  /* era sticky porque antes scrolleaba la franja entera. Ahora scrollea solo
     el feed, así que el portal es su propia fila y se queda abajo sin trucos.
     Con sticky se metía en el carril del feed y los dos se solapaban.     */
  position: relative;
  z-index: 2;
  padding: var(--nx-e2);
  border-top: var(--nx-filete) solid rgba(244, 242, 236, 0.12);
  background: var(--nx-superficie-oscura);
}
/* cerrado: ni el ☰ ni el CTA del portal. La columna entera abre. */
.nx-franja:not(.nx-franja--abierta) .nx-franja__menu,
.nx-franja:not(.nx-franja--abierta) .nx-franja__portal {
  display: none;
}/* el desvanecido va justo encima del botón, no en el borde de la franja:
   ahí abajo ya no hay corte que suavizar, lo tapa el botón */

.nx-franja__portal::before{
  content: "";
  position: absolute;
  inset-block-end: 100%;
  inset-inline: 0;
  height: 26px;
  pointer-events: none;
  background: linear-gradient(to top,
    var(--nx-superficie-oscura), rgba(7, 7, 7, 0));
}/* ---- datos de obra en la franja ------------------------------------------
   Hechos, nunca cifras del portal: metros, número de promociones y zonas.
   Solo aparecen con la franja abierta — en 184px no caben.               */



.nx-franja__datos{
  display: none;
  padding: var(--nx-e2);
  border-bottom: var(--nx-filete) solid rgba(244, 242, 236, 0.12);
}

/* En 2×2 seguían midiendo 130px para cuatro cifras: mucho sitio para el
   dato menos importante de la franja, y con la cifra encima de su etiqueta
   se leían como cuatro bloques sueltos.
   En lista una debajo de otra, con la cifra a la izquierda y el texto al
   lado, ocupan la mitad y se leen de un vistazo — que es lo que se hace con
   una lista de datos: recorrerla, no contemplarla.                        */
.nx-franja--abierta .nx-franja__datos{
  display: flex;
  flex-direction: column;
  gap: 0;
  padding-block: var(--nx-e1);
}
.nx-franja--abierta .nx-franja__dato{
  display: flex;
  align-items: baseline;
  gap: var(--nx-e2);
  padding-block: 0;
}
/* la cifra en columna propia y alineada a la derecha: así el 3 y el 12
   empiezan donde tienen que empezar y las etiquetas caen a plomo.
   Cifras tabulares para que no bailen al cambiar el número.              */
.nx-franja--abierta .nx-franja__dato b{
  display: block;
  flex: 0 0 1.6em;
  text-align: right;
  font-size: var(--nx-texto-s);
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}
/* una línea por dato, sin partir: «con posibilidad de inversión» a dos
   líneas era lo que hinchaba el bloque. Si no cabe, se recorta — la cifra
   es el dato, la etiqueta solo la nombra.                                */
.nx-franja--abierta .nx-franja__dato span{
  font-size: var(--nx-texto-xs);
  line-height: 1.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nx-franja__dato b{
  display: block;
  font-family: var(--nx-fuente-display);
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-display);
  letter-spacing: var(--nx-tracking-titulo);
  color: var(--nx-coral);
  line-height: 1;
}
.nx-franja__dato span{
  display: block;
  margin-top: 3px;
  font-size: var(--nx-texto-xs);
  color: var(--nx-texto-claro-suave);
}/* en reposo la franja son SOLO fotos: ni nombres de grupo ni títulos. El
   nombre aparece al abrir el panel — con fade, no con display (ese no anima). */


.nx-franja__etiqueta{
  display: block;
  max-height: 0;
  margin-bottom: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-coral);
  transition: opacity var(--nx-t-franja-texto) var(--nx-curva-franja),
              max-height var(--nx-t-franja-texto) var(--nx-curva-franja),
              margin-bottom var(--nx-t-franja-texto) var(--nx-curva-franja);
}.nx-franja--abierta .nx-franja__etiqueta{
  max-height: 2.5em;
  margin-bottom: var(--nx-e2);
  opacity: 1;
  pointer-events: auto;
}/* separador entre "Proyectos terminados" y "Artículos" *//* entre grupos, lo mismo: pegados en reposo, con filete al abrir */



.nx-franja__grupo + .nx-franja__grupo{ margin-top: 2px; }.nx-franja--abierta .nx-franja__grupo + .nx-franja__grupo{
  margin-top: var(--nx-e3);
  padding-top: var(--nx-e3);
  border-top: var(--nx-filete) solid rgba(244, 242, 236, 0.12);
}/* ── apertura de la franja, coreografiada ────────────────────────────────
   El problema de la versión anterior era `display:none`, que no se puede
   transicionar: el texto aparecía de golpe a mitad del ensanche. Ahora todo
   está SIEMPRE en el flujo y lo que cambia son propiedades animables.

   El orden importa y es este:
     0ms    la franja empieza a ensanchar (760ms)
     0ms    la miniatura empieza a encoger de ancho completo a 44px
     420ms  entran los textos, escalonados de 70 en 70ms
   Primero se hace el sitio, después se llena. Al revés se ve amontonado.  *//* Cerrada, el cuerpo es la VENTANA del carrusel: recorta lo que sobra y la
   pila desfila por dentro. Sin este overflow la pila —que mide el doble que
   el hueco, por la copia del bucle— se salía de la franja y se montaba encima
   del resto. Abierta se suelta y vuelve a ser flujo normal.               */



.nx-franja__cuerpo{
  padding: var(--nx-e2);
  overflow: hidden;
  /* los bordes se desvanecen: así el recorte se lee como una ventana por la
     que pasan las fotos, y no como una entrada cortada por error.
     Va aquí y no en la franja: una máscara en el contenedor difuminaría
     también el botón del portal, que es sticky. */
  mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
}/* ---- las miniaturas NO se mueven ------------------------------------------
   Había un carrusel (@keyframes nx-desfilar, 45s, nueve pasos) y se ha
   retirado entero. Razones, en orden:

     · Contenido que se mueve solo obliga a leer en movimiento, y el que
       llega tarde a una entrada tiene que esperar el ciclo completo.
     · Era la tercera animación infinita de la misma columna —con el rodillo
       y el pulso—, y de ahí venía buena parte de la sensación de «cada vez
       que hay una animación se rompe algo».
     · Se congelaba al abrir la franja y el primer grupo quedaba cortado.

   Ahora la lista está quieta. Cambia cuando se publica algo, que es cuando
   tiene sentido que cambie. Lo único que varía es el ORDEN dentro de cada
   grupo, y lo baraja el JS en cada carga: así la columna no es idéntica dos
   visitas seguidas sin que nada se mueva en pantalla.

   Sin carrusel tampoco hace falta la copia que cerraba el bucle: se ha
   quitado de franja.php y de build-preview.py.                             */


.nx-franja__nombre{
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  line-height: 1.25;
  margin: 0;
}
.nx-franja__grupo{ padding: 0; border-bottom: 0; }

.nx-franja__entrada{
  display: flex;
  align-items: flex-start;
  gap: var(--nx-e2);
  overflow: hidden;
}/* en reposo son una tira continua de fotos: 2px. La separación llega al
   abrir, cuando ya hay texto que separar. */

.nx-franja__entrada + .nx-franja__entrada{ margin-top: 2px; }.nx-franja--abierta .nx-franja__entrada + .nx-franja__entrada{ margin-top: var(--nx-e2); }

.nx-franja .nx-franja__miniatura{
  flex: 0 0 auto;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  /* cover y no el `fill` por defecto de <img>: la caja pasa de 4/3 a cuadrada
     al abrir la franja, y con fill la foto se estiraba en cada paso. Recorta,
     no deforma.                                                            */
  object-fit: cover;
  border-radius: var(--nx-radio-1);
  /* mismo tempo que el texto: un solo gesto al abrir */
  transition: width var(--nx-t-franja-texto) var(--nx-curva-franja),
              aspect-ratio var(--nx-t-franja-texto) var(--nx-curva-franja);
}/* el texto existe siempre; en reposo está a cero y recortado por la entrada */

.nx-franja__entrada > div{
  flex: 1 1 auto;
  min-width: 0;
  /* sin esto el texto, aunque invisible, mide hasta 231px: al quedarse sin
     ancho el título se parte en una letra por línea y empuja la fila */
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity   var(--nx-t-franja-texto) var(--nx-curva-franja),
              transform var(--nx-t-franja-texto) var(--nx-curva-franja);
}.nx-franja--abierta .nx-franja__miniatura{
  width: 44px;
  aspect-ratio: 1;
}.nx-franja--abierta .nx-franja__entrada > div{
  max-height: 200px;
  opacity: 1;
  transform: none;
}/* Escalón mínimo: se nota el orden sin que parezca carga a trozos. */

.nx-franja__grupo:nth-child(1) .nx-franja__entrada:nth-child(1) > div{ transition-delay: 20ms; }
.nx-franja__grupo:nth-child(1) .nx-franja__entrada:nth-child(2) > div{ transition-delay: 35ms; }
.nx-franja__grupo:nth-child(1) .nx-franja__entrada:nth-child(3) > div{ transition-delay: 50ms; }
.nx-franja__grupo:nth-child(2) .nx-franja__entrada:nth-child(1) > div{ transition-delay: 40ms; }
.nx-franja__grupo:nth-child(2) .nx-franja__entrada:nth-child(2) > div{ transition-delay: 55ms; }
.nx-franja__grupo:nth-child(2) .nx-franja__entrada:nth-child(3) > div{ transition-delay: 70ms; }
.nx-franja__grupo:nth-child(3) .nx-franja__entrada:nth-child(1) > div{ transition-delay: 60ms; }
.nx-franja__grupo:nth-child(3) .nx-franja__entrada:nth-child(2) > div{ transition-delay: 75ms; }
.nx-franja__grupo:nth-child(3) .nx-franja__entrada:nth-child(3) > div{ transition-delay: 90ms; }/* al cerrar: sin espera, pero sin el snap de 150ms */

.nx-franja:not(.nx-franja--abierta):not(.nx-franja--abierta) .nx-franja__entrada > div{
  transition-delay: 0ms;
  transition-duration: 220ms;
}

/* ---- hero ---------------------------------------------------------------- */
/* HERO OSCURO: la villa al fondo, un velo negro encima para que el texto
   se lea, y el coral VIVO — que sobre negro da 5.79:1 y sobre crema no
   llegaba ni a 3.1:1. Es la única zona clara del sitio donde el coral
   llamativo es legible, por eso vive aquí y no en el resto de la página. */
/* Sin bento: la villa ES la imagen del hero. El texto ocupa la mitad
   izquierda y la derecha queda para que se vea la foto, con el velo más
   flojo por ese lado.                                                     */
.nx-hero {
  position: relative;
  display: grid;
  /* una sola columna: el titular necesita el ancho entero. A 92px la línea
     "Inversión inmobiliaria" pide 953px y en una columna al 52% (720px) se
     partía en cuatro líneas. El resto del bloque sí se limita, más abajo.  */
  grid-template-columns: 1fr;
  align-content: center;
  min-height: min(86vh, 860px);
  gap: var(--nx-e6);
  padding: var(--nx-alto-cabecera) var(--nx-lado);
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro);
  /* clip y no hidden: no crea contexto de scroll, así que el sticky de la
     franja lateral no se rompe */
  overflow: clip;
}

/* La villa y el velo van en dos capas propias, no en el background del
   hero: una imagen de fondo no se puede mover con transform, y el parallax
   la necesita movible. El velo va aparte para que NO se mueva con ella —
   si viajara con la foto, el degradado dejaría de tapar el texto.

   inset: 0 exacto, sin margen extra. La villa (2200×1238, aspecto 1.78) es
   más ancha que la caja del hero (1.71), así que `cover` se rige por el ALTO:
   agrandar la capa la ampliaba y cambiaba el encuadre. Con la caja idéntica
   al hero, el recorte es exactamente el de antes. El hueco que el retraso
   abriría por arriba se evita en el rango de la animación, no con margen.  */
.nx-hero__fondo,
.nx-hero__velo {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* ── la foto del hero ─────────────────────────────────────────────────────
   Dos archivos, medidos en Medios:

     @0.5x   1200 × 675   198 KB
     full    2400 × 1351  302 KB     ← el doble de píxeles por 1,5× de peso

   Antes solo se servía el de 1200, sin `2x`: en cualquier portátil retina la
   foto se ampliaba al doble y se veía blanda. Ahora la pantalla elige.

   Y por encima de 1300px de ancho se sirve siempre la grande aunque la
   pantalla sea de 1x: `image-set` solo mira la densidad, no el tamaño del
   hueco, y en un monitor de 1920 el archivo de 1200 se estira un 60%.
   Ese es el caso en el que más se notaba.                                 */
.nx-hero__fondo {
  background: image-set(
      url("https://nexevo.es/wp-content/uploads/2026/08/Inversion-inmobiliaria-en-Espana-de-principio-a-fin@0.5x.webp") 1x,
      url("https://nexevo.es/wp-content/uploads/2026/08/Inversion-inmobiliaria-en-Espana-de-principio-a-fin.webp") 2x)
    center / cover no-repeat;
  will-change: transform;
}
@media (min-width: 1300px) {
  .nx-hero__fondo {
    background-image: image-set(
      url("https://nexevo.es/wp-content/uploads/2026/08/Inversion-inmobiliaria-en-Espana-de-principio-a-fin.webp") 1x);
  }
}
.nx-hero__velo {
  background: linear-gradient(100deg,
    rgba(7,7,7,0.95) 0%, rgba(7,7,7,0.86) 34%,
    rgba(7,7,7,0.42) 66%, rgba(7,7,7,0.18) 100%);
}
/* solo el contenido se levanta sobre las capas del parallax. Antes era
   `.nx-hero > *`, que le ponía position: relative también a la foto y al
   velo y los sacaba de su posición absoluta: el hero se quedaba negro. */
.nx-hero > .nx-anim { position: relative; z-index: 1; }

/* con <br> a mano, balance sobra: los cortes ya están decididos */
.nx-hero__titulo {
  max-width: none;
  color: var(--nx-blanco);
  text-wrap: normal;
}
/* el titular va a sangre; lo demás se queda en medida de lectura */
.nx-hero .nx-kicker,
.nx-hero .nx-sub,
.nx-hero .nx-lead,
.nx-hero .nx-botonera,
.nx-hero .nx-datos { max-width: 42em; }
.nx-hero .nx-kicker { color: var(--nx-coral); }
.nx-hero .nx-sub    { color: var(--nx-coral); }
.nx-hero .nx-lead   { color: var(--nx-texto-claro-suave); }
.nx-hero .nx-datos__n { color: var(--nx-coral); }
.nx-hero .nx-datos__l { color: var(--nx-texto-claro-suave); }
/* el secundario se vuelve claro, como en cualquier fondo oscuro */
.nx-hero .nx-boton--secundario {
  border-color: rgba(244, 242, 236, 0.45);
  color: var(--nx-texto-claro);
}
.nx-hero .nx-boton--secundario:hover { background: var(--nx-texto-claro); color: var(--nx-navy); }
.nx-hero a:focus-visible { outline-color: var(--nx-coral); }

/* la imagen pesada solo se pide en pantallas que la aprovechan.
   Va en las capas, NO en .nx-hero: desde que la villa vive en
   .nx-hero__fondo, un background aquí queda por DEBAJO de esa capa, así que
   el móvil se descargaba las dos imágenes (375KB) y seguía viendo la de
   escritorio. El velo también cambia: en vertical el degradado es de arriba
   abajo, no lateral.                                                       */
@media (max-width: 1100px) {
  .nx-hero__fondo {
    /* 72% y no center: la foto es apaisada y en un móvil vertical solo cabe
       una cuarta parte de su ancho. Centrada salía un trozo oscuro sin nada;
       a 72% entra el atardecer y las figuras de la playa, que es lo que se
       reconoce. Mismo archivo, otro encuadre — no hace falta una foto
       vertical aparte.                                                     */
    background: image-set(url("https://nexevo.es/wp-content/uploads/2026/08/Inversion-inmobiliaria-en-Espana-de-principio-a-fin@0.5x.webp") 1x) 72% center / cover no-repeat;
  }
  .nx-hero__velo {
    background: linear-gradient(180deg,
      rgba(7,7,7,0.92) 0%, rgba(7,7,7,0.78) 55%, rgba(7,7,7,0.55) 100%);
  }
}

/* ---- pilares ---------------------------------------------------------------
   Ya no tiene componente propio: usa .nx-tarjeta.                            */
.nx-caminos { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--nx-e3); }
/* Una columna en el mismo corte que el resto (760px). A 700px las tarjetas
   de «cómo trabajamos» seguían a dos en un iPhone Plus / landscape corto. */
.nx-pilares { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--nx-e3); }
/* Con cuatro pilares, 2×2 en escritorio. «Por qué NEXEVO» es el único bloque
   que llega a cuatro; el resto de páginas lleva tres y se queda a tres. La
   columna única va solo en móvil, más abajo, a 760px. */
.nx-pilares:has(> :nth-child(4)) { grid-template-columns: repeat(2, 1fr); }

/* ---- caminos (dos vías) ----------------------------------------------------
   Ya no tiene componente propio: usa .nx-tarjeta.                            */

/* ---- rejilla de datos (prueba de experiencia) ------------------------------ */
/* Fondo blanco y una celda con filete por dato.                              */
.nx-datos {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--nx-superficie);
  border: var(--nx-filete) solid var(--nx-borde);
  border-radius: var(--nx-radio-1);
  overflow: hidden;
}
.nx-datos__celda {
  min-width: 0;
  padding: var(--nx-e4) var(--nx-e3);
  border-right: var(--nx-filete) solid var(--nx-borde);
}
.nx-datos__celda:last-child { border-right: 0; }
.nx-datos__n {
  display: block;
  font-family: var(--nx-fuente-display);
  /* l, no xl: a 56px «+100.000 m²» y «3–5 meses» no caben en un cuarto
     de fila y reventaban la caja. 24px entra y se lee como cifra, no como
     titular de página. */
  font-size: var(--nx-texto-l);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-titulo);
  line-height: 1.15;
  color: var(--nx-acento-texto);
  overflow-wrap: break-word;
  font-variant-numeric: tabular-nums;
}
.nx-datos__l {
  display: block;
  margin-top: var(--nx-e1);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
}

/* compacta: la misma anatomía sin caja, para colgar del CTA del hero.
   Se amplía el componente, no se crea otro.
   2×2 y no 4 en fila: la columna del hero baja de 380px entre 1100 y 1300,
   y las etiquetas son más anchas que las cifras — en fila se parte en 3+1. */
.nx-datos--compacta {
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: start;
  gap: var(--nx-e3) var(--nx-e5);
  background: none;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.nx-datos--compacta .nx-datos__celda { padding: 0; border-right: 0; }
.nx-datos--compacta .nx-datos__celda--ancha { grid-column: 1 / -1; }
.nx-datos--compacta .nx-datos__n { font-size: var(--nx-texto-m); }
.nx-datos--compacta .nx-datos__l { margin-top: 2px; }

/* ---- mapa de zona de trabajo ----------------------------------------------
   Geometría real (Natural Earth), no un dibujo a mano: la silueta de España
   y las Baleares son exactas. Va inline en el HTML porque el trazo se anima
   desde CSS, y a un <img> externo no se le puede entrar.

   Cada path lleva pathLength="1", así el dasharray es 1 y no hay que medir
   longitudes reales: la costa se dibuja de 1 a 0.                          */
.nx-mapa-caja { display: flex; align-items: center; justify-content: center; height: 100%; }
.nx-mapa { width: 100%; height: auto; overflow: visible; }

.nx-mapa__tierra path {
  fill: var(--nx-superficie-baja);
  stroke: var(--nx-texto);
  stroke-width: 2;
  stroke-linejoin: round;
}
.nx-mapa__islas path {
  fill: var(--nx-acento);
  stroke: var(--nx-acento);
  stroke-width: 4;
  stroke-linejoin: round;
}
/* sin fill-box el scale de un <circle> se calcula desde el 0,0 del SVG
   y el punto sale disparado en vez de crecer sobre sí mismo */
.nx-mapa__punto {
  fill: var(--nx-acento);
  transform-box: fill-box;
  transform-origin: center;
}
/* ---- parcela → obra -------------------------------------------------------
   El hueco de la derecha del hero de /inversion-inmobiliaria-espana/ estaba
   vacío en escritorio. Misma técnica que el mapa: SVG inline con pathLength
   y trazo que se dibuja solo. Sin prefers-reduced-motion se ve el dibujo
   entero desde el primer momento, porque el dasharray solo existe dentro
   del bloque de movimiento.                                                */
.nx-parcela-caja { display: flex; align-items: center; justify-content: center; height: 100%; }
.nx-parcela { width: 100%; height: auto; overflow: visible; }
.nx-parcela__traza {
  fill: none;
  stroke: var(--nx-texto);
  stroke-width: calc(var(--nx-filete) * 2);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* el coral marca lo que es replanteo —estacas y cuerda—, no la obra */
.nx-parcela__traza--acento { stroke: var(--nx-acento); }
.nx-parcela__traza--fina { stroke: var(--nx-texto-suave); stroke-width: calc(var(--nx-filete) * 1.5); }

.nx-mapa__nombre {
  font-family: var(--nx-fuente);
  /* ahora van SOBRE la península: sin este contorno del color del relleno,
     las letras se comen la línea de costa y no se leen */
  paint-order: stroke;
  stroke: var(--nx-superficie-baja);
  stroke-width: 7;
  stroke-linejoin: round;
  font-size: 26px;                 /* unidades del viewBox, no píxeles */
  font-weight: var(--nx-peso-medio);
  letter-spacing: 0.06em;
  fill: var(--nx-texto);
  text-transform: uppercase;
}/* ---- accesos rápidos: rodillo de 7 caras ---------------------------------
   Un cilindro de verdad, no una tira que se desliza. Cada acceso está pegado
   a una cara del polígono: se le gira su ángulo y se le empuja hacia fuera el
   radio. El rodillo gira sobre su eje X y las caras entran y salen por el
   canto, girando hacia dentro.

   El radio sale de la geometría del polígono regular de 7 lados:
     r = (alto / 2) / tan(180° / 7)  ≈  alto × 1.0383

   Con 7 caras no hacen falta copias para cerrar el bucle: 360° vuelve al
   principio solo. La versión anterior era una tira plana con dos renglones
   duplicados al final — por eso se veía rara.

   Al abrir la franja se APLANA: las caras vuelven al flujo normal.        */



.nx-franja__accesos{
  --alto: 46px;
  --paso: 72deg;                    /* 360 / 5 caras */
  --radio: calc(var(--alto) * 0.6882);   /* (alto/2) / tan(180/5) */
  height: calc(var(--alto) * 2);
  padding-inline: var(--nx-e2);
  overflow: hidden;
  perspective: 340px;
  perspective-origin: 50% 50%;
  border-bottom: var(--nx-filete) solid rgba(244, 242, 236, 0.12);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 26%, #000 74%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 26%, #000 74%, transparent);
}
.nx-franja__pista{
  position: relative;
  height: var(--alto);
  margin-block: calc(var(--alto) / 2);
  transform-style: preserve-3d;
}
.nx-franja__acceso{
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  /* La cara del rodillo mide 139px y «Quiero invertir» pedía 152: se cortaba
     por la mitad. Con el tamaño chico entra entero y sigue leyéndose. */
  font-size: var(--nx-texto-xs);
  white-space: nowrap;
  font-weight: var(--nx-peso-medio);
  line-height: 1.2;
  color: var(--nx-texto-claro);
  backface-visibility: hidden;
  transform: rotateX(calc(var(--paso) * var(--i))) translateZ(var(--radio));
  /* transform+opacity se completan más abajo al aplanar; color sigue rápido */
  transition: color var(--nx-t-rapido) var(--nx-curva);
}
.nx-franja__acceso .nx-enlace__flecha{ color: var(--nx-coral); opacity: 1; transform: none; }
.nx-franja__acceso:hover{ color: var(--nx-coral); }

@media (prefers-reduced-motion: no-preference) {/* 5 caras × 3s = 15s. Fija ~2.6s + gira ~0.4s (se ve el cambio). */
  .nx-franja__pista{ animation: nx-rodar 15s ease-in-out infinite; }
  @keyframes nx-rodar {
    0.000%, 17.334% { transform: rotateX(-0deg); }
    20.000%       { transform: rotateX(-72deg); }
    20.000%, 37.334% { transform: rotateX(-72deg); }
    40.000%       { transform: rotateX(-144deg); }
    40.000%, 57.334% { transform: rotateX(-144deg); }
    60.000%       { transform: rotateX(-216deg); }
    60.000%, 77.334% { transform: rotateX(-216deg); }
    80.000%       { transform: rotateX(-288deg); }
    80.000%, 97.334% { transform: rotateX(-288deg); }
    100%            { transform: rotateX(-360deg); }
  }
}/* Al apuntar / abrir: el rodillo se aplana y se ven los siete.
   Transiciones en height/transform para que no sea un corte seco. */

.nx-franja__accesos{
  transition: height var(--nx-t-franja) var(--nx-curva-franja),
              padding-block var(--nx-t-franja) var(--nx-curva-franja);
}
.nx-franja__pista{
  transition: height var(--nx-t-franja) var(--nx-curva-franja),
              margin-block var(--nx-t-franja) var(--nx-curva-franja),
              transform var(--nx-t-franja) var(--nx-curva-franja);
}
.nx-franja__acceso{
  transition: transform var(--nx-t-franja) var(--nx-curva-franja),
              padding-block var(--nx-t-franja-texto) var(--nx-curva-franja),
              opacity var(--nx-t-franja-texto) var(--nx-curva-franja),
              color var(--nx-t-rapido) var(--nx-curva);
}
.nx-franja--abierta .nx-franja__accesos{
  height: auto;
  padding-block: var(--nx-e2);
  perspective: none;
  -webkit-mask-image: none;
          mask-image: none;
  /* imprescindible: con overflow hidden el tamaño mínimo automático de la
     caja en la rejilla es 0, así que al no caber los siete enlaces la fila
     se dejaba aplastar de 217px a 71px y solo se veían dos. En visible su
     mínimo vuelve a ser min-content y la rejilla ya no puede encogerla:
     desborda, y de eso se encarga el scroll de la franja.                 */
  overflow: visible;
}
.nx-franja--abierta .nx-franja__pista{
  height: auto;
  margin-block: 0;
  animation: none;
  transform: none;
  transform-style: flat;
}
.nx-franja--abierta .nx-franja__acceso{
  position: static;
  transform: none;
  padding-block: 7px;
}/* aparición escalonada de los 7 enlaces al aplanar: se lee como un abanico */

.nx-franja--abierta .nx-franja__acceso:nth-child(1){ transition-delay: 40ms; }
.nx-franja--abierta .nx-franja__acceso:nth-child(2){ transition-delay: 70ms; }
.nx-franja--abierta .nx-franja__acceso:nth-child(3){ transition-delay: 100ms; }
.nx-franja--abierta .nx-franja__acceso:nth-child(4){ transition-delay: 130ms; }
.nx-franja--abierta .nx-franja__acceso:nth-child(5){ transition-delay: 160ms; }

/* ---- galería de proyectos (accordion_row) ---------------------------------
   brand.json.component_rules.accordion_row: 3-5 piezas en fila, una sola
   expandida a la vez, borde coral en la expandida.

   EXCEPCIÓN DE MOVIMIENTO, la única del sistema para layout y ya declarada en
   motion.json: se anima `grid-template-columns`. No hay otra forma de que las
   piezas se repartan el ancho entre ellas.

   La expansión la resuelve `:has()` en el contenedor, sin una línea de JS.  */
.nx-galeria {
  display: grid;
  /* explícito y NO repeat(5,1fr): el navegador interpola lista contra lista.
     Con repeat() la primera apertura daba un salto y las siguientes no.   */
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  gap: 4px;
  height: 560px;
  /* la galería va más lenta que el resto: es el gesto más grande de la
     página y a 420ms se sentía como un tirón */
  transition: grid-template-columns var(--nx-t-lento) var(--nx-curva-entrada);
}
/* la pieza señalada se lleva 3 de las 7 partes; las otras cuatro, una cada una */
.nx-galeria:has(> :nth-child(1):hover), .nx-galeria:has(> :nth-child(1):focus-within) { grid-template-columns: 3fr 1fr 1fr 1fr 1fr; }
.nx-galeria:has(> :nth-child(2):hover), .nx-galeria:has(> :nth-child(2):focus-within) { grid-template-columns: 1fr 3fr 1fr 1fr 1fr; }
.nx-galeria:has(> :nth-child(3):hover), .nx-galeria:has(> :nth-child(3):focus-within) { grid-template-columns: 1fr 1fr 3fr 1fr 1fr; }
.nx-galeria:has(> :nth-child(4):hover), .nx-galeria:has(> :nth-child(4):focus-within) { grid-template-columns: 1fr 1fr 1fr 3fr 1fr; }
.nx-galeria:has(> :nth-child(5):hover), .nx-galeria:has(> :nth-child(5):focus-within) { grid-template-columns: 1fr 1fr 1fr 1fr 3fr; }

.nx-galeria__pieza {
  position: relative;
  overflow: hidden;
  min-width: 0;
  border: var(--nx-filete) solid transparent;
  border-radius: var(--nx-radio-1);
  background: var(--nx-superficie-oscura);
  transition: border-color var(--nx-t-lento) var(--nx-curva-entrada);
}
/* la foto entra ligeramente ampliada y se asienta al expandirse: es lo que
   disimula el reflujo de la rejilla y hace que el gesto se lea suave */
.nx-galeria__img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  scale: 1.06;
  transition: scale var(--nx-t-lento) var(--nx-curva-entrada);
}
.nx-galeria__pieza:hover .nx-galeria__img,
.nx-galeria__pieza:focus-within .nx-galeria__img { scale: 1; }
/* el pie se lee siempre: degradado desde el negro, no una caja */
.nx-galeria__pie {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--nx-e3);
  background: linear-gradient(to top, rgba(7, 7, 7, 0.88), rgba(7, 7, 7, 0.55) 45%, transparent);
}
.nx-galeria__indice {
  display: block;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  color: var(--nx-coral);
  margin-bottom: var(--nx-e1);
}
/* el título no envuelve: al estrecharse la pieza se recorta, como en la
   referencia — es lo que da la sensación de columna comprimida */
.nx-galeria__titulo {
  font-family: var(--nx-fuente-display);
  font-size: var(--nx-texto-l);
  font-weight: var(--nx-peso-display);
  letter-spacing: var(--nx-tracking-titulo);
  color: var(--nx-texto-claro);
  white-space: nowrap;
  margin-bottom: 0;
}
/* el detalle solo existe en la pieza expandida */
/* el enlace al portal solo con la pieza abierta: cinco «Ver más» idénticos
   apilados en ranuras estrechas son ruido, y los cinco van al mismo sitio.
   La insignia de estado sí se ve siempre — saber si está entregado o en
   venta es justo lo que decide si te interesa abrirlo.                    */
.nx-galeria__mas {
  display: inline-block;
  margin-top: var(--nx-e1);
  opacity: 0;
  transition: opacity var(--nx-t-base) var(--nx-curva-entrada);
}
.nx-galeria__meta {
  margin-top: var(--nx-e1);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-claro-suave);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--nx-t-lento) var(--nx-curva-entrada);
}
.nx-galeria__pieza { cursor: pointer; }

/* ---- visor a pantalla completa de la galería ------------------------------
   <dialog> nativo: showModal() lo centra, le da ::backdrop y atrapa el foco
   sin una librería. Un único visor por página, reutilizado por JS
   (03-scripts.html) para las cinco piezas. */
.nx-galeria__visor {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(100vw, 900px);
  height: min(100dvh, 720px);
  max-width: 100vw;
  max-height: 100dvh;
  padding: 0;
  border: none;
  border-radius: var(--nx-radio-1);
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro);
  overflow-y: auto;
}
.nx-galeria__visor::backdrop { background: rgba(7, 7, 7, 0.72); }
.nx-galeria__visor-img {
  display: block;
  width: 100%;
  max-height: 60dvh;
  object-fit: contain;
  background: #000;
}
.nx-galeria__visor-cerrar {
  position: absolute;
  inset-block-start: var(--nx-e2);
  inset-inline-end: var(--nx-e2);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(7, 7, 7, 0.55);
  color: var(--nx-texto-claro);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.nx-galeria__visor-pie { padding: var(--nx-e4); }
.nx-galeria__visor-titulo {
  font-family: var(--nx-fuente-display);
  font-size: var(--nx-texto-xl);
  font-weight: var(--nx-peso-display);
  margin-block: var(--nx-e1) 0;
}
.nx-galeria__visor-meta {
  margin-top: var(--nx-e1);
  color: var(--nx-texto-claro-suave);
}
.nx-galeria__visor-portal { margin-top: var(--nx-e3); }
@media (max-width: 560px) {
  .nx-galeria__visor {
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
  }
  .nx-galeria__visor-img { max-height: 45dvh; }
}

/* ---- glosario: bloque tipográfico -----------------------------------------
   Los términos fluyen como un texto continuo, alternando dos registros:
   impares en sans mayúscula, pares en la itálica serif. Es el contraste
   entre las dos familias lo que hace el bloque, no el color.
   Cada término abre su definición al pasar por encima o al enfocarlo.      */
/* bloque entero en negro. SOLO #nx-glosario / --glosario: :has() pintaba
   de negro toda la home si Bricks envuelve el HTML en un .nx-seccion. */
#nx-glosario,
.nx-seccion--glosario {
  background: var(--nx-superficie-oscura);
  border-block: 0;
  color: var(--nx-texto-claro);
}
#nx-glosario h2,
.nx-seccion--glosario h2 { color: var(--nx-texto-claro); }
#nx-glosario .nx-kicker,
.nx-seccion--glosario .nx-kicker { color: var(--nx-coral); }
#nx-glosario .nx-lead,
.nx-seccion--glosario .nx-lead { color: var(--nx-texto-claro-suave); }
#nx-glosario .nx-enlace,
.nx-seccion--glosario .nx-enlace { color: var(--nx-texto-claro); }
#nx-glosario .nx-enlace__flecha,
.nx-seccion--glosario .nx-enlace__flecha { color: var(--nx-coral); }
#nx-glosario .nx-glosario-ficha,
.nx-seccion--glosario .nx-glosario-ficha {
  margin: 0;
  padding: 0;
  background: transparent;
}
#nx-glosario .nx-glosario__def,
.nx-seccion--glosario .nx-glosario__def {
  background: var(--nx-navy);
  border: var(--nx-filete) solid rgba(244, 242, 236, 0.14);
}

.nx-glosario-ficha {
  margin-inline: calc(var(--nx-lado) * -1);
  margin-block-start: var(--nx-e4);
  padding: var(--nx-e5) var(--nx-lado);
  background: var(--nx-superficie-oscura);
}
.nx-glosario {
  display: flex;
  flex-direction: column;
  gap: var(--nx-e4);
  line-height: 1.15;
}
.nx-glosario__fila {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  justify-content: space-between;
  gap: clamp(10px, 1.6vw, 28px);
  width: 100%;
  min-width: 0;
}

/* ── glosario sin filas ────────────────────────────────────────────────────
   El bloque se rehízo agrupando los términos en .nx-glosario__fila, siete
   líneas llenas como el mock. Pero el HTML se pega a mano en Bricks, y la
   home que hay publicada sigue siendo la anterior: 32 términos colgando
   directos de .nx-glosario, sin filas. Con el flex en columna de arriba eso
   sale como una lista, uno por línea.

   Así que el bloque tiene que valer para las dos formas. Sin filas se
   compone como un párrafo justificado: los términos llenan la línea y saltan
   solos, que es el mismo efecto por otro camino.                          */
.nx-glosario:not(:has(.nx-glosario__fila)) {
  display: block;
  text-align: justify;
  line-height: 1.5;
}
.nx-glosario:not(:has(.nx-glosario__fila)) > .nx-glosario__item {
  display: inline;
  margin-inline-end: 0.7em;
}
/* la alternancia de registros va por posición en la fila; sin filas se cuenta
   sobre el bloque, para que no salgan los 32 términos en la misma tipografía */
.nx-glosario:not(:has(.nx-glosario__fila)) > .nx-glosario__item:nth-child(odd) .nx-glosario__termino {
  font-family: var(--nx-fuente-display);
  font-weight: var(--nx-peso-display);
  text-transform: uppercase;
  letter-spacing: calc(0.08em * 1.2);
}
.nx-glosario:not(:has(.nx-glosario__fila)) > .nx-glosario__item:nth-child(even) .nx-glosario__termino {
  font-family: var(--nx-fuente-script);
  font-style: normal;
  font-weight: var(--nx-peso-normal);
  font-size: 1.25em;
}
/* el globo mide 280px y cuelga del término; sin filas no hay forma de saber
   cuál cierra línea, y el que caiga a la derecha del todo se sale y le da
   scroll lateral a la página entera. Se ancla al bloque, como en móvil. */
.nx-glosario:not(:has(.nx-glosario__fila)) { position: relative; }
.nx-glosario:not(:has(.nx-glosario__fila)) > .nx-glosario__item { position: static; }
.nx-glosario:not(:has(.nx-glosario__fila)) .nx-glosario__def {
  inset-inline: 0;
  width: auto;
  max-width: none;
}
.nx-glosario-ficha .nx-glosario__termino,
.nx-seccion--glosario .nx-glosario__termino,
#nx-glosario .nx-glosario__termino {
  color: var(--nx-texto-claro);
  background: transparent;
  border: 0;
  padding: 0;
}
.nx-glosario-ficha .nx-glosario__termino--clave,
.nx-seccion--glosario .nx-glosario__termino--clave,
#nx-glosario .nx-glosario__termino--clave { color: var(--nx-coral); }

.nx-glosario__item {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  font-size: clamp(0.8125rem, 1.55vw, 1.75rem);
}

.nx-glosario__termino {
  white-space: nowrap;
  font-size: 1em;
  line-height: 1.15;
  color: var(--nx-texto);
  text-align: left;
  transition: color var(--nx-t-rapido) var(--nx-curva);
}
/* registro A: sans, negrita, mayúscula — por posición en la FILA.
   Tracking 0.08em × 1.2 para llenar el hueco entre palabras. */
.nx-glosario__fila .nx-glosario__item:nth-child(odd) .nx-glosario__termino {
  font-family: var(--nx-fuente-display);
  font-weight: var(--nx-peso-display);
  text-transform: uppercase;
  letter-spacing: calc(0.08em * 1.2);
}
.nx-glosario__fila--italica .nx-glosario__item:nth-child(odd) .nx-glosario__termino {
  font-family: var(--nx-fuente-script);
  font-style: normal;
  font-weight: var(--nx-peso-normal);
  text-transform: none;
  letter-spacing: var(--nx-tracking-normal);
  font-size: 1.32em;
}
/* los términos que le importan a un inversor —rentabilidad, financiación,
   riesgo— van en coral: dan el ritmo del bloque y marcan por dónde entrar */
.nx-glosario__termino--clave { color: var(--nx-acento-texto); }
#nx-glosario .nx-glosario__termino,
.nx-seccion--glosario .nx-glosario__termino,
.nx-glosario-ficha .nx-glosario__termino { color: var(--nx-texto-claro); }
#nx-glosario .nx-glosario__termino--clave,
.nx-seccion--glosario .nx-glosario__termino--clave,
.nx-glosario-ficha .nx-glosario__termino--clave { color: var(--nx-coral); }

/* registro B: script (Pinyon / Marck), sin italic sintético. 1.32em y no 1.25:
   el script lee más pequeño a igual tamaño que el sans, así que se compensa
   subiéndolo un punto (crítica de diseño móvil, 2026-09-01). */
.nx-glosario__fila .nx-glosario__item:nth-child(even) .nx-glosario__termino {
  font-family: var(--nx-fuente-script);
  font-style: normal;
  font-weight: var(--nx-peso-normal);
  font-size: 1.32em;
}
/* BUG (2026-09-01): esta regla cambiaba la familia a display/mayúsculas pero
   nunca reseteaba el font-size, así que heredaba el 1.25em pensado para el
   script de la regla de arriba — «Licencia de primera ocupación» salía un
   50% más grande que el resto de términos en mayúscula sin motivo. */
.nx-glosario__fila--italica .nx-glosario__item:nth-child(even) .nx-glosario__termino {
  font-family: var(--nx-fuente-display);
  font-style: normal;
  font-weight: var(--nx-peso-display);
  text-transform: uppercase;
  letter-spacing: calc(0.08em * 1.2);
  font-size: 1em;
}

/* la definición: cuelga del término, sin desplazar nada del bloque */
.nx-glosario__def {
  position: absolute;
  inset-block-start: calc(100% + var(--nx-e1));
  inset-inline-start: 0;
  z-index: 30;
  width: max-content;
  max-width: 280px;
  padding: var(--nx-e2);
  border-radius: var(--nx-radio-1);
  background: var(--nx-superficie-oscura);
  color: var(--nx-texto-claro);
  font-family: var(--nx-fuente);
  font-size: var(--nx-texto-s);
  font-style: normal;
  font-weight: var(--nx-peso-ligero);
  letter-spacing: var(--nx-tracking-normal);
  text-transform: none;
  line-height: 1.45;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity    var(--nx-t-rapido) var(--nx-curva),
              transform  var(--nx-t-rapido) var(--nx-curva),
              visibility var(--nx-t-rapido) var(--nx-curva);
}
/* el último de cada línea abre hacia la izquierda para no salirse */
.nx-glosario__fila .nx-glosario__item:last-child .nx-glosario__def {
  inset-inline-start: auto;
  inset-inline-end: 0;
}


/* ---- WhatsApp: en la cabecera, a la derecha del idioma --------------------
   Ya no flota a media altura: vive en .nx-header__fin, mismo sitio en móvil
   y escritorio. Fondo transparente, borde e icono coral legible (acento-texto
   da 5:1 sobre crema; el coral vivo fallaría como icono). Radio 8px.         */
.nx-wa {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1.5px solid var(--nx-acento-texto);
  border-radius: var(--nx-radio-1);   /* 8px */
  background: transparent;
  color: var(--nx-acento-texto);
  text-decoration: none;
  box-shadow: none;
  line-height: 0;
  transition: background var(--nx-t-rapido) var(--nx-curva),
              color var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva);
}
/* Bricks a veces deja justify:normal y el glifo se va 7–8px a la izquierda */
.nx-header .nx-wa {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
.nx-wa__glifo {
  flex: none;
  display: block;
  width: 22px;
  height: 22px;
  padding: 0;
  margin: 0;
}
/* La etiqueta queda solo para lectores de pantalla: el aria-label ya basta,
   pero se mantiene el texto por si algún lector lo prefiere.               */
.nx-wa__texto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}



/* ---- navegación de la cabecera --------------------------------------------
   Tres enlaces. Sustituye al menú de la franja, que tenía cinco y tres de
   ellos eran anclas a la home: desde cualquier otra página no llevaban a
   ningún sitio. Aquí están siempre, en las 29 páginas y en los dos idiomas.
   En móvil se esconde: a 375px no caben tres enlaces más el logo y ES·RU, y
   la navegación ya vive en la franja, que se abre de un toque.            */
.nx-nav { display: flex; align-items: center; gap: var(--nx-e2); }
/* LiteSpeed Unique CSS a veces recorta el display de la nav en páginas
   interiores y deja el ☰ de móvil en escritorio. En ≥1201px la nav de
   cabecera es siempre la misma fila, home y resto. */
@media (min-width: 1201px) {
  .nx-nav {
    display: flex !important;
    position: static;
    flex-direction: row;
    max-height: none;
    overflow: visible;
    padding: 0;
    background: transparent;
    border: 0;
  }
  .nx-menu-boton { display: none !important; }
}
.nx-nav__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-block: 4px;
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  font-family: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  white-space: nowrap;
  color: var(--nx-texto);
  transition: color var(--nx-t-rapido) var(--nx-curva);
}
.nx-nav__chev {
  flex: none;
  font-size: 0.7em;
  font-weight: var(--nx-peso-medio);
  line-height: 1;
  opacity: 0.7;
  transition: transform var(--nx-t-rapido) var(--nx-curva);
}
.nx-nav__grupo:hover .nx-nav__chev,
.nx-nav__grupo:focus-within .nx-nav__chev,
.nx-nav__grupo--abierto .nx-nav__chev {
  transform: rotate(90deg);
}
.nx-nav__grupo { position: relative; }
.nx-mega {
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  translate: -50% 6px;
  min-width: 248px;
  padding: var(--nx-e1);
  background: var(--nx-fondo);
  border: var(--nx-filete) solid var(--nx-borde);
  border-radius: var(--nx-radio-1);
  box-shadow: 0 16px 40px rgba(7, 7, 7, 0.1);
  display: none;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 50;
  transition: opacity var(--nx-t-rapido) var(--nx-curva),
              transform var(--nx-t-rapido) var(--nx-curva),
              visibility var(--nx-t-rapido) var(--nx-curva);
}
.nx-mega::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 100%;
  height: 12px;
}
.nx-nav__grupo:hover .nx-mega,
.nx-nav__grupo:focus-within .nx-mega,
.nx-nav__grupo--abierto .nx-mega {
  display: block;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  translate: -50% 0;
}
.nx-mega a {
  display: block;
  padding: 8px 10px;
  border-radius: var(--nx-radio-1);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto);
  text-decoration: none;
}
.nx-mega a:hover,
.nx-mega a:focus-visible {
  background: var(--nx-superficie-baja);
  color: var(--nx-acento-texto);
}
/* mismo filete que el selector de idioma: una sola idea de «esto se pulsa» */
.nx-nav__item::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  height: var(--nx-filete);
  background: var(--nx-acento);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--nx-t-base) var(--nx-curva-entrada);
}

.nx-menu-boton {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  color: inherit;
}
.nx-menu-boton__icono {
  position: relative;
  width: 18px;
  height: 12px;
}
.nx-menu-boton__icono span {
  position: absolute;
  inset-inline: 0;
  height: 1.5px;
  background: currentColor;
  border-radius: 1px;
  transition: transform var(--nx-t-rapido) var(--nx-curva), opacity var(--nx-t-rapido) var(--nx-curva);
}
.nx-menu-boton__icono span:nth-child(1) { top: 0; }
.nx-menu-boton__icono span:nth-child(2) { top: 5px; }
.nx-menu-boton__icono span:nth-child(3) { top: 10px; }
.nx-header--menu .nx-menu-boton__icono span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nx-header--menu .nx-menu-boton__icono span:nth-child(2) { opacity: 0; }
.nx-header--menu .nx-menu-boton__icono span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* ── la nav en móvil: un desplegable colgado de la cabecera ────────────────
   Aquí llegó a no haber nada: se quitaron el ☰ y la nav entera y se dejó la
   navegación solo en la franja. Mal —el ☰ es donde todo el mundo mira, y la
   franja es un rail de 36px que no se lee como menú—. Vuelve, pero con dos
   cosas que antes no tenía y que eran la causa del desastre:

     · z-index 55, por debajo de la franja (60) y por encima del hero. Antes
       empataba a 45 con la franja y se comía los toques de la tira;
     · los mega menús pasan a `static`: se despliegan DENTRO del panel, en su
       sitio. Flotando en absolute es como acababan volcados sobre el hero.  */
@media (max-width: 1200px) {
  .nx-menu-boton { display: inline-flex; }

  .nx-nav {
    display: none;
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    z-index: 55;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-height: calc(100dvh - var(--nx-header-alto));
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--nx-e2) var(--nx-lado) var(--nx-e4);
    background: var(--nx-superficie-oscura);
    border-bottom: var(--nx-filete) solid var(--nx-borde);
  }
  .nx-header--menu .nx-nav { display: flex; }

  .nx-nav__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding-block: 14px;
    color: var(--nx-texto-claro);
    text-align: start;
  }
  /* el filete del hover se hizo para una fila horizontal; en una lista
     vertical dibuja una raya de lado a lado bajo cada línea */
  .nx-nav__item::after { content: none; }
  .nx-nav__grupo + .nx-nav__grupo .nx-nav__item,
  .nx-nav__grupo + a.nx-nav__item,
  a.nx-nav__item + .nx-nav__grupo .nx-nav__item {
    border-top: var(--nx-filete) solid rgba(244, 242, 236, .14);
  }
  .nx-nav__chev { transition: transform var(--nx-t-rapido) var(--nx-curva); }
  .nx-nav__grupo--abierto .nx-nav__chev { transform: rotate(90deg); }

  .nx-mega {
    position: static;
    width: auto;
    min-width: 0;
    padding: 0 0 var(--nx-e2) var(--nx-e2);
    background: transparent;
    border: 0;
    box-shadow: none;
    transform: none;
  }
  /* El mega de escritorio se centra bajo su botón con `translate: -50%`, y eso
     hay que apagarlo aquí o el submenú sale 101px fuera por la izquierda con
     los enlaces cortados. Dos cuidados: `translate` no es `transform`, son
     propiedades distintas y anular una no toca la otra; y el desplazamiento se
     declara en la regla de «abierto», que pesa más que `.nx-mega` a secas, así
     que hay que repetir esos tres selectores para poder ganarle. */
  .nx-nav__grupo:hover .nx-mega,
  .nx-nav__grupo:focus-within .nx-mega,
  .nx-nav__grupo--abierto .nx-mega { translate: none; }
  .nx-mega::before { content: none; }
  .nx-mega a {
    display: block;
    padding-block: 9px;
    color: var(--nx-texto-claro);
    opacity: .8;
  }
  .nx-mega a:hover,
  .nx-mega a:focus-visible { opacity: 1; color: var(--nx-coral); }

  /* con el panel desplegado la cabecera es oscura sí o sí: el modo cristal
     dejaba el ☰ en blanco sobre el crema del panel y desaparecía */
  .nx-header--menu { background: var(--nx-superficie-oscura) !important; }
  .nx-header--menu .nx-menu-boton,
  .nx-header--menu .nx-idioma__op { color: var(--nx-texto-claro); }
  /* el activo en reposo usa --nx-superficie-baja (lino). Sobre la cabecera
     oscura del menú, y con el color forzado a claro, ES/EN/RU activo era
     blanco sobre crema. Misma receta que .nx-header--cristal. */
  .nx-header--menu .nx-idioma__op--activo {
    background: rgba(244, 242, 236, 0.16);
    color: var(--nx-texto-claro);
  }
  .nx-header--menu .nx-header__logo--navy { opacity: 0; }
  .nx-header--menu .nx-header__logo--claro { opacity: 1; }
}

/* Sobre el hero, mientras el logotipo gira hacia el favicon (~0-160px de
   scroll): antes quedaba 100% transparente durante todo ese tramo y el header
   competía por contraste con lo que hubiera detrás en el hero. Ahora lleva un
   velo oscuro + blur (glassmorphism) durante la transición, y solo al
   terminar (.nx-header--solido, ~160px) pasa a fondo blanco sólido. Fallback
   sin backdrop-filter: se queda con el velo oscuro semitransparente, que ya
   es mejor que transparente puro. */
.nx-header--cristal {
  background: rgba(7, 7, 9, 0.32) !important;
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom-color: rgba(244, 242, 236, 0.14) !important;
  box-shadow: none !important;
}
.nx-header--cristal .nx-header__logo--navy { opacity: 0 !important; }
.nx-header--cristal .nx-header__logo--claro { opacity: 1; }
.nx-header--cristal .nx-nav__item,
.nx-header--cristal .nx-idioma__op,
.nx-header--cristal .nx-menu-boton { color: var(--nx-blanco); }
.nx-header--cristal .nx-nav__item:hover,
.nx-header--cristal .nx-nav__item:focus-visible,
.nx-header--cristal .nx-idioma__op:hover:not(.nx-idioma__op--activo),
.nx-header--cristal .nx-idioma__op:focus-visible:not(.nx-idioma__op--activo),
.nx-header--cristal .nx-menu-boton:hover,
.nx-header--cristal .nx-menu-boton:focus-visible {
  color: var(--nx-crema);
}
.nx-header--cristal .nx-nav__item:hover::after,
.nx-header--cristal .nx-nav__item:focus-visible::after,
.nx-header--cristal .nx-idioma__op:hover::after,
.nx-header--cristal .nx-idioma__op:focus-visible::after {
  background: var(--nx-crema);
}
.nx-header--solido {
  background: #fff;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: var(--nx-borde);
  box-shadow: 0 1px 24px rgba(7, 7, 7, 0.07);
}
.nx-header--cristal .nx-idioma__op--activo { background: rgba(244, 242, 236, 0.16); }
.nx-header--cristal .nx-wa {
  color: var(--nx-blanco);
  border-color: rgba(244, 242, 236, 0.55);
}
.nx-header--cristal .nx-wa:hover,
.nx-header--cristal .nx-wa:focus-visible {
  background: rgba(244, 242, 236, 0.12);
  color: var(--nx-blanco);
  border-color: var(--nx-blanco);
}
.nx-main:has(.nx-hero) .nx-hero {
  margin-block-start: calc(var(--nx-header-alto) * -1);
  min-height: min(100vh, 920px);
  padding-block-start: calc(var(--nx-alto-cabecera) + var(--nx-header-alto));
  padding-block-end: calc(var(--nx-e5) + 2.5rem);
}
.nx-hero__cifras {
  position: absolute;
  inset-inline: var(--nx-lado);
  inset-block-end: var(--nx-e3);
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em var(--nx-e4);
  margin: 0;
  font-size: var(--nx-texto-base);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-claro-suave);
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
}
.nx-hero__nota-scroll {
  margin-block: var(--nx-e2) 0;
  font-size: var(--nx-texto-base);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-claro-suave);
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
}
.nx-hero__nota-scroll strong {
  font-weight: var(--nx-peso-display);
  color: var(--nx-blanco);
}
.nx-anim--visible > .nx-hero__nota-scroll {
  animation: none;
}
.nx-hero__nota-scroll--on {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.nx-hero__cifras strong {
  font-weight: var(--nx-peso-display);
  color: var(--nx-blanco);
}
.nx-hero__cifras span::before {
  content: "·";
  margin-inline-end: 0.5em;
  color: var(--nx-coral);
}
/* Entran al primer gesto de scroll (desde 4px). Sin timeline, JS pone --on. */
.nx-hero__cifras--on {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

/* ---- glosario A-Z: la página completa ------------------------------------
   El bloque .nx-glosario de la home es otra cosa —una tirada de términos que
   sacan su definición al pasar por encima—. Esto es la página: 59 entradas
   que se leen y se enlazan desde los tooltips por su id.                    */
.nx-azeta {
  position: sticky;
  inset-block-start: var(--nx-header-alto);
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  gap: var(--nx-e1);
  padding-block: var(--nx-e2);
  background: var(--nx-fondo);
  border-block-end: var(--nx-filete) solid var(--nx-borde);
}
.nx-azeta__letra {
  min-width: 2em;
  padding: 4px var(--nx-e1);
  border-radius: var(--nx-radio-1);
  font-weight: var(--nx-peso-fuerte);
  text-align: center;
  transition: background var(--nx-t-rapido) var(--nx-curva),
              color      var(--nx-t-rapido) var(--nx-curva);
}

/* cada letra abre su tanda. scroll-margin para que el título no se meta
   debajo de la cabecera pegajosa al llegar desde un ancla.                 */
.nx-tanda { scroll-margin-block-start: calc(var(--nx-header-alto) * 2.4); }
.nx-tanda__letra {
  font-family: var(--nx-fuente-display);
  font-size: var(--nx-texto-xl);
  font-weight: var(--nx-peso-display);
  color: var(--nx-acento-texto);
  margin-block: var(--nx-e5) var(--nx-e2);
}

.nx-termino {
  padding-block: var(--nx-e3);
  border-block-start: var(--nx-filete) solid var(--nx-borde);
  scroll-margin-block-start: calc(var(--nx-header-alto) * 2.4);
}
.nx-termino__nombre {
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-fuerte);
  margin: 0 0 var(--nx-e1);
}
.nx-termino__def { margin: 0; max-width: 62ch; }
/* «por qué importa» es lo que separa un diccionario de algo que sirve: va
   marcado, no escondido en el mismo párrafo.                               */
.nx-termino__importa {
  margin: var(--nx-e1) 0 0;
  padding-inline-start: var(--nx-e2);
  border-inline-start: 2px solid var(--nx-acento);
  max-width: 62ch;
  font-size: var(--nx-texto-s);
  color: var(--nx-texto-suave);
}/* ═══════════════════════════════════════════════════════════════════════════
   ESTADOS DE LA FRANJA — fuera de @media (hover: hover) a propósito.
   Vivían dentro, y ahí un teléfono (hover: none) no veía NINGUNA: la franja
   abierta en móvil se quedaba sin rejilla de tres, sin miniaturas cuadradas y
   sin el nombre del grupo a todo lo ancho. Se abría, pero descuadrada.
   Las gobierna una clase que pone el JS, no el ratón.
   ═══════════════════════════════════════════════════════════════════════════ *//* ── franja: tres estados, no dos ─────────────────────────────────────────
   1 · CERRADA  → solo miniaturas en columna. Sin texto de ningún tipo.
   2 · ABIERTA  → aparece el nombre de cada grupo con sus tres miniaturas en
                  FILA. Todavía sin descripciones: es un índice, no una lista.
   3 · GRUPO DESPLEGADO → al pulsar un nombre, ese grupo pasa a columna con
                  título y fecha. Desde ahí la pulsación ya navega.
   Lo gobierna la clase --abierto, que pone 03-scripts.html.              */





.nx-franja--abierta .nx-franja__etiqueta{
  max-height: 2.5em;
  margin-bottom: var(--nx-e2);
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto){
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__etiqueta{
  grid-column: 1 / -1;
}
.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__entrada > div{
  max-height: 0; opacity: 0; overflow: hidden;
}
.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__miniatura{
  /* max-width para que las tres midan lo mismo y no se estiren */
  width: 100%; max-width: 68px; aspect-ratio: 1 / 1;
}/* En columna, cada entrada se separa de la anterior con margin-top: 2px. En
   la rejilla de tres eso empujaba 2px hacia abajo la 2.ª y la 3.ª y la fila
   salía escalonada —la primera foto parecía más grande—. Aquí separa el gap. */

.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__entrada{
  margin-top: 0;
  align-items: start;
}/* y las tres celdas arrancan arriba, no estiradas al alto de la más alta */

.nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto){
  align-items: start;
  justify-items: center;
}
.nx-franja__grupo--abierto .nx-franja__entrada > div{
  max-height: 200px;
  opacity: 1;
  transform: none;
}
.nx-franja__grupo--abierto .nx-franja__miniatura{ width: 44px; aspect-ratio: 1 / 1; }


/* ── CADA BLOQUE TIENE SU FILA, CON NOMBRE ────────────────────────────────
   Este era el fallo de fondo. Las filas se repartían por orden de aparición,
   así que en cuanto un bloque se ocultaba —«datos» está oculto con la franja
   cerrada— todos los de detrás se corrían una fila hacia arriba: el feed
   heredaba una fila `auto` y crecía hasta sus 700px, y el portal se quedaba
   con la fila elástica, que ya no tenía sitio y colapsaba a 0. Por eso el
   botón del portal se salía por abajo y parecía que «se tapaba».

   Con las filas nombradas cada bloque va SIEMPRE a la suya. Ocultar uno deja
   su carril vacío y no mueve a nadie.                                     */
.nx-franja__menu     { grid-row: menu; }
.nx-franja__accesos  { grid-row: accesos; }
.nx-franja__cabecera { grid-row: cabecera; }
.nx-franja__datos    { grid-row: datos; }
.nx-franja__cuerpo   { grid-row: feed; }
.nx-franja__portal   { grid-row: portal; }

/* ── nadie se sale de su bloque ───────────────────────────────────────────
   min-height: 0 en cada fila y overflow oculto en las que no scrollean. Es lo
   que impide que un bloque crezca por dentro y empuje al de al lado.      */
.nx-franja > * { min-width: 0; }
.nx-franja__menu,
.nx-franja__accesos,
.nx-franja__datos,
.nx-franja__cabecera,
.nx-franja__portal { min-height: 0; overflow: hidden; }

.nx-franja__cuerpo {
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

/* ── cerrada, la franja ENTERA es el botón de abrir ───────────────────────
   Antes solo abrían dos sitios: el ☰ de arriba en escritorio y la tira de
   iconos en móvil. Todo lo demás —las miniaturas, las cifras, el hueco de
   abajo— no hacía nada, y en el teléfono ese hueco muerto son 160px de los
   812 de pantalla. Ahora se abre pulsando en cualquier punto.

   Una sola excepción: el botón del portal, que navega. No gira, se lee
   siempre igual y es la única salida de la franja hacia fuera.

   El rodillo NO es excepción. Sus cinco rótulos están girando: pulsar uno
   en movimiento y acabar en una página que no era la que leías es la peor
   forma de perder a alguien. Cerrado enseña; abierto se aplana en una lista
   quieta y ahí sí llevan a su página. Lo hace el JS, no pointer-events, para
   que el enlace siga siendo enlace para el teclado y para Google.          */
.nx-franja:not(.nx-franja--abierta){ cursor: pointer; }
.nx-franja:not(.nx-franja--abierta) .nx-franja__acceso{ cursor: pointer; }

/* ── la X: SOLO en móvil ──────────────────────────────────────────────────
   En escritorio sobra. Ahí el botón «Actividad» está siempre a la vista en
   lo alto de la columna y hace las dos cosas: abre y cierra. Dos salidas
   para lo mismo, una de ellas flotando sobre el contenido, era ruido.
   En móvil sí se queda: al abrirse a pantalla completa, el botón de
   «Actividad» no se pinta y sin la X no habría forma de volver.
   La regla vive en la media query de ≤1100px, más abajo.                  */

/* ---- el artículo del blog -------------------------------------------------
   Lo que escribes en WordPress no lleva clases: son <p>, <h2>, <ul>… pelados.
   Por eso todo va colgando de .nx-articulo y no suelto sobre <main>: las 21
   páginas montadas a mano viven en ese mismo <main> con sus propias clases, y
   una regla suelta sobre `p` les cambiaría el interlineado a todas.         */
/* ── el mobiliario que Bricks añade solo en las entradas ──────────────────
   La plantilla por defecto de Bricks para `single post` añade cinco bloques
   que no son de NEXEVO y que salían debajo o encima del artículo:

     .bricks-post-header    foto de fondo + autor + «0 comentarios». Era la
                            SEGUNDA vez que salía la foto destacada.
     .brxe-post-author      «Hennadiy» con avatar y biografía vacía. NEXEVO
                            firma como empresa; no hay autores.
     .brxe-post-sharing     botones de Facebook, X y LinkedIn con los colores
                            de marca de cada red — tres corporativos ajenos
                            metidos en la paleta.
     .brxe-related-posts    «Entradas relacionadas», mezclando artículos en
                            español, ruso e inglés en la misma lista.
     .brxe-post-navigation  «Publicación anterior / siguiente», idem: desde
                            un artículo español te ofrecía el siguiente en
                            ruso.

   Los relacionados y la vuelta al índice los escribe blog.php en el idioma
   que toca. Estos cinco se apagan.                                        */
.bricks-post-header,
.brxe-post-title,
.brxe-post-author,
.brxe-post-sharing,
.brxe-related-posts,
.brxe-post-navigation { display: none !important; }

/* ── la rejilla del artículo ──────────────────────────────────────────────
   El artículo usa TODO el ancho de .nx-main (no 68ch / ~734px). A partir
   de 1100px: texto a la izquierda + barra 280px. Por debajo, una columna. */
.nx-articulo {
  width: 100%;
  max-width: none;
  margin-inline: 0;
  padding-inline: var(--nx-lado);
}

@media (min-width: 1100px) {
  .nx-articulo {
    display: grid;
    grid-template-columns: [texto] minmax(0, 1fr) [barra] 280px;
    column-gap: var(--nx-e6);
    align-items: start;
  }
  .nx-migas,
  .nx-articulo__cabecera,
  .nx-articulo__relacionados,
  .nx-articulo__vuelta { grid-column: 1 / -1; }
  .nx-articulo__principal { grid-column: texto; min-width: 0; }
  .nx-articulo__lateral {
    grid-column: barra;
    position: sticky;
    inset-block-start: var(--nx-e4);
  }
}

/* ── la barra lateral ─────────────────────────────────────────────────────
   Acompaña la lectura, no compite con ella: fecha pequeña arriba y titular
   debajo, sin foto ni extracto. Es lo que hace la referencia y por eso su
   barra se lee de un vistazo.                                             */
.nx-articulo__lateral { margin-block-start: var(--nx-e5); }
.nx-lateral__bloque + * { margin-block-start: var(--nx-e5); }
.nx-lateral__titulo {
  margin-block-end: var(--nx-e3);
  padding-block-end: var(--nx-e2);
  border-block-end: var(--nx-filete) solid var(--nx-borde);
  font-family: var(--nx-fuente);
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-texto-suave);
}
.nx-lateral__lista { margin: 0; padding: 0; list-style: none; }
.nx-lateral__entrada + .nx-lateral__entrada { margin-block-start: var(--nx-e3); }
.nx-lateral__fecha {
  display: block;
  margin-block-end: 2px;
  font-size: var(--nx-texto-xs);
  color: var(--nx-texto-suave);
}
.nx-lateral__entrada a {
  color: var(--nx-texto);
  font-size: var(--nx-texto-s);
  line-height: 1.35;
  text-decoration: none;
  border-block-end: var(--nx-filete) solid transparent;
  transition: color var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva);
}
.nx-lateral__entrada a:hover,
.nx-lateral__entrada a:focus-visible {
  color: var(--nx-acento-texto);
  border-color: var(--nx-acento);
}

/* ── la cabecera del artículo ─────────────────────────────────────────────
   Sin componente propio. Kicker, h1 y lead: exactamente los mismos que abren
   cualquier página del sitio, con su tipografía y su ritmo. Hubo aquí una
   banda oscura con la foto mordiéndola y se retiró — se leía como de otra
   web, que es justo lo que un artículo no debe parecer.                   */
/* Centrada y a todo el ancho, encima de las dos columnas. El aire de debajo
   es deliberado: en la referencia el titular respira antes de que empiece
   nada, y es lo que separa un artículo de una ficha de producto. */
.nx-articulo__cabecera {
  margin-block: var(--nx-e4) var(--nx-e6);
  text-align: start;
}
/* El titular baja al tamaño de un h2. A 92px, un título de artículo ocupaba
   media pantalla antes de la primera línea de texto: en una portada eso es
   una declaración, en un artículo es un obstáculo. Sigue siendo h1 para
   Google y para el lector de pantalla; solo cambia de cuerpo. */
.nx-articulo__cabecera h1 {
  max-width: none;
  margin-inline: 0;
  margin-block: 0;
  font-size: var(--nx-texto-xl);
  text-align: start;
}
/* la línea de fecha y minutos, debajo del titular y en versalitas */
.nx-articulo__meta {
  margin-block: var(--nx-e3) 0;
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-texto-suave);
}

/* ── migas de pan ─────────────────────────────────────────────────────────
   Inicio › Actualidad › Título. El artículo era la única página sin forma de
   saber dónde estás: se llega desde Google y no había manera de subir.    */
.nx-migas { margin-block-end: var(--nx-e3); }
.nx-migas ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--nx-e1);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--nx-texto-xs);
  color: var(--nx-texto-suave);
}
.nx-migas li { display: flex; align-items: center; gap: var(--nx-e1); }
/* el separador se dibuja, no se escribe: así no lo lee un lector de pantalla
   como si fuera parte del nombre de la página */
.nx-migas li + li::before { content: "›"; color: var(--nx-borde); }
.nx-migas a {
  color: var(--nx-texto-suave);
  text-decoration: none;
  border-block-end: var(--nx-filete) solid transparent;
  transition: color var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva);
}
.nx-migas a:hover { color: var(--nx-acento-texto); border-color: var(--nx-acento); }
/* el último escalón es la página en la que estás: no es enlace y no compite */
.nx-migas [aria-current="page"] {
  color: var(--nx-texto);
  /* si el titular es largo, se corta aquí y no rompe la línea entera */
  max-width: 32ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* la primera línea del cuerpo, algo mayor: marca dónde empieza el texto */
.nx-articulo__cuerpo > p:first-child { font-size: var(--nx-texto-m); line-height: 1.6; }

/* ── capitular ────────────────────────────────────────────────────────────
   La inicial del primer párrafo, en la display y a tres líneas. Es el gesto
   más viejo de la tipografía editorial y hace una cosa concreta: decir dónde
   empieza el texto. `initial-letter` lo resuelve solo en Safari y Chrome;
   donde no, el float de respaldo deja el mismo efecto con un cálculo a mano.

   Solo si el párrafo empieza por letra: con una cifra o unas comillas queda
   como un error de maquetación.                                           */
.nx-articulo__cuerpo > p:first-child::first-letter {
  float: left;
  margin-inline-end: 0.08em;
  padding-block-start: 0.06em;
  font-family: var(--nx-fuente-display);
  font-weight: var(--nx-peso-display);
  font-size: 3.2em;
  line-height: 0.78;
  color: var(--nx-acento-texto);
  -webkit-initial-letter: 3;
          initial-letter: 3;
}
@supports (initial-letter: 3) or (-webkit-initial-letter: 3) {
  .nx-articulo__cuerpo > p:first-child::first-letter {
    float: none;
    font-size: inherit;         /* lo dimensiona initial-letter */
    line-height: inherit;
    padding-block-start: 0;
    margin-inline-end: 0.12em;
  }
}

/* ── el filete coral antes de cada apartado ───────────────────────────────
   32px de regla coral sobre cada h2. Marca el corte entre secciones sin
   añadir una línea de texto, y es el mismo coral que separa las secciones
   del resto del sitio.                                                    */
.nx-articulo__cuerpo h2::before {
  content: "";
  display: block;
  width: 32px;
  margin-block-end: var(--nx-e2);
  border-block-start: 2px solid var(--nx-acento);
}

/* ── compartir ────────────────────────────────────────────────────────────
   Debajo del artículo hasta 1500px; a partir de ahí, columna izquierda
   pegada al scroll. Texto y no logotipos: los botones de Bricks venían con
   el azul de Facebook y el de LinkedIn metidos en una paleta de tres.     */
.nx-compartir {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nx-e1) var(--nx-e3);
  max-width: none;
  margin: var(--nx-e5) 0 0;
  padding-block-start: var(--nx-e3);
  border-block-start: var(--nx-filete) solid var(--nx-borde);
}
.nx-compartir__titulo {
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-texto-suave);
}
.nx-compartir__via {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--nx-texto-s);
  color: var(--nx-texto-suave);
  text-decoration: none;
  cursor: pointer;
  border-block-end: var(--nx-filete) solid transparent;
  transition: color var(--nx-t-rapido) var(--nx-curva),
              border-color var(--nx-t-rapido) var(--nx-curva);
}
.nx-compartir__via:hover,
.nx-compartir__via:focus-visible {
  color: var(--nx-acento-texto);
  border-color: var(--nx-acento);
}
/* al copiar, el propio botón dice que lo ha hecho: nada de globos flotantes */
.nx-compartir__copiar[data-nx-copiado] { color: var(--nx-acento-texto); }

/* `figure.` y no solo la clase: más abajo hay un `.nx-articulo figure` para
   las imágenes que se insertan dentro del texto, y con dos clases de igual
   peso ganaba aquel. */
.nx-articulo figure.nx-articulo__foto {
  margin: 0 0 var(--nx-e5);
  position: relative;
  overflow: hidden;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--nx-radio-1);   /* 8px, como las tarjetas — no 99px */
  background: var(--nx-superficie-baja);
}
/* La misma escuadra coral que llevan las fotos de las tarjetas en Actualidad
   (.nx-tarjeta__media::after). Es la única marca visual que comparten todas
   las imágenes del sitio, y era lo que faltaba para que la foto del artículo
   se leyera como parte del mismo sistema y no como una imagen suelta. */
.nx-articulo__foto::after {
  content: "";
  position: absolute;
  top: var(--nx-e2); left: var(--nx-e2);
  width: 24px; height: 24px;
  border-top: 2px solid var(--nx-coral);
  border-left: 2px solid var(--nx-coral);
  z-index: 1;
}
.nx-articulo__foto img,
.nx-articulo__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}

/* ── sumario ──────────────────────────────────────────────────────────────
   Solo aparece con tres o más apartados. Es un <details>: en móvil se pliega
   y se abre pulsando el rótulo; en escritorio se va a la columna derecha y
   se queda pegado al scroll mientras lees.                                */
.nx-articulo__sumario {
  max-width: 68ch;
  margin: var(--nx-e5) 0;
  padding: var(--nx-e3) var(--nx-e4);
  border-inline-start: 2px solid var(--nx-acento);
  background: var(--nx-superficie);
}
/* dentro de la barra lateral no necesita caja: ya está en su columna, y una
   caja dentro de otra columna se lee como un cajón perdido */
@media (min-width: 1100px) {
  .nx-articulo__lateral .nx-articulo__sumario {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
  }
  .nx-articulo__lateral .nx-articulo__sumario > summary {
    padding-block-end: var(--nx-e2);
    border-block-end: var(--nx-filete) solid var(--nx-borde);
  }
}
.nx-articulo__sumario > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nx-e2);
  cursor: pointer;
  list-style: none;                 /* fuera el triángulo del navegador */
  font-size: var(--nx-texto-xs);
  font-weight: var(--nx-peso-fuerte);
  letter-spacing: var(--nx-tracking-etiqueta);
  text-transform: uppercase;
  color: var(--nx-texto-suave);
}
.nx-articulo__sumario > summary::-webkit-details-marker { display: none; }
/* el signo propio: un + que se vuelve − al abrir, como en las FAQ */
.nx-articulo__sumario > summary::after {
  content: "+";
  font-size: var(--nx-texto-m);
  line-height: 1;
  color: var(--nx-acento);
  transition: transform var(--nx-t-rapido) var(--nx-curva);
}
.nx-articulo__sumario[open] > summary::after { content: "–"; }
.nx-articulo__sumario[open] > summary { margin-block-end: var(--nx-e2); }
.nx-articulo__sumario > summary:focus-visible {
  outline: 2px solid var(--nx-acento);
  outline-offset: 3px;
}
.nx-articulo__sumario ol {
  margin: 0;
  /* decimal explícito: el reset del sitio pone list-style:none en todas las
     listas, y sin número el sumario se lee como un menú suelto, no como el
     orden en que van los apartados. */
  list-style: decimal;
  padding-inline-start: var(--nx-e3);
  font-size: var(--nx-texto-s);
}
.nx-articulo__sumario li { margin-block-end: var(--nx-e1); }
.nx-articulo__sumario li::marker {
  color: var(--nx-acento);
  font-weight: var(--nx-peso-fuerte);
}
.nx-articulo__sumario a {
  color: var(--nx-texto);
  text-decoration: none;
  border-block-end: var(--nx-filete) solid transparent;
  transition: border-color var(--nx-t-rapido) var(--nx-curva),
              color var(--nx-t-rapido) var(--nx-curva);
}
.nx-articulo__sumario a:hover { color: var(--nx-acento-texto); border-color: var(--nx-acento); }

/* el ancla no debe dejar el encabezado pegado al borde de la pantalla */
.nx-articulo h2[id] { scroll-margin-block-start: var(--nx-e5); }

.nx-articulo__cuerpo { max-width: none; width: 100%; }

/* ── seguir leyendo ───────────────────────────────────────────────────── */
.nx-articulo__relacionados {
  margin-block-start: var(--nx-e6);
  padding-block-start: var(--nx-e5);
  border-block-start: var(--nx-filete) solid var(--nx-borde);
}
.nx-articulo__relacionados-titulo {
  margin-block-end: var(--nx-e4);
  font-size: var(--nx-texto-l);
}
.nx-articulo__vuelta {
  margin-block-start: var(--nx-e5);
  padding-block-start: var(--nx-e3);
  border-block-start: var(--nx-filete) solid var(--nx-borde);
}

/* ── el índice del blog ───────────────────────────────────────────────────
   El primero manda: foto grande a un lado y texto al otro. El resto, en
   rejilla de tres. Una lista donde todo pesa igual no dice por dónde
   empezar.                                                                */
.nx-blog__cabecera {
  margin-block-end: var(--nx-e4);
  text-align: start;
}
.nx-blog__cabecera .nx-titulo--medio {
  margin-block: 0 var(--nx-e2);
  font-size: clamp(1.5rem, 2.4vw, 2.5rem); /* 24 → 40px: el titular largo no puede ir a 56 */
}
.nx-blog__entradilla {
  margin: 0;
  max-width: none;
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-ligero);
  line-height: 1.5;
  color: var(--nx-texto-suave);
}
.nx-blog__cta { margin-block-start: var(--nx-e3); }
.nx-blog__pestanias {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--nx-e1);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  margin-block: 0 var(--nx-e4);
  padding-block-end: var(--nx-e1);
  border-block-end: var(--nx-filete) solid var(--nx-borde);
}
.nx-blog__pestania {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--nx-toque);
  padding-inline: var(--nx-e2);
  border-radius: var(--nx-radio-1);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto-suave);
  text-decoration: none;
  white-space: nowrap;
}
.nx-blog__pestania:hover { color: var(--nx-navy); }
.nx-blog__pestania:focus-visible {
  outline: 2px solid var(--nx-acento);
  outline-offset: 2px;
}
.nx-blog__pestania--activa {
  background: var(--nx-coral-oscuro);
  color: var(--nx-blanco);
}
.nx-blog__pestania--activa:hover { color: var(--nx-blanco); }
.nx-blog__seccion-desc {
  margin: 0 0 var(--nx-e4);
  max-width: none;
  font-size: var(--nx-texto-m);
  font-weight: var(--nx-peso-ligero);
  line-height: 1.5;
  color: var(--nx-texto-suave);
}
/* El bloque viejo de Bricks encima del listado (kicker + H1 Actualidad +
   lead) se apaga entero: esconder solo el texto dejaba la sección vacía
   como una franja. El copy nuevo lo pinta [nx_blog]. */
#brx-content:has(.nx-blog, .nx-blog__destacado, .nx-blog__rejilla) > h1:first-child,
#brx-content:has(.nx-blog, .nx-blog__destacado, .nx-blog__rejilla) > .nx-seccion:not(:has(.nx-blog)):not(:has(.nx-blog__destacado)):not(:has(.nx-blog__rejilla)):not(.nx-seccion--cta) {
  display: none !important;
}
body:has(.nx-blog) #brx-content h1:not(.nx-blog h1),
body:has(.nx-blog) #brx-content .nx-kicker:not(.nx-blog *),
body:has(.nx-blog) #brx-content .nx-lead:not(.nx-blog *):not(.nx-seccion--cta *),
body:has(.nx-blog) #brx-content .brxe-heading:not(:has(.nx-blog)):not(.nx-seccion--cta *),
body:has(.nx-blog) #brx-content .brxe-text:not(:has(.nx-blog)):not(.nx-seccion--cta *) {
  display: none !important;
}
/* El listado no va en una banda --alt: sin filete ni fondo distinto. */
#brx-content > .nx-seccion--alt:has(.nx-blog),
#brx-content > .nx-seccion--alt:has(.nx-blog__destacado) {
  background: transparent;
  border-block: 0;
}
.nx-blog__destacado { margin-block-end: var(--nx-e5); }
.nx-blog__destacado .nx-kicker { display: block; margin-block-end: var(--nx-e2); }

/* ── el destacado: la caja mide lo que mide la foto ───────────────────────
   La imagen sangra hasta los bordes de su columna y se estira al alto de la
   tarjeta; el texto se centra al lado. Así no queda ni aire muerto debajo de
   la foto ni una caja más alta que la imagen que la llena.                */
.nx-tarjeta--ancha {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  /* CUATRO filas declaradas, una por cada hijo de texto. Sin declararlas,
     `grid-row: 1 / -1` en la foto no abarcaba nada: con la rejilla implícita,
     la línea -1 es la misma que la 1, así que la foto se quedaba en la
     primera fila y el texto se colocaba en zigzag. Es el mismo fallo que
     tenía la franja con sus bloques. */
  grid-template-rows: auto auto 1fr auto;
  column-gap: var(--nx-e4);
  /* el padding se lo queda el lado del texto; la foto llega al borde */
  padding: 0 var(--nx-e4) 0 0;
  overflow: hidden;
}
.nx-tarjeta--ancha > :not(.nx-tarjeta__media) { grid-column: 2; }
.nx-tarjeta--ancha .nx-tarjeta__media {
  grid-column: 1;
  grid-row: 1 / 5;
  margin: 0;
  aspect-ratio: auto;               /* manda el alto de la caja, no el 16/9 */
  min-height: 300px;
}
.nx-tarjeta--ancha .nx-tarjeta__img { height: 100%; object-fit: cover; }

/* ── tarjeta ancha con SOLO titular y texto ────────────────────────────────
   Las cuatro filas de arriba están pensadas para la tarjeta de Actualidad,
   que trae cuatro hijos de texto (índice, titular, texto y pie). Cuando solo
   trae dos —titular y texto— las filas 3 y 4 se quedan vacías, y la fila 1fr
   del medio se come todo el alto sobrante: el texto queda pegado arriba y
   debajo aparece un hueco muerto de varios cientos de píxeles.
   Es lo que pasaba en el bloque 02 de /reactiva-tu-proyecto-parado/.
   Con dos hijos, las filas se ajustan al contenido y el bloque se centra al
   lado de la foto, que es lo que ya decía el comentario de arriba y no
   llegaba a ocurrir. El alto de la tarjeta pasa a mandarlo el texto (con el
   min-height de 300px de la foto como suelo).
   Mismo idioma que .nx-pilares:has(> :nth-child(4)). Sin :has() se queda el
   comportamiento de antes: airoso, no roto.                                */
.nx-tarjeta--ancha:has(> .nx-tarjeta__texto:last-child) {
  grid-template-rows: auto auto;
  align-content: center;
}
.nx-tarjeta--ancha:has(> .nx-tarjeta__texto:last-child) .nx-tarjeta__media {
  grid-row: 1 / -1;
}
/* un escalón por debajo del h2: el destacado manda en la página, pero no
   compite con el titular «Actualidad» que tiene encima */
.nx-tarjeta--ancha .nx-tarjeta__titulo { font-size: var(--nx-texto-l); }
.nx-tarjeta--ancha .nx-tarjeta__indice { margin-block-start: var(--nx-e4); }
.nx-tarjeta--ancha .nx-tarjeta__pie { margin-block-end: var(--nx-e4); }

@media (max-width: 860px) {
  .nx-tarjeta--ancha {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    padding: var(--nx-e3);
  }
  .nx-tarjeta--ancha > :not(.nx-tarjeta__media) { grid-column: 1; }
  .nx-tarjeta--ancha .nx-tarjeta__media {
    grid-column: 1;
    grid-row: auto;
    aspect-ratio: 16 / 9;
    min-height: 0;
    margin: calc(var(--nx-e3) * -1) calc(var(--nx-e3) * -1) var(--nx-e3);
  }
  .nx-tarjeta--ancha .nx-tarjeta__indice,
  .nx-tarjeta--ancha .nx-tarjeta__pie { margin-block: 0; }
}

/* ── toda la tarjeta es el enlace ─────────────────────────────────────────
   El ::after del enlace del titular se estira sobre la caja entera. Un solo
   enlace, un solo objetivo de 300px de alto en vez de las 4 palabras de
   «Leer». El texto se sigue pudiendo seleccionar y el foco del teclado cae
   donde debe: en el titular.                                              */
/* El clic lo reparte el JS (03-scripts.html): pulsar en cualquier punto de la
   tarjeta sigue el enlace del titular. Se probó antes con el truco del
   ::after estirado y NO cubría la caja —medido: 503×22 en vez de 1124×385—,
   porque el ancla es inline y su pseudo se quedaba con el bloque del h2.
   Con delegación no hay que adivinar bloques contenedores, y sin JS el
   titular sigue siendo un enlace normal. */
.nx-tarjeta { position: relative; }
.nx-tarjeta--enlazada { cursor: pointer; }
.nx-tarjeta__enlace { color: inherit; text-decoration: none; }
.nx-tarjeta:hover .nx-tarjeta__enlace,
.nx-tarjeta__enlace:focus-visible { color: var(--nx-acento-texto); }
.nx-tarjeta:focus-within { border-color: var(--nx-acento); }
/* «Leer →» ya no es enlace: es la señal de que la tarjeta lo es */
.nx-tarjeta__pie .nx-enlace { pointer-events: none; }

@media (max-width: 700px) {
  .nx-articulo__sumario { padding-inline: var(--nx-e3); }
  /* la ruta completa no cabe: se queda el escalón anterior y el actual, que
     es lo que sirve para subir un nivel. «Inicio» está en el logotipo. */
  .nx-migas li:first-child { display: none; }
  .nx-migas li:nth-child(2)::before { content: none; }
  .nx-migas [aria-current="page"] { max-width: 18ch; }
}

/* El titular del índice, al tamaño de un h2. En una página cuyo trabajo es
   listar artículos, un «Actualidad» de 92px se come la primera tarjeta.
   Sigue siendo el h1 de la página; solo cambia de cuerpo. */
.nx-titulo--medio { font-size: var(--nx-texto-xl); }

.nx-blog__rejilla {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--nx-e4);
}
@media (max-width: 1000px) { .nx-blog__rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .nx-blog__rejilla { grid-template-columns: 1fr; } }

.nx-articulo p { margin-block: 0 var(--nx-e3); }
.nx-articulo h2 { margin-block: var(--nx-e5) var(--nx-e2); font-size: var(--nx-texto-l); }
.nx-articulo h3 { margin-block: var(--nx-e4) var(--nx-e2); font-size: var(--nx-texto-m); }
.nx-articulo ul,
.nx-articulo ol { margin-block: 0 var(--nx-e3); padding-inline-start: var(--nx-e3); }
.nx-articulo li { margin-block-end: var(--nx-e1); font-weight: var(--nx-peso-ligero); }
.nx-articulo img { max-width: 100%; height: auto; }
.nx-articulo a { color: var(--nx-acento-texto); text-decoration: underline; text-underline-offset: 3px; }

/* la cita: el mismo filete coral que separa las secciones del sitio */
.nx-articulo blockquote {
  margin: var(--nx-e4) 0;
  padding-inline-start: var(--nx-e3);
  border-inline-start: 2px solid var(--nx-acento);
  font-family: var(--nx-fuente-script);
  font-style: normal;
  font-size: var(--nx-texto-m);
  color: var(--nx-acento-texto);
}
.nx-articulo figure { margin: var(--nx-e4) 0; }
.nx-articulo figcaption {
  margin-block-start: var(--nx-e1);
  font-size: var(--nx-texto-s);
  color: var(--nx-texto-suave);
}

/* paginación del índice */
.nx-paginas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nx-e3);
}
.nx-paginas__cuenta { font-size: var(--nx-texto-s); color: var(--nx-texto-suave); }

/* ---- aviso de marcador de posición ---------------------------------------- */
.nx-marcador {
  margin-top: var(--nx-e3);
  padding-left: var(--nx-e2);
  border-left: 2px solid var(--nx-acento);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-ligero);
  color: var(--nx-texto-suave);
}

/* =============================================================================
   8b · MOVIMIENTO
   Contrato: 2-diseno/brand/motion.json — energy 2, elasticity 1, restraint 4.
   Solo se animan safe_props: transform, opacity, clip-path.
   Un solo elemento en movimiento por región: las tarjetas hacen máscara, la
   galería escala. Nunca las dos cosas en el mismo sitio.
   Todo el bloque cuelga de prefers-reduced-motion: no-preference.
   ============================================================================= */

@media (prefers-reduced-motion: no-preference) {

  /* ---- reveal del h1 del hero ---------------------------------------------
     Sustituye a nx-subir SOLO en el titular: mismo sistema, duración lenta y
     descubierto con clip-path, como pide el contrato para los reveals de texto.
     Especificidad (0,2,0) para ganarle a `.nx-anim--visible > *`.            */
  .nx-anim--visible > .nx-hero__titulo {
    animation: nx-revelar var(--nx-t-lento) var(--nx-curva-entrada) forwards;
  }
  @keyframes nx-revelar {
    from { opacity: 0; transform: translateY(12px); clip-path: inset(100% 0 0 0); }
    to   { opacity: 1; transform: translateY(0);    clip-path: inset(0); }
  }

  /* ---- cabecera que encoge al bajar ---------------------------------------
     A los 160px de scroll la cabecera se queda en 56px y el logotipo se ha
     fundido en la marca-disco. Al volver arriba se deshace solo, porque va atada
     a la posición de scroll y no a un evento.

     EXCEPCIÓN DE MOVIMIENTO declarada: se anima `height`, que es propiedad de
     layout. Es la segunda excepción del proyecto —la primera es el acordeón—
     y se limita a este elemento: sin ella la cabecera no ocupa menos sitio,
     que es justo lo que se pide. La animación la conduce el compositor de
     scroll, no un listener por frame.                                       */
  @supports ((animation-timeline: scroll()) and (animation-range: 0px 160px)) {

    /* la barra encoge y, al despegarse de la página, se levanta con una
       sombra muy baja. box-shadow sí está en safe_props.                  */
    .nx-header {
      animation: nx-header-encoge auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 0px 160px;
    }
    @keyframes nx-header-encoge {
      to {
        height: var(--nx-header-min);
        box-shadow: 0 1px 24px rgba(7, 7, 7, 0.07);
      }
    }

    /* El relevo entre las dos marcas es LATERAL: el logotipo se retira hacia
       la izquierda y en su sitio se queda el disco. Los dos comparten origen
       izquierdo, así que la marca no salta de posición — el logotipo se
       recoge sobre sí mismo y deja ver lo que había debajo.

       Se cruzan entre los 90 y los 120px: el logotipo ya casi no está cuando
       el disco aparece, para que sea un relevo y no dos gestos seguidos.   */
    .nx-header__logo--navy {
      animation: nx-marca-fuera auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 0px 120px;
    }
    @keyframes nx-marca-fuera {
      from { opacity: 1; transform: translateX(0)    scale(1); }
      to   { opacity: 0; transform: translateX(-14%) scale(0.86); }
    }

    /* el disco no viaja: crece en el sitio que deja el logotipo */
    .nx-header__iso {
      animation: nx-marca-dentro auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 90px 160px;
    }
    @keyframes nx-marca-dentro {
      from { opacity: 0; transform: rotate(-360deg); }
      to   { opacity: 1; transform: rotate(0deg); }
    }

    /* en la home el wordmark blanco se retira a la vez que gira el disco;
       el fondo sólido no entra hasta el final de esa vuelta (160px). */
    .nx-header--cristal .nx-header__logo--claro {
      animation: nx-marca-fuera auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 90px 160px;
    }

    .nx-hero__cifras {
      animation: nx-cifras-entra auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 4px 48px;
    }
    .nx-hero__nota-scroll {
      animation: nx-cifras-entra auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 4px 48px;
    }
    .nx-anim--visible > .nx-hero__nota-scroll {
      animation: nx-cifras-entra auto linear both;
      animation-timeline: scroll(block root);
      animation-range: 4px 48px;
    }
    @keyframes nx-cifras-entra {
      from { opacity: 0; transform: translateY(10px); }
      to   { opacity: 1; transform: none; }
    }
  }

  /* ---- mapa: la costa se traza sola y los puntos caen detrás ---------------
     Es la técnica que pide ideas-pendientes §2 para la marca: stroke-dashoffset.
     Lo dispara el observador de .nx-anim que ya existe — cero JS nuevo.     */
  .nx-mapa__tierra path,
  .nx-mapa__islas path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    fill-opacity: 0;
  }
  .nx-anim--visible .nx-mapa__tierra path {
    animation: nx-trazar 1600ms var(--nx-curva-entrada) forwards,
               nx-rellenar var(--nx-t-lento) var(--nx-curva-entrada) 1100ms forwards;
  }
  .nx-anim--visible .nx-mapa__islas path {
    animation: nx-trazar 700ms var(--nx-curva-entrada) 900ms forwards,
               nx-rellenar var(--nx-t-base) var(--nx-curva-entrada) 1400ms forwards;
  }
  @keyframes nx-trazar   { to { stroke-dashoffset: 0; } }
  @keyframes nx-rellenar { to { fill-opacity: 1; } }

  /* los ocho puntos entran escalonados cuando el trazo ya ha llegado */
  .nx-mapa__punto { opacity: 0; }
  .nx-anim--visible .nx-mapa__punto {
    animation: nx-punto var(--nx-t-base) var(--nx-curva-entrada) forwards;
    animation-delay: calc(1500ms + var(--i) * var(--nx-escalonado));
  }
  @keyframes nx-punto {
    from { opacity: 0; transform: scale(0.2); }
    to   { opacity: 1; transform: scale(1); }
  }

  /* y el nombre se escribe detrás de su punto: un barrido de izquierda a
     derecha con clip-path, que es como se lee una palabra                 */
  .nx-mapa__nombre {
    opacity: 0;
    transform-box: fill-box;
    clip-path: inset(-30% 100% -30% -10%);
  }
  .nx-anim--visible .nx-mapa__nombre {
    animation: nx-escribir var(--nx-t-lento) var(--nx-curva-entrada) forwards;
    animation-delay: calc(1700ms + var(--i) * var(--nx-escalonado));
  }
  @keyframes nx-escribir {
    from { opacity: 1; clip-path: inset(-30% 100% -30% -10%); }
    to   { opacity: 1; clip-path: inset(-30% -10% -30% -10%); }
  }

  /* ---- parcela → obra: se levanta sola sobre el terreno --------------------
     Misma técnica y mismos keyframes que el mapa: nx-trazar sobre pathLength.
     El orden lo lleva --i en el propio marcado, como los puntos del mapa, así
     que añadir o quitar un trazo no toca este CSS. Diez fases a 260ms: 3,3s
     en total, que es lo que tarda alguien en leer el titular de al lado.
     Lo dispara el observador de .nx-anim que ya existe — cero JS nuevo.   */
  .nx-parcela__traza {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  .nx-anim--visible .nx-parcela__traza {
    animation: nx-trazar var(--nx-t-lento) var(--nx-curva-entrada) forwards;
    animation-delay: calc(var(--i) * var(--nx-escalonado) * 3);
  }

  /* ---- credo: We Find. We Build. We Deliver. -------------------------------
     El <h2> lleva la clase .nx-anim, así que el observador ya existente lo
     recoge y sus tres <span> heredan el escalonado estándar. Cero JS nuevo.
     Los span necesitan inline-block: transform no aplica a cajas inline.    */
  .nx-credo > span { display: inline-block; }

  /* ---- portado del panel: nexevo-animaciones.css --------------------------
     Tres piezas que ya existían en el portal y aquí no. Se traen tal cual
     (mismos keyframes, renombrados al prefijo nx-) para que web y portal se
     muevan igual. Lo demás de ese archivo es de portal —splash de carga,
     barras de progreso, toasts— y no pinta nada en una web pública.         */

  /* phWipe · el kicker se descubre de izquierda a derecha mientras el
     tracking se cierra. Es el único texto de la página con letter-spacing
     ancho, así que el gesto se lee sin competir con el h2 de al lado.

     Va al scroll y no al cargar: de los once kickers, diez están fuera de
     pantalla al abrir y con un `animation` suelto terminaban su gesto antes
     de que nadie los viera. El del hero se excluye porque su contenedor ya
     es .nx-anim y le corresponde el escalonado, no esto.                    */
  @supports ((animation-timeline: view()) and (animation-range: entry)) {
    :not(.nx-anim) > .nx-kicker {
      animation: nx-descubrir-kicker auto linear forwards;
      animation-timeline: view();
      /* `cover` y no `entry`: el kicker mide 19px de alto, así que su rango
         entry dura esos mismos 19px de scroll y el barrido pasaba entero en
         un parpadeo. Sobre cover, ese 14% son ~170px de recorrido.         */
      animation-range: cover 0% cover 14%;
    }
    @keyframes nx-descubrir-kicker {
      from { opacity: 0; clip-path: inset(0 100% 0 0); letter-spacing: 0.3em; }
      60%  { opacity: 1; }
      to   { opacity: 1; clip-path: inset(0 -6% 0 0);
             letter-spacing: var(--nx-tracking-etiqueta); }
    }
  }

  /* phSweep · una banda de luz cruza la sección oscura una sola vez cuando
     entra, igual que en el panel-hero del portal.
     Va en un ::after por encima, no en el color del texto: probé el brillo
     con background-clip: text sobre el credo y desaparecía, porque el
     recorte no alcanza a los <span> transformados del escalonado.          */
  @supports ((animation-timeline: view()) and (animation-range: entry)) {
    .nx-seccion--destacada { position: relative; overflow: hidden; }
    .nx-seccion--destacada::after {
      content: "";
      position: absolute;
      inset-block: -20%;
      inset-inline-start: 0;
      width: 28%;
      pointer-events: none;
      background: linear-gradient(100deg,
        rgba(244, 242, 236, 0) 0%, rgba(244, 242, 236, 0.07) 50%,
        rgba(244, 242, 236, 0) 100%);
      animation: nx-barrido auto linear both;
      animation-timeline: view();
      animation-range: entry;
    }
    /* el desplazamiento va en % del propio ancho de la banda (28% de la
       sección): -130% la deja fuera por la izquierda, 480% fuera por la
       derecha. Solo transform y opacity, como manda el contrato.           */
    @keyframes nx-barrido {
      from { transform: translateX(-130%); opacity: 0; }
      15%  { opacity: 1; }
      85%  { opacity: 1; }
      to   { transform: translateX(480%);  opacity: 0; }
    }
  }/* phHaloSoft · el pulso de la franja emite un anillo además de latir. Con
     la franja cerrada el punto mide 7px y el anillo es lo que se ve de reojo. */

  
  .nx-franja__pulso{ animation: nx-pulso 2s var(--nx-curva) infinite,
                                 nx-halo 2s var(--nx-curva) infinite; }
  @keyframes nx-halo {
    0%   { box-shadow: 0 0 0 0  rgba(226, 103, 74, 0.5); }
    60%  { box-shadow: 0 0 0 12px rgba(226, 103, 74, 0); }
    100% { box-shadow: 0 0 0 0  rgba(226, 103, 74, 0); }
  }

  @supports ((animation-timeline: view()) and (animation-range: entry)) {

    /* ---- parallax del hero: la villa casi quieta -------------------------
       Va sobre scroll(root) y no sobre view(): el hero ya está en pantalla
       al cargar, así que un view() empezaría por la mitad de su recorrido y
       la foto daría un salto en el primer scroll. El velo NO se anima.

       VELOCIDAD 0.3 — la foto sube un 30% de lo que sube la página. Como la
       capa vive dentro del hero, que ya sube el 100%, hay que bajarla el 70%
       restante: 0.7 × 100vh = 70vh de recorrido.

       Arranca en 0: la foto se retrasa desde el primer píxel de scroll.

       Quien tapa el borde superior es el HEADER, no un margen en la capa, y
       sale justo: ese borde cae en 112 − 0.3·scroll y el header sticky va de
       112 a 56, así que siempre llega antes. Verificado píxel a píxel de 0 a
       1100 en 1710×929 y en 390×844 — cero franja destapada, arriba y abajo.
       Por eso la capa mide exactamente lo que el hero y el encuadre no
       cambia. Ojo si algún día se sube la velocidad por encima de 0.5: deja
       de cumplirse y habría que agrandar la capa, con el reencuadre que eso
       implica, porque aquí `cover` se rige por el alto.                    */
    .nx-hero__fondo {
      animation: nx-parallax-hero auto linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 100vh;
    }
    @keyframes nx-parallax-hero {
      from { transform: translateY(0); }
      to   { transform: translateY(70vh); }
    }

    /* ---- phBlur · los títulos de sección entran desenfocados -------------
       Portado del panel: es la entrada más cálida del repertorio, sube poco
       y desenfoca en vez de deslizar. Seis de los siete h2 no tenían ninguna
       entrada y aparecían de golpe.
       Se excluye el credo: vive dentro de .nx-anim y ya tiene su escalonado.
       El blur solo corre mientras el h2 entra, nunca hay más de dos a la vez. */
    :not(.nx-anim) > h2 {
      animation: nx-entrar-titulo auto linear forwards;
      animation-timeline: view();
      animation-range: cover 0% cover 26%;
    }
    @keyframes nx-entrar-titulo {
      from { opacity: 0; transform: translateY(12px); filter: blur(6px); }
      to   { opacity: 1; transform: none;             filter: blur(0); }
    }
    /* ---- máscara: la foto de tarjeta se descubre de abajo arriba ---------- */
    .nx-tarjeta__media {
      animation: nx-descubrir auto linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 85%;
    }
    @keyframes nx-descubrir {
      from { clip-path: inset(100% 0 0 0 round var(--nx-radio-1) var(--nx-radio-1) 0 0); }
      to   { clip-path: inset(0 round var(--nx-radio-1) var(--nx-radio-1) 0 0); }
    }
  }
}


/* =============================================================================
   9 · ESTADOS — :hover  :focus-visible
   Una interacción = una duración = una curva. Hover siempre --nx-t-rapido.
   ============================================================================= */

/* ---- foco visible: obligatorio en todo lo interactivo --------------------- */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--nx-acento-texto);
  outline-offset: 3px;
  border-radius: var(--nx-radio-1);
}
.nx-seccion--destacada a:focus-visible,
.nx-seccion--destacada button:focus-visible,
.nx-footer a:focus-visible {
  outline-color: var(--nx-coral);
}

/* ---- botones -------------------------------------------------------------- */
.nx-boton--primario:hover   { background: var(--nx-rojo); color: var(--nx-blanco); }
.nx-boton--secundario:hover { background: var(--nx-navy); color: var(--nx-texto-claro); }
/* sobre oscuro el hover se invierte a crema, igual que en el hero */
.nx-seccion--destacada .nx-boton--secundario:hover,
.nx-footer .nx-boton--secundario:hover {
  background: var(--nx-texto-claro);
  color: var(--nx-negro);
}
.nx-boton--terciario:hover { color: var(--nx-acento-texto); }

/* botones dentro del CTA coral: especificidad (0,3,0) para ganar a las de arriba */
.nx-seccion--cta .nx-boton--primario:hover   { background: var(--nx-crema); color: var(--nx-coral-oscuro); }
.nx-seccion--cta .nx-boton--secundario:hover { background: var(--nx-blanco); color: var(--nx-coral-oscuro); }
.nx-seccion--cta .nx-enlace:hover,
.nx-seccion--cta .nx-enlace:hover .nx-enlace__flecha { color: var(--nx-crema); }
.nx-seccion--cta a:focus-visible             { outline-color: var(--nx-blanco); }

.nx-boton:hover .nx-boton__texto  { transform: translateX(0); }
.nx-boton:hover .nx-boton__flecha { opacity: 1; transform: translateX(0); }
.nx-boton:focus-visible .nx-boton__texto  { transform: translateX(0); }
.nx-boton:focus-visible .nx-boton__flecha { opacity: 1; transform: translateX(0); }


/* ---- WhatsApp ------------------------------------------------------------- */
.nx-wa:hover,
.nx-wa:focus-visible {
  background: rgba(181, 64, 42, 0.08);
  border-color: var(--nx-coral-oscuro);
  color: var(--nx-coral-oscuro);
}
.nx-wa:focus-visible { outline: 2px solid var(--nx-negro); outline-offset: 3px; }



/* ---- navegación de la cabecera --------------------------------------------- */
.nx-nav__item:hover,
.nx-nav__item:focus-visible { color: var(--nx-acento-texto); }
.nx-nav__item:hover::after,
.nx-nav__item:focus-visible::after { transform: scaleX(1); }

/* ---- selector de idioma --------------------------------------------------- */
/* El activo no se subraya: ya lleva su fondo, y dos marcas para lo mismo es
   ruido. El que tiene el foco sí, para que se vea con el teclado.           */
.nx-idioma__op:hover:not(.nx-idioma__op--activo),
.nx-idioma__op:focus-visible:not(.nx-idioma__op--activo) { color: var(--nx-acento-texto); }
.nx-idioma__op:hover::after,
.nx-idioma__op:focus-visible::after { transform: scaleX(1); }
.nx-idioma__op--activo::after { display: none; }


/* ---- glosario A-Z --------------------------------------------------------- */
.nx-azeta__letra:hover,
.nx-azeta__letra:focus-visible { background: var(--nx-acento); color: var(--nx-blanco); }
.nx-termino:target .nx-termino__nombre { color: var(--nx-acento-texto); }

/* ---- enlaces -------------------------------------------------------------- */
/* color y flecha en reposo, y la animación de hover, ahora viven junto a la
   definición base de .nx-enlace (más arriba) — esto solo cubre los
   contextos oscuros, que necesitan un color de hover distinto al de reposo. */
.nx-seccion--destacada .nx-enlace:hover,
.nx-seccion--glosario .nx-enlace:hover { color: var(--nx-coral); }

.nx-footer__enlace:hover { color: var(--nx-coral); }
.nx-contacto__via:hover { color: var(--nx-coral); border-bottom-color: var(--nx-coral); }

/* ---- superficies ---------------------------------------------------------- */

.nx-faq__pregunta:hover { color: var(--nx-acento-texto); }

/* galería: la pieza señalada se marca con el filete coral y saca su detalle */
.nx-galeria__pieza:hover,
.nx-galeria__pieza:focus-within { border-color: var(--nx-acento); }
.nx-galeria__pieza:hover .nx-galeria__meta,
.nx-galeria__pieza:focus-within .nx-galeria__meta,
.nx-galeria__pieza:hover .nx-galeria__mas,
.nx-galeria__pieza:focus-within .nx-galeria__mas { opacity: 1; }

/* glosario: el término se tiñe y saca su definición. Con :focus-within
   funciona igual con teclado, sin JS.                                      */
.nx-glosario__termino:hover,
.nx-glosario__termino:focus-visible { color: var(--nx-acento-texto); }
.nx-glosario__item:hover      .nx-glosario__def,
.nx-glosario__item:focus-within .nx-glosario__def {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* un solo comportamiento de hover para TODAS las tarjetas del sitio.
   El borde de la carpeta se marca igual que la foto: coral + filete extra
   (box-shadow, para no desplazar el layout al pasar de 1px a 2px).         */
.nx-tarjeta:hover {
  transform: translateY(-3px);
  border-color: var(--nx-acento);
  box-shadow: inset 0 0 0 1px var(--nx-acento);
}
.nx-tarjeta:hover .nx-tarjeta__img { transform: scale(1.04); }
.nx-tarjeta--plana:hover {
  transform: none;
  border-color: transparent;
  box-shadow: none;
}

.nx-campo__input:focus-visible {
  outline: none;
  border-color: var(--nx-acento-texto);
  /* el borde de 1px solo era poco perceptible para baja visión — auditoría
     de accesibilidad 2026-08-31. */
  box-shadow: 0 0 0 2px var(--nx-acento-texto);
}

/* El botón flotante de la mascota (56px + 22px de margen, ver asistente.css)
   se solapaba con la última línea de párrafos largos en móvil — crítica de
   diseño, 2026-08-31. Se reserva ese hueco al final del contenido para que
   nunca quede debajo del botón. Mismo breakpoint que asistente.css usa para
   pasar la mascota a formato flotante compacto. */
@media (max-width: 560px) {
  #nx-contenido { padding-block-end: 96px; }
  /* Excepción (crítica de diseño móvil, 2026-09-01): cuando el último bloque
     de la página es el CTA coral, ese hueco de 96px se veía como una franja
     vacía entre el CTA y el pie — el CTA es un banner de color, no texto que
     la mascota pueda tapar, así que no necesita el margen de seguridad. */
  #nx-contenido:has(> .nx-seccion--cta:last-child) { padding-block-end: 0; }
}

/* ── aviso de cookies ──────────────────────────────────────────────────
   No existía ningún gestor de consentimiento (auditoría de accesibilidad y
   crítica de diseño, 2026-08-31), pese a que el footer siempre enlazó a
   /cookies/. Barra inferior, construida por JS (03-scripts.html). Superficie
   clara (corrección 2026-08-31: el fondo negro original daba poca
   visibilidad, y el botón secundario —navy sobre negro— quedaba casi
   invisible; en blanco ambos botones ya cumplen AA con sus colores por
   defecto, sin overrides).

   Rehecho 2026-09-01: en móvil ocupaba ~50% de la pantalla y solo daba
   aceptar/rechazar. Ahora tiene dos vistas — resumen (aceptar todas /
   rechazar todas / elegir cookies) y panel de categorías — y en móvil se
   queda por debajo de ~33vh: texto compacto, un enlace de texto para
   «Elegir cookies» en vez de un tercer botón, y los dos botones principales
   en la misma fila. */
.nx-cookies {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 90;
  max-height: 40vh;
  overflow-y: auto;
  padding-block-end: env(safe-area-inset-bottom);
  background: var(--nx-superficie, #FFFFFF);
  color: var(--nx-texto, #3A4450);
  border-block-start: var(--nx-filete) solid var(--nx-borde);
  box-shadow: 0 -12px 30px rgba(7, 7, 7, .14);
}
.nx-cookies[hidden] { display: none; }
.nx-cookies__vista {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--nx-e3);
  padding: var(--nx-e3) var(--nx-e4);
}
.nx-cookies__vista[hidden] { display: none; }
.nx-cookies__texto {
  flex: 1 1 320px;
  margin: 0;
  font-size: var(--nx-texto-s);
  line-height: 1.5;
  color: var(--nx-texto-suave);
}
.nx-cookies__texto .nx-enlace { color: var(--nx-acento-texto); text-decoration: underline; }
.nx-cookies__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nx-e3);
  flex: 0 0 auto;
}
.nx-cookies__elegir {
  background: none;
  border: none;
  padding: 0;
  min-height: var(--nx-toque);
  font-size: var(--nx-texto-s);
  font-weight: var(--nx-peso-medio);
  color: var(--nx-acento-texto);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.nx-cookies__botones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nx-e2);
  flex: 0 0 auto;
}
/* ---- panel de categorías -------------------------------------------------- */
.nx-cookies__vista--panel { flex-direction: column; align-items: stretch; }
.nx-cookies__categorias {
  display: flex;
  flex-direction: column;
  gap: var(--nx-e2);
}
.nx-cookies__fila {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-e2);
  font-size: var(--nx-texto-s);
  line-height: 1.4;
}
.nx-cookies__fila input[type="checkbox"] {
  flex: none;
  inline-size: 24px;
  block-size: 24px;
  margin: 0;
}
.nx-cookies__fila strong { color: var(--nx-texto); }
.nx-cookies__fila span { color: var(--nx-texto-suave); }
/* mientras se decide, la mascota se aparta: dos elementos flotantes
   compitiendo por el mismo rincón de pantalla es peor que ninguno. Mismo
   patrón que ya usa la franja abierta a pantalla completa. */
body:has(#nx-cookies:not([hidden])) .nx-asis {
  visibility: hidden;
  pointer-events: none;
}
@media (max-width: 560px) {
  .nx-cookies { max-height: 34vh; }
  .nx-cookies__vista {
    flex-direction: column;
    align-items: stretch;
    gap: var(--nx-e1);
    padding: var(--nx-e2) var(--nx-e3);
  }
  /* el texto legal puede ser más largo que el hueco disponible: se deja
     scrollear SOLO a él, para que «Elegir cookies» y los botones queden
     siempre visibles debajo y no haga falta bajar para decidir. */
  .nx-cookies__texto {
    font-size: var(--nx-texto-xs);
    line-height: 1.35;
    max-height: 9vh;
    overflow-y: auto;
  }
  .nx-cookies__acciones { align-items: stretch; gap: var(--nx-e1); flex: none; }
  .nx-cookies__elegir { align-self: center; min-height: auto; padding-block: 2px; }
  .nx-cookies__botones { justify-content: stretch; }
  .nx-cookies__botones .nx-boton {
    flex: 1 1 0;
    justify-content: center;
    min-height: 40px;
    padding-inline: var(--nx-e2);
    font-size: var(--nx-texto-xs);
  }
  .nx-cookies__categorias { max-height: 19vh; overflow-y: auto; }
  .nx-cookies__fila { font-size: var(--nx-texto-xs); }
}
.nx-franja__boton:hover{ color: var(--nx-acento-texto); }

/* =============================================================================
   10 · MEDIA QUERIES
   ============================================================================= */

/* pantallas grandes: más aire vertical */
@media (min-width: 1600px) {
  :root {
    --nx-alto-seccion:   112px;
    --nx-alto-destacada: 160px;
    --nx-lado:            72px;
  }
}

/* portátil pequeño: la franja se estrecha */
@media (max-width: 1400px) {
  :root { --nx-lado: 40px; }
  .nx-hero { gap: var(--nx-e5); }
}

/* tablet: la franja desaparece del lateral y pasa a tira inferior */
@media (max-width: 1100px) {
  /* El globo del glosario mide 280px fijos y cuelga del término. Por encima de
     1100px caben cuatro términos por línea y el truco del :nth-child(4n) basta;
     por debajo, un término que empiece a media línea manda el globo fuera de la
     pantalla y TODA la página gana scroll lateral —aunque el globo esté oculto,
     porque visibility:hidden sigue ocupando sitio—. Medido: a 873px se salía
     hasta x=1029, y a 375px hasta x=560.
     Aquí se ancla al bloque entero: siempre del ancho de la columna.         */
  /* En móvil el nowrap de escritorio no cabe: 5 términos por fila
     se apilan uno a uno y parece una lista. Se justifica como texto
     para que 2–3 compartan línea, como el mock de líneas llenas. */
  /* Doce términos extra solo rellenan huecos de escritorio. En móvil el
     bloque ya está justificado y esos doce alargarían la lista. */
  .nx-glosario__fila--extra,
  .nx-glosario__item--extra { display: none; }

  .nx-glosario {
    position: relative;
    gap: 12px;
  }
  .nx-glosario__fila {
    display: block;
    text-align: justify;
    line-height: 1.5;
  }
  .nx-glosario__item {
    display: inline;
    position: static;
    margin-inline-end: 0.55em;
    font-size: clamp(0.8125rem, 3.3vw, 1.25rem);
  }
  /* nowrap + line-height 1.15 dejaba botones de 19px de alto. El padding
     sube el objetivo táctil sin romper el justificado de la fila. */
  .nx-glosario__termino {
    white-space: normal;
    padding-block: 0.35em;
  }
  /* La cursiva sigue a 1.25em del ítem; no pisa .nx-glosario__termino. */
  .nx-glosario__def,
  .nx-glosario__fila .nx-glosario__item:last-child .nx-glosario__def {
    inset-inline: 0;
    width: auto;
    max-width: none;
  }

  :root {
    --nx-lado: 32px; --nx-texto-xxl: 2.25rem; --nx-texto-xl: 1.75rem;
    /* aquí la franja ya no ocupa columna: es una tira de 48px sobre la que
       el contenido lleva padding. La marca empieza después de esa tira. */
    --nx-marca-x: calc(var(--nx-franja-movil) + var(--nx-lado));
  }

  /* en pantalla estrecha el logotipo se dimensiona por ANCHO, no por alto:
     con height fija, max-width le recortaba la caja y el logo quedaba
     encajonado en un hueco el doble de alto de lo que necesita. La intro
     copia la misma regla para que el aterrizaje siga cuadrando.          */
  .nx-header__logo,
  .nx-intro__logo {
    height: auto;
    width: min(46vw, 200px);
    max-height: 70%;
  }

  /* El logotipo y el selector de idioma se quedaban a 2px a 375px: el logo
     pedía 164px y el aire disponible eran 285 menos los 119 de ES·EN·RU.
     Se encoge el logo en la cabecera —la intro no, ahí manda solo— y se
     reserva un hueco que no se puede comer.                                */
  .nx-header__logo { width: min(34vw, 148px); }
  .nx-header { gap: var(--nx-e3); }
  .nx-header__marca { min-width: 0; }
  .nx-header__fin { flex: none; }

  .nx-shell { grid-template-columns: 1fr; }
  /* el hueco de la tira fija: sin esto la tira se come el borde del contenido */
  .nx-main  { grid-column: 1; padding-inline-start: var(--nx-franja-movil); }/* La franja NO baja al pie: sigue lateral, estrechada a tira de iconos.

     Sobre el alto — las dos versiones anteriores fallaban por lo mismo:
       · 100dvh dejaba hueco crema en iPhone cuando la barra de URL se anima.
       · 120vh lo tapaba, pero medía 974px en una pantalla de 812: 162px de
         tira caían fuera para siempre y el rodillo, que se centra en su 62%,
         quedaba descolocado. Eso es lo de «no se puede subir, está fijo».

     No hace falta ninguna de las dos. El elemento ya es `position: fixed` con
     `top: 0` y `bottom: 0`: eso lo clava a los dos bordes del viewport y el
     navegador recalcula el alto solo cada vez que la barra aparece o se va.
     Ni hueco ni sobrante. La regla es no darle `height` y dejarle los bordes. */

  /* BUG REAL (crítica de diseño móvil, 2026-09-01 — el parche de -1px de
     abajo NO lo arregló, seguía viéndose en pruebas reales): en la primera
     pintura, antes de que el navegador termine de calcular y pintar el
     elemento `fixed` de la tira, el `<body>` de fondo (crema) puede asomar
     un instante por la esquina inferior izquierda — un hueco de timing de
     pintura, no de redondeo de subpíxel. El `body::before` de abajo llega
     TARDE porque también depende de layout; el fondo del propio `<body>`
     no: es lo primero que el navegador tiene para pintar, antes de calcular
     ningún elemento fijo. Un degradado en el propio body dedica los
     primeros `--nx-franja-movil` px a oscuro desde el fotograma cero, así
     que no hay una esquina crema que mostrar aunque el resto tarde. */
  body {
    background: linear-gradient(
      to right,
      var(--nx-superficie-oscura) 0,
      var(--nx-superficie-oscura) var(--nx-franja-movil),
      var(--nx-fondo) var(--nx-franja-movil)
    );
  }
  .nx-franja{
    grid-column: 1;
    grid-row: auto;
    position: fixed;
    /* top/bottom en vez de inset-block: -1px en el borde inferior absorbe el
       redondeo de subpíxel que dejaba una línea/esquina crema visible en la
       primera pintura (antes de cualquier reflow) en algunos móviles —
       desaparecía solo al abrir y cerrar la franja, que fuerza un repintado. */
    top: 0;
    bottom: -1px;
    inset-inline-start: 0;
    inset-inline-end: auto;
    width: var(--nx-franja-movil);
    grid-template-rows: 1fr;
    border-right: var(--nx-filete) solid var(--nx-borde);
    background: var(--nx-superficie-oscura);
    overflow: hidden;                 /* cerrado: corta el rodillo */
    z-index: 60;
  }
  /* el velo que hay detrás de la tira: mismo criterio, bordes en vez de alto.
     Mismo margen de -1px abajo que .nx-franja, por la misma razón. */
  body::before {
    content: "";
    position: fixed;
    top: 0;
    bottom: -1px;
    left: 0;
    width: var(--nx-franja-movil);
    background: var(--nx-superficie-oscura);
    z-index: 44;
    pointer-events: none;
  }/* ── colapsada: solo la tira de iconos ────────────────────────────────── */

  
  .nx-franja__menu, .nx-franja__cabecera, .nx-franja__cuerpo, .nx-franja__portal{ display: none; }

  .nx-franja__resumen{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--nx-e2);
    padding-block: var(--nx-e2);
    /* transparente, NO blanco: la franja ya es negra y todo lo que va dentro
       está pintado para fondo oscuro. Con el resumen en blanco, el texto del
       rodillo quedaba crema sobre blanco — 1,12:1, invisible. */
    background: transparent;
  }/* la etiqueta gira: es lo único que cabe de canto en 48px.
     El rotate(180deg) la hace leer de ABAJO ARRIBA, en la misma dirección
     que el rodillo. Sin él, vertical-rl lee de arriba abajo y las dos
     columnas de texto de la tira iban en sentidos opuestos.              */
  
  .nx-franja__resumen .nx-franja__titulo{
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    line-height: 1;
  }/* ── el rodillo, de canto ───────────────────────────────────────────────
     En 48px de ancho el texto horizontal se partía en trozos ilegibles
     («прое», «Док», «и раз»). En vez de rehacer la mecánica, se GIRA el
     rodillo entero 90°: sigue siendo el mismo cilindro con las mismas siete
     caras, solo que tumbado. El texto se lee de abajo arriba y las preguntas
     ruedan a lo largo de la tira.

     --alto pasa de 46 a 21px porque, girado, ese alto es el ANCHO que ocupa
     en la tira: 21 × 2 = 42px, que caben en los 48 con aire.              */

  
  .nx-franja__accesos{
    --alto: 21px;
    position: absolute;
    /* su banda es la mitad de abajo: arriba van la etiqueta y las miniaturas */
    inset-block-start: 62%;
    inset-inline-start: 50%;
    width: 300px;                     /* al girar, esto es su ALTO */
    height: calc(var(--alto) * 2);    /* al girar, esto es su ANCHO: 42px */
    padding-inline: 0;
    border-bottom: 0;
    /* translate lleva su CENTRO al punto de anclaje; rotate gira sobre ese
       mismo centro. Separados —no en un solo transform— para que el
       porcentaje del translate no se vea afectado por el giro. */
    translate: -50% -50%;
    transform: rotate(-90deg);
    transform-origin: center;
    /* Máscara MÁS DURA que en escritorio, y es la razón de que el rodillo se
       viera ilegible en el teléfono. El cilindro enseña siempre tres caras:
       la de frente y dos de canto, a ±72°. En escritorio la banda mide 92px
       y esas dos se leen como el lomo del rodillo. Aquí mide 42: las de
       canto caían a 17% y 83% de la banda, donde la máscara suave todavía
       dejaba pasar un tercio, y encima el texto va en mayúsculas de 12px.
       El resultado eran dos rótulos superpuestos —«TENGO UN SUELO O ACTIVO»
       encima de «OPORTUNIDAD»— que no se leían ni juntos ni por separado.
       Con este corte solo se ve la cara de frente.                         */
    -webkit-mask-image: linear-gradient(to bottom, transparent 22%, #000 32%, #000 68%, transparent 78%);
            mask-image: linear-gradient(to bottom, transparent 22%, #000 32%, #000 68%, transparent 78%);
  }/* las miniaturas se quedan arriba y no se meten en la banda del rodillo */
  
  .nx-franja__resumen{ max-height: 42%; overflow: hidden; }
  .nx-franja__acceso{
    justify-content: center;
    font-size: var(--nx-texto-xs);
    letter-spacing: var(--nx-tracking-etiqueta);
    text-transform: uppercase;
  }/* la flecha no aporta nada de canto y roba ancho al texto */
  
  .nx-franja__acceso .nx-enlace__flecha{ display: none; }/* la pila de iconos se centra en el alto disponible */
  
  .nx-franja__resumen .nx-franja__tiras{ margin-block: auto; }/* ── abierta: pantalla completa ───────────────────────────────────────── */

  
  .nx-franja--abierta{
    width: 100%;
    inset-inline: 0;
    height: 100%;
    height: 100dvh;
    min-height: 100dvh;
    grid-template-rows:
      [menu]     auto
      [accesos]  auto
      [cabecera] auto
      [datos]    auto
      [feed]     minmax(0, 1fr)
      [portal]   auto;
    border-right: 0;
    overflow-x: hidden;
    overflow-y: auto;                 /* artículos/proyectos deben poder moverse */
    -webkit-overflow-scrolling: touch;
  }
  .nx-franja--abierta .nx-franja__resumen{ display: none; }/* al abrir: pila en origen (no a medias del salto) */
  
  .nx-franja--abierta .nx-franja__pila{
    animation: none;
    transform: none;
  }/* En móvil el paso intermedio (solo miniaturas en fila) escondía títulos
     y fechas: el usuario abría el panel y “desaparecían” los textos. Aquí
     se muestran ya al desplegar; el acordeón de grupos queda para escritorio. */

  
  .nx-franja--abierta .nx-franja__grupo, .nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto){
    display: block;
    justify-items: stretch;
  }
  .nx-franja--abierta .nx-franja__etiqueta, .nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__etiqueta{
    grid-column: auto;
    max-height: 2.5em;
    margin-bottom: var(--nx-e2);
    opacity: 1;
    pointer-events: auto;
  }
  .nx-franja--abierta .nx-franja__entrada > div, .nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__entrada > div{
    max-height: 200px;
    opacity: 1;
    transform: none;
    overflow: visible;
  }
  .nx-franja--abierta .nx-franja__miniatura, .nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__miniatura{
    width: 44px;
    max-width: 44px;
    aspect-ratio: 1 / 1;
  }
  .nx-franja--abierta .nx-franja__entrada, .nx-franja--abierta .nx-franja__grupo:not(.nx-franja__grupo--abierto) .nx-franja__entrada{
    margin-top: 0;
    align-items: flex-start;
  }
  .nx-franja--abierta .nx-franja__entrada + .nx-franja__entrada{
    margin-top: var(--nx-e2);
  }/* Los siete accesos: en la tira cerrada son un cilindro girado -90° metido
     en una banda de 42px. Con la franja a pantalla completa esa banda sigue
     ahí, girada y absoluta, así que los siete enlaces no se veían. Abierta se
     deshace todo el montaje y vuelven a ser una lista normal.              */

  
  .nx-franja--abierta .nx-franja__accesos{
    position: static;
    width: auto;
    height: auto;
    padding-block: var(--nx-e2);
    translate: none;
    transform: none;
    perspective: none;
    -webkit-mask-image: none;
            mask-image: none;
    overflow: visible;
  }
  .nx-franja--abierta .nx-franja__pista{
    height: auto;
    margin-block: 0;
    animation: none;
    transform: none;
    transform-style: flat;
  }
  .nx-franja--abierta .nx-franja__acceso{
    position: static;
    transform: none;
    justify-content: flex-start;
    padding-block: 10px;              /* zona de toque cómoda */
    font-size: var(--nx-texto-s);
    text-transform: none;
    letter-spacing: 0;
  }
  .nx-franja--abierta .nx-franja__acceso .nx-enlace__flecha{ display: inline; }
  .nx-franja--abierta .nx-franja__menu{ display: block; }
  .nx-franja--abierta .nx-franja__cabecera{ display: flex; }
  .nx-franja--abierta .nx-franja__cuerpo{ display: block; }
  .nx-franja--abierta .nx-franja__portal{ display: block; }/* la X vive fuera del flujo de la rejilla: no ocupa fila */

  
  /* La X dedicada TAMPOCO se pinta en móvil. Medido a 378px con el panel
     abierto: el botón «Actividad» ocupa 378×54 arriba del todo y la X caía
     en 326–370 × 8–52, o sea DENTRO de su rectángulo. Dos controles de
     cerrar superpuestos, y cuál respondía dependía del apilado.

     Se queda uno: la fila «✕ Actividad», que mide 378×54 —un objetivo que
     no se falla— y además lleva la palabra al lado. Un aspa suelta en una
     esquina es más convención que información.                            */
  .nx-franja--abierta .nx-franja__cerrar{ display: none; }

  /* con la franja abierta la página de detrás no se mueve */
  .nx-sin-scroll { overflow: hidden; }

  .nx-hero { grid-template-columns: 1fr; }
    .nx-footer__cols { grid-template-columns: 1fr 1fr; }
  .nx-cita { min-height: 60vh; gap: var(--nx-e6); }
}

/* móvil */
@media (max-width: 760px) {
  :root {
    --nx-lado: 20px;
    --nx-texto-xxl: 2rem;
    --nx-texto-xl: 1.5rem;
    --nx-alto-seccion:   64px;
    --nx-alto-destacada: 80px;
    --nx-alto-cabecera:  48px;
    --nx-header-alto:    72px;
  }

  /* A ≤760px el wordmark no cabe junto a ☰ + ES·EN·RU + WA.
     A 390px .nx-header__fin mide 276px; con min-width:0 en la marca y
     max-width:100% en el <img> el flex aplastaba el logo a 14×3 px.
     Se reserva un ancho al wordmark y se estrecha el selector de idioma. */
  .nx-header { gap: var(--nx-e1); }
  .nx-header__marca {
    flex: none;
    min-width: min(24vw, 110px);
    width: min(24vw, 110px);
  }
  .nx-header__logo {
    width: 100%;
    max-width: none;
    height: auto;
    max-height: 22px;
  }
  .nx-header__fin { gap: var(--nx-e1); }
  .nx-idioma { gap: 0; }
  .nx-idioma__op {
    min-width: 36px;
    padding-inline: 4px;
  }

  .nx-grid--2,
  .nx-grid--3,
  .nx-grid--4,
  .nx-caminos,
  .nx-pilares,
  .nx-pilares:has(> :nth-child(4)) { grid-template-columns: 1fr; }

  /* cuatro cifras en una fila a 375px son cuatro columnas de 70px.
     2×2: la cifra cabe y la etiqueta no se parte en tres renglones. */
  .nx-datos { grid-template-columns: repeat(2, 1fr); }
  .nx-datos__celda:nth-child(odd) { border-right: var(--nx-filete) solid var(--nx-borde); }
  .nx-datos__celda:nth-child(-n+2) { border-bottom: var(--nx-filete) solid var(--nx-borde); }
  .nx-datos__celda:last-child { border-right: 0; }

  /* .nx-tarjetas se quedaba fuera de esta lista y a 375px las siete fichas de
     socios pedían 661px dentro de un contenedor de 287: tres de cada cuatro
     caían fuera de la pantalla y el sitio entero ganaba scroll horizontal.
     Una sola columna en móvil, como todo lo demás: a dos, el retrato baja a
     131px y la biografía queda en columnas de cuatro palabras.               */
  .nx-tarjetas--2,
  .nx-tarjetas--3,
  .nx-tarjetas--4 { grid-template-columns: 1fr; }


  /* la galería se apila: en móvil no hay hover que valga, y una columna de
     56px no enseña nada. Cada proyecto pasa a foto completa con su pie. */
  .nx-galeria {
    grid-template-columns: 1fr;
    height: auto;
    gap: var(--nx-e2);
  }
  .nx-galeria__pieza { aspect-ratio: 4 / 3; }
  /* En móvil no hay hover: título, sitio y «Ver más» se leen siempre,
     alineados a la izquierda. Un selector partido dejaba el h3 y el
     botón en opacity:0 y el título en inline-block, pegado a la derecha. */
  .nx-galeria__pie {
    text-align: start;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: var(--nx-e3);
  }
  .nx-galeria__titulo,
  .nx-galeria__meta {
    white-space: normal;
    max-width: 100%;
    opacity: 1;
  }
  .nx-galeria__titulo {
    display: block;
    font-size: var(--nx-texto-m);
  }
  .nx-galeria__mas {
    display: inline-flex;
    margin-top: var(--nx-e2);
    opacity: 1;
    font-weight: var(--nx-peso-medio);
    color: var(--nx-coral);
  }
  .nx-galeria__mas .nx-enlace__flecha { opacity: 1; transform: none; color: var(--nx-coral); }

    
  /* en móvil el titular envuelve solo: los cortes a mano son para pantalla
     ancha y aquí dejarían líneas huérfanas */
  /* el <br> se oculta, y el espacio que lo precede en el marcado es lo que
     mantiene separadas las palabras. Sin ese espacio salía
     "inmobiliariaen España,de principio".                                 */
  .nx-hero__titulo br { display: none; }
  .nx-hero__titulo { text-wrap: balance; }

  /* Las cifras iban absolute al pie del hero y, al ser más grandes y
     en tres líneas, se pintaban encima de «Quiero invertir». En móvil
     siguen al botón, en el flujo, una debajo de otra. */
  .nx-main:has(.nx-hero) .nx-hero {
    min-height: 0;
    padding-block-end: var(--nx-e5);
  }
  .nx-hero__cifras {
    position: relative;
    inset: auto;
    margin-block-start: var(--nx-e4);
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35em;
    opacity: 1;
    transform: none;
  }

  /* La mascota se quedaba arriba, centrada y a tamaño de escritorio: ocupaba
     media pantalla y se comía la pregunta, que es lo único que importa aquí.
     Ahora va pequeña, y el filete coral pasa al contenedor — en el párrafo
     quedaría por detrás de la mascota.

     El cuerpo también baja: 24px de serif en cursiva están pensados para una
     cita a media pantalla en escritorio, no para un móvil. */
  .nx-cita {
    min-height: 0;
    text-align: start;
    padding-block: var(--nx-e6);
    padding-inline: var(--nx-e4);
    border-inline-start: 2px solid var(--nx-acento);
  }
  .nx-cita__mascota { width: calc(clamp(56px, 18vw, 88px) * 0.8); }
  .nx-cita__texto {
    padding-inline-start: 0;
    border-inline-start: 0;
    font-size: clamp(1.25rem, 4.8vw, 1.5rem);
    line-height: 1.45;
  }

  /* Cuando la mascota abre el bloque, flota y el texto la rodea. Con una fila
     flex el texto quedaba encajonado en 240px y salían veinte líneas de cuatro
     palabras; flotando solo estorba las tres primeras.

     Va acotado a ese caso porque en dos páginas la mascota viene después del
     texto a propósito, para que el diseño alterne de lado. Ahí un float no
     serviría —solo empuja lo que va detrás en el código— y se quedan
     apiladas, que es como estaban. */
  .nx-cita:has(> .nx-cita__mascota:first-child) { display: block; }
  .nx-cita > .nx-cita__mascota:first-child {
    float: left;
    margin-inline-end: var(--nx-e3);
    margin-block-end: var(--nx-e2);
  }
  .nx-footer__cols { grid-template-columns: 1fr; }

  /* contactos + redes en dos columnas (crítica de diseño móvil, 2026-09-01):
     antes iban en dos bloques apilados uno debajo del otro y alargaban el
     pie sin necesidad — en dos columnas caben en el mismo alto. */
  .nx-footer__contactos { flex-direction: row; gap: var(--nx-e4); }
  .nx-footer__contactos > .nx-contacto { flex: 1 1 0; min-width: 0; }
  .nx-contacto--social { flex-direction: column; flex-wrap: nowrap; gap: 2px; }

  /* newsletter del pie sobre fondo blanco: antes se leía en crema-sobre-negro
     igual que el resto del pie y no destacaba como la acción que es —
     «déjanos tu email» necesita su propia caja, no perderse entre enlaces. */
  #nx-newsletter {
    background: var(--nx-superficie, #fff);
    color: var(--nx-texto);
    border-radius: var(--nx-radio-1);
    padding: var(--nx-e3);
  }
  #nx-newsletter .nx-footer__titulo { color: var(--nx-texto); }
  #nx-newsletter .nx-apunte { color: var(--nx-texto-suave); }
  #nx-newsletter .nx-newsletter__destacados {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nx-e1) var(--nx-e2);
    margin: var(--nx-e2) 0 0;
    padding: 0;
    list-style: none;
  }
  #nx-newsletter .nx-newsletter__destacados li {
    font-size: var(--nx-texto-xs);
    font-weight: var(--nx-peso-medio);
    color: var(--nx-acento-texto);
  }
  #nx-newsletter .nx-newsletter__destacados li::before { content: "· "; }
  #nx-newsletter .nx-newsletter__nota {
    margin: var(--nx-e1) 0 var(--nx-e3);
    font-size: var(--nx-texto-xs);
    color: var(--nx-texto-suave);
  }
  #nx-newsletter .nx-newsletter__input { background: var(--nx-crema); border-color: var(--nx-borde); color: var(--nx-texto); }
  #nx-newsletter .nx-newsletter__input::placeholder { color: var(--nx-texto-suave); }
  #nx-newsletter .nx-newsletter__consent { color: var(--nx-texto-suave); }
}

/* impresión: sin franja, sin fondos oscuros */
@media print {
  .nx-franja, .nx-header, .nx-progreso{ display: none; }
  .nx-shell { grid-template-columns: 1fr; }
  .nx-seccion--destacada { background: none; color: var(--nx-texto); }
}

/* =============================================================================
   11 · PREFERS-REDUCED-MOTION
   No es opcional: se respeta la preferencia del sistema.
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* el contenido entra visible, sin desplazamiento */
  .nx-anim > * { opacity: 1; transform: none; }

  /* el vídeo del bento no se reproduce solo */

  /* la mascota deja de flotar */
  .nx-cita__mascota { animation: none; }
}

/* ── el hover de la franja: ESCRITORIO SÍ, TÁCTIL NO ──────────────────────
   En escritorio se abre al pasar el ratón, como estaba y como debe seguir.
   Lo único que cambia es que esas reglas viven ahora dentro de
   @media (hover: hover), así que en un móvil no llegan a existir: allí el
   navegador simula el hover al tocar y no lo suelta, y la franja se quedaba
   abierta a medias.

   En táctil se abre solo al pulsar: --desplegada al tocar la tira, --ancha
   con el botón de menú. Las dos las pone 03-scripts.html.

   El :focus-within se queda FUERA a propósito: el teclado tiene que
   funcionar en cualquier dispositivo.                                     */
@media (hover: hover) {
/* salida más corta que la entrada: se siente ágil, no pegajosa */


  .nx-franja:not(.nx-franja--abierta) .nx-franja__acceso{
    transition-delay: 0ms;
    transition-duration: 240ms;
  }
















/* paused: no rebobinar el carrusel al abrir (evita el salto) */









}/* el carrusel se detiene con la franja abierta, en cualquiera de las tres
   formas de abrirla. paused (no animation:none): si se corta la animación
   el rodillo salta a translateY(0) —a veces media pantalla de tirón. */


/* ── franja abierta ───────────────────────────────────────────────────────
   Ya no hay carrusel que parar ni copia que esconder: la pila está quieta
   en los dos estados. Lo único que cambia al abrir es la forma de los
   grupos —de columna a rejilla de tres— y que el feed pasa a scrollear. */


/* Abierta NO se aplana a repeat(6, auto): eso hacía que el feed creciera con
   su contenido y empujara al portal fuera. Las mismas seis filas con nombre,
   y el feed sigue siendo el único elástico y el único con scroll.        */
.nx-franja--abierta{ grid-template-rows:
    [menu]     auto
    [accesos]  auto
    [cabecera] auto
    [datos]    auto
    [feed]     minmax(0, 1fr)
    [portal]   auto; }

.nx-franja--abierta .nx-franja__cuerpo{
  max-height: none;
  /* NO overflow: visible. Con el panel abierto caben tres grupos de 616px en
     un carril de 334: con visible se salían del bloque y quedaban cortados
     sin forma de llegar a ellos —«ya no veo los proyectos, la pantalla no se
     mueve»—. El feed es el único que scrollea, y aquí es cuando hace falta. */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  /* la máscara sí se va: con la lista abierta, un texto desvanecido por
     arriba y por abajo se lee como un fallo, no como una ventana. */
  mask-image: none;
  -webkit-mask-image: none;
}
/* La copia del carrusel ya no se genera. Esta regla se queda como red: si
   algún caché viejo de WordPress sirve todavía la pila con la copia, no se
   verán los grupos por duplicado hasta que caduque el transient. */
.nx-franja__pila > [aria-hidden="true"]{ display: none !important; }


/* Bricks imprime el titulo nativo de WordPress antes del HTML de cada pagina.
   El H1 visible correcto ya esta dentro del bloque de contenido NEXEVO. */
#brx-content:has(.nx-seccion) > h1:first-child,
#brx-content:has(.nx-seccion) > .brxe-heading:first-child,
body.page article#brx-content > h1:first-child,
body.single article#brx-content > h1:first-child,
body.archive article#brx-content > h1:first-child {
  display: none !important;
}

/* El template nativo de WordPress/Bricks limita el contenido a ~1100px.
   En páginas YA se anulaba; en entradas y archivo NO — por eso el artículo
   seguía a ~734–1100px aunque .nx-articulo no tuviera max-width. */
body.page article#brx-content.wordpress,
body.single article#brx-content.wordpress,
body.single-post article#brx-content.wordpress,
body.archive article#brx-content.wordpress,
body.blog article#brx-content.wordpress,
body.category article#brx-content.wordpress,
article#brx-content.wordpress {
  width: 100% !important;
  max-width: none !important;
  margin-inline: 0 !important;
  padding-inline: 0 !important;
}
body.single .brxe-container,
body.single-post .brxe-container,
body.archive .brxe-container,
body.blog .brxe-container,
body.single .bricks-container,
body.single-post .bricks-container {
  width: 100% !important;
  max-width: none !important;
}
.nx-articulo,
.nx-articulo__principal,
.nx-articulo__cuerpo {
  width: 100% !important;
  max-width: none !important;
}

/* Con el contenido full width, algunos terminos del glosario quedan cerca del
   borde derecho en portatil. La definicion se ancla al bloque completo para
   no crear scroll horizontal aunque este oculta. */
@media (max-width: 1500px) {
  .nx-glosario { position: relative; }
  .nx-glosario__item { position: static; }
  .nx-glosario__def,
  .nx-glosario__fila .nx-glosario__item:last-child .nx-glosario__def {
    inset-inline: 0;
    width: auto;
    max-width: none;
  }
}


/* =============================================================================
   INVERSIÓN INMOBILIARIA — lo que la página necesita y el sistema no tenía

   Se amplían componentes que YA existen en vez de crear otros. Lo que se
   quitó de la primera versión de este bloque, y por qué:

     .nx-sec .nx-wrap .nx-eyebrow .nx-nota .nx-medida
                        duplicaban .nx-seccion, .nx-kicker y .nx-legal
     .nx-cifras .nx-cifra .nx-valor .nx-etiqueta
                        duplicaban .nx-datos (§ componente de cifras)
     .nx-franja         ES EL RAIL de la izquierda, 135 reglas más arriba.
                        La franja coral del sistema es .nx-seccion--cta
     .nx-btn-blanco     .nx-seccion--cta ya invierte .nx-boton--primario
     .nx-estado         ya existe con --venta, --curso y --entregado
     .nx-anim           es el observador de entrada del sitio, no un SVG
     .nx-rail y [id]{scroll-margin-top}
                        .nx-rail no existe en este sistema, y el ancla ya
                        la resuelve el marco. Inventados: fuera.
   ============================================================================= */

/* Cifras a tres columnas. El componente nace a 4 (.nx-datos) y aquí hacen
   falta 3: entrada, plazo y rentabilidad. Se amplía, no se duplica. */
.nx-datos--tres { grid-template-columns: repeat(3, 1fr); }

/* Combinada con --compacta (sin caja) son tres en fila y no el 2×2 del
   hero: en una sección a ancho completo caben, y partirlas 2+1 dejaba una
   cifra suelta bajo dos. La usa el bloque 04 — El mercado. */
.nx-datos--compacta.nx-datos--tres {
  grid-template-columns: repeat(3, auto);
  gap: var(--nx-e3) var(--nx-e7);
}

/* Segunda línea bajo la etiqueta: matiza la cifra sin competir con ella.
   La usa «10.000 €» para aclarar que la entrada directa son 100.000 €. */
.nx-datos__apoyo {
  margin-top: var(--nx-e1);
  font-size: var(--nx-texto-s);
  opacity: 0.8;
}

/* Bloque de respuesta directa bajo el H1. Formato «respuesta primero»: es
   el párrafo que citan los motores generativos, así que va acotado en
   ancho de lectura y marcado con el filete coral. */
.nx-respuesta {
  max-width: 78ch;
  padding-inline-start: var(--nx-e4);
  border-inline-start: calc(var(--nx-filete) * 3) solid var(--nx-acento);
}

/* Comparativa. Hereda de .nx-tabla; aquí solo el scroll horizontal en
   pantallas estrechas y el realce de nuestra columna.
   overscroll-behavior-x: contain + max-width:100%: sin eso, en iPhone el
   gesto horizontal se lo queda la PÁGINA (el texto se sale y toda la
   pantalla se mueve) en vez de quedarse dentro de la tabla. Medido en
   /inversion-inmobiliaria-espana/ y /cookies/: tabla 720/557 px, caja 314. */
.nx-comparativa-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  max-width: 100%;
  min-width: 0;
}
.nx-comparativa { min-width: 720px; }
.nx-comparativa thead th {
  background: var(--nx-superficie, #fff);
  font-size: var(--nx-texto-xs);
  font-weight: 700;
  color: var(--nx-texto);
  text-transform: uppercase;
  /* tracking POSITIVO. Con --nx-tracking-titulo, que es negativo porque está
     pensado para titulares grandes, en versalitas las palabras se pegaban y
     la cabecera se leía «OBRA NUEVA CONCICLO COMPLETO». */
  letter-spacing: var(--nx-tracking-etiqueta);
}

/* La zebra de .nx-tabla pinta las filas pares con --nx-superficie-baja, que
   es el mismo color del realce de columna: en esas filas la columna de NEXEVO
   desaparecía y la tabla se veía como un tablero de ajedrez roto. Aquí manda
   la columna, así que se apaga la zebra. */
.nx-comparativa tbody tr:nth-child(even) { background: transparent; }
.nx-comparativa tbody th {
  font-weight: var(--nx-peso-medio);
  color: var(--nx-texto);
}
/* La columna de NEXEVO. Superficie hundida, no coral: el acento ya está
   en las cifras y COMPONENT_RULES §2 lo limita al 10% del área. */
.nx-comparativa__nuestra { background: var(--nx-superficie-baja); }
.nx-comparativa td strong { color: var(--nx-acento-texto); }

/* Matiz entre paréntesis dentro de una celda: «(media de mercado)». */
.nx-apunte {
  font-size: 0.85em;
  color: var(--nx-texto-suave);
}

/* En #operaciones, los enlaces van dentro de párrafos, no como cierre de
   bloque. .nx-enlace trae tamaño propio y ahí salía en miniatura. Se acota
   a esta sección para no cambiar enlaces equivalentes en otras landings. */
#operaciones .nx-lead .nx-enlace,
#operaciones .nx-parrafo .nx-enlace { font-size: inherit; }

/* ── comparativa en móvil: tarjetas apiladas, no scroll horizontal ────────
   Crítica de diseño 2026-08-31: con las 3-4 columnas de siempre, en móvil
   solo se veía una columna a la vez y el indicador de que había más era una
   barra gris casi invisible. Cada fila pasa a ser una tarjeta: el <th
   scope="row"> es el título y cada <td> muestra su etiqueta de columna
   delante del valor, con el mismo dato que ya lleva en data-label (lo pone
   el body, no se inventa nada aquí, solo se pinta con content: attr()).
   Aplica a las 7 páginas que usan .nx-comparativa. */
@media (max-width: 640px) {
  .nx-comparativa-scroll { overflow: visible; }
  .nx-comparativa { min-width: 0; width: 100%; }
  .nx-comparativa thead { display: none; }
  .nx-comparativa,
  .nx-comparativa tbody,
  .nx-comparativa tr,
  .nx-comparativa th,
  .nx-comparativa td { display: block; width: 100%; }
  .nx-comparativa tbody tr {
    margin-block-end: var(--nx-e3);
    border: var(--nx-filete) solid var(--nx-borde);
    border-radius: var(--nx-radio-1, 8px);
    overflow: hidden;
  }
  .nx-comparativa tbody th[scope="row"] {
    padding: var(--nx-e2) var(--nx-e3);
    background: var(--nx-superficie-baja);
  }
  .nx-comparativa td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--nx-e3);
    padding: var(--nx-e2) var(--nx-e3);
    border-block-start: var(--nx-filete) solid var(--nx-borde);
    text-align: end;
  }
  /* la cabecera de escritorio se oculta en móvil (arriba): esta etiqueta por
     celda hace su papel aquí, así que lleva el mismo tratamiento —fondo
     blanco y negrita— que pidió la crítica de diseño móvil, 2026-09-01. */
  .nx-comparativa td::before {
    content: attr(data-label);
    flex-shrink: 0;
    background: var(--nx-superficie, #fff);
    font-size: var(--nx-texto-xs);
    font-weight: 700;
    color: var(--nx-texto);
    text-align: start;
  }
  /* la columna NEXEVO ya no es una columna, es una línea más dentro de la
     tarjeta: se distingue con la misma superficie hundida que en escritorio,
     pero solo en esa línea, y su etiqueta pasa al color de acento para que
     se lea de un vistazo cuál es el dato de NEXEVO. */
  .nx-comparativa td.nx-comparativa__nuestra { background: var(--nx-superficie-baja); }
  .nx-comparativa td.nx-comparativa__nuestra::before { color: var(--nx-acento-texto); }
}

@media (max-width: 760px) {
  .nx-datos--tres { grid-template-columns: 1fr; }
  /* BUG (crítica de diseño móvil, 2026-09-01): .nx-datos--compacta.nx-datos--tres
     (bloque 04 — El mercado) fija sus propias 3 columnas sin media query, con
     más especificidad que la regla de arriba — en móvil seguía en columnas
     en vez de apilarse. Mismo selector combinado para poder ganarle. */
  .nx-datos--compacta.nx-datos--tres {
    grid-template-columns: 1fr;
    gap: var(--nx-e2);
  }
  .nx-respuesta {
    padding-inline-start: var(--nx-e3);
  }
  /* cita de fuente («INE, junio de 2026»): con el naranja global de
     .nx-enlace se leía como una llamada a la acción en vez de una simple
     referencia — crítica de diseño móvil, 2026-09-01. Solo en móvil, que es
     donde se pidió el cambio; en escritorio sigue el color global. */
  .nx-enlace--fuente { color: var(--nx-texto-suave); }
}
