/* ===================== TOKENS ===================== */
:root{
  --bg: #d5cfbe;
  --bg-card: #ebeada;
  --bg-card-alt: #e4e0ce;
  --ink: #0a0a0a;
  --ink-soft: rgba(10,10,10,.62);
  --ink-faint: rgba(10,10,10,.4);
  --dark: #0a0a0a;
  --dark-soft: rgba(255,255,255,.7);
  --accent: #f5f513;
  --accent-ink: #0a0a0a;
  --gray: #a6a6a6;
  --line: rgba(10,10,10,.12);

  --radius-sm: 10px;
  --radius-md: 20px;
  --radius-lg: 32px;

  --font-body: 'General Sans', Arial, sans-serif;
  --font-display: 'Clash Display', 'General Sans', Arial, sans-serif;

  --container: 1240px;
  --nav-h: 84px;
}

*{box-sizing:border-box; margin:0; padding:0;}
html{scroll-behavior:auto;}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%; display:block;}
a{color:inherit; text-decoration:none;}
ul{list-style:none;}
button{font:inherit; background:none; border:0; cursor:pointer; color:inherit;}
.container{width:100%; max-width:var(--container); margin:0 auto; padding:0 32px;}

h1,h2,h3{font-family:var(--font-display); font-weight:600; letter-spacing:-.02em; line-height:1.04;}

/* máscara usada pelo splitLines() — cada linha desliza de baixo pra cima */
.quebra-mobile{ display:none; }
.line-mask{ display:block; overflow:hidden; padding-bottom:.06em; }
.line{ display:block; will-change:transform; }
.word{ display:inline-block; }

.tag{
  display:inline-block;
  font-size:13px;
  font-weight:600;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink-soft);
  margin-bottom:18px;
}
.section-title{
  font-size:clamp(34px, 5vw, 64px);
  margin-bottom:20px;
}
.section-lead{
  max-width:560px;
  font-size:18px;
  color:var(--ink-soft);
}

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  padding:14px 28px;
  border-radius:var(--radius-sm);
  font-size:15px;
  font-weight:600;
  white-space:nowrap;
  transition:transform .35s cubic-bezier(.16,1,.3,1), background .3s ease;
}
.btn--dark{ background:var(--dark); color:#fff; }
.btn--dark:hover{ transform:translateY(-2px); }
.btn--ghost{ background:transparent; border:1px solid var(--ink); }
.btn--ghost:hover{ background:var(--ink); color:#fff; }
.btn--pill{ background:var(--bg-card); font-size:13px; padding:10px 20px; }
.btn--lg{ font-size:20px; padding:20px 40px; border-radius:var(--radius-md); }

/* ===================================================================
   SHELL — header que faz morph de HERO para SIDEBAR
   Estado natural = sidebar. `.is-hero` reposiciona para o hero.
   =================================================================== */
:root{ --sidebar-w: 236px; --sidebar-gap: 18px;
       --main-pad: calc(236px + 18px * 2); --photo-drop: calc(7.98vw - 8.5vh);
       /* eixo vertical compartilhado pela coluna esquerda e recuos da direita */
       --hero-pad: clamp(40px, 4vw, 72px);
       --hero-pad-dir: clamp(20px, 1.6vw, 28px);
       --stats-w: clamp(310px, 20vw, 336px);
       --traits-w: clamp(170px, 12vw, 198px);
       --grupo-gap: clamp(40px, 3.4vw, 64px);
       --hero-band: 42%;  /* ver nota em .shell__photo img */ }

.shell{
  position:fixed; top:var(--sidebar-gap); left:var(--sidebar-gap);
  width:var(--sidebar-w); height:calc(100vh - var(--sidebar-gap) * 2);
  z-index:40;
  pointer-events:none;
}
.shell > *{ pointer-events:auto; }

.shell__col{
  display:flex; flex-direction:column; gap:10px;
  height:100%;
}

/* --- peças (estado sidebar) --- */
.brand{
  font-family:var(--font-display); font-weight:700; font-size:19px;
  color:var(--ink); background:var(--accent);
  align-self:flex-start; padding:6px 12px; border-radius:8px;
  line-height:1;
}
.brand span{ font-size:10px; vertical-align:super; }

.stats{ display:flex; gap:8px; }
/* painel do original: rgba(194,184,172,.3) + blur(15px), raio 7px.
   Mesmo painel nos dois estados — `backdrop-filter` não interpola bem,
   e o fosco funciona tanto sobre a foto quanto sobre o fundo. */
/* O fundo é uma CAMADA à parte (mesmo padrão do .panel__bg): no hero os
   números vivem direto sobre o bege, no sidebar voltam a ser card. Não dá
   para só zerar o alpha — `backdrop-filter` continua borrando mesmo com o
   fundo transparente. */
.stat{
  flex:1; border-radius:8px; padding:12px;
  position:relative;
}
.stat::before{
  content:""; position:absolute; inset:0;
  border-radius:8px;
  background:rgba(194,184,172,.3);
  backdrop-filter:blur(15px);
  opacity:var(--stat-bg, 1);
}
.stat > *{ position:relative; }
/* cor é animada pelo GSAP (amarelo/branco no hero → escuro no sidebar):
   o CSS de `.is-hero` não vale durante o scroll. */
.stat b{ display:block; font-family:var(--font-display); font-size:24px; line-height:1; }
.stat span{ display:block; font-size:10px; font-weight:500; line-height:1.1; margin-top:4px; }

/* ---- painéis do sidebar ----
   Valores do original: fundo rgba(223,222,206,.8) + blur(15px), raio 7px.
   O fundo é um elemento à parte porque o conteúdo (stats, nav) precisa
   ficar visível no hero, onde o painel ainda não existe. */
.panel{ position:relative; padding:14px; }

/* ---- entrada da página ----
   Como no original: o wordmark aparece sozinho por um instante antes do
   resto. `.panel` não entra no morph (só as folhas entram — ver
   comentário de `morphItems` no JS), então escondê-lo aqui não contamina
   a medição do Flip. A foto usa `.shell__photo img`, não o container: o
   container tem `data-hero-fade` e é dono do morph (que reconstrói em
   load/fonts/resize e reescreve sua opacity) — brigar por essa mesma
   propriedade faria o container vencer e cancelar o fade. A `<img>` de
   dentro não pertence a nenhum dos dois sistemas. Só com JS rodando
   (classe .js, marcada antes do CSS pintar): sem ela, ou se o script
   falhar, tudo nasce visível — nunca fica preso invisível por falta de
   script. */
.js .panel, .js .shell__photo-nitida, .js .shell__photo-fade{ opacity:0; }
.panel__bg{
  position:absolute; inset:0;
  background:rgba(223,222,206,.8);
  backdrop-filter:blur(15px);
  border-radius:8px;
  opacity:0;               /* o GSAP traz no fim do scroll */
}
.panel > *:not(.panel__bg){ position:relative; }
.panel__head{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
.socials{ display:flex; gap:6px; }
.socials a{
  width:22px; height:22px; border-radius:5px; background:var(--ink);
  display:grid; place-items:center;
}
.socials svg{ width:11px; height:11px; color:#fff; }
.panel__desc{ font-size:11px; line-height:1.45; color:var(--ink-soft); margin-top:10px; }

.stats__sep{ width:1px; align-self:stretch; background:var(--line); flex:0 0 auto; }

.menu{ display:flex; flex-direction:column; gap:5px; }
.menu a{
  position:relative;
  display:flex; align-items:center; gap:7px;
  font-size:12px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:7px 10px; border-radius:7px;
  /* alfa animado pelo morph em vez de `background-color` direto: o
     GSAP escreveria a cor INLINE em todo link, e inline vence a
     classe .is-active — o amarelo do item atual nunca aparecia. */
  background:rgba(var(--pill-rgb, 235,234,218), var(--pill-a, 1));
  align-self:flex-start;
  transition:background .25s ease, color .25s ease;
}
.menu a svg{ width:13px; height:13px; flex:0 0 auto; }
/* O amarelo do item atual só existe depois que a sidebar se forma. No
   hero o original não destaca nenhum item — "HOME" saía amarelo aqui
   porque o scrollspy marca desde o topo da página. */
.shell.is-docked .menu a.is-active{ background:var(--accent); }
.menu a:hover{ background:var(--accent); }

/* Separador do hero. No original é um filete real (0.9px, rgba(0,0,0,.1)),
   não o glifo "|" — o glifo herda a altura da fonte e fica alto demais.
   Fica sempre no DOM porque `.is-hero` só está ligada durante a medição;
   no scroll quem manda é o GSAP, que não anima `content`. Absoluto para
   não alterar o layout de nenhum dos dois estados. */
.menu a::after{
  content:"";
  position:absolute; left:calc(100% + 0.2vw); top:50%;
  transform:translateY(-50%);
  width:1px; height:15px;
  background:currentColor;
  /* fallback 0: sem ele, `--sep` indefinido invalida a declaração e a
     opacidade volta para 1, mostrando os filetes no overlay mobile. */
  opacity:calc(var(--sep, 0) * .3);
  pointer-events:none;
}
.menu a:nth-child(3)::after,
.menu a:nth-last-child(2)::after,
.menu a:last-child::after{ content:none; }

/* Item corrente no HERO: sublinhado amarelo. A pílula preenchida é do
   sidebar (`.is-docked`) e ali ficaria pesada demais sobre o bege.
   `--sep` já vale 1 no hero e 0 no sidebar, então serve de chave de estado
   sem precisar de outro gatilho. */
.menu a::before{
  content:"";
  position:absolute; left:10px; right:10px; bottom:1px;
  height:2px; border-radius:2px;
  background:var(--accent);
  opacity:calc(var(--sep, 0) * var(--nav-ativo, 0));
  pointer-events:none;
}
.menu a.is-active{ --nav-ativo:1; }
.menu .lang-toggle{ min-width:34px; justify-content:center; }
.menu .lang-toggle::before,
.menu .lang-toggle::after{ content:none; }

/* Faixa de instituições: os nomes acendem em sequência, um de cada vez.
   O vão entre os nomes precisa ser MUITO maior que o espaço interno de
   "REDE CERRADO" — com os 10px antigos contra ~2,5px de espaço da fonte,
   os dois nomes colavam e a faixa lia "REDECERRADO SENADO TCU". */
/* Faixa de instituições em movimento contínuo — mesma mecânica da
   `.nav-comapny-wrap` do original: janela com `overflow:hidden`, duas
   cópias idênticas lado a lado e AMBAS deslizando de 0 a -100% da
   PRÓPRIA largura, no mesmo tempo e sem atraso. Quando a primeira sai
   por completo, a segunda ocupa exatamente a posição inicial dela — o
   laço não tem emenda visível e não precisa de JS.

   O original roda 666px em 25s = 26,6 px/s. Nossa cópia mede ~206px,
   então 8s dá 25,7 px/s — a mesma cadência. */
.clients-strip{
  display:flex; align-items:center;
  overflow:hidden;
  background:rgba(255,255,255,.35); border-radius:12px;
  /* recuo só à esquerda, como no original: os nomes saem rentes à borda
     direita em vez de pararem antes dela */
  padding:10px 0 10px 12px;
}
.clients-strip__pista{
  display:flex; align-items:center; gap:16px;
  /* o vão também DEPOIS do último nome: é ele que mantém o espaçamento
     na emenda entre a cópia 1 e a cópia 2 */
  padding-right:16px;
  flex:0 0 auto;
  animation:clientes-passa 8s linear infinite;
}
.clients-strip span{
  font-family:var(--font-display); font-size:10px; font-weight:700;
  /* o vão de 16px entre nomes precisa ser muito maior que o espaço
     interno de "REDE CERRADO" (3,8px), senão os dois colam e a faixa lê
     "REDECERRADO SENADO TCU" */
  letter-spacing:.04em; word-spacing:.2em; white-space:nowrap;
  color:var(--ink); opacity:.55;
}
@keyframes clientes-passa{
  from{ transform:translateX(0); }
  to  { transform:translateX(-100%); }
}
@media (prefers-reduced-motion: reduce){
  .clients-strip__pista{ animation:none; }
  .clients-strip__pista[aria-hidden]{ display:none; }
}

.email-row{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  background:rgba(255,255,255,.4); border-radius:8px; padding:9px 12px;
}
.email-row span{ font-size:11px; color:var(--ink-soft); }
.email-row__copy{ display:grid; place-items:center; opacity:.5; }
.email-row__copy svg{ width:13px; height:13px; }
.email-row__copy:hover{ opacity:1; }

.cta{ margin-top:auto; }
.btn--accent{ background:var(--accent); color:var(--ink); }
.btn--accent:hover{ transform:translateY(-2px); }

/* CTA secundário: só contorno, para o amarelo do primário carregar a ação */
.btn--outline{
  background:transparent; color:var(--ink);
  box-shadow:inset 0 0 0 1px rgba(10,10,10,.45);
}
.btn--outline:hover{ transform:translateY(-2px); background:rgba(10,10,10,.06); }

/* Ordem de empilhamento do hero (do fundo para a frente), igual ao original:
   1. wordmark amarelo  2. foto  3. textos/cards/nav
   No original a foto tem z-index:10 e o wordmark z-index:auto. */
.shell__photo{
  position:fixed; inset:0; z-index:2;
  display:flex; align-items:flex-end; justify-content:center;
  pointer-events:none;
}
/* A copia desfocada e um recurso EXCLUSIVO do hero mobile (dissolve a
   base do retrato no bege). No desktop ela nao tem mascara e ficaria
   como uma segunda foto borrada sobre a primeira. */
.shell__photo-fade{ display:none; }
.shell__photo img{
  height:85.5vh; width:auto; max-width:none;
  object-fit:contain; object-position:bottom center;
  /* Desce a foto para liberar os contornos do wordmark: a cabeça cruza só
     a parte de baixo das letras. Corta a base do corpo, que sai da viewport.

     O deslocamento é derivado da altura do wordmark, não um valor fixo em
     vh: o wordmark escala em vw e a foto se posiciona em vh, então em telas
     de proporção diferente (ex.: 890x630) os dois se desacoplavam e a
     sobreposição caía de 35% para 3%.
       altura do wordmark = 18vw * 0.818 = 14.7vw
       base               = 1.5vh + 14.7vw
       topo da cabeça     = base - 35% da altura = 1.5vh + 9.56vw
       topo natural       = 100vh - 96vh = 4vh
       deslocamento       = 9.56vw - 2.5vh                                */
  transform:translateY(var(--photo-drop, 0));
}
.shell__col{ position:relative; z-index:3; }
.shell__hero-only{ z-index:3; }

/* wordmark gigante — invisível no sidebar, gigante no hero */
.wordmark{
  position:absolute; top:6px; left:0; z-index:1;
  width:130px; aspect-ratio:1300 / 190;
  color:var(--accent); opacity:0; pointer-events:none;
}
.wordmark-svg{ display:block; width:100%; height:auto; overflow:hidden; }
.wordmark-svg text{
  fill:currentColor; font-family:var(--font-display); font-size:176px;
  font-weight:700; letter-spacing:-.045em;
}
.wordmark-svg path{ fill:currentColor; }
/* Reforço sutil do desenho vetorial no desktop. O contorno usa a mesma cor
   do preenchimento, então encorpa as hastes sem mudar paths, espaçamento,
   dimensões do SVG ou as medidas usadas pela animação/morph. */
.wordmark-svg--desktop .wordmark-letter:not(.wordmark-letter--reg){
  stroke:currentColor;
  stroke-width:2.2;
  stroke-linejoin:round;
  paint-order:stroke fill;
}
.wordmark-letter{ transform-box:fill-box; transform-origin:center; }
.wordmark-svg text .wordmark-letter--reg{ font-size:38px; letter-spacing:0; }
.wordmark-svg--mobile{ display:none; }

/* O proprio SVG faz a entrada e permanece no quadro final.
   Sem JS, o wordmark continua visivel. */
.js .wordmark{ visibility:hidden; }
.js.hero-intro-ready .shell > .wordmark,
.js.wordmark-intro-complete .shell > .wordmark{ visibility:visible; }
.js:not(.hero-intro-ready) .hero-title,
.js:not(.hero-intro-ready) .hero-kicker,
.js:not(.hero-intro-ready) .hero-note,
.js:not(.hero-intro-ready) .hero-buttons,
.js:not(.hero-intro-ready) .traits{ opacity:0; }

/* conteúdo só-hero */
/* fixed (não absolute) — precisa medir a viewport toda, e o .shell
   encolhe para 236px no estado sidebar */
.shell__hero-only{ position:fixed; inset:0; pointer-events:none; }
.shell__hero-only > *{ position:absolute; pointer-events:auto; }

/* 58%: o queixo cai em ~56% da viewport (foto tem altura em vh e o deslo-
   camento também, então a proporção se mantém em qualquer altura de tela).
   O título entra logo abaixo, sobre o peito — como no original. */
.hero-title{
  left:50%; top:65%; transform:translateX(-50%);
  width:max-content; text-align:center;
  /* limita pelos dois eixos: só com vw, telas baixas (ex.: 1366x640) fazem
     as 3 linhas invadirem os botões. */
  font-size:clamp(28px, min(4.9vw, 7.4vh), 70px);
  color:#fff; line-height:.95;
}
.hero-kicker{ left:2vw; bottom:8vh; font-size:15px; line-height:1.4; }
.hero-note{ right:2vw; bottom:7vh; width:min(300px, 24vw); font-size:14px; line-height:1.5; color:var(--ink-soft); }
.traits{
  left:calc(50% + max(15vw, 219px)); right:auto; top:56%;
  transform:translateY(-15%);
  background:rgba(255,255,255,.32); border-radius:14px; padding:14px 18px;
  display:flex; flex-direction:column; gap:7px;
}
/* Um ícone por qualidade (lâmpada, escudo, alvo, chave, raio) no lugar do
   quadradinho genérico — cada um diz o que a palavra diz. */
.traits li{ font-size:13px; font-weight:700; display:flex; align-items:center; gap:9px; }
.traits li svg{ width:15px; height:15px; flex:0 0 auto; color:var(--accent); }
.hero-buttons{ left:50%; bottom:5.5vh; transform:translateX(-50%); display:flex; gap:12px; }

.burger{ display:none; }

/* ---------- ESTADO HERO ---------- */
.shell.is-hero{
  top:0; left:0; width:100vw; height:100vh;
}
.shell.is-hero .shell__col{ display:block; height:100%; }

/* Os filhos diretos da coluna agora são os .panel, então o `position:
   absolute` tem de mirar as PEÇAS, não os painéis. No hero os painéis
   colapsam (static, sem padding) para que as peças resolvam suas
   coordenadas contra .shell__col e não contra a caixa de 236px. */
.shell.is-hero .panel{ position:static; padding:0; }
.shell.is-hero .panel__bg,
.shell.is-hero [data-panel-only]{ opacity:0; }
.shell.is-hero .brand,
.shell.is-hero .stats,
.shell.is-hero .menu,
.shell.is-hero .clients-strip,
.shell.is-hero .email-row,
.shell.is-hero .cta{ position:absolute; }

/* Linha única ocupando ~94% da largura, como o NESH do original.
   Com 11 caracteres o corpo fica em ~15vw; o tracking negativo fecha
   as letras para o bloco ganhar peso. */
/* Corpo maior + condensação horizontal: com 11 caracteres (contra 4 do
   NESH) a única forma de ganhar altura mantendo a largura da viewport é
   estreitar as letras. O morph trata scaleX/scaleY separadamente. */
/* Corpo maior + condensação horizontal: com 11 caracteres (contra 4 do
   NESH) a única forma de ganhar altura mantendo a largura da viewport é
   estreitar as letras. O morph trata scaleX/scaleY separadamente.

   Testado a 30.4vw/.513 para igualar os 44% de altura do NESH: bate o
   alvo, mas as letras ficam na metade da largura e o título cai de 70px
   para 42px — o queixo vai a 69% e sobra pouco até os botões. Não
   compensa. */
.shell.is-hero .wordmark{
  opacity:1;
  width:80vw; aspect-ratio:1300 / 190;
  left:10vw; top:0;
  transform:none;
}
.shell.is-hero .brand{ opacity:0; left:2vw; top:2vh; }
/* Posições conferidas contra o original (em % da viewport): nav em 64%,
   traits iniciando em ~53%, cards de stats de 17.6% a 32.9% na horizontal.

   Ancorados no CENTRO, não nas bordas: no original os cards ladeiam o
   título de perto. Preso à lateral em vw, a folga variava muito porque a
   largura do card é fixa em px.

   O piso de 190px é necessário porque o título ocupa proporcionalmente
   MAIS largura em telas estreitas (o corpo é limitado por vh): só com
   13vw a folga caía para 2px em 768. O translateY centra o bloco na
   altura do título — sem ele o segundo card batia no rodapé em 640. */
.shell.is-hero .stats{
  right:calc(50% + max(17vw, 219px)); left:auto; top:65%;
  transform:translateY(-19%);
  flex-direction:column; gap:34px; width:190px;
}
/* Os dois cards do original NÃO são o mesmo componente repetido.
   Medido na captura (em % da viewport):
     "80+"  15.3 x 14.8  -> proporção 1.03 (quase quadrado)
     "7+"    9.7 x 18.9  -> proporção 0.51 (retrato)
   O primeiro é 1.58x mais largo, o segundo 1.28x mais alto, e o segundo
   ainda entra recuado. O corpo do número também difere. */
.shell.is-hero .stats{ align-items:flex-start; }

.shell.is-hero .stat--wide{
  width:100%;
  /* padding vertical alto de propósito: o layout horizontal deixa o card
     achatado (proporção 1.53) e o do original é quase quadrado (1.03).
     107px de altura = 34 do número + 36 de respiro em cima e embaixo. */
  padding:36px 22px;
  display:flex; align-items:center; gap:14px;    /* número ao lado do rótulo -> fica largo */
}
.shell.is-hero .stat--wide b{ font-size:34px; }
.shell.is-hero .stat--wide span{ font-size:12.5px; }

.shell.is-hero .stat--tall{
  width:64%;                                     /* 9.7/15.3 do card largo */
  margin-left:22%;                               /* recuo de ~3.3 pontos */
  padding:22px 20px 26px;
}
.shell.is-hero .stat--tall b{ font-size:46px; }  /* o número grande do original */
.shell.is-hero .stat--tall span{ font-size:12.5px; margin-top:8px; }

/* Como no original: dois grupos compactos (3 à esquerda, 4 à direita)
   com um vão no meio para a foto — não espalhados de ponta a ponta.
   `margin-right:auto` no 3º item empurra o resto para a direita. */
.shell.is-hero .menu{
  flex-direction:row; align-items:center; justify-content:flex-start;
  /* 34%: logo abaixo da base do wordmark (~28%) e bem acima dos cards
     (traits em 53%, stats em 57%). O original põe o nav em 64%, mas lá ele
     passa POR TRÁS dos cards — "PROJECTS" fica meio escondido atrás do
     card de stats. Aqui vale a legibilidade: nenhum item é encoberto. */
  left:0; top:34%; width:100vw; padding:0 calc(var(--hero-pad) - 10px); gap:0.4vw;
}
/* padding igual ao do sidebar: o morph alinha as CAIXAS, então diferença
   de padding deslocaria o texto dentro delas. */
.shell.is-hero .menu a{
  background:transparent; padding:7px 12px;
  /* fluido: o original vai de 16px em 1280 para 12px em 890 */
  font-size:clamp(11px, 1.16vw, 15px); font-weight:700; letter-spacing:.05em;
}
.shell.is-hero .menu a:nth-child(3){ margin-right:auto; }

.shell.is-hero .clients-strip,
.shell.is-hero .email-row{ opacity:0; left:2vw; bottom:2vh; }
.shell.is-hero .cta{ opacity:0; left:2vw; bottom:2vh; }

/* A coluna do sidebar precisa caber na altura da viewport: com os painéis
   o conteúdo passou a medir ~691px e o botão saía da tela em telas de
   630-680. O original escala o container inteiro; aqui aperto os
   espaçamentos, o que mantém o texto legível em vez de encolher tudo. */
@media (max-height: 780px){
  .shell__col{ gap:7px; }
  .panel{ padding:11px; }
  .panel__desc{ font-size:10px; line-height:1.35; margin-top:8px; }
  .menu{ gap:3px; }
  .menu a{ padding:5px 9px; }
  .stat{ padding:9px; }
  .stat b{ font-size:20px; }
}
@media (max-height: 660px){
  .panel__desc, .clients-strip{ display:none; }
}



/* Seção escura em largura cheia, passando POR TRÁS da sidebar — no
   original a `.work_section` mede 0→100% da viewport e o
   `elementFromPoint` no canto esquerdo devolve ela, não o fundo claro.
   Aqui o `main` recua 272px pela sidebar, então a seção desfaz esse recuo
   na margem e o devolve no padding: o fundo vai de ponta a ponta, o
   conteúdo continua alinhado. `calc(100% + pad)` em vez de `100vw` para
   não somar a barra de rolagem e criar overflow. */
[data-theme="dark"]{
  margin-left:calc(-1 * var(--main-pad));
  width:calc(100% + var(--main-pad));
  /* SEM padding-left aqui: o `.work__sticky` tem overflow:hidden e herdaria
     essa caixa, recortando a trilha na borda da sidebar — os cards ficavam
     cortados em vez de passar por trás. Quem recua é só o cabeçalho. */
}

/* ===================================================================
   SIDEBAR SOBRE SEÇÃO ESCURA
   Quando um bloco `data-theme="dark"` cobre o miolo da tela, a sidebar
   inverte — como no original, que troca os elementos por variantes claras
   (`.happy-ring-white`, `.semiconbio-white`). Aqui um tema CSS faz o mesmo
   com bem menos DOM.

   `--pill-rgb` existe para o tema trocar a cor da pílula sem `!important`:
   o alfa é animado pelo morph e brigar com ele por especificidade
   custaria caro. O `.stat span` é a exceção — ali o GSAP escreve `color`
   INLINE, e só `!important` vence.
   =================================================================== */
.shell.is-dark{ --pill-rgb: 42,42,40; }
.shell.is-dark .panel__bg{ background:rgba(18,18,16,.72); }
.shell.is-dark .panel__desc{ color:rgba(255,255,255,.58); }
.shell.is-dark .stat{ background:rgba(255,255,255,.07); }
.shell.is-dark .stat span{ color:#fff !important; }
.shell.is-dark .stats__sep{ background:rgba(255,255,255,.16); }
.shell.is-dark .menu a{ color:#fff; }
.shell.is-dark.is-docked .menu a.is-active,
.shell.is-dark .menu a:hover{ background:var(--accent); color:var(--ink); }
.shell.is-dark .clients-strip{ background:rgba(255,255,255,.07); }
/* só a cor base muda; a opacidade continua sendo da animação */
.shell.is-dark .clients-strip span{ color:#fff; }
.shell.is-dark .email-row{ background:rgba(255,255,255,.07); }
.shell.is-dark .email-row span{ color:rgba(255,255,255,.62); }
.shell.is-dark .email-row__copy{ color:#fff; }
.shell.is-dark .socials a{ background:#fff; }
.shell.is-dark .socials svg{ color:var(--ink); }

/* a troca acompanha o scroll em vez de saltar */
.panel__bg, .stat, .menu a, .clients-strip, .clients-strip span,
.email-row, .socials a{
  transition:background-color .35s ease, color .35s ease;
}

/* espaçador que dá curso de scroll ao morph */
.shell-spacer{ height:100vh; }

/* conteúdo abre espaço para a sidebar */
main{ padding-left:var(--main-pad); }

/* ===================== JOURNEY (ziguezague vertical) ===================== */
.journey{ padding:140px 0 120px; }

.timeline{
  position:relative;
  margin-top:64px;
  display:flex; flex-direction:column;
  gap:clamp(40px, 7vh, 90px);
}

/* SVG cobre a caixa toda; o path é desenhado em JS a partir das âncoras
   reais dos cards, então acompanha qualquer largura ou altura. */
.timeline__svg{
  position:absolute; inset:0; width:100%; height:100%;
  overflow:visible; pointer-events:none; color:var(--ink);
}
.timeline__dot{
  position:absolute; top:0; left:0;
  width:11px; height:11px; border-radius:50%;
  background:var(--accent); border:2px solid var(--ink);
  transform:translate(-50%,-50%); opacity:0;
  pointer-events:none;
}

.tl-card{
  position:relative;
  width:min(460px, 62%);
  background:var(--bg-card);
  border-radius:var(--radius-lg);
  padding:32px 34px;
  display:grid; grid-template-columns:minmax(0,1fr) auto; column-gap:20px;
  opacity:0;                       /* o ScrollTrigger revela */
}
.tl-card--right{ align-self:flex-end; }
.tl-card--left{ align-self:flex-start; }

.tl-card__year{
  grid-column:1 / -1;
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(46px, 5.4vw, 76px); line-height:.9;
  color:var(--accent); -webkit-text-stroke:1px rgba(0,0,0,.14);
  margin-bottom:8px;
}
.tl-card__title{ grid-column:1 / -1; font-size:clamp(19px, 1.7vw, 25px); margin-bottom:10px; }
.tl-card__text{ grid-column:1 / -1; font-size:15px; color:var(--ink-soft); }

.tl-card__foot{ grid-column:1; align-self:end; display:flex; align-items:center; gap:10px; margin-top:22px; }
.tl-card__meta{ display:flex; flex-direction:column; font-size:13px; color:var(--ink-faint); }
.tl-card__meta b{ color:var(--ink); font-size:13.5px; line-height:1.2; }
.tl-card__meta span{ color:var(--ink-faint); font-size:12px; line-height:1.25; }

.tl-card__toggle{
  grid-column:2; align-self:end;
  width:auto; margin-top:22px; padding:11px 20px;
  border:1px solid rgba(54,54,54,.15); border-radius:12px;
  display:inline-flex; align-items:center; justify-content:center;
  background:#ebeada;
  font-family:var(--font-display); font-size:12px; font-weight:600;
  letter-spacing:.02em; text-transform:uppercase;
  color:var(--ink); text-align:center;
  transition:background-color .3s ease, transform .3s ease;
}
.tl-card__toggle i{
  position:relative; width:28px; height:28px; flex:0 0 28px;
  border-radius:50%; background:var(--accent); border:1px solid var(--ink);
  transition:transform .35s cubic-bezier(.16,1,.3,1);
}
.tl-card__toggle i::before,
.tl-card__toggle i::after{
  content:""; position:absolute; left:50%; top:50%;
  width:10px; height:1.5px; border-radius:2px; background:var(--ink);
  transform:translate(-50%,-50%);
}
.tl-card__toggle i::after{ transform:translate(-50%,-50%) rotate(90deg); }
.tl-card__toggle:hover{ background:var(--accent); transform:translateY(-1px); }
.tl-card__toggle:focus-visible{ outline:2px solid var(--ink); outline-offset:5px; }
.tl-card.is-expanded .tl-card__toggle i{ transform:rotate(45deg); }
.tl-card__toggle i{ display:none; }

.tl-card__details{
  display:grid; grid-template-rows:0fr;
  opacity:0; transition:grid-template-rows .42s cubic-bezier(.16,1,.3,1), opacity .28s ease;
}
.tl-card__details > div{ overflow:hidden; }
.tl-card__details p{
  padding-top:16px; font-size:14px; line-height:1.55; color:var(--ink-soft);
}
.tl-card.is-expanded .tl-card__details{ grid-template-rows:1fr; opacity:1; }

/* Detalhe da jornada — popup inspirado no componente do original.
   O conteudo continua no card e e copiado para um unico dialog acessivel. */
.tl-card__details{ display:none; }
.journey-popup{
  position:absolute; z-index:30; inset:-16px 0 auto;
  width:clamp(370px, 29.58vw, 600px); margin:auto;
  color:#fff; opacity:0; pointer-events:none;
}
.journey-popup.is-active{
  opacity:1; pointer-events:auto;
}
/* O ultimo detalhe cresce para cima: por ser absoluto, abrir para baixo
   atravessaria o limite da jornada e cobriria a secao de projetos. */
.tl-card:last-of-type .journey-popup{ inset:auto 0 -16px; }
.journey-dialog__card{
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; gap:clamp(42px, 5.5vw, 82px);
  min-height:min(670px, calc(100svh - 32px));
  padding:clamp(26px, 2.1vw, 42px);
  border:1px solid rgba(255,255,255,.28);
  border-radius:clamp(20px, 1.55vw, 30px);
  background:linear-gradient(201deg, #3b3d38, #222 48%, #444 98%);
  box-shadow:0 30px 90px rgba(0,0,0,.28);
  overflow:hidden;
}
.journey-dialog__tree{
  display:none; position:absolute; z-index:0; inset:-15%;
  width:130%; height:130%; max-width:none; object-fit:contain;
  opacity:.24; mix-blend-mode:screen; pointer-events:none;
}
.journey-dialog__tree.is-visible{ display:block; }
.journey-dialog__card > :not(.journey-dialog__tree){ position:relative; z-index:1; }
.journey-dialog__top{
  display:flex; justify-content:space-between; align-items:flex-start; gap:20px;
}
.journey-dialog__top strong{
  color:var(--accent); font-family:var(--font-display); font-weight:700;
  font-size:clamp(64px, 6vw, 100px); line-height:.82; letter-spacing:-.055em;
}
.journey-dialog__close{
  display:grid; place-items:center; flex:0 0 auto;
  width:clamp(48px, 3.1vw, 62px); height:clamp(48px, 3.1vw, 62px);
  border-radius:clamp(12px, .85vw, 17px);
  color:#aaa; background:#555652;
  font-size:clamp(35px, 2.7vw, 52px); font-weight:400; line-height:1;
  transition:color .25s ease, background .25s ease, transform .25s ease;
}
.journey-dialog__close:hover{ color:#fff; background:#646560; transform:rotate(90deg); }
.journey-dialog__close:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; }
.journey-dialog__body{ margin-top:auto; }
.journey-dialog__identity{ display:flex; align-items:center; margin-bottom:24px; }
.journey-dialog__identity span,
.journey-dialog__identity img{
  display:grid; place-items:center; width:64px; height:64px;
  border-radius:50%; object-fit:cover;
}
.journey-dialog__identity span{
  z-index:1; color:var(--ink); background:var(--accent);
  font-family:var(--font-display); font-size:22px; font-weight:700;
}
.journey-dialog__identity img{ margin-left:-13px; background:#62635f; object-position:50% 14%; }
.journey-dialog__body h3{
  max-width:12ch; margin:0 0 16px; color:#fff;
  font-size:clamp(36px, 3.1vw, 58px); line-height:1; letter-spacing:-.035em;
}
.journey-dialog__body > p{
  margin:0; color:rgba(255,255,255,.82);
  font-size:clamp(16px, 1.2vw, 21px); line-height:1.48;
}
.journey-dialog__meta{
  display:flex; justify-content:space-between; gap:18px;
  margin-top:24px; padding-top:18px; border-top:1px solid rgba(255,255,255,.18);
  color:rgba(255,255,255,.58); font-size:13px;
}
.journey-dialog__meta b{ color:#fff; font-weight:600; }

@media (prefers-reduced-motion:reduce){
  .tl-card__details, .tl-card__toggle i{ transition:none; }
  .work-card__rede-frame{ transition:none; }
}

@media (max-width:991px){
  /* Sem ziguezague no mobile: coluna única com um trilho vertical à
     esquerda e um ponto por card, como no original.

     O traçado em SVG é descartado aqui porque ele é gerado a partir das
     âncoras dos cards, que alternam entre a borda esquerda e a direita —
     em coluna única viraria um ziguezague atravessando a tela. O trilho
     abaixo é puro CSS: uma linha na `.timeline` e um ponto em cada card,
     então acompanha qualquer quantidade de cards sem depender do JS. */
  .timeline{ gap:26px; padding-left:34px; }
  .tl-card{ width:100%; align-self:stretch; padding:24px; }
  .timeline__svg, .timeline__dot{ display:none; }

  .timeline::before{
    content:""; position:absolute;
    left:7px; top:10px; bottom:10px; width:2px;
    background:var(--line);
  }
  /* ponto alinhado ao topo do card, na mesma faixa do ano */
  .tl-card::before{
    content:""; position:absolute; left:-34px; top:26px;
    width:16px; height:16px; border-radius:50%;
    background:var(--accent); border:2px solid var(--ink);
  }

  .journey-popup{
    inset:0; width:100%; max-width:none;
  }
  .tl-card:last-of-type .journey-popup{ inset:auto 0 0; }
  .journey-dialog__card{
    min-height:0;
    padding:26px 22px; border-radius:20px; gap:42px;
  }
  .journey-dialog__top strong{ font-size:clamp(62px, 20vw, 92px); }
  .journey-dialog__body h3{ font-size:clamp(34px, 10.5vw, 48px); }
  .journey-dialog__body > p{ font-size:16px; }
}

/* ===================== WORK (trilha horizontal pinada) =====================
   O ScrollTrigger pina a seção e converte scroll vertical em deslocamento
   horizontal da trilha; a vertical só volta quando a trilha acaba.
   O original faz o mesmo com position:sticky e uma pista de 2980px. */
.work{ background:var(--dark); color:#fff; }

/* Altura fixa de viewport com a trilha em flex:1 — o card mede exatamente
   o que sobra depois do cabeçalho. Antes o card tinha altura derivada da
   largura (aspect-ratio sobre 30vw) e o conjunto passava de 100vh: o
   overflow:hidden cortava o rodapé dos cards. */
.work__sticky{
  height:100vh;
  display:flex; flex-direction:column; justify-content:center;
  gap:26px;
  padding:44px 0;
  overflow:hidden;
}
.work__headwrap{ flex:0 0 auto; padding-left:var(--main-pad); }
.work__head .tag{ color:rgba(255,255,255,.55); }
.work__head .section-title{ color:#fff; }

/* barra de progresso da trilha */
.work__progress{
  margin-top:22px; width:min(280px, 40vw); height:2px;
  background:rgba(255,255,255,.18); border-radius:2px; overflow:hidden;
}
.work__progress i{ display:block; width:0%; height:100%; background:var(--accent); }

/* A trilha corre de ponta a ponta e passa POR TRÁS da sidebar, como no
   original. A seção já é full-bleed, mas seu padding-left empurraria a
   trilha para depois da sidebar — então a viewport desfaz esse recuo. */
.work__viewport{ width:100%; flex:1 1 auto; min-height:0; }
.work__track{
  display:flex; align-items:stretch; gap:26px;
  height:100%;
  /* recuo absoluto até onde o título começa: o recuo da sidebar mais a
     centragem do .container. Agora 100% é a viewport inteira, então o
     --main-pad precisa entrar na conta explicitamente. */
  padding-left:calc(var(--main-pad) + max(0px, (100% - var(--main-pad) - var(--container)) / 2) + 32px);
  padding-right:15vw;
  width:max-content;
  will-change:transform;
}

/* ===================================================================
   CARD DE PROJETO — QUATRO CAMADAS

     1. .work-card__media   base de cor (a cor dominante do projeto)
     2. .work-card__visual  a composicao editorial em SVG
     3. .work-card__scrim   overlay + vinheta, so para contraste
     4. conteudo            numero, tags, titulo, texto, botao

   O visual NUNCA recebe `opacity` baixa: apagar a midia inteira mata a
   composicao. Quem garante a legibilidade e o scrim, que e uma camada
   separada e so escurece onde o texto vive.
   =================================================================== */
.work-card{
  position:relative; flex:0 0 auto;
  height:100%; width:auto;
  aspect-ratio:5 / 6;
  min-width:250px; max-width:430px;
  border-radius:28px;
  overflow:hidden;
  isolation:isolate;
  background:var(--cor-base, #141412);
  display:flex; flex-direction:column; justify-content:space-between;
  padding:26px;
  --cor-base:#141412;
  --cor-alta:#2a2a26;
  --viz:rgba(255,255,255,.5);
}
.work-card::after{ content:""; position:absolute; inset:0; z-index:4; border:1px solid transparent; border-radius:inherit; opacity:0; pointer-events:none; transition:opacity .35s ease,box-shadow .35s ease; }

/* 1. base: a cor do projeto, com um leve gradiente de profundidade */
.work-card__media{
  position:absolute; inset:0; z-index:0;
  background:
    radial-gradient(120% 80% at 20% 0%, var(--cor-alta) 0%, transparent 60%),
    linear-gradient(160deg, var(--cor-alta) 0%, var(--cor-base) 55%, #0c0c0b 100%);
}

/* 2. composicao: ocupa a area central, entre as tags e o titulo */
.work-card__visual{
  position:absolute; z-index:1;
  left:26px; right:26px; top:20%; bottom:34%;
  display:flex; align-items:center; justify-content:center;
  transform-origin:50% 50%;
  transition:transform .6s cubic-bezier(.16,1,.3,1), opacity .5s ease;
}
.work-card__visual .vz{ width:100%; height:100%; overflow:visible; }
.work-card__rede-frame{ position:absolute; inset:0; z-index:3; width:100%; height:100%; object-fit:contain; opacity:0; pointer-events:none; transition:opacity .35s ease,transform .6s cubic-bezier(.16,1,.3,1); transform:scale(.94); }
.work-card--1:hover .work-card__rede-frame,
.work-card--1:focus-within .work-card__rede-frame,
.swiper-slide-active .work-card--1 .work-card__rede-frame{ opacity:1; transform:none; }
.work-card--1:hover .work-card__visual .vz,
.work-card--1:focus-within .work-card__visual .vz,
.swiper-slide-active .work-card--1 .work-card__visual .vz{ opacity:.04; transition:opacity .35s ease; }

/* paleta interna da composicao — herda a cor do card */
.vz-hair line{ stroke:var(--viz); stroke-width:1; opacity:.32; }
.vz-hair{ stroke:var(--viz); stroke-width:1; opacity:.32; }
.vz-edge path{ stroke:var(--viz); stroke-width:1.1; opacity:.42; }
.vz-node circle, circle.vz-node{ fill:var(--viz); opacity:.55; }
.vz-nodeStroke{ stroke:var(--viz); stroke-width:1.4; opacity:.55; fill:none; }
.vz-ring{ stroke:var(--viz); stroke-width:1.4; fill:none; opacity:.45; }
.vz-hub{ fill:var(--accent); }
.vz-bar{ fill:var(--viz); opacity:.24; }
.vz-fill{ fill:var(--accent); opacity:.72; }
.vz-arc{ stroke:var(--accent); stroke-width:6; fill:none; opacity:.85; }
.vz-arc2{ stroke:var(--viz); stroke-width:6; fill:none; opacity:.4; }
.vz-box{ fill:rgba(255,255,255,.05); stroke:var(--viz); stroke-width:1; stroke-opacity:.3; }
.vz-boxA{ fill:rgba(245,245,19,.16); stroke:var(--accent); stroke-width:1; stroke-opacity:.6; }
.vz-spark{ stroke:var(--accent); stroke-width:2; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.vz-sparkDot{ fill:var(--accent); }
.vz-check{ stroke:var(--accent); stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.work-card__visual text{ font-family:var(--font-body); fill:#fff; }
.vz-lbl{ font-size:8.5px; font-weight:700; letter-spacing:.14em; opacity:.55; }
.vz-mic{ font-size:7.5px; font-weight:600; letter-spacing:.08em; opacity:.5; }
.vz-micA{ font-size:7.5px; font-weight:700; letter-spacing:.08em; fill:var(--accent); }
.vz-txt{ font-size:9.5px; font-weight:500; opacity:.75; }
.vz-num{ font-family:var(--font-display); font-size:13px; font-weight:700; }
.vz-numA{ font-family:var(--font-display); font-size:13px; font-weight:700; fill:var(--accent); }
.vz-numS{ font-family:var(--font-display); font-size:11px; font-weight:700; fill:var(--accent); }
.vz-raci{ font-size:7px; font-weight:700; fill:var(--ink); }

/* 3. contraste: escurece embaixo (onde vive o texto) e nas bordas */
.work-card__scrim{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  background:
    linear-gradient(to top, rgba(8,8,7,.94) 0%, rgba(8,8,7,.78) 26%, rgba(8,8,7,.12) 52%, transparent 70%),
    radial-gradient(120% 100% at 50% 50%, transparent 52%, rgba(0,0,0,.5) 100%);
  transition:opacity .5s ease;
}

/* 4. conteudo */
.work-card__top,
.work-card__body{ position:relative; z-index:3; }
.work-card__top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.work-card__num{
  font-family:var(--font-display); font-size:12px; font-weight:700;
  background:rgba(0,0,0,.5); border:1px solid rgba(255,255,255,.16);
  border-radius:20px; padding:6px 11px; backdrop-filter:blur(6px);
}
.work-card__tags{
  display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end;
  transition:transform .5s cubic-bezier(.16,1,.3,1);
}
.work-card__tags span{
  font-size:11px; font-weight:600; white-space:nowrap;
  background:rgba(0,0,0,.5); border:1px solid rgba(255,255,255,.16);
  border-radius:20px; padding:6px 11px; backdrop-filter:blur(6px);
}

/* No card RedeS, a terceira tag acompanha a segunda linha da grade,
   evitando o desalinhamento causado pelo flex-wrap livre. */
.work-card--1 .work-card__tags{
  display:grid;
  grid-template-columns:auto auto;
  gap:6px;
  align-items:start;
  justify-content:end;
}
.work-card--1 .work-card__tags span:last-child{
  grid-column:2;
  justify-self:end;
}
.work-card__body h3{ font-size:clamp(21px, 2vw, 30px); margin-bottom:8px; }
.work-card__body p{
  font-size:14.5px; color:rgba(255,255,255,.75); max-width:34ch;
  /* a seta ocupa o canto inferior direito; sem esta faixa a ultima
     linha passa por baixo dela */
  padding-right:56px;
}
.work-card__arrow{
  position:absolute; right:26px; bottom:26px; z-index:4;
  width:44px; height:44px; border-radius:50%;
  background:var(--accent); color:var(--ink);
  display:grid; place-items:center;
  transition:transform .45s cubic-bezier(.16,1,.3,1), box-shadow .45s ease;
}
.work-card__arrow svg{ width:19px; height:19px; }
.work-card__arrow:focus-visible{ outline:2px solid #fff; outline-offset:4px; }

/* ---- paletas: profundas e dessaturadas, uma por projeto ---- */
.work-card--1{ --cor-base:#182018; --cor-alta:#4a3b1e; --viz:#a5b95d; }  /* Cerrado: terra, vegetacao e luz quente */
.work-card--2{ --cor-base:#0d1a2b; --cor-alta:#1b3554; --viz:#8fb8e6; }  /* azul institucional */
.work-card--3{ --cor-base:#1a1226; --cor-alta:#33244a; --viz:#bda6e0; }  /* roxo escuro */
.work-card--4{ --cor-base:#141b24; --cor-alta:#27384a; --viz:#a8bdd4; }  /* cinza azulado */
.work-card--5{ --cor-base:#231a10; --cor-alta:#463421; --viz:#d8b98d; }  /* marrom */
.work-card--6{ --cor-base:#231018; --cor-alta:#44202f; --viz:#e0a3b6; }  /* vinho */
.work-card--7{ --cor-base:#0f1e24; --cor-alta:#1e3b45; --viz:#93c6d4; }  /* petroleo frio */
.work-card--8{ --cor-base:#16152a; --cor-alta:#2b2950; --viz:#a9a6e2; }  /* indigo */
.work-card--9{ --cor-base:#181b25; --cor-alta:#30384c; --viz:#b7c4e5; }  /* azul de pesquisa */
.work-card--1 .work-card__media{ background:
  radial-gradient(90% 74% at 82% 2%, rgba(219,174,61,.34), transparent 48%),
  radial-gradient(70% 100% at 7% 28%, rgba(82,119,53,.54), transparent 66%),
  repeating-radial-gradient(ellipse at 34% 34%, transparent 0 24px, rgba(183,194,102,.08) 25px 26px, transparent 27px 42px),
  linear-gradient(155deg,#2b412b 0%,#1c2c1e 46%,#14120e 100%); }
.work-card--1 .work-card__visual{ isolation:isolate; }
.work-card--1 .work-card__visual::before{ content:""; position:absolute; inset:-14%; z-index:0; border:1px solid rgba(211,193,113,.2); border-radius:48% 52% 42% 58%; transform:rotate(-12deg); box-shadow:0 0 0 18px rgba(183,194,102,.035),0 0 0 38px rgba(183,194,102,.025); pointer-events:none; }
.work-card--1 .work-card__visual .vz{ opacity:.055; position:relative; z-index:1; }
.work-card--1 .work-card__rede-frame{ inset:-40%; width:180%; height:180%; max-width:none; opacity:.18; z-index:2; object-position:center center; }
.work-card--1:hover .work-card__visual,
.work-card--1:focus-within .work-card__visual{ transform:scale(1.025); }
.work-card--1:hover .work-card__rede-frame,
.work-card--1:focus-within .work-card__rede-frame{ filter:drop-shadow(0 10px 18px rgba(210,172,48,.22)); }

/* ---- desktop: hover ativa o card ---- */
@media (hover:hover) and (min-width:992px){
  .work-card{ transition:transform .55s cubic-bezier(.16,1,.3,1),box-shadow .55s cubic-bezier(.16,1,.3,1); }
  .work-card:hover .work-card__visual{ transform:scale(1.04); }
  .work-card:hover .work-card__scrim{ opacity:.86; }
  .work-card:hover .work-card__tags{ transform:translateY(-3px); }
  .work-card:hover .work-card__arrow{
    transform:scale(1.12) translate(2px,-2px);
    box-shadow:0 8px 26px rgba(245,245,19,.28);
  }
  .work-card.is-focused{ z-index:6; transform:translateY(-9px) scale(1.018); box-shadow:0 24px 46px rgba(0,0,0,.34),0 0 0 1px rgba(245,245,19,.25),0 0 34px rgba(170,166,63,.18); }
  .work-card.is-focused::after{ opacity:1; border-color:rgba(245,245,19,.72); box-shadow:inset 0 0 0 1px rgba(255,255,255,.16),inset 0 0 28px rgba(245,245,19,.08); }
  .work-card.is-focused .work-card__top{ transform:translateY(-2px); }
  .work-card.is-focused .work-card__body{ transform:translateY(-2px); }
}

@media (max-width:991px){
  /* Sem pin: o Swiper (buildWorkCarousel no JS) assume o toque. Nada de
     `overflow-x:auto` nem scroll-snap — o Swiper move por transform e
     traz o proprio `overflow:hidden` pela classe `.swiper`. */
  .work__sticky{ height:auto; padding:64px 0 72px; overflow:visible; }
  .work__viewport{ overflow:hidden; }
  /* `gap:0` e obrigatorio: o Swiper soma largura-do-slide + spaceBetween
     para o virtualSize e NAO enxerga o `gap` do flexbox. Com o gap:26px do
     desktop ativo, cada card ocupava 42px a mais do que ele contabilizava e
     o ultimo nunca era alcancado. O espacamento vem do `spaceBetween`. */
  .work__track{ padding:0; gap:0; }

  /* Enquadramento: 84% da viewport com proporcao 7/10, teto pela altura
     util para o card nunca estourar a tela. Os 16px de `spaceBetween`
     deixam ~48px do proximo card a mostra — convite para arrastar, sem
     revelar meio card. */
  .work-card{
    width:min(82vw, 420px);
    height:auto; max-width:none; min-width:0;
    aspect-ratio:7 / 10;
    max-height:calc(100dvh - 220px);
    border-radius:28px;
    padding:24px;
  }
  .work-card__visual{ left:24px; right:24px; top:19%; bottom:36%; }


  .work-card__num{ font-size:12px; padding:6px 12px; }
  .work-card__tags span{ font-size:12px; padding:6px 12px; }
  .work-card__body h3{
    font-size:clamp(27px, 7.4vw, 34px); line-height:1.06; margin-bottom:10px;
  }
  .work-card__body p{
    font-size:clamp(16px, 4.2vw, 19px); line-height:1.45;
    color:rgba(255,255,255,.82);
    max-width:none; padding-right:66px;
  }
  .work-card__arrow{
    width:54px; height:54px; right:24px; bottom:24px;
  }
  .work-card__arrow svg{ width:22px; height:22px; }

  /* dica de arraste no lugar da barra de progresso do desktop */
  .work__progress{ display:none; }
  .work__head .drag-hint{ display:block; margin-top:18px; }
  .work__head .drag-hint span{ color:rgba(255,255,255,.55); }

  /* nao selecionar texto durante o gesto */
  .work__viewport, .work__track, .work-card{
    -webkit-user-select:none; user-select:none;
  }

  /* ---- estado ativo (sem :hover no telefone) ----
     O card ativo ganha presenca; os vizinhos recuam. E o que diz ao dedo
     qual card esta em foco. */
  .work-card{
    transition:transform .5s cubic-bezier(.16,1,.3,1), opacity .5s ease;
  }
  .swiper-slide:not(.swiper-slide-active) .work-card__scrim{ opacity:1; }
  .swiper-slide:not(.swiper-slide-active) .work-card{ opacity:.72; }
  .swiper-slide-active .work-card__scrim{ opacity:.9; }
  .swiper-slide-active .work-card__visual{ transform:scale(1.03); }
  .swiper-slide-active .work-card__arrow{
    transform:scale(1.06);
    box-shadow:0 10px 30px rgba(245,245,19,.3);
  }
}

@media (prefers-reduced-motion: reduce){
  .work-card, .work-card__visual, .work-card__scrim,
  .work-card__tags, .work-card__arrow, .work-card::after{ transition:none !important; }
  .swiper-slide-active .work-card__visual{ transform:none; }
}


/* ===================== OFFER (kinetic) ===================== */
.offer{ padding:120px 0; }
.offer__kinetic{
  font-family:var(--font-display);
  font-size:clamp(24px, 3.4vw, 42px);
  line-height:1.35;
  max-width:900px;
  margin:36px 0 80px;
}
/* cor inicial vem do JS (ele interpola cor); aqui só o espaçamento */
.offer__kinetic .word{ transition:none; }
.offer__grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:24px;
}
.offer-card{
  background:var(--bg-card);
  border-radius:var(--radius-lg);
  padding:32px;
  opacity:0; transform:translateY(60px);
}
.offer-card__num{ font-family:var(--font-display); font-size:14px; font-weight:700; color:var(--ink-faint); }
.offer-card h3{ font-size:20px; margin:18px 0 10px; }
.offer-card p{ color:var(--ink-soft); font-size:14.5px; }
.offer-card:nth-child(4), .offer-card:nth-child(5){ grid-column:span 1; }

/* ===================== SERVICES ===================== */
.services{ padding:100px 0; }
.services__grid{
  margin-top:56px;
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:24px;
  align-items:stretch;
}
.price-card{
  background:var(--bg-card);
  border-radius:var(--radius-lg);
  padding:36px;
  display:flex; flex-direction:column;
  opacity:0; transform:translateY(60px);
}
.price-card--highlight{ background:var(--dark); color:#fff; }
.price-card--highlight .price-card__desc,
.price-card--highlight li{ color:var(--dark-soft); }
.price-card--highlight .btn--dark{ background:#fff; color:var(--dark); }
.price-card h3{ font-size:20px; margin-bottom:14px; }
.price-card__price{ font-family:var(--font-display); font-size:36px; font-weight:700; margin-bottom:16px; }
.price-card__price span{ font-size:14px; font-weight:500; opacity:.6; }
.price-card__desc{ color:var(--ink-soft); font-size:14.5px; margin-bottom:22px; }
.price-card ul{ display:flex; flex-direction:column; gap:10px; margin-bottom:28px; flex:1; }
.price-card li{ font-size:13.5px; color:var(--ink-soft); padding-left:18px; position:relative; }
.price-card li::before{ content:"—"; position:absolute; left:0; }
.price-card .btn{ align-self:flex-start; }

/* ===================== CLIENTS ===================== */
.clients{ padding:120px 0; }
.clients__swiper{ margin-top:48px; padding:0 32px 40px; }
.testimonial-card{
  width:420px;
  background:var(--bg-card);
  border-radius:var(--radius-lg);
  padding:32px;
  height:auto;
}
.testimonial-card p{ font-size:16px; line-height:1.55; margin-bottom:28px; }
.testimonial-card__author strong{ display:block; font-size:15px; }
.testimonial-card__author span{ font-size:13px; color:var(--ink-faint); }

/* ---------- DEPOIMENTOS / FAQ / RODAPE NO TELEFONE ----------
   O card mantinha `width:420px` fixo — mais largo que a viewport em
   qualquer telefone — e a secao guardava o respiro de desktop, o que
   abria o vazio entre o carrossel e o FAQ. */
@media (max-width:991px){
  .clients{ padding:72px 0 56px; }
  .clients__swiper{ margin-top:28px; padding:0 20px 8px; }
  /* `vw` pelo mesmo motivo dos cards de projeto: dentro do Swiper a
     porcentagem resolve contra o wrapper (soma dos slides), nao contra a
     viewport — dava 79%% em vez dos 88%% pedidos. */
  .testimonial-card{
    width:min(88vw, 460px); padding:24px;
  }
  .testimonial-card p{ font-size:15px; margin-bottom:20px; }
  .clients .drag-hint{ margin-top:14px; }

  .faq{ padding:56px 0 72px; }
  .faq__list{ margin-top:28px; }
  .faq-item__q{ font-size:16px; padding:20px 0; gap:16px; }
  .faq-item__q span{ min-width:0; overflow-wrap:anywhere; }

  .footer{ padding:72px 0 32px; border-radius:28px 28px 0 0; }
  .footer__title{ font-size:clamp(30px, 9vw, 48px); }
  .footer .btn--lg{
    font-size:17px; padding:16px 28px;
    max-width:100%; white-space:normal; text-align:center;
  }
  .footer__bottom{ gap:20px; }
  .footer__links{ flex-wrap:wrap; gap:14px 20px; }
  .footer__copy{
    font-size:12px; line-height:1.5;
    overflow-wrap:anywhere; max-width:100%;
  }
  /* area segura inferior dos aparelhos com barra de gestos */
  .footer .container{ padding-bottom:env(safe-area-inset-bottom, 0px); }
}

/* ===================== FAQ ===================== */
.faq{ padding:100px 0 140px; }
.faq__list{ margin-top:48px; max-width:800px; }
.faq-item{ border-bottom:1px solid var(--line); }
.faq-item__q{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  padding:26px 0; font-size:18px; font-weight:600; text-align:left;
}
.faq-item__q i{ font-style:normal; font-size:22px; transition:transform .35s ease; }
.faq-item.is-open .faq-item__q i{ transform:rotate(45deg); }
.faq-item__a{ height:0; overflow:hidden; opacity:0; }
.faq-item__a p{ padding-bottom:26px; color:var(--ink-soft); max-width:640px; }

/* ===================== FOOTER ===================== */
.footer{ background:var(--dark); color:#fff; padding:120px 0 40px; border-radius:40px 40px 0 0; }
.footer__title{ font-size:clamp(40px, 7vw, 88px); margin-bottom:40px; }
.footer .btn--dark{ background:#fff; color:var(--dark); }
/* linha de credencial abaixo do CTA: mesma opacidade dos links do rodape,
   largura travada para nao virar linha unica gigante em telas largas */
.footer__note{ margin:28px 0 0; max-width:46ch; font-size:14px; line-height:1.6;
  color:rgba(255,255,255,.55); }
.footer__bottom{
  margin-top:120px; padding-top:32px; border-top:1px solid rgba(255,255,255,.14);
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:20px;
}
.footer .nav__logo{ color:#fff; }
.footer__links{ display:flex; gap:24px; }
.footer__links a{ font-size:14px; color:rgba(255,255,255,.6); }
.footer__links a:hover{ color:#fff; }
.footer__copy{ font-size:13px; color:rgba(255,255,255,.4); }

.contact-dialog{
  width:min(920px, calc(100% - 40px));
  max-height:calc(100svh - 32px);
  margin:auto;
  padding:0;
  border:0;
  border-radius:24px;
  background:transparent;
  color:var(--ink);
  overflow:hidden;
  overscroll-behavior:contain;
  scrollbar-gutter:stable;
}
.contact-dialog::backdrop{ background:rgba(10,10,9,.72); backdrop-filter:blur(8px); }
.contact-dialog__panel{
  position:relative;
  display:grid;
  grid-template-columns:minmax(220px,.78fr) minmax(0,1.22fr);
  column-gap:clamp(30px,5vw,72px);
  align-items:start;
  padding:clamp(28px, 5vw, 52px);
  border:1px solid rgba(255,255,255,.16);
  border-radius:24px;
  background:linear-gradient(145deg,#2b2a26,#201f1c);
  box-shadow:0 28px 90px rgba(0,0,0,.36);
}
.contact-dialog__close{
  position:absolute; top:18px; right:20px;
  width:34px; height:34px; border:0;
  border-radius:50%; background:var(--accent); color:var(--ink); font-size:24px; line-height:1;
}
.contact-dialog__close:hover{ background:var(--accent); transform:translateY(-1px); }
.contact-dialog__kicker{ grid-column:1; color:var(--accent); font-size:11px; font-weight:700; letter-spacing:.14em; }
.contact-dialog h2{ grid-column:1; max-width:13ch; margin-top:14px; color:#f7f6ec; font-family:var(--font-display); font-size:clamp(32px, 4.2vw, 54px); line-height:.96; letter-spacing:-.04em; }
.contact-dialog__intro{ grid-column:1; max-width:35ch; margin-top:18px; color:rgba(255,255,255,.68); font-size:15px; line-height:1.5; }
.contact-form{ grid-column:2; grid-row:1 / span 3; display:grid; gap:16px; margin-top:0; }
.contact-form__honeypot{ position:absolute!important; width:1px!important; height:1px!important; padding:0!important; margin:-1px!important; overflow:hidden!important; clip:rect(0,0,0,0)!important; white-space:nowrap!important; border:0!important; }
.contact-form__grid{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:14px; }
.contact-form label{ display:grid; gap:7px; color:rgba(255,255,255,.78); font-size:12px; font-weight:600; }
.contact-form input,.contact-form select,.contact-form textarea{
  width:100%; border:1px solid rgba(255,255,255,.18); border-radius:9px;
  background:rgba(255,255,255,.07); color:#fff; padding:12px 13px;
  font:inherit; font-size:14px; outline:none; resize:vertical;
}
.contact-form select{ appearance:none; -webkit-appearance:none; min-height:43px; padding-right:34px; color-scheme:dark; cursor:pointer; background-color:rgba(255,255,255,.07); background-image:linear-gradient(45deg,transparent 50%,rgba(255,255,255,.72) 50%),linear-gradient(135deg,rgba(255,255,255,.72) 50%,transparent 50%); background-position:calc(100% - 17px) 50%,calc(100% - 12px) 50%; background-size:5px 5px,5px 5px; background-repeat:no-repeat; transition:border-color .2s ease,background-color .2s ease; }
.contact-form select:hover{ background-color:rgba(255,255,255,.11); border-color:rgba(245,245,19,.55); }
.contact-form select option{ color:#171714; background:#f7f6ec; }
.contact-form select:disabled{ color:rgba(255,255,255,.42); cursor:not-allowed; }
.contact-form input:focus,.contact-form select:focus,.contact-form textarea:focus{ border-color:var(--accent); box-shadow:0 0 0 3px rgba(245,245,19,.14); }
.contact-form input[aria-invalid="true"],.contact-form select[aria-invalid="true"]{ border-color:#ff8177; box-shadow:0 0 0 3px rgba(255,129,119,.12); }
.contact-form input::placeholder{ color:rgba(255,255,255,.36); }
.contact-form [hidden]{ display:none; }
.contact-form__privacy{ color:rgba(255,255,255,.48); font-size:11px; line-height:1.45; }
.contact-form__consent{ display:flex!important; grid-template-columns:none!important; align-items:flex-start; gap:9px!important; color:rgba(255,255,255,.62)!important; font-size:11px!important; line-height:1.4; font-weight:500!important; }
.contact-form__consent input{ width:16px; height:16px; flex:0 0 16px; margin:0; accent-color:var(--accent); }
.contact-form__submit{ justify-self:start; border:0; cursor:pointer; }
.contact-form__status{ min-height:18px; color:var(--accent); font-size:13px; }
.contact-form__status[data-state="error"]{ color:#ffb0a8; }
@media (max-width:600px){
  .contact-dialog{ width:calc(100% - 24px); max-height:92svh; overflow:auto; }
  .contact-dialog__panel{ display:block; padding:28px 20px 22px; }
  .contact-dialog h2{ max-width:11ch; font-size:clamp(31px, 10vw, 44px); }
  .contact-form{ margin-top:28px; }
  .contact-form__grid{ grid-template-columns:1fr; gap:12px; }
  .contact-form__submit{ width:100%; }
}



/* ===================================================================
   TESTE DE COMPOSIÇÃO — duas colunas ladeando a foto
   Ative com <header class="shell is-hero is-split"> ou pelo JS.

   Leitura: ESQUERDA = mensagem e ação (eyebrow, título, botões);
   DIREITA = prova (os números). A foto central vira a dobradiça.

   As colunas são estreitas de propósito. A silhueta come a largura
   conforme desce — a esquerda fica livre até 40% no alto e só até 25%
   embaixo; a direita libera de 57% no alto e de 73% embaixo. Os limites
   abaixo respeitam o pior caso de cada faixa.

   O card de traits e a nota do rodapé somem aqui: com os números à
   direita como prova, os adjetivos dizem a mesma coisa de novo, e a nota
   repete a descrição que já está na sidebar.
   =================================================================== */
.shell.is-split .hero-note{ display:none; }   /* duplica a descrição da sidebar */

/* O kicker fecha a coluna, abaixo dos botões. Como eyebrow ele não cabe:
   o nav termina em 42.2% e o título começa em 43% — 0.8 ponto para um
   bloco de 5. Aqui ele lê como assinatura, que é o papel do texto. */
.shell.is-split .hero-kicker{
  left:var(--hero-pad); right:auto; top:auto; bottom:6vh;
  font-size:15px; line-height:1.6;   /* o original usa 15.1px, cor cheia */
  color:var(--ink);
}

.shell.is-split .hero-title{
  left:var(--hero-pad); top:43%;
  transform:none;                    /* sai da centragem */
  width:min(32vw, 460px);
  text-align:left;
  font-size:clamp(28px, min(4.2vw, 7vh), 62px);
}

.shell.is-split .hero-buttons{
  /* 67% e não mais abaixo: a partir de 78% a silhueta avança para
     28% e os botões (que terminam em 28.6%) encostavam nela. */
  left:var(--hero-pad); bottom:auto; top:67%;
  transform:none;
  justify-content:flex-start;
}

/* prova, encostada na borda direita */
/* Estatísticas como DADO, não como card, em GRADE de duas colunas iguais.
   Antes eram flex com `width:auto`: a caixa do "7+" media 70px contra os
   98.5px que ele tem no sidebar, e o morph aplicava scaleX 0.71 — o texto
   chegava horizontalmente achatado. Com colunas de largura idêntica as
   duas escalas ficam equivalentes e não há compressão.
   O filete é a coluna do meio (1px) e agora viaja no morph junto dos
   números; parado, ele ficava órfão na posição do sidebar. */
.shell.is-split.is-hero .stats{
  left:auto; right:calc(var(--hero-pad-dir) + var(--traits-w) + var(--grupo-gap));
  top:var(--hero-band); transform:none;
  width:var(--stats-w);
  display:grid; grid-template-columns:1fr 1px 1fr;
  align-items:start;
  gap:clamp(24px, 2vw, 32px);
  --stat-bg:0;
}
/* `display:block` e `transform:none` explícitos: o layout centrado dá
   `display:flex` ao card largo (número AO LADO do rótulo, altura 44px em
   vez de 85) e `translateY(-15%)` ao bloco de características. Os dois
   vazavam para cá — o primeiro fazia o morph achatar o card em scaleY .68. */
.shell.is-split.is-hero .stat{
  width:auto; padding:0; margin:0; min-width:0;
  display:block;
}
.shell.is-split.is-hero .stat b{ font-size:clamp(34px, 3.4vw, 52px); letter-spacing:-.02em; }
.shell.is-split.is-hero .stat span{ font-size:13px; font-weight:500; line-height:1.35; margin-top:6px; }
.shell.is-split.is-hero .stats__sep{ align-self:stretch; margin:2px 0; }

/* Faixa editorial: sem caixa, itens separados por filetes finos. */
.shell.is-split .traits{
  left:auto; right:var(--hero-pad-dir); top:var(--hero-band); bottom:auto;
  transform:none;
  background:none; backdrop-filter:none;
  padding:0; gap:0;
  width:var(--traits-w);
}
.shell.is-split .traits li{
  padding:clamp(7px, 1.2vh, 12px) 0;
  border-bottom:1px solid var(--line);
  font-weight:600; letter-spacing:.01em;
}
.shell.is-split .traits li:last-child{ border-bottom:0; }

/* ===================================================================
   ACESSIBILIDADE
   Nenhum dos dois existia (nem no original): com 29 elementos focáveis a
   navegação por teclado era invisível, e um site com esse volume de
   animação sem escape é desconfortável para quem tem sensibilidade a
   movimento.
   =================================================================== */
:where(a, button, [tabindex]):focus-visible{
  outline:3px solid var(--accent);
  outline-offset:3px;
  border-radius:4px;
}
.shell.is-dark :where(a, button):focus-visible{ outline-color:#fff; }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .hero__scroll i::after{ animation:none; }
}

/* ===================== RESPONSIVE ===================== */
/* Grids de conteúdo têm breakpoint PRÓPRIO (960), separado do shell (767).
   Com a sidebar de 272px comendo a largura, 3 colunas não cabem abaixo de
   960: `1fr` não encolhe além do min-content e os price-card estouravam a
   página para 1097px, criando scroll horizontal. */
@media (max-width:960px){
  .work__grid, .offer__grid, .services__grid{ grid-template-columns:repeat(2, 1fr); }
}
/* `min-width:0` deixa a faixa encolher abaixo do min-content do conteúdo,
   que é o que impede blowout de grid em qualquer largura. */
.work__grid > *, .offer__grid > *, .services__grid > *{ min-width:0; }

@media (max-width:991px){
  /* ===================================================================
     HERO MOBILE — GABARITO 360 x 740

     A composicao e calibrada numa area de proporcao controlada. Com a
     altura do palco DETERMINADA (`--mobile-hero-height`), toda posicao
     vertical vira PORCENTAGEM dessa altura: o gabarito de 360x740 se
     transporta sozinho para qualquer largura, sem cada peca precisar
     adivinhar a viewport por conta propria — que era a origem da classe
     de bug "mudou a tela, algo colidiu".

     Tamanhos (larguras, fontes, recuos) seguem a MESMA escala do palco:
     `clamp(S, S*0.2778vw, S*1.5243)`, onde S e a medida no gabarito.
     0.2778vw = 205.56/740 e 1.5243 = 1128/740 — os dois limites do clamp
     da altura. Assim, quando a altura para de crescer (acima de 549px),
     os elementos param junto e a composicao nao se desmonta em tablet.
     =================================================================== */
  :root{
    --main-pad: 0px; --bar-h: 58px;
    --pad-lat: clamp(22px, 5.6vw, 30px);
    /* grade da barra: os tres elementos sao `fixed`, entao a 'grade' vem
       de left/right calculados a partir destas medidas — estavel e sem
       mexer no HTML. Gabarito 549px: marca x34, CTA x293 (154 de
       largura), menu x466 (50x48). */
    --bar-pad: clamp(18px, 6vw, 33px);
    --marca-w: clamp(118px, 27.5vw, 151px);
    --menu-w: 50px;
    --bar-gap: 19px;
    /* 205.56vw = 740/360. Abaixo de 360 trava em 740 e a pagina rola (o
       enunciado pede altura minima, nao compressao); acima de 549 trava
       em 1128 para o palco nao virar uma coluna vazia em tablet. */
    --mobile-hero-height: clamp(740px, 205.56vw, 1128px);
    /* 76.5% da altura efetiva do palco, inclusive quando 100svh vence o
       clamp. Usada pela foto e pela continuacao limpa de 20px no main. */
    --mobile-photo-height:max(clamp(566.1px, 157.25vw, 862.92px), 76.5svh);
  }

  .shell{
    position:relative; top:0; left:0;
    width:100%; z-index:2;
    height:max(var(--mobile-hero-height), 100svh);
    min-height:max(var(--mobile-hero-height), 100svh);
    display:flex; flex-direction:column;
    padding:calc(var(--bar-h) + env(safe-area-inset-top, 0px) + 14px) var(--pad-lat) 0;
    gap:0;
    /* Contem integralmente a largura excedente da fotografia. A faixa
       inferior e continuada pelo `main::before`, fora deste recorte. */
    overflow:hidden;
    overflow:clip;
    isolation:isolate;
  }
  main{ padding-left:0; background:var(--bg); position:relative; z-index:1; }
  main::before{
    content:"";
    position:absolute; z-index:2;
    left:0; right:0; top:0; height:20px;
    background:url('../img/perfil.webp') center bottom / auto var(--mobile-photo-height) no-repeat;
    pointer-events:none;
  }
  .shell-spacer{ display:none; }
  .quebra-mobile{ display:inline; }

  /* pecas exclusivas do sidebar ficam fora do telefone */
  [data-panel-only], .panel__bg, .clients-strip, .email-row,
  .hero-kicker, .hero-buttons{ display:none; }

  /* O paragrafo biografico sai do hero no telefone: o espaco dele e da
     fotografia. O texto continua no HTML — desktop e sidebar usam. */
  .hero-note, .shell.is-split .hero-note,
  .panel__desc, .shell.is-split .panel__desc{ display:none; }

  /* Estado inicial da entrada. Os cards e o painel vivem em `.panel`, que
     no telefone e `display:contents` — opacity em `display:contents` nao
     tem efeito, entao o fade de entrada precisa nascer aqui, nas pecas.
     Liberado pelo GSAP (e pela rede de seguranca de 3,5s do main.js). */
  .js .shell .stat, .js .shell .traits{ opacity:0; }

  /* ---------- 1. BARRA ---------- */
  .shell__bar{
    position:fixed; top:0; left:0; right:0;
    height:calc(var(--bar-h) + env(safe-area-inset-top, 0px));
    padding-top:env(safe-area-inset-top, 0px);
    background:var(--bg);
    border-bottom:1px solid var(--line);
    opacity:1; pointer-events:none; z-index:30;
  }
  .shell .brand{
    position:fixed; opacity:1; z-index:31;
    top:calc(env(safe-area-inset-top, 0px) + 11px);
    left:var(--bar-pad);
    display:flex; align-items:center; justify-content:center;
    width:var(--marca-w); height:36px; padding:0 10px; border-radius:6px;
    font-size:clamp(12.5px, 3.2vw, 15px); white-space:nowrap;
  }
  .cta{
    position:fixed; z-index:31;
    top:calc(env(safe-area-inset-top, 0px) + 7px);
    /* ancorado a direita: encosta no menu com o vao do gabarito */
    right:calc(var(--bar-pad) + var(--menu-w) + var(--bar-gap));
    left:auto; bottom:auto;
    width:clamp(128px, 28vw, 154px);
    display:inline-flex; align-items:center; justify-content:center;
    height:44px; padding:0 10px; border-radius:8px;
    font-size:clamp(12px, 3.1vw, 14.5px); white-space:nowrap;
  }
  .burger{
    display:flex; flex-direction:column; justify-content:center; gap:5px;
    position:fixed; z-index:32;
    top:calc(env(safe-area-inset-top, 0px) + 5px);
    right:var(--bar-pad);
    width:var(--menu-w); height:48px; padding:0 12px;
    background:var(--ink); border-radius:6px;
  }
  .burger span{
    height:2px; width:100%; background:#fff; border-radius:2px;
    transition:transform .35s cubic-bezier(.16,1,.3,1), opacity .25s ease;
  }
  .shell.menu-open .burger span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
  .shell.menu-open .burger span:nth-child(2){ opacity:0; }
  .shell.menu-open .burger span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

  /* ---------- 2. WORDMARK EM DUAS LINHAS (aprovado — nao mexer) ------- */
  .wordmark{
    order:1; position:static; opacity:1; z-index:1;
    width:94%; aspect-ratio:1000 / 360;
    transform:none; margin:0 0 .1em; max-width:100%;
  }
  .wordmark-svg--desktop{ display:none; }
  .wordmark-svg--mobile{ display:block; }

  /* ---------- 3. FOTOGRAFIA (camada 2) ----------
     76.5% e a proporcao definitiva do gabarito mobile: o cabelo toca
     discretamente `ERIC`, enquanto o corpo permanece ancorado na base.
     A largura sai da proporcao original do arquivo; os ombros seguem
     extravasando e sao recortados pelo `.shell`. */
  .shell__photo{
    position:absolute;
    inset:0;
    z-index:2;
    /* O palco conserva o tamanho original; apenas a imagem atravessa a
       base. Assim `height:76.5%` nao muda e os cards mantem a geometria. */
    clip-path:inset(0);
    /* Centragem por FLEX, nao por `translateX(-50%)`: o tween de entrada
       escreve `transform` na propria <img> e apagaria um translate de
       centragem. (Margem automatica tambem nao serve: com a imagem mais
       larga que o palco o navegador resolve a equacao sobre-restringida
       descartando `right`, e ela encosta em x=0.)
       `justify-content:center` distribui o excedente igualmente dos dois
       lados, que e exatamente o corte simetrico dos ombros do modelo. */
    display:flex; align-items:flex-end; justify-content:center;
    pointer-events:none; isolation:isolate;
    padding-right:0;
  }
  .shell__photo img{
    position:static; flex:0 0 auto;
    height:var(--mobile-photo-height); width:auto; max-width:none;
    margin-bottom:-20px;
    object-fit:contain; object-position:center bottom;
    transform:none;
  }
  .shell__photo-nitida{
    -webkit-mask-image:none; mask-image:none;
  }
  /* a copia desfocada servia a dissolucao antiga, que saiu */
  .shell__photo-fade{ display:none; }
  /* A fotografia termina limpa: sem nevoa, blur ou gradiente inferior. */
  .shell__photo::after{ content:none; }
  :root{ --photo-drop: 0; }

  /* a coluna some do fluxo: cada peca se posiciona no palco */
  .shell__col{ order:4; display:contents; }
  .panel{ position:static; padding:0; display:contents; }

  /* ---------- 4. TITULO SOBRE O PEITO (camada 4) ---------- */
  .shell__hero-only{ order:2; display:contents; }
  .hero-title, .shell.is-split .hero-title{
    position:absolute; z-index:4;
    left:5.5%; right:auto; bottom:auto;
    top:74%;
    width:55%;
    text-align:left;
    color:#fff;
    font-size:clamp(26px, 7.22vw, 40px);
    line-height:.98; letter-spacing:-.01em;
    white-space:normal; margin:0;
    text-shadow:0 2px 12px rgba(0,0,0,.26);
  }
  /* Camada 3: clarao curto atras do texto, so para garantir contraste
     sobre a estampa da camiseta. Como `.hero-title` tem z-index proprio,
     o `-1` fica dentro do contexto dele: cobre a fotografia e nunca os
     cards. */
  .hero-title::before{
    content:""; position:absolute; z-index:-1;
    left:-14%; right:-14%; top:-16%; bottom:-16%;
    background:radial-gradient(ellipse at center,
      rgba(26,24,20,.32) 0%, rgba(26,24,20,.15) 56%, rgba(26,24,20,0) 78%);
    pointer-events:none;
  }

  /* ---------- 5. VIDRO FUME TAUPE (os tres paineis) ---------- */
  .traits, .shell.is-split .traits, .stat{
    background:rgba(49,46,40,.36);
    -webkit-backdrop-filter:blur(17px) saturate(112%);
    backdrop-filter:blur(17px) saturate(112%);
    border:1px solid rgba(255,255,255,.22);
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.11),
      0 12px 30px rgba(0,0,0,.08);
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){
    .traits, .shell.is-split .traits, .stat{ background:rgba(30,29,26,.78); }
  }

  /* ---------- 6. PAINEL DE ATRIBUTOS — canto inferior direito -------- */
  /* Redeclarado com `.shell.is-split` porque a regra de desktop tem
     especificidade maior e zeraria background/backdrop-filter aqui. */
  .traits, .shell.is-split .traits{
    display:block; position:absolute; z-index:5;
    left:auto; bottom:auto;
    right:clamp(17px, 4.72vw, 36px);
    top:74.5%;
    width:clamp(104px, 29vw, 171px);
    transform:none;
    /* recuo, icone e vao no piso da faixa que o enunciado permite: com
       padding 9 / icone 15 / vao 7, "Estrategista" media exatamente a
       largura util (92 de 92) e qualquer variacao de metrica da fonte
       viraria overflow. Assim sobram ~5px de folga. */
    padding:clamp(8px, 2.22vw, 12px);
    border-radius:clamp(16px, 4.44vw, 24px);
  }
  .shell.is-split .traits li{
    display:flex; align-items:center; gap:clamp(6px, 1.67vw, 9px);
    min-height:clamp(28px, 7.78vw, 43px); height:auto;
    padding:0; border-bottom:1px solid rgba(255,255,255,.16);
    font-size:clamp(10.5px, 2.92vw, 16px); font-weight:600;
    color:#fff; white-space:nowrap;
  }
  .shell.is-split .traits li:last-child{ border-bottom:0; }
  .shell.is-split .traits li svg{
    width:clamp(14px, 3.89vw, 21px); height:clamp(14px, 3.89vw, 21px);
    flex:0 0 auto; color:var(--accent);
  }

  /* ---------- 7. OS DOIS NUMEROS COMO CARDS INDEPENDENTES ----------
     `display:contents` dissolve o container para cada `.stat` se
     posicionar sozinho no palco. A estrutura de desktop nao muda. */
  .shell .stats{
    display:contents; position:static;
    background:none; border:0; box-shadow:none; backdrop-filter:none;
  }
  .stats__sep{ display:none; }

  .stat{
    position:absolute; z-index:5;
    width:auto; min-width:0; margin:0;
    padding:clamp(11px, 3.06vw, 17px);
    border-radius:clamp(16px, 4.44vw, 24px);
    overflow:hidden;
  }
  .stat::before{ display:none; }
  .stat b{
    display:block; color:var(--accent);
    font-size:clamp(34px, 9.44vw, 52px); line-height:1;
  }
  .stat span{
    display:block; color:#fff;
    font-size:clamp(11px, 3.06vw, 17px); line-height:1.25;
    margin-top:clamp(4px, 1.11vw, 6px);
  }
  /* 15 anos: sobre o ombro direito, abaixo do rosto */
  .stat--tall{
    right:clamp(17px, 5.5vw, 42px); left:auto;
    top:45%;
    width:clamp(84px, 22vw, 134px);
  }
  /* 18 convenios: base esquerda, mais baixo que o painel de atributos */
  .stat--wide{
    left:clamp(24px, 7.5vw, 58px); right:auto; top:auto;
    bottom:.7%;
    width:clamp(96px, 25.5vw, 156px);
  }

  /* ---------- menu em sobreposicao ---------- */
  .shell .menu{
    position:fixed; inset:0;
    flex-direction:column; justify-content:center; gap:0;
    background:var(--bg-card);
    padding:80px 28px;
    transform:translateY(-100%);
    transition:transform .5s cubic-bezier(.16,1,.3,1);
    z-index:29;
  }
  .shell.menu-open .menu{ transform:translateY(0); }
  .shell .menu a{
    font-family:var(--font-display); font-size:26px; font-weight:600;
    text-transform:none; letter-spacing:-.01em;
    background:none; border-radius:0; padding:16px 0;
    border-bottom:1px solid var(--line);
    align-self:stretch;
  }
  .shell .menu a:hover{ background:none; color:var(--ink-soft); }
}

/* Em telas muito estreitas a marca e o CTA disputam a barra: os icones
   sociais ja estao fora, e aqui o CTA encolhe para caber sem encostar. */
@media (max-width:380px){
  .cta{ font-size:11.5px; padding:8px 11px; right:58px; }
  .shell .brand{ font-size:15px; padding:5px 9px; }
}

@media (max-width:991px){
  .container{ padding:0 20px; }
}
@media (max-width:640px){
  .container{ padding:0 20px; }
  .work__grid, .offer__grid, .services__grid{ grid-template-columns:1fr; }
  .nav__cta{ display:none; }
  .hero__actions{ flex-direction:column; align-items:flex-start; }
  .footer__bottom{ flex-direction:column; align-items:flex-start; }
}
