/* =========================================================================
   GTE — site institucional
   Tokens: knowledge/publico/marca/ (paleta.md, tipografia.md, brand.tokens.json)
   Recorte do site: work/handover/03-design-system-site.md
   Regra dura: #0F3A55 é interface, nunca marca. O navy da marca é #0E1B29.
   ========================================================================= */

/* ---------- 1. Fontes (self-hosted, OFL) ---------------------------------- */

@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url('/assets/fonts/libre-franklin-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url('/assets/fonts/libre-franklin-var-latin-ext.woff2') format('woff2');
  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: 'Public Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/public-sans-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/public-sans-var-latin-ext.woff2') format('woff2');
  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: 'Public Sans';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/public-sans-var-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/public-sans-var-italic-latin-ext.woff2') format('woff2');
  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';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');
  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;
}

/* ---------- 2. Tokens ----------------------------------------------------- */

:root {
  color-scheme: light;

  /* superfícies e texto */
  --bg: #FBF9F5;
  --alt: #EDE7DC;
  --card: #FFFFFF;
  --ink: #1E1B16;
  --strong: #0E1B29;
  --sub: #4A5A67;
  --stroke: #D5DCE2;
  /* Fronteira de componente interativo (campo, botão-fantasma, botão da nav).
     O SC 1.4.11 pede 3:1 e o --stroke decorativo dá 1,38:1 sobre o branco do
     cartão -- com o campo tendo o mesmo fundo da página, não havia pista
     nenhuma de que ali era um campo. #83919C dá 3,23:1 sobre #FFFFFF e 3,07:1
     sobre o papel. O --stroke continua valendo para separação decorativa, que
     não é informação exigida. */
  --stroke-forte: #83919C;
  --campo-bg: #FFFFFF;

  /* ação e acento */
  --acao: #0F3A55;
  --link: #175982;
  --terra: #A8431F;
  --cobre: #C4794C;
  --teal: #33707F;
  --kicker: #A8431F;
  --logo: #0E1B29;
  --focus: #0F3A55;
  /* O fio: a assinatura estrutural da marca, o maior uso de terracota do site.
     Terracota dá 5,73:1 sobre o papel e 4,89:1 sobre a areia. Sobre navy ela
     cairia para 2,89:1, e por isso lá o fio vira cobre (5,12:1) -- a terracota
     assina, o cobre trabalha. */
  --fio: #A8431F;

  /* estados */
  --ok: #166534;
  --warn: #8F5300;
  --err: #A8332E;

  /* botão */
  --btn: #0F3A55;
  --btn-h: #0C2E44;
  --btn-txt: #FFFFFF;

  /* navy fixo — âncoras que são sempre escuras, em qualquer tema */
  --navy: #0E1B29;
  --navy-line: #22364A;
  --navy-ink: #C6CFD7;
  --navy-strong: #F7F8F6;

  /* tipo */
  --display: 'Libre Franklin', Georgia, serif;
  --corpo: 'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;

  /* medidas */
  --container: 1200px;
  --gutter: clamp(20px, 5vw, 48px);
  --nav-h: clamp(64px, 9vw, 91px);
  --r-sm: 8px;
  --r-md: 12px;

  /* Ritmo vertical. Antes havia um --sec-y só para tudo, e monotonia por token:
     com o fundo alternado morrendo, o espaço passa a ser o separador, então ele
     precisa ser maior entre seções e menor dentro delas. Escala 4/8. */
  /* O degrau a mais que o desbaste de 06/08 introduziu foi devolvido na mesma
     noite: com as dobras já curtas, ele virou meia tela de fundo entre uma
     afirmação e a seguinte. Menos rolagem vazia, sem voltar ao wall of text. */
  --y-sec: clamp(72px, 9vw, 112px);
  --y-densa: clamp(56px, 6vw, 72px);
  --y-abertura: clamp(48px, 6vw, 72px);
  --y-ancora: clamp(80px, 10vw, 128px);
  --sec-y: var(--y-sec);

  /* v2: ritmo interno de bloco. O --y-* governa o espaço ENTRE seções; faltava
     governar o que acontece dentro delas, onde tudo tinha os mesmos 20px e
     nada tinha hierarquia. Quando o bloco muda de textura (prosa para tela), o
     salto é maior. */
  --y-bloco: 40px;
  --y-tela: 16px;
  --col-txt: 26rem;   /* coluna de leitura ao lado de uma tela: ~52ch */

  /* motion. A assimetria é regra, não gosto: a entrada é mais lenta que a
     saída, porque o elemento que aparece precisa de mais tempo para ser
     localizado do que o que some. */
  --t-micro: 120ms;   /* hover, foco, sublinhado */
  --t-move: 200ms;    /* saída, moldura da tela, sombra da nav */
  --t-entra: 320ms;   /* entrada de bloco */
  --t-abre: 240ms;    /* disclosure e desenho do foco */
  --ease-out: cubic-bezier(.2, .7, .3, 1);
}

[data-theme='dark'] {
  color-scheme: dark;
  --bg: #0B1622;
  --alt: #16293B;
  --card: #16293B;
  --ink: #E7E4DD;
  --strong: #F7F8F6;
  --sub: #A9B6C1;
  --stroke: #2C4053;
  --stroke-forte: #607588; /* 3,11:1 sobre a superfície elevada #16293B */
  --campo-bg: #0B1622;
  --link: #85B4D4;
  /* terracota sobre #0B1622 dá 3,03:1, margem apertada demais para um fio de
     1px: no escuro o fio é cobre, 5,37:1 */
  --fio: #C4794C;
  /* cobre clareado: o #C4794C da marca dá 4,37:1 sobre a superfície elevada do
     tema escuro (#16293B). Como acento gráfico ele continua sendo o cobre; como
     TEXTO no escuro precisa deste degrau (4,94:1). */
  --kicker: #CB8459;
  --logo: #F7F8F6;
  --focus: #85B4D4;
  --ok: #79C094;
  --warn: #E0A94F;
  --err: #E39490;
  --btn: #2F6E96;
  --btn-h: #3B7FAA;
}

/* ---------- 3. Base ------------------------------------------------------- */

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

/* a regra [hidden] da folha do navegador só vale para elementos HTML: sem isto,
   os <svg> do botão de tema aparecem os dois ao mesmo tempo. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 8px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  /* a prova sangra até a borda direita (.sangra-d): sem isto o cálculo com vw
     abriria barra de rolagem horizontal na largura da própria barra */
  overflow-x: clip;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--corpo);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* app instalado: respeita entalhe e barra de gestos do aparelho */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

img, svg { max-width: 100%; }
img { height: auto; }

a {
  color: var(--link);
  text-decoration-color: color-mix(in srgb, var(--link) 40%, transparent);
  text-underline-offset: 3px;
  transition: text-decoration-color var(--t-micro) ease-out;
}
a:hover { text-decoration-color: var(--link); }

::selection { background: #0E1B29; color: #F7F8F6; }
[data-theme='dark'] ::selection { background: #F7F8F6; color: #0E1B29; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}
/* O rodapé e a âncora são sempre navy, em qualquer tema, mas o anel de foco
   herdava o `--focus` do tema claro (#0F3A55): 1,45:1 contra navy, ou seja,
   praticamente sem indicador para quem navega por teclado -- e são ~13 links
   por página. Branco da marca dá 16,33:1. */
.rodape :focus-visible,
.sec--navy :focus-visible { outline-color: var(--navy-strong); }

input, textarea, select, button { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--strong);
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; }

/* troca de tema sem piscar o layout */
.tswap, .tswap * {
  transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease !important;
}

/* `prefers-reduced-motion` não é interruptor geral: movimento sai, fade e cor
   ficam. O martelo universal que estava aqui (`transition-duration: .01ms` em
   `*`) zerava também o realce de moldura das telas, o sublinhado dos links, o
   hover dos botões e a transição de tema -- quem liga a preferência recebia uma
   interface que não dá sinal de ter respondido. A MDN chama isso de leitura
   preguiçosa da preferência; o correto é substituir movimento por alternativa
   calma. O que muda conteúdo sozinho (o autoplay do hero) para de vez, e isso é
   decidido no JS, onde a decisão é semântica. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* movimento sai */
  .js [data-reveal],
  .js [data-reveal-stagger] > * { transform: none !important; transition-delay: 0ms !important; }

  /* fade fica, e no tempo certo */
  .js [data-reveal] { transition: opacity var(--t-entra) ease-out !important; }

  /* o disclosure abre sem transição */
  .tela__leitura[open] > *:not(summary) { animation: none !important; }

  /* cor e borda ficam: hover, foco, links, tema, moldura da tela -- intocados */
}

/* ---------- 4. Utilitários de layout -------------------------------------- */

.wrap {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sec { padding-block: var(--sec-y); }
.sec--densa { padding-block: var(--y-densa); }
.sec--tight { padding-block: clamp(40px, 6vw, 64px); }
.sec--alt { background: var(--alt); }
.sec--card { background: var(--card); border-block: 1px solid var(--stroke); }

.sec--navy {
  background: var(--navy);
  border-top: 1px solid var(--navy-line);
  color: var(--navy-ink);
  padding-block: clamp(64px, 10vw, 96px);
}
.sec--navy h2, .sec--navy h3 { color: var(--navy-strong); }

.grid { display: grid; gap: 16px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 235px), 1fr)); }

/* .split resolvia sempre em duas colunas de 1fr, independente do conteúdo:
   quando um lado era curto, a outra metade virava buraco. As composições abaixo
   são todas assimétricas de propósito -- texto e prova nunca dividem a tela ao
   meio. Mantido só onde as duas colunas têm mesmo peso. */
.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
}
.split--top { align-items: start; }

/* Assimétrico: leitura larga contra coluna de apoio estreita. */
.duo {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}
/* invertido: a prova à esquerda, o texto à direita -- alterna o lado a cada
   bloco de produto para nenhum par de seções ter a mesma forma */
.duo--inv { grid-template-columns: minmax(0, 1fr) minmax(0, 1.55fr); }
@media (max-width: 820px) {
  /* minmax(0,1fr), não 1fr: `1fr` é `minmax(auto,1fr)`, e o mínimo de conteúdo
     de um filho -- o formulário, uma tabela, um mockup -- estoura o contêiner */
  .duo, .duo--inv { grid-template-columns: minmax(0, 1fr); }
  /* na coluna única o texto vem antes da prova, sempre */
  .duo--inv > :first-child { order: 2; }
}

/* Sangria: o filho estende a borda direita até o fim da viewport. Só a prova
   sangra; texto nunca.
   A margem percentual resolveria contra a coluna do grid, não contra o
   container, então a conta é explícita: a distância entre a borda de conteúdo
   do .wrap e a borda da viewport.
   E usa `cqw`, não `vw`: `100vw` inclui a barra de rolagem, e a prova passava
   8px além da borda. A seção vira contexto de contêiner, cuja largura já
   exclui a barra. Onde `cqw` não existir, a declaração inteira é descartada e
   a prova simplesmente não sangra -- degradação segura. */
.hero, .sec { container-type: inline-size; }
.sangra-d {
  margin-right: calc(-1 * max(var(--gutter), (100cqw - var(--container)) / 2 + var(--gutter)));
}
@media (max-width: 980px) { .sangra-d { margin-right: 0; } }

/* Regra fina de fechamento de bloco, na cor da assinatura. */
.fio {
  border: 0;
  border-top: 1px solid var(--fio);
  margin: 0;
  opacity: .55;
}

.stack { display: flex; flex-direction: column; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; }

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

/* ---------- 5. Tipografia aplicada ---------------------------------------- */

.kicker {
  font: 500 12px/1.4 var(--mono);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--kicker);
  margin: 0 0 16px;
}
.sec--navy .kicker { color: var(--cobre); }

/* Calibrada para a tagline longa do dono. A escala anterior (até 67px) foi
   feita para uma frase de cinco palavras e, com esta, quebrava uma palavra
   por linha e vazava por baixo da prova. */
.h-hero { font-size: clamp(30px, 3.4vw, 46px); }
.h-pag { font-size: clamp(34px, 4vw, 50px); }
.h-sec { font-size: clamp(28px, 3.2vw, 38px); }
.h-sub { font-size: clamp(22px, 2.4vw, 28px); }
.h-card { font-size: 20px; }
.h-card--sm { font-size: 17px; font-weight: 700; }

.lead {
  font-size: clamp(18px, 1.6vw, 21px);
  line-height: 1.6;
  max-width: 52ch;
}
.medida { max-width: 66ch; }
.medida--curta { max-width: 52ch; }
.medida--titulo { max-width: 20ch; }

/* Espaçamento por fluxo. Substitui as dezenas de `style="margin:24px 0 28px"`
   espalhadas pelas páginas -- que, além de fora da escala 4/8, morriam na CSP
   de produção. O ritmo interno é mais curto que o de antes: o kicker pertence
   ao título que vem logo abaixo. */
.fluxo > * + * { margin-top: 20px; }
.fluxo > .kicker + * { margin-top: 12px; }
.fluxo > * + .row,
.fluxo > * + .fluxo__gap { margin-top: 32px; }
.fluxo > * + .lead { margin-top: 24px; }
.fluxo .kicker { margin-bottom: 0; }
/* v2: quando o bloco seguinte muda de textura -- prosa para tela, prosa para
   prova, prosa para tira de passos -- o salto é maior que o de parágrafo. */
.fluxo > * + .tela,
.fluxo > * + .prova-b,
.fluxo > * + .numeros,
.fluxo > * + .passos { margin-top: var(--y-bloco); }

/* A frase-tese: substitui um parágrafo inteiro por uma sentença. Uma por
   página, no máximo. */
.frase {
  font: 800 clamp(22px, 2.4vw, 28px)/1.25 var(--display);
  letter-spacing: -0.01em;
  color: var(--strong);
  max-width: 24ch;
  margin: 0;
}
.apoio { font-size: 15px; line-height: 1.6; }
.legenda { font-size: 13px; line-height: 1.5; color: var(--sub); }
.dado { font-family: var(--mono); font-weight: 500; font-variant-numeric: tabular-nums; }

.nota-mono {
  font: 500 13px/1.6 var(--mono);
  color: var(--kicker);
}

/* ---------- 6. Botões e links de ação ------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 12px 28px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: var(--btn);
  color: var(--btn-txt);
  font: 600 15px var(--corpo);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--t-micro) ease-out;
}
.btn:hover { background: var(--btn-h); text-decoration: none; }
.btn:active { background: var(--btn-h); transform: translateY(1px); }
.btn:disabled,
.btn[aria-disabled='true'] { opacity: .55; cursor: not-allowed; transform: none; }

.btn--terra { background: var(--terra); color: #F7F8F6; }
.btn--terra:hover, .btn--terra:active { background: #8C3417; }

/* Na âncora navy o CTA trocava de regra sem perceber: terracota sobre navy dá
   2,89:1, abaixo do mínimo de 3:1 do SC 1.4.11 -- e é o mesmo par que
   `logo/uso.md` §4 já proíbe como elemento funcional ("a terracota assina, o
   cobre trabalha"). Cobre resolve o fundo (5,12:1), mas exige texto navy: com
   texto claro daria 3,19:1, abaixo do 4,5:1 exigido para texto. Assim os dois
   critérios passam com o mesmo 5,12:1. */
.sec--navy .btn--terra { background: var(--cobre); color: var(--navy); }
.sec--navy .btn--terra:hover,
.sec--navy .btn--terra:active { background: #D89264; }

.btn--ghost {
  background: transparent;
  border-color: var(--stroke-forte);
  color: var(--strong);
  min-height: 44px;
  padding: 10px 22px;
  font-size: 14px;
}
.btn--ghost:hover { background: transparent; border-color: var(--cobre); }
.btn--ghost:active { border-color: var(--cobre); transform: translateY(1px); }

/* Ação primária na nav: a navegação tem três destinos e uma ação. */
.btn--nav { min-height: 40px; padding: 8px 18px; font-size: 14px; }
@media (max-width: 859px) { .btn--nav { display: none; } }

.acao {
  display: inline-block;
  font: 600 15px var(--corpo);
  color: var(--link);
  text-decoration: none;
  padding-block: 4px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left calc(100% - 2px);
  background-size: 0% 1.5px;
  transition: background-size var(--t-micro) ease-out;
}
.acao:hover { background-size: 100% 1.5px; text-decoration: none; }
.acao--sm { font-size: 14px; }

/* ---------- 7. Nav -------------------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 10px;
  z-index: 200;
  background: var(--card);
  color: var(--link);
  padding: 10px 16px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-sm);
  font: 600 14px var(--corpo);
  text-decoration: none;
}
.skip:focus { left: 16px; }

/* A nav não some ao rolar para baixo nem reaparece ao rolar para cima, e
   `height` nunca é animado: só `box-shadow`, que o compositor resolve sem
   reflow e sem contar para o CLS. */
.nav {
  position: sticky;
  top: 0;
  z-index: 80;
  background: var(--bg);
  border-bottom: 1px solid var(--cobre);
  transition: box-shadow 180ms ease-out;
}
.nav[data-scrolled] { box-shadow: 0 1px 0 0 color-mix(in srgb, var(--cobre) 45%, transparent); }

.nav__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--nav-h);
}

.nav__marca { display: flex; align-items: center; text-decoration: none; }
/* Duas versões canônicas em vez de recolorir os paths: a marca só existe nas
   cores dela, e a troca de tema escolhe o arquivo certo. */
.nav__marca-img { display: block; height: 48px; width: auto; }
.nav__marca-img--escuro { display: none; }
[data-theme='dark'] .nav__marca-img--claro { display: none; }
[data-theme='dark'] .nav__marca-img--escuro { display: block; }

.nav__dir { display: flex; align-items: center; gap: clamp(10px, 2vw, 28px); }

.nav__links { display: flex; gap: clamp(14px, 2.4vw, 32px); align-items: center; }

.nav__link {
  font: 600 15px var(--corpo);
  color: var(--ink);
  text-decoration: none;
  padding-block: 6px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left calc(100% - 2px);
  background-size: 0% 1.5px;
  transition: background-size var(--t-micro) ease-out, color var(--t-micro) ease-out;
}
.nav__link:hover { background-size: 100% 1.5px; color: var(--strong); text-decoration: none; }
.nav__link[aria-current='page'] { color: var(--strong); background-size: 100% 1.5px; }

.nav__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--stroke-forte);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--strong);
  cursor: pointer;
  transition: border-color var(--t-micro) ease-out;
}
.nav__btn:hover, .nav__btn:active { border-color: var(--cobre); }

.nav__hamb { flex-direction: column; gap: 4px; }
.nav__hamb span { display: block; width: 18px; height: 2px; background: currentColor; }

/* Menu de celular: painel cheio abaixo da barra, com alvos de 56px. Em app
   instalado a nav fica colada ao topo da tela, então o painel tem rolagem
   própria e respeita a área segura do aparelho. */
.nav__mobile {
  display: none;
  flex-direction: column;
  border-top: 1px solid var(--stroke);
  background: var(--bg);
  padding: 4px var(--gutter) calc(16px + env(safe-area-inset-bottom));
  max-height: calc(100dvh - var(--nav-h));
  overflow-y: auto;
  overscroll-behavior: contain;
}
.nav__mobile[data-open] { display: flex; }
.nav__mobile a {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 8px 0;
  font: 600 17px var(--corpo);
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--stroke);
}
.nav__mobile a[aria-current='page'] { color: var(--strong); }
.nav__mobile a:last-child {
  border-bottom: 0;
  margin-top: 12px;
  justify-content: center;
  background: var(--btn);
  color: var(--btn-txt);
  border-radius: var(--r-sm);
}

.nav__hamb { display: none; }

@media (max-width: 859px) {
  .nav__links { display: none; }
  .nav__hamb { display: flex; }

  /* sem JS o hambúrguer não abre nada: os links voltam, quebrando em linha */
  html:not(.js) .nav__bar { flex-wrap: wrap; height: auto; padding-block: 12px; }
  html:not(.js) .nav__links { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 14px; }
  html:not(.js) .nav__hamb { display: none; }
}

/* sem JS o botão de tema fica visível e inerte (não tem handler nem href):
   some, como o hambúrguer */
html:not(.js) [data-tema-toggle] { display: none; }

/* ---------- 8. Cartões e blocos ------------------------------------------- */

.card {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.card--rascunho { border-style: dashed; }
.card p { font-size: 15px; line-height: 1.6; }
.card .h-card, .card .h-card--sm { margin: 0; }
/* kicker de duas linhas não pode desalinhar os títulos da fileira */
.grid--4 .card > .kicker { min-height: 2.8em; display: flex; align-items: flex-start; }

.selo {
  display: inline-block;
  font: 500 13px var(--mono);
  color: var(--kicker);
  border: 1.5px solid var(--kicker);
  border-radius: 6px;
  padding: 9px 16px;
}

/* display:flex, não inline-flex: precisa ocupar a própria linha, senão o CTA
   seguinte sobe para o lado dela na âncora navy. */
.faixa-prova {
  /* cabe em uma linha na maioria das larguras; onde não couber, quebra no
     ponto separador e não no meio do rótulo */
  font-size: clamp(11px, 1vw, 12px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font: 500 12px/1.5 var(--mono);
  letter-spacing: 0.6px;
  color: var(--kicker);
  margin: 0 0 20px;
}
.faixa-prova .ponto { color: var(--cobre); }
.sec--navy .faixa-prova { color: var(--cobre); }

.ilha {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: clamp(20px, 3.5vw, 32px);
  display: flex;
  flex-wrap: wrap;
  gap: 24px 40px;
  align-items: center;
}
/* Marca da FAPERJ, dos arquivos oficiais de `faperj.br/?id=26.5.2`: as versões
   com alfa, vinho para fundo claro e branca para fundo escuro. Isso dispensa a
   placa branca que a versão anterior precisava por não ter transparência, e a
   marca entra intacta, sem recolorir e sem efeito. Manual oficial arquivado em
   `projetos/editais-faperj/2026-centelha/00-inbox/projeto-clavia/logo_FAPERJ/`. */
.ilha__marca {
  flex: none;
  width: min(230px, 60vw);
  display: flex;
  align-items: center;
}
/* a regra de tamanho tem de morar na MESMA classe da regra de tema: com
   `.ilha__marca img` a especificidade era maior e o `display:none` da versão
   escura perdia, então as duas apareciam juntas no tema claro */
.marca-terceiro { width: 100%; height: auto; display: block; }
.marca-terceiro--escuro { display: none; }
[data-theme='dark'] .marca-terceiro--claro { display: none; }
[data-theme='dark'] .marca-terceiro--escuro { display: block; }

/* ---------- Wordmarks de produto ------------------------------------------

   Logo de produto = wordmark própria + ponto terracota, e os SVGs já vêm
   assim: nunca recriar, recolorir, rotacionar nem aplicar efeito. Arquivo
   referenciado por caminho, nunca inline.

   TAMANHO MÍNIMO, e é regra dura: 80px de TINTA, não de caixa. A tinta do
   SIFRE ocupa 0,8383 da largura da viewBox (medido por achatamento das curvas
   em `logo/produtos/`), e ele é o caso que amarra: 3:1 de proporção contra
   3,29:1 da ClavIA e 4,63:1 da CadêncIA. Dimensionando por ALTURA -- que é o
   que iguala opticamente três nomes de comprimentos muito diferentes --, a
   tinta do SIFRE dá 2,515 × a altura da caixa. Daí o piso de 34px de altura:
   85px de tinta, com folga sobre os 80.

   ÁREA DE PROTEÇÃO: a altura da letra inicial. No SIFRE a tinta ocupa 0,491 da
   altura da caixa, então a 48px de caixa a inicial tem ~24px, e o respiro
   abaixo é maior que isso em todos os usos.

   A HarmonIA não tem wordmark ainda e segue como texto com o ponto em CSS. */
.marca-produto { display: block; width: auto; }
.marca-produto--escuro { display: none; }
[data-theme='dark'] .marca-produto--claro { display: none; }
[data-theme='dark'] .marca-produto--escuro { display: block; }

/* Assinatura no topo da página de produto. O h1 continua sendo texto. */
.marca-produto--pagina { height: clamp(38px, 5vw, 56px); margin-bottom: 36px; }

/* Entrada de produto em /projetos/, no lugar do kicker. A 42px de caixa a
   inicial do SIFRE tem ~20,6px, então o respiro abaixo é 24. */
.marca-produto--entrada { height: clamp(34px, 3.4vw, 42px); margin-bottom: 24px; }

/* Bloco da pauta. O teto é 40px, e não 48, por causa da área de proteção: a
   40px a inicial do SIFRE tem 19,6px. O respiro é 26px porque quem amarra é a
   CadêncIA: o circunflexo do Ê leva a tinta a 24,9px de altura, e a área de
   proteção se mede pela tinta mais alta, não pela mais provável. A tinta a
   34px ainda dá 85px de largura, acima do mínimo de 80. */
.pauta__nome .marca-produto { height: clamp(34px, 3vw, 40px); }
/* Classe estática, e não `:has()`: a pauta reescreve atributos nos
   ancestrais destes elementos a cada frame de rolagem, e um seletor
   relacional nessa posição obriga a reavaliar a subárvore inteira por
   frame. Foi o que travou a home. */
.pauta__nome--marca { line-height: 0; margin-block: 26px; }
.pauta__nome--marca + .pauta__txt { margin-top: 0; }

/* Selo de fomento em linha, para o hero e para blocos de destaque. */
.fomento {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
.fomento__placa { flex: none; width: 132px; }
.fomento__txt { font: 500 12px/1.5 var(--mono); letter-spacing: .4px; color: var(--kicker); margin: 0; max-width: 34ch; }
.sec--navy .fomento__txt { color: var(--cobre); }
.ilha__txt { flex: 1 1 300px; }
.ilha--pos { margin-top: clamp(32px, 4vw, 48px); }

.citacao {
  border-left: 2px solid var(--cobre);
  padding-left: clamp(20px, 3vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 68ch;
  font-size: clamp(17px, 1.4vw, 19px);
  line-height: 1.7;
}

.prosa { max-width: 72ch; }
.prosa h2 { font-size: 24px; margin: 0 0 12px; }
.prosa p, .prosa ul, .prosa ol { margin: 0 0 28px; line-height: 1.7; }
.prosa ul, .prosa ol { padding-left: 22px; display: flex; flex-direction: column; gap: 10px; }
.prosa ul li, .prosa ol li { margin: 0; }
.prosa strong { color: var(--strong); }
.prosa .caixa {
  padding: 16px 20px;
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  font-size: 14px;
  color: var(--sub);
  margin: 0;
}

.tabela-simples {
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  overflow: hidden;
  margin: 0 0 28px;
}
.tabela-simples table { width: 100%; border-collapse: collapse; background: var(--card); }
.tabela-simples th, .tabela-simples td {
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid var(--stroke);
  font-size: 14px;
  line-height: 1.5;
  vertical-align: top;
}
.tabela-simples th {
  font: 500 11px var(--mono);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--sub);
}
.tabela-simples tbody tr:last-child td { border-bottom: none; }
.tabela-simples td:first-child { font: 500 13px var(--mono); color: var(--strong); }

/* ---------- 9. Hero e símbolo --------------------------------------------- */

/* Hero da home: texto numa coluna de leitura e a prova ocupando o resto até
   sangrar pela borda direita. Assimétrico de propósito -- 50/50 era o que
   produzia meia tela vazia. */
.hero { padding-block: clamp(44px, 6vw, 72px) clamp(56px, 7vw, 88px); }
.hero__grade {
  display: grid;
  /* Coluna de texto fluida e mais larga que a prova: a de 440px fixos era
     estreita demais para a tagline longa. */
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(28px, 3.5vw, 48px);
  align-items: center;
}
@media (max-width: 980px) {
  .hero__grade { grid-template-columns: 1fr; }
}
.hero__txt { max-width: 640px; min-width: 0; }

/* A prova, em tamanho de prova. Antes o painel vivia a 84% de metade da tela,
   com um celular por cima cortando o gráfico. */
.prova { min-width: 0; }
/* um fone sozinho numa coluna larga fica órfão encostado à esquerda */
.prova--centro { display: flex; justify-content: center; }

/* O par do hero: a chamada na mão do professor e o painel que a secretaria lê,
   o mesmo dado nas duas pontas. O celular vem primeiro porque é onde o dado
   nasce, e é ele que carrega a troca viva.
   Abaixo de 700px o painel desce para baixo do fone e vira silhueta: a
   legenda e a leitura em texto continuam entregando o conteúdo. */
.par-hero {
  display: grid;
  /* O fone em fração, não em pixels fixos: com 260px travados, o painel
     ficava com o resto e encolhia até virar miniatura ao lado do celular.
     Agora os dois dividem a coluna em proporção e o painel manda. */
  grid-template-columns: minmax(0, 0.58fr) minmax(0, 1fr);
  gap: clamp(16px, 2vw, 28px);
  align-items: center;
  width: 100%;
}
.par-hero > .tela--fone { width: 100%; }
@media (max-width: 700px) {
  .par-hero { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .par-hero > .tela--fone { width: min(100%, 260px); }
  .par-hero > .tela--painel { width: 100%; }
}

/* A órbita saiu: ela embutia os paths da marca no HTML com cor própria e os
   girava indefinidamente, o que `logo/uso.md` §5.3 e §5.8 proíbem, o
   `02-motion-ux.md` proíbe de novo (logo animada, autoplay) e a revalidação já
   tinha decidido em gate ("logo estática"). O espaço foi para a prova. */

/* Abertura das páginas internas: leitura à esquerda, ficha à direita, uma regra
   fina fechando o bloco. Um padrão só para as seis páginas. */
.abertura { padding-block: var(--y-abertura) 0; }
.abertura__fio { margin-top: clamp(32px, 4vw, 48px); }

/* ---------- 9a. A pauta --------------------------------------------------- */

/* O eixo-síntese da marca, retomado de `agentes-mkt-design` (direcao-de-arte.md
   §2, "a LINHA DE PAUTA"). Uma forma só carregando quatro leituras verdadeiras
   ao mesmo tempo: a pauta onde a música se escreve, o caderno pautado da escola
   pública, a pauta da chamada que o professor preenche todo dia, e cada aluno
   como uma nota visível na linha.
   Guardrails do gate de 21/07 ("muito sutil, quase imperceptível"): sem clave,
   sem glifo de nota, sem instrumento. Os nós são os mesmos círculos do resto do
   sistema. E a palavra "compasso" não entra -- é nome interno proibido em peça
   pública, e foi o que derrubou a tagline anterior por leitura-associação.

   MOTION, NOTA DE GOVERNANÇA: `02-motion-ux.md` §2 reserva UM espetáculo, e o
   escolhido lá era o eixo do ciclo. A pauta viva é exceção sancionada pelo
   dono em 05/08 ("o ponto laranja vai pulando de nota") e reafirmada por ele
   ao ver a v2 sem ela. O site fica com dois elementos vivos, e só dois: esta
   pauta e a troca de tela do hero. O trilho do ciclo continua parado. */

/* A seção inteira cabe numa tela: o bloco fica preso enquanto a rolagem só
   move o ponto. Texto, pauta e os quatro produtos ficam visíveis o tempo todo,
   e o que muda é qual deles está em destaque. */
/* 100vh de curso, não 200: meia tela de rolagem por produto fazia a página
   parecer travada, que é de onde vinha a leitura de rolagem sequestrada. */
/* 140vh, não 200: dois screenfuls inteiros numa seção só é caro demais para a
   informação entregue, e o orçamento de atenção manda hero, pauta e a primeira
   prova caberem nos três primeiros. Continua sendo `sticky` com avanço linear,
   então a barra de rolagem mantém a relação normal com a entrada. */
.pauta-sec { position: relative; min-height: calc(100vh + 20vh); }
.pauta-sec__fixo {
  position: sticky;
  top: var(--nav-h);
  min-height: calc(100vh - var(--nav-h));
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(20px, 3vh, 40px);
  overflow: hidden;
}
.pauta-sec__fixo > .wrap { width: 100%; }

.pauta { margin-top: clamp(20px, 3vh, 36px); }
.pauta__palco { position: relative; }
/* os blocos moram numa faixa própria logo abaixo do pentagrama, e cada um se
   alinha com a haste da sua nota */
.pauta__blocos { position: relative; min-height: clamp(196px, 26vh, 236px); margin-top: 14px; }
.pauta__palco svg { display: block; width: 100%; height: auto; overflow: visible; }

.pauta__linha { stroke: var(--stroke); stroke-width: 1.5; }
/* As notas são cabeças vazias na pauta. Quem já foi tocado fica com o contorno
   da marca; quem ainda não, cinza. */
.pauta__no {
  fill: var(--bg);
  stroke: var(--stroke-forte);
  stroke-width: 2.5;
  transition: stroke 220ms var(--ease-out);
}
.sec--alt .pauta__no { fill: var(--alt); }
.pauta__no[data-on] { stroke: var(--fio); }

/* O ponto PULA de nota em nota, não desliza nem só pinta. O easing de chegada
   (back-out) dá o assentamento de quem pousou na nota em vez de escorregar até
   ela, e só transform é animado. */
.pauta__ponto {
  fill: var(--fio);
  transform: translate(var(--nx, 230px), var(--ny, 165px));
  transition: transform 480ms cubic-bezier(.34, 1.42, .64, 1);
}
@media (prefers-reduced-motion: reduce) {
  .pauta__ponto { transition: none; }
}

/* os blocos de produto, ancorados na posição da própria nota */
/* Nada de apagar texto por opacidade: os quatro produtos ficam legíveis o tempo
   todo (contraste é requisito, não estado), e o destaque vem da cor do nome e
   do nó aceso. */
.pauta__rot {
  position: absolute;
  width: min(21ch, 26%);
  transform: translate(-50%, 0);
}
/* Todos os blocos numa faixa só, logo abaixo do pentagrama, cada um alinhado
   com a haste da sua nota. Antes eles ficavam ancorados na altura da própria
   nota e colidiam com as linhas e entre si. */
/* o bloco em destaque cresce um degrau, ancorado no topo para não empurrar os
   vizinhos nem sair da linha da haste */
.pauta__rot {
  top: 0;
  width: min(21ch, 22%);
  transform-origin: top center;
  transition: transform 300ms var(--ease-out);
}
.pauta__rot[data-on] { transform: translate(-50%, 0) scale(1.07); }

/* o ponto terracota que assina cada produto, como na wordmark da GTE: aparece
   quando o ponto da pauta chega naquela nota */
.pauta__ponto-nome {
  color: var(--fio);
  opacity: 0;
  transition: opacity 300ms var(--ease-out);
}
.pauta__rot[data-on] .pauta__ponto-nome,
.pauta__rot[data-tocado] .pauta__ponto-nome { opacity: 1; }
.pauta__rot--a { left: 19.2%; }
.pauta__rot--b { left: 40.8%; }
.pauta__rot--c { left: 61.7%; }
.pauta__rot--d { left: 84.2%; }

/* O símbolo abre a pauta, onde a clave abriria o pentagrama. Grande e por cima
   das linhas, que passam por trás: a pauta sai da marca em vez de ficar ao lado
   dela. */
.pauta__marca {
  position: absolute;
  left: -1.5%;
  top: 50%;
  width: 15%;
  height: auto;
  transform: translateY(-50%);
  z-index: 1;
}
.pauta__marca--escuro { display: none; }
[data-theme='dark'] .pauta__marca--claro { display: none; }
[data-theme='dark'] .pauta__marca--escuro { display: block; }

.pauta__quem { font: 500 10px var(--mono); letter-spacing: 1.1px; text-transform: uppercase; color: var(--sub); margin: 0 0 4px; transition: color 220ms var(--ease-out); }
.pauta__rot[data-on] .pauta__quem { color: var(--kicker); }
.pauta__nome {
  font: 800 clamp(19px, 2vw, 26px) var(--display);
  letter-spacing: -0.01em;
  color: var(--sub);
  margin: 0;
  transition: color 220ms var(--ease-out);
}
.pauta__rot[data-on] .pauta__nome { color: var(--strong); }
.pauta__txt { font-size: 14px; line-height: 1.45; color: var(--sub); margin: 6px 0 0; }
.pauta__fim { margin-top: 8px; }
.pauta__breve { font: 500 11px var(--mono); letter-spacing: .6px; color: var(--sub); }

/* Celular: a pauta fica de pé e os MESMOS blocos viram lista -- nada de
   conteúdo duplicado no DOM para leitor de tela ler duas vezes. O trilho
   vertical e o fio avançando são o vocabulário já usado no ciclo. */
/* Quem pede menos movimento herdava o pior dos dois mundos: a animação
   desligada e ainda 200vh de rolagem inerte, porque só o breakpoint de celular
   colapsava a seção presa. Agora o modo lista vale para os dois casos. */
@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  /* celular: nada de seção presa, a pauta vira lista e a página rola normal */
  .pauta-sec { min-height: 0; }
  .pauta-sec__fixo {
    position: static;
    min-height: 0;
    overflow: visible;
    padding-block: var(--y-sec);
  }
  .pauta { padding-bottom: 0; }
  .pauta__palco { display: none; }
  .pauta__blocos {
    position: relative;
    display: grid;
    padding-left: 44px;
  }
  .pauta__trilho-v, .pauta__arco-v {
    position: absolute;
    left: 12px;
    top: 18px;
    width: 2px;
    border-radius: 1px;
  }
  .pauta__trilho-v { bottom: 18px; background: var(--stroke); }
  .pauta__arco-v { height: 100%; transform: scaleY(var(--n, 0)); transform-origin: center top; background: var(--fio); }
  .pauta__rot {
    position: static;
    width: auto;
    transform: none;
    opacity: 1;
    padding: 16px 0;
  }
  .pauta__rot--acima { transform: none; }
  /* O card ativo herdava o translate(-50%) do layout absoluto desktop (a regra
     [data-on] de fora da media query vence por especificidade) e saía meio
     viewport à esquerda no celular — cada produto quebrava na sua vez, e no
     reduced-motion os quatro de uma vez. Revisão em painel, 10/08. */
  .pauta__rot[data-on] { transform: none; }
  .pauta__rot::before {
    content: '';
    position: absolute;
    left: 6px;
    margin-top: 6px;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--bg);
    border: 2.5px solid var(--stroke-forte);
    transition: background-color 220ms var(--ease-out), border-color 220ms var(--ease-out);
  }
  .sec--alt .pauta__rot::before { background: var(--alt); }
  .pauta__rot[data-on]::before { background: var(--fio); border-color: var(--fio); }
}
@media (min-width: 901px) {
  .pauta__trilho-v, .pauta__arco-v { display: none; }
}

/* ---------- 10. Eixo do ciclo --------------------------------------------- */

/* v2: o trilho do ciclo virou rótulo, não espetáculo. Antes ele nascia
   interrompido e o fio da marca fechava as lacunas ao longo da rolagem, para
   dizer em movimento que existe um vão entre um sistema e outro. Na v2 as
   seções de tela acima já mostraram o vão fechado -- o mesmo dado saindo da
   mão da professora e chegando ao painel da rede --, então o trilho só nomeia
   as seis partes, fechado e parado. É também o que devolve a contagem de
   motion ao "um espetáculo" que `02-motion-ux.md` §2 sempre pediu.

   Seis etapas na horizontal; no celular o mesmo objeto vira vertical, sem
   mudar o vocabulário. */
.eixo__campo { margin-top: clamp(36px, 5vw, 56px); }
/* o fecho da seção do ciclo, onde entra "para quem" sem virar seção própria */
.eixo__fecho { margin: clamp(44px, 6vw, 72px) 0 clamp(28px, 3.5vw, 40px); }
.eixo {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 34px 0 0;
  counter-reset: etapa;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 24px);
}
.eixo__trilho,
.eixo__arco {
  position: absolute;
  left: 0;
  top: 12px;
  height: 2px;
  border-radius: 1px;
}
.eixo__trilho {
  right: 0;
  /* o vão, visível: 26px de traço, 12px de nada */
  background-image: repeating-linear-gradient(to right, var(--stroke) 0 26px, transparent 26px 38px);
}
/* `scaleX`, não `width`: o fio avança a cada frame de rolagem, e largura
   animada obriga reflow e conta para o CLS. */
.eixo__arco {
  width: 100%;
  transform: scaleX(var(--n, 0));
  transform-origin: left center;
  background: var(--fio);
}

.eixo__etapa {
  counter-increment: etapa;
  position: relative;
  padding-top: 30px;
}
.eixo__etapa::before {
  content: counter(etapa, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1.5px solid var(--stroke-forte);
  background: var(--bg);
  color: var(--sub);
  font: 500 10px var(--mono);
  letter-spacing: .5px;
  transition: color 200ms ease-out, background-color 200ms ease-out, border-color 200ms ease-out;
}
.sec--alt .eixo__etapa::before { background: var(--alt); }
.eixo__etapa[data-on]::before {
  background: var(--fio);
  border-color: var(--fio);
  color: var(--bg);
}
[data-theme='dark'] .eixo__etapa[data-on]::before { color: var(--navy); }

.eixo__nome {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--strong);
  margin: 0;
}

/* celular e tablet estreito: o mesmo trilho, de pé */
@media (max-width: 860px) {
  .eixo {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    padding: 0 0 0 44px;
  }
  .eixo__trilho, .eixo__arco {
    left: 12px;
    top: 14px;
    width: 2px;
    height: auto;
  }
  .eixo__trilho {
    right: auto;
    bottom: 14px;
    background-image: repeating-linear-gradient(to bottom, var(--stroke) 0 20px, transparent 20px 30px);
  }
  .eixo__arco { bottom: auto; width: 2px; height: 100%; transform: scaleY(var(--n, 0)); transform-origin: center top; }
  .eixo__etapa { padding: 12px 0; }
  .eixo__etapa::before { left: -44px; top: 12px; }
  .eixo__nome { font-size: 19px; }
  }

/* Sem movimento, o ciclo nasce fechado: a informação é o trilho inteiro, não
   a viagem até ele. */
/* Sem travessia (celular deitado, janela baixa), o fio se desenha uma vez na
   entrada, em 560ms, em vez de ficar parado num trilho interrompido. */
.eixo__campo[data-anel-auto] .eixo__arco { transition: transform 560ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  .eixo__arco { transform: none !important; }
  .eixo__campo[data-anel-auto] .eixo__arco { transition: none; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 860px) {
  .eixo__arco { width: 2px !important; height: 100% !important; }
}

/* ---------- 10b. Ficha, portfólio e colunas -------------------------------- */

/* A ficha resolve o vazio da abertura das internas com informação, não com
   decoração: seis páginas abriam idênticas, com metade do container ociosa. */
.ficha {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--stroke);
}
.ficha div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--stroke);
  font: 500 13px var(--mono);
}
.ficha dt { color: var(--sub); letter-spacing: .4px; }
.ficha dd { margin: 0; color: var(--strong); text-align: right; }
/* alvo de 24px do SC 2.5.8: numa lista de definição o link não é "link em meio
   a texto corrido", então a isenção de alvo em linha não vale aqui */
.ficha a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--link);
  overflow-wrap: anywhere;
}

/* cabeçalho das páginas legais e utilitárias */
.legal__data {
  font-family: var(--mono);
  font-weight: 500;
  margin: 12px 0 36px;
}
.legal h1 { margin-bottom: 0; }
.legal__abre { font-size: clamp(17px, 1.4vw, 19px); }
.prosa code { font: 500 14px var(--mono); }
.prosa .caixa--pos { margin-top: 32px; }
.wrap--estreito { max-width: 64ch; }

.kit--pos { margin-top: clamp(24px, 3vw, 32px); }
.tabela-simples--pos { margin-top: clamp(28px, 3.5vw, 40px); max-width: 860px; }

/* Portfólio em linhas. Substitui a primeira das duas grades de quatro cartões
   idênticos: linhas contra colunas, para que duas seções seguidas nunca tenham
   a mesma forma. */
.portfolio { border-top: 1px solid var(--stroke); }
.portfolio__linha {
  display: grid;
  grid-template-columns: 44px minmax(0, 210px) minmax(0, 1fr) auto;
  gap: 8px 24px;
  align-items: baseline;
  padding: clamp(18px, 2.2vw, 26px) 0;
  border-bottom: 1px solid var(--stroke);
}
.portfolio__i { font: 500 11px var(--mono); color: var(--sub); letter-spacing: .5px; }
.portfolio__nome { font: 800 clamp(19px, 1.8vw, 23px) var(--display); letter-spacing: -0.01em; color: var(--strong); margin: 0; }
.portfolio__quem { display: block; font: 500 11px var(--mono); letter-spacing: 1px; text-transform: uppercase; color: var(--kicker); margin-bottom: 4px; }
.portfolio__txt { margin: 0; font-size: 15px; line-height: 1.55; color: var(--sub); }
.portfolio__fim { justify-self: end; white-space: nowrap; }
.portfolio__breve { font: 500 12px var(--mono); color: var(--sub); }
@media (max-width: 760px) {
  .portfolio__linha { grid-template-columns: 36px minmax(0, 1fr); }
  .portfolio__fim { grid-column: 2; justify-self: start; }
  .portfolio__txt { grid-column: 2; }
}

/* Colunas com regra superior, sem caixa. Substitui a segunda grade de cartões. */
.colunas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: clamp(20px, 2.6vw, 32px);
}
.colunas > * { border-top: 2px solid var(--fio); padding-top: 14px; }
.colunas h3 { font-size: 17px; font-weight: 700; margin: 0 0 8px; }
.colunas p { font-size: 15px; line-height: 1.55; color: var(--sub); margin: 0; }
.colunas--pos { margin-top: clamp(28px, 3.5vw, 40px); }

/* Cabeçalho de seção que abre uma grade de colunas: a medida curta deixava o
   título ocupando um terço da largura com o resto vazio à direita, e a régua
   fina alinha o bloco de texto com a primeira coluna que vem abaixo. */
.abre-colunas { max-width: 46ch; }
.abre-colunas + .colunas { margin-top: clamp(20px, 2.4vw, 28px); }
/* frente sem prova ainda: a regra do topo perde a cor da assinatura */

.legenda--pe { margin-top: 20px; }

/* ---------- 11. Telas de produto (capturas reais) ------------------------- */

/* A imagem É a tela. O site nunca redesenha a UI do produto.
   O que estava aqui antes eram ~370 linhas de mockup desenhado à mão: celular
   a 232px (0,54x do aparelho), corpo de 10px, rótulos de 8px, e dados
   fictícios que divergiam dos do próprio produto -- a home dizia "AÇÕES DA
   SEMANA 12" e a tela real diz "MUDARAM DE PADRÃO 12". Existiam duas redes
   fictícias, e a do site era a pior. Agora existe uma só.

   O HTML do site entra apenas como camada de anotação em volta e por cima da
   imagem: chapéu com o nome da tela, selo de dado ilustrativo, legenda,
   retângulo de foco e a leitura em texto. Nada dentro do retângulo do produto
   é desenhado pelo site.

   As telas não trocam de tema: são "telas acesas" dentro da página, não
   superfícies do site. Com captura, a regra deixa de depender de disciplina e
   passa a ser literal. */
.tela {
  --tela-bezel: #0E1B29;
  --tela-contorno: transparent;   /* só o tema escuro liga */
  --tela-chrome: #EFF2F4;
  --tela-chrome-ink: #0E1B29;     /* 15,47:1 sobre o chrome */
  --tela-chrome-fraco: #5B6771;   /* 5,15:1 sobre o chrome */
  --tela-borda: #D5DCE2;
  margin: 0;
  min-width: 0;
}
/* No escuro o bezel navy (#0E1B29) fica a 1,05:1 contra o fundo (#0B1622):
   a moldura do celular simplesmente não existe para quem usa o tema escuro.
   Um contorno de 1px devolve a fronteira -- 3,82:1 contra o fundo e 3,64:1
   contra o próprio bezel. Não é opcional. */
[data-theme='dark'] .tela { --tela-contorno: #607588; }

/* O chapéu é <div>, nunca <figcaption>: <figure> só admite um figcaption, e
   ele fica reservado para a legenda de baixo, que é a que carrega significado. */
.tela__chapeu {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--tela-chrome);
  border: 1px solid var(--tela-borda);
  border-bottom: 0;
  border-radius: 12px 12px 0 0;
  font: 600 12px/1.4 var(--corpo);
  color: var(--tela-chrome-ink);
}
/* o ponto da marca abre a barra, como abre a wordmark */
.tela__chapeu::before {
  content: '';
  flex: none;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--terra);       /* 5,36:1 sobre o chrome */
}
/* O selo é desenhado pelo site, fora da imagem, por medida: dentro da captura
   o rótulo "rede fictícia" está em mono de 11px, e um painel de 1280px exibido
   numa coluna de 720px o renderiza a 6,2px. Nas telas de celular ele nem
   existe. O guardrail não pode depender do zoom do visitante. */
.tela__selo {
  margin-left: auto;
  font: 500 11px var(--mono);
  letter-spacing: .4px;
  color: var(--tela-chrome-fraco);
}

.tela__vidro {
  position: relative;
  border: 1px solid var(--tela-borda);
  border-radius: 0 0 12px 12px;
  overflow: hidden;
  background: #FFFFFF;
}
.tela__vidro img { display: block; width: 100%; height: auto; }

/* As duas capturas do hero ficam empilhadas na mesma célula de grade, e o que
   muda é a opacidade. Assimetria proposital: a que entra leva 240ms, a que sai
   200ms, sobrepostas. O quadro não desliza, não escala e não gira. */
.tela__vidro--troca { display: grid; }
.tela__vidro--troca > img {
  grid-area: 1 / 1;
  transition: opacity var(--t-abre) ease-out;
}
.tela__vidro--troca > img[data-troca-off] {
  opacity: 0;
  transition-duration: var(--t-move);
}

/* Micro-interação: a tela reage ao ponteiro por TOM e BORDA, nunca por sombra
   flutuante nem por escala. O DS do site manda elevação por borda e tom, e uma
   captura que cresce no hover viraria estética de portfólio. */
.tela__chapeu,
.tela__vidro { transition: border-color var(--t-move) ease-out, background-color var(--t-move) ease-out; }
.tela:hover .tela__chapeu,
.tela:hover .tela__vidro,
.tela:focus-within .tela__chapeu,
.tela:focus-within .tela__vidro { border-color: var(--stroke-forte); }
.tela:hover .tela__chapeu,
.tela:focus-within .tela__chapeu { background: #E4E9ED; }

/* Painel: largura da coluna, sem teto próprio. */
.tela--painel { width: 100%; }

/* Fone: o bezel É a borda, e o raio interno cai dos 32 menos os 8 de borda.
   Sem chapéu de propósito -- um aparelho de celular com barra de navegador em
   cima é mentira visual. */
.tela--fone { width: clamp(240px, 26vw, 300px); }
.tela--fone .tela__vidro {
  border: 8px solid var(--tela-bezel);
  outline: 1px solid var(--tela-contorno);
  border-radius: 32px;
  /* Proporção de aparelho real (390×844): decisão do dono, 07/08 ("mockup de
     celular real"). A captura ancora no topo e o restante da tela fica na cor
     de fundo do app — sem recapturar, sem distorcer. */
  aspect-ratio: 390 / 844;
  overflow: hidden;
  background: #F7F8F6;
}
.tela--fone .tela__vidro img {
  border-radius: 24px 24px 0 0;
  width: 100%;
  height: auto;
  display: block;
  align-self: start;
}
.tela--fone--tese { width: clamp(220px, 22vw, 280px); }  /* tela sozinha ao lado de texto.
   Revisao v3 (07/08): 360px de largura viravam ~780px de altura de aparelho --
   com captura esparsa (inicio da ClavIA), a moldura dominava a dobra e o vazio
   interno lia como erro (anti-padrao "moldura maior que a imagem"). 280px poe o
   aparelho em ~600px, subordinado ao texto da dobra. */

/* Foco: o único desenho do site por cima da imagem. Aponta, não explica --
   quem explica é a legenda, e o que o foco marca existe SEMPRE também em
   texto. Máx. 1 por tela, 3 por página, nunca sobre nome de aluno nem sobre o
   selo de dado ilustrativo. */
.tela__foco {
  animation: tela-abre var(--t-abre) ease-out 200ms backwards;
  position: absolute;
  left: var(--fx); top: var(--fy);
  width: var(--fw); height: var(--fh);
  border: 2px solid var(--terra);   /* 6,02:1 sobre o branco da tela */
  border-radius: 6px;
  pointer-events: none;
}
@media (max-width: 700px) { .tela__foco { display: none; } }

/* Uma classe por instância: as coordenadas moram no CSS, nunca em style="".
   Foi assim que o gráfico do painel morreu em produção na v1 -- as alturas
   eram inline e a CSP de produção publica style-src 'self'. */
.tela__foco--escola-porque  { --fx: 16%; --fy: 29%; --fw: 61%; --fh: 23%; }
.tela__foco--ficha-reguas   { --fx: 47%; --fy: 26%; --fw: 30%; --fh: 35%; }
/* fone em proporção real: a imagem ocupa ~74% da altura do vidro, então as
   coordenadas do foco (que são % do vidro) encolhem na vertical */
.tela__foco--chamada-salvar { --fx: 4%;  --fy: 62%; --fw: 92%; --fh: 8%; }
.tela__foco--diag-achado    { --fx: 3%;  --fy: 55%; --fw: 91%; --fh: 15%; }
.tela__foco--turma-clavia   { --fx: 4%;  --fy: 30%; --fw: 92%; --fh: 20%; }

.tela__legenda {
  margin: var(--y-tela) 0 0;
  font: 400 14px/1.6 var(--corpo);
  color: var(--sub);              /* 6,77:1 sobre papel, 5,79:1 sobre areia */
  max-width: 60ch;
}
/* nos fones o selo migra para a legenda: não há chapéu onde pendurá-lo */
.tela__selo--linha {
  display: inline-block;
  margin-right: 8px;
  font: 500 11px var(--mono);
  letter-spacing: .4px;
  color: var(--sub);
}

/* A leitura em texto: acessibilidade e SEO no mesmo elemento, fechada por
   padrão para não devolver o wall of text para a página. Ao trocar prosa por
   imagem o texto indexável cai; isto o devolve ao buscador e ao leitor de tela
   sem obrigar o visitante a atravessá-lo. É <details> nativo, e não um acordeão
   de JS, porque conteúdo em <details> é indexado e conteúdo escondido por
   display:none via script não é. */
.tela__leitura { margin-top: 8px; }
/* o corpo aparece em 240ms, e só ao pedido do visitante: nunca abre sozinho */
@keyframes tela-abre { from { opacity: 0; } to { opacity: 1; } }
.tela__leitura[open] > *:not(summary) { animation: tela-abre var(--t-abre) ease-out; }
.tela__leitura > summary {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font: 600 14px var(--corpo);
  color: var(--link);
  cursor: pointer;
  list-style: none;
}
.tela__leitura > summary::-webkit-details-marker { display: none; }
.tela__leitura > summary::after { content: ' ›'; margin-left: 4px; }
.tela__leitura[open] > summary::after { content: ' ⌄'; }
.tela__leitura > summary:hover { text-decoration: underline; }
.tela__leitura p,
.tela__leitura li { font-size: 15px; line-height: 1.65; color: var(--ink); max-width: 66ch; }
.tela__leitura ul { margin: 8px 0 0; padding-left: 20px; }
.tela__leitura ul + p { margin-top: 12px; }

/* A troca de estado: o único elemento vivo do site inteiro. Ela alterna a
   IMAGEM (p3-chamada <-> p4-salvo) com um botão de verdade, em vez de animar
   uma recriação da UI -- que é o que a v1 fazia e o que produziu a leitura de
   "fraco". Uma só no site, e ela mora no hero da home.
   Sem JavaScript o botão não aparece: o hero fica com a chamada, e a tela do
   offline continua publicada em /projetos/sifre/ e em /sobre/. */
.tela__troca { display: none; margin-top: 12px; }
.js .tela__troca { display: inline-flex; }

/* ---------- 11a. A folha de contato --------------------------------------- */

/* As telas que existem hoje, todas de uma vez, agrupadas por produto e por
   formato. Não é galeria decorativa: é o inventário do produto, e é a resposta
   mais direta ao "muita informação de texto" -- a página deixa de descrever os
   dois produtos e passa a mostrá-los inteiros.
   Fone e painel moram em grades separadas de propósito: misturar 390x844 com
   1280x500 na mesma trilha produz uma fileira rasgada que lê como erro. */
.folha { display: grid; align-items: start; gap: 28px 20px; margin-top: 20px; }
.folha--fones { grid-template-columns: repeat(auto-fill, minmax(min(100%, 132px), 1fr)); }
.folha--paineis { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
.folha--pos { margin-top: 20px; }
.folha__rot {
  font: 500 11px var(--mono);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--kicker);
  margin: 28px 0 0;
}
.folha__tit { display: block; color: var(--strong); }

/* A miniatura larga o chapéu: a 132px de largura, uma barra de 12px com nome e
   selo fica ilegível. O selo desce para a legenda, onde ele tem linha própria
   e continua obrigatório -- nenhuma tela do site aparece sem ele. */
.tela--mini { width: 100%; }
.tela--mini .tela__vidro { border-radius: 6px; }
.tela--mini.tela--fone .tela__vidro { border-width: 5px; border-radius: 18px; }
.tela--mini.tela--fone .tela__vidro img { border-radius: 13px; }
.tela--mini .tela__legenda { margin-top: 10px; font: 500 11px/1.5 var(--mono); }
.tela--mini .tela__selo--linha { display: block; margin: 2px 0 0; }

/* As renúncias, em tipo grande e sem parágrafo. Elas eram três colunas de
   prosa explicando o que a empresa não faz; a lista de `narrativa.md` já diz
   isso em quatro linhas, e dizer menos aqui é dizer mais. */
.renuncias { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.renuncias li {
  font: 800 clamp(20px, 2.2vw, 26px)/1.25 var(--display);
  letter-spacing: -0.01em;
  color: var(--strong);
  border-top: 2px solid var(--fio);
  padding-top: 16px;
  max-width: 34ch;
}

/* Nome de produto sem wordmark (HarmonIA): texto no peso do título, com o
   ponto terracota da família. Substitui a moldura vazia "sem tela", reprovada
   pelo dono em 06/08 — lia como página quebrada, não como ausência. */
.nome-produto {
  font-size: clamp(22px, 2.2vw, 28px);
  letter-spacing: .5px;
  margin: 0 0 2px;
}
.nome-produto .ponto-produto { color: var(--fio); }

/* O produto que ainda não tem nome público não recebe wordmark nem ponto: o
   ponto terracota é a assinatura da família, e usá-lo num bloco sem nome
   prometeria uma marca que ainda não existe. Ele fica em corpo de texto, um
   degrau abaixo dos nomes reais, que é o que a hierarquia deve dizer. */
.nome-produto--anonimo,
.pauta__nome--anonimo {
  font: 600 17px/1.35 var(--corpo);
  letter-spacing: 0;
  color: var(--sub);
  max-width: 22ch;
}

/* A tagline do produto, uma linha, acima da descrição. */
.frase-produto {
  font: 800 clamp(17px, 1.6vw, 20px)/1.3 var(--display);
  letter-spacing: -0.01em;
  color: var(--strong);
  margin: 0;
}

/* dentro de card (flex column) a wordmark alinha à esquerda, como o resto da
   coluna — sem tocar em display, que é quem esconde a variante do outro tema */
.card > .marca-produto--entrada { align-self: flex-start; }

/* ---------- 11b. Padrão-prova: texto curto, tela grande -------------------- */

/* A inversão de proporção é a mudança de layout mais importante da v2. No v1 o
   `.duo` dava 1.55fr ao texto (61% da largura útil) e 1fr à prova (39%): a
   prova era o filho estreito de um grid feito para texto. Aqui o texto cabe em
   22rem (~29%, ~44ch) e a tela fica com ~65%. */
.prova-b {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
}
@media (min-width: 900px) {
  .prova-b { grid-template-columns: var(--col-txt) minmax(0, 1fr); align-items: center; }
  .prova-b--inv { grid-template-columns: minmax(0, 1fr) var(--col-txt); }
  .prova-b--inv > .prova-b__txt { order: 2; }
  .prova-b--topo { align-items: start; }
}
/* abaixo de 900px o texto vem antes da tela, sempre -- a mesma regra do
   `.duo--inv`, que já valia e continua valendo */
.prova-b--inv > .prova-b__txt { order: 0; }

/* ---------- 11c. Números (só fato verificável) ---------------------------- */

/* Guardrail: `.numeros` recebe fato que a GTE pode provar -- 2025 (fundação),
   Edital 34/2025, out/2026 (POC), 0 (biometria). Número de produto fica DENTRO
   da imagem, onde o selo "dados ilustrativos" o cobre. Um "91,4%" desenhado
   pelo site em mono de 44px lê como claim da GTE, e a v1 já teve que remover
   claim por menos. */
.numeros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: 24px 32px;
  border-top: 1px solid var(--fio);
  padding-top: 24px;
}
.numeros__val {
  font: 500 clamp(32px, 4vw, 44px)/1 var(--mono);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.02em;
  color: var(--strong);
}
.numeros__rot { margin: 8px 0 0; font: 400 14px/1.5 var(--corpo); color: var(--sub); max-width: 24ch; }

/* ---------- 11d. Tira de passos ------------------------------------------- */

.passos { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: clamp(16px, 3vw, 32px); }
.passos--pos { margin-top: clamp(28px, 3.5vw, 40px); }
.passo { display: flex; flex-direction: column; gap: 16px; }
.passo .tela { align-self: center; width: min(100%, 240px); }
.passo__rot { font: 500 11px var(--mono); letter-spacing: 1px; color: var(--kicker); margin: 0 0 4px; }
.passo__txt { font-size: 14px; line-height: 1.55; color: var(--sub); margin: 0; }

/* ---------- 12. Linha do tempo do projeto --------------------------------- */

.tempo { max-width: 760px; }
.tempo__trilho { position: relative; height: 2px; background: var(--stroke); border-radius: 1px; margin: 0 6px; }
.tempo__preench { position: absolute; left: 0; top: 0; height: 2px; width: 100%; transform: scaleX(var(--n, 0)); transform-origin: left center; background: var(--terra); border-radius: 1px; transition: transform 300ms ease-out; }
.tempo__marco {
  position: absolute;
  top: -5px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--card);
  border: 1.5px solid var(--cobre);
  transform: translateX(-6px);
  transition: background-color 150ms ease-out, border-color 150ms ease-out;
}
.tempo__marco--i { left: 0; }
.tempo__marco--m { left: 50%; }
.tempo__marco--f { left: 100%; }
.tempo__marco[data-on] { background: var(--terra); border-color: var(--terra); }
.tempo__rotulos { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-top: 14px; }
.tempo__rotulos div { font: 500 11px var(--mono); letter-spacing: 0.5px; color: var(--sub); }
.tempo__rotulos div:nth-child(2) { text-align: center; }
.tempo__rotulos div:nth-child(3) { text-align: right; }
.tempo__rotulos b { display: block; font: 600 13px var(--corpo); letter-spacing: 0; color: var(--strong); }

/* ---------- 13. Formulário ------------------------------------------------ */

.form {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: clamp(20px, 3vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* textarea e select carregam largura intrínseca (cols/opções) e empurram o
   contêiner em tela estreita se não forem soltos */
.campo input, .campo select, .campo textarea { width: 100%; min-width: 0; }
.campo label { font: 600 14px var(--corpo); color: var(--strong); }
.campo label .opt { font: 400 13px var(--corpo); color: var(--sub); }
/* O campo tinha o mesmo fundo da página e uma borda a 1,38:1 -- não havia
   pista visual de que ali era um campo. Fundo próprio mais fronteira a 3,23:1. */
.campo input, .campo select, .campo textarea {
  min-height: 46px;
  padding: 10px 14px;
  border: 1px solid var(--stroke-forte);
  border-radius: var(--r-sm);
  background: var(--campo-bg);
  color: var(--ink);
  font-size: 15px;
  transition: border-color var(--t-micro) ease-out;
}
.campo input:hover, .campo select:hover, .campo textarea:hover { border-color: var(--strong); }
.campo textarea { min-height: 120px; line-height: 1.55; resize: vertical; font-family: var(--corpo); }
.campo input[aria-invalid='true'], .campo textarea[aria-invalid='true'] { border-color: var(--err); }
.campo .erro { font-size: 13px; color: var(--err); }
.campo .erro:empty { display: none; }
.form__nota { font-size: 13px; line-height: 1.55; color: var(--sub); }
.form .btn { align-self: flex-start; }
.mel { position: absolute; left: -9999px; }

.recibo {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: 32px;
}
.recibo__marca {
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 2px solid var(--ok);
  color: var(--ok);
  font: 600 18px var(--corpo);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}

/* ---------- 14. Kit de imprensa ------------------------------------------- */

.kit { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 16px; }
.kit__peca { background: var(--card); border: 1px solid var(--stroke); border-radius: var(--r-md); padding: 20px; display: flex; flex-direction: column; gap: 14px; }
/* altura fixa na vitrine: o símbolo é quadrado e os lockups são largos; sem isto
   uma peça estica o cartão e a fileira desalinha */
.kit__vitrine {
  background: #FFFFFF;
  border: 1px solid #D5DCE2;
  border-radius: var(--r-sm);
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
}
.kit__vitrine--escura { background: #0E1B29; border-color: #22364A; }
.kit__vitrine img { max-width: 82%; max-height: 100%; width: auto; height: auto; display: block; object-fit: contain; }
.kit__peca .kit__pe { margin-top: auto; }
.kit__pe { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.kit__pe span { font: 600 14px var(--corpo); color: var(--strong); }

/* ---------- 15. Rodapé ---------------------------------------------------- */

.rodape {
  background: var(--navy);
  color: var(--navy-ink);
  border-top: 1px solid var(--navy-line);
}
.rodape__wrap { padding-block: clamp(48px, 7vw, 72px) 32px; }
.rodape__topo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--navy-line);
}
.rodape__marca { display: block; height: 42px; width: auto; }
.rodape__tagline { margin: 0; font: 700 16px/1.3 var(--display); color: var(--navy-strong); }

.rodape__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 32px; padding-block: 36px; }
.rodape h2 {
  margin: 0 0 14px;
  font: 500 12px var(--mono);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--cobre);
}
/* Os links do rodapé davam 23px de altura: 1px abaixo do mínimo de 24px do
   SC 2.5.8, e eles não são links em meio a texto corrido, então não cabe a
   isenção de alvo em linha. */
.rodape__col { display: flex; flex-direction: column; gap: 6px; font-size: 15px; line-height: 1.5; align-items: flex-start; }
.rodape__col a,
.rodape__col > span,
.rodape__link-btn { display: flex; align-items: center; min-height: 32px; }
.rodape a { color: var(--navy-ink); text-decoration: none; transition: color var(--t-micro); }
.rodape a:hover { color: var(--navy-strong); text-decoration: underline; text-underline-offset: 3px; }
.rodape__link-btn {
  background: none;
  border: none;
  padding: 0;
  font: 400 15px var(--corpo);
  color: var(--navy-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  text-align: left;
}
.rodape__link-btn:hover { color: var(--navy-strong); }
.rodape__base {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  align-items: center;
  justify-content: space-between;
  padding-top: 24px;
  border-top: 1px solid var(--navy-line);
}
/* perfil decidido, link ainda não: aparece como "em breve", igual ao resto do
   site trata o que ainda não existe */
.rodape__breve { font: 500 13px var(--mono); letter-spacing: .3px; color: #8FA0AE; }
.rodape__faperj { font: 500 12px var(--mono); letter-spacing: 0.4px; color: var(--cobre); }
.rodape__cnpj { font: 500 12px var(--mono); color: #8FA0AE; }

/* ---------- 16. Aviso de cookies ------------------------------------------ */

.cookies {
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  width: min(780px, calc(100vw - 32px));
  z-index: 90;
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  padding: 18px 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px 20px;
  align-items: center;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--strong) 6%, transparent);
}
.cookies[hidden] { display: none; }
.cookies p { flex: 1 1 300px; margin: 0; font-size: 14px; line-height: 1.55; }
.cookies strong { color: var(--strong); }
.cookies__acoes { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------- 17. Motion (entradas) ----------------------------------------- */

/* 8px é o piso da faixa de deslocamento de entrada, e a escolha mais sóbria
   dela: o bloco entra uma vez, inteiro. Nada de revelar por letra, por palavra
   ou por linha, e nunca a h1 do hero -- texto principal não pode depender de
   animação para ser lido. */
[data-reveal] { opacity: 1; }
.js [data-reveal]:not([data-shown]) { opacity: 0; transform: translateY(8px); }
.js [data-reveal] { transition: opacity var(--t-entra) ease-out, transform var(--t-entra) ease-out; }
.js [data-reveal-stagger]:not([data-shown]) > * { opacity: 0; transform: translateY(8px); }
.js [data-reveal-stagger] > * { transition: opacity var(--t-entra) ease-out, transform var(--t-entra) ease-out; }

/* ---------- 18. Impressão ------------------------------------------------- */

@media print {
  .nav, .cookies, .rodape__link-btn, .tela__troca { display: none !important; }
  /* Imprimir sem ter rolado até o fim deixava 60-80% da página em branco:
     o reveal congela em opacity 0. No papel, tudo revelado. (Painel 10/08.) */
  .js [data-reveal], .js [data-reveal-stagger] > * { opacity: 1 !important; transform: none !important; }
  /* No papel a captura não se lê (0,28x de um painel de 1280px), mas a leitura
     em texto dela sim: some a imagem, abre o <details>. */
  .tela__vidro, .tela__chapeu, .tela__leitura > summary { display: none !important; }
  .tela__leitura > *:not(summary) { display: block !important; }
  body { background: #FFFFFF; color: #000000; font-size: 12pt; }
  .sec, .sec--navy { background: #FFFFFF !important; color: #000000 !important; padding-block: 12pt; }
  .sec--navy h2, .sec--navy h3 { color: #000000; }
  a { color: #000000; text-decoration: underline; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 9pt; }
}
