/**
 * landing.css — Estructura y ritmo de la landing. Compartido por las dos
 * variantes.
 *
 * Aquí no hay ni un color ni una familia tipográfica literal: todo sale de
 * custom properties que define cada variante en su propio <head>. Así la
 * comparación entre ambas aísla la identidad visual y deja fuera el layout.
 *
 * La escala tipográfica y los espaciados replican los medidos en el diseño de
 * referencia (`tokens-1440.json`): h1 100/90 px, h2 64 px, etiquetas mono de
 * 9–10 px, espaciados dominantes de 8/10/16/20 px y, deliberadamente, ninguna
 * sombra en toda la página.
 */

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

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

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--tipo-cuerpo);
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ── Tipografía ────────────────────────────────────────────────────────── */

.display {
  font-family: var(--tipo-display);
  font-weight: var(--peso-display);
  letter-spacing: var(--tracking-display);
  text-transform: var(--caja-display);
  line-height: 0.94;
  margin: 0;
  /* Averox es monolineal y muy fina: por debajo de cierto cuerpo se rompe.
     El clamp mantiene el mínimo en un tamaño donde sigue legible. */
  font-size: clamp(38px, 7.4vw, 100px);
}

h2.display { font-size: clamp(30px, 4.6vw, 64px); }
/* h4.display existe desde que «El problema» es una parte de «El principio»:
   ahí el titular cuelga de un h2 y de un h3, así que baja de nivel sin bajar
   de tamaño. Comparte regla con h3 a propósito. */
h3.display, h4.display { font-size: clamp(21px, 2.2vw, 34px); line-height: 1.12; }

.etiqueta {
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  margin: 0 0 20px;
  display: block;
}

.entradilla {
  font-size: clamp(17px, 1.5vw, 21px);
  line-height: 1.55;
  color: var(--texto-tenue);
  max-width: 46ch;
  margin: 24px 0 0;
}

p { margin: 0 0 16px; }
p:last-child { margin-bottom: 0; }

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

/* ── Rejilla ───────────────────────────────────────────────────────────── */

.env {
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 64px);
}

section { position: relative; }

.bloque { padding: clamp(80px, 12vh, 160px) 0; }
.bloque-alto { padding: clamp(110px, 18vh, 220px) 0; }

/* ── La banda de transición entre tonos ────────────────────────────────
   El hueco entre una sección oscura y una clara. Su fondo es el del tramo de
   ARRIBA; el lienzo pinta encima el color que llega desde abajo, y el corte
   duro del final cae solo. Ver `efectos/transicion/banda.js` y
   contexto/seccion_3/SPEC-transicion.md.

   ⚠️ Mide exactamente lo que mide la transición, ni un píxel más. Hubo una
   versión con un hueco de 620 px por el que una franja rígida de 340 viajaba:
   la mitad de abajo se rellenaba macizo y no se veía, pero la de ARRIBA quedaba
   transparente y dejaba un vacío enorme entre el final de la sección y el
   principio del efecto. No hace falta: el gradiente se comprime contra la base
   de la banda, así que ahí siempre hay macizo y nunca hay costura. */
.banda {
  position: relative;
  height: var(--alto-banda, 340px);
  /* Sin esto, el lienzo hereda el line-height del body y deja un hueco. */
  line-height: 0;
}
.banda > canvas { position: absolute; inset: 0; }
/* La bajada arranca del oscuro; la vuelta, del claro. */
.banda-baja { background: var(--fondo); }
.banda-sube { background: #DCEAF0; }

/* En móvil se acorta, y con ella el recorrido del efecto: es lo correcto,
   porque el scroll por pulgada es mucho mayor. */
@media (max-width: 720px) {
  .banda { --alto-banda: 190px; }
}

/* La banda ya es el aire entre las dos secciones: la de abajo no necesita
   además todo su padding de arriba. */
.banda + .tono-claro > .bloque:first-child,
.tono-claro + .banda + section.bloque { padding-top: clamp(28px, 5vh, 64px); }

/* Y la de arriba no necesita el suyo de abajo, o queda un vacío antes de que
   empiecen los puntos — que es justo lo que había que quitar. */
.lentes:has(+ .banda), section:has(+ .banda) { padding-bottom: clamp(24px, 4vh, 56px); }

/* Sin canvas o sin JavaScript la banda queda vacía y el corte entre secciones
   es seco. Es legible, y es el fallback deliberado. */

/* ── Navegación ────────────────────────────────────────────────────────── */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 16px clamp(20px, 5vw, 64px);
  /* El desenfoque mantiene legible la barra sobre la nube de puntos. */
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--fondo) 72%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--texto) 8%, transparent);
}

/* ── Averox es unicase, y su alfabeto bueno vive en la caja baja ────────
   El fichero trae DOS dibujos de capital. A–Z son capitales convencionales;
   a–z no son minúsculas —miden lo mismo, avance 745 las dos— sino capitales
   de diseño alternativo, y son las que dan el carácter de la fuente: la A sin
   travesaño, la E partida, la R de pierna recta, la D angular. Difieren en
   nueve letras: A B D E F G K P R. En las otras diecisiete la fuente es
   unicase y el dibujo es el mismo.

   Por eso la barra va en `lowercase` y no en `uppercase`: el texto del DOM
   sigue siendo "Synthetrial" y "Capacidades" —esto es presentación, no copy—,
   pero al motor tipográfico le llegan minúsculas y pinta el alfabeto bueno.
   Se sigue leyendo en caja alta. NO cambiar a `uppercase`: se pierde.

   Comprobado que los nueve rótulos de la barra tienen glifo en caja baja,
   acentos incluidos (é y á también tienen dibujo propio). El resto de la
   página sigue con `--caja-display: uppercase`. */
.nav-marca {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  font-family: var(--tipo-display);
  font-weight: var(--peso-display);
  letter-spacing: 0.2em;
  text-transform: lowercase;
  /* Averox es monolineal y muy fina: a 15px perdía el trazo geométrico y se
     leía como una grotesca cualquiera. Sube hasta 22px, que es donde el
     carácter de la fuente se reconoce sin que el wordmark le coma sitio a los
     enlaces — medido a 1280px, la barra queda con ~190px de holgura. */
  font-size: clamp(18px, 1.5vw, 22px);
}

/* La "IA" del logotipo va en color de acento: el wordmark oficial esconde
   Inteligencia Artificial dentro de SYNTHETR·IA·L, y no es casual. Los enlaces
   de la barra repiten el gesto sobre sus dos penúltimas letras. */
.nav-marca i,
.nav-enlaces i { font-style: normal; color: var(--acento); }

.nav-enlaces {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.2vw, 34px);
}
.nav-enlaces a {
  /* No `inline-flex`: convertiría cada trozo de texto en ítem flex y el gap
     abriría un hueco a los lados de las dos letras en acento. */
  display: inline-block;
  font-family: var(--tipo-display);
  font-weight: var(--peso-display);
  /* Un escalón por debajo del wordmark: la jerarquía la marca el tamaño, no
     un cambio de familia. */
  font-size: clamp(12px, 1.1vw, 15px);
  letter-spacing: 0.1em;
  text-transform: lowercase;
  white-space: nowrap;
  color: var(--texto-tenue);
  transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
}
.nav-enlaces a:hover { color: var(--texto); }

/* ── Desplegable de Capacidades ─────────────────────────────────────────
   Se abre con el puntero y con el tabulador (`:focus-within`), sin JS ni
   estado: el enlace de cabecera sigue navegando a la sección, que es lo que
   se espera al hacer clic en él. */
/* Flex, y no un bloque: como bloque, su caja de línea imponía el strut del
   `line-height` heredado —27,2 px frente a los 24 del rótulo— y el enlace se
   alineaba a ESA línea base. «Capacidades» caía 1,4 px por debajo de sus tres
   vecinos, que sí son flex items directos de `.nav-enlaces`. Así el enlace se
   blockifica y se centra con los demás. */
.nav-grupo { position: relative; display: flex; align-items: center; }

/* La punta va absoluta, y no es un capricho: como `inline-block` se alineaba a
   la línea base, su caja colgaba por debajo de ella y empujaba la caja de línea
   del enlace. «Capacidades» quedaba 1,4 px más bajo que los otros tres, que son
   flex items limpios. Fuera del flujo, el rótulo se compone exactamente igual
   que sus vecinos y el `padding-right` le reserva el sitio. */
.nav-grupo > a { position: relative; padding-right: 16px; }

.nav-punta {
  position: absolute;
  right: 0;
  top: 50%;
  width: 5px;
  height: 5px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  /* El `-50%` centra la punta sobre el rótulo sin depender de su tamaño —nada
     de restar píxeles a ojo—. El píxel extra es compensación óptica: el chevron
     apunta abajo en reposo y arriba abierto, así que su masa cae a un lado
     distinto en cada posición y hay que empujarlo al contrario. */
  transform: translateY(calc(-50% - 1px)) rotate(45deg);
  transition: transform 0.35s cubic-bezier(0.44, 0, 0.56, 1);
}
.nav-grupo:hover .nav-punta,
.nav-grupo:focus-within .nav-punta { transform: translateY(calc(-50% + 1px)) rotate(225deg); }

.nav-menu {
  position: absolute;
  top: calc(100% + 18px);
  left: -18px;
  display: flex;
  flex-direction: column;
  min-width: max-content;
  padding: 6px 0;
  background: color-mix(in srgb, var(--fondo-hondo) 92%, transparent);
  backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--texto) 10%, transparent);
  border-radius: 2px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.3s cubic-bezier(0.44, 0, 0.56, 1),
              transform 0.3s cubic-bezier(0.44, 0, 0.56, 1),
              visibility 0s linear 0.3s;
}
.nav-grupo:hover .nav-menu,
.nav-grupo:focus-within .nav-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0s;
}
/* El puente cubre el hueco entre el enlace y el panel: sin él el menú se
   cierra al cruzarlo con el puntero. */
.nav-menu::before {
  content: "";
  position: absolute;
  inset: -18px 0 100% 0;
}
.nav-menu a {
  font-size: clamp(11px, 1vw, 13px);
  letter-spacing: 0.12em;
  padding: 9px 22px;
}
.nav-menu a:hover { background: color-mix(in srgb, var(--texto) 6%, transparent); }

/* La barra es fija y mide ~80px: sin esto el ancla del submenú deja la tarjeta
   medio tapada. */
.tarjeta[id] { scroll-margin-top: 120px; }

/* ── El menú de móvil ──────────────────────────────────────────────────
   Por debajo de 720px los enlaces de la barra se ocultan. Antes no los
   sustituía nada —desde un móvil no se llegaba a ninguna sección— y el botón
   de la barra se salía 23px de una pantalla de 390 peleando por sitio con el
   wordmark. Ahora los dos se van al panel y en la barra queda el mando. */

.nav-mando { display: none; }

@media (max-width: 720px) {
  .nav-enlaces { display: none; }
  /* El CTA se va al panel: en la barra no cabía sin cortarse. */
  .nav > .boton { display: none; }
  .nav-marca { font-size: 15px; letter-spacing: 0.14em; }

  .nav-mando {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px es el mínimo táctil de WCAG 2.5.5, y el dibujo son 18px dentro. */
    width: 44px;
    height: 44px;
    margin-right: -10px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--texto);
    cursor: pointer;
  }

  .nav-rayas {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 18px;
    height: 12px;
  }
  .nav-rayas i {
    display: block;
    height: 1px;
    background: currentColor;
    transition: transform 0.22s, opacity 0.16s;
  }
  /* Abierto, las tres rayas se cruzan en aspa: el mando es el mismo botón. */
  .nav-mando[aria-expanded="true"] .nav-rayas i:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
  .nav-mando[aria-expanded="true"] .nav-rayas i:nth-child(2) { opacity: 0; }
  .nav-mando[aria-expanded="true"] .nav-rayas i:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

  .menu-movil {
    position: fixed;
    /* Arranca bajo la barra, que es fija y mide ~80px. */
    inset: 80px 0 0;
    z-index: 40;
    background: var(--fondo-hondo);
    overflow-y: auto;
    animation: mm-entra 0.2s ease-out;
  }

  .mm-enlaces {
    display: flex;
    flex-direction: column;
    padding: 18px clamp(20px, 5vw, 32px) 48px;
  }

  .mm-enlace {
    /* Cuerpo grande y alto generoso: se acierta con el pulgar sin puntería. */
    font-family: var(--tipo-display);
    font-weight: var(--peso-display);
    font-size: 21px;
    letter-spacing: 0.06em;
    text-transform: var(--caja-display);
    color: var(--texto);
    padding: 16px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 22%, transparent);
  }
  .mm-enlace i { font-style: normal; color: var(--acento); }

  /* El submenú de «Capacidades», aplanado y sangrado: se lee como hijo sin
     necesitar un desplegable dentro del desplegable. */
  .mm-hijo {
    font-size: 17px;
    padding-left: 18px;
    color: var(--texto-tenue);
  }

  .mm-cta {
    align-self: flex-start;
    margin-top: 28px;
  }
}

@keyframes mm-entra {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .menu-movil { animation: none; }
  .nav-rayas i { transition: none; }
}

/* ── Botones ───────────────────────────────────────────────────────────── */

.boton {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--tipo-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 14px 26px;
  border-radius: 2px;
  border: 1px solid var(--acento);
  color: var(--acento);
  transition: all 0.4s cubic-bezier(0.44, 0, 0.56, 1);
  cursor: pointer;
  background: transparent;
}
.boton:hover { background: var(--acento); color: var(--fondo); }

.boton-tenue { border-color: color-mix(in srgb, var(--texto) 22%, transparent); color: var(--texto-tenue); }
.boton-tenue:hover { background: transparent; border-color: var(--texto); color: var(--texto); }

/* El CTA de la barra va en Averox como el resto de la barra; los del cuerpo de
   la página se quedan en mono, que es donde la mono hace de dato y no de
   rótulo. `flex-shrink: 0` no es cosmético: sin él el flex de la barra lo
   comprime antes que a los enlaces y el rótulo se parte en tres líneas. */
.nav > .boton {
  flex-shrink: 0;
  white-space: nowrap;
  font-family: var(--tipo-display);
  font-weight: var(--peso-display);
  font-size: clamp(12px, 1vw, 14px);
  letter-spacing: 0.12em;
  padding: 16px 30px;
  /* Revierte el `uppercase` de `.boton`: ver la nota del alfabeto, arriba. */
  text-transform: lowercase;
}

/* El icono de persona del CTA de la barra. Se dimensiona en `em` para que siga
   al `clamp()` del rótulo, y hereda el color por `currentColor`: en reposo va
   en el acento como el texto, y al pasar el ratón se invierte con él.
   El `.boton` ya es un flex con `gap`, así que la alineación no pide nada más.
   El grosor va en unidades del viewBox (18): a los ~15 px que mide en pantalla
   se traduce en 1,2 px reales, que es el trazo fino del resto de la barra. */
.icono-persona {
  width: 1.15em;
  height: 1.15em;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
}

/* Entre 721 y 1079 px no caben a la vez el wordmark, los cuatro enlaces y el
   CTA: medido, el contenido pide 978 px. Cede el CTA. Con él fuera la barra
   queda en 709 px y la navegación sobrevive hasta el corte de 720.

   ⚠️ Esta regla se decidió cuando el botón decía "Hablemos de tu ensayo" y el
   hero lo repetía idéntico dos líneas más abajo, así que esconderlo no perdía
   nada. Desde que es "Área Clientes" ya no hay copia: entre 721 y 1079 px la
   web se queda sin acceso al área de clientes. Pendiente de decidir. */
@media (min-width: 721px) and (max-width: 1079px) {
  .nav > .boton { display: none; }
}
@media (max-width: 720px) {
  .nav > .boton { font-size: 11px; padding: 12px 18px; }
}

.acciones { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 38px; }

/* ── Hero ──────────────────────────────────────────────────────────────── */

/* El hero ocupa varias alturas de pantalla; el lienzo se queda pegado
   mientras el scroll consume la transición. Es la misma mecánica que el
   diseño de referencia. */
.hero-pista { position: relative; height: 320vh; }


.hero-fijo {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.hero-lienzo { position: absolute; inset: 0; z-index: 1; }

/* Fondo de la escena. El negro puro aplana la nube; un degradado radial le
   devuelve profundidad. */
/* El degradado y la viñeta caen hacia --fondo-hondo, no hacia negro: mezclar
   con negro apagaba el color y hacía que toda la escena se leyera más oscura de
   lo que dicen los tokens. */
.hero-fondo {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(
    124% 84% at 50% 44%,
    color-mix(in srgb, var(--acento) 11%, var(--fondo)) 0%,
    var(--fondo) 52%,
    var(--fondo-hondo, var(--fondo)) 100%
  );
}
.hero-vineta {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: radial-gradient(82% 66% at 50% 48%, transparent 58%,
    color-mix(in srgb, var(--fondo-hondo, #000) 72%, transparent) 100%);
}

.hero-texto {
  position: relative;
  z-index: 4;
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 64px);
  pointer-events: none;
}
.hero-texto > * { pointer-events: auto; }

/* El texto se desvanece conforme la figura se dispersa: a partir de ahí la
   atención va a la nube, no al titular. */
.hero-texto { transition: opacity 0.25s linear; }

/* ── Entrada ───────────────────────────────────────────────────────────
   Mientras corre el ciclo de presentación, el texto no está. Aparece
   escalonado al terminar, de arriba abajo, para que la lectura siga el mismo
   orden que la jerarquía. */

.hero-texto.esperando-entrada { opacity: 0; }
.hero-texto.esperando-entrada > * { visibility: hidden; }

.hero-texto.entrada-hecha .etiqueta,
.hero-texto.entrada-hecha h1,
.hero-texto.entrada-hecha .entradilla,
.hero-texto.entrada-hecha .acciones {
  animation: surgir 0.85s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}
.hero-texto.entrada-hecha .etiqueta   { animation-delay: 0.00s; }
.hero-texto.entrada-hecha h1          { animation-delay: 0.10s; }
.hero-texto.entrada-hecha .entradilla { animation-delay: 0.26s; }
.hero-texto.entrada-hecha .acciones   { animation-delay: 0.38s; }

@keyframes surgir {
  from { opacity: 0; transform: translateY(16px); filter: blur(3px); }
  to   { opacity: 1; transform: none;             filter: none; }
}

/* El indicador de scroll llega el último: hasta que no hay texto, no hay nada
   que invitar a dejar atrás. */
.hero-pista-abajo {
  animation: surgir 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.6s backwards;
}

.hero-col { max-width: 560px; }

@media (max-width: 900px) {
  .hero-col { max-width: 100%; }
  .hero-texto { text-align: left; }
}

/* Indicador de scroll */
.hero-pista-abajo {
  position: absolute;
  left: 50%; bottom: 34px; z-index: 5;
  transform: translateX(-50%);
  font-family: var(--tipo-mono);
  font-size: 9px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--texto-tenue);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.hero-pista-abajo::after {
  content: ""; width: 1px; height: 34px;
  background: linear-gradient(var(--texto-tenue), transparent);
}

/* ── La disolución del hero ────────────────────────────────────────────
   El hero acababa a filo. Medido a 1440×900: su última fila va de #0c0c11 en el
   centro a #16151f en los flancos —eso es la viñeta—, y la siguiente ya es
   --fondo, #282637. Veintitantos niveles de salto en un píxel, y el ojo lee dos
   bloques pegados en vez de una página.

   La banda va de 46vh POR ENCIMA del final del hero a 22vh POR DEBAJO, y hace
   dos cosas distintas en un solo degradado:

     tramo 1  ·  0 → 67,65 %   el negro del hero apareciendo desde alfa 0
     tramo 2  ·  67,65 → 100 % ese negro virando a --fondo, ya opaco

   El tramo 1 tapa el final del hero DESDE TRANSPARENTE: como la última fila no
   es plana, arrancar con un color liso dejaría su propia línea donde empieza —se
   cambia una costura por otra—, así que se entra en alfa 0, donde se ve el hero
   literal con su viñeta, y el salto es cero por construcción. La variación
   horizontal no se replica: se disuelve sola bajo un color uniforme. El alfa
   llega a 1 justo en el filo, de modo que el hero queda cubierto exactamente ahí.

   El tramo 2 existe porque por debajo del hero el fondo YA es --fondo: pintarlo
   translúcido encima no oscurece nada, y el texto no tendría negro detrás. Así
   que a partir del filo la banda deja de jugar con el alfa y cambia de color, por
   detrás del texto, hasta empalmar con --fondo justo donde acaba la entradilla.
   De ahí que la sección se pinte con `z-index` por encima: el rótulo y el titular
   caen sobre el negro y la entradilla sobre el tránsito.

   --disolucion-negro es el color medido de la última fila del hero (#13121b), no
   uno elegido a ojo, y sale de --fondo-hondo para que siga al tema.

   Tres cosas que no son cosméticas:

     · `margin-top` negativo IGUAL a la altura: suman cero, así que la banda vive
       entera sobre el hero y no mueve un píxel de lo que viene detrás. Lo que
       baja el texto de la sección es su propio margen, no éste.
     · `z-index`, porque .hero-fijo es sticky y eso crea contexto de apilamiento
       propio. Sin él la banda se pinta por debajo y no tapa nada.
     · Las paradas siguen un smootherstep (6t⁵-15t⁴+10t³) en los dos tramos, y no
       la recta de un degradado de dos colores: con la recta el ojo caza los codos
       —donde arranca, donde se junta con el otro tramo y donde se detiene— y
       salen tres líneas nuevas en vez de una. La curva entra y sale con pendiente
       nula en cada extremo, y por eso los dos tramos empalman sin marca. Ocho y
       nueve tramos bastan: el error de la interpolación lineal de CSS contra la
       quíntica es de 0,145 niveles de 8 bits. */
.hero-disolucion {
  --disolucion-negro: color-mix(in srgb, var(--fondo-hondo) 62%, #000);
  position: relative;
  z-index: 1;
  height: 46vh;
  margin-top: -46vh;
  pointer-events: none;
}
/* El fondo va en el pseudo y no en el elemento porque tiene que desbordar 22vh
   por abajo, hasta el final de la entradilla, sin empujar nada. */
.hero-disolucion::after { height: calc(100% + 22vh); }
.proceso-disolucion::after { height: calc(100% + clamp(28px, 3.5vh, 44px)); }
.hero-disolucion::after,
.proceso-disolucion::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--disolucion-negro) 0.0%, transparent) 0.00%,
    color-mix(in srgb, var(--disolucion-negro) 1.6%, transparent) 8.46%,
    color-mix(in srgb, var(--disolucion-negro) 10.4%, transparent) 16.91%,
    color-mix(in srgb, var(--disolucion-negro) 27.5%, transparent) 25.37%,
    color-mix(in srgb, var(--disolucion-negro) 50.0%, transparent) 33.82%,
    color-mix(in srgb, var(--disolucion-negro) 72.5%, transparent) 42.28%,
    color-mix(in srgb, var(--disolucion-negro) 89.6%, transparent) 50.74%,
    color-mix(in srgb, var(--disolucion-negro) 98.4%, transparent) 59.19%,
    color-mix(in srgb, var(--disolucion-negro) 100.0%, transparent) 67.65%,
    color-mix(in srgb, var(--fondo) 1.2%, var(--disolucion-negro)) 71.24%,
    color-mix(in srgb, var(--fondo) 7.6%, var(--disolucion-negro)) 74.84%,
    color-mix(in srgb, var(--fondo) 21.0%, var(--disolucion-negro)) 78.43%,
    color-mix(in srgb, var(--fondo) 39.7%, var(--disolucion-negro)) 82.03%,
    color-mix(in srgb, var(--fondo) 60.3%, var(--disolucion-negro)) 85.62%,
    color-mix(in srgb, var(--fondo) 79.0%, var(--disolucion-negro)) 89.22%,
    color-mix(in srgb, var(--fondo) 92.4%, var(--disolucion-negro)) 92.81%,
    color-mix(in srgb, var(--fondo) 98.8%, var(--disolucion-negro)) 96.41%,
    color-mix(in srgb, var(--fondo) 100.0%, var(--disolucion-negro)) 100.00%
  );
}

/* ── Los flancos negros de «El principio» ───────────────────────────────
   Punto 5 de Julio (2026-09-05). El hero ya se disuelve hacia abajo
   (`.hero-disolucion`); esto añade lo otro que pidió: que el negro se quede un
   rato en las DOS FRANJAS LATERALES mientras el color entra por el centro, con
   estrellas lentas dentro.

   Va DESACTIVADO salvo con `?flancos=1` o `?flancos=lab` en la URL, hasta que
   Julio dé el visto bueno sobre el GIF. Sin la clase, la página es la de antes.

   ⚠️ El ancho del flanco NO es un porcentaje fijo: es lo que sobra a cada lado
   de la caja de texto. `.env` mide como mucho 1240 px y lleva 64 de padding, así
   que el texto empieza a `(100% − 1240) / 2 + 64`. El flanco se detiene 24 px
   antes, en `+ 40`, y por debajo de 1240 px de ventana `max(0px, …)` lo deja en
   nada — que es lo correcto: ahí no sobra margen y un flanco caería sobre el
   texto. Con un 15 % fijo, a 1920 px se quedaba corto y a 1280 pisaba la letra.

   Las dos curvas son el smootherstep de siempre. Y el negro es el mismo
   `--disolucion-negro` del hero, no un #000 nuevo: si fuera otro, el flanco se
   leería como un rectángulo pegado encima en vez de como la continuación de lo
   de arriba. */
.principio-flancos {
  position: absolute;
  /* 🔴 Arranca 25 vh POR ENCIMA de la sección, y esto es lo que arregla el hueco
     que marcó Julio: `.principio` empieza en la página en y=2733, pero el negro
     del hero llega hasta ahí desde y=2505 —es la zona que cubre
     `.hero-disolucion`, 46 vh de banda más 22 de desbordamiento—. Con el flanco
     pegado al borde de la sección, esa franja de 228 px quedaba negra y SIN
     estrellas: medido, en su scroll el flanco empezaba en y=226 del viewport y
     sus dos recuadros caían entre 80 y 215. */
  inset: -25vh 0 auto 0;

  /* 🔴 EL ALTO SE MIDE CONTRA LA SECCIÓN, NO CONTRA LA VENTANA, y el `min()` no
     es prudencia: es lo que impide que el efecto rompa la página.

     Julio pidió que bajara «hasta casi la frase» y propuso 1000 vh. Medido:

       hasta la cita de Reiter y Rubin   405-411 vh, según el alto de ventana
       tope antes del tramo claro        418-424 vh

     O sea que 1000 vh mete un flanco NEGRO de más de 5.000 px sobre
     «Protocolos», que es tono claro. Y `vh` es además la unidad equivocada para
     el encargo: «hasta la frase» es una posición DE LA SECCIÓN, así que en una
     ventana baja se quedaría corto y en una alta se saldría, con el mismo
     número.

     Por eso el defecto va en porcentaje de `.principio` —`100% + 25vh` es
     exactamente el final de la sección, y los 120 px que se restan lo dejan
     justo encima de la cita— y el `min()` topa cualquier valor que llegue por
     `--alto-flanco` desde el panel. Se puede subir el slider a lo que sea: no
     desborda. */
  --tope-flanco: calc(100% + 25vh);
  height: min(var(--alto-flanco, calc(var(--tope-flanco) - 120px)), var(--tope-flanco));

  pointer-events: none;
  z-index: 0;

  /* Los valores que dejó Julio en el panel (2026-09-05, 3ª ronda). `negro 0 %`
     es negro puro: `color-mix` con 0 % de --fondo-hondo. */
  --flanco-negro: color-mix(in srgb, var(--fondo-hondo) 0%, #000);
  --flanco: max(0px, calc((100% - 1240px) / 2 + 304px));

  /* ── El foco ──────────────────────────────────────────────────────────
     `--foco-x` y `--foco-y` tienen gemelo en cielo-lento.js (`focoX`,`focoY`) y
     los dos pares van juntos: aquí se abre el hueco de la máscara, allí nacen
     los anillos. Separarlos deja los anillos naciendo donde no hay hueco.

     🔴 `--foco-w` se CALCULA, no se elige, y ése es el arreglo que hizo falta al
     mover el foco fuera del centro. La cúpula tiene que llegar al filo interior
     de los dos flancos; con el foco al 27 % el de la derecha queda mucho más
     lejos, y un ancho fijo del 42 % dejaba 42 px de costura a 1440. La fórmula
     toma la distancia al flanco MÁS LEJANO —sea el que sea, así que también vale
     si el foco se mueve a la derecha— y le suma la holgura.

     `--foco-h` va en PÍXELES y no en porcentaje a propósito: en porcentaje
     crecía con el alto del contenedor, y al pasar el flanco de 161 a 405 vh la
     cúpula habría pasado de 320 a 814 px, metiendo estrellas sobre el titular. */
  --foco-x: 27%;
  --foco-y: 24px;
  --foco-holgura: 40px;
  --foco-w: calc(
    var(--foco-holgura) +
      max(
        calc(var(--foco-x) - var(--flanco)),
        calc(100% - var(--flanco) - var(--foco-x))
      )
  );
  --foco-h: 320px;
}

/* 🔴 EL NEGRO Y LAS ESTRELLAS NO COMPARTEN SILUETA, y ésa es la clave de todo el
   efecto. Se intentó primero con una máscara única en el padre y no se puede:

     · Las estrellas tienen que verse EN EL FOCO, porque es de ahí de donde
       nacen. Con la máscara de los flancos —transparente justo en el centro— se
       borraban donde nacen.
     · El negro NO puede estar ahí: encima está el resplandor del isotipo
       recogido del hero, y taparlo mata el efecto entero. Se probó con una
       cúpula común y el icono desapareció de la pantalla.

   Así que el negro se va al pseudoelemento con la máscara de siempre —flancos ∩
   vertical— y el lienzo se lleva la suya, que además une la cúpula del foco. */
.principio-flancos::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--flanco-negro);
  -webkit-mask-image: linear-gradient(
      to right,
      rgb(0 0 0 / 1.0000) calc(var(--flanco) * 0.0000),
      rgb(0 0 0 / 0.9645) calc(var(--flanco) * 0.1667),
      rgb(0 0 0 / 0.7901) calc(var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.5000) calc(var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.2099) calc(var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.0355) calc(var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.0000) calc(var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0000) calc(100% - var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0355) calc(100% - var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.2099) calc(100% - var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.5000) calc(100% - var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.7901) calc(100% - var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.9645) calc(100% - var(--flanco) * 0.1667),
      rgb(0 0 0 / 1.0000) calc(100% - var(--flanco) * 0.0000)
    ), linear-gradient(
      to bottom,
      #000 0%,
      #000 18%,
      rgb(0 0 0 / 0.9645) 31.67%,
      rgb(0 0 0 / 0.7901) 45.33%,
      rgb(0 0 0 / 0.5000) 59.00%,
      rgb(0 0 0 / 0.2099) 72.67%,
      rgb(0 0 0 / 0.0355) 86.33%,
      rgb(0 0 0 / 0.0000) 100.00%
    );
  mask-image: linear-gradient(
      to right,
      rgb(0 0 0 / 1.0000) calc(var(--flanco) * 0.0000),
      rgb(0 0 0 / 0.9645) calc(var(--flanco) * 0.1667),
      rgb(0 0 0 / 0.7901) calc(var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.5000) calc(var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.2099) calc(var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.0355) calc(var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.0000) calc(var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0000) calc(100% - var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0355) calc(100% - var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.2099) calc(100% - var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.5000) calc(100% - var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.7901) calc(100% - var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.9645) calc(100% - var(--flanco) * 0.1667),
      rgb(0 0 0 / 1.0000) calc(100% - var(--flanco) * 0.0000)
    ), linear-gradient(
      to bottom,
      #000 0%,
      #000 18%,
      rgb(0 0 0 / 0.9645) 31.67%,
      rgb(0 0 0 / 0.7901) 45.33%,
      rgb(0 0 0 / 0.5000) 59.00%,
      rgb(0 0 0 / 0.2099) 72.67%,
      rgb(0 0 0 / 0.0355) 86.33%,
      rgb(0 0 0 / 0.0000) 100.00%
    );
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* (flancos ∪ cúpula) ∩ vertical. Con `mask-composite` la lista se aplica por
   pares —una entrada menos que capas—, así que `add, intersect` es exactamente
   eso. */
.principio-flancos canvas {
  position: absolute;
  inset: 0;
  -webkit-mask-image: linear-gradient(
      to right,
      rgb(0 0 0 / 1.0000) calc(var(--flanco) * 0.0000),
      rgb(0 0 0 / 0.9645) calc(var(--flanco) * 0.1667),
      rgb(0 0 0 / 0.7901) calc(var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.5000) calc(var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.2099) calc(var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.0355) calc(var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.0000) calc(var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0000) calc(100% - var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0355) calc(100% - var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.2099) calc(100% - var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.5000) calc(100% - var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.7901) calc(100% - var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.9645) calc(100% - var(--flanco) * 0.1667),
      rgb(0 0 0 / 1.0000) calc(100% - var(--flanco) * 0.0000)
    ), radial-gradient(
      ellipse var(--foco-w) var(--foco-h) at var(--foco-x) var(--foco-y),
      #000 0%,
      rgb(0 0 0 / 0.9648) 25%,
      rgb(0 0 0 / 0.7266) 50%,
      rgb(0 0 0 / 0.3164) 75%,
      transparent 100%
    ), linear-gradient(
      to bottom,
      #000 0%,
      #000 18%,
      rgb(0 0 0 / 0.9645) 31.67%,
      rgb(0 0 0 / 0.7901) 45.33%,
      rgb(0 0 0 / 0.5000) 59.00%,
      rgb(0 0 0 / 0.2099) 72.67%,
      rgb(0 0 0 / 0.0355) 86.33%,
      rgb(0 0 0 / 0.0000) 100.00%
    );
  mask-image: linear-gradient(
      to right,
      rgb(0 0 0 / 1.0000) calc(var(--flanco) * 0.0000),
      rgb(0 0 0 / 0.9645) calc(var(--flanco) * 0.1667),
      rgb(0 0 0 / 0.7901) calc(var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.5000) calc(var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.2099) calc(var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.0355) calc(var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.0000) calc(var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0000) calc(100% - var(--flanco) * 1.0000),
      rgb(0 0 0 / 0.0355) calc(100% - var(--flanco) * 0.8333),
      rgb(0 0 0 / 0.2099) calc(100% - var(--flanco) * 0.6667),
      rgb(0 0 0 / 0.5000) calc(100% - var(--flanco) * 0.5000),
      rgb(0 0 0 / 0.7901) calc(100% - var(--flanco) * 0.3333),
      rgb(0 0 0 / 0.9645) calc(100% - var(--flanco) * 0.1667),
      rgb(0 0 0 / 1.0000) calc(100% - var(--flanco) * 0.0000)
    ), radial-gradient(
      ellipse var(--foco-w) var(--foco-h) at var(--foco-x) var(--foco-y),
      #000 0%,
      rgb(0 0 0 / 0.9648) 25%,
      rgb(0 0 0 / 0.7266) 50%,
      rgb(0 0 0 / 0.3164) 75%,
      transparent 100%
    ), linear-gradient(
      to bottom,
      #000 0%,
      #000 18%,
      rgb(0 0 0 / 0.9645) 31.67%,
      rgb(0 0 0 / 0.7901) 45.33%,
      rgb(0 0 0 / 0.5000) 59.00%,
      rgb(0 0 0 / 0.2099) 72.67%,
      rgb(0 0 0 / 0.0355) 86.33%,
      rgb(0 0 0 / 0.0000) 100.00%
    );
  -webkit-mask-composite: source-over, source-in;
  mask-composite: add, intersect;
}

/* El contenido por encima del flanco. `.principio` ya es `position: relative`
   (se lo puso el margen negativo que lo mete en la zona oscura del hero). */
.con-flancos .principio > .env { position: relative; z-index: 1; }

/* El texto de «El principio» sube a la zona oscura en lugar de esperar a que el
   hero termine: sin esto quedaban ~190 px de --fondo liso entre el filo del hero
   y el rótulo, que es lo que hacía que se leyeran como dos páginas. Con el
   margen, el rótulo cae 27 px POR ENCIMA del filo y la entradilla acaba donde la
   banda alcanza --fondo. `z-index` por encima de la banda: el texto va delante
   del degradado, nunca debajo.

   Sólo en la home: el selector pide una .hero-disolucion delante, y en la
   subpágina «Datos sintéticos» no hay hero ni banda, así que su padding
   entero se queda como está. */
.hero-disolucion + .principio {
  position: relative;
  z-index: 2;
  margin-top: -21vh;
}

/* ── Manifiesto ────────────────────────────────────────────────────────── */



/* ── Cifras ────────────────────────────────────────────────────────────── */

.rejilla-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: clamp(28px, 4vw, 64px);
  margin-top: 72px;
}

/* Las cifras NO van en Averox: de los diez dígitos, el fichero del repo solo
   pinta el 0 y el 1 —los demás vienen con el glifo vacío o sin glifo, medido
   con fontTools— y un glifo vacío no cae al tipo siguiente, pinta un agujero.
   JetBrains Mono es el tipo de datos y etiquetas de la casa, y hay precedente:
   h3.display baja a Lato por un motivo parecido. Ver wiki/marca.md y
   contexto/seccion_3/SPEC-transicion.md §7. */
.cifra .n {
  font-family: var(--tipo-mono);
  font-weight: 400;
  letter-spacing: -0.02em;
  font-size: clamp(30px, 3.2vw, 46px);
  color: var(--acento);
  line-height: 1;
  display: block;
  margin-bottom: 18px;
}
/* h4 en los contadores de Protocolos, h5 en «El problema»: ahí las tarjetas
   cuelgan del h4 del titular de la parte. Mismo aspecto, distinto nivel. */
.cifra h4, .cifra h5 {
  font-size: 17px; font-weight: 700; margin: 0 0 10px;
  letter-spacing: -0.01em;
}
.cifra p { color: var(--texto-tenue); font-size: 15px; line-height: 1.55; }

/* ── Protocolos: los contadores ─────────────────────────────────────────
   Reutilizan .cifra a propósito: son la misma clase de dato que las cifras de
   «El problema», y con el mismo tratamiento la página no inventa un segundo
   lenguaje para lo mismo. */
.contadores { margin-top: 76px; }
.contadores .rejilla-3 { margin-top: 30px; gap: 20px; }
.cifra-delta {
  display: block;
  font-family: var(--tipo-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--acento);
  margin: -4px 0 10px;
}

/* Tarjetas con relieve: sin el `detalle` que nombraba la fuente (retirado el
   2026-09-10), la cifra sola sobre el fondo de la sección se quedaba plana.
   El relieve —superficie propia, sombra corta hacia abajo, borde fino— es lo
   que ahora hace de tarjeta sin necesitar esa segunda línea de texto. Sólo
   los contadores lo llevan: las tarjetas de «El problema» comparten `.cifra`
   pero no `.contadores`, y siguen planas. */
.contadores .cifra {
  padding: 28px 26px 26px;
  background: var(--fondo-alt);
  border: 1px solid color-mix(in srgb, var(--texto) 10%, transparent);
  border-radius: 14px;
  box-shadow: 0 14px 30px -24px color-mix(in srgb, var(--texto) 70%, transparent);
}

.etiqueta-icono {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* El sello de antigüedad del recuento. Sustituye al pie que decía «se
   recuenta una vez al día», retirado el 2026-09-10: dice lo mismo con tres
   palabras y, al calcularse sobre la fecha del JSON, no puede quedarse
   obsoleto. El punto late para que la cifra se lea como algo que se mantiene,
   no como una lápida — pero late despacio: el recuento es diario, y un
   parpadeo rápido insinuaría tiempo real. */
.cifra-sello {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 12px;
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--texto-tenue);
}
.cifra-latido {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--acento);
  animation: cifra-latido 3.4s ease-in-out infinite;
}
@keyframes cifra-latido {
  0%, 72%, 100% { opacity: 0.35; transform: scale(1); }
  80% { opacity: 1; transform: scale(1.25); }
}
@media (prefers-reduced-motion: reduce) {
  .cifra-latido { animation: none; opacity: 0.8; }
}

/* ── Una sección centrada ───────────────────────────────────────────────
   «Protocolos» pasa a ir al eje central el 2026-09-10, para que la caja de
   consulta se lea como la pantalla de arranque de un asistente. Es la única
   sección así: las otras abren todas por la izquierda.

   ⚠️ `text-align: center` baja por herencia hasta donde no debe. Lo que es
   documento o campo de escritura se devuelve a la izquierda un poco más
   abajo: un textarea con el texto centrado se lee como un error, y una
   portada de protocolo con las secciones centradas no parece un documento. */
.bloque-centrado .env { text-align: center; }
.bloque-centrado .entradilla,
.bloque-centrado .consulta,
.bloque-centrado .nota { margin-inline: auto; }
/* El filete de la nota marca un margen izquierdo que aquí no existe. */
.bloque-centrado .nota { border-left: 0; padding-left: 0; }
.bloque-centrado .etiqueta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.bloque-centrado .consulta-ejemplos { justify-content: center; }
/* De vuelta a la izquierda: se escribe y se lee, no se contempla. */
.bloque-centrado .consulta-campo,
.bloque-centrado .consulta-respuesta,
.bloque-centrado .flujo-prompt,
.bloque-centrado .flujo-doc { text-align: left; }

/* La cabecera —etiqueta, titular, entradilla— es la excepción de toda la
   sección: Julio la prefiere a la izquierda mientras el resto va al centro.
   `max-width` frena la línea a lo que medía antes de heredar el ancho
   completo del centrado, que la dejaba corriendo de borde a borde. */
.bloque-centrado .protocolos-cabecera { text-align: left; }
.bloque-centrado .protocolos-cabecera .entradilla { margin-inline: 0; max-width: 56ch; }

/* ── Protocolos: la caja de consulta ────────────────────────────────────
   Va desconectada hasta que exista el servicio (`consulta.api` en
   contenido.js). El estado de espera lo lleva el isotipo de la casa.

   La caja es UNA superficie —campo arriba, mando dentro abajo— y no un campo
   con el botón al lado: es el patrón de los prompts de IA, y con él la pieza
   se lee como un sitio donde se escribe una pregunta en vez de como un
   buscador. De ahí salen las dos cosas que rompen el lenguaje anguloso del
   resto de la página, y las dos son deliberadas: el radio grande de la caja y
   las píldoras redondas. Bajadas a los 2-3 px de la casa, el componente deja
   de reconocerse.

   Ya no hay tarjeta envolviendo el conjunto: la caja es la única superficie, y
   etiqueta, píldoras, respuesta y nota van sobre el fondo de la sección. */
.consulta {
  margin-top: 72px;
  max-width: 760px;
}

.consulta-caja {
  background: var(--fondo-alt);
  border: 1px solid color-mix(in srgb, var(--texto) 12%, transparent);
  border-radius: 16px;
  transition: border-color 0.18s;
}
/* El foco lo lleva la caja entera y no el campo: dentro hay dos elementos
   enfocables, y dos anillos seguidos se leen como un error de dibujo. */
.consulta-caja:focus-within {
  border-color: color-mix(in srgb, var(--acento) 60%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 12%, transparent);
}

/* Es un textarea: crece con el texto hasta el tope y ahí pasa a llevar barra.
   El alto lo escribe `montarConsulta`; estos dos valores son los topes. */
.consulta-campo {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 54px;
  max-height: 180px;
  resize: none;
  border: 0;
  background: none;
  color: var(--texto);
  font-family: var(--tipo-cuerpo);
  font-size: 15.5px;
  line-height: 1.5;
  padding: 15px 16px 2px;
}
.consulta-campo::placeholder { color: var(--texto-tenue); }
.consulta-campo:focus,
.consulta-campo:focus-visible { outline: none; }

/* El mando, dentro de la caja: el contador donde el componente de referencia
   pone el clip de adjuntar —que aquí no existe— y la flecha a la derecha. */
.consulta-mando {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 8px 8px 17px;
}
/* En mono, que es donde la casa pone las cifras: la Averox del repo no trae
   números. Ver wiki/marca.md. */
.consulta-cuenta {
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
  font-variant-numeric: tabular-nums;
}
.consulta-enviar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--texto) 18%, transparent);
  background: none;
  color: var(--texto-tenue);
  cursor: pointer;
  transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.consulta-enviar svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.consulta-enviar:disabled { cursor: default; }
/* Encendida = hay pregunta escrita. La tinta es --fondo y no --fondo-alt: sobre
   el acento del tramo claro da 4,89:1 medido, y el gris claro se quedaría
   corto. */
.consulta-enviar:not(:disabled) {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--fondo);
}
.consulta-enviar:not(:disabled):hover {
  background: color-mix(in srgb, var(--acento) 84%, var(--texto));
  border-color: color-mix(in srgb, var(--acento) 84%, var(--texto));
}

/* Las preguntas de ejemplo, en píldora. No son etiquetas de sector, así que no
   heredan de `.ficha`: en versales se leerían como si gritaran. El icono lo
   elige el `eje` de cada ejemplo en contenido.js. */
.consulta-ejemplos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.consulta-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--texto) 14%, transparent);
  border-radius: 999px;
  background: none;
  color: var(--texto-tenue);
  padding: 8px 15px;
  font-family: var(--tipo-cuerpo);
  font-size: 13.5px;
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s, background 0.18s;
}
.consulta-chip svg {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}
.consulta-chip:hover {
  color: var(--acento);
  border-color: color-mix(in srgb, var(--acento) 70%, transparent);
  background: color-mix(in srgb, var(--acento) 7%, transparent);
}

/* El isotipo trae la paleta de los componentes del repo —azules grisáceos
   claros— y sobre el fondo de la caja (#F2F7FA) se pierde. No se repinta el
   módulo, que lo comparte la barra sobre fondo oscuro, donde funciona tal
   cual: se oscurece aquí, que es el único sitio donde falla. Ver
   wiki/marca.md, que ya avisaba de que el símbolo arrastra su propio sistema
   de color mientras la decisión de marca siga abierta. */
.tono-claro .consulta-respuesta .isotipo { filter: brightness(0.58) saturate(1.2); }

/* Vacía no ocupa sitio: sin :empty la caja reservaría un hueco muerto. */
.consulta-respuesta {
  font-size: 15px;
  line-height: 1.55;
  color: var(--texto-tenue);
  margin-top: 20px;
  min-height: 22px;
}
.consulta-respuesta:empty { margin-top: 0; min-height: 0; }
.consulta-respuesta.pensando {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--tipo-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}
.consulta .nota { margin-top: 18px; }

/* ── Tarjetas ──────────────────────────────────────────────────────────── */

.tarjeta {
  border-top: 1px solid color-mix(in srgb, var(--texto) 14%, transparent);
  padding-top: 26px;
}
.tarjeta h3 { margin: 0 0 14px; }
.tarjeta > p { color: var(--texto-tenue); font-size: 15.5px; }

.lista { list-style: none; margin: 22px 0 0; padding: 0; }
.lista li {
  font-size: 14.5px;
  color: var(--texto-tenue);
  padding: 9px 0 9px 20px;
  position: relative;
  border-top: 1px solid color-mix(in srgb, var(--texto) 7%, transparent);
  line-height: 1.5;
}
.lista li::before {
  content: "";
  position: absolute; left: 2px; top: 17px;
  width: 5px; height: 1px; background: var(--acento);
}

.nota {
  margin-top: 20px;
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--texto-tenue);
  border-left: 1px solid color-mix(in srgb, var(--acento) 42%, transparent);
  padding-left: 12px;
}

/* ── Sección con efecto de fondo ───────────────────────────────────────── */

.escena {
  position: relative;
  min-height: 108vh;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.escena-lienzo { position: absolute; inset: 0; z-index: 0; }
.escena-texto { position: relative; z-index: 2; width: 100%; }
.escena::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(
    to right,
    color-mix(in srgb, var(--fondo) 82%, transparent) 0%,
    transparent 56%
  );
}

/* El velo de la escena general se apaga al 56 % del ancho, que llegaba justo
   cuando el texto era una entradilla corta. Aquí la columna crece —dos filas
   de logotipos y seis fichas de sector— y pasa del 70 %: sin estirar el velo,
   las marcas y las fichas se leen sobre las figuras del grafo. Se estira solo
   en esta sección para no apagar la escena de la subpágina, que sí es corta. */
/* 🔴 Y la costura de arriba, que NO es un olvido de CSS.
   `efectos/cuerpo/grafo.js` pide el renderer con `alpha: true` y limpia con
   `setClearColor(0x000000, 0)`, pero encima monta un `EffectComposer` para el
   bloom — y un composer PRESENTA OPACO: su último paso escribe el negro del
   render target sobre todo el lienzo. Por eso la escena se ve negra donde no
   hay figuras aunque `body` sea --fondo, y por eso el filo superior era un
   escalón seco. Medido antes de tocarlo, a 1440 px y en x=1300 (donde el velo
   lateral ya es transparente):

     luminancia justo encima del filo   39,7 / 255
     luminancia justo debajo             2,1 / 255
     escalón en UNA fila                37,6 / 255

   Se tapa con una segunda capa `to bottom` de 220 px sobre el mismo pseudo: no
   hace falta elemento nuevo, ni tocar el grafo, ni cambiar --fondo. Las paradas
   son el smootherstep (6t⁵−15t⁴+10t³) de `.hero-disolucion`, y por el mismo
   motivo documentado allí: con la recta de dos colores el ojo caza los codos y
   aparecen tres líneas donde había una.

   La capa de la costura va PRIMERA, o sea encima: en el filo tiene que ganar
   ella —opaca y del color de la sección de arriba— y no el velo lateral, que
   en el flanco derecho es transparente y dejaría el escalón intacto. */
.escena-marcas::after {
  background:
    linear-gradient(
    to bottom,
    color-mix(in srgb, var(--fondo) 100.0%, transparent) 0.00%,
    color-mix(in srgb, var(--fondo) 98.4%, transparent) 12.50%,
    color-mix(in srgb, var(--fondo) 89.6%, transparent) 25.00%,
    color-mix(in srgb, var(--fondo) 72.5%, transparent) 37.50%,
    color-mix(in srgb, var(--fondo) 50.0%, transparent) 50.00%,
    color-mix(in srgb, var(--fondo) 27.5%, transparent) 62.50%,
    color-mix(in srgb, var(--fondo) 10.4%, transparent) 75.00%,
    color-mix(in srgb, var(--fondo) 1.6%, transparent) 87.50%,
    color-mix(in srgb, var(--fondo) 0.0%, transparent) 100.00%
  ) no-repeat top / 100% 220px,
    linear-gradient(
      to right,
      color-mix(in srgb, var(--fondo) 93%, transparent) 0%,
      color-mix(in srgb, var(--fondo) 88%, transparent) 44%,
      transparent 80%
    ) no-repeat top / 100% 100%;
}

@media (max-width: 720px) {
  /* A ancho de móvil la columna ocupa el 100 %, así que un velo lateral deja
     media sección sin cubrir y el texto cae sobre las figuras. Pasa a velo
     uniforme: aquí la escena ya es decoración, y la marca ajena tiene que
     leerse. */
  .escena-marcas::after {
    background:
      linear-gradient(
        to bottom,
        color-mix(in srgb, var(--fondo) 100.0%, transparent) 0.00%,
        color-mix(in srgb, var(--fondo) 98.4%, transparent) 12.50%,
        color-mix(in srgb, var(--fondo) 89.6%, transparent) 25.00%,
        color-mix(in srgb, var(--fondo) 72.5%, transparent) 37.50%,
        color-mix(in srgb, var(--fondo) 50.0%, transparent) 50.00%,
        color-mix(in srgb, var(--fondo) 27.5%, transparent) 62.50%,
        color-mix(in srgb, var(--fondo) 10.4%, transparent) 75.00%,
        color-mix(in srgb, var(--fondo) 1.6%, transparent) 87.50%,
        color-mix(in srgb, var(--fondo) 0.0%, transparent) 100.00%
      ) no-repeat top / 100% 160px,
      color-mix(in srgb, var(--fondo) 82%, transparent);
  }
}

/* ── Sectores ──────────────────────────────────────────────────────────── */

/* ── Marcas de terceros ─────────────────────────────────────────────────
   Los logotipos ajenos se pintan a UNA TINTA, y no es un capricho de estilo:
   hay ficheros oficiales que vienen en gris y Medsys en teal oscuro, y sobre
   el fondo de esta sección se apagan. Blanqueados se leen todos, la fila se
   lee como un conjunto y las paletas ajenas no
   compiten con la propia. Al pasar el ratón recuperan su peso completo.

   ⚠️ `invert(1)` da por hecho que la sección va sobre fondo OSCURO. Si algún
   día se mueve al tramo claro (`.tono-claro`), este filtro la deja invisible
   y hay que sustituirlo por brightness(0) a secas. */
.marcas { margin-top: 46px; display: grid; gap: 36px; }
.marcas .etiqueta { margin-bottom: 18px; }
.marcas-fila {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(30px, 4vw, 58px);
}
.marca { display: flex; align-items: center; gap: 13px; }
.marca img {
  width: auto;
  filter: brightness(0) invert(1);
  opacity: 0.72;
  transition: opacity 0.3s ease;
}
.marca:hover img { opacity: 1; }
.marca-nombre {
  font-size: 17px;
  color: var(--texto);
  opacity: 0.78;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.fichas { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 40px; }
.ficha {
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 9px 15px;
  border: 1px solid color-mix(in srgb, var(--texto) 16%, transparent);
  border-radius: 2px;
  color: var(--texto-tenue);
}

/* Marca visible de hueco pendiente. Está a propósito: la sección existe para
   que añadir logotipos después no obligue a rehacerla, y mientras tanto el
   hueco se ve. */
.pendiente {
  margin-top: 30px;
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--acento-alt) 82%, var(--texto));
  border: 1px dashed color-mix(in srgb, var(--acento-alt) 42%, transparent);
  border-radius: 2px;
  padding: 14px 18px;
  display: inline-block;
}

/* ── Cierre ────────────────────────────────────────────────────────────── */

.cierre { text-align: center; }
.cierre .display { margin-inline: auto; }
.cierre .entradilla { margin-inline: auto; text-align: center; }
.cierre .acciones { justify-content: center; }

.correo {
  display: inline-block;
  margin-top: 26px;
  font-family: var(--tipo-mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--texto-tenue);
  border-bottom: 1px solid color-mix(in srgb, var(--acento) 50%, transparent);
  padding-bottom: 3px;
  transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
}
.correo:hover { color: var(--acento); }

/* ── Institucional ─────────────────────────────────────────────────────── */

.institucional {
  border-top: 1px solid color-mix(in srgb, var(--texto) 10%, transparent);
  padding: 54px 0;
}
.institucional-fila {
  display: flex; align-items: center; gap: 34px; flex-wrap: wrap;
}
/* Los originales son JPEG con fondo blanco. Sobre fondo oscuro dejarían un
   recuadro, así que se invierten y desaturan. Es un parche: la wiki de marca
   recomienda rehacer la barra en SVG con los originales oficiales. */
.institucional img {
  max-width: 100%;
  height: auto;
  filter: invert(1) hue-rotate(180deg) saturate(0.15) brightness(1.08);
  opacity: 0.62;
  transition: opacity 0.4s;
}
.institucional img:hover { opacity: 0.85; }
.institucional .barra { max-height: 46px; }
.institucional .sello { max-height: 74px; }

/* ── Pie ───────────────────────────────────────────────────────────────── */

.pie {
  border-top: 1px solid color-mix(in srgb, var(--texto) 10%, transparent);
  padding: 44px 0 60px;
  display: flex;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--texto-tenue);
}
/* Logotipo oficial en 1 tinta blanco. Sobre la variante A se tiñe con el
   acento del sistema; sobre la B se deja en blanco, que es su versión. */
.pie-logo {
  display: block;
  height: 26px;
  width: auto;
  margin-bottom: 14px;
  opacity: 0.72;
}

.pie-enlaces { display: flex; gap: 22px; flex-wrap: wrap; }
.pie-enlaces a:hover { color: var(--texto); }

/* ── Aparición al hacer scroll ─────────────────────────────────────────── */

.revelar {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.revelar.visible { opacity: 1; transform: none; }

/* ── Accesibilidad ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .revelar { opacity: 1; transform: none; transition: none; }
  /* El hero deja de secuestrar el scroll y se queda en una pantalla. */
  .hero-pista { height: 100vh; }
  .nav-menu, .nav-punta { transition: none; }
}

:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 3px;
}

/* Distintivo de variante, solo para la revisión interna. */

/* ── El principio · rejilla de seis cuadros ───────────────────────────────
   Tres actos, dos cuadros cada uno. La rejilla no lleva separación interna:
   los cuadros de una fila comparten borde (el segundo se queda sin borde
   izquierdo), y entre filas hay 8px. Eso da el aspecto de tabla continua.  */

.principio .env {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vw, 80px);
}

.principio-cabecera {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
.principio-cabecera .etiqueta { margin: 0; }
.principio-cabecera h2 { margin: 0; }
.principio-cabecera .entradilla { margin: 0; max-width: 52ch; }

/* El bloque que remata el rótulo, como un cursor de terminal. */
.etiqueta .cursor {
  display: inline-block;
  width: 7px;
  height: 11px;
  margin-left: 8px;
  background: var(--acento);
  vertical-align: baseline;
}

.principio-cuerpo { display: flex; gap: 8px; align-items: flex-start; }

/* ── Los tres actos, que son anclas a sus filas ───────────────────────── */
.principio-actos {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 300px;
  flex: none;
  /* Acompaña al scroll: si no, marcar el acto activo no sirve de nada porque
     el raíl ya no está en pantalla cuando cambia. */
  position: sticky;
  top: 108px;
  align-self: flex-start;
}
.acto {
  display: flex;
  align-items: center;
  height: 48px;
  padding: 10px 22px;
  background: var(--fondo-hondo);
  border-left: 2px solid transparent;
  font-family: var(--tipo-mono);
  font-size: 10px;
  line-height: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  text-decoration: none;
  transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1), border-color 0.4s;
}
.acto:hover { color: var(--texto); }
/* El acento es claro: va como barra lateral, nunca como fondo con texto
   blanco encima —ahí no cumpliría contraste—. */
.acto.activo { color: var(--acento); border-left-color: var(--acento); }
.acto:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

/* ── La rejilla ───────────────────────────────────────────────────────── */
.principio-rejilla {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}
.fila { display: flex; gap: 0; scroll-margin-top: 90px; }

.cuadro {
  flex: 1 1 0;
  min-width: 0;
  height: 480px;
  padding: 30px 30px 16px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: var(--fondo-hondo);
  border: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
}
.cuadro + .cuadro { border-left-width: 0; }

.cuadro-texto h3 {
  font-family: var(--tipo-cuerpo);
  font-size: 16px;
  line-height: 1.1;
  font-weight: 400;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--texto);
  margin: 0 0 10px;
}
.cuadro-texto p {
  font-size: 14px;
  line-height: 1.4;
  color: var(--texto-tenue);
  margin: 0;
}

/* La pieza: el vídeo del cuadro. Viene ya con el fondo de la caja, así que no hay
   marco que disimular. */
.cuadro-pieza {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.cuadro-pieza video { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

/* Las dos piezas grandes de la home: fila entera, con el pairplot completo. */
.cuadro.ancho { height: auto; }
.cuadro.ancho .cuadro-texto { max-width: 78ch; margin-bottom: 18px; }
.cuadro.ancho .cuadro-pieza { display: block; }
.cuadro.ancho .cuadro-pieza video { width: 100%; max-height: none; }
.cuadro.ancho .cuadro-pie { margin-top: 14px; }
/* La pieza estrella se marca con el acento en el filo, como el raíl activo. */
.cuadro.estrella { border-left: 2px solid var(--acento); }

/* El texto va DENTRO de la figura, en la celda que el pairplot deja libre arriba a la
   derecha —justo donde el render escribía el rótulo que se ha quitado—. Medido sobre el
   GridSpec: esa celda va del 38,1 % al 98,5 % del ancho y del 4 % al 30,2 % del alto.
   ⚠️ Da para cuatro líneas a 13px; con cinco, la última pisa la etiqueta «Gen 2». */
.cuadro.en-hueco { position: relative; }
.cuadro.en-hueco .cuadro-texto {
  position: absolute;
  left: 40.5%;
  right: 4.5%;
  top: 8.5%;
  max-width: none;
  margin: 0;
  z-index: 1;
}
.cuadro.en-hueco .cuadro-texto p { font-size: 13px; line-height: 1.45; }

/* WCAG 2.2.2: los cuatro pasan de 5 s, así que cada uno lleva su control. */
.pausa {
  font-family: var(--tipo-mono);
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  background: none;
  border: 0;
  padding: 2px 6px;
  cursor: pointer;
}
.pausa:hover, .pausa:focus-visible { color: var(--acento); }
.pausa:focus-visible { outline: 1px solid var(--acento); outline-offset: 1px; }

/* El rótulo de cada parte. La línea que lo acompaña es lo que marca el corte
   entre una parte y la siguiente; el texto va en mono, como el resto de rótulos
   de la casa, y no compite con el titular de la sección. */
h2.rotulo-parte, h3.rotulo-parte {
  font-family: var(--tipo-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  margin: 0 0 22px;
  padding-bottom: 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
}

.cuadro-pie { display: flex; justify-content: space-between; align-items: center; }
.paso { display: flex; gap: 2px; }
.paso i {
  width: 7px;
  height: 11px;
  display: block;
  background: color-mix(in srgb, var(--texto-tenue) 45%, transparent);
}
.paso i.on { background: var(--acento); }
.num {
  font-family: var(--tipo-mono);
  font-size: 9px;
  letter-spacing: 0.05em;
  color: var(--texto-tenue);
}

.principio-cita { margin: 0; text-align: center; }
.principio-cita blockquote { margin: 0; }
.principio-cita p {
  font-family: var(--tipo-cuerpo);
  font-size: clamp(18px, 2vw, 24px);
  line-height: 1.42;
  font-weight: 300;
  font-style: italic;
  color: var(--texto);
  margin: 0;
  text-wrap: balance;
}
.principio-cita figcaption {
  display: block;
  margin-top: 18px;
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  font-style: normal;
  color: var(--texto-tenue);
}
.principio-cita cite { font-style: italic; }

/* ── Las dos lecturas: pestañas y paneles ─────────────────────────────
   La barra es horizontal, sin caja y con subrayado; el raíl de actos es
   vertical, con caja y barra lateral. Dos niveles de navegación, dos formas. */
.lentes { display: flex; flex-direction: column; gap: 24px; }

.pestanas {
  display: flex;
  gap: 32px;
  border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
}
.pestana {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin: 0 0 -1px;
  padding: 14px 0;
  font-family: var(--tipo-mono);
  font-size: 11px;
  line-height: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  cursor: pointer;
  transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1), border-color 0.4s;
}
.pestana:hover { color: var(--texto); }
.pestana.activa { color: var(--acento); border-bottom-color: var(--acento); }
.pestana:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

.panel { display: flex; flex-direction: column; }
/* `hidden` solo no gana a display:flex. */
.panel[hidden] { display: none; }

/* ── «Análisis»: la matriz de fases por plataformas ─────────────────────
   Cuatro pestañas de fase; en cada una, las tres plataformas en fila. Reutiliza
   `.lentes`, `.pestanas` y `.cuadro`, que ya existen — la sección no estrena
   componente, sólo los coloca en fila en vez de en columna.

   Los cuatro puntos fuertes van a CUATRO por fila y no a tres: con la rejilla
   global (`minmax(258px)`) el cuarto caía solo en una segunda fila y a doble
   ancho. A 230 son 4×230 + 3×32 = 1016 px en los 1112 del `.env`. */
.analisis-fuertes {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 32px;
  margin-top: clamp(40px, 5vh, 64px);
  /* Contiene el viaje de la entrada lateral (más abajo). Sin esto las tarjetas
     desplazadas ensanchan el documento 31-44px en los anchos donde el `.env`
     llena la ventana —medido a 1280, 1100, 820 y 390—: a 1440 sobra margen y
     no se nota, que es cómo se cuela. `body` lleva `overflow-x: hidden`, así
     que no sale barra, pero `scrollWidth` crece igual.

     `clip` y no `hidden`: `hidden` crearía un contenedor de scroll y forzaría
     el otro eje a `auto`; `clip` recorta sin más y deja `overflow-y` visible.
     Se recorta en el borde de la COLUMNA, no en el de la ventana, por dos
     razones: el efecto sale idéntico a cualquier ancho (si no, a 1440 el viaje
     se ve entero en el margen y a 1280 lo corta el body), y todo en esta
     página vive dentro del `.env` — que la cuarta asome desde el filo de la
     columna es el dialecto de la casa. Y así no se enmascara el desborde
     preexistente de `.pl-paso` en modo estrecho, que no es de este cambio. */
  overflow-x: clip;
}
.analisis-fuertes .tarjeta h3 { font-size: 18px; margin: 0 0 10px; }
.analisis-fuertes .tarjeta p { color: var(--texto-tenue); font-size: 15px; line-height: 1.55; }

/* Las cuatro entran deslizándose desde la derecha y FRENAN en su sitio, en vez
   de subir las 22px de `.revelar`. Cuatro cosas medidas, no elegidas:

   · La opacidad (0,5 s) dura menos de la mitad que el recorrido (1,05 s). Con
     las dos a la misma duración —que es lo que hace `.revelar`— la tarjeta
     llega casi opaca al final del recorrido y el deslizamiento no se lee: se
     ve aparecer, no entrar. Así se ve entrar la mitad del trayecto.
   · El frenado es `cubic-bezier(0.16, 1, 0.3, 1)`, la curva del resto de la
     página. No hace falta inventar otra: ya es una exponencial de salida y
     gasta el 80 % del recorrido en el primer tercio del tiempo, que es
     exactamente «entra rápido y frena».
   · El escalonado va POR FILA, y los cortes están medidos sobre la propia
     rejilla (`repeat(auto-fit, minmax(230px, 1fr))`), no elegidos:

         ≥ 1132px  4 columnas   (rejilla 1015px)
       840-1128px  3 columnas   (752px)
       548- 836px  2 columnas   (489px)
        ≤  544px  1 columna

     Importa porque cada tarjeta lleva su PROPIO `.revelar` y su propia entrada
     del observer: las de una misma fila cruzan el umbral en el mismo frame y
     el retardo las escalona, pero una tarjeta que está en otra fila dispara en
     otro momento de scroll — y entonces el retardo no escalona nada, es un
     tiempo muerto en el que la tarjeta ya está en pantalla y quieta. En el
     tramo de tres columnas (840-1128px: ventana a media pantalla, tableta en
     horizontal) la cuarta se quedaría 330ms plantada a la derecha antes de
     arrancar, ya visible.

   Reconstruido el 2026-09-13: se perdió sin commitear el 2026-09-10, sobre-
   escrito en el árbol de trabajo compartido antes de que nadie lo commiteara.
   Ver la nota gemela en `comun/contenido.js`. */
@media (prefers-reduced-motion: no-preference) {
  .analisis-fuertes .tarjeta.revelar {
    transform: translateX(clamp(56px, 9vw, 130px));
    transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                transform 1.05s cubic-bezier(0.16, 1, 0.3, 1);
  }
  /* Explícita a la fuerza: `.revelar.visible` (0,2,0) pierde contra la regla de
     arriba (0,3,0) y la tarjeta se quedaría corrida para siempre. */
  .analisis-fuertes .tarjeta.revelar.visible { transform: none; }
  @media (min-width: 548px) {
    .analisis-fuertes .tarjeta.revelar:nth-child(2),
    .analisis-fuertes .tarjeta.revelar:nth-child(4) { transition-delay: 0.11s; }
  }
  @media (min-width: 840px) {
    .analisis-fuertes .tarjeta.revelar:nth-child(2) { transition-delay: 0.11s; }
    .analisis-fuertes .tarjeta.revelar:nth-child(3) { transition-delay: 0.22s; }
    .analisis-fuertes .tarjeta.revelar:nth-child(4) { transition-delay: 0s; }
  }
  @media (min-width: 1132px) {
    .analisis-fuertes .tarjeta.revelar:nth-child(4) { transition-delay: 0.33s; }
  }
}

/* El cuadro de plataforma, dentro de «Análisis». Su propio tema y sus reglas
   viven en efectos/plataforma/plataforma.css: aquí sólo se le da el sitio. */
.analisis-cuadro { margin-top: clamp(48px, 6vh, 80px); }
.analisis-cuadro + .nota { margin-top: 22px; max-width: 74ch; }

/* Texto sólo para lector de pantalla. */
.oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── La tabla de diferencias ──────────────────────────────────────────── */
.diferencias { min-width: 0; }
.tabla-diferencias {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.tabla-diferencias thead th {
  padding: 0 14px 14px;
  font-family: var(--tipo-mono);
  font-size: 10px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  text-align: left;
  vertical-align: bottom;
  border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
}
.tabla-diferencias thead th:first-child { width: 15%; }
.tabla-diferencias tbody th,
.tabla-diferencias tbody td {
  padding: 18px 14px;
  vertical-align: top;
  text-align: left;
  border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
}
.tabla-diferencias th:first-child,
.tabla-diferencias td:first-child { padding-left: 0; }
.tabla-diferencias tbody th {
  font-family: var(--tipo-cuerpo);
  font-size: 15px;
  line-height: 1.2;
  font-weight: 400;
  color: var(--texto);
}
.tabla-diferencias tbody td {
  font-family: var(--tipo-cuerpo);
  font-size: 13.5px;
  line-height: 1.42;
  color: var(--texto-tenue);
}
.tabla-diferencias .refs {
  font-family: var(--tipo-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
  vertical-align: super;
  line-height: 0;
}
/* La fila propia: el acento va como barra lateral, nunca como fondo. */
.tabla-diferencias .propia th,
.tabla-diferencias .propia td { background: var(--fondo-hondo); color: var(--texto); }
.tabla-diferencias .propia th { padding-left: 14px; border-left: 2px solid var(--acento); }
.tabla-diferencias .propia .cursor {
  display: inline-block;
  width: 7px;
  height: 11px;
  margin-left: 8px;
  background: var(--acento);
  vertical-align: baseline;
}

.diferencias-pie {
  font-family: var(--tipo-mono);
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  margin: 18px 0 0;
}
.diferencias-nota {
  font-family: var(--tipo-mono);
  font-size: 10px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  color: var(--texto-tenue);
  max-width: 72ch;
  margin: 12px 0 0;
}
.diferencias-fuentes {
  font-family: var(--tipo-mono);
  font-size: 10px;
  line-height: 1.7;
  letter-spacing: 0.05em;
  color: var(--texto-tenue);
  max-width: 72ch;
  margin: 24px 0 0;
  padding-left: 2.2em;
}
.diferencias-fuentes li::marker { color: var(--texto-tenue); }

@media (max-width: 1080px) {
  .cuadro.en-hueco .cuadro-texto { position: static; margin-bottom: 18px; }
  .cuadro.en-hueco .cuadro-texto p { font-size: 14px; line-height: 1.4; }
  .tabla-diferencias tbody td { font-size: 13px; }
}

/* ── La home: dos bloques bajo el raíl ────────────────────────────────
   El proceso (las tres filas y el pie de simulación) y la tabla breve, que
   se ven al bajar. Los id de ancla viven en los bloques, no en las filas. */
.bloque-principio { display: flex; flex-direction: column; gap: 8px; scroll-margin-top: 90px; }
.bloque-principio + .bloque-principio { margin-top: 32px; }

/* ── «El problema», la tercera parte ────────────────────────────────────
   Entró aquí el 2026-09-05, desde el tramo claro. Su rejilla de cifras NO cabe
   con los valores globales, y no por poco: el cuerpo de la sección es
   `raíl 300px + gap 8px` dentro de un `.env` de 1112, así que la columna mide
   804. La global pide `minmax(258px)` con gap de hasta 64 →
   3×258 + 2×64 = 902 px. Con `auto-fit` eso no aprieta: rompe a 2 + 1, y la
   tercera tarjeta se queda sola y a doble ancho.
   Con 220 y 32 son 724 px, 80 de holgura. Sólo aquí dentro: la rejilla global
   la usan los contadores de Protocolos, que sí tienen el ancho entero. */
.principio-cuerpo .rejilla-3 {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 32px;
  margin-top: 48px;
}
/* La entradilla de la sección mide 46ch contra el ancho completo; en la columna
   estrecha eso deja una mancha muy alta y estrecha. */
.principio-cuerpo .entradilla { max-width: 54ch; margin-top: 18px; }

/* 🔴 Y la cifra tiene que bajar de cuerpo, por la misma razón de fondo: crece con
   `3.2vw` pero su columna DEJA DE CRECER en cuanto `.env` topa con sus 1240 px.
   A partir de ahí la columna se queda en 246,7 px y la cifra sigue subiendo
   hasta 46, así que «20 → 1.733» —diez caracteres de mono— pedía 269 px y partía
   en dos líneas. Medido en navegador: con 46 px van dos líneas, con 39,68 px una.

     ancho de la cadena  =  5,847 × font-size     (mono, diez caracteres)
     cabe si             =  5,847 × F ≤ 246,7  →  F ≤ 42,2 px

   Se topa en 40 y quedan 12,8 px de holgura. La regla global no se toca: los
   contadores de Protocolos tienen el ancho entero y cifras más cortas. */
.principio-cuerpo .cifra .n { font-size: clamp(28px, 2.9vw, 40px); }

/* El pie de ISO 27001. Venía de «Cómo lo hacemos defendible» y vive aquí desde
   que esa sección se retiró: es el único sitio de la web que dice que la
   certificación está en curso (restricciones.md §2). */
.nota-iso { margin-top: 34px; max-width: 62ch; }

/* ── La tabla breve: una palabra por celda ─────────────────────────── */
.tabla-diferencias.breve thead th:first-child { width: 26%; }
.tabla-diferencias.breve tbody th,
.tabla-diferencias.breve tbody td { padding: 14px; }
.tabla-diferencias.breve th:first-child,
.tabla-diferencias.breve td:first-child { padding-left: 0; }
.tabla-diferencias.breve .propia th { padding-left: 14px; }
.tabla-diferencias.breve tbody td { font-size: 14px; line-height: 1.35; }

/* Un enlace de remate, en el mono del raíl: «Ver en detalle →». */
.enlace-mas {
  display: inline-block;
  margin-top: 18px;
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--acento);
  text-decoration: none;
  transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
}
.enlace-mas:hover { color: var(--texto); }
.enlace-mas:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.tarjeta .enlace-mas { margin-top: 14px; }

/* ── Subpágina: cabecera de página ─────────────────────────────────────
   No hay hero: la barra fija (108px) queda encima y la cabecera se separa
   sola. La sección que sigue va pegada, sin su padding superior. */
.pagina-cabecera { padding: clamp(150px, 24vh, 240px) 0 clamp(40px, 6vw, 72px); }
.pagina-cabecera .env { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.pagina-cabecera .etiqueta,
.pagina-cabecera h1 { margin: 0; }
.pagina-cabecera .entradilla { margin: 0; max-width: 52ch; }
.pagina-cabecera + .principio { padding-top: 0; }

/* ── Titulares letra a letra ──────────────────────────────────────────── */
.palabra { display: inline-block; white-space: nowrap; }
.letra {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.32em);
  animation: letra-entra 0.62s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  /* Congelada hasta que el bloque entra en pantalla: si corre al cargar, se
     acaba en el primer segundo detrás de un `.revelar` todavía invisible. */
  animation-play-state: paused;
}
.revelar.visible .letra { animation-play-state: running; }
@keyframes letra-entra { to { opacity: 1; transform: none; } }

/* ── Estrecho ─────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .principio-cuerpo { flex-direction: column; }
  /* Los actos pasan a tira horizontal desplazable. */
  .principio-actos {
    flex-direction: row;
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    position: sticky;
    top: 64px;
    z-index: 2;
    background: var(--fondo);
  }
  .acto { flex: 1 0 auto; border-left: 0; border-bottom: 2px solid transparent; }
  .acto.activo { border-left: 0; border-bottom-color: var(--acento); }
  .fila { flex-direction: column; }
  .cuadro { height: auto; min-height: 420px; }
  .cuadro + .cuadro { border-left-width: 1px; border-top-width: 0; }
  /* La barra de pestañas se queda arriba, encima del raíl pegajoso; no es pegajosa. */
  .pestanas { gap: 24px; overflow-x: auto; scrollbar-width: none; }
  /* La tabla pasa a fichas: una caja por familia, la columna como etiqueta. */
  .tabla-diferencias thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .tabla-diferencias,
  .tabla-diferencias tbody,
  .tabla-diferencias tr,
  .tabla-diferencias th,
  .tabla-diferencias td { display: block; }
  .tabla-diferencias tr {
    background: var(--fondo-hondo);
    border: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
    padding: 18px;
  }
  .tabla-diferencias tr + tr { margin-top: 8px; }
  .tabla-diferencias tbody th,
  .tabla-diferencias tbody td { padding: 0; border-bottom: 0; }
  .tabla-diferencias tbody th { font-size: 16px; margin-bottom: 14px; }
  .tabla-diferencias tbody td + td { margin-top: 12px; }
  .tabla-diferencias tbody td::before {
    content: attr(data-col);
    display: block;
    font-family: var(--tipo-mono);
    font-size: 9px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--texto-tenue);
    margin-bottom: 4px;
  }
  .tabla-diferencias .propia { border-left: 2px solid var(--acento); }
  .tabla-diferencias .propia th { padding-left: 0; border-left: 0; }
  /* La breve hereda las fichas; sus paddings de escritorio no deben ganar. */
  .tabla-diferencias.breve tbody th,
  .tabla-diferencias.breve tbody td { padding: 0; }
  .tabla-diferencias.breve .propia th { padding-left: 0; }
}

/* ── La tabla breve, en desplegables (móvil) ────────────────────────────
   Por debajo de 720px la tabla breve de la home no se pinta: la sustituyen
   cuatro desplegables, uno por pregunta. El porqué, las medidas y la regla de no
   generalizar en nombre de «el resto» están en `plegablesDiferencias()`
   (landing.js).

   Cerrados, cada uno lleva ya la respuesta de la casa con el mismo filo de
   acento que la fila propia de escritorio: se lee la diferencia sin tocar.
   Abierto, aparecen las otras ocho familias.

   El panel no es adorno: tapa el fondo fijo con el isotipo, que sin él se
   transparenta entre las líneas y cruza el texto (visto en el A55).

   El chevrón NO se enciende en acento al abrir: el acento marca lo nuestro y los
   datos, no el cromo — la misma regla que el cuadro de «Análisis». */
.plegables { display: none; }

@media (max-width: 720px) {
  .diferencias .tabla-diferencias.breve { display: none; }

  .plegables {
    display: block;
    background: var(--fondo-hondo);
    border: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
  }
  .plegable + .plegable {
    border-top: 1px solid color-mix(in srgb, var(--texto-tenue) 16%, transparent);
  }

  .plegable summary {
    list-style: none;
    cursor: pointer;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 10px 16px;
    padding: 16px;
    -webkit-tap-highlight-color: transparent;
  }
  .plegable summary::-webkit-details-marker { display: none; }
  .plegable summary:focus-visible {
    outline: 1px solid var(--texto);
    outline-offset: -1px;
  }

  .plegable-pregunta {
    grid-column: 1;
    grid-row: 1;
    font-family: var(--tipo-mono);
    font-size: 10px;
    line-height: 1.5;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--texto-tenue);
  }

  /* El chevrón: dos filos de un cuadrado girado. Apunta abajo cerrado y arriba
     abierto; se dibuja con bordes para heredar el trazo fino del resto. */
  .plegable summary::after {
    content: "";
    grid-column: 2;
    grid-row: 1;
    width: 7px;
    height: 7px;
    margin-right: 3px;
    border-right: 1.5px solid var(--texto-tenue);
    border-bottom: 1.5px solid var(--texto-tenue);
    transform: translateY(-2px) rotate(45deg);
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .plegable[open] summary::after {
    border-color: var(--texto);
    transform: translateY(2px) rotate(-135deg);
  }

  /* La respuesta de la casa, siempre a la vista. */
  .plegable-nuestra {
    grid-column: 1 / -1;
    grid-row: 2;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 10px 12px;
    border-left: 2px solid var(--acento);
    background: var(--fondo);
  }
  .plegable-nuestra .plegable-familia { font-size: 12px; color: var(--texto-tenue); }
  .plegable-nuestra .plegable-valor { font-size: 15px; color: var(--texto); text-align: right; }

  /* Las otras ocho, sangradas bajo la nuestra para que se lean como su contraste. */
  .plegable-lista {
    list-style: none;
    margin: 0;
    padding: 2px 16px 14px 30px;
  }
  .plegable-lista li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 8px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--texto-tenue) 10%, transparent);
    font-size: 13px;
    line-height: 1.35;
  }
  .plegable-lista li:last-child { border-bottom: 0; }
  .plegable-lista .plegable-familia { color: var(--texto-tenue); }
  .plegable-lista .plegable-valor { color: var(--texto); text-align: right; flex: none; max-width: 48%; }

  /* Al abrir, las ocho entran en cascada corta: 28ms entre filas, 0,2s en total. */
  .plegable[open] .plegable-lista li {
    animation: plegable-entra 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: calc(var(--i, 0) * 28ms);
  }
}

@keyframes plegable-entra {
  from { opacity: 0; transform: translateY(-4px); }
}

@media (max-width: 720px) and (prefers-reduced-motion: reduce) {
  .plegable summary::after { transition: none; }
  .plegable[open] .plegable-lista li { animation: none; }
}

/* ── La franja del proceso (subpágina «Datos sintéticos») ─────────────────
   Tres tiempos —la muestra, la estimación, la cohorte— con el motor de puntos,
   entre la barra fija y la cabecera de texto. Vive en efectos/proceso/. Mide
   unas dos barras y media: el texto tiene que verse debajo sin hacer scroll.
   `--alto-barra` la fija landing.js midiendo la barra real; 89px es la medida
   a 1440 y el valor de respaldo. */
.proceso-franja {
  position: relative;
  margin-top: var(--alto-barra, 89px);
  height: clamp(200px, 26vh, 260px);
  overflow: hidden;
  background: radial-gradient(
    124% 84% at 50% 44%,
    color-mix(in srgb, var(--acento) 11%, var(--fondo)) 0%,
    var(--fondo) 52%,
    var(--fondo-hondo, var(--fondo)) 100%
  );
}
.proceso-lienzo { position: absolute; inset: 0; }
.proceso-vineta {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(82% 66% at 50% 48%, transparent 58%,
    color-mix(in srgb, var(--fondo-hondo, #000) 72%, transparent) 100%);
}
/* La franja no termina: se disuelve, con el mismo degradado del hero —dos
   smoothsteps encadenadas, primero el negro sobre el lienzo y luego el negro al
   fondo— a su escala. Sin esto el borde inferior saltaba de (17,16,24) a
   (40,38,55) en dos píxeles, medido. Se superpone al final de la franja (margen
   negativo) y desborda un poco sobre la cabecera, como `.hero-disolucion`. */
.proceso-disolucion {
  --disolucion-negro: color-mix(in srgb, var(--fondo-hondo) 62%, #000);
  --alto-disolucion: clamp(56px, 7vh, 78px);
  position: relative;
  z-index: 1;
  height: var(--alto-disolucion);
  margin-top: calc(-1 * var(--alto-disolucion));
  pointer-events: none;
}
/* El degradado desborda sobre la cabecera: el texto tiene que quedar por encima. */
.pagina-cabecera { position: relative; z-index: 2; }

/* Con la franja delante, la cabecera ya no necesita compensar la barra fija.
   El selector colgaba de `.proceso-rotulos`, que se retiró el 2026-09-03; ahora
   cuelga de la disolución, que es el hermano inmediato. */
.proceso-disolucion + .pagina-cabecera { padding-top: clamp(28px, 4vh, 40px); }

@media (max-width: 720px) {
  .cuadro { min-height: 360px; padding: 22px 22px 14px; }
  .cuadro-pieza { min-height: 170px; }
  .tabla-diferencias tr { padding: 16px; }
  .pagina-cabecera { padding-top: 120px; }
  .proceso-disolucion + .pagina-cabecera { padding-top: 24px; }
}

/* Sin movimiento: el titular se pinta entero y las escenas quedan quietas. */
@media (prefers-reduced-motion: reduce) {
  .letra { opacity: 1; transform: none; animation: none; }
}

/* ── Las páginas legales ───────────────────────────────────────────────
   Documentos de texto: una columna de ancho de lectura, no el ancho de
   `.env`. Todo con tokens de tema.css — ni un color literal. */
.legal-cabecera .env { gap: 12px; }

.legal-meta {
  display: flex;
  align-items: baseline;
  gap: 20px;
  flex-wrap: wrap;
  margin: 0;
  font-family: var(--tipo-mono);
  font-size: 12px;
  color: var(--texto-tenue);
}

.legal-idioma { color: var(--acento); border-bottom: 1px solid transparent; }
.legal-idioma:hover { border-bottom-color: var(--acento); }

.legal { padding: 0 0 clamp(80px, 12vh, 160px); }

.legal-cuerpo {
  max-width: 72ch;
  font-size: 16px;
  line-height: 1.7;
  color: var(--texto-tenue);
}

.legal-cuerpo p { margin: 0 0 18px; }

.legal-titulo {
  font-family: var(--tipo-cuerpo);
  font-size: 17px;
  font-weight: 700;
  color: var(--texto);
  margin: 38px 0 14px;
}
.legal-titulo:first-child { margin-top: 0; }

.legal-lista { margin: 0 0 18px; padding-left: 22px; }
.legal-lista li { margin: 0 0 8px; }

/* La nota de traducción no oficial. Se lee antes que el documento, así que va
   con borde de acento y no como una nota al pie. */
.legal-aviso {
  max-width: 72ch;
  margin: 0 0 36px;
  padding: 14px 18px;
  border-left: 2px solid var(--acento);
  background: var(--fondo-hondo);
  font-size: 14px;
  line-height: 1.6;
  color: var(--texto-tenue);
}

@media (max-width: 720px) {
  .legal-cuerpo { font-size: 15px; }
}

.legal-referencia {
  max-width: 72ch;
  margin: 36px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--fondo-hondo);
  font-family: var(--tipo-mono);
  font-size: 12px;
  color: var(--texto-tenue);
}

/* ── El fondo de móvil: el isotipo, quieto y en segundo plano ───────────
   Sustituye al hero por debajo de 720px. Lo monta `iniciar()` en
   `comun/landing.js`; aquí solo va la caja.

   `fixed` para que acompañe todo el scroll, `z-index: 0` para quedarse
   detrás de todo, y `pointer-events: none` porque es decoración: si captura
   toques, se come los del contenido que tiene encima. */
.fondo-iso-movil {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Segundo plano de verdad. Por encima de ~0.5 el símbolo le disputa la
     pantalla al titular, que es justo lo que veníamos a arreglar. */
  opacity: 0.55;
}

/* El contenido monta por encima del fondo. Sin esto, `position: fixed` en el
   fondo lo dejaría tapando las secciones que no crean contexto de apilado. */
@media (max-width: 720px) {
  .nav, footer, main, section, .pagina-cabecera { position: relative; z-index: 1; }

  /* El decorado del hero se va con el hero. `.hero-fondo` es su degradado y
     `.hero-vineta` la viñeta que oscurece los bordes, y las dos siguen
     pintándose aunque la escena ya no se monte en estrecho: la viñeta va a
     z-index 3, por encima del fondo fijo, y lo lavaba hasta hacerlo
     invisible. Medido: con ellas puestas el símbolo no se veía. */
  .hero-fondo, .hero-vineta { display: none; }

  /* ── El hero en móvil ──────────────────────────────────────────────────
     Por debajo de 720px el hero NO se monta (lo sustituye el fondo fijo con el
     isotipo), así que no hay coreografía de scroll que alimentar: la pista de
     320vh eran 2.410px vacíos en un Galaxy A55. Aquí el hero mide lo que mide su
     contenido, con la pantalla como mínimo.

     ⚠️ Estas reglas van AQUÍ, al final, a propósito. Pisan reglas base de la misma
     especificidad que están más arriba —`.hero-fijo { display:grid }`,
     `.hero-lienzo { position:absolute }`, `.hero-pista-abajo { display:flex }` y
     el `.hero-pista { height:100vh }` de `prefers-reduced-motion`—. Puestas antes
     perdían `display` y `position` en silencio; medido, el lienzo ocupaba la
     pantalla entera y tapaba el texto.

     En columna: la curva, y debajo el texto. Pedido por Julio el 2026-09-14 sobre
     su teléfono: la gaussiana en el hueco que dejaba el texto centrado.

     `svh` y no `vh`: en Chrome de Android `100vh` es la ventana SIN la barra de
     direcciones (810px en el A55) y `100svh` la que se ve al llegar (753). Se
     resta la barra porque en móvil no flota: es `position:relative` (arriba) y
     ocupa sus 77px de flujo. `--alto-barra` lo pone landing.js midiéndola. */
  .hero-pista { height: auto; }
  .hero-fijo {
    height: auto;
    min-height: calc(100svh - var(--alto-barra, 77px));
    display: flex;
    flex-direction: column;
  }

  /* Alto propio con tope, no el sobrante. Con `flex:1` la curva recibía lo que
     dejara el texto: 34px en un 360×640 y 341 en un 412×915, donde tocaba el
     rótulo con 1px de margen. El motor encuadra por el alto, así que el tope es
     también el que impide que se salga por los lados. Por debajo de 100px no se
     monta (landing.js). */
  .hero-lienzo {
    position: relative;
    inset: auto;
    flex: none;
    width: 100%;
    height: clamp(120px, 22svh, 190px);
  }

  /* La disolución del hero vive ENCIMA del final del hero (margin-top negativo
     igual a su alto). A 46vh eran 373px de degradado en el A55: apagaba las notas
     y dejaba los dos botones casi invisibles —«Cómo funciona» ya se veía tenue
     antes de todo esto—. En móvil se acorta, y el texto reserva ese alto debajo
     de los botones: el degradado cae sobre espacio vacío. */
  .hero-disolucion { height: 16svh; margin-top: -16svh; }
  .hero-texto { flex: none; padding-bottom: calc(16svh + 20px); }

  /* «Desliza» invita a una coreografía que en móvil no existe, y pisaba los
     botones: en un 360×640 iba de 625 a 683 y los botones acababan en 651. */
  .hero-pista-abajo { display: none; }
}

/* ── Los cuadros de vídeo, en pestañas (móvil) ──────────────────────────
   En la home, por debajo de 720px, los cuatro cuadros de «El principio» se
   conmutan de uno en uno. El porqué y cómo, en `filasCuadros` (landing.js).

   ⚠️ Va al final del fichero a propósito: pisa `.cuadro + .cuadro` del bloque de
   900px, que tiene la misma especificidad. Con un solo cuadro a la vista, el que
   sale detrás de otro en el DOM se quedaba sin filo superior. */
.cuadros-pestanas { display: none; }

@media (max-width: 720px) {
  .cuadros-pestanas {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    /* El hueco de 1px deja ver el borde: las cuatro celdas quedan rayadas
       como una tabla sin pintar líneas. */
    background: color-mix(in srgb, var(--texto-tenue) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--texto-tenue) 20%, transparent);
    border-bottom: 0;
    /* Pegada al cuadro, como su pestaña: anula el gap de 8px del bloque. */
    margin-bottom: -8px;
  }
  .cuadro-pestana {
    appearance: none;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 48px;
    padding: 10px 12px;
    border: 0;
    background: var(--fondo-hondo);
    color: var(--texto-tenue);
    font-family: var(--tipo-mono);
    font-size: 10px;
    line-height: 1.35;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  /* El mismo cuadrito que `.paso i`: apagado, y en acento el que se ve. */
  .cuadro-pestana::before {
    content: "";
    flex: none;
    width: 7px;
    height: 11px;
    background: color-mix(in srgb, var(--texto-tenue) 45%, transparent);
  }
  .cuadro-pestana.activa { color: var(--texto); background: var(--fondo); }
  .cuadro-pestana.activa::before { background: var(--acento); }
  .cuadro-pestana:focus-visible { outline: 1px solid var(--texto); outline-offset: -2px; }

  .cuadro.fuera-de-pestana { display: none; }
  /* Las filas se disuelven: con un cuadro a la vista no hay nada que alinear. */
  .bloque-principio .cuadros-pestanas ~ .fila { display: contents; }
  .bloque-principio .cuadros-pestanas ~ .fila .cuadro { border-top-width: 1px; }
  .bloque-principio .cuadros-pestanas ~ .fila .cuadro:not(.estrella) { border-left-width: 1px; }
}
