/* ==========================================================================
   COMPONENTS — peças reutilizáveis: botão, campo, formulário, selo, lockup.

   REGRA: nenhuma cor, fonte ou medida literal. Tudo sai de token, inclusive
   o que parece óbvio — foi assim que o formulário deixou de supor que está
   sobre fundo escuro e passou a servir também um projeto de fundo claro.
   É o que permite copiar esta folha para um projeto novo e trocar só o
   tokens.css. Ajuste de layout de dobra vai no sections.css, não aqui.
   ========================================================================== */

/* ==========================================================================
   1. BOTÃO DE CONVERSÃO
   Três camadas independentes, todas em opacity/transform/background-position
   para não forçar layout a cada frame:
     ::before  brilho que varre no hover
     ::after   anel pulsante contínuo
     próprio   gradiente verde que desliza (animação de cor)
   ========================================================================== */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2xs);
  min-height: 3.5rem;
  padding: 0.95rem 2.4rem;
  border: 0;
  border-radius: var(--r-pill);
  font-size: clamp(0.9375rem, 0.88rem + 0.28vw, 1.0625rem);
  font-weight: var(--w-bold);
  letter-spacing: 0.06em;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  color: var(--action-ink, #052a15);
  background-color: var(--action, #22de70);
  /* Fallback em TODO var() dentro da lista: se um único token faltar, a
     declaração inteira vira inválida e o botão fica sem fundo nenhum. Esta
     folha é feita para ser copiada para um projeto novo, onde o tokens.css
     ainda está incompleto — é exatamente aí que isso morde.                  */
  background-image: linear-gradient(
    100deg,
    var(--action-deep, #0cc45c) 0%,
    var(--action, #22de70) 26%,
    var(--action-hover, #5cf19b) 50%,
    var(--action, #22de70) 74%,
    var(--action-deep, #0cc45c) 100%
  );
  background-size: 260% 100%;
  background-position: 0% 50%;
  box-shadow: var(--sh-action);
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  animation: btn-hue 5.5s linear infinite, btn-breathe 3.2s var(--ease-out) infinite;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-mid) var(--ease-out),
    filter var(--dur-fast) var(--ease-out);
}

/* deslize do gradiente — a "animação de cor" */
@keyframes btn-hue {
  0%   { background-position: 0% 50%; }
  100% { background-position: 260% 50%; }
}

/* respiração discreta do próprio botão */
@keyframes btn-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.022); }
}

/* Anel pulsante. Transborda o botão de propósito — é isso que faz o pulso.
   Feito com transform + opacity, não com spread de box-shadow: box-shadow
   animado repinta a cada frame, e aqui são três botões pulsando sem parar. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  border: 2px solid var(--action, #22de70);
  opacity: 0;
  animation: btn-ring 2.6s var(--ease-out) infinite;
}

@keyframes btn-ring {
  0%   { transform: scale(1);    opacity: 0.55; }
  70%  { transform: scale(1.22); opacity: 0; }
  100% { transform: scale(1.22); opacity: 0; }
}

/* Brilho que varre no hover.
   O pseudo fica parado em inset: 0 — quem se move é o FUNDO dele. Antes o
   brilho varria com translateX(±120%) e, como nada recorta o botão, ele
   aparecia flutuando fora. `overflow: hidden` no .btn não resolveria: cortaria
   também o anel do ::after, que precisa transbordar. Movendo o
   background-position, o brilho é fisicamente incapaz de sair da caixa.      */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: linear-gradient(
    110deg,
    transparent 40%,
    rgba(255, 255, 255, 0.62) 50%,
    transparent 60%
  );
  background-size: 300% 100%;
  background-repeat: no-repeat;
  background-position: 150% 0;   /* em repouso, a faixa fica fora, à esquerda */
  opacity: 0;
  transition: opacity var(--dur-fast) linear;
}

.btn:hover {
  transform: translateY(-3px) scale(1.015);
  box-shadow: 0 18px 44px color-mix(in srgb, var(--c-green-deep) 52%, transparent);
  filter: saturate(1.12);
  animation-play-state: paused, paused;
}

.btn:hover::before {
  opacity: 1;
  animation: btn-shine 0.85s var(--ease-out);
}

@keyframes btn-shine {
  from { background-position: 150% 0; }
  to   { background-position: -50% 0; }
}

.btn:active {
  transform: translateY(0) scale(0.975);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--c-green-deep) 46%, transparent);
  transition-duration: 80ms;
}

.btn:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 4px;
}

.btn[disabled],
.btn[aria-busy="true"] {
  cursor: progress;
  filter: saturate(0.55) brightness(0.97);
  animation-play-state: paused, paused;
  transform: none;
}

.btn[disabled]::after { animation: none; opacity: 0; }

.btn--block { width: 100%; }

/* Em 320px o rótulo com o respiro do desktop estourava o gutter. Na faixa
   estreita o botão ocupa a linha inteira — alvo de toque maior e nenhum corte. */
@media (max-width: 30rem) {
  .btn { padding-inline: 1.5rem; width: 100%; }
}

/* spinner do estado de envio */
.btn__spin {
  width: 1.05em;
  height: 1.05em;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--action-ink) 28%, transparent);
  border-top-color: var(--action-ink);
  animation: spin 0.7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .btn { animation: none; background-position: 50% 50%; }
  .btn::after { animation: none; opacity: 0; }
  .btn::before { display: none; }
}

/* ==========================================================================
   2. CAMPO DE FORMULÁRIO
   Erro DENTRO do campo e fora do fluxo: mensagem abaixo empurraria o layout
   e a pessoa perderia o lugar no meio do preenchimento.
   ========================================================================== */
.field {
  position: relative;
  display: block;
}

.field + .field { margin-top: 0.875rem; }

.field__input {
  width: 100%;
  min-height: 3.5rem;
  padding: 1rem 3.25rem 1rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  background-color: var(--field-bg, #ffffff);
  color: var(--field-ink);
  font-size: max(1rem, var(--t-body));  /* < 16px faz o iOS dar zoom ao focar */
  font-weight: var(--w-medium);
  line-height: 1.2;
  box-shadow: var(--sh-s);
  transition:
    border-color var(--dur-mid) var(--ease-out),
    box-shadow var(--dur-mid) var(--ease-out),
    transform var(--dur-mid) var(--ease-spring),
    padding var(--dur-mid) var(--ease-out);
}

.field__input::placeholder {
  color: var(--field-place);
  font-weight: var(--w-regular);
  transition: opacity var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out);
}

.field__input:hover {
  box-shadow: 0 6px 18px color-mix(in srgb, var(--c-blue) 22%, transparent);
}

.field__input:focus {
  outline: 0;
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--action) 80%, #ffffff);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--action) 26%, transparent),
    0 14px 30px color-mix(in srgb, var(--c-blue) 26%, transparent);
}

/* o placeholder recua um passo quando o campo recebe o cursor */
.field__input:focus::placeholder {
  opacity: 0.55;
  transform: translateX(4px);
}

/* O preenchimento automático é a maior alavanca de conversão de um formulário
   no celular — e o Chrome pinta o campo de azul-claro ao usá-lo, o que
   arrebentaria a pílula branca sobre o azul do hero. A cor do autofill só cede
   a um `inset` de box-shadow; a do texto, a -webkit-text-fill-color.          */
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover,
.field__input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--field-ink, #17243c);
  -webkit-box-shadow: inset 0 0 0 100px var(--field-bg, #ffffff), var(--sh-s);
  caret-color: var(--field-ink, #17243c);
  transition: background-color 9999s ease-out 0s;  /* segura o flash amarelo */
}

.field__input:-webkit-autofill:focus {
  -webkit-box-shadow:
    inset 0 0 0 100px var(--field-bg, #ffffff),
    0 0 0 4px color-mix(in srgb, var(--action, #22de70) 26%, transparent),
    0 14px 30px color-mix(in srgb, var(--c-blue, #10306b) 26%, transparent);
}

/* selo de campo válido — entra com mola */
.field__mark {
  position: absolute;
  top: 50%;
  right: 1.15rem;
  width: 1.4rem;
  height: 1.4rem;
  translate: 0 -50%;
  color: var(--action-deep);
  opacity: 0;
  transform: scale(0.4);
  transition:
    opacity var(--dur-mid) var(--ease-out),
    transform var(--dur-mid) var(--ease-spring);
  pointer-events: none;
}

.field.is-valid .field__mark { opacity: 1; transform: scale(1); }

/* cápsula de erro, ancorada dentro do campo */
.field__error {
  position: absolute;
  top: 50%;
  right: 0.55rem;
  translate: 0 -50%;
  max-width: 62%;
  padding: 0.24rem 0.7rem;
  border-radius: var(--r-pill);
  background: var(--danger-bg, #fff0f4);
  color: var(--danger);
  font-size: 0.75rem;
  font-weight: var(--w-bold);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.88);
  transition:
    opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-spring);
}

.field__error:empty { display: none; }

.field.is-invalid .field__error { opacity: 1; transform: scale(1); }

.field__input[aria-invalid="true"] {
  border-color: color-mix(in srgb, var(--danger) 55%, #ffffff);
  padding-right: 9rem;               /* abre espaço para o aviso não cobrir o texto */
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--danger) 16%, transparent);
  animation: field-shake 0.32s var(--ease-out);
}

@keyframes field-shake {
  0%, 100% { translate: 0 0; }
  22%      { translate: -5px 0; }
  48%      { translate: 4px 0; }
  74%      { translate: -2px 0; }
}

/* honeypot — invisível para gente, preenchido por bot */
.field--trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   3. CARTÃO DO FORMULÁRIO
   ========================================================================== */
.form { position: relative; }

.form__hint {
  margin-bottom: var(--sp-s);
  font-size: var(--t-small);
  line-height: 1.45;
  color: var(--form-hint-ink);
}

.form__submit { margin-top: 0.875rem; }

.form__status {
  margin-top: 0.75rem;
  min-height: 1.2em;
  font-size: var(--t-small);
  font-weight: var(--w-semibold);
  color: var(--form-status-ink);
}

.form__status[data-state="error"] { color: var(--form-error-ink); }
.form__status[data-state="ok"] { color: var(--form-ok-ink); }

/* Depois do sucesso sem redirect, o formulário sai de cena e fica só a
   confirmação. Sem isso o botão volta habilitado e um segundo clique manda o
   mesmo lead de novo — duplicata no CRM e conversão inflada no Ads.          */
.form.is-done .field,
.form.is-done .form__hint,
.form.is-done .form__submit { display: none; }

.form.is-done .form__status {
  margin-top: 0;
  font-size: var(--t-lead);
  line-height: var(--lh-lead);
}

/* realce quando um CTA de outra seção chama o formulário */
.form.is-called { animation: form-call 1.1s var(--ease-out); }

@keyframes form-call {
  0%   { filter: drop-shadow(0 0 0 transparent); }
  35%  { filter: drop-shadow(0 0 22px color-mix(in srgb, var(--action) 85%, transparent)); }
  100% { filter: drop-shadow(0 0 0 transparent); }
}

/* ==========================================================================
   4. SELO DE DATA + CANAL
   ========================================================================== */
.pill {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 1.1rem;
  border-radius: var(--r-s);
  background: var(--pill-bg, rgba(6, 16, 42, 0.62));
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--pill-ink, #ffffff);
  font-size: clamp(0.8125rem, 0.78rem + 0.18vw, 0.9375rem);
  font-weight: var(--w-bold);
  line-height: 1.2;
}

.pill > span:first-child { white-space: nowrap; }

.pill__sep {
  width: 1px;
  align-self: stretch;
  background: var(--pill-line, rgba(255, 255, 255, 0.24));
}

.pill__channel {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: var(--w-regular);
  white-space: nowrap;
}

.pill__channel strong { font-weight: var(--w-bold); }

.pill__yt { width: 1.5rem; height: auto; flex: none; }

/* o selo aperta antes de quebrar */
@media (max-width: 30rem) {
  .pill { padding: 0.5rem 0.85rem; gap: 0.5rem; }
  .pill__channel { gap: 0.3rem; }
  .pill__yt { width: 1.3rem; }
}

/* abaixo de 384px a linha única só caberia em corpo ilegível: o selo vira
   duas linhas e o divisor vertical sai de cena */
@media (max-width: 23.99rem) {
  .pill { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
  .pill > span:first-child { white-space: nowrap; }

.pill__sep { display: none; }
}

/* ==========================================================================
   5. LOCKUP DA MARCA
   ========================================================================== */
.lockup {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.lockup__logo {
  width: clamp(13rem, 11rem + 9vw, 19.5rem);
  height: auto;
}

