/* =========================================================================
   MOTIVOS DE "PENSANDO" — CSS puro, sin librería de animación.

   POR QUÉ CSS PURO: esto es un widget que se embebe en la página de un
   cliente. Meter Framer Motion o GSAP para mover cinco divs son 40-70 KB
   de JavaScript que el visitante descarga y parsea antes de ver nada.
   Inaceptable. Todo esto pesa menos de 4 KB sin comprimir.

   CÓMO SE ELIGE EL MOTIVO: un atributo en el contenedor.
       <span class="lw-ind" data-motivo="orbit" data-estado="pensando">
   El widget lo lee de la config (`{ motivo: "orbit" }`) y lo escribe una
   sola vez. No hay que tocar nada más.

   MARCADO ÚNICO PARA TODOS LOS MOTIVOS. Siempre los mismos cinco <i>:

       <span class="lw-ind" data-motivo="orbit" data-estado="pensando"
             role="status" aria-live="polite">
         <span class="lw-ind__pista" aria-hidden="true">
           <i></i><i></i><i></i><i></i><i></i>
         </span>
         <span class="lw-ind__texto">Pensando</span>
       </span>

   Cada motivo usa los <i> que necesita y deja el resto invisibles. Esto
   permite cambiar de motivo sin tocar el JS, y permite cambiarlo en vivo
   desde las devtools para mostrárselo a un cliente.

   DOS ESTADOS, QUE SON MOMENTOS DISTINTOS:
     data-estado="pensando"    → esperando la primera respuesta del modelo.
                                 Motivo a tamaño completo, con leyenda.
     data-estado="escribiendo" → el texto ya está llegando en streaming.
                                 El motivo se achica, se atenúa, acelera y
                                 pierde la leyenda: pasa a segundo plano
                                 porque ahora lo importante es el texto.

   TINTE DE MARCA: una sola custom property.
       .lw-ind { --lw-acento: #2563eb; }
   Por defecto hereda `currentColor`, así que si no se configura nada toma
   el color de texto del contenedor y nunca se ve roto.

   SIN LAYOUT SHIFT: `.lw-ind` tiene `min-height` de una línea de texto y
   `.lw-ind__pista` tiene ancho y alto fijos, iguales para los cinco
   motivos. Cambiar de motivo no mueve un pixel, y el indicador se renderiza
   DENTRO de la misma burbuja que después va a contener la respuesta, así
   que cuando el texto reemplaza al indicador la burbuja no salta.
   ========================================================================= */

.lw-ind {
  /*
    OJO: acá NO se declara --lw-acento. Se usa siempre como
    `var(--lw-acento, currentColor)`.

    Si se declarara `--lw-acento: currentColor` en esta regla, esa
    declaración propia le ganaría al valor heredado de `.lw` y el tinte de
    marca del cliente quedaría ignorado: el indicador siempre saldría del
    color del texto. Es un bug silencioso —se ve bien, pero nunca toma el
    color configurado— y por eso el valor por defecto va en el fallback del
    var() y no en una declaración.
  */
  --lw-vel: 1; /* multiplicador de velocidad, sin unidad */

  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 1.5rem; /* = altura de una línea. No negociar: esto es lo que
                         evita el salto cuando aparece y desaparece. */
  color: inherit;
}

.lw-ind__pista {
  position: relative;
  display: block;
  flex: none;
  width: 1.75rem; /* 28px — idéntico para los cinco motivos */
  height: 1.25rem; /* 20px */
}

.lw-ind__pista > i {
  position: absolute;
  display: block;
  background: var(--lw-acento, currentColor);
  border-radius: 50%;
  opacity: 0; /* apagados por defecto; cada motivo enciende los suyos */
}

.lw-ind__texto {
  font-size: 0.8125rem;
  line-height: 1.5rem;
  opacity: 0.7;
}

/* Estado "escribiendo": el motivo se corre a segundo plano. */
.lw-ind[data-estado="escribiendo"] {
  --lw-vel: 1.5;
}
.lw-ind[data-estado="escribiendo"] .lw-ind__pista {
  transform: scale(0.7);
  opacity: 0.55;
}
.lw-ind[data-estado="escribiendo"] .lw-ind__texto {
  display: none;
}

/* -------------------------------------------------------------------------
   1. ORBIT — rotación orbital suave.
   Un núcleo que late, un satélite que lo orbita y un anillo tenue de
   referencia. Es el más "producto serio" de los cinco y el default.
   ------------------------------------------------------------------------- */
.lw-ind[data-motivo="orbit"] i:nth-child(1) {
  top: 50%;
  left: 50%;
  width: 0.3rem;
  height: 0.3rem;
  margin: -0.15rem 0 0 -0.15rem;
  opacity: 1;
  animation: lw-nucleo calc(1.8s / var(--lw-vel)) ease-in-out infinite;
}
.lw-ind[data-motivo="orbit"] i:nth-child(2) {
  top: 50%;
  left: 50%;
  width: 0.28rem;
  height: 0.28rem;
  margin: -0.14rem 0 0 -0.14rem;
  opacity: 0.95;
  animation: lw-orbita calc(1.15s / var(--lw-vel)) linear infinite;
}
.lw-ind[data-motivo="orbit"] i:nth-child(3) {
  top: 50%;
  left: 50%;
  width: 1.15rem;
  height: 1.15rem;
  margin: -0.575rem 0 0 -0.575rem;
  background: none;
  border: 1px solid var(--lw-acento, currentColor);
  opacity: 0.16;
}

@keyframes lw-orbita {
  from {
    transform: rotate(0deg) translateX(0.575rem);
  }
  to {
    transform: rotate(360deg) translateX(0.575rem);
  }
}
@keyframes lw-nucleo {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(0.62);
    opacity: 0.55;
  }
}

/* -------------------------------------------------------------------------
   2. CONSTELACION — puntos que se conectan.
   Cinco puntos en posiciones fijas y asimétricas; cada uno dibuja con su
   ::after el segmento hacia el siguiente. Los puntos encienden en secuencia
   y las líneas los siguen. Las longitudes y ángulos están calculados sobre
   la caja de 28x20px: si cambiás el tamaño de .lw-ind__pista hay que
   recalcularlos, y por eso NO se cambia el tamaño.
   ------------------------------------------------------------------------- */
.lw-ind[data-motivo="constelacion"] i {
  width: 0.25rem;
  height: 0.25rem;
  margin: -0.125rem 0 0 -0.125rem;
  animation: lw-estrella calc(2.2s / var(--lw-vel)) ease-in-out infinite;
}
.lw-ind[data-motivo="constelacion"] i::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  height: 1px;
  background: var(--lw-acento, currentColor);
  transform-origin: left center;
  opacity: 0;
  animation: lw-enlace calc(2.2s / var(--lw-vel)) ease-in-out infinite;
}

.lw-ind[data-motivo="constelacion"] i:nth-child(1) {
  top: 70%;
  left: 10%;
  animation-delay: 0s;
}
.lw-ind[data-motivo="constelacion"] i:nth-child(1)::after {
  width: 10.6px;
  transform: rotate(-58.1deg);
  animation-delay: 0.1s;
}

.lw-ind[data-motivo="constelacion"] i:nth-child(2) {
  top: 25%;
  left: 30%;
  animation-delay: 0.18s;
}
.lw-ind[data-motivo="constelacion"] i:nth-child(2)::after {
  width: 9.35px;
  transform: rotate(48.5deg);
  animation-delay: 0.28s;
}

.lw-ind[data-motivo="constelacion"] i:nth-child(3) {
  top: 60%;
  left: 52%;
  animation-delay: 0.36s;
}
.lw-ind[data-motivo="constelacion"] i:nth-child(3)::after {
  width: 10.06px;
  transform: rotate(-52.7deg);
  animation-delay: 0.46s;
}

.lw-ind[data-motivo="constelacion"] i:nth-child(4) {
  top: 20%;
  left: 74%;
  animation-delay: 0.54s;
}
.lw-ind[data-motivo="constelacion"] i:nth-child(4)::after {
  width: 10.35px;
  transform: rotate(60.5deg);
  animation-delay: 0.64s;
}

.lw-ind[data-motivo="constelacion"] i:nth-child(5) {
  top: 65%;
  left: 92%;
  animation-delay: 0.72s;
}
/* El último punto no dibuja segmento: no hay siguiente. */
.lw-ind[data-motivo="constelacion"] i:nth-child(5)::after {
  display: none;
}

@keyframes lw-estrella {
  0%,
  100% {
    opacity: 0.2;
    transform: scale(0.75);
  }
  30%,
  55% {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes lw-enlace {
  0%,
  100% {
    opacity: 0;
  }
  35%,
  55% {
    opacity: 0.3;
  }
}

/* -------------------------------------------------------------------------
   3. PULSO — anillos concéntricos que se expanden.
   Núcleo fijo, dos anillos que salen y se desvanecen desfasados. El más
   sobrio; funciona bien en marcas serias (estudios, salud, servicios).
   ------------------------------------------------------------------------- */
.lw-ind[data-motivo="pulso"] i:nth-child(1) {
  top: 50%;
  left: 50%;
  width: 0.35rem;
  height: 0.35rem;
  margin: -0.175rem 0 0 -0.175rem;
  opacity: 1;
}
.lw-ind[data-motivo="pulso"] i:nth-child(2),
.lw-ind[data-motivo="pulso"] i:nth-child(3) {
  top: 50%;
  left: 50%;
  width: 1.25rem;
  height: 1.25rem;
  margin: -0.625rem 0 0 -0.625rem;
  background: none;
  border: 1.5px solid var(--lw-acento, currentColor);
  animation: lw-onda calc(1.9s / var(--lw-vel)) ease-out infinite;
}
.lw-ind[data-motivo="pulso"] i:nth-child(3) {
  animation-delay: calc(0.95s / var(--lw-vel));
}

@keyframes lw-onda {
  0% {
    transform: scale(0.28);
    opacity: 0.75;
  }
  100% {
    transform: scale(1);
    opacity: 0;
  }
}

/* -------------------------------------------------------------------------
   4. BARRA — indeterminada con degradado en movimiento.
   Un riel tenue y una banda que lo recorre. Es el que menos "personalidad"
   tiene, y por eso es el que mejor queda en sitios corporativos donde el
   widget no tiene que llamar la atención.
   ------------------------------------------------------------------------- */
.lw-ind[data-motivo="barra"] .lw-ind__pista {
  overflow: hidden;
  border-radius: 999px;
}
.lw-ind[data-motivo="barra"] i:nth-child(1) {
  top: 50%;
  left: 0;
  width: 100%;
  height: 0.25rem;
  margin-top: -0.125rem;
  border-radius: 999px;
  opacity: 0.15;
}
.lw-ind[data-motivo="barra"] i:nth-child(2) {
  top: 50%;
  left: 0;
  width: 60%;
  height: 0.25rem;
  margin-top: -0.125rem;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--lw-acento, currentColor) 50%,
    transparent 100%
  );
  opacity: 1;
  animation: lw-barrido calc(1.4s / var(--lw-vel)) ease-in-out infinite;
}

@keyframes lw-barrido {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(200%);
  }
}

/* -------------------------------------------------------------------------
   5. PUNTOS — el clásico, en secuencia.
   Fallback conservador. Cuando el cliente es tradicional o cuando no hay
   tiempo de discutir estética, este no genera objeciones nunca.
   ------------------------------------------------------------------------- */
.lw-ind[data-motivo="puntos"] i:nth-child(-n + 3) {
  top: 50%;
  width: 0.3rem;
  height: 0.3rem;
  margin-top: -0.15rem;
  animation: lw-rebote calc(1.2s / var(--lw-vel)) ease-in-out infinite;
}
.lw-ind[data-motivo="puntos"] i:nth-child(1) {
  left: 15%;
  animation-delay: 0s;
}
.lw-ind[data-motivo="puntos"] i:nth-child(2) {
  left: 45%;
  animation-delay: 0.16s;
}
.lw-ind[data-motivo="puntos"] i:nth-child(3) {
  left: 75%;
  animation-delay: 0.32s;
}

@keyframes lw-rebote {
  0%,
  70%,
  100% {
    opacity: 0.28;
    transform: translateY(0) scale(0.85);
  }
  35% {
    opacity: 1;
    transform: translateY(-0.2rem) scale(1);
  }
}

/* -------------------------------------------------------------------------
   CURSOR DE STREAMING
   Se agrega al final del texto mientras está llegando. Es lo que le dice al
   usuario "esto todavía no terminó" sin ocupar una línea aparte.
   `vertical-align` y `width` fijos: no reflowea el párrafo.
   ------------------------------------------------------------------------- */
.lw-cursor {
  display: inline-block;
  width: 0.5ch;
  height: 1em;
  margin-left: 0.1ch;
  vertical-align: text-bottom;
  background: var(--lw-acento, currentColor);
  opacity: 0.8;
  animation: lw-latido 1s steps(2, start) infinite;
}

@keyframes lw-latido {
  0%,
  100% {
    opacity: 0.8;
  }
  50% {
    opacity: 0.1;
  }
}

/* -------------------------------------------------------------------------
   PREFERS-REDUCED-MOTION

   No se apaga el indicador: el usuario necesita saber que algo está pasando.
   Se congela el movimiento y se reemplaza por una pulsación de opacidad muy
   suave sobre el conjunto.

   Todos los motivos se reducen al MISMO estado estático (tres puntos
   alineados). Es una decisión deliberada: conservar cinco estados estáticos
   distintos multiplica el código y las formas de romperse, y con el
   movimiento apagado los cinco se verían casi igual de todos modos.

   Los selectores acá tienen más especificidad que el `*` del reset global de
   la página (que también usa !important), así que ganan sin depender del
   orden en que se carguen las hojas.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lw-ind .lw-ind__pista > i,
  .lw-ind .lw-ind__pista > i::after {
    animation: none !important;
    transition: none !important;
  }

  .lw-ind .lw-ind__pista > i::after {
    display: none !important;
  }

  .lw-ind .lw-ind__pista > i:nth-child(-n + 3) {
    top: 50% !important;
    width: 0.3rem !important;
    height: 0.3rem !important;
    margin: -0.15rem 0 0 0 !important;
    background: var(--lw-acento, currentColor) !important;
    border: 0 !important;
    border-radius: 50% !important;
    transform: none !important;
    opacity: 1 !important;
  }
  .lw-ind .lw-ind__pista > i:nth-child(1) {
    left: 15% !important;
  }
  .lw-ind .lw-ind__pista > i:nth-child(2) {
    left: 45% !important;
  }
  .lw-ind .lw-ind__pista > i:nth-child(3) {
    left: 75% !important;
  }
  .lw-ind .lw-ind__pista > i:nth-child(n + 4) {
    display: none !important;
  }

  .lw-ind .lw-ind__pista {
    animation: lw-respira 2.6s ease-in-out infinite !important;
  }

  .lw-cursor {
    animation: lw-respira 2.6s ease-in-out infinite !important;
  }
}

@keyframes lw-respira {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}
