/* CUTHALF · partida
   Telemetría superior, escenario y lectura inferior. */

/* ── telemetría superior ─────────────────────────────────────── */
.hud{
  display:flex;align-items:center;justify-content:space-between;
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  padding-bottom:12px;border-bottom:1px solid var(--hair);
}
.hud b{font-weight:500}
.lives{display:flex;gap:6px;align-items:center}
.lives i{display:block;position:relative;width:3px;height:14px}
.lives i::before{content:"";position:absolute;inset:0;background:var(--ink);
  transition:opacity .32s,transform .32s cubic-bezier(.2,.8,.2,1);transform-origin:center}
.lives i.off::before{opacity:.16;transform:scaleY(.4)}
.lives i.new::before{opacity:0;transform:scaleY(0)}
/* ── escenario ───────────────────────────────────────────────── */
.stage{position:relative}
canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* vidas: dentro del escenario, arriba a la izquierda, enfrentadas
   a la cuenta atrás que se dibuja en el lienzo arriba a la derecha.

   Colgadas del renglón con el mismo gesto que el marcador —`top:26` y
   medio tirón hacia arriba— y no de un `top` calculado a mano: así el
   día que cambie el alto de la barra siguen centradas solas. Con la
   cuenta a mano bastaba tocar ese alto para descolgarlas.           */
.stage .lives{position:absolute;left:12px;top:26px;transform:translateY(-50%);z-index:2}
/* El marcador en directo, en medio de esas dos.

   Vidas y reloj van al renglón 26 del lienzo, que es donde render.js
   dibuja el aro. El marcador cuelga de un renglón propio, 6 px por
   debajo: el `top` con el medio tirón hacia arriba centra la caja en
   esa línea sea cual sea su tamaño.

   Seis y no cero porque a 36 px la cifra mide unos 26 de tinta, y
   colgada del mismo renglón que las otras dos le quedaban trece
   escasos hasta el filo de arriba del escenario —pegada a la raya del
   HUD, como si se saliera—. Bajándola quedan diecinueve y respira.
   Las tres siguen leyéndose como una sola banda porque el marcador es
   mucho más alto que sus vecinas y las envuelve de sobra; lo que se
   descuadraría es alinearlas por el centro cuando una mide el doble.

   En azul, que es el color del acierto, y con cifra tabular para que
   no baile al rodar de 999 a 1.000. Y sin recoger el puntero: el
   escenario entero es zona de corte, y una banda de lado a lado se
   tragaría los trazos que empiezan arriba.

   Y ese pelo con el que se sube: centrar la caja no centra la cifra.
   La tinta de un número va de la línea base al alto de versal, y eso
   no cae en medio de su caja. Cuánto se desvía no se puede deducir
   del cuerpo —el navegador redondea las medidas de la letra a píxeles
   enteros para maquetar, así que la desviación da saltos y ni
   siquiera conserva el signo—, y por eso va en píxeles y medida:
   escrita en `em` parecería que se ajusta sola al cambiar el tamaño,
   y no lo hace. Se vuelve a medir cada vez que se toque el cuerpo, y
   el paso de prueba del renglón está para avisar si se olvida.     */
.pts-live{
  position:absolute;left:0;right:0;top:32px;
  transform:translateY(calc(-50% - .5px));
  z-index:2;pointer-events:none;text-align:center;
  font-size:36px;letter-spacing:.04em;line-height:1;
}
.pts-live b{font-weight:500;color:var(--signal);font-variant-numeric:tabular-nums}
/* consejo del tutorial: banda superior del escenario, fuera del paso
   de la figura, que ocupa la franja central                        */
.tip{
  position:absolute;left:0;right:0;top:0;margin:0 auto;max-width:34ch;
  padding:6px 16px 0;text-align:center;pointer-events:none;
  font-size:12px;line-height:1.55;opacity:.75;
}
.tip.on{animation:capIn .38s cubic-bezier(.2,.8,.2,1)}
/* elogio: aparece en el centro del escenario y se va solo */
.hype{
  position:absolute;left:0;right:0;top:50%;padding:0 22px;text-align:center;
  font-family:var(--sans);font-weight:600;line-height:1.02;letter-spacing:-.03em;
  font-size:calc(clamp(30px,10vw,52px) * var(--k,1));
  color:var(--signal);opacity:0;pointer-events:none;
  transform:translateY(-50%);
}
.hype.on{animation:hype .8s cubic-bezier(.2,.8,.2,1) .1s both}
/* el fallo también habla, y sin azul: el azul sólo marca el acierto.
   Pero la balanza se vence por el centro, justo bajo este texto, y se
   dibuja en tinta plana: cualquier color fijo se perdería encima. El
   negativo se calcula contra lo que haya detrás — blanco literal, no
   una variable: con «difference» es lo que garantiza la inversión en
   los dos temas y también sobre la figura.                          */
.hype.miss{color:#fff;mix-blend-mode:difference}
@keyframes hype{
  0%{opacity:0;transform:translateY(-50%) scale(.94)}
  20%{opacity:1;transform:translateY(-50%) scale(1)}
  68%{opacity:1;transform:translateY(-50%) scale(1)}
  100%{opacity:0;transform:translateY(-50%) scale(1.03)}
}

/* ── cuenta atrás ────────────────────────────────────────────────
   Tres tarjetas que se dan la vuelta partiéndose por la mitad, como
   los paneles de los aeropuertos: la mitad de arriba cae sobre la de
   abajo y detrás queda la cifra siguiente. Es el gesto del juego
   —partir en dos por el centro— ensayado antes de jugarlo, y por eso
   el pliegue va donde va y no en otro sitio.

   Sin caja ni sombra: la tarjeta es del color del fondo y lo único
   que la dibuja es la línea del corte, que es como se dibuja todo
   aquí. Lo que se ve es el movimiento.

   Ni una duración escrita: `--flip` la pone game.js desde `CUENTA`,
   que es quien reparte el compás. Así no pueden discrepar.        */
.flap{
  position:absolute;left:50%;top:50%;width:112px;height:140px;
  transform:translate(-50%,-50%);perspective:600px;z-index:1;
  pointer-events:none;
}
.flap b{
  position:absolute;left:0;width:100%;height:50%;overflow:hidden;
  background:var(--ground);backface-visibility:hidden;
}
/* Las cuatro mitades recortan la MISMA caja de 140 px, y la de abajo
   la sube justo la mitad. Por eso el corte cae siempre en el mismo
   sitio: no depende de la forma del dígito, sino de la caja.      */
.flap i{
  display:block;width:100%;height:140px;
  font-family:var(--sans);font-style:normal;font-weight:600;
  font-size:116px;line-height:140px;letter-spacing:-.05em;
  text-align:center;color:var(--ink);
}
/* La salida: la misma tarjeta, pero con palabra. Cuatro signos donde
   cabía uno, así que cuerpo propio — a 116 se saldría de la tarjeta
   por los dos lados. A 52 ocupa 84 de los 112, algo más que la cifra
   (59) y todavía con aire a los lados, que es lo que sostiene la
   tarjeta sin caja ni sombra. El interletraje casi se suelta: el
   -.05em está para apretar dígitos y en una palabra los pega.

   Y sube 8 px para que el pliegue la parta por la mitad. Sin eso la
   palabra queda donde queda la cifra —las dos con la tinta centrada
   en 78, con el pliegue en 70—, que en una cifra de 82 px de alto son
   ocho de nada y en una palabra de 46 son un tachón por encima de las
   letras. La tarjeta parte en dos por el centro y ése es el gesto del
   juego: si algo hay que centrar en el pliegue, es esto. Se mueven
   las dos mitades a la vez, así que el corte sigue en su sitio y lo
   que se mueve es la palabra.                                      */
.flap i.word{font-size:52px;letter-spacing:-.02em;position:relative;top:-8px}
.flap .lo i{margin-top:-70px}
.flap .up{top:0;transform-origin:50% 100%;border-bottom:1px solid var(--hair)}
/* Menos en la salida. Esa línea es el corte de la tarjeta, y sobre una
   cifra —alta y estrecha— se lee como tal; pero la palabra es ancha y
   baja, y la línea le cruza las letras de lado a lado: deja de parecer
   un pliegue y parece un tachón sobre el ¡YA!. La tarjeta se sigue
   partiendo por ahí al girar, que es lo que cuenta; lo que se retira
   es sólo el trazo quieto.

   Y se retira el borde entero, no su color. Con `border-box` la mitad
   de arriba mide 70 px contando el borde, así que ese píxel se lo
   quita a la letra: la palabra se recorta en 69 y la de abajo empieza
   en 70, y en medio queda una banda del color de la tarjeta que sigue
   partiendo el texto aunque el trazo ya no se pinte. Sin borde, la
   mitad de arriba llega hasta el 70 justo donde arranca la otra y la
   palabra se lee de una pieza, que es de lo que se trataba.        */
.flap .up:has(i.word){border-bottom-width:0}
/* Y la salida, quieta, la pinta una sola mitad.

   Quitado el trazo quedaba una costura: el pliegue cae en el centro
   del escenario, y ese centro no siempre es un píxel entero de
   pantalla —con la ampliación del sistema al 125 %, la de casi
   cualquier ordenador de sobremesa, no lo es—. Ahí la mitad de arriba
   acaba a media fila y la de abajo empieza a media fila; el navegador
   compone dos bordes suavizados y donde tenía que haber tinta entera
   queda una fila más clara cruzando las letras. En un móvil, con tres
   píxeles de pantalla por cada uno, se disimula; en un monitor con el
   tema claro es una raya gris sobre negro.

   Solapar las mitades no lo arregla —cada una va en su propia capa y
   el borde se vuelve a suavizar un píxel más allá—, así que se quita
   la juntura: en reposo la tarjeta de la salida la lleva entera la
   mitad de arriba, que es la que va delante, y la palabra se rasteriza
   de una vez. Sólo en reposo: al girar, `fold` lleva la cifra que se
   va —nunca la palabra— y conserva su medio alto, que es lo que se
   dobla. La juntura sigue existiendo mientras la tarjeta se mueve,
   que es donde no se ve y donde tiene que estar.                  */
.flap .fold:has(i.word){height:100%}
.flap .lo{bottom:0;transform-origin:50% 0}
/* la que cae va delante de todo; la que sube espera de canto, que a
   90 grados no se ve, y sólo entonces tapa a la cifra vieja       */
.flap .fold{z-index:3}
.flap .rise{z-index:2;transform:rotateX(90deg)}
.flap.turn .fold{animation:flapFold calc(var(--flip)/2) ease-in forwards}
.flap.turn .rise{animation:flapRise calc(var(--flip)/2) calc(var(--flip)/2) ease-out forwards}
@keyframes flapFold{to{transform:rotateX(-90deg)}}
@keyframes flapRise{from{transform:rotateX(90deg)}to{transform:rotateX(0)}}

/* ── lectura inferior ────────────────────────────────────────── */
.readout{min-height:118px;display:flex;flex-direction:column;justify-content:flex-end;gap:8px}
.num{
  font-family:var(--sans);font-weight:600;
  font-size:clamp(50px,17vw,86px);line-height:.86;letter-spacing:-.045em;
  opacity:0;transform:translateY(6px);transition:opacity .18s ease,transform .18s ease;
  position:relative;align-self:flex-start;
}
.num.on{opacity:1;transform:none}
.num small{font-size:.34em;font-weight:400;letter-spacing:0;vertical-align:.9em;margin-left:.1em;opacity:.5}
.num::after{content:"";position:absolute;left:-4px;right:-4px;top:52%;height:1px;background:var(--ink);
  transform:scaleX(0);transform-origin:left;transition:transform .3s cubic-bezier(.2,.8,.2,1)}
.num.void::after{transform:scaleX(1)}
.num.valid{color:var(--signal)}
.cap{font-size:11px;letter-spacing:.16em;text-transform:uppercase;opacity:.55;
  border-top:1px solid var(--hair);padding-top:11px;transition:color .2s}
.cap.hit{color:var(--signal);opacity:1;animation:capIn .38s cubic-bezier(.2,.8,.2,1)}
@keyframes capIn{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
