/*
  Loadfactur — el movimiento de la web pública.

  Una capa encima de estilo.css y nada más. Allí está dibujado el estado final
  de cada escena; aquí sólo se rebobina y se reproduce. Si este fichero no
  carga, la página está completa.

  Cuatro reglas que no se tocan:

  1. Todo va dentro de `prefers-reduced-motion: no-preference`. Quien ha
     pedido menos movimiento ve directamente el estado final.
  2. Sólo `transform` (y sus propiedades sueltas), `opacity` y `clip-path`.
     Nada que obligue a recalcular el diseño en cada fotograma.
  3. Nada en bucle infinito. Cada escena se reproduce una vez y se queda
     quieta; se vuelve a ver al pasar el ratón o con «Ver otra vez».
  4. El texto que se lee no se esconde. Se animan dibujos de apoyo, no
     párrafos. Nielsen Norman Group lo midió con usuarios: el texto principal
     que aparece al hacer scroll hace esperar, y en una web B2B se lee como
     lentitud. Por eso la escalera y la frase del relato están quietas. La
     única excepción es el «Sí.»: una palabra, en 350 ms y sin retraso.

  Cada movimiento cuenta algo, igual que en Clinic Velocity, de donde sale el
  vocabulario: la factura que se lee, las cajas que enseñan su proceso y el
  «Sí.» que se estampa como un sello.

  Y una trampa que ya costó una frase invisible: nunca se recorta con
  `clip-path` el elemento que lleva `data-escena`. El IntersectionObserver de
  Chrome descuenta ese recorte, ve la escena al 0 % y no la arranca nunca. Si
  hace falta recortar, se recorta un hijo.

  Cuándo arranca cada escena lo decide director.js: pone `animable` a lo que
  se va a animar y `en-marcha` cuando entra en pantalla.
*/

:root {
  /* Decelera al llegar: lo que entra frena, no choca. */
  --llegada: cubic-bezier(0.16, 1, 0.3, 1);
  /* Acelera al irse. */
  --salida: cubic-bezier(0.7, 0, 0.84, 0);
  /* Ida y vuelta pareja: lo que viaja de un sitio a otro. */
  --viaje: cubic-bezier(0.45, 0, 0.2, 1);
}

@media (prefers-reduced-motion: no-preference) {
  /* ---------------- el reloj de cada escena ---------------- */

  /* Una escena animable espera parada en su primer fotograma hasta que el
     director le da la salida. */
  .animable {
    --reproduccion: paused;
  }

  .animable.en-marcha {
    --reproduccion: running;
  }

  /* ---------------- los botones ---------------- */

  .boton {
    transition:
      background-color 130ms ease,
      border-color 130ms ease,
      scale 160ms var(--llegada);
  }

  .boton:active {
    scale: 0.97;
  }

  /* La flecha de los atajos de la portada se adelanta al pasar por encima. */
  .atajo-flecha {
    transition: translate 160ms var(--llegada);
  }

  .atajo:hover .atajo-flecha {
    translate: 0.2rem 0;
  }

  /* ---------------- el logotipo, una vez, al cargar ---------------- */

  /* Las tres rayas se escriben como renglones y el pliegue se dobla. */
  .marca .marca-renglon,
  .marca .marca-pliegue {
    transform-box: fill-box;
  }

  .marca .marca-renglon {
    transform-origin: left center;
    animation: marca-renglon 520ms var(--llegada) both;
  }

  .marca .marca-renglon:nth-of-type(1) {
    animation-delay: 220ms;
  }

  .marca .marca-renglon:nth-of-type(2) {
    animation-delay: 330ms;
  }

  .marca .marca-renglon:nth-of-type(3) {
    animation-delay: 440ms;
  }

  .marca .marca-pliegue {
    transform-origin: right top;
    animation: marca-pliegue 420ms var(--llegada) 80ms both;
  }

  @keyframes marca-renglon {
    from {
      scale: 0 1;
    }
  }

  @keyframes marca-pliegue {
    from {
      opacity: 0;
      scale: 0.4;
    }
  }

  /* ---------------- la línea de lectura ---------------- */

  /* Atada al scroll de la página. Donde el navegador no sabe hacerlo, la raya
     se queda apagada (estilo.css) en vez de quieta. */
  @supports (animation-timeline: scroll()) {
    .progreso-lectura {
      display: block;
      animation: progreso-lectura auto linear both;
      animation-timeline: scroll(root);
    }
  }

  @keyframes progreso-lectura {
    from {
      scale: 0 1;
    }

    to {
      scale: 1 1;
    }
  }

  /* ---------------- la demostración de la portada ---------------- */

  /*
    4,8 segundos, a propósito por debajo de cinco: lo que se mueve solo más de
    cinco segundos junto a otro contenido necesitaría un botón de pausa.

    El fotograma 0 es el estado final, el mismo que está dibujado en
    estilo.css. Por eso la escena puede arrancar estando ya a la vista sin
    que se note el salto: primero se recoge y luego se vuelve a contar.

      0–6 %    se recoge lo que había
      8–17 %   llega la factura
      19–52 %  se lee dato a dato; cada impulso lleva su dato a la celda
      52–86 %  cuadra, «¿La mando a la hoja?», y el «Sí»
      82–91 %  la fila queda confirmada
  */
  .demo.animable .demo-factura,
  .demo.animable .demo-dato::before,
  .demo.animable .demo-impulso,
  .demo.animable .demo-celda,
  .demo.animable .demo-fila-nueva::before,
  .demo.animable .demo-visto,
  .demo.animable .demo-estado,
  .demo.animable .demo-cuadra,
  .demo.animable .demo-si,
  .demo.animable .demo-si::after {
    animation-duration: 4.8s;
    animation-fill-mode: both;
    animation-play-state: var(--reproduccion);
  }

  .demo.animable .demo-factura {
    animation-name: portada-factura;
  }

  .demo.animable .demo-dato-1::before {
    animation-name: portada-leer-1;
  }

  .demo.animable .demo-dato-2::before {
    animation-name: portada-leer-2;
  }

  .demo.animable .demo-dato-3::before {
    animation-name: portada-leer-3;
  }

  .demo.animable .demo-dato-4::before {
    animation-name: portada-leer-4;
  }

  .demo.animable .demo-impulso-1 {
    animation-name: portada-impulso-1;
  }

  .demo.animable .demo-impulso-2 {
    animation-name: portada-impulso-2;
  }

  .demo.animable .demo-impulso-3 {
    animation-name: portada-impulso-3;
  }

  .demo.animable .demo-impulso-4 {
    animation-name: portada-impulso-4;
  }

  .demo.animable .demo-celda-1 {
    animation-name: portada-celda-1;
  }

  .demo.animable .demo-celda-2 {
    animation-name: portada-celda-2;
  }

  .demo.animable .demo-celda-3 {
    animation-name: portada-celda-3;
  }

  .demo.animable .demo-celda-4 {
    animation-name: portada-celda-4;
  }

  .demo.animable .demo-fila-nueva::before {
    animation-name: portada-pendiente;
  }

  .demo.animable .demo-visto {
    animation-name: portada-visto;
  }

  .demo.animable .demo-estado-leyendo {
    animation-name: portada-leyendo;
  }

  .demo.animable .demo-estado-pregunta {
    animation-name: portada-pregunta;
  }

  .demo.animable .demo-estado-hecho {
    animation-name: portada-hecho;
  }

  .demo.animable .demo-cuadra {
    animation-name: portada-cuadra;
  }

  .demo.animable .demo-si {
    animation-name: portada-si;
  }

  .demo.animable .demo-si::after {
    animation-name: portada-si-toque;
  }

  @keyframes portada-factura {
    0% {
      opacity: 1;
      translate: 0 0;
      rotate: -2.5deg;
      animation-timing-function: var(--salida);
    }

    6% {
      opacity: 0;
      translate: 0 0.6em;
      rotate: -2.5deg;
    }

    8% {
      opacity: 0;
      translate: 0 -1.4em;
      rotate: -8deg;
      animation-timing-function: var(--llegada);
    }

    17%,
    100% {
      opacity: 1;
      translate: 0 0;
      rotate: -2.5deg;
    }
  }

  /* La marca de «leído», un dato detrás de otro. */
  @keyframes portada-leer-1 {
    0%,
    6% {
      scale: 1 1;
    }

    7%,
    19% {
      scale: 0 1;
      animation-timing-function: var(--llegada);
    }

    23%,
    100% {
      scale: 1 1;
    }
  }

  @keyframes portada-leer-2 {
    0%,
    6% {
      scale: 1 1;
    }

    7%,
    26% {
      scale: 0 1;
      animation-timing-function: var(--llegada);
    }

    30%,
    100% {
      scale: 1 1;
    }
  }

  @keyframes portada-leer-3 {
    0%,
    6% {
      scale: 1 1;
    }

    7%,
    33% {
      scale: 0 1;
      animation-timing-function: var(--llegada);
    }

    37%,
    100% {
      scale: 1 1;
    }
  }

  @keyframes portada-leer-4 {
    0%,
    6% {
      scale: 1 1;
    }

    7%,
    40% {
      scale: 0 1;
      animation-timing-function: var(--llegada);
    }

    44%,
    100% {
      scale: 1 1;
    }
  }

  /* Cada impulso sale de su dato cuando se lee y cae en su celda. */
  @keyframes portada-impulso-1 {
    0%,
    20% {
      opacity: 0;
      translate: var(--x0, 0px) var(--y0, 0px);
    }

    22% {
      opacity: 1;
      translate: var(--x0, 0px) var(--y0, 0px);
      animation-timing-function: var(--viaje);
    }

    28% {
      opacity: 1;
      translate: var(--x1, 0px) var(--y1, 0px);
    }

    31%,
    100% {
      opacity: 0;
      translate: var(--x1, 0px) var(--y1, 0px);
    }
  }

  @keyframes portada-impulso-2 {
    0%,
    27% {
      opacity: 0;
      translate: var(--x0, 0px) var(--y0, 0px);
    }

    29% {
      opacity: 1;
      translate: var(--x0, 0px) var(--y0, 0px);
      animation-timing-function: var(--viaje);
    }

    35% {
      opacity: 1;
      translate: var(--x1, 0px) var(--y1, 0px);
    }

    38%,
    100% {
      opacity: 0;
      translate: var(--x1, 0px) var(--y1, 0px);
    }
  }

  @keyframes portada-impulso-3 {
    0%,
    34% {
      opacity: 0;
      translate: var(--x0, 0px) var(--y0, 0px);
    }

    36% {
      opacity: 1;
      translate: var(--x0, 0px) var(--y0, 0px);
      animation-timing-function: var(--viaje);
    }

    42% {
      opacity: 1;
      translate: var(--x1, 0px) var(--y1, 0px);
    }

    45%,
    100% {
      opacity: 0;
      translate: var(--x1, 0px) var(--y1, 0px);
    }
  }

  @keyframes portada-impulso-4 {
    0%,
    41% {
      opacity: 0;
      translate: var(--x0, 0px) var(--y0, 0px);
    }

    43% {
      opacity: 1;
      translate: var(--x0, 0px) var(--y0, 0px);
      animation-timing-function: var(--viaje);
    }

    49% {
      opacity: 1;
      translate: var(--x1, 0px) var(--y1, 0px);
    }

    52%,
    100% {
      opacity: 0;
      translate: var(--x1, 0px) var(--y1, 0px);
    }
  }

  /* La celda se rellena justo cuando le llega su impulso. */
  @keyframes portada-celda-1 {
    0%,
    4% {
      opacity: 1;
      translate: 0 0;
    }

    7% {
      opacity: 0;
      translate: 0 0;
    }

    27% {
      opacity: 0;
      translate: 0 0.35em;
      animation-timing-function: var(--llegada);
    }

    31%,
    100% {
      opacity: 1;
      translate: 0 0;
    }
  }

  @keyframes portada-celda-2 {
    0%,
    4% {
      opacity: 1;
      translate: 0 0;
    }

    7% {
      opacity: 0;
      translate: 0 0;
    }

    34% {
      opacity: 0;
      translate: 0 0.35em;
      animation-timing-function: var(--llegada);
    }

    38%,
    100% {
      opacity: 1;
      translate: 0 0;
    }
  }

  @keyframes portada-celda-3 {
    0%,
    4% {
      opacity: 1;
      translate: 0 0;
    }

    7% {
      opacity: 0;
      translate: 0 0;
    }

    41% {
      opacity: 0;
      translate: 0 0.35em;
      animation-timing-function: var(--llegada);
    }

    45%,
    100% {
      opacity: 1;
      translate: 0 0;
    }
  }

  @keyframes portada-celda-4 {
    0%,
    4% {
      opacity: 1;
      translate: 0 0;
    }

    7% {
      opacity: 0;
      translate: 0 0;
    }

    48% {
      opacity: 0;
      translate: 0 0.35em;
      animation-timing-function: var(--llegada);
    }

    52%,
    100% {
      opacity: 1;
      translate: 0 0;
    }
  }

  /* La fila discontinua mientras está pendiente de revisar. */
  @keyframes portada-pendiente {
    0%,
    8% {
      opacity: 0;
    }

    12%,
    80% {
      opacity: 1;
    }

    85%,
    100% {
      opacity: 0;
    }
  }

  @keyframes portada-visto {
    0%,
    3% {
      opacity: 1;
      scale: 1;
    }

    6%,
    82% {
      opacity: 0;
      scale: 0.4;
      animation-timing-function: var(--llegada);
    }

    88%,
    100% {
      opacity: 1;
      scale: 1;
    }
  }

  /* «Leyendo la factura…»: lo que hace creíble que al otro lado hay algo
     leyendo. */
  @keyframes portada-leyendo {
    0%,
    9% {
      opacity: 0;
      translate: 0 0.35em;
      animation-timing-function: var(--llegada);
    }

    14%,
    50% {
      opacity: 1;
      translate: 0 0;
    }

    53%,
    100% {
      opacity: 0;
      translate: 0 -0.25em;
    }
  }

  @keyframes portada-pregunta {
    0%,
    52% {
      opacity: 0;
      translate: 0 0.4em;
      animation-timing-function: var(--llegada);
    }

    57%,
    82% {
      opacity: 1;
      translate: 0 0;
    }

    86%,
    100% {
      opacity: 0;
      translate: 0 -0.25em;
    }
  }

  @keyframes portada-cuadra {
    0%,
    54% {
      scale: 0.6;
      animation-timing-function: var(--llegada);
    }

    60%,
    100% {
      scale: 1;
    }
  }

  @keyframes portada-si {
    0%,
    72% {
      scale: 1;
    }

    75% {
      scale: 0.86;
    }

    79%,
    100% {
      scale: 1;
    }
  }

  @keyframes portada-si-toque {
    0%,
    73% {
      opacity: 0;
      scale: 0.7;
    }

    75% {
      opacity: 0.9;
      scale: 0.9;
      animation-timing-function: var(--llegada);
    }

    84%,
    100% {
      opacity: 0;
      scale: 1.35;
    }
  }

  @keyframes portada-hecho {
    0%,
    3% {
      opacity: 1;
      translate: 0 0;
    }

    6%,
    85% {
      opacity: 0;
      translate: 0 0.4em;
      animation-timing-function: var(--llegada);
    }

    91%,
    100% {
      opacity: 1;
      translate: 0 0;
    }
  }

  /* ---------------- las cajas: cómo va ---------------- */

  /* Llega: cada factura cae desde su canal a la misma bandeja. */
  .escena-llega.animable .llega-papel {
    animation: llega-caer 640ms var(--llegada) both;
    animation-play-state: var(--reproduccion);
  }

  .escena-llega.animable .llega-papel-1 {
    animation-delay: 150ms;
  }

  .escena-llega.animable .llega-papel-2 {
    animation-delay: 420ms;
  }

  .escena-llega.animable .llega-papel-3 {
    animation-delay: 690ms;
  }

  @keyframes llega-caer {
    0% {
      opacity: 0;
      translate: var(--caida) -3.4rem;
      rotate: 0deg;
    }

    35% {
      opacity: 1;
    }

    100% {
      opacity: 1;
      translate: var(--x) 0;
      rotate: var(--giro);
    }
  }

  /* Se lee: se marcan tres datos y el IRPF aparece vacío. */
  .escena-lee.animable .lee-renglon:not(.lee-vacio)::before {
    animation: marcar 380ms var(--llegada) both;
    animation-play-state: var(--reproduccion);
  }

  .escena-lee.animable .lee-renglon:nth-child(1)::before {
    animation-delay: 200ms;
  }

  .escena-lee.animable .lee-renglon:nth-child(2)::before {
    animation-delay: 480ms;
  }

  .escena-lee.animable .lee-renglon:nth-child(3)::before {
    animation-delay: 760ms;
  }

  .escena-lee.animable .lee-guion {
    animation: aparecer 320ms var(--llegada) 1080ms both;
    animation-play-state: var(--reproduccion);
  }

  /* Va a su sitio: entra la fila, se confirma, y la repetida rebota. */
  .escena-sitio.animable .sitio-nueva {
    animation: sitio-entrar 520ms var(--llegada) 180ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-sitio.animable .sitio-visto {
    animation: estampar 420ms var(--llegada) 640ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-sitio.animable .sitio-duplicada {
    animation: sitio-rebotar 1150ms ease-out 1150ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes sitio-entrar {
    from {
      opacity: 0;
      translate: -2.6rem 0;
    }
  }

  @keyframes sitio-rebotar {
    0% {
      opacity: 0;
      translate: -2.6rem 0;
      animation-timing-function: var(--salida);
    }

    30% {
      opacity: 1;
      translate: 0 0;
      animation-timing-function: ease-out;
    }

    40% {
      translate: -0.5rem 0;
    }

    50% {
      translate: 0.28rem 0;
    }

    60% {
      translate: -0.12rem 0;
    }

    78% {
      opacity: 1;
      translate: 0 0;
    }

    100% {
      opacity: 0;
      translate: 0 0.3rem;
    }
  }

  /* ---------------- las cajas: canales ---------------- */

  /* Web: el archivo llega arrastrado, se suelta y el borde se cierra. */
  .escena-web.animable .web-arrastre {
    animation: web-arrastrar 900ms var(--llegada) 150ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-web.animable .web-cursor {
    animation: web-soltar 1400ms linear 150ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-web.animable .web-zona::after {
    animation: aparecer 260ms var(--llegada) 1000ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes web-arrastrar {
    0% {
      opacity: 0;
      translate: 3.2rem -2.6rem;
      rotate: 10deg;
    }

    15% {
      opacity: 1;
    }

    100% {
      opacity: 1;
      translate: 0 0;
      rotate: 0deg;
    }
  }

  /* El cursor viene con el archivo, lo suelta y se aparta. */
  @keyframes web-soltar {
    0%,
    66% {
      opacity: 1;
      translate: 0 0;
    }

    100% {
      opacity: 0;
      translate: 0.7rem 0.6rem;
    }
  }

  /* Telegram y WhatsApp: sale el mensaje, se escribe, contesta. */
  .escena-chat.animable .chat-sale {
    animation: chat-subir 440ms var(--llegada) 180ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-chat.animable .chat-escribiendo {
    animation: chat-escribir 1000ms linear both;
    animation-play-state: var(--reproduccion);
  }

  .escena-chat.animable .chat-escribiendo span {
    animation: chat-punto 500ms ease-in-out 2 both;
    animation-play-state: var(--reproduccion);
  }

  .escena-chat.animable .chat-entra {
    animation: chat-subir 440ms var(--llegada) both;
    animation-play-state: var(--reproduccion);
  }

  [data-escena="telegram"].animable .chat-escribiendo {
    animation-delay: 720ms;
  }

  [data-escena="telegram"].animable .chat-escribiendo span:nth-child(1) {
    animation-delay: 720ms;
  }

  [data-escena="telegram"].animable .chat-escribiendo span:nth-child(2) {
    animation-delay: 840ms;
  }

  [data-escena="telegram"].animable .chat-escribiendo span:nth-child(3) {
    animation-delay: 960ms;
  }

  [data-escena="telegram"].animable .chat-entra {
    animation-delay: 1700ms;
  }

  /* En WhatsApp, además, los dos tics antes de que conteste. */
  [data-escena="whatsapp"].animable .chat-tic-1 {
    animation: aparecer 200ms ease-out 620ms both;
    animation-play-state: var(--reproduccion);
  }

  [data-escena="whatsapp"].animable .chat-tic-2 {
    animation: aparecer 200ms ease-out 920ms both;
    animation-play-state: var(--reproduccion);
  }

  [data-escena="whatsapp"].animable .chat-escribiendo {
    animation-delay: 1150ms;
  }

  [data-escena="whatsapp"].animable .chat-escribiendo span:nth-child(1) {
    animation-delay: 1150ms;
  }

  [data-escena="whatsapp"].animable .chat-escribiendo span:nth-child(2) {
    animation-delay: 1270ms;
  }

  [data-escena="whatsapp"].animable .chat-escribiendo span:nth-child(3) {
    animation-delay: 1390ms;
  }

  [data-escena="whatsapp"].animable .chat-entra {
    animation-delay: 2150ms;
  }

  @keyframes chat-subir {
    from {
      opacity: 0;
      translate: 0 0.9rem;
      scale: 0.94;
    }
  }

  /* Los puntos suspensivos antes de contestar. */
  @keyframes chat-escribir {
    0% {
      opacity: 0;
    }

    12%,
    88% {
      opacity: 1;
    }

    100% {
      opacity: 0;
    }
  }

  @keyframes chat-punto {
    0%,
    100% {
      opacity: 0.45;
      translate: 0 0;
    }

    50% {
      opacity: 1;
      translate: 0 -0.2rem;
    }
  }

  /* ---------------- las cajas: tus datos ---------------- */

  /* En la UE: el documento baja a su cajón y la etiqueta se estampa. */
  .escena-ue.animable .ue-documento {
    animation: ue-archivar 620ms var(--llegada) 180ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-ue.animable .ue-etiqueta {
    animation: estampar 420ms var(--llegada) 860ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes ue-archivar {
    from {
      opacity: 0;
      translate: 0 -2.8rem;
    }

    30% {
      opacity: 1;
    }
  }

  /* Seis años: la rueda sube hasta el 6 mientras la regla se llena. */
  .escena-anos.animable .anos-cinta {
    animation: anos-rodar 1400ms cubic-bezier(0.2, 0.7, 0.15, 1) 160ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-anos.animable .anos-relleno {
    animation: marcar 1400ms cubic-bezier(0.2, 0.7, 0.15, 1) 160ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes anos-rodar {
    from {
      translate: 0 0;
    }
  }

  /* Bajo llave: cae el arco y el cuerpo acusa el golpe. */
  .escena-llave.animable .candado-arco {
    animation: llave-cerrar 560ms 320ms both;
    animation-play-state: var(--reproduccion);
  }

  .escena-llave.animable .candado {
    animation: llave-golpe 560ms 320ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes llave-cerrar {
    0% {
      translate: 0 -10px;
      animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45);
    }

    64% {
      translate: 0 1.5px;
      animation-timing-function: ease-out;
    }

    100% {
      translate: 0 0;
    }
  }

  @keyframes llave-golpe {
    0%,
    62% {
      scale: 1;
    }

    76% {
      scale: 1.035 0.955;
    }

    100% {
      scale: 1;
    }
  }

  /* ---------------- el «Sí.» ---------------- */

  /*
    No se desliza: se estampa, porque es una promesa y no una lista. Es el
    único texto de la página que se anima, y por eso va dentro del margen de
    NN/g para un texto que aparece —de 100 a 400 ms— y sin retraso: a los
    190 ms ya se lee. La tinta es adorno y va detrás, sin tapar nada.
  */
  .criba .rotundo.animable {
    animation: estampar-si 350ms var(--llegada) both;
    animation-play-state: var(--reproduccion);
  }

  .criba .rotundo.animable::after {
    animation: tinta 600ms var(--llegada) 190ms both;
    animation-play-state: var(--reproduccion);
  }

  @keyframes estampar-si {
    0% {
      opacity: 0;
      scale: 1.9;
    }

    55% {
      opacity: 1;
      scale: 0.93;
    }

    78% {
      scale: 1.02;
    }

    100% {
      opacity: 1;
      scale: 1;
    }
  }

  /* El 1 % en blanco es para que la tinta no esté ya ahí mientras espera. */
  @keyframes tinta {
    0% {
      opacity: 0;
      scale: 0.55;
    }

    1% {
      opacity: 0.75;
      scale: 0.55;
    }

    100% {
      opacity: 0;
      scale: 1.7;
    }
  }

  /* ---------------- piezas comunes ---------------- */

  @keyframes aparecer {
    from {
      opacity: 0;
    }
  }

  @keyframes marcar {
    from {
      scale: 0 1;
    }
  }

  @keyframes estampar {
    0% {
      opacity: 0;
      scale: 1.8;
    }

    60% {
      opacity: 1;
      scale: 0.92;
    }

    100% {
      opacity: 1;
      scale: 1;
    }
  }
}

/* ---------------- la calculadora ---------------- */

@media (prefers-reduced-motion: no-preference) {
  /* Las barras crecen o encogen con transform: al mover un deslizador, la
     diferencia se ve cambiar en vez de saltar. */
  .calculadora .calc-barra {
    transition:
      scale 520ms var(--llegada),
      translate 520ms var(--llegada);
  }

  /* Los gráficos se descubren de izquierda a derecha la primera vez que se ven.
     El guion pone `sin-ver` antes de que lleguen y lo quita al llegar. Se
     recorta cada <svg>, nunca `.calc-graficos`, que es lo que mira el
     IntersectionObserver (la trampa del primer párrafo de este fichero). */
  .calculadora .grafico-svg {
    clip-path: inset(-6px);
    transition: clip-path 1200ms var(--llegada);
  }

  .calc-graficos.sin-ver .grafico-svg {
    clip-path: inset(-6px 100% -6px -6px);
  }

  .calc-graficos.sin-ver .calc-barra {
    scale: 0 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin movimiento no hay nada que volver a ver. */
  .demo-repetir {
    display: none;
  }
}

/* En papel todo tiene que estar en su estado final. Aquí sí vale el
   `!important`: una escena parada a medias no puede salir impresa. */
@media print {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  .progreso-lectura,
  .demo-repetir {
    display: none !important;
  }
}
