:root {
  --bg: #000;
  --fg: #f2f2f2;
  /* proporciones tomadas de Auguriositeok.png */
  --logo-y: 19.2%;
  --tagline-y: 49.6%;   /* header3.png la centra verticalmente */
  /* Margen izquierdo único: lo comparten el interruptor de idioma, el rótulo
     vertical y la cita. Si cambia, se mueven los tres a la vez. */
  --margen: clamp(18px, 2.1vw, 44px);
  /* Diámetro del punto de menú. Lo comparte el interruptor de idioma, que en
     móvil toma esa misma altura para que los dos centros coincidan. */
  --bolita: clamp(15px, 4.4vw, 22px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.header {
  position: relative;
  width: 100%;
  height: 100svh;
  min-height: 400px;
  overflow: hidden;
  background: #000;
}

.header__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

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

/* El contenido del header entra cuando el campo de puntos ya está pintado:
   primero el fondo, encima lo demás. La marca la pone app.js en <html> tras
   el primer pintado, con un plazo de seguridad por si la imagen no llega. */
.header__inner,
.idioma {
  opacity: 0;
  transition: opacity 0.7s ease;
}

.is-listo .header__inner,
.is-listo .idioma { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .header__inner, .idioma { opacity: 1; transition: none; }
}

/* ---- barra superior ----
   Medidas de header3.png (2560 x 1721). El logo baja de tamaño y sube a la
   barra; el menú va a la derecha. */
.header__logo {
  position: absolute;
  left: 50%;
  top: 2.5%;
  transform: translate(-50%, -50%);
  width: clamp(62px, 5.3%, 150px);
  height: auto;
  filter: brightness(0) invert(1);
  user-select: none;
  -webkit-user-drag: none;
}

.header__nav {
  position: absolute;
  right: 3.6%;
  top: 2.5%;
  transform: translateY(-50%);
  display: flex;
  gap: 1.5em;
  z-index: 2;
}

.header__enlace {
  font-size: max(10px, 0.7vw);
  font-weight: 400;
  letter-spacing: 0.1em;
  color: #fff;
  text-decoration: none;
  opacity: 0.75;
  transition: opacity 0.25s ease;
}

.header__enlace:hover,
.header__enlace:focus-visible { opacity: 1; }

/* TEORIA y CONTACTO todavía no llevan a ninguna parte: se ven igual pero no
   fingen ser enlaces. */
.header__enlace.is-pendiente { cursor: default; }

/* El botón de menú sólo existe en móvil: es el punto blanco de la maqueta. */
.header__menu { display: none; }

/* ---- pie del header ---- */
.header__seccion {
  position: absolute;
  left: var(--margen);
  bottom: 2.4%;
  margin: 0;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  /* En escritura vertical el interlineado es el ancho de la caja: a 1 la caja
     se ciñe al texto. Aun así los glifos girados quedan centrados sobre la
     línea base central, así que la tinta cae un poco por dentro; el margen
     negativo la devuelve al borde. Va en em para que aguante cualquier
     tamaño. */
  line-height: 1;
  margin-left: -0.15em;
  font-size: max(9px, 0.7vw);
  font-weight: 700;
  letter-spacing: 0.16em;
  color: #fff;
}

/* El testimonio, centrado abajo. Entra solo, dos segundos después de cargar y
   con un fundido muy lento: no compite con el logo ni con la frase, que ya
   están escribiéndose. Va en CSS y no en JS porque no depende de nada más. */
.header__cita {
  position: absolute;
  left: 50%;
  bottom: 2.1%;
  transform: translateX(-50%);
  width: 40.2%;
  margin: 0;
  text-align: center;
  opacity: 0;
}

/* Los dos segundos de espera cuentan desde que el header se revela, no desde
   que carga la página: si el fondo tarda, la cita no puede haberse consumido
   su entrada mientras estaba oculta. */
.is-listo .header__cita {
  animation: cita-entra 4.5s ease-in-out 2s forwards;
}

@keyframes cita-entra {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .header__cita, .is-listo .header__cita { opacity: 1; animation: none; }
}

.header__cita p {
  margin: 0;
  font-size: max(9px, 0.57vw);
  font-weight: 700;
  line-height: 1.4;
  color: #fff;
}

/* la flecha de bajar */
.header__bajar {
  position: absolute;
  left: 94.5%;
  bottom: 2.3%;
  width: 2.07%;
  min-width: 24px;
  color: #fff;
  opacity: 0.9;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.header__bajar svg { display: block; width: 100%; height: auto; }

.header__bajar:hover { opacity: 1; transform: translateY(3px); }

@media (prefers-reduced-motion: reduce) {
  .header__enlace, .header__bajar { transition: none; }
}

/* ---- frase ---- */

.tagline {
  position: absolute;
  left: 50%;
  top: var(--tagline-y);
  transform: translate(-50%, -50%);
  margin: 0;
  white-space: nowrap;
  font-style: italic;
  font-size: clamp(13px, 1.3vw, 26px);
  font-weight: 400;
  letter-spacing: 0.015em;
  color: #fff;
}

.tagline__fixed { margin-right: 0.26em; }

/* el hueco de la palabra que cambia reserva el ancho de la más larga,
   así la línea no se mueve al escribir y borrar */
.tagline__slot {
  display: inline-grid;
  grid-template-columns: 1fr;
  justify-items: start;
}

.tagline__sizer,
.tagline__live { grid-area: 1 / 1; }

.tagline__sizer { visibility: hidden; }

.tagline__caret {
  display: inline-block;
  width: 1px;
  height: 0.95em;
  margin-left: 0.06em;
  background: #fff;
  vertical-align: -0.11em;
  transform: translateZ(0);
}

/* parpadea sólo cuando está quieto: mientras escribe, se mantiene sólido */
.tagline__caret.is-idle { animation: caret-blink 1.05s steps(1, end) infinite; }

@keyframes caret-blink {
  0%, 50%   { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}



@media (prefers-reduced-motion: reduce) {
  .tagline__caret { display: none; }
}

/* ================= sección "qué hace" =================
   Medidas de mano3.png (2560 x 1560) y mano3mobile.png (984 x 1578).

   La mano se queda quieta en el centro y los textos la cruzan: el titular de
   derecha a izquierda y las fases de izquierda a derecha. Cada pista recorta
   por los lados; lo que se mueve es su contenido. */

.quehace {
  position: relative;
  height: 620svh;
  background: #eee url('textura-papel.jpg') repeat;
  background-size: 80px 80px;
}

.quehace__fijo {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: transparent;
  display: grid;
  place-items: center;
}

.quehace__marco {
  position: relative;
  width: 100%;
  height: 100%;
  color: #141414;
}

.quehace__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* el porcentaje recorrido, en el canal izquierdo */
.quehace__progreso {
  position: absolute;
  left: var(--margen);
  top: 49.5%;
  transform: translateY(-50%);
  margin: 0;
  font-size: max(10px, 0.7vw);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

/* ---- las dos pistas ---- */
.quehace__pista {
  position: absolute;
  left: 0;
  right: 0;
  overflow: hidden;
  /* el contenido se sale por los lados a propósito */
  pointer-events: none;
}

.quehace__pista--titular { top: 6%; height: 26%; }
.quehace__pista--fases   { top: 60%; height: 24%; }

.quehace__titular {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  white-space: nowrap;
  font-size: 17.9vw;      /* 458 px sobre 2560, como en la maqueta */
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1;
  will-change: transform;
}

.quehace__fases {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  /* el DOM va 1,2,3,4 y se invierte aquí: la cinta viaja a la derecha, así
     que la fase que entra primero tiene que ser la que queda más a la derecha */
  flex-direction: row-reverse;
  align-items: flex-start;
  gap: 12vw;
  will-change: transform;
}

/* la clave que abre cada fase, destacada como en la maqueta */
.quehace__clave {
  font-weight: 700;
  font-size: 0.88em;
}

.quehace__fase {
  flex: 0 0 auto;
  width: 24.8vw;          /* 636 px sobre 2560 */
  margin: 0;
  font-size: max(11px, 0.86vw);
  line-height: 1.5;
  text-indent: 6.5em;     /* la maqueta sangra la primera línea */
}

/* Cada letra va en su propio span para poder empujarla. Se agrupan por
   palabra para que el salto de línea siga cayendo donde debe.

   text-indent se hereda y se aplica a la primera línea de cada contenedor de
   bloque. Un inline-block lo es: sin anularlo, cada letra sangraba su propia
   línea y acababa midiendo 6.5em de ancho. */
.quehace__fase .pal,
.quehace__titular .pal { display: inline-block; white-space: nowrap; text-indent: 0; }

.quehace__fase .let,
.quehace__titular .let {
  display: inline-block;
  text-indent: 0;
  will-change: transform;
}

/* ---- las píldoras ---- */
.hitos {
  position: absolute;
  left: 50%;
  top: 94.3%;
  transform: translate(-50%, -50%);
  display: flex;
  gap: 1.1vw;
  z-index: 2;
}

.hito {
  flex: 0 0 auto;
  padding: 0.75em 1.9em;
  border: 0;
  border-radius: 999px;
  background: #141414;
  font: inherit;
  font-size: max(9px, 0.62vw);
  color: #f2f2f2;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.35s ease;
}

.hito:hover { opacity: 0.75; }
.hito.is-activo { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .hito { transition: none; }
}

/* ================= sección del gato =================
   .gato es sólo pista de scroll; .gato__fijo se ancla y no se mueve mientras
   se la recorre. Dentro, .gato__marco reproduce el encuadre de la referencia
   (2560x1696) ajustado por dentro, igual que el canvas: así los números caen
   siempre sobre el mismo punto del gato. Los márgenes son negros como el
   fondo, de modo que el ajuste no se nota. */

.gato {
  position: relative;
  height: 680svh;   /* el tramo de más al final sostiene la malla en pantalla */
  background: #000 url('textura-negro.jpg') repeat;
  /* La baldosa mide 160 px reales. Mostrada a 160 px CSS, en una pantalla
     DPR 2 se amplía al doble y cada píxel de ruido pasa a ser un bloque de
     2x2: eso es lo que se veía pixelado. A 80 px cae 1:1 en pantallas de
     doble densidad y el grano vuelve a ser de un píxel. */
  background-size: 80px 80px;
}

.gato__fijo {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: transparent;
  display: grid;
  place-items: center;
}

.gato__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.gato__marco {
  position: relative;
  z-index: 1;
  aspect-ratio: 2560 / 1696;
  width: min(100%, calc(100svh * 2560 / 1696));
  max-height: 100%;
}

.gato__num {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(11px, 1.55vw, 30px);
  color: #fff;
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* aparecen juntos pero escalonados, en orden numérico */
.gato__num[data-n="1"] { transition-delay: 0s; }
.gato__num[data-n="2"] { transition-delay: 0.09s; }
.gato__num[data-n="3"] { transition-delay: 0.18s; }
.gato__num[data-n="4"] { transition-delay: 0.27s; }
.gato__num[data-n="5"] { transition-delay: 0.36s; }
.gato__num[data-n="6"] { transition-delay: 0.45s; }

.gato__num.is-in { opacity: 0.55; }
/* cada número se enciende del todo cuando llega su frase */
.gato__num.is-dicho { opacity: 1; }

/* Medidas tomadas del mockup: la tarjeta se ubica respecto de la pantalla,
   no del encuadre de la ilustración, por eso cuelga del bloque anclado. */
.gato__tarjeta {
  position: absolute;
  z-index: 2;
  left: 54.5%;
  right: 16.3%;
  top: 54%;
  background: #fff;
  color: #141414;
  padding: 1.55em 1.7em;
  font-size: clamp(13px, 1.15vw, 22px);
  opacity: 0;
  transition: opacity 0.45s ease;
}

/* rótulo vertical del margen izquierdo */
.gato__rotulo {
  position: absolute;
  z-index: 2;
  left: 10.7%;
  top: 26.2%;
  margin: 0;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  transform-origin: center;
  font-size: clamp(8px, 0.62vw, 12px);
  font-weight: 700;
  letter-spacing: 0.16em;
  color: #fff;
}

/* la palabra clave abre el párrafo, con un salto marcado antes del texto */
.gato__clave {
  font-style: italic;
  font-weight: 700;
  font-size: 0.62em;
  margin-right: 3.4em;
  white-space: nowrap;
}

.gato__tarjeta.is-in { opacity: 1; }

/* La malla: al cerrarse la cadena, todos los puntos se unen con todos.
   Va más fina y a media opacidad para que la cadena original siga leyéndose
   por encima. */
.gato__malla {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.gato__malla path {
  transition: stroke-dashoffset 0.6s ease;  /* al replegarse, sin demora */
}

.gato__malla.is-in path {
  transition-delay: var(--d);
}

/* el trazo que va uniendo los números, detrás de ellos */
.gato__traza {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.gato__traza path {
  transition: stroke-dashoffset 0.9s cubic-bezier(0.33, 0.9, 0.4, 1);
}

/* Las frases se reemplazan, así que van apiladas en el mismo lugar. La altura
   de la pila la fija JS midiendo la frase activa: así la tarjeta queda ceñida
   a su texto, como en la referencia, en vez de quedar dimensionada para la
   más larga y dejar un hueco blanco con las cortas. */
.gato__pila {
  position: relative;
  transition: height 0.55s cubic-bezier(0.33, 0.9, 0.4, 1);
}

.gato__frase {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: 0;
  font-size: 1em;
  line-height: 1.5;
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}

.gato__frase.is-in {
  opacity: 1;
  transition-delay: 0.15s;
}

@media (prefers-reduced-motion: reduce) {
  .gato__num, .gato__tarjeta { opacity: 1; transform: none; transition: none; }
  /* sin animación no hay reemplazo posible: se listan una debajo de otra */
  .gato__pila { height: auto !important; }
  .gato__malla path { transition: none; }
  .gato__frase {
    position: static; opacity: 1; transition: none;
  }
  .gato__frase + .gato__frase { margin-top: 0.7em; }
  .gato__num { opacity: 1; }
}

/* ================= sección "problemas" =================
   Marco de referencia 2560 x 1452. Todo se ubica en porcentajes de ese marco:
   la cabeza, el polígono, el título y la barra caen siempre en el mismo sitio. */

.probs {
  position: relative;
  width: 100%;
  background: #000 url('textura-negro.jpg') repeat;
  /* La baldosa mide 160 px reales. Mostrada a 160 px CSS, en una pantalla
     DPR 2 se amplía al doble y cada píxel de ruido pasa a ser un bloque de
     2x2: eso es lo que se veía pixelado. A 80 px cae 1:1 en pantallas de
     doble densidad y el grano vuelve a ser de un píxel. */
  background-size: 80px 80px;
}

/* El marco ocupa todo el ancho para que el grano del fondo llegue a los
   bordes, igual que en la sección del gato. Antes quedaba centrado y más
   angosto, y a los lados aparecía negro plano sin grano. */
.probs__marco {
  position: relative;
  aspect-ratio: 2560 / 1682;
  width: 100%;
  /* En móvil el SVG del polígono se lleva a su sitio con un scale de 3.5: su
     caja pasa a medir 1382 px y, aunque es invisible, arrastraba scroll
     lateral en toda la página. La composición se recorta al marco. */
  overflow: hidden;
  /* las medidas tipográficas van en cqw: proporcionales al marco, no al
     viewport, porque el marco puede ser más angosto que la pantalla */
  container-type: inline-size;
}

.probs__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* el cuadro de línea que encierra todo el bloque, de la pregunta a la barra */
.probs__cuadro {
  position: absolute;
  left: 35.4%;
  right: 35.3%;   /* = borde derecho en 64.7% */
  top: 22.3%;
  bottom: 30%;    /* = borde inferior en 70%, justo encima de la barra */
  border: 1px solid #fff;
  pointer-events: none;
}

/* rótulo vertical del canal izquierdo, como en las demás secciones */
.probs__rotulo {
  position: absolute;
  left: 35.8%;
  top: 12.5%;
  margin: 0;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-transform: uppercase;
  font-weight: 700;
  font-size: max(8px, 0.5cqw);
  letter-spacing: 0.08em;
  color: #fff;
}

.probs__titulo {
  position: absolute;
  left: 36.2%;
  top: 23.1%;
  margin: 0;
  white-space: nowrap;
  font-weight: 700;
  font-size: 1.15cqw;
  color: #fff;
}

.probs__poli {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* cubre todo el marco y va después del menú en el DOM: sin esto le roba
     los clics a los puntos */
  pointer-events: none;
}

/* la mitad de la frase que va sobre el polígono */
.probs__arriba {
  position: absolute;
  left: 45.2%;
  top: 42.4%;
  width: 11.4%;
  margin: 0;
  font-style: italic;
  font-size: 1.25cqw;
  line-height: 1.06;
  color: #141414;
}

/* la otra mitad, en la barra blanca de abajo */
/* La barra es un rectángulo blanco del mismo ancho que el cuadro, apoyado
   justo debajo. Tus frases son más largas que la de la referencia, así que
   tres de ellas envuelven a dos líneas y la barra crece hacia abajo. */
.probs__abajo {
  position: absolute;
  left: 35.4%;
  right: 35.3%;
  top: 70%;
  margin: 0;
  background: #fff;
  padding: 0.3em 0.55em;
  font-weight: 700;
  font-size: 0.98cqw;
  line-height: 1.42;
  color: #141414;
}

/* el cambio de frase: se va y vuelve */
.probs__arriba,
.probs__abajo { transition: opacity 0.35s ease; }
.probs.is-cambiando .probs__arriba,
.probs.is-cambiando .probs__abajo { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .probs__arriba, .probs__abajo { transition: none; }
}

/* Menú de puntos, uno por frase, pegado al lado izquierdo del cuadro.
   El botón es más grande que el punto: el punto se dibuja con ::before y el
   resto del botón es área de clic invisible. Si el área fuera del tamaño del
   punto, con 3 px de diámetro sería casi imposible de acertar. */
.probs__menu {
  position: absolute;
  z-index: 3;
  right: calc(66.5% - 0.43cqw);  /* deja la columna de puntos en 33.5% */
  top: 46.2%;                   /* centrado sobre el cuadro, no sobre el marco */
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25cqw;
}

.probs__punto {
  width: 1.1cqw;
  height: 1.1cqw;
  padding: 0;
  border: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.probs__punto::before {
  content: "";
  width: 0.24cqw;
  height: 0.24cqw;
  border-radius: 50%;
  background: #fff;
  opacity: 0.3;
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.probs__punto:hover::before { opacity: 0.7; }

.probs__punto.is-activo::before {
  opacity: 1;
  transform: scale(1.7);
}

.probs__punto:focus-visible {
  outline: 1px solid #fff;
  outline-offset: -0.1cqw;
  border-radius: 50%;
}

@media (prefers-reduced-motion: reduce) {
  .probs__punto::before { transition: none; }
}

/* franja de transición entre secciones: las dos texturas de puntos se
   entremezclan en vez de cortarse en seco */
.difuminado {
  position: relative;
  width: 100%;
  height: 34svh;
  min-height: 180px;
  line-height: 0;
}

.difuminado canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ================= móvil =================
   En pantalla angosta los marcos de referencia colapsan a una franja de
   ~375x250 y todo lo que se dimensiona contra ellos queda en 2-8px. La
   solución no es achicar menos, es cambiar el reparto: la ilustración queda
   como imagen y el texto pasa a flujo vertical con cuerpo legible. */

@media (max-width: 900px) {

  /* ---- header ----
     Otra composición: la cita sube arriba, el logo baja al centro entre las
     dos figuras, la frase baja al 75% y el menú se pliega detrás de un punto.
     Medidas de "header mobile3.png" (984 x 1586). */
  .header { --tagline-y: 75.3%; }

  .header__logo {
    left: 51%;
    top: 43.3%;
    width: 19.2%;
  }

  /* El punto de la maqueta. Es el botón que despliega el menú, que en esta
     anchura no cabe en una fila. */
  /* El interruptor de idioma toma este mismo top y esta misma altura, así que
     sus centros coinciden exactamente sin calcular nada. */
  .header__menu {
    display: block;
    position: absolute;
    right: 3.2%;
    top: 1.5%;
    z-index: 3;
    width: var(--bolita);
    height: var(--bolita);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #fff;
    cursor: pointer;
    transition: transform 0.25s ease;
  }

  .header__menu[aria-expanded="true"] { transform: scale(0.72); }

  .header__nav {
    right: 3.2%;
    top: 7%;
    transform: none;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.9em;
    /* plegado hasta que se pulse el punto */
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0.25s;
  }

  .header__nav.is-abierto { opacity: 1; visibility: visible; }

  .header__enlace { font-size: 13px; }

  .idioma {
    top: 1.5%;
    height: var(--bolita);
    transform: none;
  }

  .header__cita {
    left: var(--margen);
    right: 30.5%;
    bottom: auto;
    top: 13.8%;
    width: auto;
    transform: none;
    text-align: left;
  }

  .header__cita p { font-size: max(11px, 2.85vw); line-height: 1.45; }

  .header__seccion { left: var(--margen); bottom: 4.1%; font-size: 9px; }

  .header__bajar { left: 88.7%; bottom: 3.1%; width: 5.4%; }

  @media (prefers-reduced-motion: reduce) {
    .header__menu, .header__nav { transition: none; }
  }

  /* ---- sección de la mano ----
     Se apila: el titular cruza arriba, la mano ocupa el centro y la cinta de
     fases pasa por debajo. Medidas de mano3mobile.png (984 x 1578). */
  .quehace { height: 480svh; }

  .quehace__fijo {
    position: sticky;
    top: 0;
    height: 100svh;
    overflow: hidden;
    display: block;
    padding: 0;
  }

  .quehace__marco {
    width: 100%;
    height: 100%;
    display: block;
    padding: 0;
  }

  .quehace__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    margin: 0;
  }

  .quehace__pista--titular { top: 5%; height: 24%; }
  .quehace__pista--fases   { top: 62%; height: 26%; }

  .quehace__titular { font-size: 42.8vw; }   /* 421 px sobre 984 */

  .quehace__fases { gap: 18vw; }

  .quehace__fase {
    width: 82.6vw;
    font-size: max(12px, 3.2vw);
    text-indent: 5.5em;
  }

  .quehace__progreso { top: 49.5%; font-size: 10px; }

  .hitos {
    top: 93%;
    width: 83.8%;
    gap: 0;
    justify-content: space-between;
  }

  .hito { font-size: 10px; padding: 0.7em 1.2em; }

  /* ---- sección del gato ----
     Mantiene el anclaje: su coreografía es el sentido de la sección. La
     tarjeta baja debajo del gato, donde hay sitio de sobra. */
  .gato { height: 560svh; }

  /* La escena se amplía 1,8 veces y se corre a la derecha, como en la maqueta:
     con el encuadre de escritorio el gato cae en una franja de 258 px de alto
     y los trazos que unen los números miden 40 px, que no se leen. El marco
     lleva números, trazos y tarjeta; el lienzo se amplía igual desde app.js
     (MOVIL_ZOOM y MOVIL_PAN), para que el gato siga debajo de sus números. */
  .gato__marco {
    width: 180%;
    max-height: none;
    transform: translateX(8.85%);   /* 15,9% del ancho del panel */
  }

  /* La tarjeta y el rótulo cuelgan del panel, no del marco: la ampliación de
     la escena no les afecta y siguen midiéndose contra la pantalla. */
  /* La maqueta la arranca en 41.4%, pero con ese ancho la frase 5 —la más
     larga, 187 caracteres— crece a 258 px y llega justo al borde inferior de
     la pantalla. Ensanchando a 28% baja a 191 px y le quedan 68 px de aire,
     el mismo que ya tienen las frases 1 y 3. Más ancho no gana nada: 191 es
     el suelo. Va abajo del gato, así que no le tapa nada. */
  .gato__tarjeta {
    left: 28%;
    right: 9.3%;
    top: 69.4%;
    padding: 1.1em 1.2em;
    font-size: 15px;
  }

  .gato__rotulo { left: 16.1%; top: 21%; font-size: 9px; }
  .gato__clave { margin-right: 1.6em; }
  .gato__num { font-size: 12px; }

  /* ---- sección de problemas ----
     La maqueta de móvil conserva la composición del escritorio: el cúmulo de
     puntos ocupa la sección entera, el cuadro de línea se apoya encima y el
     polígono sigue sosteniendo la primera mitad de la frase. Las medidas son
     porcentajes del marco de la maqueta, 984 x 1361.

     La tipografía va en cqw con un piso en px: la proporción de la maqueta
     daría 8 px en una pantalla de 390 y sería ilegible. */
  /* La sección es la última de la página: si sólo mide lo que el marco, debajo
     queda una franja de negro plano, sin grano, hasta el borde inferior. */
  .probs {
    min-height: 100svh;
    display: grid;
    place-items: center;
  }

  .probs__marco {
    aspect-ratio: 984 / 1361;
    min-height: 0;
    display: block;
    padding: 0;
  }

  /* la cabeza vuelve a ser el fondo de la sección, como en la maqueta */
  .probs__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }

  .probs__rotulo {
    left: 13.6%;
    top: 9.5%;
    font-size: max(7px, 0.91cqw);
    letter-spacing: 0.06em;
  }

  .probs__cuadro {
    left: 12.2%;
    right: 11.1%;
    top: 20.9%;
    bottom: 26.8%;
  }

  .probs__titulo {
    position: absolute;
    left: 13.8%;
    top: 21.8%;   /* despega el texto de la línea superior del cuadro */
    font-size: max(12px, 2.03cqw);
    white-space: nowrap;
  }

  /* El polígono se sigue dibujando en el viewBox del escritorio; aquí se lleva
     a su sitio de móvil escalándolo alrededor de su propio centro. Así la
     animación de morfeo sigue trabajando en las mismas unidades y no hay que
     duplicar las coordenadas. */
  .probs__poli {
    display: block;
    transform-origin: 51.5% 46.85%;
    transform: translate(2.52%, 4.99%) scale(3.544, 1.988);
  }

  .probs__arriba {
    position: absolute;
    left: 37%;
    right: 29%;
    top: 46.8%;
    width: auto;
    background: none;
    padding: 0;
    text-align: center;
    font-style: normal;
    font-size: max(13px, 2.44cqw);
    line-height: 1.25;
  }

  .probs__abajo {
    position: absolute;
    left: 12.5%;
    right: 11.1%;
    top: 77.1%;
    width: auto;
    padding: 0.75em 1em 0.75em 2.2em;
    font-weight: 400;
    font-size: max(12px, 2.13cqw);
    line-height: 1.5;
  }

  /* El menú baja al canal libre entre el borde de la pantalla y el cuadro.
     El punto se queda diminuto, como en el escritorio, pero el botón crece a
     20 px para que se pueda acertar con el dedo. */
  .probs__menu {
    left: 6.3%;
    right: auto;
    top: 47%;
    transform: translate(-50%, -50%);
    flex-direction: column;
    align-items: center;
    gap: 0.4cqw;
  }

  .probs__punto { width: 20px; height: 20px; }
  .probs__punto::before { width: 3px; height: 3px; }

  /* ---- franjas de difuminado ---- */
  .difuminado { height: 22svh; min-height: 120px; }
}

/* Pantallas bajas (un teléfono pequeño, o cualquiera en apaisado). La
   composición de la mano no cambia —sigue anclada, con las dos pistas
   cruzándose—, pero se aprieta para que la cinta de fases no se coma las
   píldoras. */
@media (max-width: 900px) and (max-height: 700px) {
  .quehace__pista--titular { top: 3%; height: 26%; }
  .quehace__pista--fases   { top: 58%; height: 28%; }
  .quehace__fase { font-size: 11px; }
  .hitos { top: 92%; }
  .hito { font-size: 9px; padding: 0.55em 0.9em; }
}

/* ---- interruptor de idioma ----
   Fijo arriba a la izquierda. La página alterna secciones negras y de papel,
   así que en vez de darle un fondo se mezcla en diferencia con lo que tenga
   debajo: sobre negro se ve blanco y sobre papel se ve negro, siempre legible
   y sin añadir una caja que ensucie la composición. */
.idioma {
  position: fixed;
  left: var(--margen);
  /* mismo eje que el logo y el menú de la barra superior */
  top: 2.5%;
  transform: translateY(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  /* sin relleno lateral: con él la tinta caía 3 px por dentro del margen */
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  line-height: 1;
  color: #fff;
  mix-blend-mode: difference;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.25s ease;
}

.idioma:hover { opacity: 1; }

.idioma:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 3px;
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .idioma { transition: none; }
}
