/* QuackBot · motion
   Tudo pendura em html.is-live (setado no <head>). Sem JS, com ?static=1 ou com reduzir movimento,
   a página nasce no estado final. Valores: tokens.css (← review-animations/STANDARDS.md). */

/* ── Revelação fade-up com stagger por índice (--d no HTML, zera por linha) ── */
.rv { --d: 0; }
.is-live .rv {
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  transition-delay: calc(var(--d) * var(--stagger));
}
.is-live .rv:not([data-visible]) { opacity: 0; transform: translateY(16px); }

/* Revelação de bloco grande por clip-path (imagem, janela) */
.is-live .rv-clip { transition: clip-path 900ms var(--ease-in-out); }
.is-live .rv-clip:not([data-visible]) { clip-path: inset(0 0 100% 0 round var(--r-lg)); }
.is-live .rv-clip[data-visible] { clip-path: inset(0 0 0 0 round var(--r-lg)); }

/* ── Entrada do hero no load ── */
@media (prefers-reduced-motion: no-preference) {
  .is-live .hero-in > * { animation: rise var(--dur-hero) var(--ease-out) both; }
  .is-live .hero-in > :nth-child(2) { animation-delay: calc(var(--stagger-hero) * 1); }
  .is-live .hero-in > :nth-child(3) { animation-delay: calc(var(--stagger-hero) * 2); }
  .is-live .hero-in > :nth-child(4) { animation-delay: calc(var(--stagger-hero) * 3); }
  .is-live .hero-in > :nth-child(5) { animation-delay: calc(var(--stagger-hero) * 4); }
}
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }

/* ── Assinatura: o pato no logo ──
   .qb-upper / .qb-lower giram no pivô da barra (o "quack"); .qb-eye pisca.
   JS dispara (load, hover no logo, clique no mascote). Aqui só a geometria do pivô. */
.qb-upper, .qb-lower, .qb-eye, .qb-pupil, .qb-bar { transform-box: view-box; }
.qb-upper { transform-origin: 96px 65px; }   /* pivô na borda da barra, coordenadas do icon.svg */
.qb-lower { transform-origin: 96px 191px; }
.qb-eye { transform-origin: 148px 99px; }
.qb-bar { transform-origin: 59px 242px; }

/* Montagem do mascote grande (primeira visita do hero) */
@media (prefers-reduced-motion: no-preference) {
  .is-live .mascot[data-assemble] .qb-bar { animation: bar-rise 640ms var(--ease-out) both; }
  .is-live .mascot[data-assemble] .qb-lower { animation: jaw-in-low 720ms var(--ease-out) 180ms both; }
  .is-live .mascot[data-assemble] .qb-upper { animation: jaw-in-up 720ms var(--ease-out) 260ms both; }
}
@keyframes bar-rise { from { opacity: 0; transform: translateY(48px) scaleY(0.92); } }
@keyframes jaw-in-up { from { opacity: 0; transform: rotate(-28deg); } }
@keyframes jaw-in-low { from { opacity: 0; transform: rotate(28deg); } }

/* ── Halo do hero: brilho verde estático que respira uma vez e para ── */
.halo {
  position: absolute; inset: auto; width: min(900px, 120vw); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgb(69 255 0 / 0.22), rgb(69 255 0 / 0.06) 55%, transparent 72%);
  pointer-events: none; filter: blur(8px);
}
@media (prefers-reduced-motion: no-preference) {
  .is-live .halo { animation: breathe 2.4s ease-in-out 2 alternate; /* 4,8 s: abaixo do limite de 5 s sem pausa */ }
}
@keyframes breathe { from { opacity: 0.7; transform: scale(0.96); } to { opacity: 1; transform: scale(1.02); } }

/* ── Sequência declarativa (data-a="tipo atraso duração"): estado final no CSS, o JS só toca o caminho ── */
[data-a] { will-change: auto; }

/* ── Passos com fio que se desenha pelo scroll ── */
.flow { position: relative; display: grid; gap: var(--sp-10); padding-left: 44px; }
.flow__rail { position: absolute; left: 13px; top: 8px; bottom: 8px; width: 2px; background: var(--line-2); border-radius: 2px; overflow: clip; }
.flow__fill { position: absolute; inset: 0; background: var(--accent); transform-origin: top center; transform: scaleY(1); }
.flow__step { position: relative; display: grid; gap: 6px; }
.flow__step::before {
  content: ""; position: absolute; left: -38px; top: 4px; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--accent); background: var(--bg);
  transition: background-color var(--dur-hover) ease;
}
.flow__step[data-on]::before, html:not(.is-live) .flow__step::before { background: var(--accent); }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    html.is-live:not(.no-sda) .flow { view-timeline: --flow block; }
    html.is-live:not(.no-sda) .flow__fill {
      animation: flow-fill linear both;
      animation-timeline: --flow;
      animation-range: cover 10% cover 70%;
    }
  }
}
/* Fallback sem scroll-driven: o JS escreve transform no .flow__fill */
html.is-live.no-sda .flow__fill { transform: scaleY(0); }
@keyframes flow-fill { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* ── Troca de painel (abas com visual) ── */
.panels { display: grid; }
.panel { grid-area: 1 / 1; opacity: 0; pointer-events: none; visibility: hidden; transition: opacity 0s linear var(--dur-panel), visibility 0s linear var(--dur-panel); }
.panel[data-active] { z-index: 2; opacity: 1; pointer-events: auto; visibility: visible; transition: opacity var(--dur-panel) var(--ease-out), visibility 0s; }

/* ── Botão de pausa para movimento contínuo ── */
.motion-toggle[aria-pressed="true"] .motion-toggle__pause, .motion-toggle[aria-pressed="false"] .motion-toggle__play { display: none; }

/* ── Reduzir movimento: menos e mais suave, não zero ── */
@media (prefers-reduced-motion: reduce) {
  .is-live .rv { transition: opacity 200ms ease; transition-delay: 0ms; }
  .is-live .rv:not([data-visible]) { transform: none; }
  .is-live .rv-clip { transition: none; clip-path: none; }
  .btn:active, .ask__opt:active, .card--link:active { transform: none; }
}
