/* ==========================================================================
   Disk João do Gás v2: style.css
   Tema escuro verde com faixa amarela de accent + hero 3D dirigido por
   scroll. Ver PLANO-V2.md para origem de cada decisão de cor, tipografia,
   cena 3D e animação.
   ========================================================================== */

/* ---------- reset mínimo ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* overflow-x: clip, nunca hidden. hidden cria um novo bloco de formatação de
   scroll e quebra position: sticky (header) e o pin do ScrollTrigger (hero
   3D). clip corta o transbordo sem esse efeito colateral. Precisa estar nos
   dois, html e body: só um dos dois não resolve corte lateral no mobile. */
html,
body {
  overflow-x: clip;
}

body,
h1,
h2,
h3,
p,
figure {
  margin: 0;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* picture nasce inline e sem altura própria. Dentro de um bloco que preenche
   por object-fit, o height:100% da img resolve contra a altura auto do picture
   e vira altura natural: a foto para no meio e sobra fundo chapado. Todo
   wrapper que preenche precisa repassar a altura. */
picture {
  display: block;
}

.hero__media picture,
.produto__media picture,
.atende__foto picture {
  width: 100%;
  height: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
}

/* ---------- tokens ---------- */
:root {
  --verde-fundo: #00251F;
  --verde-secao: #00342C;
  --verde-apoio: #2D605A;
  --amarelo: #FFF200;
  --osso: #F4F2ED;
  --tinta: #101512;

  --r: 4px;
  --section-space: clamp(4.5rem, 9vw, 8rem);
  --container-max: 1200px;
  --container-pad: clamp(1.25rem, 4vw, 2.5rem);
  --ease: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- fonte ---------- */
/* self-hosted, zero CDN. Sem preload nesta rodada de propósito: na v1 o
   preload de fonte competiu por banda com a imagem do LCP. Se o Lighthouse
   acusar o texto como LCP, adicionamos o preload só da Clash Display. */
@font-face {
  font-family: "Clash Display";
  src: url("../fonts/ClashDisplay-Variable.woff2?v=1786079477") format("woff2-variations"), url("../fonts/ClashDisplay-Variable.woff2?v=1786079477") format("woff2");
  font-weight: 200 700;
  font-display: swap;
  font-style: normal;
}

@font-face {
  font-family: "Satoshi";
  src: url("../fonts/Satoshi-Variable.woff2?v=1786079479") format("woff2-variations"), url("../fonts/Satoshi-Variable.woff2?v=1786079479") format("woff2");
  font-weight: 300 900;
  font-display: swap;
  font-style: normal;
}

body {
  font-family: "Satoshi", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--verde-fundo);
  color: var(--osso);
  font-variation-settings: "wght" 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

section {
  padding-block: var(--section-space);
  position: relative;
}

h1,
h2,
h3 {
  font-family: "Clash Display", "Satoshi", system-ui, sans-serif;
  font-variation-settings: "wght" 600;
  letter-spacing: -0.02em;
  line-height: 1.02;
}

h2 {
  font-size: clamp(1.875rem, 4vw, 2.75rem);
  text-transform: none;
}

h3 {
  font-size: clamp(1.25rem, 2.4vw, 1.5rem);
}

p {
  max-width: 62ch;
}

/* ---------- botões ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .9rem 1.6rem;
  border-radius: var(--r);
  font-family: "Satoshi", sans-serif;
  font-variation-settings: "wght" 700;
  font-size: 1rem;
  line-height: 1.2;
  white-space: nowrap;
  transition: transform 80ms var(--ease);
  position: relative;
  z-index: 5;
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--amarelo);
  color: var(--tinta);
}

.btn--outline {
  background: transparent;
  color: var(--osso);
  border: 1px solid rgba(244, 242, 237, .4);
}

/* ---------- header ---------- */
.header {
  position: sticky;
  top: 0;
  z-index: 40;
  height: 72px;
  display: flex;
  align-items: center;
  background: rgba(0, 37, 31, .92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(45, 96, 90, .4);
  transition: height 250ms ease-out, background 250ms ease-out;
}

/* trocado via JS quando scrollY > 80px: cabeçalho encolhe e o fundo ganha
   mais opacidade/blur */
.header.is-scrolled {
  height: 58px;
  background: rgba(0, 37, 31, .98);
}

.header__inner {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* logo-completa.webp (306x223, ~1.37:1) é mais alta que a logo antiga
   (~2,4:1): a mesma altura de antes (40px) deixaria os telefones da faixa
   vermelha ilegíveis. 52px é o piso onde eles ainda leem no header aberto;
   no header encolhido (58px) tudo bem que fiquem pequenos, contanto que não
   borrem — e não borram, é downscale da resolução nativa, nunca upscale. */
.header__logo img {
  height: 52px;
  width: auto;
  transition: height 250ms ease-out;
}

.header.is-scrolled .header__logo img {
  height: 42px;
}

.header__actions {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.header__phone {
  font-variation-settings: "wght" 600;
  font-size: .95rem;
}

.header .btn {
  padding: .65rem 1.25rem;
  font-size: .9rem;
}

@media (max-width: 640px) {
  .header__phone {
    display: none;
  }

  .header__logo img {
    height: 44px;
  }

  .header.is-scrolled .header__logo img {
    height: 36px;
  }
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  /* header sticky em fluxo (72px) + 100svh cheio soma além da tela: sempre
     calc(100svh - altura do header). svh, nunca dvh. */
  min-height: calc(100svh - 72px);
  overflow: clip;
  /* zera o padding-block genérico de `section` de propósito: todo filho
     visual do hero (media/scrim/video-wrap/container) já é position:absolute,
     então o padding nunca teria efeito nenhum - deixá-lo implícito só
     confundiria quem ler depois. */
  padding-block: 0;
}

/* rodada 3, item 1: o bloco de texto sai do rodapé do hero (align-items:end)
   e vai para 52% da altura — "centro/meio da tela", ainda alinhado à
   esquerda. .container vira o único filho posicionado (media/scrim/vídeo já
   são absolutos), então tirá-lo do fluxo com position:absolute não muda a
   altura do .hero, que já é fixada pelo min-height acima. */
.hero > .container {
  position: absolute;
  top: 52%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -3;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: linear-gradient(to top,
      rgba(0, 37, 31, .96) 0%,
      rgba(0, 37, 31, .80) 38%,
      rgba(0, 37, 31, .25) 70%,
      rgba(0, 37, 31, .45) 100%);
}


/* ---------- vídeo do hero, controlado pelo scroll ---------- */
/* fica por cima da foto/scrim, atrás do texto. pointer-events none: o CTA e
   o telefone continuam clicáveis o tempo inteiro, mesmo durante o pin. */
.hero__video-wrap {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Coluna de leitura à esquerda.
   O vídeo termina com os cilindros no centro-direita e o texto mora na
   esquerda, então os dois se encontram no meio. Empurrar o quadro do vídeo
   com scale+translate ficou pior: ampliou os cilindros e cortou o P45 fora
   da tela. A saída certa é a mesma da Prime Pinturas - degradê LATERAL, que
   dá contraste ao texto sem escurecer a foto inteira nem tocar no
   enquadramento. Mora aqui dentro do wrap, e não no .hero__scrim, porque o
   scrim tem z-index -2 e ficaria ATRÁS do vídeo. */
/* MOBILE: sobreposição preta por cima do vídeo.
   Atenção ao z-index: o .hero__scrim mora em -2, ATRÁS do vídeo (-1), então
   ele nunca escureceu o vídeo - só a foto de fundo. Por isso "faltava sombra
   no celular" mesmo com scrim existindo. A sobreposição real tem que estar
   aqui dentro do wrap, acima do vídeo.
   Preto e não o verde da marca: para escurecer imagem, preto não altera o
   matiz do que está embaixo; verde tingiria o vídeo inteiro de esverdeado.
   O gradiente é mais denso no miolo e no pé, que é onde moram o h1, o lead e
   os botões, e mais leve no topo, onde só passa o rótulo (que já tem sombra
   própria). */
@media (max-width: 999px) {
  .hero__video-wrap::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(to bottom,
        rgba(0, 0, 0, .30) 0%,
        rgba(0, 0, 0, .22) 18%,
        rgba(0, 0, 0, .48) 42%,
        rgba(0, 0, 0, .66) 62%,
        rgba(0, 0, 0, .74) 100%);
  }
}

@media (min-width: 1000px) {
  .hero__video-wrap::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(to right,
        rgba(0, 37, 31, .93) 0%,
        rgba(0, 37, 31, .84) 26%,
        rgba(0, 37, 31, .50) 48%,
        rgba(0, 37, 31, .12) 66%,
        rgba(0, 37, 31, 0) 78%);
  }
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
}

/* No celular o arquivo carregado já é um RECORTE VERTICAL 3:4 da mesma cena
   (app.js escolhe por data-src-mobile), então "cover" é o certo: preenche a
   tela sem tarja e sem perder os cilindros. Era "contain" enquanto o mobile
   ainda recebia o 16:9, e aí virava uma faixa no meio com vazio em cima e
   embaixo. */
@media (max-width: 700px) {
  .hero__video {
    object-fit: cover;
    object-position: center 42%;
  }
}

/* classe aplicada por app.js quando o vídeo dispara "loadeddata": crossfade
   vídeo 0->1, foto de fundo desce para .35 por trás dele */
.hero__video-wrap.is-ready .hero__video {
  transition: opacity 600ms var(--ease);
  opacity: 1;
}

.hero.is-video-ready .hero__media {
  transition: opacity 600ms var(--ease);
  opacity: .35;
}

/* ancorados embaixo à direita, nunca sobre o bloco de texto (que fica
   ancorado embaixo à esquerda) — os frames foram compostos com o lado
   esquerdo livre de propósito */
.hero__label {
  position: absolute;
  right: clamp(1.25rem, 6vw, 4rem);
  bottom: clamp(1.5rem, 6vw, 3rem);
  max-width: 20rem;
  text-align: right;
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  /* SEM transition aqui de propósito. A opacidade e o deslocamento agora são
     escritos a cada frame pelo app.js, seguindo o progresso do scroll com
     rampa própria (easeInOutSine). Com transition, cada escrita reiniciaria
     uma interpolação de 320ms por cima da que o scroll já está fazendo -
     dois amortecedores em série, que é justamente o que faz o movimento
     parecer arrastado e fora de sincronia com o dedo. */
  will-change: opacity, transform;
}


/* ===== VERSÃO DRONE =====
   Os rótulos aqui são frases ("Sede própria", "Frota própria"), não códigos
   curtos de três caracteres como P13/P20/P45. No mesmo corpo de fonte eles
   estouravam a caixa e quebravam em três linhas. Corpo menor e caixa mais
   larga resolvem sem perder o destaque. */
.hero__label {
  max-width: 26rem;
}

.hero__label strong {
  font-size: clamp(1.5rem, 2.9vw, 2.25rem);
}

.hero__label strong b {
  font-size: .5em;
}

@media (max-width: 640px) {
  .hero__label {
    max-width: 17rem;
  }

  .hero__label strong {
    font-size: clamp(1.35rem, 6vw, 1.7rem);
  }
}

/* usado só no fallback de prefers-reduced-motion, onde o JS não roda */
.hero__label.is-visible {
  opacity: 1;
  transform: none;
}

/* rodada 3, item 2: rótulos bem maiores, mais destaque no scroll.
   text-shadow em vez de caixa: o rótulo passa por cima de parede clara e de
   metal escuro conforme o vídeo avança, e sem isso o amarelo some no trecho
   claro. A sombra é escura e curta, some no fundo escuro e salva o claro. */
.hero__label strong {
  display: block;
  font-family: "Clash Display", sans-serif;
  font-variation-settings: "wght" 600;
  color: var(--amarelo);
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: .98;
  letter-spacing: -.01em;
  text-shadow: 0 2px 14px rgba(0, 20, 15, .85), 0 1px 3px rgba(0, 20, 15, .9);
}

/* a categoria vira segunda linha própria, menor e espaçada */
.hero__label strong b {
  display: block;
  font-variation-settings: "wght" 500;
  text-transform: uppercase;
  font-size: .42em;
  letter-spacing: .14em;
  line-height: 1.2;
  margin-top: .35em;
}

.hero__label span {
  display: block;
  margin-top: .5rem;
  font-size: clamp(.95rem, 1.4vw, 1.15rem);
  color: var(--osso);
  text-shadow: 0 1px 10px rgba(0, 20, 15, .9), 0 1px 2px rgba(0, 20, 15, .95);
  text-wrap: balance;
}

.hero__label span b {
  font-variation-settings: "wght" 700;
  color: #fff;
}

/* no mobile o texto empilha em coluna e ocupa a largura quase inteira lá
   embaixo (sem "metade direita livre" como no desktop): embaixo à direita
   colidiria direto com o botão de telefone. O topo do hero, entre o header
   e o início do bloco de texto, é o que sobra livre aqui. Medido no
   navegador: com o bloco de texto começando por volta de 40% da altura do
   hero, um rótulo por volta de 12vh do topo nunca encosta nele. */
@media (max-width: 640px) {
  .hero__label {
    right: clamp(1.25rem, 6vw, 2rem);
    bottom: auto;
    top: clamp(4.5rem, 12vh, 6rem);
    /* 12rem era estreito demais para "Empilhadeira" e jogava palavra órfã
       para uma terceira linha. 15rem cabe a categoria mais longa inteira. */
    max-width: 15rem;
  }

  .hero__label strong {
    font-size: clamp(1.75rem, 8vw, 2.25rem);
  }
}

.hero__content {
  position: relative;
  z-index: 1;
  max-width: 48rem;
}

/* rodada 3, item 8: no mobile, o h1 + lead somem durante o scroll (JS,
   dentro de initHeroVideo) para liberar a tela para os botijões, mas os
   CTAs (irmão, fora deste wrapper) nunca fazem parte desse fade — ficam
   sempre no lugar, sempre clicáveis. app.js seta opacity/transform inline
   aqui direto por frame (junto com o resto do scrub), então não há
   transition CSS competindo com o RAF. */
.hero__headline {
  will-change: opacity, transform;
}

.hero h1 {
  text-transform: uppercase;
  /* piso testado no navegador em 390px: 2.5rem do plano quebrava a copy em
     5 linhas. 2.125rem é o maior piso que ainda produz o melhor resultado
     possível (3 linhas) sem ficar ilegível. Acima de ~486px o vw assume. */
  font-size: clamp(2.125rem, 5.2vw, 4rem);
  color: var(--osso);
  /* Sombra de apoio: o título passa por cima de vídeo, e o vídeo tem trechos
     claros (parede branca, céu, metal no sol) onde o osso quase some. Três
     camadas em vez de uma: uma larga e fraca que cria a "cama" escura sob o
     bloco todo, uma média que dá corpo, e uma curta e forte que garante a
     borda da letra. Sombra única e grande vira borrão cinza; única e pequena
     não segura o fundo claro. Escura no tom do verde da marca, não preta,
     senão suja a paleta. */
  text-shadow:
    0 8px 40px rgba(0, 20, 15, .55),
    0 3px 16px rgba(0, 20, 15, .5),
    0 1px 3px rgba(0, 20, 15, .6);
}

/* o amarelo é o mais frágil sobre fundo claro: reforço só nele */
.hero h1 .hl {
  text-shadow:
    0 8px 40px rgba(0, 20, 15, .6),
    0 3px 16px rgba(0, 20, 15, .58),
    0 1px 3px rgba(0, 20, 15, .75);
}

.hero h1 .line {
  display: block;
  opacity: 0;
  transform: translateY(24px);
  font-variation-settings: "wght" 400;
  transition: opacity 900ms var(--ease), transform 900ms var(--ease), font-variation-settings 900ms var(--ease);
}

.hero__content.is-ready h1 .line {
  opacity: 1;
  transform: translateY(0);
  font-variation-settings: "wght" 700;
}

.hero__content.is-ready h1 .line:nth-child(2) {
  transition-delay: 80ms;
}

@media (prefers-reduced-motion: reduce) {
  .hero h1 .line {
    opacity: 1;
    transform: translateY(0);
    font-variation-settings: "wght" 700;
    transition: none;
  }
}

.hero h1 .hl {
  color: var(--amarelo);
}

.hero__lead {
  margin-top: 1.5rem;
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  color: var(--osso);
  max-width: 40ch;
  /* mesma razão do h1, em dose menor: texto pequeno sobre vídeo claro some
     antes do texto grande, mas sombra forte em corpo pequeno vira mancha */
  text-shadow:
    0 4px 22px rgba(0, 20, 15, .6),
    0 1px 3px rgba(0, 20, 15, .7);
}

.hero__ctas {
  margin-top: 2rem;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

@media (max-width: 520px) {
  .hero__ctas {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ---------- faixa amarela de números ---------- */
.numeros {
  background: var(--amarelo);
  color: var(--tinta);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
}

.numeros .container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  text-align: center;
}

.numeros__item {
  transition: opacity 600ms var(--ease), transform 600ms var(--ease);
}

.numeros__item:nth-child(1) { transition-delay: 0ms; }
.numeros__item:nth-child(2) { transition-delay: 120ms; }
.numeros__item:nth-child(3) { transition-delay: 240ms; }

.numeros__item strong {
  display: block;
  text-transform: uppercase;
  font-family: "Clash Display", sans-serif;
  font-variation-settings: "wght" 600;
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  line-height: 1;
}

.numeros__item span {
  display: block;
  margin-top: .5rem;
  font-variation-settings: "wght" 500;
  font-size: .95rem;
}

@media (max-width: 640px) {
  .numeros .container {
    grid-template-columns: 1fr;
    gap: 1.75rem;
  }
}

/* ---------- produtos ---------- */
.produtos {
  background: var(--verde-fundo);
}

.produtos__titulo {
  margin-bottom: 2.5rem;
}

.produtos__grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .produtos__grid {
    grid-template-columns: 1.4fr 1fr 1fr;
    grid-template-areas:
      "p45 p20  resid"
      "p45 agua agua";
    min-height: 800px;
  }

  .produto--p45 {
    grid-area: p45;
  }

  .produto--p20 {
    grid-area: p20;
  }

  .produto--resid {
    grid-area: resid;
  }

  .produto--agua {
    grid-area: agua;
  }
}

.produto {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--r);
  min-height: 320px;
}

/* reveal por clip-path: a foto "abre de baixo para cima" ao entrar na tela.
   inset(topo direita baixo esquerda). fechado = corta 100% da base. */
.reveal-clip {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 800ms var(--ease);
}

.reveal-clip.is-visible {
  clip-path: inset(0 0 0% 0);
}

.reveal-clip:nth-child(1) { transition-delay: 0ms; }
.reveal-clip:nth-child(2) { transition-delay: 100ms; }
.reveal-clip:nth-child(3) { transition-delay: 200ms; }
.reveal-clip:nth-child(4) { transition-delay: 300ms; }

.reveal-clip .produto__media img {
  transform: scale(1.08);
  transition: transform 800ms var(--ease), transform 400ms var(--ease);
}

.reveal-clip.is-visible .produto__media img {
  transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .reveal-clip,
  .reveal-clip .produto__media img {
    clip-path: inset(0 0 0% 0);
    transform: none;
    transition: none;
  }
}

.produto__media {
  position: absolute;
  /* rodada 3, item 7: parallax leve (y -20 -> 20, scrub) via GSAP em app.js.
     O overscan vertical de 20px de cada lado garante que a foto nunca
     descole da borda do card durante a translação — sem ele, o topo/base
     ficaria exposto (cor de fundo chapada) nos extremos do scroll. O scale
     de reveal (.reveal-clip) mexe no <img>, este parallax mexe no wrapper:
     são dois elementos diferentes de propósito, senão o GSAP (que escreve a
     matrix de transform inteira) atropela o scale controlado por CSS. */
  inset: -20px 0;
  z-index: 0;
  will-change: transform;
}

.produto__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms var(--ease);
}

.produto__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, rgba(0, 37, 31, .94), rgba(0, 37, 31, .15));
  transition: background 400ms var(--ease);
}

.produto__texto {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 1.75rem;
}

.produto__texto h3 {
  color: var(--osso);
  text-transform: none;
}

.produto__texto p {
  margin-top: .5rem;
  color: var(--osso);
  font-size: .95rem;
  max-width: 34ch;
}

@media (hover: hover) {
  .produto:hover .produto__media img {
    transform: scale(1.04);
  }

  .produto:hover .produto__scrim {
    background: linear-gradient(to top, rgba(0, 37, 31, .98), rgba(0, 37, 31, .35));
  }
}

/* ---------- estrutura (vídeo) ---------- */
.estrutura {
  background: var(--verde-secao);
  overflow: clip;
}

.estrutura .container {
  display: grid;
  gap: 2.5rem;
  align-items: center;
}

@media (min-width: 860px) {
  .estrutura .container {
    grid-template-columns: 1fr 1fr;
    gap: 3.5rem;
  }
}

.estrutura__video-wrap {
  order: -1;
  border-radius: var(--r);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--verde-apoio);
  /* deslocado por GSAP (scrub, y -40 -> 40) quando o motion pesado carrega.
     will-change evita popping no primeiro frame do transform */
  will-change: transform;
}

@media (min-width: 860px) {
  .estrutura__video-wrap {
    order: 2;
  }
}

.estrutura__video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.estrutura__texto p {
  margin-top: 1rem;
}

.estrutura__apoio {
  margin-top: 1.5rem;
  font-variation-settings: "wght" 600;
  color: var(--amarelo);
}

/* ---------- como funciona ---------- */
/* rodada 3, item 5: redesenhado inteiro (diagramação e animação). Os três
   passos são uma sequência temporal (chama -> confirma -> recebe em 15 min):
   numeração grande em Clash Display marca essa ordem, respiro real entre os
   três substitui os divisores apertados de antes, e a linha (SVG no
   desktop, barra vertical no mobile) conecta um ao outro. */
.como-funciona {
  background: var(--verde-fundo);
}

.passos-wrap {
  position: relative;
  margin-top: 3rem;
}

/* linha horizontal (desktop): SVG desenhado por stroke-dashoffset, scrub */
.passos__linha {
  display: none;
  width: 100%;
  height: 3px;
  margin-bottom: 3rem;
  overflow: visible;
}

@media (min-width: 760px) {
  .passos__linha {
    display: block;
  }
}

/* sem GSAP (reduced-motion, sem WebGL, etc) a linha aparece completa: o
   stroke-dashoffset some via CSS puro, sem depender de JS nenhum */
#linha-como-funciona-progresso {
  stroke-dashoffset: 0;
}

@media (min-width: 760px) {
  #linha-como-funciona-progresso.js-controlado {
    stroke-dashoffset: 1000;
  }
}

/* linha vertical (mobile): duas divs (trilho + preenchimento), não SVG —
   dispensa casar viewBox com a altura variável da pilha de passos. O
   preenchimento escala em Y via GSAP (scrub), origem no topo. */
.passos__linha-v {
  display: none;
  position: absolute;
  top: .3rem;
  bottom: .3rem;
  left: 1.15rem;
  width: 2px;
  background: var(--verde-apoio);
  z-index: 0;
}

/* sem GSAP, a barra vertical some completa via CSS puro (mesma lógica da
   horizontal): só fica em scaleY(0) quando app.js marca .js-controlado */
.passos__linha-v-fill {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--amarelo);
  transform-origin: top;
  transform: scaleY(1);
}

@media (max-width: 759px) {
  .passos__linha-v {
    display: block;
  }

  .passos__linha-v-fill.js-controlado {
    transform: scaleY(0);
  }
}

.passos {
  display: grid;
  gap: 2.75rem;
}

@media (min-width: 760px) {
  .passos {
    grid-template-columns: repeat(3, 1fr);
    gap: 3rem;
  }
}

@media (max-width: 759px) {
  .passos {
    padding-left: 2.75rem;
  }
}

.passo {
  position: relative;
}

/* número grande, Clash Display, --amarelo em opacidade baixa: marca a
   sequência sem emoji e sem ícone genérico */
.passo__num {
  display: block;
  font-family: "Clash Display", sans-serif;
  font-variation-settings: "wght" 600;
  font-size: clamp(2.75rem, 6vw, 4rem);
  line-height: 1;
  color: var(--amarelo);
  opacity: .32;
  margin-bottom: .75rem;
  user-select: none;
}

@media (max-width: 759px) {
  .passo__num {
    position: absolute;
    top: -.1rem;
    left: -2.75rem;
    font-size: 1.15rem;
    opacity: 1;
    width: 2.3rem;
    height: 2.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--verde-fundo);
    border: 2px solid var(--verde-apoio);
    margin-bottom: 0;
  }
}

.passo h3 {
  color: var(--osso);
  text-transform: none;
}

.passo p {
  margin-top: .75rem;
  color: rgba(244, 242, 237, .85);
}

/* ---------- onde atende ---------- */
.atende {
  background: var(--verde-secao);
}

.atende .container {
  display: grid;
  gap: 2.5rem;
  align-items: center;
}

@media (min-width: 860px) {
  .atende .container {
    grid-template-columns: 1fr 1fr;
    gap: 3.5rem;
  }
}

.atende__texto p {
  margin-top: 1rem;
}

.atende__bairros {
  margin-top: 1.25rem;
  color: rgba(244, 242, 237, .85);
}

.atende__nap {
  margin-top: 1.5rem;
  font-variation-settings: "wght" 600;
}

.atende__foto {
  border-radius: var(--r);
  overflow: hidden;
}

.atende__foto img {
  width: 100%;
  height: auto;
  /* escalado por GSAP (scrub, 1.1 -> 1.0) quando o motion pesado carrega */
  will-change: transform;
}

/* ---------- FAQ ---------- */
.faq {
  background: var(--verde-fundo);
}

.faq__lista {
  margin-top: 2.5rem;
  border-top: 1px solid var(--verde-apoio);
}

.faq__item {
  border-bottom: 1px solid var(--verde-apoio);
}

.faq__item summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.5rem;
}

.faq__item summary::-webkit-details-marker {
  display: none;
}

.faq__item summary h3 {
  font-family: "Satoshi", sans-serif;
  font-variation-settings: "wght" 700;
  font-size: 1.05rem;
  text-transform: none;
  letter-spacing: normal;
  line-height: 1.3;
}

.faq__icon {
  flex-shrink: 0;
  transition: transform 250ms var(--ease);
}

.faq__item[open] .faq__icon {
  transform: rotate(45deg);
}

.faq__resposta {
  padding-bottom: 1.5rem;
  color: rgba(244, 242, 237, .85);
}

/* ---------- CTA final ---------- */
.cta-final {
  position: relative;
  background: var(--verde-secao);
  text-align: center;
  overflow: clip;
}

/* rodada 3, item 7: "fundo com leve deslocamento". Não existe imagem de
   fundo nesta seção (nenhum gradiente decorativo é permitido), então o
   deslocamento é entre duas cores sólidas da própria paleta - uma camada
   --verde-fundo (mais escura) por trás, deslocada em scrub, cria a
   profundidade sem virar gradiente. */
.cta-final__fundo {
  position: absolute;
  inset: -12% 0;
  background: var(--verde-fundo);
  opacity: .4;
  z-index: 0;
  will-change: transform;
}

.cta-final .container {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.cta-final p {
  margin-top: 1rem;
}

.cta-final .btn {
  margin-top: 2rem;
  padding: 1.1rem 2.25rem;
  font-size: 1.05rem;
}

.cta-final__tels {
  margin-top: 1.5rem;
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  justify-content: center;
  font-variation-settings: "wght" 600;
}

/* ---------- rodapé ---------- */
.rodape {
  background: var(--verde-fundo);
  border-top: 1px solid var(--verde-apoio);
  padding-block: clamp(3rem, 6vw, 4rem);
  padding-bottom: calc(clamp(3rem, 6vw, 4rem) + 80px);
}

.rodape__logo img {
  width: min(200px, 60vw);
  height: auto;
}

.rodape__grid {
  margin-top: 2rem;
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 640px) {
  .rodape__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.rodape p {
  font-size: .9rem;
  color: rgba(244, 242, 237, .8);
}

.rodape__base {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--verde-apoio);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.5rem;
  justify-content: space-between;
  font-size: .85rem;
  color: rgba(244, 242, 237, .7);
}

.rodape__base a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* rodada 3, item 6: crédito da Wefox Media vira logo (raposa laranja + texto
   branco, feita pra fundo escuro), sem underline por cima da imagem */
.rodape__credito {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.rodape__credito img {
  width: 120px;
  height: auto;
}

/* ---------- WhatsApp flutuante ---------- */
.whats-float {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #25D366;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
}

.whats-float svg {
  width: 28px;
  height: 28px;
}

/* dentro do hero o botão flutuante cai em cima do CTA principal; ele só entra
   depois que o hero sai da tela, que é quando passa a ser útil */
.whats-float.is-oculto {
  opacity: 0;
  transform: scale(.7);
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .whats-float {
    transition: opacity 220ms var(--ease), transform 220ms var(--ease);
  }
}

/* ---------- motion (reveal genérico) ---------- */
@media (prefers-reduced-motion: no-preference) {

  .hero__headline,
  .hero__ctas {
    opacity: 0;
    transform: translateY(16px);
  }

  .hero__content.is-ready h1 {
    opacity: 1;
    transform: translateY(0);
  }

  .hero__content.is-ready .hero__headline {
    opacity: 1;
    transform: translateY(0);
  }

  .hero__content.is-ready .hero__lead {
    animation: subir 600ms var(--ease) 90ms forwards;
  }

  .hero__content.is-ready .hero__ctas {
    animation: subir 600ms var(--ease) 180ms forwards;
  }

  .reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 550ms var(--ease), transform 550ms var(--ease);
  }

  .reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  .numeros__item {
    opacity: 0;
    transform: translateY(20px);
  }

  .numeros .numeros__grupo.is-visible .numeros__item {
    opacity: 1;
    transform: translateY(0);
  }

  /* rodada 3, item 7: reveal genérico com entrada lateral (estrutura__texto) */
  .reveal-x {
    opacity: 0;
    transform: translateX(-40px);
    transition: opacity 600ms var(--ease), transform 600ms var(--ease);
  }

  .reveal-x.is-visible {
    opacity: 1;
    transform: translateX(0);
  }

  /* rodada 3, item 7: a faixa amarela de números "cresce" em scaleY ao
     entrar, além do stagger que os itens já tinham */
  .reveal-scale {
    transform: scaleY(.92);
    transform-origin: center;
    transition: transform 700ms var(--ease);
  }

  .reveal-scale.is-visible {
    transform: scaleY(1);
  }

  /* rodada 3, item 7: stagger genérico de até 6 filhos diretos marcados com
     .reveal dentro de um pai .reveal-stagger — usado em "Joinville e
     região" (4 filhos), FAQ (6 itens) e CTA final (4 filhos) */
  .reveal-stagger > .reveal:nth-child(1) { transition-delay: 0ms; }
  .reveal-stagger > .reveal:nth-child(2) { transition-delay: 90ms; }
  .reveal-stagger > .reveal:nth-child(3) { transition-delay: 180ms; }
  .reveal-stagger > .reveal:nth-child(4) { transition-delay: 270ms; }
  .reveal-stagger > .reveal:nth-child(5) { transition-delay: 360ms; }
  .reveal-stagger > .reveal:nth-child(6) { transition-delay: 450ms; }

  /* rodada 3, item 5: fallback CSS puro do stagger dos passos (120ms) —
     roda sempre; quando o GSAP carrega, initHeroVideo/carregarMotion faz
     gsap.set() nos mesmos elementos e assume a partir dali, sincronizado
     com a linha (scrub). Sem JS pesado, fica este reveal simples. */
  .passos .passo:nth-child(1) { transition-delay: 0ms; }
  .passos .passo:nth-child(2) { transition-delay: 120ms; }
  .passos .passo:nth-child(3) { transition-delay: 240ms; }
}

@keyframes subir {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .produto__media img {
    transition: none;
  }

  /* sem vídeo: o frame B (picture em .hero__media) já é o que aparece por
     trás. Os três rótulos ficam visíveis de uma vez, sem depender do JS de
     scroll (que nem chega a rodar quando reduced-motion está ativo). Sem
     isto os três dividiriam a mesma posição absoluta e ficariam ilegíveis
     empilhados um sobre o outro: aqui eles viram uma lista empilhada em
     flex, ainda ancorada embaixo à direita. */
  .hero__video {
    display: none;
  }

  .hero__video-wrap {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: flex-end;
    gap: .85rem;
    padding: clamp(1.25rem, 6vw, 3rem);
  }

  .hero__label {
    position: static;
    opacity: 1;
    transition: none;
  }

  /* no mobile o bloco de texto ocupa a parte de baixo quase inteira (sem
     pin, em fluxo normal): a lista embaixo à direita colide com o CTA.
     Mesma solução do modo com scroll, ancora no topo do hero. */
  @media (max-width: 640px) {
    .hero__video-wrap {
      justify-content: flex-start;
      padding-top: clamp(4.5rem, 12vh, 6rem);
    }

    .hero__label {
      max-width: 11rem;
    }

    /* rodada 3, item 1 moveu o bloco de texto pro meio da tela (52%) - certo
       pro hero animado, mas aqui embaixo os 3 rótulos empilhados (sem scroll
       controlando qual aparece) ocupam o topo inteiro e colidiam direto com
       o h1 no meio. Sem JS de scroll rodando (reduced-motion nunca carrega
       o motion pesado), a posição "meio da tela" do item 1 não se aplica
       mesmo - aqui ancora embaixo, como era antes da rodada 3, deixando o
       topo inteiro livre pra lista de rótulos. */
    .hero > .container {
      top: auto;
      bottom: 0;
      transform: none;
      padding-bottom: clamp(1.5rem, 6vw, 2.5rem);
    }
  }
}

/* ---------- utilidades ---------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
