/* ============================================================
   Nova247 — direção "Limbo"
   Preto cósmico como superfície. O violeta é a única matéria
   que se clica. O brilho lunar é o que a luz toca.
   ============================================================ */

:root {
  /* ---- superfícies ---- */
  --bg-0:  #070510;                    /* Preto Cósmico — fundo da página */
  --bg-1:  #171133;                    /* Sombra Atmosférica — cards, modal */
  --bg-2:  oklch(0.268 0.072 285);     /* hover de superfície */

  /* hairlines — cobalto rebaixado; nunca borda grossa, nunca sombra */
  --line:   oklch(0.318 0.070 283);
  /* --line-2 desenha a borda de campo, pill e card selecionável: precisa dos
     3:1 de contraste não-textual da WCAG contra a superfície do modal */
  --line-2: oklch(0.560 0.110 283);

  /* ---- tinta ---- */
  --ink:   #F4F3FF;
  --ink-2: oklch(0.812 0.030 285);
  --ink-3: oklch(0.665 0.038 285);

  /* ---- marca ---- */
  --glow:   #D4D2FF;   /* Brilho Lunar — palavra em destaque, hover */
  --violet: #7152FF;   /* Violeta Elétrico — SÓ o que é clicável */
  --cobalt: #3E27B3;   /* Cobalto Estelar — borda ativa, a caixa sólida */

  --violet-lit: oklch(0.632 0.238 285);
  --violet-dim: color-mix(in oklab, var(--violet) 14%, transparent);

  --font-d: 'Object Sans', 'Trebuchet MS', sans-serif;
  --font-b: 'Satoshi', 'Segoe UI', sans-serif;

  /* escala com degraus reais: cada nível é ~1.35x o anterior */
  --t-display: clamp(2.5rem, 5.4vw, 4rem);
  --t-h2:      clamp(2rem, 4.4vw, 3.4rem);
  --t-h3:      clamp(1.25rem, 2.1vw, 1.6rem);
  --t-lede:    clamp(1.12rem, 1.5vw, 1.35rem);
  --t-body:    1rem;
  --t-sm:      0.9rem;
  --t-xs:      0.78rem;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;
  --s11: clamp(88px, 13vw, 184px);

  --gut: clamp(20px, 5vw, 64px);
  --max: 1240px;

  /* SHAPE LOCK — três raios, regra fixa:
     botão/input = --r-btn · card/imagem/modal = --r-card · chip = --r-pill.
     Nada na página usa um raio fora dessa tabela. */
  --r-btn:  10px;
  --r-card: 16px;
  --r-pill: 999px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);

  /* z semântico */
  --z-sticky: 40;
  --z-menu: 60;
  --z-modal: 80;
  --z-intro: 120;

  color-scheme: dark;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
}

body {
  background: var(--bg-0);
  color: var(--ink-2);
  font-family: var(--font-b);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, picture { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; }

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

.skip {
  position: fixed; top: var(--s3); left: var(--s3);
  z-index: 200; padding: var(--s3) var(--s5);
  background: var(--violet); color: #fff;
  border-radius: var(--r-btn); font-weight: 600;
  transform: translateY(-160%);
  transition: transform .22s var(--ease);
}
.skip:focus-visible { transform: none; }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }

/* ---------- tipografia ---------- */
.h2, .h3, .hero__h {
  font-family: var(--font-d);
  color: var(--ink);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.045em;
  text-wrap: balance;
}

.hero__h { font-size: var(--t-display); letter-spacing: -0.05em; }
.h2 { font-size: var(--t-h2); line-height: 1.04; }
.h2--sm { font-size: clamp(1.7rem, 3.2vw, 2.2rem); }
.h3 {
  font-size: var(--t-h3);
  line-height: 1.16;
  letter-spacing: -0.03em;
  font-weight: 800;
}

/* palavra em destaque: luz, não caixa */
.lit { color: var(--glow); }

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

p { max-width: 66ch; }

/* a única caixa sólida da página — o marca-texto da identidade.
   Com box-decoration-break: clone cada linha ganha a sua própria caixa
   com o padding inteiro. A caixa mede ~1,16em de métrica mais 0,26em de
   padding: a 1,3 de entrelinha ela era mais alta que o espaço da linha e
   a segunda caixa subia por baixo da primeira, com cara de corte. A
   entrelinha aqui é o piso que impede as caixas de se tocarem. */
mark {
  background: var(--cobalt);
  color: var(--glow);
  padding: 0.06em 0.22em 0.14em;
  line-height: 1.6;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* medido: a caixa da Object Sans fica em 1,32em de métrica; com 0,2em de
   padding dá 1,52em, então a entrelinha tem que passar disso. A 1,5 as
   caixas ainda se cruzavam por 4px. */
.h2:has(mark) { line-height: 1.6; }

/* ---------- botões ---------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  min-height: 52px;
  padding: var(--s3) var(--s6);
  background: var(--violet);
  color: #fff;                       /* 4.84:1 sobre #7152FF — passa AA */
  font-weight: 600;
  font-size: var(--t-sm);
  letter-spacing: -0.01em;
  white-space: nowrap;
  border-radius: var(--r-btn);
  overflow: hidden;
  /* a linha de luz no topo é o que tira o botão do estado "retângulo chapado" */
  box-shadow: inset 0 1px 0 rgb(212 210 255 / .38);
  transition: background-color .22s var(--ease), transform .16s var(--ease), box-shadow .22s var(--ease);
}
/* varredura de brilho no hover — translate de gradiente, sem repaint de layout */
.btn::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 32%, rgb(212 210 255 / .30) 50%, transparent 68%);
  transform: translateX(-102%);
  transition: transform .62s var(--ease);
  pointer-events: none;
}
.btn > * { position: relative; z-index: 1; }
.btn:hover {
  background: var(--violet-lit);
  box-shadow: inset 0 1px 0 rgb(212 210 255 / .55);
}
.btn:hover::after { transform: translateX(102%); }
.btn:active { transform: translateY(1px) scale(.985); }

.btn--sm { min-height: 44px; padding: var(--s2) var(--s5); font-size: var(--t-xs); }
.btn--lg { min-height: 60px; padding: var(--s4) var(--s8); font-size: 1.02rem; }
.btn--full { width: 100%; min-height: 56px; }

.btn--ghost {
  background: transparent;
  border: 1px solid var(--cobalt);
  color: var(--glow);
  box-shadow: none;
}
.btn--ghost:hover {
  background: var(--violet-dim);
  border-color: var(--violet);
  box-shadow: none;
}

.link-q {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: 52px;
  padding-inline: var(--s2);
  font-size: var(--t-sm); font-weight: 500;
  color: var(--ink-2);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.link-q::after {
  content: '';
  width: 18px; height: 1px;
  background: currentColor;
  transition: width .25s var(--ease);
}
.link-q:hover { color: var(--glow); }
.link-q:hover::after { width: 32px; }

/* ============================================================
   INTRO — a logo entra no centro e pousa na nav.
   O overlay só existe se o JS o criar (uma vez por sessão).
   ============================================================ */
.intro {
  position: fixed; inset: 0; z-index: var(--z-intro);
  display: grid; place-content: center;
  background: var(--bg-0);
  animation: introOut .5s var(--ease) forwards;
  animation-delay: 1.55s;
}
.intro__glowarc {
  position: absolute;
  top: -30%; left: 50%;
  width: 120%;
  translate: -50% 0;
  opacity: .5;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 88%);
  mask-image: linear-gradient(to bottom, #000 45%, transparent 88%);
}
.intro__mark {
  position: relative;
  width: clamp(220px, 38vw, 460px);
  height: auto;
  color: var(--glow);
  animation: introMark .68s var(--ease) backwards;
}
@keyframes introMark {
  from { opacity: 0; transform: translateY(14px) scale(.94); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}
@keyframes introOut {
  to { opacity: 0; visibility: hidden; }
}
/* enquanto a intro roda, o corpo não rola */
.is-intro { overflow: hidden; }

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: var(--z-menu);
  background: color-mix(in oklab, var(--bg-0) 82%, transparent);
  border-bottom: 1px solid transparent;
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
}
.nav.is-stuck {
  background: color-mix(in oklab, var(--bg-0) 96%, transparent);
  border-bottom-color: var(--line);
  backdrop-filter: blur(14px);
}

.nav__in {
  max-width: var(--max); margin-inline: auto;
  padding: var(--s4) var(--gut);
  display: flex; align-items: center; gap: var(--s6);
}
.nav__logo { flex: none; color: var(--ink); display: flex; align-items: center; min-height: 44px; }
.nav__logo svg { width: 116px; height: auto; }
/* a logo da nav só aparece quando a intro entrega o bastão */
.is-intro .nav__logo { opacity: 0; }

.nav__links { display: none; margin-left: auto; gap: var(--s6); }
.nav__links a {
  position: relative;
  font-size: var(--t-sm); font-weight: 500;
  color: var(--ink-2);
  text-decoration: none;
  padding-block: var(--s2);
  transition: color .2s var(--ease);
}
.nav__links a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--violet);
  transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease);
}
.nav__links a:hover { color: var(--glow); }
.nav__links a:hover::after,
.nav__links a.is-here::after { transform: scaleX(1); }

.nav__act { margin-left: auto; display: flex; align-items: center; gap: var(--s3); }
.nav__act .btn { display: none; }

.nav__burger {
  width: 44px; height: 44px;
  display: grid; place-content: center; gap: 6px;
  color: var(--ink);
}
.nav__burger span {
  display: block; width: 22px; height: 1.5px;
  background: currentColor;
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav__burger[aria-expanded="true"] span:first-child { transform: translateY(3.75px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child  { transform: translateY(-3.75px) rotate(-45deg); }

.anim .menu a { --menu-anim: menuIn .5s var(--ease) backwards; }
.menu {
  position: fixed; inset: 0; z-index: var(--z-sticky);
  background: var(--bg-0);
  display: grid; align-content: center;
  padding: calc(var(--gut) + 72px) var(--gut) var(--gut);
}
.menu[hidden] { display: none; }
.menu nav { display: grid; gap: var(--s2); }
.menu a {
  font-family: var(--font-d);
  font-size: clamp(2rem, 9vw, 3rem);
  font-weight: 800; letter-spacing: -0.045em;
  color: var(--ink); text-decoration: none;
  padding-block: var(--s3);
  /* visível por padrão; a animação só melhora a entrada */
  animation: var(--menu-anim, none);
}
.menu a:nth-child(1) { animation-delay: .04s; }
.menu a:nth-child(2) { animation-delay: .08s; }
.menu a:nth-child(3) { animation-delay: .12s; }
.menu a:nth-child(4) { animation-delay: .16s; }
.menu a:nth-child(5) { animation-delay: .20s; }
@keyframes menuIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@media (min-width: 920px) {
  .nav__links { display: flex; }
  .nav__act { margin-left: 0; }
  .nav__act .btn { display: inline-flex; }
  .nav__burger { display: none; }
  .menu { display: none !important; }
}

/* ============================================================
   HERO — o arco é a assinatura. Ele nasce no alto e, ao rolar,
   se põe. Reaparece invertido no fim da página.
   ============================================================ */
.hero {
  position: relative;
  isolation: isolate;
  min-height: min(100svh, 900px);
  display: flex; align-items: flex-end;
  /* topo cede em tela curta pro CTA caber sem rolar */
  padding-block: clamp(56px, 9vh, 112px) var(--s11);
  overflow: hidden;
  /* o preto da imagem é o preto do topo da página — sem emenda */
  background: linear-gradient(to bottom, #000 0%, #000 42%, var(--bg-0) 84%);
}

.hero__arc {
  position: absolute;
  top: -14%; left: 50%;
  width: 145%;
  z-index: -1;
  translate: -50% 0;
  will-change: transform, opacity;
  -webkit-mask-image: linear-gradient(to bottom, #000 52%, transparent 93%);
  mask-image: linear-gradient(to bottom, #000 52%, transparent 93%);
}
.hero__arc img { width: 100%; }

/* o vídeo cobre exatamente a caixa da imagem — a máscara e as animações
   do .hero__arc valem para os dois. Nasce apagado: quem acende é o
   'playing' no main.js, então uma falha de autoplay não deixa buraco. */
.hero__vid {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .9s var(--ease);
  pointer-events: none;
}
.hero__arc.is-live .hero__vid { opacity: 1; }

.hero__in { position: relative; }

.hero__p { margin-top: var(--s6); }
.hero__cta {
  margin-top: var(--s7);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4);
}

@media (min-width: 900px) {
  /* o parágrafo e o CTA cedem a direita pro arco; o h1 usa a coluna
     inteira, senão a primeira linha quebra e viram quatro linhas */
  .hero__p, .hero__cta { max-width: 62%; }
  .hero__arc { top: -22%; width: 108%; }
}

/* ---------- ritmo de seção ---------- */
.sec { padding-block: var(--s11); }

/* ============================================================
   METODOLOGIA
   ============================================================ */
.meth { border-top: 1px solid var(--line); }
.meth__grid { display: grid; gap: var(--s9); }
.meth__lead .lede { margin-top: var(--s5); }

.steps { display: grid; gap: var(--s7); }
/* baseline, não start: o numeral e o título são texto, e o que alinha
   texto com texto é a linha de base. Com align-items:start o 01 flutuava
   acima do "Entender" porque a caixa dele é mais alta. */
/* auto, não uma medida em ch: o ch é do corpo e o numeral é da display,
   bem mais largo — a coluna ficava estreita e o 02 encostava no título.
   Com tabular-nums todos os numerais têm a mesma largura, então auto
   ainda alinha 01, 02 e 03 na mesma régua. */
.step { display: grid; grid-template-columns: auto 1fr; gap: var(--s5); align-items: baseline; }
.step__n {
  font-family: var(--font-d);
  /* perto do h3, não o dobro dele: o número é referência, não manchete */
  font-size: clamp(1.7rem, 3vw, 2.3rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  color: transparent;
  -webkit-text-stroke: 1.6px var(--violet);
}
.step__body h3 { margin-bottom: var(--s3); }
.step__body p { color: var(--ink-2); max-width: 48ch; }

@media (min-width: 900px) {
  .meth__grid { grid-template-columns: 1fr 1fr; gap: var(--s10); align-items: start; }
  .meth__lead { position: sticky; top: 128px; }
}

/* ============================================================
   MANIFESTO — a promessa antes da explicação.

   O rótulo de seção é um sistema, não um enfeite repetido: existem
   exatamente dois na página (aqui e na Tecnologia), no mesmo desenho e
   em cor neutra, porque rótulo não é ação.
   ============================================================ */
.eyebrow {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --- base: sem trava de rolagem. É o que roda em navegador sem
   view-timeline e em movimento reduzido — uma lista de frases, legível
   do primeiro frame, sem depender de nenhuma classe para aparecer. --- */
.manif { border-top: 1px solid var(--line); }
.manif .eyebrow { margin-bottom: clamp(40px, 8vh, 96px); }
.manif__body { display: grid; gap: clamp(40px, 7vh, 80px); }
.manif__lines { display: grid; gap: clamp(28px, 5vh, 56px); }

.manif__l {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: clamp(1.55rem, 4.2vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.04em;
  color: var(--ink);
  max-width: 20ch;
  text-wrap: balance;
}

.manif__close { display: grid; gap: var(--s6); justify-items: start; }
.manif__q {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: var(--t-h3);
  letter-spacing: -0.03em;
  line-height: 1.15;
  color: var(--glow);
  max-width: 24ch;
}

/* --- a trava de rolagem --- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* o pin é só altura: é ele que compra o tempo de rolagem que as
       cinco cenas precisam. A timeline sai daqui e as cenas fatiam. */
    .js.anim .manif__pin {
      height: 480vh;
      view-timeline-name: --manif;
      view-timeline-axis: block;
    }
    .js.anim .manif__stage {
      position: sticky;
      top: 0;
      height: 100vh;
      height: 100dvh;
      display: grid;
      align-content: center;
      overflow: hidden;
    }
    /* as cinco cenas ocupam a mesma célula: é o revezamento no ponto
       focal, e é o que garante que o texto não pule de lugar */
    .js.anim .manif__body { display: grid; gap: 0; }
    .js.anim .manif__lines,
    .js.anim .manif__close { grid-area: 1 / 1; align-self: center; }
    .js.anim .manif__lines { display: block; position: relative; }
    .js.anim .manif__l {
      position: absolute;
      inset-inline: 0;
      top: 50%;
      translate: 0 -50%;
      margin: 0;
      font-size: clamp(1.75rem, 5.2vw, 3.6rem);
      max-width: 17ch;
    }
    /* reserva a altura da cena: as frases saíram do fluxo, e sem isso a
       célula colapsaria e o fecho subiria para o lugar delas */
    .js.anim .manif__lines::before {
      content: '';
      display: block;
      min-height: clamp(180px, 30vh, 300px);
    }

    .js.anim .manif__l,
    .js.anim .manif__close {
      animation: manifFoco linear both;
      animation-timeline: --manif;
      will-change: opacity, filter, transform;
    }
    /* cada frase pega uma fatia de 26% com 6% de sobreposição: é nessa
       sobra que uma desfoca enquanto a outra entra em nitidez */
    .js.anim .manif__l {
      animation-range: contain calc(var(--i) * 20%) contain calc(var(--i) * 20% + 26%);
    }
    /* o fecho não se reveza: entra e fica. O `both` segura ele aceso nos
       6% finais do pin, que é a pausa antes do CTA. */
    .js.anim .manif__close {
      animation-name: manifPousa;
      animation-range: contain 82% contain 94%;
    }

    /* no celular a cena é mais curta: o pin longo dá sensação de página
       travada em tela pequena. O blur e o fade continuam iguais. */
    @media (max-width: 699px) {
      .js.anim .manif__pin { height: 380vh; }
    }
  }
}

@keyframes manifFoco {
  0%   { opacity: 0; filter: blur(10px); transform: translateY(18px) scale(.96); }
  26%  { opacity: 1; filter: blur(0);    transform: none; }
  72%  { opacity: 1; filter: blur(0);    transform: none; }
  100% { opacity: 0; filter: blur(10px); transform: translateY(-18px) scale(1.04); }
}

@keyframes manifPousa {
  from { opacity: 0; filter: blur(10px); transform: translateY(20px); }
  to   { opacity: 1; filter: blur(0);    transform: none; }
}

/* ============================================================
   SERVIÇOS — índice em duas colunas, diagramado por hairline.
   Sem numeração: a ordem dos seis não carrega informação, e a
   Metodologia logo acima já é a sequência numerada da página.
   O filete de topo é a régua — cada célula começa no mesmo lugar
   e o texto da coluna 2 nasce alinhado com o da coluna 1.
   ============================================================ */
.svc { border-top: 1px solid var(--line); }

.svc__top { margin-bottom: var(--s8); }
.svc__lede { margin-top: var(--s5); max-width: 46ch; }

.svc__grid { display: grid; }

.svc__cell {
  padding-block: var(--s6) var(--s7);
  border-top: 1px solid var(--line);
  transition: border-color .3s var(--ease);
}

.svc__t {
  font-family: var(--font-d);
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.035em;
  color: var(--ink);
  margin-bottom: var(--s3);
  text-wrap: balance;
  transition: color .3s var(--ease);
}
.svc__d {
  font-size: var(--t-sm);
  color: var(--ink-2);
  max-width: 44ch;
  text-wrap: pretty;
}

/* nada de preenchimento no hover: num índice de filete, quem responde
   é a própria régua. Superfície chapada é regra da marca. */
@media (hover: hover) {
  .svc__cell:hover { border-color: var(--violet); }
  .svc__cell:hover .svc__t { color: var(--glow); }
}

@media (min-width: 860px) {
  .svc__top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s9);
    align-items: end;
  }
  .svc__lede { margin-top: 0; }
  .svc__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--s9); }
}

/* ============================================================
   TECNOLOGIA — uma seção só, escura como o resto.
   O equilíbrio vem da simetria das duas colunas, não de um
   bloco de cor chapado. Muitos sinais entram, uma decisão sai.
   ============================================================ */
.tech { border-top: 1px solid var(--line); }
.tech__badge { margin-bottom: var(--s5); }
.tech__h { max-width: 20ch; }

/* --- infográfico --- */
.flow {
  margin-block: clamp(48px, 7vw, 88px);
  width: 100%;
}
.flow svg { width: 100%; height: auto; overflow: visible; }

.flow__in, .flow__out {
  fill: none;
  stroke-linecap: round;
}
.flow__in  { stroke: var(--violet); stroke-width: 1.35; opacity: .72; }
/* o fio do meio entra mais aceso: dá um centro de gravidade ao feixe */
.flow__in--lead { opacity: 1; stroke-width: 1.6; }
.flow__out { stroke: var(--glow);   stroke-width: 2.75; }
.flow__node { fill: var(--glow); }
.flow__end  { fill: var(--glow); }
.flow__halo {
  fill: none; stroke: var(--violet); stroke-width: 1; opacity: .45;
  /* sem a caixa de preenchimento o scale do pulso usaria a origem do SVG
     inteiro e o halo sairia voando em vez de respirar no lugar */
  transform-box: fill-box;
  transform-origin: center;
}

.flow__cap {
  font-family: var(--font-b);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  fill: var(--ink-3);
}

.flow__legend { display: none; }

/* O SVG escala junto com a tela: no celular ele fica com 40% do tamanho,
   e traço e texto encolhem na mesma proporção — o desenho vira um borrão.
   Aqui as medidas são engrossadas em unidades de viewBox para compensar,
   e as legendas passam a ser HTML, que não encolhe. */
@media (max-width: 699px) {
  .flow__in  { stroke-width: 3; }
  .flow__in--lead { stroke-width: 3.6; }
  .flow__out { stroke-width: 6; }
  .flow__node { r: 11; }
  .flow__halo { r: 34; stroke-width: 2.4; }
  .flow__end  { r: 8; }
  .flow__cap { display: none; }

  .flow__legend {
    display: flex;
    justify-content: space-between;
    gap: var(--s4);
    margin-top: var(--s4);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-3);
  }
  .flow__legend span:last-child { text-align: right; color: var(--ink-2); }
}

/* o traço se desenha uma vez, quando a seção entra */
.js.anim .flow--armed .flow__in,
.js.anim .flow--armed .flow__out {
  stroke-dasharray: var(--len, 600);
  stroke-dashoffset: var(--len, 600);
}
.js.anim .flow--armed.is-drawn .flow__in,
.js.anim .flow--armed.is-drawn .flow__out {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.05s var(--ease-io);
  transition-delay: var(--d, 0ms);
}
.js.anim .flow--armed .flow__node,
.js.anim .flow--armed .flow__end,
.js.anim .flow--armed .flow__halo,
.js.anim .flow--armed .flow__cap { opacity: 0; }
.js.anim .flow--armed.is-drawn .flow__node,
.js.anim .flow--armed.is-drawn .flow__cap {
  opacity: 1;
  transition: opacity .5s var(--ease) .62s;
}
/* o ponto final só acende depois de a linha chegar nele */
.js.anim .flow--armed.is-drawn .flow__end {
  opacity: 1;
  transition: opacity .4s var(--ease) 1.35s;
}
.js.anim .flow--armed.is-drawn .flow__halo {
  opacity: .45;
  transition: opacity .5s var(--ease) .62s;
}

/* --- fibra ótica: o pulso que corre depois que o desenho terminou ---
   Cada .flow__pulse é um clone do traço de baixo, feito em JS, com um
   tracejado de um segmento só: a "luz" é o segmento, e mover o
   dashoffset por um período inteiro do padrão faz ela percorrer o fio e
   voltar ao começo sem emenda.

   Os dois lados compartilham o mesmo ciclo de 6,4s e se dividem por
   keyframe: as entradas correm no primeiro trecho, o nó acende quando
   elas chegam, e só então a saída parte. É a mesma leitura do desenho
   parado — muitos sinais entram, uma decisão sai — agora em movimento. */
.flow__pulse {
  fill: none;
  stroke-linecap: round;
  opacity: 0;
  stroke-dasharray: calc(var(--seg) * 1px) calc(var(--len) * 1px);
}
.flow__pulse--in  { stroke: var(--glow); stroke-width: 1.9; }
.flow__pulse--out { stroke: #fff;        stroke-width: 3.4; }

@media (max-width: 699px) {
  .flow__pulse--in  { stroke-width: 4.2; }
  .flow__pulse--out { stroke-width: 7; }
}

.flow--live .flow__pulse--in {
  animation: fibraEntra 6.4s linear infinite;
  animation-delay: var(--pd, 0ms);
}
.flow--live .flow__pulse--out { animation: fibraSai 6.4s linear infinite; }
.flow--live .flow__halo { animation: fibraNo 6.4s var(--ease-io) infinite; }
.flow--live .flow__end  { animation: fibraFim 6.4s var(--ease-io) infinite; }

@keyframes fibraEntra {
  0%   { stroke-dashoffset: calc(var(--seg) * 1px); opacity: 0; }
  6%   { opacity: .85; }
  32%  { opacity: .85; }
  38%  { stroke-dashoffset: calc(var(--len) * -1px); opacity: 0; }
  100% { stroke-dashoffset: calc(var(--len) * -1px); opacity: 0; }
}
@keyframes fibraSai {
  0%, 36% { stroke-dashoffset: calc(var(--seg) * 1px); opacity: 0; }
  42%     { opacity: 1; }
  72%     { opacity: 1; }
  78%     { stroke-dashoffset: calc(var(--len) * -1px); opacity: 0; }
  100%    { stroke-dashoffset: calc(var(--len) * -1px); opacity: 0; }
}
/* o nó é a convergência: ele só pisca no instante em que as entradas
   chegam e a saída parte */
@keyframes fibraNo {
  0%, 30% { opacity: .45; transform: scale(1); }
  40%     { opacity: .9;  transform: scale(1.18); }
  56%     { opacity: .45; transform: scale(1); }
  100%    { opacity: .45; transform: scale(1); }
}
@keyframes fibraFim {
  0%, 70% { opacity: 1; }
  78%     { opacity: 1; filter: drop-shadow(0 0 6px var(--glow)); }
  90%     { opacity: 1; filter: none; }
  100%    { opacity: 1; }
}

/* --- o pareado: cada linha é a mesma tarefa vista dos dois lados ---
   No celular vira uma pilha e cada frase carrega seu rótulo (.duo__tag);
   no desktop os rótulos somem porque o cabeçalho de coluna já diz. */
.duo { display: grid; }

.duo__head { display: none; }
.duo__lbl {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: var(--t-h3);
  letter-spacing: -0.03em;
  line-height: 1.1;
  padding-bottom: var(--s4);
}
/* o violeta cheio dá 4,19:1 no preto cósmico e reprova nos 4,5:1 de texto.
   O --violet-lit sobe para 5,1:1 sem sair da família. */
.duo__lbl--m { color: var(--violet-lit); }
.duo__lbl--h { color: var(--glow); }

.duo__row {
  display: grid;
  gap: var(--s4);
  padding-block: var(--s5);
  border-top: 1px solid var(--line);
}
.duo__row p {
  position: relative;
  font-size: var(--t-sm);
  color: var(--ink-2);
  text-wrap: pretty;
}
.duo__h { color: var(--ink); }
.duo__h strong { color: var(--glow); font-weight: 600; }

.duo__tag {
  display: block;
  margin-bottom: 4px;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--violet-lit);
}
.duo__h .duo__tag { color: var(--glow); }

@media (min-width: 800px) {
  .duo__head { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s9); }
  .duo__row { grid-template-columns: 1fr 1fr; gap: var(--s9); align-items: start; }
  /* no desktop o marcador volta a ser o ponto, à esquerda da frase */
  .duo__row p { padding-left: 22px; }
  .duo__row p::before {
    content: '';
    position: absolute;
    left: 0; top: 0.58em;
    width: 6px; height: 6px;
    border-radius: var(--r-pill);
    background: var(--violet);
  }
  .duo__h::before { background: var(--glow); }
  .duo__tag { display: none; }
}

.tech__kicker {
  margin-top: clamp(48px, 6vw, 80px);
  padding-top: var(--s6);
  border-top: 1px solid var(--line);
  font-family: var(--font-d);
  font-weight: 800;
  font-size: var(--t-h3);
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--ink);
  max-width: none;
}


/* ============================================================
   CASES — showreel. A faixa anda de lado enquanto a página
   rola, via scroll-driven animation nativa. Onde o navegador
   não suporta (e em todo mobile) vira swipe com snap.
   ============================================================ */
.reel { border-top: 1px solid var(--line); padding-block: var(--s11) 0; }
.reel__head { margin-bottom: var(--s8); }

.reel__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(78vw, 420px);
  gap: var(--s6);
  padding-inline: var(--gut);
  padding-bottom: var(--s11);
  /* modo padrão = swipe. O pan travado só entra sob @supports. */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.reel__track::-webkit-scrollbar { display: none; }
.reel__track > * { scroll-snap-align: center; }

.case { display: grid; gap: var(--s5); align-content: start; }

.case__img {
  position: relative;
  /* isola o grupo de blend: sem isso o mix-blend-mode do ::before procura
     o backdrop lá em cima e o duotone simplesmente não pinta */
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-card);
  background: var(--bg-1);
  aspect-ratio: 4 / 5;
}
/* duotone violeta pela própria cadeia de filtros: sepia dá um matiz
   estável e o hue-rotate leva ele até o violeta da marca. Feito com
   mix-blend-mode o resultado dependia do grupo de blend e achatava. */
.case__img img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) sepia(1) hue-rotate(212deg) saturate(2.6) brightness(0.74) contrast(1.08);
  transition: filter .55s var(--ease), transform .7s var(--ease);
}

/* desafio e solução voltam em hover, só no desktop com ponteiro */
.case__more {
  position: absolute; inset: 0;
  display: grid; align-content: end; gap: var(--s3);
  padding: var(--s5);
  background: linear-gradient(to top, rgb(7 5 16 / .94) 22%, rgb(7 5 16 / .55) 62%, transparent);
  font-size: var(--t-sm);
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.case__more dt {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--glow);
  margin-bottom: 2px;
}
.case__more dd { margin: 0; color: var(--ink-2); }

@media (hover: hover) and (min-width: 900px) {
  .case:hover .case__img img {
    filter: grayscale(1) sepia(0.2) hue-rotate(212deg) saturate(1.1) brightness(0.98) contrast(1.02);
    transform: scale(1.03);
  }
  .case:hover .case__more { opacity: 1; }
}
@media not all and (min-width: 900px) {
  .case__more { display: none; }
}

.case__body { padding-inline: var(--s1); }
.case__t {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: var(--t-h3);
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin-bottom: var(--s3);
}
.case__num {
  font-size: var(--t-sm);
  color: var(--ink-3);
  max-width: none;
}
.case__num strong {
  color: var(--glow);
  font-family: var(--font-d);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.reel__hint {
  font-size: var(--t-xs);
  color: var(--ink-3);
  margin-top: var(--s5);
}

/* --- pan travado: só onde há scroll-driven animation nativa --- */
@supports (animation-timeline: scroll()) {
  @media (min-width: 900px) and (prefers-reduced-motion: no-preference) {
    .reel {
      /* a altura extra é a distância de rolagem que o pan consome */
      height: 320vh;
      padding-bottom: 0;
    }
    .reel__stick {
      position: sticky;
      top: 0;
      min-height: 100svh;
      display: grid;
      /* sem isso a track (larga por natureza) estica a coluna e o
         cabeçalho, que é centrado por margin auto, sai do eixo da página */
      grid-template-columns: minmax(0, 1fr);
      align-content: center;
      gap: var(--s8);
      overflow: hidden;
    }
    /* no modo travado a altura manda: cabeçalho + card têm de caber numa
       viewport só, senão o topo é cortado pelo align-content: center */
    .reel__track .case__img {
      aspect-ratio: auto;
      height: min(50svh, 480px);
    }
    .reel__track {
      overflow: visible;
      scroll-snap-type: none;
      grid-auto-columns: min(30vw, 400px);
      padding-bottom: 0;
      animation: reelPan linear forwards;
      animation-timeline: scroll(root);
      animation-range: contain;
    }
    .reel__hint { display: none; }
  }
}
@keyframes reelPan {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% + 100vw - var(--gut) * 2)); }
}

/* ============================================================
   CTA FINAL — o arco volta, agora nascendo por baixo.
   ============================================================ */
.final {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-top: 1px solid var(--line);
  padding-block: var(--s11) calc(var(--s11) + 4vw);
  text-align: center;
}
.final__arc {
  position: absolute;
  bottom: -62%; left: 50%;
  width: 165%;
  z-index: -1;
  translate: -50% 0;
  rotate: 180deg;
  opacity: 0.62;
  /* elemento girado 180°: 0% aqui é a base visual, 100% é o alto da seção */
  -webkit-mask-image: linear-gradient(to bottom, transparent 2%, #000 16%, #000 48%, transparent 90%);
  mask-image: linear-gradient(to bottom, transparent 2%, #000 16%, #000 48%, transparent 90%);
}
.final__arc img { width: 100%; }
/* a luz nasce do escuro do rodapé — sem corte seco na borda da seção */
.final::after {
  content: '';
  position: absolute; inset: auto 0 0 0; height: 26%;
  z-index: -1;
  background: linear-gradient(to bottom, transparent, var(--bg-0) 78%);
  pointer-events: none;
}
.final__in { display: grid; justify-items: center; gap: var(--s6); }
.final__h { max-width: 18ch; }
.final .lede { text-align: center; }

/* ---------- rodapé ---------- */
.foot {
  border-top: 1px solid var(--line);
  padding-block: var(--s8);
}
.foot__in { display: grid; gap: var(--s7); }
.foot__logo { color: var(--ink); width: max-content; display: flex; align-items: center; min-height: 44px; }
.foot__logo svg { width: 132px; }
.foot__nav { display: flex; flex-wrap: wrap; gap: var(--s5); }
.foot__nav a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: var(--t-sm); color: var(--ink-2); text-decoration: none;
  transition: color .2s var(--ease);
}
.foot__nav a:hover { color: var(--glow); }
.foot__c {
  font-size: var(--t-xs); color: var(--ink-3);
  max-width: none;
}

@media (min-width: 800px) {
  .foot__in { grid-template-columns: auto 1fr; align-items: center; row-gap: var(--s7); }
  .foot__nav { justify-content: flex-end; }
  .foot__c { grid-column: 1 / -1; }
}

/* ============================================================
   MODAL / FORMULÁRIO
   No desktop o formulário se parte em duas: o enunciado fica
   parado à esquerda, os campos rolam à direita.
   ============================================================ */
.modal {
  /* menor que os 920px de antes: quebrado em três passos, cabe muito
     menos coisa por tela, e a caixa larga só espalhava o campo */
  width: min(820px, 100%);
  max-width: none;
  max-height: 100dvh;
  margin: auto;
  --modal-h: 100dvh;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  overflow: visible;
}
.modal::backdrop {
  background: rgb(7 5 16 / .88);
  backdrop-filter: blur(8px);
}

.modal__card {
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  max-height: var(--modal-h);
  display: grid;
  overflow: hidden;
}

.modal__x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 44px; height: 44px;
  display: grid; place-content: center;
  color: var(--ink-2);
  /* fundo sólido, não transparente: o formulário rola por baixo dele e
     sem isso o X ficava em cima do texto do campo */
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.modal__x svg { width: 20px; height: 20px; }
.modal__x:hover { color: var(--glow); background: var(--bg-2); }

/* coluna esquerda: enunciado + microcópia. Não rola. */
.modal__aside {
  display: none;
  padding: clamp(28px, 3.4vw, 44px);
  border-right: 1px solid var(--line);
  /* chapado, não degradê: o design-type.md manda a profundidade vir do
     contraste entre superfícies, e o único brilho da página é o arco */
  background: color-mix(in oklab, var(--cobalt) 16%, var(--bg-1));
  align-content: space-between;
  gap: var(--s7);
}
/* na coluna estreita o h2--sm ainda quebra em quatro linhas */
.modal__aside .h2 { font-size: clamp(1.5rem, 2.2vw, 1.8rem); line-height: 1.06; }
.modal__aside .h2 + p { margin-top: var(--s4); }
.modal__aside p { font-size: var(--t-sm); color: var(--ink-2); }
.modal__aside .form__micro { margin: 0; }

/* ---------- progresso ----------
   Duas leituras do mesmo estado: a lista, na coluna da esquerda, diz
   onde a pessoa está e o que já ficou para trás; a barra compacta
   entra onde a coluna não cabe. Quem manda nas duas é o main.js. */
.prog { display: grid; gap: var(--s4); list-style: none; counter-reset: passo; }
.prog__i {
  position: relative;
  padding-left: 34px;
  font-size: var(--t-sm);
  color: var(--ink-3);
  transition: color .25s var(--ease);
}
/* o disco numerado: vazio no que falta, contornado no atual, cheio no feito */
.prog__i::before {
  counter-increment: passo;
  content: counter(passo);
  position: absolute;
  left: 0; top: -1px;
  width: 22px; height: 22px;
  display: grid; place-content: center;
  font-family: var(--font-d);
  font-weight: 800;
  font-size: 0.7rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  color: var(--ink-3);
  transition: border-color .25s var(--ease), background-color .25s var(--ease), color .25s var(--ease);
}
.prog__i.is-here { color: var(--ink); }
.prog__i.is-here::before { border-color: var(--glow); color: var(--glow); }
.prog__i.is-done { color: var(--ink-2); }
.prog__i.is-done::before {
  border-color: var(--violet);
  background: var(--violet);
  color: #fff;
}

.prog__bar { display: grid; gap: var(--s2); margin-bottom: var(--s6); }
.prog__count { font-size: var(--t-xs); color: var(--ink-2); }
.prog__count b { color: var(--glow); font-weight: 600; }
.prog__track {
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--line);
  overflow: hidden;
}
.prog__fill {
  display: block;
  height: 100%;
  width: 33.33%;
  border-radius: var(--r-pill);
  background: var(--violet);
  transition: width .4s var(--ease);
}

.modal__scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(24px, 3.4vw, 44px);
  max-height: var(--modal-h);
}
/* no mobile o enunciado vive dentro da coluna que rola */
.modal__head { margin-bottom: var(--s7); padding-right: 44px; }
.modal__head p { margin-top: var(--s4); font-size: var(--t-sm); color: var(--ink-2); }

@media (min-width: 760px) {
  .modal { --modal-h: min(100dvh - 48px, 680px); }
  /* piso de altura para a caixa não pular de tamanho a cada passo:
     os três têm quantidades de campo diferentes */
  .modal__card { grid-template-columns: 286px minmax(0, 1fr); min-height: min(100dvh - 48px, 560px); }
  .modal__aside { display: grid; }
  /* enunciado, progresso compacto e microcópia migram para a esquerda */
  .modal__head, .prog__bar, .form__micro--inline { display: none; }
}

.form { display: grid; gap: var(--s6); }

/* cada passo é um fieldset que some inteiro; o legend é o título dele */
.stepf { border: 0; padding: 0; margin: 0; display: grid; gap: var(--s6); }
.stepf[hidden] { display: none; }
.stepf__t {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: -0.03em;
  color: var(--ink);
  float: left;
  width: 100%;
  margin-bottom: var(--s5);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
}
.stepf > .f:first-of-type, .stepf > .f--set:first-of-type { clear: both; }
.js.anim .stepf:not([hidden]) { animation: passoIn .32s var(--ease); }
@keyframes passoIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* botões de navegação: o Voltar é secundário e não pode ter o mesmo
   peso do Continuar, senão a pessoa hesita entre dois retângulos iguais */
.form__nav { display: flex; flex-wrap: wrap; gap: var(--s3); }
.form__nav .btn { flex: 1 1 auto; }
.form__nav .btn--ghost { flex: 0 1 auto; min-width: 108px; }
/* o display:inline-flex do .btn vence o display:none que o [hidden] traz
   do agente de usuário — sem esta linha os dois botões aparecem juntos */
.btn[hidden] { display: none; }

.f { display: grid; gap: var(--s2); }
.f--set { border: 0; padding: 0; display: grid; gap: var(--s2); }
.f-row { display: grid; gap: var(--s6); }
@media (min-width: 560px) { .f-row { grid-template-columns: 1fr 1fr; } }

/* label e legend no mesmo ritmo — antes o legend tinha margem própria.
   As exceções são obrigatórias: pill, cartão e aceite também são <label>,
   e sem elas este `padding: 0` vencia por especificidade o padding de
   cada um deles — era por isso que o texto encostava na borda. */
.f label:not(.radio):not(.card-opt):not(.check),
.f legend {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink);
  padding: 0;
}
.f legend { float: left; width: 100%; margin-bottom: var(--s2); }
.f--set > .radios, .f--set > .cards { clear: both; }
/* o asterisco de obrigatório não é clicável, então não usa o violeta:
   na regra da marca o violeta é ação. Aqui ele é sinal, e sinal é luz. */
.f abbr { color: var(--glow); text-decoration: none; border: 0; }

/* armadilha de robô: some da tela sem usar display:none nem hidden,
   que alguns preenchedores automáticos sabem detectar e pular */
.hp {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

.f input[type="text"], .f input[type="tel"], .f input[type="email"], .f select {
  width: 100%;
  min-height: 54px;
  padding: var(--s3) var(--s5);
  background: var(--bg-0);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  color: var(--ink);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.f input::placeholder { color: var(--ink-3); }
.f input:hover, .f select:hover { border-color: var(--violet); }
.f input:focus-visible, .f select:focus-visible {
  border-color: var(--violet);
  outline: 2px solid var(--glow);
  outline-offset: 1px;
}
/* a seta era feita de dois gradientes cruzados, que só sabem virar um
   triângulo tosco. Agora é um chevron de verdade, num invólucro. */
.sel { position: relative; display: grid; }
.f .sel select { appearance: none; cursor: pointer; padding-right: 52px; }
.sel__chev {
  position: absolute;
  right: var(--s5); top: 50%;
  translate: 0 -50%;
  width: 18px; height: 18px;
  color: var(--ink-2);
  pointer-events: none;
  transition: color .2s var(--ease);
}
.sel:hover .sel__chev, .sel:focus-within .sel__chev { color: var(--glow); }
.f select option { background: var(--bg-1); color: var(--ink); }

/* área de atuação: dois cartões grandes, lado a lado — mas eles quebram
   sozinhos quando a legenda não cabe, em vez de espremer o texto */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--s3); }
.card-opt {
  display: grid; gap: var(--s1);
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  cursor: pointer;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.card-opt input { position: absolute; opacity: 0; pointer-events: none; }
.card-opt span {
  font-family: var(--font-d);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: -0.03em;
  color: var(--ink);
}
.card-opt small { font-size: var(--t-xs); color: var(--ink-2); }
.card-opt:hover { border-color: var(--violet); }
/* a borda em repouso já é violácea (precisa dos 3:1 de contraste), então
   o selecionado dobra a régua por dentro para a diferença ficar óbvia */
.card-opt:has(input:checked) {
  border-color: var(--violet);
  background: var(--violet-dim);
  box-shadow: inset 0 0 0 1px var(--violet);
}
.card-opt:has(input:focus-visible) { outline: 2px solid var(--glow); outline-offset: 2px; }

/* verba: pills que fluem, não uma torre de cinco caixas.
   São cinco na tela ao mesmo tempo, então a pill é menor que um botão —
   42px, não 48. O que compensa a altura menor é o respiro lateral: numa
   borda arredondada em pill a curva come o canto, e com padding curto o
   texto parece encostado mesmo quando não está. */
.radios { display: flex; flex-wrap: wrap; gap: var(--s3); }
.radio {
  display: inline-flex; align-items: center;
  min-height: 42px;
  padding: 9px var(--s5);
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  cursor: pointer;
  font-size: var(--t-xs);
  letter-spacing: 0.01em;
  color: var(--ink-2);
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.radio input { position: absolute; opacity: 0; pointer-events: none; }
.radio:hover { border-color: var(--violet); color: var(--ink); }
.radio:has(input:checked) {
  border-color: var(--violet);
  background: var(--violet);
  color: #fff;
  font-weight: 600;
}
.radio:has(input:focus-visible) { outline: 2px solid var(--glow); outline-offset: 2px; }

/* a caixa do aceite usa o filete quieto, não o de campo: com --line-2 ela
   ficava idêntica a um input e o olho procurava onde digitar. Os 3:1 de
   contraste que a WCAG pede são do quadradinho, que é o controle. */
.check {
  display: flex; align-items: center; gap: var(--s4);
  min-height: 54px;
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  cursor: pointer;
  font-size: var(--t-sm);
  font-weight: 400;
  color: var(--ink-2);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.check:hover { border-color: var(--violet); color: var(--ink); }
/* o checkbox nativo com accent-color abre branco no escuro; aqui é desenhado */
.check input {
  appearance: none;
  width: 18px; height: 18px;
  flex: none; cursor: pointer;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: var(--bg-0);
  display: grid; place-content: center;
  transition: background-color .18s var(--ease), border-color .18s var(--ease);
}
.check input::before {
  content: '';
  width: 10px; height: 10px;
  clip-path: polygon(14% 47%, 0 61%, 39% 100%, 100% 22%, 85% 9%, 37% 71%);
  background: #fff;
  transform: scale(0);
  transition: transform .18s var(--ease);
}
.check input:checked { background: var(--violet); border-color: var(--violet); }
.check input:checked::before { transform: scale(1); }
.check:hover input { border-color: var(--violet); }
.check:has(input:focus-visible) { outline: 2px solid var(--glow); outline-offset: 2px; }

.f--cond { overflow: hidden; }
.f--cond[hidden] { display: none; }
.f--cond.is-in { animation: condIn .34s var(--ease); }
@keyframes condIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

.f__err {
  font-size: var(--t-xs);
  color: oklch(0.75 0.16 22);
  min-height: 0;
}
.f__err:empty { display: none; }
.f input[aria-invalid="true"], .f select[aria-invalid="true"] { border-color: oklch(0.65 0.18 22); }

.form__micro { font-size: var(--t-xs); color: var(--ink-3); max-width: 32ch; }
.form__fail {
  padding: var(--s3) var(--s4);
  border: 1px solid oklch(0.52 0.15 22);
  border-radius: var(--r-btn);
  font-size: var(--t-sm);
  color: oklch(0.8 0.13 22);
}
.form__fail[hidden] { display: none; }

.btn.is-busy { pointer-events: none; opacity: .72; }
.btn.is-busy .btn__label::after {
  content: '';
  display: inline-block;
  width: 13px; height: 13px;
  margin-left: 9px;
  vertical-align: -1px;
  border: 1.8px solid rgb(255 255 255 / .45);
  border-top-color: #fff;
  border-radius: var(--r-pill);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.done { display: grid; justify-items: center; gap: var(--s5); text-align: center; padding-block: var(--s7); }
.done[hidden] { display: none; }
.done__ico { width: 56px; height: 56px; color: var(--glow); }
.done p { color: var(--ink-2); max-width: 40ch; }
.done .btn { margin-top: var(--s3); }

/* ============================================================
   MOTION — o padrão é visível. A animação só melhora o padrão.
   ============================================================ */
.js.anim [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .62s var(--ease), transform .62s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js.anim [data-reveal].is-in { opacity: 1; transform: none; }

/* entrada coreografada do hero — 'backwards' em vez de opacity:0 na base,
   pra que aba oculta ou renderer sem animação ainda mostre o conteúdo */
.js.anim [data-rise] { animation: rise .82s var(--ease) backwards; }
.js.anim [data-rise="1"] { animation-delay: .10s; }
.js.anim [data-rise="2"] { animation-delay: .18s; }
.js.anim [data-rise="3"] { animation-delay: .34s; }
.js.anim [data-rise="4"] { animation-delay: .46s; }
/* quando a intro roda, o hero espera ela sair de cena */
.js.anim.is-intro [data-rise] { animation-delay: calc(1.5s + var(--rise-at, 0ms)); }
.js.anim.is-intro [data-rise="1"] { --rise-at: .10s; }
.js.anim.is-intro [data-rise="2"] { --rise-at: .18s; }
.js.anim.is-intro [data-rise="3"] { --rise-at: .34s; }
.js.anim.is-intro [data-rise="4"] { --rise-at: .46s; }
@keyframes rise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}

/* o arco se põe conforme a página rola — animação nativa,
   sem um único listener de scroll no JS */
.js.anim .hero__arc { animation: arcIn 1.5s var(--ease) .04s backwards; }
@keyframes arcIn {
  from { opacity: 0; transform: translateY(34px) scale(1.06); }
  to   { opacity: 1; transform: none; }
}
/* o arco do topo se põe conforme a página desce: timeline do documento,
   não view() — o arco já nasce dentro da viewport, então view() começaria
   com o progresso adiantado e o hero abriria apagado */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .js.anim .hero__arc {
      animation: arcIn 1.5s var(--ease) .04s backwards, arcSet linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 90vh;
    }
    .final__arc {
      animation: arcRise linear both;
      animation-timeline: view();
      animation-range: cover 8% cover 72%;
    }
  }
}
@keyframes arcSet {
  to { transform: translateY(-32%) scale(1.05); opacity: .12; }
}
@keyframes arcRise {
  from { translate: -50% 74px; opacity: .2; }
  to   { translate: -50% -26px; opacity: .62; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js.anim [data-reveal], .js.anim [data-rise] { opacity: 1; transform: none; }
  .js.anim [data-rise], .js.anim .hero__arc { animation: none; }
  .menu a { opacity: 1; transform: none; }
  .btn::after { display: none; }
  .flow__in, .flow__out { stroke-dashoffset: 0 !important; }
  .flow__node, .flow__halo, .flow__cap { opacity: 1 !important; }
}
