/* ==========================================================================
   assets/css/add-to-cart-anim.css - Animación del icono del botón «Agregar»

   Animación hecha a medida con SVG y CSS, sin librerías externas.

   POR QUÉ ASÍ Y NO CON UN LOTTIE:
   La animación descargada de LottieFiles traía problemas que no se podían
   resolver de forma fiable: las letras eran trazados dibujados (al traducirlas
   salían letras en blanco), incluía su propio fondo y una ráfaga de confeti que
   se salía del lienzo, y su proporción no encajaba con la del botón. Cada
   arreglo rompía otra cosa.

   EL DISEÑO AHORA ES DISTINTO Y MÁS SIMPLE:
   No se reemplaza el botón entero. Se anima SOLO el hueco del icono, que tiene
   un tamaño fijo, y el texto «Agregar» permanece visible todo el tiempo.

   Así desaparece el problema de fondo: ya no hay que estirar un dibujo para
   llenar un botón de proporción variable, porque el icono mide siempre lo mismo
   sin importar lo ancho que sea el botón.
   ========================================================================== */

/* ---------- Hueco del icono ---------- */
/* Contiene el icono normal y, encima, la animación. Ambos ocupan el mismo sitio
   exacto, así que al intercambiarse no hay ningún salto de tamaño. El icono
   estático usa el mismo `--slot` a propósito: si la animación fuese de otro
   tamaño se vería el salto al empezar.
   El tamaño sale de una variable para que los dos no se puedan desincronizar.

   LÍMITE MEDIDO: el hueco no puede crecer tanto como para empujar la altura del
   botón. Con el texto de la tarjeta (.85rem, línea de 20,4 px) y su padding, el
   máximo son 1,6em; a partir de 1,7em el botón de la tarjeta pasa de 40 a 40,7 px
   y la fila crece. Por eso el valor base se queda en 1,45em. */
.btn-icon-slot {
    --slot: 1.45em;
    position: relative;
    display: inline-flex;
    width: var(--slot);
    height: var(--slot);
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    vertical-align: -.15em;
}

/* El botón del detalle es más alto (64 px con el texto a 20 px, línea de 30) y
   el icono admite más tamaño sin deformar el botón. Con 1,75em el dibujo queda
   en 33 px dentro de un botón de 64: protagonista, sin comerse el texto. */
.btn-buy .btn-icon-slot { --slot: 1.75em; }

/* El dibujo del carrito es a la vez el ICONO del botón y su ANIMACIÓN: el mismo
   SVG, siempre visible. Antes el botón mostraba una canasta de Bootstrap en
   reposo y al agregar aparecía este carrito, de modo que se veía un cambio de
   icono entre dos formas distintas. Al ser el mismo dibujo, agregar no
   reemplaza nada: solo añade las piezas que caen y la palomita.
   El TEXTO tampoco se toca nunca: sigue visible durante toda la animación. */
.btn-icon-slot svg {
    display: block;
    width: 100%;
    height: 100%;
    /* Las piezas nacen por encima del lienzo: sin esto se recortarían */
    overflow: visible;
}

/* Mientras se espera la respuesta del servidor, el carrito cede el sitio al
   spinner. El dibujo NO se borra del DOM (se oculta con una clase): si se
   destruyera, el botón se quedaría sin icono ni animación para siempre.

   El centrado se hace con `inset: 0` + `margin: auto`, NO con
   `transform: translate(-50%, -50%)`: Bootstrap anima el spinner con
   `transform: rotate(360deg)` y esa animación pisa cualquier transform propio,
   así que el spinner quedaba descolocado girando fuera de su sitio. */
.spinner-border.btn-spinner {
    position: absolute;
    inset: 0;
    margin: auto;
    width: calc(var(--slot) * .72);
    height: calc(var(--slot) * .72);
    border-width: 2px;
}

.is-loading .btn-icon-slot svg { visibility: hidden; }

/* ==================== EL CARRITO ====================
   El carrito NO se oculta nunca: es el icono del botón. Todas las animaciones
   van bajo `.is-animating`, de modo que en reposo el dibujo está quieto. Así
   no hace falta ningún icono de Bootstrap que se sustituya al agregar. */

.aca-bag {
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.aca-wheel { fill: currentColor; stroke: none; }

/* Dos grupos anidados, uno por movimiento: un elemento solo admite una
   animación de `transform` a la vez (la segunda anularía a la primera).

   Los orígenes se miden en unidades del viewBox, NO del lienzo original: con
   `transform-box: view-box` el (0,0) es la esquina del viewBox, que aquí está
   en (2.1, 3.9). Así, el centro del cuerpo (14, 16.5) es (11.9, 12.6) y las
   ruedas (y=26) quedan en 22.1. Se usa view-box y no fill-box porque el
   bounding box de un grupo CAMBIA mientras las piezas caen, y el pivote de
   giro se movería durante la propia animación. */
.aca-cart, .aca-bag-tilt { transform-box: view-box; }

/* Rebote al recibir la carga, desde el centro del cuerpo del carrito */
.aca-cart { transform-origin: 11.9px 12.6px; }

/* Inclinación al llenarse, girando sobre las ruedas */
.aca-bag-tilt { transform-origin: 11.9px 22.1px; }

.is-animating .aca-cart {
    animation: aca-pop 320ms cubic-bezier(.34, 1.56, .64, 1) both;
}
.is-animating .aca-bag-tilt {
    animation: aca-tilt 760ms ease-in-out 80ms both;
}

/* ---------- Piezas que caen al carrito ---------- */
/* En reposo están invisibles: solo existen durante la animación. El retardo
   escalonado da la sensación de que se van agregando, y cada una se desvanece
   al llegar a la bolsa, así que a los ~700 ms ya no queda ninguna. */
.aca-item {
    fill: currentColor;
    stroke: none;
    opacity: 0;
}

.is-animating .aca-item {
    animation: aca-drop 400ms cubic-bezier(.4, 0, .2, 1) both;
}
.is-animating .aca-item--1 { animation-delay: 90ms; }
.is-animating .aca-item--2 { animation-delay: 190ms; }
.is-animating .aca-item--3 { animation-delay: 290ms; }

/* ---------- Palomita de confirmación ---------- */
/* Se dibuja sola con stroke-dashoffset. En reposo está oculta (dashoffset =
   largo del trazo) y solo se dibuja al agregar.
   Empieza a los 860 ms, cuando ya acabaron las piezas (la última a 690 ms) y la
   inclinación (840 ms): así no se ve a medias ni encimada a nada. */
.aca-check {
    fill: none;
    stroke: currentColor;
    stroke-width: 3.4;
    stroke-linecap: round;
    stroke-linejoin: round;
    /* 11,4 es el largo real del trazo: √(2,6²+2,6²) + √(5,4²+5,4²) = 3,68 + 7,64 */
    stroke-dasharray: 11.4;
    stroke-dashoffset: 11.4;
}

.is-animating .aca-check {
    animation: aca-check 320ms cubic-bezier(.65, 0, .35, 1) 860ms both;
}

/* ==================== ANIMACIONES ==================== */

@keyframes aca-pop {
    0%   { transform: scale(.72); }
    100% { transform: scale(1); }
}

@keyframes aca-drop {
    0%   { transform: translateY(-10px) scale(.5); opacity: 0; }
    30%  { opacity: 1; }
    65%  { transform: translateY(0) scale(1); opacity: 1; }
    100% { transform: translateY(3px) scale(.6); opacity: 0; }
}

@keyframes aca-tilt {
    0%, 100% { transform: rotate(0deg); }
    25%      { transform: rotate(-7deg); }
    55%      { transform: rotate(5deg); }
    80%      { transform: rotate(-2deg); }
}

@keyframes aca-check {
    to { stroke-dashoffset: 0; }
}

/* ==================== ACCESIBILIDAD ==================== */
/* Si el sistema pide reducir movimiento, el carrito se queda quieto y la
   confirmación aparece de golpe. El icono del botón es el mismo dibujo, así que
   se sigue viendo en reposo. */
@media (prefers-reduced-motion: reduce) {
    .aca-cart, .aca-bag-tilt, .aca-item, .aca-check { animation: none !important; }

    .is-animating .aca-check { stroke-dashoffset: 0; }
}
