/* Camada 4: a home. So dela.
 *
 * Depende de `lv-tokens.css` (camada 1), `lv-base.css` (2) e `lv-botoes.css`
 * (3), nesta ordem de carga.
 *
 * SAIU DAQUI: a regra do `body`, que foi para `lv-base.css`, e os dois botoes,
 * que foram para `lv-botoes.css`. Nao eram da home; estavam aqui porque foi
 * aqui que fizeram falta primeiro.
 *
 * CADA SELETOR APARECE UMA VEZ. A versao anterior deste arquivo tinha crescido
 * por acrescimo: `.lv-hero` estava definido em tres lugares, `.lv-tipo h3` em
 * dois com tamanhos diferentes, e a media query do celular vinha ANTES da
 * regra que a vencia. Isso nao e estilo, e historico de edicao, e custou um
 * bug real: no celular o titulo da faixa de fechamento renderizava 44px em vez
 * de 28px, porque `@media` nao soma especificidade e a regra apendada no fim
 * do arquivo ganhava por ordem.
 *
 * A REGRA: media query vem DEPOIS da regra base que ela altera, no fim da sua
 * secao. Valor novo entra na regra que ja existe, nunca numa copia no rodape
 * do arquivo.
 *
 * OS `!important` DESTE ARQUIVO sao todos de `prefers-reduced-motion`, e todos
 * pelo mesmo motivo: desligar animacao exige vencer a regra que a ligou, que
 * tem a mesma especificidade e vem antes. Cada um esta comentado no lugar.
 */

/* ===== HERO ============================================================
   Os valores desta secao foram lidos do mockup com `getComputedStyle`, lado a
   lado com a pagina servida, e nao escolhidos a olho. */

.lv-hero {
  position: relative; overflow: hidden;
  padding: 56px 0 0;
}
/* Brilho quente do desenho. Fica ATRAS de tudo e nao intercepta clique.
   `max-width:120vw` impede que ele crie rolagem horizontal no celular. */
.lv-hero-brilho {
  position: absolute; top: -80px; right: -120px;
  width: 520px; height: 520px; max-width: 120vw;
  border-radius: 50%; pointer-events: none; z-index: 0;
  background: radial-gradient(circle at 30% 30%, #fdf2fb 0%, #fff7ed 60%, transparent 70%);
}
/* `align-items: end` e nao `center`: a foto e um recorte de corpo inteiro e
   assenta no piso da secao. Centralizada, ela flutua e o texto desce junto. */
.lv-hero-grid {
  position: relative; z-index: 1;
  max-width: var(--lv-largura); margin: 0 auto; padding: 0 32px;
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: end;
}
.lv-hero-chapeu {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--lv-font-display); font-weight: 800;
  font-size: 13px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--lv-accent); margin: 0 0 18px;
}
.lv-hero-titulo {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 62px;
  line-height: 1.08; letter-spacing: -.02em; color: var(--lv-ink); margin: 0 0 20px;
}
/* mock: rgb(220,140,219) = --lv-accent, familia Nunito. */
.lv-hero-sub {
  font-size: 27px; font-style: italic; font-weight: 700;
  font-family: var(--lv-font-display); color: var(--lv-accent);
  margin: 0 0 34px;
}

/* A COLUNA DA IMAGEM.
   O `padding` da o respiro que os cartoes flutuantes ocupam quando saem para
   fora da foto; sem ele o `overflow:hidden` da secao corta os dois. */
.lv-hero-imagem { position: relative; padding: 18px 22px 0; }
/* Recorte com alfa. O `drop-shadow` segue o contorno da pessoa; `box-shadow`
   desenharia a sombra do retangulo da imagem, inclusive do vazio em volta. */
.lv-hero-recorte {
  display: block; width: 100%; height: auto;
  /* SEM teto de altura. O teto de 560px vinha de quando o hero estava mais
     apertado; com a coluna na largura do desenho a foto assenta em 677px,
     que e a altura que ela tem la. */
  filter: drop-shadow(0 22px 26px rgba(0, 0, 0, .16));
  position: relative; z-index: 1;
}
/* PROVA SOCIAL. */
.lv-prova { display: flex; align-items: center; gap: 14px; margin: 30px 0 72px; }
.lv-prova-avatares { display: flex; }
.lv-prova-avatares picture { display: block; margin-left: -11px; width: 34px; height: 34px; }
.lv-prova-avatares picture:first-child { margin-left: 0; }
.lv-prova-avatares img {
  width: 34px; height: 34px; border-radius: 999px; object-fit: cover;
  border: 2.5px solid #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .12); display: block;
}
.lv-prova-texto { font-size: 14.5px; color: var(--lv-muted); }
.lv-prova-texto strong { color: var(--lv-ink); font-family: var(--lv-font-display); }

/* CARTOES FLUTUANTES. Ilustram o produto e nao sao dado: levam `aria-hidden`
   no HTML para o leitor de tela nao anunciar uma lista e um valor inexistentes. */
.lv-flutua {
  position: absolute; z-index: 3;
  background: #fff; border-radius: 15px; padding: 11px 14px;
  box-shadow: 0 16px 34px rgba(0, 0, 0, .16);
  display: flex; align-items: center; gap: 11px; white-space: nowrap;
}
.lv-flutua-icone {
  display: flex; align-items: center; justify-content: center;
  padding: 7px; border-radius: 999px; flex: 0 0 auto;
}
.lv-flutua-icone-ok       { background: #dcfce7; color: #16a34a; }
.lv-flutua-icone-presente { background: #ffedd5; color: #f4a261; }
.lv-flutua-texto { display: flex; flex-direction: column; line-height: 1.3; }
/* Caixa normal, e nao versal: no desenho isto e rotulo de interface, nao
   etiqueta. Em versal com 10,5px o cartao virava outra coisa. */
.lv-flutua em {
  font-style: normal; font-size: 12.5px; font-weight: 600; color: #6b7280;
}
.lv-flutua strong {
  font-family: var(--lv-font-display); font-weight: 700; font-size: 13.5px;
  color: var(--lv-ink);
}
.lv-flutua-1 { top: 6%;    left: -16px;  }
.lv-flutua-2 { bottom: 8%; right: -12px; }

/* ===== ENTRADA DO HERO: CSS puro, sem biblioteca ======================
   Nao entra GSAP aqui. Ele custa 44 KB comprimidos e ganha isso de volta
   quando ha sequencia com controle, animacao amarrada a rolagem ou
   interrupcao. Uma cascata de entrada com atraso nao e nada disso: e
   `animation-delay`, que o navegador ja tem.

   O ESTADO INICIAL NO CSS SO E SEGURO PORQUE A ANIMACAO VEM DO MESMO ARQUIVO.
   Com biblioteca externa, `opacity:0` no CSS deixa a pagina EM BRANCO se a CDN
   cair: sao dois destinos independentes e um pode falhar sozinho. Aqui, ou os
   dois carregam, ou a pagina inteira esta sem estilo e o problema e outro. */

@keyframes lvEntra {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes lvEntraImagem {
  from { opacity: 0; transform: scale(.965); }
  to   { opacity: 1; transform: none; }
}
@keyframes lvSobe { to { transform: none; } }
@keyframes lvFlutua {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-14px); }
  100% { transform: translateY(0); }
}

/* DEVAGAR DE PROPOSITO: 1,05s com `cubic-bezier(.16,1,.3,1)`, que desacelera
   forte no fim. Entrada rapida chama atencao para si; entrada lenta deixa a
   pessoa ler enquanto acontece. */
[data-anim="hero"] {
  opacity: 0;
  animation: lvEntra 1.05s cubic-bezier(.16, 1, .3, 1) forwards;
}
/* Os atrasos seguem a ORDEM DE LEITURA, e nao a ordem do markup: o chapeu
   abre, o titulo sobe palavra a palavra, e so quando a ultima palavra chega e
   que "Comece gratis" aparece. */
.lv-hero-chapeu  { animation-delay: .05s; }
.lv-hero-sub     { animation-delay: 1.05s; }
.lv-hero .lv-cta { animation-delay: 1.22s; }
.lv-prova        { animation-delay: 1.40s; }

/* REVELACAO POR MASCARA, PALAVRA A PALAVRA.
   Cada palavra fica num `.lv-p` com `overflow:hidden`, e o span de dentro
   comeca 105% abaixo: sobe de tras da propria borda, entao nada aparece do
   nada, tudo ENTRA. Por palavra, e nao por letra: por letra atrasa a leitura
   da promessa principal e vira efeito. */
.lv-p { display: inline-block; overflow: hidden; vertical-align: bottom; }
.lv-p > span {
  display: inline-block;
  transform: translateY(105%);
  animation: lvSobe 1s cubic-bezier(.16, 1, .3, 1) forwards;
}
/* Cascata de 60ms: rapida o bastante para a frase nao se desmontar, lenta o
   bastante para o olho seguir a leitura. */
.lv-p:nth-of-type(1)  > span { animation-delay: .18s; }
.lv-p:nth-of-type(2)  > span { animation-delay: .24s; }
.lv-p:nth-of-type(3)  > span { animation-delay: .30s; }
.lv-p:nth-of-type(4)  > span { animation-delay: .36s; }
.lv-p:nth-of-type(5)  > span { animation-delay: .42s; }
.lv-p:nth-of-type(6)  > span { animation-delay: .48s; }
.lv-p:nth-of-type(7)  > span { animation-delay: .54s; }
.lv-p:nth-of-type(8)  > span { animation-delay: .60s; }
.lv-p:nth-of-type(9)  > span { animation-delay: .66s; }
.lv-p:nth-of-type(10) > span { animation-delay: .72s; }

/* A imagem entra em ESCALA, nunca subindo: ela ja tem o balanco depois, e dois
   movimentos verticais no mesmo elemento ficam bambos. O balanco so comeca
   quando a entrada termina, senao um cancela o outro. */
.lv-hero-recorte {
  opacity: 0;
  animation: lvEntraImagem 1.4s cubic-bezier(.16, 1, .3, 1) .25s forwards,
             lvFlutua 6s ease-in-out 1.7s infinite;
}

/* Os dois cartoes tem duracao e atraso DIFERENTES de proposito: iguais, sobem
   e descem juntos e a tela inteira parece respirar. */
.lv-flutua-1 { animation: lvFlutua 5s ease-in-out  .5s infinite; }
.lv-flutua-2 { animation: lvFlutua 7s ease-in-out 1.0s infinite; }

/* QUEM PEDIU MENOS MOVIMENTO RECEBE ZERO MOVIMENTO. Nao e animacao mais curta:
   e nenhuma. Transtorno vestibular nao melhora com movimento rapido.
   A opacidade volta explicita porque o estado inicial e 0 -- sem isso,
   desligar a animacao esconderia o conteudo. */
@media (prefers-reduced-motion: reduce) {
  [data-anim="hero"],
  .lv-p > span,
  .lv-hero-recorte,
  .lv-flutua-1,
  .lv-flutua-2 {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

@media (max-width: 1023px) {
  .lv-hero-grid { grid-template-columns: 1fr; gap: 40px; }
  .lv-hero-titulo { font-size: 52px; }
  /* Os 72px de baixo servem ao DESKTOP: com `align-items: end`, eles empurram a
     coluna de texto ate o pe da foto. Em coluna unica nao alinham nada e viram
     72px de branco somados aos 40 do `gap` -- 125px entre a ultima linha de
     texto e a imagem. O desenho tem a mesma margem e o mesmo problema. */
  .lv-prova { margin-bottom: 0; }
}
@media (max-width: 767px) {
  .lv-hero-titulo { font-size: 38px; }
  .lv-hero-brilho { width: 420px; height: 420px; top: -60px; right: -100px; }
}
/* OS CARTOES FICAM NO CELULAR. Eu os escondia abaixo de 767px por achar que
   cobririam o rosto; medido no desenho a 390px, nao cobrem: um assenta no vazio
   acima do ombro e o outro sobre a calca. Era decisao minha, e nao do desenho. */

/* ===== SECOES: cabecalho compartilhado ================================= */

.lv-secao-interna { max-width: var(--lv-largura); margin: 0 auto; padding: 0 32px; }
.lv-secao-cabecalho { text-align: center; margin-bottom: var(--lv-titulo-gap); }
.lv-chapeu {
  display: inline-block; font-family: var(--lv-font-display); font-weight: 800;
  font-size: 13px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--lv-accent); margin-bottom: 14px;
}
.lv-titulo {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 42px;
  color: var(--lv-ink); margin: 0 0 16px; letter-spacing: -.02em;
}
.lv-linha { margin: 0 auto; max-width: 640px; font-size: 16.5px; line-height: 1.65; color: var(--lv-muted); }
/* DOIS GESTOS DE DESTAQUE, e nao um. O desenho usa gradiente em "fazer" e
   "recomenda" e cor CHAPADA em "comemoracao". Copiar o gradiente nos tres
   apagaria a distincao, e ela e proposital: o chapado abre a pagina, o
   gradiente marca as duas secoes que vendem. */
.lv-grad {
  background: var(--lv-gradient); -webkit-background-clip: text;
  background-clip: text; color: transparent;
}
.lv-realce { color: var(--lv-accent); }

@media (max-width: 639px) { .lv-titulo { font-size: 32px; } }

/* ===== TIPOS DE LISTA =================================================== */

.lv-tipos { padding: var(--lv-secao) 0; background: var(--lv-bg); }
/* 1080px e nao a largura cheia da secao: com 1280 os cards saem com 412px, a
   foto cresce junto e a grade deixa de ler como um conjunto. Valor do desenho. */
.lv-tipos-grade {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px;
  max-width: 1080px; margin: 0 auto;
}
.lv-tipo {
  /* `color: inherit` porque o card virou `<a>`: sem isto o reset do Bootstrap
     pinta o cartao inteiro do azul de link, e so o `h3` e o `p` escapam por
     terem cor propria. */
  display: block; overflow: hidden; text-decoration: none; color: inherit;
  background: var(--lv-surface); border: 1px solid var(--lv-line);
  border-radius: 22px;
  transition: transform .3s ease, box-shadow .3s ease;
}
.lv-tipo:hover { transform: translateY(-4px); box-shadow: 0 18px 38px rgba(26, 26, 46, .12); }
/* ALTURA FIXA, e nao `aspect-ratio`. Com proporcao a foto acompanha a largura
   da coluna e o card fica mais alto a cada quebra de grade; com 172px o bloco
   de texto sempre comeca no mesmo lugar nos tres cards da fileira. */
.lv-tipo-foto { display: block; height: 172px; overflow: hidden; background: #f1f2f6; }
.lv-tipo-foto img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease; }
.lv-tipo:hover .lv-tipo-foto img { transform: scale(1.05); }
/* O FRISO E `border-top` DO TEXTO, e nao uma barra no alto do card. No desenho
   a linha colorida fica ENTRE a foto e o texto, e cada tipo tem a sua cor -- a
   cor vem do `style` no HTML, que e onde ela e dado. */
.lv-tipo-texto { display: block; padding: 22px 26px 28px; border-top: 4px solid var(--lv-line); }
/* mock: 19px, peso 800. */
.lv-tipo h3 {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 19px;
  color: var(--lv-ink); margin: 0 0 8px; line-height: 1.3;
}
.lv-tipo p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--lv-muted); }

@media (max-width: 1023px) { .lv-tipos-grade { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 639px)  { .lv-tipos-grade { grid-template-columns: 1fr; } }

/* ===== COMO FUNCIONA ==================================================== */

.lv-passos { padding: var(--lv-secao) 0; }
/* `max-width: 1040px` e nao a largura cheia da secao: com 1280 as tres colunas
   ficam largas demais e cada frase cabe numa linha so, o que desmancha o
   agrupamento visual dos passos. Valor do desenho. */
.lv-passos-grade {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px;
  max-width: 1040px; margin: 0 auto;
  list-style: none; padding: 0;
}
.lv-passo { text-align: center; }
.lv-passo-circulo {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 70px; height: 70px; margin: 0 auto 20px; border-radius: 999px;
  background: var(--lv-gradient);
  /* A sombra na cor do gradiente, e nao cinza: e o que descola o circulo do
     fundo branco sem parecer um elemento de outro material. */
  box-shadow: 0 10px 24px rgba(220, 140, 219, .32);
  /* O icone e branco sobre o gradiente. Sem isto o circulo fica sendo uma bolha
     colorida com um numero pendurado.

     A COR VEM DO CIRCULO, e nao do proprio icone: o Lucide APAGA o `<i>` e poe
     um `<svg>` no lugar, entao regra escrita em `i` deixa de casar assim que o
     script roda -- o icone saia escuro e a regra parecia certa. O `<svg>` usa
     `currentColor` e herda daqui. O `b` do selo desfaz a heranca logo abaixo. */
  color: #fff;
}
.lv-passo-circulo svg,
.lv-passo-circulo i { width: 28px; height: 28px; }
/* O numero fica num SELO LARANJA com borda branca, e nao num selo branco: sobre
   o gradiente rosa, branco com branco desaparece na quina. `--lv-laranja` e a
   terceira cor da marca, a mesma ponta do gradiente.

   O DIGITO E ESCURO, e no desenho e branco. Branco sobre este laranja da
   2,06:1, e o piso da WCAG para 13px em negrito e 4,5:1 -- o numero seria
   decorativo se nao fosse justamente ele que diz a ordem dos passos.
   `--lv-ink` sobre o mesmo laranja da 8,27:1, e o selo continua sendo o ponto
   laranja do desenho. */
.lv-passo-circulo b {
  position: absolute; top: -9px; right: -9px;
  /* 31px e nao 27px: o desenho roda em `content-box`, onde os 27px sao o
     conteudo e os 2px de borda somam por fora. Aqui vale `border-box`, entao o
     total e que precisa ser 31. */
  width: 31px; height: 31px; border-radius: 999px;
  background: var(--lv-laranja); color: var(--lv-ink);
  border: 2px solid #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--lv-font-display); font-weight: 800; font-size: 13px;
}
/* mock: 21px, peso 800. */
.lv-passo h3 {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 21px;
  color: var(--lv-ink); margin: 0 0 10px;
}
.lv-passo p { margin: 0; font-size: 15px; line-height: 1.65; color: var(--lv-muted); }

@media (max-width: 1023px) { .lv-passos-grade { grid-template-columns: 1fr; gap: 32px; } }

/* ===== O QUE VOCE PODE FAZER: carrossel por plano ====================== */

.lv-recursos { padding: var(--lv-secao) 0; background: var(--lv-bg); }
/* O mockup tem letter-spacing DIFERENTE em cada titulo: -.02em em tres deles e
   `normal` neste. Nao e sistema, e variacao de quem desenhou. Espelhado como
   esta la; se um dia virar regra, o lugar e o `lv-tokens.css`. */
.lv-recursos .lv-titulo { letter-spacing: normal; }

.lv-planos-abas { display: flex; justify-content: center; gap: 8px; margin-bottom: 24px; flex-wrap: wrap; }
/* AS ABAS SAO BOTOES DE VERDADE, e nao rotulo da animacao.
   Antes eram `<span aria-hidden="true">`: mostravam qual plano estava passando
   e nao davam como escolher. Quem quisesse ver o Premium tinha de esperar a
   volta -- 14 segundos, no pior caso. */
.lv-plano-aba {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 13.5px;
  padding: 8px 20px; border-radius: 999px; color: #6b7280;
  background: transparent; border: 1px solid var(--lv-line);
  cursor: pointer; -webkit-appearance: none; appearance: none;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.lv-plano-aba:hover { border-color: #eccfe9; color: #4a3050; }
/* Contorno visivel no teclado. `:focus-visible` e nao `:focus`: o anel no
   clique do mouse e ruido, o anel no Tab e a unica pista de onde se esta. */
.lv-plano-aba:focus-visible {
  outline: 2px solid var(--lv-accent-strong); outline-offset: 2px;
}

/* ESCOLHIDO NA MAO. A partir do primeiro clique a vitrine para de girar e o
   estado passa a vir do `aria-selected`, que e o mesmo atributo que o leitor de
   tela anuncia -- uma fonte da verdade, nao duas. */
.lv-recursos.is-manual .lv-planos-trilho,
.lv-recursos.is-manual .lv-plano-aba { animation: none; }
.lv-recursos.is-manual .lv-planos-trilho {
  transition: transform .45s cubic-bezier(.16, 1, .3, 1);
  /* `flex-start` solta os paineis do esticamento. Enquanto giram sozinhos
     eles ficam todos com a altura do mais alto, que e o certo para um
     carrossel; no modo manual cada um volta a ter a altura do proprio
     conteudo, que e o que o JavaScript mede para dimensionar a janela.
     Sem isto, `scrollHeight` devolvia a altura ESTICADA e o Basic
     continuava com 362px de nada embaixo. */
  align-items: flex-start;
}
/* A altura vem do JavaScript, medida no painel escolhido; aqui so a
   transicao, para a moldura nao saltar de tamanho no clique. */
.lv-recursos.is-manual .lv-planos-janela { transition: height .45s cubic-bezier(.16, 1, .3, 1); }
.lv-plano-aba[aria-selected="true"] {
  background: #f7e9f6; color: #4a3050; border-color: #eccfe9;
}

.lv-planos-janela { overflow: hidden; }
.lv-planos-trilho { display: flex; width: 300%; animation: lvGiraPlano 21s infinite; }

/* `border-box` NAO E DETALHE: com `content-box` o padding soma a largura, o
   painel fica maior que o passo da animacao, e o desencontro acumula ate o
   ultimo card sair pela janela e ser cortado pelo `overflow:hidden`. */
.lv-plano-painel {
  width: 33.3333%; flex: 0 0 33.3333%; box-sizing: border-box;
  padding: 0 2px 6px; display: flex; flex-direction: column;
  /* `flex-start` e NAO `center`. Os tres paineis ficam com a altura do mais
     alto, que e o Premium com dezesseis cartoes; centralizado, o Basic com sete
     descia para o meio dessa altura e abria um vao enorme entre as abas e o
     primeiro cartao. Cada painel comeca no topo, e a sobra fica embaixo, onde
     ninguem repara. */
  justify-content: flex-start;
}
.lv-plano-linha { text-align: center; margin: 0 0 22px; font-size: 15px; color: #5b5f6b; }
/* SEM `align-items: start`. Com ele cada cartao ficava com a altura do proprio
   texto, e como as descricoes tem de uma a quatro linhas a fileira saia
   desalinhada -- "Listas ilimitadas" com metade da altura de "Convite digital
   personalizado", ao lado. `stretch` e o padrao do grid: todos os cartoes da
   fileira ficam com a altura do mais alto dela. */
.lv-plano-grade { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }

.lv-recurso {
  background: var(--lv-surface); border: 1px solid var(--lv-line);
  border-radius: 18px; padding: 22px 20px;
  /* `flex` para o cartao PREENCHER a altura que o grid lhe deu: sem isto ele
     fica com a altura do texto e sobra fundo vazio dentro da celula. */
  display: flex; flex-direction: column;
}
.lv-recurso-icone {
  width: 40px; height: 40px; border-radius: 12px; margin-bottom: 13px;
  display: flex; align-items: center; justify-content: center;
}
/* `svg` e nao `i`: o Lucide por script virou SVG embutido, e a regra escrita
   em `i` deixou de casar com qualquer coisa. */
.lv-recurso-icone svg { width: 19px; height: 19px; }
.lv-recurso h3 {
  font-family: var(--lv-font-display); font-weight: 700; font-size: 15px;
  color: var(--lv-ink); margin: 0 0 6px; line-height: 1.35;
}
/* mock: 15px, e nao os 13px que eu tinha posto. */
.lv-recurso p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--lv-muted); }
/* A limitacao e um cartao como os outros: icone, titulo e descricao. So o que
   ela DIZ e diferente, entao so a cor muda. Ela chegou a ficar com
   `align-self: start` enquanto era um rotulo solto de tres palavras; com a
   descricao vinda do catalogo isso deixou de fazer sentido. */
.lv-recurso-limite { background: #fffdf7; border-color: #f2e2b5; }
.lv-recurso-limite h3 { color: #8a6d1c; }
.lv-selo {
  display: inline-block; margin-left: 6px; background: #e91e8c; color: #fff;
  font-size: 10px; font-weight: 800; padding: 2px 7px; border-radius: 20px;
  letter-spacing: .4px; vertical-align: middle;
}

/* Tres paradas de 7 segundos. */
@keyframes lvGiraPlano {
  0%,    31.0% { transform: translateX(0); }
  33.9%, 64.9% { transform: translateX(-33.3333%); }
  67.8%, 98.8% { transform: translateX(-66.6666%); }
  100%         { transform: translateX(0); }
}
.lv-plano-aba-1 { animation: lvAba1 21s infinite; }
.lv-plano-aba-2 { animation: lvAba2 21s infinite; }
.lv-plano-aba-3 { animation: lvAba3 21s infinite; }
/* #4a3050 sobre #f7e9f6 da 8,9:1. Rosa claro com cinza claro seria bonito e
   ilegivel. */
@keyframes lvAba1 {
  0%,32.0%   { background: #f7e9f6; color: #4a3050; border-color: #eccfe9; }
  33.0%,100% { background: transparent; color: #6b7280; border-color: var(--lv-line); }
}
@keyframes lvAba2 {
  0%,32.9%    { background: transparent; color: #6b7280; border-color: var(--lv-line); }
  33.9%,65.9% { background: #f7e9f6; color: #4a3050; border-color: #eccfe9; }
  66.9%,100%  { background: transparent; color: #6b7280; border-color: var(--lv-line); }
}
@keyframes lvAba3 {
  0%,66.8%    { background: transparent; color: #6b7280; border-color: var(--lv-line); }
  67.8%,99.8% { background: #f7e9f6; color: #4a3050; border-color: #eccfe9; }
  100%        { background: transparent; color: #6b7280; border-color: var(--lv-line); }
}

/* PARAR SEM JAVASCRIPT. Conteudo que troca sozinho sem como parar e falha de
   acessibilidade (WCAG 2.2.2): quem le devagar perde o card no meio da frase.

   SO `:hover`. Havia um `:focus-within` ao lado, e ele nunca disparava: medido
   na pagina renderizada, nenhum dos tres paineis tem UM elemento focavel
   dentro (sao `h3`, `p` e `span`), e o catalogo tambem nao traz `<a>` nem
   `<button>` -- as duas evidencias que a regra de remocao exige. Quem chega
   por teclado para o giro de outro jeito: o `home-planos.js` para no `focusin`
   das abas, que ficam FORA desta janela. */
.lv-planos-janela:hover .lv-planos-trilho { animation-play-state: paused; }

@media (max-width: 1023px) { .lv-plano-grade { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 639px)  { .lv-plano-grade { grid-template-columns: 1fr; } }

/* MENOS MOVIMENTO: os tres EMPILHADOS, nada escondido. Parar no primeiro
   mostraria um terco do conteudo justamente a quem pediu menos movimento. */
@media (prefers-reduced-motion: reduce) {
  /* Com os tres paineis empilhados e visiveis, a lista de abas nao controla
     mais nada: sai, em vez de virar botao que nao faz diferenca nenhuma. */
  .lv-planos-abas { display: none; }
  .lv-planos-trilho { animation: none; width: 100%; flex-direction: column; gap: 40px; }
  /* O `transform` inline vem do JavaScript, ao escolher uma aba. Inline vence
     seletor de classe, entao aqui so o `!important` alcanca -- e sem ele o
     painel escolhido continuaria deslocado depois de os tres virarem pilha. */
  .lv-recursos.is-manual .lv-planos-trilho { transform: none !important; transition: none; }
  .lv-plano-painel  { width: 100%; flex: 1 1 auto; }
  /* Vence as tres animacoes de aba acima, que tem a mesma especificidade e vem
     antes: sem ele a aba continua piscando justamente para quem pediu menos
     movimento. */
  .lv-plano-aba     { animation: none !important; }
  .lv-plano-painel::before {
    content: attr(data-plano); display: block; text-align: center;
    text-transform: uppercase; font-family: var(--lv-font-display);
    font-weight: 800; font-size: 12px; letter-spacing: .1em;
    color: var(--lv-accent-strong); margin-bottom: 10px;
  }
}

/* ===== FAIXA DE FECHAMENTO ============================================= */

.lv-fechamento { padding: var(--lv-secao) 0; background: var(--lv-surface); }
/* PAINEL CLARO, e nao escuro. `--lv-ink` de fundo passa folgado no contraste,
   mas um retangulo escuro da largura da pagina nao pesa o mesmo que um cartao
   escuro dentro de um trio: le como corpo estranho. O peso vai para o botao. */
.lv-fechamento-painel {
  position: relative; overflow: hidden; border-radius: 26px;
  background: var(--lv-accent-soft); border: 1px solid #f5dcf1;
  text-align: center; padding: 62px 40px 58px;
}
.lv-fechamento-friso {
  position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: var(--lv-gradient);
}
/* mock: 44px e -.5px, e nao os 42px e -.02em dos outros titulos. */
.lv-fechamento-painel h2 {
  font-family: var(--lv-font-display); font-weight: 800; font-size: 44px;
  color: var(--lv-ink); margin: 0 0 16px; line-height: 1.16; letter-spacing: -.5px;
}
.lv-fechamento-painel p {
  font-size: 17px; color: var(--lv-muted); margin: 0 auto 34px;
  max-width: 520px; line-height: 1.6;
}
/* DOIS BRILHOS MUITO FRACOS, um em cada canto oposto. Dao volume ao painel sem
   sujar o fundo onde o texto se apoia: em fundo claro qualquer coisa mais forte
   come o contraste que a cor do texto acabou de garantir. `pointer-events:none`
   porque eles cobrem o botao. */
.lv-fechamento-painel::before,
.lv-fechamento-painel::after {
  content: ""; position: absolute; pointer-events: none; z-index: 0;
}
.lv-fechamento-painel::before {
  top: -190px; left: -140px; width: 520px; height: 520px;
  background: radial-gradient(circle, rgba(244, 162, 97, .16) 0%, rgba(244, 162, 97, 0) 70%);
}
.lv-fechamento-painel::after {
  bottom: -210px; right: -130px; width: 560px; height: 560px;
  background: radial-gradient(circle, rgba(181, 103, 199, .15) 0%, rgba(181, 103, 199, 0) 70%);
}
/* O conteudo sobe acima dos brilhos. Sem isto o botao fica atras deles e, com
   `pointer-events:none`, clicavel mas visualmente lavado. */
.lv-fechamento-painel > *:not(.lv-fechamento-friso) { position: relative; z-index: 1; }

/* DEPOIS da regra base, e nao antes. Enquanto este bloco vinha primeiro, o
   `font-size: 44px` apendado no fim do arquivo vencia por ordem e o titulo
   saia com 44px tambem no celular. */
@media (max-width: 639px) {
  .lv-fechamento-painel { padding: 44px 22px 40px; }
  .lv-fechamento-painel h2 { font-size: 28px; }
}

/* ===== DEPOIMENTOS ===================================================== */

.lv-depo { padding: var(--lv-secao) 0; background: var(--lv-bg); }
.lv-depo-janela { overflow: hidden; max-width: 1120px; margin: 0 auto; }
.lv-depo-trilho { display: flex; width: 266.6667%; animation: lvGiraDepo 30s infinite; }

/* O respiro vem de `padding` e NAO de `gap`: `gap` entraria na conta das
   porcentagens e o passo de -12,5% deixaria de bater com a largura do card. */
.lv-depo-slot {
  flex: 0 0 12.5%; box-sizing: border-box; padding: 6px 11px 10px;
  display: flex; flex-direction: column;
}
/* `flex:1` e NAO `height:100%`: altura em porcentagem dentro de item de flex
   esticado resolve contra a altura de ANTES da esticada, o card fica mais alto
   que a janela, e o `overflow:hidden` corta na vertical. */
.lv-depo-card {
  background: var(--lv-surface); border: 1px solid var(--lv-line);
  border-radius: 22px; padding: 30px; margin: 0;
  flex: 1; display: flex; flex-direction: column;
}
.lv-depo-card p { margin: 0 0 22px; font-size: 15px; line-height: 1.7; color: var(--lv-ink); flex: 1; }
.lv-depo-card footer { display: flex; align-items: center; gap: 12px; }
.lv-depo-inicial {
  width: 44px; height: 44px; border-radius: 999px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--lv-font-display); font-weight: 800; font-size: 14px; color: var(--lv-ink);
}
.lv-depo-card strong {
  display: block; font-family: var(--lv-font-display); font-weight: 700;
  color: var(--lv-ink); font-size: 14.5px;
}
.lv-depo-card em {
  display: block; font-style: normal; font-size: 12.5px; color: #6b7280;
  text-transform: uppercase; letter-spacing: .05em; font-weight: 600;
}

/* Seis paradas. A sexta mostra as copias e e identica a primeira, entao o salto
   de volta a translateX(0) nao tem nada para ser visto. */
@keyframes lvGiraDepo {
  0%,    15.0% { transform: translateX(0); }
  16.6%, 31.6% { transform: translateX(-12.5%); }
  33.3%, 48.3% { transform: translateX(-25%); }
  50.0%, 65.0% { transform: translateX(-37.5%); }
  66.6%, 81.6% { transform: translateX(-50%); }
  83.3%, 100%  { transform: translateX(-62.5%); }
}
/* O CONTROLE DE PAUSA. A caixa de marcar fica escondida da vista mas continua
   focavel pelo teclado -- `display:none` a tiraria da ordem de tabulacao, e
   quem navega por teclado perderia justamente o controle que isto veio dar. */
.lv-depo-check {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.lv-depo-botao {
  display: block; width: max-content; margin: 0 auto 18px; cursor: pointer;
  font-family: var(--lv-font-display); font-weight: 700; font-size: 13px;
  color: var(--lv-muted); background: var(--lv-surface);
  border: 1px solid var(--lv-line); border-radius: 999px; padding: 7px 18px;
  transition: border-color .2s ease, color .2s ease;
}
.lv-depo-botao:hover { border-color: var(--lv-accent); color: var(--lv-ink); }
/* O anel de foco vai no rotulo, porque a caixa em si esta fora da tela. */
.lv-depo-check:focus-visible + .lv-depo-botao {
  outline: 2px solid var(--lv-accent-strong); outline-offset: 2px;
}
.lv-depo-retomar { display: none; }
.lv-depo-check:checked + .lv-depo-botao .lv-depo-pausar  { display: none; }
.lv-depo-check:checked + .lv-depo-botao .lv-depo-retomar { display: inline; }
.lv-depo-check:checked ~ .lv-depo-janela .lv-depo-trilho { animation-play-state: paused; }

/* `:focus-within` saiu daqui pelo mesmo motivo do carrossel de planos: nao ha
   nada focavel dentro desta janela, medido no navegador e conferido no fonte.
   E o comentario da caixa de marcar logo acima ja dizia isso -- a caixa existe
   PORQUE nao ha foco aqui. A regra foi copiada por engano. */
.lv-depo-janela:hover .lv-depo-trilho { animation-play-state: paused; }

/* Um card por vez no celular. So a largura do trilho muda: o passo continua
   -12,5%, porque o slot continua sendo 1 de 8. */
@media (max-width: 639px) { .lv-depo-trilho { width: 800%; } }

@media (prefers-reduced-motion: reduce) {
  /* Sem animacao nao ha o que pausar, entao o controle inteiro sai -- INCLUSIVE
     A CAIXA DE MARCAR, e nao so o rotulo. Ela e apenas RECORTADA da vista pela
     regra base, para continuar alcancavel pelo teclado; escondendo so o rotulo,
     o Tab parava num controle invisivel, sem efeito, e com o anel de foco preso
     a um elemento em `display:none`. */
  .lv-depo-botao,
  .lv-depo-check { display: none; }
  .lv-depo-trilho { animation: none; width: 100%; flex-wrap: wrap; justify-content: center; }
  .lv-depo-slot { flex: 0 0 33.3333%; }
  .lv-depo-slot[aria-hidden="true"] { display: none; }
}
/* DEPOIS do bloco acima, senao ele vence por ordem.
   Com menos movimento os depoimentos viram grade estatica de tres colunas -- o
   que em 390px da 161px de largura por 376px de altura por cartao, texto
   espremido numa coluna alta. Abaixo de 640px cada um ocupa a fileira inteira,
   que e o que o carrossel ja fazia com um cartao por vez. */
@media (prefers-reduced-motion: reduce) and (max-width: 639px) {
  .lv-depo-slot { flex: 0 0 100%; }
}


/* ===== O BANNER DE COOKIE E O CTA DO HERO ==============================
 *
 * `mobile-nav.css:139` levanta o banner 64px em toda tela abaixo de 991px,
 * para dar espaco a `.mobile-tab-bar`. A home publica NAO tem essa barra --
 * o proprio arquivo ja trata disso duas regras acima, para o `padding-bottom`
 * --, e a folga empurrava o banner para cima do hero.
 *
 * Medido a 360x640, que e a linha Galaxy A/S: banner em y 410-576, "Comece a
 * sua lista agora!" em 422-480, dentro. `elementFromPoint` no centro do botao
 * devolvia o banner. A pessoa tocava no maior pedido da pagina e nada
 * acontecia: nem abria o wizard, nem aceitava cookie. A 375x667 -- iPhone
 * SE/8 -- cobria 75%.
 *
 * AQUI, E NAO NO `mobile-nav.css`. A primeira tentativa foi la, e foi pior:
 * aquela folha e carregada por 27 paginas, e baixar o banner desbloqueou a
 * home e passou a COBRIR o CTA das sete landings de anuncio, que estavam
 * livres a 360x640. Trocar o problema de pagina, e ainda por cima para as
 * paginas que recebem o trafego pago, nao e conserto. `lv-home.css` e
 * carregado so pelo `index.php`.
 *
 * `!important` empata com o do `mobile-nav.css`, que usa a mesma propriedade.
 * Quem desempata e o `body ` na frente do seletor -- 0,1,1 contra 0,1,0 --, e
 * NAO a ordem de carga: o `mobile-nav.css` entra pelo `menu_parcial.php`,
 * dentro do `<body>`, ou seja DEPOIS desta folha, que esta no `<head>`. Tirar o
 * `body` achando que e redundante devolve o defeito. O `z-index` de la nao e
 * tocado.
 *
 * O CTA das landings continua coberto a 375x667 -- defeito anterior a esta
 * entrega, registrado no TAREFAS.md. */
@media (max-width: 991px) {
  body .cc-window { bottom: env(safe-area-inset-bottom, 0px) !important; }
}


/* ===== TELA CURTA E ESTREITA: o hero cabe acima do banner ===============
 *
 * A 320x568 -- a menor tela ainda em uso -- o banner de cookie ocupa 190px dos
 * 568, e o CTA do hero caia em y 461-518, com o topo do banner em 378: coberto
 * inteiro, incluindo o centro. O toque ia para o banner e o wizard nao abria.
 *
 * NAO DA PARA CONSERTAR PELO BANNER. Para o CTA ficar livre, o banner teria de
 * caber em 51px, e so os dois botoes dele ja tem 40 mais o texto. O que sobra e
 * o hero subir os 148px que faltam, e ele tem de onde: 38px de titulo numa tela
 * de 320 de largura ja era grande demais para o proprio desenho.
 *
 * A CONDICAO E A ALTURA, e nao a largura. A primeira versao pedia
 * `max-width: 360px` junto, e com isso so alcancava celular estreito. Zoom de
 * 200% num desktop -- que e o requisito da WCAG 1.4.4, nao um caso exotico --
 * da 640 a 720px CSS de largura com 384 a 512 de altura: fora da faixa, e o
 * banner voltava a cobrir o "Comece a sua lista agora!". Medido em 1280x1024,
 * 1366x768 e 1440x900, e nas tres o `elementFromPoint` no centro do botao
 * devolvia o banner.
 *
 * Quem tem tela alta nao e alcancado, seja qual for a largura, e nao ha razao
 * para encolher o hero dessa pessoa. Medido depois: CTA livre, nada abaixo de
 * 44px, sem rolagem lateral. */
@media (max-height: 620px) {
  .lv-hero        { padding-top: 20px; }
  .lv-hero-titulo { font-size: 27px; margin-bottom: 12px; }
  .lv-hero-sub    { font-size: 19px; margin-bottom: 16px; }
}
