/*
  motion.css
  Camada de movimento de entrada. Curta, composta pela GPU e opcional.

  Regras que valem para tudo neste arquivo:

  - só transform e opacity são animados. Nada de width, height, top, left,
    filter ou blur, que forçam layout ou pintura a cada quadro;
  - nenhuma animação em laço. Tudo roda uma vez e para;
  - nenhum estado escondido mora aqui sem a classe is-armed, aplicada por
    reveal.js. Sem JavaScript, nada deste arquivo esconde conteúdo;
  - transform não afeta o fluxo, então nada aqui produz layout shift.

  Duas famílias:

  1. Entrada do hero, por animation. Dispara quando campaign-home.js termina de
     preencher o hero e adiciona .is-ready. Não pode ser por load: o conteúdo
     do hero chega por JavaScript e a animação rodaria em elementos vazios.

  2. Entrada por scroll, por transition. Dispara quando reveal.js adiciona
     .is-revealed. Ver o cabeçalho daquele arquivo.
*/

/*
  Vocabulário de movimento da página inteira. Quatro padrões, e só quatro:

  1. ABERTURA (hero)      cada peça entra na direção da sua própria geometria;
  2. REVEAL EDITORIAL     sobe e assenta, para todo conteúdo de leitura;
  3. PERCURSO (faixa)     uma linha se desenha e as etapas chegam com ela;
  4. MICROINTERAÇÃO       respostas de 1 a 3px, nunca mais do que isso.

  Qualquer animação nova deve caber em um destes quatro. Se não couber,
  provavelmente não pertence a esta página.
*/
:root {
  --adjuto-motion-duration: 560ms;
  --adjuto-motion-duration-hero: 620ms;
  --adjuto-motion-micro: 180ms;
  /* Desaceleração longa no fim: o elemento chega e assenta, em vez de parar
     de repente. */
  --adjuto-motion-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --adjuto-motion-rise: 18px;
  /* Deslocamento da foto do hero: segue a inclinação do corte diagonal. */
  --adjuto-motion-glide-x: 3.5rem;
  --adjuto-motion-glide-y: 2rem;
}

/* No celular tudo se move menos e um pouco mais rápido: as distâncias da
   tela são menores e movimentos largos parecem overflow. */
@media (max-width: 759px) {
  :root {
    --adjuto-motion-duration: 460ms;
    --adjuto-motion-duration-hero: 520ms;
    --adjuto-motion-rise: 12px;
    --adjuto-motion-glide-x: 1.25rem;
    --adjuto-motion-glide-y: 0.75rem;
  }
}

/* ===================================================================
   1. ENTRADA DO HERO
   =================================================================== */

/*
  A abertura é uma coreografia de direções, não uma fila de fades: cada peça
  entra na direção que a sua própria geometria sugere.

  - a coluna de texto sobe (é coluna, empilha de baixo);
  - a FOTO desliza ao longo da diagonal do corte verde, vinda de baixo e da
    direita, como se subisse a rampa que a recebe;
  - o GRAFISMO 22111 desliza da direita, prolongando o fundo de onde ele
    nasce, lento e sem pressa, porque é cenário;
  - o eyebrow abre em varredura a partir da sua barra verde;
  - a placa eleitoral entra como peça independente e, por último, o bloco
    verde do número CARIMBA a placa numa varredura curta.

  Os primeiros ~600ms contam a hierarquia: mensagem, contexto, prova, número.
  Depois disso, repouso total.
*/
@media (prefers-reduced-motion: no-preference) {
  @keyframes adjuto-hero-rise {
    from {
      opacity: 0;
      transform: translate3d(0, 20px, 0);
    }
    to {
      opacity: 1;
      transform: translate3d(0, 0, 0);
    }
  }

  /* Só deslocamento, sem opacidade. Ver a nota no título, abaixo. */
  @keyframes adjuto-hero-slide {
    from {
      transform: translate3d(0, 20px, 0);
    }
    to {
      transform: translate3d(0, 0, 0);
    }
  }

  /* Varredura a partir da borda esquerda. O clip-path anima pintura, não
     layout, e só é usado em dois elementos pequenos, uma vez cada. */
  @keyframes adjuto-hero-wipe {
    from {
      clip-path: inset(0 100% 0 0);
      transform: translate3d(-10px, 0, 0);
    }
    to {
      clip-path: inset(0 0 0 0);
      transform: translate3d(0, 0, 0);
    }
  }

  /* A varredura do número não desloca: o bloco verde chega sobre a placa
     branca como um carimbo, da esquerda para a direita. */
  @keyframes adjuto-hero-stamp {
    from {
      clip-path: inset(0 100% 0 0);
    }
    to {
      clip-path: inset(0 0 0 0);
    }
  }

  /* Foto ao longo da diagonal. Sem opacidade: é candidata a LCP. */
  @keyframes adjuto-hero-glide {
    from {
      transform: translate3d(var(--adjuto-motion-glide-x), var(--adjuto-motion-glide-y), 0);
    }
    to {
      transform: translate3d(0, 0, 0);
    }
  }

  /*
    REGRA DE OURO DO GRAFISMO 22111: a animação NUNCA toca no __bignum.

    O número decorativo depende de um transform ESTRUTURAL para existir
    (scale(0.46, 1.44) em campaign.css — a compressão e o alongamento que
    foram aprovados em várias rodadas). Uma animação com fill "both" nesse
    elemento substitui o transform inteiro pelo quadro final e destrói a
    geometria de forma permanente — foi exatamente a regressão desta rodada.

    Por isso a entrada anima o WRAPPER (__bg, o contêiner absoluto que só
    existe para segurar o grafismo): o pai desliza e esmaece, o filho carrega
    a geometria, e os dois transforms nunca disputam o mesmo elemento.
  */
  @keyframes adjuto-hero-graphic {
    from {
      opacity: 0;
      transform: translate3d(2.5%, 0, 0);
    }
    to {
      opacity: 1;
      transform: translate3d(0, 0, 0);
    }
  }

  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__text,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__actions,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__ballot {
    animation: adjuto-hero-rise var(--adjuto-motion-duration-hero) var(--adjuto-motion-ease) both;
  }

  /*
    O título é o candidato a LCP junto com a foto, e é a informação mais
    importante da página. Por isso ele nunca parte de opacidade zero: entra só
    deslizando, já legível no primeiro quadro.

    Duas consequências práticas. O LCP não espera a animação terminar. E se a
    animação não rodar por qualquer motivo, o pior caso é o título aparecer
    20px fora do lugar, e não sumir.

    Atraso zero pelo mesmo motivo: qualquer espera aqui empurraria a métrica.
  */
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__title {
    animation: adjuto-hero-slide var(--adjuto-motion-duration-hero) var(--adjuto-motion-ease) both;
    animation-delay: 0ms;
  }

  /* O eyebrow abre a partir da própria barra verde da esquerda. */
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__eyebrow {
    animation: adjuto-hero-wipe 480ms var(--adjuto-motion-ease) both;
    animation-delay: 90ms;
  }

  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__text {
    animation-delay: 150ms;
  }
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__actions {
    animation-delay: 220ms;
  }
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__ballot {
    animation-delay: 300ms;
  }

  /* O carimbo espera a placa assentar. É o último acento da abertura. */
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__ballot-number {
    animation: adjuto-hero-stamp 420ms var(--adjuto-motion-ease) both;
    animation-delay: 640ms;
  }

  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__image {
    animation: adjuto-hero-glide 850ms var(--adjuto-motion-ease) both;
    animation-delay: 60ms;
  }

  /* O grafismo é decorativo e aria-hidden. O wrapper entra devagar, para o
     número assentar no fundo sem disputar atenção com o título. O __bignum,
     filho, fica fora de qualquer animação — ver a regra de ouro acima. */
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__bg {
    animation: adjuto-hero-graphic 1300ms var(--adjuto-motion-ease) both;
    animation-delay: 200ms;
  }
}

/* ===================================================================
   2. ENTRADA POR SCROLL
   =================================================================== */

/*
  is-armed é aplicada por reveal.js e é a única coisa que esconde. Se o
  JavaScript não rodar, esta classe nunca aparece e todo o conteúdo abaixo
  permanece visível no estado final.
*/
[data-reveal].is-armed {
  opacity: 0;
  transform: translate3d(0, var(--adjuto-motion-rise), 0);
}

[data-reveal].is-armed.is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition:
    opacity var(--adjuto-motion-duration) var(--adjuto-motion-ease),
    transform var(--adjuto-motion-duration) var(--adjuto-motion-ease);
}

/*
  Grupos: o container é observado, os filhos entram em cascata curta. Um único
  elemento observado em vez de um por cartão.

  O container do grupo não anima sozinho; quem anima são os filhos. Sem isso, o
  bloco inteiro subiria e os filhos subiriam de novo dentro dele.
*/
[data-reveal="group"].is-armed {
  opacity: 1;
  transform: none;
}

[data-reveal="group"].is-armed > * {
  opacity: 0;
  transform: translate3d(0, var(--adjuto-motion-rise), 0);
}

[data-reveal="group"].is-armed.is-revealed > * {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition:
    opacity var(--adjuto-motion-duration) var(--adjuto-motion-ease),
    transform var(--adjuto-motion-duration) var(--adjuto-motion-ease);
}

/* Cascata curta. Passar de quatro passos deixa o último item chegando tarde
   demais depois que o olho já parou no bloco. */
[data-reveal="group"].is-armed.is-revealed > :nth-child(1) { transition-delay: 0ms; }
[data-reveal="group"].is-armed.is-revealed > :nth-child(2) { transition-delay: 90ms; }
[data-reveal="group"].is-armed.is-revealed > :nth-child(3) { transition-delay: 180ms; }
[data-reveal="group"].is-armed.is-revealed > :nth-child(4) { transition-delay: 270ms; }
[data-reveal="group"].is-armed.is-revealed > :nth-child(n + 5) { transition-delay: 270ms; }

/* ===================================================================
   4. MICROINTERAÇÕES
   =================================================================== */

/*
  Respostas pequenas e imediatas: 1 a 3px, ~180ms, transform e cor. Todas
  presas a (hover: hover) para nunca dependerem de hover no toque, e a
  no-preference porque são movimento como qualquer outro.

  A base do site já dá aos botões e cards um leve lift genérico; o que este
  bloco acrescenta são as respostas com identidade: o menu sublinha em verde,
  o numeral dos cards de Atuação dá um passo, o botão do Instagram inverte.
*/
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  /* Menu: o sublinhado verde se desenha a partir da esquerda, o mesmo gesto
     da linha do percurso na faixa. */
  :root[data-site-mode="officialCampaign"] .adjuto-nav__link {
    position: relative;
  }

  :root[data-site-mode="officialCampaign"] .adjuto-nav__link::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0.1rem;
    height: 2px;
    background: var(--adjuto-campaign-accent);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--adjuto-motion-micro) var(--adjuto-motion-ease);
  }

  /* Só no hover: o foco de teclado já tem a própria borda verde de 3px
     (campaign.css), e as duas linhas juntas dobrariam o sublinhado. */
  :root[data-site-mode="officialCampaign"] .adjuto-nav__link:hover::after {
    transform: scaleX(1);
  }

  /* Pressionar devolve o botão ao chão: o clique tem peso. */
  :root[data-site-mode="officialCampaign"] .adjuto-btn:active {
    transform: translateY(0);
    transition-duration: 80ms;
  }

  /* Atuação: o numeral verde dá um passo para a direita junto com o card. */
  :root[data-site-mode="officialCampaign"] #atuacao .adjuto-card::before {
    transition: transform var(--adjuto-motion-micro) var(--adjuto-motion-ease);
  }

  :root[data-site-mode="officialCampaign"] #atuacao .adjuto-card:hover::before {
    transform: translateX(3px);
  }

  /* Instagram: inverte no hover, como já faz no foco de teclado. */
  :root[data-site-mode="officialCampaign"] .adjuto-btn--instagram:hover {
    background: transparent;
    color: #ffffff;
  }

  :root[data-site-mode="officialCampaign"] .adjuto-sticky-cta:hover {
    transform: translateY(-2px);
    transition: transform var(--adjuto-motion-micro) var(--adjuto-motion-ease);
  }
}

/* ===================================================================
   5. MENOS MOVIMENTO
   =================================================================== */

/*
  Rede de segurança em CSS. reveal.js já não arma nada quando o visitante pede
  menos movimento, mas a preferência pode mudar depois do carregamento, e o
  hero é animado só por CSS. Aqui tudo cai para o estado final na hora.
*/
@media (prefers-reduced-motion: reduce) {
  [data-reveal].is-armed,
  [data-reveal].is-armed > *,
  [data-reveal="group"].is-armed > * {
    opacity: 1;
    transform: none;
    transition: none;
    animation: none;
    transition-delay: 0ms;
    animation-delay: 0ms;
  }

  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__eyebrow,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__text,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__actions,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__ballot,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__ballot-number,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__image {
    animation: none;
    opacity: 1;
    transform: none;
    clip-path: none;
  }

  /* O título tem transform próprio? Não — mas o GRAFISMO tem. Aqui só se
     desliga a animação: zerar transform destruiria o scale(0.46, 1.44)
     estrutural. O wrapper pode zerar tudo; o filho, nunca. */
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__title,
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__bg {
    animation: none;
    opacity: 1;
  }
  .adjuto-hero-campaign.is-ready .adjuto-hero-campaign__title {
    transform: none;
  }

}
