/* =====================================================================
   HIDRATACCIÓN — El personaje

   Va aparte de style.css a propósito: es una pieza que se saca de una página
   borrando dos líneas del HTML, y mezclarla en las 5.000 líneas de la hoja
   principal sería perder esa propiedad.

   Vive abajo a la izquierda. El botón de WhatsApp está abajo a la derecha
   (.wapp, z-index 120) y no se tocan nunca.

   Todo lo que se mueve es transform y opacity, como el resto del sitio: lo
   resuelve el compositor y no compite con el dibujo del sobre, que va por el
   hilo principal.
   ===================================================================== */

.avatar {
  /* El alto del MARCO de los sprites, no el del dibujo. Todas las poses vienen
     en un marco de 457x416 con el personaje apoyado abajo y al medio (ver
     scripts/recortar-avatar.mjs), así que el dibujo ocupa entre el 65% y el
     95% de este alto según la pose. Por eso el número es más grande de lo que
     mide el muñeco en pantalla. */
  --avatar-alto: clamp(8rem, 13vw, 11rem);
  --avatar-aire: clamp(1rem, 2.5vw, 1.75rem);

  position: fixed;
  left: var(--avatar-aire);
  bottom: var(--avatar-aire);
  z-index: 130;

  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;

  /* Entra desde abajo y crece. Arranca apagado: lo prende el puente cuando
     hay algo para decir, así no aparece en pantalla antes de tener motivo. */
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, 1.25rem, 0) scale(0.9);
  transform-origin: left bottom;
  transition:
    opacity 0.32s ease,
    transform 0.42s var(--transition-spring),
    visibility 0s linear 0.42s;
}

.avatar--presente {
  opacity: 1;
  visibility: visible;
  transform: translate3d(0, 0, 0) scale(1);
  transition:
    opacity 0.32s ease,
    transform 0.42s var(--transition-spring),
    visibility 0s;
}

/* ── Llegar e irse caminando ───────────────────────────────────────── */

/* Cuando puede caminar no entra creciendo: llega desde el borde de la
   pantalla, frena en su lugar y recién ahí habla (lo maneja crearViaje, en
   avatar-personaje.js). Mientras camina, la caja entera queda en su tamaño y
   sin la subida del fundido: lo único que se mueve es el muñeco.

   Estas dos reglas van DESPUÉS de .avatar--presente a propósito: tienen la
   misma especificidad y ganan por orden. */
.avatar--entra,
.avatar--sale {
  transform: none;
  transition: opacity 0.2s ease, visibility 0s;
}

/* Yéndose no se lo puede tocar: ya dijo que se va. */
.avatar--sale { pointer-events: none; }

/* El que viaja es el cuerpo —el muñeco con su aspa—, no el globo. Gira desde
   los pies, que es donde se apoya para inclinarse hacia donde va.

   El viaje no tiene velocidad propia: --avatar-viaje lo calcula el JS con la
   zancada y la cadencia del andar, así el paso y el piso coinciden. Por eso
   el traslado es lineal: el que camina va parejo, y lo que le da el frenazo
   es el golpecito de la escena al llegar, no una curva que lo vaya frenando
   con las piernas a toda marcha. */
.avatar__cuerpo { transform-origin: 50% 100%; }

.avatar--entra .avatar__cuerpo {
  animation: avatar-entra var(--avatar-viaje, 1.4s) linear both;
}
.avatar--sale .avatar__cuerpo {
  animation: avatar-sale var(--avatar-viaje, 1.4s) linear forwards;
}

/* La distancia es su propio ancho más el aire hasta el borde y un margen
   para la sombra: arranca —o termina— entero fuera de cuadro, y eso no
   depende del tamaño al que se lo dibuje. El margen tiene que coincidir con
   VIAJE_MARGEN_REM de avatar-personaje.js. */
@keyframes avatar-entra {
  0%   { transform: translate3d(calc(-100% - var(--avatar-aire, 1rem) - 1rem), 0, 0) rotate(3deg); }
  86%  { transform: translate3d(calc((-100% - var(--avatar-aire, 1rem) - 1rem) * 0.14), 0, 0) rotate(3deg); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}

@keyframes avatar-sale {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  14%  { transform: translate3d(calc((-100% - var(--avatar-aire, 1rem) - 1rem) * 0.14), 0, 0) rotate(-3deg); }
  100% { transform: translate3d(calc(-100% - var(--avatar-aire, 1rem) - 1rem), 0, 0) rotate(-3deg); }
}

/* ── Escuchar ──────────────────────────────────────────────────────── */

/* Mientras le escriben se inclina hacia el globo, que está arriba y a su
   derecha. Va en la escena, que en reposo no tiene ninguna transformación
   propia: las capas ya tienen tomada la suya con el respirar. Cuando salta el
   golpecito de cambio de cara, la animación le gana a esto mientras dura y
   después vuelve a quedar inclinado. */
.avatar .avatar__escena {
  transform-origin: 50% 100%;
  transition: transform 0.5s var(--transition-spring);
}

.avatar[data-escucha='true'] .avatar__escena {
  transform: translate3d(0.15rem, -0.1rem, 0) rotate(3deg);
}

/* ── El muñeco ─────────────────────────────────────────────────────── */

/* El muñeco y su aspa van juntos acá para que el aspa se cuelgue de la esquina
   del marco y no del rincón de la pantalla. */
.avatar__cuerpo {
  position: relative;
  display: block;
}

.avatar__munieco {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  /* El área táctil real es la imagen; el borde de foco sigue su forma. */
  border-radius: 1rem;
  transition: transform 0.3s var(--transition-spring);
}

/* La escena: la caja donde vive el muñeco, sea por capas o de una pieza. Le
   da el tamaño —se lo pone la estampa, que trae la proporción del marco en
   sus atributos width/height— y se queda con el golpe del cambio de cara.
   El respirar va adentro, en las capas, para que los dos transform no se
   pisen: el CSS deja ganar a una sola animación por propiedad. */
.avatar__escena {
  position: relative;
  display: block;
  /* La sombra del piso va en el filtro y no en un pseudo-elemento: así sigue
     la silueta recortada —que cambia con cada pose— en vez de ser una elipse
     debajo de un rectángulo. Dos capas: una pegada, que apoya al personaje,
     y una abierta y teñida de marca, que lo despega del fondo. */
  filter:
    drop-shadow(0 2px 3px rgba(6, 95, 117, 0.22))
    drop-shadow(0 12px 22px rgba(14, 164, 207, 0.28));
}

.avatar__pose {
  display: block;
  height: var(--avatar-alto);
  width: auto;
}

/* ── El muñeco por capas ───────────────────────────────────────────── */

/* Se apila encima de la estampa, del mismo tamaño y en la misma posición: los
   archivos de las capas vienen todos del mismo marco, así que no hay nada que
   acomodar. Las dos nunca se ven a la vez. */
.munieco {
  position: absolute;
  inset: 0;
}

.munieco__capa {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* El punto de giro lo pone el JS con los datos que generó el script: es
     dónde cae el hombro de cada brazo dentro del marco. */
}

/* Reposo articulado: la estampa se esconde pero sigue ocupando su lugar, que
   es lo que le da el tamaño a la escena. */
.avatar[data-articulado='true']  .avatar__pose { visibility: hidden; }
/* Estampa fija: las capas se sacan del todo, no solo se ocultan, para que no
   queden animaciones corriendo sobre algo que nadie ve. */
.avatar[data-articulado='false'] .munieco     { display: none; }

/* ── Respirar ──────────────────────────────────────────────────────── */

/* Sube y baja un poco mientras se ensancha y se afina: las dos cosas en una
   sola animación porque van sobre la misma propiedad. Lo llevan tanto las
   capas como la estampa, así que las catorce poses respiran, no solo la
   articulada. */
.munieco,
.avatar__pose {
  transform-origin: 50% 100%;
  animation: avatar-respira 3.6s ease-in-out infinite;
}

@keyframes avatar-respira {
  0%, 100% { transform: translate3d(0, 0, 0)         scale3d(1, 1, 1); }
  50%      { transform: translate3d(0, -0.35rem, 0)  scale3d(0.993, 1.014, 1); }
}

/* Los brazos van un poco atrasados respecto del cuerpo. Eso es lo que en
   animación llaman arrastre: si todo se mueve exactamente junto, se lee como
   una imagen escalando; si las puntas llegan tarde, se lee como un cuerpo. */
.munieco__capa--brazo-izq {
  animation: avatar-brazo-izq 3.6s ease-in-out -0.35s infinite;
}
.munieco__capa--brazo-der {
  animation: avatar-brazo-der 3.6s ease-in-out -0.5s infinite;
}

@keyframes avatar-brazo-izq {
  0%, 100% { transform: rotate(0deg); }
  50%      { transform: rotate(-3.2deg); }
}
@keyframes avatar-brazo-der {
  0%, 100% { transform: rotate(0deg); }
  50%      { transform: rotate(3.2deg); }
}

/* ── Parpadear ─────────────────────────────────────────────────────── */

/* En reposo el párpado está aplastado contra el borde de arriba del ojo y no
   se ve. Parpadear es estirarlo hacia abajo y volver. Así no hubo que borrar
   el ojo abierto ni repintar la cara debajo. */
.munieco__capa--parpado-izq,
.munieco__capa--parpado-der {
  transform: scaleY(0);
}

.munieco--parpadea .munieco__capa--parpado-izq {
  animation: avatar-parpadeo 190ms ease-in-out;
}
/* El otro ojo, veinticinco milisegundos después. Dos párpados perfectamente
   sincronizados se leen como un obturador; desfasados, como una cara. */
.munieco--parpadea .munieco__capa--parpado-der {
  animation: avatar-parpadeo 190ms ease-in-out 25ms;
}

@keyframes avatar-parpadeo {
  0%        { transform: scaleY(0); }
  40%, 60%  { transform: scaleY(1); }
  100%      { transform: scaleY(0); }
}

/* ── La espuma arrastra ────────────────────────────────────────────── */

/* Va medio segundo atrás del cuerpo: la espuma es lo único del dibujo que
   debería tener inercia propia, y cuando la tiene el personaje deja de
   parecer una calcomanía.

   Se BAMBOLEA, no gira (2026-10-01). Girando desde el centro de su base, las
   puntas de la línea de gotas subían y bajaban tres o cuatro píxeles, y con
   ellas la franja de vaso que la capa trae por debajo: se veía la espuma
   despegándose del vaso. Inclinada de costado (skew) y estirada para arriba
   desde la base, la base no se mueve nunca —el punto de giro de la capa es
   su borde de abajo— y lo que se mece es la copa, que es donde la inercia se
   tiene que ver. */
.munieco__capa--espuma {
  animation: avatar-espuma 3.6s ease-in-out -0.62s infinite;
}

@keyframes avatar-espuma {
  0%, 100% { transform: skewX(0deg)    scale(1, 1); }
  50%      { transform: skewX(-1.6deg) scale(1, 1.025); }
}

/* ── La mirada ─────────────────────────────────────────────────────── */

/* Cada ojo va adentro de una caja recortada con su propia forma —la máscara la
   pone el JS, que es quien sabe de dónde salen los archivos— y lo que se mueve
   es la imagen de adentro. Así el ojo se corre hasta el borde y lo que se pasa
   se corta, en vez de andar la pupila suelta por la cara. */
.munieco__capa--pupila-izq,
.munieco__capa--pupila-der {
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Las pupilas las mueve el JS, que es el que sabe dónde está el cursor, y
   también las suaviza, cuadro a cuadro (ver la mirada en avatar-articulado.js).
   Sin transición acá a propósito: una transición de CSS que se corta y vuelve
   a empezar con cada movimiento del mouse era justo lo que hacía que la
   mirada fuera atrasada y a los tirones con el mouse rápido. */
.munieco__pupila {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ── Hablar ────────────────────────────────────────────────────────── */

/* La boca se abre y se cierra sobre la línea de sus comisuras, que es el punto
   de giro que le pone el JS con lo que midió el script. Las dos puntas se
   quedan clavadas ahí y lo que sube y baja es el medio: el labio de arriba y
   el de abajo se acercan a esa línea y se separan, que es como se abre una
   boca de verdad.

   Solo escala en Y. Con escala en X también —como estaba antes— las puntas se
   corrían hacia adentro y la boca parecía encogerse entera en vez de abrirse.

   Los tiempos son irregulares a propósito: una boca que sube y baja como un
   metrónomo se lee como una máquina, no como alguien diciendo algo. */
.munieco--habla .munieco__capa--boca {
  animation: avatar-habla 0.62s ease-in-out infinite;
}

@keyframes avatar-habla {
  0%   { transform: scaleY(1); }
  12%  { transform: scaleY(0.42); }
  26%  { transform: scaleY(0.92); }
  40%  { transform: scaleY(0.5); }
  55%  { transform: scaleY(1); }
  70%  { transform: scaleY(0.46); }
  85%  { transform: scaleY(0.84); }
  100% { transform: scaleY(1); }
}

/* ── Los andares ───────────────────────────────────────────────────── */

/* Caminar y correr no son gestos: no duran un rato y se terminan solos, duran
   hasta que se los saque. Por eso se prenden y se apagan como hablar, y no se
   piden con animar().

   El dibujo no tiene piernas sueltas —el cuerpo vino entero, con las dos
   adentro— así que el paso no se puede articular. Lo que hace este andar es lo
   que hace el dibujo animado cuando no puede mover una pierna: el cuerpo
   rebota dos veces por ciclo, se achata al apoyar, se mece una vez por ciclo y
   los brazos bombean cruzados. El ojo lo lee como caminar aunque no vea un
   paso, porque lo que reconoce es la cadencia, no la pierna.

   Las dos frecuencias van en la MISMA animación del cuerpo. El rebote es del
   doble que la mecida, y como el CSS deja ganar una sola animación por
   propiedad, en dos reglas separadas una se comería a la otra. Escritas juntas
   en los mismos keyframes, conviven.

   Lo que dura un ciclo se puede cambiar de afuera con --munieco-ciclo, porque
   quien mueva al personaje por la pantalla necesita que el viaje y la cadencia
   vayan al mismo ritmo: si no, patina. */
.munieco--camina { animation: avatar-camina var(--munieco-ciclo, 0.72s) ease-in-out infinite; }
.munieco--corre  { animation: avatar-corre  var(--munieco-ciclo, 0.46s) ease-in-out infinite; }

@keyframes avatar-camina {
  0%   { transform: translate3d(0,  0.12rem, 0) scale3d(1.032, 0.968, 1) rotate(2deg); }
  15%  { transform: translate3d(0, -0.42rem, 0) scale3d(0.99,  1.01,  1) rotate(1.2deg); }
  30%  { transform: translate3d(0, -0.06rem, 0) scale3d(1,     1,     1) rotate(0deg); }
  50%  { transform: translate3d(0,  0.12rem, 0) scale3d(1.032, 0.968, 1) rotate(-2deg); }
  65%  { transform: translate3d(0, -0.42rem, 0) scale3d(0.99,  1.01,  1) rotate(-1.2deg); }
  80%  { transform: translate3d(0, -0.06rem, 0) scale3d(1,     1,     1) rotate(0deg); }
  100% { transform: translate3d(0,  0.12rem, 0) scale3d(1.032, 0.968, 1) rotate(2deg); }
}

/* Correr es el mismo ciclo con el volumen más arriba: despega más, se achata
   más al caer y se mece menos —el que corre va más derecho que el que pasea—. */
@keyframes avatar-corre {
  0%   { transform: translate3d(0,  0.22rem, 0) scale3d(1.07,  0.93,  1) rotate(1.4deg); }
  15%  { transform: translate3d(0, -0.95rem, 0) scale3d(0.955, 1.045, 1) rotate(0.8deg); }
  32%  { transform: translate3d(0, -0.18rem, 0) scale3d(1,     1,     1) rotate(0deg); }
  50%  { transform: translate3d(0,  0.22rem, 0) scale3d(1.07,  0.93,  1) rotate(-1.4deg); }
  65%  { transform: translate3d(0, -0.95rem, 0) scale3d(0.955, 1.045, 1) rotate(-0.8deg); }
  82%  { transform: translate3d(0, -0.18rem, 0) scale3d(1,     1,     1) rotate(0deg); }
  100% { transform: translate3d(0,  0.22rem, 0) scale3d(1.07,  0.93,  1) rotate(1.4deg); }
}

/* Los brazos van cruzados: cuando uno se abre, el otro se recoge. Un ciclo
   entero de brazos son dos rebotes de cuerpo, que es la relación que tiene un
   caminar de verdad —se pisa dos veces por cada vaivén de brazo—. */
.munieco--camina .munieco__capa--brazo-der { animation: avatar-camina-der var(--munieco-ciclo, 0.72s) ease-in-out infinite; }
.munieco--camina .munieco__capa--brazo-izq { animation: avatar-camina-izq var(--munieco-ciclo, 0.72s) ease-in-out infinite; }
.munieco--corre  .munieco__capa--brazo-der { animation: avatar-corre-der  var(--munieco-ciclo, 0.46s) ease-in-out infinite; }
.munieco--corre  .munieco__capa--brazo-izq { animation: avatar-corre-izq  var(--munieco-ciclo, 0.46s) ease-in-out infinite; }

@keyframes avatar-camina-der {
  0%, 100% { transform: rotate(15deg); }
  50%      { transform: rotate(-9deg); }
}
@keyframes avatar-camina-izq {
  0%, 100% { transform: rotate(9deg); }
  50%      { transform: rotate(-15deg); }
}
@keyframes avatar-corre-der {
  0%, 100% { transform: rotate(27deg); }
  50%      { transform: rotate(-17deg); }
}
@keyframes avatar-corre-izq {
  0%, 100% { transform: rotate(17deg); }
  50%      { transform: rotate(-27deg); }
}

/* La espuma va media cadencia atrás y salta con el cuerpo: es lo único del
   dibujo que tiene inercia propia, y cuando el vaso corre se nota el doble. */
.munieco--camina .munieco__capa--espuma { animation: avatar-camina-espuma var(--munieco-ciclo, 0.72s) ease-in-out -0.12s infinite; }
.munieco--corre  .munieco__capa--espuma { animation: avatar-corre-espuma  var(--munieco-ciclo, 0.46s) ease-in-out -0.09s infinite; }

/* Bamboleo y no giro, por lo mismo que en reposo: la base queda quieta. */
@keyframes avatar-camina-espuma {
  0%, 100% { transform: skewX(3deg)   scale(1, 0.98); }
  25%      { transform: skewX(-1.8deg) scale(1, 1.03); }
  50%      { transform: skewX(-3deg)  scale(1, 0.98); }
  75%      { transform: skewX(1.8deg) scale(1, 1.03); }
}
@keyframes avatar-corre-espuma {
  0%, 100% { transform: skewX(5deg)   scale(1, 0.95); }
  25%      { transform: skewX(-3deg)  scale(1, 1.06); }
  50%      { transform: skewX(-5deg)  scale(1, 0.95); }
  75%      { transform: skewX(3deg)   scale(1, 1.06); }
}

/* ── El corredor: caminar y correr con piernas ─────────────────────── */

/* Mientras camina o corre, el que se ve es el corredor (avatar-corredor.js):
   el personaje del vector de "Hidratación en movimiento", que sí tiene
   piernas. Las capas de reposo se apagan, y el rebote de arriba también:
   el corredor sube y baja con sus propias piernas. Si el corredor no está,
   nada de esto aplica y el andar es el rebote, como antes. */
/* Escondido con visibility y no con display: un display: none frena las
   animaciones de adentro, y al volver a mostrarse arrancan de cero. El banco
   le sincroniza un giro con el viaje por la pista, y desde cero quedaría
   desfasado. Lo que sí se apaga del todo son las del paso, que solo existen
   con el andar puesto. */
.munieco__corredor {
  position: absolute;
  inset: 0;
  visibility: hidden;
  transform-origin: 50% 100%;
}

.munieco__corredor > svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.munieco--con-corredor.munieco--camina .munieco__corredor,
.munieco--con-corredor.munieco--corre  .munieco__corredor { visibility: visible; }

.munieco--con-corredor.munieco--camina > .munieco__capa,
.munieco--con-corredor.munieco--corre  > .munieco__capa { display: none; }

.munieco--con-corredor.munieco--camina,
.munieco--con-corredor.munieco--corre { animation: none; }

/* Cada pieza tiene su articulación en el origen de su sistema de
   coordenadas —así lo arma el script—, y el CSS de un elemento SVG gira por
   omisión desde ahí. Se lo escribe igual, por si algún navegador sale de
   otra parte. Las unidades en px son unidades del dibujo. */
.corredor__cuerpo,
.corredor__pierna,
.corredor__muslo,
.corredor__tobillo,
.corredor__pie,
.corredor__brazo,
.corredor__espuma,
.corredor__iris {
  transform-origin: 0 0;
}

/* Los iris los mueve el JS, igual que las pupilas del muñeco de reposo, con
   el mismo suavizado por cuadro: sin transición de CSS, por lo mismo. */

/* ── Caminar ──
   Un ciclo son dos pasos. La pierna de adelante está apoyada del 0 al 50%
   y barre de -24° a +24° a ritmo parejo, con el pie plano: el pie gira al
   revés que la pierna, así que en el piso no se mueve. Al 60% despega con la
   punta, y para cruzar sin arrastrar el pie se acorta —es la rodilla que el
   dibujo no tiene—: el tubo se achica hacia la cadera y el pie sube lo mismo.
   La de atrás hace lo mismo medio ciclo después.

   El cuerpo baja dos unidades en cada apoyo doble y vuelve a subir cuando
   la pierna pasa por debajo: es lo que hace una pierna rígida, y es lo que
   mantiene el pie apoyado contra el piso mientras gira. */
.munieco--camina .corredor__pierna  { animation: corredor-camina-pierna  var(--munieco-ciclo, 0.72s) linear infinite; }
.munieco--camina .corredor__muslo   { animation: corredor-camina-muslo   var(--munieco-ciclo, 0.72s) linear infinite; }
.munieco--camina .corredor__tobillo { animation: corredor-camina-tobillo var(--munieco-ciclo, 0.72s) linear infinite; }
.munieco--camina .corredor__pie     { animation: corredor-camina-pie     var(--munieco-ciclo, 0.72s) linear infinite; }
.munieco--camina .corredor__cuerpo  { animation: corredor-camina-cuerpo  var(--munieco-ciclo, 0.72s) ease-in-out infinite; }
.munieco--camina .corredor__espuma  { animation: corredor-camina-espuma  var(--munieco-ciclo, 0.72s) ease-in-out -0.12s infinite; }
.munieco--camina .corredor__brazo--adelante { animation: corredor-camina-brazo-adelante var(--munieco-ciclo, 0.72s) ease-in-out infinite; }
.munieco--camina .corredor__brazo--atras    { animation: corredor-camina-brazo-atras    var(--munieco-ciclo, 0.72s) ease-in-out infinite; }

/* La pierna de atrás, medio ciclo corrida. Va después para que el retraso le
   gane a la regla de arriba sin necesitar más especificidad. */
.munieco--camina .corredor__pierna--lejos,
.munieco--camina .corredor__pierna--lejos .corredor__muslo,
.munieco--camina .corredor__pierna--lejos .corredor__tobillo,
.munieco--camina .corredor__pierna--lejos .corredor__pie {
  animation-delay: calc(var(--munieco-ciclo, 0.72s) * -0.5);
}

@keyframes corredor-camina-pierna {
  0%   { transform: rotate(-24deg); }
  50%  { transform: rotate(24deg); }
  60%  { transform: rotate(28deg); }
  80%  { transform: rotate(2deg); }
  95%  { transform: rotate(-26deg); }
  100% { transform: rotate(-24deg); }
}

/* Lo que se acorta la pierna, en unidades: 0 · 8 · 9 · 5 · 0,5 · 0, sobre
   24 de largo. El muslo escala a (24 − eso) / 24 y el tobillo sube eso
   mismo: las dos tablas tienen que coincidir o el pie se despega del tubo. */
@keyframes corredor-camina-muslo {
  0%, 48%  { transform: scale(1, 1); }
  60%      { transform: scale(1, 0.667); }
  70%      { transform: scale(1, 0.625); }
  82%      { transform: scale(1, 0.792); }
  94%      { transform: scale(1, 0.979); }
  100%     { transform: scale(1, 1); }
}
@keyframes corredor-camina-tobillo {
  0%, 48%  { transform: translate(0px, 0px); }
  60%      { transform: translate(0px, -8px); }
  70%      { transform: translate(0px, -9px); }
  82%      { transform: translate(0px, -5px); }
  94%      { transform: translate(0px, -0.5px); }
  100%     { transform: translate(0px, 0px); }
}

/* El pie gira desde el tobillo, y lo que importa es su ángulo contra el
   piso: el de la pierna más este. Apoya de talón con la punta un poco
   arriba, queda plano todo el apoyo, despega empujando con la punta y cruza
   con la punta hacia abajo. */
@keyframes corredor-camina-pie {
  0%   { transform: rotate(16deg); }
  6%   { transform: rotate(18.2deg); }
  48%  { transform: rotate(-22.1deg); }
  60%  { transform: rotate(-8deg); }
  70%  { transform: rotate(15deg); }
  82%  { transform: rotate(12.9deg); }
  94%  { transform: rotate(16.3deg); }
  100% { transform: rotate(16deg); }
}

@keyframes corredor-camina-cuerpo {
  0%, 50%, 100% { transform: translate(0px, 2.1px) rotate(0.5deg); }
  12.5%, 62.5%  { transform: translate(0px, 0.5px) rotate(0deg); }
  25%, 75%      { transform: translate(0px, -0.4px) rotate(-0.5deg); }
  37.5%, 87.5%  { transform: translate(0px, 0.5px) rotate(0deg); }
}

/* La espuma se bambolea desde su base —el pivote está en el borde del vaso—
   en vez de girar: girando, las puntas subían y bajaban y la base asomaba
   por encima del borde. Ver la espuma del muñeco de reposo. Se aplasta un
   poco con cada pisada y se estira cuando el cuerpo sube. */
@keyframes corredor-camina-espuma {
  0%, 50%, 100% { transform: skewX(2deg)    scale(1, 0.97); }
  25%, 75%      { transform: skewX(-1.5deg) scale(1, 1.03); }
}

/* Los brazos van cruzados con las piernas y entre sí. */
@keyframes corredor-camina-brazo-adelante {
  0%, 100% { transform: rotate(12deg); }
  50%      { transform: rotate(-14deg); }
}
@keyframes corredor-camina-brazo-atras {
  0%, 100% { transform: rotate(-10deg); }
  50%      { transform: rotate(12deg); }
}

/* ── Correr ──
   Lo que separa correr de caminar rápido es el vuelo: cada pie está apoyado
   menos de un tercio del ciclo, y entre que despega uno y apoya el otro no
   toca nada. La pierna barre más (-34° a +30°), despega empujando y patea
   para atrás doblada, y el cuerpo sube en el aire y cae en cada apoyo. */
.munieco--corre .corredor__pierna  { animation: corredor-corre-pierna  var(--munieco-ciclo, 0.46s) linear infinite; }
.munieco--corre .corredor__muslo   { animation: corredor-corre-muslo   var(--munieco-ciclo, 0.46s) linear infinite; }
.munieco--corre .corredor__tobillo { animation: corredor-corre-tobillo var(--munieco-ciclo, 0.46s) linear infinite; }
.munieco--corre .corredor__pie     { animation: corredor-corre-pie     var(--munieco-ciclo, 0.46s) linear infinite; }
.munieco--corre .corredor__cuerpo  { animation: corredor-corre-cuerpo  var(--munieco-ciclo, 0.46s) linear infinite; }
.munieco--corre .corredor__espuma  { animation: corredor-corre-espuma  var(--munieco-ciclo, 0.46s) ease-in-out -0.06s infinite; }
.munieco--corre .corredor__brazo--adelante { animation: corredor-corre-brazo-adelante var(--munieco-ciclo, 0.46s) ease-in-out infinite; }
.munieco--corre .corredor__brazo--atras    { animation: corredor-corre-brazo-atras    var(--munieco-ciclo, 0.46s) ease-in-out infinite; }

.munieco--corre .corredor__pierna--lejos,
.munieco--corre .corredor__pierna--lejos .corredor__muslo,
.munieco--corre .corredor__pierna--lejos .corredor__tobillo,
.munieco--corre .corredor__pierna--lejos .corredor__pie {
  animation-delay: calc(var(--munieco-ciclo, 0.46s) * -0.5);
}

@keyframes corredor-corre-pierna {
  0%   { transform: rotate(-34deg); }
  30%  { transform: rotate(30deg); }
  40%  { transform: rotate(26deg); }
  50%  { transform: rotate(14deg); }
  65%  { transform: rotate(-12deg); }
  80%  { transform: rotate(-32deg); }
  90%  { transform: rotate(-37deg); }
  100% { transform: rotate(-34deg); }
}

/* Acortes: 0 · 4 · 11 · 14 · 12 · 5 · 0, sobre 24. Ver caminar. */
@keyframes corredor-corre-muslo {
  0%, 22%  { transform: scale(1, 1); }
  30%      { transform: scale(1, 0.833); }
  40%      { transform: scale(1, 0.542); }
  50%      { transform: scale(1, 0.417); }
  65%      { transform: scale(1, 0.5); }
  80%      { transform: scale(1, 0.792); }
  92%, 100% { transform: scale(1, 1); }
}
@keyframes corredor-corre-tobillo {
  0%, 22%  { transform: translate(0px, 0px); }
  30%      { transform: translate(0px, -4px); }
  40%      { transform: translate(0px, -11px); }
  50%      { transform: translate(0px, -14px); }
  65%      { transform: translate(0px, -12px); }
  80%      { transform: translate(0px, -5px); }
  92%, 100% { transform: translate(0px, 0px); }
}

@keyframes corredor-corre-pie {
  0%   { transform: rotate(28deg); }
  5%   { transform: rotate(23.3deg); }
  22%  { transform: rotate(-12.9deg); }
  30%  { transform: rotate(-10deg); }
  40%  { transform: rotate(29deg); }
  50%  { transform: rotate(46deg); }
  65%  { transform: rotate(37deg); }
  80%  { transform: rotate(27deg); }
  90%  { transform: rotate(27deg); }
  100% { transform: rotate(28deg); }
}

/* Dos pasos por ciclo, así que la tabla se repite a la mitad. Apoya bajo
   (2,4), se endereza mientras la pierna pasa por debajo, despega para arriba
   y en el aire llega a lo más alto (-5,5) justo antes de caer en el otro pie.
   Se tira apenas para atrás al apoyar —frena— y para adelante al empujar. */
@keyframes corredor-corre-cuerpo {
  0%, 50%, 100% { transform: translate(0px, 2.4px)  rotate(-0.8deg); }
  7.5%, 57.5%   { transform: translate(0px, 1.4px)  rotate(-0.3deg); }
  15%, 65%      { transform: translate(0px, 0px)    rotate(0deg); }
  25%, 75%      { transform: translate(0px, 0.8px)  rotate(0.6deg); }
  30%, 80%      { transform: translate(0px, -3px)   rotate(1.2deg); }
  40%, 90%      { transform: translate(0px, -5.5px) rotate(0.8deg); }
}

/* Corriendo, el aplastón de cada apoyo y el estirón del vuelo se notan más. */
@keyframes corredor-corre-espuma {
  0%, 50%, 100% { transform: skewX(4deg)  scale(1, 0.93); }
  25%, 75%      { transform: skewX(-2deg) scale(1, 1.02); }
  37%, 87%      { transform: skewX(-3deg) scale(1, 1.07); }
}

@keyframes corredor-corre-brazo-adelante {
  0%, 100% { transform: rotate(22deg); }
  50%      { transform: rotate(-24deg); }
}
@keyframes corredor-corre-brazo-atras {
  0%, 100% { transform: rotate(-18deg); }
  50%      { transform: rotate(22deg); }
}

/* ── Los gestos ────────────────────────────────────────────────────── */

/* Todos se piden igual: una clase en .munieco que dura lo que dura la
   animación. Los que mueven el cuerpo entero PISAN el respirar, y los que
   mueven un brazo pisan su mecerse. No se suman: el CSS deja ganar a una
   sola animación por propiedad, y eso acá viene bien —mientras el personaje
   salta no tiene que estar respirando también—. */

/* Saludar con el brazo de arriba. */
.munieco--saluda .munieco__capa--brazo-der {
  animation: avatar-saluda 1.15s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}

@keyframes avatar-saluda {
  0%   { transform: rotate(0deg); }
  15%  { transform: rotate(-15deg); }
  38%  { transform: rotate(13deg); }
  60%  { transform: rotate(-11deg); }
  80%  { transform: rotate(8deg); }
  100% { transform: rotate(0deg); }
}

/* Festejar: los dos brazos al aire y un saltito. */
.munieco--festeja { animation: avatar-salta 0.95s cubic-bezier(0.34, 1.3, 0.64, 1); }
.munieco--festeja .munieco__capa--brazo-der { animation: avatar-festeja-der 0.95s ease-out; }
.munieco--festeja .munieco__capa--brazo-izq { animation: avatar-festeja-izq 0.95s ease-out; }

@keyframes avatar-festeja-der {
  0%   { transform: rotate(0deg); }
  30%  { transform: rotate(-26deg); }
  60%  { transform: rotate(-20deg); }
  100% { transform: rotate(0deg); }
}
@keyframes avatar-festeja-izq {
  0%   { transform: rotate(0deg); }
  30%  { transform: rotate(26deg); }
  60%  { transform: rotate(20deg); }
  100% { transform: rotate(0deg); }
}

/* Saltar. El achatarse antes de despegar y al caer es lo que le da peso; sin
   eso es un dibujo que sube y baja. */
.munieco--salta { animation: avatar-salta 0.95s cubic-bezier(0.34, 1.3, 0.64, 1); }

@keyframes avatar-salta {
  0%   { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1); }
  18%  { transform: translate3d(0, 0.18rem, 0)  scale3d(1.1, 0.86, 1); }
  45%  { transform: translate3d(0, -1.5rem, 0)  scale3d(0.93, 1.12, 1); }
  72%  { transform: translate3d(0, 0.12rem, 0)  scale3d(1.08, 0.9, 1); }
  100% { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1); }
}

/* Asentir: dos cabezadas cortas. Como el personaje es todo cabeza, la
   cabezada es del cuerpo entero inclinándose hacia adelante. */
.munieco--asiente { animation: avatar-asiente 0.9s ease-in-out; }

@keyframes avatar-asiente {
  0%, 100% { transform: translate3d(0, 0, 0)       rotate(0deg); }
  20%      { transform: translate3d(0, 0.28rem, 0) rotate(3.5deg); }
  40%      { transform: translate3d(0, 0, 0)       rotate(0deg); }
  60%      { transform: translate3d(0, 0.28rem, 0) rotate(3.5deg); }
  80%      { transform: translate3d(0, 0, 0)       rotate(0deg); }
}

/* Negar: dos sacudidas de costado. */
.munieco--niega { animation: avatar-niega 0.85s ease-in-out; }

@keyframes avatar-niega {
  0%, 100% { transform: rotate(0deg); }
  18%      { transform: rotate(-4.5deg); }
  42%      { transform: rotate(4.5deg); }
  66%      { transform: rotate(-3deg); }
  84%      { transform: rotate(2deg); }
}

/* Temblar: cuando algo sale mal. Rápido y chico. */
.munieco--tiembla { animation: avatar-tiembla 0.55s linear; }

@keyframes avatar-tiembla {
  0%, 100%          { transform: translate3d(0, 0, 0); }
  10%, 30%, 50%, 70% { transform: translate3d(-0.14rem, 0, 0); }
  20%, 40%, 60%, 80% { transform: translate3d(0.14rem, 0, 0); }
}

/* Guiñar: el párpado de un ojo baja y se queda un momento, y la cabeza se
   ladea hacia ese lado. Es el mismo párpado del parpadeo, más lento. Va
   después del parpadeo para ganarle si los dos caen juntos. */
.munieco--guina { animation: avatar-guina 0.7s cubic-bezier(0.34, 1.3, 0.64, 1); }
.munieco--guina .munieco__capa--parpado-der { animation: avatar-guino 0.7s ease-in-out; }

@keyframes avatar-guina {
  0%, 100% { transform: translate3d(0, 0, 0)        rotate(0deg); }
  25%, 68% { transform: translate3d(0, -0.12rem, 0) rotate(2.6deg); }
}
@keyframes avatar-guino {
  0%       { transform: scaleY(0); }
  20%, 70% { transform: scaleY(1); }
  100%     { transform: scaleY(0); }
}

/* Estirarse: se agacha un poco, sube los dos brazos y se estira para arriba
   como quien se despereza, se queda un instante y se afloja con un rebote. */
.munieco--estira { animation: avatar-estira 1.7s cubic-bezier(0.45, 0, 0.3, 1); }
.munieco--estira .munieco__capa--brazo-der { animation: avatar-estira-der 1.7s ease-in-out; }
.munieco--estira .munieco__capa--brazo-izq { animation: avatar-estira-izq 1.7s ease-in-out; }

@keyframes avatar-estira {
  0%       { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1)         rotate(0deg); }
  16%      { transform: translate3d(0, 0.12rem, 0)  scale3d(1.04, 0.95, 1)   rotate(0deg); }
  44%, 62% { transform: translate3d(0, -0.3rem, 0)  scale3d(0.96, 1.07, 1)   rotate(-1.4deg); }
  80%      { transform: translate3d(0, 0.08rem, 0)  scale3d(1.03, 0.97, 1)   rotate(0.4deg); }
  100%     { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1)         rotate(0deg); }
}
@keyframes avatar-estira-der {
  0%, 100% { transform: rotate(0deg); }
  16%      { transform: rotate(6deg); }
  44%, 62% { transform: rotate(-34deg); }
  80%      { transform: rotate(-4deg); }
}
@keyframes avatar-estira-izq {
  0%, 100% { transform: rotate(0deg); }
  16%      { transform: rotate(-6deg); }
  44%, 62% { transform: rotate(34deg); }
  80%      { transform: rotate(4deg); }
}

/* Bailar: se mece de un lado al otro marcando el pulso con un rebote, y los
   brazos van alternados. Cuatro tiempos y vuelve a quedarse quieto. */
.munieco--baila { animation: avatar-baila 1.8s ease-in-out; }
.munieco--baila .munieco__capa--brazo-der { animation: avatar-baila-der 1.8s ease-in-out; }
.munieco--baila .munieco__capa--brazo-izq { animation: avatar-baila-izq 1.8s ease-in-out; }

@keyframes avatar-baila {
  0%, 100% { transform: translate3d(0, 0, 0)               scale3d(1, 1, 1)       rotate(0deg); }
  12.5%    { transform: translate3d(-0.14rem, -0.22rem, 0) scale3d(0.98, 1.02, 1) rotate(-4.5deg); }
  25%      { transform: translate3d(0, 0.06rem, 0)         scale3d(1.04, 0.96, 1) rotate(0deg); }
  37.5%    { transform: translate3d(0.14rem, -0.22rem, 0)  scale3d(0.98, 1.02, 1) rotate(4.5deg); }
  50%      { transform: translate3d(0, 0.06rem, 0)         scale3d(1.04, 0.96, 1) rotate(0deg); }
  62.5%    { transform: translate3d(-0.14rem, -0.22rem, 0) scale3d(0.98, 1.02, 1) rotate(-4.5deg); }
  75%      { transform: translate3d(0, 0.06rem, 0)         scale3d(1.04, 0.96, 1) rotate(0deg); }
  87.5%    { transform: translate3d(0.14rem, -0.22rem, 0)  scale3d(0.98, 1.02, 1) rotate(4.5deg); }
}
@keyframes avatar-baila-der {
  0%, 25%, 50%, 75%, 100% { transform: rotate(0deg); }
  12.5%, 62.5%            { transform: rotate(-24deg); }
  37.5%, 87.5%            { transform: rotate(8deg); }
}
@keyframes avatar-baila-izq {
  0%, 25%, 50%, 75%, 100% { transform: rotate(0deg); }
  12.5%, 62.5%            { transform: rotate(-8deg); }
  37.5%, 87.5%            { transform: rotate(24deg); }
}

/* ── La espuma en los gestos ───────────────────────────────────────── */

/* Lo que separa a un muñeco de goma de uno de cartón: cuando el cuerpo
   frena, lo blando sigue. La espuma acompaña cada gesto con un poco de
   atraso, siempre desde su base —que no se mueve—.

   Saltar: al agacharse todavía no se enteró; al despegar se aplasta, porque
   el vaso sube y ella llega tarde; arriba, cuando el vaso frena, sigue de
   largo y se estira; al caer se aplasta de nuevo y rebota. Los tiempos son
   los de avatar-salta corridos un pelo. */
.munieco--salta   .munieco__capa--espuma,
.munieco--festeja .munieco__capa--espuma {
  animation: avatar-espuma-salto 0.95s ease-out;
}

@keyframes avatar-espuma-salto {
  0%   { transform: skewX(0deg) scale(1, 1); }
  25%  { transform: skewX(0deg) scale(1, 0.92); }
  45%  { transform: skewX(0deg) scale(1, 0.95); }
  60%  { transform: skewX(0deg) scale(1, 1.1); }
  80%  { transform: skewX(0deg) scale(1, 0.88); }
  91%  { transform: skewX(0deg) scale(1, 1.04); }
  100% { transform: skewX(0deg) scale(1, 1); }
}

/* Asentir y negar: la espuma se queda atrás del cabezazo y lo alcanza
   después, del lado contrario. */
.munieco--asiente .munieco__capa--espuma { animation: avatar-espuma-asiente 0.9s ease-in-out; }
.munieco--niega   .munieco__capa--espuma { animation: avatar-espuma-niega 0.85s ease-in-out; }
.munieco--tiembla .munieco__capa--espuma { animation: avatar-espuma-tiembla 0.55s linear; }

@keyframes avatar-espuma-asiente {
  0%, 100% { transform: skewX(0deg)    scale(1, 1); }
  25%      { transform: skewX(-2.5deg) scale(1, 0.96); }
  45%      { transform: skewX(1.2deg)  scale(1, 1.03); }
  65%      { transform: skewX(-2.5deg) scale(1, 0.96); }
  85%      { transform: skewX(1deg)    scale(1, 1.02); }
}
@keyframes avatar-espuma-niega {
  0%, 100% { transform: skewX(0deg); }
  24%      { transform: skewX(3.5deg); }
  48%      { transform: skewX(-3.5deg); }
  72%      { transform: skewX(2.5deg); }
  90%      { transform: skewX(-1deg); }
}
@keyframes avatar-espuma-tiembla {
  0%, 100%           { transform: skewX(0deg); }
  15%, 35%, 55%, 75% { transform: skewX(2.5deg); }
  25%, 45%, 65%, 85% { transform: skewX(-2.5deg); }
}

/* Estirándose, la espuma se queda abajo cuando el vaso sube y lo alcanza
   estirada; bailando, va siempre medio tiempo atrás del vaivén. */
.munieco--estira .munieco__capa--espuma { animation: avatar-espuma-estira 1.7s ease-in-out; }
.munieco--baila  .munieco__capa--espuma { animation: avatar-espuma-baila 1.8s ease-in-out; }

@keyframes avatar-espuma-estira {
  0%, 100% { transform: skewX(0deg)    scale(1, 1); }
  20%      { transform: skewX(0deg)    scale(1, 0.94); }
  50%      { transform: skewX(-1.5deg) scale(1, 1.08); }
  70%      { transform: skewX(0.8deg)  scale(1, 1.04); }
  88%      { transform: skewX(0deg)    scale(1, 0.96); }
}
@keyframes avatar-espuma-baila {
  0%, 100%     { transform: skewX(0deg); }
  18%, 68%     { transform: skewX(4deg); }
  43%, 93%     { transform: skewX(-4deg); }
}

/* ── Los gestos, andando ───────────────────────────────────────────── */

/* Andando, el que se ve es el corredor, así que los gestos se le piden a él.
   Los de brazo van a sus brazos: el saludo lo hace el del puño, que es el
   que está arriba. Los de cuerpo entero van a la caja del corredor, que es
   la única pieza que no tiene tomada su transform con el paso. Las piernas
   siguen caminando por debajo: saluda sin frenar.

   Van después de los andares del corredor, y con la misma especificidad:
   ganan por orden. */
.munieco--con-corredor.munieco--saluda .corredor__brazo--adelante {
  animation: corredor-saluda 1.15s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}
.munieco--con-corredor.munieco--festeja .corredor__brazo--adelante {
  animation: corredor-festeja-adelante 0.95s ease-out;
}
.munieco--con-corredor.munieco--festeja .corredor__brazo--atras {
  animation: corredor-festeja-atras 0.95s ease-out;
}
.munieco--con-corredor.munieco--festeja .munieco__corredor,
.munieco--con-corredor.munieco--salta   .munieco__corredor { animation: avatar-salta 0.95s cubic-bezier(0.34, 1.3, 0.64, 1); }
/* La espuma acompaña el salto igual que en reposo: se aplasta al despegar,
   se estira arriba y rebota al caer. */
.munieco--con-corredor.munieco--festeja .corredor__espuma,
.munieco--con-corredor.munieco--salta   .corredor__espuma { animation: avatar-espuma-salto 0.95s ease-out; }
.munieco--con-corredor.munieco--asiente .munieco__corredor { animation: avatar-asiente 0.9s ease-in-out; }
.munieco--con-corredor.munieco--niega   .munieco__corredor { animation: avatar-niega 0.85s ease-in-out; }
.munieco--con-corredor.munieco--tiembla .munieco__corredor { animation: avatar-tiembla 0.55s linear; }

/* El puño sube hacia la cabeza y se mece: girar en negativo lo levanta. */
@keyframes corredor-saluda {
  0%   { transform: rotate(0deg); }
  15%  { transform: rotate(-34deg); }
  35%  { transform: rotate(-14deg); }
  55%  { transform: rotate(-34deg); }
  75%  { transform: rotate(-16deg); }
  100% { transform: rotate(0deg); }
}
@keyframes corredor-festeja-adelante {
  0%, 100% { transform: rotate(0deg); }
  30%, 60% { transform: rotate(-38deg); }
}
@keyframes corredor-festeja-atras {
  0%, 100% { transform: rotate(0deg); }
  30%, 60% { transform: rotate(34deg); }
}

/* Yéndose camina hacia la izquierda, y el corredor está dibujado mirando a
   la derecha: se lo da vuelta. Va en el <svg> y no en la caja porque la
   caja es la que hace los gestos. */
.avatar--sale .munieco__corredor > svg { transform: scaleX(-1); }
/* Lo mismo a la vuelta de la vueltita (avatar-ocio.js). */
.avatar[data-rumbo='izq'] .munieco__corredor > svg { transform: scaleX(-1); }

.avatar__munieco:hover  { transform: translateY(-2px) scale(1.03); }
.avatar__munieco:active { transform: translateY(0) scale(0.97); }
.avatar__munieco:focus-visible {
  outline: 3px solid var(--brand-primary);
  outline-offset: 4px;
}

/* El saltito al cambiar de cara: se achata, despega y vuelve. Es la
   diferencia entre una imagen que se reemplaza y un personaje que reacciona.
   Va en la escena y no en las capas para no pelearse con el respirar. */
.avatar__escena--cambia {
  transform-origin: 50% 100%;
  animation: avatar-golpe 0.5s var(--transition-spring);
}

@keyframes avatar-golpe {
  0%   { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1); }
  22%  { transform: translate3d(0, 0.1rem, 0)   scale3d(1.08, 0.9, 1); }
  55%  { transform: translate3d(0, -0.5rem, 0)  scale3d(0.95, 1.07, 1); }
  100% { transform: translate3d(0, 0, 0)        scale3d(1, 1, 1); }
}

/* ── Lo que hace cuando no hace nada ───────────────────────────────── */

/* Las cosas que larga mientras está solo (avatar-ocio.js): burbujas que
   suben desde la espuma y las zetas de la siesta. Van en el cuerpo y no en
   la escena: la escena tiene el filtro de la sombra, y un filtro sobre algo
   que se mueve se vuelve a calcular en cada cuadro. */
.avatar__ocio {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.avatar__burbujita {
  position: absolute;
  left: var(--x, 50%);
  top: 24%;
  width: var(--tam, 0.5rem);
  height: var(--tam, 0.5rem);
  border-radius: 50%;
  border: 1.5px solid rgba(14, 164, 207, 0.55);
  background:
    radial-gradient(circle at 32% 28%, #fff 0 16%, rgba(255, 255, 255, 0) 30%),
    radial-gradient(circle, rgba(14, 164, 207, 0.05) 50%, rgba(14, 164, 207, 0.22) 100%);
  opacity: 0;
  animation: avatar-burbujita 2.1s cubic-bezier(0.3, 0.6, 0.5, 1) var(--demora, 0ms) forwards;
}

/* Sube meciéndose y al final revienta: se agranda de golpe y desaparece. */
@keyframes avatar-burbujita {
  0%   { opacity: 0;   transform: translate3d(0, 0, 0)                                scale(0.3); }
  12%  { opacity: 1;   transform: translate3d(calc(var(--deriva) * 0.2), -0.6rem, 0)  scale(1); }
  45%  {               transform: translate3d(calc(var(--deriva) * -0.3), -2rem, 0)   scale(1); }
  86%  { opacity: 0.9; transform: translate3d(var(--deriva), -3.6rem, 0)              scale(1.05); }
  100% { opacity: 0;   transform: translate3d(var(--deriva), -3.9rem, 0)              scale(1.6); }
}

.avatar__zeta {
  position: absolute;
  left: 62%;
  top: 22%;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 700;
  font-size: var(--tam, 1rem);
  line-height: 1;
  color: var(--brand-dark, #065F75);
  text-shadow: 0 0 0.35rem #fff, 0 0 0.15rem #fff;
  opacity: 0;
  animation: avatar-zeta 2.4s ease-out forwards;
}

@keyframes avatar-zeta {
  0%   { opacity: 0;    transform: translate3d(0, 0, 0)            rotate(-10deg) scale(0.6); }
  20%  { opacity: 0.95; transform: translate3d(0.4rem, -0.7rem, 0) rotate(6deg)   scale(1); }
  60%  { opacity: 0.8;  transform: translate3d(0.2rem, -2rem, 0)   rotate(-6deg)  scale(1.1); }
  100% { opacity: 0;    transform: translate3d(1rem, -3.2rem, 0)   rotate(10deg)  scale(1.25); }
}

/* Algunas caras tienen su propio movimiento, en vez del respirar de siempre.
   Tomando agua: tragos cortos, con la cabeza un poco para atrás. */
.avatar[data-pose='tomando'] .avatar__pose {
  animation: avatar-trago 0.85s ease-in-out infinite;
}
@keyframes avatar-trago {
  0%, 100% { transform: translate3d(0, 0, 0)         rotate(0deg)    scale3d(1, 1, 1); }
  35%      { transform: translate3d(0, -0.12rem, 0)  rotate(-1.6deg) scale3d(0.995, 1.012, 1); }
  60%      { transform: translate3d(0, 0.04rem, 0)   rotate(-0.4deg) scale3d(1.01, 0.99, 1); }
}

/* Dormitando: respira hondo y lento. */
.avatar[data-siesta='true'] .avatar__pose {
  animation: avatar-respira 5.2s ease-in-out infinite;
}

/* ── El globo ──────────────────────────────────────────────────────── */

.avatar__globo {
  order: -1; /* arriba del muñeco */
  position: relative;
  max-width: min(19rem, calc(100vw - 2 * var(--avatar-aire) - 1rem));
  padding: 0.85rem 1rem;
  border-radius: 1.1rem;
  border: 1px solid rgba(14, 164, 207, 0.16);

  /* Tres capas de superficie: el blanco, un velo del cian de marca arriba
     —que es lo que lo despega del paisaje— y la sombra teñida. */
  background:
    linear-gradient(180deg, rgba(14, 164, 207, 0.06), rgba(255, 255, 255, 0) 60%),
    #fff;
  box-shadow:
    0 1px 2px rgba(6, 95, 117, 0.08),
    0 10px 26px -8px rgba(14, 164, 207, 0.32),
    0 24px 52px -16px rgba(6, 95, 117, 0.24);

  transform-origin: calc(var(--avatar-alto) * 0.38) bottom;
  transition:
    opacity 0.22s ease,
    transform 0.34s var(--transition-spring);
}

.avatar[data-abierto='false'] .avatar__globo {
  opacity: 0;
  transform: translate3d(0, 0.5rem, 0) scale(0.92);
  pointer-events: none;
}

.avatar[data-abierto='true'] .avatar__globo {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

/* La colita del globo, apuntando al muñeco. Es un cuadrado girado con las dos
   mismas caras que el globo, tapado arriba por el propio globo. */
.avatar__globo::after {
  content: '';
  position: absolute;
  /* Apunta al cuerpo del personaje, que está centrado en su marco. */
  left: calc(var(--avatar-alto) * 0.38);
  bottom: -0.36rem;
  width: 0.72rem;
  height: 0.72rem;
  background: #fff;
  border-right: 1px solid rgba(14, 164, 207, 0.16);
  border-bottom: 1px solid rgba(14, 164, 207, 0.16);
  transform: rotate(45deg);
}

.avatar__texto {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--text-on-light);
}

.avatar__texto[hidden] { display: none; }

/* Lo que todavía no se escribió ocupa su lugar pero no se ve. Es lo que hace
   que el globo arranque del tamaño que va a tener: si creciera letra por
   letra, el párrafo entero bailaría mientras se escribe. */
.avatar__falta { visibility: hidden; }


/* Los tres puntos de "pensando". Es el único momento en que el globo se
   queda abierto sin decir nada, y sin señal parece colgado. */
.avatar__globo[data-pensando='true'] .avatar__texto::after {
  content: '';
  display: inline-block;
  width: 0.2rem;
  height: 0.2rem;
  margin-left: 0.35rem;
  border-radius: 50%;
  background: var(--brand-primary);
  animation: avatar-late 1.1s ease-in-out infinite;
}

@keyframes avatar-late {
  0%, 100% { opacity: 0.25; transform: translate3d(0, 0, 0); }
  50%      { opacity: 1;    transform: translate3d(0, -0.15rem, 0); }
}

/* El campo para preguntar ya no va en el globo: va en la charla
   (avatar-charla.css). El globo queda para frases cortas. */

/* ── El botón de cerrarlo ──────────────────────────────────────────── */

.avatar__cerrar {
  position: absolute;
  top: -0.3rem;
  right: -0.3rem;
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  border: 1px solid rgba(14, 164, 207, 0.2);
  border-radius: 50%;
  background: #fff;
  color: var(--brand-dark);
  cursor: pointer;
  box-shadow: 0 2px 8px -2px rgba(6, 95, 117, 0.3);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.2s ease, transform 0.24s var(--transition-spring),
              background-color 0.2s ease;
}

/* Aparece cuando el visitante se acerca al personaje. Siempre visible sería
   un aspa flotando sobre el dibujo; escondido para siempre sería un avatar
   que no se puede sacar. En pantalla táctil no hay hover, así que ahí se
   muestra desde el arranque. */
.avatar:hover .avatar__cerrar,
.avatar:focus-within .avatar__cerrar {
  opacity: 1;
  transform: scale(1);
}

.avatar__cerrar:hover  { background: var(--bg-light); }
.avatar__cerrar:active { transform: scale(0.9); }
.avatar__cerrar:focus-visible {
  outline: 3px solid var(--brand-primary);
  outline-offset: 2px;
}

@media (hover: none) {
  .avatar__cerrar { opacity: 1; transform: scale(1); }
}

/* ── Celular ───────────────────────────────────────────────────────── */

@media (max-width: 600px) {
  .avatar {
    /* Bastante más chico que en escritorio. En una pantalla de 390 px el
       muñeco de escritorio ocupa un tercio del ancho y se le sienta encima a
       lo que haya abajo de todo; a esta altura queda del orden del botón de
       WhatsApp, que es el otro que flota. */
    --avatar-alto: 6.5rem;
    /* Sube por encima de la barra de confianza y deja libre el pie. */
    bottom: calc(var(--avatar-aire) + 0.5rem);
  }
  .avatar__globo { font-size: 0.9rem; }
}

/* ── Menos movimiento ──────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .avatar,
  .avatar__globo,
  .avatar__munieco,
  .avatar__cerrar {
    transition-duration: 0.01ms;
  }
  .avatar,
  .avatar--presente,
  .avatar[data-abierto='false'] .avatar__globo,
  .avatar[data-abierto='true'] .avatar__globo {
    transform: none;
  }
  /* Se apaga todo lo que respira, se mece, parpadea, salta o mira. El
     personaje queda quieto y entero: en reposo ninguna capa está corrida de
     su lugar, así que apagar las animaciones lo deja igual que la estampa.

     Va con !important, que en esta hoja no se usa en ningún otro lado. Es a
     propósito: las reglas de cada gesto son más específicas que estas, y la
     mirada la escribe el JS como estilo en línea. Acá no hay nada que
     matizar —el visitante pidió que no se mueva— así que gana esto y listo.

     Los párpados quedan afuera de la regla de transform: tienen que seguir
     aplastados en cero, o los ojos aparecen tapados por dos pastillas. */
  .munieco,
  .munieco__capa,
  .munieco__pupila,
  .avatar__pose,
  .avatar__escena,
  .avatar__cuerpo,
  .munieco__corredor,
  .munieco__corredor *,
  .avatar__globo[data-pensando='true'] .avatar__texto::after {
    animation: none !important;
  }
  /* Lo que hace por su cuenta no corre (avatar-ocio.js no arranca), pero por
     las dudas sus adornos no se ven. */
  .avatar__ocio { display: none; }
  .munieco,
  .avatar__pose,
  .avatar__escena,
  .avatar__cuerpo,
  .munieco__pupila,
  .munieco__capa--brazo-izq,
  .munieco__capa--brazo-der,
  .munieco__capa--espuma,
  .munieco__capa--boca {
    transform: none !important;
  }
}
