/* Folha de estilo do site VDCity.
   Estava inline no index.html. Saiu para ca quando as paginas de servico
   apareceram: 17 copias de 25KB do mesmo CSS e uma divergencia esperando
   acontecer — mudar uma cor teria de ser repetido 18 vezes. */
/* DUAS PALETAS, UM CONJUNTO DE NOMES.
   O corpo do site e CLARO — e o padrao, definido aqui. As tres faixas escuras
   (barra fixa, hero e rodape) recebem a classe .on-dark, que REDECLARA os
   mesmos tokens com os valores escuros. Como todo componente le var(--ink),
   var(--mut), var(--line), var(--surface)..., cada um funciona nos dois fundos
   sem precisar de uma segunda regra.
   Quem cravar uma cor literal em vez de usar um token quebra isso: a peca fica
   presa a um dos dois fundos. */
:root{
  --bg:#FFFFFF; --bg2:#F4F7FB; --surface:#FFFFFF; --surface2:#EEF3F9;
  --line:rgba(13,27,53,.13); --line2:rgba(13,27,53,.24);
  --ink:#0A1020; --mut:#48536A; --mut2:#69738A;
  --brand:#0D6ECF; /* azul da marca — o do prisma do logo, e o unico do site */
  --acc:var(--brand); --acc2:var(--brand); --glow:rgba(13,110,207,.35);
  /* O gradiente virou cor chapada: existia para o "360°" e o "100%" do hero
     irem do ciano ao azul, e o ciano deixou de existir. A propriedade fica
     porque as regras usam background-clip:text e esperam um background. */
  --grad:linear-gradient(110deg,var(--brand),var(--brand));
  --btn-glow:rgba(10,16,32,.45);
  /* Veu da coluna da VDCity no comparativo: tinta sobre o claro. */
  --veu:rgba(10,16,32,.028);
  --maxw:1280px;
  /* CANTO RETO EM TODO O SITE. Os dois tokens valiam 20px e 14px e eram o
     caminho por onde o arredondamento chegava a quase todo container (molduras
     de video, cartoes de integracao e de midia, retratos do time, caixas de
     parceiro, a faixa de vagas). Ficam aqui, zerados, em vez de sumirem com as
     dezenas de `border-radius:var(--r)` espalhadas: assim o padrao e um so e
     esta decisao continua tendo um lugar unico para ser lida — ou revertida. */
  --r:0; --r-s:0;
  --nav-h:80px; /* altura da barra — a constelacao e a barra de rolagem se apoiam nela */
  /* A MESMA PILHA DA PLATAFORMA (vdcity/src/index.css) — nenhuma webfont.
     --f-disp e --f-body ficam como nomes distintos de proposito: hoje apontam
     para a mesma familia, e sao dois ganchos para diferenciar display de corpo
     no dia em que a marca adotar um tipo proprio, sem cacar 40 usos. */
  --f-sis:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --f-disp:var(--f-sis); --f-body:var(--f-sis);
  /* Mono: o padrao do Tailwind, que e o que a plataforma acaba usando no font-mono. */
  --f-mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
}
/* .media entra junto porque e caixa escura POR DENTRO de secao clara (as
   molduras de video): o texto dentro dela precisa da paleta escura, senao sai
   cinza-escuro sobre preto. A .devband ficava aqui pelo mesmo motivo e saiu
   com a faixa preta de dispositivos, que virou recorte sobre fundo claro. */
.on-dark, .media{
  --bg:#05070C; --bg2:#080B12; --surface:#0C111C; --surface2:#101725;
  --line:rgba(150,175,220,.12); --line2:rgba(150,175,220,.24);
  --ink:#EEF3FB; --mut:#9AA6BE; --mut2:#646F8A;
  --brand:#0D6ECF; /* mesmo valor do :root — e esse o ponto de ter o token */
  --acc:var(--brand); --acc2:var(--brand); --glow:rgba(13,110,207,.5);
  --grad:linear-gradient(110deg,var(--brand),var(--brand));
  --btn-glow:rgba(255,255,255,.4);
  --veu:rgba(150,175,220,.05); /* no escuro o veu clareia, senao some no fundo */
}
.on-dark{background:var(--bg); color:var(--ink)}
*{box-sizing:border-box;margin:0;padding:0}

/* BARRA DE ROLAGEM — um filete cinza, sem as setas das pontas.
   ATENCAO A ORDEM DAS DUAS APIS: no Chromium, declarar `scrollbar-width` FAZ O
   NAVEGADOR IGNORAR os pseudo-elementos ::-webkit-scrollbar por completo. As
   duas nao se somam — a padrao vence e desenha a barra dela, com as setas.
   Foi o que aconteceu na primeira tentativa: a barra saiu com 10px (o `thin` do
   Chrome) em vez dos 8 pedidos, e as setas continuaram la.
   Por isso a propriedade padrao fica atras de @supports, aplicada so onde os
   pseudo-elementos NAO existem — na pratica, o Firefox. */
@supports not selector(::-webkit-scrollbar){
  html{scrollbar-width:thin; scrollbar-color:rgba(130,145,175,.55) transparent}
}
/* O cinza tem alfa porque a pagina e branca no miolo e preta nas duas pontas:
   uma cor solida ficaria invisivel numa das duas. */
::-webkit-scrollbar{width:6px; height:6px}
/* A margem e o que tira o filete de cima da barra fixa: sem ela a pista comeca
   em y=0 e o polegar encosta na navbar quando a pagina esta no topo. */
::-webkit-scrollbar-track{background:transparent; margin-top:var(--nav-h)}
::-webkit-scrollbar-thumb{background:rgba(130,145,175,.5)}
::-webkit-scrollbar-thumb:hover{background:rgba(130,145,175,.75)}
::-webkit-scrollbar-button{display:none; width:0; height:0}
::-webkit-scrollbar-corner{background:transparent}
/* O fundo do <html> so aparece no overscroll (o "esticao" alem do fim da
   pagina). As duas pontas do site sao escuras — hero em cima, rodape
   embaixo —, entao ele acompanha; deixado no branco do body, aparecia uma
   faixa clara saindo do nada nos dois extremos. */
html{scroll-behavior:smooth; scroll-padding-top:96px; background:#05070C}
body{background:var(--bg); color:var(--ink); font-family:var(--f-body); -webkit-font-smoothing:antialiased; overflow-x:hidden; line-height:1.6}
a{color:inherit; text-decoration:none}
img{max-width:100%; display:block}
::selection{background:var(--acc); color:#fff}
.wrap{max-width:var(--maxw); margin:0 auto; padding:0 40px}
section{position:relative; z-index:1}
/* Secoes OPACAS. Antes eram veus semitransparentes para a constelacao do hero
   aparecer atraves da pagina inteira; agora o corpo e branco e a constelacao
   fica confinada ao hero (ver #cloud), entao cada secao pinta o proprio fundo.
   .cta usa --bg2 para dar uma quebra de tom contra o branco das vizinhas. */
/* #plataforma esta na lista mas e a faixa ESCURA da pagina: ela carrega
   `.on-dark`, entao o mesmo var(--bg) resolve para o preto. */
.own,#como,#plataforma,#semcom,#beneficios,#integracoes,#comparativo,#servicos,#sobre,#midia{background:var(--bg)}
.cta{background:var(--bg2)}

/* logo — same lockup the platform uses: the orbiting wireframe tetrahedron
   (drawn by initPrismLogo in common.js) followed by the VDCity wordmark.
   The mark is sized in `em` so a single rule serves the nav, the comparison
   header and the footer, each of which sets its own font-size. */
.logo{display:inline-flex; align-items:center; gap:.3em; font-family:var(--f-disp); line-height:1; user-select:none}
.logo__mark{flex:none; display:block; width:1.5em; height:1.5em}
.logo__word{display:inline-flex; align-items:baseline}
.logo__vdc{font-weight:800; font-style:italic; letter-spacing:-.09em}
.logo__ity{font-weight:300; font-size:.7em; letter-spacing:.05em; margin-left:.2em; opacity:.9}

h1,h2,h3{font-family:var(--f-disp); font-weight:500; line-height:1.06; letter-spacing:-.025em}
.kicker{font-family:var(--f-mono); font-size:12px; letter-spacing:.28em; text-transform:uppercase; color:var(--acc2)}
.lead{color:var(--mut); font-weight:400; font-size:clamp(16px,1.5vw,20px); line-height:1.7}
.grad-t{background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent}

[data-reveal]{opacity:0}
[data-reveal].is-in{opacity:1}

.btn{display:inline-flex; align-items:center; gap:.6em; font-family:var(--f-body); font-weight:600; font-size:15px; padding:14px 26px; border-radius:0; cursor:pointer; border:1px solid transparent; white-space:nowrap; transition:transform .25s cubic-bezier(.2,.8,.2,1), background .25s, border-color .25s, box-shadow .25s}
.btn--primary{background:var(--ink); color:var(--bg)}
.btn--primary:hover{transform:translateY(-2px); box-shadow:0 16px 40px -14px var(--btn-glow)}
.btn--glass{background:rgba(255,255,255,.06); color:#fff; border-color:rgba(255,255,255,.18); backdrop-filter:blur(8px)}
.btn--glass:hover{background:rgba(255,255,255,.12); transform:translateY(-2px)}
.btn--acc{background:var(--acc); color:#fff}
.btn--acc:hover{transform:translateY(-2px); box-shadow:0 16px 40px -14px var(--acc)}
.btn--wa{background:#1faf54; color:#fff}
.btn--wa:hover{transform:translateY(-2px)}
.btn--lg{font-size:16px; padding:17px 32px}

/* placeholder media */
.media{position:relative; overflow:hidden; background:
  repeating-linear-gradient(125deg, rgba(150,175,220,.045) 0 12px, transparent 12px 24px),
  linear-gradient(160deg, #11192a, #0a0f1a 70%); display:grid; place-items:center}
.media__tag{position:relative; z-index:2; font-family:var(--f-mono); font-size:12.5px; color:var(--mut); text-align:center; padding:16px 22px; border:1px dashed var(--line2); border-radius:0; background:rgba(5,7,12,.55); backdrop-filter:blur(2px); max-width:84%}
.media__tag b{display:block; color:var(--acc2); font-size:11px; letter-spacing:.18em; margin-bottom:7px}
/* EM BREVE: a caixa segue no HTML porque o gerar-plano.py lê dela o que falta
   gravar; na tela, o rascunho fica desfocado sob o selo. O desfoque é por
   text-shadow, e não filter, para não borrar o próprio selo. */
.media__tag b,.media__tag span,.parc .parc__i{color:transparent; text-shadow:0 0 12px var(--mut2); user-select:none}
.parc .parc__i{font-size:14px; text-shadow:0 0 10px var(--mut)}
.media__tag::after,.parc__i::after{content:"Em breve"; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  white-space:nowrap; padding:9px 18px; background:var(--brand);
  font-family:var(--f-mono); font-size:13px; font-weight:600; letter-spacing:.2em; text-transform:uppercase; color:#fff; text-shadow:none}
/* Fundo da caixa "Em breve": uma tela da plataforma desfocada a ponto de nao
   se ler nada, a mesma da apresentacao (FUNDO_BREVE). */
.media:has(.media__tag)::before{content:""; position:absolute; inset:-40px; z-index:1;
  background:url(/assets/apresentacao/servicos/cronograma-apresentacao.jpg) center/cover;
  filter:blur(10px); opacity:1}
.media__tag{border-color:transparent; background:none; backdrop-filter:none}
html[data-lang="en"] .media__tag::after,html[data-lang="en"] .parc__i::after{content:"Coming soon"}
html[data-lang="es"] .media__tag::after,html[data-lang="es"] .parc__i::after{content:"Próximamente"}
html[data-lang="fr"] .media__tag::after,html[data-lang="fr"] .parc__i::after{content:"Bientôt"}
html[data-lang="ja"] .media__tag::after,html[data-lang="ja"] .parc__i::after{content:"近日公開"}

/* nav */
/* A barra recolhe ao descer e volta ao subir (padrao "headroom"). O `transform`
   e o que anima; quem decide quando e o initNav em common.js.
   `will-change` evita o repintar da barra inteira a cada quadro do recolhimento. */
.nav{--nav-btn-h:38px; --nav-dir-w:296px; position:fixed; inset:0 0 auto 0; z-index:50; transition:transform .32s cubic-bezier(.2,.8,.2,1); will-change:transform}
.nav.is-hidden{transform:translateY(-100%)}
/* Quem pediu menos animacao nao ganha uma barra deslizante: ela some e volta
   sem trajeto. */
@media(prefers-reduced-motion:reduce){ .nav{transition:none} }
.nav__in{display:flex; align-items:center; gap:24px; height:var(--nav-h); max-width:var(--maxw); margin:0 auto; padding:0 40px}
/* Barra OPACA, sem vidro. O corpo do site é claro: um fundo translúcido com
   blur deixaria o conteúdo branco atravessar a barra ao rolar, e o menu (que é
   claro sobre preto) perderia contraste. A borda inferior é o único estado que
   muda ao rolar. */
.nav::after{content:""; position:absolute; inset:0; z-index:-1; background:var(--bg); border-bottom:1px solid transparent; transition:border-color .35s}
.nav.is-scrolled::after{border-bottom:1px solid var(--line)}
.nav.is-mega::after{border-bottom-color:transparent}
.nav .logo{font-size:25px}
.nav__links{display:flex; gap:30px; margin-left:14px}
.nav__links > a{font-size:14.5px; color:var(--ink); font-weight:500; transition:.2s}
.nav__links > a:hover{color:var(--acc2)}
/* ACOES DA BARRA — a escada do print de referencia: link de texto (entrar),
   botao de contorno (testar) e botao solido (demo). Tres pesos visuais para
   tres niveis de compromisso; se os tres tivessem o mesmo peso, nenhum seria
   o principal e o visitante teria de ler para decidir.
   Os botoes da barra sao menores que os do corpo da pagina: com tres deles ao
   lado de cinco links, o padding de 14/26px do .btn estouraria a largura. */
/* O bloco da direita tem A LARGURA DO CARTAO do drawer — os mesmos 296px do
   segundo trilho de .mega__in. Com isso a borda esquerda do globo cai no mesmo
   eixo da imagem que abre logo abaixo, e a direita segue no fim da .wrap: os
   dois pontos da barra passam a coincidir com os dois pontos do painel.
   Quem absorve a sobra e o botao primario (flex:1); os dois contornos ficam com
   a largura do proprio conteudo, que e o que os mantem discretos ao lado dele. */
.nav__right{display:flex; align-items:center; gap:8px; margin-left:auto; width:var(--nav-dir-w)}
.nav__right .btn{flex:1; justify-content:center; padding-left:12px; padding-right:12px}
.nav .btn{height:var(--nav-btn-h); padding:0 19px; font-size:14px}
/* CONTORNO, sem preenchimento. A cor e var(--ink), nao um branco cravado: na
   barra escura ele ja resolve para quase branco, e nas paginas legais — onde a
   barra e clara — um branco literal sumiria no fundo. Mesmo motivo pelo qual o
   resto da folha nunca escreve a cor na mao. */
.nav__login{display:inline-flex; align-items:center; height:var(--nav-btn-h); padding:0 14px; border:1px solid var(--ink); font-size:14.5px; font-weight:500; color:var(--ink); white-space:nowrap; transition:color .2s, border-color .2s}
.nav__login:hover{color:var(--acc2); border-color:var(--acc2)}
.btn--outline{background:transparent; color:var(--brand); border-color:var(--brand)}
.btn--outline:hover{background:var(--surface2); transform:translateY(-2px)}
/* `align-items` faltando: o inline-flex esticava a barra "/" (que nao tem
   padding) na altura dos <button> (que tem 6px), e o texto dela subia para o
   topo da caixa esticada — a barra saia flutuando acima do PT e do EN. */
/* IDIOMA — um globo que abre a lista. Era "PT / EN" escrito por extenso; virou
   icone porque a barra ganhou tres acoes e o par de siglas competia com elas
   por atencao sendo a de menor importancia.
   O `top:2px` que existia aqui foi embora junto com o texto: ele corrigia a
   linha de base do mono 12px contra a Manrope 14,5px dos vizinhos, e um icone
   nao tem linha de base para corrigir — centrar a caixa basta. */
.lang{position:relative; display:inline-flex; align-items:center; font-family:var(--f-mono); font-size:12px; line-height:1}
/* Branco como os links ao lado, nao cinza: o globo e um controle da barra,
   e em --mut ele lia como item desabilitado ao lado de "Entrar".
   Como o repouso subiu para --ink, o hover teve de sair de --ink (virou
   no-op) para --acc2 — o mesmo par que .nav__links > a ja usa. */
.lang__globo{display:flex; align-items:center; justify-content:center; width:var(--nav-btn-h); height:var(--nav-btn-h); padding:0; background:transparent; border:1px solid var(--ink); color:var(--ink); cursor:pointer; transition:color .2s, border-color .2s}
.lang__globo svg{width:18px; height:18px}
.lang__globo:hover,.lang.is-open .lang__globo{color:var(--acc2); border-color:var(--acc2)}
/* A lista sai do fluxo para nao empurrar a barra ao abrir. */
.lang__lista{position:absolute; top:calc(100% + 10px); right:0; min-width:150px; background:var(--bg); border:1px solid var(--line); padding:6px; display:none; z-index:60}
.lang.is-open .lang__lista{display:block}
/* Os nao selecionados tambem em --ink. Com isso o AZUL passa a significar
   uma coisa so na lista: "este e o seu idioma". Por isso o hover perdeu a
   troca de cor (que levava a --ink e agora nao mudaria nada) e ficou so
   com o fundo — pintar o hover de --acc2 faria item sob o cursor e item
   ativo ficarem identicos. */
.lang__lista button{display:block; width:100%; text-align:left; background:transparent; color:var(--ink); border:0; padding:9px 12px; font-family:var(--f-body); font-size:14px; cursor:pointer; transition:.2s}
.lang__lista button:hover{background:var(--surface2)}
.lang__lista button.is-active{color:var(--acc2)}
.burger{display:none; background:transparent; border:0; cursor:pointer; flex-direction:column; gap:5px; padding:8px; margin-left:auto}
.burger span{width:22px; height:2px; background:var(--ink); display:block}
/* Os dois so existem no menu do celular. No desktop o segundo nivel e o
   mega-menu, e o idioma e o globo da direita. */
.nav__sub{display:none}
.nav__idioma{display:none}

/* ============================================================ MEGA-MENU
   Painel que desce da barra ao passar o mouse num item com `data-mega`.
   Ele e IRMAO de .nav__in dentro da .nav (que e fixed), entao `top:100%` o
   ancora logo abaixo da barra sem repetir a altura dela em numero.
   Fundo ESCURO de proposito: a barra e preta e a pagina e branca; um painel
   branco descendo de uma barra preta criaria uma segunda emenda dura — o mesmo
   problema que ja foi resolvido no topo do hero.
   O painel encosta na barra (sem vao), entao o ponteiro nunca o atravessa ao
   descer: quem fecha e o mouseleave da .nav inteira. */
/* SEM linha entre a barra e o painel: os dois sao a mesma peca preta, e uma
   divisoria ali corta em duas o que deve ser lido como um bloco so. A borda
   de baixo fica — e ela que separa o painel do conteudo claro da pagina.
   `.nav.is-mega` (abaixo) apaga a borda da propria barra enquanto o painel
   esta aberto; sem isso, com a pagina rolada, a linha voltaria por ali. */
/* UMA MOLDURA, QUATRO CONTEUDOS: o fundo preto e a borda de baixo sao da
   .mega-shell, nao de cada painel. Enquanto cada painel trazia o proprio fundo,
   ir de "Plataforma" para "Servicos" fechava um e abria o outro: os dois
   apareciam meio transparentes ao mesmo tempo (um lia atraves do outro) e a
   caixa saltava de altura de uma vez so. Com a moldura, trocar de item nao
   fecha nada — ela fica onde esta, anima a altura ate a do painel novo e o
   conteudo troca por dentro. */
.mega-shell{position:absolute; top:100%; left:0; right:0; background:var(--bg); border-bottom:1px solid var(--line);
  height:0; overflow:hidden;
  opacity:0; visibility:hidden; transform:translateY(-8px); transition:opacity .2s, transform .2s, visibility .2s}
.mega-shell.is-open{opacity:1; visibility:visible; transform:none}
/* A altura so anima na TROCA de painel — o JS poe .is-morph. Na abertura vinda
   do fechado ela ja entra na medida certa: animar altura junto com a entrada
   faria a moldura crescer enquanto aparece, dois movimentos para um gesto so. */
.mega-shell.is-morph{transition:opacity .2s, transform .2s, visibility .2s, height .26s cubic-bezier(.32,.72,.3,1)}
/* Os paineis se empilham na moldura. A saida e mais curta que a entrada e a
   entrada comeca com um respiro: sem isso os dois textos ficam legiveis ao
   mesmo tempo no meio da transicao, que e exatamente o borrao a evitar. */
.mega{position:absolute; top:0; left:0; right:0; max-height:calc(100svh - var(--nav-h)); overflow-y:auto;
  opacity:0; visibility:hidden; transition:opacity .12s linear, visibility .12s}
.mega.is-open{opacity:1; visibility:visible; transition:opacity .18s ease .06s, visibility 0s}
/* A IMAGEM FICA A DIREITA, no mesmo eixo em que termina o botao da barra.
   O .mega__in ja tem o max-width e o padding da .wrap, entao a borda direita
   dele coincide com a do .nav__in — o que faltava era a coluna da imagem estar
   desse lado. Ela continua sendo o PRIMEIRO filho no HTML (e o destaque do
   painel, faz sentido vir antes na leitura de codigo e para quem navega por
   teclado); quem inverte na tela e o grid-column explicito abaixo. */
.mega__in{display:grid; grid-template-columns:1fr 296px; gap:46px; max-width:var(--maxw); margin:0 auto; padding:36px 40px 42px}
/* A LINHA PRECISA SER EXPLICITA, nao so a coluna. Com apenas `grid-column`, o
   posicionamento automatico colocava a imagem (primeira no HTML) na coluna 2 da
   linha 1 e, como ele nunca volta atras, os links — que pedem a coluna 1 —
   caiam na linha 2: o painel abria com um vao alto e a lista colada embaixo.
   Cravando `grid-row:1` nos dois, as duas colunas voltam a dividir a mesma
   linha, independentemente da ordem em que aparecem no HTML. */
.mega__cols{grid-column:1; grid-row:1; display:grid; grid-template-columns:repeat(3,1fr); gap:32px}
.mega__col h4+h4,.mega__it+h4{margin-top:26px}
.mega__col h4{font-family:var(--f-mono); font-size:11px; letter-spacing:.18em; text-transform:uppercase; color:var(--mut2); font-weight:400; margin-bottom:16px}
.mega__it{display:grid; grid-template-columns:22px 1fr; gap:12px; padding:8px 0; align-items:start}
.mega__it svg{width:18px; height:18px; margin-top:3px; color:var(--acc2)}
.mega__it b{display:block; font-size:14.5px; font-weight:500; color:var(--ink); line-height:1.3}
.mega__it i{display:block; font-style:normal; font-size:12.5px; color:var(--mut2); margin-top:2px; line-height:1.4}
.mega__it:hover b{color:var(--acc2)}
/* Cartao em destaque — a coluna da esquerda das referencias. */
.mega__feat{grid-column:2; grid-row:1; background:var(--surface); border:1px solid var(--line); padding-bottom:22px; align-self:start}
.mega__feat .media{aspect-ratio:16/10}
.mega__feat h5{font-family:var(--f-disp); font-size:16.5px; font-weight:500; color:var(--ink); margin:18px 20px 0; line-height:1.3}
.mega__feat p{font-size:13px; color:var(--mut); margin:9px 20px 0; line-height:1.55}
.mega__feat .mega__cta{display:inline-flex; align-items:center; gap:9px; margin:16px 20px 0; font-family:var(--f-mono); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--acc2); transition:gap .2s}
.mega__feat .mega__cta:hover{gap:15px}
/* Abaixo do ponto de colapso a barra vira hamburguer e o painel nao tem onde abrir. */
@media(max-width:1140px){ .mega-shell{display:none} }

/* hero — full-bleed + animated constellation */
/* --hero-base e a LINHA DE BASE do hero: a distancia entre o fim do conteudo e
   o fim da secao. Era um 88px cravado so no padding do .hero__in, e as duas
   pecas soltas (a metrica e o "role para explorar") tinham cada uma o seu
   proprio numero — 104px e um top:42% —, entao nada assentava junto. Com um
   valor unico, os tres param na mesma linha e continuam parando se ele mudar. */
.hero{position:relative; min-height:100svh; display:flex; align-items:flex-end; overflow:hidden; --hero-base:88px}
/* Presa ao hero. Era `fixed` cobrindo a viewport inteira, para a constelacao
   atravessar a pagina; com o corpo branco ela so faz sentido na faixa escura —
   e pintar um canvas de tela cheia debaixo de secoes opacas e trabalho jogado fora. */
/* Comeca ABAIXO da barra. Com o canvas colado no topo, os pontos dos primeiros
   80px ficavam escondidos atras da navbar opaca, mas as LINHAS ate os pontos de
   baixo continuavam visiveis — o desenho parecia sair cortado debaixo da barra. */
/* Largura e altura EXPLICITAS. <canvas> e elemento substituido: com
   width/height em `auto`, um `inset` com top E bottom nao o estica — o
   navegador descarta o bottom e usa o tamanho intrinseco (300x150). O
   canvas encolhia para isso e a contagem de pontos, que deriva da area,
   caia de ~150 para 4. */
#cloud{position:absolute; top:var(--nav-h); left:0; width:100%; height:calc(100% - var(--nav-h)); z-index:0; pointer-events:none}
/* O AZUL SAIU DO TOPO. Ele ficava em `at 82% 8%` — o canto superior direito,
   exatamente onde o hero encosta na barra: um claro ali contra o preto chapado
   da navbar vira uma emenda visivel. Agora o topo e chapado no mesmo preto da
   barra (a rampa comeca em .95) e o azul foi todo para BAIXO e para as LATERAIS,
   longe dessa junta. */
.hero__scrim{position:absolute; inset:0; z-index:1; pointer-events:none; background:
  linear-gradient(180deg, rgba(5,7,12,.95) 0%, rgba(5,7,12,.6) 10%, rgba(5,7,12,.08) 34%, rgba(5,7,12,.4) 74%, rgba(5,7,12,.55) 100%),
  radial-gradient(120% 90% at 18% 100%, rgba(5,7,12,.6), transparent 62%),
  radial-gradient(1200px 540px at 64% 106%, rgba(59,130,246,.24), transparent 64%),
  radial-gradient(700px 880px at -4% 56%, rgba(59,130,246,.15), transparent 62%),
  radial-gradient(700px 880px at 104% 60%, rgba(59,130,246,.17), transparent 62%)}
.hero__in{position:relative; z-index:2; width:100%; max-width:var(--maxw); margin:0 auto; padding:0 40px var(--hero-base)}
.hero h1{font-size:clamp(44px,7vw,94px); font-weight:500; max-width:15ch; margin:22px 0}
.hero .lead{max-width:56ch; font-size:clamp(17px,1.7vw,21px)}
.hero__cta{display:flex; gap:14px; flex-wrap:wrap; margin-top:38px}
.hero__scroll{position:absolute; top:auto; bottom:var(--hero-base); right:40px; z-index:2; writing-mode:vertical-rl; font-family:var(--f-mono); font-size:11px; letter-spacing:.3em; color:var(--mut); text-transform:uppercase; display:flex; align-items:center; gap:14px}
.hero__scroll::after{content:""; width:1px; height:60px; background:linear-gradient(var(--acc2),transparent)}
/* hero metric — reuses the [data-count] util in common.js */
/* O 48px daqui media a partir da BORDA DA TELA, entao o numero flutuava solto:
   em monitor largo ele ficava bem a direita do botao da barra e do resto do
   conteudo, que param no eixo da .wrap. A conta abaixo reproduz esse eixo — a
   metade do que sobra fora dos 1280px, mais os 40px de padding da .wrap — e o
   max() cobre a tela estreita, onde nao sobra nada e o recuo e so o padding. */
.hero__metric{position:absolute; right:max(40px, calc((100% - var(--maxw)) / 2 + 40px)); bottom:var(--hero-base); z-index:2; text-align:right; pointer-events:none}
.hero__metric-n{font-family:var(--f-disp); font-weight:600; line-height:.9; letter-spacing:-.03em; font-size:clamp(64px,8vw,124px); background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent; font-variant-numeric:tabular-nums}
.hero__metric-n i{font-style:normal; font-size:.42em; vertical-align:baseline; -webkit-text-fill-color:var(--acc2); color:var(--acc2)}
.hero__metric-l{display:block; margin-top:12px; font-family:var(--f-mono); font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--mut); line-height:1.55}

/* devices editorial — `own` is a leftover name from the ownership pitch this
   block used to open with; the section is now only about capture hardware. */
.own{padding:88px 0; text-align:center}
/* still styles the .lead and the app note below, not a heading of its own */
.own p{color:var(--mut); max-width:52ch; margin:20px auto 0; font-size:17px}
.own__flex{margin-top:0}
.own__flex .kicker{display:block; margin-bottom:16px}
.own__flex h3{font-family:var(--f-disp); font-weight:300; font-size:clamp(26px,3.6vw,44px); letter-spacing:-.02em; line-height:1.1; max-width:22ch; margin:0 auto}
.own__flex h3 b{font-weight:600}
.own__flex .lead{margin:16px auto 0; max-width:56ch}
/* APARELHOS — quatro recortes sobre o proprio fundo da secao.
   Antes era um PNG unico (devices-band.png) dentro de uma caixa preta, com os
   nomes por cima da foto: a caixa era o unico bloco daquele tom no meio da
   pagina clara, e o texto, mono de 12.5px em caixa alta sobre a imagem,
   competia com ela. Agora cada aparelho e um PNG com alfa; o fundo claro da
   secao e que da o contraste (os produtos sao pretos) e o nome desceu para
   fora da imagem, onde pode usar o --ink inteiro em corpo de leitura. */
/* Quatro trilhos iguais. O drone teve um trilho duplo enquanto as duas fotos
   dele ficavam lado a lado; empilhadas, elas cabem na mesma largura dos outros
   e o trilho extra so abriria vazio nas laterais. O row-gap e grande porque e
   ele que separa as fileiras quando a grade quebra nas telas menores. */
.devs{display:grid; grid-template-columns:repeat(4,1fr); gap:38px 10px; margin:48px auto 0; max-width:1240px}
.dev{margin:0; text-align:center}
/* Altura fixa e object-fit:contain porque as fotos vem em proporcoes diferentes
   — o drone e deitado, o scanner e em pe. Sem isso cada uma assentaria numa
   base propria e os quatro nomes sairiam em alturas diferentes. */
/* A ALTURA E DO <img>, NAO DA CAIXA — e por isso que aqui nao ha flex nem grid.
   Na primeira versao o .dev era `display:flex; flex-direction:column` e a caixa
   levava `height:176px`. Nao adiantou: item de flex column nasce com
   `min-height:auto`, que e o tamanho MINIMO DO CONTEUDO, e o conteudo era um
   <img> de 443px de altura natural. O minimo venceu a altura declarada, a caixa
   cresceu para 443px, o `max-height:100%` da imagem passou a medir 443 em vez
   de 176 e nao limitou nada — as fotos invadiram a legenda e o aviso do app.
   Agora o <img> ocupa exatamente a celula (100% x 100%) e quem encaixa a figura
   dentro dela, sem distorcer, e o object-fit:contain. */
/* A CAIXA E IGUAL PARA TODOS; o que muda e quanto dela cada aparelho ocupa.
   A altura precisa ser a mesma nas quatro celulas porque a legenda vem logo
   abaixo — uma caixa mais alta que as outras jogaria aquele nome para fora da
   linha de base. Entao o ajuste de tamanho vive na imagem, em % da caixa, e a
   caixa so precisa ser alta o bastante para o maior deles (a camera, em 95%) e
   para a pilha do drone (70% + 22% + o vao). Dai os 290px.
   `min-height/min-width:0` porque a caixa e flex e item de flex nao encolhe
   abaixo do tamanho intrinseco da imagem sem isso — o piso automatico que ja
   derrubou estas fotos por cima da legenda uma vez. */
.dev__img{height:290px; display:flex; align-items:center; justify-content:center}
.dev__img img{width:100%; height:100%; object-fit:contain; min-height:0; min-width:0}
/* CALIBRAGEM POR APARELHO. As fotos vem de fontes diferentes e cada uma tem uma
   folga propria de moldura, entao encaixadas na mesma caixa elas nao pesam
   igual na fileira: o scanner parecia gigante e a camera, pequena. Os numeros
   abaixo sao o ajuste fino dessa percepcao — nao a escala real dos produtos.
   O translateY existe pelo mesmo motivo, no outro eixo: a folga branca acima do
   produto varia de PNG para PNG, entao centralizar as CAIXAS nao centraliza o
   que se ve. A camera e o celular vinham nascendo acima da linha dos outros
   dois; os poucos pixels aqui sao alinhamento OPTICO, medido na tela, e nao ha
   conta que os derive — se as fotos forem trocadas, tem de ser remedidos.
   E transform, e nao margem, para nao mover a legenda junto. */
.dev--cam .dev__img img{height:95%; transform:translateY(9px)}
.dev--fone .dev__img img{height:86%; transform:translateY(26px)}
.dev--blk .dev__img img{height:78%; transform:translateY(24px)}
/* O DRONE VEM COM O CONTROLE, empilhados na mesma celula: o equipamento em
   cima, grande, e o acessorio embaixo, menor. As duas fotos seguem com a
   largura da celula (herdada da regra acima) e o que as diferencia e a ALTURA
   em porcentagem da caixa — 70% contra 22% —, com o object-fit:contain
   encaixando cada uma na sua faixa sem distorcer. Em porcentagem, e nao em px,
   para a pilha acompanhar a caixa quando ela encolhe nos telefones.
   `min-height:0` e obrigatorio: item de flex COLUMN nasce com `min-height:auto`,
   que vale o tamanho intrinseco do conteudo — 383px do drone —, e sem zerar
   isso a pilha estoura a caixa. Foi exatamente esse piso que ja tinha derrubado
   estas fotos por cima da legenda uma vez. */
.dev--kit .dev__img{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px}
.dev--kit .dev__img img{min-height:0}
.dev--kit .dev__img img:nth-child(1){height:78%}
.dev--kit .dev__img img:nth-child(2){height:19%}
.dev figcaption{margin-top:20px; text-align:center}
.dev figcaption b{display:block; font-size:15.5px; font-weight:600; color:var(--ink)}
.dev figcaption span{display:block; margin-top:6px; font-family:var(--f-mono); font-size:11.5px; letter-spacing:.06em; color:var(--mut2)}
.own__appnote{display:inline-flex; align-items:center; gap:11px; margin:22px auto 0; padding:13px 22px; border:1px solid var(--line2); border-radius:0; background:rgba(59,130,246,.06); color:var(--ink); font-size:14.5px; text-align:left; max-width:none}
.own__appnote svg{flex:none; color:var(--acc2)}
.own__appnote b{font-weight:600}

/* section base */
.sec{padding:110px 0}
.sec__head{max-width:62ch; margin-bottom:64px}
.sec__head .kicker{margin-bottom:18px; display:block}
.sec__head h2{font-size:clamp(30px,4vw,52px); font-weight:500}
.sec__head .lead{margin-top:20px}

/* process — alternating big rows */
.proc{display:grid; gap:30px}
.prow{display:grid; grid-template-columns:1fr 1fr; gap:54px; align-items:center}
.prow:nth-child(even) .prow__txt{order:2}
.prow__txt{max-width:46ch}
.prow__n{font-family:var(--f-disp); font-weight:300; font-size:64px; line-height:1; color:transparent; -webkit-text-stroke:1px var(--line2); margin-bottom:18px}
.prow__txt h3{font-size:clamp(26px,2.8vw,38px); font-weight:500; margin-bottom:14px}
.prow__txt p{color:var(--mut); font-size:17px}
/* A PROPORCAO E A DO MATERIAL, nao um numero escolhido. As gravacoes sairam
   em 1280x720 e perderam os 98px de barra do navegador no corte, sobrando
   1280x622 — quase 2:1. Manter a moldura em 4:3 obrigaria o object-fit a comer
   um terco da largura de cada lado, que e onde ficam a barra lateral e o painel
   direito da plataforma: justamente o que a peca precisa mostrar. */
.prow .media{aspect-ratio:1280/622; border-radius:var(--r); border:1px solid var(--line)}
.media--video video{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block}

/* platform — grid of screens (technical treatment) */
/* CADA TELA E UMA JANELA. Os tres sinais desceram do bloco inteiro para cada
   peca: a leitura passa a ser "quatro janelas de aplicativo abertas", que e o
   que essas telas sao de fato. Retas, sem raio, pela mesma razao de sempre —
   e a lingua do resto da pagina (ver o comentario do .cta__card). */
/* Os tres sinais sao cor LITERAL de proposito, contra a regra do resto da
   folha: eles citam um objeto do mundo real (o semaforo da janela do macOS) e
   sao os mesmos no tema claro e no escuro — nao ha papel de paleta que os
   descreva, entao nao ha token a usar. */
.plat__dots{flex:none; display:flex; gap:7px; width:47px}
/* Unico redondo que sobrou no site, e de proposito: nao e canto arredondado,
   e circulo — o semaforo da janela do macOS. Quadrado, deixa de ser a citacao
   que a barra da #plataforma faz. */
.plat__dots i{display:block; width:11px; height:11px; border-radius:50%}
.plat__dots i:nth-child(1){background:#FF5F57}
.plat__dots i:nth-child(2){background:#FEBC2E}
.plat__dots i:nth-child(3){background:#28C840}
/* `minmax(0,1fr)` e nao `1fr`: `1fr` e `minmax(auto,1fr)`, e esse `auto` poe no
   trilho um PISO de min-content. Quem levanta esse piso e a pilula da URL —
   ela e `white-space:nowrap`, entao "vdcity.io/nuvem-de-pontos" mede o texto
   inteiro por menor que seja a tela. Numa coluna so (celular) o trilho nascia
   com 352px dentro de uma caixa de 299: a janela vazava 16px para fora da
   viewport, o documento inteiro ganhava rolagem lateral e sobrava uma faixa
   preta na direita da pagina. O `0` no minimo devolve ao trilho o direito de
   encolher; quem passa do tamanho e cortado dentro da janela, que ja e
   `overflow:hidden`. */
.screens{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:38px 22px}
.scr{position:relative}

/* PALETA DA JANELA — a do modo escuro do macOS, nao a do site.
   Os tokens do site sao pretos AZULADOS (--surface e #0C111C); o macOS e cinza
   neutro. Lado a lado, o azulado denuncia que a janela e desenho nosso. Por isso
   estas cinco variaveis ficam presas a .scr__janela em vez de virem dos tokens:
   e uma citacao de outro sistema, do mesmo jeito que os tres sinais sao cor
   literal. Nada aqui destaca texto com cor — so intensidade de branco. */
.scr__janela{
  --mac-barra:#333336;      /* a barra de titulo */
  --mac-corpo:#1E1E1E;      /* o miolo da janela */
  --mac-linha:rgba(255,255,255,.09);
  --mac-forte:rgba(255,255,255,.88);
  --mac-fraco:rgba(255,255,255,.45);
  --mac-tenue:rgba(255,255,255,.32);
  border:1px solid rgba(255,255,255,.13); background:var(--mac-corpo); overflow:hidden;
  /* UNICO CANTO ARREDONDADO DO SITE, e de proposito. O resto da pagina e reto
     por decisao (ver o comentario do .cta__card e os tokens --r zerados); aqui
     a peca cita uma janela do macOS, e janela de macOS tem canto mole. E a
     mesma logica dos tres sinais serem cor literal: a excecao existe porque a
     peca fala a lingua de outro sistema, nao a nossa. */
  border-radius:10px;
  /* Janela do macOS tem sombra sempre, nao so no hover — e ela e NEUTRA. */
  box-shadow:0 16px 38px -22px rgba(0,0,0,.75);
  transition:transform .35s cubic-bezier(.2,.8,.2,1), border-color .35s, box-shadow .35s}
.scr:hover .scr__janela{transform:translateY(-5px); border-color:rgba(255,255,255,.22);
  box-shadow:0 34px 72px -30px rgba(0,0,0,.85)}
/* Sinais a esquerda, indice a direita e o titulo no meio — os dois lados tem a
   MESMA largura de proposito, senao "centralizado" seria o centro do que sobrou
   e o titulo nasceria torto. */
.scr__barra{display:flex; align-items:center; gap:9px; padding:9px 12px;
  border-bottom:1px solid var(--mac-linha); background:var(--mac-barra)}
/* OS ENFEITES DA BARRA SAO MENORES DO QUE PEDIRIA UMA JANELA SOLTA, e de
   proposito. Logo abaixo deles roda uma gravacao de 1280px de largura exibida
   em ~570px: TODA a interface da plataforma aparece a ~45% do tamanho real, e
   um botao de 16px do produto chega na tela com ~7px. Desenhados no tamanho de
   verdade (13px de icone, 9px de sinal), os enfeites ficavam quase o dobro dos
   controles reais e a leitura invertia — a moldura pesava mais que o miolo que
   ela existe para emoldurar. Agora eles caem para a mesma faixa do que o video
   mostra. A ALTURA DA BARRA nao encolheu junto: a barra de navegador que sumiu
   no corte media 98px, ~43px nessa escala, e e a folga em volta de controle
   pequeno que faz a peca ler como macOS em vez de tira apertada. */
.scr__barra .plat__dots{flex:none; width:40px; gap:5px}
.scr__barra .plat__dots i{width:7px; height:7px}
/* Titulo de janela do macOS e a fonte do sistema em caixa normal, nao mono em
   caixa alta com entreletras — que e a etiqueta do RESTO do site. Aqui a peca
   imita outro sistema, entao segue a regra dele. */
/* Setas e acoes sao enfeite funcional: existem para a barra ler como barra de
   navegador. Ficam em `aria-hidden` porque nao fazem nada — anunciar "botao
   voltar" a um leitor de tela seria mentir sobre o que a peca e. */
.scr__nav,.scr__acoes{flex:none; display:flex; align-items:center; color:var(--mac-tenue)}
.scr__nav{gap:1px}
.scr__acoes{gap:7px}
.scr__nav svg,.scr__acoes svg{width:10px; height:10px; display:block}
/* A pilula tem largura propria e margem automatica: e isso que a centraliza no
   meio da BARRA, e nao no meio do que sobrou depois dos icones. */
.scr__url{flex:0 1 250px; min-width:0; margin:0 auto; display:flex; align-items:center;
  justify-content:center; gap:4px; padding:3px 9px; border-radius:5px;
  background:rgba(255,255,255,.07); font-family:var(--f-disp); font-size:9.5px;
  color:var(--mac-tenue); white-space:nowrap; overflow:hidden}
.scr__url svg{flex:none; width:8.5px; height:8.5px; opacity:.8}
.scr__dominio{color:var(--mac-forte)}
.scr__stage{position:relative; aspect-ratio:1280/622}
.scr__stage .media{position:absolute; inset:0}
/* A faixa de dados desceu para junto da descricao, fora da janela — entao volta
   a usar os tokens do SITE. As variaveis --mac-* moram em .scr__janela e nao
   alcancam aqui; deixadas, a faixa herdaria cor de lugar nenhum. */
.scr__meta{display:flex; gap:18px; flex-wrap:wrap; margin-top:11px;
  font-family:var(--f-mono); font-size:11.5px; color:var(--mut2); letter-spacing:.03em}
.scr__meta b{color:var(--mut); font-weight:500}
.scr__cap{padding:16px 2px 0}
.scr__cap h3{font-size:18px; font-weight:500; margin-bottom:4px}
.scr__cap p{color:var(--mut); font-size:14px}

/* benefits editorial list */
.ben{display:grid; grid-template-columns:repeat(2,1fr); gap:0 60px}
.ben__i{display:grid; grid-template-columns:auto 1fr; gap:22px; padding:30px 0; border-top:1px solid var(--line); align-items:start}
.ben__mark{display:flex; flex-direction:column; align-items:flex-start; gap:12px; padding-top:3px}
.ben__mark svg{width:40px; height:40px; color:var(--acc2); stroke:var(--acc2)}
.ben__i .num{font-family:var(--f-mono); font-size:13px; color:var(--acc2)}
.ben__i h3{font-size:21px; font-weight:600; margin-bottom:7px}
.ben__i p{color:var(--mut); font-size:15px}

/* sem x com: a tabela da dor a esquerda, o numero a direita */
.semcom{display:grid; grid-template-columns:minmax(0,1.4fr) minmax(0,1fr); gap:48px; align-items:stretch}
.semcom__tab{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); column-gap:32px; align-content:start}
.semcom__h{font-family:var(--f-mono); font-size:11.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--mut2); padding-bottom:14px}
.semcom__h + .semcom__h{color:var(--acc2)}
.semcom__tab > div:not(.semcom__h){display:flex; gap:12px; align-items:baseline; padding:16px 0; border-top:1px solid var(--line); font-size:16px; color:var(--mut)}
.semcom__tab > div:nth-child(even):not(.semcom__h){color:var(--ink); font-weight:500}
.semcom__tab i{font-style:normal; font-family:var(--f-mono); color:var(--mut2); flex:none; width:12px}
.semcom__tab > div:nth-child(even) i{color:var(--acc2)}
.semcom__num{border:1px solid var(--line2); background:linear-gradient(180deg,rgba(59,130,246,.08),var(--surface)); padding:36px 34px; display:flex; flex-direction:column; justify-content:center}
.semcom__num > b{display:block; font-family:var(--f-disp); font-size:clamp(64px,7.6vw,104px); font-weight:600; color:var(--acc2); line-height:1; margin:18px 0 12px}
.semcom__num > b small{font-size:20px; font-weight:400; color:var(--mut); margin-right:10px}
.semcom__num > p:not(.kicker){color:var(--mut); font-size:16px; max-width:34ch}
.semcom__mais{display:flex; flex-wrap:wrap; gap:8px 20px; margin-top:22px; font-family:var(--f-mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase}
.semcom__mais b{color:var(--acc2); margin-right:6px}
@media(max-width:900px){ .semcom{grid-template-columns:minmax(0,1fr); gap:32px} }
@media(max-width:460px){ .semcom__tab{column-gap:16px} .semcom__tab > div:not(.semcom__h){font-size:14.5px} .semcom__num{padding:28px 22px} }

/* integrations */
.intg{display:grid; grid-template-columns:repeat(4,1fr); gap:16px}
.intg__item{position:relative; border:1px solid var(--line); background:linear-gradient(180deg,var(--surface),var(--bg)); border-radius:var(--r-s); padding:26px 18px; text-align:center; transition:transform .3s cubic-bezier(.2,.8,.2,1), border-color .3s, background .3s}
.intg__item:hover{transform:translateY(-4px); border-color:var(--line2); background:var(--surface2)}
.intg__item.is-feat{border-color:rgba(99,199,255,.4); background:linear-gradient(180deg,rgba(59,130,246,.12),var(--surface))}
.intg__item.is-feat::after{content:"\2605"; position:absolute; top:11px; right:13px; font-size:9px; color:var(--acc2)}
.intg__item svg{margin:0 auto 14px; color:var(--acc2)}
.intg__item span{display:block; font-size:14.5px; font-weight:500; color:var(--ink)}
.intg__item small{display:block; color:var(--mut2); font-family:var(--f-mono); font-size:10.5px; margin-top:5px; letter-spacing:.04em}
.intg__note{margin-top:22px; text-align:center; font-family:var(--f-mono); font-size:12.5px; color:var(--mut2); letter-spacing:.03em}
/* App e ACC: as duas integracoes que ganharam texto proprio, em dois cartoes */
/* O cartao do ACC ficou sozinho na largura toda quando o app virou secao
   propria (#app): texto a esquerda, lista a direita. */
.intg__card{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 48px; align-items:start; margin-top:44px; border:1px solid var(--line); background:linear-gradient(180deg,var(--surface),var(--bg)); border-radius:var(--r-s); padding:34px 32px}
.intg__card .kicker{display:block; margin-bottom:14px}
.intg__card h3{font-size:24px; font-weight:500; margin-bottom:10px}
.intg__card p{color:var(--mut); font-size:15.5px}
.intg__card ul{list-style:none; margin:0; padding:0}
.intg__card li{padding:11px 0; border-top:1px solid var(--line); font-size:14.5px}
.intg__card li::before{content:"+"; font-family:var(--f-mono); color:var(--acc2); margin-right:10px}
@media(max-width:900px){ .intg__card{grid-template-columns:minmax(0,1fr); padding:28px 22px} .intg__card ul{margin-top:20px} }

/* ============================================================ APP
   Texto a esquerda, as tres telas a direita. A do meio fica mais alta que as
   vizinhas: alinhadas, as tres liam como uma tabela de prints.
   A moldura e o unico canto redondo da pagina de proposito — e um celular. */
.app{background:var(--bg2); border-top:1px solid var(--line); border-bottom:1px solid var(--line)}
.app__in{display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); gap:64px; align-items:center}
.app__txt .kicker{display:block; margin-bottom:18px}
.app__txt h2{font-size:clamp(30px,4vw,52px); font-weight:500; max-width:15ch}
.app__txt .lead{margin-top:20px; max-width:46ch}
.app__so{margin-top:26px; font-family:var(--f-mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--mut2)}
.app__telas{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:22px; align-items:start}
.app__telas figure{margin:0}
.app__telas figure:nth-child(odd){margin-top:44px}
.app__cel{border:6px solid #0B0E14; border-radius:30px; overflow:hidden; background:#05070C; box-shadow:0 30px 60px -30px rgba(5,7,12,.5)}
.app__cel img{display:block; width:100%; height:auto}
.app__telas figcaption{margin-top:14px; font-size:13.5px; line-height:1.4; color:var(--mut); text-align:center}
@media(max-width:900px){
  .app__in{grid-template-columns:minmax(0,1fr); gap:40px}
  .app__telas{gap:10px}
  .app__telas figure:nth-child(odd){margin-top:24px}
  .app__cel{border-width:4px; border-radius:18px}
  .app__telas figcaption{font-size:12px}
}

/* ====================================================== TABELA COMPARATIVA
   REGUA, NAO CAIXA. Eram tres camadas de fundo empilhadas para dizer o que uma
   regua diz melhor: um painel azulado de cantos arredondados em volta do corpo
   inteiro, um veu em degrade por linha e o raio de 14px repetido nos dois. O
   que estrutura uma tabela e a coluna alinhada e o filete entre as linhas — o
   resto disputava a leitura com o texto.
   E o veu mudou de lugar: quem precisa de destaque e a COLUNA da VDCity, nao o
   corpo da tabela. O nome `.vc-wrap` ja dizia isso ("VDCity column"), mas ele
   tinha virado o painel de todas as linhas. */
.cmp{max-width:900px; margin:0 auto}
/* `stretch` + recuo NA CELULA (nunca na linha): e o que faz o veu da coluna
   correr de cima a baixo sem uma faixa vazia entre uma linha e a seguinte. */
.cmp__r{display:grid; grid-template-columns:1.5fr 1fr 1fr; align-items:stretch}
.cmp__r > *{display:flex; align-items:center; padding:17px 20px}
/* As pontas encostam na largura da .cmp: recuo interno na primeira e na ultima
   coluna desalinharia a tabela do resto da pagina. */
.cmp__r > *:first-child{padding-left:0}
.cmp__r > *:last-child{padding-right:0}
/* O filete de cima da primeira linha e o que sublinha o cabecalho — nao
   precisa de uma borda so dele.
   BORDA NA CELULA, nao na linha: o fundo de um filho e pintado DEPOIS da borda
   do pai, entao o veu da coluna cobria o filete e a regua sumia justo no meio
   da tabela. Na celula, cada uma desenha o proprio pedaco por cima do proprio
   fundo e a linha atravessa inteira. */
.cmp__r.body > *{border-top:1px solid var(--line)}
.cmp__r.body:last-child > *{border-bottom:1px solid var(--line)}
.cmp__r.head{color:var(--mut2); font-family:var(--f-mono); font-size:12px; letter-spacing:.1em; text-transform:uppercase}
/* Recuo igual nas tres celulas: e o que mantem o logo na mesma linha optica de
   RECURSO e SAAS TIPICO — as celulas centralizam o conteudo, entao basta nao
   dar recuo diferente a uma delas. */
.cmp__r.head > *{padding-top:12px; padding-bottom:12px}
.cmp__r.head .vc{color:var(--ink)}
/* A celula e flex (regra acima) para o veu preencher a altura toda; o titulo e
   o <small> voltam a empilhar aqui. */
.cmp__feat{flex-direction:column; align-items:flex-start; justify-content:center; font-weight:600; font-size:16px}
.cmp__feat small{display:block; color:var(--mut2); font-weight:400; font-size:13px; font-family:var(--f-mono); margin-top:3px}
.vc{background:var(--veu)}
.cmp__val{display:flex; align-items:center; gap:10px; font-size:15px; color:var(--mut)}
.cmp__val.yes{color:var(--acc2)}
/* No fundo escuro o azul da marca fica MENOS visivel que o cinza da coluna
   vizinha e a enfase se inverte: a coluna do concorrente passa a ganhar a
   leitura, que e o contrario do que a tabela existe para dizer. No claro o
   mesmo azul e o mais forte dos tres, entao a regra vale so aqui: o valor vai
   para o branco e o azul fica no sinal de confere, que basta como marcacao. */
.on-dark .cmp__val.yes{color:var(--ink)}
.on-dark .cmp__val.yes svg{color:var(--brand)}
.cmp__val svg{flex:none}

/* SECOES PENDENTES — Servicos, Sobre nos e Midia entraram porque o menu pede
   esses cinco destinos, mas o conteudo ainda nao existe. A caixa tracejada
   segue a mesma convencao de .media__tag: sinaliza "a preencher" em vez de
   fingir que a secao esta pronta. Ao preencher, apague .todo e o data-todo. */
.todo{max-width:760px; margin:0 auto; border:1px dashed var(--line2); border-radius:var(--r); padding:38px 30px; text-align:center; font-family:var(--f-mono); font-size:12.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--mut2)}
.todo b{display:block; color:var(--acc2); font-size:11px; letter-spacing:.2em; margin-bottom:9px}
/* Uma secao com VARIOS destinos pendentes (Sobre nos e Midia, cujos drawers
   apontam para institucional, time, blog, cases...). Cada destino precisa do
   proprio id para a ancora do menu chegar em algum lugar; empilhados em caixas
   de largura inteira eles esticariam a pagina sem dizer mais nada, entao vao
   numa grade compacta. Ao preencher um slot, tire-o daqui e escreva a secao. */
.todos{display:grid; grid-template-columns:repeat(auto-fit,minmax(228px,1fr)); gap:14px; max-width:980px; margin:0 auto}
.todos .todo{max-width:none; margin:0; padding:28px 18px}

/* cta full-bleed */
.cta{position:relative; overflow:hidden; padding:120px 0}
/* ONDE O #contato PARA quando se clica em "Contato" no menu.
   O padrao (scroll-padding-top:96px do <html>) encosta o TOPO DA SECAO logo
   abaixo da barra — e ai os 120px de padding dela ainda vinham antes do
   primeiro texto: 216px de fundo vazio no alto da tela, com o formulario,
   que e o motivo do clique, empurrado para fora. O valor negativo desconta
   esse vao. A conta: 96 (scroll-padding) + (-220) = -124px, ou seja, a secao
   comeca 124px ACIMA da dobra. O alvo do enquadramento e o formulario: o
   kicker sai de cena, o H2 assume o alto da tela (a 34px, sob a barra, que na
   chegada esta recolhida porque se esconde ao descer) e o cartao sobe junto.
   Este e o limite util — daqui para baixo quem sai da tela e o proprio H2, e
   a pessoa chega numa pagina que comeca em campo de formulario, sem a frase
   que explica o porque. Se ainda faltar espaco, o caminho passa a ser comprimir
   o bloco (o padding de 120px desta secao e o margin-top:46px do cartao), nao
   empurrar a ancora.
   Negativo so vale em scroll-margin; scroll-padding nao aceita. */
#contato{scroll-margin-top:-220px}
.cta__bg{position:absolute; inset:0; z-index:0}
.cta__bg .media{position:absolute; inset:0}
/* Veu mais leve desde que o fundo virou a foto do drone: a .94 ela sumia.
   Continua opaco no alto, onde encosta na secao de cima, e fecha embaixo,
   atras do formulario. */
.cta__scrim{position:absolute; inset:0; z-index:1; background:linear-gradient(180deg, var(--bg2), rgba(244,247,251,.8) 38%, rgba(244,247,251,.93)), radial-gradient(80% 60% at 50% 40%, rgba(30,138,230,.10), transparent 60%)}
.cta__in{position:relative; z-index:2; max-width:980px; margin:0 auto; padding:0 40px; text-align:center}
.cta__in h2{font-size:clamp(32px,4.6vw,58px); font-weight:500; max-width:18ch; margin:20px auto 0}
.cta__in .lead{max-width:52ch; margin:22px auto 0}
/* Cartao do formulario: retangulo, filete e nada mais. A sombra grande e o
   raio de 20px faziam dele o unico objeto "flutuante" de uma pagina construida
   em caixas retas e filetes (.scr, .plat__bar, .intg__item, .btn) — chamava
   mais atencao que o proprio conteudo. Branco sobre --bg2 ja o destaca. */
.cta__card{margin-top:46px; background:var(--surface); border:1px solid var(--line); border-radius:0; padding:34px; text-align:left; max-width:560px; margin-left:auto; margin-right:auto}
.form{display:grid; gap:16px}
.form .row{display:grid; grid-template-columns:1fr 1fr; gap:16px}
/* Um rotulo que quebra em duas linhas ao lado de um de uma linha empurrava o
   proprio campo para baixo e os dois da mesma linha deixavam de se alinhar
   (visivel em "Principal tipo de obra" x "Obras em andamento", no /teste).
   Com a celula em coluna e o campo colado no fim dela, quem cresce e o rotulo,
   para cima — os campos ficam sempre na mesma base. */
.form .row > div{display:flex; flex-direction:column}
.form .row > div > :last-child{margin-top:auto}
/* O recuo negativo daqui era -6px: encostava o campo no rotulo. Funcionava
   enquanto o campo era quase transparente (rgba(255,255,255,.04)); com o
   fundo claro e OPACO ele passou a cobrir a metade de baixo do rotulo. */
.form label{font-family:var(--f-mono); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--mut2); margin-bottom:7px; display:block}
/* Campo = filete retangular sobre o proprio cartao. O preenchimento cinza
   (--bg2) desenhava uma segunda caixa dentro da primeira: sete retangulos
   coloridos onde bastavam sete linhas. Sem ele, o que marca o campo e a borda,
   e o rotulo em mono acima faz o resto do trabalho. */
/* `line-height` explicito: sem ele o campo herda o 1.6 do body e a altura passa
   a depender da entrelinha de leitura, que nao tem nada a ver com um campo de
   uma linha so. Com 1.4 a conta fecha em 45px (21 de texto + 22 de recuo + 2 de
   borda) — era 54px. */
.form input,.form select,.form textarea{width:100%; font-family:var(--f-body); font-size:15px; line-height:1.4; color:var(--ink); background:transparent; border:1px solid var(--line); border-radius:0; padding:11px 14px; transition:border-color .18s, box-shadow .18s}
.form input::placeholder,.form textarea::placeholder{color:var(--mut2)}
/* Textarea so estica na vertical: `both` (o padrao) deixa o visitante arrastar
   o campo para fora do cartao. */
.form textarea{resize:vertical; min-height:62px}
/* Foco SEM halo: o anel de 3px desfocado era a unica peca macia da pagina. Uma
   segunda linha por dentro (inset) engrossa a borda para 2px sem empurrar o
   layout meio pixel — trocar a espessura da borda mexeria na altura do campo. */
.form input:focus,.form select:focus,.form textarea:focus{outline:none; border-color:var(--acc2); box-shadow:inset 0 0 0 1px var(--acc2)}
.form select{appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:36px; background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2369738A' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 14px center}
/* A seta acompanha o foco. O azul aqui e o da marca (--brand, #0D6ECF): estava
   num ciano #63C7FF que saiu da paleta quando o gradiente virou cor chapada.
   Reafirmar repeat/position e proposital — sem isso a seta ladrilha. */
.form select:focus{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230D6ECF' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 14px center}
.form select option{background:var(--surface); color:var(--ink)}
/* BOTAO EMPILHADO E DA LARGURA DO CARTAO. Lado a lado eles competiam: dois
   retangulos de cor cheia disputando a mesma linha, e o WhatsApp — que e a
   saida secundaria — chegava com o mesmo peso do envio. Um sobre o outro impoe
   ordem de leitura, e a largura total os alinha com os campos acima.
   Grade e nao flex por causa do .form__ok, que aparece depois do envio: no
   flex ele entrava na mesma linha dos botoes; aqui ele e a proxima faixa. */
.form__row2{display:grid; gap:10px; margin-top:6px}
/* Vale para os dois formularios (a home e o .tst__enviar do /teste): a regra
   pega qualquer .btn dentro de .form, e a especificidade (0,2,0) vence o
   .btn--lg que os dois carregam no HTML. */
.form .btn{width:100%; justify-content:center; font-size:15px; line-height:1.4; padding:12px 20px}
.form__ok{display:none; align-items:center; justify-content:center; gap:9px; color:var(--acc2); font-size:14.5px; font-weight:600}
.form__ok.is-in{display:flex}

/* ============================================================ RODAPE
   MAPA DO SITE, nao assinatura. Ele repete a taxonomia do mega-menu — Captura
   da Realidade, Projeto e BIM, Gestao de Obra, Time, Financeiro e Suprimentos —
   porque quem chega ao fim de uma pagina de servico nao tem o mega-menu aberto
   e precisa de um lugar com a lista inteira. Os dois blocos que o menu nao tem
   entram aqui: Plataforma (as secoes da home) e Empresa.
   Duas faixas: em cima marca + colunas de links; embaixo redes, copyright e os
   documentos (privacidade, termos, cookies). */
.foot{position:relative; overflow:hidden; border-top:1px solid var(--line); padding:64px 0 34px}
/* MESMA FUMACA AZUL DO HERO, sem a constelacao. As duas pontas escuras do site
   agora fecham igual: o azul entra por baixo e pelas laterais e o miolo escuro
   segura o texto. Aqui e so gradiente — nada de <canvas>: os pontos e linhas
   custam um requestAnimationFrame permanente e no rodape ninguem os olha.
   O TOPO FICA CHAPADO (a rampa escura comeca em .92). Acima do rodape vem uma
   secao clara: um claro azul colado no border-top brigaria com essa emenda,
   o mesmo motivo que empurrou o azul do hero para longe da barra fixa.
   A ultima parada volta a .5 para o pe da pagina encontrar o #05070C do
   overscroll do <html> sem degrau. */
.foot::before{content:""; position:absolute; inset:0; z-index:0; pointer-events:none; background:
  linear-gradient(180deg, rgba(5,7,12,.92) 0%, rgba(5,7,12,.55) 14%, rgba(5,7,12,.1) 44%, rgba(5,7,12,.34) 82%, rgba(5,7,12,.5) 100%),
  radial-gradient(1100px 420px at 62% 108%, rgba(59,130,246,.26), transparent 64%),
  radial-gradient(620px 620px at -6% 58%, rgba(59,130,246,.16), transparent 62%),
  radial-gradient(620px 620px at 106% 62%, rgba(59,130,246,.18), transparent 62%)}
/* As duas faixas do rodape sao `.wrap`; sem o z-index elas ficam no mesmo
   nivel do ::before e o veu passaria por cima do texto. */
.foot > .wrap{position:relative; z-index:1}
/* GRADE, nao flex. A marca fica numa coluna propria e as listas dividem o resto
   em quatro; com flex + wrap as colunas mudavam de largura conforme o texto de
   cada uma e a leitura vertical se perdia.
   `minmax(0,...)` nas duas faixas: sem ele, um titulo longo ("Financeiro e
   Suprimentos") force o minimo auto da coluna e ESTOURA a grade em vez de
   quebrar a linha. */
.foot__in{display:grid; grid-template-columns:minmax(230px,1fr) minmax(0,2.7fr); gap:48px}
.foot .logo{font-size:26px}
.foot__links{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:34px 28px}
/* TITULO DE GRUPO — no tipo do corpo, maior e mais pesado que os links.
   Era mono, caixa alta e 10,5px: um rotulo discreto, que e o certo dentro do
   mega-menu (poucos itens, contexto ja dado) e o errado aqui, onde ele precisa
   dividir 24 links em blocos que se enxergam de longe. */
.foot__col h4{font-family:var(--f-body); font-size:15px; font-weight:700; letter-spacing:-.01em; color:var(--ink); margin-bottom:16px}
/* Duas listas na mesma coluna (Captura + Projeto e BIM). Sem o respiro, o
   segundo titulo cola no ultimo link do grupo de cima e os dois viram um so. */
.foot__col a+h4{margin-top:30px}
/* LINK DA LISTA — branco puxado um pouco para o cinza. O titulo do grupo fica
   com o branco cheio: e essa diferenca, somada ao peso, que separa titulo de
   item numa coluna onde os dois estao um debaixo do outro.
   A primeira linha e o valor de reserva para quem nao tem color-mix; ali o
   link cai no cinza padrao do site em vez de perder a cor. */
.foot__col a{display:block; color:var(--mut); color:color-mix(in srgb, var(--ink) 75%, var(--mut)); font-size:14px; margin-bottom:10px; transition:color .2s}
.foot__col a:hover{color:var(--acc2)}

/* FAIXA DE BAIXO — redes a esquerda, copyright ao lado, documentos a direita.
   O `margin-left:auto` no bloco dos documentos e o que joga os dois grupos para
   as pontas; com `justify-content:space-between` os tres blocos se espalhariam
   com vaos desiguais assim que a linha quebrasse no celular. */
.foot__bot{margin-top:52px; padding-top:26px; display:flex; align-items:center; gap:14px 26px; flex-wrap:wrap; color:var(--ink); font-size:13.5px; font-family:var(--f-body)}
/* A faixa inteira saiu do mono. Era o tipo de maquina de escrever que o site
   usa em rotulo e legenda — certo para "01 / 04" ou "PRECISAO +-4mm", errado
   para quatro nomes de documento e a linha de copyright, que sao texto para
   ler, nao dado tecnico. */
/* Alvo de 34px: o icone tem 17, o resto e area de clique — no celular um alvo
   do tamanho do desenho nao se acerta com o polegar. */
/* As redes sobem para junto da marca. No rodape a assinatura e a lista de
   perfis dizem a mesma coisa — quem procura o Instagram olha onde esta o
   logo, nao no fim da pagina, e la embaixo elas dividiam a faixa com o
   copyright e quatro nomes de documento. */
.foot__soc{display:flex; align-items:center; gap:6px; margin:16px 0 0 -8px}
.foot__soc a{display:grid; place-items:center; width:34px; height:34px; color:var(--ink); transition:color .2s, background .2s}
.foot__soc a:hover{color:var(--acc2); background:var(--surface2)}
.foot__soc svg{width:17px; height:17px}
.foot__legal{display:flex; gap:22px; flex-wrap:wrap; margin-left:auto}
/* Sublinhado permanente: sao os links que alguem PROCURA (privacidade, termos).
   Em mono, no mesmo cinza do copyright ao lado, sem o sublinhado eles se
   confundiriam com texto corrido. */
.foot__legal a{color:var(--mut); color:color-mix(in srgb, var(--ink) 75%, var(--mut)); text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:4px; transition:color .2s, text-decoration-color .2s}
.foot__legal a:hover{color:var(--acc2); text-decoration-color:currentColor}

/* SO A BARRA. Ela carrega 5 links + idioma + 3 acoes e precisa de 1096px;
   os grids do corpo aguentam ate 980, entao os dois pontos sao separados. */
@media(max-width:1140px){
  /* A marca sai de ao lado das listas e vai para cima delas: abaixo daqui as
     quatro colunas precisam da largura inteira para nao virarem uma pilha. */
  .foot__in{grid-template-columns:1fr; gap:38px}
  .nav__links{display:none}
  .nav__right{display:none}
  .burger{display:flex}
  /* MENU DO CELULAR — so navegacao, encostada na direita.
     Nao tem botao de acao: "Entrar" e "Testar a plataforma" saem daqui e ficam
     na barra do desktop, onde ha espaco para eles pesarem. O que sobra e a
     lista, com os subitens de cada secao logo abaixo dela: no celular o painel
     do mega-menu e display:none, e sem esses subitens as doze paginas de
     servico nao teriam por onde ser alcancadas.
     A direita e onde o polegar esta e onde ja estao o hamburguer e o globo; a
     lista encostada nela le como uma coluna so, em vez de duas margens soltas.
     A rolagem propria e obrigatoria: com o submenu de servicos aberto, os doze
     itens passam da altura da tela. */
  /* A TELA INTEIRA, nao uma aba pendurada na barra. Sem os filetes, um painel
     de altura parcial terminaria num corte seco de cor por cima do hero — e a
     borda que segurava aquilo era justamente uma das linhas que sairam.
     `100svh` e nao `100vh`: no celular a barra de endereco entra e sai, e o vh
     grande deixaria o fim da lista embaixo dela. */
  /* `margin-left:0` NAO e enfeite: .nav__links carrega 14px de margem para
     afastar os links do logotipo na barra do desktop, e caixa posicionada com
     left E right junto continua honrando margem — o painel nascia 14px curto
     na esquerda, deixando uma fresta do hero aparecendo.
     A altura vai duas vezes de proposito: o `svh` e o valor certo (no celular
     a barra de endereco entra e sai, e o vh grande jogaria o fim da lista
     embaixo dela), mas navegador que nao conhece a unidade descarta a linha
     inteira do calc e ficaria com a altura do conteudo. O `vh` acima segura
     esse caso. */
  .nav.is-open .nav__links{display:flex; position:absolute; top:var(--nav-h); left:0; right:0; margin-left:0; flex-direction:column; gap:0; background:var(--bg); padding:14px 40px 34px; text-align:right; height:calc(100vh - var(--nav-h)); height:calc(100svh - var(--nav-h)); overflow-y:auto; overscroll-behavior:contain}
  /* A barra de rolagem do painel fica ESCONDIDA — o painel rola do mesmo jeito.
     Ela so aparecia ao abrir um grupo, entao piscava na tela como se fosse
     parte do menu, bem no canto onde os itens estao encostados.
     O aviso la do alto da folha (declarar `scrollbar-width` faz o Chromium
     ignorar os pseudo-elementos ::-webkit-scrollbar) nao morde aqui: la as duas
     APIs PINTAM a barra e brigariam pelo resultado; aqui as duas mandam sumir,
     entao qualquer navegador chega no mesmo lugar por um caminho ou pelo outro. */
  .nav.is-open .nav__links{scrollbar-width:none}
  .nav.is-open .nav__links::-webkit-scrollbar{width:0; height:0}
  /* Sem filete, quem separa uma linha da outra e o espaco, e o corpo maior:
     numa tela inteira os 16px de antes ficariam perdidos no alto da pagina. */
  .nav.is-open .nav__links > a{display:flex; align-items:center; justify-content:flex-end; gap:11px; padding:13px 0; font-size:20px; cursor:pointer}
  /* A seta e um quadrado com dois lados, virado 45 graus: nenhum arquivo a
     carregar, e ela herda a cor do tema junto com o resto da barra. */
  .nav__links > a.tem-sub::after{content:""; flex:none; width:6px; height:6px; margin-bottom:3px; border-right:1.5px solid var(--mut2); border-bottom:1.5px solid var(--mut2); transform:rotate(45deg); transition:transform .22s, border-color .2s}
  .nav__links > a.tem-sub.is-aberto{color:var(--acc2)}
  .nav__links > a.tem-sub.is-aberto::after{transform:rotate(-135deg); margin-bottom:-2px; border-color:var(--acc2)}
  .nav__sub.is-aberto{display:flex; flex-direction:column; padding:6px 0 18px}
  /* Os idiomas sao <button> (precisam ser: quem os escuta e o troca-idiomas),
     e os outros subitens sao <a>. Aqui os dois tem de ler como a mesma coisa,
     entao o botao devolve tudo que o navegador poe nele por conta propria. */
  .nav__sub button{width:100%; background:transparent; border:0; font-family:inherit; cursor:pointer}
  .nav__sub button.is-active{color:var(--acc2)}
  /* Os rotulos chegam dentro de um <b>, que e como o mega-menu os marca. Ali o
     negrito separa o titulo da linha de apoio abaixo; aqui nao ha linha de
     apoio, e o negrito so deixava o filho mais pesado que o pai.
     O recuo a direita e a largura da coluna da setinha (6px + 10px de folga):
     sem ele os subitens avancavam para fora do eixo dos pais, e a lista perdia
     a unica borda que a mantem lendo como uma coluna so. */
  .nav__sub a,.nav__sub button{display:block; padding:9px 17px 9px 0; font-size:15px; color:var(--mut); text-align:right; line-height:1.3}
  .nav__sub a b{font-weight:400}
  .nav__sub a:hover,.nav__sub a:active,.nav__sub button:hover{color:var(--acc2)}
  /* O hamburguer vira X enquanto o menu esta aberto: com a lista ocupando a
     tela, ele passa a ser o unico jeito visivel de fechar. */
  .burger span{transition:transform .22s, opacity .15s}
  .nav.is-open .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .nav.is-open .burger span:nth-child(2){opacity:0}
  .nav.is-open .burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}
@media(max-width:980px){
  .foot__links{grid-template-columns:repeat(2,minmax(0,1fr)); gap:30px 24px}
  .prow{grid-template-columns:1fr; gap:26px}
  .prow:nth-child(even) .prow__txt{order:0}
  .screens{grid-template-columns:minmax(0,1fr)}
  .ben{grid-template-columns:1fr; gap:0}
  .intg{grid-template-columns:repeat(2,1fr)}
  .devs{grid-template-columns:repeat(2,1fr)}
  .dev__img{height:250px}
  .screens{padding:16px; gap:16px}
  .own__appnote{display:flex; max-width:520px}
  .hero__scroll{display:none}
  .hero__metric{display:none}
}
@media(max-width:600px){
  .wrap,.nav__in,.hero__in,.cta__in{padding-left:22px; padding-right:22px}
  /* O painel aberto mantinha 40px de recuo enquanto a barra caia para 22 — e os
     dois botoes lado a lado so cabiam ate ~485px de viewport (mediram 195+195+16
     num util de 405). Num celular de 390 estouravam: .btn tem white-space:nowrap,
     entao `flex:1` nao consegue encolher abaixo do texto. Empilhados, cabem em
     qualquer largura. */
  .nav.is-open .nav__links{padding-left:22px; padding-right:22px}
  /* RODAPE NUMA COLUNA SO, tudo listado.
     Duas colunas aqui davam ~161px de util cada (346 da .wrap menos a calha), e
     nessa largura "Coordenacao e Compatibilizacao" quebrava em tres linhas: as
     duas colunas ficavam com alturas diferentes e a leitura virava ziguezague.
     Numa coluna o mapa do site le como uma lista, que e o que ele e.
     Os links trocam margem por padding: a margem so empurrava o vizinho, o
     padding entra na area de toque — 14px de texto com 10px de margem davam um
     alvo de ~30px, abaixo dos 44 que o dedo pede. */
  .foot__links{grid-template-columns:1fr; gap:24px}
  .foot__col h4{margin-bottom:4px}
  .foot__col a{font-size:15px; margin-bottom:0; padding:9px 0}
  .foot__col a+h4{margin-top:18px}
  .form .row{grid-template-columns:1fr}
  /* Os 40px de dentro do cartao sobram num util de ~346px (390 menos os 22 de
     cada lado da .cta__in): sobrariam 266px para o campo. */
  .cta__card{padding:26px 22px}
  .cmp__feat small{display:none}
  .cmp__r{grid-template-columns:1.2fr .9fr .9fr; font-size:13px}
  .cmp__r > *{padding:14px 12px}
  .cmp__r.head > *{padding-top:0; padding-bottom:11px}
  .cmp__val{font-size:13px}
  .sec,.own,.cta{padding:72px 0}
  .foot{padding:52px 0 30px}
  /* A marca vira uma linha: assinatura na esquerda, perfis encostados na
     direita. E o mesmo eixo do logo, que e onde o olho ja esta — e a direita
     e onde o polegar chega. */
  .foot__marca{display:flex; align-items:center; justify-content:space-between; gap:16px}
  .foot__soc{margin:0 -8px 0 0}
  /* Documentos empilhados e o copyright por ultimo. Em linha, "Politica de
     Privacidade" e "Termos de Uso e Servico" quebravam em duas linhas cada e
     a faixa virava um bloco de texto sublinhado sem comeco nem fim. Empilhados
     cada documento e uma linha, que e o que eles sao.
     O copyright desce pelo `order`: ele fecha o rodape, nao abre a lista de
     documentos. */
  .foot__bot{flex-direction:column; align-items:flex-start; gap:20px}
  .foot__legal{flex-direction:column; gap:13px; margin-left:0; order:1}
  .foot__bot > span{order:2}
}
@media(max-width:460px){
  /* AS SETAS E AS ACOES SAEM DA BARRA DA JANELA. Elas sao enfeite funcional —
     ja nascem `aria-hidden` porque nao fazem nada — e custam 48px de largura
     mais 14 de calha. Nessa faixa a pilula da URL nao cabia no que sobrava:
     centralizada com `overflow:hidden`, ela era cortada NOS DOIS LADOS e
     "vdcity.io/nuvem-de-pontos" aparecia sem o cadeado e sem o recarregar,
     com o dominio comido pela esquerda. Sem o enfeite, a URL inteira cabe —
     e o que a barra precisa dizer e justamente ela.
     Com os enfeites menores o corte so comecaria abaixo de ~350px de viewport
     (a pilula pede ~139px), contra os ~402 de quando eles eram maiores. O
     ponto continua em 460: e a largura que cobre todo celular com folga, e
     antecipar o corte nunca custou nada — o que sai daqui e enfeite. */
  .scr__nav,.scr__acoes{display:none}
  .devs{grid-template-columns:1fr}
  .dev__img{height:200px}
  .dev figcaption b{font-size:14.5px}
  .hero h1{font-size:38px}
  .own__appnote{font-size:13.5px; padding:12px 16px}
  .cmp__r{grid-template-columns:1.1fr .95fr .95fr; font-size:12px}
  .cmp__r > *{padding:12px 9px}
  .cmp__val{font-size:12px; gap:6px}
  .cmp__feat{font-size:13.5px}
}


/* SOBRE NOS ------------------------------------------------------------------
   Quatro blocos numa secao so (#institucional, #time, #parceiros, #trabalhe),
   porque e assim que o mega-menu de "Sobre nos" ja aponta: cada item de la e
   uma ancora aqui, nao uma pagina. Os slots seguem o padrao do resto do site —
   [COLCHETES] para o texto que depende de dado da empresa, como nas paginas
   legais, e a caixa .media "SOLTE AQUI" para a imagem que falta. */
.sobre__intro{display:grid; grid-template-columns:1fr 1fr; gap:54px; align-items:center}
.sobre__intro .media{aspect-ratio:4/3; border-radius:var(--r); border:1px solid var(--line)}
.sobre__txt{max-width:46ch}
.sobre__txt h3{font-size:clamp(26px,2.8vw,38px); font-weight:500; margin-bottom:16px}
.sobre__txt p{color:var(--mut); font-size:17px; margin-bottom:14px}
/* Sem filete acima: o espaco ja separa os numeros do texto, e a linha os
   fechava numa caixa a parte quando eles sao a continuacao do que foi dito.
   Os 54px sao os 30 de margem mais os 24 que o filete deixava de folga —
   tirar a linha nao era motivo para aproximar o bloco. */
/* TRES COLUNAS DIMENSIONADAS PELO CONTEUDO, nao em tercos iguais. O `1fr` e
   `minmax(auto,1fr)`, e esse `auto` e justamente o que faz a fileira caber: a
   coluna de texto tem 397px, entao tercos iguais dariam 119px por celula e
   "+300.000" mede 128 — em tercos iguais o numero nao caberia NEM no desktop.
   Com o piso de min-content cada coluna pega a largura que o seu conteudo pede
   (115/155/86 na medicao) e sobra folga. Trocar por `minmax(0,1fr)` aqui parece
   consertar e quebra: as celulas viram tercos e os numeros se atropelam.
   O preco do piso e que ele nao encolhe: os tres somam 315px e param de caber
   abaixo de ~360px de viewport — e por isso que o celular estreito tem regra
   propria la embaixo, em vez de a base mudar. O `break-word` no rotulo fecha a
   porta pelo outro lado: sem ele uma palavra maior que a celula empurraria a
   largura por dentro. */
.sobre__nums{display:grid; grid-template-columns:repeat(3,1fr); gap:20px; margin-top:54px}
.sobre__nums b{display:block; font-family:var(--f-disp); font-size:30px; font-weight:600; color:var(--acc2); line-height:1}
.sobre__nums span{display:block; font-family:var(--f-mono); font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--mut2); margin-top:7px; line-height:1.45; overflow-wrap:break-word}

.sobre__pil{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0 32px; margin:-18px 0 80px}
.sobre__pil > div{border-top:1px solid var(--line); padding-top:22px}
.sobre__pil h3{font-size:17px; font-weight:600; margin-bottom:8px}
.sobre__pil p{color:var(--mut); font-size:15px}
@media(max-width:900px){ .sobre__pil{grid-template-columns:repeat(2,minmax(0,1fr)); gap:28px 24px; margin:-24px 0 56px} }
@media(max-width:460px){ .sobre__pil{grid-template-columns:minmax(0,1fr)} }

.sobre__bloco{margin-top:92px}
.sobre__bloco > h3{font-size:clamp(22px,2.2vw,30px); font-weight:500; margin-bottom:12px}
.sobre__bloco > p{color:var(--mut); font-size:16px; max-width:62ch; margin-bottom:34px}

/* Duas pessoas, nao uma fileira: sem o teto de largura o auto-fit esticaria os
   dois cartoes por toda a .wrap e, como o retrato e 1:1, cada um viraria um
   quadrado de meio metro de tela. O max-width prende a dupla no tamanho que
   ela teria numa fileira de quatro, alinhada a esquerda como o resto do bloco. */
/* UM CARTAO POR PESSOA, e os dois espelhados. Lado a lado em duas colunas
   eles liam como uma tabela de duas celulas e nao sobrava largura para
   texto nenhum; empilhados e com o retrato trocando de lado, cada um ganha
   um lado da pagina — e a bio cabe. */
.time{display:grid; gap:18px}
.time__p{display:grid; grid-template-columns:210px minmax(0,1fr); gap:30px; align-items:center;
  border:1px solid var(--line); border-radius:var(--r); background:var(--surface); padding:24px 28px}
/* O ESPELHO E POR GRID, nao por `order` nem por `direction`: cravando linha e
   coluna dos dois filhos, a ordem no HTML continua sendo a de leitura (retrato,
   depois nome) — que e a que o leitor de tela segue. */
.time__p--dir{grid-template-columns:minmax(0,1fr) 210px}
.time__p--dir .media{grid-column:2; grid-row:1}
.time__p--dir .time__txt{grid-column:1; grid-row:1; text-align:right}
.time__p .media{aspect-ratio:1/1; border-radius:var(--r-s); border:1px solid var(--line)}
/* O rotulo de slot foi desenhado para moldura larga (16:10); no retrato
   quadrado ele nao cabe e a segunda linha era cortada fora da caixa. */
.time__p .media__tag{max-width:92%; padding:10px 12px; font-size:10.5px; line-height:1.5}
.time__p .media__tag b{font-size:9.5px; letter-spacing:.14em; margin-bottom:5px}
.time__p b{display:block; font-size:19px; font-weight:600; letter-spacing:-.01em}
.time__p span{display:block; font-family:var(--f-mono); font-size:11.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--mut2); margin-top:5px}
.time__bio{color:var(--mut); font-size:15px; line-height:1.65; margin-top:14px; max-width:56ch}
.time__p--dir .time__bio{margin-left:auto}
/* TEXTO QUE AINDA NAO EXISTE — mesmo acordo dos [colchetes] das paginas de
   /legal/: enquanto estiver assim na tela, a peca esta pendente. Em mono e no
   azul da marca para ninguem publicar sem ver. */
.falta{font-family:var(--f-mono); font-size:13px; line-height:1.6; color:var(--acc2);
  border-bottom:1px dashed var(--line2)}

/* Os parceiros entram como logotipo, entao a caixa e clara e larga (16:7) —
   um retrato quadrado como o do time espremeria a marca. */
/* A FAIXA CINZA de parceiros + vagas. Mesmo tom da CTA e do bloco de ROI —
   o site tem um unico cinza de faixa, e inventar um segundo seria mais uma
   cor para manter. Os filetes em cima e embaixo fecham a faixa contra as
   secoes brancas vizinhas. */
.volta{background:var(--bg2); border-top:1px solid var(--line); border-bottom:1px solid var(--line)}
/* O bloco abre a secao agora: o respiro de 92px que o separava do vizinho
   virou o proprio padding da secao, e mante-lo dobraria o vao. */
.volta .sobre__bloco,.volta .vagas:first-child{margin-top:0}
/* O cartao de vagas em --surface sobre o cinza: e o mesmo contraste que o
   .cta__card do formulario usa, e e o que o tira do fundo agora que o fundo
   deixou de ser branco. */
.parc{display:grid; grid-template-columns:repeat(4,1fr); gap:16px}
.parc__i{border:1px dashed var(--line2); border-radius:var(--r-s); background:var(--surface); aspect-ratio:16/7; display:grid; place-items:center; text-align:center; padding:10px; font-family:var(--f-mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--mut2); line-height:1.7; position:relative}

.vagas{margin-top:92px; border:1px solid var(--line); border-radius:var(--r); background:var(--surface); padding:36px 40px; display:grid; grid-template-columns:1fr auto; gap:30px; align-items:center}
.vagas h3{font-size:22px; font-weight:600; margin-bottom:8px}
.vagas p{color:var(--mut); font-size:15.5px; max-width:58ch}

/* MIDIA ----------------------------------------------------------------------
   Seis cartoes, um por tipo de conteudo, cada um com o id que o mega-menu de
   "Midia" ja chama. O scroll-margin-top e o que impede a barra fixa de cobrir
   o cartao quando se chega nele por ancora. */
.mid{display:grid; grid-template-columns:repeat(3,1fr); gap:16px}
.mid__i{border:1px solid var(--line); border-radius:var(--r-s); background:linear-gradient(180deg,var(--surface),var(--bg)); padding:28px 24px 26px; scroll-margin-top:110px; transition:transform .3s cubic-bezier(.2,.8,.2,1), border-color .3s}
.mid__i:hover{transform:translateY(-4px); border-color:var(--line2)}
.mid__i svg{width:26px; height:26px; color:var(--acc2); margin-bottom:16px}
.mid__i h3{font-size:18px; font-weight:600; margin-bottom:8px}
.mid__i p{color:var(--mut); font-size:14.5px; line-height:1.6}
.mid__tag{display:inline-block; margin-top:16px; font-family:var(--f-mono); font-size:10px; letter-spacing:.2em; text-transform:uppercase; color:var(--acc2)}

@media(max-width:900px){
  .sobre__intro{grid-template-columns:minmax(0,1fr); gap:34px}
  .sobre__bloco,.vagas{margin-top:62px}
  .volta .sobre__bloco{margin-top:0}
  .parc{grid-template-columns:repeat(2,1fr)}
  /* O retrato sobe para cima do texto: em 900px a coluna de 190px deixaria
     ao texto uma medida em que a bio quebra a cada tres palavras. E o espelho
     perde o sentido sem as duas colunas, entao os dois cartoes voltam a ler
     igual, alinhados a esquerda. */
  .time__p,.time__p--dir{grid-template-columns:minmax(0,1fr); gap:20px; justify-items:start}
  .time__p--dir .media,.time__p--dir .time__txt{grid-column:1; grid-row:auto}
  .time__p--dir .time__txt{text-align:left}
  .time__p--dir .time__bio{margin-left:0}
  .time__p .media{width:168px}
  .vagas{grid-template-columns:1fr; padding:30px 24px}
  .mid{grid-template-columns:1fr}
}

/* Depois da secao SOBRE NOS de proposito: as regras de .sobre__* nascem abaixo
   dos blocos responsivos la de cima, e uma media query com a mesma
   especificidade que viesse antes delas perderia por ordem de folha. */
@media(max-width:460px){
  /* DUAS COLUNAS, nao tres. Os pisos de min-content dos tres somam 315px + calhas
     e param de caber abaixo de ~360px de viewport — a 320 a secao vazava para
     fora da tela e abria uma faixa preta na lateral da pagina. E mesmo onde os
     tres cabiam, cabiam apertados: a 390px as colunas ficavam com 115 e 86px e
     "obras acompanhadas" e "empresas usando" quebravam em duas linhas cada, com
     alturas diferentes. Em duas colunas os rotulos voltam a uma linha so.
     O numero cede 4px junto: a 320 a celula fica com 128px, que e exatamente a
     medida de "+300.000" aos 30px — sem folga nenhuma para outra fonte de
     sistema medir um fio a mais. Aos 26px ele pede 111 e sobra margem. */
  .sobre__nums{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sobre__nums b{font-size:26px}
}


/* ============================================================ SERVICOS
   CARROSSEL, nao grade. Doze cartoes em grade seriam a peca mais alta da home
   (quatro linhas de tres) e empurrariam a calculadora, o "sobre" e o contato
   para fora do alcance de quem so rola. Deitado, o bloco custa a altura de UM
   cartao e os doze continuam a um arraste — o mesmo acordo do mapa do rodape.
   A pista e uma rolagem nativa com scroll-snap: e o navegador quem anima, quem
   trata o toque e quem respeita o "menos animacao" do sistema. O JS (initCarr
   em common.js) so faz o que o CSS nao consegue — as setas e a barra. */
/* O cabecalho abre para as setas ficarem na MESMA linha do titulo, a direita:
   sobre os cartoes elas cobririam justamente a figura do primeiro e do ultimo.
   `max-width:none` porque .sec__head trava em 62ch; o limite volta so no bloco
   de texto, de onde nunca deveria ter saido. */
.carr__head{display:flex; align-items:flex-end; justify-content:space-between; gap:32px; max-width:none}
.carr__head > div{max-width:62ch; min-width:0}
.carr__nav{display:flex; gap:8px; flex:none; padding-bottom:6px}
/* Contorno, no mesmo tom do .btn--outline da barra: a seta e controle, nao
   chamada. Ligada ela vira o botao primario (tinta cheia); desligada some pela
   metade em vez de sumir de vez — o par fica no lugar e ninguem procura a
   segunda seta quando esta na ponta da pista. */
.carr__b{width:46px; height:46px; display:grid; place-items:center; background:transparent; border:1px solid var(--line2); color:var(--ink); cursor:pointer; transition:background .2s, color .2s, border-color .2s, opacity .2s}
.carr__b svg{width:18px; height:18px}
.carr__b:hover{background:var(--ink); color:var(--bg); border-color:var(--ink)}
.carr__b:disabled{opacity:.3; cursor:default; background:transparent; color:var(--ink); border-color:var(--line2)}
/* UMA FILA, DE BORDA A BORDA. A .carr esta FORA da .wrap no HTML — e por
   isso que ela chega as duas beiradas da tela. Carrossel que para nos 1280px
   do container le como grade cortada; de borda a borda, le como fita.
   O vinheta nas pontas (mask) diz que a fita CONTINUA em vez de terminar
   cortada no meio de um cartao; sem ela o primeiro e o ultimo visiveis
   pareciam quebrados contra a borda da janela. */
.carr{position:relative; display:grid; gap:22px;
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%)}
/* Tres cartoes por tela, medidos pelo proprio trilho (100% menos duas calhas,
   dividido por tres): a largura vem do container, nao de um numero em px que
   descolaria da .wrap em qualquer viewport que nao a de quem escreveu.
   A barra de rolagem nativa sai (scrollbar-width / ::-webkit-scrollbar): o
   filete cinza embaixo de doze cartoes diria "isto e uma janela de sistema",
   e a fita anda sozinha — nao ha posicao a informar num laco infinito.
   SEM scroll-snap: o encaixe existe para slides, e aqui o movimento e
   continuo; o imã puxaria a fita de volta a cada quadro do rAF.
   `scroll-behavior:smooth` fica para as SETAS — o JS o desliga durante os
   saltos do laco e durante o arrasto. */
/* Cartao em `clamp`: cresce com a janela ate um teto, em vez de dividir a
   largura em tres — de borda a borda, "um terco" numa tela larga daria um
   cartao de 600px e a fita perderia a escala de peca colecionavel.
   Mais estreito desde que o cartao virou titulo + figura + botao: a altura de
   uma fila acompanha a largura (a figura e 16/9), e sao DUAS filas — cada
   pixel de largura economizado vale o dobro na altura da secao. */
.carr__pista{display:grid; grid-auto-flow:column; grid-auto-columns:clamp(270px,26vw,420px); gap:22px; overflow-x:auto; scroll-behavior:smooth; padding:0 22px 6px; scrollbar-width:none; -webkit-overflow-scrolling:touch; overscroll-behavior-x:contain; cursor:grab; touch-action:pan-x}
.carr__pista::-webkit-scrollbar{display:none}
@media(prefers-reduced-motion:reduce){ .carr__pista{scroll-behavior:auto} }
/* Arrastando: a mao fecha e o texto para de selecionar. O `user-select` so
   entra aqui, no gesto — fora dele o conteudo do cartao continua copiavel. */
.carr__pista.is-drag{cursor:grabbing; user-select:none; -webkit-user-select:none; scroll-behavior:auto}
/* O CARTAO E A IMAGEM, e nada mais: a proporcao mora aqui e o resto flutua
   por cima. Sem faixa de titulo e sem faixa de botao, a altura de uma fila
   passa a ser so a da figura — e sao duas filas. */
.carr__c{position:relative; display:block; min-width:0; aspect-ratio:16/10; overflow:hidden; background:var(--surface); border:1px solid var(--line); color:var(--ink); transition:border-color .3s, transform .3s cubic-bezier(.2,.8,.2,1)}
.carr__c:hover{border-color:var(--line2); transform:translateY(-4px)}
/* O CARTAO INTEIRO SAI DO ARRASTO NATIVO. O <a> oferece o proprio link e a
   figura oferece a imagem; nos dois casos o navegador assume o gesto e a fita
   para de seguir o cursor. O JS ainda chama preventDefault no `dragstart` —
   esta propriedade e prefixada e o Firefox nao a tem. */
.carr__c{-webkit-user-drag:none}
.carr__c img,.carr__c svg{-webkit-user-drag:none; pointer-events:none}
/* A figura e um SLOT enquanto a foto nao existe: o icone do modulo sobre a
   textura escura de .media segura a composicao, e o rotulo tracejado no canto
   diz "a produzir" na mesma convencao do resto do site (ver .media__tag).
   Com a foto, o <span class="carr__fig media"> vira <span class="carr__fig">
   com um <img> dentro — position/aspect/overflow moram AQUI e nao no .media
   justamente para a troca nao precisar de CSS novo. */
/* A figura preenche o cartao inteiro; titulo e botao sao filhos dela porque e
   o .media que redeclara os tokens escuros — dentro dele `var(--ink)` ja e o
   branco que o texto precisa sobre a foto, sem cravar cor nenhuma. */
.carr__fig{position:absolute; inset:0; display:grid; place-items:center}
.carr__fig > svg{width:40px; height:40px; color:var(--acc2)}
/* O VEU E O QUE TORNA A SOBREPOSICAO SEGURA. Hoje o fundo e a textura escura
   do slot e o texto se leria sem ele; com a foto real, branco sobre ceu claro
   ou sobre concreto some. Escuro nas duas pontas (onde o texto esta) e quase
   limpo no meio (onde a imagem trabalha). */
.carr__fig::after{content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(5,7,12,.78) 0, rgba(5,7,12,.12) 34%, rgba(5,7,12,.2) 58%, rgba(5,7,12,.86) 100%)}
.carr__c h3{position:absolute; z-index:2; left:15px; right:15px; top:13px; font-size:16px; font-weight:600; line-height:1.28; letter-spacing:-.01em; color:var(--ink)}
.carr__fig img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block}
.carr__slot{position:absolute; z-index:2; right:12px; top:12px; font-family:var(--f-mono); font-size:9.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--mut2); border:1px dashed var(--line2); padding:4px 7px; white-space:nowrap}
/* O "botao" e um <span>: o cartao INTEIRO ja e o <a>, e link dentro de link e
   HTML invalido. Ele existe para dizer que o cartao abre uma pagina.
   No canto de baixo, sobre o veu: o contorno claro se sustenta tanto sobre a
   textura de hoje quanto sobre a foto de amanha. Preenche no hover do CARTAO,
   nao no proprio — quem passa o mouse esta mirando o cartao todo. */
.carr__mais{position:absolute; z-index:2; left:15px; bottom:13px; display:inline-flex; align-items:center; gap:7px;
  border:1px solid var(--line2); padding:7px 13px; font-size:12.5px; font-weight:600; color:var(--ink);
  transition:background .22s, color .22s, border-color .22s}
.carr__mais svg{width:14px; height:14px; flex:none; transition:transform .25s cubic-bezier(.2,.8,.2,1)}
.carr__c:hover .carr__mais{background:var(--ink); color:var(--bg); border-color:var(--ink)}
.carr__c:hover .carr__mais svg{transform:translateX(3px)}

/* ============================================================ CALCULADORA
   PRIMITIVOS COMPARTILHADOS entre /calculadora.html e o teaser da home (#roi).
   Vieram do <style> da calculadora quando a home passou a ter as mesmas tres
   perguntas: rotulo, segmento de botoes, faixa do volume e o numero grande sao
   a mesma peca nas duas paginas e uma copia divergiria na primeira mexida. O
   que e so da calculadora (o cartao de duas colunas, os ajustes avancados, a
   quebra e a conta aberta) continua la, no ESTILO_CALC do gerador. */
.calc__campo{margin-bottom:26px}
.calc__rot{display:block; font-family:var(--f-mono); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--mut2); margin-bottom:10px}
/* Segmentos. Botao ligado usa a MESMA tinta do .btn--primary (var(--ink) com o
   texto em var(--bg)): a pagina ja tem um jeito de dizer "isto esta escolhido"
   e inventar um segundo seria so mais uma cor para manter. */
.calc__seg{display:grid; border:1px solid var(--line); background:var(--bg)}
.calc__seg--2{grid-template-columns:1fr 1fr}
.calc__seg--3{grid-template-columns:repeat(3,1fr)}
.calc__seg button{font-family:var(--f-body); font-size:13px; font-weight:600; line-height:1.3; color:var(--mut);
  background:transparent; border:0; padding:13px 9px; cursor:pointer; transition:background .2s, color .2s}
.calc__seg button:hover{color:var(--ink)}
.calc__seg button.is-on{background:var(--ink); color:var(--bg)}
.calc__seg--2 button:nth-child(2n){border-left:1px solid var(--line)}
.calc__seg--2 button:nth-child(n+3){border-top:1px solid var(--line)}
.calc__seg--3 button + button{border-left:1px solid var(--line)}
/* Volume anual. A bolha acompanha o polegar porque o valor e a informacao —
   ler "R$ 300 mi" na hora de arrastar evita ter de procurar o numero embaixo. */
.calc__faixa{position:relative; padding-top:36px}
.calc__bolha{position:absolute; top:0; transform:translateX(-50%); background:var(--ink); color:var(--bg);
  font-family:var(--f-mono); font-size:11.5px; letter-spacing:.04em; padding:5px 9px; white-space:nowrap}
.calc__bolha::after{content:""; position:absolute; left:50%; bottom:-4px; margin-left:-4px;
  border:4px solid transparent; border-top-color:var(--ink); border-bottom:0}
/* O trilho e o proprio fundo do input: um gradiente de duas paradas na posicao
   --p, que o JS atualiza. Dois elementos (trilho + preenchimento) dariam o mesmo
   resultado com mais DOM e um desalinhamento a cada navegador. */
.calc__range{-webkit-appearance:none; appearance:none; width:100%; height:4px; margin:0; cursor:pointer;
  background:linear-gradient(90deg, var(--ink) var(--p,38%), var(--line2) var(--p,38%)); outline:none}
.calc__range::-webkit-slider-thumb{-webkit-appearance:none; appearance:none; width:18px; height:18px;
  background:var(--ink); border:0; border-radius:0; cursor:grab}
.calc__range::-moz-range-thumb{width:18px; height:18px; background:var(--ink); border:0; border-radius:0; cursor:grab}
.calc__range::-moz-range-track{height:4px; background:transparent}
.calc__range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 3px var(--glow)}
.calc__range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 3px var(--glow)}
.calc__pontas{display:flex; justify-content:space-between; margin-top:11px; font-family:var(--f-mono); font-size:11px; color:var(--mut2)}
.calc__eyebrow{font-family:var(--f-mono); font-size:10.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--mut2)}
/* tabular-nums: sem isso o numero danca de largura enquanto conta, e a linha
   inteira treme a cada quadro da animacao. */
.calc__big{font-family:var(--f-disp); font-size:clamp(40px,5.4vw,70px); font-weight:600; letter-spacing:-.035em;
  line-height:1.02; margin-top:10px; font-variant-numeric:tabular-nums}
.calc__base{font-size:13px; color:var(--mut); line-height:1.5; margin-top:9px; min-height:39px}

/* ============================================================ ROI NA HOME
   Faixa cinza (--bg2), como a da CTA: entre o carrossel claro e o "sobre"
   claro, ela precisa de fundo proprio para ler como um bloco e nao como o
   terceiro paragrafo da secao de cima. Texto a esquerda, cartao a direita —
   o cartao e a mesma caixa branca com filete do formulario de contato. */
.roi{background:var(--bg2); border-top:1px solid var(--line); border-bottom:1px solid var(--line)}
.roi__in{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.05fr); gap:64px; align-items:center}
.roi__txt .kicker{display:block; margin-bottom:18px}
.roi__txt h2{font-size:clamp(30px,4vw,52px); font-weight:500; max-width:17ch}
.roi__txt .lead{margin-top:20px; max-width:52ch}
/* As tres frentes da conta, como lista de filetes: sao os mesmos tres nomes
   que a calculadora usa na quebra do resultado — quem ler aqui reconhece la. */
.roi__frentes{list-style:none; margin:34px 0 36px; border-top:1px solid var(--line)}
.roi__frentes li{display:grid; grid-template-columns:minmax(0,17ch) minmax(0,1fr); gap:4px 22px; padding:13px 0; border-bottom:1px solid var(--line); font-size:14.5px; line-height:1.5}
.roi__frentes b{font-weight:600; color:var(--ink)}
.roi__frentes span{color:var(--mut)}
.roi__card{background:var(--surface); border:1px solid var(--line); padding:34px}
/* O numero grande da calculadora e dimensionado para meia tela; aqui o cartao
   e mais estreito e o texto do lado precisa continuar respirando. */
.roi .calc__big{font-size:clamp(36px,4.2vw,56px)}
.roi__res{border-top:1px solid var(--line); margin-top:30px; padding-top:24px}
.roi__ver{display:inline-flex; align-items:center; gap:9px; margin-top:22px; font-size:14px; font-weight:600; color:var(--acc2); transition:gap .2s}
.roi__ver:hover{gap:14px}
.roi__ver svg{width:15px; height:15px; flex:none}
.roi__nota{font-size:11.5px; color:var(--mut2); line-height:1.6; margin-top:16px}

/* ============================================================ NOVIDADES
   Na coluna da marca, embaixo das redes — nao numa faixa de largura inteira.
   E o arranjo da referencia: titulo curto, o campo com o botao de enviar (so
   o icone) colado nele, uma linha dizendo o que chega e o link da politica.
   Compacto de proposito: no rodape isto e um convite, nao uma secao. */
.news{margin-top:30px; max-width:340px}
.news h4{font-family:var(--f-body); font-size:15px; font-weight:600; letter-spacing:-.01em; color:var(--ink); margin-bottom:12px}
/* Campo e botao com a mesma altura, lado a lado; a confirmacao entra como
   segunda faixa, na largura toda — mesmo arranjo do .form__row2 do contato. */
.news__form{display:grid; grid-template-columns:minmax(0,1fr) 44px; gap:8px}
.news__form input{width:100%; min-width:0; height:44px; font-family:var(--f-body); font-size:14.5px; line-height:1.4; color:var(--ink); background:var(--surface); border:1px solid var(--line2); border-radius:0; padding:0 14px; transition:border-color .18s, box-shadow .18s}
.news__form input::placeholder{color:var(--mut2)}
.news__form input:focus{outline:none; border-color:var(--acc2); box-shadow:inset 0 0 0 1px var(--acc2)}
/* So o icone, em cinza: e o unico botao da coluna e nao disputa com o
   "Testar a plataforma" da barra. Ao passar o mouse assume o azul da marca. */
.news__enviar{display:grid; place-items:center; width:44px; height:44px; background:var(--mut2); color:#fff; border:0; border-radius:0; cursor:pointer; transition:background .2s}
.news__enviar svg{width:18px; height:18px}
.news__enviar:hover{background:var(--acc)}
.news__enviar:disabled{opacity:.5; cursor:default}
.news__ok{grid-column:1/-1; display:none; align-items:center; gap:8px; font-size:13px; font-weight:600; color:var(--ink)}
.news__ok svg{color:var(--acc2); flex:none}
.news__ok.is-in{display:flex}
.news__txt{font-size:13px; color:var(--mut); line-height:1.55; margin-top:12px}
/* Sublinhado permanente, como os documentos da faixa de baixo: e link que
   alguem procura. */
.news__lgpd{display:inline-block; margin-top:4px; font-size:13px; color:var(--mut); text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:3px; transition:color .2s}
.news__lgpd:hover{color:var(--acc2)}

/* Responsivo dos tres blocos — depois deles de proposito, pelo mesmo motivo
   do bloco do SOBRE NOS: uma media query de mesma especificidade que viesse
   antes das regras perderia por ordem de folha. */
@media(max-width:980px){
  .roi__in{grid-template-columns:1fr; gap:44px}
  .roi__card{padding:26px 22px}
  .calc__seg button{font-size:12.5px; padding:12px 7px}
}
@media(max-width:600px){
  /* Um cartao e a beirada do proximo: essa fatia diz "tem mais" sem seta
     nenhuma. A vinheta encolhe junto, senao come meio cartao de cada lado. */
  .carr__pista{grid-auto-columns:74%}
  .carr{gap:14px; -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 26px, #000 calc(100% - 26px), transparent 100%);
    mask-image:linear-gradient(90deg, transparent 0, #000 26px, #000 calc(100% - 26px), transparent 100%)}
  .carr__head{flex-direction:column; align-items:flex-start; gap:18px}
  .carr__nav{padding-bottom:0}
  .roi__frentes li{grid-template-columns:1fr; gap:2px}
  .calc__seg--3 button{font-size:12px}
  /* No celular a marca vira uma linha (logo a esquerda, redes a direita —
     regra la em cima); o cadastro quebra para a linha de baixo, na largura
     toda, em vez de espremer os tres na mesma fileira. */
  .foot__marca{flex-wrap:wrap}
  .news{flex-basis:100%; max-width:none; margin-top:22px}
}
