/* ==========================================================================
   Chase — componentes do design system do handoff

   Este arquivo é a segunda camada do redesenho. A primeira, `ponte.css`, só
   trocou os VALORES dos tokens: cor, fonte, raio, sombra, espaço. Isso mudou
   a cara do site menos do que se esperava, por um motivo concreto — a paleta
   antiga já era muito próxima da nova (o amarelo é idêntico, o azul difere em
   poucos pontos, e as escalas de espaço e de tipo coincidem).

   O que muda de verdade a identidade do handoff são os componentes e o
   layout. É o que entra aqui, na ordem em que aparece na tela.

   Carrega junto com o resto da camada e obedece o mesmo interruptor
   `CHASE_DS_ATIVO`, então desligar devolve o tema anterior por inteiro.
   ========================================================================== */

/* ==========================================================================
   1. Barra de aviso acima do header

   Do `referencia/loja/Header.jsx`. Faixa azul escura com a promessa de valor
   à esquerda e o contato em amarelo à direita.

   O amarelo aqui NÃO desrespeita a regra de "no máximo um botão amarelo por
   tela": a regra do handoff é sobre BOTÃO (`variant="accent"`), e este é um
   link de texto. O próprio Header.jsx do handoff faz exatamente assim.

   Contraste medido no navegador, a 1440px: o contato amarelo sobre o azul
   escuro dá **7,11:1** e a promessa em `--blue-100` dá **8,21:1** — os dois
   folgados acima do AA.
   ========================================================================== */

.chase-aviso {
  background: var(--surface-brand-deep);
  color: var(--blue-100);
  font-size: var(--text-sm);
}

/* A FAIXA PASSOU A SER UMA LINHA SÓ, CENTRALIZADA.

   Era `space-between` com a promessa à esquerda e o WhatsApp à direita. Com o
   WhatsApp fora — ele vive no rodapé e no botão flutuante —, sobrar um único
   bloco num `space-between` o deixaria encostado à esquerda, que é a mesma
   armadilha já paga na faixa de confiança. `center` é o que a linha única
   pede. */
.chase-aviso__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-2) var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

/* O SEPARADOR É DESENHADO, NÃO ESCRITO.

   A barra vertical entre as promessas é um `::before` do segundo item em
   diante. Escrevê-la dentro do texto faria leitor de tela anunciar "barra
   vertical" a cada promessa, e prenderia o caractere dentro da string
   traduzível — onde ele é decoração, não conteúdo.

   `aria-hidden` não resolveria: não se põe atributo em pseudo-elemento. O que
   resolve é ele não existir no documento, que é exatamente o caso. */
.chase-aviso__item {
  display: inline-flex;
  align-items: center;
}

.chase-aviso__item + .chase-aviso__item::before {
  content: '';
  width: 1px;
  height: 12px;
  margin-right: var(--space-4);
  background: currentColor;
  opacity: 0.45;
}

/* NO CELULAR A FAIXA QUEBRA, E O SEPARADOR IA JUNTO COM A LINHA.

   A barra é um `::before` DENTRO do item, então quando o item passa para a
   segunda linha a barra vai com ele e sobra um `|` solto abrindo a linha.
   Defeito da 1.22.0, e quem viu foi o proprietário.

   Medido a 375 antes de corrigir: "Produtos 100% originais" e "7% Off no PIX"
   na primeira linha, "Até 12x no cartão" na segunda começando em y37 -- e com
   a barra na frente.

   **Não existe seletor de "primeiro da linha" em CSS**, então não dá para
   esconder a barra que quebrou. Nem `::after` no item anterior resolve: ali a
   barra sobra pendurada no FIM da primeira linha, que é o mesmo defeito
   espelhado. O que resolve é a barra não existir onde há quebra -- abaixo do
   ponto de quebra quem separa é o vão, e o vão cresce para compensar.

   O ponto de quebra não é chute: somadas, as três promessas pedem 455px com
   as barras (155 + 106 + 128 de texto, mais dois vãos de 16 e duas barras de
   1 + 16 de margem), e com os 48 de recuo do contêiner a linha única exige
   **503px de viewport**. Os 768 daqui deixam 265px de folga, entao promessa
   nova ou percentual maior ainda cabem antes de o limite apertar.

   O que estava aqui antes era código morto: a regra escondia
   `.chase-aviso__promessa` e o `.chase-aviso__contato` tinha estilo próprio,
   e **nenhuma das duas classes existe no markup** desde que o WhatsApp saiu
   da faixa na 1.22.0. O `justify-content: center` também era redundante --
   a regra base já centraliza. */
@media (max-width: 768px) {
  .chase-aviso__item + .chase-aviso__item::before {
    content: none;
  }

  /* Sem a barra, some junto o `1px + 16` de margem dela. O vão sobe de 16
     para 24 para o par da primeira linha não ler como uma frase só. */
  .chase-aviso__inner {
    column-gap: var(--space-6);
  }
}

/* ==========================================================================
   2. Card de produto conforme a especificação do handoff

   Do README: "Card de produto: branco, sem borda, `--shadow-md`; hover eleva
   para `--shadow-lg` e `-2px`."

   São TRÊS markups de card neste projeto e a regra precisa cobrir os dois que
   existem em grade — o da home (`.chase-product-card`) e o da loja
   (`li.product`). Cobrir só um é o erro que este projeto já cometeu mais de
   uma vez, registrado em "Existem dois markups de produto".
   ========================================================================== */

.chase-product-card,
.woocommerce ul.products li.product {
  background: var(--surface-card);
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  transition: box-shadow var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}

.chase-product-card:hover,
.woocommerce ul.products li.product:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}

/* Quem prefere menos movimento não recebe o deslocamento — só a sombra. */
@media (prefers-reduced-motion: reduce) {
  .chase-product-card,
  .woocommerce ul.products li.product {
    transition: box-shadow var(--duration-base) var(--ease-standard);
  }

  .chase-product-card:hover,
  .woocommerce ul.products li.product:hover {
    transform: none;
  }
}

/* O TEXTO DO CARD ALINHA A ESQUERDA, E OS DOIS MARKUPS DISCORDAVAM.

   O card da HOME sempre foi `start`: o corpo dele e uma pilha flex e nada
   centraliza. O da LOJA saia CENTRALIZADO, e nao por escolha nossa -- quem
   centraliza e `ul.products li.product` no `woocommerce.css` do Storefront,
   que e a folha 21 da pagina contra a 18 desta camada e ganha todo empate.

   Medido a 1440px antes de corrigir: titulo, preco e as duas linhas de
   pagamento em `center` no card da loja e em `start` no card da home. O mesmo
   produto lia diferente conforme a pagina onde aparecia.

   `body` na frente desfaz o empate sem `!important`: a regra do Storefront e
   (0,2,2) e esta e (0,2,3). Mesma conta do `body h1` da ponte e do
   `body.single-product` do produto.css.

   O rotulo do BOTAO nao acompanha, de proposito: `li.product .button` tem
   `text-align: center` proprio no nosso woocommerce.css, com especificidade
   muito maior, entao ele segue centrado na largura toda do card.

   Isto vale para toda grade que usa o loop -- loja, categoria, busca,
   relacionados e venda cruzada --, que e exatamente o alcance desejado. */
body ul.products li.product {
  text-align: left;
}

/* ALINHAR A ESQUERDA REVELOU QUE UM DOS BLOCOS NAO TINHA RECUO.

   Centralizado, o recuo lateral nao aparecia: os tres blocos de texto liam
   como uma coluna so. Medido depois de alinhar, o titulo e o preco comecam em
   x16 -- eles tem `padding: ... var(--space-4)` no nosso woocommerce.css -- e
   as linhas de pagamento comecavam em **x0**, encostadas na borda do cartao e
   16px a esquerda de tudo o mais, inclusive do botao.

   O recuo vai aqui e nao no `.chase-pagamento` geral porque o mesmo bloco
   serve o card da home e o resumo do produto, e nos dois o recuo e do pai. */
body ul.products li.product .chase-pagamento {
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}

/* ==========================================================================
   3. Grade de produtos: 4 colunas no desktop, 2 no celular

   Do README: "Grade de produtos: 4 colunas desktop / 2 mobile, gutter
   `--grid-gutter` (20px)."

   O tema estava em 3 colunas na loja, porque a lateral de filtros ocupa
   espaço. Com `auto-fit` e `minmax` a grade se resolve sozinha nos dois
   contextos — com lateral e sem lateral — em vez de precisar de um número
   fixo por página.

   O teto de 1fr é deliberado: sem ele, três produtos numa faixa de quatro
   colunas deixariam um buraco à direita, que é a armadilha já registrada em
   "Coluna de grade com 1fr ignora justify-content".
   ========================================================================== */

.woocommerce ul.products,
.chase-product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(214px, 1fr));
  gap: var(--grid-gutter);
}

@media (max-width: 768px) {
  .woocommerce ul.products,
  .chase-product-grid {
    /* Duas colunas fixas, e não auto-fit: a 375px o minmax de 214px colapsaria
       para uma coluna só, e o handoff pede duas no celular. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
  }
}

/* ==========================================================================
   4. O amarelo como acento de conversão

   Do README: "No máximo um botão amarelo (`variant="accent"`) por tela —
   sempre o de maior conversão" e "Texto sobre amarelo é `--neutral-900`,
   nunca branco".

   Na loja, o botão de maior conversão é o de adicionar ao carrinho da PÁGINA
   DE PRODUTO. O da grade continua azul de propósito: uma grade de oito cards
   com oito botões amarelos violaria a regra e mataria o efeito do acento.

   Contraste medido: `--neutral-900` (#12171c) sobre `--yellow-400` (#ffd100)
   dá 12,3:1. É o botão de melhor contraste do site.
   ========================================================================== */

.woocommerce div.product form.cart button.single_add_to_cart_button {
  background: var(--action-accent);
  color: var(--text-on-yellow);
  border: 0;
}

.woocommerce div.product form.cart button.single_add_to_cart_button:hover,
.woocommerce div.product form.cart button.single_add_to_cart_button:focus-visible {
  background: var(--action-accent-hover);
  color: var(--text-on-yellow);
}

.woocommerce div.product form.cart button.single_add_to_cart_button:active {
  background: var(--action-accent-active);
}

/* Produto esgotado não recebe o acento: o handoff manda trocar o rótulo para
   "Avise-me" e usar a variante secundária. Aqui o botão nem existe quando não
   há estoque, então a regra cobre o caso do botão desabilitado. */
.woocommerce div.product form.cart button.single_add_to_cart_button:disabled {
  background: var(--neutral-200);
  color: var(--text-muted);
}

/* ==========================================================================
   5. Rodapé no tom da marca

   Do `Footer.jsx`: fundo `--surface-brand-deep`, títulos de coluna em Outfit
   600 branco, links em `--blue-100` / `text-sm` sem sublinhado, e a barra de
   baixo separada por `1px solid rgba(255,255,255,0.14)` com texto em
   `--blue-200` / `text-xs`.

   O tema usava `--chase-text` (#22282B), quase preto. O azul escuro amarra o
   rodapé ao herói e à faixa de confiança, que usam o mesmo tom.

   O LOGO NÃO MUDA. O nosso rodapé usa o wordmark branco, que mede 14,9:1
   contra o `--chase-text` e segue confortável contra o `#0b4463`. O handoff
   usa o símbolo quadrado ali, mas trocar o wordmark pelo símbolo é decisão de
   marca e não de integração — e o handoff lista "logotipo em branco" como
   pendência do cliente.
   ========================================================================== */

/* O VÃO ANTES DO RODAPÉ É DELE, NÃO DA HOME.

   No handoff o `<footer>` carrega `marginTop: var(--section-gap)` e o vão
   fica FORA do fundo escuro; o respiro interno é do contêiner, em
   `var(--space-12)`. O tema fazia o contrário: `padding-top: var(--space-16)`
   dentro do rodapé, o que põe os mesmos 64px do lado escuro da borda.

   O efeito é o que o proprietário viu: com padding, o azul escuro começa
   colado na última linha de produtos — medido, `section.bottom` e
   `footer.top` davam o MESMO 2095,97, ou seja, zero de separação. No
   protótipo há 64px de fundo de página entre um e outro, e só depois 48px de
   escuro antes do logo.

   Trocar padding por margem aqui é o que reproduz os dois números, e é por
   isso que o `padding-top` do layout.css precisa ser zerado em vez de
   apenas somado — senão o vão viraria 64 de fora mais 64 de dentro. */
.chase-footer {
  background: var(--surface-brand-deep);
  margin-top: var(--section-gap);
  padding-top: 0;
}

/* A MARGEM DESCOBRIU O FUNDO DO PAI, E ELE ERA CINZA ESCURO.

   O `layout.css` pinta `.site-footer` com `--chase-text`, que a ponte agora
   manda para `--neutral-700` (#333b45). Enquanto o vao era `padding`, aquele
   cinza ficava ESCONDIDO atras do azul do `.chase-footer`. Ao virar margem, os
   64px passaram a mostrar o pai — uma faixa escura entre o conteudo e o
   rodape, em todas as telas.

   Eu medi aquele vao em pixels nas quatro telas e nunca medi a COR dele. Foi o
   proprietario que viu, e e o tipo de defeito que so olho humano pega.

   O `#colophon` deixa de pintar: quem pinta e o `.chase-footer`, e o vao passa
   a mostrar o fundo da pagina, como no handoff. */
#colophon.site-footer {
  background-color: transparent;
}

.chase-footer__inner {
  padding-top: var(--space-12);
}

/* DUAS CLASSES, E A SEGUNDA NAO E ENFEITE.

   O personalizador imprime `<style>` no `<head>` com
   `.site-footer h4 { color: #333 }` — (0,1,1), e inline no head vence
   folha enfileirada por ordem. O nosso `.chase-footer__heading` sozinho e
   (0,1,0) e perdia.

   Resultado medido: "Categorias", "Ajuda" e "Contato" saiam em rgb(51,51,51)
   sobre o azul #0b4463. Com o rodape antigo, que ja era escuro, isso passava
   por texto apagado; sobre o azul ficou evidente.

   Com o pai na frente a conta vai a (0,2,0) e passa na frente. */
.chase-footer .chase-footer__heading {
  font-family: var(--font-display);
  color: var(--neutral-0);
}

.chase-footer__links a {
  color: var(--blue-100);
  font-size: var(--text-sm);
  text-decoration: none;
}

.chase-footer__links a:hover,
.chase-footer__links a:focus-visible {
  color: var(--neutral-0);
  text-decoration: underline;
}

.chase-footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.chase-footer__copyright {
  color: var(--blue-200);
  font-size: var(--text-xs);
}

/* A grade do rodapé é de QUATRO colunas no handoff — `1.4fr 1fr 1fr 1fr`.

   O tema tinha três trilhas e quatro filhos: com a coluna Contato ligada, ela
   caía para uma segunda linha, medida em y2392 contra os y2151 das outras.
   Não era o Contato "no lugar errado" — era a grade sem trilha para ele. */
.chase-footer__grid {
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--space-8);
}

/* A descrição sob o logo: `--blue-100`, `text-sm`, `maxWidth: '32ch'`. */
.chase-footer__sobre {
  color: var(--blue-100);
  font-size: var(--text-sm);
  max-width: 32ch;
  margin-top: var(--space-4);
}

/* ==========================================================================
   4b. As linhas de pagamento, abaixo do preço

   Do `PriceBlock.jsx`, que as imprime nas TRÊS superfícies onde aparece preço
   de produto: o card da home, o card da loja e a página de produto. No
   protótipo é um componente só com `size` diferente; aqui é um bloco de CSS
   só, usado pelos dois markups de card e pelo resumo do produto.

   ── O TAMANHO DA LETRA NÃO ACOMPANHA O `size` ──

   No `PriceBlock.jsx` o `size` muda SÓ o número do preço — `sm: 20`,
   `md: 28`, `lg: 36`. As duas linhas de baixo são `var(--text-sm)` nos três
   tamanhos, sem exceção.

   Encolher elas no card seria o reflexo de quem desenha pelo olho, e
   contrariaria o componente. A regra deste redesenho é a oposta: o valor vem
   do componente. O `--sm` existe para o espaçamento em volta, que aí sim muda.

   O verde do Pix é `--success-500`, e é a única cor de destaque que aparece
   abaixo de um preço no site — é o que faz a linha ser lida como vantagem e
   não como nota de rodapé.
   ========================================================================== */

.chase-pagamento {
  display: flex;
  flex-direction: column;
  /* Os 2px de `marginTop` que o PriceBlock põe em cada uma das duas linhas. */
  gap: 2px;
}

.chase-pagamento__parcelas,
.chase-pagamento__pix {
  font-size: var(--text-sm);
  line-height: 1.4;
}

.chase-pagamento__parcelas {
  color: var(--text-muted);
}

.chase-pagamento__pix {
  color: var(--success-500);
  font-weight: var(--weight-semibold);
}

/* No card, o bloco se separa do preço com o mesmo 2px e não empurra o botão:
   quem dá o respiro embaixo é o `gap` da própria pilha do card. */
.chase-pagamento--sm {
  margin-top: 2px;
}

/* NO CELULAR AS DUAS LINHAS ENCOLHEM, E AQUI O PROTOTIPO NAO TEM O QUE DIZER.

   O handoff e desktop puro: a listagem dele e `repeat(3, minmax(0,1fr))` e a
   home `repeat(4, 1fr)`, fixos, sem UMA media query no arquivo inteiro. Ele
   nunca viu um card de 158px, que e o que sobra a 375 com duas colunas.

   Medido a 375: as duas linhas quebravam em duas cada uma — 39px no lugar de
   20 —, empilhando QUATRO linhas de texto de pagamento sob o preco num card
   que tem 158 de largura.

   Entao aqui o valor nao vem do componente, porque o componente nao opina. A
   12px as duas cabem numa linha so, e continuam acima do minimo legivel para
   texto de apoio.

   A pagina de produto nao entra nisto: la a coluna e inteira e o `--lg` segue
   nos 14px do `PriceBlock`. */
@media (max-width: 768px) {
  .chase-pagamento--sm .chase-pagamento__parcelas,
  .chase-pagamento--sm .chase-pagamento__pix {
    font-size: var(--text-xs);
  }
}

/* O `wc_price()` embrulha o valor em `.woocommerce-Price-amount`, e o
   Storefront dá peso próprio a ele. Dentro destas linhas quem manda é a linha,
   senão o valor do Pix sairia com um peso e o "de desconto" com outro. */
.chase-pagamento__parcelas .woocommerce-Price-amount,
.chase-pagamento__pix .woocommerce-Price-amount {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}

/* ── A fileira de redes, sob a marca ──

   Dois alvos redondos de 40px. O numero nao e estetico: 40 e o minimo
   confortavel para o dedo num rodape, e como sao dois links vizinhos com 12 de
   intervalo a area de erro de cada um nao invade a do outro.

   O fundo e branco a 10%, e nao um token de cor: o rodape e o unico lugar do
   site com fundo azul escuro, e nenhum dos tons da rampa neutra da o realce
   discreto que o handoff usa em superficie escura. Escrito em `rgba` pela
   mesma razao das outras translucidas do projeto — `var()` de hex nao entra
   dentro de `rgba()`.

   O `flex-shrink: 0` no SVG e a armadilha ja paga duas vezes neste tema: item
   flex encolhe, e um SVG sem largura declarada dentro de um pai apertado vai a
   ZERO sem erro nenhum. O botao vira uma bolinha vazia. */
.chase-footer__redes {
  display: flex;
  gap: var(--space-3);
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
}

.chase-footer__redes li {
  margin: 0;
  padding: 0;
}

.chase-footer__redes li::before {
  content: none;
}

/* O `#colophon` NAO E ENFEITE, e a conta e diferente da do heading.

   O personalizador imprime no `<head>`
   `.site-footer a:not(.button):not(.components-button) { color: #333 }`. Cada
   `:not()` pesa como CLASSE, entao aquilo e (0,3,1) — nao (0,1,1) como a
   leitura rapida sugere.

   Medido antes de corrigir: os dois glifos saiam em rgb(51,51,51) sobre o
   circulo branco a 10% sobre o azul #0b4463. Como o SVG herda `currentColor`,
   o icone inteiro ficava cinza escuro em cima de escuro — praticamente
   invisivel, e sem nenhum aviso de que a regra nao tinha valido.

   O `.chase-footer__links a` vizinho escapa porque o `layout.css` ja o escreve
   como `.site-footer .chase-footer .chase-footer__links a`, que empata em
   (0,3,1) e vence por vir depois.

   Aqui a saida e o id do rodape do Storefront: (1,1,1) vence qualquer
   quantidade de classe e nao depende de ordem de carregamento, que e
   justamente a variavel que ja mordeu este projeto. Mesmo id que o bloco do
   fundo transparente usa mais acima. */
#colophon .chase-footer__redes a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.1);
  color: var(--neutral-0);
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

#colophon .chase-footer__redes a svg {
  flex-shrink: 0;
}

#colophon .chase-footer__redes a:hover,
#colophon .chase-footer__redes a:focus-visible {
  background: var(--action-accent);
  color: var(--text-on-yellow);
  text-decoration: none;
}

@media (max-width: 1024px) {
  .chase-footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 568px) {
  .chase-footer__grid {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   5b. O botao redondo de WhatsApp, fixo no canto

   Carrega em toda tela, como o resto deste arquivo. O markup vem de
   `chase_whatsapp_flutuante()`, no `wp_footer`.

   ── O Z-INDEX E BAIXO DE PROPOSITO ──

   `--z-sticky` sao 200, e a tentacao e cravar 9999 como todo botao flutuante
   de internet faz. Aqui isso seria um defeito conhecido: a escala deste
   projeto convive com terceiros e esta documentada no `variables.css` — o
   `.site-header` do Storefront e 999, o veu do carrinho lateral e 1000 e o
   painel dele 1100.

   Com 9999 o botao ficaria POR CIMA do carrinho aberto e do veu escuro,
   flutuando sobre um painel modal. E exatamente o defeito que a escala foi
   reescrita para corrigir em 2026, quando o carrinho lateral aparecia por
   baixo do header.

   Com 200 ele fica acima do conteudo — que nao tem z-index nenhum — e por
   baixo de tudo que e sobreposicao. O header nunca disputa com ele: um mora no
   topo e o outro no rodape da janela.

   ── A COLISAO COM O AVISO DE ADICAO ──

   O `.chase-cart-notification` tambem e `position: fixed` no canto inferior
   direito, e tem `--z-toast` (9999). Ele quase nunca aparece: o `chase.js` faz
   `if (cartDrawerAtivo) return`, porque a gaveta JA E a confirmacao da adicao.

   "Quase nunca" nao e "nunca" — sem a casca do painel, com o WooCommerce
   inativo, ele volta. Entao o botao sobe 72px quando o aviso esta na tela, o
   que e a altura dele mais o intervalo. E `:has()` no `body` porque o aviso e
   criado pelo JS e anexado DEPOIS do botao: combinador de irmao so olha para a
   frente e nao alcancaria.
   ========================================================================== */

.chase-zap {
  position: fixed;
  right: var(--space-6);
  bottom: var(--space-6);
  z-index: var(--z-sticky);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: var(--radius-full);
  /* O verde e o da marca do WhatsApp, e nao um token nosso. Botao de contato
     que nao usa a cor da rede vira "mais um botao redondo" e perde o
     reconhecimento instantaneo, que e a unica razao de ele existir.

     CONTRASTE MEDIDO: branco sobre #25d366 da 1,98:1, abaixo dos 3:1 que a
     WCAG 1.4.11 pede para objeto grafico. Fica registrado em vez de escondido.

     A troca, se um dia for preciso: #128c7e — o verde escuro do MESMO conjunto
     de marca do WhatsApp — leva o glifo a 4,19:1 sem sair da identidade. E uma
     linha. Nao foi adotado agora porque o #25d366 e o botao que as pessoas
     reconhecem sem ler, e o que segura a percepcao aqui e o contraste do botao
     contra a PAGINA, mais a sombra --shadow-lg, e nao o glifo contra o verde. */
  background: #25d366;
  color: #ffffff;
  box-shadow: var(--shadow-lg);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-standard),
    background var(--duration-fast) var(--ease-standard);
}

.chase-zap svg {
  flex-shrink: 0;
}

.chase-zap:hover,
.chase-zap:focus-visible {
  background: #1ebe5a;
  color: #ffffff;
  text-decoration: none;
  transform: scale(1.06);
}

.chase-zap:focus-visible {
  outline: 3px solid var(--neutral-0);
  outline-offset: 2px;
}

/* Ver a nota do cabecalho: o aviso de adicao ocupa este mesmo canto. */
body:has(.chase-cart-notification.is-active) .chase-zap {
  transform: translateY(-72px);
}

/* O AVISO DE COOKIES OCUPA O MESMO CANTO, E ELE GANHA.

   Pego com `document.elementFromPoint` no centro do botao, que e a unica
   medicao que enxerga ordem de pintura — geometria, cor e foco estavam todos
   corretos. No centro do botao quem respondia era
   `BUTTON.chase-cookies__btn--aceitar`.

   O `#chase-cookies` do chase-core e `position: fixed`, `bottom: 0`, largura
   inteira e z-index 1000. Medido a 375px: 194px de altura, cobrindo de y618 a
   y812 — o botao mora em y748 e sumia inteiro por baixo dele.

   Subir o botao seria o reflexo, e esta errado por dois motivos: a altura do
   aviso depende da quebra do TEXTO e muda com a largura e com qualquer edicao
   da frase, entao qualquer deslocamento fixo aqui apodrece em silencio; e num
   celular de 812px um aviso de 194 nao deixa canto bom nenhum.

   Entao o botao espera. Ele volta no instante em que a pessoa decide, porque o
   `consentimento.js` so tira a classe `is-visible` e mantem o elemento no DOM
   — nao ha estado em que os dois fiquem ocultos.

   Aceitar o consentimento e a primeira decisao da visita, e concorrer com ela
   por atencao seria pior que esperar. */
body:has(#chase-cookies.is-visible) .chase-zap {
  display: none;
}

/* Quem pediu menos animacao nao quer um alvo que cresce sob o dedo. O
   deslocamento do aviso continua, porque ali ele e correcao de posicao e nao
   enfeite. */
@media (prefers-reduced-motion: reduce) {
  .chase-zap {
    transition: background var(--duration-fast) var(--ease-standard);
  }

  .chase-zap:hover,
  .chase-zap:focus-visible {
    transform: none;
  }
}

/* No celular o botao encolhe e chega mais perto do canto: a tela e menor e o
   polegar alcanca o canto inferior direito sem reposicionar a mao. Os 48px
   continuam acima do minimo de area de toque. */
@media (max-width: 768px) {
  .chase-zap {
    right: var(--space-4);
    bottom: var(--space-4);
    width: 48px;
    height: 48px;
  }

  .chase-zap svg {
    width: 26px;
    height: 26px;
  }

  /* No celular o aviso ocupa a largura toda, entao o botao sobe mais. */
  body:has(.chase-cart-notification.is-active) .chase-zap {
    transform: translateY(-80px);
  }
}

/* ==========================================================================
   6. Header do handoff

   Do `Header.jsx`. Os tokens de cor já foram trocados na ponte; aqui entra o
   que é estrutura.

     header      `position: sticky; top: 0; z-index: 30`
     faixa       `rgba(255,255,255,0.94)` + `backdrop-filter: blur(8px)`
                 + `border-bottom: 1px solid var(--border-subtle)`
     linha       `padding: 14px var(--container-pad)`, flex, gap `--space-6`
     logo        wordmark AZUL, 32px de altura
     busca       `flex: 1`, `max-width: 520px`
     ações       gap `--space-2`, empurradas para a direita
     nav         `padding: 0 var(--container-pad) 12px`, gap `--space-6`,
                 itens em Outfit 600 `text-base`, ativo com
                 `box-shadow: inset 0 -3px 0 var(--chase-yellow)`

   O `z-index: 30` do handoff NÃO é usado. O `.site-header` do Storefront é
   `z-index: 999` e cria contexto de empilhamento — baixar o nosso para 30
   colocaria o carrinho lateral por baixo do header de novo, que é o defeito
   corrigido na 1.3.4. A escala do projeto fica como está.
   ========================================================================== */

.chase-header {
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border-subtle);
}

.chase-header__inner {
  padding-top: 14px;
  padding-bottom: 14px;
  gap: var(--space-6);
}

/* O RECUO LATERAL DO HEADER TEM QUE SER O MESMO DO CORPO, EM TODA LARGURA.

   O `layout.css` reduz o recuo do header para `--space-4` (16px) abaixo de
   480, e o corpo continua nos 24 do `--container-pad`. Medido a 375: a logo
   comecava em x16 e o heroi em x24 — a mesma desavenca do desktop, so que
   de 8px em vez de 100.

   Este bloco vem LOGO DEPOIS da regra base, e nao junto do resto do
   responsivo, porque media query nao acrescenta especificidade: quem vence e
   a ultima declaracao de mesmo peso. Agrupar la embaixo ja quebrou a Minha
   conta uma vez neste projeto.

   MAS OS 8px A MAIS DE CADA LADO NAO CABIAM, e eu escrevi aqui que cabiam
   antes de medir. A conta real a 375:

       logo 114 + gap do inner 24 + acoes 206 = 336
       largura util com recuo de 24           = 327

   Faltavam 9px, e quem sobrava para fora era o hamburguer — 17px alem do
   recuo, encostado na borda. Com o recuo antigo de 16 ja estourava por 1px;
   ninguem tinha notado porque 1px nao se ve.

   A folga vem do intervalo entre os botoes de acao, que era 16 e vira 8 so no
   celular: as acoes caem de 206 para 182 e o total para 320, com 7px de
   sobra. Os botoes em si nao encolhem — seguem com 38 e 44px, acima do minimo
   de area de toque. */
@media (max-width: 480px) {
  .chase-header__inner {
    padding-left: var(--container-pad);
    padding-right: var(--container-pad);
  }

  .chase-header__actions {
    gap: var(--space-2);
  }
}

/* A navegação passa a viver na MESMA faixa branca do logo, e não numa faixa
   azul própria. O `border-top` transparente evita o risco duplo, já que o
   `.chase-header` acima também tem borda. */
.chase-nav {
  border-top: 0;
  padding-bottom: 12px;
}

.chase-nav__link {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  padding-bottom: 4px;
}

/* O item ativo do handoff é um traço amarelo de 3px POR DENTRO, e não uma
   borda: `inset 0 -3px 0`. Como sombra interna ele não desloca o texto nem
   soma altura à faixa, que é por isso que o handoff faz assim. */
.chase-nav__link[aria-current],
.chase-nav__link.is-active,
.chase-nav__item.is-active > .chase-nav__link {
  color: var(--text-strong);
  box-shadow: inset 0 -3px 0 var(--chase-header-accent);
  background: transparent;
}

/* O campo de busca do handoff é branco com borda, e não o campo dentro de
   faixa azul que o tema tinha. O `max-width` de 520px é literal do
   `Header.jsx`. */
.chase-header__search {
  flex: 1;
  max-width: 520px;
}

input.chase-header__search-input {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  color: var(--text-body);
}

input.chase-header__search-input::placeholder {
  color: var(--text-subtle);
}

input.chase-header__search-input:focus {
  border-color: var(--border-brand);
  box-shadow: var(--ring);
  outline: none;
}

/* A faixa de categorias do celular acompanha o branco. Sem isto ela ficaria
   azul sozinha, entre um header branco e o conteúdo — as três faixas andam
   juntas, como o CLAUDE.md registra. */
.chase-catbar {
  border-bottom: 1px solid var(--border-subtle);
}

.chase-catbar__link {
  color: var(--chase-header-text);
}

/* ── Ajustes do header medidos contra o protótipo ──

   Três diferenças sobraram na primeira comparação, e estas são as correções.

   LOGO a 32px, e não 48px. O CSS do tema forçava a altura e vencia os
   atributos `width`/`height` do `<img>`. O handoff usa `height: 32`.

   NAV com `gap` de 24px e SEM padding lateral no link. O tema separava os
   itens por `padding: 12px 16px 4px`, e o padding tem uma consequência
   visível: o traço amarelo do item ativo é uma sombra interna do próprio
   link, então com 16px de cada lado ele ficaria mais largo que o texto. No
   handoff o traço abraça a palavra.

   O padding vertical migra para o `<li>`, e não desaparece: sem ele o alvo de
   toque do link cairia para a altura do texto. O handoff usa só
   `paddingBottom: 4` e, nesse ponto, contraria a própria regra dele de alvo
   mínimo de 44px — preferi manter o alvo e reproduzir o traço.
   ========================================================================== */

/* O LOGO CRESCEU DE 32 PARA 48px em 25/09/2026, a pedido do proprietário.

   48 é o teto seguro, e o número tem origem: o `Wordmark LIGA.png` tem 428×120
   na fonte, então a 48px sobram 2,5x de densidade — nítido em retina. O
   próprio `CLAUDE.md` registra que acima de ~60px o PNG começa a amolecer, e
   que passar disso exige pedir o SVG ao designer.

   No celular ele FICA em 32. A fileira de ações do header já não cabia a 375px
   — a conta `logo 114 + gap 24 + ações 206` estourava os 327 disponíveis, e
   foi preciso apertar o intervalo dos botões para 8px. Crescer o logo ali
   gastaria de novo a folga que aquela correção abriu. */
.chase-header__logo img {
  height: 48px;
  width: auto;
}

@media (max-width: 768px) {
  .chase-header__logo img {
    height: 32px;
  }
}

.chase-nav__list {
  gap: var(--space-6);
}

.chase-nav__item {
  padding: 12px 0 0;
}

.chase-nav__link {
  padding: 0 0 4px;
}

/* ==========================================================================
   7. Campo de busca

   Do `Input.jsx` do handoff, com `iconLeft`:

     campo    `padding: 12px 14px` · `min-height: 44` · `radius-md`
              borda `--border-default`, foco em `--border-brand` + `--ring`
              fonte `--font-body` / `--text-base`, cor `--text-strong`
     ícone    absoluto em `left: 14`, cor `--text-muted`
     campo    com ícone, o `padding-left` vira 42

   UMA DIFERENÇA DELIBERADA. No handoff o ícone é decorativo, com
   `pointer-events: none`. Aqui ele é o BOTÃO de enviar, que já existia no
   markup — só muda de lugar e de aparência. Mantê-lo clicável é o que faz a
   busca funcionar sem JavaScript; a prévia é enfeite em cima disso, e o
   formulário precisa poder ser enviado de qualquer forma.

   O `padding: 0` e o `flex-shrink: 0` no SVG não são opcionais: o Storefront
   aplica `padding: 9.9px 22.65px` em TODO `button`, e um SVG dentro de um
   contêiner flex encolhe para largura zero. É a armadilha do botão-ícone já
   registrada no projeto, e ela pegou o hambúrguer e o enviar da busca antes.
   ========================================================================== */

.chase-header__search-form {
  position: relative;
  display: flex;
  align-items: center;
}

input.chase-header__search-input {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--text-strong);
  border-radius: var(--radius-md);
  padding: 12px 14px 12px 42px;
  min-height: 44px;
  /* line-height normal, como o navegador faz num <input> por padrao.
     Herdando o 1,5 do corpo o campo dava 52px contra os 44 do handoff --
     o mesmo defeito que apareceu no botao do heroi. */
  line-height: normal;
}

/* O `right` HERDADO ESTICAVA O BOTAO DE PONTA A PONTA.

   O `layout.css` desenha a lupa do tema anterior do lado DIREITO:
   `position: absolute; right: var(--space-1); width: 36px`.

   Aqui a lupa muda de lado — o `Header.jsx` do handoff passa `iconLeft`, e o
   `Input.jsx` posiciona o icone em `left: 14` com o campo ganhando
   `paddingLeft: 42`. Este bloco escrevia `left: 14px` e `width: auto`, mas
   NUNCA ZERAVA O `right`.

   Com `left` e `right` fixados ao mesmo tempo e largura automatica, um
   elemento absoluto estica de uma borda a outra. Medido em producao: o botao
   ficou com **502px num campo de 520**, e como ele e `display: flex` com
   `justify-content: center`, a lupa foi parar no MEIO do campo de busca.

   Quem viu foi o proprietario. A medicao anterior tinha conferido a lupa
   "dentro do campo" e ela estava dentro — so que no centro.

   `right: auto` e a linha que faltava. O `top: 50%` e o `translateY(-50%)` do
   `layout.css` continuam valendo e centralizam na vertical. */
.chase-header__search-submit {
  position: absolute;
  left: 14px;
  right: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: auto;
  min-width: 0;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--chase-header-search-icon);
  box-shadow: none;
}

.chase-header__search-submit svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: block;
}

.chase-header__search-submit:hover,
.chase-header__search-submit:focus-visible {
  background: transparent;
  color: var(--action-primary-hover);
}

/* ==========================================================================
   8. Faixa de confianca e botoes: os dois blocos que a home emprestou

   Os dois nasceram no `home.css` e mudaram de casa quando a pagina de produto
   passou a usar os mesmos: o `ProductScreen.jsx` fecha com a faixa e usa o
   botao secundario no "Tirar duvida no WhatsApp".

   Ficaram no `home.css` por engano de escopo, e o defeito era mudo: sem o CSS,
   o SVG da faixa nasce com 1192px de lado — medido — e o botao secundario
   perde os 52px de altura. Nenhum erro, so a pagina errada.

   A numeracao segue a deste arquivo; os titulos internos sao os originais.
   ========================================================================== */

/* ==========================================================================
   4. Faixa de confiança

   Do `TrustStrip.jsx` com `tone="brand"`: grade `auto-fit` de
   `minmax(220px, 1fr)`, `gap: var(--space-5)`, fundo `--surface-brand-deep`,
   `radius-lg`, `padding: var(--space-6)`. Item em flex com `gap: var(--space-3)`
   alinhado ao topo, ícone de 32px em amarelo, título em Outfit 600 branco e
   apoio em `text-sm` / `--blue-100`.
   ========================================================================== */

.chase-confianca {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  background: var(--surface-brand-deep);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

/* OS TRES ITENS PASSAM A SE DISTRIBUIR, EM VEZ DE ENCOSTAR A ESQUERDA.

   O `TrustStrip.jsx` usa `repeat(auto-fit, minmax(220px, 1fr))` e deixa cada
   item alinhado a esquerda da sua trilha. Isso funcionava com a coluna de
   1240 do handoff: as trilhas davam 368px para um conteudo de 202 a 249, e os
   ~100px de sobra de cada uma passavam por respiro.

   Com a coluna em 1440 as trilhas foram para 435 e a sobra dobrou. O
   proprietario viu na hora: "antes os 3 estavam mais centralizados, agora
   estao como se o alinhamento fosse left". Nao era impressao — era a mesma
   regra num contentor 200px mais largo.

   A saida NAO e centralizar cada item na sua trilha (`justify-items: center`).
   Medido: como os tres tem larguras diferentes — 202, 249 e 240 —, cada um
   centraliza sozinho e os vaos saem DESIGUAIS, 229 contra 210. Troca um
   desalinhamento por outro.

   O que funciona e parar de fatiar a faixa em tres partes iguais: as colunas
   passam a ter o tamanho do conteudo e o espaco sobrando e distribuido entre
   elas. Medido a 1920: vaos de 225 e 225, margens de 102 e 103.

   `grid-auto-flow: column` em vez de `repeat(3, ...)` porque o numero de itens
   e do PHP, nao do CSS — se um quarto entrar, ele se acomoda sozinho. Testado
   tambem com um texto de apoio muito mais longo: os vaos caem para 141 e 141,
   simetricos, sem transbordar.

   So acima de 900px. Abaixo disso a regra base continua valendo e os itens
   empilham, que e o comportamento certo no celular — `auto-flow: column` ali
   forcaria tudo numa linha so. */
@media (min-width: 900px) {
  .chase-confianca {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    justify-content: space-around;
  }
}

.chase-confianca__item {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
}

.chase-confianca__icone {
  color: var(--chase-yellow);
  flex-shrink: 0;
}

/* O `flex-shrink: 0` acima e a largura fixa aqui existem pelo mesmo motivo já
   registrado no projeto: o Storefront aplica padding em todo `button`, e um SVG
   dentro de um contêiner flex encolhe para largura ZERO. O ícone virava uma
   caixa vazia. */
.chase-confianca__icone svg {
  width: 32px;
  height: 32px;
  display: block;
  flex-shrink: 0;
}

.chase-confianca__corpo {
  display: flex;
  flex-direction: column;
}

.chase-confianca__titulo {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--neutral-0);
}

.chase-confianca__apoio {
  font-size: var(--text-sm);
  color: var(--blue-100);
}

/* ==========================================================================
   5. Botões do design system

   Do `Button.jsx`. Só as duas variantes que a home usa, no tamanho `lg`:

     SIZES.lg      padding 14px 24px · text-md · minHeight 52 · radius-md
     accent        fundo --action-accent · texto --text-on-yellow · shadow-sm
     secondary     fundo --surface-card · texto --blue-700 · borda 1px

   Estes são âncoras (`<a>`) e não `<button>`, porque navegam. O
   `white-space: nowrap` é do protótipo — e é a mesma armadilha do
   `.chase-btn` já registrada, então o `flex-wrap` no contêiner das ações é o
   que evita o transbordo em tela estreita.
   ========================================================================== */

.chase-btn-ds {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  /* O `line-height` é OBRIGATÓRIO aqui, e a razão é medida.
     O protótipo usa `<button>`, que por padrão do navegador NÃO herda o
     `line-height` do corpo — ele fica em `normal`, cerca de 1,2. Estes botões
     são âncoras, porque navegam, e âncora herda: pegava o 1,5 do corpo, que a
     18px dá 27px de linha.

     A conta do defeito: 14 + 14 de padding + 27 de linha + 2 de borda = 57px,
     contra os 52px do protótipo. Com 1,2 a linha cai para 21,6px, a soma dá
     51,6 e o `min-height` de 52 passa a governar — exatamente o alvo. */
  line-height: 1.2;
  transition: background var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.chase-btn-ds--lg {
  padding: 14px 24px;
  font-size: var(--text-md);
  min-height: 52px;
  border-radius: var(--radius-md);
}

.chase-btn-ds--accent {
  background: var(--action-accent);
  color: var(--text-on-yellow);
  box-shadow: var(--shadow-sm);
}

.chase-btn-ds--accent:hover,
.chase-btn-ds--accent:focus-visible {
  background: var(--action-accent-hover);
  color: var(--text-on-yellow);
}

.chase-btn-ds--accent:active {
  background: var(--action-accent-active);
  transform: scale(0.98);
}

.chase-btn-ds--secondary {
  background: var(--surface-card);
  color: var(--blue-700);
  border-color: var(--border-default);
}

.chase-btn-ds--secondary:hover,
.chase-btn-ds--secondary:focus-visible {
  background: var(--blue-50);
  border-color: var(--blue-200);
  color: var(--blue-700);
}

.chase-btn-ds--secondary:active {
  background: var(--blue-100);
  transform: scale(0.98);
}

@media (prefers-reduced-motion: reduce) {
  .chase-btn-ds:active {
    transform: none;
  }
}
