/* ============================================================================
   hwg-extras.css — adicoes da migracao React -> Laravel.

   POR QUE ESTE ARQUIVO EXISTE
   tokens.css, base.css e components.css sao artefatos READ-ONLY portados
   byte-a-byte do prototipo (7.808 linhas / 237 KB somente em components.css,
   com 20 @keyframes, 178 transitions e 23 blocos prefers-reduced-motion).
   Qualquer edicao acidental neles e impossivel de achar em code review, por isso
   tests/Feature/CssIntegrityTest.php fixa o sha256 dos tres e falha se mudarem.

   TODA regra CSS nova do projeto vem para ca.

   Carregado depois dos tres legados no <head>.
   ============================================================================ */

/* ─────────────────────────────────────────────────────────
   HERANCA DE FONTE EM CONTROLES DE FORMULARIO

   O prototipo React fazia `@import "tailwindcss"`, ou seja, embarcava o preflight
   inteiro. Este port NAO embarca o preflight de proposito (ele reescreveria as 141
   linhas de tipografia base afinadas a mao em base.css) — mas o site dependia de
   UMA regra dele: `font: inherit` em controles de formulario.

   Sem ela o <input> volta ao line-height:normal do user-agent e cada .ag-field
   fica 4,8px mais curto (60,78px -> 56px), encurtando /agendar em ~15px.
   Medido com getComputedStyle nos dois apps; com esta regra o diff volta a zero.

   Seletor de elemento (especificidade 0,0,1): qualquer regra de classe do
   components.css continua vencendo, entao font-size/peso proprios sao preservados
   e so o line-height herdado volta.
   ───────────────────────────────────────────────────────── */
input,
button,
textarea,
select {
  font: inherit;
  letter-spacing: inherit;
}

/* ─────────────────────────────────────────────────────────
   FORMULARIO /agendar — estados que o prototipo nao tinha
   (la o form era <form action="#"> sem validacao e sem backend).
   Nenhuma classe existente foi alterada; tudo aqui e classe nova.
   ───────────────────────────────────────────────────────── */

/* Honeypot: fora da tela sem display:none (bots ignoram display:none). */
.ag-honey {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Mensagem de erro por campo. */
.ag-error {
  display: block;
  margin-top: 0.5rem;
  color: #c0392b;
  font-size: var(--t-micro, 0.8125rem);
  line-height: 1.45;
  letter-spacing: 0.01em;
}

/* Resumo no topo do form. */
.ag-error--summary {
  margin: 0 0 var(--sp-4, 1.5rem);
  padding: 0.875rem 1rem;
  background: rgba(192, 57, 43, 0.06);
  border-left: 3px solid #c0392b;
  font-size: var(--t-body, 1rem);
}

/* Campo com erro: reforca a borda do .ag-input existente sem alterar a regra dele. */
.ag-input[aria-invalid='true'] {
  border-color: #c0392b;
}

.ag-input[aria-invalid='true']:focus {
  outline-color: #c0392b;
}

/* ─── Painel de sucesso (substitui o form apos o envio) ─── */
.ag-success {
  position: relative;
  padding: clamp(var(--sp-6, 2.5rem), 5vw, var(--sp-8, 4rem));
  background: var(--hwg-soft, #f2f0eb);
}

.ag-success__mark {
  display: block;
  width: 44px;
  height: 44px;
  margin-bottom: var(--sp-4, 1.5rem);
  background: var(--hwg-amber, #e07228);
  /* Mesma forma do corner-mark da marca: vertice quadrado + pontas chanfradas. */
  clip-path: polygon(0 0, 100% 0, 66% 34%, 34% 34%, 34% 66%, 0 100%);
}

.ag-success__title {
  margin: 0 0 var(--sp-3, 1rem);
  font-size: var(--t-h3, clamp(1.5rem, 3vw, 2rem));
  font-weight: var(--fw-bold, 700);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--hwg-ink, #0c1c2c);
}

.ag-success__text {
  margin: 0 0 var(--sp-5, 2rem);
  max-width: 34ch;
  font-size: var(--t-body, 1rem);
  line-height: 1.55;
  color: var(--hwg-ink, #0c1c2c);
}

.ag-success__link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--t-eyebrow, 0.875rem);
  font-weight: var(--fw-semibold, 600);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--hwg-forest, #2c6644);
}

.ag-success__link span {
  transition: transform 320ms var(--ease-out-soft, cubic-bezier(0.33, 1, 0.68, 1));
}

.ag-success__link:hover span,
.ag-success__link:focus-visible span {
  transform: translateX(4px);
}

@media (prefers-reduced-motion: reduce) {
  .ag-success__link span {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────
   MODAL DE CTA — nenhum precedente no protótipo (lá o botão era
   link puro para /agendar). `.ag-field`/`.ag-label`/`.ag-input`/
   `.ag-req`/`.ag-submit`/`.ag-honey`/`.ag-error*` são REUSADAS de
   /agendar (definidas em components.css); aqui só a moldura do
   modal em si, que não existia.
   ───────────────────────────────────────────────────────── */
.cta-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gutter);
  background: rgba(12, 28, 44, 0.72);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out-soft);
}

.cta-modal.is-open {
  opacity: 1;
  pointer-events: auto;
}

.cta-modal__box {
  position: relative;
  width: 100%;
  max-width: 420px;
  max-height: calc(100vh - var(--sp-6, 2rem) * 2);
  overflow-y: auto;
  padding: clamp(var(--sp-6, 2rem), 5vw, var(--sp-7, 3rem));
  background: var(--hwg-paper, #fff);
  transform: translateY(12px);
  transition: transform var(--dur-base) var(--ease-out-soft);
}

.cta-modal.is-open .cta-modal__box {
  transform: translateY(0);
}

.cta-modal__close {
  position: absolute;
  top: var(--sp-4, 1rem);
  right: var(--sp-4, 1rem);
  color: var(--hwg-ink, #0c1c2c);
}

/* Titulo com a MESMA fonte dos titulos do site (.ag-aside__title,
   .cta-footer__title etc.) — --ff-sans, e nao --ff-serif. --ff-serif so
   aparece em `em` dentro de corpo de texto (citacao, olho editorial); nunca em
   titulo. */
.cta-modal__title {
  margin: 0 0 var(--sp-2, 0.5rem);
  padding-right: var(--sp-6, 2rem); /* nao fica embaixo do botao fechar */
  font-family: var(--ff-sans);
  font-size: clamp(1.4rem, 2.2vw + 1rem, 1.8rem);
  font-weight: var(--fw-bold, 700);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--hwg-ink, #0c1c2c);
}

.cta-modal__lede {
  margin: 0 0 var(--sp-5, 1.5rem);
  font-size: var(--t-body, 1rem);
  line-height: 1.55;
  color: var(--hwg-ink, #0c1c2c);
  opacity: 0.72;
}

.cta-modal__form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3, 0.75rem);
}

/* Campos mais baixos que /agendar: la o form ocupa uma coluna inteira da
   pagina, aqui e um modal compacto. So o padding vertical do input muda —
   .ag-input em si (components.css) fica intocado, /agendar nao muda em nada. */
.cta-modal .ag-field {
  gap: var(--sp-1, 0.25rem);
}

.cta-modal .ag-input {
  padding-top: var(--sp-2, 0.5rem);
  padding-bottom: var(--sp-2, 0.5rem);
}

/* `.ag-error` fixa `display:block` (para o caso normal de /agendar, onde o
   span so existe no DOM quando ha erro — nunca leva o atributo `hidden`).
   Aqui o resumo de erro fica sempre no DOM e alterna via `hidden`; sem esta
   regra o `display:block` do author vence o `[hidden]` da UA stylesheet
   (origem author bate origem UA mesmo com especificidade igual), e a caixa
   aparece vazia por padrao. */
.ag-error[hidden] {
  display: none;
}

.cta-modal__submit {
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .cta-modal,
  .cta-modal__box {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────
   Ajustes pontuais sobre classes do prototipo. A regra original fica intacta
   em components.css (sha256-travado); aqui so sobrescreve a propriedade
   pedida — carregado depois, mesma especificidade, vence por ordem.
   ───────────────────────────────────────────────────────── */

/* Simbolo de fundo em .qs-quote (Quem Somos): opacidade original 0.08. */
.qs-quote__symbol {
  opacity: 0.04;
}

/* ─────────────────────────────────────────────────────────
   Vetor ambar no bloco "Processo" em formato prosa (Livro Marca).

   DIVERGE DE PROPOSITO do protótipo: o comentario original de
   components.css diz "PROSE — Personalidade como prosa fluida (substitui
   chips)" — o formato prosa nasceu sem o marcador do formato lista
   (.lm-act__list li::before) para se diferenciar dele. Pedido explicito do
   cliente, ciente da divergencia.

   UM marcador so, no inicio do paragrafo inteiro — a prosa e um bloco de
   texto continuo, nao itens separados, entao nao repete por linha visual
   como a lista repete por item. Mesma imagem/medidas do marcador da lista
   (proporcao 811:293 do "elemento lista.svg"), pela mesma identidade visual. */
.lm-act__prose {
  position: relative;
  padding-left: 1.7em;
}
.lm-act__prose::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 1.2em;
  height: 0.43em;
  background: var(--hwg-amber);
  -webkit-mask: url("../img/elementocerto.svg") left center / contain no-repeat;
          mask: url("../img/elementocerto.svg") left center / contain no-repeat;
}

/* ─────────────────────────────────────────────────────────
   Timeline da home: repouso centralizado.

   Pedido do cliente: no meio da rolagem da seção (--scroll-x volta a 0px,
   ver timeline-parallax.js), as duas fileiras devem ficar com 4 livros
   centralizados na tela, em vez do deslocamento assimétrico original
   (row--right nascia deslocada para a direita via padding-left; row--left,
   para a esquerda via margin-left negativo — nenhuma das duas centralizada
   no repouso). --book-w já é 24vw no desktop, dimensionado para ~4 livros
   caberem na largura da tela — só faltava centralizar a fileira.

   `align-items: center` no container em coluna centraliza cada fileira
   (width: max-content) pelo próprio centro geométrico; sem isto, o
   `align-items: stretch` padrão colava a fileira à esquerda e todo o
   posicionamento dependia só do padding/margin abaixo, que por isso zeram.
   O parallax cruzado (JS) continua idêntico: ele soma/subtrai deslocamento
   em cima deste repouso, então a fileira ainda desliza para os dois lados
   ao rolar — só o ponto central deixou de ser assimétrico. */
.timeline__books {
  align-items: center;
}
.timeline__row--right,
.timeline__row--left {
  padding-left: 0;
  margin-left: 0;
}

/* ─────────────────────────────────────────────────────────
   Hero do case (/case/{slug}) — imagem mais visível.

   Pedido do cliente, ajustado ao vivo no DevTools e replicado aqui: a foto
   de fundo estava apagada demais atrás do degradê escuro. Original em
   components.css: opacity 0.5 na foto/vídeo, e o primeiro stop do degradê
   (.cs-hero::after) em rgba(12, 28, 44, 0.92) 8% — quase opaco logo no topo
   da imagem. Aqui: opacity 1 (sem esmaecer a imagem em si) e o primeiro stop
   do degradê mais claro (alpha 0.60), pela mesma razão — o degradê é quem
   garante a legibilidade do texto por cima, não a opacidade da foto. */
.cs-hero__bg img,
.cs-hero__bg video {
  opacity: 1;
}
.cs-hero::after {
  background: linear-gradient(to top, rgba(12, 28, 44, 0.60) 8%, rgba(12, 28, 44, 0.35) 60%, rgba(12, 28, 44, 0.5) 100%);
}

/* ─────────────────────────────────────────────────────────
   Bloco "imagem inteira" do case (.cs-full__frame) — foto inteira, sem corte.

   Pedido do cliente, ajustado ao vivo no DevTools e replicado aqui. Original
   em components.css: aspect-ratio 16/9 no quadro, e na foto object-fit:cover
   com scale(1.12) — cortava as bordas da imagem pra preencher o quadro e
   ganhar a folga do zoom do parallax (--py). Aqui: aspect-ratio 16/7.3 (quadro
   mais baixo) e object-fit:contain com scale(1) — a imagem entra inteira, sem
   cortar nada.
   O breakpoint de celular (max-width:800px) do arquivo travado muda o
   aspect-ratio pra 4/3; sem repetir a mesma media query aqui, esta regra sem
   media (carregada depois) venceria em qualquer largura e destravaria esse
   ajuste de mobile também, que ninguém pediu. */
.cs-full__frame {
  aspect-ratio: 16 / 7.3;
}
.cs-full__frame img {
  object-fit: contain;
  transform: translateY(var(--py, 0)) scale(1);
}
@media (max-width: 800px) {
  .cs-full__frame {
    aspect-ratio: 4 / 3;
  }
}

/* ─────────────────────────────────────────────────────────
   Citação do case (.cs-quote) — sem o rótulo "Resultado" fixo em cima, e
   15% menos padding vertical.

   Pedido do cliente: o rótulo aparecia em toda citação, mesmo quando o
   texto não era um resultado (a marcação do bloco veio de
   resources/views/components/cs/quote.blade.php, removida ali). Aqui só o
   padding-y — original em components.css é
   `padding: clamp(var(--sp-9), 10vw, var(--sp-11)) var(--gutter)`;
   multiplicar o clamp inteiro por 0.85 encolhe em 15% em qualquer largura de
   tela, sem precisar recalcular os tokens à mão. padding-block em vez de
   padding para não reescrever o padding-inline (var(--gutter)), que não
   mudou. */
.cs-quote {
  padding-block: calc(clamp(var(--sp-9), 10vw, var(--sp-11)) * 0.85);
}

/* ─────────────────────────────────────────────────────────
   Seleção de texto — o realce ficava preto e comia a frase.

   base.css tem:

     ::selection { background: var(--hwg-ink); color: var(--hwg-canvas); }

   e `--hwg-canvas` NÃO EXISTE em tokens.css — o token nunca foi portado do
   protótipo (as duas únicas ocorrências no projeto são essa e o `background`
   do <body>, ambas em base.css). Um var() sem valor invalida a declaração
   inteira na hora de computar, e `color` é herdada: o texto selecionado
   ficava com a cor que já tinha, sobre um fundo #0C1C2C. Num parágrafo
   escuro, isso é tinta escura sobre tinta escura — o bloco preto que some
   com a leitura. No claro sobre escuro dava no mesmo, pelo outro lado.

   A correção não é redefinir --hwg-canvas: isso mudaria também o fundo do
   <body> (hoje inválido, e por isso pintado por outra regra), o que ninguém
   pediu. Aqui o realce ganha as duas cores explícitas, sem depender de token
   nenhum: âmbar da marca com tinta escura por cima, 5,4:1 de contraste. Como
   ::selection pinta o próprio fundo, o par vale igual nas seções claras e nas
   escuras — que é justamente o que o realce anterior não conseguia. */
::selection {
  background: var(--hwg-amber);
  color: var(--hwg-ink);
}

/* ─────────────────────────────────────────────────────────
   Interna de artigo — sem letra capitular.

   Pedido do cliente: a capitular não estava ficando boa. Original em
   components.css (.ar-content > p:first-child::first-letter): initial-letter 2,
   peso bold e cor forest. `normal` é o valor inicial de initial-letter, então
   a primeira letra volta a ocupar uma linha só; o resto é devolvido à herança
   do parágrafo, e não a valor fixo, para acompanhar qualquer mudança futura
   de .ar-content > p. */
.ar-content > p:first-child::first-letter {
  initial-letter: normal;
  -webkit-initial-letter: normal;
  font-weight: inherit;
  color: inherit;
  margin-right: 0;
}

/* ─────────────────────────────────────────────────────────
   Card de "Resultados reais" (Livro Marca / Branding Performance) — o card
   inteiro leva para o case.

   Camada esticada por cima do .bp-case__overlay (z-index 2), e não um <a> em
   volta do conteúdo: envolver o overlay mudaria a cadeia de seletores do
   components.css, que é arquivo travado, e o hover que abre .bp-case__results
   (grid-template-rows 0fr -> 1fr) pararia de casar. O <a> é vazio — o nome
   acessível vem do aria-label na view.

   .bp-case já trazia `cursor: pointer` e um conjunto de regras :focus-within
   do protótipo, escritas para este link que nunca chegou a existir; elas
   passam a valer agora, de graça. O outline só no :focus-visible mantém o
   clique de mouse sem moldura. */
.bp-case__link {
  position: absolute;
  inset: 0;
  z-index: 3;
}
.bp-case__link:focus-visible {
  outline: 2px solid var(--hwg-amber);
  outline-offset: -4px;
}

/* ─────────────────────────────────────────────────────────
   MOBILE — bugs reportados no iPhone do cliente (17 Pro Max, 440x956 CSS px).

   Contexto da investigação: renderizei hwgbranding.com.br em 440x956 e em
   393x852. O CSS de produção é byte-idêntico ao do repositório, e o mobile
   aplica normalmente nos dois (o título do hero quebra em 4 linhas igual). Os
   breakpoints do components.css vão de 480px para cima, então nenhum deles
   "escapa" num aparelho de 440px. Ou seja: não era breakpoint. As causas reais
   estão comentadas item por item abaixo.
   ───────────────────────────────────────────────────────── */

/* (1) HERO — altura travada na viewport, sobrando em branco.
   O @media (max-width: 900px) do components.css troca .hero para
   `display: block` e zera `min-height`, mas NÃO zera o
   `height: calc(100vh - var(--header-h))` que vem da regra de desktop.
   Empilhado, o conteúdo do hero mede ~584px (stage 360px + overlay ~224px); o
   resto vira branco dentro da seção. E a sobra CRESCE com a altura da tela:
   ~192px num 393x852, ~296px num 440x956 — exatamente a diferença entre o
   aparelho do cliente e os outros. Comprovado renderizando com janela de
   3400px de altura: o hero virou 3320px de branco. */
@media (max-width: 900px) {
  .hero {
    height: auto;
  }
}

/* (2) HERO SYMBOL — estado de repouso destrutivo + dimensionamento.
   O repouso do símbolo é `opacity: 0` + `scale(.7) rotate(-8deg)`, desfeito só
   quando hero.js adiciona .is-ready. Sem o JS a logo não aparece; pega no meio
   da transição, aparece INCLINADA — que é a "logo torta" do relato (renderizei
   sem JS e o símbolo saiu tombado). Aqui o repouso passa a ser o estado final,
   então falha de JS degrada para logo reta e visível. Escopo mobile de
   propósito: a animação de entrada do desktop fica intacta.

   ─── Dimensionamento (corrigido em 2026-09-11) ───
   A versão anterior deste bloco dizia corrigir uma ambiguidade de `object-fit`
   citando "caixa de 308x209 (razão 1,47) em 440px". Essa premissa estava
   errada: o `@media (max-width: 768px)` do components.css (linha 3929) já
   define `max-height: none` no símbolo, então no CELULAR aquela caixa nunca
   existiu — a caixa era 314x291, com a razão do arquivo. O corte que o cliente
   via não era object-fit, era `transform: none !important` do
   prefers-reduced-motion (ver bloco 11).

   O que a regra antiga fazia de fato, medido em WebKit 26 e Chromium (números
   iguais nos dois, então não é motor):
     - encolhia o símbolo no celular: 314x291 -> 227x211 em 393x660;
     - e RECRIAVA a divergência de razão que dizia remover: com `height: 58%`
       crescendo junto com o stage e `max-width: 70%` travando a largura, em
       440x956 a caixa ficava 308x378 para uma arte de 308x285 — 46px de vazio
       transparente acima e abaixo DENTRO do <img>.

   Correção. A altura continua mandando e a largura segue a razão do arquivo
   (819x759), mas o cinto de segurança horizontal agora é expresso como
   max-HEIGHT: um limite de largura reintroduziria a divergência de razão, um
   limite de altura não, porque a largura `auto` acompanha. Assim a caixa é
   sempre igual à arte e `object-fit` fica sem nada para decidir — letterbox
   zero de 320px a 900px, conferido.

   Os 420px do min() são o teto em tela grande: sem ele, em 767px de largura o
   símbolo passaria de 500px. Abaixo disso quem manda é a tela menos o gutter.

   O 86% do celular (bloco separado abaixo) é o que fecha o branco: o
   .hero__stage é `flex: 1 1 auto` dentro de uma hero com
   `min-height: calc(100svh - header)`, ou seja, engole TODA a sobra vertical
   da tela. Com 58% o símbolo ocupava pouco desse stage e sobravam ~150px de
   branco morto acima e abaixo num iPhone 13/14. Com 86% o símbolo cresce até
   a largura da tela permitir: 273x253 -> 342x317, e o vão cai de 147px para
   115px. Acima de 768px o 58% continua valendo, onde já estava certo. */
@media (max-width: 900px) {
  .hero__symbol {
    opacity: 1;
    transform: translate(-50%, calc(-50% + var(--py, 0px))) scale(1) rotate(0deg);
    height: 58%;
    width: auto;
    max-width: none;
    max-height: calc(min(100vw - 2 * var(--gutter), 420px) * 759 / 819);
  }
}
@media (max-width: 768px) {
  .hero__symbol {
    height: 86%;
  }
}
/* (3) MARCAS — logos fora de escala no celular.
   O @media (max-width: 600px) do components.css deixa
   `--slot: clamp(100px, 28vw, 140px)` com `--row-gap: clamp(sp-6, 8vw, sp-7)`:
   cada logo ocupa ~36vw, então só ~2,5 caberiam por linha. Em 440px o "sincorá"
   tomava 41% da largura e os das pontas saíam cortados. Com os valores abaixo
   entram 4 por linha (~110px cada em 440px).

   O marquee continua fechando: o loop é `translateX(-50%)` sobre a lista
   duplicada, então depende da proporção, não dos valores absolutos. */
@media (max-width: 600px) {
  .brands {
    --slot: clamp(76px, 20vw, 104px);
    --row-gap: clamp(var(--sp-4), 5vw, var(--sp-6));
  }
  .brands-row li {
    height: clamp(40px, 11vw, 60px);
  }
}

/* (4) REVEAL — conteúdo que desaparece quando o JS não roda.
   Inversão da lógica: nasce VISÍVEL, e só é escondido depois que o JS provou
   que sabe revelar (html.reveal-ready, marcado no <head>). Ver o comentário do
   script em partials/head.blade.php.

   As duas regras são deliberadamente de especificidade (0,1,0), igual ao
   `.reveal` original. Isso é o que preserva os overrides por elemento que já
   existem no components.css com (0,2,0) — .timeline__title.reveal,
   .qs-quote__title.reveal, .qs-building__photo.reveal (clip-path) e
   .qs-diagram__wheel.reveal. Um seletor mais específico aqui (o óbvio
   `html.reveal-ready .reveal:not(.is-visible)` pesa (0,3,1)) passaria por cima
   deles e quebraria quatro animações que hoje funcionam. Daí os :where(),
   que contribuem zero. */
.reveal {
  opacity: 1;
  transform: none;
}
:where(html.reveal-ready) .reveal:not(:where(.is-visible)) {
  opacity: 0;
  transform: translateY(20px);
}

/* (5) METHOD-CARD — tinta de hover grudada no toque.
   O painel creme/laranja do print é `.method-card:hover` aplicando
   `background-color: var(--card-tint)` (rgba(224,114,40,.05) no card de
   Branding Performance). O iOS mantém :hover depois do toque até você tocar em
   outro lugar, então a tinta fica acesa.

   Já existia uma guarda, mas atrás de `(hover: none) and (pointer: coarse)`.
   Aqui ela é reescrita só com `(hover: none)`, que é a condição que realmente
   importa e cobre também aparelho que reporte `pointer: fine`.

   Ressalva honesta: eu NÃO reproduzi este item. Em 440px o painel não aparece
   no meu render, então ou o print pegou o dedo pressionando, ou a guarda antiga
   não estava casando no Safari dele. Esta mudança ataca a segunda hipótese. */
@media (hover: none) {
  .method-card:hover {
    background-color: transparent;
    transform: none;
  }
  .method-card:active {
    background-color: var(--card-tint);
    transform: translateY(-2px);
  }
}

/* (6) METHOD-CARD — texto encostado na borda da caixa no mobile.
   O @media (max-width: 768px) do components.css deixa o card com
   `padding: clamp(sp-5, 5vw, sp-7) 0` — padding horizontal ZERO. Todo o
   conteúdo (título, verbos, régua, parágrafo e botão) encosta na borda do card,
   que fica visível quando a tinta de :active acende. Mesmo breakpoint da regra
   original, para casar exatamente onde o `0` é aplicado.

   `padding-inline` e não a shorthand: as regras de :first-child/:last-child do
   components.css — (0,3,0) — ajustam só padding-top/bottom e continuam valendo.
   O seletor aqui empata em (0,2,0) com a regra da shorthand, e como este
   arquivo carrega depois o padding-inline ganha do `0` dela sem tocar no
   vertical.

   Só mobile: o desktop já tem `padding: ... clamp(sp-6, 4vw, sp-9)` próprio e
   está fechado. */
@media (max-width: 768px) {
  .filosofia__cards .method-card {
    padding-inline: clamp(var(--sp-4), 4vw, var(--sp-6));
  }

  /* O `padding-right: clamp(56px, 14vw, 80px)` do body existe para o parágrafo
     não passar por baixo do corner mark (.method-card__sign, ancorado em
     `right: 0` na borda do card). Agora o padding do card já reserva parte
     dessa distância, então o do body desce no mesmo tanto: a borda direita do
     parágrafo fica onde está hoje e o ganho aparece todo à esquerda, sem deixar
     o texto torto. Em 440px: 17,6px de card + 44px de body = os ~61,6px de
     reserva de antes, contra os 48,4px de largura do sign. */
  .filosofia__cards .method-card__body {
    padding-right: clamp(40px, 10vw, 64px);
  }
}

/* (7) LM-METHOD — linha tracejada abaixo do bloco "marca".
   O @media (max-width: 768px) do components.css dá ao .lm-method__anchor um
   `border-bottom: 1px dashed rgba(12,28,44,.12)`. Ela existe SÓ no mobile: é o
   substituto dos .lm-method__connectors (o SVG do compasso), que nesse mesmo
   bloco viram `display: none`. Pedido do cliente para sair.

   Só o border cai. O `padding-bottom` fica: ele é o que mantém o respiro entre
   o bloco "marca" e a primeira dimensão ("Representa"), junto com o `gap` do
   grid do compasso — tirar os dois colaria os blocos.

   Desktop intacto: lá o border-bottom nunca existiu, quem liga o centro às
   dimensões é o SVG. */
@media (max-width: 768px) {
  .lm-method__anchor {
    border-bottom: 0;
  }
}

/* (8) BP-METHOD — grid sem a seta do meio.
   O span .bp-method__arrow saiu do markup (ver sections/bp-method.blade.php);
   as regras dele no components.css ficam órfãs e inertes. O manifesto era
   `grid-template-columns: minmax(0,1fr) auto minmax(0,1fr)`, com a seta na
   coluna do meio; sem o elemento, o auto-placement jogaria o 2º ato na coluna
   `auto` (que dimensiona pelo conteúdo) e deixaria a 3ª vazia — os dois atos
   ficariam encostados à esquerda e de larguras diferentes.

   `min-width: 721px` complementa exatamente o `max-width: 720px` do
   components.css, que é onde o manifesto vira `1fr` empilhado. Sem essa
   guarda a regra venceria a do mobile (este arquivo carrega depois) e o
   celular voltaria a ter duas colunas lado a lado. */
@media (min-width: 721px) {
  .bp-method__manifesto {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* (9) BP-PROBLEM — linha embaixo da palavra em destaque.
   O sublinhado de "estratégia" / "coerência" / "valor" era desenhado por DUAS
   camadas no components.css, as duas precisam sair:

   a) `.bp-problem__gap` com `border-bottom: 2px dashed color-mix(...)` — o
      tracejado fraco de base, mais o `padding-bottom: 0.04em` que abria espaço
      para ele.
   b) `.bp-problem__gap::after` — a barra sólida de 2px na cor do destaque, que
      animava de scaleX(0) para scaleX(1) quando o item entrava na tela. É esta
      que aparece no print.

   `display: none` no pseudo-elemento e não `transform: none`: dentro de
   @media (prefers-reduced-motion: reduce) o components.css força
   `transform: scaleX(1) !important` na barra. Um pseudo-elemento que não é
   renderizado ignora o transform, então o `!important` fica sem efeito — sem
   precisar de !important da minha parte.

   Sem media query: as duas regras originais são base, então a linha aparecia
   no mobile E no desktop. Removida nos dois, para os breakpoints não
   divergirem. */
.bp-problem__gap {
  border-bottom: 0;
  padding-bottom: 0;
}
.bp-problem__gap::after {
  display: none;
}

/* (10) TIMELINE — buraco branco no lugar dos livros (mobile).
   .timeline__books carrega a classe .reveal, então nasce em `opacity: 0` e só
   aparece quando reveal.js adiciona .is-visible pelo IntersectionObserver. O
   elemento tem ~597px de altura e OCUPA esse espaço mesmo invisível — é
   exatamente o tamanho do vazio branco do print. O título logo acima aparece
   porque o components.css o força a visível (.timeline__title.reveal, linha
   649), e essa assimetria é o que deixa a seção com cara de quebrada: texto
   presente, resto sumido.

   Não consegui reproduzir por que o observer não dispara nesse aparelho (o
   failsafe já publicado cobre bundle-não-carregado, e ali o bundle carrega).
   Como não sei a causa, a correção é determinística em vez de especulativa:
   os livros passam a nascer visíveis, seguindo o MESMO padrão que o
   components.css já aplica ao título desta seção. Assim não existe caminho em
   que sobre o vazio.

   Custo: os livros perdem o fade de entrada no mobile. Um strip decorativo sem
   fade é melhor que 600px de branco. Especificidade (0,2,0) para ganhar da
   regra de esconder do failsafe, que é (0,1,0) de propósito.

   Escopo mobile: no desktop ninguém reportou e o fade funciona — se aparecer
   lá também, é só tirar o @media.

   SUPERADO pelo item (12): no mobile a `.timeline__books` inteira saiu de cena
   (`display: none`) e quem aparece é o `.timeline__carousel`, que nasce sem a
   classe `.reveal`. Um elemento que não é renderizado não reserva altura, então
   o vazio deixou de ser possível por construção, e não por remendo de opacity.
   A regra abaixo só valeria para uma fileira que agora não existe nesse
   breakpoint — removida para não sobrar CSS morto apontando para um bug que
   mudou de solução. O relato original fica registrado aqui de propósito: é o
   histórico que explica por que o carrossel do Blade não leva `.reveal`. */

/* (11) HERO SYMBOL — banner cortado no canto inferior direito no iPhone.
   Sintoma do relato: no iPhone/Safari o símbolo da home aparece jogado para
   baixo e para a direita, cortado nas duas bordas; no Android aparece certo.

   NÃO é o Safari engasgando no translate. Medi a página publicada no WebKit
   26 (mesmo motor do Safari atual) em 375, 390, 393, 402, 414, 428, 430 e
   440px: em todas o transform é aplicado normalmente
   (matrix(1,0,0,1,-123,-114) em 393px) e o símbolo fica centrado e inteiro.

   O gatilho é o "Reduzir movimento" ligado no aparelho. O components.css tem,
   na linha 559:

     @media (prefers-reduced-motion: reduce) {
       .hero__symbol, .hero__portrait, ... { transform: none !important; }
     }

   e o transform do .hero__symbol acumula DOIS papéis: anima a entrada
   (scale/rotate) e POSICIONA o elemento — é o translate(-50%, -50%) que
   centraliza a imagem sobre o top: 50% / left: 50%. Ao zerar tudo, some
   também a centralização: a imagem passa a ser ancorada pelo canto superior
   esquerdo em 50%/50% do stage, transborda para a direita e para baixo, e o
   `overflow: hidden` da .hero corta a sobra.

   Reproduzido: com reducedMotion=reduce o símbolo cai em x=197 (= left: 50%)
   e y=477, cortado 31px à direita e 29px embaixo — o print do aparelho.
   O Android do outro teste simplesmente está sem a opção ligada.

   A correção devolve, dentro da MESMA media query, só o translate que
   posiciona. scale(1)/rotate(0deg) ficam de fora por serem identidade, e o
   parallax --py também: o hero.js já retorna antes de escrevê-lo quando há
   reduced motion. Ou seja, nenhum movimento volta — só o lugar.

   Sem media query de largura de propósito: a regra quebrada é global e no
   desktop o estrago é maior (left: 73% atira o símbolo para fora da tela).
   Fora de prefers-reduced-motion nada muda.

   Especificidade (0,1,0) com !important, igual à do components.css; este
   arquivo carrega depois, então vence por ordem.

   .qs-hero__symbol e .bp-hero__symbol caem em regras iguais, mas lá o
   transform é só translateY de animação — `transform: none` não desloca nada
   e ficam como estão. */
@media (prefers-reduced-motion: reduce) {
  .hero__symbol {
    transform: translate(-50%, -50%) !important;
  }
}

/* (12) TIMELINE — carrossel no lugar do parallax (mobile).
   Pedido do cliente: o deslize cruzado das duas fileiras ao rolar a página fica
   só no desktop. No mobile ele não se sustenta — a fileira tem `width:
   max-content` e no telefone isso é uma faixa ~4x mais larga que a tela, então
   o que o aparelho mostra é uma capa e meia se mexendo sozinha, sem o efeito de
   conjunto que existe em 1440px.

   No lugar entra um carrossel com setas. A troca é de BLOCO, não de layout: o
   Blade renderiza `.timeline__books` (8 posições ciclando, que o parallax
   precisa para nunca deixar vão) e `.timeline__carousel` (cada case uma vez)
   como irmãos, e cada breakpoint mostra um. Ver o comentário do Blade.

   O corte é 900px, o mesmo que o timeline-parallax.js consulta a cada frame
   para não rodar à toa — se mudar aqui, mude lá.

   O trilho é `data-scroller`, o mesmo módulo da faixa de artigos: as setas usam
   `disabled` de verdade e o `.blog__nav-btn:disabled` do components.css já as
   apaga nas pontas. Nenhum JS novo. */
.timeline__carousel {
  display: none;
}

@media (max-width: 900px) {
  .timeline__books {
    display: none;
  }

  .timeline__carousel {
    display: block;
  }

  /* `scroll-padding-inline` alinha o encaixe do snap com o gutter: sem ele o
     card pararia colado na borda da tela, e não na margem do resto da página. */
  .timeline__carousel-track {
    display: flex;
    gap: clamp(var(--sp-3), 3vw, var(--sp-4));
    padding-inline: var(--gutter);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
    cursor: grab;
  }
  .timeline__carousel-track::-webkit-scrollbar { display: none; }

  /* Espelha .blog__cards.is-dragging: durante o arrasto de mouse o snap tem que
     sair do caminho, senão ele puxa o trilho de volta a cada pixel. O
     `pointer-events: none` no link é o que impede o arrasto de virar navegação
     ao soltar o botão sobre uma capa. */
  .timeline__carousel-track.is-dragging {
    cursor: grabbing;
    user-select: none;
    scroll-behavior: auto;
    scroll-snap-type: none;
  }
  .timeline__carousel-track.is-dragging a { pointer-events: none; }

  /* 82vw deixa uma fatia do próximo livro à mostra — é o que diz "tem mais,
     arrasta" sem precisar de texto. O teto de 380px é para o tablet: sem ele,
     em 900px o card viria com 738px de largura e ~830px de altura (a
     `aspect-ratio: 4/4.5` do .timeline__book), mais alto que a tela. Acima de
     ~560px o teto troca a espiada por um segundo livro inteiro (medido no
     WebKit: 1,97 livro por tela em 820px), que continua lendo como carrossel. */
  .timeline__carousel-track .timeline__book {
    flex: 0 0 min(82vw, 380px);
    scroll-snap-align: start;
  }

  .timeline__carousel-nav {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--sp-5);
    margin-top: clamp(var(--sp-4), 4vw, var(--sp-5));
  }
}

/* (13) MARCAS — faixa navegável por setas onde o marquee não serve.

   DOIS CENÁRIOS, UMA SOLUÇÃO. A media query abaixo é uma lista separada por
   vírgula, ou seja, um OU:

   a) MOBILE (até 900px) — pedido do cliente, repetido: no celular ele quer
      escolher a marca que vai olhar, em vez de esperar o logo passar. Aqui a
      animação é DESLIGADA de propósito (`.brands-row { animation: none }`
      abaixo): seta e marquee não convivem na mesma faixa, porque a animação
      puxa de volta o que o dedo empurra. O corte é 900px, o mesmo da Timeline.

   b) prefers-reduced-motion, em QUALQUER largura — aqui o components.css
      (~1073) já congelava a animação, e com razão: um marquee infinito é o caso
      de manual dessa preferência. Só que ele congelava e pronto, e `.brands` é
      `overflow: hidden`: os logos de fora da tela ficavam inalcançáveis, sem
      rolar e sem esperar. Medido no WebKit em 390px: 5 de 24.

   O que o bloco faz nos dois casos:

   1. a faixa vira área rolável na horizontal — isto é CSS puro, então o dedo
      desliza mesmo se o bundle do Vite não chegar;
   2. as duplicatas somem. Cada fileira traz os logos duas vezes porque o loop
      do keyframes fecha em -50%; com a animação parada elas viram só repetição,
      dobrando o comprimento da rolagem à toa;
   3. as setas aparecem — mas só sob `.is-navegavel`, que o brands-nav.js marca.
      Sem JS não sobram botões mortos, e o item 1 ainda vale.

   FORA desses dois casos (desktop, movimento permitido) nada muda: as setas são
   `display: none`, `.brands` continua `overflow: hidden` e o marquee roda como
   sempre rodou. O brands-nav.js até registra os listeners lá, mas em botão
   escondido não há clique — quem liga e desliga é esta media query, que
   reavalia sozinha ao girar o aparelho. */
.brands-nav {
  display: none;
}

@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  /* Seta e marquee não convivem: a animação desfaz a rolagem a cada frame. Sob
     reduced-motion o components.css já zera isto; aqui a regra existe para o
     caso (a), o mobile, onde a preferência pode estar desligada. */
  .brands-row {
    animation: none;
  }

  .brands {
    /* `overflow-x` precisa vir junto de um `overflow-y` explícito: `hidden` no
       eixo Y com `auto` no X é a única combinação que rola de lado sem criar
       barra vertical. */
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;

    /* Recuo só no INÍCIO, exatamente como `.blog__cards` (components.css ~1128)
       faz com a faixa de artigos. Parada, a fileira começava em x=0, colada na
       borda da tela: num marquee isso é certo (o logo entra deslizando pela
       borda), numa faixa parada lê como logo cortado. O fim continua rente de
       propósito — é o corte na borda direita que diz "tem mais para o lado". */
    padding-inline-start: var(--gutter);
    padding-inline-end: 0;
    scroll-padding-inline-start: var(--gutter);
  }
  .brands::-webkit-scrollbar { display: none; }

  /* A afordância de arrasto com mouse; `.brands.is-dragging` já existe no
     components.css (~1138), escrito para este mesmo elemento. */
  .brands.is-navegavel { cursor: grab; }

  /* A metade duplicada só serve ao loop da animação, que aqui não roda. */
  .brands-row li[aria-hidden='true'] { display: none; }

  /* Some com o deslocamento de meia coluna da 2ª fileira: ele existe para
     intercalar as duas enquanto deslizam em looping. Paradas e roláveis juntas,
     ele só empurraria a fileira de baixo para fora do início. */
  .brands-row:last-child { margin-left: 0; }

  /* A classe é marcada na FAIXA, e os botões são o irmão logo depois dela no
     Blade — daí o seletor de irmão adjacente em vez de repetir a classe nos
     dois elementos. */
  .brands.is-navegavel + .brands-nav {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--sp-5);
    margin-top: clamp(var(--sp-5), 4vw, var(--sp-6));
  }
}

/* (14) HERO — o símbolo descendo junto com a rolagem e sendo cortado (mobile).
   Relato do cliente: "ao rolar para baixo a imagem do banner desce junto e fica
   cortada, passando por baixo da seção das marcas".

   É o parallax do `hero.js`: ele escreve `--py = rolagem * 0.22` no
   `.hero__symbol`, e o `components.css` soma esse valor ao translate que
   posiciona o símbolo. No desktop funciona — o hero ocupa a tela inteira e há
   folga de sobra em volta.

   No mobile não há folga. O `.hero__stage` vira um bloco de altura fixa na
   pilha (~360px), o símbolo é `position: absolute` centrado nele, e o `.hero` é
   `overflow: hidden`. Enquanto o `--py` empurra o símbolo para baixo, a borda de
   baixo do hero sobe na tela: as duas se encontram. Medido no WebKit em 390px:

     rolagem 600px → --py 116px → nada cortado
     rolagem 700px → --py 138px → 22px do símbolo cortados
     rolagem 800px → --py 160px → 44px cortados

   Os 44px são o pedaço que aparece decepado no print, rente à faixa branca das
   marcas. Não é a seção passando por cima: é o símbolo saindo por baixo do hero.

   `!important` é necessário, não é preguiça: o `hero.js` escreve o `--py` como
   estilo INLINE, e declaração inline normal vence regra de folha de estilo
   normal. Só `!important` de autor passa na frente. Isso também deixa o conserto
   íntegro se o bundle do Vite não carregar, e cobre o valor que ficaria
   congelado ao girar o aparelho de paisagem (>900px) para retrato.

   O corte é 900px, o mesmo que o hero.js consulta a cada frame — e o mesmo da
   Timeline e das Marcas. Acima disso o parallax segue intacto. */
@media (max-width: 900px) {
  .hero__symbol {
    --py: 0px !important;
  }
}

/* (15) RESULTADOS — seção da home (logo após a linha do tempo) e página
   /resultados. Layout novo, sem equivalente no protótipo: por isso tudo aqui, e
   nada no components.css travado.

   Card = etiqueta âmbar + cliente + título, sem imagem. A seção da home repete
   a mecânica da linha do tempo — duas fileiras de 4, ciclando quando há menos de
   8 resultados — mas SEM o deslize no scroll: as fileiras são grades estáticas.
   Até 900px as fileiras saem e entra o carrossel `data-scroller` (cada resultado
   uma vez), no mesmo corte e com o mesmo trilho da timeline (item 12).

   A cantoneira do título é a `.corner-mark` do components.css (máscara do
   elemento.svg), espelhada para virar ┐, como a `--inline-end` da timeline — só
   que ancorada no canto do bloco, que é onde o layout a desenha. */
.results-strip {
  background: var(--hwg-paper);
  color: var(--hwg-ink);
  padding: clamp(var(--sp-8), 7vw, var(--sp-10)) var(--gutter) clamp(var(--sp-8), 8vw, var(--sp-10));
  /* Mesma linha que separa a timeline da filosofia (border-top do .filosofia
     no components.css): com a secao entre as duas, a timeline perdeu o fio. */
  border-top: 1px solid rgba(0, 0, 0, 0.25);
}

.results-strip__title {
  position: relative;
  width: fit-content;
  /* Em em, e nao ch: o `fit-content` so encolhe a caixa ate a largura maxima,
     nunca ate a linha mais longa depois de quebrar. Com 12em a caixa fica rente
     as linhas, e a cantoneira cai sobre o fim da primeira, como no layout. */
  max-width: 12em;
  margin: 0 auto clamp(var(--sp-7), 7vw, var(--sp-10));
  font-size: clamp(1.8rem, 0.9rem + 2.6vw, 3.4rem);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  letter-spacing: var(--tr-snug);
  text-align: center;
  text-wrap: balance;
}
.results-strip__title .amber { color: var(--hwg-amber); }

.results-strip__mark {
  position: absolute;
  top: -0.3em;
  right: -0.75em;
  width: 0.72em;
  transform: scaleX(-1);
}

.results-strip__rows {
  display: grid;
  gap: clamp(var(--sp-7), 5vw, var(--sp-9));
  max-width: var(--container-max);
  margin-inline: auto;
}

.results-strip__row,
.results-page {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: clamp(var(--sp-5), 4vw, var(--sp-9));
}

.result-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: var(--hwg-ink);
  text-decoration: none;
  transform-origin: left center;
}
.result-card:focus-visible {
  outline: 2px solid var(--hwg-amber);
  outline-offset: 6px;
}

.result-card__tag {
  display: inline-block;
  padding: 0.5em 1.1em;
  border-radius: 4px;
  background: var(--hwg-amber);
  color: var(--hwg-paper);
  font-size: var(--t-micro);
  font-weight: var(--fw-bold);
  letter-spacing: 0.02em;
  line-height: 1;
  text-transform: uppercase;
}

.result-card__client {
  margin-top: var(--sp-3);
  font-size: clamp(0.85rem, 0.8rem + 0.15vw, 0.95rem);
  font-weight: var(--fw-regular);
}

.result-card__title {
  margin-top: var(--sp-5);
  max-width: 13em;
  font-size: clamp(1rem, 0.9rem + 0.3vw, 1.2rem);
  font-weight: var(--fw-bold);
  line-height: 1.45;
}

/* O layout mostra um card maior que os outros: é o hover. Escala, e não
   font-size, para não empurrar os vizinhos da grade. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .result-card {
    transition: transform var(--dur-base) var(--ease-out-soft);
  }
  .result-card:hover {
    transform: scale(1.08);
  }
}

.results-strip__carousel {
  display: none;
}

/* Página /resultados: a mesma grade, com todos os resultados uma vez cada. */
.results-page {
  max-width: var(--container-max);
  margin: 0 auto;
  row-gap: clamp(var(--sp-7), 5vw, var(--sp-9));
  padding: clamp(var(--sp-6), 5vw, var(--sp-8)) var(--gutter) clamp(var(--sp-8), 8vw, var(--sp-10));
}
.results-page__empty {
  grid-column: 1 / -1;
  font-size: var(--t-body);
}

@media (max-width: 900px) {
  .results-strip__rows {
    display: none;
  }

  .results-strip__carousel {
    display: block;
    margin-inline: calc(-1 * var(--gutter));
  }

  /* Mesmo trilho da timeline (item 12): snap no gutter, arrasto sem snap. */
  .results-strip__track {
    display: flex;
    gap: clamp(var(--sp-5), 5vw, var(--sp-6));
    padding-inline: var(--gutter);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
    cursor: grab;
  }
  .results-strip__track::-webkit-scrollbar { display: none; }
  .results-strip__track.is-dragging {
    cursor: grabbing;
    user-select: none;
    scroll-behavior: auto;
    scroll-snap-type: none;
  }
  .results-strip__track.is-dragging a { pointer-events: none; }

  /* Deixa a borda do próximo card à mostra: é o que diz "arrasta". */
  .results-strip__track .result-card {
    flex: 0 0 min(72vw, 300px);
    scroll-snap-align: start;
  }

  .results-strip__nav {
    display: flex;
    justify-content: center;
    gap: var(--sp-5);
    margin-top: clamp(var(--sp-5), 5vw, var(--sp-6));
  }

  .results-page {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .results-page {
    grid-template-columns: minmax(0, 1fr);
  }

  /* No celular o titulo ocupa a largura toda: a cantoneira sai menos para fora,
     senao encosta na borda da tela. */
  .results-strip__mark {
    right: -0.35em;
  }
}

/* (16) MENU — sexto item (Resultados).
   O components.css escalona a entrada dos cinco links do protótipo, de 120 em
   60ms (120 a 360ms). O sexto segue o mesmo passo; sem esta regra ele entraria
   sem atraso, antes de todos. O schema (Shared\Navegacao) trava o menu em 6. */
.menu-overlay.is-open .menu-link:nth-child(6) { animation-delay: 420ms; }

/* Com seis itens o menu deixou de caber em notebook baixo: em 1280x720 ele
   cabia exato com cinco e passou a sobrar 90px, empurrando a frase e as redes
   sociais para fora da tela (em 1366x650 a sobra, que ja existia, foi de 111
   para 209px). So em tela baixa de desktop o nome passa a acompanhar tambem a
   ALTURA da janela; acima de 820px de altura, e no celular, nada muda. */
@media (min-width: 901px) and (max-height: 820px) {
  .menu-link__name {
    font-size: clamp(2rem, min(5.4vw, 6.2vh), 4.8rem);
  }
}

/* (17) TIMELINE — legenda nos livros: título do case, filete âmbar e cliente.
   O cliente só aparece no hover, e até lá NÃO OCUPA ESPAÇO: o título fica rente
   ao pé do card e, no hover, a linha do cliente se abre embaixo e empurra
   título e filete para cima. Em aparelho sem hover (toque) o cliente fica
   sempre visível, senão nunca apareceria. Degradê de baixo para cima para o texto
   branco ler sobre qualquer capa. A tag "Case" continua no canto de cima.

   A legenda fica DENTRO do link, com pointer-events herdados: clicar no texto
   continua abrindo o case. */
.timeline__caption {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  --caption-gap: clamp(var(--sp-2), 1vw, var(--sp-3));
  gap: var(--caption-gap);
  padding: clamp(var(--sp-7), 5vw, var(--sp-9)) clamp(var(--sp-4), 2vw, var(--sp-6)) clamp(var(--sp-4), 2vw, var(--sp-6));
  background: linear-gradient(to top, rgba(12, 28, 44, 0.9) 0%, rgba(12, 28, 44, 0.55) 55%, rgba(12, 28, 44, 0) 100%);
  color: var(--hwg-paper);
  text-align: left;
}

.timeline__caption-title {
  font-size: clamp(1.15rem, 0.9rem + 0.9vw, 1.75rem);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tr-snug);
  line-height: 1.15;
}

.timeline__caption-rule {
  display: block;
  width: clamp(32px, 3vw, 48px);
  height: 2px;
  background: var(--hwg-amber);
}

.timeline__caption-client {
  display: block;
  font-size: clamp(0.8rem, 0.75rem + 0.2vw, 0.95rem);
  font-weight: var(--fw-medium);
  line-height: 1.3;
}

/* Fechado: altura zero e o `gap` do flex anulado pela margem negativa. Sem a
   margem sobraria um vão do tamanho do gap sob o filete. max-height de 2.6em
   comporta nome de cliente em até duas linhas. O texto só acende depois que a
   linha começou a abrir (atraso no opacity), para não surgir sobre o filete. */
@media (hover: hover) {
  .timeline__caption-client {
    max-height: 0;
    margin-top: calc(-1 * var(--caption-gap));
    overflow: hidden;
    opacity: 0;
    transition: max-height var(--dur-base) var(--ease-out-soft),
                margin-top var(--dur-base) var(--ease-out-soft),
                opacity var(--dur-fast) var(--ease-out-soft);
  }
  .timeline__book:hover .timeline__caption-client,
  .timeline__book-link:focus-visible .timeline__caption-client {
    max-height: 2.6em;
    margin-top: 0;
    opacity: 1;
    transition: max-height var(--dur-base) var(--ease-out-soft),
                margin-top var(--dur-base) var(--ease-out-soft),
                opacity var(--dur-base) var(--ease-out-soft) 120ms;
  }
}

@media (hover: hover) and (prefers-reduced-motion: reduce) {
  .timeline__caption-client,
  .timeline__book:hover .timeline__caption-client {
    transition: none;
  }
}

/* (18) OBRIGADO — confirmação do modal de CTA (/obrigado).
   Página nova, sem equivalente no protótipo. Monta-se só com peças que o site
   já tem: o eyebrow das páginas internas, com a cantoneira âmbar
   (`.lm-method__eyebrow`), título bold com destaque âmbar e o botão do
   formulário (`.ag-submit`, aqui como link e com largura do conteúdo).

   A seção ocupa a altura da tela menos o header fixo, com o conteúdo centrado
   na vertical: o rodapé sem CTA (footerBare) fica abaixo da dobra. */
.thanks {
  margin-top: var(--header-h);
  min-height: calc(100svh - var(--header-h));
  display: grid;
  align-items: center;
  padding: clamp(var(--sp-7), 7vw, var(--sp-10)) var(--gutter);
  background: var(--hwg-paper);
  color: var(--hwg-ink);
}

.thanks__inner {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(var(--sp-4), 2.4vw, var(--sp-5));
}

.thanks__title {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(2rem, 1.1rem + 3.4vw, 4rem);
  font-weight: var(--fw-bold);
  line-height: 1.08;
  letter-spacing: var(--tr-tight);
  /* balance no desktop ("agora a conversa / continua no WhatsApp."); no celular
     ele deixava "continua" sozinho, e la entra pretty — ver o @media abaixo. */
  text-wrap: balance;
}
.thanks__title .amber { color: var(--hwg-amber); }
.thanks__line { display: block; }
.thanks__line + .thanks__line { margin-top: 0.12em; }

.thanks__countdown {
  margin: clamp(var(--sp-3), 2vw, var(--sp-5)) 0 0;
  font-size: var(--t-body);
  opacity: 0.7;
}

.thanks__btn {
  width: auto;
  padding-inline: clamp(var(--sp-5), 3vw, var(--sp-7));
  text-decoration: none;
}

@media (max-width: 560px) {
  .thanks__title {
    text-wrap: pretty;
  }

  .thanks__btn {
    width: 100%;
  }
}
