/* ==========================================================================
   1. ESTILOS GLOBALES
   Las fuentes están en comunes.css
   ========================================================================== */

/* Rojo de grabación: el REC y los tallies del ecosistema y del proceso */
:root {
  --rojo-rec: #e5484d;
}

/* Reserva siempre el hueco de la barra de scroll */
html {
  scrollbar-gutter: stable;
  scroll-behavior: smooth; /* el indicador de scroll baja suave hasta el contacto; reset.css lo anula con "reducir movimiento" */
}

body {
  font-family: Jost-Regular, system-ui, sans-serif;
  background-color: #000000;
  color: #ffffff;

  /* Sin width: 100vw (sumaría la barra de scroll) ni height fijo (cortaría el contenido en pantallas bajas) */
  min-height: 100svh; /* en móvil descuenta la barra del navegador; si no lo soporta se queda con 100vh */

  /* Cabecera, contacto y pie en columna; el reparto del alto está en header y footer */
  display: flex;
  flex-direction: column;
  align-items: center;
}

a {
  text-decoration: none;
}

/* Cabecera y pie se reparten el espacio libre 0.9 : 1, así el contacto queda algo por encima del centro
   (centro óptico). Sin padding vertical: con flex-basis 0 se sumaría aparte y movería el contacto;
   va en margin de sus hijos */
header{
    flex: 0.9 1 0;
    width: 100%; /* 100% y no 100vw: 100vw incluye la barra de scroll y provoca scroll horizontal */
    }

main{
    width: 100%;
    overflow-x: clip; /* lo que un SVG asome por los lados (latidos, etiquetas) no ensancha la página; sin crear scroll */
    display: flex;
    flex-direction: column;
    gap: clamp(5rem, 16vh, 10rem); /* cada sección es su propio bloque: aire de sobra entre ellas */
    padding-inline: 1rem;
    padding-block: clamp(0.5rem, 3vh, 2rem); /* separación mínima con cabecera y pie; mínimo bajo para que quepa en móviles en horizontal (~360px de alto) sin scroll */
    }

footer{
    flex: 1 1 0;
    width: 100%;
    }

/* ==========================================================================
   2. COMPONENTES
   ========================================================================== */

  /* La cabecera (logo + haz de luz) está en comunes.css, compartida con las páginas legales */

  /* Ecosistema: misma estructura que el contacto (título y texto; la red a la derecha en pantallas anchas).
     Título y texto comparten estilos con el contacto, más abajo */
  .ecosistema{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(2rem, 5vh, 3rem);
    max-width: 62rem;
    margin-inline: auto;
    margin-top: clamp(2rem, 8vh, 4rem); /* aleja el título del haz de luz del logo */
    padding-bottom: calc(2.75rem + clamp(0.5rem, 2svh, 1.5rem) + 0.75rem); /* alto y margen del indicador de scroll + aire: nunca se solapan */
    text-align: center;
    position: relative; /* el indicador de scroll se coloca respecto a la sección */
  }

  .ecosistema__cuerpo{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: 36rem; /* líneas largas pero cómodas de leer (unos 70 caracteres) */
  }

  /* Red del set (la dibuja ecosistema.js) con el REC y el timecode debajo */
  .ecosistema__red{
    --rec: 1; /* respiración de la grabación (de 1 a 0, la marca ecosistema.js): la comparten el REC del pie y los tallies */

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    width: min(100%, 26rem); /* todo el ancho disponible en móvil (las etiquetas son pequeñas); 100% y no vw: vw no descuenta márgenes ni la barra de scroll */
    margin: 0; /* <figure> trae márgenes por defecto */
    container-type: inline-size; /* los textos del SVG se ajustan a su ancho con cqw */
  }

  .ecosistema__svg{
    width: 100%;
    height: auto;
    overflow: visible; /* el latido y un equipo que se aleja pueden salirse un poco del viewBox */
    -webkit-tap-highlight-color: transparent; /* sin recuadro azul al tocar en móvil */
  }

  .ecosistema__nube,
  .proceso__nube{
    pointer-events: none;
  }

  /* Enlaces: cada tipo con su trazo.
     Red en curva continua (de módulo a módulo); acceso punteado y tenue (de cada pantalla a su módulo);
     local, fino (de un módulo a los equipos que lleva) */
  .ecosistema__enlace{
    fill: none;
    stroke-width: 0.75;
    transition: stroke 300ms ease-out, opacity 600ms ease-out;
  }

  /* --brillo (de 0 a 1, lo marca ecosistema.js): el tramo se enciende al cruzarlo un dato y se apaga despacio */
  .ecosistema__enlace--red{
    --brillo: 0;
    stroke: rgba(255, 255, 255, calc(0.2 + 0.5 * var(--brillo)));
    stroke-width: calc(0.6 + 0.5 * var(--brillo));
    stroke-linecap: round;
  }

  .ecosistema__enlace--acceso{
    stroke: rgba(255, 255, 255, 0.3);
    stroke-dasharray: 1 3;
    stroke-linecap: round;
  }

  .ecosistema__enlace--local{
    stroke: rgba(255, 255, 255, 0.22);
  }

  .ecosistema__enlace--activo{
    stroke: rgba(255, 255, 255, 0.85);
  }

  /* Enlace perdido (módulo fuera de alcance): se desvanece */
  .ecosistema__enlace--cortado{
    opacity: 0.06;
  }

  .ecosistema__paquete{
    fill: #ffffff;
  }

  .ecosistema__paquete--control{
    fill: rgba(255, 255, 255, 0.55); /* el control es secundario: la señal manda */
  }

  .ecosistema__nodo{
    cursor: pointer;
    transition: opacity 300ms ease-out;
  }

  /* Módulos: punto blanco algo apagado y un halo fino que también es la zona de hover.
     Los halos del proceso y del sistema se dibujan igual */
  .ecosistema__punto,
  .proceso__punto,
  .sistema__punto{
    fill: rgba(255, 255, 255, 0.85);
    transition: fill 300ms ease-out, filter 300ms ease-out;
  }

  .ecosistema__halo,
  .proceso__halo,
  .sistema__halo{
    fill: rgba(0, 0, 0, 0.6); /* tapa las líneas bajo el nodo y recibe el hover aunque no se vea */
    stroke: rgba(255, 255, 255, 0.2);
    stroke-width: 0.75;
    transition: stroke 300ms ease-out;
  }

  /* Monitorización: cuadradito hueco, como una pantalla (en el proceso, tumbado sobre su capa) */
  .ecosistema__zona{
    fill: transparent;
  }

  .ecosistema__pantalla,
  .proceso__pantalla{
    fill: rgba(0, 0, 0, 0.85); /* tapa las líneas que llegan */
    stroke: rgba(255, 255, 255, 0.75);
    stroke-width: 1;
    transition: stroke 300ms ease-out, filter 300ms ease-out;
  }

  /* Latido del timecode: un aro que se abre en todos los nodos a la vez */
  .ecosistema__latido{
    fill: none;
    stroke: #ffffff;
    stroke-width: 0.9;
    pointer-events: none;
  }

  /* Tally: piloto de grabación de los equipos que graban; respira con el REC del pie, también si se alejan (siguen grabando) */
  .ecosistema__tally,
  .proceso__tally,
  .sistema__tally{
    fill: var(--rojo-rec);
    opacity: calc(0.45 + 0.55 * var(--rec));
  }

  .ecosistema__nodo--caido .ecosistema__halo{
    stroke-dasharray: 2 2;
  }

  /* Sin enlace brilla más: es lo que se mira cuando un equipo se aleja */
  .ecosistema__nodo--caido .ecosistema__tally{
    filter: drop-shadow(0 0 2px var(--rojo-rec));
  }

  /* Nombre pequeño en versalitas espaciadas, como el subtítulo del logo; el dato solo con hover */
  .ecosistema__etiqueta,
  .ecosistema__dato{
    text-anchor: middle;
    pointer-events: none;
    /* Contorno negro pintado bajo la letra: las líneas que pasan por detrás se cortan y el nombre se lee limpio */
    paint-order: stroke;
    stroke: #000000;
    stroke-width: 3px;
    stroke-linejoin: round;
  }

  /* El SVG encoge con la pantalla y sus textos con él: el tamaño (en unidades del viewBox) crece
     cuanto más estrecha es la red, para que en móvil no bajen de unos 8px reales */
  .ecosistema__etiqueta{
    font-family: Jost-Regular;
    font-size: clamp(8.5px, 15px - 1.5cqw, 11px);
    letter-spacing: 0.16em;
    fill: rgba(255, 255, 255, 0.55);
    transition: fill 300ms ease-out;
  }

  .ecosistema__dato{
    font-family: Jost-Light;
    font-size: clamp(8.5px, 15px - 1.5cqw, 11px);
    fill: rgba(255, 255, 255, 0.75);
    opacity: 0;
    transition: opacity 300ms ease-out;
  }

  /* Foco: con un nodo señalado, el resto se apaga y el elegido muestra su dato */
  .ecosistema__svg--enfocado .ecosistema__nodo:not(.ecosistema__nodo--activo){
    opacity: 0.3;
  }

  .ecosistema__nodo--activo .ecosistema__punto{
    fill: #ffffff;
    filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.8));
  }

  .ecosistema__nodo--activo .ecosistema__halo{
    stroke: rgba(255, 255, 255, 0.6);
  }

  .ecosistema__nodo--activo .ecosistema__pantalla{
    stroke: #ffffff;
    filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.7));
  }

  .ecosistema__nodo--activo .ecosistema__etiqueta{
    fill: #ffffff;
  }

  .ecosistema__nodo--activo .ecosistema__dato{
    opacity: 1;
  }

  /* Equipos que cuelgan de un módulo (las petacas): un punto pequeño, más tenue que el de los módulos */
  .ecosistema__nodo--equipo .ecosistema__punto{
    fill: rgba(255, 255, 255, 0.55);
  }


  /* Timecode: discreto y quieto, cifras de ancho fijo para que no baile al cambiar */
  .ecosistema__timecode{
    font-family: Jost-Light;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.2em;
    color: rgba(255, 255, 255, 0.5);
  }

  /* REC del set: punto rojo con su propio ritmo, el de la grabación, a la vez que los tallies de los equipos */
  .ecosistema__rec{
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    margin-right: 0.5em;
    color: rgba(255, 255, 255, 0.6);
  }

  .ecosistema__rec::before{
    content: "";
    width: 0.5em;
    height: 0.5em;
    border-radius: 50%;
    background-color: var(--rojo-rec);
    box-shadow: 0 0 0.4em var(--rojo-rec);
    opacity: calc(0.45 + 0.55 * var(--rec));
  }

  /* Indicador de scroll: una flecha de luz que baja unos píxeles y se apaga, en bucle.
     Es un enlace a la pantalla siguiente (hay uno en el ecosistema y otro en el proceso); la flecha es su ::after. Solo CSS */
  .siguiente{
    --siguiente-alto: 2.75rem;
    --siguiente-margen: clamp(0.5rem, 2svh, 1.5rem);

    position: absolute;
    left: 50%;
    bottom: var(--siguiente-margen);
    translate: -50% 0;
    width: 2.75rem; /* 44px: zona táctil cómoda aunque la flecha sea pequeña */
    height: var(--siguiente-alto);
  }

  /* Flecha: un cuadradito con dos bordes (derecho e inferior) girado 45°, que forma una "v" con brillo */
  .siguiente::after{
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 0.875rem;
    height: 0.875rem;
    border-right: 1.5px solid #ffffff;
    border-bottom: 1.5px solid #ffffff;
    translate: -50% -75%;
    rotate: 45deg; /* translate (centrado y bajada) se aplica antes del giro: la flecha baja recta */
    filter: drop-shadow(0 0 0.25rem rgba(255, 255, 255, 0.8));
    opacity: 0; /* invisible hasta que arranca la animación */
    /* El último valor es el retardo: no aparece hasta 2s después de cargar, cuando ya se ha leído la pantalla */
    animation: siguiente-bajar 2.4s ease-in-out 2s infinite;
    transition: filter 250ms ease-out;
  }

  /* Aparece algo arriba, baja unos píxeles mientras se enciende y se apaga al llegar abajo */
  @keyframes siguiente-bajar{
    0%{ translate: -50% -110%; opacity: 0; }
    40%{ opacity: 0.9; }
    100%{ translate: -50% -10%; opacity: 0; }
  }

  .siguiente:hover::after,
  .siguiente:focus-visible::after{
    filter: drop-shadow(0 0 0.4rem #ffffff);
  }

  /* Ya se ha bajado al contacto (lo marca comunes.js): se apaga con un fundido y no vuelve.
     visibility, además, lo saca del orden de tabulación; su cambio espera a que acabe el fundido */
  .siguiente{
    transition: opacity 600ms ease-out, visibility 0s linear 0s;
  }

  .siguiente--visto{
    opacity: 0;
    visibility: hidden;
    transition: opacity 600ms ease-out, visibility 0s linear 600ms;
  }

  /* Sin animación ("reducir movimiento") la flecha se queda quieta y visible */
  @media (prefers-reduced-motion: reduce){
    .siguiente::after{
      animation: none;
      opacity: 0.7;
    }
  }

  .siguiente:focus-visible{
    outline: 2px solid #ffffff;
    outline-offset: 2px;
    border-radius: 0.25rem;
  }

  /* ==========================================================================
     PROBLEMA (en prueba): los silos del set y lo que cambia con un estado común. Lo dibuja problema.js
     Misma estructura que el ecosistema: texto y, en pantallas anchas, las pestañas y el dibujo a la derecha.
     Antetítulo, título y texto comparten estilos con las otras secciones (más abajo)
     ========================================================================== */
  .problema{
    --lectura: 1.2s; /* quieto al empezar cada estado: primero se lee, luego se mira */

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(2rem, 5vh, 3rem);
    width: 100%;
    max-width: 62rem;
    margin-inline: auto;
    padding-bottom: calc(2.75rem + clamp(0.5rem, 2svh, 1.5rem) + 0.75rem); /* hueco del indicador de scroll */
    text-align: center;
    position: relative; /* el indicador de scroll se coloca respecto a la sección */
  }

  .problema__cuerpo{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: 36rem;
  }

  /* Las pestañas y el dibujo, en columna y con el mismo ancho */
  .problema__lado{
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: min(100%, 26rem);
  }

  /* Pestañas Hoy / Con LUMEN: las de las fases de "Cómo funciona", con su línea encendida en la activa */
  .problema__pestanas{
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 0.75rem;
  }

  .problema__pestana{
    --duracion: 10s; /* lo que dura su estado: lectura, animación y un reposo para mirarla */

    padding: 0.625rem 0 0.25rem;
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    background: none;
    font-family: Jost-SemiBold;
    font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
    color: rgba(255, 255, 255, 0.45);
    text-align: left;
    cursor: pointer;
    transition: color 300ms ease-out, border-color 300ms ease-out;
  }

  .problema__pestana[data-estado="lumen"]{
    --duracion: 15s; /* más largo: al final salta el aviso de la petaca y hay que dejar leerlo */
  }

  .problema__pestana--activa{
    color: rgba(255, 255, 255, 0.92);
    border-top-color: rgba(255, 255, 255, 0.6);
  }

  @media (hover: hover){
    .problema__pestana:hover{
      color: #ffffff;
    }
  }

  .problema__pestana:focus-visible{
    outline: 2px solid #ffffff;
    outline-offset: 4px;
    border-radius: 0.25rem;
  }

  /* El reloj de cada estado: una animación invisible en la pestaña activa; problema.js cambia al terminar */
  .problema__progreso{
    display: block;
  }

  .problema__pestana--activa .problema__progreso{
    animation: problema-reloj var(--duracion) linear both;
  }

  @keyframes problema-reloj{
    from{ opacity: 1; }
    to{ opacity: 1; }
  }

  /* Pestaña elegida a mano (o sin movimiento): el reloj se para. Fuera de pantalla, todo espera */
  .problema--manual .problema__progreso{
    animation: none;
  }

  .problema--fuera .problema__progreso,
  .problema--fuera .problema__svg *{
    animation-play-state: paused !important; /* como en el proceso: las reglas de cada estado usan el atajo animation: */
  }

  .problema__silos{
    width: 100%;
    margin: 0; /* <figure> trae márgenes por defecto */
    container-type: inline-size; /* los textos del SVG se ajustan a su ancho con cqw */
  }

  .problema__svg{
    width: 100%;
    height: auto;
    overflow: visible;
  }

  /* Islas: el muro punteado de cada departamento; dentro, los iconos de la red */
  .problema__muro{
    fill: none;
    stroke: rgba(255, 255, 255, 0.28);
    stroke-width: 0.75;
    stroke-dasharray: 1 3;
    stroke-linecap: round;
  }

  .problema__rotulo,
  .problema__titulo-panel,
  .problema__dato{
    font-size: clamp(8.5px, 15px - 1.5cqw, 11px); /* misma escala que las etiquetas de la red */
    letter-spacing: 0.14em;
  }

  .problema__rotulo,
  .problema__titulo-panel{
    font-family: Jost-Regular;
  }

  .problema__rotulo{
    text-anchor: middle;
    fill: rgba(255, 255, 255, 0.55);
  }

  .problema__enlace{
    stroke: rgba(255, 255, 255, 0.28);
    stroke-width: 0.75;
  }

  /* El centro de cada sistema: una forma por marca. Producción, papel */
  .problema__centro{
    fill: rgba(0, 0, 0, 0.85);
    stroke: rgba(255, 255, 255, 0.75);
    stroke-width: 1;
    stroke-linejoin: round;
  }

  .problema__centro--papel{
    stroke: rgba(255, 255, 255, 0.55);
  }

  .problema__halo{
    fill: rgba(0, 0, 0, 0.6);
    stroke: rgba(255, 255, 255, 0.2);
    stroke-width: 0.75;
  }

  .problema__punto{
    fill: rgba(255, 255, 255, 0.85);
  }

  .problema__pantalla{
    fill: rgba(0, 0, 0, 0.85);
    stroke: rgba(255, 255, 255, 0.75);
    stroke-width: 1;
  }

  /* Barras de estado: batería o tarjeta de cada equipo, y los niveles del panel de estado */
  .problema__fondo-barra{
    fill: rgba(255, 255, 255, 0.12);
  }

  .problema__barra,
  .problema__nivel{
    fill: rgba(255, 255, 255, 0.6);
    transform-box: fill-box;
    transform-origin: left;
  }

  .problema__barra{
    scale: 0.6 1; /* con LUMEN, quietas: ya no hay sorpresas */
  }

  .problema__rec{
    fill: var(--rojo-rec);
    filter: drop-shadow(0 0 2px var(--rojo-rec));
  }

  /* Con LUMEN: cada isla baja a una sola línea de luz, sin centro, y de ella sale el dispositivo */
  .problema__bajada,
  .problema__toma,
  .problema__linea{
    fill: none;
    stroke-dasharray: 1; /* sobre pathLength="1": se dibujan de 0 a 1 */
  }

  .problema__bajada,
  .problema__toma{
    stroke: rgba(255, 255, 255, 0.38);
    stroke-width: 0.75;
  }

  .problema__linea{
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 1;
    filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5));
  }

  .problema__puerto{
    fill: rgba(255, 255, 255, 0.8);
  }

  /* Datos: un punto que recorre su trazo, como los paquetes de la red (el trazo no se ve: un guion casi nulo
     con punta redonda sobre pathLength="1", que stroke-dashoffset lleva de un extremo al otro) */
  .problema__paquete{
    fill: none;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-dasharray: 0.001 1;
    opacity: 0;
  }

  /* Por dentro de cada isla circulan siempre; el que intenta salir, solo hoy; los que bajan, solo con LUMEN */
  .problema__paquete--interno{
    animation: problema-recorrer 2.6s linear calc(var(--lectura) + var(--i) * 0.45s) infinite;
  }

  /* El dato que sale y su choque comparten ciclo y retardo: así el choque ocurre justo cuando llega */
  .problema__paquete--salida,
  .problema__golpe,
  .problema__onda{
    --choque: 3.2s linear calc(var(--lectura) + var(--i) * 0.3s) infinite;
  }

  .problema[data-estado="hoy"] .problema__paquete--salida{
    animation: problema-chocar var(--choque);
  }

  /* El choque contra el muro: un destello en el tramo golpeado y una onda que se abre hacia dentro y se
     desvanece */
  .problema__golpe,
  .problema__onda{
    fill: none;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 0.75;
    stroke-linecap: round;
    opacity: 0;
  }

  .problema__golpe{
    filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.6));
  }

  /* La onda crece desde el punto de choque, que es el lado de su caja pegado al muro */
  .problema__onda{
    transform-box: fill-box;
  }

  .problema__onda--izquierda{
    transform-origin: left;
  }

  .problema__onda--derecha{
    transform-origin: right;
  }

  .problema[data-estado="hoy"] .problema__golpe{
    animation: problema-golpe var(--choque);
  }

  .problema[data-estado="hoy"] .problema__onda{
    animation: problema-onda var(--choque);
  }

  .problema[data-estado="lumen"] .problema__paquete--bajada{
    animation: problema-recorrer 3.4s linear calc(var(--lectura) + 4s + var(--i) * 0.35s) infinite;
  }

  /* El dispositivo: un rectángulo neutro con bisel; dentro, un multivisor sobrio con todo el set */
  .problema__marco{
    fill: rgba(0, 0, 0, 0.85);
    stroke: rgba(255, 255, 255, 0.55);
    stroke-width: 1;
  }

  .problema__bisel{
    fill: none;
    stroke: rgba(255, 255, 255, 0.12);
    stroke-width: 0.75;
  }

  .problema__ventana{
    fill: #050506;
    stroke: rgba(255, 255, 255, 0.18);
    stroke-width: 0.75;
  }

  .problema__titulo-panel{
    fill: rgba(255, 255, 255, 0.85);
  }

  .problema__dato{
    font-family: Jost-Light;
    font-variant-numeric: tabular-nums;
    fill: rgba(255, 255, 255, 0.65);
  }

  .problema__dato--queda{
    text-anchor: end;
    fill: #ffffff;
  }

  .problema__encuadre{
    fill: none;
    stroke: rgba(255, 255, 255, 0.8);
    stroke-width: 1;
  }

  .problema__imagen{
    fill: none;
    stroke: rgba(255, 255, 255, 0.45);
    stroke-width: 1;
    stroke-linejoin: round;
  }

  .problema__vumetro{
    fill: rgba(255, 255, 255, 0.75);
    transform-box: fill-box;
    transform-origin: bottom; /* suben y bajan desde abajo */
    animation: problema-vumetro calc(0.6s + var(--k) * 0.25s) ease-in-out infinite alternate;
  }

  .problema__pista,
  .problema__relleno{
    stroke-width: 2;
    stroke-linecap: round;
  }

  .problema__pista{
    stroke: rgba(255, 255, 255, 0.15);
  }

  .problema__relleno{
    stroke: rgba(255, 255, 255, 0.8);
    transform-box: fill-box;
    transform-origin: left;
  }

  .problema__tirador{
    fill: #ffffff;
  }

  .problema__documento{
    fill: none;
    stroke: rgba(255, 255, 255, 0.55);
    stroke-width: 0.75;
  }

  /* --- Estados: data-estado (lo pone problema.js) enciende lo de cada uno --- */

  /* Hoy, las islas centradas en el dibujo; con LUMEN suben (tras la lectura) y dejan sitio al dispositivo */
  .problema__set{
    translate: 0 108px;
    transition: translate 1400ms cubic-bezier(0.45, 0, 0.25, 1);
  }

  .problema[data-estado="lumen"] .problema__set{
    translate: 0 0;
    transition-delay: var(--lectura);
  }

  .problema__muro,
  .problema__union,
  .problema__dispositivo{
    transition: opacity 900ms ease-in-out;
  }

  .problema[data-estado="lumen"] .problema__muro,
  .problema:not([data-estado="lumen"]) :is(.problema__union, .problema__dispositivo){
    opacity: 0;
  }

  /* La alarma no sale de la isla: cuando su barra se agota, su muro se tiñe de rojo un par de veces,
     al compás del parpadeo (1 s) */
  .problema[data-estado="hoy"] .problema__isla--aviso .problema__muro{
    animation: problema-alarma 1s ease-in-out calc(var(--lectura) + var(--agota)) 2;
  }

  /* Hoy: las barras bajan sin que nadie las vea; las que se agotan (--agota, de problema.js) acaban
     en rojo y parpadean, cada una dentro de su isla. Parpadeo de 1 s y --agota en segundos enteros:
     empiezan en momentos distintos, pero cuando coinciden parpadean exactamente a la vez */
  .problema[data-estado="hoy"] .problema__barra{
    animation: problema-gastar 7s linear var(--lectura) both;
  }

  .problema[data-estado="hoy"] .problema__barra--agotada{
    animation:
      problema-agotar var(--agota) linear var(--lectura) both,
      problema-parpadear 1s steps(1) calc(var(--lectura) + var(--agota)) infinite;
  }

  /* Con LUMEN: caen los muros, las islas bajan a la línea, la línea se enciende y aparece el dispositivo,
     panel a panel; al final alguien ajusta una luz desde él */
  .problema[data-estado="lumen"] .problema__bajada{
    animation: problema-dibujar 800ms ease-in-out calc(var(--lectura) + 1.6s + var(--i) * 0.2s) both;
  }

  .problema[data-estado="lumen"] .problema__linea{
    animation: problema-dibujar 1000ms ease-in-out calc(var(--lectura) + 2.4s) both;
  }

  .problema[data-estado="lumen"] .problema__puerto{
    animation: problema-aparecer 500ms ease-in-out calc(var(--lectura) + 2.4s + var(--i) * 0.15s) both;
  }

  .problema[data-estado="lumen"] .problema__toma{
    animation: problema-dibujar 500ms ease-in-out calc(var(--lectura) + 3.4s) both;
  }

  .problema[data-estado="lumen"] :is(.problema__marco, .problema__bisel){
    animation: problema-aparecer 700ms ease-in-out calc(var(--lectura) + 3.8s) both;
  }

  .problema[data-estado="lumen"] .problema__cabecera{
    animation: problema-aparecer 600ms ease-in-out calc(var(--lectura) + 4.4s) both;
  }

  .problema[data-estado="lumen"] .problema__rec{
    animation: problema-latir 1.7s ease-in-out calc(var(--lectura) + 5s) infinite;
  }

  .problema[data-estado="lumen"] .problema__panel{
    transform-box: fill-box;
    transform-origin: center;
    animation: problema-encajar 600ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(var(--lectura) + 4.6s + var(--i) * 0.3s) both;
  }

  .problema[data-estado="lumen"] .problema__nivel{
    animation: problema-llenar 900ms ease-out calc(var(--lectura) + 6.4s) both;
  }

  .problema[data-estado="lumen"] .problema__relleno--ajuste{
    animation: problema-ajustar-relleno 1000ms ease-in-out calc(var(--lectura) + 8s) both;
  }

  .problema[data-estado="lumen"] .problema__tirador--ajuste{
    animation: problema-ajustar-tirador 1000ms ease-in-out calc(var(--lectura) + 8s) both;
  }

  /* Con LUMEN, el aviso se ve: la batería de la petaca, que ya iba baja, se gasta a la vez en su isla y en su
     fila del dispositivo (--gasto) y, en el mismo instante (--aviso), las dos se ponen en rojo, y su punto también.
     forwards y no both: antes de empezar se ve como estaba, y al terminar se queda en rojo */
  .problema{
    --gasto: calc(var(--lectura) + 7.4s);
    --aviso: calc(var(--lectura) + 10.4s);
  }

  .problema__barra--avisa{
    scale: 0.22 1; /* con LUMEN ya llega baja */
  }

  .problema[data-estado="lumen"] .problema__barra--avisa{
    animation: problema-avisar 3s linear var(--gasto) forwards;
  }

  .problema[data-estado="lumen"] .problema__halo--avisa{
    animation: problema-halo-aviso 400ms ease-out var(--aviso) forwards;
  }

  .problema__queda--alerta{
    fill: var(--rojo-rec);
    opacity: 0;
  }

  .problema[data-estado="lumen"] .problema__queda--antes{
    animation: problema-ocultar 300ms ease-out var(--aviso) forwards;
  }

  .problema[data-estado="lumen"] .problema__queda--alerta{
    animation: problema-mostrar 300ms ease-out var(--aviso) forwards;
  }

  .problema[data-estado="lumen"] .problema__fila--avisa{
    animation: problema-tenir 300ms ease-out var(--aviso) forwards;
  }

  .problema[data-estado="lumen"] .problema__nivel--avisa{
    animation:
      problema-llenar 900ms ease-out calc(var(--lectura) + 6.4s) both,
      problema-nivel-aviso 3s linear var(--gasto) forwards;
  }

  /* Bajan en blanco y, justo al final, a rojo: el cambio de color cae en --aviso */
  @keyframes problema-avisar{
    from{ scale: 0.22 1; }
    99%{ fill: rgba(255, 255, 255, 0.6); }
    to{ scale: 0.08 1; fill: var(--rojo-rec); }
  }

  @keyframes problema-halo-aviso{
    to{ stroke: var(--rojo-rec); stroke-width: 1; filter: drop-shadow(0 0 3px var(--rojo-rec)); }
  }

  @keyframes problema-ocultar{
    to{ opacity: 0; }
  }

  @keyframes problema-mostrar{
    to{ opacity: 1; }
  }

  @keyframes problema-tenir{
    to{ fill: var(--rojo-rec); }
  }

  @keyframes problema-nivel-aviso{
    from{ scale: 1 1; }
    99%{ fill: rgba(255, 255, 255, 0.6); }
    to{ scale: 0.35 1; fill: var(--rojo-rec); }
  }

  @keyframes problema-aparecer{
    from{ opacity: 0; }
  }

  @keyframes problema-latir{
    50%{ opacity: 0.45; }
  }

  /* Recorre su trazo en algo más de la mitad del ciclo y espera apagado al siguiente */
  @keyframes problema-recorrer{
    0%{ stroke-dashoffset: 0; opacity: 0; }
    8%, 52%{ opacity: 0.85; }
    60%, 100%{ stroke-dashoffset: -1; opacity: 0; }
  }

  /* Acelera hacia la isla vecina, choca con el muro (48 %), rebota un poco y se apaga */
  @keyframes problema-chocar{
    0%{ stroke-dashoffset: 0; opacity: 0; animation-timing-function: cubic-bezier(0.5, 0, 1, 1); }
    10%{ opacity: 0.85; }
    48%{ stroke-dashoffset: -0.97; opacity: 0.85; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }
    60%, 100%{ stroke-dashoffset: -0.84; opacity: 0; }
  }

  @keyframes problema-golpe{
    0%, 47.5%{ opacity: 0; }
    48%{ opacity: 0.9; animation-timing-function: ease-out; }
    58%, 100%{ opacity: 0; }
  }

  @keyframes problema-onda{
    0%, 47.5%{ opacity: 0; scale: 0.2; }
    48%{ opacity: 0.8; scale: 0.2; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }
    60%, 100%{ opacity: 0; scale: 1; }
  }

  @keyframes problema-alarma{
    50%{ stroke: var(--rojo-rec); stroke-width: 1; }
  }

  /* Aviso de agotado: encendido y apagado, sin transición */
  @keyframes problema-parpadear{
    50%{ opacity: 0.15; }
  }

  @keyframes problema-dibujar{
    from{ stroke-dashoffset: 1; }
  }

  @keyframes problema-llenar{
    from{ scale: 0 1; }
  }

  @keyframes problema-encajar{
    from{ scale: 1.04; opacity: 0; }
  }

  @keyframes problema-gastar{
    from{ scale: 0.9 1; }
    to{ scale: 0.45 1; }
  }

  @keyframes problema-agotar{
    from{ scale: 0.35 1; }
    85%{ fill: rgba(255, 255, 255, 0.6); }
    to{ scale: 0.2 1; fill: var(--rojo-rec); }
  }

  @keyframes problema-vumetro{
    from{ scale: 1 0.25; }
  }

  /* KEY de 55 % a su valor: el relleno crece y el tirador se desplaza con él */
  @keyframes problema-ajustar-relleno{
    from{ scale: 0.7 1; }
  }

  @keyframes problema-ajustar-tirador{
    from{ translate: -17px 0; }
  }

  /* ==========================================================================
     SISTEMA: tres tarjetas, cada una con su peso: la app, grande, a la izquierda; a su derecha los satélites y,
     debajo, ATLAS, opcional y más tenue. La de los satélites se despliega en las de LYNX, CICADA y LAMPYR.
     Los dibujos los hace sistema.js.
     Antetítulo y título comparten estilos con las otras secciones (más abajo)
     ========================================================================== */
  .sistema{
    --lectura: 1.2s; /* quieto al empezar: primero se lee, luego se mira */
    --rec: 1; /* los tallies respiran con su propia animación */

    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(1.25rem, 3vh, 2.25rem);
    width: 100%;
    max-width: 74rem; /* más ancha que el resto: la app grande y, a su lado, las otras dos con su texto en líneas largas */
    margin-inline: auto;
    padding-bottom: calc(2.75rem + clamp(0.5rem, 2svh, 1.5rem) + 0.75rem); /* hueco del indicador de scroll, como en el proceso */
    text-align: center;
    position: relative; /* el indicador de scroll se coloca respecto a la sección */
  }

  .sistema__cabecera{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: 48rem; /* el título cabe en una línea */
    margin-bottom: clamp(0.25rem, 1.8vh, 1.25rem); /* las tarjetas, algo separadas del título */
  }

  /* En pantallas anchas el título cabe en una línea: el corte solo hace falta en columna estrecha */
  @media (min-width: 60rem){
    .sistema__titulo br{
      display: none;
    }
  }

  /* Tarjetas: sin JS, los dos grupos uno debajo del otro */
  .sistema__tarjetas{
    display: grid;
    gap: 1rem;
    width: 100%;
  }

  .sistema__grupo{
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(0.75rem, 2vw, 1.25rem);
    transition: opacity 500ms ease-out, visibility 0s linear 0s;
  }

  /* Con JS, los dos en la misma celda: el hueco es el del más alto y se ve uno cada vez, con un fundido */
  .sistema--js .sistema__grupo{
    grid-area: 1 / 1;
  }

  /* El grupo general: la app ocupa las dos filas de la izquierda; los satélites y ATLAS, una cada uno a la derecha */
  .sistema__grupo--general{
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); /* la derecha, algo más ancha: ahí van dos tarjetas con texto */
    grid-template-rows: auto auto;
  }

  /* La app, el producto estrella: ocupa las dos filas y su borde, algo más claro que el del resto */
  .sistema__tarjeta--app{
    grid-row: 1 / 3;
    justify-content: center;
    border-color: rgba(255, 255, 255, 0.22);
  }

  /* Desplegados, los tres satélites no se estiran hasta el alto del grupo general (con el que comparten hueco):
     quedan centrados, a la medida del más alto, y su dibujo aprovecha el sitio */
  .sistema__grupo--satelites{
    align-content: center; /* tarjetas y «Volver», juntos en el centro del hueco; las de una fila, igual de altas */
  }

  .sistema__grupo--satelites .sistema__dibujo{
    height: clamp(7rem, 24svh, 14rem);
  }

  .sistema__grupo[inert]{
    opacity: 0;
    visibility: hidden;
    transition: opacity 400ms ease-out, visibility 0s linear 400ms;
  }

  /* Cada tarjeta: un borde fino como el dispositivo del problema; arriba el dibujo, debajo el texto */
  .sistema__tarjeta{
    position: relative; /* el botón de desplegar la cubre entera con su ::after */
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: clamp(1rem, 2vw, 1.5rem);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 0.75rem;
    background-color: rgba(255, 255, 255, 0.015);
    text-align: left;
    transition: border-color 300ms ease-out;
  }

  /* El alto del dibujo sale del de la pantalla: en las bajas cede sitio al texto (el dibujo se centra en su hueco) */
  .sistema__dibujo{
    display: block;
    width: 100%;
    height: clamp(6rem, 17svh, 10rem);
    margin-bottom: 0.5rem;
    overflow: visible; /* el latido puede salirse un poco */
  }

  .sistema__cuerpo{
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
  }

  /* La app, la protagonista: su dibujo, el mayor de la sección */
  .sistema__tarjeta--app .sistema__dibujo{
    height: clamp(8rem, 34svh, 19rem);
  }

  /* Su texto no se estira: dibujo y texto quedan juntos, centrados en la tarjeta */
  .sistema__tarjeta--app .sistema__cuerpo{
    flex: none;
  }

  /* Satélites: el dibujo a la izquierda y el texto a la derecha */
  .sistema__tarjeta--satelites{
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
    align-items: center;
    gap: 1rem;
  }

  /* Su alto sale de su ancho, con tope según la pantalla: en columnas estrechas no deja hueco vacío */
  .sistema__tarjeta--satelites .sistema__dibujo{
    height: auto;
    max-height: clamp(5.5rem, 14.5svh, 11rem);
    margin-bottom: 0;
  }

  /* ATLAS, lo opcional: borde punteado y más tenue, para que se lea antes de leer la palabra.
     El texto a la izquierda y su dibujo a la derecha, grande: cuenta qué es y qué hace */
  .sistema__tarjeta--atlas{
    border-style: dashed;
    border-color: rgba(255, 255, 255, 0.18);
    background-color: transparent;
  }

  .sistema__tarjeta--atlas{
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
    align-items: center;
    gap: clamp(1rem, 2vw, 1.5rem);
  }

  .sistema__tarjeta--atlas > .sistema__dibujo{
    order: 2;
    height: auto;
    max-height: clamp(8rem, 26svh, 15rem);
    margin: 0;
  }

  /* En pantallas medianas (tablets) la columna de texto quedaría estrecha: texto arriba y dibujo debajo */
  @media (min-width: 40rem) and (max-width: 67.99rem){
    .sistema__tarjeta--atlas{
      display: flex;
    }

    .sistema .sistema__tarjeta--atlas > .sistema__dibujo{
      max-height: clamp(6rem, 13.5svh, 12rem);
    }
  }

  .sistema__nombre{
    font-family: Jost-SemiBold;
    font-weight: normal; /* cada peso de Jost es su propia fuente: sin negrita fingida */
    font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.92);
  }

  /* Al desplegar, el foco pasa al título de LYNX para que el lector de pantalla siga por ahí: sin recuadro */
  .sistema__nombre:focus{
    outline: none;
  }

  /* Su papel, al lado: versalitas tenues como el antetítulo */
  .sistema__papel{
    margin-left: 0.4em;
    font-family: Jost-Light;
    font-size: 0.6em;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
  }

  /* ™ pequeño y alto, para que acompañe al nombre sin pesar */
  .sistema__tm{
    margin-left: 0.1em;
    font-family: Jost-Regular;
    font-size: 0.5em;
    letter-spacing: 0;
    vertical-align: 0.9em;
  }

  .sistema__lema{
    font-size: clamp(0.9375rem, 0.9rem + 0.15vw, 1rem);
    color: rgba(255, 255, 255, 0.85);
  }

  .sistema__detalle{
    font-size: clamp(0.875rem, 0.85rem + 0.15vw, 0.9375rem);
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.6);
    text-wrap: pretty;
  }

  /* Desplegar y volver: discretos, en versalitas tenues como el botón del ecosistema; con su zona táctil de 44px */
  .sistema__desplegar,
  .sistema__volver{
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    min-height: 2.75rem;
    padding: 0;
    border: 0;
    background: none;
    font-family: Jost-Regular;
    font-size: clamp(0.6875rem, 0.65rem + 0.15vw, 0.75rem);
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
    cursor: pointer;
    transition: color 300ms ease-out;
  }

  .sistema__desplegar{
    align-self: flex-start;
    margin-top: auto; /* al pie de la tarjeta */
  }

  .sistema__desplegar[hidden],
  .sistema__volver[hidden]{
    display: none;
  }

  /* Toda la tarjeta de los satélites se puede pulsar, no solo el botón */
  .sistema__desplegar::after{
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
  }

  .sistema__desplegar:hover,
  .sistema__desplegar:focus-visible,
  .sistema__volver:hover,
  .sistema__volver:focus-visible{
    color: #ffffff;
  }

  .sistema__tarjeta:has(.sistema__desplegar:hover){
    border-color: rgba(255, 255, 255, 0.35);
  }

  .sistema__desplegar:focus-visible,
  .sistema__volver:focus-visible{
    outline: 2px solid #ffffff;
    outline-offset: 3px;
    border-radius: 0.25rem;
  }

  /* «Volver», tras las tres tarjetas de los satélites, en su mismo grupo: ocupa la fila entera, alineado a la izquierda */
  .sistema__volver{
    grid-column: 1 / -1;
    justify-self: start;
  }

  /* Pie: la nota */
  .sistema__pie{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    width: 100%;
  }

  /* Honesto y discreto: dice en qué punto está sin competir con las piezas */
  .sistema__nota{
    margin-left: auto;
    font-family: Jost-Light;
    font-size: clamp(0.75rem, 0.72rem + 0.1vw, 0.8125rem);
    color: rgba(255, 255, 255, 0.4);
  }

  /* Los rótulos del dibujo de ATLAS, algo mayores que en el resto: es más ancho y se ve más pequeño */
  .sistema__dibujo[data-dibujo$="atlas"] .sistema__etiqueta{
    font-size: 8px;
    letter-spacing: 0.1em;
  }

  /* Su nombre, bajo la caja: que se vea cuál es el equipo */
  .sistema__dibujo[data-dibujo="atlas"] .sistema__etiqueta--nombre{
    font-size: 10px;
  }

  /* Móvil: una columna con todo en una pantalla. Cada tarjeta, compacta y en horizontal: el dibujo a la izquierda y
     el texto a la derecha; en ATLAS, su escala arriba, a todo el ancho, y el texto debajo */
  @media (max-width: 39.99rem){
    .sistema__grupo,
    .sistema__grupo--general{
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: none;
      align-content: start;
      gap: clamp(0.375rem, 1.2svh, 0.75rem);
    }

    .sistema__tarjeta--app{
      grid-row: auto;
    }

    /* Todo se mide con el alto de la pantalla: en un iPhone SE se aprieta y en un móvil alto crece hasta llenarla */
    .sistema{
      gap: clamp(0.5rem, 1.8svh, 1.25rem);
    }

    .sistema__cabecera{
      margin-bottom: 0;
    }

    .sistema__tarjeta{
      display: grid;
      grid-template-columns: minmax(0, clamp(5.5rem, 15svh, 9rem)) minmax(0, 1fr); /* el dibujo, más ancho cuanto más alta es la pantalla */
      align-items: center;
      gap: 0.625rem;
      padding: clamp(0.5rem, 1.5svh, 1rem) 0.75rem;
    }

    /* El resumen de los satélites lo cuentan, mejor, sus tres tarjetas al desplegarse: en móvil, fuera */
    .sistema__tarjeta--satelites .sistema__detalle{
      display: none;
    }

    /* La app, en vertical: su dibujo arriba, bajo, y el texto a todo el ancho, que así ocupa menos líneas */
    .sistema__tarjeta--app{
      display: flex;
      gap: 0.5rem;
    }

    .sistema__tarjeta--app .sistema__dibujo{
      max-height: clamp(4rem, 8.5svh, 7rem);
    }

    .sistema__tarjeta--atlas{
      display: flex;
      gap: 0.5rem;
    }

    .sistema__tarjeta--atlas > .sistema__dibujo{
      order: 0;
    }

    .sistema__dibujo,
    .sistema__tarjeta--app .sistema__dibujo,
    .sistema__tarjeta--satelites .sistema__dibujo{
      height: auto;
      margin: 0;
    }

    .sistema .sistema__tarjeta--atlas .sistema__dibujo{
      max-height: clamp(7rem, 22svh, 11rem);
    }

    .sistema__grupo--satelites .sistema__dibujo{
      height: auto;
    }

    .sistema__cuerpo{
      gap: 0.25rem;
    }

    .sistema__nombre{
      font-size: 1rem;
    }

    .sistema__lema{
      font-size: 0.875rem;
    }

    .sistema .sistema__detalle{ /* dos clases: gana a la de poco alto, que va después */
      font-size: 0.8125rem;
      line-height: 1.45;
    }

    /* «Ver los tres», más discreto que el subtítulo: algo menor y menos espaciado */
    .sistema__desplegar{
      min-height: 2rem;
      font-size: 0.625rem;
      letter-spacing: 0.22em;
    }

    /* Aire entre el dibujo y el texto de las tarjetas en horizontal; algo más en la de los satélites, cuyos rótulos
       llegan al borde de su dibujo. Dos clases: la regla de poco alto, que va después, aprieta el hueco vertical */
    .sistema .sistema__tarjeta{
      column-gap: 1rem;
    }

    .sistema .sistema__tarjeta--satelites{
      column-gap: 1.375rem;
    }

    /* Al desplegar, el grupo oculto no guarda su sitio: sin hueco negro bajo los tres satélites.
       Y sus dibujos, algo mayores, para que las tres tarjetas llenen la pantalla */
    .sistema--js .sistema__grupo[inert]{
      display: none;
    }

    .sistema__grupo--satelites .sistema__tarjeta{
      grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
    }
  }

  /* Pantallas de poco alto y móviles: algo más apretado */
  @media (max-height: 50rem), (max-width: 39.99rem){
    .sistema{
      gap: 0.75rem;
    }

    .sistema__cabecera{
      gap: 0.5rem;
    }

    .sistema .sistema__titulo{ /* dos clases: la regla común de los títulos va después */
      font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.25rem);
    }

    .sistema__tarjeta{
      gap: 0.375rem;
      padding: 0.875rem 1rem;
    }

    .sistema__detalle{
      font-size: 0.875rem;
      line-height: 1.45;
    }
  }

  /* Escritorio de poco alto: el dibujo de la app, algo menor, para que quepan a su lado las otras dos */
  @media (min-width: 40rem) and (max-height: 50rem){
    .sistema__tarjeta--app .sistema__dibujo{
      height: clamp(8rem, 26svh, 17rem);
    }

    .sistema__tarjeta--atlas > .sistema__dibujo{
      max-height: clamp(7rem, 24svh, 13rem);
    }
  }

  /* Móvil: la letra de las tarjetas, un punto menor, y el dibujo de la app algo más bajo */
  @media (max-width: 39.99rem){
    .sistema__tarjeta--app .sistema__dibujo{
      max-height: clamp(4rem, 7.5svh, 7rem);
    }

    .sistema__nombre{
      font-size: 0.9375rem;
    }

    .sistema__lema{
      font-size: 0.8125rem;
    }

    .sistema .sistema__detalle{
      font-size: 0.75rem;
      line-height: 1.4;
    }
  }

  /* Móviles bajos (iPhone SE y similares): sin la nota del pie y el título en una línea */
  @media (max-width: 39.99rem) and (max-height: 46rem){
    .sistema{
      padding-bottom: 3rem; /* lo justo para el indicador de scroll */
    }

    .sistema__nota{
      display: none;
    }

    .sistema .sistema__titulo{ /* dos clases: la regla común de los títulos va después */
      font-size: 1.1875rem;
    }

    .sistema__titulo br{
      display: none;
    }

  }

  /* Móvil: el dibujo al lado del texto, en todas las tarjetas (también las de los satélites desplegados), para que
     cada vista quepa en una pantalla. Salvo ATLAS: su dibujo es muy apaisado y a un lado quedaría diminuto, así que
     va arriba, más bajo. Sin la nota del pie. Va al final: manda sobre los altos y maquetas de las reglas anteriores */
  @media (max-width: 39.99rem){
    .sistema .sistema__grupo .sistema__tarjeta:not(.sistema__tarjeta--atlas){
      display: grid;
      grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
      align-items: center;
      column-gap: 1rem;
    }

    .sistema .sistema__grupo .sistema__tarjeta:not(.sistema__tarjeta--atlas) .sistema__dibujo{
      width: 100%;
      height: auto;
      max-height: none;
      margin: 0;
    }

    /* La app tiene el texto más largo: algo más de ancho para él */
    .sistema .sistema__grupo .sistema__tarjeta--app:not(.sistema__tarjeta--atlas){ /* el :not iguala la especificidad de la regla anterior */
      grid-template-columns: minmax(0, 0.7fr) minmax(0, 1fr);
    }

    .sistema .sistema__tarjeta--atlas .sistema__dibujo{
      max-height: clamp(4.5rem, 9svh, 6.5rem);
    }

    .sistema .sistema__nota{
      display: none;
    }
  }

  /* Móviles de hasta ~830 px de alto (iPhone mini y más bajos): el título, en una línea, y algo menos de aire */
  @media (max-width: 39.99rem) and (max-height: 52rem){
    .sistema.sistema{
      gap: 0.5rem;
      padding-top: 0.75rem;
    }

    .sistema .sistema__tarjeta--atlas .sistema__dibujo{
      max-height: clamp(3.75rem, 9svh, 6.5rem);
    }

    .sistema .sistema__titulo{
      font-size: 1.1875rem;
    }

    .sistema__titulo br{
      display: none;
    }
  }

  /* Fuera de pantalla todo espera */
  .sistema--fuera .sistema__dibujo *{
    animation-play-state: paused !important;
  }

  /* --- Dibujos --- */

  /* Textos de los dibujos: tamaño fijo en unidades del dibujo, que crece con la tarjeta */
  .sistema__etiqueta,
  .sistema__dato,
  .sistema__rol{
    font-family: Jost-Regular;
    font-size: 7px;
    letter-spacing: 0.16em;
    fill: rgba(255, 255, 255, 0.7);
  }

  .sistema__etiqueta{
    text-anchor: middle;
    fill: rgba(255, 255, 255, 0.55);
  }

  /* Los nombres de los satélites en su tarjeta común: en blanco y seminegrita, que se lean antes que nada */
  .sistema__etiqueta--nombre{
    font-family: Jost-SemiBold;
    font-size: 9px;
    letter-spacing: 0.12em;
    fill: #ffffff;
  }

  .sistema__tm-dibujo{
    font-family: Jost-Regular;
    font-size: 4px;
    letter-spacing: 0;
  }

  .sistema__rol{
    font-family: Jost-SemiBold;
    fill: #ffffff;
  }

  .sistema__etiqueta--tenue{
    fill: rgba(255, 255, 255, 0.4);
  }

  /* Latido: los satélites a la vez y cada 3 s, como en la red: un mismo reloj */
  .sistema__latido{
    fill: none;
    stroke: #ffffff;
    stroke-width: 0.9;
    vector-effect: non-scaling-stroke; /* el aro crece sin engordar */
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
    animation: sistema-latido 3s ease-out var(--lectura) infinite;
  }

  /* Tallies y REC respiran juntos, al ritmo de la red */
  .sistema__tally,
  .sistema__rec{
    animation: sistema-respirar 1.7s ease-in-out infinite;
  }

  .sistema__rec{
    fill: var(--rojo-rec);
    filter: drop-shadow(0 0 2px var(--rojo-rec));
  }

  .sistema__lectura{
    fill: rgba(0, 0, 0, 0.85);
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.75;
  }

  /* Timecode: cifras de ancho fijo para que no baile al cambiar */
  .sistema__tc{
    font-family: Jost-Light;
    font-size: 9px;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.12em;
    text-anchor: middle;
    fill: rgba(255, 255, 255, 0.9);
  }

  /* La cámara que graba, en la tablet: su imagen con el borde rojo de REC, como en un monitor */
  .sistema__marco-rec{
    fill: none;
    stroke: var(--rojo-rec);
    stroke-width: 0.9;
    opacity: 0.85;
    animation: sistema-respirar 1.7s ease-in-out infinite;
  }

  /* El timecode en la cabecera de la tablet: pequeño, a la derecha, junto al REC */
  .sistema__tc--app{
    font-size: 6.5px;
    text-anchor: end;
    fill: rgba(255, 255, 255, 0.8);
  }

  /* Pantallas: la tablet y los móviles; trazo fino como el resto */
  .sistema__tablet,
  .sistema__movil{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.75);
    stroke-width: 1;
  }

  .sistema__cabecera-app{
    stroke: rgba(255, 255, 255, 0.2);
    stroke-width: 0.75;
  }

  .sistema__marco{
    fill: rgba(255, 255, 255, 0.03);
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.75;
  }

  .sistema__trazo{
    fill: none;
    stroke: rgba(255, 255, 255, 0.7);
    stroke-width: 0.9;
    stroke-linecap: round;
  }

  /* Lo que se ve en cada cámara: un paisaje o una figura, tenue, como en el problema */
  .sistema__escena{
    fill: none;
    stroke: rgba(255, 255, 255, 0.45);
    stroke-width: 0.7;
    stroke-linejoin: round;
  }

  /* Valores de los paneles del móvil: letra pequeña, cifras de ancho fijo */
  .sistema__mini{
    font-family: Jost-Regular;
    font-size: 4.6px;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.08em;
    fill: rgba(255, 255, 255, 0.8);
  }

  .sistema__mini--tenue{
    fill: rgba(255, 255, 255, 0.45);
  }

  /* El techo de los niveles (0 dB): una línea punteada muy tenue */
  .sistema__tope{
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.5;
    stroke-dasharray: 1 1.5;
  }

  /* Notas: renglones como barras, sin texto que leer */
  .sistema__renglon{
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 3;
    stroke-linecap: round;
  }

  .sistema__renglon--fino{
    stroke-width: 2;
  }

  /* Niveles de sonido: suben y bajan */
  .sistema__carril-nivel{
    fill: none;
    stroke: rgba(255, 255, 255, 0.25);
    stroke-width: 0.6;
  }

  .sistema__nivel{
    fill: rgba(255, 255, 255, 0.8);
    transform-box: fill-box;
    transform-origin: center bottom;
    animation: sistema-vumetro 1.1s ease-in-out calc(var(--i) * 0.25s) infinite alternate;
  }

  /* Faders de luz: el carril y el mando */
  .sistema__carril{
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.9;
    stroke-linecap: round;
  }

  .sistema__mando{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 1;
  }

  /* Dos valores que se alternan cada 3 s: el ISO que se cambia desde el móvil (LYNX) y la escena de luz (LAMPYR) */
  .sistema__alterna{
    animation: sistema-escena-1 6s ease-in-out var(--lectura) infinite;
  }

  .sistema__alterna--2{
    opacity: 0;
    animation-name: sistema-escena-2;
  }

  /* Líneas y datos: solo se ve el punto que recorre su línea, como en el problema; el control vuelve, más tenue */
  .sistema__enlace{
    fill: none;
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.75;
  }

  .sistema__paquete{
    fill: none;
    stroke: #ffffff;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-dasharray: 0.001 1;
    opacity: 0;
    animation: sistema-recorrer 3s linear calc(var(--lectura) + var(--retardo)) infinite;
  }

  .sistema__paquete--vuelta{
    stroke: rgba(255, 255, 255, 0.55);
    stroke-width: 1.6;
  }

  /* CICADA: la batería de los receptores, que baja despacio, y el parte, que se rellena fila a fila */
  .sistema__pila{
    fill: none;
    stroke: rgba(255, 255, 255, 0.6);
    stroke-width: 0.75;
  }

  .sistema__pila-borne{
    fill: rgba(255, 255, 255, 0.6);
  }

  .sistema__carga{
    fill: rgba(255, 255, 255, 0.8);
    transform-box: fill-box;
    transform-origin: left center;
    animation: sistema-gastar 9s ease-in-out calc(var(--i) * 1.5s) infinite alternate;
  }

  .sistema__fila{
    opacity: 0;
    animation: sistema-fila 8s ease-out calc(var(--lectura) + var(--i) * 1.2s) infinite both;
  }

  /* LAMPYR: los focos del grupo; su luz cambia a la vez, con la escena */
  .sistema__foco{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 1;
  }

  .sistema__foco-haz{
    fill: #ffffff;
    opacity: calc(var(--desde) * 0.35);
    filter: blur(2px);
    animation: sistema-foco 6s ease-in-out var(--lectura) infinite;
  }

  /* LUMEN: en la tablet, el panel del rol que se ve en el móvil se enciende a la vez que él */
  .sistema__resalte{
    fill: none;
    stroke: transparent;
    stroke-width: 0.9;
    animation: sistema-resaltar 10s linear calc(var(--lectura) + var(--i) * 2.5s) infinite both;
  }

  /* Cada rol, su turno de 2,5 s en el móvil: aparece, se queda y deja paso al siguiente */
  .sistema__vista{
    opacity: 0;
    animation: sistema-turno 10s linear calc(var(--lectura) + var(--i) * 2.5s) infinite both;
  }

  /* Sin movimiento, la app se queda en el primer rol (reset.css dejaría todas al final, apagadas) */
  @media (prefers-reduced-motion: reduce){
    .sistema__vista,
    .sistema__resalte{
      animation: none;
    }

    .sistema__vista:first-of-type{
      opacity: 1;
    }

    .sistema__panel:first-of-type .sistema__resalte{
      stroke: rgba(255, 255, 255, 0.8);
    }
  }

  /* ATLAS: en sus dos escenas todo va en gris; solo su caja va encendida */
  .sistema__red{
    fill: none;
    stroke: rgba(255, 255, 255, 0.45);
    stroke-width: 0.9;
    stroke-dasharray: 1 3;
    stroke-linecap: round;
  }

  .sistema__enlace--grueso{
    stroke-width: 1.6;
  }

  /* La red de ATLAS, cada vez más lejos: aros que se abren a su alrededor */
  .sistema__onda{
    fill: none;
    stroke: #ffffff;
    stroke-width: 0.75;
    vector-effect: non-scaling-stroke;
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
    animation: sistema-onda 4s ease-out calc(var(--lectura) + var(--i) * 2s) infinite;
  }

  /* Un módulo apagado: tenue, y su tramo de red también; el resto sigue */
  .sistema__camara--apagada,
  .sistema__red--cortada{
    opacity: 0.3;
  }

  /* La tarjeta que se vuelca en ATLAS */
  .sistema__tarjeta-memoria{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.55);
    stroke-width: 0.75;
    stroke-linejoin: round;
  }

  .sistema__dibujo[data-dibujo$="atlas"] :is(.sistema__cara, .sistema__movil){
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.4);
    stroke-width: 0.75;
    stroke-linejoin: round;
  }

  .sistema__dibujo[data-dibujo$="atlas"] .sistema__tapa{
    fill: rgba(255, 255, 255, 0.22);
    stroke: rgba(255, 255, 255, 0.4);
    filter: none;
  }

  .sistema__dibujo[data-dibujo$="atlas"] .sistema__enlace{
    stroke: rgba(255, 255, 255, 0.22);
  }

  .sistema__dibujo[data-dibujo$="atlas"] .sistema__marco{
    stroke: rgba(255, 255, 255, 0.25);
  }

  .sistema__dibujo[data-dibujo$="atlas"] .sistema__atlas .sistema__cara{
    stroke: #ffffff;
  }

  .sistema__dibujo[data-dibujo$="atlas"] .sistema__atlas .sistema__tapa{
    fill: #ffffff;
    stroke: #ffffff;
    filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.8));
  }

  /* Pilotos de ATLAS: parpadean a destiempo, trabajando */
  .sistema__led{
    fill: rgba(255, 255, 255, 0.35);
    animation: sistema-parpadear 1.4s steps(1) calc(var(--lectura) + var(--i) * 0.35s) infinite;
  }

  @keyframes sistema-latido{
    0%{ scale: 1; opacity: 0.4; }
    47%, 100%{ scale: 1.8; opacity: 0; }
  }

  @keyframes sistema-respirar{
    50%{ opacity: 0.45; }
  }

  @keyframes sistema-vumetro{
    to{ scale: 1 0.55; }
  }

  @keyframes sistema-escena-1{
    0%, 42%, 100%{ opacity: 1; }
    50%, 92%{ opacity: 0; }
  }

  @keyframes sistema-escena-2{
    0%, 42%, 100%{ opacity: 0; }
    50%, 92%{ opacity: 1; }
  }

  @keyframes sistema-recorrer{
    0%{ stroke-dashoffset: 0; opacity: 0; }
    5%, 40%{ opacity: 0.9; }
    45%, 100%{ stroke-dashoffset: -1; opacity: 0; }
  }

  @keyframes sistema-onda{
    0%{ scale: 0.6; opacity: 0.35; }
    100%{ scale: 2.2; opacity: 0; }
  }

  @keyframes sistema-gastar{
    to{ scale: 0.8 1; }
  }

  @keyframes sistema-fila{
    0%{ opacity: 0; }
    4%, 80%{ opacity: 1; }
    90%, 100%{ opacity: 0; }
  }

  @keyframes sistema-foco{
    0%, 42%, 100%{ opacity: calc(var(--desde) * 0.35); }
    50%, 92%{ opacity: calc(var(--hasta) * 0.35); }
  }

  @keyframes sistema-resaltar{
    0%{ stroke: transparent; }
    3%, 22%{ stroke: rgba(255, 255, 255, 0.8); }
    25%, 100%{ stroke: transparent; }
  }

  @keyframes sistema-turno{
    0%{ opacity: 0; }
    3%, 22%{ opacity: 1; }
    25%, 100%{ opacity: 0; }
  }

  @keyframes sistema-parpadear{
    0%{ fill: #ffffff; }
    50%{ fill: rgba(255, 255, 255, 0.35); }
  }

  /* Proceso (cómo funciona): misma estructura que el ecosistema; los pasos en lista bajo el texto
     y el esquema por capas a la derecha en pantallas anchas. Título y texto, compartidos más abajo */
  .proceso{
    --lectura: 1.2s; /* quieto al empezar cada paso: primero se lee, luego se mira */
    --rodaje: calc(var(--lectura) + 7.2s); /* en Rodaje, cuando LUMEN ya está montado empieza a rodarse (DATOS en proceso.js cuenta con ello) */

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(2rem, 5vh, 3rem);
    width: 100%; /* ocupa el sitio disponible (hasta su máximo) y sus columnas se reparten dentro, sin desbordar */
    max-width: 62rem;
    margin-inline: auto;
    padding-bottom: calc(2.75rem + clamp(0.5rem, 2svh, 1.5rem) + 0.75rem); /* hueco del indicador de scroll, como en el ecosistema */
    text-align: center;
    position: relative; /* el indicador de scroll se coloca respecto a la sección */
  }

  .proceso__cuerpo{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: 36rem;
  }

  /* Pasos: una línea fina encima de cada uno; la del activo se enciende */
  .proceso__pasos{
    width: 100%;
    margin-top: 0.25rem;
    text-align: left;
  }

  .proceso__paso{
    position: relative; /* el botón cubre todo el paso con su ::after */
    padding-bottom: 0.75rem;

    /* Lectura, su animación y un reposo parecido al final de cada uno; Rodaje dura más porque monta LUMEN y rueda */
    --duracion: 12s;
  }

  .proceso__paso:nth-child(2){
    --duracion: 16s;
  }

  .proceso__barra{
    display: block;
    height: 1px;
    background-color: rgba(255, 255, 255, 0.15);
    transition: background-color 300ms ease-out;
  }

  .proceso__paso--activo .proceso__barra{
    background-color: rgba(255, 255, 255, 0.6);
  }

  /* El reloj del paso: una animación invisible; proceso.js pasa al siguiente cuando termina */
  .proceso__progreso{
    display: block;
  }

  .proceso__paso--activo .proceso__progreso{
    animation: proceso-progreso var(--duracion) linear both;
  }

  @keyframes proceso-progreso{
    from{ opacity: 1; }
    to{ opacity: 1; }
  }

  /* Paso elegido a mano (o sin movimiento): el reloj se para */
  .proceso--manual .proceso__paso--activo .proceso__progreso{
    animation: none;
  }

  /* Fuera de pantalla todo espera. !important porque las reglas de cada paso declaran su animación con el
     atajo animation:, que devuelve el estado a running y además son más específicas: sin él, el dibujo
     seguiría animándose sin verse y al llegar ya estaría terminado */
  .proceso--fuera .proceso__progreso,
  .proceso--fuera .proceso__svg *{
    animation-play-state: paused !important;
  }

  .proceso__boton{
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    width: 100%;
    padding: 0.625rem 0 0.375rem;
    border: 0;
    background: none;
    font-family: Jost-SemiBold;
    font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
    color: rgba(255, 255, 255, 0.92);
    text-align: left;
    cursor: pointer;
    transition: color 300ms ease-out;
  }

  /* Toda la fila del paso se puede pulsar, no solo el nombre */
  .proceso__boton::after{
    content: "";
    position: absolute;
    inset: 0;
  }

  .proceso__numero{
    font-family: Jost-Light;
    font-size: 0.7em;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.2em;
  }

  .proceso__descripcion{
    font-size: clamp(0.9375rem, 0.9rem + 0.15vw, 1rem);
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.6);
    transition: color 300ms ease-out;
  }

  /* Con JS, los pasos que no se están viendo se apagan */
  .proceso[data-paso] .proceso__paso:not(.proceso__paso--activo) .proceso__boton{
    color: rgba(255, 255, 255, 0.45);
  }

  .proceso[data-paso] .proceso__paso:not(.proceso__paso--activo) .proceso__descripcion{
    color: rgba(255, 255, 255, 0.35);
  }

  .proceso[data-paso] .proceso__paso .proceso__boton:hover{
    color: #ffffff;
  }

  .proceso__boton:focus-visible{
    outline: 2px solid #ffffff;
    outline-offset: 4px;
    border-radius: 0.25rem;
  }

  /* Esquema por capas (lo dibuja proceso.js) */
  .proceso__esquema{
    --rec: 1; /* la respiración de REC y tallies la marca la animación proceso-respirar */

    width: min(100%, 26rem);
    margin: 0; /* <figure> trae márgenes por defecto */
    container-type: inline-size; /* los textos del SVG se ajustan a su ancho con cqw */
  }

  .proceso__svg{
    width: 100%;
    height: auto;
    overflow: visible; /* el latido y un módulo que cae pueden salirse un poco del viewBox */
  }

  /* Planos: rombos apagados; el de LUMEN algo más claro */
  .proceso__plano{
    fill: rgba(0, 0, 0, 0.85); /* tapa lo que pasa por debajo */
    stroke: rgba(255, 255, 255, 0.3);
    stroke-width: 0.75;
    stroke-linejoin: round;
  }

  .proceso__capa--lumen .proceso__plano{
    stroke: rgba(255, 255, 255, 0.55);
  }

  /* Aristas: punteadas y tenues como el control de la red; unen los extremos de los planos sin competir con los datos */
  .proceso__aristas line{
    stroke: rgba(255, 255, 255, 0.28);
    stroke-width: 0.75;
    stroke-dasharray: 1 3;
    stroke-linecap: round;
  }

  /* Rótulos de capa y de pista: versalitas espaciadas, como las etiquetas del ecosistema */
  .proceso__rotulo,
  .proceso__etiqueta{
    font-family: Jost-Regular;
    font-size: clamp(8.5px, 15px - 1.5cqw, 11px); /* misma escala que las etiquetas de la red */
    letter-spacing: 0.16em;
  }

  .proceso__rotulo{
    fill: rgba(255, 255, 255, 0.5);
  }

  .proceso__etiqueta{
    text-anchor: middle;
    fill: rgba(255, 255, 255, 0.55); /* como las etiquetas de la red */
    /* Contorno negro pintado bajo la letra: lo que pase por detrás se corta y el nombre se lee limpio */
    paint-order: stroke;
    stroke: #000000;
    stroke-width: 3px;
    stroke-linejoin: round;
  }

  /* Iconos de la red tumbados: halo, punto y pantalla comparten estilos con ella (arriba).
     Encima de cada equipo, su módulo: un cubo con la tapa encendida */
  .proceso__cara,
  .sistema__cara{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.8);
    stroke-width: 0.75;
    stroke-linejoin: round;
  }

  .proceso__tapa,
  .sistema__tapa{
    fill: rgba(255, 255, 255, 0.85);
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 0.75;
    stroke-linejoin: round;
    filter: drop-shadow(0 0 2.5px rgba(255, 255, 255, 0.7)); /* encendida: conectado y listo */
  }

  /* Líneas que se dibujan: pathLength="1" permite trazarlas de 0 a 1 sea cual sea su largo */
  .proceso__enlace{
    fill: none;
    stroke: rgba(255, 255, 255, 0.38);
    stroke-width: 0.75;
    stroke-dasharray: 1;
  }

  /* LUMEN: rejilla fina y los puertos de cada equipo y pantalla */
  .proceso__rejilla line{
    stroke: rgba(255, 255, 255, 0.1);
    stroke-width: 0.75;
  }

  .proceso__puerto{
    fill: rgba(255, 255, 255, 0.8);
  }

  /* Luz de fondo: la nube de la red, que se enciende cuando aparece LUMEN */
  .proceso__nube{
    opacity: 0;
    transition: opacity 1500ms ease-in-out;
  }

  .proceso[data-paso="2"] .proceso__nube{
    opacity: 1;
    transition-delay: calc(var(--lectura) + 3.4s); /* a la vez que se abre LUMEN */
  }

  /* REC de la capa LUMEN */
  .proceso__rec{
    fill: var(--rojo-rec);
    filter: drop-shadow(0 0 2px var(--rojo-rec));
  }

  /* Timecode del cabezal del montaje */
  .proceso__tiempo{
    font-family: Jost-Light;
    font-size: clamp(8.5px, 15px - 1.5cqw, 11px);
    font-variant-numeric: tabular-nums; /* cifras de ancho fijo: no baila al cambiar */
    letter-spacing: 0.12em;
    fill: rgba(255, 255, 255, 0.7);
  }

  .proceso__pantalla{
    vector-effect: non-scaling-stroke; /* el cuadrado va aplastado (transform): el trazo, no */
  }

  /* Datos (los mueve proceso.js): la señal baja en blanco; el control sube, más tenue, como en la red */
  .proceso__paquete{
    fill: #ffffff;
  }

  .proceso__paquete--control{
    fill: rgba(255, 255, 255, 0.55);
  }

  /* Latido del timecode: el aro de la red, suave y en todos a la vez; cada 3 s, como allí */
  .proceso__latido{
    fill: none;
    stroke: #ffffff;
    stroke-width: 0.9;
    vector-effect: non-scaling-stroke; /* el aro crece sin engordar */
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
    animation: proceso-latido 3s ease-out var(--rodaje) infinite;
  }

  /* REC y tallies: se encienden al rodar y respiran juntos, al ritmo de la red (unos 0,6 Hz) */
  .proceso[data-paso="2"] :is(.proceso__rec, .proceso__tally){
    animation:
      proceso-aparecer 800ms ease-in-out var(--rodaje) both,
      proceso-respirar 1.7s ease-in-out calc(var(--rodaje) + 0.8s) infinite;
  }

  /* Montaje: carriles tenues, clips que encajan en el cabezal y la marca de verificado */
  .proceso__carril{
    stroke: rgba(255, 255, 255, 0.12);
    stroke-width: 0.75;
  }

  .proceso__bloque{
    fill: #0b0b0b;
    stroke: rgba(255, 255, 255, 0.75);
    stroke-width: 0.75;
  }

  .proceso__clip--audio .proceso__bloque{
    stroke: rgba(255, 255, 255, 0.45);
  }

  .proceso__nombre{
    font-family: Jost-Light;
    font-size: clamp(7px, 12px - 1.2cqw, 9px);
    letter-spacing: 0.08em;
    fill: rgba(255, 255, 255, 0.85);
  }

  .proceso__onda-sonido{
    stroke: rgba(255, 255, 255, 0.45);
    stroke-width: 1.2;
  }

  .proceso__verificado{
    fill: none;
    stroke: #ffffff;
    stroke-width: 1;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* Marcadores en la regla, con su guía punteada sobre las pistas */
  .proceso__marca{
    fill: rgba(255, 255, 255, 0.85);
  }

  .proceso__guia{
    stroke: rgba(255, 255, 255, 0.25);
    stroke-width: 0.75;
    stroke-dasharray: 1 3;
    stroke-linecap: round;
  }

  .proceso__cabezal line{
    stroke: rgba(255, 255, 255, 0.7);
    stroke-width: 0.75;
    stroke-dasharray: 2 3;
  }

  .proceso__parte rect{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.6);
    stroke-width: 0.75;
  }

  .proceso__parte path{
    stroke: rgba(255, 255, 255, 0.4);
    stroke-width: 0.75;
  }

  /* El archivo del proyecto, con el mismo tono apagado que los partes */
  .proceso__archivo path{
    fill: #000000;
    stroke: rgba(255, 255, 255, 0.6);
    stroke-width: 0.75;
    stroke-linejoin: round;
  }

  .proceso__resumen{
    fill: rgba(255, 255, 255, 0.8);
  }

  /* --- Estados del esquema: data-paso (lo pone proceso.js) enciende lo de cada paso.
     Cada paso empieza quieto (--lectura) y luego ocurre una cosa cada vez, sin prisa; --i reparte
     el turno entre hermanos y "both" deja cada cosa en su estado final. Con "reducir movimiento",
     reset.css acorta las animaciones y cada paso se ve ya terminado --- */

  /* Capas: entran de arriba abajo y en la entrega se pliegan sobre LUMEN */
  .proceso__capa,
  .proceso__aristas,
  .proceso__enlaces,
  .proceso__montaje{
    transition: translate 1400ms cubic-bezier(0.45, 0, 0.25, 1), opacity 900ms ease-in-out;
  }

  .proceso[data-paso="1"] .proceso__capa--equipos{
    translate: 0 120px; /* sola, en el centro del esquema */
  }

  .proceso[data-paso="2"] .proceso__capa--equipos{
    transition-delay: var(--lectura); /* sube después de leer */
  }

  .proceso[data-paso="1"] :is(.proceso__capa--lumen, .proceso__capa--perfiles, .proceso__aristas, .proceso__enlaces),
  .proceso[data-paso="3"] :is(.proceso__capa--lumen, .proceso__aristas, .proceso__enlaces),
  .proceso:not([data-paso="3"]) .proceso__montaje{
    opacity: 0;
  }

  .proceso[data-paso="3"] .proceso__capa--equipos{
    translate: 0 120px;
    opacity: 0;
  }

  .proceso[data-paso="3"] .proceso__capa--perfiles{
    translate: 0 -120px;
    opacity: 0;
  }

  .proceso[data-paso="3"] :is(.proceso__capa, .proceso__aristas, .proceso__enlaces){
    transition-delay: var(--lectura);
  }

  /* Lo que solo existe al rodar: fuera de Rodaje ni se pinta ni se anima, y al volver empieza de cero */
  .proceso:not([data-paso="2"]) :is(.proceso__paquete, .proceso__latido, .proceso__tally, .proceso__grabacion){
    display: none;
  }

  /* 1 · Preparación: el plano, los equipos de uno en uno, un módulo cae sobre cada uno y se encienden a la vez */
  .proceso[data-paso="1"] .proceso__capa--equipos :is(.proceso__plano, .proceso__rotulo){
    animation: proceso-aparecer 900ms ease-in-out calc(var(--lectura) - 0.2s) both;
  }

  .proceso[data-paso="1"] .proceso__equipo :is(.proceso__halo, .proceso__punto, .proceso__etiqueta){
    animation: proceso-aparecer 800ms ease-in-out calc(var(--lectura) + 1s + var(--i) * 0.7s) both;
  }

  .proceso[data-paso="1"] .proceso__modulo{
    animation: proceso-encajar 1100ms cubic-bezier(0.3, 0.7, 0.3, 1) calc(var(--lectura) + 3.4s + var(--i) * 1s) both;
  }

  .proceso[data-paso="1"] .proceso__modulo .proceso__tapa{
    animation: proceso-encender 1000ms ease-in-out calc(var(--lectura) + 7.1s) both;
  }

  /* 2 · Rodaje: los equipos suben y aparecen los departamentos... un instante sin nada que los una... y se abre
     LUMEN en medio, con su luz. Cada módulo baja a su puerto y cada pantalla cuelga del suyo.
     Desde --rodaje se rueda: REC, tallies y latido (arriba); los datos bajan a su hora y cada pantalla
     se enciende al llegarle el suyo, como el nodo señalado en la red */
  .proceso[data-paso="2"] .proceso__capa--perfiles :is(.proceso__plano, .proceso__rotulo){
    animation: proceso-aparecer 900ms ease-in-out calc(var(--lectura) + 0.6s) both;
  }

  .proceso[data-paso="2"] .proceso__perfil{
    animation: proceso-aparecer 800ms ease-in-out calc(var(--lectura) + 1s + var(--i) * 0.35s) both;
  }

  .proceso[data-paso="2"] .proceso__aristas{
    animation: proceso-aparecer 1000ms ease-in-out calc(var(--lectura) + 2.6s) both;
  }

  .proceso[data-paso="2"] .proceso__capa--lumen{
    transform-box: fill-box;
    transform-origin: center;
    animation: proceso-abrirse 1000ms cubic-bezier(0.3, 0.7, 0.3, 1) calc(var(--lectura) + 2.6s) both;
  }

  .proceso[data-paso="2"] .proceso__enlace--equipo{
    animation: proceso-dibujar 1000ms ease-in-out calc(var(--lectura) + 3.6s + var(--i) * 0.25s) both;
  }

  .proceso[data-paso="2"] .proceso__puerto--equipo{
    animation: proceso-aparecer 500ms ease-in-out calc(var(--lectura) + 4.4s + var(--i) * 0.25s) both;
  }

  .proceso[data-paso="2"] .proceso__enlace--perfil{
    animation: proceso-dibujar 1000ms ease-in-out calc(var(--lectura) + 5s + var(--i) * 0.25s) both;
  }

  .proceso[data-paso="2"] .proceso__puerto--perfil{
    animation: proceso-aparecer 500ms ease-in-out calc(var(--lectura) + 5.8s + var(--i) * 0.25s) both;
  }

  .proceso[data-paso="2"] .proceso__pantalla{
    animation: proceso-iluminar 800ms ease-in-out var(--llega) both;
  }

  /* 3 · Entrega: las capas se pliegan, llegan las pistas y los clips se alinean; luego marcas, verificado, partes y un archivo */
  .proceso[data-paso="3"] .proceso__pista{
    animation: proceso-aparecer 700ms ease-in-out calc(var(--lectura) + 1.4s + var(--i) * 0.3s) both;
  }

  .proceso[data-paso="3"] .proceso__clip{
    animation: proceso-alinear 1300ms cubic-bezier(0.3, 0.7, 0.3, 1) calc(var(--lectura) + 2.2s + var(--i) * 0.35s) both;
  }

  .proceso[data-paso="3"] .proceso__marcador{
    animation: proceso-aparecer 600ms ease-in-out calc(var(--lectura) + 3.8s + var(--j) * 0.25s) both;
  }

  .proceso[data-paso="3"] .proceso__cabezal{
    animation: proceso-aparecer 800ms ease-in-out calc(var(--lectura) + 4.8s) both;
  }

  .proceso[data-paso="3"] .proceso__verificado{
    animation: proceso-aparecer 600ms ease-in-out calc(var(--lectura) + 5.6s + var(--i) * 0.4s) both;
  }

  .proceso[data-paso="3"] .proceso__parte{
    animation: proceso-aparecer 600ms ease-in-out calc(var(--lectura) + 6.2s + var(--i) * 0.3s) both;
  }

  .proceso[data-paso="3"] .proceso__archivo{
    animation: proceso-aparecer 800ms ease-in-out calc(var(--lectura) + 6.9s) both;
  }

  /* Verificado, ordenado y sincronizado entran uno detrás de otro */
  .proceso[data-paso="3"] .proceso__resumen tspan{
    animation: proceso-aparecer-texto 700ms ease-in-out calc(var(--lectura) + 7.6s + var(--j) * 0.6s) both;
  }

  @keyframes proceso-aparecer{
    from{ opacity: 0; }
  }

  /* Para trozos de texto (tspan), que no admiten opacity en todos los navegadores */
  @keyframes proceso-aparecer-texto{
    from{ fill-opacity: 0; }
  }

  @keyframes proceso-encajar{
    from{ translate: 0 -28px; opacity: 0; }
    50%{ opacity: 1; }
  }

  /* La tapa pasa de apagada a encendida y así se queda */
  @keyframes proceso-encender{
    from{ fill: rgba(255, 255, 255, 0.3); filter: none; }
  }

  @keyframes proceso-dibujar{
    from{ stroke-dashoffset: 1; }
  }

  @keyframes proceso-abrirse{
    from{ scale: 1 0; opacity: 0; }
  }

  /* Se abre en 1,4 s (como en la red) y espera apagado al siguiente latido */
  @keyframes proceso-latido{
    0%{ scale: 1; opacity: 0.4; }
    47%, 100%{ scale: 1.8; opacity: 0; }
  }

  @keyframes proceso-respirar{
    50%{ opacity: 0.45; }
  }

  @keyframes proceso-iluminar{
    to{ stroke: #ffffff; filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.7)); }
  }

  @keyframes proceso-alinear{
    from{ translate: calc(var(--desfase) * 1px) 0; opacity: 0.3; }
  }

  /* Contacto: título grande, una línea de complemento y el correo como botón; los gatos acompañan.
     En móvil, en columna y centrado; en pantallas anchas, en dos columnas con los gatos a la derecha */
  .contacto{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(2rem, 5vh, 3rem);
    max-width: 62rem; /* cabe la frase en una línea y los gatos a su tamaño */
    margin-inline: auto;
    text-align: center;
  }

  .contacto__cuerpo{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
  }

  /* Antetítulo: versalitas pequeñas y espaciadas, como el subtítulo del logo; tenue para no competir con el título */
  .ecosistema__antetitulo,
  .problema__antetitulo,
  .sistema__antetitulo,
  .proceso__antetitulo{
    font-size: clamp(0.6875rem, 0.65rem + 0.15vw, 0.75rem);
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
    margin-bottom: -0.5rem; /* más pegado al título que el resto del bloque: forman una sola cabecera */
  }

  /* Título rotundo: SemiBold y letras algo más juntas, como pide un tamaño tan grande */
  .ecosistema__titulo,
  .problema__titulo,
  .sistema__titulo,
  .proceso__titulo,
  .contacto__titulo{
    font-family: Jost-SemiBold;
    font-weight: normal; /* cada peso de Jost es su propia fuente: sin negrita fingida */
    font-size: clamp(1.75rem, 1.3rem + 1.8vw, 2.75rem); /* contenido: por debajo del logo, que es lo que debe mandar */
    line-height: 1.05;
    letter-spacing: -0.025em;
    color: rgba(255, 255, 255, 0.92); /* blanco algo rebajado: en puro y tan grueso pesa demasiado */
  }

  /* Una sola línea, apagada: complementa al título sin competir */
  .ecosistema__texto,
  .problema__texto,
  .proceso__texto,
  .contacto__texto{
    font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.6);
    text-wrap: balance;
  }

  /* Separación de párrafo: menor que el gap entre título y texto, para que se lean como un solo bloque */
  .ecosistema__texto > p + p,
  .problema__texto > p + p{
    margin-top: 0.75em;
  }

  /* Correo como botón: lo único con fondo claro, así es lo primero que se ve después del título.
     En reposo es un blanco algo apagado para que el destello del hover (blanco puro) se vea al cruzarlo */
  .contacto__correo{
    position: relative; /* el destello (::after) se coloca respecto al botón */
    isolation: isolate; /* el destello con z-index: -1 queda sobre el fondo y bajo el texto */
    overflow: hidden; /* recorta el destello a la forma de píldora */
    display: inline-flex;
    align-items: center;
    min-height: clamp(2.5rem, 2.3rem + 0.6vw, 2.75rem); /* 40px en móvil, 44px en escritorio */
    padding: 0 clamp(1rem, 0.8rem + 0.8vw, 1.25rem);
    margin-top: 0.5rem;
    border-radius: 999px;
    background-color: #e4e4e1;
    color: #000000;
    font-size: clamp(0.875rem, 0.82rem + 0.25vw, 0.9375rem);
    overflow-wrap: anywhere; /* no desborda en pantallas muy estrechas */
    transition: background-color 600ms ease-out, box-shadow 600ms ease-out;
  }

  /* Destello: franja de luz diagonal que espera fuera, a la izquierda */
  .contacto__correo::after{
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(
      105deg,
      transparent 35%,
      rgba(255, 255, 255, 0.95) 50%,
      transparent 65%
    );
    transform: translateX(-100%);
    pointer-events: none;
  }

  /* Hover y teclado: el destello cruza la píldora y queda encendida en blanco con un halo, como la luz del logo */
  .contacto__correo:hover,
  .contacto__correo:focus-visible{
    background-color: #ffffff;
    box-shadow: 0 0 1.75rem rgba(255, 255, 255, 0.3);
  }

  .contacto__correo:hover::after,
  .contacto__correo:focus-visible::after{
    transform: translateX(100%);
    transition: transform 700ms ease-out; /* solo al entrar: al salir vuelve a su sitio sin verse */
  }

  .contacto__correo:focus-visible{
    outline: 2px solid #ffffff;
    outline-offset: 3px;
  }

  /* Ilustración: acompaña sin robar protagonismo */
  .contacto__ilustracion{
    width: min(85vw, 23rem);
    height: auto;
  }

  /* Pantallas anchas (y móviles en horizontal, donde falta alto): texto a la izquierda y gatos a la derecha.
     Una tablet en vertical sigue en columna: a dos columnas el texto quedaba apretado */
  @media (min-width: 60rem), (min-width: 40rem) and (max-height: 32rem){
    .ecosistema,
    .problema,
    .proceso,
    .contacto{
      flex-direction: row;
      justify-content: space-between;
      gap: clamp(3rem, 6vw, 5rem);
      text-align: left;
    }

    .contacto__cuerpo{
      flex: none; /* el texto mantiene su ancho (la frase en una línea); si falta sitio, encoge la ilustración */
      align-items: flex-start;
    }

    .contacto__ilustracion{
      flex: 0 1 28rem;
      width: 28rem;
      min-width: 0;
    }

    /* El texto se acerca a la red como el del contacto a los gatos: menos hueco
       (el SVG ya trae su propio margen interior) y líneas largas que llegan hasta el borde */
    .ecosistema,
    .problema,
    .proceso{
      gap: clamp(1.5rem, 3vw, 2.5rem);
    }

    .ecosistema__cuerpo,
    .problema__cuerpo,
    .proceso__cuerpo{
      flex: 1 1 36rem; /* el texto se estira en pocas líneas largas; la red cede el sitio que falte */
      max-width: none;
      align-items: flex-start;
    }

    .ecosistema__texto,
    .problema__texto,
    .proceso__texto{
      text-wrap: pretty; /* balance igualaría las líneas acortándolas todas: aquí se quieren largas */
    }

    .ecosistema__red,
    .problema__lado{
      flex: 0 1 25rem;
      width: 25rem;
      min-width: 0;
    }

    /* El esquema es más alto que ancho: algo más de anchura para que módulos y pantallas se lean */
    .proceso__esquema{
      flex: 0 1 28rem;
      width: 28rem;
      min-width: 0;
    }
  }

  /* El pie (redes, enlaces legales y copyright) está en comunes.css, compartido con las páginas legales */

/* ==========================================================================
   3. SCROLL SNAP: cada sección, una pantalla completa
   Logo + ecosistema, problema, sistema, proceso y contacto + pie.
   Solo con alto suficiente: en pantallas bajas (móvil en horizontal) el contenido
   no cabe en una pantalla y el snap obligatorio daría saltos, así que se queda el scroll normal
   ========================================================================== */

@media (min-height: 40rem){
  html{
    scroll-snap-type: y mandatory;
  }

  /* Cabecera y pie salen del flujo y se superponen a su pantalla: así cada sección mide justo
     una pantalla sin tener que conocer su alto. El hueco lo reserva el padding de cada sección */
  body{
    position: relative; /* el pie se coloca respecto al final de la página */
  }

  header,
  footer{
    position: absolute;
    left: 0;
    z-index: 1; /* encima de la sección que tapan, para que sus enlaces se puedan pulsar */
  }

  header{
    top: 0;
  }

  footer{
    bottom: 0;
  }

  main{
    gap: 0;
    padding-block: 0;
  }

  .ecosistema,
  .problema,
  .sistema,
  .proceso,
  .contacto{
    min-height: 100dvh; /* el alto de cada momento: en móvil crece al ocultarse la barra del navegador y
                           no asoma la sección siguiente (los dibujos siguen midiéndose con svh, no cambian) */
    scroll-snap-align: start;
  }

  /* Arriba, hueco para el logo (mide ≈ 1.3 veces --cabecera-tamano más su margen superior) */
  .ecosistema{
    margin-top: 0;
    padding-top: clamp(4.5rem, 3rem + 5vw, 8.5rem);
  }

  /* Sin logo encima: solo aire arriba */
  .problema,
  .sistema,
  .proceso{
    padding-top: 2rem;
  }

  /* Hueco para el pie; algo mayor que su alto para que el contacto quede por encima del centro, como antes */
  .contacto{
    padding-top: 2rem;
    padding-bottom: clamp(9rem, 8rem + 3vw, 11rem);
  }
}

/* Portátiles bajos (menos de ~740 px de alto): el sistema, con algo menos de aire arriba, cabe en su pantalla */
@media (min-height: 40rem) and (max-height: 46rem) and (min-width: 40rem){
  .sistema{
    padding-top: 1.5rem;
  }
}

/* En móvil, la sección con menos aire arriba: el que tiene se lo lleva el título */
@media (min-height: 40rem) and (max-width: 39.99rem){
  .sistema{
    padding-top: 1rem;
  }
}

/* En móvil el sistema no cabe en una pantalla: la sección es una sola parada, más alta que la pantalla, y dentro el
   scroll es libre (así lo hacen los navegadores con lo que no cabe); al llegar a la siguiente, vuelve a ajustarse */
/* En columna (móvil y tablet en vertical) el contenido se centra en vertical dentro de su pantalla;
   en fila ya lo hace align-items */
@media (min-height: 40rem) and (max-width: 59.99rem){
  .contacto{
    justify-content: center;
  }

  /* Como en el ecosistema, el aire que sobra se reparte por igual arriba, entre bloques y abajo */
  .problema,
  .proceso{
    justify-content: space-evenly;
    gap: clamp(1rem, 3svh, 3rem);
    padding-top: clamp(1.5rem, 4svh, 3rem);
  }

  /* El esquema se ajusta al alto que dejan el texto y los pasos, sea cual sea la pantalla, y su ancho sale de
     su proporción. Con tope para que quede aire: en móvil lo marca el ancho (80vw) y en tablet el alto (52svh).
     Si ni con el mínimo cabe, la sección se alarga */
  .proceso__esquema{
    flex: 1 1 0;
    min-height: 9.5rem; /* lo justo para leerse en un móvil de 640 de alto */
    max-height: min(52svh, 80vw);
    width: auto;
    max-width: min(100%, 34rem);
    aspect-ratio: 400 / 350; /* la del viewBox */
  }

  .proceso__svg{
    height: 100%; /* si el ancho topa con su máximo, el dibujo se centra en su hueco */
  }

  /* El aire sobrante se reparte por igual arriba, entre texto y red, y abajo.
     Huecos y red se miden con el alto (svh): en móviles altos queda holgado y en los bajos
     se compacta en proporción, sin que nada quede pegado al logo, al indicador ni al borde */
  .ecosistema{
    justify-content: space-evenly;
    gap: clamp(1rem, 3svh, 3rem);
    padding-top: clamp(4.75rem, 13svh, 8.5rem); /* el antetítulo sale del haz del logo */
  }

  /* La red cede sitio cuanto más baja es la pantalla: ~300px en 844 de alto, ~220px en 667 y, en los
     móviles más bajos, más deprisa (~165px en 640), para que quepa con el texto, el botón y el REC */
  .ecosistema__red{
    width: min(100%, 26rem, 44svh - 4.5rem, 140svh - 45.8rem);
  }

  /* Las pestañas y el dibujo: en móvil ocupan todo el ancho, y solo en pantallas bajas ceden (~250px en 667) */
  .problema__lado{
    width: min(100%, 26rem, 52svh - 3rem, 104svh - 27.5rem);
  }
}

/* Móviles bajos (menos de ~740px de alto): la entradilla del proceso cede su sitio al esquema,
   que si no quedaría demasiado pequeño para leerse; las fases ya explican lo mismo */
@media (min-height: 40rem) and (max-height: 46rem) and (max-width: 59.99rem){
  .proceso__texto{
    display: none;
  }

  /* La primera pantalla y la del problema, más compactas para que quepa todo: menos aire,
     y el texto un punto más pequeño */
  .ecosistema,
  .problema{
    gap: 0.75rem;
    padding-bottom: calc(2.75rem + clamp(0.5rem, 2svh, 1.5rem)); /* el hueco justo del indicador */
  }

  .ecosistema__cuerpo,
  .problema__cuerpo{
    gap: 1rem;
  }

  .ecosistema__texto,
  .problema__texto{
    font-size: 0.9375rem;
  }
}

/* Párrafo largo en columna: alineado a la izquierda se lee mejor que centrado; título y antetítulo siguen centrados */
@media (max-width: 59.99rem){
  /* En columna (con JS) los pasos son pestañas en una fila y debajo se lee la descripción del activo.
     Las tres descripciones comparten celda: el hueco es el de la más larga y nada salta al cambiar.
     display: contents deja que barra, botón y descripción de cada paso se coloquen en la rejilla de la lista */
  .proceso[data-paso] .proceso__pasos{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: 0.75rem;
  }

  .proceso[data-paso] .proceso__paso{
    display: contents;
  }

  .proceso[data-paso] .proceso__barra{
    grid-row: 1;
  }

  .proceso[data-paso] .proceso__boton{
    grid-row: 2;
    position: relative; /* sin el li como referencia, su ::after cubre solo la pestaña */
    flex-direction: column;
    gap: 0.125rem;
    padding-bottom: 0.75rem;
  }

  .proceso[data-paso] .proceso__descripcion{
    grid-row: 3;
    grid-column: 1 / -1;
    margin-top: 0.75rem; /* separada de las pestañas: se lee como el texto de la elegida, no como una más */
    visibility: hidden; /* ocupa su sitio sin verse (ni leerse) */
  }

  .proceso[data-paso] .proceso__paso--activo .proceso__descripcion{
    visibility: visible;
  }

  .ecosistema__texto,
  .problema__texto,
  .proceso__texto{
    text-align: left;
    text-wrap: pretty;
    line-height: 1.55; /* algo más compacto que en escritorio: en móvil son siete u ocho líneas */
  }
}
