/* A Archivo, servida deste domínio. Um arquivo só: é variável nos DOIS
   eixos que o site usa como recurso de desenho — largura 62 a 125 e peso
   100 a 900 — então não existem cortes separados para baixar.

   font-display: swap — o texto aparece na hora, na fonte do sistema, e
   troca quando a Archivo chega. O contrário disso é texto invisível
   esperando o download, que é justamente o que não se quer no celular.

   unicode-range fecha no latin: todo acento do português cabe aí, e assim
   o navegador nem pede a fonte se a página não tiver nada fora da faixa. */
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
                 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
                 U+FFFD;
}

/* ==========================================================================
   FIORIO — Sistema visual
   Mundo: campos cinza texturizados cortados na diagonal + ações em pílula.
   Geometria angular da referência 1, acabamento e respiro da referência 2,
   paleta amostrada do post da loja: cinza, branco e vermelho. Só isso —
   sem laranja e sem preto.
   ========================================================================== */

/* --------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------- */
:root {
  /* Marca — amostradas do post da loja. Vermelho é o ÚNICO acento:
     ele carrega tanto as ações quanto a geometria (cunhas, cantos, réguas). */
  --brand: #cf2027;
  --brand-hover: #a81920;

  /* Escala neutra — ancorada nos três cinzas do post */
  --n0: #ffffff;
  --n50: #f4f4f4;
  --n100: #e9e9e9;
  --n200: #dcdcdc;
  --n300: #d2d2d2;   /* o fundo do post */
  --n400: #b4b4b4;
  --n500: #8f8f8f;   /* o ícone do logo */
  --n600: #6e6e6e;
  --n700: #545454;
  --n800: #3c3c3c;   /* a tagline do logo */
  --n900: #262626;

  /* Papéis */
  --ground: var(--n0);
  --ground-alt: var(--n50);
  --field: var(--n300);            /* o campo cinza do post */
  --ink: var(--n800);
  --ink-2: var(--n600);
  --ink-2-on-field: var(--n700);   /* secundário sobre o cinza pede mais peso */
  --ink-on-brand: #ffffff;
  --line: var(--n200);
  --line-on-field: rgba(60, 60, 60, 0.20);

  /* Malha curva — a textura de todos os campos cinza (hero, capa de categoria,
     rodapé). Ladrilho SVG de 960×960 com dois feixes de bezier.
     Emenda sem costura porque cada curva (a) tem a MESMA tangente na entrada e
     na saída e (b) deriva um múltiplo exato do espaçamento ao atravessar o
     ladrilho — então continua na curva vizinha do ladrilho seguinte.
     Onda longa: um arco por 960px, pico ~32px. Os pontos de controle foram
     recalculados (30 e 10) porque só esticar o ladrilho aumentaria o pico junto.
     Feixe A: espaçamento 60, deriva 240.  Feixe B: espaçamento 80, deriva 320. */
  --field-mesh:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='960' height='960'%3E%3Cg fill='none' stroke='%233c3c3c' stroke-opacity='.10' stroke-width='1.1'%3E%3Cpath d='M0 -240C320 -270 640 30 960 0'/%3E%3Cpath d='M0 -180C320 -210 640 90 960 60'/%3E%3Cpath d='M0 -120C320 -150 640 150 960 120'/%3E%3Cpath d='M0 -60C320 -90 640 210 960 180'/%3E%3Cpath d='M0 0C320 -30 640 270 960 240'/%3E%3Cpath d='M0 60C320 30 640 330 960 300'/%3E%3Cpath d='M0 120C320 90 640 390 960 360'/%3E%3Cpath d='M0 180C320 150 640 450 960 420'/%3E%3Cpath d='M0 240C320 210 640 510 960 480'/%3E%3Cpath d='M0 300C320 270 640 570 960 540'/%3E%3Cpath d='M0 360C320 330 640 630 960 600'/%3E%3Cpath d='M0 420C320 390 640 690 960 660'/%3E%3Cpath d='M0 480C320 450 640 750 960 720'/%3E%3Cpath d='M0 540C320 510 640 810 960 780'/%3E%3Cpath d='M0 600C320 570 640 870 960 840'/%3E%3Cpath d='M0 660C320 630 640 930 960 900'/%3E%3Cpath d='M0 720C320 690 640 990 960 960'/%3E%3Cpath d='M0 780C320 750 640 1050 960 1020'/%3E%3Cpath d='M0 840C320 810 640 1110 960 1080'/%3E%3Cpath d='M0 900C320 870 640 1170 960 1140'/%3E%3Cpath d='M0 960C320 930 640 1230 960 1200'/%3E%3Cpath d='M-320 0C-330 320 10 640 0 960'/%3E%3Cpath d='M-240 0C-250 320 90 640 80 960'/%3E%3Cpath d='M-160 0C-170 320 170 640 160 960'/%3E%3Cpath d='M-80 0C-90 320 250 640 240 960'/%3E%3Cpath d='M0 0C-10 320 330 640 320 960'/%3E%3Cpath d='M80 0C70 320 410 640 400 960'/%3E%3Cpath d='M160 0C150 320 490 640 480 960'/%3E%3Cpath d='M240 0C230 320 570 640 560 960'/%3E%3Cpath d='M320 0C310 320 650 640 640 960'/%3E%3Cpath d='M400 0C390 320 730 640 720 960'/%3E%3Cpath d='M480 0C470 320 810 640 800 960'/%3E%3Cpath d='M560 0C550 320 890 640 880 960'/%3E%3Cpath d='M640 0C630 320 970 640 960 960'/%3E%3Cpath d='M720 0C710 320 1050 640 1040 960'/%3E%3Cpath d='M800 0C790 320 1130 640 1120 960'/%3E%3Cpath d='M880 0C870 320 1210 640 1200 960'/%3E%3Cpath d='M960 0C950 320 1290 640 1280 960'/%3E%3C/g%3E%3C/svg%3E");

  /* Espaçamento — ritmo de 8 */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --s8: 4rem;
  --s9: 6rem;
  --s10: 8rem;

  /* Layout */
  --container: 76rem;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --header-h: 5rem;
  /* altura real ocupada pelo cabeçalho, incluindo a borda inferior de 1px */
  --header-total: calc(var(--header-h) + 1px);

  /* Geometria — a diagonal é o traço da casa */
  --radius-sm: 3px;
  --radius: 6px;
  --radius-lg: 3.5rem;    /* superfícies grandes: painel de categorias */
  --radius-pill: 999px;

  /* Profundidade */
  --shadow-sm: 0 1px 2px rgba(38, 38, 38, 0.06), 0 2px 8px rgba(38, 38, 38, 0.05);
  --shadow: 0 2px 4px rgba(38, 38, 38, 0.06), 0 12px 28px rgba(38, 38, 38, 0.10);
  --shadow-lg: 0 4px 8px rgba(38, 38, 38, 0.08), 0 24px 56px rgba(38, 38, 38, 0.16);

  /* Movimento */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 260ms;
  --dur-fast: 160ms;
  /* --ease entrega ~75% do percurso nos primeiros 100ms: ótimo para cor,
     um estalo para superfície grande. Esta distribui — é o que se lê como
     deslize. Curva de gaveta do iOS. */
  --ease-desliza: cubic-bezier(0.32, 0.72, 0, 1);

  /* Tipografia */
  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --t-xs: 0.75rem;
  --t-sm: 0.875rem;
  --t-base: 1rem;
  --t-md: 1.0625rem;
  --t-lg: clamp(1.125rem, 1.02rem + 0.5vw, 1.375rem);
  --t-xl: clamp(1.5rem, 1.28rem + 1.1vw, 2.125rem);
  --t-2xl: clamp(2rem, 1.55rem + 2.2vw, 3.25rem);
  --t-3xl: clamp(2.5rem, 1.75rem + 3.4vw, 4.25rem);

  --z-header: 100;
  --z-menu: 110;
  --z-drawer: 120;
}

/* --------------------------------------------------------------
   2. Travessia entre páginas
   As 13 páginas trocavam de estalo. Isto faz a ponte na chegada, que é
   justamente onde o visitante sai da home para a categoria. Precisa ficar no
   topo da folha: @view-transition não vale aninhado.
   Navegador sem suporte ignora a regra inteira e nada muda.
   -------------------------------------------------------------- */
/* Borda com brilho girando — a técnica do componente React que o usuário
   mandou, portada para CSS puro (o original era React + Tailwind + shadcn,
   nada disso existe aqui).

   Como funciona: a borda fica TRANSPARENTE e duas camadas de fundo se
   encarregam dela. A de baixo é um cônico que cobre a caixa inteira INCLUINDO
   a borda; a de cima é a cor do painel, recortada só até o miolo. Sobra o
   cônico aparecendo no anel da borda. Girar o ângulo do cônico faz o brilho
   viajar em volta.

   O @property é obrigatório e o snippet original não o trazia: sem registrar
   o ângulo como <angle>, o navegador não sabe interpolar entre 0 e 360 e a
   animação salta em vez de girar. Quem não suporta @property mostra o
   gradiente parado — degrada para uma borda vermelha comum, que é o que
   estava lá antes.

   As cores são as duas do sistema: #a81920 no corpo e #cf2027 nos picos. Sem
   inventar um vermelho claro só para o efeito ficar mais visível.
   Dois picos, e não um: o painel fica aberto poucos segundos, então com um
   pico só haveria boa chance de nenhum passar enquanto você olha. */
@property --vm-alfa {
  syntax: '<number>';
  initial-value: 0.55;
  inherits: false;
}
@property --vm-corte {
  syntax: '<percentage>';
  initial-value: 100%;
  inherits: false;
}
@keyframes vermelho-desce {
  from { --vm-corte: -20%; }
}

@property --angulo-borda {
  syntax: '<angle>';
  initial-value: 0deg;
  /* precisa herdar: o ::after do brilho le o mesmo ângulo do pai */
  inherits: true;
}
@keyframes girar-borda {
  to { --angulo-borda: 360deg; }
}

@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 220ms; }

/* --------------------------------------------------------------
   3. Base
   -------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s5));
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.65;
  font-variation-settings: 'wdth' 100, 'wght' 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }

button {
  font: inherit;
  font-variation-settings: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

h1, h2, h3, h4 {
  margin: 0;
  font-variation-settings: 'wdth' 112, 'wght' 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
ul { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--brand); color: var(--ink-on-brand); }

/* --------------------------------------------------------------
   4. Utilitários de layout
   -------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(var(--s8), 9vw, var(--s10)); }
.section--alt { background: var(--ground-alt); }


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

.skip-link {
  position: absolute;
  top: var(--s3); left: var(--s3);
  z-index: 999;
  padding: var(--s3) var(--s5);
  background: var(--brand);
  color: var(--ink-on-brand);
  font-weight: 600;
  border-radius: var(--radius-pill);
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

/* --------------------------------------------------------------
   5. Tipografia de sistema
   -------------------------------------------------------------- */
.h2 { font-size: var(--t-xl); }

/* Etiqueta técnica — o "carimbo de especificação" do mundo.
   Sem régua vermelha à esquerda: o traço curto antes de uma etiqueta em caixa
   alta é maneirismo genérico e não carregava informação nenhuma. O que
   distingue a etiqueta é o tipo — semicondensado, entreletra aberta. */
.label {
  display: inline-block;
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}

.lede {
  font-size: var(--t-lg);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 46ch;
}

.measure { max-width: 68ch; }

/* --------------------------------------------------------------
   6. Botões — pílula (referência 2) sobre painéis angulares
   -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  min-height: 3.25rem;
  padding: 0 var(--s6);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--t-base);
  font-variation-settings: 'wdth' 100, 'wght' 620;
  letter-spacing: -0.01em;
  cursor: pointer;
  white-space: nowrap;
  text-align: center;
  transition:
    background-color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease),
    /* so o .wa-float usa translate; inerte nos demais botoes */
    translate var(--dur) var(--ease);
}
.btn .ico { width: 1.25rem; height: 1.25rem; flex: none; }

.btn--primary {
  background: var(--brand);
  color: var(--ink-on-brand);
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.10), 0 8px 20px rgba(207, 32, 39, 0.24);
}
.btn--primary:hover { background: var(--brand-hover); }


.btn--outline { border-color: var(--n500); color: var(--ink); }
.btn--outline:hover { border-color: var(--brand); background: var(--brand); color: var(--ink-on-brand); }

.btn--ghost-brand {
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--ink-on-brand);
}
.btn--ghost-brand:hover { border-color: #fff; background: rgba(255, 255, 255, 0.10); }

.btn--sm { min-height: 2.75rem; padding: 0 var(--s5); font-size: var(--t-sm); }
.btn:active { transform: translateY(1px); }

/* Retorno ao toque para os alvos que NÃO são .btn. O movimento de hover está
   atrás de @media (hover: hover), então no celular estes elementos — que são a
   navegação principal do site — não devolviam absolutamente nada ao toque.
   Sutil e rápido de propósito: são dezenas de toques por sessão. Não vai atrás
   de gate de ponteiro, porque aqui o alvo é justamente o toque. */
.gal__item:active,
.rail__link:active,
.footer__chip:active,
.megamenu__item:active,
.drawer__link:active { transform: scale(0.97); }
.btn[aria-disabled='true'] { opacity: 0.45; pointer-events: none; }

/* Link com seta — ação secundária recorrente */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 2.75rem;
  font-variation-settings: 'wdth' 100, 'wght' 620;
  color: var(--brand);
}
.arrow-link .ico { width: 1.15rem; height: 1.15rem; transition: transform var(--dur-fast) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .arrow-link:hover .ico { transform: translateX(4px); }
}

/* --------------------------------------------------------------
   7. Ícones
   -------------------------------------------------------------- */
.ico-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico {
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  color: currentColor;
}


/* ---- A chegada do cabeçalho ----

   Só na CHEGADA AO SITE, nunca na navegação interna. Com a travessia entre
   páginas ligada, animar a cada carregamento faria a barra descer de novo a
   cada categoria clicada — o elemento que deveria ser o ponto fixo virando o
   que mais se mexe, e a navegação parecendo lenta.
   Quem decide é a classe .chegada, posta pelo script do <head> conforme a
   origem da visita. Sem armazenar nada: a política de privacidade afirma que
   o site não usa armazenamento no navegador, e isso tem de continuar verdade.

   A barra desliza inteira e o conteúdo vem junto — mas invisível, porque cada
   peça só acende no atraso dela. O resultado é a barra vazia chegando primeiro
   e se preenchendo depois, sem precisar separar o fundo numa camada própria.

   Ordem: barra, logo, e daí para a direita. Último pousa em ~810ms — é
   entrada de página, não gesto de interface, então cabe passar dos 300ms.

   fill `backwards` outra vez: segura o primeiro quadro durante o atraso e
   solta no fim. Com `forwards` o transform ficaria travado e mataria o
   scale(0.97) do :active da logo. */
@keyframes barra-desce {
  from { transform: translateY(-100%); }
}
@keyframes peca-do-cabecalho {
  from { opacity: 0; transform: translateY(-0.5rem); }
}

.chegada .site-header {
  animation: barra-desce 480ms var(--ease-desliza) backwards;
}
.chegada .site-header .brand,
.chegada .nav__link,
.chegada .header__cta,
.chegada .burger {
  animation: peca-do-cabecalho 340ms var(--ease) backwards;
}

.chegada .site-header .brand      { animation-delay: 220ms; }
.chegada .nav__link:nth-child(1)  { animation-delay: 290ms; }
.chegada .nav__link:nth-child(2)  { animation-delay: 350ms; }
.chegada .nav__link:nth-child(3)  { animation-delay: 410ms; }
.chegada .header__cta             { animation-delay: 470ms; }
/* no celular a fileira não existe: a sequência é barra, logo, menu */
.chegada .burger                  { animation-delay: 290ms; }


/* ---- A chegada do hero ----

   Três tempos: a foto sozinha, o painel entrando, o texto depois.

   1. A FOTO INTEIRA. O painel começa deslocado toda a largura para a esquerda,
      então nos primeiros 260ms o hero é só a fotografia — que já assenta de
      scale(1.04) por conta própria.

   2. O PAINEL ENTRA. Ele desliza para o lugar, e o detalhe é qual borda vem na
      frente: deslocado para a esquerda, o pedaço que aparece primeiro é o
      LADO DIREITO dele — justamente onde a máscara dissolve. Ou seja, a borda
      macia lidera e o cinza sólido chega atrás. Não precisei tocar nos valores
      da máscara nem do degradê vermelho, que são os seus, aprovados: eles
      viajam junto com o painel.

   3. O TEXTO. Entra quando o painel está terminando, não depois de parado —
      lê como sequência e poupa uns 200ms até a manchete aparecer. Reaproveita
      a revelação que o hero já tem (título, texto, botões nesta ordem); só
      acrescenta a espera.

   Tudo isto vale só no desktop: abaixo de 860px o painel não existe, a foto
   fica embaixo do texto, e a entrada continua a normal. */
@keyframes painel-do-hero-entra {
  from { transform: translateX(-100%); }
}

@keyframes capa-desce { from { transform: translateY(-100%); } }

/* A capa da categoria chega como o hero da home: a foto sozinha, o cinza
   entrando, o texto depois. Vale só na CHEGADA AO SITE — quem vem clicando
   da home já está navegando por dentro, e repetir o deslize a cada uma das
   11 categorias viraria pedágio. Página de categoria é justamente a que
   recebe busca do Google, então não é regra morta. */
.chegada .cat-hero__panel {
  animation: capa-desce 700ms var(--ease-desliza) 240ms backwards;
}
.chegada .cat-hero [data-reveal] {
  transition-delay: calc(var(--reveal-delay, 0ms) + 760ms);
}
@media (min-width: 861px) {
  /* no desktop o cinza dissolve na horizontal, então ele entra pelo lado */
  .chegada .cat-hero__panel {
    animation-name: painel-do-hero-entra;
  }
}

@media (min-width: 861px) {
  .chegada .hero__panel {
    /* o cinza desliza primeiro; o vermelho só acende quando ele chega
       (260 + 760 = 1020ms), acompanhando a máscara que já está no lugar */
    animation: painel-do-hero-entra 760ms var(--ease-desliza) 260ms backwards;
  }
  /* Curva que DISTRIBUI o percurso, e não a --ease-desliza do painel: uma
     borda que atravessa a tela inteira precisa ser vista viajando, e aquela
     entrega quase tudo no começo. */
  .chegada .hero__panel::before {
    animation: vermelho-desce 700ms cubic-bezier(0.4, 0, 0.2, 1) 1020ms backwards;
  }
  /* a espera some sozinha na navegação interna, porque .chegada não existe lá */
  .chegada .hero [data-reveal] {
    transition-delay: calc(var(--reveal-delay, 0ms) + 820ms);
  }
}

/* --------------------------------------------------------------
   8. Cabeçalho
   -------------------------------------------------------------- */
.site-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-header);
  background: var(--ground);
  border-bottom: 1px solid var(--line);
  transition: box-shadow var(--dur) var(--ease);
}
.site-header[data-scrolled='true'] { box-shadow: var(--shadow-sm); }

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s5);
  min-height: var(--header-h);
}

.brand { display: flex; align-items: center; min-height: 2.75rem; margin-right: auto;
        transition: transform var(--dur-fast) var(--ease); }
/* A logo é UMA imagem. Altura fixa, largura automática: a proporção (2,826:1)
   vem do arquivo, não de número chutado aqui. Se um dia voltar a ser montada
   de pedaços, a assinatura era texto em Archivo wdth 90 / wght 600 a 0.6rem e
   a palavra era wdth 108 / wght 800 a 1.4rem — mas montar de pedaços foi
   exatamente o erro que esta versão desfaz. */
.brand__full { height: 3.75rem; width: auto; display: block; }
/* No rodapé sobra espaço: a logo entra maior, e aí a assinatura fica legível
   de verdade em vez de sugerida. */
.site-footer .brand__full { height: 4.25rem; }

.nav { display: flex; align-items: center; gap: var(--s2); }
.nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 2.75rem;
  padding: 0 var(--s4);
  border-radius: var(--radius-pill);
  font-size: var(--t-sm);
  font-variation-settings: 'wdth' 100, 'wght' 600;
  color: var(--n700);
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.nav__link:hover { color: var(--ink); background: var(--n100); }
.nav__link[aria-expanded='true'] { color: var(--ink); background: var(--n100); }
.nav__link .ico { width: 1rem; height: 1rem; transition: transform var(--dur-fast) var(--ease); }
.nav__link[aria-expanded='true'] .ico { transform: rotate(180deg); }

.header__cta { margin-left: var(--s2); }

.burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.75rem; height: 2.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: none;
  color: var(--ink);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}
.burger:active { transform: scale(0.97); }

/* Painel de categorias — 11 destinos a um clique de qualquer página */
/* O painel se desdobra da barra e o conteúdo DESLIZA de trás dela.

   Duas camadas, de propósito:
   1. o painel abre com `clip-path` cortado rente à borda inferior do
      cabeçalho — é o que torna legível que ele pertence à barra;
   2. o conteúdo entra transladado para cima e desce até o lugar. Com
      `overflow: hidden` na caixa, ele sai literalmente de trás da borda.
   Só o recorte, sem o segundo, revela no lugar em vez de deslizar.

   A curva NÃO é o --ease do site aqui. Aquela entrega ~75% do movimento nos
   primeiros 100ms: perfeita para cor, mas transforma qualquer superfície
   grande num estalo. Esta distribui o percurso, que é o que se percebe como
   deslize. É a curva de gaveta do iOS.

   Os -3rem nos três lados não são folga estética: clip-path corta a sombra
   junto, e sem eles o box-shadow sumiria mesmo com o painel aberto.

   A saída continua mais rápida que a entrada — quem fecha já decidiu. */
.megamenu {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  z-index: var(--z-menu);
  background-color: var(--n100);
  background-image:
    linear-gradient(var(--n100), var(--n100)),
    conic-gradient(from var(--angulo-borda),
      var(--brand-hover)   0%,
      var(--brand)        12%,
      var(--brand-hover)  25%,
      var(--brand-hover)  50%,
      var(--brand)        62%,
      var(--brand-hover)  75%,
      var(--brand-hover) 100%);
  background-clip: padding-box, border-box;
  background-origin: padding-box, border-box;
  /* 2px e nao 1: a 1px o brilho girando praticamente nao se ve */
  border: 2px solid transparent;
  border-top: 0;
  /* halo por fora e brilho por dentro; os dois seguem o border-radius
     sozinhos, entao abraçam as pontas de 56px sem trabalho extra. O alcance
     teto e 48px: acima disso o clip-path do painel corta. */
  box-shadow:
    var(--shadow),
    0 0 0.75rem rgba(207, 32, 39, 0.20),
    0 0 2rem rgba(207, 32, 39, 0.22),
    inset 0 0 1.25rem rgba(207, 32, 39, 0.16);
  /* pontas de baixo arredondadas; em cima fica reto porque encosta na barra */
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  clip-path: inset(0 -3rem 100% -3rem);
  transition:
    clip-path 420ms var(--ease-desliza),
    opacity 80ms var(--ease) 340ms,
    visibility 420ms;
}

.megamenu[data-open='true'] {
  opacity: 1;
  visibility: visible;
  clip-path: inset(0 -3rem -3rem -3rem);
  animation: girar-borda 6s linear infinite;
  transition:
    clip-path 500ms var(--ease-desliza),
    opacity 200ms var(--ease),
    visibility 500ms;
}

/* o conteúdo que desce de trás da barra */
.megamenu__grid { transform: translateY(-1.5rem); transition: transform 420ms var(--ease-desliza); }
.megamenu[data-open='true'] .megamenu__grid { transform: none; transition: transform 500ms var(--ease-desliza); }

/* A logo é link para a home em todas as 13 páginas e era o único elemento
   clicável do site sem retorno ao toque. */
.brand:active { transform: scale(0.97); }

.megamenu__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s1) var(--s5);
  padding-block: var(--s6);
}
.megamenu__item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--radius);
  color: var(--n700);
  font-size: var(--t-sm);
  font-variation-settings: 'wdth' 100, 'wght' 550;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.megamenu__item:hover { background: var(--ground); color: var(--ink); }
.megamenu__item .ico { width: 1.25rem; height: 1.25rem; color: var(--brand); }

/* ---- A cascata das categorias, nos DOIS sentidos ----

   Estas regras são TRANSIÇÃO e não keyframes, e a diferença é o motivo de
   existirem assim: um @keyframes preso a [data-open=true] não roda na saída.
   No instante em que o atributo cai, a regra deixa de casar e o item some no
   ato — era exatamente por isso que a volta não tinha animação.

   ENTRADA: as três colunas descem juntas, cada uma por conta própria. O atraso
   vem de --i (a linha), então dois itens na mesma linha partem no mesmo
   instante. Passo de 80ms sobre 4 linhas ocupa 240ms dos 500ms do deslize.

   SAÍDA: a ordem inverte. O fundo se recolhe de baixo para cima, então quem
   apaga primeiro é a última linha — o atraso vem de --o, a linha contada de
   baixo. Passo de 60ms: a última linha some em 200ms e a primeira em 380ms,
   dentro dos 420ms que o painel leva subindo.

   CUIDADO ao mexer: as duas listas de transição repetem background-color,
   color e transform de propósito. Declarar transição num seletor mais
   específico SUBSTITUI a lista inteira do seletor base — omitir qualquer uma
   delas aqui mataria o hover de cor ou o scale(0.97) do :active. Já aconteceu
   neste projeto, com a expansão da galeria.

   E o atraso é POR PROPRIEDADE, nunca no atalho: um transition-delay geral
   atrasaria também o hover e o toque, e a navegação ficaria pastosa. */
.megamenu__item {
  opacity: 0;
  transition:
    background-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    opacity 200ms var(--ease) calc(var(--o, 0) * 60ms);
}
.megamenu[data-open='true'] .megamenu__item {
  opacity: 1;
  transition:
    background-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    opacity 280ms var(--ease) calc(40ms + var(--i, 0) * 80ms);
}

/* O ícone se recolhe encolhendo, no mesmo compasso do item que o carrega.
   Sem opacidade própria: ela já vem do item, e repetir daria fade duplo. */
.megamenu__item .ico {
  transform: scale(0.75);
  transition: transform 220ms var(--ease-desliza) calc(var(--o, 0) * 60ms);
}
.megamenu[data-open='true'] .megamenu__item .ico {
  transform: none;
  transition: transform 320ms var(--ease-desliza) calc(40ms + var(--i, 0) * 80ms);
}


/* Gaveta mobile */
.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--ground);
  overflow-y: auto;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--dur) var(--ease), visibility var(--dur);
}
.drawer[data-open='true'] { transform: translateX(0); visibility: visible; }
.drawer__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h);
  padding-inline: var(--gutter);
  border-bottom: 1px solid var(--line);
}
.drawer__body { padding: var(--s6) var(--gutter) var(--s8); }
.drawer__link {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding-block: var(--s4);
  border-bottom: 1px solid var(--line);
  font-size: var(--t-md);
  font-variation-settings: 'wdth' 100, 'wght' 600;
  transition: transform var(--dur-fast) var(--ease);
}
.drawer__link .ico { width: 1.25rem; height: 1.25rem; color: var(--brand); }

/* --------------------------------------------------------------
   9. Hero — o corte diagonal
   -------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  background: var(--field);
  color: var(--ink);
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
/* foto e hachura empilhadas no mesmo lugar; a hachura é o fallback */
.hero__media > .ph,
.hero__foto { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__foto { object-fit: cover; }
/* A foto assenta na abertura: 1200ms com a curva do site, que entrega a maior
   parte do movimento no começo e depois só encosta no lugar. Não é para ser
   percebida como animação — é a página respirando ao abrir.
   Não toca no degradê nem na máscara do .hero__panel, que são outra camada.
   Sem gate .js: a animação se completa sozinha e não esconde conteúdo nenhum,
   então não há estado em que uma falha de script deixe a foto invisível. */
@keyframes hero-assenta { from { transform: scale(1.04); } }
.hero__foto { animation: hero-assenta 1200ms var(--ease); }

/* selo de provisório — trava para a foto de exemplo não ir ao ar sem querer */
.hero__selo {
  position: absolute;
  right: var(--s5);
  bottom: var(--s5);
  z-index: 2;
  padding: var(--s2) var(--s4);
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: var(--shadow-sm);
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* O campo cinza dissolvendo na foto.
   Não há aresta nem cunha: o vermelho é uma CAMADA do próprio campo, por isso
   ele se mistura ao cinza e some junto com a malha. Uma máscara só apaga cor,
   vermelho e malha ao mesmo tempo — se o fade fosse feito no background, a
   malha continuaria aparecendo por cima da imagem.

   DOIS DEFEITOS QUE ESTAVAM AQUI:

   1. O vermelho morria antes do cinza — sobrava uma faixa de cinza puro no
      fim. Fazer os dois zerarem no mesmo ponto NÃO resolve: o vermelho é uma
      camada DENTRO do painel, então o que se vê é o produto dele pela máscara,
      e um produto de duas curvas que caem morre antes de cada uma delas.
      A correção é o vermelho NÃO voltar a zero: ele sobe até 0,42 e fica. Quem
      apaga os dois é a máscara, e aí o vermelho é sempre 42% do cinza que
      houver — os dois somem na mesma curva, por construção.

   2. Uma linha visível cortando. As duas eram degradês de três paradas, e num
      degradê linear cada parada é uma quebra brusca de inclinação — o olho lê
      como borda (banda de Mach). As paradas intermediárias abaixo dão forma de
      sino à faixa e queda em S à máscara, sem quebra em lugar nenhum.

   O QUE NÃO MUDOU, de propósito: a máscara continua 100% opaca até 37%. A
   coluna de texto termina em ~36% da largura, então mover esse ponto para a
   esquerda tiraria contraste de trás do fim do título. O ângulo de 105° e o
   pico do vermelho em ~52% também ficam onde estavam. */
.hero__panel {
  --mask-ini: 37%;   /* até aqui o cinza é sólido, e o texto depende disso */
  --mask-fim: 70%;   /* daqui em diante é só foto — vermelho acaba junto */

  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--field);
  background-image: var(--field-mesh);
  -webkit-mask-image: linear-gradient(105deg,
      #000                    var(--mask-ini),
      rgba(0, 0, 0, 0.97)     42%,
      rgba(0, 0, 0, 0.82)     48%,
      rgba(0, 0, 0, 0.55)     54%,
      rgba(0, 0, 0, 0.28)     60%,
      rgba(0, 0, 0, 0.08)     65%,
      transparent             var(--mask-fim));
          mask-image: linear-gradient(105deg,
      #000                    var(--mask-ini),
      rgba(0, 0, 0, 0.97)     42%,
      rgba(0, 0, 0, 0.82)     48%,
      rgba(0, 0, 0, 0.55)     54%,
      rgba(0, 0, 0, 0.28)     60%,
      rgba(0, 0, 0, 0.08)     65%,
      transparent             var(--mask-fim));
}

/* A faixa vermelha, agora em camada própria.

   Ela saiu do background-image do painel porque precisa de uma máscara SÓ
   DELA: a descida é vertical, e a do painel é a diagonal de 105° que dissolve
   o cinza na foto. Duas máscaras, dois elementos.

   A máscara do painel continua valendo aqui — máscara de pai vale para o
   pseudo-elemento também —, então o vermelho continua sumindo junto com o
   cinza e com a malha, que era a razão de ele viver dentro do painel.

   Efeito colateral honesto: a malha era a primeira camada de fundo, ou seja
   ficava POR CIMA do vermelho. Agora o vermelho é um elemento e fica por cima
   dela. As linhas ganham um tom avermelhado em vez de cruzarem por cima. */
/* >>> TESTE — faixa vermelha desligada. Apagar a linha display:none
   abaixo (e este comentário) para devolver. <<< */
.hero__panel::before {
  display: none;
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(105deg,
      rgba(207, 32, 39, 0) 40%,
      rgba(207, 32, 39, calc(var(--vm-alfa) * 0.36)) 46%,
      rgba(207, 32, 39, calc(var(--vm-alfa) * 0.81)) 50%,
      rgba(207, 32, 39, var(--vm-alfa)) 54%,
      rgba(207, 32, 39, var(--vm-alfa)) var(--mask-fim));
  /* A descida. A borda tem 20% de altura de esfumaçado: um corte duro
     apareceria como uma linha atravessando a faixa. */
  -webkit-mask-image: linear-gradient(180deg,
      #000 var(--vm-corte), transparent calc(var(--vm-corte) + 20%));
          mask-image: linear-gradient(180deg,
      #000 var(--vm-corte), transparent calc(var(--vm-corte) + 20%));
}

.hero__inner {
  position: relative;
  display: grid;
  align-items: center;
  /* uma tela cheia, sem sobra: formato deitado, não quadrado */
  min-height: 100dvh;
  /* o cabeçalho flutua por cima: o vão dele entra como recuo, para o
     conteúdo não ficar embaixo da barra */
  padding-top: calc(var(--header-total) + clamp(var(--s6), 5vw, var(--s8)));
  padding-bottom: clamp(var(--s6), 5vw, var(--s8));
}
/* fica dentro da parte reta do painel, longe da costura diagonal */
.hero__content { max-width: 26rem; }
.hero__content > * + * { margin-top: var(--s5); }
/* o título é o monumento: mais ar embaixo dele do que entre o resto */
.hero__title + * { margin-top: var(--s6); }

/* O título do hero era MENOR que os títulos de seção (48px contra 52px) — o tipo
   mais importante do site estava abaixo dos vizinhos na hierarquia. Aqui ele
   assume a escala que lhe cabe SEM alargar a coluna: o eixo de largura do
   Archivo cai de 112 para 88 (o mesmo das etiquetas do sistema), o que deixa a
   letra ~22% mais estreita e libera altura. A coluna segue em 26rem e o
   degradê não é tocado. */
.hero__title {
  font-size: clamp(2.5rem, 1.5rem + 3.6vw, 3.875rem);
  font-variation-settings: 'wdth' 88, 'wght' 800;
  letter-spacing: -0.035em;
}
/* a linha vermelha ganha o peso máximo do eixo: é o momento em que a marca
   fala no volume do material do cliente, e o único acento da paleta */
.hero__title em {
  font-style: normal;
  font-variation-settings: 'wdth' 88, 'wght' 900;
  color: var(--brand);
}
.hero__text { font-size: var(--t-md); line-height: 1.55; color: var(--ink-2-on-field); max-width: 32ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
/* coluna estreita: aperta o padding para os dois botões caberem lado a lado */
.hero__actions .btn { padding-inline: var(--s5); }

/* --------------------------------------------------------------
   10. Categorias — o coração do site
   -------------------------------------------------------------- */
.sec-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s6);
  margin-bottom: var(--s7);
  flex-wrap: wrap;
}
/* O título da seção do coração do site. Era a ÚNICA headline da página sem
   font-variation-settings: renderizava na largura e peso padrão enquanto o
   hero e a seção "A loja" usam wdth 88 / wght 800. Ou seja, a seção mais
   importante tinha optado por não usar o gesto mais forte do próprio sistema.
   Aqui ela assume a mesma voz — e passa à frente em escala, porque a galeria
   de categorias é o que o visitante veio ver. */
.sec-head__title {
  font-size: clamp(2.5rem, 1.6rem + 3.4vw, 4rem);
  font-variation-settings: 'wdth' 88, 'wght' 800;
  letter-spacing: -0.038em;
  line-height: 1.02;
  max-width: 15ch;
}
/* "a obra inteira" é a promessa da seção — a loja cobre a obra do começo ao
   fim. Mesmo device do .split__titulo: peso máximo e o vermelho da casa. */
.sec-head__title em {
  font-style: normal;
  font-variation-settings: 'wdth' 88, 'wght' 900;
  color: var(--brand);
}
.sec-head > * + * { margin-top: 0; }
.sec-head__side { max-width: 32ch; color: var(--ink-2); font-size: var(--t-base); }

/* A galeria: duas fileiras, 6 em cima e 5 embaixo. O item apontado cresce e
   revela o resto da foto — que tem largura FIXA e não reescala. */
.gal {
  display: flex;
  gap: var(--s2);
  width: 100%;
  height: 17rem;

  /* Largura da foto = a do item já expandido, pela matemática do flex:
     linha = min(76rem, 100vw) − 2 × gutter; expandido = linha − 6 itens
     fechados (5rem) − 6 vãos (0,5rem) = linha − 33rem.
     Erra alguns px para MAIS de propósito: foto mais larga só esconde uma
     faixa; mais estreita deixaria buraco na borda. */
  --foto-w: calc(min(76rem, 100vw) - 2 * clamp(1.25rem, 4vw, 3rem) - 33rem);

  /* O --ease do site entrega 75% do movimento nos primeiros 104ms: ótimo para
     hover de cor, tranco para morfose de tamanho. Esta curva distribui. */
  --ease-morph: cubic-bezier(0.4, 0, 0.2, 1);
}
.gal + .gal { margin-top: var(--s2); }

/* Os dois grupos existem para quebrar 11 opções iguais num ponto de decisão só.
   O rótulo é um cabeçalho de verdade (h3), não uma etiqueta: a seção já abre
   com uma, e uma terceira no mesmo campo viraria repetição. */
.gal-grupo + .gal-grupo { margin-top: var(--s6); }
/* Os dois rótulos são um PONTO DE DECISÃO — dizem ao visitante qual metade
   das 11 categorias olhar —, mas vinham em 1,0625rem / wght 650, praticamente
   texto corrido. Aqui viram divisor: semicondensado e pesado, na mesma voz do
   resto, num degrau claramente abaixo do título da seção e acima do nome do
   ladrilho. Mais ar embaixo (s4) mantendo o s6 acima: cabeçalho respira mais
   por cima do que por baixo. */
.gal-grupo__titulo {
  font-size: clamp(1.25rem, 1.05rem + 0.85vw, 1.75rem);
  font-variation-settings: 'wdth' 88, 'wght' 800;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin-bottom: var(--s4);
}


.gal__item {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--n300);
  min-width: 5rem;
  flex: 1 1 0;
  transition: flex-grow 500ms var(--ease-morph), transform var(--dur-fast) var(--ease);
}
/* Os outros cedem sozinhos, porque continuam em 1. NÃO reintroduzir uma regra
   ".gal:hover .gal__item { flex-grow: 1 }": ela também casa com o item sob o
   mouse e, com especificidade maior (0,3,0 contra 0,2,0), anula a expansão. */
.gal__item:hover,
.gal__item:focus-visible { flex-grow: 8; }

/* O <picture> não pode gerar caixa: a foto dentro dele é posicionada contra o
   .gal__item, e um wrapper inline no meio criaria uma linha de texto vazia. */
.gal__item picture { display: contents; }
.gal__foto {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--foto-w);
  /* o reset global do site é "img { max-width: 100% }" — sem anular isto, a
     foto nunca ultrapassa a janela e a largura fixa acima não tem efeito */
  max-width: none;
  height: 100%;
  margin-left: calc(var(--foto-w) / -2);
  object-fit: cover;
}

/* véu para a legenda ter contraste sobre qualquer foto */
.gal__item::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(38, 38, 38, 0) 40%,
    rgba(38, 38, 38, .78) 100%);
}

.gal__legenda {
  position: absolute;
  z-index: 1;
  /* recuo de 12 e nao 16: sao 8px a mais de caixa, e 'Impermeabilizantes'
     estourava por 7. */
  left: var(--s3); right: var(--s3); bottom: var(--s4);
}
.gal__nome {
  display: block;
  color: #fff;
  font-size: var(--t-base);
  font-variation-settings: 'wdth' 80, 'wght' 700;
  letter-spacing: -0.01em;
  line-height: 1.1;
  text-wrap: balance;
  /* "Impermeabilizantes" e palavra unica: nao tem espaco onde quebrar, entao
     estourava a caixa e o corte do ladrilho fatiava no meio. Aqui o navegador
     parte com hifen seguindo as regras do portugues — a pagina declara
     lang="pt-BR", entao ele sabe onde pode. So age quando nao cabe: os nomes
     que quebram em espaco continuam quebrando em espaco. */
  -webkit-hyphens: auto;
          hyphens: auto;
  /* hyphens depende do dicionario do idioma, que nem todo navegador traz.
     Isto garante que nada vaze mesmo sem ele; onde a hifenizacao funciona,
     ela ganha e a quebra sai com hifen. */
  overflow-wrap: break-word;
}

/* O resumo só cabe depois que o item abre. Fechado tem altura zero, então não
   reserva espaço nenhum; ao abrir, a legenda cresce para cima (está ancorada
   embaixo) e o nome sobe junto, lendo como um bloco só. O atraso de 200ms
   deixa a janela abrir antes do texto entrar — sem ele o resumo aparece
   enquanto ainda não há largura para lê-lo. */
.gal__resumo {
  display: block;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  font-size: var(--t-sm);
  font-variation-settings: 'wdth' 100, 'wght' 400;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.9);
  transition:
    opacity 240ms var(--ease-morph) 200ms,
    max-height 320ms var(--ease-morph) 200ms;
}
.gal__item:hover .gal__resumo,
.gal__item:focus-visible .gal__resumo {
  max-height: 7rem;
  opacity: 1;
  margin-top: var(--s2);
}

/* Quando um ladrilho abre, os outros encolhem para 5rem. Sobram 51px de
   largura útil e nenhum nome cabe ali — o texto reflowava e o corte do
   ladrilho fatiava a palavra no meio.

   Antes eu fazia as legendas dos outros SUMIREM. Aqui elas continuam legíveis:
   viram VERTICAIS, que é a única orientação em que cabem numa coluna estreita.
   Medido: o nome mais longo do site ("Utilitários domésticos") ocupa 183px, e
   a altura útil do ladrilho é 240px.

   O gatilho é :has(.gal__item:hover), e não .gal:hover, de propósito: com
   .gal:hover, parar o mouse no vão de 8px entre dois ladrilhos giraria TODAS
   as legendas, porque a fileira está sob o mouse mas nenhum ladrilho está.
   Navegador sem :has ignora e fica como estava — texto cortado, nada quebrado.

   O :not() é essencial. Sem ele a regra casaria também com o ladrilho apontado
   e giraria justamente a legenda que interessa — a mesma armadilha de
   especificidade que já matou a expansão desta galeria uma vez.

   O par writing-mode + rotate(180deg) é o que faz o texto subir em vez de
   descer, que é a convenção para rótulo vertical em alfabeto latino. */
@media (hover: hover) and (pointer: fine) {
  .gal:has(.gal__item:hover) .gal__item:not(:hover) .gal__legenda,
  .gal:has(.gal__item:focus-visible) .gal__item:not(:focus-visible) .gal__legenda {
    right: auto;
    writing-mode: vertical-rl;
    rotate: 180deg;
    white-space: nowrap;
    max-height: calc(100% - 2 * var(--s4));
  }
  /* writing-mode não interpola: a virada é instantânea por natureza. O que
     dá para amaciar é a CHEGADA na nova orientação — assim não se vê o
     estalo, só a legenda assentando já na vertical.
     A volta ao horizontal fica sem animação de propósito: ela acontece com o
     ladrilho alargando, e nesse movimento todo o estalo não aparece. */
  @keyframes legenda-vira { from { opacity: 0; } }
  .gal:has(.gal__item:hover) .gal__item:not(:hover) .gal__legenda,
  .gal:has(.gal__item:focus-visible) .gal__item:not(:focus-visible) .gal__legenda {
    animation: legenda-vira 200ms var(--ease) backwards;
  }
  /* a régua vermelha e o resumo saem: na coluna estreita viram ruído */
  .gal:has(.gal__item:hover) .gal__item:not(:hover) .gal__nome::before,
  .gal:has(.gal__item:focus-visible) .gal__item:not(:focus-visible) .gal__nome::before,
  .gal:has(.gal__item:hover) .gal__item:not(:hover) .gal__resumo,
  .gal:has(.gal__item:focus-visible) .gal__item:not(:focus-visible) .gal__resumo {
    display: none;
  }
}

/* a régua vermelha: mesma marca da etiqueta .label do sistema */
.gal__nome::before {
  content: '';
  display: block;
  width: 1.5rem; height: 3px;
  margin-bottom: var(--s2);
  background: var(--brand);
}

/* --------------------------------------------------------------
   11. Sobre — texto + imagem com bloco angular
   -------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(var(--s6), 6vw, var(--s9));
  align-items: center;
}
.split__body > * + * { margin-top: var(--s5); }

/* Esta seção estava usando o .h1 genérico: 52px em wdth 112, mais larga e
   MENOR que o hero, sem vermelho nenhum. Ou seja, tinha se retirado do gesto
   mais forte do próprio sistema. Aqui ela assume a mesma voz do hero — eixo
   de largura em 88 e o fato concreto em vermelho — sem ultrapassar os 62px
   dele, que continua sendo o topo da hierarquia.
   Teto medido na coluna de 517px: 77px. 58 deixa folga. */
.split__titulo {
  font-size: clamp(2.25rem, 1.4rem + 3vw, 3.625rem);
  font-variation-settings: 'wdth' 88, 'wght' 800;
  letter-spacing: -0.035em;
}
/* os 30 anos são o fato mais concreto que a loja tem: é ele que fala alto */
.split__titulo em {
  font-style: normal;
  font-variation-settings: 'wdth' 88, 'wght' 900;
  color: var(--brand);
}
/* o monumento pede mais ar embaixo do que o resto do bloco */
.split__titulo + * { margin-top: var(--s6); }

.checklist { display: grid; gap: var(--s4); }
/* Mesmo motivo do .prosa__lista: marcador posicionado em vez de grid, para
   que um <strong> ou link dentro do item não vire um filho a mais e quebre. */
.checklist li {
  position: relative;
  padding-left: calc(0.75rem + var(--s3));
  font-size: var(--t-base);
  line-height: 1.55;
}
.checklist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 0.75rem;
  height: 0.75rem;
  background: var(--brand);
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}

/* `isolation` é obrigatório, mesma razão do .hero e do .cat-hero: o bloco
   vermelho abaixo vive em z-index -1, e sem um contexto de empilhamento aqui
   ele escapa e pinta ATRÁS do fundo da seção, que é opaco.

   O bug era intermitente e por isso enganava: enquanto a revelação de entrada
   estava rodando, o `opacity: 0` e o `transform` do [data-reveal] criavam o
   contexto sozinhos e o bloco aparecia. No último quadro a animação zera as
   duas — `opacity: 1`, `transform: none` —, o contexto some junto e o bloco
   era engolido. Daí "aparece quando carrega e depois desaparece". */
/* O recuo de baixo é o degrau: a foto menor desce para fora da maior. Toda a
   geometria daqui sai de DUAS constantes, a largura de cada foto, para que o
   bloco vermelho continue casado com a foto menor sem número mágico:

     altura do media = L*0,80*4/3 + L*0,16   = 1,2267 L
     altura da foto B = L*0,44*4/3           = 0,5867 L
     logo a foto B ocupa 0,5867/1,2267 = 47,8% da altura. */
.split__media { position: relative; isolation: isolate; padding-bottom: 16%; }
.split__foto {
  display: block;
  width: 100%;
  border-radius: var(--radius);
  object-fit: cover;
}
.split__foto--a { width: 80%; aspect-ratio: 3 / 4; }
.split__foto--b {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 44%;
  aspect-ratio: 3 / 4;
  /* moldura na cor do fundo da seção: separa as duas fotos sem inventar
     sombra, que não existe em lugar nenhum deste site */
  border: 0.5rem solid var(--ground-alt);
}
/* bloco angular vermelho atrás da foto menor */
.split__media::before {
  content: '';
  position: absolute;
  right: calc(var(--s5) * -1);
  bottom: calc(var(--s5) * -1);
  width: 44%;
  height: 47.8%;
  background: var(--brand);
  clip-path: polygon(22% 0, 100% 0, 100% 100%, 0 100%);
  z-index: -1;
}

/* --------------------------------------------------------------
   12. CTA final
   -------------------------------------------------------------- */
.cta {
  position: relative;
  isolation: isolate;
  background: var(--brand);
  color: var(--ink-on-brand);
  overflow: hidden;
  padding-block: clamp(var(--s8), 9vw, var(--s10));
}
/* A cunha em vermelho fechado que existia aqui FOI REMOVIDA quando a foto de
   atendimento entrou. Ela dava profundidade num fundo chapado, mas ao lado da
   foto virava uma SEGUNDA transição: o clip-path tem aresta dura, então a
   sequência lida era "vermelho, aresta, degradê". Agora é uma transição só.
   Se a foto sair daqui um dia, ela merece voltar. */
/* A foto entra pela direita e DISSOLVE no vermelho, o mesmo device do hero:
   sem aresta, sem moldura, o campo de cor vira imagem.

   z-index -1, igual à cunha: as duas ficam atrás do conteúdo em fluxo do
   .container sem precisar posicionar o texto. E como o ::before é gerado
   primeiro, a foto pinta por cima da cunha, que é a ordem certa.
   O .cta já tem isolation e overflow: hidden, então nada disto escapa. */
.cta__media {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  /* 66% de largura, encostada à direita: a faixa começa em 34% da seção, e é
     dentro dela que a diagonal corta. Nem mais larga (a origem tem 1200px e
     passaria a ser ampliada) nem mais estreita (a diagonal não caberia). */
  width: 66%;
  z-index: -1;
  /* CORTE RETO, sem degradê nenhum. À esquerda da diagonal fica o vermelho
     chapado da própria seção; à direita, a foto.

     Em coordenadas da SEÇÃO a linha vai de 44% no topo a 58% embaixo. A
     inclinação abre para a direita conforme desce, ao contrário da cunha que
     morava aqui — e é essa inversão que resolve o conflito com o conteúdo:
     o título e os botões estão encostados à ESQUERDA e descendo, então a
     diagonal se afasta deles justamente onde eles são mais largos.

       título, no meio da altura (y 35%):  corte em 48,9%  contra 44%  = +5
       botões, mais embaixo    (y 77%):    corte em 54,8%  contra 43%  = +12

     Convertendo para dentro da faixa, que vai de 34% a 100% da seção:
       topo    (44 - 34) / 66 = 15%
       embaixo (58 - 34) / 66 = 36%   */
  clip-path: polygon(15% 0, 100% 0, 100% 100%, 36% 100%);
}
.cta__foto { width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%; }

/* Abaixo de 1200 o corte diagonal não cabe: o .cta__inner tem 40rem fixos, e
   numa seção de 885px isso é 76% da largura — o texto e os botões chegariam
   do outro lado da diagonal. Aqui a foto vira faixa deitada no fim da seção,
   com aresta reta, sem degradê. É o mesmo desenho que o telefone usa. */
@media (max-width: 1199px) {
  .cta { padding-bottom: 0; }
  .cta__media {
    position: static;
    width: auto;
    height: 12rem;
    margin-top: var(--s7);
    clip-path: none;
  }
}

.cta__inner { display: grid; gap: var(--s6); max-width: 40rem; }
.cta__title { font-size: var(--t-2xl); }
.cta__text { color: rgba(255, 255, 255, 0.9); font-size: var(--t-lg); line-height: 1.5; max-width: 38ch; }
.cta__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
.cta .btn--primary { background: #fff; color: var(--brand); box-shadow: var(--shadow); }
.cta .btn--primary:hover { background: var(--n100); color: var(--brand-hover); }

/* --------------------------------------------------------------
   13. Contato + rodapé
   -------------------------------------------------------------- */
.contato-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s6);
}
.contato-item { display: grid; gap: var(--s2); }
.contato-item .ico { width: 1.5rem; height: 1.5rem; color: var(--brand); }
.contato-item__rotulo {
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.contato-item__valor { font-size: var(--t-md); font-variation-settings: 'wdth' 100, 'wght' 600; line-height: 1.4; }
.contato-item__valor span { display: block; font-variation-settings: 'wdth' 100, 'wght' 400; font-size: var(--t-sm); color: var(--ink-2); }

.site-footer {
  background-color: var(--field);
  background-image: var(--field-mesh);
  color: var(--ink-2-on-field);
  padding-block: var(--s8) var(--s6);
  font-size: var(--t-sm);
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--s7);
  padding-bottom: var(--s6);
}

/* As categorias ganham a largura toda: numa coluna de ~330px os chips
   quebrariam em 5 linhas e não haveria economia nenhuma. */
.footer__cats {
  padding-block: var(--s6);
  border-block: 1px solid var(--line-on-field);
}
.footer__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.footer__chip {
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0 var(--s4);
  border: 1px solid var(--line-on-field);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-variation-settings: 'wdth' 96, 'wght' 550;
  color: var(--ink-2-on-field);
  transition:
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    background-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}
.footer__chip:hover {
  border-color: var(--brand);
  background: var(--n0);
  color: var(--brand);
}
.footer__title {
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: var(--s4);
}
.footer__list { display: grid; gap: var(--s2); }
.footer__list a {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  transition: color var(--dur-fast) var(--ease);
}
.footer__list a:hover { color: var(--brand); }

.footer__legal {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.footer__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease);
}
.footer__legal a:hover { color: var(--brand); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s4);
  padding-top: var(--s5);
  font-size: var(--t-xs);
  color: var(--n700);
}

/* --------------------------------------------------------------
   14. Páginas de texto (privacidade e afins)
   -------------------------------------------------------------- */
.pagina-topo {
  background-color: var(--field);
  background-image: var(--field-mesh);
  color: var(--ink);
  padding-top: calc(var(--header-total) + clamp(var(--s7), 6vw, var(--s8)));
  padding-bottom: clamp(var(--s7), 6vw, var(--s8));
}

.prosa { max-width: 68ch; }
.prosa > * + * { margin-top: var(--s4); }
.prosa h2 {
  font-size: var(--t-lg);
  margin-top: var(--s7);
  margin-bottom: var(--s2);
}
.prosa p { line-height: 1.7; }
.prosa a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.prosa__data {
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.prosa__lista { display: grid; gap: var(--s3); }
/* Marcador posicionado, NÃO grid de duas colunas. Com grid, um <strong> ou um
   link dentro do item vira um filho a mais e quebra a linha: o item passa a
   ter três filhos (marcador, elemento, texto) para duas colunas. */
.prosa__lista li {
  position: relative;
  padding-left: calc(0.6rem + var(--s3));
  line-height: 1.6;
}
.prosa__lista li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.6rem; height: 0.6rem;
  background: var(--brand);
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}
/* pendências que só o dono pode preencher — visíveis de propósito, para não
   irem ao ar por engano */
/* Tracejada de propósito: o traço interrompido lê como "provisório", e evita
   a aba lateral colorida, que é clichê de interface gerada. */
.prosa__aviso {
  padding: var(--s4) var(--s5);
  border: 1px dashed var(--n400);
  border-radius: var(--radius);
  background: var(--n50);
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--n700);
}

/* --------------------------------------------------------------
   15. Página de categoria
   -------------------------------------------------------------- */
.cat-hero {
  position: relative;
  /* isolation e obrigatório: sem ele as camadas de z-index negativo abaixo
     escapam da capa e vão parar atrás do fundo da página. */
  isolation: isolate;
  background-color: var(--field);
  color: var(--ink);
  /* o cabeçalho é fixo e passa por cima: o vão dele entra no recuo de cima */
  padding-top: calc(var(--header-total) + clamp(var(--s8), 8vw, var(--s9)));
  padding-bottom: clamp(var(--s8), 8vw, var(--s9));
  /* FAIXA, não tela cheia: quem clicou numa categoria veio ver a lista de
     itens, e um hero de 100% empurraria o conteúdo para baixo em 11 páginas. */
  min-height: 58dvh;
  display: grid;
  align-items: center;
  overflow: hidden;
}

/* A foto ocupa o fundo inteiro. A hachura fica atrás dela: se a imagem não
   carregar, a capa não vira um retângulo vazio. */
.cat-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-color: var(--field);
}
/* foto e hachura empilhadas no mesmo lugar; a hachura é o fallback */
.cat-hero__media > .ph { position: absolute; inset: 0; }
.cat-hero__foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* o assunto das fotos fica no terço direito; ancorar à direita garante que
     ele sobreviva ao recorte em telas estreitas */
  object-position: right center;
}

/* O campo cinza cobrindo a esquerda e dissolvendo na foto — mesmo device do
   hero da home, deitado. É ele que dá contraste para o texto, no lugar do véu
   escuro que a referência usava: preto está fora da paleta do cliente. */
.cat-hero__panel {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--field);
  background-image: var(--field-mesh);
  -webkit-mask-image: linear-gradient(100deg,
      #000 42%, rgba(0, 0, 0, 0.86) 50%, rgba(0, 0, 0, 0.45) 60%,
      rgba(0, 0, 0, 0.12) 68%, transparent 76%);
          mask-image: linear-gradient(100deg,
      #000 42%, rgba(0, 0, 0, 0.86) 50%, rgba(0, 0, 0, 0.45) 60%,
      rgba(0, 0, 0, 0.12) 68%, transparent 76%);
}
/* O limite vai nos FILHOS, não no container: este elemento também é .container,
   e reduzir o max-width dele centralizaria o texto (margin-inline:auto) em vez
   de mantê-lo à esquerda — jogando-o justamente para dentro da faixa vermelha. */
.cat-hero__inner { position: relative; display: grid; gap: var(--s5); }
.cat-hero__inner > * { max-width: 34rem; }
.cat-hero__ico { width: 3rem; height: 3rem; color: var(--brand); }
.cat-hero__title { font-size: var(--t-2xl); }
.cat-hero__intro { font-size: var(--t-lg); line-height: 1.5; color: var(--ink-2-on-field); max-width: 44ch; }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--t-sm);
  color: var(--ink-2-on-field);
  margin-bottom: var(--s2);
}
/* 24px é o alvo mínimo do WCAG 2.2 (2.5.8); a linha do breadcrumb renderiza
   em 23px sem isto, um pixel abaixo. */
.breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-height: 1.5rem;
}
.breadcrumb a:hover { color: var(--brand); text-decoration: underline; }
.breadcrumb__sep { color: var(--n500); }

.cat-layout {
  display: grid;
  grid-template-columns: 1fr 17rem;
  gap: clamp(var(--s6), 6vw, var(--s8));
  align-items: start;
}

/* O título desta seção era o ÚNICO título de peso do site sem
   font-variation-settings — mesmo sintoma que o da home tinha antes. Aqui ele
   assume a voz da casa. Fica abaixo do título da capa (--t-2xl) de propósito:
   a capa nomeia a categoria, este só apresenta a lista. */
.cat-itens__titulo {
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 2.75rem);
  font-variation-settings: 'wdth' 88, 'wght' 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  max-width: 18ch;
  margin-bottom: var(--s6);
}
/* "na loja" é a promessa: o item existe e está lá agora. Mesmo device do
   .split__titulo e do .sec-head__title. */
.cat-itens__titulo em {
  font-style: normal;
  font-variation-settings: 'wdth' 88, 'wght' 900;
  color: var(--brand);
}

/* Os itens deixam de ser caixinhas e viram LISTA.

   O motivo não é gosto: eles são a substância da página — o que a loja de
   fato vende — e estavam com fundo #f4f4f4 e borda de 1px, exatamente o
   mesmo tratamento do trilho de navegação ao lado. Substância e menu com o
   mesmo peso é hierarquia invertida.

   Sem contêiner, o que estrutura a lista é o fio embaixo de cada linha. Uma
   coluna só porque toda categoria tem cinco itens: em duas, sobrava um órfão
   na última fileira. */
.itens-grid {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}
.item-chip {
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: var(--s5) 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--t-lg);
  font-variation-settings: 'wdth' 92, 'wght' 650;
  letter-spacing: -0.015em;
  color: var(--ink);
}
/* a cunha vermelha cresce junto: era 0.6rem de enfeite, agora é o marcador
   da linha e precisa segurar o tipo maior ao lado */
.item-chip::before {
  content: '';
  width: 0.85rem; height: 0.85rem;
  flex: none;
  background: var(--brand);
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}

/* O parágrafo das marcas, logo antes do que fecha a seção.
   Em prosa, e não em etiquetas: quem lê a lista de itens está lendo, e uma
   grade de caixinhas ali obrigaria a trocar de modo de leitura no meio.
   Os nomes ficam no tom do texto principal enquanto a frase em volta fica
   no secundário — assim quem varre a página procurando uma marca a acha
   sem ler a frase inteira. */
.prosa-marcas {
  margin-top: var(--s6);
  color: var(--ink-2);
}
.marca-citada {
  font-variation-settings: 'wdth' 100, 'wght' 650;
  color: var(--ink);
}

/* Trilho lateral — pular para outra categoria sem voltar */
.rail {
  position: sticky;
  top: calc(var(--header-h) + var(--s5));
  padding: var(--s5);
  background: var(--ground-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.rail__title {
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: var(--s4);
}
.rail__list { display: grid; gap: 2px; }
.rail__link {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--radius-sm);
  font-size: var(--t-sm);
  font-variation-settings: 'wdth' 100, 'wght' 550;
  color: var(--n700);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.rail__link .ico { width: 1.15rem; height: 1.15rem; color: var(--n500); transition: color var(--dur-fast) var(--ease); }
.rail__link:hover { background: var(--n0); color: var(--ink); }
.rail__link:hover .ico { color: var(--brand); }
.rail__link[aria-current='page'] { background: var(--brand); color: var(--ink-on-brand); }
.rail__link[aria-current='page'] .ico { color: var(--ink-on-brand); }

/* --------------------------------------------------------------
   Faixa de marcas — montada NA COSTURA entre a capa e o conteúdo
   -------------------------------------------------------------- */

/* Ela não fica abaixo da capa: fica em cima da divisa, metade sobre o hero e
   metade sobre a seção de baixo.

   A conta: margem de cima negativa de meia altura sobe a faixa até a costura;
   margem de baixo positiva de meia altura devolve o espaço, para o conteúdo
   seguinte não subir junto. O resultado é a faixa deslocada sem nada mais
   sair do lugar. Por isso a ALTURA É FIXA — com altura automática as duas
   margens não teriam como saber quanto vale metade.

   Cinza #6e6e6e com texto branco: 5,1:1 de contraste e três vezes mais
   distante do campo do hero do que o degrau seguinte da escala. Um tom mais
   claro reprovaria no contraste com texto branco e ficaria quase igual ao
   campo com texto escuro. */
.marcas {
  --h-marcas: 3.5rem;

  position: relative;
  z-index: 2;
  height: var(--h-marcas);
  margin-top: calc(var(--h-marcas) / -2);
  margin-bottom: calc(var(--h-marcas) / -2);
  display: flex;
  align-items: center;
  background: var(--n600);
  color: #fff;
  overflow: hidden;
}
/* A máscara fica na JANELA, não na faixa: assim ela apaga só as marcas nas
   pontas. Se estivesse na faixa, o próprio fundo cinza desbotaria nas bordas
   e a barra pareceria rasgada. */
.marcas__janela {
  flex: 1;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
/* A fita corre em loop. O componente de referência media a largura em JS para
   saber quanto andar; aqui a lista é DUPLICADA e a fita anda exatamente
   -50%, então a emenda é exata por construção e dispensa medição.
   Por isso o vão entre marcas é `margin-right` em cada item, e não `gap` do
   flex: com gap, metade da largura total cai meio vão fora do lugar e a
   emenda pula a cada volta. */
.marcas__fita {
  display: flex;
  /* obrigatório desde que --escala existe: com alturas diferentes, o stretch
     padrão alinharia os logos menores pelo topo em vez do meio da faixa. */
  align-items: center;
  width: max-content;
  /* --dur-fita vem do build, calculada a partir da largura da fita para a
     velocidade ficar igual em todas as páginas (ver faixaDeMarcas em
     src/shell.mjs). Duração fixa aqui faria a faixa de uma categoria com
     poucas marcas arrastar e a de uma com muitas disparar. */
  animation: marcas-correm var(--dur-fita, 46s) linear infinite;
}
.marcas__item {
  margin-right: var(--s8);
  flex: none;
  font-size: var(--t-base);
  font-variation-settings: 'wdth' 86, 'wght' 700;
  letter-spacing: 0.02em;
  color: #fff;
  white-space: nowrap;
}
/* A logo entra pela ALTURA, nunca pela largura: marcas têm proporções muito
   diferentes, e travar a largura achataria umas e esticaria outras.
   O max-width é o contrapeso disso: a Tramontina é 8,8× mais larga que alta,
   e na mesma altura das outras ela sozinha ocuparia meia fita. Com o teto,
   object-fit reduz as muito compridas em vez de deformá-las. */
.marcas__logo {
  display: block;
  /* --escala é o ajuste óptico por marca, vindo de data/site.mjs: altura
     igual não é tamanho igual quando o traço de uma marca é mais fino que o
     da outra. Fica entre 0,89 e 1,11 — sem ele definido, 1. */
  height: calc(1.5rem * var(--escala, 1));
  width: auto;
  max-width: calc(9rem * var(--escala, 1));
  object-fit: contain;
  /* Silhueta branca. brightness(0) achata tudo em preto preservando a
     transparência; invert(1) vira branco. Funciona com qualquer arquivo —
     colorido ou não, SVG ou PNG — e resolve de uma vez o problema de sete
     marcas trazerem sete paletas para dentro do site.
     EXIGE arquivo com fundo transparente. Os sete PNG em assets/img/marcas/
     foram preparados para isso — quatro tinham fundo branco chapado e duas
     eram o nome vazado dentro de bloco de cor. Os arquivos como vieram da
     loja estão em .backup-antes-marcas/ (fora do que sobe pro ar). Marca
     nova entra pelo mesmo tratamento, senão vira retângulo branco. */
  filter: brightness(0) invert(1);
}

@keyframes marcas-correm {
  to { transform: translateX(-50%); }
}

/* A fita NÃO pausa no hover. Chegou a pausar, para dar tempo de ler o nome,
   mas ela cruza a página inteira: o ponteiro atravessa a faixa a caminho de
   qualquer outra coisa e a parada vira acidente, não escolha. Como não há
   nada para clicar aqui, não havia o que ler com calma. */

/* fora da tela ela para: laço infinito repintando a troco de nada custa
   bateria no celular. Sem JS a fita simplesmente corre — falha segura. */
.marcas[data-correndo='false'] .marcas__fita { animation-play-state: paused; }

/* --------------------------------------------------------------
   16. Placeholder de imagem — provisório, some quando entrar foto real
   -------------------------------------------------------------- */
.ph {
  position: relative;
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(135deg,
      var(--n200) 0 8px,
      var(--n100) 8px 16px);
  color: var(--n600);
  overflow: hidden;
}
/* variante para o campo cinza: um tom acima, para o placeholder se destacar */
.ph--field {
  background:
    repeating-linear-gradient(135deg,
      var(--n400) 0 8px,
      var(--n300) 8px 16px);
  color: var(--n700);
}
.ph__label {
  font-size: var(--t-xs);
  font-variation-settings: 'wdth' 88, 'wght' 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: var(--s2) var(--s4);
  background: var(--ground);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  color: var(--ink-2);
}

/* --------------------------------------------------------------
   17. Botão flutuante de WhatsApp (mobile)
   -------------------------------------------------------------- */
/* O mapa da loja. Mesma proporção e mesmo raio do bloco reservado que ele
   substituiu, para a seção não mudar de altura na troca. */
.mapa {
  display: block;
  width: 100%;
  aspect-ratio: 21 / 7;
  border: 0;
  border-radius: var(--radius);
}
/* 21:7 no telefone vira uma fresta: não se vê rua nenhuma */
@media (max-width: 860px) {
  .mapa { aspect-ratio: 4 / 3; }
}

.wa-float {
  position: fixed;
  right: var(--s4);
  bottom: max(var(--s4), env(safe-area-inset-bottom));
  z-index: 90;
  display: none;
  box-shadow: var(--shadow-lg);
}
/* Entra só depois que o topo sai de vista — antes disso ele disputava a tela
   com o botão de WhatsApp do próprio hero, dois CTAs iguais lado a lado.

   Desloca por `translate`, não por `transform`, DE PROPÓSITO: são propriedades
   separadas, então isto não briga com o `transform: translateY(1px)` do
   .btn:active. Usando transform eu teria de recriar a lista de transição
   inteira do .btn aqui — e sobrescrevê-la é o erro que já matou a galeria.

   150% é a altura do próprio botão com folga: sai da tela em qualquer
   tamanho, sem pixel fixo. Atrás de .js porque a rede de segurança do <head>
   precisa poder devolvê-lo se o site.js não rodar — é o CTA principal do
   celular e não pode ficar fora da tela por falha de script. */
.js .wa-float { translate: 0 150%; }
.js .wa-float[data-visivel='true'] { translate: none; }


/* --------------------------------------------------------------
   18. Movimento — um gesto só, orquestrado
   -------------------------------------------------------------- */
[data-reveal] {
  opacity: 1;
  transform: none;
}
.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.25rem);
  transition:
    opacity 620ms var(--ease),
    transform 620ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal][data-shown='true'] { opacity: 1; transform: none; }
/* ---- Cascatas: o gatilho é o contêiner, o passo é de cada filho ----

   Por que ANIMAÇÃO aqui e TRANSIÇÃO no resto do site: estes filhos já têm um
   `transition` próprio — o :active de 160ms, o flex-grow de 500ms da galeria.
   Declarar transição num seletor mais específico SUBSTITUI aquela lista, e foi
   exatamente assim que a expansão da galeria já morreu uma vez. `animation` é
   outra propriedade e não encosta em `transition`.

   O fill é `backwards`, nunca `forwards`: `backwards` segura o primeiro quadro
   durante o atraso e solta o elemento quando termina. Com `forwards`, o
   `transform: none` do fim continuaria valendo e anularia o :active para sempre.

   Os keyframes só declaram `from`. O `to` implícito é o estilo real do
   elemento, então nada aqui precisa repetir (nem desatualizar) o valor final. */
@keyframes entra-de-baixo { from { opacity: 0; transform: translateY(12%); } }
@keyframes entra-do-lado  { from { opacity: 0; transform: translateX(1rem); } }

/* Galeria. O grupo é só o GATILHO e não se move: se ele também revelasse, o
   fade dele multiplicaria o dos ladrilhos e os primeiros entrariam quase
   invisíveis. Um observador por grupo (e não por ladrilho) porque no celular a
   grade tem 3 fileiras — observando cada ladrilho, os de baixo entrariam na
   tela e só apareceriam meio segundo depois. */
.js .gal-grupo[data-reveal] { opacity: 1; transform: none; transition: none; }

.js .gal-grupo[data-reveal] .gal-grupo__titulo {
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity 520ms var(--ease), transform 520ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js .gal-grupo[data-reveal][data-shown='true'] .gal-grupo__titulo {
  opacity: 1;
  transform: none;
}

/* 45ms de passo: meio da faixa de 30-80ms. Seis ladrilhos varrem em 225ms. */
.js .gal-grupo[data-reveal] .gal__item { opacity: 0; }
.js .gal-grupo[data-reveal][data-shown='true'] .gal__item {
  opacity: 1;
  animation: entra-de-baixo 520ms var(--ease) backwards;
  animation-delay: calc(var(--reveal-delay, 0ms) + 90ms + var(--i, 0) * 45ms);
}

/* Chips da página de categoria — mesma mecânica, passo menor porque são mais. */
.js .itens-grid[data-reveal] { opacity: 1; transform: none; transition: none; }
.js .itens-grid[data-reveal] .item-chip { opacity: 0; }
.js .itens-grid[data-reveal][data-shown='true'] .item-chip {
  opacity: 1;
  animation: entra-de-baixo 420ms var(--ease) backwards;
  animation-delay: calc(var(--reveal-delay, 0ms) + var(--i, 0) * 30ms);
}

/* Gaveta: os links assentam DEPOIS que o painel chega (260ms de deslize), e
   entram pelo mesmo lado de onde ele veio. Sem gate .js de propósito — a
   gaveta só abre com JS, então se ele falhar isto nunca dispara. */
.drawer[data-open='true'] .drawer__link {
  animation: entra-do-lado 240ms var(--ease) backwards;
  animation-delay: calc(120ms + var(--i, 0) * 30ms);
}


@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Movimento reduzido é menos deslocamento, não ausência de transição:
     cor e opacidade continuam, porque são pista de continuidade. Por isso o
     seletor universal não zera mais transition-duration. */
  *, *::before, *::after {
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  /* revelação na rolagem: entra sem subir */
  .js [data-reveal] { opacity: 1; transform: none; }

  /* as cascatas: os filhos aparecem, sem deslocamento e sem escalonamento */
  .js .gal-grupo[data-reveal] .gal-grupo__titulo,
  .js .gal-grupo[data-reveal] .gal__item,
  .js .itens-grid[data-reveal] .item-chip { opacity: 1; transform: none; }
  .js .gal-grupo[data-reveal][data-shown='true'] .gal__item,
  .js .itens-grid[data-reveal][data-shown='true'] .item-chip,
  .drawer[data-open='true'] .drawer__link { animation: none; }

  /* nada se desloca nem escala */
  .btn:active { transform: none; }
  .gal__item:active,
  .rail__link:active,
  .footer__chip:active,
  .megamenu__item:active,
  .drawer__link:active { transform: none; }
  /* a travessia entre páginas vira corte seco em vez de fusão */
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
  .arrow-link:hover .ico { transform: none; }
  /* a foto do hero nao assenta; o botao flutuante aparece sem deslizar */
  .hero__foto { animation: none; }
  .js .wa-float { translate: none; opacity: 0; visibility: hidden; }
  .js .wa-float[data-visivel='true'] { opacity: 1; visibility: visible; }
  /* a galeria abre mais rápido, mas continua abrindo: a revelação da foto é o
     conteúdo da seção, não enfeite */
  .gal__item { transition-duration: 200ms; }
  .gal:has(.gal__item:hover) .gal__item:not(:hover) .gal__legenda,
  .gal:has(.gal__item:focus-visible) .gal__item:not(:focus-visible) .gal__legenda { animation: none; }
  /* o painel aparece sem se desdobrar, e as categorias sem escalonar */
  .megamenu, .megamenu[data-open='true'] { clip-path: none; transform: none; }
  .megamenu[data-open='true'] { animation: none; }
  /* fita infinita: exatamente o laço que movimento reduzido existe para parar */
  .marcas__fita { animation: none; }
  .megamenu__grid, .megamenu[data-open='true'] .megamenu__grid { transform: none; }
  .megamenu__item, .megamenu[data-open='true'] .megamenu__item { transition-delay: 0ms; }
  .megamenu__item .ico,
  .megamenu[data-open='true'] .megamenu__item .ico { transform: none; transition-delay: 0ms; }
  .brand:active, .burger:active { transform: none; }
  /* a chegada do cabeçalho não roda */
  .chegada .site-header,
  .chegada .site-header .brand,
  .chegada .nav__link,
  .chegada .header__cta,
  .chegada .burger { animation: none; }
  .chegada .hero__panel,
  .chegada .hero__panel::before { animation: none; }
  .chegada .hero [data-reveal] { transition-delay: var(--reveal-delay, 0ms); }
  .chegada .cat-hero__panel { animation: none; }
  .chegada .cat-hero [data-reveal] { transition-delay: var(--reveal-delay, 0ms); }

  /* A gaveta cobre a tela inteira: sem o deslize ela teleporta, o que
     desorienta mais do que o movimento que se queria evitar. Fica, mais curta. */
  .drawer { transition-duration: var(--dur-fast); }
}

/* --------------------------------------------------------------
   19. Responsivo
   -------------------------------------------------------------- */
/* Desktop estreito: a coluna de texto tem largura fixa, mas a costura diagonal
   escala com a viewport — sem isto ela entra por cima dos botões. */
/* Sem min-width: o bloco de ≤860 vem depois e desliga o que não serve lá.
   Assim não existe faixa de largura descoberta entre as duas regras. */
@media (max-width: 1200px) {
  /* O texto ocupa uma fração maior da largura aqui, então alcança o degradê
     cedo demais: medido a 900px, o cinza sob a última letra caía para 45%.
     Empurrando o início e o fim, volta para ~81%. */
  .hero__panel { --mask-ini: 48%; --mask-fim: 78%; }
}

@media (max-width: 1024px) {
  .cat-layout { grid-template-columns: 1fr; }
  .rail { position: static; }
  .rail__list { grid-template-columns: repeat(2, minmax(0, 1fr)); display: grid; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .nav, .header__cta { display: none; }
  .burger { display: inline-flex; }
  .megamenu { display: none; }

  /* O corte diagonal vira horizontal. Aqui ele é o TOPO da imagem, não uma
     porcentagem da altura do hero: em janelas baixas a % subia por cima dos
     botões. Amarrado à imagem, o texto nunca é cortado. */
  .hero {
    display: grid;
    /* A foto era o RESTO: `1fr` só recebe o que o texto não usou, e o texto
       usava 75% da tela — sobrava uma tira de 173px, dos quais 48 eram fade.
       Com `minmax` a fileira da foto tem piso próprio e o hero cresce se
       precisar, em vez de espremê-la. */
    grid-template-rows: auto minmax(13rem, 1fr);
    /* svh, não dvh: dvh muda quando a barra de endereço do celular encolhe,
       e o hero redimensionava no meio da rolagem. svh é a altura com a barra
       aberta — o pior caso —, então cabe sempre e não se mexe. */
    min-height: 100svh;
    /* o painel some aqui, então a malha vem no próprio hero */
    background-image: var(--field-mesh);
  }
  .hero__panel { display: none; }

  /* Capa de categoria: a dissolução vira VERTICAL. Na diagonal o cinza
     sólido cobre só 42% da largura, e no telefone o texto ocupa a largura
     toda — cairia em cima da foto. Assim ele fica na parte sólida de cima e
     a foto aparece embaixo, sem custar altura extra. */
  /* A foto ficava ATRÁS do texto e só aparecia pelo que a máscara do painel
     deixava passar: opaca até 76%, transparente só aos 97% da altura. Numa
     capa de 549px isso é uma fresta de ~17px — e o recuo de baixo caía
     justamente ali. No telefone não se via foto nenhuma.

     Agora é a mesma estrutura do hero da home: o texto tem a fileira sólida
     de cima, a foto tem a fileira de baixo inteira. Uma solução só para as
     duas capas, em vez de dois truques diferentes. */
  .cat-hero {
    display: grid;
    grid-template-rows: auto auto;
    align-items: start;
    /* a altura passa a vir das duas fileiras; 74dvh forçaria vão morto */
    min-height: 0;
    padding-top: calc(var(--header-total) + var(--s6));
    /* a fileira da foto encosta no fim da capa — o recuo entra no texto */
    padding-bottom: 0;
    /* o painel some aqui, então a malha vem na própria capa */
    background-image: var(--field-mesh);
  }
  .cat-hero__panel { display: none; }
  .cat-hero__inner { grid-row: 1; padding-bottom: var(--s7); }
  .cat-hero__media {
    position: relative;
    inset: auto;
    grid-row: 2;
    /* sem isto o z-index:-2 da regra base joga a foto para trás do fundo */
    z-index: 0;
    /* altura própria e definida: o `height:100%` da foto e da hachura
       resolve contra ela. Com altura automática as duas colapsariam. */
    height: clamp(11rem, 28svh, 16rem);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 2rem);
            mask-image: linear-gradient(180deg, transparent 0, #000 2rem);
  }
  /* o recorte à direita servia à diagonal do desktop; aqui a faixa é inteira */
  .cat-hero__foto { object-position: center; }

  .hero__inner {
    grid-row: 1;
    min-height: 0;
    align-items: start;
    padding-top: calc(var(--header-total) + var(--s6));
    /* devolvido à foto: 4rem de recuo aqui é folga de desktop */
    padding-bottom: var(--s5);
  }
  .hero__content { max-width: none; }
  /* empilhados e do mesmo tamanho — evita a escadinha de larguras */
  .hero__actions .btn { flex: 1 1 100%; padding-inline: var(--s6); }

  .hero__selo { right: var(--s4); bottom: var(--s4); }
  .hero__media {
    position: relative;
    inset: auto;
    grid-row: 2;
    z-index: 0;
    /* baixo o bastante para não empurrar o hero para fora da tela;
       o 1fr do grid estica quando há espaço */
    min-height: 13rem;
    /* mesma ideia do desktop, na vertical: a foto surge por dissolução em vez
       de aresta. O grid garante que isto começa depois do texto, sempre.
       2rem, não 3: o fade era um quarto da tira inteira. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 2rem);
            mask-image: linear-gradient(180deg, transparent 0, #000 2rem);
  }
  /* >>> A faixa vermelha da passagem está DESLIGADA, igual à do desktop
     (.hero__panel::before). Apagar a linha display:none para devolver. <<< */
  .hero__media::before {
    display: none;
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(180deg,
      rgba(207, 32, 39, 0)   1.4rem,
      rgba(207, 32, 39, 0.5) 3.4rem,
      rgba(207, 32, 39, 0)   5.4rem);
  }

  /* Galeria: no telefone não existe hover, então a janela que abre não faz
     sentido. Vira grade de 2 colunas com todos os nomes visíveis. */
  .gal {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    height: auto;
    gap: var(--s2);
  }
  /* aqui não há fileira curta para compensar */

  /* A legenda sai de cima da foto. Numa célula de ~164px o resumo sobre a
     imagem ficaria em 5 linhas minúsculas e ilegível; embaixo ele respira,
     e sem véu a foto aparece inteira. */
  .gal__item {
    flex: none;
    min-width: 0;
    aspect-ratio: auto;
    background: none;
    border-radius: 0;
    overflow: visible;
  }
  .gal__item::after { display: none; }
  .gal__foto {
    position: static;
    width: 100%;
    /* height:auto é obrigatório: a regra base tem height:100%, que resolve
       contra o item e ANULA o aspect-ratio abaixo — a foto esticava e o item
       travava nessa altura, deixando a legenda fora da própria caixa. */
    height: auto;
    aspect-ratio: 4 / 5;
    margin-left: 0;
    border-radius: var(--radius);
  }
  .gal__legenda {
    position: static;
    left: auto; right: auto; bottom: auto;
    padding-top: var(--s3);
  }
  .gal__nome { font-size: var(--t-sm); color: var(--ink); }
  .gal__resumo {
    max-height: none;
    opacity: 1;
    margin-top: var(--s1);
    color: var(--ink-2);
    transition: none;
  }

  .split { grid-template-columns: 1fr; }
  /* A foto sai da direita e vira faixa no fim da seção: 46% de largura num
     telefone espremeria o texto do CTA contra a borda. */
  /* A composição escalonada CABE no telefone e vale a pena: lado a lado as
     duas ficavam com 162px, escalonadas a principal vai a 268px. O que não
     pode vir junto é o bloco vermelho — ele transborda 1,5rem à direita da
     foto, e ali isso é a calha da página: viraria rolagem horizontal.
     Por isso ele continua desligado aqui, como já estava. */
  .split__media::before { display: none; }
  .contato-grid { grid-template-columns: 1fr; }
  .wa-float { display: inline-flex; }

  /* alvos de toque confortáveis no telefone */
  .footer__list { gap: var(--s1); }
  .footer__list a { min-height: 2.75rem; }
  .footer__chip { min-height: 2.75rem; }
  /* espaço para o botão flutuante não cobrir o fim do rodapé */
  .site-footer { padding-bottom: calc(var(--s9) + env(safe-area-inset-bottom)); }
}

@media (max-width: 560px) {
  /* a galeria fica em 2 colunas mesmo aqui: uma coluna daria uma pilha
     longa demais para 11 categorias */
  .itens-grid { grid-template-columns: 1fr; }
  .rail__list { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; gap: var(--s6); }
  .sec-head { flex-direction: column; align-items: flex-start; }
}
