/* sections.css — uma regra por secao. Consome token, nunca declara cor literal. */

/* ============================================================
   TOPO (header fixo)
   ============================================================ */

.topo {
  position: sticky;
  top: 0;
  z-index: 50;
  /* 88% da superficie + 12% de transparencia: a pagina passa por baixo sem
     que o texto do header perca fundo. Sem cor literal - color-mix deriva
     do token do tema, entao ele acompanha o toggle sozinho. */
  background: color-mix(in srgb, var(--surface-base) 88%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--borda);
}

.topo-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-block: 14px;
}

/* --- marca --------------------------------------------------- */

.topo-marca {
  display: inline-flex;
  align-items: center;
  /* alvo de toque: o logo tem 40-46px de altura, o ancora garante os 44px */
  min-height: 44px;
  flex: 0 0 auto;
  text-decoration: none;
}
.topo-marca:hover { text-decoration: none; }

/* Altura controlada e largura AUTO de proposito: os atributos width/height do
   HTML (180x77) arredondam a proporcao 2,352 da assinatura para 2,338, e
   "distorcer ou alterar a proporcao" e usos_incorretos do manual. Com
   width:auto o navegador usa a proporcao real do viewBox e o par de atributos
   continua servindo so para reservar espaco (anti-CLS).
   O piso de 40px de altura vale 94px de largura, acima do tamanho minimo
   declarado para a assinatura (90px). Nao descer daqui. */
.topo-marca img {
  height: clamp(40px, 3.2vw, 46px);
  width: auto;
}

.marca-clara  { display: none; }
.marca-escura { display: block; }
:root[data-theme="light"] .marca-clara  { display: block; }
:root[data-theme="light"] .marca-escura { display: none; }

/* --- navegacao ----------------------------------------------- */

.topo-nav {
  display: flex;
  align-items: center;
  /* Fluido de proposito: com 1.6rem fixo, "Como funciona" quebrava em 2 linhas
     entre 901 e ~930px (a linha do header nao tem folga ali). O gap cede antes
     de o texto ceder; o nowrap abaixo e o cinto para o caso em que nem o gap
     minimo resolva - estoura a linha em vez de partir o rotulo. */
  gap: clamp(.9rem, 2vw, 1.6rem);
}

.topo-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-muted-on-base);
  font-size: .95rem;
  white-space: nowrap;
  text-decoration: none;
  transition: color .2s ease;
}
.topo-nav a:hover,
.topo-nav a:focus-visible {
  color: var(--text-on-base);
  text-decoration: none;
}

.topo-acoes {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex: 0 0 auto;
}

/* --- toggle de tema ------------------------------------------ */

.toggle {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  min-height: 44px;
  min-width: 44px;
  justify-content: center;
  padding: 0 1rem;
  border: 1px solid var(--traco-controle);
  border-radius: 999px;
  background: transparent;
  color: var(--text-on-base);
  font-size: .9rem;
  font-weight: 400;
  cursor: pointer;
  transition: border-color .2s ease, background-color .2s ease;
}
.toggle:hover { border-color: var(--text-muted-on-base); }

/* Glifo de traco: SOL quando esta escuro (a acao e acender) e LUA quando esta
   claro (a acao e apagar). Os dois moram no HTML e o CSS escolhe por
   [data-theme] - mesma tecnica das duas assinaturas, e por isso o glifo ja
   nasce certo no primeiro paint, sem JS novo. */
.toggle-glifo {
  display: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}
.toggle-glifo svg { width: 100%; height: 100%; }

/* Sol em ambar sobre o marinho: 9,54:1 (pares.sempre_pode), com o mesmo
   brilho que o ponto tinha. O stroke e currentColor, entao a cor vem daqui. */
.glifo-sol {
  color: var(--ambar);
  /* --glow-ambar e "0 0 24px <cor>": sem spread, entao serve
     tal e qual dentro de drop-shadow(). */
  filter: drop-shadow(var(--glow-ambar));
}
/* Lua em azul-eletrico sobre o branco-quente: 8,54:1. Sem brilho - ambar
   sobre o creme e 2,03:1 (pares.proibido) e o glow ali so sujaria. */
.glifo-lua { color: var(--azul); }

:root .glifo-sol,
:root[data-theme="dark"] .glifo-sol   { display: block; }
:root[data-theme="light"] .glifo-sol  { display: none; }
:root[data-theme="light"] .glifo-lua  { display: block; }

/* Rotulo: os dois no HTML, o CSS escolhe. Nada de estado cravado no markup. */
.rotulo-apagar  { display: none; }
:root[data-theme="light"] .rotulo-acender { display: none; }
:root[data-theme="light"] .rotulo-apagar  { display: inline; }
/* O CSS e o UNICO dono do rotulo visivel. O theme.js nao escreve aqui.
   Os dois textos existem no HTML e o [data-theme] esconde o do tema errado,
   entao o rotulo nasce certo antes do primeiro paint e continua certo sem JS. */

/* --- tablet e celular: o toggle vira so o glifo, a nav vira menu ---------- */

/* Fica so o glifo. O rotulo sai da TELA mas NAO da arvore de acessibilidade:
   com display:none, numa visita sem JS o botao ficaria sem nome nenhum (o
   aria-label so existe depois que o theme.js roda). Com o recorte de 1px o
   texto visivel continua sendo o nome acessivel, com ou sem JS. O display:none
   do rotulo do tema errado continua valendo e vence este bloco, entao so o
   rotulo certo fica na arvore.
   Desde 03/10 vale de 900px para baixo (antes, 560): e onde a linha do header
   deixa de ter folga para "Acender a luz" (o mais largo dos dois rotulos)
   ao lado da nav inteira e do botao de contato. */
@media (max-width: 900px) {
  .toggle-rotulo {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .toggle { padding: 0; }
}

/* Botao do menu: so existe com JS (html.js, posto pelo theme.js no <head>) e so
   abaixo do corte. Mesma pele do .toggle - circulo de 44px com o traco de
   controle, que e o token que a WCAG 1.4.11 exige (3:1) para o contorno que
   IDENTIFICA o componente. Nenhum token novo. */
.menu-botao {
  display: none;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--traco-controle);
  border-radius: 999px;
  background: transparent;
  color: var(--text-on-base);
  cursor: pointer;
  transition: border-color .2s ease;
}
.menu-botao:hover { border-color: var(--text-muted-on-base); }
.menu-botao svg { width: 20px; height: 20px; }
/* Dois glifos no HTML, o CSS escolhe pelo estado que o proprio botao declara:
   o aria-expanded e a fonte unica, nao ha classe paralela que possa divergir. */
.menu-botao .menu-fechar { display: none; }
.menu-botao[aria-expanded="true"] .menu-abrir  { display: none; }
.menu-botao[aria-expanded="true"] .menu-fechar { display: block; }

@keyframes menu-entra {
  from { opacity: 0; transform: translateY(-6px); }
}

/* Corte do menu: abaixo de 760px a linha do header (marca 94px + 4 links +
   toggle + botao de contato) nao cabe. Entre 760 e 900 a nav continua visivel,
   compacta, com o toggle so no glifo (bloco acima). MEDIDO: o menor viewport em
   que nav + acoes cabem sem rolagem lateral e sem link em 2 linhas, nos 2 temas. */
@media (max-width: 759px) {
  /* SEM JS: nao ha botao para abrir nada, entao a nav desce para uma 2a linha
     do header e os 4 links continuam a um toque. E o que o G4 exige: todo href
     que existe com JS existe sem. */
  .topo-linha { flex-wrap: wrap; row-gap: 0; }
  .topo-nav {
    order: 4;
    flex: 1 0 100%;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0 1rem;
  }

  /* COM JS: a nav vira painel sob o header, fechado de nascenca. */
  .js .topo-linha { flex-wrap: nowrap; }
  .js .topo-acoes { margin-left: auto; }
  .js .menu-botao { display: inline-flex; }

  .js .topo-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-block: 4px 8px;
    /* Opaco, ao contrario do header (88%): o painel cobre texto de verdade e
       transparencia ali e ilegivel. Mesmo token da superficie da pagina, entao
       acompanha o toggle e ja esta coberto pelo G1. */
    background: var(--surface-base);
    border-bottom: 1px solid var(--borda);
  }
  .js .topo-nav.aberto {
    display: flex;
    animation: menu-entra .18s ease-out;
  }
  .js .topo-nav a {
    min-height: 48px;
    padding-inline: var(--gutter);
    font-size: 1.05rem;
    color: var(--text-on-base);
  }
  .js .topo-nav a + a { border-top: 1px solid var(--borda); }
}

/* Em celular estreito o "Falar com a AeS" sai do header: marca 94px + toggle 44
   + botao ~144 + menu 44 + 3 gaps de 12 + gutter de 2x20 somam ~402px, e abaixo
   disso nao cabe sem encolher a marca (piso de 94px do manual). O CTA nao se
   perde: "Contato" esta na nav/menu em AMBOS os modos, o hero repete o convite
   e o CTA final fecha a pagina. Vale tambem sem JS: la o botao so empurrava a
   linha para baixo (marca + toggle + botao = 296px numa linha de 280).
   Sem JS o header ainda deixa de ser sticky: com a nav em 2 linhas ele passa
   de 130px e uma faixa fixa desse tamanho come a tela. */
@media (max-width: 439px) {
  .topo-acoes .botao { display: none; }
}
@media (max-width: 759px) {
  html:not(.js) .topo { position: static; }
}

/* --- botoes --------------------------------------------------- */

.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 1.5rem;
  border-radius: var(--radius);
  font-weight: 500;
  font-size: .95rem;
  white-space: nowrap;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, background-color .2s ease;
}
.botao:hover { text-decoration: none; }

/* Marinho sobre ambar = 9,54:1 (pares.sempre_pode). Fixo nos DOIS temas de
   proposito: e o par provado, nao segue a inversao do tema. */
.botao-ambar {
  background: var(--ambar);
  color: var(--marinho);
}
.botao-ambar:hover {
  box-shadow: var(--glow-ambar);
  transform: translateY(-1px);
}

.botao-linha {
  border: 1px solid var(--traco-controle);
  color: var(--text-on-base);
}
.botao-linha:hover {
  border-color: var(--text-muted-on-base);
  transform: translateY(-1px);
}

/* ============================================================
   HERO
   ============================================================ */

.hero {
  /* o header e sticky e come o topo: compensa so no hero */
  padding-block: clamp(32px, min(5vw, 5.5vh), 80px) clamp(64px, min(9vw, 11vh), 140px);
  overflow: hidden;
}

.hero-grade {
  display: grid;
  grid-template-columns: 1.35fr .65fr;
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
}

.hero-texto { min-width: 0; }

/* Enquadramento (03/10): o H1 olha a ALTURA da janela tambem, nao so a largura.
   Com 6vw puro, num notebook de ~1000x510 o titulo ia a 5 linhas e os botoes
   caiam abaixo da dobra. min(vw, vh) segura o titulo em ~3 linhas e deixa
   rotulo + H1 + sub + botoes na primeira tela. */
.hero h1 {
  max-width: 17ch;
  font-size: clamp(2.2rem, min(5.2vw, 8.4vh), 4.4rem);
  text-wrap: balance;
}

/* Acento de peso e COR, nunca italico nem serifa (decisao D5, o cliente
   recusou). font-style:normal explicito porque <em> nasce italico. */
.enfase {
  font-style: normal;
  color: var(--accent-text);
  font-weight: 600;
}

/* 🔴 DEFEITO DO PLANO, PEGO NA TASK 8. O H2 do #conceito e o PRIMEIRO .enfase
   dentro de .contraste no projeto (hero e metodo ficam na superficie base), e
   o plano nao previa esta regra. Sem ela a palavra "conexao" herda
   --accent-text, que e o acento da superficie BASE:
     tema escuro -> ambar sobre branco-quente = 2,03:1. Esse par esta em
       pares.PROIBIDO do brand-tokens.json; o spec §4 diz "ambar nunca e texto
       sobre fundo claro". A palavra sai lavada, quase invisivel.
     tema claro  -> ambar-escuro sobre marinho = 4,03:1, abaixo dos 4,5:1 de
       corpo de texto (passa so por ser titulo grande, e por acidente).
   Com --accent-on-contrast: 4,80:1 no escuro e 9,54:1 no claro. Medidos.
   ⚠️ NENHUM PORTAO VE ISTO. A matriz FAMILIAS do g1_contraste.py mede TOKEN
   contra SUPERFICIE, nao onde a classe e aplicada: --accent-text e testado
   contra --surface-base e --surface-card e passa nos dois - o portao nunca
   fica sabendo que a classe foi parar na faixa do outro lado. Mesma cegueira
   que criou a verificacao V3. Quem puser .enfase numa faixa nova confere na
   mao. O par usado aqui (--accent-on-contrast sobre --surface-contrast) esta,
   esse sim, coberto pela familia "contrast" do G1. */
.contraste .enfase { color: var(--accent-on-contrast); }

.hero-sub {
  margin-top: 1.5rem;
  max-width: 52ch;
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
}

.hero-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  margin-top: 2.25rem;
}

/* --- grafismo derivado: arcos concentricos + nucleo ----------- */

.hero-arte {
  /* Fonte unica do tamanho da arte: o SVG e o halo leem daqui, entao os dois
     nunca se descolam. So este numero muda nas media queries. */
  --arte-tam: min(440px, 30vw, 62vh);
  position: relative;
  display: flex;
  justify-content: center;
  min-width: 0;
}

/* Halo radial por tras dos arcos - o "brilho azul" da referencia. Derivado do
   --halo-arco-cor por color-mix; a forca por tema vem de --halo-arco-forca.
   ATENCAO: dimensionado pela ARTE (--arte-tam), nunca por `inset` na coluna.
   Com inset o halo herdava a largura da coluna da grade: em 1440 a coluna tem
   450px e a arte 440, dava quase um circulo e passava despercebido; em 390 a
   coluna tem 350 e a arte 180, e o halo virava uma MANCHA OVAL vazando dos
   dois lados dos arcos. Visto no render de 390, nao na folha de estilo. */
.hero-arte::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(100%, var(--arte-tam));
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 50%,
    color-mix(in srgb, var(--halo-arco-cor) var(--halo-arco-forca), transparent) 0%,
    transparent 68%
  );
  pointer-events: none;
}

.arte-arcos {
  position: relative;
  width: 100%;
  max-width: var(--arte-tam);
  height: auto;
  overflow: visible;
}

.arco {
  fill: none;
  stroke: var(--arco-traco);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: .55;
  filter: var(--glow-arco);
}

/* Anel interno: fechado e um pouco mais presente, e a ancora visual. */
.a1 { opacity: .75; }

/* Os dois externos sao ARCOS, nao circunferencias fechadas: sem o traco
   interrompido a rotacao seria matematicamente invisivel (girar um circulo
   perfeito nao muda um pixel). O dasharray e calculado sobre a circunferencia
   real para os segmentos fecharem sem emenda:
     r=110 -> C=691,150 -> 3 repeticoes de 230,383 (160 + 70,383)
     r=160 -> C=1005,310 -> 4 repeticoes de 251,327 (170 + 81,327) */
.a2 { stroke-dasharray: 160 70.383; }
.a3 { stroke-dasharray: 170 81.327; }

.nucleo {
  /* logo.regra_nucleo: fundo escuro -> branco quente, fundo claro -> marinho. */
  fill: var(--nucleo);
}

/* Movimento continuo do simbolo (manual): 60s, linear, infinito, e os dois
   arcos externos em sentidos opostos. transform-box:fill-box faz o
   transform-origin:center cair no centro do proprio circulo. */
@keyframes girar {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.a2,
.a3 {
  transform-box: fill-box;
  transform-origin: center;
  animation: girar 60s linear infinite;
}
.a3 { animation-direction: reverse; }

/* ============================================================
   ONDA — transicao entre faixas
   ============================================================ */

.onda {
  display: block;
  width: 100%;
  /* uma fonte so para as 4 ondas: ver --onda-altura no tokens.css */
  height: var(--onda-altura);
  /* A costura, e o que a medicao REALMENTE disse.
     A teoria e boa: a altura sai de clamp()/vw, cai em valor fracionario
     (medi 998,14px de base da onda em 1440, com a onda de 129,59px), e um
     arredondamento para lados opostos deixaria uma fileira de 1px com a cor
     de tras entre a onda e a secao. O -1px sobrepoe a secao nessa fileira,
     e como o fill da onda e a cor do fundo da secao a sobreposicao e
     invisivel.
     ATENCAO: SO QUE A COSTURA NAO REPRODUZIU. Varri 7 larguras (360, 390,
     601, 768, 1000, 1201, 1440) x 2 escalas de dispositivo (1 e 2) x 2 temas,
     lendo o PNG fileira a fileira em volta da juncao, COM e SEM o -1px: limpo
     nos 28 casos - e repeti a varredura inteira depois de a onda ficar mais
     funda, mesmo resultado. Fica como seguro barato (custo zero, invisivel
     por construcao), nao como conserto medido. Se alguem tirar, nada quebra no Chrome nas
     larguras varridas - e essa e a informacao honesta para quem mexer. */
  margin-bottom: -1px;
}

/* O fill le o token, entao a onda vira junto com o toggle sem uma linha de
   JavaScript. Nao ha cor literal aqui nem no HTML. */
.onda path { fill: var(--surface-contrast); }

/* Onda que SOBE: a faixa de contraste fica ACIMA dela, entao o fill continua
   sendo --surface-contrast (a regra `.onda path` acima ja serve, porque o
   elemento carrega as duas classes). O que muda e o lado da costura: quem
   desce sobrepoe 1px para BAIXO, quem sobe sobrepoe 1px para CIMA.
   ATENCAO: nada de `transform: scaleY(-1)` aqui. O path do HTML ja nasce
   invertido; espelhar por transform desalinha o preserveAspectRatio e deixa
   um degrau de 1 a 2px. Mesmo estatuto do -1px da onda que desce: seguro
   barato, nao conserto medido - a varredura de fileiras nao achou emenda. */
.onda-volta {
  margin-top: -1px;
  margin-bottom: 0;
}

/* ------------------------------------------------------------------
   ESPACAMENTO SECAO <-> ONDA — REGRA UNICA, OS DOIS SENTIDOS

   A onda ja entrega altura de respiro: metade dela fica do lado de quem vem
   antes e metade do lado de quem vem depois. Somar a isso o padding INTEIRO
   da secao empurra o conteudo para longe da crista - e ate aqui so o lado de
   BAIXO da onda tinha desconto, entao a mesma onda tinha 140px chapados em
   cima e 85px embaixo (medido em 1440). A assimetria nao era decisao de
   ninguem, era a soma que ninguem fez.

   Escrito por PADRAO ESTRUTURAL, nao caso a caso: quem manda e a onda ser
   irma imediata da secao. Secao nova encostada numa onda herda sozinha, nas
   Tasks 7, 8 e 9, sem ninguem lembrar de repetir nada e sem classe nova.
   A dose vive em --respiro-onda (tokens.css), uma so para os 2 lados.

   ⚠️ Especificidade: `.secao:has(+ .onda)` e (0,2,0) e vence o `.hero`
   (0,1,0), inclusive o `.hero` dentro da media query de 560px - e por isso
   que o hero tambem obedece, que e o que se quer. Se um dia alguem precisar
   de excecao, ela tem de ser (0,3,0) ou mais.
   ⚠️ Navegador sem `:has()` ignora a regra INTEIRA e a secao fica com o
   padding cheio - ou seja, cai no comportamento de antes desta mudanca.
   Degradacao benigna: sobra ar, nada quebra. */
.onda + .secao        { padding-top: var(--respiro-onda); }
.secao:has(+ .onda)   { padding-bottom: var(--respiro-onda); }

/* ============================================================
   ENTREGAS — 3 cards na faixa de contraste
   ============================================================ */

#solucoes h2, #produtos h2 { max-width: 24ch; }

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 28px);
  margin-top: clamp(40px, 5vw, 64px);
}

/* Valores de SUPERFICIE BASE. Dentro de .contraste eles sao trocados logo
   abaixo pelos pares "-contrast", que carregam o valor do outro tema. */
.card {
  background: var(--surface-card);
  border: 1px solid var(--borda);
  border-radius: var(--radius-md);
  padding: clamp(24px, 2.5vw, 36px);
  box-shadow: var(--sombra-card);
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}

.card:hover {
  border-color: var(--traco-azul);
  box-shadow: var(--glow-azul);
  transform: translateY(-2px);
}

/* Sem isto o cartao ganha ~1,1em de vazio no rodape, porque o <p> do base.css
   carrega margin-bottom e ele e o ultimo filho. */
.card p:last-child { margin-bottom: 0; }

/* Dentro da onda a superficie e a do OUTRO tema: sem esta troca o cartao
   ficaria com o fundo do tema corrente e sumiria na faixa. Sao valores de
   token, nunca color-mix: o portao G1 precisa ler um valor computado, e
   color-mix devolve uma string que a leitura de token nao resolve. */
.contraste .card {
  background: var(--surface-card-contrast);
  border-color: var(--borda-contrast);
  box-shadow: var(--sombra-card-contrast);
}
.contraste .card:hover {
  border-color: var(--traco-azul-contrast);
  box-shadow: var(--glow-azul-contrast);
}

/* Mesma regua do .rotulo. <span> nasce inline, dai o display:block. */
.card-num {
  display: block;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .15em;
  color: var(--accent-text);
  margin-bottom: 1rem;
}
.contraste .card-num { color: var(--accent-on-contrast); }

.card h3 { margin-bottom: .6rem; }

/* O titulo de 03 quebra em 2 linhas enquanto 01 e 02 cabem em 1, e o paragrafo
   dele comecava uma linha abaixo dos outros dois. Com a borda mais visivel o
   degrau ficou MAIS aparente, porque o olho ganhou um retangulo para comparar.
   Reserva de 2 linhas so onde os cards ficam LADO A LADO: os .cards de 3
   colunas (a partir de 861px; abaixo disso empilham e a reserva viraria
   buraco) e os .cards-duplas, que vao a 2 colunas desde 641px e a 4 acima de
   1100 (regra propria, no fim do arquivo). Em 1 linha o h3 ocupa ~1.2em. */
@media (min-width: 861px) {
  .card h3 { min-height: 2.4em; }
}

/* ============================================================
   METODO — trilha dos 3 movimentos
   ============================================================ */

#como-funciona h2 { max-width: 20ch; }

.metodo-intro, .secao-intro {
  margin-top: 1.25rem;
  max-width: 52ch;
  /* Em 1440 a frase quebrava com "resultado." sozinho na 2a linha. balance
     reparte as duas linhas; onde nao houver suporte cai na quebra normal, que
     e o que ja se ve hoje - melhoria progressiva, nao dependencia. */
  text-wrap: balance;
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
}

.trilha {
  list-style: none;
  margin: clamp(40px, 5vw, 64px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* a medida vira token local porque a linha da trilha PRECISA dela para saber
     onde esta o centro da ultima bolinha (ver .trilha::before) */
  --trilha-gap: clamp(20px, 3vw, 40px);
  gap: var(--trilha-gap);
  position: relative;
}

/* A linha que costura os 3 passos. Passa pelo CENTRO das bolinhas: elas tem
   36px e comecam no topo do <li>, entao o centro esta em 18px.
   Cor: --traco-azul, NAO --azul-sinal cru. Sobre o marinho os dois sao a mesma
   coisa (azul-sinal, 7,46:1 - e o que o plano pediu), mas no tema claro o
   azul-sinal sobre o branco-quente da 2,59:1 e um fio de 1px ja degrade nas
   pontas simplesmente nao aparece. --traco-azul e o token que existe para
   exatamente isto e vira azul-eletrico no claro (8,54:1). Medido. */
.trilha::before {
  content: '';
  position: absolute;
  top: 18px;
  /* Comeca e termina no CENTRO das bolinhas das pontas, nao nas bordas do
     grid. Com left:0/right:0 (a versao do plano) sobrava uma cauda de ~29% da
     largura depois do 03, ligando o ultimo passo a coisa nenhuma - medido em
     1440: os centros ficam em 18, 389 e 759 de 1072px.
     A conta e exata e sobrevive a mudanca do gap: cada coluna mede
     (100% - 2*gap)/3, e do centro do 03 ate a borda direita ha uma coluna
     menos os 18px do raio. Trocar o numero de passos INVALIDA o divisor 3. */
  left: 18px;
  right: calc((100% - 2 * var(--trilha-gap)) / 3 - 18px);
  height: 1px;
  /* As duas pontas dissolvem DENTRO das bolinhas, que sao opacas; a rampa
     fecha em 5% para o traco sair da bolinha ja com corpo, senao o trecho
     01->02 nasce quase invisivel e so engrossa no meio. */
  background: linear-gradient(90deg,
    transparent 0%,
    var(--traco-azul) 5%,
    var(--traco-azul) 95%,
    transparent 100%);
  pointer-events: none;
}

/* A bolinha e POSICIONADA de proposito: o ::before da trilha e absoluto e
   pintaria POR CIMA de conteudo nao posicionado, riscando os numeros. Com
   position+z-index os dois entram na mesma camada e a ordem do DOM manda. */
.passo-num {
  position: relative;
  z-index: 1;
  /* display:flex, nao inline-flex: inline-flex assenta na linha de base e o
     line-height de 1,55 do body empurraria o circulo alguns pixels para baixo,
     tirando o centro dele dos 18px onde a linha passa. */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  /* --traco-passo, nao --borda: medido, o anel com --borda dava 1,25:1 no
     escuro e 1,30:1 no claro e nao existia como objeto grafico. Token proprio
     porque --borda tambem veste header, toggle e botao-linha. */
  border: 1px solid var(--traco-passo);
  /* mesma superficie da secao: e o que "fura" a linha atras do numero */
  background: var(--surface-base);
  color: var(--accent-text);
  /* mesma regua do .rotulo e do .card-num */
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .15em;
  /* o letter-spacing sobra DEPOIS do ultimo digito e desloca o par para a
     esquerda do centro; o padding devolve a mesma medida do outro lado */
  padding-left: .15em;
}

.passo h3 { margin: 1rem 0 .5rem; }
.passo p:last-child { margin-bottom: 0; }

/* ============================================================
   ESSENCIA — as 4 percepcoes
   ============================================================ */

/* Onda dos DOIS lados desde a Task 12. Embaixo esta a 5->6, que nasceu na
   Task 8; em cima entrou a fita decorativa metodo -> essencia (2 ondas
   coladas, ver o comentario no index.html). As 2 regras estruturais do
   --respiro-onda pegam os dois lados sozinhas, sem uma linha escrita aqui:
   `.onda + .secao` no topo e `.secao:has(+ .onda)` embaixo, 140px -> 86,4px
   em 1440 nos dois. Nao criar excecao para esta secao.
   ⚠️ O vao entre o metodo e esta secao era 280px em 1440 e 144px em 390
   enquanto nao havia onda no meio - era a soma de dois paddings cheios na
   mesma superficie, par que nenhuma das 2 regras alcancava. Com a fita o par
   passou a ser alcancado: 172,8px de padding em 1440 (86,4 + 86,4) com a fita
   de ~130px x2 no meio. Medido antes e depois. */

#essencia h2 {
  max-width: 26ch;
  /* Em 390 a frase quebrava em 4 linhas deixando "AeS." SOZINHA na ultima.
     Com balance as 4 linhas se repartem e a quebra cai onde a sintaxe pede
     ("...precisam existir / em cada contato / com a AeS."), que e a mesma
     quebra da versao larga. Em 1440 nao muda um pixel (conferido por hash):
     la quem manda e o <br class="quebra-larga">.
     ⚠️ A ALTURA E IDENTICA nos dois casos - 131,3px, 4 linhas dos dois jeitos.
     Medir altura ou contar linhas NAO ve esta diferenca; so o PNG ve.
     Onde nao houver suporte, cai na quebra normal: melhoria progressiva. */
  text-wrap: balance;
}

.percepcoes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* mesma escada de gap dos .cards, so um degrau mais larga em cima porque sao
     4 colunas e nao 3 - com 28px as colunas de 1440 ficavam grudadas */
  gap: clamp(20px, 2.5vw, 36px);
  margin-top: clamp(40px, 5vw, 64px);
}

/* O filete e o unico desenho da percepcao: nao ha cartao, fundo nem sombra
   aqui. E o mesmo elemento da assinatura de e-mail aprovada em 17/09, o que
   mantem a familia visual.
   --traco-ambar, NAO --ambar cru: ambar puro sobre o branco-quente e 2,03:1
   (pares.proibido) e o filete simplesmente nao aparece no tema claro. O token
   vira ambar-escuro la, 4,80:1.
   MEDIDO contra a superficie REAL pintada atras (o <body>), nao contra o
   token: 9,54:1 no escuro e 4,80:1 no claro, contra o minimo de 3,0:1 de
   objeto grafico (WCAG 1.4.11). Com a versao do plano (--ambar puro) o mesmo
   filete da 2,03:1 no claro e REPROVA. O plano afirmava 4,0:1 e errou.
   🔴 NENHUM PORTAO VE ISTO. Rodei G1, G2 e G5 com o filete invisivel no lugar
   (--ambar puro) e os TRES deram verde: a matriz FAMILIAS do g1_contraste.py
   so varre token de TEXTO, e traco grafico (--traco-azul, --traco-passo e este)
   vive fora dela. Quem mexer nesta linha mede na mao ou nao mede. */
.percepcao {
  border-top: 2px solid var(--traco-ambar);
  padding-top: 1.25rem;
}

.percepcao h3 { margin-bottom: .5rem; }

/* Sem isto sobra ~1,1em de vazio embaixo do ultimo paragrafo (margin do <p> do
   base.css), e como nao ha caixa em volta o vazio empurra o filete seguinte em
   1 coluna. Mesmo motivo do .card p:last-child. */
.percepcao p:last-child { margin-bottom: 0; }

/* NAO existe reserva de altura no h3 daqui, ao contrario do .card. Os 4 titulos
   sao palavras unicas (Confianca, Excelencia, Cuidado, Acolhimento) e cabem em
   1 linha em TODAS as larguras medidas (360, 390, 560, 561, 768, 900, 901 e
   1440, nos 2 temas), incluindo o pior caso de 185,8px de coluna. Os 4
   paragrafos ja comecam na mesma altura sozinhos - conferido: o topo do <p> e
   identico dentro de cada linha da grade nas 8 larguras. Reserva aqui seria o
   buraco que a Task 5 pegou, sem ter o problema que a Task 5 tinha. */

/* ============================================================
   CONCEITO — a ideia central, na faixa de contraste
   ============================================================ */

/* Duas colunas de leitura: a esquerda carrega rotulo + titulo, a direita o
   texto. A coluna do texto e maior (1.2fr) de proposito - sao 3 paragrafos
   contra um titulo de 3 palavras. */
.conceito-grade {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: clamp(32px, 5vw, 80px);
  /* stretch (o padrao) nao muda nada hoje porque nao ha fundo nem borda nas
     colunas, mas amarra a altura das duas a maior delas; start declara a
     intencao e nao cobra nada de quem acrescentar um filete aqui depois. */
  align-items: start;
}

/* Grade e pai de bloco com texto longo: sem isto a coluna pode se recusar a
   encolher abaixo do conteudo e empurrar rolagem horizontal. Mesmo seguro do
   .hero-texto e do .hero-arte.
   `> *` e nao os 2 nomes de classe: assim uma 3a coluna, se um dia entrar, ja
   nasce protegida.
   ⚠️ `.conceito-titulo` e `.conceito-texto`, no HTML, NAO tem regra propria
   aqui e isso e de proposito - sao so nome para quem le o markup saber qual
   coluna e qual. Nao procure a regra que falta. */
.conceito-grade > * { min-width: 0; }

/* Cap de medida, no mesmo molde dos outros H2 (#entregas 24ch, #metodo 20ch,
   #essencia 26ch). MEDIDO: hoje ele e INERTE em toda largura de 2 colunas -
   em 1440 a coluna tem 454,5px e 14ch dao 464, em 900 e 861 a diferenca e de
   11px e nao muda uma linha. Fica como guarda de medida, nao como ajuste; se
   alguem trocar a copy, e ele que segura.
   ⚠️ `balance` (revisto em 03/10, a copy mudou): o texto antigo era "A ideia
   central e conexao." e a decisao de NAO usar balance protegia a palavra de
   acento sozinha na ultima linha. A copy de hoje e outra, e o PNG de 1440
   decidiu o contrario para o #por-que h2: sem balance sai "Tecnologia que /
   cabe no seu / negocio." (orfa), com balance "Tecnologia / que cabe no / seu
   negocio." - 3 linhas dos 2 jeitos, mesma altura, sem orfa; o acento "cabe"
   fica no meio da linha em vez de abrir a 2a. O balance dele vive no fim do
   arquivo, junto dos outros titulos com orfa medida.
   O #dores h2 tambem entrou: sem balance ele deixava "destes?" sozinho em
   480-580px ("Voce se reconhece em algum / destes?"); nas larguras onde ja
   quebrava bem ("Voce se reconhece / em algum destes?", 861-2560) o balance
   produz a mesma quebra - conferido linha a linha.
   ⚠️ Nem o portao nem a medicao de altura veem esta diferenca - as duas
   versoes tem as mesmas linhas e a mesma altura. So o PNG ve. */
#dores h2, #por-que h2 { max-width: 14ch; }

/* O paragrafo de abertura e a frase do manual que define o conceito; os dois
   seguintes explicam. A hierarquia ja existe na cor (este fica no
   --text-on-contrast cheio, os outros em .texto-suave); o corpo maior e o que
   faz a diferenca aparecer antes da leitura. Mesma escada do .hero-sub e do
   .metodo-intro, entao nao e medida nova no projeto. */
.conceito-abertura {
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
}

/* `pretty`, nao `balance`: sao PARAGRAFOS. balance reparte todas as linhas e
   e para bloco curto (titulo, subtitulo - e o que #essencia h2 e
   .metodo-intro usam); pretty mexe so nas ultimas linhas, evitando que sobre
   uma palavra sozinha.
   MEDIDO numa varredura de 9 larguras (1440, 1200, 1000, 861, 768, 640, 480,
   390, 360), paragrafo a paragrafo: sem pretty saem SEIS ultimas linhas de
   UMA palavra so - "futuro." em 1200, 640 e 360; "personalizada." em 861 e
   640; "marca." em 390 (esta e a que aparece no PNG de 390). Com pretty as 6
   viram "e futuro.", "e personalizada." e "pela marca.".
   ⚠️ CUSTO ZERO DE LAYOUT, medido: nos 27 casos da varredura o numero de
   linhas e a altura em px ficam IDENTICOS com e sem a propriedade - ela so
   escolhe outro ponto de quebra. Nas larguras em que nao ha orfa, nao muda
   nada. Onde nao houver suporte, cai na quebra normal: melhoria progressiva.
   ⚠️ Nenhum portao ve orfa, e contar linha ou medir altura tambem nao (sao
   iguais dos 2 jeitos). So o PNG ve. */
.conceito-grade p { text-wrap: pretty; }

/* Sem isto sobra ~1,1em de vazio no fim da coluna de texto (margin do <p> do
   base.css no ultimo filho), e a faixa de contraste fica com a barriga
   visivelmente maior embaixo. Mesmo motivo do .card p:last-child. */
.conceito-grade p:last-child { margin-bottom: 0; }

/* ============================================================
   RESPONSIVO
   ============================================================ */

@media (max-width: 900px) {
  .hero-grade {
    grid-template-columns: 1fr;
    gap: clamp(28px, 6vw, 48px);
  }
  /* A arte fica DEPOIS do texto no celular. O plano admitia po-la antes; com
     a headline em clamp(2.4rem,6vw,...) uma arte de 400px no topo empurra o
     H1 inteiro para fora da primeira tela, e o que o visitante precisa ler
     primeiro e a frase, nao o grafismo. Medido em 390x844. */
  .hero-arte { order: 2; }
  .hero-texto { order: 1; }
  .hero-arte { --arte-tam: 320px; }
  .hero h1 { max-width: 18ch; }
}

@media (max-width: 560px) {
  .topo-linha { gap: .75rem; }
  .topo-acoes { gap: .5rem; }
  .botao { padding: 0 1.1rem; font-size: .9rem; }

  .hero-acoes .botao { flex: 1 1 100%; }
  /* A arte tem de caber INTEIRA com folga visivel abaixo, senao parece
     defeito e nao intencao. Em 390x844 o texto termina em 609; com o topo do
     hero em 40 e a folga da grade em 24, uma arte de 180px fecha em ~797 e
     sobram ~47px de fundo ate a dobra. Medido, nao estimado. */
  .hero-arte { --arte-tam: 180px; }
  .hero { padding-block: 40px clamp(56px, 9vw, 96px); }
  .hero-grade { gap: 24px; }
}

/* Tela estreita E BAIXA: nao ha altura para texto + arte com folga. Medido em
   360x780 a arte fechava em 823 de 780, cortada pela borda outra vez - e num
   375x667 nao caberia nem perto. Um circulo partido pela dobra le como
   defeito (o manual chama "recorte parcial" de uso incorreto da marca, e
   ainda que aqui seja grafismo derivado o olho nao distingue), entao abaixo
   de 820px de altura a arte sai em vez de aparecer pela metade. Em 390x844
   ela fica, com 47px de fundo visivel abaixo. */
@media (max-width: 560px) and (max-height: 820px) {
  .hero-arte { display: none; }
}

/* Celular BAIXO (iPhone SE/mini, Android compacto, zoom): com a arte fora, o que
   empurra os botoes para baixo da dobra e o .hero-sub (5-6 linhas) somado ao
   header sticky de ~77px. Medido antes, em px que faltavam para a base de
   .hero-acoes entrar: 320x568 81 / 360x568 55 / 375-414x568 37. Corpo de 1rem
   (o piso do clamp, ja e o menor do projeto, nao desce daqui), entrelinha 1.5 e
   respiros menores. */
@media (max-width: 560px) and (max-height: 700px) {
  .hero-sub { font-size: 1rem; line-height: 1.5; margin-top: 1rem; }
  .hero-acoes { margin-top: 1.25rem; gap: .6rem; }
  .hero .rotulo { margin-bottom: .75rem; }
  /* O hero comeca 16px mais perto do header e o header perde 8px de padding
     (sobra o alvo de toque de 44px da marca): so aqui, onde cada px decide se
     o botao aparece. */
  .hero { padding-top: 24px; }
  .topo-linha { padding-block: 10px; }
}

/* 320px de largura E ate 600 de altura (iPhone SE 1a geracao): mesmo com tudo
   acima faltavam ~35px. O titulo desce do piso do clamp (2,2rem) para 2rem:
   32px, ainda acima do corpo de 16px por 2x, e continua em 4 linhas. */
@media (max-width: 359px) and (max-height: 600px) {
  .hero h1 { font-size: 2rem; }
}

/* Paisagem de celular e janela baixa: o header sticky de ~77px e 20% de uma
   tela de 390px. Em 844x390 faltavam 56px, em 720x450 (DPR 2) 2,9px. Abaixo de
   500px de altura ele deixa de acompanhar a rolagem (volta ao fluxo) e perde o
   padding: o menu continua a um toque no topo da pagina, e a navegacao nao
   some, so deixa de ocupar uma faixa fixa de uma tela que nao a tem. */
@media (max-height: 500px) {
  /* `relative`, nao `static`: static derruba o z-index:50 do .topo, e o painel
     do menu (que e filho dele) abria POR BAIXO do hero em 720x450, 667x375 e
     similares - o elementFromPoint nos links devolvia o rotulo do hero. */
  .topo { position: relative; }
  .topo-linha { padding-block: 8px; }
}

/* Paisagem larga (561 a 900px de largura, ate 500 de altura): o H1 em 18ch
   quebrava em 3 linhas dentro de uma tela de 390px de altura. Sem o teto de
   medida cabe em 2 (balance reparte), e o hero comeca mais perto do topo. */
@media (min-width: 561px) and (max-width: 900px) and (max-height: 500px) {
  .hero { padding-top: 16px; }
  .hero h1 { max-width: none; }
  .hero-sub { margin-top: 1rem; }
  .hero-acoes { margin-top: 1.5rem; }
}

/* 3 cards viram 1 coluna de uma vez, sem passo de 2: com 3 itens, duas
   colunas deixam um orfao sozinho na segunda linha. Em 768 o container tem
   ~691px, e tres cards de ~213px ja saem apertados demais para o padding de
   24px+ de cada um. Medido, nao estimado. */
@media (max-width: 860px) {
  .cards { grid-template-columns: 1fr; }
}

/* 4 percepcoes viram 2 colunas e depois 1. Ao contrario dos cards, o passo de 2
   colunas AQUI nao deixa orfao: 4 e par, entao a segunda linha nasce cheia.
   O corte em 900 e o mesmo ponto onde a navegacao do topo sai. MEDIDO em 901,
   o pior caso das 4 colunas: elas ficam com 185,8px e "Acolhimento", o titulo
   mais longo dos 4, ainda cabe em 1 linha. */
@media (max-width: 900px) {
  .percepcoes { grid-template-columns: repeat(2, 1fr); }
}

/* Em 1 coluna o gap horizontal vira vertical e 20px separariam os filetes menos
   do que o filete separa do proprio texto (1,25rem = 20px): os 4 blocos liam
   como lista continua, nao como 4 grupos. Mesmo ajuste da trilha em 1 coluna. */
@media (max-width: 560px) {
  .percepcoes {
    grid-template-columns: 1fr;
    gap: clamp(28px, 8vw, 40px);
  }
}

/* A quebra manual do H2 e composicao, nao copy: em tela estreita ela cria um
   rio no meio da frase, porque a linha ja quebra sozinha. A copy verbatim
   continua identica em qualquer largura - so o ponto de quebra sai. */
@media (max-width: 640px) {
  .quebra-larga { display: none; }
}

/* A trilha colapsa em 1 coluna antes dos cards (800 x 860) porque o conteudo e
   outro: cada passo tem um titulo curto e UMA linha de texto, entao os tres
   ainda cabem lado a lado numa largura em que os cards de 3-4 linhas ja nao
   cabem. Entre 801 e 860px a pagina fica com cards empilhados e passos em
   linha - assimetria consciente, cada bloco quebra onde o proprio texto pede.
   Em 1 coluna a linha horizontal SAI: ligar tres itens empilhados por um traco
   deitado nao liga nada, so sobra um risco solto acima do primeiro. */
@media (max-width: 800px) {
  .trilha { grid-template-columns: 1fr; }
  .trilha::before { display: none; }
  /* Empilhados, os 20px do gap horizontal ficavam quase iguais aos 16px que
     separam a bolinha do titulo DENTRO do passo (medido em 390): os tres
     passos liam como uma lista continua, nao como tres grupos. Na vertical a
     distancia entre grupos tem de ser visivelmente maior que a distancia
     dentro do grupo. */
  .trilha { --trilha-gap: clamp(32px, 9vw, 44px); }
}

/* As 2 colunas do conceito viram 1. O corte e o mesmo 860 dos cards, e pelo
   mesmo motivo: abaixo disso a coluna do texto fica estreita demais para
   paragrafo de 2 a 3 linhas. Em 1 coluna o titulo volta a poder usar a
   largura inteira, entao o max-width de 14ch sai - preso nele, a frase
   quebraria em 2 linhas curtas no meio de uma linha larga e vazia. */
@media (max-width: 860px) {
  .conceito-grade { grid-template-columns: 1fr; }
  /* Em 1 coluna o cap SAI. Preso nos 14ch a frase quebra em 2 linhas curtas
     dentro de uma coluna de 691px (medido em 768) e o titulo fica encolhido
     ao lado de um corpo de texto que usa a largura toda - comparei os 3
     renders lado a lado, e o de 14ch e o unico feio.
     Por que `none` e nao um numero maior: a frase tem 26 caracteres e a linha
     natural mede no MAXIMO 459,8px, no ponto mais largo deste modo (860px de
     viewport). Nao ha medida longa a proteger aqui.
     ⚠️ 20ch, que era o valor do 1o rascunho, da 459,774px em 860 - 0,03px
     ABAIXO da linha natural. Passa hoje por acidente e vira 2 linhas com a
     menor mudanca de metrica de fonte. Numero que empata com o conteudo nao
     e cap, e armadilha. */
  #dores h2, #por-que h2 { max-width: none; }
}

/* ============================================================
   CTA FINAL
   ============================================================ */

/* `position: relative` + `overflow: hidden` existem pelo halo: o ::before e
   dimensionado maior que a secao de proposito (para a borda do circulo nao
   aparecer como circulo) e precisa ser recortado, senao vira rolagem
   horizontal. `background` explicito, ainda que igual ao do body, para a
   secao ser autossuficiente - se um dia algo entrar entre ela e o body, o
   fundo nao muda por acidente. */
.cta {
  position: relative;
  overflow: hidden;
  background: var(--surface-base);
}

/* O halo. Mesma mecanica do .hero-arte::before: cor por color-mix a partir de
   --halo-cta-cor, intensidade em --halo-cta-forca, um valor por tema.
   No tema claro a forca e 0%, entao `color-mix(..., X 0%, transparent)`
   resolve para transparente e o gradiente inteiro some sem custo de pintura -
   a conta que levou a isso esta no tokens.css, e ela e AA, nao gosto.
   ⚠️ Dimensionado em `min(140%, 1100px)` sobre a LARGURA da secao, com
   aspect-ratio 1: nunca por `inset`, que amarraria o halo a altura da secao e
   o deixaria oval em tela estreita (a armadilha que o halo do hero ja
   documenta). O teto de 1100px impede que em tela muito larga o halo cresca
   junto e vire fundo chapado. */
.cta::before {
  content: "";
  position: absolute;
  top: 40%;
  left: 50%;
  width: min(140%, 1100px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 50%,
    color-mix(in srgb, var(--halo-cta-cor) var(--halo-cta-forca), transparent) 0%,
    transparent 62%
  );
  pointer-events: none;
  z-index: 0;
}

/* `.cta-caixa` vem junto de `.container` no HTML e vence o max-width dele por
   ordem de fonte (base.css carrega antes deste arquivo, mesma
   especificidade). O padding-inline do .container continua valendo, entao em
   1440 a coluna util e 760 - 2x64 = 632px. `z-index: 1` poe o conteudo acima
   do halo. */
.cta-caixa {
  position: relative;
  z-index: 1;
  max-width: 760px;
  text-align: center;
}

/* balance, como nos H2 de #metodo e #essencia: a frase tem 5 palavras e, sem
   ele, "conexao?" - justo a palavra de acento - cai sozinha na 2a linha nas
   larguras em que a frase quebra. */
.cta h2 { text-wrap: balance; }

.cta-sub {
  margin: 1.25rem auto 0;
  max-width: 46ch;
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
  /* pretty, nao balance: e paragrafo (mesma doutrina de .conceito-grade p). */
  text-wrap: pretty;
}

.cta-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  justify-content: center;
  margin-top: 2.25rem;
}

/* ============================================================
   RODAPE
   ============================================================ */

/* A divisoria de cima e de largura total (sangra ate a borda da janela),
   igual a do .topo - ela separa o rodape da pagina, nao uma coluna de outra.
   Ja a divisoria do bloco legal, mais abaixo, alinha com o TEXTO. Sao dois
   papeis diferentes, de proposito.
   --borda e o token decorativo (isento da V3 do G1 com justificativa escrita
   la): a linha nao identifica componente nem estado, tira-la nao esconde
   nada. Por isso aqui NAO se usa --traco-controle. */
.rodape {
  border-top: 1px solid var(--borda);
  padding-block: clamp(48px, 6vw, 80px) 32px;
}

/* `minmax(0, 1fr)` e nao `1fr`: `1fr` tem piso de min-content, e o e-mail
   (32 caracteres sem espaco) forcava a coluna a nao encolher - era rolagem
   horizontal garantida nas larguras medias. Medido em 768 antes de trocar. */
.rodape-grade {
  display: grid;
  grid-template-columns: 1.4fr minmax(0, 1fr) minmax(0, 1.3fr);
  gap: clamp(28px, 4vw, 48px);
  align-items: start;
}

/* Altura controlada e width auto, mesmo motivo do topo: os atributos 200x85
   arredondam a proporcao real do viewBox (501,996 / 213,434 = 2,352) e
   "distorcer ou alterar a proporcao" e usos_incorretos do manual. Com
   width:auto o navegador usa a proporcao do viewBox e os atributos servem so
   para reservar espaco (anti-CLS).
   56px de altura valem 131,7px de largura, bem acima do minimo de 90px
   declarado para a assinatura. */
.rodape-marca img {
  height: 56px;
  width: auto;
}
.rodape-marca p {
  margin: 1.1rem 0 0;
  max-width: 30ch;
  font-size: .92rem;
}

.rodape-nav,
.rodape-contato {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* O h3 do rodape nao e titulo de conteudo, e etiqueta de coluna: herdar o
   clamp(1,15rem .. 1,4rem) do base.css faria a palavra "Navegacao" competir
   com o H2 do CTA logo acima. Mesma escala do .rotulo, mas em
   --text-on-base e nao no acento: o acento ja e usado como abertura de secao
   e aqui nao ha secao comecando. */
.rodape h3 {
  font-size: .78rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--text-on-base);
  margin-bottom: .35rem;
}

/* min-height de 44px e o alvo de toque. Nao veio de padding porque padding
   depende do line-height herdado e o resultado dava 36px - medido. Com
   inline-flex a area clicavel tem a LARGURA DO TEXTO (nao a da coluna
   inteira, que daria um alvo enorme e confuso ao lado do texto) e os 44px de
   altura exigidos.
   overflow-wrap: anywhere e o segundo seguro do e-mail: sem ele a palavra de
   32 caracteres nao quebra em coluna estreita. */
.rodape-nav a,
.rodape-contato a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  max-width: 100%;
  color: var(--text-muted-on-base);
  overflow-wrap: anywhere;
  font-size: .92rem;
}
.rodape-nav a:hover,
.rodape-nav a:focus-visible,
.rodape-contato a:hover,
.rodape-contato a:focus-visible {
  color: var(--text-on-base);
}

/* A divisoria daqui alinha com o TEXTO, nao com a borda da janela: o
   border-top direto no elemento seguiria a caixa do .container, que tem
   max-width mas cujo padding-inline recua o conteudo - a linha comecaria
   64px antes da primeira letra e leria como erro. O ::before recua a linha
   pelo mesmo --gutter que recua o texto. */
.rodape-legal {
  position: relative;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  font-size: .82rem;
}
.rodape-legal::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  border-top: 1px solid var(--borda);
}
.rodape-legal p { margin: 0 0 .4rem; }
.rodape-legal p:last-child { margin-bottom: 0; }

/* Politica de Privacidade e Termos de Servico, que sairam da coluna
   Navegacao na Task 12. Flex com wrap porque em 360 os dois nao cabem lado a
   lado e precisam quebrar sem levar o ponto medio para o inicio da linha
   seguinte - com wrap, o separador fica grudado no fim da 1a linha.
   O alvo de toque e o MESMO mecanismo de `.rodape-nav a`: inline-flex +
   min-height 44px, nao padding (padding depende do line-height herdado e
   aqui, com font-size .82rem, daria menos ainda que os 36px medidos la).
   A largura clicavel e a do TEXTO, nao a da linha inteira.
   A margem de cima e negativa de proposito: os 44px do alvo ja incluem um
   respiro visual acima e abaixo do texto, entao sem o desconto a linha
   descolaria do endereco em ~14px que ninguem pediu. Medido.
   Sublinhado: estes 2 links ficam ENCOSTADOS em texto que nao e link (o
   bloco legal), diferente da coluna Navegacao, onde tudo em volta e link.
   Sem o sublinhado nao ha como distinguir link de texto corrido - e cor
   sozinha nao serve, porque aqui os dois herdam --text-muted-on-base. */
.rodape-legal-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 .5rem;
  margin-top: -.35rem;
}
.rodape-legal-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-muted-on-base);
  text-decoration: underline;
  text-underline-offset: .2em;
}
.rodape-legal-links a:hover,
.rodape-legal-links a:focus-visible {
  color: var(--text-on-base);
}

/* 860 e o mesmo corte dos cards e do conceito. Em 2 colunas a marca ocupa a
   linha inteira e nav + contato dividem a de baixo: a 768 isso da 330px por
   coluna e o e-mail cabe inteiro numa linha, o que em 3 colunas (185px) nao
   acontecia. */
@media (max-width: 860px) {
  .rodape-grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rodape-marca { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
  .rodape-grade {
    grid-template-columns: 1fr;
    gap: clamp(24px, 6vw, 32px);
  }
  /* Mesmo tratamento do .hero-acoes: empilhados e de largura cheia. O botao
     do e-mail tem 32 caracteres e `white-space: nowrap` herdado do .botao -
     lado a lado com o de WhatsApp ele nao caberia. */
  .cta-acoes .botao { flex: 1 1 100%; }
}

/* ============================================================
   MOVIMENTO (reveal on scroll)

   Sem cor, so opacidade e deslocamento - nenhuma destas 2 regras conhece
   token de superficie, entao elas valem igual nos 2 temas.

   ⚠️ `.revelar` NUNCA e escrita no HTML. Quem a adiciona e o js/motion.js,
   em runtime, e so em elemento que ainda nao esta na janela. Escreve-la no
   HTML (ou trocar o seletor por `.secao > .container` direto) esconderia a
   pagina inteira de quem esta sem JavaScript - que e exatamente o que a V6
   do G4 reprova.

   A transicao vive na regra base, e nao na `.visivel`, para que ela valha
   no caminho de ida. Como o motion.js pula o que ja esta na tela, o caminho
   de ida (1 -> 0) nunca chega a acontecer em elemento visivel.
   ============================================================ */

.revelar {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}

.revelar.visivel {
  opacity: 1;
  transform: none;
}

/* Cinto e suspensorio: se alguem um dia gravar `.revelar` no HTML, quem
   pede menos movimento continua vendo a pagina. O motion.js ja sai antes
   de tocar no DOM nesse caso; esta regra cobre o caminho que ele nao
   controla. */
@media (prefers-reduced-motion: reduce) {
  .revelar {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================================================
   COPY COMERCIAL (03/10/2026) — variacoes dos componentes ja medidos
   ============================================================ */
/* 4 solucoes em 2x2: 4 colunas deixariam o paragrafo com ~10 palavras por
   linha em 1440, e 3+1 cria orfao. Abaixo de 860 a regra .cards ja empilha. */
/* 4 solucoes: numa linha so em tela larga (pedido do Rafael, 03/10), 2x2 no
   meio e 1 coluna no celular. Nunca 3+1: deixa orfao. */
.cards-duplas { grid-template-columns: repeat(4, 1fr); }
/* Reserva de 2 linhas tambem nas 2 colunas (641-860, onde a regra de 861 do
   .card h3 nao chega): entre 642 e 650px "Agentes de IA e automacao" quebra e o
   paragrafo descia 22px em relacao ao card vizinho. Em 1 coluna (<=640) nao ha
   vizinho, entao nao reserva. */
@media (min-width: 641px) {
  .cards-duplas .card h3 { min-height: 2.4em; }
}
@media (max-width: 1100px) {
  .cards-duplas { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .cards-duplas { grid-template-columns: 1fr; }
}
/* card-num carrega o segmento nos produtos ("Clinicas"): mesma regua, so texto. */
.card-num { text-transform: uppercase; }

/* Trilha de 4 passos: o divisor da linha (ver .trilha::before) passa a 4
   colunas e 3 gaps. */
.trilha-4 { grid-template-columns: repeat(4, 1fr); }
.trilha-4::before {
  right: calc((100% - 3 * var(--trilha-gap)) / 4 - 18px);
}
@media (max-width: 800px) {
  .trilha-4 { grid-template-columns: 1fr; }
}
/* Mesma reserva de 2 linhas do .card h3 (decisao da Task 12): "Proposta
   personalizada" quebra e o texto do 03 descia em relacao aos outros. */
@media (min-width: 801px) {
  .trilha-4 .passo h3 { min-height: 2.4em; }
}

/* Lista de dores: travessao no acento da faixa de contraste, que e token de
   TEXTO (AA medido no G1), nao traco grafico solto. */
.lista-dores {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
  display: grid;
  gap: 1rem;
}
.lista-dores li {
  position: relative;
  padding-left: 1.6rem;
  color: var(--text-muted-on-contrast);
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
  text-wrap: pretty;
}
.lista-dores li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--accent-on-contrast);
}
.conceito-texto strong { font-weight: 600; }
.conceito-texto .conceito-abertura + .conceito-abertura { margin-top: 1rem; }

/* Navegacao do rodape em 2 colunas no celular (pedido do Rafael, 03/10): 4
   links empilhados a 44px viravam ~180px de lista. O h3 ocupa a linha toda;
   o alvo de toque de 44px continua no `a`. */
@media (max-width: 560px) {
  .rodape-nav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 16px;
    align-items: start;
  }
  .rodape-nav h3 { grid-column: 1 / -1; }
}

/* Em 320px o "Falar com a AeS" do topo passava 2px da tela (rolagem lateral,
   medido em 03/10). Abaixo de 360 o botao do topo encolhe o padding. */
@media (max-width: 359px) {
  .topo-acoes .botao { padding: 0 .9rem; font-size: .9rem; }
}

/* Palavra unica sozinha na ultima linha (medida em 03/10, varrendo 320-2560):
   "operacao." no H2 de Solucoes de 600 a 2560, "segmento." no de Produtos,
   "negocio." no de Por que a AeS, "destes?" no de Dores (480-580),
   "rodando." no de Como funciona (340), "demanda"/"automacao"/"tecnologia" nos h3 dos
   4 cards e "empresas" no rotulo do hero em 320/360. `balance` reparte as
   linhas e a palavra deixa de ficar pendurada; onde nao houver suporte cai na
   quebra normal (melhoria progressiva).
   ⚠️ `.trilha-4 h3` entra pelo mesmo motivo, mas "Proposta personalizada" so
   quebra em 1 palavra por linha - isso nao e orfa, e a menor quebra possivel.
   NAO altera a altura: so escolhe outro ponto de quebra, entao a reserva de
   2 linhas (min-height: 2.4em) do `.card h3` (cards lado a lado, ver la), do
   `.cards-duplas .card h3` (a partir de 641px) e do `.trilha-4 .passo h3` (a
   partir de 801px) segue alinhando os paragrafos irmaos - conferido por
   medida do topo de cada <p>. */
#dores h2, #solucoes h2, #produtos h2, #como-funciona h2, #por-que h2,
.cards-duplas h3, .trilha-4 h3,
.hero .rotulo { text-wrap: balance; }

/* Sobra de `balance`: em "Software sob demanda" ele escolhe "Software sob" /
   "demanda", porque a 1a linha e mais estreita em px que "sob demanda". O
   <span> segura o par junto e o texto continua com espaco normal (o G4 e o
   leitor de tela veem a frase intacta, ao contrario de &nbsp;). Onde cabe em
   1 linha nao muda nada. */
.nao-quebra { white-space: nowrap; }

/* Medida de leitura: entre 641 e 860px os cards e o conceito viram 1 coluna e o
   texto corria a largura inteira (container de ~600-780px), com linhas de 81 a
   95 caracteres no #produtos .card p, no #por-que .conceito-abertura e na lista
   de dores - medido a cada 40px, varrendo 320-2560. O teto abaixo segura em ~70
   caracteres. 52ch e o mesmo teto do .secao-intro e do .hero-sub; como `ch` e a
   largura do "0" (mais larga que a letra media da Rubik), 52ch rende ~70
   caracteres por linha, e nao 52 (conforto de leitura: 45 a 75).
   Inerte onde ja nao havia problema: em 2+ colunas o texto e mais estreito que
   52ch, e no celular o container tambem. O cartao continua com a largura da
   coluna - so o texto dentro dele recua, entao os irmaos empilhados seguem
   alinhados entre si (mesma borda esquerda, mesmo teto de medida) e a sobra
   fica como respiro a direita do paragrafo, dentro do cartao. */
.card p,
.conceito-grade p,
.lista-dores li { max-width: 52ch; }
