/* ============================================================================
   sections.css — blocos de página (header, drawer, hero, segmentos, faixas,
   cta-band, footer). Ritmo de seção azul↔creme (DESIGN §4). Consome tokens.
   Estado mobile-first aqui; overrides de breakpoint em responsive.css.
   ============================================================================ */

/* ── Faixa de seção (ritmo) ───────────────────────────────────────────────── */
/* O que se lê na tela é o VÃO, que é a soma do padding de baixo de uma seção com
   o de cima da seguinte. Largo com compacto agora fecha em 144px no desktop,
   contra os 176px medidos antes; compacto com compacto, 112px contra 128px.
   Os vãos que NÃO nascem desses dois tokens estão tratados em cada componente:
   ver o comentário do `.site-footer` e o do `.segment-hero` neste arquivo.
   .section--tight saiu de --space-2xl (64px fixo, sem relação com o degrau largo)
   para um token de seção de verdade, que acompanha o largo na mesma curva. */
.section { padding-block: var(--space-section); }
.section--tight { padding-block: var(--space-section-tight); }
.section--brand { background: var(--color-brand); color: var(--color-on-brand); }
.section--brand a:not(.btn), .section--deep a:not(.btn) { color: var(--color-on-brand); }
.section--brand .section-header__title, .section--deep .section-header__title { color: var(--color-on-brand); }
.section--brand .eyebrow { color: var(--color-accent); } /* verde sobre azul: ~5:1 AA */
.section--deep .eyebrow { color: var(--color-on-brand); } /* verde sobre accent-deep reprova AA → creme */
.section--brand .section-header__lead, .section--deep .section-header__lead { color: rgb(var(--color-canvas-rgb) / 0.85); }

/* Foco visível sobre faixas/superfícies escuras: o anel herda on-brand (claro).
   DESIGN §2 — "focus em faixa escura, o componente usa on-brand". Sobre canvas/
   surface o anel continua azul (--color-focus default). */
.section--brand, .section--deep, .cta-band, .segment-card, .hero { --color-focus: var(--color-on-brand); }

/* ══════════════════════════════ HEADER ═══════════════════════════════════ */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  background: rgb(var(--color-canvas-rgb) / 0.92);
  backdrop-filter: saturate(1.2) blur(8px);
  border-bottom: 1px solid var(--color-hairline);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-lg); padding-block: var(--space-md);
}
.site-header__brand { display: inline-flex; align-items: center; text-decoration: none; color: var(--color-brand); }
.site-header__logo { display: block; width: auto; height: 34px; }
@media (max-width: 767px) { .site-header__logo { height: 40px; } } /* monograma reduzido (mais compacto) */
.site-nav { display: none; } /* mobile: escondida; drawer assume. ≥1024 em responsive.css */
.site-nav__list { display: flex; flex-wrap: wrap; gap: var(--space-lg); list-style: none; padding: 0; margin: 0; }
/* `padding-block: 5px` leva o alvo de 15px para 25px (WCAG 2.5.8). Os 7 links
   do menu mediam 15px de altura no desktop, o mesmo problema que a auditoria
   apontou no rodapé e não viu aqui (2026-07-31). A margem negativa devolve o
   espaço, então a barra não muda de altura: conferido, 0px de diferença.
   Estes NÃO caem na exceção de "alvo inline" da norma: não são links no meio de
   uma frase, são uma barra de navegação. */
.site-nav__link {
  text-decoration: none; color: var(--color-ink);
  font-weight: var(--font-weight-medium); font-size: var(--font-size-sm);
  display: inline-block; padding-block: 5px; margin-block: -5px;
}
.site-nav__link:hover { color: var(--color-brand); }
.site-nav__link[aria-current="page"] { color: var(--color-brand); font-weight: var(--font-weight-semibold); }
.site-header__actions { display: flex; align-items: center; gap: var(--space-sm); }
.site-header__toggle {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
  background: none; border: 0; padding: var(--space-xs); cursor: pointer; color: var(--color-ink);
}
.site-header .btn--whatsapp span { display: none; } /* rótulo só a partir de 768 (responsive.css) */

/* ══════════════════════════════ DRAWER (mobile) ══════════════════════════ */
.mobile-drawer { position: fixed; inset: 0; z-index: var(--z-drawer); }
.mobile-drawer__backdrop {
  position: absolute; inset: 0;
  background: rgb(var(--color-ink-rgb) / 0.5);
  z-index: var(--z-overlay);
  opacity: 0; transition: opacity var(--motion-duration-base) var(--motion-ease-standard);
}
.mobile-drawer:not([hidden]) .mobile-drawer__backdrop { opacity: 1; }
.mobile-drawer__panel {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: var(--z-drawer);
  width: min(88vw, 360px);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
  padding: var(--space-lg);
  display: flex; flex-direction: column; gap: var(--space-lg);
  transform: translateX(100%);
  transition: transform var(--motion-duration-base) var(--motion-ease-out);
  overflow-y: auto;
}
.mobile-drawer:not([hidden]) .mobile-drawer__panel { transform: translateX(0); }
.mobile-drawer__head { display: flex; align-items: center; justify-content: space-between; }
.mobile-drawer__title { font-family: var(--font-display); text-transform: uppercase; font-size: var(--font-size-h3); color: var(--color-brand); }
.mobile-drawer__close { display: inline-flex; min-width: 44px; min-height: 44px; align-items: center; justify-content: center; background: none; border: 0; cursor: pointer; color: var(--color-ink); }
.mobile-drawer__list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-xs); }
.mobile-drawer__link {
  display: flex; align-items: center; gap: var(--space-md);
  padding: var(--space-md) var(--space-sm); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--color-ink); font-weight: var(--font-weight-medium);
}
.mobile-drawer__link:hover { background: var(--color-canvas); color: var(--color-brand); }
.mobile-drawer__link[aria-current="page"] { color: var(--color-brand); background: var(--color-canvas); }
.mobile-drawer__link .icon { color: var(--color-accent-deep); }
.mobile-drawer__cta { margin-top: auto; }

/* ══════════════════════════════ HERO ═════════════════════════════════════ */
.hero { position: relative; }
/* Slides empilhados na mesma célula (crossfade). Sem JS, o 1º slide já vem com
   .is-active no HTML → visível e estático (progressive enhancement). */
.hero__viewport { display: grid; }
.hero__slide {
  grid-area: 1 / 1;
  /* `position: relative` é o que faz o `overflow: hidden` daqui valer para a
     foto (2026-07-27). A `.hero__media` é `position: absolute`, e recorte só
     alcança descendente absoluto se o elemento que recorta TAMBÉM for o bloco
     que o contém. Sem isso a foto resolvia contra o `.hero` e, com o zoom lento
     do Ken Burns, vazava para fora do hero: medido, 9px no meio da animação e
     cerca de 19px no fim, aparecendo por baixo da barra de progresso e por cima
     da faixa azul seguinte. */
  position: relative;
  display: grid; align-items: end;
  min-height: clamp(440px, 72vh, 640px);
  /* Fallback sem foto: gradiente de marca (fotos entram na pendência de assets). */
  background: linear-gradient(135deg, var(--color-brand) 0%, var(--color-accent-deep) 100%);
  color: var(--color-on-brand);
  overflow: hidden;
  opacity: 0; visibility: hidden;
  transition: opacity var(--motion-duration-slow) var(--motion-ease-out),
              visibility var(--motion-duration-slow) var(--motion-ease-out);
}
.hero__slide.is-active { opacity: 1; visibility: visible; z-index: 1; }
/* O recorte vem por variável, não por atributo: `object-position` mora no `<img>`
   e vale para qualquer fonte que o `<picture>` escolher, então é aqui, na media
   query, que a escolha por largura pertence. `--foco` é o enquadramento da foto
   larga (a de Agricultura usa `50% 65%`, aprovado pelo gestor) e `--foco-mob` o
   da versão retrato, que foi enquadrada de propósito e por isso usa `center`.
   Quem não declara cai em `center`, que era o comportamento antigo. */
/* ── MOVIMENTO DO HERO (2026-07-27) ────────────────────────────────────────
   Quatro coisas se movem na Home, e nenhuma é enfeite solto: todas marcam
   alguma coisa que está acontecendo.

   1. A FOTO respira enquanto o slide está no ar (Ken Burns). Escala de 1 para
      1.06 nos 6s do autoplay, que é o mesmo tempo do `DELAY` em hero.js. Só no
      slide ativo: os outros ficam parados, senão o navegador anima três fotos
      grandes ao mesmo tempo à toa.
   2. O TEXTO sobe ao entrar. É o que dá a sensação de "trocou", em vez do
      crossfade puro que parece uma foto piscando.
   3. A BARRA DE PROGRESSO mostra quanto falta para o próximo slide, e para
      junto quando o visitante pausa. Movimento que informa.
   4. Nada disso roda em `prefers-reduced-motion`, tratado no fim do bloco. */
@media (prefers-reduced-motion: no-preference) {
  .hero__slide.is-active .hero__media { animation: hero-respira 9s var(--motion-ease-standard) both; }
  .hero__slide.is-active .hero__content > * { animation: hero-sobe 0.65s var(--motion-ease-out) both; }
  /* escada curta: eyebrow, título e botão entram em sequência, não em bloco */
  .hero__slide.is-active .hero__content > *:nth-child(2) { animation-delay: 90ms; }
  .hero__slide.is-active .hero__content > *:nth-child(3) { animation-delay: 180ms; }
  .hero__slide.is-active .hero__content > *:nth-child(4) { animation-delay: 260ms; }
}
@keyframes hero-respira { from { transform: scale(1); } to { transform: scale(1.06); } }
@keyframes hero-sobe { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* Barra de progresso do autoplay. `transform-origin: left` e `scaleX` para a
   animação rodar na GPU, sem reflow a cada quadro. O JS reinicia removendo e
   recolocando a classe com um reflow forçado, o mesmo recurso que o filtro de
   categoria já usa. Pausa junto com o autoplay via `is-parado` no hero. */
.hero__barra { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgb(255 255 255 / 0.18); z-index: 3; overflow: hidden; }
.hero__barra::after {
  content: ""; display: block; height: 100%; width: 100%;
  background: var(--color-accent); transform: scaleX(0); transform-origin: left;
}
@media (prefers-reduced-motion: no-preference) {
  .hero.is-correndo .hero__barra::after { animation: hero-barra 6s linear both; }
}
.hero.is-parado .hero__barra::after { animation-play-state: paused; }
@keyframes hero-barra { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.hero__media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--foco, center); z-index: 0;
}
@media (max-width: 767px) {
  .hero__media { object-position: var(--foco-mob, var(--foco, center)); }
}
.hero__slide::after { /* overlay p/ legibilidade do texto claro */
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--gradient-hero);
}
/* Sem `max-width` aqui: o elemento TAMBÉM tem a classe `.container`, e as duas
   regras têm a mesma especificidade, então quem vence depende da ordem na folha.
   Era exatamente essa colisão que fazia o título medir 427px até 1366 e 1280px a
   partir de 1440. Agora a largura do bloco é só a do `.container` (que alinha com
   o header) e a medida de linha mora em quem precisa dela: o título e o texto.
   O limite do celular ficou em responsive.css, num `max-width: 767px`. */
.hero__content { position: relative; z-index: 2; padding-block: var(--space-2xl); display: grid; gap: var(--space-md); }
.hero__eyebrow { color: var(--color-accent); }
.hero__title {
  font-family: var(--font-display); text-transform: uppercase;
  font-weight: var(--font-weight-light); font-size: var(--font-size-hero);
  line-height: var(--font-leading-tight); letter-spacing: var(--font-tracking-tight);
}
.hero__text { font-size: var(--font-size-lg); color: rgb(var(--color-canvas-rgb) / 0.9); }
.hero__cta { margin-top: var(--space-sm); }

/* Controles do slider */
.hero__controls {
  position: absolute; z-index: 3; left: 0; right: 0; bottom: var(--space-md);
  display: flex; align-items: center; justify-content: center; gap: var(--space-md);
}
.hero__dots { display: flex; gap: var(--space-sm); }
/* Mesma correção do dot do carrossel: o círculo segue com 10px e a área
   clicável vai a 24 (WCAG 2.5.8). Aqui o `::before` já era necessário porque o
   ponto tem contorno, e contorno num botão de 24px viraria um anel grande. */
.hero__dot {
  width: 24px; height: 24px; padding: 0; border: 0; background: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.hero__dot::before {
  content: ""; width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid var(--color-on-brand); background: transparent;
}
.hero__dot[aria-current="true"]::before { background: var(--color-on-brand); }
.hero__arrow, .hero__pause {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; border-radius: var(--radius-pill);
  border: 1px solid rgb(var(--color-canvas-rgb) / 0.6); background: rgb(var(--color-ink-rgb) / 0.25);
  color: var(--color-on-brand); cursor: pointer;
}
.hero__arrow:hover, .hero__pause:hover { background: rgb(var(--color-ink-rgb) / 0.45); }
.hero__arrow--prev .icon { transform: scaleX(-1); }
.hero--single .hero__controls { display: none; }
/* Pausa/retoma: o ícone segue o estado aria-pressed (sem troca por JS). */
.hero__pause .hero__ic-play { display: none; }
.hero__pause[aria-pressed="true"] .hero__ic-pause { display: none; }
.hero__pause[aria-pressed="true"] .hero__ic-play { display: inline; }

/* ══════════════════════════════ INTRO institucional ─────────────────────── */
.intro__title {
  font-family: var(--font-display); text-transform: uppercase;
  font-weight: var(--font-weight-light); font-size: var(--font-size-display);
  line-height: var(--font-leading-tight); letter-spacing: var(--font-tracking-tight);
  color: var(--color-brand); max-width: 24ch;
}
.intro__text { font-size: var(--font-size-lg); color: var(--color-ink); max-width: 60ch; margin-top: var(--space-md); }

/* ── Hero de segmento (Agricultura/Pecuária) — foto de contexto + scrim ─────── */
/* Sem margin-bottom (era var(--space-xl), 40px). A seção seguinte já abre com o
   próprio padding de topo, então a margem só somava: o encontro media 176px em
   /portfolio/, /agricultura/ e /pecuaria/. Sem ela fecha em 152px, e desses só
   os 88px de cima da seção seguinte são canvas vazio; os 64px de baixo ficam
   dentro da foto. */
.segment-hero {
  position: relative;
  min-height: clamp(300px, 46vw, 600px);
  display: grid; align-items: end;
  background: var(--color-brand);
  color: var(--color-on-brand); overflow: hidden;
}
/* A foto saiu do `background` da própria seção e virou CAMADA (2026-07-25), para
   o hero poder ter mais de uma e trocar em crossfade. Com uma foto só, o
   resultado na tela é idêntico ao de antes: a camada única fica em opacity 1 e
   nada anima. */
.segment-hero__bg { position: absolute; inset: 0; z-index: 0; }
.segment-hero__layer {
  position: absolute; inset: 0;
  background: var(--seg-bg, none) var(--seg-pos, center) / cover no-repeat;
  /* No celular vale a variante de 1280px quando ela existe. É o que torna o giro
     viável ali: a segunda foto da Pecuária cai de 631 KB para 193 KB. Sem `-sm`,
     o `var` volta para a grande e nada muda. Precisa ser media query no CSS, e
     não `<picture>`, porque isto é background-image. */
  @media (max-width: 767px) {
    background-image: var(--seg-bg-sm, var(--seg-bg, none));
  }
  opacity: 0;
  transition: opacity var(--motion-duration-slow) var(--motion-ease-standard);
}
.segment-hero__layer.is-active { opacity: 1; }
/* Pilha explícita: fotos (0) → scrim (1) → texto (2) → pausa (3). O `::after`
   é o último filho gerado, então empatar z-index com o texto o faria pintar POR
   CIMA do título. Cada camada tem o seu número, sem empate. */
.segment-hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  /* Duas direções. A vertical é a de sempre. A LATERAL entrou em 2026-07-25,
     quando a foto das embalagens passou a rodar aqui: o título é branco e cai
     em cima de bombonas brancas, e sem escurecer a esquerda ele sumia. Morre
     em 58% para não sujar o lado direito, que é onde o produto aparece. */
  background:
    linear-gradient(180deg, rgb(var(--color-scrim-rgb) / 0.12) 0%, rgb(var(--color-scrim-rgb) / 0.7) 100%),
    linear-gradient(90deg, rgb(var(--color-scrim-rgb) / 0.55) 0%, rgb(var(--color-scrim-rgb) / 0.18) 34%, rgb(var(--color-scrim-rgb) / 0) 58%);
}
/* Botão de pausa: mesma linguagem do da Home, em escala menor e discreto no
   canto. Existe porque conteúdo que se atualiza sozinho precisa de um jeito de
   parar (WCAG 2.2.2), mesmo sendo decoração. */
.segment-hero__pause {
  position: absolute; z-index: 3; right: var(--space-md); bottom: var(--space-md);
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 40px; border-radius: var(--radius-pill);
  border: 1px solid rgb(var(--color-canvas-rgb) / 0.5); background: rgb(var(--color-ink-rgb) / 0.28);
  color: var(--color-on-brand); cursor: pointer;
  backdrop-filter: blur(4px);
  opacity: 0.7; transition: opacity var(--motion-duration-fast) var(--motion-ease-standard),
                            background var(--motion-duration-fast) var(--motion-ease-standard);
}
.segment-hero:hover .segment-hero__pause,
.segment-hero__pause:focus-visible { opacity: 1; }
.segment-hero__pause:hover { background: rgb(var(--color-ink-rgb) / 0.5); }
.segment-hero__pause .segment-hero__ic-play { display: none; }
.segment-hero__pause[aria-pressed="true"] { opacity: 1; }
.segment-hero__pause[aria-pressed="true"] .segment-hero__ic-pause { display: none; }
.segment-hero__pause[aria-pressed="true"] .segment-hero__ic-play { display: inline; }
.segment-hero__inner { position: relative; z-index: 2; padding-block: var(--space-2xl); }
.segment-hero__eyebrow { color: var(--color-accent); }
.segment-hero__title {
  font-family: var(--font-display); text-transform: uppercase; font-weight: var(--font-weight-light);
  font-size: var(--font-size-hero); line-height: var(--font-leading-tight); letter-spacing: var(--font-tracking-tight);
  color: #fff; margin-top: var(--space-xs); max-width: 22ch;
}
.segment-hero__intro { font-size: var(--font-size-lg); color: rgb(var(--color-canvas-rgb) / 0.92); max-width: 54ch; margin-top: var(--space-sm); }
/* Placeholder (sem foto ainda): banda de marca + tag marcando o slot de imagem. */
.segment-hero__slot {
  position: absolute; top: var(--space-md); right: var(--space-md); z-index: 2;
  font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--font-tracking-wide);
  color: rgb(var(--color-canvas-rgb) / 0.72);
  border: 1px dashed rgb(var(--color-canvas-rgb) / 0.4); border-radius: 999px; padding: 5px 12px;
}

/* ══════════════════════════════ GRID utilitário ─────────────────────────── */
.grid { display: grid; gap: var(--space-lg); }
.grid--2 { grid-template-columns: 1fr; }
/* .grid--3 saiu em 2026-07-26 (aqui e no responsive.css): nenhum template do
   site jamais escreveu a classe. As grades de card usam .grid--cards. */
/* auto-FILL (não auto-fit): com poucos itens, os cards mantêm a largura padrão
   em vez de esticar pra preencher a linha (ex.: Limpa-Tanque com 1 produto). */
.grid--cards { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }

/* ── Listing (páginas de listagem filtrável) ──────────────────────────────── */
/* Sobrou só o intro. `.listing`, `.listing__filters`, `.listing__bar`,
   `.listing__count` e `.listing__empty` saíram em 2026-07-26: eram a casca do
   filtro por facetas, substituído pelas abas `.cat-filter`/`.cat-tab` quando o
   filtro virou dinâmico. partials/listing.njk não escreve nenhuma delas. */
.listing__intro { font-size: var(--font-size-lg); color: var(--color-ink-muted); max-width: 60ch; }

/* ── Segment card (Agricultura / Pecuária) ────────────────────────────────── */
.segment-card {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  min-height: 320px;
  display: grid; align-items: end;
  /* Cor chapada (2026-07-27), no lugar do degradê azul para verde. O degradê
     nasceu como reserva de "sem foto ainda", e com o véu por cima ele lia como
     retângulo por preencher. A cor é o azul da marca, o mesmo das faixas
     `.section--brand`, então o card entra no mesmo sistema do resto da página. */
  background: var(--color-brand);
  color: var(--color-on-brand);
  box-shadow: var(--shadow-sm);
}
.segment-card__media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
/* O véu só existe onde existe foto: ele é para domar imagem, e sobre cor
   chapada apenas escurecia o pé do card. */
.segment-card--foto::after { content: ""; position: absolute; inset: 0; z-index: 1; background: var(--gradient-hero); }
.segment-card__body { position: relative; z-index: 2; padding: var(--space-xl); display: grid; gap: var(--space-sm); }
.segment-card__title { font-family: var(--font-display); text-transform: uppercase; font-weight: var(--font-weight-light); font-size: var(--font-size-h2); line-height: var(--font-leading-tight); }
.segment-card__text { color: rgb(var(--color-canvas-rgb) / 0.9); }
/* Um card por cor da marca (2026-07-27): Agricultura no azul, Pecuária no verde
   profundo. O verde-limão do acento NÃO serve de fundo aqui: texto creme sobre
   ele mede 1,71:1 contra o mínimo de 4,5. Ele entra como DETALHE, no ícone e no
   hover do botão, que é onde um tom claro trabalha bem.
   Contraste conferido nos dois fundos: título creme 8,67 e 6,25, parágrafo 7,36
   e 5,41, ícone verde 5,06 e 3,65. Todos acima do mínimo. */
.segment-card--verde { background: var(--color-accent-deep); }

/* O ícone é o ponto de cor do card. */
.segment-card .icon { color: var(--color-accent); }

/* O botão vira verde no hover. `--color-on-accent` (tinta escura) e não branco:
   sobre o verde-limão o branco mede 1,71:1 e a tinta escura 8,68:1. É a mesma
   regra que o `.btn--accent` já segue no site. */
/* O card inteiro reage ao mouse, não só o botão: quem clica mira o retângulo,
   não o texto do link. Mesma elevação e mesma curva do `.product-card`, que já
   fazia isso, para os dois cards da Home se comportarem igual.
   O `transition` fica FORA do `prefers-reduced-motion`: sem ele o card salta de
   uma vez em vez de não se mexer, e quem pediu menos movimento quer o segundo. */
.segment-card { transition: transform var(--motion-duration-base) var(--motion-ease-out),
                            box-shadow var(--motion-duration-base) var(--motion-ease-out); }
@media (prefers-reduced-motion: no-preference) {
  .segment-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
}
/* O ícone acompanha, num passo menor: dá vida sem virar animação de brinde. */
.segment-card .icon { transition: transform var(--motion-duration-base) var(--motion-ease-out); }
@media (prefers-reduced-motion: no-preference) {
  .segment-card:hover .icon { transform: translateY(-2px) scale(1.06); }
}

.segment-card__cta { margin-top: var(--space-sm); }
.segment-card__cta:hover,
.segment-card__cta:focus-visible { background: var(--color-accent); color: var(--color-on-accent); }

/* ── Faixa CTA ────────────────────────────────────────────────────────────── */
.cta-band {
  background: var(--color-brand); color: var(--color-on-brand);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  display: flex; flex-wrap: wrap; gap: var(--space-lg);
  align-items: center; justify-content: space-between;
}
.cta-band__title { font-family: var(--font-display); text-transform: uppercase; font-weight: var(--font-weight-light); font-size: var(--font-size-h2); line-height: var(--font-leading-tight); margin: 0; max-width: 24ch; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: var(--space-md); }

/* ══════════════════════════════ PDP (produto) ════════════════════════════ */
/* Tema por produto: --product-accent é setado no .product (de products.js). O
   texto fica em cores seguras (AA); o acento aparece em barra, chips, mídia e
   detalhes — assim acentos claros (dourado/lima) não quebram contraste. */
.product-hero { background: var(--color-surface); border-top: 6px solid var(--product-accent); }
.product-hero__inner { display: grid; gap: var(--space-xl); padding-block: var(--space-2xl); align-items: center; }
.product-hero__eyebrow { font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--font-tracking-wide); font-weight: var(--font-weight-semibold); color: var(--color-accent-deep); }
.product-hero__name { font-family: var(--font-text); font-weight: var(--font-weight-bold); font-size: var(--font-size-hero); line-height: var(--font-leading-tight); color: var(--color-ink); margin-top: var(--space-xs); }
.product-hero__headline { font-family: var(--font-display); text-transform: uppercase; font-weight: var(--font-weight-light); font-size: var(--font-size-h2); line-height: var(--font-leading-tight); color: var(--color-ink-muted); margin-top: var(--space-sm); }
.product-hero__nutrients { margin-top: var(--space-lg); }
.product-hero__cta { margin-top: var(--space-lg); }
.product-hero__media { position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-lg); display: grid; place-items: center; background: color-mix(in srgb, var(--product-accent) 12%, var(--color-canvas)); }
/* `> img` e não `img`: as bombonas da família (.pack-fam img) são netas e têm
   dimensão própria, não podem herdar o 100% do logo/placeholder. */
.product-hero__media > img { width: 100%; height: 100%; object-fit: contain; padding: var(--space-xl); }
/* Packshot no hero: ABSOLUTO ancorado na base (não empurra a altura da mídia → a
   banda fica com altura consistente, guiada pelo texto). Altura proporcional ao
   volume (--pack-scale), contra a altura DEFINIDA da mídia. */
.product-hero__media .product-hero__packshot {
  position: absolute; inset: auto 0 0 0;
  width: 100%; height: calc(90% * var(--pack-scale, 1));
  object-fit: contain; object-position: center bottom;
  padding: 0;
}

/* ── Família de embalagens ─────────────────────────────────────────────────
   As bombonas do produto lado a lado, alinhadas pela base, cada uma com a
   altura proporcional ao próprio volume (--rel, calculado em products.js
   contra a maior do produto). O conjunto ocupa exatamente o mesmo espaço que a
   bombona única ocupava, então produto de tamanho único não muda em nada.
   Gestor 2026-07-25: o cliente pergunta pelas outras versões, então elas
   aparecem no lugar onde a embalagem já estava, no card e no hero. */
/* gap curto de propósito (gestor 2026-07-25): a linha tem que ler como UMA
   família, não como três produtos separados. Cada packshot já traz margem
   própria, porque o recorte no alfa inclui a sombra do render, que é mais larga
   que a bombona — então o respiro visível é maior que este número. */
.pack-fam { display: flex; align-items: flex-end; justify-content: center; gap: 0.5%; }
.pack-fam__item { position: relative; display: block; height: calc(100% * var(--rel, 1)); }
/* O `<picture>` entrou em 2026-08-01 entre o item e o `<img>`, e precisa ser
   transparente na conta de altura: sem isso o `height: 100%` do `<img>` passa a
   resolver contra a caixa `auto` do picture e a bombona colapsa. */
.pack-fam__item picture { display: block; height: 100%; }
.pack-fam__item img { display: block; height: 100%; width: auto; max-width: 100%; object-fit: contain; }
/* SEM sombra desenhada no CSS (gestor 2026-07-25). O render de estúdio já traz
   a sombra dele na própria imagem, com o formato e a direção de luz certos —
   qualquer elipse ou silhueta por cima vira sombra dobrada e artificial. Foram
   testadas e recusadas, nesta ordem: elipse única, elipse com projeção
   secundária de opacidade baixa e sombra gerada da silhueta por `mask`. A foto
   entra como veio. */

/* ── A LINHA SE MONTANDO (entrada do hero da PDP) ──────────────────────────
   Substitui a bombona flutuando, que o gestor achou infantil e que parou de
   fechar quando a embalagem virou linha de tamanhos (2026-07-25).

   A cena: a MAIOR chega primeiro no lugar dela; as menores saem DE TRÁS dela,
   uma a uma, deslizando para o seu posto. Três decisões sustentam isso:

   1. Quem desliza não faz fade. Ela parte de `translateX(112%)`, ou seja, do
      espaço que a vizinha da direita ocupa — e a vizinha é sempre mais larga
      e mais alta, então cobre a menor por inteiro. O olho lê "saiu de trás",
      não "surgiu do nada". O único fade é o do primeiro 1% do percurso, para
      a peça não existir antes da maior aparecer.
   2. A ordem de pintura já é a certa. Os itens vêm do menor para o maior no
      DOM, e irmãos posicionados pintam na ordem do documento: a maior fica
      naturalmente por cima. Nenhum `z-index` precisa entrar.
   3. `transform-origin` na base. Toda escala cresce a partir do chão, então a
      bombona nunca desgruda do apoio — que é a correção que acabamos de fazer
      na sombra e que a animação não pode desfazer.

   Responsivo de graça: tudo em % do próprio elemento e sem medida em pixel.
   O atraso `--pd` vem inline do produto.njk, contado ao contrário (a maior em
   0). Com UM tamanho só o cálculo dá 0 e sobra a chegada da bombona sozinha.

   `will-change` sai no fim da animação (regra `.is-in` + `animation-fill-mode`
   não limpa sozinho): mantê-lo ligado para sempre custa memória de GPU à toa. */
.js-pack .product-hero__packshot .pack-fam__item { opacity: 0; }
.js-pack .product-hero__packshot .pack-fam__item { transform-origin: 50% 100%; }

@media (prefers-reduced-motion: no-preference) {
  .js-pack .product-hero__packshot.is-in .pack-fam__item {
    animation: pack-chega 760ms var(--motion-ease-out) both;
    animation-delay: var(--pd, 0ms);
    will-change: transform, opacity;
  }
  /* todas menos a maior (que é a última do DOM) saem de trás da vizinha */
  .js-pack .product-hero__packshot.is-in .pack-fam__item:not(:last-child) {
    animation-name: pack-sai-de-tras;
    animation-duration: 820ms;
  }
  /* cena assentada: solta a memória de GPU (classe posta pelo pack-anim.js) */
  .js-pack .product-hero__packshot.is-pronta .pack-fam__item { will-change: auto; }
}
/* sem movimento: a linha simplesmente está lá */
@media (prefers-reduced-motion: reduce) {
  .js-pack .product-hero__packshot .pack-fam__item { opacity: 1; }
}

/* a maior: aterrissa crescendo a partir da base, sem sair do lugar */
@keyframes pack-chega {
  from { opacity: 0; transform: scale(0.93); }
  to   { opacity: 1; transform: scale(1); }
}
/* as menores: deslizam para fora de trás da vizinha maior */
@keyframes pack-sai-de-tras {
  from { opacity: 0; transform: translateX(112%) scale(0.97); }
  1%   { opacity: 1; }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
/* O cartão branco de "packshot pendente" saiu em 2026-07-31, com o ramo dele no
   produto.njk: ele abria um retângulo vazio de 360 por 530 com o nome do produto
   afundado no rodapé. Nenhum produto cai aqui hoje, os 28 têm packshot; a regra
   fica como rede para um produto novo que entre sem foto. */
.product-hero--sem-media .product-hero__inner { grid-template-columns: 1fr; }

/* ── Variante hero em BANNER (inspirada na parte superior do folder / Banner.svg):
   FOTO limpa no topo + faixa fina de transição na cor do produto + BANDA SÓLIDA
   embaixo (a cor do produto), com o packshot fazendo a ponte. Texto branco na banda,
   sem gradiente sobre a foto. EM TESTE via heroBackground. ── */
.product-hero--banner {
  /* Altura da faixa de foto. Subiu de `clamp(220px, 30vw, 420px)` em 2026-07-25,
     quando as fotos de hero começaram a chegar. Com 30vw a faixa ficava em
     3,63:1 numa janela de 1525 px e mostrava só 49% de uma imagem 16:9: o céu,
     que é de onde vem a atmosfera, era a primeira coisa que o corte comia. Com
     37vw a faixa fica em 2,70:1 de 733 até 1620 px e mostra 66%.
     O que manda aqui é o `37vw`, não o teto: o teto só entra acima de 1620 px.
     Medido no navegador, não estimado. */
  --hero-photo-h: clamp(240px, 37vw, 600px);
  position: relative; isolation: isolate; overflow: hidden;
  border-top: none;
  background: var(--product-accent);          /* a banda sólida = fundo da seção */
  color: var(--color-on-brand);
}
.product-hero__photo {
  position: absolute; top: 0; left: 0; right: 0; height: var(--hero-photo-h);
  /* Abaixo de 768 usa a variante de 1280px (`--hero-bg-sm`), que existe para as
     27 PDPs com foto; sem ela, cai na grande, que é o comportamento de antes. */
  background-image: var(--hero-bg, none); background-size: cover;
  /* `center 40%` é o recorte padrão das 28 PDPs; `--hero-foco` só existe nos
     produtos em que ele corta o assunto (products.js, campo heroFocus). */
  background-position: var(--hero-foco, center 40%);
  z-index: 0;
}
@media (max-width: 767px) {
  .product-hero__photo { background-image: var(--hero-bg-sm, var(--hero-bg, none)); }
}
.product-hero__photo::after {   /* faixa de transição = cor do produto a 50% (cor secundária) */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 44px;
  background: color-mix(in srgb, var(--product-accent) 50%, transparent);
}
/* Placeholder da foto (enquanto a imagem real não chega) — cinza neutro como o
   Banner.svg, com rótulo discreto. Some sozinho quando `--hero-bg` for setado
   (basta soltar src/img/hero/{slug}.webp). */
.product-hero__photo--placeholder { background-color: #e6e6e6; display: grid; place-items: center; }
.product-hero__photo--placeholder::before {
  content: "Imagem do produto";
  font-family: var(--font-text); font-size: var(--font-size-xs);
  letter-spacing: var(--font-tracking-wider); text-transform: uppercase; color: #a79f92;
}
.product-hero--banner .product-hero__inner {
  position: relative; z-index: 1;
  padding-top: calc(var(--hero-photo-h) + var(--space-xl));   /* respiro entre a foto e o texto */
  padding-bottom: var(--space-2xl);                            /* respiro abaixo do CTA */
  align-items: end;
}
.product-hero--banner .product-hero__eyebrow { color: var(--color-on-brand); opacity: 0.9; }
.product-hero--banner .product-hero__name,
.product-hero--banner .product-hero__headline { color: var(--color-on-brand); }
/* Ritmo interno PADRONIZADO: flex + gap uniforme cobre qualquer combinação de
   elementos (com/sem headline, com/sem chips) sem gaps estranhos. */
.product-hero--banner .product-hero__info { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-md); }
.product-hero--banner .product-hero__name,
.product-hero--banner .product-hero__headline,
.product-hero--banner .product-hero__nutrients,
.product-hero--banner .product-hero__cta { margin: 0; }
.product-hero--banner .product-hero__cta { margin-top: var(--space-sm); }
.product-hero--banner .nutrient-chip { background: rgba(255, 255, 255, 0.2); color: var(--color-on-brand); }
/* CTA legível na banda de acento ESCURO: botão branco-quente + azul de marca
   (o azul padrão sobre acento escuro tem contraste fraco). */
.product-hero--banner .btn--whatsapp { background: var(--color-on-brand); color: var(--color-brand); }
.product-hero--banner .btn--whatsapp:hover { background: #fff; color: var(--color-brand-strong); }
/* Acento CLARO (dourado/lima/…): a banda pede texto e chips ESCUROS; e o CTA
   volta ao azul padrão, que já contrasta sobre a banda clara. Marcado por
   data-accent-tone (calculado por contraste WCAG em products.js). */
.product-hero--banner[data-accent-tone="light"] .product-hero__eyebrow,
.product-hero--banner[data-accent-tone="light"] .product-hero__name,
.product-hero--banner[data-accent-tone="light"] .product-hero__headline { color: var(--color-ink); }
.product-hero--banner[data-accent-tone="light"] .nutrient-chip { background: color-mix(in srgb, var(--color-ink) 12%, transparent); color: var(--color-ink); }
.product-hero--banner[data-accent-tone="light"] .btn--whatsapp { background: var(--color-brand); color: var(--color-on-brand); }
.product-hero--banner[data-accent-tone="light"] .btn--whatsapp:hover { background: var(--color-brand-strong); }
.product-hero--banner .product-hero__media {
  background: none; border-radius: 0;
  align-self: end;
  place-items: end center;   /* a bombona assenta na base da banda (prateleira) */
  /* Altura DEFINIDA (= a da foto) em vez de aspect-ratio: sem isso, o max-height:%
     da bombona resolve contra altura indefinida e a mídia INFLA (bombonas estreitas
     como a 1L faziam a banda dobrar de tamanho). Agora a banda fica consistente,
     guiada pelo texto, igual em todos os produtos. */
  height: var(--hero-photo-h);
  aspect-ratio: auto;
  /* mobile: bombona abaixo do texto, sem overlap. A "ponte" (margin negativo) só
     entra no desktop 2-col (responsive.css), senão cobriria o CTA no empilhado. */
}
/* O cartão branco de packshot pendente saiu em 2026-07-31, junto com o ramo
   dele no produto.njk: o único produto que caía nele era o Rooting SMF, e lá a
   falta de embalagem virou permanente, não pendência. Sem a coluna de mídia a
   banda passa a ter uma coluna só (`.product-hero--sem-media`, acima). */

/* ── Corpo da PDP (redesign editorial, 2026-07-23) ─────────────────────────
   O que o produtor precisa: Sobre → Culturas indicadas → Como usar (faixa
   sutil) → Benefícios → carrossel. A COMPOSIÇÃO vive só no hero (não repete).
   Respiro generoso; reveal no scroll via [data-reveal]. Sem borda-de-acento,
   sem número-gigante, sem stepper (menos, bem feito). */
.product-block__title { font-family: var(--font-display); text-transform: uppercase; font-weight: var(--font-weight-light); font-size: var(--font-size-h2); line-height: var(--font-leading-tight); color: var(--color-brand); margin-bottom: var(--space-md); }

/* Reveal (site todo): só esconde sob html.js-reveal; --rd = stagger por item. */
.js-reveal [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity var(--motion-duration-slow) var(--motion-ease-out) var(--rd, 0ms),
              transform var(--motion-duration-slow) var(--motion-ease-out) var(--rd, 0ms);
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }

/* Cascata de filhos (2026-07-26). O container fica quieto e quem entra são os
   filhos, um atrás do outro. Existe para não ter que escrever `data-reveal` e
   `--rd` em cada card de uma grade: marcar a grade basta.

   O escalonamento é por `nth-child` e não por `--rd` inline porque os filhos
   quase sempre vêm de um `{% for %}` ou de um macro, e mexer no macro só para
   carregar um atraso contaminaria as outras páginas que o usam.

   O deslocamento é menor que o do `[data-reveal]` (14px contra 18px): são vários
   elementos entrando juntos, e com o mesmo salto do bloco inteiro a seção
   inteira parece tremer. */
.js-reveal [data-reveal-kids] > * {
  opacity: 0; transform: translateY(14px);
  transition: opacity var(--motion-duration-slow) var(--motion-ease-out),
              transform var(--motion-duration-slow) var(--motion-ease-out);
}
.js-reveal [data-reveal-kids].is-in > * { opacity: 1; transform: none; }
.js-reveal [data-reveal-kids].is-in > *:nth-child(2) { transition-delay: 90ms; }
.js-reveal [data-reveal-kids].is-in > *:nth-child(3) { transition-delay: 180ms; }
.js-reveal [data-reveal-kids].is-in > *:nth-child(4) { transition-delay: 270ms; }
.js-reveal [data-reveal-kids].is-in > *:nth-child(5) { transition-delay: 360ms; }
.js-reveal [data-reveal-kids].is-in > *:nth-child(6) { transition-delay: 450ms; }
/* teto: do sétimo em diante todos entram juntos. Cascata longa demais vira
   espera, e o visitante já rolou para longe antes de o último aparecer. */
.js-reveal [data-reveal-kids].is-in > *:nth-child(n + 7) { transition-delay: 520ms; }

/* Barra de CTA fixa (mobile) — pdp-bar.js mostra quando o hero sai de vista */
.pdp-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-header, 50);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
  padding: 10px var(--space-md) calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--color-surface); border-top: 1px solid var(--color-hairline);
  box-shadow: 0 -6px 24px rgb(var(--color-ink-rgb) / 0.08);
  transform: translateY(102%);
  transition: transform var(--motion-duration-base) var(--motion-ease-standard);
}
.pdp-bar.is-up { transform: none; }
.pdp-bar__name { font-weight: var(--font-weight-bold); color: var(--color-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pdp-bar .btn--whatsapp { flex-shrink: 0; }
@media (min-width: 768px) { .pdp-bar { display: none; } }


/* ── Corpo da PDP v3 (padrão de todas as PDPs, 2026-07-23) ─────────────────
   Composição garantida = protagonista: barras enchem no scroll (reveal) e o
   teor conta (pdp-anim.js). Culturas com ícone em marquee, "como usar" e
   benefícios com reveal. Tudo escopado em .pdp-v3. Sem JS: barras cheias e teor
   real (progressive enhancement).
   Acento como cor: --on-accent = texto/símbolo SOBRE o acento (branco no acento
   escuro, tinta no claro); --accent-ink = acento vindo como ícone/texto sobre
   fundo claro (escurecido quando o acento é claro, p/ manter contraste). O tom
   vem de data-accent-tone no <article> (products.js → accentIsLight). */
.product--v3 {
  --on-accent: var(--color-surface); --accent-ink: var(--product-accent);
  /* O INVERSO do --on-accent. Serve para um elemento que precisa de contraste
     de texto DE VERDADE em cima do acento: preenchido com --on-accent e escrito
     com --on-accent-inverse, o par vira tinta-sobre-superfície, que mede acima
     de 13:1 nos 28 produtos. Escrever direto sobre o acento não resolveria:
     três acentos (#808285, #ed1c24, #0089cf) ficam em 4,06 a 4,16 contra o
     mínimo AA de 4,5, e não há escolha entre branco e tinta que passe neles. */
  --on-accent-inverse: var(--color-ink);
}
.product--v3[data-accent-tone="light"] {
  --on-accent: var(--color-ink);
  --on-accent-inverse: var(--color-surface);
  --accent-ink: color-mix(in srgb, var(--product-accent), var(--color-ink) 42%);
}

/* eyebrow com ícone + título calmo (sentence case) */
.pdp-v3 .pv-k { display: inline-flex; align-items: center; gap: 8px; margin: 0 0 var(--space-sm);
  font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--font-tracking-wide);
  /* Era `color-mix(--product-accent 80%, ink)`, uma correção fixa que não olhava
     a cor de origem e ainda reprovava em nove produtos (AUD-007). Agora usa o
     acento já calculado para texto, que garante 4,5:1 produto a produto. */
  font-weight: var(--font-weight-semibold); color: var(--product-accent-text, var(--product-accent)); }
.pdp-v3 .pv-k__i { color: var(--accent-ink); flex: none; width: 15px; height: 15px; }
.pdp-v3 .pv-h { font-family: var(--font-text); font-weight: var(--font-weight-medium);
  font-size: clamp(1.4rem, 1rem + 1.3vw, 1.85rem); line-height: 1.15; letter-spacing: -0.01em;
  color: var(--color-ink); margin: 0; }
.pdp-v3 .pv-head { margin-bottom: clamp(var(--space-lg), 3vw, var(--space-2xl)); }
/* Coerência de conjunto: o título do carrossel de relacionados no MESMO tom dos
   headings do corpo v3 (sentence case, fonte de texto, ink) — não no display
   caixa-alta azul. Escopo product--v3, entra no rollout. */
.product--v3 .product-block__title { font-family: var(--font-text); font-weight: var(--font-weight-medium);
  text-transform: none; font-size: clamp(1.4rem, 1rem + 1.3vw, 1.85rem); line-height: 1.15;
  letter-spacing: -0.01em; color: var(--color-ink); }

/* seções soltas (não-banda) + faixas na cor do produto */
.pdp-v3 .pv-sec { padding-top: clamp(2.75rem, 6vw, 4.75rem); }
.pdp-v3 .pv-sec .pv-h { margin-bottom: var(--space-lg); }
.pdp-v3 .pv-band { margin-top: clamp(3rem, 7vw, 5.5rem); padding-block: clamp(2.75rem, 6.5vw, 5rem); }
.pdp-v3 .pv-comp-band { background: color-mix(in srgb, var(--product-accent) 6%, var(--color-canvas));
  border-block: 1px solid color-mix(in srgb, var(--product-accent) 14%, var(--color-hairline)); }
.pdp-v3 .pv-use-band { background: var(--color-surface); border-block: 1px solid var(--color-hairline); }

/* Sobre */
.pdp-v3 .pv-lead { max-width: 60ch; font-size: clamp(1.08rem, 1rem + 0.5vw, 1.28rem); line-height: 1.65; color: var(--color-ink); margin: 0; }

/* Composição — barras animadas */
/* `max-width: 720px` era a medida certa enquanto o percentual ficava na ponta
   direita da linha: o nome ancorava um lado, o número o outro, e o corte em 720
   lia como decisão. Com o número fora (2026-07-31) a barra passou a terminar no
   nada, com cerca de 500px de vazio à direita num container de 1232, e o produto
   de um nutriente só virava uma barra cheia solta no meio da página.
   No desktop o nome sobe para a MESMA linha da barra (regra do `__meta` adiante):
   a linha volta a ter conteúdo dos dois lados, a faixa encolhe pela metade na
   altura e a medida pode crescer. No celular continua empilhado. */
.pdp-v3 .pv-nuts { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(var(--space-md), 2.4vw, var(--space-xl)); max-width: 720px; }
.pdp-v3 .pv-nut { display: grid; grid-template-columns: 52px 1fr; gap: var(--space-lg); align-items: center; }
.pdp-v3 .pv-nut__sym { width: 52px; height: 52px; border-radius: var(--radius-md); display: grid; place-items: center;
  background: var(--product-accent); color: var(--on-accent);
  font-family: var(--font-text); font-weight: var(--font-weight-bold); font-size: 1.15rem; letter-spacing: -0.02em; }
.pdp-v3 .pv-nut__meta { display: grid; gap: 8px; min-width: 0; }
.pdp-v3 .pv-nut__row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-md); }
.pdp-v3 .pv-nut__nm { font-weight: var(--font-weight-medium); color: var(--color-ink); }
.pdp-v3 .pv-track { height: 9px; border-radius: 999px; overflow: hidden; background: color-mix(in srgb, var(--product-accent) 12%, var(--color-hairline)); }
.pdp-v3 .pv-nuts--unico .pv-track { display: none; }
@media (min-width: 768px) {
  /* nome e barra na mesma linha; 168px cobre "Manganês" e "Nitrogênio" sem
     quebrar, e o `1fr` deixa a barra ocupar tudo o que sobra. */
  /* Sem limite de largura: a faixa vizinha ("Como usar") ocupa o container
     inteiro, e a de composição parava em 900px, o que deixava as duas
     desalinhadas. Aqui a largura também é o que dá poder de comparação: com o
     percentual fora da tela, o comprimento da barra virou o ÚNICO sinal de
     quantidade, e barras longas na mesma coluna se comparam de relance. Por
     isso continua uma coluna só, e não duas: em duas o olho perde a régua. */
  .pdp-v3 .pv-nuts { max-width: none; }
  .pdp-v3 .pv-nut__meta { grid-template-columns: 168px 1fr; align-items: center; gap: var(--space-lg); }
  /* sem barra, o nome não precisa da coluna estreita */
  .pdp-v3 .pv-nuts--unico .pv-nut__meta { grid-template-columns: 1fr; }
}
.pdp-v3 .pv-fill { display: block; position: relative; overflow: hidden; height: 100%; width: var(--w); border-radius: 999px;
  background: var(--product-accent); } /* sólido/flat — orna com o resto do sistema (tiles, card, chips) */
/* com JS: começa em 0 e enche quando a lista entra na tela (stagger por --rd) */
.js-reveal .pdp-v3 .pv-fill { width: 0; transition: width 1s var(--motion-ease-out) var(--rd, 0ms); }
.js-reveal .pdp-v3 .pv-nuts.is-in .pv-fill { width: var(--w); }
/* glint: uma faixa de LUZ CLARA varre cada barra ao encher (ref. do gestor).
   Off-screen em repouso; dispara com .is-in, escalonada pelo --rd de cada barra. */
.pdp-v3 .pv-fill::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 55%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.38) 50%, transparent);
  transform: translateX(-140%);
}
@media (prefers-reduced-motion: no-preference) {
  .js-reveal .pdp-v3 .pv-nuts.is-in .pv-fill::after {
    animation: bar-shine 1.3s ease-in-out calc(var(--rd, 0ms) + 0.35s) both;
  }
}
@keyframes bar-shine {
  0%   { transform: translateX(-140%); opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { transform: translateX(240%); opacity: 0; }
}

/* Culturas — chips com ícone */
/* Marquee (reel) das culturas — DUAS fileiras em direções OPOSTAS, velocidades
   diferentes (40s/34s = orgânico, não mecânico), pausa no hover, fade nas bordas.
   Loop perfeito: chips duplicados + margin-right no chip (não flex-gap) → -50%
   cai exatamente no início do 2º set. Reduced-motion: para e quebra em linhas. */
.pdp-v3 .pv-marquee { margin-top: var(--space-lg); display: grid; gap: var(--space-sm); overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }
.pdp-v3 .pv-marquee__track { list-style: none; margin: 0; padding: 4px 0; display: flex; width: max-content; }
.pdp-v3 .pv-marquee__track--a { animation: chips-marquee 120s linear infinite; }
.pdp-v3 .pv-marquee__track--b { animation: chips-marquee 102s linear infinite reverse; }
.pdp-v3 .pv-marquee__track .pv-chip { margin-right: var(--space-sm); }
.pdp-v3 .pv-marquee:hover .pv-marquee__track { animation-play-state: paused; }
@keyframes chips-marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .pdp-v3 .pv-marquee { -webkit-mask-image: none; mask-image: none; }
  .pdp-v3 .pv-marquee__track { flex-wrap: wrap; row-gap: var(--space-sm); width: auto; animation: none; }
  .pdp-v3 .pv-chip--dup { display: none; }
}
/* Chip elegante p/ o nicho: maior, ícone botânico DIRETO (sem "dot", que puxava
   pro infantil), borda de acento discreta e tipografia confortável. */
.pdp-v3 .pv-chip { display: inline-flex; align-items: center; gap: 11px; padding: 10px 20px; border-radius: var(--radius-pill);
  background: var(--color-surface);
  border: 1px solid color-mix(in srgb, var(--product-accent) 22%, var(--color-hairline));
  font-size: 0.95rem; font-weight: var(--font-weight-medium); letter-spacing: 0.01em; color: var(--color-ink);
  transition: transform var(--motion-duration-fast) var(--motion-ease-standard),
              border-color var(--motion-duration-fast) var(--motion-ease-standard),
              color var(--motion-duration-fast) var(--motion-ease-standard),
              background var(--motion-duration-fast) var(--motion-ease-standard); }
.pdp-v3 .pv-chip__i { flex: none; width: 22px; height: 22px; color: var(--accent-ink);
  transition: color var(--motion-duration-fast) var(--motion-ease-standard); }
/* hover dá propósito: a cultura apontada ACENDE (verde sólido) */
.pdp-v3 .pv-chip:hover { transform: translateY(-1px); color: var(--on-accent);
  background: var(--product-accent); border-color: var(--product-accent); }
.pdp-v3 .pv-chip:hover .pv-chip__i { color: var(--on-accent); }

/* ── Culturas: faixa curta com foto suavizada por vidro LEVE (v3) ────────────
   Véu discreto: a lavoura fica visível, só amaciada (não disfarçada). Marquee
   full-bleed, SEM fade nas bordas. Foto por linha via --crops-bg. */
.pdp-v3 .pv-crops { position: relative; overflow: hidden; margin: 0;
  background-color: #16281b; background-image: var(--crops-bg); background-size: cover; background-position: center 45%; }
/* faixa COLADA: sem moldura de creme antes/depois — só o strip da imagem.
   Zera o padding das seções vizinhas no lado que encosta na faixa; o respiro
   vira o padding interno da própria imagem. */
.pdp-v3 .pv-comp-band:has(+ .pv-crops) { padding-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.pdp-v3 .pv-crops + .pv-use-band { margin-top: 0; padding-top: clamp(2.5rem, 5vw, 3.5rem); }
.pdp-v3 .pv-crops__frost { position: absolute; inset: -2px; pointer-events: none;
  -webkit-backdrop-filter: blur(8px) saturate(1.08); backdrop-filter: blur(8px) saturate(1.08);
  background: linear-gradient(180deg, rgba(18,32,22,0.10), rgba(12,24,15,0.17)); }
.pdp-v3 .pv-crops__inner { position: relative; z-index: 1;
  padding: clamp(1.25rem, 3vw, 1.75rem) 0 clamp(1.5rem, 3.5vw, 2.25rem); }
/* texto legível sobre a foto visível: sombra (não vidro escuro) */
.pdp-v3 .pv-crops .pv-k, .pdp-v3 .pv-crops .pv-h { text-shadow: 0 2px 18px rgba(0,0,0,0.55); }
.pdp-v3 .pv-crops .pv-k { color: rgba(255,255,255,0.94); margin: 0 0 var(--space-sm); }
.pdp-v3 .pv-crops .pv-k__i { color: #cfe8a0; }
.pdp-v3 .pv-crops .pv-h { color: #fff; margin: 0; }
/* marquee FULL-BLEED, sem fade nas bordas (gestor não curte o esmaecido) */
.pdp-v3 .pv-crops .pv-marquee { margin-top: clamp(var(--space-md), 2.5vw, var(--space-lg));
  -webkit-mask-image: none; mask-image: none; }
.pdp-v3 .pv-crops .pv-chip { color: #fff; background: rgba(255,255,255,0.13); border-color: rgba(255,255,255,0.30);
  text-shadow: 0 1px 8px rgba(0,0,0,0.35); -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); }
.pdp-v3 .pv-crops .pv-chip__i { color: #cfe8a0; }
.pdp-v3 .pv-crops .pv-chip:hover { background: var(--product-accent); border-color: var(--product-accent); color: var(--on-accent); text-shadow: none; }
.pdp-v3 .pv-crops .pv-chip:hover .pv-chip__i { color: var(--on-accent); }

/* Como usar — dose em destaque + passos com ícone */
/* GRADE MODULAR (2026-08-01). O desenho anterior era duas colunas: a chamada
   ocupava a esquerda inteira e os dois blocos de informação a direita. Como as
   duas colunas nunca têm a mesma altura, sobrava sempre um vão embaixo de uma
   delas, e um bloco de cor com metade vazia lê como página quebrada.
   Agora são TRÊS células numa grade de duas colunas: os dois blocos de
   informação dividem a primeira linha e a chamada ocupa a segunda inteira. Cada
   célula é preenchida pelo que tem dentro, e o que muda de tamanho entre
   produtos (o texto da aplicação) empurra a linha inteira, não deixa buraco.
   A proporção 1,6/1 dá ao texto de aplicação, que é o mais longo, quase o dobro
   da caixa de embalagens, que costuma ter uma linha só. */
.pdp-v3 .pv-use {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  grid-template-areas: "aplicacao embalagem" "chamada chamada";
  gap: clamp(var(--space-md), 2vw, var(--space-lg));
  align-items: stretch;
}
.pdp-v3 .pv-dose { display: grid; gap: 4px; align-content: center; padding: clamp(var(--space-lg), 3vw, var(--space-xl));
  border-radius: var(--radius-lg); background: var(--product-accent); color: var(--on-accent); }
/* O cartão de chamada NÃO estica junto com a coluna de passos ao lado
   (2026-08-01). Medido em 1440: ele ficava com 388px de altura para 127px de
   conteúdo, ou seja, 181px de bloco de cor vazio, quase metade. Com
   `align-self: start` ele passa a ter a altura do que tem dentro. O vão que
   sobra vira fundo de página, que lê como respiro, e não bloco vermelho vazio,
   que lê como algo faltando. No celular não muda nada: lá ele já vem primeiro,
   em coluna única, e o vazio era de 40px. */
/* Volta a esticar: numa linha própria, de largura inteira, esticar é o que
   preenche a célula. O `align-self: start` existia para conter o vão da grade
   antiga, que deixou de existir. */
.pdp-v3 .pv-dose--ask { align-self: stretch; }
/* Ícone na MESMA linha do título, e não empilhado: são duas linhas curtas, e
   empilhadas elas espalhavam 127px de conteúdo por uma área que não precisava
   de tudo isso. */
/* Faixa larga: ícone, título e botão na mesma linha, com o botão empurrado
   para a direita pelo `1fr` do meio. No celular isso quebra em duas linhas
   sozinho, pela regra de 767px adiante. */
.pdp-v3 .pv-dose--ask {
  grid-template-columns: auto 1fr auto; align-items: center;
  column-gap: var(--space-lg); padding-block: var(--space-lg);
}
.pdp-v3 .pv-dose--ask .pv-dose__cta { grid-column: auto; margin-top: 0; }
.pdp-v3 .pv-dose__i { color: var(--on-accent); opacity: 0.9; width: 28px; height: 28px; }
.pdp-v3 .pv-dose__lb { margin: 8px 0 0; font-family: var(--font-text); font-weight: var(--font-weight-semibold); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--font-tracking-wide); color: color-mix(in srgb, var(--on-accent) 82%, transparent); }
/* `.pv-dose__v`, o número grande da dose, foi retirado do template em
   2026-07-31 (o gestor tirou a dose da tela). A regra sai junto para o seletor
   não ficar órfão. No lugar entra o botão abaixo, no mesmo cartão de acento.

   O botão é `--on-accent` sobre o próprio acento do produto, e o acento varia de
   #ffcb04 a #004a82 entre as 28 PDPs. Por isso ele NÃO é preenchido: é contorno
   com a mesma tinta do rótulo acima, que já é a cor escolhida por contraste em
   `accentIsLight`. No hover inverte, e aí o fundo é a tinta e o texto é o
   acento, que é o mesmo par de cores ao contrário. Assim o contraste vale nos
   dois estados sem precisar de uma cor por produto. */
/* O cartão foi desenhado para um número grande (`.pv-dose__v`, agora retirado)
   e a altura dele vem da coluna ao lado, que tem dois blocos. Com só um rótulo
   pequeno e um botão sobrava meia altura de vermelho. Em vez de inventar texto
   novo, o RÓTULO que já existia virou o elemento grande, na fonte display, no
   lugar que era do número. As palavras são as mesmas. */
.pdp-v3 .pv-dose--ask .pv-dose__lb {
  margin: 0;
  /* Fonte SECUNDÁRIA (PF Square Sans Pro) de propósito, e não a principal
     (Fixture Condensed), que é a exceção neste elemento (gestor, 2026-08-01).
     A Fixture só existe em Light, então numa faixa larga, em corpo pequeno e ao
     lado de um botão que também é de texto, ela fica fraca; testada em caixa
     alta para ganhar presença, o gestor preferiu a secundária. Aqui o rótulo
     funciona mais como chamada de ação do que como título de seção, e a
     secundária em semibold é o que dá firmeza sem competir com o botão. */
  font-family: var(--font-text);
  font-weight: var(--font-weight-semibold);
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  line-height: 1.12;
  /* Cancela a caixa alta e o espaçamento largo da regra base do `.pv-dose__lb`,
     que ali é um rótulo de eyebrow, de 12px. Aqui o elemento é a chamada da
     faixa, em corpo maior, e caixa alta com tracking largo deixa a frase com
     cara de etiqueta. Estas duas linhas já existiram, sumiram num teste de caixa
     alta em 2026-08-01 e voltaram: sem elas, o rótulo herda o estilo de eyebrow
     e ninguém percebe olhando só este bloco. */
  text-transform: none;
  letter-spacing: var(--font-tracking-normal);
  /* Sem `max-width`. Havia um `14ch` aqui que quebrava "Dose e orientação
     técnica" em duas linhas em TODAS as larguras, e a frase cabe em uma só:
     medida no navegador, ela precisa de 275px onde o cartão oferece 310 no
     celular de 390 e 455 no desktop de 1440. O cap era herança do cartão
     antigo, onde o elemento grande era um número curto. */
  color: var(--on-accent);
}
.pdp-v3 .pv-dose__i { width: 40px; height: 40px; }
/* O botão é SÓLIDO, e não de contorno. A primeira versão era contorno com o
   texto em `--on-accent` direto sobre o acento, e isso REPROVA: em MicroMMol
   (#808285), M10 (#ed1c24) e Manzin S (#0089cf) o melhor par possível mede 4,06
   a 4,16, abaixo do mínimo AA de 4,5 para texto de 16px, e não existe escolha
   entre branco e tinta que passe nesses três.
   Preenchido, o rótulo vira tinta sobre superfície, 15,4:1 no pior dos 28, e o
   corpo do botão contra o acento, que é elemento não textual e pede 3:1, fica
   com os mesmos 4,06 a 10,35 de antes.
   O hover NÃO troca cor, justamente para não desfazer isso: acende um halo da
   mesma tinta e sobe 1px. */
.pdp-v3 .pv-dose__cta {
  justify-self: start;
  margin-top: var(--space-md);
  display: inline-flex; align-items: center; gap: var(--space-sm);
  min-height: 44px; padding: 12px var(--space-xl);
  border-radius: var(--radius-pill, 999px);
  background: var(--on-accent); color: var(--on-accent-inverse);
  font-family: var(--font-text); font-weight: var(--font-weight-semibold);
  text-decoration: none;
  transition: box-shadow var(--motion-duration-fast) var(--motion-ease-out),
              transform var(--motion-duration-fast) var(--motion-ease-out);
}
.pdp-v3 .pv-dose__cta:hover,
.pdp-v3 .pv-dose__cta:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--on-accent) 32%, transparent);
}
/* `display: contents` faz o container sumir da grade e os passos virarem
   células diretas, cada um na sua área. Sem isso eles continuariam empilhados
   dentro de uma coluna só. */
.pdp-v3 .pv-steps { display: contents; }
.pdp-v3 .pv-step--aplicacao { grid-area: aplicacao; }
.pdp-v3 .pv-step--embalagem { grid-area: embalagem; }
/* O bloco de preparo da calda está desligado hoje (`dosageNote` é null em todos
   os 28), mas se voltar ele entra numa linha própria, de largura inteira, e não
   espremido numa célula. */
.pdp-v3 .pv-step--preparo { grid-area: preparo; }
.pdp-v3 .pv-use:has(.pv-step--preparo) {
  grid-template-areas: "aplicacao embalagem" "preparo preparo" "chamada chamada";
}
.pdp-v3 .pv-dose--ask { grid-area: chamada; }
@media (max-width: 767px) {
  /* Coluna única: as três células viram três linhas, na ordem do HTML. A faixa
     larga não cabe em 390px com três colunas, então ícone e título ficam na
     primeira linha e o botão desce, ocupando a largura toda. */
  .pdp-v3 .pv-use { grid-template-columns: 1fr; grid-template-areas: "aplicacao" "embalagem" "chamada"; }
  .pdp-v3 .pv-use:has(.pv-step--preparo) { grid-template-areas: "aplicacao" "embalagem" "preparo" "chamada"; }
  .pdp-v3 .pv-dose--ask { grid-template-columns: auto 1fr; }
  .pdp-v3 .pv-dose--ask .pv-dose__cta { grid-column: 1 / -1; justify-self: stretch; justify-content: center; margin-top: var(--space-md); }
}
/* passos = cards com traçado (par do card cheio da dose). Ícone EM CIMA do
   texto — mesmo padrão do card de dose (e some com o aperto no mobile). */
.pdp-v3 .pv-step { display: flex; flex-direction: column; justify-content: center; gap: var(--space-md); flex: 1 1 auto;
  padding: clamp(var(--space-lg), 2.4vw, var(--space-xl));
  border: 1px solid color-mix(in srgb, var(--product-accent) 24%, var(--color-hairline));
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--product-accent) 4%, var(--color-surface)); }
.pdp-v3 .pv-step__i { color: var(--accent-ink); line-height: 0; }
.pdp-v3 .pv-step__i .icon { width: 28px; height: 28px; }
.pdp-v3 .pv-ben__i .icon { width: 20px; height: 20px; }
/* título do passo = MESMO estilo de "Dose recomendada" (rótulo, fonte de texto) */
.pdp-v3 .pv-step__t { margin: 0 0 6px; font-family: var(--font-text); font-weight: var(--font-weight-semibold); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--font-tracking-wide); color: var(--color-ink-muted); }
.pdp-v3 .pv-step__x { margin: 0; color: var(--color-ink); line-height: 1.6; max-width: 52ch; }

/* Benefícios — ícone + statement */
.pdp-v3 .pv-bens { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-lg); }
.pdp-v3 .pv-ben { display: grid; grid-template-columns: auto 1fr; gap: var(--space-md); align-items: center; }
.pdp-v3 .pv-ben__i { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; flex: none;
  background: color-mix(in srgb, var(--product-accent) 10%, var(--color-canvas)); color: var(--accent-ink); }
.pdp-v3 .pv-ben__t { font-size: var(--font-size-lg); line-height: 1.5; color: var(--color-ink); }

@media (min-width: 768px) {
  .pdp-v3 .pv-use { grid-template-columns: 0.9fr 1.1fr; }
  .pdp-v3 .pv-bens { grid-template-columns: 1fr 1fr; gap: var(--space-lg) var(--space-2xl); }
}

/* A embalagem no hero fica PARADA. Aqui já houve entrada subindo, balanço com
   micro-giro, sombra que respirava e parallax de scroll; tudo saiu quando a
   embalagem virou linha de tamanhos, porque o conjunto se movendo não fechava
   (gestor 2026-07-25). Este `bottom` já foi 16px para abrir folga sob a bombona
   durante o balanço: sem animação, a folga só a fazia parecer pairando, então
   desceu para zero. Seletor casa a especificidade da base para vencer o inset. */
.product--v3 .product-hero__media .product-hero__packshot { bottom: 0; z-index: 2; }
/* A bombona PARADA (gestor 2026-07-25). O balanço, a entrada subindo e o
   parallax de scroll saíram: com dois ou três tamanhos lado a lado, o conjunto
   flutuando não encaixava. A sombra de contato de cada bombona (.pack-fam__item)
   é quem ancora a cena agora, e ela é estática. */
@media (prefers-reduced-motion: no-preference) {
  /* texto do hero entra em cascata no load (eyebrow → título → chips → CTA),
     pra o hero ficar tão vivo quanto o corpo. */
  .product--v3 .product-hero__info > * { animation: hero-rise 0.7s var(--motion-ease-out) both; }
  .product--v3 .product-hero__eyebrow   { animation-delay: 0.06s; }
  .product--v3 .product-hero__name      { animation-delay: 0.14s; }
  .product--v3 .product-hero__headline  { animation-delay: 0.22s; }
  .product--v3 .product-hero__nutrients { animation-delay: 0.30s; }
  .product--v3 .product-hero__cta       { animation-delay: 0.38s; }
}
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ══════════════════════════════ FOOTER ═══════════════════════════════════ */
/* Sem margin-top (era var(--space-section), 88px de canvas vazio). Esse era o
   MAIOR vão do site e o único que aparecia nas 36 páginas: 56 da última seção
   + 88 da margem + 64 do padding interno = 208px medidos entre o último texto
   e o primeiro texto do rodapé. O rodapé é uma faixa azul, e a troca de cor já
   é o separador, exatamente como acontece entre duas seções vizinhas, que não
   ganham margem nenhuma. Sem a margem o encontro fecha em 120px. */
.site-footer { background: var(--color-brand); color: var(--color-on-brand); }
.site-footer a { color: var(--color-on-brand); }
.site-footer a:hover { color: var(--color-canvas); }
.site-footer__inner { display: grid; gap: var(--space-xl); padding-block: var(--space-2xl); }
.site-footer__logo { display: block; width: auto; height: 54px; }
.site-footer__heading { font-family: var(--font-text); font-weight: var(--font-weight-bold); font-size: var(--font-size-h3); margin-bottom: var(--space-sm); }
.site-footer__nav ul, .site-footer__links { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-sm); }
/* `padding-block: 4px` sobre a linha de 16px leva o alvo a 24 (WCAG 2.5.8):
   7 dos 13 links do rodapé mediam 16px de altura (auditoria 2026-07-30, AUD-006).
   A margem negativa devolve o espaço, então o rodapé não cresce. */
.site-footer__nav a, .site-footer__links a {
  text-decoration: none;
  display: inline-block; padding-block: 4px; margin-block: -4px;
}
.site-footer__nav a:hover, .site-footer__links a:hover { text-decoration: underline; }
.site-footer__links a { display: inline-flex; align-items: center; gap: var(--space-sm); }
.site-footer__address { font-style: normal; color: rgb(var(--color-canvas-rgb) / 0.9); margin-bottom: var(--space-md); }
/* Copyright de um lado, assinatura de quem fez do outro. Empilha no celular,
   onde `space-between` na mesma linha espremeria as duas em duas linhas cada.
   `gap` pequeno porque empilhado são duas linhas de um bloco só, não duas
   informações separadas. */
.site-footer__legal {
  padding-block: var(--space-lg);
  border-top: 1px solid rgb(var(--color-canvas-rgb) / 0.2);
  font-size: var(--font-size-sm); color: rgb(var(--color-canvas-rgb) / 0.8);
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--space-xs) var(--space-lg);
}
/* O crédito é assinatura, não chamada: fica um degrau mais apagado que o
   copyright, e o link só ganha sublinhado no hover, como o resto do rodapé.
   0.72 e não 0.65: em 0.65 o texto media 4,60:1 sobre o azul, contra o mínimo
   AA de 4,5, e passar raspando num texto de 14px não é margem. Em 0.72 sobe
   para 5,2:1 e continua lendo como secundário ao lado do copyright (6,1:1). */
.site-footer__credito { color: rgb(var(--color-canvas-rgb) / 0.72); }
/* O alvo de toque cresce de 14px para 24px (WCAG 2.5.8) sem empurrar nada: o
   padding é anulado pela margem negativa, então a linha do rodapé fica igual.
   Como o link vive dentro de uma frase, ele já cairia na exceção "inline" da
   norma; 24px é conforto, não obrigação. */
.site-footer__credito a {
  text-decoration: none;
  display: inline-block; padding-block: 5px; margin-block: -5px;
}
.site-footer__credito a:hover { text-decoration: underline; }

/* ════════════════ MATÉRIAS-PRIMAS (painel inline do Portfólio) ════════════
   A aba "Matérias-primas" do filtro troca o grid de produtos por este painel:
   insumos agrupados por tipo (Micro/Boro/Macro), calmo (menos é mais), com o
   símbolo do elemento como monograma discreto (verde). Sem página própria;
   vive dentro do Portfólio (contrato .cat-filter__mp). */
.cat-filter__mp .mp-group { margin-top: var(--space-2xl); }
.cat-filter__mp .mp-group:first-child { margin-top: 0; }
.mp-group__title {
  display: flex; align-items: baseline; gap: var(--space-sm); margin: 0;
  padding-bottom: var(--space-sm); border-bottom: 1px solid var(--color-hairline);
  font-family: var(--font-text); font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-lg); color: var(--color-ink);
}
.mp-group__title span { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--color-ink-muted); }

.mp-grid {
  list-style: none; margin: var(--space-lg) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 2px var(--space-2xl);
}
.mp-item { display: flex; align-items: center; gap: var(--space-md); padding: var(--space-sm) 0; }
.mp-item .nutrient-chip { flex: none; min-width: 40px; transition: transform var(--motion-duration-fast) var(--motion-ease-standard); }
.mp-item__name { color: var(--color-ink); line-height: 1.4; transition: color var(--motion-duration-fast) var(--motion-ease-standard); }
.mp-item:hover .nutrient-chip { transform: translateY(-2px); }
.mp-item:hover .mp-item__name { color: var(--color-brand); }

/* dinâmico: os insumos entram em cascata quando a aba abre (cat-filter.js liga
   .is-in no painel e re-dispara com reflow). --i = índice do item no grupo.
   Sem JS ou com reduce-motion: estático e visível (progressive enhancement). */
@media (prefers-reduced-motion: no-preference) {
  .cat-filter__mp.is-in .mp-item { animation: mp-item-in var(--motion-duration-base) var(--motion-ease-out) both; animation-delay: calc(var(--i, 0) * 34ms); }
}
@keyframes mp-item-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Grade do bloco de produtos, do celular para cima (2026-07-27). No celular o
   desenho é o mesmo do carrossel das PDPs, que o gestor aprovou: título e setas
   dividem a primeira linha, depois o carrossel, depois os dots. O botão de
   portfólio fica por último, com respiro próprio, em vez de colado nas setas. */
.home-port {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "cabecalho setas" "grade grade" "dots dots" "acao acao";
  column-gap: var(--space-md);
}
.home-port > .section-header { grid-area: cabecalho; }
/* `min-width: 0` e `width: auto` são o que impede o carrossel de estourar a
   grade. O `.carousel__track` nasce com `width: max-content`, que serve nas PDPs
   porque lá ele não vive dentro de grade nenhuma; aqui esse max-content vira a
   contribuição de tamanho do item e empurra a coluna `1fr` para 3.970px, jogando
   os cards e o botão para fora do container. Com `auto` + `min-width: 0` quem
   rola é o `overflow-x` do próprio track, que é o comportamento pretendido: os
   filhos já são `flex: 0 0 auto`. */
.home-port__car { grid-area: grade; width: auto; min-width: 0; }
.home-port__setas { grid-area: setas; align-self: center; }
.home-port__dots { grid-area: dots; }
/* `justify-self: start` para o botão não esticar na largura da fileira, e
   margem própria para não encostar nos dots logo acima. */
.home-port__acao { grid-area: acao; justify-self: start; margin-top: var(--space-md); }

/* ═══════════════ HOME — abertura em faixa azul e cabeçalho do portfólio ═════
   Bloco novo (2026-07-26), escopado na Home. Nada aqui reescreve regra de outra
   página: as duas primeiras declarações são a única exceção, e são ADITIVAS
   (contexto de cor que ainda não existia).

   Por que existem: `.intro__title` é `color: var(--color-brand)`, que é
   exatamente o #004a82 da faixa — sem esta regra o h1 fica azul sobre azul e
   desaparece. `.intro__text` é `--color-ink` (#26231f) e também precisa da
   versão clara. Mesmo par que a faixa já faz com `.section-header__title` e
   `.section-header__lead` (linhas 21 e 24). */
.section--brand .intro__title { color: var(--color-on-brand); }
.section--brand .intro__text { color: rgb(var(--color-canvas-rgb) / 0.85); }

/* Duas colunas na mesma proporção da abertura da Indicadores (1.15fr/0.85fr).
   `align-items: start` e não `center`: as duas colunas abrem com um `.eyebrow`
   e alinhá-las pelo topo faz os dois rótulos caírem na mesma linha. Centralizar
   desalinharia os dois, já que as colunas têm alturas diferentes. */
.home-abre__inner { display: grid; gap: var(--space-xl); align-items: start; }
/* gap curto de propósito: os dois números têm que ler como UM bloco de prova,
   não como dois cartões soltos — mesma decisão do bento do clima.
   Lado a lado em TODA largura: empilhados no celular davam duas caixas de 170px
   com o número pequeno perdido no canto, 364px para dizer dois números. */
.home-abre__nums { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); margin-top: var(--space-md); }

/* Os dois números de prova são o `.destaque` sem eyebrow, sem título e sem
   carimbo, que são slots opcionais do componente. Só o número e o rótulo.
   O `margin-top` do `__num` existe para separá-lo do título; aqui ele é o
   primeiro filho, então o espaço só empurraria o bloco para baixo. */
.home-num .destaque__num { margin-top: 0; }
/* Padding menor que o do `.destaque` na Indicadores (24px contra 40px) até 1024.
   Lá a caixa é uma só e ocupa a coluna inteira; aqui são duas lado a lado, e com
   40px de cada lado sobravam 92px úteis a 768px, contra os ~66px que "200+" mede
   na fonte display naquela largura de tela. Passava raspando. */
.home-num { padding: var(--space-lg); }

/* Portfólio: "Ver portfólio completo" sobe para a linha do título a partir de
   768. Sozinho no fim da seção ele deixava 143px de ar até a faixa CTA, no fim
   de uma seção que já tinha 173px de ar interno.
   A grade vive AQUI, no container da página, e não no `.section-header`: aquele
   componente é usado por 6 páginas e não pode virar flex por conta própria.
   No HTML o botão vem depois da grade, então no celular ele fica no fim da
   lista sem precisar de link duplicado. */
.home-port__acao { margin-top: var(--space-xl); }

@media (min-width: 768px) {
  .home-abre__inner { grid-template-columns: 1.15fr 0.85fr; }

  .home-port {
    grid-template-columns: 1fr auto auto;
    grid-template-areas: "cabecalho setas acao" "grade grade grade" "dots dots dots";
    align-items: end;
  }
  /* No desktop as setas e o botão dividem a linha do título, à direita, e os três
     assentam na mesma base. Duas armadilhas aqui, as duas medidas:
     `align-self: end` precisa ser explícito porque a regra do celular põe
     `center` nas setas, e `align-self` no item vence o `align-items` da grade.
     E a margem vai zerada nos outros lados: a regra do celular dá `margin-top`
     ao botão, que sobrava e deixava ele 18px abaixo das setas. */
  .home-port__setas,
  .home-port__acao { align-self: end; margin: 0 0 var(--space-xl); }
  .home-port__acao { justify-self: end; }
}
/* Só a partir de 1024 a coluna da direita tem largura para o padding cheio do
   `.destaque`: aí cada célula fica com 115px úteis ou mais, e "200+" mede ~108px
   na fonte display no tamanho grande. Abaixo disso o padding curto é o que
   mantém os dois lado a lado sem quebrar linha. */
@media (min-width: 1024px) {
  .home-num { padding: var(--space-xl); }
}

/* ═══════════════════ SOBRE — faixa azul da operação e a casa ═══════════════
   Bloco novo (2026-07-26), escopado na /sobre/. A página era creme do header ao
   rodapé: 4 de 4 seções com fundo transparente e nenhuma troca de faixa em
   2.241px. O ritmo agora é AZUL (abertura) → creme (a história) → AZUL (a
   operação) → creme com o cartão azul do ctaBand.

   As três primeiras regras são ADITIVAS: dão ao `.feature` o contexto claro que
   ele ainda não tinha. Ele nasce para fundo claro (título --color-ink #26231f,
   parágrafo --color-ink-muted #5f5a51, ícone --color-accent-deep #3a664f), e os
   três sobre o #004a82 da faixa reprovam contraste; o ícone simplesmente some.
   É o mesmo par que a faixa já faz com `.section-header__title` e
   `.section-header__lead` (linhas 21 e 24) e que a `.foto-band` faz na Home. */
.section--brand .feature__title { color: var(--color-on-brand); }
.section--brand .feature p { color: rgb(var(--color-canvas-rgb) / 0.85); }
.section--brand .feature .icon { color: var(--color-accent); } /* mesmo verde sobre azul do .eyebrow (~5:1) */

/* Grade explícita (1 → 2 → 4) e não `.grid--cards`: com o auto-fill de
   minmax(240px, 1fr) a grade cai para 3 colunas entre 960 e 1090px de janela e
   sobra uma célula sozinha na segunda linha — é o mesmo motivo pelo qual a
   `.home-pilares` também é explícita. Em 4 colunas o `max-width: 46ch` do
   `.feature p` deixa de morder: medido em 1440, colunas de 290px com a linha
   mais larga entre 204px e 284px, ou seja, 2% a 30% de coluna vazia, contra os
   45% a 59% que a mesma copy deixava nas colunas de 604px da `.grid--2`. */
.sobre-op__grade { grid-template-columns: 1fr; }
/* O botão fecha a faixa. Sozinho ele deixaria 40px de ar, mas aqui esse ar é
   azul, dentro da própria banda, e não creme entre seções. */
.sobre-op__acao { margin-top: var(--space-xl); }

/* Abertura em duas colunas, na mesma proporção da abertura da Home e da
   Indicadores (1.15fr/0.85fr). `align-items: start` porque as colunas têm
   alturas diferentes e o que precisa casar é o topo, onde ficam os dois
   eyebrows. A abertura antiga deixava 649px vazios à direita (53% da coluna). */
.sobre-abre__inner { display: grid; gap: var(--space-xl); align-items: start; }
/* `.intro__text` traz 16px de margem de topo para descolar do título; na coluna
   da direita o que vem antes é o eyebrow, que já tem a sua própria margem. */
.sobre-abre__texto > .intro__text:first-of-type { margin-top: var(--space-sm); }

/* Linha do tempo da história. Quatro marcos ligados por UMA linha contínua, e
   não por quatro réguas soltas: no celular ela desce pela esquerda, no desktop
   atravessa as colunas. Um por coluna a partir de 1024, dois a partir de 768.

   Como a linha atravessa o vão entre as colunas: `column-gap: 0`, e o vão vira
   `padding-right` DENTRO de cada marco. Assim o `border-top` de um marco encosta
   no do vizinho e os quatro leem como um filete só, inclusive até a borda do
   container. Com `column-gap` a régua parava na borda de cada coluna e a linha
   do tempo virava quatro traços separados, que foi o defeito apontado.

   A largura de texto de cada coluna não muda: o afastamento de 40px que era gap
   agora é padding, e some do lugar certo. */
.historia {
  list-style: none; margin: 0; padding: 0;
  display: grid; row-gap: var(--space-xl); column-gap: 0;
}
.historia__marca {
  position: relative;
  display: grid; gap: var(--space-sm); align-content: start;
  padding-left: var(--space-xl);
}
/* O ponto do marco. `z-index` porque no celular ele fica em cima do filete, que
   passa por baixo dele. */
.historia__marca::before {
  content: "";
  position: absolute; z-index: 1; left: 0; top: 6px;
  width: 12px; height: 12px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}
/* CELULAR: o filete desce pela esquerda. Cada marco desenha o trecho que vai do
   próprio ponto até o ponto do marco seguinte, e por isso a altura soma o vão da
   grade. O último não desenha: a linha sobraria para fora da lista. */
.historia__marca::after {
  content: "";
  position: absolute; left: 5px; top: 6px;
  width: 2px; height: calc(100% + var(--space-xl));
  background: var(--color-hairline);
  transform-origin: top;
}
.historia__marca:last-child::after { content: none; }

/* ── A linha do tempo se desenha (2026-07-26) ──────────────────────────────
   O ponto do marco aparece primeiro e a linha sai DELE, o que dá a leitura de
   "a história vai acontecendo". No celular ela desce, no desktop ela atravessa.
   Como os trechos se encostam, os quatro desenhando em sequência leem como UM
   filete atravessando a seção.

   O marco NÃO sobe junto com o resto do site: se cada um subisse com o seu
   atraso, os quatro trechos ficariam em alturas diferentes no meio do caminho e
   a linha pareceria quebrada. Aqui o marco só aparece; quem se move é a linha. */
.js-reveal .historia__marca[data-reveal] { transform: none; }
.js-reveal .historia__marca::before {
  transform: scale(0);
  transition: transform 320ms var(--motion-ease-out) var(--rd, 0ms);
}
.js-reveal .historia__marca.is-in::before { transform: scale(1); }
.js-reveal .historia__marca::after {
  transform: scaleY(0);
  /* sai 120ms depois do ponto: primeiro o marco existe, depois a linha parte dele */
  transition: transform 520ms var(--motion-ease-out) calc(var(--rd, 0ms) + 120ms);
}
.js-reveal .historia__marca.is-in::after { transform: scaleY(1); }
/* Mesma fonte e mesmo peso do `.stat-card__num`, um degrau menor: o ano é o
   segundo número mais forte da página e não pode competir com o "200+". */
.historia__ano {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--font-size-h2);
  line-height: 1;
  color: var(--color-brand);
}
.historia__fato { color: var(--color-ink-muted); }

/* Os dois números de prova fecham a faixa da história: são o resultado dela.
   Vinham em seção própria, uma faixa inteira de 305px de creme para dizer dois
   números. */
.sobre-prova { margin-top: var(--space-2xl); }

@media (min-width: 768px) {
  .sobre-abre__inner { grid-template-columns: 1.15fr 0.85fr; }
  .sobre-op__grade { grid-template-columns: 1fr 1fr; }

  /* DESKTOP: a mesma linha deita. É o MESMO `::after`, só que largo e baixo em
     vez de estreito e alto, e ancorado pela esquerda. Ele vai de `left: 0` a
     `right: 0` da caixa de padding do marco, ou seja, atravessa o padding-right
     que faz as vezes do vão: o trecho de um marco encosta no do vizinho e os
     quatro leem como um filete só. Não é `border-top` porque borda não anima.
     Aqui o último marco TEM linha (é o trecho da quarta coluna), ao contrário
     do celular. Em duas colunas cada fileira ganha a sua linha. */
  .historia { grid-template-columns: 1fr 1fr; }
  .historia__marca {
    padding-left: 0; padding-right: var(--space-xl); padding-top: var(--space-lg);
  }
  .historia__marca::before { top: -5px; }
  .historia__marca::after,
  .historia__marca:last-child::after {
    content: "";
    left: 0; right: 0; top: 0;
    width: auto; height: 2px;
    transform-origin: left;
  }
  .js-reveal .historia__marca::after { transform: scaleX(0); }
  .js-reveal .historia__marca.is-in::after { transform: scaleX(1); }
}
@media (min-width: 1024px) {
  .historia { grid-template-columns: repeat(4, 1fr); }
  .sobre-op__grade { grid-template-columns: repeat(4, 1fr); }
}

/* ═════════════════════════ CONTATO — abertura em faixa azul ════════════════
   Bloco novo (2026-07-26), escopado na /contato/. A página era creme do header
   ao rodapé e o h1 deixava 870px vazios à direita. O cartão de WhatsApp ocupa
   essa coluna e, no celular, sobe o botão para a primeira tela: ele ficava
   depois do formulário inteiro, a 1,12 tela de rolagem.
   Mesma proporção de coluna das aberturas da Home, da Sobre e da Indicadores. */
.contato-abre__inner { display: grid; gap: var(--space-xl); align-items: start; }
/* O cartão tem três filhos: rótulo, pergunta e botão. O `.destaque` já dá
   `gap: var(--space-xs)` entre todos, o que basta para o rótulo colar na
   pergunta que ele rotula. O botão é a AÇÃO e precisa se destacar do bloco de
   texto, então ganha margem própria. Com o número fora (2026-07-31) o ritmo
   ficou 8px entre rótulo e pergunta e 28px entre pergunta e botão: um degrau
   claro, em vez dos 8/4/28 de antes, que era o que não fechava. */
.contato-abre__acao { margin-top: var(--space-lg); }

@media (min-width: 768px) {
  .contato-abre__inner { grid-template-columns: 1.15fr 0.85fr; }
}
