/* ==========================================================================
   PORTAL · ANIMACIONES GYM (NUBIFIT) — v2
   --------------------------------------------------------------------------
   Cargar DESPUÉS de portal.css (idealmente al final de los <link> de CSS).
   100% aditivo: no cambia layout, solo movimiento. Usa únicamente los
   colores de variables.css (--color-primario, --color-exito, --color-error…).

   Qué trae de nuevo respecto a la v1
   - Resortes reales con linear() (fallback automático a cubic-bezier).
   - Entradas escalonadas ("series") al cambiar de pestaña.
   - Revelado al hacer scroll (animation-timeline: view()) en listas largas.
   - Propiedades individuales translate/scale/rotate: las animaciones ya no
     pisan los transform de los :hover de portal.css.
   - Animaciones por movimiento: sentadilla, bisagra, empuje, tracción, core
     y cardio (usa data-movimiento de portal-rutina-dia.css).
   - Latido ECG, llama de racha, escáner QR con visor, pista de energía,
     explosión de repetición completada, mancuerna que "levanta" en vacíos.
   - Todo lo decorativo e infinito se apaga con prefers-reduced-motion.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. TOKENS
   NOTA: portal.css usa var(--gym-ease-*) pero esas variables solo existían en
   este archivo; si no se enlazaba, todas esas transiciones quedaban inválidas.
   -------------------------------------------------------------------------- */
@property --gym-angulo {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

:root {
    /* Curvas heredadas (portal.css las sigue usando) */
    --gym-ease-concentric: cubic-bezier(0.16, 1, 0.3, 1);
    --gym-ease-elastic:    cubic-bezier(0.34, 1.56, 0.64, 1);
    --gym-ease-eccentric:  cubic-bezier(0.25, 1, 0.5, 1);
    --gym-ease-cadence:    cubic-bezier(0.4, 0, 0.2, 1);
    --gym-ease-smooth:     cubic-bezier(0.45, 0, 0.25, 1);
    --gym-ease-salida:  var(--gym-ease-concentric);
    --gym-ease-resorte: var(--gym-ease-elastic);
    --gym-ease-suave:   var(--gym-ease-smooth);

    /* Resortes nuevos (fallback si el navegador no soporta linear()) */
    --gym-spring:      cubic-bezier(0.34, 1.45, 0.64, 1);
    --gym-spring-soft: cubic-bezier(0.22, 1.18, 0.36, 1);

    --gym-dur-rapida: 0.18s;
    --gym-dur-media:  0.35s;
    --gym-dur-lenta:  0.6s;
    --gym-stagger:    55ms;

    --gym-resplandor: color-mix(in srgb, var(--color-primario) 26%, transparent);
    --gym-resplandor-exito: color-mix(in srgb, var(--color-exito) 30%, transparent);
}

@supports (transition-timing-function: linear(0, 1)) {
    :root {
        /* Resorte con rebote medio (≈9 %) */
        --gym-spring: linear(0, 0.038, 0.133, 0.262, 0.405, 0.549, 0.682, 0.798, 0.895, 0.97, 1.026, 1.063, 1.085, 1.094, 1.094, 1.087, 1.076, 1.063, 1.049, 1.036, 1.024, 1.014, 1.006, 1, 1);
        /* Resorte suave (≈1,5 %): ideal para tarjetas y listas */
        --gym-spring-soft: linear(0, 0.03, 0.104, 0.203, 0.312, 0.422, 0.527, 0.623, 0.706, 0.778, 0.837, 0.885, 0.923, 0.953, 0.975, 0.99, 1.001, 1.008, 1.013, 1.015, 1);
    }
}

/* --------------------------------------------------------------------------
   1. KEYFRAMES
   -------------------------------------------------------------------------- */

/* Entradas modernas (propiedades individuales: no chocan con :hover) */
@keyframes gym-in {
    from { opacity: 0; translate: 0 16px; scale: 0.98; }
    to   { opacity: 1; translate: 0 0;    scale: 1; }
}
@keyframes gym-in-izq {
    from { opacity: 0; translate: -18px 0; }
    to   { opacity: 1; translate: 0 0; }
}
@keyframes gym-revelar {
    from { opacity: 0; translate: 0 22px; scale: 0.975; }
    to   { opacity: 1; translate: 0 0;    scale: 1; }
}
@keyframes gym-pop-suave {
    from { opacity: 0; scale: 0.4; rotate: -12deg; }
    to   { opacity: 1; scale: 1;   rotate: 0deg; }
}
@keyframes gym-impacto {
    from { opacity: 0; translate: 0 30px; scale: 0.93; }
    to   { opacity: 1; translate: 0 0;    scale: 1; }
}
@keyframes gym-indicador {
    from { scale: 0 1; opacity: 0; }
    to   { scale: 1 1; opacity: 1; }
}
@keyframes gym-trazar {
    from { scale: 1 0; }
    to   { scale: 1 1; }
}

/* Nombres heredados: portal.css los usa, aquí quedan modernizados */
@keyframes gym-subir      { from { opacity: 0; transform: translateY(16px) scale(0.985); } to { opacity: 1; transform: none; } }
@keyframes gym-entrar-izq { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
@keyframes gym-bajar      { from { opacity: 0; transform: translateY(-14px); } to { opacity: 1; transform: none; } }
@keyframes gym-nav-entra  { from { transform: translateY(100%); } to { transform: none; } }
@keyframes gym-fondo      { from { opacity: 0; } to { opacity: 1; } }
@keyframes gym-escala     { from { transform: scale(0.9); } to { transform: scale(1); } }
@keyframes gym-hoja       { from { transform: translateY(100%); } to { transform: none; } }
@keyframes gym-panel      { from { opacity: 0; transform: translateY(-8px) scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes gym-modal-slam    { 0% { opacity: 0; transform: translateY(26px) scale(0.93); } 70% { opacity: 1; transform: translateY(-2px) scale(1.01); } 100% { opacity: 1; transform: none; } }
@keyframes gym-modal-entrada { 0% { opacity: 0; transform: translateY(26px) scale(0.93); } 70% { opacity: 1; transform: translateY(-2px) scale(1.01); } 100% { opacity: 1; transform: none; } }
@keyframes gym-pop {
    0%   { opacity: 0; transform: scale(0) rotate(-18deg); }
    60%  { opacity: 1; transform: scale(1.22) rotate(5deg); }
    100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes gym-onda { from { opacity: 0.85; transform: scale(0.6); } to { opacity: 0; transform: scale(1.9); } }

/* Movimientos del gimnasio */
@keyframes gym-curl {
    0%, 100% { transform: rotate(0); }
    35%      { transform: rotate(-16deg) translateY(-2px); }
    70%      { transform: rotate(7deg); }
}
@keyframes gym-levantar {
    0%, 100% { transform: translateY(0) scale(1); }
    45%, 60% { transform: translateY(-4px) scale(1.1); }
}
@keyframes gym-latido {
    0%, 60%, 100% { transform: scale(1); }
    12%           { transform: scale(1.2); }
    24%           { transform: scale(1); }
    36%           { transform: scale(1.14); }
}
@keyframes gym-flotar {
    0%, 100% { transform: translateY(0) rotate(-2deg); }
    50%      { transform: translateY(-6px) rotate(2deg); }
}
@keyframes gym-giro-disco { to { transform: rotate(360deg); } }
@keyframes gym-respirar {
    0%, 100% { transform: scale(1); opacity: 0.9; }
    50%      { transform: scale(1.07); opacity: 1; }
}
@keyframes gym-brillo     { from { transform: translateX(-120%) skewX(-20deg); } to { transform: translateX(280%) skewX(-20deg); } }
@keyframes gym-barra-brillo { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes gym-barra      { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes gym-escaneo    { 0% { top: 6%; opacity: 0; } 15%, 85% { opacity: 1; } 100% { top: 92%; opacity: 0; } }
@keyframes gym-subrayado  { to { background-size: 100% 0.14em; } }
@keyframes gym-sacudida {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-6px); } 40% { transform: translateX(6px); }
    60% { transform: translateX(-4px); } 80% { transform: translateX(4px); }
}
@keyframes gym-timbre {
    0%, 100% { transform: rotate(0); }
    12% { transform: rotate(14deg); } 24% { transform: rotate(-12deg); }
    36% { transform: rotate(8deg); }  48% { transform: rotate(-6deg); } 60% { transform: rotate(0); }
}
@keyframes gym-aviso {
    0%, 62%, 100% { transform: rotate(0); }
    70% { transform: rotate(-14deg); } 78% { transform: rotate(10deg); }
    86% { transform: rotate(-6deg); }  94% { transform: rotate(3deg); }
}
@keyframes gym-chispa { 0%, 100% { transform: scale(1) rotate(0); } 50% { transform: scale(1.22) rotate(14deg); } }
@keyframes gym-pulso-flotante {
    0%, 100% { box-shadow: 0 14px 30px rgba(15, 23, 42, 0.26), 0 0 0 0 rgba(37, 99, 235, 0.46); }
    70%      { box-shadow: 0 14px 30px rgba(15, 23, 42, 0.26), 0 0 0 16px rgba(37, 99, 235, 0); }
}
@keyframes gym-loader-press { 0%, 100% { transform: translateY(0.28rem); } 45%, 55% { transform: translateY(-0.28rem); } }
@keyframes gym-parpadeo { 50% { opacity: 0.4; } }

/* Nuevos */
/* Llama de racha / calentamiento */
@keyframes gym-llama {
    0%, 100% { transform: scale(1, 1) rotate(0); }
    25%      { transform: scale(1.04, 1.12) rotate(-3deg); }
    50%      { transform: scale(0.97, 1.04) rotate(2deg); }
    75%      { transform: scale(1.03, 1.14) rotate(-2deg); }
}
/* Una repetición completa de mancuerna: sube, sostiene, baja */
@keyframes gym-mancuerna {
    0%, 100% { translate: 0 0;    rotate: 0deg; }
    30%      { translate: 0 -9px; rotate: -5deg; }
    50%      { translate: 0 -9px; rotate: 5deg; }
    75%      { translate: 0 0;    rotate: 0deg; }
}
/* Anillo que se expande (ping) */
@keyframes gym-ping {
    0%        { transform: scale(1); opacity: 0.55; }
    75%, 100% { transform: scale(2.1); opacity: 0; }
}
@keyframes gym-ping-sombra {
    0%        { box-shadow: 0 0 0 0 var(--gym-resplandor); }
    75%, 100% { box-shadow: 0 0 0 8px transparent; }
}
/* Traza de electrocardiograma que avanza y se apaga */
@keyframes gym-ecg {
    0%   { clip-path: inset(0 100% 0 0); opacity: 1; }
    55%  { clip-path: inset(0 0 0 0);    opacity: 1; }
    85%  { clip-path: inset(0 0 0 0);    opacity: 1; }
    100% { clip-path: inset(0 0 0 0);    opacity: 0; }
}
/* Haz de escáner con estela (visor del torniquete) */
@keyframes gym-barrido {
    0%   { transform: translateY(-100%); opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { transform: translateY(263%); opacity: 0; }
}
@keyframes gym-enfocar {
    0%, 100% { scale: 1;    opacity: 1; }
    50%      { scale: 0.965; opacity: 0.7; }
}
/* Vuelta a la pista alrededor de la tarjeta de acceso */
@keyframes gym-orbita { to { --gym-angulo: 360deg; } }
/* Destello periódico tipo "nuevo récord" */
@keyframes gym-destello {
    0%, 70%   { transform: translateX(-130%) skewX(-18deg); }
    100%      { transform: translateX(330%) skewX(-18deg); }
}
/* Ráfaga al completar una repetición */
@keyframes gym-rafaga {
    from { transform: scale(0.35) rotate(0deg); opacity: 1; }
    to   { transform: scale(1.9) rotate(30deg); opacity: 0; }
}
@keyframes gym-completado {
    from { background-color: var(--gym-resplandor-exito); }
    to   { background-color: transparent; }
}
@keyframes gym-estrella {
    0%   { scale: 1; }
    45%  { scale: 1.35; rotate: -10deg; }
    100% { scale: 1; rotate: 0deg; }
}
@keyframes gym-acento { from { box-shadow: inset 0 0 0 0 var(--color-primario); } to { box-shadow: inset 3px 0 0 0 var(--color-primario); } }
@keyframes gym-skeleton { to { background-position: -200% 0; } }
@keyframes gym-header-sombra { to { box-shadow: 0 10px 28px -14px rgba(15, 23, 42, 0.28); } }

/* Movimientos por tipo de ejercicio (Entrenamiento de hoy) */
@keyframes gym-mov-sentadilla { 0%, 100% { translate: 0 0; } 45%, 60% { translate: 0 4px; scale: 1 0.9; } }
@keyframes gym-mov-bisagra    { 0%, 100% { rotate: 0deg; } 45%, 60% { rotate: 22deg; } }
@keyframes gym-mov-empuje     { 0%, 100% { translate: 0 0; } 45%, 60% { translate: 5px 0; } }
@keyframes gym-mov-traccion   { 0%, 100% { translate: 0 0; } 45%, 60% { translate: -5px 0; } }
@keyframes gym-mov-core       { 0%, 100% { scale: 1; } 45%, 60% { scale: 1.18 0.92; } }

/* Revelado al hacer scroll */
@keyframes gym-scroll-revelar {
    from { opacity: 0; translate: 0 26px; scale: 0.97; }
    to   { opacity: 1; translate: 0 0;    scale: 1; }
}

/* --------------------------------------------------------------------------
   2. ENTRADAS ESCALONADAS ("SERIES") AL CAMBIAR DE PESTAÑA
   -------------------------------------------------------------------------- */
.seccion-tab.activa { animation: gym-fondo 0.28s ease backwards; }

:is(
    .seccion-tab.activa > .vista-encabezado,
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) { --i: 0; }

:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > * {
    animation: gym-in var(--gym-dur-lenta) var(--gym-spring-soft) backwards;
    animation-delay: calc(var(--i, 0) * var(--gym-stagger) + 80ms);
}
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(1) { --i: 0; }
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(2) { --i: 1; }
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(3) { --i: 2; }
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(4) { --i: 3; }
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(5) { --i: 4; }
:is(
    .resumen-grid, .resumen-actividad, .resumen-pagos, .resumen-reservas,
    .detalle-grid, .avisos-resumen, .pv-metricas, .opciones-acceso,
    .entrenamiento-hoy-bloques, .entrenamiento-hoy-ejercicios,
    .filtros-pagos, .portal-menu-opciones
) > :nth-child(n+6) { --i: 5; }

.seccion-tab.activa > .vista-encabezado {
    animation: gym-in var(--gym-dur-lenta) var(--gym-spring-soft) backwards;
}

/* Listas largas: revelado ligado al scroll; si no hay soporte, entrada simple */
:is(.asistencia-registro, .pago-registro, .agenda-reserva-card, .agenda-clase-card,
    .reserva-item, .pv-item, .aviso-notificacion, .producto-tienda) {
    animation: gym-in 0.5s var(--gym-spring-soft) backwards;
}
@supports (animation-timeline: view()) {
    :is(.asistencia-registro, .pago-registro, .agenda-reserva-card, .agenda-clase-card,
        .reserva-item, .pv-item, .aviso-notificacion, .producto-tienda) {
        animation: gym-scroll-revelar linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 55%;
    }
}

/* --------------------------------------------------------------------------
   3. ACCESO / LOGIN
   -------------------------------------------------------------------------- */
#pantallaLogin { position: relative; isolation: isolate; overflow: hidden; }

/* Discos olímpicos: aro, rayos tenues y orificio central */
#pantallaLogin::before,
#pantallaLogin::after {
    content: '';
    position: absolute;
    z-index: -1;
    pointer-events: none;
    aspect-ratio: 1;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--color-primario) 13%, transparent);
    background:
        radial-gradient(circle, color-mix(in srgb, var(--color-superficie) 75%, transparent) 0 9%,
            color-mix(in srgb, var(--color-primario) 10%, transparent) 9.5% 11.5%, transparent 12%),
        repeating-conic-gradient(color-mix(in srgb, var(--color-primario) 5%, transparent) 0 8deg, transparent 8deg 45deg);
    box-shadow:
        inset 0 0 0 16px color-mix(in srgb, var(--color-primario) 3%, transparent),
        inset 0 0 0 34px color-mix(in srgb, var(--color-primario) 2%, transparent);
}
#pantallaLogin::before {
    width: clamp(18rem, 40vw, 32rem); right: -7rem; top: -8rem;
    animation: gym-giro-disco 90s linear infinite;
}
#pantallaLogin::after {
    width: clamp(12rem, 24vw, 20rem); left: -5rem; bottom: -6rem;
    animation: gym-giro-disco 70s linear infinite reverse;
}

.login-branding { animation: gym-in-izq 0.7s var(--gym-spring-soft) backwards; }
.login-card { animation: gym-in 0.7s 0.1s var(--gym-spring-soft) backwards; }
.selector-acceso, .panel-acceso { animation: gym-in 0.45s var(--gym-spring-soft) backwards; }
.paso-credenciales { animation: gym-in 0.35s var(--gym-spring-soft) backwards; }
.login-card-icon { animation: gym-pop-suave 0.7s 0.25s var(--gym-spring) backwards; }
.login-card:hover .login-card-icon svg { animation: gym-curl 0.7s ease-in-out; }
.portal-logo-plataforma { animation: gym-in 0.6s var(--gym-spring-soft) backwards; }

/* Pulso cardíaco (ECG) bajo el titular */
.login-branding::after {
    content: '';
    display: block;
    width: min(20rem, 100%);
    height: 2.2rem;
    margin-top: 1.4rem;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 36' fill='none' stroke='%232563eb' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M0 20H78l8-3 8 3h10l7-16 10 30 9-24 7 10h12l8-4 8 4h140'/%3E%3C/svg%3E") left center / contain no-repeat;
    opacity: 0.75;
    animation: gym-ecg 4.2s var(--gym-ease-smooth) 0.8s infinite;
}

/* Barra de levantamiento bajo la palabra clave */
.login-branding h1 span {
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 0.14em no-repeat;
    padding-bottom: 0.06em;
    animation: gym-subrayado 0.9s 0.45s var(--gym-ease-concentric) forwards;
}

.opcion-acceso {
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.3s var(--gym-spring), box-shadow 0.25s ease;
}
.opcion-acceso:hover {
    box-shadow: 0 10px 22px -8px var(--gym-resplandor);
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--color-primario) 45%, var(--color-borde));
    background: var(--color-primario-light);
}
.opcion-acceso:active { transform: scale(0.98); }
.opcion-acceso > svg { transition: transform 0.3s var(--gym-spring); }
.opcion-acceso:hover > svg:first-child { transform: rotate(-8deg) scale(1.1); }
.opcion-acceso:hover > svg:last-child { transform: translateX(5px); }

.input-control { transition: border-color 0.2s ease, box-shadow 0.25s ease; }
.input-control:focus {
    border-color: var(--color-primario);
    box-shadow: 0 0 0 4px var(--gym-resplandor);
}
.mensaje-login:not(.mensaje-acceso):not(:empty) { animation: gym-sacudida 0.45s ease; }

@media (max-width: 800px) {
    .login-branding::after { height: 1.8rem; margin-top: 1rem; }
}

/* --------------------------------------------------------------------------
   4. ESTRUCTURA: HEADER, NAVEGACIÓN, AVATAR
   -------------------------------------------------------------------------- */
.portal-header { animation: gym-bajar 0.5s var(--gym-spring-soft) backwards; }
@supports (animation-timeline: scroll()) {
    .portal-header {
        animation: gym-bajar 0.5s var(--gym-spring-soft) backwards, gym-header-sombra linear both;
        animation-timeline: auto, scroll(root);
        animation-range: normal, 0 90px;
    }
}
.portal-nav { animation: gym-nav-entra 0.6s 0.08s var(--gym-spring-soft) backwards; }

.nav-tab { transition: color 0.22s ease, background 0.22s ease, transform 0.25s var(--gym-spring); }
.nav-tab:active { transform: scale(0.9); }
.nav-tab.activa svg { animation: gym-levantar 0.55s var(--gym-spring); }

/* Indicador superior: placa que se desliza al activar la pestaña */
.nav-tab:not(.nav-tab-mas).activa::before {
    content: '';
    position: absolute;
    top: -0.55rem;
    left: 50%;
    width: 1.8rem;
    height: 3px;
    translate: -50% 0;
    border-radius: 0 0 4px 4px;
    background: var(--color-primario);
    box-shadow: 0 2px 10px var(--gym-resplandor);
    animation: gym-indicador 0.45s var(--gym-spring) backwards;
}

/* La pestaña "Hoy" (llama) arde mientras está activa o con el cursor encima */
.nav-tab[data-target="tab-entrenamiento-hoy"] svg { transform-origin: 50% 90%; }
.nav-tab[data-target="tab-entrenamiento-hoy"].activa svg {
    animation: gym-levantar 0.55s var(--gym-spring), gym-llama 1.8s 0.55s ease-in-out infinite;
}
@media (hover: hover) {
    .nav-tab[data-target="tab-entrenamiento-hoy"]:hover svg { animation: gym-llama 1.2s ease-in-out infinite; }
}

/* Campana: suena sola (con pausa larga) cuando hay avisos sin leer */
.btn-campana { transition: background 0.2s ease, color 0.2s ease, transform 0.25s var(--gym-spring); }
.btn-campana:active { transform: scale(0.9); }
.btn-campana:hover svg, .btn-campana:focus-visible svg { animation: gym-timbre 0.7s ease-in-out; transform-origin: 50% 0; }
.btn-campana:has(.badge-notificaciones:not(.oculto)) > svg {
    transform-origin: 50% 0;
    animation: gym-aviso 6s 1.5s ease-in-out infinite;
}
.badge-notificaciones { animation: gym-latido 3.2s ease-in-out infinite; }
#puntoBadgeCalificar { animation: gym-latido 2.8s ease-in-out infinite; }
#puntoBadgeCalificar::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--color-primario);
    animation: gym-ping 2.2s cubic-bezier(0, 0, 0.2, 1) infinite;
    pointer-events: none;
}

.perfil-avatar { position: relative; animation: gym-pop-suave 0.6s var(--gym-spring) backwards; transition: transform 0.3s var(--gym-spring); }
.perfil-avatar:hover { transform: scale(1.05); }
.perfil-avatar::after {
    content: '';
    position: absolute;
    inset: -5px;
    border: 2px solid color-mix(in srgb, var(--color-primario) 32%, transparent);
    border-radius: 50%;
    animation: gym-respirar 3.4s ease-in-out infinite;
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   5. TARJETAS Y BOTONES
   -------------------------------------------------------------------------- */
@media (hover: hover) {
    .resumen-item, .detalle-item, .producto-tienda, .reserva-item, .pago-registro,
    .agenda-reserva-card, .agenda-clase-card, .asistencia-registro, .perfil-panel {
        transition: transform 0.3s var(--gym-spring), box-shadow 0.3s ease, border-color 0.3s ease;
    }
    .resumen-item:hover, .detalle-item:hover, .producto-tienda:hover, .reserva-item:hover,
    .agenda-reserva-card:hover, .agenda-clase-card:hover, .asistencia-registro:hover, .pago-registro:hover {
        transform: translateY(-3px);
        box-shadow: 0 14px 26px -12px var(--gym-resplandor);
        border-color: color-mix(in srgb, var(--color-primario) 30%, var(--color-borde));
    }
}
.inicio-resumen-icono { transition: transform 0.35s var(--gym-spring); }
.resumen-item:hover .inicio-resumen-icono { transform: rotate(-8deg) scale(1.12); }

.btn {
    position: relative;
    overflow: hidden;
    transition: transform 0.25s var(--gym-spring), box-shadow 0.25s ease, background 0.2s ease, opacity 0.2s ease;
}
.btn:not(:disabled):hover { transform: translateY(-2px); box-shadow: 0 10px 22px -6px var(--gym-resplandor); }
.btn:not(:disabled):active { transform: translateY(0) scale(0.97); box-shadow: none; }

/* Reflejo metálico en botones primarios */
.btn:not(.btn-outline):not(.btn-secundario):not(.btn-cancelar):not(:disabled)::after {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 40%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
    transform: translateX(-130%) skewX(-20deg);
    pointer-events: none;
}
.btn:not(.btn-outline):not(.btn-secundario):not(.btn-cancelar):not(:disabled):hover::after { animation: gym-brillo 0.7s ease; }

.btn-secundario:not(:disabled):hover, .btn-cancelar:not(:disabled):hover { box-shadow: var(--sombra-md); }
.btn-peligro:not(:disabled):hover { box-shadow: 0 10px 20px -6px color-mix(in srgb, var(--color-error) 45%, transparent); }
.btn-reintentar, .btn-cargar-mas, .btn-guardar-qr { transition: transform 0.25s var(--gym-spring), background 0.2s ease; }
.btn-reintentar:active, .btn-cargar-mas:active, .btn-guardar-qr:active { transform: scale(0.95); }

/* Widget de racha: llama viva y destello periódico de "récord" */
.widget-asistencia {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: transform 0.3s var(--gym-spring), box-shadow 0.3s ease;
}
.widget-asistencia:hover { transform: translateY(-2px); box-shadow: 0 16px 30px -12px var(--gym-resplandor); }
.widget-asistencia:active { transform: scale(0.98); }
.widget-asistencia > svg { transform-origin: 50% 90%; animation: gym-llama 2.2s ease-in-out infinite; }
.widget-asistencia:hover > svg { animation: gym-curl 0.7s ease-in-out; }
.widget-asistencia::after {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 35%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.22), transparent);
    pointer-events: none;
    z-index: -1;
    animation: gym-destello 6s ease-in-out 1.5s infinite;
}

.estado-error { animation: gym-sacudida 0.45s ease; }

.estrella-calificacion { transition: color 0.15s ease, transform 0.3s var(--gym-spring), background 0.15s ease; }
.estrella-calificacion:hover, .estrella-calificacion:focus-visible { transform: translateY(-3px) scale(1.18); }
.estrella-calificacion:active { transform: scale(0.9); }
/* Las estrellas elegidas se encienden en cascada */
.estrella-calificacion[aria-pressed="true"] { animation: gym-estrella 0.5s var(--gym-spring) backwards; }
.estrella-calificacion[aria-pressed="true"]:nth-child(2) { animation-delay: 60ms; }
.estrella-calificacion[aria-pressed="true"]:nth-child(3) { animation-delay: 120ms; }
.estrella-calificacion[aria-pressed="true"]:nth-child(4) { animation-delay: 180ms; }
.estrella-calificacion[aria-pressed="true"]:nth-child(5) { animation-delay: 240ms; }

.producto-tienda-agregar, .control-cantidad-tienda button { transition: transform 0.22s var(--gym-spring), background 0.2s ease; }
.producto-tienda-agregar:active, .control-cantidad-tienda button:active { transform: scale(0.9); }

.interruptor > span { transition: background 0.22s var(--gym-ease-concentric); }
.interruptor > span::after { transition: transform 0.3s var(--gym-spring), width 0.15s ease; }
.interruptor input:active + span::after { width: 29px; }
.interruptor input:checked:active + span::after { transform: translateX(19px); }

.filtro-pagos { transition: background 0.2s ease, color 0.2s ease, transform 0.22s var(--gym-spring); }
.filtro-pagos:active { transform: scale(0.94); }

/* --------------------------------------------------------------------------
   6. CARGADORES, ESQUELETOS Y ESTADOS VACÍOS
   -------------------------------------------------------------------------- */
.icono-girando, .spin, .resumen-actividad-cargando svg, .lucide-loader-circle {
    animation: gym-giro-disco 0.9s linear infinite;
}
.btn-actualizar-entrenamiento svg { transition: transform 0.4s var(--gym-spring); }
.btn-actualizar-entrenamiento:not(:disabled):hover svg { transform: rotate(180deg); }
.btn-actualizar-entrenamiento:disabled svg { animation: gym-giro-disco 0.9s linear infinite; }

/* Barra con discos: el cargador "haciendo press" */
.gym-loader {
    --gl: var(--color-primario);
    display: inline-block;
    width: 3.2rem;
    height: 1.5rem;
    vertical-align: middle;
    background:
        linear-gradient(var(--gl), var(--gl)) 0 50% / .3rem 100% no-repeat,
        linear-gradient(var(--gl), var(--gl)) .4rem 50% / .3rem 72% no-repeat,
        linear-gradient(var(--gl), var(--gl)) 50% 50% / calc(100% - 1.4rem) .18rem no-repeat,
        linear-gradient(var(--gl), var(--gl)) calc(100% - .4rem) 50% / .3rem 72% no-repeat,
        linear-gradient(var(--gl), var(--gl)) 100% 50% / .3rem 100% no-repeat;
    animation: gym-loader-press 1.1s var(--gym-ease-smooth) infinite;
}

/* Utilidad: esqueleto de carga (añade class="gym-skeleton" a un bloque vacío) */
.gym-skeleton {
    min-height: 1em;
    border-radius: var(--radio-md);
    background: linear-gradient(90deg, var(--color-borde) 25%, color-mix(in srgb, var(--color-superficie) 65%, var(--color-borde)) 50%, var(--color-borde) 75%) 0 0 / 200% 100%;
    animation: gym-skeleton 1.4s linear infinite;
}

/* Estados vacíos: la mancuerna hace una repetición; el resto flota */
.estado-vacio svg, .entrenamiento-hoy-vacio svg, .pv-vacio svg, .notificaciones-vacio svg {
    animation: gym-flotar 3.6s ease-in-out infinite;
}
.estado-vacio .lucide-dumbbell, .entrenamiento-hoy-vacio .lucide-dumbbell {
    animation: gym-mancuerna 3.4s ease-in-out infinite;
}

/* --------------------------------------------------------------------------
   7. MODALES Y DIÁLOGOS
   -------------------------------------------------------------------------- */
.modal-portal { animation: gym-fondo 0.25s ease backwards; backdrop-filter: blur(5px); }
.modal-portal-contenido { animation: gym-impacto 0.6s var(--gym-spring) backwards; }
.modal-portal-icono { position: relative; animation: gym-pop-suave 0.6s 0.12s var(--gym-spring) backwards; }
/* Onda de impacto detrás del icono */
.modal-portal-icono::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 2px solid var(--color-primario);
    pointer-events: none;
    animation: gym-ping 1s 0.35s ease-out 1 backwards;
}
.modal-portal-icono.modal-icono-peligro { animation: gym-pop-suave 0.55s 0.12s var(--gym-spring) backwards, gym-sacudida 0.45s 0.65s ease; }
.modal-portal-icono.modal-icono-peligro::after { border-color: var(--color-error); }
.modal-calificacion-icono { animation: gym-pop-suave 0.6s 0.12s var(--gym-spring) backwards; }
.btn-cerrar-modal, .modal-portal-cerrar { transition: background 0.2s ease, color 0.2s ease, transform 0.3s var(--gym-spring); }
.btn-cerrar-modal:hover, .modal-portal-cerrar:hover { transform: rotate(90deg); }

.modal-overlay.activo .icono-confirmacion { animation: gym-pop-suave 0.55s 0.1s var(--gym-spring) backwards; }
.selector-gimnasio { animation: gym-fondo 0.25s ease backwards; }
.selector-gimnasio-tarjeta { animation: gym-impacto 0.6s var(--gym-spring) backwards; }

.anuncio-popup { animation: gym-impacto 0.6s var(--gym-spring) backwards; }
.anuncio-popup-dialog::backdrop { animation: gym-fondo 0.3s ease backwards; }
.anuncio-popup-etiqueta svg { animation: gym-chispa 2.4s ease-in-out infinite; }
.anuncio-popup-cerrar { transition: transform 0.3s var(--gym-spring), background 0.2s ease; }
.anuncio-popup-cerrar:hover { transform: rotate(90deg) scale(1.08); }
.aviso-clase-flotante { transition: transform 0.55s var(--gym-spring), opacity 0.25s ease; }

/* --------------------------------------------------------------------------
   8. TARJETA DE ACCESO (PASE QR DE TORNIQUETE)
   -------------------------------------------------------------------------- */
.tarjeta-acceso {
    animation: gym-in 0.65s var(--gym-spring-soft) backwards;
    transition: transform 0.3s var(--gym-spring), box-shadow 0.3s ease;
}
.tarjeta-acceso:hover {
    transform: translateY(-3px);
    box-shadow: 0 26px 38px -8px var(--gym-resplandor), 0 10px 15px -5px rgba(0, 0, 0, 0.04);
}
.tarjeta-acceso.activa::before {
    background: linear-gradient(90deg, var(--color-exito) 0%, color-mix(in srgb, var(--color-exito) 25%, #fff) 50%, var(--color-exito) 100%);
    background-size: 200% 100%;
    animation: gym-barra 2.6s linear infinite;
}
/* Acceso concedido: un destello recorre el borde como corredor en pista */
.tarjeta-acceso.activa::after {
    content: '';
    position: absolute;
    inset: 0;
    padding: 2px;
    border-radius: inherit;
    pointer-events: none;
    background: conic-gradient(from var(--gym-angulo), transparent 0 72%, color-mix(in srgb, var(--color-exito) 90%, transparent) 94%, transparent 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    animation: gym-orbita 4.5s linear infinite;
}

#codigoQR {
    position: relative;
    overflow: hidden;
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
#codigoQR:hover {
    border-color: color-mix(in srgb, var(--color-primario) 45%, var(--color-borde));
    box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06), 0 0 18px var(--gym-resplandor);
}
#codigoQR img { animation: gym-in 0.5s var(--gym-spring-soft) backwards; }

/* Barrido con estela: la línea brillante es el borde inferior de la banda */
#codigoQR:not(:empty)::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 38%;
    background: linear-gradient(180deg,
        transparent 0%,
        color-mix(in srgb, var(--color-primario) 16%, transparent) 78%,
        color-mix(in srgb, var(--color-primario) 50%, transparent) 98%,
        var(--color-primario) 100%);
    pointer-events: none;
    will-change: transform;
    transform: translateY(-100%);
    animation: gym-barrido 3.2s var(--gym-ease-smooth) infinite;
}
/* Visor de escáner: cuatro esquinas que "enfocan" */
#codigoQR:not(:empty)::after {
    --c: var(--color-primario);
    content: '';
    position: absolute;
    inset: 0.45rem;
    left: 0.45rem;
    right: 0.45rem;
    top: 0.45rem;
    height: auto;
    border-radius: 0;
    box-shadow: none;
    background:
        linear-gradient(var(--c), var(--c)) 0 0 / 18px 2px no-repeat,
        linear-gradient(var(--c), var(--c)) 0 0 / 2px 18px no-repeat,
        linear-gradient(var(--c), var(--c)) 100% 0 / 18px 2px no-repeat,
        linear-gradient(var(--c), var(--c)) 100% 0 / 2px 18px no-repeat,
        linear-gradient(var(--c), var(--c)) 0 100% / 18px 2px no-repeat,
        linear-gradient(var(--c), var(--c)) 0 100% / 2px 18px no-repeat,
        linear-gradient(var(--c), var(--c)) 100% 100% / 18px 2px no-repeat,
        linear-gradient(var(--c), var(--c)) 100% 100% / 2px 18px no-repeat;
    pointer-events: none;
    animation: gym-enfocar 2.4s ease-in-out infinite;
}
.tarjeta-acceso.inactiva #codigoQR::before,
.tarjeta-acceso.inactiva #codigoQR::after { display: none; }

/* --------------------------------------------------------------------------
   9. MI RUTINA Y REPETICIONES
   -------------------------------------------------------------------------- */
.rutina-barra-progreso span {
    position: relative;
    overflow: hidden;
    transition: width 0.8s var(--gym-spring-soft);
}
.rutina-barra-progreso span::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    animation: gym-barra-brillo 1.8s ease-in-out infinite;
}

.rutina-dia-tab { transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.25s var(--gym-spring); }
.rutina-dia-tab:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--color-primario) 45%, var(--color-borde)); }
.rutina-dia-tab:active { transform: scale(0.94); }
.rutina-dia-tab.activo { animation: gym-escala 0.4s var(--gym-spring); }

.rutina-ejercicio-cliente { transition: background-color 0.4s ease; }
.rutina-check { position: relative; transition: transform 0.25s var(--gym-spring), color 0.2s ease; }
.rutina-check:hover { transform: scale(1.15); }
.rutina-check:active { transform: scale(0.82); }

/* Repetición completada: check con rebote, onda, ráfaga de chispas y brillo de fila */
.rutina-ejercicio-cliente.completado { animation: gym-completado 1.1s ease-out; }
.rutina-ejercicio-cliente.completado .rutina-check svg { animation: gym-pop 0.55s var(--gym-spring); }
.rutina-ejercicio-cliente.completado .rutina-check::after {
    content: '';
    position: absolute;
    inset: -3px;
    border: 2px solid var(--color-exito);
    border-radius: 50%;
    pointer-events: none;
    animation: gym-onda 0.65s ease-out both;
}
.rutina-ejercicio-cliente.completado .rutina-check::before {
    content: '';
    position: absolute;
    inset: -9px;
    border-radius: 50%;
    pointer-events: none;
    background: repeating-conic-gradient(var(--color-exito) 0 5deg, transparent 5deg 60deg);
    -webkit-mask: radial-gradient(circle, transparent 52%, #000 54%, #000 74%, transparent 76%);
    mask: radial-gradient(circle, transparent 52%, #000 54%, #000 74%, transparent 76%);
    animation: gym-rafaga 0.7s ease-out both;
}

.rutina-descanso { transition: background 0.2s ease, transform 0.25s var(--gym-spring); }
.rutina-descanso:hover { background: var(--color-primario-light); transform: rotate(-8deg) scale(1.1); }
.rutina-temporizador { animation: gym-in 0.5s var(--gym-spring) backwards; }
.rutina-temporizador svg { animation: gym-latido 1.2s ease-in-out infinite; }
.rutina-sesion-resumen button { transition: background 0.2s ease, transform 0.22s var(--gym-spring); }
.rutina-sesion-resumen button:active { transform: scale(0.94); }

/* --------------------------------------------------------------------------
   10. ENTRENAMIENTO DE HOY Y VALORACIÓN
   -------------------------------------------------------------------------- */
.entrenamiento-hoy-hero::after { animation: gym-respirar 7s ease-in-out infinite; }
.entrenamiento-hoy-hero::before {
    content: '';
    position: absolute;
    right: -6.5rem;
    top: -8.5rem;
    width: 15rem;
    height: 15rem;
    border: 2px dashed rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    animation: gym-giro-disco 60s linear infinite;
    pointer-events: none;
}
.entrenamiento-hoy-chips span, .entrenamiento-hoy-zonas span { animation: gym-pop-suave 0.5s var(--gym-spring) backwards; }
.entrenamiento-hoy-chips span:nth-child(2), .entrenamiento-hoy-zonas span:nth-child(2) { animation-delay: 70ms; }
.entrenamiento-hoy-chips span:nth-child(3), .entrenamiento-hoy-zonas span:nth-child(3) { animation-delay: 140ms; }
.entrenamiento-hoy-chips span:nth-child(4), .entrenamiento-hoy-zonas span:nth-child(4) { animation-delay: 210ms; }
.entrenamiento-hoy-chips span:nth-child(n+5), .entrenamiento-hoy-zonas span:nth-child(n+5) { animation-delay: 280ms; }

.entrenamiento-hoy-ejercicio { transition: transform 0.3s var(--gym-spring), box-shadow 0.25s ease, border-color 0.25s ease; }
.entrenamiento-hoy-ejercicio:hover {
    transform: translateX(4px);
    border-color: color-mix(in srgb, var(--color-primario) 30%, var(--color-borde));
    box-shadow: var(--sombra-sm);
}
/* Cada icono repite su propio movimiento al pasar por la fila */
.entrenamiento-hoy-ejercicio:hover .entrenamiento-hoy-ejercicio-icono svg { animation: gym-curl 0.7s ease-in-out; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="sentadilla"] svg { animation: gym-mov-sentadilla 0.9s var(--gym-ease-smooth) infinite; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="bisagra"] svg    { animation: gym-mov-bisagra 0.9s var(--gym-ease-smooth) infinite; transform-origin: 50% 90%; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="empuje"] svg     { animation: gym-mov-empuje 0.8s var(--gym-ease-smooth) infinite; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="traccion"] svg   { animation: gym-mov-traccion 0.8s var(--gym-ease-smooth) infinite; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="core"] svg       { animation: gym-mov-core 1s var(--gym-ease-smooth) infinite; }
.entrenamiento-hoy-ejercicio:hover [data-movimiento="cardio"] svg     { animation: gym-latido 0.8s ease-in-out infinite; }

.perfil-tab { transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.22s var(--gym-spring); }
.perfil-tab:active { transform: scale(0.94); }
.perfil-tab.activa { animation: gym-escala 0.4s var(--gym-spring); }

/* Línea de tiempo de valoración: se traza de arriba abajo y los nodos aparecen */
.pv-linea::before { transform-origin: top; animation: gym-trazar 0.9s 0.15s var(--gym-ease-concentric) backwards; }
.pv-item::before  { animation: gym-pop-suave 0.5s 0.25s var(--gym-spring) backwards; }
.pv-item, .pv-metrica { transition: transform 0.3s var(--gym-spring), box-shadow 0.3s ease; }
@media (hover: hover) {
    .pv-item:hover { transform: translateX(4px); box-shadow: 0 14px 28px -12px var(--gym-resplandor); }
}

/* Asistencias: el check de cada ingreso hace "pop" */
.asistencia-linea { animation: gym-pop-suave 0.5s 0.1s var(--gym-spring) backwards; }

/* --------------------------------------------------------------------------
   11. AVISOS, TIENDA FLOTANTE Y TOASTS
   -------------------------------------------------------------------------- */
.aviso-notificacion.sin-leer { box-shadow: inset 3px 0 0 0 var(--color-primario); }
.punto-no-leida { animation: gym-ping-sombra 2.2s ease-out infinite; }

/* El pulso pasa de box-shadow a un anillo (más fluido y barato de pintar) */
.tienda-flotante { animation: gym-pop-suave 0.6s var(--gym-spring) backwards; }
.tienda-flotante::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--color-primario) 60%, transparent);
    pointer-events: none;
    animation: gym-ping 2.6s cubic-bezier(0, 0, 0.2, 1) 1s infinite;
}
.tienda-flotante svg { transition: transform 0.3s var(--gym-spring); }
.tienda-flotante:hover svg, .tienda-flotante:focus-visible svg { animation: gym-curl 0.75s ease-in-out infinite; }

.toast { transition: transform 0.55s var(--gym-spring), opacity 0.3s ease; }
.toast.mostrar .toast-icono { animation: gym-pop-suave 0.55s 0.15s var(--gym-spring) backwards; }
.toast.error.mostrar { animation: gym-sacudida 0.45s 0.25s ease; }

/* --------------------------------------------------------------------------
   12. MENÚ INFERIOR MÓVIL ("MÁS")
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
    .portal-menu-fondo { animation: gym-fondo 0.25s ease backwards; }
    .portal-menu-hoja { animation: gym-hoja 0.6s var(--gym-spring-soft); }
}

/* --------------------------------------------------------------------------
   13. ACCESIBILIDAD: MOVIMIENTO REDUCIDO
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        animation-timeline: auto !important;
        animation-range: normal !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0s !important;
        scroll-behavior: auto !important;
    }
    /* Lo decorativo e infinito desaparece */
    #pantallaLogin::before, #pantallaLogin::after,
    .login-branding::after, .tienda-flotante::before,
    #puntoBadgeCalificar::after, .widget-asistencia::after,
    #codigoQR:not(:empty)::before { display: none; }
    /* Los indicadores de carga siguen girando, lentos, para señalar actividad */
    .icono-girando, .spin, .resumen-actividad-cargando svg, .lucide-loader-circle,
    .btn-actualizar-entrenamiento:disabled svg {
        animation: gym-giro-disco 2s linear infinite !important;
    }
    .gym-loader { animation: gym-parpadeo 1.4s ease-in-out infinite !important; }
    .gym-skeleton { animation: none !important; }
}
