/* ============================================================
   StuStudios loading animations — 12 reusable loaders.
   Adapted from the "Loading Animations" design set. Pure CSS,
   no deps. Themeable per-container:
     --stul-accent : the moving color   (default: hub blue)
     --stul-track  : the muted track    (default: soft grey)
   Pair with loaders.js: StuLoader.html('orbit') / .make('bounce').
   Sizes are inline-scale — drop one in a button or a panel.
   ============================================================ */
:root {
  --stul-accent: #4a8fe8;
  --stul-track: rgba(80, 90, 130, 0.22);
}

@keyframes stul-spin { to { transform: rotate(360deg); } }
@keyframes stul-orbit-dash { 0% { stroke-dashoffset: 140; } 50% { stroke-dashoffset: 35; } 100% { stroke-dashoffset: 140; } }
@keyframes stul-dot-bounce { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-14px); } }
@keyframes stul-bar-pulse { 0%, 100% { transform: scaleY(0.35); opacity: 0.5; } 50% { transform: scaleY(1); opacity: 1; } }
@keyframes stul-ring-pop { 0% { transform: scale(0.55); opacity: 0.9; } 80%, 100% { transform: scale(1.25); opacity: 0; } }
@keyframes stul-track-slide { 0% { left: -35%; } 100% { left: 105%; } }
@keyframes stul-square-flip { 0% { transform: perspective(120px) rotateX(0) rotateY(0); } 25% { transform: perspective(120px) rotateX(-180deg) rotateY(0); } 50% { transform: perspective(120px) rotateX(-180deg) rotateY(-180deg); } 75% { transform: perspective(120px) rotateX(0) rotateY(-180deg); } 100% { transform: perspective(120px) rotateX(0) rotateY(-360deg); } }
@keyframes stul-dot-orbit { to { transform: rotate(360deg); } }
@keyframes stul-pulse-scale { 0%, 100% { transform: scale(0.5); opacity: 0.4; } 50% { transform: scale(1); opacity: 1; } }
@keyframes stul-seg-fade { 0%, 100% { opacity: 0.15; } 40% { opacity: 1; } }
@keyframes stul-swing { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(52px); } }
@keyframes stul-morph { 0%, 100% { border-radius: 50%; transform: rotate(0); } 50% { border-radius: 20%; transform: rotate(180deg); } }
@keyframes stul-grid-fade { 0%, 100% { opacity: 0.2; transform: scale(0.7); } 50% { opacity: 1; transform: scale(1); } }

.stul { display: inline-flex; align-items: center; justify-content: center; line-height: 0; }

/* 1A Orbit — arc spinner */
.stul-orbit { width: 56px; height: 56px; animation: stul-spin 1.4s linear infinite; }
.stul-orbit .track { fill: none; stroke: var(--stul-track); stroke-width: 5; }
.stul-orbit .arc { fill: none; stroke: var(--stul-accent); stroke-width: 5; stroke-linecap: round; stroke-dasharray: 140; animation: stul-orbit-dash 1.6s ease-in-out infinite; }

/* 1B Bounce — three dots */
.stul-bounce { display: inline-flex; gap: 10px; align-items: flex-end; height: 34px; }
.stul-bounce i { width: 12px; height: 12px; border-radius: 50%; background: var(--stul-accent); animation: stul-dot-bounce 1.1s ease-in-out infinite; }
.stul-bounce i:nth-child(2) { animation-delay: 0.14s; }
.stul-bounce i:nth-child(3) { animation-delay: 0.28s; }

/* 1C Equalizer — pulsing bars */
.stul-bars { display: inline-flex; gap: 6px; align-items: center; height: 44px; }
.stul-bars i { width: 7px; height: 40px; border-radius: 4px; background: var(--stul-accent); transform-origin: center; animation: stul-bar-pulse 1s ease-in-out infinite; }
.stul-bars i:nth-child(2) { animation-delay: 0.12s; }
.stul-bars i:nth-child(3) { animation-delay: 0.24s; }
.stul-bars i:nth-child(4) { animation-delay: 0.36s; }
.stul-bars i:nth-child(5) { animation-delay: 0.48s; }

/* 1D Ripple — expanding rings */
.stul-ripple { position: relative; width: 64px; height: 64px; }
.stul-ripple i { position: absolute; inset: 0; border-radius: 50%; border: 3px solid var(--stul-accent); animation: stul-ring-pop 1.8s cubic-bezier(0.2, 0.6, 0.35, 1) infinite; }
.stul-ripple i:nth-child(2) { animation-delay: 0.9s; }
.stul-ripple b { position: absolute; inset: 24px; border-radius: 50%; background: var(--stul-accent); }

/* 1E Sweep — indeterminate bar */
.stul-sweep { width: 180px; height: 6px; border-radius: 3px; background: var(--stul-track); position: relative; overflow: hidden; }
.stul-sweep i { position: absolute; top: 0; bottom: 0; width: 35%; border-radius: 3px; background: var(--stul-accent); animation: stul-track-slide 1.3s cubic-bezier(0.45, 0, 0.4, 1) infinite; }

/* 1F Flip — folding square */
.stul-flip { width: 40px; height: 40px; border-radius: 6px; background: var(--stul-accent); animation: stul-square-flip 2.4s ease-in-out infinite; }

/* 2A Satellite — dot orbiting a ring */
.stul-satellite { position: relative; width: 56px; height: 56px; animation: stul-dot-orbit 1.2s linear infinite; }
.stul-satellite i { position: absolute; inset: 0; border-radius: 50%; border: 3px solid var(--stul-track); }
.stul-satellite b { position: absolute; top: -5px; left: 50%; margin-left: -6px; width: 12px; height: 12px; border-radius: 50%; background: var(--stul-accent); }

/* 2B Pulse grid — 3x3 breathing dots */
.stul-grid { display: grid; grid-template-columns: repeat(3, 12px); gap: 8px; }
.stul-grid i { width: 12px; height: 12px; border-radius: 3px; background: var(--stul-accent); animation: stul-grid-fade 1.4s ease-in-out infinite; }
.stul-grid i:nth-child(1) { animation-delay: 0s; }
.stul-grid i:nth-child(2), .stul-grid i:nth-child(4) { animation-delay: 0.15s; }
.stul-grid i:nth-child(3), .stul-grid i:nth-child(5), .stul-grid i:nth-child(7) { animation-delay: 0.3s; }
.stul-grid i:nth-child(6), .stul-grid i:nth-child(8) { animation-delay: 0.45s; }
.stul-grid i:nth-child(9) { animation-delay: 0.6s; }

/* 2C Segments — clock-style fading spokes */
.stul-seg { position: relative; width: 56px; height: 56px; }
.stul-seg i { position: absolute; top: 4px; left: 50%; margin-left: -2.5px; width: 5px; height: 16px; border-radius: 3px; background: var(--stul-accent); transform-origin: 2.5px 24px; animation: stul-seg-fade 1s linear infinite; }
.stul-seg i:nth-child(1) { transform: rotate(0deg); animation-delay: 0s; }
.stul-seg i:nth-child(2) { transform: rotate(45deg); animation-delay: 0.125s; }
.stul-seg i:nth-child(3) { transform: rotate(90deg); animation-delay: 0.25s; }
.stul-seg i:nth-child(4) { transform: rotate(135deg); animation-delay: 0.375s; }
.stul-seg i:nth-child(5) { transform: rotate(180deg); animation-delay: 0.5s; }
.stul-seg i:nth-child(6) { transform: rotate(225deg); animation-delay: 0.625s; }
.stul-seg i:nth-child(7) { transform: rotate(270deg); animation-delay: 0.75s; }
.stul-seg i:nth-child(8) { transform: rotate(315deg); animation-delay: 0.875s; }

/* 2D Pendulum — dot swinging across */
.stul-pendulum { display: inline-flex; gap: 8px; align-items: center; height: 20px; }
.stul-pendulum i { width: 12px; height: 12px; border-radius: 50%; background: var(--stul-track); }
.stul-pendulum b { width: 12px; height: 12px; border-radius: 50%; background: var(--stul-accent); animation: stul-swing 1.4s cubic-bezier(0.4, 0, 0.6, 1) infinite; }

/* 2E Pulse — scaling disc with echo */
.stul-pulse { position: relative; width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center; }
.stul-pulse i { position: absolute; width: 48px; height: 48px; border-radius: 50%; background: var(--stul-accent); animation: stul-pulse-scale 1.5s ease-in-out infinite; }
.stul-pulse b { width: 18px; height: 18px; border-radius: 50%; background: var(--stul-accent); }

/* 2F Morph — blob squishing and rotating */
.stul-morph { width: 44px; height: 44px; background: var(--stul-accent); animation: stul-morph 2s ease-in-out infinite; }
