/*
 * bola-efectos.css — 30 efectos para la bola del hero (inicio_v9.php), uno elegido al azar
 * en servidor en cada carga (ver `$_bfx = random_int(1,30)` en inicio_v9.php). Cada efecto
 * es un bucle infinito autocontenido para que dure mientras la persona esté en la página.
 * Selectores con doble clase (.rotating-ball.ball-fx-N) para ganar siempre a la regla base
 * `.rotating-ball { animation: float ... }` de style.css sin depender del orden de carga.
 */

/* ── Simples (1 propiedad) ───────────────────────────────────────────── */

img.rotating-ball.ball-fx-1 { animation: bfx-spin-slow 12s linear infinite; }
@keyframes bfx-spin-slow { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

img.rotating-ball.ball-fx-2 { animation: bfx-bob-soft 5s ease-in-out infinite; }
@keyframes bfx-bob-soft { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

img.rotating-ball.ball-fx-3 { animation: bfx-pulse-scale 3s ease-in-out infinite; }
@keyframes bfx-pulse-scale { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

img.rotating-ball.ball-fx-4 { animation: bfx-sway 4s ease-in-out infinite; }
@keyframes bfx-sway { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }

img.rotating-ball.ball-fx-5 { animation: bfx-fade-breathe 6s ease-in-out infinite; }
@keyframes bfx-fade-breathe { 0%, 100% { opacity: .88; transform: scale(1); } 50% { opacity: 1; transform: scale(1.04); } }

img.rotating-ball.ball-fx-6 { animation: bfx-tilt-lr 2.6s ease-in-out infinite; }
@keyframes bfx-tilt-lr { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }

img.rotating-ball.ball-fx-7 { animation: bfx-drift-x 7s ease-in-out infinite; }
@keyframes bfx-drift-x { 0%, 100% { transform: translateX(-10px); } 50% { transform: translateX(10px); } }

img.rotating-ball.ball-fx-8 { animation: bfx-drift-y 8s ease-in-out infinite; }
@keyframes bfx-drift-y { 0%, 100% { transform: translateY(-16px); } 50% { transform: translateY(16px); } }

img.rotating-ball.ball-fx-9 { animation: bfx-brighten 4s ease-in-out infinite; }
@keyframes bfx-brighten { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.18); } }

img.rotating-ball.ball-fx-10 { animation: bfx-spin-reverse 14s linear infinite; }
@keyframes bfx-spin-reverse { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }

/* ── Medios (2-3 propiedades combinadas) ─────────────────────────────── */

img.rotating-ball.ball-fx-11 { animation: bfx-orbit-wobble 6s ease-in-out infinite; }
@keyframes bfx-orbit-wobble {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50%       { transform: translateY(-10px) rotate(5deg); }
}

img.rotating-ball.ball-fx-12 { animation: bfx-spin-bounce 8s ease-in-out infinite; }
@keyframes bfx-spin-bounce {
    0%, 100% { transform: rotate(0deg) scale(1); }
    50%       { transform: rotate(180deg) scale(1.1); }
}

img.rotating-ball.ball-fx-13 { animation: bfx-tilt-3d 7s ease-in-out infinite; }
@keyframes bfx-tilt-3d {
    0%, 100% { transform: perspective(600px) rotateY(-14deg); }
    50%       { transform: perspective(600px) rotateY(14deg); }
}

/* 15 (elastic-wobble) retirado el 2026-09-25 a petición del usuario.
   14, 20, 21 y 28 reconstruidos el mismo día (respuesta del formulario de pendientes):
   se mantienen pero con hue-rotate acotado a ±16° para no sacar la bola de la gama de
   marca (verde #87CF32 / azul #0094DC); antes giraban el tono hasta 360° y salía rosa. */

img.rotating-ball.ball-fx-14 { animation: bfx-hue-drift 9s ease-in-out infinite; }
@keyframes bfx-hue-drift {
    0%, 100% { filter: hue-rotate(-14deg) saturate(1); }
    50%       { filter: hue-rotate(14deg) saturate(1.15); }
}

img.rotating-ball.ball-fx-16 { animation: bfx-shadow-pulse 5s ease-in-out infinite; }
@keyframes bfx-shadow-pulse {
    0%, 100% { filter: drop-shadow(0 0 6px rgba(135,207,50,.35)) scale(1); transform: scale(1); }
    50%       { filter: drop-shadow(0 0 22px rgba(0,148,220,.55)) scale(1); transform: scale(1.05); }
}

img.rotating-ball.ball-fx-17 { animation: bfx-skew-flow 6s ease-in-out infinite; }
@keyframes bfx-skew-flow {
    0%, 100% { transform: translateX(-8px) skewX(-4deg); }
    50%       { transform: translateX(8px) skewX(4deg); }
}

img.rotating-ball.ball-fx-18 { animation: bfx-zoom-breathe 7s ease-in-out infinite; }
@keyframes bfx-zoom-breathe {
    0%, 100% { transform: scale(1); filter: brightness(1); }
    50%       { transform: scale(1.12); filter: brightness(1.1); }
}

img.rotating-ball.ball-fx-19 { animation: bfx-flip-peek 6s ease-in-out infinite; }
@keyframes bfx-flip-peek {
    0%, 40%, 100% { transform: perspective(600px) rotateY(0deg) scale(1); }
    20%            { transform: perspective(600px) rotateY(18deg) scale(1.03); }
}

img.rotating-ball.ball-fx-20 { animation: bfx-color-spin 10s linear infinite; }
@keyframes bfx-color-spin {
    0%   { transform: rotate(0deg);   filter: hue-rotate(0deg) saturate(1); }
    25%  { transform: rotate(90deg);  filter: hue-rotate(16deg) saturate(1.2); }
    50%  { transform: rotate(180deg); filter: hue-rotate(0deg) saturate(1); }
    75%  { transform: rotate(270deg); filter: hue-rotate(-16deg) saturate(1.2); }
    100% { transform: rotate(360deg); filter: hue-rotate(0deg) saturate(1); }
}

/* ── Complejos (multi-etapa) ──────────────────────────────────────────── */

/* 21: reconstruido con dos ráfagas por ciclo de 5s (antes una cada ~12s y parecía roto)
   y hue acotado; steps(1) mantiene el corte seco de glitch. */
img.rotating-ball.ball-fx-21 { animation: bfx-glitch 5s steps(1, end) infinite; }
@keyframes bfx-glitch {
    0%, 18%, 28%, 58%, 68%, 100% { transform: translate(0, 0) skewX(0); filter: none; }
    20% { transform: translate(-4px, 2px) skewX(-6deg); filter: hue-rotate(-16deg) brightness(1.2); }
    22% { transform: translate(3px, -2px) skewX(5deg);  filter: hue-rotate(14deg) brightness(.9); }
    24% { transform: translate(-2px, 1px) skewX(-3deg); filter: hue-rotate(-10deg) brightness(1.15); }
    26% { transform: translate(1px, 0) skewX(2deg);     filter: hue-rotate(8deg) brightness(1.05); }
    60% { transform: translate(4px, 1px) skewX(6deg);   filter: hue-rotate(16deg) brightness(1.2); }
    62% { transform: translate(-3px, -1px) skewX(-5deg); filter: hue-rotate(-14deg) brightness(.9); }
    64% { transform: translate(2px, 2px) skewX(3deg);   filter: hue-rotate(10deg) brightness(1.1); }
    66% { transform: translate(-1px, 0) skewX(-2deg);   filter: hue-rotate(-6deg) brightness(1.05); }
}

/* 22: ciclo de 60s a petición del usuario (2026-09-25) — se ensambla UNA VEZ POR
   MINUTO y el resto del ciclo se queda quieto y montado. El ensamblado ocupa el
   3% del ciclo = ~1,8s; los porcentajes son relativos a la duración, así que
   cambiar los 60s cambia también lo que dura el ensamblado. */
img.rotating-ball.ball-fx-22 { animation: bfx-assemble 60s ease-in-out infinite; }
@keyframes bfx-assemble {
    0%        { clip-path: circle(0% at 50% 50%); transform: rotate(-45deg) scale(.7); opacity: 0; }
    3%        { clip-path: circle(75% at 50% 50%); transform: rotate(0deg) scale(1); opacity: 1; }
    4%, 100%  { clip-path: circle(75% at 50% 50%); transform: rotate(0deg) scale(1); opacity: 1; }
}

img.rotating-ball.ball-fx-23 { animation: bfx-orbit-path 9s ease-in-out infinite; }
@keyframes bfx-orbit-path {
    0%   { transform: translate(0, 0); }
    25%  { transform: translate(10px, -12px); }
    50%  { transform: translate(0, -4px); }
    75%  { transform: translate(-10px, -12px); }
    100% { transform: translate(0, 0); }
}

img.rotating-ball.ball-fx-24 { animation: bfx-bounce-in 4.5s cubic-bezier(.68,-0.55,.27,1.55) infinite; }
@keyframes bfx-bounce-in {
    0%, 100% { transform: translateY(0) scale(1); }
    15%       { transform: translateY(-30px) scale(1.02); }
    30%       { transform: translateY(0) scale(.96); }
    45%       { transform: translateY(-10px) scale(1.01); }
    60%       { transform: translateY(0) scale(1); }
}

img.rotating-ball.ball-fx-25 { animation: bfx-bounce-rotate 6s cubic-bezier(.68,-0.55,.27,1.55) infinite; }
@keyframes bfx-bounce-rotate {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    20%       { transform: translateY(-22px) rotate(15deg); }
    40%       { transform: translateY(0) rotate(0deg); }
}

img.rotating-ball.ball-fx-26 { animation: bfx-multi-bounce 5s cubic-bezier(.5,0,.5,1) infinite; }
@keyframes bfx-multi-bounce {
    0%, 100% { transform: translateY(0); }
    10%       { transform: translateY(-24px); }
    22%       { transform: translateY(0); }
    32%       { transform: translateY(-12px); }
    42%       { transform: translateY(0); }
    50%       { transform: translateY(-5px); }
    58%       { transform: translateY(0); }
}

img.rotating-ball.ball-fx-27 { animation: bfx-flip-full 10s ease-in-out infinite; }
@keyframes bfx-flip-full {
    0%   { transform: perspective(700px) rotateY(0deg); filter: brightness(1); }
    50%  { transform: perspective(700px) rotateY(180deg); filter: brightness(.75); }
    100% { transform: perspective(700px) rotateY(360deg); filter: brightness(1); }
}

img.rotating-ball.ball-fx-28 { animation: bfx-aurora 11s ease-in-out infinite; }
@keyframes bfx-aurora {
    0%, 100% { transform: translateY(0);    filter: hue-rotate(-12deg) brightness(1)    drop-shadow(0 0 10px rgba(135, 207, 50, .45)); }
    33%       { transform: translateY(-6px); filter: hue-rotate(6deg)   brightness(1.08) drop-shadow(0 0 18px rgba(0, 148, 220, .5)); }
    66%       { transform: translateY(3px);  filter: hue-rotate(12deg)  brightness(1.04) drop-shadow(0 0 14px rgba(64, 180, 130, .5)); }
}

/* 29: ciclo acortado 6s→3,5s y sacudida más larga (2026-09-25, respuesta del formulario:
   «que se muevan más a menudo» — antes pasaba el 70% del ciclo quieto y parecía roto). */
img.rotating-ball.ball-fx-29 { animation: bfx-shake-settle 3.5s ease-in-out infinite; }
@keyframes bfx-shake-settle {
    0%, 50%, 80%, 100% { transform: translateX(0) rotate(0deg); }
    54%  { transform: translateX(-6px) rotate(-4deg); }
    58%  { transform: translateX(6px) rotate(4deg); }
    62%  { transform: translateX(-5px) rotate(-3deg); }
    66%  { transform: translateX(5px) rotate(3deg); }
    70%  { transform: translateX(-3px) rotate(-1.5deg); }
    74%  { transform: translateX(2px) rotate(1deg); }
}

/* 30: hue acotado a ±16° el 2026-09-25 (antes 120-240° y el destello salía rosa/violeta);
   el estallido se mantiene con brillo y halo, que no tocan el tono. */
img.rotating-ball.ball-fx-30 { animation: bfx-supernova 8s ease-in-out infinite; }
@keyframes bfx-supernova {
    0%, 100% { transform: scale(1) rotate(0deg); filter: brightness(1) hue-rotate(0deg) drop-shadow(0 0 4px rgba(135,207,50,.3)); }
    45%       { transform: scale(1) rotate(160deg); filter: brightness(1) hue-rotate(-12deg) drop-shadow(0 0 4px rgba(135,207,50,.3)); }
    50%       { transform: scale(1.35) rotate(180deg); filter: brightness(1.6) hue-rotate(16deg) drop-shadow(0 0 30px rgba(0,148,220,.8)); }
    55%       { transform: scale(1) rotate(200deg); filter: brightness(1) hue-rotate(-8deg) drop-shadow(0 0 4px rgba(135,207,50,.3)); }
}

/* Quien pide menos movimiento NO recibe desplazamientos ni giros: el efecto sorteado se
   sustituye por una respiración de opacidad (la sustitución de movimiento por fundidos es
   la práctica recomendada; antes se congelaba del todo y parecía rota — 2026-09-25).
   Excepción: .bfx-force (solo la pone ?bfx=N, una petición explícita de VER el efecto). */
@media (prefers-reduced-motion: reduce) {
    body.v9 .rotating-ball[class*="ball-fx-"]:not(.bfx-force) {
        animation: bfx-reduced-breathe 6s ease-in-out infinite !important;
    }
    @keyframes bfx-reduced-breathe {
        0%, 100% { opacity: 1;   filter: drop-shadow(0 0 4px rgba(135, 207, 50, .25)); }
        50%       { opacity: .55; filter: drop-shadow(0 0 18px rgba(0, 148, 220, .45)); }
    }
}
