/* ==================================================================
   MUUDA — camada de tokens
   Única fonte de cor, tipo e espaço do site: nenhum hex vive fora daqui, e
   tests/ux.py falha se um literal escapar.
   ================================================================== */
:root{
  /* --- marca: valores oficiais do brandbook, não alterar --- */
  --magenta:#FF02DC; --verde:#0CF25D; --laranja:#F4602C; --ciano:#81F5EE;
  --navy:#150358; --grafite:#333333; --creme:#FFFFDD; --areia:#F2DDCC;

  /* --- superfície e tinta ---
     Neutros tintados para o navy da marca. Os cinzas neutros anteriores
     reprovavam em WCAG AA sobre branco (#999 dava 2.85:1). */
  --paper:#FFFEFB;
  --ink:var(--grafite);   /* 12.63:1 — corpo */
  --ink-2:#5A5A66;        /*  6.80:1 — secundário */
  --ink-3:#6E6E7A;        /*  5.03:1 — terciário: numeração, notas */
  --line:var(--grafite);

  /* Texto sobre fundo colorido. A regra da marca, medida:
     sobre cor viva o texto é navy (5.31 a 13.69:1); branco reprova
     em magenta (3.34) e laranja (3.20). Sobre navy/grafite, creme. */
  --on-vivo:var(--navy);
  --on-escuro:var(--creme);

  /* --- degradês: recurso central da marca --- */
  --grad-1:linear-gradient(135deg,var(--magenta),var(--laranja));
  --grad-2:linear-gradient(135deg,var(--ciano),var(--verde));
  --grad-3:linear-gradient(135deg,var(--navy),var(--magenta));
  --grad-4:linear-gradient(135deg,var(--verde),var(--navy));
  --grad-5:linear-gradient(135deg,var(--laranja),var(--magenta),var(--navy));

  /* --- padrão único de hover: alias semântico, não cor nova. Referencia --navy/--grad-1
     em vez de redeclarar o hex, então a paleta continua tendo uma única fonte de verdade
     (mudar --navy muda o hover em todo o site sem editar dois lugares). --- */
  --color-hover:var(--navy);
  --gradient-primary:var(--grad-1);
  --transition-hover:.2s ease;

  /* --- tipografia: Nunito Sans oferece 200–1000; usamos cinco pesos.
     O contraste entre --w-air e --w-black é o efeito do "índice". --- */
  --w-air:200; --w-body:400; --w-mid:600; --w-bold:800; --w-black:1000;

  --t-2xs:.6875rem;   /* 11px */
  --t-xs:.8125rem;    /* 13px */
  --t-sm:.9375rem;    /* 15px */
  --t-base:1rem;      /* 16px — base do corpo */
  --t-md:1.25rem;     /* 20px — o logo em degradê chega a 3.18:1 sobre o papel,
                         e só a partir de 18.66px em peso >=700 esse valor basta */
  --t-quote:clamp(1.25rem,2.2vw,2.25rem);
  --t-quote-sm:clamp(1rem,1.1vw,1.125rem);
  --t-reveal:clamp(2.25rem,3.6vw,3.75rem);
  --t-lg:clamp(1.75rem,4.6vw,4rem);
  --t-xl:clamp(2.5rem,7.5vw,6.875rem);
  --t-display:clamp(3.25rem,10.5vw,10.5rem);

  /* --- espaço --- */
  --sp-1:.25rem; --sp-2:.5rem; --sp-3:.75rem; --sp-4:1rem;
  --sp-5:1.5rem; --sp-6:2rem;
  --sp-7:clamp(2.5rem,5vw,4rem);
  --sp-8:clamp(3.5rem,8vw,6.5rem);
  --gut:1.125rem;     /* gutter lateral */

  /* Altura do header fixo. Alimenta o #reveal, o .sec-head sticky e o scroll-margin das
     âncoras; o JS remede e reescreve este token (ver main.js), porque escrito à mão ele já
     divergiu do header real e o header cobriu o topo do painel. */
  --bar:69px;
  --sec-bar:56px;     /* altura do .sec-head sticky */
}
*{margin:0;padding:0;box-sizing:border-box}

/* Anel de foco global. Nenhuma cor sozinha resolve — o site tem fundo claro, navy e cinco
   degradês: navy dá ≥5.31:1 contra qualquer cor viva da paleta e o halo creme separa o anel
   dos fundos escuros. Global de propósito: elemento interativo novo já nasce com foco
   visível, sem depender de alguém lembrar. */
:focus-visible{
  outline:3px solid var(--navy);
  outline-offset:2px;
  box-shadow:0 0 0 6px var(--creme);
}

/* Skip link: fora da tela até receber foco. Primeiro alvo do Tab. */
.skip{
  position:fixed;left:var(--gut);top:var(--sp-2);z-index:100;
  transform:translateY(-250%);transition:transform .15s ease;
  background:var(--navy);color:var(--on-escuro);
  padding:var(--sp-3) var(--sp-4);border-radius:999px;
  font-weight:var(--w-bold);font-size:var(--t-xs);
}
.skip:focus{transform:translateY(0)}
/* ---------- fonte ----------
   Autohospedada (AD-021, porquê no <head> do index.html). `unicode-range` é o mesmo subset
   `latin` que o Google servia: cobre PT-BR e EN. */
@font-face{
  font-family:"Nunito Sans";
  font-style:normal;
  font-weight:200 1000;
  font-display:swap;
  src:url(../assets/fontes/nunito-sans-latin-var.woff2) format("woff2");
  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;
}
/* Fallback com métrica CASADA na da Nunito Sans, pro caso de a fonte não estar pronta no
   primeiro paint (preload cobre o caso normal; isto cobre rede ruim e cache frio). Números
   MEDIDOS no navegador, não estimados (Canvas measureText a 100px):
     Nunito Sans      → avanço 2435.67px, ascent 101, descent 35
     Arial/Liberation → avanço 2423.44px, ascent 90,  descent 22
   size-adjust iguala a largura (é ela que decide onde o text-wrap:balance do <h1> quebra);
   ascent/descent-override igualam a caixa de linha, senão os blocos mudam de altura quando a
   fonte real entra. */
@font-face{
  font-family:"Nunito Fallback";
  src:local("Arial"),local("Helvetica"),local("Liberation Sans");
  size-adjust:100.5%;
  ascent-override:100.5%;
  descent-override:34.8%;
  line-gap-override:0%;
}

html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  /* "Nunito Fallback" (métrica casada, ver @font-face acima) vem primeiro na reserva; as
     famílias seguintes cobrem o caso de nem Arial existir. Com só "sans-serif" a troca ao
     carregar a fonte remontava a página inteira. */
  font-family:"Nunito Sans","Nunito Fallback","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  color:var(--ink); background:var(--paper);
  font-size:var(--t-base); font-weight:var(--w-body); line-height:1.45;
  -webkit-font-smoothing:antialiased;
  /* sem isto o duplo-toque em celular custa 300ms de espera */
  touch-action:manipulation;
  -webkit-tap-highlight-color:color-mix(in srgb,var(--magenta) 20%,transparent);
}
::selection{background:var(--magenta);color:var(--on-vivo)}
a{color:inherit;text-decoration:none}

/* ---------- top bar ---------- */
header{
  position:fixed;inset:0 0 auto 0;z-index:50;
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:var(--sp-5);
  padding:var(--sp-3) max(var(--gut),env(safe-area-inset-right))
          var(--sp-3) max(var(--gut),env(safe-area-inset-left));
  background:color-mix(in srgb,var(--paper) 92%,transparent);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
}
.logo{font-weight:var(--w-black);font-size:var(--t-md);letter-spacing:-.5px;text-transform:uppercase}
.logo span{background:var(--grad-1);-webkit-background-clip:text;background-clip:text;color:transparent}
nav{display:flex;justify-content:center;gap:clamp(var(--sp-3),2.2vw,var(--sp-5));font-weight:var(--w-mid);font-size:var(--t-sm)}
/* O botão só existe quando há JS para operá-lo: a classe .js é posta pelo
   próprio script. Sem JS ele nunca aparece e a <nav> continua sendo uma lista
   visível — nunca um menu morto. */
.nav-toggle{
  display:none;background:var(--paper);color:var(--ink);
  border:1px solid var(--line);border-radius:999px;cursor:pointer;
  min-height:44px;min-width:44px;padding:var(--sp-2);
  transition:background-color var(--transition-hover),color var(--transition-hover);
}
.nav-toggle:hover{background:var(--color-hover);color:var(--on-escuro)}
/* Hambúrguer → X: currentColor herda a cor do botão (troca sozinho no hover, sem
   regra própria). As 3 linhas viram X girando as de fora 45°/-45° até o centro
   comum (12,12 no viewBox) e apagando a do meio — não precisa trocar de ícone. */
.nav-toggle .bar{
  stroke:currentColor;stroke-width:2;stroke-linecap:round;
  transform-origin:12px 12px;
  transition:transform var(--transition-hover),opacity var(--transition-hover);
}
.nav-toggle[aria-expanded="true"] .b1{transform:translateY(6px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] .b2{opacity:0}
.nav-toggle[aria-expanded="true"] .b3{transform:translateY(-6px) rotate(-45deg)}
nav a{position:relative;padding:var(--sp-1) 0}
/* O magenta sobre o papel dá 3.31:1 — serve como acento, não como texto.
   A cor vai para --color-hover e o magenta vira sublinhado (elemento não-textual, 3:1). */
nav a:hover{color:var(--color-hover);text-decoration:underline;
  text-decoration-color:var(--magenta);text-decoration-thickness:2px;
  text-underline-offset:4px;transition:color var(--transition-hover)}
.header-cta{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  min-height:44px;padding:var(--sp-2) var(--sp-4);border:1px solid var(--navy);
  border-radius:999px;background:var(--gradient-primary);color:var(--navy);
  font-size:var(--t-sm);font-weight:var(--w-bold);white-space:nowrap;cursor:pointer;
  transition:background var(--transition-hover),color var(--transition-hover),
    transform .15s ease;
}
.header-cta:hover{background:var(--color-hover);color:var(--on-escuro)}
/* Grid do header usa 1 gap só (--sp-5, 24px) pras 3 colunas. Pra switch e CTA
   ficarem mais próximos entre si (8px, --sp-2) que do resto, os dois viram uma
   coluna só por dentro — um flex com seu próprio gap. */
.header-actions{display:flex;align-items:center;gap:var(--sp-2)}
/* Switch iOS-style (role="switch"): a trilha (.rail) imprime PT/EN nas pontas e a bolinha
   (.thumb) desliza pro lado do idioma ativo. A área de toque (o <button>) é maior que a
   trilha visual — min-height:44px. Os textos PT/EN são aria-hidden: o nome acessível vem do
   aria-label, que descreve a AÇÃO, não o estado. */
.lang-toggle{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:var(--sp-2);border:none;border-radius:999px;
  background:transparent;cursor:pointer;
}
.lang-toggle .rail{
  position:relative;display:flex;align-items:center;
  width:84px;height:44px;
  border:1px solid var(--line);border-radius:999px;
  transition:border-color var(--transition-hover);
}
.lang-toggle:hover .rail{border-color:var(--color-hover)}
/* 2 cópias do switch (desktop + dentro do <nav> mobile) — só 1 visível por vez. A de dentro
   do <nav> fica oculta fora do breakpoint mobile sempre, de propósito, pra nunca aparecer
   duplicada lado a lado com a do header. */
nav .lang-toggle{display:none}
.lang-toggle .lbl{
  position:relative;z-index:1;flex:1;text-align:center;
  font-size:var(--t-2xs);font-weight:var(--w-bold);color:var(--ink-3);
  transition:color var(--transition-hover);
}
.lang-toggle .thumb{
  /* top+bottom em vez de height fixo: .rail tem border:1px e a posição absoluta é relativa
     ao padding-box, então height fixo dava 2px em cima e 0 embaixo. Assim os 2 lados ficam
     iguais mesmo se a altura da trilha mudar. */
  position:absolute;top:2px;bottom:2px;left:3px;
  width:38px;
  border-radius:999px;background:var(--navy);
  transition:transform var(--transition-hover);
}
/* aria-checked="true" = EN ativo (PT é o padrão/"desligado", AD-012) — a bolinha
   desliza pra ponta direita da trilha e o rótulo EN ganha o contraste de "ativo". */
.lang-toggle[aria-checked="true"] .thumb{transform:translateX(100%)}
.lang-toggle[aria-checked="false"] .lbl.pt,
.lang-toggle[aria-checked="true"] .lbl.en{color:var(--on-escuro)}
.tagline{text-align:right;font-weight:var(--w-mid);color:var(--ink-3);font-size:var(--t-xs)}
.tagline b{color:var(--ink)}

/* ---------- hero ---------- */
.hero{
  /* svh e não vh: com vh a altura considera a barra do navegador móvel
     expandida, e o hero salta quando ela recolhe. */
  min-height:88svh;display:flex;flex-direction:column;justify-content:flex-end;
  padding:var(--sp-8) var(--gut) var(--sp-7);
  border-bottom:1px solid var(--line);position:relative;overflow:hidden;
}
.hero h1{
  font-weight:var(--w-black);text-transform:uppercase;letter-spacing:-.02em;
  font-size:var(--t-display);line-height:.92;text-wrap:balance;
}
.hero h1 .grad{background:var(--grad-1);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero-meta{
  display:flex;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;
  margin-top:var(--sp-6);font-weight:var(--w-mid);color:var(--ink-2);
  font-size:var(--t-md);max-width:100%;
}
.hero-meta .btns{display:flex;gap:var(--sp-2);flex-wrap:wrap}
.hero-meta .pill{
  display:inline-flex;align-items:center;min-height:44px;
  border:1px solid var(--line);border-radius:999px;
  padding:var(--sp-2) var(--sp-5);color:var(--ink);font-size:var(--t-sm);
  transition:background-color var(--transition-hover),color var(--transition-hover);
}
.hero-meta .pill:hover{background:var(--color-hover);color:var(--on-escuro)}

/* ---------- section head ----------
   Cada seção carrega um degradê da marca como faixa no cabeçalho: é o que transforma a lista
   num índice com capítulos — a cor identifica onde se está, não é enfeite.
   Faixa e não texto colorido porque verde e ciano sobre o papel dão 1.51:1 e 1.29:1: nenhuma
   cor viva da paleta pode carregar texto sobre fundo claro. */
section{border-bottom:1px solid var(--line);position:relative}
#sobre{--faixa:var(--grad-1)}
#fazemos{--faixa:var(--grad-2)}
#quem{--faixa:var(--grad-3)}
#depoimentos{--faixa:var(--grad-4)}
#modelo{--faixa:var(--grad-5)}
#clientes{--faixa:var(--grad-1)}
.sec-head::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:5px;
  background:var(--faixa);
}
/* O header é fixo e o .sec-head é sticky: sem esta margem, clicar na navegação
   deixa o topo da seção escondido atrás dos dois. Sem gap extra: .sec-head gruda
   direto em --bar (ver logo abaixo), então a margem é só a soma das duas alturas. */
[id]{scroll-margin-top:calc(var(--bar) + var(--sec-bar))}
.sec-head{
  display:grid;grid-template-columns:90px 1fr auto;gap:var(--sp-3);align-items:baseline;
  padding:var(--sp-4) var(--gut) var(--sp-4) calc(var(--gut) + var(--sp-1));
  border-bottom:1px solid var(--line);
  /* top:var(--bar), sem somar --sp-2: com a soma sobrava uma frincha de 8px entre o
     header fixo e este título, e o conteúdo da seção anterior aparecia por trás dela. */
  position:sticky;top:var(--bar);background:var(--paper);z-index:5;
}
.sec-head .num{font-weight:var(--w-air);color:var(--ink-3)}
.sec-head h2{font-size:var(--t-sm);font-weight:var(--w-black);text-transform:uppercase;letter-spacing:.06em}
.sec-head .note{color:var(--ink-3);font-weight:var(--w-mid);font-size:var(--t-xs)}

/* ---------- index rows ----------
   Sem `transition` no hover, de propósito (AD-020, guarda UX-36). `background-color` e
   `color` não são compositáveis: cada quadro repinta a linha inteira e varrer o mouse deixa
   várias linhas animando juntas. Medido com trace do Chrome (6 passadas sobre 3 linhas):
   175.6ms de raster / 1154 tarefas COM transições, 48.3ms / 212 SEM. Era a causa do
   travamento no hover. */
.row{
  display:grid;grid-template-columns:90px 1fr 1fr;gap:var(--sp-3);align-items:baseline;
  padding:var(--sp-3) var(--gut);border-bottom:1px solid var(--line);cursor:default;
}
.row:last-child{border-bottom:none}
.row .c1{font-weight:var(--w-air);color:var(--ink-3)}
.row .c2{font-weight:var(--w-bold)}
.row .c3{font-weight:var(--w-mid);color:var(--ink-2)}
.row .c3 a,.legal a{text-decoration:underline;text-underline-offset:3px}
.row:hover,.row:focus-within{background:var(--hov);color:var(--hovtx)}
/* A ênfase secundária no hover vem de MISTURA com o fundo, não de opacity:
   opacity reduz o contraste sem que ninguém perceba. A 90% o pior par
   (navy sobre magenta) fica em 4.81:1; a 85% cairia para 4.50, no limiar. */
.row:hover .c1,.row:hover .c3,
.row:focus-within .c1,.row:focus-within .c3{color:color-mix(in srgb,var(--hovtx) 90%,var(--hov))}
.row.m1{--hov:var(--magenta);--hovtx:var(--on-vivo)}
.row.m2{--hov:var(--verde);--hovtx:var(--on-vivo)}
.row.m3{--hov:var(--laranja);--hovtx:var(--on-vivo)}
.row.m4{--hov:var(--navy);--hovtx:var(--on-escuro)}
.row.m5{--hov:var(--ciano);--hovtx:var(--on-vivo)}

/* ---------- linhas de depoimentos (<details>, não <div>) ----------
   <details> é o que sustenta o accordion do mobile sem JS nenhum. O grid de 3 colunas e o
   hover coloridos continuam vindo de `.row`/`.mN`. O que precisa de ajuste é só o que o
   <details> muda de estrutura: o grid genérico cairia sobre <summary>+<figure> como se
   fossem 2 colunas, e o hover pintaria o <figure> aberto inteiro — as regras abaixo cancelam
   os dois e movem pro <summary>. */
.row.dep-row{display:block;padding:0;border-bottom:none}
.row.dep-row>summary{
  display:grid;grid-template-columns:90px 1fr 1fr;gap:var(--sp-3);align-items:baseline;
  padding:var(--sp-3) var(--gut);border-bottom:1px solid var(--line);
  cursor:pointer;list-style:none;
}
.row.dep-row:last-of-type>summary{border-bottom:none}
.row.dep-row>summary::-webkit-details-marker,.row.dep-row>summary::marker{display:none}
.row.dep-row:hover,.row.dep-row:focus-within{background:none;color:inherit}
.row.dep-row>summary:hover,.row.dep-row>summary:focus-visible{background:var(--hov);color:var(--hovtx)}
.row.dep-row>summary:hover .c1,.row.dep-row>summary:hover .c3,
.row.dep-row>summary:focus-visible .c1,.row.dep-row>summary:focus-visible .c3{
  color:color-mix(in srgb,var(--hovtx) 90%,var(--hov));
}
/* Fechado por padrão em qualquer largura. No desktop o realce é o #reveal e o clique de mouse
   NÃO abre este bloco (AD-019); quem abre lá é o teclado, que precisa disso porque o #reveal
   é aria-hidden e trunca em 38vh. Abaixo de 1101px o clique abre normalmente. */
.row.dep-row>.quote{margin-bottom:var(--sp-5)}

/* ---------- reveal panel ---------- */
#reveal{
  position:fixed;top:var(--bar);right:0;width:clamp(340px,34vw,560px);height:calc(100dvh - var(--bar));z-index:40;
  display:flex;flex-direction:column;align-items:stretch;justify-content:flex-end;
  padding:var(--sp-6);overflow:hidden;
  opacity:0;pointer-events:none;border-left:1px solid var(--line);
  transition:opacity .18s ease;
  background:var(--grad-1);
}
#reveal.show{opacity:1}
/* Painel nunca é interativo: é realce visual (aria-hidden) e o mouse passa por cima dele pra
   linha de baixo. O degradê é escolhido por atributo — a paleta não pode voltar pro JS. */
#reveal[data-grad="1"]{background:var(--grad-1)}
#reveal[data-grad="2"]{background:var(--grad-2)}
#reveal[data-grad="3"]{background:var(--grad-3)}
#reveal[data-grad="4"]{background:var(--grad-4)}
#reveal[data-grad="5"]{background:var(--grad-5)}
/* Escurecimento navy sobre o degradê e a foto. Sem ele o texto claro chegava a 1.27:1 no
   ciano→verde; a 55% o pior par da paleta fica em 5.08:1 e a cor da marca continua aparecendo. */
#reveal::after{
  content:"";position:absolute;inset:0;
  background:color-mix(in srgb,var(--navy) 55%,transparent);
  pointer-events:none;
}
#reveal .big,#reveal .small,#reveal .reveal-quote{position:relative;z-index:1}
#reveal img[hidden]{display:none}
/* Trecho do depoimento — só existe quando a linha tem data-quote-ref. O painel é decorativo
   (pointer-events:none), então isto não é rolável: `max-height` clipa e o texto INTEGRAL vive
   no <details> da própria linha. `overflow-y:auto` fica porque `-webkit-line-clamp`/
   `text-overflow` são proibidos no projeto — o texto nunca é elipsado. */
#reveal .reveal-quote{
  max-height:38vh;overflow-y:auto;margin-bottom:var(--sp-4);
  padding-left:var(--sp-3);border-left:2px solid var(--creme);
  color:var(--on-escuro);font-weight:var(--w-mid);
  font-size:var(--t-sm);line-height:1.6;text-wrap:pretty;
}
#reveal .reveal-quote[hidden]{display:none}
#reveal .big{
  font-weight:var(--w-black);text-transform:uppercase;color:var(--on-escuro);
  display:block;width:100%;min-width:0;max-width:100%;
  font-size:var(--t-reveal);line-height:.95;letter-spacing:-.02em;
  text-wrap:balance;overflow-wrap:normal;word-break:normal;hyphens:none;
}
/* Tipografia maior/mais pesada no descritivo do painel (estilo brutalista, referência do
   cliente: arianaescobar.com, theoutline.com), igual nas 4 seções que passam pelo #reveal.
   Tamanho fixo, não token vw-based: o painel (clamp(340-560px)) não escala com a viewport. */
#reveal .small{
  position:absolute;top:var(--sp-6);left:var(--sp-6);right:var(--sp-6);z-index:1;
  padding-left:var(--sp-3);border-left:2px solid var(--creme);
  color:var(--on-escuro);font-weight:var(--w-bold);text-transform:uppercase;
  font-size:1.5rem;line-height:1.2;max-width:calc(100% - var(--sp-6) * 2);
  overflow-wrap:normal;word-break:normal;hyphens:none;
}
#reveal img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1);mix-blend-mode:multiply;opacity:.6;
}

/* ---------- depoimentos ----------
   O texto integral de cada depoimento mora no <figure>, que é o conteúdo do <details> (ver
   .dep-row acima).
   O retrato leva a linguagem fotográfica do brandbook — PB sob um degradê da marca em
   multiply. O degradê fica num ::before na MESMA célula do grid que a imagem, jeito de pôr
   algo atrás dela sem envolver a img num elemento a mais. A 60% de opacidade: em multiply o
   degradê cheio escurece o rosto até perdê-lo. */
.section-intro{padding:var(--sp-5) var(--gut) 0}
.testimonials-intro{
  display:grid;grid-template-columns:minmax(150px,1fr) minmax(0,2fr) minmax(190px,1.2fr);
  gap:var(--sp-6);align-items:end
}
.eyebrow{
  align-self:start;color:var(--ink-3);font-size:var(--t-xs);font-weight:var(--w-bold);
  letter-spacing:.08em;text-transform:uppercase;padding-top:var(--sp-2)
}
.testimonials-intro h3{
  max-width:24ch;font-size:clamp(1.75rem,3.2vw,3rem);font-weight:var(--w-black);line-height:1.02;
  letter-spacing:-.02em;text-wrap:balance
}
.testimonials-intro p{
  grid-column:3;max-width:30ch;color:var(--ink-2);font-size:var(--t-sm);font-weight:var(--w-mid);line-height:1.45
}
.quote{
  display:grid;
  grid-template-columns:var(--foto) 1fr;
  gap:var(--sp-3) var(--sp-5);
  align-items:start;
  max-width:var(--larg,100%);
}
.quote::before{
  content:"";grid-area:1 / 1;aspect-ratio:1;
  background:var(--tint);opacity:.6;
}
.quote img{
  grid-area:1 / 1;width:100%;height:auto;aspect-ratio:1;object-fit:cover;
  filter:grayscale(1);mix-blend-mode:multiply;
}
.quote blockquote{
  grid-area:1 / 2;font-weight:var(--w-body);line-height:1.55;
  text-wrap:pretty;
}
.quote blockquote::before{
  content:"“";display:block;height:.45em;color:var(--magenta);font-size:3rem;
  font-weight:var(--w-black);line-height:.8
}
.quote figcaption{grid-area:2 / 2;font-size:var(--t-xs);line-height:1.4}
.quote figcaption b{font-weight:var(--w-bold);display:block}
.quote figcaption span{color:var(--ink-2)}

/* Cada relato entra numa escala e numa largura diferentes — é o que dá ritmo
   à seção sem recorrer a moldura ou sombra. */
.q1{--foto:6rem;--tint:var(--grad-1)}
.q2{--foto:6rem;--tint:var(--grad-2)}
.q3{--foto:6rem;--tint:var(--grad-3)}
.q4{--foto:6rem;--tint:var(--grad-4)}
/* Conteúdo do <details>: no desktop fica fechado (o realce é o #reveal); em ≤1100px é o
   conteúdo visível da linha. */
.dep-row .quote{
  padding:var(--sp-5) var(--gut);background:var(--areia);border-top:5px solid var(--magenta);
}
.dep-row .quote blockquote{font-size:var(--t-quote-sm);line-height:1.5}
.dep-row .quote figcaption{font-size:var(--t-sm)}

/* ---------- statement blocks ---------- */
.statement{
  padding:var(--sp-8) var(--gut);font-weight:var(--w-black);text-transform:uppercase;
  font-size:var(--t-lg);line-height:1.02;letter-spacing:-.015em;max-width:1100px;
  text-wrap:balance;
}
.statement .grad{background:var(--grad-3);-webkit-background-clip:text;background-clip:text;color:transparent}
.statement small{
  display:block;margin-top:var(--sp-4);font-size:var(--t-sm);font-weight:var(--w-mid);
  color:var(--ink-2);text-transform:none;letter-spacing:0;line-height:1.5;max-width:60ch;
}

/* ---------- clientes marquee ---------- */
.clients{overflow:hidden;padding:var(--sp-6) 0;white-space:nowrap}
.clients .track{display:inline-block;animation:mq 40s linear infinite}
/* Os logos vão de 1:1 (YPO) a 8.85:1 (Marins Bertoldi). Altura fixa faria o wordmark
   dominar; largura fixa faria o quadrado dominar. Aqui cada slot tem a MESMA ÁREA:
   largura = K·√ratio, altura = K/√ratio, com K=95 — então todos pesam igual na barra.
   O slot já reserva o espaço, então não há layout shift. */
.clients{--k:1}          /* escala da barra inteira — único botão a girar no mobile */
.clients .cli{
  display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;
  width:calc(var(--w) * var(--k));height:calc(100px * var(--k));
  margin-right:calc(52px * var(--k));
}
.clients .cli{position:relative}
.clients .cli img{
  max-width:100%;max-height:100%;object-fit:contain;
  opacity:.72;transition:opacity .15s ease;
}

/* hover: o logo vira MÁSCARA e a cor de destaque é pintada por baixo.
   filter não serve — os logos são cinza neutro (#333), e hue-rotate sobre algo
   sem saturação não produz cor nenhuma. A máscara dá o magenta exato, e aceitaria
   um degradê da marca no lugar (é só trocar o background desta regra).

   ⚠️ A mask-image fica numa declaração normal, NÃO dentro de um custom property:
   url() em custom property tem resolução ambígua entre navegadores, e quando erra
   a máscara some sem erro visível — o logo simplesmente fica branco no hover. */
.clients .cli::after{
  content:"";position:absolute;inset:0;
  background:var(--magenta);
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  opacity:0;transition:opacity .15s ease;
  pointer-events:none;
}
.clients .cli:hover::after{opacity:1}
.clients .cli:hover img{opacity:0}

/* largura por logo = 95·√ratio, o que iguala a ÁREA de todos na barra */
.cli:has(img[src$="ypo.webp"])                         {--w:95px}   /* ratio 1.00 */
.cli:has(img[src$="buschle-lepper.webp"])              {--w:100px}  /* ratio 1.11 */
.cli:has(img[src$="fg-empreendimentos.webp"])          {--w:119px}  /* ratio 1.58 */
.cli:has(img[src$="roberlo.webp"])                     {--w:121px}  /* ratio 1.62 */
.cli:has(img[src$="peri.webp"])                        {--w:133px}  /* ratio 1.96 */
.cli:has(img[src$="ekron.webp"])                       {--w:175px}  /* ratio 3.38 */
.cli:has(img[src$="pgmais.webp"])                      {--w:183px}  /* ratio 3.71 */
.cli:has(img[src$="paranatex.webp"])                   {--w:195px}  /* ratio 4.23 */
.cli:has(img[src$="hoteis-ponta-verde.webp"])          {--w:197px}  /* ratio 4.30 */
.cli:has(img[src$="remax.webp"])                       {--w:204px}  /* ratio 4.60 */
.cli:has(img[src$="market4u.webp"])                    {--w:238px}  /* ratio 6.26 */
.cli:has(img[src$="marins-bertoldi.webp"])             {--w:283px}  /* ratio 8.85 */

/* a máscara de cada logo — mesmo arquivo do src, caminho relativo a ESTE css */
.cli:has(img[src$="ypo.webp"])::after{-webkit-mask-image:url(../assets/clientes/ypo.webp);mask-image:url(../assets/clientes/ypo.webp)}
.cli:has(img[src$="buschle-lepper.webp"])::after{-webkit-mask-image:url(../assets/clientes/buschle-lepper.webp);mask-image:url(../assets/clientes/buschle-lepper.webp)}
.cli:has(img[src$="fg-empreendimentos.webp"])::after{-webkit-mask-image:url(../assets/clientes/fg-empreendimentos.webp);mask-image:url(../assets/clientes/fg-empreendimentos.webp)}
.cli:has(img[src$="roberlo.webp"])::after{-webkit-mask-image:url(../assets/clientes/roberlo.webp);mask-image:url(../assets/clientes/roberlo.webp)}
.cli:has(img[src$="peri.webp"])::after{-webkit-mask-image:url(../assets/clientes/peri.webp);mask-image:url(../assets/clientes/peri.webp)}
.cli:has(img[src$="ekron.webp"])::after{-webkit-mask-image:url(../assets/clientes/ekron.webp);mask-image:url(../assets/clientes/ekron.webp)}
.cli:has(img[src$="pgmais.webp"])::after{-webkit-mask-image:url(../assets/clientes/pgmais.webp);mask-image:url(../assets/clientes/pgmais.webp)}
.cli:has(img[src$="paranatex.webp"])::after{-webkit-mask-image:url(../assets/clientes/paranatex.webp);mask-image:url(../assets/clientes/paranatex.webp)}
.cli:has(img[src$="hoteis-ponta-verde.webp"])::after{-webkit-mask-image:url(../assets/clientes/hoteis-ponta-verde.webp);mask-image:url(../assets/clientes/hoteis-ponta-verde.webp)}
.cli:has(img[src$="remax.webp"])::after{-webkit-mask-image:url(../assets/clientes/remax.webp);mask-image:url(../assets/clientes/remax.webp)}
.cli:has(img[src$="market4u.webp"])::after{-webkit-mask-image:url(../assets/clientes/market4u.webp);mask-image:url(../assets/clientes/market4u.webp)}
.cli:has(img[src$="marins-bertoldi.webp"])::after{-webkit-mask-image:url(../assets/clientes/marins-bertoldi.webp);mask-image:url(../assets/clientes/marins-bertoldi.webp)}
@keyframes mq{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* WCAG 2.2.2: movimento automático acima de 5s precisa de um jeito de parar.
   A pausa fica em regra separada de propósito — a declaração de 40s do .track
   é asserida literalmente por check.py e não pode virar variável. */
.clients[data-paused] .track{animation-play-state:paused}

/* ---------- CTA final ---------- */
.cta{
  padding:var(--sp-8) var(--gut);background:var(--grafite);color:var(--on-escuro);text-align:left;
  background-image:var(--grad-5);
}
.cta h2{
  font-weight:var(--w-black);text-transform:uppercase;font-size:var(--t-xl);
  line-height:.95;letter-spacing:-.02em;color:var(--on-escuro);
}
.cta .actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-7);flex-wrap:wrap}
/* Os 2 botões são preenchidos em areia sobre o degradê da seção: fundo opaco próprio, então
   o contraste não depende de onde o degradê está (navy sobre areia dá 13.5:1 em qualquer
   ponto). Sem borda em nenhum dos dois — o que separa primário de secundário é a ordem e o
   "→" do primeiro. */
.cta .actions a{
  border:none;border-radius:999px;
  display:inline-flex;align-items:center;min-height:44px;
  padding:var(--sp-3) var(--sp-6);font-weight:var(--w-bold);
  font-size:var(--t-sm);
  transition:background-color var(--transition-hover),color var(--transition-hover);
  background:var(--areia);color:var(--on-vivo);
}
.cta .actions a:hover{background:var(--color-hover);color:var(--on-escuro)}

/* ---------- página 404 (404.html) ----------
   Mesma linguagem da home de propósito: quem cai aqui tem que reconhecer o site, não achar
   que pulou pra outro lugar. A página é curta — erro + CTA; a navegação sai pelo header.
   O lettering do 404 (assets/marca/404.webp) é o único ativo de marca aqui: os dois zeros são
   o desenho do logo. Fica no grafite original — o brandbook proíbe recolorir a marca letra a
   letra ou preenchê-la com degradê, então a cor da marca entra pelo degradê do <h1>. */
.err{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:var(--sp-5);
  /* Sem header nesta página, então nada de somar --bar no padding: o bloco ocupa a tela e
     centra nela. `justify-content:center` é seguro aqui porque o conteúdo é curto (lettering
     + 2 linhas) e cabe com folga — o padding continua sendo o piso, e em tela muito baixa o
     bloco cresce em vez de vazar (min-height, não height). */
  min-height:78svh;justify-content:center;
  padding:var(--sp-7) var(--gut);
}
.err-code{max-width:min(464px,72vw)}
.err-code img{width:100%;height:auto;display:block}
.err h1{
  font-weight:var(--w-black);text-transform:uppercase;letter-spacing:-.02em;
  font-size:var(--t-xl);line-height:.92;text-wrap:balance;
}
.err h1 .grad{background:var(--grad-1);-webkit-background-clip:text;background-clip:text;color:transparent}
.err-lead{
  max-width:48ch;color:var(--ink-2);font-weight:var(--w-mid);
  font-size:var(--t-md);line-height:1.4;text-wrap:pretty;
}

/* ---------- footer ---------- */
footer{
  padding:var(--sp-8) var(--gut) var(--sp-6);border-bottom:1px solid var(--line);
}
.footer-lead{
  display:grid;grid-template-columns:1.1fr .9fr;gap:var(--sp-8);align-items:end;
  padding-bottom:var(--sp-8);border-bottom:1px solid var(--line)
}
.footer-lead h2{
  margin-top:var(--sp-3);font-size:var(--t-xl);font-weight:var(--w-black);line-height:.92;
  letter-spacing:-.03em;text-transform:uppercase
}
.footer-lead h2 span{background:var(--grad-1);-webkit-background-clip:text;background-clip:text;color:transparent}
.footer-lead-copy{max-width:34ch;justify-self:end}
.footer-lead-copy p{color:var(--ink-2);font-size:var(--t-md);font-weight:var(--w-mid);line-height:1.35}
.footer-grid{
  /* max-content + space-between em vez de fr: com fr cada coluna esticava pra largura
     proporcional do container, muito mais larga que o próprio conteúdo, com o texto grudado
     à esquerda e um vão vazio à direita. */
  display:grid;grid-template-columns:repeat(4,max-content);justify-content:space-between;
  gap:var(--sp-7);padding-top:var(--sp-7)
}
footer h3{
  font-size:var(--t-xs);font-weight:var(--w-black);text-transform:uppercase;
  letter-spacing:.08em;margin-bottom:var(--sp-2);color:var(--ink-3);
}
footer a{display:block;font-weight:var(--w-mid);padding:var(--sp-1) 0;font-size:var(--t-sm);transition:color var(--transition-hover),text-decoration-color var(--transition-hover)}
footer a:hover{color:var(--color-hover);text-decoration:underline;
  text-decoration-color:var(--magenta);text-decoration-thickness:2px;
  text-underline-offset:4px}
.footer-label{display:block;margin-top:var(--sp-4);color:var(--ink-3);font-size:var(--t-xs);font-weight:var(--w-bold);text-transform:uppercase;letter-spacing:.06em}
.footer-contact p{max-width:23ch;color:var(--ink-2);font-size:var(--t-sm);line-height:1.5}
.footer-link{margin-top:var(--sp-4);color:var(--navy);font-weight:var(--w-bold);text-decoration:underline;text-underline-offset:3px}
.legal{
  display:flex;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-4) max(var(--gut),env(safe-area-inset-right))
          max(var(--sp-4),env(safe-area-inset-bottom)) max(var(--gut),env(safe-area-inset-left));
  color:var(--ink-3);font-weight:var(--w-mid);font-size:var(--t-sm);
}

/* ---------- telas médias ----------
   Entre 861px e 1100px o painel de 44vw cobre justamente a coluna de texto da linha que o
   disparou — não existe largura em que caiba sem sobrepor o que a pessoa lê, então nessa
   faixa ele não aparece. Aceitável porque nada vive exclusivamente no painel: ele é realce,
   e um realce pode faltar. */
@media (max-width:1100px){
  #reveal{display:none}
  /* Nenhuma seção de linha tem painel abaixo daqui — ".c3" (sempre visível na própria linha)
     é o equivalente do descritivo do desktop. 18px, não 24px como lá: ".c3" convive na mesma
     linha que ".c2" (título, ~16px), e 24px inverteria a hierarquia visual entre os dois. */
  .row .c3{font-size:1.125rem;font-weight:var(--w-bold);text-transform:uppercase}
  .err-code{max-width:min(320px,64vw)}   /* 404.html: lettering menor em tela estreita */
}

/* ---------- mobile ---------- */
@media (max-width:860px){
  header{grid-template-columns:1fr auto}
  .header-actions{display:none}
  .js .nav-toggle{display:inline-flex;align-items:center;justify-content:center}
  .js nav{display:none}
  nav .lang-toggle{display:inline-flex}
  .js header[data-nav-aberto] nav{
    display:flex;flex-direction:column;gap:var(--sp-1);
    grid-column:1 / -1;padding-top:var(--sp-4);font-size:var(--t-base);
  }
  .js header[data-nav-aberto] nav a{padding:var(--sp-3) 0}
  #reveal{display:none}
  .row{grid-template-columns:56px 1fr;grid-auto-rows:auto}
  .row .c3{grid-column:2}
  /* Depoimentos: número inline com o nome, cargo com a linha inteira. Coluna do número em
     56px — igual a .row/.sec-head — pra o nome começar no MESMO x que o título de seção; com
     "auto" ela encolhia pro tamanho de "01" e o nome saía ~38px desalinhado do resto.
     ⚠️ O seletor tem que ser ".row.dep-row>summary" (as 2 classes, como a regra de desktop):
     com só ".dep-row>summary" a especificidade fica MENOR e o @media perde a cascata mesmo
     casando a condição — falha invisível na leitura do CSS, só getComputedStyle pega. */
  .row.dep-row>summary{grid-template-columns:56px 1fr}
  .dep-row>summary .c1::after{content:" · "}
  .dep-row>summary .c3{grid-column:1 / -1}
  .sec-head{grid-template-columns:56px 1fr}
  .sec-head .note{display:none}
  .testimonials-intro{display:block}
  .testimonials-intro h3{max-width:16ch;margin-top:var(--sp-3);font-size:clamp(1.5rem,8vw,2.4rem)}
  .testimonials-intro p{margin-top:var(--sp-4)}
  /* <figure> aberto pelo accordion: empilhado, a coluna é 1fr e o retrato
     tomaria a largura toda se não travasse a largura dele. */
  .quote{grid-template-columns:1fr;gap:var(--sp-4);max-width:100%}
  .quote::before,.quote img{width:var(--foto);justify-self:start;grid-area:1 / 1}
  .quote blockquote{grid-area:2 / 1}
  .quote figcaption{grid-area:3 / 1}
  .q1,.q2,.q3,.q4{--foto:5.5rem}
  .clients{--k:.62}
  .footer-lead{display:block}
  .footer-lead-copy{max-width:38ch;margin-top:var(--sp-6);justify-self:auto}
  .footer-grid{grid-template-columns:1fr 1fr;gap:var(--sp-6) var(--sp-5)}
}

@media (max-width:540px){
  .footer-grid{grid-template-columns:1fr}
}

/* ---------- movimento reduzido ----------
   WCAG 2.3.3 e sensibilidade vestibular. Único mecanismo de pausa do marquee (AD-013): quem
   não seta a preferência no SO não tem outro jeito de parar a animação, trade-off aceito.
   O foco não entra aqui — reduzir movimento nunca pode reduzir a visibilidade do foco. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .clients .track{animation-play-state:paused}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* ---------- estado pressionado ----------
   :active dá o retorno de toque no celular, que é justamente onde não existe hover. */
.hero-meta .pill:active,.cta .actions a:active,
.nav-toggle:active,.lang-toggle:active,.skip:active{transform:translateY(1px)}
nav a:active,footer a:active,.row .c3 a:active,.legal a:active{
  text-decoration:underline;text-decoration-thickness:3px;
}
