/* ============================================================
   UPWINS · /aidd
   Layout das seções desta página. Reset, tokens, botões, header,
   acordeão, contato, faixa de rota, rodapé, CTA fixa e reveal moram
   em assets/, que precisa vir antes.

   REGRA DA PÁGINA
   Uma família de layout por seção: nenhuma repete o desenho de outra.
   A peça assinatura é #matriz, o único bloco invertido (regra "um tema
   por página"). Todo o resto vive no papel claro.

   O vocabulário visual vem de duas fontes que se somam:
   - o sistema Upwins (azul único, dois raios, fio de 1px, sem hype);
   - a leitura de end.game: rótulo em versalete com fio que corre até a
     margem, número de ordem no canto do cartão, textura milimetrada e
     uma matriz que diz o processo inteiro sem parágrafo.
   ============================================================ */

/* ============================================================
   RESKIN BMW CORPORATE (ver DESIGN-bmw.md) — escopo: só /aidd
   Troca de papel visual, nada mais. assets/tokens.css e
   assets/base.css continuam intocados e servindo /ai-first e
   /builder no sistema Upwins original; esta folha carrega por
   último, então os mesmos nomes de custom property aqui vencem
   só nesta página. Estrutura, copy e interação (matriz, jornada
   presa, SVGs de #contraste) não mudam — só cor, tipografia,
   raio e elevação.
   ============================================================ */
:root {
  color-scheme: light;

  /* Acento único: era branco/preto (regra Upwins), agora é o azul
     corporativo BMW — a única cor de ação da página. */
  --accent:        #1c69d4;
  --accent-strong: #1c69d4;
  --accent-hover:  #0653b6;
  --accent-wash:   rgba(28, 105, 212, .08);
  --on-accent:     #ffffff;

  /* Papel e superfícies: claro no lugar do navy escuro. */
  --canvas:          #ffffff;
  --surface:         #fafafa;
  --surface-2:       #ebebeb;
  --hairline:        #e6e6e6;
  --hairline-strong: #cccccc;

  /* Texto */
  --ink:   #262626;
  --body:  #3c3c3c;
  --muted: #6b6b6b;

  /* Azul claro só para dentro do bloco invertido (#matriz), onde o
     texto e os ícones precisam ler sobre o navy escuro do hero band. */
  --blue-300: color-mix(in srgb, #1c69d4 45%, white);

  --good:  #22c55e;
  --alert: #dc2626;

  /* Bloco invertido: era a rampa navy da marca Upwins; vira o hero
     band escuro do BMW corporate — mesmo papel (o único tema escuro
     da página), cor do sistema novo. */
  --inv-bg:   #1a2129;
  --inv-bg-2: #262e38;
  --inv-ink:  #ffffff;
  --inv-body: #bbbbbb;

  /* BMW nunca usa sombra: profundidade vem de contraste de cor-bloco
     e fotografia, não de elevação. Zerar aqui desliga todo hover com
     box-shadow: var(--shadow-*) da página inteira, sem editar cada
     regra. */
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;

  /* O vidro (header solto, menu mobile, CTA fixa) vem de assets/base.css.
     BMW não usa blur nem transparência, então a "camada de vidro" vira
     mobília chapada no papel claro — mesmo raciocínio do shadow acima. */
  --glass-bg:        #ffffff;
  --glass-solid:     #ffffff;
  --glass-border:    var(--hairline-strong);
  --glass-highlight: transparent;
  --glass-shadow:    none;
  --glass-blur:      none;

  /* BMW Type Next Latin é licenciada à BMW; Inter é o substituto
     documentado, nos pesos 700/300 do par que é a assinatura do
     sistema. font-mono segue Geist Mono: é vocabulário próprio desta
     página (rótulo em versalete, herdado da leitura de end.game), não
     parte do sistema BMW, e por isso não entra na troca. */
  --font-sans: "Inter", "BMW Type Next Latin", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Raio único: 0px no que está no fluxo e no que flutua — "retangular
     para tudo" é a regra BMW, substituindo os dois raios do sistema
     Upwins. Os poucos círculos da página (setor__icone, modulo__num,
     spinner do botão) usam border-radius:50% direto na regra, fora
     deste token, e continuam circulares: é a única exceção que a BMW
     também abre, para botão de ícone. */
  --radius:       0px;
  --radius-float: 0px;
}

/* ---------- TIPOGRAFIA: o contraste 700/300 ----------
   Peso 500 está fora do sistema BMW (weight 500 is absent). Os pesos
   500/600/900 que o sistema Upwins usava viram 700 (títulos, rótulos
   e ênfase) ou 400 (papéis neutros, como nav-link e caption), nunca
   500. h1/h2/h3 e os componentes de assets/base.css são sobrescritos
   aqui porque essa folha carrega por último. */
h1, h2, h3 { font-weight: 700; letter-spacing: 0; }
.nav__link { font-weight: 400; }
.btn { font-weight: 700; }
.faq__q { font-weight: 700; }
.link-arrow { font-weight: 700; }
.field__label { font-weight: 700; }

/* ---------- RÓTULO DE SEÇÃO ----------
   Versalete em mono, com um fio que corre da etiqueta até a margem do
   shell. Abre toda seção e é o que dá cadência à página: o olho aprende
   que ali começa assunto novo. */
.rotulo {
  display: flex; align-items: center; gap: 1rem;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.25rem;
}
.rotulo::after {
  content: ""; flex: 1 1 2rem; min-width: 0; height: 1px; background: var(--hairline-strong);
}
.rotulo--inv { color: var(--inv-body); }
.rotulo--inv::after { background: var(--inv-line); }

@media (max-width: 600px) {
  .rotulo {
    flex-wrap: wrap;
    gap: .5rem 1rem;
    line-height: 1.4;
  }
}

/* ============================================================
   1 · HERO · centralizado + faixa de métricas

   Papel liso, de propósito. A primeira versão tinha uma grade milimetrada
   de fundo, justificada como "antecipa a matriz", o que é enfeite com
   desculpa, não função. A grade só significa alguma coisa em #matriz, que
   é de fato uma superfície de medição; espalhada pelo hero ela vira a
   textura genérica que aparece em todo site de IA, exatamente o que a
   direção da marca proíbe.

   O hero já tem estrutura sua para se sustentar: o fio do rótulo, a régua
   no acento sob o título, o fio acima das métricas e a coluna de números.

   .hero__flow é a exceção pedida explicitamente: linhas convergindo para
   um ponto único, na mesma cor do --accent que já assina o fio sob o
   título. A leitura pretendida é "muita execução convergindo para um
   ponto de decisão", eco do "o agente executa, você julga" de #matriz,
   não textura solta. Fica atrás do texto, em opacidade baixa, some sob
   prefers-reduced-motion e não compete com a hierarquia do texto.
   ============================================================ */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(4.5rem, 3rem + 7vw, 8.5rem) clamp(3.5rem, 2rem + 5vw, 6rem);
  border-bottom: 1px solid var(--hairline);
}

.hero__flow {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  text-align: center;
}

/* O .rotulo é a etiqueta com fio que abre toda seção, sempre à esquerda
   — aqui não, porque o resto do hero é centralizado e o fio correndo
   para a margem ficaria puxando para um lado só. Só no hero: label
   centralizado, sem o fio. */
.hero__inner .rotulo {
  justify-content: center;
}
.hero__inner .rotulo::after {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .hero__flow { display: none; }
}

.hero__title {
  font-size: var(--fs-display);
  max-width: 20ch;
  margin-inline: auto;
  font-weight: 700;
  text-wrap: balance;
}
.hero__title em {
  font-style: normal; font-weight: 700;
  color: var(--accent);
}

/* Fio sob o título: cresce do centro quando o hero entra, para acompanhar
   o texto agora centralizado. */
.hero__rule {
  display: block; height: 3px; width: min(320px, 42%);
  margin-top: clamp(1.5rem, 2.5vw, 2.25rem);
  margin-inline: auto;
  background: var(--accent);
  transform-origin: center center;
}
@media (prefers-reduced-motion: no-preference) {
  .js .hero__rule { transform: scaleX(0); transition: transform .8s .25s var(--ease); }
  .js .hero__rule.is-revealed { transform: scaleX(1); }
}

.hero__lead {
  margin-top: clamp(1.5rem, 2.5vw, 2.25rem);
  margin-inline: auto;
  font-size: var(--fs-lead); color: var(--body);
  max-width: 62ch;
}
.hero__actions {
  margin-top: clamp(2rem, 3vw, 2.75rem);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1rem 2rem;
}

@media (max-width: 520px) {
  .hero__title { max-width: none; }
}

/* ============================================================
   3 · PILARES · cartões numerados, um largo e três estreitos
   O primeiro é largo porque Curadoria sustenta os outros três; a
   hierarquia do texto aparece na largura, não em cor de destaque.
   ============================================================ */
.pilares { border-bottom: 1px solid var(--hairline); }
.pilares__grade {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  display: grid; gap: clamp(1rem, 1.8vw, 1.5rem);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.pilar {
  position: relative; isolation: isolate; overflow: hidden;
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  background: var(--canvas);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
/* Textura milimetrada só no cartão largo, e só no canto direito, apagando
   para a esquerda. É ele que tem coluna vazia à direita; nos estreitos a
   grade passaria por baixo do texto, então lá não existe. */
.pilar--largo::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image:
    linear-gradient(to right, var(--hairline) 1px, transparent 1px),
    linear-gradient(to bottom, var(--hairline) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(to left, #000, transparent 62%);
  mask-image: linear-gradient(to left, #000, transparent 62%);
}
.pilar:hover { border-color: var(--accent); box-shadow: var(--shadow-md); }
.pilar--largo { grid-column: 1 / -1; }

.pilar__num {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--accent); letter-spacing: .08em;
  margin-bottom: 1.5rem;
}
.pilar__titulo { font-size: var(--fs-h3); }
.pilar__texto { margin-top: .875rem; font-size: var(--fs-sm); color: var(--body); max-width: 52ch; }

.pilar__lista {
  margin-top: 1.5rem; padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
  display: grid; gap: .55rem;
  list-style: none;
}
.pilar__lista li {
  position: relative; padding-left: 1.1rem;
  font-size: var(--fs-sm); color: var(--muted);
}
.pilar__lista li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 6px; height: 1px; background: var(--accent);
}
.pilar--largo .pilar__lista {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .55rem 2rem;
}

/* Abaixo de 860px o cartão largo também fica estreito: sem coluna vazia,
   não há onde a grade caber sem encostar no texto. */
@media (max-width: 860px) {
  .pilares__grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pilar--largo .pilar__lista { grid-template-columns: 1fr; }
  .pilar--largo::before { display: none; }
}
@media (max-width: 560px) {
  .pilares__grade { grid-template-columns: 1fr; }
}

/* ============================================================
   4 · MATRIZ · bloco invertido, grade milimetrada, full-bleed
   A peça assinatura. É o único tema invertido da página e a única
   seção que sangra até a borda da tela.

   O desenho responde a uma pergunta só: onde o agente entra e onde a
   pessoa continua respondendo. Duas famílias de chip, uma linha divisória
   entre elas, e o eixo escrito na vertical à esquerda para o rótulo não
   roubar coluna do conteúdo.
   ============================================================ */
.matriz {
  position: relative; isolation: isolate;
  background: var(--inv-bg);
  color: var(--inv-body);
  padding-block: var(--section-y);
  border-block: 1px solid var(--inv-line);
}
.matriz::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.07) 1px, transparent 1px);
  background-size: 40px 40px;
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 45%, #000, transparent);
  mask-image: radial-gradient(ellipse 80% 70% at 50% 45%, #000, transparent);
}
.matriz__titulo {
  font-size: var(--fs-h2); color: var(--inv-ink);
  max-width: 20ch; text-wrap: balance;
}
.matriz__lead {
  margin-top: 1.25rem; font-size: var(--fs-lead);
  color: var(--inv-body); max-width: 62ch;
}

/* No estreito a matriz rola sozinha em vez de espremer seis colunas.
   O container é focável para quem navega por teclado alcançar a rolagem. */
.matriz__scroll {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  overflow-x: auto;
  padding-bottom: .5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--inv-line-hover) transparent;
}
.matriz__scroll:focus-visible { outline: 2px solid var(--blue-300); outline-offset: 6px; }

.matriz__grade {
  display: grid;
  grid-template-columns: max-content repeat(7, minmax(122px, 1fr));
  gap: 6px 8px;
  min-width: 980px;
}

/* Eixos: escritos na vertical, de baixo para cima, colados na coluna
   de chips que rotulam. Cada um ocupa exatamente as linhas do seu bloco.
   O rótulo é curto de propósito: escrito na vertical, ele é quem define a
   altura mínima do bloco, e um rótulo longo desalinharia o ritmo das linhas. */
.matriz__eixo {
  writing-mode: vertical-rl; transform: rotate(180deg);
  place-self: stretch;
  display: grid; place-items: center;
  min-height: 0;
  padding-inline: .25rem;
  font-family: var(--font-mono); font-size: .6875rem;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--inv-body); opacity: .65;
  white-space: nowrap;
}
.matriz__eixo--setor  { grid-row: 1; opacity: .5; }
.matriz__eixo--fluxo  { grid-row: 2 / span 2; opacity: .5; }
.matriz__eixo--agente { grid-row: 4 / span 3; color: var(--blue-300); opacity: 1; }
.matriz__eixo--humano { grid-row: 8 / span 2; }

/* Fio que atravessa a grade inteira separando o que é delegado do que não
   é. É a única linha da matriz e ela existe para ser lida como fronteira. */
.matriz__corte {
  grid-column: 1 / -1; grid-row: 7;
  height: 1px; background: var(--inv-line-hover);
  margin-block: .5rem;
}

/* BANDA 1 · SETOR · quem responde pela coluna.
   É a porta de entrada da matriz. A leitura vem da referência: lá a grade
   abre por papel (product manager, architect, developer…) antes de abrir por
   fase, e é o que faz a peça funcionar, porque empresa se organiza por área.
   O leitor acha a própria caixa primeiro e só depois lê o que se delega.

   O que veio foi a estrutura, não o desenho: o ícone é traço de 1.5px no azul
   da marca dentro de um círculo de fio, sem preenchimento e sem sombra. */
.setor {
  display: grid; justify-items: center; gap: .55rem;
  transition: border-color .25s var(--ease);
  align-content: end;
  padding-bottom: .75rem;
  border-bottom: 1px solid var(--inv-line);
}
.setor__icone {
  width: 40px; height: 40px; padding: 9px;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
  border: 1px solid var(--inv-line);
  border-radius: 50%;
  color: var(--blue-300);
}
.setor__nome {
  font-family: var(--font-mono); font-size: .6875rem;
  letter-spacing: .08em; text-transform: uppercase;
  text-align: center; line-height: 1.35;
  color: var(--inv-ink);
}

/* BANDA 2 · FLUXO · dois níveis, grupo e fase.
   O grupo é uma barra que atravessa as colunas do seu trecho e a fase é a
   caixa de cada coluna. Os dois níveis existem porque o ciclo tem quatro
   momentos e sete postos: sem a barra, as sete fases lidas em fila parecem
   sete etapas independentes, que é justamente o erro que a matriz corrige. */
.matriz__grupo {
  grid-row: 2;
  transition: background-color .25s var(--ease);
  padding: .45rem .75rem;
  background: color-mix(in srgb, var(--blue-300) 26%, transparent);
  border-radius: var(--radius);
  font-family: var(--font-mono); font-size: .6875rem;
  font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; text-align: center;
  color: var(--inv-ink);
}
.matriz__grupo--1 { grid-column: 2 / span 1; }
.matriz__grupo--2 { grid-column: 3 / span 2; }
.matriz__grupo--3 { grid-column: 5 / span 2; }
.matriz__grupo--4 { grid-column: 7 / span 2; }

.matriz__fase {
  grid-row: 3;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
  padding: .7rem .75rem;
  background: color-mix(in srgb, var(--blue-300) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue-300) 30%, transparent);
  border-radius: var(--radius);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; text-align: center;
  color: var(--inv-ink);
}

.chip {
  display: grid; place-items: center;
  padding: .7rem .6rem;
  background: var(--inv-bg-2);
  border: 1px solid var(--inv-line);
  border-radius: var(--radius);
  min-height: 3.5rem;
  font-size: var(--fs-xs); color: var(--inv-ink);
  text-align: center; line-height: 1.3;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.chip:hover { border-color: var(--inv-line-hover); }

/* O que a pessoa decide é vazado, não preenchido: o contorno diz que
   ali não há automação, só responsabilidade. */
.chip--humano {
  background: transparent;
  border-color: var(--inv-line-hover);
  color: var(--inv-body);
}
.chip--humano:hover { background: color-mix(in srgb, var(--blue-300) 8%, transparent); }

/* DESTAQUE DE COLUNA
   Passar o mouse em qualquer célula acende a coluna inteira, do setor até
   o último chip. É o que a matriz pede: a coluna é a unidade de leitura,
   e ler uma célula sozinha não responde nada. O índice é calculado em
   main.js, porque coluna de grid não é elemento e nenhum seletor a alcança.

   O acender é um degrau de luz, não uma cor nova: o mesmo azul da marca,
   com mais presença. Fora do hover a matriz continua exatamente como está. */
.setor.is-coluna-ativa,
.matriz__fase.is-coluna-ativa,
.matriz__grupo.is-coluna-ativa,
.chip.is-coluna-ativa {
  transition: border-color .25s var(--ease), background-color .25s var(--ease), color .25s var(--ease);
}
.setor.is-coluna-ativa { border-bottom-color: var(--blue-300); }
.setor.is-coluna-ativa .setor__icone {
  border-color: var(--blue-300);
  background: color-mix(in srgb, var(--blue-300) 12%, transparent);
}
.matriz__grupo.is-coluna-ativa { background: color-mix(in srgb, var(--blue-300) 40%, transparent); }
.matriz__fase.is-coluna-ativa {
  background: color-mix(in srgb, var(--blue-300) 30%, transparent);
  border-color: color-mix(in srgb, var(--blue-300) 55%, transparent);
}
.chip.is-coluna-ativa {
  background: color-mix(in srgb, var(--blue-300) 12%, var(--inv-bg-2));
  border-color: var(--inv-line-hover);
  color: var(--inv-ink);
}
.chip--humano.is-coluna-ativa {
  background: color-mix(in srgb, var(--blue-300) 8%, transparent);
  border-color: color-mix(in srgb, var(--blue-300) 60%, transparent);
  color: var(--inv-ink);
}

.matriz__arraste {
  display: none;
  margin-top: .875rem;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--blue-300);
}

/* A matriz é mais larga que qualquer telefone. Onde ela passa a rolar, o
   aviso aparece: o corte na borda direita sozinho não é affordance. */
@media (max-width: 1060px) {
  .matriz__arraste { display: block; }
}
@media (max-width: 560px) {
  .matriz__grade { grid-template-columns: max-content repeat(7, minmax(112px, 1fr)); min-width: 900px; }
  .setor__icone { width: 34px; height: 34px; padding: 7px; }
}

/* ============================================================
   5 · JORNADA · duas colunas pareadas: o programa e o que fica

   Eram duas seções. Empilhadas, o leitor lia o programa, esquecia, e
   recomeçava do zero no inventário. Lado a lado a relação fica explícita:
   trabalho de um lado, artefato do outro, e a coluna da direita termina no
   CTA. A ficha técnica sobe para antes das colunas porque vale para as duas.

   As duas colunas usam listas numeradas com o mesmo fio horizontal, o que
   é de propósito: são o mesmo inventário lido de dois ângulos. O que as
   separa é o peso do texto, não um desenho novo.
   ============================================================ */
.jornada { border-bottom: 1px solid var(--hairline); }

/* O cabeçalho da seção mora dentro do bloco preso, então ele acompanha os
   seis passos em vez de sair de tela quando eles começam. No repouso não há
   pin nenhum e ele é o cabeçalho comum de qualquer seção.

   Preso, o conjunto precisa caber numa tela junto com as duas colunas, e é
   por isso que o ar entre o cabeçalho e a grade encolhe: o lead continua
   inteiro, mas para de gastar a altura de uma seção solta. */
.jornada.is-stepped .jornada__grid {
  margin-top: clamp(1.5rem, 2.4vw, 2.25rem);
}

/* O h2 solto tem max-width de 20ch e quebra em três linhas, o que custa 158px
   de uma tela que precisa caber cabeçalho e duas colunas. Preso ele ganha
   largura e cai para duas linhas: mesma tipografia, mesmo peso, 52px a menos.
   Não é redução de escala, é quebra melhor. */
.jornada.is-stepped .jornada__cabecalho .section__title { max-width: 38ch; }
.jornada.is-stepped .jornada__cabecalho .section__lead  { max-width: 68ch; }

/* A árvore respirava em line-height 2 porque era o único conteúdo da coluna.
   Dentro do bloco preso ela divide a altura com o cabeçalho. */
.jornada.is-stepped .acervo__arvore { line-height: 1.8; }
.jornada.is-stepped .acervo__nota {
  margin-top: clamp(1rem, 1.6vw, 1.25rem);
  padding-top: clamp(.85rem, 1.4vw, 1rem);
}

/* ---------- O BLOCO PRESO ----------
   O trilho é só altura: um viewport para o painel morar mais o percurso de
   rolagem dos seis passos. Os dois números ficam em custom property porque
   afinar o ritmo é afinar --por-passo, não recalcular um valor composto.

   NADA DISSO EXISTE SEM .is-stepped. No repouso o trilho não tem altura
   extra, o painel não gruda e todos os resumos estão abertos: a seção é
   idêntica à lista que ela era antes. Quem liga o modo é o script, e só
   quando há JS, largura de sobra e nenhum pedido de movimento reduzido. */
.jornada__trilho { position: relative; }

.jornada.is-stepped .jornada__trilho {
  --passos: 7;
  --por-passo: 42vh;
  min-height: calc(100vh + var(--passos) * var(--por-passo));
}

.jornada.is-stepped .jornada__pin {
  position: sticky;
  /* 72px do header, mais ar para o rótulo da coluna não colar nele. */
  top: 88px;
}

/* Seis faixas de mesma altura cobrindo o PERCURSO PRESO, que é o trilho
   menos a altura do painel: passado esse ponto o painel solta e sai de
   tela. Dividir o trilho inteiro punha o centro da última sentinela fora
   do percurso, e o passo 6 só acendia com o painel já subindo.

   --pin-h é medido em main.js com ResizeObserver, porque a altura do
   painel muda com o resumo que abre e com a largura da coluna. O fallback
   de 45vh só existe para o intervalo entre a primeira pintura e a medição.

   Sem largura e sem conteúdo: elas só precisam cruzar a faixa de 1px no
   meio da tela que o observer recorta. */
.jornada__sentinelas {
  position: absolute;
  top: 0; left: 0; width: 1px;
  bottom: calc(var(--pin-h, 45vh) + 88px);
  display: none; flex-direction: column;
  pointer-events: none;
}
.jornada.is-stepped .jornada__sentinelas { display: flex; }
.jornada__sentinela { flex: 1 0 0; }

/* ---------- OS TRÊS ESTADOS ----------
   Futuro apaga, ativo abre, passado FICA ACESO. O terceiro é o que separa
   um rastro de progresso de um holofote solitário: o leitor precisa ver
   onde esteve, não só onde está.

   O ativo não é preenchido no acento cheio, que na referência é o desenho
   dela: aqui o acento sólido é do botão, e a régua da casa para "este é o
   bloco corrente" é superfície mais fio. */
.jornada.is-stepped .modulo {
  opacity: .4;
  transition: opacity .35s var(--ease);
}
.jornada.is-stepped .modulo.is-passado,
.jornada.is-stepped .modulo.is-ativo { opacity: 1; }

.jornada.is-stepped .modulo__resumo {
  max-height: 0; overflow: hidden;
  opacity: 0;
  margin-top: 0;
  transition: max-height .35s var(--ease), opacity .25s var(--ease), margin-top .35s var(--ease);
}
/* 2em cortava: o resumo é fs-sm com line-height 1.5, então duas linhas pedem
   3em e em coluna estreita (perto dos 900px) vários resumos quebram em duas.
   Com overflow hidden a segunda linha sumia. O valor só precisa ser folgado o
   bastante para não cortar; quem manda na altura real é o texto. */
.jornada.is-stepped .modulo.is-ativo .modulo__resumo {
  max-height: 5em; opacity: 1; margin-top: .3rem;
}

/* A superfície do módulo corrente é DESENHADA, não é caixa.

   Ela era padding no próprio <li>, e isso quebrava de três jeitos. O vão
   entre módulos é `padding-bottom: 1.5rem` (padding, e não margin, porque o
   fio de ligação corre por dentro dele), então pintar o fundo do <li> pintava
   o vão inteiro. Para compensar entrava `margin-bottom: -.55rem`, e a conta
   terminava com a superfície indo .55rem ALÉM do ponto onde o módulo seguinte
   começa: daí a sobreposição no texto de baixo. No último módulo, cujo
   padding-bottom base é 0, sobravam 2,05rem de superfície vazia. E o
   `padding-top` subia a borda do padding box, desalinhando o círculo do
   número, que é posicionado em relação a ela.

   Como ::after nada disso existe: zero mudança de layout, o círculo fica onde
   estava, a altura da coluna não oscila de passo em passo (o que importa,
   porque --pin-h é medido dela) e a superfície abraça o texto com folga igual
   em cima e embaixo. `bottom` para .95rem acima da borda do padding box, que é
   1,5rem abaixo do texto: sobra a mesma .55rem do topo. */
.jornada.is-stepped .modulo.is-ativo::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: -.55rem;
  left: -.85rem;
  right: -.85rem;
  bottom: calc(1.5rem - .55rem);
  background: var(--surface);
  border-radius: var(--radius);
}

/* O último módulo não tem vão embaixo (padding-bottom: 0), então a borda de
   baixo da superfície é a folga direta. */
.jornada.is-stepped .modulo:last-child.is-ativo::after {
  bottom: -.55rem;
}

/* O nó da semana corrente preenche. O último nó tinha preenchimento fixo
   ("a chegada"), e no modo passo a passo ele espera a própria vez: dois
   acentos ao mesmo tempo diriam que há dois lugares importantes. */
.jornada.is-stepped .modulo:last-child .modulo__num {
  background: var(--canvas); border-color: var(--hairline-strong); color: var(--muted);
}
.jornada.is-stepped .modulo.is-passado .modulo__num {
  border-color: var(--accent); color: var(--accent);
}
.jornada.is-stepped .modulo.is-ativo .modulo__num {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}

/* ---------- A ÁRVORE, ENCHENDO ----------
   Fantasma é o arquivo que ainda não existe; ele fica na página desde o
   começo porque ver o destino antes de sair é o que dá sentido ao percurso.
   is-novo é a linha que acabou de assentar. */
.jornada.is-stepped .acervo__linha {
  opacity: .22;
  transition: opacity .4s var(--ease), color .4s var(--ease);
}
.jornada.is-stepped .acervo__linha.is-dentro { opacity: 1; }
.jornada.is-stepped .acervo__linha.is-novo { color: var(--accent); }

/* A batida da semana 5: nenhum arquivo novo, o acervo inteiro acende. É a
   única coisa que a animação diz e a lista estática não dizia. */
.jornada.is-stepped .acervo__linha.is-lido { color: var(--accent); }

.jornada.is-stepped .acervo__nota {
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.jornada.is-stepped .acervo__nota.is-visivel { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .jornada .modulo,
  .jornada .modulo__resumo,
  .jornada .acervo__linha,
  .jornada .acervo__nota { transition: none; }
}

.jornada__grid {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: start;
}

/* Cabeça de coluna: régua no acento e nome em mono. Não é o .rotulo, que
   tem fio fino e já abriu a seção; aqui a régua cheia diz "coluna", não
   "assunto novo". */
.jornada__cabeca {
  padding-top: .9rem;
  border-top: 2px solid var(--accent);
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
}

/* Ficha técnica: os fatos comerciais valem para as duas colunas, então vêm
   antes delas, logo abaixo do lead. Eram quatro; o quarto era "Etapa inicial:
   diagnóstico", que já é o módulo 01 e a entrega 01. Três fatos, nenhum
   repetido mais adiante. */
/* [estrutura] A ficha deixou de ser de #programa e virou peça da página:
   ela abre o hero (escopo comprável antes da tese) e o formulário de
   #contato reusa o mesmo desenho de célula. Por isso o seletor perdeu o
   prefixo de seção. */
.ficha {
  margin-top: clamp(2rem, 3vw, 2.75rem);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
  list-style: none;
}
.ficha > li {
  background: var(--surface);
  padding: clamp(1.1rem, 1.8vw, 1.5rem);
}

/* No hero são quatro fatos, não três, porque "quem participa" absorveu a
   linha .hero__topicos que flutuava solta abaixo dos botões. Quatro caem
   em 4 / 2 / 1 conforme a largura: em duas colunas nenhum fica órfão. */
.hero__ficha {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  text-align: center;
}
@media (max-width: 900px) { .hero__ficha { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .hero__ficha { grid-template-columns: 1fr; } }
.fato__chave {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .5rem;
}
.fato__valor { font-size: var(--fs-sm); color: var(--ink); line-height: 1.5; }

/* ---------- COLUNA 1 · o programa ----------
   Era lista numerada com fio horizontal entre os itens, igual à coluna da
   direita. Virou trilha vertical, e a diferença é semântica, não estética:
   a esquerda é SEQUÊNCIA (a semana 2 depende da 1) e a direita é INVENTÁRIO
   (a ordem dos artefatos é arbitrária). Desenhar as duas iguais escondia
   isso. Fio vertical diz "vem depois"; fio horizontal diz "e também".

   O número não ganhou um marcador ao lado: ele VIROU o marcador. Uma coisa
   no lugar de duas, e a numeração que já existia passa a carregar a função
   de nó em vez de só rotular.

   O último nó é o único preenchido. Não é enfeite de fim de lista: a
   promessa da seção é "no fim, o time roda o método sozinho", então a
   chegada é a única coisa que merece acento nesta coluna. */
/* ol.modulos, e não .modulos: o reset de tokens.css tem
   ol[role="list"] { padding: 0 }, que é (0,1,1) e ganharia de (0,1,0).
   Com o elemento no seletor a especificidade empata e a ordem decide, e
   styles.css vem depois. Sem isso a calha da trilha não abre e os nós
   ficam fora da tela. */
ol.modulos {
  --no: 30px;
  --calha: 46px;
  margin-top: 1.5rem;
  padding: 0 0 0 var(--calha); list-style: none;
  display: grid; gap: 0;
}
.modulo {
  position: relative;
  padding-bottom: 1.5rem;
}
.modulo:last-child { padding-bottom: 0; }

/* o trecho de fio que liga este nó ao próximo. O último não tem para onde
   apontar, então não desenha nada. */
.modulo::before {
  content: ""; position: absolute;
  left: calc(var(--calha) * -1 + var(--no) / 2);
  top: calc(var(--no) - 3px); bottom: -3px;
  width: 1px; background: var(--hairline-strong);
}
.modulo:last-child::before { content: none; }

.modulo__num {
  position: absolute; left: calc(var(--calha) * -1); top: -3px;
  width: var(--no); height: var(--no);
  display: grid; place-items: center;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  background: var(--canvas);
  font-family: var(--font-mono); font-size: var(--fs-xs); line-height: 1;
  letter-spacing: .04em;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.modulo:last-child .modulo__num {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}

.modulo__titulo { font-size: var(--fs-body); font-weight: 700; color: var(--ink); }
.modulo__resumo {
  margin-top: .3rem;
  font-size: var(--fs-sm); color: var(--body); line-height: 1.5;
}

/* ---------- COLUNA 2 · o acervo ----------
   Era um inventário em prosa de quatro linhas. Virou árvore de arquivos:
   os mesmos quatro artefatos escritos como o que eles de fato são. Nome de
   arquivo é a coisa mais verificável que a página afirma, e por isso ele
   convence mais do que a frase que descrevia o arquivo.

   O id #ganhos foi aposentado. Ele existia porque o menu tinha um link por
   coluna; depois da redução para cinco itens nenhum link apontava para cá,
   e o scroll-margin-top que ele carregava só servia àquele link. */
.acervo__arvore {
  margin-top: 1.5rem;
  padding: 0; list-style: none;
  font-family: var(--font-mono); font-size: var(--fs-sm);
  line-height: 2;
}
/* Recuo por atributo, e não por custom property inline: são três níveis
   fixos e o HTML fica sem style=. */
.acervo__linha {
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.acervo__linha[data-nivel="1"] { padding-left: 1.35rem; }
.acervo__linha[data-nivel="2"] { padding-left: 2.7rem; }
.acervo__linha--pasta { color: var(--muted); }

.acervo__nota {
  margin-top: clamp(1.25rem, 2vw, 1.75rem);
  padding-top: clamp(1rem, 1.6vw, 1.25rem);
  border-top: 1px solid var(--hairline);
  font-size: var(--fs-sm); color: var(--muted); line-height: 1.55;
}

.entrega__fecho {
  margin-top: clamp(1.5rem, 2.5vw, 2rem);
  font-size: var(--fs-sm); color: var(--body); line-height: 1.55;
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
}

/* O CTA fecha a coluna. A linha acima dele deixou de ser ressalva ("nenhum
   item é promessa teórica") e passou a ser o motivo de clicar: o que a
   conversa entrega e o que ela ainda não é. Ressalva imediatamente antes do
   botão só ensina o leitor a hesitar. */
.entrega__cta {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .75rem 1.5rem;
}
.entrega__cta-nota {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .04em; color: var(--muted);
}

/* A ficha saiu daqui para o hero e leva os próprios pontos de quebra (4 / 2
   / 1); mantê-la nesta media query a derrubava para uma coluna já em 780px,
   cortando a faixa de duas colunas antes da hora. Aqui sobra o colapso das
   duas colunas da jornada, que é o que esta seção de fato tem. */
@media (max-width: 780px) {
  .jornada__grid { grid-template-columns: 1fr; gap: clamp(2.5rem, 6vw, 3.5rem); }
}

/* ============================================================
   6 · CASOS · grid editorial de casos de campo com imagem
   ============================================================ */
.casos { border-bottom: 1px solid var(--hairline); }
.casos__head .section__lead { max-width: 58ch; }

.casos__grid {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 2.5vw, 2.25rem);
}

.caso-card {
  display: flex;
  flex-direction: column;
  background: var(--canvas);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.caso-card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.caso-card__media {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--surface-2);
  margin: 0;
  border-bottom: 1px solid var(--hairline);
}
.caso-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .3s var(--ease);
}
.caso-card:hover .caso-card__media img {
  transform: scale(1.03);
}

.caso-card__badge {
  position: absolute;
  bottom: .75rem;
  left: .75rem;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  background: var(--inv-bg);
  color: #fff;
  padding: .3rem .6rem;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.caso-card__body {
  padding: clamp(1.25rem, 2vw, 1.75rem);
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}

.caso-card__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: .6rem;
}

.caso-card__titulo {
  font-size: var(--fs-h3);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
}

.caso-card__desc {
  margin-top: .75rem;
  font-size: var(--fs-sm);
  color: var(--body);
  line-height: 1.55;
}

@media (max-width: 960px) {
  .casos__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  .casos__grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   8 · INSTRUTOR · card editorial com autoridade direta
   ============================================================ */
.instrutor { border-bottom: 1px solid var(--hairline); }
.instrutor .section__title { max-width: 24ch; margin-bottom: clamp(2rem, 3.5vw, 3rem); }

.instrutor__grade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 640px), 1fr));
  gap: clamp(1.5rem, 2.5vw, 2rem);
}

.instrutor__card {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: clamp(1.25rem, 2.5vw, 2rem);
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  background: var(--canvas);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  align-items: start;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.instrutor__card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-sm);
}

.instrutor__foto {
  margin: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--hairline);
  aspect-ratio: 1 / 1;
}
/* A foto já vem recortada em busto (quadrada, 480px), então não há zoom
   por CSS compensando um retrato de corpo inteiro. Sem grayscale: rosto
   dessaturado trabalha contra o argumento de "quem responde é quem está
   na sala". */
.instrutor__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  transition: transform .3s var(--ease);
}
.instrutor__card:hover .instrutor__foto img {
  transform: scale(1.06);
}

.instrutor__corpo {
  display: flex;
  flex-direction: column;
  gap: .65rem;
}

.instrutor__card-topo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem 1rem;
}

.instrutor__nome {
  font-size: var(--fs-h3);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.2;
}

.instrutor__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--accent);
}

.instrutor__bio {
  font-size: var(--fs-sm);
  color: var(--body);
  line-height: 1.55;
}

.instrutor__nota {
  margin-top: .25rem;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.45;
  border-top: 1px solid var(--hairline);
  padding-top: .65rem;
}

@media (max-width: 560px) {
  .instrutor__card {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }
  .instrutor__foto {
    max-width: 130px;
  }
}

/* ============================================================
   7 · PRÁTICA · trilho de clipes verticais 9:16
   Única seção com mídia em linha e única que rola na horizontal.
   O clipe é 9:16 porque foi gravado assim: recortar para 16:9 faria
   parecer material de banco, que é justamente o que ele não é.
   Nenhum clipe tem faixa de áudio, então não existe controle de som.

   NOTA: este bloco agora é usado por /ai-first e por /aidd. Promover
   para assets/ na próxima passada, conforme assets/README.md.
   ============================================================ */
.pratica { border-bottom: 1px solid var(--hairline); }
.pratica__head .section__lead { max-width: 56ch; }

.pratica__rail {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: clamp(1rem, 2.2vw, 1.75rem);
}

.clipe { margin: 0; min-width: 0; }
.clipe__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
  box-shadow: var(--shadow-md);
}
.clipe__video {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}

/* Controle de pausa: exigido porque o clipe roda sozinho e passa de
   cinco segundos. Fica sempre visível, nunca só no hover, senão some
   no toque e no teclado. Controle, então 4px mesmo flutuando. */
.clipe__toggle {
  position: absolute; right: .625rem; bottom: .625rem;
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  padding: 0; cursor: pointer;
  color: var(--ink);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  transition: background-color .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
@supports not (backdrop-filter: blur(1px)) {
  .clipe__toggle { background: var(--glass-solid); }
}
@media (prefers-reduced-transparency: reduce) {
  .clipe__toggle { background: var(--glass-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.clipe__toggle:hover { color: var(--accent); border-color: var(--hairline-strong); }
.clipe__toggle:active { transform: scale(.94); }

.clipe__toggle-icon { position: relative; display: block; width: 10px; height: 12px; }
.clipe__toggle-icon::before,
.clipe__toggle-icon::after {
  content: ""; position: absolute; top: 0;
  width: 3px; height: 12px; background: currentColor;
}
.clipe__toggle-icon::before { left: 0; }
.clipe__toggle-icon::after  { right: 0; }
/* aria-pressed="true" = pausado, então o ícone vira "tocar" */
.clipe__toggle[aria-pressed="true"] .clipe__toggle-icon::before {
  left: 1px; width: 0; height: 0; background: transparent;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 10px solid currentColor;
}
.clipe__toggle[aria-pressed="true"] .clipe__toggle-icon::after { opacity: 0; }

.clipe__toggle-label {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.clipe__cap { margin-top: 1.125rem; }
.clipe__local {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--ink); font-weight: 400;
  padding-left: .75rem; border-left: 2px solid var(--accent);
}
.clipe__desc {
  margin-top: .625rem; padding-left: .75rem;
  font-size: var(--fs-sm); color: var(--body); line-height: 1.55;
}

/* Abaixo de 860px o trilho vira carrossel: o clipe mantém a largura
   de leitura em vez de espremer três colunas numa tela de telefone. */
@media (max-width: 860px) {
  .pratica__rail {
    grid-auto-columns: minmax(240px, 68vw);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--gutter);
    padding-inline: var(--gutter);
    margin-inline: calc(var(--gutter) * -1);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .pratica__rail::-webkit-scrollbar { display: none; }
  .clipe { scroll-snap-align: start; }
}
@media (max-width: 520px) {
  .pratica__rail { grid-auto-columns: minmax(220px, 78vw); }
}

/* ============================================================
   9 · CONTRASTE · duas placas de desenho pareadas + linha de veredito

   Família nova. A placa é prancha de desenho, não cartão: superfície
   --surface em vez do --canvas de #pilares e #casos, sem número de ordem,
   sem hover e sem sombra. O conteúdo dela é um desenho, não um parágrafo,
   e é isso que a separa das outras famílias da página.

   O desenho é SVG inline e sem cor literal: tudo sai de var(), então ele
   vira no tema escuro junto com o resto. O texto do SVG é <text> de
   verdade, então ele escala com o viewBox e continua selecionável.

   O gráfico da segunda placa é ESQUEMA, não medição: sem eixo numerado,
   sem grade, sem fonte, porque não há dado por trás. Depois que #lastro
   saiu da página, esta é a única quantidade desenhada que restou, e por
   isso a distinção pesa mais: nada aqui é número medido.
   ============================================================ */
/* Mesmo desenho da .casos__regua: linha de fonte atrás de um fio, sem
   cartão e sem fundo. As duas dizem a mesma coisa em lugares diferentes,
   uma sobre número próprio e outra sobre desenho, e por isso são a mesma
   peça tipográfica. */
.contraste__legenda {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  padding-top: clamp(1.25rem, 2vw, 1.75rem);
  border-top: 1px solid var(--hairline);
  font-size: var(--fs-sm);
  color: var(--muted);
  max-width: 74ch;
}
.contraste__legenda a { color: var(--accent); }

.contraste {
  border-bottom: 1px solid var(--hairline);
  overflow-x: clip;
}
.contraste .section__lead { max-width: 64ch; }

/* "versus" em itálico apagado: ele separa os dois nomes sem competir com
   eles. É a única itálica da página, e existe só aqui. */
.contraste__titulo { max-width: 24ch; }
.contraste__titulo em { font-style: italic; font-weight: 400; color: var(--muted); }

.contraste__placas {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  display: grid; gap: clamp(1rem, 1.8vw, 1.5rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  min-width: 0;
  max-width: 100%;
}

/* min-width: 0 é obrigatório, não é ajuste fino. A placa é item de grid, e
   item de grid nasce com min-width: auto, que resolve para o tamanho mínimo
   do conteúdo. O conteúdo aqui é um SVG com min-width: 440px (o piso de
   legibilidade da .desenho-scroll), então sem isto a placa não encolhe
   abaixo de 440px e empurra a página inteira para fora da tela no celular:
   quem rola vira o documento, não o desenho. */
.placa {
  margin: 0; min-width: 0;
  display: flex; flex-direction: column;
  padding: clamp(1.25rem, 2.2vw, 1.75rem);
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}
.placa__rotulo {
  display: flex; align-items: baseline; gap: .6rem;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.5rem;
}
/* O qualificador "esquema" anda junto do rótulo porque a honestidade do
   desenho é parte do rótulo dele, não uma nota de rodapé. */
.placa__nota {
  font-size: var(--fs-xs); letter-spacing: .04em; text-transform: none;
  color: var(--body);
  padding: .1rem .45rem;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
}
.placa__desenho { width: 100%; height: auto; margin-block: auto; }

/* ---------- OS DOIS FLUXOS ----------
   Um sobre o outro, separados por fio: a comparação é vertical porque as
   duas linhas do tempo começam no mesmo ponto à esquerda. */
.fluxo {
  min-width: 0;
  max-width: 100%;
}
.fluxo + .fluxo {
  margin-top: 1.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--hairline-strong);
}
.fluxo__quem {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .5rem;
}
.fluxo__quem--acento { color: var(--accent); }
.fluxo__desenho { width: 100%; height: auto; }

/* ---------- VOCABULÁRIO DO DESENHO ----------
   Um traço só, 1.5px, como os ícones de setor de #matriz. Nada de
   preenchimento e nada de sombra. */
.d-linha, .d-eixo {
  stroke: var(--hairline-strong); stroke-width: 1.5; fill: none;
}
.d-no { fill: var(--body); }
.d-no-forte { fill: var(--accent); }
.d-check { stroke: var(--on-accent); stroke-width: 2; fill: none;
           stroke-linecap: round; stroke-linejoin: round; }
.d-ponta { fill: var(--hairline-strong); }
.d-ponta--acento { fill: var(--accent); }

/* A volta de aprendizado é tracejada porque ela não é uma etapa: é o que
   a etapa de revisão devolve para a próxima intenção. */
.d-volta {
  stroke: var(--accent); stroke-width: 1.5; fill: none;
  stroke-dasharray: 5 4;
}

/* O font-size aqui é unidade de usuário do viewBox, não pixel de tela: ele
   escala junto com o desenho. Por isso a régua de tipo da página não se
   aplica, e por isso a legibilidade depende da largura em que o SVG é
   desenhado, que é o que .desenho-scroll resolve logo abaixo. */
.d-rot {
  font-family: var(--font-sans); font-size: var(--fs-sm);
  fill: var(--body);
}
.d-rot--acento { fill: var(--accent); font-weight: 700; }
.d-eixo-rot {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  fill: var(--muted);
}

/* ---------- PISO DE LEGIBILIDADE ----------
   O SVG escala uniformemente, então em 390px o rótulo de 13 unidades cairia
   para cerca de 7px de tela. Aumentar a fonte no viewBox não resolve: as
   palavras encostariam umas nas outras, porque as posições dos nós são
   fixas. A saída é a mesma de #matriz: o desenho para de encolher num piso
   e a caixa rola. Em 440px de largura o rótulo fica em torno de 11px, que
   é o menor tamanho em que ele ainda se lê. */
.desenho-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.desenho-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.desenho-scroll > svg { min-width: 440px; display: block; }

/* ---------- A LINHA D'ÁGUA ----------
   O envelope é a capacidade de gerar código, e ele é IDÊNTICO nas duas
   faixas: plano até a marca de adoção de IA e dobrando depois dela. Isso é
   premissa, não resultado, e é o que faz o desenho falar de IA em vez de
   servir para qualquer processo: a aceleração entra igual dos dois lados.

   O que muda é a fatia de baixo, e é ela que decide se o ganho da aceleração
   vira roadmap ou some. À esquerda da marca os dois desenhos são o mesmo
   desenho; a divergência inteira acontece depois dela.

   Azul cheio é roadmap. Retrabalho é hachura, não vermelho: hachura já
   significa "isto não conta como saída" em qualquer desenho técnico, e
   vermelho gastaria o único da página num desenho que é modelo, não medição.
   A base embaixo da hachura existe porque o azul da banda passa por baixo
   dela, e ela é --canvas e não --surface de propósito: um degrau afastado da
   superfície da placa, para a fatia consumida ler como buraco em vez de se
   dissolver no fundo. Funciona nos dois temas, porque --canvas está de um
   lado de --surface no claro e do outro no escuro.

   A chave de leitura em HTML saiu: os nomes das duas fatias agora ficam ao
   lado de cada uma, na coluna da direita. Nome no lugar da coisa dispensa
   legenda, e legenda era o que tornava a versão anterior menos intuitiva. */
.p-envelope { fill: none; stroke: var(--hairline-strong); stroke-width: 1.5; }
.p-envelope-fundo { fill: var(--accent); }

/* A marca de adoção é tracejada porque não é um evento com data: é o ponto
   a partir do qual o desenho passa a falar de IA. */
.p-marco { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 4 4; }
.p-retrabalho-base { fill: var(--canvas); }
.p-retrabalho { fill: url(#ct-hachura); }
.d-hachura { stroke: var(--muted); stroke-width: 1; }
.p-linha-agua { fill: none; stroke: var(--ink); stroke-width: 2; }
.d-eixo-rot--acento { fill: var(--accent); }

/* A animação é o eixo x tocado: uma cortina abre da esquerda para a direita
   e as duas linhas aparecem divergindo, em vez de o leitor já encontrar o
   resultado pronto. É o beat que o desenho parado joga fora, porque as duas
   faixas começam no MESMO ponto e só separam depois.

   É retângulo opaco por cima, recolhendo para a direita em scaleX. Com
   clipPath funcionaria igual; a persiana ganha por ordem de desenho: o
   contorno da banda é pintado depois dela e fica visível o tempo todo, sem
   precisar de um segundo grupo fora do recorte. scaleX e não width para não
   medir layout a cada quadro.

   O contorno da banda é desenhado DEPOIS da persiana: o tanque aparece antes
   da água, e a altura fixa se lê como premissa, não como resultado.

   O estado parado é scaleX(0), ou seja, persiana recolhida: sem JS e em
   reduced-motion o desenho já nasce completo e nada se move. */
.p-cortina {
  fill: var(--surface);
  transform-box: fill-box; transform-origin: right;
  transform: scaleX(0);
}

@media (prefers-reduced-motion: no-preference) {
  .js .p-cortina { transform: scaleX(1); transition: transform 1.4s .15s var(--ease-out); }
  .js [data-reveal].is-revealed .p-cortina { transform: scaleX(0); }
}


/* Mesma affordance de #matriz, e aparece só na faixa em que o desenho de
   fato passa do piso de 440px e começa a rolar. */
.contraste__arraste {
  display: none;
  margin-top: .875rem;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent);
}
@media (max-width: 560px) {
  .placa { padding: 1rem .875rem; }
  .contraste__arraste { display: block; }
}


/* ---------- A LINHA DE VEREDITO ----------
   Duas colunas separadas por fio vertical, cada uma com o nome em cima e
   a frase embaixo. É o resumo em uma linha de cada lado, para quem só
   olhou os desenhos. */
.contraste__veredito {
  margin-top: clamp(2rem, 3.5vw, 3rem);
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid var(--hairline-strong);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 3.5rem);
  min-width: 0;
  max-width: 100%;
}
.veredito + .veredito {
  padding-left: clamp(1.5rem, 4vw, 3.5rem);
  border-left: 1px solid var(--hairline);
}
.veredito__quem {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: .875rem;
}
.veredito__quem--acento { color: var(--accent); }
/* pretty, não balance: com duas linhas curtas o balance parte a frase da
   direita depois do artigo ("Entrega rápida. A / qualidade fica..."), que
   é exatamente a órfã que ele deveria evitar. */
.veredito__frase {
  font-size: var(--fs-h3); font-weight: 700; color: var(--ink);
  line-height: 1.3; text-wrap: pretty; max-width: 26ch;
}

@media (max-width: 900px) {
  .contraste__placas { grid-template-columns: 1fr; }
}
/* Empilhado, o fio que separa os dois vereditos passa a ser horizontal:
   fio vertical sem coluna ao lado não separa nada. */
@media (max-width: 620px) {
  .contraste__veredito { grid-template-columns: 1fr; gap: 1.5rem; }
  .veredito + .veredito {
    padding-left: 0; border-left: 0;
    padding-top: 1.5rem; border-top: 1px solid var(--hairline);
  }
}

/* ============================================================
   10 · DÚVIDAS · acordeão agrupado por assunto
   O agrupamento existe porque as objeções vêm de pessoas diferentes:
   quem decide pergunta de risco, quem executa pergunta de método.
   ============================================================ */
.duvidas { border-bottom: 1px solid var(--hairline); }
.faq__grupo {
  margin-top: clamp(2rem, 3vw, 2.75rem);
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
}
.faq__grupo + .faq { margin-top: .75rem; }

/* ============================================================
   11 · CONVERSÃO · card executivo de ação direta
   ============================================================ */
.contato { border-bottom: 1px solid var(--hairline); }
.contato__card {
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  padding: clamp(2.5rem, 5vw, 4.5rem) clamp(1.5rem, 4vw, 3.5rem);
  text-align: center;
  max-width: 820px;
  margin-inline: auto;
}
.contato__card .section__title {
  max-width: 22ch; margin-inline: auto;
}
.contato__card .section__lead { margin-inline: auto; max-width: 56ch; }

/* ---------- AGENDA · o bloco de vaga ----------
   Fica ENTRE o lead e o formulário, não embaixo do botão. Embaixo ele seria
   consolo depois da decisão; aqui ele é o motivo de preencher agora, lido
   antes do primeiro campo.

   Célula --canvas dentro do card --surface, que é a mesma relação das células
   do formulário logo abaixo: o bloco rima com os campos em vez de trazer o
   selo de escassez de qualquer site. Sem vermelho, sem contorno grosso e sem
   ícone de urgência. O vermelho da página é reservado ao dado de fracasso e
   ao erro de campo, e gastar ele aqui seria dizer que uma vaga cheia é um
   problema do leitor.

   O peso está no numeral, e só nele: "2 vagas" no acento, o resto em corpo
   normal. A data em letra miúda é o que separa fato mantido de adesivo. */
.agenda {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  display: grid; gap: .3rem;
  justify-items: center;
  padding: clamp(1rem, 1.8vw, 1.35rem) clamp(1.25rem, 2.5vw, 1.75rem);
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  max-width: 34rem; margin-inline: auto;
}
.agenda__chave {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
}
.agenda__valor {
  font-size: var(--fs-body); color: var(--ink); line-height: 1.4;
  text-wrap: balance;
}
.agenda__valor strong {
  font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.agenda__nota {
  font-size: var(--fs-xs); color: var(--muted); line-height: 1.5;
}
.agenda__nota time { font-variant-numeric: tabular-nums; }

/* O .form compartilhado traz a própria superfície, borda e raio, porque em
   /builder ele fica solto na coluna. Aqui o .contato__card já é a superfície:
   deixar as duas empilhadas é cartão dentro de cartão no mesmo fundo, um
   degrau que não existe. O componente entra só pelo comportamento e pelos
   campos; a caixa é a de fora.
   O cabeçalho do card continua centralizado, mas rótulo precisa de margem
   esquerda estável, então o formulário volta a alinhar à esquerda. */
.contato__form {
  margin-top: clamp(2rem, 3vw, 2.5rem);
  background: none; border: 0; border-radius: 0; padding: 0;
  text-align: left;
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
  justify-items: center;
}

/* ---------- os campos são a ficha técnica de #programa ----------
   .ficha é uma grade de células separadas por fio de 1px, cada uma
   com rótulo em mono versalete no acento e o conteúdo embaixo. Isso já é a
   forma de um campo: pergunta em cima, resposta embaixo. Reaproveitar o
   desenho aqui faz o fecho rimar com a ficha três seções acima, em vez de o
   único bloco da página vir com a caixa de input de qualquer site.

   O que muda em relação à ficha: as células são --canvas e não --surface,
   porque o card já é --surface e célula do mesmo tom não teria degrau. A
   grade colapsa por largura do card, não da janela: o card é limitado a
   820px dentro do shell, então media query teria de refazer a conta do
   padding para acertar o mesmo ponto. O min() interno existe porque
   minmax(15rem, ...) é piso rígido: num card mais estreito que 15rem a
   trilha não encolhe e vaza para fora. */
.contato__campos {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
}
.contato__campos .field {
  position: relative;
  background: var(--canvas);
  padding: clamp(.9rem, 1.6vw, 1.15rem) clamp(1.1rem, 1.8vw, 1.5rem);
  gap: .35rem;
  transition: background .2s var(--ease);
}
.contato__campos .field--full { grid-column: 1 / -1; }

/* Rótulo é o .fato__chave da ficha, letra por letra. */
.contato__campos .field__label {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent);
}

/* O campo perde a própria caixa: quem é a caixa agora é a célula. Sem borda,
   sem fundo e sem padding lateral, o que a pessoa digita alinha com o rótulo
   acima, que é o alinhamento que a ficha técnica tem.
   background-color, e não o atalho background: o atalho zeraria junto o
   background-image, que é onde o base.css desenha a seta do select. */
.contato__campos .field__input {
  padding: 0; border: 0; background-color: transparent; border-radius: 0;
  font-size: var(--fs-sm); line-height: 1.5; min-height: 1.5rem;
}
.contato__campos .field__input:hover { border-color: transparent; }
.contato__campos .field__input:focus { outline: none; box-shadow: none; }

/* Foco e erro passam a ser da célula inteira, porque é ela que tem contorno.
   Anel por dentro e não por fora: a grade tem overflow hidden para cortar os
   cantos, e sombra para fora seria cortada junto. */
.contato__campos .field:focus-within { background: var(--accent-wash); }
.contato__campos .field::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: none; transition: box-shadow .2s var(--ease);
}
.contato__campos .field:focus-within::after { box-shadow: inset 0 0 0 2px var(--accent); }
.contato__campos .field.is-invalid::after { box-shadow: inset 0 0 0 1px var(--alert); }
.contato__campos .field.is-invalid:focus-within::after { box-shadow: inset 0 0 0 2px var(--alert); }
.contato__campos .field.is-invalid .field__input { border-color: transparent; }
.contato__campos .field__error { margin-top: .1rem; }

/* A seta do select vem do base.css e conta com o padding-right do campo em
   caixa, que aqui é zero. Reposicionada na borda direita da célula. */
.contato__campos select.field__input {
  padding-right: 1.4rem;
  background-position:
    calc(100% - .5rem) calc(50% + 1px),
    calc(100% - .2rem) calc(50% + 1px);
}

/* Botão e status ficam fora da grade de fios: célula é lugar de campo. O
   botão não é --block porque largura cheia num card de 820px vira faixa. */
.contato__enviar { width: 100%; max-width: 20rem; }
.contato__form .form__status { text-align: center; }

.contato__note {
  margin-top: .875rem;
  font-size: var(--fs-sm); color: var(--muted);
}

/* ---------- VARIANTE LADO A LADO (teste) ----------
   Ativada pela classe .contato--lado na <section>. Para voltar à versão
   empilhada, remova a classe do HTML; nada acima foi alterado.
   Texto à esquerda, formulário à direita, a partir de 960px. Abaixo disso
   empilha como antes. O card perde o limite de 820px e a centralização. */
@media (min-width: 960px) {
  .contato--lado .contato__card {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(2.5rem, 5vw, 4.5rem);
    align-items: start;
    text-align: left;
  }
  .contato--lado .contato__card .section__title,
  .contato--lado .contato__card .section__lead { margin-inline: 0; }
  .contato--lado .agenda {
    justify-items: start; margin-inline: 0; max-width: none;
  }
  .contato--lado .contato__form { margin-top: 0; justify-items: stretch; }
  .contato--lado .contato__campos { grid-template-columns: 1fr 1fr; }
  .contato--lado .contato__campos .field:nth-child(n+7) { grid-column: 1 / -1; }
  .contato--lado .contato__enviar { max-width: none; }
  .contato--lado .contato__note { text-align: center; }
}

/* O fio era do bloco de chips de público, que saiu daqui: ele repetia o hero
   e a FAQ e disputava atenção com o botão. O fio fica, porque o corte entre
   a ação e a letra miúda continua existindo; quem o carrega agora é a única
   linha que sobrou embaixo. */
.contato__scarcity {
  margin-top: clamp(2rem, 3.5vw, 3rem);
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid var(--hairline-strong);
  font-size: var(--fs-sm); color: var(--muted);
  max-width: 52ch; margin-inline: auto;
}


/* ============================================================
   6.1 · RÉGUA DOS NÚMEROS PRÓPRIOS

   A página tem disciplina exemplar com dado de terceiro (fonte, data e
   universo no mesmo bloco) e não tinha nenhuma com número da própria
   casa. Esta linha é a régua dos badges de #casos, e é desenhada como
   linha de fonte: sem cartão, sem fundo, atrás de um fio, no mesmo peso
   das notas de rodapé da página.
   ============================================================ */
.casos__regua {
  margin-top: clamp(2rem, 3.5vw, 2.75rem);
  padding-top: clamp(1.25rem, 2vw, 1.75rem);
  border-top: 1px solid var(--hairline);
  font-size: var(--fs-sm);
  color: var(--muted);
  max-width: 74ch;
}

/* ============================================================
   6.5 · MARCO · a linha de tempo até valor

   Uma frase por tela, sem cartão e sem fundo próprio: se ela virasse
   caixa, entraria na disputa com #casos acima e com o trilho de clipes
   abaixo, que já são dois blocos de mídia seguidos. O que a destaca é
   escala de tipo e ar, que é a moeda que a página ainda não tinha gasto.

   Fio curto no acento acima do texto, no mesmo idioma do .hero__rule.
   ============================================================ */
.marco {
  padding-block: clamp(3.5rem, 7vw, 6rem);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.marco__texto {
  position: relative;
  font-size: clamp(1.5rem, 3.2vw, 2.25rem);
  line-height: 1.22;
  font-weight: 700;
  text-wrap: balance;
  color: var(--ink);
  max-width: 26ch;
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
}
.marco__texto::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: 3.5rem; height: 3px; background: var(--accent);
}
.marco__texto em { font-style: normal; color: var(--accent); }
.marco__nota {
  margin-top: clamp(1rem, 1.8vw, 1.5rem);
  font-size: var(--fs-sm); color: var(--muted);
  max-width: 56ch;
}

/* ---------- o CTA do meio da página ----------
   Entre o CTA de #programa e o de #contato havia nove seções sem ponto de
   conversão. Este é o primeiro lugar em que o leitor termina de entender o
   método, e quem se convence aqui precisa de uma porta.

   Família própria: fio forte no topo, texto à esquerda e botão à direita.
   O .entrega__cta é botão com nota em mono alinhado à esquerda, e #contato é
   card centralizado; nenhum dos dois se repete aqui.

   O botão não leva --lg. Mesmo acento e mesmo rótulo, escala menor: os dois
   CTAs de peso continuam sendo o do hero e o do fecho, e este não disputa
   com eles. */
.eixo-cta {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid var(--hairline-strong);
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  gap: 1.25rem 2.5rem;
}
.eixo-cta__texto {
  font-size: var(--fs-sm); color: var(--body); line-height: 1.55;
  max-width: 46ch;
}
.eixo-cta__texto strong {
  display: block;
  font-size: var(--fs-body); font-weight: 700; color: var(--ink);
  margin-bottom: .2rem;
}

/* ============================================================
   4.5 · STACKS · a faixa de ferramentas suportadas

   Faixa fina, uma linha de altura no desktop. Não é seção: não tem
   rótulo, não tem h2 e não entra no menu, porque o que ela responde é
   uma objeção de relance, não um assunto.

   Nomes em mono e não em logotipo: logo de terceiro numa página
   comercial sugere parceria, e a lista muda toda vez que o mercado
   muda. Estática, sem marquee, porque logo em movimento é a assinatura
   visual de site de IA gerado.
   ============================================================ */
/* Sem fundo próprio: a regra travada é que #matriz é a única superfície
   com tema, e a página inteira separa banda de banda com fio, não com
   preenchimento. O que delimita esta faixa são os dois fios; quem carrega
   a superfície são os chips. */
.stacks {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  padding-block: clamp(1.75rem, 3vw, 2.5rem);
}
.stacks__inner {
  display: flex; flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: clamp(1rem, 2.5vw, 2.5rem);
}
.stacks__chamada {
  font-size: var(--fs-body);
  font-weight: 700;
  color: var(--ink);
  max-width: 34ch;
}
.stacks__sub {
  display: block;
  margin-top: .3rem;
  font-size: var(--fs-sm); font-weight: 400;
  color: var(--muted);
}
.stacks__lista {
  display: flex; flex-wrap: wrap;
  gap: .4rem .5rem;
  list-style: none;
}
.stacks__lista li {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .04em;
  color: var(--body);
  padding: .3rem .6rem;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: var(--surface);
  white-space: nowrap;
}

/* ============================================================
   12 · ROTA · duas saídas nomeadas por intenção

   O que distingue as duas saídas é a condição, não o destino: a linha
   de cima é a pergunta que o leitor está se fazendo, e o nome da rota
   vem depois dela. Por isso .rota__quando é a primeira coisa da célula
   e o destino é que carrega a seta.

   Célula de fio, sem preenchimento e sem sombra: é a mesma gramática da
   .ficha do hero, o que fecha a página no desenho com que ela abriu.
   ============================================================ */
/* Padding menor que o de uma seção cheia: isto é rampa de saída, não
   assunto. Com o var(--section-y) padrão a faixa passava de 560px de
   altura para carregar dois links. */
.rota {
  border-top: 1px solid var(--hairline);
  padding-block: clamp(2.5rem, 4.5vw, 4rem);
}
.rota__grade {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
}
.rota__saida {
  display: flex; flex-direction: column;
  gap: .35rem;
  background: var(--canvas);
  padding: clamp(1.5rem, 2.5vw, 2rem);
  text-decoration: none;
  transition: background .2s var(--ease);
}
.rota__saida:hover,
.rota__saida:focus-visible { background: var(--surface); }
.rota__quando {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .06em;
  color: var(--muted);
}
.rota__destino {
  font-size: var(--fs-h3);
  font-weight: 700;
  color: var(--accent);
}
.rota__destino::after {
  content: " \2192";
  display: inline-block;
  transition: transform .2s var(--ease);
}
.rota__saida:hover .rota__destino::after { transform: translateX(.2rem); }
.rota__desc {
  font-size: var(--fs-sm);
  color: var(--body);
  max-width: 40ch;
}
@media (max-width: 680px) {
  .rota__grade { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .rota__saida, .rota__destino::after { transition: none; }
  .rota__saida:hover .rota__destino::after { transform: none; }
}

/* Ícone do LinkedIn no rodapé. Vive aqui e não em base.css porque o base.css
   é compartilhado com /ai-first. Área de toque de 44px. */
.site-footer__social {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-top: .5rem; margin-left: -.6rem;
  color: var(--muted);
  transition: color .2s var(--ease);
}
.site-footer__social:hover { color: var(--accent); }

.site-footer__about {
  margin-top: .9rem; max-width: 38ch;
  font-size: var(--fs-sm); line-height: 1.55; color: var(--muted);
}

/* Título da coluna de navegação do rodapé (o menu desta página). */
.site-footer__nav-titulo {
  margin-bottom: .9rem;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}

/* ============================================================
   1.5 · CLIENTES · faixa de logos passando
   Quatro listas idênticas lado a lado; o trilho anda 25% e reinicia, então o
   loop fecha sem emenda. O trilho não pausa; no hover o azulejo cresce. Sob reduced-motion: sem
   animação, só a primeira lista, quebrando linha.
   ============================================================ */
.clientes {
  border-bottom: 1px solid var(--hairline);
  padding-block: clamp(1.75rem, 3vw, 2.5rem);
}
.clientes__rotulo {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); text-align: center;
  margin-bottom: clamp(1.25rem, 2vw, 1.75rem);
}
.clientes__janela {
  overflow: hidden;
  padding-block: 12px; /* folga para o azulejo crescer no hover sem ser cortado */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.clientes__trilho {
  display: flex; width: max-content;
  animation: clientes-corre 40s linear infinite;
}
.clientes__lista {
  display: flex; flex: none; align-items: center;
  gap: clamp(4rem, 8vw, 7rem);
  /* margin e não padding: ul[role="list"] do tokens.css zera o padding com
     especificidade maior, e a emenda entre listas ficava sem espaço. */
  margin: 0 clamp(4rem, 8vw, 7rem) 0 0;
  list-style: none;
}
.clientes__item {
  display: flex; align-items: center; justify-content: center;
  height: 56px;
  transition: transform .25s var(--ease);
}
.clientes__item:hover { transform: scale(1.15); position: relative; z-index: 1; }
/* Silhueta de uma cor (cor original no hover): o tamanho vem dos atributos width/height do <img>. */
.clientes__item img {
  display: block;
  filter: brightness(0);
  opacity: .55;
  transition: opacity .2s var(--ease);
}
:root[data-theme="dark"] .clientes__item img { filter: brightness(0) invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .clientes__item img { filter: brightness(0) invert(1); }
}
/* Hover: cor original. Vem depois e repete os seletores dos temas para
   vencer a silhueta em especificidade. */
.clientes__item:hover img,
:root[data-theme="dark"] .clientes__item:hover img { filter: none; opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .clientes__item:hover img { filter: none; opacity: 1; }
}
@keyframes clientes-corre { to { transform: translateX(-25%); } }

@media (prefers-reduced-motion: reduce) {
  .clientes__janela { -webkit-mask-image: none; mask-image: none; }
  .clientes__trilho { animation: none; width: auto; justify-content: center; }
  .clientes__lista { flex-wrap: wrap; justify-content: center; margin-right: 0; row-gap: 1.25rem; }
  .clientes__lista[aria-hidden="true"] { display: none; }
}
