/* ==========================================================================
   JL Certificado Digital — landing page
   landing.css — apenas o que é específico desta página.

   Depende de design-system/tokens.css e design-system/components.css, nesta
   ordem. Nenhum hex, nenhum px de fonte e nenhuma sombra literal aqui: só
   var(--semantic-*). Prefixo .lp- para tudo que não pertence ao sistema.
   ========================================================================== */

/* --------------------------------------------------------------------------
   CENA — palco institucional
   O herói e o fechamento vivem sobre marinho pleno. Dentro de .lp-stage os
   tokens semânticos são reapontados uma única vez, e daí para baixo todo
   componente do sistema já nasce na versão invertida sem saber disso.

   O cabeçalho recebe o MESMO bloco de tokens, embora viva fora de .lp-stage
   (ver comentário no index.html sobre por que o sticky precisou sair do
   palco). Ele é uma barra de vidro escura persistente — precisa manter essa
   aparência sobre qualquer seção clara por trás dela, não só sobre o herói.
   -------------------------------------------------------------------------- */
.lp-stage {
  position: relative;
  isolation: isolate;
  overflow: clip;
  background: var(--jl-navy-900);
}

.lp-header,
.lp-stage {
  --surface-page: var(--jl-navy-900);
  --surface-card: rgba(255, 255, 255, 0.045);
  --surface-sunk: rgba(0, 0, 0, 0.2);
  --surface-silver: rgba(218, 218, 218, 0.12);
  --surface-brand-soft: rgba(218, 218, 218, 0.1);
  --surface-brand: var(--jl-silver-200);
  --text-primary: var(--jl-white);
  --text-secondary: rgba(218, 218, 218, 0.76);
  --text-tertiary: rgba(218, 218, 218, 0.54);
  --text-brand: var(--jl-silver-200);
  --text-on-brand: var(--jl-navy-800);
  --text-link: var(--jl-navy-200);
  --border-subtle: rgba(218, 218, 218, 0.14);
  --border-default: rgba(218, 218, 218, 0.24);
  --border-strong: rgba(218, 218, 218, 0.4);
  --border-brand: var(--jl-silver-200);
  --action-primary: var(--jl-silver-200);
  --action-primary-hover: var(--jl-white);
  --action-primary-text: var(--jl-navy-800);
  --action-secondary: rgba(218, 218, 218, 0.1);
  --action-secondary-hover: rgba(218, 218, 218, 0.18);
  --action-secondary-text: var(--jl-white);
  --focus-ring-color: var(--jl-silver-200);
  --logo-ink: var(--jl-silver-200);
}

/* O palco (e o cabeçalho, que se alinha a ele) é a única área da página que
   quebra a grade de 1120px. As seções de conteúdo (planos, FAQ) ficam na
   largura padrão de leitura; o herói e o fechamento são cena, não texto
   corrido, e usam a tela inteira melhor com mais respiro lateral. Sem isso,
   em telas largas a coluna do título fica estreita à toa e o título quebra
   em linhas demais. O cabeçalho precisa do mesmo valor, senão logo e nav
   ficam desalinhados com o título mais largo do herói logo abaixo. */
.lp-header .jl-container,
.lp-stage .jl-container {
  max-width: 1360px;
}

/* Guilhoché: a gravura do papel de segurança. Desenhada uma vez em canvas e
   girada por CSS — mais barato que redesenhar quadro a quadro. */
.lp-stage__guilloche {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(160vw, 1500px);
  aspect-ratio: 1;
  translate: -50% -50%;
  z-index: -2;
  opacity: 0.5;
  pointer-events: none;
  mask-image: radial-gradient(circle at center, #000 22%, transparent 68%);
  animation: lp-rotate 220s linear infinite;
}

@keyframes lp-rotate { to { rotate: 360deg; } }

/* Luz rasante de cima, e um assoalho mais escuro para dar profundidade. */
.lp-stage__light {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(80% 60% at 68% -10%, rgba(184, 188, 245, 0.16), transparent 60%),
    radial-gradient(50% 40% at 10% 0%, rgba(218, 218, 218, 0.07), transparent 70%),
    linear-gradient(to bottom, transparent 55%, rgba(0, 0, 0, 0.45));
}

/* Fio prateado que fecha a cena. */
.lp-stage__edge {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    rgba(218, 218, 218, 0.45) 30%,
    rgba(218, 218, 218, 0.45) 70%,
    transparent
  );
}

/* --------------------------------------------------------------------------
   LIGAÇÃO ENTRE SEÇÕES — fio condutor

   Referência (cogni.aura.build): lá, um shader WebGL único ocupa a página
   inteira atrás de TODAS as seções, que nunca têm fundo próprio — por isso a
   rolagem nunca corta bruscamente, é sempre o mesmo fundo passando atrás de
   blocos transparentes. Aqui não dá pra copiar a técnica ao pé da letra: a
   leitura desta página é cinematográfica por CONTRASTE de fundo opaco
   (marinho no herói, branco no preço, marinho no fechamento — ver .lp-stage
   acima) e um fundo único atrás de tudo apagaria exatamente esse ritmo, além
   de nunca aparecer de verdade atrás de uma seção 100% opaca.

   A adaptação troca "um fundo só" por "uma costura visível em cada emenda",
   e essa costura foi redesenhada para puxar pro registro de tecnologia e
   criptografia que é o produto de verdade da JL — não decoração emprestada:
   1. uma golfada de luz marinho muito fraca entrando pelo topo da seção —
      mesma família de gradiente radial de .lp-stage__light, só que fraca o
      bastante (5-8%) para não sujar texto de corpo sobre branco;
   2. um NÓ hexagonal pulsando bem em cima do ponto de emenda — o desenho de
      um pad de circuito impresso, não um círculo genérico. O A3 desta marca
      é fisicamente um chip; o nó cita esse objeto real, não inventa um.
   3. duas trilhas tracejadas curtas, uma de cada lado do nó, "escoando" na
      direção dele — o mesmo gesto do fio de luz que abre cada seção no
      template de referência (`w-px h-16 bg-gradient-to-b`), só que como uma
      trilha de PCB animada em vez de um traço parado, e em prata da marca,
      não magenta.

   O mesmo nó, na mesma posição, com a mesma cadência de pulso, se repete em
   toda emenda da página — é essa repetição idêntica que lê como "uma cadeia
   só" percorrendo a rolagem inteira, não um efeito individual por seção.

   Escopo deliberado: a golfada cobre uma faixa de ~220px, mas o nó e as
   trilhas ficam contidos a 40px de cada lado da emenda — bem dentro do
   menor respiro possível no topo de uma seção (--jl-section-y não desce de
   56px). O miolo de leitura de cada seção continua limpo: nenhum parágrafo
   nasce sobre gradiente, nenhum título é cruzado por trilha.
   -------------------------------------------------------------------------- */
.lp-linked {
  position: relative;
  isolation: isolate;
  background-image: radial-gradient(60% 220px at 50% 0%, rgba(11, 15, 74, 0.05), transparent 72%);
  background-repeat: no-repeat;
  background-position: top center;
}

.lp-linked::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 1;
  width: 11px;
  height: 11px;
  translate: -50% -50%;
  background: var(--jl-navy-700);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  box-shadow: 0 0 0 0 rgba(11, 15, 74, 0.35);
  animation: lp-node-ping 2.6s var(--jl-ease-inout) infinite;
  pointer-events: none;
}

.lp-linked::after {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 1px;
  height: 80px;
  translate: -50% -40px;
  background-image: repeating-linear-gradient(
    to bottom,
    var(--jl-silver-400) 0,
    var(--jl-silver-400) 4px,
    transparent 4px,
    transparent 10px
  );
  background-size: 1px 20px;
  opacity: 0.6;
  animation: lp-trace-flow 900ms linear infinite;
  pointer-events: none;
}

@keyframes lp-node-ping {
  0%, 100% { box-shadow: 0 0 0 0 rgba(11, 15, 74, 0.35); }
  60% { box-shadow: 0 0 0 7px rgba(11, 15, 74, 0); }
}

@keyframes lp-trace-flow {
  to { background-position: 0 20px; }
}

/* Saindo direto de um palco marinho pleno (o herói): a golfada e o nó
   precisam ser mais fortes para ler como a MESMA corrente continuando, não
   um fundo novo do zero começando por conta própria. */
.lp-linked--deep {
  background-image: radial-gradient(65% 260px at 50% 0%, rgba(11, 15, 74, 0.08), transparent 74%);
}

.lp-linked--deep::before {
  width: 13px;
  height: 13px;
}

/* Variante de saída: a golfada, o nó e as trilhas migram para a base da
   seção, anunciando o próximo palco escuro (o fechamento) antes de ele
   começar — em vez de a seção clara terminar seca e o marinho só aparecer
   depois. */
.lp-linked--exit {
  background-image: radial-gradient(60% 220px at 50% 100%, rgba(11, 15, 74, 0.06), transparent 72%);
  background-position: bottom center;
}

.lp-linked--exit::before {
  top: auto;
  bottom: 0;
  translate: -50% 50%;
}

.lp-linked--exit::after {
  top: auto;
  bottom: 0;
  translate: -50% 40px;
}

/* --------------------------------------------------------------------------
   CABEÇALHO
   -------------------------------------------------------------------------- */
.lp-header {
  position: sticky;
  top: 0;
  z-index: var(--jl-z-header);
  /* 0.94, não 0.72. A barra atravessa a página inteira, e mais da metade
     dela é seção clara: a 72% o branco de trás subia através do marinho e
     lavava a cor até um azul-acinzentado — lia como desbotado, não como
     translúcido. A 94% o desfoque continua dando a profundidade de vidro no
     rolar, mas a cor lida é marinho da marca em qualquer trecho da página. */
  background: rgba(6, 8, 40, 0.94);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid rgba(218, 218, 218, 0.16);
  transition: background-color var(--jl-dur-base) var(--jl-ease-out),
    box-shadow var(--jl-dur-base) var(--jl-ease-out),
    border-color var(--jl-dur-base) var(--jl-ease-out);
}

/* Estado "rolado" (landing.js, iniciarHeaderScroll): a barra adensa e ganha
   sombra própria assim que o herói começa a sair de baixo dela — reforça
   que ela é uma camada de vidro flutuando SOBRE o conteúdo, não pintada nele.
   Mesma ideia da navbar do template de referência (que troca padding e
   ganha blur ao rolar); aqui o ajuste é mais discreto para não competir com
   as golfadas de .lp-linked logo abaixo dela. */
.lp-header[data-scrolled="true"] {
  background: rgba(6, 8, 40, 0.98);
  border-bottom-color: rgba(218, 218, 218, 0.26);
  box-shadow: var(--jl-shadow-md);
}

.lp-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jl-space-6);
  padding-block: var(--jl-space-4);
}

.lp-nav {
  display: none;
  gap: var(--jl-space-6);
}

.lp-nav a {
  position: relative;
  font-size: var(--jl-size-body-sm);
  font-weight: var(--jl-weight-medium);
  /* Prata da marca cheia, não a 78%. Rebaixada, ela deixava de ser prata e
     virava um cinza médio (~#ACACAC) sobre o marinho. Cheia lê como prata,
     e o contraste do estado hover fica por conta do branco puro mais do
     sublinhado que desenha — não por escurecer o repouso. */
  color: var(--jl-silver-200);
  text-decoration: none;
  padding-block: var(--jl-space-2);
  transition: color var(--jl-dur-base) var(--jl-ease-out);
}

/* Sublinhado que desenha da esquerda pra direita, não um traço que só troca
   de cor. scaleX em vez de width: anima na GPU, não força layout a cada
   frame — importante porque isso roda a cada hover, não uma vez só. */
.lp-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--jl-silver-200);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 380ms var(--jl-ease-out);
}

.lp-nav a:hover,
.lp-nav a:focus-visible { color: var(--jl-white); }
.lp-nav a:hover::after,
.lp-nav a:focus-visible::after { transform: scaleX(1); }

@media (min-width: 900px) { .lp-nav { display: flex; } }

/* Abaixo de 560px o letreiro sai e fica só o monograma. Com ele, a soma
   monograma + letreiro + botão passava de 400px e o CTA do cabeçalho era
   empurrado para fora da tela em 375px — cortado, e sem gerar rolagem
   horizontal que denunciasse o problema. */
@media (max-width: 559px) {
  .lp-header .jl-logo__word { display: none; }
  .lp-header__inner { gap: var(--jl-space-4); }
}

/* --------------------------------------------------------------------------
   HERÓI

   O título é a maior fonte do sistema — maior que --jl-size-display-xl de
   propósito, é o único lugar da página com esse peso — mas presa a um teto
   de 3,75rem (60px). Acima disso, numa coluna de texto que só tem metade do
   palco, a frase completa passa de quatro linhas e o herói vira uma tela
   cheia de título. O balanço aqui é: grande o bastante para ler como
   declaração, contido o bastante para caber em duas ou três linhas.
   -------------------------------------------------------------------------- */
.lp-hero { padding-block: clamp(2.5rem, 1.4rem + 4.4vw, 5.5rem) clamp(3rem, 1.6rem + 5.2vw, 6.5rem); }

.lp-hero__grid {
  display: grid;
  gap: clamp(2.5rem, 1rem + 5vw, 4.5rem);
  align-items: center;
}

@media (min-width: 1000px) {
  /* 1.3 : 0.7 — o cartão do certificado é apoio visual, não precisa da
     metade do palco. O texto é o que carrega a promessa. */
  .lp-hero__grid { grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr); }
}

.lp-hero__title {
  font-family: var(--jl-font-display);
  font-size: clamp(2.25rem, 1.15rem + 3.6vw, 3.75rem);
  font-weight: var(--jl-weight-bold);
  line-height: 1.08;
  letter-spacing: -0.04em;
  color: var(--jl-white);
  margin: 0;
  text-wrap: balance;
}

/* Verniz prateado na última linha do título — o brilho do metal, sem
   inventar cor: é a própria prata da marca em gradiente. */
.lp-hero__shine {
  background: linear-gradient(96deg, #ffffff 12%, #b8bcf5 38%, #dadada 58%, #ffffff 86%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: lp-sheen 9s var(--jl-ease-inout) infinite;
}

@keyframes lp-sheen {
  0%, 100% { background-position: 120% 0; }
  50% { background-position: -20% 0; }
}

.lp-hero__lead { max-width: 54ch; }

/* Pilha do herói um degrau mais compacta que o padrão --jl-space-8 (32px):
   com título, subtítulo, cupom, CTA e prova social empilhados, o gap padrão
   somava altura à toa. 24px continua respirando sem alongar a cena. */
.lp-hero__grid > .jl-stack--loose { gap: var(--jl-space-6); }

.lp-hero__proof {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--jl-space-3) var(--jl-space-6);
  padding-top: var(--jl-space-6);
  border-top: 1px solid rgba(218, 218, 218, 0.14);
}

.lp-proof {
  display: flex;
  align-items: center;
  gap: var(--jl-space-2);
  font-size: var(--jl-size-caption);
  color: rgba(218, 218, 218, 0.72);
}

.lp-proof strong { color: var(--jl-white); font-weight: var(--jl-weight-semibold); }

/* --------------------------------------------------------------------------
   OFERTA SUTIL — pílula de cupom, herói e preços

   Existia um segundo componente aqui, .lp-coupon: um banner com borda
   tracejada, pensado pra seção de preços, "porque ali a decisão de compra
   já está em jogo". Pedido do cliente foi o oposto — tornar o cupom MAIS
   sutil ali, não menos — e a pílula abaixo (criada pro herói, onde um bloco
   grande competiria com o título) já resolvia exatamente isso. Um
   componente fazendo o trabalho dos dois lugares, em vez de dois
   componentes achando motivo pra existir separado.

   Cabe numa linha ao lado do texto sem gritar, mas o ponto pulsante e o
   brilho lento de metal garantem que ainda assim ela respire — é sutil, não
   inerte.
   -------------------------------------------------------------------------- */
.lp-offer {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: var(--jl-space-2);
  align-self: flex-start;
  padding: var(--jl-space-2) var(--jl-space-4);
  border: 1px solid rgba(218, 218, 218, 0.26);
  border-radius: var(--jl-radius-pill);
  background: rgba(218, 218, 218, 0.05);
  font-family: var(--jl-font-body);
  font-size: var(--jl-size-caption);
  color: rgba(218, 218, 218, 0.85);
  cursor: pointer;
  transition:
    border-color var(--jl-dur-base) var(--jl-ease-out),
    background-color var(--jl-dur-base) var(--jl-ease-out);
}

.lp-offer:hover {
  border-color: rgba(218, 218, 218, 0.5);
  background: rgba(218, 218, 218, 0.09);
}

.lp-offer[data-copied="true"] { border-color: var(--jl-silver-200); }

.lp-offer__dot {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: var(--jl-radius-pill);
  background: var(--jl-silver-200);
  box-shadow: 0 0 0 3px rgba(218, 218, 218, 0.16);
}

.lp-offer strong {
  color: var(--jl-white);
  font-weight: var(--jl-weight-bold);
  letter-spacing: 0.03em;
}

.lp-offer__hint {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(218, 218, 218, 0.5);
}

/* Brilho de metal cruzando a pílula devagar — a mesma família do sweep da
   medalha ICP e do cartão, um fio condutor entre os três em vez de três
   animações inventadas soltas. */
.lp-offer::after {
  content: "";
  position: absolute;
  inset: -60% -20%;
  background: linear-gradient(75deg, transparent 42%, rgba(255, 255, 255, 0.5) 50%, transparent 58%);
  translate: -160% 0;
  animation: lp-offer-sweep 6.5s var(--jl-ease-inout) infinite;
  pointer-events: none;
}

@keyframes lp-offer-sweep {
  0%, 58%, 100% { translate: -160% 0; }
  78% { translate: 160% 0; }
}

/* Pílula sobre fundo claro (seção de preços): mesma peça, tons invertidos.
   O sweep branco a 0.5 de alpha soma quase nada sobre um fundo já claro —
   por isso vira marinho aqui, senão o brilho simplesmente não aparece. */
.lp-offer--light {
  border-color: var(--border-default);
  background: var(--surface-brand-soft);
  /* --text-secondary é calibrado pra 5,1:1 sobre branco puro (ver
     tokens.css) — sobre o lilás de --surface-brand-soft isso cai pra
     ~4,47:1, abaixo do mínimo de AA. --text-primary sobra contraste aqui. */
  color: var(--text-primary);
}
.lp-offer--light:hover { border-color: var(--border-brand); background: var(--surface-silver); }
.lp-offer--light .lp-offer__dot { background: var(--text-brand); box-shadow: 0 0 0 3px var(--surface-brand-soft); }
.lp-offer--light strong { color: var(--text-primary); }
.lp-offer--light .lp-offer__hint { color: var(--text-primary); }
.lp-offer--light::after {
  background: linear-gradient(75deg, transparent 42%, rgba(11, 15, 74, 0.14) 50%, transparent 58%);
}

/* --------------------------------------------------------------------------
   CABEÇALHO DE PREÇOS — texto e cupom na mesma linha

   Pedido do cliente: o aviso de cupom ocupava sua própria fileira cheia
   (.jl-cluster) abaixo do parágrafo — outro bloco na pilha, outro
   --jl-space-8 de gap, altura de seção somando à toa por um aviso que é
   secundário ao preço em si. Juntar os dois numa linha só devolve essa
   altura inteira: o cupom deixa de ser uma seção própria e volta a ser o
   que é, uma nota ao lado do título. Em telas estreitas cai pra baixo do
   texto — empilhar aqui é normal, esconder o cupom não seria. */
.lp-precos-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--jl-space-6) var(--jl-space-8);
}

.lp-precos-head > .jl-stack { flex: 1 1 380px; max-width: 640px; min-width: 0; }
.lp-precos-head > .lp-offer--light { flex: 0 0 auto; margin-top: var(--jl-space-1); }

/* --------------------------------------------------------------------------
   CARTÃO DO CERTIFICADO — o objeto do herói

   Três camadas de vida agora:

   1. AMBIENTE, superfície (::after) — um brilho lento cruza a face sozinho,
      num ciclo de 10s. Existe para quem nunca encosta o mouse: metade dos
      visitantes chega pelo celular e nunca vai disparar um hover.
   2. AMBIENTE, contorno (.lp-cert__ring) — um traço de luz percorre a borda
      devagar, num ciclo de 8s propositalmente dessincronizado do sweep da
      superfície, pra não ler como um padrão mecânico repetindo junto.
   3. INTERATIVO (--cert-rx/ry/mx/my, setados por landing.js) — em telas com
      mouse de verdade, o cartão inclina em 3D seguindo o cursor e um facho
      de luz acompanha o ponteiro pela superfície, como metal escovado
      reagindo à luz. É a interação mais elaborada da página de propósito:
      é o objeto que a página vende, o único lugar que merece esse investimento.

   overflow:hidden contém os sweeps dentro do contorno arredondado do
   cartão — por isso o fio de luz do topo (::before) fica em top:0, não
   top:-1px, senão o corte o comeria.

   A entrada (opacity/translate/scale) usa propriedades independentes de
   transform de propósito: transform já pertence à inclinação por mouse
   acima, e uma keyframe disputando essa mesma propriedade com
   fill-mode:forwards prenderia o cartão na pose final da animação para
   sempre — o mouse nunca mais conseguiria inclinar nada depois. translate e
   scale são propriedades CSS próprias desde o Transforms Level 2 e compõem
   ao lado de transform sem brigar por ele; é o mesmo motivo pelo qual
   .lp-reveal, em toda a página, anima translate em vez de transform.
   -------------------------------------------------------------------------- */
.lp-cert {
  --cert-rx: 0deg;
  --cert-ry: 0deg;
  --cert-mx: 50%;
  --cert-my: 30%;

  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-5);
  padding: var(--jl-space-8);
  border-radius: var(--jl-radius-2xl);
  border: 1px solid rgba(218, 218, 218, 0.2);
  background:
    linear-gradient(150deg, rgba(218, 218, 218, 0.13), rgba(218, 218, 218, 0.03) 46%, rgba(6, 8, 40, 0.4));
  /* drop-shadow, não box-shadow: box-shadow seria cortada pelo overflow:hidden
     acima (que existe para conter os sweeps no contorno arredondado);
     drop-shadow é um filtro, não sofre esse corte. */
  filter: drop-shadow(0 40px 50px rgba(0, 0, 0, 0.5));
  backdrop-filter: blur(2px);
  transform: perspective(1000px) rotateX(var(--cert-rx)) rotateY(var(--cert-ry));
  transition: transform 240ms var(--jl-ease-out);
  will-change: transform;

  /* Entrada evolutiva: 680ms de atraso continua exatamente o cadenciamento
     de 100ms em 100ms do texto ao lado (.lp-enter, até 580ms no 6º item) —
     o cartão materializa como se fosse o próximo passo da mesma sequência,
     não um efeito solto chegando depois por conta própria. */
  opacity: 0;
  translate: 0 28px;
  scale: 0.96;
  animation-name: lp-cert-enter;
  animation-duration: 900ms;
  animation-timing-function: var(--jl-ease-out);
  animation-delay: 680ms;
  animation-fill-mode: both;
}

@keyframes lp-cert-enter {
  to { opacity: 1; translate: 0 0; scale: 1; }
}

/* Abaixo de 640px o cartão empilha sob o texto (grid de 1 coluna, ver
   .lp-hero__grid) e vira só altura de rolagem antes do CTA — no mobile de
   verdade o que vende é o título + a oferta, não a réplica do
   certificado. Some só aqui; do tablet pra cima ele ainda cabe ao lado do
   texto e continua valendo como apoio visual. Regra vem DEPOIS de
   .lp-cert (mesma especificidade) de propósito: é o que a faz vencer. */
@media (max-width: 639px) {
  .lp-cert { display: none; }
}

/* Fio de luz no topo do cartão: o reflexo que dá a leitura de metal. */
.lp-cert::before {
  content: "";
  position: absolute;
  inset-inline: 12%;
  top: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.75), transparent);
  z-index: 1;
}

/* Camada do contorno — um traço de luz percorrendo a borda devagar, como um
   neon sutil. Sem cor nova: prata da marca, a mesma família dos outros
   brilhos do cartão, só que na moldura em vez da face.

   Técnica do "anel mascarado": .lp-cert__ring tem padding igual à espessura
   do traço e uma máscara que soma o content-box (miolo) ao border-box
   (tudo) por XOR — o que sobra visível é só o anel fino da diferença entre
   os dois. Dentro dele, ::before é um quadrado enorme (60% maior que o
   próprio anel em cada lado) girando devagar: por ser tão maior que a
   janela mascarada, nenhuma quina do giro chega perto da borda visível, e
   o resultado lido é um cometa de luz contornando sem nunca "quebrar"
   quina nenhuma. */
.lp-cert__ring {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 1px;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

.lp-cert__ring::before {
  content: "";
  position: absolute;
  inset: -60%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    transparent 268deg,
    rgba(218, 218, 218, 0.12) 300deg,
    var(--jl-silver-200) 330deg,
    #ffffff 344deg,
    var(--jl-silver-200) 352deg,
    rgba(218, 218, 218, 0.12) 360deg
  );
  animation: lp-cert-ring-spin 8s linear infinite;
}

@keyframes lp-cert-ring-spin { to { transform: rotate(360deg); } }

/* Camada 1 — sweep ambiente, sempre ligado. */
.lp-cert::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 32%, rgba(255, 255, 255, 0.09) 50%, transparent 68%);
  translate: -150% 0;
  animation: lp-cert-sweep 10s var(--jl-ease-inout) infinite;
  pointer-events: none;
}

@keyframes lp-cert-sweep {
  0%, 60%, 100% { translate: -150% 0; }
  80% { translate: 150% 0; }
}

/* Camada 2 — facho que segue o cursor, só existe visualmente quando o mouse
   está sobre o cartão (landing.js só escreve nos tokens --cert-mx/my sob
   :hover; em repouso a opacidade zero esconde a camada). */
.lp-cert__sheen {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  background: radial-gradient(480px circle at var(--cert-mx) var(--cert-my), rgba(255, 255, 255, 0.24), transparent 55%);
  opacity: 0;
  transition: opacity 320ms var(--jl-ease-out);
  pointer-events: none;
}

.lp-cert:hover .lp-cert__sheen { opacity: 1; }

.lp-cert__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jl-space-4);
  padding-bottom: var(--jl-space-5);
  border-bottom: 1px solid rgba(218, 218, 218, 0.16);
}

.lp-cert__kind {
  font-family: var(--jl-font-display);
  font-size: var(--jl-size-heading-md);
  font-weight: var(--jl-weight-bold);
  letter-spacing: var(--jl-ls-heading);
  color: var(--jl-white);
}

.lp-cert__rows {
  display: grid;
  gap: var(--jl-space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.lp-cert__row { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lp-cert__row--wide { grid-column: 1 / -1; }

.lp-cert__key {
  font-size: 11px;
  font-weight: var(--jl-weight-bold);
  letter-spacing: var(--jl-ls-eyebrow);
  text-transform: uppercase;
  color: rgba(218, 218, 218, 0.5);
}

.lp-cert__val {
  font-family: var(--jl-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--jl-size-body-sm);
  color: var(--jl-white);
  overflow-wrap: anywhere;
}

.lp-cert__foot {
  display: flex;
  align-items: center;
  gap: var(--jl-space-4);
  padding-top: var(--jl-space-5);
  border-top: 1px solid rgba(218, 218, 218, 0.16);
}

/* Medalha metálica com varredura de brilho lenta. */
.lp-medal {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.lp-medal::after {
  content: "";
  position: absolute;
  inset: -40%;
  background: linear-gradient(70deg, transparent 40%, rgba(255, 255, 255, 0.85) 50%, transparent 60%);
  animation: lp-medal-sweep 7s var(--jl-ease-inout) infinite;
}

@keyframes lp-medal-sweep {
  0%, 62%, 100% { translate: -120% 0; }
  80% { translate: 120% 0; }
}

/* --------------------------------------------------------------------------
   ESCASSEZ — faixa de prazo e vagas
   Sem cor de alerta: o peso vem do fundo marinho pleno e da mono tabular.

   Grid de 3 colunas, não flex com wrap. Com flex+space-between, a largura de
   cada bloco é só o quanto o próprio conteúdo pede — e a soma dos três (com
   o texto do 3º bloco variando) já passou do container por 10px em algum
   momento, o suficiente pra derrubar o bloco inteiro pra uma segunda linha
   sozinho, sobrando um vão feio no meio da primeira. Com grid, a coluna do
   meio (1fr) absorve toda a variação: o texto dela quebra dentro da própria
   coluna se precisar, sem nunca arrastar as colunas 1 e 3 com ela.
   -------------------------------------------------------------------------- */
.lp-scarcity {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--jl-space-8);
  padding: var(--jl-space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--jl-radius-xl);
  background: var(--surface-card);
}

.lp-scarcity > :last-child {
  justify-self: end;
  text-align: right;
  /* Sobrepõe o gap de 8px de .jl-stack--tight. A sombra do --emphasis
     (0 14px 34px) tem alcance visual real de uns 30-40px abaixo do botão —
     8px deixava a legenda quase dentro da sombra, prejudicando a leitura. */
  gap: var(--jl-space-10);
}

@media (max-width: 899px) {
  .lp-scarcity {
    grid-template-columns: 1fr;
    justify-items: start;
    gap: var(--jl-space-5);
  }

  .lp-scarcity > :last-child {
    justify-self: start;
    text-align: left;
  }
}

.lp-slots { display: flex; flex-direction: column; gap: var(--jl-space-2); }

/* --------------------------------------------------------------------------
   GRADE DE PLANOS — uma fileira só, sempre

   Terceira versão desta grade. A primeira era 4 colunas fixas (cartão de
   ~245px, apertado demais pro conteúdo que os cartões carregam hoje). A
   segunda trocou por 2×2 pra dar espaço a ícone + descrição + 3 funções —
   só que duas fileiras esticam a altura da seção mais do que deveriam, e o
   pedido explícito do cliente foi "sem 2 linhas, evitar rolagem
   desnecessária". As duas coisas — cartão largo o bastante pro conteúdo E
   uma fileira só — não cabem juntas em toda largura de tela: em ~1180px de
   viewport pra baixo, 4 cartões de largura confortável simplesmente não
   entram lado a lado. A saída não é escolher uma ou outra, é deixar o CSS
   decidir por viewport:

     grid-auto-flow: column        -> 1 fileira, nunca quebra pra 2ª linha
     grid-auto-columns: minmax(260px, 1fr)
                                    -> cada cartão cresce até dividir o
                                       espaço igualmente (1fr) quando cabe,
                                       e trava em 260px (o mínimo que
                                       ícone + título + 3 funções pedem,
                                       testado no cartão de 2 colunas da
                                       versão anterior) quando não cabe
     overflow-x: auto              -> quando os 4×260px não cabem, a
                                       fileira vira scroll horizontal em
                                       vez de estourar a tela ou quebrar
                                       linha — rolagem lateral contida, não
                                       a rolagem vertical indesejada que
                                       gerava o pedido

   Resultado: telas largas (a partir de ~1180px, com o container também
   alargado pra 1360px como .lp-stage já faz) mostram os 4 lado a lado sem
   rolagem nenhuma. Abaixo disso — tablet, mobile — a fileira continua
   sendo UMA fileira, só que folheável com o dedo/scroll lateral, com
   scroll-snap pra cada cartão encaixar inteiro na tela. */
#precos .jl-container { max-width: 1360px; }

.lp-plans-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(260px, 1fr);
  gap: var(--jl-space-5);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  /* Espaço acima e no rodapé: sem isso, o selo ".jl-plan__flag" (que
     avança pra fora do cartão em top negativo) e a sombra do cartão
     selecionado ficariam cortados — a rolagem horizontal também vira
     contêiner de recorte no eixo vertical (regra do spec: um eixo não
     visível força o outro a se comportar como auto, não como visible). */
  padding-block: var(--jl-space-4) var(--jl-space-2);
}

.lp-plans-grid > .jl-plan { scroll-snap-align: start; }

/* --------------------------------------------------------------------------
   ÍCONE DO PRODUTO — à direita do título do cartão

   Os quatro produtos, agora — A1 e A3 chegaram em levas diferentes: os A1
   mostram um laptop com a tela nomeada, os A3 mostram o kit físico do
   token (pasta, pendrive, cartão de chip). Os PNGs em
   design-system/product-icons/ vêm das artes com fundo já removido em
   design-system/Design Products/*(transparente).png — 500² com alpha real
   — apenas recortados rente ao objeto e reduzidos pra ~280px de altura (a
   fonte agora tem resolução de sobra pro tamanho maior abaixo). (A primeira
   leva de A1 usada aqui vinha de um .webp de 1254² cujo "fundo
   transparente" era na verdade um xadrez de preview gravado em pixel
   opaco; foi descartada.)

   [VERIFICAR] os dois arquivos-fonte dos A3 chegaram nomeados
   "…_a_Corrigir" — confirmar com o cliente se é a arte final ou se ainda
   vem uma correção antes de publicar.

   alt="" em todos porque a imagem é redundante ao texto do título ao
   lado — leitor de tela não precisa ouvir "e-CNPJ A1" duas vezes seguidas.

   O cartão agora tem DUAS larguras possíveis dependendo do viewport — trava
   em 260px em rolagem horizontal, ou cresce até ~305px numa fileira sem
   rolagem (ver .lp-plans-grid acima) — e não existe um valor de vw que
   acompanhe as duas ao mesmo tempo sem estourar numa delas. Por isso o
   ícone usa container query (cqi = 1% da largura do próprio cartão, não do
   viewport): ele sabe a largura real do cartão em qualquer um dos dois
   modos e nunca briga com o título por espaço. Compromisso assumido: não é
   mais tão grande quanto a versão de 2 colunas (que chegava a 130px) — o
   pedido de "1 fileira só" tem esse custo físico, dado quanto espaço
   sobra por cartão. O DOM segue título-depois-ícone: quem define "à
   direita" aqui é a ordem no HTML, não `order` no CSS. */
.jl-plan { container-type: inline-size; }

.lp-plan__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--jl-space-3);
}

.lp-plan__icon {
  flex: none;
  height: clamp(64px, 36cqi, 100px);
  width: auto;
}

/* --------------------------------------------------------------------------
   PREÇO SIMPLES
   -------------------------------------------------------------------------- */
.lp-plan-price {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-1);
  margin-top: auto;
}

.lp-plan-coupon {
  font-size: 11px;
  font-weight: var(--jl-weight-bold);
  letter-spacing: var(--jl-ls-eyebrow);
  text-transform: uppercase;
  color: var(--text-brand);
}

/* --------------------------------------------------------------------------
   PARA QUE SERVE — duas colunas por identificação, não 4 cartões soltos

   Nada de cartão aqui de propósito: dois blocos editoriais lado a lado,
   separados por um fio vertical simples (não uma borda colorida de
   destaque — é um filete neutro de coluna, como um jornal de duas colunas,
   a 1px). auto-fit com minmax(280px,1fr): sem breakpoint próprio, empilha
   sozinho quando o espaço não sustenta as duas colunas lado a lado.

   Entrada com direção alternada (data-dir="left"/"right", mecanismo que já
   existe em .lp-reveal) — cada coluna entra do seu próprio lado, reforçando
   a leitura de "dois casos, um em cada mão" em vez de um bloco só.
   -------------------------------------------------------------------------- */
.lp-uses {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--jl-space-10);
}

.lp-uses__col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--jl-space-4);
}

@media (min-width: 700px) {
  .lp-uses__col + .lp-uses__col {
    border-left: 1px solid var(--border-subtle);
    padding-left: var(--jl-space-10);
  }
}

/* --------------------------------------------------------------------------
   AÇÕES SECUNDÁRIAS — .jl-btn--ghost como "link enquadrado"

   Os quatro "Ver ..." da página deixaram de ser texto sublinhado e viraram
   botões ghost pequenos. Ghost porque são ações de APOIO: levam a outra
   seção ou a um site externo, nunca à conversão. Se fossem sólidos,
   disputariam atenção com os CTAs de emissão, que são o que a página vende.
   -------------------------------------------------------------------------- */

/* A borda do ghost vem de --border-default, que sobre o branco da página dá
   1,74:1 e sobre a seção rebaixada, 1,62:1 — a WCAG pede 3:1 para o contorno
   de um componente. Como "enquadrado" é justamente o efeito pedido, uma
   moldura que quase não aparece falha no design E na norma ao mesmo tempo.
   --border-strong também não resolve (2,18:1); o único token que passa é
   --border-brand, marinho pleno, pesado demais para uma ação de apoio.
   Daí a transparência: 50% do marinho da marca fica em ~3,4:1 sobre os dois
   fundos onde estes botões aparecem, e ainda lê como cinza-azulado leve, não
   como botão sólido. Mesma família dos outros rgba de marca já usados neste
   arquivo — nenhuma cor nova entra por isso. */
.jl-btn--ghost { border-color: rgba(11, 15, 74, 0.5); }

/* O hover do ghost troca o FUNDO para --surface-sunk. Numa seção que já é
   --sunk (o caso de "Para que serve"), essa troca é invisível: fundo do botão
   e fundo da seção viram exatamente a mesma cor. Por isso quem carrega o
   gesto aqui é a borda fechando em marinho pleno — funciona nos dois
   contextos, sem o botão precisar saber em que seção foi parar. */
.jl-btn--ghost:hover:not([aria-disabled="true"]) { border-color: var(--border-brand); }

/* --------------------------------------------------------------------------
   BLOCO DE CREDENCIAMENTO — corpo em duas colunas

   Antes, heading + parágrafo + parágrafo + botão empilhavam num .jl-stack
   só, de largura única — o bloco crescia em ALTURA sem nunca aproveitar a
   largura que sobrava ao lado, num container de até 1120px. Virou duas
   colunas lado a lado: a afirmação de credenciamento à esquerda, a instrução
   de verificação (o "pesquise por AR JL CERTIFICADO DIGITAL" + o botão) à
   direita — a mesma divisória fina de coluna editorial já usada em
   .lp-uses__col, reaproveitada aqui em vez de inventada de novo.

   auto-fit com minmax: sem breakpoint próprio, as duas colunas empilham
   sozinhas quando o espaço não sustenta as duas lado a lado (mesmo padrão
   de .lp-uses).
   -------------------------------------------------------------------------- */
.jl-trust__body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--jl-space-8) var(--jl-space-10);
  flex: 1 1 auto;
  min-width: 0;
}

.jl-trust__main,
.jl-trust__verify {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--jl-space-2);
  min-width: 0;
}

/* A coluna de verificação é a que "vai para a direita": como é a segunda
   célula do grid, ela naturalmente ocupa o lado direito quando as duas
   colunas cabem lado a lado, e o gap vertical assume sozinho quando empilha
   em telas estreitas. */
@media (min-width: 640px) {
  .jl-trust__verify {
    border-left: 1px solid var(--border-subtle);
    padding-left: var(--jl-space-10);
  }
}

/* .jl-trust__verify já é column flex com align-items:flex-start — o botão
   não precisa mais de align-self próprio, só do respiro em relação ao
   parágrafo acima (gap:var(--jl-space-2) do pai já dava, mas o botão pede um
   pouco mais de ar que o texto corrido). */
.jl-trust__cta {
  margin-top: var(--jl-space-2);
}

/* --------------------------------------------------------------------------
   FLUXO — a trilha do processo, que avança com a rolagem

   Substitui os três .lp-step-card lado a lado (topo colorido + número solto).
   Três cartões numa fileira mostram passos SIMULTÂNEOS; o processo da JL é
   uma sequência de cinco, e o que o visitante precisa entender é justamente a
   ORDEM — sobretudo que o pagamento é o último. Uma trilha vertical que se
   preenche conforme ele desce diz isso sem precisar escrever.

   Vocabulário visual: o nó é o MESMO hexágono de pad de circuito que costura
   as seções em .lp-linked, só que grande e numerado. É a mesma peça da página
   inteira reaparecendo onde a sequência acontece de verdade, não um ícone
   novo inventado para esta seção.

   PADRÃO SEM JS = TUDO CONCLUÍDO. O estado de repouso (sem .js-flow) tem o
   trilho cheio e os cinco nós marinhos. Só depois que o JS confirma que vai
   rodar é que ele zera o progresso e passa a acompanhar a rolagem. Mesmo
   princípio de .lp-reveal, e pela mesma razão: sem JS, com JS quebrado ou em
   renderizador headless, a seção continua legível e completa — nunca uma
   fileira de nós apagados.

   Nenhum estado apaga texto: título e descrição ficam em contraste cheio o
   tempo todo. Quem carrega o estado é o nó e o trilho, não a legibilidade.
   -------------------------------------------------------------------------- */
.lp-flow-layout {
  --flow-progress: 1;
  display: grid;
  gap: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
  align-items: start;
}

@media (min-width: 1000px) {
  .lp-flow-layout { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }

  /* A coluna de texto acompanha a rolagem da trilha: o visitante nunca perde
     de vista onde está no processo. 96px de topo = a barra fixa (~72px) mais
     um respiro, senão o título encosta no vidro do cabeçalho. */
  .lp-flow-aside {
    position: sticky;
    top: var(--jl-space-24);
  }
}

.lp-flow-aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--jl-space-4);
}

.lp-flow-aside .jl-cluster { margin-top: var(--jl-space-2); }

/* Medidor — o mesmo progresso do trilho, em número. Existe porque na coluna
   fixa ele fica sempre visível, inclusive quando o nó atual já passou do
   campo de visão. Número em mono tabular: sem isso o "01 → 02" empurra o
   texto de lado a cada troca. */
.lp-flow-meter {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-2);
  width: 100%;
  max-width: 260px;
  margin-top: var(--jl-space-2);
}

.lp-flow-meter__label {
  margin: 0;
  font-size: var(--jl-size-caption);
  color: var(--text-secondary);
}

.lp-flow-meter__label .jl-mono {
  font-variant-numeric: tabular-nums;
  font-weight: var(--jl-weight-bold);
  color: var(--text-primary);
}

.lp-flow-meter__track {
  height: 2px;
  border-radius: var(--jl-radius-pill);
  background: var(--border-subtle);
  overflow: hidden;
}

/* Sem transition: o valor é reescrito a cada quadro pela rolagem, e uma
   transição em cima disso só faria o preenchimento correr ATRÁS do scroll,
   sempre alguns décimos desatualizado. Quem dá a suavidade aqui é o próprio
   movimento do dedo/roda; o mesmo vale para o trilho em .lp-flow::after.
   As transições ficam onde há troca discreta de estado — a cor dos nós. */
.lp-flow-meter__fill {
  display: block;
  height: 100%;
  background: var(--action-primary);
  transform: scaleX(var(--flow-progress));
  transform-origin: left;
}

/* --- a trilha ----------------------------------------------------------- */
.lp-flow {
  --node: 46px;
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2rem, 1.2rem + 2.4vw, 3rem);
}

@media (max-width: 599px) { .lp-flow { --node: 38px; } }

/* Trilho: vai do centro do primeiro nó ao centro do último, não da borda da
   lista — senão sobra um toco de linha acima do 01 e abaixo do 05. */
.lp-flow::before,
.lp-flow::after {
  content: "";
  position: absolute;
  left: calc(var(--node) / 2 - 1px);
  top: calc(var(--node) / 2);
  bottom: calc(var(--node) / 2);
  width: 2px;
  border-radius: var(--jl-radius-pill);
  pointer-events: none;
}

.lp-flow::before { background: var(--border-subtle); }

.lp-flow::after {
  background: var(--action-primary);
  transform: scaleY(var(--flow-progress));
  transform-origin: top;
}

.lp-flow__step {
  position: relative;
  display: grid;
  grid-template-columns: var(--node) minmax(0, 1fr);
  gap: var(--jl-space-5);
  align-items: start;
}

.lp-flow__body {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-2);
  /* Alinha a primeira linha do título com o centro óptico do nó. */
  padding-top: calc((var(--node) - 1.6em) / 2);
}

.lp-flow__body .jl-body-sm { max-width: 54ch; }

/* --- o nó ---------------------------------------------------------------
   Hexágono com "borda": duas camadas recortadas pelo mesmo clip-path, a de
   dentro 2px menor. Um box-shadow inset seria cortado pelo clip-path e
   renderizaria pela metade; empilhar dois hexágonos é o que dá contorno
   limpo em qualquer zoom. */
.lp-flow__node {
  --node-edge: var(--action-primary);
  --node-face: var(--action-primary);
  --node-ink: var(--action-primary-text);

  position: relative;
  z-index: 1;
  width: var(--node);
  height: var(--node);
  display: grid;
  place-items: center;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  background: var(--node-edge);
  transition:
    background-color 320ms var(--jl-ease-out),
    filter 320ms var(--jl-ease-out);
}

.lp-flow__node::before {
  content: "";
  position: absolute;
  inset: 2px;
  clip-path: inherit;
  background: var(--node-face);
  transition: background-color 320ms var(--jl-ease-out);
}

.lp-flow__num {
  position: relative;
  font-family: var(--jl-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--jl-size-caption);
  font-weight: var(--jl-weight-bold);
  color: var(--node-ink);
  transition: color 320ms var(--jl-ease-out);
}

/* --- estados dirigidos pela rolagem (só com .js-flow ativo) -------------- */
.js-flow .lp-flow-layout { --flow-progress: 0; }

.js-flow .lp-flow__step[data-reached="false"] .lp-flow__node {
  --node-edge: var(--border-default);
  --node-face: var(--surface-page);
  --node-ink: var(--text-secondary);
}

/* Etapa corrente: o halo é drop-shadow, não box-shadow. box-shadow externo
   em elemento com clip-path é recortado junto e simplesmente some;
   drop-shadow é filtro, acompanha a silhueta do hexágono. */
.js-flow .lp-flow__step[data-current="true"] .lp-flow__node {
  filter: drop-shadow(0 0 10px rgba(11, 15, 74, 0.32));
}

/* --------------------------------------------------------------------------
   FECHAMENTO
   -------------------------------------------------------------------------- */
.lp-close { padding-block: clamp(4rem, 2rem + 8vw, 8rem); }

.lp-close__grid {
  display: grid;
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: center;
}

@media (min-width: 940px) {
  .lp-close__grid { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); }
}

/* --------------------------------------------------------------------------
   RODAPÉ
   -------------------------------------------------------------------------- */
.lp-footer {
  background: var(--jl-navy-900);
  color: rgba(218, 218, 218, 0.7);
  padding-block: var(--jl-space-16) var(--jl-space-10);
}

.lp-footer__grid {
  display: grid;
  gap: var(--jl-space-10);
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
}

.lp-footer h3 {
  font-family: var(--jl-font-display);
  font-size: var(--jl-size-eyebrow);
  font-weight: var(--jl-weight-bold);
  letter-spacing: var(--jl-ls-eyebrow);
  text-transform: uppercase;
  color: var(--jl-silver-200);
  margin: 0 0 var(--jl-space-4);
}

.lp-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--jl-space-3); }
.lp-footer a { color: rgba(218, 218, 218, 0.72); text-decoration: none; font-size: var(--jl-size-body-sm); }
.lp-footer a:hover { color: var(--jl-white); text-decoration: underline; text-underline-offset: 3px; }

/* Ícones de rede social — círculo com traço, mesma família visual do "×"
   do seletor (.lp-selector__close): moldura discreta, ganha presença só
   no hover. Sem underline no :hover porque não é link de texto — o
   próprio preenchimento do fundo já é o feedback do gesto, e um traço
   por baixo de um ícone sem rótulo visível lê como acidente de CSS. */
.lp-footer__social {
  display: flex;
  gap: var(--jl-space-3);
  margin-top: var(--jl-space-5);
}

.lp-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid rgba(218, 218, 218, 0.24);
  border-radius: var(--jl-radius-pill);
  color: rgba(218, 218, 218, 0.72);
  transition: background-color var(--jl-dur-base) var(--jl-ease-out), border-color var(--jl-dur-base) var(--jl-ease-out), color var(--jl-dur-base) var(--jl-ease-out);
}

.lp-footer__social a:hover {
  background: rgba(218, 218, 218, 0.1);
  border-color: rgba(218, 218, 218, 0.4);
  color: var(--jl-white);
  text-decoration: none;
}

.lp-footer__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jl-space-4);
  justify-content: space-between;
  margin-top: var(--jl-space-12);
  padding-top: var(--jl-space-6);
  border-top: 1px solid rgba(218, 218, 218, 0.14);
  font-size: var(--jl-size-caption);
  /* 0.5 dava 4,07:1 sobre o fundo quase-preto do rodapé — abaixo do
     mínimo de AA (4,5:1). 0.6 sobe pra ~5,4:1, ainda lendo como legenda
     discreta. */
  color: rgba(218, 218, 218, 0.6);
}

/* --------------------------------------------------------------------------
   BARRA FIXA DE CONVERSÃO — mobile
   -------------------------------------------------------------------------- */
.lp-actionbar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--jl-z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jl-space-4);
  padding: var(--jl-space-3) var(--jl-space-4);
  background: var(--surface-card);
  border-top: 1px solid var(--border-subtle);
  box-shadow: 0 -8px 24px rgba(6, 8, 40, 0.16);
  translate: 0 110%;
  transition: translate var(--jl-dur-slow) var(--jl-ease-out);
}

.lp-actionbar[data-visible="true"] { translate: 0 0; }

@media (min-width: 860px) { .lp-actionbar { display: none; } }

/* --------------------------------------------------------------------------
   REVELAÇÃO NO SCROLL

   O estado padrão é VISÍVEL. Só depois que o JS confirma que tem
   IntersectionObserver é que ele marca .js-reveal na raiz e o conteúdo passa
   a entrar animado. Sem JS, com JS quebrado ou com o observador que não
   dispara, a página continua inteira na tela.

   Não é preciosismo: na primeira versão o padrão era opacidade 0, e bastou o
   observador não rodar para os 25 blocos da página sumirem de uma vez. Numa
   página de venda, conteúdo não pode depender de script para existir.
   -------------------------------------------------------------------------- */
.js-reveal .lp-reveal {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 620ms var(--jl-ease-out), translate 620ms var(--jl-ease-out);
}

.js-reveal .lp-reveal[data-shown="true"] { opacity: 1; translate: 0 0; }

/* Direção alternativa de entrada — mesmo princípio de .reveal-left/right do
   template de referência, só que como atributo em vez de quatro classes
   soltas: a direção é detalhe do conteúdo (ex.: depoimentos alternando
   lado), o comportamento continua sendo o mesmo .lp-reveal de sempre. */
.js-reveal .lp-reveal[data-dir="left"] { translate: -18px 0; }
.js-reveal .lp-reveal[data-dir="right"] { translate: 18px 0; }

/* --------------------------------------------------------------------------
   SPOTLIGHT — brilho que segue o cursor

   Adaptado do spotlight card do template de referência: lá o brilho é
   magenta/ciano sobre canvas escuro, disparado a cada mousemove. Aqui é a
   mesma mecânica — glow radial preso à posição do cursor via custom
   property, escrito por landing.js — só que em marinho a 7% sobre fundo
   claro: dá profundidade ao cartão no hover sem inventar cor. Em touch a
   opacidade de repouso já é zero e nenhum listener chega a disparar.

   z-index:-1 no pseudo-elemento (não overflow:hidden no cartão) é o que
   evita cortar o selo "Mais vendido" do .jl-plan, que fica de propósito
   for a do contorno do cartão.
   -------------------------------------------------------------------------- */
.lp-spotlight {
  --spot-x: 50%;
  --spot-y: 50%;
  position: relative;
  isolation: isolate;
}

.lp-spotlight::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(260px circle at var(--spot-x) var(--spot-y), rgba(11, 15, 74, 0.07), transparent 68%);
  opacity: 0;
  transition: opacity 320ms var(--jl-ease-out);
  pointer-events: none;
}

.lp-spotlight:hover::after { opacity: 1; }

/* --------------------------------------------------------------------------
   FLUTUAÇÃO — só a medalha

   Adaptado do float do mockup no template de referência (lá aplicado ao
   telefone inteiro, amplitude de ~20px). Aqui a amplitude cai para 3px e o
   alvo é só a medalha ICP-Brasil: é o único elemento decorativo o bastante
   para "respirar" sem que o gesto leia como brincadeira num selo de
   credenciamento oficial.
   -------------------------------------------------------------------------- */
@keyframes lp-seal-float {
  0%, 100% { translate: 0 -3px; }
  50% { translate: 0 3px; }
}

.lp-seal-float { animation: lp-seal-float 6s var(--jl-ease-inout) infinite; }

/* Entrada encenada do herói: uma sequência só, na carga da página. */
.lp-enter > * {
  opacity: 0;
  translate: 0 22px;
  animation: lp-enter 900ms var(--jl-ease-out) forwards;
}

.lp-enter > *:nth-child(1) { animation-delay: 80ms; }
.lp-enter > *:nth-child(2) { animation-delay: 180ms; }
.lp-enter > *:nth-child(3) { animation-delay: 280ms; }
.lp-enter > *:nth-child(4) { animation-delay: 380ms; }
.lp-enter > *:nth-child(5) { animation-delay: 480ms; }
.lp-enter > *:nth-child(6) { animation-delay: 580ms; }

@keyframes lp-enter { to { opacity: 1; translate: 0 0; } }

/* --------------------------------------------------------------------------
   NOSSA UNIDADE — fotos, endereço e mapa da loja matriz

   Duas colunas: fotos + dados de contato à esquerda, mapa à direita — a
   mesma divisão de "quem vai até a loja" (endereço, telefone, horário) e
   "onde fica" (mapa) que uma página de contato normal já usa, sem
   inventar layout novo. auto-fit com minmax empilha sozinho em telas
   estreitas, mesmo padrão de .lp-uses logo acima na página.
   -------------------------------------------------------------------------- */
.lp-unidade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--jl-space-8);
  align-items: stretch;
}

.lp-unidade__info {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-6);
}

.lp-unidade__fotos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--jl-space-3);
}

.lp-unidade__fotos img {
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--jl-radius-lg);
  border: 1px solid var(--border-subtle);
}

.lp-unidade__dados {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--jl-space-2);
}

.lp-unidade__dados > .jl-cluster { margin-top: var(--jl-space-2); }

/* <address> vem itálico por padrão em todo navegador — herança do HTML4,
   não decisão nossa. Sem isto o endereço destoaria do resto do corpo de
   texto da página, que não usa itálico em lugar nenhum. */
.lp-unidade__endereco {
  font-style: normal;
  color: var(--text-secondary);
  margin: 0;
}

.lp-unidade__telefone {
  font-size: var(--jl-size-heading-sm);
  font-weight: var(--jl-weight-bold);
  color: var(--text-primary);
  text-decoration: none;
}

.lp-unidade__telefone:hover { color: var(--text-brand); }

/* O iframe do Locator Plus (fornecido pronto pelo Google, width:100%
   height:100%) precisa de um ancestral com altura EXPLÍCITA pra ter onde
   esticar — 100% de um pai sem altura própria não gera pixel nenhum.
   min-height fixo faz esse papel e garante que o mapa não fique
   esmagado nem em telas baixas. */
.lp-unidade__mapa {
  position: relative;
  min-height: 360px;
  border-radius: var(--jl-radius-lg);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}

.lp-unidade__mapa iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* --------------------------------------------------------------------------
   SELETOR DE CERTIFICADO — subtela guiada em duas perguntas

   Overlay fixo, centralizado, sobre .jl-z-modal. Some do fluxo do documento
   via [hidden] em repouso — sem JS, os botões que abririam isto continuam
   sendo <a href="#precos"> normais (ver comentário no index.html) e este
   bloco nunca é exibido, então não pesa nada em quem não roda o script.

   Duas camadas de transição, deliberadamente:
     1. [hidden] -> sem [hidden]           (display: none -> grid, instantâneo)
     2. data-open="false" -> data-open="true"  (opacidade/escala, 320ms)
   landing.js remove o [hidden] primeiro e só no quadro seguinte liga
   data-open="true" — juntando as duas etapas no mesmo passo, o navegador
   não tem quadro nenhum para pintar o estado de repouso e a transição
   nunca dispara (a mesma razão pela qual .lp-reveal liga sua classe depois
   do primeiro cálculo do IntersectionObserver, não antes).
   -------------------------------------------------------------------------- */
.lp-selector {
  position: fixed;
  inset: 0;
  z-index: var(--jl-z-modal);
  display: grid;
  place-items: center;
  padding: var(--jl-space-5);
}

.lp-selector[hidden] { display: none; }

/* Trava a rolagem por trás do modal — landing.js liga/desliga esta classe
   no <html> junto com abrir()/fechar(). */
html.lp-selector-aberto { overflow: hidden; }

.lp-selector__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 8, 40, 0.62);
  backdrop-filter: blur(6px) saturate(120%);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  opacity: 0;
  transition: opacity var(--jl-dur-slow) var(--jl-ease-out);
}

.lp-selector__panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-3);
  width: min(640px, 100%);
  max-height: min(712px, 100dvh - var(--jl-space-6));
  overflow-y: auto;
  padding: var(--jl-space-5);
  border-radius: var(--jl-radius-2xl);
  background: var(--surface-card);
  color: var(--text-primary);
  box-shadow: var(--jl-shadow-lg);
  opacity: 0;
  scale: 0.96;
  translate: 0 12px;
  transition:
    opacity var(--jl-dur-slow) var(--jl-ease-out),
    scale var(--jl-dur-slow) var(--jl-ease-out),
    translate var(--jl-dur-slow) var(--jl-ease-out);
}

.lp-selector[data-open="true"] .lp-selector__backdrop { opacity: 1; }
.lp-selector[data-open="true"] .lp-selector__panel { opacity: 1; scale: 1; translate: 0 0; }

.lp-selector__close {
  position: absolute;
  top: var(--jl-space-4);
  right: var(--jl-space-4);
  z-index: 2;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-subtle);
  border-radius: var(--jl-radius-pill);
  background: var(--surface-sunk);
  color: var(--text-secondary);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--jl-dur-base) var(--jl-ease-out), color var(--jl-dur-base) var(--jl-ease-out);
}

.lp-selector__close:hover { background: var(--surface-silver); color: var(--text-primary); }

/* Medidor — mesma lógica de número tabular do .lp-flow-meter (ver "Como
   funciona"), só que a barra avança por PERGUNTA RESPONDIDA, não por
   rolagem: quem escreve a largura é o atributo data-step do painel, não
   JS calculando pixel a pixel. No passo 3 (resultado) o medidor some —
   ali não há mais pergunta pendente, só o cartão e as ações. */
/* padding-right reserva o espaço do botão fechar (.lp-selector__close):
   ele é position:absolute, então não empurra o medidor sozinho — sem
   este respiro, o rótulo e a barra de progresso (que esticam até a borda
   do painel por causa do align-items:stretch padrão do flex) passavam
   POR BAIXO do "×". 36px de largura do botão + 16px (var(--jl-space-4),
   o "right" dele) + 8px de folga = 60px, com margem de sobra. */
.lp-selector__meter { display: flex; flex-direction: column; gap: var(--jl-space-2); padding-right: 60px; }
.lp-selector__meter-label { margin: 0; font-size: var(--jl-size-caption); color: var(--text-secondary); }
.lp-selector__meter-track { height: 3px; border-radius: var(--jl-radius-pill); background: var(--border-subtle); overflow: hidden; }
.lp-selector__meter-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--action-primary);
  transition: width var(--jl-dur-slow) var(--jl-ease-out);
}

.lp-selector__panel[data-step="1"] .lp-selector__meter-fill { width: 50%; }
.lp-selector__panel[data-step="2"] .lp-selector__meter-fill { width: 100%; }
.lp-selector__panel[data-step="3"] .lp-selector__meter { display: none; }

.lp-selector__stage { display: grid; }

.lp-selector__step {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-2);
  grid-area: 1 / 1;
}

.lp-selector__step[hidden] { display: none; }

/* Entrada deslizando da direita ao avançar, da esquerda ao voltar — a
   mesma leitura de "passo seguinte" / "passo anterior" que uma trilha
   física teria. data-dir vive no .lp-selector__stage (não no passo), porque
   é o gesto de TROCA que tem direção, não o passo em si. */
.lp-selector__step:not([hidden]) { animation: lp-selector-in-fwd var(--jl-dur-slow) var(--jl-ease-out); }
.lp-selector__stage[data-dir="back"] .lp-selector__step:not([hidden]) { animation-name: lp-selector-in-back; }

@keyframes lp-selector-in-fwd { from { opacity: 0; translate: 18px 0; } to { opacity: 1; translate: 0 0; } }
@keyframes lp-selector-in-back { from { opacity: 0; translate: -18px 0; } to { opacity: 1; translate: 0 0; } }

.lp-selector__back {
  align-self: flex-start;
  border: 0;
  padding: 0;
  background: none;
  color: var(--text-secondary);
  font-family: var(--jl-font-body);
  font-size: var(--jl-size-body-sm);
  font-weight: var(--jl-weight-semibold);
  cursor: pointer;
  transition: color var(--jl-dur-base) var(--jl-ease-out);
}

.lp-selector__back:hover { color: var(--text-primary); }

/* Pilha vertical, de propósito: cada opção é sempre uma linha inteira,
   nunca 2 colunas lado a lado — pedido explícito, mesmo com 5 opções do
   lado pessoa física.

   A altura de cada linha é o parâmetro delicado desta tela: apertada
   demais, as 5 opções leem como uma lista empilhada e não como 5 escolhas
   separadas; folgada demais, o passo 2 estoura a altura do painel e volta
   a pedir rolagem — que é justamente o que este seletor existe pra evitar.
   Os valores abaixo (gap, padding, ícone e entrelinha em
   .lp-selector__option) foram calibrados juntos contra o pior caso real:
   5 opções visíveis, no viewport mais curto que a página atende. Mexer em
   um deles pede remedir os outros. */
.lp-selector__options {
  display: flex;
  flex-direction: column;
  gap: var(--jl-space-3);
}

/* [hidden] some por JS quando a opção não se aplica a quem=pj (ver
   data-somente-pf em index.html / iniciarSeletor em landing.js). Precisa
   de regra própria: CSS de autor tem prioridade sobre o display:none que
   o próprio navegador aplicaria a [hidden] sozinho, então sem isto o
   .lp-selector__option { display:flex } logo abaixo venceria e a opção
   continuaria visível mesmo com o atributo presente. */
.lp-selector__option[hidden] { display: none; }

.lp-selector__option {
  display: flex;
  align-items: center;
  gap: var(--jl-space-4);
  width: 100%;
  padding: var(--jl-space-3) var(--jl-space-4);
  border: 1.5px solid var(--border-default);
  border-radius: var(--jl-radius-lg);
  background: var(--surface-card);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--jl-dur-base) var(--jl-ease-out),
    background-color var(--jl-dur-base) var(--jl-ease-out),
    transform var(--jl-dur-fast) var(--jl-ease-out);
}

.lp-selector__option:hover { border-color: var(--border-brand); background: var(--surface-sunk); transform: translateY(-1px); }
.lp-selector__option:active { transform: translateY(0); }

/* Destaque do A1 — a opção mais vendida (ver comentário no index.html).
   Contorno cheio mais grosso em marinho, não uma barra lateral colorida:
   a moldura inteira é o que marca "este é o recomendado" sem inventar
   ornamento novo. O anel externo a 10% é o mesmo gesto do
   .jl-btn--emphasis (anel prata em volta do botão de ênfase), reduzido —
   dá presença sem virar sombra pesada numa lista de 5 itens.

   :hover mantém o contorno em marinho pleno: sem isto, a opção destacada
   ficaria visualmente IGUAL às outras no hover (todas fecham em
   --border-brand), perdendo o destaque justo no momento em que o
   visitante está com o cursor nela. */
.lp-selector__option--destaque {
  border-width: 2px;
  border-color: var(--border-brand);
  box-shadow: 0 0 0 3px rgba(11, 15, 74, 0.1);
}

.lp-selector__option--destaque:hover { background: var(--surface-brand-soft); }

.lp-selector__option-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--jl-radius-md);
  background: var(--surface-brand-soft);
  color: var(--text-brand);
}

.lp-selector__option-icon svg { width: 19px; height: 19px; }

.lp-selector__option-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  min-width: 0;
}

/* Título e selo na mesma linha. flex-wrap porque em tela estreita o selo
   desce sozinho em vez de espremer o título contra ele. */
.lp-selector__option-headline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--jl-space-2);
}

.lp-selector__option-title {
  font-family: var(--jl-font-display);
  font-weight: var(--jl-weight-semibold);
  line-height: 1.3;
  color: var(--text-primary);
}

/* O selo reaproveita .jl-badge--solid --upper, o MESMO par usado no
   "Mais vendido" dos cartões de #precos: é a mesma afirmação sobre o
   mesmo produto, então usa o mesmo vocabulário. Só encolhe — aqui ele
   convive com um título na mesma linha, não abre um cartão inteiro. */
.lp-selector__option-tag {
  padding: 1px var(--jl-space-2);
  font-size: 10px;
  letter-spacing: 0.1em;
}

.lp-selector__option-desc {
  font-size: var(--jl-size-caption);
  line-height: 1.35;
  color: var(--text-secondary);
}

.lp-selector__option-arrow {
  flex: none;
  color: var(--text-tertiary);
  transition: translate var(--jl-dur-base) var(--jl-ease-out), color var(--jl-dur-base) var(--jl-ease-out);
}

.lp-selector__option:hover .lp-selector__option-arrow { translate: 4px 0; color: var(--text-brand); }

.lp-selector__result-head { display: flex; flex-direction: column; gap: var(--jl-space-2); align-items: flex-start; }

/* O cartão do resultado é o MESMO .jl-plan da fileira de preços — só assim
   o produto que o seletor recomenda lê como o mesmo objeto que está logo
   ali embaixo em #precos, não uma versão paralela inventada pra caber no
   modal. data-selected="true" reaproveita o destaque que .lp-spotlight
   usa nos dois cartões "Mais vendido"/"Mais escolhido".

   Três ajustes SÓ dentro do modal, sem tocar em .jl-plan (que continua
   servindo #precos como está): o ícone do produto (.lp-plan__icon) mede a
   própria altura em cqi — 36% da largura do CARTÃO — porque foi desenhado
   pra caber nos ~260-305px estreitos da fileira de preços. O painel do
   seletor tem 640px: o mesmo cqi ali batia no teto do clamp (100px) e
   sozinho já empurrava o passo 3 pra fora da altura de qualquer notebook,
   obrigando rolagem bem no passo que define o produto — o oposto do que
   este modal existe pra fazer. Trava-se a altura em 64px (o piso do
   clamp original) em vez de deixar o cqi correr solto num container mais
   largo do que ele foi calibrado pra medir. padding/gap também encolhem
   dois degraus — o cartão aqui é a ÚNICA coisa na tela, não precisa do
   mesmo respiro que tem ao lado de mais três na fileira, e o passo 3
   ainda carrega o cabeçalho do resultado e as duas ações por cima dele
   dentro do mesmo painel de altura travada. */
.lp-selector__plan { width: 100%; }
.lp-selector__plan.jl-plan { gap: var(--jl-space-2); padding: var(--jl-space-4); }
.lp-selector__plan .lp-plan__icon { height: 64px; }
.lp-selector__plan .jl-checklist { gap: var(--jl-space-2); }

/* --jl-lh-body (1.65) é pensado pra parágrafo corrido — nestas duas linhas
   curtas (descrição de 1-2 linhas, item de lista de 3-6 palavras) ele só
   infla altura sem ganhar legibilidade nenhuma. 1.3-1.35 é o suficiente
   pra não parecer apertado e ainda devolve alguns px por linha, que somam
   rápido quando multiplicados por 3 itens de checklist. */
.lp-selector__plan .jl-plan__desc { line-height: var(--jl-lh-heading); }
.lp-selector__plan .jl-checklist__item { line-height: 1.3; }
.lp-selector__plan .jl-btn { padding-block: var(--jl-space-3); padding-inline: var(--jl-space-5); }

.lp-selector__result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jl-space-3);
  align-items: center;
  justify-content: space-between;
}

/* Abaixo de ~560px o painel vira folha inferior: mais fácil de alcançar
   com o polegar do que um modal centralizado, e evita a barra de
   endereço do navegador mobile comendo a margem superior. */
@media (max-width: 560px) {
  .lp-selector { padding: 0; align-items: flex-end; }

  .lp-selector__panel {
    width: 100%;
    max-height: 92dvh;
    border-radius: var(--jl-radius-2xl) var(--jl-radius-2xl) 0 0;
    padding: var(--jl-space-5) var(--jl-space-4) var(--jl-space-6);
  }

  .lp-selector[data-open="true"] .lp-selector__panel { translate: 0 0; }
  .lp-selector__panel { translate: 0 24px; }

  .lp-selector__result-actions { flex-direction: column; align-items: stretch; }
  .lp-selector__result-actions .jl-btn { width: 100%; }

  /* O respiro extra que as opções ganharam no desktop não cabe aqui, e a
     razão não é o padding: nesta largura os títulos e as descrições
     QUEBRAM em 2 linhas (a coluna de texto sobra com ~230px depois de
     ícone, seta e recuos), e é a quebra que multiplica a altura — 5
     opções passavam de 435px só de linha, contra 613px de folha inteira.
     Escondendo a descrição, o título fica com a linha inteira pra si e
     raramente quebra, o que devolve altura suficiente pra manter o padding
     folgado do desktop nas 5 opções sem rolagem. A descrição é reforço:
     o título ("Certificado digital em arquivo", "No celular, ou em vários
     aparelhos"...) já carrega a decisão sozinho, e o selo "Mais vendido"
     continua visível. O ícone encolhe junto porque, sem a segunda linha
     de texto, é ele que passa a ditar a altura da linha. */
  .lp-selector__option-desc { display: none; }
  .lp-selector__option-icon { width: 34px; height: 34px; }
  .lp-selector__option-icon svg { width: 17px; height: 17px; }
  .lp-selector__options { gap: var(--jl-space-2); }

  /* Mesma lógica: na tela mais estreita, o checklist de 3 benefícios do
     cartão de resultado é reforço que o visitante já viu implicitamente
     ao responder as duas perguntas — preço, cupom e o botão de WhatsApp
     são o que decide a ação, então ficam. O checklist completo continua
     em #precos pra quem clicar em "Comparar os 4 certificados". */
  .lp-selector__plan .jl-checklist { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .lp-stage__guilloche { animation: none; }
  .lp-hero__shine { animation: none; }
  .lp-medal::after { animation: none; opacity: 0; }
  .lp-offer::after { animation: none; opacity: 0; }
  .lp-cert::after { animation: none; opacity: 0; }
  .lp-cert__ring::before { animation: none; }
  .lp-cert { transform: none; opacity: 1; translate: none; scale: none; animation: none; }
  .js-reveal .lp-reveal { opacity: 1; translate: none; transition: none; }
  .lp-enter > * { opacity: 1; translate: none; animation: none; }
  .lp-seal-float { animation: none; }
  .lp-spotlight::after { transition: none; }
  /* A trilha do processo não é animada aqui: landing.js nem chega a ligar o
     modo dirigido por rolagem com movimento reduzido, então ela fica no
     estado de repouso — cinco etapas concluídas, trilho cheio, tudo legível.
     Estas duas linhas só garantem que nada transicione se o estado mudar. */
  .lp-flow__node,
  .lp-flow__node::before,
  .lp-flow__num { transition: none; }
  .lp-linked::before { animation: none; box-shadow: 0 0 0 3px rgba(11, 15, 74, 0.16); }
  .lp-linked::after { animation: none; background-position: 0 0; }
  .lp-selector__step:not([hidden]) { animation: none; }
}
