﻿/* ==========================================================================
   APROXIMA — styles.css
   Paleta da marca: AMARELO, BRANCO e PRETO. Sem cor fora disso.
   Tipografia forte, blocos sólidos, muito branco. Nada de gradiente
   decorativo, glow, blob ou qualquer coisa com cara de "gerado".
   Mobile-first.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  /* Cores — extraídas do logotipo */
  --amarelo:      #FFE500;   /* amarelo principal (lado esquerdo da seta) */
  --ambar:        #FFC728;   /* amarelo secundário (lado direito da seta) */
  --preto:        #111111;   /* texto e blocos sólidos */
  --preto-2:      #3A3A3A;   /* contorno do símbolo; texto secundário */
  --cinza:        #6E6E6E;   /* texto de apoio */
  --linha:        #E2E2E2;   /* réguas e bordas */
  --branco:       #FFFFFF;
  --branco-2:     #F7F7F5;   /* fundo de bloco neutro */

  /* Tipografia — SUBSTITUIR pelas fontes licenciadas da marca (@font-face).
     A fonte do logotipo é uma grotesca geométrica leve. */
  --font-display: "Helvetica Neue", Inter, "Segoe UI", Arial, sans-serif;
  --font-text:    "Helvetica Neue", Inter, "Segoe UI", Arial, sans-serif;
  --font-mono:    ui-monospace, "SFMono-Regular", "Cascadia Mono", Consolas, monospace;

  /* Escala fluida */
  --fs-eyebrow: clamp(0.7rem, 0.66rem + 0.2vw, 0.8rem);
  --fs-body:    clamp(1rem, 0.96rem + 0.3vw, 1.1rem);
  --fs-lead:    clamp(1.1rem, 1rem + 0.6vw, 1.4rem);
  --fs-h3:      clamp(1.5rem, 1.2rem + 1.4vw, 2.4rem);
  --fs-h2:      clamp(1.9rem, 1.35rem + 2.5vw, 3.4rem);
  --fs-h1:      clamp(2.3rem, 1.5rem + 3.8vw, 4.8rem);

  /* Ritmo */
  /* A largura útil deixa uma calha livre dos dois lados: é por ela que o
     trajeto (linha + seta) corre sem cruzar texto. Se aumentar --wrap,
     revise os valores de data-trail-x no HTML. */
  --wrap:     min(88vw, 1180px);
  --space-s:  clamp(0.75rem, 2vw, 1.25rem);
  --space-m:  clamp(1.5rem, 4vw, 2.5rem);
  --space-l:  clamp(2.5rem, 7vw, 5rem);
  --space-xl: clamp(4rem, 11vw, 9rem);

  /* --header-h / --header-bar definidos logo abaixo do cabeçalho (com safe-area). */
  /* Altura do dock flutuante + respiro + safe area iOS. O dock é fixo e
     paira sobre a página; sem esta faixa ele cobre o texto legal do rodapé
     e, no iPhone, a home indicator. */
  --dock-safe: calc(64px + clamp(0.75rem, 2vw, 1.5rem) + 1rem + env(safe-area-inset-bottom, 0px));
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------------------
   2. RESET LEVE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  /* SEM scroll-behavior: smooth. O suave nativo gasta tempo proporcional à
     distância e esta página passa de 17.000px no celular — ir da hero ao
     contato levava segundos. Quem conduz a rolagem por âncora agora é o
     módulo Scroller do script.js, com duração fixa. O scroll-padding continua
     valendo para quem CHEGA na página já com #hash na URL. */
  scroll-padding-top: calc(var(--header-h) + 1rem);
}
body {
  margin: 0;
  background: var(--branco);
  color: var(--preto);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  line-height: 1.6;
  overflow-x: hidden;
}

/* --------------------------------------------------------------------------
   2.1 SCROLLBAR — barra lateral do sistema, no visual da marca
   -------------------------------------------------------------------------- */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--amarelo) var(--preto);
}
html::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
html::-webkit-scrollbar-track {
  background: var(--preto);
}
html::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--amarelo) 0%, var(--ambar) 100%);
  border: 2px solid var(--preto);
  border-radius: 2px;
  min-height: 48px;
}
html::-webkit-scrollbar-thumb:hover {
  background: var(--amarelo);
}
html::-webkit-scrollbar-corner {
  background: var(--preto);
}

img, svg, video { max-width: 100%; display: block; }
h1, h2, h3, h4 {
  font-family: var(--font-display); font-weight: 700;
  letter-spacing: -0.03em; line-height: 1.05; margin: 0; text-wrap: balance;
}
p { margin: 0 0 1em; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }
/* O realce precisa de entrelinha folgada, senão a caixa amarela de uma linha
   invade a linha de cima (a caixa do texto é mais alta que o line-height). */
mark { background: var(--amarelo); color: var(--preto); padding: 0 0.12em; }

:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--amarelo);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--preto);
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 0.5rem; top: -100px; z-index: 999;
  background: var(--preto); color: var(--amarelo); padding: 0.75rem 1rem;
  font-family: var(--font-display); font-weight: 600; font-size: 0.9rem;
}
.skip-link:focus { top: 0.5rem; }

.wrap { width: var(--wrap); margin-inline: auto; }

/* --------------------------------------------------------------------------
   3. CABEÇALHO
   -------------------------------------------------------------------------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  padding-top: env(safe-area-inset-top, 0px);
  background: color-mix(in srgb, var(--branco) 92%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}
/* Assim que a página sai do topo o cabeçalho fica opaco. Translúcido, o texto
   que passa por baixo vazava pelo fundo e os títulos apareciam cortados ao
   meio — especialmente no celular, onde o cabeçalho ocupa mais da tela. */
.site-header.is-stuck {
  border-bottom-color: var(--linha);
  background: var(--branco);
}
.site-header__inner {
  width: var(--wrap); margin-inline: auto; height: var(--header-bar, var(--header-h));
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.brand { display: inline-flex; align-items: center; min-height: 44px; }
.brand__logo { height: clamp(26px, 3.4vw, 34px); width: auto; }
.site-header__progress {
  height: 3px; width: 0%;
  background: var(--amarelo);
  transition: width 0.08s linear;
}

/* O cabeçalho carrega só a marca. A chamada principal vive no dock flutuante
   e no diagnóstico da seção 06.
   --header-bar = faixa da marca; --header-h = barra + safe-area (offsets). */
:root {
  --header-bar: 62px;
  --header-h: calc(var(--header-bar) + env(safe-area-inset-top, 0px));
}
@media (min-width: 900px) {
  :root {
    --header-bar: 76px;
    --header-h: calc(var(--header-bar) + env(safe-area-inset-top, 0px));
  }
}

/* --------------------------------------------------------------------------
   3.1 DOCK FLUTUANTE — navegação por seções
   --------------------------------------------------------------------------
   Porte do MagnificationDock. O tamanho de cada item é escrito pelo JS na
   variável --size, com mola; o CSS só reage. Em tela de toque o JS não mexe
   e fica a barra simples.
   -------------------------------------------------------------------------- */
.dock {
  position: fixed; left: 50%;
  bottom: calc(clamp(0.75rem, 2vw, 1.5rem) + env(safe-area-inset-bottom, 0px));
  z-index: 70;
  display: flex; align-items: flex-end; gap: clamp(0.3rem, 0.8vw, 0.6rem);
  height: 64px; padding: 0 clamp(0.5rem, 1.2vw, 0.9rem) 8px;
  background: color-mix(in srgb, var(--branco) 84%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 2px solid var(--preto); border-radius: 999px;
  box-shadow: 0 14px 40px rgba(17,17,17,0.18);
  transform: translateX(-50%) translateY(150%);
  opacity: 0; pointer-events: none;
  transition: transform 0.5s var(--ease), opacity 0.35s var(--ease);
}
.dock.is-visible { transform: translateX(-50%); opacity: 1; pointer-events: auto; }

.dock__item {
  --size: 46px;
  width: var(--size); height: var(--size);
  flex: none; position: relative;
  display: grid; place-items: center;
  border-radius: 999px; text-decoration: none; color: var(--preto);
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.dock__item svg { width: 46%; height: 46%; }
.dock__item:hover, .dock__item.is-current { background: var(--amarelo); }
.dock__item--cta { background: var(--preto); color: var(--branco); }
.dock__item--cta:hover { background: var(--amarelo); color: var(--preto); }

.dock__sep { width: 2px; height: 26px; background: var(--linha); flex: none; margin-inline: 0.2rem; align-self: center; }

.dock__label {
  position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(6px);
  background: var(--preto); color: var(--branco);
  font-family: var(--font-mono); font-size: 0.6rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.35rem 0.6rem; white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.dock__item:hover .dock__label,
.dock__item:focus-visible .dock__label { opacity: 1; transform: translateX(-50%); }

@media (max-width: 719px) {
  /* 44px é o mínimo de alvo de toque. 6 itens de 44 + vãos + respiro = 292px,
     ainda folgado num aparelho de 390px. */
  .dock { height: 60px; gap: 0.15rem; padding-bottom: 6px; }
  .dock__item { --size: 44px; }
  .dock__label { display: none; }
  .dock__sep { height: 22px; }
}

/* --------------------------------------------------------------------------
   3.2 CURSOR — blur amarelo redondo (só ponteiro fino / desktop)
   -------------------------------------------------------------------------- */
html.has-cursor,
html.has-cursor * {
  cursor: none !important;
}
html.has-cursor input,
html.has-cursor textarea,
html.has-cursor select,
html.has-cursor [contenteditable="true"] {
  cursor: text !important;
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10050;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-100px, -100px, 0);
  transition: opacity 0.25s var(--ease);
  will-change: transform;
}
.cursor.is-on { opacity: 1; }

.cursor__blob {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 50%,
    color-mix(in srgb, var(--amarelo) 85%, white) 0%,
    color-mix(in srgb, var(--amarelo) 55%, transparent) 45%,
    transparent 72%
  );
  filter: blur(6px);
  transform: scale(1);
  opacity: 0.9;
  transition: transform 0.2s var(--ease), opacity 0.2s var(--ease), filter 0.2s var(--ease);
}
.cursor__core {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--amarelo);
  border: 1.5px solid var(--preto);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ambar) 60%, transparent);
  transition: transform 0.18s var(--ease);
}

.cursor.is-hot .cursor__blob {
  transform: scale(1.45);
  opacity: 1;
  filter: blur(8px);
}
.cursor.is-hot .cursor__core {
  transform: scale(1.25);
}

.cursor.is-click .cursor__blob {
  transform: scale(0.72);
  opacity: 1;
  filter: blur(4px);
}
.cursor.is-click .cursor__core {
  transform: scale(0.7);
}

/* Ondas soltas no clique (elementos .cursor__wave) */
.cursor__wave {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--amarelo) 70%, transparent) 0%,
    transparent 70%
  );
  filter: blur(4px);
  pointer-events: none;
  animation: cursor-wave 0.55s var(--ease) forwards;
}
@keyframes cursor-wave {
  0%   { transform: scale(0.4); opacity: 0.85; }
  100% { transform: scale(3.4); opacity: 0; }
}

body.is-intro .cursor {
  opacity: 0 !important;
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .cursor { display: none !important; }
  html.has-cursor,
  html.has-cursor * { cursor: auto !important; }
}

/* --------------------------------------------------------------------------
   4. BOTÕES E MICRO-COMPONENTES
   -------------------------------------------------------------------------- */
.btn {
  /* min-height garante o alvo de toque de 44px mesmo nos botões pequenos */
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 44px;
  font-family: var(--font-display); font-weight: 700; font-size: 0.95rem;
  letter-spacing: -0.01em; text-decoration: none; cursor: pointer;
  padding: 0.9rem 1.6rem; border: 2px solid var(--preto); border-radius: 2px;
  background: transparent; color: var(--preto);
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.btn--solid  { background: var(--preto); color: var(--branco); }
.btn--solid:hover  { background: var(--amarelo); color: var(--preto); border-color: var(--amarelo); }
.btn--ghost:hover  { background: var(--amarelo); border-color: var(--preto); }
.btn--amarelo { background: var(--amarelo); border-color: var(--amarelo); color: var(--preto); }
.btn--amarelo:hover { background: var(--branco); border-color: var(--branco); }
.btn--on-dark { color: var(--branco); border-color: rgba(255,255,255,0.4); }
.btn--on-dark:hover { background: var(--branco); color: var(--preto); border-color: var(--branco); }

.eyebrow {
  font-family: var(--font-mono); font-size: var(--fs-eyebrow);
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--cinza); margin: 0 0 var(--space-s);
}
.eyebrow--light { color: rgba(255,255,255,0.6); }

/* --------------------------------------------------------------------------
   4.1 SWAP — troca de imagem no hover: CLIENTE → O QUE ENTREGAMOS
   --------------------------------------------------------------------------
   Estrutura:
     figure.swap[data-swap][tabindex=0]
       .swap__layer--front   → imagem do cliente / contexto (define a altura)
       .swap__layer--back    → imagem da entrega (aparece por cima)
       figcaption.swap__hint → etiqueta que muda de texto junto

   Aciona por hover, por foco de teclado e, em telas de toque, por toque
   (o script.js adiciona .is-open). Trocar cada .media-slot por:
     <img src="..." alt="..." loading="lazy" decoding="async">
   mantendo as classes swap__layer--front / swap__layer--back.
   -------------------------------------------------------------------------- */
.swap {
  position: relative; display: block; margin: 0;
  overflow: hidden; cursor: pointer;
  background: var(--branco-2);
  border: 2px solid transparent;
  transition: border-color 0.25s var(--ease);
}
.swap:hover, .swap:focus-visible, .swap.is-open { border-color: var(--preto); }

.swap__layer { display: block; }
.swap__layer > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.swap__layer--front { transition: transform 0.6s var(--ease); }
.swap__layer--back {
  position: absolute; inset: 0;
  opacity: 0; transform: scale(1.05);
  transition: opacity 0.35s var(--ease), transform 0.6s var(--ease);
}
.swap__layer--back > * { height: 100%; }

.swap:hover .swap__layer--front,
.swap:focus-visible .swap__layer--front,
.swap.is-open .swap__layer--front { transform: scale(1.05); }

.swap:hover .swap__layer--back,
.swap:focus-visible .swap__layer--back,
.swap.is-open .swap__layer--back { opacity: 1; transform: none; }

/* Etiqueta de estado */
.swap__hint {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  background: var(--preto); color: var(--branco);
  font-family: var(--font-mono); font-size: 0.6rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.4rem 0.7rem;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
}
.swap__hint-b { display: none; }
.swap:hover .swap__hint, .swap:focus-visible .swap__hint, .swap.is-open .swap__hint {
  background: var(--amarelo); color: var(--preto);
}
.swap:hover .swap__hint-a, .swap:focus-visible .swap__hint-a, .swap.is-open .swap__hint-a { display: none; }
.swap:hover .swap__hint-b, .swap:focus-visible .swap__hint-b, .swap.is-open .swap__hint-b { display: inline; }

/* Variante pequena (fotos de equipe): sem etiqueta */
.swap--sm .swap__hint { display: none; }

/* Em tela de toque a dica muda: não existe hover */
@media (hover: none) {
  .swap__hint-a::after { content: " · toque"; opacity: 0.6; }
}

/* --- MODO BLOB ------------------------------------------------------------
   O script.js liga .is-blob só onde há ponteiro fino e o usuário não pediu
   menos movimento. A camada de trás fica sempre visível, mas recortada por
   uma máscara de gradientes radiais que o JS reposiciona a cada quadro
   (--blob): o bloco principal segue o mouse com atraso e os menores formam
   o rastro. Sem JS, sem mouse ou com reduced-motion, vale o cruzamento
   simples definido acima. */
/* O cursor real continua visível de propósito: a bolha segue com atraso e,
   sem a seta do mouse, o usuário perde a referência de onde está apontando.
   Para a bolha virar o cursor, troque por cursor: none. */
.swap.is-blob { cursor: crosshair; }
.swap.is-blob .swap__layer--front { transform: none !important; }
.swap.is-blob .swap__layer--back {
  opacity: 1; transform: none; transition: none;
  -webkit-mask-image: var(--blob, radial-gradient(circle 0px at 50% 50%, #000 0%, rgba(0,0,0,0) 100%));
          mask-image: var(--blob, radial-gradient(circle 0px at 50% 50%, #000 0%, rgba(0,0,0,0) 100%));
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-composite: source-over; mask-composite: add;
  /* SEM will-change aqui. São 10 imagens na página; deixar todas com a máscara
     "pronta" obriga o navegador a manter 10 camadas mascaradas vivas o tempo
     todo. O script.js liga o will-change só na imagem sob o cursor. */
}
/* Teclado e toque revelam a imagem inteira: ninguém navega blob com Tab */
.swap.is-blob:focus-visible .swap__layer--back,
.swap.is-blob.is-open .swap__layer--back {
  -webkit-mask-image: none; mask-image: none;
}

/* Placeholders de mídia real — sem enfeite, deixando claro que é lugar de foto */
.media-slot {
  display: grid; place-items: center; text-align: center;
  background: var(--branco-2);
  border: 2px dashed var(--preto-2);
  color: var(--cinza);
  font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 1rem; min-height: 180px; aspect-ratio: 4 / 3;
}
.media-slot--portrait { aspect-ratio: 3 / 4; }
.media-slot--square   { aspect-ratio: 1 / 1; min-height: 0; font-size: 0.6rem; padding: 0.5rem; }
/* Camada de trás: o que foi entregue. Amarelo só para distinguir os dois
   estados enquanto são placeholders — com as fotos reais some. */
.media-slot--entrega {
  background: var(--amarelo); border-color: var(--preto); color: var(--preto);
  height: 100%; aspect-ratio: auto;
}

/* --------------------------------------------------------------------------
   5. TRAJETO — linha + seta da marca
   -------------------------------------------------------------------------- */
.page { position: relative; }

/* Medição do trajeto: o script.js liga esta classe por um instante dentro de
   Trail.build(). No Chrome, offsetTop de um elemento sticky devolve a posição
   JÁ DESLOCADA pelo sticky — então medir com a página parada dentro do baralho
   colapsava as âncoras das cartas umas sobre as outras e, entre a carta 3 e a
   4, chegava a INVERTER a ordem vertical. A linha voltava e a seta andava de ré
   justamente ao chegar em "Marca e Posicionamento". Sem o sticky, offsetTop
   devolve a posição estática real. */
.medindo-trajeto .produto,
.medindo-trajeto .xplode__stage { position: static; }

.trail { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.trail__svg { width: 100%; height: 100%; overflow: visible; }
.trail__line { stroke-linecap: round; stroke-linejoin: round; fill: none; }
.trail__line--ghost { stroke: var(--linha); stroke-width: 2; }
/* Sem will-change: o traço cobre a altura inteira do documento (~16.000px) e
   pedir camada pronta para ele é caro sem ganho — stroke-dashoffset não é
   propriedade compostável, o navegador repinta de qualquer jeito. */
.trail__line--draw  { stroke: var(--amarelo); stroke-width: 5; }

/* Seta da marca percorrendo a linha */
.trail__arrow { will-change: transform; }
.trail__arrow-shape {
  fill: var(--amarelo);
  stroke: var(--preto); stroke-width: 2.5; stroke-linejoin: round;
}

.trail__pins { position: absolute; inset: 0; }
.trail-pin {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 0.6rem;
  opacity: 0.4; transition: opacity 0.4s var(--ease);
}
.trail-pin__dot {
  width: 14px; height: 14px; border-radius: 50%;
  border: 3px solid var(--linha); background: var(--branco);
  flex: none;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.trail-pin__label {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--cinza); white-space: nowrap;
  opacity: 0; transform: translateX(-6px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.trail-pin--right { flex-direction: row-reverse; }
.trail-pin--right .trail-pin__label { transform: translateX(6px); }

.trail-pin.is-live { opacity: 1; }
.trail-pin.is-live .trail-pin__dot {
  border-color: var(--preto); background: var(--amarelo); transform: scale(1.2);
}
.trail-pin.is-live .trail-pin__label { opacity: 1; transform: translateX(0); color: var(--preto); }

.trail-pin--end .trail-pin__dot { width: 20px; height: 20px; }

@media (max-width: 719px) {
  /* Mobile: o trajeto vira uma fita vertical dentro da calha esquerda. O JS
     estreita a camada até a largura da calha e desenha ali — a linha nunca
     cruza texto e a superfície a repintar é um filete, não a tela toda.
     Os marcadores continuam: sem eles a linha seria um enfeite, com eles o
     visitante sente onde está no percurso. O rótulo é que não cabe. */
  .trail__line--ghost { stroke-width: 1.5; }
  .trail__line--draw  { stroke-width: 3; }
  .trail__arrow-shape { stroke-width: 3; }

  .trail-pin__dot   { width: 10px; height: 10px; border-width: 2px; }
  .trail-pin__label { display: none; }
  .trail-pin--end .trail-pin__dot { width: 14px; height: 14px; }
}

/* --------------------------------------------------------------------------
   6. SEÇÕES
   -------------------------------------------------------------------------- */
.section { position: relative; z-index: 1; padding-block: var(--space-xl); }
.section__head { max-width: 62ch; margin-bottom: var(--space-l); }
.section__title { font-size: var(--fs-h2); margin-bottom: var(--space-s); }
.section__text { font-size: var(--fs-lead); color: var(--preto-2); max-width: 56ch; }

.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }

/* --- MÁQUINA DE ESCREVER ---------------------------------------------------
   O JS quebra o texto em um <span class="ch"> por caractere. Todos já ocupam
   o lugar deles desde o início (visibility, não display) — por isso o texto
   não empurra o layout enquanto é escrito, e o título não muda de quebra de
   linha no meio da animação. */
.ch { visibility: hidden; position: relative; }
.ch.is-on { visibility: visible; }

/* No H1 o realce amarelo nasce junto com a letra, em vez de aparecer como um
   bloco vazio esperando o texto chegar.
   Escopado em .is-typed (classe que o JS adiciona): sem script, o realce
   continua sendo o bloco amarelo normal em vez de sumir. */
.hero__title.is-typed mark { background: transparent; padding: 0; }
.hero__title.is-typed mark .ch.is-on { background: var(--amarelo); }

/* Cursor: posicionado absoluto para não somar largura e reflowar o título */
.ch.is-caret::after {
  content: ""; position: absolute; left: 100%; top: 0.1em;
  width: 3px; height: 0.86em; background: var(--amarelo);
  animation: piscar 1s steps(2, jump-none) infinite;
}
@keyframes piscar { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .ch { visibility: visible; }
  .ch.is-caret::after { display: none; }
}

/* --- 6.1 HERO ------------------------------------------------------------ */
.hero {
  min-height: 100svh;
  padding-top: calc(var(--header-h) + var(--space-l));
  display: flex; flex-direction: column; justify-content: center;
}
.hero__title {
  font-size: var(--fs-h1); line-height: 1.2;
  margin-bottom: var(--space-m); max-width: 15ch;
}
.hero__title mark { display: inline; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.hero__text { font-size: var(--fs-lead); max-width: 54ch; color: var(--preto-2); }
/* A rota da Aproxima — o texto que justifica o preenchimento do mapa.
   Corpo menor que o parágrafo de abertura de propósito: ela COMPLEMENTA a
   promessa da hero, não disputa com ela. A régua amarela à esquerda é a
   mesma marca do trajeto que percorre a página; aqui ela avisa, antes da
   leitura, que este parágrafo é sobre percurso. */
.hero__rota {
  margin: var(--space-s) 0 0;
  padding-left: 0.9rem;
  border-left: 3px solid var(--amarelo);
  max-width: 54ch;
  font-size: 1rem; line-height: 1.6;
  color: var(--preto-2);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-s); margin-block: var(--space-m); }

/* Os números do hero viram uma LISTA: número à esquerda numa coluna fixa,
   texto à direita, uma régua por linha. Assim eles têm um eixo vertical só —
   antes eram três colunas soltas, cada rótulo quebrando numa altura. */
.hero__numeros { margin: 0; display: grid; --col-num: 4.6rem; }
.hero__numeros > div {
  /* Largura fixa na coluna do número (em rem, não em ch: `ch` resolveria pela
     fonte da LINHA, não pelo corpo do número, e o rótulo colava no algarismo).
     Cabem dois dígitos e também a sigla da UF na linha viva. */
  display: grid; grid-template-columns: var(--col-num) 1fr;
  gap: var(--space-s); align-items: baseline;
  padding: var(--space-s) 0;
  border-bottom: 1px solid var(--linha);
}
.hero__numeros > div:first-child { padding-top: 0; }
.hero__numeros dt {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2rem, 1.3rem + 1.8vw, 2.9rem); line-height: 1;
  letter-spacing: -0.03em;
}
.hero__numeros dd { margin: 0; font-size: 0.95rem; color: var(--cinza); max-width: 34ch; }

.hero__scroll {
  width: var(--wrap); margin: var(--space-m) auto 0;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--cinza);
}

/* HERO EM DUAS COLUNAS — a copy à esquerda, o painel (mapa + números) à
   direita, os dois começando na mesma linha do alto. O objetivo declarado é
   caber em uma tela: por isso o título desce de corpo aqui (com 15ch de
   medida numa coluna de meia largura, o corpo cheio abriria quatro linhas) e
   a lista de números fica mais compacta que na versão empilhada. */
@media (min-width: 900px) {
  /* A hero herdava padding-block: var(--space-xl) da .section — 144px em cima
     e 144 embaixo. Numa seção comum isso é o respiro entre blocos; aqui, numa
     seção que já tem min-height 100svh e centraliza o conteúdo, era só altura
     morta empurrando o painel para fora da primeira tela. */
  .hero {
    padding-top: calc(var(--header-h) + var(--space-m));
    padding-bottom: var(--space-s);
  }
  .hero .wrap {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--space-l);
    /* stretch, não start: as duas colunas terminam na mesma linha e a cena
       fica com toda a altura que a copy deixar (ver .hero__painel). */
    align-items: stretch;
  }
  .hero__title { font-size: clamp(2.2rem, 1.1rem + 2.8vw, 3.9rem); }
  /* Sem margem embaixo dos botões: eles fecham a coluna, e ali a margem só
     estica a hero. */
  .hero__actions { margin-block: var(--space-m) 0; }
  /* As folgas do próprio .hero__painel (margin/padding/gap) são reescritas
     junto com a regra base dele, lá no bloco do mapa — mesma especificidade,
     e a base vem depois neste arquivo. */

  /* NÚMEROS EM FAIXA — no desktop a lista deixa de ser quatro linhas empilhadas
     e vira uma faixa de quatro colunas embaixo do mapa: número em cima, rótulo
     curto embaixo, um filete vertical separando. Cada entrada gasta ~70px de
     altura em vez de ~35 por linha × 4 — e a diferença toda vai para a cena. */
  .hero__numeros {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-s);
  }
  .hero__numeros > div {
    display: block;                 /* deixa de ser [número | rótulo] */
    padding: 0 0 0 var(--space-s);
    border-bottom: 0;
    border-left: 1px solid var(--linha);
  }
  /* `padding: 0` e não só `padding-left`: a regra base zera o padding-top da
     primeira entrada, e num strip horizontal isso desalinharia o "15" dos
     outros três números. */
  .hero__numeros > div:first-child { padding: 0; border-left: 0; }
  .hero__numeros dt { font-size: clamp(1.6rem, 1rem + 1.1vw, 2.2rem); }
  .hero__numeros dd {
    margin-top: 0.35rem;
    font-size: 0.78rem; line-height: 1.35; max-width: none;
  }
}

/* TELA BAIXA (notebook de 768px, janela não maximizada): antes de deixar o
   painel escapar da primeira tela, a hero aperta o próprio ritmo — título e
   lead descem de corpo, as réguas encostam. É a mesma hero, mais junta. */
@media (min-width: 900px) and (max-height: 820px) {
  .hero__title {
    font-size: clamp(2rem, 1rem + 2.2vw, 3rem);
    margin-bottom: var(--space-s);
  }
  .hero__text { font-size: 1.05rem; }
}

/* Último degrau — 1366×768, que é onde a tela útil fica em torno de 580px.
   As folgas do painel e a altura da cena ficam no bloco do mapa, mais abaixo. */
@media (min-width: 900px) and (max-height: 720px) {
  .hero { padding-top: calc(var(--header-h) + var(--space-s)); }
  .hero__scroll { margin-top: var(--space-s); }
  .hero__numeros dt { font-size: 1.5rem; }
  .hero__numeros dd { font-size: 0.72rem; }
}

@media (max-width: 719px) {
  /* A hero media 1112px no celular — duas telas cheias antes da primeira
     seção, sendo que boa parte disso é espaço reservado para o título que
     ainda está sendo escrito. Aqui ela volta a caber em uma tela e um pouco. */
  .hero { padding-top: calc(var(--header-h) + var(--space-m)); padding-bottom: var(--space-l); }
  .hero__title { max-width: none; margin-bottom: var(--space-s); }
  .hero__actions { margin-block: var(--space-m) 0; }

  /* No celular a lista fica mais apertada, mas continua lista: o alinhamento
     do número com o texto é o que segurava esta área. */
  .hero__numeros { --col-num: 3rem; }
  .hero__numeros > div { padding: 0.6rem 0; }
  .hero__numeros dt { font-size: 1.8rem; }
  .hero__numeros dd { font-size: 0.85rem; line-height: 1.4; max-width: none; }

  .hero__scroll { margin-top: var(--space-m); }
}

/* --- 6.2 MODOS ----------------------------------------------------------- */
.modos__grid { display: grid; gap: var(--space-m); }
.modo {
  border: 3px solid var(--preto); border-radius: 2px;
  padding: var(--space-m); display: flex; flex-direction: column;
}
.modo--exec { background: var(--preto); color: var(--branco); }
.modo--exec .modo__tag { color: var(--amarelo); }
.modo--exec .modo__text { color: rgba(255,255,255,0.8); }
.modo--exec .modo__fit { color: rgba(255,255,255,0.65); border-top-color: rgba(255,255,255,0.25); }
.modo--consult { background: var(--amarelo); }
.modo__tag {
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.18em;
  text-transform: uppercase; margin-bottom: var(--space-s);
}
.modo__title { font-size: var(--fs-h3); margin-bottom: 0.6rem; }
.modo__text { color: var(--preto-2); }
.modo__fit {
  margin: auto 0 0; padding-top: var(--space-s);
  border-top: 2px solid rgba(17,17,17,0.2);
  font-size: 0.92rem; color: var(--preto-2);
}
.modos__note {
  margin-top: var(--space-m); font-family: var(--font-display);
  font-size: 1rem; color: var(--cinza); max-width: 54ch;
}
@media (min-width: 800px) { .modos__grid { grid-template-columns: 1fr 1fr; gap: var(--space-m); } }

/* --- 6.3 PRODUTOS — baralho que empilha no topo ---------------------------
   Os sete produtos ocupavam 41% da página inteira: 7,7 telas só para essa
   seção. Aqui cada carta gruda no topo e a seguinte desliza por cima, como
   um baralho sendo montado. Três coisas fazem o efeito funcionar:

   1. A lista precisa ser BLOCK, não grid. Num grid, o bloco que contém cada
      sticky é a célula dela — do tamanho exato da carta — então a sticky não
      teria por onde correr e nada grudaria.
   2. Cada carta precisa de fundo sólido, senão a de baixo aparece através.
   3. O degrau crescente no `top` deixa à mostra uma faixa de cada carta já
      empilhada, que é o que dá a leitura de baralho em vez de troca seca.

   A margem negativa encurta o trecho de rolagem de cada carta: sem ela o
   efeito seria bonito mas a página continuaria do mesmo tamanho. */
/* O recuo mora na LISTA e é herdado pelas cartas. Assim o espaçador de baixo
   (padding-bottom) usa exatamente a mesma medida do recuo de cada carta. */
.produtos__lista {
  display: block;
  /* Recuo menor = mais trecho de rolagem por carta, tempo de leitura maior
     antes da seguinte cobrir. */
  --recuo: 8svh;
}
/* Espaçador que devolve à última carta o trecho de rolagem que ela não tem.
   Sem ele a lista termina rente à última carta e não sobra onde ela grudar:
   as três primeiras ficavam presas no topo enquanto a quarta subia sozinha,
   descobrindo o rodapé das anteriores por baixo dela — o CTA de "Projetos"
   aparecia como se fosse do card de "Marca".

   Precisa ser um FILHO (::after), não padding-bottom: o bloco de contenção de
   um sticky é a caixa de CONTEÚDO do pai, e padding fica fora dela — por isso
   reservar o espaço com padding não mudava nada.

   O script.js reescreve --espaco-final com a medida real da carta; o valor
   aqui é a reserva para quando ele não roda. */
.produtos__lista::after {
  content: ""; display: block;
  height: var(--espaco-final, calc(var(--recuo) * 2));
}

.produto {
  position: sticky;
  top: calc(var(--header-h) + 0.75rem + var(--degrau, 0px));
  display: grid; gap: var(--space-m);
  background: var(--branco);
  border: 3px solid var(--preto);
  padding: var(--space-m);
  overflow: visible;
  /* O recuo é o que encurta a página: sem ele o baralho seria bonito e o site
     continuaria com as mesmas 7,7 telas. Cada carta cede este tanto do próprio
     trecho de rolagem para a seguinte. Vale para TODAS, inclusive a última:
     com margens iguais as quatro se soltam juntas no fim, e o baralho sai de
     cena inteiro em vez de se desmontar carta a carta. */
  margin-bottom: calc(-1 * var(--recuo));
}

.produto:nth-child(1) { --degrau: 0px;  }
.produto:nth-child(2) { --degrau: 12px; }
.produto:nth-child(3) { --degrau: 24px; }
.produto:nth-child(4) { --degrau: 36px; }
.produto:nth-child(5) { --degrau: 48px; }
.produto:nth-child(6) { --degrau: 60px; }
.produto:nth-child(7) { --degrau: 72px; }

/* Sombra só para cima: é a borda superior que encosta na carta de baixo, e
   ela precisa parecer folha sobreposta, não caixa flutuando. */
.produto { box-shadow: 0 -14px 30px rgba(17, 17, 17, 0.07); }

/* As cartas NÃO usam .reveal, de propósito. Um fade de opacidade numa pilha
   deixa a carta translúcida enquanto entra, e o texto da carta de baixo
   atravessa a de cima — vira sopa de letras nos ~0,6s da transição. Aqui a
   entrada é o próprio deslizar do baralho, que já é movimento suficiente. */
.produto__num {
  font-family: var(--font-mono); font-size: 0.9rem; letter-spacing: 0.16em;
  color: var(--preto); margin: 0;
}
/* O número precisa ler na mesma linha do título. Dando à caixa de linha dele a
   mesma altura da primeira linha do título, os dois ficam opticamente
   centrados um no outro — antes o número flutuava colado no topo da célula,
   alguns pixels acima da capitular. Só no layout largo: no celular o número
   é uma linha própria acima do título e esta altura viraria um buraco. */
@media (min-width: 900px) {
  .produto__num { line-height: calc(var(--fs-h3) * 1.05); }
}
.produto__nome { font-size: var(--fs-h3); margin-bottom: 0.5rem; }
/* Sem o realce amarelo fixo sob o título. Ele marcava os sete produtos
   antigos, mas com quatro cards grandes e empilhados virava peso demais —
   competia com o próprio nome da solução. O amarelo agora só aparece no
   hover, como resposta, não como decoração permanente. */
.produto__link {
  text-decoration: none; display: inline-flex; align-items: baseline; gap: 0.4rem;
  box-shadow: inset 0 0 0 var(--amarelo);
  transition: box-shadow 0.2s var(--ease);
}
.produto__link::after { content: "→"; font-size: 0.7em; transition: transform 0.2s var(--ease); }
.produto__link:hover { box-shadow: inset 0 -100% 0 var(--amarelo); }
.produto__link:hover::after { transform: translateX(4px); }
/* Sem teto em ch aqui: a medida de leitura passou a ser definida em
   porcentagem da largura interna do card, no bloco de tela larga. Assim o
   celular usa a largura inteira e o desktop não deixa a faixa vazia à direita
   que os 46ch antigos criavam. */
.produto__necessidade {
  font-size: var(--fs-lead); color: var(--preto-2);
  /* Respiro entre o subtítulo e a descrição — 20 a 24px. */
  margin-bottom: clamp(1.25rem, 1.6vw, 1.5rem);
}
.produto__itens {
  display: grid; gap: 0.4rem; margin-bottom: var(--space-m);
  padding-top: var(--space-s); border-top: 1px solid var(--linha);
}
.produto__itens li { position: relative; padding-left: 1.4rem; font-size: 0.97rem; color: var(--preto-2); }
.produto__itens li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 10px; height: 3px; background: var(--amarelo);
}

.produto__case {
  background: var(--branco-2); border-left: 6px solid var(--amarelo);
  padding: var(--space-s) var(--space-m); margin-bottom: var(--space-m);
}
.produto__case-label {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--cinza); margin-bottom: 0.3rem;
}
.produto__case-nome { font-size: 1.25rem; margin-bottom: 0.4rem; }
.produto__case-texto { margin: 0; font-size: 0.97rem; color: var(--preto-2); }

/* As duas portas: gestão ou consultoria */
.portas { display: grid; gap: 0.6rem; }
.porta {
  margin: 0; font-size: 0.95rem; color: var(--preto-2);
  padding: 0.7rem 0.9rem; border: 2px solid var(--linha); border-radius: 2px;
}
.porta span {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--preto); margin-bottom: 0.2rem;
}
.porta--exec { border-color: var(--preto); }
.porta--consult { border-color: var(--amarelo); background: color-mix(in srgb, var(--amarelo) 14%, var(--branco)); }

/* O título é link, mas com 26px de altura ele não é alvo de toque decente.
   Este é o link de verdade para o dedo — e deixa explícito que há uma página. */
.produto__cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 44px; margin-top: var(--space-s);
  font-family: var(--font-display); font-weight: 700; font-size: 0.95rem;
  text-decoration: none;
  border-bottom: 3px solid var(--amarelo);
  transition: gap 0.2s var(--ease), border-color 0.2s var(--ease);
}
.produto__cta::after { content: "→"; }
.produto__cta:hover { gap: 0.8rem; border-bottom-color: var(--preto); }

.produto--destaque { border-top-color: var(--amarelo); border-top-width: 8px; }

/* Card de solução: texto + ilustração; CTA logo abaixo do texto
   (NÃO no rodapé — no baralho sticky a carta seguinte cobre a base). */
.produto--solucao .produto__desc {
  color: var(--preto-2);
  margin-bottom: 0.75rem;
}
.produto--solucao .frentes {
  margin-bottom: 0.5rem;
  margin-top: 0.75rem;
}
.produto--solucao .produto__cta {
  margin-top: 0.35rem;
  padding-top: 0;
  font-size: 1.08rem;
  border-bottom-width: 4px;
  border-bottom-color: var(--amarelo);
}

.produto--solucao .produto__linha {
  display: grid;
  gap: var(--space-m);
  min-width: 0;
}
.produto--solucao .produto__media {
  display: flex;
  align-items: flex-start; /* topo alinhado ao título / seta → */
  justify-content: center;
  margin: 0;
  min-width: 0;
}
.produto--solucao .produto__media img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: top center;
}

/* As frentes de cada solução. <details> nativo: abre sem JS, responde ao
   teclado e o leitor de tela anuncia aberto/fechado sozinho.
   overflow-anchor evita o browser “puxar” o scroll sozinho ao expandir. */
.frentes {
  border-top: 1px solid var(--linha);
  padding-top: var(--space-s); margin-bottom: var(--space-s);
  overflow-anchor: none;
}
.frentes__abre {
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 0.5rem; min-height: 44px;
  font-family: var(--font-display); font-weight: 700; font-size: 0.9rem;
  overflow-anchor: auto;
  scroll-margin-block: 0;
}
.frentes__abre::-webkit-details-marker { display: none; }
.frentes__abre::before {
  content: "+"; display: grid; place-items: center;
  width: 22px; height: 22px; flex: none;
  border: 2px solid var(--preto); font-size: 0.9rem; line-height: 1;
}
.frentes[open] .frentes__abre::before { content: "–"; background: var(--amarelo); }
.frentes__lista { display: grid; gap: 0.4rem; padding: var(--space-s) 0 0.2rem; }
.frentes__lista li {
  position: relative; padding-left: 1.4rem;
  font-size: 0.97rem; color: var(--preto-2);
}
.frentes__lista li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 10px; height: 3px; background: var(--amarelo);
}

/* --- 6.3.1 CAPACIDADES ----------------------------------------------------
   HIERARQUIA — esta seção existe abaixo das soluções, e precisa PARECER
   abaixo. A regra que orienta tudo aqui:

     Solução   = o que o cliente contrata para resolver um problema.
                 Cartão com borda de 3px, empilha no scroll, título grande,
                 CTA própria.
     Capacidade= o que a Aproxima aciona para entregar a solução.
                 Etiqueta. Sem cartão, sem empilhamento, sem CTA, tipografia
                 de apoio e fundo neutro.

   Se um dia alguém aumentar o peso daqui, "Vídeo" vai passar a competir com
   "Diagnóstico de Crescimento" na leitura — que é exatamente o que esta
   seção não pode fazer.

   O respiro de entrada é MAIOR que o padding padrão de .section, de
   propósito: os tópicos que terminam em texto ganham ~80px extras do
   margin-bottom do próprio .section__head, e o baralho de soluções termina
   num card, sem esse extra. Sem a compensação, a chegada ao 04 media ~306px
   contra ~368px do vão 01→02 — e parecia colada. */
.capacidades { padding-top: calc(var(--space-xl) + var(--space-l)); }
.capacidades__titulo { font-size: var(--fs-h3); }

.capacidades__grade {
  display: grid; gap: 0.6rem; margin-top: var(--space-m);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.capacidade {
  background: var(--branco-2);
  border-left: 3px solid var(--amarelo);
  font-family: var(--font-display); font-weight: 600;
  font-size: 0.92rem; color: var(--preto-2);
}
/* Quatro das nove têm página própria; as outras cinco ainda são só rótulo.
   O padding vive no item OU no link, para o alvo de toque cobrir a etiqueta
   inteira em vez de só o texto. */
.capacidade { padding: 0.85rem 1rem; }
.capacidade:has(a) { padding: 0; }
.capacidade a {
  display: flex; align-items: center; min-height: 44px;
  padding: 0.85rem 1rem; text-decoration: none;
  transition: background-color 0.2s var(--ease);
}
.capacidade a::after { content: "→"; margin-left: auto; opacity: 0.45; }
.capacidade a:hover { background: var(--amarelo); color: var(--preto); }
.capacidade a:hover::after { opacity: 1; }

/* --- ESTEIRA DE CAPACIDADES -----------------------------------------------
   Leitura do CircularGallery (WebGL/OGL) para o que este site é: HTML e
   transform, sem dependência e sem canvas. O que veio de lá:

     · fluxo contínuo e infinito, com as etiquetas reentrando pela outra ponta;
     · inércia — o impulso decai por interpolação, o mesmo lerp do original;
     · o ARCO: a mesma conta de círculo por três pontos, aplicada em translateY
       e rotate em vez de posição de malha 3D;
     · arrastar para empurrar a fita.

   O que NÃO veio, de propósito: o listener de wheel no window (roubaria a
   rolagem da página inteira) e o peso de uma galeria de imagens — estas
   etiquetas precisam continuar lendo abaixo dos cards de solução.

   A grade acima é o estado base. Tudo aqui só vale com .is-live, que o
   script.js liga apenas quando há espaço e movimento é bem-vindo. */
.capacidades__esteira { overflow: hidden; }

.capacidades__esteira.is-live {
  cursor: grab;
  /* Vertical passa; o JS só assume arraste quando o gesto é horizontal. */
  touch-action: pan-y;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
@media (hover: none) {
  .capacidades__esteira.is-live { cursor: default; }
}
.capacidades__esteira.is-live.is-arrastando { cursor: grabbing; }

/* Vira trilho: a grade deixa de distribuir em colunas e cada etiqueta passa a
   ser posicionada por transform. A altura é escrita pelo script com a medida
   real das etiquetas mais a flecha do arco. */
.capacidades__esteira.is-live .capacidades__grade {
  display: block; position: relative;
  height: var(--altura-esteira, 64px);
  margin-top: var(--space-m);
}
.capacidades__esteira.is-live .capacidade {
  position: absolute; top: 0; left: 0;
  white-space: nowrap;
  transform-origin: 50% 50%;
}
/* Enquanto arrasta, o clique no link é suprimido pelo script — sem isto o
   dedo que empurra a fita abriria a página da etiqueta que ficou sob ele. */
.capacidades__esteira.is-arrastando .capacidade a { pointer-events: none; }

@media (max-width: 899px) {
  /* No celular o sticky + recuo cortava CTA e frentes (carta alta demais
     para a tela). Aqui a pilha vira lista normal: todo o conteúdo aparece. */
  .produtos__lista { --recuo: 0px; }
  .produtos__lista::after { display: none; }
  .produto {
    position: relative;
    top: auto;
    margin-bottom: var(--space-m);
    padding: clamp(2rem, 6vw, 2.75rem) clamp(1.5rem, 5vw, 2rem);
    gap: var(--space-m);
  }
  .produto__necessidade { margin-bottom: 1.25rem; }
  .produto__itens { margin-bottom: var(--space-s); }
  .produto__case { padding: var(--space-s); margin-bottom: var(--space-s); }
  .produto__media .media-slot { aspect-ratio: 16 / 9; min-height: 130px; }
  .produto--solucao .produto__media {
    margin-top: var(--space-s);
    padding-inline: clamp(0.5rem, 4vw, 1.5rem);
  }
  .produto--solucao .produto__media img {
    width: 100%;
    height: auto;
    max-width: 480px;
    margin-inline: auto;
    object-fit: contain;
  }
  /* Mobile: lista normal — a pista de leitura do baralho não se aplica.
     Sem isto, .is-expandido (0,2,0) ganhava do .produto e abria ~28svh
     de vão fantasma ao expandir frentes no celular. */
  .produto.is-expandido {
    margin-bottom: var(--space-m);
  }

  /* Entrada dos cards de solução no mobile (mesmo timing/easing do .reveal).
     Desktop continua sem fade — lá a entrada é o empilhar do baralho. */
  .produto--solucao.produto--entra {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
  }
  .produto--solucao.produto--entra.is-inview {
    opacity: 1;
    transform: none;
  }
}

@media (min-width: 900px) {
  .produto {
    grid-template-columns: 4rem minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--space-m) var(--space-l);
    align-items: stretch;
    padding: clamp(3rem, 4vw, 4.25rem) clamp(3.5rem, 5vw, 5rem);
  }
  .produto__num   { grid-column: 1; grid-row: 1; }
  .produto__corpo { grid-column: 2; grid-row: 1; display: flex; flex-direction: column; }
  .produto__corpo .produto__cta {
    margin-top: auto;
    padding-top: var(--space-m);
    align-self: flex-start;
  }
  /* Soluções: NÃO usar margin-top:auto — no baralho isso esconde o link
     sob a carta seguinte (era o bug dos cards 01 e 02). */
  .produto--solucao .produto__corpo .produto__cta {
    margin-top: 0.35rem;
    padding-top: 0;
    align-self: flex-start;
    font-size: 1.08rem;
    border-bottom: 4px solid var(--amarelo);
    position: relative;
    z-index: 2;
  }
  .produto__media { grid-column: 3; grid-row: 1; }

  /* Solução: CTA fica JUNTO do texto (após a descrição), não no rodapé.
     No baralho, a carta seguinte cobre a base — por isso 01 e 02 “sumiam”. */
  .produto--solucao {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    align-content: start;
    min-height: clamp(480px, 58svh, 640px);
  }
  .produto--solucao .produto__linha {
    grid-column: 1;
    grid-row: 1;
    grid-template-columns: minmax(0, 1fr) minmax(22rem, 1.05fr);
    gap: clamp(1.5rem, 2.5vw, 2.25rem);
    align-items: start;
    align-self: start;
    min-height: 0;
  }
  .produto--solucao .produto__corpo {
    grid-column: auto;
    grid-row: auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    height: auto;
  }
  .produto--solucao .produto__media {
    grid-column: auto;
    grid-row: auto;
    width: 100%;
    max-width: 560px;
    justify-self: stretch;
    align-self: start;
    margin-top: 0.15rem;
  }
  .produto--solucao .produto__media img {
    width: 100%;
    height: auto;
    object-fit: contain;
    object-position: top center;
  }

  /* Desktop only: frentes abertas ganham pista de rolagem (não no mobile).
     Última carta não recebe .is-expandido via JS. */
  .produto.is-expandido {
    margin-bottom: var(--recuo-leitura, 28svh);
  }

  .produto--invertido { grid-template-columns: minmax(0, 0.8fr) 3rem minmax(0, 1.2fr); }
  .produto--invertido .produto__media { grid-column: 1; }
  .produto--invertido .produto__num   { grid-column: 2; }
  .produto--invertido .produto__corpo { grid-column: 3; }

  .portas { grid-template-columns: 1fr 1fr; }
  .produto--destaque .portas { grid-template-columns: 1fr; }
}

/* --- 6.4 QUEM SOMOS ------------------------------------------------------ */
.quem__grid { display: grid; gap: var(--space-l); }
.quem__list { margin-top: var(--space-m); display: grid; gap: var(--space-s); }
.quem__list li { padding-left: 1.6rem; position: relative; color: var(--preto-2); max-width: 52ch; }
.quem__list li::before {
  content: ""; position: absolute; left: 0; top: 0.45em;
  width: 10px; height: 10px; background: var(--amarelo); border: 2px solid var(--preto);
}
/* --- RASTRO — o quadro grande da seção, em dois tempos --------------------
   Três camadas dentro do mesmo palco:

     .rastro__capa  → os sócios se revezando, cada foto preenchendo o quadro.
                      É também o estado base: sem JS, sem mouse fino ou com
                      reduced-motion, fica só a primeira, parada.
     .rastro__img   → as fotos do rastro. Invisíveis e fora do fluxo até o
                      script.js ligar .is-live; a partir daí ele posiciona cada
                      uma no ponto do cursor e roda a animação de entrada e
                      saída (Web Animations API, nada aqui no CSS).

   A proporção 3/4 é a mesma do slot de vídeo que ocupava este lugar: quando o
   vídeo do Lucas for gravado e entrar aqui, a coluna não muda de altura.

   Sem sombra, sem canto arredondado e sem glow: a referência de origem é um
   showcase com estética de vidro, e este site é o contrário disso — foto
   sólida, corte reto, movimento curto.
   -------------------------------------------------------------------------- */
.rastro { margin: 0; }
.rastro__palco {
  position: relative; overflow: hidden;
  background: var(--branco-2);
  aspect-ratio: 3 / 4;
}
.rastro__capa {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0; transition: opacity 0.45s var(--ease);
}
.rastro__capa.is-on { opacity: 1; }
/* Assim que a primeira foto do rastro é disparada, a capa sai de cena — e
   vence o .is-on porque tem uma classe a mais no seletor. */
.rastro.is-tocado .rastro__capa { opacity: 0; }

.rastro__img {
  position: absolute; left: 0; top: 0;
  width: 46%; aspect-ratio: 3 / 4; height: auto;
  object-fit: cover; display: block;
  opacity: 0; pointer-events: none;
  /* Sem .is-live (sem JS) elas nunca aparecem: só a capa conta. */
}
.rastro.is-live .rastro__palco { cursor: crosshair; }
/* will-change só nas que o rastro usa, e só com ele ligado: são 7 imagens,
   e manter as 7 promovidas a camada própria o tempo todo é caro à toa. */
.rastro.is-live .rastro__img { will-change: transform, opacity; }

/* Etiqueta de foto — a mesma em qualquer retrato do site: régua preta, nome em
   mono e a função num bloco amarelo. Vale para o quadro do "quem somos" e para
   a abertura das páginas de solução. */
.rastro__legenda,
.foto-cred {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem;
  margin-top: 0.7rem; padding-top: 0.6rem;
  border-top: 3px solid var(--preto);
  font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.12em; text-transform: uppercase;
}
.rastro__legenda strong,
.foto-cred strong { color: var(--preto); font-weight: 700; }
.rastro__papel,
.foto-cred__papel {
  background: var(--amarelo); color: var(--preto);
  padding: 0.2rem 0.45rem;
}
/* A legenda acompanha o quadro: parado, nomeia o sócio que está na capa e
   convida a passar o cursor; com o rastro andando, passa a falar do time.
   Em toque (is-toque) a dica muda — não há cursor para “passar”. */
.rastro__time, .rastro__dica { display: none; }
.rastro__dica { color: var(--cinza); }
.rastro.is-live .rastro__dica:not(.rastro__dica--toque) { display: inline; }
.rastro.is-toque .rastro__dica--toque { display: inline; }
.rastro.is-live.is-tocado .rastro__nome,
.rastro.is-live.is-tocado .rastro__papel,
.rastro.is-live.is-tocado .rastro__dica { display: none; }
.rastro.is-live.is-tocado .rastro__time { display: inline; }

@media (min-width: 900px) {
  .quem__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); gap: var(--space-xl); align-items: start; }
}

/* --- 6.5 HISTÓRIAS — filmstrip (acordeão horizontal de fotos) -----------
   Frestas se abrem sob hover (desktop) ou toque (≤999px). Fundo claro, alinhado
   ao restante do site — sem chrome de marca/dica/contador. */
.historias { padding-bottom: var(--space-l); }
.historias .section__head { margin-bottom: var(--space-m); }

.filmstrip {
  --fs-sliver: 22px;
  --fs-gap: 6px;
  --fs-open: 384px;
  --fs-reel-h: 440px;
  --fs-ease: cubic-bezier(0.16, 0.84, 0.3, 1);
  --fs-dur: 0.9s;
  --fs-gold: var(--amarelo);
  width: 100%;
  margin-top: var(--space-m);
}
.filmstrip__stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: auto;
  padding: clamp(1.25rem, 3vh, 2rem) 0 clamp(1.75rem, 4vh, 2.75rem);
  background: var(--branco-2);
  color: var(--preto);
  overflow: hidden;
}
.filmstrip__track {
  position: relative;
  width: min(92%, 1440px);
  height: var(--fs-reel-h);
  margin: 0 auto;
}
.filmstrip__frame {
  position: absolute;
  top: 0;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  background-color: var(--linha);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: grayscale(0.45) brightness(0.92);
  transition:
    left var(--fs-dur) var(--fs-ease),
    width var(--fs-dur) var(--fs-ease),
    filter var(--fs-dur) var(--fs-ease);
  -webkit-tap-highlight-color: transparent;
}
/* Fallback sem JS: abre o primeiro no centro aproximado */
.filmstrip:not(.is-live) .filmstrip__frame {
  position: absolute;
  left: calc(50% - (var(--fs-open) / 2));
  width: var(--fs-sliver);
}
.filmstrip:not(.is-live) .filmstrip__frame.is-open {
  width: var(--fs-open);
  filter: none;
  z-index: 2;
}
.filmstrip__frame.is-open {
  filter: none;
  z-index: 2;
}
.filmstrip__frame:focus-visible {
  outline: 2px solid var(--preto);
  outline-offset: 3px;
}

.filmstrip__bracket {
  position: absolute;
  top: 0;
  height: 100%;
  border: 2px solid var(--fs-gold);
  border-radius: 2px;
  box-shadow: 3px 3px 0 var(--preto);
  pointer-events: none;
  z-index: 3;
  transition: left var(--fs-dur) var(--fs-ease), width var(--fs-dur) var(--fs-ease);
  opacity: 0;
}
.filmstrip.is-live .filmstrip__bracket { opacity: 1; }

@media (max-width: 999px) {
  .filmstrip {
    --fs-open: 132px;
    --fs-reel-h: 320px;
  }
  .filmstrip__stage { padding: 1rem 0 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .filmstrip__frame,
  .filmstrip__bracket {
    transition: none !important;
  }
}

/* Cases em páginas de capacidade (prova) — cards de texto, não o filmstrip */
.case { border-top: 3px solid var(--preto); padding-top: var(--space-s); }
.case__produto {
  display: inline-block; background: var(--amarelo);
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em;
  text-transform: uppercase; padding: 0.25rem 0.5rem; margin-bottom: 0.6rem;
}
.case__title { font-size: 1.35rem; margin-bottom: 0.25rem; }
.case__seg { font-size: 0.85rem; color: var(--cinza); margin-bottom: 0.6rem; }
.case__texto { font-size: 0.95rem; color: var(--preto-2); margin: 0; }
.cases__nota {
  margin-top: var(--space-l); font-family: var(--font-display);
  color: var(--cinza); border-left: 6px solid var(--amarelo);
  padding-left: var(--space-s); max-width: 56ch;
}

/* --- 6.6 PROCESSO -------------------------------------------------------- */
/* --- EXPLODED VIEW ---------------------------------------------------------
   O layout final (a escada) é o layout NATURAL do CSS. O JS só aplica
   transform por cima para levar as etapas ao estado juntas → separadas →
   travadas. Assim, se o script não rodar, o que sobra é o layout certo. */
.xplode__scroll { position: relative; }
.xplode__stage { display: grid; gap: var(--space-m); }
/* A legenda não está dentro de um .wrap no HTML: sem esta largura ela cola na
   borda da tela enquanto as etapas respeitam a margem, e as duas coisas
   deixam de parecer o mesmo bloco. */
.xplode__caption {
  width: var(--wrap); margin: 0 auto;
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.06em;
  color: var(--cinza);
  position: relative;
  z-index: 6;
  padding-bottom: 0.35rem;
}

/* A área fixa e o cartão das etapas valem em qualquer largura — o exploded
   view também roda no celular. O que muda por tamanho é só o arranjo final:
   escada de quatro colunas no desktop, grade 2×2 no celular. */
.xplode.is-live .xplode__stage {
  position: sticky; top: var(--header-h);
  height: calc(100svh - var(--header-h));
  align-content: center;
  /* visible: o texto dos cards não pode ser decepado no explode */
  overflow: visible;
  padding-block: clamp(0.75rem, 2vh, 1.5rem);
  box-sizing: border-box;
}
/* Na fase inicial as etapas ficam empilhadas. Sem fundo sólido, os quatro
   textos se sobrepõem e viram borrão — por isso viram cartão opaco, e a
   ordem de empilhamento é invertida para a etapa 01 ficar por cima. */
.xplode.is-live .passo {
  background: var(--branco);
  border: 2px solid var(--linha); border-top: 3px solid var(--preto);
  padding: var(--space-s);
  overflow: visible;
}
.xplode.is-live .passo p {
  max-width: none;
}
.xplode.is-live .passo:nth-child(1) { z-index: 4; }
.xplode.is-live .passo:nth-child(2) { z-index: 3; }
.xplode.is-live .passo:nth-child(3) { z-index: 2; }
.xplode.is-live .passo:nth-child(4) { z-index: 1; }

@media (min-width: 900px) {
  .xplode.is-live .xplode__scroll { height: 260vh; }
  /* Escada: o degrau é o estado final em que as etapas travam */
  .xplode.is-live .passo:nth-child(2) { margin-top: 2.5rem; }
  .xplode.is-live .passo:nth-child(3) { margin-top: 5rem; }
  .xplode.is-live .passo:nth-child(4) { margin-top: 7.5rem; }
}

@media (max-width: 899px) {
  /* svh, não vh: com vh, a barra de endereço do celular entrando e saindo
     muda a altura do trilho no meio da animação e as etapas dão um salto. */
  .xplode.is-live .xplode__scroll { height: 230svh; }

  /* Quatro etapas em coluna única não cabem na área fixa. Em 2×2 cabem, e o
     arranjo final continua sendo o layout natural que o JS mede — por isso
     measure() não precisa saber que existe uma versão mobile. */
  .xplode.is-live .processo__steps {
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem; align-content: center;
  }
  .xplode.is-live .passo { padding: 0.65rem 0.75rem; }
  .xplode.is-live .passo__title { font-size: 0.95rem; margin-bottom: 0.3rem; }
  .xplode.is-live .passo p {
    font-size: 0.8rem;
    line-height: 1.45;
    max-width: none; /* no 2×2, o teto em ch cortava frases no meio */
  }
  .xplode.is-live .xplode__caption { font-size: 0.72rem; letter-spacing: 0.04em; }
}

.processo__steps { display: grid; gap: var(--space-m); }
.passo { border-top: 1px solid var(--linha); padding-top: var(--space-s); }
.passo__num {
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.16em;
  display: inline-block; background: var(--amarelo); padding: 0.1rem 0.4rem;
  margin-bottom: 0.6rem;
}
.passo__title { font-size: 1.2rem; margin-bottom: 0.4rem; }
.passo p { color: var(--preto-2); font-size: 0.95rem; margin: 0; max-width: 44ch; }
.processo__note {
  margin-top: var(--space-l); font-size: var(--fs-lead);
  max-width: 46ch; border-left: 6px solid var(--amarelo); padding-left: var(--space-m);
}
@media (min-width: 720px)  { .processo__steps { grid-template-columns: 1fr 1fr; gap: var(--space-l) var(--space-m); } }
@media (min-width: 1080px) { .processo__steps { grid-template-columns: repeat(4, 1fr); } }

/* --- 6.7 CONTATO --------------------------------------------------------- */
.contato { padding-bottom: var(--space-l); }
/* Faixa vazia onde a seta termina, logo acima do bloco de contato */
.contato__anchor { height: clamp(80px, 12vw, 140px); }

/* O bloco de fecho de TODAS as páginas — branco limpo + borda preta.
   Amarelo ficou pesado; o CTA amarelo dos botões já carrega a marca. */
.contato__card {
  background: var(--branco-2);
  color: var(--preto);
  border: 2px solid var(--linha);
  padding: clamp(2rem, 6vw, 5rem);
  border-radius: 2px;
}
.contato__card .eyebrow,
.contato__card .eyebrow--light {
  color: var(--cinza);
}
.contato__title { font-size: var(--fs-h2); margin-bottom: var(--space-s); max-width: 16ch; }
.contato__text {
  font-size: var(--fs-lead);
  color: var(--preto-2);
  max-width: 46ch;
}
.contato__actions { display: flex; flex-wrap: wrap; gap: var(--space-s); margin-block: var(--space-m); }

.contato__fine {
  font-family: var(--font-mono); font-size: 0.7rem; line-height: 1.8;
  letter-spacing: 0.08em; color: var(--cinza); margin: 0;
}

/* Botões no card claro: CTA amarelo da marca + ghost preto. */
.contato__card .btn--amarelo {
  background: var(--amarelo);
  border-color: var(--amarelo);
  color: var(--preto);
}
.contato__card .btn--amarelo:hover {
  background: var(--preto);
  border-color: var(--preto);
  color: var(--branco);
}
.contato__card .btn--on-dark,
.contato__card .btn--ghost {
  color: var(--preto);
  border-color: var(--preto);
  background: transparent;
}
.contato__card .btn--on-dark:hover,
.contato__card .btn--ghost:hover {
  background: var(--amarelo);
  color: var(--preto);
  border-color: var(--preto);
}

/* --------------------------------------------------------------------------
   6.8 PÁGINA DE SERVIÇO (servico-*.html)
   -------------------------------------------------------------------------- */
.voltar {
  display: flex; width: fit-content; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--cinza); text-decoration: none;
  margin-bottom: var(--space-m);
}
.voltar:hover { color: var(--preto); }
.voltar::before { content: "←"; }

/* Marco invisível: só serve de ponto de medição para o trajeto. Ocupa altura
   para a seta ter onde nascer, sem entrar na leitura da página. */
.trilho-marco { height: clamp(48px, 8vw, 96px); }

.servico-hero { padding-top: calc(var(--header-h) + var(--space-l)); }
.servico-hero__num {
  font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.18em;
  background: var(--amarelo); padding: 0.2rem 0.5rem; display: inline-block;
  margin-bottom: var(--space-s);
}
.servico-hero__title { font-size: var(--fs-h1); line-height: 1.1; max-width: 16ch; margin-bottom: var(--space-s); }
.servico-hero__lead { font-size: var(--fs-lead); color: var(--preto-2); max-width: 52ch; }
.servico-hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-s); margin-top: var(--space-m); }

/* --- Foto de abertura da página de solução --------------------------------
   Uma foto do evento ao LADO da narrativa, não atrás dela.

   Banner de fundo foi descartado por três motivos concretos: o H1 daqui é
   escrito caractere a caractere pelo Typer e tem um <mark> amarelo no meio —
   texto que se monta sobre foto exige um véu escuro por cima para continuar
   legível, e véu é gradiente decorativo, que é justamente o que a paleta
   desta marca não usa. Além disso as fotos são verticais: esticadas numa
   faixa larga, sobra teto e corta gente.

   Ao lado, o tipo continua no branco onde ele funciona, a foto entra inteira
   na proporção em que foi tirada e a página reaproveita a mesma gramática de
   duas colunas que o "quem somos" da home já usa.
   -------------------------------------------------------------------------- */
.servico-hero__grid { display: grid; gap: var(--space-m); }
.servico-hero__foto { margin: 0; }
.servico-hero__quadro {
  aspect-ratio: 3 / 4; overflow: hidden; background: var(--branco-2);
}
.servico-hero__quadro img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

@media (min-width: 900px) {
  .servico-hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
    column-gap: var(--space-l);
    align-items: center;
  }
}
/* Abaixo de 900px a foto entra embaixo do texto, contida: em tamanho cheio ela
   empurraria os botões da abertura para fora da primeira tela. */
@media (max-width: 899px) {
  .servico-hero__foto { max-width: 240px; }
}

/* --------------------------------------------------------------------------
   RETRATO — foto de colaborador
   --------------------------------------------------------------------------
   Um só componente para os dois lugares onde o time aparece: os cards de
   "quem faz" das páginas de capacidade e o bloco "quem somos" da home.
   Sempre quadrado e recortado por object-fit, para que fotos de origens
   diferentes (estúdio, evento, avatar) fiquem no mesmo eixo.

   Quem ainda não tem foto entra com .retrato--sigla: bloco preto com as
   iniciais. É proposital — vazio se lê como erro, monograma se lê como
   decisão. Assim que a foto chegar, troque o <span> por um <img> e remova
   a classe modificadora.
   -------------------------------------------------------------------------- */
.retrato {
  aspect-ratio: 1 / 1; overflow: hidden; margin: 0;
  background: var(--branco-2);
}
.retrato img { width: 100%; height: 100%; object-fit: cover; display: block; }
.retrato--sigla {
  display: grid; place-items: center;
  background: var(--preto); color: var(--amarelo);
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.5rem, 4.5vw, 2.4rem); letter-spacing: 0.04em;
}

/* Quem faz — o time responsável pela frente */
.time__grid {
  display: grid; gap: var(--space-m);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr));
}
.time__card { border-top: 3px solid var(--preto); padding-top: var(--space-s); }
.time__card .retrato { margin-bottom: var(--space-s); }
.time__papel {
  display: inline-block; background: var(--amarelo);
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.14em;
  text-transform: uppercase; padding: 0.25rem 0.5rem; margin-bottom: 0.6rem;
}
.time__nome { font-size: 1.2rem; margin-bottom: 0.3rem; }
.time__desc { font-size: 0.92rem; color: var(--preto-2); margin: 0; }
.time__nota {
  margin-top: var(--space-m); font-family: var(--font-display);
  color: var(--cinza); border-left: 6px solid var(--amarelo);
  padding-left: var(--space-s); max-width: 56ch; font-size: 0.95rem;
}

/* --------------------------------------------------------------------------
   6.9 PÁGINA DE SOLUÇÃO — blocos do documento de conteúdo
   --------------------------------------------------------------------------
   As quatro páginas seguem a mesma arquitetura editorial: promessa, momento
   de compra, problema, atuação, modalidades, processo, entregáveis, limites,
   próximos passos e CTA. Estes blocos existem para essa sequência.
   -------------------------------------------------------------------------- */

/* Lista corrida de qualificação ("faz sentido quando…"). Duas colunas em tela
   larga porque são listas longas — em coluna única viram um paredão. */
.lista-marcada { display: grid; gap: 0.55rem; }
.lista-marcada li {
  position: relative; padding-left: 1.4rem;
  font-size: 0.97rem; color: var(--preto-2);
}
.lista-marcada li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 10px; height: 3px; background: var(--amarelo);
}
@media (min-width: 900px) {
  .lista-marcada--duas { grid-template-columns: 1fr 1fr; gap: 0.55rem var(--space-l); }
}

/* Os limites do escopo. Marcador e cor diferentes de propósito: esta lista diz
   o que NÃO entra, e ler igual à lista de entregáveis seria confuso. */
.lista-limites { display: grid; gap: 0.55rem; }
.lista-limites li {
  position: relative; padding-left: 1.4rem;
  font-size: 0.95rem; color: var(--cinza);
}
.lista-limites li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 10px; height: 2px; background: var(--linha);
}
@media (min-width: 900px) {
  .lista-limites--duas { grid-template-columns: 1fr 1fr; gap: 0.55rem var(--space-l); }
}

/* Modalidades e frentes: os caminhos dentro de cada solução. */
.modalidades { display: grid; gap: var(--space-m); }
@media (min-width: 900px) { .modalidades--duas { grid-template-columns: 1fr 1fr; } }

.modalidade {
  border-top: 3px solid var(--preto);
  padding-top: var(--space-s);
}
.modalidade__nome { font-size: 1.35rem; margin-bottom: 0.4rem; }
.modalidade__desc { color: var(--preto-2); font-size: 0.97rem; }
.modalidade__rotulo {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--cinza);
  margin: var(--space-s) 0 0.4rem;
}
/* Sub-modalidade: existe dentro de uma frente (ex.: Ativação de Base dentro de
   Receita da Base e CRM). O filete lateral marca a subordinação sem precisar
   de mais um nível de título. */
.submodalidade {
  border-left: 3px solid var(--amarelo);
  padding-left: var(--space-s);
  margin-top: var(--space-s);
}
.submodalidade__nome { font-size: 1.05rem; margin-bottom: 0.3rem; }

/* O parágrafo que fecha uma modalidade vem logo depois da lista e colava nela.
   Os itens da lista têm respiro entre si; a frase de fecho precisa de mais,
   senão lê como se fosse mais um item. */
.lista-marcada + .modalidade__desc { margin-top: var(--space-s); }

/* "Como funciona": as etapas numeradas. Reaproveita o desenho do .passo da
   home, mas sem o exploded view — aqui é leitura, não animação. */
.etapas { display: grid; gap: var(--space-m); counter-reset: etapa; }
@media (min-width: 720px)  { .etapas { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1080px) { .etapas--muitas { grid-template-columns: repeat(4, 1fr); } }
.etapa { border-top: 1px solid var(--linha); padding-top: var(--space-s); }
.etapa__num {
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.16em;
  display: inline-block; background: var(--amarelo); padding: 0.1rem 0.4rem;
  margin-bottom: 0.6rem;
}
.etapa__titulo { font-size: 1.05rem; margin-bottom: 0.4rem; }
.etapa p { color: var(--preto-2); font-size: 0.93rem; margin: 0; }

/* A frase que fecha um bloco — a honestidade sobre limites, o princípio de
   não criar dependência. São afirmações de postura, não de escopo. */
.principio {
  margin-top: var(--space-m);
  border-left: 6px solid var(--amarelo);
  padding-left: var(--space-m);
  font-size: var(--fs-lead); color: var(--preto);
  max-width: 52ch;
}

/* --------------------------------------------------------------------------
   6.10 PÁGINAS LEGAIS — política de privacidade e termos de uso
   --------------------------------------------------------------------------
   Documento corrido de leitura: medida estreita, hierarquia tipográfica
   simples, sem animação além do padrão do site. A régua amarela nos títulos
   e nos marcadores mantém a identidade sem competir com o texto.
   -------------------------------------------------------------------------- */
.legal-hero { padding: calc(var(--header-h) + var(--space-l)) 0 0; }
.legal-hero__title { font-size: var(--fs-h2); max-width: 22ch; margin-bottom: var(--space-s); }
.legal-hero__meta {
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--cinza);
}

/* A medida de leitura é limitada nos FILHOS, não no contêiner. O bloco também
   é .wrap: pôr max-width nele encolheria a própria caixa que o .wrap centraliza,
   e o texto ora ficava centrado (com margin auto), ora colado na borda (sem
   ela) — nos dois casos desalinhado do título, que segue a calha do site. */
.legal-doc > * { max-width: 68ch; }
.legal-doc h2 {
  font-size: 1.4rem; margin: var(--space-l) 0 var(--space-s);
  padding-top: var(--space-s); border-top: 3px solid var(--preto);
}
/* O primeiro título já tem o respiro da seção acima dele */
.legal-doc h2:first-child { margin-top: 0; }
.legal-doc h3 { font-size: 1.05rem; margin: var(--space-m) 0 0.4rem; }
.legal-doc p, .legal-doc li { color: var(--preto-2); font-size: 0.97rem; }
.legal-doc ul { display: grid; gap: 0.45rem; margin: 0.6rem 0 1em; }
.legal-doc ul li { position: relative; padding-left: 1.4rem; }
.legal-doc ul li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 10px; height: 3px; background: var(--amarelo);
}
.legal-doc a { text-decoration-color: var(--amarelo); text-decoration-thickness: 2px; }
.legal-doc strong { color: var(--preto); }

/* Resumo de abertura: o que o documento diz, em linguagem de gente */
.legal-resumo {
  border-left: 6px solid var(--amarelo); background: var(--branco-2);
  padding: var(--space-s) var(--space-m); margin: var(--space-m) 0 0;
}
.legal-resumo p { margin: 0; }

/* --------------------------------------------------------------------------
   7. RODAPÉ
   -------------------------------------------------------------------------- */
/* Rodapé de FAIXA, não de bloco: marca e navegação dividem uma linha, os
   dados cadastrais correm em outra. O aviso de cookies e de tratamento de
   dados saiu daqui — ele vive por extenso nas páginas de Privacidade e
   Termos, e repetido no rodapé só engordava a faixa com texto que ninguém lê
   duas vezes.

   O dock é fixo e paira sobre a página inteira: o fim do documento precisa
   reservar a faixa dele, senão a razão social e o CNPJ ficam atrás do dock. */
.site-footer {
  position: relative; z-index: 1;
  border-top: 3px solid var(--preto);
  padding-block: var(--space-m) calc(var(--space-m) + var(--dock-safe));
}
.site-footer__inner { display: grid; gap: var(--space-s); }
.site-footer__logo { height: 26px; width: auto; }

/* O menu é sempre horizontal. O wrap existe para telas estreitas, mas o vão
   VERTICAL é zero: se os links quebrarem em duas fileiras, elas não podem
   custar a altura de duas listas. */
.site-footer__links {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0 clamp(0.85rem, 1.8vw, 1.5rem);
}
.site-footer__links a {
  font-family: var(--font-display); font-size: 0.85rem;
  text-decoration: none; color: var(--preto-2);
  /* alvo de toque: com só a altura da linha, dava 19px */
  display: inline-flex; align-items: center; min-height: 44px;
}
.site-footer__links a:hover { box-shadow: inset 0 -3px 0 var(--amarelo); }
.site-footer__legal { font-family: var(--font-mono); font-size: 0.64rem; line-height: 1.7; letter-spacing: 0.05em; color: var(--cinza); margin: 0; }
.site-footer__legal a { color: inherit; text-decoration-color: var(--amarelo); text-decoration-thickness: 2px; }
@media (min-width: 900px) {
  /* Duas colunas, não três. Com os dados cadastrais numa terceira coluna eles
     espremiam a navegação até ~70px e os sete links viravam uma PILHA de sete
     fileiras — o oposto de um rodapé de faixa. Agora eles ocupam a largura
     inteira na linha de baixo e a navegação fica com todo o espaço restante. */
  .site-footer__inner { grid-template-columns: auto 1fr; align-items: center; }
  .site-footer__legal { grid-column: 1 / -1; }
}

/* --------------------------------------------------------------------------
   8. ACESSIBILIDADE — prefers-reduced-motion
   Sem animação de scroll: a linha aparece inteira, a seta some, os
   marcadores ficam todos acesos.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .produto--solucao.produto--entra { opacity: 1; transform: none; }
  .trail-pin { opacity: 1; }
}
.reduced-motion .trail__arrow { display: none; }
.reduced-motion .produto__media { position: static; }

/* --------------------------------------------------------------------------
   10. MAPA DO BRASIL NA HERO + POPUP DE CASES
   O mapa é uma cena WebGL de fundo transparente: mora numa coluna ao lado do
   título e some sem estardalhaço se o navegador não der conta. A tela do
   estado lista os clientes daquela UF agrupados por frente de atuação —
   mesma marcação usada na página /mapa-cases, então as classes
   .uf/.frente/.cliente/.case-ui vivem aqui e lá, em dois temas.
   -------------------------------------------------------------------------- */
/* PAINEL: números e mapa são UM bloco só, empilhado — a cena em cima, a lista
   logo abaixo dela. A última linha da lista pertence ao mapa, e é a
   proximidade entre os dois que deixa isso óbvio; não é preciso régua nenhuma
   por cima para amarrar o bloco. Antes o painel se dividia em duas colunas
   internas; agora quem divide é a hero (copy | painel), e aqui basta uma. */
.hero__painel {
  margin-top: var(--space-l);
  display: grid; gap: var(--space-m); align-items: start;
}

/* Linha viva: é a linha do MAPA dentro da lista. Em repouso mostra o total de
   estados; sob o cursor troca para a sigla + o estado, e a sigla ganha o
   amarelo da seleção — o mesmo amarelo que acende no mapa ao lado. */
.hero__viva dt {
  display: inline-block;
  padding: 0 0.12em;
  background: transparent;
  transition: background-color 0.18s var(--ease);
}
.hero__viva dd {
  font-family: var(--font-mono); font-size: var(--fs-eyebrow);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--cinza-2, var(--cinza)); line-height: 1.5;
}
.hero__viva.is-ativa dt { background: var(--amarelo); }
.hero__viva.is-ativa dd { color: var(--preto); }

.hero__mapa { position: relative; }
.hero__mapa-palco {
  width: 100%;
  height: clamp(300px, 46vh, 520px);
  /* touch-action: pan-y mantém a rolagem vertical no dedo — só dois dedos
     giram o mapa (ver girarComUmDedo em mapa3d.js) */
  touch-action: pan-y;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.hero__mapa-palco.is-pronto { opacity: 1; }

/* Convite comercial do mapa. Fica sobre o palco, ancorado no centro do estado
   que o cursor está tocando — o JS só escreve o `transform`, o resto é daqui.
   `pointer-events: none` é o detalhe que faz funcionar: sem isso o selo
   nasceria debaixo do ponteiro e roubaria o clique que abre a tela do estado,
   além de disparar um pisca-pisca de entra-e-sai no hover do próprio mapa. */
.hero__convite {
  position: absolute; top: 0; left: 0; z-index: 3;
  margin: 0; padding: 0.35rem 0.6rem;
  background: var(--amarelo); color: var(--preto);
  border: 2px solid var(--preto);
  font-family: var(--font-mono); font-size: var(--fs-eyebrow);
  letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap;
  pointer-events: none;
  opacity: 0; transition: opacity 0.18s var(--ease);
}
.hero__convite.is-on { opacity: 1; }
/* O selo é afordância de mouse: em tela de toque não há hover, e quem toca
   já abre a tela do estado, onde a mesma oferta está escrita por extenso. */
@media (hover: none) { .hero__convite { display: none; } }
.hero__mapa-palco canvas { display: block; }

/* Na hero de duas colunas a cena divide a coluna com a lista de números, então
   ela cede altura: é a única medida da hero que dá para encolher sem cortar
   texto. Em svh, não vh — no celular com barra retrátil o vh mente, e é
   justamente esta altura que decide se a hero cabe ou não em uma tela.
   (Precisa vir DEPOIS da regra base: mesma especificidade, ganha a última.) */
@media (min-width: 900px) {
  /* Na hero de duas colunas o painel não vem DEPOIS da copy, vem AO LADO: o
     topo da cena nasce na mesma altura do eyebrow, sem a margem que existia
     para separar os dois blocos empilhados. */
  .hero__painel {
    margin-top: 0;
    /* A faixa de números pede o tamanho que precisa; a cena fica com TODO o
       resto. Assim o mapa não tem altura própria: ele é o que sobra da altura
       da copy ao lado — e cresce sozinho em monitor maior.
       align-items volta a stretch (a base é start): sem isso o .hero__mapa
       encolhe até o conteúdo e o height:100% do palco não tem contra o que
       resolver. */
    grid-template-rows: minmax(0, 1fr) auto;
    align-items: stretch;
  }
  .hero__mapa { min-height: 0; }
  .hero__mapa-palco { height: 100%; min-height: 240px; }

  /* Na lista vertical a linha viva se anunciava pelo texto em mono/caixa alta.
     Na faixa horizontal isso quebra a leitura — são quatro rótulos lado a lado
     e um deles em outra fonte —, e o letter-spacing ainda empurrava o texto
     mais comprido ("São Paulo — 14 clientes") para três linhas, altura que é
     reservada de antemão e sai da cena. Aqui ela se iguala às outras três; o
     que sinaliza que está viva é o amarelo que acende na sigla. */
  .hero__viva dd {
    font-family: inherit; text-transform: none;
    font-size: 0.78rem; letter-spacing: 0; line-height: 1.35;
  }
}
/* Notebook baixo (1366×768 e afins): as folgas do painel encostam para a cena
   ficar com o máximo possível da altura da primeira tela. */
@media (min-width: 900px) and (max-height: 720px) {
  .hero__painel { gap: var(--space-s); }
  .hero__mapa-palco { min-height: 200px; }
}

/* -------------------------------------------------------- tela do estado
   Não é um modal: é a TELA daquele estado, recortada no formato da UF e
   crescendo até ocupar a viewport (portal-estado.js escreve o clip-path a
   cada quadro). Por isso ela é opaca, cobre tudo e não tem fundo escuro
   atrás — quando termina de abrir, é a página. */
.tela-estado {
  position: fixed; inset: 0; z-index: 200;
  background: var(--branco);
  overflow: hidden;
  /* clip-path é escrito pelo JS durante a transição; fora dela, some. */
}
.tela-estado[hidden] { display: none; }
/* Durante a expansão nada é clicável: evita acertar um botão no meio do voo. */
.tela-estado.em-transicao { pointer-events: none; }

.tela-estado__interior {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  /* a transform-origin é posta pelo JS EM CIMA do estado clicado: o conteúdo
     cresce de dentro dele, não do centro da tela */
  transform-origin: 50% 50%;
}

.tela-estado__topo {
  flex: none;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  padding-top: max(var(--space-s), env(safe-area-inset-top, 0px));
  border-bottom: 1px solid var(--linha);
}
.tela-estado__marcador {
  margin: 0; display: flex; align-items: center; gap: 0.6rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.05rem;
}
.tela-estado__uf {
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em;
  background: var(--amarelo); padding: 3px 7px; border-radius: 2px;
}
.tela-estado__fechar {
  flex: none; min-height: 44px; cursor: pointer;
  padding: 0.6rem 1.1rem;
  border: 2px solid var(--preto); border-radius: 2px;
  background: transparent;
  font-family: var(--font-display); font-weight: 700; font-size: 0.9rem;
}
.tela-estado__fechar:hover { background: var(--amarelo); }
.tela-estado__corpo {
  flex: 1 1 auto;
  overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-m);
  padding-bottom: max(var(--space-m), env(safe-area-inset-bottom, 0px));
}
/* O miolo tem medida de leitura, mas a tela é cheia. */
.tela-estado .uf,
.tela-estado__corpo > .case-ui__frente,
.tela-estado__corpo > .case-ui__cliente,
.tela-estado__corpo > .case-ui__resumo,
.tela-estado__corpo > .case-ui__acoes { max-width: 760px; margin-inline: auto; }
.tela-estado .case-ui__cliente { font-size: var(--fs-h2); }
/* O nome do estado já está no cabeçalho da tela: repeti-lo aqui seria ruído. */
.tela-estado .uf__nome { display: none; }

/* ---------------------------------------------------- um case, num slide
   A hierarquia é: a marca do cliente → de que frente é → QUEM é o cliente →
   onde e de quê → o que descobrimos. O nome do cliente é o título porque é ele que a pessoa
   reconhece; o título do case entra logo abaixo, como frase de abertura. */
/* A marca do cliente abre o slide. As logos chegam em proporções muito
   diferentes — de um brasão quadrado a uma assinatura larga e baixa —, e
   fixar só a altura faria a assinatura larga dominar a tela enquanto o brasão
   encolhia. Por isso o que se fixa é uma CAIXA (altura e largura) e o desenho
   se encaixa dentro dela: a marca larga esbarra na largura, a quadrada esbarra
   na altura, e as duas terminam com peso parecido. A caixa tem tamanho próprio
   mesmo antes de a imagem chegar, então nada pula quando ela carrega.
   Cliente sem logo não ganha moldura vazia — a linha simplesmente não existe. */
.case-ui__logo { margin: 0 0 var(--space-s); }
.case-ui__logo img {
  display: block; height: 56px; width: auto;
  max-width: min(100%, 220px);
  object-fit: contain; object-position: left center;
}
@media (max-width: 640px) {
  .case-ui__logo img { height: 44px; max-width: min(100%, 170px); }
}
.case-ui__frente {
  margin: 0; font-family: var(--font-mono); font-size: var(--fs-eyebrow);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--cinza);
}
.case-ui__cliente {
  margin: 0.5rem 0 0; font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-h3); line-height: 1.05; letter-spacing: -0.02em;
}
.case-ui__meta { margin: 0.4rem 0 0; font-size: 0.85rem; color: var(--cinza); }
.case-ui__titulo {
  margin: var(--space-s) 0 0; font-family: var(--font-display); font-weight: 700;
  font-size: 1.15rem; line-height: 1.25; letter-spacing: -0.01em;
  padding-top: var(--space-s); border-top: 3px solid var(--preto);
}
.case-ui__resumo { margin: 0.7rem 0 0; color: var(--preto-2); line-height: 1.6; }
.case-ui__corpo p { margin: 1rem 0 0; line-height: 1.7; color: var(--preto-2); }
/* Ressalva do case (dado em consolidação, anonimização): em voz baixa, mas
   presente — sumir com ela vira promessa que o case não cumpre. */
.case-ui__nota {
  margin: var(--space-s) 0 0; padding-left: 0.9rem; border-left: 2px solid var(--linha);
  font-size: 0.85rem; color: var(--cinza); line-height: 1.6;
}
.case-ui__externo { margin: var(--space-s) 0 0; font-size: 0.85rem; }
.case-ui__acoes { display: flex; flex-wrap: wrap; gap: var(--space-s); margin: var(--space-m) 0 0; }

/* -------------------------------------------------- cabeçalho do estado */
.uf__cabeca { margin: 0 0 var(--space-m); }
.uf__nome {
  margin: 0; font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-h3); line-height: 1.05; letter-spacing: -0.02em;
}
.uf__conta {
  margin: 0.4rem 0 0; font-family: var(--font-mono); font-size: var(--fs-eyebrow);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--cinza);
}

.metricas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-s); margin: var(--space-m) 0 0; padding: 0; list-style: none;
}
.metricas li { border-top: 3px solid var(--preto); padding-top: 0.5rem; }
.metricas b {
  display: block; font-family: var(--font-display); font-size: 1.4rem;
  line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance;
}
.metricas span { display: block; margin-top: 0.25rem; font-size: 0.75rem; color: var(--cinza); line-height: 1.35; }

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: var(--space-m) 0 0; padding: 0; list-style: none; }
.tags li { font-size: 0.72rem; color: var(--cinza); border: 1px solid var(--linha); border-radius: 999px; padding: 0.25rem 0.7rem; }

/* -------------------------------------------------------------- carrossel
   Um cliente por vez, e o case inteiro dentro do slide. A pista é um scroll
   horizontal com snap: no touch o arrasto já funciona sozinho e as setas são
   só um atalho de mouse. */
.carrossel { display: flex; flex-direction: column; }
.carrossel__pista {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  scroll-behavior: smooth;
  /* Os slides têm alturas diferentes. Alinhar no topo impede que o mais curto
     seja esticado, e o JS fixa a altura da pista na do slide visível — sem
     isso, um case curto termina com um vão do tamanho do case mais longo.
     `overflow-y: hidden` guarda os slides altos que estão fora de quadro. */
  align-items: flex-start;
  overflow-y: hidden;
  transition: height 0.35s var(--ease);
}
.carrossel__pista::-webkit-scrollbar { display: none; }
.carrossel__pista:focus-visible { outline: 3px solid var(--amarelo); outline-offset: 4px; }
.carrossel__slide { flex: 0 0 100%; min-width: 100%; scroll-snap-align: start; }
/* Barra de navegação no TOPO: quantos clientes há e como trocar, antes de
   começar a ler — não depois de rolar seis parágrafos. */
.carrossel__nav {
  display: flex; align-items: center; gap: var(--space-s);
  margin-bottom: var(--space-s); padding-bottom: var(--space-s);
  border-bottom: 1px solid var(--linha);
}
.carrossel__setas { display: flex; gap: 0.4rem; margin-left: auto; }
.carrossel__seta {
  width: 44px; height: 44px; cursor: pointer;
  border: 2px solid var(--preto); border-radius: 2px; background: transparent;
  font-size: 1rem; line-height: 1;
  transition: background-color 0.18s var(--ease), opacity 0.18s var(--ease);
}
.carrossel__seta:hover:not(:disabled) { background: var(--amarelo); }
.carrossel__seta:disabled { opacity: 0.25; cursor: default; }
.carrossel__conta { font-family: var(--font-mono); font-size: 0.78rem; color: var(--cinza); flex: none; }
/* São Paulo tem 14 clientes, ou seja, 14 pontinhos. Eles encolhem em vez de
   estourar a linha — largura fixa só até onde couber. */
.carrossel__pontos { display: flex; flex-wrap: wrap; gap: 0.25rem; min-width: 0; }
.carrossel__pontos button {
  flex: 1 1 6px; min-width: 6px; max-width: 26px;
  height: 4px; padding: 0; border: 0; cursor: pointer;
  background: var(--linha); transition: background-color 0.18s var(--ease);
}
.carrossel__pontos button[aria-current="true"] { background: var(--preto); }

/* Cliente cujo case ainda não foi escrito: o slide diz isso, em voz baixa. */
.case-ui__breve {
  margin: var(--space-s) 0 0; padding-top: var(--space-s);
  border-top: 1px solid var(--linha);
  max-width: 62ch; color: var(--cinza); line-height: 1.6;
}

@media (prefers-reduced-motion: reduce) {
  .hero__mapa-palco { opacity: 1; }
  .carrossel__pista { scroll-behavior: auto; transition: none; }
}

/* --------------------------------------------------------------------------
   INTRO — logo (ícone + proxima). Leve: só transform + opacity.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "AproximaHand";
  src: url("assets/fonts/Caveat-Variable.ttf") format("truetype");
  font-weight: 400 700;
  font-style: normal;
  font-display: block;
}

.intro {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  place-items: center;
  overflow: hidden; /* evita scroll horizontal durante a queda das letras */
  background: var(--branco);
  color: var(--preto);
  padding:
    max(0.5rem, env(safe-area-inset-top))
    max(0.75rem, env(safe-area-inset-right))
    max(0.5rem, env(safe-area-inset-bottom))
    max(0.75rem, env(safe-area-inset-left));
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.intro.is-out {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.intro__stage {
  display: grid;
  place-items: center;
  width: min(100%, 36rem);
  transform: translateY(-2vh);
}
.intro__wordmark {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.1em;
  max-width: 100%;
  min-height: clamp(64px, 14vw, 110px);
}

.intro__mark {
  width: clamp(44px, 11vw, 78px);
  height: auto;
  flex: none;
  overflow: visible;
  opacity: 0;
  transform: translate3d(0, -24vh, 0) rotate(-8deg);
}
.intro__mark-l { fill: var(--amarelo); }
.intro__mark-r { fill: var(--ambar); }
.intro__mark-stroke {
  stroke: var(--preto);
  stroke-width: 2.4;
  stroke-linejoin: round;
}
.intro.is-drop .intro__mark {
  animation: intro-drop 0.55s cubic-bezier(0.22, 1.15, 0.36, 1) forwards;
}
@keyframes intro-drop {
  0%   { opacity: 0; transform: translate3d(0, -24vh, 0) rotate(-8deg); }
  55%  { opacity: 1; transform: translate3d(0, 6px, 0) rotate(2deg); }
  78%  { transform: translate3d(0, -3px, 0) rotate(-1deg); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); }
}

.intro__letters {
  margin: 0;
  font-family: "AproximaHand", "Segoe Print", "Bradley Hand", cursive;
  /* Em tela estreita escala por vw para não estourar a largura */
  font-size: clamp(1.85rem, 10.5vw, 4.35rem);
  font-weight: 600;
  line-height: 0.9;
  letter-spacing: -0.01em;
  color: var(--preto);
  white-space: nowrap;
  max-width: 100%;
}
.intro__letter {
  display: inline-block;
  opacity: 0;
  transform-origin: 50% 100%;
  --dx: 0px;
  --dy: -14vh;
  --rot: 0deg;
  transform: translate3d(var(--dx), var(--dy), 0) rotate(var(--rot));
}
.intro__letter[data-letter="r"] { --dx: -0.4em; --dy: -11vh; --rot: -6deg; }
.intro__letter[data-letter="o"] { --dx: 0px; --dy: -15vh; --rot: 4deg; }
.intro__letter[data-letter="x"] { --dx: 0.35em; --dy: -11vh; --rot: 6deg; }
.intro__letter[data-letter="i"] { --dx: 0px; --dy: -16vh; --rot: 0deg; }
.intro__letter[data-letter="m"] { --dx: 0px; --dy: -12vh; --rot: -3deg; }
.intro__letter[data-letter="a"] { --dx: 0px; --dy: -9vh; --rot: 2deg; }

.intro.is-sign .intro__letter[data-letter="p"] { animation: intro-letter 0.4s cubic-bezier(0.22, 1.2, 0.36, 1) 0.16s forwards; }
.intro.is-sign .intro__letter[data-letter="r"] { animation: intro-letter 0.4s cubic-bezier(0.22, 1.2, 0.36, 1) 0.22s forwards; }
.intro.is-sign .intro__letter[data-letter="o"] { animation: intro-letter 0.42s cubic-bezier(0.22, 1.25, 0.36, 1) 0.28s forwards; }
.intro.is-sign .intro__letter[data-letter="x"] { animation: intro-letter 0.4s cubic-bezier(0.22, 1.2, 0.36, 1) 0.34s forwards; }
.intro.is-sign .intro__letter[data-letter="i"] { animation: intro-letter 0.36s cubic-bezier(0.22, 1.15, 0.36, 1) 0.40s forwards; }
.intro.is-sign .intro__letter[data-letter="m"] { animation: intro-letter 0.42s cubic-bezier(0.2, 1.2, 0.36, 1) 0.46s forwards; }
.intro.is-sign .intro__letter[data-letter="a"] { animation: intro-letter 0.38s cubic-bezier(0.22, 1.15, 0.36, 1) 0.52s forwards; }

@keyframes intro-letter {
  0%   { opacity: 0; transform: translate3d(var(--dx), var(--dy), 0) rotate(var(--rot)); }
  55%  { opacity: 1; transform: translate3d(0, 4px, 0) rotate(0deg) scale(1.02, 0.97); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
}

.intro.is-settled .intro__mark,
.intro.is-settled .intro__letter {
  animation: none !important;
  opacity: 1;
  transform: none;
}

.intro__skip {
  position: absolute;
  right: max(0.5rem, env(safe-area-inset-right));
  bottom: max(0.5rem, env(safe-area-inset-bottom));
  min-width: 44px;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cinza);
  background: transparent;
  border: 0;
  padding: 0.75rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.intro__skip:hover { color: var(--preto); }

body.is-intro {
  overflow: hidden;
  height: 100%;
  height: 100dvh;
}
body.is-intro .site-header,
body.is-intro .dock {
  visibility: hidden;
}

/* Celular / tablet estreito: wordmark cabe, queda mais curta (barra do browser) */
@media (max-width: 719px) {
  .intro__stage { transform: none; }
  .intro__mark {
    width: clamp(40px, 12vw, 52px);
    transform: translate3d(0, -16vh, 0) rotate(-6deg);
  }
  .intro.is-drop .intro__mark {
    animation: intro-drop-mobile 0.48s cubic-bezier(0.22, 1.15, 0.36, 1) forwards;
  }
  @keyframes intro-drop-mobile {
    0%   { opacity: 0; transform: translate3d(0, -16vh, 0) rotate(-6deg); }
    55%  { opacity: 1; transform: translate3d(0, 5px, 0) rotate(1.5deg); }
    78%  { transform: translate3d(0, -2px, 0) rotate(-0.5deg); }
    100% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); }
  }
  .intro__letter { --dy: -10vh; }
  .intro__letter[data-letter="r"] { --dx: -0.28em; --dy: -8vh; }
  .intro__letter[data-letter="o"] { --dy: -11vh; }
  .intro__letter[data-letter="x"] { --dx: 0.25em; --dy: -8vh; }
  .intro__letter[data-letter="i"] { --dy: -12vh; }
  .intro__letter[data-letter="m"] { --dy: -9vh; }
  .intro__letter[data-letter="a"] { --dy: -7vh; }
  .intro.is-sign .intro__letter[data-letter="p"],
  .intro.is-sign .intro__letter[data-letter="r"],
  .intro.is-sign .intro__letter[data-letter="o"],
  .intro.is-sign .intro__letter[data-letter="x"],
  .intro.is-sign .intro__letter[data-letter="i"],
  .intro.is-sign .intro__letter[data-letter="m"],
  .intro.is-sign .intro__letter[data-letter="a"] {
    animation-duration: 0.34s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .intro__mark,
  .intro__letter {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* --------------------------------------------------------------------------
   9. IMPRESSÃO
   -------------------------------------------------------------------------- */
@media print {
  .intro, .trail, .site-header, .hero__scroll, .dock, .hero__mapa, .tela-estado { display: none !important; }
  body { background: #fff; }
  .modo--exec, .contato__card { background: #fff !important; color: #000 !important; border: 2px solid #000; }
  .contato__card .contato__fine,
  .contato__card .contato__text { color: #000 !important; }
}
