  :root{
    /* ══ MARCA ══ Todo el color de la página sale de estas seis líneas, planos
       y transparencias incluidas: las versiones *-rgb existen para que un
       rgba() no tenga que repetir el número. Cambiar la paleta es cambiar acá
       y nada más. El esmeralda (#0b6b5e) y el dorado (#b07d34) que había antes
       salieron en agosto de 2026: el verde se leía como cualquier sistema
       clínico y el dorado envejecía todo lo que tocaba. */
    --cielo: #33708f;      --cielo-rgb: 51,112,143;
    --cielo-vivo: #4a8fae;
    --cielo-luz: #79b3cd;  --cielo-luz-rgb: 121,179,205;
    --cobre: #c4553f;      --cobre-rgb: 196,85,63;
    --cobre-luz: #e2896a;
    /* el mismo cobre, dos pasos más oscuro: el de marca no llega a contraste
       AA cuando el texto es chico (3.95:1 sobre el fondo del día) */
    --cobre-hondo: #a8422e;
    --cream: #fbf8f1;  --ink: #211d18;
    --noche: #050403;
    /* ⚠ EL PRIMER ESCALÓN DEL ALBA, Y TIENE QUE SER EL MISMO NÚMERO QUE
       `ALBA[0]` EN `noche.js`. El acto 4 NO arranca en `--noche`: arranca acá,
       once puntos de azul más arriba, porque un negro puro no es una noche —es
       la ausencia de imagen— y la rampa del amanecer necesita de dónde salir.
       Vive en un token porque la costura que baja hasta el acto tiene que
       ATERRIZAR en este color y no en el negro de la marca. Cuando aterrizaba
       en `--noche` había un escalón de 44 puntos en un solo píxel —medido con
       `costura-perfil`: 5,4,3 → 13,19,24— y eso es exactamente una línea
       dibujada a mano cruzando la página. Se veía, y nadie sabía nombrarla. */
    --alba-0: 11,17,22;
    /* ══ LA LUZ DE AIRA ══ Lo que el teléfono derrama sobre la sala en la
       escena. Es marca, no decorado: era verde-agua cuando la marca era
       esmeralda, y se corrió al azul con el resto. Mismo brillo, otro tono —
       si alguna vez hay que volver atrás o entibiarla, se toca sólo acá. */
    --luz-rgb: 124,196,222;
    --luz-viva-rgb: 84,196,224;
    --luz-media-rgb: 62,150,186;
    --luz-honda-rgb: 26,120,150;
    --luz-sombra-rgb: 3,17,24;
    /* ══ EL DÍA ══ Un blanco con el cielo de la marca adentro: el color de
       una sala con la persiana recién abierta. --dia-suave es 0.66 y no 0.62
       por una razón medida: con 0.62 da 4.48:1 y no llega al piso de AA. */
    --dia-fondo: #eef2f5;  --dia-alto: #f8fafb;
    --dia-tinta: #14202a;  --dia-suave: rgba(20,32,42,0.66);
    --dia-linea: rgba(51,112,143,0.20);
    --dia-hueso: #dde5ea;
    /* Largo de las dos costuras entre el día y la noche. Vive acá arriba
       porque el colchón de #planes se calcula A PARTIR de él: si el degradé y
       el padding se miden en unidades distintas, en algún alto de pantalla uno
       le pasa por encima al otro (pasaba en tablet vertical: el degradé tapaba
       «Sin tarjeta.»). Con un solo token la relación se sostiene en cualquier
       viewport. */
    --costura: 300px;

    /* ══ LA BARRA ══
       El margen lateral y el alto de la barra viven acá porque hay cosas
       ABAJO que tienen que alinearse con ella: el reloj del hero arrancaba en
       `left:6vw` y `top:76px`, o sea desalineado del logo en todos los anchos
       —38px a 1440— y METIDO 18px adentro de la barra, que es por qué se leía
       como parte del menú y no como la hora del consultorio. Atados al mismo
       token, no se vuelven a separar.
       El alto es el medido, no el calculado: la barra la define el botón, no
       el texto. */
    --barra-x: 48px;  --barra-h: 94px;

    /* ══ MOVIMIENTO ══
       La misma curva que el panel (PR #447): un resorte SIN rebote. Se eligió
       allá comparándola contra `ease`, contra la emphasized de Material y
       contra un resorte con overshoot — el rebote es divertido una vez y
       molesto a la décima. Que la página y el producto se muevan igual es
       parte de la marca, tanto como el color.
       La regla que viene con ella: el movimiento sólo explica cambios de
       estado —algo entra, algo se resuelve, algo carga, algo se puede
       deshacer—. Si una animación no contesta una de esas cuatro, no va. */
    --spring: linear(0, .009, .035, .078, .276, .523, .72, .857, .936, .976, .994, 1);
    --ease-salida: cubic-bezier(.2, 0, 0, 1);
    --dur-rapida: 220ms;   /* responde a un click: tiene que empezar ya */
    --dur-base: 440ms;     /* algo que entra, se despliega o se acomoda */
    --dur-plano: 760ms;    /* un plano entero entrando: acá sí hay recorrido */
    --f-d: ui-serif, Georgia, 'Times New Roman', serif;
    --f-s: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  }
  *{box-sizing:border-box}
  html,body{margin:0;padding:0;background:var(--noche);color:var(--dia-tinta);font-family:var(--f-s)}
  /* El día ya está DEBAJO de la escena: es el fondo sobre el que termina de
     entregarse (ver `amanecer()` en hero.js). Mientras la escena manda no se
     ve, porque el stage pegajoso tapa la pantalla entera. */
  /* 865 y no 820: los últimos 0,45 de pantalla son el AMANECER y ocurre acá
     adentro, con la escena pegada. Antes pasaba mientras el track salía y había
     que compensar el sticky con JS en cada cuadro: eso se siente como un scroll
     roto. Pegada, el scroll es nativo y ningún borde cruza la pantalla. */
  .track{height:865vh;position:relative;background:var(--dia-fondo)}
  /* El z-index hace posible la disolución: la escena sigue pegada y las
     secciones del día le pasan por DEBAJO. Sin él, #que-es se pinta encima y le
     corta el borde inferior con un filo horizontal. Muy por debajo del nav. */
  .stage{position:sticky;top:0;height:100vh;overflow:hidden;background:var(--noche);z-index:2}

  /* EL RELLENO: lo que rodea al cuadro. Antes era negro plano —dos barras—.
     Usa object-fit: cover a propósito: acá no hay cámara que mover, es un
     fondo (la regla de «la placa entera» vale para .plate). */
  .relleno{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--noche);contain:paint}
  .relleno img{width:100%;height:100%;object-fit:cover;
               filter:blur(34px) brightness(.42) saturate(.7);transform:scale(1.12)}
  .relleno-dia{position:absolute;inset:0;z-index:0;display:block;opacity:0;
               background:var(--dia-fondo);will-change:opacity}

  /* El CUADRO. En pantalla ancha ocupa todo; en vertical es una banda apaisada
     y alrededor queda el relleno. Todo lo fotográfico vive acá adentro. */
  .frame{position:absolute;left:0;top:50%;transform:translateY(-50%);
         width:100%;aspect-ratio:1.18;max-height:100%;overflow:hidden}

  /* dos placas: la general y el primer plano de la madera.
     La cámara corta de una a otra, como en una secuencia filmada. */
  .world{position:absolute;inset:0;will-change:transform,opacity;transform-origin:50% 50%}
  /* La placa NO se recorta con object-fit: entera y más grande que el cuadro,
     que es el que recorta. Con object-fit lo que sobraba se tiraba antes de que
     la cámara se moviera y desplazarse hacia el monitor no lo traía. */
  .plate,.over,.haz{position:absolute;left:50%;top:50%;display:block;will-change:transform}

  /* ── SI EL JAVASCRIPT NO ESTÁ ──
     El tamaño y el centrado de las placas los pone `medirPlacas()` en píxeles
     (`width` y un `marginLeft` de -W/2). Sin JS la placa se quedaba con
     `left:50%; top:50%` y su tamaño natural: una foto que ARRANCA en el centro
     de la pantalla y se va hacia abajo a la derecha, con el resto en relleno
     desenfocado. No es una hipótesis de laboratorio: es lo que ve cualquiera al
     que se le cayó el pedido de un `.js`, y también parte de lo que ve un
     crawler que no ejecuta scripts.

     Sin nadie que la mueva, la placa deja de ser una cámara y pasa a ser un
     fondo — que es lo único honesto que puede ser. Las capas vectoriales se
     apagan: el haz y el overlay están clavados a coordenadas de una placa que
     ya no está donde ellos creen. Y del segundo plano se muestra sólo el
     primero: los dos `world` se cruzan por opacidad desde el JS, así que sin él
     quedaban los dos encima, y ganaba el teléfono en primerísimo plano, que es
     el final de la escena y no su principio. */
  html:not(.js) .plate {
    left: 0; top: 0; width: 100%; height: 100%;
    margin: 0; object-fit: cover; transform: none;
  }
  html:not(.js) .haz,
  html:not(.js) .over { display: none; }
  html:not(.js) #worldB { display: none; }

  /* El haz de luna. Con feGaussianBlur de SVG se comía 32 de 54 fps: la cámara
     reescala el mundo por cuadro y el filtro se recalculaba entero. Con blur de
     CSS se rasteriza una vez. El clip va en el hijo porque el filtro se aplica
     ANTES del recorte: al revés el haz perdería los bordes. */
  .haz{pointer-events:none;opacity:0;filter:blur(26px);will-change:opacity,transform}
  .haz>i{display:block;width:100%;height:100%}
  .haz-a>i{clip-path:polygon(14.53% 0, 33.43% 0, 94.48% 100%, 61.77% 100%)}
  .haz-b>i{clip-path:polygon(5.81% 0, 30.52% 0, 45.06% 80.73%, 18.90% 80.73%)}
  .luna>i{background:linear-gradient(180deg, rgba(198,222,255,0.20), rgba(198,222,255,0))}
  .teal>i{background:linear-gradient(180deg, rgba(var(--luz-rgb),0.28), rgba(var(--luz-rgb),0))}

  .glow{position:absolute;border-radius:50%;pointer-events:none;will-change:opacity}
  .g-phone{width:20%;height:22%;left:46%;top:46%;background:rgba(var(--luz-rgb),0.42);filter:blur(50px);opacity:0}
  .g-room {width:80%;height:58%;left:10%;top:24%;background:rgba(var(--luz-honda-rgb),0.20);filter:blur(140px);opacity:0}
  .g-scr  {width:19%;height:23%;left:6%;top:38%;background:rgba(var(--luz-honda-rgb),0.50);filter:blur(44px);opacity:0}

  /* Aira no ilumina el teléfono: ilumina la sala. Va en 'screen' para LEVANTAR
     lo que ya está en la foto; un filtro encima la lavaba. */
  .flood{position:absolute;inset:-10%;pointer-events:none;opacity:0;
         mix-blend-mode:screen;will-change:opacity;
         background:
           radial-gradient(36% 44% at 46% 52%, rgba(var(--luz-viva-rgb),0.52), rgba(var(--luz-media-rgb),0.15) 44%, transparent 74%),
           radial-gradient(92% 84% at 44% 46%, rgba(var(--luz-honda-rgb),0.26), transparent 76%)}
  /* el contraste que el verde se come, devuelto por los bordes */
  .floodv{position:absolute;inset:0;pointer-events:none;opacity:0;
          background:radial-gradient(70% 64% at 46% 50%, transparent 44%, rgba(var(--luz-sombra-rgb),0.66) 100%)}

  .grade{position:absolute;inset:0;pointer-events:none;mix-blend-mode:soft-light;
         background:linear-gradient(180deg, rgba(120,160,220,0.26), rgba(0,0,0,0) 45%, rgba(0,0,0,0.40))}
  .grain{position:absolute;inset:-110px;pointer-events:none;opacity:0.15;mix-blend-mode:overlay}
  /* mientras la escena se va, lo caro de la película deja de existir: el grano
     y el polvo no se ven —la luz ya está quemando la sala— pero se seguían
     componiendo cuadro a cuadro */
  .stage.saliendo .grain, .stage.saliendo #aDust, .stage.saliendo #bDust{display:none}
  /* y con ellos, todo lo que se mezcla: cada capa con blend mode obliga a
     recomponer el subárbol entero de la escena en cada cuadro. La luz de Aira y
     el viraje no tienen nada que hacer acá —la sala se está volviendo blanca—,
     pero la viñeta SE QUEDA: no lleva blend, no cuesta, y sacarla se notaba
     como un salto de la escena a una foto pelada. */
  .stage.saliendo .flood, .stage.saliendo .floodv,
  .stage.saliendo .grade, .stage.saliendo .over{display:none}
  .vig{position:absolute;inset:0;pointer-events:none;
       background:radial-gradient(80% 76% at 50% 48%, transparent 42%, rgba(0,0,0,0.70) 100%)}

  /* La sobreexposición: blanco en `screen`, la misma técnica que la luz de
     Aira. Con filter: brightness() costaba 15 fps —reprocesa todo el cuadro—. */
  .quema{position:absolute;inset:0;pointer-events:none;opacity:0;
         background:#fff;mix-blend-mode:screen;will-change:opacity}

  /* EL AMANECER. El origen (16% 26%) es donde cae la ventana en la placa A:
     si se cambia la foto, se re-mide con ?cal=a. Vive fuera del .frame para
     cubrir también el relleno. Lo empuja `amanecer()` en hero.js. */
  .sol{position:absolute;inset:-40%;z-index:10;pointer-events:none;opacity:0;
       transform:scale(.25);transform-origin:16% 26%;will-change:opacity,transform;
       background:radial-gradient(closest-side, #fff 0%, rgba(255,255,255,.92) 42%,
                  rgba(255,247,232,.5) 66%, rgba(255,247,232,0) 100%)}

  .cap{position:absolute;left:0;right:0;bottom:88px;text-align:center;z-index:9;padding:0 6vw;pointer-events:none}
  .cap .t{display:inline-block;font-family:var(--f-d);font-size:clamp(17px,2.2vw,27px);line-height:1.35;
          color:rgba(251,248,241,0.94);text-shadow:0 2px 26px rgba(0,0,0,0.9);
          transition:opacity .38s ease, transform .38s ease}
  .cap .t.out{opacity:0;transform:translateY(6px)}
  .cap .t em{font-style:italic;color:var(--cielo-luz)}

  .dlg{position:absolute;top:22vh;right:6vw;width:34vw;min-width:280px;z-index:9;pointer-events:none}
  .dlg .ln{opacity:0;transform:translateY(12px);transition:opacity .55s ease, transform .55s ease;margin-bottom:22px}
  .dlg .ln.on{opacity:1;transform:none}
  .dlg .rol{font-size:9.5px;letter-spacing:.24em;text-transform:uppercase;font-weight:700;
            color:rgba(251,248,241,.4);display:block;margin-bottom:4px}
  .dlg .tx{font-family:var(--f-d);font-size:clamp(15px,1.5vw,19px);line-height:1.42;
           color:rgba(251,248,241,.9);text-shadow:0 2px 18px rgba(0,0,0,.85)}
  .dlg .ln.aira{text-align:right}
  .dlg .ln.aira .tx{color:var(--cielo-luz)}

  .hora{position:absolute;top:calc(var(--barra-h) + 18px);left:var(--barra-x);z-index:9;pointer-events:none}
  .hora .hh{font-family:var(--f-d);font-size:clamp(30px,3.6vw,46px);line-height:1;
            color:rgba(251,248,241,.9);text-shadow:0 2px 22px rgba(0,0,0,.9);font-variant-numeric:tabular-nums}
  /* El cobre de marca sobre la sala de noche da 3.7:1 —y contra la pared ya
     iluminada del amanecer, 2.9:1— a 9.5px con letter-spacing ancho: no se
     leía, se adivinaba. Es el mismo caso del punto del logo, que ya se aclara
     sobre la escena, y se arregla con la misma variable: --cobre-luz da 5.9:1
     de noche y sigue pasando AA cuando la sala se aclara. */
  .hora .cc{margin-top:7px;font-size:9.5px;letter-spacing:.3em;text-transform:uppercase;
            font-weight:700;color:var(--cobre-luz);text-shadow:0 1px 14px rgba(0,0,0,.75)}

  .hint{position:absolute;left:50%;bottom:26px;transform:translateX(-50%);z-index:10;
        display:inline-flex;align-items:center;gap:8px;padding:9px 17px;border-radius:999px;
        background:rgba(251,248,241,.09);border:1px solid rgba(251,248,241,.16);
        color:rgba(251,248,241,.8);font-size:12px;backdrop-filter:blur(8px);transition:opacity .4s ease}
  .hint.off{opacity:0}
  /* ── LA FLECHA SE MUEVE, PORQUE SI NO NADIE LA MIRA ──
     La única instrucción de la página estaba QUIETA: 12px sobre una foto de
     noche, compitiendo con el reloj, el sonido y un diálogo que se escribe
     solo. En una pantalla donde todo se mueve, lo quieto no se ve — y no se
     vio. Es la excepción a la regla de la casa («el movimiento sólo explica
     cambios de estado»): acá no explica uno, lo PIDE.
     Casi segundo y medio de quietud entre pulso y pulso: dos bajadas seguidas
     leen como un banner. */
  @keyframes hint-baja{
    0%,62%,100%{transform:translateY(0);opacity:.55}
    18%{transform:translateY(4px);opacity:1}
    40%{transform:translateY(0);opacity:.75}
  }
  .hint svg{display:block;animation:hint-baja 2.1s var(--spring) infinite}
  .hint.off svg{animation:none}

  /* ══ EL HILO DE LA PELÍCULA ══
     El aviso se apaga apenas scrolleás; esto acompaña las nueve pantallas que
     siguen, al pie, que es donde un reproductor pone su progreso. El color es
     la luz de Aira: no entra un color nuevo a la película.
     `scaleX` y no `width`: `render()` lo escribe en cada cuadro y animar
     `width` a 60 fps rehace el layout de la escena entera. */
  .hilo{position:absolute;left:0;right:0;bottom:0;height:2px;z-index:10;
        background:rgba(251,248,241,.10);transition:opacity .4s ease;pointer-events:none}
  .hilo i{display:block;height:100%;width:100%;transform-origin:0 50%;transform:scaleX(0);
          background:linear-gradient(90deg,rgba(var(--luz-rgb),.45),rgba(var(--luz-rgb),.95))}

  @keyframes ringx{0%{opacity:0;transform:scale(.55)}18%{opacity:.85}100%{opacity:0;transform:scale(1.5)}}
  .rc{transform-box:fill-box;opacity:0}
  .rc.rt{transform-origin:0% 50%} .rc.lf{transform-origin:100% 50%}
  .ringing .rc{animation:ringx 2.2s ease-out infinite;opacity:1}
  .ringing .rc.r2{animation-delay:.73s}
  .ringing .rc.r3{animation-delay:1.46s}

  /* El sonido arranca APAGADO siempre: nadie quiere que una página le haga
     ruido sin permiso, y los navegadores tampoco lo dejan. El botón es el
     permiso. */
  /* 116 y no 74: a 74 quedaba pegado abajo del botón del nav —dos pastillas
     tocándose en la esquina— y se leían como si fueran del mismo grupo. */
  .snd{position:absolute;top:116px;right:6vw;z-index:11;display:inline-flex;align-items:center;gap:8px;
       padding:9px 15px;border-radius:999px;cursor:pointer;
       background:rgba(5,12,10,.5);border:1px solid rgba(251,248,241,.16);
       color:rgba(251,248,241,.55);font-family:var(--f-s);font-size:12px;
       backdrop-filter:blur(8px);transition:color .3s ease, border-color .3s ease}
  .snd:hover{color:rgba(251,248,241,.85);border-color:rgba(251,248,241,.3)}
  .snd .s-on{opacity:0} .snd .s-off{opacity:1}
  .snd.on{color:var(--cielo-luz);border-color:rgba(var(--luz-rgb),.42)}
  .snd.on .s-on{opacity:1} .snd.on .s-off{opacity:0}


  /* En vertical el cuadro es una banda apaisada: el diálogo no puede quedar
     montado a caballo del borde —se parte en dos— así que baja al negro de
     abajo, que es donde hay aire. */
  @media (max-width:760px){
    /* EL RÓTULO DEL RELOJ SE METÍA DEBAJO DEL BOTÓN DE SONIDO, y ahí se
       terminaba de leer. Los dos viven arriba y a la misma altura —el rótulo
       cuelga del reloj, a la izquierda; el botón está a la derecha en top:116—
       y el rótulo CAMBIA DE TEXTO a mitad de la película: «tu consultorio, hoy»
       entra, «y mañana tenés un paciente más» mide 256px y no. Medido: se
       pisaban 80px a 320, 42 a 360 y 14 a 390 — o sea en todo teléfono, y justo
       con la frase que remata el hero. Arriba de 430 no pasa, y ésa es la razón
       por la que nadie lo había visto.
       No se arregla moviendo el botón: a 74 ya se probó y quedaba pegado al del
       nav, y bajarlo lo deja flotando sobre la foto. El rótulo tiene lugar de
       sobra para romper en dos renglones, y `.hora` es `absolute`, así que
       romper no empuja nada. 50vw deja 17px de aire en el peor caso. */
    .hora .cc{max-width:50vw}
    /* ══ EL RELOJ Y LA FRASE SE PEGAN A LA FOTO ══
       En vertical el cuadro es una banda apaisada centrada, y arriba y abajo
       queda relleno. El reloj colgaba del borde de ARRIBA de la pantalla y la
       frase del de abajo: a 390×844 quedaban a 157 y 133 px de la foto — dos
       textos flotando en dos manchas grises, con la película partida en tres.
       Ahora los dos cuelgan DEL CUADRO: su alto es 100vw/1,18 y está centrado,
       así que su borde de arriba cae en `50% - 100vw/2,36`. El reloj se apoya
       76 px por encima (lo que pide su rótulo de dos renglones) y la frase, 44
       por debajo. El `max()` es el seguro: en una pantalla apaisada y baja la
       cuenta da negativo y ahí gana el valor de siempre. */
    .hora{top:max(calc(var(--barra-h) + 18px), calc(50% - 100vw / 2.36 - 76px))}
    .dlg{top:auto;bottom:118px;left:5vw;right:5vw;width:auto}
    .dlg .ln{margin-bottom:14px}
    /* 104 es el piso —abajo de eso el aviso de scroll, que a este ancho rompe en
       dos renglones, le quedaba apoyado encima— pero el valor que manda es el
       que la pega al cuadro. Ver la cuenta en `.hora`, arriba. */
    .cap{bottom:max(104px, calc(50% - 100vw / 2.36 - 44px))}
    /* 12,5 y no 11,5: es la única instrucción de toda la página —le dice al
       visitante qué tiene que hacer para que la película arranque— y en un
       teléfono es justo donde peor se lee. Entra igual en una línea. */
    .hint{font-size:12.5px;white-space:nowrap;padding:8px 14px}
  }
  @media (prefers-reduced-motion: reduce){ .ringing .rc, .hint svg{animation:none} }

  /* El día arranca ANTES de que el track termine y la escena —pegada y por
     encima— le pasa por delante mientras se disuelve: el título ya está en su
     lugar cuando la luz se apaga, sin mover nada con JS. Sin esto quedaba casi
     una pantalla de blanco entre la luz y el título. */
  /* `clip` y NO `hidden`: hidden convierte a main en contenedor de scroll y
     rompe el sticky del mazo. clip recorta sin crear scrollport. Hace falta
     porque el barrido mete un plano entero desde la derecha, y sin esto son
     cientos de píxeles de scroll horizontal — el mismo bug que dio el `100vw`
     y que en headless no se ve, así que lo mira qa-final. */
  main.dia { background: var(--dia-fondo); margin-top: -62vh; position: relative;
             overflow-x: clip; }
  /* el nav es fijo: sin esto los anclas dejan el título debajo de la barra */
  main.dia section { scroll-margin-top: 72px; }

  /* sin position: la sección era relativa sólo para colgarle el degradé de la
     costura, y posicionarla la ponía a pintar por encima de la escena */
  /* 40 y no 96 arriba: el título tiene que entrar MIENTRAS la luz del
     amanecer sigue encendida, para nacer de ella. Con 96 la escena terminaba
     de irse antes y quedaba una pantalla vacía. */
  #agenda {
    background: var(--dia-fondo);
    padding: 40px 24px 64px;
    text-align: center;
  }
  /* La costura de entrada no se pinta: acá no hay ninguna capa. El puente
     entre la noche y el día es la luz, y vive en `amanecer()` (hero.js). */
  /* El primero era un h1 y los otros cinco son h2. El margen se fija acá, con
     el mismo 0.83em que el navegador le da a un h2, para que el cambio de tag
     no mueva nada: sin esto el h1 traería su propio margen y el título quedaría
     unos píxeles más arriba que los demás. */
  .s-tit {
    font-family: 'Fraunces', serif; font-weight: 300;
    font-size: clamp(30px, 4.4vw, 52px); line-height: 1.12; letter-spacing: -0.01em;
    margin: 0.83em 0;
  }
  .s-sub { margin-top: 14px; font-size: 17px; color: var(--dia-suave); }

  /* ══ PRUEBA: LOS PLANOS SE APILAN ══
     Probado en un solo paso —del reproductor al panel— para poder mirarlo antes
     de comprometer la página entera.

     Cómo funciona: el plano de abajo queda PEGADO en pantalla (sticky) y el
     siguiente sube por encima y lo tapa, como una carta que cae sobre otra. Lo
     que lo vende son tres cosas: el canto redondeado de la que sube, la sombra
     que tira sobre la que queda, y que la de abajo se hunde un poco mientras la
     tapan (se achica y se oscurece).

     Se activa sólo en pantallas anchas y con altura suficiente: apilar en un
     alto de 700 px deja el contenido cortado, y en un teléfono no hay dónde.
     Para sacarlo alcanza con borrar este bloque. */
  @media (min-width: 900px) and (min-height: 760px) {
    #escuchar{
      position:sticky;top:0;min-height:100vh;
      display:flex;align-items:center;
      /* mientras lo tapan se hunde: es lo que hace que se lea como profundidad
         y no como que la de arriba le pasa por encima */
      transform:scale(calc(1 - var(--sal, 0) * .045));
      filter:brightness(calc(1 - var(--sal, 0) * .10));
      transform-origin:50% 30%;
    }
    #escuchar > .ec{width:100%}
    /* el dolly de salida se apaga acá: el plano ya se va tapado, y las dos
       cosas juntas lo hacían desaparecer dos veces.
       `translate` y `scale` van explícitas por lo mismo que `opacity`: este
       plano NO tiene entrada —viene del hero, ya está—, y desde que la entrada
       de los planos se mudó de `transform` a sus propias propiedades, apagar
       sólo el `transform` dejaba de alcanzar. Le quedaban los 60px de abajo
       hasta que el observer marcaba la sección. */
    .js #escuchar .s-tit,
    .js #escuchar .s-sub,
    .js #escuchar .an:not(.s-tit):not(.s-sub){
      opacity:1;filter:none;translate:none;scale:none;
      transform:translateY(calc((var(--p,.5) - .5) * -18px));
    }

    #agenda{
      position:relative;z-index:3;
      border-radius:36px 36px 0 0;
      /* la sombra es lo que vende el apilado: las dos secciones son casi del
         mismo claro, así que sin ella el canto no se lee como un plano nuevo
         sino como un borde raro */
      box-shadow:0 -34px 80px rgba(20,32,42,.22), 0 -1px 0 rgba(255,255,255,.75);
    }
    /* el halo del amanecer se recorta con el canto de la que sube */
    #agenda{overflow:hidden}
  }

  /* ══ ACTO 2 — LA AGENDA QUE SE LLENÓ SOLA ══
     Era una tabla centrada sobre fondo liso: se leía como una tabla y no como
     el panel de la clínica. Lo que cambió no es el dato, es la puesta en
     escena. Tres cosas la hacen objeto y no caja:
       · la ventana entera —barra, menú, contenido—, para que se entienda de
         qué se está mirando una foto;
       · perspectiva: llega inclinada y se endereza mientras subís (--ag-p lo
         maneja el scroll, transform-only);
       · luz: el halo del amanecer sigue encendido arriba, así el plano nace de
         la escena en vez de empezar de cero sobre un fondo liso. */
  #agenda{position:relative;overflow:hidden;padding:40px 24px 96px}
  /* el resto de la luz del amanecer, que muere justo antes de la ventana */
  .ag-luz{position:absolute;left:50%;top:-14%;width:min(1100px,120%);height:520px;
          transform:translateX(-50%);pointer-events:none;z-index:0;
          background:radial-gradient(50% 50% at 50% 50%,
            rgba(var(--luz-rgb),.22), rgba(var(--luz-rgb),.06) 46%, transparent 72%)}
  #agenda > *:not(.ag-luz){position:relative;z-index:1}

  /* la caja de perspectiva: vive acá y no en la ventana, si no el 3D se aplana */
  .ag-escena{perspective:1400px;perspective-origin:50% 0%;margin-top:44px}

  .ag-ventana{
    --ag-p:0;                                  /* 0 = llegando · 1 = enderezada */
    width:min(940px,100%);margin:0 auto;text-align:left;
    background:var(--pn-bg);border-radius:20px;overflow:hidden;
    border:1px solid var(--dia-linea);
    transform:
      perspective(1400px)
      rotateX(calc((1 - var(--ag-p)) * 9deg))
      translateY(calc((1 - var(--ag-p)) * 34px))
      scale(calc(0.955 + var(--ag-p) * 0.045));
    /* la sombra crece con la ventana: es lo que la despega del fondo */
    box-shadow:
      0 calc(18px + var(--ag-p) * 30px) calc(40px + var(--ag-p) * 60px) rgba(20,32,42,calc(.10 + var(--ag-p) * .10)),
      0 2px 6px rgba(20,32,42,.06);
    will-change:transform;
  }

  /* ══ LA VENTANA ES EL PANEL DE VERDAD ══
     Contra el panel de HOY (`origin/main`, post PR #500), no contra el de hace
     tres meses: la copia anterior venía de la paleta esmeralda y de un shell
     que ya no existe. Los tokens son los de `globals.css`, literales — ojo con
     los dos grises de texto, que estaban un escalón claros.
     Lo único que cambia es la ESCALA: la ventana mide 940 px y el panel se
     dibuja sobre 1600, así que lo grande baja un escalón (barra 56→46, menú
     220→200, título 30→22). Nada que ya esté en su piso de legibilidad se
     toca: 11 px el turno, 12 los rótulos, 13 el menú.
     Y los números NO van en Fraunces: en el panel `font-serif` está mapeado a
     Geist, que es una sans. */
  .ag-ventana{
    --pn-bg:#f9f8f5; --pn-sup:#ffffff; --pn-sup2:#f2f0ea;
    --pn-line:#e5e2da; --pn-line-f:#cfcabd;
    --pn-ink:#211d18; --pn-muted:#615951; --pn-faint:#726b63;
    --pn-ac:#33708f; --pn-ac-fuerte:#275770; --pn-ac-suave:#e8f1f6; --pn-ac-luz:#79b3cd;
    --pn-cobre:#c4553f; --pn-verde:#2f7d5f;
    --pn-r-ctrl:14px; --pn-r-card:20px;
    --pn-sombra:0 1px 2px rgba(33,29,24,.04),0 6px 20px rgba(33,29,24,.05);
    --pn-sombra-alta:0 2px 6px rgba(33,29,24,.06),0 14px 40px rgba(33,29,24,.09);
    /* la monoespaciada del panel es Geist Mono; acá va la del sistema, que no
       cuesta un pedido de red y hace el mismo trabajo: alinear horas */
    --pn-mono:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,monospace;
    color:var(--pn-ink);
  }

  /* ── LA BARRA DE ARRIBA ──
     Eran los tres puntos de macOS, y el panel no es una app de escritorio: su
     barra lleva el wordmark, el buscador y quién está adentro. Es lo primero
     que dice de qué producto es esta foto. */
  .ag-top{display:flex;align-items:center;gap:12px;height:46px;padding:0 14px;
          background:var(--pn-sup);border-bottom:1px solid var(--pn-line)}
  .ag-marca{font-size:17px;font-weight:600;letter-spacing:-.02em;line-height:1;
            color:var(--pn-ink)}
  /* el punto es el mismo cobre que cierra la marca en el resto de la página */
  .ag-marca i{font-style:normal;color:var(--pn-cobre)}
  .ag-ham,.ag-cerrar{display:none}
  .ag-buscar{display:flex;align-items:center;gap:8px;margin-left:10px;
             height:30px;width:230px;padding:0 11px;border-radius:11px;
             background:var(--pn-sup2);color:var(--pn-faint);font-size:12.5px}
  .ag-buscar svg{width:14px;height:14px;flex:none}
  .ag-buscar kbd{margin-left:auto;font:inherit;font-size:10px;font-weight:600;
                 color:var(--pn-muted);background:var(--pn-sup);
                 border:1px solid var(--pn-line-f);border-radius:4px;padding:1px 5px}
  .ag-yo{display:flex;align-items:center;gap:9px;margin-left:auto}
  .ag-yo-av{display:grid;place-items:center;width:25px;height:25px;border-radius:50%;
            flex:none;background:var(--pn-sup2);color:var(--pn-muted);
            font-size:10px;font-weight:700;letter-spacing:.02em}
  .ag-yo-tx{font-size:11.5px;color:var(--pn-muted);white-space:nowrap}

  /* alto fijo: sin esto la ventana crecía y se achicaba con cada pantalla del
     menú, y el plano entero saltaba al navegar */
  .ag-cuerpo{position:relative;display:grid;grid-template-columns:200px 1fr;
             background:var(--pn-bg);min-height:512px}
  .ag-pant{height:100%}
  /* El velo del cajón NO existe fuera del teléfono. Sin este `display:none` es
     un hijo más de la grilla y se come la primera columna. */
  .ag-velo{display:none}

  /* ── EL MENÚ ──
     Era blanco con una línea a la derecha. En el panel es una ZONA MATE y el
     contenido es la hoja blanca que se apoya encima: esa línea era lo que lo
     hacía leer como una plantilla. Y «OPERACIÓN» no existe más. */
  .ag-menu{background:var(--pn-sup2);padding:11px 10px;
           display:flex;flex-direction:column;min-width:0}
  .ag-menu-cab{display:flex;align-items:center;gap:8px;margin-bottom:11px}
  /* en el panel es surface-2 sobre una barra que ya es surface-2: no se ve.
     Acá tampoco, a propósito. */
  .ag-clinica{display:flex;align-items:center;gap:10px;padding:5px 4px;min-width:0;flex:1}
  .ag-ini{display:grid;place-items:center;width:30px;height:30px;border-radius:8px;flex:none;
          background:linear-gradient(135deg,var(--pn-ac-luz),var(--pn-ac-fuerte));
          color:#fff;font-size:11px;font-weight:700;letter-spacing:.02em}
  .ag-clinica-tx{display:grid;min-width:0}
  .ag-clinica-tx b{font-size:12px;font-weight:700;color:var(--pn-ink);
                   overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ag-clinica-tx i{font-style:normal;font-size:10px;color:var(--pn-faint)}
  /* ⚠ EL RESET NO ES DECORATIVO: en esta hoja `nav`, `footer` y `main` están
     estilados POR ELEMENTO, así que un <nav> acá adentro nace `position:fixed`
     y a ancho completo. Ya había pasado con el <footer> de la receta. Usar
     cualquiera de las tres dentro de un componente obliga a resetearla en la
     misma regla en que se la crea. La historia entera, en `qa-panel`. */
  .ag-menu nav.ag-lista-nav{position:static;inset:auto;z-index:auto;
    display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;
    gap:2px;min-width:0;padding:0;border:0;background:none;transition:none}
  .ag-item{display:flex;align-items:center;gap:11px;padding:8px 11px;
           border-radius:var(--pn-r-ctrl);cursor:pointer;
           font:inherit;font-family:var(--f-s);font-size:13px;font-weight:500;
           text-align:left;border:0;background:transparent;width:100%;
           color:var(--pn-muted);
           transition:background-color var(--dur-rapida) var(--ease-salida),
                      color var(--dur-rapida) var(--ease-salida),
                      transform var(--dur-rapida) var(--ease-salida),
                      box-shadow var(--dur-rapida) var(--ease-salida)}
  .ag-item svg{width:16px;height:16px;flex:none;color:var(--pn-faint)}
  /* las filas se levantan al pasar por encima: así separa el panel nuevo, con
     profundidad y no con una línea */
  .ag-item:hover{background:rgba(255,255,255,.7);color:var(--pn-ink);transform:translateX(2px)}
  .ag-item:hover svg{color:var(--pn-muted)}
  /* El activo NO se pinta de celeste: se LEVANTA. Superficie blanca con sombra
     sobre el mate, y el ícono en el color de marca. Es la regla del panel. */
  .ag-item.on{background:var(--pn-sup);color:var(--pn-ink);font-weight:600;
              box-shadow:var(--pn-sombra);transform:none}
  .ag-item.on svg{color:var(--pn-ac)}
  .ag-item:focus-visible{outline:2px solid var(--pn-ac);outline-offset:2px}
  .ag-badge{margin-left:auto;background:var(--pn-ac);color:#fff;font-size:10px;font-weight:700;
            line-height:1;border-radius:999px;padding:3px 6px}

  /* ── EL LIENZO ──
     El contenido no vive en una barra blanca con borde: flota sobre el hueso, y
     las tarjetas son lo único blanco. Por eso la cabecera no tiene fondo. */
  .ag-panel{display:flex;flex-direction:column;background:var(--pn-bg);
            padding:16px 20px 20px;min-width:0}
  .ag-cab{display:flex;justify-content:space-between;align-items:flex-start;
          gap:16px;margin-bottom:14px}
  .ag-cab-tx{display:grid;gap:2px;min-width:0}
  .ag-dia{font-family:var(--f-s);font-size:22px;font-weight:600;letter-spacing:-.02em;
          line-height:1.2;color:var(--pn-ink)}
  .ag-sub{font-style:normal;font-size:12.5px;color:var(--pn-muted)}

  /* el control segmentado del panel: contenedor redondo, botones de esquina
     suave, y el activo en celeste claro —no en blanco— */
  .ag-vistas{display:flex;align-items:center;gap:3px;flex:none;
             background:var(--pn-sup2);border-radius:999px;padding:3px}
  .ag-v{font:inherit;font-family:var(--f-s);font-size:11.5px;font-weight:600;
        height:27px;padding:0 11px;border:0;border-radius:10px;
        background:transparent;color:var(--pn-muted);cursor:pointer;
        transition:background-color .2s ease,color .2s ease}
  /* el hover del panel es surface-2 y el contenedor ya lo es: no se ve. Acá se
     levanta con blanco, como el ítem del menú */
  .ag-v:hover:not(.on){background:var(--pn-sup);color:var(--pn-ink)}
  .ag-v.on{background:var(--pn-ac-suave);color:var(--pn-ac-fuerte)}
  .ag-v:focus-visible{outline:2px solid var(--pn-ac);outline-offset:2px}

  /* la fila de navegación: flechas, «Hoy» y el rótulo de la fecha */
  .ag-fecha{display:flex;align-items:center;gap:7px;margin-bottom:11px}
  .ag-flechas{display:flex;gap:6px}
  .ag-flechas i{display:grid;place-items:center;width:25px;height:25px;border-radius:999px;
                background:var(--pn-sup);box-shadow:var(--pn-sombra);color:var(--pn-muted)}
  .ag-flechas svg{width:13px;height:13px}
  .ag-hoy{border-radius:999px;background:var(--pn-sup);box-shadow:var(--pn-sombra);
          padding:5px 13px;font-size:12px;color:var(--pn-muted);line-height:1.2}
  .ag-cuando{margin-left:3px;font-size:12.5px;font-weight:500;color:var(--pn-ink)}
  /* El panel no lleva contador global —el conteo vive por día— pero acá el
     número ES el punto: sube mientras los turnos caen. Va con la pastilla que
     el panel sí tiene, la del conteo por día. */
  .ag-cont{margin-left:auto;border-radius:999px;padding:2px 9px;
           background:var(--pn-ac-suave);color:var(--pn-ac-fuerte);
           font-size:11.5px;font-weight:500;white-space:nowrap}
  .ag-cont b{font-weight:700;font-variant-numeric:tabular-nums}

  /* ── las cuatro vistas ── */
  .ag-vista{display:none}
  .ag-vista.on{display:block;animation:agEntra .34s var(--spring)}
  @keyframes agEntra{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

  /* ══ VISTA DÍA ══
     Eran dos cajas blancas redondeadas, una por profesional, y eso era lo que
     la hacía leer como una tabla. Es UNA grilla. Los bordes acá son el único
     lugar del panel donde una línea de 1px no es decoración: es el instrumento. */
  .ag-grilla{display:grid;grid-template-columns:50px 1fr;
             background:var(--pn-sup);border-radius:var(--pn-r-card);
             box-shadow:var(--pn-sombra);overflow:hidden}
  /* 44px por franja de 30 min. En el panel son 48 en densidad Cómodo; acá baja
     con el resto de la escala, y el resultado es el mismo 1,47 px por minuto
     con el que se calcula el alto de cada turno. */
  /* ⚠ EL ALTO DE LA CABECERA SE HEREDA: el `32px` va como FALLBACK del `var()`,
     no como declaración. Fijarlo acá le ganaba al 44 que hereda de `.ag-sem` y
     la canaleta de la Semana quedaba 12px arriba de su franja. */
  .ag-horas{position:relative;padding-top:var(--ag-cab-h,32px);
            border-right:1px solid var(--pn-line)}
  /* la línea de la cabecera cruza también la canaleta: sin esto queda cortada
     justo en los 50px de la izquierda */
  .ag-horas::before{content:'';position:absolute;left:0;right:0;top:var(--ag-cab-h,32px);
                    height:1px;background:var(--pn-line)}
  /* una grilla de franjas y no nueve reglas de posición: el rótulo va a la
     derecha, montado sobre su línea, como el panel */
  .ag-horas{display:grid;grid-template-rows:repeat(9,44px)}
  .ag-horas span{text-align:right;padding-right:6px;transform:translateY(-5px);
                 font-family:var(--pn-mono);font-size:9.5px;line-height:1;
                 color:var(--pn-faint);font-variant-numeric:tabular-nums}
  /* el primero no puede treparse a la línea de la cabecera */
  .ag-horas span:first-child{transform:translateY(3px)}

  .ag-cols{position:relative;display:flex;min-width:0}
  .ag-col{flex:1;display:flex;flex-direction:column;min-width:0}
  .ag-col + .ag-col{border-left:1px solid var(--pn-line)}
  .ag-med{height:var(--ag-cab-h,32px);display:flex;align-items:center;justify-content:center;
          border-bottom:1px solid var(--pn-line);
          font-size:12.5px;font-weight:600;color:var(--pn-ink);
          overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 8px}
  /* las líneas van en el fondo y no en siete elementos por columna: veintiocho
     nodos menos */
  /* 396 y no 352: «primera vez» dura 60 min y el de las 11:00 terminaba pegado
     al borde. El panel hace esto mismo — extiende el rango si un turno cae
     afuera— para no ocultar ninguno. */
  .ag-slots{position:relative;height:396px;
            background-color:rgba(232,241,246,.20);
            background-image:repeating-linear-gradient(to bottom,
              transparent 0 43px, var(--pn-line) 43px 44px)}
  /* la línea de «ahora». En la vista Día del panel es un borde de 2px y NO
     lleva punto —el punto es de la vista Semana—. */
  .ag-ahora{position:absolute;left:0;right:0;top:calc(var(--ag-cab-h,32px) + 154px);
            height:0;border-top:2px solid var(--pn-ac);pointer-events:none;z-index:3}

  /* ── EL TURNO ──
     Ocupaba dos renglones y 43 px fijos. En el panel es UNA línea —hora en
     monoespaciada al 70 % y paciente— y mide LO QUE DURA. El tipo va en el
     `title`, como el tooltip del panel. */
  .ag-fila{position:absolute;left:2px;right:2px;z-index:2;
           border-radius:6px;padding:2px 6px;overflow:hidden;
           font-family:var(--f-s);font-size:11px;font-weight:500;line-height:1.25;
           white-space:nowrap;text-overflow:ellipsis;
           opacity:0;transform:translateY(-6px) scale(.98);
           transition:opacity .45s ease,transform .45s var(--spring),
                      box-shadow .5s ease}
  .ag-fila.in{opacity:1;transform:none}
  /* al caer se enciende, como cuando entra un turno de verdad en el panel. El
     verde de antes era del esmeralda que la marca dejó: va el cielo. */
  .ag-fila.nueva{box-shadow:0 0 0 3px rgba(var(--cielo-rgb),.38)}
  /* el anillo del estado confirmado, que el panel dibuja por dentro */
  .ag-fila::after{content:'';position:absolute;inset:0;border-radius:6px;
                  box-shadow:inset 0 0 0 1px rgba(16,185,129,.4);pointer-events:none}
  .ag-hora{font-family:var(--pn-mono);font-size:10px;opacity:.7;
           font-variant-numeric:tabular-nums}
  .ag-quien{font-weight:500}
  /* los cinco colores de tipo de turno del panel (TIPO_COLOR_MAP).
     `t-accent` era menta (#ecfdf5 sobre #09564b): el esmeralda de la marca
     vieja, que se fue en agosto de 2026 y acá había quedado. */
  .t-accent{background:#e8f1f6;color:#275770}
  .t-sky{background:#e0f2fe;color:#0369a1}
  .t-violet{background:#ede9fe;color:#6d28d9}
  .t-amber{background:#fef3c7;color:#b45309}
  .t-rose{background:#ffe4e6;color:#be123c}

  /* ══ VISTA SEMANA ══
     Siete días y no cinco: el panel dibuja lunes a domingo siempre. Misma
     grilla que Día, con el encabezado en dos renglones y su pastilla de conteo. */
  .ag-sem{--ag-cab-h:44px;display:grid;grid-template-columns:50px 1fr;
          background:var(--pn-sup);border-radius:var(--pn-r-card);
          box-shadow:var(--pn-sombra);overflow:hidden}
  .ag-sem-dia{flex:1;display:flex;flex-direction:column;min-width:0}
  .ag-sem-dia + .ag-sem-dia{border-left:1px solid var(--pn-line)}
  .ag-sem-cab{height:var(--ag-cab-h);display:flex;flex-direction:column;
              align-items:center;justify-content:center;gap:1px;
              border-bottom:1px solid var(--pn-line);padding:0 2px}
  .ag-sem-cab.hoy{background:rgba(232,241,246,.5)}
  .ag-sem-et{font-size:9.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
             color:var(--pn-faint);line-height:1}
  .ag-sem-cab.hoy .ag-sem-et{color:var(--pn-ac-fuerte)}
  .ag-sem-n{display:flex;align-items:center;gap:4px;font-size:12.5px;font-weight:700;
            color:var(--pn-ink);line-height:1}
  .ag-sem-cab.hoy .ag-sem-n{color:var(--pn-ac-fuerte)}
  /* el badge del panel es el número pelado, sin la palabra «turnos» */
  .ag-sem-b{border-radius:999px;background:var(--pn-ac);color:#fff;
            font-size:9px;font-weight:700;line-height:1;padding:2px 5px}

  /* ══ VISTA MES ══
     Las celdas eran cajas redondeadas con borde y las de otro mes mostraban su
     número. En el panel se dibuja con una línea abajo y otra a la derecha, el
     día va en un círculo y las celdas de relleno van VACÍAS. */
  .ag-mes{background:var(--pn-sup);border-radius:var(--pn-r-card);
          box-shadow:var(--pn-sombra);overflow:hidden}
  .ag-mes-dias{display:grid;grid-template-columns:repeat(7,1fr);
               background:var(--pn-sup2);border-bottom:1px solid var(--pn-line)}
  .ag-mes-dias span{padding:7px 0;text-align:center;font-size:11.5px;font-weight:600;
                    color:var(--pn-muted)}
  .ag-mes-grilla{display:grid;grid-template-columns:repeat(7,1fr)}
  .ag-mes-c{min-height:56px;display:flex;flex-direction:column;gap:4px;padding:5px;
            border-bottom:1px solid var(--pn-line);border-right:1px solid var(--pn-line);
            min-width:0}
  .ag-mes-c:nth-child(7n){border-right:0}
  .ag-mes-c:nth-last-child(-n+7){border-bottom:0}
  .ag-mes-c.fuera{background:rgba(242,240,234,.4)}
  .ag-mes-n{display:grid;place-items:center;width:21px;height:21px;border-radius:50%;
            font-size:11.5px;color:var(--pn-ink);font-variant-numeric:tabular-nums}
  .ag-mes-c.hoy .ag-mes-n{background:var(--pn-ac);color:#fff;font-weight:600}
  .ag-mes-b{margin-top:auto;align-self:flex-start;border-radius:999px;padding:1px 7px;
            background:var(--pn-ac-suave);color:var(--pn-ac-fuerte);
            font-size:10.5px;font-weight:500;white-space:nowrap}

  /* ══ VISTA LISTA ══
     La cuarta vista del panel, que acá no estaba. Es la única que dice el
     ESTADO de cada turno con todas las letras; en la grilla es un anillo de 1px. */
  .ag-lst{display:grid;gap:11px}
  .ag-lst-d{background:var(--pn-sup);border-radius:var(--pn-r-card);
            box-shadow:var(--pn-sombra);overflow:hidden}
  .ag-lst-cab{display:flex;align-items:center;gap:8px;padding:7px 13px;
              background:var(--pn-sup2);border-bottom:1px solid var(--pn-line)}
  .ag-lst-hoy{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
              color:var(--pn-ac-fuerte)}
  .ag-lst-f2{font-size:12.5px;font-weight:600;color:var(--pn-ink)}
  .ag-lst-n{margin-left:auto;border-radius:999px;padding:1px 8px;font-size:11px;
            font-weight:500;color:var(--pn-muted);background:rgba(229,226,218,.6)}
  .ag-lst-f{display:flex;align-items:center;gap:10px;padding:8px 13px;font-size:12.5px}
  .ag-lst-f + .ag-lst-f{border-top:1px solid var(--pn-line)}
  .ag-lst-h{width:42px;flex:none;font-family:var(--pn-mono);font-size:11px;
            color:var(--pn-muted);font-variant-numeric:tabular-nums}
  .ag-lst-pt{width:8px;height:8px;border-radius:50%;flex:none}
  .ag-lst-q{font-weight:500;color:var(--pn-ink);overflow:hidden;
            text-overflow:ellipsis;white-space:nowrap}
  .ag-lst-q em{font-style:normal;font-weight:400;font-size:11px;color:var(--pn-faint)}
  .ag-lst-m{margin-left:auto;font-size:11px;color:var(--pn-faint);white-space:nowrap}
  .ag-lst-e{flex:none;border-radius:999px;border:1px solid var(--pn-ac);
            background:var(--pn-ac-suave);color:var(--pn-ac-fuerte);
            font-size:10.5px;font-weight:500;padding:1px 8px;white-space:nowrap}

  /* ══ LAS OTRAS PANTALLAS ══
     El menú navega de verdad. Tarjetas blancas de radio grande con sombra, y
     nada de líneas de 1px. */
  .ag-pant{display:none}
  .ag-pant.on{display:block;animation:agEntra .34s var(--spring)}

  /* la cabecera propia del dashboard: el panel es la única pantalla que tiene
     versalita de fecha, saludo y bajada de pendientes */
  .pn-cab{margin-bottom:16px}
  .pn-eyebrow{font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
              color:var(--pn-faint)}
  .pn-saludo{margin:5px 0 0;font-family:var(--f-s);font-size:22px;font-weight:400;
             letter-spacing:-.02em;line-height:1.2;color:var(--pn-ink)}
  .pn-pend-tx{margin:4px 0 0;font-size:13px;color:var(--pn-muted)}

  /* ── LOS KPI ──
     Eran cuatro, con el rótulo arriba y el número en Fraunces: ésa es la
     tarjeta VIEJA del panel (`ui/Stat.tsx`, que ya no la importa nadie). La
     viva es `KpiCard`: dos, círculo de ícono, número arriba en la sans, rótulo
     abajo, y sin estirarse — es un dato del día, no una fila de cajas. */
  .pn-kpis{display:flex;flex-wrap:wrap;gap:11px}
  .pn-kpi{display:flex;align-items:center;gap:13px;
          background:var(--pn-sup);border-radius:var(--pn-r-card);padding:12px 16px;
          box-shadow:var(--pn-sombra)}
  .pn-kpi-ic{display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
             flex:none;background:var(--pn-ac-suave);color:var(--pn-ac-fuerte)}
  .pn-kpi-ic svg{width:15px;height:15px}
  .pn-kpi-n{font-family:var(--f-s);font-size:22px;font-weight:400;letter-spacing:-.02em;
            line-height:1;color:var(--pn-ink);font-variant-numeric:tabular-nums}
  .pn-kpi-rot{display:block;margin-top:4px;font-size:11.5px;color:var(--pn-muted)}
  .pn-kpi-pie{display:block;font-size:11px;color:var(--pn-faint)}

  /* ── LAS TARJETAS DE LISTA ──
     Sin separador entre filas: se levantan solas al pasar por encima. */
  .pn-cols{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:14px;
           align-items:start}
  .pn-card{background:var(--pn-sup);border-radius:var(--pn-r-card);padding:16px;
           box-shadow:var(--pn-sombra);min-width:0}
  .pn-card-cab{display:flex;align-items:center;gap:8px}
  .pn-card-cab h4{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;
                  color:var(--pn-ink)}
  .pn-card-n{font-size:11.5px;color:var(--pn-faint)}
  .pn-card-sub{margin:3px 0 10px;font-size:11.5px;color:var(--pn-muted)}
  .pn-filas{list-style:none;margin:0 -6px;padding:0;display:grid;gap:1px}
  .pn-f{position:relative;display:flex;align-items:center;gap:9px;padding:7px 6px;
        border-radius:var(--pn-r-ctrl);font-size:12.5px;min-width:0;
        transition:background-color var(--dur-rapida) var(--ease-salida),
                   box-shadow var(--dur-rapida) var(--ease-salida)}
  .pn-f:hover{background:var(--pn-sup);box-shadow:var(--pn-sombra)}
  .pn-f-h{width:40px;flex:none;font-weight:600;color:var(--pn-ac-fuerte);
          font-variant-numeric:tabular-nums}
  .pn-f-q{font-weight:500;color:var(--pn-ink);overflow:hidden;
          text-overflow:ellipsis;white-space:nowrap}
  .pn-f-m{margin-left:auto;font-size:11px;color:var(--pn-faint);white-space:nowrap}
  /* `flex:1` y el corte en las DOS líneas: sin esto la caja de texto se
     estrangulaba contra el botón —que ocupa lugar aunque esté invisible— y el
     nombre salía «Renata Du…» mientras el detalle se abría en tres renglones
     por debajo de la pastilla. */
  /* ⚠ LOS DOS SELECTORES VAN CON `>`: sin el hijo directo, un <b> anidado
     dentro del <i> también se vuelve bloque y se lleva puesta la fila. La fecha
     usa <u> por lo mismo — un gancho que no choca con ninguna de las dos. */
  .pn-f-tx{flex:1;display:grid;gap:1px;min-width:0}
  .pn-f-tx > b,.pn-f-tx > i{display:block;overflow:hidden;text-overflow:ellipsis;
                            white-space:nowrap}
  .pn-f-tx > b{font-size:12.5px;font-weight:500;color:var(--pn-ink)}
  .pn-f-tx > i{font-style:normal;font-size:11px;color:var(--pn-faint)}
  /* la fecha relativa de «Para emitir» va en cobre, que en el panel es el único
     lugar donde el color de marca dice «esto lleva esperando» */
  .pn-f-tx u{text-decoration:none;color:var(--pn-cobre);font-weight:600}
  .pn-tipo{flex:none;font-style:normal;border-radius:999px;padding:2px 7px;
           font-size:9.5px;font-weight:600;line-height:1.3;
           letter-spacing:.02em;text-transform:uppercase;white-space:nowrap}
  /* ⚠ LOS MODIFICADORES VAN CON PREFIJO. Se llamaban `.rx` y `.or` a secas, y
     `.rx` YA EXISTE acá: es el mazo de recetas del acto siguiente, de 940 px de
     ancho. En esta hoja los nombres cortos son de la página, no del componente. */
  .pn-tipo.pn-rx{background:var(--pn-ac-suave);color:var(--pn-ac-fuerte)}
  .pn-tipo.pn-or{background:var(--pn-sup2);color:var(--pn-muted)}
  /* el botón de la fila aparece al pasar por encima, como en el panel */
  /* El botón va ENCIMA de la fila y no en el flujo: en el panel la tarjeta mide
     el doble de ancho; en 340 px, reservarle lugar deja el dato sin ninguno. */
  .pn-acc{position:absolute;right:6px;top:50%;transform:translateY(-50%);
          border:0;border-radius:12px;cursor:pointer;
          background:var(--pn-ac);color:#fff;font:inherit;font-family:var(--f-s);
          font-size:11px;font-weight:600;padding:5px 11px;
          box-shadow:0 2px 10px rgba(33,29,24,.16);
          opacity:0;pointer-events:none;transition:opacity .2s ease}
  .pn-f:hover .pn-acc,.pn-acc:focus-visible{opacity:1;pointer-events:auto}
  .pn-acc:active{transform:translateY(-50%) scale(.965)}
  /* Sin hover no hay «al pasar por encima». En el panel el botón se muestra
     siempre porque HACE algo; acá es una foto, y tapaba la pastilla que dice si
     es receta u orden. En pantalla táctil manda el dato. */
  @media (hover:none){ .pn-acc{display:none} }

  /* HISTORIAL de llamadas y listas sueltas */
  .pn-dash,.pn-lista,.pn-pac,.pn-wa,.pn-band{padding:0}
  .pn-lista{display:grid;gap:6px}
  .pn-fila{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;
           background:var(--pn-sup);border-radius:var(--pn-r-ctrl);padding:10px 13px;
           transition:transform .18s ease,box-shadow .18s ease}
  .pn-fila:hover{transform:translateY(-1px);box-shadow:var(--pn-sombra-alta)}
  .pn-av{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;flex:none;
         background:var(--pn-sup2);color:var(--pn-muted);font-size:11.5px;font-weight:700}
  .pn-av-g{width:40px;height:40px;font-size:15px}
  .pn-fila-tx{display:grid;gap:1px;min-width:0}
  .pn-fila-tx b{font-size:13px;color:var(--pn-ink);font-weight:600}
  .pn-fila-tx i{font-style:normal;font-size:11px;color:var(--pn-muted)}
  .pn-tags{display:flex;align-items:center;gap:9px}
  .pn-tag{font-style:normal;font-size:10px;font-weight:600;border-radius:999px;padding:2px 8px;
          background:var(--pn-sup2);color:var(--pn-muted)}
  .pn-hora{font-style:normal;font-size:11px;color:var(--pn-faint);
           font-family:var(--pn-mono);white-space:nowrap}

  /* PACIENTES: lista + ficha 360 */
  .pn-pac{display:grid;grid-template-columns:180px 1fr;gap:12px}
  .pn-pac-lista{display:grid;gap:3px;align-content:start}
  .pn-pac-item{display:flex;align-items:center;gap:9px;padding:6px 8px;
               border-radius:var(--pn-r-ctrl);
               font-size:12.5px;color:var(--pn-muted);cursor:pointer;
               transition:background-color .18s ease,box-shadow .18s ease}
  .pn-pac-item .pn-av{width:24px;height:24px;font-size:10px}
  .pn-pac-item:hover{background:rgba(255,255,255,.7)}
  .pn-pac-item.on{background:var(--pn-sup);color:var(--pn-ink);font-weight:600;
                  box-shadow:var(--pn-sombra)}
  .pn-ficha{background:var(--pn-sup);border-radius:var(--pn-r-card);padding:16px;
            box-shadow:var(--pn-sombra);min-width:0}
  .pn-ficha-cab{display:flex;align-items:center;gap:12px}
  .pn-ficha-cab b{display:block;font-size:15px;font-weight:600;color:var(--pn-ink)}
  .pn-ficha-cab i{font-style:normal;font-size:11.5px;color:var(--pn-muted)}
  /* la alerta de alergia es lo primero que se ve de un paciente, y es roja */
  .pn-alerta{margin-top:12px;background:rgba(194,53,42,.10);color:#8f2c22;
             border-radius:var(--pn-r-ctrl);padding:8px 12px;font-size:12px;font-weight:600}
  .pn-alerta::before{content:'\26A0  ';opacity:.8}
  .pn-tabs{display:flex;gap:16px;margin-top:14px;border-bottom:1px solid var(--pn-line);
           padding-bottom:7px}
  .pn-tabs em{font-style:normal;font-size:12px;color:var(--pn-muted)}
  .pn-tabs em.on{color:var(--pn-ac-fuerte);font-weight:600}
  .pn-evo{margin-top:12px;display:grid;gap:3px}
  .pn-evo b{font-size:11.5px;color:var(--pn-ac-fuerte)}
  .pn-evo span{font-size:12.5px;line-height:1.45;color:var(--pn-ink)}
  .pn-evo.tenue b{color:var(--pn-faint)}
  .pn-evo.tenue span{color:var(--pn-muted)}

  /* WHATSAPP: adentro manda la marca de WhatsApp, no la de Aira */
  .pn-wa-cab{display:flex;align-items:center;gap:11px;padding-bottom:12px}
  .pn-wa-cab b{display:block;font-size:13px;font-weight:600;color:var(--pn-ink)}
  .pn-wa-cab i{font-style:normal;font-size:11px;color:var(--pn-muted)}
  .pn-av-wa{background:#d9fdd3;color:#1a6b3c}
  .pn-wa-est{margin-left:auto;font-style:normal;font-size:10.5px;font-weight:600;
             border-radius:999px;padding:3px 10px;background:#e7f8e9;color:#1a6b3c}
  .pn-wa-chat{background:#efeae2;border-radius:var(--pn-r-card);padding:14px;
              display:grid;gap:8px;min-height:250px;align-content:start}
  .pn-msg{position:relative;max-width:74%;padding:7px 11px 16px;border-radius:9px;
          font-size:12.5px;line-height:1.4;color:#111b21;
          box-shadow:0 1px 1px rgba(11,20,26,.13)}
  .pn-msg-h{position:absolute;right:9px;bottom:4px;font-style:normal;font-size:9.5px;
            color:rgba(17,27,33,.45)}
  .pn-wa-pie{margin-top:10px;font-size:11.5px;color:var(--pn-muted);text-align:center}

  /* la hora en que entró la llamada NO es del panel —el turno muestra hora y
     paciente, nada más—: es lo que cuenta la historia, y por eso va afuera de
     la ventana, en el pie */
  .ag-pie{margin:28px auto 0;font-size:15px;color:var(--dia-suave)}
  .ag-pie b{font-weight:600;color:var(--cobre-hondo);font-variant-numeric:tabular-nums}

  /* ══ EL PANEL EN UN TELÉFONO ══
     El menú se escondía con `display:none` y con él se iban las otras cinco
     pantallas: en un teléfono la ventana era la agenda y nada más — justo donde
     la mayoría ve esta página. Se resuelve como lo resuelve el panel: la barra
     lateral pasa a ser un CAJÓN con su velo. Es la misma pieza, no un invento. */
  @media (max-width:760px){
    #agenda{padding-bottom:72px}
    .ag-escena{perspective:none;margin-top:32px}
    /* en vertical el 3D no aporta y le come legibilidad a una pantalla chica */
    .ag-ventana{transform:none;box-shadow:0 14px 34px rgba(20,32,42,.12)}
    .ag-top{height:44px;padding:0 10px;gap:9px}
    .ag-buscar{display:none}
    .ag-yo-tx{display:none}
    .ag-ham{display:grid;place-items:center;width:30px;height:30px;flex:none;
            border:0;border-radius:9px;background:transparent;color:var(--pn-muted);
            cursor:pointer;padding:0}
    .ag-ham svg{width:18px;height:18px}
    .ag-cuerpo{grid-template-columns:1fr;min-height:0}
    /* el cajón: fuera de pantalla, blanco (no mate) y con sombra, como el panel */
    .ag-menu{position:absolute;left:0;top:0;bottom:0;z-index:6;width:230px;
             background:var(--pn-sup);box-shadow:0 20px 25px -5px rgba(0,0,0,.1),
                                                  0 8px 10px -6px rgba(0,0,0,.1);
             transform:translateX(-100%);visibility:hidden;
             transition:transform var(--dur-base) var(--ease-salida),visibility var(--dur-base)}
    .ag-menu.abierto{transform:none;visibility:visible}
    .ag-menu-cab{border-bottom:1px solid var(--pn-line);padding-bottom:9px}
    .ag-cerrar{display:grid;place-items:center;width:28px;height:28px;flex:none;
               border:0;border-radius:9px;background:transparent;color:var(--pn-muted);
               cursor:pointer;padding:0}
    .ag-cerrar svg{width:16px;height:16px}
    .ag-item:hover{background:var(--pn-sup2);transform:none}
    .ag-velo{display:block;position:absolute;inset:0;z-index:5;background:rgba(0,0,0,.4);
             opacity:0;visibility:hidden;
             transition:opacity var(--dur-rapida) ease,visibility var(--dur-rapida)}
    .ag-velo.on{opacity:1;visibility:visible}

    .ag-panel{padding:13px 13px 16px}
    .ag-cab{flex-direction:column;align-items:stretch;gap:10px;margin-bottom:11px}
    .ag-dia{font-size:19px}
    .ag-vistas{align-self:flex-start}
    .ag-v{padding:0 9px;font-size:11px;height:25px}
    .ag-fecha{gap:6px;flex-wrap:wrap}
    .ag-cuando{font-size:11.5px}
    .ag-cont{font-size:11px;padding:2px 8px}
    /* la canaleta se achica pero los rótulos siguen cada media hora */
    .ag-grilla{grid-template-columns:42px 1fr}
    .ag-horas span{font-size:9px;right:5px}
    .ag-med{font-size:11.5px}
    .ag-fila{left:2px;right:2px;padding:2px 5px;font-size:10.5px}
    .ag-hora{font-size:9.5px}
    /* SEMANA a 390: siete columnas de 44px no aguantan un nombre, así que el
       turno pasa a ser una BANDA DE COLOR con su hora, que es lo que el panel
       muestra cuando la columna se angosta. El nombre vive en la vista Lista,
       que es la que el panel ofrece justamente para esto. */
    .ag-sem{--ag-cab-h:40px;grid-template-columns:30px 1fr}
    .ag-sem-et{font-size:8px;letter-spacing:.04em}
    .ag-sem-n{font-size:11px;gap:2px}
    .ag-sem-b{font-size:8px;padding:1px 4px}
    .ag-sem .ag-fila{left:1px;right:1px;padding:1px 3px;font-size:9px}
    .ag-sem .ag-quien{display:none}
    /* MES a 390: la celda mide 47px y «3 turnos» pide 44 — quedaba pisando el
       borde. Va el número pelado, que es la pastilla que el panel usa en el
       encabezado de la semana. */
    .ag-mes-c{min-height:44px;padding:4px;gap:2px}
    .ag-mes-dias span{font-size:10px;padding:5px 0}
    .ag-mes-n{width:18px;height:18px;font-size:10.5px}
    .ag-mes-b{padding:0 5px;font-size:9.5px}
    .ag-mes-b span{display:none}
    .ag-lst-f{gap:8px;padding:7px 10px;font-size:12px}
    .ag-lst-m{display:none}
    .ag-lst-h{width:36px;font-size:10.5px}

    .pn-kpis{gap:9px}
    .pn-kpi{flex:1 1 100%;padding:11px 13px}
    .pn-cols{grid-template-columns:1fr;gap:11px;margin-top:11px}
    .pn-pac{grid-template-columns:1fr}
    .pn-pac-lista{display:flex;overflow-x:auto;scrollbar-width:none}
    .pn-pac-lista::-webkit-scrollbar{display:none}
    .pn-pac-item{flex:none}
    .pn-msg{max-width:86%}
    .ag-pie{font-size:13.5px;padding:0 6px}
  }
  @media (prefers-reduced-motion: reduce){
    .ag-fila{transition:none;opacity:1;transform:none}
    .ag-ventana{transform:none}
    .ag-menu{transition:none}
    .ag-velo{transition:none}
  }

  /* ══ LAS COSTURAS ══
     Una sección que termina y otra que empieza es un filo: el borde se ve, y
     la página se lee como una lista de bloques en vez de como una sola cosa.
     Donde cambia el fondo, el cambio se PINTA — nunca se corta.

     Regla de los stops: cuando el viaje es de día a noche (o al revés) los
     intermedios no son grises, bajan por el azul. Un degradé directo entre el
     hueso y el negro pasa por un gris sucio que se lee como una banda gris
     puesta a propósito, que es exactamente lo que se quería evitar.

     Las tres costuras de la página, con su lógica:
       · del split a la noche      → #mientras::after (acá abajo)
       · de la noche al día        → #escuchar::after (con la sección)
       · del hueso al día del cierre → #cuenta::before
     La cuarta, la del cierre, ya vivía con #cierre y usa el mismo idioma. */
  /* del día de la agenda al hueso de la receta: dos claros distintos que se
     tocaban sin nada en el medio, y el ojo lee ese borde igual que uno duro */
  #escrito::before{
    content:'';position:absolute;left:0;right:0;top:0;height:120px;z-index:0;
    pointer-events:none;
    background:linear-gradient(180deg, var(--dia-fondo), rgba(221,229,234,0));
  }
  #escrito > *{position:relative;z-index:1}

  /* La costura de entrada de #cuenta y su `position:relative` viven abajo, con
     el acto 4: desde que la sección es la noche entera, el degradé va del hueso
     de la receta al NEGRO y no al día. El que había acá lo pisaba entero. */
  #cuenta > *{position:relative;z-index:1}

  /* ══ ESCUCHÁ CÓMO ATIENDE — el flashback ══
     Las cinco llamadas son de noche, así que la sección vuelve a la noche: es la
     única que muestra lo que pasó mientras no había nadie. Placa general del
     hero, otro encuadre. Acá el texto va claro, no con los tokens del día. */
  /* Era de noche y venía más abajo. Subió pegada al hero —es la prueba, y lo
     primero que un médico quiere es oírla— y con eso pasó al día: quedar de
     noche justo después del amanecer contradecía la película, que acababa de
     encender la luz. Las llamadas siguen siendo nocturnas y eso lo dicen las
     horas, no el fondo. */
  #escuchar{background:var(--dia-fondo);padding:0;position:relative}
  /* #escuchar no tiene padding lateral, así que acá alcanza con el ancho
     normal: nada de 100vw, que se pasa lo que mide la barra de scroll. */
  /* sin foto: la sala pintada. El degradé pone la luz del teléfono donde estaba
     en la placa —arriba a la derecha— así que sigue siendo el mismo lugar sin
     repetir la imagen. */
  /* El plano es de día. El fondo lleva un resto de la luz del teléfono arriba
     a la derecha —donde estaba en la escena— para que se siga sintiendo el
     mismo lugar sin volver a apagar la luz que el amanecer acaba de encender. */
  .ec{position:relative;min-height:0;padding:78px 5vw 84px;
      display:flex;flex-direction:column;justify-content:center;overflow:hidden;
      background:
        radial-gradient(72% 60% at 78% 12%, rgba(var(--cielo-rgb),.10), transparent 62%),
        var(--dia-fondo)}
  .ec-tit{position:relative;z-index:2;text-align:left;max-width:1080px;
          margin:0 auto 30px;width:100%}
  #escuchar .s-tit{color:var(--dia-tinta);margin:0}
  #escuchar .s-sub{color:var(--dia-suave);margin-top:12px}

  .esc-wrap{position:relative;z-index:2;max-width:1080px;margin:0 auto;width:100%;
            display:grid;grid-template-columns:250px 1fr 210px;gap:26px;
            text-align:left;align-items:start}

  /* la lista: renglones sobre la foto, sin marco */
  .esc-list{list-style:none;display:flex;flex-direction:column}
  .esc-btn{width:100%;display:flex;align-items:center;gap:10px;padding:12px 10px;
           border:0;border-bottom:1px solid rgba(20,32,42,.14);border-radius:0;
           box-shadow:inset 2px 0 0 transparent;background:transparent;
           color:var(--dia-suave);font:inherit;font-size:14.5px;cursor:pointer;
           transition:background .2s ease, color .2s ease, box-shadow .2s ease}
  .esc-btn:hover{background:rgba(var(--cielo-rgb),.07);color:var(--dia-tinta)}
  .esc-item.sel .esc-btn{color:var(--cielo);box-shadow:inset 2px 0 0 var(--cielo)}
  .esc-play-ic{color:var(--cielo);flex:none}

  .esc-play{border:0;background:none;padding:0;min-height:250px}
  .esc-cab{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--dia-suave)}
  .esc-punto{width:7px;height:7px;border-radius:50%;background:rgba(20,32,42,.22)}
  .esc-punto.vivo{background:var(--cielo);animation:escLatir 1.4s ease-in-out infinite}
  @keyframes escLatir{0%,100%{opacity:1}50%{opacity:.35}}
  .esc-reloj{margin-left:auto;font-variant-numeric:tabular-nums}
  /* la onda es lo más grande de la sección: es una llamada, y lo que hay para
     ver es la voz */
  /* La onda acompaña, no manda: el avance ahora lo cuenta la barra. Pegada
     abajo de los controles y tenue, dice «hay una voz sonando» y nada más. */
  .esc-wave{display:block;width:100%;height:26px;margin:-4px 0 16px;opacity:.72}
  .esc-agenda{border:0;border-left:1px solid var(--dia-linea);border-radius:0;
              padding:2px 0 2px 20px;background:none}
  .esc-ag-tit{font-size:11px;letter-spacing:.06em;text-transform:uppercase;
              color:var(--dia-suave)}
  .esc-turno{margin-top:12px;display:flex;flex-direction:column;gap:3px}
  .esc-turno.entra{animation:escSalto .42s cubic-bezier(.2,1.6,.4,1)}
  @keyframes escSalto{from{transform:translateY(6px);opacity:0}to{transform:none;opacity:1}}
  .esc-hora{font-family:'Fraunces',serif;font-size:25px;color:var(--cielo)}
  .esc-nom{font-size:13.5px;color:var(--dia-suave)}
  .esc-ag-vacio{margin-top:10px;font-size:12.5px;color:var(--dia-suave)}

  /* ── EL FANTASMA DEL RACCORD ──
     Nace como lo que es en la agenda de la llamada —tipografía grande, sin
     caja— y aterriza como lo que es en el panel: un bloque chico de color. O
     sea que la caja no lo acompaña: CRECE alrededor del texto mientras el texto
     se achica. Por eso el fondo, el borde y el padding cuelgan de `--k` igual
     que el tamaño.
     Las medidas (width/height/transform) las escribe el JS, porque salen de los
     dos rectángulos reales. Acá viven sólo la piel y la tipografía. */
  .rc-ghost{
    position:fixed;left:0;top:0;z-index:60;display:none;pointer-events:none;
    box-sizing:border-box;overflow:hidden;
    flex-direction:column;justify-content:center;gap:calc(3px - 1px * var(--k,0));
    padding:0 calc(var(--k,0) * 9px);
    border-radius:calc(var(--k,0) * 7px);
    background:rgba(236,253,245,var(--k,0));
    box-shadow:0 0 0 1px rgba(9,86,75,calc(var(--k,0) * .10));
    /* el fantasma no puede ensuciar el layout de la página: es fixed, tiene
       medida propia y nada de afuera depende de él */
    contain:layout paint;
    will-change:transform,width,height;
  }
  .rc-ghost.vuela{display:flex}
  /* el color viaja del cielo de la marca al verde del turno del panel */
  .rc-h{
    font-family:'Fraunces',serif;
    font-size:calc(25px - 14.5px * var(--k,0));
    line-height:1;font-variant-numeric:tabular-nums;
    color:rgb(calc(51 - 42 * var(--k,0)) calc(112 - 26 * var(--k,0)) calc(143 - 68 * var(--k,0)));
    opacity:calc(1 - var(--k,0) * .25);
  }
  .rc-n{
    font-size:calc(13.5px - 2px * var(--k,0));
    line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
    font-weight:calc(400 + 200 * var(--k,0));
    color:rgb(calc(20 + -11 * var(--k,0)) calc(32 + 54 * var(--k,0)) calc(42 + 33 * var(--k,0)) / calc(.66 + .34 * var(--k,0)));
  }

  @media (max-width: 900px){
    .esc-wrap{grid-template-columns:1fr}
    .esc-agenda{border-left:0;border-top:1px solid var(--dia-linea);padding:18px 0 2px}
    .ec{min-height:0;padding:56px 5vw 62px}
  }
  @media (prefers-reduced-motion: reduce){
    .esc-punto.vivo{animation:none}
    .esc-turno.entra{animation:none}
  }

  /* ── LOS CONTROLES DE LA LLAMADA ──
     Antes la llamada arrancaba sola y no había cómo pararla, saltarla ni
     bajarla. Ahora hay play/pausa, una barra que es la conversación y volumen.
     La barra no es lisa: cada tramo es un TURNO DE HABLA, los de Aira más
     claros que los del paciente, así se ve la ida y vuelta antes de escucharla
     y se puede saltar a cualquiera. */
  .esc-ctrl{display:flex;align-items:center;gap:14px;margin:14px 0 12px}
  .esc-pp{width:42px;height:42px;flex:none;border-radius:50%;border:0;cursor:pointer;
          display:grid;place-items:center;background:var(--cielo);color:#fff;
          transition:transform .18s ease,background-color .25s ease,box-shadow .25s ease;
          box-shadow:0 6px 18px rgba(var(--cielo-rgb),.35)}
  .esc-pp:hover{transform:scale(1.06);background:var(--cielo-vivo)}
  .esc-pp:active{transform:scale(.97)}
  .esc-pp .ic-pause{display:none}
  .esc-pp.son .ic-play{display:none}
  .esc-pp.son .ic-pause{display:block}

  .esc-barra{flex:1;display:flex;gap:3px;height:26px;align-items:center;cursor:pointer;
             min-width:0}
  .esc-barra:focus-visible{outline:2px solid var(--cielo);outline-offset:4px;border-radius:6px}
  .esc-tramo{position:relative;height:7px;border-radius:4px;overflow:hidden;
             background:rgba(20,32,42,.12);transition:height .2s ease,background-color .2s ease}
  .esc-tramo.de-aira{background:rgba(var(--cielo-rgb),.20)}
  .esc-barra:hover .esc-tramo{height:10px}
  .esc-tramo.en{height:12px}
  .esc-tramo b{position:absolute;inset:0;transform-origin:left;transform:scaleX(0);
               background:var(--cielo);border-radius:4px}
  .esc-tramo.de-aira b{background:var(--cobre)}

  .esc-vol{display:flex;align-items:center;gap:7px;flex:none}
  .esc-mute{width:30px;height:30px;border:0;border-radius:9px;cursor:pointer;display:grid;
            place-items:center;background:transparent;color:var(--dia-suave);
            transition:color .2s ease,background-color .2s ease}
  .esc-mute:hover{color:var(--dia-tinta);background:rgba(20,32,42,.06)}
  .esc-mute .ic-mudo{display:none}
  .esc-mute.mudo .ic-son{display:none}
  .esc-mute.mudo .ic-mudo{display:block}
  .esc-vol-r{width:78px;accent-color:var(--cielo);cursor:pointer}

  /* ── LA TRANSCRIPCIÓN, SIN CAJA ──
     Estaba en un rectángulo de 90 px con scroll: el alto saltaba línea por
     línea y había que arrastrar para leer lo que ya había pasado. Ahora se
     siembra entera y apagada —el alto es el mismo desde el principio— y se
     enciende a medida que suena. De paso se ve de qué va la charla antes de
     darle play. */
  .esc-cron{list-style:none;margin:0;padding:0;display:grid;gap:9px}
  .esc-cron .l{display:grid;grid-template-columns:64px 1fr;gap:12px;align-items:baseline;
               opacity:.34;transition:opacity .45s ease,transform .45s var(--spring);
               transform:translateY(2px)}
  .esc-cron .l.dicha{opacity:.6;transform:none}
  .esc-cron .l.ahora{opacity:1;transform:none}
  .esc-cron .rol{font-size:10px;letter-spacing:.14em;text-transform:uppercase;
                 color:var(--dia-suave);text-align:right}
  .esc-cron .l.aira .rol{color:var(--cielo)}
  .esc-cron .tx{font-size:14.5px;line-height:1.5;color:var(--dia-tinta)}
  .esc-cron .l.ahora .tx{color:var(--dia-tinta);font-weight:500}
  /* el renglón que suena se marca con una línea de luz a la izquierda */
  .esc-cron .l.ahora .rol{position:relative}
  .esc-cron .l.ahora .rol::after{content:'';position:absolute;right:-7px;top:1px;bottom:1px;
                                 width:2px;border-radius:2px;background:var(--cielo)}

  @media (max-width:760px){
    .esc-ctrl{gap:10px}
    .esc-vol-r{width:54px}
    .esc-cron .l{grid-template-columns:52px 1fr;gap:9px}
    .esc-cron .tx{font-size:13.5px}
  }
  @media (prefers-reduced-motion: reduce){
    .esc-cron .l,.esc-tramo,.esc-pp{transition:none}
  }

  /* ══ ACTO 3b — LO QUE QUEDA ESCRITO ══
     Papel sobre el día: el único plano de la página que no es ni foto ni
     pantalla, y de eso vive.
     Es un mazo que GIRA. Un documento contaba un solo feature; girando entran
     los cuatro que quedan después de una consulta —receta, orden, indicaciones
     y el resumen de la llamada— sin sumar una sección más a la página. El giro
     es sobre el eje Y con el mazo en perspectiva: la hoja que sale se va por su
     canto y la que entra llega por el otro, como pasar una hoja de verdad. */
  #escrito{background:var(--dia-hueso);padding:74px 24px 84px;text-align:center;
           position:relative;overflow:hidden}
  .rx{display:flex;gap:40px;align-items:center;justify-content:center;
      width:min(940px,100%);margin:40px auto 0;text-align:left;flex-wrap:wrap}

  /* el mazo: alto fijo para que cambiar de hoja no mueva la página */
  .rx-mazo{position:relative;flex:1 1 420px;max-width:452px;height:530px;
           perspective:1500px;perspective-origin:50% 50%}
  /* una hoja tiene canto: sin borde, sobre un fondo claro, el papel flotaba
     como un rectángulo blanco sin empezar ni terminar en ningún lado */
  .rx-hoja{position:absolute;inset:0;background:#fff;border:1px solid #d7dde3;
           border-radius:3px;padding:30px 32px;
           display:flex;flex-direction:column;
           box-shadow:0 20px 44px rgba(20,32,42,.12);
           transform-origin:50% 50%;backface-visibility:hidden;
           opacity:0;pointer-events:none;
           transform:rotateY(38deg) translateZ(-90px) scale(.94);
           transition:transform .62s var(--spring), opacity .42s ease}
  /* la que está a la vista */
  .rx-hoja.on{opacity:1;pointer-events:auto;transform:rotateY(0) translateZ(0) scale(1)}
  /* la que se acaba de ir: sale por su canto, del lado contrario al que entran */
  .rx-hoja.sale{opacity:0;transform:rotateY(-38deg) translateZ(-90px) scale(.94)}

  /* ── EL DOCUMENTO ──
     Copia del que emite el producto (components/recetas/RecetaDocument.tsx):
     membrete de la CLÍNICA —la receta es del médico, no de Aira—, el ℞, los
     datos obligatorios de ReNaPDiS, la cantidad también en letras y el pie de
     validación con su leyenda textual. Tipografía de sistema y no la de la
     marca: un documento regulado se lee como un documento, no como una pieza
     de diseño. */
  .rx-hoja{font-family:var(--f-s);color:#1e293b}

  /* la marca de agua del borrador, que se va al firmar */
  .rx-agua{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;
           font-size:64px;font-weight:900;letter-spacing:.14em;color:rgba(20,32,42,.055);
           transform:rotate(-24deg);transition:opacity .6s ease;z-index:0}
  .rx.firmada .rx-hoja[data-doc="receta"] .rx-agua{opacity:0}
  .rx-hoja > *:not(.rx-agua){position:relative;z-index:1}

  .rx-mem{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;
          padding-bottom:11px;border-bottom:1px solid #cbd5e1}
  .rx-mem b{display:block;font-family:'Fraunces',serif;font-size:21px;font-weight:400;
            color:#0f172a;line-height:1.2}
  .rx-mem i{display:block;font-style:normal;font-size:11.5px;color:#64748b;margin-top:3px}
  .rx-mem-der{text-align:right;flex:none}
  .rx-mem-der em{display:block;font-style:normal;font-size:9.5px;font-weight:700;
                 letter-spacing:.12em;text-transform:uppercase;color:var(--cielo)}

  .rx-linea{display:flex;justify-content:space-between;gap:12px;margin-top:18px;font-size:15px}
  .rx-linea span{display:block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#94a3b8}
  .rx-linea b{font-weight:600;color:#0f172a}
  .rx-datos{margin:4px 0 0;font-size:10.5px;color:#64748b;line-height:1.5}

  /* el ℞ es la marca visual de una receta: sin él, esto es una tarjeta */
  .rx-rp{margin-top:14px;flex:1}
  .rx-rp-s{display:block;font-family:'Fraunces',serif;font-size:30px;line-height:1;
           color:#0f172a;border-bottom:1px solid #e2e8f0;padding-bottom:5px}
  .rx-rp-lab{font-size:15px;letter-spacing:.14em;text-transform:uppercase;color:#64748b}
  .rx-items{list-style:none;margin:11px 0 0;padding:0;display:grid;gap:9px}
  .rx-items li{display:flex;gap:8px;padding-bottom:8px;border-bottom:1px dashed #e2e8f0}
  .rx-items li:last-child{border-bottom:0}
  .rx-n{color:var(--cielo);font-weight:600;font-size:13px;flex:none}
  .rx-item-p{margin:0;font-size:16px;font-weight:600;color:#0f172a}
  /* la cantidad también en letras: control anti-adulteración del recetario */
  .rx-item-d{margin:4px 0 0;font-size:14px;color:#334155}

  /* indicaciones: no es un documento regulado, así que no finge serlo */
  .rx-ind{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:11px;flex:1}
  .rx-ind li{display:grid;grid-template-columns:56px 1fr;gap:11px;align-items:baseline;
             padding-bottom:9px;border-bottom:1px dashed #e2e8f0}
  .rx-ind li:last-child{border-bottom:0}
  .rx-ind b{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--cielo)}
  .rx-ind span{font-size:12.5px;line-height:1.45;color:#334155}

  .rx-charla{margin-top:13px;display:grid;gap:8px;flex:1;align-content:start}
  .rx-charla p{margin:0;font-size:12.5px;line-height:1.45;color:#334155;
               display:grid;grid-template-columns:58px 1fr;gap:10px}
  .rx-charla i{font-style:normal;font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
               color:#94a3b8;text-align:right}
  .rx-charla .de-aira{color:#0f172a}
  .rx-charla .de-aira i{color:var(--cielo)}

  /* ── el pie: firma y validación ──
     El reset es necesario: el pie de la hoja es un <footer> y el <footer> DE LA
     PÁGINA está estilado por elemento (flex, con su padding y su fondo), así
     que se lo comía —el bloque de validación quedaba de 50px de ancho y el
     texto se apilaba letra por letra. */
  .rx-hoja footer{display:block;background:none;padding:0;margin:0;border:0;
                  gap:0;justify-content:initial;align-items:initial;font-size:inherit}
  .rx-pie{margin-top:12px;padding-top:11px;border-top:1px solid #cbd5e1}
  .rx-firmada{margin:0;font-size:13px;color:#0f172a}
  .rx-firmada b{font-weight:600}
  .rx-prof{margin:2px 0 0;font-size:12px;color:#475569}
  .rx-val{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
          margin-top:10px;padding-top:9px;border-top:1px solid #e2e8f0}
  .rx-val-tx{min-width:0;display:grid;gap:1px}
  /* 11,5px era letra chica de verdad, y esto NO es letra chica decorativa: es
     lo que sostiene la promesa legal de la receta —quién la firma y cómo se
     verifica—, o sea lo que un médico lee para creernos. Va a 12,5. */
  .rx-val-tx p{margin:0;font-size:12.5px;color:#5b6b7d;line-height:1.5}
  .rx-ley{padding-top:5px}
  .rx-qr{flex:none;color:#0f172a;opacity:0;transform:scale(.9);
         transition:opacity .5s ease,transform .5s var(--spring)}
  .rx.firmada .rx-hoja[data-doc="receta"] .rx-qr,
  .rx-hoja[data-doc="orden"] .rx-qr{opacity:1;transform:none}

  /* ── el costado: qué documento se mira y qué garantiza ── */
  .rx-lado{flex:1 1 280px;max-width:330px;display:grid;gap:18px;align-content:center}
  .rx-tabs{display:flex;flex-wrap:wrap;gap:7px}
  .rx-tab{font:inherit;font-size:12.5px;padding:7px 14px;border-radius:999px;cursor:pointer;
          border:1px solid var(--dia-linea);background:transparent;color:var(--dia-suave);
          transition:background-color .25s ease,color .25s ease,border-color .25s ease,transform .18s ease}
  .rx-tab:hover{color:var(--dia-tinta);border-color:rgba(var(--cielo-rgb),.4)}
  .rx-tab:active{transform:translateY(1px)}
  .rx-tab.on{background:var(--cielo);border-color:var(--cielo);color:#fff;font-weight:500}
  .rx-tab:focus-visible{outline:2px solid var(--cielo);outline-offset:3px}

  .rx-sellos{list-style:none;margin:0;padding:0;display:grid;gap:13px;min-height:104px}
  .rx-sellos li{font-size:14px;line-height:1.45;color:var(--dia-suave);
                padding-left:16px;border-left:2px solid rgba(var(--cielo-rgb),.35);
                animation:rxSello .45s var(--spring) backwards}
  .rx-sellos li:nth-child(2){animation-delay:.06s}
  .rx-sellos li:nth-child(3){animation-delay:.12s}
  .rx-sellos b{color:var(--dia-tinta);font-weight:600}
  @keyframes rxSello{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}

  @media (max-width:760px){
    .rx{gap:26px}
    .rx-mazo{max-width:none;height:520px;perspective:none}
    /* sin perspectiva el giro se lee mal en una pantalla angosta: se cruza con
       un desplazamiento lateral, que cuenta lo mismo y no cuesta nada */
    .rx-hoja{transform:translateX(26px) scale(.98);padding:18px 16px}
    .rx-hoja.on{transform:none}
    .rx-hoja.sale{transform:translateX(-26px) scale(.98)}
    .rx-lado{max-width:none}
  }
  @media (prefers-reduced-motion: reduce){
    .rx-hoja{transition:opacity .3s ease}
    .rx-hoja,.rx-hoja.sale{transform:none}
    .rx-sellos li{animation:none}
  }

  /* ══ ACTO 4 — LA CUENTA ══
     Sin foto y sin caja: número grande y tipografía. Es el respiro visual antes
     del precio —viene de un documento y de tres interfaces— y el único plano
     donde el visitante toca algo. */
  /* El CSS de los tres números que había acá —#cuenta, .ct, .ct-n, .ct-cierre,
     y su media query— se fue con ellos: era mil doscientos bytes de estilos que
     no usaba nadie, y el presupuesto de peso de esta página no tiene lugar para
     código muerto. Si hay que volver atrás, `git revert` del commit «el acto 4
     deja de ser tres números» lo trae todo junto, que es más seguro que
     reconstruirlo a mano. */

  /* ══ ACTO 4 · LOS HILOS — INICIO ══
     Para sacarlo se borra hasta la marca FIN; el resto está en `noche.js`. El
     CSS de los tres números (.ct, .ct-n, .ct-cierre) quedó sin tocar, justo
     para que volver sea cambiar el HTML y nada más.
     El alto ES la noche, y 360vh y no más: cada pantalla acá es una que el
     visitante recorre antes de llegar al precio. */
  /* El color lo lleva LA SECCIÓN y no un hijo: si lo pinta `.nq-fondo`,
     cualquiera que pregunte de qué color es #cuenta —la barra, un chequeo—
     recibe el del día. `qa-nav` lo cantó al primer intento. */
  #cuenta {
    height: 360vh; padding: 0; text-align: left; position: relative;
    background: var(--plano, var(--noche));
  }
  /* La costura de entrada va del hueso de la receta a la noche, por los azules
     del anochecer: un oscuro con alfa sobre fondo claro pasa por todos los
     grises.
     ⚠ Y TERMINA EN `--alba-0`, NO EN `--noche`, Y LOS DOS ÚLTIMOS STOPS SE VAN
     EN ALFA. Terminaba en el negro de la marca mientras el acto arrancaba once
     puntos de azul más arriba: en el píxel donde se tocaban había un salto de
     44 puntos —medido— o sea una línea. Aterrizando en el mismo color con el
     que el acto empieza, el aterrizaje deja de existir; y bajando el alfa en
     los últimos 18 px, el resplandor de cobre del acto (que vive en la capa de
     abajo) no se enciende de golpe: entra atravesando la costura. */
  #cuenta::before {
    content: ''; position: absolute; left: 0; right: 0; top: 0;
    height: var(--costura); z-index: 2; pointer-events: none;
    background: linear-gradient(to bottom,
      var(--dia-hueso) 0%, rgb(200,215,226) 14%, rgb(150,178,197) 30%,
      rgb(96,128,153) 48%, rgb(52,76,100) 64%, rgb(28,44,60) 78%,
      rgb(17,25,32) 88%,
      rgb(var(--alba-0)) 93%,
      rgba(var(--alba-0),0) 100%);
  }
  /* Con el ID y no `.nq-pega` a secas: `#cuenta > *{position:relative}` —que
     quedó para poder volver atrás— le ganaba y le pisaba el sticky. Daba una
     pantalla en blanco de tres mil píxeles. */
  #cuenta > .nq-pega {
    position: sticky; top: 0; height: 100vh; overflow: hidden;
    /* el tope sale de `--barra-h`, el mismo token del que cuelgan el reloj del
       hero y el pie: sin eso el reloj nacía DEBAJO de la barra y se leía medio
       número. Si algo tiene que alinearse con la barra, sale de ahí. */
    padding: calc(var(--barra-h) + 14px) clamp(18px, 4vw, 60px) clamp(18px, 3.4vh, 34px);
    display: grid; grid-template-rows: auto 1fr auto; gap: clamp(8px, 1.6vh, 18px);
  }
  /* El color va PLANO y no en degradé vertical: con un degradé, en plena
     transición la pantalla tiene el cielo claro arriba y la noche abajo a la
     vez, y ningún cruce de tinta puede servir. Medido: 1.09:1. */
  /* ya no pinta el color: sólo el resplandor del alba y la viñeta */
  .nq-fondo { position: absolute; inset: 0; z-index: 0; }
  .nq-fondo::after {
    content: ""; position: absolute; inset: 0;
    background:
      radial-gradient(120% 60% at 10% 106%, rgba(var(--cobre-rgb),.24), rgba(var(--cobre-rgb),0) 62%),
      linear-gradient(to bottom, rgba(255,255,255,.07), rgba(0,0,0,0) 44%, rgba(0,0,0,.05));
    /* la viñeta se APAGA con el día: con 16% de negro al pie, el remate caía a
       4,22:1 — el adorno rompiéndole el contraste al texto */
    opacity: calc(.35 + var(--am, 0) * .35);
  }
  .nq-capa { position: relative; z-index: 1; min-width: 0; }

  .nq-cabeza { display: flex; align-items: baseline; justify-content: space-between; gap: 18px; }
  .nq-reloj {
    font-family: var(--f-d); font-weight: 300; line-height: .92;
    font-size: clamp(44px, 8vw, 92px); letter-spacing: -2.4px;
    font-variant-numeric: tabular-nums; color: var(--cream);
    text-shadow: 0 2px 26px rgba(0,0,0,.42);
    transition: color .45s ease, text-shadow .45s ease;
  }
  .nq-dia .nq-reloj { color: var(--dia-tinta); text-shadow: none; }
  .nq-lugar {
    text-align: right; font-size: 10.5px; letter-spacing: .24em;
    text-transform: uppercase; font-weight: 700; color: var(--cobre-luz);
    transition: color .45s ease;
  }
  .nq-dia .nq-lugar { color: var(--cobre-hondo); }
  .nq-lugar u {
    display: block; text-decoration: none; letter-spacing: .1em; font-weight: 600;
    color: rgba(251,248,241,.55); margin-top: 4px; transition: color .45s ease;
  }
  .nq-dia .nq-lugar u { color: var(--dia-suave); }

  /* ── los dos rieles ──
     El prefijo `nq-` no es cosmético, y acá costó las dos líneas: `.dia` YA
     EXISTE —es `<main>`— y `.dia .nq-reloj` aplicaba siempre, con los colores
     del día sobre la noche.

     ⚠ Y LOS RIELES NO SE DIBUJARON NUNCA. El HTML los escribía `noche` y `dia`
     y estas cuatro reglas los buscaban `arriba` y `abajo`: ni una matcheaba, así
     que las dos líneas quedaban transparentes y apiladas en `top:0`. El acto
     entero —que ES dos líneas de tiempo, una de llamadas y otra de turnos— se
     dibujó todo este tiempo sin sus líneas. Las etiquetas y los hilos los
     coloca `noche.js` por su cuenta, y por eso la escena parecía entera.
     Renombrarlos `arriba`/`abajo` a secas es peor y está probado: `.arriba` es
     el botón de volver al principio, y el riel salía `position: fixed` y de
     42px de alto. De ahí el `nq-`. */
  .nq-cuerpo { position: relative; display: grid; grid-template-rows: 1fr; }
  .nq-riel { position: absolute; left: 0; right: 0; height: 1px; }
  .nq-riel.nq-arr { top: 22%; background: rgba(251,248,241,.26); transition: background .5s ease, opacity .6s ease; }
  .nq-riel.nq-aba   { top: 82%; background: rgba(251,248,241,.14); transition: background .5s ease; }
  .nq-dia .nq-riel.nq-arr { background: rgba(var(--cielo-rgb),.18); opacity: .5; }
  .nq-dia .nq-riel.nq-aba   { background: rgba(var(--cielo-rgb),.5); }

  /* Los rótulos van pegados al riel: arriba se montaban encima de «21:47» y se
     leían como una sola cosa. */
  .nq-rot {
    position: absolute; left: 0; max-width: 30%;
    font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
    /* .52 y no .3: con .3 daba 2,58:1 sobre la noche —medido leyendo el píxel—
       y a 9,5px con letter-spacing ancho eso no se lee, se adivina. El cálculo
       para llegar a 4,5:1 sobre este fondo da .463; va .52 con margen. */
    font-weight: 700; color: rgba(251,248,241,.52);
    transition: color .5s ease, opacity .5s ease;
  }
  .nq-rot-arr { top: calc(22% + 7px); }
  .nq-rot-aba { top: calc(82% - 20px); }
  .nq-dia .nq-rot { color: var(--dia-suave); }
  .nq-dia .nq-rot-arr { opacity: .45; }

  .nq-cursor {
    position: absolute; top: 0; height: 22%; width: 1px;
    background: linear-gradient(to bottom, rgba(var(--cobre-rgb),0), var(--cobre-luz));
    transition: opacity .6s ease;
  }
  .nq-cursor::after {
    content: ""; position: absolute; bottom: -4px; left: -4px;
    width: 9px; height: 9px; border-radius: 999px; background: var(--cobre-luz);
    box-shadow: 0 0 16px rgba(var(--cobre-rgb),.7);
  }
  .nq-dia .nq-cursor { opacity: 0; }

  /* ── las llamadas ── */
  .nq-llam {
    position: absolute; top: 22%; transform: translate(-50%, -28px);
    text-align: center; opacity: 0; transition: opacity .5s ease;
  }
  .nq-llam.baja { transform: translate(-50%, 9px); }
  .nq-llam.on { opacity: 1; }
  .nq-llam b {
    display: block; font-family: var(--f-d); font-weight: 300;
    font-size: clamp(15px, 1.5vw, 19px); line-height: 1;
    font-variant-numeric: tabular-nums; color: var(--cobre-luz);
    transition: color .5s ease, opacity .5s ease;
  }
  .nq-dia .nq-llam b { color: var(--cielo); opacity: .5; }
  .nq-pt {
    position: absolute; left: 50%; margin-left: -3.5px; width: 7px; height: 7px;
    border-radius: 999px; background: var(--cobre-luz); transition: background .5s ease;
  }
  .nq-llam:not(.baja) .nq-pt { top: 30px; }
  .nq-llam.baja .nq-pt { top: -13px; }
  .nq-llam.on .nq-pt { animation: nq-pulso 1.7s ease-out 1; }
  .nq-dia .nq-llam .nq-pt { background: rgba(var(--cielo-rgb),.45); }
  @keyframes nq-pulso {
    0%   { box-shadow: 0 0 0 0 rgba(var(--cobre-rgb),.6); }
    100% { box-shadow: 0 0 0 17px rgba(var(--cobre-rgb),0); }
  }

  /* ── los turnos ── */
  .nq-trn {
    position: absolute; top: 82%; transform: translate(-50%, 14px);
    text-align: center; opacity: 0; transition: opacity .6s ease;
    width: max-content; max-width: 21vw;
  }
  .nq-trn.on { opacity: 1; }
  .nq-trn b {
    display: block; font-family: var(--f-d); font-weight: 300;
    font-size: clamp(17px, 1.9vw, 24px); line-height: 1;
    font-variant-numeric: tabular-nums; color: var(--cream); transition: color .5s ease;
  }
  .nq-trn span {
    display: block; margin-top: 4px; font-size: clamp(10px, 1vw, 12px);
    color: rgba(251,248,241,.5); transition: color .5s ease;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* el apellido va en su propia caja para poder apagarlo en celular; el <u> es
     un gancho, no un subrayado */
  .nq-trn span u { text-decoration: none; }
  .nq-dia .nq-trn b { color: var(--dia-tinta); }
  .nq-dia .nq-trn span { color: var(--dia-suave); }
  .nq-trn .nq-pt { top: -18px; background: var(--cielo-luz); }
  .nq-dia .nq-trn .nq-pt { background: var(--cielo); }

  /* ── los hilos ── `--largo` lo escribe el JS con getTotalLength(): clavado,
     los largos salen cortados y los cortos aparecen de golpe. */
  .nq-hilos { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
  .nq-hilos path {
    fill: none; stroke: var(--cielo-luz); stroke-width: 1.2; opacity: .5;
    stroke-dasharray: var(--largo); stroke-dashoffset: var(--largo);
    transition: stroke-dashoffset 1.15s var(--spring), opacity .6s ease, stroke .5s ease;
  }
  .nq-hilos path.on { stroke-dashoffset: 0; }
  .nq-dia .nq-hilos path { stroke: var(--cielo); opacity: .34; }

  /* El nombre va ARRIBA: en el medio les cortaba el paso a los hilos. Acá
     comparte renglón con el reloj, que es lo que está contando. */
  .nq-nombre {
    position: absolute; left: 0; right: 0; top: -6%; margin: 0;
    text-align: center; opacity: 0; transition: opacity .45s ease; pointer-events: none;
  }
  .nq-nombre.on { opacity: 1; }
  .nq-nm {
    display: block; font-family: var(--f-d); font-weight: 300;
    font-size: clamp(20px, 2.8vw, 33px); line-height: 1.05; letter-spacing: -.7px;
    color: var(--cream); transition: color .5s ease;
  }
  .nq-dt {
    display: block; margin-top: 4px; font-size: clamp(10.5px, 1.1vw, 12.5px);
    color: rgba(251,248,241,.52); font-variant-numeric: tabular-nums;
    transition: color .5s ease;
  }
  .nq-dia .nq-nombre { opacity: 0 !important; }

  .nq-quieto {
    position: absolute; left: 0; right: 0; top: 46%; margin: 0;
    text-align: center; opacity: 0; transition: opacity .7s ease;
    font-family: var(--f-d); font-weight: 300;
    font-size: clamp(17px, 2.2vw, 26px); line-height: 1.25; letter-spacing: -.4px;
    color: rgba(251,248,241,.5); pointer-events: none;
  }
  .nq-quieto.on { opacity: 1; }

  .nq-cuenta {
    position: absolute; right: 0; top: calc(82% - 20px); max-width: 30%; text-align: right;
    font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
    /* misma cuenta que el rótulo: con .42 daba 3,92:1 */
    font-weight: 700; color: rgba(251,248,241,.55);
    font-variant-numeric: tabular-nums; transition: color .5s ease;
  }
  .nq-dia .nq-cuenta { color: var(--cobre-hondo); }

  .nq-remate {
    text-align: center; opacity: 0; transform: translateY(12px);
    transition: opacity .6s ease, transform .6s var(--spring);
  }
  .nq-remate.on { opacity: 1; transform: none; }
  .nq-remate .t {
    font-family: var(--f-d); font-weight: 300;
    font-size: clamp(21px, 3.2vw, 36px); line-height: 1.06; letter-spacing: -.8px;
    color: var(--cream); transition: color .5s ease; text-wrap: balance;
  }
  .nq-remate .s {
    margin: 8px 0 0; font-size: clamp(12.5px, 1.4vw, 15px);
    color: rgba(251,248,241,.55); transition: color .5s ease; text-wrap: balance;
  }
  .nq-dia .nq-remate .t { color: var(--dia-tinta); }
  .nq-dia .nq-remate .s { color: var(--dia-suave); }

  /* ══ EL ACTO 4 EN UN TELÉFONO ══
     Dos rieles apaisados en 320px. Tres choques, y el primero tiene trampa:

     1. El rótulo se montaba encima de «22:36». Va pegado al riel y a la
        IZQUIERDA, que es justo donde caen las cinco llamadas —el eje va de
        21:00 a 08:00 y ninguna entró después de las 02:14—. Ahora va a la
        derecha, donde el riel está vacío: ahí no molesta y encima nombra el
        silencio. ⚠ NO se arregla comprimiendo el eje al rango real de las
        llamadas, que es lo primero que uno quiere hacer: ese vacío ES el
        mensaje («Y después, nada. Casi seis horas.»). Comprimirlo hace entrar
        las etiquetas y borra el acto.
     2. Los turnos quedan a 65px y «Renata Duarte» mide 75: se leía «Renata
        DuarteMartín Peralta». Queda el nombre de pila (el apellido tiene su
        caja en `noche.js` para poder apagarlo acá).
     3. «Y después, nada» cruzaba los hilos por el medio, claro sobre claro.
        Se sube al mismo vacío que nombra. */
  @media (max-width: 760px) {
    #cuenta { height: 420vh; }
    .nq-llam b { font-size: 12px; }
    .nq-trn b { font-size: 15px; }
    /* 12px es el piso de la página y no se negocia por caber: la regla base
       da `clamp(10px, 1vw, 12px)`, o sea 10px en un teléfono — estaba oculto
       y por eso nadie lo había medido. A 12px «Renata» mide 42 y el hueco
       entre turnos es de 65, así que entra. */
    .nq-trn span { font-size: 12px; max-width: 78px; }
    .nq-trn span u { display: none; }
    .nq-rot { font-size: 8.5px; letter-spacing: .12em; }
    .nq-rot-arr { left: auto; right: 0; text-align: right; max-width: 44%; }
    .nq-cuenta { font-size: 9px; letter-spacing: .1em; }
    .nq-quieto { top: 30%; left: auto; right: 0; width: 58%; text-align: right; }
  }

  /* ══ EL ACTO 4 EN UNA PANTALLA BAJA ══
     El acto ES dos líneas de tiempo, una arriba de la otra. Cuánto aire tienen
     entre ellas no lo decide esta sección: los rieles van al 22% y al 82% del
     cuerpo, y el cuerpo es lo que SOBRA del alto de la pantalla después de la
     barra, del reloj y del remate. En un teléfono acostado —844x390, que es
     girar el teléfono, no un caso de laboratorio— sobraban 74px: los rieles
     quedaban a 45 uno del otro, «LAS LLAMADAS» y «JUEVES 24» a seis píxeles, y
     el acto entero aplastado en una franja.

     Medido a 844x390 antes: 108 de padding + 75 de cabeza + 99 de remate + 18
     de padding + 16 de gaps = 316 de los 390. Acá se recorta de los cinco a la
     vez, que es de donde se puede: el padding de arriba NO se toca abajo de
     `--barra-h` porque el reloj tiene que nacer debajo de la barra, igual que
     el del hero. Queda un cuerpo de ~180 y los rieles a ~108.

     El corte es por ALTURA y no por ancho a propósito: una tablet vertical
     tiene 1024 de alto y no necesita nada de esto. */
  @media (max-height: 560px) {
    #cuenta > .nq-pega {
      padding: calc(var(--barra-h) + 6px) clamp(18px, 4vw, 60px) 10px;
      gap: 6px;
    }
    .nq-reloj { font-size: clamp(30px, 9vh, 44px); letter-spacing: -1.2px; }
    .nq-lugar { font-size: 9px; letter-spacing: .18em; }
    .nq-lugar u { margin-top: 2px; }
    .nq-remate .t { font-size: clamp(16px, 4.4vh, 22px); letter-spacing: -.4px; }
    .nq-remate .s { font-size: 11.5px; margin-top: 4px; }
  }

  /* Sin movimiento no hay noche que recorrer: `noche.js` deja puesta la mañana
     y acá se desarma el sticky. Nunca una pantalla a medio hacer. */
  @media (prefers-reduced-motion: reduce) {
    #cuenta { height: auto; }
    /* con el ID otra vez: `#cuenta > .nq-pega` de arriba le gana a `.nq-pega`
       a secas y el sticky sobrevivía al media query */
    #cuenta > .nq-pega { position: static; height: auto; min-height: 88vh; }
    .nq-llam, .nq-trn, .nq-hilos path, .nq-nombre, .nq-quieto, .nq-remate { transition: none !important; }
    .nq-hilos path { stroke-dashoffset: 0 !important; }
    .nq-llam.on .nq-pt { animation: none; }
  }

  /* ══ ACTO 4 · LOS HILOS — FIN ══ */

  /* ── PRECIOS ── */
  /* el colchón de abajo SIEMPRE mide la costura + 40px: así «Sin tarjeta.»
     termina antes de que arranque el degradé en cualquier alto de pantalla */
  #planes{background:var(--dia-fondo);padding:76px 24px calc(var(--costura) + 40px);
          text-align:center;position:relative;overflow:hidden}
  /* ══ COSTURA: LA MAÑANA SIGUE ══
     Los dos lados son el mismo `--dia-fondo`, así que parecía que no había nada
     que arreglar. Pero el acto no termina en su color de fondo: termina en su
     ATMÓSFERA —el resplandor de cobre del amanecer, abajo a la izquierda—.
     Medido en el píxel del borde: 226,214,213 contra 238,242,245. Setenta y dos
     puntos y, peor, un cambio de TEMPERATURA, que es lo que se lee como una
     línea aunque los dos lados sean claros.
     No se apaga el resplandor: se lo CONTINÚA. Esta capa es la misma radial de
     `.nq-fondo::after` seguida hacia abajo — su centro está 6 vh por debajo del
     borde y su radio vertical es 60 vh, así que en una capa de 60 vh el centro
     cae al 10 % y el radio al 100 %. El alfa es .24 por la opacidad .70 con la
     que el acto la dibuja de día. */
  #planes::before{
    content:'';position:absolute;left:0;right:0;top:0;height:60vh;z-index:0;
    pointer-events:none;
    background:
      radial-gradient(120% 100% at 10% 10%,
        rgba(var(--cobre-rgb),.168), rgba(var(--cobre-rgb),0) 62%),
      linear-gradient(to bottom, rgba(0,0,0,.035), rgba(0,0,0,0) 25%);
  }
  /* el contenido por encima del resplandor, y la noche que sube por encima de
     los dos: sin los tres z-index el degradé del anochecer se iría al fondo */
  #planes > *{position:relative;z-index:1}
  #planes::after{z-index:2}
  /* el fondo de sala desenfocado que había acá se fue con el acto 4: era la
     tercera vez que aparecía la misma foto en la página */
  .planes-nota { margin-top: 26px; font-size: 13.5px; color: var(--dia-suave); }

  /* `center` alineaba las tres columnas por el medio, y como no miden lo mismo
     —el destacado lleva el precio en 56px y «A medida» es una sola linea— los
     tres nombres de plan arrancaban a alturas distintas (269 / 265 / 283 px
     medidos): se leia como un desprolijo, no como jerarquia. Arriba se alinean
     y abajo se alinean los botones; lo que distingue al destacado sigue siendo
     el peso del precio, que es lo que se decidio. */
  /* Grid y no flex por una razón concreta: en flex cada columna resuelve sus
     alturas sola, y las tres tenían distintas —el precio destacado mide 56px
     contra 48, y «A medida» no lleva el `sup` que estira la caja de línea—. El
     resultado eran los tres divisores a 554, 566 y 558: doce píxeles de
     desprolijidad en una fila de tres, que es donde más se nota.
     Con `subgrid` las cinco filas las decide la fila, no la columna: nombre,
     precio, divisor, texto y botón quedan a la misma altura sin un solo número
     fijo, y siguen alineados si mañana cambia un precio o se agrega una línea.
     El gap va sólo a lo ancho: en subgrid el row-gap se hereda, y con 20px
     habría metido veinte píxeles entre cada renglón de cada tarjeta. */
  .price-cards {
    display: grid; grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto auto auto 1fr auto;
    gap: 0 20px;
    margin-top: 46px; align-items: stretch;
    max-width: 960px; width: 100%; margin-left: auto; margin-right: auto;
  }
  /* Tres columnas separadas por una línea, no tres cajas: si vuelve la caja
     negra destacada, vuelve el aire de plantilla. */
  .price-card {
    border: 0; border-radius: 0; background: none;
    padding: 34px 26px; text-align: left;
    border-left: 1px solid var(--dia-linea);
    grid-row: span 5; display: grid; grid-template-rows: subgrid;
  }
  .price-cards > .price-card:first-child { border-left: 0; }
  /* El destacado se distingue por peso y por aire, no por una caja negra con
     sombra: el precio pisa más fuerte y la línea de abajo es más larga. */
  .price-card.featured { background: none; box-shadow: none; padding: 34px 30px; }
  /* El cobre de marca da 3.95:1 sobre el día y esto es texto de 10px: va la
     versión honda (5.35:1). El de marca sigue en lo gráfico y en texto grande. */
  .price-plan {
    font-size: 10px; letter-spacing: 2.5px;
    text-transform: uppercase; color: var(--cobre-hondo);
    display: block; margin-bottom: 12px;
  }
  .price-tag {
    font-family: 'Fraunces', serif;
    font-size: 48px; font-weight: 300;
    color: var(--dia-tinta); line-height: 1;
    margin-bottom: 4px; display: block;
  }
  .price-tag sup { font-size: 20px; vertical-align: super; }
  .price-tag .period { font-size: 16px; opacity: 0.4; }
  .price-card.featured .price-tag { color: var(--dia-tinta); font-size: 56px; }

  .price-divider { width: 32px; height: 1px; background: rgba(var(--cielo-rgb),0.2); margin: 20px 0; }
  .price-card.featured .price-divider { background: rgba(var(--cielo-rgb),0.45); width: 56px; }

  .price-desc { font-size: 14px; line-height: 1.75; color: var(--dia-suave); margin-bottom: 28px; }
  .price-card.featured .price-desc { color: var(--dia-suave); }

  /* `auto` empuja los tres botones al pie de la columna mas alta; el margen de
     28px que tenia lo pone ahora `.price-desc`, para que en la columna mas
     larga siga habiendo aire y no quede el boton pegado al parrafo. */
  .price-cta {
    display: block; margin-top: auto;
    padding: 12px 24px; border-radius: 8px;
    font-size: 14px; font-weight: 500;
    text-align: center; text-decoration: none;
    cursor: pointer; border: none;
    background: rgba(var(--cielo-rgb),0.08); color: var(--cielo);
    transition: opacity 0.2s;
  }
  .price-cta:hover { opacity: 0.8; }
  .price-card.featured .price-cta { background: var(--cielo); color: #fff; }

  /* ── CIERRE ── */
  #cierre{background:var(--noche);color:var(--cream);padding:126px 24px 104px;
          text-align:center;position:relative;overflow:hidden}
  /* la película cierra donde empezó: el mismo teléfono, otra vez de noche */
  .ci-fondo{position:absolute;inset:0;z-index:0;pointer-events:none}
  /* La foto estaba tan apagada que no se leía como plano sino como una mancha
     sucia detrás de los campos. Sube un poco, y en cambio la oscuridad se
     concentra ABAJO Y AL CENTRO, que es exactamente donde se apoya el
     formulario: así la escena se ve arriba y el formulario tiene suelo limpio.
     Es la misma idea que el resto de la página — no se apaga todo por igual,
     se ilumina lo que toca. */
  .ci-fondo img{width:100%;height:100%;object-fit:cover;object-position:50% 42%;
                display:block;filter:brightness(.66) saturate(.9);opacity:.62}
  .ci-fondo::after{content:'';position:absolute;inset:0;
    background:
      radial-gradient(76% 52% at 50% 74%, rgba(4,7,10,.92), rgba(4,7,10,.30) 72%),
      radial-gradient(88% 74% at 50% 34%, rgba(5,4,3,.20), rgba(5,4,3,.86) 86%)}
  #cierre > *:not(.ci-fondo){position:relative;z-index:1}
  /* La costura vuelve a la noche ANOCHECIENDO: los stops intermedios no son
     mezclas neutras del fondo con el negro —eso da gris, que es justo lo que
     no puede pasar en esta página— sino el mismo cielo de la marca cada vez
     más hondo. Van escritos a mano porque un gradient no puede interpolar dos
     custom properties directo.
     Llega a --noche al 90% y se sostiene sólida el resto: la transición
     completa antes del borde de #cierre, no justo en él. */
  /* La costura vive en #planes y no en #cierre: colgada de #cierre salía por
     arriba de su caja y el propio `overflow:hidden` de la sección la recortaba
     entera. Se veía un corte seco de blanco a negro — el degradé estaba
     escrito y no llegaba a pintarse nunca. */
  /* ══ COSTURA: ANOCHECE ══
     El degradé de abajo pinta el pasaje, pero no PASA nada: está siempre ahí,
     igual de oscuro, mires donde mires. Lo que le faltaba a esta costura es lo
     mismo que le faltaba a las otras — que ocurra mientras scrolleás.

     Ahora una sombra baja sobre los precios a medida que la sección se va, y
     recién cuando ya se los llevó empieza el degradé. Es el reverso exacto del
     amanecer del hero: la película arranca de noche, amanece, y la noche
     vuelve a caer sobre el cierre.

     Va por delante del contenido (z-index 2) y por detrás del degradé (::after,
     que es hermano posterior), así que los dos se encadenan sin costura propia.
     Es un solo transform sobre una sola capa: no cuesta nada y por eso corre
     también en celular. */
  /* ══ COSTURA: ANOCHECE ══
     SEGUNDO INTENTO. El primero fue una capa oscura translucida encima de los
     precios, con la opacidad atada al scroll. Se veía mal y el motivo estaba
     escrito dos secciones más arriba, en el amanecer: **un color oscuro con
     alfa sobre un fondo claro pasa por todos los grises del camino.** Mezclar
     `rgb(19,28,34)` al 50% con el día da `rgb(129,141,148)`, que es gris de
     manual. Salía una banda sucia en el medio de la página.

     Por eso el degradé de abajo tiene los stops escritos a mano y curvados
     hacia el azul: para no pisar esa línea recta. La conclusión es que la
     oscuridad no puede LLEGAR mezclándose — tiene que llegar siendo ella.

     Así que no hay capa nueva: SUBE LA QUE YA ESTABA. El degradé mide una
     costura más media pantalla, y arranca empujado hacia abajo para que se vea
     exactamente lo de siempre; a medida que la sección se va, trepa. La noche
     entra por abajo, opaca y por el azul, sin un gris en todo el camino.

     Es un transform sobre una capa que ya existía: no agrega una sola
     composición. Y no depende del alto de la sección —lo que hundía al primer
     intento— porque el recorrido se mide en vh. */
  .js #planes{--anoche:clamp(0, calc(var(--pb, 0) * 1.55), 1)}
  /* el plano se va tapado por la noche que sube: si además hiciera el dolly de
     salida se iría dos veces — el mismo motivo por el que el mazo lo apaga */
  .js #planes.vis .an:not(.s-tit):not(.s-sub),
  .js #planes.vis .s-tit,
  .js #planes.vis .s-sub{
    opacity:1;filter:none;
    transform:translateY(calc((var(--p,.5) - .5) * -16px));
  }

  #planes::after {
    content: ""; position: absolute; left: 0; right: 0;
    /* media pantalla de más que la costura: es lo que trepa. Empieza empujado
       hacia abajo, así que sin JS —o con reduced-motion— se ve la costura de
       siempre y nada se rompe. */
    bottom: 0; height: calc(var(--costura) + 54vh);
    transform: translateY(calc((1 - var(--anoche, 0)) * 54vh));
    will-change: transform;
    /* ⚠ LOS STOPS VAN EN PX Y NO EN %, Y ES TODA LA COSTURA.
       Escritos en %, el degradé se estiraba sobre los 786px de la capa y sólo
       llegaba al negro en el 90% — o sea CASI AL FINAL. Pero la capa arranca
       empujada 54vh hacia abajo y `#planes` la recorta, así que lo que tocaba
       el borde de #cierre no era el final del degradé sino su mitad. Medido a
       mitad del anochecer: 46,62,72 arriba del filo y 7,10,11 abajo, en un
       píxel. Un acantilado de 152 puntos que dura casi todo el trepado, que es
       justo lo que este degradé existe para que no pase.

       Ahora la transición ocurre entera en los primeros `--costura` px y el
       resto —los 54vh que se empujan— es noche sólida. Así el borde de abajo
       de la capa SIEMPRE es `--noche`, esté donde esté el trepado, y se toca
       con el negro de #cierre sin nada en el medio.

       Los 54vh de cola son exactamente el empuje: la cuenta es que la cola
       tiene que ser al menos tan larga como lo que se empuja, o vuelve a
       asomar un color del medio por abajo.

       Y el horizonte cae dentro del colchón de #planes (`--costura` + 40px),
       que está vacío a propósito: al empezar, la banda oscura no toca ni un
       precio. */
    background: linear-gradient(to bottom,
      var(--dia-fondo) 0,
      rgb(220,229,234) calc(var(--costura) * .13),
      rgb(188,205,216) calc(var(--costura) * .27),
      rgb(147,174,189) calc(var(--costura) * .40),
      rgb(106,135,152) calc(var(--costura) * .52),
      rgb(74,98,114)   calc(var(--costura) * .63),
      rgb(51,69,79)    calc(var(--costura) * .72),
      rgb(34,48,58)    calc(var(--costura) * .79),
      rgb(19,28,34)    calc(var(--costura) * .85),
      var(--noche)     calc(var(--costura) * .90),
      var(--noche) 100%);
    pointer-events: none;
  }
  #cierre .s-sub { color: rgba(251,248,241,0.62); }

  /* ── EL FORMULARIO DEL CIERRE ──
     Va acá y no antes: se pide el teléfono después de haber mostrado todo, no
     en la puerta. Sobre la noche los campos son de vidrio —fondo apenas claro y
     un borde— porque una caja blanca en el medio de la escena sería una ventana
     de sistema pegada encima de la película. */
  /* El formulario flotaba directamente sobre la foto: los campos se pisaban
     con el disco del teléfono y no se leía ninguno. Ahora se apoya en una
     superficie propia — vidrio oscuro, sin borde duro, radio grande y una sola
     línea de luz arriba, que es lo que le da canto sin dibujarle una caja. */
  .ci-form{width:min(560px,100%);margin:34px auto 0;text-align:left;
           background:rgba(9,13,17,.66);border-radius:24px;padding:28px 28px 24px;
           box-shadow:inset 0 1px 0 rgba(251,248,241,.08),
                      0 30px 68px rgba(0,0,0,.55)}
  .ci-campos{display:grid;grid-template-columns:1fr 1fr;gap:14px}
  .ci-ancho{grid-column:1 / -1}
  .ci-form label{display:grid;gap:7px}
  /* 11px para un rótulo de formulario es poco: no es un ojal decorativo, es lo
     que dice qué hay que escribir en el campo de abajo. 12,5 con el mismo
     tracking se lee igual de discreto y entra en la regla. */
  .ci-form span{font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;
                color:rgba(251,248,241,.62)}
  /* ══ SE MARCA EL QUE SOBRA, NO LOS QUE FALTAN ══
     La pregunta era si va un asterisco en los obligatorios. Van dos de tres, así
     que asteriscar dos campos de tres es ruido —y un asterisco solo no dice
     nada: necesita una leyenda «* obligatorio» al pie, que es un renglón de
     burocracia en un formulario que promete «sin compromiso y sin tarjeta».
     Marcando el único opcional, todo lo demás se lee obligatorio sin explicar
     nada. Va en el rótulo y no en el placeholder porque el placeholder
     desaparece al escribir, y esto tiene que seguir estando. */
  .ci-form span u{text-decoration:none;letter-spacing:.06em;
                  color:rgba(251,248,241,.38);font-weight:400}
  .ci-form input{
    font:inherit;font-size:15px;color:var(--cream);
    background:rgba(251,248,241,.06);border:1px solid rgba(251,248,241,.10);
    border-radius:14px;padding:14px 16px;width:100%;
    transition:border-color .25s ease,background-color .25s ease}
  .ci-form input::placeholder{color:rgba(251,248,241,.40)}
  .ci-form input:hover{border-color:rgba(251,248,241,.3)}
  .ci-form input:focus{outline:none;border-color:var(--cielo-luz);
                       background:rgba(251,248,241,.11)}
  .ci-form input:focus-visible{outline:2px solid var(--cielo-luz);outline-offset:2px}
  /* el campo que falta se marca al intentar enviar, no mientras se escribe:
     corregir a alguien mientras escribe es de mala educación */
  .ci-form.probado input:invalid{border-color:rgba(196,85,63,.75)}
  /* Esto era un <button> SIN NINGUN ESTILO. La clase `btn-primary` que
     arrastraba no estaba definida en ninguna parte de la hoja — quedó huérfana
     de un bloque que se borró— y lo único que se aplicaba era `width:100%`.
     Por eso se veía como una barra blanca plana: era el botón del navegador
     estirado. Es el control más importante de la página y era el único sin
     diseñar.
     Ahora es lo más brillante de la sección, en el cielo de la marca, con el
     resorte sin rebote que usa el panel. */
  .ci-enviar{
    margin-top:22px;width:100%;display:flex;align-items:center;
    justify-content:center;font:inherit;font-size:15.5px;font-weight:600;
    color:#fff;background:var(--cielo);border:0;border-radius:14px;
    padding:15px 24px;cursor:pointer;letter-spacing:.005em;
    box-shadow:0 10px 26px rgba(var(--cielo-rgb),.34);
    transition:background-color var(--dur-rapida) var(--spring),
               box-shadow var(--dur-rapida) var(--spring),
               transform var(--dur-rapida) var(--spring)}
  .ci-enviar:hover{background:var(--cielo-vivo);
                   box-shadow:0 14px 32px rgba(var(--cielo-rgb),.44)}
  .ci-enviar:active{transform:translateY(1px);
                    box-shadow:0 6px 18px rgba(var(--cielo-rgb),.34)}
  .ci-enviar:focus-visible{outline:2px solid var(--cielo-luz);outline-offset:3px}
  /* Fuera de pantalla y no `display:none`: hay bots que ignoran los campos
     ocultos con display, y este tiene que ser tentador. `aria-hidden` en el
     label lo saca del lector de pantalla y `tabindex=-1` del recorrido de
     teclado, así que una persona no lo encuentra nunca. */
  /* El renglon de error de cada campo. Vacio no ocupa nada, asi que el
     formulario no salta cuando aparece: es `display:block` con contenido y
     nada sin el. El cobre es el unico lugar de la pagina donde el color de
     marca dice un estado, y se banca porque ademas esta el texto. */
  /* `text-transform` y `letter-spacing` en none: es un <span> dentro del label
     y hereda el estilo de los ROTULOS, que van en mayusculas con tracking. Un
     error en mayusculas se lee como que te estan gritando. */
  /* `.ci-form span` (clase + elemento) le gana a `.ci-err` (clase sola), asi
     que el selector tiene que llevar las dos: si no, el error hereda el estilo
     de los ROTULOS y se lee en mayusculas, o sea como si te gritaran. */
  .ci-form .ci-err{display:none;font-size:13px;color:var(--cobre-luz);margin-top:-2px;
                   text-transform:none;letter-spacing:normal}
  .ci-form .ci-err:not(:empty){display:block}
  .ci-form.probado input[aria-invalid="true"]{border-color:rgba(196,85,63,.75)}
  .ci-trampa{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
  .ci-nota{margin:14px 0 0;font-size:13px;color:rgba(251,248,241,.55);text-align:center}
  .ci-nota.bien{color:var(--cielo-luz)}
  .ci-enviar[disabled]{opacity:.6;cursor:progress}
  .ci-nota.mal{color:var(--cobre-luz)}
  /* la salida de emergencia: aparece sólo cuando el envío falló, y con el
     enlace a la vista — no escondido detrás de un `location.href` que en una
     máquina sin cliente de correo no hace nada */
  .ci-salida{margin:8px 0 0;font-size:13px;text-align:center;
             color:rgba(251,248,241,.55)}
  .ci-salida a{color:var(--cielo-luz);text-decoration:underline;
               text-underline-offset:3px}
  .ci-salida a:hover{color:var(--cream)}
  /* La «o» suelta antes del enlace se leía como un error de tipeo. Ahora la
     salida secundaria es una sola frase, y se apaga contra el botón en vez de
     competirle: subrayado sólo al pasar por encima. */
  .ci-o{margin:24px 0 0;font-size:14px}
  .ci-o a{color:var(--cielo-luz);text-decoration:none;
          text-underline-offset:3px;transition:color var(--dur-rapida) var(--spring)}
  .ci-o a:hover{color:var(--cream);text-decoration:underline}
  .ci-o a:focus-visible{outline:2px solid var(--cielo-luz);outline-offset:3px;border-radius:4px}
  @media (max-width:620px){
    .ci-campos{grid-template-columns:1fr}
  }
  /* A 320 —y sólo a 320— el mail de ejemplo no entra por TRES PÍXELES:
     «sofia@clinicadelparque.com» mide 185 y el campo deja 182, así que se cortaba
     la última letra y quedaba «…parque.con». Un ejemplo cortado se lee como un
     error del sitio, que es lo contrario de lo que un ejemplo tiene que hacer.
     Se achica el PLACEHOLDER, no el campo: lo que el visitante escribe sigue a
     15px, y a 14 el ejemplo entra con 12px de aire. */
  @media (max-width:400px){
    .ci-form input::placeholder{font-size:14px}
  }


  @media (max-width: 768px) {
    /* En pantalla angosta la costura se mide en vh —no en píxeles fijos— para
       no dejar un pozo de crema vacío en pantallas cortas. El colchón de
       #planes la sigue solo, porque sale del mismo token. */
    :root { --costura: 28vh; }
    /* ══ EL SILENCIO ANTES DEL REMATE, MEDIDO ══
       Entre «Sin tarjeta.» y «Esta noche va a sonar igual» había 441 px en una
       pantalla de 844: media pantalla de nada. Parte es necesaria —el colchón
       de `#planes` existe para que la banda oscura no toque ningún precio, y
       ahí la noche EstÁ cayendo aunque en una captura parezca vacío— pero los
       126 px de aire de `#cierre` encima de eso son de más. Bajan a 78 y el
       remate llega antes sin tocar la mecánica de la costura. */
    #cierre { padding-top: 78px; }
    /* apilados no hay fila que alinear: el subgrid se deshace y cada tarjeta
       vuelve a resolver sus alturas sola, que apilada es lo correcto */
    .price-cards { grid-template-columns: 1fr; grid-template-rows: none; gap: 0; }
    /* apilados, la línea que los separa pasa de izquierda a arriba */
    .price-card { border-left: 0; border-top: 1px solid var(--dia-linea); padding: 30px 4px;
                  grid-row: auto; display: flex; flex-direction: column; }
    .price-cards > .price-card:first-child { border-top: 0; }
    .price-card.featured { padding: 30px 4px; }
  }

  /* ══ ESTE BLOQUE SE HABÍA PERDIDO ══
     Se borró entero en `7d87ada` (el commit que sacó el split y reordenó la
     página), junto con la sección que ese commit sí quería sacar. Con él se
     fueron el nav, el logo, el botón «Crear cuenta», el acuse de click, el
     anillo de foco de teclado y el botón de volver al principio.
     Consecuencia visible: la barra de arriba de todo quedó siendo una lista con
     viñetas de enlaces azules subrayados por defecto del navegador, en flujo
     normal, y ninguna de las catorce suites lo vio — todas miran el contenido,
     ninguna miraba que el nav tuviera estilos. `qa-nav` ahora lo mira.
     La lección es la misma que ya costó una llave huérfana en su momento:
     borrar una sección de una hoja de estilos por región se lleva puesto lo que
     tenga al lado, y en silencio. */

  /* ── NAV ──
     Mientras la escena está en pantalla el nav ES la escena: sin fondo, sin
     borde y sin blur, con el logo, los enlaces y el botón en claro sobre la
     foto.
     Son DOS cruces y no uno, porque el amanecer los separó. La sala se pone
     blanca a media salida: si el texto claro esperara al fondo de la barra,
     quedaría blanco sobre blanco y no se leería. Entonces:
     · `.tinta` (a 0.38 de la salida) pasa el texto a oscuro, sin fondo: el nav
       sigue siendo parte de la escena, pero legible sobre la sala iluminada.
     · `.scrolled` (a 0.62) trae recién el fondo, el borde y el blur, ya con el
       día abajo. El blur va SÓLO acá: un backdrop-filter permanente obliga al
       navegador a muestrear el fondo en cada cuadro de la escena, y ahí abajo
       hay una película corriendo. */
  nav {
    position: fixed; top: 0; left: 0; right: 0; z-index: 100;
    display: flex; justify-content: space-between; align-items: center;
    padding: 20px var(--barra-x);
    border-bottom: 1px solid transparent;
    background-color: rgba(251,248,241,0);
    transition: padding .45s ease, background-color .45s ease, border-color .45s ease;
  }
  /* El fondo del nav es el del día: con el crema de antes se leía como una
     banda más cálida pegada arriba de todo. */
  /* 0.94 y no 0.85: con 0.85 el título de cada sección se leía borroneado a
     través de la barra mientras le pasaba por detrás —dos textos encimados—.
     Con este alfa el blur sigue dando el vidrio pero lo de atrás no se lee. */
  nav.scrolled {
    padding: 14px var(--barra-x);
    background-color: rgba(238,242,245,0.94);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom-color: var(--dia-linea);
  }

  /* La marca es la palabra: no hay símbolo al lado. El isologo de dos órbitas
     se sacó porque a tamaño de favicon las elipses se tocaban y quedaba una
     mancha; acá el nombre se sostiene solo y el único color es el punto. */
  .logo {
    display: inline-block;
    font-family: 'Fraunces', serif;
    font-size: 30px; font-weight: 400;
    color: var(--cream); letter-spacing: -0.3px;
    text-shadow: 0 1px 16px rgba(0,0,0,0.55);
    text-decoration: none; transition: color .45s ease, text-shadow .45s ease;
  }
  nav.tinta .logo { color: var(--dia-tinta); text-shadow: none; }
  /* El punto cierra la palabra como cierra un asunto: es lo único de color en
     toda la marca. Sobre la escena se aclara —igual que hacía el isologo—
     porque el cobre del día se apaga contra la foto. */
  .punto { font-style: normal; color: var(--cobre); transition: color .45s ease; }
  nav:not(.tinta) .logo .punto { color: var(--cobre-luz); }

  .nav-links { display: flex; align-items: center; gap: 32px; list-style: none; }
  /* ── LOS ENLACES, EN LA FUENTE DE LA MARCA ──
     Iban con `--f-s` en 14/400 y nada encima: la fuente del sistema tal cual
     sale de fábrica al lado de un logo en Fraunces. Era lo único de la barra
     sin decisión tipográfica y se leía así — «parece un Word», textual.
     El botón NO cambia: lo que se lee es serif, lo que se toca es sans.
     No cuesta un byte: el `text=` del `<link>` ya pide el alfabeto entero, no
     la copia de hoy. 15 y no 14 porque la serif tiene menos x-height. */
  .nav-links a {
    font-family: 'Fraunces', serif;
    font-size: 15px; font-weight: 400; color: rgba(251,248,241,0.82);
    text-shadow: 0 1px 12px rgba(0,0,0,0.55);
    text-decoration: none; transition: color .45s ease, text-shadow .45s ease;
  }
  .nav-links a:hover { color: var(--cream); }
  nav.tinta .nav-links a { color: var(--dia-suave); text-shadow: none; }
  nav.tinta .nav-links a:hover { color: var(--dia-tinta); }

  /* El borde va también en el estado sólido —transparente— para que la caja
     mida lo mismo en los dos y el botón no dé un salto de 2px al cambiar. */
  .nav-cta {
    background-color: var(--cielo); color: #fff;
    padding: 10px 22px; border-radius: 8px;
    border: 1px solid transparent;
    font-family: var(--f-s); font-size: 14px; font-weight: 500;
    cursor: pointer; text-decoration: none; display: inline-block;
    transition: opacity .2s, background-color .45s ease, border-color .45s ease, color .45s ease;
  }
  /* Sobre la escena el bloque verde sólido se lee como una calcomanía pegada
     encima de la foto. Ahí es un contorno de luz —el mismo idioma que el botón
     de sonido y el aviso de scroll—, y recién en el día se vuelve macizo. */
  nav:not(.tinta) .nav-cta {
    background-color: rgba(251,248,241,0.07);
    border-color: rgba(251,248,241,0.36);
    color: rgba(251,248,241,0.94);
  }
  .nav-cta:hover { opacity: 0.88; }
  /* el contorno no se apaga al pasar por encima: se enciende */
  nav:not(.tinta) .nav-cta:hover {
    opacity: 1;
    background-color: rgba(251,248,241,0.15);
    border-color: rgba(251,248,241,0.6);
  }

  /* ── LA BARRA VUELVE A LA NOCHE ──
     El cierre apaga la página otra vez, y la barra se quedaba con el fondo del
     día: una banda gris clara pegada arriba del remate, justo donde está el
     formulario. Es el mismo problema que ya tenía el botón de volver arriba, y
     se resuelve igual —dándolo vuelta— con una diferencia: acá el fondo NO
     puede ser el claro con alfa bajo. Un color claro con alfa sobre la noche
     pasa por todos los grises, que es la lección del amanecer al revés. Llega
     siendo la noche, con el blur haciendo el vidrio.
     El color no es el #050403 del cierre sino rgb(19,28,34), que es el stop del
     85% del degradé que sube: en el instante del cruce la barra PERTENECE a la
     costura en vez de adelantarse a ella, y una vez abajo, sobre el negro del
     cierre, la diferencia son cuatro puntos de azul que nadie ve.
     Va DESPUÉS de `.tinta` a propósito: en el cierre las dos clases conviven y
     tiene que ganar ésta. */
  nav.noche {
    background-color: rgba(19,28,34,0.82);
    border-bottom-color: rgba(251,248,241,0.10);
  }
  nav.noche .logo { color: var(--cream); text-shadow: none; }
  nav.noche .logo .punto { color: var(--cobre-luz); }
  nav.noche .nav-links a { color: rgba(251,248,241,0.72); text-shadow: none; }
  nav.noche .nav-links a:hover { color: var(--cream); }
  /* el botón se queda macizo: sobre el negro el cielo sólido es el mismo que
     usa «Que me escriban» tres centímetros más abajo, y son el mismo destino */
  nav.noche .nav-cta { background-color: var(--cielo); color: #fff; }

  /* En celular los enlaces se ESCONDÍAN y el único destino de la barra quedaba
     siendo «Crear cuenta»: no había forma de llegar a ningún lado sin scrollear
     la película entera. Son tres enlaces, no un menú: entran achicando el tipo y
     el aire, y un desplegable sería más máquina que la que hace falta. */
  @media (max-width: 768px) {
    /* los dos tokens bajan juntos: el reloj del hero cuelga de ellos */
    :root { --barra-x: 20px; --barra-h: 82px; }
    /* el gap es el piso: con space-between y la barra casi llena, «Planes»
       terminaba apoyado contra el botón */
    nav { padding: 14px var(--barra-x); gap: 12px; }
    nav .nav-links { gap: 18px; }
    /* el mismo medio punto que arriba: la serif pide un poco más de cuerpo */
    .nav-links a { font-size: 14px; }
    .logo { font-size: 24px; }
    .nav-cta { padding: 9px 16px; font-size: 13px; }
  }
  /* el escalón de los teléfonos angostos (360–400): el mismo contenido, medio
     punto más chico, para que el botón no empuje a los enlaces fuera */
  /* Con TRES enlaces el botón se salía de la pantalla: medido, a 360 px se
     pasaba 6 px del borde y a 320 px, 46. Y no lo delataba el chequeo de scroll
     horizontal, porque la barra es fixed y lo que se le sale no agranda el
     documento: se recorta y listo. Abajo de 480 quedan los dos destinos que un
     médico quiere de verdad — oírla y saber cuánto sale — y el panel se ve
     igual scrolleando, que es lo que va a hacer en un teléfono. */
  @media (max-width: 480px) { .nav-ancho { display: none; } }

  @media (max-width: 400px) {
    :root { --barra-x: 14px; --barra-h: 78px; }
    /* nowrap: sin esto «El panel» y «Crear cuenta» rompen en dos renglones y la
       barra se pone de dos pisos */
    /* el aire entre los tres bloques baja con ellos: es de donde salen los
       píxeles que la serif se lleva (ver el bloque de abajo) */
    nav { padding: 12px var(--barra-x); gap: 8px; }
    .nav-links a, .nav-cta { white-space: nowrap; }
    /* ── LO QUE LA SERIF COBRA A 320 ──
       Fraunces es más ancha que la del sistema al mismo cuerpo, y a 320 px eso
       alcanza para volver a sacar el botón de la pantalla: `qa-nav` lo midió
       en -9 px con 13, y todavía en -1 px con 12. Acá NO se paga el medio
       punto que se paga arriba —queda en 12— y los tres píxeles que faltaban
       salen del aire entre enlaces, que a este ancho ya son dos y no tres. */
    nav .nav-links { gap: 10px; }
    .nav-links a { font-size: 12px; }
    .logo { font-size: 21px; }
    .nav-cta { padding: 8px 12px; font-size: 12px; }
  }

  /* ── EL CLICK Y EL FOCO ──
     Todo lo pulsable tenía hover y nada más: en un teléfono, donde el hover no
     existe, tocar un botón no devolvía ninguna señal. Un pixel para abajo y
     medio punto de opacidad alcanzan —es acuse de recibo, no una animación—. */
  .nav-cta:active, .ci-enviar:active, .price-cta:active,
  .snd:active, .esc-btn:active, .arriba:active { transform: translateY(1px); opacity: 0.9; }

  /* El foco de teclado quedaba en manos del anillo por defecto del navegador,
     que sobre la escena en negro no se ve. Va el azul de la luz de Aira, que
     es el único color que la página usa para decir «acá». */
  a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
    outline: 2px solid var(--cielo-luz);
    outline-offset: 3px;
    border-radius: 4px;
  }

  /* ── VOLVER AL PRINCIPIO ──
     La página mide doce mil píxeles y en celular no había vuelta atrás. Aparece
     recién en el día —durante la escena taparía la película— y el salto es
     seco, no suave: un scroll animado de vuelta se comería la película entera
     al revés, que es lo contrario de lo que pide el que lo aprieta. */
  .arriba {
    position: fixed; right: 22px; bottom: 22px; z-index: 90;
    width: 42px; height: 42px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(238,242,245,0.92); color: var(--dia-tinta);
    border: 1px solid var(--dia-linea); cursor: pointer;
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 6px 22px rgba(20,32,42,0.10);
    opacity: 0; visibility: hidden; transform: translateY(8px);
    transition: opacity .35s ease, transform .35s ease, visibility .35s;
  }
  .arriba.on { opacity: 1; visibility: visible; transform: none; }
  .arriba:hover { background: #fff; border-color: rgba(var(--cielo-rgb),0.45); }
  /* sobre el cierre, que vuelve a ser de noche, el botón claro se lee como una
     mancha: ahí se da vuelta */
  .arriba.noche {
    background: rgba(5,12,10,0.55); color: rgba(251,248,241,0.9);
    border-color: rgba(251,248,241,0.22);
  }
  .arriba.noche:hover { background: rgba(5,12,10,0.75); border-color: rgba(251,248,241,0.4); }
  @media (max-width: 768px) { .arriba { right: 14px; bottom: 14px; } }
  @media (prefers-reduced-motion: reduce) { .arriba { transition: none; } }


  /* ══ EL DEDO ══
     Auditado con la base de ui-ux-pro-max: veintidós controles no llegaban a
     44×44 en un teléfono. El reproductor entero —play, silencio, volumen y la
     barra—, los enlaces del nav y del pie, las pestañas de la receta, el menú
     del panel y el enlace de «creá tu cuenta», que además es un CTA.

     La regla dice 44×44, no «que el botón MIDA 44×44»: lo que tiene que medir
     eso es el ÁREA QUE RESPONDE. Así que nada de agrandar los controles —el
     diseño quedaría inflado y el reproductor dejaría de parecer un
     reproductor—: se les cuelga un `::after` invisible que estira la zona
     sensible hasta el mínimo. El dibujo no se mueve un píxel.

     Se estira sobre todo EN VERTICAL, que es donde sobra aire. A lo ancho, los
     enlaces del nav y las pestañas están a pocos píxeles unos de otros, y dos
     áreas invisibles superpuestas hacen que el dedo abra lo que no quiso.

     `pointer: coarse` y no `max-width`: lo que manda no es el ancho de la
     pantalla sino si el que apunta es un dedo o un mouse. Una tablet ancha con
     dedo necesita el área grande; un notebook angosto con mouse, no. */
  @media (pointer: coarse) {
    /* ⚠ ACÁ NO PUEDE ENTRAR NADA QUE YA ESTÉ POSICIONADO. Entraban DOS, y las
       dos se rompían en cualquier pantalla táctil:

       · `.snd` —el botón de sonido del hero— es `absolute; top:116px;
         right:6vw`. Con `relative`, `right` deja de medirse contra la pantalla
         y pasa a correrlo 23px hacia la IZQUIERDA de donde caería solo:
         terminaba en x=-23, medio afuera del teléfono y encima de «tu
         consultorio, hoy».
       · `.arriba` —volver al principio— es `fixed`. Con `relative` DEJA DE
         FLOTAR: se cae al final del documento, en x=-14. O sea que en todo
         celular el botón no estaba donde tiene que estar.

       Ninguna de las dos necesitaba estar en la lista. Esto existe sólo para
       que el `::after` que agranda el área tenga contra qué colgarse: `.snd`
       ya es `absolute`, que sirve igual, y `.arriba` no tiene `::after`.

       POR QUÉ NO LO VIO NADIE, que es lo que hay que recordar: el chequeo de
       desborde mira `scrollWidth`, y `main.dia` tiene `overflow-x: clip`, así
       que algo colgando por la izquierda NO genera scroll horizontal — la
       página mide «sin desborde» con el botón afuera. Y `qa-nav` sí chequea
       que `.arriba` sea `fixed`, pero lo hace a 1440, donde no hay dedo y esta
       media query ni se aplica. Ahora se mide con rectángulos y con dedo. */
    .nav-links a, .logo, .footer-link, .ci-o a, .esc-mute, .esc-pp,
    .esc-btn, .ag-item, .ag-v, .rx-tab, .price-cta {
      position: relative;
    }
    .nav-links a::after, .logo::after, .footer-link::after, .ci-o a::after,
    .esc-mute::after, .esc-pp::after, .ag-v::after, .rx-tab::after {
      content: ''; position: absolute; left: 0; right: 0;
      top: 50%; height: 44px; transform: translateY(-50%);
    }
    /* el play y el silencio son cuadrados y están sueltos: ahí sí se puede
       estirar también a lo ancho sin pisarle el área a nadie */
    .esc-pp::after, .esc-mute::after { left: 50%; width: 44px; margin-left: -22px; }
    /* el de sonido del hero mide 36 de alto: le faltaban 8 */
    .snd::after { content: ''; position: absolute; left: 0; right: 0;
                  top: 50%; height: 44px; transform: translateY(-50%); }
    /* la barra de avance se arrastra: necesita alto de dedo, no de mouse */
    .esc-barra { padding-block: 9px; background-clip: content-box; }
    /* el control de volumen del navegador es de 16px de alto y no se puede
       estirar por dentro: se le da caja */
    .esc-vol-r { height: 44px; }
    /* los tres botones de plan ya casi llegaban: 43 px por un punto de padding */
    .price-cta { padding-block: 14px; }
  }

  /* ── FOOTER ── */
  /* El pie era tinta (#211d18) contra la noche (#050403) del cierre: la página
     terminaba pasando de blanco a negro y de negro a gris. Ahora es la misma
     noche y lo único que lo separa es una línea. */
  /* El margen lateral es el de la barra y no 80px sueltos: arriba y abajo de la
     página está el MISMO logo, y estaban en dos columnas distintas —48 contra
     80 a 1440, 14 contra 24 en celular—. Es de esas costuras que nadie sabría
     nombrar y que hacen que una página se sienta armada o junta. */
  /* ══ EL PIE NO EMPIEZA CON UNA LÍNEA ══
     El cierre y el pie son los dos la misma noche, así que lo único que los
     separaba era un borde de 1px — y un borde de 1px es exactamente lo que esta
     página no hace en ningún otro lado: «donde cambia el fondo, el cambio se
     PINTA, nunca se corta». Era la última costura que quedaba dibujada a mano.
     Ahora el pie es una zona apenas más clara que sube desde la nada en 56 px:
     se lee como que la página se apoya en algo, sin que haya un filo.
     El 2,8 % está medido, no elegido: sobre `--noche` deja el copyright en
     5,0:1 y los enlaces en 5,7:1 —los dos siguen pasando AA— y es lo máximo
     que se puede levantar sin empezar a comerse ese contraste. */
  footer {
    background:
      linear-gradient(to bottom,
        rgba(251,248,241,0) 0,
        rgba(251,248,241,.028) 56px,
        rgba(251,248,241,.028) 100%),
      var(--noche);
    padding: 48px var(--barra-x);
    display: flex; justify-content: space-between; align-items: center;
  }
  .footer-logo { font-family: 'Fraunces', serif; font-size: 20px; color: rgba(255,255,255,0.6); }
  /* En el pie el fondo es tinta: el cobre del día se hunde, va el mismo tono
     claro que usa la marca sobre la escena. */
  .footer-logo .punto { color: var(--cobre-luz); }
  /* Sobre el ink del pie el texto es blanco: para subir el contraste hay que
     hacerlo MÁS opaco, no más oscuro (oscurecerlo lo acercaría al fondo).
     0.30 → 0.50 deja el copyright en 5.13:1 y 0.40 → 0.55 los enlaces en
     5.90:1; la jerarquía se mantiene (copy < enlace < logo). */
  .footer-copy { font-size: 13px; color: rgba(255,255,255,0.5); }
  .footer-link { font-size: 13px; color: rgba(255,255,255,0.55); text-decoration: none; transition: color 0.2s; }
  .footer-link:hover { color: rgba(255,255,255,0.7); }

  @media (max-width: 768px) {
    footer { flex-direction: column; gap: 14px; text-align: center; padding: 40px var(--barra-x); }
  }

  /* ══ CÓMO ENTRA UN PLANO ══
     Lo de antes —un fade con 26 px— era correcto y, en la práctica, invisible.
     Ahora entran tres cosas juntas: el título palabra por palabra (el mismo
     gesto del titular del hero), un recorrido que se ve de verdad con la curva
     de la marca, y las capas moviéndose a distinta velocidad mientras el plano
     está en pantalla (`--p`, que publica secciones.js).
     Todo por transform y opacity. La clase `js` la pone el script: si no llega
     a correr, la página queda entera y quieta en su estado final. */

  /* ── el título, palabra por palabra ── */
  .js .s-tit .pal{display:inline-block;opacity:0;transform:translateY(.44em) rotate(1.2deg);
                  filter:blur(7px);transform-origin:0% 100%;
                  transition:opacity .62s var(--ease-salida),
                              transform .78s var(--spring),
                              filter .62s var(--ease-salida);
                  transition-delay:calc(var(--i) * 62ms)}
  .js .vis .s-tit .pal{opacity:1;transform:none;filter:none}

  /* ── lo demás del plano ──
     ⚠ LA ENTRADA VA EN `translate`/`scale` Y NO EN `transform`, Y NO ES UN
     CAPRICHO: EL RECORRIDO NO OCURRÍA.

     Sobre el mismo `transform` había dos cosas peleándose: la ENTRADA, que es
     por tiempo (una transición de 760ms con la curva de la marca), y el
     PARALAJE, que es por scroll (`--p`, que se reescribe en cada cuadro). Como
     ganaba la regla del paralaje, el destino de la transición cambiaba 60 veces
     por segundo, y una transición cuyo destino cambia se REINICIA: de los 760ms
     de la curva sólo se recorrían los primeros 16 — y el resorte, que arranca
     en 0, .009, .035, en 16ms no mueve nada.

     Medido bajando a velocidad de rueda: las tres tarjetas de precio y los
     subtítulos se quedaban clavados en los 60px de abajo TODO el descenso, con
     la opacidad y el desenfoque animando normalmente (esos dos sí tienen
     destino fijo). Recién al frenar pegaban el salto de 60px de una. O sea que
     el «recorrido que se ve de verdad» que este bloque vino a traer sólo se
     veía si dejabas de scrollear, que es justo cuando no lo estás mirando.

     Con `d1`…`d4` era peor todavía: el retardo vuelve a contar desde cero en
     cada reinicio, así que nunca llegaba a cumplirse y no se movían NUNCA.
     Sacar el retardo tampoco alcanzaba: probado, avanzaba 5px en 750ms.

     `translate` y `scale` son propiedades independientes que se componen con
     `transform` en vez de reemplazarlo. La entrada vive en las suyas, el
     paralaje se queda con `transform`, y ninguna le pisa el destino a la otra.
     Es la misma cuenta de composición para el navegador: sigue siendo una sola
     matriz y sigue sin tocar layout. */
  .js .an{opacity:0;translate:0 60px;scale:.985;filter:blur(9px);
          transition:opacity var(--dur-plano) var(--ease-salida),
                      translate var(--dur-plano) var(--spring),
                      scale var(--dur-plano) var(--spring),
                      filter var(--dur-plano) var(--ease-salida)}
  .js .vis .an{opacity:1;translate:none;scale:none;filter:none}
  .js .vis .an.d1{transition-delay:.12s}
  .js .vis .an.d2{transition-delay:.26s}
  .js .vis .an.d3{transition-delay:.40s}
  .js .vis .an.d4{transition-delay:.52s}
  /* el título ya se anima palabra por palabra: si además entra como bloque, el
     gesto se duplica y se pierde */
  .js .s-tit.an{opacity:1;translate:none;scale:none;filter:none;transition:none}

  /* ── EL RECORRIDO: UN PLANO ENTRA Y UN PLANO SE VA ──
     Antes el contenido entraba y ahí se quedaba: la mitad del movimiento
     faltaba, y por eso el pasaje de una sección a otra se sentía nulo. Ahora
     cada plano hace las dos cosas, atado al scroll (`--p`, de 0 a 1):

       · ENTRA  (p 0 → .40): sube, se acomoda y enfoca. Lo maneja la transición.
       · ESTÁ   (p .40 → .58): quieto, para poder leerlo. Un plano que no para
                                nunca es mareo, no cine.
       · SE VA  (p .58 → 1): la cámara se aleja — el plano se achica, se sube y
                                se apaga mientras el siguiente sube a ocuparlo.

     `--sal` es esa última etapa, de 0 a 1. Se calcula con clamp() sobre `--p`,
     así que no cuesta un solo cálculo de JS extra: el rAF ya escribe `--p`.
     Y todo es transform y opacity: nada de esto toca layout. */
  @media (min-width: 900px) {
    .js [data-an]{--sal:clamp(0, calc((var(--p, 0) - .58) * 2.4), 1)}

    /* el título es lo que más recorre, en las dos puntas: es el ancla del plano */
    .js .vis .s-tit{
      transform:translateY(calc((var(--p,.5) - .5) * -52px - var(--sal) * 130px))
                scale(calc(1 - var(--sal) * .10));
      opacity:calc(1 - var(--sal) * .95);
      filter:blur(calc(var(--sal) * 5px));
    }
    .js .vis .s-sub{
      transform:translateY(calc((var(--p,.5) - .5) * -30px - var(--sal) * 104px));
      opacity:calc(1 - var(--sal));
      filter:blur(calc(var(--sal) * 4px));
    }
    /* el objeto del plano —la ventana, el mazo, los números— se aleja como si
       la cámara retrocediera, y se lleva su sombra con él. El desenfoque es el
       que hace que se lea como profundidad y no como un elemento que se apaga:
       lo que sale de plano pierde foco, igual que en la escena del hero. */
    .js .vis .an:not(.s-tit):not(.s-sub){
      transform:translateY(calc((var(--p,.5) - .5) * 26px - var(--sal) * 86px))
                scale(calc(1 - var(--sal) * .11));
      opacity:calc(1 - var(--sal) * .9);
      filter:blur(calc(var(--sal) * 6px));
    }
    /* ── COSTURA: LA CÁMARA ATRAVIESA EL PAPEL (receta → la cuenta) ──
       La salida genérica ALEJA la cámara: el plano se achica y se va para
       arriba. Acá se invierte. La receta CRECE y pierde foco —la cámara la
       atraviesa, no la abandona— y del otro lado los números nacen chicos y
       desenfocados atrás, y llegan a foco al llegar al frente.

       Es el pasaje que más sentido tiene que sea de profundidad: de un
       documento a un número, o sea de algo que se lee de cerca a algo que se
       lee de lejos. Y es el mismo idioma que ya habla el hero cuando la
       cámara entra al monitor, así que la página termina teniendo una sola
       cámara en vez de dos gramáticas.

       El desenfoque es lo caro de toda la página, así que vive SÓLO en la
       costura y no en todo el recorrido: fuera del tramo de salida el valor
       es 0 y el navegador ni lo compone. */
    .js #escrito.vis .s-tit{
      transform:translateY(calc((var(--p,.5) - .5) * -34px)) scale(calc(1 + var(--sal) * .24));
      opacity:calc(1 - var(--sal) * 1.08);
      filter:blur(calc(var(--sal) * 7px));
    }
    .js #escrito.vis .s-sub{
      transform:translateY(calc((var(--p,.5) - .5) * -22px)) scale(calc(1 + var(--sal) * .20));
      opacity:calc(1 - var(--sal) * 1.15);
      filter:blur(calc(var(--sal) * 9px));
    }
    .js #escrito.vis .an:not(.s-tit):not(.s-sub){
      transform:translateY(calc((var(--p,.5) - .5) * 14px)) scale(calc(1 + var(--sal) * .30));
      opacity:calc(1 - var(--sal) * 1.05);
      filter:blur(calc(var(--sal) * 7px));
      transform-origin:50% 44%;
    }
    /* El acto 4 ya no tiene `.s-tit`, `.s-sub` ni `.an`: es la noche entera con
       sus propias clases `nq-*`, y `#cuenta` ni siquiera lleva `data-an`, así
       que nadie le publica `--p`. Acá vivía su entrada —y el arreglo de que la
       transición de `.js .an` le pisaba la opacidad y la dejaba invisible al
       pasar—; con la sección vieja se fue también el problema. Se saca en vez
       de dejarlo: el presupuesto de peso no tiene lugar para código muerto, y
       ese fue el mismo criterio con el que el acto 4 borró el CSS de los tres
       números. */

    /* ── COSTURA: EL BARRIDO (el panel → la receta) ──
       El único salto de registro fuerte que tiene la página: de una pantalla a
       un papel. Es donde el corte tiene que decir «esto es otra cosa», y por
       eso acá se gasta la única vez que un movimiento horizontal no marea.

       La receta ENTRA COMO PLANO, no como contenido: la sección entera llega
       desde la derecha con su fondo, y el panel se va hacia la izquierda a un
       tercio de esa velocidad. Esa diferencia es todo — si los dos se movieran
       igual sería una diapositiva; con paralaje se lee como que uno pasa por
       delante del otro.

       El filo es una SOMBRA y no una línea de luz: sobre una página clara el
       blanco no se ve, y lo que hace leer el barrido como un plano que tapa al
       otro es la sombra que tira sobre el que se va.

       ⚠ ESA SOMBRA NO SE DIBUJABA NUNCA. Vivía en un `::after` con `right:100%`
       —o sea ENTERA fuera de la caja— y el `overflow:hidden` que #escrito
       necesita para el mazo que gira la recortaba sin dejar rastro. Congelado a
       mitad del barrido, el fondo pasaba de 238,242,245 a 225,232,236 en DOS
       píxeles: dos grises casi iguales separados por un filo duro, que es
       exactamente lo que la sombra existía para evitar.

       Ahora es un `box-shadow` del elemento. Su propio overflow no toca las
       decoraciones de su caja, así que se ve.

       Y no hace falta apagarla con `--ent`: cuando el plano termina de llegar,
       su borde izquierdo ES el de la pantalla y la sombra queda afuera sola.
       Un elemento menos y una opacidad menos que pintar por cuadro.

       Los números no son al azar: con blur 46 y spread -23 lo que sobresale
       arriba y abajo es 46/2 - 23 = 0 —ahí no hay filo, y una sombra en el
       borde de arriba ensuciaría la costura horizontal con #agenda—, y del
       lado derecho la sombra cae 38px DENTRO del plano, tapada por él.

       Sin sticky y sin tocar la estructura: cada sección lee su propio avance. */
    .js #escrito{--ent:clamp(0, calc((var(--p, 0) - .04) * 3.4), 1);
                 transform:translateX(calc((1 - var(--ent)) * 62%));
                 box-shadow:-44px 0 58px -29px rgba(6,14,20,.22);
                 will-change:transform}
    /* el panel se va por la izquierda, a un tercio */
    .js #agenda.vis .an:not(.s-tit):not(.s-sub),
    .js #agenda.vis .ag-escena{
      transform:translate(calc(var(--sal) * -19%), calc(var(--sal) * -26px))
                scale(calc(1 - var(--sal) * .06));
      opacity:calc(1 - var(--sal) * .85);
      filter:blur(calc(var(--sal) * 4px));
    }
    .js #agenda.vis .s-tit{
      transform:translate(calc(var(--sal) * -26%), calc((var(--p,.5) - .5) * -52px));
      opacity:calc(1 - var(--sal) * .95);
      filter:blur(calc(var(--sal) * 4px));
    }
    .js #agenda.vis .s-sub{
      transform:translate(calc(var(--sal) * -22%), calc((var(--p,.5) - .5) * -30px));
      opacity:calc(1 - var(--sal));
    }

    /* el halo del amanecer va al revés y más rápido: es lo que queda de la luz
       de la escena, y tiene que despegarse de lo que ilumina */
    .js .vis .ag-luz{transform:translate(-50%, calc((var(--p,.5) - .5) * -70px))}
    /* la ventana del panel maneja su propia perspectiva con --ag-p: acá sólo se
       le suma la salida, si no una de las dos pisa a la otra */
    .js .vis .ag-escena{transform:translateY(calc(var(--sal) * -86px)) scale(calc(1 - var(--sal) * .11));
                        opacity:calc(1 - var(--sal) * .9);filter:blur(calc(var(--sal) * 6px))}
  }

  @media (prefers-reduced-motion: reduce) {
    /* == EL ESTADO FINAL, NO EL DE CAMINO ==
       Con reduced-motion la pagina tiene que mostrar lo que se ve AL FINAL de
       cada gesto, no el fotograma inicial. Enumerar regla por regla no alcanza
       —lo probe y se me escaparon dos secciones enteras—: aca se les fija el
       valor a los CUATRO MOTORES de los que cuelga todo el movimiento, y con
       eso queda neutralizada cualquier regla que dependa de ellos, incluidas
       las que alguien escriba manana.

         --p .5   → el punto medio: todos los `(var(--p,.5) - .5)` dan cero
         --sal 0  → nada se esta yendo
         --ent 1  → todo ya llego
         --pb 0   → ninguna costura arranco

       Va con `!important` porque `--p` y `--pb` los escribe el JS INLINE en
       cada cuadro, y sin eso el inline gana.

       LO QUE PASABA SIN ESTO, medido: «El que no te encuentra, llama al de al
       lado» era una PANTALLA EN BLANCO —sus cuatro elementos con opacidad 0,
       porque `--ent` sin escribir vale 0 y ahi multiplica— y la receta quedaba
       corrida un 62% a la derecha, medio afuera de la pantalla. Dos secciones
       enteras inutilizadas para alguien que apago las animaciones. */
    .js [data-an]{--p:.5 !important; --pb:0 !important;
                  --sal:0 !important; --ent:1 !important; --anoche:0 !important}
    /* el mazo tambien es movimiento atado al scroll */
    .js #escuchar{position:static !important; min-height:0 !important;
                  transform:none !important; filter:none !important}
    /* la sombra del barrido: con --ent en 1 el plano ya llego y la sombra cae
       fuera de la pantalla sola, pero apagarla es una regla y no un frame */
    .js #escrito{box-shadow:none}

    /* `translate` y `scale` van explicitos: la entrada de los planos vive ahi
       desde que se separo del `transform` del paralaje, y sin resetearlas el
       que apago las animaciones se queda con todo 60px abajo y al 98.5% */
    .js .an, .js .s-tit .pal{opacity:1;transform:none;translate:none;scale:none;
                             filter:none;transition:none}
    .js .vis .s-tit, .js .vis .s-sub, .js .vis .ag-escena,
    .js .vis .rx, .js .vis .ag-luz{transform:none}
    .js .vis .ag-luz{transform:translateX(-50%)}
  }

