/* sitio.css — Gran Danés LM
   ─────────────────────────────────────────────────────────────────────────────
   El sitio vive en negro a propósito y no tiene tema claro: la pieza es una
   fotografía de las siete de la tarde disolviéndose en negro, y sobre blanco no
   existe. Por eso `color-scheme: dark` está declarado en el <head> y todos los
   colores se pintan explícitos — nada se hereda del navegador. */

:root{
  --negro:      #000;      /* el ground. La foto se disuelve EN él, no sobre él */
  --tinta:      #e8ddc8;   /* crema cálida: el mismo tono que la luz de la foto */
  /* DOS tokens, no uno: el texto y el filete pedían cosas opuestas. El tostado
     viejo (#5d5346) sobre negro da 2.79:1 — bajo el mínimo 4.5:1 de WCAG AA para
     texto normal, y aquí es el peor caso (cuerpo chico, versales, tracking alto).
     Subirlo a secas dejaba los filetes de 1 px como un subrayado grueso. Por eso
     se parten: --tenue pinta texto (5.11:1 contra negro, mismo matiz cálido);
     --filete conserva el susurro de 1 px. Medido, no a ojo. */
  --tenue:      #8a7b68;   /* texto: 5.11:1 contra --negro */
  --filete:     #5d5346;   /* trazo de 1 px: el tostado de siempre */
  --brasa:      #c8a06a;
}

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

/* EL RESPALDO DE `overflow-x:clip` PARA iOS 15.6 — el porqué, en la regla de
   abajo. Va antes para que `clip` lo pise donde `clip` se entiende. */
html{ overflow-x:hidden; }

html,body{
  min-height:100%;
  background:var(--negro);
  color:var(--tinta);
  /* `clip`, NO `hidden`, Y ES LA DIFERENCIA ENTRE QUE LA SECCIÓN DE CONCURSOS
     FUNCIONE O NO. `overflow-x:hidden` obliga a que `overflow-y` compute a
     `auto`, y eso convierte al <body> en un contenedor de scroll propio: un
     `position:sticky` de dentro deja de pegarse a la ventana y se va hacia
     arriba con la página. Medido: el top de la vista bajaba a −540, −1620,
     −2700… o sea que el relevo cambiaba de pieza mientras el usuario ya estaba
     mirando negro vacío.

     `clip` recorta igual y NO crea contenedor de scroll, así que el sticky
     vuelve a pegarse a la ventana.

     ── Y `clip` NO EXISTE ANTES DE SAFARI 16, o sea que en un iPhone con iOS
     15.6 —que está en el parque objetivo— esta declaración entera se cae y el
     `overflow-x` se queda en `visible`: la página se arrastra de lado. El
     respaldo va en la regla de ARRIBA y SÓLO SOBRE `html`, nunca sobre el
     <body>, y esa distinción es todo el arreglo: el overflow del ELEMENTO RAÍZ
     se propaga al viewport y el propio <html> computa a `visible`, así que no
     se convierte en contenedor de scroll y el sticky de concursos sigue
     pegándose. Al <body> no se le pone respaldo: con el viewport ya recortado
     no le queda nada que recortar.

     Y LA DISTINCIÓN ESTÁ MEDIDA, no razonada: con las cinco declaraciones que
     Safari 15.6 tira y el respaldo SÓLO en <html>, el top de `.concursos__vista`
     sale 0 en y=4000, 5000, 6000 y 7000 —pegada—. Añadiendo el mismo respaldo al
     <body>, los mismos cuatro puntos dan −3156, −4156, −5156 y −6156: la vista
     se va con la página. Son los mismos números negativos del párrafo de arriba,
     reproducidos.

     El orden es el que manda: respaldo primero, `clip` después. Donde `clip`
     existe gana por ser la última declaración y el dibujo es el de siempre. */
  overflow-x:clip;
}
body{ -webkit-font-smoothing:antialiased; }

/* ── EL REBOTE DE ARRIBA NO PUEDE ENSEÑAR NEGRO ───────────────────────────────
   VICTOR, EN EL IPHONE: «responde y rebota, la típica. No quiero que vean negro
   si scrollean hacia arriba.» Al tirar hacia abajo estando arriba del todo, el
   rebote elástico de iOS despega el contenido del canto y lo que asoma por
   encima es el fondo del ELEMENTO RAÍZ — que hasta hoy era el mismo negro plano
   del resto de la página. En un sitio cuyo hero es una fotografía a sangre, eso
   se lee como un hueco.

   NO SE MATA EL REBOTE, y esa era la otra salida. `overscroll-behavior-y:contain`
   lo quita, pero en la raíz quita TAMBIÉN el tirar-para-recargar del navegador,
   que es gesto de sistema y no nuestro. Lo que molesta no es que rebote: es lo
   que se ve detrás.

   ASÍ QUE EL FONDO DE LA RAÍZ DEJA DE SER NEGRO Y PASA A SER EL CANTO DE ARRIBA
   DE LA ESCENA QUE ESTÉ PUESTA. `hero.js` lo publica al pasar de lámina (§ el
   campo `canto` de ESCENAS), así que el rebote continúa la fotografía en vez de
   cortarla. Y NO PUEDE SER UN COLOR FIJO, que es lo primero que uno intenta:
   medido sobre el recorte vertical real de cada una a 390×844, el canto de
   arriba va de #0d0b0a (Piano) a #9e9387 (Cachorro) — un factor de diez. Un solo
   valor acertaría con una y fallaría con seis.

   EL VALOR ESCRITO AQUÍ ES EL DE SANTOS, y por la misma razón que su `--foco`
   vive en el CSS: Santos es la que abre y la única que se dibuja SIN JavaScript.
   Si `hero.js` no llega, el rebote sigue enseñando el canto correcto.

   `background-color` y no `background` para no pisar nada, y con la MISMA
   duración y curva del fundido de las láminas: si el color saltara de golpe
   mientras las fotografías se disuelven, el salto se vería justo en el borde.

   PENDIENTE DE CONFIRMAR EN EL APARATO DE VICTOR. El rebote elástico es un gesto
   táctil de iOS: no ocurre con el ratón y no se reproduce en este banco. Lo que
   sí está medido aquí son los siete colores y que el color viaja con la
   rotación. */
html{
  background-color:#3b2d20;
  transition:background-color var(--hero-fundido) var(--hero-curva);
}
@media (prefers-reduced-motion: reduce){ html{ transition:none; } }

/* ── EL HERO ─────────────────────────────────────────────────────────────────
   UNA FOTOGRAFÍA A PANTALLA COMPLETA Y UN RÓTULO EN LA ESQUINA. Antes esto era
   un tríptico de WebGL en un canvas; el porqué del cambio está en `index.html`,
   sobre la propia sección.

   EL HERO SIGUE CLAVADO, y eso no es herencia perezosa: es lo que hace que la
   sección de concursos SUBA POR ENCIMA de la fotografía en vez de empujarla, que
   es el gesto del recorrido de este sitio. `.hero__riel` —hermano, en flujo
   normal— es lo único que le da altura al documento, y mide una pantalla.

   `100svh` Y NO `100vh`: en un teléfono `100vh` es la ventana GRANDE, con la
   barra del navegador escondida, así que la fotografía nacería más alta que la
   ventana de ahora y el `cover` recortaría por arriba y por abajo píxeles que no
   hacen falta. `svh` es la ventana pequeña, la que de verdad se ve.

   Y EL NEGRO ESTÁ DECLARADO DEBAJO, no heredado: mientras la lámina baja, lo que
   se ve es el ground del sitio y no el blanco del navegador. */
.hero{
  /* EL TOKEN SE DECLARA AQUÍ Y NO EN CADA RÓTULO, y no es ahorro de líneas: la
     marca y el pie son DOS nodos que tienen que dibujarse con la misma letra, y
     dos declaraciones del mismo token son exactamente como se separan. `--garalda`
     vive en `.concursos` —lo declara `concursos.css` junto a su `@font-face`— y
     fuera de ese árbol no resuelve, así que sin esta línea el hero sale en Times.
     Es la misma cuenta que hace el conmutador de idioma doscientas líneas abajo. */
  --garalda:"Cormorant Concursos", Garamond, "Hoefler Text", "Times New Roman", serif;
  position:fixed; inset:0; z-index:0;
  height:100vh; height:100svh;
  background:var(--negro);
  /* `hidden` PRIMERO Y `clip` DESPUÉS, y aquí el respaldo sí puede ser `hidden`
     sin pagar nada: el estropicio que `clip` evita en el <body> —volverse
     contenedor de scroll y despegar el sticky— no aplica a una caja `fixed` que
     no tiene dentro un solo `position:sticky`. En Safari 15.6 `clip` se cae, se
     queda `hidden` y el hero recorta igual; de 16 en adelante gana `clip` y el
     dibujo es el mismo píxel por píxel. */
  overflow:hidden;
  overflow:clip;
}
/* EL HERO SE GUARDA CUANDO SU RIEL SALE DE PANTALLA. El porqué entero está en el
   script del final del index (§ EL HERO SE GUARDA CUANDO NO LE TOCA): al ser
   `fixed` sigue pintado detrás de TODO el documento, así que cualquier píxel que
   no tape un elemento opaco lo enseña — y contra el rebote de iOS, que revela una
   zona que no pertenece al documento, no hay elemento que se pueda estirar.
   `visibility` y no `display`: no toca el layout. */
body.hero-guardado .hero{ visibility:hidden; }

/* ── EL RIEL ──────────────────────────────────────────────────────────────────
   El hero es `fixed` y no ocupa flujo, así que este `<div>` es lo único que le da
   altura al documento y por tanto quien decide DÓNDE empieza la sección de
   concursos y, con ella, si el `loading="lazy"` de sus láminas sirve de algo.

   MIDE UNA PANTALLA, EN TODAS LAS VENTANAS. Una fotografía quieta no tiene
   recorrido interno que agotar: está agotada desde el primer píxel, y por eso
   `HERO_FIN()` vale 0 y el salto a concursos se dispara con «tantito scroll».
   Es exactamente lo que medía el riel de la portada del bucle —la que mandaba
   por defecto—, así que el recorrido de concursos hacia abajo no se mueve un
   píxel respecto de lo que había.

   Y AHORA ESTÁ EN CSS Y NO EN UN JAVASCRIPT GENERADO. Este número lo escribía
   `medios.js` en el <head>, inyectando una etiqueta `<style>`, porque dependía
   del encuadre del tríptico —N pantallas en relevo, una en tríptico— y eso no se
   sabía sin leer las escenas. Con una sola forma no hay nada que calcular, y una
   regla estática está decidida antes del primer layout sin que corra una línea
   de JavaScript: el `lazy` de los concursos funciona incluso con el JS apagado.

   `svh` ANTES QUE `vh` por la misma razón que en `.hero`, y el `100vh` de
   delante es el respaldo para quien no conozca `svh`. */
.hero__riel{ height:100vh; height:100svh; pointer-events:none; }

/* ── LA LÁMINA · UN PUNTO FOCAL POR ESCENA ───────────────────────────────────
   `cover` para que la fotografía sangre por las cuatro orillas en cualquier
   ventana, y `object-position` MEDIDO —no `center`— porque un `cover` a ciegas
   corta cabezas.

   HASTA EL 16 DE SEPTIEMBRE DE 2026 EL NÚMERO ERA UNO SOLO PARA LAS SIETE, y ése
   era el defecto: Santos y Cachorro se compusieron PARA el hero, y Reloj, Cama,
   Piano, Plata Abrazo y Perlas eran piezas sueltas con el sujeto en otro sitio.
   Una regla global no puede servir a siete composiciones. Victor: «están como
   cortadas, o cortadas abajo o cortadas arriba, no respiran bien».

   AHORA CADA ESCENA TRAE SU PAR DE NÚMEROS, en `--foco`, y en apaisado y en
   vertical por separado. La tabla está abajo, con la caja del grupo de la que
   sale cada uno.

   ── CÓMO SE CALCULÓ, PARA QUE SE PUEDA REHACER ──────────────────────────────
   Con `cover`, la fracción VISIBLE de la lámina en cada eje sale de comparar la
   proporción de la ventana `ab` con la de la imagen `ai`:

     ab > ai  →  se ve todo el ancho y sólo `ai/ab` del alto   (recorte vertical)
     ab < ai  →  se ve todo el alto  y sólo `ab/ai` del ancho  (recorte horizontal)

   Y con una fracción visible `f`, un `object-position` de `p` deja a la vista el
   tramo `[p(1−f), p(1−f)+f]`. O sea que para que la caja del grupo `[b0,b1]` no
   se corte hacen falta las dos:  `p ≤ b0/(1−f)`  y  `p ≥ (b1−f)/(1−f)`.
   El valor elegido es el que MAXIMIZA EL MARGEN MÍNIMO sobre todas las ventanas
   donde el grupo cabe; donde no cabe, reparte la pérdida entre los dos cantos.

   Ventanas con las que se resolvió — apaisado `ab` 1.60 · 1.739 · 1.778 · 1.86 ·
   1.93 · 2.00, vertical `ab` 0.462 · 0.50 · 0.563 · 0.62 · 0.695 · 0.75. La
   apaisada llega a 2.00 y no se queda en 1.778 porque UN NAVEGADOR DE VERDAD ES
   MÁS BAJO QUE SU PANTALLA: en 1440×900 la ventana útil de Chrome ronda 1440×760,
   o sea `ab` 1.90, y ahí el recorte vertical ya vale 6.5 % del alto. Medir sólo a
   1440×900 exactos es medir la única ventana donde este número no hace nada.

   ── LAS SIETE CAJAS, EN FRACCIÓN DE SU LÁMINA ───────────────────────────────
   «el grupo» = ella y los perros, del pelo de la coronilla a la uña de la pata.

     escena          apaisado 16:9 (1672×941)     vertical 9:16 (941×1672)
     santos          x .365-.700  y .36-.97       x .12-.93  y .32-.88
     piano           x .310-.700  y .27-.93       x .00-.96  y .27-.85
     reloj           x .295-.625  y .30-.94       x .09-.94  y .27-.80   (930×1692)
     plata-abrazo    x .375-.630  y .045-.95      x .09-.88  y .09-.98
     cachorro        x .350-.780  y .06-.98       x .26-.94  y .30-.97
     perlas          x .375-.705  y .155-.99      x .15-.93  y .215-.89
     cama            x .245-.790  y .30-.95       x .00-.98  y .345-.79

   ── LA REGLA DEL AIRE · ARRIBA MANDA SOBRE ABAJO ───────────────────────────
   VICTOR, VIENDO LAS SIETE EN PANTALLA: «prefiero que escondas la parte de abajo,
   las patas; me importa menos la parte de abajo que la parte de arriba. Ella
   SIEMPRE tiene que tener aire en la parte de arriba.»

   Eso INVIERTE la prioridad con la que se resolvió la primera pasada, que sólo
   pedía que la cabeza y las patas entraran las dos. Cuando no caben las dos, la
   que entra es la cabeza y el recorte se lo come el SUELO.

   EL SUELO DE AIRE, MEDIBLE Y NO A OJO: el punto más alto del sujeto —la
   coronilla de ella, o la punta de la oreja del perro si está más arriba—
   conserva por encima al menos el 4 % del alto del viewport, y nunca menos de
   24 px. En `cover`, ese aire vale `(y0 − p(1−fv)) / fv` en fracción de la
   ventana, así que GANAR AIRE ES BAJAR `p` HACIA EL 0 %: se enseña más techo y se
   recorta más suelo.

   Y DE AHÍ SALE UNA SOLA REGLA PARA LAS SIETE, no dos parches:

     `p` = el MENOR valor que deja el fondo del grupo dentro —o sea el máximo
     aire arriba sin perder las patas—; y si ése no llega al suelo de aire en
     alguna ventana, se BAJA hasta el mayor que sí lo cumpla, y el suelo de la
     fotografía se pierde lo justo y nada más.

   Cuatro escenas cierran con «patas dentro» y tres pagan suelo: Plata Abrazo,
   Cachorro y Perlas en apaisado, y Plata Abrazo en vertical.

   ── LAS DOS QUE VICTOR SEÑALÓ, CON SU NÚMERO ───────────────────────────────
   · PLATA ABRAZO (apaisado), la peor: lo que se salía por arriba era el perro de
     pie, que es lo que esa fotografía viene a enseñar. Su oreja empieza en y
     .045 y el `47 %` de la pasada anterior dejaba 3.5 % de aire en una ventana de
     `ab` 1.90 — por debajo del suelo. Ahora `6 %`, que es el máximo que admite el
     maestro: 4.5 % en toda ventana de 16:9 o más estrecha y 4.0 % en la peor.
     A cambio pierde hasta un 4.6 % de abajo —la punta de las botas— a `ab` 1.98.
   · CACHORRO (apaisado), la que él llama la más importante: la coronilla de ella
     está en y .06 y con el `75 %` quedaba pegada al canto. Ahora `15 %`: 6.0 % de
     aire en las ventanas sin recorte y 4.8 % en la peor, pagando hasta un 6.7 %
     del suelo — las patas del perro de pie.

   ── EL TECHO DE CADA MAESTRO, QUE ES LO QUE NO SE PUEDE COMPRAR ────────────
   A 1440×900, 1920×1080 y 2000×1150 la lámina 16:9 NO SE RECORTA DE ALTO —la
   ventana es menos alargada que la imagen—, así que el aire de arriba vale
   exactamente `y0` y ningún `object-position` lo cambia. Ése es el techo:
   Plata Abrazo 4.5 %, Cachorro 6.0 %, Perlas 15.5 %, Piano 27 %, Reloj y Cama
   30 %, Santos 36 %. Las dos primeras están ahí por el encuadre del maestro, no
   por esta hoja de estilo; más aire que ése pide otro maestro.

   ── EL EJE HORIZONTAL SIGUE LA MISMA REGLA: SI NO CABEN LAS DOS, GANA LA CABEZA
   Tres verticales no caben de ancho —el sujeto mide más que la ventana— y una de
   ellas la nombró Victor probándola en el teléfono.

   · CAMA, y es la que él nombró: «no quiero que se le corte la cabeza al perro».
     El danés está echado A LO LARGO y el grupo mide el 98 % del ancho; a 390×844
     se ve el 82.1 %, o sea que faltan 15.9 puntos. La cabeza dormida es el sujeto
     de esa fotografía tanto como la coronilla de ella, y está pegada al canto
     IZQUIERDO: el hocico empieza en x .02 y la cabeza entera va de .02 a .23.
     REPARTIR LA PÉRDIDA POR LOS DOS LADOS —el 44 % de la primera pasada— metía la
     orilla visible en .079 y le cortaba el hocico. Con `0 %` la orilla izquierda
     caía en .000 y entraban la cabeza y las patas delanteras completas; lo que se
     va es el 17.9 % de la derecha, o sea los cuartos traseros y la cola. Mismo
     criterio que el aire de arriba, aplicado al eje de las x.
     HOY VA EN `8 %` Y ESE NÚMERO ES UN TOPE, NO UN GUSTO. Victor la quiso «un
     poquito a la izquierda», que en `cover` es subir la x; pero cada punto de x
     se come .179 puntos de la orilla izquierda, y el hocico empieza en .020. El
     último valor que no lo toca es el 11.2 %, así que el empujón se para en 8 y
     deja .006 de margen — un pelo de foto, pero medido. Más allá de ahí no es un
     encuadre más apretado: es la cabeza cortada que él prohibió por su nombre.
   · PIANO: el grupo mide el 96 % del ancho, faltan 13.9 puntos. Aquí sí se
     reparte (39 %) porque ninguna de las dos cabezas está en un canto: se va la
     pata delantera del perro izquierdo y la cola del derecho, ~7 % cada una.
   · RELOJ: 85 % contra 84.1 % —su maestro es 930×1692 y no 941×1672—. Faltan 0.9
     puntos, 4 px en un teléfono de 390. Se reparten.

   ── LOS CUATRO EMPUJONES DE VICTOR EN EL TELÉFONO, Y HACIA DÓNDE VAN ────────
   «Un poquito. No mucho», mirando las siete en vertical. En `cover` SUBIR LA x
   CORRE EL SUJETO HACIA LA IZQUIERDA —se enseña más del lado derecho de la
   fotografía—, y eso está comprobado mirando los abanicos de cuatro valores por
   escena, no aplicando la fórmula a ciegas:

     CAMA           0 % → 8 %    izquierda, y el 8 es el tope del hocico (arriba)
     RELOJ         67 % → 75 %   izquierda
     PLATA ABRAZO  42 % → 50 %   izquierda; a 66 ella empieza a tocar el canto
     PERLAS        72 % → 64 %   derecha; a 48 el danés izquierdo se corta

   CACHORRO NO SE TOCA: Victor la dio por buena por su nombre. Y el apaisado no
   se toca en ninguna de las siete: estos cuatro números son sólo del bloque
   vertical, que es el que él tiene delante en el teléfono.

   ── RELOJ BAJA DEL 25 % AL 0 % EN VERTICAL, Y NO ROMPE ESTA REGLA: LA ESTIRA ──
   Victor, en el iPhone y con el rótulo de tres alturas ya puesto: «la del reloj
   creo que la tenemos que hacer para abajo, bastante, especialmente si el título
   va a estar arriba». Bajar el SUJETO es exactamente lo mismo que ganar aire
   arriba —`GANAR AIRE ES BAJAR p HACIA EL 0 %`, cinco párrafos más arriba—, así
   que este empujón tira en la MISMA dirección que la regla y no contra ella: el
   0 % es el extremo de la escala, o sea el máximo aire que admite el maestro
   (su techo es 30 %) y el máximo suelo recortado. Lo que se pierde por abajo son
   las patas delanteras del danés echado, que es el precio que la regla ya tenía
   escrito. De las siete, ésta es la ÚNICA que se toca: Victor dice que muchas van
   a necesitar bajar con el título puesto, pero no puede juzgarlas hasta verlo.

   Y en apaisado, a partir de `ab` 2.00 —un monitor ancho con la ventana muy baja—
   PLATA ABRAZO (le faltan 1.7 puntos de alto) y CACHORRO (3.2) no caben enteras.
   Ahí manda la regla del aire: se pierde el suelo y la cabeza se queda.

   ── POR QUÉ LA TABLA VIVE EN EL CSS Y NO EN `ESCENAS` DE `hero.js` ──────────
   Porque el par de números CAMBIA CON LA ORIENTACIÓN, y quien conoce la
   orientación es el CSS. Metidos en el JavaScript harían falta un `matchMedia`,
   una escucha de giro de teléfono y un reescribir del estilo en línea a cada
   cambio — y sobre todo: LA PRIMERA LÁMINA NO PASA POR `hero.js`. Santos vive en
   el `<picture>` de `index.html` y se dibuja con el JavaScript apagado; su foco
   tiene que llegarle por la misma puerta que a las otras seis o serían dos
   verdades. Lo único que pone el JavaScript es la CLASE —`hero__foto--<nombre>`,
   que sale de `esc.nombre` y no se escribe dos veces—, y el `<img>` del index la
   trae puesta a mano. */
.hero__foto{
  /* `absolute` Y NO EL `block` DE ANTES, y con una sola lámina dibuja el mismo
     píxel: `.hero__laminas` es `absolute; inset:0` dentro de un `.hero` que es
     `fixed; inset:0`, así que la caja es la misma pantalla completa de siempre.
     Lo que compra es que las láminas se APILEN: dos fotografías en el flujo se
     pondrían una debajo de la otra y el hero mediría dos pantallas. */
  position:absolute; inset:0;
  display:block; width:100%; height:100%;
  object-fit:cover;
  /* EL RESPALDO ES EL DE ANTES —`50% 82%`— y no es decorativo: lo usa cualquier
     lámina que llegue sin clase de escena, que hoy no existe y mañana puede
     existir si alguien añade una fila a `ESCENAS` y olvida su fila de aquí. Una
     lámina sin foco se ve centrada, no rota. */
  object-position:var(--foco, 50% 82%);
  /* EL NÚMERO DEL FUNDIDO NO ESTÁ AQUÍ Y NO ES UN OLVIDO: lo escribe `hero.js`
     en `--hero-fundido` al arrancar, y es el ÚNICO sitio del sitio donde vive
     —`SEGUNDOS_DE_FUNDIDO`, arriba de ese archivo, junto a los segundos por
     lámina—. Un respaldo aquí sería la segunda copia del mismo número, y las dos
     copias se separan el día que Victor cambie una.
     Y SIN JAVASCRIPT LA VARIABLE NO EXISTE, con lo que esta `transition` entera
     es inválida y no hay transición. Es exactamente lo correcto: sin JavaScript
     tampoco hay rotación que fundir, y el hero es el hero quieto de siempre.

     LA CURVA VIENE POR LA MISMA PUERTA Y POR LA MISMA RAZÓN (`--hero-curva`,
     `CURVA_DEL_FUNDIDO` en `hero.js`). Era `linear` hasta el 16 de septiembre de
     2026; ahora es la cúbica in-out que `🔭 Estudio-Horoscopo` cronometró en el
     template que Victor quiso copiar, junto con los 1 178 ms. Una cúbica in-out
     no arranca: se queda quieta, cruza rápido por el medio y se posa, y eso es lo
     que hace que el cambio se lea como un pase de página. Es lo ÚNICO que se
     copió de aquella transición —el efecto era un shader de WebGL— y costó
     0 bytes. */
  transition:opacity var(--hero-fundido) var(--hero-curva);
}
/* ── EL ORDEN DE APILAMIENTO DEL HERO, EN UN SITIO Y CON SU PORQUÉ ────────────
   Cuatro capas y cada número está obligado por la de al lado:

     0  `.hero__laminas`   las fotografías
     1  `.hero__lumbre`    el disco de luz del cursor
     2  `.hero::after`     la caída de luz que le da contraste al texto
     3  `.hero__portada` y `.hero__baja`  el texto y la rueda de scroll

   LA LUMBRE OBLIGÓ A SUBIR LAS DOS DE ARRIBA, y no es cosmética: `mix-blend-mode`
   se funde con lo que hay debajo DENTRO DE SU CONTEXTO DE APILAMIENTO. Si la
   lumbre se quedara empatada con la caída de luz en 1, se fundiría CON ELLA y no
   con la fotografía, que es justo lo que no se quiere. Tiene que ir encima de las
   láminas y debajo de la caída, o sea que la caída sube a 2 y el texto a 3.
   Lo midió `🔭 Estudio-Horoscopo` y es la única trampa del efecto.

   LA CAJA DONDE SE BARAJAN. `z-index:0` —no `auto`— para que sea su propio
   contexto de apilamiento: dentro, `hero.js` sube el z-index de la lámina que
   entra vuelta tras vuelta sin techo, y nada de eso puede asomar por encima de
   las tres capas de arriba. El porqué del `z-index` que sube está en `hero.js`,
   sobre `pasaA()`. */
.hero__laminas{ position:absolute; inset:0; z-index:0; }
/* LA LÁMINA QUE ESPERA SU TURNO. La primera NO lleva esta clase —nace opaca y se
   ve sin una línea de JavaScript—; las demás las crea `hero.js` con ella puesta
   y se la quita al pasarles el turno. */
.hero__foto--espera{ opacity:0; }
/* ── EL FOCO DE CADA ESCENA · VERTICAL ARRIBA, APAISADO ABAJO ────────────────
   El orden de los dos bloques ES la regla: el vertical va primero y sin consulta
   —es el respaldo— y el apaisado lo pisa cuando la ventana es más ancha que alta.
   La frontera es `orientation`, letra por letra la misma que llevan los
   `<source>` del `<picture>` y la que reparte los encuadres en `hero.js`; si
   divergen, el navegador dibuja un encuadre con el foco del otro.
   Las cajas de las que salen estos catorce números están en el comentario
   grande de arriba, con la cuenta para rehacerlos. */
.hero__foto--santos      { --foco: 64% 52%; }
.hero__foto--piano       { --foco: 39% 40%; }   /* no cabe de ancho: reparte */
.hero__foto--reloj       { --foco: 75%  0%; }   /* los dos empujones de Victor; ver abajo */
.hero__foto--plata-abrazo{ --foco: 50% 24%; }   /* suelo sacrificado · empujón */
.hero__foto--cachorro    { --foco:100% 88%; }
.hero__foto--perlas      { --foco: 64% 56%; }   /* empujón a la derecha */
.hero__foto--cama        { --foco:  8% 16%; }   /* el tope del hocico; ver abajo */
@media (orientation: landscape){
  .hero__foto--santos      { --foco: 83% 82%; }
  .hero__foto--piano       { --foco: 55% 58%; }
  .hero__foto--reloj       { --foco: 10% 64%; }
  .hero__foto--plata-abrazo{ --foco: 52%  6%; }   /* suelo sacrificado; ver arriba */
  .hero__foto--cachorro    { --foco:100% 15%; }   /* suelo sacrificado */
  .hero__foto--perlas      { --foco: 90% 72%; }   /* suelo sacrificado */
  .hero__foto--cama        { --foco: 68% 70%; }
}

/* ── EL LIENZO DEL MÁRMOL ────────────────────────────────────────────────────
   El `<canvas>` donde `hero-shader.js` licúa las dos fotografías durante el
   cruce. No está en el HTML y no puede estarlo: existe sólo cuando hay
   JavaScript Y WebGL Y no se ha pedido menos movimiento, y `hero.js` lo crea
   dentro de `.hero__laminas` después del primer pintado.

   `display:none` DE ENTRADA Y VISIBLE UN SEGUNDO POR VUELTA. Entre lámina y
   lámina no dibuja nada, así que además de ocultarlo `hero.js` lo baja a 1×1
   para devolver el búfer — ver `duerme()`. Las dos cosas hacen falta: ocultarlo
   sin vaciarlo deja la memoria reservada, y vaciarlo sin ocultarlo enseñaría un
   píxel estirado a pantalla completa.

   VIVE DENTRO DE `.hero__laminas` Y NO SUELTO EN `.hero`, y eso es lo que deja
   la lumbre en su sitio: `.hero__laminas` es `z-index:0` y su propio contexto de
   apilamiento, así que el `z-index` que `hero.js` le sube al lienzo para ponerlo
   por encima de la lámina que entra NO PUEDE asomar por encima del disco de luz
   (1), la caída de luz (2) ni el texto (3). El mármol pasa por debajo de la lumbre,
   que es donde tiene que pasar. */
.hero__licua{
  position:absolute; inset:0;
  display:none;
  width:100%; height:100%;
}
.hero__licua.es-visible{ display:block; }
/* Y MIENTRAS EL MÁRMOL CORRE, LAS LÁMINAS NO SE FUNDEN. El canvas ya está
   tapando la pantalla con las dos fotografías dentro, así que la que entra se
   pone opaca de golpe y debajo: fundir además con CSS sería cruzar dos veces la
   misma pareja y el resultado se ve lavado en el medio. La clase la pone y la
   quita `pasaA()`, y sin ella —o sin JavaScript— la `transition` de siempre. */
.hero__laminas.es-licua .hero__foto{ transition:none; }

/* ── LA LUMBRE · UN DISCO DE LUZ QUE SIGUE AL CURSOR ─────────────────────────
   El efecto que Victor mandó copiar del template del horóscopo, y el único de
   aquella página que se copia ENTERO: un degradado radial blanco fundido en
   `overlay`, que es el modo que aclara lo claro y respeta lo oscuro — o sea que
   sobre esta fotografía se lee como una linterna suave y no como un velo. Medido
   por `🔭 Estudio-Horoscopo`: +33.9 de RGB a 100 px del centro y +0.3 a 350, con
   lo que la caída muere dentro del disco y no ensucia el resto de la pantalla.

   CERO BYTES DE DESCARGA. El template gasta 4.8 KB comprimidos de `mousetrap.js`
   para esto; aquí el degradado y la fusión son CSS y del JavaScript sólo salen
   `--lx` y `--ly`, que es dónde está el cursor.

   NUEVE PARADAS Y NO LAS TREINTA Y UNA DEL ORIGINAL. Las suyas son una sinusoide
   muestreada por su editor; con nueve la caída no se escalona y son 300 B en vez
   de 1 100.

   `display:none` DE ENTRADA Y SE ENCIENDE POR CAPACIDAD DEL PUNTERO. En un
   teléfono este `<div>` no se dibuja NUNCA —ni una capa, ni un byte— y no hay
   sustituto táctil, que es deliberado: un efecto cuyo argumento es «dónde está el
   cursor» no tiene traducción en un dedo. El template lo deja en
   `visibility:hidden`, que es pagar el nodo para no verlo.

   Y CON `prefers-reduced-motion` DESAPARECE. El template NO lo respeta —está
   verificado en el informe—; aquí el `display:none` gana a la consulta de puntero
   por venir después, y `hero.js` además no escribe las variables. */
.hero__lumbre{
  display:none;                 /* ← sólo con puntero fino, dos reglas más abajo */
  position:absolute; inset:0; z-index:1;
  pointer-events:none;          /* no se toca: es luz, no un control */
  opacity:0;
  /* `overlay` sobre la lámina y NO sobre el negro de `.hero`: por eso z-index 1,
     encima de `.hero__laminas` y debajo de la caída de luz. Ver la tabla de
     apilamiento sobre `.hero__laminas` — si empata con ella, se funden. */
  mix-blend-mode:overlay;
  transition:opacity var(--lumbre-fundido) var(--lumbre-curva);
}
/* EL DISCO VA EN EL PSEUDOELEMENTO Y NO EN LA CAJA, y es lo que deja animar dos
   cosas por separado con la misma curva: la caja hace el `opacity` y el disco el
   `scale`. Sin el `scale` la lumbre no APARECE, se enciende — y esa mitad del
   gesto es la que se nota. */
.hero__lumbre::before{
  content:''; position:absolute;
  width:var(--lumbre-d); height:var(--lumbre-d);
  /* `--lx`/`--ly` las escribe `hero.js` en píxeles de ventana. El respaldo es el
     centro: si el script no corre, el `<div>` está en `opacity:0` y no se ve
     nada, pero un `left` sin valor sí sería un error de sintaxis que se llevaría
     por delante la regla entera. */
  left:var(--lx, 50%); top:var(--ly, 50%);
  transform:translate(-50%, -50%) scale(var(--lumbre-s, 0));
  transition:transform var(--lumbre-fundido) var(--lumbre-curva);
  border-radius:50%;
  background:radial-gradient(circle,
    rgba(255,255,255,.80) 0%,  rgba(255,255,255,.66) 17%, rgba(255,255,255,.44) 30%,
    rgba(255,255,255,.20) 43%, rgba(255,255,255,.08) 52%, rgba(255,255,255,0)  65%,
    rgba(255,255,255,0) 100%);
}
/* LOS TRES NÚMEROS DEL GESTO, JUNTOS Y CON SU PROCEDENCIA. El diámetro y el medio
   segundo salen del template medido; la curva es LA MISMA del fundido de las
   láminas, y que sean la misma es la decisión: la portada tiene un solo
   temperamento y no dos.

   AQUÍ SÍ SE ESCRIBE LA CURVA A MANO y en `.hero__foto` no. No es una
   incoherencia: aquél es el número que Victor cambia —vive arriba de `hero.js`,
   con los segundos por lámina— y éste es una constante del efecto. Un valor que
   sólo se toca aquí no gana nada por dar un rodeo por el JavaScript, y perdería
   lo único que importa: que la lumbre se vea igual con el script apagado... que
   es que no se vea, porque sin `--lx` no hay nada que encender. */
.hero__lumbre{
  --lumbre-d:700px;
  --lumbre-fundido:500ms;
  --lumbre-curva:cubic-bezier(.645, .045, .355, 1);
}
@media (hover: hover) and (pointer: fine){
  .hero__lumbre{ display:block; }
}
/* `.tiene-lumbre` LA PONE `hero.js` y sólo cuando va a poder mover el disco. Sin
   JavaScript el `:hover` no llega aquí y no se enciende nada — que es lo correcto:
   encendido y quieto en el centro de la pantalla se vería peor que apagado. */
.hero.tiene-lumbre:hover .hero__lumbre{ opacity:1; }
.hero.tiene-lumbre:hover .hero__lumbre::before{ --lumbre-s:1; }
@media (prefers-reduced-motion: reduce){
  .hero__lumbre{ display:none; }
}

/* ── EL CANTO DE ARRIBA · LA FOTOGRAFÍA ACUSA EL EMPUJÓN ──────────────────────
   Arriba del todo el único elemento agarrable es la lámina, así que el empujón
   contra el borde superior lo acusa ELLA, creciendo un pelo contra el dedo como
   una fotografía que se aprieta y no cede. Es el gesto de las cabeceras de foto
   de las aplicaciones, que es literalmente como lo pidió Victor.

   Y AQUÍ SIGUE LA REGLA DURA DE AQUELLA LANE, que ahora vale igual: EL MUELLE DE
   ARRIBA SÓLO PUEDE REBASAR HACIA ARRIBA. `--cima` está topado en 0 por el
   script, así que esta escala nunca baja de 1. Una escala de 0.99 sobre un
   elemento a pantalla completa dentro de un `fixed` ABRE UN MARCO en los cuatro
   cantos, y por ese marco se ve lo que haya debajo del hero — que es el agujero
   de dceb633 y de 1431d9e por una puerta nueva.

   VA COLGADO DE UNA CLASE Y NO COMO `transform:scale(1)` PERMANENTE: en reposo la
   lámina no lleva transform ninguno y no cuesta una capa mientras nadie empuja.
   Antes esto vivía sobre `.hero__lienzo`, el `<div>` que envolvía el canvas del
   tríptico; el elemento cambió de nombre y de naturaleza, el gesto no. */
body.rebota-cima .hero__foto,
body.rebota-cima .hero__licua{
  transform:scale(calc(1 + var(--cima, 0) * var(--lamina, .015)));
  transform-origin:50% 50%;
}

/* ── LA CAÍDA DE LUZ · LOS DOS CANTOS DE LA FOTOGRAFÍA, DE PUNTA A PUNTA ─────
   NO ES ATMÓSFERA: ES CONTRASTE, Y SALE DE UNA MEDIDA. El texto de la portada ya
   no vive en una esquina: son tres alturas CENTRADAS —membrete y marca pegados al
   canto de arriba, oficio pegado al de abajo—, y debajo de cada una puede caer
   cualquier cosa de siete fotografías distintas. Medido sobre las capturas, la
   crema de la casa (#e8ddc8, L 0.7303) pide un fondo de L ≤ 0.1234 para llegar a
   4.5:1, y el canto de arriba de CACHORRO es #9e9387 (L 0.2988): sobre él la
   palabra da 2.19:1 sin nada debajo. Ilegible, y no en un caso raro — es el borde
   entero de la lámina más clara de las siete.

   ── POR QUÉ ES UN DEGRADADO DE CANTO A CANTO Y NO UNA VIÑETA ────────────────
   Hasta hoy esto era una elipse anclada en `0% 100%`, la esquina de abajo a la
   izquierda, porque ahí y sólo ahí había texto. Con el texto centrado esa elipse
   no sirve para nada: cae fuera de las tres alturas nuevas y deja el membrete y
   las dos palabras grandes a la intemperie. Y una elipse CENTRADA tampoco vale,
   que fue el segundo intento y el que Victor vio y nombró: «lo horripilante que
   es la pinche mancha negra». Una elipse sobre un texto es una MANCHA — tiene
   forma, tiene centro y se ve —, y da igual que el contraste salga bien.

   LO QUE NO SE VE ES LA CAÍDA DE LUZ DE UNA PORTADA IMPRESA: los dos cantos
   horizontales oscurecidos ENTEROS, sin centro y sin forma, apagándose hacia el
   medio a lo largo de casi media pantalla. No hay canto que detectar porque no
   hay un sitio donde el degradado empiece: empieza en el borde del papel. Es
   exactamente lo que hace la fotografía de la referencia por sí sola —su borde
   superior es oscuro y por eso GRAN se lee sin una caja detrás—, y aquí se
   fabrica para las siete, incluidas las dos que no lo traen puesto.

   ── LAS CIFRAS ────────────────────────────────────────────────────────────
   `.60` en el canto y CINCO paradas hasta cero en el 48 %. El .60 sale de la peor
   medición: sobre #9e9387 un negro al 36 % ya cruza el 4.5:1, y de ahí al .60 hay
   el margen que se come el rebote de arriba —que enseña ese mismo canto— y la
   mancha de sol de RELOJ. Las cinco paradas son lo que borra el escalonado: con
   tres, la caída se ve a bandas en un degradado tan largo; con cinco, no. Y el
   48 % es el punto en que las dos caídas se encuentran en cero, o sea que en el
   medio de la pantalla la fotografía está intacta.

   `pointer-events:none` porque no hay nada que tocar aquí, y `z-index:2` para
   quedar entre la lumbre y el texto — la tabla del apilamiento está arriba,
   sobre `.hero__laminas`, y ahí se explica por qué este número era 1 hasta que
   entró la lumbre. */
.hero::after{
  content:''; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.60) 0%, rgba(0,0,0,.52) 8%,
      rgba(0,0,0,.34) 18%, rgba(0,0,0,.16) 28%, rgba(0,0,0,.05) 38%, rgba(0,0,0,0) 48%),
    linear-gradient(to top,    rgba(0,0,0,.60) 0%, rgba(0,0,0,.52) 8%,
      rgba(0,0,0,.34) 18%, rgba(0,0,0,.16) 28%, rgba(0,0,0,.05) 38%, rgba(0,0,0,0) 48%);
}

/* ══ LA PORTADA ══════════════════════════════════════════════════════════════
   Membrete, palabra grande, fotografía, palabra grande. El porqué de la
   composición está en `index.html`, sobre su marcado; aquí viven las medidas.

   UNA SOLA CAJA A SANGRE Y `space-between`, y eso es lo que hace el sándwich: la
   cabecera se planta contra el canto de arriba, el oficio contra el de abajo y el
   hueco de en medio —la fotografía— es lo que sobra. Con tres cajas posicionadas
   por su cuenta ese hueco sería la resta de tres números y cambiaría de signo en
   cuanto el cuerpo de una palabra creciera; aquí no hay resta que hacer.

   `--garalda` SE DECLARA AQUÍ y no se hereda, por lo mismo que en el conmutador
   de idioma: el token vive en `.concursos` —donde lo declara `concursos.css`— y
   fuera de ese árbol no resuelve. Sin esta línea la portada entera sale en Times.

   SE PUEDE SELECCIONAR, y por eso NO lleva `pointer-events:none`: es texto de
   verdad y se copia como texto de verdad. Que cubra el hero entero no le quita el
   hover a nadie —la lumbre escucha en `.hero`, y un evento sobre un hijo pasa por
   el padre— ni tapa ningún control, porque dentro del hero no hay ninguno. */
.hero__portada{
  position:absolute; inset:0; z-index:3;
  display:flex; flex-direction:column; justify-content:space-between;
  align-items:center; text-align:center;
  padding:var(--portada-techo) clamp(.6rem, 2.5vw, 2rem) var(--portada-suelo);
  --garalda:"Cormorant Concursos", Garamond, "Hoefler Text", "Times New Roman", serif;
}

/* LOS TOKENS DEL CUERPO CUELGAN DE `.hero` Y NO DE LA PORTADA, y no es un gusto:
   el indicador de scroll es HERMANO de la portada, no hijo, y una custom property
   viaja hacia abajo pero nunca de lado. Puesto en la portada, `.hero__baja` no
   podría leer el cuerpo de la palabra que tiene que esquivar y el número volvería
   a estar tecleado dos veces. El único ascendiente de los dos es `.hero`.

   ── EL CUERPO DE LAS DOS PALABRAS GRANDES, Y DE DÓNDE SALE ────────────────
     LA PALABRA CRUZA LA PANTALLA, así que su cuerpo no es un número elegido: es
     el que hace que ESA palabra mida el 88 % del ancho. Y eso depende de cuántos
     ems ocupa la palabra, que cambia con cada idioma — KENNEL son seis letras y
     CRIADERO ocho, y con un cuerpo común la inglesa se quedaría a un tercio del
     ancho de la española.

     `--em-*` ES EL ANCHO DE LA PALABRA EN EMS, MEDIDO Y NO CALCULADO. Se saca
     pintándola a 100 px con este mismo tracking y dividiendo el ancho por 100:

         GRAN DANÉS 7.55    GREAT DANE 7.44    CRIADERO 6.11    KENNEL 4.54

     Si mañana cambia una de las cuatro palabras, ESTE es el número que hay que
     volver a medir; el cuerpo sale solo. Y si alguien lo olvida, lo que se ve es
     una palabra corta o desbordada —un fallo que se ve—, no un silencio.

     EL TOPE ESTÁ EN `svh` Y NO EN PÍXELES porque lo que topa es el reparto de la
     pantalla, no el tamaño de la letra: en una ventana apaisada y baja —un iPhone
     tumbado, 844×390— el 88 % del ancho serían 122 px de cuerpo y la palabra de
     abajo se comería el 29 % del alto ella sola. Con el tope en 26svh las dos
     puntas juntas nunca pasan de la mitad de la pantalla y la fotografía conserva
     la otra mitad, que es la que trae los perros. */
.hero{
  /* el relleno de la portada vive aquí por lo mismo que el cuerpo: el indicador
     de scroll se aparta del canto de abajo con ESTE número y no con una copia */
  --portada-techo:calc(.95rem + env(safe-area-inset-top, 0px));
  --portada-suelo:calc(.35rem + env(safe-area-inset-bottom, 0px));
  --em-marca:7.55;
  --em-oficio:6.11;
  --cuerpo-marca: min(calc(88vw / var(--em-marca)),  26svh);
  --cuerpo-oficio:min(calc(88vw / var(--em-oficio)), 26svh);
}
/* EL INGLÉS MIDE OTRA COSA. `pon()` cambia el texto y escribe `lang` en el
   <html> (index.html, al final), así que el CSS se entera del idioma sin que
   nadie le avise. Sin JavaScript el documento se queda en `lang="es"`, que es lo
   que trae escrito, y los números de arriba son los correctos. */
:root[lang="en"] .hero{ --em-marca:7.44; --em-oficio:4.54; }

/* LA CABECERA SON DOS ALTURAS PEGADAS, Y POR ESO TIENEN CAJA PROPIA.
   `space-between` reparte el aire entre los HIJOS de la portada: con el membrete,
   la marca y el oficio sueltos serían tres hijos y el hueco caería también entre
   el membrete y la marca, que es justo lo que no puede pasar — el membrete es el
   renglón de arriba de la marca, no una tercera pieza. */
.hero__portada__cabeza{
  display:flex; flex-direction:column; align-items:center;
  gap:clamp(.4rem, 1.2svh, .9rem);
}

/* ── EL MEMBRETE ─────────────────────────────────────────────────────────────
   Una línea fina de versalitas en lo alto que dice qué es esto, dónde está y
   desde cuándo. Lleva `.cintillo` PEGADO en el HTML, así que el tracking, las
   mayúsculas, el cuerpo y el `wght` 600 le llegan de `concursos.css`; aquí sólo
   está lo que cambia respecto de un cintillo cualquiera.

   YA NO SE APARTA DEL CONMUTADOR DE IDIOMA, y esa es la mitad de lo que se
   simplifica al centrarlo: antes vivía anclado a la izquierda con un `max-width`
   calculado para dejarle libre la banda del conmutador. Centrado, el ancho que
   ocupa se reparte por los dos lados y en la ventana más ancha en que cabe de una
   pieza —701 px— su canto derecho queda a 42 px del conmutador. La cuenta se cae
   sola y no hay nada que esquivar.

   Y NO TRAE VIÑETA. Tuvo una —una elipse negra dibujada sobre una caja mayor que
   el texto— y era la segunda de las dos manchas que Victor mandó quitar. El
   contraste lo da ahora la caída de luz del canto de arriba, que es la misma para
   las tres alturas y no dibuja una forma detrás de ninguna. Las siete mediciones,
   en `Taller/Auditoria/Hero-Portada · Informe.md`.

   EL `text-indent` COMPENSA EL TRACKING: abre por la DERECHA de la última letra,
   así que una línea centrada se ve corrida media unidad hacia la izquierda. Se
   devuelve la MITAD, que es lo que sobra por ese lado. */
.hero__membrete.cintillo{
  margin:0;
  /* 92 % Y NO UN `ch`: el `ch` mide la cifra CERO de la fuente y este rótulo va a
     .34em de tracking, o sea que cada carácter ocupa casi el doble de un `ch`.
     Un `max-width:60ch` partía en dos la línea a 1440 px, donde cabe de sobra. */
  max-width:92%;
  line-height:1.5;
  color:var(--tinta);
  text-shadow:0 1px 10px rgba(0,0,0,.6), 0 0 3px rgba(0,0,0,.5);
  text-indent:.17em;
}
/* EL CORTE POR EL `·`. De 700 px para arriba la línea se lee de una pieza; por
   debajo vuelven los `<br>` que viajan en el texto y en el diccionario, y la
   línea cae en dos tramos limpios sin cortar una frase. */
.hero__membrete br{ display:none; }
@media (max-width:700px){ .hero__membrete br{ display:inline; } }

/* ── LAS DOS PALABRAS GRANDES ────────────────────────────────────────────────
   Las dos son la MISMA regla porque son la misma pieza vista dos veces: el
   sándwich de la portada. Lo único que las distingue es el cuerpo, y el cuerpo
   sale de cuántos ems mide cada palabra (§ arriba, `--em-*`).

   MAYÚSCULAS CON TRACKING Y NI UNA VERSALITA, que es la regla de la casa desde
   que Victor vio el A/B: `text-transform:uppercase`, nunca `font-variant-caps`.

   `wght` 300 Y NO EL 500 DE ANTES, y no es un capricho: 500 era el peso de un
   rótulo de 40 px donde el asta fina todavía necesita ayuda. Aquí el cuerpo pasa
   de 200 px en una ventana de escritorio, y a ese tamaño el grueso de un 500
   tapa justo el contraste de asta que hace que una garalda sea una garalda. 300
   es el extremo ligero del eje real de Cormorant (§ `@font-face`, 300 700) y es
   el peso de una portada impresa.

   `letter-spacing:.14em` — tracking generoso, que es lo que separa un titular de
   una palabra grande. Cuesta ancho: a .14em GRAN DANÉS mide 7.55 em contra los
   6.15 que mediría sin tracking, o sea que la letra sale un 19 % más chica para
   ocupar el mismo sitio. Se paga porque una portada se lee por el aire entre
   letras, no por el tamaño.

   `line-height:.92` Y NO 1: a este cuerpo, la interlínea normal de la fuente deja
   por encima y por debajo de las versales un aire muerto de decenas de píxeles
   que separa la palabra de su canto y deshace el sándwich. .92 aprieta la caja
   contra las versales — no hay descendentes en ninguna de las cuatro palabras y
   los acentos de DANÉS caben dentro (medido: la Á sube 0.71 em sobre la base y la
   caja da 0.92).

   `white-space:nowrap` NO ES DECORACIÓN, ES EL REQUISITO 5: la palabra grande no
   se parte ni desborda a 320 px. Y no se parte POR CONSTRUCCIÓN y no por suerte:
   el cuerpo es una fracción del ancho de la ventana, así que a cualquier anchura
   la palabra mide el mismo 88 % de ella. El `nowrap` es el centinela de que la
   cuenta de ems sigue siendo verdad — si alguien cambia el texto y olvida el
   número, se ve desbordar.

   EL `margin-left` ES EL AJUSTE ÓPTICO DEL TRACKING, y aquí importa más que en el
   membrete porque el cuerpo es veinte veces mayor: la caja de la palabra incluye
   el hueco que abre la última letra por su derecha, así que centrarla deja los
   trazos .07 em corridos a la izquierda. Con la caja centrada por el flex, un
   margen izquierdo de .14 em se reparte a medias y devuelve exactamente eso.

   LA SOMBRA NO SUSTITUYE A LA CAÍDA DE LUZ y no está por eso: la caída es la que
   garantiza el 4.5:1 y esto es el medio píxel de asiento que separa la crema del
   grano de la fotografía. */
.hero__marca,
.hero__oficio{
  margin:0;
  font-family:var(--garalda);
  font-variation-settings:"wght" 300;
  line-height:.92;
  letter-spacing:.14em;
  margin-left:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  color:var(--tinta);
  text-shadow:0 1px 14px rgba(0,0,0,.5), 0 0 4px rgba(0,0,0,.45);
}
.hero__marca { font-size:var(--cuerpo-marca); }
.hero__oficio{ font-size:var(--cuerpo-oficio); }


/* ── EL INDICADOR DE SCROLL ───────────────────────────────────────────────────
   Una rueda de ratón abajo del hero diciendo «baja». El porqué de que exista, de
   que sea un ratón y de que viva en el HTML está sobre su marcado, en el index.
   Aquí van las tres medidas que no son obvias.

   ── EN MEDIO SE QUEDA, Y AHORA LO QUE HAY EN MEDIO ES UNA PALABRA ENORME ───
   Victor lo pidió «justamente en medio», y en medio y abajo vive desde hoy la
   segunda mitad del sándwich de la portada: el oficio cruzando la pantalla. No es
   un vecino del que apartarse por el lado —ocupa el 88 % del ancho en TODA
   ventana— así que el icono sube por encima de ÉL. Es la misma cura que esta
   regla ya aplicaba cuando el vecino era el rótulo de la esquina; lo que cambia
   es el vecino, no el criterio.

   ── Y LO QUE CAMBIA DE VERDAD ES DE DÓNDE SALE EL NÚMERO ───────────────────
   Hasta hoy eran dos escalones tecleados —6.6rem por debajo de 560 px y 1.7rem
   hasta 1000— y una tabla de ocho ventanas midiendo cuándo el rótulo de la
   esquina cruzaba el centro. Esa tabla describía una caja que ya no existe: la
   marca y el pie vivían abajo a la izquierda, tenían suelo de cuerpo y por eso
   cruzaban el centro sólo en algunas anchuras. Un número medido contra una caja
   que se fue no es un número conservador: es un número que miente, y el día que
   alguien lo lea creerá que describe lo que hay.

   Hoy el icono se planta leyendo EL CUERPO de la palabra que esquiva
   —`--cuerpo-oficio`, el mismo token del que cuelga su `font-size`—, así que no
   hay dos verdades que mantener de acuerdo: cambie la palabra, el idioma o la
   ventana, el icono se entera solo y los escalones sobran. La cuenta, de abajo
   arriba: el relleno de la portada, la caja de la palabra (su cuerpo por el .92
   de su interlínea) y un dedo de aire.

   ── `env(safe-area-inset-bottom)` SE SUMA, NO SE COME ──────────────────────
   En un iPhone sin botón, los últimos 34 px de la ventana son la barra del
   gesto: un icono clavado ahí queda debajo del indicador del sistema y encima de
   la zona donde el dedo arrastra para cerrar la aplicación. Ya viene sumado
   dentro de `--portada-suelo`, que es el mismo relleno con el que la palabra de
   abajo se aparta de ese borde — los dos se apartan de lo mismo y por el mismo
   número.

   ── Y EL VALOR DE REPOSO ES EL DE SIEMPRE ──────────────────────────────────
   `opacity:.62` y no 1: es una pista, no un rótulo; compite con la portada y
   tiene que perder. El `drop-shadow` es el mismo halo que llevan las dos palabras
   grandes: el icono cae en el centro de la fotografía, donde la caída de luz de
   los cantos ya vale cero y puede haber pavimento claro debajo. */
.hero__baja{
  /* z-index 3, al ras de la portada: los dos son la capa de texto del hero. Ver
     la tabla de apilamiento sobre `.hero__laminas`. */
  position:absolute; z-index:3; pointer-events:none;
  left:50%; transform:translateX(-50%);
  bottom:calc(var(--portada-suelo) + var(--cuerpo-oficio) * .92 + .9rem);
  color:var(--tinta);
  opacity:.62;
  filter:drop-shadow(0 1px 10px rgba(0,0,0,.6));
  /* la retirada al primer scroll: la clase la pone `hero.js` y el nodo se va del
     árbol al acabar este fundido */
  transition:opacity 600ms linear;
}
.hero__baja.es-ido{ opacity:0; }
.hero__baja__icono{
  display:block;
  /* CHICO A PROPÓSITO, y el suelo importa tanto como el techo: en el iPhone
     apaisado la ventana mide 292 px de alto y un icono grande se comería la
     fotografía. 1.32rem de ancho son 21 px, o sea 39 px de alto con su
     proporción — menos de un séptimo de esa ventana. */
  width:clamp(1.15rem, 2.6svh, 1.6rem);
  height:auto;
}

/* LA ANIMACIÓN ES LA RUEDITA BAJANDO, Y NADA MÁS SE MUEVE. El marco del ratón
   está quieto: lo que se lee es el GESTO —el dedo empujando la rueda— y para eso
   basta con que se mueva la rueda. Un icono entero botando arriba y abajo es el
   adorno de cualquier plantilla y llama más atención que el <h1> que tiene al
   lado.

   2.8 s POR VUELTA, que es lento de verdad, y con la mitad del ciclo en reposo:
   el movimiento entra, cae 6 px desvaneciéndose y luego no pasa nada durante más
   de un segundo. Es un latido, no un bucle. */
@keyframes hero-rueda{
  0%             { transform:translateY(0);    opacity:1; }
  38%            { transform:translateY(6px);  opacity:0; }
  46%, 100%      { transform:translateY(0);    opacity:0; }
  /* el tramo 46→100 deja la rueda invisible y quieta: el descanso */
}
.hero__baja__rueda{
  animation:hero-rueda 2.8s cubic-bezier(.4, 0, .5, 1) infinite;
  transform-origin:50% 50%;
}
/* EL PICO DE ABAJO RESPIRA MEDIO SEGUNDO DETRÁS DE LA RUEDA y no a la vez: los
   dos a compás se leen como una sola forma parpadeando; en cascada se leen como
   un movimiento que va hacia abajo, que es la frase. */
.hero__baja__pico{
  animation:hero-pico 2.8s cubic-bezier(.4, 0, .5, 1) infinite;
}
@keyframes hero-pico{
  0%, 12%   { opacity:.25; }
  34%       { opacity:.9; }
  62%, 100% { opacity:.25; }
}

/* CON `prefers-reduced-motion` EL ICONO SE QUEDA QUIETO Y SIGUE AHÍ. No
   desaparece, y ésa es la distinción que suele fallarse: quien pide menos
   movimiento no está pidiendo menos información, y este icono es información —es
   la única pista de que debajo de la fotografía hay un sitio entero—. Se apaga
   la animación y se dejan las dos piezas en su valor de reposo: la rueda arriba y
   opaca, el pico en su gris. */
@media (prefers-reduced-motion: reduce){
  .hero__baja__rueda, .hero__baja__pico{ animation:none; }
  .hero__baja__rueda{ opacity:1; }
  .hero__baja__pico{ opacity:.55; }
}

/* Foco visible: el hero no tiene controles todavía, pero el sitio sí los tendrá
   y esto es el default del que van a heredar. */
:focus-visible{ outline:2px solid var(--brasa); outline-offset:3px; }

/* LO QUE EL HERO REDUCE, Y DÓNDE. Esta nota decía —y era verdad hasta el 16 de
   septiembre de 2026— que el hero no tenía nada que reducir, porque era una
   fotografía quieta. Ya no lo es: la portada rota entre láminas y abajo late un
   indicador de scroll. Las dos cosas obedecen `prefers-reduced-motion`, y no en
   el mismo sitio, que es lo que hay que saber para buscarlas:

     · LA ROTACIÓN la para `hero.js` en JavaScript, y no una regla de aquí. No es
       una elección de estilo: con la preferencia puesta las láminas que no se van
       a ver TAMPOCO SE BAJAN, y un `animation:none` no puede evitar una descarga.
       Se queda la primera, quieta y entera.
     · EL INDICADOR sí es CSS y está doscientas líneas arriba, con el icono: se
       le apaga la animación y se queda VISIBLE en su valor de reposo. */

/* ══ EL MENÚ DEL CLICK DERECHO SE FUE CON EL TRÍPTICO ═══════════════════════
   Aquí vivían el alto del riel por portada y un menú contextual de la casa con
   el que Victor cambiaba entre las DOS portadas —el tríptico y el bucle— delante
   de un cliente sin un solo botón en el diseño. Con una sola portada no hay nada
   que elegir: el menú, sus cuatro selectores y el `html.portada-bucle` del riel
   salen enteros. El alto del riel subió arriba, junto a `.hero`, que es donde le
   toca ahora que no depende de nadie. Todo está en git, en el commit anterior. */

/* ══ EL CONMUTADOR DE IDIOMA ══════════════════════════════════════════════════
   Arriba a la derecha y `fixed`, porque no hay un sitio del documento donde
   ponerlo que esté siempre a mano: el hero es `fixed`, los concursos son un riel
   de siete pantallas y el retrato mide dos.

   `--garalda` se declara aquí por lo mismo de siempre —el token vive en
   `.concursos` y fuera de ahí no resuelve—, y los selectores llevan `.cintillo`
   PEGADO por la lección del commit 29ffcd0: `concursos.css` se enlaza después de
   esta hoja, así que con una sola clase su `font-size`, su `letter-spacing` y su
   `color` ganarían por orden.

   VA EN `--tinta`, LA CREMA DE LA CASA, Y NO EN BLANCO. Victor lo vio «apagado»
   y tenía razón —estaba en `--tenue`—, pero el blanco puro no es la cura: el
   sitio entero es crema y un blanco sería el ÚNICO elemento blanco de la
   página, o sea todavía más pegado encima. Y no arregla lo que parece: sobre una
   zona clara de la fotografía del hero (~#b9a78d) el blanco mide 2.34:1, que
   sigue siendo ilegible. Ningún color plano resuelve un fondo que cambia siete
   veces; lo resuelve la caída de luz del canto de arriba (§ `.hero::after`),
   que es la misma que lee el membrete de la portada dos palmos a la izquierda.

   `mix-blend-mode:difference` NO se usa aquí a propósito, aunque el rótulo cruce
   fotografía y negro: en la primera pantalla el fondo es un canvas de WebGL y la
   mezcla obliga al compositor a leer de vuelta esa capa en cada cuadro. Se paga
   con una sombra de un píxel, que cuesta cero. */
.idioma{
  --garalda:"Cormorant Concursos", Garamond, "Hoefler Text", "Times New Roman", serif;
  position:fixed; top:1.15rem; right:1.25rem; z-index:40;
  display:flex; align-items:baseline; gap:.5em;
  text-shadow:0 1px 10px rgba(0,0,0,.6), 0 0 3px rgba(0,0,0,.55);
  /* ── SIN VELO, Y ESO NO DEJA ESTE WIDGET A LA INTEMPERIE ──────────────────
     TRES CHOQUES LLEVA ESTE RÓTULO Y LOS TRES SON EL MISMO PROBLEMA: es
     `position:fixed` arriba a la derecha, así que POR DEBAJO LE PASA EL DOCUMENTO
     ENTERO —el membrete de la portada, el título de concursos, su `border-top` de
     1 px— y apartarse de UN vecino no dice nada del siguiente, que todavía no
     existe cuando se escribe el arreglo. Los dos primeros se taparon moviendo la
     caja unos píxeles y por eso volvieron. El tercero enseñó que medir cajas de
     texto no basta: a 1280 lo que cruzaba «ESPAÑOL» era un filete de un píxel que
     va de x=51.2 a x=1228.8, y contra eso no hay hueco al que apartarse.

     LA CURA FUE OCULTAR, Y HOY LA OCULTACIÓN NO ES SUYA. El widget llegó a traer
     su propio negro —primero opaco, después una elipse—, y la elipse es la mancha
     que Victor mandó quitar (el detalle, justo debajo de esta regla). Lo que la
     sustituye no es un velo más discreto: es que el canto de arriba de la
     fotografía ya viene oscurecido de punta a punta por la portada. El rótulo se
     lee por contraste propio —crema de la casa y halo ancho, arriba— sobre un
     fondo que nunca es la fotografía cruda.

     Y LO QUE SE PIERDE, DICHO SIN ADORNO: con el negro opaco la respuesta a «¿es
     seguro para cualquier cosa que pase por debajo?» era «sí, por construcción».
     Hoy vuelve a ser «sí, medido», y la medida vale sólo mientras el conmutador
     caiga dentro de la caída de luz. Vive a 1.15rem del canto y la caída no
     empieza a apagarse hasta el 8 % del alto: en la ventana más baja del parque
     —un iPhone tumbado, 390 px— eso son 31 px, y el rótulo entero cabe dentro.
     Si alguien lo baja de ahí, esta cuenta es la que hay que rehacer. */
  padding:.42rem .62rem;
}
/* LA VIÑETA SE FUE, Y ESA ES LA MITAD DEL ENCARGO DE ESTA LANE.
   VICTOR, LITERAL: «te pedí que me quitaras lo horripilante que es la pinche
   mancha negra que está debajo del idioma, y lo que fuiste fue a ponerme otra
   mancha del lado izquierdo». Tenía razón en las dos. Aquí vivía una elipse negra
   —`.idioma::before`, `inset:-150% -80%`, núcleo al 52 %— dibujada sobre una caja
   mucho mayor que el rótulo para que ninguna letra se saliera del núcleo. Cumplía
   su medición: 14.7:1 en el núcleo y 7.5:1 sobre el píxel más claro del hero. Y
   se veía. Una elipse sobre una fotografía tiene forma, tiene centro y se lee
   como una mancha aunque el contraste sobre; el número no era el problema.

   LO QUE LA SUSTITUYE NO ES OTRO VELO: ES QUE YA NO HACE FALTA NINGUNO. El
   conmutador vive en el canto de ARRIBA, y desde que la portada es una portada el
   canto de arriba de la fotografía viene oscurecido de punta a punta por la caída
   de luz de `.hero::after` — que existe para el membrete y las dos palabras
   grandes y cubre esta esquina de paso, por geometría y no por casualidad. El
   mismo recurso, una sola vez, para las cuatro cosas que se leen sobre la
   fotografía. Las siete mediciones de esta esquina, en
   `Taller/Auditoria/Hero-Portada · Informe.md`.

   LO QUE SÍ SE QUEDA ES LA SOMBRA, Y SUBE UN PUNTO. Era `0 1px 3px rgba(0,0,0,.9)`
   —un asiento de un píxel pensado para vivir sobre un velo opaco— y ahora es el
   halo de la casa, el mismo de las dos palabras grandes: un desenfoque ancho y
   suave que separa la crema del grano sin dibujar un canto. Va en la regla de
   arriba, junto a la geometría.

   ── Y EL TERCER CHOQUE DE ESTE WIDGET SIGUE RESUELTO, POR OTRA PUERTA ──────
   La nota que este archivo llevaba aquí decía que el velo existía porque por
   debajo del conmutador pasa el documento ENTERO: el cintillo del hero, el título
   de concursos y su `border-top` de 1 px, que a 1280 cruzaba «ESPAÑOL» a 1.2 px
   del canto. Eso sigue siendo verdad y sigue sin poderse esquivar moviendo la
   caja. Lo que lo resuelve hoy es que el rótulo se lee por contraste propio sobre
   lo que haya: crema de la casa, halo ancho, y el canto de arriba oscurecido
   mientras se está sobre el hero. Un filete de 1 px cruzando una letra crema con
   halo no la borra — lo que la borraba era una fotografía clara detrás, y eso es
   lo que la caída de luz quita. */
.idioma__op.cintillo{
  background:none; border:0; padding:.2rem .1rem; cursor:pointer;
  font-size:.62rem; letter-spacing:.26em;
  /* ── EL REPOSO ES CREMA, Y ESO TIENE DOS FACTURAS DETRÁS ────────────────────
     `--filete` es el trazo de 1 px de la casa, no un color de TEXTO: 2.79:1
     sobre el negro con el cuerpo computado de 9.92 px, y la WCAG AA pide 4.5:1.
     `--tenue` lo subió a 5.11:1 y con eso cruzó el suelo… CONTRA EL NEGRO. Pero
     el conmutador no vive sobre negro: vive sobre la fotografía del hero, que
     desde `Hero-Siete` rota entre siete escenas con zonas claras. Sobre una de
     ellas `--tenue` mide 1.76:1. El umbral estaba bien calculado contra el fondo
     equivocado, y por eso Victor lo vio apagado antes que ninguna medición.
     `--tinta` es la crema de la marca —la misma de `.hero__marca`, que resuelve
     este problema exacto sobre la misma fotografía— y sobre la caída de luz del
     canto de arriba da 9.8:1 en la peor de las siete escenas.

     `--tenue` NO desaparece del sitio: sigue siendo el gris de texto sobre el
     negro de la página (§ `.cierre__puerta__txt`, que sí vive sobre negro). Lo
     que desaparece es usarlo encima de una fotografía. */
  color:var(--tinta);
  transition:color 180ms ease;
  /* sólo para colgar de aquí el campo de toque; no cambia el dibujo */
  position:relative;
}
/* ── EL CAMPO DE TOQUE, QUE NO ES LA LETRA ────────────────────────────────────
   «ESPAÑOL» a .62rem con .2rem de relleno es una caja de 54.7 × 16.3 px medida a
   390×844, y un pulgar necesita 44. Subir el relleno movería la caja del velo y
   volvería a apretar contra el cintillo de concursos, que es el choque que la
   sección de arriba acaba de resolver tres veces — así que el campo se agranda
   SIN TOCAR UN PÍXEL: una capa transparente centrada sobre el botón. No pinta,
   no ocupa flujo y no cambia dónde cae ninguna letra; lo único que cambia es
   dónde acierta el dedo. Los dos botones miden 54.7 de ancho y van separados por
   su `·`, así que ninguno de los dos campos pisa al otro.

   Y CRECE HACIA ABAJO, NO HACIA LOS DOS LADOS. Centrado sobre la letra, los 44
   px se salen por el canto de arriba de la pantalla —el conmutador vive a
   `.3rem` del borde— y quedan 41 px alcanzables: medido. Anclado al techo del
   botón, los 44 caen enteros dentro de la ventana, y lo que queda debajo es
   fotografía, que no recibe ni toque ni foco. */
.idioma__op.cintillo::after{
  content:"";
  position:absolute; left:50%; top:0;
  transform:translateX(-50%);
  width:100%; min-width:44px; height:44px;
}
/* El `aria-pressed` de abajo NO LO RECIBE NADIE HOY: el conmutador es de una sola
   opción —«English» en español y «Español» en inglés (index.html:92)—, así que
   esta regla es sólo el respaldo de un futuro conmutador de dos. La legibilidad
   del reposo NO cuelga de ella; la da `--tenue` de arriba. */
.idioma__op.cintillo[aria-pressed="true"]{ color:var(--tinta); }
/* ── LOS ESTADOS, AHORA QUE EL REPOSO YA ES CREMA ────────────────────────────
   Hasta hoy `:hover` y `:focus-visible` se distinguían subiendo el color de
   `--tenue` a `--tinta`. Con el reposo YA en `--tinta` esa diferencia es cero, y
   un estado que no se ve no existe: hay que devolverlo por otro sitio.

   EL HOVER SUBE A BLANCO, que es el único paso que queda por encima de la crema
   y el mismo recurso que usan las dos puertas del cierre (§ carrusel.css,
   `.cierre__puerta:hover`). No se subraya: a .26em de tracking un subrayado corre
   por debajo de las letras Y de sus huecos, y se lee como un filete.

   EL FOCO NO PUEDE COLGAR DEL COLOR y nunca debió: quien llega con el tabulador
   necesita ver DÓNDE está, no que algo cambió de tono. Un `outline` de brasa, el
   mismo de las puertas del cierre, y `outline-offset` para que no toque las
   letras. Así el foco se ve igual con el reposo que tenga el conmutador. */
.idioma__op.cintillo:hover{ color:#fff; }
.idioma__op.cintillo:focus-visible{
  color:#fff;
  outline:2px solid var(--brasa); outline-offset:3px;
}
.idioma__sep{ color:var(--filete); font-size:.62rem; line-height:1; }

/* En un teléfono se aparta del borde lo justo para no caer bajo el pulgar que
   sujeta el aparato, y crece hasta el objetivo táctil de 44 px que pide la WCAG
   — el mismo criterio que el menú del click derecho veinte líneas más arriba. */
/* EN TELÉFONO NO HAY ZONA LIBRE, Y ESO ES UN HECHO DE LA COMPOSICIÓN, no una
   pega que se pueda esquivar moviendo la caja. El cabezal del hero es un lockup
   a sangre: cintillo y palabra grande ARRIBA, palabra de la escena ABAJO, y el
   sujeto en medio. Se probaron las tres colocaciones y las tres chocan, medido:
   arriba a 11…47 se monta sobre el cintillo (empieza en ~30); a 70…106 sobre la
   T de GREAT; abajo a 792…828 sobre COMPANION, que es la más larga de las seis
   palabras y llega al 80 % del ancho; y en el medio del canto derecho cae sobre
   el vestido plateado de la escena 1 y desaparece por contraste.

   ASÍ QUE LO QUE CAMBIA NO ES EL SITIO SINO LA LEGIBILIDAD: un velo oscuro
   pequeño detrás, que es exactamente el recurso que esta hoja ya usa para el menú
   del click derecho —negro translúcido y un desenfoque de lo que hay detrás, sin
   borde, sin esquina redonda y sin sombra de sistema operativo—. No es cromo
   añadido: es el mismo idioma, y es lo único que hace que dos palabras de 11 px
   sobrevivan encima de una fotografía que cambia cada tres segundos.

   Se queda ARRIBA A LA DERECHA, que es donde se busca un conmutador de idioma, y
   con el velo ya no importa que el cintillo pase por debajo. */
@media (max-width:640px){
  .idioma{
    /* PEGADO AL CANTO Y LO MÁS PEQUEÑO QUE AGUANTA. La banda de arriba la pelean
       DOS cintillos —el del hero en la portada y el del título de concursos, que
       en español cae en dos renglones— y a 375 la caja del conmutador quedaba a
       UN píxel del segundo. Un píxel no es holgura: es que todavía no ha chocado.
       Con el velo detrás ya no tapa nada que no se lea, pero seguía apretando, así
       que se le recorta el relleno y se pega más a la esquina. */
    top:calc(.3rem + env(safe-area-inset-top, 0px)); bottom:auto;
    right:.4rem; transform:none;
    /* el velo ya lo trae la regla de arriba, y con más cuerpo: aquí sólo queda
       la GEOMETRÍA, que en un teléfono se aprieta contra la esquina */
    padding:.34rem .5rem;
  }
  /* el `color:var(--tinta)` que vivía aquí se fue a la regla de arriba: era la
     única parte del teléfono que ya estaba bien, y hoy es la regla del sitio.
     Aquí sólo queda la GEOMETRÍA. */
  .idioma__op.cintillo{ padding:0; font-size:.6rem; letter-spacing:.2em; }
}

/* ══ EL RETRATO DE ESCALA ══════════════════════════════════════════════════════
   El tamaño del perro no se cuenta con una cifra: se cuenta CON EL SCROLL. Se
   entra y sólo se le ve la cara, se baja, y al salir sólo se ve el cachorro entre
   sus patas. SIN UNA LÍNEA DE JAVASCRIPT — ni `scroll`, ni `sticky`, ni
   `IntersectionObserver`: es un cajón más alto que la ventana con una imagen más
   alta que la ventana dentro, y la página lo recorre sola.

   TODO CUELGA DEL ALTO DEL CAJÓN, y ese alto no lleva UNA sola cifra tecleada.
   Sale de seis variables: cuatro que MIDE `Scripts/retrato.py` sobre el PNG y
   reimprime cada vez que se corre, y dos que son decisiones.

     --aspecto    ancho ÷ alto del PNG. LA PROPORCIÓN DEL ARCHIVO SE ESCRIBE AQUÍ
                  Y EN NINGÚN OTRO SITIO: la guarda, el tope y la caja de la
                  lámina salen de ella con una división.
     --perro      cuánto del lienzo ocupa EL PERRO, de las orejas a las patas del
                  cachorro. Hace que «dos pantallas» sea dos pantallas DE PERRO y
                  no de archivo. Sin él la pieza se rompe en silencio el día que
                  el PNG traiga negro añadido: medido con un lienzo de prueba 9:39
                  (862×3735), «dos pantallas» dejaban al perro en 0.83 pantallas
                  —cabe entero de una vez, el scroll ya no lo recorre— y con
                  `--perro` los dos lienzos rinden IDÉNTICO: 695 px de ancho
                  dibujado y 1.48 pantallas de perro a 390×844 con los dos.
     --holgura    medio lienzo ÷ media banda del perro con su aire. Es COMPOSICIÓN,
                  no archivo: no cambia con la resolución ni con el relleno negro.
     --nativo     el ancho en píxeles del PNG. Sólo alimenta el tope de nitidez.

     --pantallas  CUÁNTO MIDE LA PIEZA, en pantallas de perro. Es la única perilla
                  que se va a querer mover: a 200vh el perro ocupa el 32 % del
                  ancho de un 1440. En TELÉFONO subirla no hace nada y es correcto
                  —ahí manda la guarda, que es un tope—: medido a 2, 3 y 4, la
                  sección mide 1471 px y la banda vista 189…673 en las tres.
     --invento    cuánto puede el navegador estirar la lámina, en múltiplos del
                  ancho nativo. HOY ESTA PERILLA MUERDE A LA OTRA: con 862 px topa
                  la sección en 1825, que a 1440×900 son justo 2 pantallas de
                  perro, así que subir `--pantallas` no mueve un píxel mientras
                  `--invento` sea 1. La receta de las dos está en el mensaje del
                  commit. No es pega de la regla, es el archivo: el sitio ya sirve
                  esta lámina con 2.42× de invención en un teléfono a dpr 3, y con
                  el retrato a 2400 px el tope se va a 5081 y la perilla del alto
                  queda libre hasta 4 pantallas sin pagar nada.

   LA FÓRMULA. La imagen va a `height:100%`, o sea `alto × aspecto` de ancho, y de
   ella se ven los `100vw` centrales. Que el perro entre entero pide

       100vw ÷ (alto × aspecto) × (lienzo÷2)  ≥  media banda + aire

   y despejando sale `100vw × holgura ÷ aspecto`: LA GUARDA DE LAS PATAS, la única
   razón por la que la pieza no mide siempre dos pantallas. Lo primero que se
   pierde por los lados son las patas delanteras, que son lo que enmarca al
   cachorro. Hoy da 377vw; a 420vw —el número con el que llegó el encargo— se ven
   los 50.4 % centrales y las zarpas se cortan 18 px por lado. Mirado en
   `Capturas/Escala/`, no razonado. Los 6 px de aire que lleva dentro la holgura
   son también lo que absorbe que `100vw` incluya la barra de scroll y el redondeo
   del navegador al escalar.

   Y LO QUE NINGÚN ARCHIVO ARREGLA: el recorte no lo decide el lienzo, lo decide
   EL PERRO. Mide 470×1825 px —3.88 veces más alto que ancho— contra 2.16 de una
   pantalla de 390×844. Dibujar N pantallas de perro pide N×844×0.2575 px de
   ancho: N=1.79 pide 389 y N=2 pide 435. DOS PANTALLAS DE PERRO SIN CORTAR NO
   EXISTEN en un teléfono de 390, con este lienzo ni con ninguno. La guarda
   entrega 1.74 pantallas de lienzo, el 97 % de ese techo geométrico.

   `vh` Y NO `svh`, al revés que el riel del hero: aquel necesita no pasarse de la
   ventana de ahora, y éste necesita NO MOVERSE. `svh` cambia cuando la barra del
   navegador se esconde, y eso reescribiría el alto del documento con el dedo
   dentro de la sección.

   `background` explícito: a 1440×900 la imagen se dibuja a 862 px centrados y a
   los lados hay negro de verdad, que tiene que ser el mismo de la fotografía.
   `z-index:1` como los concursos, o el hero `fixed` en z-index 0 la taparía. */
.escala{
  /* LAS CUATRO, MEDIDAS AHORA DE LOS 192 CUADROS DE `Assets/Video/escala-1440.mp4`.
     El video cambió de forma —era 1056×608 apaisado y ahora es 1440×2560 VERTICAL—
     y aun así estas cuatro casi no se mueven, que es la prueba de que llega la
     MISMA toma con más píxeles y no un encuadre nuevo: recortado al marco, el
     video viejo y el nuevo son la misma fotografía (`--perro` 0.8536 → 0.8527,
     una milésima). Lo que cambia de verdad es la RESOLUCIÓN, y eso vive en
     `--nativo` y en los dos encodes.

     `--aspecto` NO CAMBIA: es el aspecto del MARCO, no el del archivo. Lo que sí
     cambia es el ancho del fondo en marcos, y eso vive en `.escala__fondo`.

     `--perro` es la UNIÓN de los 192 cuadros y no la del último: de las orejas
     más altas que el adulto llega a levantar (y=108 del video, cuadros 179-192)
     a la LÍNEA DE CONTACTO con el suelo (y=2291). Las orejas se miden a
     luminancia > 20 dentro de la ventana del marco —están retroiluminadas—.
     LAS PATAS YA NO SE PUEDEN MEDIR CON EL UMBRAL 140 DEL VIDEO ANTERIOR, y esto
     es una trampa heredada que hay que dejar escrita: en aquel render el reflejo
     no pasaba de 121 y >140 separaba al perro de su espejo; en éste el piso
     refleja MUCHO más y >140 sigue dando positivo hasta y=2435, que son 144 px
     de REFLEJO contados como perro. La línea de contacto se saca por SIMETRÍA
     ESPECULAR —se correlaciona la banda de las patas por encima y por debajo de
     cada `y` candidata y se toma el máximo— y da 2291, confirmado por un segundo
     método independiente (fin de la primera racha brillante de cada columna,
     p90 = 2284, máx = 2289). En los 192 cuadros el contacto se mueve de 2293 a
     2290: TRES PÍXELES, y por eso el charco de aquí abajo puede ser fijo.

     `--holgura` sale de la banda de las patas EN REPOSO, igual que antes: medio
     marco ÷ (media banda + aire). La banda a la altura del contacto va de x=400
     a x=1050 del video, o sea 0.27293 marcos de semibanda contra los 0.28556 de
     la toma anterior —el perro nuevo pisa un pelo más estrecho—, más los mismos
     6 px sobre 862 de aire, EN RAZÓN y no en píxeles.
     LO QUE NO PROTEGE SIGUE SIENDO LA COLA: en los cuadros del meneo se abre
     hasta x=1439 —el canto del video, 0.5947 marcos de semiancho— y protegerla
     pediría --holgura 0.84, o sea dibujar la pieza MÁS GRANDE que la ventana.
     Se corta en teléfono y está dicho, igual que antes.

     `--nativo` VUELVE A QUERER DECIR CASI «no ampliar», y ése es el arreglo que
     Victor pidió. El marco mide 1210 px de ancho DENTRO del video (2560 ×
     --aspecto) donde antes medía 287, así que el mismo 862 px de tope pasa de
     ser un presupuesto de AMPLIACIÓN de 3.00× a uno de REDUCCIÓN de 0.71×
     (862 ÷ 1210). El valor no se toca —moverlo movería el aterrizaje, que es lo
     único que esta pieza no puede mover— pero su significado se dio la vuelta:
     en escritorio a dpr 1 el video se dibuja MÁS CHICO que su píxel nativo. */
  --aspecto:0.4723;      /* 862 ÷ 1825 — el MARCO, que no se mueve */
  --perro:0.8531;        /* orejas y=107 → contacto y=2291, unión de los 350 cuadros */
  --holgura:1.7863;      /* 0.5 ÷ (semibanda 0.27293 + aire 0.00696), en marcos */
  --nativo:862px;        /* presupuesto: 0.71× sobre los 1210 px nativos del marco */
  /* y las dos perillas de la decisión, una cifra cada una */
  --pantallas:2;
  --invento:1;

  position:relative; z-index:1;
  /* el alto va a una variable propia y no directo en `height` porque lo lee más
     de una regla, y repetir un `min()` de tres términos en dos sitios es
     exactamente como se separan. Lo leía el radio del halo, que ya no está; lo
     sigue leyendo quien tenga que escalar con la pieza y no con la ventana */
  --alto:min(calc(var(--pantallas) * 100vh / var(--perro)),
             calc(100vw * var(--holgura) / var(--aspecto)),
             calc(var(--nativo) * var(--invento) / var(--aspecto)));
  height:var(--alto);
  overflow:hidden;
  background:var(--negro);
}

/* AIRE DESPUÉS DE LA PIEZA, PARA PODER CENTRAR AL PERRO. Sin esto la sección es
   lo último del documento: al llegar al final del scroll el canto de abajo de la
   fotografía coincide con el canto de la ventana y el perro se queda anclado
   ABAJO, sin margen para subirlo. Con 12vh de aire el scroll llega un poco más
   lejos y la pieza sube: medido a 1440x900, el centro del cachorro pasa de y=497
   a y=389 en el último cuadro del recorrido, o sea de pegado al borde inferior a
   centrado alto. Sólo en escritorio: en un teléfono la pieza ya llena la ventana
   y el aire sólo añadiría negro que empujar. */
/* EL AIRE DE DESPUÉS lo da el bloque del rótulo, que vive fuera de la sección:
   ver `.escala__cta`. Su alto es lo único que decide DÓNDE queda el cachorro en
   el último cuadro, porque el scroll acaba en el canto de abajo del documento:
       y del cachorro = alto de ventana − alto del bloque − 403 px
   (los 403 son lo que el cachorro está por encima del canto de la fotografía).
   Con el bloque en ~180 px y una ventana de 900, el cachorro cae en y≈316: un
   pelo por encima del centro, que es exactamente lo pedido. */

/* EL ALTO DE ESCRITORIO, APARTE Y SIN DUPLICAR LA REGLA: aquí no se reescribe el
   `height`, sólo la variable de la que sale. 821 px es la MISMA frontera que ya
   usa el `sizes` de las láminas de concursos, así que no se inventa un punto de
   ruptura nuevo. Queda en 2 porque hoy subirlo no haría nada — ver `--invento`. */
@media (min-width:821px){
  .escala{ --pantallas:2; }
}

/* ── DOS CAPAS SOBRE UN SOLO MARCO, Y LAS DOS SON LA MISMA CAJA ───────────────
   Hasta hoy la fotografía llegaba en tres láminas con alfa —el estudio, el adulto
   y el cachorro— que se apilaban para poder tocar a cada uno por separado. Ya no:
   el video es UNA superficie y todo lo que hacía falta separar se murió con el
   recorte (el halo). Quedan dos capas y ocupan exactamente la misma caja: el
   `<img>` del último cuadro debajo y el `<video>` encima.

   EL MARCO NO SE MUEVE, y es lo que salva las medidas de las lanes anteriores: es
   el mismo lienzo 862×1825 de los sujetos, mismo alto, mismo `--aspecto`, mismo
   centro. Por eso la guarda de las patas, el aire de 6 px y las capturas siguen
   valiendo sin rehacerlas — lo que cambió es qué se dibuja dentro, no dónde.

   Y LA CAJA DEL FONDO ES LA QUE REGISTRA EL VIDEO CON EL MARCO: sale con `x`
   NEGATIVA y 3.68 marcos de ancho, así que el piso se derrama por los dos lados y
   en escritorio cubre de lado a lado. Como el video trae al perro centrado, esa
   caja es todo el encuadre que hace falta: no se reencuadra nada, se calibra.

   Sigue habiendo una tercera caja, `.escala__cachorro`, pero ya no lleva lámina:
   es la zona que se pica, medida del último cuadro. */
.escala__marco{
  position:absolute; top:0; left:50%; transform:translateX(-50%);
  height:100%; aspect-ratio:var(--aspecto);
  /* PROMOVIDO A SU PROPIA CAPA, Y EN ESTE ORDEN: primero se encogió el fondo (ver
     el bloque de abajo) y sólo DESPUÉS se promueve. Al revés habría sido peor —
     promover una capa de 2 614 px de ancho a dpr 3 es pedirle al compositor que
     sostenga 34 Mpx en memoria de textura—. Con el fondo ceñido al marco, la capa
     mide lo que la pieza y el scroll la TRASLADA en vez de re-rasterizar mosaicos
     según entran en la ventana, que es lo que se veía al bajar rápido.
     `translateZ(0)` y no sólo `will-change`: aquí ya hay un `translateX`, así que
     la promoción sale del mismo transform y no se paga dos veces. */
  transform:translateX(-50%) translateZ(0);
  will-change:transform;
}
.escala__capa{
  position:absolute;
  left:calc(var(--x) * 100%);  top:calc(var(--y) * 100%);
  width:calc(var(--w) * 100%); height:calc(var(--h) * 100%);
  max-width:none; display:block;
}
/* EL ANCHO DEL FONDO SALE DEL ARCHIVO, Y CON EL VIDEO VERTICAL SE DIO LA VUELTA:
   el video apaisado medía 1056×608 = 1.73684 y se derramaba 3.68 marcos a lo
   ancho; éste mide 1440×2560 = 0.5625 —9:16 clavado— y son 0.5625 ÷ 0.4723 =
   1.19098 marcos. La `x` es lo que hay que correrse a la izquierda para que el
   centro del video sea el del marco, y el píxel queda cuadrado.

   LO QUE SE PIERDE CON ESO VA DICHO SIN ADORNO: el piso YA NO LLEGA A LOS CANTOS
   DE LA VENTANA EN ESCRITORIO. A 1440×900 el fondo se dibuja a 1027 px CSS sobre
   una ventana de 1440 —antes eran 3243— así que sobran 207 px de negro de página
   por lado. No hay forma de arreglarlo con este archivo: el encuadre vertical no
   tiene más madera que enseñar, y estirarlo sería deformar al perro. Lo que sí
   hace falta es que el corte no se vea, y de eso se encarga el velo lateral de
   aquí abajo, que hasta hoy era una red que no se disparaba nunca y ahora
   trabaja de verdad. */
.escala__fondo   { --x:-0.09549; --y:0;       --w:1.19098; --h:1;       }

/* ── EL FONDO NO SE DERRAMA EN UN TELÉFONO, Y ESTO ES UN ARREGLO DE RASTER ────
   Victor: bajando rápido por el perro «se ven los bloques de la foto cargando,
   it makes it look cheap», y —lo que lo delata— PASA TAMBIÉN DESPUÉS DE CARGADA:
   subes, vuelves a bajar y los trozos se vuelven a pintar.

   LA CIFRA LO EXPLICA ENTERO. El derrame 16:9 hace que el fondo se dibuje a 3.76
   marcos de ancho. En un teléfono de 390 eso son 2 614 px CSS, y a dpr 3 la
   superficie que el navegador tiene que rasterizar y SOSTENER es de 34.6 Mpx
   (42.1 en un 430). No la sostiene: tira los mosaicos cuando sales y los vuelve a
   pintar cuando reapareces. Eso no es «cargando», es re-rasterizando — por eso
   pasa con la lámina ya descargada. En escritorio la misma regla son 5.9 Mpx y
   por eso ahí nunca se vio.

   Y LO QUE SE TIRA NO SE VE NUNCA: el derrame existe para que la madera llegue a
   los cantos en ESCRITORIO; en teléfono ya está medido que sobran de 1 069 a
   1 226 px por lado. Se está pagando raster por fotografía que cae fuera de la
   pantalla en todas las ventanas de teléfono.

   Debajo de 820 px el fondo se ciñe al marco y se recorta con `object-fit:cover`,
   que a este aspecto conserva EXACTAMENTE el encuadre vertical de siempre y
   recorta por los lados justo el ala que sobraba: la composición no se mueve un
   píxel y la superficie baja de 34.6 a 9.2 Mpx. El negro de los cantos, si
   sobrara, ya lo pone la sección — no hace falta una fotografía para pintarlo. */
/* CON VIDEO ESTO NO SE HEREDA, SE REHACE, y la cuenta que manda es otra: una
   lámina se rasteriza una vez y un video se decodifica 24 veces por segundo. Con
   el archivo VERTICAL el ala que sobra ya no son 2.68 marcos sino 0.19, así que
   el ahorro de ceñir el fondo cae de 25 Mpx de textura a casi nada — pero el
   recorte SIGUE VALIENDO LA PENA, y ahora por la razón contraria: no por lo que
   ahorra sino por lo que COMPRA. El archivo de teléfono viene recortado al marco
   de fábrica (1080×2284, § index.html), o sea que los 1080 px se gastan enteros
   dentro del marco en vez de repartirse en un 9:16 del que el marco sólo ve el
   84 %. Medido en la caja del cachorro a 390×844 dpr2 —energía de alta
   frecuencia, varianza del laplaciano normalizada por contraste—: el 9:16 sin
   recortar a 1080 da 0.0218 y el recorte a 1080 da 0.0249, con los MISMOS bytes.
   Y contra lo que había desplegado, 0.0011: veintidós veces menos.
   El `cover` se queda para los dos: el recorte mide 1080/2284 = 0.47285 contra el
   0.4723 del marco, y esos cinco diezmilésimos los absorbe él. */
@media (max-width:820px){
  .escala__fondo{
    --x:0; --w:1;
    object-fit:cover; object-position:50% 50%;
  }
  /* ── EL PERRO SE CORRE 20 px A LA DERECHA EN TELÉFONO ──────────────────────
     Victor, en el iPhone: «el perro como que se sale del display, la cara, cuando
     hace sus movimientos». Es cierto y sólo pasa en movimiento: a 430×932, hacia
     el segundo 4 de la intro, el danés gira la cabeza y el hocico, la lengua y la
     oreja izquierda quedan CORTADOS por el canto izquierdo. En el primer cuadro
     no se ve — por eso hay que mirarlo con el vídeo corriendo, no con una captura
     del principio.

     Y NO SE ARREGLA CON `object-position`, aunque sea lo primero que uno toca. El
     archivo de teléfono viene recortado al marco de fábrica (1080×2284) y el
     `cover` sobre esta caja deja 0.8 px de desbordamiento horizontal: medido. No
     hay nada que panear dentro del vídeo. Lo que SÍ recorta es el MARCO, que mide
     768.1 px en una ventana de 430 y va centrado, o sea 169 px fuera por cada
     lado. El encuadre real lo decide dónde se planta ese marco.

     20 px, y el número sale de mirar los dos cantos a lo largo de la intro: con
     el marco centrado la cara se sale por la izquierda; a +20 entra entera con
     aire y al canto derecho todavía le sobra; a +28 el aire de la derecha empieza
     a quedarse corto sin que la izquierda gane nada que se note. Es el mismo
     criterio que el eje x del hero: cuando no caben los dos lados, gana la
     CABEZA. */
  .escala__marco{ transform:translateX(calc(-50% + 20px)) translateZ(0); }
}
/* LA CAJA DEL CACHORRO, MEDIDA DEL VIDEO VERTICAL Y NO DEL APAISADO: x 545-862 e
   y 1801-2291 de los 1440×2560, pasados a marcos con la caja del fondo de aquí
   arriba (el marco ocupa x 115-1325 del video). El canto de abajo es la LÍNEA DE
   CONTACTO, que es la misma para el adulto y para el cachorro porque pisan el
   mismo suelo, y el de arriba son las orejas del cachorro sentado: por encima de
   y=1801 hay negro puro —medido, luminancia 0 en toda la banda 1760-1799—, así
   que el borde no es de gusto.
   SUS PATAS CAEN DONDE CAÍAN, que es lo único que el aterrizaje mira: 0.89492 del
   alto del marco contra 0.88158 de la toma anterior, trece milésimas — y eso son
   3.4 px en un teléfono y 3.7 en escritorio, dentro de los ±5 px que esta pieza
   se permite.
   EL CACHORRO NUEVO ES MÁS ALTO Y MENOS ANCHO EN EL MARCO —0.262 × 0.191 contra
   0.282 × 0.245— porque está sentado más erguido y más lejos del suelo. */
.escala__cachorro{ --x: 0.35537; --y:0.70313; --w:0.26198; --h:0.19180; }

/* EL VELO DE LOS CANTOS VUELVE A TRABAJAR, Y NO ES UNA REGLA NUEVA. Con el video
   apaisado el piso se dibujaba a 3243 px sobre una ventana de 1440 y el canto
   caía 900 px fuera de la pantalla: este velo era una red para una ventana
   absurdamente ancha y no se disparaba nunca. Con el archivo VERTICAL el fondo
   mide 1027 px CSS en esa misma ventana, o sea que sus dos cantos están DENTRO
   y son dos líneas verticales donde la madera corta contra el negro de página.
   El 6 % del ancho de la lámina son 62 px CSS de disolvencia a 1440×900, que es
   lo que convierte ese corte en un desvanecido. En teléfono el fondo va ceñido al
   marco (§ arriba) y el marco es más ancho que la ventana, así que el velo cae
   fuera de pantalla y no cuesta nada. */
.escala__fondo{
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 6%,
                                     #000 94%, transparent 100%);
          mask-image:linear-gradient(90deg, transparent 0, #000 6%,
                                     #000 94%, transparent 100%);
}

/* ── TRES CAPAS EN LA MISMA CAJA, Y CADA UNA SE DESCUBRE CUANDO YA PINTA ──────
   Las tres ocupan la MISMA caja (`.escala__fondo`): abajo el `<img>` con el
   PRIMER cuadro del bucle —que es el estado de reposo de la pieza—, encima la
   INTRO, y encima de ella el BUCLE.

   EL ORDEN NO ES DECORATIVO: cada capa tapa a la anterior, así que descubrir una
   nunca puede abrir un hueco. La intro NO SE APAGA cuando entra el bucle; se
   queda debajo, congelada en su último cuadro, que es la misma imagen con la que
   el bucle empieza. Si el bucle tarda, lo que se ve es esa imagen sostenida.

   POR QUÉ NO SE VEN DESDE QUE EXISTEN, QUE ES LO NATURAL: si la intro se viera
   desde que existe, lo primero que enseñaría es su cuadro 1 —el cachorro
   TUMBADO— justo después de que el visitante haya visto la lámina de reposo —el
   cachorro SENTADO—. Eso se lee como un rebobinado. Descubriéndola en `playing`,
   el salto ocurre con la reproducción ya en marcha y, con el disparo media
   pantalla antes de entrar (§ index.html), fuera de la ventana.

   Y ES TAMBIÉN EL RESPALDO, EN DOS ESCALONES Y SIN UNA REGLA DE MÁS: si no hay
   JavaScript, ni video, ni decodificación, o el navegador rechaza la
   reproducción automática, no se pone ninguna clase y la pieza se queda en la
   lámina; si llega la intro y no el bucle, se queda en el último cuadro de la
   intro, que es la misma imagen que la lámina. Entera en los dos casos, sin un
   hueco negro y sin nada que explicar.

   `object-fit:cover` EXPLÍCITO PORQUE UN <video> NO SE COMPORTA COMO UN <img>: el
   ajuste por defecto de un video es `contain` y el de una imagen es `fill`, así
   que un redondeo de un píxel entre la caja y el archivo deja dos franjas negras
   en vez de rellenar. Con `cover` la caja se llena siempre y las dos capas se
   encuadran igual. */
.escala__video{ opacity:0; object-fit:cover; }
.escala.es-vivo  .escala__intro{ opacity:1; }
.escala.es-bucle .escala__bucle{ opacity:1; }
/* Y LA INTRO SE APAGA EN CUANTO EL BUCLE HA PINTADO, QUE NO ES UN DETALLE DE
   LIMPIEZA SINO EL ARREGLO DE UNA REGRESIÓN MEDIDA. Dejarla debajo cuesta una
   capa de compositor de 1080×2284 (2 460×5 202 en un teléfono a dpr 2) que ya no
   enseña un solo píxel, y eso SE VE EN EL CUADRO: con las dos capas vivas, cuatro
   flicks táctiles con CPU ×4 dan 58.0 fps y seis cuadros de 33.4 ms; quitando la
   segunda capa, 60.3 fps y CERO cuadros largos, medido con los brazos
   intercalados y reproducido en cinco vueltas seguidas. No es decodificación —el
   brazo con los dos videos PAUSADOS da los mismos 58.0—: es tener dos superficies
   de ese tamaño en el árbol de capas.
   `visibility` y no `opacity:0`: una capa a opacidad 0 sigue siendo una capa que
   el compositor sostiene, que es justo lo que se está pagando. Y es seguro
   porque la clase que la enciende sólo la pone el primer cuadro PRESENTADO del
   bucle (§ index.html), no su `playing`: cuando la intro desaparece, encima ya
   hay un cuadro opaco pintado. */
.escala.es-bucle .escala__intro{ visibility:hidden; }

/* ── LA ZONA QUE SE PICA, QUE YA NO TIENE LÁMINA PROPIA ───────────────────────
   Era una capa con dos imágenes dentro —el halo y la nítida—, las dos recortadas
   del PNG del cachorro. Con el video no hay recorte que valga: la pieza es UNA
   sola superficie, así que esto vuelve a ser lo que por debajo siempre fue, una
   caja medida encima del cachorro que lleva el `<a>` de WhatsApp.

   SU CAJA ES LA UNIÓN DE LOS 350 CUADROS —los 192 de la intro y los 158 del
   bucle— y no la de un cuadro suelto. El techo lo pone el cachorro SENTADO, que
   es la pose del bucle y la del reposo; durante los 8 s de la intro sube desde
   tumbado, o sea SIEMPRE POR DEBAJO de ese techo. El canto de abajo es la línea
   de contacto con el suelo, que en los 350 cuadros se mueve entre y=2289 y
   y=2293: cuatro píxeles de video, uno de CSS.

   EL HALO SE FUE CON EL RECORTE Y LO QUE LO SUSTITUYE NO VA SOBRE EL CACHORRO
   SINO BAJO ÉL: el charco de luz de aquí abajo (§ `.escala__charco`). `--brillo`
   y `--realce` los sigue escribiendo el mismo script de proximidad sobre
   `.escala` y ahora SÍ los lee alguien — esta caja se quedó sin lámina, pero el
   gancho no se movió ni un carácter.

   EL ACUSE DEL PICADO YA NO CUELGA DE ESTA CAJA. El `scale(1.035)` de abajo se
   queda escrito y sigue sin enseñar un píxel —escalar una caja vacía no dibuja
   nada— pero ha dejado de ser el único acuse: quien acusa hoy es el charco, que
   fogonea (§ `.escala__charco`). La regla se conserva porque el día que esta caja
   vuelva a tener algo dentro vuelve sola, y porque el `transform-origin:50% 96%`
   es la medida de dónde pisa el cachorro y no quiero perderla.

   Y LA FLECHA SÍ RECOGE EL RELEVO, POR FIN. Las dos reglas que lo pedían
   —`.escala.es-picado .escala__cta__flecha`, aquí y en el bloque de la flecha—
   estaban MUERTAS y lo estaban ya en HEAD: piden que la flecha esté DENTRO de la
   sección, y el rótulo vive FUERA desde que se sacó del marco por el contexto de
   apilado. Medido en el navegador: `document.querySelectorAll('.escala.es-picado
   .escala__cta__flecha').length` da 0 aun poniendo la clase a mano. El rótulo es
   el HERMANO INMEDIATO de la sección, así que el combinador correcto es `+` y no
   el descendente; con `.escala.es-picado + .escala__cta ...` el mismo selector da
   1 y la flecha vuelve a saltar al picar al cachorro, que es lo que el archivo
   llevaba diciendo que hacía. Es una conducta que se VE y por eso va con su
   número: 0 → 1. Lo que SÍ seguía vivo del picado es lo que no se dibuja: la
   vibración y el toque sintetizado, y no se tocan. */
.escala__cachorro{
  cursor:pointer;
  /* crece desde SUS PATAS: está sentado en el piso y escalar desde el centro lo
     despegaría del suelo */
  transition:transform 160ms cubic-bezier(.2,.9,.3,1.35);
  transform-origin:50% 96%;
}
.escala.es-picado .escala__cachorro{ transform:scale(1.035); }
.escala.es-picado + .escala__cta .escala__cta__flecha{ transform:translateY(-.7em); }
@media (prefers-reduced-motion: reduce){
  .escala__cachorro{ transition:none; }
  .escala.es-picado .escala__cachorro{ transform:none; }
}

/* ── EL CHARCO DE LUZ, QUE ES LO QUE DICE QUE EL CACHORRO SE PUEDE TOCAR ──────
   El halo dibujaba el contorno del cachorro, y para eso hacía falta un alfa que
   se murió con el recorte. Esto no: lo pinta la PÁGINA, no la fotografía. Tres
   cosas lo hacen la respuesta correcta y ninguna es de gusto —no necesita alfa,
   no se despega cuando el cachorro se mueve porque su contacto con el suelo no
   cambia, y es del idioma de la casa: el CSS del halo ya decía que un brillo
   quieto «de hecho ES una luz de estudio plausible», y un charco sobre un piso
   reflectante lo es todavía más—. Por eso, a diferencia del halo, ESTE SE VE EN
   REPOSO (`--reposo`): un pozo de luz encendido es fotografía, no interfaz.

   VA ENCIMA DEL VIDEO Y NO DEBAJO, porque el video es OPACO — no hay «debajo».
   De ahí sale `mix-blend-mode:screen`, que no es un adorno sino la única mezcla
   que cumple la premisa de la sección: `screen` NUNCA OSCURECE, así que sobre el
   negro de la página el resultado es exactamente el color del degradado y donde
   el degradado llega a alfa 0 el fondo se queda BIT A BIT como estaba. Un velo
   normal con el mismo dibujo ensuciaría el negro que la pieza entera se esfuerza
   en que valga `var(--negro)` — y además apagaría al cachorro, que es blanco:
   `normal` interpola HACIA el color del velo y sobre 255 eso resta.

   ES UNA ELIPSE Y NO UN CÍRCULO, Y EL ACHATAMIENTO ESTÁ MEDIDO. Un círculo sobre
   un suelo en perspectiva se lee como calcomanía. Los tres pasos de abajo se
   hicieron sobre la TOMA ANTERIOR (1056×608) y sus píxeles son de aquel archivo;
   valen para éste porque el marco enseña la misma vista, y el transporte está
   hecho y con su número más abajo. Quedan escritos con sus cifras originales
   porque son el MÉTODO, y el día que llegue una toma de verdad distinta hay que
   repetirlos y no reescalarlos:

     ① EL HORIZONTE, de la veta del piso. Las bandas horizontales de la madera son
       líneas de profundidad constante, así que su separación en `y` obedece
       u_k = K/(k+c) con u = y − y_horizonte. Ajustando las seis bandas limpias de
       los cuadros (y = 540, 547, 555, 563, 573, 582, en columnas sin reflejo)
       sale y_horizonte = 344.25 px con R² = 0.99963. El horizonte cae DENTRO del
       encuadre, 40 px por debajo del centro: la cámara mira un pelo hacia abajo.
     ② LA ESCALA HORIZONTAL, del adulto. Su cruz mide 435 px del piso al cráneo y
       un gran danés adulto mide ahí ~110 cm, o sea 3.95 px/cm en el plano de las
       patas. Con eso la ALTURA DE LA CÁMARA sale sola y sin más supuestos:
       H = u_contacto / escala = 191.75 / 3.95 = 48.5 cm. Cuarenta y ocho
       centímetros: la cámara está casi a ras del piso, y eso se ve sin medir
       nada en las patas del adulto —se les ve el frente de los dedos y no el
       lomo de la pata—.
     ③ EL ACHATAMIENTO de un círculo pequeño en el piso es b/a = u/f, con
       u = 191.75 px. La distancia focal es lo único que no se puede medir aquí
       —esto es un render y su madera es VETA, no duelas con juntas, así que no
       hay regla en el suelo; queda dicho para que nadie cite una duela que no
       existe—: para un encuadre de retrato de 35° a 50° horizontales sobre 1056
       px, f va de 1130 a 1670 px y b/a de 0.170 a 0.115. Se toma el centro,
       b/a = 0.14, o sea UNA ELIPSE DE 1 : 7.

   PERO LA ELIPSE MEDIDA ES LA DEL CHARCO EN EL PISO Y NO LA DE TODA LA LUZ, y
   ésa es la corrección de la segunda vuelta. Victor lo vio desplegado: «el charco
   de luz apenas si se nota y no le enseña a la persona que es un botón». Tenía
   razón, y el fallo no fue de ejecución sino de OBJETIVO: la primera versión
   optimizó la VEROSIMILITUD —367 : 1 entre lo que sube el piso y lo que sube el
   cachorro, o sea la luz cae en el suelo y no mancha al perro— cuando lo que
   estaba fallando era la LEGIBILIDAD. Un desconocido en un teléfono tiene que
   entender que ese cachorro se toca, y 0.088 de 255 sobre el cachorro no se lo
   dice nadie.

   Y EL ARREGLO NO ES SUBIR EL BRILLO, ES QUE HAYA DOS LUCES, porque en el mundo
   también las hay: un pozo de luz sobre un piso reflectante no se queda en el
   piso — REBOTA. Si el suelo brilla y el perro que está DENTRO no, el ojo lee
   «hay una mancha en el suelo» en vez de «este perrito está iluminado», y eso es
   exactamente lo que Victor vio. Así que el elemento pinta DOS degradados:

     ① EL CHARCO, en el piso, con la elipse de 1 : 7 medida arriba. Es la que
       tiene que ser plana; si ésta fuera redonda, calcomanía.
     ② EL REBOTE, mucho más alto que ancho, centrado en el MISMO contacto. Es la
       luz que sube del suelo y baña al cachorro desde abajo: fuerte en sus patas,
       menos en el pecho, nada en la cabeza. No es una licencia — es la única
       forma de que la luz alcance al sujeto sin dibujarle un contorno, que es lo
       que hacía el halo y que ya no se puede hacer sin recorte.

   EL CENTRO SE PONE EN EL CUADRO 539 DEL VIDEO, cuatro píxeles POR DELANTE del
   contacto (535), y esos cuatro no son gusto: la perspectiva ensancha el lado
   cercano, así que un charco real es asimétrico hacia el espectador.

   EL NÚCLEO SIGUE TALLADO AL CACHORRO AUNQUE EL CHARCO SEA MUCHO MÁS GRANDE, y
   ésa es la diferencia entre crecer y desparramarse. Su huella en el piso, medida
   en LOS 350 CUADROS, va de x 547 a 767 del video; las patas del adulto acaban en
   443 y vuelven a empezar en 876. HAY HUECO A LOS LADOS PERO NO SIRVE DE NADA: un
   charco que muriera dentro de ese hueco tendría 0.27 marcos de ancho y sería más
   estrecho que el propio cachorro, o sea una mancha bajo él en vez de una luz.
   No existe ningún charco que alumbre al cachorro Y llegue a leerse en un
   teléfono dejando al adulto a oscuras; quien pida eso está pidiendo un imposible
   de escala, no de geometría. Lo que se hace es poner la MESETA
   del degradado —el tramo que va casi a alfa 1— en el 45 % del radio, que son los
   ±45 px de la huella, y dejar que la caída se derrame hasta ±100. El adulto
   recibe COLA y el cachorro recibe núcleo, que es exactamente lo que hace una luz
   de verdad. Los tramos se abrieron MIRANDO EL PÍXEL y no calculándolos: en la
   primera versión el charco se leía más estrecho que la huella que señalaba.

   Y NO ES UN ANILLO NI UN PULSO TIPO RADAR. Se descarta a propósito y queda
   escrito para que nadie lo reproponga: eso es interfaz pegada encima, y esta
   casa habla el idioma de la luz fotográfica.

   LA CAJA VA EN EL MISMO SISTEMA QUE LAS DEMÁS CAPAS (`--x --y --w --h` en
   marcos) Y ESO NO ES PEREZA: es lo que hace que el charco caiga en el mismo
   sitio en el archivo de escritorio (1440×2560, con el fondo a 1.19 marcos) y en
   el de teléfono (1080×2284, ceñido al marco con `cover`), sin una sola media
   query. Y ES TAMBIÉN LO QUE SALVÓ ESTA CALIBRACIÓN AL CAMBIAR DE VIDEO: los
   cuatro números de abajo son los de la segunda vuelta con Victor, transportados
   TAL CUAL en marcos, porque el marco enseña la misma fotografía en las dos
   tomas (§ el bloque de `.escala`, `--perro` 0.8536 → 0.8527). Sólo se remidió
   el CENTRO, que es lo único que depende de dónde pisa este cachorro.

   EN PÍXELES DEL VIDEO NUEVO la caja mide 885 × 1221 y va centrada en (672,
   2308): el marco mide 1210 px de ancho y 2560 de alto, así que
              ancho  885 ÷ 1210 = 0.73128 marcos   (lo mismo que antes)
              alto  1221 ÷ 2560 = 0.47697 del alto (lo mismo que antes)
   El centro en x es la HUELLA DEL CACHORRO EN REPOSO —sus dos patas delanteras
   van de x=587 a x=758, punto medio 672— y no el centro de su caja, que cae 31 px
   a la derecha (703) porque sentado se recuesta hacia ese lado. Medida sobre los
   192 cuadros la huella se abre a 547-767 mientras está tumbado, o sea que el
   centro de la unión sería 657: se toma el de REPOSO porque el charco es fijo y
   el reposo es el estado en el que la pieza pasa el 99 % del tiempo, que es
   cuando la afordancia tiene que leerse. Los 15 px de diferencia son 5 px CSS en
   escritorio.
   EN `y` VA 17 PX POR DELANTE DEL CONTACTO (2291 → 2308), que es el mismo cuarto
   de por ciento del alto que llevaba la versión anterior: la perspectiva ensancha
   el lado cercano, así que un charco real es asimétrico hacia el espectador.

   LO ÚNICO QUE SE MOVIÓ EN LA RELACIÓN LUZ/HUELLA, Y VA DICHO PORQUE ES UNA
   CONCESIÓN: la huella de este cachorro es más estrecha DENTRO DEL MARCO que la
   del anterior —0.184 marcos contra 0.310— así que la meseta del degradado, que
   allí coincidía con la huella (45 % del radio), aquí la desborda: el tramo casi
   opaco llega al 26 % del radio, que son 109 px de video contra los 111 de
   semihuella. Coincide, pero por el tramo de la MESETA y no por el del 45 %. El
   radio no se baja para volver a cuadrar los porcentajes porque el que mandaba
   nunca fue la huella sino el TECHO DE TELÉFONO: a 390×844 el marco se dibuja a
   697 px CSS sobre una ventana de 390, o sea que sólo se ve el 56 % de él, y un
   charco más ancho deja de señalar para volverse un lavado de pared a pared.
   Ésa es la misma frontera que fijó los ±100 px de la vuelta anterior.

   Y ASÍ SALE EL REPARTO, MEDIDO CON EL CONTROL BUENO (el charco a `opacity:0` y
   no a `display:none`, para que el grupo de mezcla exista en los dos brazos): en
   reposo el piso bajo el cachorro sube +93.6 de 255 en escritorio (×2.49) y +95.6
   en teléfono (×2.41) — clavado en los +95.0 y +87.0 de la vuelta anterior— y
   dentro del cachorro la luz CAE de abajo arriba, que es la firma del rebote:
   patas +40.3, pecho +21.0, cabeza +7.2. Un foco cenital daría lo contrario.
   LO QUE SÍ CAMBIÓ ES CUÁNTO LE TOCA AL CACHORRO EN TOTAL, y no por una decisión
   sino por su tamaño: +21.3 contra los +7.7 de la vuelta anterior, o sea que la
   razón piso : cachorro pasa de 12.3 : 1 a 4.4 : 1. La luz es LA MISMA —los ocho
   números del degradado no se tocaron— pero este cachorro ocupa 0.192 del alto
   del marco donde el anterior ocupaba 0.245: es un 22 % más bajo y por eso cabe
   más adentro del pozo de luz. Queda dicho con su número por si alguien decide
   que es demasiado; bajarlo es bajar el radio vertical del rebote y nada más.

   LA CAJA LA MANDA EL REBOTE Y NO EL CHARCO —es lo alto—, así que los dos
   degradados van con RADIOS EXPLÍCITOS en porcentaje de ella y no con
   `closest-side`: el charco 47.6 % × 4.83 % y el rebote 29.5 % × 50 %. Escrito con
   `closest-side`, los dos habrían heredado la misma elipse y el charco se habría
   vuelto redondo — que es justamente la calcomanía que este bloque lleva veinte
   líneas evitando. Y LA ELIPSE SIGUE SIENDO 1 : 7 SIN VOLVER A DERIVARLA, porque
   b/a = u/f es una propiedad de la VISTA y el marco enseña la misma: transportada
   al video nuevo, la línea del horizonte cae en y≈1488 y u = 803 px, con f entre
   4763 y 7038 px para el mismo abanico de 35° a 50°, o sea b/a entre 0.114 y
   0.169 — el mismo centro, 0.14. NO PUDE REHACER EL AJUSTE DE LA VETA en este
   render y lo digo en vez de callarlo: por debajo del contacto sólo hay tres
   bandas limpias y su solución armónica pone el horizonte 35 px POR ENCIMA del
   contacto, que es geométricamente imposible. El número viejo se sostiene por el
   argumento de la vista, no por una segunda medición del piso.
   Y LA CAJA SE SALE DEL MARCO POR ABAJO A PROPÓSITO (0.663 + 0.477 = 1.140): la
   recorta el `overflow:hidden` de la sección y encima le pasa el velo del canto,
   así que la mitad de abajo del rebote muere donde tiene que morir. */
.escala__charco{
  /* centrada en la HUELLA del cachorro en reposo, x=676 del video, y=2308 */
  --x:0.09797; --y:0.66309; --w:0.73128; --h:0.47697;
  /* EN REPOSO SE VE, Y ES LO QUE HACE QUE LA AFORDANCIA NO DEPENDA DE UNA LÍNEA
     DE JAVASCRIPT: sin script, sin `--brillo` y con movimiento reducido, el
     charco sigue encendido en este valor. El halo no podía permitírselo porque un
     contorno encendido en reposo es un error de composición; una luz en el piso
     en reposo es la fotografía.
     SUBE DE .34 A .62 EN LA SEGUNDA VUELTA, y el .34 no era tímido por descuido:
     era el valor del halo, que estaba pegado a la silueta y por eso se veía con
     poco. Un charco vive en el suelo, lejos del ojo y sobre madera oscura, y a
     .34 se lo comía la fotografía. */
  --reposo:.70;
  /* `--brillo` lo escribe el puntero por proximidad y se topa en .78; `--realce`
     es del hover y es lo que separa «cerca» de «encima». El reposo se queda como
     SUELO y la proximidad reparte lo que falta hasta 1, así que ninguno de los
     dos pisa al otro y el charco nunca puede apagarse por debajo del reposo. */
  opacity:calc((var(--reposo) + (1 - var(--reposo)) * var(--brillo, 0))
               * var(--realce, 1));
  /* LOS DOS DEGRADADOS, Y EL ORDEN IMPORTA: el charco va PRIMERO, o sea encima,
     porque es el que manda donde los dos se pisan. Los alfas son el perfil de la
     luz y el color se cierra hacia el ámbar conforme cae — una luz cálida se lee
     como LUZ y una blanca como un defecto de pantalla, que es por lo que el halo
     viejo también era ámbar. La segunda vuelta calienta el núcleo entero: el
     (255,238,209) de antes era casi papel. Los tramos finales repiten el MISMO
     rgb con alfa 0 y no `transparent`: `transparent` es rgba(0,0,0,0) y al
     interpolar hacia él el degradado pasa por un gris sucio. */
  background:
    /* ① EL CHARCO EN EL PISO · 100 × 14 px de video, la elipse de 1 : 7 */
    radial-gradient(ellipse 47.6% 4.83% at 50% 50%,
      rgba(255,236,198,1)   0%,
      rgba(255,222,164,.94) 26%,
      rgba(255,206,134,.66) 44%,
      rgba(255,188,100,.34) 62%,
      rgba(255,172, 76,.12) 80%,
      rgba(255,164, 66,.03) 92%,
      rgba(255,164, 66,  0) 100%),
    /* ② EL REBOTE · 62 × 145 px, la luz que sube del suelo y baña al cachorro */
    radial-gradient(ellipse 29.5% 50% at 50% 50%,
      rgba(255,226,176,.68) 0%,
      rgba(255,210,142,.46) 28%,
      rgba(255,192,108,.24) 52%,
      rgba(255,176, 82,.09) 76%,
      rgba(255,164, 66,  0) 100%);
  mix-blend-mode:screen;
  pointer-events:none;
  /* el brillo lo escribe el puntero cuadro a cuadro, así que la opacidad NO lleva
     transición: la perseguiría con retraso. La única transición es la del gesto,
     que sí es un evento y no un seguimiento. */
  transition:transform 180ms cubic-bezier(.2,.9,.3,1.35);
  transform-origin:50% 50%;
  will-change:opacity, transform;
}

/* ENCIMA LA LUZ SE CIÑE. Es la traducción honesta de lo que hacía el halo en este
   estado —«pasa de brillar a estar RECORTADO»—: una luz que se cierra un punto se
   lee como un foco que enfoca, y el `--realce` la sube a la vez. Cerca se entera,
   encima se ofrece, picado acusa; y siguen siendo tres cosas distintas y no una
   con tres intensidades. El charco es hermano POSTERIOR del `<a>` para que este
   `~` exista: un hermano anterior no se puede alcanzar desde CSS.

   Y VA DENTRO DE LA MISMA GUARDA QUE USA EL SCRIPT, que no es simetría sino un
   bug cazado midiendo: en un teléfono `:hover` SE QUEDA PEGADO al último elemento
   tocado —comprobado con toque emulado de verdad, `--realce` seguía en 1.35 tras
   soltar—, así que sin la guarda un solo toque dejaba el charco ceñido al 94 %
   para siempre. «Encima» no existe donde no hay puntero que se pose, y ésta es la
   única frontera que lo dice. */
@media (hover:hover) and (pointer:fine){
  .escala__cachorro:hover ~ .escala__charco{
    --realce:1.35;
    transform:scale(.94, .90);
  }
}

/* Y AL PICAR, FOGONEA. El acuse se quedó sin lámina que escalar cuando se fue el
   recorte, así que sale de la misma pieza que ya está pintada y no pide un
   elemento nuevo: sube a tope, se ensancha un pelo y vuelve. `animation:none`
   porque en táctil la opacidad la lleva el latido y una regla de la hoja no le
   gana a un keyframe; a tope se escribe aquí y no inline como el `--brillo`,
   porque aquí sí hay clase que lo sostenga. */
.escala.es-picado .escala__charco{
  animation:none;
  opacity:1;
  transform:scale(1.14, 1.16);
}

/* SIN PUNTERO FINO NO HAY «ACERCARSE», ASÍ QUE EN UN TELÉFONO EL CHARCO RESPIRA.
   Es la misma decisión que llevaba el halo y con el mismo número, que no es
   arbitrario: 1.3 s es LA MITAD EXACTA de los 2.6 s del vaivén de la flecha, así
   que el charco late DOS veces por cada movimiento de ella y los dos coinciden en
   cada ciclo — se lee como un pulso y su eco, no como dos adornos que baten entre
   sí. Cualquier valor cercano pero no múltiplo (2.0, 2.2) los cruza y los separa
   sin repetir nunca, y una pieza con dos ritmos así se siente nerviosa.
   `ease-in-out` y no lineal: un latido lineal es un parpadeo de aviso, y esto no
   es una alarma. Y NUNCA LLEGA A APAGARSE DEL TODO — un charco que se apaga deja
   ver el corte del degradado contra el negro y salta a la vista como un fallo.
   Cuesta cero en el hilo principal: es OPACIDAD sobre una capa promovida, así que
   la resuelve el compositor sin tocar disposición ni pintura.

   EL COMPÁS NO SE TOCA Y EL RECORRIDO SÍ, Y ESA ES LA SEGUNDA VUELTA. Los 1.3 s
   se quedan clavados porque son la mitad de los 2.6 s de la flecha y ahí vive el
   pulso-y-eco; lo que estaba mal calibrado era el RANGO. El .18–.86 se midió para
   un halo pegado a una silueta, donde una diferencia pequeña se ve porque está
   junto al contorno. Un charco vive en el suelo, lejos, sobre madera: con ese
   recorrido se leía como una mancha quieta del piso y no como algo VIVO. Pasa a
   .26–1.00, o sea de 0.68 de recorrido a 0.74 pero sobre un charco que además
   parte de mucho más arriba — en píxeles el suelo bajo el cachorro respira ahora
   entre dos valores que se ven, que es lo único que el ojo juzga. */
@media (hover:none), (pointer:coarse){
  .escala__charco{ animation:escala-late 1.3s ease-in-out infinite; }
}
@keyframes escala-late{
  0%, 100% { opacity:.26; }
  50%      { opacity:1; }
}

/* CON MOVIMIENTO REDUCIDO EL CHARCO SE QUEDA, QUIETO. Apagarlo sería quitarle al
   visitante la única cosa que dice que el cachorro se puede tocar, y un brillo
   fijo no es movimiento: se queda en su valor de reposo, que es justo el que ya
   tiene sin JavaScript. */
@media (prefers-reduced-motion: reduce){
  .escala__charco{ animation:none; transition:none; }
  .escala.es-picado .escala__charco,
  .escala__cachorro:hover ~ .escala__charco{ transform:none; }
}

/* EL CANTO DE ABAJO SE DISUELVE, Y EL VIDEO PIDE MUCHO MENOS VELO QUE EL PNG.
   La sección era lo último del documento y el corte de la fotografía coincidía
   con el fin de la página; con la línea de disponibilidad debajo hay negro
   después, y entonces el piso acabaría en una raya horizontal dura — la misma
   fotografía pegada sobre la página que esta casa lleva tres secciones evitando,
   sólo que por el otro canto.

   LA MEDIDA SE REHÍZO OTRA VEZ PORQUE EL PISO VOLVIÓ A CAMBIAR, Y ESTA VEZ HACIA
   ARRIBA. La última fila del PNG viejo daba luminancia media 12 y máxima 133; la
   del video apaisado, 4.6 y 34 —ese piso se moría solo y por eso el velo bajó de
   26 % a 14 %—; la del video VERTICAL da 26.3 de media y 99 de máxima. El reflejo
   vuelve a llegar VIVO al canto, cinco veces y media más que en la toma anterior,
   así que el velo tiene que volver a trabajar: si se dejara en 14 % con las
   paradas de entonces, la fotografía cortaría contra el negro de la página con
   madera todavía encendida.
   PASA A 16 % Y LAS PARADAS SE CORREN, y el número que decide dónde empieza no es
   el piso sino EL CACHORRO: sus patas acaban en el 89.49 % del alto del marco, y
   el velo tiene que llegar ahí con el 11 % de arriba de la curva y no más — que
   es exactamente lo que le costaba el velo anterior (0.112 contra 0.114 de alfa,
   dos milésimas). O sea: dos puntos más de velo para un piso cinco veces más
   brillante, y al cachorro NO se le cobra ni un punto de más. */
.escala::after{
  content:""; position:absolute; left:0; right:0; bottom:0;
  /* Z-INDEX EXPLÍCITO, Y COSTÓ ENCONTRARLO: el rótulo se declaraba blanco puro
     —el computado decía rgb(255,255,255)— y en la captura su píxel más claro era
     191. No era la tipografía ni la sombra: era ESTE velo pintándose encima. Un
     pseudo-elemento posicionado sin `z-index` no está por debajo de un hermano
     con `z-index:2` por arte de magia, y aquí el orden acababa al revés. Con el
     velo en 1 y el rótulo en 2 el orden queda dicho y no supuesto: medido otra
     vez, el blanco vuelve a 255. */
  z-index:1;
  /* 16 % Y TRES PARADAS: empieza en el 84 % del alto —por debajo de las patas del
     cachorro, que acaban en el 89.49 %, con sólo el 11 % de arriba de la curva—, y
     de ahí al canto lleva el último 10 % del marco, que es reflejo del piso y
     nada más, hasta el negro de la página. */
  height:16%; pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(0,0,0,0) 0%, rgba(0,0,0,.16) 48%, rgba(0,0,0,.70) 80%, var(--negro) 100%);
}

/* ── LA LÍNEA DE DISPONIBILIDAD ───────────────────────────────────────────────
   El cierre del sitio y lo único que esta casa le pide al visitante. Va DEBAJO de
   la fotografía, sobre el negro de la página, y sube una flecha desde ella hasta
   el cachorro: la flecha dice CUÁL y el rótulo dice para qué. Eran tres —el halo
   decía además que algo estaba vivo— y desde que la pieza es un video son dos,
   así que la flecha carga sola con señalar: es lo ÚNICO que dice qué hay que
   picar, y por eso no se toca.

   EL AIRE ES EL DISEÑO. Apretado contra la foto se leía como un pie de imagen —y
   así se veía en la captura de Victor, todo junto—. Con 14vh por arriba y 20vh
   por abajo el bloque mide un tercio de pantalla en escritorio, y ese tercio es
   NEGRO: es también lo que le da a la fotografía sitio donde morir.

   `--garalda` se declara aquí porque el token vive en `.concursos`, no en `:root`.
   El cuerpo es el de la PÁGINA y no el de la fotografía —la pieza se dibuja a 694
   px de ancho en un teléfono y a 862 en un monitor—, así que un rótulo que
   escalara con ella saldría diminuto donde más se necesita. */
.escala__cta{
  --garalda:"Cormorant Concursos", Garamond, "Hoefler Text", "Times New Roman", serif;
  position:relative; z-index:1;
  display:flex; flex-direction:column; align-items:center;
  /* EL ÚLTIMO CUADRO ES UNA COMPOSICIÓN, NO UNA COLA. Victor lo pidió como el
     logo de Apple al encender un teléfono: el perro centrado o un pelo por
     encima, y la palabra justo debajo — LOS DOS EN LA MISMA PANTALLA. Con
     relleno normal el bloque medía 477 px y empujaba al cachorro hasta el borde
     de arriba; el cachorro vive 403 px por encima del canto de la fotografía, o
     sea que cada píxel de este bloque se lo come.

     Por eso el relleno de arriba es CERO y la flecha sube con un margen negativo
     hasta solaparse con el piso: así el bloque sólo aporta la palabra y su aire,
     la flecha se dibuja SOBRE la fotografía apuntando al cachorro, y el conjunto
     cabe. Los números salen de la medida, no del gusto: ver el aire de después,
     que es el otro término de la misma ecuación. */
  /* LAS MISMAS CUATRO VARIABLES DE LA SECCIÓN, porque este bloque tiene que
     resolver la MISMA ecuación desde fuera: `--alto` se declara en `.escala` y
     aquí no se hereda. Repetirlas es feo; adivinar el alto de la fotografía lo
     sería más. */
  --aspecto:0.4723; --perro:0.850; --holgura:1.781; --nativo:862px;
  --pantallas:2; --invento:1;
  --alto:min(calc(var(--pantallas) * 100vh / var(--perro)),
             calc(100vw * var(--holgura) / var(--aspecto)),
             calc(var(--nativo) * var(--invento) / var(--aspecto)));
  /* EL CACHORRO VIVE 0.2211 DEL ALTO DE LA FOTOGRAFÍA POR ENCIMA DE SU CANTO
     —su centro está en el píxel 1421.5 de 1825, medido— y el scroll acaba en el
     canto de abajo del documento, así que:
         y del cachorro = alto de ventana − alto de ESTE bloque − 0.2211·alto
     Despejando para que caiga en el 40 % de la ventana —un pelo por encima del
     centro, el encuadre del logo al encender un teléfono— sale el relleno de
     abajo. El `max(2vh, …)` es el suelo para ventanas bajas, donde la ecuación
     pediría un número negativo. */
  padding:0 1.2rem max(2vh, calc(60vh - 0.2211 * var(--alto) - 1.2em));
  gap:.2em;
  background:var(--negro);
  text-decoration:none;
  color:#fff;
  font-size:clamp(2rem, 7.6vw, 6.4rem);
}

/* ── YA NO ES EL CANTO DEL DOCUMENTO, Y LA ECUACIÓN DE ARRIBA SÍ LO CREE ─────
   El relleno de abajo despeja «que el cachorro caiga en el 40 % de la ventana
   CUANDO EL SCROLL SE ACABA», y el scroll se acababa aquí. Desde que el carrusel
   de Liz y el cierre van detrás (index.html), debajo de este bloque hay dos
   piezas más: el rótulo se lee igual y el encuadre del cachorro sigue saliendo
   de la misma cuenta, pero ya nadie garantiza que el visitante lo mire con el
   documento tocando fondo. Se deja la cuenta intacta a propósito —rehacerla es
   rediseñar la sección, y eso no es de esta vuelta—; queda escrito para que
   quien la retome sepa que su premisa cambió de sitio.

   Y EL REBOTE DEL PIE (§ `body.rebota-pie`) ya no puede alcanzarlo: la goma del
   canto ocurre ahora bajo el cierre, dos bloques más abajo. La regla se conserva
   porque no cuesta nada y vuelve sola el día que este bloque vuelva al final.

   APARECE AL LLEGAR. Es lo único de la página que pide algo: que se
   revele cuando el visitante llega le da el peso de un cierre en vez
   del de un letrero que ya estaba. La clase que esconde se la pone el SCRIPT, no
   el HTML: esconder desde el HTML y revelar desde el script es la receta clásica
   para dejar un texto invisible para siempre en cuanto algo falle. */
/* LA OPACIDAD DEL REVELADO VA EN EL CONTENIDO, NUNCA EN EL BLOQUE, y esto fue un
   bug que se vio en pantalla: el bloque pinta el NEGRO que tapa al hero —que es
   `position:fixed` y sigue vivo debajo de todo el documento—, así que bajarle la
   opacidad para la entrada volvía translúcido también ese negro y durante los 900
   ms del revelado se leía GUARDIÁN del hero por detrás de AVAILABILITY. Victor lo
   cazó en una captura a media animación. El fondo del bloque es opaco SIEMPRE; lo
   que aparece es la palabra y la flecha. */
.escala__cta.es-oculto .escala__cta__texto,
.escala__cta.es-oculto .escala__cta__flecha{ opacity:0; }
.escala__cta.es-oculto .escala__cta__texto{ transform:translateY(.7em); }
/* EL EFECTO ES LA TIPOGRAFÍA ABRIÉNDOSE, no una caja deslizándose. La palabra
   entra con el tracking cerrado y se ABRE hasta el suyo mientras sube: en una
   versal de rótulo eso se lee como un rótulo asentándose en su sitio, que es
   el gesto de una portada impresa. Y la flecha llega DESPUÉS —200 ms de retraso—
   para que primero se lea QUÉ y luego se señale DÓNDE; las dos a la vez es una
   animación, escalonadas son una frase. */
.escala__cta.es-oculto .escala__cta__texto{ --pista:.14em; }

.escala__cta__texto{ transition:letter-spacing 1100ms cubic-bezier(.2,.7,.2,1),
                     text-indent 1100ms cubic-bezier(.2,.7,.2,1),
                     opacity 900ms ease,
                     transform 900ms cubic-bezier(.2,.7,.2,1); }
.escala__cta__flecha{ transition:transform 260ms ease, opacity 700ms ease 200ms; }

/* EL REBOTE APAGA LA TRANSICIÓN DEL TRACKING MIENTRAS DURA, y esto se vio
   MIDIENDO, no razonando: el revelado de arriba pone 1100 ms de transición sobre
   `letter-spacing`, y el rebote escribe esa misma propiedad SESENTA VECES POR
   SEGUNDO. Con la transición viva, cada valor que escribe el muelle arranca su
   propia interpolación de 1100 ms y lo que llega a la pantalla es el promedio de
   sesenta animaciones solapadas — o sea, papilla con un segundo de retraso: justo
   lo contrario de un gesto que va con el dedo. En el barrido salía en el número,
   con el tracking leyendo 21.47 px donde tocaban 30.70.

   Se apaga sólo mientras hay tensión, así que la ENTRADA conserva su transición
   entera: el revelado ocurre al llegar al cierre y el rebote sólo puede ocurrir
   en el canto del documento, que está más abajo. Nunca coinciden. Y al soltar,
   la clase se quita cuando el muelle YA está en reposo, así que no hay salto. */
body.rebota-pie .escala__cta__texto{ transition:none; }

/* ── QUÉ ACUSA EL EMPUJÓN ABAJO · SE DECIDE MIDIENDO, NO POR VENTANA ──────────
   LO NATURAL AQUÍ SERÍA ABRIR EL TRACKING, que es el gesto de la casa: el rótulo
   entra abriéndose de .14em a .30em (6af9c06) porque en una versal de rótulo
   eso es un rótulo asentándose. PERO ABRIR EL TRACKING CUESTA ANCHO, y en esta
   página casi nunca lo hay. Medido en español —«Disponibilidad», un 17 % más
   ancha que «Availability»— la palabra ocupa en reposo:

       320 px → 287.6 de 284.8 de hueco     821 px →  804.3 de  782.6
       375 px → 337.0 de 339.8              1024 px → 1003.2 de  985.6
       390 px → 350.5 de 354.8              1280 px → 1254.1 de 1241.6
       430 px → 386.3 de 394.8              1440 px → 1320.1 de 1401.6

   O sea que EN LA MITAD DE LAS VENTANAS YA SE SALE ELLA SOLA, sin que nadie la
   toque —eso es un bug de la página y no de esta lane, y va apuntado—, y en el
   resto le sobran cuatro píxeles. Abrirla un 4.7 % encima la sacaría entre 10 y
   62 px. Sólo a 1440 y más arriba, donde el cuerpo topa en 6.4rem y deja de
   crecer con la ventana, hay sitio de verdad.

   POR ESO EL CANAL NO LO ELIGE UNA MEDIA QUERY SINO UNA MEDIDA. Una media query
   no sabe qué idioma se está leyendo, y la diferencia entre las dos palabras es
   mayor que la que hay entre dos ventanas. El script mide el hueco que le sobra a
   la palabra ANTES de cada gesto y pone `rebote-abre` sólo si el tracking abierto
   cabe entero. Si no cabe —que es lo normal en un teléfono y en un portátil
   estrecho— el empujón se acusa en el eje que SÍ tiene sitio: la palabra CEDE
   HACIA ABAJO contra el dedo, dentro de los 11vh de aire que el bloque ya lleva
   debajo. Misma física, misma amplitud, cero píxeles de ancho.

   LAS DOS SON SEGURAS por lo mismo, y es lo que hace libre a este canto: con
   `hero-guardado` puesto el hero no se pinta, y el bloque es opaco. Mover la
   palabra aquí no puede destapar nada. */
body.rebota-pie .escala__cta__texto{ transform:translateY(calc(var(--pie, 0) * .10em)); }
body.rebota-pie.rebote-abre .escala__cta__texto{ transform:none; --tira:.034em; }

/* ── LA FLECHA ────────────────────────────────────────────────────────────────
   ES UN VECTOR SÓLIDO, no un filete: un `<path>` de 1 px sobre la veta de la
   madera y a media pantalla de distancia sencillamente no existe. Y se dibuja con
   DOS CAJAS y no con un `<svg>` porque tiene que cumplir dos cosas que no escalan
   igual — LLEGAR hasta las patas del cachorro (un largo en fracción de la
   SECCIÓN) y tener el grosor de un trazo tipográfico (un ancho en `em`, atado a
   la palabra). Un `viewBox` fijo tiene que elegir: o estira la punta al estirar el
   asta, o la punta se queda enana en un monitor.

   OJO: el `clip-path` va en el `::after` y NO en el elemento. En el elemento
   recorta también a sus hijos, y así fue como una versión anterior se comió su
   propia punta. */
.escala__cta__flecha{
  position:relative; flex:none;
  width:.9em;
  /* EL LARGO VA EN `em` Y NO EN FRACCIÓN DE LA SECCIÓN, y el cambio es
     obligatorio desde que el rótulo vive FUERA de `.escala`: `--alto` se declara
     en la sección y aquí ya no se hereda, así que el `calc` quedaba inválido y la
     flecha se quedaba sin asta — sólo la punta, flotando. En `em` escala con la
     palabra, que es a lo que pertenece ahora. */
  height:1.55em;
  /* SUBE Y SE SOLAPA CON EL PISO: no ocupa alto en el bloque, así que no empuja
     al perro. Es además donde tiene que estar — dentro de la fotografía,
     señalando al cachorro, no en el margen de debajo. */
  margin-top:-1.55em; margin-bottom:0;
  filter:drop-shadow(0 0 .1em rgba(0,0,0,.96)) drop-shadow(0 0 .34em rgba(0,0,0,.88));
  transition:transform 260ms ease;
  /* SE MECE SOLA. Una flecha quieta apuntando a un perro es una anotación; una
     que respira es una invitación, y en un teléfono —donde no hay hover que
     descubra nada— es lo único que dice que ahí hay algo vivo. */
  animation:escala-mece 2.6s ease-in-out infinite;
}
@keyframes escala-mece{
  0%, 100% { transform:translateY(.14em); }
  50%      { transform:translateY(-.14em); }
}
.escala__cta__flecha::after{          /* el ASTA, afilada hacia la punta */
  content:""; position:absolute; left:50%; bottom:0;
  transform:translateX(-50%);
  width:.18em; height:calc(100% - .52em);
  background:currentColor;
  clip-path:polygon(0 100%, 100% 100%, 81% 0, 19% 0);
}
.escala__cta__flecha::before{         /* la PUNTA: aguja, no triángulo de icono */
  content:""; position:absolute; left:50%; top:0;
  transform:translateX(-50%);
  border-left:.24em solid transparent;
  border-right:.24em solid transparent;
  border-bottom:.58em solid currentColor;
}
.escala__cta:hover .escala__cta__flecha,
.escala__cta:focus-visible .escala__cta__flecha{ animation:none; transform:translateY(-.45em); }
.escala.es-picado + .escala__cta .escala__cta__flecha{ animation:none; transform:translateY(-.7em); }

.escala__cta__texto{
  font-family:var(--garalda);
  /* ── EL CANTO DE ABAJO · EL TRACKING ACUSA EL EMPUJÓN ───────────────────────
     EL TRACKING SE ESCRIBE COMO UNA SUMA, y ésa es toda la razón por la que el
     rebote y el revelado de 6af9c06 pueden compartir la misma propiedad sin
     pisarse: `--pista` es el tracking de REPOSO —el que cambia entre escritorio,
     teléfono y la entrada—, y `--pie` es la TENSIÓN, de -1 a 1, que escribe el
     script. Ninguno de los dos sabe del otro.

     ES EL MISMO GESTO DE LA CASA Y NO UN `scale` DE INTERFAZ: en una versal de
     rótulo, abrir el tracking es lo que hace que se lea como que se asienta. El revelado lo usa para entrar; el rebote lo usa para acusar el
     empujón. Y `--pie` LLEGA EN NEGATIVO al soltar, porque el muelle rebasa: la
     palabra se pasa un pelo POR DEBAJO de su tracking de reposo antes de
     asentarse. Eso es, con estas letras, lo que pidió Victor — «que crezca
     tantito y se haga más chiquito y te empuje de vuelta». Aquí el rebasamiento
     sale gratis y arriba no: esto es texto blanco sobre un bloque OPACO, y con
     `hero-guardado` puesto el hero ni siquiera se pinta.

     `white-space:nowrap` NO ES ADORNO, ES EL SEGURO: si el tracking abierto
     partiera la palabra en dos renglones, el bloque crecería de alto, el
     documento entero cambiaría de altura A MEDIO GESTO y el scroll saltaría bajo
     el dedo. Una línea, siempre. */
  --pista:.30em;
  /* EL TRACKING NO SE ABRE POR DEFECTO: SE GANA MIDIENDO. Ver `.rebote-abre`
     ochenta líneas más abajo — en esta página la palabra suele llenar su caja. */
  --tira:0em;
  letter-spacing:calc(var(--pista) + var(--pie, 0) * var(--tira));
  text-indent:calc(var(--pista) + var(--pie, 0) * var(--tira));
  white-space:nowrap;
  /* wght 600 Y ESTÁ MEDIDO, NO ELEGIDO — y de paso la medida corrige el porqué
     que estaba escrito aquí. Decía que a 102 px una Bodoni de peso 400 se lee
     PLATEADA porque el ojo promedia asta y fino: a este cuerpo eso NO se
     reproduce en ninguna de las dos tipografías. Erosionando un píxel la máscara
     de tinta —o sea quitándole al trazo su antialias y quedándose con el centro
     del asta— el centro sale a 254.6 sobre 255 en Bodoni 400, en Bodoni 500 y en
     Cormorant a cualquier peso. A 102 px el asta llega a blanco siempre; el
     plateado de aquel día era de otro tamaño o de otro fondo.
     Lo que sí cambia con el peso, y es lo que se ve, es la DENSIDAD DE TINTA:
     la luminancia media del trazo con su antialias, en 1440x900:
                         @1x     @2x
         Bodoni    500   226.5   237.5     ← el estado que Victor aprobó
         Cormorant 500   222.4   235.2     por debajo: se lee más flaca
         Cormorant 600   229.6   239.0     el primero que lo iguala y lo pasa
         Cormorant 700   230.9   240.3     ya no es una garalda, es una negra
     600, que además es el peldaño que se esperaba: Cormorant dibuja más ligera
     que Bodoni al mismo número. */
  font-variation-settings:"wght" 600;
  font-size:1em;
  line-height:1;
  text-transform:uppercase;
  color:inherit;
  margin:0;
  /* la viñeta va en PÍXELES y no en `em`: en `em` el desenfoque crecía con la
     letra, se metía dentro de las astas y el blanco salía gris */
  text-shadow:0 0 8px rgba(0,0,0,.95), 0 0 26px rgba(0,0,0,.85), 0 0 70px rgba(0,0,0,.7);
}

/* EN UN TELÉFONO EL TRACKING SE CIERRA PARA QUE EL CUERPO PUEDA CRECER: con .30em
   la palabra medía 423 px en una ventana de 390 y se salía. Encogerla habría sido
   lo contrario de lo pedido; cerrar el tracking a cuerpos grandes es además lo
   tipográficamente correcto. Y el trazo sube un peldaño más — ver el bloque del
   final de concursos.css, que es donde está el porqué entero. */
@media (max-width:820px){
  .escala__cta{ padding:8vh 1.1rem 11vh; }
  .escala__cta__texto{
    font-variation-settings:"wght" 650;
    font-size:clamp(1.5rem, 8.2vw, 6.4rem);
    --pista:.15em;
  }
}

/* ── EL TELÉFONO APAISADO ES OTRA COMPOSICIÓN, Y LA CULPA ES DE `vh` ──────────
   MEDIDO Y NO DEDUCIDO: simulador iOS 26.5, iPhone 17 girado, Mobile Safari.
   `innerWidth` 874, `innerHeight` 292 — y `100vh` = 402. Los 110 px de diferencia
   son las barras de Safari, que apaisado se comen el 27 % de la pantalla y que
   `vh` NO CUENTA NUNCA: en iOS `100vh` es el viewport GRANDE, el de las barras
   escondidas. Con eso la pieza se dibujaba a 942 px de alto (2 × 402 / 0.8531)
   dentro de una ventana de 292, y al fondo del documento el cachorro aterrizaba
   en y = −75: FUERA DE PANTALLA. Cachorro y llamada a WhatsApp no se veían juntos
   nunca, que es lo único que esta sección tiene que hacer.

   `svh` Y NO `dvh`, Y NO CONTRADICE EL COMENTARIO DE `.escala`. Lo que aquél
   defiende es que el alto del documento NO SE MUEVA con el dedo dentro de la
   sección, y el que se mueve es `dvh`. `svh` es el viewport PEQUEÑO —barras
   puestas— y es tan fijo como `vh`; la diferencia es que es el que SE VE. Y falla
   por el lado bueno: con las barras escondidas sobran esos 110 px y el cachorro
   sube DENTRO de la ventana en vez de salirse por arriba.

   LA FRONTERA ES EL ALTO Y NO EL ANCHO, y por eso no sirve el `(max-width:820px)`
   de aquí arriba: un iPhone apaisado mide 874 de ancho y se cuela entero por el
   lado de escritorio —sus rellenos de 8vh/11vh tampoco valdrían aquí—. 520 px
   deja fuera cualquier escritorio y dentro cualquier teléfono de canto, que como
   mucho mide 430. En vertical no entra: el encuadre medido no se toca.

   Y EL RÓTULO CEDE CUERPO, que es lo único que se sacrifica. A 7.6vw medía 66 px
   y su bloque ocupaba 87 de los 292 px de ventana, el 30 %; a 4.6vw mide 40 px y
   el bloque 54, el 18 %. La cuenta que manda es

       y del cachorro = alto de ventana − alto del bloque − 0.29687 × --alto

   —0.10507 de piso que le queda debajo más los 0.19180 que mide él—, y con
   --alto = 684.6 px da y = 35 px de aire por encima en vez de −75. El campo de
   toque del enlace queda en 874 × 54, por encima de los 44 × 44 de Apple. */
@media (orientation:landscape) and (max-height:520px){
  .escala, .escala__cta{
    --alto:min(calc(var(--pantallas) * 100svh / var(--perro)),
               calc(100vw * var(--holgura) / var(--aspecto)),
               calc(var(--nativo) * var(--invento) / var(--aspecto)));
  }
  /* LA MISMA ECUACIÓN DEL BLOQUE DE ARRIBA CON EL VIEWPORT QUE SE VE, y el inset
     de abajo sumado aparte y no metido en el `max()`: con `viewport-fit=cover` el
     indicador de inicio vive en los últimos píxeles de la ventana y el rótulo se
     le metía debajo. Los laterales van por `max()` porque apaisado el inset del
     lado de la isla son 59 px y 1.1rem son 17.6: ahí manda el que sea mayor. */
  .escala__cta{
    padding:0 max(1.1rem, env(safe-area-inset-right, 0px))
              calc(max(2svh, calc(60svh - 0.2211 * var(--alto) - 1.2em))
                   + env(safe-area-inset-bottom, 0px))
              max(1.1rem, env(safe-area-inset-left, 0px));
  }
  .escala__cta__texto{ font-size:clamp(1.25rem, 4.4vw, 2.25rem); }
}

@media (prefers-reduced-motion: reduce){
  .escala__cta, .escala__cta__flecha, .escala__cachorro{ transition:none; animation:none; }
  /* EL REBOTE SE APAGA EN LA HOJA Y NO SÓLO EN EL SCRIPT. El script no se
     instala con reduced-motion, pero alguien puede cambiar la preferencia con la
     página ya abierta y el oyente ya puesto: poniendo a cero las dos amplitudes,
     los dos `calc` caen en su valor de reposo pase lo que pase. */
  .escala__cta__texto{ --tira:0em; }
  body.rebota-pie .escala__cta__texto{ transform:none; }
  body.rebota-cima .hero__foto,
  body.rebota-cima .hero__licua{ transform:none; }
  .escala.es-picado .escala__cachorro{ transform:none; }
  .escala__cta.es-oculto{ opacity:1; transform:none; }
}
