/* ============================================================================
   DUET · Loader animado (SVG vetorial)
   Dois blobs iridescentes orbitando um ao outro numa órbita elíptica,
   deformados como gotas na direção do movimento. Ao parar (.is-idle no SVG),
   eles se acomodam no centro em duas bolas redondas — a marca em repouso.

   USO:
     <span data-duet-loader style="--duet-loader-size:96px"></span>
     <script src="duet-loader.js"></script>   (clona o <template> nos slots)
   Parar/retomar: DuetLoader.stop(el) / .start(el) / .toggle(el),
   ou alterne a classe .is-idle no <svg class="duet-loader">.
   Tamanho via --duet-loader-size (padrão 96px).
   ============================================================================ */

.duet-loader {
  width: var(--duet-loader-size, 96px);
  height: var(--duet-loader-size, 96px);
  overflow: visible;
}

/* --- ÓRBITA: o grupo inteiro gira; a elipse vem da deformação abaixo --- */
.duet-loader-orbit {
  transform-box: view-box;      /* coordenadas = viewBox (0..120) */
  transform-origin: 60px 60px;  /* centro do viewBox */
  animation: duet-orbit-rotate var(--duet-orbit-duration, 2.4s) linear infinite;
}

/* A órbita elíptica: além de girar, o grupo "respira" no eixo X/Y em fase com
   a rotação, fazendo o caminho circular virar oval. */
@keyframes duet-orbit-rotate {
  0%   { transform: rotate(0deg)    scaleX(1)    scaleY(1); }
  25%  { transform: rotate(-90deg)  scaleX(0.82) scaleY(1.12); }
  50%  { transform: rotate(-180deg) scaleX(1)    scaleY(1); }
  75%  { transform: rotate(-270deg) scaleX(0.82) scaleY(1.12); }
  100% { transform: rotate(-360deg) scaleX(1)    scaleY(1); }
}

/* --- BLOBS: cada gota pulsa levemente (matéria sendo puxada) --- */
.duet-loader-blob {
  transform-box: fill-box;
  transform-origin: center;
}
.duet-loader-blob--a {
  animation: duet-blob-breathe var(--duet-orbit-duration, 2.4s) ease-in-out infinite;
}
.duet-loader-blob--b {
  animation: duet-blob-breathe var(--duet-orbit-duration, 2.4s) ease-in-out infinite;
  animation-delay: calc(var(--duet-orbit-duration, 2.4s) / -2);
}

@keyframes duet-blob-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}

/* A "gota": em movimento é alongada (cauda de cometa) e afina; a deformação já
   está no ry<rx do SVG, aqui só damos um leve estica-encolhe rítmico. */
.duet-loader-drop {
  transform-box: fill-box;
  transform-origin: center;
  animation: duet-drop-stretch var(--duet-orbit-duration, 2.4s) ease-in-out infinite;
}
@keyframes duet-drop-stretch {
  0%, 100% { transform: scale(1, 1); }
  50%      { transform: scale(1.12, 0.9); }
}

/* ============================================================================
   ESTADO PARADO · .is-idle
   Órbita desacelera e para; os blobs deslizam ao centro e viram bolas redondas.
   ============================================================================ */
.duet-loader.is-idle .duet-loader-orbit {
  animation: none;
  transform: rotate(0deg);
}

.duet-loader.is-idle .duet-loader-blob {
  animation: none;
  transition: transform var(--duet-dur-slow, 480ms) var(--duet-ease, cubic-bezier(0.22,1,0.36,1));
}
/* Aproxima os dois blobs do centro e os curva um para o outro (yin-yang):
   A desce e gira levemente, B sobe e gira ao contrário — encaixam como a marca. */
.duet-loader.is-idle .duet-loader-blob--a {
  transform: translateY(18px) rotate(-12deg);
}
.duet-loader.is-idle .duet-loader-blob--b {
  transform: translateY(-18px) rotate(-12deg);
}

/* Relaxa a gota em bola perfeita (rx==ry) */
.duet-loader.is-idle .duet-loader-drop {
  animation: none;
  transition: transform var(--duet-dur-slow, 480ms) var(--duet-ease, cubic-bezier(0.22,1,0.36,1));
  transform: scale(1, 1.31); /* compensa ry(13)->rx(17): 17/13 ≈ 1.31 => vira circulo */
}

/* ============================================================================
   ACESSIBILIDADE
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  .duet-loader-orbit,
  .duet-loader-blob,
  .duet-loader-drop { animation: none !important; }
}

/* ============================================================================
   OVERLAY DE CARREGAMENTO (tela cheia)
   Cobre a tela com um véu escuro borrado e centraliza o loader + rótulo.
   Mostre com display: grid (ou remova o display:none inline).
   ============================================================================ */
.duet-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;   /* orb + label agrupados no centro */
  gap: var(--duet-space-5, 24px);
  background: rgba(5, 6, 10, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: duet-overlay-in var(--duet-dur, 260ms) var(--duet-ease, ease);
}
.duet-loading-label {
  font-family: var(--duet-font-heading, serif);
  font-size: var(--duet-fs-h3, 1.35rem);
  color: var(--duet-text-muted, #a6adcb);
  letter-spacing: 0.02em;
}
@keyframes duet-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
