/*
 * 05_landing.css — BLOCO LANDING
 * ═══════════════════════════════════════════════════════════════════════════
 * As DUAS primeiras telas que alguém vê: `/` no host raiz (a página comercial
 * da Elevô) e `/` no host do tenant (a porta da empresa cliente).
 *
 * ─── O QUE NÃO ESTÁ AQUI, E ESTÁ DE PROPÓSITO ──────────────────────────────
 *
 * Botão, cartão, aviso, selo, medidor, grade, `.botoes`, `.heroi`, `.porta`,
 * o cabeçalho e o rodapé públicos: TUDO isso é da onda D e está em
 * 10_componentes.css e 20_navegacao.css. Este arquivo não redefine nenhum
 * deles — nem "só a cor", nem "só o padding". O que existe aqui é o que uma
 * landing tem e uma tela de produto não tem: ritmo vertical longo, seção com
 * etiqueta, cartão que abre detalhe, uma arte e uma chamada final.
 *
 * ─── POR QUE TODO BLOCO DAQUI COMEÇA COM `landing-` ────────────────────────
 *
 * Porque a ordem na cascata NÃO protege ninguém, e este arquivo já custou uma
 * tela por acreditar que protegia. O número 05 põe esta folha antes de todas
 * as outras, mas a cascata só arbitra PROPRIEDADE DISPUTADA: se dois arquivos
 * usam o mesmo nome de classe e este declara uma propriedade que o outro não
 * declara, quem vence é este — não importa a ordem.
 *
 * Foi exatamente o que aconteceu. Este arquivo declarava `.passos`, nome que
 * `30_identidade.css` já usava na trilha dos quatro passos do paredão
 * (§13.4, `perfis/completar`). Lá a trilha é `display:flex; flex-wrap:wrap` e
 * nenhum `flex-direction`; o `flex-direction: column` daqui era o único
 * declarante e valia — quatro elos empilhados, 152 px de trilha vertical
 * empurrando o formulário da tela de maior abandono do produto. Nenhum teste
 * pegou: CSS não tem teste de unidade.
 *
 * Daí a regra, sem exceção: TODO bloco que só existe na landing carrega o
 * prefixo `landing-` (ou `arte-`), mesmo quando não há colisão hoje.
 *
 * ─── O HERÓI NÃO USA MAIS `.heroi` ─────────────────────────────────────────
 *
 * A versão anterior herdava `.heroi` da onda D, que é `text-align: center` e
 * `padding: var(--esp-16) 0 var(--esp-12)`. Daí saíram DOIS dos três defeitos
 * que o Sergio mediu na tela: quase uma dobra inteira de espaço morto antes da
 * primeira palavra (4 rem de `.heroi` + 2 rem de `.conteudo--publico`), e um
 * herói centralizado seguido de sete seções à esquerda.
 *
 * O bloco novo `.landing-heroi` é próprio, à ESQUERDA como o resto da página,
 * com respiro de topo curto e duas colunas no desktop. `.heroi` da onda D
 * continua intacto e continua sendo o da porta do tenant.
 *
 * ─── MOBILE-FIRST DE VERDADE ───────────────────────────────────────────────
 *
 * Metade de quem abrir isto abre no celular, porque lê o link no WhatsApp.
 * Toda regra base é a do celular; as media queries (40/48/64rem) só
 * ACRESCENTAM colunas e respiro. Nenhum `min-width` em pixel.
 *
 * ─── MOVIMENTO: LEIA ANTES DE MEXER ────────────────────────────────────────
 *
 * O motor é do bloco MOTOR e mora em `03_movimento.css`, nos controllers
 * `revelar`/`contador`/`modal` e em `movimento_helper.rb`. A landing NÃO
 * reimplementa nada disso — e não é só higiene: a regra nº 1 daquele motor é
 * que o conteúdo NASCE VISÍVEL e só o JS esconde, depois de confirmar que há
 * `IntersectionObserver`. Uma revelação escrita em CSS puro (que esta folha
 * chegou a ter, com `animation-timeline: view()`) não consegue obedecer a
 * isso: ela esconde antes de saber se vai conseguir mostrar.
 *
 * Então a divisão é:
 *
 *   revelação ao rolar ..... helpers `revelar`/`revelar_item` na view
 *   número que conta ....... helper `contar_ate` na view
 *   cartão que levanta ..... `.cartao--acionavel` (folha 03)
 *   ENTRADA DO HERÓI ....... aqui. CSS puro, na carga, sem JS — é a primeira
 *                            dobra, e o motor de propósito não anima o que já
 *                            está na tela (evitar o pisca vale mais).
 *   SEQUÊNCIA DO DIAGRAMA .. aqui. Também CSS puro, na carga.
 *
 * As duas regras duras da marca valem em cada linha do que sobrou: anima-se SÓ
 * `transform` e `opacity`, e TODO quadro `100%` é o estado de repouso. Isso não
 * é estética: `02_base.css` corta toda animação para 0,01 ms sob
 * `prefers-reduced-motion`, e o que fica na tela é exatamente o quadro 100%.
 * Além disso, toda animação desta folha está DENTRO de
 * `@media (prefers-reduced-motion: no-preference)` — quem pediu menos
 * movimento não recebe animação nenhuma para ser cortada. Há teste medindo as
 * três coisas em `test/integration/landing_test.rb`.
 */

/* ═══ RITMO VERTICAL ══════════════════════════════════════════════════════ */

/* A única coisa que a landing tem e nenhuma tela do produto tem: distância
   generosa entre blocos de assunto. `gap` e não `margin` nos filhos — assim
   nenhuma seção precisa saber quem vem antes ou depois dela. */
.landing {
  display: flex;
  flex-direction: column;
  gap: var(--esp-12);
  /* REDE DE BAIXO CONTRA ROLAGEM HORIZONTAL, e ela existiu por um defeito
     medido: a arte do white label entrava com `revelar--esquerda`, que é
     `translate3d(20px,0,0)` — e a borda direita de layout dela, a 390 px de
     janela, já estava em 359. scrollWidth 379 contra clientWidth 375, o
     celular do público-alvo rolando de lado. Pior: só para quem TEM JS, e só
     até a pessoa rolar até a seção, o que fazia a medição feita no fim da
     página dar limpa.

     A causa foi corrigida na view (`:suave` naquela arte). Isto aqui é o que
     impede a próxima: qualquer revelação lateral, qualquer sombra, qualquer
     ::after de um elemento colado na margem para de exportar rolagem.

     `clip` e NÃO `hidden`: `overflow-x: hidden` força o eixo Y a `auto` e
     cria um contêiner de rolagem — o que mataria `position: sticky` de
     qualquer descendente e trocaria o scroll da janela pelo de uma caixa. Os
     13 painéis de detalhe são `position: fixed` e vivem FORA de `.landing`,
     de propósito, então nada aqui os recorta. */
  overflow-x: clip;
}

@media (min-width: 48rem) {
  .landing { gap: var(--esp-16) }
}

/* A etiqueta (o "sobre-título") de cada seção. Caixa alta com espaçamento de
   letra é legível a 12 px; caixa alta SEM espaçamento não é. */
.landing__etiqueta {
  margin: 0 0 var(--esp-3);
  color: var(--cor-marca);
  font-size: var(--texto-xs);
  font-weight: var(--peso-forte);
  letter-spacing: var(--espacamento-etiqueta);
  text-transform: uppercase;
}

/* A ressalva, a letra miúda de parágrafo, o "antes que você pergunte".
   `--texto-suave` e não `--texto-tenue`: isto ainda é para ser LIDO (9,4:1
   contra o fundo, contra os 6,2:1 do tenue, que é rótulo de campo). */
.landing__nota {
  display: flex;
  align-items: flex-start;
  gap: var(--esp-2);
  margin: 0;
  color: var(--texto-suave);
  font-size: var(--texto-sm);
  line-height: var(--altura-solta);
}
.landing__nota-icone { flex: none; margin-top: 0.15rem; color: var(--cor-marca) }

/* O rótulo de botão da onda D é `white-space: nowrap`, e está certo numa barra
   de ações de admin: lá o texto é "Salvar" e quebrar um botão em duas linhas
   estraga a linha da tabela. Na landing é risco MEDIDO — num celular de 360 px
   um rótulo comprido rolava a página na horizontal. A altura do botão é
   `min-height`, então o alvo de toque de 48 px continua de pé em duas linhas:
   é por isso que este afrouxamento é seguro aqui e não seria numa tabela. */
.landing .botao__rotulo { white-space: normal }

/* ═══ HERÓI ═══════════════════════════════════════════════════════════════ */

/* Respiro de topo CURTO: `.conteudo--publico` já dá 2 rem e o cabeçalho é
   transparente. Era aqui que estava a dobra vazia da versão reprovada. */
.landing-heroi {
  display: grid;
  gap: var(--esp-8);
  padding: var(--esp-2) 0 0;
  align-items: center;
}

/* A coluna de texto tem nome PRÓPRIO — `__coluna`, não `__texto`. Ela e o
   parágrafo do herói já dividiram o mesmo nome, e o preço foi invisível na
   revisão e visível na tela: a coluna herdava `color: var(--texto-suave)` e o
   `<h1>` da página comercial saía cinza-claro em vez de branco, além de a
   coluna ganhar o `max-width: 34rem` que era do parágrafo e estreitar a
   grade. Dois elementos com papéis diferentes, dois nomes. */
.landing-heroi__coluna { min-width: 0 }

.landing-heroi__titulo {
  margin: 0 0 var(--esp-5);
  max-width: 20ch;
  font-size: var(--texto-3xl);
  line-height: var(--altura-apertada);
  letter-spacing: var(--espacamento-titulo);
  text-wrap: balance;
}

/* O parágrafo do herói tinha `max-width: var(--largura-leitura)` (38 rem) e
   ficava estreito e mal quebrado no desktop. Aqui a medida é 34 rem no
   empilhado e, no desktop, quem manda é a COLUNA da grade — que é o jeito
   certo: a medida acompanha o layout em vez de brigar com ele. */
.landing-heroi__texto {
  margin: 0 0 var(--esp-6);
  max-width: 34rem;
  color: var(--texto-suave);
  font-size: var(--texto-lg);
  line-height: var(--altura-solta);
}

/* UMA SENTENÇA POR LINHA. A view parte `heroi.titulo` no ponto final e põe
   cada frase aqui dentro; `display: block` é tudo o que falta. Antes disso a
   manchete saía em três linhas de 427/321/340 px, com "coisa. Prove"
   terminando a linha 2 — as duas sentenças atravessando as quebras.

   E é por isso que a coluna de 1,15fr continua de pé: quem precisava de
   627 px era a frase INTEIRA numa linha só; a maior sentença isolada mede
   427 px e cabe folgada nos 529 px da coluna. Os dois botões do herói somam
   509 px e é por eles que a coluna não pode encolher. */
.landing-heroi__frase {
  display: block;
  /* `text-wrap: balance` do <h1> INVERTIA o conserto quando herdado aqui: cada
     sentença virou um bloco próprio e o balanceador quebrou "Ensine qualquer
     coisa." em duas linhas ("Ensine" / "qualquer coisa.") dentro de uma coluna
     de 529 px em que a frase inteira mede 427. Balanceamento é para um bloco
     de texto longo; aqui cada bloco é UMA FRASE, e o lugar certo de quebrar
     ela já escolheu. `wrap` e não `normal`: `normal` não é valor de
     `text-wrap` e é descartado em silêncio — a manchete continuava em três
     linhas e o CSS parecia certo. */
  text-wrap: wrap;
}

.landing-heroi__botoes { margin-bottom: var(--esp-6) }
.landing-heroi__nota { max-width: 34rem }

@media (min-width: 48rem) {
  .landing-heroi { padding-top: var(--esp-6) }
  .landing-heroi__titulo { font-size: var(--texto-4xl) }
}

@media (min-width: 64rem) {
  /* A coluna do texto é MAIOR que a da arte, e o número saiu de medição, não
     de gosto: os dois botões do herói somam 509 px com o tamanho `grande` da
     onda D, e uma coluna de 1fr no conteúdo de 64rem dá 492 px — os botões
     quebravam em duas linhas no desktop, que é a cara de peça mal fechada.
     1,15fr entrega 566 px e a barra fica numa linha só. Se um dia o rótulo de
     um botão crescer, é este número que se mexe. */
  .landing-heroi {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--esp-10);
  }
  /* 40 px, e não os 48 px do `--texto-4xl`. A conta é de MEDIDA, não de gosto:
     a coluna do herói tem 529 px e "Ensine qualquer coisa." mede 577 px a
     48 px — a primeira sentença não cabia numa linha, e era daí que saíam as
     três linhas com as duas frases atravessando as quebras. A 40 px a mesma
     sentença mede 481 px e sobra folga.

     A alternativa era alargar a coluna para ~600 px, e ela cobra da arte: o
     diagrama cairia de 391 para ~340 px de largura, e as notas dele ("medido
     no servidor") são texto de 10 unidades de viewBox — encolher a figura é
     encolher a legenda. 48 px num bloco de 529 px também é tipografia
     apertada: dá 11 caracteres por linha. Entre uma manchete 17% menor e uma
     figura ilegível, a manchete cede. */
  .landing-heroi__titulo { font-size: 2.5rem }
  /* A arte vai para a segunda coluna, mas no DOM ela vem depois do texto —
     que é a ordem de leitura certa e a ordem certa no celular. */
  .landing-heroi__arte { order: 2 }
}

/* ═══ SEÇÃO ═══════════════════════════════════════════════════════════════ */

.landing-secao {
  display: flex;
  flex-direction: column;
  gap: var(--esp-6);
}

/* A medida do cabeçalho é curta de propósito: título e chamada de seção são
   para bater o olho, não para ler parágrafo. Era 46 rem — 736 px medidos, que
   a 18 px dão 75 a 80 caracteres por linha, acima da faixa confortável. 40 rem
   dá 640 px e ~66 caracteres, que é o meio da faixa. */
.landing-secao__cabecalho { max-width: 40rem }

.landing-secao__titulo {
  margin: 0;
  font-size: var(--texto-2xl);
  letter-spacing: var(--espacamento-titulo);
  text-wrap: balance;
}
.landing-secao__chamada {
  margin: var(--esp-4) 0 0;
  color: var(--texto-suave);
  font-size: var(--texto-lg);
  line-height: var(--altura-solta);
}

@media (min-width: 48rem) {
  .landing-secao__titulo { font-size: var(--texto-3xl) }
  .landing-secao { gap: var(--esp-8) }
}

/* Texto de um lado, arte do outro — SÓ a partir de 64rem. Abaixo disso é uma
   coluna e a arte vai para o fim: no celular, empurrar 200 px de desenho para
   cima do primeiro parágrafo custa a rolagem inteira da seção. */
.landing-secao--par { display: grid; gap: var(--esp-8); align-items: center }
.landing-secao--par .landing-secao__arte { order: 2 }
.landing-secao--par .landing-secao__texto { display: flex; flex-direction: column; gap: var(--esp-5) }
.landing-secao--par .landing-secao__chamada { margin-top: 0 }

@media (min-width: 64rem) {
  .landing-secao--par { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: var(--esp-12) }
}

/* A seção quieta: ressalva não é argumento de venda e não ganha o mesmo peso
   tipográfico do resto da página. */
.landing-secao--quieta .landing-secao__titulo { font-size: var(--texto-xl) }
@media (min-width: 48rem) {
  .landing-secao--quieta .landing-secao__titulo { font-size: var(--texto-2xl) }
}

/* ═══ CARTÃO QUE ABRE DETALHE ═════════════════════════════════════════════
   O padrão CARD → MODAL da marca (§3). O cartão INTEIRO é o alvo — não um
   "saiba mais" de 14 px no rodapé dele: o dedo de quem lê no celular acerta o
   cartão, e quem usa teclado recebe UM tab por cartão em vez de dois.        */

.landing-cartoes { align-items: stretch }

/* A PELE do cartão é `.cartao` (folha 10) e a ELEVAÇÃO ao dedo é
   `.cartao--acionavel` (folha 03, bloco MOTOR) — nenhuma das duas se repete
   aqui. Este bloco só acrescenta o que é da landing: o empilhamento interno, o
   índice decorativo e a linha de ação colada no rodapé do cartão. */
.landing-cartao {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  overflow: hidden;
}

/* ── A COLISÃO DE `transition`, MEDIDA NO NAVEGADOR E CONSERTADA AQUI ─────
   Nove cartões desta página — os 3 do argumento e os 6 do catálogo — entravam
   SEM revelação nenhuma: os seis do catálogo saltavam de opacidade 0 para 1
   em UM quadro (t=404 ms `[0,0,0,0,0,0]`, t=464 ms `[1,1,1,1,1,1]`), sem fade
   e sem cascata, com `--revelar-atraso` calculado pelo controller (0, 60, 120,
   180, 240, 300 ms) e lido por ninguém.

   A causa é de cascata, não de JS. `.revelar` (03_movimento.css) declara a
   SHORTHAND `transition: opacity …, transform …`. `.cartao--acionavel` (mesma
   folha, mais adiante) declara a SHORTHAND `transition: transform, box-shadow,
   border-color` para o hover. Mesma especificidade, e shorthand não compõe:
   a segunda SUBSTITUI a primeira inteira. Some `opacity`, some o atraso.

   Por que só estes nove: em `passos` e em `operacao` quem recebe `.revelar` é
   o `<li>` ou um cartão sem `--acionavel`, e lá não há colisão — os 4 e os 3
   sempre animaram. Medido, e por isso "16 de 19" da crítica é 9 de 19.

   O conserto local é declarar a transição COMPLETA aqui, numa folha que vem
   depois da 03. E a divisão de trabalho entre as propriedades é o que faz as
   duas coisas conviverem sem uma atrapalhar a outra:

     opacity   → é da ENTRADA, e só. Leva a duração longa e, com ela, o
                 `--revelar-atraso` que dá a cascata.
     transform → é do DEDO. Leva a duração de hover e NENHUM atraso — porque
                 `--revelar-atraso` fica na propriedade inline do elemento
                 depois da revelação, e um hover com 300 ms de atraso parece
                 que o cartão não pegou.

   É por isso que as duas grades trocaram `:cresce` por `:suave` na view: sem
   deslocamento nem escala na entrada, `transform` fica livre para o hover e a
   cascata inteira é carregada pela opacidade, que é o que o olho lê.

   ⚠ ISTO É REMENDO LOCAL. A colisão é entre duas classes da folha 03 e vale
   para todo `.cartao--acionavel` revelado do produto, não só para a landing.
   O conserto de verdade é do bloco MOTOR e está no relatório desta onda. */
.landing-cartao,
.landing-passo__cartao {
  transition:
    opacity var(--tempo-lento) var(--curva-entrada) var(--revelar-atraso, 0ms),
    transform var(--tempo-normal) var(--curva-entrada),
    box-shadow var(--tempo-normal) var(--curva-entrada),
    border-color var(--tempo-rapido) var(--curva-padrao);
}

.landing-cartao__titulo { font-size: var(--texto-lg) }
/* O gatilho é o link do título, e é ele que estica o `::after` por cima do
   cartão inteiro (regra da folha 03). Aqui só se tira o sublinhado e se herda
   a cor: o cartão é o alvo, não um link azul no meio do texto. */
.landing-cartao__titulo .cartao__gatilho { color: inherit; text-decoration: none }
.landing-cartao__texto {
  margin: 0;
  color: var(--texto-suave);
  font-size: var(--texto-sm);
  line-height: var(--altura-solta);
}

/* `margin-top: auto` cola a linha de ação no rodapé do cartão, e é o que
   mantém os três (ou seis) cartões de uma fileira com a ação na mesma altura
   mesmo com resumos de tamanhos diferentes. */
.landing-cartao__acao {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  margin-top: auto;
  padding-top: var(--esp-3);
  color: var(--cor-marca);
  font-size: var(--texto-sm);
  font-weight: var(--peso-medio);
}
.landing-cartao__seta { transition: transform var(--tempo-rapido) var(--curva-saida) }

/* O índice decorativo "01 02 03" SAIU, e a medida é o motivo: ele era
   `position: absolute` no canto de um cartão de 309 px com `--texto-3xl`, e o
   `max-width: calc(100% - 3rem)` que ele impunha ao título deixava 219 px de
   linha — os três títulos do argumento quebravam em duas linhas por causa de
   um enfeite. Três cartões debaixo de "a Elevô prova em três etapas" já se
   contam sozinhos. */


/* A seta anda quando o cartão inteiro recebe o dedo ou o teclado. `:has` e não
   `:hover` no link: quem acende é o CARTÃO (a área clicável é ele), e o link
   focado por teclado precisa mover a mesma seta. */
@media (hover: hover) {
  .cartao--acionavel:hover .landing-cartao__seta { transform: translateX(0.2rem) }
}
.cartao--acionavel:has(:focus-visible) .landing-cartao__seta { transform: translateX(0.2rem) }

/* ═══ OS TRÊS TETOS DO SISTEMA ════════════════════════════════════════════ */

.landing-numeros {
  padding-top: var(--esp-8);
  border-top: 1px solid var(--borda);
}
.landing-numeros__titulo {
  margin: 0 0 var(--esp-6);
  max-width: 46rem;
  color: var(--texto-tenue);
  font-size: var(--texto-sm);
}
.landing-numeros__lista {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--esp-6);
}
@media (min-width: 48rem) {
  .landing-numeros__lista { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--esp-8) }
}

.landing-numero__valor {
  margin: 0;
  color: var(--cor-marca);
  font-size: var(--texto-4xl);
  font-weight: var(--peso-forte);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
/* `<dd>` nasce com 40 px de recuo no navegador; aqui o alinhamento é do
   número, não do agente de usuário. */
.landing-numero__rotulo {
  margin: var(--esp-3) 0 0;
  color: var(--texto-suave);
  font-size: var(--texto-sm);
  line-height: var(--altura-solta);
}

/* ═══ OS QUATRO PASSOS ════════════════════════════════════════════════════ */

/* É `<ol>` na view: a ordem é a informação, e o leitor de tela já anuncia
   "item 3 de 4". O número desenhado é decorativo (`aria-hidden`). */
.landing-passos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--esp-4);
}
@media (min-width: 64rem) {
  .landing-passos { grid-template-columns: repeat(2, minmax(0, 1fr)) }
}

.landing-passo { display: flex }

.landing-passo__cartao {
  flex: 1;
  display: flex;
  /* `stretch`, e o número se desalinha sozinho com `align-self`. Com
     `flex-start` no contêiner o corpo do passo não esticava, o
     `margin-top: auto` do "Ver detalhe" não tinha altura sobrando para empurrar
     nada, e os quatro passos da grade 2×2 fechavam a linha de ação em quatro
     alturas diferentes. Medido no navegador. */
  align-items: stretch;
  gap: var(--esp-4);
}

/* Círculo com o número. `--cor-marca-forte` + `--cor-marca-contraste` é o par
   que a §15.2 garante em 4,5:1 para QUALQUER hex de tenant — o mesmo par do
   botão primário. Pintar o número com `--cor-marca` sobre o preenchimento
   seria a mesma cor sobre ela mesma no dia em que o cliente escolhesse um
   azul claro. */
.landing-passo__numero {
  flex: none;
  align-self: flex-start;
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: var(--raio-redondo);
  background: var(--cor-marca-forte);
  color: var(--cor-marca-contraste);
  font-size: var(--texto-lg);
  font-weight: var(--peso-forte);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.landing-passo__corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--esp-2) }
.landing-passo__titulo { font-size: var(--texto-lg) }
.landing-passo__titulo .cartao__gatilho { color: inherit; text-decoration: none }
.landing-passo__texto {
  margin: 0;
  color: var(--texto-suave);
  font-size: var(--texto-sm);
  line-height: var(--altura-solta);
}

/* ═══ LISTA DE CONFERÊNCIA ════════════════════════════════════════════════ */

/* Marcador desenhado (ícone de check) em vez de `list-style`, porque o bullet
   padrão não tem cor de marca nem alinhamento previsível entre navegadores. */
.landing-marcadores {
  list-style: none;
  margin: 0 0 var(--esp-4);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
}
.landing-marcadores li {
  display: flex;
  align-items: flex-start;
  gap: var(--esp-3);
  line-height: var(--altura-normal);
}
.landing-marcadores__icone { flex: none; margin-top: 0.2rem; color: var(--cor-aprovado) }

/* ═══ ENDEREÇO WHITE LABEL ════════════════════════════════════════════════ */

.landing-endereco {
  padding: var(--esp-5);
  background: var(--fundo-cartao);
  border: 1px solid var(--borda);
  border-radius: var(--raio-3);
}
.landing-endereco__rotulo { margin: 0; font-size: var(--texto-sm); font-weight: var(--peso-forte) }
.landing-endereco__barra {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  margin: var(--esp-4) 0 var(--esp-3);
  padding: var(--esp-3) var(--esp-4);
  background: var(--fundo-fundo);
  border: 1px solid var(--borda);
  border-radius: var(--raio-redondo);
  /* O endereço pode passar da largura no celular pequeno; ele ROLA dentro da
     própria barra em vez de alargar a página. A landing nunca rola de lado. */
  overflow-x: auto;
  scrollbar-width: none;
}
.landing-endereco__barra::-webkit-scrollbar { display: none }
.landing-endereco__cadeado { flex: none; color: var(--cor-aprovado) }
.landing-endereco__url { color: var(--texto-suave); font-size: var(--texto-sm); white-space: nowrap }
.landing-endereco__sub { color: var(--cor-marca); font-weight: var(--peso-forte) }
.landing-endereco__nota { margin: 0; color: var(--texto-tenue); font-size: var(--texto-sm) }

/* ═══ A LETRA MIÚDA ═══════════════════════════════════════════════════════ */

/* `<dl>`: cada item é "o que não é" → "por quê", que é par termo/definição de
   verdade. Régua à esquerda em vez de cartão — são ressalvas, e ressalva
   dentro de cartão com sombra vira mais um argumento de venda. */
.landing-miudo {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--esp-2);
}
.landing-miudo__titulo {
  margin: 0;
  padding-left: var(--esp-4);
  border-left: 3px solid var(--cor-marca);
  font-size: var(--texto-md);
  font-weight: var(--peso-forte);
}
.landing-miudo__texto {
  /* No celular o par empilha, então a distância ENTRE pares sai daqui: o
     `row-gap` da grade é o respiro de dentro do par e não pode crescer sem
     descolar o título do próprio texto. */
  margin: 0 0 var(--esp-5);
  padding-left: var(--esp-4);
  border-left: 3px solid var(--borda);
  color: var(--texto-suave);
  font-size: var(--texto-sm);
  line-height: var(--altura-solta);
}

@media (min-width: 48rem) {
  .landing-miudo { grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); column-gap: var(--esp-8); row-gap: var(--esp-6) }
  .landing-miudo__texto { margin: 0 }
}

/* ═══ A CHAMADA FINAL ═════════════════════════════════════════════════════ */

/* Alinhada à ESQUERDA como o resto da página. A versão anterior centralizava
   esta peça e o herói, e deixava sete seções à esquerda no meio. */
.landing-chamada {
  padding: var(--esp-8) var(--esp-5);
  background: var(--cor-marca-suave);
  border: 1px solid var(--cor-marca-tenue);
  border-radius: var(--raio-4);
}
.landing-chamada__titulo {
  margin: 0 0 var(--esp-3);
  max-width: 24ch;
  font-size: var(--texto-2xl);
  letter-spacing: var(--espacamento-titulo);
  text-wrap: balance;
}
.landing-chamada__texto {
  max-width: 42rem;
  margin: 0 0 var(--esp-6);
  color: var(--texto-suave);
  line-height: var(--altura-solta);
}
.landing-chamada__email { margin-top: var(--esp-5) }

@media (min-width: 48rem) {
  .landing-chamada { padding: var(--esp-12) var(--esp-10) }
  .landing-chamada__titulo { font-size: var(--texto-3xl) }
}

/* A METADE DIREITA ESTAVA VAZIA, e lia como "alguma coisa não carregou": a
   caixa mede 926 px e o conteúdo empilhado parava em ~680. Não era falta de
   conteúdo, era falta de COMPOSIÇÃO — texto e ação um debaixo do outro dentro
   de uma caixa larga deixam uma coluna inteira de vazio à direita.

   A partir de 64rem a caixa vira duas colunas: o convite à esquerda, a ação à
   direita, as duas ancoradas no topo. Continua tudo alinhado à ESQUERDA dentro
   da sua coluna — o eixo único da página não muda, o que muda é a caixa deixar
   de ter um lado morto. Abaixo de 64rem empilha, que é o certo no celular. */
@media (min-width: 64rem) {
  .landing-chamada {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    column-gap: var(--esp-10);
    row-gap: var(--esp-4);
    align-items: start;
  }
  /* As quatro peças são colocadas UMA A UMA, e não deixadas ao fluxo
     automático. Com `grid-row: 1 / span 2` na barra de ações, o endereço em
     texto caía numa terceira linha criada depois do parágrafo — 180 px abaixo
     do botão a que ele pertence. Convite à esquerda, ação à direita, cada um
     com duas linhas próprias. */
  .landing-chamada__titulo { grid-column: 1; grid-row: 1 }
  .landing-chamada__texto  { grid-column: 1; grid-row: 2; margin-bottom: 0 }
  .landing-chamada .botoes {
    grid-column: 2;
    grid-row: 1;
    flex-direction: column;
    align-items: stretch;
  }
  .landing-chamada__email { grid-column: 2; grid-row: 2; margin-top: 0 }

  /* A medida de 24ch vale para a caixa de uma coluna. Aqui quem manda é a
     coluna da grade, e o cap fazia a manchete quebrar em três linhas dentro de
     um espaço em que ela cabe em duas. */
  .landing-chamada__titulo { max-width: none }
}

/* ═══ CARD → MODAL ════════════════════════════════════════════════════════
   O painel de detalhe. O mecanismo (`:target`), o que ele entrega e o que
   falta estão escritos no topo de `app/views/institucional/_ficha.html.erb`.

   Fechado: `visibility: hidden` — some da árvore de acessibilidade E da ordem
   de tabulação, sem `display: none`, que não anima. `pointer-events: none` é
   cinto e suspensório: elemento invisível já não recebe clique, mas este aqui
   cobre a janela inteira e um engano custaria a página.                       */

.landing-ficha {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transicao), visibility var(--transicao);
}
.landing-ficha:target { visibility: visible; opacity: 1; pointer-events: auto }

.landing-ficha__fundo {
  position: absolute;
  inset: 0;
  background: rgb(3 5 9 / 0.72);
}
/* O desfoque do fundo só existe no painel ABERTO. São treze painéis nesta
   página, e treze camadas de `backdrop-filter` do tamanho da janela, ainda que
   invisíveis, são treze superfícies de composição que o navegador carrega a
   página inteira — medido: a captura de tela do Chromium estourava 30 s de
   espera. Custo de compositor não é pago por quem não abriu o modal. */
.landing-ficha:target .landing-ficha__fundo { backdrop-filter: blur(3px) }

.landing-ficha__caixa {
  position: relative;
  width: 100%;
  max-height: 86dvh;
  overflow-y: auto;
  padding: var(--esp-5);
  padding-bottom: calc(var(--esp-6) + env(safe-area-inset-bottom));
  background: var(--fundo-elevado);
  border: 1px solid var(--borda-forte);
  border-radius: var(--raio-4) var(--raio-4) 0 0;
  box-shadow: var(--sombra-3);
  /* No celular sobe do rodapé, como folha — é o que a marca pede (§3). */
  transform: translateY(100%);
  transition: transform var(--transicao-lenta);
}
.landing-ficha:target .landing-ficha__caixa { transform: none }

.landing-ficha__topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--esp-4);
  margin-bottom: var(--esp-4);
}
.landing-ficha__titulo { margin: 0; font-size: var(--texto-xl) }
.landing-ficha__x {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--alvo);
  height: var(--alvo);
  margin: calc(var(--esp-2) * -1) calc(var(--esp-2) * -1) 0 0;
  border-radius: var(--raio-redondo);
  color: var(--texto-suave);
  transition: background var(--transicao), color var(--transicao);
}
.landing-ficha__x:hover { background: var(--fundo-fundo); color: var(--texto) }

.landing-ficha__corpo { color: var(--texto-suave); line-height: var(--altura-solta) }
.landing-ficha__corpo > p { margin: 0 0 var(--esp-4) }
.landing-ficha__corpo > :last-child { margin-bottom: 0 }
.landing-ficha__subtitulo {
  margin: var(--esp-6) 0 var(--esp-3);
  color: var(--texto);
  font-size: var(--texto-md);
  font-weight: var(--peso-forte);
}
.landing-ficha__ressalva { font-size: var(--texto-sm); color: var(--texto-tenue) }
.landing-ficha__acoes { margin-top: var(--esp-6) }

@media (min-width: 40rem) {
  /* No desktop é caixa centrada, e entra com escala — não com folha subindo. */
  .landing-ficha { align-items: center }
  .landing-ficha__caixa {
    width: min(40rem, calc(100vw - 3rem));
    border-radius: var(--raio-4);
    padding: var(--esp-6);
    padding-bottom: var(--esp-6);
    transform: scale(0.96);
    transition: transform var(--transicao);
  }
  .landing-ficha:target .landing-ficha__caixa { transform: none }
}

/* ═══ OS TRÊS BLOCOS DA PORTA DO TENANT ═══════════════════════════════════ */

/* O cartão é da onda D; daqui sai só o selo de símbolo no topo. */
.landing-bloco__simbolo {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--esp-3);
  border-radius: var(--raio-2);
  background: var(--cor-marca-suave);
  color: var(--cor-marca);
}

/* `.botoes` da onda D empilha no celular e vira linha a partir de 30rem. No
   herói centralizado da PORTA DO TENANT ela precisa centralizar também — e
   isso a onda D não decide, porque nas telas dela a barra é à esquerda.
   A landing institucional NÃO usa este modificador: lá tudo é à esquerda. */
.botoes--centro { align-items: stretch }
@media (min-width: 30rem) {
  .botoes--centro { justify-content: center; align-items: center }
}

/* ═══ MOVIMENTO ═══════════════════════════════════════════════════════════
   Leia o aviso no topo do arquivo antes de mexer. Regra sem exceção: todo
   quadro `100%` é o estado de REPOUSO, porque é nele que a página fica sob
   `prefers-reduced-motion`.                                                  */

@keyframes landing-sobe {
  from { opacity: 0; transform: translateY(1rem) }
  to   { opacity: 1; transform: none }
}

@keyframes landing-entra-lado {
  from { opacity: 0; transform: translateX(1.25rem) scale(0.98) }
  to   { opacity: 1; transform: none }
}

/* ── 1. A entrada do herói, na carga ──────────────────────────────────────
   Cascata curta (70 ms entre peças) e rápida: isto é o topo da página e o
   texto não pode chegar depois do leitor. O total, do primeiro ao último
   quadro, é meio segundo. */
@media (prefers-reduced-motion: no-preference) {
  .landing-heroi__etiqueta,
  .landing-heroi__titulo,
  .landing-heroi__texto,
  .landing-heroi__botoes,
  .landing-heroi__nota {
    animation: landing-sobe var(--tempo-lento) var(--curva-entrada) both;
  }
  .landing-heroi__titulo  { animation-delay: 70ms }
  .landing-heroi__texto   { animation-delay: 140ms }
  .landing-heroi__botoes  { animation-delay: 210ms }
  .landing-heroi__nota    { animation-delay: 280ms }

  .landing-heroi__arte {
    animation: landing-entra-lado 520ms var(--curva-entrada) both;
    animation-delay: 180ms;
  }
}

/* ── 2. A revelação ao rolar: NÃO É DAQUI ─────────────────────────────────
   Enquanto o bloco MOTOR não existia, esta folha revelava as seções sozinha,
   com `animation-timeline: view()` dentro de um `@supports`. O motor chegou, e
   a regra dele é melhor que a minha: `revelar_controller` só esconde o que
   está FORA DA TELA no momento do `connect`, então é impossível o pisca de
   "apareceu, sumiu, apareceu" — e, se o JS não carregar, nada some, porque a
   classe que esconde nunca chega ao CSS.

   A folha de rolagem não sabia fazer nem uma coisa nem outra: escondia pelo
   CSS (logo, sem JS TAMBÉM escondia) e não tinha como não piscar a primeira
   dobra. Saiu inteira. Quem revela agora são os helpers `revelar`/
   `revelar_item` na view, e a folha `03_movimento.css`.

   O que sobrou aqui é só o que o motor não cobre e não depende de JS nenhum:
   a entrada do herói na CARGA (acima, item 1) e a sequência do diagrama
   (abaixo). As duas são CSS puro e nascem do primeiro quadro da página. */

/* ═══ A ARTE DO HERÓI — O FLUXO ═══════════════════════════════════════════
 *
 * assiste → avalia → certificado → e a seta que ninguém mais desenha, a da
 * conferência por terceiro. As cores estão AQUI e não em atributos `fill=` no
 * SVG por um motivo de projeto: atributo de apresentação é valor fixo, e o dia
 * em que o tenant mudar de cor (ou o tema virar claro) o desenho não
 * acompanharia. `style=` também não serve — a CSP põe nonce em `style-src` e
 * nonce não vale para atributo `style`.
 */
.arte-fluxo {
  width: 100%;
  max-width: 34rem;
  height: auto;
  display: block;
}

.arte-fluxo__cartao { fill: var(--fundo-cartao); stroke: var(--borda); stroke-width: 1 }
.arte-fluxo__tela { fill: var(--fundo-fundo); stroke: var(--borda); stroke-width: 1 }
.arte-fluxo__play { fill: var(--cor-marca) }
.arte-fluxo__trilho { fill: var(--fundo-fundo); stroke: var(--borda); stroke-width: 0.75 }
.arte-fluxo__barra { fill: var(--cor-marca-forte) }
.arte-fluxo__bolinha { fill: none; stroke: var(--borda-forte); stroke-width: 1.25 }
.arte-fluxo__opcao { fill: var(--texto-tenue); opacity: 0.4 }
.arte-fluxo__bolinha-cheia { fill: var(--cor-aprovado) }
.arte-fluxo__check { fill: none; stroke: var(--cor-aprovado-contraste); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round }
.arte-fluxo__folha { fill: var(--fundo-fundo); stroke: var(--borda); stroke-width: 1 }
.arte-fluxo__linha { fill: var(--texto-tenue); opacity: 0.45 }
.arte-fluxo__qr-fundo { fill: var(--fundo-cartao); stroke: var(--borda-forte); stroke-width: 0.75 }
.arte-fluxo__qr-modulo { fill: var(--texto) }
.arte-fluxo__selo-disco { fill: var(--cor-marca-forte) }
.arte-fluxo__selo-check { fill: none; stroke: var(--cor-marca-contraste); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round }
.arte-fluxo__seta-traco { stroke: var(--borda-forte); stroke-width: 1.5; stroke-linecap: round }
.arte-fluxo__seta-ponta { fill: var(--borda-forte) }
.arte-fluxo__tracejado {
  stroke: var(--cor-marca);
  stroke-width: 1.5;
  stroke-dasharray: 4 4;
  stroke-linecap: round;
}
.arte-fluxo__pilula { fill: var(--cor-marca-suave); stroke: var(--cor-marca-tenue); stroke-width: 1 }
.arte-fluxo__lupa { fill: none; stroke: var(--cor-marca); stroke-width: 1.75 }
.arte-fluxo__lupa-cabo { stroke: var(--cor-marca); stroke-width: 1.75; stroke-linecap: round }

.arte-fluxo__rotulo {
  fill: var(--texto);
  font-family: var(--fonte);
  font-size: 13px;
  font-weight: 700;
  text-anchor: middle;
}
.arte-fluxo__nota {
  fill: var(--texto-tenue);
  font-family: var(--fonte);
  font-size: 10px;
  text-anchor: middle;
}
.arte-fluxo__confere-texto {
  fill: var(--cor-marca);
  font-family: var(--fonte);
  font-size: 13px;
  font-weight: 700;
}

/* ── O movimento do diagrama ──────────────────────────────────────────────
   A sequência É o argumento: a barra enche (o servidor medindo), o check cai
   (a avaliação), o selo fecha (o certificado) e a conferência acende. Roda UMA
   VEZ, na carga — figura que pisca para sempre num herói é a definição de
   animação que atrapalha. `transform-box: fill-box` porque, sem ele, a origem
   de transformação de um nó SVG é o canto do viewBox inteiro e a barra
   cresceria a partir do lugar errado. */
@keyframes arte-fluxo-enche {
  from { transform: scaleX(0) }
  to   { transform: scaleX(1) }
}
@keyframes arte-fluxo-surge {
  from { opacity: 0; transform: scale(0.4) }
  to   { opacity: 1; transform: none }
}
@keyframes arte-fluxo-acende {
  from { opacity: 0 }
  to   { opacity: 1 }
}

/* OS TEMPOS SÃO MEDIDOS, E "MENOS DE 1,8 s" NÃO ERA CONSERTO — ERA O MESMO
   DEFEITO COM UM NÚMERO MENOR. A medição, do início da navegação:

     h1 389 ms · parágrafo 473 ms · botões 539 ms · selo 1356 ms ·
     pílula "Qualquer um confere" 1755 ms

   Ou seja: por ~1,3 segundo o herói dizia "Assiste → Avalia → Certificado",
   que é o que qualquer LMS faz, e A ÚNICA COISA QUE DIFERENCIA A ELEVÔ —
   terceiro confere sem pedir nada a ninguém — chegava por último. Quem rolasse
   no primeiro segundo nunca via. `MARCA.md §2`: a animação nunca atrasa a
   informação, e a informação aqui é a pílula.

   Os tempos abaixo põem a pílula a 520 ms, no mesmo instante em que a barra de
   botões do herói termina de entrar (210 ms de atraso + 420 ms) — que é o que
   a crítica pediu com estas palavras: "junto com os botões". A sequência
   inteira fecha em 860 ms, contra 1.770 ms. O que se perdeu foi meio segundo
   de suspense; o que se ganhou foi o argumento chegar na primeira dobra.

   A ORDEM CONTINUA SENDO O ARGUMENTO (barra enche → check cai → selo fecha →
   conferência acende): ela só ficou apertada de 1,77 s para 0,86 s. Encavalar
   um pouco as etapas é o que permite isso sem a figura parecer um piscar só —
   a barra ainda está enchendo quando a seta 1 acende. */
@media (prefers-reduced-motion: no-preference) {
  .arte-fluxo__barra {
    transform-box: fill-box;
    transform-origin: left center;
    animation: arte-fluxo-enche 520ms var(--curva-entrada) 120ms both;
  }
  .arte-fluxo__seta--1 { animation: arte-fluxo-acende 200ms linear 360ms both }
  .arte-fluxo__bolinha-cheia,
  .arte-fluxo__check {
    transform-box: fill-box;
    transform-origin: center;
    animation: arte-fluxo-surge 300ms var(--curva-elastica) 400ms both;
  }
  .arte-fluxo__seta--2 { animation: arte-fluxo-acende 200ms linear 460ms both }
  .arte-fluxo__qr { animation: arte-fluxo-acende 220ms linear 470ms both }
  .arte-fluxo__selo {
    transform-box: fill-box;
    transform-origin: center;
    animation: arte-fluxo-surge 320ms var(--curva-elastica) 500ms both;
  }
  .arte-fluxo__tracejado { animation: arte-fluxo-acende 240ms linear 500ms both }
  .arte-fluxo__confere { animation: landing-sobe 340ms var(--curva-entrada) 520ms both }
}

/* ═══ A ARTE DO CERTIFICADO ═══════════════════════════════════════════════
 *
 * Esquema do certificado, com os mesmos tokens. É ESQUEMA, NÃO FAC-SÍMILE: o
 * protocolo aparece com os X literais e o quadriculado é decorativo — desenhar
 * documento de aparência real numa peça comercial é fabricar documento.
 */
.arte-certificado {
  width: 100%;
  max-width: 30rem;
  height: auto;
  margin-inline: auto;
  display: block;
}

.arte-certificado__folha { fill: var(--fundo-cartao); stroke: var(--borda); stroke-width: 1.5 }
.arte-certificado__marca { fill: var(--cor-marca) }
.arte-certificado__titulo { fill: var(--texto); opacity: 0.9 }
.arte-certificado__nome { fill: var(--texto); opacity: 0.65 }
.arte-certificado__linha { fill: var(--texto-tenue); opacity: 0.45 }
.arte-certificado__regua { stroke: var(--borda); stroke-width: 1 }

.arte-certificado__selo { fill: var(--cor-marca-suave); stroke: var(--cor-marca-tenue); stroke-width: 1.5 }
.arte-certificado__selo-interno { fill: none; stroke: var(--cor-marca); stroke-width: 1; opacity: 0.55 }
.arte-certificado__selo-check {
  fill: none;
  stroke: var(--cor-marca);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.arte-certificado__qr-fundo { fill: var(--fundo-fundo) }
.arte-certificado__qr { fill: var(--texto); opacity: 0.85 }
.arte-certificado__qr-vazado { fill: var(--fundo-fundo) }
.arte-certificado__protocolo {
  fill: var(--texto-suave);
  font-family: var(--fonte-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
}
