/* ==========================================================================
   Peter Maker — folha de estilo do site
   Direção visual: hero fotográfico (a foto do Peter: escritório quase preto,
   luz laranja quente, notebook e celular sobre a mesa — com o demo (Casa Moka)
   projetado nas telas), Inter, cards com borda fina.

   Cor de destaque: laranja, como no mockup do Peter (21/09/2026). A logo é
   ouro (#CE9039); pra voltar ao ouro basta trocar as quatro variáveis
   --accent* abaixo, todo o resto lê delas.
   ========================================================================== */

/* ==========================================================================
   Os dois temas
   --------------------------------------------------------------------------
   O tema vive no atributo data-tema do <html>, escrito antes da primeira
   pintura por um script no <head> do index (sem ele a página nasceria escura
   e piscaria pro claro). Escuro é o padrão; claro é escolha do visitante,
   guardada no localStorage.

   Regra pra mexer aqui: **nenhuma cor de fundo, linha ou texto entra
   escrita à mão fora deste bloco.** Tudo lê das variáveis, senão o tema
   claro nasce com buraco preto no meio. As duas exceções conscientes são o
   fundo das prévias da Capacidade e o da tela do hero enquanto o demo não
   carregou — os dois têm a cor do próprio demo, que não muda com o tema.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* Destaque. Três versões de propósito (regra do design-guide): base em área
     preenchida, clareada em letra pequena sobre o escuro. O --accent-rgb
     alimenta todos os rgba() do arquivo. */
  --accent:        #FF6A00;
  --accent-bright: #FF8C3A;
  --accent-glow:   #FFB266;
  --accent-rgb:    255, 106, 0;

  /* Fundo. Preto quente, não preto puro nem azulado: combina com a luz
     laranja e não parece "tema escuro de sistema". O *-rgb existe porque
     meia dúzia de véus e degradês precisam do fundo com transparência. */
  --bg:       #060606;
  --bg-2:     #0b0a09;
  --bg-rgb:   6, 6, 6;
  --bg2-rgb:  11, 10, 9;
  --card:     #100f0e;
  --card-hi:  #171512;
  --line:     rgba(255, 255, 255, .10);
  --line-hi:  rgba(var(--accent-rgb), .45);

  --ink:      #f4f2ef;
  --ink-hero: #e8e4df;        /* o parágrafo do hero, que fica sobre a foto */
  --ink-soft: #b1aaa2;
  --ink-mute: #746e67;

  /* Superfície de vidro: a camada translúcida de botão fantasma, etiqueta,
     contador e cabeça de modelo. No escuro é luz por cima; no claro, sombra. */
  --vidro:    rgba(255, 255, 255, .02);
  --vidro-2:  rgba(255, 255, 255, .06);
  --vidro-3:  rgba(255, 255, 255, .20);

  /* Malha de pontos do contato (o canvas lê estas duas pelo getComputedStyle) */
  --malha-calmo: 255, 178, 102;
  --malha-aceso: 255, 140, 58;

  /* Foto do hero: largura da original, usada pelo recorte do celular */
  --foto-w: 1774;
  /* Zoom da foto dentro do quadro do hero. A foto escura é a referência, então
     aqui é 1; o tema claro sobe esse número pra igualar o tamanho das telas
     (ver "As duas fotos não mostram os aparelhos do mesmo tamanho"). */
  --zoom-foto: 1;
  --vidro-tela: .08;          /* força do reflexo diagonal na tela do notebook */
  --luz-card: .16;            /* força do holofote que segue o cursor */

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --wrap: 1180px;
  --wrap-hero: 1280px;

  /* Altura do cabeçalho fixo. Vive aqui porque seis lugares dependem dela: a
     própria barra, a gaveta do menu no celular (que abre logo abaixo), o
     scroll-padding das âncoras, a altura mínima do hero e a do contato. Antes
     eram seis números soltos, e mudar a barra desalinhava os outros cinco.
     A folga vertical da logo sai daqui: a logo tem 130px de largura, ou seja
     79px de altura, e 120 - 79 dá ~20px de respiro em cima e embaixo. Os 104
     da primeira tentativa (13px de folga) ainda deixavam os cantos da logo
     perto dos cantos da barra — 25/09, segunda volta do Peter. */
  --h-topo: 120px;

  --radius: 18px;
  --radius-lg: 24px;
  --radius-xl: 30px;
  --shadow-md: 0 10px 30px rgba(0, 0, 0, .35);
  --shadow-lg: 0 24px 70px rgba(0, 0, 0, .55);
  --glow: 0 0 40px rgba(var(--accent-rgb), .35);

  /* Brilho do texto laranja. Duas camadas: um halo curto que dá o corpo da
     luz e um longo que espalha no preto. O forte é só pra letra grande —
     em texto pequeno um raio largo borra o contorno em vez de iluminar. */
  --glow-texto:     0 0 16px rgba(var(--accent-rgb), .40), 0 0 44px rgba(var(--accent-rgb), .20);
  --glow-texto-min: 0 0 10px rgba(var(--accent-rgb), .32);
  --glow-icone:     drop-shadow(0 0 8px rgba(var(--accent-rgb), .30));
}

/* Tema claro ----------------------------------------------------------------
   Não é o escuro invertido. Três coisas mudam de natureza:

   1. **O laranja escurece.** #FF6A00 em letra pequena sobre fundo claro dá
      3,0:1 — reprova. A versão de texto vira #B84400 (4,9:1 sobre o --bg),
      e a de área preenchida, #E35C00. É a regra das três versões do
      design-guide, aplicada do outro lado.
   2. **O brilho sai.** Halo laranja em texto só funciona sobre o escuro; no
      claro vira borrão. Por isso --glow-texto* viram `none`.
   3. **A foto do hero troca** (assets/imagens/hero-claro.*), e com ela os
      cantos das telas — quem cuida disso é o main.js, "Telas do hero".

   O fundo é bege bem claro, não branco puro, e o texto é quase-preto quente,
   não #000: mesma regra do design-guide que vale pros sites de cliente. */
:root[data-tema="claro"] {
  color-scheme: light;

  --accent:        #E35C00;
  --accent-bright: #B84400;
  --accent-glow:   #FF8C3A;
  --accent-rgb:    227, 92, 0;

  --bg:       #F6F4F1;
  --bg-2:     #EBE7E1;
  --bg-rgb:   246, 244, 241;
  --bg2-rgb:  235, 231, 225;
  --card:     #FFFFFF;
  --card-hi:  #FFFFFF;
  --line:     rgba(23, 19, 16, .13);
  --line-hi:  rgba(var(--accent-rgb), .40);

  --ink:      #171310;
  --ink-hero: #3F3934;
  --ink-soft: #554E48;
  --ink-mute: #857C74;

  --vidro:    rgba(23, 19, 16, .025);
  --vidro-2:  rgba(23, 19, 16, .05);
  --vidro-3:  rgba(23, 19, 16, .18);

  --malha-calmo: 197, 120, 60;
  --malha-aceso: 227, 92, 0;

  --foto-w: 1440;
  /* A foto clara pegou os aparelhos de mais longe: sem isso a tela do notebook
     e a do celular saem 4,5% menores que na escura (medido no navegador em
     28/09: área 146.365 contra 160.312 px² no notebook, 49.402 contra 54.167
     no celular). 1,0468 = raiz da razão entre as áreas, e o mesmo número serve
     pros dois aparelhos porque a foto clara é a mesma cena um passo atrás.
     Vale só de 901px pra cima; abaixo disso quem manda é o recorte
     (--cx0/--cy0/--cw/--ch), corrigido lá embaixo. */
  --zoom-foto: 1.0468;
  --vidro-tela: .05;
  --luz-card: .10;

  --shadow-md: 0 10px 30px rgba(40, 28, 16, .10);
  --shadow-lg: 0 24px 60px rgba(40, 28, 16, .16);
  --glow: 0 10px 26px rgba(var(--accent-rgb), .28);
  --glow-texto:     none;
  --glow-texto-min: none;
  --glow-icone:     none;
}

/* Reset -------------------------------------------------------------------- */

/* Inter, hospedada aqui mesmo -------------------------------------------
   Era um <link> pro fonts.googleapis.com: dois preconnect, um CSS externo
   e cinco arquivos de peso, 95 KB e seis conexões fora do domínio. Este é
   um arquivo só, a versão variável, que cobre 400 a 800 em 48 KB — e vem
   do mesmo servidor do site, então não paga DNS nem TLS de novo. Só o
   subset latin: o português inteiro cabe em U+0000-00FF. Peso novo fora
   de 400-800 não existe; se precisar, o navegador interpola dentro da
   faixa. Licença SIL OFL 1.1 (ver assets/fontes/LEIAME.txt). */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../assets/fontes/inter-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

*, *::before, *::after { box-sizing: border-box; }

/* Nada de selecionar, nada de zoom -------------------------------------------
   Pedido do Peter (24/09/2026), a mesma decisão que já vale no site do
   Colégio Aprov. Tem custo real e conhecido: quem quiser copiar o telefone,
   o endereço ou um trecho do texto não consegue, e quem enxerga pouco perde
   o gesto de pinça pra ampliar. Não é acidente — é escolha, e está registrada
   no ESTADO-DO-SITE.md pra não ser "consertada" por engano.

   São três camadas, porque nenhuma sozinha resolve:
     - user-select: none        → tira a seleção de texto com mouse e toque;
     - touch-action: manipulation → mata o zoom de dois toques no celular;
     - o resto (pinça e ctrl+roda) é o viewport do HTML e o main.js.
   O -webkit-touch-callout evita o balão de "copiar" do iOS ao segurar. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--h-topo) + 6px);
  touch-action: manipulation;
}

/* Barra de rolagem escondida (pedido do Peter, 28/09/2026). A página continua
   rolando por roda, toque e teclado; some só a barra do lado. Duas regras
   porque nenhum navegador entende as duas: scrollbar-width é Firefox e Chrome
   novo, o ::-webkit-scrollbar é Safari e Chrome antigo. A rolagem suave da
   roda está no main.js. */
html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar,
body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* Cursor de mira (pedido do Peter, 28/09/2026): branca no tema escuro, preta
   no claro. Vale em tudo, inclusive link e botão — por isso o !important, que
   passa por cima dos cursor: pointer espalhados pela folha. Custo: some a
   mãozinha que avisa "isto é clicável".
   32px é o teto seguro: acima disso o Chrome troca o cursor pela seta quando
   ele encosta na borda da janela. O @2x é pra tela de alta densidade. Os
   originais, grandes demais pra ir pro ar, estão em site/ (fora de web/).
   Três linhas por regra: o navegador fica com a última que entender, e o
   url() sozinho é o que sobra pra quem não conhece image-set.
   Só com mouse (29/09/2026): no celular não existe cursor, mas o navegador
   baixava a imagem mesmo assim — na página e em cada iframe do hero. */
@media (hover: hover) and (pointer: fine) {
  html, html * {
    cursor: url(../assets/imagens/mira-branca.png) 16 16, crosshair !important;
    cursor: -webkit-image-set(url(../assets/imagens/mira-branca.png) 1x, url(../assets/imagens/mira-branca@2x.png) 2x) 16 16, crosshair !important;
    cursor: image-set(url(../assets/imagens/mira-branca.png) 1x, url(../assets/imagens/mira-branca@2x.png) 2x) 16 16, crosshair !important;
  }
  html[data-tema="claro"], html[data-tema="claro"] * {
    cursor: url(../assets/imagens/mira-preta.png) 16 16, crosshair !important;
    cursor: -webkit-image-set(url(../assets/imagens/mira-preta.png) 1x, url(../assets/imagens/mira-preta@2x.png) 2x) 16 16, crosshair !important;
    cursor: image-set(url(../assets/imagens/mira-preta.png) 1x, url(../assets/imagens/mira-preta@2x.png) 2x) 16 16, crosshair !important;
  }
}

/* Mira desenhada (28/09, segundo pedido): 40px e pulsando em cima de tudo que
   é clicável. Cursor de sistema não anima nem passa de 32px com segurança,
   então o main.js esconde o cursor (.tem-mira) e põe no lugar este elemento,
   que segue o ponteiro. As regras de cima ficam de reserva pra quando o JS não
   roda e pro instante antes dele. Só em aparelho com mouse — no toque não há
   cursor. Sobre as telas do hero quem avisa a posição é o próprio demo, e o
   .tela__sonda é o ponto que converte a coordenada dele pra da página. */
html.tem-mira, html.tem-mira * { cursor: none !important; }
.mira {
  position: fixed;
  left: 0; top: 0;
  z-index: 2147483647;
  width: 40px; height: 40px;
  margin: -20px 0 0 -20px;               /* o centro da mira é o ponto do clique */
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s;
  will-change: transform;
}
.mira.is-visivel { opacity: 1; }
.mira__img {
  width: 100%; height: 100%;
  background: url(../assets/imagens/mira-branca-96.png) center / contain no-repeat;
}
html[data-tema="claro"] .mira__img { background-image: url(../assets/imagens/mira-preta-96.png); }
.mira.is-alvo .mira__img { animation: mira-pulsa .9s ease-in-out infinite; }
@keyframes mira-pulsa {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.25); }
}
.tela__sonda { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .mira.is-alvo .mira__img { animation: none; transform: scale(1.15); }
}

body, .btn, a, button {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
/* Sem isso o display do .btn ganha do hidden do navegador e o botão sem link aparece */
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
figure { margin: 0; }
h1, h2, h3, p { margin: 0; }

.wrap { width: min(var(--wrap), 100% - 40px); margin-inline: auto; }
.ico { width: 20px; height: 20px; flex: none; }
.ico--fim { width: 18px; height: 18px; }

/* Tipografia --------------------------------------------------------------- */

.kicker {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-bright);
  text-shadow: var(--glow-texto-min);
  margin-bottom: 14px;
}

.title {
  font-size: clamp(30px, 3.6vw, 44px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -.025em;
}

/* A segunda metade do título em laranja é o gesto que repete em todas as
   seções. É <em> no HTML, sem itálico, pra manter semântica de ênfase. */
.title em, .hero__title em { font-style: normal; color: var(--accent-bright); text-shadow: var(--glow-texto); }

.lead {
  color: var(--ink-soft);
  font-size: 17.5px;
  max-width: 560px;
  margin: 18px 0 28px;
}

/* Botões ------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 12px 26px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 15.5px;
  line-height: 1.2;
  text-align: center;
  border: 1.5px solid transparent;
  transition: transform .18s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease;
  cursor: pointer;
}

.btn--primary {
  background: linear-gradient(135deg, var(--accent-glow), var(--accent));
  color: #1a0900;
  box-shadow: var(--glow);
}
.btn--primary:hover { transform: translateY(-2px); box-shadow: 0 0 55px rgba(var(--accent-rgb), .5); }

.btn--ghost {
  border-color: var(--line-hi);
  color: var(--ink);
  background: var(--vidro);
}
.btn--ghost:hover { border-color: var(--accent-bright); background: rgba(var(--accent-rgb), .08); transform: translateY(-2px); }

.btn--sm { min-height: 42px; padding: 8px 18px; font-size: 14.5px; }

/* Cabeçalho ---------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(var(--bg-rgb), .82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

/* Ordem na barra: logo · (sobra) · tema e idioma · menu e "Fale conosco".
   Pedido do Peter em 25/09: o menu e o botão de WhatsApp voltam pro canto
   direito, onde ficavam, e os dois botões de tema e idioma entram logo antes
   deles. Quem come a sobra é o .ferramentas, então os dois grupos andam
   juntos e param colados no fim da barra.

   A largura continua sendo --wrap (1180px). Chegou a ir pra --wrap-hero
   (1280px) na primeira tentativa, pra alinhar com a foto — mas isso encostava
   a logo na borda, que é justamente o que ele queria evitar. */
.header__inner {
  display: flex;
  align-items: center;
  gap: 18px;
  height: var(--h-topo);
}
.header__logo { flex: none; }
.header__logo img { width: 130px; height: auto; display: block; }
/* Come toda a sobra da barra: a partir daqui, tema/idioma e o menu andam
   colados e param no fim. Vale também com a gaveta, onde o menu sai do fluxo
   e sobram só a logo, as ferramentas e o botão de três riscos. */
.header__inner > .ferramentas { margin-left: auto; }

/* Uma logo por tema: a branca sobre o escuro, a de cor sobre o claro.
   Vale no cabeçalho, no rodapé e na página de erro. */
:root[data-tema="escuro"] .logo--claro,
:root[data-tema="claro"]  .logo--escuro { display: none; }

/* O afastamento extra separa os dois botões de ferramenta do menu — com só o
   gap de 18px da barra os dois grupos leem como um bloco só. */
.nav { display: flex; align-items: center; gap: 30px; margin-left: 10px; }
.nav__link {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.nav__link:hover, .nav__link.is-active { color: var(--ink); border-bottom-color: var(--accent); }
.nav__cta { margin-left: 8px; min-height: 44px; padding: 9px 20px; font-size: 14.5px; }

.menu-toggle {
  display: none;
  flex: none;                 /* nunca encolhe: é o único caminho pro menu no celular */
  width: 46px; height: 46px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  align-items: center; justify-content: center;
  cursor: pointer;
}
.menu-toggle .ico { width: 24px; height: 24px; }
.menu-toggle .ico--fechar { display: none; }
.menu-toggle[aria-expanded="true"] .ico--abrir { display: none; }
.menu-toggle[aria-expanded="true"] .ico--fechar { display: block; }

/* Tema e idioma -------------------------------------------------------------
   Os dois controles ficam FORA da gaveta do menu, entre a navegação e o
   botão de três riscos. No celular isso importa: trocar o idioma não pode
   exigir abrir o menu primeiro — quem caiu aqui num idioma que não lê
   precisa achar a troca na primeira tela. */

.ferramentas { display: flex; align-items: center; gap: 8px; }

.ferramenta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 42px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--vidro);
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}
.ferramenta:hover { color: var(--ink); border-color: var(--line-hi); background: rgba(var(--accent-rgb), .07); }
.ferramenta:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.ferramenta .ico { width: 18px; height: 18px; }

/* Um ícone por tema: o sol é o que você VAI ter, não o que já está. */
.ferramenta--tema { width: 42px; padding: 0; }
:root[data-tema="escuro"] .ferramenta--tema .ico--lua,
:root[data-tema="claro"]  .ferramenta--tema .ico--sol { display: none; }

.idioma { position: relative; }
.idioma__sigla { letter-spacing: .06em; }

.idioma__lista {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  min-width: 178px;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--shadow-md);
}
/* A lista some por opacity/visibility, não por display: assim ela pode
   animar, e o [hidden] continua valendo pra quem chega sem JS. */
.idioma__lista[hidden] { display: none; }

.idioma__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.idioma__item:hover { background: var(--vidro-2); color: var(--ink); }
.idioma__item:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -2px; }
.idioma__item[aria-checked="true"] { color: var(--accent-bright); text-shadow: var(--glow-texto-min); }
.idioma__item .ico { width: 16px; height: 16px; margin-left: auto; opacity: 0; flex: none; }
.idioma__item[aria-checked="true"] .ico { opacity: 1; }
.idioma__bandeira {
  flex: none;
  width: 22px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  color: var(--ink-mute);
}
.idioma__item[aria-checked="true"] .idioma__bandeira { color: inherit; }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;   /* fallback */
  overflow: clip;     /* NÃO rolável, nem por programa — ver nota do .tela */
  display: flex;
  align-items: center;
  /* A foto é 2:1. Com a altura presa em 50vw (limitada pela janela), no
     desktop ela cabe inteira quase sempre — e os aparelhos ficam onde a foto
     os pôs, à direita do texto. Só cresce além disso se o texto precisar. */
  min-height: min(calc(100svh - var(--h-topo)), 50vw);
  padding: 48px 0 72px;
}

.hero__inner {
  position: relative;
  z-index: 1;                 /* acima do cenário */
  pointer-events: none;       /* a coluna vazia da direita deixa o clique passar pras telas */
  width: min(var(--wrap-hero), 100% - 40px);
  display: grid;
  grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);   /* ~40% texto, ~60% aparelhos (que estão na foto) */
  align-items: center;
  gap: 40px;
}
.hero__text { pointer-events: auto; }

.hero__title {
  font-size: clamp(30px, 3vw, 43px);   /* caixa alta ocupa ~18% mais largura: menor em px, mesma altura de caixa alta na tela */
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -.03em;
  text-transform: uppercase;
  width: fit-content;   /* a caixa abraça a linha mais longa, pra centrar DIGITAL pelo texto e não pela coluna */
}

/* O título do hero quebra em três linhas fixas, sem <br>: a palavra do meio
   e a linha laranja viram bloco. "DIGITAL" é curta e fica centrada entre as
   duas linhas longas — é escolha de composição, não sobra de quebra. */
.hero__title-meio { display: block; text-align: center; }
.hero__title em { display: block; }

.hero__lead { color: var(--ink-hero); font-size: 17.5px; max-width: 500px; margin: 22px 0 30px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

.hero__pontos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 24px;
  margin-top: 36px;
  font-size: 14.5px;
  color: var(--ink-soft);
}
.hero__pontos li { display: flex; align-items: center; gap: 10px; }
.hero__pontos .ico { color: var(--accent-bright); }

/* Cenário -------------------------------------------------------------------
   A foto do Peter (escritório escuro, notebook e celular sobre a mesa) é o
   fundo do hero inteiro. As telas dos dois aparelhos são recobertas por um
   iframe cada, com o demo (Casa Moka) rodando em tamanho real e projetado com
   matrix3d pra cair nos quatro cantos da tela na foto (main.js, "Telas do
   hero"). Não tem perspective no pai nem preserve-3d: cada tela é um único
   elemento transformado, e o hit-test do navegador cai direto no iframe —
   foi o 3D aninhado que engolia a roda do mouse na versão em CSS. */
.hero__cena { position: absolute; inset: 0; z-index: 0; }

.hero__quadro {
  position: absolute; inset: 0;
  overflow: hidden;   /* fallback */
  overflow: clip;
  container-type: size;       /* pras unidades cq* da caixa da foto */
}

/* Caixa da foto, sempre na proporção dela (1774×887) e sempre com a largura
   do quadro — assim notebook e celular ficam na mesma posição em relação ao
   texto em qualquer janela. Se o hero for mais alto que 2:1 (o texto
   precisa), a foto encosta embaixo e o topo dela se dissolve no fundo
   (gradiente da .hero__luz). Se for mais baixo (janela larga e curta), o
   corte fica 35% em cima e 65% embaixo, na mesa, pra não perder o notebook.
   No celular (media query lá embaixo) mostra só o recorte dos aparelhos.
   Tudo que está dentro — foto, luz e telas — é posicionado em relação a
   ela, então escala junto. */
/* As duas fotos do hero são 2:1 — é dessa proporção que sai o 50cqw das
   contas daqui e o 50vw do min-height do .hero. Foto nova que não seja 2:1
   quebra as duas coisas juntas. */
/* O --zoom-foto multiplica a largura e fica centrado na horizontal (o left
   negativo é metade do que sobrou). A conta do top é a mesma de antes, só que
   a meia-largura virou 50cqw × zoom — sem isso o pé da foto descolaria da
   borda de baixo no tema claro. Com zoom 1 (tema escuro) as três linhas dão
   exatamente o que davam antes. O JS não precisa saber de nada disso: os
   cantos das telas são fração da caixa da foto, então crescem junto e a tela
   continua encaixada no aparelho. */
.hero__foto {
  position: absolute;
  left: calc(50cqw - (50cqw * var(--zoom-foto)));
  width: calc(100cqw * var(--zoom-foto));
  aspect-ratio: 2 / 1;
  top: max(calc(100cqh - (50cqw * var(--zoom-foto))), calc((100cqh - (50cqw * var(--zoom-foto))) * .35));
}
/* <picture> com display: contents some do layout, entao a <img> continua se
   comportando como filha direta da caixa da foto. Os seletores abaixo usam
   descendente (sem >) pelo mesmo motivo. */
.hero__foto picture, .hero__frente picture, .header__logo picture,
.footer__logo picture { display: contents; }

.hero__foto img { display: block; width: 100%; height: 100%; pointer-events: none; }

/* Uma foto por tema. As duas são 2:1, então a caixa não muda de forma — o
   que muda são os cantos das telas, que o main.js relê do data-cantos-claro
   na hora da troca. A foto que não está em uso fica em display: none e
   nasce com loading="lazy" no HTML: assim o navegador só busca os bytes da
   que vai aparecer. */
:root[data-tema="escuro"] .hero__foto .foto--claro,
:root[data-tema="claro"]  .hero__foto .foto--escuro,
:root[data-tema="escuro"] .hero__frente .foto--claro,
:root[data-tema="claro"]  .hero__frente .foto--escuro { display: none; }

/* O corpo do celular recortado só existe pra foto escura, onde o celular
   está na frente da tela do notebook. Na foto clara os dois aparelhos ficam
   lado a lado, sem sobreposição — medido em 24/09: a borda direita da tela
   do notebook encosta na esquerda do celular, com 5 a 7px de moldura entre
   elas e nenhuma invasão. */
:root[data-tema="claro"] .hero__frente { display: none; }

/* Luz por cima da foto e embaixo das telas: escurece o lado do texto (as
   faixas laranja da parede passam atrás do parágrafo) e emenda o pé da foto
   no fundo da seção seguinte. */
.hero__luz {
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(var(--bg-rgb), .80) 0%, rgba(var(--bg-rgb), .66) 26%, rgba(var(--bg-rgb), .30) 42%, transparent 54%),
    linear-gradient(180deg, var(--bg) 0%, rgba(var(--bg-rgb), .55) 7%, transparent 20%, transparent 76%, var(--bg) 100%);
}

/* Corpo do celular por cima da tela do notebook. É a mesma foto (e a mesma
   luz) de novo, recortada pelo contorno do celular — o JS monta o clip-path
   a partir do data-contorno/data-raio. Assim o celular fica na frente do
   site do notebook, como está na foto. */
.hero__frente {
  position: absolute; inset: 0;
  z-index: 2;
  pointer-events: none;
  clip-path: polygon(0 0, 0 0, 0 0);   /* invisível até o JS recortar */
}
.hero__frente img { display: block; width: 100%; height: 100%; }

/* Tela = iframe com o site em tamanho real (1200×750 no notebook, 360×780 no
   celular). A caixa fica em 0,0 da foto com esse tamanho e o JS aplica a
   matrix3d que a leva pros cantos medidos; transform-origin 0 0 pra conta
   bater. Até o JS rodar fica invisível — sem JS aparece a tela da própria
   foto, que já é um mockup. --vw/--vh vivem aqui porque mudam no breakpoint
   do celular. */
.tela {
  position: absolute;
  left: 0; top: 0;
  z-index: 1;
  width: calc(var(--vw) * 1px);
  height: calc(var(--vh) * 1px);
  /* clip, não hidden: hidden ainda deixa a caixa rolável por programa, e a
     rolagem suave de uma âncora dentro do iframe tenta rolar os ancestrais
     em sequência — o seguro do JS que zerava a caixa abortava a sequência
     inteira, e o site de dentro parava de rolar (só no Edge com janela). Com
     clip a caixa não é rolável de jeito nenhum. hidden fica de fallback. */
  overflow: hidden;
  overflow: clip;
  /* Cor do fundo do demo que está na tela, pra não piscar enquanto ele carrega.
     O padrão é o marrom da Casa Moka, que é quem abre; o trocador reescreve
     esta variável a cada troca com o data-fundo do demo escolhido (main.js,
     "Trocador de demo do hero"). É a exceção consciente à regra de cor por
     variável de tema: é a cor do demo, que não muda com o tema da página. */
  background: var(--tela-fundo, #2A1610);
  transform-origin: 0 0;
  visibility: hidden;
  will-change: transform;
}
.tela.is-projetada { visibility: visible; }
.tela iframe { display: block; width: 100%; height: 100%; border: 0; background: var(--tela-fundo, #2A1610); }

/* Tela de toque (29/09/2026): o dedo não entra no demo. Arrastar em cima das
   telas rola a PÁGINA (antes rolava o demo e o visitante ficava preso ali), e
   um toque cai no .tela__abrir, o link que o main.js estica sobre cada tela e
   que abre o demo escolhido inteiro, numa aba nova. Com mouse, nada muda: o
   link some e o iframe continua clicável e rolável. A frase embaixo das telas
   acompanha — cada tipo de aparelho lê a sua. */
.tela__abrir { display: none; }
.hero__dica-toque { display: none; }
@media (hover: none) and (pointer: coarse) {
  .tela iframe { pointer-events: none; }
  .tela__abrir { display: block; position: absolute; inset: 0; z-index: 3; }
  .hero__dica-mouse { display: none; }
  .hero__dica-toque { display: inline; }
}

.tela--notebook { --vw: 1200; --vh: 750; border-radius: 10px; }

/* O demo do mesmo tamanho e da mesma forma nos dois temas --------------------
   As telas das duas fotos não têm nem a mesma forma nem o mesmo tamanho: a
   foto clara pegou os aparelhos de mais longe. Com o mesmo retângulo de origem
   nos dois temas, o demo saía esticado num e achatado no outro, e menor no
   claro. Pedido do Peter em 25/09, nas duas voltas: primeiro igualar a forma,
   depois **igualar também o tamanho**, mesmo sabendo que a tela da foto clara
   é menor.

   A correção vai no retângulo de origem, NUNCA nos cantos: os cantos são
   medida da foto, mexer neles desalinha a tela do aparelho.

   A conta: com o quadrilátero de destino fixo, a escala horizontal do que
   aparece é proporcional a 1/--vw e a vertical a 1/--vh. Então, medindo a
   escala média nos dois temas (jacobiana da homografia num grid de 9×9 dentro
   de cada tela — não a razão entre as bordas, que é só uma amostra de
   perspectiva), o tamanho novo é regra de três:

     --vw do claro = 1200 × (escala h do claro ÷ escala h do escuro)
     --vh do claro =  750 × (escala v do claro ÷ escala v do escuro)

   **São três faixas, porque abaixo de 900px cada tema mostra um recorte
   diferente da foto** (o `--cx0/--cy0/--cw/--ch` do `.hero__quadro`), e aí a
   relação de tamanho entre as duas telas muda:

   **28/09, terceira volta: o tema claro não tem mais retângulo próprio.**
   Durante o dia esse bloco chegou a ter 1231×733 no claro, calculado pra
   compensar a forma da foto. O Peter cortou o assunto: *"pegue exatamente o
   tamanho do site demo do modo escuro e replique EXATAMENTE IGUAL no modo
   claro."* Então **não existe mais nenhuma regra `[data-tema="claro"]` de
   `--vw`/`--vh`** — o claro herda 1200×750 e 360×780 do escuro, nas três
   faixas, e o demo mostra exatamente a mesma página, com o mesmo corte e as
   mesmas quebras de linha.

   Quem iguala o TAMANHO agora é só o `--zoom-foto` (ver o `.hero__foto`) e,
   abaixo de 900px, o recorte (`--cx0/--cy0/--cw/--ch`). Medido depois: a área
   da tela bate com a do escuro dentro de 0,3% nas três faixas.

   **O que não dá pra igualar, e o Peter sabe:** o notebook da foto clara está
   num ângulo um pouco mais aberto, então a tela dele é um retângulo
   ligeiramente mais largo e mais baixo. Com o mesmo 1200×750 nos dois temas, o
   texto do demo sai **~2,5% mais largo e ~2,5% mais baixo** no claro. O
   tamanho total é o mesmo (a área bate); o que muda é a proporção, e isso vem
   da foto, não do CSS. Só sumiria com outra foto — ou desencaixando a tela do
   aparelho, que custa 13px no canto inferior direito e foi recusado.

   **Não reintroduzir um `--vw`/`--vh` só do claro sem falar com ele.** Já foi
   feito duas vezes (25/09 e 28/09) e desfeito. */
/* Vidro: brilho diagonal bem fraco por cima do site, como a tela da foto.
   pointer-events: none pra não roubar o clique do iframe. */
.tela--notebook::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(112deg, rgba(255, 255, 255, var(--vidro-tela)) 0%, rgba(255, 255, 255, calc(var(--vidro-tela) * .3)) 30%, transparent 48%);
}

.tela--celular { --vw: 360; --vh: 780; z-index: 3; }   /* acima da .hero__frente; o raio dos cantos vem do JS (data-raio) */
/* Ilha dinâmica, por cima do site */
.tela--celular::before {
  content: "";
  position: absolute;
  z-index: 2;
  top: 14px; left: 50%;
  width: 100px; height: 16px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: #050505;
  pointer-events: none;
}

/* O celular da foto clara é de outra geração: tem notch, não ilha. E o
   notch fica DENTRO do quadrilátero da tela (medido: a borda de cima da
   tela está em y≈249 e o notch desce até y≈262 na foto), então o iframe
   passaria por cima dele e o aparelho perderia o recorte. Por isso ele é
   redesenhado aqui.

   As medidas não são as da foto divididas pela largura: a projeção é
   perspectiva, e o mesmo passo em px da tela vale menos do lado que está
   mais longe. Os 18,2% e 74,5% saem da conta de peso entre as duas
   laterais do trapézio (322px de altura na esquerda, 342px na direita). */
:root[data-tema="claro"] .tela--celular::before {
  top: 0;
  left: 18.2%;
  width: 56.3%;
  /* Em porcentagem, não em px: a medida original era 30px quando --vh era 780
     (3,846%). Desde 28/09 o --vh voltou a ser 780 nos dois temas, então em px
     daria no mesmo — a porcentagem fica porque é o certo: se um dia o --vh do
     claro voltar a divergir, o notch continua caindo no mesmo lugar da foto,
     que é o que importa. */
  height: 3.846%;
  transform: none;
  border-radius: 0 0 18px 18px;
  background: #0A0A0A;
}

/* Trocador do demo, embaixo dos aparelhos -------------------------------------
   Duas setas laranjas com o nome do modelo no meio (pedido do Peter,
   28/09/2026). Três posições, todas embaixo dos aparelhos: acima de 1140px
   fica solto sobre a mesa da foto, centrado no par (que vai de 47,9% a 93,7%
   da foto); de 901 a 1140px anda pra esquerda e fica embaixo do notebook,
   porque a mesa sob o celular encolhe junto com a janela e deixa de caber;
   abaixo de 900px cai no fluxo, entre a moldura e a legenda. As duas últimas
   são media queries lá embaixo.

   Os quatro nomes ficam na MESMA célula de grade (grid-area 1/1), então a
   caixa nasce com a largura do nome mais longo e as setas não andam pra frente
   e pra trás quando o nome muda. A troca é um fade curto; a visibility entra
   na transição pra que o nome que saiu não sobre na árvore de acessibilidade
   (o bloco é aria-live, leitor de tela leria os quatro). */
.hero__trocador {
  position: absolute;
  z-index: 4;
  left: 50%; right: 4%;
  /* 42px do pé da foto: é o que centra o trocador na faixa livre entre o
     aparelho mais baixo e a legenda **no tema claro**, que é o apertado — a
     foto clara pega os aparelhos um passo atrás e mais pra baixo, e lá sobram
     53px entre a base do celular e a legenda (contra 67 no escuro). Isso vale
     acima de 1140px; abaixo, quem dá o ar é a media query. */
  bottom: 42px;
  /* Escondido até o JS ligar (.is-pronto). Sem JS as telas também não carregam
     — aparece a tela da própria foto — e setas que não trocam nada seriam
     mobília morta. */
  display: none;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.hero__trocador.is-pronto { display: flex; }

.trocador__seta {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  padding: 0;
  border: 1px solid rgba(var(--accent-rgb), .45);
  border-radius: 50%;
  background: rgba(var(--accent-rgb), .12);
  color: var(--accent-bright);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .12s ease;
}
/* Área de toque maior que o desenho: a seta tem 34–38px, pouco pro dedo. O
   ::after invisível estende o alvo pra ~48px sem mudar nada no visual. */
.trocador__seta { position: relative; }
.trocador__seta::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; }
.trocador__seta:hover { background: rgba(var(--accent-rgb), .22); border-color: var(--accent-bright); }
.trocador__seta:active { transform: scale(.92); }
.trocador__seta:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
.trocador__seta .ico { width: 19px; height: 19px; filter: var(--glow-icone); }
.trocador__seta--antes .ico { transform: scaleX(-1); }   /* a mesma seta, espelhada */

.trocador__nomes { display: grid; align-items: center; justify-items: center; }
.trocador__nome {
  grid-area: 1 / 1;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
  text-shadow: 0 1px 3px rgba(var(--bg-rgb), .55);   /* a foto embaixo é textura, não fundo liso */
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s ease;
}
.trocador__nome.is-ativo { opacity: 1; visibility: visible; transform: none; }

/* Legenda pequena embaixo dos aparelhos, que diz o que dá pra fazer nas telas */
.hero__dica {
  position: absolute;
  z-index: 3;
  left: 50%; right: 4%; bottom: 14px;
  margin: 0;
  pointer-events: none;
  text-align: center;
  font-size: 13px;
  color: var(--ink-mute);
}
/* O anel que se espalha é um ::after crescendo (transform + opacity), não um
   box-shadow animado: box-shadow repinta a página a cada quadro, pra sempre,
   e transform/opacity o navegador anima sozinho, fora da thread principal.
   Mesmo desenho: 8px de ponto, anel até 28px (10px de cada lado) sumindo. */
.hero__dica-ponto {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  margin: -2px 10px 0 0;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
}
.hero__dica-ponto::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
  animation: pulsa 2.2s ease-out infinite;
}
@keyframes pulsa {
  0%   { transform: scale(1);   opacity: .55; }
  100% { transform: scale(3.5); opacity: 0; }
}

/* Seções ------------------------------------------------------------------- */

.section { position: relative; padding: 96px 0; }

/* Não existe seção clara: o ritmo aqui é escuro / escuro-um-pouco-mais-claro,
   separado por uma linha. A regra de nunca encostar duas seções escuras vale
   pra site claro; neste, a alternância é de tom. */
.section--alt {
  background: var(--bg-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* Mesmo tom da página, só com a linha em cima. Como funciona usa esta desde
   que Projetos saiu (28/09): assim ela não encosta no Contato, que é --alt. */
.section--linha { border-top: 1px solid var(--line); }

.section__head { max-width: 640px; margin-bottom: 44px; }

/* Serviços ----------------------------------------------------------------- */

.servicos {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: 56px;
  align-items: start;
}

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.card {
  padding: 26px 22px 24px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  /* background-color, não o atalho background: o atalho zeraria a camada de
     imagem, que é onde o holofote desenha (ver bloco abaixo). */
  background-color: var(--card);
  /* O card sobe no hover por position/top, não por transform. Um transform faz
     o navegador tratar background-attachment: fixed como preso ao elemento, e
     a luz do holofote (abaixo) pularia pro centro justo no card sob o mouse. */
  position: relative;
  top: 0;
  transition: top .2s ease, border-color .2s ease, background-color .2s ease;
}
/* Hover só onde existe ponteiro pairando: no celular o :hover gruda depois
   do toque e o card ficaria levantado até tocar em outro lugar. Lá quem
   seleciona é o .is-tocado, posto e tirado pelo main.js (ver o holofote). */
@media (hover: hover) {
  .card:hover { top: -6px; border-color: var(--line-hi); background-color: var(--card-hi); }
}
.card.is-tocado { top: -6px; border-color: var(--line-hi); background-color: var(--card-hi); }

/* Holofote nos cards -------------------------------------------------------
   O ponteiro vira coordenada da janela (--px/--py, escritas no :root uma vez
   por quadro pelo main.js) e todas as camadas de luz usam
   background-attachment: fixed. Assim o gradiente fica preso à tela, não ao
   card: uma variável só ilumina a grade inteira e cada card mostra apenas o
   pedaço de luz que cai dentro dele — seis cards acesos pela mesma lanterna,
   sem um listener por card.

   Quatro camadas, todas no laranja da marca:
     .card           → a mancha suave por dentro
     .card::before   → a borda acendendo
     .card::after    → o núcleo claro no centro da luz
     .card__brilho   → a mesma borda, grossa e borrada, derramando pra fora

   O recorte da moldura é o truque de duas máscaras: uma na padding-box, outra
   na border-box, subtraídas — sobra só o anel. A classe .tem-holofote vem do
   JS: sem JS, nada disso existe e o card fica como sempre foi.

   No toque (.holofote-toque, também do JS) a luz não segue nada: acende só
   no card tocado (.is-tocado), no ponto do toque, e apaga sozinha. Ver o
   bloco "Holofote no toque", logo abaixo. */

.tem-holofote .card,
.holofote-toque .card.is-tocado {
  --luz: 260px;                                  /* diâmetro da lanterna */
  --luz-borda: 1.25px;                           /* espessura do anel aceso */
  --luz-hue: calc(18 + (var(--pxp, .5) * 12));   /* 18–30, centrado nos 25° do #FF6A00: varia sem sair do laranja */
  background-image: radial-gradient(
    var(--luz) var(--luz) at var(--px, -999px) var(--py, -999px),
    hsl(var(--luz-hue) 100% 62% / calc(var(--luz-card) * var(--luz-nivel) * var(--luz-reforco, 1))), transparent 65%);
  background-attachment: fixed;
}

.tem-holofote .card::before,
.tem-holofote .card::after,
.holofote-toque .card.is-tocado::before,
.holofote-toque .card.is-tocado::after { content: ""; }

.tem-holofote .card::before,
.tem-holofote .card::after,
.tem-holofote .card__brilho,
.holofote-toque .card.is-tocado::before,
.holofote-toque .card.is-tocado::after,
.holofote-toque .card.is-tocado .card__brilho {
  position: absolute;
  inset: calc(var(--luz-borda) * -1);
  border: var(--luz-borda) solid transparent;
  border-radius: calc(var(--radius) + var(--luz-borda));
  background-attachment: fixed;
  background-repeat: no-repeat;
  pointer-events: none;
  opacity: var(--luz-nivel);
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

/* a borda acendendo */
.tem-holofote .card::before,
.holofote-toque .card.is-tocado::before {
  background-image: radial-gradient(
    calc(var(--luz) * .8) calc(var(--luz) * .8) at var(--px, -999px) var(--py, -999px),
    hsl(var(--luz-hue) 100% 56%), transparent 100%);
}

/* o núcleo, bem menor, onde a luz bate mais forte. Sem brightness em cima do
   laranja: clarear um tom saturado estoura o vermelho, sobe o verde e a luz
   vira dourada — o brilho vem da luminosidade do hsl, que mantém o tom. */
.tem-holofote .card::after,
.holofote-toque .card.is-tocado::after {
  background-image: radial-gradient(
    calc(var(--luz) * .32) calc(var(--luz) * .32) at var(--px, -999px) var(--py, -999px),
    hsl(26 100% 86% / .6), transparent 100%);
}

/* A mesma borda derramada pra fora: borrada e mais fraca. O alcance é curto
   de propósito — a grade tem 16px de respiro, então cada card só pode
   derramar uns 8px pro lado, senão o brilho de um encosta no do vizinho e os
   dois viram uma mancha só no vão. */
.tem-holofote .card__brilho,
.holofote-toque .card.is-tocado .card__brilho {
  inset: -4px;
  border-width: 4px;
  border-radius: calc(var(--radius) + 4px);
  background-image: radial-gradient(
    calc(var(--luz) * .8) calc(var(--luz) * .8) at var(--px, -999px) var(--py, -999px),
    hsl(var(--luz-hue) 100% 55% / .45), transparent 100%);
  filter: blur(5px);
}

/* Holofote no toque -------------------------------------------------------
   Pedido do Peter em 01/10: no celular não há cursor pra seguir, então o
   toque acende a luz no ponto tocado, o card fica selecionado enquanto ela
   dura e os dois somem juntos.

   Duas diferenças em relação ao mouse:
     - a coordenada é do card, não da janela (--px/--py escritas no próprio
       card pelo main.js), e as camadas usam background-attachment: scroll.
       O fixed não serve aqui: o Safari do iPhone o ignora e trata como
       scroll, então a luz cairia no lugar errado justamente no celular;
     - a luz acende e apaga por --luz-nivel, um número registrado (@property)
       pra poder ser animado: as quatro camadas leem dele (a mancha no alfa,
       as outras três na opacidade). No mouse ele fica em 1 e nada muda.

   A duração da animação é a da seleção: o JS tira o .is-tocado no
   animationend. Mudar o tempo aqui muda os dois. */
@property --luz-nivel {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}
:root { --luz-nivel: 1; }

.holofote-toque .card.is-tocado,
.holofote-toque .card.is-tocado::before,
.holofote-toque .card.is-tocado::after,
.holofote-toque .card.is-tocado .card__brilho { background-attachment: scroll; }

/* a luz do toque dura pouco e precisa ser vista: a mancha vem 1,8× mais forte
   que a do mouse, nos dois temas (multiplica o --luz-card de cada um) */
.holofote-toque .card.is-tocado {
  --luz-reforco: 1.8;
  animation: luz-toque 1.2s ease-out both;
}

@keyframes luz-toque {
  0%   { --luz-nivel: 0; }
  12%  { --luz-nivel: 1; }
  55%  { --luz-nivel: 1; }
  100% { --luz-nivel: 0; }
}

.card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  border-radius: 12px;
  color: var(--accent-bright);
  background: rgba(var(--accent-rgb), .1);
  border: 1px solid rgba(var(--accent-rgb), .25);
}
.card__icon .ico { width: 24px; height: 24px; }

/* Ícone é SVG: text-shadow não pega nele, drop-shadow sim. */
.card__icon .ico, .hero__pontos .ico {
  filter: var(--glow-icone);
}

.card h3 { font-size: 17px; font-weight: 700; margin: 18px 0 8px; }
.card p { font-size: 14.5px; color: var(--ink-soft); line-height: 1.55; }

/* Como funciona ------------------------------------------------------------
   A jornada (28/09/2026). Duas colunas: à esquerda o título e o painel da
   etapa, presos na tela enquanto os passos passam; à direita, os quatro passos
   pendurados num trilho.

   O trilho não é um elemento só: cada passo desenha o trecho que vai do seu
   círculo até o círculo do próximo (::before, cinza) e o fio laranja por cima
   (::after), cheio na proporção de --enche (0 a 1). Assim o fio nasce e morre
   exatamente nos círculos, qualquer que seja a altura de cada cartão. Quem
   escreve --enche, .is-aceso e .is-atual é o main.js ("Jornada do Como
   funciona"); sem JS o --enche vale 1 e os quatro passos nascem acesos.

   Nada aqui usa sticky dentro de overflow: hidden — um ancestral com overflow
   escondido vira o "rolador" do sticky e o painel deixa de prender. Por isso
   a luz de fundo é um degradê que cabe na seção, não um borrão que vaza. */

.jornada { position: relative; }

.jornada__luz {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 45% 55% at 78% 45%, rgba(var(--accent-rgb), .07), transparent 70%);
}

.passos {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: 72px;
  align-items: stretch;          /* a coluna do texto tem a altura da lista: é nela que o sticky corre */
}

.passos__fixo {
  position: sticky;
  top: calc(var(--h-topo) + 40px);
}
.passos__fixo .lead { margin-top: 18px; }

/* Painel da etapa: número grande, nome do passo e uma barra de quatro
   segmentos. É só um espelho do trilho, por isso aria-hidden no HTML. */
.painel {
  margin-top: 32px;
  max-width: 340px;
  padding: 20px 22px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--card);
}
.painel__rotulo {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.painel__conta { display: flex; align-items: baseline; gap: 10px; margin-top: 4px; }
.painel__num {
  font-size: 56px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  color: var(--accent-bright);
  text-shadow: var(--glow-texto);
}
.painel__total { font-size: 18px; font-weight: 700; color: var(--ink-mute); }
.painel__nome { margin-top: 8px; font-size: 17px; font-weight: 700; color: var(--ink); }
.painel__barra { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 16px; }
.painel__barra span {
  height: 4px;
  border-radius: 4px;
  background: var(--vidro-2);
  transition: background-color .35s ease, box-shadow .35s ease;
}
.painel__barra span.is-feito { background: var(--accent); box-shadow: 0 0 10px rgba(var(--accent-rgb), .55); }

.passos__cta { margin-top: 28px; }

/* Os passos ------------------------------------------------------------------ */

.passos__lista {
  --no: 56px;                    /* diâmetro do círculo do trilho */
  --vao: 22px;                   /* espaço entre um cartão e o próximo */
  list-style: none;
  display: grid;
  gap: var(--vao);
}

.passo {
  --enche: 1;
  position: relative;
  display: grid;
  grid-template-columns: var(--no) minmax(0, 1fr);
  gap: 26px;
  align-items: start;
}
.tem-jornada .passo { --enche: 0; }

/* O trecho de trilho até o próximo círculo: sai de baixo deste e atravessa o
   vão até o topo do próximo. O último passo não tem trecho. */
.passo:not(:last-child)::before,
.passo:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc(var(--no) / 2 - 1px);
  top: var(--no);
  width: 2px;
  height: calc(100% - var(--no) + var(--vao));
  border-radius: 2px;
}
.passo:not(:last-child)::before { background: var(--line); }
.passo:not(:last-child)::after {
  background: linear-gradient(var(--accent-glow), var(--accent));
  box-shadow: 0 0 12px rgba(var(--accent-rgb), .55);
  transform-origin: top;
  transform: scaleY(var(--enche));
}

.passo__no {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--no); height: var(--no);
  border-radius: 50%;
  color: var(--ink-mute);
  background: var(--card);
  border: 1px solid var(--line);
  transition: color .35s ease, border-color .35s ease, background-color .35s ease, box-shadow .35s ease;
}
.passo__no .ico { width: 24px; height: 24px; }

.passo.is-aceso .passo__no {
  color: var(--accent-bright);
  border-color: rgba(var(--accent-rgb), .55);
  background-image: linear-gradient(rgba(var(--accent-rgb), .14), rgba(var(--accent-rgb), .14));
  box-shadow: 0 0 0 6px rgba(var(--accent-rgb), .07), 0 0 28px rgba(var(--accent-rgb), .30);
}
.passo.is-aceso .passo__no .ico { filter: var(--glow-icone); }

/* O passo em que a leitura está ganha um anel que respira */
.passo.is-atual .passo__no::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  border: 1px solid rgba(var(--accent-rgb), .6);
  animation: passo-anel 2.2s ease-out infinite;
}
@keyframes passo-anel {
  from { transform: scale(1);   opacity: .9; }
  to   { transform: scale(1.6); opacity: 0; }
}

.passo__cartao {
  position: relative;
  overflow: hidden;
  padding: 26px 30px 26px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--card);
  transition: border-color .35s ease, background-color .35s ease, box-shadow .35s ease, opacity .35s ease;
}
/* Com JS, o que a leitura ainda não alcançou fica mais apagado */
.tem-jornada .passo:not(.is-aceso) .passo__cartao { opacity: .55; }

/* A risca de luz no topo do cartão atual */
.passo__cartao::before {
  content: "";
  position: absolute;
  top: 0; left: 24px; right: 24px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: 0;
  transition: opacity .35s ease;
}
.passo.is-atual .passo__cartao {
  border-color: var(--line-hi);
  background-color: var(--card-hi);
  box-shadow: 0 24px 60px -34px rgba(var(--accent-rgb), .55);
}
.passo.is-atual .passo__cartao::before { opacity: 1; }

/* O número gigante, só em contorno, no canto do cartão */
.passo__marca {
  position: absolute;
  top: 4px; right: 20px;
  font-size: 112px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.05em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line);
  pointer-events: none;
  transition: -webkit-text-stroke-color .35s ease;
}
.passo.is-atual .passo__marca { -webkit-text-stroke-color: rgba(var(--accent-rgb), .45); }

.passo__etapa {
  position: relative;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-bright);
  text-shadow: var(--glow-texto-min);
}
.passo h3 { position: relative; margin-top: 8px; font-size: 22px; font-weight: 800; letter-spacing: -.02em; }
/* O parágrafo não entra no canto do número gigante: sem essa reserva, em
   1000px e em inglês a primeira linha passava por baixo do contorno. */
.passo__texto { position: relative; margin-top: 8px; max-width: min(46ch, calc(100% - 130px)); font-size: 15px; line-height: 1.6; color: var(--ink-soft); }

.passo__recebe {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px dashed var(--line);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.passo__itens { list-style: none; display: grid; gap: 9px; margin-top: 12px; }
.passo__itens li { display: flex; align-items: flex-start; gap: 10px; font-size: 14.5px; line-height: 1.5; color: var(--ink); }
.passo__itens .ico { flex: none; width: 16px; height: 16px; margin-top: 3px; color: var(--accent-bright); }

/* Contato ------------------------------------------------------------------ */

/* O fecho da página ocupa a tela toda: a malha animada precisa de espaço pra
   aparecer, e o bloco de texto fica centrado no meio dela. O desconto é a
   altura do cabeçalho fixo (o mesmo cálculo do scroll-padding-top), pra que
   a seção caiba exata quando o menu leva pra cá. svh cobre o celular, onde a
   barra do navegador entra e sai. */
.contato {
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: calc(100vh - var(--h-topo) - 6px);
  min-height: calc(100svh - var(--h-topo) - 6px);
}
.contato__glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 75% at 50% 55%, rgba(var(--accent-rgb), .20), transparent 65%);
}

/* A malha de pontos, desenhada em <canvas> pelo main.js. Aqui o CSS só a
   estica sobre a seção e a deixa atrás do texto. Vem depois do glow no HTML,
   então pinta por cima dele — a malha aparece dentro da luz laranja. */
.contato__malha {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Véu entre a malha e o texto: apaga o centro, onde a leitura acontece, e
   some nas bordas, onde a malha pode aparecer inteira. Sem ele a lead e
   o botão competem com os pontos. */
.contato__veu {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 54% 64% at 50% 50%, rgba(var(--bg2-rgb), .84), rgba(var(--bg2-rgb), 0) 70%);
}

/* Uma coluna só, centrada: o bloco inteiro é o fecho da página, e o fundo
   animado ocupa o lugar que era do celular. */
.contato__inner {
  position: relative;
  z-index: 1;
  max-width: 680px;
  margin-inline: auto;
  text-align: center;
}
.contato__text .lead { margin-left: auto; margin-right: auto; }
.contato__text .hero__actions { justify-content: center; }

/* Capacidade ----------------------------------------------------------------
   Vitrine de estilos: quatro modelos na esquerda, a prévia do escolhido na
   direita. Desde 28/09/2026 a prévia é o próprio demo (web/demos/) rodando
   em miniatura num iframe — até ali eram maquetes desenhadas em CSS.

   Regra que vale pra seção inteira: **só a prévia ativa anda.** O iframe só
   carrega quando o modelo é escolhido com a seção perto da tela, e o main.js
   ("Capacidade") avisa o demo por mensagem quando ele deve parar — fora da
   tela ou fora de foco, o demo pausa as animações e o passeio. Isso não é
   capricho — o site já perdeu metade do FPS uma vez, em 22/09, por causa de
   um efeito que rodava fora da tela (ver ESTADO-DO-SITE.md). */

.capacidade {
  position: relative;
  overflow: hidden;
  border-top: 1px solid var(--line);
}

/* Luz laranja atrás da vitrine, do lado onde a maquete fica. Fica atrás de
   tudo e não recebe clique. */
.capacidade__brilho {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 45% 55% at 78% 45%, rgba(var(--accent-rgb), .13), transparent 68%);
}

.capacidade .wrap { position: relative; z-index: 1; }

.capacidade__head { max-width: 760px; }

/* Selo do topo: número em círculo, risco e rótulo — o mesmo gesto do
   componente que o Peter mandou, na cor da casa. */
.capacidade__selo { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.capacidade__num {
  width: 36px; height: 36px;
  flex: none;
  display: grid; place-items: center;
  border-radius: 999px;
  background: var(--accent);
  color: #120800;
  font-size: 14px;
  font-weight: 800;
  box-shadow: 0 0 18px rgba(var(--accent-rgb), .45);
}
.capacidade__risco { width: 46px; height: 1px; background: var(--line); }
.capacidade__rotulo {
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--vidro-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.capacidade__grade {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 26px;
  align-items: start;
  margin-top: 40px;
}

.capacidade__nota {
  margin-top: 26px;
  font-size: 13.5px;
  color: var(--ink-mute);
}

/* Os quatro modelos ---------------------------------------------------------
   Um card por modelo. Fechado mostra número e título; aberto mostra o estilo,
   o texto e os quatro itens. Só um fica aberto por vez. */

.modelos { display: flex; flex-direction: column; gap: 12px; }

.modelo {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 18px 20px;
  cursor: pointer;
  transition: border-color .25s ease, background .25s ease, box-shadow .25s ease;
}
.modelo:hover { border-color: var(--vidro-3); background: var(--card-hi); }
.modelo:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }

.modelo.is-ativo {
  background: var(--card-hi);
  border-color: var(--line-hi);
  box-shadow: 0 14px 40px rgba(var(--accent-rgb), .10);
}

.modelo__topo { display: flex; align-items: center; gap: 14px; }

.modelo__num {
  flex: none;
  padding: 3px 9px;
  border-radius: 7px;
  background: var(--vidro-2);
  color: var(--ink-mute);
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  transition: background .25s ease, color .25s ease;
}
.modelo.is-ativo .modelo__num { background: var(--accent); color: #120800; }

.modelo__titulo {
  flex: 1;
  font-size: 17px;
  font-weight: 700;
  color: var(--ink-soft);
  transition: color .25s ease;
}
.modelo.is-ativo .modelo__titulo { color: var(--ink); }

/* O "+" vira "×" no aberto, girando 45° */
.modelo__mais {
  flex: none;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 999px;
  background: var(--vidro-2);
  color: var(--ink-mute);
  transition: transform .3s ease, background .25s ease, color .25s ease;
}
.modelo__mais svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.modelo.is-ativo .modelo__mais { transform: rotate(45deg); background: var(--accent); color: #120800; }

/* Corpo: fechado tem altura zero. grid-template-rows anima a altura sem
   precisar medir nada em JS. */
.modelo__corpo {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows .35s ease, opacity .25s ease, margin-top .35s ease;
  margin-top: 0;
}
/* O recorte mora no filho único: um grid de 0fr só zera a PRIMEIRA linha,
   então com estilo, texto e lista soltos lá dentro os dois últimos ficavam
   de fora do colapso e o card fechado nascia gigante. */
.modelo__interno { overflow: hidden; min-height: 0; }
.modelo.is-ativo .modelo__corpo {
  grid-template-rows: 1fr;
  opacity: 1;
  margin-top: 16px;
}

/* A primeira linha do card aberto: o que o site faz pelo negócio, não como ele
   é feito. A descrição do estilo saiu daqui e virou o data-legenda do modelo,
   que rotula a maquete ao lado (main.js, "Capacidade"). */
.modelo__resultado {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--accent-bright);
  text-shadow: var(--glow-texto-min);
  padding-top: 15px;
  border-top: 1px solid var(--line);
}
.modelo__texto {
  margin-top: 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.modelo__itens {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px 16px;
  list-style: none;
  font-size: 12.5px;
  color: var(--ink-soft);
}
.modelo__itens li { display: flex; align-items: start; gap: 8px; line-height: 1.45; }
.modelo__itens li::before {
  content: "";
  flex: none;
  width: 5px; height: 5px;
  margin-top: 6px;
  border-radius: 999px;
  background: var(--accent);
}

/* A vitrine da direita ------------------------------------------------------ */

.vitrine {
  position: sticky;
  /* Cabeçalho + folga. Era 104px cravado, da época em que a barra tinha 84:
     com a barra em 120, o topo da vitrine grudava 16px por baixo dela. */
  top: calc(var(--h-topo) + 20px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--card);
  padding: 20px;
  overflow: hidden;
}
.vitrine__fundo {
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(var(--accent-rgb), .10), transparent 70%);
}

.vitrine__topo {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.vitrine__etiqueta {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-bright);
  text-shadow: var(--glow-texto-min);
}
.vitrine__contador {
  padding: 3px 9px;
  border-radius: 7px;
  background: var(--vidro-2);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}
.vitrine__contador b { color: var(--ink-soft); font-weight: 700; }

/* O palco é a moldura onde a maquete vive. container-type pra que as peças
   sejam medidas em cqw e a maquete inteira escale junto com a largura. */
.vitrine__palco {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 16 / 10.6;
  border-radius: 14px;
  overflow: hidden;
  background: #050505;
  border: 1px solid var(--line);
}

.vitrine__legenda {
  margin-top: 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
  min-height: 39px;
}

.vitrine__pe {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.vitrine__abrir[aria-disabled="true"] {
  opacity: .42;
  pointer-events: none;
}
.vitrine__aviso {
  display: block;
  margin-top: 9px;
  font-size: 11.5px;
  color: var(--ink-mute);
}

/* A prévia -------------------------------------------------------------------
   Cada maquete guarda um iframe com o demo inteiro em 1200×795 (a proporção
   do palco), reduzido pela --escala-previa que o main.js mede no palco. O
   demo roda de verdade, mas sem clique: é pra olhar. Enquanto carrega, o
   fundo já é a cor do demo, pra não piscar. A troca é um fade curto com um
   empurrãozinho pra cima, pra leitura não pular. */

.maquete {
  position: absolute;
  inset: 0;
  overflow: hidden;
  animation: maq-entra .45s ease both;
}
.maquete[hidden] { display: none; }
.maquete iframe {
  position: absolute;
  left: 0; top: 0;
  width: 1200px;
  height: 795px;
  border: 0;
  transform: scale(var(--escala-previa, .5));
  transform-origin: 0 0;
  pointer-events: none;
  background: transparent;
}
.maquete--cafe          { background: #2A1610; }
.maquete--turismo       { background: #F3EBD9; }
.maquete--imoveis       { background: #FFFFFF; }
.maquete--investimentos { background: #060507; }

@keyframes maq-entra {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* O nome curto só existe na fileira de botões do celular. */
.modelo__curto { display: none; }
.vitrine__info { display: none; }

/* Telas menores -------------------------------------------------------------
   Pedido do Peter em 30/09: abaixo de 900px os quatro modelos viram uma
   fileira de botões em cima da prévia, lado a lado, no mesmo desenho do
   número do selo (pílula com o número em cima, laranja no ativo). O nome, o
   texto e os itens do modelo ativo descem pra .vitrine__info, embaixo da
   prévia e antes do "Ver o site inteiro" — o main.js copia o conteúdo a cada
   troca. Os cards continuam sendo as tabs, só que sem corpo. */

@media (max-width: 900px) {
  .capacidade__grade {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
  }
  /* relative, não static: com static o .vitrine__fundo (absolute, inset 0)
     escapava pro .wrap e pintava a luz dele no topo da seção inteira, cortada
     reto em cima do selo "04 Capacidade" — o bug do print do Peter em 30/09. */
  .vitrine { position: relative; top: auto; }

  .modelos { flex-direction: row; gap: 8px; }
  .modelo {
    flex: 1 1 0;
    min-width: 0;
    padding: 10px 4px 11px;
    border-radius: 12px;
  }
  .modelo.is-ativo { border-color: rgba(var(--accent-rgb), .55); }
  .modelo__topo { flex-direction: column; gap: 7px; text-align: center; }
  .modelo__titulo, .modelo__mais, .modelo__corpo { display: none; }
  .modelo__curto {
    display: block;
    max-width: 100%;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--ink-soft);
    overflow-wrap: break-word;
    transition: color .25s ease;
  }
  .modelo.is-ativo .modelo__curto { color: var(--ink); }

  .vitrine__info { display: block; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
  .vitrine__info-titulo { font-size: 18px; font-weight: 700; }
  .vitrine__info .modelo__resultado { border-top: 0; padding-top: 0; margin-top: 6px; }
  .vitrine__info .modelo__itens { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 520px) {
  .capacidade__selo { gap: 10px; }
  .capacidade__risco { width: 24px; }
  .modelos { gap: 6px; }
  .modelo__curto { font-size: 11.5px; }
  .vitrine { padding: 15px; }
  .vitrine__info-titulo { font-size: 16.5px; }
}

/* Quem pediu menos movimento vê tudo parado — mesma regra do holofote e da
   malha do contato. A prévia para sozinha: o demo recebe o aviso e não passeia. */
@media (prefers-reduced-motion: reduce) {
  .maquete { animation: none; }
  .modelo, .modelo__corpo, .modelo__mais { transition: none; }
}

/* Rodapé ------------------------------------------------------------------- */

.footer { border-top: 1px solid var(--line); background: var(--bg); }
.footer__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 34px 0;
}
.footer__logo img { width: 118px; height: auto; }
.footer__nav { display: flex; flex-wrap: wrap; gap: 26px; font-size: 14.5px; color: var(--ink-soft); }
.footer__nav a:hover { color: var(--ink); }

.footer__social { display: flex; gap: 10px; }
.footer__social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  transition: color .18s ease, border-color .18s ease;
}
.footer__social a:hover { color: var(--accent-bright); border-color: var(--line-hi); text-shadow: var(--glow-texto-min); }

.footer__base {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  padding: 16px 0 24px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-mute);
}

/* Movimento ---------------------------------------------------------------- */

.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s ease, transform .7s ease; }
.reveal--delay { transition-delay: .15s; }
.reveal.is-visible { opacity: 1; transform: none; }

/* Tudo desligado de uma vez: entrada dos blocos, hover, flutuação do notebook
   e o pulso da legenda. O paralaxe é desligado no JS pela mesma media query. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .btn, .card { transition: none; }
  .btn:hover { transform: none; }
  .card:hover { top: 0; }
  .hero__dica-ponto::after { animation: none; }
  /* A jornada acende do mesmo jeito, só sem transição nem anel respirando */
  .passo__no, .passo__cartao, .passo__cartao::before, .passo__marca, .painel__barra span { transition: none; }
  .passo.is-atual .passo__no::after { animation: none; opacity: 0; }
  /* O nome do modelo troca seco, sem fade nem deslocamento */
  .trocador__nome { transition: none; transform: none; }
  .trocador__seta { transition: none; }
  .trocador__seta:active { transform: none; }
}

/* Tablet e celular ---------------------------------------------------------- */

/* O trocador e a legenda embaixo do NOTEBOOK, não do celular ---------------
   A foto encolhe junto com a janela, mas o trocador e a legenda continuam do
   mesmo tamanho em px. A faixa de mesa embaixo do CELULAR vale 16,8% da
   altura da foto, ou 0,084 × a largura da janela: em 1440px são 121px pra um
   conjunto de 80px (seta + folga + legenda), mas em 950px são 80px — e a seta
   da direita encosta no pé do celular (medido: 0,2px de sobra).

   A saída é horizontal, não vertical: daqui pra baixo o conjunto anda pra
   esquerda e passa a viver embaixo do notebook, onde a mesa é quase o dobro
   (28,3% da altura da foto). **A legenda vai junto**, senão as duas linhas
   ficam com centros diferentes. Acima de 1140px nada disso acontece e as duas
   ficam centradas no par de aparelhos (que vai de 47,9% a 93,7% da foto). */
@media (max-width: 1140px) and (min-width: 901px) {
  /* Mesmo centro nas duas (57% da janela), caixas de larguras diferentes: a
     legenda é uma frase, e numa caixa de 38% ela quebra em duas linhas e sobe
     por cima do trocador. Centro = (esquerda + (100 − direita)) ÷ 2. */
  .hero__trocador { left: 38%; right: 24%; }
  .hero__dica     { left: 28%; right: 14%; }
}

@media (max-width: 1080px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .passos { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 44px; }

  .hero__inner { gap: 28px; }
  .hero__pontos { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  /* Texto → botões → foto recortada nos aparelhos (com as telas vivas) */
  .hero { padding: 40px 0 56px; min-height: 0; flex-direction: column; align-items: stretch; }
  .hero__inner { grid-template-columns: 1fr; gap: 0; pointer-events: auto; }
  .hero__text { max-width: 560px; }
  .hero__title { font-size: clamp(34px, 6vw, 44px); }   /* empilhado, o texto ganha 560px: o título volta a crescer */
  .hero__pontos { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* O cenário deixa de ser fundo e vira um bloco em fluxo: um recorte da
     foto (--cx0/--cy0/--cw/--ch, em px da foto original) só com os
     aparelhos. A caixa da foto continua 2:1 e as telas continuam presas
     nos mesmos cantos — só muda o pedaço que aparece. */
  .hero__cena {
    position: relative; inset: auto; z-index: auto;
    width: min(var(--wrap-hero), 100% - 40px);
    max-width: 640px;
    margin: 36px auto 0;
  }
  .hero__quadro {
    --cx0: 790; --cy0: 110; --cw: 910; --ch: 720;
    position: relative; inset: auto;
    aspect-ratio: var(--cw) / var(--ch);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg), inset 0 0 0 1px var(--line);
    container-type: normal;
  }
  /* A foto clara tem outro enquadramento: os aparelhos ficam mais ao centro
     e o celular vai mais pra direita. O recorte é em px da foto clara
     (1440×720), não da escura.

     **Apertado em 28/09** (era 670 / 90 / 750 / 540) pelo mesmo motivo do
     `--zoom-foto` lá em cima: os aparelhos saíam 5,9% menores que no escuro.
     Aqui não dá pra usar o zoom — quem enquadra nesta faixa é o recorte — então
     o que encolheu foi o recorte: `--cw` de 750 pra 706 (= 750 ÷ 1,0623), que é
     o que amplia os aparelhos, e o resto foi escolhido pra caber e pra repetir
     a moldura do escuro:
       · --cx0 665: deixa 30px de folga à esquerda da tela do notebook e 26 à
         direita do celular. A base do notebook continua cortada na esquerda,
         como já acontece no tema escuro.
       · --ch 560: não mexe no tamanho dos aparelhos (só --cw faz isso), mexe na
         altura da moldura. 706/560 dá 1,261 — a mesma proporção de moldura do
         escuro (910/720 = 1,264), com a mesma folga em cima e embaixo. */
  :root[data-tema="claro"] .hero__quadro { --cx0: 665; --cy0: 103; --cw: 706; --ch: 560; }
  .hero__foto {
    width: calc(var(--foto-w) / var(--cw) * 100%);
    left: calc(-1 * var(--cx0) / var(--cw) * 100%);
    top: calc(-1 * var(--cy0) / var(--ch) * 100%);
  }
  .hero__luz { display: none; }
  /* Fora da foto e em fluxo: moldura → trocador → legenda, um embaixo do outro */
  .hero__trocador { position: static; margin-top: 16px; }
  .hero__dica { position: static; margin-top: 10px; }

  .servicos, .passos { grid-template-columns: 1fr; gap: 36px; }
  /* Uma coluna: o texto não prende mais (não teria do lado de quem ficar) e o
     painel da etapa sai — no celular quem mostra a etapa é o próprio trilho. */
  .passos__fixo { position: static; }
  .painel { display: none; }
  .section { padding: 72px 0; }

  /* Aqui havia um --vw/--vh só do tema claro. Saiu em 28/09: o claro usa os
     mesmos números do escuro em todas as faixas (ver o bloco das telas, mais
     acima). Quem iguala o tamanho nesta faixa é o recorte da foto, logo
     acima. */
}

/* Menu vira gaveta ------------------------------------------------------------
   Este breakpoint é o do MENU, não o do layout, e por isso está separado dos
   900px acima. A gaveta abria só abaixo de 901px, mas a barra horizontal
   nunca coube em 901 — **de 901 a ~1106 ela estourava a página**, dando barra
   de rolagem horizontal em iPad deitado (1024px) e em notebook de 1024/960.
   Defeito antigo, achado em 25/09 só porque a barra cresceu.

   O número vem de medir a barra inteira **nos três idiomas** (o menu muda de
   largura com a língua) e ficar com o pior caso:

     pt  logo 130 + 18 + ferramentas 120 + 18 + 10 + menu 771 = 1067 → 1107px de janela
     es  ... menu 765 = 1060 → 1100px
     en  ... menu 730 = 1026 → 1066px

   O corte é 1119px, com uns 13px de folga sobre o pior caso. **Ao acrescentar
   item no menu, ou trocar texto de link, remedir nos três idiomas.** Não
   adianta tentar apertar o menu pra ele caber mais embaixo: com gap 16 e sem
   afastamento ainda faltam uns 100px numa janela de 901px.

   O botão de WhatsApp continua dentro da gaveta, então nenhum caminho some. */
@media (max-width: 1119px) {
  .menu-toggle { display: inline-flex; }
  .nav {
    position: fixed;
    inset: var(--h-topo) 0 auto 0;
    margin: 0;                 /* zera o afastamento da logo, que só vale na barra */
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 16px 20px 24px;
    /* Opaca, não 97%: não há desfoque atrás da gaveta, então os 3% não
       davam efeito de vidro — davam só o fantasma do título do hero por
       baixo do menu (8 níveis de cor, medidos em 24/09). Vale nos dois temas. */
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    /* Com o celular deitado a gaveta (~350px) passava do fim da tela, e por ser
       fixa ela não rolava: o "Fale conosco" ficava fora de alcance. */
    max-height: calc(100vh - var(--h-topo));
    max-height: calc(100dvh - var(--h-topo));
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease, transform .2s ease, visibility 0s .2s;
  }
  .nav.is-open { transform: none; opacity: 1; visibility: visible; transition-delay: 0s; }
  .nav__link { padding: 12px 4px; border-bottom: 1px solid var(--line); font-size: 16px; }
  .nav__link.is-active { border-bottom-color: var(--line); color: var(--accent-bright); text-shadow: var(--glow-texto-min); }
  .nav__cta { margin: 14px 0 0; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  .wrap { width: min(var(--wrap), 100% - 32px); }
  .hero__inner { width: min(var(--wrap-hero), 100% - 32px); }
  /* Barra mais baixa no celular, mas com folga na mesma proporção: a logo cai
     pra 108px de largura (66px de altura) e sobram 15px em cima e embaixo —
     contra 21px de folga pra 79px de logo no desktop. A gaveta do menu, o
     scroll-padding e as duas seções de tela cheia seguem a variável sozinhos. */
  :root { --h-topo: 96px; }
  .header__logo img { width: 108px; }

  .hero__title { font-size: clamp(22px, 6.6vw, 32px); }
  .hero__pontos { grid-template-columns: 1fr; }
  .hero__actions .btn { width: 100%; }

  /* Hero compacto (30/09/2026, pedido do Peter: "diminua levemente os textos
     e os espaços entre tudo no Início pra tentar fazer tudo aparecer na
     tela"). Antes faltavam 180 a 260px nos celulares comuns pra legenda das
     telas aparecer sem rolar. Cada linha aqui tira um pouco: respiro de cima,
     kicker, título (acima), parágrafo, botões e pontos — sem tirar nada. */
  .hero { padding-top: 18px; }
  .hero .kicker { font-size: 11px; margin-bottom: 8px; }
  .hero__lead { font-size: 14.5px; line-height: 1.5; margin: 10px 0 16px; }
  .hero__actions { gap: 10px; }
  .hero__actions .btn { min-height: 44px; padding: 10px 22px; font-size: 14.5px; }
  .hero__pontos { margin-top: 16px; gap: 6px; font-size: 13px; }
  .hero__pontos .ico { width: 17px; height: 17px; }

  /* Hero do celular com as fotos verticais (30/09/2026) -----------------------
     Pedido do Peter: usar no celular as duas fotos que ele mandou (uma por
     tema, 941×1672), mantendo tudo o que o hero já tinha. A foto vertical é a
     mesma cena do desktop — notebook e celular na mesa — com metade de céu em
     cima, e é esse céu que recebe o texto, como a parede vazia recebe no
     desktop:

       texto (kicker, título, parágrafo, botões, quatro pontos)
         ↓ por cima do céu da foto
       aparelhos com os demos vivos, projetados nas telas da foto
         ↓
       trocador e legenda, sobre a mesa, que se dissolve no fundo

     A foto ocupa a largura toda da tela (sem moldura nem margem) e sobe por
     baixo do texto com margem negativa. Margem em %, que no fluxo é % da
     LARGURA do hero — a mesma medida de que sai a altura da foto, então a
     conta vale em qualquer celular. 81% da largura ≈ 46% da altura da foto: o
     texto termina pouco acima do notebook (que começa em 51%).

     Quem não muda: os iframes, as medidas do demo (960 de largura no
     notebook, 360×780 no celular, iguais nos dois temas), o trocador, a
     legenda e o toque que abre o demo. */
  .hero { padding-bottom: 0; }
  /* -86% (era -81%, apertado no hero compacto): o texto termina a ~48% da
     altura da foto, pouco acima do notebook, que começa em 51%. */
  .hero__cena {
    width: 100%; max-width: none;
    margin: -86% 0 0;
    z-index: 0;
  }
  /* A moldura corta o pé da foto: sobra mesa só pro trocador e a legenda
     (hero compacto). A altura NÃO é uma proporção fixa — a foto encolhe com
     a largura e o trocador e a legenda não (são px), e com corte fixo as
     setas encostavam no celular em 320 e 360px (pego pelo
     conferir-trocador.js). Então: o pé da tela do celular na foto
     (1329/941 da largura = 141,23vw) + 86px fixos (74 de trocador e
     legenda, 12 de folga). Em 390px dá ~1535 dos 1672px da foto.
     A foto continua inteira na proporção dela, presa no topo — os cantos
     das telas não mudam. */
  .hero__quadro {
    aspect-ratio: auto;
    height: calc(141.23vw + 86px);
    border-radius: 0;
    box-shadow: none;
  }
  .hero__foto { left: 0; top: 0; width: 100%; height: auto; aspect-ratio: 941 / 1672; }
  /* Luz da foto vertical: o topo nasce do fundo da página (a foto começa por
     trás do título), fica um véu sobre o céu enquanto tem texto em cima e
     some antes dos aparelhos. */
  .hero__luz {
    display: block;
    background: linear-gradient(180deg,
      var(--bg) 0%,
      rgba(var(--bg-rgb), .9) 12%,
      rgba(var(--bg-rgb), .72) 30%,
      rgba(var(--bg-rgb), .45) 42%,
      transparent 50%);
  }
  /* No pé, a mesa se dissolve no fundo pra o trocador e a legenda lerem bem,
     e a seção seguinte emenda sem corte. Fica na moldura, não na .hero__luz:
     o corte da moldura muda com a largura (ver acima), e o degradê tem de
     acabar exatamente no pé dela. Começa logo abaixo do celular (o pé da
     tela dele está a 86px do fim). */
  .hero__quadro::after {
    content: "";
    position: absolute; inset: 0;
    z-index: 0;   /* acima da foto (vem depois dela), abaixo das telas, do trocador (4) e da legenda (3) */
    pointer-events: none;
    background: linear-gradient(180deg,
      transparent calc(100% - 80px),
      rgba(var(--bg-rgb), .8) calc(100% - 44px),
      var(--bg) calc(100% - 6px));
  }
  /* Na foto vertical o celular também cobre a borda do notebook nos dois
     temas, então o corpo recortado volta a valer no claro. */
  :root[data-tema="claro"] .hero__frente { display: block; }

  /* Trocador e legenda sobre a mesa da foto, como no desktop. A distância
     entre os dois é fixa em px (a legenda tem duas linhas até ~420px); só o
     pé acompanha a altura da foto. */
  .hero__trocador { position: absolute; left: 16px; right: 16px; bottom: 40px; margin: 0; }
  .hero__dica { position: absolute; left: 16px; right: 16px; bottom: 4px; margin: 0; line-height: 1.3; }

  /* Notebook: 960 de largura, como antes; a altura acompanha a tela da foto
     vertical, que é mais larga (1,70 : 1) do que 960×600 (1,6 : 1) — sem
     isso o demo sairia 6% esticado na horizontal. Igual nos dois temas. */
  .tela--notebook { --vw: 960; --vh: 566; }
  /* As duas fotos verticais têm notch, não ilha — e ele fica dentro da tela,
     então é redesenhado por cima do demo (como o do claro no desktop).
     Medido na foto: escura 25,7% / 48,1% de largura / 4,5% de altura; clara
     26,3% / 47% / 2,9%. */
  .tela--celular::before {
    top: 0; left: 25.7%;
    width: 48.1%; height: 4.5%;
    transform: none;
    border-radius: 0 0 16px 16px;
    background: #050505;
  }
  :root[data-tema="claro"] .tela--celular::before { left: 26.3%; width: 47%; height: 2.9%; }

  .hero__dica { font-size: 12px; }
  .trocador__seta { width: 34px; height: 34px; }
  .trocador__nome { font-size: 14px; }

  /* Pedido do Peter em 30/09: no celular os seis serviços ficam em 2 colunas
     × 3 linhas. Cada card tem de 140 a 165px de largura (320 a 375 de tela),
     então tudo encolhe junto: respiro, ícone e letra. O vão continua com 12px
     pra o brilho do holofote de um card não encostar no do vizinho. A quebra
     com hífen é pra "automatización" (ES), a palavra mais longa dos três
     idiomas, que não cabe inteira numa linha a 320px. */
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .card { padding: 18px 14px 16px; }
  .card__icon { width: 38px; height: 38px; border-radius: 10px; }
  .card__icon .ico { width: 20px; height: 20px; }
  .card h3 { font-size: 15px; line-height: 1.3; margin: 14px 0 6px; hyphens: auto; overflow-wrap: break-word; }
  .card p { font-size: 13px; line-height: 1.5; }
}

/* A 320px o hífen não salva: o Chrome sem dicionário de espanhol cortou
   "automatizació-n". A 14px a palavra cabe inteira nos 110px do card. */
@media (max-width: 360px) {
  .card h3 { font-size: 14px; }
}

@media (max-width: 640px) {
  .passos__lista { --no: 44px; --vao: 18px; }
  .passo { gap: 14px; }
  .passo__no .ico { width: 20px; height: 20px; }
  .passo__cartao { padding: 22px 20px; }
  .passo__marca { font-size: 80px; right: 12px; }
  .passo h3 { font-size: 19px; }
  .passo__texto { max-width: none; }
  .footer__inner { flex-direction: column; align-items: flex-start; }
  .footer__base { flex-direction: column; }
}

/* Links do rodapé com altura de dedo em tela de toque (celular E tablet):
   tinham 23px. O padding cresce o alvo e o vão vertical encolhe na mesma
   medida, então o desenho quase não muda. */
@media (pointer: coarse) {
  .footer__nav { gap: 0 24px; }
  .footer__nav a { padding: 10px 0; }
}

/* Celular estreito (iPhone SE de 1ª geração, Android pequeno) -------------------
   Em 320px a barra não cabia: logo 108 + ferramentas 120 + menu 46 + dois vãos
   de 18 dá 310px pra 288 de espaço, e o botão de três riscos era espremido pra
   38px e passava da margem, colado na borda da tela (medido em 29/09/2026).
   Aqui a logo desce pra 96px e o vão pra 10px: 96 + 120 + 46 + 20 = 282. */
@media (max-width: 359px) {
  .header__inner { gap: 10px; }
  .header__logo img { width: 96px; }
}

/* Celular deitado ---------------------------------------------------------------
   Com ~360px de altura, a barra de 120px (a do desktop, porque a largura passa
   de 640) comia um terço da tela e ficava presa ali a página inteira. Aqui ela
   cai pra 80px, com a logo a 96px (58 de altura, 11 de folga em cima e
   embaixo). A gaveta, o scroll-padding e as seções de tela cheia seguem a
   variável sozinhos. */
@media (max-height: 520px) and (max-width: 1119px) {
  :root { --h-topo: 80px; }
  .header__logo img { width: 96px; }
}
