/* Movimiento y profundidad de la portada.
   ═══════════════════════════════════════════════════════════════════════════

   Todo el efecto sale de CSS y de un observador de intersección: cero bytes de
   librería. Three.js son ~600 KB y la regla 11 prohíbe los CDN — desde Cuba eso
   es una portada que no llega a pintarse.

   La dirección la manda Nocturne: el acento es LÍNEA y RESPLANDOR, nunca relleno
   de un área grande. Por eso la profundidad aquí se construye con auroras muy
   diluidas, bordes que se encienden y planos que se inclinan, no con bloques de
   color saturado.

   Todo respeta `prefers-reduced-motion`: quien lo pida ve la página quieta y
   completa, nunca a medio aparecer. */


/* ───────────────────────────────────────────────── aurora del encabezado

   Dos manchas de acento muy diluidas que respiran detrás del titular. Diluidas al
   20 % y desenfocadas 80 px no inundan nada: dan fondo a la página. */

.portada {
  position: relative;
  isolation: isolate;
  /* Las auroras se salen del contenedor a propósito (top:-180px, right:-120px). Sin
     recortarlas empujan el ancho del documento y aparece barra horizontal: 524 px en
     un teléfono de 390. `clip` recorta sin crear un contenedor de desplazamiento,
     que es lo que haría `hidden`. */
  overflow: hidden;
  overflow: clip;
}

.portada::before,
.portada::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(80px);
}
.portada::before {
  width: 720px; height: 720px;
  top: -240px; left: -180px;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent) 55%, transparent), transparent 68%);
  animation: respirar 11s ease-in-out infinite;
}
.portada::after {
  width: 620px; height: 620px;
  top: -60px; right: -160px;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent-400) 42%, transparent), transparent 68%);
  animation: respirar 15s ease-in-out infinite reverse;
}

@keyframes respirar {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1);      opacity: .5; }
  33%      { transform: translate3d(60px, -40px, 0) scale(1.25); opacity: 1; }
  66%      { transform: translate3d(-30px, 35px, 0) scale(.95);  opacity: .7; }
}


/* ───────────────────────────────────────────────── entrada del titular

   El titular y su acompañamiento suben escalonados al cargar. No es adorno: marca
   el orden de lectura antes de que el ojo elija por su cuenta. */

.portada-texto > * { animation: subir .7s cubic-bezier(.16, 1, .3, 1) backwards; }
.portada-texto > *:nth-child(1) { animation-delay: .05s; }
.portada-texto > *:nth-child(2) { animation-delay: .12s; }
.portada-texto > *:nth-child(3) { animation-delay: .19s; }
.portada-texto > *:nth-child(4) { animation-delay: .26s; }

.portada-cotizador { animation: subir .8s cubic-bezier(.16, 1, .3, 1) .18s backwards; }

@keyframes subir {
  from { opacity: 0; transform: translate3d(0, 40px, 0) scale(.97); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}


/* ───────────────────────────────────────────────── revelado al desplazar

   Cada sección aparece cuando entra en pantalla. La clase `.visible` la pone
   movimiento.js; sin JavaScript nada añade `.revelar` y la página se ve completa
   desde el primer momento. */

.revelar {
  opacity: 0;
  transform: translate3d(0, 48px, 0) scale(.98);
  transition: opacity .75s cubic-bezier(.16, 1, .3, 1),
              transform .75s cubic-bezier(.16, 1, .3, 1);
}
.revelar.visible { opacity: 1; transform: none; }

/* Los hijos de una rejilla entran en cascada, no en bloque. */
.revelar-cascada > * {
  opacity: 0;
  transform: translate3d(0, 38px, 0) scale(.97);
  transition: opacity .6s cubic-bezier(.16, 1, .3, 1),
              transform .6s cubic-bezier(.16, 1, .3, 1);
}
.revelar-cascada.visible > * { opacity: 1; transform: none; }
.revelar-cascada.visible > *:nth-child(1) { transition-delay: .00s; }
.revelar-cascada.visible > *:nth-child(2) { transition-delay: .07s; }
.revelar-cascada.visible > *:nth-child(3) { transition-delay: .14s; }
.revelar-cascada.visible > *:nth-child(4) { transition-delay: .21s; }
.revelar-cascada.visible > *:nth-child(5) { transition-delay: .28s; }


/* ───────────────────────────────────────────────── tarjetas con relieve

   Inclinación real en tres dimensiones siguiendo el puntero: la tarjeta gira sobre
   sus ejes X e Y y un resplandor la recorre por donde pasa el cursor. Las
   variables --gx/--gy las escribe movimiento.js. En el teléfono no hay puntero:
   no se activa nada y la tarjeta se queda plana. */

.rejilla-modalidades { perspective: 700px; }

.rejilla-modalidades .card {
  transform-style: preserve-3d;
  transition: transform .35s cubic-bezier(.16, 1, .3, 1),
              border-color .35s ease, box-shadow .35s ease;
  position: relative;
  overflow: hidden;
}

/* El resplandor que sigue al cursor. Al 10 % es un brillo, no un relleno. */
.rejilla-modalidades .card::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
  background: radial-gradient(
    300px circle at var(--gx, 50%) var(--gy, 50%),
    color-mix(in srgb, var(--color-accent) 30%, transparent),
    transparent 62%
  );
}
.rejilla-modalidades .card:hover::after { opacity: 1; }
.rejilla-modalidades .card:hover {
  border-color: color-mix(in srgb, var(--color-accent) 45%, var(--color-divider));
  box-shadow: var(--shadow-md);
}

/* El contenido se despega del plano de la tarjeta: eso es lo que da el relieve. */
.rejilla-modalidades .card > * { transform: translateZ(38px); }

/* Las tarjetas de modalidad son ENLACES: el giro que las seguía con el puntero las
   apartaba del cursor, igual que la del cotizador. Se quedan quietas; el
   resplandor que sigue al ratón se mantiene, porque ese no mueve nada. */
.rejilla-modalidades .card:hover { transform: none !important; }


/* ───────────────────────────────────────────────── cifras que cuentan

   El número sube desde cero al entrar en pantalla. `tabular-nums` evita que el
   ancho baile mientras cuenta. */

.cifra { font-variant-numeric: tabular-nums; }


/* ───────────────────────────────────────────────── pasos que se encienden */

.paso { position: relative; padding-left: var(--space-3); }
.paso::before {
  content: "";
  position: absolute;
  left: 0; top: 4px; bottom: 4px;
  width: 2px;
  border-radius: 1px;
  background: var(--color-accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform .5s cubic-bezier(.16, 1, .3, 1);
}
.revelar-cascada.visible .paso::before { transform: scaleY(1); }
.revelar-cascada.visible .paso:nth-child(1)::before { transition-delay: .10s; }
.revelar-cascada.visible .paso:nth-child(2)::before { transition-delay: .20s; }
.revelar-cascada.visible .paso:nth-child(3)::before { transition-delay: .30s; }
.revelar-cascada.visible .paso:nth-child(4)::before { transition-delay: .40s; }
.revelar-cascada.visible .paso:nth-child(5)::before { transition-delay: .50s; }


/* ───────────────────────────────────────────────── fundador con paralaje

   La foto se mueve más despacio que la página al desplazar. `--desplazamiento` lo
   escribe movimiento.js a partir de la posición del propio elemento. */

.fundador-foto picture {
  display: block;
  transform: translate3d(0, var(--desplazamiento, 0px), 0);
}


/* ───────────────────────────────────────────────── acordeón */

.acordeon details[open] p { animation: desplegar .35s cubic-bezier(.16, 1, .3, 1); }
@keyframes desplegar {
  from { opacity: 0; transform: translate3d(0, -6px, 0); }
  to   { opacity: 1; transform: none; }
}
.acordeon summary { transition: color .2s ease; }
.acordeon-signo { transition: transform .3s cubic-bezier(.16, 1, .3, 1), color .2s ease; }
.acordeon details[open] .acordeon-signo { transform: rotate(180deg); }


/* ───────────────────────────────────────────────── botones

   NINGÚN BOTÓN SE MUEVE. Ni al pasar el puntero ni al pulsarlo.

   Aquí había `translateY(-1px)` en `:hover` y `translateY(0)` en `:active`. Suena
   inofensivo y no lo es: el botón sube al acercar el ratón y BAJA al pulsarlo, así
   que el `mousedown` y el `mouseup` caen en sitios distintos y el navegador no
   genera un `click`. Dentro de la tarjeta del cotizador, que está bajo
   `perspective: 1100px`, ese píxel se proyecta a ~10 px.

   Resultado medido: «Abrir el cotizador» no respondía al ratón. Con este bloque
   quitado el desvío pasa de 10×11 px a 0×0 y el enlace funciona.

   El realce ahora sale del BORDE y de la SOMBRA, que no mueven nada. */

.btn { transition: border-color .2s ease, color .2s ease, box-shadow .2s ease; }
.btn:hover { box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 35%, transparent); }
.btn:active { box-shadow: none; }


/* ───────────────────────────────────────────────── quien pide quietud

   No se «reduce» la animación: se apaga entera y todo queda en su posición final.
   Una página a medio revelar es peor que una sin movimiento. */

@media (prefers-reduced-motion: reduce) {
  .portada::before,
  .portada::after { animation: none; }

  .portada-texto > *,
  .portada-cotizador,
  .acordeon details[open] p { animation: none; }

  .revelar,
  .revelar-cascada > * { opacity: 1; transform: none; transition: none; }

  .paso::before { transform: scaleY(1); transition: none; }

  .rejilla-modalidades .card,
  .fundador-foto picture,
  .btn { transition: none; transform: none; box-shadow: none; }

  .acordeon-signo { transition: none; }
}

/* ═════════════════════════════════════════════════════════════════════════
   PROFUNDIDAD QUE SE VE SOLA

   Lo anterior solo aparecía al pasar el ratón por una tarjeta, y en el teléfono
   no existía: para quien abre la portada y desplaza, el sitio parecía plano.

   Aquí la escena se mueve SOLA. Nada de esto necesita puntero, así que en el
   teléfono se ve igual que en el escritorio.
   ═════════════════════════════════════════════════════════════════════════ */


/* ───────────────────────────────────────────── el escenario

   `perspective` en el contenedor es lo que convierte un `translateZ` en
   profundidad real en vez de un simple escalado. Sin esto no hay 3D, hay dibujo. */

.portada,
.rejilla-modalidades,
.fundador {
  perspective: 1100px;
  perspective-origin: 50% 40%;
}


/* ───────────────────────────────────────────── la tarjeta del cotizador

   Es lo que más se mira de toda la portada, así que es lo que tiene que tener
   cuerpo. Flota y bascula sola, despacio, como una carta sostenida en la mano. */

/* LA REGLA QUE SE ME ESCAPÓ: nada con lo que se interactúa puede moverse solo.
   ────────────────────────────────────────────────────────────────────────────
   Esta tarjeta flotaba. Es un formulario: se escribe y se pulsa dentro. Una
   tarjeta que se desplaza sola es un blanco en movimiento — el botón «Abrir el
   cotizador» sencillamente NO respondía, porque entre que el navegador calcula
   dónde está el enlace y el clic ocurre, la tarjeta se ha ido a otro sitio.

   Pausarla al pasar el puntero no bastaba: la propia transición de pausarse la
   movía otra vez, justo en el momento de pulsar.

   Ahora tiene relieve —perspectiva, sombra, un borde encendido— pero está QUIETA.
   La profundidad se ve igual; lo que se pierde es el balanceo, que costaba un
   botón que no funcionaba. */
.portada-cotizador {
  /* NADA DE GIRO. Esto es un FORMULARIO: etiquetas, campos y bordes que el ojo lee
     como líneas rectas. Inclinado no se lee como profundidad, se lee como torcido
     — y un formulario torcido parece roto, no premium.
     El relieve lo dan la sombra y el borde encendido, que no deforman nada. */
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--color-accent) 26%, transparent),
    0 24px 60px -24px rgba(0, 0, 0, .8);
}

/* NADA de mover la tarjeta al pasar el puntero.
   ────────────────────────────────────────────
   Enderezarla en `:hover` la apartaba del cursor. Al apartarse se perdía el
   `:hover`, volvía a su sitio, se volvía a activar… un bucle. El botón «Abrir el
   cotizador» quedaba INALCANZABLE con el ratón: un clic necesita que el `mousedown`
   y el `mouseup` caigan en el mismo elemento, y la tarjeta se movía entre uno y
   otro.

   Comprobado: el clic programático navegaba y el del ratón no. Ese era el fallo.

   Un elemento con el que se interactúa puede cambiar de COLOR o de SOMBRA al pasar
   el puntero. De POSICIÓN, nunca. */
.portada-cotizador:hover,
.portada-cotizador:focus-within {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--color-accent) 45%, transparent),
    0 34px 80px -20px rgba(0, 0, 0, .8);
}

/* (Aquí había un segundo bloque que enderezaba la tarjeta al pasar el puntero.
   Sobraba y era dañino: movía 10 px lo que hay dentro justo al ir a pulsarlo.
   El realce está arriba, hecho solo con sombra.) */


/* ───────────────────────────────────────────── las modalidades, en el aire

   Cada tarjeta bascula sola con su propio desfase, así que la fila entera
   respira en vez de moverse en bloque. El giro con el puntero sigue existiendo
   y manda por encima de esto cuando hay ratón. */

/* Quietas por lo mismo: cada una lleva contenido y son pulsables. El relieve sale
   de la perspectiva y de la sombra, no de moverse. Con el puntero encima sí giran
   —eso lo controla la persona, no un temporizador. */
.rejilla-modalidades .card {
  box-shadow: 0 18px 40px -22px rgba(0, 0, 0, .8);
}
/* Las tarjetas no giran ni se levantan.
   No giran porque cuatro rectángulos de texto torcidos en direcciones distintas se
   leen como un fallo de maquetación. Y no se levantan al pasar el ratón aunque hoy
   no sean enlaces: mañana lo serán —el patrón «Cotizar un viaje →» ya existe— y un
   elemento que se mueve entre el `mousedown` y el `mouseup` se come el clic. Ya
   costó un botón que no respondía.
   Responden con LUZ, que no mueve nada. */
.rejilla-modalidades .card { transition: box-shadow .3s ease, border-color .3s ease; }
.rejilla-modalidades .card:hover {
  border-color: color-mix(in srgb, var(--color-accent) 50%, var(--color-divider));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 30%, transparent),
              0 18px 40px -22px rgba(0, 0, 0, .8);
}

/* El puntero manda: al entrar, la animación se para y toma el control el giro.
   Sin esto, cualquier cosa pulsable dentro de la tarjeta sería un blanco móvil. */
.rejilla-modalidades .card:hover { animation-play-state: paused; }

/* Nada pulsable puede estar dentro de algo que se mueve solo. Es la regla que se
   me escapó y dejó un botón que no respondía. */
.asistente,
.asistente * { animation-play-state: running; }

/* `bascular` queda sin usar: giraba las tarjetas y las dejaba torcidas. Se
   conserva el nombre fuera para que nadie lo reintroduzca por costumbre. */


/* ───────────────────────────────────────────── capas que se separan al desplazar

   `--profundidad` la escribe movimiento.js con la posición de cada sección en
   pantalla. El resultado es que el contenido no «aparece»: se acerca. */

.seccion {
  transform-style: preserve-3d;
}
.seccion .titulo-seccion {
  transform: translate3d(0, 0, calc(var(--profundidad, 0) * 34px));
  transition: transform .1s linear;
}
.seccion .rejilla-modalidades,
.seccion .acordeon {
  transform: translate3d(0, 0, calc(var(--profundidad, 0) * 14px));
  transition: transform .1s linear;
}


/* ───────────────────────────────────────────── el retrato, con cuerpo

   El fundador deja de ser una foto pegada: se separa del fondo y bascula con el
   desplazamiento, como si estuviera un paso por delante de la página. */

.fundador-foto {
  transform-style: preserve-3d;
}
.fundador-foto picture {
  /* Sin giro: el retrato se acerca y se mueve un poco, nada más. Girándolo con el
     desplazamiento parecía que se caía. */
  transform: translate3d(0, var(--desplazamiento, 0px), 40px);
  transition: transform .12s linear;
}


/* ───────────────────────────────────────────── el titular, en dos planos */

.hero {
  transform-style: preserve-3d;
  animation: acercar 1.1s cubic-bezier(.16, 1, .3, 1) backwards;
}
@keyframes acercar {
  /* El titular entra desde el fondo, sin girar: un texto inclinado que se
     endereza se lee mal justo mientras aparece. */
  from { opacity: 0; transform: translate3d(0, 26px, -120px); }
  to   { opacity: 1; transform: none; }
}

.cifras { transform-style: preserve-3d; }
.cifra {
  transform: translateZ(18px);
  text-shadow: 0 8px 24px rgba(0, 0, 0, .6);
}


/* ───────────────────────────────────────────── quien pide quietud

   Se apaga TODO y cada plano vuelve a cero. Una escena a medio girar es peor
   que una plana. */

@media (prefers-reduced-motion: reduce) {
  .portada-cotizador,
  .rejilla-modalidades .card,
  .hero { animation: none; transform: none; }

  .seccion .titulo-seccion,
  .seccion .rejilla-modalidades,
  .seccion .acordeon,
  .fundador-foto picture,
  .cifra { transform: none; transition: none; }

  .portada,
  .rejilla-modalidades,
  .fundador { perspective: none; }
}

/* ═════════════════════════════════════════════════════════════════════════
   LA ESCENA DEL RECORRIDO — de la recogida a la entrega

   Todo SVG y CSS: ni una librería, ni una imagen que descargar. El movimiento
   va con `offset-path`, que hace que cada vehículo siga la CURVA de la calle en
   vez de cruzar en línea recta — que es lo que separa esto de un GIF.

   Nada de aquí es pulsable, y no es un detalle: ya costó un botón que no
   funcionaba tener cosas moviéndose donde la gente pulsa.
   ═════════════════════════════════════════════════════════════════════════ */

.escena {
  width: 100%;
  margin: var(--space-6) 0;
  pointer-events: none;        /* decoración: no intercepta ni un clic */
  user-select: none;
}
.escena svg { width: 100%; height: auto; display: block; overflow: visible; }

/* ───────────────────────────── la ciudad */

.escena .ciudad rect {
  fill: var(--color-neutral-800);
  stroke: var(--color-divider);
  stroke-width: 1;
}

.escena .ventanas rect {
  fill: var(--color-accent);
  animation: ventana 7s ease-in-out infinite;
}
/* Desfases primos para que no parpadeen a la vez, que delataría el truco. */
.escena .ventanas rect:nth-child(2) { animation-delay: -1.7s; }
.escena .ventanas rect:nth-child(3) { animation-delay: -3.1s; }
.escena .ventanas rect:nth-child(4) { animation-delay: -4.3s; }
.escena .ventanas rect:nth-child(5) { animation-delay: -5.9s; }

@keyframes ventana {
  0%, 100% { opacity: .25; }
  50%      { opacity: .85; }
}

.escena .palmas path {
  fill: none;
  stroke: var(--color-neutral-600);
  stroke-width: 2;
  stroke-linecap: round;
  transform-origin: center bottom;
  animation: brisa 6s ease-in-out infinite;
}
@keyframes brisa {
  0%, 100% { transform: rotate(-1.2deg); }
  50%      { transform: rotate(1.2deg); }
}

/* ───────────────────────────── la calle */

.escena .calle {
  fill: none;
  stroke: url(#via);
  stroke-width: 10;
  stroke-linecap: round;
}

/* La línea discontinua que corre por el centro: da sentido de avance aunque no
   pase ningún vehículo. */
.escena .calle-linea {
  fill: none;
  stroke: var(--color-accent-300);
  stroke-width: 1.5;
  stroke-dasharray: 10 16;
  opacity: .5;
  animation: avanzar 2.4s linear infinite;
}
@keyframes avanzar {
  to { stroke-dashoffset: -26; }
}

/* ───────────────────────────── A y B */

.escena .extremo .punto { fill: var(--color-accent); }
.escena .extremo-b .punto { fill: var(--color-accent-300); }

.escena .extremo .halo {
  fill: var(--color-accent);
  opacity: .18;
  /* `transform-box: fill-box` es obligatorio aqui. Sin el, `transform-origin:
     center` apunta al centro del LIENZO SVG, no al del circulo: el halo se
     escapaba a la izquierda y quedaba una mancha oscura sobre la familia. */
  transform-box: fill-box;
  transform-origin: center;
  animation: latir 2.6s ease-out infinite;
}
.escena .extremo-b .halo { animation-delay: -1.3s; }

@keyframes latir {
  0%   { transform: scale(.5); opacity: .35; }
  70%  { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

.escena .extremo text {
  fill: var(--color-text);
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: var(--font-heading-weight);
  text-anchor: middle;
}

/* ───────────────────────────── la familia esperando */

.escena .figura circle { fill: var(--color-neutral-500); }
.escena .figura path {
  fill: none;
  stroke: var(--color-neutral-500);
  stroke-width: 2;
  stroke-linecap: round;
}

/* Se balancean un poco: quietas del todo parecen postes. */
.escena .figura {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: esperar 3.4s ease-in-out infinite;
}
.escena .familia > g:nth-child(2) .figura { animation-delay: -1.1s; }
.escena .familia > g:nth-child(3) .figura { animation-delay: -2.2s; }
.escena .familia-b .figura { animation-duration: 4s; }

@keyframes esperar {
  0%, 100% { transform: translateY(0) rotate(-.8deg); }
  50%      { transform: translateY(-1.5px) rotate(.8deg); }
}

/* ───────────────────────────── los vehículos

   `offset-path` con la MISMA curva que la calle: por eso suben y bajan con ella
   en vez de flotar por encima. `offset-rotate: auto` los inclina siguiendo la
   pendiente, que es el detalle que lo hace creíble. */

.escena .viajero {
  offset-path: path("M80 200 C 220 200, 260 168, 400 168 S 580 200, 720 200");
  offset-rotate: auto;
  animation: recorrer 9s cubic-bezier(.45, 0, .55, 1) infinite;
}
.escena .viajero-moto     { animation-duration: 7s;  animation-delay: -2.5s; }
.escena .viajero-triciclo { animation-duration: 12s; animation-delay: -5.5s; }

@keyframes recorrer {
  0%        { offset-distance: 0%;   opacity: 0; }
  6%        { opacity: 1; }
  90%       { opacity: 1; }
  100%      { offset-distance: 100%; opacity: 0; }
}

.escena .carroceria { fill: var(--color-accent); }
.escena .viajero-moto .carroceria     { fill: var(--color-accent-300); }
.escena .viajero-triciclo .carroceria { fill: var(--color-accent-400); }

.escena .rueda { fill: var(--color-neutral-900); stroke: var(--color-neutral-500); stroke-width: 1.2; }
.escena .tripulante { fill: var(--color-neutral-400); }

/* Un botecito, como una calle cubana de verdad. */
.escena .vehiculo {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: baches .7s ease-in-out infinite;
}
@keyframes baches {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-1px); }
}

/* ───────────────────────────── quien pide quietud

   Se apaga TODO y queda un dibujo fijo con los vehículos repartidos por la
   calle: sigue contando lo mismo, sin una sola animación. */

@media (prefers-reduced-motion: reduce) {
  .escena .ventanas rect,
  .escena .palmas path,
  .escena .calle-linea,
  .escena .extremo .halo,
  .escena .figura,
  .escena .vehiculo { animation: none; }

  .escena .viajero { animation: none; opacity: 1; }
  .escena .viajero-auto     { offset-distance: 22%; }
  .escena .viajero-moto     { offset-distance: 52%; }
  .escena .viajero-triciclo { offset-distance: 78%; }
  .escena .extremo .halo { opacity: .18; }
}

/* En el teléfono la escena se recorta un poco: a 390 px los detalles no se ven
   y solo cuestan altura. */
@media (max-width: 640px) {
  .escena .ciudad rect:nth-child(n+9),
  .escena .ventanas rect:nth-child(n+4) { display: none; }
}

/* ═════════════════════════════════════════════════════════════════════════
   EL FONDO VIVO — rutas trazándose sobre las calles

   Lo que la app hace es llevar cosas de un punto a otro; el fondo dibuja eso.
   Muy diluido a propósito: si se lee antes que el titular, sobra.
   ═════════════════════════════════════════════════════════════════════════ */

.fondo-rutas {
  /* `fixed`, no `absolute`: acompaña TODAS las páginas y se queda detrás mientras
     se desplaza. Con `absolute` habría que dibujarlo del alto de la página, y en
     /preguntas/ o /terminos/ eso son varias pantallas de retícula. */
  position: fixed;
  inset: 0;
  z-index: -2;                /* detrás incluso de las auroras de la portada */
  overflow: hidden;
  pointer-events: none;
  /* Sin máscara: llega de borde a borde. La que había abría un hueco en el centro
     y recortaba los lados — se veía como un recuadro dentro de la página en vez de
     un fondo. Que no compita con el texto se resuelve con opacidad, no tapándolo. */
}
.fondo-rutas svg {
  /* Más ancho que la ventana: con `slice` y una pantalla muy apaisada, el SVG se
     escala por el alto y los trazos se quedaban cortos por los lados. */
  width: 100%;
  height: 100%;
  min-width: 1200px;
  display: block;
}

/* MUY diluido y con un desenfoque leve. Es FONDO: tiene que leerse como textura,
   nunca como una línea que cruza el titular. Antes iba al 28 % sin desenfocar y los
   trazos pasaban por encima del texto — se leía la línea antes que la frase. */
.fondo-rutas { filter: blur(.6px); }

.fondo-rutas .reticula path {
  fill: none;
  stroke: var(--color-divider);
  stroke-width: 1;
  opacity: .13;
}

/* El trazo se dibuja y se borra con `stroke-dashoffset`. Los 2400 cubren de sobra
   el largo de cualquiera de los tres recorridos. */
.fondo-rutas .trazo {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .16;
  stroke-dasharray: 2400;
  animation: trazar-ruta 14s ease-in-out infinite;
}
.fondo-rutas .trazo-2 { stroke: var(--color-accent-300); animation-delay: -4.6s; }
.fondo-rutas .trazo-3 { stroke: var(--color-accent-400); animation-delay: -9.2s; }

@keyframes trazar-ruta {
  0%   { stroke-dashoffset: 2400; opacity: 0; }
  10%  { opacity: .16; }
  45%  { stroke-dashoffset: 0;    opacity: .16; }
  70%  { stroke-dashoffset: 0;    opacity: .16; }
  95%  { stroke-dashoffset: -2400; opacity: 0; }
  100% { stroke-dashoffset: -2400; opacity: 0; }
}

.fondo-rutas .nodo {
  fill: var(--color-accent);
  transform-box: fill-box;      /* si no, `center` es el centro del LIENZO */
  transform-origin: center;
  animation: nodo-late 14s ease-out infinite;
}
.fondo-rutas .nodo-2 { animation-delay: -4.6s; }
.fondo-rutas .nodo-3 { animation-delay: -9.2s; }

@keyframes nodo-late {
  0%       { transform: scale(0); opacity: 0; }
  8%       { transform: scale(1.6); opacity: .3; }
  16%      { transform: scale(1); opacity: .2; }
  90%      { opacity: .2; }
  100%     { transform: scale(1); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fondo-rutas .trazo { animation: none; stroke-dashoffset: 0; opacity: .12; }
  .fondo-rutas .nodo { animation: none; opacity: .2; transform: none; }
}

/* En el teléfono el fondo estorba más de lo que aporta: la retícula compite con
   el texto en una pantalla estrecha. */
@media (max-width: 720px) {
  .fondo-rutas { display: none; }
}
