/* =========================================================
   GR Brands — Eduardo Rodrigues
   Branco, preto e vermelho. Precisão.
   ========================================================= */

@font-face{font-family:'Inter';src:url('Inter-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Inter';src:url('Inter-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Inter';src:url('Inter-SemiBold.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Jersey 10';src:url('Jersey10-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}

:root{
  --paper:#F7F7F7;
  --card:#FFFFFF;
  --ink:#0E0E10;
  --muted:#6E6E76;
  --faint:#93939C;
  --line:#E2E2E6;
  --surface:#FFFFFF;
  --ph:#EBEBEF;
  --ph2:#E2E2E7;
  --red:#E4322A;
  --glass:rgba(255,255,255,.72);
  --lg-fill:rgba(255,255,255,.82);
  --lg-fill-hover:#FFFFFF;
  --lg-gloss:rgba(255,255,255,.7);
  --lg-edge:rgba(255,255,255,.95);
  --lg-ring:rgba(14,14,16,.14);
  --lg-ring-hover:rgba(14,14,16,.24);
  --lg-rim:rgba(14,14,16,.05);
  --lg-inner:rgba(255,255,255,.96);
  --lg-drop:rgba(14,14,16,.16);
  --lg-drop-hover:rgba(14,14,16,.24);
  --lg-sheen:rgba(255,255,255,.75);
  --lg-press:rgba(14,14,16,.26);
  --hero-a:rgba(255,255,255,.95);
  --hero-b:rgba(228,50,42,.07);
  --hero-c:rgba(88,120,255,.055);
  --hero-d:rgba(255,168,80,.05);
  --hero-base:#EFEFF1;
  --grain:.05;
  --lg-fill-press:rgba(236,236,239,.92);
  --shadow:rgba(14,14,16,.34);
  --shadow-soft:rgba(14,14,16,.14);
  --arrow:%236E6E76;
  --tool-glow:rgba(228,50,42,.12);
  --tool-wash:rgba(255,112,67,.035);
  --t1:#00A63F; --t2:#F59300; --t3:#0091FF; --t4:#9B3DFF; --t5:#FF2D6F; --t6:#E4322A;

  --rail:96.8px;
  --gut:clamp(22px,5vw,79.2px);
  --maxw:1452px;
  --r:15.4px;
  --rsec:clamp(30.8px,4vw,61.6px);
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-soft:cubic-bezier(.4,0,.2,1);
  /* soltar tem uma sobra elastica; pressionar e seco */
  --ease-release:cubic-bezier(.2,1.5,.4,1);
  --ease-press:cubic-bezier(.5,0,.9,.4);
}

/* ---------- modo escuro ---------- */
[data-theme="dark"]{
  --paper:#0B0B0D;
  --card:#141419;
  --ink:#F3F3F5;
  --muted:#9C9CA6;
  --faint:#6B6B75;
  --line:#26262B;
  --surface:#111114;
  --ph:#17171B;
  --ph2:#1E1E23;
  --red:#FF4A3F;
  --glass:rgba(11,11,13,.66);
  --lg-fill:rgba(255,255,255,.08);
  --lg-fill-hover:rgba(255,255,255,.15);
  --lg-gloss:rgba(255,255,255,.09);
  --lg-edge:rgba(255,255,255,.24);
  --lg-ring:rgba(255,255,255,.12);
  --lg-ring-hover:rgba(255,255,255,.22);
  --lg-rim:rgba(0,0,0,.45);
  --lg-inner:rgba(255,255,255,.3);
  --lg-drop:rgba(0,0,0,.45);
  --lg-drop-hover:rgba(0,0,0,.6);
  --lg-sheen:rgba(255,255,255,.22);
  --lg-press:rgba(0,0,0,.62);
  --hero-a:rgba(255,255,255,.07);
  --hero-b:rgba(255,74,63,.12);
  --hero-c:rgba(88,120,255,.10);
  --hero-d:rgba(255,168,80,.07);
  --hero-base:#08080A;
  --grain:.07;
  --lg-fill-press:rgba(23,23,27,.94);
  --shadow:rgba(0,0,0,.66);
  --shadow-soft:rgba(0,0,0,.4);
  --arrow:%239C9CA6;
  --tool-glow:rgba(255,74,63,.18);
  --tool-wash:rgba(255,106,61,.055);
  --t1:#2BFF88; --t2:#FFC13D; --t3:#4FD8FF; --t4:#C08BFF; --t5:#FF5FA8; --t6:#FF5A4E;
}
html{color-scheme:light}
[data-theme="dark"]{color-scheme:dark}
body,.head,.sec--surface,.sec--contact,.cell,.svc,.form,.tool,.arc__card,.about__card{
  transition:background-color .35s,border-color .35s,color .35s;
}

/* ---------- troca de modo: o novo tema abre em circulo ----------
   O script anima o clip-path de ::view-transition-new(root), entao os dois
   crossfades padrao do navegador saem do caminho: o antigo fica parado por
   baixo, inteiro, e o novo o cobre de dentro para fora. Sem isto, os dois
   estariam desaparecendo ao mesmo tempo e o meio da animacao mostraria a
   pagina lavada.
   mix-blend-mode:normal e obrigatorio: o padrao (plus-lighter) foi feito para
   dois lados que se cruzam somando luz — com um dos lados opaco, ele estoura os
   claros e o modo escuro chega cinza. */
::view-transition-old(root),
::view-transition-new(root){
  animation:none;
  mix-blend-mode:normal;
}
/* A borda da passagem e macia, e nao um corte.
   O JS anima UM comprimento (--wipe-r); a mascara se redesenha a cada quadro a
   partir dele. Foi preciso chegar ate aqui porque animar mask-image direto nao
   funciona: gradiente nao interpola, e o Chrome resolve isso trocando de valor
   no meio do caminho — o que aparecia como a tela piscando de um tema para o
   outro, sem passagem nenhuma. Medido antes de confiar.
   A faixa macia tem espessura FIXA (180px): em porcentagem ela engrossaria
   junto com o raio, comecando afiada e terminando borrada. */
::view-transition-new(root){
  --wipe-x:50%;--wipe-y:50%;
  -webkit-mask-image:radial-gradient(circle at var(--wipe-x) var(--wipe-y),
    #000 calc(var(--wipe-r) - 180px), rgba(0,0,0,0) var(--wipe-r));
  mask-image:radial-gradient(circle at var(--wipe-x) var(--wipe-y),
    #000 calc(var(--wipe-r) - 180px), rgba(0,0,0,0) var(--wipe-r));
}
::view-transition-old(root){z-index:1}
::view-transition-new(root){z-index:2}

/* Durante a captura, as cores tem de estar no valor FINAL: a foto do estado
   novo e tirada no quadro seguinte a troca do atributo, e um fade de .35s ainda
   estaria quase todo na cor antiga naquele instante. */
/* A lista de antes cobria so os blocos grandes. Mas botao, etapa do processo,
   card de servico e link do menu tambem tem transicao de cor propria, e a foto
   do estado novo e tirada UM QUADRO depois da troca do atributo: cada um desses
   aparecia dentro do circulo ainda na cor antiga, terminando de virar so quando
   a transicao acabava. Era isso que fazia a metade revelada parecer "meio
   trocada". Aqui a rede e ampla de proposito: durante os poucos centesimos da
   captura, nada no documento transiciona.
   Nao ha risco de prender uma transicao pela metade: o DOM vivo fica escondido
   atras das fotos esse tempo inteiro. */
html.is-theming *,
html.is-theming *::before,
html.is-theming *::after{
  transition:none!important;
}

/* NAO dar view-transition-name ao interruptor — por mais tentador que pareca.
   A ideia era tira-lo da foto da pagina para que ele continuasse se mexendo
   durante o circulo. Mas todo elemento nomeado ganha do proprio navegador uma
   animacao de transform no grupo (-ua-view-transition-group-anim-*) para
   encaixar a posicao antiga na nova — e QUALQUER transform nas camadas da
   transicao derruba a foto da RAIZ: o circulo passa a abrir sobre um vazio
   preto em vez da pagina antiga.
   Medido no arquivo real, luminancia media fora do circulo (onde a pagina
   ANTIGA deveria aparecer; ~180 = viva, ~11 = perdida):
     com o nome ........................ 11
     com o nome, animacao do grupo off . 183
     sem as animacoes de old/new ....... 11
     sem o nome ........................ 183
   Como a animacao do grupo e do navegador e nao da para remove-la de fora, o
   nome esta fora de questao. O retorno do toque acontece no DOM vivo, ANTES do
   congelamento (ver o atraso de 150ms em script.js), e o giro do icone entra
   depois que a pagina volta a viver. */

@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){animation:none!important}
}

/* @property permite interpolar o raio da luz; sem ele o valor so troca de degrau */
@property --glow-r{syntax:'<length>';inherits:false;initial-value:120px}
@property --glow-a{syntax:'<number>';inherits:false;initial-value:0}
/* O raio da passagem de tema. Sem @property, um custom property so troca de
   degrau, e a mascara pularia de 0 ao raio final sem nada no meio. */
@property --wipe-r{syntax:'<length>';inherits:false;initial-value:0px}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:123.2px;-webkit-text-size-adjust:100%}

/* ---------- barra de rolagem nativa ----------
   O indicador de progresso da pagina e o rail da esquerda, que ja mostra onde a
   leitura esta. A barra do navegador na direita repete essa informacao com um
   desenho que nao e do site — e, no Windows, ainda risca uma faixa cinza ao
   lado do vidro do header. Sai de cena; a rolagem em si (roda, teclado, toque,
   arrasto de barra de espaco) continua inteira.
   Cada motor esconde de um jeito: Firefox por scrollbar-width, WebKit/Blink
   pelo pseudo-elemento, Edge legado por -ms-overflow-style. */
html{scrollbar-width:none;-ms-overflow-style:none}
html::-webkit-scrollbar,body::-webkit-scrollbar,*::-webkit-scrollbar{
  width:0;height:0;background:transparent;
}

/* ---------- toque no mobile ----------
   O Chrome/Safari do Android e iOS pintam um retangulo azul por cima de tudo que
   e clicavel no instante do toque. Ele ignora o border-radius do vidro, entao a
   pilula aparece dentro de um QUADRADO azul e o efeito de vidro some no momento
   exato em que a pessoa esta olhando para ele. O feedback proprio ja existe
   (:active, .is-pressed e o bloom da luz), entao o realce nativo so atrapalha.
   touch-action:manipulation ainda tira o atraso de 300ms herdado do duplo-toque
   para dar zoom, o que faz o :active responder na hora. */
html{-webkit-tap-highlight-color:transparent}
a,button,label,summary,[role="button"],input,select,textarea{
  -webkit-tap-highlight-color:transparent;
}
a,button,label,summary,[role="button"]{touch-action:manipulation}
/* O menu de toque longo do iOS ("abrir em nova aba", "copiar link") so estorva
   nos controles — num link de texto ele e uma funcao real, entao fica de pe. */
.btn,.glass,.theme,.burger,.foot__up,.skills li{-webkit-touch-callout:none}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:17.6px;
  line-height:1.6;
  font-feature-settings:"kern","liga","calt";
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
h1,h2,h3,p,ul,ol,dl,dd,figure,blockquote{margin:0}
ul,ol{list-style:none;padding:0}
button,input,select,textarea{font:inherit;color:inherit}

.skip{position:absolute;left:-10998.9px;top:0;background:var(--ink);color:var(--paper);padding:13.2px 19.8px;z-index:200}
.skip:focus{left:13.2px;top:13.2px}
:focus-visible{outline:2.2px solid var(--red);outline-offset:3.3px;border-radius:4.4px}

/* ---------- tipografia base ---------- */
.eyebrow{
  font-size:12.1px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  color:var(--faint);margin-bottom:24.2px;display:flex;align-items:center;gap:13.2px;
}
.eyebrow::before{content:"";width:28.6px;height:1.1px;background:var(--red);flex:none}

h1,h2{letter-spacing:-.035em;line-height:1.02;font-weight:600}
h1{font-size:clamp(44px,6.4vw,96.8px)}
h2{font-size:clamp(34.1px,4.4vw,68.2px)}
h1 em{font-style:normal;color:var(--red)}
/* ---------- palavra em brasa ----------
   O vermelho da marca aceso: halo curto para a letra brilhar por dentro e halo
   largo para a cor escapar no fundo, pulsando devagar.
   O "precisao" do hero JA NAO usa isto: numa primeira dobra que ja tem o veu da
   abertura, o leque girando e a onda cromatica dos pixels, mais uma coisa
   pulsando era ruido — a palavra ficou so no vermelho da marca, que basta para
   ela ser o remate da frase. O brilho continua na pagina de obrigado, onde e a
   unica coisa viva da tela.
   Os raios estao em em, e nao em px, para o halo acompanhar o corpo da letra em
   vez de ficar preso a uma medida fixa.
   Com prefers-reduced-motion o bloco no fim do arquivo zera a animacao e sobra
   o brilho parado, que e o estado do meio do pulso. */
.thanks h1 span{
  text-shadow:
    0 0 .37em color-mix(in srgb,var(--red) 42%,transparent),
    0 0 1.02em color-mix(in srgb,var(--red) 26%,transparent);
  animation:brilho 3.2s var(--ease-soft) infinite alternate;
}
@keyframes brilho{
  from{
    text-shadow:
      0 0 .245em color-mix(in srgb,var(--red) 26%,transparent),
      0 0 .735em color-mix(in srgb,var(--red) 14%,transparent);
  }
  to{
    text-shadow:
      0 0 .49em color-mix(in srgb,var(--red) 58%,transparent),
      0 0 1.35em color-mix(in srgb,var(--red) 36%,transparent);
  }
}
/* A segunda linha do titulo vira BLOCO para poder ser balanceada. Com ela
   inline, o <br> que a separa da primeira linha impede o balance de agir: o
   navegador so reparte linhas dentro de um mesmo bloco sem quebra forcada.
   Sem isso, em 414 e 430px (iPhone Plus e Pro Max) sobrava a palavra "cliente"
   sozinha na ultima linha. */
.dim{color:var(--faint);display:block;text-wrap:balance}
.red{color:var(--red)}
.pixel{
  display:inline-block;white-space:nowrap;
  font-family:'Jersey 10','Courier New',monospace;
  font-weight:400;letter-spacing:.01em;
  font-size:1.34em;line-height:.82;
  -webkit-font-smoothing:none;font-smooth:never;
}
/* cada caractere recebe uma onda cromática contínua */
.pixel .px{display:inline-block;font-style:normal;color:var(--t1)}
.pixel .px-word{display:inline-block;white-space:nowrap}
.pixel.is-split .px{opacity:0}
.is-in .pixel.is-split .px{
  opacity:1;
  transition:opacity .45s var(--ease-soft) calc(var(--n) * 24ms);
  /* onda cromatica no dobro da velocidade: o passo por caractere cai junto com
     a duracao, senao a onda so fica mais curta em vez de mais rapida. */
  animation:pxterm 3.6s ease-in-out infinite alternate;
  animation-delay:calc(var(--n) * -55ms);
}
@keyframes pxterm{
  0%{color:var(--t1)}
  20%{color:var(--t2)}
  40%{color:var(--t3)}
  60%{color:var(--t4)}
  80%{color:var(--t5)}
  100%{color:var(--t6)}
}
.lede,.sec__lede{color:var(--muted);font-size:clamp(16.5px,1.25vw,19.8px);max-width:56ch;line-height:1.65;text-wrap:balance}
/* dois paragrafos de lede seguidos (perfil do Miguel) precisam de respiro:
   o reset zera a margem de <p> e eles colavam num bloco unico. */
.sec__lede + .sec__lede{margin-top:1.05em}
/* A Inter aqui e carregada so em Regular, Medium e SemiBold — nao ha arquivo
   italico, entao <em> sairia com o italico sintetico do navegador (a letra
   inclinada por matriz, com as junções tortas). Mesma solucao ja usada em
   h1 em: a enfase vem do tom, nao da inclinacao. */
.lede em,.sec__lede em{font-style:normal;color:var(--ink)}

/* ---------- lateral: progresso da rolagem ---------- */
.rail{
  position:fixed;left:0;top:0;bottom:0;width:var(--rail);
  border-right:1.1px solid var(--line);background:var(--paper);z-index:60;
}
.rail__track{
  position:absolute;left:50%;top:0;bottom:0;width:2.2px;border-radius:2.2px;
  transform:translateX(-50%);background:var(--line);
}
.rail__fill{
  position:absolute;left:0;top:0;width:100%;height:100%;
  background:var(--red);transform:scaleY(var(--scroll-progress,0));transform-origin:top;
  will-change:transform;
}
/* posicao em % do trilho: independe do zoom aplicado no html */
.rail__dot{
  position:absolute;left:50%;top:calc(var(--scroll-progress,0) * 100%);
  width:9.9px;height:9.9px;border-radius:50%;
  background:var(--red);transform:translate3d(-50%,-50%,0);
  will-change:top;
  box-shadow:0 0 0 5.5px var(--paper);
}

/* ---------- header ---------- */
.head{
  position:fixed;top:0;right:auto;z-index:80;
  left:calc(50% + var(--rail) / 2);
  /* --head-y e o unico responsavel pelo deslocamento vertical: animar `top`
     obrigava o navegador a refazer o layout do header em cada quadro, e isso
     acontecia exatamente durante a rolagem, quando a thread principal ja esta
     ocupada. Em transform o compositor resolve sozinho. */
  --head-y:0px;
  transform:translate3d(-50%,var(--head-y),0);
  width:calc(100% - var(--rail));
  display:flex;align-items:center;gap:35.2px;
  /* o header do desktop respira mais: com 22px o botao encostava na borda de
     cima e na de baixo da barra e o conjunto lia como apertado */
  padding:26.4px var(--gut);
  background:var(--glass);
  backdrop-filter:blur(24.2px) saturate(150%);-webkit-backdrop-filter:blur(24.2px) saturate(150%);
  border:1.1px solid transparent;border-radius:0;
  box-shadow:0 0 0 0 rgba(14,14,16,0);
  transition:transform .5s var(--ease),width .5s var(--ease),padding .5s var(--ease),
             border-radius .5s var(--ease),border-color .4s,
             box-shadow .5s var(--ease),background .3s,gap .45s var(--ease);
  will-change:transform;
}
.head.is-stuck{
  --head-y:15.4px;
  width:min(1254px, calc(100% - var(--rail) - 35.2px));
  padding:14.3px 16.5px 14.3px 28.6px;
  border-radius:1098.9px;
  border-color:var(--lg-ring);
  background:var(--glass);
  box-shadow:
    inset 0 1.1px 0 var(--lg-inner),
    inset 0 -1.1px 0 var(--lg-rim),
    0 19.8px 44px -24.2px var(--shadow), 0 2.2px 8.8px -4.4px var(--shadow-soft);
}
/* vidro sobre vidro embaça duas vezes: dentro do header, os botões só pigmentam.
   Agora vale tambem para as variantes tingidas, que passaram a ter blur proprio. */
.head .theme,.head .burger,.head .btn{
  backdrop-filter:none;-webkit-backdrop-filter:none;
}
.head.is-stuck .head__nav{gap:33px}
.head__brand{display:flex;align-items:center;gap:12.1px;font-weight:600;letter-spacing:-.02em}
/* simbolo menor e nome maior: o disco preto dominava o lockup */
.head__brand img{width:31.9px;height:31.9px;transition:transform .42s var(--ease-release)}
.head__name{font-size:20.9px;line-height:1}
/* o ponto vermelho e a assinatura da marca — o mesmo do rodape */
.head__brand .dot{display:inline-block;transition:transform .42s var(--ease-release)}
.head__brand:hover img{transform:rotate(12deg)}
.head__brand:hover .dot{transform:scale(1.4)}
.head__nav{margin-left:auto;display:flex;gap:39.6px;transition:gap .45s var(--ease)}
.head__nav a{
  font-size:16.5px;color:var(--muted);position:relative;padding:4.4px 0;
  transition:color .2s;
}
.head__nav a::after{
  content:"";position:absolute;left:0;bottom:0;width:100%;height:1.1px;background:var(--red);
  transform:scaleX(0);transform-origin:right;transition:transform .38s var(--ease);
}
.head__nav a:hover{color:var(--ink)}
.head__nav a:hover::after,.head__nav a.is-active::after{transform:scaleX(1);transform-origin:left}
.head__nav a.is-active{color:var(--ink)}

/* ---------- botões ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  height:52.8px;padding:0 28.6px;border-radius:1098.9px;border:1.1px solid transparent;
  font-size:15.4px;font-weight:500;letter-spacing:-.01em;cursor:pointer;
  transition:background .25s,color .25s,border-color .25s,transform .25s var(--ease);
}

/* =========================================================
   liquid glass — base de todos os botões
   O contorno e um inset ring: fica colado no preenchimento,
   sem o vao de 1px que a borda transparente abria.
   ========================================================= */
.glass,.btn,.theme,.burger,.foot__up,.skills li{
  position:relative;isolation:isolate;overflow:hidden;
  border:0;
  background:
    linear-gradient(180deg,var(--lg-gloss),transparent 58%),
    var(--lg-fill);
  background-clip:padding-box;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  backdrop-filter:blur(18px) saturate(165%);
  -webkit-backdrop-filter:blur(18px) saturate(165%);
  box-shadow:
    inset 0 0 0 1px var(--lg-ring),   /* contorno */
    inset 0 1px 0 var(--lg-edge),     /* fio de luz na aresta de cima */
    0 1px 2px -1px var(--lg-drop),
    0 10px 22px -14px var(--lg-drop);
  --glow-r:120px;--glow-a:0;
  transition:
    transform .52s var(--ease-release),
    box-shadow .42s var(--ease-soft),
    background .34s var(--ease-soft),
    --glow-r .5s var(--ease-soft),
    --glow-a .38s var(--ease-soft),
    color .22s;
}
/* luz especular que segue o ponteiro */
.glass::after,.btn::after,.theme::after,.burger::after,.foot__up::after,.skills li::after{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:radial-gradient(circle var(--glow-r) at var(--mx,50%) var(--my,0%),
             var(--lg-sheen),transparent 68%);
  opacity:var(--glow-a);
}
/* bloom: a luz floresce do ponto tocado e se dissolve */
@keyframes glass-bloom{
  0%  {opacity:.95;transform:scale(.4)}
  55% {opacity:.5}
  100%{opacity:0;transform:scale(1.9)}
}
.is-bloom::after{
  animation:glass-bloom .62s var(--ease-soft) forwards;
  transform-origin:var(--mx,50%) var(--my,50%);
}
/* especular: uma cupula de luz que acompanha a pilula inteira */
.glass::before,.btn::before,.theme::before,.burger::before,.foot__up::before,.skills li::before{
  content:"";position:absolute;inset:0;z-index:-1;
  pointer-events:none;border-radius:inherit;
  background:radial-gradient(ellipse 132% 82% at 50% -34%,var(--lg-sheen),transparent 64%);
  transition:opacity .3s var(--ease-soft);
}

/* fallback previsivel quando o navegador nao oferece backdrop-filter */
@supports not ((backdrop-filter:blur(1.1px)) or (-webkit-backdrop-filter:blur(1.1px))){
  .glass,.btn,.theme,.burger,.foot__up,.skills li{background:color-mix(in srgb,var(--paper) 92%,var(--surface))}
  .btn--ink{background:var(--red)}
  .btn--red{background:var(--red)}
}
.glass:hover,.btn:hover,.theme:hover,.burger:hover,.foot__up:hover,.skills li:hover{
  background:
    linear-gradient(180deg,var(--lg-gloss),transparent 58%),
    var(--lg-fill-hover);
  background-clip:padding-box;
  --glow-r:170px;--glow-a:.9;
  transform:translateY(-1.5px);
  transition-duration:.34s,.3s,.28s,.34s,.3s,.2s;
  box-shadow:
    inset 0 0 0 1px var(--lg-ring-hover),
    inset 0 1px 0 var(--lg-edge),
    0 3px 6px -3px var(--lg-drop),
    0 20px 36px -18px var(--lg-drop-hover);
}
.glass:focus-visible,.btn:focus-visible,.theme:focus-visible,.burger:focus-visible,.foot__up:focus-visible{
  outline:2.2px solid var(--red);outline-offset:3.3px
}

/* =========================================================
   variantes tingidas — o MESMO vidro, so que pigmentado
   Nao sao pilulas chapadas: continuam translucidas, com
   backdrop-filter, contorno inset e especular proprios.
   ========================================================= */
.btn--ghost{color:var(--ink)}

/* A pilula de acao e vermelha nos dois temas. Como o tom sai de var(--red),
   cada tema usa o seu: #E4322A no claro, #FF4A3F no escuro. */
.btn--ink{
  color:#fff;
  background:
    linear-gradient(180deg,rgba(255,255,255,.24),transparent 56%),
    color-mix(in srgb,var(--red) 86%,transparent);
  background-clip:padding-box;
  backdrop-filter:blur(20px) saturate(190%);
  -webkit-backdrop-filter:blur(20px) saturate(190%);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--red) 70%,transparent),
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 -1px 0 rgba(0,0,0,.24),
    0 1px 2px -1px var(--lg-drop),
    0 14px 32px -14px color-mix(in srgb,var(--red) 46%,transparent);
}
/* a pilula ja e vermelha: o hover acende o mesmo vermelho em vez de inverter
   para o claro — invertendo, o botao "ficava branco" no clique */
.btn--ink:hover{
  background:
    linear-gradient(180deg,rgba(255,255,255,.34),transparent 56%),
    color-mix(in srgb,var(--red) 96%,transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--red) 82%,transparent),
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 -1px 0 rgba(0,0,0,.2),
    0 2px 5px -2px var(--lg-drop),
    0 22px 44px -16px color-mix(in srgb,var(--red) 54%,transparent);
}

.btn--red{
  height:59.4px;padding:0 37.4px;color:#fff;
  background:
    linear-gradient(180deg,rgba(255,255,255,.24),transparent 56%),
    color-mix(in srgb,var(--red) 86%,transparent);
  background-clip:padding-box;
  backdrop-filter:blur(20px) saturate(190%);
  -webkit-backdrop-filter:blur(20px) saturate(190%);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--red) 70%,transparent),
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 -1px 0 rgba(0,0,0,.24),
    0 1px 2px -1px var(--lg-drop),
    0 14px 32px -14px color-mix(in srgb,var(--red) 46%,transparent);
}
.btn--red:hover{
  background:
    linear-gradient(180deg,rgba(255,255,255,.2),transparent 56%),
    color-mix(in srgb,var(--ink) 86%,transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--ink) 66%,transparent),
    inset 0 1px 0 rgba(255,255,255,.32),
    inset 0 -1px 0 rgba(0,0,0,.34),
    0 2px 5px -2px var(--lg-drop),
    0 22px 44px -16px var(--lg-drop-hover);
}
/* o .btn--ink agora nasce vermelho nos dois temas, entao o bloco que o pintava
   so no escuro saiu: ele era copia da base e, por vir depois, ainda vencia o
   proprio :hover dela. Aqui fica so o .btn--red, que no claro inverte para o
   escuro e no escuro nao pode inverter — "ficava branco" no clique. */
[data-theme="dark"] .btn--red:hover{
  color:#fff;
  background:
    linear-gradient(180deg,rgba(255,255,255,.34),transparent 56%),
    color-mix(in srgb,var(--red) 96%,transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--red) 82%,transparent),
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 -1px 0 rgba(0,0,0,.2),
    0 2px 5px -2px var(--lg-drop),
    0 22px 44px -16px color-mix(in srgb,var(--red) 54%,transparent);
}

/* nas variantes escuras o especular branco de 75% estoura: e reduzido */
.btn--ink::before,.btn--red::before{
  background:radial-gradient(ellipse 132% 82% at 50% -34%,rgba(255,255,255,.28),transparent 64%);
}
.btn--ink::after,.btn--red::after{
  background:radial-gradient(circle var(--glow-r) at var(--mx,50%) var(--my,0%),
             rgba(255,255,255,.34),transparent 68%);
}

.head__cta{height:49.5px;padding:0 24.2px;font-size:15.4px}

/* ---------- modo escuro: nada de luz colada no ponteiro ----------
   No claro o fill do vidro e opaco (.82, e #FFF no hover), entao o especular
   radial do ::after e o bloom do clique ficam escondidos atras dele: o que se
   ve e o botao inteiro acendendo de uma vez. No escuro o fill e translucido
   (.08 / .15) e essa mesma luz aparecia por cima, como uma mancha que seguia
   o cursor e "escorria" do ponto do clique. Aqui ela e desligada; o brilho
   fica por conta do fill, do aro e do especular fixo do ::before. */
[data-theme="dark"] .glass::after,
[data-theme="dark"] .btn::after,
[data-theme="dark"] .theme::after,
[data-theme="dark"] .burger::after,
[data-theme="dark"] .foot__up::after,
[data-theme="dark"] .skills li::after{
  display:none;
}
/* sem a mancha, o hover repoe o brilho subindo o fill e o fio de luz */
[data-theme="dark"] .glass:hover,
[data-theme="dark"] .btn:hover:not(.btn--ink):not(.btn--red),
[data-theme="dark"] .theme:hover,[data-theme="dark"] .burger:hover,
[data-theme="dark"] .skills li:hover{
  background:
    linear-gradient(180deg,rgba(255,255,255,.13),transparent 58%),
    rgba(255,255,255,.185);
  background-clip:padding-box;
}


/* ---------- afundar no clique ----------
   Depois das variantes, para vencer os :hover tingidos. */
.btn--ghost:active,.glass:active,.theme:active,.burger:active,.foot__up:active,.skills li:active{
  color:var(--faint);
}
.glass:active,.btn:active:not(.btn--ink):not(.btn--red),
.theme:active,.burger:active,.foot__up:active,.skills li:active,
.glass.is-pressed,.btn.is-pressed:not(.btn--ink):not(.btn--red),
.theme.is-pressed,.burger.is-pressed,.foot__up.is-pressed{
  --glow-r:70px;--glow-a:.25;
  transform:translateY(1.5px) scale(.962);
  transition:transform .11s var(--ease-press),box-shadow .11s var(--ease-press),
             background .11s,color .11s,--glow-r .16s,--glow-a .16s;
  background:var(--lg-fill-press);
  box-shadow:
    inset 0 0 0 1px var(--lg-ring-hover),
    inset 0 3px 5px -1px var(--lg-press),
    inset 0 12px 20px -10px var(--lg-press);
}
.glass:active::before,.btn:active::before,.theme:active::before,.burger:active::before,.foot__up:active::before,
.glass.is-pressed::before,.btn.is-pressed::before,.theme.is-pressed::before,.burger.is-pressed::before,.foot__up.is-pressed::before{
  opacity:0
}
.btn--ink:active,.btn--red:active,.btn--ink.is-pressed,.btn--red.is-pressed{
  transform:translateY(1.5px) scale(.962);
  transition:transform .11s var(--ease-press),box-shadow .11s var(--ease-press),color .11s;
  /* a ultima sombra e uma camada chapada que escurece a pilula inteira: o tom
     continua sendo o do botao (vermelho no hero), so que rebaixado — antes o
     press trocava o fundo pelo vidro claro e a cor sumia no meio do clique */
  box-shadow:
    inset 0 3px 9px rgba(0,0,0,.42),
    inset 0 -1px 0 rgba(255,255,255,.18),
    inset 0 0 0 999px rgba(0,0,0,.16);
  /* o texto perde um pouco de forca junto com a pilula */
  color:rgba(255,255,255,.76);
}

/* ---------- afundar no clique: correcao do modo escuro ----------
   No escuro a cova era desenhada so com preto: o fill de pressao quase
   transparente sobre fundo #0B0B0D apagava o botao, a sombra larga de 20px
   preenchia a pilula inteira e o aro sumia junto com o texto em --faint.
   Aqui a cova vem de uma sombra curta no alto mais um fio de luz na aresta
   de baixo — que e o que faz o olho ler baixo-relevo quando nao ha fundo
   claro para escurecer. */
[data-theme="dark"] .glass:active,
[data-theme="dark"] .btn:active:not(.btn--ink):not(.btn--red),
[data-theme="dark"] .theme:active,[data-theme="dark"] .burger:active,
[data-theme="dark"] .skills li:active,
[data-theme="dark"] .glass.is-pressed,
[data-theme="dark"] .btn.is-pressed:not(.btn--ink):not(.btn--red),
[data-theme="dark"] .theme.is-pressed,[data-theme="dark"] .burger.is-pressed{
  /* opaco como no claro: o fill cobre o especular e o bloom, senao a luz do
     ponteiro vaza pelo botao apagado e o clique parece "escorrer" do dedo */
  --glow-a:0;
  background:
    linear-gradient(180deg,rgba(255,255,255,.05),transparent 62%),
    var(--lg-fill-press);
  background-clip:padding-box;
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.17),
    inset 0 4px 7px -3px rgba(0,0,0,.72),
    inset 0 -1px 0 rgba(255,255,255,.13);
}
/* --faint no escuro (#6B6B75) sobre a pilula afundada quase desaparece */
[data-theme="dark"] .btn--ghost:active,[data-theme="dark"] .glass:active,
[data-theme="dark"] .theme:active,[data-theme="dark"] .burger:active,
[data-theme="dark"] .skills li:active{
  color:var(--muted);
}
/* o hover tingido do escuro tem especificidade maior que o press base, entao
   as sombras de afundar precisam ser repetidas aqui — senao o botao vermelho
   so encolhia, sem escurecer */
[data-theme="dark"] .btn--ink:active,[data-theme="dark"] .btn--red:active,
[data-theme="dark"] .btn--ink.is-pressed,[data-theme="dark"] .btn--red.is-pressed{
  box-shadow:
    inset 0 3px 9px rgba(0,0,0,.4),
    inset 0 -1px 0 rgba(255,255,255,.2),
    inset 0 0 0 999px rgba(0,0,0,.22);
}
/* o botao de topo fica vermelho no hover: afunda como as pilulas tingidas,
   sem perder o pigmento */
[data-theme="dark"] .foot__up:active{
  background:var(--red);
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,.3),
    inset 0 3px 7px -2px rgba(0,0,0,.42),
    inset 0 -1px 0 rgba(255,255,255,.2);
  color:rgba(255,255,255,.76);
}

/* alternador de tema */
.theme{
  width:49.5px;height:49.5px;flex:none;border-radius:1098.9px;
  cursor:pointer;display:grid;place-items:center;
}
.theme svg{width:20.9px;height:20.9px;stroke:var(--ink);fill:none;stroke-width:1.6;stroke-linecap:round}
.theme__moon{display:none}
[data-theme="dark"] .theme__sun{display:none}
[data-theme="dark"] .theme__moon{display:block}

/* marca: troca o símbolo conforme o tema */
.brand-mark--dark{display:none}
[data-theme="dark"] .brand-mark--light{display:none}
[data-theme="dark"] .brand-mark--dark{display:block}

/* o ponto da marca é vermelho */
.dot{color:var(--red)}

/* ---------- menu mobile ---------- */
.burger{display:none;width:46.2px;height:46.2px;border-radius:1098.9px}
.burger span{position:absolute;left:13.2px;width:19.8px;height:1.65px;background:var(--ink);transition:transform .3s var(--ease),opacity .2s}
.burger span:nth-child(1){top:19.8px}
.burger span:nth-child(2){top:25.3px}
.burger.is-open span:nth-child(1){transform:translateY(2.75px) rotate(45deg)}
.burger.is-open span:nth-child(2){transform:translateY(-2.75px) rotate(-45deg)}
.menu{
  position:fixed;inset:0;z-index:75;background:var(--paper);padding:121px var(--gut) 44px;display:flex;
  opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-13.2px);
  transition:opacity .38s var(--ease-soft),transform .5s var(--ease),visibility 0s linear .5s;
}
.menu[hidden]{display:none}
.menu.is-open{opacity:1;visibility:visible;pointer-events:auto;transform:none;transition-delay:0s}
.menu-open{overflow:hidden}
.menu nav{display:flex;flex-direction:column;gap:6.6px;width:100%}
.menu a{
  display:flex;align-items:baseline;gap:17.6px;font-size:33px;font-weight:600;letter-spacing:-.03em;padding:15.4px 0;border-bottom:1.1px solid var(--line);
  opacity:0;transform:translateY(15.4px);transition:opacity .35s var(--ease-soft),transform .5s var(--ease);
}
.menu.is-open a{opacity:1;transform:none}
.menu.is-open a:nth-child(1){transition-delay:.06s}
.menu.is-open a:nth-child(2){transition-delay:.10s}
.menu.is-open a:nth-child(3){transition-delay:.14s}
.menu.is-open a:nth-child(4){transition-delay:.18s}
.menu.is-open a:nth-child(5){transition-delay:.22s}
.menu a i{font-style:normal;font-size:12.1px;font-weight:600;letter-spacing:.14em;color:var(--red)}

/* ---------- estrutura ---------- */
main{margin-left:var(--rail)}
.foot{margin-left:var(--rail)}
.sec{padding:clamp(92.4px,10vw,165px) var(--gut)}
.sec--surface{
  background:var(--surface);border:1.1px solid var(--line);border-inline:0;
  border-radius:var(--rsec) var(--rsec) 0 0;
}
.sec__head{max-width:var(--maxw);margin:0 auto clamp(52.8px,5vw,83.6px)}
.sec__head h2{margin-bottom:26.4px}
/* Serviços e Processo sao blocos densos: o ar de secao inteira que serve ao
   mosaico dos trabalhos deixava as duas com um vazio grande antes dos cartoes. */
#servicos,#processo{padding-block:clamp(72.6px,7.4vw,118.8px)}
#servicos .sec__head,#processo .sec__head{margin-bottom:clamp(35.2px,3.4vw,52.8px)}
#servicos .sec__head h2,#processo .sec__head h2{margin-bottom:19.8px}
#processo .sec__head{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(320px,.62fr);
  align-items:end;gap:clamp(35.2px,6vw,96.8px);
}
#processo .sec__head h2{margin-bottom:0}
#processo .sec__head .sec__lede{justify-self:end;max-width:48ch}
#trabalhos{padding-bottom:clamp(44px,5vw,77px)}

/* ---------- hero ---------- */
/* o hero ocupa a primeira tela inteira; o leque cresce para preencher a sobra */
.hero{
  position:relative;
  height:100svh;min-height:660px;
  display:flex;flex-direction:column;
  padding:104px 0 0;overflow:hidden;
  border-radius:0 0 var(--rsec) var(--rsec);
}
/* Fundo do hero: sem isto o backdrop-filter dos botoes nao tem o que refratar.
   Quatro nucleos de luz sobre uma base levemente mais escura que a pagina. */
.hero::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(58% 46% at 16% 8%,var(--hero-a),transparent 62%),
    radial-gradient(42% 40% at 84% 4%,var(--hero-b),transparent 66%),
    radial-gradient(48% 44% at 68% 46%,var(--hero-c),transparent 68%),
    radial-gradient(46% 40% at 24% 62%,var(--hero-d),transparent 70%),
    linear-gradient(180deg,var(--paper) 0%,var(--hero-base) 100%);
}
/* grao: tira o aspecto de degrade digital e da textura ao vidro */
.hero::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  opacity:var(--grain);mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>");
}
.hero__inner{flex:none}
.hero__inner{
  width:100%;max-width:calc(var(--maxw) + 2 * var(--gut));margin:0 auto;
  padding:clamp(13.2px,2vw,30.8px) var(--gut) clamp(26.4px,2.6vw,46.2px);
  position:relative;z-index:2;
}
.hero h1{margin-bottom:clamp(24.2px,2.6vw,37.4px);max-width:21ch;font-size:clamp(41.8px,5.9vw,90.2px)}
.hero__row{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(22px,4vw,66px);align-items:end;
}
.hero__cta{display:flex;flex-wrap:wrap;gap:13.2px;justify-content:flex-end}

/* Leque real: cartas empilhadas giram em torno de um pivô abaixo delas. */
.arc{
  --cards:8;--step:12.5deg;--radius:clamp(1120px,112vw,1760px);
  /* so encolhe em tela muito baixa; no resto mantem o tamanho cheio */
  --cw:clamp(160px,min(19vw,36vh),304px);--ch:calc(var(--cw) * 2.0132);
  position:relative;width:100%;overflow:visible;pointer-events:none;isolation:isolate;
  flex:1 1 auto;min-height:clamp(300px,34vw,480px);
  /* Os aparelhos das pontas sobem acima da caixa do leque conforme ele gira.
     A mascara lateral e recortada pela border-box (mask-clip padrao), entao sem
     esta folga o topo deles some. O padding cresce a caixa para cima e a margem
     negativa devolve o espaco: nada se move no layout, so para de cortar. */
  padding-top:180px;margin-top:-180px;
}
/* mascara no lugar dos degrades chapados: acompanha qualquer fundo */
.arc{-webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
             mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
/* ancorado pela base: o leque encosta no fim da tela e sangra por baixo,
   com o mesmo recorte independente da altura que o hero assumir */
.arc__wheel{position:absolute;left:50%;top:auto;bottom:calc(var(--ch) * -.17);width:var(--cw);height:var(--ch);margin-left:calc(var(--cw) * -.5)}
.arc__card{--angle:calc((var(--i) - 3.5) * var(--step));position:absolute;inset:0;width:var(--cw);height:var(--ch);background:transparent;border:0;transform-origin:50% var(--radius);transform:translateZ(0) rotate(var(--angle));backface-visibility:hidden;-webkit-backface-visibility:hidden;will-change:transform}
.arc__card::after{content:"";position:absolute;z-index:2;inset:0;background:url("hero/iphone-frame.webp") center/100% 100% no-repeat;pointer-events:none;filter:drop-shadow(0 26.4px 26.4px color-mix(in srgb,var(--shadow) 54%,transparent));transform:translateZ(0);backface-visibility:hidden}
/* recorte da tela do frame novo (1359x2736): janela transparente em
   x 90..1268 e y 90..2645 — 6.62% nas laterais, 3.29% em cima e embaixo. */
.arc__card img{position:absolute;z-index:1;inset:3.29% 6.62%;width:86.75%;height:93.42%;border-radius:14%/6.4%;object-fit:fill;display:block}
/* Cascata da esquerda para a direita: cada card por cima do seguinte.
   O JS reescreve estes valores a cada frame conforme o leque gira — isto aqui
   e o estado inicial e o fallback de prefers-reduced-motion, onde o JS nao roda. */
.arc__card:nth-child(1){z-index:9}
.arc__card:nth-child(2){z-index:8}
.arc__card:nth-child(3){z-index:7}
.arc__card:nth-child(4){z-index:6}
.arc__card:nth-child(5){z-index:5}
.arc__card:nth-child(6){z-index:4}
.arc__card:nth-child(7){z-index:3}
.arc__card:nth-child(8){z-index:2}

/* Duas esteiras de ferramentas, como na referencia enviada. */
.toolbelt{
  --tool-gap:19.8px;--loop-offset:9.9px;
  position:relative;flex:none;width:100%;height:clamp(242px,20vw,286px);
  padding:26.4px 0;overflow:hidden;display:grid;align-content:center;gap:17.6px;
  background:linear-gradient(180deg,transparent,var(--tool-wash),transparent);
}
/* Antes as pontas desbotavam com mask-image. A mascara obriga a esteira inteira
   — inclusive o glow desfocado — a virar uma camada so, re-rasterizada a cada
   frame da marquee: a pagina caia para 1 fps. Dois degrades por cima fazem o
   mesmo efeito e nao custam nada. */
.toolbelt::before,.toolbelt::after{
  content:"";position:absolute;z-index:3;top:0;bottom:0;width:9%;pointer-events:none;
}
.toolbelt::before{left:0;background:linear-gradient(90deg,var(--paper),transparent)}
.toolbelt::after{right:0;background:linear-gradient(-90deg,var(--paper),transparent)}
/* O brilho de fundo usava filter:blur(24px) num elemento proprio. Atras de uma
   esteira em animacao continua, esse filtro era reaplicado a cada frame e
   derrubava a pagina para 1 fps (esconde-lo devolvia 61 fps). Um degrade radial
   com queda longa da o mesmo aspecto difuso e nao custa filtro nenhum. */
.toolbelt__glow{
  position:absolute;left:50%;top:50%;width:78%;height:130%;
  transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(ellipse at center,
    var(--tool-glow) 0%,
    color-mix(in srgb,var(--tool-glow) 55%,transparent) 34%,
    color-mix(in srgb,var(--tool-glow) 18%,transparent) 58%,
    transparent 78%);
}
.toolbelt__row{display:flex;width:100%;overflow:hidden;position:relative;z-index:2}
.toolbelt__track{display:flex;flex:none;gap:var(--tool-gap);width:max-content;animation:tool-marquee 36s linear infinite;will-change:transform;transform:translate3d(0,0,0);backface-visibility:hidden}
.toolbelt__row--reverse .toolbelt__track{animation-direction:reverse;animation-duration:40s}
.tool{width:85.8px;height:85.8px;flex:none;position:relative;isolation:isolate;overflow:hidden;background-clip:padding-box;-webkit-mask-image:-webkit-radial-gradient(white,black);backface-visibility:hidden;display:grid;place-items:center;border:0;border-radius:16.5px;background:linear-gradient(180deg,var(--lg-gloss),transparent 58%),var(--lg-fill);background-clip:padding-box;box-shadow:inset 0 0 0 1px var(--lg-ring),inset 0 1px 0 var(--lg-edge),0 14px 28px -22px var(--lg-drop);font-weight:600;font-size:19.8px;letter-spacing:-.04em;color:var(--ink)}
.tool::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(ellipse 92% 64% at 50% -8%,var(--lg-sheen),transparent 72%);opacity:.42}
.tool--figma{color:#ff7262}.tool--ps{color:#31a8ff}.tool--ai{color:#ff9a00}.tool--xd{color:#ff61f6}.tool--web{color:#775cff}.tool--html{color:#ff5a3c;font-size:14.3px}.tool--css{color:#5b8cff}.tool--js{color:#e2b714}.tool--wp{color:#38a7d8}.tool--seo{color:#56c487;font-size:27.5px}.tool--gr{color:var(--red)}.tool--code{color:#a881ff}
@keyframes tool-marquee{to{transform:translate3d(calc(-50% - var(--loop-offset)),0,0)}}

/* ---------- trabalhos: um bento por marca ---------- */
.cases{max-width:var(--maxw);margin:0 auto;display:flex;flex-direction:column;gap:clamp(61.6px,7vw,121px)}

.case__head{
  display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);
  row-gap:4.4px;column-gap:clamp(19.8px,4vw,70.4px);align-items:end;
  padding-bottom:24.2px;margin-bottom:19.8px;border-bottom:1.1px solid var(--line);
}
.case__cat{
  grid-column:1;grid-row:1;
  font-size:11.55px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;color:var(--red);
  margin-bottom:6.6px;
}
.case__head h3{
  grid-column:1;grid-row:2;
  font-size:clamp(30.8px,3.6vw,55px);font-weight:600;letter-spacing:-.035em;line-height:1;
}
.case__desc{
  grid-column:2;grid-row:2;
  color:var(--muted);font-size:16.5px;line-height:1.6;max-width:52ch;
  justify-self:end;text-align:right;
}

.case__grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  grid-auto-rows:clamp(132px,12vw,195.8px);gap:15.4px;
  /* com blocos de 2 linhas no mosaico sobra buraco no fim da fila:
     o dense puxa a proxima peca que couber para dentro dele */
  grid-auto-flow:row dense;
}
.cell{
  background:var(--ph);border:1.1px solid var(--line);border-radius:var(--r);
  overflow:hidden;display:grid;place-items:center;padding:22px;
  transition:background .35s,border-color .3s,transform .5s var(--ease),box-shadow .5s var(--ease);
}
.cell span{font-size:13.2px;line-height:1.6;color:var(--faint);text-align:center;max-width:30ch}
.cell--xl{grid-column:span 2;grid-row:span 2}
.cell--w{grid-column:span 2}

/* espelha o mosaico do segundo caso */
.case--flip .case__grid{direction:rtl}
.case--flip .cell{direction:ltr}
/* mesma estrutura do cabecalho dos outros casos (categoria + titulo de um lado,
   descricao na mesma linha do titulo), so que espelhada: tudo alinhado a direita */
.case--flip .case__head{grid-template-columns:minmax(0,1fr) minmax(0,auto)}
.case--flip .case__cat{
  grid-column:2;grid-row:1;justify-self:end;text-align:right;
}
.case--flip .case__head h3{
  grid-column:2;grid-row:2;justify-self:end;text-align:right;
}
.case--flip .case__desc{
  grid-column:1;grid-row:2;justify-self:start;text-align:left;min-width:0;
}

/* =========================================================
   CASE AO VIVO — o site inteiro dentro do card
   O iframe recebe um viewport FIXO (1440x900 no desktop) e e reduzido por
   transform ate a largura do card. Sem isso, o iframe herdaria a largura do
   card (~600px) e a pagina de dentro cairia no proprio layout mobile — o
   visitante veria a versao estreita achando que e o site de desktop.
   O viewport e 1440x900 em QUALQUER tela, inclusive no celular. O card e uma
   miniatura do trabalho, e trabalho de web se apresenta na versao web: trocar
   para a versao mobile no telefone faria o mesmo projeto mudar de cara conforme
   o aparelho de quem visita, e a secao perderia a leitura de conjunto — quatro
   pecas do mesmo formato, uma embaixo da outra.
   A escala vem do JS (uma conta so, em ResizeObserver): CSS nao divide
   comprimento por comprimento para gerar o numero que scale() exige. */
.case__live{
  --vw:1440;--vh:900;
  position:relative;display:block;
  aspect-ratio:var(--vw) / var(--vh);
  border:1.1px solid var(--line);
  /* --r (15.4px) e o raio dos blocos pequenos do mosaico. Num card que passa
     de 1000px de largura no desktop ele some: o canto le como reto e a
     miniatura fica com cara de captura de tela, nao de aparelho. O raio aqui
     acompanha a largura da tela, como ja fazem os outros cards grandes. */
  border-radius:clamp(16px,2.1vw,30px);
  overflow:hidden;background:var(--ph);
  box-shadow:0 30.8px 66px -57.2px var(--shadow);
  transition:border-color .3s,box-shadow .5s var(--ease),transform .5s var(--ease);
}
.case__live iframe{
  position:absolute;top:0;left:0;
  width:calc(var(--vw) * 1px);height:calc(var(--vh) * 1px);
  border:0;
  /* nada aqui dentro recebe ponteiro: sem clique, sem selecao, sem rolagem
     roubada quando o dedo passa por cima do card */
  pointer-events:none;
  transform-origin:0 0;
  transform:scale(var(--k,1));
}
/* enquanto o JS nao mediu, o iframe fica escondido para nao aparecer em
   tamanho real e vazar do card por um quadro */
.case__live:not([style*="--k"]) iframe{opacity:0}
.case__live{transition:border-color .3s,box-shadow .5s var(--ease),transform .5s var(--ease)}
.case__live iframe{transition:opacity .4s var(--ease-soft)}

/* O card e vitrine, nao controle: sem cursor de link, sem hover que prometa
   clique e sem foco de teclado. O iframe ja vem com pointer-events desligado,
   entao nem arrastar dentro dele funciona. */
.case__live{cursor:default;user-select:none}

/* quando a foto real entrar no lugar do placeholder */
.cell:has(img){padding:0}
.cell img{width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease)}
/* peças de arte chapada (logo, paleta, versões, tipografia) aparecem inteiras.
   O fundo do bloco recebe a cor do proprio fundo da arte (--fit-bg, no HTML):
   a faixa que sobra do contain funde com a peca e a imagem parece encaixada
   de ponta a ponta, em vez de flutuar numa moldura de outra cor. */
.cell--fit:has(img){padding:0;background:var(--fit-bg,var(--surface));position:relative}
.cell--fit img{
  position:absolute;inset:0;margin:auto;
  width:auto;height:auto;max-width:100%;max-height:100%;
  object-fit:contain;
}
/* bloco de duas linhas: para peca em retrato ou banner que nao cabe deitado */
.cell--tall{grid-row:span 2}

/* ---------- serviços ---------- */
/* Um unico painel editorial substitui as tres caixas soltas. Os servicos sao
   partes da mesma entrega e o vermelho aparece somente no item em foco. */
.svcs{
  max-width:var(--maxw);margin:0 auto;display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));gap:0;
  overflow:hidden;overflow:clip;border:1.1px solid var(--line);border-radius:clamp(15.4px,1.6vw,22px);
  background:var(--paper);box-shadow:0 30.8px 66px -57.2px var(--shadow);
}
.svc{
  position:relative;min-width:0;padding:clamp(28.6px,2.7vw,39.6px);
  display:flex;flex-direction:column;cursor:default;
  background:transparent;border:0;border-radius:0;
  transition:background-color .42s var(--ease-soft);
}
.svc+.svc{border-left:1.1px solid var(--line)}
/* indicador integrado ao frame: horizontal no desktop e vertical quando os
   servicos viram uma sequencia de leitura. */
.svc::before{
  content:"";position:absolute;z-index:2;left:0;right:0;top:0;height:2.2px;
  background:var(--red);transform:scaleX(0);transform-origin:left;
  transition:transform .55s var(--ease);
}
.svc__top{display:flex;align-items:center;justify-content:space-between;gap:13.2px;margin-bottom:28.6px}
.svc__n{
  color:var(--faint);font-family:'Jersey 10','Courier New',monospace;
  font-size:46.2px;line-height:.8;letter-spacing:.02em;
  transition:color .4s var(--ease-soft),transform .5s var(--ease);
}
/* O processo mantem seus indices circulares; os servicos usam numeracao
   tipografica para nao repetir a mesma peca em duas secoes consecutivas. */
.step__n{
  width:37.4px;height:37.4px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:var(--red);color:#fff;
  font-family:'Jersey 10','Courier New',monospace;font-size:20.9px;line-height:1;
  letter-spacing:.04em;padding-top:2.2px;
}
.svc__heading{display:flex;flex-wrap:wrap;align-items:center;gap:9.9px 13.2px;margin-bottom:11px}
.svc h3{font-size:clamp(26.4px,2.1vw,31.9px);font-weight:600;letter-spacing:-.04em;line-height:1.08}
.svc__popular{
  display:inline-flex;align-items:center;height:24.2px;padding:0 9.9px;border-radius:1098.9px;
  border:1.1px solid color-mix(in srgb,var(--red) 30%,var(--line));
  background:color-mix(in srgb,var(--red) 8%,var(--paper));
  color:color-mix(in srgb,var(--red) 72%,var(--ink));
  font-size:9.9px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
}
.svc>p{max-width:38ch;color:var(--muted);font-size:16.5px;line-height:1.62}
.svc__scope{margin-top:28.6px}
.svc__list{border-top:1.1px solid var(--line)}
.svc__list li{
  padding:10.45px 0;border-bottom:1.1px solid color-mix(in srgb,var(--line) 72%,transparent);
  color:var(--muted);font-size:14.3px;line-height:1.45;
}
.svc__cta{
  margin-top:auto;padding-top:24.2px;display:flex;align-items:center;justify-content:space-between;gap:17.6px;
  color:var(--ink);font-size:14.3px;font-weight:600;letter-spacing:-.01em;
  transition:color .25s var(--ease-soft);
}
.svc__cta span{
  width:30.8px;height:30.8px;flex:none;display:grid;place-items:center;border-radius:50%;
  border:1.1px solid var(--line);transition:color .25s,border-color .25s,transform .4s var(--ease);
}
.svc__cta:hover{color:var(--red)}
.svc__cta:hover span{color:var(--red);border-color:color-mix(in srgb,var(--red) 45%,var(--line));transform:translate(2.2px,-2.2px)}
.svc.is-current,.svc:focus-within{background:color-mix(in srgb,var(--red) 4%,var(--paper))}
.svc.is-current::before,.svc:focus-within::before{transform:scaleX(1)}
.svc.is-current .svc__n,.svc:focus-within .svc__n{color:var(--red)}
.tag{
  position:relative;z-index:1;
  display:inline-flex;align-items:center;min-height:28.6px;padding:4.4px 13.2px;border-radius:1098.9px;
  border:1.1px solid var(--line);background:var(--surface);
  font-size:11px;font-weight:600;line-height:1.2;letter-spacing:.11em;text-transform:uppercase;color:var(--muted);
}
.sec--surface .tag{background:var(--surface)}
.tag--red{background:var(--red);border-color:var(--red);color:#fff}
.sec--surface .tag--red{background:var(--red)}

/* ---------- processo ---------- */
/* Uma unica folha editorial. As quatro faixas ocupam quatro alturas reais,
   portanto cada checkpoint tem seu proprio momento de rolagem. */
.steps{
  --local-start:0px;--local-span:0px;--local-fill:0px;
  position:relative;max-width:var(--maxw);margin:0 auto;overflow:hidden;overflow:clip;
  border:1.1px solid var(--line);border-radius:clamp(15.4px,1.6vw,22px);
  background:var(--paper);box-shadow:0 30.8px 66px -57.2px var(--shadow);
}
.step{
  position:relative;min-height:145.2px;
  display:grid;grid-template-columns:61.6px minmax(176px,.62fr) minmax(300px,1.25fr) minmax(187px,.68fr);
  align-items:center;column-gap:clamp(24.2px,3vw,52.8px);
  padding:clamp(26.4px,2.5vw,35.2px) clamp(28.6px,3vw,44px);
  background-color:transparent;border:0;border-radius:0;
}
.step+.step{border-top:1.1px solid var(--line)}
.step::before{
  content:"";position:absolute;z-index:2;left:0;top:0;bottom:0;width:3.3px;
  background:var(--red);transform:scaleY(0);transform-origin:center;
  transition:transform .42s var(--ease);
}
.step__n{
  width:auto;height:auto;display:block;padding:0;border-radius:0;background:transparent;
  color:var(--faint);font-family:'Jersey 10','Courier New',monospace;
  font-size:clamp(42px,3.8vw,55px);line-height:.8;letter-spacing:.03em;
  transition:color .28s var(--ease-soft),transform .38s var(--ease);
}
.step__heading{min-width:0}
.step__phase{
  display:flex;align-items:center;gap:9.9px;margin-bottom:7.7px;
  color:var(--faint);font-size:10.45px;font-weight:600;line-height:1.2;
  letter-spacing:.15em;text-transform:uppercase;
  transition:color .28s var(--ease-soft);
}
.step__phase::before{
  content:"";width:14.3px;height:1.1px;flex:none;background:var(--line);
  transition:width .38s var(--ease),background-color .28s var(--ease-soft);
}
.step h3{
  font-size:clamp(24.2px,2vw,30.8px);font-weight:600;
  letter-spacing:-.035em;line-height:1.08;
}
/* O texto da etapa acompanha o destaque: cinza enquanto a etapa esta so
   esperando a vez, vermelho na etapa que o cursor esta lendo. Sem isso as
   quatro descricoes tinham exatamente a mesma cor e nada dizia ao olho qual
   delas corresponde ao ponto aceso no trilho. */
.step__desc{
  color:var(--muted);font-size:16.5px;line-height:1.62;max-width:54ch;
  transition:color .28s var(--ease-soft);
}
.step__out{
  display:flex;flex-direction:column;align-items:flex-start;gap:5.5px;
  margin:0;padding-left:22px;border-left:1.1px solid var(--line);
}
.step__out span{
  color:var(--faint);font-size:9.9px;font-weight:600;line-height:1.2;
  letter-spacing:.14em;text-transform:uppercase;
}
.step__out strong{
  color:var(--ink);font-size:14.85px;font-weight:600;line-height:1.35;
  letter-spacing:-.015em;
}
/* As quatro etapas trocam de estado enquanto a pessoa rola: sem transicao
   declarada, fundo, barra e numero pulavam de um valor para o outro no quadro
   em que a classe muda. Uma curva so, e todas as pecas da etapa chegam juntas. */
.step{transition:background-color .42s var(--ease-soft)}
.step::before{transition:transform .42s var(--ease),background-color .32s var(--ease-soft)}
.step__n{transition:color .32s var(--ease-soft),transform .42s var(--ease)}
.step__out{transition:border-left-color .32s var(--ease-soft)}
.step.is-past .step__n{color:color-mix(in srgb,var(--red) 62%,var(--faint))}
.step.is-past .step__phase::before{background:color-mix(in srgb,var(--red) 58%,var(--line))}
.step.is-current{background-color:color-mix(in srgb,var(--red) 4.5%,var(--paper))}
.step.is-current::before{transform:scaleY(1)}
.step.is-current .step__n{color:var(--red);transform:translateX(3.3px)}
.step.is-current .step__phase{color:var(--red)}
.step.is-current .step__phase::before{width:22px;background:var(--red)}
.step.is-current .step__out{border-left-color:color-mix(in srgb,var(--red) 50%,var(--line))}
.step.is-current .step__desc{color:var(--red)}

/* ---------- sobre ---------- */
.about{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:minmax(0,374px) minmax(0,1fr);
  gap:clamp(33px,5vw,88px);align-items:start;
}
.about__card{
  border:1.1px solid var(--line);border-radius:var(--r);padding:22px;
  position:sticky;top:121px;background:var(--card);
}
.about__ph{
  aspect-ratio:4/5;background:var(--ph);border-radius:8.8px;display:grid;place-items:center;margin-bottom:22px;
}
.about__ph span{font-size:13.2px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.about__ph img{width:100%;height:100%;object-fit:cover;object-position:center 48%;border-radius:8.8px}
.about__card h3{font-size:22px;font-weight:600;letter-spacing:-.03em}
.about__role{font-size:14.3px;color:var(--red);font-weight:500;margin-bottom:19.8px}
.about__facts{display:flex;flex-direction:column;gap:11px;border-top:1.1px solid var(--line);padding-top:17.6px}
.about__facts div{display:flex;justify-content:space-between;gap:15.4px}
.about__facts dt{font-size:13.2px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.about__facts dd{font-size:14.85px;margin:0;text-align:right}
.about__text h2{margin-bottom:28.6px;max-width:none}
/* No desktop o agrupador nao cria uma caixa e preserva a composicao original.
   No mobile ele passa a controlar as quebras da frase pixelada. */
.about__accent{display:contents}
/* segundo perfil: mesmo bloco, card do outro lado */
.about + .about{
  margin-top:clamp(55px,7vw,110px);padding-top:clamp(55px,7vw,110px);
  border-top:1.1px solid var(--line);
}
.about--flip{grid-template-columns:minmax(0,1fr) minmax(0,374px)}
/* O card do segundo perfil NAO gruda. No primeiro, o card e a coluna da
   esquerda e a leitura corre ao lado dele: faz sentido ele esperar ali.
   No segundo, ele esta na direita e o texto e mais longo (dois ledes), entao o
   card descia a secao inteira colado no topo da tela — uma peca perseguindo a
   rolagem, sem nada para sustentar. Aqui ele fica onde nasce e sai de cena com
   o resto do bloco. */
.about--flip .about__card{grid-column:2;grid-row:1;position:static}
.about--flip .about__text{grid-column:1;grid-row:1}
/* O espelho do segundo perfil e SO de composicao: o card troca de lado, o
   texto nao. Titulo, ledes, citacao e habilidades ficam alinhados a esquerda
   nos dois perfis, em qualquer largura — a barra vermelha da citacao continua
   na esquerda e a lista de habilidades continua comecando na esquerda.
   Ja existiu aqui um bloco espelhando o texto para a direita acima de 1081px;
   foi retirado de proposito: alinhado a direita, a margem esquerda do
   paragrafo fica serrilhada, e e justamente a borda que o olho procura para
   voltar ao comeco de cada linha. */
.quote{
  margin:41.8px 0 37.4px;padding-left:28.6px;border-left:2.2px solid var(--red);
  font-size:clamp(19.8px,2vw,26.4px);line-height:1.42;letter-spacing:-.025em;max-width:34ch;
}
.skills{display:flex;flex-wrap:wrap;gap:8.8px}
.skills li{
  border-radius:1098.9px;padding:8.8px 17.6px;
  color:var(--muted);font-size:14.3px;
}
.skills li:hover{color:var(--ink);transform:translateY(-2px)}
/* O bloco "afundar no clique" mora la em cima, antes desta secao, e tem a mesma
   especificidade deste :hover — entao o :hover ganhava por vir depois e o chip
   nunca afundava (pressionar sempre implica estar sobre ele). Aqui o transform
   do estado pressionado volta; o resto (fundo, sombra) o bloco de la ja aplica. */
.skills li:active{transform:translateY(1.5px) scale(.962)}

/* ---------- contato ---------- */
.sec--contact{
  background:var(--surface);border-top:1.1px solid var(--line);
  border-radius:var(--rsec) var(--rsec) 0 0;
}
.contact{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.12fr);
  gap:clamp(39.6px,5vw,99px);align-items:start;
}
/* o lado esquerdo acompanha a rolagem enquanto o formulario passa ao lado —
   mesmo comportamento do card do Sobre. So no desktop: empilhado nao faz
   sentido grudar. */
@media (min-width:1081px){
  .contact__side{position:sticky;top:121px}
}
.contact__side h2{margin-bottom:26.4px}
.contact__list{margin-top:37.4px;display:flex;flex-direction:column}
.contact__list li{
  padding:16.5px 0;border-bottom:1.1px solid var(--line);font-size:16.5px;color:var(--muted);
  display:flex;align-items:center;gap:13.2px;
}
.contact__list li::before{content:"";width:5.5px;height:5.5px;border-radius:50%;background:var(--red);flex:none}

/* ---------- formulario ----------
   O formulario e um PAINEL, com o mesmo tratamento dos outros paineis da pagina
   (.svcs, .steps): fundo de papel, fio de 1.1px e a sombra rasa e larga que
   descola a peca da secao. Ele era o unico painel do site sem essa sombra.
   Dentro dele os campos sao caixas de verdade — poco branco, fio proprio, 11px
   de raio —, porque e assim que se le "aqui se escreve". */
.form{
  background:var(--paper);border:1.1px solid var(--line);border-radius:var(--r);
  box-shadow:0 30.8px 66px -57.2px var(--shadow);
  padding:clamp(26.4px,3vw,37.4px);
  display:grid;grid-template-columns:1fr 1fr;gap:17.6px;
  transition:border-color .3s var(--ease-soft),box-shadow .34s var(--ease-soft);
}
/* enquanto se preenche, o painel inteiro se acende de leve: o cartao sai do
   repouso junto com o campo, em vez de so o campo reagir dentro de uma caixa
   parada. Mesma ideia do .svc.is-current, na dose de um fundo. */
.form:focus-within{
  border-color:color-mix(in srgb,var(--red) 26%,var(--line));
  box-shadow:0 0 0 1.1px color-mix(in srgb,var(--red) 12%,transparent),
             0 30.8px 66px -57.2px var(--shadow);
}
.field{display:flex;flex-direction:column;gap:7.7px;min-width:0}
.field--full{grid-column:1/-1}
/* rotulo em corpo de texto, nao em versalete: quem esta preenchendo le o nome
   do campo de relance, e caixa alta com entrelinha aberta se le mais devagar */
.field label{
  font-size:14.3px;font-weight:600;letter-spacing:-.005em;color:var(--muted);
  transition:color .25s var(--ease-soft);
}
.req{color:var(--red)}
.field input,.field select,.field textarea{
  width:100%;background:var(--card);
  border:1.1px solid var(--line);border-radius:11px;
  font-size:16.5px;letter-spacing:-.01em;
  transition:border-color .2s var(--ease-soft),box-shadow .2s var(--ease-soft),
             background-color .2s var(--ease-soft);
  appearance:none;
}
/* altura fixa nos campos de uma linha: com padding vertical, input e select
   fechavam alturas diferentes lado a lado (o select conta a caixa de opcoes) */
.field input,.field select{height:50.6px;padding:0 16.5px}
.field textarea{padding:13.2px 16.5px;min-height:114.4px;line-height:1.6;resize:vertical}
.field select{
  padding-right:41.8px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6E76' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15.4px center;background-size:16.5px;
}
[data-theme="dark"] .field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239C9CA6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* a lista aberta do select e pintada pelo sistema; sem isto ela sai branca no
   modo escuro em Windows e Linux */
.field select option{background:var(--card);color:var(--ink)}
.field input::placeholder,.field textarea::placeholder{color:var(--faint);opacity:1}
/* enquanto nada foi escolhido, o select fica no tom de placeholder — senao
   "Selecione uma opcao" chega na cor de resposta preenchida */
.field select:has(option[value=""]:checked){color:var(--faint)}
@media (hover:hover){
  .field input:hover,.field select:hover,.field textarea:hover{
    border-color:color-mix(in srgb,var(--ink) 26%,var(--line));
  }
}
/* Foco: o fio vira o vermelho da marca e um anel de 3.3px se abre em volta.
   E o mesmo vermelho do :focus-visible de todos os controles do site. */
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--red);
  box-shadow:0 0 0 3.3px color-mix(in srgb,var(--red) 15%,transparent);
}
/* O erro tambem e vermelho — se distingue do foco pelo poco lavado de vermelho
   e pelo rotulo aceso, e nao pela cor do fio. Assim um campo invalido continua
   legivel como invalido enquanto esta sendo corrigido. */
.field.is-bad label{color:var(--red)}
.field.is-bad input,.field.is-bad select,.field.is-bad textarea{
  border-color:var(--red);background:color-mix(in srgb,var(--red) 5%,var(--card));
}
.field.is-bad input:focus,.field.is-bad select:focus,.field.is-bad textarea:focus{
  box-shadow:0 0 0 3.3px color-mix(in srgb,var(--red) 17%,transparent);
}
/* O autofill do Chrome pinta o campo de amarelo por cima de tudo. A sombra
   interna de 1000px repinta o poco e o text-fill devolve a cor do texto. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px var(--card) inset;
  -webkit-text-fill-color:var(--ink);
  caret-color:var(--ink);
}
.field__count{
  align-self:flex-end;margin:0;
  font-size:12.65px;letter-spacing:.02em;color:var(--faint);
  font-variant-numeric:tabular-nums;
}
.field__count.is-full{color:var(--red)}
/* O envio ocupa a largura do painel: e a unica acao do bloco, e uma pilula
   curta encostada na esquerda deixava um vazio grande a direita do cartao. */
.form__send{grid-column:1/-1;width:100%;height:59.4px;margin-top:6.6px}
/* o aviso so ocupa espaco quando tem o que dizer */
.form__note{
  grid-column:1/-1;margin-top:-6.6px;
  font-size:14.3px;line-height:1.5;color:var(--muted);text-align:center;
}
.form__note:empty{display:none}
.form__note.is-bad{color:var(--red)}
/* a linha de tranquilidade sob o botao: quem chega ate aqui esta decidindo se
   entrega o proprio contato, e essa e a duvida que sobra */
.form__foot{
  grid-column:1/-1;margin-top:-6.6px;
  font-size:12.65px;line-height:1.5;color:var(--faint);text-align:center;
}

/* ---------- footer ---------- */
.foot{
  border-top:1.1px solid var(--line);
  padding:clamp(28.6px,3vw,41.8px) var(--gut) 24.2px;
}
.foot__top,.foot__bottom{max-width:var(--maxw);margin-inline:auto;display:flex;align-items:center;justify-content:space-between;gap:26.4px}
.foot__top{padding-bottom:clamp(26.4px,2.8vw,39.6px)}
.foot__bottom{padding-top:18.7px;border-top:1.1px solid var(--line)}
/* rodape usa o mesmo lockup do header — mesmo simbolo, mesma proporcao */
.foot__brand{display:inline-flex;color:inherit}
.foot__up{width:48.4px;height:48.4px;flex:none;display:grid;place-items:center;border-radius:50%;font-size:19.8px}
.foot__up:hover{color:#fff;background:var(--red);border-color:var(--red);transform:translate(2.2px,-2.2px)}
.foot__nav{display:flex;align-items:center;gap:24.2px;font-size:13.75px;color:var(--muted)}
.foot__nav a{position:relative;transition:color .2s}
.foot__nav a:hover{color:var(--ink)}
/* as duas bases sao dois itens, separados pelo ponto vermelho da marca — o
   mesmo bullet da lista de contato. Assim elas quebram em linhas proprias no
   mobile em vez de virar uma frase unica com pipe e travessoes */
.foot__local{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:4.4px 13.2px;font-size:13.75px;color:var(--muted);letter-spacing:.02em;
}
.foot__local span{display:inline-flex;align-items:center;gap:13.2px;white-space:nowrap}
.foot__local span+span::before{
  content:"";width:4.4px;height:4.4px;border-radius:50%;background:var(--red);flex:none;
}
.foot__copy{font-size:13.75px;color:var(--faint)}

/* ---------- reveal ---------- */
.reveal{
  opacity:0;transform:translate3d(0,19.8px,0);
  transition:opacity .78s var(--ease-soft) var(--reveal-delay,0ms),transform .82s var(--ease) var(--reveal-delay,0ms);
  will-change:opacity,transform;
}
.reveal.is-in{opacity:1;transform:none;will-change:auto}
/* O reveal define a propriedade transition inteira; os servicos recompõem a
   lista para que o wash do item em foco continue suave depois da entrada. */
.svc.reveal{
  transition:opacity .78s var(--ease-soft) var(--reveal-delay,0ms),
             transform .82s var(--ease) var(--reveal-delay,0ms),
             background-color .42s var(--ease-soft);
}
.step.reveal{
  transition:opacity .78s var(--ease-soft) var(--reveal-delay,0ms),
             transform .82s var(--ease) var(--reveal-delay,0ms),
             background-color .32s var(--ease-soft);
}

/* Evita estados de hover presos em telas touch. */
@media (hover:hover) and (pointer:fine){
  .cell:hover{background:var(--ph2);border-color:var(--ink);transform:translateY(-3.3px);box-shadow:0 26.4px 50.6px -37.4px var(--shadow)}
  .cell:hover img{transform:scale(1.035)}
  /* mesmo gesto do mosaico dos trabalhos: sobe 3.3px com sombra baixa */
  .svc:hover{background:color-mix(in srgb,var(--red) 4%,var(--paper))}
  .svc:hover::before{transform:scaleX(1)}
  .svc:hover .svc__n{color:var(--red);transform:translateY(-2.2px)}
  .step:not(.is-current):hover{background-color:color-mix(in srgb,var(--red) 2%,var(--paper))}
}

/* ---------- responsivo ---------- */
/* O processo precisa virar tres colunas um pouco antes do restante da pagina:
   entre 1081 e 1100px a entrega final ficaria espremida no frame de quatro. */
@media (max-width:1100px){
  .step{
    grid-template-columns:52.8px minmax(165px,.62fr) minmax(0,1fr);
    row-gap:17.6px;min-height:0;
  }
  .step__out{
    grid-column:2/4;display:grid;grid-template-columns:145.2px minmax(0,1fr);
    align-items:center;gap:17.6px;padding:15.4px 0 0;border-left:0;border-top:1.1px solid var(--line);
  }
}
@media (max-width:1080px){
  .hero__row{grid-template-columns:1fr;align-items:start;gap:28.6px}
  .hero__cta{justify-content:flex-start}
  .case__head{grid-template-columns:1fr;row-gap:13.2px}
  .case__cat,.case__head h3,.case__desc{grid-column:1!important}
  .case__cat{grid-row:1!important}
  .case__head h3{grid-row:2!important}
  .case__desc{grid-row:3!important;justify-self:start!important;text-align:left!important;max-width:60ch}
  .case--flip .case__head{grid-template-columns:1fr}
  .case--flip .case__cat,.case--flip .case__head h3,.case--flip .case__desc{
    justify-self:end!important;text-align:right!important;
  }
  /* Tablet: o painel vira tres linhas editoriais, ainda dentro do mesmo frame. */
  .svcs{grid-template-columns:1fr}
  .svc{
    min-height:0;display:grid;
    grid-template-columns:105.6px minmax(0,.82fr) minmax(300px,1.18fr);
    grid-template-rows:auto auto minmax(44px,1fr);
    column-gap:clamp(24.2px,4vw,48.4px);padding:28.6px;
  }
  .svc+.svc{border-left:0;border-top:1.1px solid var(--line)}
  .svc::before{
    left:0;right:auto;top:0;bottom:0;width:2.2px;height:auto;
    transform:scaleY(0);transform-origin:top;
  }
  .svc.is-current::before,.svc:focus-within::before,.svc:hover::before{transform:scaleY(1)}
  .svc__top{grid-column:1;grid-row:1/4;flex-direction:column;align-items:flex-start;justify-content:flex-start;margin:0}
  .svc__heading{grid-column:2;grid-row:1;margin-bottom:9.9px}
  .svc>p{grid-column:2;grid-row:2;max-width:42ch}
  .svc__scope{grid-column:3;grid-row:1/4;margin-top:0}
  .svc__cta{grid-column:2;grid-row:3;align-self:end;margin-top:17.6px;padding-top:0}
  .about{grid-template-columns:1fr}
  .about--flip{grid-template-columns:1fr}
  .about--flip .about__card,.about--flip .about__text{grid-column:1;grid-row:auto}
  .about__card{position:static;max-width:374px}
  /* O gap da grade foi medido para separar duas COLUNAS grandes (39.6-99px).
     Empilhado, com o display:contents abaixo, ele virava o respiro entre o h2
     e a propria linha de apoio dele — e ainda somava com o margin-bottom do h2:
     66px no minimo entre um titulo e o texto que pertence a ele.
     Aqui o eixo das linhas zera e cada peca declara o seu proprio respiro. */
  .contact{grid-template-columns:1fr;row-gap:0}
  /* empilhado, a lista de informacoes vai para depois do formulario: quem
     chega aqui quer preencher, nao ler os detalhes de novo. display:contents
     solta os filhos do .contact__side como itens da grade para poder ordenar */
  .contact__side{display:contents}
  .contact__side h2{order:1;margin-bottom:15.4px}
  .contact__side .sec__lede{order:2}
  .contact .form{order:3;margin-top:clamp(30.8px,4vw,44px)}
  .contact .contact__list{order:4;margin-top:clamp(30.8px,4vw,44px)}
  .contact .contact__list li{padding:13.2px 0;font-size:15.4px}
  .contact .contact__list li::before{width:4.4px;height:4.4px}
  /* Em tablet retrato o 15.5vw do desktop travava no minimo de 132px: aparelhos
     minusculos com um vazio enorme acima. Aqui o leque volta a escalar. */
  .arc{--step:12deg;--radius:1160px;--cw:clamp(190px,24vw,262px);min-height:calc(var(--ch) * .83 + 10px)}
}
@media (max-width:760px){
  :root{--rail:0px;--muted:#606068;--faint:#74747D}
  [data-theme="dark"]{--muted:#ADADB6;--faint:#85858F}
  body{font-size:18px;line-height:1.65}
  .rail{display:none}
  #processo{overflow:hidden}
  #processo .sec__head{display:block}
  #processo .sec__head h2{margin-bottom:19.8px}
  #processo .sec__head .sec__lede{max-width:38ch}
  .steps{
    margin-inline:calc(var(--gut) * -1);border-inline:0;border-radius:0;
    box-shadow:none;overflow:visible;
  }
  .steps::before,.steps::after{
    content:"";position:absolute;z-index:2;
    left:calc(var(--gut) + 17.6px);top:var(--local-start);
    width:2.2px;height:var(--local-span);border-radius:2.2px;
    transform:translateX(-50%);background:var(--line);pointer-events:none;
  }
  .steps::after{height:var(--local-fill);background:var(--red)}
  .step{
    min-height:0;grid-template-columns:35.2px minmax(0,1fr);
    grid-template-rows:auto auto auto;align-items:start;
    column-gap:15.4px;row-gap:11px;
    padding:28.6px var(--gut);
  }
  .step__n{
    position:relative;z-index:3;grid-column:1;grid-row:1/4;align-self:start;
    width:35.2px;height:35.2px;display:grid;place-items:center;
    border:1.1px solid var(--line);border-radius:50%;background:var(--paper);
    color:var(--faint);font-family:'Inter',system-ui,sans-serif;
    font-size:10.45px;font-weight:600;line-height:1;letter-spacing:.09em;
  }
  .step__heading{grid-column:2;grid-row:1}
  .step__desc{grid-column:2;grid-row:2;max-width:none}
  .step__out{
    grid-column:2;grid-row:3;display:flex;gap:4.4px;
    margin-top:3.3px;padding:13.2px 0 0;border-top:1.1px solid var(--line);
    /* o bloco de 1080px centraliza estes dois para o layout de duas colunas.
       Aqui a etapa ja e uma coluna so, e centralizados eles ficavam num eixo
       proprio, desalinhados do titulo e do texto logo acima. */
    align-items:flex-start;
  }
  .step__phase,.step__out span{font-size:12.1px}
  .step__out strong{font-size:14.85px}
  .step.is-past .step__n{border-color:color-mix(in srgb,var(--red) 42%,var(--line))}
  .step.is-current{
    background:linear-gradient(90deg,color-mix(in srgb,var(--red) 8%,var(--paper)),color-mix(in srgb,var(--red) 2%,var(--paper)) 58%,var(--paper));
  }
  .step.is-current .step__n{
    color:#fff;background:var(--red);border-color:var(--red);transform:none;
    box-shadow:0 0 0 5.5px var(--paper);
  }
  .head{gap:8.8px;padding:15.4px var(--gut)}
  .head.is-stuck{padding:8.8px 8.8px 8.8px 17.6px;width:calc(100% - 22px);--head-y:11px}
  .head__nav,.head__cta{display:none}
  .head__brand{margin-right:auto}
  .theme,.burger{width:44px;height:44px}
  .burger{display:block}
  .burger span{left:12.1px}
  .case__grid{grid-template-columns:repeat(2,1fr);grid-auto-rows:145.2px}
  .cell--xl{grid-column:span 2;grid-row:span 2}
  .cell--w{grid-column:span 2}
  .cell span{font-size:14px}
  .form{grid-template-columns:1fr}
  /* Mobile: blocos independentes; o destaque usa apenas fundo e borda durante
     a passagem pela faixa central da tela. */
  .svcs{
    gap:13.2px;overflow:visible;border:0;border-radius:0;background:transparent;box-shadow:none;
  }
  .svc{
    display:flex;padding:24.2px 22px;
    border:1.1px solid var(--line);border-radius:var(--r);background:var(--paper);
  }
  .svc+.svc{border-left:1.1px solid var(--line);border-top:1.1px solid var(--line)}
  .svc::before{display:none}
  .svc.is-current{
    border-color:color-mix(in srgb,var(--red) 82%,#fff);
    background:color-mix(in srgb,var(--red) 4.5%,var(--paper));
    box-shadow:0 0 0 1px color-mix(in srgb,var(--red) 24%,transparent),
               0 0 22px color-mix(in srgb,var(--red) 22%,transparent),
               0 22px 48.4px -39.6px var(--shadow);
  }
  .svc.is-current::before{transform:scaleY(1)}
  .svc__top{flex-direction:row;align-items:center;justify-content:space-between;margin-bottom:22px}
  .svc__heading{margin-bottom:9.9px}
  .svc>p{max-width:none}
  .svc__scope{margin-top:24.2px}
  .svc__cta{margin-top:22px;padding-top:0}
  /* Escala de leitura mobile: textos corridos em 17px, controles em 16px e
     informacoes auxiliares nunca menores que 13px. */
  .lede,.sec__lede,.case__desc,.svc p,.step p{font-size:17px}
  .eyebrow{font-size:13px}
  .case__cat,.tag,.menu a i{font-size:12.5px}
  .btn{font-size:16px}
  .about__role,.skills li{font-size:15.5px}
  .about__facts dt{font-size:13.5px}
  .about__facts dd{font-size:15.5px}
  .field label{font-size:15px}
  .field input,.field select,.field textarea{font-size:16px}
  .field__count{font-size:13px}
  .form__foot{font-size:13px}
  .form__note{font-size:15px}
  .foot__nav,.foot__local,.foot__copy{font-size:15px}
  .foot__local{justify-content:flex-start}
  .hero{height:auto;min-height:100svh;padding-top:114.4px}
  /* No mobile o clamp travava no minimo de 41.8px e o titulo quebrava em 4 linhas.
     Aqui ele volta a escalar com a largura. */
  .hero h1{font-size:clamp(42px,13.4vw,58px);margin-bottom:24px;max-width:none;line-height:1.02;letter-spacing:-.02em}
  /* botoes lado a lado e de larguras iguais, em vez de empilhados e desalinhados */
  .hero__cta{display:grid;grid-template-columns:1fr 1fr;gap:10px;width:100%}
  .hero__cta .btn{width:100%;height:50px;padding:0 6px;font-size:16px;letter-spacing:-.025em}
  .hero__row{gap:22px}
  /* O leque so mostra a carta inteira se ela couber na altura que sobra do hero.
     Com 62vw a carta ficava com 495px de altura numa faixa de 368px: o topo dos
     iPhones era cortado e o resultado era uma tira de imagem sem moldura.
     Cartas menores e a faixa reservando os 83% da carta que ficam acima da base
     do leque (ver .arc__wheel), para o topo do aparelho nunca ser cortado. */
  /* margem menor que os -180px do padrao: em telas curtas (360x780) o titulo
     maior empurra o conteudo e os aparelhos encostavam nos botoes. */
  .arc{--step:11.5deg;--radius:960px;--cw:clamp(165px,50vw,230px);min-height:calc(var(--ch) * 1.2 + 16px);margin-top:-152px}
  .toolbelt{--tool-gap:13.2px;--loop-offset:6.6px;height:253px;gap:15.4px;padding:28.6px 0}
  .tool{width:63.8px;height:63.8px;border-radius:12.1px;font-size:15.4px}
  .desktop-break{display:none}
  /* A frase e UMA so, igual ao desktop: "Comecei consertando computadores.
     Terminei obcecado com pixels" corre inteira, no mesmo tamanho e no mesmo
     estilo, e a parte pixelada e so a textura do remate — nao um segundo
     bloco. O que muda em relacao ao desktop e apenas o corpo e as quebras:
     os <br class="desktop-break"> somem e a frase quebra sozinha.
     Por isso .about__origin e .about__accent NAO recebem display aqui: o
     display:contents do accent (regra base) mantem os dois trechos no mesmo
     fluxo de texto. Qualquer display:block aqui parte a frase em dois. */
  .about__text h2{
    margin-bottom:26.4px;font-size:clamp(25px,7.1vw,29px);
    letter-spacing:-.035em;overflow-wrap:normal;
    /* 1.14 e o minimo para o entrelinha ficar parelho: a caixa da Jersey 10
       ocupa 1.10em da linha (1.34em de corpo x .82 de line-height), entao com
       o 1.02 do desktop so as linhas com pixel cresciam e o bloco ficava
       desencontrado. */
    line-height:1.14;
  }
  /* Sem o balance nesta coluna. Ele existe para ledes curtas, de duas ou tres
     linhas, onde reparte o texto em linhas parelhas. Num paragrafo de seis
     linhas na largura do telefone ele faz o contrario do que se espera: puxa
     TODAS as linhas para ~78% da coluna, e o bloco fica estreito e picotado
     ao lado do resto do texto. O pretty mantem a linha cheia, como no desktop,
     e so evita a palavra solta na ultima. */
  .about__text .sec__lede{font-size:17px;line-height:1.65;text-wrap:pretty}
  .foot__top{align-items:flex-end}
  .foot__bottom{align-items:flex-start;flex-direction:column;gap:13.2px}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .pixel.is-split .px,.is-in .pixel.is-split .px{opacity:1;animation:none;color:var(--ink)}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important}
  .reveal{opacity:1;transform:none}
  .toolbelt__track{animation:none;transform:translateX(-12%)}
}

/* ---------- páginas internas (legal) ---------- */
/* ---------- obrigado ---------- */
.page--thanks{
  --rail:0px;min-height:100svh;display:flex;flex-direction:column;background:var(--paper);
}
.page--thanks main{flex:1;display:flex;flex-direction:column}
.page--thanks .foot{margin-left:0}
.sec--thanks{
  position:relative;isolation:isolate;overflow:hidden;
  flex:1;display:grid;place-items:center;
  padding:clamp(104px,12vh,132px) var(--gut) clamp(28px,4vh,48px);
}
.thanks{
  position:relative;width:100%;max-width:1180px;margin:0 auto;
  display:grid;grid-template-columns:minmax(0,1.08fr) minmax(340px,.92fr);
  overflow:hidden;border:1.1px solid var(--line);border-radius:clamp(20px,2.4vw,30.8px);
  background:var(--card);
  box-shadow:0 42px 88px -58px var(--shadow),inset 0 1.1px 0 var(--lg-inner);
}
.thanks__hero{padding:clamp(35.2px,3.5vw,52.8px);display:flex;flex-direction:column;align-items:flex-start}
.thanks__status{
  display:inline-flex;align-items:center;gap:13.2px;margin-bottom:28.6px;
  padding:6.6px 17.6px 6.6px 6.6px;border-radius:17.6px;
  border:1.1px solid color-mix(in srgb,var(--red) 22%,var(--line));
  background:color-mix(in srgb,var(--red) 4.5%,var(--card));
  box-shadow:inset 0 1.1px 0 color-mix(in srgb,#fff 58%,transparent);
}
.thanks__mark{
  width:44px;height:44px;border-radius:12.1px;flex:none;
  display:grid;place-items:center;border:0;background:var(--red);
  box-shadow:inset 0 1.1px 0 rgba(255,255,255,.3),0 13.2px 26.4px -19.8px var(--red);
}
.thanks__mark svg{
  width:22px;height:22px;fill:none;stroke:#fff;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
}
.thanks__status-copy{display:flex;flex-direction:column;align-items:flex-start;line-height:1.2}
.thanks__status-copy strong{
  color:var(--ink);font-size:11.55px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
}
.thanks__status-copy small{margin-top:4.4px;color:var(--muted);font-size:12.1px}
.thanks h1{
  max-width:12ch;margin:0 0 19.8px;
  font-size:clamp(38px,4.2vw,58px);line-height:1.01;letter-spacing:-.045em;
}
/* O remate do titulo e a promessa da pagina, e a unica linha vermelha dela.
   Deixou de ser display:block: agora corre no fluxo do texto, entao a frase
   inteira fica vermelha mesmo quebrando entre "Agora" e "e com a gente!" —
   com bloco, a cor pararia no fim da linha e a frase se partiria em duas.
   O brilho vem do bloco "palavra em brasa", la em cima. */
.thanks h1 span{color:var(--red)}
.thanks__lead{max-width:51ch;color:var(--muted);font-size:16.5px;line-height:1.65}
.thanks__facts{
  width:100%;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  margin-top:28.6px;padding:19.8px 0;
  border-top:1.1px solid var(--line);border-bottom:1.1px solid var(--line);
}
.thanks__facts div{min-width:0;padding-right:22px}
.thanks__facts div+div{padding-left:22px;border-left:1.1px solid var(--line)}
.thanks__facts dt{
  margin-bottom:4.4px;color:var(--faint);font-size:11px;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;
}
.thanks__facts dd{margin:0;color:var(--ink);font-size:16.5px;font-weight:600;letter-spacing:-.02em}
/* Os dois botoes com a MESMA largura, sem esticarem ate a borda do card.
   Em flex cada um encolhia ate o proprio texto e "Voltar ao inicio" saia mais
   largo que "Ver projetos". Aqui as duas colunas sao 1fr, entao as duas ficam
   com a largura do maior conteudo — e o bloco continua encolhendo ate o
   conteudo, porque o pai (.thanks__hero) e um flex com align-items:flex-start
   e nao estica o item. */
.thanks__acts{
  margin-top:28.6px;display:grid;
  grid-auto-flow:column;grid-auto-columns:1fr;gap:11px;
}
/* .btn--red e a pilula principal do site e nasce MAIOR que a base: 59.4px de
   altura e 37.4px de respiro lateral, contra 52.8px e 28.6px da fantasma. Lado
   a lado, na mesma linha, essa diferenca aparece como um botao mais gordo que o
   outro — a largura ja era igual pelas colunas do grid, a altura e que nao era.
   Aqui as duas adotam a medida da principal: a vermelha nao encolhe, a outra
   sobe para encontra-la. */
.thanks__acts .btn{min-width:154px;height:59.4px;padding:0 28.6px}

.thanks__next{
  padding:clamp(35.2px,3.5vw,52.8px);
  border-left:1.1px solid var(--line);
  background:
    linear-gradient(150deg,color-mix(in srgb,var(--red) 5%,transparent),transparent 48%),
    var(--surface);
}
.thanks__kicker{
  margin-bottom:8.8px;color:var(--red);font-size:11.55px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;
}
.thanks__next>h2{font-size:clamp(27.5px,2.4vw,35.2px);line-height:1.08;margin-bottom:26.4px}
.thanks__steps{border-top:1.1px solid var(--line)}
.thanks__steps li{
  display:grid;grid-template-columns:41.8px minmax(0,1fr);gap:15.4px;
  padding:19.8px 0;border-bottom:1.1px solid var(--line);
}
.thanks__steps>li>span{
  width:35.2px;height:35.2px;border-radius:50%;display:grid;place-items:center;
  color:var(--red);border:1.1px solid color-mix(in srgb,var(--red) 28%,var(--line));
  background:var(--card);font-size:11px;font-weight:600;letter-spacing:.08em;
}
.thanks__steps h3{margin:1.1px 0 4.4px;font-size:17.6px;line-height:1.25;letter-spacing:-.025em}
.thanks__steps p{color:var(--muted);font-size:14.3px;line-height:1.55}
.thanks__note{
  margin-top:22px;padding:14.3px 15.4px;border-radius:11px;
  color:var(--muted);background:color-mix(in srgb,var(--red) 5%,var(--card));
  font-size:13.2px;line-height:1.5;
}
.thanks__note strong{color:var(--ink);font-weight:600}
@media (max-width:900px){
  .sec--thanks{padding-top:96px}
  .thanks{grid-template-columns:1fr;max-width:680px}
  .thanks__next{border-left:0;border-top:1.1px solid var(--line)}
  .thanks h1{max-width:14ch}
}
@media (max-width:760px){
  .sec--thanks{display:block;padding:88px 14px 28px}
  .thanks{border-radius:19.8px}
  .thanks__hero,.thanks__next{padding:28.6px 22px}
  .thanks__status{margin-bottom:24.2px;padding:5.5px 14.3px 5.5px 5.5px;gap:11px}
  .thanks__mark{width:41.8px;height:41.8px;border-radius:11px}
  .thanks__mark svg{width:20.9px;height:20.9px}
  .thanks__status-copy strong{font-size:10.45px}
  .thanks__status-copy small{font-size:11.55px}
  .thanks h1{font-size:clamp(34px,10.2vw,43px);margin-bottom:17.6px}
  .thanks__lead{font-size:15.4px;line-height:1.6}
  .thanks__facts{margin-top:24.2px;padding:17.6px 0}
  .thanks__facts div{padding-right:13.2px}
  .thanks__facts div+div{padding-left:13.2px}
  .thanks__facts dt{font-size:9.9px}
  .thanks__facts dd{font-size:14.3px}
  .thanks__acts{display:grid;grid-template-columns:1fr 1fr;width:100%;margin-top:24.2px;gap:8.8px}
  .thanks__acts .btn{min-width:0;height:48.4px;padding:0 10px;font-size:14.3px}
  .thanks__next>h2{font-size:27.5px;margin-bottom:22px}
  .thanks__steps li{padding:17.6px 0}
  .thanks__note{margin-top:19.8px}
}
@media (max-width:374px){
  /* empilhado: o fluxo volta a ser por linha, senao o grid-auto-flow:column
     criaria colunas implicitas e os dois continuariam lado a lado */
  .thanks__acts{grid-template-columns:1fr;grid-auto-flow:row}
  .thanks__acts .btn{width:100%}
  .thanks__facts{grid-template-columns:1fr;gap:13.2px}
  .thanks__facts div{padding-right:0}
  .thanks__facts div+div{padding:13.2px 0 0;border-left:0;border-top:1.1px solid var(--line)}
}

.legal{max-width:902px;margin:0 auto}
.legal .sec__head{margin-bottom:48.4px}
.legal h3{font-size:20.9px;font-weight:600;letter-spacing:-.025em;margin:41.8px 0 13.2px}
.legal p,.legal li{color:var(--muted);font-size:17.05px;line-height:1.7}
.legal ul{margin:13.2px 0;display:flex;flex-direction:column;gap:8.8px}
.legal li{padding-left:22px;position:relative}
.legal li::before{content:"";position:absolute;left:0;top:12.1px;width:6.6px;height:1.1px;background:var(--red)}
.legal a{color:var(--ink);text-decoration:underline;text-underline-offset:3.3px}
.legal a:hover{color:var(--red)}
.legal__back{margin-top:57.2px}
.legal__date{font-size:14.3px;color:var(--faint);margin-top:37.4px;padding-top:19.8px;border-top:1.1px solid var(--line)}

@media (max-width:374px){
  .foot__local{flex-direction:column;align-items:flex-start;gap:6.6px}
  .foot__local span{gap:8.8px}
  .foot__local span::before{
    content:"";width:4.4px;height:4.4px;border-radius:50%;background:var(--red);flex:none;
  }
}


/* =========================================================
   ABERTURA — versão calma
   Menos efeitos simultâneos, mais continuidade. O final usa uma cópia da
   própria marca do header para garantir um pouso pixel-perfect.

   Suavidade: tudo o que se move usa transform/opacity (o compositor resolve
   sem repintar) e uma curva única — duas curvas diferentes rodando lado a lado
   sao percebidas como uma "batida" mesmo quando cada uma esta correta. O unico
   filtro animado e o blur das metades, que resolve antes do fim do movimento
   para que a chegada seja puramente composta.
   ========================================================= */
.intro{display:none}
html.is-intro{overflow:hidden}
html.is-intro .intro{
  display:grid;place-items:center;
  position:fixed;inset:0;z-index:300;
  /* curva unica da cena: desacelera sem passar do ponto */
  --intro-ease:cubic-bezier(.22,.86,.28,1);
  --intro-ease-soft:cubic-bezier(.4,.12,.22,1);
}

.intro__veil{
  position:absolute;inset:0;
  background:color-mix(in srgb,var(--paper) 54%,transparent);
  backdrop-filter:blur(22px) saturate(155%);
  -webkit-backdrop-filter:blur(22px) saturate(155%);
  animation:intro-defog 1.02s var(--intro-ease-soft) 1.42s forwards;
  /* camada propria: o desembacar e so opacity, e a opacity de um elemento com
     backdrop-filter tambem dissolve o proprio borrao — nao ha "pulo" no fim */
  transform:translateZ(0);
  will-change:opacity;
}
@supports not ((backdrop-filter:blur(1.1px)) or (-webkit-backdrop-filter:blur(1.1px))){
  .intro__veil{background:var(--hero-base)}
}

.intro__lock{
  position:relative;z-index:2;
  display:flex;align-items:center;gap:35.2px;
  color:var(--ink);
}

/* A placa não “abre” mais como uma persiana. Ela apenas se materializa.
   Agora é vidro de verdade: tem backdrop-filter proprio, entao a lamina fosca
   por baixo aparece mais densa e mais saturada dentro da pilula — a diferenca
   entre o dentro e o fora e o que faz o olho ler "vidro" em vez de "pintura".
   Por isso .intro__lock nao pode declarar will-change:opacity: isso o tornaria
   um backdrop root e a placa passaria a filtrar um fundo vazio. O will-change
   volta so nos estados que de fato animam o lockup (handoff e saida). */
.intro__plate{
  position:absolute;z-index:-1;inset:-30.8px -46.2px;
  border-radius:1098.9px;overflow:hidden;
  background:
    radial-gradient(118% 150% at 16% -34%,
      color-mix(in srgb,var(--lg-sheen) 60%,transparent),transparent 56%),
    linear-gradient(180deg,var(--lg-gloss),transparent 62%),
    var(--lg-fill);
  background-clip:padding-box;
  backdrop-filter:blur(9px) saturate(184%) brightness(1.02);
  -webkit-backdrop-filter:blur(9px) saturate(184%) brightness(1.02);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb,var(--lg-ring) 74%,transparent),
    inset 0 1px 0 color-mix(in srgb,var(--lg-edge) 72%,transparent),
    inset 0 -1px 0 color-mix(in srgb,var(--lg-rim) 70%,transparent),
    0 34px 72px -46px var(--lg-drop);
  animation:intro-plate .86s var(--intro-ease) .32s both;
}

/* Especular: uma faixa de luz atravessa a placa uma vez so. E transform +
   opacity, entao nao custa nada, e e o gesto que separa vidro de plastico. */
.intro__sheen{
  display:block;position:absolute;inset:-1px;border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(104deg,
    transparent 24%,
    color-mix(in srgb,var(--lg-sheen) 26%,transparent) 36%,
    color-mix(in srgb,var(--lg-sheen) 68%,transparent) 46%,
    color-mix(in srgb,var(--lg-edge) 52%,transparent) 50%,
    color-mix(in srgb,var(--lg-sheen) 68%,transparent) 54%,
    color-mix(in srgb,var(--lg-sheen) 26%,transparent) 64%,
    transparent 76%);
  opacity:0;
  transform:translate3d(-64%,0,0);
  will-change:transform,opacity;
  animation:intro-sheen .96s var(--intro-ease-soft) .54s both;
}

.intro__mark{position:relative;flex:none;display:block;width:92.4px;height:92.4px}
.intro__half{position:absolute;inset:0;display:block;will-change:transform,filter,opacity}
.intro__half svg{display:block;width:92.4px;height:92.4px}
.intro__half--a{animation:intro-half-a .90s var(--intro-ease) .12s both}
.intro__half--b{animation:intro-half-b .90s var(--intro-ease) .18s both}

/* Quase um halo, não um “pulso”. */
.intro__ring{
  position:absolute;left:50%;top:50%;width:92.4px;height:92.4px;margin:-46.2px 0 0 -46.2px;
  border-radius:50%;border:1px solid color-mix(in srgb,var(--lg-ring) 55%,transparent);
  pointer-events:none;
  will-change:transform,opacity;
  animation:intro-ring .82s var(--intro-ease-soft) .66s both;
}

.intro__name{
  display:flex;align-items:baseline;
  font-size:63.8px;font-weight:600;letter-spacing:-.02em;line-height:1;
  white-space:nowrap;
  will-change:transform,opacity;
  animation:intro-name .70s var(--intro-ease) .52s both;
}
.intro__name i{
  font-style:normal;color:var(--red);
  animation:intro-dot .48s var(--intro-ease) .80s both;
}

/* Indicador discreto: 1px, curto, sem “degraus” visuais. */
.intro__bar{
  position:absolute;left:50%;top:calc(50% + 91px);transform:translateX(-50%);
  width:min(132px,34vw);height:1px;border-radius:999px;overflow:hidden;
  background:color-mix(in srgb,var(--ink) 7%,transparent);
  opacity:.56;
  animation:intro-bar-in .5s ease .84s both;
}
.intro__bar i{
  display:block;width:100%;height:100%;border-radius:inherit;
  background:color-mix(in srgb,var(--red) 48%,transparent);
  transform:scaleX(var(--load,0));transform-origin:left;
  will-change:transform;
}

/* Cópia da marca REAL usada só na passagem final. */
.intro__flybrand{
  position:fixed!important;
  z-index:302!important;
  margin:0!important;
  pointer-events:none!important;
  transform-origin:0 0!important;
  opacity:0;
  will-change:transform,opacity;
  transition:
    transform .74s cubic-bezier(.22,.72,.23,1),
    opacity .18s ease;
}
.intro__flybrand .head__name{white-space:nowrap}
.intro.is-handoff .intro__lock{
  opacity:0;
  transform:scale(.994);
  will-change:opacity,transform;
  transition:opacity .18s ease,transform .34s var(--intro-ease-soft);
}
/* o brilho nao sobrevive ao lockup: some junto, sem piscar */
.intro.is-handoff .intro__sheen,
.intro.is-skipping .intro__sheen{animation:none;opacity:0;transition:opacity .16s linear}

@media (max-width:760px){
  .intro{
    --intro-enter-a:clamp(-42px,-11vw,-34px);
    --intro-enter-b:clamp(34px,11vw,42px);
    --intro-blur:4px;
  }
  .intro__veil{
    background:color-mix(in srgb,var(--paper) 66%,transparent);
    backdrop-filter:blur(16px) saturate(145%);
    -webkit-backdrop-filter:blur(16px) saturate(145%);
  }
  .intro__lock{gap:clamp(22px,6.45vw,25.14px)}
  .intro__plate{
    inset:clamp(-22px,-5.64vw,-17.6px) clamp(-19.8px,-5vw,-15.4px);
    /* GPU de celular: menos raio de borrao, mesma leitura de vidro */
    backdrop-filter:blur(6px) saturate(172%);
    -webkit-backdrop-filter:blur(6px) saturate(172%);
    box-shadow:
      inset 0 0 0 1px var(--lg-ring),
      inset 0 1px 0 color-mix(in srgb,var(--lg-edge) 66%,transparent),
      0 24px 52px -36px var(--lg-drop);
  }
  .intro__mark,.intro__half svg{
    width:clamp(57.2px,16.92vw,66px);
    height:clamp(57.2px,16.92vw,66px);
  }
  .intro__ring{
    width:clamp(57.2px,16.92vw,66px);
    height:clamp(57.2px,16.92vw,66px);
    margin:clamp(-33px,-8.46vw,-28.6px) 0 0 clamp(-33px,-8.46vw,-28.6px);
  }
  .intro__name{font-size:clamp(39.6px,11.69vw,45.6px)}
  .intro__bar{top:calc(50% + clamp(68px,19vw,75px));width:min(116px,40vw)}
}

@keyframes intro-defog{from{opacity:1}to{opacity:0}}
/* o blur resolve em 58% do tempo: os ultimos 40% do percurso sao so transform,
   ou seja, quadros compostos puros justamente onde o olho acompanha a chegada */
@keyframes intro-half-a{
  0%{opacity:0;filter:blur(var(--intro-blur,6px));transform:rotate(-22deg) translateY(var(--intro-enter-a,-48px)) rotate(22deg) scale(1.025)}
  58%{opacity:1;filter:blur(0)}
  100%{opacity:1;filter:blur(0);transform:none}
}
@keyframes intro-half-b{
  0%{opacity:0;filter:blur(var(--intro-blur,6px));transform:rotate(-22deg) translateY(var(--intro-enter-b,48px)) rotate(22deg) scale(1.025)}
  58%{opacity:1;filter:blur(0)}
  100%{opacity:1;filter:blur(0);transform:none}
}
@keyframes intro-ring{
  0%{opacity:0;transform:scale(.92)}
  22%{opacity:.24}
  100%{opacity:0;transform:scale(1.34)}
}
@keyframes intro-plate{
  from{opacity:0;transform:scale(.968)}
  to{opacity:1;transform:none}
}
@keyframes intro-sheen{
  0%{opacity:0;transform:translate3d(-64%,0,0)}
  26%{opacity:.9}
  74%{opacity:.52}
  100%{opacity:0;transform:translate3d(64%,0,0)}
}
@keyframes intro-name{
  from{opacity:0;transform:translate3d(-6px,0,0)}
  to{opacity:1;transform:none}
}
@keyframes intro-dot{
  from{opacity:0;transform:scale(.82)}
  to{opacity:1;transform:scale(1)}
}
@keyframes intro-bar-in{from{opacity:0}to{opacity:.56}}
@keyframes intro-bar-out{from{opacity:.56}to{opacity:0}}
@keyframes intro-lock-out{from{opacity:1}to{opacity:0}}

/* Com JS, o final é controlado pelo carregamento real. */
.intro.is-live .intro__veil{animation:none}
.intro.is-opening .intro__veil{animation:intro-defog 1.02s var(--intro-ease-soft) forwards}
.intro.is-opening .intro__plate{opacity:.88;transition:opacity .38s var(--intro-ease-soft)}
.intro.is-opening .intro__bar{animation:intro-bar-out .36s ease forwards}

.intro.is-skipping .intro__veil{animation:intro-defog .38s ease both}
.intro.is-skipping .intro__lock{animation:intro-lock-out .26s ease both;will-change:opacity}
.intro.is-skipping .intro__bar{animation:intro-bar-out .2s ease both}

@media (prefers-reduced-motion:reduce){
  html.is-intro:not(.is-intro-forced){overflow:auto}
  html.is-intro:not(.is-intro-forced) .intro{display:none}
}
