/* ==========================================================================
   NEXUS theme-final / assets/css/sections/metodo.css
   Territorio exclusivo desta secao (contrato §1: "CSS por secao"). So
   consome tokens de 01-tokens.css e primitivos de 03-ui.css/04-sections.css.
   Nenhum hex, nenhum px de raio, nenhuma familia de fonte literal.

   ROADMAP ALTERNADO (01/09/2026, pedido do dono: "direita, esquerda,
   direita, esquerda, descendo mesmo com scroll"). Trilho central, etapas
   alternando de lado a partir de 900px (impar a esquerda, par a direita);
   abaixo disso volta a uma coluna so, no a esquerda e conteudo a direita
   para as cinco, porque nao sobra largura para duas margens de leitura.
   O cabecalho da secao (.metodo__intro) deixou de ser coluna fixa ao lado
   da timeline (era assim so acima de 1560px) e virou bloco unico, largura
   cheia, acima do trilho: aquela coluna lateral sobrava vazia (978px
   medidos em 1920px) e o zigue-zague usa essa largura por inteiro.

   Tipografia: no maximo TRES niveis por etapa (nome, linha de apoio,
   corpo). O rotulo "Entregavel" reusa o par da linha de apoio
   (.metodo__legend) e a lista de entregaveis reusa o par do corpo
   (.metodo__text) — nao ha um quarto ou quinto tratamento. Mono fica so no
   numero do no (dado curto, tabular); nenhum texto corrido usa mono.

   Motion: so transform e opacity animam. A linha de progresso preenche via
   transform: scaleY(...) a partir do topo (transform-origin: top), nunca
   via height. Duracao sempre multiplicada por var(--motion); o reset global
   de prefers-reduced-motion (02-base.css §7) zera qualquer transicao aqui
   tambem, sem necessidade de media query propria.
   ========================================================================== */

.metodo {
  --metodo-node: calc(var(--fs-h3) * 1.5);
  --metodo-gap: clamp(1rem, 0.75rem + 1.1vw, 2rem);

  /* Peça decorativa da coluna que o zigue-zague deixa vazia (900px+, ver
     bloco ".metodo__visual*" mais abaixo). Era quadrada (aspect-ratio: 1,
     48% da coluna) dentro de uma coluna RETANGULAR e baixa — o quadrado
     nunca cabia direito (nota do dono, 02/09/2026: "poderia ser mais
     retangular"). Largura e altura agora são medidas de verdade contra a
     coluna e o bloco de texto (partials/metodo.js, ajustarPecaVisual) e
     escritas em --metodo-visual-w/--metodo-visual-h — ver esse bloco pro
     porquê (mesmo raciocínio do corte do trilho: não dá pra medir "coluna
     real" em CSS puro quando quem define a largura é o próprio grid). */

  /* Posicao horizontal do trilho: sob o no quando ele e a PRIMEIRA coluna
     (mobile, coluna unica) ou no centro do container quando ele vira a
     coluna do MEIO do zigue-zague (900px+, redefinido mais abaixo). */
  --metodo-line-x: calc((var(--metodo-node) - var(--hairline) * 2) / 2);

  /* Corte do trilho no último nó (agosto/2026, pedido do dono): ver bloco
     "Trilho" abaixo para a explicação completa. --metodo-line-cut é a folga
     extra, além do meio-nó já descontado em .metodo__line, que compensa a
     etapa 05 ter texto mais alto que o próprio nó.

     ATENÇÃO, MUDOU NA 14ª RODADA (06/08/2026): estes valores deixaram de ser
     a fonte da verdade e passaram a ser FALLBACK SEM JS. Quem manda agora é
     `partials/metodo.js`, que mede a geometria real da última etapa (por
     offset, não por rect, para não se calibrar no meio da revelação) e
     escreve `--metodo-line-cut` em pixel no próprio `.metodo__timeline`, no
     mount, quando as fontes assentam e a cada mudança de tamanho.

     O motivo é que a estimativa fixa envelhece sozinha: esta rodada
     acrescentou o parágrafo "Entregável" às cinco etapas, a etapa 05 ficou
     mais alta, e o trilho voltou a atravessar o nó 05 nas CINCO peles, de 34
     a 137px além do centro. Recalibrar os doze números só adiaria o mesmo
     defeito para a próxima mudança de copy. Medido depois da correção, nas
     cinco peles, nos dois modos, em 1440x900 e 390x844: o trilho fecha de 1 a
     3px ANTES do centro do nó 05, que é o lado seguro do erro.

     Quem mexer aqui: mexer nestes rem só muda o que aparece sem JS. Para
     mudar o comportamento real, o arquivo é `partials/metodo.js`. */
  --metodo-line-cut: 11.5rem;
}

@media (min-width: 420px) {
  .metodo { --metodo-line-cut: 10.25rem; }
}

@media (min-width: 490px) {
  .metodo { --metodo-line-cut: 8.75rem; }
}

@media (min-width: 768px) {
  .metodo { --metodo-line-cut: 5.25rem; }
}

/* Duas peles mudam quanto texto da última etapa some abaixo do nó, então
   herdam o corte acima mas com folga própria — território desta seção, não
   das folhas de pele, porque o problema é sempre "onde o trilho para",
   nunca a pintura da pele em si.

   GLASS: .metodo__title/legend/text não mudam de tamanho, mas
   .metodo__timeline ganha max-width própria (--measure + 12rem,
   06-skin-glass.css §6.2) — a coluna de conteúdo passa por pontos de quebra
   de linha diferentes dos da pele default nas mesmas larguras, então a
   última etapa às vezes fecha em uma linha a mais.

   SMOOTH: .metodo__content vira cartão (padding var(--space-6)
   var(--space-7), 10-skin-smooth.css §11) — o padding-block sozinho já soma
   2 × var(--space-6) de altura que a pele default não tem. */
:is([data-skin="glass"]) .metodo {
  --metodo-line-cut: 14.5rem;
}

@media (min-width: 420px) {
  :is([data-skin="glass"]) .metodo { --metodo-line-cut: 16rem; }
}

@media (min-width: 490px) {
  :is([data-skin="glass"]) .metodo { --metodo-line-cut: 11.25rem; }
}

@media (min-width: 700px) {
  :is([data-skin="glass"]) .metodo { --metodo-line-cut: 8.5rem; }
}

:is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .metodo {
  --metodo-line-cut: 21rem;
}

@media (min-width: 420px) {
  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .metodo {
    --metodo-line-cut: 17rem;
  }
}

@media (min-width: 490px) {
  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .metodo {
    --metodo-line-cut: 15.5rem;
  }
}

@media (min-width: 700px) {
  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .metodo {
    --metodo-line-cut: 11.5rem;
  }
}

.metodo__timeline {
  position: relative;
  margin-block-start: var(--space-2);

  /* Cada lado do zigue-zague recebe a mesma medida de paragrafo que a
     coluna unica ja usava (--measure); a largura total e so a soma dos
     dois lados mais o no e as duas folgas, centralizada no container. Em
     qualquer largura menor que isso os dois lados encolhem juntos (1fr em
     .metodo__step, mais abaixo), nunca estouram. */
  max-width: calc(var(--measure) * 2 + var(--metodo-node) + var(--metodo-gap) * 2);
  margin-inline: auto;
}

/* Vão entre o lead e a timeline (agosto/2026, pedido do dono: "encosta mais
   as coisas"). .section__head já carrega margin-block-end de 02-base.css
   (respiro padrão de QUALQUER cabeçalho de seção), e .metodo__layout, logo
   abaixo, soma o próprio gap entre cabeçalho e timeline: as duas folgas se
   acumulavam (até ~88px no mobile) porque ambas resolvem o mesmo problema
   em camadas diferentes. A mesma correção já existe em #govtech, por um
   motivo idêntico (ver sections/govtech.css §1): zera a margem própria do
   cabeçalho e deixa .metodo__layout ser a ÚNICA fonte do respiro. */
.metodo__intro > .section__head {
  margin-block-end: 0;
}

/* A promessa da seção não termina em viúva (01/09/2026, achado da auditoria
   de gosto): "…com cada decisão registrada / por escrito." deixava duas
   palavras sozinhas na última linha, 16% da largura da linha mais longa, em
   1024, 1440 e 1920. `balance` reparte as linhas em vez de encher a primeira. */
.metodo__intro > .section__head > .lead {
  text-wrap: balance;
}

/* Cabeçalho e trilho em bloco único, cabeçalho sempre em cima, largura
   cheia, em qualquer viewport — ver header do arquivo para o porquê. */
.metodo__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-10);
}

/* --------------------------------------------------------------------------
   Trilho: linha neutra de fundo (track) + linha de progresso sobreposta.
   Ambas absolutas, centralizadas no eixo dos nos, encolhidas meio-no em
   cima e embaixo para o traco ir de centro a centro, sem sobrar ponta.
   -------------------------------------------------------------------------- */

/* O TRILHO PARA NO NÓ 05, NÃO DEPOIS (pedido do dono, agosto/2026,
   reforçado por captura: "a linha atravessa o nó 05 e continua para
   baixo"). .metodo__line é absolutamente posicionado dentro de
   .metodo__timeline (§ acima), e a extremidade de baixo usava o mesmo meio-
   nó de folga que a extremidade de cima (inset-block: calc(node/2) valia
   para os dois lados). Isso está certo no TOPO — a primeira etapa é o
   filho mais alto de .metodo__list, então meio-nó a partir do topo do
   container cai exatamente no centro do primeiro nó — mas está errado na
   BASE: cada linha de .metodo__step usa align-items: start (o nó e o bloco
   de texto começam juntos no topo da própria linha da grade), e o bloco de
   texto é sempre mais alto que o nó circular. A ALTURA DA LINHA DE GRADE,
   e portanto a altura de .metodo__timeline, é ditada pelo texto, não pelo
   nó — então "meio-nó a partir da base do container" cai bem abaixo do
   centro do nó 05, dentro do próprio parágrafo da última etapa.

   Não há como medir em CSS puro "onde termina o texto da última etapa"
   sem tocar no script (proibido: metodo.js é território de outro agente,
   e o próprio JS não mede pixel nenhum aqui — o preenchimento anima por
   FRAÇÃO de etapas, scaleY((etapa+1)/total), então a altura de .metodo__line
   É o que define onde "100% preenchido" para). A folga extra que falta
   fica em --metodo-line-cut (bloco .metodo acima): medida na etapa 05 real
   ("Transferência") nas larguras de 360 a 1920px pelo harness do projeto
   (scripts/shots.mjs-style, getBoundingClientRect), com uma margem de
   segurança para nunca sobrar traço abaixo do nó — o erro seguro aqui é
   parar um pouco ANTES do centro do nó, nunca depois. */
/* O trilho liga os cinco nós sempre (pedido do dono: "não dá pra ver a linha
   ligando esses números"). --metodo-line-x resolve a posição horizontal: sob
   o nó quando ele é a primeira coluna (mobile) ou no centro do container
   quando o zigue-zague o põe na coluna do meio (900px+, ver abaixo). O
   preenchimento continua sendo o scaleY de partials/metodo.js. */
.metodo__line {
  position: absolute;
  inset-inline-start: var(--metodo-line-x);
  inset-block-start: calc(var(--metodo-node) / 2);
  inset-block-end: calc(var(--metodo-node) / 2 + var(--metodo-line-cut));
  inline-size: calc(var(--hairline) * 2);
  background-color: hsl(var(--border));
  border-radius: 0;
  overflow: hidden;
}

.metodo__line-fill {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: 100%;
  background-image: linear-gradient(to bottom, hsl(var(--primary)), hsl(var(--primary) / 0.55));
  transform: scaleY(0);
  transform-origin: top;
  will-change: transform;
  transition: transform calc(var(--dur-slow) * var(--motion)) var(--ease-out);
}

/* --------------------------------------------------------------------------
   Lista de etapas
   -------------------------------------------------------------------------- */

.metodo__list {
  position: relative;
  z-index: 1;
  display: grid;
  row-gap: clamp(2.25rem, 1.6rem + 2.6vw, 4rem);
  list-style: none;
  padding: 0;
  margin: 0;
}

.metodo__step {
  display: grid;
  grid-template-columns: var(--metodo-node) 1fr;
  column-gap: var(--metodo-gap);
  align-items: start;
}

.metodo__rail {
  display: flex;
  justify-content: center;
  padding-block-start: calc((var(--metodo-node) - var(--fs-h3) * var(--lh-tight)) / 2);
}

.metodo__node {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: var(--metodo-node);
  block-size: var(--metodo-node);
  border-radius: var(--radius-full);
  border: var(--hairline) solid hsl(var(--border));
  background-color: hsl(var(--surface-2));
  color: hsl(var(--muted-foreground));
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-mono);
  font-variant-numeric: tabular-nums;
  transition:
    background-color calc(var(--dur-base) * var(--motion)) var(--ease-out),
    border-color calc(var(--dur-base) * var(--motion)) var(--ease-out),
    color calc(var(--dur-base) * var(--motion)) var(--ease-out),
    transform calc(var(--dur-base) * var(--motion)) var(--ease-out);
}

/* Ativado por JS quando a linha de progresso alcanca a etapa. */
.metodo__node[data-metodo-active] {
  background-color: hsl(var(--primary));
  border-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  transform: scale(1.08);
}

.metodo__content {
  display: grid;
  gap: var(--space-2);
  padding-block-start: calc((var(--metodo-node) - var(--fs-h3) * var(--lh-tight)) / 2);
  max-width: var(--measure);
}

/* --------------------------------------------------------------------------
   Zigue-zague (01/09/2026, pedido do dono: "direita, esquerda, direita,
   esquerda, descendo mesmo com scroll"). A partir de 900px .metodo__step
   ganha uma terceira coluna e o conteúdo troca de lado por paridade; o nó
   fica sempre na coluna do meio, então o trilho central (--metodo-line-x
   acima) continua ligando os cinco sem desviar. Abaixo de 900px não sobra
   largura para duas margens de leitura: volta a uma coluna só, nó à
   esquerda e conteúdo à direita para as cinco etapas.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .metodo {
    --metodo-line-x: calc(50% - var(--hairline));
  }

  .metodo__step {
    grid-template-columns: minmax(0, 1fr) var(--metodo-node) minmax(0, 1fr);
    column-gap: var(--metodo-gap);
  }

  /* grid-row: 1 nos três filhos (rail, content, visual) não é decoração,
     é a CORREÇÃO da altura inconsistente (pedido do dono, medida: até 235px
     de diferença entre a peça mais alta e a mais baixa). Causa real, achada
     medindo grid-template-rows: sem row explícita, o algoritmo de
     auto-placement do Grid anda a coluna pra FRENTE a cada item posicionado
     e, se o próximo item pede uma coluna MENOR que a do cursor, ele pula pra
     próxima linha inteira — não é bug do navegador, é a regra do spec. O
     rail é sempre coluna 2; content/visual trocam entre coluna 1 e 3 por
     paridade (zigue-zague, comentário abaixo). Nas ímpares o cursor sai de
     content(1)→rail(2), e visual(3) segue reto; mas nas pares sai de
     content(3)→rail(2)... e como 2 é MENOR que 3, o rail já teria empurrado
     visual(1) pra uma segunda linha auto — a peça inteira nascia numa altura
     que dependia da ORDEM das colunas, não do texto. Travar as três em
     grid-row:1 tira essa dependência: todo mundo sempre na mesma linha. */
  .metodo__rail {
    grid-column: 2;
    grid-row: 1;
  }

  .metodo__content {
    grid-column: 1;
    grid-row: 1;
    justify-self: end;
  }

  .metodo__step:nth-child(even) .metodo__content {
    grid-column: 3;
  }

  /* A peça visual (ver bloco ".metodo__visual*" abaixo) mora na coluna
     OPOSTA à do texto — a mesma que .metodo__content deixa vazia. */
  /* Centralizada na coluna e no bloco (02/09/2026, pedido do dono: "kd a
     simetria??? tá torto" — media 242px fora do centro da coluna numa
     captura dele — e "mais centralizado" antes disso). justify-self:
     center substitui o antigo "rente ao trilho" (start/end por paridade);
     com a peça ocupando ~86% da coluna (JS, ver abaixo) a folga que sobra
     é pequena, e center reparte ela nos dois lados. align-self: center
     entra pela mesma razão, e agora funciona de verdade: altura vem do JS
     medindo .metodo__content (--metodo-visual-h), não mais da peça
     mesma — antes ERA ela quem dita a altura da linha (era quadrada,
     maior que o texto), e centrar contra uma linha que a própria peça
     define não move nada. Sem JS, a peça cai no piso do var() (não
     centralizada, mas nunca quebrada). */
  .metodo__visual {
    align-self: center;
    justify-self: center;
    grid-column: 3;
    grid-row: 1;
    inline-size: var(--metodo-visual-w, 20rem);
    block-size: var(--metodo-visual-h, 12rem);
    color: hsl(var(--muted-foreground));
  }

  .metodo__step:nth-child(even) .metodo__visual {
    grid-column: 1;
  }
}

/* --------------------------------------------------------------------------
   Cinco peças (02/09/2026, quarta correção do dono: "feio demais, negócio
   passando por dentro de texto... faz algo mais contido, premium... tipo
   esses efeitos do site humanlike" — ver partials/metodo.js, bloco "peça
   visual", pro raciocínio completo, incluindo os dois bugs de contenção
   achados e corrigidos nesta rodada.

   VOCABULÁRIO NOVO: nada de nó/aresta (diagrama técnico). Os elementos
   citam UI abstrata — retângulo = linha de texto, círculo = pessoa/ponto,
   quadrado pequeno = cartão/ícone/campo, círculo com traço = selo de
   check/x. O que fica de SISTEMA entre as cinco é só acabamento: mesmo
   traço (--metodo-visual-stroke), mesmo raio (--radius-sm nos retângulos e
   quadrados, --radius-full nos círculos — nunca cápsula, o site é
   quadrado), mesma paleta de dois tons (--muted-foreground pra estrutura,
   --signal pro que está "aceso" — o único token cromático da casa;
   --primary é tinta neutra, preto/branco, não serve pra isso) e a mesma
   escala de elemento por PAPEL (avatar sempre 13cqmin, selo sempre
   8-9cqmin, ponto pequeno 3,6cqmin, quadrado de ícone 7-8,5cqmin,
   espessura de linha 3,2cqmin) — nunca por cena. A FORMA de cada cena é
   livre; a régua por trás não muda.

   ELEVAÇÃO E CAMADAS (02/09/2026, "ainda mais premium"): cartão/painel/chip
   ganharam superfície própria (--surface-3) + --shadow-sm — eram traço puro
   sobre o fundo da seção, flutuando. O palco (.metodo__visual, abaixo)
   ganhou uma camada de fundo discreta (--surface-2 translúcido + hairline)
   que separa a peça inteira do fundo da seção. Nenhuma das duas muda a
   contenção: sombra e fundo são pintura estática, o `overflow: hidden`
   continua sendo quem garante que nada escapa do retângulo.

   PALCO: retangular, medido de verdade contra a coluna e o texto
   (partials/metodo.js, ajustarPecaVisual) — sem aspect-ratio próprio.
   `container-type: size` (não só inline-size, como antes) habilita
   cqi/cqb/cqmin corretos nos dois eixos: com só inline-size contido, cqb
   cai no fallback do viewport, e um translate3d em cqb vira um salto de
   centenas de px — era a causa real do "elemento vazando por cima do texto
   ao lado" que o dono reportou. `overflow: hidden` é o cinto e suspensório
   final: nada escapa do retângulo, nunca, mesmo se uma conta futura errar. */

.metodo__visual {
  display: none;
}

@media (min-width: 900px) {
  .metodo__visual {
    display: block;
    position: relative;
    overflow: hidden;
    container-type: size;
    container-name: metodo-visual;
    --metodo-visual-stroke: 2px;

    /* Camada de fundo discreta (02/09/2026, "premium"): sem ela a peça
       inteira flutuava direto sobre o fundo da seção. Só tinta + hairline,
       sem sombra própria — a sombra fica pras superfícies DE DENTRO
       (cartões/chips acima), senão o palco competiria com o conteúdo. */
    background-color: hsl(var(--surface-2) / 0.55);
    border: var(--hairline) solid hsl(var(--border) / 0.6);
    border-radius: var(--radius-md);
  }
}

/* ---- formas-base: geometria só, o tom vem dos modificadores abaixo ---- */

/* Retângulo (cartão/coluna): ancorado por canto (x, y = topo-esquerda),
   tamanho em % simples — um raio fixo (rem) não distorce mesmo com w/h em
   % não-uniformes, então não precisa do tratamento em cqmin dos círculos.
   Superfície própria (--surface-3) + --shadow-sm (02/09/2026, "premium" —
   cartão de traço puro flutuava sobre o fundo da seção, sem assentar). A
   variante tracejada (opção descartada, etapa 02) fica sem preenchimento
   nem sombra de propósito: material mais fraco reforça "não escolhida"
   além da cor. */
.metodo__visual-caixa {
  position: absolute;
  border-radius: var(--radius-sm);
  background-color: hsl(var(--surface-3));
  border: var(--metodo-visual-stroke) solid hsl(var(--muted-foreground) / 0.42);
  box-shadow: var(--shadow-sm);
}

.metodo__visual-caixa--tracejada {
  background-color: transparent;
  border-style: dashed;
  border-color: hsl(var(--muted-foreground) / 0.32);
  box-shadow: none;
}

/* Linha de texto (nunca palavra real — ver partial): ancorada por canto,
   largura em %, espessura fixa em cqmin (a mesma em qualquer cena).
   transform-origin: left é a base do "se escreve"/"a barra corre" (bloco
   Movimento, abaixo) — parada, não muda nada aqui. */
.metodo__visual-linha {
  position: absolute;
  block-size: 3.2cqmin;
  border-radius: var(--radius-sm);
  background-color: hsl(var(--muted-foreground) / 0.55);
  transform-origin: left;
}

.metodo__visual-linha--fraca {
  background-color: hsl(var(--muted-foreground) / 0.24);
}

/* Círculo (pessoa/ponto) e quadrado (cartão pequeno/ícone): ancorados pelo
   CENTRO (x, y), tamanho igual nos dois eixos em cqmin — só um comprimento
   físico uniforme garante um círculo de verdade num palco não-quadrado
   (esticar em % faria elipse). Dois estados: dormente (superfície própria,
   sem tinta) e aceso (preenchido a --signal — o único acento CROMÁTICO da
   casa; --primary é tinta neutra, preto/branco, não "cor"). Sombra igual
   nos dois: "suave" (pedido do dono), não um degrau de elevação por estado. */
.metodo__visual-ponto,
.metodo__visual-quadrado {
  position: absolute;
  inline-size: var(--d);
  block-size: var(--d);
  transform: translate(-50%, -50%);
  box-shadow: var(--shadow-sm);
}

.metodo__visual-ponto {
  border-radius: var(--radius-full);
}

.metodo__visual-quadrado {
  border-radius: var(--radius-sm);
}

.metodo__visual-ponto--dormente,
.metodo__visual-quadrado--dormente {
  background-color: hsl(var(--surface-3));
  border: var(--metodo-visual-stroke) solid hsl(var(--muted-foreground) / 0.5);
}

.metodo__visual-ponto--aceso,
.metodo__visual-quadrado--aceso {
  background-color: hsl(var(--signal) / 0.62);
}

/* Selo (círculo pequeno com glifo — check/x): mesma centragem por cqmin dos
   dois de cima, mas hospeda um <svg> de ícone (viewBox PRÓPRIO, 0 0 24 24,
   não o do palco — ver partial). `color` tinge o glifo via currentColor.
   Superfície própria: o selo é um badge sobre o cartão, precisa se separar
   dele visualmente, não só por estar por cima na pilha de pintura. */
.metodo__visual-selo {
  position: absolute;
  inline-size: var(--d);
  block-size: var(--d);
  border-radius: var(--radius-full);
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  background-color: hsl(var(--surface-1));
  border: var(--metodo-visual-stroke) solid currentColor;
  box-shadow: var(--shadow-sm);
}

.metodo__visual-selo--dormente {
  color: hsl(var(--muted-foreground) / 0.55);
}

.metodo__visual-selo--aceso {
  color: hsl(var(--signal) / 0.75);
}

.metodo__visual-icone {
  inline-size: 52%;
  block-size: 52%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* --------------------------------------------------------------------------
   Movimento: cada cena é uma COREOGRAFIA de 3-4 momentos que se encadeiam e
   contam a etapa (02/09/2026, "tao pouco efeito... fazer ainda mais
   premium" — reverte o "um foco só" que havia antes aqui, que deixava
   metade das cenas parecendo estática). Só opacity/transform animam; toda
   keyframe que mexe em transform repete a cadeia INTEIRA da base
   (translate(-50%,-50%) ...), nunca só o pedaço novo — animar transform
   SUBSTITUI a propriedade, não soma (era o bug do respira antigo).

   Cada cena usa UM relógio: a MESMA duração total em todos os elementos que
   participam dela. Os momentos se encaixam escalonando os PONTOS
   PERCENTUAIS do keyframe, não a duração — assim o "recomeça" de cada cena
   sai sincronizado, tudo volta ao início junto.

   REDUCED-MOTION, "cena correta parada": os três elementos cujo
   aparecimento é NO MEIO da história (o selo de "pronto" da 03, a barra e o
   selo de confirmação da 05) têm opacity:0 estático fora da animação — sem
   isso, animation:none os deixaria visíveis num estágio que ainda não
   aconteceu (peça ainda na largada, selo de pronto já aceso). O resto (as
   falas da 01, as duas opções da 02, as três linhas do painel da 04) já
   nasce visível por padrão do CSS: parado, mostra a cena inteira montada,
   que também é uma leitura correta. */

/* ---- Etapa 01 — indicadores piscam sobre a conversa, sempre visível ----
   CORRIGIDO 02/09/2026 (achado do dono, captura em 1440 escuro: cenas
   inteiras — 02 e 04 — apareciam VAZIAS, moldura sem nada dentro, porque
   TODO elemento entrava de opacity:0 no mesmo instante do laço). Regra
   nova, valendo pras cinco cenas a partir daqui: todo elemento ESTRUTURAL
   (aqui, os dois avatares e as duas linhas de fala) fica SEMPRE visível,
   sem animação nenhuma — a coreografia é só acento por cima. Os dois
   "cursores" (pontinho aceso na ponta de cada linha) piscam em sequência,
   depois os três pontos de escuta pulsam — três momentos, zero instante
   vazio, porque avatar+linha nunca saem de cena. Relógio único ×5.4
   --dur-slow. */
.metodo__visual--cursor-1 {
  opacity: 0;
  animation: nx-metodo-cursor-1 calc(var(--dur-slow) * 5.4 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--cursor-2 {
  opacity: 0;
  animation: nx-metodo-cursor-2 calc(var(--dur-slow) * 5.4 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--escuta {
  animation: nx-metodo-escuta calc(var(--dur-slow) * 5.4 * var(--motion)) var(--ease-io) infinite;
  animation-delay: calc(var(--dur-fast) * var(--i, 0) * -1);
}

@keyframes nx-metodo-cursor-1 {
  0%, 6%    { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  12%       { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
  18%, 20%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  26%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
}

@keyframes nx-metodo-cursor-2 {
  0%, 24%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  30%       { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
  36%, 38%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  44%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
}

@keyframes nx-metodo-escuta {
  0%, 42%   { opacity: 0.45; transform: translate(-50%, -50%) scale(1); }
  50%       { opacity: 1;    transform: translate(-50%, -50%) scale(1.35); }
  58%       { opacity: 0.6;  transform: translate(-50%, -50%) scale(1); }
  66%       { opacity: 1;    transform: translate(-50%, -50%) scale(1.3); }
  74%, 100% { opacity: 0.45; transform: translate(-50%, -50%) scale(1); }
}

/* ---- Etapa 02 — a opção descartada respira mais fraco, nunca some ----
   CORRIGIDO: os dois cartões eram animados (entrar/esmaecer) e os dois
   caíam em opacity:0 no MESMO instante (0% e 96-100%) — cena inteira
   vazia. Agora o cartão escolhido é ESTRUTURAL, sempre visível, sem
   animação. O descartado (cartão + linha + X) é a única coreografia de
   base: respira entre 1 e 0.4, nunca menos — "esmaece", não "desaparece".
   O selo de check é o ACENTO (pode ir a zero: a cena continua legível sem
   ele, os dois cartões seguem lá). Relógio único ×5 --dur-slow. */
.metodo__visual-caixa.metodo__visual--opcao-b,
.metodo__visual-linha.metodo__visual--opcao-b,
.metodo__visual-selo.metodo__visual--opcao-b {
  animation: nx-metodo-opcao-recusa calc(var(--dur-slow) * 5 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--carimba {
  animation: nx-metodo-carimba calc(var(--dur-slow) * 5 * var(--motion)) var(--ease-io) infinite;
}

@keyframes nx-metodo-opcao-recusa {
  0%, 40%   { opacity: 1; }
  54%, 84%  { opacity: 0.4; }
  96%, 100% { opacity: 1; }
}

@keyframes nx-metodo-carimba {
  0%, 28%  { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  38%      { opacity: 1; transform: translate(-50%, -50%) scale(1.18); }
  46%, 88% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  96%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
}

/* ---- Etapa 03 — o item atravessa as colunas, a última ganha peso ----
   Já compatível com a regra nova sem mexer: as três colunas + os dois
   cabeçalhos NUNCA animam (sempre visíveis, é a base) — só o cartão que
   viaja e o selo de "pronto" são acento, podem ir a zero, a cena continua
   legível (o quadro de três colunas nunca some). 31cqi e 62cqi continuam
   sendo a metade e o total da distância entre os centros das colunas 1 e 3
   (partials/metodo.js, case '03': 19%, 50%, 81% do palco). Ao chegar na 3ª
   coluna o cartão cresce (scale 1.14, "ganha peso") e um selo de check
   carimba do lado, "pronto". Relógio único ×5.6 --dur-slow. */
.metodo__visual--desliza-colunas {
  animation: nx-metodo-trilha calc(var(--dur-slow) * 5.6 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--03-pronto {
  opacity: 0;
  animation: nx-metodo-03-pronto calc(var(--dur-slow) * 5.6 * var(--motion)) var(--ease-io) infinite;
}

@keyframes nx-metodo-trilha {
  0%   { opacity: 0; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(0.85); }
  7%   { opacity: 1; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(1); }
  27%  { opacity: 1; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(1); }
  46%  { opacity: 1; transform: translate(-50%, -50%) translate3d(31cqi, 0, 0) scale(1); }
  63%  { opacity: 1; transform: translate(-50%, -50%) translate3d(31cqi, 0, 0) scale(1); }
  82%  { opacity: 1; transform: translate(-50%, -50%) translate3d(62cqi, 0, 0) scale(1.14); }
  91%  { opacity: 1; transform: translate(-50%, -50%) translate3d(62cqi, 0, 0) scale(1.14); }
  97%  { opacity: 0; transform: translate(-50%, -50%) translate3d(62cqi, 0, 0) scale(1.14); }
  100% { opacity: 0; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(0.85); }
}

@keyframes nx-metodo-03-pronto {
  0%, 80%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  89%       { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  93%       { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  97%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
}

/* ---- Etapa 04 — as duas leituras ficam, o alerta acende e apaga ----
   CORRIGIDO: as duas leituras também entravam de opacity:0 junto com o
   alerta — no instante 0% a cena inteira sumia. Leituras agora são
   ESTRUTURAIS (sempre visíveis, sem animação, é o painel "de pé"); só a
   linha de alerta é acento — acende (exagero de escala, "acende") e apaga,
   pode ir a zero porque as duas leituras seguem lá, o painel nunca fica
   vazio. Relógio único ×5.2 --dur-slow. */
.metodo__visual-quadrado.metodo__visual--acende {
  animation: nx-metodo-acende calc(var(--dur-slow) * 5.2 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual-linha.metodo__visual--acende-linha {
  animation: nx-metodo-acende-linha calc(var(--dur-slow) * 5.2 * var(--motion)) var(--ease-io) infinite;
}

@keyframes nx-metodo-acende {
  0%, 26%  { opacity: 0; transform: translate(-50%, -50%) translateY(5cqmin) scale(0.7); }
  36%      { opacity: 1; transform: translate(-50%, -50%) translateY(0) scale(1.22); }
  44%, 86% { opacity: 1; transform: translate(-50%, -50%) translateY(0) scale(1); }
  95%, 100% { opacity: 0; transform: translate(-50%, -50%) translateY(5cqmin) scale(0.7); }
}

@keyframes nx-metodo-acende-linha {
  0%, 26%  { opacity: 0; transform: translateY(5cqmin); }
  36%, 86% { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; transform: translateY(5cqmin); }
}

/* ---- Etapa 05 — o pacote sai, a barra corre, a checagem acende na chegada
   Já compatível com a regra nova sem mexer: o cartão de origem, as duas
   linhas dele, o trilho da barra e o avatar de destino NUNCA animam —
   sempre visíveis, é a base. 61cqi é a distância entre os centros de
   origem (23%) e destino (84%) do palco. A barra (acento — mesma técnica
   de scaleX a partir de transform-origin: left) enche no mesmo compasso da
   viagem do pacote (acento); o selo de confirmação (acento) acende quando
   as duas terminam. Os três acentos podem ir a zero: cartão, linhas e
   trilho seguem visíveis o tempo todo. Relógio único ×5 --dur-slow. */
.metodo__visual--desliza-entrega {
  animation: nx-metodo-entrega calc(var(--dur-slow) * 5 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--barra-corre {
  opacity: 0;
  background-color: hsl(var(--signal) / 0.6);
  animation: nx-metodo-barra-corre calc(var(--dur-slow) * 5 * var(--motion)) var(--ease-io) infinite;
}

.metodo__visual--confirma {
  opacity: 0;
  animation: nx-metodo-confirma calc(var(--dur-slow) * 5 * var(--motion)) var(--ease-io) infinite;
}

@keyframes nx-metodo-entrega {
  0%   { opacity: 0; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(0.8); }
  9%   { opacity: 1; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(1); }
  68%  { opacity: 1; transform: translate(-50%, -50%) translate3d(61cqi, 0, 0) scale(1); }
  82%  { opacity: 0; transform: translate(-50%, -50%) translate3d(61cqi, 0, 0) scale(0.8); }
  100% { opacity: 0; transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(0.8); }
}

@keyframes nx-metodo-barra-corre {
  0%, 9%  { opacity: 0;   transform: scaleX(0); }
  16%     { opacity: 0.9; transform: scaleX(0); }
  68%     { opacity: 0.9; transform: scaleX(1); }
  82%     { opacity: 0;   transform: scaleX(1); }
  100%    { opacity: 0;   transform: scaleX(0); }
}

@keyframes nx-metodo-confirma {
  0%, 62%  { opacity: 0; transform: translate(-50%, -50%) scale(0.7); }
  72%      { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }
  80%, 90% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  98%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
}

/* Parado (sem JS, ou reduced-motion): estrutura (avatar/linha/cartão/
   coluna/leitura/trilho) nunca teve animação — some daqui só o que já era
   opacity:0 fora do laço (03-pronto, barra-corre, confirma, os dois
   cursores da 01) e o que a animação levava a 1 volta a 1 estático
   (opcao-b, acende). Nenhuma cena fica vazia parada: é sempre o mesmo
   conjunto que fica visível rodando. */
@media (prefers-reduced-motion: reduce) {
  .metodo__visual--cursor-1,
  .metodo__visual--cursor-2,
  .metodo__visual--escuta,
  .metodo__visual--opcao-b,
  .metodo__visual--carimba,
  .metodo__visual--desliza-colunas,
  .metodo__visual--03-pronto,
  .metodo__visual--acende,
  .metodo__visual--acende-linha,
  .metodo__visual--desliza-entrega,
  .metodo__visual--barra-corre,
  .metodo__visual--confirma {
    animation: none;
  }
}

.metodo__title {
  margin: 0;
  font-size: var(--fs-h3);
}

/* Nível 2 (linha de apoio): mesmo par para a legenda da etapa E o rótulo
   "Entregável" logo abaixo — não são dois tratamentos, são o mesmo aplicado
   duas vezes (pedido do dono: padronizar a fonte, no máximo três níveis por
   etapa). A legenda é TEXTO, e o piso dela é 4,5 contra a superfície que
   hospeda a etapa, que muda com a pele; --primary não carrega esse piso (a
   paleta garante a primária contra --primary-foreground e contra o fundo a
   3:1, não contra si mesma), então a tinta é --foreground (§2.5). A
   hierarquia com o título e o corpo vem do tamanho, do peso e da entrelinha,
   nunca da cor: o croma da marca fica na trilha e no nó, que são superfície
   pintada de --primary, não tinta de glifo. */
.metodo__legend,
.metodo__entregavel-rotulo {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: 650;
  line-height: 1.45;
  color: hsl(var(--foreground));
}

/* Nível 3 (corpo): mesmo par para o texto da etapa E a lista de
   entregáveis, pelo mesmo motivo do nível 2 acima. */
.metodo__text,
.metodo__entregavel {
  margin: 0;
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  color: hsl(var(--muted-foreground));
}

/* Entregável da etapa (06/08/2026, reforma editorial, item H da spec do
   dono; padronizado para o par do corpo em 01/09/2026). Uma linha por
   etapa, com os artefatos separados por interponto na origem
   (content.metodo.etapas[].entregavel).

   COLUNA, NÃO LINHA. A primeira versão punha rótulo e valor lado a lado com
   `flex-wrap`, e o resultado foi inconsistente entre as cinco etapas: só a
   mais curta cabia na mesma linha, as outras quatro empurravam o valor para
   baixo. Rótulo sempre acima do valor resolve, e é a MESMA forma de ficha
   que .case-block__fact já usa (sections/cases.css) — só a tipografia deixou
   de copiar a de lá, para não abrir um quarto/quinto nível só para este
   campo. */
.metodo__entregavel {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* --------------------------------------------------------------------------
   Telas muito estreitas: a folga entre trilho e conteudo nao pode colapsar
   a ponto de encostar o texto no no. O clamp ja cobre a maioria dos casos;
   este ajuste so refina o minimo absoluto em 360px.
   -------------------------------------------------------------------------- */

@media (max-width: 380px) {
  .metodo__timeline {
    --metodo-gap: var(--space-4);
  }
}
