/* =========================================================
   NODUS · site oficial de pré-lançamento
   HTML, CSS e JS puros. Sem framework, sem build step.

   Regra de cor: existem quatro hex no arquivo inteiro, todos
   declarados no :root. Qualquer outro valor é alpha de um deles.
   ========================================================= */

/* ---------- fontes self-hosted ---------- */
@font-face {
  font-family: "Space Grotesk";
  src: url("assets/fonts/SpaceGrotesk-var-latin.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("assets/fonts/SpaceGrotesk-var-latin-ext.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-400-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-400-latin-ext.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-500-latin.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-500-latin-ext.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* =========================================================
   TOKENS
   ========================================================= */
:root {
  --paper:   #F5F0E8;
  --ink:     #000000;
  --teal:    #16B5A6;
  --magenta: #D63F84;

  /* As mesmas duas cores, escurecidas para texto sobre fundo claro. Sobre
     paper o teal da marca dá 2,2:1 e o magenta 3,78:1, e os dois reprovam em
     texto corrido. Estas passam: teal 5,41:1 e magenta 6,14:1. Servem só para
     letra pequena sobre claro — em fio, borda e display, a cor é a da marca. */
  --teal-texto:    #0A6E63;
  --magenta-texto: #A32760;

  /* tinta apagada para rótulo secundário sobre claro. Abaixo de 55% de
     opacidade a tinta sobre paper cai de 4,5:1, então este é o piso. */
  --ink-fraco: rgba(0, 0, 0, .62);

  /* derivados: alpha das quatro cores acima, nenhum hex novo */
  --wash:        rgba(0, 0, 0, .062);      /* paper escurecido do bloco 06 */
  --rule-light:  rgba(0, 0, 0, .16);
  --rule-dark:   rgba(245, 240, 232, .18);
  --teal-rule:   rgba(22, 181, 166, .32);
  --teal-wash:   rgba(22, 181, 166, .06);
  --scrim:       rgba(0, 0, 0, .58);
  --scrim-deep:  rgba(0, 0, 0, .74);

  --gutter:  clamp(24px, 5.5vw, 104px);
  --measure: 62ch;

  --ease:     cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  --sans: "Space Grotesk", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}


/* =========================================================
   BASE
   ========================================================= */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* a trava de sangria horizontal mora aqui, não no body: em overflow-x
     hidden o navegador computa overflow-y auto, e no body isso faz dele um
     contêiner de rolagem que nunca rola, matando qualquer position sticky
     da página. No html, que é o elemento que de fato rola, o sticky vive. */
  overflow-x: hidden;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ol, ul, figure, figcaption { margin: 0; }
ol, ul { list-style: none; padding: 0; }
img { display: block; max-width: 100%; }
cite { font-style: normal; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 14px 20px;
  font-family: var(--mono);
  font-size: 14px;
}
.skip:focus { left: 12px; top: 12px; }

.wrap {
  width: min(1280px, 100% - var(--gutter) * 2);
  margin-inline: auto;
}

.block {
  position: relative;
  padding-block: clamp(104px, 13vw, 200px);
}


/* =========================================================
   TIPOGRAFIA
   ========================================================= */
.display {
  font-weight: 600;
  letter-spacing: -.022em;
  line-height: 1.05;
  text-wrap: balance;
}

.display--xl { font-size: clamp(3rem, 8vw, 7rem); letter-spacing: -.03em; }
.display--lg { font-size: clamp(2.125rem, 4.6vw, 4.25rem); }
.display--md { font-size: clamp(1.875rem, 3.4vw, 3.125rem); }
.display--sm { font-size: clamp(1.5rem, 2.2vw, 2rem); }

/* rótulo mono. Sobre fundo escuro pode ser teal, sobre paper nunca:
   teal sobre paper dá 2.2:1 e reprova em AA. */
.label {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: .2em;
  text-transform: uppercase;
}

/* A assinatura entrando dentro de uma frase, no lugar da palavra. A altura é
   medida pela caixa alta do texto ao redor e não pelo em inteiro: em 1em ela
   cresce demais e para de ser palavra para virar logotipo. O PNG já vem
   recortado na altura das maiúsculas, então a base assenta sozinha. */
.wordmark {
  display: inline-block;
  width: auto;
  height: .74em;
  vertical-align: baseline;
}


/* =========================================================
   AÇÃO
   Mesma gramática do botão da lista de espera: mono em caixa
   alta, retângulo cheio, sem canto arredondado.
   ========================================================= */
.action {
  display: inline-block;
  padding: 17px 32px;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  background: var(--ink);
  transition: opacity .25s var(--ease);
}

.action:hover { opacity: .84; }

/* sobre fundo escuro a polaridade inverte */
.action--reverse {
  color: var(--ink);
  background: var(--paper);
}

/* O magenta pede tinta preta em cima, não paper: paper sobre magenta dá
   3,78:1 e reprova em AA. Ink sobre magenta dá 4,90:1 e passa. É a mesma
   razão do painel teal da lista de espera. */
.action--magenta {
  color: var(--ink);
  background: var(--magenta);
}

/* de fio, para quando o retângulo cheio pesaria demais na composição */
.action--fio {
  color: var(--paper);
  background: transparent;
  border: 1px solid var(--rule-dark);
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.action--fio:hover {
  opacity: 1;
  border-color: var(--teal);
  background-color: var(--teal-wash);
}

/* O mesmo fio, sobre fundo claro. A variante acima nasceu nas seções escuras
   e pinta o texto de paper: sobre paper ela some, e o botão vira um retângulo
   invisível que ainda ocupa o lugar dele. */
.action--fio-claro {
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule-light);
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.action--fio-claro:hover {
  opacity: 1;
  border-color: var(--ink);
  background-color: var(--wash);
}


/* O termo que a marca reivindica. Magenta sobre paper dá 3,78:1, então ele
   só pode viver em corpo de display, onde o mínimo é 3:1. */
.term { color: var(--magenta); }

/* Em texto corrido o mínimo sobe para 4,5:1 e o magenta da marca reprova.
   "ecossistema" mora no corpo do bloco 04, e por isso usa a versão escurecida. */
.define__body .term { color: var(--magenta-texto); }


/* =========================================================
   HEADER
   ========================================================= */
.masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  background: transparent;
  transition: background-color .4s var(--ease), backdrop-filter .4s var(--ease);
}

.masthead__inner {
  width: min(1280px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 26px;
  transition: padding-block .4s var(--ease);
}

/* lockup fechado: assinatura e tagline saem do mesmo arquivo, na fonte da
   marca. A altura conta o conjunto, então 44px deixa a assinatura nos mesmos
   26px de antes. */
.masthead__logo {
  width: auto;
  height: 44px;
  transition: height .4s var(--ease);
}

.masthead__mark { display: block; line-height: 0; }

/* encolhe no scroll */
.masthead.is-stuck { background-color: var(--ink); }
.masthead.is-stuck .masthead__inner { padding-block: 14px; }
.masthead.is-stuck .masthead__logo { height: 35px; }


/* ---------------------------------------------------------
   Menu

   No desktop os destinos ficam deitados na barra. Abaixo de
   900px viram um painel de tela cheia, que é o único jeito de
   caber sem encolher o alvo de toque.
   --------------------------------------------------------- */
.menu {
  display: flex;
  align-items: center;
  gap: clamp(22px, 2.6vw, 40px);
}

.menu__list {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.4vw, 38px);
}

.menu__link {
  position: relative;
  font-size: 15px;
  text-decoration: none;
  color: var(--paper);
  padding-block: 4px;
}

/* o filete cresce do lugar, sem deslocar o texto ao lado */
.menu__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s var(--ease-out);
}

.menu__link:hover::after { transform: none; }

.menu__cta { padding: 12px 22px; font-size: 12px; }

/* o botão só existe no painel de celular */
.masthead__toggle { display: none; }

/* o logo e o botão ficam por cima do painel quando ele abre */
.masthead__mark,
.masthead__toggle { position: relative; z-index: 2; }

html.menu-open, html.menu-open body { overflow: hidden; }


/* =========================================================
   01 · HERO
   ========================================================= */
.hero {
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding-block: clamp(140px, 18vh, 200px) clamp(120px, 16vh, 180px);
  background: var(--ink);
}

/* camada em sangria: sobrou só a do hero. A do bloco 03 é coluna de grid e
   não fundo, a da filosofia vive dentro de .call__fundo, e a das ventures
   saiu quando a seção virou clara. */
.hero__media {
  position: absolute;
  inset: -4% 0;
  z-index: 0;
  display: block;
}

.call__media { position: absolute; inset: 0; z-index: 0; display: block; }

.hero__media img,
.call__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Véu em duas camadas, para a hora dourada chegar e o texto ainda passar em AA.
   A vertical escurece topo e base, onde ficam o header e o indicador.
   A elipse escurece só o miolo, onde o texto mora, e some antes das bordas:
   é o que segura o contraste do subtítulo sem apagar a luz na rocha. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(ellipse 74% 46% at 50% 54%,
      rgba(0, 0, 0, .42) 0%,
      rgba(0, 0, 0, .30) 52%,
      rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom,
      rgba(0, 0, 0, .62) 0%,
      rgba(0, 0, 0, .34) 34%,
      rgba(0, 0, 0, .40) 62%,
      rgba(0, 0, 0, .72) 100%);
}

/* o hero é a exceção centralizada da página, junto com os blocos 05 e 09 */
.hero__inner {
  position: relative;
  z-index: 2;
  width: min(1280px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  color: var(--paper);
  text-align: center;
}

.hero__sub {
  margin-top: clamp(26px, 3vw, 40px);
  font-size: clamp(1.1875rem, 1.55vw, 1.5rem);
  line-height: 1.5;
  /* sem <br>: a medida decide a quebra. 44ch parte a frase em duas
     linhas de peso parecido, que é o que o eixo central pede. */
  max-width: 44ch;
  margin-inline: auto;
  color: var(--paper);
}

.scroll-cue {
  position: absolute;
  z-index: 2;
  left: 50%;
  transform: translateX(-50%);
  bottom: clamp(32px, 5vh, 56px);
  width: 1px;
  height: 74px;
  overflow: hidden;
  background-color: var(--teal-rule);
}

.scroll-cue span {
  position: absolute;
  inset: 0 0 auto 0;
  height: 32px;
  background-color: var(--teal);
}


/* =========================================================
   02 · A VIRADA
   A frase já tem a virada embutida: a primeira metade arma, a
   segunda desmente. O bloco encena isso em vez de imprimir as
   quatro linhas de uma vez. A metade escura sobe por cima da
   clara e troca a frase no mesmo ponto da tela.

   O estado base, aqui embaixo, é o de quem não tem JS: as duas
   metades empilhadas, na mesma ordem de leitura. O mecanismo de
   corte só entra sob html.js, e volta a este empilhamento quando
   a pessoa pede movimento reduzido.
   ========================================================= */
.turn { padding-block: 0; }

.turn__layer {
  display: flex;
  align-items: center;
  padding-block: clamp(130px, 19vw, 250px);
}

.turn__layer--antes  { background: var(--paper); color: var(--ink); }
.turn__layer--depois { background: var(--ink);   color: var(--paper); }

/* escala maior que a display--lg: aqui a frase ocupa a tela inteira
   e não divide o bloco com mais nada */
.turn__head {
  font-size: clamp(2.25rem, 6.2vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: -.032em;
}

.turn__body {
  margin-top: clamp(30px, 3.4vw, 50px);
  font-size: clamp(1.1875rem, 1.5vw, 1.4375rem);
  line-height: 1.6;
  max-width: var(--measure);
}


/* ---------- com JS, o bloco vira um corte governado pelo scroll ---------- */
html.js .turn { height: 260vh; }

html.js .turn__stick {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

html.js .turn__layer {
  position: absolute;
  inset: 0;
  padding-block: 0;
}

/* --cut vem do scroll: 100% esconde a metade escura, 0% cobre a tela */
html.js .turn__layer--depois { clip-path: inset(var(--cut, 100%) 0 0 0); }

html.js .turn__body {
  opacity: var(--body, 0);
  transform: translate3d(0, calc((1 - var(--body, 0)) * 16px), 0);
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out);
}

/* o fio teal marca a linha de corte enquanto ela sobe */
html.js .turn__edge {
  position: absolute;
  left: 0; right: 0;
  top: var(--cut, 100%);
  height: 2px;
  background: var(--teal);
  opacity: var(--edge, 0);
}


/* =========================================================
   03 · MANIFESTO, TEMPO 2
   Um dado só, em escala gigante, com a fonte nomeada.
   ========================================================= */
/* Composição dividida: o número vive no preto, a imagem sangra na direita
   em brilho real. Imagem atrás de texto obriga a véu pesado e some. Aqui
   ela ocupa metade da tela sem disputar legibilidade com nada. */
.datum {
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
}

.datum__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 40%;
  gap: clamp(40px, 5vw, 80px);
  align-items: center;
  padding-left: max(var(--gutter), calc((100% - 1280px) / 2));
}

.datum__col { max-width: 640px; }

.datum__media {
  height: clamp(460px, 54vw, 760px);
  overflow: hidden;
}

.datum__media picture,
.datum__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.datum__head { margin-top: clamp(48px, 5vw, 76px); }

.datum__number {
  font-size: clamp(3.5rem, 8.2vw, 7.5rem);
  font-weight: 600;
  letter-spacing: -.045em;
  line-height: .92;
  color: var(--paper);
}

.datum__unit,
.datum__scale {
  font-size: .34em;
  font-weight: 500;
  letter-spacing: -.01em;
  vertical-align: baseline;
}

.datum__unit { margin-right: .12em; }
.datum__scale { margin-left: .04em; }

.datum__caption {
  margin-top: clamp(24px, 2.6vw, 36px);
  padding-top: 22px;
  border-top: 1px solid var(--teal-rule);
  font-size: clamp(1rem, 1.15vw, 1.125rem);
  line-height: 1.55;
  max-width: 34ch;
  color: var(--paper);
}

.datum__source {
  display: block;
  margin-top: 12px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--teal);
}


/* =========================================================
   04 · O QUE É A NODUS
   É o único bloco que define categoria, então ele não pode ser
   só um parágrafo bonito. O texto afirma de um lado e o esquema
   mostra do outro: entra P&D, passam os dois motores, sai a
   empresa. É a única ilustração da página inteira.
   ========================================================= */
.define { background: var(--paper); }

.define__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(44px, 6vw, 96px);
  align-items: center;
}

.define__body {
  margin-top: clamp(26px, 2.8vw, 40px);
  font-size: clamp(1.0625rem, 1.3vw, 1.25rem);
  line-height: 1.65;
  max-width: 46ch;
  color: var(--ink);
}

.define__action { margin-top: clamp(30px, 3.2vw, 46px); }

.define__prancha { margin: 0; }


/* ---------------------------------------------------------
   A prancha

   Vocabulário de desenho técnico, não de fluxograma: espessura
   única nos traços, cantos retos, junta marcada onde a linha
   se divide, índice numerado em cada nó e marca de registro
   nos quatro cantos. Os dois motores são os únicos elementos
   preenchidos, porque são o assunto.
   --------------------------------------------------------- */
/* pathLength="1" em cada traço: o dash vira fração do próprio caminho, então
   o desenho não precisa de medição em JS e funciona nas duas pranchas, mesmo
   na que está fora de tela no momento. */
.plate { width: 100%; height: auto; overflow: visible; }
.plate--estreito { display: none; }

.plate__marca path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1;
  opacity: .3;
}

.plate .risco {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.5;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--desenha, 0));
}

.plate .junta { fill: var(--ink); opacity: var(--desenha, 0); }

.plate .caixa {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.5;
  opacity: var(--desenha, 0);
}

.plate .bloco {
  fill: var(--teal-wash);
  stroke: var(--teal);
  stroke-width: 2;
  opacity: var(--desenha, 0);
}

.plate__chave path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1;
  opacity: calc(var(--desenha, 0) * .55);
}

.plate text {
  font-family: var(--mono);
  fill: var(--ink);
  opacity: var(--desenha, 0);
}

/* O ciclo é o único traço que não é preto: ele não faz parte do fluxo de
   produção, ele é a volta. Teal e tracejado leem como retorno, e não como
   mais uma etapa.

   O tracejado ocupa o stroke-dasharray, então este traço não pode usar a
   animação de desenho dos outros — os dois disputam a mesma propriedade.
   Ele entra por opacidade, e com atraso: a conta só sai de zero quando o
   resto da prancha já desenhou 55%, que é a ordem em que a frase se lê. */
.plate__ciclo .risco {
  stroke: var(--teal);
  stroke-width: 2;
  stroke-dasharray: 7 5;
  stroke-dashoffset: 0;
  opacity: calc((var(--desenha, 0) - .55) * 2.4);
}

.plate__ciclo .ciclo__seta {
  fill: var(--teal);
  opacity: calc((var(--desenha, 0) - .7) * 3.4);
}

.plate .rot { font-size: 26px; letter-spacing: -.01em; }
.plate .idx { font-size: 13px; letter-spacing: .18em; opacity: calc(var(--desenha, 0) * .45); }
.plate .sub {
  font-size: 13px;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: calc(var(--desenha, 0) * .6);
}

/* depois de .plate .sub, e não antes: o rótulo do ciclo tem as duas classes
   e as duas regras têm a mesma especificidade, então quem vem por último
   ganha. Antes daqui, o .sub anulava o atraso do ciclo. */
.plate .sub--ciclo {
  fill: var(--teal);
  opacity: calc((var(--desenha, 0) - .7) * 3.4);
}


/* =========================================================
   05 · OS MOTORES

   Dois rotores de precisão engrenados, girando em sentidos
   opostos: um não anda sem o outro, que é o que a seção diz.
   A frase que ela defende mora dentro dos rotores, em corpo
   de manchete, e não num rodapé de 13px.

   Cada motor tem a sua cor: o Mentat é teal, o Grafus é
   magenta. Isso obriga o bloco a ser escuro. Teal sobre paper
   dá 2,2:1 e some, e magenta sobre paper reprova nos rótulos.
   Sobre tinta preta os dois passam: teal 7,4:1 e magenta
   4,9:1.
   ========================================================= */
.engines {
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
}

.engines__abre { position: relative; z-index: 1; }

.engines__intro {
  margin-top: clamp(22px, 2.4vw, 34px);
  max-width: 46ch;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  line-height: 1.65;
  color: var(--paper);
}

.engines__palco {
  display: grid;
  place-items: center;
  padding-block: clamp(24px, 3.4vw, 56px);
}

.rotores { width: min(1180px, 100%); height: auto; overflow: visible; }
.rotores--estreito { display: none; }


/* ---------- a peça ---------- */
.rotores .aro,
.rotores .risco { fill: none; }
.rotores .aro { stroke-width: 1.5; }

.rotor--mentat .aro,
.rotor--mentat .risco { stroke: var(--teal); }
.rotor--mentat .letras { fill: var(--teal); }

.rotor--grafus .aro,
.rotor--grafus .risco { stroke: var(--magenta); }
.rotor--grafus .letras { fill: var(--magenta); }

.rotores .letras {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: .3em;
  text-transform: uppercase;
}

/* o maior elemento do desenho é a frase, não a peça */
.rotores .frase {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 62px;
  letter-spacing: -.035em;
  fill: var(--paper);
  text-anchor: middle;
}


/* ---------- o texto ---------- */
.engines__par {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(34px, 4.6vw, 84px);
  margin-top: clamp(36px, 4.6vw, 70px);
}

/* coluna flex para o botão poder ser empurrado ao pé: as duas descrições
   têm comprimentos diferentes e os botões precisam se alinhar entre si */
.engine {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--rule-dark);
  padding-top: clamp(24px, 2.8vw, 38px);
}

.engine__nome {
  font-size: clamp(2.25rem, 4.6vw, 3.75rem);
  font-weight: 600;
  letter-spacing: -.035em;
  line-height: 1;
}

.engine--mentat .engine__nome { color: var(--teal); }
.engine--grafus .engine__nome { color: var(--magenta); }

.engine__papel {
  margin-top: 14px;
  color: var(--paper);
  opacity: .6;
}

.engine__corpo {
  margin-top: clamp(18px, 2vw, 26px);
  margin-bottom: clamp(26px, 3vw, 40px);
  max-width: 40ch;
  font-size: clamp(1.0625rem, 1.2vw, 1.1875rem);
  line-height: 1.65;
  color: var(--paper);
}

/* margin-top auto come a folga que sobra, então os dois botões pousam na
   mesma linha mesmo com descrições de tamanhos diferentes */
.engine__action { margin-top: auto; align-self: flex-start; }


/* =========================================================
   06 · AS VENTURES

   Grade clara, ficha escura. A seção é a única do miolo em
   papel entre os motores e a filosofia, o que quebra a
   sequência de três blocos escuros seguidos.

   A cor da marca não cabe aqui: teal sobre paper dá 2,2:1 e
   some. Então a grade é tinta sobre papel, monocromática, e o
   teal volta na ficha, que é escura. O mergulho do claro para
   o escuro é o próprio gesto de abrir.
   ========================================================= */
.ventures { background: var(--paper); color: var(--ink); }

.ventures__head { color: var(--ink); }

.ventures__lead {
  margin-top: clamp(20px, 2.2vw, 30px);
  max-width: 52ch;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  line-height: 1.65;
  color: var(--ink);
}


/* ---------- a grade ---------- */
.vgrade {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 28px);
  margin-top: clamp(44px, 5vw, 76px);
}

.vcard {
  appearance: none;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(28px, 3.4vw, 48px);
  min-height: 212px;
  padding: clamp(20px, 2.4vw, 30px);
  border: 1px solid var(--rule-light);
  background: transparent;
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}

.vcard:hover {
  border-color: var(--ink);
  background-color: var(--wash);
}

.vcard__topo { display: block; }

/* o rótulo de estágio em tinta, não em teal: sobre papel o teal reprova */
.vcard__estagio { display: block; color: var(--ink); opacity: .6; }

.vcard__nome {
  display: block;
  margin-top: 14px;
  font-size: clamp(1.375rem, 2.2vw, 1.875rem);
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.05;
}

.vcard__setor { display: block; margin-top: 6px; font-size: .9375rem; line-height: 1.5; opacity: .68; }

.vcard__seta {
  align-self: flex-end;
  font-size: 20px;
  line-height: 1;
  transition: transform .3s var(--ease-out);
}
.vcard:hover .vcard__seta { transform: translate(4px, -4px); }


/* ---------- a ficha em tela cheia ---------- */
.vficha {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--ink);
  color: var(--paper);
}

/* o atributo hidden é a fonte da verdade do estado: sem JS a ficha
   simplesmente não existe, e a grade continua sendo uma lista legível */
.vficha[hidden] { display: none; }

html.js .vficha {
  opacity: 0;
  transition: opacity .35s var(--ease);
}
html.js .vficha.is-aberta { opacity: 1; }

.vficha__fechar {
  position: absolute;
  top: clamp(20px, 2.4vw, 34px);
  right: clamp(20px, 2.4vw, 34px);
  z-index: 2;
  appearance: none;
  padding: 11px 18px;
  border: 1px solid var(--rule-dark);
  background: transparent;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper);
  cursor: pointer;
  transition: border-color .25s var(--ease);
}
.vficha__fechar:hover { border-color: var(--teal); }

.vficha__media { position: relative; overflow: hidden; }

.vficha__texto {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(40px, 5vw, 96px);
  overflow-y: auto;
}

.vficha__estagio { color: var(--teal); }

.vficha__nome {
  margin-top: 14px;
  font-size: clamp(2.25rem, 4.4vw, 3.75rem);
  font-weight: 600;
  letter-spacing: -.035em;
  line-height: 1;
}

.vficha__setor {
  margin-top: 10px;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  opacity: .7;
}

.vficha__corpo-texto {
  margin-top: clamp(24px, 2.8vw, 38px);
  max-width: 46ch;
  font-size: clamp(1.0625rem, 1.3vw, 1.25rem);
  line-height: 1.65;
}

.vficha__rot {
  margin-top: clamp(28px, 3.2vw, 44px);
  padding-top: clamp(16px, 1.8vw, 22px);
  border-top: 1px solid var(--rule-dark);
  color: var(--paper);
  opacity: .6;
}

.vficha__time {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
}

.vficha__site {
  display: inline-block;
  margin-top: clamp(22px, 2.6vw, 34px);
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .1em;
  color: var(--teal);
  text-underline-offset: 5px;
}

/* o marcador de pendência é inline-flex por padrão, para caber dentro de
   frase. Aqui ele é um parágrafo do fluxo, e sem isto o link do site subia
   para a mesma linha e os dois colidiam. */
.vficha .slot--line {
  display: flex;
  width: fit-content;
  margin-top: clamp(24px, 2.8vw, 38px);
}
.vficha .slot--line + .vficha__site { display: block; }

/* a moldura da foto que ainda não existe, no lado escuro */
.vficha .slot--venture {
  position: absolute;
  inset: 0;
  height: auto;
}


/* =========================================================
   07 · NOSSA FILOSOFIA
   O bloco mais longo. Coluna única larga, cada declaração
   com seu próprio tempo de scroll.
   ========================================================= */
.call {
  background: var(--ink);
  color: var(--paper);
  /* o respiro vive no conteúdo, não na seção: assim o fundo fixo começa
     na borda de cima sem precisar de margem negativa, que arrastaria o
     texto junto e cortaria o título */
  padding-block: 0;
}
/* sem overflow hidden aqui: ele faz da seção um contêiner de rolagem e
   mata o sticky do fundo, que passaria a cobrir só a primeira tela. A
   sangria que o overflow continha saiu junto com a camada antiga. */

/* Véu calibrado por medição sobre o cânion, que é bem mais claro que o
   veio de minério que estava aqui. Em .74 chapado a foto sumia; a rampa
   abaixo abre o miolo, onde mora a luz da primeira hora, e fecha nas
   pontas, onde passam o header e o texto. */
.call__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to bottom,
      rgba(0, 0, 0, .78) 0%,
      rgba(0, 0, 0, .58) 38%,
      rgba(0, 0, 0, .60) 66%,
      rgba(0, 0, 0, .80) 100%);
}



.call__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(140px, 16vw, 240px);
}

/* O fundo é fixo e do tamanho da tela, não da seção.

   Duas razões. A seção tem 2460px de altura e a foto é uma vista horizontal:
   cobrindo tudo, o cover recortaria uma tira vertical e a composição sumiria.
   E o wipe abre em faixa a partir do centro da camada, então numa camada de
   2657px a faixa aberta nascia abaixo da tela e o leitor via preto até ela
   crescer. Do tamanho da tela, os dois problemas somem: o cânion fica
   inteiro e o wipe se comporta como no hero. */
.call__fundo {
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100vh;
  /* a margem negativa zera a caixa de fluxo: sem ela o sticky de 900px
     dentro de uma seção de 1942px só ficaria preso por 1042px e soltaria
     antes do fim, deixando a última tela preta. Com ela, o curso é o da
     seção inteira, e de quebra o conteúdo não precisa ser puxado de volta. */
  margin-bottom: -100vh;
  overflow: hidden;
}

/* o bloco pedia um nome antes da declaração: entra como rótulo, para o
   leitor saber o que está lendo sem perder a frase que abre */
.call__label {
  margin-bottom: clamp(22px, 2.4vw, 34px);
  color: var(--teal);
}

.call__open {
  max-width: 24ch;
  color: var(--paper);
}

.creed {
  margin-top: clamp(88px, 12vw, 160px);
  display: grid;
  gap: clamp(64px, 8vw, 116px);
}

.creed__item {
  position: relative;
  padding-left: clamp(20px, 3vw, 44px);
  max-width: 60ch;
}

/* barra curta no lugar de numeração: manifesto, não política interna */
.creed__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: .46em;
  width: 3px;
  height: 1.15em;
  background-color: var(--teal);
}

/* único uso de magenta nesta parte da página, na declaração que
   separa a Nodus de promessa de aceleradora */
.creed__item--key::before { background-color: var(--magenta); }

.creed__title {
  font-size: clamp(1.625rem, 3vw, 2.75rem);
  font-weight: 500;
  line-height: 1.14;
  letter-spacing: -.018em;
  color: var(--paper);
}

.creed__support {
  margin-top: clamp(14px, 1.4vw, 20px);
  font-size: clamp(1.0625rem, 1.25vw, 1.25rem);
  line-height: 1.55;
  max-width: 52ch;
  color: var(--paper);
}


/* =========================================================
   07 · O QUE SE COMPARTILHA

   Escuro entre a grade clara das ventures e a bifurcação
   clara. O bloco lista o que o ecossistema entrega, e o
   último item é uma meta declarada, não uma entrega: ele
   ganha contorno teal em vez de preenchimento, para se ler
   como promessa de projeto e não como item pronto.
   ========================================================= */
.share {
  background: var(--ink);
  color: var(--paper);
}

.share__rot { color: var(--teal); }

.share__head { margin-top: clamp(14px, 1.6vw, 22px); }

/* Sem opacidade: sobre fundo escuro o texto é paper cheio. Toda seção
   escura do site que já foi aprovada faz assim, e texto acinzentado sobre
   escuro está fora do vocabulário da marca. */
.share__lead {
  margin-top: clamp(20px, 2.2vw, 30px);
  max-width: 54ch;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  line-height: 1.65;
}

.share__desenho { margin: clamp(40px, 5vw, 72px) 0 0; }

.share__grid {
  list-style: none;
  margin: clamp(32px, 3.4vw, 48px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(20px, 2.2vw, 32px);
}

.share__item {
  border-top: 1px solid var(--rule-dark);
  padding-top: clamp(16px, 1.8vw, 22px);
}

.share__nome {
  font-size: clamp(1rem, 1.2vw, 1.125rem);
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.25;
}

.share__corpo {
  margin-top: 9px;
  font-size: .9375rem;
  line-height: 1.6;
}


/* ---------------------------------------------------------
   O leito

   As cinco ventures apoiadas na base comum, e a sexta em
   tracejado. Mesmo vocabulário da prancha do bloco 04:
   traço único, canto reto, rótulo em mono. O teal marca o
   que é da Nodus, e o tracejado marca o que ainda não é.
   --------------------------------------------------------- */
.leito { width: 100%; height: auto; display: block; }
.leito--estreito { display: none; }

.leito__marca path {
  fill: none;
  stroke: var(--paper);
  stroke-width: 1;
  opacity: .3;
}

.leito .vcaixa {
  fill: none;
  stroke: var(--paper);
  stroke-width: 1.5;
}

.leito .vcaixa--proxima {
  stroke: var(--teal);
  stroke-dasharray: 6 5;
}

.leito .perna {
  fill: none;
  stroke: var(--paper);
  stroke-width: 1.5;
  opacity: .55;
}

.leito .perna--proxima {
  stroke: var(--teal);
  stroke-dasharray: 6 5;
  opacity: 1;
}

/* a base é o único elemento preenchido, porque é o assunto do bloco */
.leito .bloco {
  fill: rgba(22, 181, 166, .12);
  stroke: var(--teal);
  stroke-width: 2;
}

.leito text { font-family: var(--mono); fill: var(--paper); }
.leito .vnome { font-size: 20px; letter-spacing: -.01em; }
.leito .vnome--proxima { fill: var(--teal); font-size: 17px; }
.leito .brot { font-size: 19px; letter-spacing: -.01em; }
.leito .leito__cap {
  font-size: 14px;
  letter-spacing: .16em;
  text-transform: uppercase;
  fill: var(--teal);
}


/* =========================================================
   08 · OS DOIS CAMINHOS

   Claro, para separar o convite da prova escura que vem
   antes. Cada caminho fica com a cor de um motor: a venture
   em teal, a solução em magenta, que é o mesmo par que o
   bloco 05 usa.
   ========================================================= */
.fork { background: var(--paper); }

.fork__lead {
  margin-top: clamp(20px, 2.2vw, 30px);
  max-width: 58ch;
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  line-height: 1.65;
}

.fork__par {
  margin-top: clamp(40px, 4.6vw, 68px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 40px);
}

.via {
  border: 1px solid var(--rule-light);
  border-top-width: 3px;
  padding: clamp(24px, 3vw, 40px);
  display: flex;
  flex-direction: column;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}

.via--venture { border-top-color: var(--teal); }
.via--solucao { border-top-color: var(--magenta); }
.via:hover { background: var(--wash); }

/* rótulo de 13px sobre paper: a cor da marca reprova aqui, então entra a
   versão escurecida. A borda de cima do cartão continua na cor da marca,
   porque fio não é texto e o mínimo dele é 3:1. */
.via__rot { color: var(--ink-fraco); }
.via--venture .via__rot { color: var(--teal-texto); }
.via--solucao .via__rot { color: var(--magenta-texto); }

.via__nome {
  margin-top: 12px;
  font-size: clamp(1.375rem, 2.2vw, 1.875rem);
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.1;
}

.via__corpo {
  margin-top: 14px;
  font-size: 1rem;
  line-height: 1.65;
  max-width: 42ch;
  /* cresce para empurrar o botão ao pé do cartão. O empurrão não pode vir de
     margin-top:auto no botão: quando os dois cartões têm a mesma altura não
     sobra espaço, o auto vira zero e o botão encosta no texto. */
  flex: 1 1 auto;
}

.via__action { margin-top: clamp(24px, 2.6vw, 36px); align-self: flex-start; }

/* cada botão puxa a cor do seu caminho no hover, o mesmo par teal/magenta
   que a borda de cima do cartão já usa */
.via--venture .via__action:hover { border-color: var(--teal);    background-color: var(--teal-wash); }
.via--solucao .via__action:hover { border-color: var(--magenta); background-color: rgba(214, 63, 132, .08); }


/* =========================================================
   10 · QUEM CONSTRÓI
   ========================================================= */
.crew { background: var(--paper); }

.crew__grid {
  margin-top: clamp(48px, 5vw, 76px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(24px, 2.6vw, 40px);
}

/* Em cor. O monocromático foi testado e reprovado: envelhecia as quatro
   pessoas e dava ar de retrato póstumo. O recorte 4:5 e a equalização de
   tom continuam valendo, e são eles que fazem quatro fotos de origens
   diferentes conviverem na mesma grade. */
.person__foto {
  display: block;
  aspect-ratio: 4 / 5;
  background-color: var(--wash);
  overflow: hidden;
}

.person__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.person__name {
  margin-top: 20px;
  font-size: clamp(1.0625rem, 1.3vw, 1.1875rem);
  font-weight: 600;
  letter-spacing: -.01em;
}

.person__role {
  margin-top: 5px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink);
}

.person__bio {
  margin-top: 12px;
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--ink);
}


/* =========================================================
   09 · WAITLIST
   Painel teal sobre paper. Texto em ink: paper sobre teal
   dá 2.5:1 e reprova.
   ========================================================= */
.join { background: var(--paper); }

.join__panel {
  background: var(--teal);
  color: var(--ink);
  padding: clamp(56px, 8vw, 120px) clamp(28px, 6vw, 96px);
  text-align: center;
}

.join__head { color: var(--ink); }

.join__body {
  margin-top: clamp(24px, 2.6vw, 36px);
  margin-inline: auto;
  max-width: 48ch;
  font-size: clamp(1.0625rem, 1.3vw, 1.1875rem);
  line-height: 1.6;
  color: var(--ink);
}

.waitlist {
  margin-top: clamp(40px, 4.5vw, 64px);
  margin-inline: auto;
  max-width: 520px;
  text-align: left;
  display: grid;
  gap: 26px;
}

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

.field { position: relative; }

.field__label {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink);
}

/* "opcional" se distingue por caixa e tamanho, não por tinta rebaixada */
.field__opt { text-transform: none; letter-spacing: .04em; font-size: 10px; }

.field__input {
  width: 100%;
  margin-top: 8px;
  padding: 12px 0;
  font-family: var(--sans);
  font-size: 1.0625rem;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  transition: border-color .25s var(--ease);
}

.field__input:focus { outline: none; border-bottom-width: 3px; }
.field__input:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; }

.field__count {
  position: absolute;
  right: 0;
  bottom: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  color: var(--ink);
}

.consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

/* caixa desenhada à mão: a nativa entra branca sobre o teal e destoa.
   Continua sendo um input de verdade, com foco e teclado intactos. */
.consent__box {
  appearance: none;
  -webkit-appearance: none;
  width: 21px;
  height: 21px;
  margin: 2px 0 0;
  flex: 0 0 auto;
  background: transparent;
  border: 2px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  display: grid;
  place-content: center;
}

.consent__box::after {
  content: "";
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--teal);
  border-bottom: 2px solid var(--teal);
  transform: rotate(-45deg) translate(1px, -1px) scale(0);
  transition: transform .16s var(--ease-out);
}

.consent__box:checked { background: var(--ink); }
.consent__box:checked::after { transform: rotate(-45deg) translate(1px, -1px) scale(1); }

.consent__label {
  font-size: .875rem;
  line-height: 1.5;
  color: var(--ink);
}

.consent__label a { color: var(--ink); text-underline-offset: 3px; }

.waitlist__submit {
  justify-self: start;
  padding: 17px 32px;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  border: 0;
  cursor: pointer;
  transition: opacity .25s var(--ease);
}

.waitlist__submit:hover { opacity: .84; }
.waitlist__submit:disabled { cursor: default; opacity: .6; }

.waitlist__error {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  border-left: 3px solid var(--ink);
  padding-left: 12px;
}

.join__done {
  margin-top: clamp(40px, 4.5vw, 64px);
  font-size: clamp(1.25rem, 1.7vw, 1.5rem);
  font-weight: 500;
  color: var(--ink);
}

.join__note {
  margin-top: clamp(30px, 3vw, 44px);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .06em;
  line-height: 1.6;
  color: var(--ink);
}


/* =========================================================
   ASSET SLOTS
   Placeholder dimensionado para o que ainda não chegou.
   Nada de logo ou ícone desenhado em CSS.
   ========================================================= */
.slot {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  border: 2px dashed var(--teal-rule);
  background-color: var(--teal-wash);
  text-align: center;
  padding: 16px;
}

.slot--person { aspect-ratio: 4 / 5; }

/* pendência de uma linha, mesma gramática do slot de imagem: o que falta
   fica visível em vez de virar texto inventado */
.slot--line {
  display: inline-flex;
  width: auto;
  margin-top: clamp(18px, 2vw, 26px);
  padding: 7px 14px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--teal);
}

/* sobre imagem o slot precisa de fundo próprio, senão vira fantasma */
.slot--venture {
  height: 100%;
  background-color: rgba(0, 0, 0, .74);
  border-color: var(--teal-rule);
}

.slot__name,
.slot__dim {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: .04em;
}

.slot__name { color: var(--teal); }
.slot__dim  { color: var(--teal); }

/* sobre paper, o teal do slot não é texto de leitura, é etiqueta de
   produção. Ainda assim ganha peso para não sumir. */
.crew .slot__name,
.crew .slot__dim { color: var(--ink); }
.crew .slot { border-color: var(--rule-light); background-color: var(--wash); }


/* =========================================================
   PÁGINA DE PRIVACIDADE
   ========================================================= */
.masthead--solid { background-color: var(--ink); }

.legal {
  padding-block: clamp(140px, 15vw, 200px) clamp(80px, 9vw, 130px);
}

.legal__inner { max-width: 68ch; }

.legal__stamp {
  margin-top: 18px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink);
}

.legal__lead {
  margin-top: clamp(32px, 3.5vw, 48px);
  font-size: clamp(1.125rem, 1.35vw, 1.25rem);
  line-height: 1.6;
}

.legal__h2 {
  margin-top: clamp(44px, 4.5vw, 64px);
  font-size: clamp(1.125rem, 1.4vw, 1.3125rem);
  font-weight: 600;
  letter-spacing: -.01em;
  padding-top: 18px;
  border-top: 3px solid var(--teal);
}

.legal p { margin-top: 16px; line-height: 1.65; }
.legal__list { margin-top: 16px; display: grid; gap: 8px; }

.legal__list li {
  position: relative;
  padding-left: 22px;
  line-height: 1.6;
}

.legal__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 9px;
  height: 1px;
  background-color: var(--teal);
}

.legal a { color: var(--ink); text-underline-offset: 3px; }

.legal__foot {
  margin-top: clamp(44px, 4.5vw, 64px);
  padding-top: 22px;
  border-top: 1px solid var(--rule-light);
  font-size: .9375rem;
}

.legal__back {
  margin-top: clamp(32px, 3.5vw, 48px);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
}


/* =========================================================
   FOOTER
   ========================================================= */
.colophon {
  background: var(--paper);
  padding-block: clamp(44px, 5vw, 72px);
  border-top: 1px solid var(--rule-light);
}

.colophon__inner {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3.5vw, 52px);
}

.colophon__logo { width: auto; height: 34px; }

.colophon__year,
.colophon__link {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink);
}

.colophon__year { margin-left: auto; }
.colophon__link { text-underline-offset: 3px; }


/* =========================================================
   MOTION
   Base do briefing: fade mais 16px de translate, 400ms, ease-out.
   As headlines de display ganham revelação por linha, porque o
   manifesto é a espinha da página e pede mais atenção.
   ========================================================= */
html.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .4s var(--ease-out), transform .4s var(--ease-out);
}

html.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* stagger curto entre as declarações do bloco 04 */
html.js .creed__item { transition-delay: 60ms; }

html.js .engine--grafus { transition-delay: 90ms; }
html.js .person:nth-child(2) { transition-delay: 70ms; }
html.js .person:nth-child(3) { transition-delay: 140ms; }
html.js .person:nth-child(4) { transition-delay: 210ms; }

/* ---------------------------------------------------------
   Abertura da imagem
   A foto entra por uma fenda horizontal que se abre até a tela
   cheia, e assenta de 1.06 para 1. A imagem não aparece, ela é
   revelada. É o gesto que dá o tom de precisão do site.

   Dois eixos separados de propósito: o recorte e a escala ficam
   aqui, o deslocamento do parallax fica no transform do <picture>,
   escrito pelo JS. Se dividissem a mesma propriedade, um
   sobrescreveria o outro a cada quadro de scroll.
   --------------------------------------------------------- */
/* display block é obrigatório: <picture> nasce inline, e clip-path em
   porcentagem sobre caixa inline recorta a imagem inteira. */
.media-wipe { display: block; }

html.js .media-wipe {
  clip-path: inset(47% 0 47% 0);
  transition: clip-path 1.15s var(--ease-out);
  will-change: clip-path, transform;
}

html.js .media-wipe.is-open { clip-path: inset(0 0 0 0); }

/* O assentamento de entrada vale só para as imagens em coluna, que não
   são governadas pelo scroll. Nas de sangria quem manda é --z, e uma
   regra `.is-open img { transform: none }` genérica venceria por
   especificidade e mataria o recuo. */
html.js .datum__media img {
  transform: scale(1.06);
  transition: transform 1.9s var(--ease-slow);
}

html.js .datum__media .is-open img { transform: none; }

/* =========================================================
   PROFUNDIDADE NAS IMAGENS EM SANGRIA
   Nas três imagens que ocupam a tela inteira, a foto recua
   enquanto você rola: você entra colada no detalhe e sai vendo
   o conjunto. Somada ao deslocamento de 8%, é o que faz o scroll
   parecer atravessar um espaço em vez de empilhar seções.

   A escala é escrita pelo script em --z, então aqui não há
   transição: quem comanda é o scroll, quadro a quadro. O
   deslocamento fica no transform do <picture>, num eixo separado,
   senão um sobrescreveria o outro a cada quadro.
   ========================================================= */
html.js .hero__media img,
html.js .call__media img {
  transform: scale(var(--z, 1));
  transition: none;
}

/* revelação por linha das headlines */
.line { display: block; overflow: hidden; padding: .1em 0 .17em; margin: -.1em 0 -.17em; }
.line__in { display: block; }

html.js .is-split .line__in {
  transform: translateY(115%);
  transition: transform .55s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 80ms);
}

html.js .is-split.is-visible .line__in { transform: none; }

/* a headline dividida não usa o fade genérico: a máscara já esconde */
html.js .is-split { opacity: 1; transform: none; transition: none; }

/* o hero entra sozinho, sem esperar o observer */
html.js .hero .is-split .line__in { transition-delay: calc(.15s + var(--i, 0) * 80ms); }
html.js .hero__sub { transition-delay: .45s; }

.scroll-cue { opacity: 0; }
html.js .scroll-cue { animation: cue-in .8s var(--ease) 1.1s forwards; }
html.js .scroll-cue span { animation: cue 2.6s var(--ease) infinite; }
html:not(.js) .scroll-cue { opacity: 1; }

@keyframes cue-in { to { opacity: 1; } }
@keyframes cue {
  0%   { transform: translateY(-100%); }
  55%  { transform: translateY(132%); }
  100% { transform: translateY(132%); }
}

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

  html.js .reveal,
  html.js .reveal.is-visible,
  html.js .is-split .line__in,
  html.js .datum__media img {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }

  html.js .media-wipe {
    clip-path: none;
    transition: none;
    transform: none !important;
  }

  html.js .hero__media img,
  html.js .call__media img { transform: none; }

  /* a virada volta a ser empilhamento: sem o scroll escrevendo --cut, a
     metade escura ficaria recortada fora da tela e a frase perderia o
     desmentido. Aqui não é só o movimento que sai, é conteúdo. */
  html.js .turn { height: auto; }
  html.js .turn__stick { position: static; height: auto; overflow: visible; }
  html.js .turn__layer {
    position: static;
    inset: auto;
    padding-block: clamp(130px, 19vw, 250px);
  }
  html.js .turn__layer--depois { clip-path: none; }
  html.js .turn__body { opacity: 1; transform: none; }
  html.js .turn__edge { display: none; }

  html.js .scroll-cue { opacity: 1; animation: none; }
  html.js .scroll-cue span { animation: none; }

  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}


/* =========================================================
   RESPONSIVO
   Mobile não é redução. O manifesto mantém escala.
   ========================================================= */
@media (max-width: 1080px) {
  /* quatro colunas de item compartilhado ficam estreitas demais antes disso */
  .share__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .datum__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(44px, 7vw, 68px);
    padding-inline: var(--gutter);
  }
  .datum__col { max-width: none; }
  .datum__media {
    height: clamp(320px, 52vw, 460px);
    margin-right: calc(var(--gutter) * -1);
  }

  .define__grid { grid-template-columns: minmax(0, 1fr); gap: clamp(40px, 7vw, 64px); }
  .define__body { max-width: none; }

  .vgrade { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .engines__par { grid-template-columns: minmax(0, 1fr); }
  .engines__intro { max-width: none; }

  .crew__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* ---------------------------------------------------------
   Menu de celular

   Sem JS o painel não teria como abrir, então ele só vira
   painel sob html.js. Sem JS os destinos quebram para uma
   segunda linha da barra: mais feio, mas alcançável.
   --------------------------------------------------------- */
@media (max-width: 900px) {
  .masthead__inner { flex-wrap: wrap; gap: 14px 20px; }
  .menu { flex-wrap: wrap; gap: 14px 22px; }
  .menu__list { flex-wrap: wrap; gap: 16px; }

  html.js .masthead__toggle {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    border: 0;
    background: transparent;
    color: var(--paper);
    font-family: var(--mono);
    font-weight: 500;
    font-size: 12px;
    letter-spacing: .18em;
    text-transform: uppercase;
    cursor: pointer;
  }

  .masthead__burger { position: relative; display: block; width: 22px; height: 14px; }
  .masthead__burger i {
    position: absolute;
    left: 0; right: 0;
    height: 2px;
    background: var(--paper);
    transition: transform .3s var(--ease-out), opacity .2s var(--ease-out);
  }
  .masthead__burger i:nth-child(1) { top: 0; }
  .masthead__burger i:nth-child(2) { top: 6px; }
  .masthead__burger i:nth-child(3) { top: 12px; }

  [aria-expanded="true"] .masthead__burger i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  [aria-expanded="true"] .masthead__burger i:nth-child(2) { opacity: 0; }
  [aria-expanded="true"] .masthead__burger i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

  html.js .menu {
    position: fixed;
    inset: 0;
    z-index: 1;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: clamp(30px, 6vw, 48px);
    padding: 0 var(--gutter);
    background: var(--ink);
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s var(--ease), visibility .3s;
  }

  html.js .menu.is-open { opacity: 1; visibility: visible; }

  html.js .menu__list {
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(18px, 3.4vw, 28px);
  }
  html.js .menu__link { font-size: clamp(1.75rem, 6.4vw, 2.5rem); letter-spacing: -.02em; }
  html.js .menu__link::after { display: none; }
  html.js .menu__cta { padding: 16px 28px; font-size: 13px; }

  /* na página de motor o header é claro, então a barra do menu inverte */
  .masthead--claro .masthead__burger i { background: var(--ink); }
}


@media (max-width: 720px) {
  .share__grid { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .share__item--meta {
    margin-top: 4px;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .share__item--meta .share__corpo { grid-row: auto; grid-column: 1; }
  .fork__par { grid-template-columns: minmax(0, 1fr); }

  .masthead__inner { padding-block: 16px; }
  .masthead__logo { height: 37px; }
  .masthead.is-stuck .masthead__inner { padding-block: 11px; }
  .masthead.is-stuck .masthead__logo { height: 31px; }

  .hero { padding-block: 130px 120px; }
  .hero__sub { max-width: none; }

  /* o curso do corte encurta: 260vh de polegar num telefone é longo demais
     para uma frase só */
  html.js .turn { height: 210vh; }

  /* a prancha larga encolhe até os rótulos ficarem ilegíveis: aqui entra a
     versão vertical, que cabe na largura do telefone com o texto legível */
  .plate--largo { display: none; }
  .plate--estreito { display: block; }

  /* mesma troca no leito: seis caixas lado a lado em 390px ficam com 55px
     cada, e o nome da venture não cabe */
  .leito--largo { display: none; }
  .leito--estreito { display: block; }

  /* mesmo problema nos rotores: lado a lado em 390px cada um fica com 110px
     e a frase cai para 22px. Empilhados, cada rotor ocupa a largura toda. */
  .rotores--largo { display: none; }
  .rotores--estreito { display: block; }

  .vgrade { grid-template-columns: minmax(0, 1fr); }

  /* a ficha deita: a foto vira faixa no topo e o texto rola abaixo dela.
     Em duas colunas nesta largura o nome da venture não cabe e corta. */
  .vficha {
    display: block;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .vficha__media { height: 38vh; }
  .vficha__texto { display: block; padding: clamp(28px, 7vw, 48px); }
  .vficha__nome { font-size: clamp(2rem, 9vw, 2.75rem); }

  /* o bloco da filosofia é onde o celular precisa impressionar mais, não
     menos: a escala do título de declaração não cai abaixo do desktop médio */
  .creed__title { font-size: clamp(1.625rem, 7vw, 2.125rem); }
  .creed { gap: clamp(56px, 14vw, 88px); }

  .crew__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }

  .waitlist__submit { justify-self: stretch; text-align: center; }

  .colophon__inner { flex-wrap: wrap; gap: 14px 24px; }
  .colophon__year { margin-left: auto; }
}


@media (max-width: 420px) {
  .crew__grid { grid-template-columns: minmax(0, 1fr); }
}
